From: Nikolay Sivov nsivov@codeweavers.com
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- Makefile.am | 1 + tests/hlsl/ceil.shader_test | 57 +++++++++++++++++++++++++++++++++++++ 2 files changed, 58 insertions(+) create mode 100644 tests/hlsl/ceil.shader_test
diff --git a/Makefile.am b/Makefile.am index 8364aaa37..f876f405d 100644 --- a/Makefile.am +++ b/Makefile.am @@ -69,6 +69,7 @@ vkd3d_shader_tests = \ tests/hlsl/cast-to-int.shader_test \ tests/hlsl/cast-to-uint.shader_test \ tests/hlsl/cbuffer.shader_test \ + tests/hlsl/ceil.shader_test \ tests/hlsl/clamp.shader_test \ tests/hlsl/clip.shader_test \ tests/hlsl/combined-samplers.shader_test \ diff --git a/tests/hlsl/ceil.shader_test b/tests/hlsl/ceil.shader_test new file mode 100644 index 000000000..677ef93d7 --- /dev/null +++ b/tests/hlsl/ceil.shader_test @@ -0,0 +1,57 @@ +[pixel shader todo] +float4 main() : sv_target +{ + return ceil(float4(-0.5, 6.5, 7.5, 3.4)); +} + +[test] +todo draw quad +todo probe all rgba (0.0, 7.0, 8.0, 4.0) 4 + +[pixel shader todo] +uniform float4 u; + +float4 main() : sv_target +{ + return ceil(u); +} + +[test] +uniform 0 float4 -0.5 6.5 7.5 3.4 +todo draw quad +todo probe all rgba (0.0, 7.0, 8.0, 4.0) 4 + +[pixel shader todo] +uniform float4 u; + +float4 main() : sv_target +{ + float a = ceil(u.r); + int2 b = ceil(u.gb); + float4 res = float4(b, a, u.a); + return ceil(res); +} + +[test] +uniform 0 float4 -0.5 6.5 7.5 3.4 +todo draw quad +todo probe all rgba (7.0, 8.0, 0.0, 4.0) 4 + +[require] +shader model >= 4.0 + +[pixel shader todo] +uniform int4 u; + +float4 main() : sv_target +{ + float a = ceil(u.r); + int2 b = ceil(u.gb); + float4 res = float4(b, a, u.a); + return ceil(res); +} + +[test] +uniform 0 int4 -1 6 7 3 +todo draw quad +todo probe all rgba (6.0, 7.0, -1.0, 3.0) 4
From: Nikolay Sivov nsivov@codeweavers.com
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- libs/vkd3d-shader/hlsl.c | 1 + libs/vkd3d-shader/hlsl.h | 1 + libs/vkd3d-shader/hlsl.y | 12 ++++++++++++ 3 files changed, 14 insertions(+)
diff --git a/libs/vkd3d-shader/hlsl.c b/libs/vkd3d-shader/hlsl.c index b42e30888..9e88c30c1 100644 --- a/libs/vkd3d-shader/hlsl.c +++ b/libs/vkd3d-shader/hlsl.c @@ -2462,6 +2462,7 @@ const char *debug_hlsl_expr_op(enum hlsl_ir_expr_op op) [HLSL_OP1_ABS] = "abs", [HLSL_OP1_BIT_NOT] = "~", [HLSL_OP1_CAST] = "cast", + [HLSL_OP1_CEIL] = "ceil", [HLSL_OP1_COS] = "cos", [HLSL_OP1_COS_REDUCED] = "cos_reduced", [HLSL_OP1_DSX] = "dsx", diff --git a/libs/vkd3d-shader/hlsl.h b/libs/vkd3d-shader/hlsl.h index 9f1a3fe21..ff4379033 100644 --- a/libs/vkd3d-shader/hlsl.h +++ b/libs/vkd3d-shader/hlsl.h @@ -506,6 +506,7 @@ enum hlsl_ir_expr_op HLSL_OP1_ABS, HLSL_OP1_BIT_NOT, HLSL_OP1_CAST, + HLSL_OP1_CEIL, HLSL_OP1_COS, HLSL_OP1_COS_REDUCED, /* Reduced range [-pi, pi] */ HLSL_OP1_DSX, diff --git a/libs/vkd3d-shader/hlsl.y b/libs/vkd3d-shader/hlsl.y index ba738473f..d373a6563 100644 --- a/libs/vkd3d-shader/hlsl.y +++ b/libs/vkd3d-shader/hlsl.y @@ -2715,6 +2715,17 @@ static bool intrinsic_asuint(struct hlsl_ctx *ctx, return add_expr(ctx, params->instrs, HLSL_OP1_REINTERPRET, operands, data_type, loc); }
+static bool intrinsic_ceil(struct hlsl_ctx *ctx, + const struct parse_initializer *params, const struct vkd3d_shader_location *loc) +{ + struct hlsl_ir_node *arg; + + if (!(arg = intrinsic_float_convert_arg(ctx, params, params->args[0], loc))) + return false; + + return !!add_unary_arithmetic_expr(ctx, params->instrs, HLSL_OP1_CEIL, arg, loc); +} + static bool intrinsic_clamp(struct hlsl_ctx *ctx, const struct parse_initializer *params, const struct vkd3d_shader_location *loc) { @@ -3746,6 +3757,7 @@ intrinsic_functions[] = {"any", 1, true, intrinsic_any}, {"asfloat", 1, true, intrinsic_asfloat}, {"asuint", -1, true, intrinsic_asuint}, + {"ceil", 1, true, intrinsic_ceil}, {"clamp", 3, true, intrinsic_clamp}, {"clip", 1, true, intrinsic_clip}, {"cos", 1, true, intrinsic_cos},
From: Nikolay Sivov nsivov@codeweavers.com
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- libs/vkd3d-shader/tpf.c | 5 +++++ tests/hlsl/ceil.shader_test | 24 ++++++++++++------------ 2 files changed, 17 insertions(+), 12 deletions(-)
diff --git a/libs/vkd3d-shader/tpf.c b/libs/vkd3d-shader/tpf.c index bf4c03c05..6b4fd4e7f 100644 --- a/libs/vkd3d-shader/tpf.c +++ b/libs/vkd3d-shader/tpf.c @@ -4785,6 +4785,11 @@ static void write_sm4_expr(const struct tpf_writer *tpf, const struct hlsl_ir_ex write_sm4_cast(tpf, expr); break;
+ case HLSL_OP1_CEIL: + assert(type_is_float(dst_type)); + write_sm4_unary_op(tpf, VKD3D_SM4_OP_ROUND_PI, &expr->node, arg1, 0); + break; + case HLSL_OP1_COS: assert(type_is_float(dst_type)); write_sm4_unary_op_with_two_destinations(tpf, VKD3D_SM4_OP_SINCOS, &expr->node, 1, arg1); diff --git a/tests/hlsl/ceil.shader_test b/tests/hlsl/ceil.shader_test index 677ef93d7..ef26cc8ef 100644 --- a/tests/hlsl/ceil.shader_test +++ b/tests/hlsl/ceil.shader_test @@ -1,14 +1,14 @@ -[pixel shader todo] +[pixel shader] float4 main() : sv_target { return ceil(float4(-0.5, 6.5, 7.5, 3.4)); }
[test] -todo draw quad -todo probe all rgba (0.0, 7.0, 8.0, 4.0) 4 +draw quad +probe all rgba (0.0, 7.0, 8.0, 4.0) 4
-[pixel shader todo] +[pixel shader] uniform float4 u;
float4 main() : sv_target @@ -18,10 +18,10 @@ float4 main() : sv_target
[test] uniform 0 float4 -0.5 6.5 7.5 3.4 -todo draw quad -todo probe all rgba (0.0, 7.0, 8.0, 4.0) 4 +draw quad +probe all rgba (0.0, 7.0, 8.0, 4.0) 4
-[pixel shader todo] +[pixel shader] uniform float4 u;
float4 main() : sv_target @@ -34,13 +34,13 @@ float4 main() : sv_target
[test] uniform 0 float4 -0.5 6.5 7.5 3.4 -todo draw quad -todo probe all rgba (7.0, 8.0, 0.0, 4.0) 4 +draw quad +probe all rgba (7.0, 8.0, 0.0, 4.0) 4
[require] shader model >= 4.0
-[pixel shader todo] +[pixel shader] uniform int4 u;
float4 main() : sv_target @@ -53,5 +53,5 @@ float4 main() : sv_target
[test] uniform 0 int4 -1 6 7 3 -todo draw quad -todo probe all rgba (6.0, 7.0, -1.0, 3.0) 4 +draw quad +probe all rgba (6.0, 7.0, -1.0, 3.0) 4
From: Nikolay Sivov nsivov@codeweavers.com
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- libs/vkd3d-shader/hlsl_codegen.c | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+)
diff --git a/libs/vkd3d-shader/hlsl_codegen.c b/libs/vkd3d-shader/hlsl_codegen.c index 7d17ca8ce..ddf5e64d7 100644 --- a/libs/vkd3d-shader/hlsl_codegen.c +++ b/libs/vkd3d-shader/hlsl_codegen.c @@ -2464,6 +2464,35 @@ static bool lower_round(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, struct return true; }
+/* Lower CEIL to FRC */ +static bool lower_ceil(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, struct hlsl_block *block) +{ + struct hlsl_ir_node *arg, *neg, *sum, *frc; + struct hlsl_ir_expr *expr; + + if (instr->type != HLSL_IR_EXPR) + return false; + + expr = hlsl_ir_expr(instr); + arg = expr->operands[0].node; + if (expr->op != HLSL_OP1_CEIL) + return false; + + if (!(neg = hlsl_new_unary_expr(ctx, HLSL_OP1_NEG, arg, &instr->loc))) + return false; + hlsl_block_add_instr(block, neg); + + if (!(frc = hlsl_new_unary_expr(ctx, HLSL_OP1_FRACT, neg, &instr->loc))) + return false; + hlsl_block_add_instr(block, frc); + + if (!(sum = hlsl_new_binary_expr(ctx, HLSL_OP2_ADD, frc, arg))) + return false; + hlsl_block_add_instr(block, sum); + + return true; +} + /* Use 'movc' for the ternary operator. */ static bool lower_ternary(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, struct hlsl_block *block) { @@ -4472,6 +4501,7 @@ int hlsl_emit_bytecode(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl *entry lower_ir(ctx, lower_sqrt, body); lower_ir(ctx, lower_dot, body); lower_ir(ctx, lower_round, body); + lower_ir(ctx, lower_ceil, body); }
if (profile->major_version < 2)
From: Nikolay Sivov nsivov@codeweavers.com
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- libs/vkd3d-shader/hlsl_codegen.c | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+)
diff --git a/libs/vkd3d-shader/hlsl_codegen.c b/libs/vkd3d-shader/hlsl_codegen.c index ddf5e64d7..e2d374298 100644 --- a/libs/vkd3d-shader/hlsl_codegen.c +++ b/libs/vkd3d-shader/hlsl_codegen.c @@ -2493,6 +2493,35 @@ static bool lower_ceil(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, struct return true; }
+/* Lower FLOOR to FRC */ +static bool lower_floor(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, struct hlsl_block *block) +{ + struct hlsl_ir_node *arg, *neg, *sum, *frc; + struct hlsl_ir_expr *expr; + + if (instr->type != HLSL_IR_EXPR) + return false; + + expr = hlsl_ir_expr(instr); + arg = expr->operands[0].node; + if (expr->op != HLSL_OP1_FLOOR) + return false; + + if (!(frc = hlsl_new_unary_expr(ctx, HLSL_OP1_FRACT, arg, &instr->loc))) + return false; + hlsl_block_add_instr(block, frc); + + if (!(neg = hlsl_new_unary_expr(ctx, HLSL_OP1_NEG, frc, &instr->loc))) + return false; + hlsl_block_add_instr(block, neg); + + if (!(sum = hlsl_new_binary_expr(ctx, HLSL_OP2_ADD, neg, arg))) + return false; + hlsl_block_add_instr(block, sum); + + return true; +} + /* Use 'movc' for the ternary operator. */ static bool lower_ternary(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, struct hlsl_block *block) { @@ -4502,6 +4531,7 @@ int hlsl_emit_bytecode(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl *entry lower_ir(ctx, lower_dot, body); lower_ir(ctx, lower_round, body); lower_ir(ctx, lower_ceil, body); + lower_ir(ctx, lower_floor, body); }
if (profile->major_version < 2)
From: Nikolay Sivov nsivov@codeweavers.com
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- libs/vkd3d-shader/hlsl_constant_ops.c | 30 +++++++++++++++++++++++++++ 1 file changed, 30 insertions(+)
diff --git a/libs/vkd3d-shader/hlsl_constant_ops.c b/libs/vkd3d-shader/hlsl_constant_ops.c index 64629dc29..c869dc023 100644 --- a/libs/vkd3d-shader/hlsl_constant_ops.c +++ b/libs/vkd3d-shader/hlsl_constant_ops.c @@ -228,6 +228,32 @@ static bool fold_cast(struct hlsl_ctx *ctx, struct hlsl_constant_value *dst, return true; }
+static bool fold_ceil(struct hlsl_ctx *ctx, struct hlsl_constant_value *dst, + const struct hlsl_type *dst_type, const struct hlsl_ir_constant *src) +{ + enum hlsl_base_type type = dst_type->base_type; + unsigned int k; + + assert(type == src->node.data_type->base_type); + + for (k = 0; k < dst_type->dimx; ++k) + { + switch (type) + { + case HLSL_TYPE_FLOAT: + case HLSL_TYPE_HALF: + dst->u[k].f = ceilf(src->value.u[k].f); + break; + + default: + FIXME("Fold 'ceil' for type %s.\n", debug_hlsl_type(ctx, dst_type)); + return false; + } + } + + return true; +} + static bool fold_exp2(struct hlsl_ctx *ctx, struct hlsl_constant_value *dst, const struct hlsl_type *dst_type, const struct hlsl_ir_constant *src) { @@ -1229,6 +1255,10 @@ bool hlsl_fold_constant_exprs(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, success = fold_cast(ctx, &res, instr->data_type, arg1); break;
+ case HLSL_OP1_CEIL: + success = fold_ceil(ctx, &res, instr->data_type, arg1); + break; + case HLSL_OP1_EXP2: success = fold_exp2(ctx, &res, instr->data_type, arg1); break;
From: Nikolay Sivov nsivov@codeweavers.com
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- libs/vkd3d-shader/hlsl.c | 1 + 1 file changed, 1 insertion(+)
diff --git a/libs/vkd3d-shader/hlsl.c b/libs/vkd3d-shader/hlsl.c index 9e88c30c1..8258c47d0 100644 --- a/libs/vkd3d-shader/hlsl.c +++ b/libs/vkd3d-shader/hlsl.c @@ -2472,6 +2472,7 @@ const char *debug_hlsl_expr_op(enum hlsl_ir_expr_op op) [HLSL_OP1_DSY_COARSE] = "dsy_coarse", [HLSL_OP1_DSY_FINE] = "dsy_fine", [HLSL_OP1_EXP2] = "exp2", + [HLSL_OP1_FLOOR] = "floor", [HLSL_OP1_FRACT] = "fract", [HLSL_OP1_LOG2] = "log2", [HLSL_OP1_LOGIC_NOT] = "!",
From: Nikolay Sivov nsivov@codeweavers.com
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- libs/vkd3d-shader/hlsl_constant_ops.c | 30 +++++++++++++++++++++++++++ tests/hlsl/floor.shader_test | 10 +++++++++ 2 files changed, 40 insertions(+)
diff --git a/libs/vkd3d-shader/hlsl_constant_ops.c b/libs/vkd3d-shader/hlsl_constant_ops.c index c869dc023..b76b1fce5 100644 --- a/libs/vkd3d-shader/hlsl_constant_ops.c +++ b/libs/vkd3d-shader/hlsl_constant_ops.c @@ -280,6 +280,32 @@ static bool fold_exp2(struct hlsl_ctx *ctx, struct hlsl_constant_value *dst, return true; }
+static bool fold_floor(struct hlsl_ctx *ctx, struct hlsl_constant_value *dst, + const struct hlsl_type *dst_type, const struct hlsl_ir_constant *src) +{ + enum hlsl_base_type type = dst_type->base_type; + unsigned int k; + + assert(type == src->node.data_type->base_type); + + for (k = 0; k < dst_type->dimx; ++k) + { + switch (type) + { + case HLSL_TYPE_FLOAT: + case HLSL_TYPE_HALF: + dst->u[k].f = floorf(src->value.u[k].f); + break; + + default: + FIXME("Fold 'floor' for type %s.\n", debug_hlsl_type(ctx, dst_type)); + return false; + } + } + + return true; +} + static bool fold_fract(struct hlsl_ctx *ctx, struct hlsl_constant_value *dst, const struct hlsl_type *dst_type, const struct hlsl_ir_constant *src) { @@ -1263,6 +1289,10 @@ bool hlsl_fold_constant_exprs(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, success = fold_exp2(ctx, &res, instr->data_type, arg1); break;
+ case HLSL_OP1_FLOOR: + success = fold_floor(ctx, &res, instr->data_type, arg1); + break; + case HLSL_OP1_FRACT: success = fold_fract(ctx, &res, instr->data_type, arg1); break; diff --git a/tests/hlsl/floor.shader_test b/tests/hlsl/floor.shader_test index deb9acf91..e6562c4aa 100644 --- a/tests/hlsl/floor.shader_test +++ b/tests/hlsl/floor.shader_test @@ -1,3 +1,13 @@ +[pixel shader] +float4 main() : sv_target +{ + return floor(float4(-0.5, 6.5, 7.5, 3.4)); +} + +[test] +draw quad +probe all rgba (-1.0, 6.0, 7.0, 3.0) 4 + [pixel shader] uniform float4 u;