mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-01-01 11:50:09 +01:00
radeonsi: use current context for DCC feedback-loop decompress, fixes Elemental
This is just a workaround. The problem is described in the code. Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=96541 v2: say that it's only between the current context and aux_context Reviewed-by: Nicolai Hähnle <nicolai.haehnle@amd.com> (v1)
This commit is contained in:
parent
9812a50ae6
commit
a6b5845a0d
4 changed files with 38 additions and 16 deletions
|
|
@ -771,7 +771,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);
|
||||
bool r600_texture_disable_dcc(struct r600_common_screen *rscreen,
|
||||
bool r600_texture_disable_dcc(struct r600_common_context *rctx,
|
||||
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);
|
||||
|
|
|
|||
|
|
@ -400,20 +400,44 @@ static bool r600_texture_discard_dcc(struct r600_common_screen *rscreen,
|
|||
return true;
|
||||
}
|
||||
|
||||
bool r600_texture_disable_dcc(struct r600_common_screen *rscreen,
|
||||
/**
|
||||
* Disable DCC for the texture. (first decompress, then discard metadata).
|
||||
*
|
||||
* There is unresolved multi-context synchronization issue between
|
||||
* screen::aux_context and the current context. If applications do this with
|
||||
* multiple contexts, it's already undefined behavior for them and we don't
|
||||
* have to worry about that. The scenario is:
|
||||
*
|
||||
* If context 1 disables DCC and context 2 has queued commands that write
|
||||
* to the texture via CB with DCC enabled, and the order of operations is
|
||||
* as follows:
|
||||
* context 2 queues draw calls rendering to the texture, but doesn't flush
|
||||
* context 1 disables DCC and flushes
|
||||
* context 1 & 2 reset descriptors and FB state
|
||||
* context 2 flushes (new compressed tiles written by the draw calls)
|
||||
* context 1 & 2 read garbage, because DCC is disabled, yet there are
|
||||
* compressed tiled
|
||||
*
|
||||
* \param rctx the current context if you have one, or rscreen->aux_context
|
||||
* if you don't.
|
||||
*/
|
||||
bool r600_texture_disable_dcc(struct r600_common_context *rctx,
|
||||
struct r600_texture *rtex)
|
||||
{
|
||||
struct r600_common_context *rctx =
|
||||
(struct r600_common_context *)rscreen->aux_context;
|
||||
struct r600_common_screen *rscreen = rctx->screen;
|
||||
|
||||
if (!r600_can_disable_dcc(rtex))
|
||||
return false;
|
||||
|
||||
if (&rctx->b == rscreen->aux_context)
|
||||
pipe_mutex_lock(rscreen->aux_context_lock);
|
||||
|
||||
/* Decompress DCC. */
|
||||
pipe_mutex_lock(rscreen->aux_context_lock);
|
||||
rctx->decompress_dcc(&rctx->b, rtex);
|
||||
rctx->b.flush(&rctx->b, NULL, 0);
|
||||
pipe_mutex_unlock(rscreen->aux_context_lock);
|
||||
|
||||
if (&rctx->b == rscreen->aux_context)
|
||||
pipe_mutex_unlock(rscreen->aux_context_lock);
|
||||
|
||||
return r600_texture_discard_dcc(rscreen, rtex);
|
||||
}
|
||||
|
|
@ -492,6 +516,8 @@ static boolean r600_texture_get_handle(struct pipe_screen* screen,
|
|||
unsigned usage)
|
||||
{
|
||||
struct r600_common_screen *rscreen = (struct r600_common_screen*)screen;
|
||||
struct r600_common_context *aux_context =
|
||||
(struct r600_common_context*)rscreen->aux_context;
|
||||
struct r600_resource *res = (struct r600_resource*)resource;
|
||||
struct r600_texture *rtex = (struct r600_texture*)resource;
|
||||
struct radeon_bo_metadata metadata;
|
||||
|
|
@ -510,7 +536,7 @@ static boolean r600_texture_get_handle(struct pipe_screen* screen,
|
|||
* access.
|
||||
*/
|
||||
if (usage & PIPE_HANDLE_USAGE_WRITE && rtex->dcc_offset) {
|
||||
if (r600_texture_disable_dcc(rscreen, rtex))
|
||||
if (r600_texture_disable_dcc(aux_context, rtex))
|
||||
update_metadata = true;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -557,10 +557,8 @@ static void si_check_render_feedback_textures(struct si_context *sctx,
|
|||
render_feedback = true;
|
||||
}
|
||||
|
||||
if (render_feedback) {
|
||||
struct si_screen *screen = sctx->screen;
|
||||
r600_texture_disable_dcc(&screen->b, tex);
|
||||
}
|
||||
if (render_feedback)
|
||||
r600_texture_disable_dcc(&sctx->b, tex);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -599,10 +597,8 @@ static void si_check_render_feedback_images(struct si_context *sctx,
|
|||
render_feedback = true;
|
||||
}
|
||||
|
||||
if (render_feedback) {
|
||||
struct si_screen *screen = sctx->screen;
|
||||
r600_texture_disable_dcc(&screen->b, tex);
|
||||
}
|
||||
if (render_feedback)
|
||||
r600_texture_disable_dcc(&sctx->b, tex);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -663,7 +663,7 @@ static void si_set_shader_image(struct si_context *ctx,
|
|||
* The decompression is relatively cheap if the surface
|
||||
* has been decompressed already.
|
||||
*/
|
||||
if (r600_texture_disable_dcc(&screen->b, tex))
|
||||
if (r600_texture_disable_dcc(&ctx->b, tex))
|
||||
uses_dcc = false;
|
||||
else
|
||||
ctx->b.decompress_dcc(&ctx->b.b, tex);
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue