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