mirror of
https://gitlab.winehq.org/wine/vkd3d.git
synced 2025-01-28 13:05:02 -08:00
vkd3d-shader/hlsl: Implement the isinf() intrinsic.
Signed-off-by: Nikolay Sivov <nsivov@codeweavers.com>
This commit is contained in:
parent
ce4f2728ba
commit
a082daeb56
Notes:
Henri Verbeet
2025-01-16 19:30:04 +01:00
Approved-by: Elizabeth Figura (@zfigura) Approved-by: Henri Verbeet (@hverbeet) Merge-Request: https://gitlab.winehq.org/wine/vkd3d/-/merge_requests/1336
@ -164,6 +164,7 @@ vkd3d_shader_tests = \
|
||||
tests/hlsl/invalid.shader_test \
|
||||
tests/hlsl/inverse-trig.shader_test \
|
||||
tests/hlsl/is-front-face.shader_test \
|
||||
tests/hlsl/isinf.shader_test \
|
||||
tests/hlsl/ldexp.shader_test \
|
||||
tests/hlsl/length.shader_test \
|
||||
tests/hlsl/lerp.shader_test \
|
||||
|
@ -3238,6 +3238,7 @@ const char *debug_hlsl_expr_op(enum hlsl_ir_expr_op op)
|
||||
[HLSL_OP1_F32TOF16] = "f32tof16",
|
||||
[HLSL_OP1_FLOOR] = "floor",
|
||||
[HLSL_OP1_FRACT] = "fract",
|
||||
[HLSL_OP1_ISINF] = "isinf",
|
||||
[HLSL_OP1_LOG2] = "log2",
|
||||
[HLSL_OP1_LOGIC_NOT] = "!",
|
||||
[HLSL_OP1_NEG] = "-",
|
||||
|
@ -704,6 +704,7 @@ enum hlsl_ir_expr_op
|
||||
HLSL_OP1_F32TOF16,
|
||||
HLSL_OP1_FLOOR,
|
||||
HLSL_OP1_FRACT,
|
||||
HLSL_OP1_ISINF,
|
||||
HLSL_OP1_LOG2,
|
||||
HLSL_OP1_LOGIC_NOT,
|
||||
HLSL_OP1_NEG,
|
||||
|
@ -4313,6 +4313,19 @@ static bool intrinsic_fwidth(struct hlsl_ctx *ctx,
|
||||
return !!add_user_call(ctx, func, params, false, loc);
|
||||
}
|
||||
|
||||
static bool intrinsic_isinf(struct hlsl_ctx *ctx,
|
||||
const struct parse_initializer *params, const struct vkd3d_shader_location *loc)
|
||||
{
|
||||
struct hlsl_type *type = params->args[0]->data_type, *bool_type;
|
||||
struct hlsl_ir_node *args[HLSL_MAX_OPERANDS] = {0};
|
||||
|
||||
bool_type = hlsl_get_numeric_type(ctx, type->class, HLSL_TYPE_BOOL,
|
||||
type->e.numeric.dimx, type->e.numeric.dimy);
|
||||
|
||||
args[0] = params->args[0];
|
||||
return !!add_expr(ctx, params->instrs, HLSL_OP1_ISINF, args, bool_type, loc);
|
||||
}
|
||||
|
||||
static bool intrinsic_ldexp(struct hlsl_ctx *ctx,
|
||||
const struct parse_initializer *params, const struct vkd3d_shader_location *loc)
|
||||
{
|
||||
@ -5410,6 +5423,7 @@ intrinsic_functions[] =
|
||||
{"fmod", 2, true, intrinsic_fmod},
|
||||
{"frac", 1, true, intrinsic_frac},
|
||||
{"fwidth", 1, true, intrinsic_fwidth},
|
||||
{"isinf", 1, true, intrinsic_isinf},
|
||||
{"ldexp", 2, true, intrinsic_ldexp},
|
||||
{"length", 1, true, intrinsic_length},
|
||||
{"lerp", 3, true, intrinsic_lerp},
|
||||
|
@ -11825,6 +11825,95 @@ static bool lower_f32tof16(struct hlsl_ctx *ctx, struct hlsl_ir_node *node, stru
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool lower_isinf(struct hlsl_ctx *ctx, struct hlsl_ir_node *node, struct hlsl_block *block)
|
||||
{
|
||||
struct hlsl_ir_node *call, *rhs, *store;
|
||||
struct hlsl_ir_function_decl *func;
|
||||
unsigned int component_count;
|
||||
struct hlsl_ir_load *load;
|
||||
struct hlsl_ir_expr *expr;
|
||||
struct hlsl_ir_var *lhs;
|
||||
const char *template;
|
||||
char *body;
|
||||
|
||||
static const char template_sm2[] =
|
||||
"typedef bool%u boolX;\n"
|
||||
"typedef float%u floatX;\n"
|
||||
"boolX isinf(floatX x)\n"
|
||||
"{\n"
|
||||
" floatX v = 1 / x;\n"
|
||||
" v = v * v;\n"
|
||||
" return v <= 0;\n"
|
||||
"}\n";
|
||||
|
||||
static const char template_sm3[] =
|
||||
"typedef bool%u boolX;\n"
|
||||
"typedef float%u floatX;\n"
|
||||
"boolX isinf(floatX x)\n"
|
||||
"{\n"
|
||||
" floatX v = 1 / x;\n"
|
||||
" return v <= 0;\n"
|
||||
"}\n";
|
||||
|
||||
static const char template_sm4[] =
|
||||
"typedef bool%u boolX;\n"
|
||||
"typedef float%u floatX;\n"
|
||||
"boolX isinf(floatX x)\n"
|
||||
"{\n"
|
||||
" return (asuint(x) & 0x7fffffff) == 0x7f800000;\n"
|
||||
"}\n";
|
||||
|
||||
static const char template_int[] =
|
||||
"typedef bool%u boolX;\n"
|
||||
"typedef float%u floatX;\n"
|
||||
"boolX isinf(floatX x)\n"
|
||||
"{\n"
|
||||
" return false;\n"
|
||||
"}";
|
||||
|
||||
if (node->type != HLSL_IR_EXPR)
|
||||
return false;
|
||||
|
||||
expr = hlsl_ir_expr(node);
|
||||
|
||||
if (expr->op != HLSL_OP1_ISINF)
|
||||
return false;
|
||||
|
||||
rhs = expr->operands[0].node;
|
||||
|
||||
if (hlsl_version_lt(ctx, 3, 0))
|
||||
template = template_sm2;
|
||||
else if (hlsl_version_lt(ctx, 4, 0))
|
||||
template = template_sm3;
|
||||
else if (type_is_integer(rhs->data_type))
|
||||
template = template_int;
|
||||
else
|
||||
template = template_sm4;
|
||||
|
||||
component_count = hlsl_type_component_count(rhs->data_type);
|
||||
if (!(body = hlsl_sprintf_alloc(ctx, template, component_count, component_count)))
|
||||
return false;
|
||||
|
||||
if (!(func = hlsl_compile_internal_function(ctx, "isinf", body)))
|
||||
return false;
|
||||
|
||||
lhs = func->parameters.vars[0];
|
||||
|
||||
if (!(store = hlsl_new_simple_store(ctx, lhs, rhs)))
|
||||
return false;
|
||||
hlsl_block_add_instr(block, store);
|
||||
|
||||
if (!(call = hlsl_new_call(ctx, func, &node->loc)))
|
||||
return false;
|
||||
hlsl_block_add_instr(block, call);
|
||||
|
||||
if (!(load = hlsl_new_var_load(ctx, func->return_var, &node->loc)))
|
||||
return false;
|
||||
hlsl_block_add_instr(block, &load->node);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static void process_entry_function(struct hlsl_ctx *ctx,
|
||||
const struct hlsl_block *global_uniform_block, struct hlsl_ir_function_decl *entry_func)
|
||||
{
|
||||
@ -11858,6 +11947,8 @@ static void process_entry_function(struct hlsl_ctx *ctx,
|
||||
lower_ir(ctx, lower_f32tof16, body);
|
||||
}
|
||||
|
||||
lower_ir(ctx, lower_isinf, body);
|
||||
|
||||
lower_return(ctx, entry_func, body, false);
|
||||
|
||||
while (hlsl_transform_ir(ctx, lower_calls, body, NULL));
|
||||
|
31
tests/hlsl/isinf.shader_test
Normal file
31
tests/hlsl/isinf.shader_test
Normal file
@ -0,0 +1,31 @@
|
||||
[pixel shader]
|
||||
float4 v;
|
||||
|
||||
float4 main() : sv_target
|
||||
{
|
||||
return isinf(1.0f / v) + 1.0f;
|
||||
}
|
||||
|
||||
[test]
|
||||
uniform 0 float4 1.0 0.0 -0.0 0.0
|
||||
draw quad
|
||||
probe (0, 0) rgba(1.0, 2.0, 2.0, 2.0)
|
||||
|
||||
[require]
|
||||
shader model >= 4.0
|
||||
|
||||
[pixel shader]
|
||||
float4 v;
|
||||
|
||||
float4 main() : sv_target
|
||||
{
|
||||
return isinf(v) + 1.0f;
|
||||
}
|
||||
|
||||
[test]
|
||||
uniform 0 float4 1.0 0.0 -1.0 2.0
|
||||
draw quad
|
||||
probe (0, 0) rgba(1.0, 1.0, 1.0, 1.0)
|
||||
uniform 0 uint4 0x7f800000 0xff800000 0xffc00001 0xff800001
|
||||
draw quad
|
||||
probe (0, 0) rgba(2.0, 2.0, 1.0, 1.0)
|
Loading…
x
Reference in New Issue
Block a user