vk_pipeline_cache: Move SPIRV emittion to a worker thread (#7170)

* vk_scheduler: Remove RenderpassCache dependency

* vk_pipeline_cache: Move spirv emittion to worker thread
This commit is contained in:
GPUCode 2023-11-21 06:05:35 +02:00 committed by GitHub
parent f8ae41dfe3
commit 5733c8681e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 15 additions and 24 deletions

View File

@ -7,7 +7,6 @@
#include "common/memory_detect.h" #include "common/memory_detect.h"
#include "common/microprofile.h" #include "common/microprofile.h"
#include "common/settings.h" #include "common/settings.h"
#include "common/texture.h"
#include "core/core.h" #include "core/core.h"
#include "core/frontend/emu_window.h" #include "core/frontend/emu_window.h"
#include "core/hw/gpu.h" #include "core/hw/gpu.h"
@ -21,7 +20,6 @@
#include "video_core/host_shaders/vulkan_present_frag_spv.h" #include "video_core/host_shaders/vulkan_present_frag_spv.h"
#include "video_core/host_shaders/vulkan_present_interlaced_frag_spv.h" #include "video_core/host_shaders/vulkan_present_interlaced_frag_spv.h"
#include "video_core/host_shaders/vulkan_present_vert_spv.h" #include "video_core/host_shaders/vulkan_present_vert_spv.h"
#include "vulkan/vulkan_format_traits.hpp"
#include <vk_mem_alloc.h> #include <vk_mem_alloc.h>
@ -57,7 +55,7 @@ RendererVulkan::RendererVulkan(Core::System& system, Frontend::EmuWindow& window
Frontend::EmuWindow* secondary_window) Frontend::EmuWindow* secondary_window)
: RendererBase{system, window, secondary_window}, memory{system.Memory()}, : RendererBase{system, window, secondary_window}, memory{system.Memory()},
instance{system.TelemetrySession(), window, Settings::values.physical_device.GetValue()}, instance{system.TelemetrySession(), window, Settings::values.physical_device.GetValue()},
scheduler{instance, renderpass_cache}, renderpass_cache{instance, scheduler}, pool{instance}, scheduler{instance}, renderpass_cache{instance, scheduler}, pool{instance},
main_window{window, instance, scheduler}, main_window{window, instance, scheduler},
vertex_buffer{instance, scheduler, vk::BufferUsageFlagBits::eVertexBuffer, vertex_buffer{instance, scheduler, vk::BufferUsageFlagBits::eVertexBuffer,
VERTEX_BUFFER_SIZE}, VERTEX_BUFFER_SIZE},

View File

