gl_shader_disk_cache: Use unordered containers

master
ReinUsesLisp 2019-02-02 21:14:36 +07:00
parent e147ed4fc0
commit e6a2245304
4 changed files with 64 additions and 56 deletions

@ -431,11 +431,11 @@ CachedProgram ShaderCacheOpenGL::GeneratePrecompiledProgram(
return shader; return shader;
} }
std::map<u64, UnspecializedShader> ShaderCacheOpenGL::GenerateUnspecializedShaders( std::unordered_map<u64, UnspecializedShader> ShaderCacheOpenGL::GenerateUnspecializedShaders(
const std::atomic_bool& stop_loading, const VideoCore::DiskResourceLoadCallback& callback, const std::atomic_bool& stop_loading, const VideoCore::DiskResourceLoadCallback& callback,
const std::vector<ShaderDiskCacheRaw>& raws, const std::vector<ShaderDiskCacheRaw>& raws,
const std::map<u64, ShaderDiskCacheDecompiled>& decompiled) { const std::unordered_map<u64, ShaderDiskCacheDecompiled>& decompiled) {
std::map<u64, UnspecializedShader> unspecialized; std::unordered_map<u64, UnspecializedShader> unspecialized;
if (callback) if (callback)
callback(VideoCore::LoadCallbackStage::Decompile, 0, raws.size()); callback(VideoCore::LoadCallbackStage::Decompile, 0, raws.size());

@ -5,10 +5,10 @@
#pragma once #pragma once
#include <array> #include <array>
#include <map>
#include <memory> #include <memory>
#include <set> #include <set>
#include <tuple> #include <tuple>
#include <unordered_map>
#include <glad/glad.h> #include <glad/glad.h>
@ -34,8 +34,8 @@ struct UnspecializedShader;
using Shader = std::shared_ptr<CachedShader>; using Shader = std::shared_ptr<CachedShader>;
using CachedProgram = std::shared_ptr<OGLProgram>; using CachedProgram = std::shared_ptr<OGLProgram>;
using Maxwell = Tegra::Engines::Maxwell3D::Regs; using Maxwell = Tegra::Engines::Maxwell3D::Regs;
using PrecompiledPrograms = std::map<ShaderDiskCacheUsage, CachedProgram>; using PrecompiledPrograms = std::unordered_map<ShaderDiskCacheUsage, CachedProgram>;
using PrecompiledShaders = std::map<u64, GLShader::ProgramResult>; using PrecompiledShaders = std::unordered_map<u64, GLShader::ProgramResult>;
class CachedShader final : public RasterizerCacheObject { class CachedShader final : public RasterizerCacheObject {
public: public:
@ -102,12 +102,12 @@ private:
std::string code; std::string code;
std::map<BaseBindings, CachedProgram> programs; std::unordered_map<BaseBindings, CachedProgram> programs;
std::map<BaseBindings, GeometryPrograms> geometry_programs; std::unordered_map<BaseBindings, GeometryPrograms> geometry_programs;
std::map<u32, GLuint> cbuf_resource_cache; std::unordered_map<u32, GLuint> cbuf_resource_cache;
std::map<u32, GLuint> gmem_resource_cache; std::unordered_map<u32, GLuint> gmem_resource_cache;
std::map<u32, GLint> uniform_cache; std::unordered_map<u32, GLint> uniform_cache;
}; };
class ShaderCacheOpenGL final : public RasterizerCache<Shader> { class ShaderCacheOpenGL final : public RasterizerCache<Shader> {
@ -122,10 +122,10 @@ public:
Shader GetStageProgram(Maxwell::ShaderProgram program); Shader GetStageProgram(Maxwell::ShaderProgram program);
private: private:
std::map<u64, UnspecializedShader> GenerateUnspecializedShaders( std::unordered_map<u64, UnspecializedShader> GenerateUnspecializedShaders(
const std::atomic_bool& stop_loading, const VideoCore::DiskResourceLoadCallback& callback, const std::atomic_bool& stop_loading, const VideoCore::DiskResourceLoadCallback& callback,
const std::vector<ShaderDiskCacheRaw>& raws, const std::vector<ShaderDiskCacheRaw>& raws,
const std::map<u64, ShaderDiskCacheDecompiled>& decompiled); const std::unordered_map<u64, ShaderDiskCacheDecompiled>& decompiled);
CachedProgram GeneratePrecompiledProgram(const ShaderDiskCacheDump& dump, CachedProgram GeneratePrecompiledProgram(const ShaderDiskCacheDump& dump,
const std::set<GLenum>& supported_formats); const std::set<GLenum>& supported_formats);

@ -211,8 +211,8 @@ ShaderDiskCacheOpenGL::LoadTransferable() {
return {{raws, usages}}; return {{raws, usages}};
} }
std::pair<std::map<u64, ShaderDiskCacheDecompiled>, std::pair<std::unordered_map<u64, ShaderDiskCacheDecompiled>,
std::map<ShaderDiskCacheUsage, ShaderDiskCacheDump>> std::unordered_map<ShaderDiskCacheUsage, ShaderDiskCacheDump>>
ShaderDiskCacheOpenGL::LoadPrecompiled() { ShaderDiskCacheOpenGL::LoadPrecompiled() {
if (!IsUsable()) if (!IsUsable())
return {}; return {};
@ -236,8 +236,8 @@ ShaderDiskCacheOpenGL::LoadPrecompiled() {
return *result; return *result;
} }
std::optional<std::pair<std::map<u64, ShaderDiskCacheDecompiled>, std::optional<std::pair<std::unordered_map<u64, ShaderDiskCacheDecompiled>,
std::map<ShaderDiskCacheUsage, ShaderDiskCacheDump>>> std::unordered_map<ShaderDiskCacheUsage, ShaderDiskCacheDump>>>
ShaderDiskCacheOpenGL::LoadPrecompiledFile(FileUtil::IOFile& file) { ShaderDiskCacheOpenGL::LoadPrecompiledFile(FileUtil::IOFile& file) {
ShaderCacheVersionHash file_hash{}; ShaderCacheVersionHash file_hash{};
if (file.ReadArray(file_hash.data(), file_hash.size()) != file_hash.size()) { if (file.ReadArray(file_hash.data(), file_hash.size()) != file_hash.size()) {
@ -248,8 +248,8 @@ ShaderDiskCacheOpenGL::LoadPrecompiledFile(FileUtil::IOFile& file) {
return {}; return {};
} }
std::map<u64, ShaderDiskCacheDecompiled> decompiled; std::unordered_map<u64, ShaderDiskCacheDecompiled> decompiled;
std::map<ShaderDiskCacheUsage, ShaderDiskCacheDump> dumps; std::unordered_map<ShaderDiskCacheUsage, ShaderDiskCacheDump> dumps;
while (file.Tell() < file.GetSize()) { while (file.Tell() < file.GetSize()) {
PrecompiledEntryKind kind{}; PrecompiledEntryKind kind{};
if (file.ReadBytes(&kind, sizeof(u32)) != sizeof(u32)) { if (file.ReadBytes(&kind, sizeof(u32)) != sizeof(u32)) {

@ -5,9 +5,10 @@
#pragma once #pragma once
#include <optional> #include <optional>
#include <set>
#include <string> #include <string>
#include <tuple> #include <tuple>
#include <unordered_map>
#include <unordered_set>
#include <utility> #include <utility>
#include <vector> #include <vector>
@ -37,23 +38,54 @@ struct BaseBindings {
u32 gmem{}; u32 gmem{};
u32 sampler{}; u32 sampler{};
bool operator<(const BaseBindings& rhs) const {
return Tie() < rhs.Tie();
}
bool operator==(const BaseBindings& rhs) const { 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 { bool operator!=(const BaseBindings& rhs) const {
return !operator==(rhs); return !operator==(rhs);
} }
};
std::tuple<u32, u32, u32> Tie() const { /// Describes how a shader is used
return std::tie(cbuf, gmem, sampler); 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<OpenGL::BaseBindings> {
std::size_t operator()(const OpenGL::BaseBindings& bindings) const {
return bindings.cbuf | bindings.gmem << 8 | bindings.sampler << 16;
}
};
template <>
struct hash<OpenGL::ShaderDiskCacheUsage> {
std::size_t operator()(const OpenGL::ShaderDiskCacheUsage& usage) const {
return static_cast<std::size_t>(usage.unique_identifier) ^
std::hash<OpenGL::BaseBindings>()(usage.bindings) ^ usage.primitive << 16;
}
};
} // namespace std
namespace OpenGL {
/// Describes a shader how it's used by the guest GPU /// Describes a shader how it's used by the guest GPU
class ShaderDiskCacheRaw { class ShaderDiskCacheRaw {
public: public:
@ -114,30 +146,6 @@ private:
ProgramCode program_code_b; 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<u64, BaseBindings, GLenum> Tie() const {
return std::tie(unique_identifier, bindings, primitive);
}
};
/// Contains decompiled data from a shader /// Contains decompiled data from a shader
struct ShaderDiskCacheDecompiled { struct ShaderDiskCacheDecompiled {
std::string code; std::string code;
@ -159,8 +167,8 @@ public:
LoadTransferable(); LoadTransferable();
/// Loads current game's precompiled cache. Invalidates on failure. /// Loads current game's precompiled cache. Invalidates on failure.
std::pair<std::map<u64, ShaderDiskCacheDecompiled>, std::pair<std::unordered_map<u64, ShaderDiskCacheDecompiled>,
std::map<ShaderDiskCacheUsage, ShaderDiskCacheDump>> std::unordered_map<ShaderDiskCacheUsage, ShaderDiskCacheDump>>
LoadPrecompiled(); LoadPrecompiled();
/// Removes the transferable (and precompiled) cache file. /// Removes the transferable (and precompiled) cache file.
@ -184,8 +192,8 @@ public:
private: private:
/// Loads the transferable cache. Returns empty on failure. /// Loads the transferable cache. Returns empty on failure.
std::optional<std::pair<std::map<u64, ShaderDiskCacheDecompiled>, std::optional<std::pair<std::unordered_map<u64, ShaderDiskCacheDecompiled>,
std::map<ShaderDiskCacheUsage, ShaderDiskCacheDump>>> std::unordered_map<ShaderDiskCacheUsage, ShaderDiskCacheDump>>>
LoadPrecompiledFile(FileUtil::IOFile& file); LoadPrecompiledFile(FileUtil::IOFile& file);
/// Loads a decompiled cache entry from the passed file. Returns empty on failure. /// Loads a decompiled cache entry from the passed file. Returns empty on failure.
@ -229,7 +237,7 @@ private:
// Copre system // Copre system
Core::System& system; Core::System& system;
// Stored transferable shaders // Stored transferable shaders
std::map<u64, std::set<ShaderDiskCacheUsage>> transferable; std::map<u64, std::unordered_set<ShaderDiskCacheUsage>> transferable;
// The cache has been loaded at boot // The cache has been loaded at boot
bool tried_to_load{}; bool tried_to_load{};
}; };