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

@@ -1393,74 +1393,6 @@ bool hlsl_fold_constant_exprs(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr,
return success;
}
static bool constant_is_zero(struct hlsl_ir_constant *const_arg)
{
struct hlsl_type *data_type = const_arg->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 (const_arg->value.u[k].f != 0.0f)
return false;
break;
case HLSL_TYPE_DOUBLE:
if (const_arg->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 (const_arg->value.u[k].u != 0)
return false;
break;
}
}
return true;
}
static bool constant_is_one(struct hlsl_ir_constant *const_arg)
{
struct hlsl_type *data_type = const_arg->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 (const_arg->value.u[k].f != 1.0f)
return false;
break;
case HLSL_TYPE_DOUBLE:
if (const_arg->value.u[k].d != 1.0)
return false;
break;
case HLSL_TYPE_UINT:
case HLSL_TYPE_INT:
case HLSL_TYPE_MIN16UINT:
if (const_arg->value.u[k].u != 1)
return false;
break;
case HLSL_TYPE_BOOL:
if (const_arg->value.u[k].u != ~0)
return false;
break;
}
}
return true;
}
bool hlsl_fold_constant_identities(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, void *context)
{
struct hlsl_ir_constant *const_arg = NULL;
@@ -1502,26 +1434,26 @@ bool hlsl_fold_constant_identities(struct hlsl_ctx *ctx, struct hlsl_ir_node *in
switch (expr->op)
{
case HLSL_OP2_ADD:
if (constant_is_zero(const_arg))
if (hlsl_constant_is_zero(const_arg))
res_node = mut_arg;
break;
case HLSL_OP2_MUL:
if (constant_is_one(const_arg))
if (hlsl_constant_is_one(const_arg))
res_node = mut_arg;
break;
case HLSL_OP2_LOGIC_AND:
if (constant_is_zero(const_arg))
if (hlsl_constant_is_zero(const_arg))
res_node = &const_arg->node;
else if (constant_is_one(const_arg))
else if (hlsl_constant_is_one(const_arg))
res_node = mut_arg;
break;
case HLSL_OP2_LOGIC_OR:
if (constant_is_zero(const_arg))
if (hlsl_constant_is_zero(const_arg))
res_node = mut_arg;
else if (constant_is_one(const_arg))
else if (hlsl_constant_is_one(const_arg))
res_node = &const_arg->node;
break;