mirror of
https://git.eden-emu.dev/eden-emu/eden
synced 2026-05-20 18:27:02 +02:00
[vk, pipeline] Added In-flight conditional for multiple pipeline compilations
This commit is contained in:
parent
49894f3897
commit
525e878ddc
2 changed files with 108 additions and 9 deletions
|
|
@ -553,12 +553,17 @@ ComputePipeline* PipelineCache::CurrentComputePipeline() {
|
||||||
.shared_memory_size = qmd.shared_alloc,
|
.shared_memory_size = qmd.shared_alloc,
|
||||||
.workgroup_size{qmd.block_dim_x, qmd.block_dim_y, qmd.block_dim_z},
|
.workgroup_size{qmd.block_dim_x, qmd.block_dim_y, qmd.block_dim_z},
|
||||||
};
|
};
|
||||||
const auto [pair, is_new]{compute_cache.try_emplace(key)};
|
const auto [pair, inserted]{compute_cache.try_emplace(key)};
|
||||||
auto& pipeline{pair->second};
|
auto& pipeline{pair->second};
|
||||||
if (!is_new) {
|
if (!pipeline) {
|
||||||
return pipeline.get();
|
auto [slot, should_build] = AcquireComputeBuildSlot(key);
|
||||||
|
if (!should_build) {
|
||||||
|
WaitForBuildCompletion(slot);
|
||||||
|
} else {
|
||||||
|
pipeline = CreateComputePipeline(key, shader);
|
||||||
|
ReleaseComputeBuildSlot(key, slot);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
pipeline = CreateComputePipeline(key, shader);
|
|
||||||
return pipeline.get();
|
return pipeline.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -674,13 +679,20 @@ void PipelineCache::LoadDiskResources(u64 title_id, std::stop_token stop_loading
|
||||||
}
|
}
|
||||||
|
|
||||||
GraphicsPipeline* PipelineCache::CurrentGraphicsPipelineSlowPath() {
|
GraphicsPipeline* PipelineCache::CurrentGraphicsPipelineSlowPath() {
|
||||||
const auto [pair, is_new]{graphics_cache.try_emplace(graphics_key)};
|
const auto [pair, inserted]{graphics_cache.try_emplace(graphics_key)};
|
||||||
auto& pipeline{pair->second};
|
auto& pipeline{pair->second};
|
||||||
if (is_new) {
|
|
||||||
pipeline = CreateGraphicsPipeline();
|
|
||||||
}
|
|
||||||
if (!pipeline) {
|
if (!pipeline) {
|
||||||
return nullptr;
|
const auto key = pair->first;
|
||||||
|
auto [slot, should_build] = AcquireGraphicsBuildSlot(key);
|
||||||
|
if (!should_build) {
|
||||||
|
WaitForBuildCompletion(slot);
|
||||||
|
} else {
|
||||||
|
pipeline = CreateGraphicsPipeline();
|
||||||
|
ReleaseGraphicsBuildSlot(key, slot);
|
||||||
|
}
|
||||||
|
if (!pipeline) {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (current_pipeline) {
|
if (current_pipeline) {
|
||||||
current_pipeline->AddTransition(pipeline.get());
|
current_pipeline->AddTransition(pipeline.get());
|
||||||
|
|
@ -994,4 +1006,68 @@ vk::PipelineCache PipelineCache::LoadVulkanPipelineCache(const std::filesystem::
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
auto PipelineCache::AcquireGraphicsBuildSlot(const GraphicsPipelineCacheKey& key)
|
||||||
|
-> std::pair<InFlightPipelinePtr, bool> {
|
||||||
|
std::scoped_lock lock(graphics_inflight_mutex);
|
||||||
|
auto [it, inserted] = graphics_inflight_builds.try_emplace(key);
|
||||||
|
if (inserted || !it->second) {
|
||||||
|
it->second = std::make_shared<InFlightPipelineBuild>();
|
||||||
|
return {it->second, true};
|
||||||
|
}
|
||||||
|
return {it->second, false};
|
||||||
|
}
|
||||||
|
|
||||||
|
auto PipelineCache::AcquireComputeBuildSlot(const ComputePipelineCacheKey& key)
|
||||||
|
-> std::pair<InFlightPipelinePtr, bool> {
|
||||||
|
std::scoped_lock lock(compute_inflight_mutex);
|
||||||
|
auto [it, inserted] = compute_inflight_builds.try_emplace(key);
|
||||||
|
if (inserted || !it->second) {
|
||||||
|
it->second = std::make_shared<InFlightPipelineBuild>();
|
||||||
|
return {it->second, true};
|
||||||
|
}
|
||||||
|
return {it->second, false};
|
||||||
|
}
|
||||||
|
|
||||||
|
void PipelineCache::ReleaseGraphicsBuildSlot(const GraphicsPipelineCacheKey& key,
|
||||||
|
const InFlightPipelinePtr& slot) {
|
||||||
|
if (!slot) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
{
|
||||||
|
std::scoped_lock slot_lock(slot->mutex);
|
||||||
|
slot->building = false;
|
||||||
|
}
|
||||||
|
slot->cv.notify_all();
|
||||||
|
std::scoped_lock map_lock(graphics_inflight_mutex);
|
||||||
|
auto it = graphics_inflight_builds.find(key);
|
||||||
|
if (it != graphics_inflight_builds.end() && it->second == slot) {
|
||||||
|
graphics_inflight_builds.erase(it);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void PipelineCache::ReleaseComputeBuildSlot(const ComputePipelineCacheKey& key,
|
||||||
|
const InFlightPipelinePtr& slot) {
|
||||||
|
if (!slot) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
{
|
||||||
|
std::scoped_lock slot_lock(slot->mutex);
|
||||||
|
slot->building = false;
|
||||||
|
}
|
||||||
|
slot->cv.notify_all();
|
||||||
|
std::scoped_lock map_lock(compute_inflight_mutex);
|
||||||
|
auto it = compute_inflight_builds.find(key);
|
||||||
|
if (it != compute_inflight_builds.end() && it->second == slot) {
|
||||||
|
compute_inflight_builds.erase(it);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void PipelineCache::WaitForBuildCompletion(const InFlightPipelinePtr& slot) const {
|
||||||
|
if (!slot) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
std::unique_lock lock(slot->mutex);
|
||||||
|
slot->cv.wait(lock, [&] { return !slot->building; });
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace Vulkan
|
} // namespace Vulkan
|
||||||
|
|
|
||||||
|
|
@ -5,8 +5,10 @@
|
||||||
|
|
||||||
#include <array>
|
#include <array>
|
||||||
#include <cstddef>
|
#include <cstddef>
|
||||||
|
#include <condition_variable>
|
||||||
#include <filesystem>
|
#include <filesystem>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
#include <mutex>
|
||||||
#include <type_traits>
|
#include <type_traits>
|
||||||
#include <unordered_map>
|
#include <unordered_map>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
@ -114,6 +116,14 @@ public:
|
||||||
const VideoCore::DiskResourceLoadCallback& callback);
|
const VideoCore::DiskResourceLoadCallback& callback);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
struct InFlightPipelineBuild {
|
||||||
|
std::mutex mutex;
|
||||||
|
std::condition_variable cv;
|
||||||
|
bool building{true};
|
||||||
|
};
|
||||||
|
|
||||||
|
using InFlightPipelinePtr = std::shared_ptr<InFlightPipelineBuild>;
|
||||||
|
|
||||||
[[nodiscard]] GraphicsPipeline* CurrentGraphicsPipelineSlowPath();
|
[[nodiscard]] GraphicsPipeline* CurrentGraphicsPipelineSlowPath();
|
||||||
|
|
||||||
[[nodiscard]] GraphicsPipeline* BuiltPipeline(GraphicsPipeline* pipeline) const noexcept;
|
[[nodiscard]] GraphicsPipeline* BuiltPipeline(GraphicsPipeline* pipeline) const noexcept;
|
||||||
|
|
@ -140,6 +150,14 @@ private:
|
||||||
vk::PipelineCache LoadVulkanPipelineCache(const std::filesystem::path& filename,
|
vk::PipelineCache LoadVulkanPipelineCache(const std::filesystem::path& filename,
|
||||||
u32 expected_cache_version);
|
u32 expected_cache_version);
|
||||||
|
|
||||||
|
std::pair<InFlightPipelinePtr, bool> AcquireGraphicsBuildSlot(
|
||||||
|
const GraphicsPipelineCacheKey& key);
|
||||||
|
std::pair<InFlightPipelinePtr, bool> AcquireComputeBuildSlot(
|
||||||
|
const ComputePipelineCacheKey& key);
|
||||||
|
void ReleaseGraphicsBuildSlot(const GraphicsPipelineCacheKey& key, const InFlightPipelinePtr& slot);
|
||||||
|
void ReleaseComputeBuildSlot(const ComputePipelineCacheKey& key, const InFlightPipelinePtr& slot);
|
||||||
|
void WaitForBuildCompletion(const InFlightPipelinePtr& slot) const;
|
||||||
|
|
||||||
const Device& device;
|
const Device& device;
|
||||||
Scheduler& scheduler;
|
Scheduler& scheduler;
|
||||||
DescriptorPool& descriptor_pool;
|
DescriptorPool& descriptor_pool;
|
||||||
|
|
@ -158,6 +176,11 @@ private:
|
||||||
std::unordered_map<ComputePipelineCacheKey, std::unique_ptr<ComputePipeline>> compute_cache;
|
std::unordered_map<ComputePipelineCacheKey, std::unique_ptr<ComputePipeline>> compute_cache;
|
||||||
std::unordered_map<GraphicsPipelineCacheKey, std::unique_ptr<GraphicsPipeline>> graphics_cache;
|
std::unordered_map<GraphicsPipelineCacheKey, std::unique_ptr<GraphicsPipeline>> graphics_cache;
|
||||||
|
|
||||||
|
std::mutex graphics_inflight_mutex;
|
||||||
|
std::unordered_map<GraphicsPipelineCacheKey, InFlightPipelinePtr> graphics_inflight_builds;
|
||||||
|
std::mutex compute_inflight_mutex;
|
||||||
|
std::unordered_map<ComputePipelineCacheKey, InFlightPipelinePtr> compute_inflight_builds;
|
||||||
|
|
||||||
ShaderPools main_pools;
|
ShaderPools main_pools;
|
||||||
|
|
||||||
Shader::Profile profile;
|
Shader::Profile profile;
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue