Not when making the loop header available, which is too early and might lead to open too many loops at once.
This fixes an assertion failure with some shaders seen in the wild.
From: Giovanni Mascellani gmascellani@codeweavers.com
Not when making the loop header available, which is too early and might lead to open too many loops at once. --- libs/vkd3d-shader/ir.c | 34 ++++++++++++++++++---------------- 1 file changed, 18 insertions(+), 16 deletions(-)
diff --git a/libs/vkd3d-shader/ir.c b/libs/vkd3d-shader/ir.c index 4f0226187..4e4abe427 100644 --- a/libs/vkd3d-shader/ir.c +++ b/libs/vkd3d-shader/ir.c @@ -3629,27 +3629,11 @@ struct vsir_cfg_node_sorter
static enum vkd3d_result vsir_cfg_node_sorter_make_node_available(struct vsir_cfg_node_sorter *sorter, struct vsir_block *block) { - struct vsir_block_list *loop = NULL; - struct vsir_cfg_node_sorter_stack_item *item; enum vkd3d_result ret;
- if (sorter->cfg->loops_by_header[block->label - 1] != SIZE_MAX) - loop = &sorter->cfg->loops[sorter->cfg->loops_by_header[block->label - 1]]; - if ((ret = vsir_block_list_add_checked(&sorter->available_blocks, block)) < 0) return ret;
- if (!loop) - return VKD3D_OK; - - if (!vkd3d_array_reserve((void **)&sorter->stack, &sorter->stack_capacity, sorter->stack_count + 1, sizeof(*sorter->stack))) - return VKD3D_ERROR_OUT_OF_MEMORY; - - item = &sorter->stack[sorter->stack_count++]; - item->loop = loop; - item->seen_count = 0; - item->begin = sorter->cfg->order.count; - return VKD3D_OK; }
@@ -3754,6 +3738,24 @@ static enum vkd3d_result vsir_cfg_sort_nodes(struct vsir_cfg *cfg) break; }
+ /* If the node is a loop header, open the loop. */ + if (sorter.cfg->loops_by_header[block->label - 1] != SIZE_MAX) + { + struct vsir_block_list *loop = &sorter.cfg->loops[sorter.cfg->loops_by_header[block->label - 1]]; + + if (loop) + { + if (!vkd3d_array_reserve((void **)&sorter.stack, &sorter.stack_capacity, + sorter.stack_count + 1, sizeof(*sorter.stack))) + return VKD3D_ERROR_OUT_OF_MEMORY; + + inner_stack_item = &sorter.stack[sorter.stack_count++]; + inner_stack_item->loop = loop; + inner_stack_item->seen_count = 0; + inner_stack_item->begin = sorter.cfg->order.count; + } + } + vsir_block_list_remove_index(&sorter.available_blocks, i); block->order_pos = cfg->order.count; if ((ret = vsir_block_list_add_checked(&cfg->order, block)) < 0)
From: Giovanni Mascellani gmascellani@codeweavers.com
--- libs/vkd3d-shader/ir.c | 14 ++------------ 1 file changed, 2 insertions(+), 12 deletions(-)
diff --git a/libs/vkd3d-shader/ir.c b/libs/vkd3d-shader/ir.c index 4e4abe427..8b260c1a9 100644 --- a/libs/vkd3d-shader/ir.c +++ b/libs/vkd3d-shader/ir.c @@ -3627,16 +3627,6 @@ struct vsir_cfg_node_sorter struct vsir_block_list available_blocks; };
-static enum vkd3d_result vsir_cfg_node_sorter_make_node_available(struct vsir_cfg_node_sorter *sorter, struct vsir_block *block) -{ - enum vkd3d_result ret; - - if ((ret = vsir_block_list_add_checked(&sorter->available_blocks, block)) < 0) - return ret; - - return VKD3D_OK; -} - /* Topologically sort the blocks according to the forward edges. By * definition if the input CFG is reducible then its forward edges * form a DAG, so a topological sorting exists. In order to compute it @@ -3711,7 +3701,7 @@ static enum vkd3d_result vsir_cfg_sort_nodes(struct vsir_cfg *cfg)
vsir_block_list_init(&sorter.available_blocks);
- if ((ret = vsir_cfg_node_sorter_make_node_available(&sorter, cfg->entry)) < 0) + if ((ret = vsir_block_list_add_checked(&sorter.available_blocks, cfg->entry)) < 0) goto fail;
while (sorter.available_blocks.count != 0) @@ -3797,7 +3787,7 @@ static enum vkd3d_result vsir_cfg_sort_nodes(struct vsir_cfg *cfg)
if (in_degrees[successor->label - 1] == 0) { - if ((ret = vsir_cfg_node_sorter_make_node_available(&sorter, successor)) < 0) + if ((ret = vsir_block_list_add_checked(&sorter.available_blocks, successor)) < 0) goto fail; } }
This merge request was approved by Giovanni Mascellani.