dri_screen.c revision 866f9b18c68ede63c00917ec9c3dae3524ca8826
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#include "xmlpool.h" 34 35#include "dri_screen.h" 36 37#include "util/u_inlines.h" 38#include "pipe/p_screen.h" 39#include "pipe/p_format.h" 40#include "state_tracker/st_gl_api.h" /* for st_gl_api_create */ 41 42#include "util/u_debug.h" 43 44PUBLIC const char __driConfigOptions[] = 45 DRI_CONF_BEGIN 46 DRI_CONF_SECTION_PERFORMANCE 47 DRI_CONF_FTHROTTLE_MODE(DRI_CONF_FTHROTTLE_IRQS) 48 DRI_CONF_VBLANK_MODE(DRI_CONF_VBLANK_DEF_INTERVAL_0) 49 DRI_CONF_SECTION_END 50 51 DRI_CONF_SECTION_QUALITY 52/* DRI_CONF_FORCE_S3TC_ENABLE(false) */ 53 DRI_CONF_ALLOW_LARGE_TEXTURES(1) 54 DRI_CONF_PP_CELSHADE(0) 55 DRI_CONF_PP_NORED(0) 56 DRI_CONF_PP_NOGREEN(0) 57 DRI_CONF_PP_NOBLUE(0) 58 DRI_CONF_PP_JIMENEZMLAA(0, 0, 32) 59 DRI_CONF_PP_JIMENEZMLAA_COLOR(0, 0, 32) 60 DRI_CONF_SECTION_END 61 DRI_CONF_END; 62 63static const uint __driNConfigOptions = 9; 64 65static const __DRIconfig ** 66dri_fill_in_modes(struct dri_screen *screen, 67 unsigned pixel_bits) 68{ 69 __DRIconfig **configs = NULL; 70 __DRIconfig **configs_r5g6b5 = NULL; 71 __DRIconfig **configs_a8r8g8b8 = NULL; 72 __DRIconfig **configs_x8r8g8b8 = NULL; 73 uint8_t depth_bits_array[5]; 74 uint8_t stencil_bits_array[5]; 75 uint8_t msaa_samples_array[5]; 76 unsigned depth_buffer_factor; 77 unsigned back_buffer_factor; 78 unsigned msaa_samples_factor; 79 unsigned i; 80 struct pipe_screen *p_screen = screen->base.screen; 81 boolean pf_r5g6b5, pf_a8r8g8b8, pf_x8r8g8b8; 82 boolean pf_z16, pf_x8z24, pf_z24x8, pf_s8z24, pf_z24s8, pf_z32; 83 84 static const GLenum back_buffer_modes[] = { 85 GLX_NONE, GLX_SWAP_UNDEFINED_OML, GLX_SWAP_COPY_OML 86 }; 87 88 depth_bits_array[0] = 0; 89 stencil_bits_array[0] = 0; 90 depth_buffer_factor = 1; 91 92 pf_x8z24 = p_screen->is_format_supported(p_screen, PIPE_FORMAT_Z24X8_UNORM, 93 PIPE_TEXTURE_2D, 0, 94 PIPE_BIND_DEPTH_STENCIL); 95 pf_z24x8 = p_screen->is_format_supported(p_screen, PIPE_FORMAT_X8Z24_UNORM, 96 PIPE_TEXTURE_2D, 0, 97 PIPE_BIND_DEPTH_STENCIL); 98 pf_s8z24 = p_screen->is_format_supported(p_screen, PIPE_FORMAT_Z24_UNORM_S8_UINT, 99 PIPE_TEXTURE_2D, 0, 100 PIPE_BIND_DEPTH_STENCIL); 101 pf_z24s8 = p_screen->is_format_supported(p_screen, PIPE_FORMAT_S8_UINT_Z24_UNORM, 102 PIPE_TEXTURE_2D, 0, 103 PIPE_BIND_DEPTH_STENCIL); 104 pf_a8r8g8b8 = p_screen->is_format_supported(p_screen, PIPE_FORMAT_B8G8R8A8_UNORM, 105 PIPE_TEXTURE_2D, 0, 106 PIPE_BIND_RENDER_TARGET); 107 pf_x8r8g8b8 = p_screen->is_format_supported(p_screen, PIPE_FORMAT_B8G8R8X8_UNORM, 108 PIPE_TEXTURE_2D, 0, 109 PIPE_BIND_RENDER_TARGET); 110 pf_r5g6b5 = p_screen->is_format_supported(p_screen, PIPE_FORMAT_B5G6R5_UNORM, 111 PIPE_TEXTURE_2D, 0, 112 PIPE_BIND_RENDER_TARGET); 113 114 /* We can only get a 16 or 32 bit depth buffer with getBuffersWithFormat */ 115 if (dri_with_format(screen->sPriv)) { 116 pf_z16 = p_screen->is_format_supported(p_screen, PIPE_FORMAT_Z16_UNORM, 117 PIPE_TEXTURE_2D, 0, 118 PIPE_BIND_DEPTH_STENCIL); 119 pf_z32 = p_screen->is_format_supported(p_screen, PIPE_FORMAT_Z32_UNORM, 120 PIPE_TEXTURE_2D, 0, 121 PIPE_BIND_DEPTH_STENCIL); 122 } else { 123 pf_z16 = FALSE; 124 pf_z32 = FALSE; 125 } 126 127 if (pf_z16) { 128 depth_bits_array[depth_buffer_factor] = 16; 129 stencil_bits_array[depth_buffer_factor++] = 0; 130 } 131 if (pf_x8z24 || pf_z24x8) { 132 depth_bits_array[depth_buffer_factor] = 24; 133 stencil_bits_array[depth_buffer_factor++] = 0; 134 screen->d_depth_bits_last = pf_x8z24; 135 } 136 if (pf_s8z24 || pf_z24s8) { 137 depth_bits_array[depth_buffer_factor] = 24; 138 stencil_bits_array[depth_buffer_factor++] = 8; 139 screen->sd_depth_bits_last = pf_s8z24; 140 } 141 if (pf_z32) { 142 depth_bits_array[depth_buffer_factor] = 32; 143 stencil_bits_array[depth_buffer_factor++] = 0; 144 } 145 146 msaa_samples_array[0] = 0; 147 back_buffer_factor = 3; 148 149 /* also test color for msaa 2/4/6/8 - just assume it'll work for all depth buffers */ 150 if (pf_r5g6b5) { 151 msaa_samples_factor = 1; 152 for (i = 1; i < 5; i++) { 153 if (p_screen->is_format_supported(p_screen, PIPE_FORMAT_B5G6R5_UNORM, 154 PIPE_TEXTURE_2D, i*2, 155 PIPE_BIND_RENDER_TARGET)) { 156 msaa_samples_array[msaa_samples_factor] = i * 2; 157 msaa_samples_factor++; 158 } 159 } 160 161 configs_r5g6b5 = driCreateConfigs(GL_RGB, GL_UNSIGNED_SHORT_5_6_5, 162 depth_bits_array, stencil_bits_array, 163 depth_buffer_factor, back_buffer_modes, 164 back_buffer_factor, 165 msaa_samples_array, msaa_samples_factor, 166 GL_TRUE); 167 } 168 169 if (pf_a8r8g8b8) { 170 msaa_samples_factor = 1; 171 for (i = 1; i < 5; i++) { 172 if (p_screen->is_format_supported(p_screen, PIPE_FORMAT_B8G8R8A8_UNORM, 173 PIPE_TEXTURE_2D, i*2, 174 PIPE_BIND_RENDER_TARGET)) { 175 msaa_samples_array[msaa_samples_factor] = i * 2; 176 msaa_samples_factor++; 177 } 178 } 179 180 configs_a8r8g8b8 = driCreateConfigs(GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, 181 depth_bits_array, 182 stencil_bits_array, 183 depth_buffer_factor, 184 back_buffer_modes, 185 back_buffer_factor, 186 msaa_samples_array, 187 msaa_samples_factor, 188 GL_TRUE); 189 } 190 191 if (pf_x8r8g8b8) { 192 msaa_samples_factor = 1; 193 for (i = 1; i < 5; i++) { 194 if (p_screen->is_format_supported(p_screen, PIPE_FORMAT_B8G8R8X8_UNORM, 195 PIPE_TEXTURE_2D, i*2, 196 PIPE_BIND_RENDER_TARGET)) { 197 msaa_samples_array[msaa_samples_factor] = i * 2; 198 msaa_samples_factor++; 199 } 200 } 201 202 configs_x8r8g8b8 = driCreateConfigs(GL_BGR, GL_UNSIGNED_INT_8_8_8_8_REV, 203 depth_bits_array, 204 stencil_bits_array, 205 depth_buffer_factor, 206 back_buffer_modes, 207 back_buffer_factor, 208 msaa_samples_array, 209 msaa_samples_factor, 210 GL_TRUE); 211 } 212 213 if (pixel_bits == 16) { 214 configs = configs_r5g6b5; 215 if (configs_a8r8g8b8) 216 configs = configs ? driConcatConfigs(configs, configs_a8r8g8b8) : configs_a8r8g8b8; 217 if (configs_x8r8g8b8) 218 configs = configs ? driConcatConfigs(configs, configs_x8r8g8b8) : configs_x8r8g8b8; 219 } else { 220 configs = configs_a8r8g8b8; 221 if (configs_x8r8g8b8) 222 configs = configs ? driConcatConfigs(configs, configs_x8r8g8b8) : configs_x8r8g8b8; 223 if (configs_r5g6b5) 224 configs = configs ? driConcatConfigs(configs, configs_r5g6b5) : configs_r5g6b5; 225 } 226 227 if (configs == NULL) { 228 debug_printf("%s: driCreateConfigs failed\n", __FUNCTION__); 229 return NULL; 230 } 231 232 return (const __DRIconfig **)configs; 233} 234 235/** 236 * Roughly the converse of dri_fill_in_modes. 237 */ 238void 239dri_fill_st_visual(struct st_visual *stvis, struct dri_screen *screen, 240 const struct gl_config *mode) 241{ 242 memset(stvis, 0, sizeof(*stvis)); 243 244 if (!mode) 245 return; 246 247 stvis->samples = mode->samples; 248 249 if (mode->redBits == 8) { 250 if (mode->alphaBits == 8) 251 stvis->color_format = PIPE_FORMAT_B8G8R8A8_UNORM; 252 else 253 stvis->color_format = PIPE_FORMAT_B8G8R8X8_UNORM; 254 } else { 255 stvis->color_format = PIPE_FORMAT_B5G6R5_UNORM; 256 } 257 258 switch (mode->depthBits) { 259 default: 260 case 0: 261 stvis->depth_stencil_format = PIPE_FORMAT_NONE; 262 break; 263 case 16: 264 stvis->depth_stencil_format = PIPE_FORMAT_Z16_UNORM; 265 break; 266 case 24: 267 if (mode->stencilBits == 0) { 268 stvis->depth_stencil_format = (screen->d_depth_bits_last) ? 269 PIPE_FORMAT_Z24X8_UNORM: 270 PIPE_FORMAT_X8Z24_UNORM; 271 } else { 272 stvis->depth_stencil_format = (screen->sd_depth_bits_last) ? 273 PIPE_FORMAT_Z24_UNORM_S8_UINT: 274 PIPE_FORMAT_S8_UINT_Z24_UNORM; 275 } 276 break; 277 case 32: 278 stvis->depth_stencil_format = PIPE_FORMAT_Z32_UNORM; 279 break; 280 } 281 282 stvis->accum_format = (mode->haveAccumBuffer) ? 283 PIPE_FORMAT_R16G16B16A16_SNORM : PIPE_FORMAT_NONE; 284 285 stvis->buffer_mask |= ST_ATTACHMENT_FRONT_LEFT_MASK; 286 stvis->render_buffer = ST_ATTACHMENT_FRONT_LEFT; 287 if (mode->doubleBufferMode) { 288 stvis->buffer_mask |= ST_ATTACHMENT_BACK_LEFT_MASK; 289 stvis->render_buffer = ST_ATTACHMENT_BACK_LEFT; 290 } 291 if (mode->stereoMode) { 292 stvis->buffer_mask |= ST_ATTACHMENT_FRONT_RIGHT_MASK; 293 if (mode->doubleBufferMode) 294 stvis->buffer_mask |= ST_ATTACHMENT_BACK_RIGHT_MASK; 295 } 296 297 if (mode->haveDepthBuffer || mode->haveStencilBuffer) 298 stvis->buffer_mask |= ST_ATTACHMENT_DEPTH_STENCIL_MASK; 299 /* let the state tracker allocate the accum buffer */ 300} 301 302static boolean 303dri_get_egl_image(struct st_manager *smapi, 304 void *egl_image, 305 struct st_egl_image *stimg) 306{ 307 struct dri_screen *screen = (struct dri_screen *)smapi; 308 __DRIimage *img = NULL; 309 310 if (screen->lookup_egl_image) { 311 img = screen->lookup_egl_image(screen, egl_image); 312 } 313 314 if (!img) 315 return FALSE; 316 317 stimg->texture = NULL; 318 pipe_resource_reference(&stimg->texture, img->texture); 319 stimg->level = img->level; 320 stimg->layer = img->layer; 321 322 return TRUE; 323} 324 325static int 326dri_get_param(struct st_manager *smapi, 327 enum st_manager_param param) 328{ 329 struct dri_screen *screen = (struct dri_screen *)smapi; 330 331 switch(param) { 332 case ST_MANAGER_BROKEN_INVALIDATE: 333 return screen->broken_invalidate; 334 default: 335 return 0; 336 } 337} 338 339static void 340dri_destroy_option_cache(struct dri_screen * screen) 341{ 342 int i; 343 344 if (screen->optionCache.info) { 345 for (i = 0; i < (1 << screen->optionCache.tableSize); ++i) { 346 FREE(screen->optionCache.info[i].name); 347 FREE(screen->optionCache.info[i].ranges); 348 } 349 FREE(screen->optionCache.info); 350 } 351 352 FREE(screen->optionCache.values); 353} 354 355void 356dri_destroy_screen_helper(struct dri_screen * screen) 357{ 358 if (screen->st_api && screen->st_api->destroy) 359 screen->st_api->destroy(screen->st_api); 360 361 if (screen->base.screen) 362 screen->base.screen->destroy(screen->base.screen); 363 364 dri_destroy_option_cache(screen); 365} 366 367void 368dri_destroy_screen(__DRIscreen * sPriv) 369{ 370 struct dri_screen *screen = dri_screen(sPriv); 371 372 dri_destroy_screen_helper(screen); 373 374 FREE(screen); 375 sPriv->private = NULL; 376 sPriv->extensions = NULL; 377} 378 379const __DRIconfig ** 380dri_init_screen_helper(struct dri_screen *screen, 381 struct pipe_screen *pscreen, 382 unsigned pixel_bits) 383{ 384 screen->base.screen = pscreen; 385 if (!screen->base.screen) { 386 debug_printf("%s: failed to create pipe_screen\n", __FUNCTION__); 387 return NULL; 388 } 389 390 screen->base.get_egl_image = dri_get_egl_image; 391 screen->base.get_param = dri_get_param; 392 393 screen->st_api = st_gl_api_create(); 394 if (!screen->st_api) 395 return NULL; 396 397 if(pscreen->get_param(pscreen, PIPE_CAP_NPOT_TEXTURES)) 398 screen->target = PIPE_TEXTURE_2D; 399 else 400 screen->target = PIPE_TEXTURE_RECT; 401 402 driParseOptionInfo(&screen->optionCache, 403 __driConfigOptions, __driNConfigOptions); 404 405 return dri_fill_in_modes(screen, pixel_bits); 406} 407 408/* vim: set sw=3 ts=8 sts=3 expandtab: */ 409