Mesa (master): vc4: Add support for 8-bit unnormalized vertex attrs.

Eric Anholt anholt at kemper.freedesktop.org
Mon Dec 15 22:33:32 UTC 2014


Module: Mesa
Branch: master
Commit: 2142fd1f6f36ef9a384ef298fec02111dc826308
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=2142fd1f6f36ef9a384ef298fec02111dc826308

Author: Eric Anholt <eric at anholt.net>
Date:   Mon Dec 15 11:19:58 2014 -0800

vc4: Add support for 8-bit unnormalized vertex attrs.

---

 src/gallium/drivers/vc4/vc4_program.c           |   30 ++++++++++++++---------
 src/gallium/drivers/vc4/vc4_qir.c               |    4 +++
 src/gallium/drivers/vc4/vc4_qir.h               |   13 ++++++++++
 src/gallium/drivers/vc4/vc4_qpu_emit.c          |   21 ++++++++++++++++
 src/gallium/drivers/vc4/vc4_register_allocate.c |    4 +++
 src/gallium/drivers/vc4/vc4_screen.c            |    8 ++++++
 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 fd9cd5e..1efdf37 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 e83c036..8cd571d 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 c612b28..9da120a 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 8b3a001..f880727 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 f48ce18..8f8c189 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 aa5cbfa..6bb158b 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:




More information about the mesa-commit mailing list