summaryrefslogtreecommitdiff
path: root/src/gallium/drivers/nouveau/codegen/nv50_ir_from_tgsi.cpp
diff options
context:
space:
mode:
authorKarol Herbst <kherbst@redhat.com>2019-07-04 16:02:09 +0200
committerMarge Bot <eric+marge@anholt.net>2020-08-25 18:56:37 +0000
commitf2924994bd3e0389446c2ca6bc23d4712a7742de (patch)
tree68e0ec3f462cf5c35aa9c4525e73da63d97984ac /src/gallium/drivers/nouveau/codegen/nv50_ir_from_tgsi.cpp
parentfa8e62824075d8481d1e63ff057be7cd966c4149 (diff)
nv50/ir: add nv50_ir_prog_info_out
Split out the output relevant fields from the nv50_ir_prog_info struct in order to have a cleaner separation between the input and output of the compilation. Signed-off-by: Karol Herbst <kherbst@redhat.com> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/4264>
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.cpp261
1 files changed, 132 insertions, 129 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 5d396035c1a..f799a4d5659 100644
--- a/src/gallium/drivers/nouveau/codegen/nv50_ir_from_tgsi.cpp
+++ b/src/gallium/drivers/nouveau/codegen/nv50_ir_from_tgsi.cpp
@@ -986,7 +986,7 @@ bool Instruction::checkDstSrcAliasing() const
class Source
{
public:
- Source(struct nv50_ir_prog_info *, nv50_ir::Program *);
+ Source(struct nv50_ir_prog_info *, struct nv50_ir_prog_info_out *, nv50_ir::Program *);
~Source();
public:
@@ -998,6 +998,7 @@ public:
struct tgsi_full_instruction *insns;
const struct tgsi_token *tokens;
struct nv50_ir_prog_info *info;
+ struct nv50_ir_prog_info_out *info_out;
nv50_ir::DynArray tempArrays;
nv50_ir::DynArray immdArrays;
@@ -1053,8 +1054,9 @@ private:
inline bool isEdgeFlagPassthrough(const Instruction&) const;
};
-Source::Source(struct nv50_ir_prog_info *info, nv50_ir::Program *prog)
-: info(info), prog(prog)
+Source::Source(struct nv50_ir_prog_info *info, struct nv50_ir_prog_info_out *info_out,
+ nv50_ir::Program *prog)
+: info(info), info_out(info_out), prog(prog)
{
tokens = (const struct tgsi_token *)info->bin.source;
@@ -1094,16 +1096,16 @@ bool Source::scanSource()
memoryFiles.resize(scan.file_max[TGSI_FILE_MEMORY] + 1);
bufferAtomics.resize(scan.file_max[TGSI_FILE_BUFFER] + 1);
- 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_out->numInputs = scan.file_max[TGSI_FILE_INPUT] + 1;
+ info_out->numOutputs = scan.file_max[TGSI_FILE_OUTPUT] + 1;
+ info_out->numSysVals = scan.file_max[TGSI_FILE_SYSTEM_VALUE] + 1;
if (info->type == PIPE_SHADER_FRAGMENT) {
- info->prop.fp.writesDepth = scan.writes_z;
- info->prop.fp.usesDiscard = scan.uses_kill || info->io.alphaRefBase;
+ info_out->prop.fp.writesDepth = scan.writes_z;
+ info_out->prop.fp.usesDiscard = scan.uses_kill || info->io.alphaRefBase;
} else
if (info->type == PIPE_SHADER_GEOMETRY) {
- info->prop.gp.instanceCount = 1; // default value
+ info_out->prop.gp.instanceCount = 1; // default value
}
info->io.viewportId = -1;
@@ -1141,40 +1143,40 @@ bool Source::scanSource()
indirectTempOffsets.insert(std::make_pair(*it, tempBase - info.first));
tempBase += info.second;
}
- info->bin.tlsSpace += tempBase * 16;
+ info_out->bin.tlsSpace += tempBase * 16;
}
- if (info->io.genUserClip > 0) {
- info->io.clipDistances = info->io.genUserClip;
+ if (info_out->io.genUserClip > 0) {
+ info_out->io.clipDistances = info_out->io.genUserClip;
- const unsigned int nOut = (info->io.genUserClip + 3) / 4;
+ const unsigned int nOut = (info_out->io.genUserClip + 3) / 4;
for (unsigned int n = 0; n < nOut; ++n) {
- unsigned int i = info->numOutputs++;
- info->out[i].id = i;
- info->out[i].sn = TGSI_SEMANTIC_CLIPDIST;
- info->out[i].si = n;
- info->out[i].mask = ((1 << info->io.clipDistances) - 1) >> (n * 4);
+ unsigned int i = info_out->numOutputs++;
+ info_out->out[i].id = i;
+ info_out->out[i].sn = TGSI_SEMANTIC_CLIPDIST;
+ info_out->out[i].si = n;
+ info_out->out[i].mask = ((1 << info_out->io.clipDistances) - 1) >> (n * 4);
}
}
- return info->assignSlots(info) == 0;
+ return info->assignSlots(info_out) == 0;
}
void Source::scanProperty(const struct tgsi_full_property *prop)
{
switch (prop->Property.PropertyName) {
case TGSI_PROPERTY_GS_OUTPUT_PRIM:
- info->prop.gp.outputPrim = prop->u[0].Data;
+ info_out->prop.gp.outputPrim = prop->u[0].Data;
break;
case TGSI_PROPERTY_GS_MAX_OUTPUT_VERTICES:
- info->prop.gp.maxVertices = prop->u[0].Data;
+ info_out->prop.gp.maxVertices = prop->u[0].Data;
break;
case TGSI_PROPERTY_GS_INVOCATIONS:
- info->prop.gp.instanceCount = prop->u[0].Data;
+ info_out->prop.gp.instanceCount = prop->u[0].Data;
break;
case TGSI_PROPERTY_FS_COLOR0_WRITES_ALL_CBUFS:
- info->prop.fp.separateFragData = true;
+ info_out->prop.fp.separateFragData = true;
break;
case TGSI_PROPERTY_FS_COORD_ORIGIN:
case TGSI_PROPERTY_FS_COORD_PIXEL_CENTER:
@@ -1183,25 +1185,25 @@ void Source::scanProperty(const struct tgsi_full_property *prop)
// we don't care
break;
case TGSI_PROPERTY_VS_PROHIBIT_UCPS:
- info->io.genUserClip = -1;
+ info_out->io.genUserClip = -1;
break;
case TGSI_PROPERTY_TCS_VERTICES_OUT:
- info->prop.tp.outputPatchSize = prop->u[0].Data;
+ info_out->prop.tp.outputPatchSize = prop->u[0].Data;
break;
case TGSI_PROPERTY_TES_PRIM_MODE:
- info->prop.tp.domain = prop->u[0].Data;
+ info_out->prop.tp.domain = prop->u[0].Data;
break;
case TGSI_PROPERTY_TES_SPACING:
- info->prop.tp.partitioning = prop->u[0].Data;
+ info_out->prop.tp.partitioning = prop->u[0].Data;
break;
case TGSI_PROPERTY_TES_VERTEX_ORDER_CW:
- info->prop.tp.winding = prop->u[0].Data;
+ info_out->prop.tp.winding = prop->u[0].Data;
break;
case TGSI_PROPERTY_TES_POINT_MODE:
if (prop->u[0].Data)
- info->prop.tp.outputPrim = PIPE_PRIM_POINTS;
+ info_out->prop.tp.outputPrim = PIPE_PRIM_POINTS;
else
- info->prop.tp.outputPrim = PIPE_PRIM_TRIANGLES; /* anything but points */
+ info_out->prop.tp.outputPrim = PIPE_PRIM_TRIANGLES; /* anything but points */
break;
case TGSI_PROPERTY_CS_FIXED_BLOCK_WIDTH:
info->prop.cp.numThreads[0] = prop->u[0].Data;
@@ -1213,25 +1215,25 @@ void Source::scanProperty(const struct tgsi_full_property *prop)
info->prop.cp.numThreads[2] = prop->u[0].Data;
break;
case TGSI_PROPERTY_NUM_CLIPDIST_ENABLED:
- info->io.clipDistances = prop->u[0].Data;
+ info_out->io.clipDistances = prop->u[0].Data;
break;
case TGSI_PROPERTY_NUM_CULLDIST_ENABLED:
- info->io.cullDistances = prop->u[0].Data;
+ info_out->io.cullDistances = prop->u[0].Data;
break;
case TGSI_PROPERTY_NEXT_SHADER:
/* Do not need to know the next shader stage. */
break;
case TGSI_PROPERTY_FS_EARLY_DEPTH_STENCIL:
- info->prop.fp.earlyFragTests = prop->u[0].Data;
+ info_out->prop.fp.earlyFragTests = prop->u[0].Data;
break;
case TGSI_PROPERTY_FS_POST_DEPTH_COVERAGE:
- info->prop.fp.postDepthCoverage = prop->u[0].Data;
+ info_out->prop.fp.postDepthCoverage = prop->u[0].Data;
break;
case TGSI_PROPERTY_MUL_ZERO_WINS:
info->io.mul_zero_wins = prop->u[0].Data;
break;
case TGSI_PROPERTY_LAYER_VIEWPORT_RELATIVE:
- info->io.layer_viewport_relative = prop->u[0].Data;
+ info_out->io.layer_viewport_relative = prop->u[0].Data;
break;
default:
INFO("unhandled TGSI property %d\n", prop->Property.PropertyName);
@@ -1294,37 +1296,37 @@ bool Source::scanDeclaration(const struct tgsi_full_declaration *decl)
if (info->type == PIPE_SHADER_VERTEX) {
// all vertex attributes are equal
for (i = first; i <= last; ++i) {
- info->in[i].sn = TGSI_SEMANTIC_GENERIC;
- info->in[i].si = i;
+ info_out->in[i].sn = TGSI_SEMANTIC_GENERIC;
+ info_out->in[i].si = i;
}
} else {
for (i = first; i <= last; ++i, ++si) {
- info->in[i].id = i;
- info->in[i].sn = sn;
- info->in[i].si = si;
+ info_out->in[i].id = i;
+ info_out->in[i].sn = sn;
+ info_out->in[i].si = si;
if (info->type == PIPE_SHADER_FRAGMENT) {
// translate interpolation mode
switch (decl->Interp.Interpolate) {
case TGSI_INTERPOLATE_CONSTANT:
- info->in[i].flat = 1;
+ info_out->in[i].flat = 1;
break;
case TGSI_INTERPOLATE_COLOR:
- info->in[i].sc = 1;
+ info_out->in[i].sc = 1;
break;
case TGSI_INTERPOLATE_LINEAR:
- info->in[i].linear = 1;
+ info_out->in[i].linear = 1;
break;
default:
break;
}
if (decl->Interp.Location)
- info->in[i].centroid = 1;
+ info_out->in[i].centroid = 1;
}
if (sn == TGSI_SEMANTIC_PATCH)
- info->in[i].patch = 1;
+ info_out->in[i].patch = 1;
if (sn == TGSI_SEMANTIC_PATCH)
- info->numPatchConstants = MAX2(info->numPatchConstants, si + 1);
+ info_out->numPatchConstants = MAX2(info_out->numPatchConstants, si + 1);
}
}
break;
@@ -1333,77 +1335,77 @@ bool Source::scanDeclaration(const struct tgsi_full_declaration *decl)
switch (sn) {
case TGSI_SEMANTIC_POSITION:
if (info->type == PIPE_SHADER_FRAGMENT)
- info->io.fragDepth = i;
+ info_out->io.fragDepth = i;
else
if (clipVertexOutput < 0)
clipVertexOutput = i;
break;
case TGSI_SEMANTIC_COLOR:
if (info->type == PIPE_SHADER_FRAGMENT)
- info->prop.fp.numColourResults++;
+ info_out->prop.fp.numColourResults++;
break;
case TGSI_SEMANTIC_EDGEFLAG:
- info->io.edgeFlagOut = i;
+ info_out->io.edgeFlagOut = i;
break;
case TGSI_SEMANTIC_CLIPVERTEX:
clipVertexOutput = i;
break;
case TGSI_SEMANTIC_CLIPDIST:
- info->io.genUserClip = -1;
+ info_out->io.genUserClip = -1;
break;
case TGSI_SEMANTIC_SAMPLEMASK:
- info->io.sampleMask = i;
+ info_out->io.sampleMask = i;
break;
case TGSI_SEMANTIC_VIEWPORT_INDEX:
info->io.viewportId = i;
break;
case TGSI_SEMANTIC_PATCH:
- info->numPatchConstants = MAX2(info->numPatchConstants, si + 1);
+ info_out->numPatchConstants = MAX2(info_out->numPatchConstants, si + 1);
/* fallthrough */
case TGSI_SEMANTIC_TESSOUTER:
case TGSI_SEMANTIC_TESSINNER:
- info->out[i].patch = 1;
+ info_out->out[i].patch = 1;
break;
default:
break;
}
- info->out[i].id = i;
- info->out[i].sn = sn;
- info->out[i].si = si;
+ info_out->out[i].id = i;
+ info_out->out[i].sn = sn;
+ info_out->out[i].si = si;
}
break;
case TGSI_FILE_SYSTEM_VALUE:
switch (sn) {
case TGSI_SEMANTIC_INSTANCEID:
- info->io.instanceId = first;
+ info_out->io.instanceId = first;
break;
case TGSI_SEMANTIC_VERTEXID:
- info->io.vertexId = first;
+ info_out->io.vertexId = first;
break;
case TGSI_SEMANTIC_BASEVERTEX:
case TGSI_SEMANTIC_BASEINSTANCE:
case TGSI_SEMANTIC_DRAWID:
- info->prop.vp.usesDrawParameters = true;
+ info_out->prop.vp.usesDrawParameters = true;
break;
case TGSI_SEMANTIC_SAMPLEID:
case TGSI_SEMANTIC_SAMPLEPOS:
prog->persampleInvocation = true;
break;
case TGSI_SEMANTIC_SAMPLEMASK:
- info->prop.fp.usesSampleMaskIn = true;
+ info_out->prop.fp.usesSampleMaskIn = true;
break;
default:
break;
}
for (i = first; i <= last; ++i, ++si) {
- info->sv[i].sn = sn;
- info->sv[i].si = si;
- info->sv[i].input = inferSysValDirection(sn);
+ info_out->sv[i].sn = sn;
+ info_out->sv[i].si = si;
+ info_out->sv[i].input = inferSysValDirection(sn);
switch (sn) {
case TGSI_SEMANTIC_TESSOUTER:
case TGSI_SEMANTIC_TESSINNER:
- info->sv[i].patch = 1;
+ info_out->sv[i].patch = 1;
break;
}
}
@@ -1453,7 +1455,7 @@ bool Source::scanDeclaration(const struct tgsi_full_declaration *decl)
inline bool Source::isEdgeFlagPassthrough(const Instruction& insn) const
{
return insn.getOpcode() == TGSI_OPCODE_MOV &&
- insn.getDst(0).getIndex(0) == info->io.edgeFlagOut &&
+ insn.getDst(0).getIndex(0) == info_out->io.edgeFlagOut &&
insn.getSrc(0).getFile() == TGSI_FILE_INPUT;
}
@@ -1469,22 +1471,22 @@ void Source::scanInstructionSrc(const Instruction& insn,
if (src.isIndirect(0)) {
// We don't know which one is accessed, just mark everything for
// reading. This is an extremely unlikely occurrence.
- for (unsigned i = 0; i < info->numOutputs; ++i)
- info->out[i].oread = 1;
+ for (unsigned i = 0; i < info_out->numOutputs; ++i)
+ info_out->out[i].oread = 1;
} else {
- info->out[src.getIndex(0)].oread = 1;
+ info_out->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 (info_out->sv[src.getIndex(0)].sn == TGSI_SEMANTIC_SAMPLEPOS)
+ info_out->prop.fp.readsSampleLocations = true;
}
if (src.getFile() != TGSI_FILE_INPUT)
return;
if (src.isIndirect(0)) {
- for (unsigned i = 0; i < info->numInputs; ++i)
- info->in[i].mask = 0xf;
+ for (unsigned i = 0; i < info_out->numInputs; ++i)
+ info_out->in[i].mask = 0xf;
} else {
const int i = src.getIndex(0);
for (unsigned c = 0; c < 4; ++c) {
@@ -1492,16 +1494,16 @@ void Source::scanInstructionSrc(const Instruction& insn,
continue;
int k = src.getSwizzle(c);
if (k <= TGSI_SWIZZLE_W)
- info->in[i].mask |= 1 << k;
+ info_out->in[i].mask |= 1 << k;
}
- switch (info->in[i].sn) {
+ switch (info_out->in[i].sn) {
case TGSI_SEMANTIC_PSIZE:
case TGSI_SEMANTIC_PRIMID:
case TGSI_SEMANTIC_FOG:
- info->in[i].mask &= 0x1;
+ info_out->in[i].mask &= 0x1;
break;
case TGSI_SEMANTIC_PCOORD:
- info->in[i].mask &= 0x3;
+ info_out->in[i].mask &= 0x3;
break;
default:
break;
@@ -1514,48 +1516,47 @@ bool Source::scanInstruction(const struct tgsi_full_instruction *inst)
Instruction insn(inst);
if (insn.getOpcode() == TGSI_OPCODE_BARRIER)
- info->numBarriers = 1;
+ info_out->numBarriers = 1;
if (insn.getOpcode() == TGSI_OPCODE_FBFETCH)
- info->prop.fp.readsFramebuffer = true;
+ info_out->prop.fp.readsFramebuffer = true;
if (insn.getOpcode() == TGSI_OPCODE_INTERP_SAMPLE)
- info->prop.fp.readsSampleLocations = true;
+ info_out->prop.fp.readsSampleLocations = true;
if (insn.getOpcode() == TGSI_OPCODE_DEMOTE)
- info->prop.fp.usesDiscard = true;
+ info_out->prop.fp.usesDiscard = 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;
+ info_out->io.globalAccess |= 0x2;
if (dst.getFile() == TGSI_FILE_INPUT) {
// TODO: Handle indirect somehow?
const int i = dst.getIndex(0);
- info->in[i].mask |= 1;
+ info_out->in[i].mask |= 1;
}
}
if (dst.getFile() == TGSI_FILE_OUTPUT) {
if (dst.isIndirect(0))
- for (unsigned i = 0; i < info->numOutputs; ++i)
- info->out[i].mask = 0xf;
+ for (unsigned i = 0; i < info_out->numOutputs; ++i)
+ info_out->out[i].mask = 0xf;
else
- info->out[dst.getIndex(0)].mask |= dst.getMask();
+ info_out->out[dst.getIndex(0)].mask |= dst.getMask();
- if (info->out[dst.getIndex(0)].sn == TGSI_SEMANTIC_PSIZE ||
- info->out[dst.getIndex(0)].sn == TGSI_SEMANTIC_PRIMID ||
- info->out[dst.getIndex(0)].sn == TGSI_SEMANTIC_LAYER ||
- info->out[dst.getIndex(0)].sn == TGSI_SEMANTIC_VIEWPORT_INDEX ||
- info->out[dst.getIndex(0)].sn == TGSI_SEMANTIC_VIEWPORT_MASK ||
- info->out[dst.getIndex(0)].sn == TGSI_SEMANTIC_FOG)
- info->out[dst.getIndex(0)].mask &= 1;
+ if (info_out->out[dst.getIndex(0)].sn == TGSI_SEMANTIC_PSIZE ||
+ info_out->out[dst.getIndex(0)].sn == TGSI_SEMANTIC_PRIMID ||
+ info_out->out[dst.getIndex(0)].sn == TGSI_SEMANTIC_LAYER ||
+ info_out->out[dst.getIndex(0)].sn == TGSI_SEMANTIC_VIEWPORT_INDEX ||
+ info_out->out[dst.getIndex(0)].sn == TGSI_SEMANTIC_FOG)
+ info_out->out[dst.getIndex(0)].mask &= 1;
if (isEdgeFlagPassthrough(insn))
- info->io.edgeFlagIn = insn.getSrc(0).getIndex(0);
+ info_out->io.edgeFlagIn = insn.getSrc(0).getIndex(0);
} else
if (dst.getFile() == TGSI_FILE_TEMPORARY) {
if (dst.isIndirect(0))
@@ -1565,7 +1566,7 @@ bool Source::scanInstruction(const struct tgsi_full_instruction *inst)
dst.getFile() == TGSI_FILE_IMAGE ||
(dst.getFile() == TGSI_FILE_MEMORY &&
memoryFiles[dst.getIndex(0)].mem_type == TGSI_MEMORY_TYPE_GLOBAL)) {
- info->io.globalAccess |= 0x2;
+ info_out->io.globalAccess |= 0x2;
}
}
@@ -1588,7 +1589,7 @@ bool Source::scanInstruction(const struct tgsi_full_instruction *inst)
case TGSI_OPCODE_ATOMDEC_WRAP:
case TGSI_OPCODE_ATOMINC_WRAP:
case TGSI_OPCODE_LOAD:
- info->io.globalAccess |= (insn.getOpcode() == TGSI_OPCODE_LOAD) ?
+ info_out->io.globalAccess |= (insn.getOpcode() == TGSI_OPCODE_LOAD) ?
0x1 : 0x2;
break;
}
@@ -1633,7 +1634,7 @@ using namespace nv50_ir;
class Converter : public ConverterCommon
{
public:
- Converter(Program *, const tgsi::Source *);
+ Converter(Program *, const tgsi::Source *, nv50_ir_prog_info_out *);
~Converter();
bool run();
@@ -1792,13 +1793,13 @@ Converter::makeSym(uint tgsiFile, int fileIdx, int idx, int c, uint32_t address)
if (idx >= 0) {
if (sym->reg.file == FILE_SHADER_INPUT)
- sym->setOffset(info->in[idx].slot[c] * 4);
+ sym->setOffset(info_out->in[idx].slot[c] * 4);
else
if (sym->reg.file == FILE_SHADER_OUTPUT)
- sym->setOffset(info->out[idx].slot[c] * 4);
+ sym->setOffset(info_out->out[idx].slot[c] * 4);
else
if (sym->reg.file == FILE_SYSTEM_VALUE)
- sym->setSV(tgsi::translateSysVal(info->sv[idx].sn), c);
+ sym->setSV(tgsi::translateSysVal(info_out->sv[idx].sn), c);
else
sym->setOffset(address);
} else {
@@ -1813,7 +1814,7 @@ Converter::interpolate(tgsi::Instruction::SrcRegister src, int c, Value *ptr)
operation op;
// XXX: no way to know interpolation mode if we don't know what's accessed
- const uint8_t mode = translateInterpMode(&info->in[ptr ? 0 :
+ const uint8_t mode = translateInterpMode(&info_out->in[ptr ? 0 :
src.getIndex(0)], op);
Instruction *insn = new_Instruction(func, op, TYPE_F32);
@@ -2025,12 +2026,12 @@ Converter::fetchSrc(tgsi::Instruction::SrcRegister src, int c, Value *ptr)
case TGSI_FILE_INPUT:
if (prog->getType() == Program::TYPE_FRAGMENT) {
// don't load masked inputs, won't be assigned a slot
- if (!ptr && !(info->in[idx].mask & (1 << swz)))
+ if (!ptr && !(info_out->in[idx].mask & (1 << swz)))
return loadImm(NULL, swz == TGSI_SWIZZLE_W ? 1.0f : 0.0f);
return interpolate(src, c, shiftAddress(ptr));
} else
if (prog->getType() == Program::TYPE_GEOMETRY) {
- if (!ptr && info->in[idx].sn == TGSI_SEMANTIC_PRIMID)
+ if (!ptr && info_out->in[idx].sn == TGSI_SEMANTIC_PRIMID)
return mkOp1v(OP_RDSV, TYPE_U32, getSSA(), mkSysVal(SV_PRIMITIVE_ID, 0));
// 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.
@@ -2041,24 +2042,24 @@ Converter::fetchSrc(tgsi::Instruction::SrcRegister src, int c, Value *ptr)
return mkLoadv(TYPE_U32, srcToSym(src, c), ptr);
}
ld = mkLoad(TYPE_U32, getSSA(), srcToSym(src, c), shiftAddress(ptr));
- ld->perPatch = info->in[idx].patch;
+ ld->perPatch = info_out->in[idx].patch;
return ld->getDef(0);
case TGSI_FILE_OUTPUT:
assert(prog->getType() == Program::TYPE_TESSELLATION_CONTROL);
ld = mkLoad(TYPE_U32, getSSA(), srcToSym(src, c), shiftAddress(ptr));
- ld->perPatch = info->out[idx].patch;
+ ld->perPatch = info_out->out[idx].patch;
return ld->getDef(0);
case TGSI_FILE_SYSTEM_VALUE:
assert(!ptr);
- if (info->sv[idx].sn == TGSI_SEMANTIC_THREAD_ID &&
+ if (info_out->sv[idx].sn == TGSI_SEMANTIC_THREAD_ID &&
info->prop.cp.numThreads[swz] == 1)
return loadImm(NULL, 0u);
- if (isSubGroupMask(info->sv[idx].sn) && swz > 0)
+ if (isSubGroupMask(info_out->sv[idx].sn) && swz > 0)
return loadImm(NULL, 0u);
- if (info->sv[idx].sn == TGSI_SEMANTIC_SUBGROUP_SIZE)
+ if (info_out->sv[idx].sn == TGSI_SEMANTIC_SUBGROUP_SIZE)
return loadImm(NULL, 32u);
ld = mkOp1(OP_RDSV, TYPE_U32, getSSA(), srcToSym(src, c));
- ld->perPatch = info->sv[idx].patch;
+ ld->perPatch = info_out->sv[idx].patch;
return ld->getDef(0);
case TGSI_FILE_TEMPORARY: {
int arrayid = src.getArrayId();
@@ -2113,7 +2114,7 @@ Converter::storeDst(int d, int c, Value *val)
if (dst.isIndirect(0))
ptr = shiftAddress(fetchSrc(dst.getIndirect(0), 0, NULL));
- if (info->io.genUserClip > 0 &&
+ if (info_out->io.genUserClip > 0 &&
dst.getFile() == TGSI_FILE_OUTPUT &&
!dst.isIndirect(0) && dst.getIndex(0) == code->clipVertexOutput) {
mkMov(clipVtx[c], val);
@@ -2137,16 +2138,16 @@ Converter::storeDst(const tgsi::Instruction::DstRegister dst, int c,
} else
if (f == TGSI_FILE_OUTPUT && prog->getType() != Program::TYPE_FRAGMENT) {
- if (ptr || (info->out[idx].mask & (1 << c))) {
+ if (ptr || (info_out->out[idx].mask & (1 << c))) {
/* Save the viewport index into a scratch register so that it can be
exported at EMIT time */
- if (info->out[idx].sn == TGSI_SEMANTIC_VIEWPORT_INDEX &&
+ if (info_out->out[idx].sn == TGSI_SEMANTIC_VIEWPORT_INDEX &&
prog->getType() == Program::TYPE_GEOMETRY &&
viewport != NULL)
mkOp1(OP_MOV, TYPE_U32, viewport, val);
else
mkStore(OP_EXPORT, TYPE_U32, dstToSym(dst, c), ptr, val)->perPatch =
- info->out[idx].patch;
+ info_out->out[idx].patch;
}
} else
if (f == TGSI_FILE_TEMPORARY ||
@@ -3033,7 +3034,7 @@ Converter::handleINTERP(Value *dst[4])
// We can assume that the fixed index will point to an input of the same
// interpolation type in case of an indirect.
// TODO: Make use of ArrayID.
- linear = info->in[src.getIndex(0)].linear;
+ linear = info_out->in[src.getIndex(0)].linear;
if (linear) {
op = OP_LINTERP;
mode = NV50_IR_INTERP_LINEAR;
@@ -3526,11 +3527,11 @@ Converter::handleInstruction(const struct tgsi_full_instruction *insn)
/* export the saved viewport index */
if (viewport != NULL) {
Symbol *vpSym = mkSymbol(FILE_SHADER_OUTPUT, 0, TYPE_U32,
- info->out[info->io.viewportId].slot[0] * 4);
+ info_out->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)
+ if (info_out->io.genUserClip > 0)
handleUserClipPlanes();
/* fallthrough */
case TGSI_OPCODE_ENDPRIM:
@@ -3539,7 +3540,7 @@ Converter::handleInstruction(const struct tgsi_full_instruction *insn)
unsigned int stream = tgsi.getSrc(0).getValueU32(0, code->immd.data);
if (stream && op == OP_RESTART)
break;
- if (info->prop.gp.maxVertices == 0)
+ if (info_out->prop.gp.maxVertices == 0)
break;
src0 = mkImm(stream);
mkOp1(op, TYPE_U32, NULL, src0)->fixed = 1;
@@ -3708,7 +3709,7 @@ Converter::handleInstruction(const struct tgsi_full_instruction *insn)
exportOutputs();
if ((prog->getType() == Program::TYPE_VERTEX ||
prog->getType() == Program::TYPE_TESSELLATION_EVAL
- ) && info->io.genUserClip > 0)
+ ) && info_out->io.genUserClip > 0)
handleUserClipPlanes();
mkOp(OP_EXIT, TYPE_NONE, NULL)->terminator = 1;
}
@@ -4154,9 +4155,9 @@ void
Converter::exportOutputs()
{
if (info->io.alphaRefBase) {
- for (unsigned int i = 0; i < info->numOutputs; ++i) {
- if (info->out[i].sn != TGSI_SEMANTIC_COLOR ||
- info->out[i].si != 0)
+ for (unsigned int i = 0; i < info_out->numOutputs; ++i) {
+ if (info_out->out[i].sn != TGSI_SEMANTIC_COLOR ||
+ info_out->out[i].si != 0)
continue;
const unsigned int c = 3;
if (!oData.exists(sub.cur->values, i, c))
@@ -4175,15 +4176,15 @@ Converter::exportOutputs()
}
}
- for (unsigned int i = 0; i < info->numOutputs; ++i) {
+ for (unsigned int i = 0; i < info_out->numOutputs; ++i) {
for (unsigned int c = 0; c < 4; ++c) {
if (!oData.exists(sub.cur->values, i, c))
continue;
Symbol *sym = mkSymbol(FILE_SHADER_OUTPUT, 0, TYPE_F32,
- info->out[i].slot[c] * 4);
+ info_out->out[i].slot[c] * 4);
Value *val = oData.load(sub.cur->values, i, c, NULL);
if (val) {
- if (info->out[i].sn == TGSI_SEMANTIC_POSITION)
+ if (info_out->out[i].sn == TGSI_SEMANTIC_POSITION)
mkOp1(OP_SAT, TYPE_F32, val, val);
mkStore(OP_EXPORT, TYPE_F32, sym, NULL, val);
}
@@ -4191,7 +4192,8 @@ Converter::exportOutputs()
}
}
-Converter::Converter(Program *ir, const tgsi::Source *code) : ConverterCommon(ir, code->info),
+Converter::Converter(Program *ir, const tgsi::Source *code, nv50_ir_prog_info_out *info_out)
+: ConverterCommon(ir, code->info, info_out),
code(code),
tgsi(NULL),
tData(this), lData(this), aData(this), oData(this)
@@ -4292,7 +4294,7 @@ Converter::run()
setPosition(entry, true);
sub.cur = getSubroutine(prog->main);
- if (info->io.genUserClip > 0) {
+ if (info_out->io.genUserClip > 0) {
for (int c = 0; c < 4; ++c)
clipVtx[c] = getScratch();
}
@@ -4335,14 +4337,15 @@ Converter::run()
namespace nv50_ir {
bool
-Program::makeFromTGSI(struct nv50_ir_prog_info *info)
+Program::makeFromTGSI(struct nv50_ir_prog_info *info,
+ struct nv50_ir_prog_info_out *info_out)
{
- tgsi::Source src(info, this);
+ tgsi::Source src(info, info_out, this);
if (!src.scanSource())
return false;
- tlsSize = info->bin.tlsSpace;
+ tlsSize = info_out->bin.tlsSpace;
- Converter builder(this, &src);
+ Converter builder(this, &src, info_out);
return builder.run();
}