From 2bb7ea436dc74f812a8092201dc597ed58ff3c7a Mon Sep 17 00:00:00 2001
From: Liam <byteslice@airmail.cc>
Date: Sat, 10 Jun 2023 11:40:58 -0400
Subject: shader_recompiler: remove barriers in conditional control flow when
 device lacks support

---
 .../ir_opt/conditional_barrier_pass.cpp            | 44 ++++++++++++++++++++++
 1 file changed, 44 insertions(+)
 create mode 100644 src/shader_recompiler/ir_opt/conditional_barrier_pass.cpp

(limited to 'src/shader_recompiler/ir_opt/conditional_barrier_pass.cpp')

diff --git a/src/shader_recompiler/ir_opt/conditional_barrier_pass.cpp b/src/shader_recompiler/ir_opt/conditional_barrier_pass.cpp
new file mode 100644
index 0000000000..c3ed27f4f2
--- /dev/null
+++ b/src/shader_recompiler/ir_opt/conditional_barrier_pass.cpp
@@ -0,0 +1,44 @@
+// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
+// SPDX-License-Identifier: GPL-2.0-or-later
+
+#include "shader_recompiler/frontend/ir/program.h"
+#include "shader_recompiler/ir_opt/passes.h"
+
+namespace Shader::Optimization {
+
+void ConditionalBarrierPass(IR::Program& program) {
+    s32 conditional_control_flow_count{0};
+    s32 conditional_return_count{0};
+    for (IR::AbstractSyntaxNode& node : program.syntax_list) {
+        switch (node.type) {
+        case IR::AbstractSyntaxNode::Type::If:
+        case IR::AbstractSyntaxNode::Type::Loop:
+            conditional_control_flow_count++;
+            break;
+        case IR::AbstractSyntaxNode::Type::EndIf:
+        case IR::AbstractSyntaxNode::Type::Repeat:
+            conditional_control_flow_count--;
+            break;
+        case IR::AbstractSyntaxNode::Type::Unreachable:
+        case IR::AbstractSyntaxNode::Type::Return:
+            if (conditional_control_flow_count > 0) {
+                conditional_return_count++;
+            }
+            break;
+        case IR::AbstractSyntaxNode::Type::Block:
+            for (IR::Inst& inst : node.data.block->Instructions()) {
+                if ((conditional_control_flow_count > 0 || conditional_return_count > 0) &&
+                    inst.GetOpcode() == IR::Opcode::Barrier) {
+                    LOG_WARNING(Shader, "Barrier within conditional control flow");
+                    inst.ReplaceOpcode(IR::Opcode::Identity);
+                }
+            }
+            break;
+        default:
+            break;
+        }
+    }
+    ASSERT(conditional_control_flow_count == 0);
+}
+
+} // namespace Shader::Optimization
-- 
cgit v1.2.3-70-g09d2