iris: only flush the render cache for aux changes, not format changes

Reviewed-by: Felix DeGrood <felix.j.degrood@intel.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/10217>
This commit is contained in:
Kenneth Graunke 2021-02-08 15:35:35 -08:00 committed by Marge Bot
parent ed8f2c4cbe
commit bfe2c5f667
3 changed files with 16 additions and 29 deletions

View File

@ -274,15 +274,13 @@ iris_blorp_exec(struct blorp_batch *blorp_batch,
PIPE_CONTROL_STALL_AT_SCOREBOARD);
#endif
/* Flush the render cache in cases where the same surface is reinterpreted
* with a different format, which blorp does for stencil and depth data
* among other things. Invalidation of sampler caches and flushing of any
* caches which had previously written the source surfaces should already
* have been handled by the caller.
/* Flush the render cache in cases where the same surface is used with
* different aux modes, which can lead to GPU hangs. Invalidation of
* sampler caches and flushing of any caches which had previously written
* the source surfaces should already have been handled by the caller.
*/
if (params->dst.enabled) {
iris_cache_flush_for_render(batch, params->dst.addr.buffer,
params->dst.view.format,
params->dst.aux_usage);
}

View File

@ -984,7 +984,6 @@ void iris_postdraw_update_resolve_tracking(struct iris_context *ice,
struct iris_batch *batch);
void iris_cache_flush_for_render(struct iris_batch *batch,
struct iris_bo *bo,
enum isl_format format,
enum isl_aux_usage aux_usage);
int iris_get_driver_query_info(struct pipe_screen *pscreen, unsigned index,
struct pipe_driver_query_info *info);

View File

@ -254,8 +254,7 @@ iris_predraw_resolve_framebuffer(struct iris_context *ice,
surf->view.array_len,
aux_usage);
iris_cache_flush_for_render(batch, res->bo, surf->view.format,
aux_usage);
iris_cache_flush_for_render(batch, res->bo, aux_usage);
}
}
}
@ -330,24 +329,16 @@ iris_postdraw_update_resolve_tracking(struct iris_context *ice,
}
}
static void *
format_aux_tuple(enum isl_format format, enum isl_aux_usage aux_usage)
{
return (void *)(uintptr_t)((uint32_t)format << 8 | aux_usage);
}
void
iris_cache_flush_for_render(struct iris_batch *batch,
struct iris_bo *bo,
enum isl_format format,
enum isl_aux_usage aux_usage)
{
iris_emit_buffer_barrier_for(batch, bo, IRIS_DOMAIN_RENDER_WRITE);
/* Check to see if this bo has been used by a previous rendering operation
* but with a different format or aux usage. If it has, flush the render
* cache so we ensure that it's only in there with one format or aux usage
* at a time.
* but with a different aux usage. If it has, flush the render cache so we
* ensure that it's only in there with one aux usage at a time.
*
* Even though it's not obvious, this can easily happen in practice.
* Suppose a client is blending on a surface with sRGB encode enabled on
@ -360,24 +351,23 @@ iris_cache_flush_for_render(struct iris_batch *batch,
* same time and the pixel scoreboard and color blender are trying to sort
* it all out. This ends badly (i.e. GPU hangs).
*
* To date, we have never observed GPU hangs or even corruption to be
* associated with switching the format, only the aux usage. However,
* there are comments in various docs which indicate that the render cache
* isn't 100% resilient to format changes. We may as well be conservative
* and flush on format changes too. We can always relax this later if we
* find it to be a performance problem.
* There are comments in various docs which indicate that the render cache
* isn't 100% resilient to format changes. However, to date, we have never
* observed GPU hangs or even corruption to be associated with switching the
* format, only the aux usage. So we let that slide for now.
*/
void *v_aux_usage = (void *) (uintptr_t) aux_usage;
struct hash_entry *entry =
_mesa_hash_table_search_pre_hashed(batch->cache.render, bo->hash, bo);
if (!entry) {
_mesa_hash_table_insert_pre_hashed(batch->cache.render, bo->hash, bo,
format_aux_tuple(format, aux_usage));
} else if (entry->data != format_aux_tuple(format, aux_usage)) {
v_aux_usage);
} else if (entry->data != v_aux_usage) {
iris_emit_pipe_control_flush(batch,
"cache tracker: render format mismatch",
"cache tracker: aux usage mismatch",
PIPE_CONTROL_RENDER_TARGET_FLUSH |
PIPE_CONTROL_CS_STALL);
entry->data = format_aux_tuple(format, aux_usage);
entry->data = v_aux_usage;
}
}