vl: add entrypoint to is_video_format_supported
[mesa.git] / src / gallium / state_trackers / vdpau / query.c
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 "pipe/p_screen.h"
33 #include "pipe/p_defines.h"
34 #include "util/u_debug.h"
35
36 /**
37 * Retrieve the VDPAU version implemented by the backend.
38 */
39 VdpStatus
40 vlVdpGetApiVersion(uint32_t *api_version)
41 {
42 if (!api_version)
43 return VDP_STATUS_INVALID_POINTER;
44
45 *api_version = 1;
46 return VDP_STATUS_OK;
47 }
48
49 /**
50 * Retrieve an implementation-specific string description of the implementation.
51 * This typically includes detailed version information.
52 */
53 VdpStatus
54 vlVdpGetInformationString(char const **information_string)
55 {
56 if (!information_string)
57 return VDP_STATUS_INVALID_POINTER;
58
59 *information_string = INFORMATION_STRING;
60 return VDP_STATUS_OK;
61 }
62
63 /**
64 * Query the implementation's VdpVideoSurface capabilities.
65 */
66 VdpStatus
67 vlVdpVideoSurfaceQueryCapabilities(VdpDevice device, VdpChromaType surface_chroma_type,
68 VdpBool *is_supported, uint32_t *max_width, uint32_t *max_height)
69 {
70 vlVdpDevice *dev;
71 struct pipe_screen *pscreen;
72 uint32_t max_2d_texture_level;
73
74 if (!(is_supported && max_width && max_height))
75 return VDP_STATUS_INVALID_POINTER;
76
77 dev = vlGetDataHTAB(device);
78 if (!dev)
79 return VDP_STATUS_INVALID_HANDLE;
80
81 pscreen = dev->vscreen->pscreen;
82 if (!pscreen)
83 return VDP_STATUS_RESOURCES;
84
85 pipe_mutex_lock(dev->mutex);
86
87 /* XXX: Current limits */
88 *is_supported = true;
89 max_2d_texture_level = pscreen->get_param(pscreen, PIPE_CAP_MAX_TEXTURE_2D_LEVELS);
90 pipe_mutex_unlock(dev->mutex);
91 if (!max_2d_texture_level)
92 return VDP_STATUS_RESOURCES;
93
94 /* I am not quite sure if it is max_2d_texture_level-1 or just max_2d_texture_level */
95 *max_width = *max_height = pow(2,max_2d_texture_level-1);
96
97 return VDP_STATUS_OK;
98 }
99
100 /**
101 * Query the implementation's VdpVideoSurface GetBits/PutBits capabilities.
102 */
103 VdpStatus
104 vlVdpVideoSurfaceQueryGetPutBitsYCbCrCapabilities(VdpDevice device, VdpChromaType surface_chroma_type,
105 VdpYCbCrFormat bits_ycbcr_format,
106 VdpBool *is_supported)
107 {
108 vlVdpDevice *dev;
109 struct pipe_screen *pscreen;
110
111 if (!is_supported)
112 return VDP_STATUS_INVALID_POINTER;
113
114 dev = vlGetDataHTAB(device);
115 if (!dev)
116 return VDP_STATUS_INVALID_HANDLE;
117
118 pscreen = dev->vscreen->pscreen;
119 if (!pscreen)
120 return VDP_STATUS_RESOURCES;
121
122 pipe_mutex_lock(dev->mutex);
123
124 switch(bits_ycbcr_format) {
125 case VDP_YCBCR_FORMAT_UYVY:
126 case VDP_YCBCR_FORMAT_YUYV:
127 *is_supported = surface_chroma_type == VDP_CHROMA_TYPE_422;
128 break;
129
130 case VDP_YCBCR_FORMAT_Y8U8V8A8:
131 case VDP_YCBCR_FORMAT_V8U8Y8A8:
132 *is_supported = surface_chroma_type == VDP_CHROMA_TYPE_444;
133 break;
134
135 default:
136 *is_supported = true;
137 break;
138 }
139
140 *is_supported &= pscreen->is_video_format_supported
141 (
142 pscreen,
143 FormatYCBCRToPipe(bits_ycbcr_format),
144 PIPE_VIDEO_PROFILE_UNKNOWN,
145 PIPE_VIDEO_ENTRYPOINT_BITSTREAM
146 );
147 pipe_mutex_unlock(dev->mutex);
148
149 return VDP_STATUS_OK;
150 }
151
152 /**
153 * Query the implementation's VdpDecoder capabilities.
154 */
155 VdpStatus
156 vlVdpDecoderQueryCapabilities(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_ENTRYPOINT_BITSTREAM,
183 PIPE_VIDEO_CAP_SUPPORTED);
184 if (*is_supported) {
185 *max_width = pscreen->get_video_param(pscreen, p_profile, PIPE_VIDEO_ENTRYPOINT_BITSTREAM,
186 PIPE_VIDEO_CAP_MAX_WIDTH);
187 *max_height = pscreen->get_video_param(pscreen, p_profile, PIPE_VIDEO_ENTRYPOINT_BITSTREAM,
188 PIPE_VIDEO_CAP_MAX_HEIGHT);
189 *max_level = pscreen->get_video_param(pscreen, p_profile, PIPE_VIDEO_ENTRYPOINT_BITSTREAM,
190 PIPE_VIDEO_CAP_MAX_LEVEL);
191 *max_macroblocks = (*max_width/16)*(*max_height/16);
192 } else {
193 *max_width = 0;
194 *max_height = 0;
195 *max_level = 0;
196 *max_macroblocks = 0;
197 }
198 pipe_mutex_unlock(dev->mutex);
199
200 return VDP_STATUS_OK;
201 }
202
203 /**
204 * Query the implementation's VdpOutputSurface capabilities.
205 */
206 VdpStatus
207 vlVdpOutputSurfaceQueryCapabilities(VdpDevice device, VdpRGBAFormat surface_rgba_format,
208 VdpBool *is_supported, uint32_t *max_width, uint32_t *max_height)
209 {
210 vlVdpDevice *dev;
211 struct pipe_screen *pscreen;
212 enum pipe_format format;
213
214 dev = vlGetDataHTAB(device);
215 if (!dev)
216 return VDP_STATUS_INVALID_HANDLE;
217
218 pscreen = dev->vscreen->pscreen;
219 if (!pscreen)
220 return VDP_STATUS_RESOURCES;
221
222 format = FormatRGBAToPipe(surface_rgba_format);
223 if (format == PIPE_FORMAT_NONE || format == PIPE_FORMAT_A8_UNORM)
224 return VDP_STATUS_INVALID_RGBA_FORMAT;
225
226 if (!(is_supported && max_width && max_height))
227 return VDP_STATUS_INVALID_POINTER;
228
229 pipe_mutex_lock(dev->mutex);
230 *is_supported = pscreen->is_format_supported
231 (
232 pscreen, format, PIPE_TEXTURE_3D, 1,
233 PIPE_BIND_SAMPLER_VIEW | PIPE_BIND_RENDER_TARGET
234 );
235 if (*is_supported) {
236 uint32_t max_2d_texture_level = pscreen->get_param(
237 pscreen, PIPE_CAP_MAX_TEXTURE_2D_LEVELS);
238
239 if (!max_2d_texture_level) {
240 pipe_mutex_unlock(dev->mutex);
241 return VDP_STATUS_ERROR;
242 }
243
244 *max_width = *max_height = pow(2, max_2d_texture_level - 1);
245 } else {
246 *max_width = 0;
247 *max_height = 0;
248 }
249 pipe_mutex_unlock(dev->mutex);
250
251 return VDP_STATUS_OK;
252 }
253
254 /**
255 * Query the implementation's capability to perform a PutBits operation using
256 * application data matching the surface's format.
257 */
258 VdpStatus
259 vlVdpOutputSurfaceQueryGetPutBitsNativeCapabilities(VdpDevice device, VdpRGBAFormat surface_rgba_format,
260 VdpBool *is_supported)
261 {
262 vlVdpDevice *dev;
263 struct pipe_screen *pscreen;
264 enum pipe_format format;
265
266 dev = vlGetDataHTAB(device);
267 if (!dev)
268 return VDP_STATUS_INVALID_HANDLE;
269
270 pscreen = dev->vscreen->pscreen;
271 if (!pscreen)
272 return VDP_STATUS_ERROR;
273
274 format = FormatRGBAToPipe(surface_rgba_format);
275 if (format == PIPE_FORMAT_NONE || format == PIPE_FORMAT_A8_UNORM)
276 return VDP_STATUS_INVALID_RGBA_FORMAT;
277
278 if (!is_supported)
279 return VDP_STATUS_INVALID_POINTER;
280
281 pipe_mutex_lock(dev->mutex);
282 *is_supported = pscreen->is_format_supported
283 (
284 pscreen, format, PIPE_TEXTURE_2D, 1,
285 PIPE_BIND_SAMPLER_VIEW | PIPE_BIND_RENDER_TARGET
286 );
287 pipe_mutex_unlock(dev->mutex);
288
289 return VDP_STATUS_OK;
290 }
291
292 /**
293 * Query the implementation's capability to perform a PutBits operation using
294 * application data in a specific indexed format.
295 */
296 VdpStatus
297 vlVdpOutputSurfaceQueryPutBitsIndexedCapabilities(VdpDevice device,
298 VdpRGBAFormat surface_rgba_format,
299 VdpIndexedFormat bits_indexed_format,
300 VdpColorTableFormat color_table_format,
301 VdpBool *is_supported)
302 {
303 vlVdpDevice *dev;
304 struct pipe_screen *pscreen;
305 enum pipe_format rgba_format, index_format, colortbl_format;
306
307 dev = vlGetDataHTAB(device);
308 if (!dev)
309 return VDP_STATUS_INVALID_HANDLE;
310
311 pscreen = dev->vscreen->pscreen;
312 if (!pscreen)
313 return VDP_STATUS_ERROR;
314
315 rgba_format = FormatRGBAToPipe(surface_rgba_format);
316 if (rgba_format == PIPE_FORMAT_NONE || rgba_format == PIPE_FORMAT_A8_UNORM)
317 return VDP_STATUS_INVALID_RGBA_FORMAT;
318
319 index_format = FormatIndexedToPipe(bits_indexed_format);
320 if (index_format == PIPE_FORMAT_NONE)
321 return VDP_STATUS_INVALID_INDEXED_FORMAT;
322
323 colortbl_format = FormatColorTableToPipe(color_table_format);
324 if (colortbl_format == PIPE_FORMAT_NONE)
325 return VDP_STATUS_INVALID_COLOR_TABLE_FORMAT;
326
327 if (!is_supported)
328 return VDP_STATUS_INVALID_POINTER;
329
330 pipe_mutex_lock(dev->mutex);
331 *is_supported = pscreen->is_format_supported
332 (
333 pscreen, rgba_format, PIPE_TEXTURE_2D, 1,
334 PIPE_BIND_SAMPLER_VIEW | PIPE_BIND_RENDER_TARGET
335 );
336
337 *is_supported &= pscreen->is_format_supported
338 (
339 pscreen, index_format, PIPE_TEXTURE_2D, 1,
340 PIPE_BIND_SAMPLER_VIEW
341 );
342
343 *is_supported &= pscreen->is_format_supported
344 (
345 pscreen, colortbl_format, PIPE_TEXTURE_1D, 1,
346 PIPE_BIND_SAMPLER_VIEW
347 );
348 pipe_mutex_unlock(dev->mutex);
349
350 return VDP_STATUS_OK;
351 }
352
353 /**
354 * Query the implementation's capability to perform a PutBits operation using
355 * application data in a specific YCbCr/YUB format.
356 */
357 VdpStatus
358 vlVdpOutputSurfaceQueryPutBitsYCbCrCapabilities(VdpDevice device, VdpRGBAFormat surface_rgba_format,
359 VdpYCbCrFormat bits_ycbcr_format,
360 VdpBool *is_supported)
361 {
362 vlVdpDevice *dev;
363 struct pipe_screen *pscreen;
364 enum pipe_format rgba_format, ycbcr_format;
365
366 dev = vlGetDataHTAB(device);
367 if (!dev)
368 return VDP_STATUS_INVALID_HANDLE;
369
370 pscreen = dev->vscreen->pscreen;
371 if (!pscreen)
372 return VDP_STATUS_ERROR;
373
374 rgba_format = FormatRGBAToPipe(surface_rgba_format);
375 if (rgba_format == PIPE_FORMAT_NONE || rgba_format == PIPE_FORMAT_A8_UNORM)
376 return VDP_STATUS_INVALID_RGBA_FORMAT;
377
378 ycbcr_format = FormatYCBCRToPipe(bits_ycbcr_format);
379 if (ycbcr_format == PIPE_FORMAT_NONE)
380 return VDP_STATUS_INVALID_INDEXED_FORMAT;
381
382 if (!is_supported)
383 return VDP_STATUS_INVALID_POINTER;
384
385 pipe_mutex_lock(dev->mutex);
386 *is_supported = pscreen->is_format_supported
387 (
388 pscreen, rgba_format, PIPE_TEXTURE_2D, 1,
389 PIPE_BIND_SAMPLER_VIEW | PIPE_BIND_RENDER_TARGET
390 );
391
392 *is_supported &= pscreen->is_video_format_supported
393 (
394 pscreen, ycbcr_format,
395 PIPE_VIDEO_PROFILE_UNKNOWN,
396 PIPE_VIDEO_ENTRYPOINT_BITSTREAM
397 );
398 pipe_mutex_unlock(dev->mutex);
399
400 return VDP_STATUS_OK;
401 }
402
403 /**
404 * Query the implementation's VdpBitmapSurface capabilities.
405 */
406 VdpStatus
407 vlVdpBitmapSurfaceQueryCapabilities(VdpDevice device, VdpRGBAFormat surface_rgba_format,
408 VdpBool *is_supported, uint32_t *max_width, uint32_t *max_height)
409 {
410 vlVdpDevice *dev;
411 struct pipe_screen *pscreen;
412 enum pipe_format format;
413
414 dev = vlGetDataHTAB(device);
415 if (!dev)
416 return VDP_STATUS_INVALID_HANDLE;
417
418 pscreen = dev->vscreen->pscreen;
419 if (!pscreen)
420 return VDP_STATUS_RESOURCES;
421
422 format = FormatRGBAToPipe(surface_rgba_format);
423 if (format == PIPE_FORMAT_NONE)
424 return VDP_STATUS_INVALID_RGBA_FORMAT;
425
426 if (!(is_supported && max_width && max_height))
427 return VDP_STATUS_INVALID_POINTER;
428
429 pipe_mutex_lock(dev->mutex);
430 *is_supported = pscreen->is_format_supported
431 (
432 pscreen, format, PIPE_TEXTURE_3D, 1,
433 PIPE_BIND_SAMPLER_VIEW | PIPE_BIND_RENDER_TARGET
434 );
435 if (*is_supported) {
436 uint32_t max_2d_texture_level = pscreen->get_param(
437 pscreen, PIPE_CAP_MAX_TEXTURE_2D_LEVELS);
438
439 if (!max_2d_texture_level) {
440 pipe_mutex_unlock(dev->mutex);
441 return VDP_STATUS_ERROR;
442 }
443
444 *max_width = *max_height = pow(2, max_2d_texture_level - 1);
445 } else {
446 *max_width = 0;
447 *max_height = 0;
448 }
449 pipe_mutex_unlock(dev->mutex);
450
451 return VDP_STATUS_OK;
452 }
453
454 /**
455 * Query the implementation's support for a specific feature.
456 */
457 VdpStatus
458 vlVdpVideoMixerQueryFeatureSupport(VdpDevice device, VdpVideoMixerFeature feature,
459 VdpBool *is_supported)
460 {
461 if (!is_supported)
462 return VDP_STATUS_INVALID_POINTER;
463
464 switch (feature) {
465 case VDP_VIDEO_MIXER_FEATURE_SHARPNESS:
466 case VDP_VIDEO_MIXER_FEATURE_NOISE_REDUCTION:
467 *is_supported = VDP_TRUE;
468 break;
469 default:
470 *is_supported = VDP_FALSE;
471 break;
472 }
473 return VDP_STATUS_OK;
474 }
475
476 /**
477 * Query the implementation's support for a specific parameter.
478 */
479 VdpStatus
480 vlVdpVideoMixerQueryParameterSupport(VdpDevice device, VdpVideoMixerParameter parameter,
481 VdpBool *is_supported)
482 {
483 if (!is_supported)
484 return VDP_STATUS_INVALID_POINTER;
485
486 switch (parameter) {
487 case VDP_VIDEO_MIXER_PARAMETER_VIDEO_SURFACE_WIDTH:
488 case VDP_VIDEO_MIXER_PARAMETER_VIDEO_SURFACE_HEIGHT:
489 case VDP_VIDEO_MIXER_PARAMETER_CHROMA_TYPE:
490 case VDP_VIDEO_MIXER_PARAMETER_LAYERS:
491 *is_supported = VDP_TRUE;
492 break;
493 default:
494 *is_supported = VDP_FALSE;
495 break;
496 }
497 return VDP_STATUS_OK;
498 }
499
500 /**
501 * Query the implementation's supported for a specific parameter.
502 */
503 VdpStatus
504 vlVdpVideoMixerQueryParameterValueRange(VdpDevice device, VdpVideoMixerParameter parameter,
505 void *min_value, void *max_value)
506 {
507 vlVdpDevice *dev = vlGetDataHTAB(device);
508 struct pipe_screen *screen;
509 enum pipe_video_profile prof = PIPE_VIDEO_PROFILE_UNKNOWN;
510
511 if (!dev)
512 return VDP_STATUS_INVALID_HANDLE;
513 if (!(min_value && max_value))
514 return VDP_STATUS_INVALID_POINTER;
515
516 pipe_mutex_lock(dev->mutex);
517 screen = dev->vscreen->pscreen;
518 switch (parameter) {
519 case VDP_VIDEO_MIXER_PARAMETER_VIDEO_SURFACE_WIDTH:
520 *(uint32_t*)min_value = 48;
521 *(uint32_t*)max_value = screen->get_video_param(screen, prof, PIPE_VIDEO_ENTRYPOINT_BITSTREAM,
522 PIPE_VIDEO_CAP_MAX_WIDTH);
523 break;
524 case VDP_VIDEO_MIXER_PARAMETER_VIDEO_SURFACE_HEIGHT:
525 *(uint32_t*)min_value = 48;
526 *(uint32_t*)max_value = screen->get_video_param(screen, prof, PIPE_VIDEO_ENTRYPOINT_BITSTREAM,
527 PIPE_VIDEO_CAP_MAX_HEIGHT);
528 break;
529
530 case VDP_VIDEO_MIXER_PARAMETER_LAYERS:
531 *(uint32_t*)min_value = 0;
532 *(uint32_t*)max_value = 4;
533 break;
534
535 case VDP_VIDEO_MIXER_PARAMETER_CHROMA_TYPE:
536 default:
537 pipe_mutex_unlock(dev->mutex);
538 return VDP_STATUS_INVALID_VIDEO_MIXER_PARAMETER;
539 }
540 pipe_mutex_unlock(dev->mutex);
541 return VDP_STATUS_OK;
542 }
543
544 /**
545 * Query the implementation's support for a specific attribute.
546 */
547 VdpStatus
548 vlVdpVideoMixerQueryAttributeSupport(VdpDevice device, VdpVideoMixerAttribute attribute,
549 VdpBool *is_supported)
550 {
551 if (!is_supported)
552 return VDP_STATUS_INVALID_POINTER;
553
554 switch (attribute) {
555 case VDP_VIDEO_MIXER_ATTRIBUTE_BACKGROUND_COLOR:
556 case VDP_VIDEO_MIXER_ATTRIBUTE_CSC_MATRIX:
557 case VDP_VIDEO_MIXER_ATTRIBUTE_NOISE_REDUCTION_LEVEL:
558 case VDP_VIDEO_MIXER_ATTRIBUTE_SHARPNESS_LEVEL:
559 case VDP_VIDEO_MIXER_ATTRIBUTE_LUMA_KEY_MIN_LUMA:
560 case VDP_VIDEO_MIXER_ATTRIBUTE_LUMA_KEY_MAX_LUMA:
561 case VDP_VIDEO_MIXER_ATTRIBUTE_SKIP_CHROMA_DEINTERLACE:
562 *is_supported = VDP_TRUE;
563 break;
564 default:
565 *is_supported = VDP_FALSE;
566 }
567 return VDP_STATUS_OK;
568 }
569
570 /**
571 * Query the implementation's supported for a specific attribute.
572 */
573 VdpStatus
574 vlVdpVideoMixerQueryAttributeValueRange(VdpDevice device, VdpVideoMixerAttribute attribute,
575 void *min_value, void *max_value)
576 {
577 if (!(min_value && max_value))
578 return VDP_STATUS_INVALID_POINTER;
579
580 switch (attribute) {
581 case VDP_VIDEO_MIXER_ATTRIBUTE_NOISE_REDUCTION_LEVEL:
582 case VDP_VIDEO_MIXER_ATTRIBUTE_LUMA_KEY_MIN_LUMA:
583 case VDP_VIDEO_MIXER_ATTRIBUTE_LUMA_KEY_MAX_LUMA:
584 *(float*)min_value = 0.f;
585 *(float*)max_value = 1.f;
586 break;
587 case VDP_VIDEO_MIXER_ATTRIBUTE_SHARPNESS_LEVEL:
588 *(float*)min_value = -1.f;
589 *(float*)max_value = 1.f;
590 break;
591 case VDP_VIDEO_MIXER_ATTRIBUTE_SKIP_CHROMA_DEINTERLACE:
592 *(uint8_t*)min_value = 0;
593 *(uint8_t*)max_value = 1;
594 break;
595 case VDP_VIDEO_MIXER_ATTRIBUTE_BACKGROUND_COLOR:
596 case VDP_VIDEO_MIXER_ATTRIBUTE_CSC_MATRIX:
597 default:
598 return VDP_STATUS_INVALID_VIDEO_MIXER_ATTRIBUTE;
599 }
600 return VDP_STATUS_OK;
601 }