From: Philip Rebohle philip.rebohle@tu-dortmund.de
Avoiding generation of invalid SPIR-V.
Signed-off-by: Conor McCarthy cmccarthy@codeweavers.com Signed-off-by: Henri Verbeet hverbeet@codeweavers.com --- v2: Move the corresponding test after this patch in the series. There's not much point in comitting the test first if we're just going to skip it.
libs/vkd3d-shader/spirv.c | 6 +++++- libs/vkd3d-shader/vkd3d_shader_main.c | 1 + 2 files changed, 6 insertions(+), 1 deletion(-)
diff --git a/libs/vkd3d-shader/spirv.c b/libs/vkd3d-shader/spirv.c index 9f6eb886..e5b9ef03 100644 --- a/libs/vkd3d-shader/spirv.c +++ b/libs/vkd3d-shader/spirv.c @@ -7661,6 +7661,7 @@ static int vkd3d_dxbc_compiler_emit_control_flow_instruction(struct vkd3d_dxbc_c cf_info->u.loop.continue_block_id = continue_block_id; cf_info->u.loop.merge_block_id = merge_block_id; cf_info->current_block = VKD3D_BLOCK_LOOP; + cf_info->inside_block = true;
vkd3d_spirv_build_op_name(builder, loop_header_block_id, "loop%u_header", compiler->loop_id); vkd3d_spirv_build_op_name(builder, loop_body_block_id, "loop%u_body", compiler->loop_id); @@ -7673,7 +7674,10 @@ static int vkd3d_dxbc_compiler_emit_control_flow_instruction(struct vkd3d_dxbc_c assert(compiler->control_flow_depth); assert(cf_info->current_block == VKD3D_BLOCK_LOOP);
- vkd3d_spirv_build_op_branch(builder, cf_info->u.loop.continue_block_id); + /* The loop block may have already been ended by an unconditional + * break instruction right before the end of the loop. */ + if (cf_info->inside_block) + vkd3d_spirv_build_op_branch(builder, cf_info->u.loop.continue_block_id);
vkd3d_spirv_build_op_label(builder, cf_info->u.loop.continue_block_id); vkd3d_spirv_build_op_branch(builder, cf_info->u.loop.header_block_id); diff --git a/libs/vkd3d-shader/vkd3d_shader_main.c b/libs/vkd3d-shader/vkd3d_shader_main.c index d2045332..3982d073 100644 --- a/libs/vkd3d-shader/vkd3d_shader_main.c +++ b/libs/vkd3d-shader/vkd3d_shader_main.c @@ -814,6 +814,7 @@ static int vkd3d_shader_scan_instruction(struct vkd3d_shader_scan_context *conte case VKD3DSIH_LOOP: cf_info = vkd3d_shader_scan_push_cf_info(context); cf_info->type = VKD3D_SHADER_BLOCK_LOOP; + cf_info->inside_block = true; break; case VKD3DSIH_ENDLOOP: if (!(cf_info = vkd3d_shader_scan_get_current_cf_info(context)) || cf_info->type != VKD3D_SHADER_BLOCK_LOOP)