From b31dc058b913390e6bdc46eccd0b31299734cdab Mon Sep 17 00:00:00 2001 From: Shaun Ren Date: Mon, 17 Nov 2025 22:04:52 -0500 Subject: [PATCH] vkd3d-shader/hlsl: Validate groupshared variables. --- libs/vkd3d-shader/hlsl.y | 30 ++++++++++++++++++++++++++---- tests/hlsl/tgsm.shader_test | 4 ++-- 2 files changed, 28 insertions(+), 6 deletions(-) diff --git a/libs/vkd3d-shader/hlsl.y b/libs/vkd3d-shader/hlsl.y index 4efa1cd28..d5dcc775a 100644 --- a/libs/vkd3d-shader/hlsl.y +++ b/libs/vkd3d-shader/hlsl.y @@ -2410,6 +2410,21 @@ static void check_invalid_object_fields(struct hlsl_ctx *ctx, const struct hlsl_ "Target profile doesn't support objects as struct members in uniform variables."); } +static void validate_groupshared_var(struct hlsl_ctx *ctx, const struct hlsl_ir_var *var) +{ + if (type_has_object_components(var->data_type)) + { + struct vkd3d_string_buffer *string; + + if ((string = hlsl_type_to_string(ctx, var->data_type))) + { + hlsl_error(ctx, &var->loc, VKD3D_SHADER_ERROR_HLSL_INVALID_TYPE, + "Groupshared type %s is not numeric.", string->buffer); + hlsl_release_string_buffer(ctx, string); + } + } +} + static void declare_var(struct hlsl_ctx *ctx, struct parse_variable_def *v) { uint32_t modifiers = v->modifiers | v->semantic.modifiers; @@ -2564,11 +2579,18 @@ static void declare_var(struct hlsl_ctx *ctx, struct parse_variable_def *v) hlsl_error(ctx, &var->loc, VKD3D_SHADER_ERROR_HLSL_INVALID_MODIFIER, "Variable '%s' is declared as both \"uniform\" and \"static\".", var->name); - if ((modifiers & HLSL_STORAGE_GROUPSHARED) && ctx->profile->type != VKD3D_SHADER_TYPE_COMPUTE) + if ((modifiers & HLSL_STORAGE_GROUPSHARED)) { - modifiers &= ~HLSL_STORAGE_GROUPSHARED; - hlsl_warning(ctx, &var->loc, VKD3D_SHADER_WARNING_HLSL_IGNORED_MODIFIER, - "Ignoring the 'groupshared' modifier in a non-compute shader."); + /* d3dcompiler/fxc always validates global groupshared variables, + * regardless of whether the groupshared modifier is ignored. */ + validate_groupshared_var(ctx, var); + + if (ctx->profile->type != VKD3D_SHADER_TYPE_COMPUTE) + { + modifiers &= ~HLSL_STORAGE_GROUPSHARED; + hlsl_warning(ctx, &var->loc, VKD3D_SHADER_WARNING_HLSL_IGNORED_MODIFIER, + "Ignoring the 'groupshared' modifier in a non-compute shader."); + } } /* Mark it as uniform. We need to do this here since synthetic diff --git a/tests/hlsl/tgsm.shader_test b/tests/hlsl/tgsm.shader_test index c26f6e551..4dd0bc062 100644 --- a/tests/hlsl/tgsm.shader_test +++ b/tests/hlsl/tgsm.shader_test @@ -49,7 +49,7 @@ void main(uint local_idx : SV_GroupIndex) shader model >= 4.0 % The type of a groupshared variable must not contain objects. -[compute shader fail(sm<6) todo] +[compute shader fail(sm<6)] struct data { Texture2D tex; @@ -65,7 +65,7 @@ void main(uint local_idx : SV_GroupIndex) % Even though the 'groupshared' attribute is ignored in non-compute shaders, % native still checks whether the type of the variable contains objects or not. -[pixel shader fail(sm<6) todo] +[pixel shader fail(sm<6) todo(sm>=5.1 & sm<6)] groupshared Texture2D m[4]; float4 main() : SV_Target