spirv: Always mark FS layer and viewport index inpus as flat

The spec requires these to be decorated as FLAT,
but some apps forgot to set that,
eg. old DXVK before d12a8e09a855

Let's unconditionally decorate these FS inputs as FLAT
in spirv_to_nir, we can do that for free and prevent those
apps from crashing RADV.

Cc: mesa-stable
Signed-off-by: Timur Kristóf <timur.kristof@gmail.com>
Reviewed-by: Alyssa Rosenzweig <alyssa@rosenzweig.io>
Reviewed-by: Faith Ekstrand <faith.ekstrand@collabora.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/33205>
This commit is contained in:
Timur Kristóf
2025-01-24 14:51:10 +01:00
parent e4668b8427
commit da184ddbe4
+19 -12
View File
@@ -885,7 +885,8 @@ set_mode_system_value(struct vtn_builder *b, nir_variable_mode *mode)
static void
vtn_get_builtin_location(struct vtn_builder *b,
SpvBuiltIn builtin, int *location,
nir_variable_mode *mode)
nir_variable_mode *mode,
enum glsl_interp_mode *interp_mode)
{
switch (builtin) {
case SpvBuiltInPosition:
@@ -940,31 +941,35 @@ vtn_get_builtin_location(struct vtn_builder *b,
case SpvBuiltInLayer:
case SpvBuiltInLayerPerViewNV:
*location = VARYING_SLOT_LAYER;
if (b->shader->info.stage == MESA_SHADER_FRAGMENT)
if (b->shader->info.stage == MESA_SHADER_FRAGMENT) {
*mode = nir_var_shader_in;
else if (b->shader->info.stage == MESA_SHADER_GEOMETRY)
*interp_mode = INTERP_MODE_FLAT;
} else if (b->shader->info.stage == MESA_SHADER_GEOMETRY) {
*mode = nir_var_shader_out;
else if (b->supported_capabilities.ShaderViewportIndexLayerEXT &&
} else if (b->supported_capabilities.ShaderViewportIndexLayerEXT &&
(b->shader->info.stage == MESA_SHADER_VERTEX ||
b->shader->info.stage == MESA_SHADER_TESS_EVAL ||
b->shader->info.stage == MESA_SHADER_MESH))
b->shader->info.stage == MESA_SHADER_MESH)) {
*mode = nir_var_shader_out;
else
} else {
vtn_fail("invalid stage for SpvBuiltInLayer");
}
break;
case SpvBuiltInViewportIndex:
*location = VARYING_SLOT_VIEWPORT;
if (b->shader->info.stage == MESA_SHADER_GEOMETRY)
if (b->shader->info.stage == MESA_SHADER_GEOMETRY) {
*mode = nir_var_shader_out;
else if (b->supported_capabilities.ShaderViewportIndexLayerEXT &&
} else if (b->supported_capabilities.ShaderViewportIndexLayerEXT &&
(b->shader->info.stage == MESA_SHADER_VERTEX ||
b->shader->info.stage == MESA_SHADER_TESS_EVAL ||
b->shader->info.stage == MESA_SHADER_MESH))
b->shader->info.stage == MESA_SHADER_MESH)) {
*mode = nir_var_shader_out;
else if (b->shader->info.stage == MESA_SHADER_FRAGMENT)
} else if (b->shader->info.stage == MESA_SHADER_FRAGMENT) {
*mode = nir_var_shader_in;
else
*interp_mode = INTERP_MODE_FLAT;
} else {
vtn_fail("invalid stage for SpvBuiltInViewportIndex");
}
break;
case SpvBuiltInViewportMaskNV:
case SpvBuiltInViewportMaskPerViewNV:
@@ -1402,8 +1407,10 @@ apply_var_decoration(struct vtn_builder *b,
SpvBuiltIn builtin = dec->operands[0];
nir_variable_mode mode = var_data->mode;
vtn_get_builtin_location(b, builtin, &var_data->location, &mode);
enum glsl_interp_mode interpolation = var_data->interpolation;
vtn_get_builtin_location(b, builtin, &var_data->location, &mode, &interpolation);
var_data->mode = mode;
var_data->interpolation = interpolation;
switch (builtin) {
case SpvBuiltInTessLevelOuter: