mirror of
https://gitlab.winehq.org/wine/vkd3d.git
synced 2025-04-13 05:43:18 -07:00
vkd3d-shader/dxil: Pass the code block and instruction in a struct to intrinsic handlers.
Simplifies handling of intrinsics which need to emit more than one instruction.
This commit is contained in:
committed by
Alexandre Julliard
parent
14da4df99e
commit
80d7ea2924
Notes:
Alexandre Julliard
2024-01-22 22:52:15 +01:00
Approved-by: Giovanni Mascellani (@giomasce) Approved-by: Henri Verbeet (@hverbeet) Approved-by: Alexandre Julliard (@julliard) Merge-Request: https://gitlab.winehq.org/wine/vkd3d/-/merge_requests/533
@ -3113,6 +3113,12 @@ static struct sm6_phi *sm6_block_phi_require_space(struct sm6_block *block, stru
|
|||||||
return phi;
|
return phi;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct function_emission_state
|
||||||
|
{
|
||||||
|
struct sm6_block *code_block;
|
||||||
|
struct vkd3d_shader_instruction *ins;
|
||||||
|
};
|
||||||
|
|
||||||
static void sm6_parser_emit_alloca(struct sm6_parser *sm6, const struct dxil_record *record,
|
static void sm6_parser_emit_alloca(struct sm6_parser *sm6, const struct dxil_record *record,
|
||||||
struct vkd3d_shader_instruction *ins, struct sm6_value *dst)
|
struct vkd3d_shader_instruction *ins, struct sm6_value *dst)
|
||||||
{
|
{
|
||||||
@ -3479,9 +3485,10 @@ static enum vkd3d_shader_opcode map_dx_unary_op(enum dx_intrinsic_opcode op)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void sm6_parser_emit_dx_unary(struct sm6_parser *sm6, struct sm6_block *code_block,
|
static void sm6_parser_emit_dx_unary(struct sm6_parser *sm6, enum dx_intrinsic_opcode op,
|
||||||
enum dx_intrinsic_opcode op, const struct sm6_value **operands, struct vkd3d_shader_instruction *ins)
|
const struct sm6_value **operands, struct function_emission_state *state)
|
||||||
{
|
{
|
||||||
|
struct vkd3d_shader_instruction *ins = state->ins;
|
||||||
struct vkd3d_shader_src_param *src_param;
|
struct vkd3d_shader_src_param *src_param;
|
||||||
|
|
||||||
vsir_instruction_init(ins, &sm6->p.location, map_dx_unary_op(op));
|
vsir_instruction_init(ins, &sm6->p.location, map_dx_unary_op(op));
|
||||||
@ -3491,10 +3498,11 @@ static void sm6_parser_emit_dx_unary(struct sm6_parser *sm6, struct sm6_block *c
|
|||||||
instruction_dst_param_init_ssa_scalar(ins, sm6);
|
instruction_dst_param_init_ssa_scalar(ins, sm6);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void sm6_parser_emit_dx_cbuffer_load(struct sm6_parser *sm6, struct sm6_block *code_block,
|
static void sm6_parser_emit_dx_cbuffer_load(struct sm6_parser *sm6, enum dx_intrinsic_opcode op,
|
||||||
enum dx_intrinsic_opcode op, const struct sm6_value **operands, struct vkd3d_shader_instruction *ins)
|
const struct sm6_value **operands, struct function_emission_state *state)
|
||||||
{
|
{
|
||||||
struct sm6_value *dst = sm6_parser_get_current_value(sm6);
|
struct sm6_value *dst = sm6_parser_get_current_value(sm6);
|
||||||
|
struct vkd3d_shader_instruction *ins = state->ins;
|
||||||
struct vkd3d_shader_src_param *src_param;
|
struct vkd3d_shader_src_param *src_param;
|
||||||
const struct sm6_value *buffer;
|
const struct sm6_value *buffer;
|
||||||
const struct sm6_type *type;
|
const struct sm6_type *type;
|
||||||
@ -3542,9 +3550,10 @@ static const struct sm6_descriptor_info *sm6_parser_get_descriptor(struct sm6_pa
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void sm6_parser_emit_dx_create_handle(struct sm6_parser *sm6, struct sm6_block *code_block,
|
static void sm6_parser_emit_dx_create_handle(struct sm6_parser *sm6, enum dx_intrinsic_opcode op,
|
||||||
enum dx_intrinsic_opcode op, const struct sm6_value **operands, struct vkd3d_shader_instruction *ins)
|
const struct sm6_value **operands, struct function_emission_state *state)
|
||||||
{
|
{
|
||||||
|
struct vkd3d_shader_instruction *ins = state->ins;
|
||||||
enum vkd3d_shader_descriptor_type type;
|
enum vkd3d_shader_descriptor_type type;
|
||||||
const struct sm6_descriptor_info *d;
|
const struct sm6_descriptor_info *d;
|
||||||
struct vkd3d_shader_register *reg;
|
struct vkd3d_shader_register *reg;
|
||||||
@ -3578,9 +3587,10 @@ static void sm6_parser_emit_dx_create_handle(struct sm6_parser *sm6, struct sm6_
|
|||||||
ins->handler_idx = VKD3DSIH_NOP;
|
ins->handler_idx = VKD3DSIH_NOP;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void sm6_parser_emit_dx_load_input(struct sm6_parser *sm6, struct sm6_block *code_block,
|
static void sm6_parser_emit_dx_load_input(struct sm6_parser *sm6, enum dx_intrinsic_opcode op,
|
||||||
enum dx_intrinsic_opcode op, const struct sm6_value **operands, struct vkd3d_shader_instruction *ins)
|
const struct sm6_value **operands, struct function_emission_state *state)
|
||||||
{
|
{
|
||||||
|
struct vkd3d_shader_instruction *ins = state->ins;
|
||||||
struct vkd3d_shader_src_param *src_param;
|
struct vkd3d_shader_src_param *src_param;
|
||||||
const struct shader_signature *signature;
|
const struct shader_signature *signature;
|
||||||
unsigned int row_index, column_index;
|
unsigned int row_index, column_index;
|
||||||
@ -3610,9 +3620,10 @@ static void sm6_parser_emit_dx_load_input(struct sm6_parser *sm6, struct sm6_blo
|
|||||||
instruction_dst_param_init_ssa_scalar(ins, sm6);
|
instruction_dst_param_init_ssa_scalar(ins, sm6);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void sm6_parser_emit_dx_store_output(struct sm6_parser *sm6, struct sm6_block *code_block,
|
static void sm6_parser_emit_dx_store_output(struct sm6_parser *sm6, enum dx_intrinsic_opcode op,
|
||||||
enum dx_intrinsic_opcode op, const struct sm6_value **operands, struct vkd3d_shader_instruction *ins)
|
const struct sm6_value **operands, struct function_emission_state *state)
|
||||||
{
|
{
|
||||||
|
struct vkd3d_shader_instruction *ins = state->ins;
|
||||||
struct vkd3d_shader_src_param *src_param;
|
struct vkd3d_shader_src_param *src_param;
|
||||||
struct vkd3d_shader_dst_param *dst_param;
|
struct vkd3d_shader_dst_param *dst_param;
|
||||||
const struct shader_signature *signature;
|
const struct shader_signature *signature;
|
||||||
@ -3667,8 +3678,8 @@ struct sm6_dx_opcode_info
|
|||||||
{
|
{
|
||||||
const char *ret_type;
|
const char *ret_type;
|
||||||
const char *operand_info;
|
const char *operand_info;
|
||||||
void (*handler)(struct sm6_parser *, struct sm6_block *, enum dx_intrinsic_opcode,
|
void (*handler)(struct sm6_parser *, enum dx_intrinsic_opcode, const struct sm6_value **,
|
||||||
const struct sm6_value **, struct vkd3d_shader_instruction *);
|
struct function_emission_state *);
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -3820,27 +3831,27 @@ static void sm6_parser_emit_unhandled(struct sm6_parser *sm6, struct vkd3d_shade
|
|||||||
/* dst->is_undefined is not set here because it flags only explicitly undefined values. */
|
/* dst->is_undefined is not set here because it flags only explicitly undefined values. */
|
||||||
}
|
}
|
||||||
|
|
||||||
static void sm6_parser_decode_dx_op(struct sm6_parser *sm6, struct sm6_block *code_block, enum dx_intrinsic_opcode op,
|
static void sm6_parser_decode_dx_op(struct sm6_parser *sm6, enum dx_intrinsic_opcode op,
|
||||||
const char *name, const struct sm6_value **operands, unsigned int operand_count,
|
const char *name, const struct sm6_value **operands, unsigned int operand_count,
|
||||||
struct vkd3d_shader_instruction *ins, struct sm6_value *dst)
|
struct function_emission_state *state, struct sm6_value *dst)
|
||||||
{
|
{
|
||||||
if (op >= ARRAY_SIZE(sm6_dx_op_table) || !sm6_dx_op_table[op].operand_info)
|
if (op >= ARRAY_SIZE(sm6_dx_op_table) || !sm6_dx_op_table[op].operand_info)
|
||||||
{
|
{
|
||||||
FIXME("Unhandled dx intrinsic function id %u, '%s'.\n", op, name);
|
FIXME("Unhandled dx intrinsic function id %u, '%s'.\n", op, name);
|
||||||
vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_UNHANDLED_INTRINSIC,
|
vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_UNHANDLED_INTRINSIC,
|
||||||
"Call to intrinsic function %s is unhandled.", name);
|
"Call to intrinsic function %s is unhandled.", name);
|
||||||
sm6_parser_emit_unhandled(sm6, ins, dst);
|
sm6_parser_emit_unhandled(sm6, state->ins, dst);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (sm6_parser_validate_dx_op(sm6, op, name, operands, operand_count, dst))
|
if (sm6_parser_validate_dx_op(sm6, op, name, operands, operand_count, dst))
|
||||||
sm6_dx_op_table[op].handler(sm6, code_block, op, operands, ins);
|
sm6_dx_op_table[op].handler(sm6, op, operands, state);
|
||||||
else
|
else
|
||||||
sm6_parser_emit_unhandled(sm6, ins, dst);
|
sm6_parser_emit_unhandled(sm6, state->ins, dst);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void sm6_parser_emit_call(struct sm6_parser *sm6, const struct dxil_record *record,
|
static void sm6_parser_emit_call(struct sm6_parser *sm6, const struct dxil_record *record,
|
||||||
struct sm6_block *code_block, struct vkd3d_shader_instruction *ins, struct sm6_value *dst)
|
struct function_emission_state *state, struct sm6_value *dst)
|
||||||
{
|
{
|
||||||
const struct sm6_value *operands[DXIL_OP_MAX_OPERANDS];
|
const struct sm6_value *operands[DXIL_OP_MAX_OPERANDS];
|
||||||
const struct sm6_value *fn_value, *op_value;
|
const struct sm6_value *fn_value, *op_value;
|
||||||
@ -3922,8 +3933,8 @@ static void sm6_parser_emit_call(struct sm6_parser *sm6, const struct dxil_recor
|
|||||||
"Expected a constant integer dx intrinsic function id.");
|
"Expected a constant integer dx intrinsic function id.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
sm6_parser_decode_dx_op(sm6, code_block, register_get_uint_value(&op_value->u.reg),
|
sm6_parser_decode_dx_op(sm6, register_get_uint_value(&op_value->u.reg),
|
||||||
fn_value->u.function.name, &operands[1], operand_count - 1, ins, dst);
|
fn_value->u.function.name, &operands[1], operand_count - 1, state, dst);
|
||||||
}
|
}
|
||||||
|
|
||||||
static enum vkd3d_shader_opcode sm6_map_cast_op(uint64_t code, const struct sm6_type *from,
|
static enum vkd3d_shader_opcode sm6_map_cast_op(uint64_t code, const struct sm6_type *from,
|
||||||
@ -5121,8 +5132,11 @@ static enum vkd3d_result sm6_parser_function_init(struct sm6_parser *sm6, const
|
|||||||
is_terminator = true;
|
is_terminator = true;
|
||||||
break;
|
break;
|
||||||
case FUNC_CODE_INST_CALL:
|
case FUNC_CODE_INST_CALL:
|
||||||
sm6_parser_emit_call(sm6, record, code_block, ins, dst);
|
{
|
||||||
|
struct function_emission_state state = {code_block, ins};
|
||||||
|
sm6_parser_emit_call(sm6, record, &state, dst);
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
case FUNC_CODE_INST_CAST:
|
case FUNC_CODE_INST_CAST:
|
||||||
sm6_parser_emit_cast(sm6, record, ins, dst);
|
sm6_parser_emit_cast(sm6, record, ins, dst);
|
||||||
break;
|
break;
|
||||||
|
Reference in New Issue
Block a user