diff options
Diffstat (limited to 'src/gallium/drivers/nouveau/codegen')
-rw-r--r-- | src/gallium/drivers/nouveau/codegen/nv50_ir_from_tgsi.cpp | 147 |
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; } |