summaryrefslogtreecommitdiffstats
path: root/src/video_core/renderer_opengl/gl_shader_disk_cache.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/video_core/renderer_opengl/gl_shader_disk_cache.cpp')
-rw-r--r--src/video_core/renderer_opengl/gl_shader_disk_cache.cpp92
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)) {