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