[Mesa-dev] [PATCH 07/11] ttn: add buffer support
Ilia Mirkin
imirkin at alum.mit.edu
Sat Sep 26 23:33:23 PDT 2015
This adds preliminary support for dealing with buffers. There are a few
deficiencies, but nothing that should prevent atomic counters and ssbo
buffers from working. This converts to using ssbo intrinsics.
Signed-off-by: Ilia Mirkin <imirkin at alum.mit.edu>
---
src/gallium/auxiliary/nir/tgsi_to_nir.c | 118 +++++++++++++++++++++++++++++++-
1 file changed, 117 insertions(+), 1 deletion(-)
diff --git a/src/gallium/auxiliary/nir/tgsi_to_nir.c b/src/gallium/auxiliary/nir/tgsi_to_nir.c
index 9cfb62a..da84454 100644
--- a/src/gallium/auxiliary/nir/tgsi_to_nir.c
+++ b/src/gallium/auxiliary/nir/tgsi_to_nir.c
@@ -280,6 +280,8 @@ ttn_emit_declaration(struct ttn_compile *c)
c->addr_reg->num_components = 4;
} else if (file == TGSI_FILE_SYSTEM_VALUE) {
/* Nothing to record for system values. */
+ } else if (file == TGSI_FILE_BUFFER) {
+ /* Nothing to record for buffers. */
} else if (file == TGSI_FILE_SAMPLER) {
/* Nothing to record for samplers. */
} else if (file == TGSI_FILE_SAMPLER_VIEW) {
@@ -763,7 +765,8 @@ ttn_get_src(struct ttn_compile *c, struct tgsi_full_src_register *tgsi_fsrc)
if (tgsi_src->File == TGSI_FILE_NULL) {
return nir_imm_float(b, 0.0);
- } else if (tgsi_src->File == TGSI_FILE_SAMPLER) {
+ } else if (tgsi_src->File == TGSI_FILE_SAMPLER ||
+ tgsi_src->File == TGSI_FILE_BUFFER) {
/* Only the index of the sampler gets used in texturing, and it will
* handle looking that up on its own instead of using the nir_alu_src.
*/
@@ -1483,6 +1486,100 @@ ttn_txq(struct ttn_compile *c, nir_alu_dest dest, nir_ssa_def **src)
ttn_move_dest_masked(b, dest, &qlv->dest.ssa, TGSI_WRITEMASK_W);
}
+static void
+ttn_buffer(struct ttn_compile *c, nir_alu_dest dest, nir_ssa_def **src)
+{
+ nir_builder *b = &c->build;
+ struct tgsi_full_instruction *tgsi_inst = &c->token->FullInstruction;
+ nir_intrinsic_instr *instr;
+ nir_intrinsic_op op;
+ bool buf_offset_const = false;
+
+ switch (tgsi_inst->Instruction.Opcode) {
+ case TGSI_OPCODE_LOAD:
+ op = nir_intrinsic_load_ssbo;
+ /* TODO: figure out how to extract the immediate */
+ if (1 || tgsi_inst->Src[1].Register.File != TGSI_FILE_IMMEDIATE)
+ op = nir_intrinsic_load_ssbo_indirect;
+ else
+ buf_offset_const = true;
+ break;
+ case TGSI_OPCODE_STORE:
+ op = nir_intrinsic_store_ssbo;
+ /* TODO: figure out how to extract the immediate */
+ if (1 || tgsi_inst->Src[1].Register.File != TGSI_FILE_IMMEDIATE)
+ op = nir_intrinsic_store_ssbo_indirect;
+ else
+ buf_offset_const = true;
+ break;
+ case TGSI_OPCODE_ATOMUADD:
+ op = nir_intrinsic_ssbo_atomic_add;
+ break;
+ case TGSI_OPCODE_ATOMXCHG:
+ op = nir_intrinsic_ssbo_atomic_exchange;
+ break;
+ case TGSI_OPCODE_ATOMCAS:
+ op = nir_intrinsic_ssbo_atomic_comp_swap;
+ break;
+ case TGSI_OPCODE_ATOMAND:
+ op = nir_intrinsic_ssbo_atomic_and;
+ break;
+ case TGSI_OPCODE_ATOMOR:
+ op = nir_intrinsic_ssbo_atomic_or;
+ break;
+ case TGSI_OPCODE_ATOMXOR:
+ op = nir_intrinsic_ssbo_atomic_xor;
+ break;
+ case TGSI_OPCODE_ATOMUMIN: /* XXX */
+ case TGSI_OPCODE_ATOMIMIN:
+ op = nir_intrinsic_ssbo_atomic_min;
+ break;
+ case TGSI_OPCODE_ATOMUMAX: /* XXX */
+ case TGSI_OPCODE_ATOMIMAX:
+ op = nir_intrinsic_ssbo_atomic_max;
+ break;
+ default:
+ unreachable("Unexpected buffer opcode");
+ }
+
+ for (unsigned c = 0; c < 4; c++) {
+ if (!(dest.write_mask & (1 << c)))
+ continue;
+
+ instr = nir_intrinsic_instr_create(b->shader, op);
+ instr->src[0] = nir_src_for_ssa(
+ nir_imm_int(b, tgsi_inst->Src[0].Register.Index));
+/* TODO: make this work and adjust conditions above.
+ if (buf_offset_const) {
+ nir_const_value *val = nir_src_as_const_value(
+ nir_src_for_ssa(src[1]));
+ instr->const_index[0] = val->u[c];
+ }
+*/
+ if (tgsi_inst->Instruction.Opcode == TGSI_OPCODE_LOAD) {
+ instr->num_components = 1;
+ if (!buf_offset_const)
+ instr->src[1] = nir_src_for_ssa(nir_channel(b, src[1], c));
+ } else if (tgsi_inst->Instruction.Opcode == TGSI_OPCODE_STORE) {
+ instr->src[1] = instr->src[0];
+ instr->src[0] = nir_src_for_ssa(nir_channel(b, src[2], c));
+ if (!buf_offset_const)
+ instr->src[2] = nir_src_for_ssa(nir_channel(b, src[1], c));
+ } else {
+ instr->num_components = 1;
+ instr->src[1] = nir_src_for_ssa(nir_channel(b, src[1], c));
+ instr->src[2] = nir_src_for_ssa(nir_channel(b, src[2], c));
+ if (op == TGSI_OPCODE_ATOMCAS)
+ instr->src[3] = nir_src_for_ssa(nir_channel(b, src[3], c));
+ }
+
+ nir_ssa_dest_init(&instr->instr, &instr->dest, 1, NULL);
+ nir_builder_instr_insert(b, &instr->instr);
+
+ ttn_move_dest_masked(b, dest, &instr->dest.ssa, 1 << c);
+ }
+}
+
static const nir_op op_trans[TGSI_OPCODE_LAST] = {
[TGSI_OPCODE_ARL] = 0,
[TGSI_OPCODE_MOV] = nir_op_fmov,
@@ -1820,7 +1917,26 @@ ttn_emit_instruction(struct ttn_compile *c)
ttn_txq(c, dest, src);
break;
+ case TGSI_OPCODE_LOAD:
+ case TGSI_OPCODE_STORE:
+ case TGSI_OPCODE_ATOMUADD:
+ case TGSI_OPCODE_ATOMXCHG:
+ case TGSI_OPCODE_ATOMCAS:
+ case TGSI_OPCODE_ATOMAND:
+ case TGSI_OPCODE_ATOMOR:
+ case TGSI_OPCODE_ATOMXOR:
+ case TGSI_OPCODE_ATOMUMIN:
+ case TGSI_OPCODE_ATOMUMAX:
+ case TGSI_OPCODE_ATOMIMIN:
+ case TGSI_OPCODE_ATOMIMAX:
+ ttn_buffer(c, dest, src);
+ break;
+
case TGSI_OPCODE_NOP:
+ /* XXX Make the st not generate these for ir_call intrinsics */
+ case TGSI_OPCODE_BGNSUB:
+ case TGSI_OPCODE_RET:
+ case TGSI_OPCODE_ENDSUB:
break;
case TGSI_OPCODE_IF:
--
2.4.9
More information about the mesa-dev
mailing list