query.c revision 5d5b414a7b840a4a90050041fabd88a9af6dca43
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   pipe_mutex_lock(dev->mutex);
87
88   /* XXX: Current limits */
89   *is_supported = true;
90   max_2d_texture_level = pscreen->get_param(pscreen, PIPE_CAP_MAX_TEXTURE_2D_LEVELS);
91   pipe_mutex_unlock(dev->mutex);
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   pipe_mutex_lock(dev->mutex);
124
125   switch(bits_ycbcr_format) {
126   case VDP_YCBCR_FORMAT_UYVY:
127   case VDP_YCBCR_FORMAT_YUYV:
128      *is_supported = surface_chroma_type == VDP_CHROMA_TYPE_422;
129      break;
130
131   case VDP_YCBCR_FORMAT_Y8U8V8A8:
132   case VDP_YCBCR_FORMAT_V8U8Y8A8:
133      *is_supported = surface_chroma_type == VDP_CHROMA_TYPE_444;
134      break;
135
136   default:
137      *is_supported = true;
138      break;
139   }
140
141   *is_supported &= pscreen->is_video_format_supported
142   (
143      pscreen,
144      FormatYCBCRToPipe(bits_ycbcr_format),
145      PIPE_VIDEO_PROFILE_UNKNOWN
146   );
147   pipe_mutex_unlock(dev->mutex);
148
149   return VDP_STATUS_OK;
150}
151
152/**
153 * Query the implementation's VdpDecoder capabilities.
154 */
155VdpStatus
156vlVdpDecoderQueryCapabilities(VdpDevice device, VdpDecoderProfile profile,
157                              VdpBool *is_supported, uint32_t *max_level, uint32_t *max_macroblocks,
158                              uint32_t *max_width, uint32_t *max_height)
159{
160   vlVdpDevice *dev;
161   struct pipe_screen *pscreen;
162   enum pipe_video_profile p_profile;
163
164   if (!(is_supported && max_level && max_macroblocks && max_width && max_height))
165      return VDP_STATUS_INVALID_POINTER;
166
167   dev = vlGetDataHTAB(device);
168   if (!dev)
169      return VDP_STATUS_INVALID_HANDLE;
170
171   pscreen = dev->vscreen->pscreen;
172   if (!pscreen)
173      return VDP_STATUS_RESOURCES;
174
175   p_profile = ProfileToPipe(profile);
176   if (p_profile == PIPE_VIDEO_PROFILE_UNKNOWN)	{
177      *is_supported = false;
178      return VDP_STATUS_OK;
179   }
180
181   pipe_mutex_lock(dev->mutex);
182   *is_supported = pscreen->get_video_param(pscreen, p_profile, PIPE_VIDEO_CAP_SUPPORTED);
183   if (*is_supported) {
184      *max_width = pscreen->get_video_param(pscreen, p_profile, PIPE_VIDEO_CAP_MAX_WIDTH);
185      *max_height = pscreen->get_video_param(pscreen, p_profile, PIPE_VIDEO_CAP_MAX_HEIGHT);
186      *max_level = 16;
187      *max_macroblocks = (*max_width/16)*(*max_height/16);
188   } else {
189      *max_width = 0;
190      *max_height = 0;
191      *max_level = 0;
192      *max_macroblocks = 0;
193   }
194   pipe_mutex_unlock(dev->mutex);
195
196   return VDP_STATUS_OK;
197}
198
199/**
200 * Query the implementation's VdpOutputSurface capabilities.
201 */
202VdpStatus
203vlVdpOutputSurfaceQueryCapabilities(VdpDevice device, VdpRGBAFormat surface_rgba_format,
204                                    VdpBool *is_supported, uint32_t *max_width, uint32_t *max_height)
205{
206   vlVdpDevice *dev;
207   struct pipe_screen *pscreen;
208   enum pipe_format format;
209
210   dev = vlGetDataHTAB(device);
211   if (!dev)
212      return VDP_STATUS_INVALID_HANDLE;
213
214   pscreen = dev->vscreen->pscreen;
215   if (!pscreen)
216      return VDP_STATUS_RESOURCES;
217
218   format = FormatRGBAToPipe(surface_rgba_format);
219   if (format == PIPE_FORMAT_NONE || format == PIPE_FORMAT_A8_UNORM)
220      return VDP_STATUS_INVALID_RGBA_FORMAT;
221
222   if (!(is_supported && max_width && max_height))
223      return VDP_STATUS_INVALID_POINTER;
224
225   pipe_mutex_lock(dev->mutex);
226   *is_supported = pscreen->is_format_supported
227   (
228      pscreen, format, PIPE_TEXTURE_3D, 1,
229      PIPE_BIND_SAMPLER_VIEW | PIPE_BIND_RENDER_TARGET
230   );
231   if (*is_supported) {
232      uint32_t max_2d_texture_level = pscreen->get_param(
233         pscreen, PIPE_CAP_MAX_TEXTURE_2D_LEVELS);
234
235      if (!max_2d_texture_level) {
236         pipe_mutex_unlock(dev->mutex);
237         return VDP_STATUS_ERROR;
238      }
239
240      *max_width = *max_height = pow(2, max_2d_texture_level - 1);
241   } else {
242      *max_width = 0;
243      *max_height = 0;
244   }
245   pipe_mutex_unlock(dev->mutex);
246
247   return VDP_STATUS_OK;
248}
249
250/**
251 * Query the implementation's capability to perform a PutBits operation using
252 * application data matching the surface's format.
253 */
254VdpStatus
255vlVdpOutputSurfaceQueryGetPutBitsNativeCapabilities(VdpDevice device, VdpRGBAFormat surface_rgba_format,
256                                                    VdpBool *is_supported)
257{
258   vlVdpDevice *dev;
259   struct pipe_screen *pscreen;
260   enum pipe_format format;
261
262   dev = vlGetDataHTAB(device);
263   if (!dev)
264      return VDP_STATUS_INVALID_HANDLE;
265
266   pscreen = dev->vscreen->pscreen;
267   if (!pscreen)
268      return VDP_STATUS_ERROR;
269
270   format = FormatRGBAToPipe(surface_rgba_format);
271   if (format == PIPE_FORMAT_NONE || format == PIPE_FORMAT_A8_UNORM)
272      return VDP_STATUS_INVALID_RGBA_FORMAT;
273
274   if (!is_supported)
275      return VDP_STATUS_INVALID_POINTER;
276
277   pipe_mutex_lock(dev->mutex);
278   *is_supported = pscreen->is_format_supported
279   (
280      pscreen, format, PIPE_TEXTURE_2D, 1,
281      PIPE_BIND_SAMPLER_VIEW | PIPE_BIND_RENDER_TARGET
282   );
283   pipe_mutex_unlock(dev->mutex);
284
285   return VDP_STATUS_OK;
286}
287
288/**
289 * Query the implementation's capability to perform a PutBits operation using
290 * application data in a specific indexed format.
291 */
292VdpStatus
293vlVdpOutputSurfaceQueryPutBitsIndexedCapabilities(VdpDevice device,
294                                                  VdpRGBAFormat surface_rgba_format,
295                                                  VdpIndexedFormat bits_indexed_format,
296                                                  VdpColorTableFormat color_table_format,
297                                                  VdpBool *is_supported)
298{
299   vlVdpDevice *dev;
300   struct pipe_screen *pscreen;
301   enum pipe_format rgba_format, index_format, colortbl_format;
302
303   dev = vlGetDataHTAB(device);
304   if (!dev)
305      return VDP_STATUS_INVALID_HANDLE;
306
307   pscreen = dev->vscreen->pscreen;
308   if (!pscreen)
309      return VDP_STATUS_ERROR;
310
311   rgba_format = FormatRGBAToPipe(surface_rgba_format);
312   if (rgba_format == PIPE_FORMAT_NONE || rgba_format == PIPE_FORMAT_A8_UNORM)
313      return VDP_STATUS_INVALID_RGBA_FORMAT;
314
315   index_format = FormatIndexedToPipe(bits_indexed_format);
316   if (index_format == PIPE_FORMAT_NONE)
317       return VDP_STATUS_INVALID_INDEXED_FORMAT;
318
319   colortbl_format = FormatColorTableToPipe(color_table_format);
320   if (colortbl_format == PIPE_FORMAT_NONE)
321       return VDP_STATUS_INVALID_COLOR_TABLE_FORMAT;
322
323   if (!is_supported)
324      return VDP_STATUS_INVALID_POINTER;
325
326   pipe_mutex_lock(dev->mutex);
327   *is_supported = pscreen->is_format_supported
328   (
329      pscreen, rgba_format, PIPE_TEXTURE_2D, 1,
330      PIPE_BIND_SAMPLER_VIEW | PIPE_BIND_RENDER_TARGET
331   );
332
333   *is_supported &= pscreen->is_format_supported
334   (
335      pscreen, index_format, PIPE_TEXTURE_2D, 1,
336      PIPE_BIND_SAMPLER_VIEW
337   );
338
339   *is_supported &= pscreen->is_format_supported
340   (
341      pscreen, colortbl_format, PIPE_TEXTURE_1D, 1,
342      PIPE_BIND_SAMPLER_VIEW
343   );
344   pipe_mutex_unlock(dev->mutex);
345
346   return VDP_STATUS_OK;
347}
348
349/**
350 * Query the implementation's capability to perform a PutBits operation using
351 * application data in a specific YCbCr/YUB format.
352 */
353VdpStatus
354vlVdpOutputSurfaceQueryPutBitsYCbCrCapabilities(VdpDevice device, VdpRGBAFormat surface_rgba_format,
355                                                VdpYCbCrFormat bits_ycbcr_format,
356                                                VdpBool *is_supported)
357{
358   vlVdpDevice *dev;
359   struct pipe_screen *pscreen;
360   enum pipe_format rgba_format, ycbcr_format;
361
362   dev = vlGetDataHTAB(device);
363   if (!dev)
364      return VDP_STATUS_INVALID_HANDLE;
365
366   pscreen = dev->vscreen->pscreen;
367   if (!pscreen)
368      return VDP_STATUS_ERROR;
369
370   rgba_format = FormatRGBAToPipe(surface_rgba_format);
371   if (rgba_format == PIPE_FORMAT_NONE || rgba_format == PIPE_FORMAT_A8_UNORM)
372      return VDP_STATUS_INVALID_RGBA_FORMAT;
373
374   ycbcr_format = FormatYCBCRToPipe(bits_ycbcr_format);
375   if (ycbcr_format == PIPE_FORMAT_NONE)
376       return VDP_STATUS_INVALID_INDEXED_FORMAT;
377
378   if (!is_supported)
379      return VDP_STATUS_INVALID_POINTER;
380
381   pipe_mutex_lock(dev->mutex);
382   *is_supported = pscreen->is_format_supported
383   (
384      pscreen, rgba_format, PIPE_TEXTURE_2D, 1,
385      PIPE_BIND_SAMPLER_VIEW | PIPE_BIND_RENDER_TARGET
386   );
387
388   *is_supported &= pscreen->is_video_format_supported
389   (
390      pscreen, ycbcr_format,
391      PIPE_VIDEO_PROFILE_UNKNOWN
392   );
393   pipe_mutex_unlock(dev->mutex);
394
395   return VDP_STATUS_OK;
396}
397
398/**
399 * Query the implementation's VdpBitmapSurface capabilities.
400 */
401VdpStatus
402vlVdpBitmapSurfaceQueryCapabilities(VdpDevice device, VdpRGBAFormat surface_rgba_format,
403                                    VdpBool *is_supported, uint32_t *max_width, uint32_t *max_height)
404{
405   vlVdpDevice *dev;
406   struct pipe_screen *pscreen;
407   enum pipe_format format;
408
409   dev = vlGetDataHTAB(device);
410   if (!dev)
411      return VDP_STATUS_INVALID_HANDLE;
412
413   pscreen = dev->vscreen->pscreen;
414   if (!pscreen)
415      return VDP_STATUS_RESOURCES;
416
417   format = FormatRGBAToPipe(surface_rgba_format);
418   if (format == PIPE_FORMAT_NONE)
419      return VDP_STATUS_INVALID_RGBA_FORMAT;
420
421   if (!(is_supported && max_width && max_height))
422      return VDP_STATUS_INVALID_POINTER;
423
424   pipe_mutex_lock(dev->mutex);
425   *is_supported = pscreen->is_format_supported
426   (
427      pscreen, format, PIPE_TEXTURE_3D, 1,
428      PIPE_BIND_SAMPLER_VIEW | PIPE_BIND_RENDER_TARGET
429   );
430   if (*is_supported) {
431      uint32_t max_2d_texture_level = pscreen->get_param(
432         pscreen, PIPE_CAP_MAX_TEXTURE_2D_LEVELS);
433
434      if (!max_2d_texture_level) {
435         pipe_mutex_unlock(dev->mutex);
436         return VDP_STATUS_ERROR;
437      }
438
439      *max_width = *max_height = pow(2, max_2d_texture_level - 1);
440   } else {
441      *max_width = 0;
442      *max_height = 0;
443   }
444   pipe_mutex_unlock(dev->mutex);
445
446   return VDP_STATUS_OK;
447}
448
449/**
450 * Query the implementation's support for a specific feature.
451 */
452VdpStatus
453vlVdpVideoMixerQueryFeatureSupport(VdpDevice device, VdpVideoMixerFeature feature,
454                                   VdpBool *is_supported)
455{
456   if (!is_supported)
457      return VDP_STATUS_INVALID_POINTER;
458
459   switch (feature) {
460   case VDP_VIDEO_MIXER_FEATURE_SHARPNESS:
461   case VDP_VIDEO_MIXER_FEATURE_NOISE_REDUCTION:
462      *is_supported = VDP_TRUE;
463      break;
464   default:
465      *is_supported = VDP_FALSE;
466      break;
467   }
468   return VDP_STATUS_OK;
469}
470
471/**
472 * Query the implementation's support for a specific parameter.
473 */
474VdpStatus
475vlVdpVideoMixerQueryParameterSupport(VdpDevice device, VdpVideoMixerParameter parameter,
476                                     VdpBool *is_supported)
477{
478   if (!is_supported)
479      return VDP_STATUS_INVALID_POINTER;
480
481   switch (parameter) {
482   case VDP_VIDEO_MIXER_PARAMETER_VIDEO_SURFACE_WIDTH:
483   case VDP_VIDEO_MIXER_PARAMETER_VIDEO_SURFACE_HEIGHT:
484   case VDP_VIDEO_MIXER_PARAMETER_CHROMA_TYPE:
485   case VDP_VIDEO_MIXER_PARAMETER_LAYERS:
486      *is_supported = VDP_TRUE;
487      break;
488   default:
489      *is_supported = VDP_FALSE;
490      break;
491   }
492   return VDP_STATUS_OK;
493}
494
495/**
496 * Query the implementation's supported for a specific parameter.
497 */
498VdpStatus
499vlVdpVideoMixerQueryParameterValueRange(VdpDevice device, VdpVideoMixerParameter parameter,
500                                        void *min_value, void *max_value)
501{
502   vlVdpDevice *dev = vlGetDataHTAB(device);
503   struct pipe_screen *screen;
504   enum pipe_video_profile prof = PIPE_VIDEO_PROFILE_UNKNOWN;
505
506   if (!dev)
507      return VDP_STATUS_INVALID_HANDLE;
508   if (!(min_value && max_value))
509      return VDP_STATUS_INVALID_POINTER;
510
511   pipe_mutex_lock(dev->mutex);
512   screen = dev->vscreen->pscreen;
513   switch (parameter) {
514   case VDP_VIDEO_MIXER_PARAMETER_VIDEO_SURFACE_WIDTH:
515      *(uint32_t*)min_value = 48;
516      *(uint32_t*)max_value = screen->get_video_param(screen, prof, PIPE_VIDEO_CAP_MAX_WIDTH);
517      break;
518   case VDP_VIDEO_MIXER_PARAMETER_VIDEO_SURFACE_HEIGHT:
519      *(uint32_t*)min_value = 48;
520      *(uint32_t*)max_value = screen->get_video_param(screen, prof, PIPE_VIDEO_CAP_MAX_HEIGHT);
521      break;
522
523   case VDP_VIDEO_MIXER_PARAMETER_LAYERS:
524      *(uint32_t*)min_value = 0;
525      *(uint32_t*)max_value = 4;
526      break;
527
528   case VDP_VIDEO_MIXER_PARAMETER_CHROMA_TYPE:
529   default:
530      pipe_mutex_unlock(dev->mutex);
531      return VDP_STATUS_INVALID_VIDEO_MIXER_PARAMETER;
532   }
533   pipe_mutex_unlock(dev->mutex);
534   return VDP_STATUS_OK;
535}
536
537/**
538 * Query the implementation's support for a specific attribute.
539 */
540VdpStatus
541vlVdpVideoMixerQueryAttributeSupport(VdpDevice device, VdpVideoMixerAttribute attribute,
542                                     VdpBool *is_supported)
543{
544   if (!is_supported)
545      return VDP_STATUS_INVALID_POINTER;
546
547   switch (attribute) {
548   case VDP_VIDEO_MIXER_ATTRIBUTE_BACKGROUND_COLOR:
549   case VDP_VIDEO_MIXER_ATTRIBUTE_CSC_MATRIX:
550   case VDP_VIDEO_MIXER_ATTRIBUTE_NOISE_REDUCTION_LEVEL:
551   case VDP_VIDEO_MIXER_ATTRIBUTE_SHARPNESS_LEVEL:
552   case VDP_VIDEO_MIXER_ATTRIBUTE_LUMA_KEY_MIN_LUMA:
553   case VDP_VIDEO_MIXER_ATTRIBUTE_LUMA_KEY_MAX_LUMA:
554   case VDP_VIDEO_MIXER_ATTRIBUTE_SKIP_CHROMA_DEINTERLACE:
555      *is_supported = VDP_TRUE;
556      break;
557   default:
558      *is_supported = VDP_FALSE;
559   }
560   return VDP_STATUS_OK;
561}
562
563/**
564 * Query the implementation's supported for a specific attribute.
565 */
566VdpStatus
567vlVdpVideoMixerQueryAttributeValueRange(VdpDevice device, VdpVideoMixerAttribute attribute,
568                                        void *min_value, void *max_value)
569{
570   if (!(min_value && max_value))
571      return VDP_STATUS_INVALID_POINTER;
572
573   switch (attribute) {
574   case VDP_VIDEO_MIXER_ATTRIBUTE_NOISE_REDUCTION_LEVEL:
575   case VDP_VIDEO_MIXER_ATTRIBUTE_LUMA_KEY_MIN_LUMA:
576   case VDP_VIDEO_MIXER_ATTRIBUTE_LUMA_KEY_MAX_LUMA:
577      *(float*)min_value = 0.f;
578      *(float*)max_value = 1.f;
579      break;
580   case VDP_VIDEO_MIXER_ATTRIBUTE_SHARPNESS_LEVEL:
581      *(float*)min_value = -1.f;
582      *(float*)max_value = 1.f;
583      break;
584   case VDP_VIDEO_MIXER_ATTRIBUTE_SKIP_CHROMA_DEINTERLACE:
585      *(uint8_t*)min_value = 0;
586      *(uint8_t*)max_value = 1;
587      break;
588   case VDP_VIDEO_MIXER_ATTRIBUTE_BACKGROUND_COLOR:
589   case VDP_VIDEO_MIXER_ATTRIBUTE_CSC_MATRIX:
590   default:
591      return VDP_STATUS_INVALID_VIDEO_MIXER_ATTRIBUTE;
592   }
593   return VDP_STATUS_OK;
594}
595