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