summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBas Nieuwenhuizen <[email protected]>2015-10-21 00:10:41 +0200
committerMarek Olšák <[email protected]>2016-03-09 15:02:27 +0100
commit1e48ec7571cb36b4ee5660f8066c7905a3432969 (patch)
tree642591be3ba79bae59b6743227b6e3b70e361939
parentb744ac9f44099e1b50d335dc9bdc0950ab7ec374 (diff)
radeonsi: add DCC decompression (v2)
This is currently not needed but will be necessary when we have features that do not work with DCC enabled, such as image stores and sharing non-scanout surfaces. v2: Marek: rebase, remove decompression from si_flush_resource (not needed) Reviewed-by: Marek Olšák <[email protected]> Reviewed-by: Michel Dänzer <[email protected]> Reviewed-by: Nicolai Hähnle <[email protected]>
-rw-r--r--src/gallium/drivers/radeonsi/si_blit.c28
-rw-r--r--src/gallium/drivers/radeonsi/si_pipe.c2
-rw-r--r--src/gallium/drivers/radeonsi/si_pipe.h1
-rw-r--r--src/gallium/drivers/radeonsi/si_state.c1
4 files changed, 23 insertions, 9 deletions
diff --git a/src/gallium/drivers/radeonsi/si_blit.c b/src/gallium/drivers/radeonsi/si_blit.c
index 60b9f7b6a70..198f57d542f 100644
--- a/src/gallium/drivers/radeonsi/si_blit.c
+++ b/src/gallium/drivers/radeonsi/si_blit.c
@@ -271,18 +271,29 @@ void si_flush_depth_textures(struct si_context *sctx,
static void si_blit_decompress_color(struct pipe_context *ctx,
struct r600_texture *rtex,
unsigned first_level, unsigned last_level,
- unsigned first_layer, unsigned last_layer)
+ unsigned first_layer, unsigned last_layer,
+ bool need_dcc_decompress)
{
struct si_context *sctx = (struct si_context *)ctx;
unsigned layer, level, checked_last_layer, max_layer;
- if (!rtex->dirty_level_mask)
+ if (!rtex->dirty_level_mask && !need_dcc_decompress)
return;
for (level = first_level; level <= last_level; level++) {
- if (!(rtex->dirty_level_mask & (1 << level)))
+ void* custom_blend;
+
+ if (!(rtex->dirty_level_mask & (1 << level)) && !need_dcc_decompress)
continue;
+ if (rtex->dcc_offset && need_dcc_decompress) {
+ custom_blend = sctx->custom_blend_dcc_decompress;
+ } else if (rtex->fmask.size) {
+ custom_blend = sctx->custom_blend_decompress;
+ } else {
+ custom_blend = sctx->custom_blend_fastclear;
+ }
+
/* The smaller the mipmap level, the less layers there are
* as far as 3D textures are concerned. */
max_layer = util_max_layer(&rtex->resource.b.b, level);
@@ -298,9 +309,7 @@ static void si_blit_decompress_color(struct pipe_context *ctx,
cbsurf = ctx->create_surface(ctx, &rtex->resource.b.b, &surf_tmpl);
si_blitter_begin(ctx, SI_DECOMPRESS);
- util_blitter_custom_color(sctx->blitter, cbsurf,
- rtex->fmask.size ? sctx->custom_blend_decompress :
- sctx->custom_blend_fastclear);
+ util_blitter_custom_color(sctx->blitter, cbsurf, custom_blend);
si_blitter_end(ctx);
pipe_surface_reference(&cbsurf, NULL);
@@ -334,7 +343,8 @@ void si_decompress_color_textures(struct si_context *sctx,
si_blit_decompress_color(&sctx->b.b, tex,
view->u.tex.first_level, view->u.tex.last_level,
- 0, util_max_layer(&tex->resource.b.b, view->u.tex.first_level));
+ 0, util_max_layer(&tex->resource.b.b, view->u.tex.first_level),
+ false);
}
}
@@ -485,7 +495,7 @@ static void si_decompress_subresource(struct pipe_context *ctx,
first_layer, last_layer);
} else if (rtex->fmask.size || rtex->cmask.size || rtex->dcc_offset) {
si_blit_decompress_color(ctx, rtex, level, level,
- first_layer, last_layer);
+ first_layer, last_layer, false);
}
}
@@ -763,7 +773,7 @@ static void si_flush_resource(struct pipe_context *ctx,
if (!rtex->is_depth && (rtex->cmask.size || rtex->dcc_offset)) {
si_blit_decompress_color(ctx, rtex, 0, res->last_level,
- 0, util_max_layer(res, 0));
+ 0, util_max_layer(res, 0), false);
}
}
diff --git a/src/gallium/drivers/radeonsi/si_pipe.c b/src/gallium/drivers/radeonsi/si_pipe.c
index 37fd4a25d59..b445f6f010f 100644
--- a/src/gallium/drivers/radeonsi/si_pipe.c
+++ b/src/gallium/drivers/radeonsi/si_pipe.c
@@ -68,6 +68,8 @@ static void si_destroy_context(struct pipe_context *context)
sctx->b.b.delete_blend_state(&sctx->b.b, sctx->custom_blend_decompress);
if (sctx->custom_blend_fastclear)
sctx->b.b.delete_blend_state(&sctx->b.b, sctx->custom_blend_fastclear);
+ if (sctx->custom_blend_dcc_decompress)
+ sctx->b.b.delete_blend_state(&sctx->b.b, sctx->custom_blend_dcc_decompress);
util_unreference_framebuffer_state(&sctx->framebuffer.state);
if (sctx->blitter)
diff --git a/src/gallium/drivers/radeonsi/si_pipe.h b/src/gallium/drivers/radeonsi/si_pipe.h
index e6f92a31f96..4d45e8ca3f1 100644
--- a/src/gallium/drivers/radeonsi/si_pipe.h
+++ b/src/gallium/drivers/radeonsi/si_pipe.h
@@ -196,6 +196,7 @@ struct si_context {
void *custom_blend_resolve;
void *custom_blend_decompress;
void *custom_blend_fastclear;
+ void *custom_blend_dcc_decompress;
void *pstipple_sampler_state;
struct si_screen *screen;
struct pipe_fence_handle *last_gfx_fence;
diff --git a/src/gallium/drivers/radeonsi/si_state.c b/src/gallium/drivers/radeonsi/si_state.c
index 08a6505b0b3..c7be30a2967 100644
--- a/src/gallium/drivers/radeonsi/si_state.c
+++ b/src/gallium/drivers/radeonsi/si_state.c
@@ -3513,6 +3513,7 @@ void si_init_state_functions(struct si_context *sctx)
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->custom_blend_dcc_decompress = si_create_blend_custom(sctx, V_028808_CB_DCC_DECOMPRESS);
sctx->b.b.set_clip_state = si_set_clip_state;
sctx->b.b.set_scissor_states = si_set_scissor_states;