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