[Mesa-dev] [PATCH 2/2] st/mesa: a couple fixes for st_BlitFramebuffer()

Brian Paul brianp at vmware.com
Wed Jan 16 07:58:07 PST 2013


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
---
 src/mesa/state_tracker/st_cb_blit.c |   85 +++++++++++++++++++++-------------
 1 files changed, 52 insertions(+), 33 deletions(-)

diff --git a/src/mesa/state_tracker/st_cb_blit.c b/src/mesa/state_tracker/st_cb_blit.c
index d6194bf..c284f06 100644
--- a/src/mesa/state_tracker/st_cb_blit.c
+++ b/src/mesa/state_tracker/st_cb_blit.c
@@ -184,48 +184,67 @@ 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);
+               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;
+
+         if (!srcRb || !srcRb->surface)
+            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);
+         srcSurf = srcRb->surface;
 
-         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);
+         for (i = 0; i < drawFB->_NumColorDrawBuffers; i++) {
+            struct st_renderbuffer *dstRb =
+               st_renderbuffer(drawFB->_ColorDrawBuffers[i]);
 
-         st->pipe->blit(st->pipe, &blit);
+            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);
+               }
+            }
+         }
       }
    }
 
-- 
1.7.3.4



More information about the mesa-dev mailing list