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