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 <robclark@freedesktop.org>
This commit is contained in:
@@ -1596,6 +1596,12 @@ static const struct instr_translater translaters[TGSI_OPCODE_LAST] = {
|
|||||||
INSTR(KILL, instr_cat0, .opc = OPC_KILL),
|
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
|
static int
|
||||||
decl_in(struct fd3_compile_context *ctx, struct tgsi_full_declaration *decl)
|
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;
|
unsigned i, flags = 0;
|
||||||
int nop = 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)
|
if (ctx->so->half_precision)
|
||||||
flags |= IR3_REG_HALF;
|
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
|
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].compmask = (1 << ncomp) - 1;
|
||||||
so->inputs[n].regid = r;
|
so->inputs[n].regid = r;
|
||||||
so->inputs[n].inloc = ctx->next_inloc;
|
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_GENERIC:
|
||||||
case TGSI_SEMANTIC_FOG:
|
case TGSI_SEMANTIC_FOG:
|
||||||
case TGSI_SEMANTIC_TEXCOORD:
|
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;
|
break;
|
||||||
default:
|
default:
|
||||||
compile_error(ctx, "unknown VS semantic name: %s\n",
|
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);
|
so->color_regid = regid(decl->Range.First + base, 0);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
compile_error(ctx, "unknown VS semantic name: %s\n",
|
compile_error(ctx, "unknown FS semantic name: %s\n",
|
||||||
tgsi_semantic_names[name]);
|
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
|
static void
|
||||||
|
@@ -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
|
void
|
||||||
fd3_program_emit(struct fd_ringbuffer *ring,
|
fd3_program_emit(struct fd_ringbuffer *ring,
|
||||||
struct fd_program_stateobj *prog)
|
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_PSIZEREGID(vp->psize_regid) |
|
||||||
A3XX_SP_VS_PARAM_REG_TOTALVSOUTVAR(fp->inputs_count));
|
A3XX_SP_VS_PARAM_REG_TOTALVSOUTVAR(fp->inputs_count));
|
||||||
|
|
||||||
assert(vp->outputs_count >= fp->inputs_count);
|
|
||||||
|
|
||||||
for (i = 0; i < fp->inputs_count; ) {
|
for (i = 0; i < fp->inputs_count; ) {
|
||||||
uint32_t reg = 0;
|
uint32_t reg = 0;
|
||||||
|
int j;
|
||||||
|
|
||||||
OUT_PKT0(ring, REG_A3XX_SP_VS_OUT_REG(i/2), 1);
|
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);
|
reg |= A3XX_SP_VS_OUT_REG_A_COMPMASK(fp->inputs[i].compmask);
|
||||||
i++;
|
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);
|
reg |= A3XX_SP_VS_OUT_REG_B_COMPMASK(fp->inputs[i].compmask);
|
||||||
i++;
|
i++;
|
||||||
|
|
||||||
@@ -507,6 +518,7 @@ create_blit_fp(struct pipe_context *pctx)
|
|||||||
so->color_regid = regid(0,0);
|
so->color_regid = regid(0,0);
|
||||||
so->half_precision = true;
|
so->half_precision = true;
|
||||||
so->inputs_count = 1;
|
so->inputs_count = 1;
|
||||||
|
so->inputs[0].semantic = fd3_semantic_name(TGSI_SEMANTIC_TEXCOORD, 0);
|
||||||
so->inputs[0].inloc = 8;
|
so->inputs[0].inloc = 8;
|
||||||
so->inputs[0].compmask = 0x3;
|
so->inputs[0].compmask = 0x3;
|
||||||
so->total_in = 2;
|
so->total_in = 2;
|
||||||
@@ -547,6 +559,7 @@ create_blit_vp(struct pipe_context *pctx)
|
|||||||
so->inputs[1].compmask = 0xf;
|
so->inputs[1].compmask = 0xf;
|
||||||
so->total_in = 8;
|
so->total_in = 8;
|
||||||
so->outputs_count = 1;
|
so->outputs_count = 1;
|
||||||
|
so->outputs[0].semantic = fd3_semantic_name(TGSI_SEMANTIC_TEXCOORD, 0);
|
||||||
so->outputs[0].regid = regid(0,0);
|
so->outputs[0].regid = regid(0,0);
|
||||||
|
|
||||||
fixup_vp_regfootprint(so);
|
fixup_vp_regfootprint(so);
|
||||||
|
@@ -36,6 +36,13 @@
|
|||||||
#include "ir-a3xx.h"
|
#include "ir-a3xx.h"
|
||||||
#include "disasm.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 {
|
struct fd3_shader_stateobj {
|
||||||
enum shader_t type;
|
enum shader_t type;
|
||||||
|
|
||||||
@@ -74,12 +81,14 @@ struct fd3_shader_stateobj {
|
|||||||
/* varyings/outputs: */
|
/* varyings/outputs: */
|
||||||
unsigned outputs_count;
|
unsigned outputs_count;
|
||||||
struct {
|
struct {
|
||||||
|
fd3_semantic semantic;
|
||||||
uint8_t regid;
|
uint8_t regid;
|
||||||
} outputs[16];
|
} outputs[16];
|
||||||
|
|
||||||
/* vertices/inputs: */
|
/* vertices/inputs: */
|
||||||
unsigned inputs_count;
|
unsigned inputs_count;
|
||||||
struct {
|
struct {
|
||||||
|
fd3_semantic semantic;
|
||||||
uint8_t regid;
|
uint8_t regid;
|
||||||
uint8_t compmask;
|
uint8_t compmask;
|
||||||
/* in theory inloc of fs should match outloc of vs: */
|
/* in theory inloc of fs should match outloc of vs: */
|
||||||
|
Reference in New Issue
Block a user