vkd3d-shader/hlsl: Correctly fold casts from float.

I.e., without invoking undefined behavior in the compiler. The rules
are desumed from the the MSDN documentation for ftoi and ftou.
This commit is contained in:
Giovanni Mascellani 2023-09-10 22:50:01 +02:00 committed by Alexandre Julliard
parent d9c984c11a
commit 49bbd98a04
Notes: Alexandre Julliard 2023-09-22 22:46:53 +02:00
Approved-by: Zebediah Figura (@zfigura)
Approved-by: Francisco Casas (@fcasas)
Approved-by: Henri Verbeet (@hverbeet)
Approved-by: Alexandre Julliard (@julliard)
Merge-Request: https://gitlab.winehq.org/wine/vkd3d/-/merge_requests/338
2 changed files with 28 additions and 3 deletions

View File

@ -63,6 +63,31 @@ static bool fold_abs(struct hlsl_ctx *ctx, struct hlsl_constant_value *dst,
return true;
}
static uint32_t float_to_uint(float x)
{
if (isnan(x) || x <= 0)
return 0;
if (x >= 4294967296.0f)
return UINT32_MAX;
return x;
}
static int32_t float_to_int(float x)
{
if (isnan(x))
return 0;
if (x <= -2147483648.0f)
return INT32_MIN;
if (x >= 2147483648.0f)
return INT32_MAX;
return x;
}
static bool fold_cast(struct hlsl_ctx *ctx, struct hlsl_constant_value *dst,
const struct hlsl_type *dst_type, const struct hlsl_ir_constant *src)
{
@ -86,8 +111,8 @@ static bool fold_cast(struct hlsl_ctx *ctx, struct hlsl_constant_value *dst,
{
case HLSL_TYPE_FLOAT:
case HLSL_TYPE_HALF:
u = src->value.u[k].f;
i = src->value.u[k].f;
u = float_to_uint(src->value.u[k].f);
i = float_to_int(src->value.u[k].f);
f = src->value.u[k].f;
d = src->value.u[k].f;
break;

View File

@ -41,4 +41,4 @@ float4 main() : sv_target
[test]
draw quad
todo probe all rgba (0.5, 0.5, 0.5, 0.5)
probe all rgba (0.5, 0.5, 0.5, 0.5)