mirror of
https://gitlab.winehq.org/wine/vkd3d.git
synced 2024-09-13 09:16:14 -07:00
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:
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
@ -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;
|
||||
}
|
||||
|
||||
|
104
tests/hlsl/bitwise-assignment.shader_test
Normal file
104
tests/hlsl/bitwise-assignment.shader_test
Normal 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)
|
@ -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
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user