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