Mesa (master): pan/midgard: Lower SSBOs in NIR

GitLab Mirror gitlab-mirror at kemper.freedesktop.org
Mon Feb 24 14:14:17 UTC 2020


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

Author: Alyssa Rosenzweig <alyssa.rosenzweig at collabora.com>
Date:   Tue Nov  5 08:59:49 2019 -0500

pan/midgard: Lower SSBOs in NIR

We need to lower SSBOs to globals regardless. Rather than do this in our
backend like we do now, use the common NIR pass, which will support
bounds checking.

Signed-off-by: Alyssa Rosenzweig <alyssa.rosenzweig at collabora.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/merge_requests/3775>

---

 src/panfrost/midgard/midgard_compile.c | 90 ++++++++++------------------------
 1 file changed, 26 insertions(+), 64 deletions(-)

diff --git a/src/panfrost/midgard/midgard_compile.c b/src/panfrost/midgard/midgard_compile.c
index 8aa54bfb0a2..8f1911d22ef 100644
--- a/src/panfrost/midgard/midgard_compile.c
+++ b/src/panfrost/midgard/midgard_compile.c
@@ -295,14 +295,11 @@ midgard_nir_lower_fdot2_body(nir_builder *b, nir_alu_instr *alu)
         nir_ssa_def_rewrite_uses(&alu->dest.dest.ssa, nir_src_for_ssa(sum));
 }
 
+/* TODO: ssbo_size */
 static int
 midgard_sysval_for_ssbo(nir_intrinsic_instr *instr)
 {
-        /* This is way too meta */
-        bool is_store = instr->intrinsic == nir_intrinsic_store_ssbo;
-        unsigned idx_idx = is_store ? 1 : 0;
-
-        nir_src index = instr->src[idx_idx];
+        nir_src index = instr->src[0];
         assert(nir_src_is_const(index));
         uint32_t uindex = nir_src_as_uint(index);
 
@@ -320,7 +317,7 @@ midgard_sysval_for_sampler(nir_intrinsic_instr *instr)
         return PAN_SYSVAL(SAMPLER, uindex);
 }
 
