Merge pull request #10699 from liamwhite/conditional-barrier
shader_recompiler: remove barriers in conditional control flow when device lacks support
This commit is contained in:
commit
28e1429daf
10 changed files with 65 additions and 0 deletions
|
@ -216,6 +216,7 @@ add_library(shader_recompiler STATIC
|
|||
frontend/maxwell/translate_program.h
|
||||
host_translate_info.h
|
||||
ir_opt/collect_shader_info_pass.cpp
|
||||
ir_opt/conditional_barrier_pass.cpp
|
||||
ir_opt/constant_propagation_pass.cpp
|
||||
ir_opt/dead_code_elimination_pass.cpp
|
||||
ir_opt/dual_vertex_pass.cpp
|
||||
|
|
|
@ -289,6 +289,9 @@ IR::Program TranslateProgram(ObjectPool<IR::Inst>& inst_pool, ObjectPool<IR::Blo
|
|||
if (!host_info.support_int64) {
|
||||
Optimization::LowerInt64ToInt32(program);
|
||||
}
|
||||
if (!host_info.support_conditional_barrier) {
|
||||
Optimization::ConditionalBarrierPass(program);
|
||||
}
|
||||
Optimization::SsaRewritePass(program);
|
||||
|
||||
Optimization::ConstantPropagationPass(env, program);
|
||||
|
|
|
@ -18,6 +18,8 @@ struct HostTranslateInfo {
|
|||
bool support_viewport_index_layer{}; ///< True when the device supports gl_Layer in VS
|
||||
bool support_geometry_shader_passthrough{}; ///< True when the device supports geometry
|
||||
///< passthrough shaders
|
||||
bool support_conditional_barrier{}; ///< True when the device supports barriers in conditional
|
||||
///< control flow
|
||||
};
|
||||
|
||||
} // namespace Shader
|
||||
|
|
44
src/shader_recompiler/ir_opt/conditional_barrier_pass.cpp
Normal file
44
src/shader_recompiler/ir_opt/conditional_barrier_pass.cpp
Normal file
|
@ -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
|
|
@ -13,6 +13,7 @@ struct HostTranslateInfo;
|
|||
namespace Shader::Optimization {
|
||||
|
||||
void CollectShaderInfoPass(Environment& env, IR::Program& program);
|
||||
void ConditionalBarrierPass(IR::Program& program);
|
||||
void ConstantPropagationPass(Environment& env, IR::Program& program);
|
||||
void DeadCodeEliminationPass(IR::Program& program);
|
||||
void GlobalMemoryToStorageBufferPass(IR::Program& program);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue