diff --git a/Makefile.am b/Makefile.am index 01d73167..36c63e56 100644 --- a/Makefile.am +++ b/Makefile.am @@ -62,6 +62,7 @@ vkd3d_shader_tests = \ tests/hlsl/array-size-expr.shader_test \ tests/hlsl/asfloat.shader_test \ tests/hlsl/asuint.shader_test \ + tests/hlsl/asint.shader_test \ tests/hlsl/attributes.shader_test \ tests/hlsl/bitwise.shader_test \ tests/hlsl/bool-cast.shader_test \ diff --git a/libs/vkd3d-shader/hlsl.y b/libs/vkd3d-shader/hlsl.y index 55ff8aa9..312eaec8 100644 --- a/libs/vkd3d-shader/hlsl.y +++ b/libs/vkd3d-shader/hlsl.y @@ -3299,6 +3299,29 @@ static bool intrinsic_asfloat(struct hlsl_ctx *ctx, return add_expr(ctx, params->instrs, HLSL_OP1_REINTERPRET, operands, data_type, loc); } +static bool intrinsic_asint(struct hlsl_ctx *ctx, + const struct parse_initializer *params, const struct vkd3d_shader_location *loc) +{ + struct hlsl_ir_node *operands[HLSL_MAX_OPERANDS] = {0}; + struct hlsl_type *data_type; + + data_type = params->args[0]->data_type; + if (data_type->e.numeric.type == HLSL_TYPE_BOOL || data_type->e.numeric.type == HLSL_TYPE_DOUBLE) + { + struct vkd3d_string_buffer *string; + + if ((string = hlsl_type_to_string(ctx, data_type))) + hlsl_error(ctx, loc, VKD3D_SHADER_ERROR_HLSL_INVALID_TYPE, + "Wrong argument type of asint(): expected 'int', 'uint', 'float', or 'half', but got '%s'.", + string->buffer); + hlsl_release_string_buffer(ctx, string); + } + data_type = convert_numeric_type(ctx, data_type, HLSL_TYPE_INT); + + operands[0] = params->args[0]; + return add_expr(ctx, params->instrs, HLSL_OP1_REINTERPRET, operands, data_type, loc); +} + static bool intrinsic_asuint(struct hlsl_ctx *ctx, const struct parse_initializer *params, const struct vkd3d_shader_location *loc) { @@ -4825,6 +4848,7 @@ intrinsic_functions[] = {"any", 1, true, intrinsic_any}, {"asfloat", 1, true, intrinsic_asfloat}, {"asin", 1, true, intrinsic_asin}, + {"asint", 1, true, intrinsic_asint}, {"asuint", -1, true, intrinsic_asuint}, {"atan", 1, true, intrinsic_atan}, {"atan2", 2, true, intrinsic_atan2}, diff --git a/tests/hlsl/asint.shader_test b/tests/hlsl/asint.shader_test new file mode 100644 index 00000000..74222afb --- /dev/null +++ b/tests/hlsl/asint.shader_test @@ -0,0 +1,60 @@ +[require] +shader model >= 4.0 + +[pixel shader] +uniform float f; +uniform int i; +uniform uint u; +uniform float h; + +float4 main() : sv_target +{ + uint4 ret; + + ret.x = asint(f); + ret.y = asint(i); + ret.z = asint(u); + ret.w = asint((half)h); + return ret; +} + +[test] +uniform 0 int4 123 0xc00000 456 0x7fd69345 +todo(glsl) draw quad +probe (320,240) rgba (123.0, 12582912.0, 456.0, 2144768896.0) + +[pixel shader] +uniform float2x2 m; +uniform float4 v; + +float4 main() : sv_target +{ + return float4(asint(m)[0][1], asint(v).y, 0, 0); +} + +[test] +uniform 0 int4 11 12 0 0 +uniform 4 int4 13 14 0 0 +uniform 8 int4 20 21 22 23 +todo(glsl) draw quad +probe (320,240) rgba (13.0, 21.0, 0.0, 0.0) + + +[pixel shader fail] + +float4 main() : sv_target +{ + bool b = true; + + return asint(b); +} + + +[pixel shader fail] + +float4 main() : sv_target +{ + double d = 1.0; + + return asint(d); +}