intel_context.c revision c6e26d76c7f59b51be00c960112c85ad4b3d2334
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 29#include "main/glheader.h" 30#include "main/context.h" 31#include "main/extensions.h" 32#include "main/framebuffer.h" 33#include "main/imports.h" 34#include "main/points.h" 35 36#include "swrast/swrast.h" 37#include "swrast_setup/swrast_setup.h" 38#include "tnl/tnl.h" 39#include "drivers/common/driverfuncs.h" 40#include "drivers/common/meta.h" 41 42#include "i830_dri.h" 43 44#include "intel_chipset.h" 45#include "intel_buffers.h" 46#include "intel_tex.h" 47#include "intel_batchbuffer.h" 48#include "intel_clear.h" 49#include "intel_extensions.h" 50#include "intel_pixel.h" 51#include "intel_regions.h" 52#include "intel_buffer_objects.h" 53#include "intel_fbo.h" 54#include "intel_bufmgr.h" 55#include "intel_screen.h" 56 57#include "drirenderbuffer.h" 58#include "utils.h" 59 60 61#ifndef INTEL_DEBUG 62int INTEL_DEBUG = (0); 63#endif 64 65 66#define DRIVER_DATE "20091221 DEVELOPMENT" 67#define DRIVER_DATE_GEM "GEM " DRIVER_DATE 68 69 70static const GLubyte * 71intelGetString(GLcontext * ctx, GLenum name) 72{ 73 const struct intel_context *const intel = intel_context(ctx); 74 const char *chipset; 75 static char buffer[128]; 76 77 switch (name) { 78 case GL_VENDOR: 79 return (GLubyte *) "Tungsten Graphics, Inc"; 80 break; 81 82 case GL_RENDERER: 83 switch (intel->intelScreen->deviceID) { 84 case PCI_CHIP_845_G: 85 chipset = "Intel(R) 845G"; 86 break; 87 case PCI_CHIP_I830_M: 88 chipset = "Intel(R) 830M"; 89 break; 90 case PCI_CHIP_I855_GM: 91 chipset = "Intel(R) 852GM/855GM"; 92 break; 93 case PCI_CHIP_I865_G: 94 chipset = "Intel(R) 865G"; 95 break; 96 case PCI_CHIP_I915_G: 97 chipset = "Intel(R) 915G"; 98 break; 99 case PCI_CHIP_E7221_G: 100 chipset = "Intel (R) E7221G (i915)"; 101 break; 102 case PCI_CHIP_I915_GM: 103 chipset = "Intel(R) 915GM"; 104 break; 105 case PCI_CHIP_I945_G: 106 chipset = "Intel(R) 945G"; 107 break; 108 case PCI_CHIP_I945_GM: 109 chipset = "Intel(R) 945GM"; 110 break; 111 case PCI_CHIP_I945_GME: 112 chipset = "Intel(R) 945GME"; 113 break; 114 case PCI_CHIP_G33_G: 115 chipset = "Intel(R) G33"; 116 break; 117 case PCI_CHIP_Q35_G: 118 chipset = "Intel(R) Q35"; 119 break; 120 case PCI_CHIP_Q33_G: 121 chipset = "Intel(R) Q33"; 122 break; 123 case PCI_CHIP_IGD_GM: 124 case PCI_CHIP_IGD_G: 125 chipset = "Intel(R) IGD"; 126 break; 127 case PCI_CHIP_I965_Q: 128 chipset = "Intel(R) 965Q"; 129 break; 130 case PCI_CHIP_I965_G: 131 case PCI_CHIP_I965_G_1: 132 chipset = "Intel(R) 965G"; 133 break; 134 case PCI_CHIP_I946_GZ: 135 chipset = "Intel(R) 946GZ"; 136 break; 137 case PCI_CHIP_I965_GM: 138 chipset = "Intel(R) 965GM"; 139 break; 140 case PCI_CHIP_I965_GME: 141 chipset = "Intel(R) 965GME/GLE"; 142 break; 143 case PCI_CHIP_GM45_GM: 144 chipset = "Mobile Intel® GM45 Express Chipset"; 145 break; 146 case PCI_CHIP_IGD_E_G: 147 chipset = "Intel(R) Integrated Graphics Device"; 148 break; 149 case PCI_CHIP_G45_G: 150 chipset = "Intel(R) G45/G43"; 151 break; 152 case PCI_CHIP_Q45_G: 153 chipset = "Intel(R) Q45/Q43"; 154 break; 155 case PCI_CHIP_G41_G: 156 chipset = "Intel(R) G41"; 157 break; 158 case PCI_CHIP_B43_G: 159 chipset = "Intel(R) B43"; 160 break; 161 case PCI_CHIP_ILD_G: 162 chipset = "Intel(R) IGDNG_D"; 163 break; 164 case PCI_CHIP_ILM_G: 165 chipset = "Intel(R) IGDNG_M"; 166 break; 167 default: 168 chipset = "Unknown Intel Chipset"; 169 break; 170 } 171 172 (void) driGetRendererString(buffer, chipset, DRIVER_DATE_GEM, 0); 173 return (GLubyte *) buffer; 174 175 default: 176 return NULL; 177 } 178} 179 180static unsigned 181intel_bits_per_pixel(const struct intel_renderbuffer *rb) 182{ 183 return _mesa_get_format_bytes(rb->Base.Format) * 8; 184} 185 186void 187intel_update_renderbuffers(__DRIcontext *context, __DRIdrawable *drawable) 188{ 189 struct gl_framebuffer *fb = drawable->driverPrivate; 190 struct intel_renderbuffer *rb; 191 struct intel_region *region, *depth_region; 192 struct intel_context *intel = context->driverPrivate; 193 struct intel_renderbuffer *front_rb, *back_rb, *depth_rb, *stencil_rb; 194 __DRIbuffer *buffers = NULL; 195 __DRIscreen *screen; 196 int i, count; 197 unsigned int attachments[10]; 198 uint32_t name; 199 const char *region_name; 200 201 if (INTEL_DEBUG & DEBUG_DRI) 202 fprintf(stderr, "enter %s, drawable %p\n", __func__, drawable); 203 204 screen = intel->intelScreen->driScrnPriv; 205 206 if (screen->dri2.loader 207 && (screen->dri2.loader->base.version > 2) 208 && (screen->dri2.loader->getBuffersWithFormat != NULL)) { 209 210 front_rb = intel_get_renderbuffer(fb, BUFFER_FRONT_LEFT); 211 back_rb = intel_get_renderbuffer(fb, BUFFER_BACK_LEFT); 212 depth_rb = intel_get_renderbuffer(fb, BUFFER_DEPTH); 213 stencil_rb = intel_get_renderbuffer(fb, BUFFER_STENCIL); 214 215 i = 0; 216 if ((intel->is_front_buffer_rendering || 217 intel->is_front_buffer_reading || 218 !back_rb) && front_rb) { 219 attachments[i++] = __DRI_BUFFER_FRONT_LEFT; 220 attachments[i++] = intel_bits_per_pixel(front_rb); 221 } 222 223 if (back_rb) { 224 attachments[i++] = __DRI_BUFFER_BACK_LEFT; 225 attachments[i++] = intel_bits_per_pixel(back_rb); 226 } 227 228 if ((depth_rb != NULL) && (stencil_rb != NULL)) { 229 attachments[i++] = __DRI_BUFFER_DEPTH_STENCIL; 230 attachments[i++] = intel_bits_per_pixel(depth_rb); 231 } else if (depth_rb != NULL) { 232 attachments[i++] = __DRI_BUFFER_DEPTH; 233 attachments[i++] = intel_bits_per_pixel(depth_rb); 234 } else if (stencil_rb != NULL) { 235 attachments[i++] = __DRI_BUFFER_STENCIL; 236 attachments[i++] = intel_bits_per_pixel(stencil_rb); 237 } 238 239 buffers = 240 (*screen->dri2.loader->getBuffersWithFormat)(drawable, 241 &drawable->w, 242 &drawable->h, 243 attachments, i / 2, 244 &count, 245 drawable->loaderPrivate); 246 } else if (screen->dri2.loader) { 247 i = 0; 248 if (intel_get_renderbuffer(fb, BUFFER_FRONT_LEFT)) 249 attachments[i++] = __DRI_BUFFER_FRONT_LEFT; 250 if (intel_get_renderbuffer(fb, BUFFER_BACK_LEFT)) 251 attachments[i++] = __DRI_BUFFER_BACK_LEFT; 252 if (intel_get_renderbuffer(fb, BUFFER_DEPTH)) 253 attachments[i++] = __DRI_BUFFER_DEPTH; 254 if (intel_get_renderbuffer(fb, BUFFER_STENCIL)) 255 attachments[i++] = __DRI_BUFFER_STENCIL; 256 257 buffers = (*screen->dri2.loader->getBuffers)(drawable, 258 &drawable->w, 259 &drawable->h, 260 attachments, i, 261 &count, 262 drawable->loaderPrivate); 263 } 264 265 if (buffers == NULL) 266 return; 267 268 drawable->x = 0; 269 drawable->y = 0; 270 drawable->backX = 0; 271 drawable->backY = 0; 272 drawable->numClipRects = 1; 273 drawable->pClipRects[0].x1 = 0; 274 drawable->pClipRects[0].y1 = 0; 275 drawable->pClipRects[0].x2 = drawable->w; 276 drawable->pClipRects[0].y2 = drawable->h; 277 drawable->numBackClipRects = 1; 278 drawable->pBackClipRects[0].x1 = 0; 279 drawable->pBackClipRects[0].y1 = 0; 280 drawable->pBackClipRects[0].x2 = drawable->w; 281 drawable->pBackClipRects[0].y2 = drawable->h; 282 283 depth_region = NULL; 284 for (i = 0; i < count; i++) { 285 switch (buffers[i].attachment) { 286 case __DRI_BUFFER_FRONT_LEFT: 287 rb = intel_get_renderbuffer(fb, BUFFER_FRONT_LEFT); 288 region_name = "dri2 front buffer"; 289 break; 290 291 case __DRI_BUFFER_FAKE_FRONT_LEFT: 292 rb = intel_get_renderbuffer(fb, BUFFER_FRONT_LEFT); 293 region_name = "dri2 fake front buffer"; 294 break; 295 296 case __DRI_BUFFER_BACK_LEFT: 297 rb = intel_get_renderbuffer(fb, BUFFER_BACK_LEFT); 298 region_name = "dri2 back buffer"; 299 break; 300 301 case __DRI_BUFFER_DEPTH: 302 rb = intel_get_renderbuffer(fb, BUFFER_DEPTH); 303 region_name = "dri2 depth buffer"; 304 break; 305 306 case __DRI_BUFFER_DEPTH_STENCIL: 307 rb = intel_get_renderbuffer(fb, BUFFER_DEPTH); 308 region_name = "dri2 depth / stencil buffer"; 309 break; 310 311 case __DRI_BUFFER_STENCIL: 312 rb = intel_get_renderbuffer(fb, BUFFER_STENCIL); 313 region_name = "dri2 stencil buffer"; 314 break; 315 316 case __DRI_BUFFER_ACCUM: 317 default: 318 fprintf(stderr, 319 "unhandled buffer attach event, attacment type %d\n", 320 buffers[i].attachment); 321 return; 322 } 323 324 if (rb == NULL) 325 continue; 326 327 if (rb->region) { 328 dri_bo_flink(rb->region->buffer, &name); 329 if (name == buffers[i].name) 330 continue; 331 } 332 333 if (INTEL_DEBUG & DEBUG_DRI) 334 fprintf(stderr, 335 "attaching buffer %d, at %d, cpp %d, pitch %d\n", 336 buffers[i].name, buffers[i].attachment, 337 buffers[i].cpp, buffers[i].pitch); 338 339 if (buffers[i].attachment == __DRI_BUFFER_STENCIL && depth_region) { 340 if (INTEL_DEBUG & DEBUG_DRI) 341 fprintf(stderr, "(reusing depth buffer as stencil)\n"); 342 intel_region_reference(®ion, depth_region); 343 } 344 else 345 region = intel_region_alloc_for_handle(intel, buffers[i].cpp, 346 drawable->w, 347 drawable->h, 348 buffers[i].pitch / buffers[i].cpp, 349 buffers[i].name, 350 region_name); 351 352 if (buffers[i].attachment == __DRI_BUFFER_DEPTH) 353 depth_region = region; 354 355 intel_renderbuffer_set_region(rb, region); 356 intel_region_release(®ion); 357 358 if (buffers[i].attachment == __DRI_BUFFER_DEPTH_STENCIL) { 359 rb = intel_get_renderbuffer(fb, BUFFER_STENCIL); 360 if (rb != NULL) { 361 struct intel_region *stencil_region = NULL; 362 363 if (rb->region) { 364 dri_bo_flink(rb->region->buffer, &name); 365 if (name == buffers[i].name) 366 continue; 367 } 368 369 intel_region_reference(&stencil_region, region); 370 intel_renderbuffer_set_region(rb, stencil_region); 371 intel_region_release(&stencil_region); 372 } 373 } 374 } 375 376 drawable->validBuffers = GL_TRUE; 377 driUpdateFramebufferSize(&intel->ctx, drawable); 378} 379 380void 381intel_viewport(GLcontext *ctx, GLint x, GLint y, GLsizei w, GLsizei h) 382{ 383 struct intel_context *intel = intel_context(ctx); 384 __DRIcontext *driContext = intel->driContext; 385 void (*old_viewport)(GLcontext *ctx, GLint x, GLint y, 386 GLsizei w, GLsizei h); 387 388 if (!intel->meta.internal_viewport_call && ctx->DrawBuffer->Name == 0) { 389 /* If we're rendering to the fake front buffer, make sure all the pending 390 * drawing has landed on the real front buffer. Otherwise when we 391 * eventually get to DRI2GetBuffersWithFormat the stale real front 392 * buffer contents will get copied to the new fake front buffer. 393 */ 394 if (intel->is_front_buffer_rendering) { 395 intel_flush(ctx, GL_FALSE); 396 } 397 398 intel_update_renderbuffers(driContext, driContext->driDrawablePriv); 399 if (driContext->driDrawablePriv != driContext->driReadablePriv) 400 intel_update_renderbuffers(driContext, driContext->driReadablePriv); 401 } 402 403 old_viewport = ctx->Driver.Viewport; 404 ctx->Driver.Viewport = NULL; 405 intel->driDrawable = driContext->driDrawablePriv; 406 intel_draw_buffer(ctx, intel->ctx.DrawBuffer); 407 ctx->Driver.Viewport = old_viewport; 408} 409 410 411static const struct dri_debug_control debug_control[] = { 412 { "tex", DEBUG_TEXTURE}, 413 { "state", DEBUG_STATE}, 414 { "ioctl", DEBUG_IOCTL}, 415 { "blit", DEBUG_BLIT}, 416 { "mip", DEBUG_MIPTREE}, 417 { "fall", DEBUG_FALLBACKS}, 418 { "verb", DEBUG_VERBOSE}, 419 { "bat", DEBUG_BATCH}, 420 { "pix", DEBUG_PIXEL}, 421 { "buf", DEBUG_BUFMGR}, 422 { "reg", DEBUG_REGION}, 423 { "fbo", DEBUG_FBO}, 424 { "lock", DEBUG_LOCK}, 425 { "sync", DEBUG_SYNC}, 426 { "prim", DEBUG_PRIMS }, 427 { "vert", DEBUG_VERTS }, 428 { "dri", DEBUG_DRI }, 429 { "dma", DEBUG_DMA }, 430 { "san", DEBUG_SANITY }, 431 { "sleep", DEBUG_SLEEP }, 432 { "stats", DEBUG_STATS }, 433 { "tile", DEBUG_TILE }, 434 { "sing", DEBUG_SINGLE_THREAD }, 435 { "thre", DEBUG_SINGLE_THREAD }, 436 { "wm", DEBUG_WM }, 437 { "urb", DEBUG_URB }, 438 { "vs", DEBUG_VS }, 439 { NULL, 0 } 440}; 441 442 443static void 444intelInvalidateState(GLcontext * ctx, GLuint new_state) 445{ 446 struct intel_context *intel = intel_context(ctx); 447 448 _swrast_InvalidateState(ctx, new_state); 449 _swsetup_InvalidateState(ctx, new_state); 450 _vbo_InvalidateState(ctx, new_state); 451 _tnl_InvalidateState(ctx, new_state); 452 _tnl_invalidate_vertex_state(ctx, new_state); 453 454 intel->NewGLState |= new_state; 455 456 if (intel->vtbl.invalidate_state) 457 intel->vtbl.invalidate_state( intel, new_state ); 458} 459 460void 461intel_flush(GLcontext *ctx, GLboolean needs_mi_flush) 462{ 463 struct intel_context *intel = intel_context(ctx); 464 465 if (intel->Fallback) 466 _swrast_flush(ctx); 467 468 if (intel->gen < 4) 469 INTEL_FIREVERTICES(intel); 470 471 if (intel->batch->map != intel->batch->ptr) 472 intel_batchbuffer_flush(intel->batch); 473 474 if ((ctx->DrawBuffer->Name == 0) && intel->front_buffer_dirty) { 475 __DRIscreen *const screen = intel->intelScreen->driScrnPriv; 476 477 if (screen->dri2.loader && 478 (screen->dri2.loader->base.version >= 2) 479 && (screen->dri2.loader->flushFrontBuffer != NULL) && 480 intel->driDrawable && intel->driDrawable->loaderPrivate) { 481 (*screen->dri2.loader->flushFrontBuffer)(intel->driDrawable, 482 intel->driDrawable->loaderPrivate); 483 484 /* Only clear the dirty bit if front-buffer rendering is no longer 485 * enabled. This is done so that the dirty bit can only be set in 486 * glDrawBuffer. Otherwise the dirty bit would have to be set at 487 * each of N places that do rendering. This has worse performances, 488 * but it is much easier to get correct. 489 */ 490 if (!intel->is_front_buffer_rendering) { 491 intel->front_buffer_dirty = GL_FALSE; 492 } 493 } 494 } 495} 496 497void 498intelFlush(GLcontext * ctx) 499{ 500 intel_flush(ctx, GL_FALSE); 501} 502 503static void 504intel_glFlush(GLcontext *ctx) 505{ 506 struct intel_context *intel = intel_context(ctx); 507 508 intel_flush(ctx, GL_TRUE); 509 510 /* We're using glFlush as an indicator that a frame is done, which is 511 * what DRI2 does before calling SwapBuffers (and means we should catch 512 * people doing front-buffer rendering, as well).. 513 * 514 * Wait for the swapbuffers before the one we just emitted, so we don't 515 * get too many swaps outstanding for apps that are GPU-heavy but not 516 * CPU-heavy. 517 * 518 * Unfortunately, we don't have a handle to the batch containing the swap, 519 * and getting our hands on that doesn't seem worth it, so we just us the 520 * first batch we emitted after the last swap. 521 */ 522 if (!intel->using_dri2_swapbuffers && 523 intel->first_post_swapbuffers_batch != NULL) { 524 drm_intel_bo_wait_rendering(intel->first_post_swapbuffers_batch); 525 drm_intel_bo_unreference(intel->first_post_swapbuffers_batch); 526 intel->first_post_swapbuffers_batch = NULL; 527 } 528} 529 530void 531intelFinish(GLcontext * ctx) 532{ 533 struct gl_framebuffer *fb = ctx->DrawBuffer; 534 int i; 535 536 intelFlush(ctx); 537 538 for (i = 0; i < fb->_NumColorDrawBuffers; i++) { 539 struct intel_renderbuffer *irb; 540 541 irb = intel_renderbuffer(fb->_ColorDrawBuffers[i]); 542 543 if (irb && irb->region) 544 dri_bo_wait_rendering(irb->region->buffer); 545 } 546 if (fb->_DepthBuffer) { 547 /* XXX: Wait on buffer idle */ 548 } 549} 550 551void 552intelInitDriverFunctions(struct dd_function_table *functions) 553{ 554 _mesa_init_driver_functions(functions); 555 556 functions->Flush = intel_glFlush; 557 functions->Finish = intelFinish; 558 functions->GetString = intelGetString; 559 functions->UpdateState = intelInvalidateState; 560 561 intelInitTextureFuncs(functions); 562 intelInitTextureImageFuncs(functions); 563 intelInitTextureSubImageFuncs(functions); 564 intelInitTextureCopyImageFuncs(functions); 565 intelInitStateFuncs(functions); 566 intelInitClearFuncs(functions); 567 intelInitBufferFuncs(functions); 568 intelInitPixelFuncs(functions); 569 intelInitBufferObjectFuncs(functions); 570 intel_init_syncobj_functions(functions); 571} 572 573 574GLboolean 575intelInitContext(struct intel_context *intel, 576 const __GLcontextModes * mesaVis, 577 __DRIcontext * driContextPriv, 578 void *sharedContextPrivate, 579 struct dd_function_table *functions) 580{ 581 GLcontext *ctx = &intel->ctx; 582 GLcontext *shareCtx = (GLcontext *) sharedContextPrivate; 583 __DRIscreen *sPriv = driContextPriv->driScreenPriv; 584 intelScreenPrivate *intelScreen = (intelScreenPrivate *) sPriv->private; 585 int bo_reuse_mode; 586 587 if (!_mesa_initialize_context(&intel->ctx, mesaVis, shareCtx, 588 functions, (void *) intel)) { 589 _mesa_printf("%s: failed to init mesa context\n", __FUNCTION__); 590 return GL_FALSE; 591 } 592 593 driContextPriv->driverPrivate = intel; 594 intel->intelScreen = intelScreen; 595 intel->driScreen = sPriv; 596 intel->driContext = driContextPriv; 597 intel->driFd = sPriv->fd; 598 599 if (IS_965(intel->intelScreen->deviceID)) { 600 intel->gen = 4; 601 } else if (IS_9XX(intel->intelScreen->deviceID)) { 602 intel->gen = 3; 603 if (IS_945(intel->intelScreen->deviceID)) { 604 intel->is_945 = GL_TRUE; 605 } 606 } else { 607 intel->gen = 2; 608 } 609 610 if (IS_IGDNG(intel->intelScreen->deviceID)) { 611 intel->is_ironlake = GL_TRUE; 612 intel->needs_ff_sync = GL_TRUE; 613 intel->has_luminance_srgb = GL_TRUE; 614 } else if (IS_G4X(intel->intelScreen->deviceID)) { 615 intel->has_luminance_srgb = GL_TRUE; 616 intel->is_g4x = GL_TRUE; 617 } 618 619 driParseConfigFiles(&intel->optionCache, &intelScreen->optionCache, 620 intel->driScreen->myNum, 621 (intel->gen >= 4) ? "i965" : "i915"); 622 if (intelScreen->deviceID == PCI_CHIP_I865_G) 623 intel->maxBatchSize = 4096; 624 else 625 intel->maxBatchSize = BATCH_SZ; 626 627 intel->bufmgr = intelScreen->bufmgr; 628 629 bo_reuse_mode = driQueryOptioni(&intel->optionCache, "bo_reuse"); 630 switch (bo_reuse_mode) { 631 case DRI_CONF_BO_REUSE_DISABLED: 632 break; 633 case DRI_CONF_BO_REUSE_ALL: 634 intel_bufmgr_gem_enable_reuse(intel->bufmgr); 635 break; 636 } 637 638 /* This doesn't yet catch all non-conformant rendering, but it's a 639 * start. 640 */ 641 if (getenv("INTEL_STRICT_CONFORMANCE")) { 642 unsigned int value = atoi(getenv("INTEL_STRICT_CONFORMANCE")); 643 if (value > 0) { 644 intel->conformance_mode = value; 645 } 646 else { 647 intel->conformance_mode = 1; 648 } 649 } 650 651 if (intel->conformance_mode > 0) { 652 ctx->Const.MinLineWidth = 1.0; 653 ctx->Const.MinLineWidthAA = 1.0; 654 ctx->Const.MaxLineWidth = 1.0; 655 ctx->Const.MaxLineWidthAA = 1.0; 656 ctx->Const.LineWidthGranularity = 1.0; 657 } 658 else { 659 ctx->Const.MinLineWidth = 1.0; 660 ctx->Const.MinLineWidthAA = 1.0; 661 ctx->Const.MaxLineWidth = 5.0; 662 ctx->Const.MaxLineWidthAA = 5.0; 663 ctx->Const.LineWidthGranularity = 0.5; 664 } 665 666 ctx->Const.MinPointSize = 1.0; 667 ctx->Const.MinPointSizeAA = 1.0; 668 ctx->Const.MaxPointSize = 255.0; 669 ctx->Const.MaxPointSizeAA = 3.0; 670 ctx->Const.PointSizeGranularity = 1.0; 671 672 /* reinitialize the context point state. 673 * It depend on constants in __GLcontextRec::Const 674 */ 675 _mesa_init_point(ctx); 676 677 meta_init_metaops(ctx, &intel->meta); 678 ctx->Const.MaxColorAttachments = 4; /* XXX FBO: review this */ 679 if (intel->gen >= 4) { 680 if (MAX_WIDTH > 8192) 681 ctx->Const.MaxRenderbufferSize = 8192; 682 } else { 683 if (MAX_WIDTH > 2048) 684 ctx->Const.MaxRenderbufferSize = 2048; 685 } 686 687 /* Initialize the software rasterizer and helper modules. */ 688 _swrast_CreateContext(ctx); 689 _vbo_CreateContext(ctx); 690 _tnl_CreateContext(ctx); 691 _swsetup_CreateContext(ctx); 692 693 /* Configure swrast to match hardware characteristics: */ 694 _swrast_allow_pixel_fog(ctx, GL_FALSE); 695 _swrast_allow_vertex_fog(ctx, GL_TRUE); 696 697 _mesa_meta_init(ctx); 698 699 intel->hw_stencil = mesaVis->stencilBits && mesaVis->depthBits == 24; 700 intel->hw_stipple = 1; 701 702 /* XXX FBO: this doesn't seem to be used anywhere */ 703 switch (mesaVis->depthBits) { 704 case 0: /* what to do in this case? */ 705 case 16: 706 intel->polygon_offset_scale = 1.0; 707 break; 708 case 24: 709 intel->polygon_offset_scale = 2.0; /* req'd to pass glean */ 710 break; 711 default: 712 assert(0); 713 break; 714 } 715 716 if (intel->gen >= 4) 717 intel->polygon_offset_scale /= 0xffff; 718 719 intel->RenderIndex = ~0; 720 721 if (intel->gen >= 4 && !intel->intelScreen->irq_active) { 722 _mesa_printf("IRQs not active. Exiting\n"); 723 exit(1); 724 } 725 726 intelInitExtensions(ctx); 727 728 INTEL_DEBUG = driParseDebugString(getenv("INTEL_DEBUG"), debug_control); 729 if (INTEL_DEBUG & DEBUG_BUFMGR) 730 dri_bufmgr_set_debug(intel->bufmgr, GL_TRUE); 731 732 intel->batch = intel_batchbuffer_alloc(intel); 733 734 intel_fbo_init(intel); 735 736 if (intel->ctx.Mesa_DXTn) { 737 _mesa_enable_extension(ctx, "GL_EXT_texture_compression_s3tc"); 738 _mesa_enable_extension(ctx, "GL_S3_s3tc"); 739 } 740 else if (driQueryOptionb(&intel->optionCache, "force_s3tc_enable")) { 741 _mesa_enable_extension(ctx, "GL_EXT_texture_compression_s3tc"); 742 } 743 intel->use_texture_tiling = driQueryOptionb(&intel->optionCache, 744 "texture_tiling"); 745 if (intel->use_texture_tiling && 746 !intel->intelScreen->kernel_exec_fencing) { 747 fprintf(stderr, "No kernel support for execution fencing, " 748 "disabling texture tiling\n"); 749 intel->use_texture_tiling = GL_FALSE; 750 } 751 intel->use_early_z = driQueryOptionb(&intel->optionCache, "early_z"); 752 753 intel->prim.primitive = ~0; 754 755 /* Force all software fallbacks */ 756 if (driQueryOptionb(&intel->optionCache, "no_rast")) { 757 fprintf(stderr, "disabling 3D rasterization\n"); 758 intel->no_rast = 1; 759 } 760 761 if (driQueryOptionb(&intel->optionCache, "always_flush_batch")) { 762 fprintf(stderr, "flushing batchbuffer before/after each draw call\n"); 763 intel->always_flush_batch = 1; 764 } 765 766 if (driQueryOptionb(&intel->optionCache, "always_flush_cache")) { 767 fprintf(stderr, "flushing GPU caches before/after each draw call\n"); 768 intel->always_flush_cache = 1; 769 } 770 771 /* Disable all hardware rendering (skip emitting batches and fences/waits 772 * to the kernel) 773 */ 774 intel->no_hw = getenv("INTEL_NO_HW") != NULL; 775 776 return GL_TRUE; 777} 778 779void 780intelDestroyContext(__DRIcontext * driContextPriv) 781{ 782 struct intel_context *intel = 783 (struct intel_context *) driContextPriv->driverPrivate; 784 785 assert(intel); /* should never be null */ 786 if (intel) { 787 GLboolean release_texture_heaps; 788 789 INTEL_FIREVERTICES(intel); 790 791 _mesa_meta_free(&intel->ctx); 792 793 meta_destroy_metaops(&intel->meta); 794 795 intel->vtbl.destroy(intel); 796 797 release_texture_heaps = (intel->ctx.Shared->RefCount == 1); 798 _swsetup_DestroyContext(&intel->ctx); 799 _tnl_DestroyContext(&intel->ctx); 800 _vbo_DestroyContext(&intel->ctx); 801 802 _swrast_DestroyContext(&intel->ctx); 803 intel->Fallback = 0x0; /* don't call _swrast_Flush later */ 804 805 intel_batchbuffer_free(intel->batch); 806 intel->batch = NULL; 807 808 free(intel->prim.vb); 809 intel->prim.vb = NULL; 810 dri_bo_unreference(intel->prim.vb_bo); 811 intel->prim.vb_bo = NULL; 812 dri_bo_unreference(intel->first_post_swapbuffers_batch); 813 intel->first_post_swapbuffers_batch = NULL; 814 815 if (release_texture_heaps) { 816 /* Nothing is currently done here to free texture heaps; 817 * but we're not using the texture heap utilities, so I 818 * rather think we shouldn't. I've taken a look, and can't 819 * find any private texture data hanging around anywhere, but 820 * I'm not yet certain there isn't any at all... 821 */ 822 /* if (INTEL_DEBUG & DEBUG_TEXTURE) 823 fprintf(stderr, "do something to free texture heaps\n"); 824 */ 825 } 826 827 driDestroyOptionCache(&intel->optionCache); 828 829 /* free the Mesa context */ 830 _mesa_free_context_data(&intel->ctx); 831 832 FREE(intel); 833 driContextPriv->driverPrivate = NULL; 834 } 835} 836 837GLboolean 838intelUnbindContext(__DRIcontext * driContextPriv) 839{ 840 struct intel_context *intel = 841 (struct intel_context *) driContextPriv->driverPrivate; 842 843 /* Deassociate the context with the drawables. 844 */ 845 intel->driDrawable = NULL; 846 intel->driReadDrawable = NULL; 847 848 return GL_TRUE; 849} 850 851GLboolean 852intelMakeCurrent(__DRIcontext * driContextPriv, 853 __DRIdrawable * driDrawPriv, 854 __DRIdrawable * driReadPriv) 855{ 856 struct intel_context *intel; 857 GET_CURRENT_CONTEXT(curCtx); 858 859 if (driContextPriv) 860 intel = (struct intel_context *) driContextPriv->driverPrivate; 861 else 862 intel = NULL; 863 864 /* According to the glXMakeCurrent() man page: "Pending commands to 865 * the previous context, if any, are flushed before it is released." 866 * But only flush if we're actually changing contexts. 867 */ 868 if (intel_context(curCtx) && intel_context(curCtx) != intel) { 869 _mesa_flush(curCtx); 870 } 871 872 if (driContextPriv) { 873 struct gl_framebuffer *fb = driDrawPriv->driverPrivate; 874 struct gl_framebuffer *readFb = driReadPriv->driverPrivate; 875 876 intel_update_renderbuffers(driContextPriv, driDrawPriv); 877 if (driDrawPriv != driReadPriv) 878 intel_update_renderbuffers(driContextPriv, driReadPriv); 879 880 /* set GLframebuffer size to match window, if needed */ 881 driUpdateFramebufferSize(&intel->ctx, driDrawPriv); 882 883 if (driReadPriv != driDrawPriv) { 884 driUpdateFramebufferSize(&intel->ctx, driReadPriv); 885 } 886 887 _mesa_make_current(&intel->ctx, fb, readFb); 888 intel->driReadDrawable = driReadPriv; 889 intel->driDrawable = driDrawPriv; 890 intel_draw_buffer(&intel->ctx, fb); 891 } 892 else { 893 _mesa_make_current(NULL, NULL, NULL); 894 } 895 896 return GL_TRUE; 897} 898