Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(380)

Side by Side Diff: src/gpu/vk/GrVkPipelineState.h

Issue 1816153002: Set up cache in vulkan to reuse GrVkPrograms (aka VkPipelines) (Closed) Base URL: https://skia.googlesource.com/skia.git@progSamplers
Patch Set: rebase Created 4 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/gpu/vk/GrVkPipeline.cpp ('k') | src/gpu/vk/GrVkPipelineState.cpp » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 /*
2 * Copyright 2016 Google Inc.
3 *
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
6 */
7
8
9 #ifndef GrVkPipelineState_DEFINED
10 #define GrVkPipelineState_DEFINED
11
12 #include "GrVkImage.h"
13 #include "GrVkProgramDesc.h"
14 #include "GrVkPipelineStateDataManager.h"
15 #include "glsl/GrGLSLProgramBuilder.h"
16
17 #include "vulkan/vulkan.h"
18
19 class GrPipeline;
20 class GrVkCommandBuffer;
21 class GrVkDescriptorPool;
22 class GrVkGpu;
23 class GrVkImageView;
24 class GrVkPipeline;
25 class GrVkSampler;
26 class GrVkUniformBuffer;
27
28 /**
29 * This class holds onto a GrVkPipeline object that we use for draws. Besides st oring the acutal
30 * GrVkPipeline object, this class is also responsible handling all uniforms, de scriptors, samplers,
31 * and other similar objects that are used along with the VkPipeline in the draw . This includes both
32 * allocating and freeing these objects, as well as updating their values.
33 */
34 class GrVkPipelineState : public SkRefCnt {
35 public:
36 typedef GrGLSLProgramBuilder::BuiltinUniformHandles BuiltinUniformHandles;
37
38 ~GrVkPipelineState();
39
40 GrVkPipeline* vkPipeline() const { return fPipeline; }
41
42 void setData(GrVkGpu*, const GrPrimitiveProcessor&, const GrPipeline&);
43
44 void bind(const GrVkGpu* gpu, GrVkCommandBuffer* commandBuffer);
45
46 void addUniformResources(GrVkCommandBuffer&);
47
48 void freeGPUResources(const GrVkGpu* gpu);
49
50 // This releases resources that only a given instance of a GrVkPipelineState needs to hold onto
51 // and don't need to survive across new uses of the GrVkPipelineState.
52 void freeTempResources(const GrVkGpu* gpu);
53
54 void abandonGPUResources();
55
56 // The key is composed of two parts:
57 // 1. uint32_t for total key length
58 // 2. Pipeline state data
59 enum StateKeyOffsets {
60 // Part 1.
61 kLength_StateKeyOffset = 0,
62 // Part 2.
63 kData_StateKeyOffset = kLength_StateKeyOffset + sizeof(uint32_t),
64 };
65 static void BuildStateKey(const GrPipeline&, GrPrimitiveType primitiveType,
66 SkTArray<unsigned char, true>* key);
67
68 /**
69 * For Vulkan we want to cache the entire VkPipeline for reuse of draws. The Desc here holds all
70 * the information needed to differentiate one pipeline from another.
71 *
72 * The GrVkProgramDesc contains all the information need to create the actua l shaders for the
73 * pipeline.
74 *
75 * The fStateKey is used to store all the inputs for the rest of the state s tored on the
76 * pipeline. This includes stencil settings, blending information, render pa ss format, draw face
77 * information, and primitive type. Note that some state is set dynamically on the pipeline for
78 * each draw and thus is not included in this descriptor. This includes the viewport, scissor,
79 * and blend constant.
80 *
81 * A checksum which includes the fProgramDesc and fStateKey is included at t he top of the Desc
82 * for caching purposes and faster equality checks.
83 */
84 struct Desc {
85 uint32_t fChecksum;
86 GrVkProgramDesc fProgramDesc;
87
88 enum {
89 kRenderPassKeyAlloc = 12, // This is typical color attachment with n o stencil or msaa
90 kStencilKeyAlloc = sizeof(GrStencilSettings),
91 kDrawFaceKeyAlloc = 4,
92 kBlendingKeyAlloc = 4,
93 kPrimitiveTypeKeyAlloc = 4,
94 kPreAllocSize = kData_StateKeyOffset + kRenderPassKeyAlloc + kStenci lKeyAlloc +
95 kDrawFaceKeyAlloc + kBlendingKeyAlloc + kPrimitiveTy peKeyAlloc,
96 };
97 SkSTArray<kPreAllocSize, uint8_t, true> fStateKey;
98
99 bool operator== (const Desc& that) const {
100 if (fChecksum != that.fChecksum || fProgramDesc != that.fProgramDesc ) {
101 return false;
102 }
103 // We store the keyLength at the start of fVkKey. Thus we don't have to worry about
104 // different length keys since we will fail on the comparison immedi ately. Therefore we
105 // just use this PipelineDesc to get the length to iterate over.
106 int keyLength = fStateKey.count();
107 SkASSERT(SkIsAlign4(keyLength));
108 int l = keyLength >> 2;
109 const uint32_t* aKey = reinterpret_cast<const uint32_t*>(fStateKey.b egin());
110 const uint32_t* bKey = reinterpret_cast<const uint32_t*>(that.fState Key.begin());
111 for (int i = 0; i < l; ++i) {
112 if (aKey[i] != bKey[i]) {
113 return false;
114 }
115 }
116 return true;
117 }
118
119 static bool Less(const Desc& a, const Desc& b) {
120 if (a.fChecksum != b.fChecksum) {
121 return a.fChecksum < b.fChecksum ? true : false;
122 }
123 bool progDescLess = GrProgramDesc::Less(a.fProgramDesc, b.fProgramDe sc);
124 if (progDescLess || a.fProgramDesc != b.fProgramDesc) {
125 return progDescLess;
126 }
127
128 int keyLength = a.fStateKey.count();
129 SkASSERT(SkIsAlign4(keyLength));
130 int l = keyLength >> 2;
131 const uint32_t* aKey = reinterpret_cast<const uint32_t*>(a.fStateKey .begin());
132 const uint32_t* bKey = reinterpret_cast<const uint32_t*>(b.fStateKey .begin());
133 for (int i = 0; i < l; ++i) {
134 if (aKey[i] != bKey[i]) {
135 return aKey[i] < bKey[i] ? true : false;
136 }
137 }
138 return false;
139 }
140 };
141
142 const Desc& getDesc() { return fDesc; }
143
144 private:
145 typedef GrVkPipelineStateDataManager::UniformInfoArray UniformInfoArray;
146 typedef GrGLSLProgramDataManager::UniformHandle UniformHandle;
147
148 GrVkPipelineState(GrVkGpu* gpu,
149 const GrVkPipelineState::Desc&,
150 GrVkPipeline* pipeline,
151 VkPipelineLayout layout,
152 VkDescriptorSetLayout dsLayout[2],
153 const BuiltinUniformHandles& builtinUniformHandles,
154 const UniformInfoArray& uniforms,
155 uint32_t vertexUniformSize,
156 uint32_t fragmentUniformSize,
157 uint32_t numSamplers,
158 GrGLSLPrimitiveProcessor* geometryProcessor,
159 GrGLSLXferProcessor* xferProcessor,
160 const GrGLSLFragProcs& fragmentProcessors);
161
162 // Each pool will manage one type of descriptor. Thus each descriptor set we use will all be of
163 // one VkDescriptorType.
164 struct DescriptorPoolManager {
165 DescriptorPoolManager(VkDescriptorSetLayout layout, VkDescriptorType typ e,
166 uint32_t descCount, GrVkGpu* gpu)
167 : fDescLayout(layout)
168 , fDescType(type)
169 , fCurrentDescriptorSet(0)
170 , fPool(nullptr) {
171 SkASSERT(descCount < (SK_MaxU32 >> 2));
172 fMaxDescriptorSets = descCount << 2;
173 this->getNewPool(gpu);
174 }
175
176 ~DescriptorPoolManager() {
177 SkASSERT(!fDescLayout);
178 SkASSERT(!fPool);
179 }
180
181 void getNewDescriptorSet(GrVkGpu* gpu, VkDescriptorSet* ds);
182
183 void freeGPUResources(const GrVkGpu* gpu);
184 void abandonGPUResources();
185
186 VkDescriptorSetLayout fDescLayout;
187 VkDescriptorType fDescType;
188 uint32_t fMaxDescriptorSets;
189 uint32_t fCurrentDescriptorSet;
190 GrVkDescriptorPool* fPool;
191
192 private:
193 void getNewPool(GrVkGpu* gpu);
194 };
195
196 void writeUniformBuffers(const GrVkGpu* gpu);
197
198 void writeSamplers(GrVkGpu* gpu, const SkTArray<const GrTextureAccess*>& tex tureBindings);
199
200 /**
201 * We use the RT's size and origin to adjust from Skia device space to vulkan normalized device
202 * space and to make device space positions have the correct origin for proce ssors that require
203 * them.
204 */
205 struct RenderTargetState {
206 SkISize fRenderTargetSize;
207 GrSurfaceOrigin fRenderTargetOrigin;
208
209 RenderTargetState() { this->invalidate(); }
210 void invalidate() {
211 fRenderTargetSize.fWidth = -1;
212 fRenderTargetSize.fHeight = -1;
213 fRenderTargetOrigin = (GrSurfaceOrigin)-1;
214 }
215
216 /**
217 * Gets a vec4 that adjusts the position from Skia device coords to Vulka ns normalized device
218 * coords. Assuming the transformed position, pos, is a homogeneous vec3, the vec, v, is
219 * applied as such:
220 * pos.x = dot(v.xy, pos.xz)
221 * pos.y = dot(v.zw, pos.yz)
222 */
223 void getRTAdjustmentVec(float* destVec) {
224 destVec[0] = 2.f / fRenderTargetSize.fWidth;
225 destVec[1] = -1.f;
226 if (kBottomLeft_GrSurfaceOrigin == fRenderTargetOrigin) {
227 destVec[2] = -2.f / fRenderTargetSize.fHeight;
228 destVec[3] = 1.f;
229 } else {
230 destVec[2] = 2.f / fRenderTargetSize.fHeight;
231 destVec[3] = -1.f;
232 }
233 }
234 };
235
236 // Helper for setData() that sets the view matrix and loads the render targe t height uniform
237 void setRenderTargetState(const GrPipeline&);
238
239 // GrVkResources
240 GrVkPipeline* fPipeline;
241
242 // Used for binding DescriptorSets to the command buffer but does not need t o survive during
243 // command buffer execution. Thus this is not need to be a GrVkResource.
244 VkPipelineLayout fPipelineLayout;
245
246 // The DescriptorSets need to survive until the gpu has finished all draws t hat use them.
247 // However, they will only be freed by the descriptor pool. Thus by simply k eeping the
248 // descriptor pool alive through the draw, the descritor sets will also stay alive. Thus we do
249 // not need a GrVkResource versions of VkDescriptorSet. We hold on to these in the
250 // GrVkPipelineState since we update the descriptor sets and bind them at se parate times;
251 VkDescriptorSet fDescriptorSets[2];
252
253 // Meta data so we know which descriptor sets we are using and need to bind.
254 int fStartDS;
255 int fDSCount;
256
257 SkAutoTDelete<GrVkUniformBuffer> fVertexUniformBuffer;
258 SkAutoTDelete<GrVkUniformBuffer> fFragmentUniformBuffer;
259
260 // GrVkResources used for sampling textures
261 SkTDArray<GrVkSampler*> fSamplers;
262 SkTDArray<const GrVkImageView*> fTextureViews;
263 SkTDArray<const GrVkImage::Resource*> fTextures;
264
265 // Tracks the current render target uniforms stored in the vertex buffer.
266 RenderTargetState fRenderTargetState;
267 BuiltinUniformHandles fBuiltinUniformHandles;
268
269 // Processors in the GrVkPipelineState
270 SkAutoTDelete<GrGLSLPrimitiveProcessor> fGeometryProcessor;
271 SkAutoTDelete<GrGLSLXferProcessor> fXferProcessor;
272 GrGLSLFragProcs fFragmentProcessors;
273
274 Desc fDesc;
275
276 GrVkPipelineStateDataManager fDataManager;
277
278 DescriptorPoolManager fSamplerPoolManager;
279 DescriptorPoolManager fUniformPoolManager;
280
281 int fNumSamplers;
282
283 friend class GrVkPipelineStateBuilder;
284 };
285
286 #endif
OLDNEW
« no previous file with comments | « src/gpu/vk/GrVkPipeline.cpp ('k') | src/gpu/vk/GrVkPipelineState.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698