|
|
@ -366,7 +366,8 @@ PipelineCache::PipelineCache(RasterizerVulkan& rasterizer_, const Device& device |
|
|
|
|
|
|
|
|
PipelineCache::~PipelineCache() { |
|
|
PipelineCache::~PipelineCache() { |
|
|
if (use_vulkan_pipeline_cache && !vulkan_pipeline_cache_filename.empty()) { |
|
|
if (use_vulkan_pipeline_cache && !vulkan_pipeline_cache_filename.empty()) { |
|
|
SerializeVulkanPipelineCache(vulkan_pipeline_cache_filename, vulkan_pipeline_cache); |
|
|
|
|
|
|
|
|
SerializeVulkanPipelineCache(vulkan_pipeline_cache_filename, vulkan_pipeline_cache, |
|
|
|
|
|
CACHE_VERSION); |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
@ -426,7 +427,8 @@ void PipelineCache::LoadDiskResources(u64 title_id, std::stop_token stop_loading |
|
|
|
|
|
|
|
|
if (use_vulkan_pipeline_cache) { |
|
|
if (use_vulkan_pipeline_cache) { |
|
|
vulkan_pipeline_cache_filename = base_dir / "vulkan_pipelines.bin"; |
|
|
vulkan_pipeline_cache_filename = base_dir / "vulkan_pipelines.bin"; |
|
|
vulkan_pipeline_cache = LoadVulkanPipelineCache(vulkan_pipeline_cache_filename); |
|
|
|
|
|
|
|
|
vulkan_pipeline_cache = |
|
|
|
|
|
LoadVulkanPipelineCache(vulkan_pipeline_cache_filename, CACHE_VERSION); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
struct { |
|
|
struct { |
|
|
@ -508,7 +510,8 @@ void PipelineCache::LoadDiskResources(u64 title_id, std::stop_token stop_loading |
|
|
workers.WaitForRequests(stop_loading); |
|
|
workers.WaitForRequests(stop_loading); |
|
|
|
|
|
|
|
|
if (use_vulkan_pipeline_cache) { |
|
|
if (use_vulkan_pipeline_cache) { |
|
|
SerializeVulkanPipelineCache(vulkan_pipeline_cache_filename, vulkan_pipeline_cache); |
|
|
|
|
|
|
|
|
SerializeVulkanPipelineCache(vulkan_pipeline_cache_filename, vulkan_pipeline_cache, |
|
|
|
|
|
CACHE_VERSION); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
if (state.statistics) { |
|
|
if (state.statistics) { |
|
|
@ -714,15 +717,17 @@ std::unique_ptr<ComputePipeline> PipelineCache::CreateComputePipeline( |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
void PipelineCache::SerializeVulkanPipelineCache(const std::filesystem::path& filename, |
|
|
void PipelineCache::SerializeVulkanPipelineCache(const std::filesystem::path& filename, |
|
|
const vk::PipelineCache& pipeline_cache) try { |
|
|
|
|
|
|
|
|
const vk::PipelineCache& pipeline_cache, |
|
|
|
|
|
u32 cache_version) try { |
|
|
std::ofstream file(filename, std::ios::binary); |
|
|
std::ofstream file(filename, std::ios::binary); |
|
|
file.exceptions(std::ifstream::failbit); |
|
|
file.exceptions(std::ifstream::failbit); |
|
|
if (!file.is_open()) { |
|
|
if (!file.is_open()) { |
|
|
LOG_ERROR(Common_Filesystem, "Failed to open Vulkan pipeline cache file {}", |
|
|
|
|
|
|
|
|
LOG_ERROR(Common_Filesystem, "Failed to open Vulkan driver pipeline cache file {}", |
|
|
Common::FS::PathToUTF8String(filename)); |
|
|
Common::FS::PathToUTF8String(filename)); |
|
|
return; |
|
|
return; |
|
|
} |
|
|
} |
|
|
file.write(VULKAN_CACHE_MAGIC_NUMBER.data(), VULKAN_CACHE_MAGIC_NUMBER.size()); |
|
|
|
|
|
|
|
|
file.write(VULKAN_CACHE_MAGIC_NUMBER.data(), VULKAN_CACHE_MAGIC_NUMBER.size()) |
|
|
|
|
|
.write(reinterpret_cast<const char*>(&cache_version), sizeof(cache_version)); |
|
|
|
|
|
|
|
|
size_t cache_size = 0; |
|
|
size_t cache_size = 0; |
|
|
std::vector<char> cache_data; |
|
|
std::vector<char> cache_data; |
|
|
@ -733,18 +738,19 @@ void PipelineCache::SerializeVulkanPipelineCache(const std::filesystem::path& fi |
|
|
} |
|
|
} |
|
|
file.write(cache_data.data(), cache_size); |
|
|
file.write(cache_data.data(), cache_size); |
|
|
|
|
|
|
|
|
LOG_INFO(Render_Vulkan, "Vulkan pipelines cached at: {}", |
|
|
|
|
|
|
|
|
LOG_INFO(Render_Vulkan, "Vulkan driver pipelines cached at: {}", |
|
|
Common::FS::PathToUTF8String(filename)); |
|
|
Common::FS::PathToUTF8String(filename)); |
|
|
|
|
|
|
|
|
} catch (const std::ios_base::failure& e) { |
|
|
} catch (const std::ios_base::failure& e) { |
|
|
LOG_ERROR(Common_Filesystem, "{}", e.what()); |
|
|
LOG_ERROR(Common_Filesystem, "{}", e.what()); |
|
|
if (!Common::FS::RemoveFile(filename)) { |
|
|
if (!Common::FS::RemoveFile(filename)) { |
|
|
LOG_ERROR(Common_Filesystem, "Failed to delete Vulkan pipeline cache file {}", |
|
|
|
|
|
|
|
|
LOG_ERROR(Common_Filesystem, "Failed to delete Vulkan driver pipeline cache file {}", |
|
|
Common::FS::PathToUTF8String(filename)); |
|
|
Common::FS::PathToUTF8String(filename)); |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
vk::PipelineCache PipelineCache::LoadVulkanPipelineCache(const std::filesystem::path& filename) { |
|
|
|
|
|
|
|
|
vk::PipelineCache PipelineCache::LoadVulkanPipelineCache(const std::filesystem::path& filename, |
|
|
|
|
|
u32 expected_cache_version) { |
|
|
const auto create_pipeline_cache = [this](size_t data_size, const void* data) { |
|
|
const auto create_pipeline_cache = [this](size_t data_size, const void* data) { |
|
|
VkPipelineCacheCreateInfo pipeline_cache_ci = { |
|
|
VkPipelineCacheCreateInfo pipeline_cache_ci = { |
|
|
.sType = VK_STRUCTURE_TYPE_PIPELINE_CACHE_CREATE_INFO, |
|
|
.sType = VK_STRUCTURE_TYPE_PIPELINE_CACHE_CREATE_INFO, |
|
|
@ -764,12 +770,17 @@ vk::PipelineCache PipelineCache::LoadVulkanPipelineCache(const std::filesystem:: |
|
|
file.seekg(0, std::ios::beg); |
|
|
file.seekg(0, std::ios::beg); |
|
|
|
|
|
|
|
|
std::array<char, 8> magic_number; |
|
|
std::array<char, 8> magic_number; |
|
|
file.read(magic_number.data(), magic_number.size()); |
|
|
|
|
|
if (magic_number != VULKAN_CACHE_MAGIC_NUMBER) { |
|
|
|
|
|
|
|
|
u32 cache_version; |
|
|
|
|
|
file.read(magic_number.data(), magic_number.size()) |
|
|
|
|
|
.read(reinterpret_cast<char*>(&cache_version), sizeof(cache_version)); |
|
|
|
|
|
if (magic_number != VULKAN_CACHE_MAGIC_NUMBER || cache_version != expected_cache_version) { |
|
|
file.close(); |
|
|
file.close(); |
|
|
if (Common::FS::RemoveFile(filename)) { |
|
|
if (Common::FS::RemoveFile(filename)) { |
|
|
if (magic_number != VULKAN_CACHE_MAGIC_NUMBER) { |
|
|
if (magic_number != VULKAN_CACHE_MAGIC_NUMBER) { |
|
|
LOG_ERROR(Common_Filesystem, "Invalid Vulkan pipeline cache file"); |
|
|
|
|
|
|
|
|
LOG_ERROR(Common_Filesystem, "Invalid Vulkan driver pipeline cache file"); |
|
|
|
|
|
} |
|
|
|
|
|
if (cache_version != expected_cache_version) { |
|
|
|
|
|
LOG_INFO(Common_Filesystem, "Deleting old Vulkan driver pipeline cache"); |
|
|
} |
|
|
} |
|
|
} else { |
|
|
} else { |
|
|
LOG_ERROR(Common_Filesystem, |
|
|
LOG_ERROR(Common_Filesystem, |
|
|
@ -784,14 +795,14 @@ vk::PipelineCache PipelineCache::LoadVulkanPipelineCache(const std::filesystem:: |
|
|
file.read(cache_data.data(), cache_size); |
|
|
file.read(cache_data.data(), cache_size); |
|
|
|
|
|
|
|
|
LOG_INFO(Render_Vulkan, |
|
|
LOG_INFO(Render_Vulkan, |
|
|
"Loaded Vulkan pipeline cache: ", Common::FS::PathToUTF8String(filename)); |
|
|
|
|
|
|
|
|
"Loaded Vulkan driver pipeline cache: ", Common::FS::PathToUTF8String(filename)); |
|
|
|
|
|
|
|
|
return create_pipeline_cache(cache_size, cache_data.data()); |
|
|
return create_pipeline_cache(cache_size, cache_data.data()); |
|
|
|
|
|
|
|
|
} catch (const std::ios_base::failure& e) { |
|
|
} catch (const std::ios_base::failure& e) { |
|
|
LOG_ERROR(Common_Filesystem, "{}", e.what()); |
|
|
LOG_ERROR(Common_Filesystem, "{}", e.what()); |
|
|
if (!Common::FS::RemoveFile(filename)) { |
|
|
if (!Common::FS::RemoveFile(filename)) { |
|
|
LOG_ERROR(Common_Filesystem, "Failed to delete Vulkan pipeline cache file {}", |
|
|
|
|
|
|
|
|
LOG_ERROR(Common_Filesystem, "Failed to delete Vulkan driver pipeline cache file {}", |
|
|
Common::FS::PathToUTF8String(filename)); |
|
|
Common::FS::PathToUTF8String(filename)); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|