mirror of
https://git.eden-emu.dev/eden-emu/eden
synced 2026-04-27 22:18:57 +02:00
[spirv] nuke spirv-opt (#3877)
lots of AGILEism in spirv-opt theres BETTER alternatives like https://github.com/renderbag/re-spirv (im not gonna bother for now, it probably has shitty build system) it sucks the IR already resolves most of the shader code to just constant load/stores Spirv-opt passes do not seem to make such a big difference only introduce extra latency like for example cbuf pass in IR already removes a lot of code, that spirv_opt would otherwise miss due to the fact it doesn't have cbuf information Signed-off-by: lizzie <lizzie@eden-emu.dev> Co-authored-by: crueter <crueter@eden-emu.dev> Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/3877 Reviewed-by: CamilleLaVey <camillelavey99@gmail.com> Reviewed-by: crueter <crueter@eden-emu.dev>
This commit is contained in:
parent
bd6dd7ecec
commit
17e2be173c
19 changed files with 14 additions and 431 deletions
|
|
@ -24,7 +24,6 @@ enum class IntSetting(override val key: String) : AbstractIntSetting {
|
|||
RENDERER_ANTI_ALIASING("anti_aliasing"),
|
||||
RENDERER_SCREEN_LAYOUT("screen_layout"),
|
||||
RENDERER_ASPECT_RATIO("aspect_ratio"),
|
||||
RENDERER_OPTIMIZE_SPIRV_OUTPUT("optimize_spirv_output"),
|
||||
|
||||
RENDERER_DYNA_STATE("dyna_state"),
|
||||
DMA_ACCURACY("dma_accuracy"),
|
||||
|
|
|
|||
|
|
@ -643,15 +643,6 @@ abstract class SettingsItem(
|
|||
descriptionId = R.string.renderer_async_presentation_description
|
||||
)
|
||||
)
|
||||
put(
|
||||
SingleChoiceSetting(
|
||||
IntSetting.RENDERER_OPTIMIZE_SPIRV_OUTPUT,
|
||||
titleId = R.string.renderer_optimize_spirv_output,
|
||||
descriptionId = R.string.renderer_optimize_spirv_output_description,
|
||||
choicesId = R.array.optimizeSpirvOutputEntries,
|
||||
valuesId = R.array.optimizeSpirvOutputValues
|
||||
)
|
||||
)
|
||||
put(
|
||||
SingleChoiceSetting(
|
||||
IntSetting.DMA_ACCURACY,
|
||||
|
|
|
|||
|
|
@ -271,7 +271,6 @@ class SettingsFragmentPresenter(
|
|||
add(IntSetting.FSR_SHARPENING_SLIDER.key)
|
||||
}
|
||||
add(IntSetting.RENDERER_ANTI_ALIASING.key)
|
||||
add(IntSetting.RENDERER_OPTIMIZE_SPIRV_OUTPUT.key)
|
||||
|
||||
add(HeaderSetting(R.string.advanced))
|
||||
|
||||
|
|
|
|||
|
|
@ -388,10 +388,6 @@ struct Values {
|
|||
true,
|
||||
true};
|
||||
|
||||
SwitchableSetting<SpirvOptimizeMode, true> optimize_spirv_output{linkage,
|
||||
SpirvOptimizeMode::Never,
|
||||
"optimize_spirv_output",
|
||||
Category::Renderer};
|
||||
SwitchableSetting<bool> use_asynchronous_gpu_emulation{
|
||||
linkage, true, "use_asynchronous_gpu_emulation", Category::Renderer};
|
||||
// *nix platforms may have issues with the borderless windowed fullscreen mode.
|
||||
|
|
|
|||
|
|
@ -165,10 +165,6 @@ std::unique_ptr<TranslationMap> InitializeTranslations(QObject* parent) {
|
|||
INSERT(Settings, use_disk_shader_cache, tr("Use persistent pipeline cache"),
|
||||
tr("Allows saving shaders to storage for faster loading on following game "
|
||||
"boots.\nDisabling it is only intended for debugging."));
|
||||
INSERT(Settings, optimize_spirv_output, tr("Optimize SPIRV output"),
|
||||
tr("Runs an additional optimization pass over generated SPIRV shaders.\n"
|
||||
"Will increase time required for shader compilation.\nMay slightly improve "
|
||||
"performance.\nThis feature is experimental."));
|
||||
INSERT(Settings, use_asynchronous_gpu_emulation, tr("Use asynchronous GPU emulation"),
|
||||
tr("Uses an extra CPU thread for rendering.\nThis option should always remain enabled."));
|
||||
INSERT(Settings, nvdec_emulation, tr("NVDEC emulation:"),
|
||||
|
|
|
|||
|
|
@ -243,7 +243,7 @@ add_library(shader_recompiler STATIC
|
|||
|
||||
)
|
||||
|
||||
target_link_libraries(shader_recompiler PUBLIC common fmt::fmt sirit::sirit SPIRV-Tools::SPIRV-Tools)
|
||||
target_link_libraries(shader_recompiler PUBLIC common fmt::fmt sirit::sirit)
|
||||
|
||||
if (MSVC)
|
||||
target_compile_options(shader_recompiler PRIVATE
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
|
||||
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
// SPDX-FileCopyrightText: Copyright 2021 yuzu Emulator Project
|
||||
|
|
@ -9,7 +9,6 @@
|
|||
#include <type_traits>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
#include <spirv-tools/optimizer.hpp>
|
||||
|
||||
#include "common/settings.h"
|
||||
#include "shader_recompiler/backend/spirv/emit_spirv.h"
|
||||
|
|
@ -22,15 +21,7 @@ namespace Shader::Backend::SPIRV {
|
|||
namespace {
|
||||
template <class Func>
|
||||
struct FuncTraits {};
|
||||
thread_local std::unique_ptr<spvtools::Optimizer> thread_optimizer;
|
||||
|
||||
spvtools::Optimizer& GetThreadOptimizer() {
|
||||
if (!thread_optimizer) {
|
||||
thread_optimizer = std::make_unique<spvtools::Optimizer>(SPV_ENV_VULKAN_1_3);
|
||||
thread_optimizer->RegisterPerformancePasses();
|
||||
}
|
||||
return *thread_optimizer;
|
||||
}
|
||||
template <class ReturnType_, class... Args>
|
||||
struct FuncTraits<ReturnType_ (*)(Args...)> {
|
||||
using ReturnType = ReturnType_;
|
||||
|
|
@ -501,8 +492,7 @@ void PatchPhiNodes(IR::Program& program, EmitContext& ctx) {
|
|||
}
|
||||
} // Anonymous namespace
|
||||
|
||||
std::vector<u32> EmitSPIRV(const Profile& profile, const RuntimeInfo& runtime_info,
|
||||
IR::Program& program, Bindings& bindings, bool optimize) {
|
||||
std::vector<u32> EmitSPIRV(const Profile& profile, const RuntimeInfo& runtime_info, IR::Program& program, Bindings& bindings) {
|
||||
EmitContext ctx{profile, runtime_info, program, bindings};
|
||||
const Id main{DefineMain(ctx, program)};
|
||||
DefineEntryPoint(program, ctx, main);
|
||||
|
|
@ -514,29 +504,7 @@ std::vector<u32> EmitSPIRV(const Profile& profile, const RuntimeInfo& runtime_in
|
|||
SetupCapabilities(profile, program.info, ctx);
|
||||
SetupTransformFeedbackCapabilities(ctx, main);
|
||||
PatchPhiNodes(program, ctx);
|
||||
|
||||
if (!optimize) {
|
||||
return ctx.Assemble();
|
||||
} else {
|
||||
std::vector<u32> spirv = ctx.Assemble();
|
||||
|
||||
// Use thread-local optimizer instead of creating a new one
|
||||
auto& spv_opt = GetThreadOptimizer();
|
||||
spv_opt.SetMessageConsumer([](spv_message_level_t, const char*, const spv_position_t&, const char* m) {
|
||||
LOG_ERROR(HW_GPU, "spirv-opt: {}", m);
|
||||
});
|
||||
|
||||
spvtools::OptimizerOptions opt_options;
|
||||
opt_options.set_run_validator(false);
|
||||
|
||||
std::vector<u32> result;
|
||||
if (!spv_opt.Run(spirv.data(), spirv.size(), &result, opt_options)) {
|
||||
LOG_ERROR(HW_GPU,
|
||||
"Failed to optimize SPIRV shader output, continuing without optimization");
|
||||
result = std::move(spirv);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
return ctx.Assemble();
|
||||
}
|
||||
|
||||
Id EmitPhi(EmitContext& ctx, IR::Inst* inst) {
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
|
||||
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
// SPDX-FileCopyrightText: Copyright 2021 yuzu Emulator Project
|
||||
|
|
@ -33,13 +33,10 @@ constexpr u32 RESCALING_LAYOUT_WORDS_OFFSET = offsetof(RescalingLayout, rescalin
|
|||
constexpr u32 RESCALING_LAYOUT_DOWN_FACTOR_OFFSET = offsetof(RescalingLayout, down_factor);
|
||||
constexpr u32 RENDERAREA_LAYOUT_OFFSET = offsetof(RenderAreaLayout, render_area);
|
||||
|
||||
[[nodiscard]] std::vector<u32> EmitSPIRV(const Profile& profile, const RuntimeInfo& runtime_info,
|
||||
IR::Program& program, Bindings& bindings, bool optimize);
|
||||
|
||||
[[nodiscard]] inline std::vector<u32> EmitSPIRV(const Profile& profile, IR::Program& program,
|
||||
bool optimize) {
|
||||
[[nodiscard]] std::vector<u32> EmitSPIRV(const Profile& profile, const RuntimeInfo& runtime_info, IR::Program& program, Bindings& bindings);
|
||||
[[nodiscard]] inline std::vector<u32> EmitSPIRV(const Profile& profile, IR::Program& program) {
|
||||
Bindings binding;
|
||||
return EmitSPIRV(profile, {}, program, binding, optimize);
|
||||
return EmitSPIRV(profile, {}, program, binding);
|
||||
}
|
||||
|
||||
} // namespace Shader::Backend::SPIRV
|
||||
|
|
|
|||
|
|
@ -181,7 +181,6 @@ ShaderCache::ShaderCache(Tegra::MaxwellDeviceMemoryManager& device_memory_,
|
|||
state_tracker{state_tracker_}, shader_notify{shader_notify_},
|
||||
use_asynchronous_shaders{device.UseAsynchronousShaders()},
|
||||
strict_context_required{device.StrictContextRequired()},
|
||||
optimize_spirv_output{Settings::values.optimize_spirv_output.GetValue() != Settings::SpirvOptimizeMode::Never},
|
||||
profile{
|
||||
.supported_spirv = 0x00010000,
|
||||
|
||||
|
|
@ -348,10 +347,6 @@ void ShaderCache::LoadDiskResources(u64 title_id, std::stop_token stop_loading,
|
|||
if (!use_asynchronous_shaders) {
|
||||
workers.reset();
|
||||
}
|
||||
|
||||
if (Settings::values.optimize_spirv_output.GetValue() != Settings::SpirvOptimizeMode::Always) {
|
||||
this->optimize_spirv_output = false;
|
||||
}
|
||||
}
|
||||
|
||||
GraphicsPipeline* ShaderCache::CurrentGraphicsPipeline() {
|
||||
|
|
@ -537,7 +532,7 @@ std::unique_ptr<GraphicsPipeline> ShaderCache::CreateGraphicsPipeline(
|
|||
break;
|
||||
case Settings::RendererBackend::OpenGL_SPIRV:
|
||||
ConvertLegacyToGeneric(program, runtime_info);
|
||||
sources_spirv[stage_index] = EmitSPIRV(profile, runtime_info, program, binding, this->optimize_spirv_output);
|
||||
sources_spirv[stage_index] = EmitSPIRV(profile, runtime_info, program, binding);
|
||||
break;
|
||||
default:
|
||||
UNREACHABLE();
|
||||
|
|
@ -598,7 +593,7 @@ std::unique_ptr<ComputePipeline> ShaderCache::CreateComputePipeline(
|
|||
code = EmitGLASM(profile, info, program);
|
||||
break;
|
||||
case Settings::RendererBackend::OpenGL_SPIRV:
|
||||
code_spirv = EmitSPIRV(profile, program, this->optimize_spirv_output);
|
||||
code_spirv = EmitSPIRV(profile, program);
|
||||
break;
|
||||
default:
|
||||
UNREACHABLE();
|
||||
|
|
|
|||
|
|
@ -76,7 +76,6 @@ private:
|
|||
VideoCore::ShaderNotify& shader_notify;
|
||||
const bool use_asynchronous_shaders;
|
||||
const bool strict_context_required;
|
||||
bool optimize_spirv_output{};
|
||||
|
||||
GraphicsPipelineKey graphics_key{};
|
||||
GraphicsPipeline* current_pipeline{};
|
||||
|
|
|
|||
|
|
@ -369,7 +369,6 @@ PipelineCache::PipelineCache(Tegra::MaxwellDeviceMemoryManager& device_memory_,
|
|||
texture_cache{texture_cache_}, shader_notify{shader_notify_},
|
||||
use_asynchronous_shaders{Settings::values.use_asynchronous_shaders.GetValue()},
|
||||
use_vulkan_pipeline_cache{Settings::values.use_vulkan_driver_pipeline_cache.GetValue()},
|
||||
optimize_spirv_output{Settings::values.optimize_spirv_output.GetValue() != Settings::SpirvOptimizeMode::Never},
|
||||
workers(device.HasBrokenParallelShaderCompiling() ? 1ULL : GetTotalPipelineWorkers(),
|
||||
"VkPipelineBuilder"),
|
||||
serialization_thread(1, "VkPipelineSerialization") {
|
||||
|
|
@ -669,10 +668,6 @@ void PipelineCache::LoadDiskResources(u64 title_id, std::stop_token stop_loading
|
|||
if (state.statistics) {
|
||||
state.statistics->Report();
|
||||
}
|
||||
|
||||
if (Settings::values.optimize_spirv_output.GetValue() != Settings::SpirvOptimizeMode::Always) {
|
||||
this->optimize_spirv_output = false;
|
||||
}
|
||||
}
|
||||
|
||||
GraphicsPipeline* PipelineCache::CurrentGraphicsPipelineSlowPath() {
|
||||
|
|
@ -777,7 +772,7 @@ std::unique_ptr<GraphicsPipeline> PipelineCache::CreateGraphicsPipeline(
|
|||
|
||||
const auto runtime_info{MakeRuntimeInfo(programs, key, program, previous_stage, device)};
|
||||
ConvertLegacyToGeneric(program, runtime_info);
|
||||
const std::vector<u32> code{EmitSPIRV(profile, runtime_info, program, binding, this->optimize_spirv_output)};
|
||||
const std::vector<u32> code{EmitSPIRV(profile, runtime_info, program, binding)};
|
||||
device.SaveShader(code);
|
||||
modules[stage_index] = BuildShader(device, code);
|
||||
|
||||
|
|
@ -895,7 +890,7 @@ std::unique_ptr<ComputePipeline> PipelineCache::CreateComputePipeline(
|
|||
max_shared_memory / 1024);
|
||||
program.shared_memory_size = max_shared_memory;
|
||||
}
|
||||
const std::vector<u32> code{EmitSPIRV(profile, program, this->optimize_spirv_output)};
|
||||
const std::vector<u32> code{EmitSPIRV(profile, program)};
|
||||
device.SaveShader(code);
|
||||
vk::ShaderModule spv_module{BuildShader(device, code)};
|
||||
|
||||
|
|
|
|||
|
|
@ -153,7 +153,6 @@ private:
|
|||
VideoCore::ShaderNotify& shader_notify;
|
||||
bool use_asynchronous_shaders{};
|
||||
bool use_vulkan_pipeline_cache{};
|
||||
bool optimize_spirv_output{};
|
||||
|
||||
GraphicsPipelineCacheKey graphics_key{};
|
||||
GraphicsPipeline* current_pipeline{};
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue