[Mesa-dev] [PATCH 7/9] panfrost/midgard: Implement UBO reads

Alyssa Rosenzweig alyssa.rosenzweig at collabora.com
Fri Jun 21 22:20:59 UTC 2019


UBOs and uniforms now use a common code path with an explicit `index`
argument passed, enabling UBO reads.

Signed-off-by: Alyssa Rosenzweig <alyssa.rosenzweig at collabora.com>
---
 .../panfrost/midgard/midgard_compile.c        | 65 +++++++++++++++----
 1 file changed, 51 insertions(+), 14 deletions(-)

diff --git a/src/gallium/drivers/panfrost/midgard/midgard_compile.c b/src/gallium/drivers/panfrost/midgard/midgard_compile.c
index baf637d666a..938872cc09e 100644
--- a/src/gallium/drivers/panfrost/midgard/midgard_compile.c
+++ b/src/gallium/drivers/panfrost/midgard/midgard_compile.c
@@ -1069,12 +1069,20 @@ emit_alu(compiler_context *ctx, nir_alu_instr *instr)
 
 #undef ALU_CASE
 
+/* Uniforms and UBOs use a shared code path, as uniforms are just (slightly
+ * optimized) versions of UBO #0 */
+
 static void
-emit_uniform_read(compiler_context *ctx, unsigned dest, unsigned offset, nir_src *indirect_offset)
+emit_ubo_read(
+                compiler_context *ctx,
+                unsigned dest,
+                unsigned offset,
+                nir_src *indirect_offset,
+                unsigned index)
 {
         /* TODO: half-floats */
 
-        if (!indirect_offset && offset < ctx->uniform_cutoff) {
+        if (!indirect_offset && offset < ctx->uniform_cutoff && index == 0) {
                 /* Fast path: For the first 16 uniforms, direct accesses are
                  * 0-cycle, since they're just a register fetch in the usual
                  * case.  So, we alias the registers while we're still in
@@ -1095,11 +1103,13 @@ emit_uniform_read(compiler_context *ctx, unsigned dest, unsigned offset, nir_src
 
                 if (indirect_offset) {
                         emit_indirect_offset(ctx, indirect_offset);
-                        ins.load_store.unknown = 0x8700; /* xxx: what is this? */
+                        ins.load_store.unknown = 0x8700 | index; /* xxx: what is this? */
                 } else {
-                        ins.load_store.unknown = 0x1E00; /* xxx: what is this? */
+                        ins.load_store.unknown = 0x1E00 | index; /* xxx: what is this? */
                 }
 
+                /* TODO respect index */
+
                 emit_mir_instruction(ctx, ins);
         }
 }
@@ -1152,7 +1162,7 @@ emit_sysval_read(compiler_context *ctx, nir_instr *instr)
         unsigned uniform = ((uintptr_t) val) - 1;
 
         /* Emit the read itself -- this is never indirect */
-        emit_uniform_read(ctx, dest, uniform, NULL);
+        emit_ubo_read(ctx, dest, uniform, NULL, 0);
 }
 
 /* Reads RGBA8888 value from the tilebuffer and converts to a RGBA32F register,
@@ -1231,7 +1241,7 @@ emit_fb_read_blend_scalar(compiler_context *ctx, unsigned reg)
 static void
 emit_intrinsic(compiler_context *ctx, nir_intrinsic_instr *instr)
 {
-        unsigned offset, reg;
+        unsigned offset = 0, reg;
 
         switch (instr->intrinsic) {
         case nir_intrinsic_discard_if:
@@ -1250,23 +1260,49 @@ emit_intrinsic(compiler_context *ctx, nir_intrinsic_instr *instr)
         }
 
         case nir_intrinsic_load_uniform:
-        case nir_intrinsic_load_input:
-                offset = nir_intrinsic_base(instr);
+        case nir_intrinsic_load_ubo:
+        case nir_intrinsic_load_input: {
+                bool is_uniform = instr->intrinsic == nir_intrinsic_load_uniform;
+                bool is_ubo = instr->intrinsic == nir_intrinsic_load_ubo;
+
+                if (!is_ubo) {
+                        offset = nir_intrinsic_base(instr);
+                }
 
                 unsigned nr_comp = nir_intrinsic_dest_components(instr);
-                bool direct = nir_src_is_const(instr->src[0]);
 
-                if (direct) {
-                        offset += nir_src_as_uint(instr->src[0]);
-                }
+                nir_src *src_offset = nir_get_io_offset_src(instr);
+
+                bool direct = nir_src_is_const(*src_offset);
+
+                if (direct)
+                        offset += nir_src_as_uint(*src_offset);
 
                 /* We may need to apply a fractional offset */
                 int component = instr->intrinsic == nir_intrinsic_load_input ?
                         nir_intrinsic_component(instr) : 0;
                 reg = nir_dest_index(ctx, &instr->dest);
 
-                if (instr->intrinsic == nir_intrinsic_load_uniform && !ctx->is_blend) {
-                        emit_uniform_read(ctx, reg, ctx->sysval_count + offset, !direct ? &instr->src[0] : NULL);
+                if (is_uniform && !ctx->is_blend) {
+                        emit_ubo_read(ctx, reg, ctx->sysval_count + offset, !direct ? &instr->src[0] : NULL, 0);
+                } else if (is_ubo) {
+                        nir_src index = instr->src[0];
+
+                        /* We don't yet support indirect UBOs. For indirect
+                         * block numbers (if that's possible), we don't know
+                         * enough about the hardware yet. For indirect sources,
+                         * we know what we need but we need to add some NIR
+                         * support for lowering correctly with respect to
+                         * 128-bit reads */
+
+                        assert(nir_src_is_const(index));
+                        assert(nir_src_is_const(*src_offset));
+
+                        /* TODO: Alignment */
+                        assert((offset & 0xF) == 0);
+
+                        uint32_t uindex = nir_src_as_uint(index) + 1;
+                        emit_ubo_read(ctx, reg, offset / 16, NULL, uindex);
                 } else if (ctx->stage == MESA_SHADER_FRAGMENT && !ctx->is_blend) {
                         emit_varying_read(ctx, reg, offset, nr_comp, component, !direct ? &instr->src[0] : NULL);
                 } else if (ctx->is_blend) {
@@ -1286,6 +1322,7 @@ emit_intrinsic(compiler_context *ctx, nir_intrinsic_instr *instr)
                 }
 
                 break;
+       }
 
         case nir_intrinsic_load_output:
                 assert(nir_src_is_const(instr->src[0]));
-- 
2.20.1



More information about the mesa-dev mailing list