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