query.c revision 222600972c60ce987b63c6422f26b9b8da95f1b0
1/**************************************************************************
2 *
3 * Copyright 2010 Younes Manton.
4 * All Rights Reserved.
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a
7 * copy of this software and associated documentation files (the
8 * "Software"), to deal in the Software without restriction, including
9 * without limitation the rights to use, copy, modify, merge, publish,
10 * distribute, sub license, and/or sell copies of the Software, and to
11 * permit persons to whom the Software is furnished to do so, subject to
12 * the following conditions:
13 *
14 * The above copyright notice and this permission notice (including the
15 * next paragraph) shall be included in all copies or substantial portions
16 * of the Software.
17 *
18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
19 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
21 * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
22 * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
23 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
24 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
25 *
26 **************************************************************************/
27
28#include <assert.h>
29#include <math.h>
30
31#include "vdpau_private.h"
32#include "vl_winsys.h"
33#include "pipe/p_screen.h"
34#include "pipe/p_defines.h"
35#include "util/u_debug.h"
36
37/**
38 * Retrieve the VDPAU version implemented by the backend.
39 */
40VdpStatus
41vlVdpGetApiVersion(uint32_t *api_version)
42{
43   if (!api_version)
44      return VDP_STATUS_INVALID_POINTER;
45
46   *api_version = 1;
47   return VDP_STATUS_OK;
48}
49
50/**
51 * Retrieve an implementation-specific string description of the implementation.
52 * This typically includes detailed version information.
53 */
54VdpStatus
55vlVdpGetInformationString(char const **information_string)
56{
57   if (!information_string)
58      return VDP_STATUS_INVALID_POINTER;
59
60   *information_string = INFORMATION_STRING;
61   return VDP_STATUS_OK;
62}
63
64/**
65 * Query the implementation's VdpVideoSurface capabilities.
66 */
67VdpStatus
68vlVdpVideoSurfaceQueryCapabilities(VdpDevice device, VdpChromaType surface_chroma_type,
69                                   VdpBool *is_supported, uint32_t *max_width, uint32_t *max_height)
70{
71   vlVdpDevice *dev;
72   struct pipe_screen *pscreen;
73   uint32_t max_2d_texture_level;
74
75   if (!(is_supported && max_width && max_height))
76      return VDP_STATUS_INVALID_POINTER;
77
78   dev = vlGetDataHTAB(device);
79   if (!dev)
80      return VDP_STATUS_INVALID_HANDLE;
81
82   pscreen = dev->vscreen->pscreen;
83   if (!pscreen)
84      return VDP_STATUS_RESOURCES;
85
86   /* XXX: Current limits */
87   *is_supported = true;
88   if (surface_chroma_type != VDP_CHROMA_TYPE_420)
89      *is_supported = false;
90
91   max_2d_texture_level = pscreen->get_param(pscreen, PIPE_CAP_MAX_TEXTURE_2D_LEVELS);
92   if (!max_2d_texture_level)
93      return VDP_STATUS_RESOURCES;
94
95   /* I am not quite sure if it is max_2d_texture_level-1 or just max_2d_texture_level */
96   *max_width = *max_height = pow(2,max_2d_texture_level-1);
97
98   return VDP_STATUS_OK;
99}
100
101/**
102 * Query the implementation's VdpVideoSurface GetBits/PutBits capabilities.
103 */
104VdpStatus
105vlVdpVideoSurfaceQueryGetPutBitsYCbCrCapabilities(VdpDevice device, VdpChromaType surface_chroma_type,
106                                                  VdpYCbCrFormat bits_ycbcr_format,
107                                                  VdpBool *is_supported)
108{
109   vlVdpDevice *dev;
110   struct pipe_screen *pscreen;
111
112   if (!is_supported)
113      return VDP_STATUS_INVALID_POINTER;
114
115   dev = vlGetDataHTAB(device);
116   if (!dev)
117      return VDP_STATUS_INVALID_HANDLE;
118
119   pscreen = dev->vscreen->pscreen;
120   if (!pscreen)
121      return VDP_STATUS_RESOURCES;
122
123   *is_supported = pscreen->is_video_format_supported
124   (
125      pscreen,
126      FormatYCBCRToPipe(bits_ycbcr_format),
127      PIPE_VIDEO_PROFILE_UNKNOWN
128   );
129
130   return VDP_STATUS_OK;
131}
132
133/**
134 * Query the implementation's VdpDecoder capabilities.
135 */
136VdpStatus
137vlVdpDecoderQueryCapabilities(VdpDevice device, VdpDecoderProfile profile,
138                              VdpBool *is_supported, uint32_t *max_level, uint32_t *max_macroblocks,
139                              uint32_t *max_width, uint32_t *max_height)
140{
141   vlVdpDevice *dev;
142   struct pipe_screen *pscreen;
143   enum pipe_video_profile p_profile;
144
145   if (!(is_supported && max_level && max_macroblocks && max_width && max_height))
146      return VDP_STATUS_INVALID_POINTER;
147
148   dev = vlGetDataHTAB(device);
149   if (!dev)
150      return VDP_STATUS_INVALID_HANDLE;
151
152   pscreen = dev->vscreen->pscreen;
153   if (!pscreen)
154      return VDP_STATUS_RESOURCES;
155
156   p_profile = ProfileToPipe(profile);
157   if (p_profile == PIPE_VIDEO_PROFILE_UNKNOWN)	{
158      *is_supported = false;
159      return VDP_STATUS_OK;
160   }
161
162   *is_supported = pscreen->get_video_param(pscreen, p_profile, PIPE_VIDEO_CAP_SUPPORTED);
163   if (*is_supported) {
164      *max_width = pscreen->get_video_param(pscreen, p_profile, PIPE_VIDEO_CAP_MAX_WIDTH);
165      *max_height = pscreen->get_video_param(pscreen, p_profile, PIPE_VIDEO_CAP_MAX_HEIGHT);
166      *max_level = 16;
167      *max_macroblocks = (*max_width/16)*(*max_height/16);
168   } else {
169      *max_width = 0;
170      *max_height = 0;
171      *max_level = 0;
172      *max_macroblocks = 0;
173   }
174
175   return VDP_STATUS_OK;
176}
177
178/**
179 * Query the implementation's VdpOutputSurface capabilities.
180 */
181VdpStatus
182vlVdpOutputSurfaceQueryCapabilities(VdpDevice device, VdpRGBAFormat surface_rgba_format,
183                                    VdpBool *is_supported, uint32_t *max_width, uint32_t *max_height)
184{
185   vlVdpDevice *dev;
186   struct pipe_screen *pscreen;
187   enum pipe_format format;
188
189   dev = vlGetDataHTAB(device);
190   if (!dev)
191      return VDP_STATUS_INVALID_HANDLE;
192
193   pscreen = dev->vscreen->pscreen;
194   if (!pscreen)
195      return VDP_STATUS_RESOURCES;
196
197   format = FormatRGBAToPipe(surface_rgba_format);
198   if (format == PIPE_FORMAT_NONE || format == PIPE_FORMAT_A8_UNORM)
199      return VDP_STATUS_INVALID_RGBA_FORMAT;
200
201   if (!(is_supported && max_width && max_height))
202      return VDP_STATUS_INVALID_POINTER;
203
204   *is_supported = pscreen->is_format_supported
205   (
206      pscreen, format, PIPE_TEXTURE_3D, 1,
207      PIPE_BIND_SAMPLER_VIEW | PIPE_BIND_RENDER_TARGET
208   );
209   if (*is_supported) {
210      uint32_t max_2d_texture_level = pscreen->get_param(
211         pscreen, PIPE_CAP_MAX_TEXTURE_2D_LEVELS);
212
213      if (!max_2d_texture_level)
214         return VDP_STATUS_ERROR;
215
216      *max_width = *max_height = pow(2, max_2d_texture_level - 1);
217   } else {
218      *max_width = 0;
219      *max_height = 0;
220   }
221
222   return VDP_STATUS_OK;
223}
224
225/**
226 * Query the implementation's capability to perform a PutBits operation using
227 * application data matching the surface's format.
228 */
229VdpStatus
230vlVdpOutputSurfaceQueryGetPutBitsNativeCapabilities(VdpDevice device, VdpRGBAFormat surface_rgba_format,
231                                                    VdpBool *is_supported)
232{
233   vlVdpDevice *dev;
234   struct pipe_screen *pscreen;
235   enum pipe_format format;
236
237   dev = vlGetDataHTAB(device);
238   if (!dev)
239      return VDP_STATUS_INVALID_HANDLE;
240
241   pscreen = dev->vscreen->pscreen;
242   if (!pscreen)
243      return VDP_STATUS_ERROR;
244
245   format = FormatRGBAToPipe(surface_rgba_format);
246   if (format == PIPE_FORMAT_NONE || format == PIPE_FORMAT_A8_UNORM)
247      return VDP_STATUS_INVALID_RGBA_FORMAT;
248
249   if (!is_supported)
250      return VDP_STATUS_INVALID_POINTER;
251
252   *is_supported = pscreen->is_format_supported
253   (
254      pscreen, format, PIPE_TEXTURE_2D, 1,
255      PIPE_BIND_SAMPLER_VIEW | PIPE_BIND_RENDER_TARGET
256   );
257
258   return VDP_STATUS_OK;
259}
260
261/**
262 * Query the implementation's capability to perform a PutBits operation using
263 * application data in a specific indexed format.
264 */
265VdpStatus
266vlVdpOutputSurfaceQueryPutBitsIndexedCapabilities(VdpDevice device,
267                                                  VdpRGBAFormat surface_rgba_format,
268                                                  VdpIndexedFormat bits_indexed_format,
269                                                  VdpColorTableFormat color_table_format,
270                                                  VdpBool *is_supported)
271{
272   vlVdpDevice *dev;
273   struct pipe_screen *pscreen;
274   enum pipe_format rgba_format, index_format, colortbl_format;
275
276   dev = vlGetDataHTAB(device);
277   if (!dev)
278      return VDP_STATUS_INVALID_HANDLE;
279
280   pscreen = dev->vscreen->pscreen;
281   if (!pscreen)
282      return VDP_STATUS_ERROR;
283
284   rgba_format = FormatRGBAToPipe(surface_rgba_format);
285   if (rgba_format == PIPE_FORMAT_NONE || rgba_format == PIPE_FORMAT_A8_UNORM)
286      return VDP_STATUS_INVALID_RGBA_FORMAT;
287
288   index_format = FormatIndexedToPipe(bits_indexed_format);
289   if (index_format == PIPE_FORMAT_NONE)
290       return VDP_STATUS_INVALID_INDEXED_FORMAT;
291
292   colortbl_format = FormatColorTableToPipe(color_table_format);
293   if (colortbl_format == PIPE_FORMAT_NONE)
294       return VDP_STATUS_INVALID_COLOR_TABLE_FORMAT;
295
296   if (!is_supported)
297      return VDP_STATUS_INVALID_POINTER;
298
299   *is_supported = pscreen->is_format_supported
300   (
301      pscreen, rgba_format, PIPE_TEXTURE_2D, 1,
302      PIPE_BIND_SAMPLER_VIEW | PIPE_BIND_RENDER_TARGET
303   );
304
305   *is_supported &= pscreen->is_format_supported
306   (
307      pscreen, index_format, PIPE_TEXTURE_2D, 1,
308      PIPE_BIND_SAMPLER_VIEW
309   );
310
311   *is_supported &= pscreen->is_format_supported
312   (
313      pscreen, colortbl_format, PIPE_TEXTURE_1D, 1,
314      PIPE_BIND_SAMPLER_VIEW
315   );
316
317   return VDP_STATUS_OK;
318}
319
320/**
321 * Query the implementation's capability to perform a PutBits operation using
322 * application data in a specific YCbCr/YUB format.
323 */
324VdpStatus
325vlVdpOutputSurfaceQueryPutBitsYCbCrCapabilities(VdpDevice device, VdpRGBAFormat surface_rgba_format,
326                                                VdpYCbCrFormat bits_ycbcr_format,
327                                                VdpBool *is_supported)
328{
329   if (!is_supported)
330      return VDP_STATUS_INVALID_POINTER;
331
332   return VDP_STATUS_NO_IMPLEMENTATION;
333}
334
335/**
336 * Query the implementation's VdpBitmapSurface capabilities.
337 */
338VdpStatus
339vlVdpBitmapSurfaceQueryCapabilities(VdpDevice device, VdpRGBAFormat surface_rgba_format,
340                                    VdpBool *is_supported, uint32_t *max_width, uint32_t *max_height)
341{
342   vlVdpDevice *dev;
343   struct pipe_screen *pscreen;
344   enum pipe_format format;
345
346   dev = vlGetDataHTAB(device);
347   if (!dev)
348      return VDP_STATUS_INVALID_HANDLE;
349
350   pscreen = dev->vscreen->pscreen;
351   if (!pscreen)
352      return VDP_STATUS_RESOURCES;
353
354   format = FormatRGBAToPipe(surface_rgba_format);
355   if (format == PIPE_FORMAT_NONE)
356      return VDP_STATUS_INVALID_RGBA_FORMAT;
357
358   if (!(is_supported && max_width && max_height))
359      return VDP_STATUS_INVALID_POINTER;
360
361   *is_supported = pscreen->is_format_supported
362   (
363      pscreen, format, PIPE_TEXTURE_3D, 1,
364      PIPE_BIND_SAMPLER_VIEW | PIPE_BIND_RENDER_TARGET
365   );
366   if (*is_supported) {
367      uint32_t max_2d_texture_level = pscreen->get_param(
368         pscreen, PIPE_CAP_MAX_TEXTURE_2D_LEVELS);
369
370      if (!max_2d_texture_level)
371         return VDP_STATUS_ERROR;
372
373      *max_width = *max_height = pow(2, max_2d_texture_level - 1);
374   } else {
375      *max_width = 0;
376      *max_height = 0;
377   }
378
379   return VDP_STATUS_OK;
380}
381
382/**
383 * Query the implementation's support for a specific feature.
384 */
385VdpStatus
386vlVdpVideoMixerQueryFeatureSupport(VdpDevice device, VdpVideoMixerFeature feature,
387                                   VdpBool *is_supported)
388{
389   if (!is_supported)
390      return VDP_STATUS_INVALID_POINTER;
391
392   switch (feature) {
393   case VDP_VIDEO_MIXER_FEATURE_SHARPNESS:
394   case VDP_VIDEO_MIXER_FEATURE_NOISE_REDUCTION:
395      *is_supported = VDP_TRUE;
396      break;
397   default:
398      *is_supported = VDP_FALSE;
399      break;
400   }
401   return VDP_STATUS_OK;
402}
403
404/**
405 * Query the implementation's support for a specific parameter.
406 */
407VdpStatus
408vlVdpVideoMixerQueryParameterSupport(VdpDevice device, VdpVideoMixerParameter parameter,
409                                     VdpBool *is_supported)
410{
411   if (!is_supported)
412      return VDP_STATUS_INVALID_POINTER;
413
414   switch (parameter) {
415   case VDP_VIDEO_MIXER_PARAMETER_VIDEO_SURFACE_WIDTH:
416   case VDP_VIDEO_MIXER_PARAMETER_VIDEO_SURFACE_HEIGHT:
417   case VDP_VIDEO_MIXER_PARAMETER_CHROMA_TYPE:
418   case VDP_VIDEO_MIXER_PARAMETER_LAYERS:
419      *is_supported = VDP_TRUE;
420      break;
421   default:
422      *is_supported = VDP_FALSE;
423      break;
424   }
425   return VDP_STATUS_OK;
426}
427
428/**
429 * Query the implementation's supported for a specific parameter.
430 */
431VdpStatus
432vlVdpVideoMixerQueryParameterValueRange(VdpDevice device, VdpVideoMixerParameter parameter,
433                                        void *min_value, void *max_value)
434{
435   vlVdpDevice *dev = vlGetDataHTAB(device);
436   struct pipe_screen *screen;
437   enum pipe_video_profile prof = PIPE_VIDEO_PROFILE_UNKNOWN;
438   if (!dev)
439      return VDP_STATUS_INVALID_HANDLE;
440   if (!(min_value && max_value))
441      return VDP_STATUS_INVALID_POINTER;
442   screen = dev->vscreen->pscreen;
443   switch (parameter) {
444   case VDP_VIDEO_MIXER_PARAMETER_VIDEO_SURFACE_WIDTH:
445      *(uint32_t*)min_value = 48;
446      *(uint32_t*)max_value = screen->get_video_param(screen, prof, PIPE_VIDEO_CAP_MAX_WIDTH);
447      break;
448   case VDP_VIDEO_MIXER_PARAMETER_VIDEO_SURFACE_HEIGHT:
449      *(uint32_t*)min_value = 48;
450      *(uint32_t*)max_value = screen->get_video_param(screen, prof, PIPE_VIDEO_CAP_MAX_HEIGHT);
451      break;
452
453   case VDP_VIDEO_MIXER_PARAMETER_LAYERS:
454      *(uint32_t*)min_value = 0;
455      *(uint32_t*)max_value = 4;
456      break;
457
458   case VDP_VIDEO_MIXER_PARAMETER_CHROMA_TYPE:
459   default:
460      return VDP_STATUS_INVALID_VIDEO_MIXER_PARAMETER;
461   }
462   return VDP_STATUS_OK;
463}
464
465/**
466 * Query the implementation's support for a specific attribute.
467 */
468VdpStatus
469vlVdpVideoMixerQueryAttributeSupport(VdpDevice device, VdpVideoMixerAttribute attribute,
470                                     VdpBool *is_supported)
471{
472   if (!is_supported)
473      return VDP_STATUS_INVALID_POINTER;
474
475   switch (attribute) {
476   case VDP_VIDEO_MIXER_ATTRIBUTE_BACKGROUND_COLOR:
477   case VDP_VIDEO_MIXER_ATTRIBUTE_CSC_MATRIX:
478   case VDP_VIDEO_MIXER_ATTRIBUTE_NOISE_REDUCTION_LEVEL:
479   case VDP_VIDEO_MIXER_ATTRIBUTE_SHARPNESS_LEVEL:
480   case VDP_VIDEO_MIXER_ATTRIBUTE_LUMA_KEY_MIN_LUMA:
481   case VDP_VIDEO_MIXER_ATTRIBUTE_LUMA_KEY_MAX_LUMA:
482   case VDP_VIDEO_MIXER_ATTRIBUTE_SKIP_CHROMA_DEINTERLACE:
483      *is_supported = VDP_TRUE;
484      break;
485   default:
486      *is_supported = VDP_FALSE;
487   }
488   return VDP_STATUS_OK;
489}
490
491/**
492 * Query the implementation's supported for a specific attribute.
493 */
494VdpStatus
495vlVdpVideoMixerQueryAttributeValueRange(VdpDevice device, VdpVideoMixerAttribute attribute,
496                                        void *min_value, void *max_value)
497{
498   if (!(min_value && max_value))
499      return VDP_STATUS_INVALID_POINTER;
500
501   switch (attribute) {
502   case VDP_VIDEO_MIXER_ATTRIBUTE_NOISE_REDUCTION_LEVEL:
503   case VDP_VIDEO_MIXER_ATTRIBUTE_LUMA_KEY_MIN_LUMA:
504   case VDP_VIDEO_MIXER_ATTRIBUTE_LUMA_KEY_MAX_LUMA:
505      *(float*)min_value = 0.f;
506      *(float*)max_value = 1.f;
507      break;
508   case VDP_VIDEO_MIXER_ATTRIBUTE_SHARPNESS_LEVEL:
509      *(float*)min_value = -1.f;
510      *(float*)max_value = 1.f;
511      break;
512   case VDP_VIDEO_MIXER_ATTRIBUTE_SKIP_CHROMA_DEINTERLACE:
513      *(uint8_t*)min_value = 0;
514      *(uint8_t*)max_value = 1;
515      break;
516   case VDP_VIDEO_MIXER_ATTRIBUTE_BACKGROUND_COLOR:
517   case VDP_VIDEO_MIXER_ATTRIBUTE_CSC_MATRIX:
518   default:
519      return VDP_STATUS_INVALID_VIDEO_MIXER_ATTRIBUTE;
520   }
521   return VDP_STATUS_OK;
522}
523