#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;
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,
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)