diff --git a/libs/vkd3d-shader/dxbc.c b/libs/vkd3d-shader/dxbc.c index b81ac976..e57cc413 100644 --- a/libs/vkd3d-shader/dxbc.c +++ b/libs/vkd3d-shader/dxbc.c @@ -310,6 +310,7 @@ enum vkd3d_sm4_opcode VKD3D_SM5_OP_IMM_ATOMIC_UMAX = 0xbc, VKD3D_SM5_OP_IMM_ATOMIC_UMIN = 0xbd, VKD3D_SM5_OP_SYNC = 0xbe, + VKD3D_SM5_OP_DEQ = 0xc3, VKD3D_SM5_OP_EVAL_SAMPLE_INDEX = 0xcc, VKD3D_SM5_OP_EVAL_CENTROID = 0xcd, VKD3D_SM5_OP_DCL_GS_INSTANCES = 0xce, @@ -1011,6 +1012,7 @@ static void shader_sm5_read_sync(struct vkd3d_shader_instruction *ins, } /* + * d -> VKD3D_DATA_DOUBLE * f -> VKD3D_DATA_FLOAT * i -> VKD3D_DATA_INT * u -> VKD3D_DATA_UINT @@ -1247,6 +1249,7 @@ static const struct vkd3d_sm4_opcode_info opcode_table[] = {VKD3D_SM5_OP_IMM_ATOMIC_UMIN, VKD3DSIH_IMM_ATOMIC_UMIN, "uU", "iu"}, {VKD3D_SM5_OP_SYNC, VKD3DSIH_SYNC, "", "", shader_sm5_read_sync}, + {VKD3D_SM5_OP_DEQ, VKD3DSIH_DEQ, "u", "dd"}, {VKD3D_SM5_OP_EVAL_SAMPLE_INDEX, VKD3DSIH_EVAL_SAMPLE_INDEX, "f", "fi"}, {VKD3D_SM5_OP_EVAL_CENTROID, VKD3DSIH_EVAL_CENTROID, "f", "f"}, {VKD3D_SM5_OP_DCL_GS_INSTANCES, VKD3DSIH_DCL_GS_INSTANCES, "", "", @@ -1338,6 +1341,8 @@ static enum vkd3d_data_type map_data_type(char t) { switch (t) { + case 'd': + return VKD3D_DATA_DOUBLE; case 'f': return VKD3D_DATA_FLOAT; case 'i': diff --git a/libs/vkd3d-shader/spirv.c b/libs/vkd3d-shader/spirv.c index 65834696..33e664cf 100644 --- a/libs/vkd3d-shader/spirv.c +++ b/libs/vkd3d-shader/spirv.c @@ -3308,6 +3308,7 @@ static uint32_t vkd3d_dxbc_compiler_emit_load_reg(struct vkd3d_dxbc_compiler *co enum vkd3d_shader_component_type component_type; struct vkd3d_shader_register_info reg_info; unsigned int component_count; + unsigned int write_mask32; uint32_t type_id, val_id; if (reg->type == VKD3DSPR_IMMCONST) @@ -3320,14 +3321,17 @@ static uint32_t vkd3d_dxbc_compiler_emit_load_reg(struct vkd3d_dxbc_compiler *co type_id = vkd3d_spirv_get_type_id(builder, component_type, component_count); return vkd3d_spirv_build_op_undef(builder, &builder->global_stream, type_id); } + assert(reg_info.component_type != VKD3D_SHADER_COMPONENT_DOUBLE); vkd3d_dxbc_compiler_emit_dereference_register(compiler, reg, ®_info); + write_mask32 = (reg->data_type == VKD3D_DATA_DOUBLE) ? vkd3d_write_mask_32_from_64(write_mask) : write_mask; + /* Intermediate value (no storage class). */ if (reg_info.storage_class == SpvStorageClassMax) { val_id = reg_info.id; } - else if (component_count == 1) + else if (vkd3d_write_mask_component_count(write_mask32) == 1) { return vkd3d_dxbc_compiler_emit_load_scalar(compiler, reg, swizzle, write_mask, ®_info); } @@ -3339,7 +3343,7 @@ static uint32_t vkd3d_dxbc_compiler_emit_load_reg(struct vkd3d_dxbc_compiler *co } val_id = vkd3d_dxbc_compiler_emit_swizzle(compiler, - val_id, reg_info.write_mask, reg_info.component_type, swizzle, write_mask); + val_id, reg_info.write_mask, reg_info.component_type, swizzle, write_mask32); if (component_type != reg_info.component_type) { @@ -7066,6 +7070,7 @@ static void vkd3d_dxbc_compiler_emit_comparison_instruction(struct vkd3d_dxbc_co switch (instruction->handler_idx) { + case VKD3DSIH_DEQ: case VKD3DSIH_EQ: op = SpvOpFOrdEqual; break; case VKD3DSIH_GE: op = SpvOpFOrdGreaterThanEqual; break; case VKD3DSIH_IEQ: op = SpvOpIEqual; break; @@ -9249,6 +9254,7 @@ int vkd3d_dxbc_compiler_handle_instruction(struct vkd3d_dxbc_compiler *compiler, case VKD3DSIH_UDIV: vkd3d_dxbc_compiler_emit_udiv(compiler, instruction); break; + case VKD3DSIH_DEQ: case VKD3DSIH_EQ: case VKD3DSIH_GE: case VKD3DSIH_IEQ: diff --git a/libs/vkd3d-shader/trace.c b/libs/vkd3d-shader/trace.c index c21cb3e2..556654ec 100644 --- a/libs/vkd3d-shader/trace.c +++ b/libs/vkd3d-shader/trace.c @@ -103,6 +103,7 @@ static const char * const shader_opcode_names[] = /* VKD3DSIH_DEFAULT */ "default", /* VKD3DSIH_DEFB */ "defb", /* VKD3DSIH_DEFI */ "defi", + /* VKD3DSIH_DEQ */ "deq", /* VKD3DSIH_DIV */ "div", /* VKD3DSIH_DP2 */ "dp2", /* VKD3DSIH_DP2ADD */ "dp2add", diff --git a/libs/vkd3d-shader/vkd3d_shader_private.h b/libs/vkd3d-shader/vkd3d_shader_private.h index 033d8f07..f5d22c5c 100644 --- a/libs/vkd3d-shader/vkd3d_shader_private.h +++ b/libs/vkd3d-shader/vkd3d_shader_private.h @@ -190,6 +190,7 @@ enum vkd3d_shader_opcode VKD3DSIH_DEFAULT, VKD3DSIH_DEFB, VKD3DSIH_DEFI, + VKD3DSIH_DEQ, VKD3DSIH_DIV, VKD3DSIH_DP2, VKD3DSIH_DP2ADD, @@ -1032,6 +1033,13 @@ static inline unsigned int vkd3d_write_mask_from_component_count(unsigned int co return (VKD3DSP_WRITEMASK_0 << component_count) - 1; } +static inline unsigned int vkd3d_write_mask_32_from_64(unsigned int write_mask64) +{ + unsigned int write_mask32 = (write_mask64 | (write_mask64 << 1)) + & (VKD3DSP_WRITEMASK_0 | VKD3DSP_WRITEMASK_2); + return write_mask32 | (write_mask32 << 1); +} + static inline unsigned int vkd3d_swizzle_get_component(DWORD swizzle, unsigned int idx) { diff --git a/tests/d3d12.c b/tests/d3d12.c index 04c1e2c8..f14114d1 100644 --- a/tests/d3d12.c +++ b/tests/d3d12.c @@ -9879,8 +9879,8 @@ static void test_shader_instructions(void) {&ps_dmovc, {.d = {{1.5, 0.0}}}, {.d = {1.5, 0.0}}, true, true}, {&ps_dmodifier, {.d = {{1.5, 0.0}}}, {.d = {1.5f, 2.5f}}, true, true}, {&ps_dmodifier, {.d = {{-1.5, 0.0}}}, {.d = {1.5f, 1.5f}}, true, true}, - {&ps_deq, {.d = {{0.0, 0.0}}}, {{0xffffffff}}, true, true}, - {&ps_deq, {.d = {{1.0, 0.0}}}, {{0x00000000}}, true, true}, + {&ps_deq, {.d = {{0.0, 0.0}}}, {{0xffffffff}}, true}, + {&ps_deq, {.d = {{1.0, 0.0}}}, {{0x00000000}}, true}, {&ps_dne, {.d = {{0.0, 0.0}}}, {{0x00000000}}, true, true}, {&ps_dne, {.d = {{1.0, 0.0}}}, {{0xffffffff}}, true, true}, {&ps_dtou, {.d = {{ -NAN}}}, {{ 0, 0 }}, true, true},