Module: vkd3d Branch: master Commit: 25ff56769b794730116be9c3eee326cb728b4624 URL: https://gitlab.winehq.org/wine/vkd3d/-/commit/25ff56769b794730116be9c3eee326...
Author: Nikolay Sivov nsivov@codeweavers.com Date: Sun Jun 18 20:46:51 2023 +0200
vkd3d-shader: Add constant folding for the 'dot' operation.
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com
---
libs/vkd3d-shader/hlsl_constant_ops.c | 32 ++++++++++++++++++++++++++++++++ tests/hlsl/dot.shader_test | 13 +++++++++++++ 2 files changed, 45 insertions(+)
diff --git a/libs/vkd3d-shader/hlsl_constant_ops.c b/libs/vkd3d-shader/hlsl_constant_ops.c index 01c438ae..5501b6e9 100644 --- a/libs/vkd3d-shader/hlsl_constant_ops.c +++ b/libs/vkd3d-shader/hlsl_constant_ops.c @@ -348,6 +348,34 @@ static bool fold_bit_xor(struct hlsl_ctx *ctx, struct hlsl_constant_value *dst, return true; }
+static bool fold_dot(struct hlsl_ctx *ctx, struct hlsl_constant_value *dst, const struct hlsl_type *dst_type, + const struct hlsl_ir_constant *src1, const struct hlsl_ir_constant *src2) +{ + enum hlsl_base_type type = dst_type->base_type; + unsigned int k; + + assert(type == src1->node.data_type->base_type); + assert(type == src2->node.data_type->base_type); + assert(src1->node.data_type->dimx == src2->node.data_type->dimx); + + dst->u[0].f = 0.0f; + for (k = 0; k < src1->node.data_type->dimx; ++k) + { + switch (type) + { + case HLSL_TYPE_FLOAT: + case HLSL_TYPE_HALF: + dst->u[0].f += src1->value.u[k].f * src2->value.u[k].f; + break; + default: + FIXME("Fold 'dot' for type %s.\n", debug_hlsl_type(ctx, dst_type)); + return false; + } + } + + return true; +} + static bool fold_div(struct hlsl_ctx *ctx, struct hlsl_constant_value *dst, const struct hlsl_type *dst_type, const struct hlsl_ir_constant *src1, const struct hlsl_ir_constant *src2, const struct vkd3d_shader_location *loc) @@ -788,6 +816,10 @@ bool hlsl_fold_constant_exprs(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, success = fold_bit_xor(ctx, &res, instr->data_type, arg1, arg2); break;
+ case HLSL_OP2_DOT: + success = fold_dot(ctx, &res, instr->data_type, arg1, arg2); + break; + case HLSL_OP2_DIV: success = fold_div(ctx, &res, instr->data_type, arg1, arg2, &instr->loc); break; diff --git a/tests/hlsl/dot.shader_test b/tests/hlsl/dot.shader_test index e51d7cb8..15f120f7 100644 --- a/tests/hlsl/dot.shader_test +++ b/tests/hlsl/dot.shader_test @@ -74,6 +74,19 @@ uniform 4 float4 3.0 0.0 0.0 0.0 draw quad probe all rgba (6.0, 6.0, 6.0, 6.0)
+[pixel shader] +static const float4 x = float4(2.0, 3.0, 4.0, 5.0); +static const float4 y = float4(6.0, 7.0, 8.0, 9.0); + +float4 main() : sv_target +{ + return dot(x, y); +} + +[test] +draw quad +probe all rgba (110.0, 110.0, 110.0, 110.0) + [pixel shader fail] uniform float1x1 x; uniform float4 y;