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