dri_screen.c revision f8ee415e3c2fa8e475e9f7fad0315c06c232ff94
15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/************************************************************************** 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Copyright 2009, VMware, Inc. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * All Rights Reserved. 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Permission is hereby granted, free of charge, to any person obtaining a 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * copy of this software and associated documentation files (the 8868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) * "Software"), to deal in the Software without restriction, including 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * without limitation the rights to use, copy, modify, merge, publish, 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * distribute, sub license, and/or sell copies of the Software, and to 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * permit persons to whom the Software is furnished to do so, subject to 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * the following conditions: 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * The above copyright notice and this permission notice (including the 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * next paragraph) shall be included in all copies or substantial portions 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * of the Software. 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) **************************************************************************/ 27f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)/* 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Author: Keith Whitwell <keithw@vmware.com> 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Author: Jakob Bornecrantz <wallbraker@gmail.com> 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "utils.h" 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "xmlpool.h" 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "dri_screen.h" 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "util/u_inlines.h" 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "pipe/p_screen.h" 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "pipe/p_format.h" 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "state_tracker/st_gl_api.h" /* for st_gl_api_create */ 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "util/u_debug.h" 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)PUBLIC const char __driConfigOptions[] = 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DRI_CONF_BEGIN DRI_CONF_SECTION_PERFORMANCE 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DRI_CONF_FTHROTTLE_MODE(DRI_CONF_FTHROTTLE_IRQS) 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DRI_CONF_VBLANK_MODE(DRI_CONF_VBLANK_DEF_INTERVAL_0) 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DRI_CONF_SECTION_END DRI_CONF_SECTION_QUALITY 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* DRI_CONF_FORCE_S3TC_ENABLE(false) */ 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DRI_CONF_ALLOW_LARGE_TEXTURES(1) 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DRI_CONF_SECTION_END DRI_CONF_END; 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 53f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)static const uint __driNConfigOptions = 3; 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static const __DRIconfig ** 56a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)dri_fill_in_modes(struct dri_screen *screen, 57a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) unsigned pixel_bits) 582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles){ 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) __DRIconfig **configs = NULL; 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) __DRIconfig **configs_r5g6b5 = NULL; 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) __DRIconfig **configs_a8r8g8b8 = NULL; 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) __DRIconfig **configs_x8r8g8b8 = NULL; 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) uint8_t depth_bits_array[5]; 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) uint8_t stencil_bits_array[5]; 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) uint8_t msaa_samples_array[5]; 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned depth_buffer_factor; 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned back_buffer_factor; 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned msaa_samples_factor; 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned i; 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct pipe_screen *p_screen = screen->base.screen; 712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) boolean pf_r5g6b5, pf_a8r8g8b8, pf_x8r8g8b8; 722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) boolean pf_z16, pf_x8z24, pf_z24x8, pf_s8z24, pf_z24s8, pf_z32; 732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) static const GLenum back_buffer_modes[] = { 752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) GLX_NONE, GLX_SWAP_UNDEFINED_OML, GLX_SWAP_COPY_OML 762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) }; 772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) depth_bits_array[0] = 0; 792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) stencil_bits_array[0] = 0; 802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) depth_buffer_factor = 1; 812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 825f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) pf_x8z24 = p_screen->is_format_supported(p_screen, PIPE_FORMAT_Z24X8_UNORM, 835f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) PIPE_TEXTURE_2D, 0, 845f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) PIPE_BIND_DEPTH_STENCIL, 0); 855f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) pf_z24x8 = p_screen->is_format_supported(p_screen, PIPE_FORMAT_X8Z24_UNORM, 865f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) PIPE_TEXTURE_2D, 0, 875f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) PIPE_BIND_DEPTH_STENCIL, 0); 885f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) pf_s8z24 = p_screen->is_format_supported(p_screen, PIPE_FORMAT_Z24_UNORM_S8_USCALED, 895f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) PIPE_TEXTURE_2D, 0, 905f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) PIPE_BIND_DEPTH_STENCIL, 0); 915f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) pf_z24s8 = p_screen->is_format_supported(p_screen, PIPE_FORMAT_S8_USCALED_Z24_UNORM, 925f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) PIPE_TEXTURE_2D, 0, 93 PIPE_BIND_DEPTH_STENCIL, 0); 94 pf_a8r8g8b8 = p_screen->is_format_supported(p_screen, PIPE_FORMAT_B8G8R8A8_UNORM, 95 PIPE_TEXTURE_2D, 0, 96 PIPE_BIND_RENDER_TARGET, 0); 97 pf_x8r8g8b8 = p_screen->is_format_supported(p_screen, PIPE_FORMAT_B8G8R8X8_UNORM, 98 PIPE_TEXTURE_2D, 0, 99 PIPE_BIND_RENDER_TARGET, 0); 100 pf_r5g6b5 = p_screen->is_format_supported(p_screen, PIPE_FORMAT_B5G6R5_UNORM, 101 PIPE_TEXTURE_2D, 0, 102 PIPE_BIND_RENDER_TARGET, 0); 103 104 /* We can only get a 16 or 32 bit depth buffer with getBuffersWithFormat */ 105 if (dri_with_format(screen->sPriv)) { 106 pf_z16 = p_screen->is_format_supported(p_screen, PIPE_FORMAT_Z16_UNORM, 107 PIPE_TEXTURE_2D, 0, 108 PIPE_BIND_DEPTH_STENCIL, 0); 109 pf_z32 = p_screen->is_format_supported(p_screen, PIPE_FORMAT_Z32_UNORM, 110 PIPE_TEXTURE_2D, 0, 111 PIPE_BIND_DEPTH_STENCIL, 0); 112 } else { 113 pf_z16 = FALSE; 114 pf_z32 = FALSE; 115 } 116 117 if (pf_z16) { 118 depth_bits_array[depth_buffer_factor] = 16; 119 stencil_bits_array[depth_buffer_factor++] = 0; 120 } 121 if (pf_x8z24 || pf_z24x8) { 122 depth_bits_array[depth_buffer_factor] = 24; 123 stencil_bits_array[depth_buffer_factor++] = 0; 124 screen->d_depth_bits_last = pf_x8z24; 125 } 126 if (pf_s8z24 || pf_z24s8) { 127 depth_bits_array[depth_buffer_factor] = 24; 128 stencil_bits_array[depth_buffer_factor++] = 8; 129 screen->sd_depth_bits_last = pf_s8z24; 130 } 131 if (pf_z32) { 132 depth_bits_array[depth_buffer_factor] = 32; 133 stencil_bits_array[depth_buffer_factor++] = 0; 134 } 135 136 msaa_samples_array[0] = 0; 137 back_buffer_factor = 3; 138 139 /* also test color for msaa 2/4/6/8 - just assume it'll work for all depth buffers */ 140 if (pf_r5g6b5) { 141 msaa_samples_factor = 1; 142 for (i = 1; i < 5; i++) { 143 if (p_screen->is_format_supported(p_screen, PIPE_FORMAT_B5G6R5_UNORM, 144 PIPE_TEXTURE_2D, i*2, 145 PIPE_BIND_RENDER_TARGET, 0)) { 146 msaa_samples_array[msaa_samples_factor] = i * 2; 147 msaa_samples_factor++; 148 } 149 } 150 151 configs_r5g6b5 = driCreateConfigs(GL_RGB, GL_UNSIGNED_SHORT_5_6_5, 152 depth_bits_array, stencil_bits_array, 153 depth_buffer_factor, back_buffer_modes, 154 back_buffer_factor, 155 msaa_samples_array, msaa_samples_factor, 156 GL_TRUE); 157 } 158 159 if (pf_a8r8g8b8) { 160 msaa_samples_factor = 1; 161 for (i = 1; i < 5; i++) { 162 if (p_screen->is_format_supported(p_screen, PIPE_FORMAT_B8G8R8A8_UNORM, 163 PIPE_TEXTURE_2D, i*2, 164 PIPE_BIND_RENDER_TARGET, 0)) { 165 msaa_samples_array[msaa_samples_factor] = i * 2; 166 msaa_samples_factor++; 167 } 168 } 169 170 configs_a8r8g8b8 = driCreateConfigs(GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, 171 depth_bits_array, 172 stencil_bits_array, 173 depth_buffer_factor, 174 back_buffer_modes, 175 back_buffer_factor, 176 msaa_samples_array, 177 msaa_samples_factor, 178 GL_TRUE); 179 } 180 181 if (pf_x8r8g8b8) { 182 msaa_samples_factor = 1; 183 for (i = 1; i < 5; i++) { 184 if (p_screen->is_format_supported(p_screen, PIPE_FORMAT_B8G8R8X8_UNORM, 185 PIPE_TEXTURE_2D, i*2, 186 PIPE_BIND_RENDER_TARGET, 0)) { 187 msaa_samples_array[msaa_samples_factor] = i * 2; 188 msaa_samples_factor++; 189 } 190 } 191 192 configs_x8r8g8b8 = driCreateConfigs(GL_BGR, GL_UNSIGNED_INT_8_8_8_8_REV, 193 depth_bits_array, 194 stencil_bits_array, 195 depth_buffer_factor, 196 back_buffer_modes, 197 back_buffer_factor, 198 msaa_samples_array, 199 msaa_samples_factor, 200 GL_TRUE); 201 } 202 203 if (pixel_bits == 16) { 204 configs = configs_r5g6b5; 205 if (configs_a8r8g8b8) 206 configs = configs ? driConcatConfigs(configs, configs_a8r8g8b8) : configs_a8r8g8b8; 207 if (configs_x8r8g8b8) 208 configs = configs ? driConcatConfigs(configs, configs_x8r8g8b8) : configs_x8r8g8b8; 209 } else { 210 configs = configs_a8r8g8b8; 211 if (configs_x8r8g8b8) 212 configs = configs ? driConcatConfigs(configs, configs_x8r8g8b8) : configs_x8r8g8b8; 213 if (configs_r5g6b5) 214 configs = configs ? driConcatConfigs(configs, configs_r5g6b5) : configs_r5g6b5; 215 } 216 217 if (configs == NULL) { 218 debug_printf("%s: driCreateConfigs failed\n", __FUNCTION__); 219 return NULL; 220 } 221 222 return (const __DRIconfig **)configs; 223} 224 225/** 226 * Roughly the converse of dri_fill_in_modes. 227 */ 228void 229dri_fill_st_visual(struct st_visual *stvis, struct dri_screen *screen, 230 const __GLcontextModes *mode) 231{ 232 memset(stvis, 0, sizeof(*stvis)); 233 234 stvis->samples = mode->samples; 235 stvis->render_buffer = ST_ATTACHMENT_INVALID; 236 237 if (mode->redBits == 8) { 238 if (mode->alphaBits == 8) 239 stvis->color_format = PIPE_FORMAT_B8G8R8A8_UNORM; 240 else 241 stvis->color_format = PIPE_FORMAT_B8G8R8X8_UNORM; 242 } else { 243 stvis->color_format = PIPE_FORMAT_B5G6R5_UNORM; 244 } 245 246 switch (mode->depthBits) { 247 default: 248 case 0: 249 stvis->depth_stencil_format = PIPE_FORMAT_NONE; 250 break; 251 case 16: 252 stvis->depth_stencil_format = PIPE_FORMAT_Z16_UNORM; 253 break; 254 case 24: 255 if (mode->stencilBits == 0) { 256 stvis->depth_stencil_format = (screen->d_depth_bits_last) ? 257 PIPE_FORMAT_Z24X8_UNORM: 258 PIPE_FORMAT_X8Z24_UNORM; 259 } else { 260 stvis->depth_stencil_format = (screen->sd_depth_bits_last) ? 261 PIPE_FORMAT_Z24_UNORM_S8_USCALED: 262 PIPE_FORMAT_S8_USCALED_Z24_UNORM; 263 } 264 break; 265 case 32: 266 stvis->depth_stencil_format = PIPE_FORMAT_Z32_UNORM; 267 break; 268 } 269 270 stvis->accum_format = (mode->haveAccumBuffer) ? 271 PIPE_FORMAT_R16G16B16A16_SNORM : PIPE_FORMAT_NONE; 272 273 stvis->buffer_mask |= ST_ATTACHMENT_FRONT_LEFT_MASK; 274 if (mode->doubleBufferMode) 275 stvis->buffer_mask |= ST_ATTACHMENT_BACK_LEFT_MASK; 276 if (mode->stereoMode) { 277 stvis->buffer_mask |= ST_ATTACHMENT_FRONT_RIGHT_MASK; 278 if (mode->doubleBufferMode) 279 stvis->buffer_mask |= ST_ATTACHMENT_BACK_RIGHT_MASK; 280 } 281 282 if (mode->haveDepthBuffer || mode->haveStencilBuffer) 283 stvis->buffer_mask |= ST_ATTACHMENT_DEPTH_STENCIL_MASK; 284 /* let the state tracker allocate the accum buffer */ 285} 286 287static boolean 288dri_get_egl_image(struct st_manager *smapi, 289 void *egl_image, 290 struct st_egl_image *stimg) 291{ 292 struct dri_screen *screen = (struct dri_screen *)smapi; 293 __DRIimage *img = NULL; 294 295 if (screen->lookup_egl_image) { 296 img = screen->lookup_egl_image(screen, egl_image); 297 } 298 299 if (!img) 300 return FALSE; 301 302 stimg->texture = NULL; 303 pipe_resource_reference(&stimg->texture, img->texture); 304 stimg->face = img->face; 305 stimg->level = img->level; 306 stimg->zslice = img->zslice; 307 308 return TRUE; 309} 310 311static int 312dri_get_param(struct st_manager *smapi, 313 enum st_manager_param param) 314{ 315 struct dri_screen *screen = (struct dri_screen *)smapi; 316 317 switch(param) { 318 case ST_MANAGER_BROKEN_INVALIDATE: 319 return screen->broken_invalidate; 320 default: 321 return 0; 322 } 323} 324 325static void 326dri_destroy_option_cache(struct dri_screen * screen) 327{ 328 int i; 329 330 if (screen->optionCache.info) { 331 for (i = 0; i < (1 << screen->optionCache.tableSize); ++i) { 332 FREE(screen->optionCache.info[i].name); 333 FREE(screen->optionCache.info[i].ranges); 334 } 335 FREE(screen->optionCache.info); 336 } 337 338 FREE(screen->optionCache.values); 339} 340 341void 342dri_destroy_screen_helper(struct dri_screen * screen) 343{ 344 if (screen->st_api && screen->st_api->destroy) 345 screen->st_api->destroy(screen->st_api); 346 347 if (screen->base.screen) 348 screen->base.screen->destroy(screen->base.screen); 349 350 dri_destroy_option_cache(screen); 351} 352 353void 354dri_destroy_screen(__DRIscreen * sPriv) 355{ 356 struct dri_screen *screen = dri_screen(sPriv); 357 358 dri_destroy_screen_helper(screen); 359 360 FREE(screen); 361 sPriv->private = NULL; 362 sPriv->extensions = NULL; 363} 364 365const __DRIconfig ** 366dri_init_screen_helper(struct dri_screen *screen, 367 struct pipe_screen *pscreen, 368 unsigned pixel_bits) 369{ 370 screen->base.screen = pscreen; 371 if (!screen->base.screen) { 372 debug_printf("%s: failed to create pipe_screen\n", __FUNCTION__); 373 return NULL; 374 } 375 376 screen->base.get_egl_image = dri_get_egl_image; 377 screen->base.get_param = dri_get_param; 378 379 screen->st_api = st_gl_api_create(); 380 if (!screen->st_api) 381 return NULL; 382 383 if(pscreen->get_param(pscreen, PIPE_CAP_NPOT_TEXTURES)) 384 screen->target = PIPE_TEXTURE_2D; 385 else 386 screen->target = PIPE_TEXTURE_RECT; 387 388 driParseOptionInfo(&screen->optionCache, 389 __driConfigOptions, __driNConfigOptions); 390 391 return dri_fill_in_modes(screen, pixel_bits); 392} 393 394/* vim: set sw=3 ts=8 sts=3 expandtab: */ 395