Mesa (staging/20.3): spirv: Implement OpArrayLength for OpenGL

GitLab Mirror gitlab-mirror at kemper.freedesktop.org
Fri Dec 18 21:19:44 UTC 2020


Module: Mesa
Branch: staging/20.3
Commit: a5f47bc43d6c34ed76d921b9aeaae952ca6a8bd9
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=a5f47bc43d6c34ed76d921b9aeaae952ca6a8bd9

Author: Caio Marcelo de Oliveira Filho <caio.oliveira at intel.com>
Date:   Wed Dec 16 20:51:30 2020 -0800

spirv: Implement OpArrayLength for OpenGL

Uses same NIR intrinsic as glsl_to_nir.  Make it an option so it is
easy later to move Vulkan drivers incrementally to use it.

Fixes piglit test spec/arb_gl_spirv/execution/ssbo/unsized-array-length.

Backported from f65750d2215 ("spirv: Implement OpArrayLength for OpenGL").

Closes: https://gitlab.freedesktop.org/mesa/mesa/-/issues/3691
Fixes: 15e43907 ("iris: Enable ARB_gl_spirv and ARB_spirv_extensions")
Reviewed-by: Alejandro Piñeiro <apinheiro at igalia.com>
Reviewed-by: Jason Ekstrand <jason at jlekstrand.net>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/8167>

---

 src/compiler/spirv/nir_spirv.h     |  5 +++
 src/compiler/spirv/vtn_variables.c | 73 ++++++++++++++++++++++++--------------
 src/mesa/main/glspirv.c            |  1 +
 3 files changed, 52 insertions(+), 27 deletions(-)

diff --git a/src/compiler/spirv/nir_spirv.h b/src/compiler/spirv/nir_spirv.h
index 5964184338b..750c77764e0 100644
--- a/src/compiler/spirv/nir_spirv.h
+++ b/src/compiler/spirv/nir_spirv.h
@@ -69,6 +69,11 @@ struct spirv_to_nir_options {
    /* Create a nir library. */
    bool create_library;
 
+   /* Whether to use nir_intrinsic_deref_buffer_array_length intrinsic instead
+    * of nir_intrinsic_get_ssbo_size to lower OpArrayLength.
+    */
+   bool use_deref_buffer_array_length;
+
    struct spirv_supported_capabilities caps;
 
    /* Address format for various kinds of pointers. */
diff --git a/src/compiler/spirv/vtn_variables.c b/src/compiler/spirv/vtn_variables.c
index 168d0e5156f..83171160a59 100644
--- a/src/compiler/spirv/vtn_variables.c
+++ b/src/compiler/spirv/vtn_variables.c
@@ -2434,36 +2434,55 @@ vtn_handle_variables(struct vtn_builder *b, SpvOp opcode,
                   "OpArrayLength must reference the last memeber of the "
                   "structure and that must be an array");
 
-      const uint32_t offset = ptr->type->offsets[field];
-      const uint32_t stride = ptr->type->members[field]->stride;
-
-      if (!ptr->block_index) {
+      if (b->options->use_deref_buffer_array_length) {
          struct vtn_access_chain chain = {
-            .length = 0,
+            .length = 1,
+            .link = {
+               { .mode = vtn_access_mode_literal, .id = field },
+            }
          };
-         ptr = vtn_pointer_dereference(b, ptr, &chain);
-         vtn_assert(ptr->block_index);
-      }
+         struct vtn_pointer *array = vtn_pointer_dereference(b, ptr, &chain);
 
-      nir_intrinsic_instr *instr =
-         nir_intrinsic_instr_create(b->nb.shader,
-                                    nir_intrinsic_get_ssbo_size);
-      instr->src[0] = nir_src_for_ssa(ptr->block_index);
-      nir_ssa_dest_init(&instr->instr, &instr->dest, 1, 32, NULL);
-      nir_builder_instr_insert(&b->nb, &instr->instr);
-      nir_ssa_def *buf_size = &instr->dest.ssa;
-
-      /* array_length = max(buffer_size - offset, 0) / stride */
-      nir_ssa_def *array_length =
-         nir_idiv(&b->nb,
-                  nir_imax(&b->nb,
-                           nir_isub(&b->nb,
-                                    buf_size,
-                                    nir_imm_int(&b->nb, offset)),
-                           nir_imm_int(&b->nb, 0u)),
-                  nir_imm_int(&b->nb, stride));
-
-      vtn_push_nir_ssa(b, w[2], array_length);
+         nir_intrinsic_instr *instr =
+            nir_intrinsic_instr_create(b->nb.shader,
+                                       nir_intrinsic_deref_buffer_array_length);
+         instr->src[0] = nir_src_for_ssa(vtn_pointer_to_ssa(b, array));
+         nir_ssa_dest_init(&instr->instr, &instr->dest, 1, 32, NULL);
+         nir_builder_instr_insert(&b->nb, &instr->instr);
+
+         vtn_push_nir_ssa(b, w[2], &instr->dest.ssa);
+      } else {
+         const uint32_t offset = ptr->type->offsets[field];
+         const uint32_t stride = ptr->type->members[field]->stride;
+
+         if (!ptr->block_index) {
+            struct vtn_access_chain chain = {
+               .length = 0,
+            };
+            ptr = vtn_pointer_dereference(b, ptr, &chain);
+            vtn_assert(ptr->block_index);
+         }
+
+         nir_intrinsic_instr *instr =
+            nir_intrinsic_instr_create(b->nb.shader,
+                                       nir_intrinsic_get_ssbo_size);
+         instr->src[0] = nir_src_for_ssa(ptr->block_index);
+         nir_ssa_dest_init(&instr->instr, &instr->dest, 1, 32, NULL);
+         nir_builder_instr_insert(&b->nb, &instr->instr);
+         nir_ssa_def *buf_size = &instr->dest.ssa;
+
+         /* array_length = max(buffer_size - offset, 0) / stride */
+         nir_ssa_def *array_length =
+            nir_idiv(&b->nb,
+                     nir_imax(&b->nb,
+                              nir_isub(&b->nb,
+                                       buf_size,
+                                       nir_imm_int(&b->nb, offset)),
+                              nir_imm_int(&b->nb, 0u)),
+                     nir_imm_int(&b->nb, stride));
+
+         vtn_push_nir_ssa(b, w[2], array_length);
+      }
       break;
    }
 
diff --git a/src/mesa/main/glspirv.c b/src/mesa/main/glspirv.c
index 92c521ba649..1668be08d95 100644
--- a/src/mesa/main/glspirv.c
+++ b/src/mesa/main/glspirv.c
@@ -244,6 +244,7 @@ _mesa_spirv_to_nir(struct gl_context *ctx,
    const struct spirv_to_nir_options spirv_options = {
       .environment = NIR_SPIRV_OPENGL,
       .frag_coord_is_sysval = ctx->Const.GLSLFragCoordIsSysVal,
+      .use_deref_buffer_array_length = true,
       .caps = ctx->Const.SpirVCapabilities,
       .ubo_addr_format = nir_address_format_32bit_index_offset,
       .ssbo_addr_format = nir_address_format_32bit_index_offset,



More information about the mesa-commit mailing list