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

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

Powered by Google App Engine
This is Rietveld 408576698