I encountered a case where a game provides an empty fragment shader, one that disassembles to just:
``` ps_5_0 dcl_globalFlags refactoringAllowed ``` which gets translated to:
``` OpCapability Shader OpMemoryModel Logical GLSL450 OpEntryPoint Fragment %main "main" OpExecutionMode %main OriginUpperLeft OpName %main "main" %void = OpTypeVoid %3 = OpTypeFunction %void %main = OpFunction %void None %3 %4 = OpLabel OpFunctionEnd ```
This patch is to detect that the OpLabel has not been terminated by a corresponding top-level return, and add it.
-- v2: vkd3d-shader: Ensure that the OpLabel emitted vkd3d_spirv_builder_begin_main_function() gets terminated.
From: Jan Sikorski jsikorski@codeweavers.com
--- libs/vkd3d-shader/spirv.c | 7 +++++++ 1 file changed, 7 insertions(+)
diff --git a/libs/vkd3d-shader/spirv.c b/libs/vkd3d-shader/spirv.c index ed24e743..9606902b 100644 --- a/libs/vkd3d-shader/spirv.c +++ b/libs/vkd3d-shader/spirv.c @@ -2247,6 +2247,7 @@ struct spirv_compiler struct vkd3d_push_constant_buffer_binding *push_constants; const struct vkd3d_shader_spirv_target_info *spirv_target_info;
+ bool main_block_open; bool after_declarations_section; struct shader_signature input_signature; struct shader_signature output_signature; @@ -5216,6 +5217,7 @@ static void spirv_compiler_emit_initial_declarations(struct spirv_compiler *comp if (compiler->shader_type != VKD3D_SHADER_TYPE_HULL) { vkd3d_spirv_builder_begin_main_function(builder); + compiler->main_block_open = true; } }
@@ -7511,6 +7513,8 @@ static int spirv_compiler_emit_control_flow_instruction(struct spirv_compiler *c
if (cf_info) cf_info->inside_block = false; + else + compiler->main_block_open = false; break;
case VKD3DSIH_RETP: @@ -9471,6 +9475,9 @@ static int spirv_compiler_generate_spirv(struct spirv_compiler *compiler, if (result < 0) return result;
+ if (compiler->main_block_open) + vkd3d_spirv_build_op_return(builder); + if (!is_in_default_phase(compiler)) spirv_compiler_leave_shader_phase(compiler); else