diff --git a/libs/vkd3d-shader/d3d_asm.c b/libs/vkd3d-shader/d3d_asm.c index 4747b2bb..895ffd31 100644 --- a/libs/vkd3d-shader/d3d_asm.c +++ b/libs/vkd3d-shader/d3d_asm.c @@ -254,6 +254,9 @@ static const char * const shader_opcode_names[] = [VKD3DSIH_PHASE ] = "phase", [VKD3DSIH_PHI ] = "phi", [VKD3DSIH_POW ] = "pow", + [VKD3DSIH_QUAD_READ_ACROSS_D ] = "quad_read_across_d", + [VKD3DSIH_QUAD_READ_ACROSS_X ] = "quad_read_across_x", + [VKD3DSIH_QUAD_READ_ACROSS_Y ] = "quad_read_across_y", [VKD3DSIH_RCP ] = "rcp", [VKD3DSIH_REP ] = "rep", [VKD3DSIH_RESINFO ] = "resinfo", diff --git a/libs/vkd3d-shader/dxil.c b/libs/vkd3d-shader/dxil.c index c08654ae..a055f795 100644 --- a/libs/vkd3d-shader/dxil.c +++ b/libs/vkd3d-shader/dxil.c @@ -458,6 +458,7 @@ enum dx_intrinsic_opcode DX_WAVE_ACTIVE_OP = 119, DX_WAVE_ACTIVE_BIT = 120, DX_WAVE_PREFIX_OP = 121, + DX_QUAD_OP = 123, DX_LEGACY_F32TOF16 = 130, DX_LEGACY_F16TOF32 = 131, DX_WAVE_ALL_BIT_COUNT = 135, @@ -576,6 +577,13 @@ enum dxil_wave_op_kind WAVE_OP_MAX = 3, }; +enum dxil_quad_op_kind +{ + QUAD_READ_ACROSS_X = 0, + QUAD_READ_ACROSS_Y = 1, + QUAD_READ_ACROSS_D = 2, +}; + struct sm6_pointer_info { const struct sm6_type *type; @@ -5370,6 +5378,47 @@ static void sm6_parser_emit_dx_primitive_id(struct sm6_parser *sm6, enum dx_intr sm6_parser_emit_dx_input_register_mov(sm6, state->ins, VKD3DSPR_PRIMID, VKD3D_DATA_UINT); } +static enum vkd3d_shader_opcode dx_map_quad_op(enum dxil_quad_op_kind op) +{ + switch (op) + { + case QUAD_READ_ACROSS_X: + return VKD3DSIH_QUAD_READ_ACROSS_X; + case QUAD_READ_ACROSS_Y: + return VKD3DSIH_QUAD_READ_ACROSS_Y; + case QUAD_READ_ACROSS_D: + return VKD3DSIH_QUAD_READ_ACROSS_D; + default: + return VKD3DSIH_INVALID; + } +} + +static void sm6_parser_emit_dx_quad_op(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 vkd3d_shader_opcode opcode; + enum dxil_quad_op_kind quad_op; + + quad_op = sm6_value_get_constant_uint(operands[1]); + if ((opcode = dx_map_quad_op(quad_op)) == VKD3DSIH_INVALID) + { + FIXME("Unhandled quad op kind %u.\n", quad_op); + vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_UNHANDLED_INTRINSIC, + "Quad op kind %u is unhandled.", quad_op); + 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_raw_buffer_load(struct sm6_parser *sm6, enum dx_intrinsic_opcode op, const struct sm6_value **operands, struct function_emission_state *state) { @@ -6229,6 +6278,7 @@ static const struct sm6_dx_opcode_info sm6_dx_op_table[] = [DX_MAKE_DOUBLE ] = {"d", "ii", sm6_parser_emit_dx_make_double}, [DX_OUTPUT_CONTROL_POINT_ID ] = {"i", "", sm6_parser_emit_dx_output_control_point_id}, [DX_PRIMITIVE_ID ] = {"i", "", sm6_parser_emit_dx_primitive_id}, + [DX_QUAD_OP ] = {"n", "Rc", sm6_parser_emit_dx_quad_op}, [DX_RAW_BUFFER_LOAD ] = {"o", "Hii8i", sm6_parser_emit_dx_raw_buffer_load}, [DX_RAW_BUFFER_STORE ] = {"v", "Hiioooocc", sm6_parser_emit_dx_raw_buffer_store}, [DX_ROUND_NE ] = {"g", "R", sm6_parser_emit_dx_unary}, diff --git a/libs/vkd3d-shader/vkd3d_shader_private.h b/libs/vkd3d-shader/vkd3d_shader_private.h index efd3b59a..d3370744 100644 --- a/libs/vkd3d-shader/vkd3d_shader_private.h +++ b/libs/vkd3d-shader/vkd3d_shader_private.h @@ -455,6 +455,9 @@ enum vkd3d_shader_opcode VKD3DSIH_PHASE, VKD3DSIH_PHI, VKD3DSIH_POW, + VKD3DSIH_QUAD_READ_ACROSS_D, + VKD3DSIH_QUAD_READ_ACROSS_X, + VKD3DSIH_QUAD_READ_ACROSS_Y, VKD3DSIH_RCP, VKD3DSIH_REP, VKD3DSIH_RESINFO,