[PATCH 5/6] st/mesa: implement multisample resolve via BlitFramebuffer

Christoph Bumiller e0425955 at student.tuwien.ac.at
Mon Jul 25 05:14:01 PDT 2011


---
 src/gallium/auxiliary/util/u_box.h  |   25 +++++++++
 src/mesa/state_tracker/st_cb_blit.c |   95 +++++++++++++++++++++++++++++++++++
 2 files changed, 120 insertions(+), 0 deletions(-)

diff --git a/src/gallium/auxiliary/util/u_box.h b/src/gallium/auxiliary/util/u_box.h
index 0b28d0f..3eb842e 100644
--- a/src/gallium/auxiliary/util/u_box.h
+++ b/src/gallium/auxiliary/util/u_box.h
@@ -77,4 +77,29 @@ void u_box_3d( unsigned x,
    box->depth = d;
 }
 
+/* Returns whether vertical flip is required. */
+static INLINE
+boolean u_box_2d_corners(unsigned x0, unsigned y0,
+                         unsigned x1, unsigned y1, struct pipe_box *box)
+{
+   boolean yflip = FALSE;
+
+   if (y0 > y1) {
+      unsigned bt = y1;
+      y1 = y0;
+      y0 = bt;
+      yflip = TRUE;
+   }
+   assert(x1 >= x0);
+
+   box->x = x0;
+   box->y = y0;
+   box->z = 0;
+   box->width = x1 - x0;
+   box->height = y1 - y0;
+   box->depth = 1;
+
+   return yflip;
+}
+
 #endif
diff --git a/src/mesa/state_tracker/st_cb_blit.c b/src/mesa/state_tracker/st_cb_blit.c
index 416be19..57f8729 100644
--- a/src/mesa/state_tracker/st_cb_blit.c
+++ b/src/mesa/state_tracker/st_cb_blit.c
@@ -42,6 +42,7 @@
 #include "st_atom.h"
 
 #include "util/u_blit.h"
+#include "util/u_box.h"
 
 
 void
@@ -62,6 +63,85 @@ st_destroy_blit(struct st_context *st)
 #if FEATURE_EXT_framebuffer_blit
 
 static void
+st_BlitFramebuffer_resolve(struct gl_context *ctx, GLbitfield mask,
+                           GLint dstX, GLint dstY, struct pipe_box *box,
+                           boolean yflip)
+{
+   const GLbitfield depthStencil = GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT;
+
+   struct st_context *st = st_context(ctx);
+
+   struct st_renderbuffer *srcRb, *dstRb;
+
+   if (mask & GL_COLOR_BUFFER_BIT) {
+      srcRb = st_renderbuffer(ctx->ReadBuffer->_ColorReadBuffer);
+      dstRb = st_renderbuffer(ctx->DrawBuffer->_ColorDrawBuffers[0]);
+
+      box->z = srcRb->surface->u.tex.first_layer;
+
+      st->pipe->resource_resolve(st->pipe, PIPE_MASK_RGBA,
+                                 dstRb->texture,
+                                 dstRb->surface->u.tex.level, dstX, dstY,
+                                 dstRb->surface->u.tex.first_layer,
+                                 srcRb->texture,
+                                 srcRb->surface->u.tex.level, box, yflip);
+   }
+
+   if (mask & depthStencil) {
+      struct gl_renderbuffer_attachment *srcDepth, *srcStencil;
+      struct gl_renderbuffer_attachment *dstDepth, *dstStencil;
+
+      srcDepth = &ctx->ReadBuffer->Attachment[BUFFER_DEPTH];
+      dstDepth = &ctx->DrawBuffer->Attachment[BUFFER_DEPTH];
+      srcStencil = &ctx->ReadBuffer->Attachment[BUFFER_STENCIL];
+      dstStencil = &ctx->DrawBuffer->Attachment[BUFFER_STENCIL];
+
+      const boolean combined =
+         st_is_depth_stencil_combined(srcDepth, srcStencil) &&
+         st_is_depth_stencil_combined(dstDepth, dstStencil);
+
+      if ((mask & GL_DEPTH_BUFFER_BIT) || combined) {
+         /* resolve depth and, if combined and requested, stencil as well */
+         unsigned pipeMask = 0;
+
+         srcRb = st_renderbuffer(srcDepth->Renderbuffer);
+         dstRb = st_renderbuffer(dstDepth->Renderbuffer);
+
+         box->z = srcRb->surface->u.tex.first_layer;
+
+         if (mask & GL_DEPTH_BUFFER_BIT)
+            pipeMask |= PIPE_MASK_Z;
+         if ((mask & GL_STENCIL_BUFFER_BIT) && combined) {
+            mask = 0;
+            pipeMask |= PIPE_MASK_S;
+         }
+
+         st->pipe->resource_resolve(st->pipe, pipeMask,
+                                    dstRb->texture,
+                                    dstRb->surface->u.tex.level, dstX, dstY,
+                                    dstRb->surface->u.tex.first_layer,
+                                    srcRb->texture,
+                                    srcRb->surface->u.tex.level, box, yflip);
+      }
+
+      if (mask & GL_STENCIL_BUFFER_BIT) {
+         /* resolve separate stencil buffer */
+         srcRb = st_renderbuffer(srcStencil->Renderbuffer);
+         dstRb = st_renderbuffer(dstStencil->Renderbuffer);
+
+         box->z = srcRb->surface->u.tex.first_layer;
+
+         st->pipe->resource_resolve(st->pipe, PIPE_MASK_S,
+                                    dstRb->texture,
+                                    dstRb->surface->u.tex.level, dstX, dstY,
+                                    dstRb->surface->u.tex.first_layer,
+                                    srcRb->texture,
+                                    srcRb->surface->u.tex.level, box, yflip);
+      }
+   }
+}
+
+static void
 st_BlitFramebuffer(struct gl_context *ctx,
                    GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1,
                    GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,
@@ -114,6 +194,21 @@ st_BlitFramebuffer(struct gl_context *ctx,
       st->pipe->render_condition(st->pipe, NULL, 0);
    }
 
+   if (readFB->Visual.sampleBuffers != drawFB->Visual.sampleBuffers) {
+      boolean yflip;
+      struct pipe_box box; /* no scaling, already checked by mesa */
+
+      yflip = u_box_2d_corners(srcX0, srcY0, srcX1, srcY1, &box);
+
+      if (dstY0 > dstY1) {
+         yflip = TRUE;
+         dstY0 = dstY1;
+      }
+      st_BlitFramebuffer_resolve(ctx, mask, dstX0, dstY0, &box, yflip);
+
+      goto done;
+   }
+
    if (mask & GL_COLOR_BUFFER_BIT) {
       struct gl_renderbuffer_attachment *srcAtt =
          &readFB->Attachment[readFB->_ColorReadBufferIndex];
-- 
1.7.2.2


--------------050805050107080403080409--


More information about the mesa-dev mailing list