@ -469,19 +469,18 @@ void PipelineCache::UseFragmentShader(const Pica::Regs& regs,
auto& shader = it->second; auto& shader = it->second;
if (new_shader) { if (new_shader) {
const bool use_spirv = Settings::values.spirv_shader_gen.GetValue(); workers.QueueWork([fs_config, this, &shader]() {
if (use_spirv && !fs_config.UsesShadowPipeline()) { const bool use_spirv = Settings::values.spirv_shader_gen.GetValue();
const std::vector code = SPIRV::GenerateFragmentShader(fs_config, profile); if (use_spirv && !fs_config.UsesShadowPipeline()) {
shader.module = CompileSPV(code, instance.GetDevice()); const std::vector code = SPIRV::GenerateFragmentShader(fs_config, profile);
shader.MarkDone(); shader.module = CompileSPV(code, instance.GetDevice());
} else { } else {
workers.QueueWork([fs_config, this, &shader]() {
const std::string code = GLSL::GenerateFragmentShader(fs_config, profile); const std::string code = GLSL::GenerateFragmentShader(fs_config, profile);
shader.module = shader.module =
Compile(code, vk::ShaderStageFlagBits::eFragment, instance.GetDevice()); Compile(code, vk::ShaderStageFlagBits::eFragment, instance.GetDevice());
shader.MarkDone(); }
}); shader.MarkDone();
} });
} }
current_shaders[ProgramType::FS] = &shader; current_shaders[ProgramType::FS] = &shader;

View File

@ -42,8 +42,8 @@ void Scheduler::CommandChunk::ExecuteAll(vk::CommandBuffer cmdbuf) {
last = nullptr; last = nullptr;
} }
Scheduler::Scheduler(const Instance& instance, RenderpassCache& renderpass_cache) Scheduler::Scheduler(const Instance& instance)
: renderpass_cache{renderpass_cache}, master_semaphore{MakeMasterSemaphore(instance)}, : master_semaphore{MakeMasterSemaphore(instance)},
command_pool{instance, master_semaphore.get()}, use_worker_thread{true} { command_pool{instance, master_semaphore.get()}, use_worker_thread{true} {
AllocateWorkerCommandBuffers(); AllocateWorkerCommandBuffers();
if (use_worker_thread) { if (use_worker_thread) {
@ -173,7 +173,6 @@ void Scheduler::SubmitExecution(vk::Semaphore signal_semaphore, vk::Semaphore wa
state = StateFlags::AllDirty; state = StateFlags::AllDirty;
const u64 signal_value = master_semaphore->NextTick(); const u64 signal_value = master_semaphore->NextTick();
renderpass_cache.EndRendering();
Record([signal_semaphore, wait_semaphore, signal_value, this](vk::CommandBuffer cmdbuf) { Record([signal_semaphore, wait_semaphore, signal_value, this](vk::CommandBuffer cmdbuf) {
MICROPROFILE_SCOPE(Vulkan_Submit); MICROPROFILE_SCOPE(Vulkan_Submit);
std::scoped_lock lock{submit_mutex}; std::scoped_lock lock{submit_mutex};

View File

@ -8,7 +8,6 @@
#include <utility> #include <utility>
#include "common/alignment.h" #include "common/alignment.h"
#include "common/common_funcs.h" #include "common/common_funcs.h"
#include "common/logging/log.h"
#include "common/polyfill_thread.h" #include "common/polyfill_thread.h"
#include "video_core/renderer_vulkan/vk_master_semaphore.h" #include "video_core/renderer_vulkan/vk_master_semaphore.h"
#include "video_core/renderer_vulkan/vk_resource_pool.h" #include "video_core/renderer_vulkan/vk_resource_pool.h"
@ -17,21 +16,18 @@ namespace Vulkan {
enum class StateFlags { enum class StateFlags {
AllDirty = 0, AllDirty = 0,
Renderpass = 1 << 0, Pipeline = 1 << 0,
Pipeline = 1 << 1, DescriptorSets = 1 << 1,
DescriptorSets = 1 << 2
}; };
DECLARE_ENUM_FLAG_OPERATORS(StateFlags) DECLARE_ENUM_FLAG_OPERATORS(StateFlags)
class Instance; class Instance;
class RenderpassCache;
/// The scheduler abstracts command buffer and fence management with an interface that's able to do /// The scheduler abstracts command buffer and fence management with an interface that's able to do
/// OpenGL-like operations on Vulkan command buffers. /// OpenGL-like operations on Vulkan command buffers.
class Scheduler { class Scheduler {
public: public:
explicit Scheduler(const Instance& instance, RenderpassCache& renderpass_cache); explicit Scheduler(const Instance& instance);
~Scheduler(); ~Scheduler();
/// Sends the current execution context to the GPU. /// Sends the current execution context to the GPU.
@ -191,7 +187,6 @@ private:
void AcquireNewChunk(); void AcquireNewChunk();
private: private:
RenderpassCache& renderpass_cache;
std::unique_ptr<MasterSemaphore> master_semaphore; std::unique_ptr<MasterSemaphore> master_semaphore;
CommandPool command_pool; CommandPool command_pool;
std::unique_ptr<CommandChunk> chunk; std::unique_ptr<CommandChunk> chunk;