diff options
4 files changed, 33 insertions, 13 deletions
diff --git a/src/gallium/drivers/nv50/codegen/nv50_ir_build_util.cpp b/src/gallium/drivers/nv50/codegen/nv50_ir_build_util.cpp index 521578ac6f2..f9c18fa8d88 100644 --- a/src/gallium/drivers/nv50/codegen/nv50_ir_build_util.cpp +++ b/src/gallium/drivers/nv50/codegen/nv50_ir_build_util.cpp @@ -137,6 +137,25 @@ BuildUtil::mkFetch(Value *dst, DataType ty, DataFile file, int32_t offset, } 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) { Instruction *insn = new_Instruction(func, OP_MOV, ty); diff --git a/src/gallium/drivers/nv50/codegen/nv50_ir_build_util.h b/src/gallium/drivers/nv50/codegen/nv50_ir_build_util.h index ad7d54f0d41..dbc6723fe90 100644 --- a/src/gallium/drivers/nv50/codegen/nv50_ir_build_util.h +++ b/src/gallium/drivers/nv50/codegen/nv50_ir_build_util.h @@ -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); diff --git a/src/gallium/drivers/nv50/codegen/nv50_ir_from_tgsi.cpp b/src/gallium/drivers/nv50/codegen/nv50_ir_from_tgsi.cpp index 40ea6a0d2d3..6cb61b87766 100644 --- a/src/gallium/drivers/nv50/codegen/nv50_ir_from_tgsi.cpp +++ b/src/gallium/drivers/nv50/codegen/nv50_ir_from_tgsi.cpp @@ -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); diff --git a/src/gallium/drivers/nvc0/codegen/nv50_ir_lowering_nvc0.cpp b/src/gallium/drivers/nvc0/codegen/nv50_ir_lowering_nvc0.cpp index 51537972644..6faef9b68ca 100644 --- a/src/gallium/drivers/nvc0/codegen/nv50_ir_lowering_nvc0.cpp +++ b/src/gallium/drivers/nvc0/codegen/nv50_ir_lowering_nvc0.cpp @@ -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; } |