summaryrefslogtreecommitdiffstats
path: root/src/broadcom/compiler/nir_to_vir.c
diff options
context:
space:
mode:
authorEric Anholt <[email protected]>2017-12-11 12:52:27 -0800
committerEric Anholt <[email protected]>2019-01-14 15:40:55 -0800
commit6281f26f064ada36b57d45feb68d8e7d783198c9 (patch)
treed06588f36d6e2d273ae33cd9aaca640b3d027039 /src/broadcom/compiler/nir_to_vir.c
parent5932c2f0b9b56e6eeee87baa7b0b493227850f69 (diff)
v3d: Add support for shader_image_load_store.
This is only exposed on V3D 4.1+, because we didn't have the TMU write operations for images on 3.3 (To do GLES 3.1 there, you have to lower it to SSBO load/stores, which is a problem to solve later).
Diffstat (limited to 'src/broadcom/compiler/nir_to_vir.c')
-rw-r--r--src/broadcom/compiler/nir_to_vir.c48
1 files changed, 48 insertions, 0 deletions
diff --git a/src/broadcom/compiler/nir_to_vir.c b/src/broadcom/compiler/nir_to_vir.c
index b8e39f357f7..f10ed5975c1 100644
--- a/src/broadcom/compiler/nir_to_vir.c
+++ b/src/broadcom/compiler/nir_to_vir.c
@@ -1693,6 +1693,32 @@ ntq_emit_ssa_undef(struct v3d_compile *c, nir_ssa_undef_instr *instr)
}
static void
+ntq_emit_image_size(struct v3d_compile *c, nir_intrinsic_instr *instr)
+{
+ assert(instr->intrinsic == nir_intrinsic_image_deref_size);
+ nir_variable *var = nir_intrinsic_get_var(instr, 0);
+ unsigned image_index = var->data.driver_location;
+ const struct glsl_type *sampler_type = glsl_without_array(var->type);
+ bool is_array = glsl_sampler_type_is_array(sampler_type);
+
+ ntq_store_dest(c, &instr->dest, 0,
+ vir_uniform(c, QUNIFORM_IMAGE_WIDTH, image_index));
+ if (instr->num_components > 1) {
+ ntq_store_dest(c, &instr->dest, 1,
+ vir_uniform(c, QUNIFORM_IMAGE_HEIGHT,
+ image_index));
+ }
+ if (instr->num_components > 2) {
+ ntq_store_dest(c, &instr->dest, 2,
+ vir_uniform(c,
+ is_array ?
+ QUNIFORM_IMAGE_ARRAY_SIZE :
+ QUNIFORM_IMAGE_DEPTH,
+ image_index));
+ }
+}
+
+static void
ntq_emit_intrinsic(struct v3d_compile *c, nir_intrinsic_instr *instr)
{
unsigned offset;
@@ -1734,6 +1760,19 @@ ntq_emit_intrinsic(struct v3d_compile *c, nir_intrinsic_instr *instr)
ntq_emit_tmu_general(c, instr);
break;
+ case nir_intrinsic_image_deref_load:
+ case nir_intrinsic_image_deref_store:
+ case nir_intrinsic_image_deref_atomic_add:
+ case nir_intrinsic_image_deref_atomic_min:
+ case nir_intrinsic_image_deref_atomic_max:
+ case nir_intrinsic_image_deref_atomic_and:
+ case nir_intrinsic_image_deref_atomic_or:
+ case nir_intrinsic_image_deref_atomic_xor:
+ case nir_intrinsic_image_deref_atomic_exchange:
+ case nir_intrinsic_image_deref_atomic_comp_swap:
+ v3d40_vir_emit_image_load_store(c, instr);
+ break;
+
case nir_intrinsic_get_buffer_size:
ntq_store_dest(c, &instr->dest, 0,
vir_uniform(c, QUNIFORM_GET_BUFFER_SIZE,
@@ -1807,6 +1846,10 @@ ntq_emit_intrinsic(struct v3d_compile *c, nir_intrinsic_instr *instr)
offset + instr->num_components);
break;
+ case nir_intrinsic_image_deref_size:
+ ntq_emit_image_size(c, instr);
+ break;
+
case nir_intrinsic_discard:
if (c->execute.file != QFILE_NULL) {
vir_PF(c, c->execute, V3D_QPU_PF_PUSHZ);
@@ -1846,6 +1889,7 @@ ntq_emit_intrinsic(struct v3d_compile *c, nir_intrinsic_instr *instr)
case nir_intrinsic_memory_barrier:
case nir_intrinsic_memory_barrier_atomic_counter:
case nir_intrinsic_memory_barrier_buffer:
+ case nir_intrinsic_memory_barrier_image:
/* We don't do any instruction scheduling of these NIR
* instructions between each other, so we just need to make
* sure that the TMU operations before the barrier are flushed
@@ -2066,6 +2110,10 @@ static void
ntq_emit_instr(struct v3d_compile *c, nir_instr *instr)
{
switch (instr->type) {
+ case nir_instr_type_deref:
+ /* ignored, will be walked by the intrinsic using it. */
+ break;
+
case nir_instr_type_alu:
ntq_emit_alu(c, nir_instr_as_alu(instr));
break;