1 // Copyright 2018 The SwiftShader Authors. All Rights Reserved.
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14
15 #ifndef VK_PIPELINE_CACHE_HPP_
16 #define VK_PIPELINE_CACHE_HPP_
17
18 #include "VkObject.hpp"
19
20 #include <cstring>
21 #include <functional>
22 #include <map>
23 #include <memory>
24 #include <mutex>
25 #include <string>
26 #include <vector>
27
28 namespace sw {
29
30 class ComputeProgram;
31 class SpirvShader;
32
33 } // namespace sw
34
35 namespace vk {
36
37 class PipelineLayout;
38 class RenderPass;
39
40 class PipelineCache : public Object<PipelineCache, VkPipelineCache>
41 {
42 public:
43 PipelineCache(const VkPipelineCacheCreateInfo *pCreateInfo, void *mem);
44 virtual ~PipelineCache();
45 void destroy(const VkAllocationCallbacks *pAllocator);
46
47 static size_t ComputeRequiredAllocationSize(const VkPipelineCacheCreateInfo *pCreateInfo);
48
49 VkResult getData(size_t *pDataSize, void *pData);
50 VkResult merge(uint32_t srcCacheCount, const VkPipelineCache *pSrcCaches);
51
52 struct SpirvShaderKey
53 {
54 struct SpecializationInfo
55 {
56 SpecializationInfo(const VkSpecializationInfo *specializationInfo);
57
58 bool operator<(const SpecializationInfo &specializationInfo) const;
59
getvk::PipelineCache::SpirvShaderKey::SpecializationInfo60 const VkSpecializationInfo *get() const { return info.get(); }
61
62 private:
63 struct Deleter
64 {
65 void operator()(VkSpecializationInfo *) const;
66 };
67
68 std::shared_ptr<VkSpecializationInfo> info;
69 };
70
71 SpirvShaderKey(const VkShaderStageFlagBits pipelineStage,
72 const std::string &entryPointName,
73 const std::vector<uint32_t> &insns,
74 const vk::RenderPass *renderPass,
75 const uint32_t subpassIndex,
76 const VkSpecializationInfo *specializationInfo);
77
78 bool operator<(const SpirvShaderKey &other) const;
79
getPipelineStagevk::PipelineCache::SpirvShaderKey80 const VkShaderStageFlagBits &getPipelineStage() const { return pipelineStage; }
getEntryPointNamevk::PipelineCache::SpirvShaderKey81 const std::string &getEntryPointName() const { return entryPointName; }
getInsnsvk::PipelineCache::SpirvShaderKey82 const std::vector<uint32_t> &getInsns() const { return insns; }
getRenderPassvk::PipelineCache::SpirvShaderKey83 const vk::RenderPass *getRenderPass() const { return renderPass; }
getSubpassIndexvk::PipelineCache::SpirvShaderKey84 uint32_t getSubpassIndex() const { return subpassIndex; }
getSpecializationInfovk::PipelineCache::SpirvShaderKey85 const VkSpecializationInfo *getSpecializationInfo() const { return specializationInfo.get(); }
86
87 private:
88 const VkShaderStageFlagBits pipelineStage;
89 const std::string entryPointName;
90 const std::vector<uint32_t> insns;
91 const vk::RenderPass *renderPass;
92 const uint32_t subpassIndex;
93 const SpecializationInfo specializationInfo;
94 };
95
getShaderMutex()96 std::mutex &getShaderMutex() { return spirvShadersMutex; }
97 const std::shared_ptr<sw::SpirvShader> *operator[](const PipelineCache::SpirvShaderKey &key) const;
98 void insert(const PipelineCache::SpirvShaderKey &key, const std::shared_ptr<sw::SpirvShader> &shader);
99
100 struct ComputeProgramKey
101 {
ComputeProgramKeyvk::PipelineCache::ComputeProgramKey102 ComputeProgramKey(const sw::SpirvShader *shader, const vk::PipelineLayout *layout)
103 : shader(shader)
104 , layout(layout)
105 {}
106
operator <vk::PipelineCache::ComputeProgramKey107 bool operator<(const ComputeProgramKey &other) const
108 {
109 return std::tie(shader, layout) < std::tie(other.shader, other.layout);
110 }
111
getShadervk::PipelineCache::ComputeProgramKey112 const sw::SpirvShader *getShader() const { return shader; }
getLayoutvk::PipelineCache::ComputeProgramKey113 const vk::PipelineLayout *getLayout() const { return layout; }
114
115 private:
116 const sw::SpirvShader *shader;
117 const vk::PipelineLayout *layout;
118 };
119
getProgramMutex()120 std::mutex &getProgramMutex() { return computeProgramsMutex; }
121 const std::shared_ptr<sw::ComputeProgram> *operator[](const PipelineCache::ComputeProgramKey &key) const;
122 void insert(const PipelineCache::ComputeProgramKey &key, const std::shared_ptr<sw::ComputeProgram> &computeProgram);
123
124 private:
125 struct CacheHeader
126 {
127 uint32_t headerLength;
128 uint32_t headerVersion;
129 uint32_t vendorID;
130 uint32_t deviceID;
131 uint8_t pipelineCacheUUID[VK_UUID_SIZE];
132 };
133
134 size_t dataSize = 0;
135 uint8_t *data = nullptr;
136
137 std::mutex spirvShadersMutex;
138 std::map<SpirvShaderKey, std::shared_ptr<sw::SpirvShader>> spirvShaders;
139
140 std::mutex computeProgramsMutex;
141 std::map<ComputeProgramKey, std::shared_ptr<sw::ComputeProgram>> computePrograms;
142 };
143
Cast(VkPipelineCache object)144 static inline PipelineCache *Cast(VkPipelineCache object)
145 {
146 return PipelineCache::Cast(object);
147 }
148
149 } // namespace vk
150
151 #endif // VK_PIPELINE_CACHE_HPP_
152