From abc158cdfe440b96d0cb86eb825d8bfa2b6e0f40 Mon Sep 17 00:00:00 2001 From: FernandoS27 Date: Mon, 4 Jan 2021 16:17:13 +0100 Subject: [PATCH] ShaderIR: interpret kill as a return abort in non fragment shaders. --- .../renderer_opengl/gl_arb_decompiler.cpp | 10 +++++++++- .../renderer_opengl/gl_shader_decompiler.cpp | 12 ++++++++++-- .../renderer_vulkan/vk_shader_decompiler.cpp | 18 +++++++++++++----- 3 files changed, 32 insertions(+), 8 deletions(-) diff --git a/src/video_core/renderer_opengl/gl_arb_decompiler.cpp b/src/video_core/renderer_opengl/gl_arb_decompiler.cpp index edbde8b0c9..84b8a3243b 100644 --- a/src/video_core/renderer_opengl/gl_arb_decompiler.cpp +++ b/src/video_core/renderer_opengl/gl_arb_decompiler.cpp @@ -1193,7 +1193,11 @@ void ARBDecompiler::VisitAST(const ASTNode& node) { ResetTemporaries(); } if (ast_return->kills) { - AddLine("KIL TR;"); + if (stage == ShaderType::Fragment) { + AddLine("KIL TR;"); + } else { + AddLine("RET;"); + } } else { Exit(); } @@ -2082,6 +2086,10 @@ std::string ARBDecompiler::Exit(Operation) { } std::string ARBDecompiler::Discard(Operation) { + if (stage != ShaderType::Fragment) { + AddLine("RET;"); + return {}; + } AddLine("KIL TR;"); return {}; } diff --git a/src/video_core/renderer_opengl/gl_shader_decompiler.cpp b/src/video_core/renderer_opengl/gl_shader_decompiler.cpp index 5404a388ea..b0a23724d0 100644 --- a/src/video_core/renderer_opengl/gl_shader_decompiler.cpp +++ b/src/video_core/renderer_opengl/gl_shader_decompiler.cpp @@ -2305,7 +2305,11 @@ private: // about unexecuted instructions that may follow this. code.AddLine("if (true) {{"); ++code.scope; - code.AddLine("discard;"); + if (stage != ShaderType::Fragment) { + code.AddLine("return;"); + } else { + code.AddLine("discard;"); + } --code.scope; code.AddLine("}}"); return {}; @@ -2932,7 +2936,11 @@ public: decomp.code.scope++; } if (ast.kills) { - decomp.code.AddLine("discard;"); + if (decomp.stage != ShaderType::Fragment) { + decomp.code.AddLine("return;"); + } else { + decomp.code.AddLine("discard;"); + } } else { if (decomp.context_func->IsMain()) { decomp.PreExit(); diff --git a/src/video_core/renderer_vulkan/vk_shader_decompiler.cpp b/src/video_core/renderer_vulkan/vk_shader_decompiler.cpp index 7e8a228e3d..67f519870b 100644 --- a/src/video_core/renderer_vulkan/vk_shader_decompiler.cpp +++ b/src/video_core/renderer_vulkan/vk_shader_decompiler.cpp @@ -591,6 +591,14 @@ private: DeclareOutputVertex(); } + void SafeKill() { + if (stage != ShaderType::Fragment) { + OpReturn(); + return; + } + OpKill(); + } + void DeclareFragment() { if (stage != ShaderType::Fragment) { return; @@ -2126,7 +2134,7 @@ private: OpBranchConditional(condition, true_label, discard_label); AddLabel(discard_label); - OpKill(); + SafeKill(); AddLabel(true_label); } @@ -2196,12 +2204,12 @@ private: Expression Discard(Operation operation) { inside_branch = true; if (conditional_branch_set) { - OpKill(); + SafeKill(); } else { const Id dummy = OpLabel(); OpBranch(dummy); AddLabel(dummy); - OpKill(); + SafeKill(); AddLabel(); } return {}; @@ -3053,7 +3061,7 @@ public: decomp.OpBranchConditional(condition, then_label, endif_label); decomp.AddLabel(then_label); if (ast.kills) { - decomp.OpKill(); + decomp.SafeKill(); } else { if (decomp.context_func->IsMain()) { decomp.PreExit(); @@ -3066,7 +3074,7 @@ public: decomp.OpBranch(next_block); decomp.AddLabel(next_block); if (ast.kills) { - decomp.OpKill(); + decomp.SafeKill(); } else { if (decomp.context_func->IsMain()) { decomp.PreExit();