vkd3d-shader/hlsl: Partially defer continue resolution.

We need 'for' iter blocks to be separate for loop unrolling.
This commit is contained in:
Victor Chiletto
2024-10-16 17:19:36 -03:00
committed by Henri Verbeet
parent 5d8448a44e
commit 351d58a95b
Notes: Henri Verbeet 2024-12-12 17:48:02 +01:00
Approved-by: Francisco Casas (@fcasas)
Approved-by: Elizabeth Figura (@zfigura)
Approved-by: Henri Verbeet (@hverbeet)
Merge-Request: https://gitlab.winehq.org/wine/vkd3d/-/merge_requests/1053
4 changed files with 139 additions and 36 deletions

View File

@@ -555,13 +555,6 @@ static bool append_conditional_break(struct hlsl_ctx *ctx, struct hlsl_block *co
return true;
}
enum loop_type
{
LOOP_FOR,
LOOP_WHILE,
LOOP_DO_WHILE
};
static void check_attribute_list_for_duplicates(struct hlsl_ctx *ctx, const struct parse_attribute_list *attrs)
{
unsigned int i, j;
@@ -577,8 +570,8 @@ static void check_attribute_list_for_duplicates(struct hlsl_ctx *ctx, const stru
}
}
static void resolve_loop_continue(struct hlsl_ctx *ctx, struct hlsl_block *block, enum loop_type type,
struct hlsl_block *cond, struct hlsl_block *iter)
static void resolve_loop_continue(struct hlsl_ctx *ctx, struct hlsl_block *block,
enum hlsl_loop_type type, struct hlsl_block *cond)
{
struct hlsl_ir_node *instr, *next;
@@ -588,8 +581,8 @@ static void resolve_loop_continue(struct hlsl_ctx *ctx, struct hlsl_block *block
{
struct hlsl_ir_if *iff = hlsl_ir_if(instr);
resolve_loop_continue(ctx, &iff->then_block, type, cond, iter);
resolve_loop_continue(ctx, &iff->else_block, type, cond, iter);
resolve_loop_continue(ctx, &iff->then_block, type, cond);
resolve_loop_continue(ctx, &iff->else_block, type, cond);
}
else if (instr->type == HLSL_IR_JUMP)
{
@@ -599,7 +592,7 @@ static void resolve_loop_continue(struct hlsl_ctx *ctx, struct hlsl_block *block
if (jump->type != HLSL_IR_JUMP_UNRESOLVED_CONTINUE)
continue;
if (type == LOOP_DO_WHILE)
if (type == HLSL_LOOP_DO_WHILE)
{
if (!hlsl_clone_block(ctx, &cond_block, cond))
return;
@@ -610,13 +603,6 @@ static void resolve_loop_continue(struct hlsl_ctx *ctx, struct hlsl_block *block
}
list_move_before(&instr->entry, &cond_block.instrs);
}
else if (type == LOOP_FOR)
{
if (!hlsl_clone_block(ctx, &cond_block, iter))
return;
list_move_before(&instr->entry, &cond_block.instrs);
}
jump->type = HLSL_IR_JUMP_CONTINUE;
}
}
}
@@ -740,7 +726,7 @@ static unsigned int evaluate_static_expression_as_uint(struct hlsl_ctx *ctx, str
return res.number.u;
}
static struct hlsl_block *create_loop(struct hlsl_ctx *ctx, enum loop_type type,
static struct hlsl_block *create_loop(struct hlsl_ctx *ctx, enum hlsl_loop_type type,
const struct parse_attribute_list *attributes, struct hlsl_block *init, struct hlsl_block *cond,
struct hlsl_block *iter, struct hlsl_block *body, const struct vkd3d_shader_location *loc)
{
@@ -792,7 +778,7 @@ static struct hlsl_block *create_loop(struct hlsl_ctx *ctx, enum loop_type type,
}
}
resolve_loop_continue(ctx, body, type, cond, iter);
resolve_loop_continue(ctx, body, type, cond);
if (!init && !(init = make_empty_block(ctx)))
goto oom;
@@ -800,15 +786,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)
if (type == HLSL_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, unroll_type, unroll_limit, loc)))
if (!(loop = hlsl_new_loop(ctx, iter, body, unroll_type, unroll_limit, loc)))
goto oom;
hlsl_block_add_instr(init, loop);
@@ -8831,25 +8814,25 @@ if_body:
loop_statement:
attribute_list_optional loop_scope_start KW_WHILE '(' expr ')' statement
{
$$ = create_loop(ctx, LOOP_WHILE, &$1, NULL, $5, NULL, $7, &@3);
$$ = create_loop(ctx, HLSL_LOOP_WHILE, &$1, NULL, $5, NULL, $7, &@3);
hlsl_pop_scope(ctx);
cleanup_parse_attribute_list(&$1);
}
| attribute_list_optional loop_scope_start KW_DO statement KW_WHILE '(' expr ')' ';'
{
$$ = create_loop(ctx, LOOP_DO_WHILE, &$1, NULL, $7, NULL, $4, &@3);
$$ = create_loop(ctx, HLSL_LOOP_DO_WHILE, &$1, NULL, $7, NULL, $4, &@3);
hlsl_pop_scope(ctx);
cleanup_parse_attribute_list(&$1);
}
| attribute_list_optional loop_scope_start KW_FOR '(' expr_statement expr_statement expr_optional ')' statement
{
$$ = create_loop(ctx, LOOP_FOR, &$1, $5, $6, $7, $9, &@3);
$$ = create_loop(ctx, HLSL_LOOP_FOR, &$1, $5, $6, $7, $9, &@3);
hlsl_pop_scope(ctx);
cleanup_parse_attribute_list(&$1);
}
| attribute_list_optional loop_scope_start KW_FOR '(' declaration expr_statement expr_optional ')' statement
{
$$ = create_loop(ctx, LOOP_FOR, &$1, $5, $6, $7, $9, &@3);
$$ = create_loop(ctx, HLSL_LOOP_FOR, &$1, $5, $6, $7, $9, &@3);
hlsl_pop_scope(ctx);
cleanup_parse_attribute_list(&$1);
}