summaryrefslogtreecommitdiffstats
path: root/src/gallium/drivers/nouveau
diff options
context:
space:
mode:
authorIlia Mirkin <[email protected]>2016-10-19 01:20:03 -0400
committerIlia Mirkin <[email protected]>2016-10-19 21:02:01 -0400
commitcd45d758ff87305ceecca899fe7325779bb6755b (patch)
tree9afe16598dd07d2fb1be3a44f8d844a818909064 /src/gallium/drivers/nouveau
parent313fba5ee1de9416930e45da8aff63a24763940b (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]>
Diffstat (limited to 'src/gallium/drivers/nouveau')
-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 0c98744f92e..3e4f26c6bb1 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 *);
@@ -1365,6 +1398,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);
@@ -1397,66 +1485,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;
}