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