summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEric Anholt <[email protected]>2014-12-15 11:19:58 -0800
committerEric Anholt <[email protected]>2014-12-15 14:33:00 -0800
commit2142fd1f6f36ef9a384ef298fec02111dc826308 (patch)
treeedb792a5d627d87da3a0638ca7657c4709f1003a
parent214a169b3268bed63785d3e5953b24022f1beccb (diff)
vc4: Add support for 8-bit unnormalized vertex attrs.
-rw-r--r--src/gallium/drivers/vc4/vc4_program.c30
-rw-r--r--src/gallium/drivers/vc4/vc4_qir.c4
-rw-r--r--src/gallium/drivers/vc4/vc4_qir.h13
-rw-r--r--src/gallium/drivers/vc4/vc4_qpu_emit.c21
-rw-r--r--src/gallium/drivers/vc4/vc4_register_allocate.c4
-rw-r--r--src/gallium/drivers/vc4/vc4_screen.c8
6 files changed, 69 insertions, 11 deletions
diff --git a/src/gallium/drivers/vc4/vc4_program.c b/src/gallium/drivers/vc4/vc4_program.c
index fd9cd5e3471..1efdf37097f 100644
--- a/src/gallium/drivers/vc4/vc4_program.c
+++ b/src/gallium/drivers/vc4/vc4_program.c
@@ -1003,20 +1003,28 @@ get_channel_from_vpm(struct vc4_compile *c,
return get_swizzled_channel(c, vpm_reads, swiz);
} else if (chan->size == 8 &&
(chan->type == UTIL_FORMAT_TYPE_UNSIGNED ||
- chan->type == UTIL_FORMAT_TYPE_SIGNED) &&
- chan->normalized) {
+ chan->type == UTIL_FORMAT_TYPE_SIGNED)) {
struct qreg vpm = vpm_reads[0];
- if (chan->type == UTIL_FORMAT_TYPE_SIGNED)
- vpm = qir_XOR(c, vpm, qir_uniform_ui(c, 0x80808080));
- temp = qir_UNPACK_8_F(c, vpm, swiz);
-
if (chan->type == UTIL_FORMAT_TYPE_SIGNED) {
- return qir_FSUB(c, qir_FMUL(c,
- temp,
- qir_uniform_f(c, 2.0)),
- qir_uniform_f(c, 1.0));
+ temp = qir_XOR(c, vpm, qir_uniform_ui(c, 0x80808080));
+ if (chan->normalized) {
+ return qir_FSUB(c, qir_FMUL(c,
+ qir_UNPACK_8_F(c, temp, swiz),
+ qir_uniform_f(c, 2.0)),
+ qir_uniform_f(c, 1.0));
+ } else {
+ return qir_FADD(c,
+ qir_ITOF(c,
+ qir_UNPACK_8_I(c, temp,
+ swiz)),
+ qir_uniform_f(c, -128.0));
+ }
} else {
- return temp;
+ if (chan->normalized) {
+ return qir_UNPACK_8_F(c, vpm, swiz);
+ } else {
+ return qir_ITOF(c, qir_UNPACK_8_I(c, vpm, swiz));
+ }
}
} else {
return c->undef;
diff --git a/src/gallium/drivers/vc4/vc4_qir.c b/src/gallium/drivers/vc4/vc4_qir.c
index e83c03654b0..8cd571d5b77 100644
--- a/src/gallium/drivers/vc4/vc4_qir.c
+++ b/src/gallium/drivers/vc4/vc4_qir.c
@@ -103,6 +103,10 @@ static const struct qir_op_info qir_op_info[] = {
[QOP_UNPACK_8B_F] = { "unpack_8b_f", 1, 1 },
[QOP_UNPACK_8C_F] = { "unpack_8c_f", 1, 1 },
[QOP_UNPACK_8D_F] = { "unpack_8d_f", 1, 1 },
+ [QOP_UNPACK_8A_I] = { "unpack_8a_i", 1, 1 },
+ [QOP_UNPACK_8B_I] = { "unpack_8b_i", 1, 1 },
+ [QOP_UNPACK_8C_I] = { "unpack_8c_i", 1, 1 },
+ [QOP_UNPACK_8D_I] = { "unpack_8d_i", 1, 1 },
};
static const char *
diff --git a/src/gallium/drivers/vc4/vc4_qir.h b/src/gallium/drivers/vc4/vc4_qir.h
index c612b283b90..9da120ab912 100644
--- a/src/gallium/drivers/vc4/vc4_qir.h
+++ b/src/gallium/drivers/vc4/vc4_qir.h
@@ -114,6 +114,11 @@ enum qop {
QOP_UNPACK_8C_F,
QOP_UNPACK_8D_F,
+ QOP_UNPACK_8A_I,
+ QOP_UNPACK_8B_I,
+ QOP_UNPACK_8C_I,
+ QOP_UNPACK_8D_I,
+
/** Texture x coordinate parameter write */
QOP_TEX_S,
/** Texture y coordinate parameter write */
@@ -497,6 +502,14 @@ qir_UNPACK_8_F(struct vc4_compile *c, struct qreg src, int i)
}
static inline struct qreg
+qir_UNPACK_8_I(struct vc4_compile *c, struct qreg src, int i)
+{
+ struct qreg t = qir_get_temp(c);
+ qir_emit(c, qir_inst(QOP_UNPACK_8A_I + i, t, src, c->undef));
+ return t;
+}
+
+static inline struct qreg
qir_POW(struct vc4_compile *c, struct qreg x, struct qreg y)
{
return qir_EXP2(c, qir_FMUL(c,
diff --git a/src/gallium/drivers/vc4/vc4_qpu_emit.c b/src/gallium/drivers/vc4/vc4_qpu_emit.c
index 8b3a0010d33..f8807276660 100644
--- a/src/gallium/drivers/vc4/vc4_qpu_emit.c
+++ b/src/gallium/drivers/vc4/vc4_qpu_emit.c
@@ -490,6 +490,27 @@ vc4_generate_code(struct vc4_context *vc4, struct vc4_compile *c)
}
break;
+ case QOP_UNPACK_8A_I:
+ case QOP_UNPACK_8B_I:
+ case QOP_UNPACK_8C_I:
+ case QOP_UNPACK_8D_I:
+ assert(src[0].mux == QPU_MUX_A);
+
+ /* Since we're setting the pack bits, if the
+ * destination is in A it would get re-packed.
+ */
+ queue(c, qpu_a_MOV((dst.mux == QPU_MUX_A ?
+ qpu_rb(31) : dst), src[0]));
+ *last_inst(c) |= QPU_SET_FIELD(QPU_UNPACK_8A +
+ (qinst->op -
+ QOP_UNPACK_8A_I),
+ QPU_UNPACK);
+
+ if (dst.mux == QPU_MUX_A) {
+ queue(c, qpu_a_MOV(dst, qpu_rb(31)));
+ }
+ break;
+
default:
assert(qinst->op < ARRAY_SIZE(translate));
assert(translate[qinst->op].op != 0); /* NOPs */
diff --git a/src/gallium/drivers/vc4/vc4_register_allocate.c b/src/gallium/drivers/vc4/vc4_register_allocate.c
index f48ce1804d3..8f8c1899071 100644
--- a/src/gallium/drivers/vc4/vc4_register_allocate.c
+++ b/src/gallium/drivers/vc4/vc4_register_allocate.c
@@ -258,6 +258,10 @@ vc4_register_allocate(struct vc4_context *vc4, struct vc4_compile *c)
case QOP_UNPACK_8B_F:
case QOP_UNPACK_8C_F:
case QOP_UNPACK_8D_F:
+ case QOP_UNPACK_8A_I:
+ case QOP_UNPACK_8B_I:
+ case QOP_UNPACK_8C_I:
+ case QOP_UNPACK_8D_I:
/* The unpack flags require an A-file src register. */
ra_set_node_class(g, temp_to_node[inst->src[0].index],
vc4->reg_class_a);
diff --git a/src/gallium/drivers/vc4/vc4_screen.c b/src/gallium/drivers/vc4/vc4_screen.c
index aa5cbfa2348..6bb158b5990 100644
--- a/src/gallium/drivers/vc4/vc4_screen.c
+++ b/src/gallium/drivers/vc4/vc4_screen.c
@@ -354,6 +354,14 @@ vc4_screen_is_format_supported(struct pipe_screen *pscreen,
case PIPE_FORMAT_R8G8B8_SNORM:
case PIPE_FORMAT_R8G8_SNORM:
case PIPE_FORMAT_R8_SNORM:
+ case PIPE_FORMAT_R8G8B8A8_USCALED:
+ case PIPE_FORMAT_R8G8B8_USCALED:
+ case PIPE_FORMAT_R8G8_USCALED:
+ case PIPE_FORMAT_R8_USCALED:
+ case PIPE_FORMAT_R8G8B8A8_SSCALED:
+ case PIPE_FORMAT_R8G8B8_SSCALED:
+ case PIPE_FORMAT_R8G8_SSCALED:
+ case PIPE_FORMAT_R8_SSCALED:
retval |= PIPE_BIND_VERTEX_BUFFER;
break;
default: