Browse Source

Funny experiment for pipelines

temporary-branch
CamilleLaVey 3 days ago
parent
commit
eb8706e366
  1. 18
      src/video_core/renderer_vulkan/blit_image.cpp
  2. 2
      src/video_core/renderer_vulkan/present/util.cpp
  3. 2
      src/video_core/renderer_vulkan/vk_compute_pass.cpp
  4. 104
      src/video_core/vulkan_common/vulkan_device.cpp
  5. 9
      src/video_core/vulkan_common/vulkan_device.h

18
src/video_core/renderer_vulkan/blit_image.cpp

@ -1270,7 +1270,7 @@ VkPipeline BlitImageHelper::FindOrEmplaceColorPipeline(const BlitImagePipelineKe
.subpass = 0, .subpass = 0,
.basePipelineHandle = VK_NULL_HANDLE, .basePipelineHandle = VK_NULL_HANDLE,
.basePipelineIndex = 0, .basePipelineIndex = 0,
}));
}, device.StaticPipelineCache()));
return *blit_color_pipelines.back(); return *blit_color_pipelines.back();
} }
@ -1304,7 +1304,7 @@ VkPipeline BlitImageHelper::FindOrEmplaceDepthStencilPipeline(const BlitImagePip
.subpass = 0, .subpass = 0,
.basePipelineHandle = VK_NULL_HANDLE, .basePipelineHandle = VK_NULL_HANDLE,
.basePipelineIndex = 0, .basePipelineIndex = 0,
}));
}, device.StaticPipelineCache()));
return *blit_depth_stencil_pipelines.back(); return *blit_depth_stencil_pipelines.back();
} }
@ -1365,7 +1365,7 @@ VkPipeline BlitImageHelper::FindOrEmplaceClearColorPipeline(const BlitImagePipel
.subpass = 0, .subpass = 0,
.basePipelineHandle = VK_NULL_HANDLE, .basePipelineHandle = VK_NULL_HANDLE,
.basePipelineIndex = 0, .basePipelineIndex = 0,
}));
}, device.StaticPipelineCache()));
return *clear_color_pipelines.back(); return *clear_color_pipelines.back();
} }
@ -1434,7 +1434,7 @@ VkPipeline BlitImageHelper::FindOrEmplaceClearStencilPipeline(
.subpass = 0, .subpass = 0,
.basePipelineHandle = VK_NULL_HANDLE, .basePipelineHandle = VK_NULL_HANDLE,
.basePipelineIndex = 0, .basePipelineIndex = 0,
}));
}, device.StaticPipelineCache()));
return *clear_stencil_pipelines.back(); return *clear_stencil_pipelines.back();
} }
@ -1479,7 +1479,7 @@ VkPipeline BlitImageHelper::FindOrEmplaceBlitColorMSAAPipeline(const BlitMSAAPip
.subpass = 0, .subpass = 0,
.basePipelineHandle = VK_NULL_HANDLE, .basePipelineHandle = VK_NULL_HANDLE,
.basePipelineIndex = 0, .basePipelineIndex = 0,
}));
}, device.StaticPipelineCache()));
return *blit_msaa_color_pipelines.back(); return *blit_msaa_color_pipelines.back();
} }
@ -1523,7 +1523,7 @@ VkPipeline BlitImageHelper::FindOrEmplaceResolveDepthStencilPipeline(
.subpass = 0, .subpass = 0,
.basePipelineHandle = VK_NULL_HANDLE, .basePipelineHandle = VK_NULL_HANDLE,
.basePipelineIndex = 0, .basePipelineIndex = 0,
}));
}, device.StaticPipelineCache()));
return *pipelines.back(); return *pipelines.back();
} }
@ -1596,7 +1596,7 @@ VkPipeline BlitImageHelper::FindOrEmplaceMSAACopyPipeline(const MSAACopyPipeline
.subpass = 0, .subpass = 0,
.basePipelineHandle = VK_NULL_HANDLE, .basePipelineHandle = VK_NULL_HANDLE,
.basePipelineIndex = 0, .basePipelineIndex = 0,
}));
}, device.StaticPipelineCache()));
return *msaa_copy_pipelines.back(); return *msaa_copy_pipelines.back();
} }
@ -1641,7 +1641,7 @@ void BlitImageHelper::ConvertPipelineEx(vk::Pipeline& pipeline, const Framebuffe
.subpass = 0, .subpass = 0,
.basePipelineHandle = VK_NULL_HANDLE, .basePipelineHandle = VK_NULL_HANDLE,
.basePipelineIndex = 0, .basePipelineIndex = 0,
});
}, device.StaticPipelineCache());
} }
void BlitImageHelper::ConvertPipelineColorTargetEx(vk::Pipeline& pipeline, void BlitImageHelper::ConvertPipelineColorTargetEx(vk::Pipeline& pipeline,
@ -1688,7 +1688,7 @@ void BlitImageHelper::ConvertPipeline(vk::Pipeline& pipeline, const Framebuffer*
.subpass = 0, .subpass = 0,
.basePipelineHandle = VK_NULL_HANDLE, .basePipelineHandle = VK_NULL_HANDLE,
.basePipelineIndex = 0, .basePipelineIndex = 0,
});
}, device.StaticPipelineCache());
} }
} // namespace Vulkan } // namespace Vulkan

