shader_environment: Receive cache version from outside

This allows us invalidating OpenGL and Vulkan separately in the future.
This commit is contained in:
ReinUsesLisp 2021-07-18 21:07:12 -03:00 committed by ameerj
parent 4a82450c81
commit 258f35515d
4 changed files with 23 additions and 16 deletions

View file

@ -48,9 +48,12 @@ using VideoCommon::ComputeEnvironment;
using VideoCommon::FileEnvironment; using VideoCommon::FileEnvironment;
using VideoCommon::GenericEnvironment; using VideoCommon::GenericEnvironment;
using VideoCommon::GraphicsEnvironment; using VideoCommon::GraphicsEnvironment;
using VideoCommon::LoadPipelines;
using VideoCommon::SerializePipeline; using VideoCommon::SerializePipeline;
using Context = ShaderContext::Context; using Context = ShaderContext::Context;
constexpr u32 CACHE_VERSION = 5;
template <typename Container> template <typename Container>
auto MakeSpan(Container& container) { auto MakeSpan(Container& container) {
return std::span(container.data(), container.size()); return std::span(container.data(), container.size());
@ -287,7 +290,7 @@ void ShaderCache::LoadDiskResources(u64 title_id, std::stop_token stop_loading,
}); });
++state.total; ++state.total;
}}; }};
VideoCommon::LoadPipelines(stop_loading, shader_cache_filename, load_compute, load_graphics); LoadPipelines(stop_loading, shader_cache_filename, CACHE_VERSION, load_compute, load_graphics);
std::unique_lock lock{state.mutex}; std::unique_lock lock{state.mutex};
callback(VideoCore::LoadCallbackStage::Build, 0, state.total); callback(VideoCore::LoadCallbackStage::Build, 0, state.total);
@ -394,7 +397,7 @@ std::unique_ptr<GraphicsPipeline> ShaderCache::CreateGraphicsPipeline() {
env_ptrs.push_back(&environments.envs[index]); env_ptrs.push_back(&environments.envs[index]);
} }
} }
SerializePipeline(graphics_key, env_ptrs, shader_cache_filename); SerializePipeline(graphics_key, env_ptrs, shader_cache_filename, CACHE_VERSION);
return pipeline; return pipeline;
} }
@ -492,7 +495,8 @@ std::unique_ptr<ComputePipeline> ShaderCache::CreateComputePipeline(
if (!pipeline || shader_cache_filename.empty()) { if (!pipeline || shader_cache_filename.empty()) {
return pipeline; return pipeline;
} }
SerializePipeline(key, std::array<const GenericEnvironment*, 1>{&env}, shader_cache_filename); SerializePipeline(key, std::array<const GenericEnvironment*, 1>{&env}, shader_cache_filename,
CACHE_VERSION);
return pipeline; return pipeline;
} }

View file

@ -54,6 +54,8 @@ using VideoCommon::FileEnvironment;
using VideoCommon::GenericEnvironment; using VideoCommon::GenericEnvironment;
using VideoCommon::GraphicsEnvironment; using VideoCommon::GraphicsEnvironment;
constexpr u32 CACHE_VERSION = 5;
template <typename Container> template <typename Container>
auto MakeSpan(Container& container) { auto MakeSpan(Container& container) {
return std::span(container.data(), container.size()); return std::span(container.data(), container.size());
@ -434,7 +436,8 @@ void PipelineCache::LoadDiskResources(u64 title_id, std::stop_token stop_loading
}); });
++state.total; ++state.total;
}}; }};
VideoCommon::LoadPipelines(stop_loading, pipeline_cache_filename, load_compute, load_graphics); VideoCommon::LoadPipelines(stop_loading, pipeline_cache_filename, CACHE_VERSION, load_compute,
load_graphics);
std::unique_lock lock{state.mutex}; std::unique_lock lock{state.mutex};
callback(VideoCore::LoadCallbackStage::Build, 0, state.total); callback(VideoCore::LoadCallbackStage::Build, 0, state.total);
@ -562,7 +565,7 @@ std::unique_ptr<GraphicsPipeline> PipelineCache::CreateGraphicsPipeline() {
env_ptrs.push_back(&envs[index]); env_ptrs.push_back(&envs[index]);
} }
} }
SerializePipeline(key, env_ptrs, pipeline_cache_filename); SerializePipeline(key, env_ptrs, pipeline_cache_filename, CACHE_VERSION);
}); });
return pipeline; return pipeline;
} }
@ -581,7 +584,7 @@ std::unique_ptr<ComputePipeline> PipelineCache::CreateComputePipeline(
} }
serialization_thread.QueueWork([this, key, env = std::move(env)] { serialization_thread.QueueWork([this, key, env = std::move(env)] {
SerializePipeline(key, std::array<const GenericEnvironment*, 1>{&env}, SerializePipeline(key, std::array<const GenericEnvironment*, 1>{&env},
pipeline_cache_filename); pipeline_cache_filename, CACHE_VERSION);
}); });
return pipeline; return pipeline;
} }

View file

