mirror of
https://gitlab.winehq.org/wine/vkd3d.git
synced 2025-09-12 18:50:22 -07:00
vkd3d-shader/hlsl: Implement the frexp() intrinsic.
This commit is contained in:
committed by
Henri Verbeet
parent
ea6104cf5e
commit
d964d55b4a
Notes:
Henri Verbeet
2025-08-21 16:34:21 +02:00
Approved-by: Elizabeth Figura (@zfigura) Approved-by: Henri Verbeet (@hverbeet) Merge-Request: https://gitlab.winehq.org/wine/vkd3d/-/merge_requests/1000
@@ -3983,6 +3983,53 @@ static bool intrinsic_frac(struct hlsl_ctx *ctx,
|
|||||||
return !!add_unary_arithmetic_expr(ctx, params->instrs, HLSL_OP1_FRACT, arg, loc);
|
return !!add_unary_arithmetic_expr(ctx, params->instrs, HLSL_OP1_FRACT, arg, loc);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool intrinsic_frexp(struct hlsl_ctx *ctx,
|
||||||
|
const struct parse_initializer *params, const struct vkd3d_shader_location *loc)
|
||||||
|
{
|
||||||
|
struct hlsl_type *type, *uint_dim_type, *int_dim_type, *bool_dim_type;
|
||||||
|
struct hlsl_ir_function_decl *func;
|
||||||
|
char *body;
|
||||||
|
|
||||||
|
static const char template[] =
|
||||||
|
"%s frexp(%s x, out %s exp)\n"
|
||||||
|
"{\n"
|
||||||
|
/* If x is zero, always return zero for exp and mantissa. */
|
||||||
|
" %s is_nonzero_mask = x != 0.0;\n"
|
||||||
|
" %s bits = asuint(x);\n"
|
||||||
|
/* Subtract 126, not 127, to increase the exponent */
|
||||||
|
" %s exp_int = asint((bits & 0x7f800000u) >> 23) - 126;\n"
|
||||||
|
/* Clear the given exponent and replace it with the bit pattern
|
||||||
|
* for 2^-1 */
|
||||||
|
" %s mantissa = asfloat((bits & 0x007fffffu) | 0x3f000000);\n"
|
||||||
|
" exp = is_nonzero_mask * %s(exp_int);\n"
|
||||||
|
" return is_nonzero_mask * mantissa;\n"
|
||||||
|
"}\n";
|
||||||
|
|
||||||
|
if (!elementwise_intrinsic_float_convert_args(ctx, params, loc))
|
||||||
|
return false;
|
||||||
|
type = params->args[0]->data_type;
|
||||||
|
|
||||||
|
if (type->e.numeric.type == HLSL_TYPE_DOUBLE)
|
||||||
|
{
|
||||||
|
hlsl_fixme(ctx, loc, "frexp() on doubles.");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
type = hlsl_get_numeric_type(ctx, type->class, HLSL_TYPE_FLOAT, type->e.numeric.dimx, type->e.numeric.dimy);
|
||||||
|
uint_dim_type = hlsl_get_numeric_type(ctx, type->class, HLSL_TYPE_UINT, type->e.numeric.dimx, type->e.numeric.dimy);
|
||||||
|
int_dim_type = hlsl_get_numeric_type(ctx, type->class, HLSL_TYPE_INT, type->e.numeric.dimx, type->e.numeric.dimy);
|
||||||
|
bool_dim_type = hlsl_get_numeric_type(ctx, type->class, HLSL_TYPE_BOOL, type->e.numeric.dimx, type->e.numeric.dimy);
|
||||||
|
|
||||||
|
if (!(body = hlsl_sprintf_alloc(ctx, template, type->name, type->name, type->name,
|
||||||
|
bool_dim_type->name, uint_dim_type->name, int_dim_type->name, type->name, type->name)))
|
||||||
|
return false;
|
||||||
|
func = hlsl_compile_internal_function(ctx, "frexp", body);
|
||||||
|
vkd3d_free(body);
|
||||||
|
if (!func)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return !!add_user_call(ctx, func, params, false, loc);
|
||||||
|
}
|
||||||
|
|
||||||
static bool intrinsic_fwidth(struct hlsl_ctx *ctx,
|
static bool intrinsic_fwidth(struct hlsl_ctx *ctx,
|
||||||
const struct parse_initializer *params, const struct vkd3d_shader_location *loc)
|
const struct parse_initializer *params, const struct vkd3d_shader_location *loc)
|
||||||
{
|
{
|
||||||
@@ -5283,6 +5330,7 @@ intrinsic_functions[] =
|
|||||||
{"floor", 1, true, intrinsic_floor},
|
{"floor", 1, true, intrinsic_floor},
|
||||||
{"fmod", 2, true, intrinsic_fmod},
|
{"fmod", 2, true, intrinsic_fmod},
|
||||||
{"frac", 1, true, intrinsic_frac},
|
{"frac", 1, true, intrinsic_frac},
|
||||||
|
{"frexp", 2, true, intrinsic_frexp},
|
||||||
{"fwidth", 1, true, intrinsic_fwidth},
|
{"fwidth", 1, true, intrinsic_fwidth},
|
||||||
{"isinf", 1, true, intrinsic_isinf},
|
{"isinf", 1, true, intrinsic_isinf},
|
||||||
{"ldexp", 2, true, intrinsic_ldexp},
|
{"ldexp", 2, true, intrinsic_ldexp},
|
||||||
|
@@ -1,4 +1,4 @@
|
|||||||
[pixel shader todo(sm<6)]
|
[pixel shader todo(sm<4)]
|
||||||
uniform float4 f;
|
uniform float4 f;
|
||||||
|
|
||||||
float4 main() : sv_target
|
float4 main() : sv_target
|
||||||
@@ -10,52 +10,52 @@ float4 main() : sv_target
|
|||||||
|
|
||||||
[test]
|
[test]
|
||||||
uniform 0 float4 3.1415927 0.0 0.0 0.0
|
uniform 0 float4 3.1415927 0.0 0.0 0.0
|
||||||
todo(sm<6 | msl) draw quad
|
todo(sm<4 | msl & sm>=6) draw quad
|
||||||
probe (0, 0) f32(2.0, 0.785398185, 0.0, 0.0)
|
probe (0, 0) f32(2.0, 0.785398185, 0.0, 0.0)
|
||||||
|
|
||||||
uniform 0 float4 -3.1415927 0.0 0.0 0.0
|
uniform 0 float4 -3.1415927 0.0 0.0 0.0
|
||||||
todo(sm<6 | msl) draw quad
|
todo(sm<4 | msl & sm>=6) draw quad
|
||||||
if(sm<4) probe (0, 0) f32(2.0, -0.785398185, 0.0, 0.0)
|
if(sm<4) probe (0, 0) f32(2.0, -0.785398185, 0.0, 0.0)
|
||||||
% Starting with shader model 4, negative inputs give positive mantissa.
|
% Starting with shader model 4, negative inputs give positive mantissa.
|
||||||
if(sm>=4) probe (0, 0) f32(2.0, 0.785398185, 0.0, 0.0)
|
if(sm>=4) probe (0, 0) f32(2.0, 0.785398185, 0.0, 0.0)
|
||||||
|
|
||||||
uniform 0 float4 7604.123 0.0 0.0 0.0
|
uniform 0 float4 7604.123 0.0 0.0 0.0
|
||||||
todo(sm<6 | msl) draw quad
|
todo(sm<4 | msl & sm>=6) draw quad
|
||||||
probe (0, 0) f32(13.0, 0.92823765, 0.0, 0.0)
|
probe (0, 0) f32(13.0, 0.92823765, 0.0, 0.0)
|
||||||
|
|
||||||
uniform 0 float4 0.00001234 0.0 0.0 0.0
|
uniform 0 float4 0.00001234 0.0 0.0 0.0
|
||||||
todo(sm<6 | msl) draw quad
|
todo(sm<4 | msl & sm>=6) draw quad
|
||||||
probe (0, 0) f32(-16.0, 0.8087142, 0.0, 0.0)
|
probe (0, 0) f32(-16.0, 0.8087142, 0.0, 0.0)
|
||||||
|
|
||||||
uniform 0 float4 0.0 0.0 0.0 0.0
|
uniform 0 float4 0.0 0.0 0.0 0.0
|
||||||
todo(sm<6 | msl) draw quad
|
todo(sm<4 | msl & sm>=6) draw quad
|
||||||
probe (0, 0) f32(0.0, 0.0, 0.0, 0.0)
|
probe (0, 0) f32(0.0, 0.0, 0.0, 0.0)
|
||||||
|
|
||||||
uniform 0 float4 -0.0 0.0 0.0 0.0
|
uniform 0 float4 -0.0 0.0 0.0 0.0
|
||||||
todo(sm<6 | msl) draw quad
|
todo(sm<4 | msl & sm>=6) draw quad
|
||||||
probe (0, 0) f32(0.0, 0.0, 0.0, 0.0)
|
probe (0, 0) f32(0.0, 0.0, 0.0, 0.0)
|
||||||
|
|
||||||
uniform 0 float4 INF 0.0 0.0 0.0
|
uniform 0 float4 INF 0.0 0.0 0.0
|
||||||
todo(sm<6 | msl) draw quad
|
todo(sm<4 | msl & sm>=6) draw quad
|
||||||
if(sm<4) probe (0, 0) f32(-NAN, -NAN, 0, 0)
|
if(sm<4) probe (0, 0) f32(-NAN, -NAN, 0, 0)
|
||||||
if(sm>=4) probe (0, 0) f32(129, 0.5, 0, 0)
|
if(sm>=4) probe (0, 0) f32(129, 0.5, 0, 0)
|
||||||
|
|
||||||
uniform 0 float4 -INF 0.0 0.0 0.0
|
uniform 0 float4 -INF 0.0 0.0 0.0
|
||||||
todo(sm<6 | msl) draw quad
|
todo(sm<4 | msl & sm>=6) draw quad
|
||||||
if(sm<4) probe (0, 0) f32(-NAN, -NAN, 0, 0)
|
if(sm<4) probe (0, 0) f32(-NAN, -NAN, 0, 0)
|
||||||
if(sm>=4) probe (0, 0) f32(129, 0.5, 0, 0)
|
if(sm>=4) probe (0, 0) f32(129, 0.5, 0, 0)
|
||||||
|
|
||||||
uniform 0 float4 NAN 0 0 0
|
uniform 0 float4 NAN 0 0 0
|
||||||
todo(sm<6 | msl) draw quad
|
todo(sm<4 | msl & sm>=6) draw quad
|
||||||
if(sm<4) probe (0, 0) f32(NAN, NAN, 0, 0)
|
if(sm<4) probe (0, 0) f32(NAN, NAN, 0, 0)
|
||||||
if(sm>=4) probe (0, 0) f32(129, 0.75, 0, 0)
|
if(sm>=4) probe (0, 0) f32(129, 0.75, 0, 0)
|
||||||
|
|
||||||
% Subnormals.
|
% Subnormals.
|
||||||
uniform 0 uint4 0x0007ffff 0 0 0
|
uniform 0 uint4 0x0007ffff 0 0 0
|
||||||
todo(sm<6 | msl) draw quad
|
todo(sm<4 | msl & sm>=6) draw quad
|
||||||
probe (0, 0) f32(0, 0, 0, 0)
|
probe (0, 0) f32(0, 0, 0, 0)
|
||||||
|
|
||||||
[pixel shader todo(sm<6)]
|
[pixel shader todo(sm<4)]
|
||||||
float4 main() : sv_target
|
float4 main() : sv_target
|
||||||
{
|
{
|
||||||
int arg = 7604;
|
int arg = 7604;
|
||||||
@@ -66,10 +66,10 @@ float4 main() : sv_target
|
|||||||
}
|
}
|
||||||
|
|
||||||
[test]
|
[test]
|
||||||
todo(sm<6) draw quad
|
todo(sm<4) draw quad
|
||||||
probe (0, 0) f32(13.0, 0.0, 0.0, 0.0)
|
probe (0, 0) f32(13.0, 0.0, 0.0, 0.0)
|
||||||
|
|
||||||
[pixel shader todo(sm<6)]
|
[pixel shader todo(sm<4)]
|
||||||
float4 main() : sv_target
|
float4 main() : sv_target
|
||||||
{
|
{
|
||||||
bool arg = true;
|
bool arg = true;
|
||||||
@@ -80,11 +80,11 @@ float4 main() : sv_target
|
|||||||
}
|
}
|
||||||
|
|
||||||
[test]
|
[test]
|
||||||
todo(sm<6) draw quad
|
todo(sm<4) draw quad
|
||||||
if(sm<4) probe (0, 0) f32(0.0, 1.0, 0.0, 0.0)
|
if(sm<4) probe (0, 0) f32(0.0, 1.0, 0.0, 0.0)
|
||||||
if(sm>=4) probe (0, 0) f32(1.0, 1.0, 0.0, 0.0)
|
if(sm>=4) probe (0, 0) f32(1.0, 1.0, 0.0, 0.0)
|
||||||
|
|
||||||
[pixel shader todo(sm<6)]
|
[pixel shader todo(sm<4)]
|
||||||
float4 main() : sv_target
|
float4 main() : sv_target
|
||||||
{
|
{
|
||||||
half arg = 3.141;
|
half arg = 3.141;
|
||||||
@@ -95,7 +95,7 @@ float4 main() : sv_target
|
|||||||
}
|
}
|
||||||
|
|
||||||
[test]
|
[test]
|
||||||
todo(sm<6) draw quad
|
todo(sm<4) draw quad
|
||||||
probe (0, 0) f32(2.0, 0.785250008, 0.0, 0.0)
|
probe (0, 0) f32(2.0, 0.785250008, 0.0, 0.0)
|
||||||
|
|
||||||
[require]
|
[require]
|
||||||
|
Reference in New Issue
Block a user