Mesa (master): zink: flatten out ssbo/ubo variable decls in ntv

GitLab Mirror gitlab-mirror at kemper.freedesktop.org
Thu Jan 28 14:41:40 UTC 2021


Module: Mesa
Branch: master
Commit: 7e5c4b4da311f5314e3ecb72a52414b3e375faf3
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=7e5c4b4da311f5314e3ecb72a52414b3e375faf3

Author: Mike Blumenkrantz <michael.blumenkrantz at gmail.com>
Date:   Wed Dec  2 12:22:51 2020 -0500

zink: flatten out ssbo/ubo variable decls in ntv

we were using a system of block=array<uvec4> here, but we can really
just simplify this to block=array<uint> to make all the related code much
simpler

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

---

 .../drivers/zink/nir_to_spirv/nir_to_spirv.c       | 70 +++++++---------------
 1 file changed, 20 insertions(+), 50 deletions(-)

diff --git a/src/gallium/drivers/zink/nir_to_spirv/nir_to_spirv.c b/src/gallium/drivers/zink/nir_to_spirv/nir_to_spirv.c
index 38b23724b8f..d68314ef387 100644
--- a/src/gallium/drivers/zink/nir_to_spirv/nir_to_spirv.c
+++ b/src/gallium/drivers/zink/nir_to_spirv/nir_to_spirv.c
@@ -827,16 +827,16 @@ emit_bo(struct ntv_context *ctx, struct nir_variable *var)
    bool ssbo = var->data.mode == nir_var_mem_ssbo;
 
    SpvId array_type;
-   SpvId vec4_type = get_uvec_type(ctx, 32, 4);
+   SpvId uint_type = spirv_builder_type_uint(&ctx->builder, 32);
    uint32_t array_size = glsl_count_attribute_slots(var->interface_type, false);
    if (glsl_type_is_unsized_array(var->type))
