From: Giovanni Mascellani gmascellani@codeweavers.com
--- Makefile.am | 1 + tests/hlsl-length.shader_test | 80 +++++++++++++++++++++++++++++++++++ 2 files changed, 81 insertions(+) create mode 100644 tests/hlsl-length.shader_test
diff --git a/Makefile.am b/Makefile.am index cc06a839..ba69c4f3 100644 --- a/Makefile.am +++ b/Makefile.am @@ -90,6 +90,7 @@ vkd3d_shader_tests = \ tests/hlsl-intrinsic-override.shader_test \ tests/hlsl-invalid.shader_test \ tests/hlsl-ldexp.shader_test \ + tests/hlsl-length.shader_test \ tests/hlsl-lerp.shader_test \ tests/hlsl-majority-pragma.shader_test \ tests/hlsl-majority-typedef.shader_test \ diff --git a/tests/hlsl-length.shader_test b/tests/hlsl-length.shader_test new file mode 100644 index 00000000..e9f7c8ae --- /dev/null +++ b/tests/hlsl-length.shader_test @@ -0,0 +1,80 @@ +[pixel shader] +uniform float4 x; + +float4 main() : SV_TARGET +{ + return length(x); +} + +[test] +uniform 0 float4 2.0 3.0 4.0 5.0 +todo draw quad +probe all rgba (7.34846926, 7.34846926, 7.34846926, 7.34846926) 1 + +[pixel shader] +uniform float3 x; + +float4 main() : SV_TARGET +{ + return length(x); +} + +[test] +uniform 0 float4 2.0 3.0 4.0 0.0 +todo draw quad +probe all rgba (5.38516474, 5.38516474, 5.38516474, 5.38516474) 1 + +[pixel shader] +uniform float2 x; + +float4 main() : SV_TARGET +{ + return length(x); +} + +[test] +uniform 0 float4 2.0 3.0 0.0 0.0 +todo draw quad +probe all rgba (3.60555124, 3.60555124, 3.60555124, 3.60555124) 1 + +[pixel shader] +uniform float1 x; + +float4 main() : SV_TARGET +{ + return length(x); +} + +[test] +uniform 0 float4 2.0 0.0 0.0 0.0 +todo draw quad +probe all rgba (2.0, 2.0, 2.0, 2.0) + +[pixel shader] +uniform float x; + +float4 main() : SV_TARGET +{ + return length(x); +} + +[test] +uniform 0 float4 2.0 0.0 0.0 0.0 +todo draw quad +probe all rgba (2.0, 2.0, 2.0, 2.0) + +[pixel shader fail] +uniform float1x3 x; + +float4 main() : SV_TARGET +{ + return length(x); +} + +[pixel shader fail] +uniform float4x1 x; + +float4 main() : SV_TARGET +{ + return length(x); +}
From: Giovanni Mascellani gmascellani@codeweavers.com
--- libs/vkd3d-shader/hlsl.y | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+)
diff --git a/libs/vkd3d-shader/hlsl.y b/libs/vkd3d-shader/hlsl.y index fc3b31a4..98b89455 100644 --- a/libs/vkd3d-shader/hlsl.y +++ b/libs/vkd3d-shader/hlsl.y @@ -2148,6 +2148,31 @@ static bool intrinsic_ldexp(struct hlsl_ctx *ctx, return !!add_binary_arithmetic_expr(ctx, params->instrs, HLSL_OP2_MUL, params->args[0], arg, loc); }
+static bool intrinsic_length(struct hlsl_ctx *ctx, + const struct parse_initializer *params, const struct vkd3d_shader_location *loc) +{ + struct hlsl_type *type = params->args[0]->data_type; + struct hlsl_ir_node *arg, *dot; + + if (type->type == HLSL_CLASS_MATRIX) + { + struct vkd3d_string_buffer *string; + + if ((string = hlsl_type_to_string(ctx, type))) + hlsl_error(ctx, loc, VKD3D_SHADER_ERROR_HLSL_INVALID_TYPE, + "Invalid type %s.", string->buffer); + hlsl_release_string_buffer(ctx, string); + } + + if (!(arg = intrinsic_float_convert_arg(ctx, params, params->args[0], loc))) + return false; + + if (!(dot = add_binary_dot_expr(ctx, params->instrs, arg, arg, loc))) + return false; + + return !!add_unary_arithmetic_expr(ctx, params->instrs, HLSL_OP1_SQRT, dot, loc); +} + static bool intrinsic_lerp(struct hlsl_ctx *ctx, const struct parse_initializer *params, const struct vkd3d_shader_location *loc) { @@ -2338,6 +2363,7 @@ intrinsic_functions[] = {"dot", 2, true, intrinsic_dot}, {"floor", 1, true, intrinsic_floor}, {"ldexp", 2, true, intrinsic_ldexp}, + {"length", 1, true, intrinsic_length}, {"lerp", 3, true, intrinsic_lerp}, {"max", 2, true, intrinsic_max}, {"min", 2, true, intrinsic_min},
From: Giovanni Mascellani gmascellani@codeweavers.com
--- libs/vkd3d-shader/hlsl_sm4.c | 5 +++++ tests/hlsl-length.shader_test | 10 +++++----- 2 files changed, 10 insertions(+), 5 deletions(-)
diff --git a/libs/vkd3d-shader/hlsl_sm4.c b/libs/vkd3d-shader/hlsl_sm4.c index 5d763c56..aa366b12 100644 --- a/libs/vkd3d-shader/hlsl_sm4.c +++ b/libs/vkd3d-shader/hlsl_sm4.c @@ -1676,6 +1676,11 @@ static void write_sm4_expr(struct hlsl_ctx *ctx, &expr->node, arg1, 0); break;
+ case HLSL_OP1_SQRT: + assert(type_is_float(dst_type)); + write_sm4_unary_op(buffer, VKD3D_SM4_OP_SQRT, &expr->node, arg1, 0); + break; + case HLSL_OP2_ADD: switch (dst_type->base_type) { diff --git a/tests/hlsl-length.shader_test b/tests/hlsl-length.shader_test index e9f7c8ae..d5a708e2 100644 --- a/tests/hlsl-length.shader_test +++ b/tests/hlsl-length.shader_test @@ -8,7 +8,7 @@ float4 main() : SV_TARGET
[test] uniform 0 float4 2.0 3.0 4.0 5.0 -todo draw quad +draw quad probe all rgba (7.34846926, 7.34846926, 7.34846926, 7.34846926) 1
[pixel shader] @@ -21,7 +21,7 @@ float4 main() : SV_TARGET
[test] uniform 0 float4 2.0 3.0 4.0 0.0 -todo draw quad +draw quad probe all rgba (5.38516474, 5.38516474, 5.38516474, 5.38516474) 1
[pixel shader] @@ -34,7 +34,7 @@ float4 main() : SV_TARGET
[test] uniform 0 float4 2.0 3.0 0.0 0.0 -todo draw quad +draw quad probe all rgba (3.60555124, 3.60555124, 3.60555124, 3.60555124) 1
[pixel shader] @@ -47,7 +47,7 @@ float4 main() : SV_TARGET
[test] uniform 0 float4 2.0 0.0 0.0 0.0 -todo draw quad +draw quad probe all rgba (2.0, 2.0, 2.0, 2.0)
[pixel shader] @@ -60,7 +60,7 @@ float4 main() : SV_TARGET
[test] uniform 0 float4 2.0 0.0 0.0 0.0 -todo draw quad +draw quad probe all rgba (2.0, 2.0, 2.0, 2.0)
[pixel shader fail]
From: Giovanni Mascellani gmascellani@codeweavers.com
--- tests/arithmetic-int-uniform.shader_test | 13 +++++++++++++ 1 file changed, 13 insertions(+)
diff --git a/tests/arithmetic-int-uniform.shader_test b/tests/arithmetic-int-uniform.shader_test index ff80a9b0..643c910b 100644 --- a/tests/arithmetic-int-uniform.shader_test +++ b/tests/arithmetic-int-uniform.shader_test @@ -27,3 +27,16 @@ float4 main() : SV_TARGET uniform 0 float4 5.0 16.0 0.0 0.0 todo draw quad probe all rgba (5.0, 5.0, -5.0, 3.0) + +[pixel shader] +uniform float4 a; + +float4 main() : SV_TARGET +{ + return abs(int4(a)); +} + +[test] +uniform 0 float4 5.0 -7.0 0.0 -10.0 +todo draw quad +probe all rgba (5.0, 7.0, 0.0, 10.0)
From: Giovanni Mascellani gmascellani@codeweavers.com
--- libs/vkd3d-shader/hlsl_codegen.c | 30 ++++++++++++++++++++++++ tests/arithmetic-int-uniform.shader_test | 2 +- 2 files changed, 31 insertions(+), 1 deletion(-)
diff --git a/libs/vkd3d-shader/hlsl_codegen.c b/libs/vkd3d-shader/hlsl_codegen.c index 289c5a11..ef67e39b 100644 --- a/libs/vkd3d-shader/hlsl_codegen.c +++ b/libs/vkd3d-shader/hlsl_codegen.c @@ -1284,6 +1284,35 @@ static bool lower_casts_to_bool(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr return true; }
+static bool lower_int_abs(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, void *context) +{ + struct hlsl_type *type = instr->data_type; + struct hlsl_ir_node *arg, *neg; + struct hlsl_ir_expr *expr; + + if (instr->type != HLSL_IR_EXPR) + return false; + expr = hlsl_ir_expr(instr); + + if (expr->op != HLSL_OP1_ABS) + return false; + if (type->type != HLSL_CLASS_SCALAR && type->type != HLSL_CLASS_VECTOR) + return false; + if (type->base_type != HLSL_TYPE_INT) + return false; + + arg = expr->operands[0].node; + + if (!(neg = hlsl_new_unary_expr(ctx, HLSL_OP1_NEG, arg, instr->loc))) + return false; + list_add_before(&instr->entry, &neg->entry); + + expr->op = HLSL_OP2_MAX; + hlsl_src_from_node(&expr->operands[1], neg); + + return true; +} + static bool dce(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, void *context) { switch (instr->type) @@ -2268,6 +2297,7 @@ int hlsl_emit_bytecode(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl *entry
transform_ir(ctx, lower_narrowing_casts, body, NULL); transform_ir(ctx, lower_casts_to_bool, body, NULL); + transform_ir(ctx, lower_int_abs, body, NULL); do { progress = transform_ir(ctx, hlsl_fold_constant_exprs, body, NULL); diff --git a/tests/arithmetic-int-uniform.shader_test b/tests/arithmetic-int-uniform.shader_test index 643c910b..f7fe8291 100644 --- a/tests/arithmetic-int-uniform.shader_test +++ b/tests/arithmetic-int-uniform.shader_test @@ -38,5 +38,5 @@ float4 main() : SV_TARGET
[test] uniform 0 float4 5.0 -7.0 0.0 -10.0 -todo draw quad +draw quad probe all rgba (5.0, 7.0, 0.0, 10.0)
From: Giovanni Mascellani gmascellani@codeweavers.com
--- libs/vkd3d-shader/hlsl_codegen.c | 105 +++++++++++++++++++++++ tests/arithmetic-int-uniform.shader_test | 2 +- 2 files changed, 106 insertions(+), 1 deletion(-)
diff --git a/libs/vkd3d-shader/hlsl_codegen.c b/libs/vkd3d-shader/hlsl_codegen.c index ef67e39b..656e2e93 100644 --- a/libs/vkd3d-shader/hlsl_codegen.c +++ b/libs/vkd3d-shader/hlsl_codegen.c @@ -1284,6 +1284,110 @@ static bool lower_casts_to_bool(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr return true; }
+static struct hlsl_ir_load *add_conditional(struct hlsl_ctx *ctx, struct list *instrs, + struct hlsl_ir_node *condition, struct hlsl_ir_node *if_true, struct hlsl_ir_node *if_false) +{ + struct hlsl_ir_store *store; + struct hlsl_ir_load *load; + struct hlsl_ir_var *var; + struct hlsl_ir_if *iff; + + assert(hlsl_types_are_equal(if_true->data_type, if_false->data_type)); + + if (!(var = hlsl_new_synthetic_var(ctx, "conditional", if_true->data_type, &condition->loc))) + return NULL; + + if (!(iff = hlsl_new_if(ctx, condition, condition->loc))) + return NULL; + list_add_tail(instrs, &iff->node.entry); + + if (!(store = hlsl_new_simple_store(ctx, var, if_true))) + return NULL; + list_add_tail(&iff->then_instrs.instrs, &store->node.entry); + + if (!(store = hlsl_new_simple_store(ctx, var, if_false))) + return NULL; + list_add_tail(&iff->else_instrs.instrs, &store->node.entry); + + if (!(load = hlsl_new_var_load(ctx, var, condition->loc))) + return NULL; + list_add_tail(instrs, &load->node.entry); + + return load; +} + +static bool lower_int_division(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, void *context) +{ + struct hlsl_ir_node *arg1, *arg2, *xor, *and, *abs1, *abs2, *div, *neg; + struct hlsl_type *type = instr->data_type, *utype; + struct hlsl_ir_expr *cast1, *cast2, *cast3; + struct hlsl_ir_constant *high_bit; + struct hlsl_ir_expr *expr; + struct hlsl_ir_load *cond; + unsigned int i; + + if (instr->type != HLSL_IR_EXPR) + return false; + expr = hlsl_ir_expr(instr); + arg1 = expr->operands[0].node; + arg2 = expr->operands[1].node; + if (expr->op != HLSL_OP2_DIV) + return false; + if (type->type != HLSL_CLASS_SCALAR && type->type != HLSL_CLASS_VECTOR) + return false; + if (type->base_type != HLSL_TYPE_INT) + return false; + utype = hlsl_get_numeric_type(ctx, type->type, HLSL_TYPE_UINT, type->dimx, type->dimy); + + if (!(xor = hlsl_new_binary_expr(ctx, HLSL_OP2_BIT_XOR, arg1, arg2))) + return false; + list_add_before(&instr->entry, &xor->entry); + + if (!(high_bit = hlsl_new_constant(ctx, type, &instr->loc))) + return false; + for (i = 0; i < type->dimx; ++i) + high_bit->value[i].u = 0x80000000; + list_add_before(&instr->entry, &high_bit->node.entry); + + if (!(and = hlsl_new_binary_expr(ctx, HLSL_OP2_BIT_AND, xor, &high_bit->node))) + return false; + list_add_before(&instr->entry, &and->entry); + + if (!(abs1 = hlsl_new_unary_expr(ctx, HLSL_OP1_ABS, arg1, instr->loc))) + return false; + list_add_before(&instr->entry, &abs1->entry); + + if (!(cast1 = hlsl_new_cast(ctx, abs1, utype, &instr->loc))) + return false; + list_add_before(&instr->entry, &cast1->node.entry); + + if (!(abs2 = hlsl_new_unary_expr(ctx, HLSL_OP1_ABS, arg2, instr->loc))) + return false; + list_add_before(&instr->entry, &abs2->entry); + + if (!(cast2 = hlsl_new_cast(ctx, abs2, utype, &instr->loc))) + return false; + list_add_before(&instr->entry, &cast2->node.entry); + + if (!(div = hlsl_new_binary_expr(ctx, HLSL_OP2_DIV, &cast1->node, &cast2->node))) + return false; + list_add_before(&instr->entry, &div->entry); + + if (!(cast3 = hlsl_new_cast(ctx, div, type, &instr->loc))) + return false; + list_add_before(&instr->entry, &cast3->node.entry); + + if (!(neg = hlsl_new_unary_expr(ctx, HLSL_OP1_NEG, &cast3->node, instr->loc))) + return false; + list_add_before(&instr->entry, &neg->entry); + + if (!(cond = add_conditional(ctx, &instr->entry, and, neg, &cast3->node))) + return false; + hlsl_replace_node(instr, &cond->node); + + return true; +} + static bool lower_int_abs(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, void *context) { struct hlsl_type *type = instr->data_type; @@ -2297,6 +2401,7 @@ int hlsl_emit_bytecode(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl *entry
transform_ir(ctx, lower_narrowing_casts, body, NULL); transform_ir(ctx, lower_casts_to_bool, body, NULL); + transform_ir(ctx, lower_int_division, body, NULL); transform_ir(ctx, lower_int_abs, body, NULL); do { diff --git a/tests/arithmetic-int-uniform.shader_test b/tests/arithmetic-int-uniform.shader_test index f7fe8291..3190be00 100644 --- a/tests/arithmetic-int-uniform.shader_test +++ b/tests/arithmetic-int-uniform.shader_test @@ -10,7 +10,7 @@ float4 main() : SV_TARGET
[test] uniform 0 float4 5.0 16.0 0.0 0.0 -todo draw quad +draw quad probe all rgba (21.0, -11.0, 80.0, 0.0)
[pixel shader]
This merge request was approved by Zebediah Figura.
This merge request was approved by Henri Verbeet.