summaryrefslogtreecommitdiff
path: root/src/gallium/drivers/nouveau/codegen/nv50_ir_from_tgsi.cpp
diff options
context:
space:
mode:
authorBryan Cain <bryancain3@gmail.com>2013-04-17 15:55:46 -0500
committerMaarten Lankhorst <maarten.lankhorst@canonical.com>2014-01-27 16:40:42 +0100
commitb3f82e1a63e8a58f0e7ac297fc5e94ebe76c3339 (patch)
treea562a31522d0edb8027c6c33b52a188370aa6132 /src/gallium/drivers/nouveau/codegen/nv50_ir_from_tgsi.cpp
parent67250acbaba924ccaab696f2b348dfa898c41d0b (diff)
nv50/ir: delay calculation of indirect addresses
Instead of emitting an SHL 4 io an address register on the TGSI ARL and UARL instructions, emit the shift when the loaded address is actually used. This is necessary because input vertex and attribute indices in geometry shaders on nv50 need to be shifted left by 2 instead of 4. Signed-off-by: Bryan Cain <bryancain3@gmail.com> [calim: various updates to the indirect address logic] Signed-off-by: Christoph Bumiller <e0425955@student.tuwien.ac.at> [imirkin: remove OP_MAD change that calim made, add OP_RESTART handling same as OP_EMIT for code flow analysis] Signed-off-by: Ilia Mirkin <imirkin@alum.mit.edu>
Diffstat (limited to 'src/gallium/drivers/nouveau/codegen/nv50_ir_from_tgsi.cpp')
-rw-r--r--src/gallium/drivers/nouveau/codegen/nv50_ir_from_tgsi.cpp38
1 files changed, 28 insertions, 10 deletions
diff --git a/src/gallium/drivers/nouveau/codegen/nv50_ir_from_tgsi.cpp b/src/gallium/drivers/nouveau/codegen/nv50_ir_from_tgsi.cpp
index 49a45f8394b..3c790cfe77f 100644
--- a/src/gallium/drivers/nouveau/codegen/nv50_ir_from_tgsi.cpp
+++ b/src/gallium/drivers/nouveau/codegen/nv50_ir_from_tgsi.cpp
@@ -1126,6 +1126,7 @@ private:
ValueMap values;
};
+ Value *shiftAddress(Value *);
Value *getVertexBase(int s);
DataArray *getArrayForFile(unsigned file, int idx);
Value *fetchSrc(int s, int c);
@@ -1344,7 +1345,8 @@ Converter::getVertexBase(int s)
if (tgsi.getSrc(s).isIndirect(1))
rel = fetchSrc(tgsi.getSrc(s).getIndirect(1), 0, NULL);
vtxBaseValid |= 1 << s;
- vtxBase[s] = mkOp2v(OP_PFETCH, TYPE_U32, getSSA(), mkImm(index), rel);
+ vtxBase[s] = mkOp2v(OP_PFETCH, TYPE_U32, getSSA(4, FILE_ADDRESS),
+ mkImm(index), rel);
}
return vtxBase[s];
}
@@ -1403,6 +1405,14 @@ Converter::getArrayForFile(unsigned file, int idx)
}
Value *
+Converter::shiftAddress(Value *index)
+{
+ if (!index)
+ return NULL;
+ return mkOp2v(OP_SHL, TYPE_U32, getSSA(4, FILE_ADDRESS), index, mkImm(4));
+}
+
+Value *
Converter::fetchSrc(tgsi::Instruction::SrcRegister src, int c, Value *ptr)
{
const int idx2d = src.is2D() ? src.getIndex(1) : 0;
@@ -1414,7 +1424,7 @@ Converter::fetchSrc(tgsi::Instruction::SrcRegister src, int c, Value *ptr)
assert(!ptr);
return loadImm(NULL, info->immd.data[idx * 4 + swz]);
case TGSI_FILE_CONSTANT:
- return mkLoadv(TYPE_U32, srcToSym(src, c), ptr);
+ return mkLoadv(TYPE_U32, srcToSym(src, c), shiftAddress(ptr));
case TGSI_FILE_INPUT:
if (prog->getType() == Program::TYPE_FRAGMENT) {
// don't load masked inputs, won't be assigned a slot
@@ -1422,9 +1432,17 @@ Converter::fetchSrc(tgsi::Instruction::SrcRegister src, int c, Value *ptr)
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 interpolate(src, c, shiftAddress(ptr));
+ } else
+ if (ptr && prog->getType() == Program::TYPE_GEOMETRY) {
+ // XXX: This is going to be a problem with scalar arrays, i.e. when
+ // we cannot assume that the address is given in units of vec4.
+ //
+ // nv50 and nvc0 need different things here, so let the lowering
+ // passes decide what to do with the address
+ return mkLoadv(TYPE_U32, srcToSym(src, c), ptr);
}
- return mkLoadv(TYPE_U32, srcToSym(src, c), ptr);
+ return mkLoadv(TYPE_U32, srcToSym(src, c), shiftAddress(ptr));
case TGSI_FILE_OUTPUT:
assert(!"load from output file");
return NULL;
@@ -1433,7 +1451,7 @@ Converter::fetchSrc(tgsi::Instruction::SrcRegister src, int c, Value *ptr)
return mkOp1v(OP_RDSV, TYPE_U32, getSSA(), srcToSym(src, c));
default:
return getArrayForFile(src.getFile(), idx2d)->load(
- sub.cur->values, idx, swz, ptr);
+ sub.cur->values, idx, swz, shiftAddress(ptr));
}
}
@@ -1476,8 +1494,9 @@ Converter::storeDst(int d, int c, Value *val)
break;
}
- Value *ptr = dst.isIndirect(0) ?
- fetchSrc(dst.getIndirect(0), 0, NULL) : NULL;
+ Value *ptr = NULL;
+ if (dst.isIndirect(0))
+ ptr = shiftAddress(fetchSrc(dst.getIndirect(0), 0, NULL));
if (info->io.genUserClip > 0 &&
dst.getFile() == TGSI_FILE_OUTPUT &&
@@ -2179,12 +2198,11 @@ Converter::handleInstruction(const struct tgsi_full_instruction *insn)
FOR_EACH_DST_ENABLED_CHANNEL(0, c, tgsi) {
src0 = fetchSrc(0, c);
mkCvt(OP_CVT, TYPE_S32, dst0[c], TYPE_F32, src0)->rnd = ROUND_M;
- mkOp2(OP_SHL, TYPE_U32, dst0[c], dst0[c], mkImm(4));
}
break;
case TGSI_OPCODE_UARL:
FOR_EACH_DST_ENABLED_CHANNEL(0, c, tgsi)
- mkOp2(OP_SHL, TYPE_U32, dst0[c], fetchSrc(0, c), mkImm(4));
+ mkOp1(OP_MOV, TYPE_U32, dst0[c], fetchSrc(0, c));
break;
case TGSI_OPCODE_EX2:
case TGSI_OPCODE_LG2:
@@ -2721,7 +2739,7 @@ Converter::Converter(Program *ir, const tgsi::Source *code) : BuildUtil(ir),
tData.setup(TGSI_FILE_TEMPORARY, 0, 0, tSize, 4, 4, tFile, 0);
pData.setup(TGSI_FILE_PREDICATE, 0, 0, pSize, 4, 4, FILE_PREDICATE, 0);
- aData.setup(TGSI_FILE_ADDRESS, 0, 0, aSize, 4, 4, FILE_ADDRESS, 0);
+ aData.setup(TGSI_FILE_ADDRESS, 0, 0, aSize, 4, 4, FILE_GPR, 0);
oData.setup(TGSI_FILE_OUTPUT, 0, 0, oSize, 4, 4, FILE_GPR, 0);
zero = mkImm((uint32_t)0);