-      array_type = spirv_builder_type_runtime_array(&ctx->builder, vec4_type);
+      array_type = spirv_builder_type_runtime_array(&ctx->builder, uint_type);
    else {
-      SpvId array_length = emit_uint_const(ctx, 32, array_size);
-      array_type = spirv_builder_type_array(&ctx->builder, vec4_type,
+      SpvId array_length = emit_uint_const(ctx, 32, array_size * 4);
+      array_type = spirv_builder_type_array(&ctx->builder, uint_type,
                                                array_length);
    }
-   spirv_builder_emit_array_stride(&ctx->builder, array_type, 16);
+   spirv_builder_emit_array_stride(&ctx->builder, array_type, 4);
 
    // wrap UBO-array in a struct
    SpvId runtime_array = 0;
@@ -1893,8 +1893,6 @@ emit_load_bo(struct ntv_context *ctx, nir_intrinsic_instr *intr)
 
    /* destination type for the load */
    SpvId type = get_dest_uvec_type(ctx, &intr->dest);
-   /* an id of the array stride in bytes */
-   SpvId vec4_size = emit_uint_const(ctx, 32, sizeof(uint32_t) * 4);
    /* an id of an array member in bytes */
    SpvId uint_size = emit_uint_const(ctx, 32, sizeof(uint32_t));
 
@@ -1906,7 +1904,7 @@ emit_load_bo(struct ntv_context *ctx, nir_intrinsic_instr *intr)
    /* our generated uniform has a memory layout like
     *
     * struct {
-    *    vec4 base[array_size];
+    *    uint base[array_size];
     * };
     *
     * where 'array_size' is set as though every member of the ubo takes up a vec4,
@@ -1919,25 +1917,18 @@ emit_load_bo(struct ntv_context *ctx, nir_intrinsic_instr *intr)
     * it may be a const value or it may be dynamic in the shader
     */
    SpvId offset = get_src(ctx, &intr->src[1]);
-   /* convert offset to an array index for 'base' to determine which vec4 to access */
-   SpvId vec_offset = emit_binop(ctx, SpvOpUDiv, uint_type, offset, vec4_size);
-   /* use the remainder to calculate the byte offset in the vec, which tells us the member
-    * that we're going to access
-    */
-   SpvId vec_member_offset = emit_binop(ctx, SpvOpUDiv, uint_type,
-                                        emit_binop(ctx, SpvOpUMod, uint_type, offset, vec4_size),
-                                        uint_size);
+   /* calculate the byte offset in the array */
+   SpvId vec_offset = emit_binop(ctx, SpvOpUDiv, uint_type, offset, uint_size);
    /* OpAccessChain takes an array of indices that drill into a hierarchy based on the type:
     * index 0 is accessing 'base'
     * index 1 is accessing 'base[index 1]'
-    * index 2 is accessing 'base[index 1][index 2]'
     *
     * we must perform the access this way in case src[1] is dynamic because there's
     * no other spirv method for using an id to access a member of a composite, as
     * (composite|vector)_extract both take literals
     */
    for (unsigned i = 0; i < num_components; i++) {
-      SpvId indices[3] = { member, vec_offset, vec_member_offset };
+      SpvId indices[2] = { member, vec_offset };
       SpvId ptr = spirv_builder_emit_access_chain(&ctx->builder, pointer_type,
                                                   bo, indices,
                                                   ARRAY_SIZE(indices));
@@ -1946,12 +1937,8 @@ emit_load_bo(struct ntv_context *ctx, nir_intrinsic_instr *intr)
          constituents[i] = emit_atomic(ctx, SpvOpAtomicLoad, uint_type, ptr, 0, 0);
       else
          constituents[i] = spirv_builder_emit_load(&ctx->builder, uint_type, ptr);
-      /* increment to the next vec4 member index for the next load */
-      vec_member_offset = emit_binop(ctx, SpvOpIAdd, uint_type, vec_member_offset, one);
-      if (i == 3 && num_components > 4) {
-         vec_offset = emit_binop(ctx, SpvOpIAdd, uint_type, vec_offset, one);
-         vec_member_offset = emit_uint_const(ctx, 32, 0);
-      }
+      /* increment to the next member index for the next load */
+      vec_offset = emit_binop(ctx, SpvOpIAdd, uint_type, vec_offset, one);
    }
 
    /* if we're loading a 64bit value, we have to reassemble all the u32 values we've loaded into u64 values
@@ -2282,16 +2269,11 @@ emit_atomic_intrinsic(struct ntv_context *ctx, nir_intrinsic_instr *intr)
                                                    dest_type);
    SpvId uint_type = get_uvec_type(ctx, 32, 1);
    /* an id of the array stride in bytes */
-   SpvId vec4_size = emit_uint_const(ctx, 32, sizeof(uint32_t) * 4);
-   /* an id of an array member in bytes */
    SpvId uint_size = emit_uint_const(ctx, 32, sizeof(uint32_t));
    SpvId member = emit_uint_const(ctx, 32, 0);
    SpvId offset = get_src(ctx, &intr->src[1]);
-   SpvId vec_offset = emit_binop(ctx, SpvOpUDiv, uint_type, offset, vec4_size);
-   SpvId vec_member_offset = emit_binop(ctx, SpvOpUDiv, uint_type,
-                                        emit_binop(ctx, SpvOpUMod, uint_type, offset, vec4_size),
-                                        uint_size);
-   SpvId indices[3] = { member, vec_offset, vec_member_offset };
+   SpvId vec_offset = emit_binop(ctx, SpvOpUDiv, uint_type, offset, uint_size);
+   SpvId indices[] = { member, vec_offset };
    SpvId ptr = spirv_builder_emit_access_chain(&ctx->builder, pointer_type,
                                                ssbo, indices,
                                                ARRAY_SIZE(indices));
@@ -2379,8 +2361,6 @@ emit_intrinsic(struct ntv_context *ctx, nir_intrinsic_instr *intr)
       /* we need to grab 2x32 to fill the 64bit value */
       bool is_64bit = bit_size == 64;
 
-      /* an id of the array stride in bytes */
-      SpvId vec4_size = emit_uint_const(ctx, 32, sizeof(uint32_t) * 4);
       /* an id of an array member in bytes */
       SpvId uint_size = emit_uint_const(ctx, 32, sizeof(uint32_t));
       /* we grab a single array member at a time, so it's a pointer to a uint */
@@ -2391,7 +2371,7 @@ emit_intrinsic(struct ntv_context *ctx, nir_intrinsic_instr *intr)
       /* our generated uniform has a memory layout like
        *
        * struct {
-       *    vec4 base[array_size];
+       *    uint base[array_size];
        * };
        *
        * where 'array_size' is set as though every member of the ubo takes up a vec4,
@@ -2404,14 +2384,8 @@ emit_intrinsic(struct ntv_context *ctx, nir_intrinsic_instr *intr)
        * it may be a const value or it may be dynamic in the shader
        */
       SpvId offset = get_src(ctx, &intr->src[2]);
-      /* convert offset to an array index for 'base' to determine which vec4 to access */
-      SpvId vec_offset = emit_binop(ctx, SpvOpUDiv, uint_type, offset, vec4_size);
-      /* use the remainder to calculate the byte offset in the vec, which tells us the member
-       * that we're going to access
-       */
-      SpvId vec_member_offset = emit_binop(ctx, SpvOpUDiv, uint_type,
-                                           emit_binop(ctx, SpvOpUMod, uint_type, offset, vec4_size),
-                                           uint_size);
+      /* calculate byte offset */
+      SpvId vec_offset = emit_binop(ctx, SpvOpUDiv, uint_type, offset, uint_size);
 
       SpvId value = get_src(ctx, &intr->src[0]);
       /* OpAccessChain takes an array of indices that drill into a hierarchy based on the type:
@@ -2435,8 +2409,8 @@ emit_intrinsic(struct ntv_context *ctx, nir_intrinsic_instr *intr)
                component_split = emit_bitcast(ctx, get_uvec_type(ctx, 32, 2), component);
             for (unsigned j = 0; j < 1 + !!is_64bit; j++) {
                if (j)
-                  vec_member_offset = emit_binop(ctx, SpvOpIAdd, uint_type, vec_member_offset, one);
-               SpvId indices[3] = { member, vec_offset, vec_member_offset };
+                  vec_offset = emit_binop(ctx, SpvOpIAdd, uint_type, vec_offset, one);
+               SpvId indices[] = { member, vec_offset };
                SpvId ptr = spirv_builder_emit_access_chain(&ctx->builder, pointer_type,
                                                            bo, indices,
                                                            ARRAY_SIZE(indices));
@@ -2447,14 +2421,10 @@ emit_intrinsic(struct ntv_context *ctx, nir_intrinsic_instr *intr)
             write_count++;
          } else if (is_64bit)
             /* we're doing 32bit stores here, so we need to increment correctly here */
-            vec_member_offset = emit_binop(ctx, SpvOpIAdd, uint_type, vec_member_offset, one);
+            vec_offset = emit_binop(ctx, SpvOpIAdd, uint_type, vec_offset, one);
 
          /* increment to the next vec4 member index for the next store */
-         vec_member_offset = emit_binop(ctx, SpvOpIAdd, uint_type, vec_member_offset, one);
-         if (i == 1 && is_64bit) {
-            vec_offset = emit_binop(ctx, SpvOpIAdd, uint_type, vec_offset, one);
-            vec_member_offset = emit_uint_const(ctx, 32, 0);
-         }
+         vec_offset = emit_binop(ctx, SpvOpIAdd, uint_type, vec_offset, one);
       }
       break;
    }



More information about the mesa-commit mailing list