From dd83ef0d1a14b144c562129b5572f9ebdbe56042 Mon Sep 17 00:00:00 2001 From: Kenneth Graunke Date: Tue, 10 Sep 2019 11:14:57 -0700 Subject: [PATCH] iris: Track per-stage bind history, reduce work accordingly We now track per-stage bind history for constant and shader buffers, shader images, and sampler views by adding an extra res->bind_stages field to go with res->bind_history. This lets us flag IRIS_DIRTY_CONSTANTS for only the specific stages involved, and also skip some CPU overhead in iris_rebind_buffer. Cuts 4% of 3DSTATE_CONSTANT_XS packets in a Shadow of Mordor trace on Icelake. Reviewed-by: Caio Marcelo de Oliveira Filho --- src/gallium/drivers/iris/iris_context.h | 1 + src/gallium/drivers/iris/iris_resource.c | 7 +------ src/gallium/drivers/iris/iris_resource.h | 6 ++++++ src/gallium/drivers/iris/iris_state.c | 8 ++++++++ 4 files changed, 16 insertions(+), 6 deletions(-) diff --git a/src/gallium/drivers/iris/iris_context.h b/src/gallium/drivers/iris/iris_context.h index 08533039d81..f711398f33b 100644 --- a/src/gallium/drivers/iris/iris_context.h +++ b/src/gallium/drivers/iris/iris_context.h @@ -110,6 +110,7 @@ enum { #define IRIS_DIRTY_FS (1ull << 32) #define IRIS_DIRTY_CS (1ull << 33) #define IRIS_DIRTY_URB (1ull << 34) +#define IRIS_SHIFT_FOR_DIRTY_CONSTANTS 35 #define IRIS_DIRTY_CONSTANTS_VS (1ull << 35) #define IRIS_DIRTY_CONSTANTS_TCS (1ull << 36) #define IRIS_DIRTY_CONSTANTS_TES (1ull << 37) diff --git a/src/gallium/drivers/iris/iris_resource.c b/src/gallium/drivers/iris/iris_resource.c index 4de7b2090a8..7394825f637 100644 --- a/src/gallium/drivers/iris/iris_resource.c +++ b/src/gallium/drivers/iris/iris_resource.c @@ -1894,12 +1894,7 @@ iris_dirty_for_history(struct iris_context *ice, uint64_t dirty = 0ull; if (res->bind_history & PIPE_BIND_CONSTANT_BUFFER) { - dirty |= IRIS_DIRTY_CONSTANTS_VS | - IRIS_DIRTY_CONSTANTS_TCS | - IRIS_DIRTY_CONSTANTS_TES | - IRIS_DIRTY_CONSTANTS_GS | - IRIS_DIRTY_CONSTANTS_FS | - IRIS_DIRTY_CONSTANTS_CS; + dirty |= ((uint64_t)res->bind_stages) << IRIS_SHIFT_FOR_DIRTY_CONSTANTS; } ice->state.dirty |= dirty; diff --git a/src/gallium/drivers/iris/iris_resource.h b/src/gallium/drivers/iris/iris_resource.h index 5e3356e5055..826c959eb46 100644 --- a/src/gallium/drivers/iris/iris_resource.h +++ b/src/gallium/drivers/iris/iris_resource.h @@ -77,6 +77,12 @@ struct iris_resource { */ unsigned bind_history; + /** + * A bitfield of MESA_SHADER_* stages indicating where this resource + * was bound. + */ + unsigned bind_stages; + /** * For PIPE_BUFFER resources, a range which may contain valid data. * diff --git a/src/gallium/drivers/iris/iris_state.c b/src/gallium/drivers/iris/iris_state.c index 99e4a84c414..fad3a7fdcfd 100644 --- a/src/gallium/drivers/iris/iris_state.c +++ b/src/gallium/drivers/iris/iris_state.c @@ -2305,6 +2305,7 @@ iris_set_shader_images(struct pipe_context *ctx, shs->bound_image_views |= 1 << (start_slot + i); res->bind_history |= PIPE_BIND_SHADER_IMAGE; + res->bind_stages |= 1 << stage; isl_surf_usage_flags_t usage = ISL_SURF_USAGE_STORAGE_BIT; enum isl_format isl_fmt = @@ -2409,6 +2410,8 @@ iris_set_sampler_views(struct pipe_context *ctx, struct iris_sampler_view *view = (void *) pview; if (view) { view->res->bind_history |= PIPE_BIND_SAMPLER_VIEW; + view->res->bind_stages |= 1 << stage; + shs->bound_sampler_views |= 1 << (start + i); } } @@ -2756,6 +2759,7 @@ iris_set_constant_buffer(struct pipe_context *ctx, struct iris_resource *res = (void *) cbuf->buffer; res->bind_history |= PIPE_BIND_CONSTANT_BUFFER; + res->bind_stages |= 1 << stage; iris_upload_ubo_ssbo_surf_state(ice, cbuf, &shs->constbuf_surf_state[index], @@ -2888,6 +2892,7 @@ iris_set_shader_buffers(struct pipe_context *ctx, iris_upload_ubo_ssbo_surf_state(ice, ssbo, surf_state, true); res->bind_history |= PIPE_BIND_SHADER_BUFFER; + res->bind_stages |= 1 << stage; util_range_add(&res->valid_buffer_range, ssbo->buffer_offset, ssbo->buffer_offset + ssbo->buffer_size); @@ -6046,6 +6051,9 @@ iris_rebind_buffer(struct iris_context *ice, struct iris_shader_state *shs = &ice->state.shaders[s]; enum pipe_shader_type p_stage = stage_to_pipe(s); + if (!(res->bind_stages & (1 << s))) + continue; + if (res->bind_history & PIPE_BIND_CONSTANT_BUFFER) { /* Skip constant buffer 0, it's for regular uniforms, not UBOs */ uint32_t bound_cbufs = shs->bound_cbufs & ~1u; -- 2.30.2