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 | |
34 | namespace vk |
35 | { |
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 | |
60 | 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 | |
80 | const VkShaderStageFlagBits& getPipelineStage() const { return pipelineStage; } |
81 | const std::string& getEntryPointName() const { return entryPointName; } |
82 | const std::vector<uint32_t>& getInsns() const { return insns; } |
83 | const vk::RenderPass *getRenderPass() const { return renderPass; } |
84 | uint32_t getSubpassIndex() const { return subpassIndex; } |
85 | 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 | |
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 | { |
102 | ComputeProgramKey(const sw::SpirvShader* shader, const vk::PipelineLayout* layout) : |
103 | shader(shader), layout(layout) |
104 | {} |
105 | |
106 | bool operator<(const ComputeProgramKey &other) const |
107 | { |
108 | return std::tie(shader, layout) < std::tie(other.shader, other.layout); |
109 | } |
110 | |
111 | const sw::SpirvShader* getShader() const { return shader; } |
112 | const vk::PipelineLayout* getLayout() const { return layout; } |
113 | |
114 | private: |
115 | const sw::SpirvShader* shader; |
116 | const vk::PipelineLayout* layout; |
117 | }; |
118 | |
119 | std::mutex& getProgramMutex() { return computeProgramsMutex; } |
120 | const std::shared_ptr<sw::ComputeProgram>* operator[](const PipelineCache::ComputeProgramKey& key) const; |
121 | void insert(const PipelineCache::ComputeProgramKey& key, const std::shared_ptr<sw::ComputeProgram> &computeProgram); |
122 | |
123 | private: |
124 | struct |
125 | { |
126 | uint32_t ; |
127 | uint32_t ; |
128 | uint32_t ; |
129 | uint32_t ; |
130 | uint8_t [VK_UUID_SIZE]; |
131 | }; |
132 | |
133 | size_t dataSize = 0; |
134 | uint8_t* data = nullptr; |
135 | |
136 | std::mutex spirvShadersMutex; |
137 | std::map<SpirvShaderKey, std::shared_ptr<sw::SpirvShader>> spirvShaders; |
138 | |
139 | std::mutex computeProgramsMutex; |
140 | std::map<ComputeProgramKey, std::shared_ptr<sw::ComputeProgram>> computePrograms; |
141 | }; |
142 | |
143 | static inline PipelineCache* Cast(VkPipelineCache object) |
144 | { |
145 | return PipelineCache::Cast(object); |
146 | } |
147 | |
148 | } // namespace vk |
149 | |
150 | #endif // VK_PIPELINE_CACHE_HPP_ |
151 | |