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