[PATCH vkd3d v2] vkd3d-shader/hlsl: Correctly calculate offsets for array elements.

Matteo Bruni mbruni at codeweavers.com
Thu Mar 17 15:58:35 CDT 2022


From: Zebediah Figura <zfigura at codeweavers.com>

Signed-off-by: Matteo Bruni <mbruni at codeweavers.com>
---
v2: Improve comment in the shader test.

 Makefile.am                         |  2 +-
 libs/vkd3d-shader/hlsl.c            |  7 +++++++
 libs/vkd3d-shader/hlsl.h            |  1 +
 libs/vkd3d-shader/hlsl.y            |  2 +-
 libs/vkd3d-shader/hlsl_codegen.c    |  2 +-
 tests/hlsl-struct-array.shader_test | 19 +++++++++++++++++++
 6 files changed, 30 insertions(+), 3 deletions(-)
 create mode 100644 tests/hlsl-struct-array.shader_test

diff --git a/Makefile.am b/Makefile.am
index 79aacfcd..f2c8440c 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -96,6 +96,7 @@ vkd3d_shader_tests = \
 	tests/hlsl-state-block-syntax.shader_test \
 	tests/hlsl-static-initializer.shader_test \
 	tests/hlsl-storage-qualifiers.shader_test \
+	tests/hlsl-struct-array.shader_test \
 	tests/hlsl-struct-assignment.shader_test \
 	tests/hlsl-struct-semantics.shader_test \
 	tests/hlsl-vector-indexing.shader_test \
@@ -339,7 +340,6 @@ XFAIL_TESTS = \
 	tests/hlsl-majority-pragma.shader_test \
 	tests/hlsl-majority-typedef.shader_test \
 	tests/hlsl-mul.shader_test \
-	tests/hlsl-nested-arrays.shader_test \
 	tests/hlsl-numeric-constructor-truncation.shader_test \
 	tests/hlsl-numeric-types.shader_test \
 	tests/hlsl-return-implicit-conversion.shader_test \
diff --git a/libs/vkd3d-shader/hlsl.c b/libs/vkd3d-shader/hlsl.c
index ea5e35d2..d88b0b6d 100644
--- a/libs/vkd3d-shader/hlsl.c
+++ b/libs/vkd3d-shader/hlsl.c
@@ -202,6 +202,13 @@ static void hlsl_type_calculate_reg_size(struct hlsl_ctx *ctx, struct hlsl_type
     }
 }
 
+/* Returns the size of a type, considered as part of an array of that type.
+ * As such it includes padding after the type. */
+unsigned int hlsl_type_get_array_element_reg_size(const struct hlsl_type *type)
+{
+    return align(type->reg_size, 4);
+}
+
 static struct hlsl_type *hlsl_new_type(struct hlsl_ctx *ctx, const char *name, enum hlsl_type_class type_class,
         enum hlsl_base_type base_type, unsigned dimx, unsigned dimy)
 {
diff --git a/libs/vkd3d-shader/hlsl.h b/libs/vkd3d-shader/hlsl.h
index 243ed72b..2e8ba4af 100644
--- a/libs/vkd3d-shader/hlsl.h
+++ b/libs/vkd3d-shader/hlsl.h
@@ -783,6 +783,7 @@ bool hlsl_scope_add_type(struct hlsl_scope *scope, struct hlsl_type *type);
 struct hlsl_type *hlsl_type_clone(struct hlsl_ctx *ctx, struct hlsl_type *old,
         unsigned int default_majority, unsigned int modifiers);
 unsigned int hlsl_type_component_count(struct hlsl_type *type);
+unsigned int hlsl_type_get_array_element_reg_size(const struct hlsl_type *type);
 unsigned int hlsl_type_get_sm4_offset(const struct hlsl_type *type, unsigned int offset);
 bool hlsl_types_are_equal(const struct hlsl_type *t1, const struct hlsl_type *t2);
 
diff --git a/libs/vkd3d-shader/hlsl.y b/libs/vkd3d-shader/hlsl.y
index 92dcb3f2..521ca0a7 100644
--- a/libs/vkd3d-shader/hlsl.y
+++ b/libs/vkd3d-shader/hlsl.y
@@ -607,7 +607,7 @@ static struct hlsl_ir_load *add_array_load(struct hlsl_ctx *ctx, struct list *in
         return NULL;
     }
 
-    if (!(c = hlsl_new_uint_constant(ctx, data_type->reg_size, loc)))
+    if (!(c = hlsl_new_uint_constant(ctx, hlsl_type_get_array_element_reg_size(data_type), loc)))
         return NULL;
     list_add_tail(instrs, &c->node.entry);
     if (!(mul = hlsl_new_binary_expr(ctx, HLSL_OP2_MUL, index, &c->node)))
diff --git a/libs/vkd3d-shader/hlsl_codegen.c b/libs/vkd3d-shader/hlsl_codegen.c
index 62dbce5e..ca3acba0 100644
--- a/libs/vkd3d-shader/hlsl_codegen.c
+++ b/libs/vkd3d-shader/hlsl_codegen.c
@@ -621,7 +621,7 @@ static bool split_array_copies(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr,
     if (type->type != HLSL_CLASS_ARRAY)
         return false;
     element_type = type->e.array.type;
-    element_size = element_type->reg_size;
+    element_size = hlsl_type_get_array_element_reg_size(element_type);
 
     for (i = 0; i < type->e.array.elements_count; ++i)
     {
diff --git a/tests/hlsl-struct-array.shader_test b/tests/hlsl-struct-array.shader_test
new file mode 100644
index 00000000..a5df9cdb
--- /dev/null
+++ b/tests/hlsl-struct-array.shader_test
@@ -0,0 +1,19 @@
+% In SM4, array elements are always aligned to the next vec4, although structs are not.
+
+[pixel shader]
+uniform struct
+{
+    float p, q;
+} colours[3];
+
+float4 main() : sv_target
+{
+    return float4(colours[0].q, colours[1].p, colours[2].q, colours[2].p);
+}
+
+[test]
+uniform 0 float4 0.1 0.2 0.0 0.0
+uniform 4 float4 0.3 0.4 0.0 0.0
+uniform 8 float4 0.5 0.6 0.0 0.0
+draw quad
+probe all rgba (0.2, 0.3, 0.6, 0.5)
-- 
2.34.1




More information about the wine-devel mailing list