diff options
author | Marek Olšák <[email protected]> | 2016-06-02 23:30:01 +0200 |
---|---|---|
committer | Marek Olšák <[email protected]> | 2016-06-07 11:12:26 +0200 |
commit | 9e5b5fbde0b445df1a3265b33e2ac890d6505409 (patch) | |
tree | 816f3c99493bdb404f60c40865cc237995cb2c26 | |
parent | c6b14bafa446d1556eb0dd344de34288617e1278 (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.h | 2 | ||||
-rw-r--r-- | src/gallium/drivers/radeon/r600_texture.c | 31 | ||||
-rw-r--r-- | src/gallium/drivers/radeonsi/si_descriptors.c | 10 |
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; |