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
42b2bc204f
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -201,6 +201,7 @@ Device::Device(Core::Frontend::EmuWindow& emu_window) {
|
|||
use_asynchronous_shaders = Settings::values.use_asynchronous_shaders.GetValue() &&
|
||||
!(is_amd || (is_intel && !is_linux)) && !strict_context_required;
|
||||
use_driver_cache = is_nvidia;
|
||||
supports_conditional_barriers = !is_intel;
|
||||
|
||||
LOG_INFO(Render_OpenGL, "Renderer_VariableAOFFI: {}", has_variable_aoffi);
|
||||
LOG_INFO(Render_OpenGL, "Renderer_ComponentIndexingBug: {}", has_component_indexing_bug);
|
||||
|
|
|
@ -188,6 +188,10 @@ public:
|
|||
return strict_context_required;
|
||||
}
|
||||
|
||||
bool SupportsConditionalBarriers() const {
|
||||
return supports_conditional_barriers;
|
||||
}
|
||||
|
||||
private:
|
||||
static bool TestVariableAoffi();
|
||||
static bool TestPreciseBug();
|
||||
|
@ -233,6 +237,7 @@ private:
|
|||
bool has_bool_ref_bug{};
|
||||
bool can_report_memory{};
|
||||
bool strict_context_required{};
|
||||
bool supports_conditional_barriers{};
|
||||
|
||||
std::string vendor_name;
|
||||
};
|
||||
|
|
|
@ -239,6 +239,7 @@ ShaderCache::ShaderCache(RasterizerOpenGL& rasterizer_, Core::Frontend::EmuWindo
|
|||
.support_snorm_render_buffer = false,
|
||||
.support_viewport_index_layer = device.HasVertexViewportLayer(),
|
||||
.support_geometry_shader_passthrough = device.HasGeometryShaderPassthrough(),
|
||||
.support_conditional_barrier = device.SupportsConditionalBarriers(),
|
||||
} {
|
||||
if (use_asynchronous_shaders) {
|
||||
workers = CreateWorkers();
|
||||
|
|
|
@ -386,6 +386,8 @@ Device::Device(VkInstance instance_, vk::PhysicalDevice physical_, VkSurfaceKHR
|
|||
IsFormatSupported(VK_FORMAT_D24_UNORM_S8_UINT,
|
||||
VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT, FormatType::Optimal);
|
||||
|
||||
supports_conditional_barriers = !(is_intel_anv || is_intel_windows);
|
||||
|
||||
CollectPhysicalMemoryInfo();
|
||||
CollectToolingInfo();
|
||||
|
||||
|
|
|
@ -585,6 +585,10 @@ public:
|
|||
return properties.properties.limits.maxVertexInputBindings;
|
||||
}
|
||||
|
||||
bool SupportsConditionalBarriers() const {
|
||||
return supports_conditional_barriers;
|
||||
}
|
||||
|
||||
private:
|
||||
/// Checks if the physical device is suitable and configures the object state
|
||||
/// with all necessary info about its properties.
|
||||
|
@ -688,6 +692,7 @@ private:
|
|||
bool must_emulate_bgr565{}; ///< Emulates BGR565 by swizzling RGB565 format.
|
||||
bool dynamic_state3_blending{}; ///< Has all blending features of dynamic_state3.
|
||||
bool dynamic_state3_enables{}; ///< Has all enables features of dynamic_state3.
|
||||
bool supports_conditional_barriers{}; ///< Allows barriers in conditional control flow.
|
||||
u64 device_access_memory{}; ///< Total size of device local memory in bytes.
|
||||
u32 sets_per_pool{}; ///< Sets per Description Pool
|
||||
|
||||
|
|
Loading…
Reference in New Issue