Mesa (master): vc4: Add support for having 0 vertex elements used.

Eric Anholt anholt at kemper.freedesktop.org
Tue Oct 14 10:30:37 UTC 2014


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

Author: Eric Anholt <eric at anholt.net>
Date:   Thu Sep 25 14:57:01 2014 -0700

vc4: Add support for having 0 vertex elements used.

You have to load at least 1, according to the simulator.  Fixes 4 piglit
tests and even more ES2 conformance tests.

---

 src/gallium/drivers/vc4/vc4_draw.c    |   27 +++++++++++++++++++++------
 src/gallium/drivers/vc4/vc4_program.c |   26 ++++++++++++++++++++++++++
 2 files changed, 47 insertions(+), 6 deletions(-)

diff --git a/src/gallium/drivers/vc4/vc4_draw.c b/src/gallium/drivers/vc4/vc4_draw.c
index 1a0c0dc..0938a76 100644
--- a/src/gallium/drivers/vc4/vc4_draw.c
+++ b/src/gallium/drivers/vc4/vc4_draw.c
@@ -120,8 +120,12 @@ vc4_draw_vbo(struct pipe_context *pctx, const struct pipe_draw_info *info)
                            &vc4->constbuf[PIPE_SHADER_VERTEX],
                            &vc4->verttex);
 
+        /* The simulator throws a fit if VS or CS don't read an attribute, so
+         * we emit a dummy read.
+         */
+        uint32_t num_elements_emit = MAX2(vtx->num_elements, 1);
         /* Emit the shader record. */
-        cl_start_shader_reloc(&vc4->shader_rec, 3 + vtx->num_elements);
+        cl_start_shader_reloc(&vc4->shader_rec, 3 + num_elements_emit);
         cl_u16(&vc4->shader_rec,
                VC4_SHADER_FLAG_ENABLE_CLIPPING |
                ((info->mode == PIPE_PRIM_POINTS &&
@@ -133,14 +137,14 @@ vc4_draw_vbo(struct pipe_context *pctx, const struct pipe_draw_info *info)
         cl_u32(&vc4->shader_rec, 0); /* UBO offset written by kernel */
 
         cl_u16(&vc4->shader_rec, 0); /* vs num uniforms */
-        cl_u8(&vc4->shader_rec, (1 << vtx->num_elements) - 1); /* vs attribute array bitfield */
-        cl_u8(&vc4->shader_rec, 16 * vtx->num_elements); /* vs total attribute size */
+        cl_u8(&vc4->shader_rec, (1 << num_elements_emit) - 1); /* vs attribute array bitfield */
+        cl_u8(&vc4->shader_rec, 16 * num_elements_emit); /* vs total attribute size */
         cl_reloc(vc4, &vc4->shader_rec, vc4->prog.vs->bo, 0);
         cl_u32(&vc4->shader_rec, 0); /* UBO offset written by kernel */
 
         cl_u16(&vc4->shader_rec, 0); /* cs num uniforms */
-        cl_u8(&vc4->shader_rec, (1 << vtx->num_elements) - 1); /* cs attribute array bitfield */
-        cl_u8(&vc4->shader_rec, 16 * vtx->num_elements); /* cs total attribute size */
+        cl_u8(&vc4->shader_rec, (1 << num_elements_emit) - 1); /* cs attribute array bitfield */
+        cl_u8(&vc4->shader_rec, 16 * num_elements_emit); /* cs total attribute size */
         cl_reloc(vc4, &vc4->shader_rec, vc4->prog.cs->bo, 0);
         cl_u32(&vc4->shader_rec, 0); /* UBO offset written by kernel */
 
@@ -167,13 +171,24 @@ vc4_draw_vbo(struct pipe_context *pctx, const struct pipe_draw_info *info)
                 }
         }
 
+        if (vtx->num_elements == 0) {
+                assert(num_elements_emit == 1);
+                struct vc4_bo *bo = vc4_bo_alloc(vc4->screen, 4096, "scratch VBO");
+                cl_reloc(vc4, &vc4->shader_rec, bo, 0);
+                cl_u8(&vc4->shader_rec, 16 - 1); /* element size */
+                cl_u8(&vc4->shader_rec, 0); /* stride */
+                cl_u8(&vc4->shader_rec, 0); /* VS VPM offset */
+                cl_u8(&vc4->shader_rec, 0); /* CS VPM offset */
+                vc4_bo_unreference(&bo);
+        }
+
         /* the actual draw call. */
         cl_u8(&vc4->bcl, VC4_PACKET_GL_SHADER_STATE);
         assert(vtx->num_elements <= 8);
         /* Note that number of attributes == 0 in the packet means 8
          * attributes.  This field also contains the offset into shader_rec.
          */
-        cl_u32(&vc4->bcl, vtx->num_elements & 0x7);
+        cl_u32(&vc4->bcl, num_elements_emit & 0x7);
 
         /* Note that the primitive type fields match with OpenGL/gallium
          * definitions, up to but not including QUADS.
diff --git a/src/gallium/drivers/vc4/vc4_program.c b/src/gallium/drivers/vc4/vc4_program.c
index 3056c67..c603425 100644
--- a/src/gallium/drivers/vc4/vc4_program.c
+++ b/src/gallium/drivers/vc4/vc4_program.c
@@ -1619,6 +1619,29 @@ emit_point_size_write(struct vc4_compile *c)
         qir_VPM_WRITE(c, point_size);
 }
 
+/**
+ * Emits a VPM read of the stub vertex attribute set up by vc4_draw.c.
+ *
+ * The simulator insists that there be at least one vertex attribute, so
+ * vc4_draw.c will emit one if it wouldn't have otherwise.  The simulator also
+ * insists that all vertex attributes loaded get read by the VS/CS, so we have
+ * to consume it here.
+ */
+static void
+emit_stub_vpm_read(struct vc4_compile *c)
+{
+        if (c->num_inputs)
+                return;
+
+        for (int i = 0; i < 4; i++) {
+                qir_emit(c, qir_inst(QOP_VPM_READ,
+                                     qir_get_temp(c),
+                                     c->undef,
+                                     c->undef));
+                c->num_inputs++;
+        }
+}
+
 static void
 emit_vert_end(struct vc4_compile *c,
               struct vc4_varying_semantic *fs_inputs,
@@ -1626,6 +1649,7 @@ emit_vert_end(struct vc4_compile *c,
 {
         struct qreg rcp_w = qir_RCP(c, c->outputs[3]);
 
+        emit_stub_vpm_read(c);
         emit_scaled_viewport_write(c, rcp_w);
         emit_zs_write(c, rcp_w);
         emit_rcp_wc_write(c, rcp_w);
@@ -1658,6 +1682,8 @@ emit_coord_end(struct vc4_compile *c)
 {
         struct qreg rcp_w = qir_RCP(c, c->outputs[3]);
 
+        emit_stub_vpm_read(c);
+
         for (int i = 0; i < 4; i++)
                 qir_VPM_WRITE(c, c->outputs[i]);
 




More information about the mesa-commit mailing list