[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