From 88bc5baa00c632c2411304b2c7e5cc49f882c30e Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Fri, 1 Aug 2014 12:50:53 -0700 Subject: [PATCH] vc4: Add support for swizzles of 32 bit float vertex attributes. Some tests start working (useprogram-flushverts, for example) due to getitng the right vertices now. Some that used to pass start failing with memory overflow during binning, which is weird (glsl-fs-texture2drect). And a couple stop rendering correctly (glsl-fs-bug25902). v2: Move the attribute format setup in the key from after search time to before the search. v3: Fix reading of attributes other than position (I forgot to respect attr and stored everything in inputs 0-3, i.e. position). --- src/gallium/drivers/vc4/vc4_draw.c | 5 -- src/gallium/drivers/vc4/vc4_program.c | 88 ++++++++++++++++++++++----- 2 files changed, 73 insertions(+), 20 deletions(-) diff --git a/src/gallium/drivers/vc4/vc4_draw.c b/src/gallium/drivers/vc4/vc4_draw.c index 24d5edf6a0b..c0fb082c548 100644 --- a/src/gallium/drivers/vc4/vc4_draw.c +++ b/src/gallium/drivers/vc4/vc4_draw.c @@ -205,11 +205,6 @@ vc4_draw_vbo(struct pipe_context *pctx, const struct pipe_draw_info *info) &vertexbuf->vb[elem->vertex_buffer_index]; struct vc4_resource *rsc = vc4_resource(vb->buffer); - if (elem->src_format != PIPE_FORMAT_R32G32B32A32_FLOAT) { - fprintf(stderr, "Unsupported attribute format %s\n", - util_format_name(elem->src_format)); - } - cl_reloc(vc4, &vc4->shader_rec, rsc->bo, vb->buffer_offset + elem->src_offset); cl_u8(&vc4->shader_rec, diff --git a/src/gallium/drivers/vc4/vc4_program.c b/src/gallium/drivers/vc4/vc4_program.c index 8c0b241d7ef..5d640f45321 100644 --- a/src/gallium/drivers/vc4/vc4_program.c +++ b/src/gallium/drivers/vc4/vc4_program.c @@ -369,6 +369,64 @@ tgsi_to_qir_abs(struct tgsi_to_qir *trans, return qir_FMAXABS(c, arg, arg); } +static void +emit_vertex_input(struct tgsi_to_qir *trans, int attr) +{ + enum pipe_format format = trans->vs_key->attr_formats[attr]; + struct qcompile *c = trans->c; + struct qreg vpm_reads[4]; + + /* Right now, we're setting the VPM offsets to be 16 bytes wide every + * time, so we always read 4 32-bit VPM entries. + */ + for (int i = 0; i < 4; i++) { + vpm_reads[i] = qir_get_temp(c); + qir_emit(c, qir_inst(QOP_VPM_READ, + vpm_reads[i], + c->undef, + c->undef)); + c->num_inputs++; + } + + bool format_warned = false; + const struct util_format_description *desc = + util_format_description(format); + + for (int i = 0; i < 4; i++) { + uint8_t swiz = desc->swizzle[i]; + + switch (swiz) { + case UTIL_FORMAT_SWIZZLE_NONE: + if (!format_warned) { + fprintf(stderr, + "vtx element %d NONE swizzle: %s\n", + attr, util_format_name(format)); + format_warned = true; + } + /* FALLTHROUGH */ + case UTIL_FORMAT_SWIZZLE_0: + trans->inputs[attr * 4 + i] = qir_uniform_ui(trans, 0); + break; + case UTIL_FORMAT_SWIZZLE_1: + trans->inputs[attr * 4 + i] = qir_uniform_ui(trans, + fui(1.0)); + break; + default: + if (!format_warned && + (desc->channel[swiz].type != UTIL_FORMAT_TYPE_FLOAT || + desc->channel[swiz].size != 32)) { + fprintf(stderr, + "vtx element %d unsupported type: %s\n", + attr, util_format_name(format)); + format_warned = true; + } + + trans->inputs[attr * 4 + i] = vpm_reads[swiz]; + break; + } + } +} + static void emit_tgsi_declaration(struct tgsi_to_qir *trans, struct tgsi_full_declaration *decl) @@ -377,28 +435,25 @@ emit_tgsi_declaration(struct tgsi_to_qir *trans, switch (decl->Declaration.File) { case TGSI_FILE_INPUT: - for (int i = decl->Range.First * 4; - i < (decl->Range.Last + 1) * 4; - i++) { - if (c->stage == QSTAGE_FRAG) { + if (c->stage == QSTAGE_FRAG) { + for (int i = decl->Range.First * 4; + i < (decl->Range.Last + 1) * 4; + i++) { struct qreg vary = { QFILE_VARY, i }; - trans->inputs[i] = qir_VARY_ADD_C(c, qir_MOV(c, vary)); - } else { - struct qreg dst = qir_get_temp(c); - /* XXX: attribute type/size/count */ - qir_emit(c, qir_inst(QOP_VPM_READ, - dst, - c->undef, - c->undef)); - trans->inputs[i] = dst; - } - c->num_inputs++; + c->num_inputs++; + } + } else { + for (int i = decl->Range.First; + i <= decl->Range.Last; + i++) { + emit_vertex_input(trans, i); + } } break; } @@ -793,6 +848,9 @@ vc4_update_compiled_vs(struct vc4_context *vc4) memset(key, 0, sizeof(*key)); key->base.shader_state = vc4->prog.bind_vs; + for (int i = 0; i < ARRAY_SIZE(key->attr_formats); i++) + key->attr_formats[i] = vc4->vtx->pipe[i].src_format; + vc4->prog.vs = util_hash_table_get(vc4->vs_cache, key); if (vc4->prog.vs) return; -- 2.30.2