vc4: Add support for swizzles of 32 bit float vertex attributes.
authorEric Anholt <eric@anholt.net>
Fri, 1 Aug 2014 19:50:53 +0000 (12:50 -0700)
committerEric Anholt <eric@anholt.net>
Sat, 9 Aug 2014 01:59:47 +0000 (18:59 -0700)
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
src/gallium/drivers/vc4/vc4_program.c

index 24d5edf6a0b08a9431585409abe71839f0bcadb2..c0fb082c548e81588368f641138c097edda69b20 100644 (file)
@@ -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,
index 8c0b241d7ef0bfce2a110739c15f65acb2cee71d..5d640f45321629d35ddb1d1aba760642868621c3 100644 (file)
@@ -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;