radeon_fbo.c revision f9e1542286a05e9773f8f31ee75887f6da969cdb
1/************************************************************************** 2 * 3 * Copyright 2008 Red Hat Inc. 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/enums.h" 34#include "main/fbobject.h" 35#include "main/framebuffer.h" 36#include "main/renderbuffer.h" 37#include "main/context.h" 38#include "main/texrender.h" 39#include "drivers/common/meta.h" 40 41#include "radeon_common.h" 42#include "radeon_mipmap_tree.h" 43 44#define FILE_DEBUG_FLAG RADEON_TEXTURE 45#define DBG(...) do { \ 46 if (RADEON_DEBUG & FILE_DEBUG_FLAG) \ 47 printf(__VA_ARGS__); \ 48} while(0) 49 50static struct gl_framebuffer * 51radeon_new_framebuffer(struct gl_context *ctx, GLuint name) 52{ 53 return _mesa_new_framebuffer(ctx, name); 54} 55 56static void 57radeon_delete_renderbuffer(struct gl_renderbuffer *rb) 58{ 59 struct radeon_renderbuffer *rrb = radeon_renderbuffer(rb); 60 61 radeon_print(RADEON_TEXTURE, RADEON_TRACE, 62 "%s(rb %p, rrb %p) \n", 63 __func__, rb, rrb); 64 65 ASSERT(rrb); 66 67 if (rrb && rrb->bo) { 68 radeon_bo_unref(rrb->bo); 69 } 70 free(rrb); 71} 72 73static void * 74radeon_get_pointer(struct gl_context *ctx, struct gl_renderbuffer *rb, 75 GLint x, GLint y) 76{ 77 radeon_print(RADEON_TEXTURE, RADEON_TRACE, 78 "%s(%p, rb %p) \n", 79 __func__, ctx, rb); 80 81 return NULL; 82} 83 84/** 85 * Called via glRenderbufferStorageEXT() to set the format and allocate 86 * storage for a user-created renderbuffer. 87 */ 88static GLboolean 89radeon_alloc_renderbuffer_storage(struct gl_context * ctx, struct gl_renderbuffer *rb, 90 GLenum internalFormat, 91 GLuint width, GLuint height) 92{ 93 struct radeon_context *radeon = RADEON_CONTEXT(ctx); 94 struct radeon_renderbuffer *rrb = radeon_renderbuffer(rb); 95 GLboolean software_buffer = GL_FALSE; 96 int cpp; 97 98 radeon_print(RADEON_TEXTURE, RADEON_TRACE, 99 "%s(%p, rb %p) \n", 100 __func__, ctx, rb); 101 102 ASSERT(rb->Name != 0); 103 switch (internalFormat) { 104 case GL_R3_G3_B2: 105 case GL_RGB4: 106 case GL_RGB5: 107 rb->Format = _dri_texformat_rgb565; 108 rb->DataType = GL_UNSIGNED_BYTE; 109 cpp = 2; 110 break; 111 case GL_RGB: 112 case GL_RGB8: 113 case GL_RGB10: 114 case GL_RGB12: 115 case GL_RGB16: 116 rb->Format = _dri_texformat_argb8888; 117 rb->DataType = GL_UNSIGNED_BYTE; 118 cpp = 4; 119 break; 120 case GL_RGBA: 121 case GL_RGBA2: 122 case GL_RGBA4: 123 case GL_RGB5_A1: 124 case GL_RGBA8: 125 case GL_RGB10_A2: 126 case GL_RGBA12: 127 case GL_RGBA16: 128 rb->Format = _dri_texformat_argb8888; 129 rb->DataType = GL_UNSIGNED_BYTE; 130 cpp = 4; 131 break; 132 case GL_STENCIL_INDEX: 133 case GL_STENCIL_INDEX1_EXT: 134 case GL_STENCIL_INDEX4_EXT: 135 case GL_STENCIL_INDEX8_EXT: 136 case GL_STENCIL_INDEX16_EXT: 137 /* alloc a depth+stencil buffer */ 138 rb->Format = MESA_FORMAT_S8_Z24; 139 rb->DataType = GL_UNSIGNED_INT_24_8_EXT; 140 cpp = 4; 141 break; 142 case GL_DEPTH_COMPONENT16: 143 rb->Format = MESA_FORMAT_Z16; 144 rb->DataType = GL_UNSIGNED_SHORT; 145 cpp = 2; 146 break; 147 case GL_DEPTH_COMPONENT: 148 case GL_DEPTH_COMPONENT24: 149 case GL_DEPTH_COMPONENT32: 150 rb->Format = MESA_FORMAT_X8_Z24; 151 rb->DataType = GL_UNSIGNED_INT; 152 cpp = 4; 153 break; 154 case GL_DEPTH_STENCIL_EXT: 155 case GL_DEPTH24_STENCIL8_EXT: 156 rb->Format = MESA_FORMAT_S8_Z24; 157 rb->DataType = GL_UNSIGNED_INT_24_8_EXT; 158 cpp = 4; 159 break; 160 default: 161 _mesa_problem(ctx, 162 "Unexpected format in radeon_alloc_renderbuffer_storage"); 163 return GL_FALSE; 164 } 165 166 rb->_BaseFormat = _mesa_base_fbo_format(ctx, internalFormat); 167 168 if (ctx->Driver.Flush) 169 ctx->Driver.Flush(ctx); /* +r6/r7 */ 170 171 if (rrb->bo) 172 radeon_bo_unref(rrb->bo); 173 174 175 if (software_buffer) { 176 return _mesa_soft_renderbuffer_storage(ctx, rb, internalFormat, 177 width, height); 178 } 179 else { 180 uint32_t size; 181 uint32_t pitch = ((cpp * width + 63) & ~63) / cpp; 182 183 if (RADEON_DEBUG & RADEON_MEMORY) 184 fprintf(stderr,"Allocating %d x %d radeon RBO (pitch %d)\n", width, 185 height, pitch); 186 187 size = pitch * height * cpp; 188 rrb->pitch = pitch * cpp; 189 rrb->cpp = cpp; 190 rrb->bo = radeon_bo_open(radeon->radeonScreen->bom, 191 0, 192 size, 193 0, 194 RADEON_GEM_DOMAIN_VRAM, 195 0); 196 rb->Width = width; 197 rb->Height = height; 198 return GL_TRUE; 199 } 200 201} 202 203#if FEATURE_OES_EGL_image 204static void 205radeon_image_target_renderbuffer_storage(struct gl_context *ctx, 206 struct gl_renderbuffer *rb, 207 void *image_handle) 208{ 209 radeonContextPtr radeon = RADEON_CONTEXT(ctx); 210 struct radeon_renderbuffer *rrb; 211 __DRIscreen *screen; 212 __DRIimage *image; 213 214 screen = radeon->radeonScreen->driScreen; 215 image = screen->dri2.image->lookupEGLImage(screen, image_handle, 216 screen->loaderPrivate); 217 if (image == NULL) 218 return; 219 220 rrb = radeon_renderbuffer(rb); 221 222 if (ctx->Driver.Flush) 223 ctx->Driver.Flush(ctx); /* +r6/r7 */ 224 225 if (rrb->bo) 226 radeon_bo_unref(rrb->bo); 227 rrb->bo = image->bo; 228 radeon_bo_ref(rrb->bo); 229 fprintf(stderr, "image->bo: %p, name: %d, rbs: w %d -> p %d\n", image->bo, image->bo->handle, 230 image->width, image->pitch); 231 232 rrb->cpp = image->cpp; 233 rrb->pitch = image->pitch * image->cpp; 234 235 rb->Format = image->format; 236 rb->InternalFormat = image->internal_format; 237 rb->Width = image->width; 238 rb->Height = image->height; 239 rb->Format = image->format; 240 rb->DataType = image->data_type; 241 rb->_BaseFormat = _mesa_base_fbo_format(radeon->glCtx, 242 image->internal_format); 243} 244#endif 245 246/** 247 * Called for each hardware renderbuffer when a _window_ is resized. 248 * Just update fields. 249 * Not used for user-created renderbuffers! 250 */ 251static GLboolean 252radeon_alloc_window_storage(struct gl_context * ctx, struct gl_renderbuffer *rb, 253 GLenum internalFormat, GLuint width, GLuint height) 254{ 255 ASSERT(rb->Name == 0); 256 rb->Width = width; 257 rb->Height = height; 258 rb->InternalFormat = internalFormat; 259 radeon_print(RADEON_TEXTURE, RADEON_TRACE, 260 "%s(%p, rb %p) \n", 261 __func__, ctx, rb); 262 263 264 return GL_TRUE; 265} 266 267 268static void 269radeon_resize_buffers(struct gl_context *ctx, struct gl_framebuffer *fb, 270 GLuint width, GLuint height) 271{ 272 struct radeon_framebuffer *radeon_fb = (struct radeon_framebuffer*)fb; 273 int i; 274 275 radeon_print(RADEON_TEXTURE, RADEON_TRACE, 276 "%s(%p, fb %p) \n", 277 __func__, ctx, fb); 278 279 _mesa_resize_framebuffer(ctx, fb, width, height); 280 281 fb->Initialized = GL_TRUE; /* XXX remove someday */ 282 283 if (fb->Name != 0) { 284 return; 285 } 286 287 /* Make sure all window system renderbuffers are up to date */ 288 for (i = 0; i < 2; i++) { 289 struct gl_renderbuffer *rb = &radeon_fb->color_rb[i]->base; 290 291 /* only resize if size is changing */ 292 if (rb && (rb->Width != width || rb->Height != height)) { 293 rb->AllocStorage(ctx, rb, rb->InternalFormat, width, height); 294 } 295 } 296} 297 298 299/** Dummy function for gl_renderbuffer::AllocStorage() */ 300static GLboolean 301radeon_nop_alloc_storage(struct gl_context * ctx, struct gl_renderbuffer *rb, 302 GLenum internalFormat, GLuint width, GLuint height) 303{ 304 _mesa_problem(ctx, "radeon_op_alloc_storage should never be called."); 305 return GL_FALSE; 306} 307 308 309/** 310 * Create a renderbuffer for a window's color, depth and/or stencil buffer. 311 * Not used for user-created renderbuffers. 312 */ 313struct radeon_renderbuffer * 314radeon_create_renderbuffer(gl_format format, __DRIdrawable *driDrawPriv) 315{ 316 struct radeon_renderbuffer *rrb; 317 318 rrb = CALLOC_STRUCT(radeon_renderbuffer); 319 320 radeon_print(RADEON_TEXTURE, RADEON_TRACE, 321 "%s( rrb %p ) \n", 322 __func__, rrb); 323 324 if (!rrb) 325 return NULL; 326 327 _mesa_init_renderbuffer(&rrb->base, 0); 328 rrb->base.ClassID = RADEON_RB_CLASS; 329 330 rrb->base.Format = format; 331 332 switch (format) { 333 case MESA_FORMAT_RGB565: 334 assert(_mesa_little_endian()); 335 rrb->base.DataType = GL_UNSIGNED_BYTE; 336 rrb->base._BaseFormat = GL_RGB; 337 break; 338 case MESA_FORMAT_RGB565_REV: 339 assert(!_mesa_little_endian()); 340 rrb->base.DataType = GL_UNSIGNED_BYTE; 341 rrb->base._BaseFormat = GL_RGB; 342 break; 343 case MESA_FORMAT_XRGB8888: 344 assert(_mesa_little_endian()); 345 rrb->base.DataType = GL_UNSIGNED_BYTE; 346 rrb->base._BaseFormat = GL_RGB; 347 break; 348 case MESA_FORMAT_XRGB8888_REV: 349 assert(!_mesa_little_endian()); 350 rrb->base.DataType = GL_UNSIGNED_BYTE; 351 rrb->base._BaseFormat = GL_RGB; 352 break; 353 case MESA_FORMAT_ARGB8888: 354 assert(_mesa_little_endian()); 355 rrb->base.DataType = GL_UNSIGNED_BYTE; 356 rrb->base._BaseFormat = GL_RGBA; 357 break; 358 case MESA_FORMAT_ARGB8888_REV: 359 assert(!_mesa_little_endian()); 360 rrb->base.DataType = GL_UNSIGNED_BYTE; 361 rrb->base._BaseFormat = GL_RGBA; 362 break; 363 case MESA_FORMAT_S8: 364 rrb->base.DataType = GL_UNSIGNED_BYTE; 365 rrb->base._BaseFormat = GL_STENCIL_INDEX; 366 break; 367 case MESA_FORMAT_Z16: 368 rrb->base.DataType = GL_UNSIGNED_SHORT; 369 rrb->base._BaseFormat = GL_DEPTH_COMPONENT; 370 break; 371 case MESA_FORMAT_X8_Z24: 372 rrb->base.DataType = GL_UNSIGNED_INT; 373 rrb->base._BaseFormat = GL_DEPTH_COMPONENT; 374 break; 375 case MESA_FORMAT_S8_Z24: 376 rrb->base.DataType = GL_UNSIGNED_INT_24_8_EXT; 377 rrb->base._BaseFormat = GL_DEPTH_STENCIL; 378 break; 379 default: 380 fprintf(stderr, "%s: Unknown format %s\n", 381 __FUNCTION__, _mesa_get_format_name(format)); 382 _mesa_delete_renderbuffer(&rrb->base); 383 return NULL; 384 } 385 386 rrb->dPriv = driDrawPriv; 387 rrb->base.InternalFormat = _mesa_get_format_base_format(format); 388 389 rrb->base.Delete = radeon_delete_renderbuffer; 390 rrb->base.AllocStorage = radeon_alloc_window_storage; 391 rrb->base.GetPointer = radeon_get_pointer; 392 393 rrb->bo = NULL; 394 return rrb; 395} 396 397static struct gl_renderbuffer * 398radeon_new_renderbuffer(struct gl_context * ctx, GLuint name) 399{ 400 struct radeon_renderbuffer *rrb; 401 402 rrb = CALLOC_STRUCT(radeon_renderbuffer); 403 404 radeon_print(RADEON_TEXTURE, RADEON_TRACE, 405 "%s(%p, rrb %p) \n", 406 __func__, ctx, rrb); 407 408 if (!rrb) 409 return NULL; 410 411 _mesa_init_renderbuffer(&rrb->base, name); 412 rrb->base.ClassID = RADEON_RB_CLASS; 413 414 rrb->base.Delete = radeon_delete_renderbuffer; 415 rrb->base.AllocStorage = radeon_alloc_renderbuffer_storage; 416 rrb->base.GetPointer = radeon_get_pointer; 417 418 return &rrb->base; 419} 420 421static void 422radeon_bind_framebuffer(struct gl_context * ctx, GLenum target, 423 struct gl_framebuffer *fb, struct gl_framebuffer *fbread) 424{ 425 radeon_print(RADEON_TEXTURE, RADEON_TRACE, 426 "%s(%p, fb %p, target %s) \n", 427 __func__, ctx, fb, 428 _mesa_lookup_enum_by_nr(target)); 429 430 if (target == GL_FRAMEBUFFER_EXT || target == GL_DRAW_FRAMEBUFFER_EXT) { 431 radeon_draw_buffer(ctx, fb); 432 } 433 else { 434 /* don't need to do anything if target == GL_READ_FRAMEBUFFER_EXT */ 435 } 436} 437 438static void 439radeon_framebuffer_renderbuffer(struct gl_context * ctx, 440 struct gl_framebuffer *fb, 441 GLenum attachment, struct gl_renderbuffer *rb) 442{ 443 444 if (ctx->Driver.Flush) 445 ctx->Driver.Flush(ctx); /* +r6/r7 */ 446 447 radeon_print(RADEON_TEXTURE, RADEON_TRACE, 448 "%s(%p, fb %p, rb %p) \n", 449 __func__, ctx, fb, rb); 450 451 _mesa_framebuffer_renderbuffer(ctx, fb, attachment, rb); 452 radeon_draw_buffer(ctx, fb); 453} 454 455static GLboolean 456radeon_update_wrapper(struct gl_context *ctx, struct radeon_renderbuffer *rrb, 457 struct gl_texture_image *texImage) 458{ 459 radeon_print(RADEON_TEXTURE, RADEON_TRACE, 460 "%s(%p, rrb %p, texImage %p, texFormat %s) \n", 461 __func__, ctx, rrb, texImage, _mesa_get_format_name(texImage->TexFormat)); 462 463 switch (texImage->TexFormat) { 464 case MESA_FORMAT_RGBA8888: 465 case MESA_FORMAT_RGBA8888_REV: 466 case MESA_FORMAT_ARGB8888: 467 case MESA_FORMAT_ARGB8888_REV: 468 case MESA_FORMAT_XRGB8888: 469 case MESA_FORMAT_XRGB8888_REV: 470 case MESA_FORMAT_RGB565: 471 case MESA_FORMAT_RGB565_REV: 472 case MESA_FORMAT_RGBA5551: 473 case MESA_FORMAT_ARGB1555: 474 case MESA_FORMAT_ARGB1555_REV: 475 case MESA_FORMAT_ARGB4444: 476 case MESA_FORMAT_ARGB4444_REV: 477 rrb->base.DataType = GL_UNSIGNED_BYTE; 478 break; 479 case MESA_FORMAT_Z16: 480 rrb->base.DataType = GL_UNSIGNED_SHORT; 481 break; 482 case MESA_FORMAT_X8_Z24: 483 rrb->base.DataType = GL_UNSIGNED_INT; 484 break; 485 case MESA_FORMAT_S8_Z24: 486 rrb->base.DataType = GL_UNSIGNED_INT_24_8_EXT; 487 break; 488 default: 489 _mesa_problem(ctx, "Unexpected texture format in radeon_update_wrapper()"); 490 } 491 492 rrb->cpp = _mesa_get_format_bytes(texImage->TexFormat); 493 rrb->pitch = texImage->Width * rrb->cpp; 494 rrb->base.Format = texImage->TexFormat; 495 rrb->base.InternalFormat = texImage->InternalFormat; 496 rrb->base._BaseFormat = _mesa_base_fbo_format(ctx, rrb->base.InternalFormat); 497 rrb->base.Width = texImage->Width; 498 rrb->base.Height = texImage->Height; 499 rrb->base.Delete = radeon_delete_renderbuffer; 500 rrb->base.AllocStorage = radeon_nop_alloc_storage; 501 502 return GL_TRUE; 503} 504 505 506static struct radeon_renderbuffer * 507radeon_wrap_texture(struct gl_context * ctx, struct gl_texture_image *texImage) 508{ 509 const GLuint name = ~0; /* not significant, but distinct for debugging */ 510 struct radeon_renderbuffer *rrb; 511 512 /* make an radeon_renderbuffer to wrap the texture image */ 513 rrb = CALLOC_STRUCT(radeon_renderbuffer); 514 515 radeon_print(RADEON_TEXTURE, RADEON_TRACE, 516 "%s(%p, rrb %p, texImage %p) \n", 517 __func__, ctx, rrb, texImage); 518 519 if (!rrb) { 520 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glFramebufferTexture"); 521 return NULL; 522 } 523 524 _mesa_init_renderbuffer(&rrb->base, name); 525 rrb->base.ClassID = RADEON_RB_CLASS; 526 527 if (!radeon_update_wrapper(ctx, rrb, texImage)) { 528 free(rrb); 529 return NULL; 530 } 531 532 return rrb; 533 534} 535static void 536radeon_render_texture(struct gl_context * ctx, 537 struct gl_framebuffer *fb, 538 struct gl_renderbuffer_attachment *att) 539{ 540 struct gl_texture_image *newImage 541 = att->Texture->Image[att->CubeMapFace][att->TextureLevel]; 542 struct radeon_renderbuffer *rrb = radeon_renderbuffer(att->Renderbuffer); 543 radeon_texture_image *radeon_image; 544 GLuint imageOffset; 545 546 radeon_print(RADEON_TEXTURE, RADEON_TRACE, 547 "%s(%p, fb %p, rrb %p, att %p)\n", 548 __func__, ctx, fb, rrb, att); 549 550 (void) fb; 551 552 ASSERT(newImage); 553 554 radeon_image = (radeon_texture_image *)newImage; 555 556 if (!radeon_image->mt || newImage->Border != 0) { 557 /* Fallback on drawing to a texture without a miptree. 558 */ 559 _mesa_reference_renderbuffer(&att->Renderbuffer, NULL); 560 _mesa_render_texture(ctx, fb, att); 561 return; 562 } 563 else if (!rrb) { 564 rrb = radeon_wrap_texture(ctx, newImage); 565 if (rrb) { 566 /* bind the wrapper to the attachment point */ 567 _mesa_reference_renderbuffer(&att->Renderbuffer, &rrb->base); 568 } 569 else { 570 /* fallback to software rendering */ 571 _mesa_render_texture(ctx, fb, att); 572 return; 573 } 574 } 575 576 if (!radeon_update_wrapper(ctx, rrb, newImage)) { 577 _mesa_reference_renderbuffer(&att->Renderbuffer, NULL); 578 _mesa_render_texture(ctx, fb, att); 579 return; 580 } 581 582 DBG("Begin render texture tid %lx tex=%u w=%d h=%d refcount=%d\n", 583 _glthread_GetID(), 584 att->Texture->Name, newImage->Width, newImage->Height, 585 rrb->base.RefCount); 586 587 /* point the renderbufer's region to the texture image region */ 588 if (rrb->bo != radeon_image->mt->bo) { 589 if (rrb->bo) 590 radeon_bo_unref(rrb->bo); 591 rrb->bo = radeon_image->mt->bo; 592 radeon_bo_ref(rrb->bo); 593 } 594 595 /* compute offset of the particular 2D image within the texture region */ 596 imageOffset = radeon_miptree_image_offset(radeon_image->mt, 597 att->CubeMapFace, 598 att->TextureLevel); 599 600 if (att->Texture->Target == GL_TEXTURE_3D) { 601 imageOffset += radeon_image->mt->levels[att->TextureLevel].rowstride * 602 radeon_image->mt->levels[att->TextureLevel].height * 603 att->Zoffset; 604 } 605 606 /* store that offset in the region, along with the correct pitch for 607 * the image we are rendering to */ 608 rrb->draw_offset = imageOffset; 609 rrb->pitch = radeon_image->mt->levels[att->TextureLevel].rowstride; 610 611 /* update drawing region, etc */ 612 radeon_draw_buffer(ctx, fb); 613} 614 615static void 616radeon_finish_render_texture(struct gl_context * ctx, 617 struct gl_renderbuffer_attachment *att) 618{ 619 620} 621static void 622radeon_validate_framebuffer(struct gl_context *ctx, struct gl_framebuffer *fb) 623{ 624 radeonContextPtr radeon = RADEON_CONTEXT(ctx); 625 gl_format mesa_format; 626 int i; 627 628 for (i = -2; i < (GLint) ctx->Const.MaxColorAttachments; i++) { 629 struct gl_renderbuffer_attachment *att; 630 if (i == -2) { 631 att = &fb->Attachment[BUFFER_DEPTH]; 632 } else if (i == -1) { 633 att = &fb->Attachment[BUFFER_STENCIL]; 634 } else { 635 att = &fb->Attachment[BUFFER_COLOR0 + i]; 636 } 637 638 if (att->Type == GL_TEXTURE) { 639 mesa_format = att->Texture->Image[att->CubeMapFace][att->TextureLevel]->TexFormat; 640 } else { 641 /* All renderbuffer formats are renderable, but not sampable */ 642 continue; 643 } 644 645 if (!radeon->vtbl.is_format_renderable(mesa_format)){ 646 fb->_Status = GL_FRAMEBUFFER_UNSUPPORTED; 647 radeon_print(RADEON_TEXTURE, RADEON_TRACE, 648 "%s: HW doesn't support format %s as output format of attachment %d\n", 649 __FUNCTION__, _mesa_get_format_name(mesa_format), i); 650 return; 651 } 652 } 653} 654 655void radeon_fbo_init(struct radeon_context *radeon) 656{ 657#if FEATURE_EXT_framebuffer_object 658 radeon->glCtx->Driver.NewFramebuffer = radeon_new_framebuffer; 659 radeon->glCtx->Driver.NewRenderbuffer = radeon_new_renderbuffer; 660 radeon->glCtx->Driver.BindFramebuffer = radeon_bind_framebuffer; 661 radeon->glCtx->Driver.FramebufferRenderbuffer = radeon_framebuffer_renderbuffer; 662 radeon->glCtx->Driver.RenderTexture = radeon_render_texture; 663 radeon->glCtx->Driver.FinishRenderTexture = radeon_finish_render_texture; 664 radeon->glCtx->Driver.ResizeBuffers = radeon_resize_buffers; 665 radeon->glCtx->Driver.ValidateFramebuffer = radeon_validate_framebuffer; 666#endif 667#if FEATURE_EXT_framebuffer_blit 668 radeon->glCtx->Driver.BlitFramebuffer = _mesa_meta_BlitFramebuffer; 669#endif 670#if FEATURE_OES_EGL_image 671 radeon->glCtx->Driver.EGLImageTargetRenderbufferStorage = 672 radeon_image_target_renderbuffer_storage; 673#endif 674} 675 676 677void radeon_renderbuffer_set_bo(struct radeon_renderbuffer *rb, 678 struct radeon_bo *bo) 679{ 680 struct radeon_bo *old; 681 old = rb->bo; 682 rb->bo = bo; 683 radeon_bo_ref(bo); 684 if (old) 685 radeon_bo_unref(old); 686} 687