diff --git a/libs/vkd3d-shader/hlsl.c b/libs/vkd3d-shader/hlsl.c index cec8a7b1b..653ddd2e8 100644 --- a/libs/vkd3d-shader/hlsl.c +++ b/libs/vkd3d-shader/hlsl.c @@ -372,6 +372,27 @@ bool hlsl_base_type_is_integer(enum hlsl_base_type type) vkd3d_unreachable(); } +bool hlsl_type_is_signed_integer(const struct hlsl_type *type) +{ + VKD3D_ASSERT(hlsl_is_numeric_type(type)); + + switch (type->e.numeric.type) + { + case HLSL_TYPE_INT: + return true; + + case HLSL_TYPE_BOOL: + case HLSL_TYPE_DOUBLE: + case HLSL_TYPE_FLOAT: + case HLSL_TYPE_HALF: + case HLSL_TYPE_MIN16UINT: + case HLSL_TYPE_UINT: + return false; + } + + vkd3d_unreachable(); +} + bool hlsl_type_is_integer(const struct hlsl_type *type) { VKD3D_ASSERT(hlsl_is_numeric_type(type)); diff --git a/libs/vkd3d-shader/hlsl.h b/libs/vkd3d-shader/hlsl.h index 646ce3f7f..ff74a1182 100644 --- a/libs/vkd3d-shader/hlsl.h +++ b/libs/vkd3d-shader/hlsl.h @@ -1771,6 +1771,7 @@ unsigned int hlsl_type_get_component_offset(struct hlsl_ctx *ctx, struct hlsl_ty bool hlsl_type_is_integer(const struct hlsl_type *type); bool hlsl_type_is_floating_point(const struct hlsl_type *type); bool hlsl_type_is_row_major(const struct hlsl_type *type); +bool hlsl_type_is_signed_integer(const struct hlsl_type *type); unsigned int hlsl_type_minor_size(const struct hlsl_type *type); unsigned int hlsl_type_major_size(const struct hlsl_type *type); unsigned int hlsl_type_element_count(const struct hlsl_type *type); diff --git a/libs/vkd3d-shader/hlsl.y b/libs/vkd3d-shader/hlsl.y index 166e1558b..2de9e607d 100644 --- a/libs/vkd3d-shader/hlsl.y +++ b/libs/vkd3d-shader/hlsl.y @@ -3189,6 +3189,11 @@ static bool elementwise_intrinsic_uint_convert_args(struct hlsl_ctx *ctx, static bool intrinsic_abs(struct hlsl_ctx *ctx, const struct parse_initializer *params, const struct vkd3d_shader_location *loc) { + const struct hlsl_type *type = params->args[0]->data_type; + + if (!hlsl_type_is_floating_point(type) && !hlsl_type_is_signed_integer(type)) + return true; + return !!add_unary_arithmetic_expr(ctx, params->instrs, HLSL_OP1_ABS, params->args[0], loc); } diff --git a/libs/vkd3d-shader/hlsl_constant_ops.c b/libs/vkd3d-shader/hlsl_constant_ops.c index f74ecffcd..d339a06e6 100644 --- a/libs/vkd3d-shader/hlsl_constant_ops.c +++ b/libs/vkd3d-shader/hlsl_constant_ops.c @@ -51,14 +51,11 @@ static bool fold_abs(struct hlsl_ctx *ctx, struct hlsl_constant_value *dst, dst->u[k].i = abs(src->value.u[k].i); break; + case HLSL_TYPE_BOOL: case HLSL_TYPE_MIN16UINT: case HLSL_TYPE_UINT: - dst->u[k].u = src->value.u[k].u; - break; - - default: - FIXME("Fold abs() for type %s.\n", debug_hlsl_type(ctx, dst_type)); - return false; + /* Should not occur. */ + vkd3d_unreachable(); } } return true; diff --git a/tests/hlsl/abs.shader_test b/tests/hlsl/abs.shader_test index cb548b4c0..58ba40ea7 100644 --- a/tests/hlsl/abs.shader_test +++ b/tests/hlsl/abs.shader_test @@ -13,3 +13,20 @@ probe (0, 0) rgba (0.1, 0.7, 0.4, 0.4) uniform 0 float4 -0.7 0.1 0.0 0.0 draw quad probe (0, 0) rgba (0.7, 0.1, 1.2, 0.4) + +[pixel shader fail(sm<2)] +uniform float u; + +float4 main() : sv_target +{ + int i = u; + return float4(abs(i), abs(-8), abs(uint(3)), abs(bool(true))); +} + +[test] +uniform 0 float 2.0 +todo(msl) draw quad +probe (0, 0) rgba(2, 8, 3, 1) +uniform 0 float -1.0 +todo(msl) draw quad +probe (0, 0) rgba(1, 8, 3, 1)