diff --git a/libs/vkd3d-shader/d3d_asm.c b/libs/vkd3d-shader/d3d_asm.c index 0e182506..4961fcf5 100644 --- a/libs/vkd3d-shader/d3d_asm.c +++ b/libs/vkd3d-shader/d3d_asm.c @@ -329,6 +329,9 @@ static const char * const shader_opcode_names[] = [VKD3DSIH_UTOU ] = "utou", [VKD3DSIH_WAVE_ACTIVE_ALL_EQUAL ] = "wave_active_all_equal", [VKD3DSIH_WAVE_ACTIVE_BALLOT ] = "wave_active_ballot", + [VKD3DSIH_WAVE_ACTIVE_BIT_AND ] = "wave_active_bit_and", + [VKD3DSIH_WAVE_ACTIVE_BIT_OR ] = "wave_active_bit_or", + [VKD3DSIH_WAVE_ACTIVE_BIT_XOR ] = "wave_active_bit_xor", [VKD3DSIH_WAVE_ALL_TRUE ] = "wave_all_true", [VKD3DSIH_WAVE_ANY_TRUE ] = "wave_any_true", [VKD3DSIH_XOR ] = "xor", diff --git a/libs/vkd3d-shader/dxil.c b/libs/vkd3d-shader/dxil.c index 048281ee..622c1ee8 100644 --- a/libs/vkd3d-shader/dxil.c +++ b/libs/vkd3d-shader/dxil.c @@ -433,6 +433,7 @@ enum dx_intrinsic_opcode DX_WAVE_ALL_TRUE = 114, DX_WAVE_ACTIVE_ALL_EQUAL = 115, DX_WAVE_ACTIVE_BALLOT = 116, + DX_WAVE_ACTIVE_BIT = 120, DX_LEGACY_F32TOF16 = 130, DX_LEGACY_F16TOF32 = 131, DX_RAW_BUFFER_LOAD = 139, @@ -534,6 +535,13 @@ enum dxil_sync_flags SYNC_GROUP_SHARED_MEMORY = 0x8, }; +enum dxil_wave_bit_op_kind +{ + WAVE_BIT_OP_AND = 0, + WAVE_BIT_OP_OR = 1, + WAVE_BIT_OP_XOR = 2, +}; + struct sm6_pointer_info { const struct sm6_type *type; @@ -5925,6 +5933,46 @@ static void sm6_parser_emit_dx_wave_active_ballot(struct sm6_parser *sm6, enum d instruction_dst_param_init_ssa_vector(ins, VKD3D_VEC4_SIZE, sm6); } +static enum vkd3d_shader_opcode sm6_dx_map_wave_bit_op(enum dxil_wave_bit_op_kind op, + struct sm6_parser *sm6) +{ + switch (op) + { + case WAVE_BIT_OP_AND: + return VKD3DSIH_WAVE_ACTIVE_BIT_AND; + case WAVE_BIT_OP_OR: + return VKD3DSIH_WAVE_ACTIVE_BIT_OR; + case WAVE_BIT_OP_XOR: + return VKD3DSIH_WAVE_ACTIVE_BIT_XOR; + default: + FIXME("Unhandled wave bit op %u.\n", op); + vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_UNHANDLED_INTRINSIC, + "Wave bit operation %u is unhandled.\n", op); + return VKD3DSIH_INVALID; + } +} + +static void sm6_parser_emit_dx_wave_active_bit(struct sm6_parser *sm6, enum dx_intrinsic_opcode op, + const struct sm6_value **operands, struct function_emission_state *state) +{ + struct vkd3d_shader_instruction *ins = state->ins; + struct vkd3d_shader_src_param *src_param; + enum dxil_wave_bit_op_kind wave_op; + enum vkd3d_shader_opcode opcode; + + wave_op = sm6_value_get_constant_uint(operands[1]); + + if ((opcode = sm6_dx_map_wave_bit_op(wave_op, sm6)) == VKD3DSIH_INVALID) + return; + vsir_instruction_init(ins, &sm6->p.location, opcode); + + if (!(src_param = instruction_src_params_alloc(ins, 1, sm6))) + return; + src_param_init_from_value(src_param, operands[0]); + + instruction_dst_param_init_ssa_scalar(ins, sm6); +} + static void sm6_parser_emit_dx_wave_builtin(struct sm6_parser *sm6, enum dx_intrinsic_opcode op, const struct sm6_value **operands, struct function_emission_state *state) { @@ -6068,6 +6116,7 @@ static const struct sm6_dx_opcode_info sm6_dx_op_table[] = [DX_UMIN ] = {"m", "RR", sm6_parser_emit_dx_binary}, [DX_WAVE_ACTIVE_ALL_EQUAL ] = {"1", "n", sm6_parser_emit_dx_unary}, [DX_WAVE_ACTIVE_BALLOT ] = {"V", "1", sm6_parser_emit_dx_wave_active_ballot}, + [DX_WAVE_ACTIVE_BIT ] = {"m", "Rc", sm6_parser_emit_dx_wave_active_bit}, [DX_WAVE_ALL_TRUE ] = {"1", "1", sm6_parser_emit_dx_unary}, [DX_WAVE_ANY_TRUE ] = {"1", "1", sm6_parser_emit_dx_unary}, [DX_WAVE_GET_LANE_COUNT ] = {"i", "", sm6_parser_emit_dx_wave_builtin}, diff --git a/libs/vkd3d-shader/vkd3d_shader_private.h b/libs/vkd3d-shader/vkd3d_shader_private.h index 14d27c11..7747a422 100644 --- a/libs/vkd3d-shader/vkd3d_shader_private.h +++ b/libs/vkd3d-shader/vkd3d_shader_private.h @@ -529,6 +529,9 @@ enum vkd3d_shader_opcode VKD3DSIH_UTOU, VKD3DSIH_WAVE_ACTIVE_ALL_EQUAL, VKD3DSIH_WAVE_ACTIVE_BALLOT, + VKD3DSIH_WAVE_ACTIVE_BIT_AND, + VKD3DSIH_WAVE_ACTIVE_BIT_OR, + VKD3DSIH_WAVE_ACTIVE_BIT_XOR, VKD3DSIH_WAVE_ALL_TRUE, VKD3DSIH_WAVE_ANY_TRUE, VKD3DSIH_XOR,