From 56c01d81094795286828ecb83713e043695e905a Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Wed, 16 Jan 2013 08:41:01 -0700 Subject: [PATCH] st/mesa: a couple fixes for st_BlitFramebuffer() MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit 1. Loop over multiple destination color buffers. If we set glDrawBuffers(GL_FRONT_AND_BACK) we need to loop over multiple color buffers, blitting to each. 2. Add checks for null src/dst surface pointers. This fixes a crash in the piglit fbo-missing-attachment-blit test. See bug http://bugs.freedesktop.org/show_bug.cgi?id=59450 Reviewed-by: Reviewed-by: Marek Olšák --- src/mesa/state_tracker/st_cb_blit.c | 82 ++++++++++++++++++----------- 1 file changed, 52 insertions(+), 30 deletions(-) diff --git a/src/mesa/state_tracker/st_cb_blit.c b/src/mesa/state_tracker/st_cb_blit.c index d6194bf15eb..ddef2707a97 100644 --- a/src/mesa/state_tracker/st_cb_blit.c +++ b/src/mesa/state_tracker/st_cb_blit.c @@ -184,48 +184,70 @@ st_BlitFramebuffer(struct gl_context *ctx, blit.mask = PIPE_MASK_RGBA; if (srcAtt->Type == GL_TEXTURE) { - struct st_texture_object *srcObj = - st_texture_object(srcAtt->Texture); - struct st_renderbuffer *dstRb = - st_renderbuffer(drawFB->_ColorDrawBuffers[0]); - struct pipe_surface *dstSurf = dstRb->surface; - - assert(srcObj->pt); - if (!srcObj->pt) { + struct st_texture_object *srcObj = st_texture_object(srcAtt->Texture); + GLuint i; + + if (!srcObj || !srcObj->pt) { return; } - blit.dst.resource = dstSurf->texture; - blit.dst.level = dstSurf->u.tex.level; - blit.dst.box.z = dstSurf->u.tex.first_layer; - blit.dst.format = util_format_linear(dstSurf->format); + for (i = 0; i < drawFB->_NumColorDrawBuffers; i++) { + struct st_renderbuffer *dstRb = + st_renderbuffer(drawFB->_ColorDrawBuffers[i]); - blit.src.resource = srcObj->pt; - blit.src.level = srcAtt->TextureLevel; - blit.src.box.z = srcAtt->Zoffset + srcAtt->CubeMapFace; - blit.src.format = util_format_linear(srcObj->pt->format); + if (dstRb) { + struct pipe_surface *dstSurf = dstRb->surface; - st->pipe->blit(st->pipe, &blit); + if (dstSurf) { + blit.dst.resource = dstSurf->texture; + blit.dst.level = dstSurf->u.tex.level; + blit.dst.box.z = dstSurf->u.tex.first_layer; + blit.dst.format = util_format_linear(dstSurf->format); + + blit.src.resource = srcObj->pt; + blit.src.level = srcAtt->TextureLevel; + blit.src.box.z = srcAtt->Zoffset + srcAtt->CubeMapFace; + blit.src.format = util_format_linear(srcObj->pt->format); + + st->pipe->blit(st->pipe, &blit); + } + } + } } else { struct st_renderbuffer *srcRb = st_renderbuffer(readFB->_ColorReadBuffer); - struct st_renderbuffer *dstRb = - st_renderbuffer(drawFB->_ColorDrawBuffers[0]); - struct pipe_surface *srcSurf = srcRb->surface; - struct pipe_surface *dstSurf = dstRb->surface; + struct pipe_surface *srcSurf; + GLuint i; - blit.dst.resource = dstSurf->texture; - blit.dst.level = dstSurf->u.tex.level; - blit.dst.box.z = dstSurf->u.tex.first_layer; - blit.dst.format = util_format_linear(dstSurf->format); + if (!srcRb || !srcRb->surface) { + return; + } - blit.src.resource = srcSurf->texture; - blit.src.level = srcSurf->u.tex.level; - blit.src.box.z = srcSurf->u.tex.first_layer; - blit.src.format = util_format_linear(srcSurf->format); + srcSurf = srcRb->surface; - st->pipe->blit(st->pipe, &blit); + for (i = 0; i < drawFB->_NumColorDrawBuffers; i++) { + struct st_renderbuffer *dstRb = + st_renderbuffer(drawFB->_ColorDrawBuffers[i]); + + if (dstRb) { + struct pipe_surface *dstSurf = dstRb->surface; + + if (dstSurf) { + blit.dst.resource = dstSurf->texture; + blit.dst.level = dstSurf->u.tex.level; + blit.dst.box.z = dstSurf->u.tex.first_layer; + blit.dst.format = util_format_linear(dstSurf->format); + + blit.src.resource = srcSurf->texture; + blit.src.level = srcSurf->u.tex.level; + blit.src.box.z = srcSurf->u.tex.first_layer; + blit.src.format = util_format_linear(srcSurf->format); + + st->pipe->blit(st->pipe, &blit); + } + } + } } } -- 2.30.2