summaryrefslogtreecommitdiffstats
path: root/src/glsl/nir
diff options
context:
space:
mode:
authorIago Toral Quiroga <[email protected]>2015-07-09 10:26:42 +0200
committerSamuel Iglesias Gonsalvez <[email protected]>2015-09-25 08:39:22 +0200
commit9bb7d9ecf881a10f198fba2c52ffb8bf3d557d6a (patch)
tree3a6a291d49dcf617710a0ee77486580dbf16fc5e /src/glsl/nir
parentf17c6b90660f4e156e76f4fa333af86cda2a0125 (diff)
nir: Implement __intrinsic_store_ssbo
v2 (Connor): - Make the STORE() macro take arguments for the extra sources (and their size) and any extra indices required. Reviewed-by: Kristian Høgsberg <[email protected]>
Diffstat (limited to 'src/glsl/nir')
-rw-r--r--src/glsl/nir/glsl_to_nir.cpp36
-rw-r--r--src/glsl/nir/nir_intrinsics.h20
2 files changed, 48 insertions, 8 deletions
diff --git a/src/glsl/nir/glsl_to_nir.cpp b/src/glsl/nir/glsl_to_nir.cpp
index d114da49272..add6b6261b4 100644
--- a/src/glsl/nir/glsl_to_nir.cpp
+++ b/src/glsl/nir/glsl_to_nir.cpp
@@ -649,6 +649,8 @@ nir_visitor::visit(ir_call *ir)
op = nir_intrinsic_image_size;
} else if (strcmp(ir->callee_name(), "__intrinsic_image_samples") == 0) {
op = nir_intrinsic_image_samples;
+ } else if (strcmp(ir->callee_name(), "__intrinsic_store_ssbo") == 0) {
+ op = nir_intrinsic_store_ssbo;
} else {
unreachable("not reached");
}
@@ -747,6 +749,40 @@ nir_visitor::visit(ir_call *ir)
}
case nir_intrinsic_memory_barrier:
break;
+ case nir_intrinsic_store_ssbo: {
+ exec_node *param = ir->actual_parameters.get_head();
+ ir_rvalue *block = ((ir_instruction *)param)->as_rvalue();
+
+ param = param->get_next();
+ ir_rvalue *offset = ((ir_instruction *)param)->as_rvalue();
+
+ param = param->get_next();
+ ir_rvalue *val = ((ir_instruction *)param)->as_rvalue();
+
+ param = param->get_next();
+ ir_constant *write_mask = ((ir_instruction *)param)->as_constant();
+ assert(write_mask);
+
+ /* Check if we need the indirect version */
+ ir_constant *const_offset = offset->as_constant();
+ if (!const_offset) {
+ op = nir_intrinsic_store_ssbo_indirect;
+ ralloc_free(instr);
+ instr = nir_intrinsic_instr_create(shader, op);
+ instr->src[2] = evaluate_rvalue(offset);
+ instr->const_index[0] = 0;
+ } else {
+ instr->const_index[0] = const_offset->value.u[0];
+ }
+
+ instr->const_index[1] = write_mask->value.u[0];
+
+ instr->src[0] = evaluate_rvalue(val);
+ instr->num_components = val->type->vector_elements;
+
+ instr->src[1] = evaluate_rvalue(block);
+ break;
+ }
default:
unreachable("not reached");
}
diff --git a/src/glsl/nir/nir_intrinsics.h b/src/glsl/nir/nir_intrinsics.h
index 271dc42d984..d0dd7b9ee60 100644
--- a/src/glsl/nir/nir_intrinsics.h
+++ b/src/glsl/nir/nir_intrinsics.h
@@ -205,15 +205,19 @@ LOAD(input, 0, 1, NIR_INTRINSIC_CAN_ELIMINATE | NIR_INTRINSIC_CAN_REORDER)
/*
* Stores work the same way as loads, except now the first register input is
* the value or array to store and the optional second input is the indirect
- * offset.
+ * offset. SSBO stores are similar, but they accept an extra source for the
+ * block index and an extra index with the writemask to use.
*/
-#define STORE(name, num_indices, flags) \
- INTRINSIC(store_##name, 1, ARR(0), false, 0, 0, num_indices, flags) \
- INTRINSIC(store_##name##_indirect, 2, ARR(0, 1), false, 0, 0, \
- num_indices, flags) \
+#define STORE(name, extra_srcs, extra_srcs_size, extra_indices, flags) \
+ INTRINSIC(store_##name, 1 + extra_srcs, \
+ ARR(0, extra_srcs_size, extra_srcs_size, extra_srcs_size), \
+ false, 0, 0, 1 + extra_indices, flags) \
+ INTRINSIC(store_##name##_indirect, 2 + extra_srcs, \
+ ARR(0, 1, extra_srcs_size, extra_srcs_size), \
+ false, 0, 0, 1 + extra_indices, flags)
-STORE(output, 1, 0)
-/* STORE(ssbo, 2, 0) */
+STORE(output, 0, 0, 0, 0)
+STORE(ssbo, 1, 1, 1, 0)
-LAST_INTRINSIC(store_output_indirect)
+LAST_INTRINSIC(store_ssbo_indirect)