blob: ffdfc2c5246852e31a30072a95c5f07cf05aa411 [file] [log] [blame]
Alexis Hetu18a84252018-11-19 11:30:43 -05001// 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"
Alexis Hetu52edb172019-06-26 10:17:18 -040019#include <cstring>
20#include <functional>
21#include <memory>
22#include <map>
23#include <mutex>
24#include <vector>
25
26namespace sw
27{
28 class ComputeProgram;
29 class SpirvShader;
30}
Alexis Hetu18a84252018-11-19 11:30:43 -050031
32namespace vk
33{
34
Alexis Hetu52edb172019-06-26 10:17:18 -040035class PipelineLayout;
36class RenderPass;
37
Alexis Hetu18a84252018-11-19 11:30:43 -050038class PipelineCache : public Object<PipelineCache, VkPipelineCache>
39{
40public:
Alexis Hetu1424ef62019-04-05 18:03:53 -040041 PipelineCache(const VkPipelineCacheCreateInfo* pCreateInfo, void* mem);
Alexis Hetu52edb172019-06-26 10:17:18 -040042 virtual ~PipelineCache();
Alexis Hetu1424ef62019-04-05 18:03:53 -040043 void destroy(const VkAllocationCallbacks* pAllocator);
Alexis Hetu18a84252018-11-19 11:30:43 -050044
Alexis Hetu1424ef62019-04-05 18:03:53 -040045 static size_t ComputeRequiredAllocationSize(const VkPipelineCacheCreateInfo* pCreateInfo);
46
47 VkResult getData(size_t* pDataSize, void* pData);
48 VkResult merge(uint32_t srcCacheCount, const VkPipelineCache* pSrcCaches);
Alexis Hetu18a84252018-11-19 11:30:43 -050049
Alexis Hetu52edb172019-06-26 10:17:18 -040050 struct SpirvShaderKey
51 {
52 struct SpecializationInfo
53 {
54 SpecializationInfo(const VkSpecializationInfo* specializationInfo);
55 ~SpecializationInfo();
56
57 bool operator<(const SpecializationInfo& specializationInfo) const;
58
59 VkSpecializationInfo* get() const { return info; }
60
61 private:
62 VkSpecializationInfo* info = nullptr;
63 };
64
65 SpirvShaderKey(const VkShaderStageFlagBits pipelineStage,
66 const std::string& entryPointName,
67 const std::vector<uint32_t>& insns,
68 const vk::RenderPass *renderPass,
69 const uint32_t subpassIndex,
70 const VkSpecializationInfo* specializationInfo);
71
72 bool operator<(const SpirvShaderKey &other) const;
73
74 const VkShaderStageFlagBits& getPipelineStage() const { return pipelineStage; }
75 const std::string& getEntryPointName() const { return entryPointName; }
76 const std::vector<uint32_t>& getInsns() const { return insns; }
77 const vk::RenderPass *getRenderPass() const { return renderPass; }
78 uint32_t getSubpassIndex() const { return subpassIndex; }
79 const VkSpecializationInfo *getSpecializationInfo() const { return specializationInfo.get(); }
80
81 private:
82 const VkShaderStageFlagBits pipelineStage;
83 const std::string entryPointName;
84 const std::vector<uint32_t> insns;
85 const vk::RenderPass *renderPass;
86 const uint32_t subpassIndex;
87 const SpecializationInfo specializationInfo;
88 };
89
90 std::mutex& getShaderMutex() { return spirvShadersMutex; }
91 const std::shared_ptr<sw::SpirvShader>* operator[](const PipelineCache::SpirvShaderKey& key) const;
92 void insert(const PipelineCache::SpirvShaderKey& key, const std::shared_ptr<sw::SpirvShader> &shader);
93
94 struct ComputeProgramKey
95 {
96 ComputeProgramKey(const sw::SpirvShader* shader, const vk::PipelineLayout* layout) :
97 shader(shader), layout(layout)
98 {}
99
100 bool operator<(const ComputeProgramKey &other) const
101 {
102 return (shader < other.shader) || (layout < other.layout);
103 }
104
105 const sw::SpirvShader* getShader() const { return shader; }
106 const vk::PipelineLayout* getLayout() const { return layout; }
107
108 private:
109 const sw::SpirvShader* shader;
110 const vk::PipelineLayout* layout;
111 };
112
113 std::mutex& getProgramMutex() { return computeProgramsMutex; }
114 const std::shared_ptr<sw::ComputeProgram>* operator[](const PipelineCache::ComputeProgramKey& key) const;
115 void insert(const PipelineCache::ComputeProgramKey& key, const std::shared_ptr<sw::ComputeProgram> &computeProgram);
116
Alexis Hetu18a84252018-11-19 11:30:43 -0500117private:
Alexis Hetu1424ef62019-04-05 18:03:53 -0400118 struct CacheHeader
119 {
120 uint32_t headerLength;
121 uint32_t headerVersion;
122 uint32_t vendorID;
123 uint32_t deviceID;
124 uint8_t pipelineCacheUUID[VK_UUID_SIZE];
125 };
126
127 size_t dataSize = 0;
128 uint8_t* data = nullptr;
Alexis Hetu52edb172019-06-26 10:17:18 -0400129
130 std::mutex spirvShadersMutex;
131 std::map<SpirvShaderKey, std::shared_ptr<sw::SpirvShader>> spirvShaders;
132
133 std::mutex computeProgramsMutex;
134 std::map<ComputeProgramKey, std::shared_ptr<sw::ComputeProgram>> computePrograms;
Alexis Hetu18a84252018-11-19 11:30:43 -0500135};
136
137static inline PipelineCache* Cast(VkPipelineCache object)
138{
Alexis Hetubd4cf812019-06-14 15:14:07 -0400139 return PipelineCache::Cast(object);
Alexis Hetu18a84252018-11-19 11:30:43 -0500140}
141
142} // namespace vk
143
144#endif // VK_PIPELINE_CACHE_HPP_