diff options
| author | 2019-01-15 01:48:29 -0300 | |
|---|---|---|
| committer | 2019-02-06 22:23:39 -0300 | |
| commit | f087639e4a0b7ff5fbe06fe84f78302f89fae1a6 (patch) | |
| tree | 65fadc896c08a20706211b7a4f7dfc1a795e961e /src | |
| parent | gl_shader_disk_cache: Save GLSL and entries into the precompiled file (diff) | |
| download | yuzu-f087639e4a0b7ff5fbe06fe84f78302f89fae1a6.tar.gz yuzu-f087639e4a0b7ff5fbe06fe84f78302f89fae1a6.tar.xz yuzu-f087639e4a0b7ff5fbe06fe84f78302f89fae1a6.zip | |
gl_shader_disk_cache: Compress GLSL code using LZ4
Diffstat (limited to 'src')
| -rw-r--r-- | src/video_core/CMakeLists.txt | 2 | ||||
| -rw-r--r-- | src/video_core/renderer_opengl/gl_shader_disk_cache.cpp | 61 |
2 files changed, 57 insertions, 6 deletions
diff --git a/src/video_core/CMakeLists.txt b/src/video_core/CMakeLists.txt index 48be37082..33e507e69 100644 --- a/src/video_core/CMakeLists.txt +++ b/src/video_core/CMakeLists.txt | |||
| @@ -104,4 +104,4 @@ add_library(video_core STATIC | |||
| 104 | create_target_directory_groups(video_core) | 104 | create_target_directory_groups(video_core) |
| 105 | 105 | ||
| 106 | target_link_libraries(video_core PUBLIC common core) | 106 | target_link_libraries(video_core PUBLIC common core) |
| 107 | target_link_libraries(video_core PRIVATE glad) | 107 | target_link_libraries(video_core PRIVATE glad lz4_static) |
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 7628a74c2..bea4b29d1 100644 --- a/src/video_core/renderer_opengl/gl_shader_disk_cache.cpp +++ b/src/video_core/renderer_opengl/gl_shader_disk_cache.cpp | |||
| @@ -5,8 +5,8 @@ | |||
| 5 | #pragma once | 5 | #pragma once |
| 6 | 6 | ||
| 7 | #include <cstring> | 7 | #include <cstring> |
| 8 | |||
| 9 | #include <fmt/format.h> | 8 | #include <fmt/format.h> |
| 9 | #include <lz4.h> | ||
| 10 | 10 | ||
| 11 | #include "common/assert.h" | 11 | #include "common/assert.h" |
| 12 | #include "common/common_paths.h" | 12 | #include "common/common_paths.h" |
| @@ -51,6 +51,35 @@ std::string GetShaderHash() { | |||
| 51 | std::strncpy(hash.data(), Common::g_shader_cache_version, ShaderHashSize); | 51 | std::strncpy(hash.data(), Common::g_shader_cache_version, ShaderHashSize); |
| 52 | return std::string(hash.data()); | 52 | return std::string(hash.data()); |
| 53 | } | 53 | } |
| 54 | |||
| 55 | template <typename T> | ||
| 56 | std::vector<u8> CompressData(const T* source, std::size_t source_size) { | ||
| 57 | const auto source_size_int = static_cast<int>(source_size); | ||
| 58 | const int max_compressed_size = LZ4_compressBound(source_size_int); | ||
| 59 | std::vector<u8> compressed(max_compressed_size); | ||
| 60 | const int compressed_size = LZ4_compress_default(reinterpret_cast<const char*>(source), | ||
| 61 | reinterpret_cast<char*>(compressed.data()), | ||
| 62 | source_size_int, max_compressed_size); | ||
| 63 | if (compressed_size < 0) { | ||
| 64 | // Compression failed | ||
| 65 | return {}; | ||
| 66 | } | ||
| 67 | compressed.resize(compressed_size); | ||
| 68 | return compressed; | ||
| 69 | } | ||
| 70 | |||
| 71 | std::vector<u8> DecompressData(const std::vector<u8>& compressed, std::size_t uncompressed_size) { | ||
| 72 | std::vector<u8> uncompressed(uncompressed_size); | ||
| 73 | const int size_check = LZ4_decompress_safe(reinterpret_cast<const char*>(compressed.data()), | ||
| 74 | reinterpret_cast<char*>(uncompressed.data()), | ||
| 75 | static_cast<int>(compressed.size()), | ||
| 76 | static_cast<int>(uncompressed.size())); | ||
| 77 | if (static_cast<int>(uncompressed_size) != size_check) { | ||
| 78 | // Decompression failed | ||
| 79 | return {}; | ||
| 80 | } | ||
| 81 | return uncompressed; | ||
| 82 | } | ||
| 54 | } // namespace | 83 | } // namespace |
| 55 | 84 | ||
| 56 | ShaderDiskCacheRaw::ShaderDiskCacheRaw(FileUtil::IOFile& file) { | 85 | ShaderDiskCacheRaw::ShaderDiskCacheRaw(FileUtil::IOFile& file) { |
| @@ -175,10 +204,24 @@ bool ShaderDiskCacheOpenGL::LoadPrecompiled( | |||
| 175 | file.ReadBytes(&unique_identifier, sizeof(u64)); | 204 | file.ReadBytes(&unique_identifier, sizeof(u64)); |
| 176 | 205 | ||
| 177 | u32 code_size{}; | 206 | u32 code_size{}; |
| 207 | u32 compressed_code_size{}; | ||
| 178 | file.ReadBytes(&code_size, sizeof(u32)); | 208 | file.ReadBytes(&code_size, sizeof(u32)); |
| 179 | std::vector<u8> code(code_size); | 209 | file.ReadBytes(&compressed_code_size, sizeof(u32)); |
| 180 | file.ReadArray(code.data(), code.size()); | 210 | |
| 181 | entry.code = std::string(reinterpret_cast<char*>(code.data()), code_size); | 211 | std::vector<u8> compressed_code(compressed_code_size); |
| 212 | file.ReadArray(compressed_code.data(), compressed_code.size()); | ||
| 213 | |||
| 214 | const std::vector<u8> code = DecompressData(compressed_code, code_size); | ||
| 215 | if (code.empty()) { | ||
| 216 | LOG_ERROR(Render_OpenGL, | ||
| 217 | "Failed to decompress GLSL code in precompiled shader={:016x} - removing", | ||
| 218 | unique_identifier); | ||
| 219 | InvalidatePrecompiled(); | ||
| 220 | dumps.clear(); | ||
| 221 | decompiled.clear(); | ||
| 222 | return false; | ||
| 223 | } | ||
| 224 | entry.code = std::string(reinterpret_cast<const char*>(code.data()), code_size); | ||
| 182 | 225 | ||
| 183 | u32 const_buffers_count{}; | 226 | u32 const_buffers_count{}; |
| 184 | file.ReadBytes(&const_buffers_count, sizeof(u32)); | 227 | file.ReadBytes(&const_buffers_count, sizeof(u32)); |
| @@ -321,12 +364,20 @@ void ShaderDiskCacheOpenGL::SaveDecompiled(u64 unique_identifier, const std::str | |||
| 321 | return; | 364 | return; |
| 322 | } | 365 | } |
| 323 | 366 | ||
| 367 | const std::vector<u8> compressed_code{CompressData(code.data(), code.size())}; | ||
| 368 | if (compressed_code.empty()) { | ||
| 369 | LOG_ERROR(Render_OpenGL, "Failed to compress GLSL code - skipping shader {:016x}", | ||
| 370 | unique_identifier); | ||
| 371 | return; | ||
| 372 | } | ||
| 373 | |||
| 324 | file.WriteObject(static_cast<u32>(PrecompiledEntryKind::Decompiled)); | 374 | file.WriteObject(static_cast<u32>(PrecompiledEntryKind::Decompiled)); |
| 325 | 375 | ||
| 326 | file.WriteObject(unique_identifier); | 376 | file.WriteObject(unique_identifier); |
| 327 | 377 | ||
| 328 | file.WriteObject(static_cast<u32>(code.size())); | 378 | file.WriteObject(static_cast<u32>(code.size())); |
| 329 | file.WriteArray(code.data(), code.size()); | 379 | file.WriteObject(static_cast<u32>(compressed_code.size())); |
| 380 | file.WriteArray(compressed_code.data(), compressed_code.size()); | ||
| 330 | 381 | ||
| 331 | file.WriteObject(static_cast<u32>(entries.const_buffers.size())); | 382 | file.WriteObject(static_cast<u32>(entries.const_buffers.size())); |
| 332 | for (const auto& cbuf : entries.const_buffers) { | 383 | for (const auto& cbuf : entries.const_buffers) { |