Allows MSAA colorbuffers, which have a CMASK automatically and don't
need any further special handling, to be fast cleared. Instead
of clearing the buffer, set the clear color and the CMASK to the
cleared state.
---
 src/gallium/drivers/r600/evergreen_state.c |  8 +++++++-
 src/gallium/drivers/r600/r600_blit.c       | 29 +++++++++++++++++++++++++++++
 src/gallium/drivers/r600/r600_resource.h   |  3 +++
 3 files changed, 39 insertions(+), 1 deletion(-)

diff --git a/src/gallium/drivers/r600/evergreen_state.c 
b/src/gallium/drivers/r600/evergreen_state.c
index 3ebb157..072a365 100644
--- a/src/gallium/drivers/r600/evergreen_state.c
+++ b/src/gallium/drivers/r600/evergreen_state.c
@@ -1584,6 +1584,8 @@ void evergreen_init_color_surface(struct r600_context 
*rctx,
        surf->cb_color_fmask_slice = 
S_028C88_TILE_MAX(rtex->fmask_slice_tile_max);
        surf->cb_color_cmask_slice = 
S_028C80_TILE_MAX(rtex->cmask_slice_tile_max);
 
+       surf->cb_color_clear_value = rtex->color_clear_value;
+
        surf->color_initialized = true;
 }
 
@@ -2178,7 +2180,7 @@ static void evergreen_emit_framebuffer_state(struct 
r600_context *rctx, struct r
                                                       (struct 
r600_resource*)cb->base.texture,
                                                       RADEON_USAGE_READWRITE);
 
-               r600_write_context_reg_seq(cs, R_028C60_CB_COLOR0_BASE + i * 
0x3C, 11);
+               r600_write_context_reg_seq(cs, R_028C60_CB_COLOR0_BASE + i * 
0x3C, 15);
                r600_write_value(cs, cb->cb_color_base);        /* 
R_028C60_CB_COLOR0_BASE */
                r600_write_value(cs, cb->cb_color_pitch);       /* 
R_028C64_CB_COLOR0_PITCH */
                r600_write_value(cs, cb->cb_color_slice);       /* 
R_028C68_CB_COLOR0_SLICE */
@@ -2190,6 +2192,10 @@ static void evergreen_emit_framebuffer_state(struct 
r600_context *rctx, struct r
                r600_write_value(cs, cb->cb_color_cmask_slice); /* 
R_028C80_CB_COLOR0_CMASK_SLICE */
                r600_write_value(cs, cb->cb_color_fmask);       /* 
R_028C84_CB_COLOR0_FMASK */
                r600_write_value(cs, cb->cb_color_fmask_slice); /* 
R_028C88_CB_COLOR0_FMASK_SLICE */
+               r600_write_value(cs, cb->cb_color_clear_value); /* 
R_028C8C_CB_COLOR0_CLEAR_WORD0 */
+               r600_write_value(cs, 0);                        /* 
R_028C90_CB_COLOR0_CLEAR_WORD1 */
+               r600_write_value(cs, 0);                        /* 
R_028C94_CB_COLOR0_CLEAR_WORD2 */
+               r600_write_value(cs, 0);                        /* 
R_028C98_CB_COLOR0_CLEAR_WORD3 */
 
                r600_write_value(cs, PKT3(PKT3_NOP, 0, 0)); /* 
R_028C60_CB_COLOR0_BASE */
                r600_write_value(cs, reloc);
diff --git a/src/gallium/drivers/r600/r600_blit.c 
b/src/gallium/drivers/r600/r600_blit.c
index 058bf81..2b1b49a 100644
--- a/src/gallium/drivers/r600/r600_blit.c
+++ b/src/gallium/drivers/r600/r600_blit.c
@@ -412,6 +412,23 @@ static boolean is_simple_msaa_resolve(const struct 
pipe_blit_info *info)
                dst_tile_mode >= RADEON_SURF_MODE_1D;
 }
 
+static void r600_clear_buffer(struct pipe_context *ctx, struct pipe_resource 
*dst,
+                             unsigned offset, unsigned size, unsigned char 
value);
+
+static void eg_set_clear_color(struct pipe_context *ctx,
+                              const union pipe_color_union *color)
+{
+       struct r600_context *rctx = (struct r600_context *)ctx;
+       struct pipe_framebuffer_state *fb = &rctx->framebuffer.state;
+       union util_color uc;
+
+       memset(&uc, 0, sizeof(uc));
+       util_pack_color(color->f, fb->cbufs[0]->format, &uc);
+
+       /* TODO: color formats with more than 32bpp */
+       ((struct r600_texture *)fb->cbufs[0]->texture)->color_clear_value = 
uc.ui;
+}
+
 static void r600_clear(struct pipe_context *ctx, unsigned buffers,
                       const union pipe_color_union *color,
                       double depth, unsigned stencil)
@@ -419,6 +436,18 @@ static void r600_clear(struct pipe_context *ctx, unsigned 
buffers,
        struct r600_context *rctx = (struct r600_context *)ctx;
        struct pipe_framebuffer_state *fb = &rctx->framebuffer.state;
 
+       /* fast color clear on AA framebuffers (EG+) */
+       /* TODO: multiple color buffers */
+       if (rctx->chip_class >= EVERGREEN &&
+                       (buffers & PIPE_CLEAR_COLOR) && fb->nr_cbufs == 1 &&
+                       ((struct r600_texture 
*)fb->cbufs[0]->texture)->cmask_size) {
+               struct r600_texture *tex = (struct r600_texture 
*)fb->cbufs[0]->texture;
+               eg_set_clear_color(ctx, color);
+               r600_clear_buffer(ctx, fb->cbufs[0]->texture,
+                               tex->cmask_offset, tex->cmask_size, 0);
+               buffers &= ~PIPE_CLEAR_COLOR;
+       }
+
        /* if hyperz enabled just clear hyperz */
        if (fb->zsbuf && (buffers & PIPE_CLEAR_DEPTH)) {
                struct r600_texture *rtex;
diff --git a/src/gallium/drivers/r600/r600_resource.h 
b/src/gallium/drivers/r600/r600_resource.h
index d5df633..08a3ba7 100644
--- a/src/gallium/drivers/r600/r600_resource.h
+++ b/src/gallium/drivers/r600/r600_resource.h
@@ -91,6 +91,8 @@ struct r600_texture {
        struct r600_resource            *htile;
        /* use htile only for first level */
        float                           depth_clear;
+
+       unsigned                        color_clear_value;
 };
 
 #define R600_TEX_IS_TILED(tex, level) ((tex)->array_mode[level] != 
V_038000_ARRAY_LINEAR_GENERAL && (tex)->array_mode[level] != 
V_038000_ARRAY_LINEAR_ALIGNED)
@@ -132,6 +134,7 @@ struct r600_surface {
        unsigned cb_color_cmask;        /* CB_COLORn_CMASK (EG) or 
CB_COLORn_TILE (r600) */
        unsigned cb_color_cmask_slice;  /* EG only */
        unsigned cb_color_mask;         /* R600 only */
+       unsigned cb_color_clear_value;  /* EG only */
        struct r600_resource *cb_buffer_fmask; /* Used for FMASK relocations. 
R600 only */
        struct r600_resource *cb_buffer_cmask; /* Used for CMASK relocations. 
R600 only */
 
-- 
1.8.1.2

_______________________________________________
mesa-dev mailing list
mesa-dev@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/mesa-dev

Reply via email to