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
28namespace sw
29{
30 class ComputeProgram;
31 class SpirvShader;
32}
33
34namespace vk
35{
36
37class PipelineLayout;
38class RenderPass;
39
40class PipelineCache : public Object<PipelineCache, VkPipelineCache>
41{
42public:
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
123private:
124 struct CacheHeader
125 {
126 uint32_t headerLength;
127 uint32_t headerVersion;
128 uint32_t vendorID;
129 uint32_t deviceID;
130 uint8_t pipelineCacheUUID[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
143static inline PipelineCache* Cast(VkPipelineCache object)
144{
145 return PipelineCache::Cast(object);
146}
147
148} // namespace vk
149
150#endif // VK_PIPELINE_CACHE_HPP_
151