intel_fbo.c revision 6b56140b4bafcef8bea5ca67cb31023a533c3bd4
1/************************************************************************** 2 * 3 * Copyright 2006 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 29#include "main/enums.h" 30#include "main/imports.h" 31#include "main/macros.h" 32#include "main/mfeatures.h" 33#include "main/mtypes.h" 34#include "main/fbobject.h" 35#include "main/framebuffer.h" 36#include "main/renderbuffer.h" 37#include "main/context.h" 38#include "main/teximage.h" 39#include "main/image.h" 40 41#include "swrast/swrast.h" 42#include "drivers/common/meta.h" 43 44#include "intel_context.h" 45#include "intel_batchbuffer.h" 46#include "intel_buffers.h" 47#include "intel_blit.h" 48#include "intel_fbo.h" 49#include "intel_mipmap_tree.h" 50#include "intel_regions.h" 51#include "intel_tex.h" 52#include "intel_span.h" 53#ifndef I915 54#include "brw_context.h" 55#endif 56 57#define FILE_DEBUG_FLAG DEBUG_FBO 58 59static struct gl_renderbuffer * 60intel_new_renderbuffer(struct gl_context * ctx, GLuint name); 61 62struct intel_region* 63intel_get_rb_region(struct gl_framebuffer *fb, GLuint attIndex) 64{ 65 struct intel_renderbuffer *irb = intel_get_renderbuffer(fb, attIndex); 66 if (irb && irb->mt) { 67 if (attIndex == BUFFER_STENCIL && irb->mt->stencil_mt) 68 return irb->mt->stencil_mt->region; 69 else 70 return irb->mt->region; 71 } else 72 return NULL; 73} 74 75/** 76 * Create a new framebuffer object. 77 */ 78static struct gl_framebuffer * 79intel_new_framebuffer(struct gl_context * ctx, GLuint name) 80{ 81 /* Only drawable state in intel_framebuffer at this time, just use Mesa's 82 * class 83 */ 84 return _mesa_new_framebuffer(ctx, name); 85} 86 87 88/** Called by gl_renderbuffer::Delete() */ 89static void 90intel_delete_renderbuffer(struct gl_renderbuffer *rb) 91{ 92 struct intel_renderbuffer *irb = intel_renderbuffer(rb); 93 94 ASSERT(irb); 95 96 intel_miptree_release(&irb->mt); 97 98 free(irb); 99} 100 101/** 102 * \see dd_function_table::MapRenderbuffer 103 */ 104static void 105intel_map_renderbuffer(struct gl_context *ctx, 106 struct gl_renderbuffer *rb, 107 GLuint x, GLuint y, GLuint w, GLuint h, 108 GLbitfield mode, 109 GLubyte **out_map, 110 GLint *out_stride) 111{ 112 struct intel_context *intel = intel_context(ctx); 113 struct swrast_renderbuffer *srb = (struct swrast_renderbuffer *)rb; 114 struct intel_renderbuffer *irb = intel_renderbuffer(rb); 115 void *map; 116 int stride; 117 118 if (srb->Buffer) { 119 /* this is a malloc'd renderbuffer (accum buffer), not an irb */ 120 GLint bpp = _mesa_get_format_bytes(rb->Format); 121 GLint rowStride = srb->RowStride; 122 *out_map = (GLubyte *) srb->Buffer + y * rowStride + x * bpp; 123 *out_stride = rowStride; 124 return; 125 } 126 127 /* We sometimes get called with this by our intel_span.c usage. */ 128 if (!irb->mt) { 129 *out_map = NULL; 130 *out_stride = 0; 131 return; 132 } 133 134 /* For a window-system renderbuffer, we need to flip the mapping we receive 135 * upside-down. So we need to ask for a rectangle on flipped vertically, and 136 * we then return a pointer to the bottom of it with a negative stride. 137 */ 138 if (rb->Name == 0) { 139 y = rb->Height - y - h; 140 } 141 142 intel_miptree_map(intel, irb->mt, irb->mt_level, irb->mt_layer, 143 x, y, w, h, mode, &map, &stride); 144 145 if (rb->Name == 0) { 146 map += (h - 1) * stride; 147 stride = -stride; 148 } 149 150 DBG("%s: rb %d (%s) mt mapped: (%d, %d) (%dx%d) -> %p/%d\n", 151 __FUNCTION__, rb->Name, _mesa_get_format_name(rb->Format), 152 x, y, w, h, map, stride); 153 154 *out_map = map; 155 *out_stride = stride; 156} 157 158/** 159 * \see dd_function_table::UnmapRenderbuffer 160 */ 161static void 162intel_unmap_renderbuffer(struct gl_context *ctx, 163 struct gl_renderbuffer *rb) 164{ 165 struct intel_context *intel = intel_context(ctx); 166 struct swrast_renderbuffer *srb = (struct swrast_renderbuffer *)rb; 167 struct intel_renderbuffer *irb = intel_renderbuffer(rb); 168 169 DBG("%s: rb %d (%s)\n", __FUNCTION__, 170 rb->Name, _mesa_get_format_name(rb->Format)); 171 172 if (srb->Buffer) { 173 /* this is a malloc'd renderbuffer (accum buffer) */ 174 /* nothing to do */ 175 return; 176 } 177 178 intel_miptree_unmap(intel, irb->mt, irb->mt_level, irb->mt_layer); 179} 180 181 182/** 183 * Round up the requested multisample count to the next supported sample size. 184 */ 185unsigned 186intel_quantize_num_samples(struct intel_screen *intel, unsigned num_samples) 187{ 188 switch (intel->gen) { 189 case 6: 190 /* Gen6 supports only 4x multisampling. */ 191 if (num_samples > 0) 192 return 4; 193 else 194 return 0; 195 case 7: 196 /* Gen7 supports 4x and 8x multisampling. */ 197 if (num_samples > 4) 198 return 8; 199 else if (num_samples > 0) 200 return 4; 201 else 202 return 0; 203 return 0; 204 default: 205 /* MSAA unsupported. However, a careful reading of 206 * EXT_framebuffer_multisample reveals that we need to permit 207 * num_samples to be 1 (since num_samples is permitted to be as high as 208 * GL_MAX_SAMPLES, and GL_MAX_SAMPLES must be at least 1). Since 209 * platforms before Gen6 don't support MSAA, this is safe, because 210 * multisampling won't happen anyhow. 211 */ 212 if (num_samples > 0) 213 return 1; 214 return 0; 215 } 216} 217 218 219/** 220 * Called via glRenderbufferStorageEXT() to set the format and allocate 221 * storage for a user-created renderbuffer. 222 */ 223GLboolean 224intel_alloc_renderbuffer_storage(struct gl_context * ctx, struct gl_renderbuffer *rb, 225 GLenum internalFormat, 226 GLuint width, GLuint height) 227{ 228 struct intel_context *intel = intel_context(ctx); 229 struct intel_screen *screen = intel->intelScreen; 230 struct intel_renderbuffer *irb = intel_renderbuffer(rb); 231 rb->NumSamples = intel_quantize_num_samples(screen, rb->NumSamples); 232 233 switch (internalFormat) { 234 default: 235 /* Use the same format-choice logic as for textures. 236 * Renderbuffers aren't any different from textures for us, 237 * except they're less useful because you can't texture with 238 * them. 239 */ 240 rb->Format = intel->ctx.Driver.ChooseTextureFormat(ctx, internalFormat, 241 GL_NONE, GL_NONE); 242 break; 243 case GL_STENCIL_INDEX: 244 case GL_STENCIL_INDEX1_EXT: 245 case GL_STENCIL_INDEX4_EXT: 246 case GL_STENCIL_INDEX8_EXT: 247 case GL_STENCIL_INDEX16_EXT: 248 /* These aren't actual texture formats, so force them here. */ 249 if (intel->has_separate_stencil) { 250 rb->Format = MESA_FORMAT_S8; 251 } else { 252 assert(!intel->must_use_separate_stencil); 253 rb->Format = MESA_FORMAT_S8_Z24; 254 } 255 break; 256 } 257 258 rb->Width = width; 259 rb->Height = height; 260 rb->_BaseFormat = _mesa_base_fbo_format(ctx, internalFormat); 261 262 intel_miptree_release(&irb->mt); 263 264 DBG("%s: %s: %s (%dx%d)\n", __FUNCTION__, 265 _mesa_lookup_enum_by_nr(internalFormat), 266 _mesa_get_format_name(rb->Format), width, height); 267 268 if (width == 0 || height == 0) 269 return true; 270 271 irb->mt = intel_miptree_create_for_renderbuffer(intel, rb->Format, 272 width, height, 273 rb->NumSamples); 274 if (!irb->mt) 275 return false; 276 277 return true; 278} 279 280 281#if FEATURE_OES_EGL_image 282static void 283intel_image_target_renderbuffer_storage(struct gl_context *ctx, 284 struct gl_renderbuffer *rb, 285 void *image_handle) 286{ 287 struct intel_context *intel = intel_context(ctx); 288 struct intel_renderbuffer *irb; 289 __DRIscreen *screen; 290 __DRIimage *image; 291 292 screen = intel->intelScreen->driScrnPriv; 293 image = screen->dri2.image->lookupEGLImage(screen, image_handle, 294 screen->loaderPrivate); 295 if (image == NULL) 296 return; 297 298 /* __DRIimage is opaque to the core so it has to be checked here */ 299 switch (image->format) { 300 case MESA_FORMAT_RGBA8888_REV: 301 _mesa_error(&intel->ctx, GL_INVALID_OPERATION, 302 "glEGLImageTargetRenderbufferStorage(unsupported image format"); 303 return; 304 break; 305 default: 306 break; 307 } 308 309 irb = intel_renderbuffer(rb); 310 intel_miptree_release(&irb->mt); 311 irb->mt = intel_miptree_create_for_region(intel, 312 GL_TEXTURE_2D, 313 image->format, 314 image->region); 315 if (!irb->mt) 316 return; 317 318 rb->InternalFormat = image->internal_format; 319 rb->Width = image->region->width; 320 rb->Height = image->region->height; 321 rb->Format = image->format; 322 rb->_BaseFormat = _mesa_base_fbo_format(&intel->ctx, 323 image->internal_format); 324} 325#endif 326 327/** 328 * Called for each hardware renderbuffer when a _window_ is resized. 329 * Just update fields. 330 * Not used for user-created renderbuffers! 331 */ 332static GLboolean 333intel_alloc_window_storage(struct gl_context * ctx, struct gl_renderbuffer *rb, 334 GLenum internalFormat, GLuint width, GLuint height) 335{ 336 ASSERT(rb->Name == 0); 337 rb->Width = width; 338 rb->Height = height; 339 rb->InternalFormat = internalFormat; 340 341 return true; 342} 343 344 345static void 346intel_resize_buffers(struct gl_context *ctx, struct gl_framebuffer *fb, 347 GLuint width, GLuint height) 348{ 349 int i; 350 351 _mesa_resize_framebuffer(ctx, fb, width, height); 352 353 fb->Initialized = true; /* XXX remove someday */ 354 355 if (_mesa_is_user_fbo(fb)) { 356 return; 357 } 358 359 360 /* Make sure all window system renderbuffers are up to date */ 361 for (i = BUFFER_FRONT_LEFT; i <= BUFFER_BACK_RIGHT; i++) { 362 struct gl_renderbuffer *rb = fb->Attachment[i].Renderbuffer; 363 364 /* only resize if size is changing */ 365 if (rb && (rb->Width != width || rb->Height != height)) { 366 rb->AllocStorage(ctx, rb, rb->InternalFormat, width, height); 367 } 368 } 369} 370 371 372/** Dummy function for gl_renderbuffer::AllocStorage() */ 373static GLboolean 374intel_nop_alloc_storage(struct gl_context * ctx, struct gl_renderbuffer *rb, 375 GLenum internalFormat, GLuint width, GLuint height) 376{ 377 _mesa_problem(ctx, "intel_op_alloc_storage should never be called."); 378 return false; 379} 380 381/** 382 * Create a new intel_renderbuffer which corresponds to an on-screen window, 383 * not a user-created renderbuffer. 384 * 385 * \param num_samples must be quantized. 386 */ 387struct intel_renderbuffer * 388intel_create_renderbuffer(gl_format format, unsigned num_samples) 389{ 390 struct intel_renderbuffer *irb; 391 struct gl_renderbuffer *rb; 392 393 GET_CURRENT_CONTEXT(ctx); 394 395 irb = CALLOC_STRUCT(intel_renderbuffer); 396 if (!irb) { 397 _mesa_error(ctx, GL_OUT_OF_MEMORY, "creating renderbuffer"); 398 return NULL; 399 } 400 401 rb = &irb->Base.Base; 402 403 _mesa_init_renderbuffer(rb, 0); 404 rb->ClassID = INTEL_RB_CLASS; 405 rb->_BaseFormat = _mesa_get_format_base_format(format); 406 rb->Format = format; 407 rb->InternalFormat = rb->_BaseFormat; 408 rb->NumSamples = num_samples; 409 410 /* intel-specific methods */ 411 rb->Delete = intel_delete_renderbuffer; 412 rb->AllocStorage = intel_alloc_window_storage; 413 414 return irb; 415} 416 417/** 418 * Private window-system buffers (as opposed to ones shared with the display 419 * server created with intel_create_renderbuffer()) are most similar in their 420 * handling to user-created renderbuffers, but they have a resize handler that 421 * may be called at intel_update_renderbuffers() time. 422 * 423 * \param num_samples must be quantized. 424 */ 425struct intel_renderbuffer * 426intel_create_private_renderbuffer(gl_format format, unsigned num_samples) 427{ 428 struct intel_renderbuffer *irb; 429 430 irb = intel_create_renderbuffer(format, num_samples); 431 irb->Base.Base.AllocStorage = intel_alloc_renderbuffer_storage; 432 433 return irb; 434} 435 436/** 437 * Create a new renderbuffer object. 438 * Typically called via glBindRenderbufferEXT(). 439 */ 440static struct gl_renderbuffer * 441intel_new_renderbuffer(struct gl_context * ctx, GLuint name) 442{ 443 /*struct intel_context *intel = intel_context(ctx); */ 444 struct intel_renderbuffer *irb; 445 struct gl_renderbuffer *rb; 446 447 irb = CALLOC_STRUCT(intel_renderbuffer); 448 if (!irb) { 449 _mesa_error(ctx, GL_OUT_OF_MEMORY, "creating renderbuffer"); 450 return NULL; 451 } 452 453 rb = &irb->Base.Base; 454 455 _mesa_init_renderbuffer(rb, name); 456 rb->ClassID = INTEL_RB_CLASS; 457 458 /* intel-specific methods */ 459 rb->Delete = intel_delete_renderbuffer; 460 rb->AllocStorage = intel_alloc_renderbuffer_storage; 461 /* span routines set in alloc_storage function */ 462 463 return rb; 464} 465 466 467/** 468 * Called via glBindFramebufferEXT(). 469 */ 470static void 471intel_bind_framebuffer(struct gl_context * ctx, GLenum target, 472 struct gl_framebuffer *fb, struct gl_framebuffer *fbread) 473{ 474 if (target == GL_FRAMEBUFFER_EXT || target == GL_DRAW_FRAMEBUFFER_EXT) { 475 intel_draw_buffer(ctx); 476 } 477 else { 478 /* don't need to do anything if target == GL_READ_FRAMEBUFFER_EXT */ 479 } 480} 481 482 483/** 484 * Called via glFramebufferRenderbufferEXT(). 485 */ 486static void 487intel_framebuffer_renderbuffer(struct gl_context * ctx, 488 struct gl_framebuffer *fb, 489 GLenum attachment, struct gl_renderbuffer *rb) 490{ 491 DBG("Intel FramebufferRenderbuffer %u %u\n", fb->Name, rb ? rb->Name : 0); 492 493 _mesa_framebuffer_renderbuffer(ctx, fb, attachment, rb); 494 intel_draw_buffer(ctx); 495} 496 497/** 498 * \par Special case for separate stencil 499 * 500 * When wrapping a depthstencil texture that uses separate stencil, this 501 * function is recursively called twice: once to create \c 502 * irb->wrapped_depth and again to create \c irb->wrapped_stencil. On the 503 * call to create \c irb->wrapped_depth, the \c format and \c 504 * internal_format parameters do not match \c mt->format. In that case, \c 505 * mt->format is MESA_FORMAT_S8_Z24 and \c format is \c 506 * MESA_FORMAT_X8_Z24. 507 * 508 * @return true on success 509 */ 510 511static bool 512intel_renderbuffer_update_wrapper(struct intel_context *intel, 513 struct intel_renderbuffer *irb, 514 struct gl_texture_image *image, 515 uint32_t layer) 516{ 517 struct gl_renderbuffer *rb = &irb->Base.Base; 518 struct intel_texture_image *intel_image = intel_texture_image(image); 519 struct intel_mipmap_tree *mt = intel_image->mt; 520 int level = image->Level; 521 522 rb->Format = image->TexFormat; 523 rb->InternalFormat = image->InternalFormat; 524 rb->_BaseFormat = image->_BaseFormat; 525 rb->Width = mt->level[level].width; 526 rb->Height = mt->level[level].height; 527 528 rb->Delete = intel_delete_renderbuffer; 529 rb->AllocStorage = intel_nop_alloc_storage; 530 531 intel_miptree_check_level_layer(mt, level, layer); 532 irb->mt_level = level; 533 irb->mt_layer = layer; 534 535 intel_miptree_reference(&irb->mt, mt); 536 537 intel_renderbuffer_set_draw_offset(irb); 538 539 if (mt->hiz_mt == NULL && 540 intel->vtbl.is_hiz_depth_format(intel, rb->Format)) { 541 intel_miptree_alloc_hiz(intel, mt, 0 /* num_samples */); 542 if (!mt->hiz_mt) 543 return false; 544 } 545 546 return true; 547} 548 549void 550intel_renderbuffer_set_draw_offset(struct intel_renderbuffer *irb) 551{ 552 unsigned int dst_x, dst_y; 553 554 /* compute offset of the particular 2D image within the texture region */ 555 intel_miptree_get_image_offset(irb->mt, 556 irb->mt_level, 557 0, /* face, which we ignore */ 558 irb->mt_layer, 559 &dst_x, &dst_y); 560 561 irb->draw_x = dst_x; 562 irb->draw_y = dst_y; 563} 564 565/** 566 * Rendering to tiled buffers requires that the base address of the 567 * buffer be aligned to a page boundary. We generally render to 568 * textures by pointing the surface at the mipmap image level, which 569 * may not be aligned to a tile boundary. 570 * 571 * This function returns an appropriately-aligned base offset 572 * according to the tiling restrictions, plus any required x/y offset 573 * from there. 574 */ 575uint32_t 576intel_renderbuffer_tile_offsets(struct intel_renderbuffer *irb, 577 uint32_t *tile_x, 578 uint32_t *tile_y) 579{ 580 struct intel_region *region = irb->mt->region; 581 uint32_t mask_x, mask_y; 582 583 intel_region_get_tile_masks(region, &mask_x, &mask_y); 584 585 *tile_x = irb->draw_x & mask_x; 586 *tile_y = irb->draw_y & mask_y; 587 return intel_region_get_aligned_offset(region, irb->draw_x & ~mask_x, 588 irb->draw_y & ~mask_y); 589} 590 591/** 592 * Called by glFramebufferTexture[123]DEXT() (and other places) to 593 * prepare for rendering into texture memory. This might be called 594 * many times to choose different texture levels, cube faces, etc 595 * before intel_finish_render_texture() is ever called. 596 */ 597static void 598intel_render_texture(struct gl_context * ctx, 599 struct gl_framebuffer *fb, 600 struct gl_renderbuffer_attachment *att) 601{ 602 struct intel_context *intel = intel_context(ctx); 603 struct gl_texture_image *image = _mesa_get_attachment_teximage(att); 604 struct intel_renderbuffer *irb = intel_renderbuffer(att->Renderbuffer); 605 struct intel_texture_image *intel_image = intel_texture_image(image); 606 struct intel_mipmap_tree *mt = intel_image->mt; 607 int layer; 608 609 (void) fb; 610 611 if (att->CubeMapFace > 0) { 612 assert(att->Zoffset == 0); 613 layer = att->CubeMapFace; 614 } else { 615 layer = att->Zoffset; 616 } 617 618 if (!intel_image->mt) { 619 /* Fallback on drawing to a texture that doesn't have a miptree 620 * (has a border, width/height 0, etc.) 621 */ 622 _mesa_reference_renderbuffer(&att->Renderbuffer, NULL); 623 _swrast_render_texture(ctx, fb, att); 624 return; 625 } 626 else if (!irb) { 627 intel_miptree_check_level_layer(mt, att->TextureLevel, layer); 628 629 irb = (struct intel_renderbuffer *)intel_new_renderbuffer(ctx, ~0); 630 631 if (irb) { 632 /* bind the wrapper to the attachment point */ 633 _mesa_reference_renderbuffer(&att->Renderbuffer, &irb->Base.Base); 634 } 635 else { 636 /* fallback to software rendering */ 637 _swrast_render_texture(ctx, fb, att); 638 return; 639 } 640 } 641 642 if (!intel_renderbuffer_update_wrapper(intel, irb, image, layer)) { 643 _mesa_reference_renderbuffer(&att->Renderbuffer, NULL); 644 _swrast_render_texture(ctx, fb, att); 645 return; 646 } 647 648 irb->tex_image = image; 649 650 DBG("Begin render %s texture tex=%u w=%d h=%d refcount=%d\n", 651 _mesa_get_format_name(image->TexFormat), 652 att->Texture->Name, image->Width, image->Height, 653 irb->Base.Base.RefCount); 654 655 /* update drawing region, etc */ 656 intel_draw_buffer(ctx); 657} 658 659 660/** 661 * Called by Mesa when rendering to a texture is done. 662 */ 663static void 664intel_finish_render_texture(struct gl_context * ctx, 665 struct gl_renderbuffer_attachment *att) 666{ 667 struct intel_context *intel = intel_context(ctx); 668 struct gl_texture_object *tex_obj = att->Texture; 669 struct gl_texture_image *image = 670 tex_obj->Image[att->CubeMapFace][att->TextureLevel]; 671 struct intel_renderbuffer *irb = intel_renderbuffer(att->Renderbuffer); 672 673 DBG("Finish render %s texture tex=%u\n", 674 _mesa_get_format_name(image->TexFormat), att->Texture->Name); 675 676 if (irb) 677 irb->tex_image = NULL; 678 679 /* Since we've (probably) rendered to the texture and will (likely) use 680 * it in the texture domain later on in this batchbuffer, flush the 681 * batch. Once again, we wish for a domain tracker in libdrm to cover 682 * usage inside of a batchbuffer like GEM does in the kernel. 683 */ 684 intel_batchbuffer_emit_mi_flush(intel); 685} 686 687/** 688 * Do additional "completeness" testing of a framebuffer object. 689 */ 690static void 691intel_validate_framebuffer(struct gl_context *ctx, struct gl_framebuffer *fb) 692{ 693 struct intel_context *intel = intel_context(ctx); 694 const struct intel_renderbuffer *depthRb = 695 intel_get_renderbuffer(fb, BUFFER_DEPTH); 696 const struct intel_renderbuffer *stencilRb = 697 intel_get_renderbuffer(fb, BUFFER_STENCIL); 698 struct intel_mipmap_tree *depth_mt = NULL, *stencil_mt = NULL; 699 int i; 700 701 DBG("%s() on fb %p (%s)\n", __FUNCTION__, 702 fb, (fb == ctx->DrawBuffer ? "drawbuffer" : 703 (fb == ctx->ReadBuffer ? "readbuffer" : "other buffer"))); 704 705 if (depthRb) 706 depth_mt = depthRb->mt; 707 if (stencilRb) { 708 stencil_mt = stencilRb->mt; 709 if (stencil_mt->stencil_mt) 710 stencil_mt = stencil_mt->stencil_mt; 711 } 712 713 if (depth_mt && stencil_mt) { 714 if (depth_mt == stencil_mt) { 715 /* For true packed depth/stencil (not faked on prefers-separate-stencil 716 * hardware) we need to be sure they're the same level/layer, since 717 * we'll be emitting a single packet describing the packed setup. 718 */ 719 if (depthRb->mt_level != stencilRb->mt_level || 720 depthRb->mt_layer != stencilRb->mt_layer) { 721 DBG("depth image level/layer %d/%d != stencil image %d/%d\n", 722 depthRb->mt_level, 723 depthRb->mt_layer, 724 stencilRb->mt_level, 725 stencilRb->mt_layer); 726 fb->_Status = GL_FRAMEBUFFER_UNSUPPORTED_EXT; 727 } 728 } else { 729 if (!intel->has_separate_stencil) { 730 DBG("separate stencil unsupported\n"); 731 fb->_Status = GL_FRAMEBUFFER_UNSUPPORTED_EXT; 732 } 733 if (stencil_mt->format != MESA_FORMAT_S8) { 734 DBG("separate stencil is %s instead of S8\n", 735 _mesa_get_format_name(stencil_mt->format)); 736 fb->_Status = GL_FRAMEBUFFER_UNSUPPORTED_EXT; 737 } 738 if (intel->gen < 7 && depth_mt->hiz_mt == NULL) { 739 /* Before Gen7, separate depth and stencil buffers can be used 740 * only if HiZ is enabled. From the Sandybridge PRM, Volume 2, 741 * Part 1, Bit 3DSTATE_DEPTH_BUFFER.SeparateStencilBufferEnable: 742 * [DevSNB]: This field must be set to the same value (enabled 743 * or disabled) as Hierarchical Depth Buffer Enable. 744 */ 745 DBG("separate stencil without HiZ\n"); 746 fb->_Status = GL_FRAMEBUFFER_UNSUPPORTED; 747 } 748 } 749 } 750 751 for (i = 0; i < Elements(fb->Attachment); i++) { 752 struct gl_renderbuffer *rb; 753 struct intel_renderbuffer *irb; 754 755 if (fb->Attachment[i].Type == GL_NONE) 756 continue; 757 758 /* A supported attachment will have a Renderbuffer set either 759 * from being a Renderbuffer or being a texture that got the 760 * intel_wrap_texture() treatment. 761 */ 762 rb = fb->Attachment[i].Renderbuffer; 763 if (rb == NULL) { 764 DBG("attachment without renderbuffer\n"); 765 fb->_Status = GL_FRAMEBUFFER_UNSUPPORTED_EXT; 766 continue; 767 } 768 769 if (fb->Attachment[i].Type == GL_TEXTURE) { 770 const struct gl_texture_image *img = 771 _mesa_get_attachment_teximage_const(&fb->Attachment[i]); 772 773 if (img->Border) { 774 DBG("texture with border\n"); 775 fb->_Status = GL_FRAMEBUFFER_UNSUPPORTED_EXT; 776 continue; 777 } 778 } 779 780 irb = intel_renderbuffer(rb); 781 if (irb == NULL) { 782 DBG("software rendering renderbuffer\n"); 783 fb->_Status = GL_FRAMEBUFFER_UNSUPPORTED_EXT; 784 continue; 785 } 786 787 if (!intel->vtbl.render_target_supported(intel, rb)) { 788 DBG("Unsupported HW texture/renderbuffer format attached: %s\n", 789 _mesa_get_format_name(intel_rb_format(irb))); 790 fb->_Status = GL_FRAMEBUFFER_UNSUPPORTED_EXT; 791 } 792 } 793} 794 795/** 796 * Try to do a glBlitFramebuffer using glCopyTexSubImage2D 797 * We can do this when the dst renderbuffer is actually a texture and 798 * there is no scaling, mirroring or scissoring. 799 * 800 * \return new buffer mask indicating the buffers left to blit using the 801 * normal path. 802 */ 803static GLbitfield 804intel_blit_framebuffer_copy_tex_sub_image(struct gl_context *ctx, 805 GLint srcX0, GLint srcY0, 806 GLint srcX1, GLint srcY1, 807 GLint dstX0, GLint dstY0, 808 GLint dstX1, GLint dstY1, 809 GLbitfield mask, GLenum filter) 810{ 811 if (mask & GL_COLOR_BUFFER_BIT) { 812 const struct gl_framebuffer *drawFb = ctx->DrawBuffer; 813 const struct gl_framebuffer *readFb = ctx->ReadBuffer; 814 const struct gl_renderbuffer_attachment *drawAtt = 815 &drawFb->Attachment[drawFb->_ColorDrawBufferIndexes[0]]; 816 struct intel_renderbuffer *srcRb = 817 intel_renderbuffer(readFb->_ColorReadBuffer); 818 819 /* If the source and destination are the same size with no 820 mirroring, the rectangles are within the size of the 821 texture and there is no scissor then we can use 822 glCopyTexSubimage2D to implement the blit. This will end 823 up as a fast hardware blit on some drivers */ 824 if (srcRb && drawAtt && drawAtt->Texture && 825 srcX0 - srcX1 == dstX0 - dstX1 && 826 srcY0 - srcY1 == dstY0 - dstY1 && 827 srcX1 >= srcX0 && 828 srcY1 >= srcY0 && 829 srcX0 >= 0 && srcX1 <= readFb->Width && 830 srcY0 >= 0 && srcY1 <= readFb->Height && 831 dstX0 >= 0 && dstX1 <= drawFb->Width && 832 dstY0 >= 0 && dstY1 <= drawFb->Height && 833 !ctx->Scissor.Enabled) { 834 const struct gl_texture_object *texObj = drawAtt->Texture; 835 const GLuint dstLevel = drawAtt->TextureLevel; 836 const GLenum target = texObj->Target; 837 838 struct gl_texture_image *texImage = 839 _mesa_select_tex_image(ctx, texObj, target, dstLevel); 840 841 if (intel_copy_texsubimage(intel_context(ctx), 842 intel_texture_image(texImage), 843 dstX0, dstY0, 844 srcRb, 845 srcX0, srcY0, 846 srcX1 - srcX0, /* width */ 847 srcY1 - srcY0)) 848 mask &= ~GL_COLOR_BUFFER_BIT; 849 } 850 } 851 852 return mask; 853} 854 855static void 856intel_blit_framebuffer(struct gl_context *ctx, 857 GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, 858 GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, 859 GLbitfield mask, GLenum filter) 860{ 861 /* Try faster, glCopyTexSubImage2D approach first which uses the BLT. */ 862 mask = intel_blit_framebuffer_copy_tex_sub_image(ctx, 863 srcX0, srcY0, srcX1, srcY1, 864 dstX0, dstY0, dstX1, dstY1, 865 mask, filter); 866 if (mask == 0x0) 867 return; 868 869#ifndef I915 870 mask = brw_blorp_framebuffer(intel_context(ctx), 871 srcX0, srcY0, srcX1, srcY1, 872 dstX0, dstY0, dstX1, dstY1, 873 mask, filter); 874 if (mask == 0x0) 875 return; 876#endif 877 878 _mesa_meta_BlitFramebuffer(ctx, 879 srcX0, srcY0, srcX1, srcY1, 880 dstX0, dstY0, dstX1, dstY1, 881 mask, filter); 882} 883 884/** 885 * This is a no-op except on multisample buffers shared with DRI2. 886 */ 887void 888intel_renderbuffer_set_needs_downsample(struct intel_renderbuffer *irb) 889{ 890 if (irb->mt && irb->mt->singlesample_mt) 891 irb->mt->need_downsample = true; 892} 893 894void 895intel_renderbuffer_set_needs_hiz_resolve(struct intel_renderbuffer *irb) 896{ 897 if (irb->mt) { 898 intel_miptree_slice_set_needs_hiz_resolve(irb->mt, 899 irb->mt_level, 900 irb->mt_layer); 901 } 902} 903 904void 905intel_renderbuffer_set_needs_depth_resolve(struct intel_renderbuffer *irb) 906{ 907 if (irb->mt) { 908 intel_miptree_slice_set_needs_depth_resolve(irb->mt, 909 irb->mt_level, 910 irb->mt_layer); 911 } 912} 913 914bool 915intel_renderbuffer_resolve_hiz(struct intel_context *intel, 916 struct intel_renderbuffer *irb) 917{ 918 if (irb->mt) 919 return intel_miptree_slice_resolve_hiz(intel, 920 irb->mt, 921 irb->mt_level, 922 irb->mt_layer); 923 924 return false; 925} 926 927bool 928intel_renderbuffer_resolve_depth(struct intel_context *intel, 929 struct intel_renderbuffer *irb) 930{ 931 if (irb->mt) 932 return intel_miptree_slice_resolve_depth(intel, 933 irb->mt, 934 irb->mt_level, 935 irb->mt_layer); 936 937 return false; 938} 939 940/** 941 * Do one-time context initializations related to GL_EXT_framebuffer_object. 942 * Hook in device driver functions. 943 */ 944void 945intel_fbo_init(struct intel_context *intel) 946{ 947 intel->ctx.Driver.NewFramebuffer = intel_new_framebuffer; 948 intel->ctx.Driver.NewRenderbuffer = intel_new_renderbuffer; 949 intel->ctx.Driver.MapRenderbuffer = intel_map_renderbuffer; 950 intel->ctx.Driver.UnmapRenderbuffer = intel_unmap_renderbuffer; 951 intel->ctx.Driver.BindFramebuffer = intel_bind_framebuffer; 952 intel->ctx.Driver.FramebufferRenderbuffer = intel_framebuffer_renderbuffer; 953 intel->ctx.Driver.RenderTexture = intel_render_texture; 954 intel->ctx.Driver.FinishRenderTexture = intel_finish_render_texture; 955 intel->ctx.Driver.ResizeBuffers = intel_resize_buffers; 956 intel->ctx.Driver.ValidateFramebuffer = intel_validate_framebuffer; 957 intel->ctx.Driver.BlitFramebuffer = intel_blit_framebuffer; 958 959#if FEATURE_OES_EGL_image 960 intel->ctx.Driver.EGLImageTargetRenderbufferStorage = 961 intel_image_target_renderbuffer_storage; 962#endif 963} 964