Mesa (main): zink: fix buffer descriptor hashing

GitLab Mirror gitlab-mirror at kemper.freedesktop.org
Thu Jun 9 12:30:59 UTC 2022


Module: Mesa
Branch: main
Commit: 3156a5705dc5a5c97404bfd89f8a4a52bc9e1700
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=3156a5705dc5a5c97404bfd89f8a4a52bc9e1700

Author: Mike Blumenkrantz <michael.blumenkrantz at gmail.com>
Date:   Wed Jun  8 13:49:56 2022 -0400

zink: fix buffer descriptor hashing

since all the buffers are now an array descriptor, hashing needs
to iterate over all the descriptors in order to be accurate

Fixes: a7327c7cac9 ("zink: implement indirect buffer indexing")

Reviewed-by: Dave Airlie <airlied at redhat.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/16927>

---

 src/gallium/drivers/zink/zink_descriptors.c | 52 ++++++++++++++++-------------
 1 file changed, 28 insertions(+), 24 deletions(-)

diff --git a/src/gallium/drivers/zink/zink_descriptors.c b/src/gallium/drivers/zink/zink_descriptors.c
index d422d33e703..4f2f3e1eafc 100644
--- a/src/gallium/drivers/zink/zink_descriptors.c
+++ b/src/gallium/drivers/zink/zink_descriptors.c
@@ -1608,33 +1608,37 @@ zink_batch_descriptor_init(struct zink_screen *screen, struct zink_batch_state *
 }
 
 static uint32_t
-calc_descriptor_state_hash_ubo(struct zink_context *ctx, enum pipe_shader_type shader, int idx, uint32_t hash, bool need_offset)
-{
-   struct zink_resource *res = ctx->di.descriptor_res[ZINK_DESCRIPTOR_TYPE_UBO][shader][idx];
-   struct zink_resource_object *obj = res ? res->obj : NULL;
-   hash = XXH32(&obj, sizeof(void*), hash);
-   void *hash_data = &ctx->di.ubos[shader][idx].range;
-   size_t data_size = sizeof(unsigned);
-   hash = XXH32(hash_data, data_size, hash);
-   if (need_offset)
-      hash = XXH32(&ctx->di.ubos[shader][idx].offset, sizeof(unsigned), hash);
+calc_descriptor_state_hash_ubo(struct zink_context *ctx, struct zink_shader *zs, enum pipe_shader_type shader, int i, int idx, uint32_t hash, bool need_offset)
+{
+   for (unsigned k = 0; k < zs->bindings[ZINK_DESCRIPTOR_TYPE_UBO][i].size; k++) {
+      struct zink_resource *res = ctx->di.descriptor_res[ZINK_DESCRIPTOR_TYPE_UBO][shader][idx + k];
+      struct zink_resource_object *obj = res ? res->obj : NULL;
+      hash = XXH32(&obj, sizeof(void*), hash);
+      void *hash_data = &ctx->di.ubos[shader][idx + k].range;
+      size_t data_size = sizeof(unsigned);
+      hash = XXH32(hash_data, data_size, hash);
+      if (need_offset)
+         hash = XXH32(&ctx->di.ubos[shader][idx + k].offset, sizeof(unsigned), hash);
+   }
    return hash;
 }
 
 static uint32_t
 calc_descriptor_state_hash_ssbo(struct zink_context *ctx, struct zink_shader *zs, enum pipe_shader_type shader, int i, int idx, uint32_t hash)
 {
-   struct zink_resource *res = ctx->di.descriptor_res[ZINK_DESCRIPTOR_TYPE_SSBO][shader][idx];
-   struct zink_resource_object *obj = res ? res->obj : NULL;
-   hash = XXH32(&obj, sizeof(void*), hash);
-   if (obj) {
-      struct pipe_shader_buffer *ssbo = &ctx->ssbos[shader][idx];
-      hash = XXH32(&ssbo->buffer_offset, sizeof(ssbo->buffer_offset), hash);
-      hash = XXH32(&ssbo->buffer_size, sizeof(ssbo->buffer_size), hash);
-      /* compacted sets need a way to differentiate between a buffer bound as a ubo vs ssbo */
-      if (zink_screen(ctx->base.screen)->compact_descriptors) {
-         uint32_t writable = ctx->writable_ssbos[shader] & BITFIELD_BIT(idx);
-         hash = XXH32(&writable, sizeof(writable), hash);
+   for (unsigned k = 0; k < zs->bindings[ZINK_DESCRIPTOR_TYPE_SSBO][i].size; k++) {
+      struct zink_resource *res = ctx->di.descriptor_res[ZINK_DESCRIPTOR_TYPE_SSBO][shader][idx + k];
+      struct zink_resource_object *obj = res ? res->obj : NULL;
+      hash = XXH32(&obj, sizeof(void*), hash);
+      if (obj) {
+         struct pipe_shader_buffer *ssbo = &ctx->ssbos[shader][idx + k];
+         hash = XXH32(&ssbo->buffer_offset, sizeof(ssbo->buffer_offset), hash);
+         hash = XXH32(&ssbo->buffer_size, sizeof(ssbo->buffer_size), hash);
+         /* compacted sets need a way to differentiate between a buffer bound as a ubo vs ssbo */
+         if (zink_screen(ctx->base.screen)->compact_descriptors) {
+            uint32_t writable = ctx->writable_ssbos[shader] & BITFIELD_BIT(idx + k);
+            hash = XXH32(&writable, sizeof(writable), hash);
+         }
       }
    }
    return hash;
@@ -1688,7 +1692,7 @@ update_descriptor_stage_state(struct zink_context *ctx, enum pipe_shader_type sh
       int idx = zs->bindings[type][i].index;
       switch (type) {
       case ZINK_DESCRIPTOR_TYPE_UBO:
-         hash = calc_descriptor_state_hash_ubo(ctx, shader, idx, hash, true);
+         hash = calc_descriptor_state_hash_ubo(ctx, zs, shader, i, idx, hash, true);
          break;
       case ZINK_DESCRIPTOR_TYPE_SSBO:
          hash = calc_descriptor_state_hash_ssbo(ctx, zs, shader, i, idx, hash);
@@ -1760,12 +1764,12 @@ zink_context_update_descriptor_states(struct zink_context *ctx, struct zink_prog
                                            pg->dd->push_usage != ctx->dd->last_push_usage[pg->is_compute])) {
       uint32_t hash = 0;
       if (pg->is_compute) {
-          hash = calc_descriptor_state_hash_ubo(ctx, PIPE_SHADER_COMPUTE, 0, 0, false);
+          hash = calc_descriptor_state_hash_ubo(ctx, ctx->compute_stage, PIPE_SHADER_COMPUTE, 0, 0, 0, false);
       } else {
          bool first = true;
          u_foreach_bit(stage, pg->dd->push_usage) {
             if (!ctx->dd->gfx_push_valid[stage]) {
-               ctx->dd->gfx_push_state[stage] = calc_descriptor_state_hash_ubo(ctx, stage, 0, 0, false);
+               ctx->dd->gfx_push_state[stage] = calc_descriptor_state_hash_ubo(ctx, ctx->gfx_stages[stage], stage, 0, 0, 0, false);
                ctx->dd->gfx_push_valid[stage] = true;
             }
             if (first)



More information about the mesa-commit mailing list