summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarek Olšák <marek.olsak@amd.com>2014-03-06 02:44:07 +0100
committerMarek Olšák <marek.olsak@amd.com>2014-03-11 18:51:20 +0100
commita38e1fd78ba406abe6c6dfd665804ec0d8f98172 (patch)
treeead562dfb1eca0604d9cce10e1f352831701deda
parent28eb0bcf19a2a82166f685bf68bb0366bc560ba9 (diff)
radeonsi: implement fast color clear
This works for both multi-sample and single-sample color buffers. Reviewed-by: Michel Dänzer <michel.daenzer@amd.com>
-rw-r--r--src/gallium/drivers/radeon/r600_texture.c6
-rw-r--r--src/gallium/drivers/radeonsi/si_blit.c38
-rw-r--r--src/gallium/drivers/radeonsi/si_pipe.c1
-rw-r--r--src/gallium/drivers/radeonsi/si_pipe.h1
-rw-r--r--src/gallium/drivers/radeonsi/si_state.c17
5 files changed, 59 insertions, 4 deletions
diff --git a/src/gallium/drivers/radeon/r600_texture.c b/src/gallium/drivers/radeon/r600_texture.c
index 0ff43e7bae4..8eb48678f07 100644
--- a/src/gallium/drivers/radeon/r600_texture.c
+++ b/src/gallium/drivers/radeon/r600_texture.c
@@ -458,7 +458,11 @@ static void r600_texture_alloc_cmask_separate(struct r600_common_screen *rscreen
assert(rtex->cmask.size == 0);
- r600_texture_get_cmask_info(rscreen, rtex, &rtex->cmask);
+ if (rscreen->chip_class >= SI) {
+ si_texture_get_cmask_info(rscreen, rtex, &rtex->cmask);
+ } else {
+ r600_texture_get_cmask_info(rscreen, rtex, &rtex->cmask);
+ }
rtex->cmask_buffer = (struct r600_resource *)
pipe_buffer_create(&rscreen->b, PIPE_BIND_CUSTOM,
diff --git a/src/gallium/drivers/radeonsi/si_blit.c b/src/gallium/drivers/radeonsi/si_blit.c
index dd303c80008..6bc89ab76d1 100644
--- a/src/gallium/drivers/radeonsi/si_blit.c
+++ b/src/gallium/drivers/radeonsi/si_blit.c
@@ -277,7 +277,8 @@ static void si_blit_decompress_color(struct pipe_context *ctx,
si_blitter_begin(ctx, SI_DECOMPRESS);
util_blitter_custom_color(sctx->blitter, cbsurf,
- sctx->custom_blend_decompress);
+ rtex->fmask.size ? sctx->custom_blend_decompress :
+ sctx->custom_blend_fastclear);
si_blitter_end(ctx);
pipe_surface_reference(&cbsurf, NULL);
@@ -322,6 +323,31 @@ static void si_clear(struct pipe_context *ctx, unsigned buffers,
struct si_context *sctx = (struct si_context *)ctx;
struct pipe_framebuffer_state *fb = &sctx->framebuffer.state;
+ if (buffers & PIPE_CLEAR_COLOR) {
+ evergreen_do_fast_color_clear(&sctx->b, fb, &sctx->framebuffer.atom,
+ &buffers, color);
+ }
+
+ if (buffers & PIPE_CLEAR_COLOR) {
+ int i;
+
+ /* These buffers cannot use fast clear, make sure to disable expansion. */
+ for (i = 0; i < fb->nr_cbufs; i++) {
+ struct r600_texture *tex;
+
+ /* If not clearing this buffer, skip. */
+ if (!(buffers & (PIPE_CLEAR_COLOR0 << i)))
+ continue;
+
+ if (!fb->cbufs[i])
+ continue;
+
+ tex = (struct r600_texture *)fb->cbufs[i]->texture;
+ if (tex->fmask.size == 0)
+ tex->dirty_level_mask &= ~(1 << fb->cbufs[i]->u.tex.level);
+ }
+ }
+
si_blitter_begin(ctx, SI_CLEAR);
util_blitter_clear(sctx->blitter, fb->width, fb->height,
util_framebuffer_get_num_layers(fb),
@@ -700,8 +726,16 @@ static void si_blit(struct pipe_context *ctx,
}
static void si_flush_resource(struct pipe_context *ctx,
- struct pipe_resource *resource)
+ struct pipe_resource *res)
{
+ struct r600_texture *rtex = (struct r600_texture*)res;
+
+ assert(res->target != PIPE_BUFFER);
+
+ if (!rtex->is_depth && rtex->cmask.size) {
+ si_blit_decompress_color(ctx, rtex, 0, res->last_level,
+ 0, res->array_size - 1);
+ }
}
void si_init_blit_functions(struct si_context *sctx)
diff --git a/src/gallium/drivers/radeonsi/si_pipe.c b/src/gallium/drivers/radeonsi/si_pipe.c
index f8693bf8cdd..040fc5c6535 100644
--- a/src/gallium/drivers/radeonsi/si_pipe.c
+++ b/src/gallium/drivers/radeonsi/si_pipe.c
@@ -98,6 +98,7 @@ static void si_destroy_context(struct pipe_context *context)
sctx->b.b.delete_depth_stencil_alpha_state(&sctx->b.b, sctx->custom_dsa_flush_inplace);
sctx->b.b.delete_blend_state(&sctx->b.b, sctx->custom_blend_resolve);
sctx->b.b.delete_blend_state(&sctx->b.b, sctx->custom_blend_decompress);
+ sctx->b.b.delete_blend_state(&sctx->b.b, sctx->custom_blend_fastclear);
util_unreference_framebuffer_state(&sctx->framebuffer.state);
util_blitter_destroy(sctx->blitter);
diff --git a/src/gallium/drivers/radeonsi/si_pipe.h b/src/gallium/drivers/radeonsi/si_pipe.h
index c66c88e05a4..e8aa13e2df8 100644
--- a/src/gallium/drivers/radeonsi/si_pipe.h
+++ b/src/gallium/drivers/radeonsi/si_pipe.h
@@ -95,6 +95,7 @@ struct si_context {
void *custom_dsa_flush_inplace;
void *custom_blend_resolve;
void *custom_blend_decompress;
+ void *custom_blend_fastclear;
struct si_screen *screen;
union {
diff --git a/src/gallium/drivers/radeonsi/si_state.c b/src/gallium/drivers/radeonsi/si_state.c
index b95e1e20c8c..b012d0991c1 100644
--- a/src/gallium/drivers/radeonsi/si_state.c
+++ b/src/gallium/drivers/radeonsi/si_state.c
@@ -1667,6 +1667,20 @@ static void si_initialize_color_surface(struct si_context *sctx,
if (rtex->fmask.size) {
surf->cb_color_fmask = (offset + rtex->fmask.offset) >> 8;
surf->cb_color_fmask_slice = S_028C88_TILE_MAX(rtex->fmask.slice_tile_max);
+ } else {
+ /* This must be set for fast clear to work without FMASK. */
+ surf->cb_color_fmask = surf->cb_color_base;
+ surf->cb_color_fmask_slice = surf->cb_color_slice;
+ surf->cb_color_attrib |= S_028C74_FMASK_TILE_MODE_INDEX(tile_mode_index);
+
+ if (sctx->b.chip_class == SI) {
+ unsigned bankh = util_logbase2(rtex->surface.bankh);
+ surf->cb_color_attrib |= S_028C74_FMASK_BANK_HEIGHT(bankh);
+ }
+
+ if (sctx->b.chip_class >= CIK) {
+ surf->cb_color_pitch |= S_028C64_FMASK_TILE_MAX(pitch);
+ }
}
/* Determine pixel shader export format */
@@ -1866,7 +1880,7 @@ static void si_set_framebuffer_state(struct pipe_context *ctx,
sctx->framebuffer.export_16bpc |= 1 << i;
}
- if (rtex->fmask.size || rtex->cmask.size) {
+ if (rtex->fmask.size && rtex->cmask.size) {
sctx->framebuffer.compressed_cb_mask |= 1 << i;
}
}
@@ -2964,6 +2978,7 @@ void si_init_state_functions(struct si_context *sctx)
sctx->custom_dsa_flush_inplace = si_create_db_flush_dsa(sctx, false, false, 0);
sctx->custom_blend_resolve = si_create_blend_custom(sctx, V_028808_CB_RESOLVE);
sctx->custom_blend_decompress = si_create_blend_custom(sctx, V_028808_CB_FMASK_DECOMPRESS);
+ sctx->custom_blend_fastclear = si_create_blend_custom(sctx, V_028808_CB_ELIMINATE_FAST_CLEAR);
sctx->b.b.set_clip_state = si_set_clip_state;
sctx->b.b.set_scissor_states = si_set_scissor_states;