mirror of
https://github.com/mandarine3ds/mandarine.git
synced 2024-11-26 16:00:49 +00:00
video_core: Implement Vulkan SPIR-V Optimization on Desktop OSes
Some checks failed
mandarine-build / source (push) Has been cancelled
mandarine-build / linux (appimage) (push) Has been cancelled
mandarine-build / linux (fresh) (push) Has been cancelled
mandarine-build / macos (arm64) (push) Has been cancelled
mandarine-build / macos (x86_64) (push) Has been cancelled
mandarine-build / windows (msvc) (push) Has been cancelled
mandarine-build / windows (msys2) (push) Has been cancelled
mandarine-build / android (push) Has been cancelled
mandarine-format / clang-format (push) Has been cancelled
mandarine-build / macos-universal (push) Has been cancelled
mandarine-build / release (push) Has been cancelled
Some checks failed
mandarine-build / source (push) Has been cancelled
mandarine-build / linux (appimage) (push) Has been cancelled
mandarine-build / linux (fresh) (push) Has been cancelled
mandarine-build / macos (arm64) (push) Has been cancelled
mandarine-build / macos (x86_64) (push) Has been cancelled
mandarine-build / windows (msvc) (push) Has been cancelled
mandarine-build / windows (msys2) (push) Has been cancelled
mandarine-build / android (push) Has been cancelled
mandarine-format / clang-format (push) Has been cancelled
mandarine-build / macos-universal (push) Has been cancelled
mandarine-build / release (push) Has been cancelled
This commit is contained in:
parent
17422ff2c7
commit
e6f0b73d23
3
.gitmodules
vendored
3
.gitmodules
vendored
@ -94,3 +94,6 @@
|
||||
[submodule "externals/oboe"]
|
||||
path = externals/oboe
|
||||
url = https://github.com/google/oboe.git
|
||||
[submodule "externals/SPIRV-Tools"]
|
||||
path = externals/SPIRV-Tools
|
||||
url = https://github.com/KhronosGroup/SPIRV-Tools.git
|
||||
|
4
externals/CMakeLists.txt
vendored
4
externals/CMakeLists.txt
vendored
@ -427,6 +427,10 @@ if (ENABLE_VULKAN)
|
||||
target_include_directories(vulkan-headers SYSTEM INTERFACE ./vulkan-headers/include)
|
||||
endif()
|
||||
|
||||
# SPIRV-Tools
|
||||
add_library(SPIRV-Tools INTERFACE)
|
||||
target_include_directories(SPIRV-Tools SYSTEM INTERFACE ./SPIRV-Tools/include)
|
||||
|
||||
# adrenotools
|
||||
if (ANDROID AND "arm64" IN_LIST ARCHITECTURE)
|
||||
add_subdirectory(libadrenotools)
|
||||
|
1
externals/SPIRV-Tools
vendored
Submodule
1
externals/SPIRV-Tools
vendored
Submodule
@ -0,0 +1 @@
|
||||
Subproject commit 35e5f1160ecd2b963682e14e869001a60160a0c4
|
@ -471,6 +471,21 @@ struct Values {
|
||||
Setting<bool> renderer_debug{false, "renderer_debug"};
|
||||
Setting<bool> dump_command_buffers{false, "dump_command_buffers"};
|
||||
SwitchableSetting<bool> spirv_shader_gen{true, "spirv_shader_gen"};
|
||||
|
||||
// SPIR-V Optimization only works on Desktop OSes for now
|
||||
#ifdef __APPLE__
|
||||
#include <TargetConditionals.h>
|
||||
#if TARGET_OS_IPHONE
|
||||
SwitchableSetting<bool> optimize_spirv_output{false, "optimize_spirv_output"};
|
||||
#elif TARGET_OS_MAC
|
||||
SwitchableSetting<bool> optimize_spirv_output{true, "optimize_spirv_output"};
|
||||
#endif
|
||||
#elif __ANDROID__
|
||||
SwitchableSetting<bool> optimize_spirv_output{false, "optimize_spirv_output"};
|
||||
#else
|
||||
SwitchableSetting<bool> optimize_spirv_output{true, "optimize_spirv_output"};
|
||||
#endif
|
||||
|
||||
SwitchableSetting<bool> async_shader_compilation{false, "async_shader_compilation"};
|
||||
SwitchableSetting<bool> async_presentation{true, "async_presentation"};
|
||||
SwitchableSetting<bool> use_hw_shader{true, "use_hw_shader"};
|
||||
|
@ -3,12 +3,30 @@
|
||||
// Refer to the license.txt file included.
|
||||
|
||||
#include <memory>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
#include <SPIRV/GlslangToSpv.h>
|
||||
#include <glslang/Include/ResourceLimits.h>
|
||||
#include <glslang/Public/ShaderLang.h>
|
||||
|
||||
// The optimizer included in SPIRV-Tools only works on Desktop OSes
|
||||
#if defined(_WIN32) || (defined(__linux__) && !defined(__ANDROID__))
|
||||
#define OPTIMIZE_SPIRV
|
||||
#elif defined(__APPLE__)
|
||||
#include <TargetConditionals.h>
|
||||
#if TARGET_OS_OSX
|
||||
#define OPTIMIZE_SPIRV
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef OPTIMIZE_SPIRV
|
||||
#include <spirv-tools/optimizer.hpp>
|
||||
#endif
|
||||
|
||||
#include "common/assert.h"
|
||||
#include "common/literals.h"
|
||||
#include "common/logging/log.h"
|
||||
#include "common/settings.h"
|
||||
#include "video_core/renderer_vulkan/vk_shader_util.h"
|
||||
|
||||
namespace Vulkan {
|
||||
@ -159,6 +177,35 @@ bool InitializeCompiler() {
|
||||
}
|
||||
} // Anonymous namespace
|
||||
|
||||
/**
|
||||
* NOTE: The libraries included in SPIRV-Tools only work on Windows, Linux and MacOS.
|
||||
* @brief Optimizes SPIR-V code (but only on Desktop)
|
||||
* @param code The string containing SPIR-V code
|
||||
*/
|
||||
std::vector<u32> OptimizeSPIRV(std::vector<u32> code) {
|
||||
|
||||
std::vector<u32> result = code;
|
||||
|
||||
#ifdef OPTIMIZE_SPIRV
|
||||
std::vector<u32> spirv = code;
|
||||
spvtools::Optimizer spv_opt(SPV_ENV_VULKAN_1_3);
|
||||
spv_opt.SetMessageConsumer([](spv_message_level_t, const char*, const spv_position_t&,
|
||||
const char* m) { LOG_ERROR(HW_GPU, "spirv-opt: {}", m); });
|
||||
spv_opt.RegisterPerformancePasses();
|
||||
|
||||
spvtools::OptimizerOptions opt_options;
|
||||
opt_options.set_run_validator(false);
|
||||
|
||||
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);
|
||||
}
|
||||
#endif
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Compiles GLSL into SPIRV
|
||||
* @param code The string containing GLSL code.
|
||||
@ -222,7 +269,14 @@ std::vector<u32> CompileGLSLtoSPIRV(std::string_view code, vk::ShaderStageFlagBi
|
||||
LOG_INFO(Render_Vulkan, "SPIR-V conversion messages: {}", spv_messages);
|
||||
}
|
||||
|
||||
// Final pass through SPIRV-Optimizer
|
||||
if (!Settings::values.optimize_spirv_output.GetValue()) {
|
||||
return out_code;
|
||||
} else {
|
||||
std::vector<u32> result;
|
||||
result = OptimizeSPIRV(out_code);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
vk::ShaderModule Compile(std::string_view code, vk::ShaderStageFlagBits stage, vk::Device device,
|
||||
|
@ -10,6 +10,12 @@
|
||||
|
||||
namespace Vulkan {
|
||||
|
||||
/**
|
||||
* @brief Optimizes SPIR-V code
|
||||
* @param code The string containing SPIR-V code
|
||||
*/
|
||||
std::vector<u32> OptimizeSPIRV(std::vector<u32> code);
|
||||
|
||||
/**
|
||||
* @brief Compiles GLSL into SPIRV
|
||||
* @param code The string containing GLSL code.
|
||||
|
@ -3,6 +3,8 @@
|
||||
// Refer to the license.txt file included.
|
||||
|
||||
#include <boost/container/small_vector.hpp>
|
||||
#include "common/settings.h"
|
||||
#include "video_core/renderer_vulkan/vk_shader_util.h"
|
||||
#include "video_core/shader/generator/pica_fs_config.h"
|
||||
#include "video_core/shader/generator/spv_fs_shader_gen.h"
|
||||
|
||||
@ -1605,7 +1607,15 @@ void FragmentModule::DefineInterface() {
|
||||
std::vector<u32> GenerateFragmentShader(const FSConfig& config, const Profile& profile) {
|
||||
FragmentModule module{config, profile};
|
||||
module.Generate();
|
||||
|
||||
// Run through SPIRV-Optimizer
|
||||
if (!Settings::values.optimize_spirv_output.GetValue()) {
|
||||
return module.Assemble();
|
||||
} else {
|
||||
std::vector<u32> result;
|
||||
result = Vulkan::OptimizeSPIRV(module.Assemble());
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace Pica::Shader::Generator::SPIRV
|
||||
|
@ -2,7 +2,9 @@
|
||||
// Licensed under GPLv2 or any later version
|
||||
// Refer to the license.txt file included.
|
||||
|
||||
#include "common/settings.h"
|
||||
#include "video_core/pica/regs_rasterizer.h"
|
||||
#include "video_core/renderer_vulkan/vk_shader_util.h"
|
||||
#include "video_core/shader/generator/shader_gen.h"
|
||||
#include "video_core/shader/generator/spv_shader_gen.h"
|
||||
|
||||
@ -267,7 +269,15 @@ std::vector<u32> GenerateTrivialVertexShader(bool use_clip_planes) {
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// Run through SPIR-V Optimizer
|
||||
if (!Settings::values.optimize_spirv_output.GetValue()) {
|
||||
return module.Assemble();
|
||||
} else {
|
||||
std::vector<u32> result;
|
||||
result = Vulkan::OptimizeSPIRV(module.Assemble());
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace Pica::Shader::Generator::SPIRV
|
||||
|
Loading…
Reference in New Issue
Block a user