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 #include "GrVkPipelineState.h"
9
10 #include "GrContext.h"
11 #include "GrPipeline.h"
12 #include "GrTexturePriv.h"
13 #include "GrVkBufferView.h"
14 #include "GrVkCommandBuffer.h"
15 #include "GrVkDescriptorPool.h"
16 #include "GrVkDescriptorSet.h"
17 #include "GrVkGpu.h"
18 #include "GrVkImageView.h"
19 #include "GrVkMemory.h"
20 #include "GrVkPipeline.h"
21 #include "GrVkRenderTarget.h"
22 #include "GrVkSampler.h"
23 #include "GrVkTexelBuffer.h"
24 #include "GrVkTexture.h"
25 #include "GrVkUniformBuffer.h"
26 #include "glsl/GrGLSLFragmentProcessor.h"
27 #include "glsl/GrGLSLGeometryProcessor.h"
28 #include "glsl/GrGLSLXferProcessor.h"
29 #include "SkMipMap.h"
30
GrVkPipelineState(GrVkGpu * gpu,const GrVkPipelineState::Desc & desc,GrVkPipeline * pipeline,VkPipelineLayout layout,const GrVkDescriptorSetManager::Handle & samplerDSHandle,const GrVkDescriptorSetManager::Handle & texelBufferDSHandle,const BuiltinUniformHandles & builtinUniformHandles,const UniformInfoArray & uniforms,uint32_t geometryUniformSize,uint32_t fragmentUniformSize,uint32_t numSamplers,uint32_t numTexelBuffers,GrGLSLPrimitiveProcessor * geometryProcessor,GrGLSLXferProcessor * xferProcessor,const GrGLSLFragProcs & fragmentProcessors)31 GrVkPipelineState::GrVkPipelineState(GrVkGpu* gpu,
32 const GrVkPipelineState::Desc& desc,
33 GrVkPipeline* pipeline,
34 VkPipelineLayout layout,
35 const GrVkDescriptorSetManager::Handle& samplerDSHandle,
36 const GrVkDescriptorSetManager::Handle& texelBufferDSHandle,
37 const BuiltinUniformHandles& builtinUniformHandles,
38 const UniformInfoArray& uniforms,
39 uint32_t geometryUniformSize,
40 uint32_t fragmentUniformSize,
41 uint32_t numSamplers,
42 uint32_t numTexelBuffers,
43 GrGLSLPrimitiveProcessor* geometryProcessor,
44 GrGLSLXferProcessor* xferProcessor,
45 const GrGLSLFragProcs& fragmentProcessors)
46 : fPipeline(pipeline)
47 , fPipelineLayout(layout)
48 , fUniformDescriptorSet(nullptr)
49 , fSamplerDescriptorSet(nullptr)
50 , fTexelBufferDescriptorSet(nullptr)
51 , fSamplerDSHandle(samplerDSHandle)
52 , fTexelBufferDSHandle(texelBufferDSHandle)
53 , fBuiltinUniformHandles(builtinUniformHandles)
54 , fGeometryProcessor(geometryProcessor)
55 , fXferProcessor(xferProcessor)
56 , fFragmentProcessors(fragmentProcessors)
57 , fDesc(desc)
58 , fDataManager(uniforms, geometryUniformSize, fragmentUniformSize) {
59 fSamplers.setReserve(numSamplers);
60 fTextureViews.setReserve(numSamplers);
61 fTextures.setReserve(numSamplers);
62 fBufferViews.setReserve(numTexelBuffers);
63 fTexelBuffers.setReserve(numTexelBuffers);
64
65 fDescriptorSets[0] = VK_NULL_HANDLE;
66 fDescriptorSets[1] = VK_NULL_HANDLE;
67 fDescriptorSets[2] = VK_NULL_HANDLE;
68
69 fGeometryUniformBuffer.reset(GrVkUniformBuffer::Create(gpu, geometryUniformSize));
70 fFragmentUniformBuffer.reset(GrVkUniformBuffer::Create(gpu, fragmentUniformSize));
71
72 fNumSamplers = numSamplers;
73 fNumTexelBuffers = numTexelBuffers;
74 }
75
~GrVkPipelineState()76 GrVkPipelineState::~GrVkPipelineState() {
77 // Must have freed all GPU resources before this is destroyed
78 SkASSERT(!fPipeline);
79 SkASSERT(!fPipelineLayout);
80 SkASSERT(!fSamplers.count());
81 SkASSERT(!fTextureViews.count());
82 SkASSERT(!fTextures.count());
83 SkASSERT(!fBufferViews.count());
84 SkASSERT(!fTexelBuffers.count());
85
86 for (int i = 0; i < fFragmentProcessors.count(); ++i) {
87 delete fFragmentProcessors[i];
88 }
89 }
90
freeTempResources(const GrVkGpu * gpu)91 void GrVkPipelineState::freeTempResources(const GrVkGpu* gpu) {
92 for (int i = 0; i < fSamplers.count(); ++i) {
93 fSamplers[i]->unref(gpu);
94 }
95 fSamplers.rewind();
96
97 for (int i = 0; i < fTextureViews.count(); ++i) {
98 fTextureViews[i]->unref(gpu);
99 }
100 fTextureViews.rewind();
101
102 for (int i = 0; i < fTextures.count(); ++i) {
103 fTextures[i]->unref(gpu);
104 }
105 fTextures.rewind();
106
107 for (int i = 0; i < fBufferViews.count(); ++i) {
108 fBufferViews[i]->unref(gpu);
109 }
110 fBufferViews.rewind();
111
112 for (int i = 0; i < fTexelBuffers.count(); ++i) {
113 fTexelBuffers[i]->unref(gpu);
114 }
115 fTexelBuffers.rewind();
116 }
117
freeGPUResources(const GrVkGpu * gpu)118 void GrVkPipelineState::freeGPUResources(const GrVkGpu* gpu) {
119 if (fPipeline) {
120 fPipeline->unref(gpu);
121 fPipeline = nullptr;
122 }
123
124 if (fPipelineLayout) {
125 GR_VK_CALL(gpu->vkInterface(), DestroyPipelineLayout(gpu->device(),
126 fPipelineLayout,
127 nullptr));
128 fPipelineLayout = VK_NULL_HANDLE;
129 }
130
131 if (fGeometryUniformBuffer) {
132 fGeometryUniformBuffer->release(gpu);
133 }
134
135 if (fFragmentUniformBuffer) {
136 fFragmentUniformBuffer->release(gpu);
137 }
138
139 if (fUniformDescriptorSet) {
140 fUniformDescriptorSet->recycle(const_cast<GrVkGpu*>(gpu));
141 fUniformDescriptorSet = nullptr;
142 }
143
144 if (fSamplerDescriptorSet) {
145 fSamplerDescriptorSet->recycle(const_cast<GrVkGpu*>(gpu));
146 fSamplerDescriptorSet = nullptr;
147 }
148
149 if (fTexelBufferDescriptorSet) {
150 fTexelBufferDescriptorSet->recycle(const_cast<GrVkGpu*>(gpu));
151 fTexelBufferDescriptorSet = nullptr;
152 }
153
154
155 this->freeTempResources(gpu);
156 }
157
abandonGPUResources()158 void GrVkPipelineState::abandonGPUResources() {
159 fPipeline->unrefAndAbandon();
160 fPipeline = nullptr;
161
162 fPipelineLayout = VK_NULL_HANDLE;
163
164 fGeometryUniformBuffer->abandon();
165 fFragmentUniformBuffer->abandon();
166
167 for (int i = 0; i < fSamplers.count(); ++i) {
168 fSamplers[i]->unrefAndAbandon();
169 }
170 fSamplers.rewind();
171
172 for (int i = 0; i < fTextureViews.count(); ++i) {
173 fTextureViews[i]->unrefAndAbandon();
174 }
175 fTextureViews.rewind();
176
177 for (int i = 0; i < fTextures.count(); ++i) {
178 fTextures[i]->unrefAndAbandon();
179 }
180 fTextures.rewind();
181
182 for (int i = 0; i < fBufferViews.count(); ++i) {
183 fBufferViews[i]->unrefAndAbandon();
184 }
185 fBufferViews.rewind();
186
187 for (int i = 0; i < fTexelBuffers.count(); ++i) {
188 fTexelBuffers[i]->unrefAndAbandon();
189 }
190
191 fTexelBuffers.rewind();
192 if (fUniformDescriptorSet) {
193 fUniformDescriptorSet->unrefAndAbandon();
194 fUniformDescriptorSet = nullptr;
195 }
196
197 if (fSamplerDescriptorSet) {
198 fSamplerDescriptorSet->unrefAndAbandon();
199 fSamplerDescriptorSet = nullptr;
200 }
201
202 if (fTexelBufferDescriptorSet) {
203 fTexelBufferDescriptorSet->unrefAndAbandon();
204 fTexelBufferDescriptorSet = nullptr;
205 }
206 }
207
append_texture_bindings(const GrResourceIOProcessor & processor,SkTArray<const GrResourceIOProcessor::TextureSampler * > * textureBindings,SkTArray<const GrResourceIOProcessor::BufferAccess * > * bufferAccesses)208 static void append_texture_bindings(
209 const GrResourceIOProcessor& processor,
210 SkTArray<const GrResourceIOProcessor::TextureSampler*>* textureBindings,
211 SkTArray<const GrResourceIOProcessor::BufferAccess*>* bufferAccesses) {
212 // We don't support image storages in VK.
213 SkASSERT(!processor.numImageStorages());
214 if (int numTextureSamplers = processor.numTextureSamplers()) {
215 const GrResourceIOProcessor::TextureSampler** bindings =
216 textureBindings->push_back_n(numTextureSamplers);
217 int i = 0;
218 do {
219 bindings[i] = &processor.textureSampler(i);
220 } while (++i < numTextureSamplers);
221 }
222 if (int numTexelBuffers = processor.numBuffers()) {
223 const GrResourceIOProcessor::BufferAccess** accesses =
224 bufferAccesses->push_back_n(numTexelBuffers);
225 int i = 0;
226 do {
227 accesses[i] = &processor.bufferAccess(i);
228 } while (++i < numTexelBuffers);
229 }
230 }
231
setData(GrVkGpu * gpu,const GrPrimitiveProcessor & primProc,const GrPipeline & pipeline)232 void GrVkPipelineState::setData(GrVkGpu* gpu,
233 const GrPrimitiveProcessor& primProc,
234 const GrPipeline& pipeline) {
235 // This is here to protect against someone calling setData multiple times in a row without
236 // freeing the tempData between calls.
237 this->freeTempResources(gpu);
238
239 this->setRenderTargetState(pipeline.getRenderTarget());
240
241 SkSTArray<8, const GrResourceIOProcessor::TextureSampler*> textureBindings;
242 SkSTArray<8, const GrResourceIOProcessor::BufferAccess*> bufferAccesses;
243
244 fGeometryProcessor->setData(fDataManager, primProc,
245 GrFragmentProcessor::CoordTransformIter(pipeline));
246 append_texture_bindings(primProc, &textureBindings, &bufferAccesses);
247
248 GrFragmentProcessor::Iter iter(pipeline);
249 GrGLSLFragmentProcessor::Iter glslIter(fFragmentProcessors.begin(),
250 fFragmentProcessors.count());
251 const GrFragmentProcessor* fp = iter.next();
252 GrGLSLFragmentProcessor* glslFP = glslIter.next();
253 while (fp && glslFP) {
254 glslFP->setData(fDataManager, *fp);
255 append_texture_bindings(*fp, &textureBindings, &bufferAccesses);
256 fp = iter.next();
257 glslFP = glslIter.next();
258 }
259 SkASSERT(!fp && !glslFP);
260
261 {
262 SkIPoint offset;
263 GrTexture* dstTexture = pipeline.peekDstTexture(&offset);
264
265 fXferProcessor->setData(fDataManager, pipeline.getXferProcessor(), dstTexture, offset);
266 }
267
268 GrResourceIOProcessor::TextureSampler dstTextureSampler;
269 if (GrTextureProxy* dstTextureProxy = pipeline.dstTextureProxy()) {
270 dstTextureSampler.reset(sk_ref_sp(dstTextureProxy));
271 SkAssertResult(dstTextureSampler.instantiate(gpu->getContext()->resourceProvider()));
272 textureBindings.push_back(&dstTextureSampler);
273 }
274
275 // Get new descriptor sets
276 if (fNumSamplers) {
277 if (fSamplerDescriptorSet) {
278 fSamplerDescriptorSet->recycle(gpu);
279 }
280 fSamplerDescriptorSet = gpu->resourceProvider().getSamplerDescriptorSet(fSamplerDSHandle);
281 int samplerDSIdx = GrVkUniformHandler::kSamplerDescSet;
282 fDescriptorSets[samplerDSIdx] = fSamplerDescriptorSet->descriptorSet();
283 this->writeSamplers(gpu, textureBindings, pipeline.getAllowSRGBInputs());
284 }
285
286 if (fNumTexelBuffers) {
287 if (fTexelBufferDescriptorSet) {
288 fTexelBufferDescriptorSet->recycle(gpu);
289 }
290 fTexelBufferDescriptorSet =
291 gpu->resourceProvider().getSamplerDescriptorSet(fTexelBufferDSHandle);
292 int texelBufferDSIdx = GrVkUniformHandler::kTexelBufferDescSet;
293 fDescriptorSets[texelBufferDSIdx] = fTexelBufferDescriptorSet->descriptorSet();
294 this->writeTexelBuffers(gpu, bufferAccesses);
295 }
296
297 if (fGeometryUniformBuffer || fFragmentUniformBuffer) {
298 if (fDataManager.uploadUniformBuffers(gpu,
299 fGeometryUniformBuffer.get(),
300 fFragmentUniformBuffer.get())
301 || !fUniformDescriptorSet)
302 {
303 if (fUniformDescriptorSet) {
304 fUniformDescriptorSet->recycle(gpu);
305 }
306 fUniformDescriptorSet = gpu->resourceProvider().getUniformDescriptorSet();
307 int uniformDSIdx = GrVkUniformHandler::kUniformBufferDescSet;
308 fDescriptorSets[uniformDSIdx] = fUniformDescriptorSet->descriptorSet();
309 this->writeUniformBuffers(gpu);
310 }
311 }
312 }
313
set_uniform_descriptor_writes(VkWriteDescriptorSet * descriptorWrite,VkDescriptorBufferInfo * bufferInfo,const GrVkUniformBuffer * buffer,VkDescriptorSet descriptorSet,uint32_t binding)314 void set_uniform_descriptor_writes(VkWriteDescriptorSet* descriptorWrite,
315 VkDescriptorBufferInfo* bufferInfo,
316 const GrVkUniformBuffer* buffer,
317 VkDescriptorSet descriptorSet,
318 uint32_t binding) {
319
320 memset(bufferInfo, 0, sizeof(VkDescriptorBufferInfo));
321 bufferInfo->buffer = buffer->buffer();
322 bufferInfo->offset = buffer->offset();
323 bufferInfo->range = buffer->size();
324
325 memset(descriptorWrite, 0, sizeof(VkWriteDescriptorSet));
326 descriptorWrite->sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
327 descriptorWrite->pNext = nullptr;
328 descriptorWrite->dstSet = descriptorSet;
329 descriptorWrite->dstBinding = binding;
330 descriptorWrite->dstArrayElement = 0;
331 descriptorWrite->descriptorCount = 1;
332 descriptorWrite->descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
333 descriptorWrite->pImageInfo = nullptr;
334 descriptorWrite->pBufferInfo = bufferInfo;
335 descriptorWrite->pTexelBufferView = nullptr;
336 }
337
writeUniformBuffers(const GrVkGpu * gpu)338 void GrVkPipelineState::writeUniformBuffers(const GrVkGpu* gpu) {
339 VkWriteDescriptorSet descriptorWrites[3];
340 VkDescriptorBufferInfo bufferInfos[3];
341
342 uint32_t writeCount = 0;
343
344 // Geometry Uniform Buffer
345 if (fGeometryUniformBuffer.get()) {
346 set_uniform_descriptor_writes(&descriptorWrites[writeCount],
347 &bufferInfos[writeCount],
348 fGeometryUniformBuffer.get(),
349 fDescriptorSets[GrVkUniformHandler::kUniformBufferDescSet],
350 GrVkUniformHandler::kGeometryBinding);
351 ++writeCount;
352 }
353
354 // Fragment Uniform Buffer
355 if (fFragmentUniformBuffer.get()) {
356 set_uniform_descriptor_writes(&descriptorWrites[writeCount],
357 &bufferInfos[writeCount],
358 fFragmentUniformBuffer.get(),
359 fDescriptorSets[GrVkUniformHandler::kUniformBufferDescSet],
360 GrVkUniformHandler::kFragBinding);
361 ++writeCount;
362 }
363
364 if (writeCount) {
365 GR_VK_CALL(gpu->vkInterface(), UpdateDescriptorSets(gpu->device(),
366 writeCount,
367 descriptorWrites,
368 0, nullptr));
369 }
370 }
371
writeSamplers(GrVkGpu * gpu,const SkTArray<const GrResourceIOProcessor::TextureSampler * > & textureBindings,bool allowSRGBInputs)372 void GrVkPipelineState::writeSamplers(
373 GrVkGpu* gpu,
374 const SkTArray<const GrResourceIOProcessor::TextureSampler*>& textureBindings,
375 bool allowSRGBInputs) {
376 SkASSERT(fNumSamplers == textureBindings.count());
377
378 for (int i = 0; i < textureBindings.count(); ++i) {
379 const GrSamplerParams& params = textureBindings[i]->params();
380
381 GrVkTexture* texture = static_cast<GrVkTexture*>(textureBindings[i]->peekTexture());
382
383 fSamplers.push(gpu->resourceProvider().findOrCreateCompatibleSampler(params,
384 texture->texturePriv().maxMipMapLevel()));
385
386 const GrVkResource* textureResource = texture->resource();
387 textureResource->ref();
388 fTextures.push(textureResource);
389
390 const GrVkImageView* textureView = texture->textureView(allowSRGBInputs);
391 textureView->ref();
392 fTextureViews.push(textureView);
393
394 VkDescriptorImageInfo imageInfo;
395 memset(&imageInfo, 0, sizeof(VkDescriptorImageInfo));
396 imageInfo.sampler = fSamplers[i]->sampler();
397 imageInfo.imageView = textureView->imageView();
398 imageInfo.imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
399
400 VkWriteDescriptorSet writeInfo;
401 memset(&writeInfo, 0, sizeof(VkWriteDescriptorSet));
402 writeInfo.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
403 writeInfo.pNext = nullptr;
404 writeInfo.dstSet = fDescriptorSets[GrVkUniformHandler::kSamplerDescSet];
405 writeInfo.dstBinding = i;
406 writeInfo.dstArrayElement = 0;
407 writeInfo.descriptorCount = 1;
408 writeInfo.descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
409 writeInfo.pImageInfo = &imageInfo;
410 writeInfo.pBufferInfo = nullptr;
411 writeInfo.pTexelBufferView = nullptr;
412
413 GR_VK_CALL(gpu->vkInterface(), UpdateDescriptorSets(gpu->device(),
414 1,
415 &writeInfo,
416 0,
417 nullptr));
418 }
419 }
420
writeTexelBuffers(GrVkGpu * gpu,const SkTArray<const GrResourceIOProcessor::BufferAccess * > & bufferAccesses)421 void GrVkPipelineState::writeTexelBuffers(
422 GrVkGpu* gpu,
423 const SkTArray<const GrResourceIOProcessor::BufferAccess*>& bufferAccesses) {
424 SkASSERT(fNumTexelBuffers == bufferAccesses.count());
425
426 for (int i = 0; i < bufferAccesses.count(); ++i) {
427 GrPixelConfig config = bufferAccesses[i]->texelConfig();
428 VkFormat format;
429 SkAssertResult(GrPixelConfigToVkFormat(config, &format));
430
431 GrVkTexelBuffer* buffer = static_cast<GrVkTexelBuffer*>(bufferAccesses[i]->buffer());
432
433 const GrVkBufferView* bufferView = GrVkBufferView::Create(gpu, buffer->buffer(),
434 format, buffer->offset(),
435 buffer->size());
436 fBufferViews.push(bufferView);
437
438 const GrVkResource* bufferResource = buffer->resource();
439 bufferResource->ref();
440 fTexelBuffers.push(bufferResource);
441
442 VkWriteDescriptorSet writeInfo;
443 memset(&writeInfo, 0, sizeof(VkWriteDescriptorSet));
444 writeInfo.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
445 writeInfo.pNext = nullptr;
446 writeInfo.dstSet = fDescriptorSets[GrVkUniformHandler::kTexelBufferDescSet];
447 writeInfo.dstBinding = i;
448 writeInfo.dstArrayElement = 0;
449 writeInfo.descriptorCount = 1;
450 writeInfo.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER;
451 writeInfo.pImageInfo = nullptr;
452 writeInfo.pBufferInfo = nullptr;
453 VkBufferView vkBufferView = bufferView->bufferView();
454 writeInfo.pTexelBufferView = &vkBufferView;
455
456 GR_VK_CALL(gpu->vkInterface(), UpdateDescriptorSets(gpu->device(),
457 1,
458 &writeInfo,
459 0,
460 nullptr));
461 }
462 }
463
setRenderTargetState(const GrRenderTarget * rt)464 void GrVkPipelineState::setRenderTargetState(const GrRenderTarget* rt) {
465 // Load the RT height uniform if it is needed to y-flip gl_FragCoord.
466 if (fBuiltinUniformHandles.fRTHeightUni.isValid() &&
467 fRenderTargetState.fRenderTargetSize.fHeight != rt->height()) {
468 fDataManager.set1f(fBuiltinUniformHandles.fRTHeightUni, SkIntToScalar(rt->height()));
469 }
470
471 // set RT adjustment
472 SkISize size;
473 size.set(rt->width(), rt->height());
474 SkASSERT(fBuiltinUniformHandles.fRTAdjustmentUni.isValid());
475 if (fRenderTargetState.fRenderTargetOrigin != rt->origin() ||
476 fRenderTargetState.fRenderTargetSize != size) {
477 fRenderTargetState.fRenderTargetSize = size;
478 fRenderTargetState.fRenderTargetOrigin = rt->origin();
479
480 float rtAdjustmentVec[4];
481 fRenderTargetState.getRTAdjustmentVec(rtAdjustmentVec);
482 fDataManager.set4fv(fBuiltinUniformHandles.fRTAdjustmentUni, 1, rtAdjustmentVec);
483 }
484 }
485
bind(const GrVkGpu * gpu,GrVkCommandBuffer * commandBuffer)486 void GrVkPipelineState::bind(const GrVkGpu* gpu, GrVkCommandBuffer* commandBuffer) {
487 commandBuffer->bindPipeline(gpu, fPipeline);
488
489 if (fGeometryUniformBuffer || fFragmentUniformBuffer) {
490 int dsIndex = GrVkUniformHandler::kUniformBufferDescSet;
491 commandBuffer->bindDescriptorSets(gpu, this, fPipelineLayout,
492 dsIndex, 1,
493 &fDescriptorSets[dsIndex], 0, nullptr);
494 }
495 if (fNumSamplers) {
496 int dsIndex = GrVkUniformHandler::kSamplerDescSet;
497 commandBuffer->bindDescriptorSets(gpu, this, fPipelineLayout,
498 dsIndex, 1,
499 &fDescriptorSets[dsIndex], 0, nullptr);
500 }
501 if (fNumTexelBuffers) {
502 int dsIndex = GrVkUniformHandler::kTexelBufferDescSet;
503 commandBuffer->bindDescriptorSets(gpu, this, fPipelineLayout,
504 dsIndex, 1,
505 &fDescriptorSets[dsIndex], 0, nullptr);
506 }
507 }
508
addUniformResources(GrVkCommandBuffer & commandBuffer)509 void GrVkPipelineState::addUniformResources(GrVkCommandBuffer& commandBuffer) {
510 if (fUniformDescriptorSet) {
511 commandBuffer.addRecycledResource(fUniformDescriptorSet);
512 }
513 if (fSamplerDescriptorSet) {
514 commandBuffer.addRecycledResource(fSamplerDescriptorSet);
515 }
516 if (fTexelBufferDescriptorSet) {
517 commandBuffer.addRecycledResource(fTexelBufferDescriptorSet);
518 }
519
520 if (fGeometryUniformBuffer.get()) {
521 commandBuffer.addRecycledResource(fGeometryUniformBuffer->resource());
522 }
523 if (fFragmentUniformBuffer.get()) {
524 commandBuffer.addRecycledResource(fFragmentUniformBuffer->resource());
525 }
526
527 for (int i = 0; i < fSamplers.count(); ++i) {
528 commandBuffer.addResource(fSamplers[i]);
529 }
530
531 for (int i = 0; i < fTextureViews.count(); ++i) {
532 commandBuffer.addResource(fTextureViews[i]);
533 }
534
535 for (int i = 0; i < fTextures.count(); ++i) {
536 commandBuffer.addResource(fTextures[i]);
537 }
538
539 for (int i = 0; i < fBufferViews.count(); ++i) {
540 commandBuffer.addResource(fBufferViews[i]);
541 }
542
543 for (int i = 0; i < fTexelBuffers.count(); ++i) {
544 commandBuffer.addResource(fTexelBuffers[i]);
545 }
546 }
547
548 ////////////////////////////////////////////////////////////////////////////////
549
get_blend_info_key(const GrPipeline & pipeline)550 uint32_t get_blend_info_key(const GrPipeline& pipeline) {
551 GrXferProcessor::BlendInfo blendInfo;
552 pipeline.getXferProcessor().getBlendInfo(&blendInfo);
553
554 static const uint32_t kBlendWriteShift = 1;
555 static const uint32_t kBlendCoeffShift = 5;
556 GR_STATIC_ASSERT(kLast_GrBlendCoeff < (1 << kBlendCoeffShift));
557 GR_STATIC_ASSERT(kFirstAdvancedGrBlendEquation - 1 < 4);
558
559 uint32_t key = blendInfo.fWriteColor;
560 key |= (blendInfo.fSrcBlend << kBlendWriteShift);
561 key |= (blendInfo.fDstBlend << (kBlendWriteShift + kBlendCoeffShift));
562 key |= (blendInfo.fEquation << (kBlendWriteShift + 2 * kBlendCoeffShift));
563
564 return key;
565 }
566
Build(Desc * desc,const GrPrimitiveProcessor & primProc,const GrPipeline & pipeline,const GrStencilSettings & stencil,GrPrimitiveType primitiveType,const GrShaderCaps & caps)567 bool GrVkPipelineState::Desc::Build(Desc* desc,
568 const GrPrimitiveProcessor& primProc,
569 const GrPipeline& pipeline,
570 const GrStencilSettings& stencil,
571 GrPrimitiveType primitiveType,
572 const GrShaderCaps& caps) {
573 if (!INHERITED::Build(desc, primProc, primitiveType == GrPrimitiveType::kPoints, pipeline,
574 caps)) {
575 return false;
576 }
577
578 GrProcessorKeyBuilder b(&desc->key());
579 GrVkRenderTarget* vkRT = (GrVkRenderTarget*)pipeline.getRenderTarget();
580 vkRT->simpleRenderPass()->genKey(&b);
581
582 stencil.genKey(&b);
583
584 b.add32(get_blend_info_key(pipeline));
585
586 b.add32((uint32_t)primitiveType);
587
588 return true;
589 }
590