citra_qt: Add SPIR-V shader option
This commit is contained in:
@ -605,6 +605,7 @@ void Config::ReadRendererValues() {
|
|||||||
|
|
||||||
ReadGlobalSetting(Settings::values.physical_device);
|
ReadGlobalSetting(Settings::values.physical_device);
|
||||||
ReadGlobalSetting(Settings::values.async_command_recording);
|
ReadGlobalSetting(Settings::values.async_command_recording);
|
||||||
|
ReadGlobalSetting(Settings::values.spirv_shader_gen);
|
||||||
ReadGlobalSetting(Settings::values.graphics_api);
|
ReadGlobalSetting(Settings::values.graphics_api);
|
||||||
ReadGlobalSetting(Settings::values.use_hw_renderer);
|
ReadGlobalSetting(Settings::values.use_hw_renderer);
|
||||||
ReadGlobalSetting(Settings::values.use_hw_shader);
|
ReadGlobalSetting(Settings::values.use_hw_shader);
|
||||||
@ -1087,6 +1088,7 @@ void Config::SaveRendererValues() {
|
|||||||
WriteGlobalSetting(Settings::values.graphics_api);
|
WriteGlobalSetting(Settings::values.graphics_api);
|
||||||
WriteGlobalSetting(Settings::values.physical_device);
|
WriteGlobalSetting(Settings::values.physical_device);
|
||||||
WriteGlobalSetting(Settings::values.async_command_recording);
|
WriteGlobalSetting(Settings::values.async_command_recording);
|
||||||
|
WriteGlobalSetting(Settings::values.spirv_shader_gen);
|
||||||
WriteGlobalSetting(Settings::values.use_hw_renderer);
|
WriteGlobalSetting(Settings::values.use_hw_renderer);
|
||||||
WriteGlobalSetting(Settings::values.use_hw_shader);
|
WriteGlobalSetting(Settings::values.use_hw_shader);
|
||||||
#ifdef __APPLE__
|
#ifdef __APPLE__
|
||||||
|
@ -86,6 +86,7 @@ void ConfigureGraphics::SetConfiguration() {
|
|||||||
ui->graphics_api_combo->setCurrentIndex(static_cast<int>(Settings::values.graphics_api.GetValue()));
|
ui->graphics_api_combo->setCurrentIndex(static_cast<int>(Settings::values.graphics_api.GetValue()));
|
||||||
ui->physical_device_combo->setCurrentIndex(static_cast<int>(Settings::values.physical_device.GetValue()));
|
ui->physical_device_combo->setCurrentIndex(static_cast<int>(Settings::values.physical_device.GetValue()));
|
||||||
ui->toggle_async_recording->setChecked(Settings::values.async_command_recording.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()) {
|
if (Settings::IsConfiguringGlobal()) {
|
||||||
ui->toggle_shader_jit->setChecked(Settings::values.use_shader_jit.GetValue());
|
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.physical_device, ui->physical_device_combo);
|
||||||
ConfigurationShared::ApplyPerGameSetting(&Settings::values.async_command_recording, ui->toggle_async_recording,
|
ConfigurationShared::ApplyPerGameSetting(&Settings::values.async_command_recording, ui->toggle_async_recording,
|
||||||
async_command_recording);
|
async_command_recording);
|
||||||
|
ConfigurationShared::ApplyPerGameSetting(&Settings::values.spirv_shader_gen, ui->spirv_shader_gen,
|
||||||
|
spirv_shader_gen);
|
||||||
|
|
||||||
if (Settings::IsConfiguringGlobal()) {
|
if (Settings::IsConfiguringGlobal()) {
|
||||||
Settings::values.use_shader_jit = ui->toggle_shader_jit->isChecked();
|
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;
|
const bool is_visible = graphics_api == Settings::GraphicsAPI::Vulkan;
|
||||||
ui->physical_device_label->setVisible(is_visible);
|
ui->physical_device_label->setVisible(is_visible);
|
||||||
ui->physical_device_combo->setVisible(is_visible);
|
ui->physical_device_combo->setVisible(is_visible);
|
||||||
|
<<<<<<< HEAD
|
||||||
}
|
}
|
||||||
|
=======
|
||||||
|
ui->spirv_shader_gen->setVisible(is_visible);
|
||||||
|
}
|
||||||
|
>>>>>>> 25502ebc8 (citra_qt: Add SPIR-V shader option)
|
||||||
|
@ -41,6 +41,7 @@ private:
|
|||||||
ConfigurationShared::CheckState use_disk_shader_cache;
|
ConfigurationShared::CheckState use_disk_shader_cache;
|
||||||
ConfigurationShared::CheckState use_vsync_new;
|
ConfigurationShared::CheckState use_vsync_new;
|
||||||
ConfigurationShared::CheckState async_command_recording;
|
ConfigurationShared::CheckState async_command_recording;
|
||||||
|
ConfigurationShared::CheckState spirv_shader_gen;
|
||||||
std::unique_ptr<Ui::ConfigureGraphics> ui;
|
std::unique_ptr<Ui::ConfigureGraphics> ui;
|
||||||
QColor bg_color;
|
QColor bg_color;
|
||||||
};
|
};
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
<x>0</x>
|
<x>0</x>
|
||||||
<y>0</y>
|
<y>0</y>
|
||||||
<width>400</width>
|
<width>400</width>
|
||||||
<height>430</height>
|
<height>513</height>
|
||||||
</rect>
|
</rect>
|
||||||
</property>
|
</property>
|
||||||
<property name="minimumSize">
|
<property name="minimumSize">
|
||||||
@ -70,6 +70,13 @@
|
|||||||
</item>
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
</item>
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QCheckBox" name="spirv_shader_gen">
|
||||||
|
<property name="text">
|
||||||
|
<string>SPIR-V Shader Generation</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
|
@ -448,6 +448,7 @@ struct Values {
|
|||||||
// Renderer
|
// Renderer
|
||||||
SwitchableSetting<GraphicsAPI> graphics_api{GraphicsAPI::OpenGL, "graphics_api"};
|
SwitchableSetting<GraphicsAPI> graphics_api{GraphicsAPI::OpenGL, "graphics_api"};
|
||||||
SwitchableSetting<u16> physical_device{0, "physical_device"};
|
SwitchableSetting<u16> physical_device{0, "physical_device"};
|
||||||
|
SwitchableSetting<bool> spirv_shader_gen{true, "spirv_shader_gen"};
|
||||||
Setting<bool> renderer_debug{false, "renderer_debug"};
|
Setting<bool> renderer_debug{false, "renderer_debug"};
|
||||||
Setting<bool> dump_command_buffers{false, "dump_command_buffers"};
|
Setting<bool> dump_command_buffers{false, "dump_command_buffers"};
|
||||||
SwitchableSetting<bool> async_command_recording{true, "async_command_recording"};
|
SwitchableSetting<bool> async_command_recording{true, "async_command_recording"};
|
||||||
|
@ -92,7 +92,11 @@ PipelineCache::~PipelineCache() {
|
|||||||
device.destroyShaderModule(module);
|
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);
|
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) {
|
void PipelineCache::UseFragmentShader(const Pica::Regs& regs) {
|
||||||
const PicaFSConfig config{regs, instance};
|
const PicaFSConfig config{regs, instance};
|
||||||
|
|
||||||
scheduler.Record([this, config](vk::CommandBuffer, vk::CommandBuffer) {
|
scheduler.Record([this, config](vk::CommandBuffer, vk::CommandBuffer) {
|
||||||
vk::ShaderModule handle = fragment_shaders.Get(config, vk::ShaderStageFlagBits::eFragment,
|
MICROPROFILE_SCOPE(Vulkan_FragmentGeneration);
|
||||||
instance.GetDevice(), ShaderOptimization::Debug);
|
|
||||||
|
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;
|
current_shaders[ProgramType::FS] = handle;
|
||||||
shader_hashes[ProgramType::FS] = config.Hash();
|
shader_hashes[ProgramType::FS] = config.Hash();
|
||||||
});
|
});
|
||||||
|
@ -116,7 +116,10 @@ using ProgrammableVertexShaders = Pica::Shader::ShaderDoubleCache<PicaVSConfig,
|
|||||||
using FixedGeometryShaders = Pica::Shader::ShaderCache<PicaFixedGSConfig, vk::ShaderModule,
|
using FixedGeometryShaders = Pica::Shader::ShaderCache<PicaFixedGSConfig, vk::ShaderModule,
|
||||||
&Compile, &GenerateFixedGeometryShader>;
|
&Compile, &GenerateFixedGeometryShader>;
|
||||||
|
|
||||||
using FragmentShaders =
|
using FragmentShadersGLSL =
|
||||||
|
Pica::Shader::ShaderCache<PicaFSConfig, vk::ShaderModule, &Compile, &GenerateFragmentShader>;
|
||||||
|
|
||||||
|
using FragmentShadersSPV =
|
||||||
Pica::Shader::ShaderCache<PicaFSConfig, vk::ShaderModule, &CompileSPV, &GenerateFragmentShaderSPV>;
|
Pica::Shader::ShaderCache<PicaFSConfig, vk::ShaderModule, &CompileSPV, &GenerateFragmentShaderSPV>;
|
||||||
|
|
||||||
class Instance;
|
class Instance;
|
||||||
@ -217,7 +220,8 @@ private:
|
|||||||
std::array<u64, MAX_SHADER_STAGES> shader_hashes;
|
std::array<u64, MAX_SHADER_STAGES> shader_hashes;
|
||||||
ProgrammableVertexShaders programmable_vertex_shaders;
|
ProgrammableVertexShaders programmable_vertex_shaders;
|
||||||
FixedGeometryShaders fixed_geometry_shaders;
|
FixedGeometryShaders fixed_geometry_shaders;
|
||||||
FragmentShaders fragment_shaders;
|
FragmentShadersGLSL fragment_shaders_glsl;
|
||||||
|
FragmentShadersSPV fragment_shaders_spv;
|
||||||
vk::ShaderModule trivial_vertex_shader;
|
vk::ShaderModule trivial_vertex_shader;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -893,9 +893,7 @@ void FragmentModule::DefineInterface() {
|
|||||||
Decorate(gl_frag_depth_id, spv::Decoration::BuiltIn, spv::BuiltIn::FragDepth);
|
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<u32> GenerateFragmentShaderSPV(const PicaFSConfig& config) {
|
std::vector<u32> GenerateFragmentShaderSPV(const PicaFSConfig& config) {
|
||||||
MICROPROFILE_SCOPE(Vulkan_FragmentGenerationSPV);
|
|
||||||
FragmentModule module{config};
|
FragmentModule module{config};
|
||||||
module.Generate();
|
module.Generate();
|
||||||
return module.Assemble();
|
return module.Assemble();
|
||||||
|
@ -6,6 +6,7 @@
|
|||||||
#include <glslang/Include/ResourceLimits.h>
|
#include <glslang/Include/ResourceLimits.h>
|
||||||
#include <glslang/Public/ShaderLang.h>
|
#include <glslang/Public/ShaderLang.h>
|
||||||
#include "common/assert.h"
|
#include "common/assert.h"
|
||||||
|
#include "common/microprofile.h"
|
||||||
#include "common/logging/log.h"
|
#include "common/logging/log.h"
|
||||||
#include "video_core/renderer_vulkan/vk_shader_util.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);
|
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<u32> code, vk::ShaderStageFlagBits stage, vk::Device device,
|
MICROPROFILE_DEFINE(Vulkan_SPVCompilation, "Vulkan", "SPIR-V Shader Compilation", MP_RGB(100, 255, 52));
|
||||||
ShaderOptimization) {
|
vk::ShaderModule CompileSPV(std::vector<u32> code, vk::Device device) {
|
||||||
|
MICROPROFILE_SCOPE(Vulkan_SPVCompilation);
|
||||||
const vk::ShaderModuleCreateInfo shader_info = {.codeSize = code.size() * sizeof(u32),
|
const vk::ShaderModuleCreateInfo shader_info = {.codeSize = code.size() * sizeof(u32),
|
||||||
.pCode = code.data()};
|
.pCode = code.data()};
|
||||||
try {
|
try {
|
||||||
|
@ -13,7 +13,6 @@ enum class ShaderOptimization { High = 0, Debug = 1 };
|
|||||||
vk::ShaderModule Compile(std::string_view code, vk::ShaderStageFlagBits stage, vk::Device device,
|
vk::ShaderModule Compile(std::string_view code, vk::ShaderStageFlagBits stage, vk::Device device,
|
||||||
ShaderOptimization level);
|
ShaderOptimization level);
|
||||||
|
|
||||||
vk::ShaderModule CompileSPV(std::vector<u32> code, vk::ShaderStageFlagBits stage, vk::Device device,
|
vk::ShaderModule CompileSPV(std::vector<u32> code, vk::Device device);
|
||||||
ShaderOptimization level);
|
|
||||||
|
|
||||||
} // namespace Vulkan
|
} // namespace Vulkan
|
||||||
|
@ -189,7 +189,14 @@ ImageAlloc TextureRuntime::Allocate(u32 width, u32 height, VideoCore::PixelForma
|
|||||||
.samples = vk::SampleCountFlagBits::e1,
|
.samples = vk::SampleCountFlagBits::e1,
|
||||||
.usage = usage};
|
.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{};
|
VkImage unsafe_image{};
|
||||||
VkImageCreateInfo unsafe_image_info = static_cast<VkImageCreateInfo>(image_info);
|
VkImageCreateInfo unsafe_image_info = static_cast<VkImageCreateInfo>(image_info);
|
||||||
|
Reference in New Issue
Block a user