iris: Track per-stage bind history, reduce work accordingly
authorKenneth Graunke <kenneth@whitecape.org>
Tue, 10 Sep 2019 18:14:57 +0000 (11:14 -0700)
committerKenneth Graunke <kenneth@whitecape.org>
Wed, 18 Sep 2019 22:44:22 +0000 (15:44 -0700)
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>
src/gallium/drivers/iris/iris_context.h
src/gallium/drivers/iris/iris_resource.c
src/gallium/drivers/iris/iris_resource.h
src/gallium/drivers/iris/iris_state.c

index 08533039d81d43f4ff631857f98ecf8c027e0171..f711398f33b82aa64bdacef1321e9e8e3e0f5f9a 100644 (file)
@@ -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)
index 4de7b2090a84ca1f818b827fb3025930d2ae0ff9..7394825f637639e7c8beffb364f7a09ee4f21a47 100644 (file)
@@ -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;
index 5e3356e5055c64434d7309a158815f1659de2adb..826c959eb46287b44c08c04b49f1b09d72bcafc9 100644 (file)
@@ -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.
     *
index 99e4a84c414dcc0efa284e17060499bfcd8b9a61..fad3a7fdcfd4d36166dd603d851a1061b5be0bfb 100644 (file)
@@ -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;