nv50/ir: use RDSV to fetch FrontFacing before lowering
This commit is contained in:
@@ -136,6 +136,25 @@ BuildUtil::mkFetch(Value *dst, DataType ty, DataFile file, int32_t offset,
|
||||
return insn;
|
||||
}
|
||||
|
||||
Instruction *
|
||||
BuildUtil::mkInterp(unsigned mode, Value *dst, int32_t offset, Value *rel)
|
||||
{
|
||||
operation op = OP_LINTERP;
|
||||
DataType ty = TYPE_F32;
|
||||
|
||||
if ((mode & NV50_IR_INTERP_MODE_MASK) == NV50_IR_INTERP_FLAT)
|
||||
ty = TYPE_U32;
|
||||
else
|
||||
if ((mode & NV50_IR_INTERP_MODE_MASK) == NV50_IR_INTERP_PERSPECTIVE)
|
||||
op = OP_PINTERP;
|
||||
|
||||
Symbol *sym = mkSymbol(FILE_SHADER_INPUT, 0, ty, offset);
|
||||
|
||||
Instruction *insn = mkOp1(op, ty, dst, sym);
|
||||
insn->setIndirect(0, 0, rel);
|
||||
return insn;
|
||||
}
|
||||
|
||||
Instruction *
|
||||
BuildUtil::mkMov(Value *dst, Value *src, DataType ty)
|
||||
{
|
||||
|
||||
@@ -63,6 +63,7 @@ public:
|
||||
Instruction *mkMovToReg(int id, Value *);
|
||||
Instruction *mkMovFromReg(Value *, int id);
|
||||
|
||||
Instruction *mkInterp(unsigned mode, Value *, int32_t offset, Value *rel);
|
||||
Instruction *mkFetch(Value *, DataType, DataFile, int32_t offset,
|
||||
Value *attrRel, Value *primRel);
|
||||
|
||||
|
||||
@@ -1246,6 +1246,8 @@ Converter::fetchSrc(tgsi::Instruction::SrcRegister src, int c, Value *ptr)
|
||||
// don't load masked inputs, won't be assigned a slot
|
||||
if (!ptr && !(info->in[idx].mask & (1 << swz)))
|
||||
return loadImm(NULL, swz == TGSI_SWIZZLE_W ? 1.0f : 0.0f);
|
||||
if (!ptr && info->in[idx].sn == TGSI_SEMANTIC_FACE)
|
||||
return mkOp1v(OP_RDSV, TYPE_F32, getSSA(), mkSysVal(SV_FACE, 0));
|
||||
return interpolate(src, c, ptr);
|
||||
}
|
||||
return mkLoad(TYPE_U32, srcToSym(src, c), ptr);
|
||||
|
||||
@@ -509,11 +509,17 @@ NVC0LoweringPass::handleRDSV(Instruction *i)
|
||||
switch (i->getSrc(0)->reg.data.sv.sv) {
|
||||
case SV_POSITION:
|
||||
assert(prog->getType() == Program::TYPE_FRAGMENT);
|
||||
ld = new_Instruction(func, OP_LINTERP, TYPE_F32);
|
||||
ld->setDef(0, i->getDef(0));
|
||||
ld->setSrc(0, bld.mkSymbol(FILE_SHADER_INPUT, 0, TYPE_F32, addr));
|
||||
ld->setInterpolate(NV50_IR_INTERP_LINEAR);
|
||||
bld.getBB()->insertAfter(i, ld);
|
||||
bld.mkInterp(NV50_IR_INTERP_LINEAR, i->getDef(0), addr, NULL);
|
||||
break;
|
||||
case SV_FACE:
|
||||
{
|
||||
Value *face = i->getDef(0);
|
||||
bld.mkInterp(NV50_IR_INTERP_FLAT, face, addr, NULL);
|
||||
if (i->dType == TYPE_F32) {
|
||||
bld.mkOp2(OP_AND, TYPE_U32, face, face, bld.mkImm(0x80000000));
|
||||
bld.mkOp2(OP_XOR, TYPE_U32, face, face, bld.mkImm(0xbf800000));
|
||||
}
|
||||
}
|
||||
break;
|
||||
case SV_TESS_COORD:
|
||||
assert(prog->getType() == Program::TYPE_TESSELLATION_EVAL);
|
||||
@@ -705,14 +711,6 @@ NVC0LoweringPass::visit(Instruction *i)
|
||||
i->getSrc(0)->reg.data.offset < 0x2c0)
|
||||
i->setInterpolate(i->getSampleMode() | NV50_IR_INTERP_SC);
|
||||
break;
|
||||
case OP_LINTERP:
|
||||
if (i->getSrc(0)->reg.data.offset == 0x3fc) {
|
||||
Value *face = i->getDef(0);
|
||||
bld.setPosition(i, true);
|
||||
bld.mkOp2(OP_SHL, TYPE_U32, face, face, bld.mkImm(31));
|
||||
bld.mkOp2(OP_XOR, TYPE_U32, face, face, bld.mkImm(0xbf800000));
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user