From e48d811509a661939136b1567d165fc400a38784 Mon Sep 17 00:00:00 2001 From: Alistair Leslie-Hughes Date: Fri, 6 Sep 2024 08:13:50 +1000 Subject: [PATCH] Updated vkd3d to bfd1fc9cd6cf9cf4e9c23b4ffad2ba8a3282c1f9. --- libs/vkd3d/libs/vkd3d-shader/d3dbc.c | 98 +++++++++++----------- libs/vkd3d/libs/vkd3d-shader/ir.c | 121 ++++++++++++++++----------- 2 files changed, 121 insertions(+), 98 deletions(-) diff --git a/libs/vkd3d/libs/vkd3d-shader/d3dbc.c b/libs/vkd3d/libs/vkd3d-shader/d3dbc.c index 3b9ec98448d..de5f28c1815 100644 --- a/libs/vkd3d/libs/vkd3d-shader/d3dbc.c +++ b/libs/vkd3d/libs/vkd3d-shader/d3dbc.c @@ -1862,7 +1862,7 @@ void write_sm1_uniforms(struct hlsl_ctx *ctx, struct vkd3d_bytecode_buffer *buff set_u32(buffer, creator_offset, offset - ctab_start); ctab_end = bytecode_align(buffer); - set_u32(buffer, size_offset, vkd3d_make_u32(D3DSIO_COMMENT, (ctab_end - ctab_offset) / sizeof(uint32_t))); + set_u32(buffer, size_offset, vkd3d_make_u32(VKD3D_SM1_OP_COMMENT, (ctab_end - ctab_offset) / sizeof(uint32_t))); } static uint32_t sm1_encode_register_type(enum vkd3d_shader_register_type type) @@ -1873,7 +1873,7 @@ static uint32_t sm1_encode_register_type(enum vkd3d_shader_register_type type) struct sm1_instruction { - D3DSHADER_INSTRUCTION_OPCODE_TYPE opcode; + enum vkd3d_sm1_opcode opcode; unsigned int flags; struct sm1_dst_register @@ -1902,7 +1902,7 @@ static bool is_inconsequential_instr(const struct sm1_instruction *instr) const struct sm1_dst_register *dst = &instr->dst; unsigned int i; - if (instr->opcode != D3DSIO_MOV) + if (instr->opcode != VKD3D_SM1_OP_MOV) return false; if (dst->mod != D3DSPDM_NONE) return false; @@ -1947,7 +1947,7 @@ static void d3dbc_write_instruction(struct d3dbc_compiler *d3dbc, const struct s token |= VKD3D_SM1_INSTRUCTION_FLAGS_MASK & (instr->flags << VKD3D_SM1_INSTRUCTION_FLAGS_SHIFT); if (version->major > 1) - token |= (instr->has_dst + instr->src_count) << D3DSI_INSTLENGTH_SHIFT; + token |= (instr->has_dst + instr->src_count) << VKD3D_SM1_INSTRUCTION_LENGTH_SHIFT; put_u32(buffer, token); if (instr->has_dst) @@ -1967,7 +1967,7 @@ static void d3dbc_write_dp2add(struct d3dbc_compiler *d3dbc, const struct hlsl_r { struct sm1_instruction instr = { - .opcode = D3DSIO_DP2ADD, + .opcode = VKD3D_SM1_OP_DP2ADD, .dst.type = VKD3DSPR_TEMP, .dst.writemask = dst->writemask, @@ -1989,9 +1989,9 @@ static void d3dbc_write_dp2add(struct d3dbc_compiler *d3dbc, const struct hlsl_r d3dbc_write_instruction(d3dbc, &instr); } -static void d3dbc_write_ternary_op(struct d3dbc_compiler *d3dbc, - D3DSHADER_INSTRUCTION_OPCODE_TYPE opcode, const struct hlsl_reg *dst, - const struct hlsl_reg *src1, const struct hlsl_reg *src2, const struct hlsl_reg *src3) +static void d3dbc_write_ternary_op(struct d3dbc_compiler *d3dbc, enum vkd3d_sm1_opcode opcode, + const struct hlsl_reg *dst, const struct hlsl_reg *src1, + const struct hlsl_reg *src2, const struct hlsl_reg *src3) { struct sm1_instruction instr = { @@ -2020,7 +2020,7 @@ static void d3dbc_write_ternary_op(struct d3dbc_compiler *d3dbc, d3dbc_write_instruction(d3dbc, &instr); } -static void d3dbc_write_binary_op(struct d3dbc_compiler *d3dbc, D3DSHADER_INSTRUCTION_OPCODE_TYPE opcode, +static void d3dbc_write_binary_op(struct d3dbc_compiler *d3dbc, enum vkd3d_sm1_opcode opcode, const struct hlsl_reg *dst, const struct hlsl_reg *src1, const struct hlsl_reg *src2) { struct sm1_instruction instr = @@ -2046,7 +2046,7 @@ static void d3dbc_write_binary_op(struct d3dbc_compiler *d3dbc, D3DSHADER_INSTRU d3dbc_write_instruction(d3dbc, &instr); } -static void d3dbc_write_dot(struct d3dbc_compiler *d3dbc, D3DSHADER_INSTRUCTION_OPCODE_TYPE opcode, +static void d3dbc_write_dot(struct d3dbc_compiler *d3dbc, enum vkd3d_sm1_opcode opcode, const struct hlsl_reg *dst, const struct hlsl_reg *src1, const struct hlsl_reg *src2) { struct sm1_instruction instr = @@ -2070,7 +2070,7 @@ static void d3dbc_write_dot(struct d3dbc_compiler *d3dbc, D3DSHADER_INSTRUCTION_ d3dbc_write_instruction(d3dbc, &instr); } -static void d3dbc_write_unary_op(struct d3dbc_compiler *d3dbc, D3DSHADER_INSTRUCTION_OPCODE_TYPE opcode, +static void d3dbc_write_unary_op(struct d3dbc_compiler *d3dbc, enum vkd3d_sm1_opcode opcode, const struct hlsl_reg *dst, const struct hlsl_reg *src, D3DSHADER_PARAM_SRCMOD_TYPE src_mod, D3DSHADER_PARAM_DSTMOD_TYPE dst_mod) { @@ -2118,7 +2118,7 @@ static void d3dbc_write_cast(struct d3dbc_compiler *d3dbc, const struct hlsl_ir_ /* Integrals are internally represented as floats, so no change is necessary.*/ case HLSL_TYPE_HALF: case HLSL_TYPE_FLOAT: - d3dbc_write_unary_op(d3dbc, D3DSIO_MOV, &instr->reg, &arg1->reg, 0, 0); + d3dbc_write_unary_op(d3dbc, VKD3D_SM1_OP_MOV, &instr->reg, &arg1->reg, 0, 0); break; case HLSL_TYPE_DOUBLE: @@ -2142,7 +2142,7 @@ static void d3dbc_write_cast(struct d3dbc_compiler *d3dbc, const struct hlsl_ir_ break; case HLSL_TYPE_INT: case HLSL_TYPE_UINT: - d3dbc_write_unary_op(d3dbc, D3DSIO_MOV, &instr->reg, &arg1->reg, 0, 0); + d3dbc_write_unary_op(d3dbc, VKD3D_SM1_OP_MOV, &instr->reg, &arg1->reg, 0, 0); break; case HLSL_TYPE_BOOL: @@ -2353,7 +2353,7 @@ static void d3dbc_write_vsir_simple_instruction(struct d3dbc_compiler *d3dbc, return; } - instr.opcode = (D3DSHADER_INSTRUCTION_OPCODE_TYPE)info->sm1_opcode; + instr.opcode = info->sm1_opcode; instr.has_dst = info->dst_count; instr.src_count = info->src_count; @@ -2413,9 +2413,9 @@ static void d3dbc_write_semantic_dcl(struct d3dbc_compiler *d3dbc, reg.reg = element->register_index; } - token = D3DSIO_DCL; + token = VKD3D_SM1_OP_DCL; if (version->major > 1) - token |= 2 << D3DSI_INSTLENGTH_SHIFT; + token |= 2 << VKD3D_SM1_INSTRUCTION_LENGTH_SHIFT; put_u32(buffer, token); token = (1u << 31); @@ -2455,7 +2455,7 @@ static void d3dbc_write_semantic_dcls(struct d3dbc_compiler *d3dbc) } static void d3dbc_write_per_component_unary_op(struct d3dbc_compiler *d3dbc, - const struct hlsl_ir_node *instr, D3DSHADER_INSTRUCTION_OPCODE_TYPE opcode) + const struct hlsl_ir_node *instr, enum vkd3d_sm1_opcode opcode) { struct hlsl_ir_expr *expr = hlsl_ir_expr(instr); struct hlsl_ir_node *arg1 = expr->operands[0].node; @@ -2476,7 +2476,7 @@ static void d3dbc_write_sincos(struct d3dbc_compiler *d3dbc, enum hlsl_ir_expr_o { struct sm1_instruction instr = { - .opcode = D3DSIO_SINCOS, + .opcode = VKD3D_SM1_OP_SINCOS, .dst.type = VKD3DSPR_TEMP, .dst.writemask = dst->writemask, @@ -2523,7 +2523,7 @@ static void d3dbc_write_expr(struct d3dbc_compiler *d3dbc, const struct hlsl_ir_ if (expr->op == HLSL_OP1_REINTERPRET) { - d3dbc_write_unary_op(d3dbc, D3DSIO_MOV, &instr->reg, &arg1->reg, 0, 0); + d3dbc_write_unary_op(d3dbc, VKD3D_SM1_OP_MOV, &instr->reg, &arg1->reg, 0, 0); return; } @@ -2543,39 +2543,39 @@ static void d3dbc_write_expr(struct d3dbc_compiler *d3dbc, const struct hlsl_ir_ switch (expr->op) { case HLSL_OP1_ABS: - d3dbc_write_unary_op(d3dbc, D3DSIO_ABS, &instr->reg, &arg1->reg, 0, 0); + d3dbc_write_unary_op(d3dbc, VKD3D_SM1_OP_ABS, &instr->reg, &arg1->reg, 0, 0); break; case HLSL_OP1_DSX: - d3dbc_write_unary_op(d3dbc, D3DSIO_DSX, &instr->reg, &arg1->reg, 0, 0); + d3dbc_write_unary_op(d3dbc, VKD3D_SM1_OP_DSX, &instr->reg, &arg1->reg, 0, 0); break; case HLSL_OP1_DSY: - d3dbc_write_unary_op(d3dbc, D3DSIO_DSY, &instr->reg, &arg1->reg, 0, 0); + d3dbc_write_unary_op(d3dbc, VKD3D_SM1_OP_DSY, &instr->reg, &arg1->reg, 0, 0); break; case HLSL_OP1_EXP2: - d3dbc_write_per_component_unary_op(d3dbc, instr, D3DSIO_EXP); + d3dbc_write_per_component_unary_op(d3dbc, instr, VKD3D_SM1_OP_EXP); break; case HLSL_OP1_LOG2: - d3dbc_write_per_component_unary_op(d3dbc, instr, D3DSIO_LOG); + d3dbc_write_per_component_unary_op(d3dbc, instr, VKD3D_SM1_OP_LOG); break; case HLSL_OP1_NEG: - d3dbc_write_unary_op(d3dbc, D3DSIO_MOV, &instr->reg, &arg1->reg, D3DSPSM_NEG, 0); + d3dbc_write_unary_op(d3dbc, VKD3D_SM1_OP_MOV, &instr->reg, &arg1->reg, D3DSPSM_NEG, 0); break; case HLSL_OP1_SAT: - d3dbc_write_unary_op(d3dbc, D3DSIO_MOV, &instr->reg, &arg1->reg, 0, D3DSPDM_SATURATE); + d3dbc_write_unary_op(d3dbc, VKD3D_SM1_OP_MOV, &instr->reg, &arg1->reg, 0, D3DSPDM_SATURATE); break; case HLSL_OP1_RCP: - d3dbc_write_per_component_unary_op(d3dbc, instr, D3DSIO_RCP); + d3dbc_write_per_component_unary_op(d3dbc, instr, VKD3D_SM1_OP_RCP); break; case HLSL_OP1_RSQ: - d3dbc_write_per_component_unary_op(d3dbc, instr, D3DSIO_RSQ); + d3dbc_write_per_component_unary_op(d3dbc, instr, VKD3D_SM1_OP_RSQ); break; case HLSL_OP1_COS_REDUCED: @@ -2584,34 +2584,34 @@ static void d3dbc_write_expr(struct d3dbc_compiler *d3dbc, const struct hlsl_ir_ break; case HLSL_OP2_ADD: - d3dbc_write_binary_op(d3dbc, D3DSIO_ADD, &instr->reg, &arg1->reg, &arg2->reg); + d3dbc_write_binary_op(d3dbc, VKD3D_SM1_OP_ADD, &instr->reg, &arg1->reg, &arg2->reg); break; case HLSL_OP2_MAX: - d3dbc_write_binary_op(d3dbc, D3DSIO_MAX, &instr->reg, &arg1->reg, &arg2->reg); + d3dbc_write_binary_op(d3dbc, VKD3D_SM1_OP_MAX, &instr->reg, &arg1->reg, &arg2->reg); break; case HLSL_OP2_MIN: - d3dbc_write_binary_op(d3dbc, D3DSIO_MIN, &instr->reg, &arg1->reg, &arg2->reg); + d3dbc_write_binary_op(d3dbc, VKD3D_SM1_OP_MIN, &instr->reg, &arg1->reg, &arg2->reg); break; case HLSL_OP2_MUL: - d3dbc_write_binary_op(d3dbc, D3DSIO_MUL, &instr->reg, &arg1->reg, &arg2->reg); + d3dbc_write_binary_op(d3dbc, VKD3D_SM1_OP_MUL, &instr->reg, &arg1->reg, &arg2->reg); break; case HLSL_OP1_FRACT: - d3dbc_write_unary_op(d3dbc, D3DSIO_FRC, &instr->reg, &arg1->reg, D3DSPSM_NONE, 0); + d3dbc_write_unary_op(d3dbc, VKD3D_SM1_OP_FRC, &instr->reg, &arg1->reg, D3DSPSM_NONE, 0); break; case HLSL_OP2_DOT: switch (arg1->data_type->dimx) { case 4: - d3dbc_write_dot(d3dbc, D3DSIO_DP4, &instr->reg, &arg1->reg, &arg2->reg); + d3dbc_write_dot(d3dbc, VKD3D_SM1_OP_DP4, &instr->reg, &arg1->reg, &arg2->reg); break; case 3: - d3dbc_write_dot(d3dbc, D3DSIO_DP3, &instr->reg, &arg1->reg, &arg2->reg); + d3dbc_write_dot(d3dbc, VKD3D_SM1_OP_DP3, &instr->reg, &arg1->reg, &arg2->reg); break; default: @@ -2620,23 +2620,23 @@ static void d3dbc_write_expr(struct d3dbc_compiler *d3dbc, const struct hlsl_ir_ break; case HLSL_OP2_LOGIC_AND: - d3dbc_write_binary_op(d3dbc, D3DSIO_MIN, &instr->reg, &arg1->reg, &arg2->reg); + d3dbc_write_binary_op(d3dbc, VKD3D_SM1_OP_MIN, &instr->reg, &arg1->reg, &arg2->reg); break; case HLSL_OP2_LOGIC_OR: - d3dbc_write_binary_op(d3dbc, D3DSIO_MAX, &instr->reg, &arg1->reg, &arg2->reg); + d3dbc_write_binary_op(d3dbc, VKD3D_SM1_OP_MAX, &instr->reg, &arg1->reg, &arg2->reg); break; case HLSL_OP2_SLT: if (version->type == VKD3D_SHADER_TYPE_PIXEL) hlsl_fixme(ctx, &instr->loc, "Lower SLT instructions for pixel shaders."); - d3dbc_write_binary_op(d3dbc, D3DSIO_SLT, &instr->reg, &arg1->reg, &arg2->reg); + d3dbc_write_binary_op(d3dbc, VKD3D_SM1_OP_SLT, &instr->reg, &arg1->reg, &arg2->reg); break; case HLSL_OP3_CMP: if (version->type == VKD3D_SHADER_TYPE_VERTEX) hlsl_fixme(ctx, &instr->loc, "Lower CMP instructions for vertex shaders."); - d3dbc_write_ternary_op(d3dbc, D3DSIO_CMP, &instr->reg, &arg1->reg, &arg2->reg, &arg3->reg); + d3dbc_write_ternary_op(d3dbc, VKD3D_SM1_OP_CMP, &instr->reg, &arg1->reg, &arg2->reg, &arg3->reg); break; case HLSL_OP3_DP2ADD: @@ -2644,7 +2644,7 @@ static void d3dbc_write_expr(struct d3dbc_compiler *d3dbc, const struct hlsl_ir_ break; case HLSL_OP3_MAD: - d3dbc_write_ternary_op(d3dbc, D3DSIO_MAD, &instr->reg, &arg1->reg, &arg2->reg, &arg3->reg); + d3dbc_write_ternary_op(d3dbc, VKD3D_SM1_OP_MAD, &instr->reg, &arg1->reg, &arg2->reg, &arg3->reg); break; default: @@ -2666,7 +2666,7 @@ static void d3dbc_write_if(struct d3dbc_compiler *d3dbc, const struct hlsl_ir_no sm1_ifc = (struct sm1_instruction) { - .opcode = D3DSIO_IFC, + .opcode = VKD3D_SM1_OP_IFC, .flags = VKD3D_SHADER_REL_OP_NE, /* Make it a "if_ne" instruction. */ .srcs[0].type = VKD3DSPR_TEMP, @@ -2686,12 +2686,12 @@ static void d3dbc_write_if(struct d3dbc_compiler *d3dbc, const struct hlsl_ir_no if (!list_empty(&iff->else_block.instrs)) { - sm1_else = (struct sm1_instruction){.opcode = D3DSIO_ELSE}; + sm1_else = (struct sm1_instruction){.opcode = VKD3D_SM1_OP_ELSE}; d3dbc_write_instruction(d3dbc, &sm1_else); d3dbc_write_block(d3dbc, &iff->else_block); } - sm1_endif = (struct sm1_instruction){.opcode = D3DSIO_ENDIF}; + sm1_endif = (struct sm1_instruction){.opcode = VKD3D_SM1_OP_ENDIF}; d3dbc_write_instruction(d3dbc, &sm1_endif); } @@ -2707,7 +2707,7 @@ static void d3dbc_write_jump(struct d3dbc_compiler *d3dbc, const struct hlsl_ir_ struct sm1_instruction sm1_instr = { - .opcode = D3DSIO_TEXKILL, + .opcode = VKD3D_SM1_OP_TEXKILL, .dst.type = VKD3DSPR_TEMP, .dst.reg = reg->id, @@ -2758,21 +2758,21 @@ static void d3dbc_write_resource_load(struct d3dbc_compiler *d3dbc, const struct switch (load->load_type) { case HLSL_RESOURCE_SAMPLE: - sm1_instr.opcode = D3DSIO_TEX; + sm1_instr.opcode = VKD3D_SM1_OP_TEX; break; case HLSL_RESOURCE_SAMPLE_PROJ: - sm1_instr.opcode = D3DSIO_TEX; + sm1_instr.opcode = VKD3D_SM1_OP_TEX; sm1_instr.opcode |= VKD3DSI_TEXLD_PROJECT << VKD3D_SM1_INSTRUCTION_FLAGS_SHIFT; break; case HLSL_RESOURCE_SAMPLE_LOD_BIAS: - sm1_instr.opcode = D3DSIO_TEX; + sm1_instr.opcode = VKD3D_SM1_OP_TEX; sm1_instr.opcode |= VKD3DSI_TEXLD_BIAS << VKD3D_SM1_INSTRUCTION_FLAGS_SHIFT; break; case HLSL_RESOURCE_SAMPLE_GRAD: - sm1_instr.opcode = D3DSIO_TEXLDD; + sm1_instr.opcode = VKD3D_SM1_OP_TEXLDD; sm1_instr.srcs[2].type = VKD3DSPR_TEMP; sm1_instr.srcs[2].reg = ddx->reg.id; @@ -2889,7 +2889,7 @@ int d3dbc_compile(struct vsir_program *program, uint64_t config_flags, d3dbc_write_semantic_dcls(&d3dbc); d3dbc_write_block(&d3dbc, &entry_func->body); - put_u32(buffer, D3DSIO_END); + put_u32(buffer, VKD3D_SM1_OP_END); result = ctx->result; if (buffer->status) diff --git a/libs/vkd3d/libs/vkd3d-shader/ir.c b/libs/vkd3d/libs/vkd3d-shader/ir.c index d765abc938b..a483c25f3ad 100644 --- a/libs/vkd3d/libs/vkd3d-shader/ir.c +++ b/libs/vkd3d/libs/vkd3d-shader/ir.c @@ -19,6 +19,15 @@ #include "vkd3d_shader_private.h" #include "vkd3d_types.h" +struct vsir_normalisation_context +{ + enum vkd3d_result result; + struct vsir_program *program; + uint64_t config_flags; + const struct vkd3d_shader_compile_info *compile_info; + struct vkd3d_shader_message_context *message_context; +}; + static int convert_parameter_info(const struct vkd3d_shader_compile_info *compile_info, unsigned int *ret_count, const struct vkd3d_shader_parameter1 **ret_parameters) { @@ -442,9 +451,10 @@ static enum vkd3d_result vsir_program_lower_sm1_sincos(struct vsir_program *prog } static enum vkd3d_result vsir_program_lower_instructions(struct vsir_program *program, - struct vkd3d_shader_message_context *message_context) + struct vsir_normalisation_context *ctx) { struct vkd3d_shader_instruction_array *instructions = &program->instructions; + struct vkd3d_shader_message_context *message_context = ctx->message_context; unsigned int tmp_idx = ~0u, i; enum vkd3d_result ret; @@ -1755,8 +1765,7 @@ static enum vkd3d_result vsir_program_normalise_io_registers(struct vsir_program { struct io_normaliser normaliser = {program->instructions}; struct vkd3d_shader_instruction *ins; - bool has_control_point_phase; - unsigned int i, j; + unsigned int i; normaliser.phase = VKD3DSIH_INVALID; normaliser.shader_type = program->shader_version.type; @@ -1765,7 +1774,7 @@ static enum vkd3d_result vsir_program_normalise_io_registers(struct vsir_program normaliser.output_signature = &program->output_signature; normaliser.patch_constant_signature = &program->patch_constant_signature; - for (i = 0, has_control_point_phase = false; i < program->instructions.count; ++i) + for (i = 0; i < program->instructions.count; ++i) { ins = &program->instructions.elements[i]; @@ -1779,8 +1788,6 @@ static enum vkd3d_result vsir_program_normalise_io_registers(struct vsir_program vkd3d_shader_instruction_make_nop(ins); break; case VKD3DSIH_HS_CONTROL_POINT_PHASE: - has_control_point_phase = true; - /* fall through */ case VKD3DSIH_HS_FORK_PHASE: case VKD3DSIH_HS_JOIN_PHASE: normaliser.phase = ins->opcode; @@ -1790,22 +1797,6 @@ static enum vkd3d_result vsir_program_normalise_io_registers(struct vsir_program } } - if (normaliser.shader_type == VKD3D_SHADER_TYPE_HULL && !has_control_point_phase) - { - /* Inputs and outputs must match for the default phase, so merge ranges must match too. */ - for (i = 0; i < MAX_REG_OUTPUT; ++i) - { - for (j = 0; j < VKD3D_VEC4_SIZE; ++j) - { - if (!normaliser.input_range_map[i][j] && normaliser.output_range_map[i][j]) - normaliser.input_range_map[i][j] = normaliser.output_range_map[i][j]; - else if (normaliser.input_range_map[i][j] && !normaliser.output_range_map[i][j]) - normaliser.output_range_map[i][j] = normaliser.input_range_map[i][j]; - else VKD3D_ASSERT(normaliser.input_range_map[i][j] == normaliser.output_range_map[i][j]); - } - } - } - if (!shader_signature_merge(&program->input_signature, normaliser.input_range_map, false) || !shader_signature_merge(&program->output_signature, normaliser.output_range_map, false) || !shader_signature_merge(&program->patch_constant_signature, normaliser.pc_range_map, true)) @@ -2789,8 +2780,9 @@ static enum vkd3d_result cf_flattener_iterate_instruction_array(struct cf_flatte } static enum vkd3d_result vsir_program_flatten_control_flow_constructs(struct vsir_program *program, - struct vkd3d_shader_message_context *message_context) + struct vsir_normalisation_context *ctx) { + struct vkd3d_shader_message_context *message_context = ctx->message_context; struct cf_flattener flattener = {.program = program}; enum vkd3d_result result; @@ -2860,7 +2852,8 @@ static bool lower_switch_to_if_ladder_add_block_mapping(struct lower_switch_to_i return true; } -static enum vkd3d_result lower_switch_to_if_ladder(struct vsir_program *program) +static enum vkd3d_result vsir_program_lower_switch_to_selection_ladder(struct vsir_program *program, + struct vsir_normalisation_context *ctx) { unsigned int block_count = program->block_count, ssa_count = program->ssa_count, current_label = 0, if_label; size_t ins_capacity = 0, ins_count = 0, i, map_capacity = 0, map_count = 0; @@ -3050,7 +3043,8 @@ static void ssas_to_temps_block_info_cleanup(struct ssas_to_temps_block_info *bl vkd3d_free(block_info); } -static enum vkd3d_result vsir_program_materialise_phi_ssas_to_temps(struct vsir_program *program) +static enum vkd3d_result vsir_program_materialise_phi_ssas_to_temps(struct vsir_program *program, + struct vsir_normalisation_context *ctx) { size_t ins_capacity = 0, ins_count = 0, phi_count, incoming_count, i; struct ssas_to_temps_block_info *info, *block_info = NULL; @@ -5271,8 +5265,9 @@ out: } static enum vkd3d_result vsir_program_structurize(struct vsir_program *program, - struct vkd3d_shader_message_context *message_context) + struct vsir_normalisation_context *ctx) { + struct vkd3d_shader_message_context *message_context = ctx->message_context; struct vsir_cfg_emit_target target = {0}; enum vkd3d_result ret; size_t i; @@ -5451,8 +5446,9 @@ static enum vkd3d_result vsir_program_materialize_undominated_ssas_to_temps_in_f } static enum vkd3d_result vsir_program_materialize_undominated_ssas_to_temps(struct vsir_program *program, - struct vkd3d_shader_message_context *message_context) + struct vsir_normalisation_context *ctx) { + struct vkd3d_shader_message_context *message_context = ctx->message_context; enum vkd3d_result ret; size_t i; @@ -5731,14 +5727,14 @@ static void VKD3D_PRINTF_FUNC(3, 4) validator_error(struct validation_context *c if (ctx->invalid_instruction_idx) { vkd3d_shader_error(ctx->message_context, &ctx->null_location, error, "%s", buf.buffer); - ERR("VSIR validation error: %s\n", buf.buffer); + WARN("VSIR validation error: %s\n", buf.buffer); } else { const struct vkd3d_shader_instruction *ins = &ctx->program->instructions.elements[ctx->instruction_idx]; vkd3d_shader_error(ctx->message_context, &ins->location, error, "instruction %zu: %s", ctx->instruction_idx + 1, buf.buffer); - ERR("VSIR validation error: instruction %zu: %s\n", ctx->instruction_idx + 1, buf.buffer); + WARN("VSIR validation error: instruction %zu: %s\n", ctx->instruction_idx + 1, buf.buffer); } vkd3d_string_buffer_cleanup(&buf); @@ -6243,12 +6239,13 @@ static void vsir_validate_instruction(struct validation_context *ctx) /* We support two different control flow types in shaders: * block-based, like DXIL and SPIR-V, and structured, like D3DBC * and TPF. The shader is detected as block-based when its first - * instruction, except for DCL_* and phases, is a LABEL. Currently - * we mandate that each shader is either purely block-based or + * instruction, except for NOP, DCL_* and phases, is a LABEL. + * Currently we mandate that each shader is either purely block-based or * purely structured. In principle we could allow structured * constructs in a block, provided they are confined in a single * block, but need for that hasn't arisen yet, so we don't. */ - if (ctx->cf_type == CF_TYPE_UNKNOWN && !vsir_instruction_is_dcl(instruction)) + if (ctx->cf_type == CF_TYPE_UNKNOWN && instruction->opcode != VKD3DSIH_NOP + && !vsir_instruction_is_dcl(instruction)) { if (instruction->opcode == VKD3DSIH_LABEL) ctx->cf_type = CF_TYPE_BLOCKS; @@ -6610,33 +6607,59 @@ fail: return VKD3D_ERROR_OUT_OF_MEMORY; } -enum vkd3d_result vsir_program_normalise(struct vsir_program *program, uint64_t config_flags, - const struct vkd3d_shader_compile_info *compile_info, struct vkd3d_shader_message_context *message_context) +#define vsir_transform(ctx, step) vsir_transform_(ctx, #step, step) +static void vsir_transform_( + struct vsir_normalisation_context *ctx, const char *step_name, + enum vkd3d_result (*step)(struct vsir_program *program, struct vsir_normalisation_context *ctx)) { - enum vkd3d_result result = VKD3D_OK; + if (ctx->result < 0) + return; - if ((result = vsir_program_lower_instructions(program, message_context)) < 0) - return result; + if ((ctx->result = step(ctx->program, ctx)) < 0) + { + WARN("Transformation \"%s\" failed with result %u.\n", step_name, ctx->result); + return; + } - if (program->shader_version.major >= 6) + if ((ctx->result = vsir_program_validate(ctx->program, ctx->config_flags, + ctx->compile_info->source_name, ctx->message_context)) < 0) { - if ((result = vsir_program_materialise_phi_ssas_to_temps(program)) < 0) - return result; + WARN("Validation failed with result %u after transformation \"%s\".\n", ctx->result, step_name); + return; + } +} - if ((result = lower_switch_to_if_ladder(program)) < 0) - return result; +enum vkd3d_result vsir_program_normalise(struct vsir_program *program, uint64_t config_flags, + const struct vkd3d_shader_compile_info *compile_info, struct vkd3d_shader_message_context *message_context) +{ + struct vsir_normalisation_context ctx = + { + .result = VKD3D_OK, + .program = program, + .config_flags = config_flags, + .compile_info = compile_info, + .message_context = message_context, + }; + enum vkd3d_result result; - if ((result = vsir_program_structurize(program, message_context)) < 0) - return result; + vsir_transform(&ctx, vsir_program_lower_instructions); - if ((result = vsir_program_flatten_control_flow_constructs(program, message_context)) < 0) - return result; + if (program->shader_version.major >= 6) + { + vsir_transform(&ctx, vsir_program_materialise_phi_ssas_to_temps); + vsir_transform(&ctx, vsir_program_lower_switch_to_selection_ladder); + vsir_transform(&ctx, vsir_program_structurize); + vsir_transform(&ctx, vsir_program_flatten_control_flow_constructs); + vsir_transform(&ctx, vsir_program_materialize_undominated_ssas_to_temps); - if ((result = vsir_program_materialize_undominated_ssas_to_temps(program, message_context)) < 0) - return result; + if (ctx.result < 0) + return ctx.result; } else { + if (ctx.result < 0) + return ctx.result; + if (program->shader_version.type != VKD3D_SHADER_TYPE_PIXEL) { if ((result = vsir_program_remap_output_signature(program, compile_info, message_context)) < 0) @@ -6665,7 +6688,7 @@ enum vkd3d_result vsir_program_normalise(struct vsir_program *program, uint64_t return result; if (compile_info->target_type != VKD3D_SHADER_TARGET_GLSL - && (result = vsir_program_flatten_control_flow_constructs(program, message_context)) < 0) + && (result = vsir_program_flatten_control_flow_constructs(program, &ctx)) < 0) return result; } -- 2.45.2