vk_pipeline_cache: Make pipeline cache reads more robust (#7194)
This commit is contained in:
parent
85bd1be852
commit
1dc0fa7bb5
|
@ -8,6 +8,7 @@
|
||||||
#include "common/file_util.h"
|
#include "common/file_util.h"
|
||||||
#include "common/logging/log.h"
|
#include "common/logging/log.h"
|
||||||
#include "common/microprofile.h"
|
#include "common/microprofile.h"
|
||||||
|
#include "common/scope_exit.h"
|
||||||
#include "common/settings.h"
|
#include "common/settings.h"
|
||||||
#include "video_core/renderer_vulkan/pica_to_vk.h"
|
#include "video_core/renderer_vulkan/pica_to_vk.h"
|
||||||
#include "video_core/renderer_vulkan/vk_instance.h"
|
#include "video_core/renderer_vulkan/vk_instance.h"
|
||||||
|
@ -128,34 +129,42 @@ void PipelineCache::LoadDiskCache() {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const std::string cache_file_path = fmt::format("{}{:x}{:x}.bin", GetPipelineCacheDir(),
|
const auto cache_dir = GetPipelineCacheDir();
|
||||||
instance.GetVendorID(), instance.GetDeviceID());
|
const u32 vendor_id = instance.GetVendorID();
|
||||||
vk::PipelineCacheCreateInfo cache_info = {
|
const u32 device_id = instance.GetDeviceID();
|
||||||
.initialDataSize = 0,
|
const auto cache_file_path = fmt::format("{}{:x}{:x}.bin", cache_dir, vendor_id, device_id);
|
||||||
.pInitialData = nullptr,
|
|
||||||
};
|
|
||||||
|
|
||||||
|
vk::PipelineCacheCreateInfo cache_info{};
|
||||||
std::vector<u8> cache_data;
|
std::vector<u8> cache_data;
|
||||||
FileUtil::IOFile cache_file{cache_file_path, "r"};
|
|
||||||
if (cache_file.IsOpen()) {
|
|
||||||
LOG_INFO(Render_Vulkan, "Loading pipeline cache");
|
|
||||||
|
|
||||||
const u64 cache_file_size = cache_file.GetSize();
|
SCOPE_EXIT({
|
||||||
cache_data.resize(cache_file_size);
|
const vk::Device device = instance.GetDevice();
|
||||||
if (cache_file.ReadBytes(cache_data.data(), cache_file_size)) {
|
pipeline_cache = device.createPipelineCacheUnique(cache_info);
|
||||||
if (!IsCacheValid(cache_data)) {
|
});
|
||||||
LOG_WARNING(Render_Vulkan, "Pipeline cache provided invalid, ignoring");
|
|
||||||
} else {
|
|
||||||
cache_info.initialDataSize = cache_file_size;
|
|
||||||
cache_info.pInitialData = cache_data.data();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
cache_file.Close();
|
FileUtil::IOFile cache_file{cache_file_path, "rb"};
|
||||||
|
if (!cache_file.IsOpen()) {
|
||||||
|
LOG_INFO(Render_Vulkan, "No pipeline cache found for device");
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
vk::Device device = instance.GetDevice();
|
const u64 cache_file_size = cache_file.GetSize();
|
||||||
pipeline_cache = device.createPipelineCacheUnique(cache_info);
|
cache_data.resize(cache_file_size);
|
||||||
|
if (cache_file.ReadBytes(cache_data.data(), cache_file_size) != cache_file_size) {
|
||||||
|
LOG_ERROR(Render_Vulkan, "Error during pipeline cache read");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!IsCacheValid(cache_data)) {
|
||||||
|
LOG_WARNING(Render_Vulkan, "Pipeline cache provided invalid, removing");
|
||||||
|
cache_file.Close();
|
||||||
|
FileUtil::Delete(cache_file_path);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
LOG_INFO(Render_Vulkan, "Loading pipeline cache with size {} KB", cache_file_size / 1024);
|
||||||
|
cache_info.initialDataSize = cache_file_size;
|
||||||
|
cache_info.pInitialData = cache_data.data();
|
||||||
}
|
}
|
||||||
|
|
||||||
void PipelineCache::SaveDiskCache() {
|
void PipelineCache::SaveDiskCache() {
|
||||||
|
@ -163,22 +172,23 @@ void PipelineCache::SaveDiskCache() {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const std::string cache_file_path = fmt::format("{}{:x}{:x}.bin", GetPipelineCacheDir(),
|
const auto cache_dir = GetPipelineCacheDir();
|
||||||
instance.GetVendorID(), instance.GetDeviceID());
|
const u32 vendor_id = instance.GetVendorID();
|
||||||
|
const u32 device_id = instance.GetDeviceID();
|
||||||
|
const auto cache_file_path = fmt::format("{}{:x}{:x}.bin", cache_dir, vendor_id, device_id);
|
||||||
|
|
||||||
FileUtil::IOFile cache_file{cache_file_path, "wb"};
|
FileUtil::IOFile cache_file{cache_file_path, "wb"};
|
||||||
if (!cache_file.IsOpen()) {
|
if (!cache_file.IsOpen()) {
|
||||||
LOG_ERROR(Render_Vulkan, "Unable to open pipeline cache for writing");
|
LOG_ERROR(Render_Vulkan, "Unable to open pipeline cache for writing");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
vk::Device device = instance.GetDevice();
|
const vk::Device device = instance.GetDevice();
|
||||||
auto cache_data = device.getPipelineCacheData(*pipeline_cache);
|
const auto cache_data = device.getPipelineCacheData(*pipeline_cache);
|
||||||
if (!cache_file.WriteBytes(cache_data.data(), cache_data.size())) {
|
if (cache_file.WriteBytes(cache_data.data(), cache_data.size()) != cache_data.size()) {
|
||||||
LOG_ERROR(Render_Vulkan, "Error during pipeline cache write");
|
LOG_ERROR(Render_Vulkan, "Error during pipeline cache write");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
cache_file.Close();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool PipelineCache::BindPipeline(const PipelineInfo& info, bool wait_built) {
|
bool PipelineCache::BindPipeline(const PipelineInfo& info, bool wait_built) {
|
||||||
|
|
Loading…
Reference in New Issue