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