query.c revision a0571b135ef2fdc9ade78b476e0af154f0f8a1f6
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   if (!is_supported)
234      return VDP_STATUS_INVALID_POINTER;
235
236   return VDP_STATUS_NO_IMPLEMENTATION;
237}
238
239/**
240 * Query the implementation's capability to perform a PutBits operation using
241 * application data in a specific indexed format.
242 */
243VdpStatus
244vlVdpOutputSurfaceQueryPutBitsIndexedCapabilities(VdpDevice device,
245                                                  VdpRGBAFormat surface_rgba_format,
246                                                  VdpIndexedFormat bits_indexed_format,
247                                                  VdpColorTableFormat color_table_format,
248                                                  VdpBool *is_supported)
249{
250   vlVdpDevice *dev;
251   struct pipe_screen *pscreen;
252   enum pipe_format rgba_format, index_format, colortbl_format;
253
254   dev = vlGetDataHTAB(device);
255   if (!dev)
256      return VDP_STATUS_INVALID_HANDLE;
257
258   pscreen = dev->vscreen->pscreen;
259   if (!pscreen)
260      return VDP_STATUS_ERROR;
261
262   rgba_format = FormatRGBAToPipe(surface_rgba_format);
263   if (rgba_format == PIPE_FORMAT_NONE || rgba_format == PIPE_FORMAT_A8_UNORM)
264      return VDP_STATUS_INVALID_RGBA_FORMAT;
265
266   index_format = FormatIndexedToPipe(bits_indexed_format);
267   if (index_format == PIPE_FORMAT_NONE)
268       return VDP_STATUS_INVALID_INDEXED_FORMAT;
269
270   colortbl_format = FormatColorTableToPipe(color_table_format);
271   if (colortbl_format == PIPE_FORMAT_NONE)
272       return VDP_STATUS_INVALID_COLOR_TABLE_FORMAT;
273
274   if (!is_supported)
275      return VDP_STATUS_INVALID_POINTER;
276
277   *is_supported = pscreen->is_format_supported
278   (
279      pscreen, rgba_format, PIPE_TEXTURE_2D, 1,
280      PIPE_BIND_SAMPLER_VIEW | PIPE_BIND_RENDER_TARGET
281   );
282
283   *is_supported &= pscreen->is_format_supported
284   (
285      pscreen, index_format, PIPE_TEXTURE_2D, 1,
286      PIPE_BIND_SAMPLER_VIEW
287   );
288
289   *is_supported &= pscreen->is_format_supported
290   (
291      pscreen, colortbl_format, PIPE_TEXTURE_1D, 1,
292      PIPE_BIND_SAMPLER_VIEW
293   );
294
295   return VDP_STATUS_OK;
296}
297
298/**
299 * Query the implementation's capability to perform a PutBits operation using
300 * application data in a specific YCbCr/YUB format.
301 */
302VdpStatus
303vlVdpOutputSurfaceQueryPutBitsYCbCrCapabilities(VdpDevice device, VdpRGBAFormat surface_rgba_format,
304                                                VdpYCbCrFormat bits_ycbcr_format,
305                                                VdpBool *is_supported)
306{
307   if (!is_supported)
308      return VDP_STATUS_INVALID_POINTER;
309
310   return VDP_STATUS_NO_IMPLEMENTATION;
311}
312
313/**
314 * Query the implementation's VdpBitmapSurface capabilities.
315 */
316VdpStatus
317vlVdpBitmapSurfaceQueryCapabilities(VdpDevice device, VdpRGBAFormat surface_rgba_format,
318                                    VdpBool *is_supported, uint32_t *max_width, uint32_t *max_height)
319{
320   vlVdpDevice *dev;
321   struct pipe_screen *pscreen;
322   enum pipe_format format;
323
324   dev = vlGetDataHTAB(device);
325   if (!dev)
326      return VDP_STATUS_INVALID_HANDLE;
327
328   pscreen = dev->vscreen->pscreen;
329   if (!pscreen)
330      return VDP_STATUS_RESOURCES;
331
332   format = FormatRGBAToPipe(surface_rgba_format);
333   if (format == PIPE_FORMAT_NONE)
334      return VDP_STATUS_INVALID_RGBA_FORMAT;
335
336   if (!(is_supported && max_width && max_height))
337      return VDP_STATUS_INVALID_POINTER;
338
339   *is_supported = pscreen->is_format_supported
340   (
341      pscreen, format, PIPE_TEXTURE_3D, 1,
342      PIPE_BIND_SAMPLER_VIEW | PIPE_BIND_RENDER_TARGET
343   );
344   if (*is_supported) {
345      uint32_t max_2d_texture_level = pscreen->get_param(
346         pscreen, PIPE_CAP_MAX_TEXTURE_2D_LEVELS);
347
348      if (!max_2d_texture_level)
349         return VDP_STATUS_ERROR;
350
351      *max_width = *max_height = pow(2, max_2d_texture_level - 1);
352   } else {
353      *max_width = 0;
354      *max_height = 0;
355   }
356
357   return VDP_STATUS_OK;
358}
359
360/**
361 * Query the implementation's support for a specific feature.
362 */
363VdpStatus
364vlVdpVideoMixerQueryFeatureSupport(VdpDevice device, VdpVideoMixerFeature feature,
365                                   VdpBool *is_supported)
366{
367   if (!is_supported)
368      return VDP_STATUS_INVALID_POINTER;
369
370   switch (feature) {
371   case VDP_VIDEO_MIXER_FEATURE_SHARPNESS:
372   case VDP_VIDEO_MIXER_FEATURE_NOISE_REDUCTION:
373      *is_supported = VDP_TRUE;
374      break;
375   default:
376      *is_supported = VDP_FALSE;
377      break;
378   }
379   return VDP_STATUS_OK;
380}
381
382/**
383 * Query the implementation's support for a specific parameter.
384 */
385VdpStatus
386vlVdpVideoMixerQueryParameterSupport(VdpDevice device, VdpVideoMixerParameter parameter,
387                                     VdpBool *is_supported)
388{
389   if (!is_supported)
390      return VDP_STATUS_INVALID_POINTER;
391
392   switch (parameter) {
393   case VDP_VIDEO_MIXER_PARAMETER_VIDEO_SURFACE_WIDTH:
394   case VDP_VIDEO_MIXER_PARAMETER_VIDEO_SURFACE_HEIGHT:
395   case VDP_VIDEO_MIXER_PARAMETER_CHROMA_TYPE:
396   case VDP_VIDEO_MIXER_PARAMETER_LAYERS:
397      *is_supported = VDP_TRUE;
398      break;
399   default:
400      *is_supported = VDP_FALSE;
401      break;
402   }
403   return VDP_STATUS_OK;
404}
405
406/**
407 * Query the implementation's supported for a specific parameter.
408 */
409VdpStatus
410vlVdpVideoMixerQueryParameterValueRange(VdpDevice device, VdpVideoMixerParameter parameter,
411                                        void *min_value, void *max_value)
412{
413   vlVdpDevice *dev = vlGetDataHTAB(device);
414   struct pipe_screen *screen;
415   enum pipe_video_profile prof = PIPE_VIDEO_PROFILE_UNKNOWN;
416   if (!dev)
417      return VDP_STATUS_INVALID_HANDLE;
418   if (!(min_value && max_value))
419      return VDP_STATUS_INVALID_POINTER;
420   screen = dev->vscreen->pscreen;
421   switch (parameter) {
422   case VDP_VIDEO_MIXER_PARAMETER_VIDEO_SURFACE_WIDTH:
423      *(uint32_t*)min_value = 48;
424      *(uint32_t*)max_value = screen->get_video_param(screen, prof, PIPE_VIDEO_CAP_MAX_WIDTH);
425      break;
426   case VDP_VIDEO_MIXER_PARAMETER_VIDEO_SURFACE_HEIGHT:
427      *(uint32_t*)min_value = 48;
428      *(uint32_t*)max_value = screen->get_video_param(screen, prof, PIPE_VIDEO_CAP_MAX_HEIGHT);
429      break;
430
431   case VDP_VIDEO_MIXER_PARAMETER_LAYERS:
432      *(uint32_t*)min_value = 0;
433      *(uint32_t*)max_value = 4;
434      break;
435
436   case VDP_VIDEO_MIXER_PARAMETER_CHROMA_TYPE:
437   default:
438      return VDP_STATUS_INVALID_VIDEO_MIXER_PARAMETER;
439   }
440   return VDP_STATUS_OK;
441}
442
443/**
444 * Query the implementation's support for a specific attribute.
445 */
446VdpStatus
447vlVdpVideoMixerQueryAttributeSupport(VdpDevice device, VdpVideoMixerAttribute attribute,
448                                     VdpBool *is_supported)
449{
450   if (!is_supported)
451      return VDP_STATUS_INVALID_POINTER;
452
453   switch (attribute) {
454   case VDP_VIDEO_MIXER_ATTRIBUTE_BACKGROUND_COLOR:
455   case VDP_VIDEO_MIXER_ATTRIBUTE_CSC_MATRIX:
456   case VDP_VIDEO_MIXER_ATTRIBUTE_NOISE_REDUCTION_LEVEL:
457   case VDP_VIDEO_MIXER_ATTRIBUTE_SHARPNESS_LEVEL:
458   case VDP_VIDEO_MIXER_ATTRIBUTE_LUMA_KEY_MIN_LUMA:
459   case VDP_VIDEO_MIXER_ATTRIBUTE_LUMA_KEY_MAX_LUMA:
460   case VDP_VIDEO_MIXER_ATTRIBUTE_SKIP_CHROMA_DEINTERLACE:
461      *is_supported = VDP_TRUE;
462      break;
463   default:
464      *is_supported = VDP_FALSE;
465   }
466   return VDP_STATUS_OK;
467}
468
469/**
470 * Query the implementation's supported for a specific attribute.
471 */
472VdpStatus
473vlVdpVideoMixerQueryAttributeValueRange(VdpDevice device, VdpVideoMixerAttribute attribute,
474                                        void *min_value, void *max_value)
475{
476   if (!(min_value && max_value))
477      return VDP_STATUS_INVALID_POINTER;
478
479   switch (attribute) {
480   case VDP_VIDEO_MIXER_ATTRIBUTE_NOISE_REDUCTION_LEVEL:
481   case VDP_VIDEO_MIXER_ATTRIBUTE_LUMA_KEY_MIN_LUMA:
482   case VDP_VIDEO_MIXER_ATTRIBUTE_LUMA_KEY_MAX_LUMA:
483      *(float*)min_value = 0.f;
484      *(float*)max_value = 1.f;
485      break;
486   case VDP_VIDEO_MIXER_ATTRIBUTE_SHARPNESS_LEVEL:
487      *(float*)min_value = -1.f;
488      *(float*)max_value = 1.f;
489      break;
490   case VDP_VIDEO_MIXER_ATTRIBUTE_SKIP_CHROMA_DEINTERLACE:
491      *(uint8_t*)min_value = 0;
492      *(uint8_t*)max_value = 1;
493      break;
494   case VDP_VIDEO_MIXER_ATTRIBUTE_BACKGROUND_COLOR:
495   case VDP_VIDEO_MIXER_ATTRIBUTE_CSC_MATRIX:
496   default:
497      return VDP_STATUS_INVALID_VIDEO_MIXER_ATTRIBUTE;
498   }
499   return VDP_STATUS_OK;
500}
501