shader: Remove atomic flags and use mutex + cond variable for pipelines

This commit is contained in:
ReinUsesLisp 2021-04-03 21:41:49 -03:00 committed by ameerj
parent 0b26f2b90e
commit 5ed68e83db
4 changed files with 32 additions and 11 deletions

View file

@ -55,8 +55,9 @@ ComputePipeline::ComputePipeline(const Device& device, VKDescriptorPool& descrip
.basePipelineHandle = 0, .basePipelineHandle = 0,
.basePipelineIndex = 0, .basePipelineIndex = 0,
}); });
building_flag.test_and_set(); std::lock_guard lock{build_mutex};
building_flag.notify_all(); is_built = true;
build_condvar.notify_one();
}}; }};
if (thread_worker) { if (thread_worker) {
thread_worker->QueueWork(std::move(func)); thread_worker->QueueWork(std::move(func));
@ -75,7 +76,8 @@ void ComputePipeline::Configure(Tegra::Engines::KeplerCompute& kepler_compute,
size_t ssbo_index{}; size_t ssbo_index{};
for (const auto& desc : info.storage_buffers_descriptors) { for (const auto& desc : info.storage_buffers_descriptors) {
ASSERT(desc.count == 1); ASSERT(desc.count == 1);
buffer_cache.BindComputeStorageBuffer(ssbo_index, desc.cbuf_index, desc.cbuf_offset, desc.is_written); buffer_cache.BindComputeStorageBuffer(ssbo_index, desc.cbuf_index, desc.cbuf_offset,
desc.is_written);
++ssbo_index; ++ssbo_index;
} }
buffer_cache.UpdateComputeBuffers(); buffer_cache.UpdateComputeBuffers();
@ -112,9 +114,12 @@ void ComputePipeline::Configure(Tegra::Engines::KeplerCompute& kepler_compute,
PushImageDescriptors(info, samplers.data(), image_view_ids.data(), texture_cache, PushImageDescriptors(info, samplers.data(), image_view_ids.data(), texture_cache,
update_descriptor_queue, image_index); update_descriptor_queue, image_index);
if (!building_flag.test()) { if (!is_built.load(std::memory_order::relaxed)) {
// Wait for the pipeline to be built // Wait for the pipeline to be built
scheduler.Record([this](vk::CommandBuffer) { building_flag.wait(false); }); scheduler.Record([this](vk::CommandBuffer) {
std::unique_lock lock{build_mutex};
build_condvar.wait(lock, [this] { return is_built.load(std::memory_order::relaxed); });
});
} }
scheduler.Record([this](vk::CommandBuffer cmdbuf) { scheduler.Record([this](vk::CommandBuffer cmdbuf) {
cmdbuf.BindPipeline(VK_PIPELINE_BIND_POINT_COMPUTE, *pipeline); cmdbuf.BindPipeline(VK_PIPELINE_BIND_POINT_COMPUTE, *pipeline);

View file

@ -4,6 +4,8 @@
#pragma once #pragma once
#include <mutex>
#include <condition_variable>
#include <atomic> #include <atomic>
#include "common/common_types.h" #include "common/common_types.h"
@ -47,7 +49,10 @@ private:
vk::PipelineLayout pipeline_layout; vk::PipelineLayout pipeline_layout;
vk::DescriptorUpdateTemplateKHR descriptor_update_template; vk::DescriptorUpdateTemplateKHR descriptor_update_template;
vk::Pipeline pipeline; vk::Pipeline pipeline;
std::atomic_flag building_flag{};
std::condition_variable build_condvar;
std::mutex build_mutex;
std::atomic_bool is_built{false};
}; };
} // namespace Vulkan } // namespace Vulkan

View file

@ -135,8 +135,10 @@ GraphicsPipeline::GraphicsPipeline(Tegra::Engines::Maxwell3D& maxwell3d_,
const VkRenderPass render_pass{render_pass_cache.Get(MakeRenderPassKey(state))}; const VkRenderPass render_pass{render_pass_cache.Get(MakeRenderPassKey(state))};
MakePipeline(device, render_pass); MakePipeline(device, render_pass);
building_flag.test_and_set();
building_flag.notify_all(); std::lock_guard lock{build_mutex};
is_built = true;
build_condvar.notify_one();
}}; }};
if (worker_thread) { if (worker_thread) {
worker_thread->QueueWork(std::move(func)); worker_thread->QueueWork(std::move(func));
@ -196,8 +198,12 @@ void GraphicsPipeline::Configure(bool is_indexed) {
texture_cache.UpdateRenderTargets(false); texture_cache.UpdateRenderTargets(false);
scheduler.RequestRenderpass(texture_cache.GetFramebuffer()); scheduler.RequestRenderpass(texture_cache.GetFramebuffer());
if (!building_flag.test()) { if (!is_built.load(std::memory_order::relaxed)) {
scheduler.Record([this](vk::CommandBuffer) { building_flag.wait(false); }); // Wait for the pipeline to be built
scheduler.Record([this](vk::CommandBuffer) {
std::unique_lock lock{build_mutex};
build_condvar.wait(lock, [this] { return is_built.load(std::memory_order::relaxed); });
});
} }
if (scheduler.UpdateGraphicsPipeline(this)) { if (scheduler.UpdateGraphicsPipeline(this)) {
scheduler.Record([this](vk::CommandBuffer cmdbuf) { scheduler.Record([this](vk::CommandBuffer cmdbuf) {

View file

@ -6,6 +6,8 @@
#include <array> #include <array>
#include <atomic> #include <atomic>
#include <condition_variable>
#include <mutex>
#include "common/thread_worker.h" #include "common/thread_worker.h"
#include "shader_recompiler/shader_info.h" #include "shader_recompiler/shader_info.h"
@ -63,7 +65,10 @@ private:
vk::PipelineLayout pipeline_layout; vk::PipelineLayout pipeline_layout;
vk::DescriptorUpdateTemplateKHR descriptor_update_template; vk::DescriptorUpdateTemplateKHR descriptor_update_template;
vk::Pipeline pipeline; vk::Pipeline pipeline;
std::atomic_flag building_flag{};
std::condition_variable build_condvar;
std::mutex build_mutex;
std::atomic_bool is_built{false};
}; };
} // namespace Vulkan } // namespace Vulkan