From 02b249d5e753f3271877094c454b68d618870440 Mon Sep 17 00:00:00 2001
From: Francisco Casas <fcasas@codeweavers.com>
Date: Mon, 24 Jun 2024 17:30:46 -0400
Subject: [PATCH 1/5] vkd3d-shader/hlsl: Introduce enum hlsl_compile_type.

---
 libs/vkd3d-shader/hlsl.c | 47 +++++++++++++++++++++++++---------------
 libs/vkd3d-shader/hlsl.h | 16 +++++++++-----
 libs/vkd3d-shader/hlsl.y |  3 ++-
 3 files changed, 43 insertions(+), 23 deletions(-)

diff --git a/libs/vkd3d-shader/hlsl.c b/libs/vkd3d-shader/hlsl.c
index 6f737be2e2..d86097a39c 100644
--- a/libs/vkd3d-shader/hlsl.c
+++ b/libs/vkd3d-shader/hlsl.c
@@ -1847,30 +1847,36 @@ struct hlsl_ir_node *hlsl_new_swizzle(struct hlsl_ctx *ctx, uint32_t s, unsigned
     return &swizzle->node;
 }
 
-struct hlsl_ir_node *hlsl_new_compile(struct hlsl_ctx *ctx, const char *profile_name,
-        struct hlsl_ir_node **args, unsigned int args_count, struct hlsl_block *args_instrs,
-        const struct vkd3d_shader_location *loc)
+struct hlsl_ir_node *hlsl_new_compile(struct hlsl_ctx *ctx, enum hlsl_compile_type compile_type,
+        const char *profile_name, struct hlsl_ir_node **args, unsigned int args_count,
+        struct hlsl_block *args_instrs, const struct vkd3d_shader_location *loc)
 {
     const struct hlsl_profile_info *profile_info = NULL;
     struct hlsl_ir_compile *compile;
     struct hlsl_type *type = NULL;
     unsigned int i;
 
-    if (!(profile_info = hlsl_get_target_info(profile_name)))
+    switch (compile_type)
     {
-        hlsl_error(ctx, loc, VKD3D_SHADER_ERROR_HLSL_INVALID_PROFILE, "Unknown profile \"%s\".", profile_name);
-        return NULL;
-    }
+        case HLSL_COMPILE_TYPE_COMPILE:
+            if (!(profile_info = hlsl_get_target_info(profile_name)))
+            {
+                hlsl_error(ctx, loc, VKD3D_SHADER_ERROR_HLSL_INVALID_PROFILE, "Unknown profile \"%s\".", profile_name);
+                return NULL;
+            }
 
-    if (profile_info->type == VKD3D_SHADER_TYPE_PIXEL)
-        type = hlsl_get_type(ctx->cur_scope, "PixelShader", true, true);
-    else if (profile_info->type == VKD3D_SHADER_TYPE_VERTEX)
-        type = hlsl_get_type(ctx->cur_scope, "VertexShader", true, true);
+            if (profile_info->type == VKD3D_SHADER_TYPE_PIXEL)
+                type = hlsl_get_type(ctx->cur_scope, "PixelShader", true, true);
+            else if (profile_info->type == VKD3D_SHADER_TYPE_VERTEX)
+                type = hlsl_get_type(ctx->cur_scope, "VertexShader", true, true);
 
-    if (!type)
-    {
-        hlsl_error(ctx, loc, VKD3D_SHADER_ERROR_HLSL_INVALID_PROFILE, "Invalid profile \"%s\".", profile_name);
-        return NULL;
+            if (!type)
+            {
+                hlsl_error(ctx, loc, VKD3D_SHADER_ERROR_HLSL_INVALID_PROFILE, "Invalid profile \"%s\".", profile_name);
+                return NULL;
+            }
+
+            break;
     }
 
     if (!(compile = hlsl_alloc(ctx, sizeof(*compile))))
@@ -1878,6 +1884,7 @@ struct hlsl_ir_node *hlsl_new_compile(struct hlsl_ctx *ctx, const char *profile_
 
     init_node(&compile->node, HLSL_IR_COMPILE, type, loc);
 
+    compile->compile_type = compile_type;
     compile->profile = profile_info;
 
     hlsl_block_init(&compile->instrs);
@@ -2271,7 +2278,8 @@ static struct hlsl_ir_node *clone_compile(struct hlsl_ctx *ctx,
     if (compile->profile)
         profile_name = compile->profile->name;
 
-    if (!(node = hlsl_new_compile(ctx, profile_name, args, compile->args_count, &block, &compile->node.loc)))
+    if (!(node = hlsl_new_compile(ctx, compile->compile_type, profile_name,
+            args, compile->args_count, &block, &compile->node.loc)))
     {
         hlsl_block_cleanup(&block);
         vkd3d_free(args);
@@ -3300,7 +3308,12 @@ static void dump_ir_compile(struct hlsl_ctx *ctx, struct vkd3d_string_buffer *bu
 {
     unsigned int i;
 
-    vkd3d_string_buffer_printf(buffer, "compile %s {\n", compile->profile->name);
+    switch (compile->compile_type)
+    {
+        case HLSL_COMPILE_TYPE_COMPILE:
+            vkd3d_string_buffer_printf(buffer, "compile %s {\n", compile->profile->name);
+            break;
+    }
 
     dump_block(ctx, buffer, &compile->instrs);
 
diff --git a/libs/vkd3d-shader/hlsl.h b/libs/vkd3d-shader/hlsl.h
index 6e61db748b..c39d58d961 100644
--- a/libs/vkd3d-shader/hlsl.h
+++ b/libs/vkd3d-shader/hlsl.h
@@ -875,14 +875,20 @@ struct hlsl_ir_compile
 {
     struct hlsl_ir_node node;
 
-    /* Special field to store the profile argument. */
+    enum hlsl_compile_type
+    {
+        /* A shader compilation through the CompileShader() function or the "compile" syntax. */
+        HLSL_COMPILE_TYPE_COMPILE,
+    } compile_type;
+
+    /* Special field to store the profile argument for HLSL_COMPILE_TYPE_COMPILE. */
     const struct hlsl_profile_info *profile;
 
     /* Block containing the instructions required by the arguments of the
      * compilation call. */
     struct hlsl_block instrs;
 
-    /* Arguments to the compilation call. For a "compile" or "CompileShader()"
+    /* Arguments to the compilation call. For HLSL_COMPILE_TYPE_COMPILE
      * args[0] is an hlsl_ir_call to the specified function. */
     struct hlsl_src *args;
     unsigned int args_count;
@@ -1491,9 +1497,9 @@ bool hlsl_index_is_noncontiguous(struct hlsl_ir_index *index);
 bool hlsl_index_is_resource_access(struct hlsl_ir_index *index);
 bool hlsl_index_chain_has_resource_access(struct hlsl_ir_index *index);
 
-struct hlsl_ir_node *hlsl_new_compile(struct hlsl_ctx *ctx, const char *profile_name,
-        struct hlsl_ir_node **args, unsigned int args_count, struct hlsl_block *args_instrs,
-        const struct vkd3d_shader_location *loc);
+struct hlsl_ir_node *hlsl_new_compile(struct hlsl_ctx *ctx, enum hlsl_compile_type compile_type,
+        const char *profile_name, struct hlsl_ir_node **args, unsigned int args_count,
+        struct hlsl_block *args_instrs, const struct vkd3d_shader_location *loc);
 struct hlsl_ir_node *hlsl_new_index(struct hlsl_ctx *ctx, struct hlsl_ir_node *val,
         struct hlsl_ir_node *idx, const struct vkd3d_shader_location *loc);
 struct hlsl_ir_node *hlsl_new_loop(struct hlsl_ctx *ctx,
diff --git a/libs/vkd3d-shader/hlsl.y b/libs/vkd3d-shader/hlsl.y
index 60e196c63c..77134c26e1 100644
--- a/libs/vkd3d-shader/hlsl.y
+++ b/libs/vkd3d-shader/hlsl.y
@@ -5224,7 +5224,8 @@ static struct hlsl_block *add_shader_compilation(struct hlsl_ctx *ctx, const cha
         return NULL;
     }
 
-    if (!(compile = hlsl_new_compile(ctx, profile_name, &call_to_compile, 1, args->instrs, loc)))
+    if (!(compile = hlsl_new_compile(ctx, HLSL_COMPILE_TYPE_COMPILE,
+            profile_name, &call_to_compile, 1, args->instrs, loc)))
     {
         free_parse_initializer(args);
         return NULL;
-- 
GitLab


From 3423d1b54b5c8937bf433f9735dc2e3a83d23040 Mon Sep 17 00:00:00 2001
From: Francisco Casas <fcasas@codeweavers.com>
Date: Tue, 25 Jun 2024 21:18:14 -0400
Subject: [PATCH 2/5] tests: Test ConstructGSWithSO() parsing.

---
 Makefile.am                              |  1 +
 tests/hlsl/constructgswithso.shader_test | 35 ++++++++++++++++++++++++
 2 files changed, 36 insertions(+)
 create mode 100644 tests/hlsl/constructgswithso.shader_test

diff --git a/Makefile.am b/Makefile.am
index c86715108b..1c8ef1235d 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -88,6 +88,7 @@ vkd3d_shader_tests = \
 	tests/hlsl/compute.shader_test \
 	tests/hlsl/conditional.shader_test \
 	tests/hlsl/const.shader_test \
+        tests/hlsl/constructgswithso.shader_test \
 	tests/hlsl/coverage.shader_test \
 	tests/hlsl/cross.shader_test \
 	tests/hlsl/d3dcolor-to-ubyte4.shader_test \
diff --git a/tests/hlsl/constructgswithso.shader_test b/tests/hlsl/constructgswithso.shader_test
new file mode 100644
index 0000000000..0ea82708a0
--- /dev/null
+++ b/tests/hlsl/constructgswithso.shader_test
@@ -0,0 +1,35 @@
+[pixel shader todo]
+float4 main() : sv_target { return 0; }
+
+GeometryShader gs1 = CompileShader(gs_5_0, main());
+GeometryShader gs2 = ConstructGSWithSO(gs1, "random_string", "another_string", NULL, NULL, 1);
+
+technique11
+{
+    pass
+    {
+        SetGeometryShader(gs2);
+    }
+}
+
+% ConstructGSWithSO for pixel shaders parses with either 2 or 6 arguments, without doing type checking.
+[pixel shader fail(sm<6)]
+float4 main() : sv_target { return 0; }
+GeometryShader gs1 = CompileShader(gs_5_0, main());
+GeometryShader gs2 = ConstructGSWithSO(gs1);
+
+[pixel shader todo]
+float4 main() : sv_target { return 0; }
+GeometryShader gs2 = ConstructGSWithSO("foo", "bar");
+
+[pixel shader fail(sm<6)]
+float4 main() : sv_target { return 0; }
+GeometryShader gs2 = ConstructGSWithSO(1, 2, 3);
+
+[pixel shader todo]
+float4 main() : sv_target { return 0; }
+GeometryShader gs2 = ConstructGSWithSO("foo", "bar", float2(42, 42), 3, 4, NULL);
+
+[pixel shader fail(sm<6)]
+float4 main() : sv_target { return 0; }
+GeometryShader gs2 = ConstructGSWithSO(1, 2, 3, 4, 5, 6, 7);
-- 
GitLab


From 1f9fc2a422d51c3f618687127c14e599b62374f5 Mon Sep 17 00:00:00 2001
From: Francisco Casas <fcasas@codeweavers.com>
Date: Fri, 21 Jun 2024 15:59:23 -0400
Subject: [PATCH 3/5] vkd3d-shader/hlsl: Process GeometryShader as a valid
 stateblock lhs.

---
 libs/vkd3d-shader/fx.c   | 3 +++
 libs/vkd3d-shader/hlsl.c | 1 +
 libs/vkd3d-shader/hlsl.y | 5 +++++
 3 files changed, 9 insertions(+)

diff --git a/libs/vkd3d-shader/fx.c b/libs/vkd3d-shader/fx.c
index 2c2e486aa0..1314bc09e7 100644
--- a/libs/vkd3d-shader/fx.c
+++ b/libs/vkd3d-shader/fx.c
@@ -570,6 +570,9 @@ static const char * get_fx_4_type_name(const struct hlsl_type *type)
         case HLSL_CLASS_VERTEX_SHADER:
             return "VertexShader";
 
+        case HLSL_CLASS_GEOMETRY_SHADER:
+            return "GeometryShader";
+
         case HLSL_CLASS_PIXEL_SHADER:
             return "PixelShader";
 
diff --git a/libs/vkd3d-shader/hlsl.c b/libs/vkd3d-shader/hlsl.c
index d86097a39c..ddf06b7254 100644
--- a/libs/vkd3d-shader/hlsl.c
+++ b/libs/vkd3d-shader/hlsl.c
@@ -969,6 +969,7 @@ static const char * get_case_insensitive_typename(const char *name)
     {
         "dword",
         "float",
+        "geometryshader",
         "matrix",
         "pixelshader",
         "texture",
diff --git a/libs/vkd3d-shader/hlsl.y b/libs/vkd3d-shader/hlsl.y
index 77134c26e1..46a45bca8e 100644
--- a/libs/vkd3d-shader/hlsl.y
+++ b/libs/vkd3d-shader/hlsl.y
@@ -7797,6 +7797,11 @@ stateblock_lhs_identifier:
             if (!($$ = hlsl_strdup(ctx, "vertexshader")))
                 YYABORT;
         }
+    | KW_GEOMETRYSHADER
+        {
+            if (!($$ = hlsl_strdup(ctx, "geometryshader")))
+                YYABORT;
+        }
 
 state_block_index_opt:
       %empty
-- 
GitLab


From 4aa262d773a8c55154af65c9ce49faf1ace0ae2c Mon Sep 17 00:00:00 2001
From: Francisco Casas <fcasas@codeweavers.com>
Date: Mon, 24 Jun 2024 19:22:22 -0400
Subject: [PATCH 4/5] vkd3d-shader/hlsl: Parse ConstructGSWithSO().

---
 libs/vkd3d-shader/hlsl.c                 |  8 ++++++
 libs/vkd3d-shader/hlsl.h                 |  2 ++
 libs/vkd3d-shader/hlsl.l                 |  1 +
 libs/vkd3d-shader/hlsl.y                 | 36 ++++++++++++++++++++++++
 tests/hlsl/constructgswithso.shader_test |  4 +--
 5 files changed, 49 insertions(+), 2 deletions(-)

diff --git a/libs/vkd3d-shader/hlsl.c b/libs/vkd3d-shader/hlsl.c
index ddf06b7254..895a026571 100644
--- a/libs/vkd3d-shader/hlsl.c
+++ b/libs/vkd3d-shader/hlsl.c
@@ -1878,6 +1878,10 @@ struct hlsl_ir_node *hlsl_new_compile(struct hlsl_ctx *ctx, enum hlsl_compile_ty
             }
 
             break;
+
+        case HLSL_COMPILE_TYPE_CONSTRUCTGSWITHSO:
+            type = hlsl_get_type(ctx->cur_scope, "GeometryShader", true, true);
+            break;
     }
 
     if (!(compile = hlsl_alloc(ctx, sizeof(*compile))))
@@ -3314,6 +3318,10 @@ static void dump_ir_compile(struct hlsl_ctx *ctx, struct vkd3d_string_buffer *bu
         case HLSL_COMPILE_TYPE_COMPILE:
             vkd3d_string_buffer_printf(buffer, "compile %s {\n", compile->profile->name);
             break;
+
+        case HLSL_COMPILE_TYPE_CONSTRUCTGSWITHSO:
+            vkd3d_string_buffer_printf(buffer, "ConstructGSWithSO {\n");
+            break;
     }
 
     dump_block(ctx, buffer, &compile->instrs);
diff --git a/libs/vkd3d-shader/hlsl.h b/libs/vkd3d-shader/hlsl.h
index c39d58d961..51ef19449a 100644
--- a/libs/vkd3d-shader/hlsl.h
+++ b/libs/vkd3d-shader/hlsl.h
@@ -879,6 +879,8 @@ struct hlsl_ir_compile
     {
         /* A shader compilation through the CompileShader() function or the "compile" syntax. */
         HLSL_COMPILE_TYPE_COMPILE,
+        /* A call to ConstructGSWithSO(), which receives a geometry shader and retrieves one as well. */
+        HLSL_COMPILE_TYPE_CONSTRUCTGSWITHSO,
     } compile_type;
 
     /* Special field to store the profile argument for HLSL_COMPILE_TYPE_COMPILE. */
diff --git a/libs/vkd3d-shader/hlsl.l b/libs/vkd3d-shader/hlsl.l
index e5472709a8..b7c242661e 100644
--- a/libs/vkd3d-shader/hlsl.l
+++ b/libs/vkd3d-shader/hlsl.l
@@ -82,6 +82,7 @@ ComputeShader           {return KW_COMPUTESHADER;       }
 compile                 {return KW_COMPILE;             }
 CompileShader           {return KW_COMPILESHADER;       }
 const                   {return KW_CONST;               }
+ConstructGSWithSO       {return KW_CONSTRUCTGSWITHSO;   }
 continue                {return KW_CONTINUE;            }
 DepthStencilState       {return KW_DEPTHSTENCILSTATE;   }
 DepthStencilView        {return KW_DEPTHSTENCILVIEW;    }
diff --git a/libs/vkd3d-shader/hlsl.y b/libs/vkd3d-shader/hlsl.y
index 46a45bca8e..787373cc9e 100644
--- a/libs/vkd3d-shader/hlsl.y
+++ b/libs/vkd3d-shader/hlsl.y
@@ -5235,6 +5235,36 @@ static struct hlsl_block *add_shader_compilation(struct hlsl_ctx *ctx, const cha
     return make_block(ctx, compile);
 }
 
+static struct hlsl_block *add_compile_variant(struct hlsl_ctx *ctx, enum hlsl_compile_type compile_type,
+        struct parse_initializer *args, const struct vkd3d_shader_location *loc)
+{
+    struct hlsl_ir_node *compile;
+
+    switch (compile_type)
+    {
+        case HLSL_COMPILE_TYPE_COMPILE:
+            vkd3d_unreachable();
+
+        case HLSL_COMPILE_TYPE_CONSTRUCTGSWITHSO:
+            if (args->args_count != 2 && args->args_count != 6)
+            {
+                hlsl_error(ctx, loc, VKD3D_SHADER_ERROR_HLSL_WRONG_PARAMETER_COUNT,
+                        "Wrong number of arguments to ConstructGSWithSO: expected 2 or 6, but got %u.",
+                        args->args_count);
+            }
+            break;
+    }
+
+    if (!(compile = hlsl_new_compile(ctx, compile_type, NULL, args->args, args->args_count, args->instrs, loc)))
+    {
+        free_parse_initializer(args);
+        return NULL;
+    }
+
+    free_parse_initializer(args);
+    return make_block(ctx, compile);
+}
+
 static struct hlsl_block *add_constructor(struct hlsl_ctx *ctx, struct hlsl_type *type,
         struct parse_initializer *params, const struct vkd3d_shader_location *loc)
 {
@@ -6236,6 +6266,7 @@ static bool state_block_add_entry(struct hlsl_state_block *state_block, struct h
 %token KW_COMPILESHADER
 %token KW_COMPUTESHADER
 %token KW_CONST
+%token KW_CONSTRUCTGSWITHSO
 %token KW_CONTINUE
 %token KW_DEFAULT
 %token KW_DEPTHSTENCILSTATE
@@ -8596,6 +8627,11 @@ primary_expr:
             vkd3d_free($3);
             vkd3d_free($5);
         }
+    | KW_CONSTRUCTGSWITHSO '(' func_arguments ')'
+        {
+            if (!($$ = add_compile_variant(ctx, HLSL_COMPILE_TYPE_CONSTRUCTGSWITHSO, &$3, &@1)))
+                YYABORT;
+        }
     | var_identifier '(' func_arguments ')'
         {
             if (!($$ = add_call(ctx, $1, &$3, &@1)))
diff --git a/tests/hlsl/constructgswithso.shader_test b/tests/hlsl/constructgswithso.shader_test
index 0ea82708a0..50e5cbed01 100644
--- a/tests/hlsl/constructgswithso.shader_test
+++ b/tests/hlsl/constructgswithso.shader_test
@@ -18,7 +18,7 @@ float4 main() : sv_target { return 0; }
 GeometryShader gs1 = CompileShader(gs_5_0, main());
 GeometryShader gs2 = ConstructGSWithSO(gs1);
 
-[pixel shader todo]
+[pixel shader]
 float4 main() : sv_target { return 0; }
 GeometryShader gs2 = ConstructGSWithSO("foo", "bar");
 
@@ -26,7 +26,7 @@ GeometryShader gs2 = ConstructGSWithSO("foo", "bar");
 float4 main() : sv_target { return 0; }
 GeometryShader gs2 = ConstructGSWithSO(1, 2, 3);
 
-[pixel shader todo]
+[pixel shader]
 float4 main() : sv_target { return 0; }
 GeometryShader gs2 = ConstructGSWithSO("foo", "bar", float2(42, 42), 3, 4, NULL);
 
-- 
GitLab


From ffc14494124e2046b505f2d15c11b03b29e8b08f Mon Sep 17 00:00:00 2001
From: Francisco Casas <fcasas@codeweavers.com>
Date: Tue, 25 Jun 2024 18:36:32 -0400
Subject: [PATCH 5/5] vkd3d-shader/hlsl: Allow effect calls on default value
 initializers.

---
 libs/vkd3d-shader/hlsl.y                 | 62 ++++++++++++++++--------
 libs/vkd3d-shader/vkd3d_shader_private.h |  1 +
 tests/hlsl/annotations.shader_test       |  2 +-
 tests/hlsl/array-dimension.shader_test   |  8 +++
 tests/hlsl/default-values.shader_test    | 11 +++++
 tests/hlsl/effect-compile.shader_test    |  8 +--
 6 files changed, 68 insertions(+), 24 deletions(-)

diff --git a/libs/vkd3d-shader/hlsl.y b/libs/vkd3d-shader/hlsl.y
index 787373cc9e..489fbd5582 100644
--- a/libs/vkd3d-shader/hlsl.y
+++ b/libs/vkd3d-shader/hlsl.y
@@ -609,6 +609,7 @@ static struct hlsl_default_value evaluate_static_expression(struct hlsl_ctx *ctx
     {
         switch (node->type)
         {
+            case HLSL_IR_COMPILE:
             case HLSL_IR_CONSTANT:
             case HLSL_IR_EXPR:
             case HLSL_IR_STRING_CONSTANT:
@@ -627,7 +628,6 @@ static struct hlsl_default_value evaluate_static_expression(struct hlsl_ctx *ctx
             case HLSL_IR_RESOURCE_LOAD:
             case HLSL_IR_RESOURCE_STORE:
             case HLSL_IR_SWITCH:
-            case HLSL_IR_COMPILE:
             case HLSL_IR_STATEBLOCK_CONSTANT:
                 hlsl_error(ctx, &node->loc, VKD3D_SHADER_ERROR_HLSL_INVALID_SYNTAX,
                         "Expected literal expression.");
@@ -1227,7 +1227,8 @@ static bool add_typedef(struct hlsl_ctx *ctx, struct hlsl_type *const orig_type,
 }
 
 static void initialize_var_components(struct hlsl_ctx *ctx, struct hlsl_block *instrs,
-        struct hlsl_ir_var *dst, unsigned int *store_index, struct hlsl_ir_node *src);
+        struct hlsl_ir_var *dst, unsigned int *store_index, struct hlsl_ir_node *src,
+        bool is_default_values_initializer);
 
 static bool add_func_parameter(struct hlsl_ctx *ctx, struct hlsl_func_parameters *parameters,
         struct parse_parameter *param, const struct vkd3d_shader_location *loc)
@@ -1285,7 +1286,8 @@ static bool add_func_parameter(struct hlsl_ctx *ctx, struct hlsl_func_parameters
 
         for (i = 0; i < param->initializer.args_count; ++i)
         {
-            initialize_var_components(ctx, param->initializer.instrs, var, &store_index, param->initializer.args[i]);
+            initialize_var_components(ctx, param->initializer.instrs, var,
+                    &store_index, param->initializer.args[i], true);
         }
 
         free_parse_initializer(&param->initializer);
@@ -2368,7 +2370,8 @@ static unsigned int get_component_index_from_default_initializer_index(struct hl
 }
 
 static void initialize_var_components(struct hlsl_ctx *ctx, struct hlsl_block *instrs,
-        struct hlsl_ir_var *dst, unsigned int *store_index, struct hlsl_ir_node *src)
+        struct hlsl_ir_var *dst, unsigned int *store_index, struct hlsl_ir_node *src,
+        bool is_default_values_initializer)
 {
     unsigned int src_comp_count = hlsl_type_component_count(src->data_type);
     struct hlsl_deref dst_deref;
@@ -2387,23 +2390,43 @@ static void initialize_var_components(struct hlsl_ctx *ctx, struct hlsl_block *i
 
         dst_comp_type = hlsl_type_get_component_type(ctx, dst->data_type, *store_index);
 
-        if (dst->default_values)
+        if (is_default_values_initializer)
         {
             struct hlsl_default_value default_value = {0};
             unsigned int dst_index;
 
-            if (!hlsl_clone_block(ctx, &block, instrs))
-                return;
-            default_value = evaluate_static_expression(ctx, &block, dst_comp_type, &src->loc);
+            if (hlsl_is_numeric_type(dst_comp_type))
+            {
+                if (src->type == HLSL_IR_COMPILE)
+                {
+                    /* Default values are discarded if they contain an object
+                     * literal expression for a numeric component. */
+                    if (dst->default_values)
+                    {
+                        hlsl_warning(ctx, &src->loc, VKD3D_SHADER_WARNING_HLSL_IGNORED_DEFAULT_VALUE,
+                                "Component %u in variable '%s' initializer is object literal. Default values discarded.",
+                                k, dst->name);
+                        vkd3d_free(dst->default_values);
+                        dst->default_values = NULL;
+                    }
+                }
+                else
+                {
+                    if (!hlsl_clone_block(ctx, &block, instrs))
+                        return;
+                    default_value = evaluate_static_expression(ctx, &block, dst_comp_type, &src->loc);
 
-            if (dst->is_param)
-                dst_index = *store_index;
-            else
-                dst_index = get_component_index_from_default_initializer_index(ctx, dst->data_type, *store_index);
+                    if (dst->is_param)
+                        dst_index = *store_index;
+                    else
+                        dst_index = get_component_index_from_default_initializer_index(ctx, dst->data_type, *store_index);
 
-            dst->default_values[dst_index] = default_value;
+                    if (dst->default_values)
+                        dst->default_values[dst_index] = default_value;
 
-            hlsl_block_cleanup(&block);
+                    hlsl_block_cleanup(&block);
+                }
+            }
         }
         else
         {
@@ -2793,7 +2816,8 @@ static struct hlsl_block *initialize_vars(struct hlsl_ctx *ctx, struct list *var
 
             for (k = 0; k < v->initializer.args_count; ++k)
             {
-                initialize_var_components(ctx, v->initializer.instrs, var, &store_index, v->initializer.args[k]);
+                initialize_var_components(ctx, v->initializer.instrs, var,
+                        &store_index, v->initializer.args[k], is_default_values_initializer);
             }
 
             if (is_default_values_initializer)
@@ -4785,17 +4809,17 @@ static bool intrinsic_tex(struct hlsl_ctx *ctx, const struct parse_initializer *
         if (!(var = hlsl_new_synthetic_var(ctx, "coords", hlsl_get_vector_type(ctx, HLSL_TYPE_FLOAT, 2), loc)))
             return false;
 
-        initialize_var_components(ctx, params->instrs, var, &idx, coords);
+        initialize_var_components(ctx, params->instrs, var, &idx, coords, false);
         if (hlsl_version_ge(ctx, 4, 0))
         {
             if (!(half = hlsl_new_float_constant(ctx, 0.5f, loc)))
                 return false;
             hlsl_block_add_instr(params->instrs, half);
 
-            initialize_var_components(ctx, params->instrs, var, &idx, half);
+            initialize_var_components(ctx, params->instrs, var, &idx, half, false);
         }
         else
-            initialize_var_components(ctx, params->instrs, var, &idx, coords);
+            initialize_var_components(ctx, params->instrs, var, &idx, coords, false);
 
         if (!(load = hlsl_new_var_load(ctx, var, loc)))
             return false;
@@ -5276,7 +5300,7 @@ static struct hlsl_block *add_constructor(struct hlsl_ctx *ctx, struct hlsl_type
         return NULL;
 
     for (i = 0; i < params->args_count; ++i)
-        initialize_var_components(ctx, params->instrs, var, &idx, params->args[i]);
+        initialize_var_components(ctx, params->instrs, var, &idx, params->args[i], false);
 
     if (!(load = hlsl_new_var_load(ctx, var, loc)))
         return NULL;
diff --git a/libs/vkd3d-shader/vkd3d_shader_private.h b/libs/vkd3d-shader/vkd3d_shader_private.h
index 6442943225..205da5c24e 100644
--- a/libs/vkd3d-shader/vkd3d_shader_private.h
+++ b/libs/vkd3d-shader/vkd3d_shader_private.h
@@ -165,6 +165,7 @@ enum vkd3d_shader_error
     VKD3D_SHADER_WARNING_HLSL_IMAGINARY_NUMERIC_RESULT  = 5303,
     VKD3D_SHADER_WARNING_HLSL_NON_FINITE_RESULT         = 5304,
     VKD3D_SHADER_WARNING_HLSL_IGNORED_ATTRIBUTE         = 5305,
+    VKD3D_SHADER_WARNING_HLSL_IGNORED_DEFAULT_VALUE     = 5306,
 
     VKD3D_SHADER_ERROR_GLSL_INTERNAL                    = 6000,
 
diff --git a/tests/hlsl/annotations.shader_test b/tests/hlsl/annotations.shader_test
index 4f4f4d670f..5db5dae32b 100644
--- a/tests/hlsl/annotations.shader_test
+++ b/tests/hlsl/annotations.shader_test
@@ -83,7 +83,7 @@ technique10
 // Without initializer
 technique10 < int a; > {}
 
-[effect fail]
+[effect fail todo]
 // Only numeric types and strings are allowed
 technique10 < DepthStencilState ds = { 0 }; > {}
 
diff --git a/tests/hlsl/array-dimension.shader_test b/tests/hlsl/array-dimension.shader_test
index 142fa22432..672f035a18 100644
--- a/tests/hlsl/array-dimension.shader_test
+++ b/tests/hlsl/array-dimension.shader_test
@@ -20,3 +20,11 @@ float4 main() : sv_target
 [test]
 todo(sm<6) draw quad
 probe (0, 0) rgba (0.1, 0.1, 0.2, 0.4)
+
+
+[pixel shader fail]
+float4 fun() { return 0; };
+
+float a[CompileShader(ps_2_0, main())];
+
+float4 main() : sv_target { return 0; }
diff --git a/tests/hlsl/default-values.shader_test b/tests/hlsl/default-values.shader_test
index 0d319f4dbd..6245ffc648 100644
--- a/tests/hlsl/default-values.shader_test
+++ b/tests/hlsl/default-values.shader_test
@@ -294,6 +294,17 @@ float4 main() : sv_target
 }
 
 
+% This compiles but default values for 'p' aren't written to the output binary.
+[pixel shader fail(sm>=6)]
+float4 fun() { return 0; };
+float2 p = {5, CompileShader(ps_2_0, fun())};
+
+float4 main() : sv_target
+{
+    return p.xyxy;
+}
+
+
 [require]
 shader model >= 5.0
 
diff --git a/tests/hlsl/effect-compile.shader_test b/tests/hlsl/effect-compile.shader_test
index 7155fc5692..48a1dd800c 100644
--- a/tests/hlsl/effect-compile.shader_test
+++ b/tests/hlsl/effect-compile.shader_test
@@ -161,13 +161,13 @@ float4 main() : sv_target { return 0; }
 PixelShader ps1 = {42}; // braces make the type checking more permissive.
 
 % This compiles, but the default value of "f" is not written.
-[pixel shader todo fail(sm>=6)]
+[pixel shader fail(sm>=6)]
 float4 fun() : sv_target { return 0; }
 float f = {CompileShader(ps_2_0, fun())};
 float4 main() : sv_target { return f; }
 
 % This also compiles, but the default value of "f" is not written.
-[pixel shader todo fail(sm>=6)]
+[pixel shader fail(sm>=6)]
 float4 fun() : sv_target { return 0; }
 float4 f = {1, 2, compile ps_2_0 fun(), 4};
 float4 main() : sv_target { return f; }
@@ -225,7 +225,7 @@ shader model < 6.0
 
 
 % The following test segfaults on DXC.
-[pixel shader todo]
+[pixel shader]
 float f;
 
 float4 foo(uniform float r) : sv_target { return r; }
@@ -247,7 +247,7 @@ technique
 float4 main() : sv_target { return 0; }
 
 [test]
-todo draw quad
+todo(glsl) draw quad
 probe (0, 0) rgba (0, 0, 0, 0)
 
 
-- 
GitLab