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

View File

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

View File

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