* OTHER DEALINGS IN THE SOFTWARE.
*/
+#include "tgsi/tgsi_build.h"
#include "tgsi/tgsi_dump.h"
#include "tgsi/tgsi_scan.h"
#include "tgsi/tgsi_util.h"
#include <set>
#include "codegen/nv50_ir.h"
+#include "codegen/nv50_ir_from_common.h"
#include "codegen/nv50_ir_util.h"
-#include "codegen/nv50_ir_build_util.h"
namespace tgsi {
return SrcRegister(fdr->Indirect);
}
+ struct tgsi_full_src_register asSrc()
+ {
+ assert(fdr);
+ return tgsi_full_src_register_from_dst(fdr);
+ }
+
int getArrayId() const
{
if (isIndirect(0))
nv50_ir::TexInstruction::Target getTexture(const Source *, int s) const;
+ const nv50_ir::TexInstruction::ImgFormatDesc *getImageFormat() const {
+ return &nv50_ir::TexInstruction::formatTable[
+ translateImgFormat(insn->Memory.Format)];
+ }
+
+ nv50_ir::TexTarget getImageTarget() const {
+ return translateTexture(insn->Memory.Texture);
+ }
+
nv50_ir::CacheMode getCacheMode() const {
if (!insn->Instruction.Memory)
return nv50_ir::CACHE_CA;
NV50_IR_OPCODE_CASE(ATOMUMAX, ATOM);
NV50_IR_OPCODE_CASE(ATOMIMIN, ATOM);
NV50_IR_OPCODE_CASE(ATOMIMAX, ATOM);
+ NV50_IR_OPCODE_CASE(ATOMFADD, ATOM);
NV50_IR_OPCODE_CASE(TEX2, TEX);
NV50_IR_OPCODE_CASE(TXB2, TXB);
case TGSI_OPCODE_ATOMIMIN: return NV50_IR_SUBOP_ATOM_MIN;
case TGSI_OPCODE_ATOMUMAX: return NV50_IR_SUBOP_ATOM_MAX;
case TGSI_OPCODE_ATOMIMAX: return NV50_IR_SUBOP_ATOM_MAX;
+ case TGSI_OPCODE_ATOMFADD: return NV50_IR_SUBOP_ATOM_ADD;
case TGSI_OPCODE_IMUL_HI:
case TGSI_OPCODE_UMUL_HI:
return NV50_IR_SUBOP_MUL_HIGH;
std::vector<Resource> resources;
*/
- struct Image {
- uint8_t target; // TGSI_TEXTURE_*
- bool raw;
- uint8_t slot;
- uint16_t format; // PIPE_FORMAT_*
- };
- std::vector<Image> images;
-
struct MemoryFile {
uint8_t mem_type; // TGSI_MEMORY_TYPE_*
};
std::vector<MemoryFile> memoryFiles;
+ std::vector<bool> bufferAtomics;
+
private:
int inferSysValDirection(unsigned sn) const;
bool scanDeclaration(const struct tgsi_full_declaration *);
textureViews.resize(scan.file_max[TGSI_FILE_SAMPLER_VIEW] + 1);
//resources.resize(scan.file_max[TGSI_FILE_RESOURCE] + 1);
- images.resize(scan.file_max[TGSI_FILE_IMAGE] + 1);
tempArrayId.resize(scan.file_max[TGSI_FILE_TEMPORARY] + 1);
memoryFiles.resize(scan.file_max[TGSI_FILE_MEMORY] + 1);
+ bufferAtomics.resize(scan.file_max[TGSI_FILE_BUFFER] + 1);
info->immd.bufSize = 0;
}
break;
*/
- case TGSI_FILE_IMAGE:
- for (i = first; i <= last; ++i) {
- images[i].target = decl->Image.Resource;
- images[i].raw = decl->Image.Raw;
- images[i].format = decl->Image.Format;
- images[i].slot = i;
- }
- break;
case TGSI_FILE_SAMPLER_VIEW:
for (i = first; i <= last; ++i)
textureViews[i].target = decl->SamplerView.Resource;
tempArrayInfo.insert(std::make_pair(arrayId, std::make_pair(
first, last - first + 1)));
break;
+ case TGSI_FILE_BUFFER:
+ for (i = first; i <= last; ++i)
+ bufferAtomics[i] = decl->Declaration.Atomic;
+ break;
case TGSI_FILE_ADDRESS:
case TGSI_FILE_CONSTANT:
case TGSI_FILE_IMMEDIATE:
case TGSI_FILE_SAMPLER:
- case TGSI_FILE_BUFFER:
+ case TGSI_FILE_IMAGE:
break;
default:
ERROR("unhandled TGSI_FILE %d\n", decl->Declaration.File);
if (src.isIndirect(0))
indirectTempArrays.insert(src.getArrayId());
} else
- if (src.getFile() == TGSI_FILE_BUFFER ||
- src.getFile() == TGSI_FILE_IMAGE ||
- (src.getFile() == TGSI_FILE_MEMORY &&
- memoryFiles[src.getIndex(0)].mem_type == TGSI_MEMORY_TYPE_GLOBAL)) {
- info->io.globalAccess |= (insn.getOpcode() == TGSI_OPCODE_LOAD) ?
- 0x1 : 0x2;
- } else
if (src.getFile() == TGSI_FILE_OUTPUT) {
if (src.isIndirect(0)) {
// We don't know which one is accessed, just mark everything for
info->out[src.getIndex(0)].oread = 1;
}
}
+ if (src.getFile() == TGSI_FILE_SYSTEM_VALUE) {
+ if (info->sv[src.getIndex(0)].sn == TGSI_SEMANTIC_SAMPLEPOS)
+ info->prop.fp.readsSampleLocations = true;
+ }
if (src.getFile() != TGSI_FILE_INPUT)
return;
if (insn.getOpcode() == TGSI_OPCODE_FBFETCH)
info->prop.fp.readsFramebuffer = true;
+ if (insn.getOpcode() == TGSI_OPCODE_INTERP_SAMPLE)
+ info->prop.fp.readsSampleLocations = true;
+
if (insn.dstCount()) {
Instruction::DstRegister dst = insn.getDst(0);
+ if (insn.getOpcode() == TGSI_OPCODE_STORE &&
+ dst.getFile() != TGSI_FILE_MEMORY) {
+ info->io.globalAccess |= 0x2;
+ }
+
if (dst.getFile() == TGSI_FILE_OUTPUT) {
if (dst.isIndirect(0))
for (unsigned i = 0; i < info->numOutputs; ++i)
}
}
+ if (insn.srcCount() && (
+ insn.getSrc(0).getFile() != TGSI_FILE_MEMORY ||
+ memoryFiles[insn.getSrc(0).getIndex(0)].mem_type ==
+ TGSI_MEMORY_TYPE_GLOBAL)) {
+ switch (insn.getOpcode()) {
+ case TGSI_OPCODE_ATOMUADD:
+ case TGSI_OPCODE_ATOMXCHG:
+ case TGSI_OPCODE_ATOMCAS:
+ case TGSI_OPCODE_ATOMAND:
+ case TGSI_OPCODE_ATOMOR:
+ case TGSI_OPCODE_ATOMXOR:
+ case TGSI_OPCODE_ATOMUMIN:
+ case TGSI_OPCODE_ATOMIMIN:
+ case TGSI_OPCODE_ATOMUMAX:
+ case TGSI_OPCODE_ATOMIMAX:
+ case TGSI_OPCODE_ATOMFADD:
+ case TGSI_OPCODE_LOAD:
+ info->io.globalAccess |= (insn.getOpcode() == TGSI_OPCODE_LOAD) ?
+ 0x1 : 0x2;
+ break;
+ }
+ }
+
+
for (unsigned s = 0; s < insn.srcCount(); ++s)
scanInstructionSrc(insn, insn.getSrc(s), insn.srcMask(s));
using namespace nv50_ir;
-class Converter : public BuildUtil
+class Converter : public ConverterCommon
{
public:
Converter(Program *, const tgsi::Source *);
bool run();
private:
- struct Subroutine
- {
- Subroutine(Function *f) : f(f) { }
- Function *f;
- ValueMap values;
- };
-
Value *shiftAddress(Value *);
Value *getVertexBase(int s);
Value *getOutputBase(int s);
DataArray *getArrayForFile(unsigned file, int idx);
Value *fetchSrc(int s, int c);
+ Value *fetchDst(int d, int c);
Value *acquireDst(int d, int c);
void storeDst(int d, int c, Value *);
bool handleInstruction(const struct tgsi_full_instruction *);
void exportOutputs();
- inline Subroutine *getSubroutine(unsigned ip);
- inline Subroutine *getSubroutine(Function *);
inline bool isEndOfSubroutine(uint ip);
void loadProjTexCoords(Value *dst[4], Value *src[4], unsigned int mask);
void handleTXQ(Value *dst0[4], enum TexQuery, int R);
void handleFBFETCH(Value *dst0[4]);
void handleLIT(Value *dst0[4]);
- void handleUserClipPlanes();
// Symbol *getResourceBase(int r);
- void getImageCoords(std::vector<Value *>&, int r, int s);
+ void getImageCoords(std::vector<Value *>&, int s);
void handleLOAD(Value *dst0[4]);
void handleSTORE();
void handleINTERP(Value *dst0[4]);
- uint8_t translateInterpMode(const struct nv50_ir_varying *var,
- operation& op);
Value *interpolate(tgsi::Instruction::SrcRegister, int c, Value *ptr);
void insertConvergenceOps(BasicBlock *conv, BasicBlock *fork);
private:
const tgsi::Source *code;
- const struct nv50_ir_prog_info *info;
-
- struct {
- std::map<unsigned, Subroutine> map;
- Subroutine *cur;
- } sub;
uint ip; // instruction pointer
DataArray oData; // TGSI_FILE_OUTPUT (if outputs in registers)
Value *zero;
- Value *fragCoord[4];
- Value *clipVtx[4];
Value *vtxBase[5]; // base address of vertex in primitive (for TP/GP)
uint8_t vtxBaseValid;
- Value *outBase; // base address of vertex out patch (for TCP)
-
Stack condBBs; // fork BB, then else clause BB
Stack joinBBs; // fork BB, for inserting join ops on ENDIF
Stack loopBBs; // loop headers
return sym;
}
-uint8_t
-Converter::translateInterpMode(const struct nv50_ir_varying *var, operation& op)
-{
- uint8_t mode = NV50_IR_INTERP_PERSPECTIVE;
-
- if (var->flat)
- mode = NV50_IR_INTERP_FLAT;
- else
- if (var->linear)
- mode = NV50_IR_INTERP_LINEAR;
- else
- if (var->sc)
- mode = NV50_IR_INTERP_SC;
-
- op = (mode == NV50_IR_INTERP_PERSPECTIVE || mode == NV50_IR_INTERP_SC)
- ? OP_PINTERP : OP_LINTERP;
-
- if (var->centroid)
- mode |= NV50_IR_INTERP_CENTROID;
-
- return mode;
-}
-
Value *
Converter::interpolate(tgsi::Instruction::SrcRegister src, int c, Value *ptr)
{
return applySrcMod(res, s, c);
}
+Value *
+Converter::fetchDst(int d, int c)
+{
+ Value *res;
+ Value *ptr = NULL, *dimRel = NULL;
+
+ tgsi::Instruction::DstRegister dst = tgsi.getDst(d);
+
+ if (dst.isIndirect(0))
+ ptr = fetchSrc(dst.getIndirect(0), 0, NULL);
+
+ if (dst.is2D()) {
+ switch (dst.getFile()) {
+ case TGSI_FILE_OUTPUT:
+ assert(0); // TODO
+ dimRel = NULL;
+ break;
+ case TGSI_FILE_INPUT:
+ assert(0); // TODO
+ dimRel = NULL;
+ break;
+ case TGSI_FILE_CONSTANT:
+ // on NVC0, this is valid and c{I+J}[k] == cI[(J << 16) + k]
+ if (dst.isIndirect(1))
+ dimRel = fetchSrc(dst.getIndirect(1), 0, 0);
+ break;
+ default:
+ break;
+ }
+ }
+
+ struct tgsi_full_src_register fsr = dst.asSrc();
+ tgsi::Instruction::SrcRegister src(&fsr);
+ res = fetchSrc(src, c, ptr);
+
+ if (dimRel)
+ res->getInsn()->setIndirect(0, 1, dimRel);
+
+ return res;
+}
+
Converter::DataArray *
Converter::getArrayForFile(unsigned file, int idx)
{
{
unsigned rIdx = 0, sIdx = 0;
+ if (R >= 0 && tgsi.getSrc(R).getFile() != TGSI_FILE_SAMPLER) {
+ // This is the bindless case. We have to get the actual value and pass
+ // it in. This will be the complete handle.
+ tex->tex.rIndirectSrc = s;
+ tex->setSrc(s++, fetchSrc(R, 0));
+ tex->setTexture(tgsi.getTexture(code, R), 0xff, 0x1f);
+ tex->tex.bindless = true;
+ return;
+ }
+
if (R >= 0)
rIdx = tgsi.getSrc(R).getIndex(0);
if (S >= 0)
coords[0] = mkOp1v(OP_MOV, TYPE_U32, getScratch(4, FILE_ADDRESS),
coords[0]);
}
-*/
+
static inline int
partitionLoadStore(uint8_t comp[2], uint8_t size[2], uint8_t mask)
{
}
return n + 1;
}
-
-static inline nv50_ir::TexTarget
-getImageTarget(const tgsi::Source *code, int r)
-{
- return tgsi::translateTexture(code->images.at(r).target);
-}
-
-static inline const nv50_ir::TexInstruction::ImgFormatDesc *
-getImageFormat(const tgsi::Source *code, int r)
-{
- return &nv50_ir::TexInstruction::formatTable[
- tgsi::translateImgFormat(code->images.at(r).format)];
-}
-
+*/
void
-Converter::getImageCoords(std::vector<Value *> &coords, int r, int s)
+Converter::getImageCoords(std::vector<Value *> &coords, int s)
{
TexInstruction::Target t =
- TexInstruction::Target(getImageTarget(code, r));
+ TexInstruction::Target(tgsi.getImageTarget());
const int arg = t.getDim() + (t.isArray() || t.isCube());
for (int c = 0; c < arg; ++c)
}
Instruction *ld = mkLoad(TYPE_U32, dst0[c], sym, off);
- ld->cache = tgsi.getCacheMode();
+ if (tgsi.getSrc(0).getFile() == TGSI_FILE_BUFFER &&
+ code->bufferAtomics[r])
+ ld->cache = nv50_ir::CACHE_CG;
+ else
+ ld->cache = tgsi.getCacheMode();
if (ind)
ld->setIndirect(0, 1, ind);
}
break;
- case TGSI_FILE_IMAGE: {
- assert(!code->images[r].raw);
-
- getImageCoords(off, r, 1);
+ default: {
+ getImageCoords(off, 1);
def.resize(4);
for (c = 0; c < 4; ++c) {
def[c] = dst0[c];
}
+ bool bindless = tgsi.getSrc(0).getFile() != TGSI_FILE_IMAGE;
+ if (bindless)
+ ind = fetchSrc(0, 0);
+
TexInstruction *ld =
- mkTex(OP_SULDP, getImageTarget(code, r), code->images[r].slot, 0,
- def, off);
+ mkTex(OP_SULDP, tgsi.getImageTarget(), 0, 0, def, off);
ld->tex.mask = tgsi.getDst(0).getMask();
- ld->tex.format = getImageFormat(code, r);
+ ld->tex.format = tgsi.getImageFormat();
ld->cache = tgsi.getCacheMode();
+ ld->tex.bindless = bindless;
+ if (!bindless)
+ ld->tex.r = r;
if (ind)
ld->setIndirectR(ind);
FOR_EACH_DST_ENABLED_CHANNEL(0, c, tgsi)
if (dst0[c] != def[c])
mkMov(dst0[c], def[tgsi.getSrc(0).getSwizzle(c)]);
- }
break;
- default:
- assert(!"Unsupported srcFile for LOAD");
}
+ }
+
/* Keep this around for now as reference when adding img support
getResourceCoords(off, r, 1);
st->setIndirect(0, 1, ind);
}
break;
- case TGSI_FILE_IMAGE: {
- assert(!code->images[r].raw);
-
- getImageCoords(off, r, 0);
+ default: {
+ getImageCoords(off, 0);
src = off;
FOR_EACH_DST_ENABLED_CHANNEL(0, c, tgsi)
src.push_back(fetchSrc(1, c));
+ bool bindless = tgsi.getDst(0).getFile() != TGSI_FILE_IMAGE;
+ if (bindless)
+ ind = fetchDst(0, 0);
+
TexInstruction *st =
- mkTex(OP_SUSTP, getImageTarget(code, r), code->images[r].slot,
- 0, dummy, src);
+ mkTex(OP_SUSTP, tgsi.getImageTarget(), 0, 0, dummy, src);
st->tex.mask = tgsi.getDst(0).getMask();
- st->tex.format = getImageFormat(code, r);
+ st->tex.format = tgsi.getImageFormat();
st->cache = tgsi.getCacheMode();
+ st->tex.bindless = bindless;
+ if (!bindless)
+ st->tex.r = r;
if (ind)
st->setIndirectR(ind);
- }
+
break;
- default:
- assert(!"Unsupported dstFile for STORE");
+ }
}
/* Keep this around for now as reference when adding img support
if (dst0[c])
dst0[c] = dst; // not equal to rDst so handleInstruction will do mkMov
break;
- case TGSI_FILE_IMAGE: {
- assert(!code->images[r].raw);
-
- getImageCoords(srcv, r, 1);
+ default: {
+ getImageCoords(srcv, 1);
defv.push_back(dst);
srcv.push_back(fetchSrc(2, 0));
if (subOp == NV50_IR_SUBOP_ATOM_CAS)
srcv.push_back(fetchSrc(3, 0));
- TexInstruction *tex = mkTex(OP_SUREDP, getImageTarget(code, r),
- code->images[r].slot, 0, defv, srcv);
+ bool bindless = tgsi.getSrc(0).getFile() != TGSI_FILE_IMAGE;
+ if (bindless)
+ ind = fetchSrc(0, 0);
+
+ TexInstruction *tex = mkTex(OP_SUREDP, tgsi.getImageTarget(),
+ 0, 0, defv, srcv);
tex->subOp = subOp;
tex->tex.mask = 1;
- tex->tex.format = getImageFormat(code, r);
+ tex->tex.format = tgsi.getImageFormat();
tex->setType(ty);
+ tex->tex.bindless = bindless;
+ if (!bindless)
+ tex->tex.r = r;
if (ind)
tex->setIndirectR(ind);
for (int c = 0; c < 4; ++c)
if (dst0[c])
dst0[c] = dst; // not equal to rDst so handleInstruction will do mkMov
- }
break;
- default:
- assert(!"Unsupported srcFile for ATOM");
+ }
}
/* Keep this around for now as reference when adding img support
assert(sym[c]);
op = insn->op;
mode = insn->ipa;
+ ptr = insn->getIndirect(0, 0);
}
} else {
if (src.isIndirect(0))
- ptr = fetchSrc(src.getIndirect(0), 0, NULL);
+ ptr = shiftAddress(fetchSrc(src.getIndirect(0), 0, NULL));
// We can assume that the fixed index will point to an input of the same
// interpolation type in case of an indirect.
insn = mkOp1(op, TYPE_F32, dst[c], sym[c] ? sym[c] : srcToSym(src, c));
if (op == OP_PINTERP)
insn->setSrc(1, w);
- if (ptr)
- insn->setIndirect(0, 0, ptr);
if (offset)
insn->setSrc(op == OP_PINTERP ? 2 : 1, offset);
+ if (ptr)
+ insn->setIndirect(0, 0, ptr);
insn->setInterpolate(mode);
}
}
-Converter::Subroutine *
-Converter::getSubroutine(unsigned ip)
-{
- std::map<unsigned, Subroutine>::iterator it = sub.map.find(ip);
-
- if (it == sub.map.end())
- it = sub.map.insert(std::make_pair(
- ip, Subroutine(new Function(prog, "SUB", ip)))).first;
-
- return &it->second;
-}
-
-Converter::Subroutine *
-Converter::getSubroutine(Function *f)
-{
- unsigned ip = f->getLabel();
- std::map<unsigned, Subroutine>::iterator it = sub.map.find(ip);
-
- if (it == sub.map.end())
- it = sub.map.insert(std::make_pair(ip, Subroutine(f))).first;
-
- return &it->second;
-}
-
bool
Converter::isEndOfSubroutine(uint ip)
{
unsigned int mask = tgsi.dstCount() ? tgsi.getDst(0).getMask() : 0;
- if (tgsi.dstCount()) {
+ if (tgsi.dstCount() && tgsi.getOpcode() != TGSI_OPCODE_STORE) {
for (c = 0; c < 4; ++c) {
rDst0[c] = acquireDst(0, c);
dst0[c] = (useScratchDst && rDst0[c]) ? getScratch() : rDst0[c];
info->out[info->io.viewportId].slot[0] * 4);
mkStore(OP_EXPORT, TYPE_U32, vpSym, NULL, viewport);
}
+ /* handle user clip planes for each emitted vertex */
+ if (info->io.genUserClip > 0)
+ handleUserClipPlanes();
/* fallthrough */
case TGSI_OPCODE_ENDPRIM:
{
setPosition(epilogue, true);
if (prog->getType() == Program::TYPE_FRAGMENT)
exportOutputs();
- if (info->io.genUserClip > 0)
+ if ((prog->getType() == Program::TYPE_VERTEX ||
+ prog->getType() == Program::TYPE_TESSELLATION_EVAL
+ ) && info->io.genUserClip > 0)
handleUserClipPlanes();
mkOp(OP_EXIT, TYPE_NONE, NULL)->terminator = 1;
}
case TGSI_OPCODE_ATOMIMIN:
case TGSI_OPCODE_ATOMUMAX:
case TGSI_OPCODE_ATOMIMAX:
+ case TGSI_OPCODE_ATOMFADD:
handleATOM(dst0, dstTy, tgsi::opcodeToSubOp(tgsi.getOpcode()));
break;
case TGSI_OPCODE_RESQ:
if (ind)
geni->setIndirect(0, 1, ind);
} else {
- assert(tgsi.getSrc(0).getFile() == TGSI_FILE_IMAGE);
-
TexInstruction *texi = new_TexInstruction(func, OP_SUQ);
for (int c = 0, d = 0; c < 4; ++c) {
if (dst0[c]) {
texi->tex.mask |= 1 << c;
}
}
- texi->tex.r = tgsi.getSrc(0).getIndex(0);
- texi->tex.target = getImageTarget(code, texi->tex.r);
-
- if (tgsi.getSrc(0).isIndirect(0))
- texi->setIndirectR(fetchSrc(tgsi.getSrc(0).getIndirect(0), 0, NULL));
+ if (tgsi.getSrc(0).getFile() == TGSI_FILE_IMAGE) {
+ texi->tex.r = tgsi.getSrc(0).getIndex(0);
+ if (tgsi.getSrc(0).isIndirect(0))
+ texi->setIndirectR(fetchSrc(tgsi.getSrc(0).getIndirect(0), 0, NULL));
+ } else {
+ texi->tex.bindless = true;
+ texi->setIndirectR(fetchSrc(0, 0));
+ }
+ texi->tex.target = tgsi.getImageTarget();
bb->insertTail(texi);
}
break;
}
- if (tgsi.dstCount()) {
+ if (tgsi.dstCount() && tgsi.getOpcode() != TGSI_OPCODE_STORE) {
for (c = 0; c < 4; ++c) {
if (!dst0[c])
continue;
return true;
}
-void
-Converter::handleUserClipPlanes()
-{
- Value *res[8];
- int n, i, c;
-
- for (c = 0; c < 4; ++c) {
- for (i = 0; i < info->io.genUserClip; ++i) {
- Symbol *sym = mkSymbol(FILE_MEMORY_CONST, info->io.auxCBSlot,
- TYPE_F32, info->io.ucpBase + i * 16 + c * 4);
- Value *ucp = mkLoadv(TYPE_F32, sym, NULL);
- if (c == 0)
- res[i] = mkOp2v(OP_MUL, TYPE_F32, getScratch(), clipVtx[c], ucp);
- else
- mkOp3(OP_MAD, TYPE_F32, res[i], clipVtx[c], ucp, res[i]);
- }
- }
-
- const int first = info->numOutputs - (info->io.genUserClip + 3) / 4;
-
- for (i = 0; i < info->io.genUserClip; ++i) {
- n = i / 4 + first;
- c = i % 4;
- Symbol *sym =
- mkSymbol(FILE_SHADER_OUTPUT, 0, TYPE_F32, info->out[n].slot[c] * 4);
- mkStore(OP_EXPORT, TYPE_F32, sym, NULL, res[i]);
- }
-}
-
void
Converter::exportOutputs()
{
}
}
-Converter::Converter(Program *ir, const tgsi::Source *code) : BuildUtil(ir),
+Converter::Converter(Program *ir, const tgsi::Source *code) : ConverterCommon(ir, code->info),
code(code),
tgsi(NULL),
tData(this), lData(this), aData(this), oData(this)
{
- info = code->info;
-
const unsigned tSize = code->fileSize(TGSI_FILE_TEMPORARY);
const unsigned aSize = code->fileSize(TGSI_FILE_ADDRESS);
const unsigned oSize = code->fileSize(TGSI_FILE_OUTPUT);