summaryrefslogtreecommitdiffstats
path: root/src/panfrost/midgard
diff options
context:
space:
mode:
authorAlyssa Rosenzweig <[email protected]>2019-11-05 08:59:49 -0500
committerMarge Bot <[email protected]>2020-02-24 13:56:59 +0000
commit3148937ef7c7be7a0685de333de6a5ed31ce3857 (patch)
treeb098ea4284ec8e9f18afae39c3c0abd334a6bbe4 /src/panfrost/midgard
parent99f2b6144b5c3c4f48096ed0de4b15d1d13afd96 (diff)
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 <[email protected]> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/merge_requests/3775>
Diffstat (limited to 'src/panfrost/midgard')
-rw-r--r--src/panfrost/midgard/midgard_compile.c90
1 files 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 */