From a65c0b0e22195cfe4bdeb760e74bc6a86a46e8b1 Mon Sep 17 00:00:00 2001
From: Nikolay Sivov <nsivov@codeweavers.com>
Date: Wed, 28 Jun 2023 11:28:49 +0200
Subject: [PATCH 1/2] vkd3d-shader/hlsl: Support evaluated expressions for
 sample count in multisampled textures declarations.

Signed-off-by: Nikolay Sivov <nsivov@codeweavers.com>
---
 libs/vkd3d-shader/hlsl.y            | 20 +++++++++++++++-----
 tests/hlsl/texture-load.shader_test |  3 ++-
 2 files changed, 17 insertions(+), 6 deletions(-)

diff --git a/libs/vkd3d-shader/hlsl.y b/libs/vkd3d-shader/hlsl.y
index 80ba8e1186..3dd8dd3a41 100644
--- a/libs/vkd3d-shader/hlsl.y
+++ b/libs/vkd3d-shader/hlsl.y
@@ -1139,20 +1139,28 @@ static unsigned int evaluate_static_expression_as_uint(struct hlsl_ctx *ctx, str
 {
     struct hlsl_ir_constant *constant;
     struct hlsl_ir_node *node;
+    struct hlsl_block expr;
     unsigned int ret = 0;
     bool progress;
 
-    if (!add_implicit_conversion(ctx, &block->instrs, node_from_list(&block->instrs),
+    if (!hlsl_clone_block(ctx, &expr, &ctx->static_initializers))
+        return 0;
+    hlsl_block_add_block(&expr, block);
+
+    if (!add_implicit_conversion(ctx, &expr.instrs, node_from_list(&expr.instrs),
             hlsl_get_scalar_type(ctx, HLSL_TYPE_UINT), loc))
+    {
+        hlsl_block_cleanup(&expr);
         return 0;
+    }
 
     do
     {
-        progress = hlsl_transform_ir(ctx, hlsl_fold_constant_exprs, block, NULL);
-        progress |= hlsl_copy_propagation_execute(ctx, block);
+        progress = hlsl_transform_ir(ctx, hlsl_fold_constant_exprs, &expr, NULL);
+        progress |= hlsl_copy_propagation_execute(ctx, &expr);
     } while (progress);
 
-    node = node_from_list(&block->instrs);
+    node = node_from_list(&expr.instrs);
     if (node->type == HLSL_IR_CONSTANT)
     {
         constant = hlsl_ir_constant(node);
@@ -1164,6 +1172,8 @@ static unsigned int evaluate_static_expression_as_uint(struct hlsl_ctx *ctx, str
                 "Failed to evaluate constant expression %d.", node->type);
     }
 
+    hlsl_block_cleanup(&expr);
+
     return ret;
 }
 
@@ -5675,7 +5685,7 @@ arrays:
             uint32_t *new_array;
             unsigned int size;
 
-            hlsl_clone_block(ctx, &block, &ctx->static_initializers);
+            hlsl_block_init(&block);
             list_move_tail(&block.instrs, $2);
 
             size = evaluate_static_expression_as_uint(ctx, &block, &@2);
diff --git a/tests/hlsl/texture-load.shader_test b/tests/hlsl/texture-load.shader_test
index 4893e4d841..362e1d2e37 100644
--- a/tests/hlsl/texture-load.shader_test
+++ b/tests/hlsl/texture-load.shader_test
@@ -37,7 +37,8 @@ probe (0, 1) rgba (0.5, 0.7, 0.6, 0.8)
 probe (1, 1) rgba (0.8, 0.0, 0.7, 1.0)
 
 [pixel shader]
-Texture2DMS<float4, 1> t;
+static const int size = 2;
+Texture2DMS<float4, size - 1> t;
 
 float4 main(float4 pos : sv_position) : sv_target
 {
-- 
GitLab


From 06040d2a3034eafbe839951f77b6a7abda32f7ce Mon Sep 17 00:00:00 2001
From: Nikolay Sivov <nsivov@codeweavers.com>
Date: Wed, 28 Jun 2023 11:57:54 +0200
Subject: [PATCH 2/2] vkd3d-shader/hlsl: Disallow certain instruction types
 from constant expressions.

Signed-off-by: Nikolay Sivov <nsivov@codeweavers.com>
---
 libs/vkd3d-shader/hlsl.y               | 24 +++++++++++++++++++++++-
 tests/hlsl/array-size-expr.shader_test | 15 +++++++++++++++
 tests/hlsl/invalid.shader_test         |  2 +-
 3 files changed, 39 insertions(+), 2 deletions(-)

diff --git a/libs/vkd3d-shader/hlsl.y b/libs/vkd3d-shader/hlsl.y
index 3dd8dd3a41..82dd19ebb7 100644
--- a/libs/vkd3d-shader/hlsl.y
+++ b/libs/vkd3d-shader/hlsl.y
@@ -1143,6 +1143,28 @@ static unsigned int evaluate_static_expression_as_uint(struct hlsl_ctx *ctx, str
     unsigned int ret = 0;
     bool progress;
 
+    LIST_FOR_EACH_ENTRY(node, &block->instrs, struct hlsl_ir_node, entry)
+    {
+        switch (node->type)
+        {
+            case HLSL_IR_CONSTANT:
+            case HLSL_IR_EXPR:
+            case HLSL_IR_SWIZZLE:
+            case HLSL_IR_LOAD:
+            case HLSL_IR_INDEX:
+                continue;
+            case HLSL_IR_CALL:
+            case HLSL_IR_IF:
+            case HLSL_IR_LOOP:
+            case HLSL_IR_JUMP:
+            case HLSL_IR_RESOURCE_LOAD:
+            case HLSL_IR_RESOURCE_STORE:
+            case HLSL_IR_STORE:
+                hlsl_error(ctx, &node->loc, VKD3D_SHADER_ERROR_HLSL_INVALID_SYNTAX,
+                        "Expected literal expression.");
+        }
+    }
+
     if (!hlsl_clone_block(ctx, &expr, &ctx->static_initializers))
         return 0;
     hlsl_block_add_block(&expr, block);
@@ -1169,7 +1191,7 @@ static unsigned int evaluate_static_expression_as_uint(struct hlsl_ctx *ctx, str
     else
     {
         hlsl_error(ctx, &node->loc, VKD3D_SHADER_ERROR_HLSL_INVALID_SYNTAX,
-                "Failed to evaluate constant expression %d.", node->type);
+                "Failed to evaluate constant expression.");
     }
 
     hlsl_block_cleanup(&expr);
diff --git a/tests/hlsl/array-size-expr.shader_test b/tests/hlsl/array-size-expr.shader_test
index ac774be1b9..1fd4e2627a 100644
--- a/tests/hlsl/array-size-expr.shader_test
+++ b/tests/hlsl/array-size-expr.shader_test
@@ -51,3 +51,18 @@ float4 main() : sv_target
 [test]
 draw quad
 probe all rgba (2, 3, 6, 1)
+
+% Additional level of indirection
+[pixel shader todo]
+static const float array[8] = {1, 2, 3, 4, 5, 6, 7, 8};
+static const int idx = 2;
+static const float array2[array[idx]] = {1, 2, 3};
+
+float4 main() : sv_target
+{
+    return float4(array[1], array2[2], array[5], array[0]);
+}
+
+[test]
+todo draw quad
+probe all rgba (2, 3, 6, 1)
diff --git a/tests/hlsl/invalid.shader_test b/tests/hlsl/invalid.shader_test
index 61033811d7..ad0626520c 100644
--- a/tests/hlsl/invalid.shader_test
+++ b/tests/hlsl/invalid.shader_test
@@ -72,7 +72,7 @@ float4 main() : sv_target
     return 0;
 }
 
-[pixel shader fail todo]
+[pixel shader fail]
 float4 main() : sv_target
 {
     int x;
-- 
GitLab