Signed-off-by: Karol Herbst <kher...@redhat.com> --- .../drivers/nouveau/codegen/nv50_ir_from_nir.cpp | 427 +++++++++++++++++++++ 1 file changed, 427 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 009f3df875..d114fe28dd 100644 --- a/src/gallium/drivers/nouveau/codegen/nv50_ir_from_nir.cpp +++ b/src/gallium/drivers/nouveau/codegen/nv50_ir_from_nir.cpp @@ -64,6 +64,11 @@ public: Value* getSrc(nir_src *, uint8_t); Value* getSrc(nir_ssa_def *, uint8_t); + void setInterpolate(nv50_ir_varying *, + decltype(nir_variable().data.interpolation), + unsigned semantics); + bool assignSlots(); + bool visit(nir_alu_instr *); bool visit(nir_block *); bool visit(nir_cf_node *); @@ -471,6 +476,423 @@ Converter::getSrc(nir_ssa_def *src, uint8_t idx) return (*it).second[idx]; } +static void +vert_attrib_to_tgsi_semantic(unsigned slot, unsigned *name, unsigned *index) +{ + if (slot >= VERT_ATTRIB_GENERIC0) { + *name = TGSI_SEMANTIC_GENERIC; + *index = slot - VERT_ATTRIB_GENERIC0; + return; + } + + if (slot == VERT_ATTRIB_POINT_SIZE) { + ERROR("unknown vert attrib slot %u\n", slot); + assert(false); + return; + } + + if (slot >= VERT_ATTRIB_TEX0) { + *name = TGSI_SEMANTIC_TEXCOORD; + *index = slot - VERT_ATTRIB_TEX0; + return; + } + + switch (slot) { + case VERT_ATTRIB_COLOR0: + *name = TGSI_SEMANTIC_COLOR; + *index = 0; + break; + case VERT_ATTRIB_COLOR1: + *name = TGSI_SEMANTIC_COLOR; + *index = 1; + break; + case VERT_ATTRIB_EDGEFLAG: + *name = TGSI_SEMANTIC_EDGEFLAG; + *index = 0; + break; + case VERT_ATTRIB_FOG: + *name = TGSI_SEMANTIC_FOG; + *index = 0; + break; + case VERT_ATTRIB_NORMAL: + *name = TGSI_SEMANTIC_NORMAL; + *index = 0; + break; + case VERT_ATTRIB_POS: + *name = TGSI_SEMANTIC_POSITION; + *index = 0; + break; + default: + ERROR("unknown vert attrib slot %u\n", slot); + assert(false); + } +} + +static void +varying_slot_to_tgsi_semantic(unsigned slot, unsigned *name, unsigned *index) +{ + if (slot >= VARYING_SLOT_VAR0) { + *name = TGSI_SEMANTIC_GENERIC; + *index = slot - VARYING_SLOT_VAR0; + return; + } + + if (slot >= VARYING_SLOT_TEX0 && slot <= VARYING_SLOT_TEX7) { + *name = TGSI_SEMANTIC_TEXCOORD; + *index = slot - VARYING_SLOT_TEX0; + return; + } + + switch (slot) { + case VARYING_SLOT_BFC0: + *name = TGSI_SEMANTIC_BCOLOR; + *index = 0; + break; + case VARYING_SLOT_BFC1: + *name = TGSI_SEMANTIC_BCOLOR; + *index = 1; + break; + case VARYING_SLOT_CLIP_DIST0: + *name = TGSI_SEMANTIC_CLIPDIST; + *index = 0; + break; + case VARYING_SLOT_CLIP_DIST1: + *name = TGSI_SEMANTIC_CLIPDIST; + *index = 1; + break; + case VARYING_SLOT_CLIP_VERTEX: + *name = TGSI_SEMANTIC_CLIPVERTEX; + *index = 0; + break; + case VARYING_SLOT_COL0: + *name = TGSI_SEMANTIC_COLOR; + *index = 0; + break; + case VARYING_SLOT_COL1: + *name = TGSI_SEMANTIC_COLOR; + *index = 1; + break; + case VARYING_SLOT_EDGE: + *name = TGSI_SEMANTIC_EDGEFLAG; + *index = 0; + break; + case VARYING_SLOT_FACE: + *name = TGSI_SEMANTIC_FACE; + *index = 0; + break; + case VARYING_SLOT_FOGC: + *name = TGSI_SEMANTIC_FOG; + *index = 0; + break; + case VARYING_SLOT_LAYER: + *name = TGSI_SEMANTIC_LAYER; + *index = 0; + break; + case VARYING_SLOT_PNTC: + *name = TGSI_SEMANTIC_PCOORD; + *index = 0; + break; + case VARYING_SLOT_POS: + *name = TGSI_SEMANTIC_POSITION; + *index = 0; + break; + case VARYING_SLOT_PRIMITIVE_ID: + *name = TGSI_SEMANTIC_PRIMID; + *index = 0; + break; + case VARYING_SLOT_PSIZ: + *name = TGSI_SEMANTIC_PSIZE; + *index = 0; + break; + case VARYING_SLOT_VIEWPORT: + *name = TGSI_SEMANTIC_VIEWPORT_INDEX; + *index = 0; + break; + default: + ERROR("unknown varying slot %u\n", slot); + assert(false); + } +} + +static void +frag_result_to_tgsi_semantic(unsigned slot, unsigned *name, unsigned *index) +{ + if (slot >= FRAG_RESULT_DATA0) { + *name = TGSI_SEMANTIC_COLOR; + *index = slot - FRAG_RESULT_COLOR - 2; // intentional + return; + } + + switch (slot) { + case FRAG_RESULT_COLOR: + *name = TGSI_SEMANTIC_COLOR; + *index = 0; + break; + case FRAG_RESULT_DEPTH: + *name = TGSI_SEMANTIC_POSITION; + *index = 0; + break; + default: + ERROR("unknown frag result slot %u\n", slot); + assert(false); + } +} + +static void +system_val_to_tgsi_semantic(unsigned val, unsigned *name, unsigned *index) +{ + *index = 0; + switch (val) { + /* Vertex shader */ + case SYSTEM_VALUE_VERTEX_ID: + *name = TGSI_SEMANTIC_VERTEXID; + break; + case SYSTEM_VALUE_INSTANCE_ID: + *name = TGSI_SEMANTIC_INSTANCEID; + break; + case SYSTEM_VALUE_VERTEX_ID_ZERO_BASE: + *name = TGSI_SEMANTIC_VERTEXID_NOBASE; + break; + case SYSTEM_VALUE_BASE_VERTEX: + *name = TGSI_SEMANTIC_BASEVERTEX; + break; + case SYSTEM_VALUE_BASE_INSTANCE: + *name = TGSI_SEMANTIC_BASEINSTANCE; + break; + case SYSTEM_VALUE_DRAW_ID: + *name = TGSI_SEMANTIC_DRAWID; + break; + + /* Geometry shader */ + case SYSTEM_VALUE_INVOCATION_ID: + *name = TGSI_SEMANTIC_INVOCATIONID; + break; + + /* Fragment shader */ + case SYSTEM_VALUE_FRAG_COORD: + *name = TGSI_SEMANTIC_POSITION; + break; + case SYSTEM_VALUE_FRONT_FACE: + *name = TGSI_SEMANTIC_FACE; + break; + case SYSTEM_VALUE_SAMPLE_ID: + *name = TGSI_SEMANTIC_SAMPLEID; + break; + case SYSTEM_VALUE_SAMPLE_POS: + *name = TGSI_SEMANTIC_SAMPLEPOS; + break; + case SYSTEM_VALUE_SAMPLE_MASK_IN: + *name = TGSI_SEMANTIC_SAMPLEMASK; + break; + case SYSTEM_VALUE_HELPER_INVOCATION: + *name = TGSI_SEMANTIC_HELPER_INVOCATION; + break; + + /* Tessellation shader */ + case SYSTEM_VALUE_TESS_COORD: + *name = TGSI_SEMANTIC_TESSCOORD; + break; + case SYSTEM_VALUE_VERTICES_IN: + *name = TGSI_SEMANTIC_VERTICESIN; + break; + case SYSTEM_VALUE_PRIMITIVE_ID: + *name = TGSI_SEMANTIC_PRIMID; + break; + case SYSTEM_VALUE_TESS_LEVEL_OUTER: + *name = TGSI_SEMANTIC_TESSOUTER; + break; + case SYSTEM_VALUE_TESS_LEVEL_INNER: + *name = TGSI_SEMANTIC_TESSINNER; + break; + + /* Compute shader */ + case SYSTEM_VALUE_LOCAL_INVOCATION_ID: + *name = TGSI_SEMANTIC_THREAD_ID; + break; + case SYSTEM_VALUE_WORK_GROUP_ID: + *name = TGSI_SEMANTIC_BLOCK_ID; + break; + case SYSTEM_VALUE_NUM_WORK_GROUPS: + *name = TGSI_SEMANTIC_GRID_SIZE; + break; + case SYSTEM_VALUE_LOCAL_GROUP_SIZE: + *name = TGSI_SEMANTIC_BLOCK_SIZE; + break; + + /* ARB_shader_ballot */ + case SYSTEM_VALUE_SUBGROUP_SIZE: + *name = TGSI_SEMANTIC_SUBGROUP_SIZE; + break; + case SYSTEM_VALUE_SUBGROUP_INVOCATION: + *name = TGSI_SEMANTIC_SUBGROUP_INVOCATION; + break; + case SYSTEM_VALUE_SUBGROUP_EQ_MASK: + *name = TGSI_SEMANTIC_SUBGROUP_EQ_MASK; + break; + case SYSTEM_VALUE_SUBGROUP_GE_MASK: + *name = TGSI_SEMANTIC_SUBGROUP_GE_MASK; + break; + case SYSTEM_VALUE_SUBGROUP_GT_MASK: + *name = TGSI_SEMANTIC_SUBGROUP_GT_MASK; + break; + case SYSTEM_VALUE_SUBGROUP_LE_MASK: + *name = TGSI_SEMANTIC_SUBGROUP_LE_MASK; + break; + case SYSTEM_VALUE_SUBGROUP_LT_MASK: + *name = TGSI_SEMANTIC_SUBGROUP_LT_MASK; + break; + default: + ERROR("unknown system value %u\n", val); + assert(false); + } +} + +void +Converter::setInterpolate(nv50_ir_varying *var, + decltype(nir_variable().data.interpolation) mode, + unsigned semantic) +{ + + switch (mode) { + case INTERP_MODE_NONE: + switch (semantic) { + case TGSI_SEMANTIC_COLOR: + var->sc = 1; + break; + case TGSI_SEMANTIC_POSITION: + var->linear = 1; + break; + default: + break; + } + break; + case INTERP_MODE_SMOOTH: + break; + case INTERP_MODE_FLAT: + var->flat = 1; + break; + case INTERP_MODE_NOPERSPECTIVE: + var->linear = 1; + break; + } +} + +bool Converter::assignSlots() { + unsigned name; + unsigned index; + + info->numInputs = 0; + nir_foreach_variable(var, &nir->inputs) { + auto slot = var->data.location; + auto comp = var->type->components(); + auto frac = var->data.location_frac; + auto vary = var->data.driver_location; + + assert(vary < PIPE_MAX_SHADER_INPUTS); + + switch(prog->getType()) { + case Program::TYPE_FRAGMENT: + varying_slot_to_tgsi_semantic((gl_varying_slot)slot, &name, &index); + setInterpolate(&info->in[vary], var->data.interpolation, name); + break; + case Program::TYPE_VERTEX: + vert_attrib_to_tgsi_semantic((gl_vert_attrib)slot, &name, &index); + break; + default: + ERROR("unknown shader type %u in assignSlots\n", prog->getType()); + return false; + } + info->in[vary].sn = name; + info->in[vary].si = index; + info->in[vary].mask |= ((1 << comp) - 1) << frac; + info->numInputs = std::max<uint8_t>(info->numInputs, vary + 1); + } + + info->numOutputs = 0; + nir_foreach_variable(var, &nir->outputs) { + auto slot = var->data.location; + auto comp = var->type->components(); + auto frac = var->data.location_frac; + auto vary = var->data.driver_location; + + assert(vary < PIPE_MAX_SHADER_OUTPUTS); + + switch(prog->getType()) { + case Program::TYPE_FRAGMENT: + frag_result_to_tgsi_semantic((gl_frag_result)slot, &name, &index); + switch (name) { + case TGSI_SEMANTIC_COLOR: + info->prop.fp.numColourResults++; + break; + case TGSI_SEMANTIC_POSITION: + info->io.fragDepth = vary; + info->prop.fp.writesDepth = true; + break; + default: + break; + } + break; + case Program::TYPE_VERTEX: + varying_slot_to_tgsi_semantic((gl_varying_slot)slot, &name, &index); + switch (name) { + case TGSI_SEMANTIC_CLIPDIST: + info->io.genUserClip = -1; + break; + case TGSI_SEMANTIC_EDGEFLAG: + info->io.edgeFlagOut = vary; + break; + default: + break; + } + break; + default: + ERROR("unknown shader type %u in assignSlots\n", prog->getType()); + return false; + } + + info->out[vary].sn = name; + info->out[vary].si = index; + info->out[vary].mask |= ((1 << comp) - 1) << frac; + info->numOutputs = std::max<uint8_t>(info->numOutputs, vary + 1); + } + + info->numSysVals = 0; + for (uint8_t i = 0; i < 64; ++i) { + if (!(nir->info.system_values_read & 1ll << i)) + continue; + + system_val_to_tgsi_semantic(i, &name, &index); + info->sv[info->numSysVals].sn = name; + info->sv[info->numSysVals].si = index; + info->sv[info->numSysVals].input = 0; // TODO inferSysValDirection(sn); + + switch (i) { + case SYSTEM_VALUE_VERTEX_ID: + info->io.vertexId = 1; + break; + default: + break; + } + info->numSysVals += 1; + } + + if (info->io.genUserClip > 0) { + info->io.clipDistances = info->io.genUserClip; + + const unsigned int nOut = (info->io.genUserClip + 3) / 4; + + for (unsigned int n = 0; n < nOut; ++n) { + unsigned int i = info->numOutputs++; + info->out[i].id = i; + info->out[i].sn = TGSI_SEMANTIC_CLIPDIST; + info->out[i].si = n; + info->out[i].mask = ((1 << info->io.clipDistances) - 1) >> (n * 4); + } + } + + return info->assignSlots(info) == 0; +} + bool Converter::visit(nir_function *function) { @@ -1209,6 +1631,11 @@ Converter::run() if (prog->dbgFlags & NV50_IR_DEBUG_BASIC) nir_print_shader(nir, stderr); + if (!assignSlots()) { + ERROR("Couldn't assign slots!\n"); + return false; + } + nir_foreach_function(function, nir) { if (!visit(function)) return false; -- 2.14.3 _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/mesa-dev