summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMarek Olšák <[email protected]>2016-06-02 23:30:01 +0200
committerMarek Olšák <[email protected]>2016-06-07 11:12:26 +0200
commit9e5b5fbde0b445df1a3265b33e2ac890d6505409 (patch)
tree816f3c99493bdb404f60c40865cc237995cb2c26
parentc6b14bafa446d1556eb0dd344de34288617e1278 (diff)
gallium/radeon: don't discard DCC if an external user can write to it
We don't import textures with DCC now, but soon we will. v2: if we can't disable DCC for image writes, at least decompress DCC at bind time Reviewed-by: Nicolai Hähnle <[email protected]>
-rw-r--r--src/gallium/drivers/radeon/r600_pipe_common.h2
-rw-r--r--src/gallium/drivers/radeon/r600_texture.c31
-rw-r--r--src/gallium/drivers/radeonsi/si_descriptors.c10
3 files changed, 31 insertions, 12 deletions
diff --git a/src/gallium/drivers/radeon/r600_pipe_common.h b/src/gallium/drivers/radeon/r600_pipe_common.h
index 8072833204a..2d60da49b72 100644
--- a/src/gallium/drivers/radeon/r600_pipe_common.h
+++ b/src/gallium/drivers/radeon/r600_pipe_common.h
@@ -676,7 +676,7 @@ void evergreen_do_fast_color_clear(struct r600_common_context *rctx,
struct r600_atom *fb_state,
unsigned *buffers, unsigned *dirty_cbufs,
const union pipe_color_union *color);
-void r600_texture_disable_dcc(struct r600_common_screen *rscreen,
+bool r600_texture_disable_dcc(struct r600_common_screen *rscreen,
struct r600_texture *rtex);
void r600_init_screen_texture_functions(struct r600_common_screen *rscreen);
void r600_init_context_texture_functions(struct r600_common_context *rctx);
diff --git a/src/gallium/drivers/radeon/r600_texture.c b/src/gallium/drivers/radeon/r600_texture.c
index 71758c42093..0f5c08f281a 100644
--- a/src/gallium/drivers/radeon/r600_texture.c
+++ b/src/gallium/drivers/radeon/r600_texture.c
@@ -32,7 +32,7 @@
#include <errno.h>
#include <inttypes.h>
-static void r600_texture_discard_dcc(struct r600_common_screen *rscreen,
+static bool r600_texture_discard_dcc(struct r600_common_screen *rscreen,
struct r600_texture *rtex);
static void r600_texture_discard_cmask(struct r600_common_screen *rscreen,
struct r600_texture *rtex);
@@ -86,7 +86,8 @@ bool r600_prepare_for_dma_blit(struct r600_common_context *rctx,
src_box->height, src_box->depth))
return false;
- r600_texture_discard_dcc(rctx->screen, rdst);
+ if (!r600_texture_discard_dcc(rctx->screen, rdst))
+ return false;
}
/* CMASK as:
@@ -376,25 +377,37 @@ static void r600_texture_discard_cmask(struct r600_common_screen *rscreen,
p_atomic_inc(&rscreen->compressed_colortex_counter);
}
-static void r600_texture_discard_dcc(struct r600_common_screen *rscreen,
+static bool r600_can_disable_dcc(struct r600_texture *rtex)
+{
+ /* We can't disable DCC if it can be written by another process. */
+ return rtex->dcc_offset &&
+ (!rtex->resource.is_shared ||
+ !(rtex->resource.external_usage & PIPE_HANDLE_USAGE_WRITE));
+}
+
+static bool r600_texture_discard_dcc(struct r600_common_screen *rscreen,
struct r600_texture *rtex)
{
+ if (!r600_can_disable_dcc(rtex))
+ return false;
+
/* Disable DCC. */
rtex->dcc_offset = 0;
rtex->cb_color_info &= ~VI_S_028C70_DCC_ENABLE(1);
/* Notify all contexts about the change. */
r600_dirty_all_framebuffer_states(rscreen);
+ return true;
}
-void r600_texture_disable_dcc(struct r600_common_screen *rscreen,
+bool r600_texture_disable_dcc(struct r600_common_screen *rscreen,
struct r600_texture *rtex)
{
struct r600_common_context *rctx =
(struct r600_common_context *)rscreen->aux_context;
- if (!rtex->dcc_offset)
- return;
+ if (!r600_can_disable_dcc(rtex))
+ return false;
/* Decompress DCC. */
pipe_mutex_lock(rscreen->aux_context_lock);
@@ -402,7 +415,7 @@ void r600_texture_disable_dcc(struct r600_common_screen *rscreen,
rctx->b.flush(&rctx->b, NULL, 0);
pipe_mutex_unlock(rscreen->aux_context_lock);
- r600_texture_discard_dcc(rscreen, rtex);
+ return r600_texture_discard_dcc(rscreen, rtex);
}
static void r600_degrade_tile_mode_to_linear(struct r600_common_context *rctx,
@@ -497,8 +510,8 @@ static boolean r600_texture_get_handle(struct pipe_screen* screen,
* access.
*/
if (usage & PIPE_HANDLE_USAGE_WRITE && rtex->dcc_offset) {
- r600_texture_disable_dcc(rscreen, rtex);
- update_metadata = true;
+ if (r600_texture_disable_dcc(rscreen, rtex))
+ update_metadata = true;
}
if (!(usage & PIPE_HANDLE_USAGE_EXPLICIT_FLUSH) &&
diff --git a/src/gallium/drivers/radeonsi/si_descriptors.c b/src/gallium/drivers/radeonsi/si_descriptors.c
index f48ddb77aab..9ddb142602d 100644
--- a/src/gallium/drivers/radeonsi/si_descriptors.c
+++ b/src/gallium/drivers/radeonsi/si_descriptors.c
@@ -570,8 +570,14 @@ static void si_set_shader_image(struct si_context *ctx,
assert(tex->fmask.size == 0);
if (tex->dcc_offset &&
- view->access & PIPE_IMAGE_ACCESS_WRITE)
- r600_texture_disable_dcc(&screen->b, tex);
+ view->access & PIPE_IMAGE_ACCESS_WRITE) {
+ /* If DCC can't be disabled, at least decompress it.
+ * The decompression is relatively cheap if the surface
+ * has been decompressed already.
+ */
+ if (!r600_texture_disable_dcc(&screen->b, tex))
+ ctx->b.decompress_dcc(&ctx->b.b, tex);
+ }
if (is_compressed_colortex(tex)) {
images->compressed_colortex_mask |= 1 << slot;