From cd45d758ff87305ceecca899fe7325779bb6755b Mon Sep 17 00:00:00 2001 From: Ilia Mirkin Date: Wed, 19 Oct 2016 01:20:03 -0400 Subject: [PATCH] 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 Reviewed-by: Samuel Pitoiset Tested-by: Dave Airlie Cc: 12.0 13.0 --- .../nouveau/codegen/nv50_ir_from_tgsi.cpp | 147 +++++++++++------- 1 file 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; } -- 2.30.2