diff options
author | Rob Clark <[email protected]> | 2013-11-01 10:11:27 -0400 |
---|---|---|
committer | Rob Clark <[email protected]> | 2013-11-01 20:20:47 -0400 |
commit | f16b084bb92f77acc40b83ad5708e406d4debf14 (patch) | |
tree | 45939d1105d5939baad2e212ba17e782c4db1242 /src/gallium/drivers/freedreno/a3xx | |
parent | 83318d6511da580e3b40af7cb0111684b165f315 (diff) |
freedreno/a3xx: fix VS out / FS in linking
Actually link VS out / FS in based on semantic info, keeping in mind
that position/pointsize can also be an input to the FS. This fixes a
few fragment shaders which were using gl_Position.
Signed-off-by: Rob Clark <[email protected]>
Diffstat (limited to 'src/gallium/drivers/freedreno/a3xx')
-rw-r--r-- | src/gallium/drivers/freedreno/a3xx/fd3_compiler.c | 24 | ||||
-rw-r--r-- | src/gallium/drivers/freedreno/a3xx/fd3_program.c | 21 | ||||
-rw-r--r-- | src/gallium/drivers/freedreno/a3xx/fd3_program.h | 9 |
3 files changed, 47 insertions, 7 deletions
diff --git a/src/gallium/drivers/freedreno/a3xx/fd3_compiler.c b/src/gallium/drivers/freedreno/a3xx/fd3_compiler.c index 760fb7de2ed..7f53a2c6ea9 100644 --- a/src/gallium/drivers/freedreno/a3xx/fd3_compiler.c +++ b/src/gallium/drivers/freedreno/a3xx/fd3_compiler.c @@ -1596,6 +1596,12 @@ static const struct instr_translater translaters[TGSI_OPCODE_LAST] = { INSTR(KILL, instr_cat0, .opc = OPC_KILL), }; +static fd3_semantic +decl_semantic(const struct tgsi_declaration_semantic *sem) +{ + return fd3_semantic_name(sem->Name, sem->Index); +} + static int decl_in(struct fd3_compile_context *ctx, struct tgsi_full_declaration *decl) { @@ -1604,6 +1610,13 @@ decl_in(struct fd3_compile_context *ctx, struct tgsi_full_declaration *decl) unsigned i, flags = 0; int nop = 0; + /* I don't think we should get frag shader input without + * semantic info? Otherwise how do inputs get linked to + * vert outputs? + */ + compile_assert(ctx, (ctx->type == TGSI_PROCESSOR_VERTEX) || + decl->Declaration.Semantic); + if (ctx->so->half_precision) flags |= IR3_REG_HALF; @@ -1617,6 +1630,7 @@ decl_in(struct fd3_compile_context *ctx, struct tgsi_full_declaration *decl) DBG("decl in -> r%d", i + base); // XXX + so->inputs[n].semantic = decl_semantic(&decl->Semantic); so->inputs[n].compmask = (1 << ncomp) - 1; so->inputs[n].regid = r; so->inputs[n].inloc = ctx->next_inloc; @@ -1672,8 +1686,6 @@ decl_out(struct fd3_compile_context *ctx, struct tgsi_full_declaration *decl) case TGSI_SEMANTIC_GENERIC: case TGSI_SEMANTIC_FOG: case TGSI_SEMANTIC_TEXCOORD: - for (i = decl->Range.First; i <= decl->Range.Last; i++) - so->outputs[so->outputs_count++].regid = regid(i + base, 0); break; default: compile_error(ctx, "unknown VS semantic name: %s\n", @@ -1685,10 +1697,16 @@ decl_out(struct fd3_compile_context *ctx, struct tgsi_full_declaration *decl) so->color_regid = regid(decl->Range.First + base, 0); break; default: - compile_error(ctx, "unknown VS semantic name: %s\n", + compile_error(ctx, "unknown FS semantic name: %s\n", tgsi_semantic_names[name]); } } + + for (i = decl->Range.First; i <= decl->Range.Last; i++) { + unsigned n = so->outputs_count++; + so->outputs[n].semantic = decl_semantic(&decl->Semantic); + so->outputs[n].regid = regid(i + base, 0); + } } static void diff --git a/src/gallium/drivers/freedreno/a3xx/fd3_program.c b/src/gallium/drivers/freedreno/a3xx/fd3_program.c index 7bb96faa899..17659af373f 100644 --- a/src/gallium/drivers/freedreno/a3xx/fd3_program.c +++ b/src/gallium/drivers/freedreno/a3xx/fd3_program.c @@ -215,6 +215,16 @@ emit_shader(struct fd_ringbuffer *ring, struct fd3_shader_stateobj *so) } } +static int +find_output(struct fd3_shader_stateobj *so, fd3_semantic semantic) +{ + int j; + for (j = 0; j < so->outputs_count; j++) + if (so->outputs[j].semantic == semantic) + return j; + return 0; +} + void fd3_program_emit(struct fd_ringbuffer *ring, struct fd_program_stateobj *prog) @@ -287,18 +297,19 @@ fd3_program_emit(struct fd_ringbuffer *ring, A3XX_SP_VS_PARAM_REG_PSIZEREGID(vp->psize_regid) | A3XX_SP_VS_PARAM_REG_TOTALVSOUTVAR(fp->inputs_count)); - assert(vp->outputs_count >= fp->inputs_count); - for (i = 0; i < fp->inputs_count; ) { uint32_t reg = 0; + int j; OUT_PKT0(ring, REG_A3XX_SP_VS_OUT_REG(i/2), 1); - reg |= A3XX_SP_VS_OUT_REG_A_REGID(vp->outputs[i].regid); + j = find_output(vp, fp->inputs[i].semantic); + reg |= A3XX_SP_VS_OUT_REG_A_REGID(vp->outputs[j].regid); reg |= A3XX_SP_VS_OUT_REG_A_COMPMASK(fp->inputs[i].compmask); i++; - reg |= A3XX_SP_VS_OUT_REG_B_REGID(vp->outputs[i].regid); + j = find_output(vp, fp->inputs[i].semantic); + reg |= A3XX_SP_VS_OUT_REG_B_REGID(vp->outputs[j].regid); reg |= A3XX_SP_VS_OUT_REG_B_COMPMASK(fp->inputs[i].compmask); i++; @@ -507,6 +518,7 @@ create_blit_fp(struct pipe_context *pctx) so->color_regid = regid(0,0); so->half_precision = true; so->inputs_count = 1; + so->inputs[0].semantic = fd3_semantic_name(TGSI_SEMANTIC_TEXCOORD, 0); so->inputs[0].inloc = 8; so->inputs[0].compmask = 0x3; so->total_in = 2; @@ -547,6 +559,7 @@ create_blit_vp(struct pipe_context *pctx) so->inputs[1].compmask = 0xf; so->total_in = 8; so->outputs_count = 1; + so->outputs[0].semantic = fd3_semantic_name(TGSI_SEMANTIC_TEXCOORD, 0); so->outputs[0].regid = regid(0,0); fixup_vp_regfootprint(so); diff --git a/src/gallium/drivers/freedreno/a3xx/fd3_program.h b/src/gallium/drivers/freedreno/a3xx/fd3_program.h index 9b50d34f756..85c22a54cf7 100644 --- a/src/gallium/drivers/freedreno/a3xx/fd3_program.h +++ b/src/gallium/drivers/freedreno/a3xx/fd3_program.h @@ -36,6 +36,13 @@ #include "ir-a3xx.h" #include "disasm.h" +typedef uint16_t fd3_semantic; /* semantic name + index */ +static inline fd3_semantic +fd3_semantic_name(uint8_t name, uint16_t index) +{ + return (name << 8) | (index & 0xff); +} + struct fd3_shader_stateobj { enum shader_t type; @@ -74,12 +81,14 @@ struct fd3_shader_stateobj { /* varyings/outputs: */ unsigned outputs_count; struct { + fd3_semantic semantic; uint8_t regid; } outputs[16]; /* vertices/inputs: */ unsigned inputs_count; struct { + fd3_semantic semantic; uint8_t regid; uint8_t compmask; /* in theory inloc of fs should match outloc of vs: */ |