summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlyssa Rosenzweig <[email protected]>2020-03-10 16:20:18 -0400
committerMarge Bot <[email protected]>2020-03-11 20:28:20 +0000
commit218785c4a95319145b194db4ca9fe9fbc0713461 (patch)
tree3f4be3aa532b6d24ee42efb454d52d61b7911f2c
parente6f5ae88a7ff758bc9a506488f7930d53b68ab19 (diff)
pan/bi: Implement sysvals
Now that it's all abstracted nicely with an implementation shared with Midgard, this is pretty easy to get. Signed-off-by: Alyssa Rosenzweig <[email protected]> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/4150>
-rw-r--r--src/panfrost/bifrost/bifrost_compile.c55
-rw-r--r--src/panfrost/bifrost/compiler.h1
2 files changed, 56 insertions, 0 deletions
diff --git a/src/panfrost/bifrost/bifrost_compile.c b/src/panfrost/bifrost/bifrost_compile.c
index 39ae2a62748..46f9aea5496 100644
--- a/src/panfrost/bifrost/bifrost_compile.c
+++ b/src/panfrost/bifrost/bifrost_compile.c
@@ -163,10 +163,46 @@ bi_emit_ld_uniform(bi_context *ctx, nir_intrinsic_instr *instr)
{
bi_instruction ld = bi_load(BI_LOAD_UNIFORM, instr);
ld.src[1] = BIR_INDEX_ZERO; /* TODO: UBO index */
+
+ /* TODO: Indirect access, since we need to multiply by the element
+ * size. I believe we can get this lowering automatically via
+ * nir_lower_io (as mul instructions) with the proper options, but this
+ * is TODO */
+ assert(ld.src[0] & BIR_INDEX_CONSTANT);
+ ld.constant.u64 += ctx->sysvals.sysval_count;
+ ld.constant.u64 *= 16;
+
bi_emit(ctx, ld);
}
static void
+bi_emit_sysval(bi_context *ctx, nir_instr *instr,
+ unsigned nr_components, unsigned offset)
+{
+ nir_dest nir_dest;
+
+ /* Figure out which uniform this is */
+ int sysval = panfrost_sysval_for_instr(instr, &nir_dest);
+ void *val = _mesa_hash_table_u64_search(ctx->sysvals.sysval_to_id, sysval);
+
+ /* Sysvals are prefix uniforms */
+ unsigned uniform = ((uintptr_t) val) - 1;
+
+ /* Emit the read itself -- this is never indirect */
+
+ bi_instruction load = {
+ .type = BI_LOAD_UNIFORM,
+ .writemask = (1 << (nr_components * 4)) - 1,
+ .src = { BIR_INDEX_CONSTANT},
+ .constant = { (uniform * 16) + offset },
+ .dest = bir_dest_index(&nir_dest),
+ .dest_type = nir_type_uint32, /* TODO */
+ };
+
+ bi_emit(ctx, load);
+}
+
+static void
emit_intrinsic(bi_context *ctx, nir_intrinsic_instr *instr)
{
@@ -198,6 +234,21 @@ emit_intrinsic(bi_context *ctx, nir_intrinsic_instr *instr)
bi_emit_ld_uniform(ctx, instr);
break;
+ case nir_intrinsic_load_ssbo_address:
+ bi_emit_sysval(ctx, &instr->instr, 1, 0);
+ break;
+
+ case nir_intrinsic_get_buffer_size:
+ bi_emit_sysval(ctx, &instr->instr, 1, 8);
+ break;
+
+ case nir_intrinsic_load_viewport_scale:
+ case nir_intrinsic_load_viewport_offset:
+ case nir_intrinsic_load_num_work_groups:
+ case nir_intrinsic_load_sampler_lod_parameters_pan:
+ bi_emit_sysval(ctx, &instr->instr, 3, 0);
+ break;
+
default:
/* todo */
break;
@@ -800,6 +851,10 @@ bifrost_compile_shader_nir(nir_shader *nir, panfrost_program *program, unsigned
bi_optimize_nir(nir);
nir_print_shader(nir, stdout);
+ panfrost_nir_assign_sysvals(&ctx->sysvals, nir);
+ program->sysval_count = ctx->sysvals.sysval_count;
+ memcpy(program->sysvals, ctx->sysvals.sysvals, sizeof(ctx->sysvals.sysvals[0]) * ctx->sysvals.sysval_count);
+
nir_foreach_function(func, nir) {
if (!func->impl)
continue;
diff --git a/src/panfrost/bifrost/compiler.h b/src/panfrost/bifrost/compiler.h
index cd0408b6119..49ecb19302b 100644
--- a/src/panfrost/bifrost/compiler.h
+++ b/src/panfrost/bifrost/compiler.h
@@ -325,6 +325,7 @@ typedef struct {
nir_shader *nir;
gl_shader_stage stage;
struct list_head blocks; /* list of bi_block */
+ struct panfrost_sysvals sysvals;
uint32_t quirks;
/* During NIR->BIR */