struct {
int16_t maxGPR; /* may be -1 if none used */
- int16_t maxOutput;
uint32_t tlsSpace; /* required local memory per thread */
uint32_t smemSize; /* required shared memory per block */
uint32_t *code;
uint8_t numPatchConstants; /* also included in numInputs/numOutputs */
uint8_t numSysVals;
- struct {
- uint32_t *buf; /* for IMMEDIATE_ARRAY */
- uint16_t bufSize; /* size of immediate array */
- uint16_t count; /* count of inline immediates */
- uint32_t *data; /* inline immediate data */
- uint8_t *type; /* for each vec4 (128 bit) */
- } immd;
-
union {
struct {
- uint32_t inputMask[4]; /* mask of attributes read (1 bit per scalar) */
bool usesDrawParameters;
} vp;
struct {
uint8_t outputPrim; /* PIPE_PRIM_{TRIANGLES,LINES,POINTS} */
} tp;
struct {
- uint8_t inputPrim;
uint8_t outputPrim;
unsigned instanceCount;
unsigned maxVertices;
bool postDepthCoverage;
bool separateFragData;
bool usesDiscard;
- bool persampleInvocation;
bool usesSampleMaskIn;
bool readsFramebuffer;
bool readsSampleLocations;
} fp;
struct {
uint32_t inputOffset; /* base address for user args */
- uint32_t sharedOffset; /* reserved space in s[] */
uint32_t gridInfoBase; /* base address for NTID,NCTAID */
uint16_t numThreads[3]; /* max number of threads */
} cp;
uint16_t ucpBase; /* base address for UCPs */
uint16_t drawInfoBase; /* base address for draw parameters */
uint16_t alphaRefBase; /* base address for alpha test values */
- uint8_t pointSize; /* output index for PointSize */
uint8_t instanceId; /* system value index of InstanceID */
uint8_t vertexId; /* system value index of VertexID */
uint8_t edgeFlagIn;
int8_t viewportId; /* output index of ViewportIndex */
uint8_t fragDepth; /* output index of FragDepth */
uint8_t sampleMask; /* output index of SampleMask */
- uint8_t backFaceColor[2]; /* input/output indices of back face colour */
uint8_t globalAccess; /* 1 for read, 2 for wr, 3 for rw */
bool fp64; /* program uses fp64 math */
bool mul_zero_wins; /* program wants for x*0 = 0 */
return SrcRegister(fsr->Indirect);
}
- uint32_t getValueU32(int c, const struct nv50_ir_prog_info *info) const
+ uint32_t getValueU32(int c, const uint32_t *data) const
{
assert(reg.File == TGSI_FILE_IMMEDIATE);
assert(!reg.Absolute);
assert(!reg.Negate);
- return info->immd.data[reg.Index * 4 + getSwizzle(c)];
+ return data[reg.Index * 4 + getSwizzle(c)];
}
private:
class Source
{
public:
- Source(struct nv50_ir_prog_info *);
+ Source(struct nv50_ir_prog_info *, nv50_ir::Program *);
~Source();
public:
std::vector<bool> bufferAtomics;
+ struct {
+ uint16_t count; /* count of inline immediates */
+ uint32_t *data; /* inline immediate data */
+ } immd;
+
private:
+ nv50_ir::Program *prog;
int inferSysValDirection(unsigned sn) const;
bool scanDeclaration(const struct tgsi_full_declaration *);
bool scanInstruction(const struct tgsi_full_instruction *);
inline bool isEdgeFlagPassthrough(const Instruction&) const;
};
-Source::Source(struct nv50_ir_prog_info *prog) : info(prog)
+Source::Source(struct nv50_ir_prog_info *info, nv50_ir::Program *prog)
+: info(info), prog(prog)
{
tokens = (const struct tgsi_token *)info->bin.source;
- if (prog->dbgFlags & NV50_IR_DEBUG_BASIC)
+ if (info->dbgFlags & NV50_IR_DEBUG_BASIC)
tgsi_dump(tokens, 0);
+
+ immd.count = 0;
+ immd.data = (uint32_t *)MALLOC(scan.immediate_count * 16);
}
Source::~Source()
if (insns)
FREE(insns);
- if (info->immd.data)
- FREE(info->immd.data);
- if (info->immd.type)
- FREE(info->immd.type);
+ if (immd.data)
+ FREE(immd.data);
}
bool Source::scanSource()
memoryFiles.resize(scan.file_max[TGSI_FILE_MEMORY] + 1);
bufferAtomics.resize(scan.file_max[TGSI_FILE_BUFFER] + 1);
- info->immd.bufSize = 0;
-
info->numInputs = scan.file_max[TGSI_FILE_INPUT] + 1;
info->numOutputs = scan.file_max[TGSI_FILE_OUTPUT] + 1;
info->numSysVals = scan.file_max[TGSI_FILE_SYSTEM_VALUE] + 1;
info->io.viewportId = -1;
- info->immd.data = (uint32_t *)MALLOC(scan.immediate_count * 16);
- info->immd.type = (ubyte *)MALLOC(scan.immediate_count * sizeof(ubyte));
-
tgsi_parse_init(&parse, tokens);
while (!tgsi_parse_end_of_tokens(&parse)) {
tgsi_parse_token(&parse);
case TGSI_PROPERTY_GS_OUTPUT_PRIM:
info->prop.gp.outputPrim = prop->u[0].Data;
break;
- case TGSI_PROPERTY_GS_INPUT_PRIM:
- info->prop.gp.inputPrim = prop->u[0].Data;
- break;
case TGSI_PROPERTY_GS_MAX_OUTPUT_VERTICES:
info->prop.gp.maxVertices = prop->u[0].Data;
break;
void Source::scanImmediate(const struct tgsi_full_immediate *imm)
{
- const unsigned n = info->immd.count++;
+ const unsigned n = immd.count++;
assert(n < scan.immediate_count);
for (int c = 0; c < 4; ++c)
- info->immd.data[n * 4 + c] = imm->u[c].Uint;
-
- info->immd.type[n] = imm->Immediate.DataType;
+ immd.data[n * 4 + c] = imm->u[c].Uint;
}
int Source::inferSysValDirection(unsigned sn) const
break;
case TGSI_SEMANTIC_SAMPLEID:
case TGSI_SEMANTIC_SAMPLEPOS:
- info->prop.fp.persampleInvocation = true;
+ prog->persampleInvocation = true;
break;
case TGSI_SEMANTIC_SAMPLEMASK:
info->prop.fp.usesSampleMaskIn = true;
switch (src.getFile()) {
case TGSI_FILE_IMMEDIATE:
assert(!ptr);
- return loadImm(NULL, info->immd.data[idx * 4 + swz]);
+ return loadImm(NULL, code->immd.data[idx * 4 + swz]);
case TGSI_FILE_CONSTANT:
return mkLoadv(TYPE_U32, srcToSym(src, c), shiftAddress(ptr));
case TGSI_FILE_INPUT:
tgsi.getOpcode() == TGSI_OPCODE_TXP))
texi->tex.levelZero = true;
if (tgsi.getOpcode() == TGSI_OPCODE_TG4 && !tgt.isShadow())
- texi->tex.gatherComp = tgsi.getSrc(1).getValueU32(0, info);
+ texi->tex.gatherComp = tgsi.getSrc(1).getValueU32(0, code->immd.data);
texi->tex.useOffsets = tgsi.getNumTexOffsets();
for (s = 0; s < tgsi.getNumTexOffsets(); ++s) {
if (tgsi.getSrc(1).getFile() == TGSI_FILE_IMMEDIATE) {
off = NULL;
sym = makeSym(tgsi.getSrc(0).getFile(), r, -1, c,
- tgsi.getSrc(1).getValueU32(0, info) +
+ tgsi.getSrc(1).getValueU32(0, code->immd.data) +
src0_component_offset);
} else {
// yzw are ignored for buffers
if (tgsi.getSrc(0).getFile() == TGSI_FILE_IMMEDIATE) {
off = NULL;
sym = makeSym(tgsi.getDst(0).getFile(), r, -1, c,
- tgsi.getSrc(0).getValueU32(0, info) + 4 * c);
+ tgsi.getSrc(0).getValueU32(0, code->immd.data) + 4 * c);
} else {
// yzw are ignored for buffers
off = fetchSrc(0, 0);
Value *sym;
if (tgsi.getSrc(1).getFile() == TGSI_FILE_IMMEDIATE)
sym = makeSym(tgsi.getSrc(0).getFile(), r, -1, c,
- tgsi.getSrc(1).getValueU32(c, info));
+ tgsi.getSrc(1).getValueU32(c, code->immd.data));
else
sym = makeSym(tgsi.getSrc(0).getFile(), r, -1, c, 0);
if (subOp == NV50_IR_SUBOP_ATOM_CAS)
case TGSI_OPCODE_ENDPRIM:
{
// get vertex stream (must be immediate)
- unsigned int stream = tgsi.getSrc(0).getValueU32(0, info);
+ unsigned int stream = tgsi.getSrc(0).getValueU32(0, code->immd.data);
if (stream && op == OP_RESTART)
break;
if (info->prop.gp.maxVertices == 0)
break;
case TGSI_OPCODE_MEMBAR:
{
- uint32_t level = tgsi.getSrc(0).getValueU32(0, info);
+ uint32_t level = tgsi.getSrc(0).getValueU32(0, code->immd.data);
geni = mkOp(OP_MEMBAR, TYPE_NONE, NULL);
geni->fixed = 1;
if (!(level & ~(TGSI_MEMBAR_THREAD_GROUP | TGSI_MEMBAR_SHARED)))
val0 = getScratch();
if (tgsi.getSrc(1).getFile() == TGSI_FILE_IMMEDIATE &&
tgsi.getSrc(2).getFile() == TGSI_FILE_IMMEDIATE) {
- loadImm(val0, (tgsi.getSrc(2).getValueU32(c, info) << 8) |
- tgsi.getSrc(1).getValueU32(c, info));
+ loadImm(val0, (tgsi.getSrc(2).getValueU32(c, code->immd.data) << 8) |
+ tgsi.getSrc(1).getValueU32(c, code->immd.data));
} else {
src1 = fetchSrc(1, c);
src2 = fetchSrc(2, c);
bool
Program::makeFromTGSI(struct nv50_ir_prog_info *info)
{
- tgsi::Source src(info);
+ tgsi::Source src(info, this);
if (!src.scanSource())
return false;
tlsSize = info->bin.tlsSpace;