mirror of
https://git.eden-emu.dev/eden-emu/eden.git
synced 2026-08-18 06:10:35 +00:00
Funny experiment for pipelines
This commit is contained in:
@@ -1270,7 +1270,7 @@ VkPipeline BlitImageHelper::FindOrEmplaceColorPipeline(const BlitImagePipelineKe
|
||||
.subpass = 0,
|
||||
.basePipelineHandle = VK_NULL_HANDLE,
|
||||
.basePipelineIndex = 0,
|
||||
}));
|
||||
}, device.StaticPipelineCache()));
|
||||
return *blit_color_pipelines.back();
|
||||
}
|
||||
|
||||
@@ -1304,7 +1304,7 @@ VkPipeline BlitImageHelper::FindOrEmplaceDepthStencilPipeline(const BlitImagePip
|
||||
.subpass = 0,
|
||||
.basePipelineHandle = VK_NULL_HANDLE,
|
||||
.basePipelineIndex = 0,
|
||||
}));
|
||||
}, device.StaticPipelineCache()));
|
||||
return *blit_depth_stencil_pipelines.back();
|
||||
}
|
||||
|
||||
@@ -1365,7 +1365,7 @@ VkPipeline BlitImageHelper::FindOrEmplaceClearColorPipeline(const BlitImagePipel
|
||||
.subpass = 0,
|
||||
.basePipelineHandle = VK_NULL_HANDLE,
|
||||
.basePipelineIndex = 0,
|
||||
}));
|
||||
}, device.StaticPipelineCache()));
|
||||
return *clear_color_pipelines.back();
|
||||
}
|
||||
|
||||
@@ -1434,7 +1434,7 @@ VkPipeline BlitImageHelper::FindOrEmplaceClearStencilPipeline(
|
||||
.subpass = 0,
|
||||
.basePipelineHandle = VK_NULL_HANDLE,
|
||||
.basePipelineIndex = 0,
|
||||
}));
|
||||
}, device.StaticPipelineCache()));
|
||||
return *clear_stencil_pipelines.back();
|
||||
}
|
||||
|
||||
@@ -1479,7 +1479,7 @@ VkPipeline BlitImageHelper::FindOrEmplaceBlitColorMSAAPipeline(const BlitMSAAPip
|
||||
.subpass = 0,
|
||||
.basePipelineHandle = VK_NULL_HANDLE,
|
||||
.basePipelineIndex = 0,
|
||||
}));
|
||||
}, device.StaticPipelineCache()));
|
||||
return *blit_msaa_color_pipelines.back();
|
||||
}
|
||||
|
||||
@@ -1523,7 +1523,7 @@ VkPipeline BlitImageHelper::FindOrEmplaceResolveDepthStencilPipeline(
|
||||
.subpass = 0,
|
||||
.basePipelineHandle = VK_NULL_HANDLE,
|
||||
.basePipelineIndex = 0,
|
||||
}));
|
||||
}, device.StaticPipelineCache()));
|
||||
return *pipelines.back();
|
||||
}
|
||||
|
||||
@@ -1596,7 +1596,7 @@ VkPipeline BlitImageHelper::FindOrEmplaceMSAACopyPipeline(const MSAACopyPipeline
|
||||
.subpass = 0,
|
||||
.basePipelineHandle = VK_NULL_HANDLE,
|
||||
.basePipelineIndex = 0,
|
||||
}));
|
||||
}, device.StaticPipelineCache()));
|
||||
return *msaa_copy_pipelines.back();
|
||||
}
|
||||
|
||||
@@ -1641,7 +1641,7 @@ void BlitImageHelper::ConvertPipelineEx(vk::Pipeline& pipeline, const Framebuffe
|
||||
.subpass = 0,
|
||||
.basePipelineHandle = VK_NULL_HANDLE,
|
||||
.basePipelineIndex = 0,
|
||||
});
|
||||
}, device.StaticPipelineCache());
|
||||
}
|
||||
|
||||
void BlitImageHelper::ConvertPipelineColorTargetEx(vk::Pipeline& pipeline,
|
||||
@@ -1688,7 +1688,7 @@ void BlitImageHelper::ConvertPipeline(vk::Pipeline& pipeline, const Framebuffer*
|
||||
.subpass = 0,
|
||||
.basePipelineHandle = VK_NULL_HANDLE,
|
||||
.basePipelineIndex = 0,
|
||||
});
|
||||
}, device.StaticPipelineCache());
|
||||
}
|
||||
|
||||
} // namespace Vulkan
|
||||
|
||||
@@ -491,7 +491,7 @@ static vk::Pipeline CreateWrappedPipelineImpl(
|
||||
.subpass = 0,
|
||||
.basePipelineHandle = 0,
|
||||
.basePipelineIndex = 0,
|
||||
});
|
||||
}, device.StaticPipelineCache());
|
||||
}
|
||||
|
||||
vk::Pipeline CreateWrappedPipeline(const Device& device, vk::RenderPass& renderpass,
|
||||
|
||||
@@ -268,7 +268,7 @@ ComputePass::ComputePass(const Device& device_, Scheduler& scheduler, Descriptor
|
||||
.layout = *layout,
|
||||
.basePipelineHandle = {},
|
||||
.basePipelineIndex = 0,
|
||||
});
|
||||
}, device.StaticPipelineCache());
|
||||
}
|
||||
|
||||
ComputePass::~ComputePass() = default;
|
||||
|
||||
@@ -8,6 +8,8 @@
|
||||
#include <array>
|
||||
#include <bitset>
|
||||
#include <chrono>
|
||||
#include <filesystem>
|
||||
#include <fstream>
|
||||
#include <optional>
|
||||
#include <thread>
|
||||
#include <ankerl/unordered_dense.h>
|
||||
@@ -17,6 +19,8 @@
|
||||
#include <fmt/format.h>
|
||||
|
||||
#include "common/assert.h"
|
||||
#include "common/fs/fs.h"
|
||||
#include "common/fs/path_util.h"
|
||||
#include "common/literals.h"
|
||||
#include <ranges>
|
||||
#include "common/settings.h"
|
||||
@@ -394,6 +398,17 @@ std::vector<const char*> ExtensionListForVulkan(
|
||||
return output;
|
||||
}
|
||||
|
||||
constexpr std::array<char, 8> STATIC_CACHE_MAGIC_NUMBER{'e', 'd', 'e', 'n', 's', 't', 'p', 'c'};
|
||||
constexpr u32 STATIC_CACHE_VERSION = 1;
|
||||
|
||||
std::filesystem::path StaticPipelineCacheFilename() {
|
||||
const auto shader_dir = Common::FS::GetEdenPath(Common::FS::EdenPath::ShaderDir);
|
||||
if (!Common::FS::CreateDir(shader_dir)) {
|
||||
return {};
|
||||
}
|
||||
return shader_dir / "vulkan_static_pipelines.bin";
|
||||
}
|
||||
|
||||
} // Anonymous namespace
|
||||
|
||||
void Device::RemoveExtension(bool& extension, const std::string& extension_name) {
|
||||
@@ -778,16 +793,105 @@ Device::Device(VkInstance instance_, vk::PhysicalDevice physical_, VkSurfaceKHR
|
||||
limits.storageImageSampleCounts);
|
||||
}
|
||||
|
||||
owns_static_pipeline_cache = surface != VkSurfaceKHR{};
|
||||
LoadStaticPipelineCache();
|
||||
|
||||
// Initialize GPU logging if enabled
|
||||
InitializeGPULogging();
|
||||
}
|
||||
|
||||
Device::~Device() {
|
||||
SaveStaticPipelineCache();
|
||||
ShutdownGPULogging();
|
||||
vk::FlushDeletionQueue();
|
||||
vmaDestroyAllocator(allocator);
|
||||
}
|
||||
|
||||
void Device::LoadStaticPipelineCache() {
|
||||
const auto create = [this](size_t size, const void* data) {
|
||||
static_pipeline_cache = logical.CreatePipelineCache({
|
||||
.sType = VK_STRUCTURE_TYPE_PIPELINE_CACHE_CREATE_INFO,
|
||||
.pNext = nullptr,
|
||||
.flags = 0,
|
||||
.initialDataSize = size,
|
||||
.pInitialData = data,
|
||||
});
|
||||
};
|
||||
if (!owns_static_pipeline_cache) {
|
||||
create(0, nullptr);
|
||||
return;
|
||||
}
|
||||
const auto filename = StaticPipelineCacheFilename();
|
||||
if (filename.empty()) {
|
||||
create(0, nullptr);
|
||||
return;
|
||||
}
|
||||
std::vector<char> data;
|
||||
try {
|
||||
std::ifstream file(filename, std::ios::binary | std::ios::ate);
|
||||
if (!file.is_open()) {
|
||||
create(0, nullptr);
|
||||
return;
|
||||
}
|
||||
file.exceptions(std::ifstream::failbit | std::ifstream::badbit);
|
||||
const size_t total = static_cast<size_t>(file.tellg());
|
||||
file.seekg(0, std::ios::beg);
|
||||
std::array<char, 8> magic{};
|
||||
u32 version{};
|
||||
if (total < magic.size() + sizeof(version)) {
|
||||
create(0, nullptr);
|
||||
return;
|
||||
}
|
||||
file.read(magic.data(), magic.size())
|
||||
.read(reinterpret_cast<char*>(&version), sizeof(version));
|
||||
if (magic != STATIC_CACHE_MAGIC_NUMBER || version != STATIC_CACHE_VERSION) {
|
||||
LOG_INFO(Render_Vulkan, "Discarding stale static pipeline cache");
|
||||
create(0, nullptr);
|
||||
return;
|
||||
}
|
||||
data.resize(total - magic.size() - sizeof(version));
|
||||
file.read(data.data(), static_cast<std::streamsize>(data.size()));
|
||||
} catch (const std::ios_base::failure& e) {
|
||||
LOG_WARNING(Render_Vulkan, "Failed to read static pipeline cache: {}", e.what());
|
||||
create(0, nullptr);
|
||||
return;
|
||||
}
|
||||
create(data.size(), data.empty() ? nullptr : data.data());
|
||||
LOG_INFO(Render_Vulkan, "Loaded {} bytes of static pipeline cache", data.size());
|
||||
}
|
||||
|
||||
void Device::SaveStaticPipelineCache() const {
|
||||
if (!owns_static_pipeline_cache || !static_pipeline_cache) {
|
||||
return;
|
||||
}
|
||||
const auto filename = StaticPipelineCacheFilename();
|
||||
if (filename.empty()) {
|
||||
return;
|
||||
}
|
||||
size_t size = 0;
|
||||
std::vector<char> data;
|
||||
static_pipeline_cache.Read(&size, nullptr);
|
||||
if (size == 0) {
|
||||
return;
|
||||
}
|
||||
data.resize(size);
|
||||
static_pipeline_cache.Read(&size, data.data());
|
||||
try {
|
||||
std::ofstream file(filename, std::ios::binary | std::ios::trunc);
|
||||
file.exceptions(std::ofstream::failbit);
|
||||
if (!file.is_open()) {
|
||||
return;
|
||||
}
|
||||
file.write(STATIC_CACHE_MAGIC_NUMBER.data(), STATIC_CACHE_MAGIC_NUMBER.size())
|
||||
.write(reinterpret_cast<const char*>(&STATIC_CACHE_VERSION),
|
||||
sizeof(STATIC_CACHE_VERSION))
|
||||
.write(data.data(), static_cast<std::streamsize>(size));
|
||||
} catch (const std::ios_base::failure& e) {
|
||||
LOG_WARNING(Render_Vulkan, "Failed to write static pipeline cache: {}", e.what());
|
||||
Common::FS::RemoveFile(filename);
|
||||
}
|
||||
}
|
||||
|
||||
VkFormat Device::GetSupportedFormat(VkFormat wanted_format, VkFormatFeatureFlags wanted_usage,
|
||||
FormatType format_type) const {
|
||||
if (IsFormatSupported(wanted_format, wanted_usage, format_type)) {
|
||||
|
||||
@@ -282,6 +282,10 @@ public:
|
||||
return physical;
|
||||
}
|
||||
|
||||
VkPipelineCache StaticPipelineCache() const noexcept {
|
||||
return *static_pipeline_cache;
|
||||
}
|
||||
|
||||
/// Returns the main graphics queue.
|
||||
vk::Queue GetGraphicsQueue() const {
|
||||
return graphics_queue;
|
||||
@@ -1184,6 +1188,9 @@ private:
|
||||
/// Returns true if the device natively supports blitting depth stencil images.
|
||||
bool TestDepthStencilBlits(VkFormat format) const;
|
||||
|
||||
void LoadStaticPipelineCache();
|
||||
void SaveStaticPipelineCache() const;
|
||||
|
||||
private:
|
||||
VkInstance instance; ///< Vulkan instance.
|
||||
VmaAllocator allocator; ///< VMA allocator.
|
||||
@@ -1193,6 +1200,8 @@ private:
|
||||
vk::Device logical; ///< Logical device.
|
||||
vk::Queue graphics_queue; ///< Main graphics queue.
|
||||
vk::Queue present_queue; ///< Main present queue.
|
||||
vk::PipelineCache static_pipeline_cache;
|
||||
bool owns_static_pipeline_cache{};
|
||||
u32 instance_version{}; ///< Vulkan instance version.
|
||||
u32 graphics_family{}; ///< Main graphics queue family index.
|
||||
u32 present_family{}; ///< Main present queue family index.
|
||||
|
||||
Reference in New Issue
Block a user