freedreno/a3xx: fix VS out / FS in linking
authorRob Clark <robclark@freedesktop.org>
Fri, 1 Nov 2013 14:11:27 +0000 (10:11 -0400)
committerRob Clark <robclark@freedesktop.org>
Sat, 2 Nov 2013 00:20:47 +0000 (20:20 -0400)
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 <robclark@freedesktop.org>
src/gallium/drivers/freedreno/a3xx/fd3_compiler.c
src/gallium/drivers/freedreno/a3xx/fd3_program.c
src/gallium/drivers/freedreno/a3xx/fd3_program.h

index 760fb7de2ed9a99d788089a7a33da37c66b27c41..7f53a2c6ea9559f437060835766055b3cc8eb51e 100644 (file)
@@ -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
index 7bb96faa8999f5aacd16d5991e530cf65f341853..17659af373ff05f6963d4d32e35a99539b808d3a 100644 (file)
@@ -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);
index 9b50d34f7566b876eaf8039d58fda199a556950a..85c22a54cf7b72d5b83674d3d545f6e15576b811 100644 (file)
 #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: */