-static int
+static unsigned
 midgard_nir_sysval_for_intrinsic(nir_intrinsic_instr *instr)
 {
         switch (instr->intrinsic) {
@@ -330,8 +327,7 @@ midgard_nir_sysval_for_intrinsic(nir_intrinsic_instr *instr)
                 return PAN_SYSVAL_VIEWPORT_OFFSET;
         case nir_intrinsic_load_num_work_groups:
                 return PAN_SYSVAL_NUM_WORK_GROUPS;
-        case nir_intrinsic_load_ssbo: 
-        case nir_intrinsic_store_ssbo: 
+        case nir_intrinsic_load_ssbo_address: 
                 return midgard_sysval_for_ssbo(instr);
         case nir_intrinsic_load_sampler_lod_parameters_pan:
                 return midgard_sysval_for_sampler(instr);
@@ -346,16 +342,13 @@ static int sysval_for_instr(compiler_context *ctx, nir_instr *instr,
         nir_intrinsic_instr *intr;
         nir_dest *dst = NULL;
         nir_tex_instr *tex;
-        int sysval = -1;
-
-        bool is_store = false;
+        unsigned sysval = ~0;
 
         switch (instr->type) {
         case nir_instr_type_intrinsic:
                 intr = nir_instr_as_intrinsic(instr);
                 sysval = midgard_nir_sysval_for_intrinsic(intr);
                 dst = &intr->dest;
-                is_store |= intr->intrinsic == nir_intrinsic_store_ssbo;
                 break;
         case nir_instr_type_tex:
                 tex = nir_instr_as_tex(instr);
@@ -373,7 +366,7 @@ static int sysval_for_instr(compiler_context *ctx, nir_instr *instr,
                 break;
         }
 
-        if (dest && dst && !is_store)
+        if (dest && dst)
                 *dest = nir_dest_index(ctx, dst);
 
         return sysval;
@@ -1265,29 +1258,21 @@ emit_ubo_read(
 /* SSBO reads are like UBO reads if you squint */
 
 static void
-emit_ssbo_access(
+emit_global(
         compiler_context *ctx,
         nir_instr *instr,
         bool is_read,
         unsigned srcdest,
-        unsigned offset,
-        nir_src *indirect_offset,
-        unsigned index)
+        nir_src *indirect_offset)
 {
         /* TODO: types */
 
         midgard_instruction ins; 
 
         if (is_read)
-                ins = m_ld_int4(srcdest, offset);
+                ins = m_ld_int4(srcdest, 0);
         else
-                ins = m_st_int4(srcdest, offset);
-
-        /* SSBO reads use a generic memory read interface, so we need the
-         * address of the SSBO as the first argument. This is a sysval. */
-
-        unsigned addr = make_compiler_temp(ctx);
-        emit_sysval_read(ctx, instr, addr, 2);
+                ins = m_st_int4(srcdest, 0);
 
         /* The source array:
          *
@@ -1299,25 +1284,9 @@ emit_ssbo_access(
          * arg_2 = the offset.
          */
 
-        ins.src[1] = addr;
-
-        /* TODO: What is this? It looks superficially like a shift << 5, but
-         * arg_1 doesn't take a shift Should it be E0 or A0? We also need the
-         * indirect offset. */
-
-        if (indirect_offset) {
-                ins.load_store.arg_1 |= 0xE0;
-                ins.src[2] = nir_src_index(ctx, indirect_offset);
-        } else {
-                ins.load_store.arg_2 = 0x7E;
-        }
-
-        /* TODO: Bounds check */
-
-        /* Finally, we emit the direct offset */
-
-        ins.load_store.varying_parameters = (offset & 0x1FF) << 1;
-        ins.load_store.address = (offset >> 9);
+        /* TODO: What is this? */
+        ins.load_store.arg_1 = 0x7E;
+        ins.src[2] = nir_src_index(ctx, indirect_offset);
         mir_set_intr_mask(instr, &ins, is_read);
 
         emit_mir_instruction(ctx, ins);
@@ -1558,25 +1527,25 @@ emit_intrinsic(compiler_context *ctx, nir_intrinsic_instr *instr)
 
         case nir_intrinsic_load_uniform:
         case nir_intrinsic_load_ubo:
-        case nir_intrinsic_load_ssbo:
+        case nir_intrinsic_load_global:
         case nir_intrinsic_load_input:
         case nir_intrinsic_load_interpolated_input: {
                 bool is_uniform = instr->intrinsic == nir_intrinsic_load_uniform;
                 bool is_ubo = instr->intrinsic == nir_intrinsic_load_ubo;
-                bool is_ssbo = instr->intrinsic == nir_intrinsic_load_ssbo;
+                bool is_global = instr->intrinsic == nir_intrinsic_load_global;
                 bool is_flat = instr->intrinsic == nir_intrinsic_load_input;
                 bool is_interp = instr->intrinsic == nir_intrinsic_load_interpolated_input;
 
                 /* Get the base type of the intrinsic */
                 /* TODO: Infer type? Does it matter? */
                 nir_alu_type t =
-                        (is_ubo || is_ssbo) ? nir_type_uint :
+                        (is_ubo || is_global) ? nir_type_uint :
                         (is_interp) ? nir_type_float :
                         nir_intrinsic_type(instr);
 
                 t = nir_alu_type_get_base_type(t);
 
-                if (!(is_ubo || is_ssbo)) {
+                if (!(is_ubo || is_global)) {
                         offset = nir_intrinsic_base(instr);
                 }
 
@@ -1605,12 +1574,8 @@ emit_intrinsic(compiler_context *ctx, nir_intrinsic_instr *instr)
 
                         uint32_t uindex = nir_src_as_uint(index) + 1;
                         emit_ubo_read(ctx, &instr->instr, reg, offset, indirect_offset, 0, uindex);
-                } else if (is_ssbo) {
-                        nir_src index = instr->src[0];
-                        assert(nir_src_is_const(index));
-                        uint32_t uindex = nir_src_as_uint(index);
-
-                        emit_ssbo_access(ctx, &instr->instr, true, reg, offset, indirect_offset, uindex);
+                } else if (is_global) {
+                        emit_global(ctx, &instr->instr, true, reg, indirect_offset);
                 } else if (ctx->stage == MESA_SHADER_FRAGMENT && !ctx->is_blend) {
                         emit_varying_read(ctx, reg, offset, nr_comp, component, indirect_offset, t, is_flat);
                 } else if (ctx->is_blend) {
@@ -1802,20 +1767,16 @@ emit_intrinsic(compiler_context *ctx, nir_intrinsic_instr *instr)
 
                 break;
 
-        case nir_intrinsic_store_ssbo:
-                assert(nir_src_is_const(instr->src[1]));
-
-                bool direct_offset = nir_src_is_const(instr->src[2]);
-                offset = direct_offset ? nir_src_as_uint(instr->src[2]) : 0;
-                nir_src *indirect_offset = direct_offset ? NULL : &instr->src[2];
+        case nir_intrinsic_store_global:
                 reg = nir_src_index(ctx, &instr->src[0]);
-
-                uint32_t uindex = nir_src_as_uint(instr->src[1]);
-
                 emit_explicit_constant(ctx, reg, reg);
-                emit_ssbo_access(ctx, &instr->instr, false, reg, offset, indirect_offset, uindex);
+                emit_global(ctx, &instr->instr, false, reg, &instr->src[1]);
                 break;
 
+        case nir_intrinsic_load_ssbo_address:
+                emit_sysval_read(ctx, &instr->instr, ~0, 1);
+                break;
+ 
         case nir_intrinsic_load_viewport_scale:
         case nir_intrinsic_load_viewport_offset:
         case nir_intrinsic_load_num_work_groups:
@@ -2856,6 +2817,7 @@ midgard_compile_shader_nir(nir_shader *nir, midgard_program *program, bool is_bl
         NIR_PASS_V(nir, nir_lower_vars_to_ssa);
 
         NIR_PASS_V(nir, nir_lower_io, nir_var_all, glsl_type_size, 0);
+        NIR_PASS_V(nir, nir_lower_ssbo);
         NIR_PASS_V(nir, midgard_nir_lower_zs_store);
 
         /* Optimisation passes */



More information about the mesa-commit mailing list