Signed-off-by: Giovanni Mascellani gmascellani@codeweavers.com --- libs/vkd3d-shader/hlsl.y | 74 ++++++++++++++++++++++++++++++++++++ tests/hlsl-shape.shader_test | 30 +++++++-------- 2 files changed, 89 insertions(+), 15 deletions(-)
diff --git a/libs/vkd3d-shader/hlsl.y b/libs/vkd3d-shader/hlsl.y index d6ea668d..22853ceb 100644 --- a/libs/vkd3d-shader/hlsl.y +++ b/libs/vkd3d-shader/hlsl.y @@ -1197,6 +1197,22 @@ static bool expr_common_shape(struct hlsl_ctx *ctx, struct hlsl_type *t1, struct return true; }
+static unsigned int minor_size(const struct hlsl_type *type) +{ + if (type->modifiers & HLSL_MODIFIER_ROW_MAJOR) + return type->dimx; + else + return type->dimy; +} + +static unsigned int major_size(const struct hlsl_type *type) +{ + if (type->modifiers & HLSL_MODIFIER_ROW_MAJOR) + return type->dimy; + else + return type->dimx; +} + static struct hlsl_ir_node *add_expr(struct hlsl_ctx *ctx, struct list *instrs, enum hlsl_ir_expr_op op, struct hlsl_ir_node *operands[HLSL_MAX_OPERANDS], struct hlsl_type *type, const struct vkd3d_shader_location *loc) @@ -1204,6 +1220,64 @@ static struct hlsl_ir_node *add_expr(struct hlsl_ctx *ctx, struct list *instrs, struct hlsl_ir_expr *expr; unsigned int i;
+ if (type->type == HLSL_CLASS_MATRIX) + { + struct vkd3d_string_buffer *name; + static unsigned int counter = 0; + struct hlsl_type *vector_type; + struct hlsl_ir_load *load; + struct hlsl_ir_var *var; + + vector_type = hlsl_get_vector_type(ctx, type->base_type, minor_size(type)); + + name = vkd3d_string_buffer_get(&ctx->string_buffers); + vkd3d_string_buffer_printf(name, "<split_op-%u>", counter++); + var = hlsl_new_synthetic_var(ctx, name->buffer, type, *loc); + vkd3d_string_buffer_release(&ctx->string_buffers, name); + if (!var) + return NULL; + + for (i = 0; i < major_size(type); i++) + { + struct hlsl_ir_node *value, *vector_operands[HLSL_MAX_OPERANDS] = { NULL }; + struct hlsl_ir_store *store; + struct hlsl_ir_constant *c; + unsigned int j; + + if (!(c = hlsl_new_uint_constant(ctx, 4 * i, loc))) + return NULL; + list_add_tail(instrs, &c->node.entry); + + for (j = 0; j < HLSL_MAX_OPERANDS; j++) + { + if (operands[j]) + { + struct hlsl_type *vector_arg_type; + struct hlsl_ir_load *load; + + vector_arg_type = hlsl_get_vector_type(ctx, operands[j]->data_type->base_type, minor_size(type)); + + if (!(load = add_load(ctx, instrs, operands[j], &c->node, vector_arg_type, *loc))) + return NULL; + vector_operands[j] = &load->node; + } + } + + if (!(value = add_expr(ctx, instrs, op, vector_operands, vector_type, loc))) + return NULL; + + if (!(store = hlsl_new_store(ctx, var, &c->node, value, 0, *loc))) + return NULL; + list_add_tail(instrs, &store->node.entry); + } + + if (!(load = hlsl_new_load(ctx, var, NULL, type, *loc))) + return NULL; + list_add_tail(instrs, &load->node.entry); + + return &load->node; + } + if (!(expr = hlsl_alloc(ctx, sizeof(*expr)))) return NULL; init_node(&expr->node, HLSL_IR_EXPR, type, *loc); diff --git a/tests/hlsl-shape.shader_test b/tests/hlsl-shape.shader_test index 65cc322c..b96f0fd2 100644 --- a/tests/hlsl-shape.shader_test +++ b/tests/hlsl-shape.shader_test @@ -93,7 +93,7 @@ float4 main() : sv_target }
[test] -todo draw quad +draw quad probe all rgba (2.0, 4.0, 7.0, 9.0)
[pixel shader] @@ -107,7 +107,7 @@ float4 main() : sv_target }
[test] -todo draw quad +draw quad probe all rgba (2.0, 4.0, 7.0, 9.0)
[pixel shader] @@ -122,7 +122,7 @@ float4 main() : sv_target }
[test] -todo draw quad +draw quad probe all rgba (2.0, 4.0, 6.0, 8.0)
[pixel shader] @@ -137,7 +137,7 @@ float4 main() : sv_target }
[test] -todo draw quad +draw quad probe all rgba (2.0, 4.0, 6.0, 8.0)
[pixel shader] @@ -152,7 +152,7 @@ float4 main() : sv_target }
[test] -todo draw quad +draw quad probe all rgba (2.0, 7.0, 12.0, 17.0)
[pixel shader] @@ -167,7 +167,7 @@ float4 main() : sv_target }
[test] -todo draw quad +draw quad probe all rgba (2.0, 7.0, 12.0, 17.0)
[pixel shader] @@ -183,7 +183,7 @@ float4 main() : sv_target }
[test] -todo draw quad +draw quad probe all rgba (2.0, 4.0, 6.0, 0.0)
[pixel shader] @@ -199,7 +199,7 @@ float4 main() : sv_target }
[test] -todo draw quad +draw quad probe all rgba (9.0, 11.0, 13.0, 0.0)
[pixel shader] @@ -223,7 +223,7 @@ float4 main() : sv_target }
[test] -todo draw quad +draw quad probe all rgba (2.0, 4.0, 6.0, 8.0)
[pixel shader] @@ -247,7 +247,7 @@ float4 main() : sv_target }
[test] -todo draw quad +draw quad probe all rgba (2.0, 4.0, 6.0, 8.0)
[pixel shader] @@ -273,7 +273,7 @@ float4 main() : sv_target }
[test] -todo draw quad +draw quad probe all rgba (2.0, 4.0, 6.0, 8.0)
[pixel shader] @@ -285,7 +285,7 @@ float4 main() : sv_target }
[test] -todo draw quad +draw quad probe all rgba (2.0, 3.0, 4.0, 5.0)
[pixel shader] @@ -297,7 +297,7 @@ float4 main() : sv_target }
[test] -todo draw quad +draw quad probe all rgba (2.0, 3.0, 4.0, 5.0)
[pixel shader] @@ -336,7 +336,7 @@ float4 main() : sv_target }
[test] -todo draw quad +draw quad probe all rgba (2.0, 3.0, 4.0, 5.0)
[pixel shader] @@ -351,5 +351,5 @@ float4 main() : sv_target }
[test] -todo draw quad +draw quad probe all rgba (6.0, 7.0, 8.0, 9.0)