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