[Mesa-dev] [PATCH v2 11/31] nvir/nir: run assignSlots
Karol Herbst
kherbst at redhat.com
Thu Jan 4 15:01:57 UTC 2018
v2: add support for geometry shaders
set idx
add some missing mappings
fix for 64bit inputs/outputs
fix up some FP color output index messup
parse centroid flag
Signed-off-by: Karol Herbst <kherbst at redhat.com>
---
.../drivers/nouveau/codegen/nv50_ir_from_nir.cpp | 531 +++++++++++++++++++++
1 file changed, 531 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 b8f956d2f1..9ab4b66f55 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,12 @@ public:
Value* getSrc(nir_ssa_def *, uint8_t);
uint32_t getIndirect(nir_src *, uint8_t, Value**);
+ void setInterpolate(nv50_ir_varying *,
+ decltype(nir_variable().data.interpolation),
+ bool centroid,
+ unsigned semantics);
+ bool assignSlots();
+
bool run();
bool isFloatType(nir_alu_type);
@@ -294,6 +300,526 @@ Converter::getIndirect(nir_src *src, uint8_t idx, Value **indirect)
return 0;
}
+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_PATCH0) {
+ *name = TGSI_SEMANTIC_PATCH;
+ *index = slot - VARYING_SLOT_PATCH0;
+ return;
+ }
+
+ 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_TESS_LEVEL_INNER:
+ *name = TGSI_SEMANTIC_TESSINNER;
+ *index = 0;
+ break;
+ case VARYING_SLOT_TESS_LEVEL_OUTER:
+ *name = TGSI_SEMANTIC_TESSOUTER;
+ *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;
+ case FRAG_RESULT_SAMPLE_MASK:
+ *name = TGSI_SEMANTIC_SAMPLEMASK;
+ *index = 0;
+ break;
+ default:
+ ERROR("unknown frag result slot %u\n", slot);
+ assert(false);
+ }
+}
+
+// copy of _mesa_sysval_to_semantic
+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,
+ bool centroid,
+ 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;
+ }
+ var->centroid = centroid;
+}
+
+static uint16_t
+calcSlots(const glsl_type *type, Program::Type stage, const shader_info &info, bool input) {
+ if (!type->is_array())
+ return 1;
+
+ uint16_t slots;
+ switch (stage) {
+ case Program::TYPE_GEOMETRY:
+ slots = type->uniform_locations();
+ if (input)
+ slots /= info.gs.vertices_in;
+ break;
+ case Program::TYPE_TESSELLATION_CONTROL:
+ case Program::TYPE_TESSELLATION_EVAL:
+ // remove first dimension
+ slots = type->fields.array->uniform_locations();
+ break;
+ default:
+ slots = type->uniform_locations();
+ break;
+ }
+
+ return slots;
+}
+
+bool Converter::assignSlots() {
+ unsigned name;
+ unsigned index;
+
+ info->io.viewportId = -1;
+ info->numInputs = 0;
+ nir_foreach_variable(var, &nir->inputs) {
+ const glsl_type *type = var->type;
+ auto slot = var->data.location;
+ auto slots = calcSlots(type, prog->getType(), nir->info, true);
+ auto comp = type->is_array() ? type->without_array()->components() : type->components();
+ auto frac = var->data.location_frac;
+ auto vary = var->data.driver_location;
+
+ assert(vary + slots <= 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, var->data.centroid, name);
+ break;
+ case Program::TYPE_GEOMETRY:
+ varying_slot_to_tgsi_semantic((gl_varying_slot)slot, &name, &index);
+ break;
+ case Program::TYPE_TESSELLATION_CONTROL:
+ case Program::TYPE_TESSELLATION_EVAL:
+ varying_slot_to_tgsi_semantic((gl_varying_slot)slot, &name, &index);
+ if (name == TGSI_SEMANTIC_PATCH) {
+ info->in[vary].patch = 1;
+ info->numPatchConstants = MAX2(info->numPatchConstants, index + 1);
+ }
+ break;
+ case Program::TYPE_VERTEX:
+ vert_attrib_to_tgsi_semantic((gl_vert_attrib)slot, &name, &index);
+ switch (name) {
+ case TGSI_SEMANTIC_EDGEFLAG:
+ info->io.edgeFlagIn = vary;
+ break;
+ default:
+ break;
+ }
+ break;
+ default:
+ ERROR("unknown shader type %u in assignSlots\n", prog->getType());
+ return false;
+ }
+
+ for (auto i = 0u; i < slots; ++i, ++vary) {
+ info->in[vary].id = vary;
+ info->in[vary].sn = name;
+ info->in[vary].si = index + i;
+ if (glsl_base_type_is_64bit(type->base_type))
+ info->in[vary].mask |= ((1 << (comp * 2)) - 1) << (frac * 2);
+ else
+ 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) {
+ const glsl_type *type = var->type;
+ auto slot = var->data.location;
+ auto comp = type->is_array() ? type->without_array()->components() : 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++;
+ info->prop.fp.separateFragData = true;
+ // sometimes we get FRAG_RESULT_DATAX with data.index 0
+ // sometimes we get FRAG_RESULT_DATA0 with data.index X
+ index = index == 0 ? var->data.index : index;
+ break;
+ case TGSI_SEMANTIC_POSITION:
+ info->io.fragDepth = vary;
+ info->prop.fp.writesDepth = true;
+ break;
+ case TGSI_SEMANTIC_SAMPLEMASK:
+ info->io.sampleMask = vary;
+ break;
+ default:
+ break;
+ }
+ break;
+ case Program::TYPE_GEOMETRY:
+ case Program::TYPE_TESSELLATION_CONTROL:
+ case Program::TYPE_TESSELLATION_EVAL:
+ 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;
+ case TGSI_SEMANTIC_PATCH:
+ info->numPatchConstants = MAX2(info->numPatchConstants, index + 1);
+ /* fallthrough */
+ case TGSI_SEMANTIC_TESSINNER:
+ case TGSI_SEMANTIC_TESSOUTER:
+ info->out[vary].patch = 1;
+ break;
+ default:
+ break;
+ }
+ break;
+ default:
+ ERROR("unknown shader type %u in assignSlots\n", prog->getType());
+ return false;
+ }
+
+ info->out[vary].id = vary;
+ info->out[vary].sn = name;
+ info->out[vary].si = index;
+ if (glsl_base_type_is_64bit(type->base_type))
+ info->out[vary].mask |= ((1 << (comp * 2)) - 1) << (frac * 2);
+ else
+ 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_INSTANCE_ID:
+ info->io.instanceId = info->numSysVals;
+ break;
+ case SYSTEM_VALUE_TESS_LEVEL_INNER:
+ case SYSTEM_VALUE_TESS_LEVEL_OUTER:
+ info->sv[info->numSysVals].patch = 1;
+ break;
+ case SYSTEM_VALUE_VERTEX_ID:
+ info->io.vertexId = info->numSysVals;
+ 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::run()
{
@@ -331,6 +857,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;
+ }
+
return false;
}
--
2.14.3
More information about the mesa-dev
mailing list