1/************************************************************************** 2 * 3 * Copyright 2009, VMware, Inc. 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 VMWARE 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 * Author: Keith Whitwell <keithw@vmware.com> 29 * Author: Jakob Bornecrantz <wallbraker@gmail.com> 30 */ 31 32#include "utils.h" 33 34#include "dri_screen.h" 35#include "dri_context.h" 36 37#include "util/u_inlines.h" 38#include "pipe/p_screen.h" 39#include "pipe/p_format.h" 40#include "pipe-loader/pipe_loader.h" 41#include "state_tracker/st_gl_api.h" /* for st_gl_api_create */ 42#include "state_tracker/drm_driver.h" 43 44#include "util/u_debug.h" 45#include "util/u_format_s3tc.h" 46 47#define MSAA_VISUAL_MAX_SAMPLES 32 48 49#undef false 50 51const __DRIconfigOptionsExtension gallium_config_options = { 52 .base = { __DRI_CONFIG_OPTIONS, 2 }, 53 .xml = gallium_driinfo_xml, 54 .getXml = pipe_loader_get_driinfo_xml 55}; 56 57#define false 0 58 59static void 60dri_fill_st_options(struct dri_screen *screen) 61{ 62 struct st_config_options *options = &screen->options; 63 const struct driOptionCache *optionCache = &screen->dev->option_cache; 64 65 options->disable_blend_func_extended = 66 driQueryOptionb(optionCache, "disable_blend_func_extended"); 67 options->disable_glsl_line_continuations = 68 driQueryOptionb(optionCache, "disable_glsl_line_continuations"); 69 options->force_glsl_extensions_warn = 70 driQueryOptionb(optionCache, "force_glsl_extensions_warn"); 71 options->force_glsl_version = 72 driQueryOptioni(optionCache, "force_glsl_version"); 73 options->allow_glsl_extension_directive_midshader = 74 driQueryOptionb(optionCache, "allow_glsl_extension_directive_midshader"); 75 options->allow_glsl_builtin_const_expression = 76 driQueryOptionb(optionCache, "allow_glsl_builtin_const_expression"); 77 options->allow_glsl_relaxed_es = 78 driQueryOptionb(optionCache, "allow_glsl_relaxed_es"); 79 options->allow_glsl_builtin_variable_redeclaration = 80 driQueryOptionb(optionCache, "allow_glsl_builtin_variable_redeclaration"); 81 options->allow_higher_compat_version = 82 driQueryOptionb(optionCache, "allow_higher_compat_version"); 83 options->glsl_zero_init = driQueryOptionb(optionCache, "glsl_zero_init"); 84 options->force_glsl_abs_sqrt = 85 driQueryOptionb(optionCache, "force_glsl_abs_sqrt"); 86 options->allow_glsl_cross_stage_interpolation_mismatch = 87 driQueryOptionb(optionCache, "allow_glsl_cross_stage_interpolation_mismatch"); 88 options->allow_glsl_layout_qualifier_on_function_parameters = 89 driQueryOptionb(optionCache, "allow_glsl_layout_qualifier_on_function_parameters"); 90 91 driComputeOptionsSha1(optionCache, options->config_options_sha1); 92} 93 94static unsigned 95dri_loader_get_cap(struct dri_screen *screen, enum dri_loader_cap cap) 96{ 97 const __DRIdri2LoaderExtension *dri2_loader = screen->sPriv->dri2.loader; 98 const __DRIimageLoaderExtension *image_loader = screen->sPriv->image.loader; 99 100 if (dri2_loader && dri2_loader->base.version >= 4 && 101 dri2_loader->getCapability) 102 return dri2_loader->getCapability(screen->sPriv->loaderPrivate, cap); 103 104 if (image_loader && image_loader->base.version >= 2 && 105 image_loader->getCapability) 106 return image_loader->getCapability(screen->sPriv->loaderPrivate, cap); 107 108 return 0; 109} 110 111static const __DRIconfig ** 112dri_fill_in_modes(struct dri_screen *screen) 113{ 114 static const mesa_format mesa_formats[] = { 115 MESA_FORMAT_B10G10R10A2_UNORM, 116 MESA_FORMAT_B10G10R10X2_UNORM, 117 MESA_FORMAT_R10G10B10A2_UNORM, 118 MESA_FORMAT_R10G10B10X2_UNORM, 119 MESA_FORMAT_B8G8R8A8_UNORM, 120 MESA_FORMAT_B8G8R8X8_UNORM, 121 MESA_FORMAT_B8G8R8A8_SRGB, 122 MESA_FORMAT_B8G8R8X8_SRGB, 123 MESA_FORMAT_B5G6R5_UNORM, 124 125 /* The 32-bit RGBA format must not precede the 32-bit BGRA format. 126 * Likewise for RGBX and BGRX. Otherwise, the GLX client and the GLX 127 * server may disagree on which format the GLXFBConfig represents, 128 * resulting in swapped color channels. 129 * 130 * The problem, as of 2017-05-30: 131 * When matching a GLXFBConfig to a __DRIconfig, GLX ignores the channel 132 * order and chooses the first __DRIconfig with the expected channel 133 * sizes. Specifically, GLX compares the GLXFBConfig's and __DRIconfig's 134 * __DRI_ATTRIB_{CHANNEL}_SIZE but ignores __DRI_ATTRIB_{CHANNEL}_MASK. 135 * 136 * EGL does not suffer from this problem. It correctly compares the 137 * channel masks when matching EGLConfig to __DRIconfig. 138 */ 139 140 /* Required by Android, for HAL_PIXEL_FORMAT_RGBA_8888. */ 141 MESA_FORMAT_R8G8B8A8_UNORM, 142 143 /* Required by Android, for HAL_PIXEL_FORMAT_RGBX_8888. */ 144 MESA_FORMAT_R8G8B8X8_UNORM, 145 }; 146 static const enum pipe_format pipe_formats[] = { 147 PIPE_FORMAT_B10G10R10A2_UNORM, 148 PIPE_FORMAT_B10G10R10X2_UNORM, 149 PIPE_FORMAT_R10G10B10A2_UNORM, 150 PIPE_FORMAT_R10G10B10X2_UNORM, 151 PIPE_FORMAT_BGRA8888_UNORM, 152 PIPE_FORMAT_BGRX8888_UNORM, 153 PIPE_FORMAT_BGRA8888_SRGB, 154 PIPE_FORMAT_BGRX8888_SRGB, 155 PIPE_FORMAT_B5G6R5_UNORM, 156 PIPE_FORMAT_RGBA8888_UNORM, 157 PIPE_FORMAT_RGBX8888_UNORM, 158 }; 159 mesa_format format; 160 __DRIconfig **configs = NULL; 161 uint8_t depth_bits_array[5]; 162 uint8_t stencil_bits_array[5]; 163 unsigned depth_buffer_factor; 164 unsigned msaa_samples_max; 165 unsigned i; 166 struct pipe_screen *p_screen = screen->base.screen; 167 boolean pf_z16, pf_x8z24, pf_z24x8, pf_s8z24, pf_z24s8, pf_z32; 168 boolean mixed_color_depth; 169 boolean allow_rgb10; 170 171 static const GLenum back_buffer_modes[] = { 172 __DRI_ATTRIB_SWAP_NONE, __DRI_ATTRIB_SWAP_UNDEFINED, 173 __DRI_ATTRIB_SWAP_COPY 174 }; 175 176 if (driQueryOptionb(&screen->dev->option_cache, "always_have_depth_buffer")) { 177 /* all visuals will have a depth buffer */ 178 depth_buffer_factor = 0; 179 } 180 else { 181 depth_bits_array[0] = 0; 182 stencil_bits_array[0] = 0; 183 depth_buffer_factor = 1; 184 } 185 186 allow_rgb10 = driQueryOptionb(&screen->dev->option_cache, "allow_rgb10_configs"); 187 188 msaa_samples_max = (screen->st_api->feature_mask & ST_API_FEATURE_MS_VISUALS_MASK) 189 ? MSAA_VISUAL_MAX_SAMPLES : 1; 190 191 pf_x8z24 = p_screen->is_format_supported(p_screen, PIPE_FORMAT_Z24X8_UNORM, 192 PIPE_TEXTURE_2D, 0, 0, 193 PIPE_BIND_DEPTH_STENCIL); 194 pf_z24x8 = p_screen->is_format_supported(p_screen, PIPE_FORMAT_X8Z24_UNORM, 195 PIPE_TEXTURE_2D, 0, 0, 196 PIPE_BIND_DEPTH_STENCIL); 197 pf_s8z24 = p_screen->is_format_supported(p_screen, PIPE_FORMAT_Z24_UNORM_S8_UINT, 198 PIPE_TEXTURE_2D, 0, 0, 199 PIPE_BIND_DEPTH_STENCIL); 200 pf_z24s8 = p_screen->is_format_supported(p_screen, PIPE_FORMAT_S8_UINT_Z24_UNORM, 201 PIPE_TEXTURE_2D, 0, 0, 202 PIPE_BIND_DEPTH_STENCIL); 203 pf_z16 = p_screen->is_format_supported(p_screen, PIPE_FORMAT_Z16_UNORM, 204 PIPE_TEXTURE_2D, 0, 0, 205 PIPE_BIND_DEPTH_STENCIL); 206 pf_z32 = p_screen->is_format_supported(p_screen, PIPE_FORMAT_Z32_UNORM, 207 PIPE_TEXTURE_2D, 0, 0, 208 PIPE_BIND_DEPTH_STENCIL); 209 210 if (pf_z16) { 211 depth_bits_array[depth_buffer_factor] = 16; 212 stencil_bits_array[depth_buffer_factor++] = 0; 213 } 214 if (pf_x8z24 || pf_z24x8) { 215 depth_bits_array[depth_buffer_factor] = 24; 216 stencil_bits_array[depth_buffer_factor++] = 0; 217 screen->d_depth_bits_last = pf_x8z24; 218 } 219 if (pf_s8z24 || pf_z24s8) { 220 depth_bits_array[depth_buffer_factor] = 24; 221 stencil_bits_array[depth_buffer_factor++] = 8; 222 screen->sd_depth_bits_last = pf_s8z24; 223 } 224 if (pf_z32) { 225 depth_bits_array[depth_buffer_factor] = 32; 226 stencil_bits_array[depth_buffer_factor++] = 0; 227 } 228 229 mixed_color_depth = 230 p_screen->get_param(p_screen, PIPE_CAP_MIXED_COLOR_DEPTH_BITS); 231 232 assert(ARRAY_SIZE(mesa_formats) == ARRAY_SIZE(pipe_formats)); 233 234 /* Expose only BGRA ordering if the loader doesn't support RGBA ordering. */ 235 unsigned num_formats; 236 if (dri_loader_get_cap(screen, DRI_LOADER_CAP_RGBA_ORDERING)) 237 num_formats = ARRAY_SIZE(mesa_formats); 238 else 239 num_formats = ARRAY_SIZE(mesa_formats) - 2; /* all - RGBA_ORDERING formats */ 240 241 /* Add configs. */ 242 for (format = 0; format < num_formats; format++) { 243 __DRIconfig **new_configs = NULL; 244 unsigned num_msaa_modes = 0; /* includes a single-sample mode */ 245 uint8_t msaa_modes[MSAA_VISUAL_MAX_SAMPLES]; 246 247 if (!allow_rgb10 && 248 (mesa_formats[format] == MESA_FORMAT_B10G10R10A2_UNORM || 249 mesa_formats[format] == MESA_FORMAT_B10G10R10X2_UNORM || 250 mesa_formats[format] == MESA_FORMAT_R10G10B10A2_UNORM || 251 mesa_formats[format] == MESA_FORMAT_R10G10B10X2_UNORM)) 252 continue; 253 254 if (!p_screen->is_format_supported(p_screen, pipe_formats[format], 255 PIPE_TEXTURE_2D, 0, 0, 256 PIPE_BIND_RENDER_TARGET | 257 PIPE_BIND_DISPLAY_TARGET)) 258 continue; 259 260 for (i = 1; i <= msaa_samples_max; i++) { 261 int samples = i > 1 ? i : 0; 262 263 if (p_screen->is_format_supported(p_screen, pipe_formats[format], 264 PIPE_TEXTURE_2D, samples, samples, 265 PIPE_BIND_RENDER_TARGET)) { 266 msaa_modes[num_msaa_modes++] = samples; 267 } 268 } 269 270 if (num_msaa_modes) { 271 /* Single-sample configs with an accumulation buffer. */ 272 new_configs = driCreateConfigs(mesa_formats[format], 273 depth_bits_array, stencil_bits_array, 274 depth_buffer_factor, back_buffer_modes, 275 ARRAY_SIZE(back_buffer_modes), 276 msaa_modes, 1, 277 GL_TRUE, !mixed_color_depth, GL_FALSE); 278 configs = driConcatConfigs(configs, new_configs); 279 280 /* Multi-sample configs without an accumulation buffer. */ 281 if (num_msaa_modes > 1) { 282 new_configs = driCreateConfigs(mesa_formats[format], 283 depth_bits_array, stencil_bits_array, 284 depth_buffer_factor, back_buffer_modes, 285 ARRAY_SIZE(back_buffer_modes), 286 msaa_modes+1, num_msaa_modes-1, 287 GL_FALSE, !mixed_color_depth, GL_FALSE); 288 configs = driConcatConfigs(configs, new_configs); 289 } 290 } 291 } 292 293 if (configs == NULL) { 294 debug_printf("%s: driCreateConfigs failed\n", __FUNCTION__); 295 return NULL; 296 } 297 298 return (const __DRIconfig **)configs; 299} 300 301/** 302 * Roughly the converse of dri_fill_in_modes. 303 */ 304void 305dri_fill_st_visual(struct st_visual *stvis, 306 const struct dri_screen *screen, 307 const struct gl_config *mode) 308{ 309 memset(stvis, 0, sizeof(*stvis)); 310 311 if (!mode) { 312 stvis->no_config = true; 313 return; 314 } 315 316 /* Deduce the color format. */ 317 switch (mode->redMask) { 318 case 0x3FF00000: 319 if (mode->alphaMask) { 320 assert(mode->alphaMask == 0xC0000000); 321 stvis->color_format = PIPE_FORMAT_B10G10R10A2_UNORM; 322 } else { 323 stvis->color_format = PIPE_FORMAT_B10G10R10X2_UNORM; 324 } 325 break; 326 327 case 0x000003FF: 328 if (mode->alphaMask) { 329 assert(mode->alphaMask == 0xC0000000); 330 stvis->color_format = PIPE_FORMAT_R10G10B10A2_UNORM; 331 } else { 332 stvis->color_format = PIPE_FORMAT_R10G10B10X2_UNORM; 333 } 334 break; 335 336 case 0x00FF0000: 337 if (mode->alphaMask) { 338 assert(mode->alphaMask == 0xFF000000); 339 stvis->color_format = mode->sRGBCapable ? 340 PIPE_FORMAT_BGRA8888_SRGB : 341 PIPE_FORMAT_BGRA8888_UNORM; 342 } else { 343 stvis->color_format = mode->sRGBCapable ? 344 PIPE_FORMAT_BGRX8888_SRGB : 345 PIPE_FORMAT_BGRX8888_UNORM; 346 } 347 break; 348 349 case 0x000000FF: 350 if (mode->alphaMask) { 351 assert(mode->alphaMask == 0xFF000000); 352 stvis->color_format = mode->sRGBCapable ? 353 PIPE_FORMAT_RGBA8888_SRGB : 354 PIPE_FORMAT_RGBA8888_UNORM; 355 } else { 356 stvis->color_format = mode->sRGBCapable ? 357 PIPE_FORMAT_RGBX8888_SRGB : 358 PIPE_FORMAT_RGBX8888_UNORM; 359 } 360 break; 361 362 case 0x0000F800: 363 stvis->color_format = PIPE_FORMAT_B5G6R5_UNORM; 364 break; 365 366 default: 367 assert(!"unsupported visual: invalid red mask"); 368 return; 369 } 370 371 if (mode->sampleBuffers) { 372 stvis->samples = mode->samples; 373 } 374 375 switch (mode->depthBits) { 376 default: 377 case 0: 378 stvis->depth_stencil_format = PIPE_FORMAT_NONE; 379 break; 380 case 16: 381 stvis->depth_stencil_format = PIPE_FORMAT_Z16_UNORM; 382 break; 383 case 24: 384 if (mode->stencilBits == 0) { 385 stvis->depth_stencil_format = (screen->d_depth_bits_last) ? 386 PIPE_FORMAT_Z24X8_UNORM: 387 PIPE_FORMAT_X8Z24_UNORM; 388 } else { 389 stvis->depth_stencil_format = (screen->sd_depth_bits_last) ? 390 PIPE_FORMAT_Z24_UNORM_S8_UINT: 391 PIPE_FORMAT_S8_UINT_Z24_UNORM; 392 } 393 break; 394 case 32: 395 stvis->depth_stencil_format = PIPE_FORMAT_Z32_UNORM; 396 break; 397 } 398 399 stvis->accum_format = (mode->haveAccumBuffer) ? 400 PIPE_FORMAT_R16G16B16A16_SNORM : PIPE_FORMAT_NONE; 401 402 stvis->buffer_mask |= ST_ATTACHMENT_FRONT_LEFT_MASK; 403 stvis->render_buffer = ST_ATTACHMENT_FRONT_LEFT; 404 if (mode->doubleBufferMode) { 405 stvis->buffer_mask |= ST_ATTACHMENT_BACK_LEFT_MASK; 406 stvis->render_buffer = ST_ATTACHMENT_BACK_LEFT; 407 } 408 if (mode->stereoMode) { 409 stvis->buffer_mask |= ST_ATTACHMENT_FRONT_RIGHT_MASK; 410 if (mode->doubleBufferMode) 411 stvis->buffer_mask |= ST_ATTACHMENT_BACK_RIGHT_MASK; 412 } 413 414 if (mode->haveDepthBuffer || mode->haveStencilBuffer) 415 stvis->buffer_mask |= ST_ATTACHMENT_DEPTH_STENCIL_MASK; 416 /* let the state tracker allocate the accum buffer */ 417} 418 419static boolean 420dri_get_egl_image(struct st_manager *smapi, 421 void *egl_image, 422 struct st_egl_image *stimg) 423{ 424 struct dri_screen *screen = (struct dri_screen *)smapi; 425 __DRIimage *img = NULL; 426 427 if (screen->lookup_egl_image) { 428 img = screen->lookup_egl_image(screen, egl_image); 429 } 430 431 if (!img) 432 return FALSE; 433 434 stimg->texture = NULL; 435 pipe_resource_reference(&stimg->texture, img->texture); 436 switch (img->dri_components) { 437 case __DRI_IMAGE_COMPONENTS_Y_U_V: 438 stimg->format = PIPE_FORMAT_IYUV; 439 break; 440 case __DRI_IMAGE_COMPONENTS_Y_UV: 441 stimg->format = PIPE_FORMAT_NV12; 442 break; 443 default: 444 stimg->format = img->texture->format; 445 break; 446 } 447 stimg->level = img->level; 448 stimg->layer = img->layer; 449 450 return TRUE; 451} 452 453static int 454dri_get_param(struct st_manager *smapi, 455 enum st_manager_param param) 456{ 457 struct dri_screen *screen = (struct dri_screen *)smapi; 458 459 switch(param) { 460 case ST_MANAGER_BROKEN_INVALIDATE: 461 return screen->broken_invalidate; 462 default: 463 return 0; 464 } 465} 466 467void 468dri_destroy_screen_helper(struct dri_screen * screen) 469{ 470 if (screen->base.destroy) 471 screen->base.destroy(&screen->base); 472 473 if (screen->st_api && screen->st_api->destroy) 474 screen->st_api->destroy(screen->st_api); 475 476 if (screen->base.screen) 477 screen->base.screen->destroy(screen->base.screen); 478 479 mtx_destroy(&screen->opencl_func_mutex); 480} 481 482void 483dri_destroy_screen(__DRIscreen * sPriv) 484{ 485 struct dri_screen *screen = dri_screen(sPriv); 486 487 dri_destroy_screen_helper(screen); 488 489 pipe_loader_release(&screen->dev, 1); 490 491 /* The caller in dri_util preserves the fd ownership */ 492 free(screen); 493 sPriv->driverPrivate = NULL; 494 sPriv->extensions = NULL; 495} 496 497static void 498dri_postprocessing_init(struct dri_screen *screen) 499{ 500 unsigned i; 501 502 for (i = 0; i < PP_FILTERS; i++) { 503 screen->pp_enabled[i] = driQueryOptioni(&screen->dev->option_cache, 504 pp_filters[i].name); 505 } 506} 507 508static void 509dri_set_background_context(struct st_context_iface *st, 510 struct util_queue_monitoring *queue_info) 511{ 512 struct dri_context *ctx = (struct dri_context *)st->st_manager_private; 513 const __DRIbackgroundCallableExtension *backgroundCallable = 514 ctx->sPriv->dri2.backgroundCallable; 515 516 /* Note: Mesa will only call this function if GL multithreading is enabled 517 * We only do that if the loader exposed the __DRI_BACKGROUND_CALLABLE 518 * extension. So we know that backgroundCallable is not NULL. 519 */ 520 assert(backgroundCallable); 521 backgroundCallable->setBackgroundContext(ctx->cPriv->loaderPrivate); 522 523 if (ctx->hud) 524 hud_add_queue_for_monitoring(ctx->hud, queue_info); 525} 526 527void 528dri_init_options(struct dri_screen *screen) 529{ 530 pipe_loader_load_options(screen->dev); 531 532 dri_fill_st_options(screen); 533} 534 535const __DRIconfig ** 536dri_init_screen_helper(struct dri_screen *screen, 537 struct pipe_screen *pscreen) 538{ 539 screen->base.screen = pscreen; 540 screen->base.get_egl_image = dri_get_egl_image; 541 screen->base.get_param = dri_get_param; 542 screen->base.set_background_context = dri_set_background_context; 543 544 screen->st_api = st_gl_api_create(); 545 if (!screen->st_api) 546 return NULL; 547 548 if(pscreen->get_param(pscreen, PIPE_CAP_NPOT_TEXTURES)) 549 screen->target = PIPE_TEXTURE_2D; 550 else 551 screen->target = PIPE_TEXTURE_RECT; 552 553 dri_postprocessing_init(screen); 554 555 screen->st_api->query_versions(screen->st_api, &screen->base, 556 &screen->options, 557 &screen->sPriv->max_gl_core_version, 558 &screen->sPriv->max_gl_compat_version, 559 &screen->sPriv->max_gl_es1_version, 560 &screen->sPriv->max_gl_es2_version); 561 562 return dri_fill_in_modes(screen); 563} 564 565/* vim: set sw=3 ts=8 sts=3 expandtab: */ 566