summaryrefslogtreecommitdiffstats
path: root/src/gallium/drivers/vc4/vc4_program.c
diff options
context:
space:
mode:
authorEric Anholt <[email protected]>2014-08-01 12:50:53 -0700
committerEric Anholt <[email protected]>2014-08-08 18:59:47 -0700
commit88bc5baa00c632c2411304b2c7e5cc49f882c30e (patch)
treecc0aa57ffc9464b96d54049b759cab579f19ee01 /src/gallium/drivers/vc4/vc4_program.c
parentf069367f3938741c07658f54390c16550e1b5a5c (diff)
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).
Diffstat (limited to 'src/gallium/drivers/vc4/vc4_program.c')
-rw-r--r--src/gallium/drivers/vc4/vc4_program.c88
1 files changed, 73 insertions, 15 deletions
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
@@ -370,6 +370,64 @@ tgsi_to_qir_abs(struct tgsi_to_qir *trans,
}
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;