Signed-off-by: Conor McCarthy cmccarthy@codeweavers.com --- v2: Also test immediate constants. --- tests/d3d12.c | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-)
diff --git a/tests/d3d12.c b/tests/d3d12.c index 70f73b79..a393401c 100644 --- a/tests/d3d12.c +++ b/tests/d3d12.c @@ -8598,15 +8598,16 @@ static void test_shader_instructions(void)
void main(out uint4 dst : SV_Target) { - dst = src << 2; + dst = src << uint4(2, 2, 0x22, 0x22); } #endif - 0x43425844, 0x5b749bf4, 0xe24de3dc, 0xbbd75bc9, 0xc6fc9eca, 0x00000001, 0x000000c0, 0x00000003, + 0x43425844, 0x999070b8, 0x623414f1, 0xb1ce04f4, 0x58554022, 0x00000001, 0x000000d0, 0x00000003, 0x0000002c, 0x0000003c, 0x00000070, 0x4e475349, 0x00000008, 0x00000000, 0x00000008, 0x4e47534f, 0x0000002c, 0x00000001, 0x00000008, 0x00000020, 0x00000000, 0x00000000, 0x00000001, 0x00000000, - 0x0000000f, 0x545f5653, 0x65677261, 0xabab0074, 0x52444853, 0x00000048, 0x00000040, 0x00000012, - 0x04000059, 0x00208e46, 0x00000000, 0x00000001, 0x03000065, 0x001020f2, 0x00000000, 0x08000029, - 0x001020f2, 0x00000000, 0x00208e46, 0x00000000, 0x00000000, 0x00004001, 0x00000002, 0x0100003e, + 0x0000000f, 0x545f5653, 0x65677261, 0xabab0074, 0x58454853, 0x00000058, 0x00000050, 0x00000016, + 0x0100086a, 0x04000059, 0x00208e46, 0x00000000, 0x00000001, 0x03000065, 0x001020f2, 0x00000000, + 0x0b000029, 0x001020f2, 0x00000000, 0x00208e46, 0x00000000, 0x00000000, 0x00004002, 0x00000002, + 0x00000002, 0x00000022, 0x00000022, 0x0100003e, }; static struct named_shader ps_ishl_const = {"ishl_const", ps_ishl_const_code, sizeof(ps_ishl_const_code)}; static const DWORD ps_not_code[] = @@ -9927,6 +9928,8 @@ static void test_shader_instructions(void) {{0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff}}}, {&ps_ishl, {{{0xfefefefe, 0x0fefefef, 0x0f0f0f0f, 0x12345678}, {~0x1fu, 0, 32, 64}}}, {{0xfefefefe, 0x0fefefef, 0x0f0f0f0f, 0x12345678}}}, + {&ps_ishl, {{{0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff}, { 33, 34, 65, 66}}}, + {{0xfffffffe, 0xfffffffc, 0xfffffffe, 0xfffffffc}}}, {&ps_ishl, {{{0x00000000, 0x00000000, 0x00000000, 0x00000000}, { 31, 7, 15, 11}}}, {{0x00000000, 0x00000000, 0x00000000, 0x00000000}}}, {&ps_ishl, {{{0x80000000, 0x80000000, 0x80000000, 0x80000000}, { 31, 7, 15, 11}}},
This is undefined behaviour in SPIR-V, but well-defined in DXBC, so we should explicitly 'and' the shift amount with 31.
Based on a vkd3d-proton patch by Philip Rebohle.
Signed-off-by: Conor McCarthy cmccarthy@codeweavers.com --- v2: Do not skip the operation for immediate constants. --- libs/vkd3d-shader/spirv.c | 12 ++++++++++++ 1 file changed, 12 insertions(+)
diff --git a/libs/vkd3d-shader/spirv.c b/libs/vkd3d-shader/spirv.c index fab92059..23668216 100644 --- a/libs/vkd3d-shader/spirv.c +++ b/libs/vkd3d-shader/spirv.c @@ -6846,6 +6846,18 @@ static void vkd3d_dxbc_compiler_emit_alu_instruction(struct vkd3d_dxbc_compiler for (i = 0; i < instruction->src_count; ++i) src_ids[i] = vkd3d_dxbc_compiler_emit_load_src(compiler, &src[i], dst->write_mask);
+ /* The SPIR-V specification states, "The resulting value is undefined if Shift is greater than or + * equal to the bit width of the components of Base." D3D applies only the lowest 5 bits of the shift. + * Microsoft fxc will compile immediate constants larger than 5 bits. Fixing up the constants would be + * more elegant, but the simplest way is to let this handle constants too. */ + if (instruction->handler_idx == VKD3DSIH_ISHL || instruction->handler_idx == VKD3DSIH_ISHR + || instruction->handler_idx == VKD3DSIH_USHR) + { + uint32_t mask_id = vkd3d_dxbc_compiler_get_constant_vector(compiler, VKD3D_SHADER_COMPONENT_UINT, + vkd3d_write_mask_component_count(dst->write_mask), 0x1f); + src_ids[1] = vkd3d_spirv_build_op_and(builder, type_id, src_ids[1], mask_id); + } + val_id = vkd3d_spirv_build_op_trv(builder, &builder->function_stream, op, type_id, src_ids, instruction->src_count); if (instruction->flags & VKD3DSI_PRECISE_XYZW)