diff options
Diffstat (limited to '')
-rw-r--r-- | src/video_core/renderer_opengl/gl_shader_disk_cache.cpp | 92 |
1 files changed, 92 insertions, 0 deletions
diff --git a/src/video_core/renderer_opengl/gl_shader_disk_cache.cpp b/src/video_core/renderer_opengl/gl_shader_disk_cache.cpp index de890676e..ef8cfffd6 100644 --- a/src/video_core/renderer_opengl/gl_shader_disk_cache.cpp +++ b/src/video_core/renderer_opengl/gl_shader_disk_cache.cpp @@ -20,8 +20,16 @@ namespace OpenGL { +enum class EntryKind : u32 { + Raw, + Usage, +}; + +constexpr u32 NativeVersion = 1; + // Making sure sizes doesn't change by accident static_assert(sizeof(BaseBindings) == 12); +static_assert(sizeof(ShaderDiskCacheUsage) == 24); namespace { std::string GetTitleID() { @@ -29,6 +37,90 @@ std::string GetTitleID() { } } // namespace +ShaderDiskCacheRaw::ShaderDiskCacheRaw(FileUtil::IOFile& file) { + file.ReadBytes(&unique_identifier, sizeof(u64)); + file.ReadBytes(&program_type, sizeof(u32)); + + u32 program_code_size{}, program_code_size_b{}; + file.ReadBytes(&program_code_size, sizeof(u32)); + file.ReadBytes(&program_code_size_b, sizeof(u32)); + + program_code.resize(program_code_size); + program_code_b.resize(program_code_size_b); + + file.ReadArray(program_code.data(), program_code_size); + if (HasProgramA()) { + file.ReadArray(program_code_b.data(), program_code_size_b); + } +} + +void ShaderDiskCacheRaw::Save(FileUtil::IOFile& file) const { + file.WriteObject(unique_identifier); + file.WriteObject(static_cast<u32>(program_type)); + file.WriteObject(program_code_size); + file.WriteObject(program_code_size_b); + + file.WriteArray(program_code.data(), program_code_size); + if (HasProgramA()) { + file.WriteArray(program_code_b.data(), program_code_size_b); + } +} + +void ShaderDiskCacheOpenGL::SaveRaw(const ShaderDiskCacheRaw& entry) { + const u64 id = entry.GetUniqueIdentifier(); + if (transferable.find(id) != transferable.end()) { + // The shader already exists + return; + } + + FileUtil::IOFile file = AppendTransferableFile(); + if (!file.IsOpen()) { + return; + } + file.WriteObject(EntryKind::Raw); + entry.Save(file); + + transferable.insert({id, {}}); +} + +void ShaderDiskCacheOpenGL::SaveUsage(const ShaderDiskCacheUsage& usage) { + const auto it = transferable.find(usage.unique_identifier); + if (it == transferable.end()) { + LOG_CRITICAL(Render_OpenGL, "Saving shader usage without storing raw previously"); + UNREACHABLE(); + } + auto& usages{it->second}; + ASSERT(usages.find(usage) == usages.end()); + usages.insert(usage); + + FileUtil::IOFile file = AppendTransferableFile(); + if (!file.IsOpen()) { + return; + } + file.WriteObject(EntryKind::Usage); + file.WriteObject(usage); +} + +FileUtil::IOFile ShaderDiskCacheOpenGL::AppendTransferableFile() const { + if (!EnsureDirectories()) { + return {}; + } + + const auto transferable_path{GetTransferablePath()}; + const bool existed = FileUtil::Exists(transferable_path); + + FileUtil::IOFile file(transferable_path, "ab"); + if (!file.IsOpen()) { + LOG_ERROR(Render_OpenGL, "Failed to open transferable cache in path={}", transferable_path); + return {}; + } + if (!existed || file.GetSize() == 0) { + // If the file didn't exist, write its version + file.WriteObject(NativeVersion); + } + return file; +} + bool ShaderDiskCacheOpenGL::EnsureDirectories() const { const auto CreateDir = [](const std::string& dir) { if (!FileUtil::CreateDir(dir)) { |