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