vkd3d-shader/hlsl: Fold some general conditional identities.

The following conditional identities are applied:

  c ? x : x -> x
  false ? x : y -> y; true ? x : y -> x
  c ? true : false -> c; c ? false : true -> !c
  !c ? x : y -> c ? y : x

Lastly, for expression chains x, y in a conditional expression
  c ? x : y,
we evaluate all conditionals in the expression chains with the
condition c, assuming c is true (for x), or false (for y).
This commit is contained in:
Shaun Ren
2025-08-01 19:24:12 -04:00
committed by Henri Verbeet
parent 245430002a
commit 320c3c9652
Notes: Henri Verbeet 2025-08-21 16:34:35 +02:00
Approved-by: Francisco Casas (@fcasas)
Approved-by: Elizabeth Figura (@zfigura)
Approved-by: Henri Verbeet (@hverbeet)
Merge-Request: https://gitlab.winehq.org/wine/vkd3d/-/merge_requests/1648
5 changed files with 352 additions and 74 deletions

View File

@@ -1809,6 +1809,76 @@ struct hlsl_ir_node *hlsl_new_null_constant(struct hlsl_ctx *ctx, const struct v
return hlsl_new_constant(ctx, ctx->builtin_types.null, &value, loc);
}
bool hlsl_constant_is_zero(struct hlsl_ir_constant *c)
{
struct hlsl_type *data_type = c->node.data_type;
unsigned int k;
for (k = 0; k < data_type->e.numeric.dimx; ++k)
{
switch (data_type->e.numeric.type)
{
case HLSL_TYPE_FLOAT:
case HLSL_TYPE_HALF:
if (c->value.u[k].f != 0.0f)
return false;
break;
case HLSL_TYPE_DOUBLE:
if (c->value.u[k].d != 0.0)
return false;
break;
case HLSL_TYPE_UINT:
case HLSL_TYPE_INT:
case HLSL_TYPE_BOOL:
case HLSL_TYPE_MIN16UINT:
if (c->value.u[k].u != 0)
return false;
break;
}
}
return true;
}
bool hlsl_constant_is_one(struct hlsl_ir_constant *c)
{
struct hlsl_type *data_type = c->node.data_type;
unsigned int k;
for (k = 0; k < data_type->e.numeric.dimx; ++k)
{
switch (data_type->e.numeric.type)
{
case HLSL_TYPE_FLOAT:
case HLSL_TYPE_HALF:
if (c->value.u[k].f != 1.0f)
return false;
break;
case HLSL_TYPE_DOUBLE:
if (c->value.u[k].d != 1.0)
return false;
break;
case HLSL_TYPE_UINT:
case HLSL_TYPE_INT:
case HLSL_TYPE_MIN16UINT:
if (c->value.u[k].u != 1)
return false;
break;
case HLSL_TYPE_BOOL:
if (c->value.u[k].u != ~0)
return false;
break;
}
}
return true;
}
static struct hlsl_ir_node *hlsl_new_expr(struct hlsl_ctx *ctx, enum hlsl_ir_expr_op op,
struct hlsl_ir_node *operands[HLSL_MAX_OPERANDS],
struct hlsl_type *data_type, const struct vkd3d_shader_location *loc)