summaryrefslogtreecommitdiffstats
path: root/src/gallium/drivers/vc4/vc4_program.c
diff options
context:
space:
mode:
authorEric Anholt <[email protected]>2015-10-20 10:49:10 +0100
committerEric Anholt <[email protected]>2015-10-20 12:47:27 +0100
commit85b946478c326df853926ed18bfbd898c0a514ef (patch)
tree6eaf090d81cadebaf1ee99b01155473e3221caa9 /src/gallium/drivers/vc4/vc4_program.c
parent8910ebd8e8ed7e163ae69bb85cda55531675e95d (diff)
vc4: Add limited support for ibfe/ubfe.
This is just enough to cover our unpack modes, which will be used by some new NIR-based lowering in the next commit.
Diffstat (limited to 'src/gallium/drivers/vc4/vc4_program.c')
-rw-r--r--src/gallium/drivers/vc4/vc4_program.c42
1 files changed, 42 insertions, 0 deletions
diff --git a/src/gallium/drivers/vc4/vc4_program.c b/src/gallium/drivers/vc4/vc4_program.c
index 1b590a2d0c4..d3e856a8530 100644
--- a/src/gallium/drivers/vc4/vc4_program.c
+++ b/src/gallium/drivers/vc4/vc4_program.c
@@ -876,6 +876,40 @@ ntq_emit_pack_unorm_4x8(struct vc4_compile *c, nir_alu_instr *instr)
*dest = result;
}
+/** Handles sign-extended bitfield extracts for 16 bits. */
+static struct qreg
+ntq_emit_ibfe(struct vc4_compile *c, struct qreg base, struct qreg offset,
+ struct qreg bits)
+{
+ assert(bits.file == QFILE_UNIF &&
+ c->uniform_contents[bits.index] == QUNIFORM_CONSTANT &&
+ c->uniform_data[bits.index] == 16);
+
+ assert(offset.file == QFILE_UNIF &&
+ c->uniform_contents[offset.index] == QUNIFORM_CONSTANT);
+ int offset_bit = c->uniform_data[offset.index];
+ assert(offset_bit % 16 == 0);
+
+ return qir_UNPACK_16_I(c, base, offset_bit / 16);
+}
+
+/** Handles unsigned bitfield extracts for 8 bits. */
+static struct qreg
+ntq_emit_ubfe(struct vc4_compile *c, struct qreg base, struct qreg offset,
+ struct qreg bits)
+{
+ assert(bits.file == QFILE_UNIF &&
+ c->uniform_contents[bits.index] == QUNIFORM_CONSTANT &&
+ c->uniform_data[bits.index] == 8);
+
+ assert(offset.file == QFILE_UNIF &&
+ c->uniform_contents[offset.index] == QUNIFORM_CONSTANT);
+ int offset_bit = c->uniform_data[offset.index];
+ assert(offset_bit % 8 == 0);
+
+ return qir_UNPACK_8_I(c, base, offset_bit / 8);
+}
+
static void
ntq_emit_alu(struct vc4_compile *c, nir_alu_instr *instr)
{
@@ -1106,6 +1140,14 @@ ntq_emit_alu(struct vc4_compile *c, nir_alu_instr *instr)
qir_SUB(c, qir_uniform_ui(c, 0), src[0]));
break;
+ case nir_op_ibitfield_extract:
+ *dest = ntq_emit_ibfe(c, src[0], src[1], src[2]);
+ break;
+
+ case nir_op_ubitfield_extract:
+ *dest = ntq_emit_ubfe(c, src[0], src[1], src[2]);
+ break;
+
default:
fprintf(stderr, "unknown NIR ALU inst: ");
nir_print_instr(&instr->instr, stderr);