intel_screen.c revision 636646a481ef6ce29e74e4604125a42def3ed1e5
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 <errno.h> 29#include "main/glheader.h" 30#include "main/context.h" 31#include "main/framebuffer.h" 32#include "main/renderbuffer.h" 33#include "main/hash.h" 34#include "main/fbobject.h" 35#include "main/mfeatures.h" 36#include "main/version.h" 37#include "swrast/s_renderbuffer.h" 38 39#include "utils.h" 40#include "xmlpool.h" 41 42PUBLIC const char __driConfigOptions[] = 43 DRI_CONF_BEGIN 44 DRI_CONF_SECTION_PERFORMANCE 45 DRI_CONF_VBLANK_MODE(DRI_CONF_VBLANK_ALWAYS_SYNC) 46 /* Options correspond to DRI_CONF_BO_REUSE_DISABLED, 47 * DRI_CONF_BO_REUSE_ALL 48 */ 49 DRI_CONF_OPT_BEGIN_V(bo_reuse, enum, 1, "0:1") 50 DRI_CONF_DESC_BEGIN(en, "Buffer object reuse") 51 DRI_CONF_ENUM(0, "Disable buffer object reuse") 52 DRI_CONF_ENUM(1, "Enable reuse of all sizes of buffer objects") 53 DRI_CONF_DESC_END 54 DRI_CONF_OPT_END 55 56 DRI_CONF_OPT_BEGIN(texture_tiling, bool, true) 57 DRI_CONF_DESC(en, "Enable texture tiling") 58 DRI_CONF_OPT_END 59 60 DRI_CONF_OPT_BEGIN(hiz, bool, true) 61 DRI_CONF_DESC(en, "Enable Hierarchical Z on gen6+") 62 DRI_CONF_OPT_END 63 64 DRI_CONF_OPT_BEGIN(early_z, bool, false) 65 DRI_CONF_DESC(en, "Enable early Z in classic mode (unstable, 945-only).") 66 DRI_CONF_OPT_END 67 68 DRI_CONF_OPT_BEGIN(fragment_shader, bool, true) 69 DRI_CONF_DESC(en, "Enable limited ARB_fragment_shader support on 915/945.") 70 DRI_CONF_OPT_END 71 72 DRI_CONF_SECTION_END 73 DRI_CONF_SECTION_QUALITY 74 DRI_CONF_FORCE_S3TC_ENABLE(false) 75 DRI_CONF_ALLOW_LARGE_TEXTURES(2) 76 DRI_CONF_SECTION_END 77 DRI_CONF_SECTION_DEBUG 78 DRI_CONF_NO_RAST(false) 79 DRI_CONF_ALWAYS_FLUSH_BATCH(false) 80 DRI_CONF_ALWAYS_FLUSH_CACHE(false) 81 DRI_CONF_FORCE_GLSL_EXTENSIONS_WARN(false) 82 83 DRI_CONF_OPT_BEGIN(stub_occlusion_query, bool, false) 84 DRI_CONF_DESC(en, "Enable stub ARB_occlusion_query support on 915/945.") 85 DRI_CONF_OPT_END 86 87 DRI_CONF_OPT_BEGIN(shader_precompile, bool, false) 88 DRI_CONF_DESC(en, "Perform code generation at shader link time.") 89 DRI_CONF_OPT_END 90 DRI_CONF_SECTION_END 91DRI_CONF_END; 92 93const GLuint __driNConfigOptions = 14; 94 95#include "intel_batchbuffer.h" 96#include "intel_buffers.h" 97#include "intel_bufmgr.h" 98#include "intel_chipset.h" 99#include "intel_fbo.h" 100#include "intel_mipmap_tree.h" 101#include "intel_screen.h" 102#include "intel_tex.h" 103#include "intel_regions.h" 104 105#include "i915_drm.h" 106 107#ifdef USE_NEW_INTERFACE 108static PFNGLXCREATECONTEXTMODES create_context_modes = NULL; 109#endif /*USE_NEW_INTERFACE */ 110 111void 112aub_dump_bmp(struct gl_context *ctx) 113{ 114 struct gl_framebuffer *fb = ctx->DrawBuffer; 115 116 for (int i = 0; i < fb->_NumColorDrawBuffers; i++) { 117 struct intel_renderbuffer *irb = 118 intel_renderbuffer(fb->_ColorDrawBuffers[i]); 119 120 if (irb && irb->mt) { 121 enum aub_dump_bmp_format format; 122 123 switch (irb->Base.Base.Format) { 124 case MESA_FORMAT_ARGB8888: 125 case MESA_FORMAT_XRGB8888: 126 format = AUB_DUMP_BMP_FORMAT_ARGB_8888; 127 break; 128 default: 129 continue; 130 } 131 132 drm_intel_gem_bo_aub_dump_bmp(irb->mt->region->bo, 133 irb->draw_x, 134 irb->draw_y, 135 irb->Base.Base.Width, 136 irb->Base.Base.Height, 137 format, 138 irb->mt->region->pitch * 139 irb->mt->region->cpp, 140 0); 141 } 142 } 143} 144 145static const __DRItexBufferExtension intelTexBufferExtension = { 146 { __DRI_TEX_BUFFER, __DRI_TEX_BUFFER_VERSION }, 147 intelSetTexBuffer, 148 intelSetTexBuffer2, 149}; 150 151static void 152intelDRI2Flush(__DRIdrawable *drawable) 153{ 154 GET_CURRENT_CONTEXT(ctx); 155 struct intel_context *intel = intel_context(ctx); 156 if (intel == NULL) 157 return; 158 159 if (intel->gen < 4) 160 INTEL_FIREVERTICES(intel); 161 162 intel->need_throttle = true; 163 164 if (intel->batch.used) 165 intel_batchbuffer_flush(intel); 166 167 if (INTEL_DEBUG & DEBUG_AUB) { 168 aub_dump_bmp(ctx); 169 } 170} 171 172static const struct __DRI2flushExtensionRec intelFlushExtension = { 173 { __DRI2_FLUSH, __DRI2_FLUSH_VERSION }, 174 intelDRI2Flush, 175 dri2InvalidateDrawable, 176}; 177 178static __DRIimage * 179intel_allocate_image(int dri_format, void *loaderPrivate) 180{ 181 __DRIimage *image; 182 183 image = CALLOC(sizeof *image); 184 if (image == NULL) 185 return NULL; 186 187 image->dri_format = dri_format; 188 image->offset = 0; 189 190 switch (dri_format) { 191 case __DRI_IMAGE_FORMAT_RGB565: 192 image->format = MESA_FORMAT_RGB565; 193 break; 194 case __DRI_IMAGE_FORMAT_XRGB8888: 195 image->format = MESA_FORMAT_XRGB8888; 196 break; 197 case __DRI_IMAGE_FORMAT_ARGB8888: 198 image->format = MESA_FORMAT_ARGB8888; 199 break; 200 case __DRI_IMAGE_FORMAT_ABGR8888: 201 image->format = MESA_FORMAT_RGBA8888_REV; 202 break; 203 case __DRI_IMAGE_FORMAT_XBGR8888: 204 image->format = MESA_FORMAT_RGBX8888_REV; 205 break; 206 case __DRI_IMAGE_FORMAT_R8: 207 image->format = MESA_FORMAT_R8; 208 break; 209 case __DRI_IMAGE_FORMAT_GR88: 210 image->format = MESA_FORMAT_GR88; 211 break; 212 case __DRI_IMAGE_FORMAT_NONE: 213 image->format = MESA_FORMAT_NONE; 214 break; 215 default: 216 free(image); 217 return NULL; 218 } 219 220 image->internal_format = _mesa_get_format_base_format(image->format); 221 image->data = loaderPrivate; 222 223 return image; 224} 225 226static __DRIimage * 227intel_create_image_from_name(__DRIscreen *screen, 228 int width, int height, int format, 229 int name, int pitch, void *loaderPrivate) 230{ 231 struct intel_screen *intelScreen = screen->driverPrivate; 232 __DRIimage *image; 233 int cpp; 234 235 image = intel_allocate_image(format, loaderPrivate); 236 if (image->format == MESA_FORMAT_NONE) 237 cpp = 0; 238 else 239 cpp = _mesa_get_format_bytes(image->format); 240 image->region = intel_region_alloc_for_handle(intelScreen, 241 cpp, width, height, 242 pitch, name, "image"); 243 if (image->region == NULL) { 244 FREE(image); 245 return NULL; 246 } 247 248 return image; 249} 250 251static __DRIimage * 252intel_create_image_from_renderbuffer(__DRIcontext *context, 253 int renderbuffer, void *loaderPrivate) 254{ 255 __DRIimage *image; 256 struct intel_context *intel = context->driverPrivate; 257 struct gl_renderbuffer *rb; 258 struct intel_renderbuffer *irb; 259 260 rb = _mesa_lookup_renderbuffer(&intel->ctx, renderbuffer); 261 if (!rb) { 262 _mesa_error(&intel->ctx, 263 GL_INVALID_OPERATION, "glRenderbufferExternalMESA"); 264 return NULL; 265 } 266 267 irb = intel_renderbuffer(rb); 268 image = CALLOC(sizeof *image); 269 if (image == NULL) 270 return NULL; 271 272 image->internal_format = rb->InternalFormat; 273 image->format = rb->Format; 274 image->offset = 0; 275 image->data = loaderPrivate; 276 intel_region_reference(&image->region, irb->mt->region); 277 278 switch (image->format) { 279 case MESA_FORMAT_RGB565: 280 image->dri_format = __DRI_IMAGE_FORMAT_RGB565; 281 break; 282 case MESA_FORMAT_XRGB8888: 283 image->dri_format = __DRI_IMAGE_FORMAT_XRGB8888; 284 break; 285 case MESA_FORMAT_ARGB8888: 286 image->dri_format = __DRI_IMAGE_FORMAT_ARGB8888; 287 break; 288 case MESA_FORMAT_RGBA8888_REV: 289 image->dri_format = __DRI_IMAGE_FORMAT_ABGR8888; 290 break; 291 case MESA_FORMAT_R8: 292 image->dri_format = __DRI_IMAGE_FORMAT_R8; 293 break; 294 case MESA_FORMAT_RG88: 295 image->dri_format = __DRI_IMAGE_FORMAT_GR88; 296 break; 297 } 298 299 return image; 300} 301 302static void 303intel_destroy_image(__DRIimage *image) 304{ 305 intel_region_release(&image->region); 306 FREE(image); 307} 308 309static __DRIimage * 310intel_create_image(__DRIscreen *screen, 311 int width, int height, int format, 312 unsigned int use, 313 void *loaderPrivate) 314{ 315 __DRIimage *image; 316 struct intel_screen *intelScreen = screen->driverPrivate; 317 uint32_t tiling; 318 int cpp; 319 320 tiling = I915_TILING_X; 321 if (use & __DRI_IMAGE_USE_CURSOR) { 322 if (width != 64 || height != 64) 323 return NULL; 324 tiling = I915_TILING_NONE; 325 } 326 327 /* We only support write for cursor drm images */ 328 if ((use & __DRI_IMAGE_USE_WRITE) && 329 use != (__DRI_IMAGE_USE_WRITE | __DRI_IMAGE_USE_CURSOR)) 330 return NULL; 331 332 image = intel_allocate_image(format, loaderPrivate); 333 image->usage = use; 334 cpp = _mesa_get_format_bytes(image->format); 335 image->region = 336 intel_region_alloc(intelScreen, tiling, cpp, width, height, true); 337 if (image->region == NULL) { 338 FREE(image); 339 return NULL; 340 } 341 342 return image; 343} 344 345static GLboolean 346intel_query_image(__DRIimage *image, int attrib, int *value) 347{ 348 switch (attrib) { 349 case __DRI_IMAGE_ATTRIB_STRIDE: 350 *value = image->region->pitch * image->region->cpp; 351 return true; 352 case __DRI_IMAGE_ATTRIB_HANDLE: 353 *value = image->region->bo->handle; 354 return true; 355 case __DRI_IMAGE_ATTRIB_NAME: 356 return intel_region_flink(image->region, (uint32_t *) value); 357 case __DRI_IMAGE_ATTRIB_FORMAT: 358 *value = image->dri_format; 359 return true; 360 default: 361 return false; 362 } 363} 364 365static __DRIimage * 366intel_dup_image(__DRIimage *orig_image, void *loaderPrivate) 367{ 368 __DRIimage *image; 369 370 image = CALLOC(sizeof *image); 371 if (image == NULL) 372 return NULL; 373 374 intel_region_reference(&image->region, orig_image->region); 375 if (image->region == NULL) { 376 FREE(image); 377 return NULL; 378 } 379 380 image->internal_format = orig_image->internal_format; 381 image->usage = orig_image->usage; 382 image->dri_format = orig_image->dri_format; 383 image->format = orig_image->format; 384 image->offset = orig_image->offset; 385 image->data = loaderPrivate; 386 387 return image; 388} 389 390static GLboolean 391intel_validate_usage(__DRIimage *image, unsigned int use) 392{ 393 if (use & __DRI_IMAGE_USE_CURSOR) { 394 if (image->region->width != 64 || image->region->height != 64) 395 return GL_FALSE; 396 } 397 398 /* We only support write for cursor drm images */ 399 if ((use & __DRI_IMAGE_USE_WRITE) && 400 use != (__DRI_IMAGE_USE_WRITE | __DRI_IMAGE_USE_CURSOR)) 401 return GL_FALSE; 402 403 return GL_TRUE; 404} 405 406static int 407intel_image_write(__DRIimage *image, const void *buf, size_t count) 408{ 409 if (image->region->map_refcount) 410 return -1; 411 if (!(image->usage & __DRI_IMAGE_USE_WRITE)) 412 return -1; 413 414 drm_intel_bo_map(image->region->bo, true); 415 memcpy(image->region->bo->virtual, buf, count); 416 drm_intel_bo_unmap(image->region->bo); 417 418 return 0; 419} 420 421static __DRIimage * 422intel_create_sub_image(__DRIimage *parent, 423 int width, int height, int dri_format, 424 int offset, int pitch, void *loaderPrivate) 425{ 426 __DRIimage *image; 427 int cpp; 428 uint32_t mask_x, mask_y; 429 430 image = intel_allocate_image(dri_format, loaderPrivate); 431 cpp = _mesa_get_format_bytes(image->format); 432 if (offset + height * cpp * pitch > parent->region->bo->size) { 433 _mesa_warning(NULL, "intel_create_sub_image: subimage out of bounds"); 434 FREE(image); 435 return NULL; 436 } 437 438 image->region = calloc(sizeof(*image->region), 1); 439 if (image->region == NULL) { 440 FREE(image); 441 return NULL; 442 } 443 444 image->region->cpp = _mesa_get_format_bytes(image->format); 445 image->region->width = width; 446 image->region->height = height; 447 image->region->pitch = pitch; 448 image->region->refcount = 1; 449 image->region->bo = parent->region->bo; 450 drm_intel_bo_reference(image->region->bo); 451 image->region->tiling = parent->region->tiling; 452 image->region->screen = parent->region->screen; 453 image->offset = offset; 454 455 intel_region_get_tile_masks(image->region, &mask_x, &mask_y); 456 if (offset & mask_x) 457 _mesa_warning(NULL, 458 "intel_create_sub_image: offset not on tile boundary"); 459 460 return image; 461} 462 463static struct __DRIimageExtensionRec intelImageExtension = { 464 { __DRI_IMAGE, 5 }, 465 intel_create_image_from_name, 466 intel_create_image_from_renderbuffer, 467 intel_destroy_image, 468 intel_create_image, 469 intel_query_image, 470 intel_dup_image, 471 intel_validate_usage, 472 intel_image_write, 473 intel_create_sub_image 474}; 475 476static const __DRIextension *intelScreenExtensions[] = { 477 &intelTexBufferExtension.base, 478 &intelFlushExtension.base, 479 &intelImageExtension.base, 480 &dri2ConfigQueryExtension.base, 481 NULL 482}; 483 484static bool 485intel_get_param(__DRIscreen *psp, int param, int *value) 486{ 487 int ret; 488 struct drm_i915_getparam gp; 489 490 memset(&gp, 0, sizeof(gp)); 491 gp.param = param; 492 gp.value = value; 493 494 ret = drmCommandWriteRead(psp->fd, DRM_I915_GETPARAM, &gp, sizeof(gp)); 495 if (ret) { 496 if (ret != -EINVAL) 497 _mesa_warning(NULL, "drm_i915_getparam: %d", ret); 498 return false; 499 } 500 501 return true; 502} 503 504static bool 505intel_get_boolean(__DRIscreen *psp, int param) 506{ 507 int value = 0; 508 return intel_get_param(psp, param, &value) && value; 509} 510 511static void 512nop_callback(GLuint key, void *data, void *userData) 513{ 514} 515 516static void 517intelDestroyScreen(__DRIscreen * sPriv) 518{ 519 struct intel_screen *intelScreen = sPriv->driverPrivate; 520 521 dri_bufmgr_destroy(intelScreen->bufmgr); 522 driDestroyOptionInfo(&intelScreen->optionCache); 523 524 /* Some regions may still have references to them at this point, so 525 * flush the hash table to prevent _mesa_DeleteHashTable() from 526 * complaining about the hash not being empty; */ 527 _mesa_HashDeleteAll(intelScreen->named_regions, nop_callback, NULL); 528 _mesa_DeleteHashTable(intelScreen->named_regions); 529 530 FREE(intelScreen); 531 sPriv->driverPrivate = NULL; 532} 533 534 535/** 536 * This is called when we need to set up GL rendering to a new X window. 537 */ 538static GLboolean 539intelCreateBuffer(__DRIscreen * driScrnPriv, 540 __DRIdrawable * driDrawPriv, 541 const struct gl_config * mesaVis, GLboolean isPixmap) 542{ 543 struct intel_renderbuffer *rb; 544 struct intel_screen *screen = (struct intel_screen*) driScrnPriv->driverPrivate; 545 546 if (isPixmap) { 547 return false; /* not implemented */ 548 } 549 else { 550 gl_format rgbFormat; 551 552 struct gl_framebuffer *fb = CALLOC_STRUCT(gl_framebuffer); 553 554 if (!fb) 555 return false; 556 557 _mesa_initialize_window_framebuffer(fb, mesaVis); 558 559 if (mesaVis->redBits == 5) 560 rgbFormat = MESA_FORMAT_RGB565; 561 else if (mesaVis->alphaBits == 0) 562 rgbFormat = MESA_FORMAT_XRGB8888; 563 else 564 rgbFormat = MESA_FORMAT_ARGB8888; 565 566 /* setup the hardware-based renderbuffers */ 567 rb = intel_create_renderbuffer(rgbFormat); 568 _mesa_add_renderbuffer(fb, BUFFER_FRONT_LEFT, &rb->Base.Base); 569 570 if (mesaVis->doubleBufferMode) { 571 rb = intel_create_renderbuffer(rgbFormat); 572 _mesa_add_renderbuffer(fb, BUFFER_BACK_LEFT, &rb->Base.Base); 573 } 574 575 /* 576 * Assert here that the gl_config has an expected depth/stencil bit 577 * combination: one of d24/s8, d16/s0, d0/s0. (See intelInitScreen2(), 578 * which constructs the advertised configs.) 579 */ 580 if (mesaVis->depthBits == 24) { 581 assert(mesaVis->stencilBits == 8); 582 583 if (screen->hw_has_separate_stencil 584 && screen->dri2_has_hiz != INTEL_DRI2_HAS_HIZ_FALSE) { 585 /* 586 * Request a separate stencil buffer even if we do not yet know if 587 * the screen supports it. (See comments for 588 * enum intel_dri2_has_hiz). 589 */ 590 rb = intel_create_renderbuffer(MESA_FORMAT_X8_Z24); 591 _mesa_add_renderbuffer(fb, BUFFER_DEPTH, &rb->Base.Base); 592 rb = intel_create_renderbuffer(MESA_FORMAT_S8); 593 _mesa_add_renderbuffer(fb, BUFFER_STENCIL, &rb->Base.Base); 594 } else { 595 /* 596 * Use combined depth/stencil. Note that the renderbuffer is 597 * attached to two attachment points. 598 */ 599 rb = intel_create_renderbuffer(MESA_FORMAT_S8_Z24); 600 _mesa_add_renderbuffer(fb, BUFFER_DEPTH, &rb->Base.Base); 601 _mesa_add_renderbuffer(fb, BUFFER_STENCIL, &rb->Base.Base); 602 } 603 } 604 else if (mesaVis->depthBits == 16) { 605 assert(mesaVis->stencilBits == 0); 606 /* just 16-bit depth buffer, no hw stencil */ 607 struct intel_renderbuffer *depthRb 608 = intel_create_renderbuffer(MESA_FORMAT_Z16); 609 _mesa_add_renderbuffer(fb, BUFFER_DEPTH, &depthRb->Base.Base); 610 } 611 else { 612 assert(mesaVis->depthBits == 0); 613 assert(mesaVis->stencilBits == 0); 614 } 615 616 /* now add any/all software-based renderbuffers we may need */ 617 _swrast_add_soft_renderbuffers(fb, 618 false, /* never sw color */ 619 false, /* never sw depth */ 620 false, /* never sw stencil */ 621 mesaVis->accumRedBits > 0, 622 false, /* never sw alpha */ 623 false /* never sw aux */ ); 624 driDrawPriv->driverPrivate = fb; 625 626 return true; 627 } 628} 629 630static void 631intelDestroyBuffer(__DRIdrawable * driDrawPriv) 632{ 633 struct gl_framebuffer *fb = driDrawPriv->driverPrivate; 634 635 _mesa_reference_framebuffer(&fb, NULL); 636} 637 638/* There are probably better ways to do this, such as an 639 * init-designated function to register chipids and createcontext 640 * functions. 641 */ 642extern bool 643i830CreateContext(const struct gl_config *mesaVis, 644 __DRIcontext *driContextPriv, 645 void *sharedContextPrivate); 646 647extern bool 648i915CreateContext(int api, 649 const struct gl_config *mesaVis, 650 __DRIcontext *driContextPriv, 651 void *sharedContextPrivate); 652extern bool 653brwCreateContext(int api, 654 const struct gl_config *mesaVis, 655 __DRIcontext *driContextPriv, 656 void *sharedContextPrivate); 657 658static GLboolean 659intelCreateContext(gl_api api, 660 const struct gl_config * mesaVis, 661 __DRIcontext * driContextPriv, 662 unsigned major_version, 663 unsigned minor_version, 664 uint32_t flags, 665 unsigned *error, 666 void *sharedContextPrivate) 667{ 668 __DRIscreen *sPriv = driContextPriv->driScreenPriv; 669 struct intel_screen *intelScreen = sPriv->driverPrivate; 670 bool success = false; 671 672#ifdef I915 673 if (IS_9XX(intelScreen->deviceID)) { 674 if (!IS_965(intelScreen->deviceID)) { 675 success = i915CreateContext(api, mesaVis, driContextPriv, 676 sharedContextPrivate); 677 } 678 } else { 679 intelScreen->no_vbo = true; 680 success = i830CreateContext(mesaVis, driContextPriv, 681 sharedContextPrivate); 682 } 683#else 684 if (IS_965(intelScreen->deviceID)) 685 success = brwCreateContext(api, mesaVis, 686 driContextPriv, 687 sharedContextPrivate); 688#endif 689 690 if (success) { 691 struct gl_context *ctx = 692 (struct gl_context *) driContextPriv->driverPrivate; 693 694 _mesa_compute_version(ctx); 695 if (ctx->VersionMajor > major_version 696 || (ctx->VersionMajor == major_version 697 && ctx->VersionMinor >= minor_version)) { 698 *error = __DRI_CTX_ERROR_BAD_VERSION; 699 return true; 700 } 701 702 intelDestroyContext(driContextPriv); 703 } else { 704 *error = __DRI_CTX_ERROR_NO_MEMORY; 705 fprintf(stderr, "Unrecognized deviceID 0x%x\n", intelScreen->deviceID); 706 } 707 708 return false; 709} 710 711static bool 712intel_init_bufmgr(struct intel_screen *intelScreen) 713{ 714 __DRIscreen *spriv = intelScreen->driScrnPriv; 715 int num_fences = 0; 716 717 intelScreen->no_hw = getenv("INTEL_NO_HW") != NULL; 718 719 intelScreen->bufmgr = intel_bufmgr_gem_init(spriv->fd, BATCH_SZ); 720 if (intelScreen->bufmgr == NULL) { 721 fprintf(stderr, "[%s:%u] Error initializing buffer manager.\n", 722 __func__, __LINE__); 723 return false; 724 } 725 726 if (!intel_get_param(spriv, I915_PARAM_NUM_FENCES_AVAIL, &num_fences) || 727 num_fences == 0) { 728 fprintf(stderr, "[%s: %u] Kernel 2.6.29 required.\n", __func__, __LINE__); 729 return false; 730 } 731 732 drm_intel_bufmgr_gem_enable_fenced_relocs(intelScreen->bufmgr); 733 734 intelScreen->named_regions = _mesa_NewHashTable(); 735 736 intelScreen->relaxed_relocations = 0; 737 intelScreen->relaxed_relocations |= 738 intel_get_boolean(spriv, I915_PARAM_HAS_RELAXED_DELTA) << 0; 739 740 return true; 741} 742 743/** 744 * Override intel_screen.hw_has_separate_stencil with environment variable 745 * INTEL_SEPARATE_STENCIL. 746 * 747 * Valid values for INTEL_SEPARATE_STENCIL are "0" and "1". If an invalid 748 * valid value is encountered, a warning is emitted and INTEL_SEPARATE_STENCIL 749 * is ignored. 750 */ 751static void 752intel_override_separate_stencil(struct intel_screen *screen) 753{ 754 const char *s = getenv("INTEL_SEPARATE_STENCIL"); 755 if (!s) { 756 return; 757 } else if (!strncmp("0", s, 2)) { 758 screen->hw_has_separate_stencil = false; 759 } else if (!strncmp("1", s, 2)) { 760 screen->hw_has_separate_stencil = true; 761 } else { 762 fprintf(stderr, 763 "warning: env variable INTEL_SEPARATE_STENCIL=\"%s\" has " 764 "invalid value and is ignored", s); 765 } 766} 767 768static bool 769intel_detect_swizzling(struct intel_screen *screen) 770{ 771 drm_intel_bo *buffer; 772 unsigned long flags = 0; 773 unsigned long aligned_pitch; 774 uint32_t tiling = I915_TILING_X; 775 uint32_t swizzle_mode = 0; 776 777 buffer = drm_intel_bo_alloc_tiled(screen->bufmgr, "swizzle test", 778 64, 64, 4, 779 &tiling, &aligned_pitch, flags); 780 if (buffer == NULL) 781 return false; 782 783 drm_intel_bo_get_tiling(buffer, &tiling, &swizzle_mode); 784 drm_intel_bo_unreference(buffer); 785 786 if (swizzle_mode == I915_BIT_6_SWIZZLE_NONE) 787 return false; 788 else 789 return true; 790} 791 792/** 793 * This is the driver specific part of the createNewScreen entry point. 794 * Called when using DRI2. 795 * 796 * \return the struct gl_config supported by this driver 797 */ 798static const 799__DRIconfig **intelInitScreen2(__DRIscreen *psp) 800{ 801 struct intel_screen *intelScreen; 802 GLenum fb_format[3]; 803 GLenum fb_type[3]; 804 unsigned int api_mask; 805 806 static const GLenum back_buffer_modes[] = { 807 GLX_NONE, GLX_SWAP_UNDEFINED_OML, GLX_SWAP_COPY_OML 808 }; 809 uint8_t depth_bits[4], stencil_bits[4], msaa_samples_array[1]; 810 int color; 811 __DRIconfig **configs = NULL; 812 813 /* Allocate the private area */ 814 intelScreen = CALLOC(sizeof *intelScreen); 815 if (!intelScreen) { 816 fprintf(stderr, "\nERROR! Allocating private area failed\n"); 817 return false; 818 } 819 /* parse information in __driConfigOptions */ 820 driParseOptionInfo(&intelScreen->optionCache, 821 __driConfigOptions, __driNConfigOptions); 822 823 intelScreen->driScrnPriv = psp; 824 psp->driverPrivate = (void *) intelScreen; 825 826 if (!intel_init_bufmgr(intelScreen)) 827 return false; 828 829 intelScreen->deviceID = drm_intel_bufmgr_gem_get_devid(intelScreen->bufmgr); 830 831 intelScreen->kernel_has_gen7_sol_reset = 832 intel_get_boolean(intelScreen->driScrnPriv, 833 I915_PARAM_HAS_GEN7_SOL_RESET); 834 835 if (IS_GEN7(intelScreen->deviceID)) { 836 intelScreen->gen = 7; 837 } else if (IS_GEN6(intelScreen->deviceID)) { 838 intelScreen->gen = 6; 839 } else if (IS_GEN5(intelScreen->deviceID)) { 840 intelScreen->gen = 5; 841 } else if (IS_965(intelScreen->deviceID)) { 842 intelScreen->gen = 4; 843 } else if (IS_9XX(intelScreen->deviceID)) { 844 intelScreen->gen = 3; 845 } else { 846 intelScreen->gen = 2; 847 } 848 849 intelScreen->hw_has_separate_stencil = intelScreen->gen >= 6; 850 intelScreen->hw_must_use_separate_stencil = intelScreen->gen >= 7; 851 intelScreen->dri2_has_hiz = INTEL_DRI2_HAS_HIZ_UNKNOWN; 852 853 int has_llc = 0; 854 bool success = intel_get_param(intelScreen->driScrnPriv, I915_PARAM_HAS_LLC, 855 &has_llc); 856 if (success && has_llc) 857 intelScreen->hw_has_llc = true; 858 else if (!success && intelScreen->gen >= 6) 859 intelScreen->hw_has_llc = true; 860 861 intel_override_separate_stencil(intelScreen); 862 863 api_mask = (1 << __DRI_API_OPENGL); 864#if FEATURE_ES1 865 api_mask |= (1 << __DRI_API_GLES); 866#endif 867#if FEATURE_ES2 868 api_mask |= (1 << __DRI_API_GLES2); 869#endif 870 871 if (IS_9XX(intelScreen->deviceID) || IS_965(intelScreen->deviceID)) 872 psp->api_mask = api_mask; 873 874 intelScreen->hw_has_swizzling = intel_detect_swizzling(intelScreen); 875 876 psp->extensions = intelScreenExtensions; 877 878 msaa_samples_array[0] = 0; 879 880 fb_format[0] = GL_RGB; 881 fb_type[0] = GL_UNSIGNED_SHORT_5_6_5; 882 883 fb_format[1] = GL_BGR; 884 fb_type[1] = GL_UNSIGNED_INT_8_8_8_8_REV; 885 886 fb_format[2] = GL_BGRA; 887 fb_type[2] = GL_UNSIGNED_INT_8_8_8_8_REV; 888 889 depth_bits[0] = 0; 890 stencil_bits[0] = 0; 891 892 /* Generate a rich set of useful configs that do not include an 893 * accumulation buffer. 894 */ 895 for (color = 0; color < ARRAY_SIZE(fb_format); color++) { 896 __DRIconfig **new_configs; 897 int depth_factor; 898 899 /* Starting with DRI2 protocol version 1.1 we can request a depth/stencil 900 * buffer that has a diffferent number of bits per pixel than the color 901 * buffer. This isn't yet supported here. 902 */ 903 if (fb_type[color] == GL_UNSIGNED_SHORT_5_6_5) { 904 depth_bits[1] = 16; 905 stencil_bits[1] = 0; 906 } else { 907 depth_bits[1] = 24; 908 stencil_bits[1] = 8; 909 } 910 911 depth_factor = 2; 912 913 new_configs = driCreateConfigs(fb_format[color], fb_type[color], 914 depth_bits, 915 stencil_bits, 916 depth_factor, 917 back_buffer_modes, 918 ARRAY_SIZE(back_buffer_modes), 919 msaa_samples_array, 920 ARRAY_SIZE(msaa_samples_array), 921 false); 922 if (configs == NULL) 923 configs = new_configs; 924 else 925 configs = driConcatConfigs(configs, new_configs); 926 } 927 928 /* Generate the minimum possible set of configs that include an 929 * accumulation buffer. 930 */ 931 for (color = 0; color < ARRAY_SIZE(fb_format); color++) { 932 __DRIconfig **new_configs; 933 934 if (fb_type[color] == GL_UNSIGNED_SHORT_5_6_5) { 935 depth_bits[0] = 16; 936 stencil_bits[0] = 0; 937 } else { 938 depth_bits[0] = 24; 939 stencil_bits[0] = 8; 940 } 941 942 new_configs = driCreateConfigs(fb_format[color], fb_type[color], 943 depth_bits, stencil_bits, 1, 944 back_buffer_modes + 1, 1, 945 msaa_samples_array, 1, 946 true); 947 if (configs == NULL) 948 configs = new_configs; 949 else 950 configs = driConcatConfigs(configs, new_configs); 951 } 952 953 if (configs == NULL) { 954 fprintf(stderr, "[%s:%u] Error creating FBConfig!\n", __func__, 955 __LINE__); 956 return NULL; 957 } 958 959 return (const __DRIconfig **)configs; 960} 961 962struct intel_buffer { 963 __DRIbuffer base; 964 struct intel_region *region; 965}; 966 967/** 968 * \brief Get tiling format for a DRI buffer. 969 * 970 * \param attachment is the buffer's attachmet point, such as 971 * __DRI_BUFFER_DEPTH. 972 * \param out_tiling is the returned tiling format for buffer. 973 * \return false if attachment is unrecognized or is incompatible with screen. 974 */ 975static bool 976intel_get_dri_buffer_tiling(struct intel_screen *screen, 977 uint32_t attachment, 978 uint32_t *out_tiling) 979{ 980 if (screen->gen < 4) { 981 *out_tiling = I915_TILING_X; 982 return true; 983 } 984 985 switch (attachment) { 986 case __DRI_BUFFER_DEPTH: 987 case __DRI_BUFFER_DEPTH_STENCIL: 988 case __DRI_BUFFER_HIZ: 989 *out_tiling = I915_TILING_Y; 990 return true; 991 case __DRI_BUFFER_ACCUM: 992 case __DRI_BUFFER_FRONT_LEFT: 993 case __DRI_BUFFER_FRONT_RIGHT: 994 case __DRI_BUFFER_BACK_LEFT: 995 case __DRI_BUFFER_BACK_RIGHT: 996 case __DRI_BUFFER_FAKE_FRONT_LEFT: 997 case __DRI_BUFFER_FAKE_FRONT_RIGHT: 998 *out_tiling = I915_TILING_X; 999 return true; 1000 case __DRI_BUFFER_STENCIL: 1001 /* The stencil buffer is W tiled. However, we request from the kernel 1002 * a non-tiled buffer because the GTT is incapable of W fencing. 1003 */ 1004 *out_tiling = I915_TILING_NONE; 1005 return true; 1006 default: 1007 if(unlikely(INTEL_DEBUG & DEBUG_DRI)) { 1008 fprintf(stderr, "error: %s: unrecognized DRI buffer attachment 0x%x\n", 1009 __FUNCTION__, attachment); 1010 } 1011 return false; 1012 } 1013} 1014 1015static __DRIbuffer * 1016intelAllocateBuffer(__DRIscreen *screen, 1017 unsigned attachment, unsigned format, 1018 int width, int height) 1019{ 1020 struct intel_buffer *intelBuffer; 1021 struct intel_screen *intelScreen = screen->driverPrivate; 1022 1023 uint32_t tiling; 1024 uint32_t region_width; 1025 uint32_t region_height; 1026 uint32_t region_cpp; 1027 1028 bool ok = true; 1029 1030 ok = intel_get_dri_buffer_tiling(intelScreen, attachment, &tiling); 1031 if (!ok) 1032 return NULL; 1033 1034 intelBuffer = CALLOC(sizeof *intelBuffer); 1035 if (intelBuffer == NULL) 1036 return NULL; 1037 1038 if (attachment == __DRI_BUFFER_STENCIL) { 1039 /* Stencil buffers use W tiling, a tiling format that the DRM functions 1040 * don't properly account for. Therefore, when we allocate a stencil 1041 * buffer that is private to Mesa (see intel_miptree_create), we round 1042 * the height and width up to the next multiple of the tile size (64x64) 1043 * and then ask DRM to allocate an untiled buffer. Consequently, the 1044 * height and the width stored in the stencil buffer's region structure 1045 * are always multiples of 64, even if the stencil buffer itself is 1046 * smaller. 1047 * 1048 * To avoid inconsistencies between how we represent private buffers and 1049 * buffers shared with the window system, round up the height and width 1050 * for window system buffers too. 1051 */ 1052 region_width = ALIGN(width, 64); 1053 region_height = ALIGN(height, 64); 1054 } else { 1055 region_width = width; 1056 region_height = height; 1057 } 1058 1059 region_cpp = format / 8; 1060 1061 intelBuffer->region = intel_region_alloc(intelScreen, 1062 tiling, 1063 region_cpp, 1064 region_width, 1065 region_height, 1066 true); 1067 1068 if (intelBuffer->region == NULL) { 1069 FREE(intelBuffer); 1070 return NULL; 1071 } 1072 1073 intel_region_flink(intelBuffer->region, &intelBuffer->base.name); 1074 1075 intelBuffer->base.attachment = attachment; 1076 intelBuffer->base.cpp = intelBuffer->region->cpp; 1077 intelBuffer->base.pitch = 1078 intelBuffer->region->pitch * intelBuffer->region->cpp; 1079 1080 return &intelBuffer->base; 1081} 1082 1083static void 1084intelReleaseBuffer(__DRIscreen *screen, __DRIbuffer *buffer) 1085{ 1086 struct intel_buffer *intelBuffer = (struct intel_buffer *) buffer; 1087 1088 intel_region_release(&intelBuffer->region); 1089 free(intelBuffer); 1090} 1091 1092 1093const struct __DriverAPIRec driDriverAPI = { 1094 .InitScreen = intelInitScreen2, 1095 .DestroyScreen = intelDestroyScreen, 1096 .CreateContext = intelCreateContext, 1097 .DestroyContext = intelDestroyContext, 1098 .CreateBuffer = intelCreateBuffer, 1099 .DestroyBuffer = intelDestroyBuffer, 1100 .MakeCurrent = intelMakeCurrent, 1101 .UnbindContext = intelUnbindContext, 1102 .AllocateBuffer = intelAllocateBuffer, 1103 .ReleaseBuffer = intelReleaseBuffer 1104}; 1105 1106/* This is the table of extensions that the loader will dlsym() for. */ 1107PUBLIC const __DRIextension *__driDriverExtensions[] = { 1108 &driCoreExtension.base, 1109 &driDRI2Extension.base, 1110 NULL 1111}; 1112