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 <caio.oliveira@intel.com>
This commit is contained in:
@@ -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)
|
||||
|
@@ -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;
|
||||
|
@@ -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.
|
||||
*
|
||||
|
@@ -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;
|
||||
|
Reference in New Issue
Block a user