mirror of
https://gitlab.winehq.org/wine/vkd3d.git
synced 2025-01-28 13:05:02 -08:00
vkd3d-shader/hlsl: Pass hlsl_block pointers to hlsl_new_if().
This commit is contained in:
parent
5a3fe1609b
commit
50f0ae1b21
Notes:
Alexandre Julliard
2023-04-18 22:35:06 +02: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/153
@ -1208,16 +1208,20 @@ struct hlsl_ir_node *hlsl_new_binary_expr(struct hlsl_ctx *ctx, enum hlsl_ir_exp
|
||||
return hlsl_new_expr(ctx, op, operands, arg1->data_type, &arg1->loc);
|
||||
}
|
||||
|
||||
struct hlsl_ir_if *hlsl_new_if(struct hlsl_ctx *ctx, struct hlsl_ir_node *condition, struct vkd3d_shader_location loc)
|
||||
struct hlsl_ir_if *hlsl_new_if(struct hlsl_ctx *ctx, struct hlsl_ir_node *condition,
|
||||
struct hlsl_block *then_block, struct hlsl_block *else_block, const struct vkd3d_shader_location *loc)
|
||||
{
|
||||
struct hlsl_ir_if *iff;
|
||||
|
||||
if (!(iff = hlsl_alloc(ctx, sizeof(*iff))))
|
||||
return NULL;
|
||||
init_node(&iff->node, HLSL_IR_IF, NULL, &loc);
|
||||
init_node(&iff->node, HLSL_IR_IF, NULL, loc);
|
||||
hlsl_src_from_node(&iff->condition, condition);
|
||||
hlsl_block_init(&iff->then_instrs);
|
||||
hlsl_block_init(&iff->else_instrs);
|
||||
hlsl_block_init(&iff->then_block);
|
||||
hlsl_block_add_block(&iff->then_block, then_block);
|
||||
hlsl_block_init(&iff->else_block);
|
||||
if (else_block)
|
||||
hlsl_block_add_block(&iff->else_block, else_block);
|
||||
return iff;
|
||||
}
|
||||
|
||||
@ -1516,17 +1520,24 @@ static struct hlsl_ir_node *clone_expr(struct hlsl_ctx *ctx, struct clone_instr_
|
||||
|
||||
static struct hlsl_ir_node *clone_if(struct hlsl_ctx *ctx, struct clone_instr_map *map, struct hlsl_ir_if *src)
|
||||
{
|
||||
struct hlsl_block then_block, else_block;
|
||||
struct hlsl_ir_if *dst;
|
||||
|
||||
if (!(dst = hlsl_new_if(ctx, map_instr(map, src->condition.node), src->node.loc)))
|
||||
if (!clone_block(ctx, &then_block, &src->then_block, map))
|
||||
return NULL;
|
||||
|
||||
if (!clone_block(ctx, &dst->then_instrs, &src->then_instrs, map)
|
||||
|| !clone_block(ctx, &dst->else_instrs, &src->else_instrs, map))
|
||||
if (!clone_block(ctx, &else_block, &src->else_block, map))
|
||||
{
|
||||
hlsl_free_instr(&dst->node);
|
||||
hlsl_block_cleanup(&then_block);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (!(dst = hlsl_new_if(ctx, map_instr(map, src->condition.node), &then_block, &else_block, &src->node.loc)))
|
||||
{
|
||||
hlsl_block_cleanup(&then_block);
|
||||
hlsl_block_cleanup(&else_block);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return &dst->node;
|
||||
}
|
||||
|
||||
@ -2334,9 +2345,9 @@ static void dump_ir_if(struct hlsl_ctx *ctx, struct vkd3d_string_buffer *buffer,
|
||||
vkd3d_string_buffer_printf(buffer, "if (");
|
||||
dump_src(buffer, &if_node->condition);
|
||||
vkd3d_string_buffer_printf(buffer, ") {\n");
|
||||
dump_instr_list(ctx, buffer, &if_node->then_instrs.instrs);
|
||||
dump_instr_list(ctx, buffer, &if_node->then_block.instrs);
|
||||
vkd3d_string_buffer_printf(buffer, " %10s } else {\n", "");
|
||||
dump_instr_list(ctx, buffer, &if_node->else_instrs.instrs);
|
||||
dump_instr_list(ctx, buffer, &if_node->else_block.instrs);
|
||||
vkd3d_string_buffer_printf(buffer, " %10s }", "");
|
||||
}
|
||||
|
||||
@ -2605,8 +2616,8 @@ static void free_ir_expr(struct hlsl_ir_expr *expr)
|
||||
|
||||
static void free_ir_if(struct hlsl_ir_if *if_node)
|
||||
{
|
||||
hlsl_block_cleanup(&if_node->then_instrs);
|
||||
hlsl_block_cleanup(&if_node->else_instrs);
|
||||
hlsl_block_cleanup(&if_node->then_block);
|
||||
hlsl_block_cleanup(&if_node->else_block);
|
||||
hlsl_src_remove(&if_node->condition);
|
||||
vkd3d_free(if_node);
|
||||
}
|
||||
|
@ -451,8 +451,8 @@ struct hlsl_ir_if
|
||||
{
|
||||
struct hlsl_ir_node node;
|
||||
struct hlsl_src condition;
|
||||
struct hlsl_block then_instrs;
|
||||
struct hlsl_block else_instrs;
|
||||
struct hlsl_block then_block;
|
||||
struct hlsl_block else_block;
|
||||
};
|
||||
|
||||
struct hlsl_ir_loop
|
||||
@ -1067,7 +1067,8 @@ struct hlsl_ir_node *hlsl_new_float_constant(struct hlsl_ctx *ctx,
|
||||
struct hlsl_ir_function_decl *hlsl_new_func_decl(struct hlsl_ctx *ctx,
|
||||
struct hlsl_type *return_type, const struct hlsl_func_parameters *parameters,
|
||||
const struct hlsl_semantic *semantic, const struct vkd3d_shader_location *loc);
|
||||
struct hlsl_ir_if *hlsl_new_if(struct hlsl_ctx *ctx, struct hlsl_ir_node *condition, struct vkd3d_shader_location loc);
|
||||
struct hlsl_ir_if *hlsl_new_if(struct hlsl_ctx *ctx, struct hlsl_ir_node *condition,
|
||||
struct hlsl_block *then_block, struct hlsl_block *else_block, const struct vkd3d_shader_location *loc);
|
||||
struct hlsl_ir_constant *hlsl_new_int_constant(struct hlsl_ctx *ctx, int n,
|
||||
const struct vkd3d_shader_location *loc);
|
||||
struct hlsl_ir_jump *hlsl_new_jump(struct hlsl_ctx *ctx, enum hlsl_ir_jump_type type, struct vkd3d_shader_location loc);
|
||||
|
@ -85,8 +85,8 @@ struct parse_function
|
||||
|
||||
struct parse_if_body
|
||||
{
|
||||
struct list *then_instrs;
|
||||
struct list *else_instrs;
|
||||
struct list *then_block;
|
||||
struct list *else_block;
|
||||
};
|
||||
|
||||
enum parse_assign_op
|
||||
@ -407,6 +407,7 @@ static DWORD add_modifiers(struct hlsl_ctx *ctx, DWORD modifiers, DWORD mod, con
|
||||
static bool append_conditional_break(struct hlsl_ctx *ctx, struct list *cond_list)
|
||||
{
|
||||
struct hlsl_ir_node *condition, *not;
|
||||
struct hlsl_block then_block;
|
||||
struct hlsl_ir_jump *jump;
|
||||
struct hlsl_ir_if *iff;
|
||||
|
||||
@ -419,13 +420,15 @@ static bool append_conditional_break(struct hlsl_ctx *ctx, struct list *cond_lis
|
||||
return false;
|
||||
list_add_tail(cond_list, ¬->entry);
|
||||
|
||||
if (!(iff = hlsl_new_if(ctx, not, condition->loc)))
|
||||
return false;
|
||||
list_add_tail(cond_list, &iff->node.entry);
|
||||
hlsl_block_init(&then_block);
|
||||
|
||||
if (!(jump = hlsl_new_jump(ctx, HLSL_IR_JUMP_BREAK, condition->loc)))
|
||||
return false;
|
||||
hlsl_block_add_instr(&iff->then_instrs, &jump->node);
|
||||
hlsl_block_add_instr(&then_block, &jump->node);
|
||||
|
||||
if (!(iff = hlsl_new_if(ctx, not, &then_block, NULL, &condition->loc)))
|
||||
return false;
|
||||
list_add_tail(cond_list, &iff->node.entry);
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -5241,15 +5244,19 @@ selection_statement:
|
||||
KW_IF '(' expr ')' if_body
|
||||
{
|
||||
struct hlsl_ir_node *condition = node_from_list($3);
|
||||
struct hlsl_block then_block, else_block;
|
||||
struct hlsl_ir_if *instr;
|
||||
|
||||
if (!(instr = hlsl_new_if(ctx, condition, @1)))
|
||||
hlsl_block_init(&then_block);
|
||||
list_move_tail(&then_block.instrs, $5.then_block);
|
||||
hlsl_block_init(&else_block);
|
||||
if ($5.else_block)
|
||||
list_move_tail(&else_block.instrs, $5.else_block);
|
||||
vkd3d_free($5.then_block);
|
||||
vkd3d_free($5.else_block);
|
||||
|
||||
if (!(instr = hlsl_new_if(ctx, condition, &then_block, &else_block, &@1)))
|
||||
YYABORT;
|
||||
list_move_tail(&instr->then_instrs.instrs, $5.then_instrs);
|
||||
if ($5.else_instrs)
|
||||
list_move_tail(&instr->else_instrs.instrs, $5.else_instrs);
|
||||
vkd3d_free($5.then_instrs);
|
||||
vkd3d_free($5.else_instrs);
|
||||
if (condition->data_type->dimx > 1 || condition->data_type->dimy > 1)
|
||||
{
|
||||
struct vkd3d_string_buffer *string;
|
||||
@ -5266,13 +5273,13 @@ selection_statement:
|
||||
if_body:
|
||||
statement
|
||||
{
|
||||
$$.then_instrs = $1;
|
||||
$$.else_instrs = NULL;
|
||||
$$.then_block = $1;
|
||||
$$.else_block = NULL;
|
||||
}
|
||||
| statement KW_ELSE statement
|
||||
{
|
||||
$$.then_instrs = $1;
|
||||
$$.else_instrs = $3;
|
||||
$$.then_block = $1;
|
||||
$$.else_block = $3;
|
||||
}
|
||||
|
||||
loop_statement:
|
||||
|
@ -459,8 +459,8 @@ static bool transform_ir(struct hlsl_ctx *ctx, bool (*func)(struct hlsl_ctx *ctx
|
||||
{
|
||||
struct hlsl_ir_if *iff = hlsl_ir_if(instr);
|
||||
|
||||
progress |= transform_ir(ctx, func, &iff->then_instrs, context);
|
||||
progress |= transform_ir(ctx, func, &iff->else_instrs, context);
|
||||
progress |= transform_ir(ctx, func, &iff->then_block, context);
|
||||
progress |= transform_ir(ctx, func, &iff->else_block, context);
|
||||
}
|
||||
else if (instr->type == HLSL_IR_LOOP)
|
||||
progress |= transform_ir(ctx, func, &hlsl_ir_loop(instr)->body, context);
|
||||
@ -516,21 +516,24 @@ static bool find_recursive_calls(struct hlsl_ctx *ctx, struct hlsl_ir_node *inst
|
||||
static void insert_early_return_break(struct hlsl_ctx *ctx,
|
||||
struct hlsl_ir_function_decl *func, struct hlsl_ir_node *cf_instr)
|
||||
{
|
||||
struct hlsl_block then_block;
|
||||
struct hlsl_ir_jump *jump;
|
||||
struct hlsl_ir_load *load;
|
||||
struct hlsl_ir_if *iff;
|
||||
|
||||
hlsl_block_init(&then_block);
|
||||
|
||||
if (!(load = hlsl_new_var_load(ctx, func->early_return_var, cf_instr->loc)))
|
||||
return;
|
||||
list_add_after(&cf_instr->entry, &load->node.entry);
|
||||
|
||||
if (!(iff = hlsl_new_if(ctx, &load->node, cf_instr->loc)))
|
||||
return;
|
||||
list_add_after(&load->node.entry, &iff->node.entry);
|
||||
|
||||
if (!(jump = hlsl_new_jump(ctx, HLSL_IR_JUMP_BREAK, cf_instr->loc)))
|
||||
return;
|
||||
hlsl_block_add_instr(&iff->then_instrs, &jump->node);
|
||||
hlsl_block_add_instr(&then_block, &jump->node);
|
||||
|
||||
if (!(iff = hlsl_new_if(ctx, &load->node, &then_block, NULL, &cf_instr->loc)))
|
||||
return;
|
||||
list_add_after(&load->node.entry, &iff->node.entry);
|
||||
}
|
||||
|
||||
/* Remove HLSL_IR_JUMP_RETURN calls by altering subsequent control flow. */
|
||||
@ -591,8 +594,8 @@ static bool lower_return(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl *fun
|
||||
{
|
||||
struct hlsl_ir_if *iff = hlsl_ir_if(instr);
|
||||
|
||||
has_early_return |= lower_return(ctx, func, &iff->then_instrs, in_loop);
|
||||
has_early_return |= lower_return(ctx, func, &iff->else_instrs, in_loop);
|
||||
has_early_return |= lower_return(ctx, func, &iff->then_block, in_loop);
|
||||
has_early_return |= lower_return(ctx, func, &iff->else_block, in_loop);
|
||||
|
||||
if (has_early_return)
|
||||
{
|
||||
@ -675,6 +678,7 @@ static bool lower_return(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl *fun
|
||||
else if (cf_instr)
|
||||
{
|
||||
struct list *tail = list_tail(&block->instrs);
|
||||
struct hlsl_block then_block;
|
||||
struct hlsl_ir_load *load;
|
||||
struct hlsl_ir_node *not;
|
||||
struct hlsl_ir_if *iff;
|
||||
@ -685,6 +689,10 @@ static bool lower_return(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl *fun
|
||||
if (tail == &cf_instr->entry)
|
||||
return has_early_return;
|
||||
|
||||
hlsl_block_init(&then_block);
|
||||
list_move_slice_tail(&then_block.instrs, list_next(&block->instrs, &cf_instr->entry), tail);
|
||||
lower_return(ctx, func, &then_block, in_loop);
|
||||
|
||||
if (!(load = hlsl_new_var_load(ctx, func->early_return_var, cf_instr->loc)))
|
||||
return false;
|
||||
hlsl_block_add_instr(block, &load->node);
|
||||
@ -693,13 +701,9 @@ static bool lower_return(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl *fun
|
||||
return false;
|
||||
hlsl_block_add_instr(block, not);
|
||||
|
||||
if (!(iff = hlsl_new_if(ctx, not, cf_instr->loc)))
|
||||
if (!(iff = hlsl_new_if(ctx, not, &then_block, NULL, &cf_instr->loc)))
|
||||
return false;
|
||||
hlsl_block_add_instr(block, &iff->node);
|
||||
|
||||
list_move_slice_tail(&iff->then_instrs.instrs, list_next(&block->instrs, &cf_instr->entry), tail);
|
||||
|
||||
lower_return(ctx, func, &iff->then_instrs, in_loop);
|
||||
list_add_tail(&block->instrs, &iff->node.entry);
|
||||
}
|
||||
|
||||
return has_early_return;
|
||||
@ -1343,8 +1347,8 @@ static void copy_propagation_invalidate_from_block(struct hlsl_ctx *ctx, struct
|
||||
{
|
||||
struct hlsl_ir_if *iff = hlsl_ir_if(instr);
|
||||
|
||||
copy_propagation_invalidate_from_block(ctx, state, &iff->then_instrs);
|
||||
copy_propagation_invalidate_from_block(ctx, state, &iff->else_instrs);
|
||||
copy_propagation_invalidate_from_block(ctx, state, &iff->then_block);
|
||||
copy_propagation_invalidate_from_block(ctx, state, &iff->else_block);
|
||||
|
||||
break;
|
||||
}
|
||||
@ -1374,19 +1378,19 @@ static bool copy_propagation_process_if(struct hlsl_ctx *ctx, struct hlsl_ir_if
|
||||
bool progress = false;
|
||||
|
||||
copy_propagation_state_init(ctx, &inner_state, state);
|
||||
progress |= copy_propagation_transform_block(ctx, &iff->then_instrs, &inner_state);
|
||||
progress |= copy_propagation_transform_block(ctx, &iff->then_block, &inner_state);
|
||||
copy_propagation_state_destroy(&inner_state);
|
||||
|
||||
copy_propagation_state_init(ctx, &inner_state, state);
|
||||
progress |= copy_propagation_transform_block(ctx, &iff->else_instrs, &inner_state);
|
||||
progress |= copy_propagation_transform_block(ctx, &iff->else_block, &inner_state);
|
||||
copy_propagation_state_destroy(&inner_state);
|
||||
|
||||
/* Ideally we'd invalidate the outer state looking at what was
|
||||
* touched in the two inner states, but this doesn't work for
|
||||
* loops (because we need to know what is invalidated in advance),
|
||||
* so we need copy_propagation_invalidate_from_block() anyway. */
|
||||
copy_propagation_invalidate_from_block(ctx, state, &iff->then_instrs);
|
||||
copy_propagation_invalidate_from_block(ctx, state, &iff->else_instrs);
|
||||
copy_propagation_invalidate_from_block(ctx, state, &iff->then_block);
|
||||
copy_propagation_invalidate_from_block(ctx, state, &iff->else_block);
|
||||
|
||||
return progress;
|
||||
}
|
||||
@ -1999,6 +2003,7 @@ static bool lower_casts_to_bool(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr
|
||||
struct hlsl_ir_load *hlsl_add_conditional(struct hlsl_ctx *ctx, struct list *instrs,
|
||||
struct hlsl_ir_node *condition, struct hlsl_ir_node *if_true, struct hlsl_ir_node *if_false)
|
||||
{
|
||||
struct hlsl_block then_block, else_block;
|
||||
struct hlsl_ir_store *store;
|
||||
struct hlsl_ir_load *load;
|
||||
struct hlsl_ir_var *var;
|
||||
@ -2009,17 +2014,20 @@ struct hlsl_ir_load *hlsl_add_conditional(struct hlsl_ctx *ctx, struct list *ins
|
||||
if (!(var = hlsl_new_synthetic_var(ctx, "conditional", if_true->data_type, &condition->loc)))
|
||||
return NULL;
|
||||
|
||||
if (!(iff = hlsl_new_if(ctx, condition, condition->loc)))
|
||||
return NULL;
|
||||
list_add_tail(instrs, &iff->node.entry);
|
||||
hlsl_block_init(&then_block);
|
||||
hlsl_block_init(&else_block);
|
||||
|
||||
if (!(store = hlsl_new_simple_store(ctx, var, if_true)))
|
||||
return NULL;
|
||||
hlsl_block_add_instr(&iff->then_instrs, &store->node);
|
||||
hlsl_block_add_instr(&then_block, &store->node);
|
||||
|
||||
if (!(store = hlsl_new_simple_store(ctx, var, if_false)))
|
||||
return NULL;
|
||||
hlsl_block_add_instr(&iff->else_instrs, &store->node);
|
||||
hlsl_block_add_instr(&else_block, &store->node);
|
||||
|
||||
if (!(iff = hlsl_new_if(ctx, condition, &then_block, &else_block, &condition->loc)))
|
||||
return NULL;
|
||||
list_add_tail(instrs, &iff->node.entry);
|
||||
|
||||
if (!(load = hlsl_new_var_load(ctx, var, condition->loc)))
|
||||
return NULL;
|
||||
@ -2320,8 +2328,8 @@ static unsigned int index_instructions(struct hlsl_block *block, unsigned int in
|
||||
if (instr->type == HLSL_IR_IF)
|
||||
{
|
||||
struct hlsl_ir_if *iff = hlsl_ir_if(instr);
|
||||
index = index_instructions(&iff->then_instrs, index);
|
||||
index = index_instructions(&iff->else_instrs, index);
|
||||
index = index_instructions(&iff->then_block, index);
|
||||
index = index_instructions(&iff->else_block, index);
|
||||
}
|
||||
else if (instr->type == HLSL_IR_LOOP)
|
||||
{
|
||||
@ -2446,8 +2454,8 @@ static void compute_liveness_recurse(struct hlsl_block *block, unsigned int loop
|
||||
{
|
||||
struct hlsl_ir_if *iff = hlsl_ir_if(instr);
|
||||
|
||||
compute_liveness_recurse(&iff->then_instrs, loop_first, loop_last);
|
||||
compute_liveness_recurse(&iff->else_instrs, loop_first, loop_last);
|
||||
compute_liveness_recurse(&iff->then_block, loop_first, loop_last);
|
||||
compute_liveness_recurse(&iff->else_block, loop_first, loop_last);
|
||||
iff->condition.node->last_read = instr->index;
|
||||
break;
|
||||
}
|
||||
@ -2724,8 +2732,8 @@ static void allocate_temp_registers_recurse(struct hlsl_ctx *ctx, struct hlsl_bl
|
||||
case HLSL_IR_IF:
|
||||
{
|
||||
struct hlsl_ir_if *iff = hlsl_ir_if(instr);
|
||||
allocate_temp_registers_recurse(ctx, &iff->then_instrs, liveness);
|
||||
allocate_temp_registers_recurse(ctx, &iff->else_instrs, liveness);
|
||||
allocate_temp_registers_recurse(ctx, &iff->then_block, liveness);
|
||||
allocate_temp_registers_recurse(ctx, &iff->else_block, liveness);
|
||||
break;
|
||||
}
|
||||
|
||||
@ -2839,8 +2847,8 @@ static void allocate_const_registers_recurse(struct hlsl_ctx *ctx, struct hlsl_b
|
||||
case HLSL_IR_IF:
|
||||
{
|
||||
struct hlsl_ir_if *iff = hlsl_ir_if(instr);
|
||||
allocate_const_registers_recurse(ctx, &iff->then_instrs, liveness);
|
||||
allocate_const_registers_recurse(ctx, &iff->else_instrs, liveness);
|
||||
allocate_const_registers_recurse(ctx, &iff->then_block, liveness);
|
||||
allocate_const_registers_recurse(ctx, &iff->else_block, liveness);
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -2118,15 +2118,15 @@ static void write_sm4_if(struct hlsl_ctx *ctx, struct vkd3d_bytecode_buffer *buf
|
||||
sm4_src_from_node(&instr.srcs[0], iff->condition.node, VKD3DSP_WRITEMASK_ALL);
|
||||
write_sm4_instruction(buffer, &instr);
|
||||
|
||||
write_sm4_block(ctx, buffer, &iff->then_instrs);
|
||||
write_sm4_block(ctx, buffer, &iff->then_block);
|
||||
|
||||
if (!list_empty(&iff->else_instrs.instrs))
|
||||
if (!list_empty(&iff->else_block.instrs))
|
||||
{
|
||||
instr.opcode = VKD3D_SM4_OP_ELSE;
|
||||
instr.src_count = 0;
|
||||
write_sm4_instruction(buffer, &instr);
|
||||
|
||||
write_sm4_block(ctx, buffer, &iff->else_instrs);
|
||||
write_sm4_block(ctx, buffer, &iff->else_block);
|
||||
}
|
||||
|
||||
instr.opcode = VKD3D_SM4_OP_ENDIF;
|
||||
|
Loading…
x
Reference in New Issue
Block a user