dri_screen.c revision 4a5acc0ec7d6d94ea2a73b3d8ee498f75e929a1c
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 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * "Software"), to deal in the Software without restriction, including 9424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (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 122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * the following conditions: 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (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 167dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch * of the Software. 177dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch * 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 207dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch * 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) **************************************************************************/ 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* 287dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch * Author: Keith Whitwell <keithw@vmware.com> 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Author: Jakob Bornecrantz <wallbraker@gmail.com> 30424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) */ 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 327dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "utils.h" 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "xmlpool.h" 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "dri_screen.h" 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "dri_context.h" 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "util/u_inlines.h" 393240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch#include "pipe/p_screen.h" 403240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch#include "pipe/p_format.h" 413240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch#include "state_tracker/st_gl_api.h" /* for st_gl_api_create */ 423240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch 433240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch#include "util/u_debug.h" 447dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 457dbb3d5cf0c15f500944d211057644d6a2f37371Ben MurdochPUBLIC const char __driConfigOptions[] = 467dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch DRI_CONF_BEGIN DRI_CONF_SECTION_PERFORMANCE 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DRI_CONF_FTHROTTLE_MODE(DRI_CONF_FTHROTTLE_IRQS) 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DRI_CONF_VBLANK_MODE(DRI_CONF_VBLANK_DEF_INTERVAL_0) 497dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch DRI_CONF_SECTION_END DRI_CONF_SECTION_QUALITY 507dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch/* DRI_CONF_FORCE_S3TC_ENABLE(false) */ 517dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch DRI_CONF_ALLOW_LARGE_TEXTURES(1) 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DRI_CONF_SECTION_END DRI_CONF_END; 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 547dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochstatic const uint __driNConfigOptions = 3; 557dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static const __DRIconfig ** 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)dri_fill_in_modes(struct dri_screen *screen, 587dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch unsigned pixel_bits) 597dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch{ 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) __DRIconfig **configs = NULL; 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) __DRIconfig **configs_r5g6b5 = NULL; 622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) __DRIconfig **configs_a8r8g8b8 = NULL; 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) __DRIconfig **configs_x8r8g8b8 = NULL; 647dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch uint8_t depth_bits_array[5]; 65424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) uint8_t stencil_bits_array[5]; 66424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) uint8_t msaa_samples_array[5]; 677dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch unsigned depth_buffer_factor; 687dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch unsigned back_buffer_factor; 697dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch unsigned msaa_samples_factor; 707dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch unsigned i; 717dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch struct pipe_screen *p_screen = screen->base.screen; 727dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch boolean pf_r5g6b5, pf_a8r8g8b8, pf_x8r8g8b8; 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) boolean pf_z16, pf_x8z24, pf_z24x8, pf_s8z24, pf_z24s8, pf_z32; 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static const GLenum back_buffer_modes[] = { 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GLX_NONE, GLX_SWAP_UNDEFINED_OML, GLX_SWAP_COPY_OML 773240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch }; 783240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch 793240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch depth_bits_array[0] = 0; 803240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch stencil_bits_array[0] = 0; 81424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) depth_buffer_factor = 1; 827dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 837dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch pf_x8z24 = p_screen->is_format_supported(p_screen, PIPE_FORMAT_Z24X8_UNORM, 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PIPE_TEXTURE_2D, 0, 857dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch PIPE_BIND_DEPTH_STENCIL, 0); 867dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch pf_z24x8 = p_screen->is_format_supported(p_screen, PIPE_FORMAT_X8Z24_UNORM, 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PIPE_TEXTURE_2D, 0, 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PIPE_BIND_DEPTH_STENCIL, 0); 897dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch pf_s8z24 = p_screen->is_format_supported(p_screen, PIPE_FORMAT_Z24_UNORM_S8_USCALED, 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PIPE_TEXTURE_2D, 0, 91 PIPE_BIND_DEPTH_STENCIL, 0); 92 pf_z24s8 = p_screen->is_format_supported(p_screen, PIPE_FORMAT_S8_USCALED_Z24_UNORM, 93 PIPE_TEXTURE_2D, 0, 94 PIPE_BIND_DEPTH_STENCIL, 0); 95 pf_a8r8g8b8 = p_screen->is_format_supported(p_screen, PIPE_FORMAT_B8G8R8A8_UNORM, 96 PIPE_TEXTURE_2D, 0, 97 PIPE_BIND_RENDER_TARGET, 0); 98 pf_x8r8g8b8 = p_screen->is_format_supported(p_screen, PIPE_FORMAT_B8G8R8X8_UNORM, 99 PIPE_TEXTURE_2D, 0, 100 PIPE_BIND_RENDER_TARGET, 0); 101 pf_r5g6b5 = p_screen->is_format_supported(p_screen, PIPE_FORMAT_B5G6R5_UNORM, 102 PIPE_TEXTURE_2D, 0, 103 PIPE_BIND_RENDER_TARGET, 0); 104 105 /* We can only get a 16 or 32 bit depth buffer with getBuffersWithFormat */ 106 if (dri_with_format(screen->sPriv)) { 107 pf_z16 = p_screen->is_format_supported(p_screen, PIPE_FORMAT_Z16_UNORM, 108 PIPE_TEXTURE_2D, 0, 109 PIPE_BIND_DEPTH_STENCIL, 0); 110 pf_z32 = p_screen->is_format_supported(p_screen, PIPE_FORMAT_Z32_UNORM, 111 PIPE_TEXTURE_2D, 0, 112 PIPE_BIND_DEPTH_STENCIL, 0); 113 } else { 114 pf_z16 = FALSE; 115 pf_z32 = FALSE; 116 } 117 118 if (pf_z16) { 119 depth_bits_array[depth_buffer_factor] = 16; 120 stencil_bits_array[depth_buffer_factor++] = 0; 121 } 122 if (pf_x8z24 || pf_z24x8) { 123 depth_bits_array[depth_buffer_factor] = 24; 124 stencil_bits_array[depth_buffer_factor++] = 0; 125 screen->d_depth_bits_last = pf_x8z24; 126 } 127 if (pf_s8z24 || pf_z24s8) { 128 depth_bits_array[depth_buffer_factor] = 24; 129 stencil_bits_array[depth_buffer_factor++] = 8; 130 screen->sd_depth_bits_last = pf_s8z24; 131 } 132 if (pf_z32) { 133 depth_bits_array[depth_buffer_factor] = 32; 134 stencil_bits_array[depth_buffer_factor++] = 0; 135 } 136 137 msaa_samples_array[0] = 0; 138 back_buffer_factor = 3; 139 140 /* also test color for msaa 2/4/6/8 - just assume it'll work for all depth buffers */ 141 if (pf_r5g6b5) { 142 msaa_samples_factor = 1; 143 for (i = 1; i < 5; i++) { 144 if (p_screen->is_format_supported(p_screen, PIPE_FORMAT_B5G6R5_UNORM, 145 PIPE_TEXTURE_2D, i*2, 146 PIPE_BIND_RENDER_TARGET, 0)) { 147 msaa_samples_array[msaa_samples_factor] = i * 2; 148 msaa_samples_factor++; 149 } 150 } 151 152 configs_r5g6b5 = driCreateConfigs(GL_RGB, GL_UNSIGNED_SHORT_5_6_5, 153 depth_bits_array, stencil_bits_array, 154 depth_buffer_factor, back_buffer_modes, 155 back_buffer_factor, 156 msaa_samples_array, msaa_samples_factor, 157 GL_TRUE); 158 } 159 160 if (pf_a8r8g8b8) { 161 msaa_samples_factor = 1; 162 for (i = 1; i < 5; i++) { 163 if (p_screen->is_format_supported(p_screen, PIPE_FORMAT_B8G8R8A8_UNORM, 164 PIPE_TEXTURE_2D, i*2, 165 PIPE_BIND_RENDER_TARGET, 0)) { 166 msaa_samples_array[msaa_samples_factor] = i * 2; 167 msaa_samples_factor++; 168 } 169 } 170 171 configs_a8r8g8b8 = driCreateConfigs(GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, 172 depth_bits_array, 173 stencil_bits_array, 174 depth_buffer_factor, 175 back_buffer_modes, 176 back_buffer_factor, 177 msaa_samples_array, 178 msaa_samples_factor, 179 GL_TRUE); 180 } 181 182 if (pf_x8r8g8b8) { 183 msaa_samples_factor = 1; 184 for (i = 1; i < 5; i++) { 185 if (p_screen->is_format_supported(p_screen, PIPE_FORMAT_B8G8R8X8_UNORM, 186 PIPE_TEXTURE_2D, i*2, 187 PIPE_BIND_RENDER_TARGET, 0)) { 188 msaa_samples_array[msaa_samples_factor] = i * 2; 189 msaa_samples_factor++; 190 } 191 } 192 193 configs_x8r8g8b8 = driCreateConfigs(GL_BGR, GL_UNSIGNED_INT_8_8_8_8_REV, 194 depth_bits_array, 195 stencil_bits_array, 196 depth_buffer_factor, 197 back_buffer_modes, 198 back_buffer_factor, 199 msaa_samples_array, 200 msaa_samples_factor, 201 GL_TRUE); 202 } 203 204 if (pixel_bits == 16) { 205 configs = configs_r5g6b5; 206 if (configs_a8r8g8b8) 207 configs = configs ? driConcatConfigs(configs, configs_a8r8g8b8) : configs_a8r8g8b8; 208 if (configs_x8r8g8b8) 209 configs = configs ? driConcatConfigs(configs, configs_x8r8g8b8) : configs_x8r8g8b8; 210 } else { 211 configs = configs_a8r8g8b8; 212 if (configs_x8r8g8b8) 213 configs = configs ? driConcatConfigs(configs, configs_x8r8g8b8) : configs_x8r8g8b8; 214 if (configs_r5g6b5) 215 configs = configs ? driConcatConfigs(configs, configs_r5g6b5) : configs_r5g6b5; 216 } 217 218 if (configs == NULL) { 219 debug_printf("%s: driCreateConfigs failed\n", __FUNCTION__); 220 return NULL; 221 } 222 223 return (const __DRIconfig **)configs; 224} 225 226/** 227 * Roughly the converse of dri_fill_in_modes. 228 */ 229void 230dri_fill_st_visual(struct st_visual *stvis, struct dri_screen *screen, 231 const __GLcontextModes *mode) 232{ 233 memset(stvis, 0, sizeof(*stvis)); 234 235 stvis->samples = mode->samples; 236 stvis->render_buffer = ST_ATTACHMENT_INVALID; 237 238 if (mode->redBits == 8) { 239 if (mode->alphaBits == 8) 240 stvis->color_format = PIPE_FORMAT_B8G8R8A8_UNORM; 241 else 242 stvis->color_format = PIPE_FORMAT_B8G8R8X8_UNORM; 243 } else { 244 stvis->color_format = PIPE_FORMAT_B5G6R5_UNORM; 245 } 246 247 switch (mode->depthBits) { 248 default: 249 case 0: 250 stvis->depth_stencil_format = PIPE_FORMAT_NONE; 251 break; 252 case 16: 253 stvis->depth_stencil_format = PIPE_FORMAT_Z16_UNORM; 254 break; 255 case 24: 256 if (mode->stencilBits == 0) { 257 stvis->depth_stencil_format = (screen->d_depth_bits_last) ? 258 PIPE_FORMAT_Z24X8_UNORM: 259 PIPE_FORMAT_X8Z24_UNORM; 260 } else { 261 stvis->depth_stencil_format = (screen->sd_depth_bits_last) ? 262 PIPE_FORMAT_Z24_UNORM_S8_USCALED: 263 PIPE_FORMAT_S8_USCALED_Z24_UNORM; 264 } 265 break; 266 case 32: 267 stvis->depth_stencil_format = PIPE_FORMAT_Z32_UNORM; 268 break; 269 } 270 271 stvis->accum_format = (mode->haveAccumBuffer) ? 272 PIPE_FORMAT_R16G16B16A16_SNORM : PIPE_FORMAT_NONE; 273 274 stvis->buffer_mask |= ST_ATTACHMENT_FRONT_LEFT_MASK; 275 if (mode->doubleBufferMode) 276 stvis->buffer_mask |= ST_ATTACHMENT_BACK_LEFT_MASK; 277 if (mode->stereoMode) { 278 stvis->buffer_mask |= ST_ATTACHMENT_FRONT_RIGHT_MASK; 279 if (mode->doubleBufferMode) 280 stvis->buffer_mask |= ST_ATTACHMENT_BACK_RIGHT_MASK; 281 } 282 283 if (mode->haveDepthBuffer || mode->haveStencilBuffer) 284 stvis->buffer_mask |= ST_ATTACHMENT_DEPTH_STENCIL_MASK; 285 /* let the state tracker allocate the accum buffer */ 286} 287 288static boolean 289dri_get_egl_image(struct st_manager *smapi, 290 struct st_context_iface *stctxi, 291 void *egl_image, 292 struct st_egl_image *stimg) 293{ 294 struct dri_context *ctx = 295 (struct dri_context *)stctxi->st_manager_private; 296 __DRIimage *img = NULL; 297 298 if (ctx->lookup_egl_image) { 299 img = ctx->lookup_egl_image(ctx, egl_image); 300 } 301 302 if (!img) 303 return FALSE; 304 305 stimg->texture = NULL; 306 pipe_resource_reference(&stimg->texture, img->texture); 307 stimg->face = img->face; 308 stimg->level = img->level; 309 stimg->zslice = img->zslice; 310 311 return TRUE; 312} 313 314static int 315dri_get_param(struct st_manager *smapi, 316 enum st_manager_param param) 317{ 318 struct dri_screen *screen = (struct dri_screen *)smapi; 319 320 switch(param) { 321 case ST_MANAGER_BROKEN_INVALIDATE: 322 return screen->broken_invalidate; 323 default: 324 return 0; 325 } 326} 327 328static void 329dri_destroy_option_cache(struct dri_screen * screen) 330{ 331 int i; 332 333 if (screen->optionCache.info) { 334 for (i = 0; i < (1 << screen->optionCache.tableSize); ++i) { 335 FREE(screen->optionCache.info[i].name); 336 FREE(screen->optionCache.info[i].ranges); 337 } 338 FREE(screen->optionCache.info); 339 } 340 341 FREE(screen->optionCache.values); 342} 343 344void 345dri_destroy_screen_helper(struct dri_screen * screen) 346{ 347 if (screen->st_api && screen->st_api->destroy) 348 screen->st_api->destroy(screen->st_api); 349 350 if (screen->base.screen) 351 screen->base.screen->destroy(screen->base.screen); 352 353 dri_destroy_option_cache(screen); 354} 355 356void 357dri_destroy_screen(__DRIscreen * sPriv) 358{ 359 struct dri_screen *screen = dri_screen(sPriv); 360 361 dri_destroy_screen_helper(screen); 362 363 FREE(screen); 364 sPriv->private = NULL; 365 sPriv->extensions = NULL; 366} 367 368const __DRIconfig ** 369dri_init_screen_helper(struct dri_screen *screen, 370 struct pipe_screen *pscreen, 371 unsigned pixel_bits) 372{ 373 screen->base.screen = pscreen; 374 if (!screen->base.screen) { 375 debug_printf("%s: failed to create pipe_screen\n", __FUNCTION__); 376 return NULL; 377 } 378 379 screen->base.get_egl_image = dri_get_egl_image; 380 screen->base.get_param = dri_get_param; 381 screen->st_api = st_gl_api_create(); 382 383 if (!screen->st_api) 384 return NULL; 385 386 if(pscreen->get_param(pscreen, PIPE_CAP_NPOT_TEXTURES)) 387 screen->target = PIPE_TEXTURE_2D; 388 else 389 screen->target = PIPE_TEXTURE_RECT; 390 391 driParseOptionInfo(&screen->optionCache, 392 __driConfigOptions, __driNConfigOptions); 393 394 return dri_fill_in_modes(screen, pixel_bits); 395} 396 397/* vim: set sw=3 ts=8 sts=3 expandtab: */ 398