vkd3d-shader/hlsl: Factor out add_binary_expr() and use it for assignment operators.

This fixes a lot of internal compiler errors with assignment operators,
especially bitwise ones. The bitwise-assignment test has the motivating
examples.
This commit is contained in:
Petrichor Park 2024-08-14 13:53:25 -05:00 committed by Henri Verbeet
parent ebc039d128
commit 4467c655f0
Notes: Henri Verbeet 2024-08-19 14:29:40 +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/999
3 changed files with 160 additions and 36 deletions

View File

@ -1899,6 +1899,41 @@ static struct hlsl_ir_node *add_binary_dot_expr(struct hlsl_ctx *ctx, struct hls
return add_expr(ctx, instrs, op, args, ret_type, loc);
}
static struct hlsl_ir_node *add_binary_expr(struct hlsl_ctx *ctx, struct hlsl_block *block, enum hlsl_ir_expr_op op,
struct hlsl_ir_node *lhs, struct hlsl_ir_node *rhs, const struct vkd3d_shader_location *loc)
{
switch (op)
{
case HLSL_OP2_ADD:
case HLSL_OP2_DIV:
case HLSL_OP2_MOD:
case HLSL_OP2_MUL:
return add_binary_arithmetic_expr(ctx, block, op, lhs, rhs, loc);
case HLSL_OP2_BIT_AND:
case HLSL_OP2_BIT_OR:
case HLSL_OP2_BIT_XOR:
return add_binary_bitwise_expr(ctx, block, op, lhs, rhs, loc);
case HLSL_OP2_LESS:
case HLSL_OP2_GEQUAL:
case HLSL_OP2_EQUAL:
case HLSL_OP2_NEQUAL:
return add_binary_comparison_expr(ctx, block, op, lhs, rhs, loc);
case HLSL_OP2_LOGIC_AND:
case HLSL_OP2_LOGIC_OR:
return add_binary_logical_expr(ctx, block, op, lhs, rhs, loc);
case HLSL_OP2_LSHIFT:
case HLSL_OP2_RSHIFT:
return add_binary_shift_expr(ctx, block, op, lhs, rhs, loc);
default:
vkd3d_unreachable();
}
}
static struct hlsl_block *add_binary_expr_merge(struct hlsl_ctx *ctx, struct hlsl_block *block1,
struct hlsl_block *block2, enum hlsl_ir_expr_op op, const struct vkd3d_shader_location *loc)
{
@ -1907,41 +1942,8 @@ static struct hlsl_block *add_binary_expr_merge(struct hlsl_ctx *ctx, struct hls
hlsl_block_add_block(block1, block2);
destroy_block(block2);
switch (op)
{
case HLSL_OP2_ADD:
case HLSL_OP2_DIV:
case HLSL_OP2_MOD:
case HLSL_OP2_MUL:
add_binary_arithmetic_expr(ctx, block1, op, arg1, arg2, loc);
break;
case HLSL_OP2_BIT_AND:
case HLSL_OP2_BIT_OR:
case HLSL_OP2_BIT_XOR:
add_binary_bitwise_expr(ctx, block1, op, arg1, arg2, loc);
break;
case HLSL_OP2_LESS:
case HLSL_OP2_GEQUAL:
case HLSL_OP2_EQUAL:
case HLSL_OP2_NEQUAL:
add_binary_comparison_expr(ctx, block1, op, arg1, arg2, loc);
break;
case HLSL_OP2_LOGIC_AND:
case HLSL_OP2_LOGIC_OR:
add_binary_logical_expr(ctx, block1, op, arg1, arg2, loc);
break;
case HLSL_OP2_LSHIFT:
case HLSL_OP2_RSHIFT:
add_binary_shift_expr(ctx, block1, op, arg1, arg2, loc);
break;
default:
vkd3d_unreachable();
}
if (add_binary_expr(ctx, block1, op, arg1, arg2, loc) == NULL)
return NULL;
return block1;
}
@ -2065,7 +2067,7 @@ static struct hlsl_ir_node *add_assignment(struct hlsl_ctx *ctx, struct hlsl_blo
enum hlsl_ir_expr_op op = op_from_assignment(assign_op);
VKD3D_ASSERT(op);
if (!(rhs = add_binary_arithmetic_expr(ctx, block, op, lhs, rhs, &rhs->loc)))
if (!(rhs = add_binary_expr(ctx, block, op, lhs, rhs, &rhs->loc)))
return NULL;
}

View File

@ -0,0 +1,104 @@
[require]
shader model >= 4.0
[pixel shader]
uniform uint4 nonconst;
float4 main() : SV_TARGET
{
uint a = 35, r = 2;
uint shifted = a; shifted >>= nonconst.x;
a >>= r;
return float4(a, shifted, 0, 0);
}
[test]
uniform 0 uint4 2 0 0 0
todo(glsl) draw quad
probe (0, 0) rgba (8, 8, 0, 0)
[pixel shader]
uniform uint4 nonconst;
float4 main() : SV_TARGET
{
int a = 5, b = -12;
uint r = 1;
int shifted_a = a; shifted_a >>= nonconst.x;
int shifted_b = b; shifted_b >>= nonconst.x;
a >>= r;
b >>= r;
return float4(a, b, shifted_a, shifted_b);
}
[test]
uniform 0 uint4 1 0 0 0
todo(glsl) draw quad
probe (0, 0) rgba (2, -6, 2, -6)
[pixel shader]
uniform uint4 nonconst;
float4 main() : SV_TARGET
{
uint a = 35, r = 3;
uint shifted = a; shifted <<= nonconst.x;
a <<= r;
return float4(a, shifted, 0, 0);
}
[test]
uniform 0 uint4 3 0 0 0
todo(glsl) draw quad
probe (0, 0) rgba (280, 280, 0, 0)
[pixel shader]
uniform uint4 nonconst;
float4 main() : SV_TARGET
{
int a = 5, b = -12;
uint r = 2;
int shifted_a = a; shifted_a <<= nonconst.x;
int shifted_b = b; shifted_b <<= nonconst.x;
a <<= r;
b <<= r;
return float4(a, b, shifted_a, shifted_b);
}
[test]
uniform 0 uint4 2 0 0 0
todo(glsl) draw quad
probe (0, 0) rgba (20, -48, 20, -48)
[pixel shader fail]
% Make sure that bitshifts DON'T work with floats
float4 main() : SV_TARGET
{
float x = 5.0, y = 15.0;
x <<= y;
y <<= x;
return float4(x, y, 0, 0);
}
[pixel shader]
float4 main() : SV_TARGET
{
int source = 55;
int i = -0x4141;
uint u = 128;
int a = source; a &= i;
int b = source; b |= u;
int c = source; c ^= i;
return float4(a, b, c, 0);
}
[test]
todo(glsl) draw quad
probe (0, 0) rgba (55, 183, -16760, 0)

View File

@ -129,6 +129,24 @@ float4 main() : SV_TARGET
todo(glsl) draw quad
probe (0, 0) rgba (0.0, 0.0, 163840.0, 480.0)
[pixel shader fail]
% Make sure that bitshifts DON'T work with floats
float4 main() : SV_TARGET
{
uint u = 5;
float f = 15.0;
return float4(u >> f, 0, 0, 0);
}
[pixel shader fail]
float4 main() : SV_TARGET
{
uint u = 5;
float f = 15.0;
return float4(f >> u, 0, 0, 0);
}
[pixel shader]
float4 main() : SV_TARGET
{