From 415ede346decfcc21b0639052dc01c4d41060385 Mon Sep 17 00:00:00 2001 From: Kenneth Graunke Date: Wed, 21 Nov 2018 01:03:48 -0800 Subject: [PATCH] iris: Flush for history at various moments When we blit, transfer, or copy_resource to a buffer, we need to flush to ensure any stale data for that buffer is invalidated in the caches. bind_history will inform us which caches need to be flushed. Also, for any push constant buffers, we need to flag those dirty so that we re-emit 3DSTATE_CONSTANT_*, causing the data to be re-pushed. --- src/gallium/drivers/iris/iris_blit.c | 5 +++ src/gallium/drivers/iris/iris_resource.c | 42 ++++++++++++++++-------- src/gallium/drivers/iris/iris_resource.h | 1 + 3 files changed, 34 insertions(+), 14 deletions(-) diff --git a/src/gallium/drivers/iris/iris_blit.c b/src/gallium/drivers/iris/iris_blit.c index 6e6f4456072..c50e7958d24 100644 --- a/src/gallium/drivers/iris/iris_blit.c +++ b/src/gallium/drivers/iris/iris_blit.c @@ -378,6 +378,9 @@ iris_blit(struct pipe_context *ctx, const struct pipe_blit_info *info) } blorp_batch_finish(&blorp_batch); + + iris_flush_and_dirty_for_history(ice, batch, (struct iris_resource *) + info->dst.resource); } /** @@ -432,6 +435,8 @@ iris_resource_copy_region(struct pipe_context *ctx, } blorp_batch_finish(&blorp_batch); + + iris_flush_and_dirty_for_history(ice, batch, (struct iris_resource *) dst); } void diff --git a/src/gallium/drivers/iris/iris_resource.c b/src/gallium/drivers/iris/iris_resource.c index 67586b22751..677bb0be1d1 100644 --- a/src/gallium/drivers/iris/iris_resource.c +++ b/src/gallium/drivers/iris/iris_resource.c @@ -858,24 +858,41 @@ iris_transfer_map(struct pipe_context *ctx, return map->ptr; } +static void +iris_transfer_flush_region(struct pipe_context *ctx, + struct pipe_transfer *xfer, + const struct pipe_box *box) +{ + struct iris_context *ice = (struct iris_context *)ctx; + struct iris_resource *res = (struct iris_resource *) xfer->resource; + + + // XXX: don't emit flushes in both engines...? we may also need to flush + // even if there isn't a draw yet - may still be stale data in caches... + for (int i = 0; i < IRIS_BATCH_COUNT; i++) { + if (ice->batches[i].contains_draw) { + iris_batch_maybe_flush(&ice->batches[i], 24); + iris_flush_and_dirty_for_history(ice, &ice->batches[i], res); + } + } +} + static void iris_transfer_unmap(struct pipe_context *ctx, struct pipe_transfer *xfer) { struct iris_context *ice = (struct iris_context *)ctx; struct iris_transfer *map = (void *) xfer; struct iris_resource *res = (struct iris_resource *) xfer->resource; - struct isl_surf *surf = &res->surf; if (map->unmap) map->unmap(map); - /* XXX: big ol' hack! need to re-emit UBOs. want bind_history? */ - if (surf->tiling == ISL_TILING_LINEAR) { - ice->state.dirty |= IRIS_DIRTY_CONSTANTS_VS | IRIS_DIRTY_BINDINGS_VS - | IRIS_DIRTY_CONSTANTS_TCS | IRIS_DIRTY_BINDINGS_TCS - | IRIS_DIRTY_CONSTANTS_TES | IRIS_DIRTY_BINDINGS_TES - | IRIS_DIRTY_CONSTANTS_GS | IRIS_DIRTY_BINDINGS_GS - | IRIS_DIRTY_CONSTANTS_FS | IRIS_DIRTY_BINDINGS_FS; + // XXX: don't emit flushes in both engines...? + for (int i = 0; i < IRIS_BATCH_COUNT; i++) { + if (ice->batches[i].contains_draw) { + iris_batch_maybe_flush(&ice->batches[i], 24); + iris_flush_and_dirty_for_history(ice, &ice->batches[i], res); + } } pipe_resource_reference(&xfer->resource, NULL); @@ -889,6 +906,7 @@ iris_flush_resource(struct pipe_context *ctx, struct pipe_resource *resource) void iris_flush_and_dirty_for_history(struct iris_context *ice, + struct iris_batch *batch, struct iris_resource *res) { if (res->base.target != PIPE_BUFFER) @@ -918,11 +936,7 @@ iris_flush_and_dirty_for_history(struct iris_context *ice, if (res->bind_history & (PIPE_BIND_SHADER_BUFFER | PIPE_BIND_SHADER_IMAGE)) flush |= PIPE_CONTROL_DATA_CACHE_FLUSH; - // XXX: don't emit flushes in both engines...? - for (int i = 0; i < IRIS_BATCH_COUNT; i++) { - if (ice->batches[i].contains_draw) - iris_emit_pipe_control_flush(&ice->batches[i], flush); - } + iris_emit_pipe_control_flush(batch, flush); ice->state.dirty |= dirty; } @@ -939,7 +953,7 @@ static const struct u_transfer_vtbl transfer_vtbl = { .resource_destroy = iris_resource_destroy, .transfer_map = iris_transfer_map, .transfer_unmap = iris_transfer_unmap, - .transfer_flush_region = u_default_transfer_flush_region, + .transfer_flush_region = iris_transfer_flush_region, .get_internal_format = iris_resource_get_internal_format, .set_stencil = iris_resource_set_separate_stencil, .get_stencil = iris_resource_get_separate_stencil, diff --git a/src/gallium/drivers/iris/iris_resource.h b/src/gallium/drivers/iris/iris_resource.h index cff0efe49ad..8a3c44fdf78 100644 --- a/src/gallium/drivers/iris/iris_resource.h +++ b/src/gallium/drivers/iris/iris_resource.h @@ -136,6 +136,7 @@ void iris_get_depth_stencil_resources(struct pipe_resource *res, void iris_init_screen_resource_functions(struct pipe_screen *pscreen); void iris_flush_and_dirty_for_history(struct iris_context *ice, + struct iris_batch *batch, struct iris_resource *res); #endif -- 2.30.2