From: Conor McCarthy cmccarthy@codeweavers.com
--- libs/vkd3d-shader/dxil.c | 18 +++++++++++++----- tests/hlsl/uav-atomics.shader_test | 8 ++++---- 2 files changed, 17 insertions(+), 9 deletions(-)
diff --git a/libs/vkd3d-shader/dxil.c b/libs/vkd3d-shader/dxil.c index dae2be791..ab6eed76d 100644 --- a/libs/vkd3d-shader/dxil.c +++ b/libs/vkd3d-shader/dxil.c @@ -373,6 +373,7 @@ enum dx_intrinsic_opcode DX_TEXTURE_STORE = 67, DX_BUFFER_LOAD = 68, DX_ATOMIC_BINOP = 78, + DX_ATOMIC_CMP_XCHG = 79, DX_DERIV_COARSEX = 83, DX_DERIV_COARSEY = 84, DX_DERIV_FINEX = 85, @@ -3869,21 +3870,25 @@ static void sm6_parser_emit_dx_atomic_binop(struct sm6_parser *sm6, enum dx_intr const struct sm6_value **operands, struct function_emission_state *state) { struct sm6_value *dst = sm6_parser_get_current_value(sm6); + bool is_cmp_xchg = op == DX_ATOMIC_CMP_XCHG; struct vkd3d_shader_dst_param *dst_params; struct vkd3d_shader_src_param *src_params; enum vkd3d_shader_opcode handler_idx; struct vkd3d_shader_instruction *ins; const struct sm6_value *resource; struct vkd3d_shader_register reg; - const unsigned int coord_idx = 2; + unsigned int coord_idx;
resource = operands[0]; if (!sm6_value_validate_is_handle(resource, sm6)) return;
- if ((handler_idx = map_dx_atomic_binop(operands[1], sm6)) == VKD3DSIH_INVALID) + if (is_cmp_xchg) + handler_idx = VKD3DSIH_IMM_ATOMIC_CMP_EXCH; + else if ((handler_idx = map_dx_atomic_binop(operands[1], sm6)) == VKD3DSIH_INVALID) return;
+ coord_idx = 2 - is_cmp_xchg; reg.type = VKD3DSPR_INVALID; if (resource->u.handle.d->resource_type != VKD3D_SHADER_RESOURCE_BUFFER) { @@ -3898,7 +3903,7 @@ static void sm6_parser_emit_dx_atomic_binop(struct sm6_parser *sm6, enum dx_intr
ins = state->ins; vsir_instruction_init(ins, &sm6->p.location, handler_idx); - src_params = instruction_src_params_alloc(ins, 2, sm6); + src_params = instruction_src_params_alloc(ins, 2 + is_cmp_xchg, sm6); if (reg.type != VKD3DSPR_INVALID) { src_param_init_vector_from_reg(&src_params[0], ®); @@ -3906,14 +3911,16 @@ static void sm6_parser_emit_dx_atomic_binop(struct sm6_parser *sm6, enum dx_intr else { src_param_init_from_value(&src_params[0], operands[coord_idx]); - if (!operands[3]->is_undefined || !operands[4]->is_undefined) + if (!operands[3]->is_undefined || (!is_cmp_xchg && !operands[4]->is_undefined)) { WARN("Ignoring unexpected operand.\n"); vkd3d_shader_parser_warning(&sm6->p, VKD3D_SHADER_WARNING_DXIL_IGNORING_OPERANDS, "Ignoring an unexpected defined operand value for atomic instruction %u.", handler_idx); } } - src_param_init_from_value(&src_params[1], operands[5]); + if (is_cmp_xchg) + src_param_init_from_value(&src_params[1], operands[4]); + src_param_init_from_value(&src_params[1 + is_cmp_xchg], operands[5]);
dst_params = instruction_dst_params_alloc(ins, 2, sm6); dst_param_init(&dst_params[0]); @@ -4387,6 +4394,7 @@ static const struct sm6_dx_opcode_info sm6_dx_op_table[] = [DX_ASIN ] = {"g", "R", sm6_parser_emit_dx_unary}, [DX_ATAN ] = {"g", "R", sm6_parser_emit_dx_unary}, [DX_ATOMIC_BINOP ] = {"o", "HciiiR", sm6_parser_emit_dx_atomic_binop}, + [DX_ATOMIC_CMP_XCHG ] = {"o", "HiiiRR", sm6_parser_emit_dx_atomic_binop}, [DX_BFREV ] = {"m", "R", sm6_parser_emit_dx_unary}, [DX_BUFFER_LOAD ] = {"o", "Hii", sm6_parser_emit_dx_buffer_load}, [DX_CBUFFER_LOAD_LEGACY ] = {"o", "Hi", sm6_parser_emit_dx_cbuffer_load}, diff --git a/tests/hlsl/uav-atomics.shader_test b/tests/hlsl/uav-atomics.shader_test index a68420d40..aed1da6ce 100644 --- a/tests/hlsl/uav-atomics.shader_test +++ b/tests/hlsl/uav-atomics.shader_test @@ -26,7 +26,7 @@ void main()
[test] uniform 0 uint4 3 5 0 0 -todo dispatch 1 1 1 +todo(sm<6) dispatch 1 1 1 probe buffer uav 1 (0, 0) rui (1) probe buffer uav 1 (1, 0) rui (3) probe buffer uav 1 (2, 0) rui (15) @@ -36,7 +36,7 @@ probe buffer uav 1 (5, 0) rui (3) probe buffer uav 1 (6, 0) rui (4)
uniform 0 uint4 1 2 0 0 -todo dispatch 2 1 1 +todo(sm<6) dispatch 2 1 1 probe buffer uav 1 (0, 0) rui (1) probe buffer uav 1 (1, 0) rui (3) probe buffer uav 1 (2, 0) rui (21) @@ -66,11 +66,11 @@ void main()
[test] uniform 0 int4 1 -3 0 0 -todo dispatch 1 1 1 +todo(sm<6) dispatch 1 1 1 probe buffer uav 2 (0, 0) ri (1) probe buffer uav 2 (1, 0) ri (-3)
uniform 0 int4 -3 1 0 0 -todo dispatch 1 1 1 +todo(sm<6) dispatch 1 1 1 probe buffer uav 2 (0, 0) ri (1) probe buffer uav 2 (1, 0) ri (-3)