Files
XCEngine/engine/include/XCEngine/Resources/Shader/ShaderCompilationCache.h

92 lines
2.9 KiB
C++

#pragma once
#include <XCEngine/Core/Asset/AssetGUID.h>
#include <XCEngine/Core/Containers/Array.h>
#include <XCEngine/Core/Containers/String.h>
#include <XCEngine/Core/Types.h>
#include <XCEngine/Resources/Shader/Shader.h>
#include <unordered_map>
namespace XCEngine {
namespace Resources {
constexpr Core::uint32 kShaderCompilationCacheSchemaVersion = 1;
enum class ShaderBytecodeFormat : Core::uint32 {
Unknown = 0,
DXIL,
DXBC,
SPIRV,
GLSLSource,
OpenGLProgramBinary
};
struct ShaderCompileKey {
Containers::String shaderPath;
Containers::String sourceHash;
Containers::String dependencyHash;
Containers::String passName;
Containers::String entryPoint;
Containers::String profile;
Containers::String compilerName;
Containers::String compilerVersion;
Containers::String optionsSignature;
ShaderType stage = ShaderType::Fragment;
ShaderLanguage sourceLanguage = ShaderLanguage::HLSL;
ShaderBackend backend = ShaderBackend::Generic;
Containers::Array<Containers::String> keywords;
void Normalize();
Containers::String BuildSignature() const;
Containers::String BuildCacheKey() const;
};
struct ShaderCacheEntry {
ShaderCompileKey key;
ShaderBytecodeFormat format = ShaderBytecodeFormat::Unknown;
Containers::Array<Core::uint8> payload;
};
class ShaderCompilationCache {
public:
void Initialize(const Containers::String& libraryRoot);
void Shutdown();
bool IsInitialized() const { return !m_libraryRoot.Empty(); }
const Containers::String& GetLibraryRoot() const { return m_libraryRoot; }
const Containers::String& GetDatabasePath() const { return m_databasePath; }
Core::uint32 GetRecordCount() const { return static_cast<Core::uint32>(m_records.size()); }
Containers::String BuildCacheKey(const ShaderCompileKey& key) const;
Containers::String BuildCacheRelativePath(const ShaderCompileKey& key) const;
Containers::String BuildCacheAbsolutePath(const ShaderCompileKey& key) const;
bool Store(const ShaderCacheEntry& entry,
Containers::String* outErrorMessage = nullptr);
bool TryLoad(const ShaderCompileKey& key,
ShaderCacheEntry& outEntry,
Containers::String* outErrorMessage = nullptr) const;
private:
struct ShaderCacheRecord {
ShaderBackend backend = ShaderBackend::Generic;
ShaderBytecodeFormat format = ShaderBytecodeFormat::Unknown;
Containers::String relativePath;
Core::uint64 payloadSize = 0;
};
void LoadDatabase();
void SaveDatabase() const;
static Containers::String BuildBackendDirectoryName(ShaderBackend backend);
static AssetGUID ComputeKeyGuid(const Containers::String& cacheKey);
Containers::String m_libraryRoot;
Containers::String m_databasePath;
std::unordered_map<std::string, ShaderCacheRecord> m_records;
};
} // namespace Resources
} // namespace XCEngine