return tgsi_util_get_src_register_swizzle(®, chan);
}
+ int getArrayId() const
+ {
+ if (isIndirect(0))
+ return fsr->Indirect.ArrayID;
+ return 0;
+ }
+
nv50_ir::Modifier getMod(int chan) const;
SrcRegister getIndirect(int dim) const
return SrcRegister(fdr->Indirect);
}
+ int getArrayId() const
+ {
+ if (isIndirect(0))
+ return fdr->Indirect.ArrayID;
+ return 0;
+ }
+
private:
const struct tgsi_dst_register reg;
const struct tgsi_full_dst_register *fdr;
// these registers are per-subroutine, cannot be used for parameter passing
std::set<Location> locals;
- bool mainTempsInLMem;
+ std::set<int> indirectTempArrays;
+ std::vector<int> tempArrayId;
int clipVertexOutput;
if (prog->dbgFlags & NV50_IR_DEBUG_BASIC)
tgsi_dump(tokens, 0);
-
- mainTempsInLMem = false;
}
Source::~Source()
textureViews.resize(scan.file_max[TGSI_FILE_SAMPLER_VIEW] + 1);
//resources.resize(scan.file_max[TGSI_FILE_RESOURCE] + 1);
+ tempArrayId.resize(scan.file_max[TGSI_FILE_TEMPORARY] + 1);
info->immd.bufSize = 0;
}
tgsi_parse_free(&parse);
- if (mainTempsInLMem)
+ // TODO: Compute based on relevant array sizes
+ if (indirectTempArrays.size())
info->bin.tlsSpace += (scan.file_max[TGSI_FILE_TEMPORARY] + 1) * 16;
if (info->io.genUserClip > 0) {
unsigned sn = TGSI_SEMANTIC_GENERIC;
unsigned si = 0;
const unsigned first = decl->Range.First, last = decl->Range.Last;
+ const int arrayId = decl->Array.ArrayID;
if (decl->Declaration.Semantic) {
sn = decl->Semantic.Name;
for (i = first; i <= last; ++i)
textureViews[i].target = decl->SamplerView.Resource;
break;
- case TGSI_FILE_NULL:
case TGSI_FILE_TEMPORARY:
+ for (i = first; i <= last; ++i)
+ tempArrayId[i] = arrayId;
+ break;
+ case TGSI_FILE_NULL:
case TGSI_FILE_ADDRESS:
case TGSI_FILE_CONSTANT:
case TGSI_FILE_IMMEDIATE:
} else
if (insn.getDst(0).getFile() == TGSI_FILE_TEMPORARY) {
if (insn.getDst(0).isIndirect(0))
- mainTempsInLMem = true;
+ indirectTempArrays.insert(insn.getDst(0).getArrayId());
}
}
Instruction::SrcRegister src = insn.getSrc(s);
if (src.getFile() == TGSI_FILE_TEMPORARY) {
if (src.isIndirect(0))
- mainTempsInLMem = true;
+ indirectTempArrays.insert(src.getArrayId());
} else
/*
if (src.getFile() == TGSI_FILE_RESOURCE) {
DataType srcTy;
DataArray tData; // TGSI_FILE_TEMPORARY
+ DataArray lData; // TGSI_FILE_TEMPORARY, for indirect arrays
DataArray aData; // TGSI_FILE_ADDRESS
DataArray pData; // TGSI_FILE_PREDICATE
DataArray oData; // TGSI_FILE_OUTPUT (if outputs in registers)
{
switch (file) {
case TGSI_FILE_TEMPORARY:
- return &tData;
+ return idx == 0 ? &tData : &lData;
case TGSI_FILE_PREDICATE:
return &pData;
case TGSI_FILE_ADDRESS:
Value *
Converter::fetchSrc(tgsi::Instruction::SrcRegister src, int c, Value *ptr)
{
- const int idx2d = src.is2D() ? src.getIndex(1) : 0;
+ int idx2d = src.is2D() ? src.getIndex(1) : 0;
const int idx = src.getIndex(0);
const int swz = src.getSwizzle(c);
Instruction *ld;
ld = mkOp1(OP_RDSV, TYPE_U32, getSSA(), srcToSym(src, c));
ld->perPatch = info->sv[idx].patch;
return ld->getDef(0);
+ case TGSI_FILE_TEMPORARY: {
+ int arrayid = src.getArrayId();
+ if (!arrayid)
+ arrayid = code->tempArrayId[idx];
+ idx2d = (code->indirectTempArrays.find(arrayid) !=
+ code->indirectTempArrays.end());
+ }
+ /* fallthrough */
default:
return getArrayForFile(src.getFile(), idx2d)->load(
sub.cur->values, idx, swz, shiftAddress(ptr));
const tgsi::Instruction::DstRegister dst = tgsi.getDst(d);
const unsigned f = dst.getFile();
const int idx = dst.getIndex(0);
- const int idx2d = dst.is2D() ? dst.getIndex(1) : 0;
+ int idx2d = dst.is2D() ? dst.getIndex(1) : 0;
if (dst.isMasked(c)/* || f == TGSI_FILE_RESOURCE*/)
return NULL;
(f == TGSI_FILE_OUTPUT && prog->getType() != Program::TYPE_FRAGMENT))
return getScratch();
+ if (f == TGSI_FILE_TEMPORARY)
+ idx2d = code->indirectTempArrays.find(code->tempArrayId[idx]) !=
+ code->indirectTempArrays.end();
+
return getArrayForFile(f, idx2d)-> acquire(sub.cur->values, idx, c);
}
{
const unsigned f = dst.getFile();
const int idx = dst.getIndex(0);
- const int idx2d = dst.is2D() ? dst.getIndex(1) : 0;
+ int idx2d = dst.is2D() ? dst.getIndex(1) : 0;
if (f == TGSI_FILE_SYSTEM_VALUE) {
assert(!ptr);
f == TGSI_FILE_PREDICATE ||
f == TGSI_FILE_ADDRESS ||
f == TGSI_FILE_OUTPUT) {
+ if (f == TGSI_FILE_TEMPORARY)
+ idx2d = code->indirectTempArrays.find(code->tempArrayId[idx]) !=
+ code->indirectTempArrays.end();
+
getArrayForFile(f, idx2d)->store(sub.cur->values, idx, c, ptr, val);
} else {
assert(!"invalid dst file");
Converter::Converter(Program *ir, const tgsi::Source *code) : BuildUtil(ir),
code(code),
tgsi(NULL),
- tData(this), aData(this), pData(this), oData(this)
+ tData(this), lData(this), aData(this), pData(this), oData(this)
{
info = code->info;
- const DataFile tFile = code->mainTempsInLMem ? FILE_MEMORY_LOCAL : FILE_GPR;
-
const unsigned tSize = code->fileSize(TGSI_FILE_TEMPORARY);
const unsigned pSize = code->fileSize(TGSI_FILE_PREDICATE);
const unsigned aSize = code->fileSize(TGSI_FILE_ADDRESS);
const unsigned oSize = code->fileSize(TGSI_FILE_OUTPUT);
- tData.setup(TGSI_FILE_TEMPORARY, 0, 0, tSize, 4, 4, tFile, 0);
+ tData.setup(TGSI_FILE_TEMPORARY, 0, 0, tSize, 4, 4, FILE_GPR, 0);
+ lData.setup(TGSI_FILE_TEMPORARY, 1, 0, tSize, 4, 4, FILE_MEMORY_LOCAL, 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_GPR, 0);
oData.setup(TGSI_FILE_OUTPUT, 0, 0, oSize, 4, 4, FILE_GPR, 0);