summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/video_core/renderer_opengl/gl_shader_disk_cache.cpp54
-rw-r--r--src/video_core/renderer_opengl/gl_shader_disk_cache.h28
2 files changed, 48 insertions, 34 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 254c0d499..fba9c594a 100644
--- a/src/video_core/renderer_opengl/gl_shader_disk_cache.cpp
+++ b/src/video_core/renderer_opengl/gl_shader_disk_cache.cpp
@@ -104,8 +104,9 @@ bool ShaderDiskCacheRaw::Save(FileUtil::IOFile& file) const {
104 return true; 104 return true;
105} 105}
106 106
107ShaderDiskCacheOpenGL::ShaderDiskCacheOpenGL(Core::System& system) 107ShaderDiskCacheOpenGL::ShaderDiskCacheOpenGL(Core::System& system) : system{system} {}
108 : system{system}, precompiled_cache_virtual_file_offset{0} {} 108
109ShaderDiskCacheOpenGL::~ShaderDiskCacheOpenGL() = default;
109 110
110std::optional<std::pair<std::vector<ShaderDiskCacheRaw>, std::vector<ShaderDiskCacheUsage>>> 111std::optional<std::pair<std::vector<ShaderDiskCacheRaw>, std::vector<ShaderDiskCacheUsage>>>
111ShaderDiskCacheOpenGL::LoadTransferable() { 112ShaderDiskCacheOpenGL::LoadTransferable() {
@@ -243,7 +244,7 @@ ShaderDiskCacheOpenGL::LoadPrecompiledFile(FileUtil::IOFile& file) {
243 return {}; 244 return {};
244 } 245 }
245 246
246 const auto entry = LoadDecompiledEntry(); 247 auto entry = LoadDecompiledEntry();
247 if (!entry) { 248 if (!entry) {
248 return {}; 249 return {};
249 } 250 }
@@ -287,13 +288,13 @@ std::optional<ShaderDiskCacheDecompiled> ShaderDiskCacheOpenGL::LoadDecompiledEn
287 return {}; 288 return {};
288 } 289 }
289 290
290 std::vector<u8> code(code_size); 291 std::string code(code_size, '\0');
291 if (!LoadArrayFromPrecompiled(code.data(), code.size())) { 292 if (!LoadArrayFromPrecompiled(code.data(), code.size())) {
292 return {}; 293 return {};
293 } 294 }
294 295
295 ShaderDiskCacheDecompiled entry; 296 ShaderDiskCacheDecompiled entry;
296 entry.code = std::string(reinterpret_cast<const char*>(code.data()), code_size); 297 entry.code = std::move(code);
297 298
298 u32 const_buffers_count{}; 299 u32 const_buffers_count{};
299 if (!LoadObjectFromPrecompiled(const_buffers_count)) { 300 if (!LoadObjectFromPrecompiled(const_buffers_count)) {
@@ -303,12 +304,12 @@ std::optional<ShaderDiskCacheDecompiled> ShaderDiskCacheOpenGL::LoadDecompiledEn
303 for (u32 i = 0; i < const_buffers_count; ++i) { 304 for (u32 i = 0; i < const_buffers_count; ++i) {
304 u32 max_offset{}; 305 u32 max_offset{};
305 u32 index{}; 306 u32 index{};
306 u8 is_indirect{}; 307 bool is_indirect{};
307 if (!LoadObjectFromPrecompiled(max_offset) || !LoadObjectFromPrecompiled(index) || 308 if (!LoadObjectFromPrecompiled(max_offset) || !LoadObjectFromPrecompiled(index) ||
308 !LoadObjectFromPrecompiled(is_indirect)) { 309 !LoadObjectFromPrecompiled(is_indirect)) {
309 return {}; 310 return {};
310 } 311 }
311 entry.entries.const_buffers.emplace_back(max_offset, is_indirect != 0, index); 312 entry.entries.const_buffers.emplace_back(max_offset, is_indirect, index);
312 } 313 }
313 314
314 u32 samplers_count{}; 315 u32 samplers_count{};
@@ -320,18 +321,17 @@ std::optional<ShaderDiskCacheDecompiled> ShaderDiskCacheOpenGL::LoadDecompiledEn
320 u64 offset{}; 321 u64 offset{};
321 u64 index{}; 322 u64 index{};
322 u32 type{}; 323 u32 type{};
323 u8 is_array{}; 324 bool is_array{};
324 u8 is_shadow{}; 325 bool is_shadow{};
325 u8 is_bindless{}; 326 bool is_bindless{};
326 if (!LoadObjectFromPrecompiled(offset) || !LoadObjectFromPrecompiled(index) || 327 if (!LoadObjectFromPrecompiled(offset) || !LoadObjectFromPrecompiled(index) ||
327 !LoadObjectFromPrecompiled(type) || !LoadObjectFromPrecompiled(is_array) || 328 !LoadObjectFromPrecompiled(type) || !LoadObjectFromPrecompiled(is_array) ||
328 !LoadObjectFromPrecompiled(is_shadow) || !LoadObjectFromPrecompiled(is_bindless)) { 329 !LoadObjectFromPrecompiled(is_shadow) || !LoadObjectFromPrecompiled(is_bindless)) {
329 return {}; 330 return {};
330 } 331 }
331 entry.entries.samplers.emplace_back(static_cast<std::size_t>(offset), 332 entry.entries.samplers.emplace_back(
332 static_cast<std::size_t>(index), 333 static_cast<std::size_t>(offset), static_cast<std::size_t>(index),
333 static_cast<Tegra::Shader::TextureType>(type), 334 static_cast<Tegra::Shader::TextureType>(type), is_array, is_shadow, is_bindless);
334 is_array != 0, is_shadow != 0, is_bindless != 0);
335 } 335 }
336 336
337 u32 global_memory_count{}; 337 u32 global_memory_count{};
@@ -342,21 +342,20 @@ std::optional<ShaderDiskCacheDecompiled> ShaderDiskCacheOpenGL::LoadDecompiledEn
342 for (u32 i = 0; i < global_memory_count; ++i) { 342 for (u32 i = 0; i < global_memory_count; ++i) {
343 u32 cbuf_index{}; 343 u32 cbuf_index{};
344 u32 cbuf_offset{}; 344 u32 cbuf_offset{};
345 u8 is_read{}; 345 bool is_read{};
346 u8 is_written{}; 346 bool is_written{};
347 if (!LoadObjectFromPrecompiled(cbuf_index) || !LoadObjectFromPrecompiled(cbuf_offset) || 347 if (!LoadObjectFromPrecompiled(cbuf_index) || !LoadObjectFromPrecompiled(cbuf_offset) ||
348 !LoadObjectFromPrecompiled(is_read) || !LoadObjectFromPrecompiled(is_written)) { 348 !LoadObjectFromPrecompiled(is_read) || !LoadObjectFromPrecompiled(is_written)) {
349 return {}; 349 return {};
350 } 350 }
351 entry.entries.global_memory_entries.emplace_back(cbuf_index, cbuf_offset, is_read != 0, 351 entry.entries.global_memory_entries.emplace_back(cbuf_index, cbuf_offset, is_read,
352 is_written != 0); 352 is_written);
353 } 353 }
354 354
355 for (auto& clip_distance : entry.entries.clip_distances) { 355 for (auto& clip_distance : entry.entries.clip_distances) {
356 u8 clip_distance_raw{}; 356 if (!LoadObjectFromPrecompiled(clip_distance)) {
357 if (!LoadObjectFromPrecompiled(clip_distance_raw))
358 return {}; 357 return {};
359 clip_distance = clip_distance_raw != 0; 358 }
360 } 359 }
361 360
362 u64 shader_length{}; 361 u64 shader_length{};
@@ -384,7 +383,7 @@ bool ShaderDiskCacheOpenGL::SaveDecompiledFile(u64 unique_identifier, const std:
384 for (const auto& cbuf : entries.const_buffers) { 383 for (const auto& cbuf : entries.const_buffers) {
385 if (!SaveObjectToPrecompiled(static_cast<u32>(cbuf.GetMaxOffset())) || 384 if (!SaveObjectToPrecompiled(static_cast<u32>(cbuf.GetMaxOffset())) ||
386 !SaveObjectToPrecompiled(static_cast<u32>(cbuf.GetIndex())) || 385 !SaveObjectToPrecompiled(static_cast<u32>(cbuf.GetIndex())) ||
387 !SaveObjectToPrecompiled(static_cast<u8>(cbuf.IsIndirect() ? 1 : 0))) { 386 !SaveObjectToPrecompiled(cbuf.IsIndirect())) {
388 return false; 387 return false;
389 } 388 }
390 } 389 }
@@ -396,9 +395,9 @@ bool ShaderDiskCacheOpenGL::SaveDecompiledFile(u64 unique_identifier, const std:
396 if (!SaveObjectToPrecompiled(static_cast<u64>(sampler.GetOffset())) || 395 if (!SaveObjectToPrecompiled(static_cast<u64>(sampler.GetOffset())) ||
397 !SaveObjectToPrecompiled(static_cast<u64>(sampler.GetIndex())) || 396 !SaveObjectToPrecompiled(static_cast<u64>(sampler.GetIndex())) ||
398 !SaveObjectToPrecompiled(static_cast<u32>(sampler.GetType())) || 397 !SaveObjectToPrecompiled(static_cast<u32>(sampler.GetType())) ||
399 !SaveObjectToPrecompiled(static_cast<u8>(sampler.IsArray() ? 1 : 0)) || 398 !SaveObjectToPrecompiled(sampler.IsArray()) ||
400 !SaveObjectToPrecompiled(static_cast<u8>(sampler.IsShadow() ? 1 : 0)) || 399 !SaveObjectToPrecompiled(sampler.IsShadow()) ||
401 !SaveObjectToPrecompiled(static_cast<u8>(sampler.IsBindless() ? 1 : 0))) { 400 !SaveObjectToPrecompiled(sampler.IsBindless())) {
402 return false; 401 return false;
403 } 402 }
404 } 403 }
@@ -409,14 +408,13 @@ bool ShaderDiskCacheOpenGL::SaveDecompiledFile(u64 unique_identifier, const std:
409 for (const auto& gmem : entries.global_memory_entries) { 408 for (const auto& gmem : entries.global_memory_entries) {
410 if (!SaveObjectToPrecompiled(static_cast<u32>(gmem.GetCbufIndex())) || 409 if (!SaveObjectToPrecompiled(static_cast<u32>(gmem.GetCbufIndex())) ||
411 !SaveObjectToPrecompiled(static_cast<u32>(gmem.GetCbufOffset())) || 410 !SaveObjectToPrecompiled(static_cast<u32>(gmem.GetCbufOffset())) ||
412 !SaveObjectToPrecompiled(static_cast<u8>(gmem.IsRead() ? 1 : 0)) || 411 !SaveObjectToPrecompiled(gmem.IsRead()) || !SaveObjectToPrecompiled(gmem.IsWritten())) {
413 !SaveObjectToPrecompiled(static_cast<u8>(gmem.IsWritten() ? 1 : 0))) {
414 return false; 412 return false;
415 } 413 }
416 } 414 }
417 415
418 for (const bool clip_distance : entries.clip_distances) { 416 for (const bool clip_distance : entries.clip_distances) {
419 if (!SaveObjectToPrecompiled(static_cast<u8>(clip_distance ? 1 : 0))) { 417 if (!SaveObjectToPrecompiled(clip_distance)) {
420 return false; 418 return false;
421 } 419 }
422 } 420 }
diff --git a/src/video_core/renderer_opengl/gl_shader_disk_cache.h b/src/video_core/renderer_opengl/gl_shader_disk_cache.h
index 0142b2e3b..2da0a4a23 100644
--- a/src/video_core/renderer_opengl/gl_shader_disk_cache.h
+++ b/src/video_core/renderer_opengl/gl_shader_disk_cache.h
@@ -70,14 +70,14 @@ namespace std {
70 70
71template <> 71template <>
72struct hash<OpenGL::BaseBindings> { 72struct hash<OpenGL::BaseBindings> {
73 std::size_t operator()(const OpenGL::BaseBindings& bindings) const { 73 std::size_t operator()(const OpenGL::BaseBindings& bindings) const noexcept {
74 return bindings.cbuf | bindings.gmem << 8 | bindings.sampler << 16; 74 return bindings.cbuf | bindings.gmem << 8 | bindings.sampler << 16;
75 } 75 }
76}; 76};
77 77
78template <> 78template <>
79struct hash<OpenGL::ShaderDiskCacheUsage> { 79struct hash<OpenGL::ShaderDiskCacheUsage> {
80 std::size_t operator()(const OpenGL::ShaderDiskCacheUsage& usage) const { 80 std::size_t operator()(const OpenGL::ShaderDiskCacheUsage& usage) const noexcept {
81 return static_cast<std::size_t>(usage.unique_identifier) ^ 81 return static_cast<std::size_t>(usage.unique_identifier) ^
82 std::hash<OpenGL::BaseBindings>()(usage.bindings) ^ usage.primitive << 16; 82 std::hash<OpenGL::BaseBindings>()(usage.bindings) ^ usage.primitive << 16;
83 } 83 }
@@ -162,6 +162,7 @@ struct ShaderDiskCacheDump {
162class ShaderDiskCacheOpenGL { 162class ShaderDiskCacheOpenGL {
163public: 163public:
164 explicit ShaderDiskCacheOpenGL(Core::System& system); 164 explicit ShaderDiskCacheOpenGL(Core::System& system);
165 ~ShaderDiskCacheOpenGL();
165 166
166 /// Loads transferable cache. If file has a old version or on failure, it deletes the file. 167 /// Loads transferable cache. If file has a old version or on failure, it deletes the file.
167 std::optional<std::pair<std::vector<ShaderDiskCacheRaw>, std::vector<ShaderDiskCacheUsage>>> 168 std::optional<std::pair<std::vector<ShaderDiskCacheRaw>, std::vector<ShaderDiskCacheUsage>>>
@@ -259,20 +260,35 @@ private:
259 return SaveArrayToPrecompiled(&object, 1); 260 return SaveArrayToPrecompiled(&object, 1);
260 } 261 }
261 262
263 bool SaveObjectToPrecompiled(bool object) {
264 const auto value = static_cast<u8>(object);
265 return SaveArrayToPrecompiled(&value, 1);
266 }
267
262 template <typename T> 268 template <typename T>
263 bool LoadObjectFromPrecompiled(T& object) { 269 bool LoadObjectFromPrecompiled(T& object) {
264 return LoadArrayFromPrecompiled(&object, 1); 270 return LoadArrayFromPrecompiled(&object, 1);
265 } 271 }
266 272
267 // Copre system 273 bool LoadObjectFromPrecompiled(bool& object) {
274 u8 value;
275 const bool read_ok = LoadArrayFromPrecompiled(&value, 1);
276 if (!read_ok) {
277 return false;
278 }
279
280 object = value != 0;
281 return true;
282 }
283
284 // Core system
268 Core::System& system; 285 Core::System& system;
269 // Stored transferable shaders 286 // Stored transferable shaders
270 std::map<u64, std::unordered_set<ShaderDiskCacheUsage>> transferable; 287 std::map<u64, std::unordered_set<ShaderDiskCacheUsage>> transferable;
271 // Stores whole precompiled cache which will be read from or saved to the precompiled chache 288 // Stores whole precompiled cache which will be read from/saved to the precompiled cache file
272 // file
273 FileSys::VectorVfsFile precompiled_cache_virtual_file; 289 FileSys::VectorVfsFile precompiled_cache_virtual_file;
274 // Stores the current offset of the precompiled cache file for IO purposes 290 // Stores the current offset of the precompiled cache file for IO purposes
275 std::size_t precompiled_cache_virtual_file_offset; 291 std::size_t precompiled_cache_virtual_file_offset = 0;
276 292
277 // The cache has been loaded at boot 293 // The cache has been loaded at boot
278 bool tried_to_load{}; 294 bool tried_to_load{};