diff --git a/src/citra_qt/configuration/config.cpp b/src/citra_qt/configuration/config.cpp index 601e2616f..4de8281e7 100644 --- a/src/citra_qt/configuration/config.cpp +++ b/src/citra_qt/configuration/config.cpp @@ -605,6 +605,7 @@ void Config::ReadRendererValues() { ReadGlobalSetting(Settings::values.physical_device); ReadGlobalSetting(Settings::values.async_command_recording); + ReadGlobalSetting(Settings::values.spirv_shader_gen); ReadGlobalSetting(Settings::values.graphics_api); ReadGlobalSetting(Settings::values.use_hw_renderer); ReadGlobalSetting(Settings::values.use_hw_shader); @@ -1087,6 +1088,7 @@ void Config::SaveRendererValues() { WriteGlobalSetting(Settings::values.graphics_api); WriteGlobalSetting(Settings::values.physical_device); WriteGlobalSetting(Settings::values.async_command_recording); + WriteGlobalSetting(Settings::values.spirv_shader_gen); WriteGlobalSetting(Settings::values.use_hw_renderer); WriteGlobalSetting(Settings::values.use_hw_shader); #ifdef __APPLE__ diff --git a/src/citra_qt/configuration/configure_graphics.cpp b/src/citra_qt/configuration/configure_graphics.cpp index c79eb3d09..f63331791 100644 --- a/src/citra_qt/configuration/configure_graphics.cpp +++ b/src/citra_qt/configuration/configure_graphics.cpp @@ -86,6 +86,7 @@ void ConfigureGraphics::SetConfiguration() { ui->graphics_api_combo->setCurrentIndex(static_cast(Settings::values.graphics_api.GetValue())); ui->physical_device_combo->setCurrentIndex(static_cast(Settings::values.physical_device.GetValue())); ui->toggle_async_recording->setChecked(Settings::values.async_command_recording.GetValue()); + ui->spirv_shader_gen->setChecked(Settings::values.spirv_shader_gen.GetValue()); if (Settings::IsConfiguringGlobal()) { ui->toggle_shader_jit->setChecked(Settings::values.use_shader_jit.GetValue()); @@ -109,6 +110,8 @@ void ConfigureGraphics::ApplyConfiguration() { ConfigurationShared::ApplyPerGameSetting(&Settings::values.physical_device, ui->physical_device_combo); ConfigurationShared::ApplyPerGameSetting(&Settings::values.async_command_recording, ui->toggle_async_recording, async_command_recording); + ConfigurationShared::ApplyPerGameSetting(&Settings::values.spirv_shader_gen, ui->spirv_shader_gen, + spirv_shader_gen); if (Settings::IsConfiguringGlobal()) { Settings::values.use_shader_jit = ui->toggle_shader_jit->isChecked(); @@ -165,4 +168,9 @@ void ConfigureGraphics::SetPhysicalDeviceComboVisibility(int index) { const bool is_visible = graphics_api == Settings::GraphicsAPI::Vulkan; ui->physical_device_label->setVisible(is_visible); ui->physical_device_combo->setVisible(is_visible); -} \ No newline at end of file +<<<<<<< HEAD +} +======= + ui->spirv_shader_gen->setVisible(is_visible); +} +>>>>>>> 25502ebc8 (citra_qt: Add SPIR-V shader option) diff --git a/src/citra_qt/configuration/configure_graphics.h b/src/citra_qt/configuration/configure_graphics.h index 61563dc78..f8783ee90 100644 --- a/src/citra_qt/configuration/configure_graphics.h +++ b/src/citra_qt/configuration/configure_graphics.h @@ -41,6 +41,7 @@ private: ConfigurationShared::CheckState use_disk_shader_cache; ConfigurationShared::CheckState use_vsync_new; ConfigurationShared::CheckState async_command_recording; + ConfigurationShared::CheckState spirv_shader_gen; std::unique_ptr ui; QColor bg_color; }; diff --git a/src/citra_qt/configuration/configure_graphics.ui b/src/citra_qt/configuration/configure_graphics.ui index 81fe84d5e..313cb82b1 100644 --- a/src/citra_qt/configuration/configure_graphics.ui +++ b/src/citra_qt/configuration/configure_graphics.ui @@ -7,7 +7,7 @@ 0 0 400 - 430 + 513 @@ -70,6 +70,13 @@ + + + + SPIR-V Shader Generation + + + diff --git a/src/common/settings.h b/src/common/settings.h index 7109a7769..12aa11ae5 100644 --- a/src/common/settings.h +++ b/src/common/settings.h @@ -448,6 +448,7 @@ struct Values { // Renderer SwitchableSetting graphics_api{GraphicsAPI::OpenGL, "graphics_api"}; SwitchableSetting physical_device{0, "physical_device"}; + SwitchableSetting spirv_shader_gen{true, "spirv_shader_gen"}; Setting renderer_debug{false, "renderer_debug"}; Setting dump_command_buffers{false, "dump_command_buffers"}; SwitchableSetting async_command_recording{true, "async_command_recording"}; diff --git a/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp b/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp index ee64fbf0b..aac3b0860 100644 --- a/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp +++ b/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp @@ -92,7 +92,11 @@ PipelineCache::~PipelineCache() { device.destroyShaderModule(module); } - for (auto& [key, module] : fragment_shaders.shaders) { + for (auto& [key, module] : fragment_shaders_glsl.shaders) { + device.destroyShaderModule(module); + } + + for (auto& [key, module] : fragment_shaders_spv.shaders) { device.destroyShaderModule(module); } @@ -244,12 +248,21 @@ void PipelineCache::UseTrivialGeometryShader() { }); } +MICROPROFILE_DEFINE(Vulkan_FragmentGeneration, "Vulkan", "Fragment Shader Compilation", MP_RGB(255, 100, 100)); void PipelineCache::UseFragmentShader(const Pica::Regs& regs) { const PicaFSConfig config{regs, instance}; scheduler.Record([this, config](vk::CommandBuffer, vk::CommandBuffer) { - vk::ShaderModule handle = fragment_shaders.Get(config, vk::ShaderStageFlagBits::eFragment, - instance.GetDevice(), ShaderOptimization::Debug); + MICROPROFILE_SCOPE(Vulkan_FragmentGeneration); + + vk::ShaderModule handle{}; + if (Settings::values.spirv_shader_gen) { + handle = fragment_shaders_spv.Get(config, instance.GetDevice()); + } else { + handle = fragment_shaders_glsl.Get(config, vk::ShaderStageFlagBits::eFragment, + instance.GetDevice(), ShaderOptimization::Debug); + } + current_shaders[ProgramType::FS] = handle; shader_hashes[ProgramType::FS] = config.Hash(); }); diff --git a/src/video_core/renderer_vulkan/vk_pipeline_cache.h b/src/video_core/renderer_vulkan/vk_pipeline_cache.h index 3ee58eaef..6893a9fe2 100644 --- a/src/video_core/renderer_vulkan/vk_pipeline_cache.h +++ b/src/video_core/renderer_vulkan/vk_pipeline_cache.h @@ -116,7 +116,10 @@ using ProgrammableVertexShaders = Pica::Shader::ShaderDoubleCache; -using FragmentShaders = +using FragmentShadersGLSL = + Pica::Shader::ShaderCache; + +using FragmentShadersSPV = Pica::Shader::ShaderCache; class Instance; @@ -217,7 +220,8 @@ private: std::array shader_hashes; ProgrammableVertexShaders programmable_vertex_shaders; FixedGeometryShaders fixed_geometry_shaders; - FragmentShaders fragment_shaders; + FragmentShadersGLSL fragment_shaders_glsl; + FragmentShadersSPV fragment_shaders_spv; vk::ShaderModule trivial_vertex_shader; }; diff --git a/src/video_core/renderer_vulkan/vk_shader_gen_spv.cpp b/src/video_core/renderer_vulkan/vk_shader_gen_spv.cpp index d4929d238..dd351c2f1 100644 --- a/src/video_core/renderer_vulkan/vk_shader_gen_spv.cpp +++ b/src/video_core/renderer_vulkan/vk_shader_gen_spv.cpp @@ -893,9 +893,7 @@ void FragmentModule::DefineInterface() { Decorate(gl_frag_depth_id, spv::Decoration::BuiltIn, spv::BuiltIn::FragDepth); } -MICROPROFILE_DEFINE(Vulkan_FragmentGenerationSPV, "Vulkan", "SPIRV Fragment Shader Compilation", MP_RGB(255, 100, 100)); std::vector GenerateFragmentShaderSPV(const PicaFSConfig& config) { - MICROPROFILE_SCOPE(Vulkan_FragmentGenerationSPV); FragmentModule module{config}; module.Generate(); return module.Assemble(); diff --git a/src/video_core/renderer_vulkan/vk_shader_util.cpp b/src/video_core/renderer_vulkan/vk_shader_util.cpp index 6d3e19607..76adadf44 100644 --- a/src/video_core/renderer_vulkan/vk_shader_util.cpp +++ b/src/video_core/renderer_vulkan/vk_shader_util.cpp @@ -6,6 +6,7 @@ #include #include #include "common/assert.h" +#include "common/microprofile.h" #include "common/logging/log.h" #include "video_core/renderer_vulkan/vk_shader_util.h" @@ -217,11 +218,12 @@ vk::ShaderModule Compile(std::string_view code, vk::ShaderStageFlagBits stage, v LOG_INFO(Render_Vulkan, "SPIR-V conversion messages: {}", spv_messages); } - return CompileSPV(out_code, stage, device, level); + return CompileSPV(out_code, device); } -vk::ShaderModule CompileSPV(std::vector code, vk::ShaderStageFlagBits stage, vk::Device device, - ShaderOptimization) { +MICROPROFILE_DEFINE(Vulkan_SPVCompilation, "Vulkan", "SPIR-V Shader Compilation", MP_RGB(100, 255, 52)); +vk::ShaderModule CompileSPV(std::vector code, vk::Device device) { + MICROPROFILE_SCOPE(Vulkan_SPVCompilation); const vk::ShaderModuleCreateInfo shader_info = {.codeSize = code.size() * sizeof(u32), .pCode = code.data()}; try { diff --git a/src/video_core/renderer_vulkan/vk_shader_util.h b/src/video_core/renderer_vulkan/vk_shader_util.h index 6ea356d8c..f21299948 100644 --- a/src/video_core/renderer_vulkan/vk_shader_util.h +++ b/src/video_core/renderer_vulkan/vk_shader_util.h @@ -13,7 +13,6 @@ enum class ShaderOptimization { High = 0, Debug = 1 }; vk::ShaderModule Compile(std::string_view code, vk::ShaderStageFlagBits stage, vk::Device device, ShaderOptimization level); -vk::ShaderModule CompileSPV(std::vector code, vk::ShaderStageFlagBits stage, vk::Device device, - ShaderOptimization level); +vk::ShaderModule CompileSPV(std::vector code, vk::Device device); } // namespace Vulkan diff --git a/src/video_core/renderer_vulkan/vk_texture_runtime.cpp b/src/video_core/renderer_vulkan/vk_texture_runtime.cpp index f52821fd4..539851b67 100644 --- a/src/video_core/renderer_vulkan/vk_texture_runtime.cpp +++ b/src/video_core/renderer_vulkan/vk_texture_runtime.cpp @@ -189,7 +189,14 @@ ImageAlloc TextureRuntime::Allocate(u32 width, u32 height, VideoCore::PixelForma .samples = vk::SampleCountFlagBits::e1, .usage = usage}; - const VmaAllocationCreateInfo alloc_info = {.usage = VMA_MEMORY_USAGE_AUTO_PREFER_DEVICE}; + const VmaAllocationCreateInfo alloc_info = { + .flags = VMA_ALLOCATION_CREATE_WITHIN_BUDGET_BIT, + .usage = VMA_MEMORY_USAGE_AUTO_PREFER_DEVICE, + .requiredFlags = 0, + .preferredFlags = 0, + .pool = VK_NULL_HANDLE, + .pUserData = nullptr, + }; VkImage unsafe_image{}; VkImageCreateInfo unsafe_image_info = static_cast(image_info);