From 7df92b6e502ea774f2cbfb4acfc6f2c218c8de6b Mon Sep 17 00:00:00 2001 From: Giovanni Mascellani Date: Sun, 27 Jul 2025 15:06:06 +0200 Subject: [PATCH] vkd3d-shader/msl: Reject shaders with duplicate I/O target locations. We'll have to handle them eventually, but let's avoid generating invalid code in the meantime. --- libs/vkd3d-shader/msl.c | 32 ++++++++++++++++++++++++++++++-- 1 file changed, 30 insertions(+), 2 deletions(-) diff --git a/libs/vkd3d-shader/msl.c b/libs/vkd3d-shader/msl.c index cf01772ef..bfab70423 100644 --- a/libs/vkd3d-shader/msl.c +++ b/libs/vkd3d-shader/msl.c @@ -18,6 +18,8 @@ #include "vkd3d_shader_private.h" +#define MAX_IO_REG_COUNT 32 + enum msl_data_type { MSL_DATA_FLOAT, @@ -1614,6 +1616,7 @@ static void msl_generate_input_struct_declarations(struct msl_generator *gen) const struct shader_signature *signature = &gen->program->input_signature; enum vkd3d_shader_type type = gen->program->shader_version.type; struct vkd3d_string_buffer *buffer = gen->buffer; + bool locations[MAX_IO_REG_COUNT] = {0}; const struct signature_element *e; unsigned int i; @@ -1626,6 +1629,18 @@ static void msl_generate_input_struct_declarations(struct msl_generator *gen) if (e->target_location == SIGNATURE_TARGET_LOCATION_UNUSED) continue; + if (e->target_location >= ARRAY_SIZE(locations)) + { + msl_compiler_error(gen, VKD3D_SHADER_ERROR_MSL_INTERNAL, + "Internal compiler error: Unhandled input target location %u.", e->target_location); + continue; + } + + if (locations[e->target_location]) + msl_compiler_error(gen, VKD3D_SHADER_ERROR_MSL_INTERNAL, + "Internal compiler error: Unhandled duplicate input target location %u.", e->target_location); + locations[e->target_location] = true; + switch (e->sysval_semantic) { case VKD3D_SHADER_SV_NONE: @@ -1777,6 +1792,7 @@ static void msl_generate_output_struct_declarations(struct msl_generator *gen) const struct shader_signature *signature = &gen->program->output_signature; enum vkd3d_shader_type type = gen->program->shader_version.type; struct vkd3d_string_buffer *buffer = gen->buffer; + bool locations[MAX_IO_REG_COUNT] = {0}; const struct signature_element *e; unsigned int i; @@ -1790,6 +1806,18 @@ static void msl_generate_output_struct_declarations(struct msl_generator *gen) || e->sysval_semantic == VKD3D_SHADER_SV_DEPTH) continue; + if (e->target_location >= ARRAY_SIZE(locations)) + { + msl_compiler_error(gen, VKD3D_SHADER_ERROR_MSL_INTERNAL, + "Internal compiler error: Unhandled input target location %u.", e->target_location); + continue; + } + + if (locations[e->target_location]) + msl_compiler_error(gen, VKD3D_SHADER_ERROR_MSL_INTERNAL, + "Internal compiler error: Unhandled duplicate input target location %u.", e->target_location); + locations[e->target_location] = true; + if (e->min_precision != VKD3D_SHADER_MINIMUM_PRECISION_NONE) { msl_compiler_error(gen, VKD3D_SHADER_ERROR_MSL_INTERNAL, @@ -1995,8 +2023,8 @@ static void msl_generate_entrypoint(struct msl_generator *gen) vkd3d_string_buffer_printf(gen->buffer, "vkd3d_%s_in input [[stage_in]])\n{\n", gen->prefix); /* TODO: declare #maximum_register + 1 */ - vkd3d_string_buffer_printf(gen->buffer, " vkd3d_vec4 %s_in[%u];\n", gen->prefix, 32); - vkd3d_string_buffer_printf(gen->buffer, " vkd3d_vec4 %s_out[%u];\n", gen->prefix, 32); + vkd3d_string_buffer_printf(gen->buffer, " vkd3d_vec4 %s_in[%u];\n", gen->prefix, MAX_IO_REG_COUNT); + vkd3d_string_buffer_printf(gen->buffer, " vkd3d_vec4 %s_out[%u];\n", gen->prefix, MAX_IO_REG_COUNT); vkd3d_string_buffer_printf(gen->buffer, " vkd3d_%s_out output;\n", gen->prefix); if (bitmap_is_set(gen->program->io_dcls, VKD3DSPR_SAMPLEMASK)) vkd3d_string_buffer_printf(gen->buffer, " vkd3d_scalar o_mask;\n");