aboutsummaryrefslogtreecommitdiffstats
path: root/src/gallium/drivers/zink
diff options
context:
space:
mode:
authorMike Blumenkrantz <[email protected]>2020-06-10 15:26:07 -0400
committerMarge Bot <[email protected]>2020-06-15 15:36:06 +0000
commit828c767113f557e2a6098342a3dfbfa3e393aa91 (patch)
treead4f9daf6a76654aa712613161624f68e7c1226b /src/gallium/drivers/zink
parentf90bc6daa973b3d762d87254bf4cbe2a71475fda (diff)
zink: rework input/output location emission
glsl builtins that have no analog in spirv are emitted as regular varyings, which means they take up a slot. we need to ensure that there's no conflict between these regular varying slots (from user-defined varyings) and the glsl translated builtins, so we do that by "reserving" the max number of varying slots that can be used by a given stage, then remapping all glsl builtins with no spirv builtin to a packed layout location that can be consistent across stages sort of addresses mesa/mesa#3113 except now there's 10 fewer varying slots Reviewed-by: Erik Faye-Lund <[email protected]> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/5432>
Diffstat (limited to 'src/gallium/drivers/zink')
-rw-r--r--src/gallium/drivers/zink/nir_to_spirv/nir_to_spirv.c162
1 files changed, 107 insertions, 55 deletions
diff --git a/src/gallium/drivers/zink/nir_to_spirv/nir_to_spirv.c b/src/gallium/drivers/zink/nir_to_spirv/nir_to_spirv.c
index 881103c1432..cabc83b7022 100644
--- a/src/gallium/drivers/zink/nir_to_spirv/nir_to_spirv.c
+++ b/src/gallium/drivers/zink/nir_to_spirv/nir_to_spirv.c
@@ -29,6 +29,66 @@
#include "util/u_memory.h"
#include "util/hash_table.h"
+/* this consistently maps slots to a zero-indexed value to avoid wasting slots */
+static unsigned slot_pack_map[] = {
+ /* Position is builtin */
+ [VARYING_SLOT_POS] = UINT_MAX,
+ [VARYING_SLOT_COL0] = 0, /* input/output */
+ [VARYING_SLOT_COL1] = 1, /* input/output */
+ [VARYING_SLOT_FOGC] = 2, /* input/output */
+ /* TEX0-7 are translated to VAR0-7 by nir, so we don't need to reserve */
+ [VARYING_SLOT_TEX0] = UINT_MAX, /* input/output */
+ [VARYING_SLOT_TEX1] = UINT_MAX,
+ [VARYING_SLOT_TEX2] = UINT_MAX,
+ [VARYING_SLOT_TEX3] = UINT_MAX,
+ [VARYING_SLOT_TEX4] = UINT_MAX,
+ [VARYING_SLOT_TEX5] = UINT_MAX,
+ [VARYING_SLOT_TEX6] = UINT_MAX,
+ [VARYING_SLOT_TEX7] = UINT_MAX,
+
+ /* PointSize is builtin */
+ [VARYING_SLOT_PSIZ] = UINT_MAX,
+
+ [VARYING_SLOT_BFC0] = 3, /* output only */
+ [VARYING_SLOT_BFC1] = 4, /* output only */
+ [VARYING_SLOT_EDGE] = 5, /* output only */
+ [VARYING_SLOT_CLIP_VERTEX] = 6, /* output only */
+
+ /* ClipDistance is builtin */
+ [VARYING_SLOT_CLIP_DIST0] = UINT_MAX,
+ [VARYING_SLOT_CLIP_DIST1] = UINT_MAX,
+
+ /* CullDistance is builtin */
+ [VARYING_SLOT_CULL_DIST0] = UINT_MAX, /* input/output */
+ [VARYING_SLOT_CULL_DIST1] = UINT_MAX, /* never actually used */
+
+ /* PrimitiveId is builtin */
+ [VARYING_SLOT_PRIMITIVE_ID] = UINT_MAX,
+
+ /* Layer is builtin */
+ [VARYING_SLOT_LAYER] = UINT_MAX, /* input/output */
+
+ /* ViewportIndex is builtin */
+ [VARYING_SLOT_VIEWPORT] = UINT_MAX, /* input/output */
+
+ /* FrontFacing is builtin */
+ [VARYING_SLOT_FACE] = UINT_MAX,
+
+ /* PointCoord is builtin */
+ [VARYING_SLOT_PNTC] = UINT_MAX, /* input only */
+
+ /* TessLevelOuter is builtin */
+ [VARYING_SLOT_TESS_LEVEL_OUTER] = UINT_MAX,
+ /* TessLevelInner is builtin */
+ [VARYING_SLOT_TESS_LEVEL_INNER] = UINT_MAX,
+
+ [VARYING_SLOT_BOUNDING_BOX0] = 7, /* Only appears as TCS output. */
+ [VARYING_SLOT_BOUNDING_BOX1] = 8, /* Only appears as TCS output. */
+ [VARYING_SLOT_VIEW_INDEX] = 9, /* input/output */
+ [VARYING_SLOT_VIEWPORT_MASK] = 10, /* output only */
+};
+#define NTV_MIN_RESERVED_SLOTS 10
+
struct ntv_context {
struct spirv_builder builder;
@@ -240,32 +300,26 @@ emit_input(struct ntv_context *ctx, struct nir_variable *var)
spirv_builder_emit_name(&ctx->builder, var_id, var->name);
if (ctx->stage == MESA_SHADER_FRAGMENT) {
- if (var->data.location >= VARYING_SLOT_VAR0)
- spirv_builder_emit_location(&ctx->builder, var_id,
- var->data.location -
- VARYING_SLOT_VAR0 +
- VARYING_SLOT_TEX0);
- else if ((var->data.location >= VARYING_SLOT_COL0 &&
- var->data.location <= VARYING_SLOT_TEX7) ||
- var->data.location == VARYING_SLOT_BFC0 ||
- var->data.location == VARYING_SLOT_BFC1) {
- spirv_builder_emit_location(&ctx->builder, var_id,
- var->data.location);
- } else {
- switch (var->data.location) {
- HANDLE_EMIT_BUILTIN(POS, FragCoord);
- HANDLE_EMIT_BUILTIN(PNTC, PointCoord);
- HANDLE_EMIT_BUILTIN(LAYER, Layer);
- HANDLE_EMIT_BUILTIN(PRIMITIVE_ID, PrimitiveId);
- HANDLE_EMIT_BUILTIN(CLIP_DIST0, ClipDistance);
- HANDLE_EMIT_BUILTIN(CULL_DIST0, CullDistance);
- HANDLE_EMIT_BUILTIN(VIEWPORT, ViewportIndex);
- HANDLE_EMIT_BUILTIN(FACE, FrontFacing);
+ unsigned slot = var->data.location;
+ switch (slot) {
+ HANDLE_EMIT_BUILTIN(POS, FragCoord);
+ HANDLE_EMIT_BUILTIN(PNTC, PointCoord);
+ HANDLE_EMIT_BUILTIN(LAYER, Layer);
+ HANDLE_EMIT_BUILTIN(PRIMITIVE_ID, PrimitiveId);
+ HANDLE_EMIT_BUILTIN(CLIP_DIST0, ClipDistance);
+ HANDLE_EMIT_BUILTIN(CULL_DIST0, CullDistance);
+ HANDLE_EMIT_BUILTIN(VIEWPORT, ViewportIndex);
+ HANDLE_EMIT_BUILTIN(FACE, FrontFacing);
- default:
- debug_printf("unknown varying slot: %s\n", gl_varying_slot_name(var->data.location));
- unreachable("unexpected varying slot");
- }
+ default:
+ if (slot < VARYING_SLOT_VAR0) {
+ slot = slot_pack_map[slot];
+ if (slot == UINT_MAX)
+ debug_printf("unhandled varying slot: %s\n", gl_varying_slot_name(var->data.location));
+ } else
+ slot -= VARYING_SLOT_VAR0 - NTV_MIN_RESERVED_SLOTS;
+ assert(slot < VARYING_SLOT_VAR0);
+ spirv_builder_emit_location(&ctx->builder, var_id, slot);
}
} else {
spirv_builder_emit_location(&ctx->builder, var_id,
@@ -299,37 +353,35 @@ emit_output(struct ntv_context *ctx, struct nir_variable *var)
if (ctx->stage == MESA_SHADER_VERTEX) {
- if (var->data.location >= VARYING_SLOT_VAR0)
- spirv_builder_emit_location(&ctx->builder, var_id,
- var->data.location -
- VARYING_SLOT_VAR0 +
- VARYING_SLOT_TEX0);
- else if ((var->data.location >= VARYING_SLOT_COL0 &&
- var->data.location <= VARYING_SLOT_TEX7) ||
- var->data.location == VARYING_SLOT_BFC0 ||
- var->data.location == VARYING_SLOT_BFC1) {
- spirv_builder_emit_location(&ctx->builder, var_id,
- var->data.location);
- } else {
- switch (var->data.location) {
- HANDLE_EMIT_BUILTIN(POS, Position);
- HANDLE_EMIT_BUILTIN(PSIZ, PointSize);
- HANDLE_EMIT_BUILTIN(LAYER, Layer);
- HANDLE_EMIT_BUILTIN(PRIMITIVE_ID, PrimitiveId);
- HANDLE_EMIT_BUILTIN(CULL_DIST0, CullDistance);
- HANDLE_EMIT_BUILTIN(VIEWPORT, ViewportIndex);
- HANDLE_EMIT_BUILTIN(TESS_LEVEL_OUTER, TessLevelOuter);
- HANDLE_EMIT_BUILTIN(TESS_LEVEL_INNER, TessLevelInner);
-
- case VARYING_SLOT_CLIP_DIST0:
- assert(glsl_type_is_array(var->type));
- spirv_builder_emit_builtin(&ctx->builder, var_id, SpvBuiltInClipDistance);
- break;
- default:
- debug_printf("unknown varying slot: %s\n", gl_varying_slot_name(var->data.location));
- unreachable("unexpected varying slot");
- }
+ unsigned slot = var->data.location;
+ switch (slot) {
+ HANDLE_EMIT_BUILTIN(POS, Position);
+ HANDLE_EMIT_BUILTIN(PSIZ, PointSize);
+ HANDLE_EMIT_BUILTIN(LAYER, Layer);
+ HANDLE_EMIT_BUILTIN(PRIMITIVE_ID, PrimitiveId);
+ HANDLE_EMIT_BUILTIN(CULL_DIST0, CullDistance);
+ HANDLE_EMIT_BUILTIN(VIEWPORT, ViewportIndex);
+ HANDLE_EMIT_BUILTIN(TESS_LEVEL_OUTER, TessLevelOuter);
+ HANDLE_EMIT_BUILTIN(TESS_LEVEL_INNER, TessLevelInner);
+
+ case VARYING_SLOT_CLIP_DIST0:
+ assert(glsl_type_is_array(var->type));
+ spirv_builder_emit_builtin(&ctx->builder, var_id, SpvBuiltInClipDistance);
+ break;
+
+ default:
+ if (slot < VARYING_SLOT_VAR0) {
+ slot = slot_pack_map[slot];
+ if (slot == UINT_MAX)
+ debug_printf("unhandled varying slot: %s\n", gl_varying_slot_name(var->data.location));
+ } else
+ slot -= VARYING_SLOT_VAR0 - NTV_MIN_RESERVED_SLOTS;
+ assert(slot < VARYING_SLOT_VAR0);
+ spirv_builder_emit_location(&ctx->builder, var_id, slot);
+ /* non-builtins get location incremented by VARYING_SLOT_VAR0 in vtn, so
+ * use driver_location for non-builtins with defined slots to avoid overlap
+ */
}
} else if (ctx->stage == MESA_SHADER_FRAGMENT) {
if (var->data.location >= FRAG_RESULT_DATA0)