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