diff --git a/Makefile.am b/Makefile.am index 371c340f6..ecfc990d0 100644 --- a/Makefile.am +++ b/Makefile.am @@ -199,6 +199,7 @@ vkd3d_shader_tests = \ tests/hlsl/multiple-rt.shader_test \ tests/hlsl/nested-arrays.shader_test \ tests/hlsl/nointerpolation.shader_test \ + tests/hlsl/noise.shader_test \ tests/hlsl/non-const-indexing.shader_test \ tests/hlsl/normalize.shader_test \ tests/hlsl/null.shader_test \ diff --git a/libs/vkd3d-shader/hlsl.c b/libs/vkd3d-shader/hlsl.c index 653ddd2e8..2b88a04a1 100644 --- a/libs/vkd3d-shader/hlsl.c +++ b/libs/vkd3d-shader/hlsl.c @@ -3652,6 +3652,7 @@ const char *debug_hlsl_expr_op(enum hlsl_ir_expr_op op) [HLSL_OP1_LOG2] = "log2", [HLSL_OP1_LOGIC_NOT] = "!", [HLSL_OP1_NEG] = "-", + [HLSL_OP1_NOISE] = "noise", [HLSL_OP1_RCP] = "rcp", [HLSL_OP1_REINTERPRET] = "reinterpret", [HLSL_OP1_ROUND] = "round", diff --git a/libs/vkd3d-shader/hlsl.h b/libs/vkd3d-shader/hlsl.h index 8b1f3ec3d..3fdf0d20d 100644 --- a/libs/vkd3d-shader/hlsl.h +++ b/libs/vkd3d-shader/hlsl.h @@ -734,6 +734,7 @@ enum hlsl_ir_expr_op HLSL_OP1_ISINF, HLSL_OP1_LOG2, HLSL_OP1_LOGIC_NOT, + HLSL_OP1_NOISE, HLSL_OP1_NEG, HLSL_OP1_RCP, HLSL_OP1_REINTERPRET, diff --git a/libs/vkd3d-shader/hlsl.y b/libs/vkd3d-shader/hlsl.y index bad9d3309..fa3688fad 100644 --- a/libs/vkd3d-shader/hlsl.y +++ b/libs/vkd3d-shader/hlsl.y @@ -4294,6 +4294,28 @@ static bool intrinsic_mul(struct hlsl_ctx *ctx, return true; } +static bool intrinsic_noise(struct hlsl_ctx *ctx, + const struct parse_initializer *params, const struct vkd3d_shader_location *loc) +{ + struct hlsl_type *type = params->args[0]->data_type, *ret_type; + struct hlsl_ir_node *args[HLSL_MAX_OPERANDS] = {0}; + + type = params->args[0]->data_type; + if (type->class == 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, + "Wrong argument type for noise(): expected vector or scalar, but got '%s'.", string->buffer); + hlsl_release_string_buffer(ctx, string); + } + + args[0] = intrinsic_float_convert_arg(ctx, params, params->args[0], loc); + ret_type = hlsl_get_scalar_type(ctx, args[0]->data_type->e.numeric.type); + + return !!add_expr(ctx, params->instrs, HLSL_OP1_NOISE, args, ret_type, loc); +} + static bool intrinsic_normalize(struct hlsl_ctx *ctx, const struct parse_initializer *params, const struct vkd3d_shader_location *loc) { @@ -5258,6 +5280,7 @@ intrinsic_functions[] = {"min", 2, true, intrinsic_min}, {"modf", 2, true, intrinsic_modf}, {"mul", 2, true, intrinsic_mul}, + {"noise", 1, true, intrinsic_noise}, {"normalize", 1, true, intrinsic_normalize}, {"pow", 2, true, intrinsic_pow}, {"radians", 1, true, intrinsic_radians}, diff --git a/tests/hlsl/noise.shader_test b/tests/hlsl/noise.shader_test new file mode 100644 index 000000000..d41bcb309 --- /dev/null +++ b/tests/hlsl/noise.shader_test @@ -0,0 +1,33 @@ +[pixel shader fail(sm>=6)] +float v1; +float1 v2; +float4 v3; +int2 v4; +int3 v5; + +float4 func() +{ + return noise(v1) + noise(v2) + noise(v3) + noise(v4) + noise(v5); +} + +float4 main() : sv_target +{ + return float4(1, 2, 3, 4); +} + +[test] +draw quad +probe (0, 0) f32(1.0, 2.0, 3.0, 4.0) + +[pixel shader fail] +float2x2 v1; + +float4 func() +{ + return noise(v1); +} + +float4 main() : sv_target +{ + return float4(1, 2, 3, 4); +}