• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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