summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorIlia Mirkin <[email protected]>2016-10-19 01:20:03 -0400
committerEmil Velikov <[email protected]>2016-10-24 09:01:03 +0100
commit52df379d6b3a3485bf2814f8a0fb54c90b0af6ad (patch)
treee8b851a32059aabc1938d79d4403f10156e67397 /src
parent05b89cf40e1f1c2a31fac1aed389764a9b1141b0 (diff)
nv50/ir: process texture offset sources as regular sources
With ARB_gpu_shader5, texture offsets can be any source, including TEMPs and IN's. Make sure to process them as regular sources so that we pick up masks, etc. This should fix some CTS tests that feed offsets directly to textureGatherOffset, and we were not picking up the input use, thus not advertising it in the shader header. Signed-off-by: Ilia Mirkin <[email protected]> Reviewed-by: Samuel Pitoiset <[email protected]> Tested-by: Dave Airlie <[email protected]> Cc: 12.0 13.0 <[email protected]> (cherry picked from commit cd45d758ff87305ceecca899fe7325779bb6755b)
Diffstat (limited to 'src')
-rw-r--r--src/gallium/drivers/nouveau/codegen/nv50_ir_from_tgsi.cpp147
1 files changed, 94 insertions, 53 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 db03281a4d4..01e5808d927 100644
--- a/src/gallium/drivers/nouveau/codegen/nv50_ir_from_tgsi.cpp
+++ b/src/gallium/drivers/nouveau/codegen/nv50_ir_from_tgsi.cpp
@@ -182,6 +182,7 @@ public:
// mask of used components of source s
unsigned int srcMask(unsigned int s) const;
+ unsigned int texOffsetMask() const;
SrcRegister getSrc(unsigned int s) const
{
@@ -234,6 +235,35 @@ private:
const struct tgsi_full_instruction *insn;
};
+unsigned int Instruction::texOffsetMask() const
+{
+ const struct tgsi_instruction_texture *tex = &insn->Texture;
+ assert(insn->Instruction.Texture);
+
+ switch (tex->Texture) {
+ case TGSI_TEXTURE_BUFFER:
+ case TGSI_TEXTURE_1D:
+ case TGSI_TEXTURE_SHADOW1D:
+ case TGSI_TEXTURE_1D_ARRAY:
+ case TGSI_TEXTURE_SHADOW1D_ARRAY:
+ return 0x1;
+ case TGSI_TEXTURE_2D:
+ case TGSI_TEXTURE_SHADOW2D:
+ case TGSI_TEXTURE_2D_ARRAY:
+ case TGSI_TEXTURE_SHADOW2D_ARRAY:
+ case TGSI_TEXTURE_RECT:
+ case TGSI_TEXTURE_SHADOWRECT:
+ case TGSI_TEXTURE_2D_MSAA:
+ case TGSI_TEXTURE_2D_ARRAY_MSAA:
+ return 0x3;
+ case TGSI_TEXTURE_3D:
+ return 0x7;
+ default:
+ assert(!"Unexpected texture target");
+ return 0xf;
+ }
+}
+
unsigned int Instruction::srcMask(unsigned int s) const
{
unsigned int mask = insn->Dst[0].Register.WriteMask;
@@ -955,6 +985,9 @@ private:
int inferSysValDirection(unsigned sn) const;
bool scanDeclaration(const struct tgsi_full_declaration *);
bool scanInstruction(const struct tgsi_full_instruction *);
+ void scanInstructionSrc(const Instruction& insn,
+ const Instruction::SrcRegister& src,
+ unsigned mask);
void scanProperty(const struct tgsi_full_property *);
void scanImmediate(const struct tgsi_full_immediate *);
@@ -1364,6 +1397,61 @@ inline bool Source::isEdgeFlagPassthrough(const Instruction& insn) const
insn.getSrc(0).getFile() == TGSI_FILE_INPUT;
}
+void Source::scanInstructionSrc(const Instruction& insn,
+ const Instruction::SrcRegister& src,
+ unsigned mask)
+{
+ if (src.getFile() == TGSI_FILE_TEMPORARY) {
+ 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
+ // reading. This is an extremely unlikely occurrence.
+ for (unsigned i = 0; i < info->numOutputs; ++i)
+ info->out[i].oread = 1;
+ } else {
+ info->out[src.getIndex(0)].oread = 1;
+ }
+ }
+ if (src.getFile() != TGSI_FILE_INPUT)
+ return;
+
+ if (src.isIndirect(0)) {
+ for (unsigned i = 0; i < info->numInputs; ++i)
+ info->in[i].mask = 0xf;
+ } else {
+ const int i = src.getIndex(0);
+ for (unsigned c = 0; c < 4; ++c) {
+ if (!(mask & (1 << c)))
+ continue;
+ int k = src.getSwizzle(c);
+ if (k <= TGSI_SWIZZLE_W)
+ info->in[i].mask |= 1 << k;
+ }
+ switch (info->in[i].sn) {
+ case TGSI_SEMANTIC_PSIZE:
+ case TGSI_SEMANTIC_PRIMID:
+ case TGSI_SEMANTIC_FOG:
+ info->in[i].mask &= 0x1;
+ break;
+ case TGSI_SEMANTIC_PCOORD:
+ info->in[i].mask &= 0x3;
+ break;
+ default:
+ break;
+ }
+ }
+}
+
bool Source::scanInstruction(const struct tgsi_full_instruction *inst)
{
Instruction insn(inst);
@@ -1396,66 +1484,19 @@ bool Source::scanInstruction(const struct tgsi_full_instruction *inst)
indirectTempArrays.insert(dst.getArrayId());
} else
if (dst.getFile() == TGSI_FILE_BUFFER ||
- dst.getFile() == TGSI_FILE_IMAGE ||
+ dst.getFile() == TGSI_FILE_IMAGE ||
(dst.getFile() == TGSI_FILE_MEMORY &&
memoryFiles[dst.getIndex(0)].mem_type == TGSI_MEMORY_TYPE_GLOBAL)) {
info->io.globalAccess |= 0x2;
}
}
- for (unsigned s = 0; s < insn.srcCount(); ++s) {
- Instruction::SrcRegister src = insn.getSrc(s);
- if (src.getFile() == TGSI_FILE_TEMPORARY) {
- 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
- // reading. This is an extremely unlikely occurrence.
- for (unsigned i = 0; i < info->numOutputs; ++i)
- info->out[i].oread = 1;
- } else {
- info->out[src.getIndex(0)].oread = 1;
- }
- }
- if (src.getFile() != TGSI_FILE_INPUT)
- continue;
- unsigned mask = insn.srcMask(s);
+ for (unsigned s = 0; s < insn.srcCount(); ++s)
+ scanInstructionSrc(insn, insn.getSrc(s), insn.srcMask(s));
+
+ for (unsigned s = 0; s < insn.getNumTexOffsets(); ++s)
+ scanInstructionSrc(insn, insn.getTexOffset(s), insn.texOffsetMask());
- if (src.isIndirect(0)) {
- for (unsigned i = 0; i < info->numInputs; ++i)
- info->in[i].mask = 0xf;
- } else {
- const int i = src.getIndex(0);
- for (unsigned c = 0; c < 4; ++c) {
- if (!(mask & (1 << c)))
- continue;
- int k = src.getSwizzle(c);
- if (k <= TGSI_SWIZZLE_W)
- info->in[i].mask |= 1 << k;
- }
- switch (info->in[i].sn) {
- case TGSI_SEMANTIC_PSIZE:
- case TGSI_SEMANTIC_PRIMID:
- case TGSI_SEMANTIC_FOG:
- info->in[i].mask &= 0x1;
- break;
- case TGSI_SEMANTIC_PCOORD:
- info->in[i].mask &= 0x3;
- break;
- default:
- break;
- }
- }
- }
return true;
}