intel_fbo.c revision 4de8e2123ebeb50db252b2bb57fb167058fa4683
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/mtypes.h" 32#include "main/fbobject.h" 33#include "main/framebuffer.h" 34#include "main/renderbuffer.h" 35#include "main/context.h" 36#include "main/texformat.h" 37#include "main/texrender.h" 38#include "drivers/common/meta.h" 39 40#include "intel_context.h" 41#include "intel_buffers.h" 42#include "intel_fbo.h" 43#include "intel_mipmap_tree.h" 44#include "intel_regions.h" 45 46 47#define FILE_DEBUG_FLAG DEBUG_FBO 48 49 50/** 51 * Create a new framebuffer object. 52 */ 53static struct gl_framebuffer * 54intel_new_framebuffer(GLcontext * ctx, GLuint name) 55{ 56 /* Only drawable state in intel_framebuffer at this time, just use Mesa's 57 * class 58 */ 59 return _mesa_new_framebuffer(ctx, name); 60} 61 62 63/** Called by gl_renderbuffer::Delete() */ 64static void 65intel_delete_renderbuffer(struct gl_renderbuffer *rb) 66{ 67 GET_CURRENT_CONTEXT(ctx); 68 struct intel_context *intel = intel_context(ctx); 69 struct intel_renderbuffer *irb = intel_renderbuffer(rb); 70 71 ASSERT(irb); 72 73 if (irb->span_cache != NULL) 74 _mesa_free(irb->span_cache); 75 76 if (intel && irb->region) { 77 intel_region_release(&irb->region); 78 } 79 80 _mesa_free(irb); 81} 82 83 84/** 85 * Return a pointer to a specific pixel in a renderbuffer. 86 */ 87static void * 88intel_get_pointer(GLcontext * ctx, struct gl_renderbuffer *rb, 89 GLint x, GLint y) 90{ 91 /* By returning NULL we force all software rendering to go through 92 * the span routines. 93 */ 94 return NULL; 95} 96 97 98/** 99 * Called via glRenderbufferStorageEXT() to set the format and allocate 100 * storage for a user-created renderbuffer. 101 */ 102static GLboolean 103intel_alloc_renderbuffer_storage(GLcontext * ctx, struct gl_renderbuffer *rb, 104 GLenum internalFormat, 105 GLuint width, GLuint height) 106{ 107 struct intel_context *intel = intel_context(ctx); 108 struct intel_renderbuffer *irb = intel_renderbuffer(rb); 109 GLboolean softwareBuffer = GL_FALSE; 110 int cpp; 111 112 ASSERT(rb->Name != 0); 113 114 switch (internalFormat) { 115 case GL_R3_G3_B2: 116 case GL_RGB4: 117 case GL_RGB5: 118 rb->_ActualFormat = GL_RGB5; 119 rb->DataType = GL_UNSIGNED_BYTE; 120 rb->RedBits = 5; 121 rb->GreenBits = 6; 122 rb->BlueBits = 5; 123 irb->texformat = &_mesa_texformat_rgb565; 124 cpp = 2; 125 break; 126 case GL_RGB: 127 case GL_RGB8: 128 case GL_RGB10: 129 case GL_RGB12: 130 case GL_RGB16: 131 rb->_ActualFormat = GL_RGB8; 132 rb->DataType = GL_UNSIGNED_BYTE; 133 rb->RedBits = 8; 134 rb->GreenBits = 8; 135 rb->BlueBits = 8; 136 rb->AlphaBits = 0; 137 irb->texformat = &_mesa_texformat_argb8888; /* XXX: Need xrgb8888 */ 138 cpp = 4; 139 break; 140 case GL_RGBA: 141 case GL_RGBA2: 142 case GL_RGBA4: 143 case GL_RGB5_A1: 144 case GL_RGBA8: 145 case GL_RGB10_A2: 146 case GL_RGBA12: 147 case GL_RGBA16: 148 rb->_ActualFormat = GL_RGBA8; 149 rb->DataType = GL_UNSIGNED_BYTE; 150 rb->RedBits = 8; 151 rb->GreenBits = 8; 152 rb->BlueBits = 8; 153 rb->AlphaBits = 8; 154 irb->texformat = &_mesa_texformat_argb8888; 155 cpp = 4; 156 break; 157 case GL_STENCIL_INDEX: 158 case GL_STENCIL_INDEX1_EXT: 159 case GL_STENCIL_INDEX4_EXT: 160 case GL_STENCIL_INDEX8_EXT: 161 case GL_STENCIL_INDEX16_EXT: 162 /* alloc a depth+stencil buffer */ 163 rb->_ActualFormat = GL_DEPTH24_STENCIL8_EXT; 164 rb->DataType = GL_UNSIGNED_INT_24_8_EXT; 165 rb->StencilBits = 8; 166 cpp = 4; 167 irb->texformat = &_mesa_texformat_s8_z24; 168 break; 169 case GL_DEPTH_COMPONENT16: 170 rb->_ActualFormat = GL_DEPTH_COMPONENT16; 171 rb->DataType = GL_UNSIGNED_SHORT; 172 rb->DepthBits = 16; 173 cpp = 2; 174 irb->texformat = &_mesa_texformat_z16; 175 break; 176 case GL_DEPTH_COMPONENT: 177 case GL_DEPTH_COMPONENT24: 178 case GL_DEPTH_COMPONENT32: 179 rb->_ActualFormat = GL_DEPTH24_STENCIL8_EXT; 180 rb->DataType = GL_UNSIGNED_INT_24_8_EXT; 181 rb->DepthBits = 24; 182 cpp = 4; 183 irb->texformat = &_mesa_texformat_s8_z24; 184 break; 185 case GL_DEPTH_STENCIL_EXT: 186 case GL_DEPTH24_STENCIL8_EXT: 187 rb->_ActualFormat = GL_DEPTH24_STENCIL8_EXT; 188 rb->DataType = GL_UNSIGNED_INT_24_8_EXT; 189 rb->DepthBits = 24; 190 rb->StencilBits = 8; 191 cpp = 4; 192 irb->texformat = &_mesa_texformat_s8_z24; 193 break; 194 default: 195 _mesa_problem(ctx, 196 "Unexpected format in intel_alloc_renderbuffer_storage"); 197 return GL_FALSE; 198 } 199 200 intelFlush(ctx); 201 202 /* free old region */ 203 if (irb->region) { 204 intel_region_release(&irb->region); 205 } 206 207 /* allocate new memory region/renderbuffer */ 208 if (softwareBuffer) { 209 return _mesa_soft_renderbuffer_storage(ctx, rb, internalFormat, 210 width, height); 211 } 212 else { 213 /* Choose a pitch to match hardware requirements: 214 */ 215 GLuint pitch = ((cpp * width + 63) & ~63) / cpp; 216 217 /* alloc hardware renderbuffer */ 218 DBG("Allocating %d x %d Intel RBO (pitch %d)\n", width, 219 height, pitch); 220 221 irb->region = intel_region_alloc(intel, I915_TILING_NONE, 222 cpp, width, height, pitch, 223 GL_TRUE); 224 if (!irb->region) 225 return GL_FALSE; /* out of memory? */ 226 227 ASSERT(irb->region->buffer); 228 229 rb->Width = width; 230 rb->Height = height; 231 232 return GL_TRUE; 233 } 234} 235 236 237/** 238 * Called for each hardware renderbuffer when a _window_ is resized. 239 * Just update fields. 240 * Not used for user-created renderbuffers! 241 */ 242static GLboolean 243intel_alloc_window_storage(GLcontext * ctx, struct gl_renderbuffer *rb, 244 GLenum internalFormat, GLuint width, GLuint height) 245{ 246 ASSERT(rb->Name == 0); 247 rb->Width = width; 248 rb->Height = height; 249 rb->_ActualFormat = internalFormat; 250 251 return GL_TRUE; 252} 253 254 255static void 256intel_resize_buffers(GLcontext *ctx, struct gl_framebuffer *fb, 257 GLuint width, GLuint height) 258{ 259 struct intel_framebuffer *intel_fb = (struct intel_framebuffer*)fb; 260 int i; 261 262 _mesa_resize_framebuffer(ctx, fb, width, height); 263 264 fb->Initialized = GL_TRUE; /* XXX remove someday */ 265 266 if (fb->Name != 0) { 267 return; 268 } 269 270 /* Make sure all window system renderbuffers are up to date */ 271 for (i = 0; i < 2; i++) { 272 struct gl_renderbuffer *rb = &intel_fb->color_rb[i]->Base; 273 274 /* only resize if size is changing */ 275 if (rb && (rb->Width != width || rb->Height != height)) { 276 rb->AllocStorage(ctx, rb, rb->InternalFormat, width, height); 277 } 278 } 279} 280 281 282/** Dummy function for gl_renderbuffer::AllocStorage() */ 283static GLboolean 284intel_nop_alloc_storage(GLcontext * ctx, struct gl_renderbuffer *rb, 285 GLenum internalFormat, GLuint width, GLuint height) 286{ 287 _mesa_problem(ctx, "intel_op_alloc_storage should never be called."); 288 return GL_FALSE; 289} 290 291 292void 293intel_renderbuffer_set_region(struct intel_renderbuffer *rb, 294 struct intel_region *region) 295{ 296 struct intel_region *old; 297 298 old = rb->region; 299 rb->region = NULL; 300 intel_region_reference(&rb->region, region); 301 intel_region_release(&old); 302} 303 304 305/** 306 * Create a new intel_renderbuffer which corresponds to an on-screen window, 307 * not a user-created renderbuffer. 308 */ 309struct intel_renderbuffer * 310intel_create_renderbuffer(GLenum intFormat) 311{ 312 GET_CURRENT_CONTEXT(ctx); 313 314 struct intel_renderbuffer *irb; 315 const GLuint name = 0; 316 317 irb = CALLOC_STRUCT(intel_renderbuffer); 318 if (!irb) { 319 _mesa_error(ctx, GL_OUT_OF_MEMORY, "creating renderbuffer"); 320 return NULL; 321 } 322 323 _mesa_init_renderbuffer(&irb->Base, name); 324 irb->Base.ClassID = INTEL_RB_CLASS; 325 326 switch (intFormat) { 327 case GL_RGB5: 328 irb->Base._ActualFormat = GL_RGB5; 329 irb->Base._BaseFormat = GL_RGBA; 330 irb->Base.RedBits = 5; 331 irb->Base.GreenBits = 6; 332 irb->Base.BlueBits = 5; 333 irb->Base.DataType = GL_UNSIGNED_BYTE; 334 irb->texformat = &_mesa_texformat_rgb565; 335 break; 336 case GL_RGB8: 337 irb->Base._ActualFormat = GL_RGB8; 338 irb->Base._BaseFormat = GL_RGB; 339 irb->Base.RedBits = 8; 340 irb->Base.GreenBits = 8; 341 irb->Base.BlueBits = 8; 342 irb->Base.AlphaBits = 0; 343 irb->Base.DataType = GL_UNSIGNED_BYTE; 344 irb->texformat = &_mesa_texformat_argb8888; /* XXX: Need xrgb8888 */ 345 break; 346 case GL_RGBA8: 347 irb->Base._ActualFormat = GL_RGBA8; 348 irb->Base._BaseFormat = GL_RGBA; 349 irb->Base.RedBits = 8; 350 irb->Base.GreenBits = 8; 351 irb->Base.BlueBits = 8; 352 irb->Base.AlphaBits = 8; 353 irb->Base.DataType = GL_UNSIGNED_BYTE; 354 irb->texformat = &_mesa_texformat_argb8888; 355 break; 356 case GL_STENCIL_INDEX8_EXT: 357 irb->Base._ActualFormat = GL_STENCIL_INDEX8_EXT; 358 irb->Base._BaseFormat = GL_STENCIL_INDEX; 359 irb->Base.StencilBits = 8; 360 irb->Base.DataType = GL_UNSIGNED_BYTE; 361 irb->texformat = &_mesa_texformat_s8_z24; 362 break; 363 case GL_DEPTH_COMPONENT16: 364 irb->Base._ActualFormat = GL_DEPTH_COMPONENT16; 365 irb->Base._BaseFormat = GL_DEPTH_COMPONENT; 366 irb->Base.DepthBits = 16; 367 irb->Base.DataType = GL_UNSIGNED_SHORT; 368 irb->texformat = &_mesa_texformat_z16; 369 break; 370 case GL_DEPTH_COMPONENT24: 371 irb->Base._ActualFormat = GL_DEPTH24_STENCIL8_EXT; 372 irb->Base._BaseFormat = GL_DEPTH_COMPONENT; 373 irb->Base.DepthBits = 24; 374 irb->Base.DataType = GL_UNSIGNED_INT; 375 irb->texformat = &_mesa_texformat_s8_z24; 376 break; 377 case GL_DEPTH24_STENCIL8_EXT: 378 irb->Base._ActualFormat = GL_DEPTH24_STENCIL8_EXT; 379 irb->Base._BaseFormat = GL_DEPTH_STENCIL_EXT; 380 irb->Base.DepthBits = 24; 381 irb->Base.StencilBits = 8; 382 irb->Base.DataType = GL_UNSIGNED_INT_24_8_EXT; 383 irb->texformat = &_mesa_texformat_s8_z24; 384 break; 385 default: 386 _mesa_problem(NULL, 387 "Unexpected intFormat in intel_create_renderbuffer"); 388 return NULL; 389 } 390 391 irb->Base.InternalFormat = intFormat; 392 393 /* intel-specific methods */ 394 irb->Base.Delete = intel_delete_renderbuffer; 395 irb->Base.AllocStorage = intel_alloc_window_storage; 396 irb->Base.GetPointer = intel_get_pointer; 397 398 return irb; 399} 400 401 402/** 403 * Create a new renderbuffer object. 404 * Typically called via glBindRenderbufferEXT(). 405 */ 406static struct gl_renderbuffer * 407intel_new_renderbuffer(GLcontext * ctx, GLuint name) 408{ 409 /*struct intel_context *intel = intel_context(ctx); */ 410 struct intel_renderbuffer *irb; 411 412 irb = CALLOC_STRUCT(intel_renderbuffer); 413 if (!irb) { 414 _mesa_error(ctx, GL_OUT_OF_MEMORY, "creating renderbuffer"); 415 return NULL; 416 } 417 418 _mesa_init_renderbuffer(&irb->Base, name); 419 irb->Base.ClassID = INTEL_RB_CLASS; 420 421 /* intel-specific methods */ 422 irb->Base.Delete = intel_delete_renderbuffer; 423 irb->Base.AllocStorage = intel_alloc_renderbuffer_storage; 424 irb->Base.GetPointer = intel_get_pointer; 425 /* span routines set in alloc_storage function */ 426 427 return &irb->Base; 428} 429 430 431/** 432 * Called via glBindFramebufferEXT(). 433 */ 434static void 435intel_bind_framebuffer(GLcontext * ctx, GLenum target, 436 struct gl_framebuffer *fb, struct gl_framebuffer *fbread) 437{ 438 if (target == GL_FRAMEBUFFER_EXT || target == GL_DRAW_FRAMEBUFFER_EXT) { 439 intel_draw_buffer(ctx, fb); 440 } 441 else { 442 /* don't need to do anything if target == GL_READ_FRAMEBUFFER_EXT */ 443 } 444} 445 446 447/** 448 * Called via glFramebufferRenderbufferEXT(). 449 */ 450static void 451intel_framebuffer_renderbuffer(GLcontext * ctx, 452 struct gl_framebuffer *fb, 453 GLenum attachment, struct gl_renderbuffer *rb) 454{ 455 DBG("Intel FramebufferRenderbuffer %u %u\n", fb->Name, rb ? rb->Name : 0); 456 457 intelFlush(ctx); 458 459 _mesa_framebuffer_renderbuffer(ctx, fb, attachment, rb); 460 intel_draw_buffer(ctx, fb); 461} 462 463 464static GLboolean 465intel_update_wrapper(GLcontext *ctx, struct intel_renderbuffer *irb, 466 struct gl_texture_image *texImage) 467{ 468 irb->texformat = texImage->TexFormat; 469 470 if (texImage->TexFormat == &_mesa_texformat_argb8888) { 471 irb->Base._ActualFormat = GL_RGBA8; 472 irb->Base._BaseFormat = GL_RGBA; 473 irb->Base.DataType = GL_UNSIGNED_BYTE; 474 DBG("Render to RGBA8 texture OK\n"); 475 } 476 else if (texImage->TexFormat == &_mesa_texformat_rgb565) { 477 irb->Base._ActualFormat = GL_RGB5; 478 irb->Base._BaseFormat = GL_RGB; 479 irb->Base.DataType = GL_UNSIGNED_BYTE; 480 DBG("Render to RGB5 texture OK\n"); 481 } 482 else if (texImage->TexFormat == &_mesa_texformat_argb1555) { 483 irb->Base._ActualFormat = GL_RGB5_A1; 484 irb->Base._BaseFormat = GL_RGBA; 485 irb->Base.DataType = GL_UNSIGNED_BYTE; 486 DBG("Render to ARGB1555 texture OK\n"); 487 } 488 else if (texImage->TexFormat == &_mesa_texformat_argb4444) { 489 irb->Base._ActualFormat = GL_RGBA4; 490 irb->Base._BaseFormat = GL_RGBA; 491 irb->Base.DataType = GL_UNSIGNED_BYTE; 492 DBG("Render to ARGB4444 texture OK\n"); 493 } 494 else if (texImage->TexFormat == &_mesa_texformat_z16) { 495 irb->Base._ActualFormat = GL_DEPTH_COMPONENT16; 496 irb->Base._BaseFormat = GL_DEPTH_COMPONENT; 497 irb->Base.DataType = GL_UNSIGNED_SHORT; 498 DBG("Render to DEPTH16 texture OK\n"); 499 } 500 else if (texImage->TexFormat == &_mesa_texformat_s8_z24) { 501 irb->Base._ActualFormat = GL_DEPTH24_STENCIL8_EXT; 502 irb->Base._BaseFormat = GL_DEPTH_STENCIL_EXT; 503 irb->Base.DataType = GL_UNSIGNED_INT_24_8_EXT; 504 DBG("Render to DEPTH_STENCIL texture OK\n"); 505 } 506 else { 507 DBG("Render to texture BAD FORMAT %d\n", 508 texImage->TexFormat->MesaFormat); 509 return GL_FALSE; 510 } 511 512 irb->Base.InternalFormat = irb->Base._ActualFormat; 513 irb->Base.Width = texImage->Width; 514 irb->Base.Height = texImage->Height; 515 irb->Base.RedBits = texImage->TexFormat->RedBits; 516 irb->Base.GreenBits = texImage->TexFormat->GreenBits; 517 irb->Base.BlueBits = texImage->TexFormat->BlueBits; 518 irb->Base.AlphaBits = texImage->TexFormat->AlphaBits; 519 irb->Base.DepthBits = texImage->TexFormat->DepthBits; 520 irb->Base.StencilBits = texImage->TexFormat->StencilBits; 521 522 irb->Base.Delete = intel_delete_renderbuffer; 523 irb->Base.AllocStorage = intel_nop_alloc_storage; 524 525 return GL_TRUE; 526} 527 528 529/** 530 * When glFramebufferTexture[123]D is called this function sets up the 531 * gl_renderbuffer wrapper around the texture image. 532 * This will have the region info needed for hardware rendering. 533 */ 534static struct intel_renderbuffer * 535intel_wrap_texture(GLcontext * ctx, struct gl_texture_image *texImage) 536{ 537 const GLuint name = ~0; /* not significant, but distinct for debugging */ 538 struct intel_renderbuffer *irb; 539 540 /* make an intel_renderbuffer to wrap the texture image */ 541 irb = CALLOC_STRUCT(intel_renderbuffer); 542 if (!irb) { 543 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glFramebufferTexture"); 544 return NULL; 545 } 546 547 _mesa_init_renderbuffer(&irb->Base, name); 548 irb->Base.ClassID = INTEL_RB_CLASS; 549 550 if (!intel_update_wrapper(ctx, irb, texImage)) { 551 _mesa_free(irb); 552 return NULL; 553 } 554 555 return irb; 556} 557 558 559/** 560 * Called by glFramebufferTexture[123]DEXT() (and other places) to 561 * prepare for rendering into texture memory. This might be called 562 * many times to choose different texture levels, cube faces, etc 563 * before intel_finish_render_texture() is ever called. 564 */ 565static void 566intel_render_texture(GLcontext * ctx, 567 struct gl_framebuffer *fb, 568 struct gl_renderbuffer_attachment *att) 569{ 570 struct gl_texture_image *newImage 571 = att->Texture->Image[att->CubeMapFace][att->TextureLevel]; 572 struct intel_renderbuffer *irb = intel_renderbuffer(att->Renderbuffer); 573 struct intel_texture_image *intel_image; 574 GLuint imageOffset; 575 576 (void) fb; 577 578 ASSERT(newImage); 579 580 intel_image = intel_texture_image(newImage); 581 if (!intel_image->mt) { 582 /* Fallback on drawing to a texture that doesn't have a miptree 583 * (has a border, width/height 0, etc.) 584 */ 585 _mesa_reference_renderbuffer(&att->Renderbuffer, NULL); 586 _mesa_render_texture(ctx, fb, att); 587 return; 588 } 589 else if (!irb) { 590 irb = intel_wrap_texture(ctx, newImage); 591 if (irb) { 592 /* bind the wrapper to the attachment point */ 593 _mesa_reference_renderbuffer(&att->Renderbuffer, &irb->Base); 594 } 595 else { 596 /* fallback to software rendering */ 597 _mesa_render_texture(ctx, fb, att); 598 return; 599 } 600 } 601 602 if (!intel_update_wrapper(ctx, irb, newImage)) { 603 _mesa_reference_renderbuffer(&att->Renderbuffer, NULL); 604 _mesa_render_texture(ctx, fb, att); 605 return; 606 } 607 608 DBG("Begin render texture tid %x tex=%u w=%d h=%d refcount=%d\n", 609 _glthread_GetID(), 610 att->Texture->Name, newImage->Width, newImage->Height, 611 irb->Base.RefCount); 612 613 /* point the renderbufer's region to the texture image region */ 614 if (irb->region != intel_image->mt->region) { 615 if (irb->region) 616 intel_region_release(&irb->region); 617 intel_region_reference(&irb->region, intel_image->mt->region); 618 } 619 620 /* compute offset of the particular 2D image within the texture region */ 621 imageOffset = intel_miptree_image_offset(intel_image->mt, 622 att->CubeMapFace, 623 att->TextureLevel); 624 625 if (att->Texture->Target == GL_TEXTURE_3D) { 626 const GLuint *offsets = intel_miptree_depth_offsets(intel_image->mt, 627 att->TextureLevel); 628 imageOffset += offsets[att->Zoffset]; 629 } 630 631 /* store that offset in the region */ 632 intel_image->mt->region->draw_offset = imageOffset; 633 634 /* update drawing region, etc */ 635 intel_draw_buffer(ctx, fb); 636} 637 638 639/** 640 * Called by Mesa when rendering to a texture is done. 641 */ 642static void 643intel_finish_render_texture(GLcontext * ctx, 644 struct gl_renderbuffer_attachment *att) 645{ 646 /* no-op 647 * Previously we released the renderbuffer's intel_region but 648 * that's not necessary and actually caused problems when trying 649 * to do a glRead/CopyPixels from the renderbuffer later. 650 * The region will be released later if the texture is replaced 651 * or the renderbuffer deleted. 652 * 653 * The intention of this driver hook is more of a "done rendering 654 * to texture, please re-twiddle/etc if necessary". 655 */ 656} 657 658 659/** 660 * Do additional "completeness" testing of a framebuffer object. 661 */ 662static void 663intel_validate_framebuffer(GLcontext *ctx, struct gl_framebuffer *fb) 664{ 665 const struct intel_renderbuffer *depthRb = 666 intel_get_renderbuffer(fb, BUFFER_DEPTH); 667 const struct intel_renderbuffer *stencilRb = 668 intel_get_renderbuffer(fb, BUFFER_STENCIL); 669 int i; 670 671 if (stencilRb && stencilRb != depthRb) { 672 /* we only support combined depth/stencil buffers, not separate 673 * stencil buffers. 674 */ 675 fb->_Status = GL_FRAMEBUFFER_UNSUPPORTED_EXT; 676 } 677 678 for (i = 0; i < ctx->Const.MaxDrawBuffers; i++) { 679 struct gl_renderbuffer *rb = ctx->DrawBuffer->_ColorDrawBuffers[i]; 680 struct intel_renderbuffer *irb = intel_renderbuffer(rb); 681 682 if (rb == NULL) 683 continue; 684 685 if (irb == NULL) { 686 fb->_Status = GL_FRAMEBUFFER_UNSUPPORTED_EXT; 687 continue; 688 } 689 690 switch (irb->texformat->MesaFormat) { 691 case MESA_FORMAT_ARGB8888: 692 case MESA_FORMAT_RGB565: 693 case MESA_FORMAT_ARGB1555: 694 case MESA_FORMAT_ARGB4444: 695 break; 696 default: 697 fb->_Status = GL_FRAMEBUFFER_UNSUPPORTED_EXT; 698 } 699 } 700} 701 702 703/** 704 * Do one-time context initializations related to GL_EXT_framebuffer_object. 705 * Hook in device driver functions. 706 */ 707void 708intel_fbo_init(struct intel_context *intel) 709{ 710 intel->ctx.Driver.NewFramebuffer = intel_new_framebuffer; 711 intel->ctx.Driver.NewRenderbuffer = intel_new_renderbuffer; 712 intel->ctx.Driver.BindFramebuffer = intel_bind_framebuffer; 713 intel->ctx.Driver.FramebufferRenderbuffer = intel_framebuffer_renderbuffer; 714 intel->ctx.Driver.RenderTexture = intel_render_texture; 715 intel->ctx.Driver.FinishRenderTexture = intel_finish_render_texture; 716 intel->ctx.Driver.ResizeBuffers = intel_resize_buffers; 717 intel->ctx.Driver.ValidateFramebuffer = intel_validate_framebuffer; 718 intel->ctx.Driver.BlitFramebuffer = _mesa_meta_BlitFramebuffer; 719} 720