• 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 "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