From: Victor Chiletto vchiletto@codeweavers.com
--- libs/vkd3d-shader/hlsl.c | 19 ++++++++++++++++--- libs/vkd3d-shader/hlsl.h | 3 ++- libs/vkd3d-shader/hlsl.y | 5 +---- libs/vkd3d-shader/hlsl_codegen.c | 12 ++++++++++++ libs/vkd3d-shader/tpf.c | 1 + 5 files changed, 32 insertions(+), 8 deletions(-)
diff --git a/libs/vkd3d-shader/hlsl.c b/libs/vkd3d-shader/hlsl.c index cba954c98..b7bb856aa 100644 --- a/libs/vkd3d-shader/hlsl.c +++ b/libs/vkd3d-shader/hlsl.c @@ -1618,7 +1618,7 @@ struct hlsl_ir_node *hlsl_new_jump(struct hlsl_ctx *ctx, enum hlsl_ir_jump_type }
struct hlsl_ir_node *hlsl_new_loop(struct hlsl_ctx *ctx, - struct hlsl_block *block, const struct vkd3d_shader_location *loc) + struct hlsl_block *block, struct hlsl_block *iter, const struct vkd3d_shader_location *loc) { struct hlsl_ir_loop *loop;
@@ -1627,6 +1627,11 @@ struct hlsl_ir_node *hlsl_new_loop(struct hlsl_ctx *ctx, init_node(&loop->node, HLSL_IR_LOOP, NULL, loc); hlsl_block_init(&loop->body); hlsl_block_add_block(&loop->body, block); + + hlsl_block_init(&loop->iter); + if (iter) + hlsl_block_add_block(&loop->iter, iter); + return &loop->node; }
@@ -1783,12 +1788,18 @@ static struct hlsl_ir_node *clone_load(struct hlsl_ctx *ctx, struct clone_instr_ static struct hlsl_ir_node *clone_loop(struct hlsl_ctx *ctx, struct clone_instr_map *map, struct hlsl_ir_loop *src) { struct hlsl_ir_node *dst; - struct hlsl_block body; + struct hlsl_block body, iter;
if (!clone_block(ctx, &body, &src->body, map)) return NULL;
- if (!(dst = hlsl_new_loop(ctx, &body, &src->node.loc))) + if (!clone_block(ctx, &iter, &src->iter, map)) + { + hlsl_block_cleanup(&body); + return NULL; + } + + if (!(dst = hlsl_new_loop(ctx, &body, &iter, &src->node.loc))) { hlsl_block_cleanup(&body); return NULL; @@ -2694,6 +2705,7 @@ static void dump_ir_loop(struct hlsl_ctx *ctx, struct vkd3d_string_buffer *buffe { vkd3d_string_buffer_printf(buffer, "for (;;) {\n"); dump_block(ctx, buffer, &loop->body); + dump_block(ctx, buffer, &loop->iter); vkd3d_string_buffer_printf(buffer, " %10s }", ""); }
@@ -3012,6 +3024,7 @@ static void free_ir_load(struct hlsl_ir_load *load)
static void free_ir_loop(struct hlsl_ir_loop *loop) { + hlsl_block_cleanup(&loop->iter); hlsl_block_cleanup(&loop->body); vkd3d_free(loop); } diff --git a/libs/vkd3d-shader/hlsl.h b/libs/vkd3d-shader/hlsl.h index 64111f3fc..9a04c8ee7 100644 --- a/libs/vkd3d-shader/hlsl.h +++ b/libs/vkd3d-shader/hlsl.h @@ -522,6 +522,7 @@ struct hlsl_ir_loop struct hlsl_ir_node node; /* loop condition is stored in the body (as "if (!condition) break;") */ struct hlsl_block body; + struct hlsl_block iter; unsigned int next_index; /* liveness index of the end of the loop */ };
@@ -1278,7 +1279,7 @@ bool hlsl_index_chain_has_resource_access(struct hlsl_ir_index *index); struct hlsl_ir_node *hlsl_new_index(struct hlsl_ctx *ctx, struct hlsl_ir_node *val, struct hlsl_ir_node *idx, const struct vkd3d_shader_location *loc); struct hlsl_ir_node *hlsl_new_loop(struct hlsl_ctx *ctx, - struct hlsl_block *block, const struct vkd3d_shader_location *loc); + struct hlsl_block *block, struct hlsl_block *iter, const struct vkd3d_shader_location *loc); struct hlsl_ir_node *hlsl_new_resource_load(struct hlsl_ctx *ctx, const struct hlsl_resource_load_params *params, const struct vkd3d_shader_location *loc); struct hlsl_ir_node *hlsl_new_resource_store(struct hlsl_ctx *ctx, const struct hlsl_deref *resource, diff --git a/libs/vkd3d-shader/hlsl.y b/libs/vkd3d-shader/hlsl.y index 52c217654..2372af026 100644 --- a/libs/vkd3d-shader/hlsl.y +++ b/libs/vkd3d-shader/hlsl.y @@ -610,15 +610,12 @@ static struct hlsl_block *create_loop(struct hlsl_ctx *ctx, enum loop_type type, if (!append_conditional_break(ctx, cond)) goto oom;
- if (iter) - hlsl_block_add_block(body, iter); - if (type == LOOP_DO_WHILE) list_move_tail(&body->instrs, &cond->instrs); else list_move_head(&body->instrs, &cond->instrs);
- if (!(loop = hlsl_new_loop(ctx, body, loc))) + if (!(loop = hlsl_new_loop(ctx, body, iter, loc))) goto oom; hlsl_block_add_instr(init, loop);
diff --git a/libs/vkd3d-shader/hlsl_codegen.c b/libs/vkd3d-shader/hlsl_codegen.c index 882401665..87c0081ec 100644 --- a/libs/vkd3d-shader/hlsl_codegen.c +++ b/libs/vkd3d-shader/hlsl_codegen.c @@ -616,6 +616,7 @@ bool hlsl_transform_ir(struct hlsl_ctx *ctx, bool (*func)(struct hlsl_ctx *ctx, else if (instr->type == HLSL_IR_LOOP) { progress |= hlsl_transform_ir(ctx, func, &hlsl_ir_loop(instr)->body, context); + progress |= hlsl_transform_ir(ctx, func, &hlsl_ir_loop(instr)->iter, context); } else if (instr->type == HLSL_IR_SWITCH) { @@ -843,6 +844,7 @@ static bool lower_return(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl *fun else if (instr->type == HLSL_IR_LOOP) { has_early_return |= lower_return(ctx, func, &hlsl_ir_loop(instr)->body, true); + has_early_return |= lower_return(ctx, func, &hlsl_ir_loop(instr)->iter, true);
if (has_early_return) { @@ -1228,6 +1230,7 @@ static unsigned int index_instructions(struct hlsl_block *block, unsigned int in else if (instr->type == HLSL_IR_LOOP) { index = index_instructions(&hlsl_ir_loop(instr)->body, index); + index = index_instructions(&hlsl_ir_loop(instr)->iter, index); hlsl_ir_loop(instr)->next_index = index; } else if (instr->type == HLSL_IR_SWITCH) @@ -1801,6 +1804,7 @@ static void copy_propagation_invalidate_from_block(struct hlsl_ctx *ctx, struct struct hlsl_ir_loop *loop = hlsl_ir_loop(instr);
copy_propagation_invalidate_from_block(ctx, state, &loop->body, time); + copy_propagation_invalidate_from_block(ctx, state, &loop->iter, time);
break; } @@ -1858,9 +1862,11 @@ static bool copy_propagation_process_loop(struct hlsl_ctx *ctx, struct hlsl_ir_l bool progress = false;
copy_propagation_invalidate_from_block(ctx, state, &loop->body, loop->node.index); + copy_propagation_invalidate_from_block(ctx, state, &loop->iter, loop->node.index);
copy_propagation_state_init(ctx, &inner_state, state); progress |= copy_propagation_transform_block(ctx, &loop->body, &inner_state); + progress |= copy_propagation_transform_block(ctx, &loop->iter, &inner_state); copy_propagation_state_destroy(&inner_state);
return progress; @@ -3998,6 +4004,9 @@ static void compute_liveness_recurse(struct hlsl_block *block, unsigned int loop
compute_liveness_recurse(&loop->body, loop_first ? loop_first : instr->index, loop_last ? loop_last : loop->next_index); + + compute_liveness_recurse(&loop->iter, loop_first ? loop_first : instr->index, + loop_last ? loop_last : loop->next_index); break; } case HLSL_IR_RESOURCE_LOAD: @@ -4439,6 +4448,7 @@ static void allocate_temp_registers_recurse(struct hlsl_ctx *ctx, { struct hlsl_ir_loop *loop = hlsl_ir_loop(instr); allocate_temp_registers_recurse(ctx, &loop->body, allocator); + allocate_temp_registers_recurse(ctx, &loop->iter, allocator); break; }
@@ -4567,6 +4577,7 @@ static void allocate_const_registers_recurse(struct hlsl_ctx *ctx, { struct hlsl_ir_loop *loop = hlsl_ir_loop(instr); allocate_const_registers_recurse(ctx, &loop->body, allocator); + allocate_const_registers_recurse(ctx, &loop->iter, allocator); break; }
@@ -5351,6 +5362,7 @@ static void remove_unreachable_code(struct hlsl_ctx *ctx, struct hlsl_block *bod struct hlsl_ir_loop *loop = hlsl_ir_loop(instr);
remove_unreachable_code(ctx, &loop->body); + remove_unreachable_code(ctx, &loop->iter); } else if (instr->type == HLSL_IR_SWITCH) { diff --git a/libs/vkd3d-shader/tpf.c b/libs/vkd3d-shader/tpf.c index 4d0658313..4dea50237 100644 --- a/libs/vkd3d-shader/tpf.c +++ b/libs/vkd3d-shader/tpf.c @@ -5478,6 +5478,7 @@ static void write_sm4_loop(const struct tpf_writer *tpf, const struct hlsl_ir_lo write_sm4_instruction(tpf, &instr);
write_sm4_block(tpf, &loop->body); + write_sm4_block(tpf, &loop->iter);
instr.opcode = VKD3D_SM4_OP_ENDLOOP; write_sm4_instruction(tpf, &instr);