From 2142fd1f6f36ef9a384ef298fec02111dc826308 Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Mon, 15 Dec 2014 11:19:58 -0800 Subject: [PATCH] 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 +++++++++++++ .../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 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 */ @@ -496,6 +501,14 @@ qir_UNPACK_8_F(struct vc4_compile *c, struct qreg src, int i) return t; } +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) { 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: -- 2.30.2