nv50/ir: use RDSV to fetch FrontFacing before lowering
authorChristoph Bumiller <e0425955@student.tuwien.ac.at>
Mon, 17 Oct 2011 21:04:11 +0000 (23:04 +0200)
committerChristoph Bumiller <e0425955@student.tuwien.ac.at>
Fri, 21 Oct 2011 21:00:39 +0000 (23:00 +0200)
src/gallium/drivers/nv50/codegen/nv50_ir_build_util.cpp
src/gallium/drivers/nv50/codegen/nv50_ir_build_util.h
src/gallium/drivers/nv50/codegen/nv50_ir_from_tgsi.cpp
src/gallium/drivers/nvc0/codegen/nv50_ir_lowering_nvc0.cpp

index 521578a..f9c18fa 100644 (file)
@@ -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);
index ad7d54f..dbc6723 100644 (file)
@@ -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);
 
index 40ea6a0..6cb61b8 100644 (file)
@@ -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);
index 5153797..6faef9b 100644 (file)
@@ -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;
    }