gpu_shader_cache.h (2222B)
1 // SPDX-FileCopyrightText: 2023 Connor McLaughlin <stenzek@gmail.com> 2 // SPDX-License-Identifier: (GPL-3.0 OR CC-BY-NC-ND-4.0) 3 4 #pragma once 5 6 #include "common/hash_combine.h" 7 #include "common/heap_array.h" 8 #include "common/types.h" 9 10 #include <optional> 11 #include <string> 12 #include <string_view> 13 #include <unordered_map> 14 #include <vector> 15 16 enum class GPUShaderStage : u8; 17 enum class GPUShaderLanguage : u8; 18 19 class GPUShaderCache 20 { 21 public: 22 using ShaderBinary = DynamicHeapArray<u8>; 23 24 struct alignas(8) CacheIndexKey 25 { 26 u8 shader_type; 27 u8 shader_language; 28 u8 unused[2]; 29 u32 source_length; 30 u64 source_hash_low; 31 u64 source_hash_high; 32 u64 entry_point_low; 33 u64 entry_point_high; 34 35 bool operator==(const CacheIndexKey& key) const; 36 bool operator!=(const CacheIndexKey& key) const; 37 }; 38 static_assert(sizeof(CacheIndexKey) == 40, "Cache key has no padding"); 39 40 struct CacheIndexEntryHash 41 { 42 std::size_t operator()(const CacheIndexKey& e) const noexcept; 43 }; 44 45 GPUShaderCache(); 46 ~GPUShaderCache(); 47 48 ALWAYS_INLINE const std::string& GetBaseFilename() const { return m_base_filename; } 49 ALWAYS_INLINE u32 GetVersion() const { return m_version; } 50 51 bool IsOpen() const { return (m_index_file != nullptr); } 52 53 bool Open(std::string_view base_filename, u32 version); 54 bool Create(); 55 void Close(); 56 57 static CacheIndexKey GetCacheKey(GPUShaderStage stage, GPUShaderLanguage language, std::string_view shader_code, 58 std::string_view entry_point); 59 60 std::optional<ShaderBinary> Lookup(const CacheIndexKey& key); 61 bool Insert(const CacheIndexKey& key, const void* data, u32 data_size); 62 void Clear(); 63 64 private: 65 struct CacheIndexData 66 { 67 u32 file_offset; 68 u32 compressed_size; 69 u32 uncompressed_size; 70 }; 71 72 using CacheIndex = std::unordered_map<CacheIndexKey, CacheIndexData, CacheIndexEntryHash>; 73 74 bool CreateNew(const std::string& index_filename, const std::string& blob_filename); 75 bool ReadExisting(const std::string& index_filename, const std::string& blob_filename); 76 77 CacheIndex m_index; 78 79 std::string m_base_filename; 80 u32 m_version = 0; 81 82 std::FILE* m_index_file = nullptr; 83 std::FILE* m_blob_file = nullptr; 84 };