2
src/video_core/renderer_vulkan/present/util.cpp

@ -491,7 +491,7 @@ static vk::Pipeline CreateWrappedPipelineImpl(
.subpass = 0, .subpass = 0,
.basePipelineHandle = 0, .basePipelineHandle = 0,
.basePipelineIndex = 0, .basePipelineIndex = 0,
});
}, device.StaticPipelineCache());
} }
vk::Pipeline CreateWrappedPipeline(const Device& device, vk::RenderPass& renderpass, vk::Pipeline CreateWrappedPipeline(const Device& device, vk::RenderPass& renderpass,

2
src/video_core/renderer_vulkan/vk_compute_pass.cpp

@ -268,7 +268,7 @@ ComputePass::ComputePass(const Device& device_, Scheduler& scheduler, Descriptor
.layout = *layout, .layout = *layout,
.basePipelineHandle = {}, .basePipelineHandle = {},
.basePipelineIndex = 0, .basePipelineIndex = 0,
});
}, device.StaticPipelineCache());
} }
ComputePass::~ComputePass() = default; ComputePass::~ComputePass() = default;

104
src/video_core/vulkan_common/vulkan_device.cpp

@ -8,6 +8,8 @@
#include <array> #include <array>
#include <bitset> #include <bitset>
#include <chrono> #include <chrono>
#include <filesystem>
#include <fstream>
#include <optional> #include <optional>
#include <thread> #include <thread>
#include <ankerl/unordered_dense.h> #include <ankerl/unordered_dense.h>
@ -17,6 +19,8 @@
#include <fmt/format.h> #include <fmt/format.h>
#include "common/assert.h" #include "common/assert.h"
#include "common/fs/fs.h"
#include "common/fs/path_util.h"
#include "common/literals.h" #include "common/literals.h"
#include <ranges> #include <ranges>
#include "common/settings.h" #include "common/settings.h"
@ -394,6 +398,17 @@ std::vector<const char*> ExtensionListForVulkan(
return output; 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 } // Anonymous namespace
void Device::RemoveExtension(bool& extension, const std::string& extension_name) { void Device::RemoveExtension(bool& extension, const std::string& extension_name) {
@ -778,16 +793,105 @@ Device::Device(VkInstance instance_, vk::PhysicalDevice physical_, VkSurfaceKHR
limits.storageImageSampleCounts); limits.storageImageSampleCounts);
} }
owns_static_pipeline_cache = surface != VkSurfaceKHR{};
LoadStaticPipelineCache();
// Initialize GPU logging if enabled // Initialize GPU logging if enabled
InitializeGPULogging(); InitializeGPULogging();
} }
Device::~Device() { Device::~Device() {
SaveStaticPipelineCache();
ShutdownGPULogging(); ShutdownGPULogging();
vk::FlushDeletionQueue(); vk::FlushDeletionQueue();
vmaDestroyAllocator(allocator); 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, VkFormat Device::GetSupportedFormat(VkFormat wanted_format, VkFormatFeatureFlags wanted_usage,
FormatType format_type) const { FormatType format_type) const {
if (IsFormatSupported(wanted_format, wanted_usage, format_type)) { if (IsFormatSupported(wanted_format, wanted_usage, format_type)) {

9
src/video_core/vulkan_common/vulkan_device.h

@ -282,6 +282,10 @@ public:
return physical; return physical;
} }
VkPipelineCache StaticPipelineCache() const noexcept {
return *static_pipeline_cache;
}
/// Returns the main graphics queue. /// Returns the main graphics queue.
vk::Queue GetGraphicsQueue() const { vk::Queue GetGraphicsQueue() const {
return graphics_queue; return graphics_queue;
@ -1184,6 +1188,9 @@ private:
/// Returns true if the device natively supports blitting depth stencil images. /// Returns true if the device natively supports blitting depth stencil images.
bool TestDepthStencilBlits(VkFormat format) const; bool TestDepthStencilBlits(VkFormat format) const;
void LoadStaticPipelineCache();
void SaveStaticPipelineCache() const;
private: private:
VkInstance instance; ///< Vulkan instance. VkInstance instance; ///< Vulkan instance.
VmaAllocator allocator; ///< VMA allocator. VmaAllocator allocator; ///< VMA allocator.
@ -1193,6 +1200,8 @@ private:
vk::Device logical; ///< Logical device. vk::Device logical; ///< Logical device.
vk::Queue graphics_queue; ///< Main graphics queue. vk::Queue graphics_queue; ///< Main graphics queue.
vk::Queue present_queue; ///< Main present 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 instance_version{}; ///< Vulkan instance version.
u32 graphics_family{}; ///< Main graphics queue family index. u32 graphics_family{}; ///< Main graphics queue family index.
u32 present_family{}; ///< Main present queue family index. u32 present_family{}; ///< Main present queue family index.

Loading…
Cancel
Save