intel_screen.c revision 17ef1f6074d6107c167f1956a5c60993904c0b72
1/************************************************************************** 2 * 3 * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas. 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 TUNGSTEN GRAPHICS 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#include "main/glheader.h" 29#include "main/context.h" 30#include "main/framebuffer.h" 31#include "main/renderbuffer.h" 32 33#include "utils.h" 34#include "vblank.h" 35#include "xmlpool.h" 36 37#include "intel_batchbuffer.h" 38#include "intel_buffers.h" 39#include "intel_bufmgr.h" 40#include "intel_chipset.h" 41#include "intel_extensions.h" 42#include "intel_fbo.h" 43#include "intel_regions.h" 44#include "intel_swapbuffers.h" 45#include "intel_screen.h" 46#include "intel_span.h" 47#include "intel_tex.h" 48 49#include "i915_drm.h" 50#include "i830_dri.h" 51 52#define DRI_CONF_TEXTURE_TILING(def) \ 53 DRI_CONF_OPT_BEGIN(texture_tiling, bool, def) \ 54 DRI_CONF_DESC(en, "Enable texture tiling") \ 55 DRI_CONF_OPT_END \ 56 57PUBLIC const char __driConfigOptions[] = 58 DRI_CONF_BEGIN 59 DRI_CONF_SECTION_PERFORMANCE 60 DRI_CONF_FTHROTTLE_MODE(DRI_CONF_FTHROTTLE_IRQS) 61 DRI_CONF_VBLANK_MODE(DRI_CONF_VBLANK_ALWAYS_SYNC) 62 /* Options correspond to DRI_CONF_BO_REUSE_DISABLED, 63 * DRI_CONF_BO_REUSE_ALL 64 */ 65 DRI_CONF_OPT_BEGIN_V(bo_reuse, enum, 1, "0:1") 66 DRI_CONF_DESC_BEGIN(en, "Buffer object reuse") 67 DRI_CONF_ENUM(0, "Disable buffer object reuse") 68 DRI_CONF_ENUM(1, "Enable reuse of all sizes of buffer objects") 69 DRI_CONF_DESC_END 70 DRI_CONF_OPT_END 71 72#ifdef I915 73 DRI_CONF_TEXTURE_TILING(false) 74#else 75 DRI_CONF_TEXTURE_TILING(true) 76#endif 77 78 DRI_CONF_OPT_BEGIN(early_z, bool, false) 79 DRI_CONF_DESC(en, "Enable early Z in classic mode (unstable, 945-only).") 80 DRI_CONF_OPT_END 81 82 DRI_CONF_OPT_BEGIN(fragment_shader, bool, false) 83 DRI_CONF_DESC(en, "Enable limited ARB_fragment_shader support on 915/945.") 84 DRI_CONF_OPT_END 85 86 DRI_CONF_SECTION_END 87 DRI_CONF_SECTION_QUALITY 88 DRI_CONF_FORCE_S3TC_ENABLE(false) 89 DRI_CONF_ALLOW_LARGE_TEXTURES(2) 90 DRI_CONF_SECTION_END 91 DRI_CONF_SECTION_DEBUG 92 DRI_CONF_NO_RAST(false) 93 DRI_CONF_ALWAYS_FLUSH_BATCH(false) 94 DRI_CONF_ALWAYS_FLUSH_CACHE(false) 95 96 DRI_CONF_OPT_BEGIN(stub_occlusion_query, bool, false) 97 DRI_CONF_DESC(en, "Enable stub ARB_occlusion_query support on 915/945.") 98 DRI_CONF_OPT_END 99 DRI_CONF_SECTION_END 100DRI_CONF_END; 101 102const GLuint __driNConfigOptions = 12; 103 104#ifdef USE_NEW_INTERFACE 105static PFNGLXCREATECONTEXTMODES create_context_modes = NULL; 106#endif /*USE_NEW_INTERFACE */ 107 108/** 109 * Map all the memory regions described by the screen. 110 * \return GL_TRUE if success, GL_FALSE if error. 111 */ 112GLboolean 113intelMapScreenRegions(__DRIscreenPrivate * sPriv) 114{ 115 intelScreenPrivate *intelScreen = (intelScreenPrivate *) sPriv->private; 116 117 if (0) 118 _mesa_printf("TEX 0x%08x ", intelScreen->tex.handle); 119 if (intelScreen->tex.size != 0) { 120 if (drmMap(sPriv->fd, 121 intelScreen->tex.handle, 122 intelScreen->tex.size, 123 (drmAddress *) & intelScreen->tex.map) != 0) { 124 intelUnmapScreenRegions(intelScreen); 125 return GL_FALSE; 126 } 127 } 128 129 return GL_TRUE; 130} 131 132void 133intelUnmapScreenRegions(intelScreenPrivate * intelScreen) 134{ 135 if (intelScreen->tex.map) { 136 drmUnmap(intelScreen->tex.map, intelScreen->tex.size); 137 intelScreen->tex.map = NULL; 138 } 139} 140 141 142static void 143intelPrintDRIInfo(intelScreenPrivate * intelScreen, 144 __DRIscreenPrivate * sPriv, I830DRIPtr gDRIPriv) 145{ 146 fprintf(stderr, "*** Front size: 0x%x offset: 0x%x pitch: %d\n", 147 intelScreen->front.size, intelScreen->front.offset, 148 intelScreen->pitch); 149 fprintf(stderr, "*** Back size: 0x%x offset: 0x%x pitch: %d\n", 150 intelScreen->back.size, intelScreen->back.offset, 151 intelScreen->pitch); 152 fprintf(stderr, "*** Depth size: 0x%x offset: 0x%x pitch: %d\n", 153 intelScreen->depth.size, intelScreen->depth.offset, 154 intelScreen->pitch); 155 fprintf(stderr, "*** Texture size: 0x%x offset: 0x%x\n", 156 intelScreen->tex.size, intelScreen->tex.offset); 157 fprintf(stderr, "*** Memory : 0x%x\n", gDRIPriv->mem); 158} 159 160 161static void 162intelPrintSAREA(const drm_i915_sarea_t * sarea) 163{ 164 fprintf(stderr, "SAREA: sarea width %d height %d\n", sarea->width, 165 sarea->height); 166 fprintf(stderr, "SAREA: pitch: %d\n", sarea->pitch); 167 fprintf(stderr, 168 "SAREA: front offset: 0x%08x size: 0x%x handle: 0x%x tiled: %d\n", 169 sarea->front_offset, sarea->front_size, 170 (unsigned) sarea->front_handle, sarea->front_tiled); 171 fprintf(stderr, 172 "SAREA: back offset: 0x%08x size: 0x%x handle: 0x%x tiled: %d\n", 173 sarea->back_offset, sarea->back_size, 174 (unsigned) sarea->back_handle, sarea->back_tiled); 175 fprintf(stderr, "SAREA: depth offset: 0x%08x size: 0x%x handle: 0x%x tiled: %d\n", 176 sarea->depth_offset, sarea->depth_size, 177 (unsigned) sarea->depth_handle, sarea->depth_tiled); 178 fprintf(stderr, "SAREA: tex offset: 0x%08x size: 0x%x handle: 0x%x\n", 179 sarea->tex_offset, sarea->tex_size, (unsigned) sarea->tex_handle); 180} 181 182 183/** 184 * A number of the screen parameters are obtained/computed from 185 * information in the SAREA. This function updates those parameters. 186 */ 187static void 188intelUpdateScreenFromSAREA(intelScreenPrivate * intelScreen, 189 drm_i915_sarea_t * sarea) 190{ 191 intelScreen->width = sarea->width; 192 intelScreen->height = sarea->height; 193 intelScreen->pitch = sarea->pitch; 194 195 intelScreen->front.offset = sarea->front_offset; 196 intelScreen->front.handle = sarea->front_handle; 197 intelScreen->front.size = sarea->front_size; 198 intelScreen->front.tiled = sarea->front_tiled; 199 200 intelScreen->back.offset = sarea->back_offset; 201 intelScreen->back.handle = sarea->back_handle; 202 intelScreen->back.size = sarea->back_size; 203 intelScreen->back.tiled = sarea->back_tiled; 204 205 intelScreen->depth.offset = sarea->depth_offset; 206 intelScreen->depth.handle = sarea->depth_handle; 207 intelScreen->depth.size = sarea->depth_size; 208 intelScreen->depth.tiled = sarea->depth_tiled; 209 210 if (intelScreen->driScrnPriv->ddx_version.minor >= 9) { 211 intelScreen->front.bo_handle = sarea->front_bo_handle; 212 intelScreen->back.bo_handle = sarea->back_bo_handle; 213 intelScreen->depth.bo_handle = sarea->depth_bo_handle; 214 } else { 215 intelScreen->front.bo_handle = -1; 216 intelScreen->back.bo_handle = -1; 217 intelScreen->depth.bo_handle = -1; 218 } 219 220 intelScreen->tex.offset = sarea->tex_offset; 221 intelScreen->logTextureGranularity = sarea->log_tex_granularity; 222 intelScreen->tex.handle = sarea->tex_handle; 223 intelScreen->tex.size = sarea->tex_size; 224 225 if (0) 226 intelPrintSAREA(sarea); 227} 228 229static const __DRItexOffsetExtension intelTexOffsetExtension = { 230 { __DRI_TEX_OFFSET }, 231 intelSetTexOffset, 232}; 233 234static const __DRItexBufferExtension intelTexBufferExtension = { 235 { __DRI_TEX_BUFFER, __DRI_TEX_BUFFER_VERSION }, 236 intelSetTexBuffer, 237 intelSetTexBuffer2, 238}; 239 240static const __DRIextension *intelScreenExtensions[] = { 241 &driReadDrawableExtension, 242 &driCopySubBufferExtension.base, 243 &driSwapControlExtension.base, 244 &driFrameTrackingExtension.base, 245 &driMediaStreamCounterExtension.base, 246 &intelTexOffsetExtension.base, 247 &intelTexBufferExtension.base, 248 NULL 249}; 250 251static GLboolean 252intel_get_param(__DRIscreenPrivate *psp, int param, int *value) 253{ 254 int ret; 255 struct drm_i915_getparam gp; 256 257 gp.param = param; 258 gp.value = value; 259 260 ret = drmCommandWriteRead(psp->fd, DRM_I915_GETPARAM, &gp, sizeof(gp)); 261 if (ret) { 262 _mesa_warning(NULL, "drm_i915_getparam: %d", ret); 263 return GL_FALSE; 264 } 265 266 return GL_TRUE; 267} 268 269static GLboolean intelInitDriver(__DRIscreenPrivate *sPriv) 270{ 271 intelScreenPrivate *intelScreen; 272 I830DRIPtr gDRIPriv = (I830DRIPtr) sPriv->pDevPriv; 273 drm_i915_sarea_t *sarea; 274 275 if (sPriv->devPrivSize != sizeof(I830DRIRec)) { 276 fprintf(stderr, 277 "\nERROR! sizeof(I830DRIRec) does not match passed size from device driver\n"); 278 return GL_FALSE; 279 } 280 281 /* Allocate the private area */ 282 intelScreen = (intelScreenPrivate *) CALLOC(sizeof(intelScreenPrivate)); 283 if (!intelScreen) { 284 fprintf(stderr, "\nERROR! Allocating private area failed\n"); 285 return GL_FALSE; 286 } 287 /* parse information in __driConfigOptions */ 288 driParseOptionInfo(&intelScreen->optionCache, 289 __driConfigOptions, __driNConfigOptions); 290 291 intelScreen->driScrnPriv = sPriv; 292 sPriv->private = (void *) intelScreen; 293 sarea = (drm_i915_sarea_t *) 294 (((GLubyte *) sPriv->pSAREA) + gDRIPriv->sarea_priv_offset); 295 intelScreen->sarea = sarea; 296 297 intelScreen->deviceID = gDRIPriv->deviceID; 298 299 intelUpdateScreenFromSAREA(intelScreen, sarea); 300 301 if (!intelMapScreenRegions(sPriv)) { 302 fprintf(stderr, "\nERROR! mapping regions\n"); 303 _mesa_free(intelScreen); 304 sPriv->private = NULL; 305 return GL_FALSE; 306 } 307 308 if (0) 309 intelPrintDRIInfo(intelScreen, sPriv, gDRIPriv); 310 311 intelScreen->drmMinor = sPriv->drm_version.minor; 312 313 /* Determine if IRQs are active? */ 314 if (!intel_get_param(sPriv, I915_PARAM_IRQ_ACTIVE, 315 &intelScreen->irq_active)) 316 return GL_FALSE; 317 318 sPriv->extensions = intelScreenExtensions; 319 320 return GL_TRUE; 321} 322 323 324static void 325intelDestroyScreen(__DRIscreenPrivate * sPriv) 326{ 327 intelScreenPrivate *intelScreen = (intelScreenPrivate *) sPriv->private; 328 329 dri_bufmgr_destroy(intelScreen->bufmgr); 330 intelUnmapScreenRegions(intelScreen); 331 driDestroyOptionInfo(&intelScreen->optionCache); 332 333 FREE(intelScreen); 334 sPriv->private = NULL; 335} 336 337 338/** 339 * This is called when we need to set up GL rendering to a new X window. 340 */ 341static GLboolean 342intelCreateBuffer(__DRIscreenPrivate * driScrnPriv, 343 __DRIdrawablePrivate * driDrawPriv, 344 const __GLcontextModes * mesaVis, GLboolean isPixmap) 345{ 346 if (isPixmap) { 347 return GL_FALSE; /* not implemented */ 348 } 349 else { 350 GLboolean swStencil = (mesaVis->stencilBits > 0 && 351 mesaVis->depthBits != 24); 352 GLenum rgbFormat; 353 354 struct intel_framebuffer *intel_fb = CALLOC_STRUCT(intel_framebuffer); 355 356 if (!intel_fb) 357 return GL_FALSE; 358 359 _mesa_initialize_framebuffer(&intel_fb->Base, mesaVis); 360 361 if (mesaVis->redBits == 5) 362 rgbFormat = GL_RGB5; 363 else if (mesaVis->alphaBits == 0) 364 rgbFormat = GL_RGB8; 365 else 366 rgbFormat = GL_RGBA8; 367 368 /* setup the hardware-based renderbuffers */ 369 intel_fb->color_rb[0] = intel_create_renderbuffer(rgbFormat); 370 _mesa_add_renderbuffer(&intel_fb->Base, BUFFER_FRONT_LEFT, 371 &intel_fb->color_rb[0]->Base); 372 373 if (mesaVis->doubleBufferMode) { 374 intel_fb->color_rb[1] = intel_create_renderbuffer(rgbFormat); 375 376 _mesa_add_renderbuffer(&intel_fb->Base, BUFFER_BACK_LEFT, 377 &intel_fb->color_rb[1]->Base); 378 379 } 380 381 if (mesaVis->depthBits == 24) { 382 if (mesaVis->stencilBits == 8) { 383 /* combined depth/stencil buffer */ 384 struct intel_renderbuffer *depthStencilRb 385 = intel_create_renderbuffer(GL_DEPTH24_STENCIL8_EXT); 386 /* note: bind RB to two attachment points */ 387 _mesa_add_renderbuffer(&intel_fb->Base, BUFFER_DEPTH, 388 &depthStencilRb->Base); 389 _mesa_add_renderbuffer(&intel_fb->Base, BUFFER_STENCIL, 390 &depthStencilRb->Base); 391 } else { 392 struct intel_renderbuffer *depthRb 393 = intel_create_renderbuffer(GL_DEPTH_COMPONENT24); 394 _mesa_add_renderbuffer(&intel_fb->Base, BUFFER_DEPTH, 395 &depthRb->Base); 396 } 397 } 398 else if (mesaVis->depthBits == 16) { 399 /* just 16-bit depth buffer, no hw stencil */ 400 struct intel_renderbuffer *depthRb 401 = intel_create_renderbuffer(GL_DEPTH_COMPONENT16); 402 _mesa_add_renderbuffer(&intel_fb->Base, BUFFER_DEPTH, &depthRb->Base); 403 } 404 405 /* now add any/all software-based renderbuffers we may need */ 406 _mesa_add_soft_renderbuffers(&intel_fb->Base, 407 GL_FALSE, /* never sw color */ 408 GL_FALSE, /* never sw depth */ 409 swStencil, mesaVis->accumRedBits > 0, 410 GL_FALSE, /* never sw alpha */ 411 GL_FALSE /* never sw aux */ ); 412 driDrawPriv->driverPrivate = (void *) intel_fb; 413 414 return GL_TRUE; 415 } 416} 417 418static void 419intelDestroyBuffer(__DRIdrawablePrivate * driDrawPriv) 420{ 421 struct intel_framebuffer *intel_fb = driDrawPriv->driverPrivate; 422 struct intel_renderbuffer *depth_rb; 423 struct intel_renderbuffer *stencil_rb; 424 425 if (intel_fb) { 426 if (intel_fb->color_rb[0]) { 427 intel_renderbuffer_set_region(intel_fb->color_rb[0], NULL); 428 } 429 430 if (intel_fb->color_rb[1]) { 431 intel_renderbuffer_set_region(intel_fb->color_rb[1], NULL); 432 } 433 434 depth_rb = intel_get_renderbuffer(&intel_fb->Base, BUFFER_DEPTH); 435 if (depth_rb) { 436 intel_renderbuffer_set_region(depth_rb, NULL); 437 } 438 439 stencil_rb = intel_get_renderbuffer(&intel_fb->Base, BUFFER_STENCIL); 440 if (stencil_rb) { 441 intel_renderbuffer_set_region(stencil_rb, NULL); 442 } 443 } 444 445 _mesa_reference_framebuffer((GLframebuffer **)(&(driDrawPriv->driverPrivate)), NULL); 446} 447 448 449/** 450 * Get information about previous buffer swaps. 451 */ 452static int 453intelGetSwapInfo(__DRIdrawablePrivate * dPriv, __DRIswapInfo * sInfo) 454{ 455 struct intel_framebuffer *intel_fb; 456 457 if ((dPriv == NULL) || (dPriv->driverPrivate == NULL) 458 || (sInfo == NULL)) { 459 return -1; 460 } 461 462 intel_fb = dPriv->driverPrivate; 463 sInfo->swap_count = intel_fb->swap_count; 464 sInfo->swap_ust = intel_fb->swap_ust; 465 sInfo->swap_missed_count = intel_fb->swap_missed_count; 466 467 sInfo->swap_missed_usage = (sInfo->swap_missed_count != 0) 468 ? driCalculateSwapUsage(dPriv, 0, intel_fb->swap_missed_ust) 469 : 0.0; 470 471 return 0; 472} 473 474 475/* There are probably better ways to do this, such as an 476 * init-designated function to register chipids and createcontext 477 * functions. 478 */ 479extern GLboolean i830CreateContext(const __GLcontextModes * mesaVis, 480 __DRIcontextPrivate * driContextPriv, 481 void *sharedContextPrivate); 482 483extern GLboolean i915CreateContext(const __GLcontextModes * mesaVis, 484 __DRIcontextPrivate * driContextPriv, 485 void *sharedContextPrivate); 486extern GLboolean brwCreateContext(const __GLcontextModes * mesaVis, 487 __DRIcontextPrivate * driContextPriv, 488 void *sharedContextPrivate); 489 490static GLboolean 491intelCreateContext(const __GLcontextModes * mesaVis, 492 __DRIcontextPrivate * driContextPriv, 493 void *sharedContextPrivate) 494{ 495 __DRIscreenPrivate *sPriv = driContextPriv->driScreenPriv; 496 intelScreenPrivate *intelScreen = (intelScreenPrivate *) sPriv->private; 497 498#ifdef I915 499 if (IS_9XX(intelScreen->deviceID)) { 500 if (!IS_965(intelScreen->deviceID)) { 501 return i915CreateContext(mesaVis, driContextPriv, 502 sharedContextPrivate); 503 } 504 } else { 505 intelScreen->no_vbo = GL_TRUE; 506 return i830CreateContext(mesaVis, driContextPriv, sharedContextPrivate); 507 } 508#else 509 if (IS_965(intelScreen->deviceID)) 510 return brwCreateContext(mesaVis, driContextPriv, sharedContextPrivate); 511#endif 512 fprintf(stderr, "Unrecognized deviceID %x\n", intelScreen->deviceID); 513 return GL_FALSE; 514} 515 516 517static __DRIconfig ** 518intelFillInModes(__DRIscreenPrivate *psp, 519 unsigned pixel_bits, unsigned depth_bits, 520 unsigned stencil_bits, GLboolean have_back_buffer) 521{ 522 __DRIconfig **configs; 523 __GLcontextModes *m; 524 unsigned depth_buffer_factor; 525 unsigned back_buffer_factor; 526 int i; 527 528 /* GLX_SWAP_COPY_OML is only supported because the Intel driver doesn't 529 * support pageflipping at all. 530 */ 531 static const GLenum back_buffer_modes[] = { 532 GLX_NONE, GLX_SWAP_UNDEFINED_OML, GLX_SWAP_COPY_OML 533 }; 534 535 uint8_t depth_bits_array[3]; 536 uint8_t stencil_bits_array[3]; 537 uint8_t msaa_samples_array[1]; 538 539 depth_bits_array[0] = 0; 540 depth_bits_array[1] = depth_bits; 541 depth_bits_array[2] = depth_bits; 542 543 /* Just like with the accumulation buffer, always provide some modes 544 * with a stencil buffer. It will be a sw fallback, but some apps won't 545 * care about that. 546 */ 547 stencil_bits_array[0] = 0; 548 stencil_bits_array[1] = 0; 549 if (depth_bits == 24) 550 stencil_bits_array[1] = (stencil_bits == 0) ? 8 : stencil_bits; 551 552 stencil_bits_array[2] = (stencil_bits == 0) ? 8 : stencil_bits; 553 554 msaa_samples_array[0] = 0; 555 556 depth_buffer_factor = ((depth_bits != 0) || (stencil_bits != 0)) ? 3 : 1; 557 back_buffer_factor = (have_back_buffer) ? 3 : 1; 558 559 if (pixel_bits == 16) { 560 configs = driCreateConfigs(GL_RGB, GL_UNSIGNED_SHORT_5_6_5, 561 depth_bits_array, stencil_bits_array, 562 depth_buffer_factor, back_buffer_modes, 563 back_buffer_factor, 564 msaa_samples_array, 1); 565 } 566 else { 567 __DRIconfig **configs_a8r8g8b8; 568 __DRIconfig **configs_x8r8g8b8; 569 570 configs_a8r8g8b8 = driCreateConfigs(GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, 571 depth_bits_array, 572 stencil_bits_array, 573 depth_buffer_factor, 574 back_buffer_modes, 575 back_buffer_factor, 576 msaa_samples_array, 1); 577 configs_x8r8g8b8 = driCreateConfigs(GL_BGR, GL_UNSIGNED_INT_8_8_8_8_REV, 578 depth_bits_array, 579 stencil_bits_array, 580 depth_buffer_factor, 581 back_buffer_modes, 582 back_buffer_factor, 583 msaa_samples_array, 1); 584 configs = driConcatConfigs(configs_a8r8g8b8, configs_x8r8g8b8); 585 } 586 587 if (configs == NULL) { 588 fprintf(stderr, "[%s:%u] Error creating FBConfig!\n", __func__, 589 __LINE__); 590 return NULL; 591 } 592 593 /* Mark the visual as slow if there are "fake" stencil bits. 594 */ 595 for (i = 0; configs[i]; i++) { 596 m = &configs[i]->modes; 597 if ((m->stencilBits != 0) && (m->stencilBits != stencil_bits)) { 598 m->visualRating = GLX_SLOW_CONFIG; 599 } 600 } 601 602 return configs; 603} 604 605static GLboolean 606intel_init_bufmgr(intelScreenPrivate *intelScreen) 607{ 608 GLboolean gem_disable = getenv("INTEL_NO_GEM") != NULL; 609 int gem_kernel = 0; 610 GLboolean gem_supported; 611 struct drm_i915_getparam gp; 612 __DRIscreenPrivate *spriv = intelScreen->driScrnPriv; 613 int num_fences = 0; 614 615 intelScreen->no_hw = getenv("INTEL_NO_HW") != NULL; 616 617 gp.param = I915_PARAM_HAS_GEM; 618 gp.value = &gem_kernel; 619 620 (void) drmCommandWriteRead(spriv->fd, DRM_I915_GETPARAM, &gp, sizeof(gp)); 621 622 /* If we've got a new enough DDX that's initializing GEM and giving us 623 * object handles for the shared buffers, use that. 624 */ 625 intelScreen->ttm = GL_FALSE; 626 if (intelScreen->driScrnPriv->dri2.enabled) 627 gem_supported = GL_TRUE; 628 else if (intelScreen->driScrnPriv->ddx_version.minor >= 9 && 629 gem_kernel && 630 intelScreen->front.bo_handle != -1) 631 gem_supported = GL_TRUE; 632 else 633 gem_supported = GL_FALSE; 634 635 if (!gem_disable && gem_supported) { 636 intelScreen->bufmgr = intel_bufmgr_gem_init(spriv->fd, BATCH_SZ); 637 if (intelScreen->bufmgr != NULL) 638 intelScreen->ttm = GL_TRUE; 639 } 640 /* Otherwise, use the classic buffer manager. */ 641 if (intelScreen->bufmgr == NULL) { 642 if (gem_disable) { 643 _mesa_warning(NULL, "GEM disabled. Using classic."); 644 } else { 645 _mesa_warning(NULL, 646 "Failed to initialize GEM. Falling back to classic."); 647 } 648 649 if (intelScreen->tex.size == 0) { 650 fprintf(stderr, "[%s:%u] Error initializing buffer manager.\n", 651 __func__, __LINE__); 652 return GL_FALSE; 653 } 654 655 intelScreen->bufmgr = 656 intel_bufmgr_fake_init(spriv->fd, 657 intelScreen->tex.offset, 658 intelScreen->tex.map, 659 intelScreen->tex.size, 660 (unsigned int * volatile) 661 &intelScreen->sarea->last_dispatch); 662 } 663 664 if (intel_get_param(spriv, I915_PARAM_NUM_FENCES_AVAIL, &num_fences)) 665 intelScreen->kernel_exec_fencing = !!num_fences; 666 else 667 intelScreen->kernel_exec_fencing = GL_FALSE; 668 669 return GL_TRUE; 670} 671 672/** 673 * This is the driver specific part of the createNewScreen entry point. 674 * Called when using legacy DRI. 675 * 676 * \todo maybe fold this into intelInitDriver 677 * 678 * \return the __GLcontextModes supported by this driver 679 */ 680static const __DRIconfig **intelInitScreen(__DRIscreenPrivate *psp) 681{ 682 intelScreenPrivate *intelScreen; 683#ifdef I915 684 static const __DRIversion ddx_expected = { 1, 5, 0 }; 685#else 686 static const __DRIversion ddx_expected = { 1, 6, 0 }; 687#endif 688 static const __DRIversion dri_expected = { 4, 0, 0 }; 689 static const __DRIversion drm_expected = { 1, 5, 0 }; 690 I830DRIPtr dri_priv = (I830DRIPtr) psp->pDevPriv; 691 692 if (!driCheckDriDdxDrmVersions2("i915", 693 &psp->dri_version, &dri_expected, 694 &psp->ddx_version, &ddx_expected, 695 &psp->drm_version, &drm_expected)) { 696 return NULL; 697 } 698 699 if (!intelInitDriver(psp)) 700 return NULL; 701 702 psp->extensions = intelScreenExtensions; 703 704 intelScreen = psp->private; 705 if (!intel_init_bufmgr(intelScreen)) 706 return GL_FALSE; 707 708 return (const __DRIconfig **) 709 intelFillInModes(psp, dri_priv->cpp * 8, 710 (dri_priv->cpp == 2) ? 16 : 24, 711 (dri_priv->cpp == 2) ? 0 : 8, 1); 712} 713 714struct intel_context *intelScreenContext(intelScreenPrivate *intelScreen) 715{ 716 /* 717 * This should probably change to have the screen allocate a dummy 718 * context at screen creation. For now just use the current context. 719 */ 720 721 GET_CURRENT_CONTEXT(ctx); 722 if (ctx == NULL) { 723 _mesa_problem(NULL, "No current context in intelScreenContext\n"); 724 return NULL; 725 } 726 return intel_context(ctx); 727} 728 729/** 730 * This is the driver specific part of the createNewScreen entry point. 731 * Called when using DRI2. 732 * 733 * \return the __GLcontextModes supported by this driver 734 */ 735static const 736__DRIconfig **intelInitScreen2(__DRIscreenPrivate *psp) 737{ 738 intelScreenPrivate *intelScreen; 739 GLenum fb_format[3]; 740 GLenum fb_type[3]; 741 /* GLX_SWAP_COPY_OML is only supported because the Intel driver doesn't 742 * support pageflipping at all. 743 */ 744 static const GLenum back_buffer_modes[] = { 745 GLX_NONE, GLX_SWAP_UNDEFINED_OML, GLX_SWAP_COPY_OML 746 }; 747 uint8_t depth_bits[4], stencil_bits[4], msaa_samples_array[1]; 748 int color; 749 __DRIconfig **configs = NULL; 750 751 /* Allocate the private area */ 752 intelScreen = (intelScreenPrivate *) CALLOC(sizeof(intelScreenPrivate)); 753 if (!intelScreen) { 754 fprintf(stderr, "\nERROR! Allocating private area failed\n"); 755 return GL_FALSE; 756 } 757 /* parse information in __driConfigOptions */ 758 driParseOptionInfo(&intelScreen->optionCache, 759 __driConfigOptions, __driNConfigOptions); 760 761 intelScreen->driScrnPriv = psp; 762 psp->private = (void *) intelScreen; 763 764 intelScreen->drmMinor = psp->drm_version.minor; 765 766 /* Determine chipset ID */ 767 if (!intel_get_param(psp, I915_PARAM_CHIPSET_ID, 768 &intelScreen->deviceID)) 769 return GL_FALSE; 770 771 if (!intel_init_bufmgr(intelScreen)) 772 return GL_FALSE; 773 774 intelScreen->irq_active = 1; 775 psp->extensions = intelScreenExtensions; 776 777 depth_bits[0] = 0; 778 stencil_bits[0] = 0; 779 depth_bits[1] = 16; 780 stencil_bits[1] = 0; 781 depth_bits[2] = 24; 782 stencil_bits[2] = 0; 783 depth_bits[3] = 24; 784 stencil_bits[3] = 8; 785 786 msaa_samples_array[0] = 0; 787 788 fb_format[0] = GL_RGB; 789 fb_type[0] = GL_UNSIGNED_SHORT_5_6_5; 790 791 fb_format[1] = GL_BGR; 792 fb_type[1] = GL_UNSIGNED_INT_8_8_8_8_REV; 793 794 fb_format[2] = GL_BGRA; 795 fb_type[2] = GL_UNSIGNED_INT_8_8_8_8_REV; 796 797 depth_bits[0] = 0; 798 stencil_bits[0] = 0; 799 800 for (color = 0; color < ARRAY_SIZE(fb_format); color++) { 801 __DRIconfig **new_configs; 802 int depth_factor; 803 804 /* With DRI2 right now, GetBuffers always returns a depth/stencil buffer 805 * with the same cpp as the drawable. So we can't support depth cpp != 806 * color cpp currently. 807 */ 808 if (fb_type[color] == GL_UNSIGNED_SHORT_5_6_5) { 809 depth_bits[1] = 16; 810 stencil_bits[1] = 0; 811 812 depth_factor = 2; 813 } else { 814 depth_bits[1] = 24; 815 stencil_bits[1] = 0; 816 depth_bits[2] = 24; 817 stencil_bits[2] = 8; 818 819 depth_factor = 3; 820 } 821 new_configs = driCreateConfigs(fb_format[color], fb_type[color], 822 depth_bits, 823 stencil_bits, 824 depth_factor, 825 back_buffer_modes, 826 ARRAY_SIZE(back_buffer_modes), 827 msaa_samples_array, 828 ARRAY_SIZE(msaa_samples_array)); 829 if (configs == NULL) 830 configs = new_configs; 831 else 832 configs = driConcatConfigs(configs, new_configs); 833 } 834 835 if (configs == NULL) { 836 fprintf(stderr, "[%s:%u] Error creating FBConfig!\n", __func__, 837 __LINE__); 838 return NULL; 839 } 840 841 return (const __DRIconfig **)configs; 842} 843 844const struct __DriverAPIRec driDriverAPI = { 845 .InitScreen = intelInitScreen, 846 .DestroyScreen = intelDestroyScreen, 847 .CreateContext = intelCreateContext, 848 .DestroyContext = intelDestroyContext, 849 .CreateBuffer = intelCreateBuffer, 850 .DestroyBuffer = intelDestroyBuffer, 851 .SwapBuffers = intelSwapBuffers, 852 .MakeCurrent = intelMakeCurrent, 853 .UnbindContext = intelUnbindContext, 854 .GetSwapInfo = intelGetSwapInfo, 855 .GetDrawableMSC = driDrawableGetMSC32, 856 .WaitForMSC = driWaitForMSC32, 857 .CopySubBuffer = intelCopySubBuffer, 858 859 .InitScreen2 = intelInitScreen2, 860}; 861