summaryrefslogtreecommitdiffstats
path: root/src/gallium/drivers/vc4/vc4_program.c
diff options
context:
space:
mode:
authorEric Anholt <eric@anholt.net>2016-08-25 12:32:19 -0700
committerEric Anholt <eric@anholt.net>2016-08-25 17:24:11 -0700
commit00c72acba5a98965622000d949b6835f28a9d71a (patch)
treeffea5c75087b4df9309789ba0f3e90a2a10d64bc /src/gallium/drivers/vc4/vc4_program.c
parente763e19808a84ae0218117c89864ff50cb6b0d16 (diff)
downloadexternal_mesa3d-00c72acba5a98965622000d949b6835f28a9d71a.zip
external_mesa3d-00c72acba5a98965622000d949b6835f28a9d71a.tar.gz
external_mesa3d-00c72acba5a98965622000d949b6835f28a9d71a.tar.bz2
vc4: Add support for fddx/fddy
Based vaguely on a patch by jonasarrow on github.
Diffstat (limited to 'src/gallium/drivers/vc4/vc4_program.c')
-rw-r--r--src/gallium/drivers/vc4/vc4_program.c52
1 files changed, 52 insertions, 0 deletions
diff --git a/src/gallium/drivers/vc4/vc4_program.c b/src/gallium/drivers/vc4/vc4_program.c
index dd8c421..19bb8a3 100644
--- a/src/gallium/drivers/vc4/vc4_program.c
+++ b/src/gallium/drivers/vc4/vc4_program.c
@@ -932,6 +932,46 @@ out:
return qir_SEL(c, QPU_COND_NS, src[1], src[2]);
}
+static struct qreg
+ntq_fddx(struct vc4_compile *c, struct qreg src)
+{
+ /* Make sure that we have a bare temp to use for MUL rotation, so it
+ * can be allocated to an accumulator.
+ */
+ if (src.pack || src.file != QFILE_TEMP)
+ src = qir_MOV(c, src);
+
+ struct qreg from_left = qir_ROT_MUL(c, src, 1);
+ struct qreg from_right = qir_ROT_MUL(c, src, 15);
+
+ /* Distinguish left/right pixels of the quad. */
+ qir_SF(c, qir_AND(c, qir_reg(QFILE_QPU_ELEMENT, 0),
+ qir_uniform_ui(c, 1)));
+
+ return qir_SEL(c, QPU_COND_ZS,
+ qir_FSUB(c, from_right, src),
+ qir_FSUB(c, src, from_left));
+}
+
+static struct qreg
+ntq_fddy(struct vc4_compile *c, struct qreg src)
+{
+ if (src.pack || src.file != QFILE_TEMP)
+ src = qir_MOV(c, src);
+
+ struct qreg from_bottom = qir_ROT_MUL(c, src, 2);
+ struct qreg from_top = qir_ROT_MUL(c, src, 14);
+
+ /* Distinguish top/bottom pixels of the quad. */
+ qir_SF(c, qir_AND(c,
+ qir_reg(QFILE_QPU_ELEMENT, 0),
+ qir_uniform_ui(c, 2)));
+
+ return qir_SEL(c, QPU_COND_ZS,
+ qir_FSUB(c, from_top, src),
+ qir_FSUB(c, src, from_bottom));
+}
+
static void
ntq_emit_alu(struct vc4_compile *c, nir_alu_instr *instr)
{
@@ -1158,6 +1198,18 @@ ntq_emit_alu(struct vc4_compile *c, nir_alu_instr *instr)
result = qir_V8MULD(c, src[0], src[1]);
break;
+ case nir_op_fddx:
+ case nir_op_fddx_coarse:
+ case nir_op_fddx_fine:
+ result = ntq_fddx(c, src[0]);
+ break;
+
+ case nir_op_fddy:
+ case nir_op_fddy_coarse:
+ case nir_op_fddy_fine:
+ result = ntq_fddy(c, src[0]);
+ break;
+
default:
fprintf(stderr, "unknown NIR ALU inst: ");
nir_print_instr(&instr->instr, stderr);