1 /*
2 * Copyright 2015 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 "src/gpu/vk/GrVkRenderPass.h"
9
10 #include "src/gpu/GrProcessor.h"
11 #include "src/gpu/KeyBuilder.h"
12 #include "src/gpu/vk/GrVkFramebuffer.h"
13 #include "src/gpu/vk/GrVkGpu.h"
14 #include "src/gpu/vk/GrVkRenderTarget.h"
15 #include "src/gpu/vk/GrVkUtil.h"
16
17 typedef GrVkRenderPass::AttachmentsDescriptor::AttachmentDesc AttachmentDesc;
18
setup_vk_attachment_description(VkAttachmentDescription * attachment,const AttachmentDesc & desc,VkImageLayout startLayout,VkImageLayout endLayout)19 void setup_vk_attachment_description(VkAttachmentDescription* attachment,
20 const AttachmentDesc& desc,
21 VkImageLayout startLayout,
22 VkImageLayout endLayout) {
23 attachment->flags = 0;
24 attachment->format = desc.fFormat;
25 SkAssertResult(GrSampleCountToVkSampleCount(desc.fSamples, &attachment->samples));
26 switch (startLayout) {
27 case VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL:
28 case VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL:
29 case VK_IMAGE_LAYOUT_GENERAL:
30 attachment->loadOp = desc.fLoadStoreOps.fLoadOp;
31 attachment->storeOp = desc.fLoadStoreOps.fStoreOp;
32 attachment->stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
33 attachment->stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
34 break;
35 case VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL:
36 attachment->loadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
37 attachment->storeOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
38 attachment->stencilLoadOp = desc.fLoadStoreOps.fLoadOp;
39 attachment->stencilStoreOp = desc.fLoadStoreOps.fStoreOp;
40 break;
41 default:
42 SK_ABORT("Unexpected attachment layout");
43 }
44
45 attachment->initialLayout = startLayout;
46 attachment->finalLayout = endLayout == VK_IMAGE_LAYOUT_UNDEFINED ? startLayout : endLayout;
47 }
48
CreateSimple(GrVkGpu * gpu,AttachmentsDescriptor * attachmentsDescriptor,AttachmentFlags attachmentFlags,SelfDependencyFlags selfDepFlags,LoadFromResolve loadFromResolve)49 GrVkRenderPass* GrVkRenderPass::CreateSimple(GrVkGpu* gpu,
50 AttachmentsDescriptor* attachmentsDescriptor,
51 AttachmentFlags attachmentFlags,
52 SelfDependencyFlags selfDepFlags,
53 LoadFromResolve loadFromResolve) {
54 static const GrVkRenderPass::LoadStoreOps kBasicLoadStoreOps(VK_ATTACHMENT_LOAD_OP_LOAD,
55 VK_ATTACHMENT_STORE_OP_STORE);
56 switch (loadFromResolve) {
57 case LoadFromResolve::kNo:
58 return Create(gpu, attachmentFlags, attachmentsDescriptor, kBasicLoadStoreOps,
59 kBasicLoadStoreOps, kBasicLoadStoreOps, selfDepFlags, loadFromResolve);
60 case LoadFromResolve::kLoad: {
61 static const GrVkRenderPass::LoadStoreOps kDiscardLoadStoreOps(
62 VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_STORE_OP_DONT_CARE);
63 return Create(gpu, attachmentFlags, attachmentsDescriptor, kDiscardLoadStoreOps,
64 kBasicLoadStoreOps, kBasicLoadStoreOps, selfDepFlags, loadFromResolve);
65 }
66 }
67 SkUNREACHABLE;
68 }
69
Create(GrVkGpu * gpu,const GrVkRenderPass & compatibleRenderPass,const LoadStoreOps & colorOp,const LoadStoreOps & resolveOp,const LoadStoreOps & stencilOp)70 GrVkRenderPass* GrVkRenderPass::Create(GrVkGpu* gpu,
71 const GrVkRenderPass& compatibleRenderPass,
72 const LoadStoreOps& colorOp,
73 const LoadStoreOps& resolveOp,
74 const LoadStoreOps& stencilOp) {
75 AttachmentFlags attachmentFlags = compatibleRenderPass.fAttachmentFlags;
76 AttachmentsDescriptor attachmentsDescriptor = compatibleRenderPass.fAttachmentsDescriptor;
77 SelfDependencyFlags selfDepFlags = compatibleRenderPass.fSelfDepFlags;
78 LoadFromResolve loadFromResolve = compatibleRenderPass.fLoadFromResolve;
79 return Create(gpu, attachmentFlags, &attachmentsDescriptor, colorOp, resolveOp, stencilOp,
80 selfDepFlags, loadFromResolve);
81 }
82
Create(GrVkGpu * gpu,AttachmentFlags attachmentFlags,AttachmentsDescriptor * attachmentsDescriptor,const LoadStoreOps & colorOp,const LoadStoreOps & resolveOp,const LoadStoreOps & stencilOp,SelfDependencyFlags selfDepFlags,LoadFromResolve loadFromResolve)83 GrVkRenderPass* GrVkRenderPass::Create(GrVkGpu* gpu,
84 AttachmentFlags attachmentFlags,
85 AttachmentsDescriptor* attachmentsDescriptor,
86 const LoadStoreOps& colorOp,
87 const LoadStoreOps& resolveOp,
88 const LoadStoreOps& stencilOp,
89 SelfDependencyFlags selfDepFlags,
90 LoadFromResolve loadFromResolve) {
91 SkASSERT(!SkToBool(selfDepFlags & SelfDependencyFlags::kForNonCoherentAdvBlend) ||
92 gpu->caps()->advancedBlendEquationSupport());
93 SkASSERT(!SkToBool(selfDepFlags & SelfDependencyFlags::kForInputAttachment) ||
94 gpu->caps()->textureBarrierSupport());
95
96 // If we have a resolve attachment, we will always do a resolve into it. Thus it doesn't make
97 // sense not to store the resolve attachment at the end of the render pass.
98 //
99 // Currently today (when not using discardable msaa images) we load and store the the msaa image
100 // and then use the copy resolve command to handle the resolving. If instead we moved to doing
101 // the resolving at the end of the last render pass, we would probably want a separate flag
102 // for having a resolve attachment versus actually doing the resolving. This would allow us to
103 // use the same VkPiplines for render passes where we resolve and those we don't since each will
104 // always have the resolve attachment. The actual resolving or not does not affect render pass
105 // compatibility if there is only one sub pass, just the presence of the attachment or not.
106 SkASSERT(!SkToBool(attachmentFlags & kResolve_AttachmentFlag) ||
107 resolveOp.fStoreOp == VK_ATTACHMENT_STORE_OP_STORE);
108
109 SkASSERT(loadFromResolve == LoadFromResolve::kNo ||
110 (SkToBool(attachmentFlags & kColor_AttachmentFlag) &&
111 SkToBool(attachmentFlags & kResolve_AttachmentFlag)));
112
113 #ifdef SK_DEBUG
114 if (loadFromResolve == LoadFromResolve::kLoad) {
115 // If we are loading the resolve image into the msaa color attachment then we should not be
116 // loading or storing the msaa attachment. Additionally we need to make sure we are loading
117 // the resolve so it can be copied into the msaa color attachment.
118 SkASSERT(colorOp.fLoadOp == VK_ATTACHMENT_LOAD_OP_DONT_CARE);
119 SkASSERT(colorOp.fStoreOp == VK_ATTACHMENT_STORE_OP_DONT_CARE);
120 SkASSERT(resolveOp.fLoadOp == VK_ATTACHMENT_LOAD_OP_LOAD);
121 }
122 #endif
123
124 uint32_t numAttachments = attachmentsDescriptor->fAttachmentCount;
125 // Attachment descriptions to be set on the render pass
126 SkTArray<VkAttachmentDescription> attachments(numAttachments);
127 attachments.reset(numAttachments);
128 memset(attachments.begin(), 0, numAttachments * sizeof(VkAttachmentDescription));
129
130 // Refs to attachments on the render pass (as described by the VkAttachmentDescription above),
131 // that are used by the subpass.
132 VkAttachmentReference colorRef;
133 VkAttachmentReference resolveRef;
134 VkAttachmentReference resolveLoadInputRef;
135 VkAttachmentReference stencilRef;
136 uint32_t currentAttachment = 0;
137
138 // Go through each of the attachment types (color, stencil) and set the necessary
139 // on the various Vk structs.
140 VkSubpassDescription subpassDescs[2];
141 memset(subpassDescs, 0, 2*sizeof(VkSubpassDescription));
142 const int mainSubpass = loadFromResolve == LoadFromResolve::kLoad ? 1 : 0;
143 VkSubpassDescription& subpassDescMain = subpassDescs[mainSubpass];
144 subpassDescMain.flags = 0;
145 subpassDescMain.pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS;
146 subpassDescMain.inputAttachmentCount = 0;
147 subpassDescMain.pInputAttachments = nullptr;
148 subpassDescMain.pResolveAttachments = nullptr;
149
150 uint32_t clearValueCount = 0;
151
152 VkSubpassDependency dependencies[2];
153 int currentDependency = 0;
154
155 if (attachmentFlags & kColor_AttachmentFlag) {
156 // set up color attachment
157 bool needsGeneralLayout = SkToBool(selfDepFlags & SelfDependencyFlags::kForInputAttachment);
158 VkImageLayout layout = needsGeneralLayout ? VK_IMAGE_LAYOUT_GENERAL
159 : VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
160
161 attachmentsDescriptor->fColor.fLoadStoreOps = colorOp;
162
163 setup_vk_attachment_description(&attachments[currentAttachment],
164 attachmentsDescriptor->fColor,
165 layout, layout);
166 // setup subpass use of attachment
167 colorRef.attachment = currentAttachment++;
168 colorRef.layout = layout;
169 subpassDescMain.colorAttachmentCount = 1;
170
171 if (selfDepFlags != SelfDependencyFlags::kNone) {
172 VkSubpassDependency& dependency = dependencies[currentDependency++];
173 dependency.srcSubpass = mainSubpass;
174 dependency.dstSubpass = mainSubpass;
175 dependency.dependencyFlags = VK_DEPENDENCY_BY_REGION_BIT;
176 dependency.srcStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
177 dependency.srcAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
178 dependency.dstStageMask = 0;
179 dependency.dstAccessMask = 0;
180
181 if (selfDepFlags & SelfDependencyFlags::kForNonCoherentAdvBlend) {
182 // If we have coherent support we shouldn't be needing a self dependency
183 SkASSERT(!gpu->caps()->advancedCoherentBlendEquationSupport());
184 dependency.dstStageMask |= VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
185 dependency.dstAccessMask |= VK_ACCESS_COLOR_ATTACHMENT_READ_NONCOHERENT_BIT_EXT;
186 }
187 if (selfDepFlags & SelfDependencyFlags::kForInputAttachment) {
188 SkASSERT(gpu->vkCaps().maxInputAttachmentDescriptors());
189
190 subpassDescMain.inputAttachmentCount = 1;
191 subpassDescMain.pInputAttachments = &colorRef;
192
193 dependency.dstStageMask |= VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT;
194 dependency.dstAccessMask |= VK_ACCESS_INPUT_ATTACHMENT_READ_BIT;
195 }
196 }
197
198 if (VK_ATTACHMENT_LOAD_OP_CLEAR == colorOp.fLoadOp) {
199 clearValueCount = colorRef.attachment + 1;
200 }
201 } else {
202 // I don't think there should ever be a time where we don't have a color attachment
203 SkASSERT(false);
204 SkASSERT(selfDepFlags == SelfDependencyFlags::kNone);
205 colorRef.attachment = VK_ATTACHMENT_UNUSED;
206 colorRef.layout = VK_IMAGE_LAYOUT_UNDEFINED;
207 subpassDescMain.colorAttachmentCount = 0;
208 }
209
210 subpassDescMain.pColorAttachments = &colorRef;
211
212 if (attachmentFlags & kResolve_AttachmentFlag) {
213 attachmentsDescriptor->fResolve.fLoadStoreOps = resolveOp;
214
215 VkImageLayout layout = loadFromResolve == LoadFromResolve::kLoad
216 ? VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL
217 : VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
218
219 setup_vk_attachment_description(&attachments[currentAttachment],
220 attachmentsDescriptor->fResolve,
221 layout,
222 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL);
223
224 // setup main subpass use of attachment
225 resolveRef.attachment = currentAttachment++;
226 resolveRef.layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
227
228 subpassDescMain.pResolveAttachments = &resolveRef;
229
230 // Setup the load subpass and set subpass dependendcies
231 if (loadFromResolve == LoadFromResolve::kLoad) {
232 resolveLoadInputRef.attachment = resolveRef.attachment;
233 resolveLoadInputRef.layout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
234
235 // The load subpass will always be the first
236 VkSubpassDescription& subpassDescLoad = subpassDescs[0];
237 subpassDescLoad.flags = 0;
238 subpassDescLoad.pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS;
239 subpassDescLoad.inputAttachmentCount = 1;
240 subpassDescLoad.pInputAttachments = &resolveLoadInputRef;
241 subpassDescLoad.colorAttachmentCount = 1;
242 subpassDescLoad.pColorAttachments = &colorRef;
243 subpassDescLoad.pResolveAttachments = nullptr;
244 subpassDescLoad.pDepthStencilAttachment = nullptr;
245 subpassDescLoad.preserveAttachmentCount = 0;
246 subpassDescLoad.pPreserveAttachments = nullptr;
247
248 VkSubpassDependency& dependency = dependencies[currentDependency++];
249 dependency.srcSubpass = 0;
250 dependency.dstSubpass = mainSubpass;
251 dependency.dependencyFlags = VK_DEPENDENCY_BY_REGION_BIT;
252 dependency.srcStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
253 dependency.srcAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
254 dependency.dstStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
255 dependency.dstAccessMask =
256 VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
257 }
258 }
259
260
261 if (attachmentFlags & kStencil_AttachmentFlag) {
262 // set up stencil attachment
263 attachmentsDescriptor->fStencil.fLoadStoreOps = stencilOp;
264 setup_vk_attachment_description(&attachments[currentAttachment],
265 attachmentsDescriptor->fStencil,
266 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
267 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL);
268 // setup subpass use of attachment
269 stencilRef.attachment = currentAttachment++;
270 stencilRef.layout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
271 if (VK_ATTACHMENT_LOAD_OP_CLEAR == stencilOp.fLoadOp) {
272 clearValueCount = std::max(clearValueCount, stencilRef.attachment + 1);
273 }
274 } else {
275 stencilRef.attachment = VK_ATTACHMENT_UNUSED;
276 stencilRef.layout = VK_IMAGE_LAYOUT_UNDEFINED;
277 }
278 subpassDescMain.pDepthStencilAttachment = &stencilRef;
279
280 subpassDescMain.preserveAttachmentCount = 0;
281 subpassDescMain.pPreserveAttachments = nullptr;
282
283 SkASSERT(numAttachments == currentAttachment);
284
285 uint32_t subpassCount = loadFromResolve == LoadFromResolve::kLoad ? 2 : 1;
286
287 // Create the VkRenderPass compatible with the attachment descriptions above
288 VkRenderPassCreateInfo createInfo;
289 memset(&createInfo, 0, sizeof(VkRenderPassCreateInfo));
290 createInfo.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO;
291 createInfo.pNext = nullptr;
292 createInfo.flags = 0;
293 createInfo.attachmentCount = numAttachments;
294 createInfo.pAttachments = attachments.begin();
295 createInfo.subpassCount = subpassCount;
296 createInfo.pSubpasses = subpassDescs;
297 createInfo.dependencyCount = currentDependency;
298 createInfo.pDependencies = dependencies;
299
300 VkResult result;
301 VkRenderPass renderPass;
302 GR_VK_CALL_RESULT(gpu, result, CreateRenderPass(gpu->device(),
303 &createInfo,
304 nullptr,
305 &renderPass));
306 if (result != VK_SUCCESS) {
307 return nullptr;
308 }
309
310 VkExtent2D granularity;
311 // Get granularity for this render pass
312 GR_VK_CALL(gpu->vkInterface(), GetRenderAreaGranularity(gpu->device(),
313 renderPass,
314 &granularity));
315
316 return new GrVkRenderPass(gpu, renderPass, attachmentFlags, *attachmentsDescriptor,
317 selfDepFlags, loadFromResolve, granularity, clearValueCount);
318 }
319
GrVkRenderPass(const GrVkGpu * gpu,VkRenderPass renderPass,AttachmentFlags flags,const AttachmentsDescriptor & descriptor,SelfDependencyFlags selfDepFlags,LoadFromResolve loadFromResolve,const VkExtent2D & granularity,uint32_t clearValueCount)320 GrVkRenderPass::GrVkRenderPass(const GrVkGpu* gpu, VkRenderPass renderPass, AttachmentFlags flags,
321 const AttachmentsDescriptor& descriptor,
322 SelfDependencyFlags selfDepFlags,
323 LoadFromResolve loadFromResolve,
324 const VkExtent2D& granularity, uint32_t clearValueCount)
325 : INHERITED(gpu)
326 , fRenderPass(renderPass)
327 , fAttachmentFlags(flags)
328 , fAttachmentsDescriptor(descriptor)
329 , fSelfDepFlags(selfDepFlags)
330 , fLoadFromResolve(loadFromResolve)
331 , fGranularity(granularity)
332 , fClearValueCount(clearValueCount) {
333 }
334
freeGPUData() const335 void GrVkRenderPass::freeGPUData() const {
336 if (!(fAttachmentFlags & kExternal_AttachmentFlag)) {
337 GR_VK_CALL(fGpu->vkInterface(), DestroyRenderPass(fGpu->device(), fRenderPass, nullptr));
338 }
339 }
340
colorAttachmentIndex(uint32_t * index) const341 bool GrVkRenderPass::colorAttachmentIndex(uint32_t* index) const {
342 *index = fColorAttachmentIndex;
343 if ((fAttachmentFlags & kColor_AttachmentFlag) ||
344 (fAttachmentFlags & kExternal_AttachmentFlag)) {
345 return true;
346 }
347 return false;
348 }
349
350 // Works under the assumption that stencil attachment will always be after the color and resolve
351 // attachments.
stencilAttachmentIndex(uint32_t * index) const352 bool GrVkRenderPass::stencilAttachmentIndex(uint32_t* index) const {
353 *index = 0;
354 if (fAttachmentFlags & kColor_AttachmentFlag) {
355 ++(*index);
356 }
357 if (fAttachmentFlags & kStencil_AttachmentFlag) {
358 return true;
359 }
360 return false;
361 }
362
isCompatible(const AttachmentsDescriptor & desc,const AttachmentFlags & flags,SelfDependencyFlags selfDepFlags,LoadFromResolve loadFromResolve) const363 bool GrVkRenderPass::isCompatible(const AttachmentsDescriptor& desc,
364 const AttachmentFlags& flags,
365 SelfDependencyFlags selfDepFlags,
366 LoadFromResolve loadFromResolve) const {
367 SkASSERT(!(fAttachmentFlags & kExternal_AttachmentFlag));
368 if (flags != fAttachmentFlags) {
369 return false;
370 }
371
372 if (fAttachmentFlags & kColor_AttachmentFlag) {
373 if (!fAttachmentsDescriptor.fColor.isCompatible(desc.fColor)) {
374 return false;
375 }
376 }
377 if (fAttachmentFlags & kResolve_AttachmentFlag) {
378 if (!fAttachmentsDescriptor.fResolve.isCompatible(desc.fResolve)) {
379 return false;
380 }
381 }
382 if (fAttachmentFlags & kStencil_AttachmentFlag) {
383 if (!fAttachmentsDescriptor.fStencil.isCompatible(desc.fStencil)) {
384 return false;
385 }
386 }
387
388 if (fSelfDepFlags != selfDepFlags) {
389 return false;
390 }
391
392 if (fLoadFromResolve != loadFromResolve) {
393 return false;
394 }
395
396 return true;
397 }
398
isCompatible(GrVkRenderTarget * target,SelfDependencyFlags selfDepFlags,LoadFromResolve loadFromResolve) const399 bool GrVkRenderPass::isCompatible(GrVkRenderTarget* target,
400 SelfDependencyFlags selfDepFlags,
401 LoadFromResolve loadFromResolve) const {
402 SkASSERT(!(fAttachmentFlags & kExternal_AttachmentFlag));
403
404 AttachmentsDescriptor desc;
405 AttachmentFlags flags;
406 target->getAttachmentsDescriptor(&desc, &flags, this->hasResolveAttachment(),
407 this->hasStencilAttachment());
408
409 return this->isCompatible(desc, flags, selfDepFlags, loadFromResolve);
410 }
411
isCompatible(const GrVkRenderPass & renderPass) const412 bool GrVkRenderPass::isCompatible(const GrVkRenderPass& renderPass) const {
413 SkASSERT(!(fAttachmentFlags & kExternal_AttachmentFlag));
414 return this->isCompatible(renderPass.fAttachmentsDescriptor, renderPass.fAttachmentFlags,
415 renderPass.fSelfDepFlags, renderPass.fLoadFromResolve);
416 }
417
isCompatibleExternalRP(VkRenderPass renderPass) const418 bool GrVkRenderPass::isCompatibleExternalRP(VkRenderPass renderPass) const {
419 SkASSERT(fAttachmentFlags & kExternal_AttachmentFlag);
420 return fRenderPass == renderPass;
421 }
422
equalLoadStoreOps(const LoadStoreOps & colorOps,const LoadStoreOps & resolveOps,const LoadStoreOps & stencilOps) const423 bool GrVkRenderPass::equalLoadStoreOps(const LoadStoreOps& colorOps,
424 const LoadStoreOps& resolveOps,
425 const LoadStoreOps& stencilOps) const {
426 SkASSERT(!(fAttachmentFlags & kExternal_AttachmentFlag));
427 if (fAttachmentFlags & kColor_AttachmentFlag) {
428 if (fAttachmentsDescriptor.fColor.fLoadStoreOps != colorOps) {
429 return false;
430 }
431 }
432 if (fAttachmentFlags & kResolve_AttachmentFlag) {
433 if (fAttachmentsDescriptor.fResolve.fLoadStoreOps != resolveOps) {
434 return false;
435 }
436 }
437 if (fAttachmentFlags & kStencil_AttachmentFlag) {
438 if (fAttachmentsDescriptor.fStencil.fLoadStoreOps != stencilOps) {
439 return false;
440 }
441 }
442 return true;
443 }
444
genKey(skgpu::KeyBuilder * b) const445 void GrVkRenderPass::genKey(skgpu::KeyBuilder* b) const {
446 GenKey(b, fAttachmentFlags, fAttachmentsDescriptor, fSelfDepFlags,
447 fLoadFromResolve, (uint64_t)fRenderPass);
448 }
449
GenKey(skgpu::KeyBuilder * b,AttachmentFlags attachmentFlags,const AttachmentsDescriptor & attachmentsDescriptor,SelfDependencyFlags selfDepFlags,LoadFromResolve loadFromResolve,uint64_t externalRenderPass)450 void GrVkRenderPass::GenKey(skgpu::KeyBuilder* b,
451 AttachmentFlags attachmentFlags,
452 const AttachmentsDescriptor& attachmentsDescriptor,
453 SelfDependencyFlags selfDepFlags,
454 LoadFromResolve loadFromResolve,
455 uint64_t externalRenderPass) {
456 b->add32(attachmentFlags);
457 if (attachmentFlags & kColor_AttachmentFlag) {
458 b->add32(attachmentsDescriptor.fColor.fFormat);
459 b->add32(attachmentsDescriptor.fColor.fSamples);
460 }
461 if (attachmentFlags & kResolve_AttachmentFlag) {
462 b->add32(attachmentsDescriptor.fResolve.fFormat);
463 b->add32(attachmentsDescriptor.fResolve.fSamples);
464 }
465 if (attachmentFlags & kStencil_AttachmentFlag) {
466 b->add32(attachmentsDescriptor.fStencil.fFormat);
467 b->add32(attachmentsDescriptor.fStencil.fSamples);
468 }
469
470 uint32_t extraFlags = (uint32_t)selfDepFlags;
471 SkASSERT(extraFlags < (1 << 30));
472 SkASSERT((uint32_t)loadFromResolve <= 2);
473 extraFlags |= ((uint32_t)loadFromResolve << 30);
474
475 b->add32(extraFlags);
476
477 if (attachmentFlags & kExternal_AttachmentFlag) {
478 SkASSERT(!(attachmentFlags & ~kExternal_AttachmentFlag));
479 b->add32((uint32_t)(externalRenderPass & 0xFFFFFFFF));
480 b->add32((uint32_t)(externalRenderPass>>32));
481 }
482 }
483