From b5fc9d5664d08d2e47ae89bf580e43732346a694 Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Thu, 25 Sep 2014 14:57:01 -0700 Subject: 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 1a0c0dc6552..0938a76e000 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 3056c6736af..c6034257e42 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]); -- cgit v1.2.3