v2: add helper function for indirects v4: add new getIndirect overload for easier use v5: use getSSA for ssa values we can just create the values for unassigned registers in getSrc v6: always create at least 32 bit values
Signed-off-by: Karol Herbst <kher...@redhat.com> --- .../drivers/nouveau/codegen/nv50_ir_from_nir.cpp | 133 +++++++++++++++++++++ 1 file changed, 133 insertions(+) diff --git a/src/gallium/drivers/nouveau/codegen/nv50_ir_from_nir.cpp b/src/gallium/drivers/nouveau/codegen/nv50_ir_from_nir.cpp index 0b7a5981f73..ab497ef77b3 100644 --- a/src/gallium/drivers/nouveau/codegen/nv50_ir_from_nir.cpp +++ b/src/gallium/drivers/nouveau/codegen/nv50_ir_from_nir.cpp @@ -31,6 +31,9 @@ #include "codegen/nv50_ir_lowering_helper.h" #include "codegen/nv50_ir_util.h" +#include <unordered_map> +#include <vector> + static int type_size(const struct glsl_type *type) { @@ -48,13 +51,143 @@ public: bool run(); private: + typedef std::vector<LValue*> LValues; + typedef decltype(nir_ssa_def().index) NirSSADefIdx; + typedef std::unordered_map<NirSSADefIdx, LValues> NirDefMap; + + LValues& convert(nir_alu_dest *); + LValues& convert(nir_dest *); + LValues& convert(nir_register *); + LValues& convert(nir_ssa_def *); + + Value* getSrc(nir_alu_src *, uint8_t component = 0); + Value* getSrc(nir_register *, uint8_t); + Value* getSrc(nir_src *, uint8_t, bool indirect = false); + Value* getSrc(nir_ssa_def *, uint8_t); + + uint32_t getIndirect(nir_src *, uint8_t, Value**); + uint32_t getIndirect(nir_intrinsic_instr *, uint8_t s, uint8_t c, Value**); + nir_shader *nir; + + NirDefMap ssaDefs; + NirDefMap regDefs; }; Converter::Converter(Program *prog, nir_shader *nir, nv50_ir_prog_info *info) : ConverterCommon(prog, info), nir(nir) {} +Converter::LValues& +Converter::convert(nir_dest *dest) +{ + if (dest->is_ssa) + return convert(&dest->ssa); + if (dest->reg.indirect) { + ERROR("no support for indirects."); + assert(false); + } + return convert(dest->reg.reg); +} + +Converter::LValues& +Converter::convert(nir_register *reg) +{ + NirDefMap::iterator it = regDefs.find(reg->index); + if (it != regDefs.end()) + return (*it).second; + + LValues newDef(reg->num_components); + for (auto i = 0u; i < reg->num_components; i++) + newDef[i] = getScratch(std::max(4, reg->bit_size / 8)); + return regDefs[reg->index] = newDef; +} + +Converter::LValues& +Converter::convert(nir_ssa_def *def) +{ + NirDefMap::iterator it = ssaDefs.find(def->index); + if (it != ssaDefs.end()) + return (*it).second; + + LValues newDef(def->num_components); + for (auto i = 0; i < def->num_components; i++) + newDef[i] = getSSA(std::max(4, def->bit_size / 8)); + return ssaDefs[def->index] = newDef; +} + +Value* +Converter::getSrc(nir_alu_src *src, uint8_t component) +{ + if (src->abs || src->negate) { + ERROR("modifiers currently not supported on nir_alu_src\n"); + assert(false); + } + return getSrc(&src->src, src->swizzle[component]); +} + +Value* +Converter::getSrc(nir_register *reg, uint8_t idx) +{ + NirDefMap::iterator it = regDefs.find(reg->index); + if (it == regDefs.end()) + return convert(reg)[idx]; + return (*it).second[idx]; +} + +Value* +Converter::getSrc(nir_src *src, uint8_t idx, bool indirect) +{ + if (src->is_ssa) + return getSrc(src->ssa, idx); + + if (src->reg.indirect) { + if (indirect) + return getSrc(src->reg.indirect, idx); + ERROR("no support for indirects."); + assert(false); + return nullptr; + } + + return getSrc(src->reg.reg, idx); +} + +Value* +Converter::getSrc(nir_ssa_def *src, uint8_t idx) +{ + NirDefMap::iterator it = ssaDefs.find(src->index); + if (it == ssaDefs.end()) { + ERROR("SSA value %u not found\n", src->index); + assert(false); + return nullptr; + } + return (*it).second[idx]; +} + +uint32_t +Converter::getIndirect(nir_src *src, uint8_t idx, Value **indirect) +{ + nir_const_value *offset = nir_src_as_const_value(*src); + + if (offset) { + *indirect = nullptr; + return offset->u32[0]; + } + + *indirect = getSrc(src, idx, true); + return 0; +} + +uint32_t +Converter::getIndirect(nir_intrinsic_instr *insn, uint8_t s, uint8_t c, Value **indirect) +{ + auto idx = nir_intrinsic_base(insn) + getIndirect(&insn->src[s], c, indirect); + if (*indirect) { + *indirect = mkOp2v(OP_SHL, TYPE_U32, getSSA(4, FILE_ADDRESS), *indirect, loadImm(nullptr, 4)); + } + return idx; +} + bool Converter::run() { -- 2.14.3 _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/mesa-dev