@ -22,7 +22,6 @@
namespace VideoCommon { namespace VideoCommon {
constexpr std::array<char, 8> MAGIC_NUMBER{'y', 'u', 'z', 'u', 'c', 'a', 'c', 'h'}; constexpr std::array<char, 8> MAGIC_NUMBER{'y', 'u', 'z', 'u', 'c', 'a', 'c', 'h'};
constexpr u32 CACHE_VERSION = 5;
constexpr size_t INST_SIZE = sizeof(u64); constexpr size_t INST_SIZE = sizeof(u64);
@ -370,7 +369,7 @@ std::array<u32, 3> FileEnvironment::WorkgroupSize() const {
} }
void SerializePipeline(std::span<const char> key, std::span<const GenericEnvironment* const> envs, void SerializePipeline(std::span<const char> key, std::span<const GenericEnvironment* const> envs,
const std::filesystem::path& filename) try { const std::filesystem::path& filename, u32 cache_version) try {
std::ofstream file(filename, std::ios::binary | std::ios::ate | std::ios::app); std::ofstream file(filename, std::ios::binary | std::ios::ate | std::ios::app);
file.exceptions(std::ifstream::failbit); file.exceptions(std::ifstream::failbit);
if (!file.is_open()) { if (!file.is_open()) {
@ -381,7 +380,7 @@ void SerializePipeline(std::span<const char> key, std::span<const GenericEnviron
if (file.tellp() == 0) { if (file.tellp() == 0) {
// Write header // Write header
file.write(MAGIC_NUMBER.data(), MAGIC_NUMBER.size()) file.write(MAGIC_NUMBER.data(), MAGIC_NUMBER.size())
.write(reinterpret_cast<const char*>(&CACHE_VERSION), sizeof(CACHE_VERSION)); .write(reinterpret_cast<const char*>(&cache_version), sizeof(cache_version));
} }
if (!std::ranges::all_of(envs, &GenericEnvironment::CanBeSerialized)) { if (!std::ranges::all_of(envs, &GenericEnvironment::CanBeSerialized)) {
return; return;
@ -402,7 +401,7 @@ void SerializePipeline(std::span<const char> key, std::span<const GenericEnviron
} }
void LoadPipelines( void LoadPipelines(
std::stop_token stop_loading, const std::filesystem::path& filename, std::stop_token stop_loading, const std::filesystem::path& filename, u32 expected_cache_version,
Common::UniqueFunction<void, std::ifstream&, FileEnvironment> load_compute, Common::UniqueFunction<void, std::ifstream&, FileEnvironment> load_compute,
Common::UniqueFunction<void, std::ifstream&, std::vector<FileEnvironment>> load_graphics) try { Common::UniqueFunction<void, std::ifstream&, std::vector<FileEnvironment>> load_graphics) try {
std::ifstream file(filename, std::ios::binary | std::ios::ate); std::ifstream file(filename, std::ios::binary | std::ios::ate);
@ -417,13 +416,13 @@ void LoadPipelines(
u32 cache_version; u32 cache_version;
file.read(magic_number.data(), magic_number.size()) file.read(magic_number.data(), magic_number.size())
.read(reinterpret_cast<char*>(&cache_version), sizeof(cache_version)); .read(reinterpret_cast<char*>(&cache_version), sizeof(cache_version));
if (magic_number != MAGIC_NUMBER || cache_version != CACHE_VERSION) { if (magic_number != MAGIC_NUMBER || cache_version != expected_cache_version) {
file.close(); file.close();
if (Common::FS::RemoveFile(filename)) { if (Common::FS::RemoveFile(filename)) {
if (magic_number != MAGIC_NUMBER) { if (magic_number != MAGIC_NUMBER) {
LOG_ERROR(Common_Filesystem, "Invalid pipeline cache file"); LOG_ERROR(Common_Filesystem, "Invalid pipeline cache file");
} }
if (cache_version != CACHE_VERSION) { if (cache_version != expected_cache_version) {
LOG_INFO(Common_Filesystem, "Deleting old pipeline cache"); LOG_INFO(Common_Filesystem, "Deleting old pipeline cache");
} }
} else { } else {

View file

@ -164,18 +164,19 @@ private:
}; };
void SerializePipeline(std::span<const char> key, std::span<const GenericEnvironment* const> envs, void SerializePipeline(std::span<const char> key, std::span<const GenericEnvironment* const> envs,
const std::filesystem::path& filename); const std::filesystem::path& filename, u32 cache_version);
template <typename Key, typename Envs> template <typename Key, typename Envs>
void SerializePipeline(const Key& key, const Envs& envs, const std::filesystem::path& filename) { void SerializePipeline(const Key& key, const Envs& envs, const std::filesystem::path& filename,
u32 cache_version) {
static_assert(std::is_trivially_copyable_v<Key>); static_assert(std::is_trivially_copyable_v<Key>);
static_assert(std::has_unique_object_representations_v<Key>); static_assert(std::has_unique_object_representations_v<Key>);
SerializePipeline(std::span(reinterpret_cast<const char*>(&key), sizeof(key)), SerializePipeline(std::span(reinterpret_cast<const char*>(&key), sizeof(key)),
std::span(envs.data(), envs.size()), filename); std::span(envs.data(), envs.size()), filename, cache_version);
} }
void LoadPipelines( void LoadPipelines(
std::stop_token stop_loading, const std::filesystem::path& filename, std::stop_token stop_loading, const std::filesystem::path& filename, u32 expected_cache_version,
Common::UniqueFunction<void, std::ifstream&, FileEnvironment> load_compute, Common::UniqueFunction<void, std::ifstream&, FileEnvironment> load_compute,
Common::UniqueFunction<void, std::ifstream&, std::vector<FileEnvironment>> load_graphics); Common::UniqueFunction<void, std::ifstream&, std::vector<FileEnvironment>> load_graphics);