diff --git a/src/video_core/renderer_opengl/gl_shader_cache.cpp b/src/video_core/renderer_opengl/gl_shader_cache.cpp index bbcd158676..4883e4f625 100644 --- a/src/video_core/renderer_opengl/gl_shader_cache.cpp +++ b/src/video_core/renderer_opengl/gl_shader_cache.cpp @@ -431,11 +431,11 @@ CachedProgram ShaderCacheOpenGL::GeneratePrecompiledProgram( return shader; } -std::map ShaderCacheOpenGL::GenerateUnspecializedShaders( +std::unordered_map ShaderCacheOpenGL::GenerateUnspecializedShaders( const std::atomic_bool& stop_loading, const VideoCore::DiskResourceLoadCallback& callback, const std::vector& raws, - const std::map& decompiled) { - std::map unspecialized; + const std::unordered_map& decompiled) { + std::unordered_map unspecialized; if (callback) callback(VideoCore::LoadCallbackStage::Decompile, 0, raws.size()); diff --git a/src/video_core/renderer_opengl/gl_shader_cache.h b/src/video_core/renderer_opengl/gl_shader_cache.h index 9c6b19fc34..97eed192fd 100644 --- a/src/video_core/renderer_opengl/gl_shader_cache.h +++ b/src/video_core/renderer_opengl/gl_shader_cache.h @@ -5,10 +5,10 @@ #pragma once #include -#include #include #include #include +#include #include @@ -34,8 +34,8 @@ struct UnspecializedShader; using Shader = std::shared_ptr; using CachedProgram = std::shared_ptr; using Maxwell = Tegra::Engines::Maxwell3D::Regs; -using PrecompiledPrograms = std::map; -using PrecompiledShaders = std::map; +using PrecompiledPrograms = std::unordered_map; +using PrecompiledShaders = std::unordered_map; class CachedShader final : public RasterizerCacheObject { public: @@ -102,12 +102,12 @@ private: std::string code; - std::map programs; - std::map geometry_programs; + std::unordered_map programs; + std::unordered_map geometry_programs; - std::map cbuf_resource_cache; - std::map gmem_resource_cache; - std::map uniform_cache; + std::unordered_map cbuf_resource_cache; + std::unordered_map gmem_resource_cache; + std::unordered_map uniform_cache; }; class ShaderCacheOpenGL final : public RasterizerCache { @@ -122,10 +122,10 @@ public: Shader GetStageProgram(Maxwell::ShaderProgram program); private: - std::map GenerateUnspecializedShaders( + std::unordered_map GenerateUnspecializedShaders( const std::atomic_bool& stop_loading, const VideoCore::DiskResourceLoadCallback& callback, const std::vector& raws, - const std::map& decompiled); + const std::unordered_map& decompiled); CachedProgram GeneratePrecompiledProgram(const ShaderDiskCacheDump& dump, const std::set& supported_formats); 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 d88fff388a..554d0dfb9b 100644 --- a/src/video_core/renderer_opengl/gl_shader_disk_cache.cpp +++ b/src/video_core/renderer_opengl/gl_shader_disk_cache.cpp @@ -211,8 +211,8 @@ ShaderDiskCacheOpenGL::LoadTransferable() { return {{raws, usages}}; } -std::pair, - std::map> +std::pair, + std::unordered_map> ShaderDiskCacheOpenGL::LoadPrecompiled() { if (!IsUsable()) return {}; @@ -236,8 +236,8 @@ ShaderDiskCacheOpenGL::LoadPrecompiled() { return *result; } -std::optional, - std::map>> +std::optional, + std::unordered_map>> ShaderDiskCacheOpenGL::LoadPrecompiledFile(FileUtil::IOFile& file) { ShaderCacheVersionHash file_hash{}; if (file.ReadArray(file_hash.data(), file_hash.size()) != file_hash.size()) { @@ -248,8 +248,8 @@ ShaderDiskCacheOpenGL::LoadPrecompiledFile(FileUtil::IOFile& file) { return {}; } - std::map decompiled; - std::map dumps; + std::unordered_map decompiled; + std::unordered_map dumps; while (file.Tell() < file.GetSize()) { PrecompiledEntryKind kind{}; if (file.ReadBytes(&kind, sizeof(u32)) != sizeof(u32)) { 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 061c4f204c..6be0c0547b 100644 --- a/src/video_core/renderer_opengl/gl_shader_disk_cache.h +++ b/src/video_core/renderer_opengl/gl_shader_disk_cache.h @@ -5,9 +5,10 @@ #pragma once #include -#include #include #include +#include +#include #include #include @@ -37,23 +38,54 @@ struct BaseBindings { u32 gmem{}; u32 sampler{}; - bool operator<(const BaseBindings& rhs) const { - return Tie() < rhs.Tie(); - } - bool operator==(const BaseBindings& rhs) const { - return Tie() == rhs.Tie(); + return std::tie(cbuf, gmem, sampler) == std::tie(rhs.cbuf, rhs.gmem, rhs.sampler); } bool operator!=(const BaseBindings& rhs) const { return !operator==(rhs); } +}; - std::tuple Tie() const { - return std::tie(cbuf, gmem, sampler); +/// Describes how a shader is used +struct ShaderDiskCacheUsage { + u64 unique_identifier{}; + BaseBindings bindings; + GLenum primitive{}; + + bool operator==(const ShaderDiskCacheUsage& rhs) const { + return std::tie(unique_identifier, bindings, primitive) == + std::tie(rhs.unique_identifier, rhs.bindings, rhs.primitive); + } + + bool operator!=(const ShaderDiskCacheUsage& rhs) const { + return !operator==(rhs); } }; +} // namespace OpenGL + +namespace std { + +template <> +struct hash { + std::size_t operator()(const OpenGL::BaseBindings& bindings) const { + return bindings.cbuf | bindings.gmem << 8 | bindings.sampler << 16; + } +}; + +template <> +struct hash { + std::size_t operator()(const OpenGL::ShaderDiskCacheUsage& usage) const { + return static_cast(usage.unique_identifier) ^ + std::hash()(usage.bindings) ^ usage.primitive << 16; + } +}; + +} // namespace std + +namespace OpenGL { + /// Describes a shader how it's used by the guest GPU class ShaderDiskCacheRaw { public: @@ -114,30 +146,6 @@ private: ProgramCode program_code_b; }; -/// Describes how a shader is used -struct ShaderDiskCacheUsage { - bool operator<(const ShaderDiskCacheUsage& rhs) const { - return Tie() < rhs.Tie(); - } - - bool operator==(const ShaderDiskCacheUsage& rhs) const { - return Tie() == rhs.Tie(); - } - - bool operator!=(const ShaderDiskCacheUsage& rhs) const { - return !operator==(rhs); - } - - u64 unique_identifier{}; - BaseBindings bindings; - GLenum primitive{}; - -private: - std::tuple Tie() const { - return std::tie(unique_identifier, bindings, primitive); - } -}; - /// Contains decompiled data from a shader struct ShaderDiskCacheDecompiled { std::string code; @@ -159,8 +167,8 @@ public: LoadTransferable(); /// Loads current game's precompiled cache. Invalidates on failure. - std::pair, - std::map> + std::pair, + std::unordered_map> LoadPrecompiled(); /// Removes the transferable (and precompiled) cache file. @@ -184,8 +192,8 @@ public: private: /// Loads the transferable cache. Returns empty on failure. - std::optional, - std::map>> + std::optional, + std::unordered_map>> LoadPrecompiledFile(FileUtil::IOFile& file); /// Loads a decompiled cache entry from the passed file. Returns empty on failure. @@ -229,7 +237,7 @@ private: // Copre system Core::System& system; // Stored transferable shaders - std::map> transferable; + std::map> transferable; // The cache has been loaded at boot bool tried_to_load{}; };