intel_screen.c revision 3566bc7584475daa852f4d5735a81a28c032297d
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_VBLANK_MODE(DRI_CONF_VBLANK_ALWAYS_SYNC) 61 /* Options correspond to DRI_CONF_BO_REUSE_DISABLED, 62 * DRI_CONF_BO_REUSE_ALL 63 */ 64 DRI_CONF_OPT_BEGIN_V(bo_reuse, enum, 1, "0:1") 65 DRI_CONF_DESC_BEGIN(en, "Buffer object reuse") 66 DRI_CONF_ENUM(0, "Disable buffer object reuse") 67 DRI_CONF_ENUM(1, "Enable reuse of all sizes of buffer objects") 68 DRI_CONF_DESC_END 69 DRI_CONF_OPT_END 70 71#ifdef I915 72 DRI_CONF_TEXTURE_TILING(false) 73#else 74 DRI_CONF_TEXTURE_TILING(true) 75#endif 76 77 DRI_CONF_OPT_BEGIN(early_z, bool, false) 78 DRI_CONF_DESC(en, "Enable early Z in classic mode (unstable, 945-only).") 79 DRI_CONF_OPT_END 80 81 DRI_CONF_OPT_BEGIN(fragment_shader, bool, false) 82 DRI_CONF_DESC(en, "Enable limited ARB_fragment_shader support on 915/945.") 83 DRI_CONF_OPT_END 84 85 DRI_CONF_SECTION_END 86 DRI_CONF_SECTION_QUALITY 87 DRI_CONF_FORCE_S3TC_ENABLE(false) 88 DRI_CONF_ALLOW_LARGE_TEXTURES(2) 89 DRI_CONF_SECTION_END 90 DRI_CONF_SECTION_DEBUG 91 DRI_CONF_NO_RAST(false) 92 DRI_CONF_ALWAYS_FLUSH_BATCH(false) 93 DRI_CONF_ALWAYS_FLUSH_CACHE(false) 94 95 DRI_CONF_OPT_BEGIN(stub_occlusion_query, bool, false) 96 DRI_CONF_DESC(en, "Enable stub ARB_occlusion_query support on 915/945.") 97 DRI_CONF_OPT_END 98 DRI_CONF_SECTION_END 99DRI_CONF_END; 100 101const GLuint __driNConfigOptions = 11; 102 103#ifdef USE_NEW_INTERFACE 104static PFNGLXCREATECONTEXTMODES create_context_modes = NULL; 105#endif /*USE_NEW_INTERFACE */ 106 107/** 108 * Map all the memory regions described by the screen. 109 * \return GL_TRUE if success, GL_FALSE if error. 110 */ 111GLboolean 112intelMapScreenRegions(__DRIscreen * sPriv) 113{ 114 intelScreenPrivate *intelScreen = (intelScreenPrivate *) sPriv->private; 115 116 if (0) 117 _mesa_printf("TEX 0x%08x ", intelScreen->tex.handle); 118 if (intelScreen->tex.size != 0) { 119 if (drmMap(sPriv->fd, 120 intelScreen->tex.handle, 121 intelScreen->tex.size, 122 (drmAddress *) & intelScreen->tex.map) != 0) { 123 intelUnmapScreenRegions(intelScreen); 124 return GL_FALSE; 125 } 126 } 127 128 return GL_TRUE; 129} 130 131void 132intelUnmapScreenRegions(intelScreenPrivate * intelScreen) 133{ 134 if (intelScreen->tex.map) { 135 drmUnmap(intelScreen->tex.map, intelScreen->tex.size); 136 intelScreen->tex.map = NULL; 137 } 138} 139 140 141static void 142intelPrintDRIInfo(intelScreenPrivate * intelScreen, 143 __DRIscreen * sPriv, I830DRIPtr gDRIPriv) 144{ 145 fprintf(stderr, "*** Front size: 0x%x offset: 0x%x pitch: %d\n", 146 intelScreen->front.size, intelScreen->front.offset, 147 intelScreen->pitch); 148 fprintf(stderr, "*** Back size: 0x%x offset: 0x%x pitch: %d\n", 149 intelScreen->back.size, intelScreen->back.offset, 150 intelScreen->pitch); 151 fprintf(stderr, "*** Depth size: 0x%x offset: 0x%x pitch: %d\n", 152 intelScreen->depth.size, intelScreen->depth.offset, 153 intelScreen->pitch); 154 fprintf(stderr, "*** Texture size: 0x%x offset: 0x%x\n", 155 intelScreen->tex.size, intelScreen->tex.offset); 156 fprintf(stderr, "*** Memory : 0x%x\n", gDRIPriv->mem); 157} 158 159 160static void 161intelPrintSAREA(const drm_i915_sarea_t * sarea) 162{ 163 fprintf(stderr, "SAREA: sarea width %d height %d\n", sarea->width, 164 sarea->height); 165 fprintf(stderr, "SAREA: pitch: %d\n", sarea->pitch); 166 fprintf(stderr, 167 "SAREA: front offset: 0x%08x size: 0x%x handle: 0x%x tiled: %d\n", 168 sarea->front_offset, sarea->front_size, 169 (unsigned) sarea->front_handle, sarea->front_tiled); 170 fprintf(stderr, 171 "SAREA: back offset: 0x%08x size: 0x%x handle: 0x%x tiled: %d\n", 172 sarea->back_offset, sarea->back_size, 173 (unsigned) sarea->back_handle, sarea->back_tiled); 174 fprintf(stderr, "SAREA: depth offset: 0x%08x size: 0x%x handle: 0x%x tiled: %d\n", 175 sarea->depth_offset, sarea->depth_size, 176 (unsigned) sarea->depth_handle, sarea->depth_tiled); 177 fprintf(stderr, "SAREA: tex offset: 0x%08x size: 0x%x handle: 0x%x\n", 178 sarea->tex_offset, sarea->tex_size, (unsigned) sarea->tex_handle); 179} 180 181 182/** 183 * A number of the screen parameters are obtained/computed from 184 * information in the SAREA. This function updates those parameters. 185 */ 186static void 187intelUpdateScreenFromSAREA(intelScreenPrivate * intelScreen, 188 drm_i915_sarea_t * sarea) 189{ 190 intelScreen->width = sarea->width; 191 intelScreen->height = sarea->height; 192 intelScreen->pitch = sarea->pitch; 193 194 intelScreen->front.offset = sarea->front_offset; 195 intelScreen->front.handle = sarea->front_handle; 196 intelScreen->front.size = sarea->front_size; 197 intelScreen->front.tiled = sarea->front_tiled; 198 199 intelScreen->back.offset = sarea->back_offset; 200 intelScreen->back.handle = sarea->back_handle; 201 intelScreen->back.size = sarea->back_size; 202 intelScreen->back.tiled = sarea->back_tiled; 203 204 intelScreen->depth.offset = sarea->depth_offset; 205 intelScreen->depth.handle = sarea->depth_handle; 206 intelScreen->depth.size = sarea->depth_size; 207 intelScreen->depth.tiled = sarea->depth_tiled; 208 209 if (intelScreen->driScrnPriv->ddx_version.minor >= 9) { 210 intelScreen->front.bo_handle = sarea->front_bo_handle; 211 intelScreen->back.bo_handle = sarea->back_bo_handle; 212 intelScreen->depth.bo_handle = sarea->depth_bo_handle; 213 } else { 214 intelScreen->front.bo_handle = -1; 215 intelScreen->back.bo_handle = -1; 216 intelScreen->depth.bo_handle = -1; 217 } 218 219 intelScreen->tex.offset = sarea->tex_offset; 220 intelScreen->logTextureGranularity = sarea->log_tex_granularity; 221 intelScreen->tex.handle = sarea->tex_handle; 222 intelScreen->tex.size = sarea->tex_size; 223 224 if (0) 225 intelPrintSAREA(sarea); 226} 227 228static const __DRItexOffsetExtension intelTexOffsetExtension = { 229 { __DRI_TEX_OFFSET }, 230 intelSetTexOffset, 231}; 232 233static const __DRItexBufferExtension intelTexBufferExtension = { 234 { __DRI_TEX_BUFFER, __DRI_TEX_BUFFER_VERSION }, 235 intelSetTexBuffer, 236 intelSetTexBuffer2, 237}; 238 239static const __DRIextension *intelScreenExtensions[] = { 240 &driReadDrawableExtension, 241 &driSwapControlExtension.base, 242 &driFrameTrackingExtension.base, 243 &driMediaStreamCounterExtension.base, 244 &intelTexOffsetExtension.base, 245 &intelTexBufferExtension.base, 246 NULL 247}; 248 249static GLboolean 250intel_get_param(__DRIscreen *psp, int param, int *value) 251{ 252 int ret; 253 struct drm_i915_getparam gp; 254 255 gp.param = param; 256 gp.value = value; 257 258 ret = drmCommandWriteRead(psp->fd, DRM_I915_GETPARAM, &gp, sizeof(gp)); 259 if (ret) { 260 _mesa_warning(NULL, "drm_i915_getparam: %d", ret); 261 return GL_FALSE; 262 } 263 264 return GL_TRUE; 265} 266 267static GLboolean intelInitDriver(__DRIscreen *sPriv) 268{ 269 intelScreenPrivate *intelScreen; 270 I830DRIPtr gDRIPriv = (I830DRIPtr) sPriv->pDevPriv; 271 drm_i915_sarea_t *sarea; 272 273 if (sPriv->devPrivSize != sizeof(I830DRIRec)) { 274 fprintf(stderr, 275 "\nERROR! sizeof(I830DRIRec) does not match passed size from device driver\n"); 276 return GL_FALSE; 277 } 278 279 /* Allocate the private area */ 280 intelScreen = (intelScreenPrivate *) CALLOC(sizeof(intelScreenPrivate)); 281 if (!intelScreen) { 282 fprintf(stderr, "\nERROR! Allocating private area failed\n"); 283 return GL_FALSE; 284 } 285 /* parse information in __driConfigOptions */ 286 driParseOptionInfo(&intelScreen->optionCache, 287 __driConfigOptions, __driNConfigOptions); 288 289 intelScreen->driScrnPriv = sPriv; 290 sPriv->private = (void *) intelScreen; 291 sarea = (drm_i915_sarea_t *) 292 (((GLubyte *) sPriv->pSAREA) + gDRIPriv->sarea_priv_offset); 293 intelScreen->sarea = sarea; 294 295 intelScreen->deviceID = gDRIPriv->deviceID; 296 297 intelUpdateScreenFromSAREA(intelScreen, sarea); 298 299 if (!intelMapScreenRegions(sPriv)) { 300 fprintf(stderr, "\nERROR! mapping regions\n"); 301 _mesa_free(intelScreen); 302 sPriv->private = NULL; 303 return GL_FALSE; 304 } 305 306 if (0) 307 intelPrintDRIInfo(intelScreen, sPriv, gDRIPriv); 308 309 intelScreen->drmMinor = sPriv->drm_version.minor; 310 311 /* Determine if IRQs are active? */ 312 if (!intel_get_param(sPriv, I915_PARAM_IRQ_ACTIVE, 313 &intelScreen->irq_active)) 314 return GL_FALSE; 315 316 sPriv->extensions = intelScreenExtensions; 317 318 return GL_TRUE; 319} 320 321 322static void 323intelDestroyScreen(__DRIscreen * sPriv) 324{ 325 intelScreenPrivate *intelScreen = (intelScreenPrivate *) sPriv->private; 326 327 dri_bufmgr_destroy(intelScreen->bufmgr); 328 intelUnmapScreenRegions(intelScreen); 329 driDestroyOptionInfo(&intelScreen->optionCache); 330 331 FREE(intelScreen); 332 sPriv->private = NULL; 333} 334 335 336/** 337 * This is called when we need to set up GL rendering to a new X window. 338 */ 339static GLboolean 340intelCreateBuffer(__DRIscreen * driScrnPriv, 341 __DRIdrawable * driDrawPriv, 342 const __GLcontextModes * mesaVis, GLboolean isPixmap) 343{ 344 if (isPixmap) { 345 return GL_FALSE; /* not implemented */ 346 } 347 else { 348 GLboolean swStencil = (mesaVis->stencilBits > 0 && 349 mesaVis->depthBits != 24); 350 gl_format rgbFormat; 351 352 struct intel_framebuffer *intel_fb = CALLOC_STRUCT(intel_framebuffer); 353 354 if (!intel_fb) 355 return GL_FALSE; 356 357 _mesa_initialize_framebuffer(&intel_fb->Base, mesaVis); 358 359 if (mesaVis->redBits == 5) 360 rgbFormat = MESA_FORMAT_RGB565; 361 else if (mesaVis->alphaBits == 0) 362 rgbFormat = MESA_FORMAT_XRGB8888; 363 else 364 rgbFormat = MESA_FORMAT_ARGB8888; 365 366 /* setup the hardware-based renderbuffers */ 367 intel_fb->color_rb[0] = intel_create_renderbuffer(rgbFormat); 368 _mesa_add_renderbuffer(&intel_fb->Base, BUFFER_FRONT_LEFT, 369 &intel_fb->color_rb[0]->Base); 370 371 if (mesaVis->doubleBufferMode) { 372 intel_fb->color_rb[1] = intel_create_renderbuffer(rgbFormat); 373 374 _mesa_add_renderbuffer(&intel_fb->Base, BUFFER_BACK_LEFT, 375 &intel_fb->color_rb[1]->Base); 376 377 } 378 379 if (mesaVis->depthBits == 24) { 380 if (mesaVis->stencilBits == 8) { 381 /* combined depth/stencil buffer */ 382 struct intel_renderbuffer *depthStencilRb 383 = intel_create_renderbuffer(MESA_FORMAT_S8_Z24); 384 /* note: bind RB to two attachment points */ 385 _mesa_add_renderbuffer(&intel_fb->Base, BUFFER_DEPTH, 386 &depthStencilRb->Base); 387 _mesa_add_renderbuffer(&intel_fb->Base, BUFFER_STENCIL, 388 &depthStencilRb->Base); 389 } else { 390 struct intel_renderbuffer *depthRb 391 = intel_create_renderbuffer(MESA_FORMAT_X8_Z24); 392 _mesa_add_renderbuffer(&intel_fb->Base, BUFFER_DEPTH, 393 &depthRb->Base); 394 } 395 } 396 else if (mesaVis->depthBits == 16) { 397 /* just 16-bit depth buffer, no hw stencil */ 398 struct intel_renderbuffer *depthRb 399 = intel_create_renderbuffer(MESA_FORMAT_Z16); 400 _mesa_add_renderbuffer(&intel_fb->Base, BUFFER_DEPTH, &depthRb->Base); 401 } 402 403 /* now add any/all software-based renderbuffers we may need */ 404 _mesa_add_soft_renderbuffers(&intel_fb->Base, 405 GL_FALSE, /* never sw color */ 406 GL_FALSE, /* never sw depth */ 407 swStencil, mesaVis->accumRedBits > 0, 408 GL_FALSE, /* never sw alpha */ 409 GL_FALSE /* never sw aux */ ); 410 driDrawPriv->driverPrivate = (void *) intel_fb; 411 412 return GL_TRUE; 413 } 414} 415 416static void 417intelDestroyBuffer(__DRIdrawable * driDrawPriv) 418{ 419 struct intel_framebuffer *intel_fb = driDrawPriv->driverPrivate; 420 struct intel_renderbuffer *depth_rb; 421 struct intel_renderbuffer *stencil_rb; 422 423 if (intel_fb) { 424 if (intel_fb->color_rb[0]) { 425 intel_renderbuffer_set_region(intel_fb->color_rb[0], NULL); 426 } 427 428 if (intel_fb->color_rb[1]) { 429 intel_renderbuffer_set_region(intel_fb->color_rb[1], NULL); 430 } 431 432 depth_rb = intel_get_renderbuffer(&intel_fb->Base, BUFFER_DEPTH); 433 if (depth_rb) { 434 intel_renderbuffer_set_region(depth_rb, NULL); 435 } 436 437 stencil_rb = intel_get_renderbuffer(&intel_fb->Base, BUFFER_STENCIL); 438 if (stencil_rb) { 439 intel_renderbuffer_set_region(stencil_rb, NULL); 440 } 441 } 442 443 _mesa_reference_framebuffer((GLframebuffer **)(&(driDrawPriv->driverPrivate)), NULL); 444} 445 446 447/** 448 * Get information about previous buffer swaps. 449 */ 450static int 451intelGetSwapInfo(__DRIdrawable * dPriv, __DRIswapInfo * sInfo) 452{ 453 struct intel_framebuffer *intel_fb; 454 455 if ((dPriv == NULL) || (dPriv->driverPrivate == NULL) 456 || (sInfo == NULL)) { 457 return -1; 458 } 459 460 intel_fb = dPriv->driverPrivate; 461 sInfo->swap_count = intel_fb->swap_count; 462 sInfo->swap_ust = intel_fb->swap_ust; 463 sInfo->swap_missed_count = intel_fb->swap_missed_count; 464 465 sInfo->swap_missed_usage = (sInfo->swap_missed_count != 0) 466 ? driCalculateSwapUsage(dPriv, 0, intel_fb->swap_missed_ust) 467 : 0.0; 468 469 return 0; 470} 471 472 473/* There are probably better ways to do this, such as an 474 * init-designated function to register chipids and createcontext 475 * functions. 476 */ 477extern GLboolean i830CreateContext(const __GLcontextModes * mesaVis, 478 __DRIcontext * driContextPriv, 479 void *sharedContextPrivate); 480 481extern GLboolean i915CreateContext(const __GLcontextModes * mesaVis, 482 __DRIcontext * driContextPriv, 483 void *sharedContextPrivate); 484extern GLboolean brwCreateContext(const __GLcontextModes * mesaVis, 485 __DRIcontext * driContextPriv, 486 void *sharedContextPrivate); 487 488static GLboolean 489intelCreateContext(const __GLcontextModes * mesaVis, 490 __DRIcontext * driContextPriv, 491 void *sharedContextPrivate) 492{ 493 __DRIscreen *sPriv = driContextPriv->driScreenPriv; 494 intelScreenPrivate *intelScreen = (intelScreenPrivate *) sPriv->private; 495 496#ifdef I915 497 if (IS_9XX(intelScreen->deviceID)) { 498 if (!IS_965(intelScreen->deviceID)) { 499 return i915CreateContext(mesaVis, driContextPriv, 500 sharedContextPrivate); 501 } 502 } else { 503 intelScreen->no_vbo = GL_TRUE; 504 return i830CreateContext(mesaVis, driContextPriv, sharedContextPrivate); 505 } 506#else 507 if (IS_965(intelScreen->deviceID)) 508 return brwCreateContext(mesaVis, driContextPriv, sharedContextPrivate); 509#endif 510 fprintf(stderr, "Unrecognized deviceID %x\n", intelScreen->deviceID); 511 return GL_FALSE; 512} 513 514static GLboolean 515intel_init_bufmgr(intelScreenPrivate *intelScreen) 516{ 517 int gem_kernel = 0; 518 struct drm_i915_getparam gp; 519 __DRIscreen *spriv = intelScreen->driScrnPriv; 520 int num_fences = 0; 521 522 intelScreen->no_hw = getenv("INTEL_NO_HW") != NULL; 523 524 gp.param = I915_PARAM_HAS_GEM; 525 gp.value = &gem_kernel; 526 527 (void) drmCommandWriteRead(spriv->fd, DRM_I915_GETPARAM, &gp, sizeof(gp)); 528 529 /* If we've got a new enough DDX that's initializing GEM and giving us 530 * object handles for the shared buffers, use that. 531 */ 532 if (!intelScreen->driScrnPriv->dri2.enabled && 533 intelScreen->driScrnPriv->ddx_version.minor < 9) { 534 fprintf(stderr, "[%s:%u] Error initializing GEM.\n", 535 __func__, __LINE__); 536 return GL_FALSE; 537 } 538 539 intelScreen->bufmgr = intel_bufmgr_gem_init(spriv->fd, BATCH_SZ); 540 /* Otherwise, use the classic buffer manager. */ 541 if (intelScreen->bufmgr == NULL) { 542 fprintf(stderr, "[%s:%u] Error initializing buffer manager.\n", 543 __func__, __LINE__); 544 return GL_FALSE; 545 } 546 547 if (intel_get_param(spriv, I915_PARAM_NUM_FENCES_AVAIL, &num_fences)) 548 intelScreen->kernel_exec_fencing = !!num_fences; 549 else 550 intelScreen->kernel_exec_fencing = GL_FALSE; 551 552 return GL_TRUE; 553} 554 555struct intel_context *intelScreenContext(intelScreenPrivate *intelScreen) 556{ 557 /* 558 * This should probably change to have the screen allocate a dummy 559 * context at screen creation. For now just use the current context. 560 */ 561 562 GET_CURRENT_CONTEXT(ctx); 563 if (ctx == NULL) { 564 _mesa_problem(NULL, "No current context in intelScreenContext\n"); 565 return NULL; 566 } 567 return intel_context(ctx); 568} 569 570/** 571 * This is the driver specific part of the createNewScreen entry point. 572 * Called when using DRI2. 573 * 574 * \return the __GLcontextModes supported by this driver 575 */ 576static const 577__DRIconfig **intelInitScreen2(__DRIscreen *psp) 578{ 579 intelScreenPrivate *intelScreen; 580 GLenum fb_format[3]; 581 GLenum fb_type[3]; 582 /* GLX_SWAP_COPY_OML is only supported because the Intel driver doesn't 583 * support pageflipping at all. 584 */ 585 static const GLenum back_buffer_modes[] = { 586 GLX_NONE, GLX_SWAP_UNDEFINED_OML, GLX_SWAP_COPY_OML 587 }; 588 uint8_t depth_bits[4], stencil_bits[4], msaa_samples_array[1]; 589 int color; 590 __DRIconfig **configs = NULL; 591 592 /* Allocate the private area */ 593 intelScreen = (intelScreenPrivate *) CALLOC(sizeof(intelScreenPrivate)); 594 if (!intelScreen) { 595 fprintf(stderr, "\nERROR! Allocating private area failed\n"); 596 return GL_FALSE; 597 } 598 /* parse information in __driConfigOptions */ 599 driParseOptionInfo(&intelScreen->optionCache, 600 __driConfigOptions, __driNConfigOptions); 601 602 intelScreen->driScrnPriv = psp; 603 psp->private = (void *) intelScreen; 604 605 intelScreen->drmMinor = psp->drm_version.minor; 606 607 /* Determine chipset ID */ 608 if (!intel_get_param(psp, I915_PARAM_CHIPSET_ID, 609 &intelScreen->deviceID)) 610 return GL_FALSE; 611 612 if (!intel_init_bufmgr(intelScreen)) 613 return GL_FALSE; 614 615 intelScreen->irq_active = 1; 616 psp->extensions = intelScreenExtensions; 617 618 depth_bits[0] = 0; 619 stencil_bits[0] = 0; 620 depth_bits[1] = 16; 621 stencil_bits[1] = 0; 622 depth_bits[2] = 24; 623 stencil_bits[2] = 0; 624 depth_bits[3] = 24; 625 stencil_bits[3] = 8; 626 627 msaa_samples_array[0] = 0; 628 629 fb_format[0] = GL_RGB; 630 fb_type[0] = GL_UNSIGNED_SHORT_5_6_5; 631 632 fb_format[1] = GL_BGR; 633 fb_type[1] = GL_UNSIGNED_INT_8_8_8_8_REV; 634 635 fb_format[2] = GL_BGRA; 636 fb_type[2] = GL_UNSIGNED_INT_8_8_8_8_REV; 637 638 depth_bits[0] = 0; 639 stencil_bits[0] = 0; 640 641 for (color = 0; color < ARRAY_SIZE(fb_format); color++) { 642 __DRIconfig **new_configs; 643 int depth_factor; 644 645 /* With DRI2 right now, GetBuffers always returns a depth/stencil buffer 646 * with the same cpp as the drawable. So we can't support depth cpp != 647 * color cpp currently. 648 */ 649 if (fb_type[color] == GL_UNSIGNED_SHORT_5_6_5) { 650 depth_bits[1] = 16; 651 stencil_bits[1] = 0; 652 653 depth_factor = 2; 654 } else { 655 depth_bits[1] = 24; 656 stencil_bits[1] = 0; 657 depth_bits[2] = 24; 658 stencil_bits[2] = 8; 659 660 depth_factor = 3; 661 } 662 new_configs = driCreateConfigs(fb_format[color], fb_type[color], 663 depth_bits, 664 stencil_bits, 665 depth_factor, 666 back_buffer_modes, 667 ARRAY_SIZE(back_buffer_modes), 668 msaa_samples_array, 669 ARRAY_SIZE(msaa_samples_array)); 670 if (configs == NULL) 671 configs = new_configs; 672 else 673 configs = driConcatConfigs(configs, new_configs); 674 } 675 676 if (configs == NULL) { 677 fprintf(stderr, "[%s:%u] Error creating FBConfig!\n", __func__, 678 __LINE__); 679 return NULL; 680 } 681 682 return (const __DRIconfig **)configs; 683} 684 685const struct __DriverAPIRec driDriverAPI = { 686 .DestroyScreen = intelDestroyScreen, 687 .CreateContext = intelCreateContext, 688 .DestroyContext = intelDestroyContext, 689 .CreateBuffer = intelCreateBuffer, 690 .DestroyBuffer = intelDestroyBuffer, 691 .MakeCurrent = intelMakeCurrent, 692 .UnbindContext = intelUnbindContext, 693 .GetSwapInfo = intelGetSwapInfo, 694 .GetDrawableMSC = driDrawableGetMSC32, 695 .WaitForMSC = driWaitForMSC32, 696 697 .InitScreen2 = intelInitScreen2, 698}; 699 700/* This is the table of extensions that the loader will dlsym() for. */ 701PUBLIC const __DRIextension *__driDriverExtensions[] = { 702 &driCoreExtension.base, 703 &driDRI2Extension.base, 704 NULL 705}; 706