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