xref: /aosp_15_r20/external/skia/src/gpu/graphite/vk/VulkanRenderPass.cpp (revision c8dee2aa9b3f27cf6c858bd81872bdeb2c07ed17)
1*c8dee2aaSAndroid Build Coastguard Worker /*
2*c8dee2aaSAndroid Build Coastguard Worker * Copyright 2023 Google LLC
3*c8dee2aaSAndroid Build Coastguard Worker *
4*c8dee2aaSAndroid Build Coastguard Worker * Use of this source code is governed by a BSD-style license that can be
5*c8dee2aaSAndroid Build Coastguard Worker * found in the LICENSE file.
6*c8dee2aaSAndroid Build Coastguard Worker */
7*c8dee2aaSAndroid Build Coastguard Worker 
8*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/graphite/vk/VulkanRenderPass.h"
9*c8dee2aaSAndroid Build Coastguard Worker 
10*c8dee2aaSAndroid Build Coastguard Worker #include "include/gpu/graphite/vk/VulkanGraphiteTypes.h"
11*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/graphite/RenderPassDesc.h"
12*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/graphite/Texture.h"
13*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/graphite/vk/VulkanCommandBuffer.h"
14*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/graphite/vk/VulkanGraphiteUtilsPriv.h"
15*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/graphite/vk/VulkanSharedContext.h"
16*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/graphite/vk/VulkanTexture.h"
17*c8dee2aaSAndroid Build Coastguard Worker 
18*c8dee2aaSAndroid Build Coastguard Worker #include <limits>
19*c8dee2aaSAndroid Build Coastguard Worker 
20*c8dee2aaSAndroid Build Coastguard Worker namespace skgpu::graphite {
21*c8dee2aaSAndroid Build Coastguard Worker 
22*c8dee2aaSAndroid Build Coastguard Worker namespace { // anonymous namespace
23*c8dee2aaSAndroid Build Coastguard Worker 
determine_uint32_count(int rpAttachmentCount,int subpassCount,int subpassDependencyCount)24*c8dee2aaSAndroid Build Coastguard Worker int determine_uint32_count(int rpAttachmentCount, int subpassCount, int subpassDependencyCount ) {
25*c8dee2aaSAndroid Build Coastguard Worker     // The key will be formed such that bigger-picture items (such as the total attachment count)
26*c8dee2aaSAndroid Build Coastguard Worker     // will be near the front of the key to more quickly eliminate incompatible keys. Each
27*c8dee2aaSAndroid Build Coastguard Worker     // renderpass key will start with the total number of attachments associated with it
28*c8dee2aaSAndroid Build Coastguard Worker     // followed by how many subpasses and subpass dependencies the renderpass has.Packed together,
29*c8dee2aaSAndroid Build Coastguard Worker     // these will use one uint32.
30*c8dee2aaSAndroid Build Coastguard Worker     int num32DataCnt = 1;
31*c8dee2aaSAndroid Build Coastguard Worker     SkASSERT(static_cast<uint32_t>(rpAttachmentCount) <= (1u << 8));
32*c8dee2aaSAndroid Build Coastguard Worker     SkASSERT(static_cast<uint32_t>(subpassCount) <= (1u << 8));
33*c8dee2aaSAndroid Build Coastguard Worker     SkASSERT(static_cast<uint32_t>(subpassDependencyCount) <= (1u << 8));
34*c8dee2aaSAndroid Build Coastguard Worker 
35*c8dee2aaSAndroid Build Coastguard Worker     // The key will then contain key information for each attachment. This includes format, sample
36*c8dee2aaSAndroid Build Coastguard Worker     // count, and load/store operation information.
37*c8dee2aaSAndroid Build Coastguard Worker     num32DataCnt += 3 * rpAttachmentCount;
38*c8dee2aaSAndroid Build Coastguard Worker     // Then, subpass information will be added in the form of attachment reference indices. Reserve
39*c8dee2aaSAndroid Build Coastguard Worker     // one int32 for each possible attachment reference type, of which there are 4.
40*c8dee2aaSAndroid Build Coastguard Worker     // There are 4 possible attachment reference types. Pack all 4 attachment reference indices into
41*c8dee2aaSAndroid Build Coastguard Worker     // one uint32.
42*c8dee2aaSAndroid Build Coastguard Worker     num32DataCnt += subpassCount;
43*c8dee2aaSAndroid Build Coastguard Worker     // Each subpass dependency will be allotted 6 int32s to store all its pertinent information.
44*c8dee2aaSAndroid Build Coastguard Worker     num32DataCnt += 6 * subpassDependencyCount;
45*c8dee2aaSAndroid Build Coastguard Worker 
46*c8dee2aaSAndroid Build Coastguard Worker     return num32DataCnt;
47*c8dee2aaSAndroid Build Coastguard Worker }
48*c8dee2aaSAndroid Build Coastguard Worker 
add_attachment_description_info_to_key(ResourceKey::Builder & builder,const TextureInfo & textureInfo,int & builderIdx,LoadOp loadOp,StoreOp storeOp)49*c8dee2aaSAndroid Build Coastguard Worker void add_attachment_description_info_to_key(ResourceKey::Builder& builder,
50*c8dee2aaSAndroid Build Coastguard Worker                                             const TextureInfo& textureInfo,
51*c8dee2aaSAndroid Build Coastguard Worker                                             int& builderIdx,
52*c8dee2aaSAndroid Build Coastguard Worker                                             LoadOp loadOp,
53*c8dee2aaSAndroid Build Coastguard Worker                                             StoreOp storeOp) {
54*c8dee2aaSAndroid Build Coastguard Worker     VulkanTextureInfo vkTexInfo;
55*c8dee2aaSAndroid Build Coastguard Worker     if (textureInfo.isValid() && TextureInfos::GetVulkanTextureInfo(textureInfo, &vkTexInfo)) {
56*c8dee2aaSAndroid Build Coastguard Worker         builder[builderIdx++] = vkTexInfo.fFormat;
57*c8dee2aaSAndroid Build Coastguard Worker         builder[builderIdx++] = vkTexInfo.fSampleCount;
58*c8dee2aaSAndroid Build Coastguard Worker         SkASSERT(sizeof(loadOp)  < (1u << 8));
59*c8dee2aaSAndroid Build Coastguard Worker         SkASSERT(sizeof(storeOp) < (1u << 8));
60*c8dee2aaSAndroid Build Coastguard Worker         builder[builderIdx++] = static_cast<uint8_t>(loadOp) << 8 | static_cast<uint8_t>(storeOp);
61*c8dee2aaSAndroid Build Coastguard Worker     }
62*c8dee2aaSAndroid Build Coastguard Worker     // We only count attachments that are valid textures when calculating the total number of
63*c8dee2aaSAndroid Build Coastguard Worker     // render pass attachments, so if a texture is invalid, simply skip it rather than using
64*c8dee2aaSAndroid Build Coastguard Worker     // VK_ATTACHMENT_UNUSED and incrementing the builderIdx. Attachments can be differentiated from
65*c8dee2aaSAndroid Build Coastguard Worker     // one another by their sample count and format (i.e. depth/stencil attachments will have a
66*c8dee2aaSAndroid Build Coastguard Worker     // depth/stencil format).
67*c8dee2aaSAndroid Build Coastguard Worker }
68*c8dee2aaSAndroid Build Coastguard Worker 
add_subpass_info_to_key(ResourceKey::Builder & builder,int & builderIdx,bool hasColorAttachment,bool hasColorResolveAttachment,bool hasDepthStencilAttachment,bool loadMSAAFromResolve,int subpassCount,int subpassDependencyCount)69*c8dee2aaSAndroid Build Coastguard Worker void add_subpass_info_to_key(ResourceKey::Builder& builder,
70*c8dee2aaSAndroid Build Coastguard Worker                              int& builderIdx,
71*c8dee2aaSAndroid Build Coastguard Worker                              bool hasColorAttachment,
72*c8dee2aaSAndroid Build Coastguard Worker                              bool hasColorResolveAttachment,
73*c8dee2aaSAndroid Build Coastguard Worker                              bool hasDepthStencilAttachment,
74*c8dee2aaSAndroid Build Coastguard Worker                              bool loadMSAAFromResolve,
75*c8dee2aaSAndroid Build Coastguard Worker                              int subpassCount,
76*c8dee2aaSAndroid Build Coastguard Worker                              int subpassDependencyCount) {
77*c8dee2aaSAndroid Build Coastguard Worker     // TODO: Fetch actual attachment reference and index information for each
78*c8dee2aaSAndroid Build Coastguard Worker     // subpass from RenderPassDesc. For now, determine subpass data based upon whether we are
79*c8dee2aaSAndroid Build Coastguard Worker     // loading from MSAA or not.
80*c8dee2aaSAndroid Build Coastguard Worker     const int mainSubpassIdx = loadMSAAFromResolve ? 1 : 0;
81*c8dee2aaSAndroid Build Coastguard Worker     // Assign a smaller value to represent VK_ATTACHMENT_UNUSED.
82*c8dee2aaSAndroid Build Coastguard Worker     static constexpr int kAttachmentUnused = std::numeric_limits<uint8_t>::max();
83*c8dee2aaSAndroid Build Coastguard Worker 
84*c8dee2aaSAndroid Build Coastguard Worker     // The following key structure assumes that we only have up to one reference of each type per
85*c8dee2aaSAndroid Build Coastguard Worker     // subpass and that attachments are indexed in order of color, resolve, depth/stencil, then
86*c8dee2aaSAndroid Build Coastguard Worker     // input attachments. These indices are statically defined in the VulkanRenderPass header file.
87*c8dee2aaSAndroid Build Coastguard Worker     for (int j = 0; j < subpassCount; j++) {
88*c8dee2aaSAndroid Build Coastguard Worker         if (j == mainSubpassIdx) {
89*c8dee2aaSAndroid Build Coastguard Worker             uint32_t attachmentIdxKeyInfo;
90*c8dee2aaSAndroid Build Coastguard Worker             attachmentIdxKeyInfo = hasColorAttachment ? VulkanRenderPass::kColorAttachmentIdx
91*c8dee2aaSAndroid Build Coastguard Worker                                                       : kAttachmentUnused;
92*c8dee2aaSAndroid Build Coastguard Worker             attachmentIdxKeyInfo |=
93*c8dee2aaSAndroid Build Coastguard Worker                     (hasColorResolveAttachment ? VulkanRenderPass::kColorResolveAttachmentIdx
94*c8dee2aaSAndroid Build Coastguard Worker                                                : kAttachmentUnused) << 8;
95*c8dee2aaSAndroid Build Coastguard Worker             attachmentIdxKeyInfo |=
96*c8dee2aaSAndroid Build Coastguard Worker                     (hasDepthStencilAttachment ? VulkanRenderPass::kDepthStencilAttachmentIdx
97*c8dee2aaSAndroid Build Coastguard Worker                                                : kAttachmentUnused) << 16;
98*c8dee2aaSAndroid Build Coastguard Worker             // TODO: Add input attachment info to key once supported for use in main subpass
99*c8dee2aaSAndroid Build Coastguard Worker             attachmentIdxKeyInfo |= kAttachmentUnused << 24;
100*c8dee2aaSAndroid Build Coastguard Worker 
101*c8dee2aaSAndroid Build Coastguard Worker             builder[builderIdx++] = attachmentIdxKeyInfo;
102*c8dee2aaSAndroid Build Coastguard Worker         } else { // Loading MSAA from resolve subpass
103*c8dee2aaSAndroid Build Coastguard Worker             SkASSERT(hasColorAttachment);
104*c8dee2aaSAndroid Build Coastguard Worker             builder[builderIdx++] =
105*c8dee2aaSAndroid Build Coastguard Worker                     VulkanRenderPass::kColorAttachmentIdx | // color attachment
106*c8dee2aaSAndroid Build Coastguard Worker                     (kAttachmentUnused << 8)              | // No color resolve attachment
107*c8dee2aaSAndroid Build Coastguard Worker                     (kAttachmentUnused << 16)             | // No depth/stencil attachment
108*c8dee2aaSAndroid Build Coastguard Worker                     // The input attachment for the load subpass is the color resolve texture.
109*c8dee2aaSAndroid Build Coastguard Worker                     (VulkanRenderPass::kColorResolveAttachmentIdx << 24);
110*c8dee2aaSAndroid Build Coastguard Worker         }
111*c8dee2aaSAndroid Build Coastguard Worker     }
112*c8dee2aaSAndroid Build Coastguard Worker 
113*c8dee2aaSAndroid Build Coastguard Worker     // TODO: Query RenderPassDesc for subpass dependency information & populate the key accordingly.
114*c8dee2aaSAndroid Build Coastguard Worker     // For now, we know that the only subpass dependency will be that expected for loading MSAA from
115*c8dee2aaSAndroid Build Coastguard Worker     // resolve.
116*c8dee2aaSAndroid Build Coastguard Worker     for (int i = 0; i < subpassDependencyCount; i++) {
117*c8dee2aaSAndroid Build Coastguard Worker         builder[builderIdx++] = 0 | (mainSubpassIdx << 8); // srcSubpass, dstSubpass
118*c8dee2aaSAndroid Build Coastguard Worker         builder[builderIdx++] = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT; // srcStageMask
119*c8dee2aaSAndroid Build Coastguard Worker         builder[builderIdx++] = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT; // dstStageMask
120*c8dee2aaSAndroid Build Coastguard Worker         builder[builderIdx++] = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;          // srcAccessMask
121*c8dee2aaSAndroid Build Coastguard Worker         builder[builderIdx++] = VK_ACCESS_COLOR_ATTACHMENT_READ_BIT |          // dstAccessMask
122*c8dee2aaSAndroid Build Coastguard Worker                                 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
123*c8dee2aaSAndroid Build Coastguard Worker         builder[builderIdx++] = VK_DEPENDENCY_BY_REGION_BIT;                   // dependencyFlags
124*c8dee2aaSAndroid Build Coastguard Worker     }
125*c8dee2aaSAndroid Build Coastguard Worker }
126*c8dee2aaSAndroid Build Coastguard Worker 
populate_key(VulkanRenderPass::VulkanRenderPassMetaData & rpMetaData,ResourceKey::Builder & builder,int & builderIdx,bool compatibleOnly)127*c8dee2aaSAndroid Build Coastguard Worker void populate_key(VulkanRenderPass::VulkanRenderPassMetaData& rpMetaData,
128*c8dee2aaSAndroid Build Coastguard Worker                   ResourceKey::Builder& builder,
129*c8dee2aaSAndroid Build Coastguard Worker                   int& builderIdx,
130*c8dee2aaSAndroid Build Coastguard Worker                   bool compatibleOnly) {
131*c8dee2aaSAndroid Build Coastguard Worker     builder[builderIdx++] = rpMetaData.fAttachments.size()  |
132*c8dee2aaSAndroid Build Coastguard Worker                             (rpMetaData.fSubpassCount << 8) |
133*c8dee2aaSAndroid Build Coastguard Worker                             (rpMetaData.fSubpassDependencyCount << 16);
134*c8dee2aaSAndroid Build Coastguard Worker 
135*c8dee2aaSAndroid Build Coastguard Worker     // Iterate through each renderpass attachment to add its information
136*c8dee2aaSAndroid Build Coastguard Worker     for (int i = 0; i < rpMetaData.fAttachments.size(); i++) {
137*c8dee2aaSAndroid Build Coastguard Worker         add_attachment_description_info_to_key(
138*c8dee2aaSAndroid Build Coastguard Worker                 builder,
139*c8dee2aaSAndroid Build Coastguard Worker                 rpMetaData.fAttachments[i]->fTextureInfo,
140*c8dee2aaSAndroid Build Coastguard Worker                 builderIdx,
141*c8dee2aaSAndroid Build Coastguard Worker                 // Assign LoadOp::kLoad and StoreOp::kStore as default load/store operations for
142*c8dee2aaSAndroid Build Coastguard Worker                 // compatible render passes where load/store ops don't need to match.
143*c8dee2aaSAndroid Build Coastguard Worker                 compatibleOnly ? LoadOp::kLoad   : rpMetaData.fAttachments[i]->fLoadOp,
144*c8dee2aaSAndroid Build Coastguard Worker                 compatibleOnly ? StoreOp::kStore : rpMetaData.fAttachments[i]->fStoreOp);
145*c8dee2aaSAndroid Build Coastguard Worker     }
146*c8dee2aaSAndroid Build Coastguard Worker 
147*c8dee2aaSAndroid Build Coastguard Worker     add_subpass_info_to_key(builder,
148*c8dee2aaSAndroid Build Coastguard Worker                             builderIdx,
149*c8dee2aaSAndroid Build Coastguard Worker                             rpMetaData.fHasColorAttachment,
150*c8dee2aaSAndroid Build Coastguard Worker                             rpMetaData.fHasColorResolveAttachment,
151*c8dee2aaSAndroid Build Coastguard Worker                             rpMetaData.fHasDepthStencilAttachment,
152*c8dee2aaSAndroid Build Coastguard Worker                             rpMetaData.fLoadMSAAFromResolve,
153*c8dee2aaSAndroid Build Coastguard Worker                             rpMetaData.fSubpassCount,
154*c8dee2aaSAndroid Build Coastguard Worker                             rpMetaData.fSubpassDependencyCount);
155*c8dee2aaSAndroid Build Coastguard Worker }
156*c8dee2aaSAndroid Build Coastguard Worker 
157*c8dee2aaSAndroid Build Coastguard Worker } // anonymous namespace
158*c8dee2aaSAndroid Build Coastguard Worker 
VulkanRenderPassMetaData(const RenderPassDesc & renderPassDesc)159*c8dee2aaSAndroid Build Coastguard Worker VulkanRenderPass::VulkanRenderPassMetaData::VulkanRenderPassMetaData(
160*c8dee2aaSAndroid Build Coastguard Worker         const RenderPassDesc& renderPassDesc) {
161*c8dee2aaSAndroid Build Coastguard Worker     fLoadMSAAFromResolve = renderPassDesc.fColorResolveAttachment.fTextureInfo.isValid() &&
162*c8dee2aaSAndroid Build Coastguard Worker                            renderPassDesc.fColorResolveAttachment.fLoadOp == LoadOp::kLoad;
163*c8dee2aaSAndroid Build Coastguard Worker     fHasColorAttachment        = renderPassDesc.fColorAttachment.fTextureInfo.isValid();
164*c8dee2aaSAndroid Build Coastguard Worker     fHasColorResolveAttachment =
165*c8dee2aaSAndroid Build Coastguard Worker             renderPassDesc.fColorResolveAttachment.fTextureInfo.isValid();
166*c8dee2aaSAndroid Build Coastguard Worker     fHasDepthStencilAttachment =
167*c8dee2aaSAndroid Build Coastguard Worker             renderPassDesc.fDepthStencilAttachment.fTextureInfo.isValid();
168*c8dee2aaSAndroid Build Coastguard Worker 
169*c8dee2aaSAndroid Build Coastguard Worker     // TODO: Query for more attachments once the RenderPassDesc struct contains that information.
170*c8dee2aaSAndroid Build Coastguard Worker     // For now, we only ever expect to see 0 or 1 of each attachment type (color, resolve, and
171*c8dee2aaSAndroid Build Coastguard Worker     // depth/stencil), so the count of each of those can simply be determined with a bool.
172*c8dee2aaSAndroid Build Coastguard Worker     fNumColorAttachments        = fHasColorAttachment ? 1 : 0;
173*c8dee2aaSAndroid Build Coastguard Worker     fNumResolveAttachments      = fHasColorResolveAttachment ? 1 : 0;
174*c8dee2aaSAndroid Build Coastguard Worker     fNumDepthStencilAttachments = fHasDepthStencilAttachment ? 1 : 0;
175*c8dee2aaSAndroid Build Coastguard Worker 
176*c8dee2aaSAndroid Build Coastguard Worker     // Accumulate attachments into a container to mimic future structure in RenderPassDesc
177*c8dee2aaSAndroid Build Coastguard Worker     fAttachments = skia_private::TArray<const AttachmentDesc*>(fNumColorAttachments   +
178*c8dee2aaSAndroid Build Coastguard Worker                                                                fNumResolveAttachments +
179*c8dee2aaSAndroid Build Coastguard Worker                                                                fNumDepthStencilAttachments);
180*c8dee2aaSAndroid Build Coastguard Worker     if (fHasColorAttachment) {
181*c8dee2aaSAndroid Build Coastguard Worker         fAttachments.push_back(&renderPassDesc.fColorAttachment);
182*c8dee2aaSAndroid Build Coastguard Worker     }
183*c8dee2aaSAndroid Build Coastguard Worker     if (fHasColorResolveAttachment) {
184*c8dee2aaSAndroid Build Coastguard Worker         fAttachments.push_back(&renderPassDesc.fColorResolveAttachment);
185*c8dee2aaSAndroid Build Coastguard Worker     }
186*c8dee2aaSAndroid Build Coastguard Worker     if (fHasDepthStencilAttachment) {
187*c8dee2aaSAndroid Build Coastguard Worker         fAttachments.push_back(&renderPassDesc.fDepthStencilAttachment);
188*c8dee2aaSAndroid Build Coastguard Worker     }
189*c8dee2aaSAndroid Build Coastguard Worker 
190*c8dee2aaSAndroid Build Coastguard Worker     // TODO: Reference RenderPassDesc to determine number and makeup of subpasses and their
191*c8dee2aaSAndroid Build Coastguard Worker     // dependencies. For now, we only ever expect 1 (in most cases) or 2 (when loading MSAA).
192*c8dee2aaSAndroid Build Coastguard Worker     fSubpassCount = fLoadMSAAFromResolve ? 2 : 1;
193*c8dee2aaSAndroid Build Coastguard Worker     fSubpassDependencyCount = fLoadMSAAFromResolve ? 1 : 0;
194*c8dee2aaSAndroid Build Coastguard Worker     fUint32DataCnt = determine_uint32_count(
195*c8dee2aaSAndroid Build Coastguard Worker             fAttachments.size(), fSubpassCount,  fSubpassDependencyCount);
196*c8dee2aaSAndroid Build Coastguard Worker }
197*c8dee2aaSAndroid Build Coastguard Worker 
MakeRenderPassKey(const RenderPassDesc & renderPassDesc,bool compatibleOnly)198*c8dee2aaSAndroid Build Coastguard Worker GraphiteResourceKey VulkanRenderPass::MakeRenderPassKey(
199*c8dee2aaSAndroid Build Coastguard Worker         const RenderPassDesc& renderPassDesc, bool compatibleOnly) {
200*c8dee2aaSAndroid Build Coastguard Worker 
201*c8dee2aaSAndroid Build Coastguard Worker     VulkanRenderPassMetaData rpMetaData = VulkanRenderPassMetaData(renderPassDesc);
202*c8dee2aaSAndroid Build Coastguard Worker 
203*c8dee2aaSAndroid Build Coastguard Worker     static const ResourceType kType = GraphiteResourceKey::GenerateResourceType();
204*c8dee2aaSAndroid Build Coastguard Worker     GraphiteResourceKey key;
205*c8dee2aaSAndroid Build Coastguard Worker     GraphiteResourceKey::Builder builder(&key, kType, rpMetaData.fUint32DataCnt, Shareable::kYes);
206*c8dee2aaSAndroid Build Coastguard Worker 
207*c8dee2aaSAndroid Build Coastguard Worker     int startingIdx = 0;
208*c8dee2aaSAndroid Build Coastguard Worker     populate_key(rpMetaData, builder, startingIdx, compatibleOnly);
209*c8dee2aaSAndroid Build Coastguard Worker 
210*c8dee2aaSAndroid Build Coastguard Worker     builder.finish();
211*c8dee2aaSAndroid Build Coastguard Worker     return key;
212*c8dee2aaSAndroid Build Coastguard Worker }
213*c8dee2aaSAndroid Build Coastguard Worker 
AddRenderPassInfoToKey(VulkanRenderPassMetaData & rpMetaData,ResourceKey::Builder & builder,int & builderIdx,bool compatibleOnly)214*c8dee2aaSAndroid Build Coastguard Worker void VulkanRenderPass::AddRenderPassInfoToKey(VulkanRenderPassMetaData& rpMetaData,
215*c8dee2aaSAndroid Build Coastguard Worker                                               ResourceKey::Builder& builder,
216*c8dee2aaSAndroid Build Coastguard Worker                                               int& builderIdx,
217*c8dee2aaSAndroid Build Coastguard Worker                                               bool compatibleOnly) {
218*c8dee2aaSAndroid Build Coastguard Worker     populate_key(rpMetaData, builder, builderIdx, /*compatibleOnly=*/true);
219*c8dee2aaSAndroid Build Coastguard Worker }
220*c8dee2aaSAndroid Build Coastguard Worker 
221*c8dee2aaSAndroid Build Coastguard Worker namespace { // anonymous namespace
setup_vk_attachment_description(VkAttachmentDescription * outAttachment,const VulkanTextureInfo & textureInfo,const AttachmentDesc & desc,const LoadOp loadOp,const StoreOp storeOp,const VkImageLayout initialLayout,const VkImageLayout finalLayout)222*c8dee2aaSAndroid Build Coastguard Worker void setup_vk_attachment_description(VkAttachmentDescription* outAttachment,
223*c8dee2aaSAndroid Build Coastguard Worker                                      const VulkanTextureInfo& textureInfo,
224*c8dee2aaSAndroid Build Coastguard Worker                                      const AttachmentDesc& desc,
225*c8dee2aaSAndroid Build Coastguard Worker                                      const LoadOp loadOp,
226*c8dee2aaSAndroid Build Coastguard Worker                                      const StoreOp storeOp,
227*c8dee2aaSAndroid Build Coastguard Worker                                      const VkImageLayout initialLayout,
228*c8dee2aaSAndroid Build Coastguard Worker                                      const VkImageLayout finalLayout) {
229*c8dee2aaSAndroid Build Coastguard Worker     static_assert((int)LoadOp::kLoad == 0);
230*c8dee2aaSAndroid Build Coastguard Worker     static_assert((int)LoadOp::kClear == 1);
231*c8dee2aaSAndroid Build Coastguard Worker     static_assert((int)LoadOp::kDiscard == 2);
232*c8dee2aaSAndroid Build Coastguard Worker     static_assert(std::size(vkLoadOp) == kLoadOpCount);
233*c8dee2aaSAndroid Build Coastguard Worker     static_assert((int)StoreOp::kStore == 0);
234*c8dee2aaSAndroid Build Coastguard Worker     static_assert((int)StoreOp::kDiscard == 1);
235*c8dee2aaSAndroid Build Coastguard Worker     static_assert(std::size(vkStoreOp) == kStoreOpCount);
236*c8dee2aaSAndroid Build Coastguard Worker 
237*c8dee2aaSAndroid Build Coastguard Worker     outAttachment->flags = 0;
238*c8dee2aaSAndroid Build Coastguard Worker     outAttachment->format = textureInfo.fFormat;
239*c8dee2aaSAndroid Build Coastguard Worker     VkSampleCountFlagBits sampleCount;
240*c8dee2aaSAndroid Build Coastguard Worker     SkAssertResult(
241*c8dee2aaSAndroid Build Coastguard Worker             skgpu::SampleCountToVkSampleCount(textureInfo.fSampleCount, &sampleCount));
242*c8dee2aaSAndroid Build Coastguard Worker     outAttachment->samples = sampleCount;
243*c8dee2aaSAndroid Build Coastguard Worker     switch (initialLayout) {
244*c8dee2aaSAndroid Build Coastguard Worker         case VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL:
245*c8dee2aaSAndroid Build Coastguard Worker         case VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL:
246*c8dee2aaSAndroid Build Coastguard Worker         case VK_IMAGE_LAYOUT_GENERAL:
247*c8dee2aaSAndroid Build Coastguard Worker             outAttachment->loadOp = vkLoadOp[static_cast<int>(loadOp)];
248*c8dee2aaSAndroid Build Coastguard Worker             outAttachment->storeOp = vkStoreOp[static_cast<int>(storeOp)];
249*c8dee2aaSAndroid Build Coastguard Worker             outAttachment->stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
250*c8dee2aaSAndroid Build Coastguard Worker             outAttachment->stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
251*c8dee2aaSAndroid Build Coastguard Worker             break;
252*c8dee2aaSAndroid Build Coastguard Worker         case VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL:
253*c8dee2aaSAndroid Build Coastguard Worker             // The loadOp and storeOp refer to the depth part of the attachment and the stencil*Ops
254*c8dee2aaSAndroid Build Coastguard Worker             // refer to the stencil bits in the attachment.
255*c8dee2aaSAndroid Build Coastguard Worker             outAttachment->loadOp = vkLoadOp[static_cast<int>(loadOp)];
256*c8dee2aaSAndroid Build Coastguard Worker             outAttachment->storeOp = vkStoreOp[static_cast<int>(storeOp)];
257*c8dee2aaSAndroid Build Coastguard Worker             outAttachment->stencilLoadOp = vkLoadOp[static_cast<int>(loadOp)];
258*c8dee2aaSAndroid Build Coastguard Worker             outAttachment->stencilStoreOp = vkStoreOp[static_cast<int>(storeOp)];
259*c8dee2aaSAndroid Build Coastguard Worker             break;
260*c8dee2aaSAndroid Build Coastguard Worker         default:
261*c8dee2aaSAndroid Build Coastguard Worker             SK_ABORT("Unexpected attachment layout");
262*c8dee2aaSAndroid Build Coastguard Worker     }
263*c8dee2aaSAndroid Build Coastguard Worker     outAttachment->initialLayout = initialLayout;
264*c8dee2aaSAndroid Build Coastguard Worker     outAttachment->finalLayout = finalLayout == VK_IMAGE_LAYOUT_UNDEFINED ? initialLayout
265*c8dee2aaSAndroid Build Coastguard Worker                                                                           : finalLayout;
266*c8dee2aaSAndroid Build Coastguard Worker }
267*c8dee2aaSAndroid Build Coastguard Worker } // anonymous namespace
268*c8dee2aaSAndroid Build Coastguard Worker 
MakeRenderPass(const VulkanSharedContext * context,const RenderPassDesc & renderPassDesc,bool compatibleOnly)269*c8dee2aaSAndroid Build Coastguard Worker sk_sp<VulkanRenderPass> VulkanRenderPass::MakeRenderPass(const VulkanSharedContext* context,
270*c8dee2aaSAndroid Build Coastguard Worker                                                          const RenderPassDesc& renderPassDesc,
271*c8dee2aaSAndroid Build Coastguard Worker                                                          bool compatibleOnly) {
272*c8dee2aaSAndroid Build Coastguard Worker     VkRenderPass renderPass;
273*c8dee2aaSAndroid Build Coastguard Worker     renderPass = VK_NULL_HANDLE;
274*c8dee2aaSAndroid Build Coastguard Worker     auto& colorAttachmentTextureInfo        = renderPassDesc.fColorAttachment.fTextureInfo;
275*c8dee2aaSAndroid Build Coastguard Worker     auto& colorResolveAttachmentTextureInfo = renderPassDesc.fColorResolveAttachment.fTextureInfo;
276*c8dee2aaSAndroid Build Coastguard Worker     auto& depthStencilAttachmentTextureInfo = renderPassDesc.fDepthStencilAttachment.fTextureInfo;
277*c8dee2aaSAndroid Build Coastguard Worker     bool hasColorAttachment        = colorAttachmentTextureInfo.isValid();
278*c8dee2aaSAndroid Build Coastguard Worker     bool hasColorResolveAttachment = colorResolveAttachmentTextureInfo.isValid();
279*c8dee2aaSAndroid Build Coastguard Worker     bool hasDepthStencilAttachment = depthStencilAttachmentTextureInfo.isValid();
280*c8dee2aaSAndroid Build Coastguard Worker 
281*c8dee2aaSAndroid Build Coastguard Worker     skia_private::TArray<VkAttachmentDescription> attachmentDescs;
282*c8dee2aaSAndroid Build Coastguard Worker     // Create and track attachment references for the subpass.
283*c8dee2aaSAndroid Build Coastguard Worker     VkAttachmentReference colorRef;
284*c8dee2aaSAndroid Build Coastguard Worker     VkAttachmentReference resolveRef;
285*c8dee2aaSAndroid Build Coastguard Worker     VkAttachmentReference resolveLoadInputRef;
286*c8dee2aaSAndroid Build Coastguard Worker     VkAttachmentReference depthStencilRef;
287*c8dee2aaSAndroid Build Coastguard Worker 
288*c8dee2aaSAndroid Build Coastguard Worker     bool loadMSAAFromResolve = false;
289*c8dee2aaSAndroid Build Coastguard Worker     if (hasColorAttachment) {
290*c8dee2aaSAndroid Build Coastguard Worker         VulkanTextureInfo colorAttachTexInfo;
291*c8dee2aaSAndroid Build Coastguard Worker         SkAssertResult(TextureInfos::GetVulkanTextureInfo(colorAttachmentTextureInfo,
292*c8dee2aaSAndroid Build Coastguard Worker                                                           &colorAttachTexInfo));
293*c8dee2aaSAndroid Build Coastguard Worker         auto& colorAttachDesc = renderPassDesc.fColorAttachment;
294*c8dee2aaSAndroid Build Coastguard Worker 
295*c8dee2aaSAndroid Build Coastguard Worker         colorRef.attachment = attachmentDescs.size();
296*c8dee2aaSAndroid Build Coastguard Worker         VkAttachmentDescription& vkColorAttachDesc = attachmentDescs.push_back();
297*c8dee2aaSAndroid Build Coastguard Worker         memset(&vkColorAttachDesc, 0, sizeof(VkAttachmentDescription));
298*c8dee2aaSAndroid Build Coastguard Worker         setup_vk_attachment_description(
299*c8dee2aaSAndroid Build Coastguard Worker                 &vkColorAttachDesc,
300*c8dee2aaSAndroid Build Coastguard Worker                 colorAttachTexInfo,
301*c8dee2aaSAndroid Build Coastguard Worker                 colorAttachDesc,
302*c8dee2aaSAndroid Build Coastguard Worker                 compatibleOnly ? LoadOp::kDiscard  : colorAttachDesc.fLoadOp,
303*c8dee2aaSAndroid Build Coastguard Worker                 compatibleOnly ? StoreOp::kDiscard : colorAttachDesc.fStoreOp,
304*c8dee2aaSAndroid Build Coastguard Worker                 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
305*c8dee2aaSAndroid Build Coastguard Worker                 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL);
306*c8dee2aaSAndroid Build Coastguard Worker         colorRef.layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
307*c8dee2aaSAndroid Build Coastguard Worker 
308*c8dee2aaSAndroid Build Coastguard Worker         if (hasColorResolveAttachment) {
309*c8dee2aaSAndroid Build Coastguard Worker             loadMSAAFromResolve = renderPassDesc.fColorResolveAttachment.fLoadOp == LoadOp::kLoad;
310*c8dee2aaSAndroid Build Coastguard Worker             SkASSERT(renderPassDesc.fColorResolveAttachment.fStoreOp == StoreOp::kStore);
311*c8dee2aaSAndroid Build Coastguard Worker             VulkanTextureInfo resolveAttachTexInfo;
312*c8dee2aaSAndroid Build Coastguard Worker             SkAssertResult(TextureInfos::GetVulkanTextureInfo(colorResolveAttachmentTextureInfo,
313*c8dee2aaSAndroid Build Coastguard Worker                                                               &resolveAttachTexInfo));
314*c8dee2aaSAndroid Build Coastguard Worker             auto& resolveAttachDesc = renderPassDesc.fColorResolveAttachment;
315*c8dee2aaSAndroid Build Coastguard Worker 
316*c8dee2aaSAndroid Build Coastguard Worker             resolveRef.attachment = attachmentDescs.size();
317*c8dee2aaSAndroid Build Coastguard Worker             VkAttachmentDescription& vkResolveAttachDesc = attachmentDescs.push_back();
318*c8dee2aaSAndroid Build Coastguard Worker             memset(&vkResolveAttachDesc, 0, sizeof(VkAttachmentDescription));
319*c8dee2aaSAndroid Build Coastguard Worker             setup_vk_attachment_description(
320*c8dee2aaSAndroid Build Coastguard Worker                     &vkResolveAttachDesc,
321*c8dee2aaSAndroid Build Coastguard Worker                     resolveAttachTexInfo,
322*c8dee2aaSAndroid Build Coastguard Worker                     resolveAttachDesc,
323*c8dee2aaSAndroid Build Coastguard Worker                     compatibleOnly ? LoadOp::kDiscard  : resolveAttachDesc.fLoadOp,
324*c8dee2aaSAndroid Build Coastguard Worker                     compatibleOnly ? StoreOp::kDiscard : resolveAttachDesc.fStoreOp,
325*c8dee2aaSAndroid Build Coastguard Worker                     loadMSAAFromResolve ? VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL
326*c8dee2aaSAndroid Build Coastguard Worker                                         : VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
327*c8dee2aaSAndroid Build Coastguard Worker                     VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL);
328*c8dee2aaSAndroid Build Coastguard Worker             resolveRef.layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
329*c8dee2aaSAndroid Build Coastguard Worker         } else {
330*c8dee2aaSAndroid Build Coastguard Worker             resolveRef.attachment = VK_ATTACHMENT_UNUSED;
331*c8dee2aaSAndroid Build Coastguard Worker             resolveRef.layout = VK_IMAGE_LAYOUT_UNDEFINED;
332*c8dee2aaSAndroid Build Coastguard Worker         }
333*c8dee2aaSAndroid Build Coastguard Worker     } else {
334*c8dee2aaSAndroid Build Coastguard Worker         SkASSERT(false);
335*c8dee2aaSAndroid Build Coastguard Worker         colorRef.attachment = VK_ATTACHMENT_UNUSED;
336*c8dee2aaSAndroid Build Coastguard Worker         colorRef.layout = VK_IMAGE_LAYOUT_UNDEFINED;
337*c8dee2aaSAndroid Build Coastguard Worker         resolveRef.attachment = VK_ATTACHMENT_UNUSED;
338*c8dee2aaSAndroid Build Coastguard Worker         resolveRef.layout = VK_IMAGE_LAYOUT_UNDEFINED;
339*c8dee2aaSAndroid Build Coastguard Worker     }
340*c8dee2aaSAndroid Build Coastguard Worker 
341*c8dee2aaSAndroid Build Coastguard Worker     if (hasDepthStencilAttachment) {
342*c8dee2aaSAndroid Build Coastguard Worker         VulkanTextureInfo depthStencilTexInfo;
343*c8dee2aaSAndroid Build Coastguard Worker         SkAssertResult(TextureInfos::GetVulkanTextureInfo(depthStencilAttachmentTextureInfo,
344*c8dee2aaSAndroid Build Coastguard Worker                                                           &depthStencilTexInfo));
345*c8dee2aaSAndroid Build Coastguard Worker         auto& depthStencilAttachDesc = renderPassDesc.fDepthStencilAttachment;
346*c8dee2aaSAndroid Build Coastguard Worker 
347*c8dee2aaSAndroid Build Coastguard Worker         depthStencilRef.attachment = attachmentDescs.size();
348*c8dee2aaSAndroid Build Coastguard Worker         VkAttachmentDescription& vkDepthStencilAttachDesc = attachmentDescs.push_back();
349*c8dee2aaSAndroid Build Coastguard Worker         setup_vk_attachment_description(
350*c8dee2aaSAndroid Build Coastguard Worker                 &vkDepthStencilAttachDesc,
351*c8dee2aaSAndroid Build Coastguard Worker                 depthStencilTexInfo,
352*c8dee2aaSAndroid Build Coastguard Worker                 depthStencilAttachDesc,
353*c8dee2aaSAndroid Build Coastguard Worker                 compatibleOnly ? LoadOp::kDiscard   : depthStencilAttachDesc.fLoadOp,
354*c8dee2aaSAndroid Build Coastguard Worker                 compatibleOnly ? StoreOp::kDiscard  : depthStencilAttachDesc.fStoreOp,
355*c8dee2aaSAndroid Build Coastguard Worker                 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
356*c8dee2aaSAndroid Build Coastguard Worker                 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL);
357*c8dee2aaSAndroid Build Coastguard Worker         depthStencilRef.layout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
358*c8dee2aaSAndroid Build Coastguard Worker     } else {
359*c8dee2aaSAndroid Build Coastguard Worker         depthStencilRef.attachment = VK_ATTACHMENT_UNUSED;
360*c8dee2aaSAndroid Build Coastguard Worker         depthStencilRef.layout = VK_IMAGE_LAYOUT_UNDEFINED;
361*c8dee2aaSAndroid Build Coastguard Worker     }
362*c8dee2aaSAndroid Build Coastguard Worker 
363*c8dee2aaSAndroid Build Coastguard Worker     // Create VkRenderPass
364*c8dee2aaSAndroid Build Coastguard Worker     VkRenderPassCreateInfo renderPassInfo;
365*c8dee2aaSAndroid Build Coastguard Worker     memset(&renderPassInfo, 0, sizeof(VkRenderPassCreateInfo));
366*c8dee2aaSAndroid Build Coastguard Worker     renderPassInfo.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO;
367*c8dee2aaSAndroid Build Coastguard Worker     renderPassInfo.pNext = nullptr;
368*c8dee2aaSAndroid Build Coastguard Worker     renderPassInfo.flags = 0;
369*c8dee2aaSAndroid Build Coastguard Worker     renderPassInfo.subpassCount = loadMSAAFromResolve ? 2 : 1;
370*c8dee2aaSAndroid Build Coastguard Worker 
371*c8dee2aaSAndroid Build Coastguard Worker     skia_private::TArray<VkSubpassDescription> subpassDescs(renderPassInfo.subpassCount);
372*c8dee2aaSAndroid Build Coastguard Worker     memset(subpassDescs.begin(), 0, renderPassInfo.subpassCount * sizeof(VkSubpassDescription));
373*c8dee2aaSAndroid Build Coastguard Worker 
374*c8dee2aaSAndroid Build Coastguard Worker     // If we are loading MSAA from resolve, that subpass must always be first.
375*c8dee2aaSAndroid Build Coastguard Worker     VkSubpassDependency dependency;
376*c8dee2aaSAndroid Build Coastguard Worker     if (loadMSAAFromResolve) {
377*c8dee2aaSAndroid Build Coastguard Worker         resolveLoadInputRef.attachment = resolveRef.attachment;
378*c8dee2aaSAndroid Build Coastguard Worker         resolveLoadInputRef.layout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
379*c8dee2aaSAndroid Build Coastguard Worker 
380*c8dee2aaSAndroid Build Coastguard Worker         VkSubpassDescription& loadSubpassDesc = subpassDescs.push_back();
381*c8dee2aaSAndroid Build Coastguard Worker         memset(&loadSubpassDesc, 0, sizeof(VkSubpassDescription));
382*c8dee2aaSAndroid Build Coastguard Worker         loadSubpassDesc.flags = 0;
383*c8dee2aaSAndroid Build Coastguard Worker         loadSubpassDesc.pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS;
384*c8dee2aaSAndroid Build Coastguard Worker         loadSubpassDesc.inputAttachmentCount = 1;
385*c8dee2aaSAndroid Build Coastguard Worker         loadSubpassDesc.pInputAttachments = &resolveLoadInputRef;
386*c8dee2aaSAndroid Build Coastguard Worker         loadSubpassDesc.colorAttachmentCount = 1;
387*c8dee2aaSAndroid Build Coastguard Worker         loadSubpassDesc.pColorAttachments = &colorRef;
388*c8dee2aaSAndroid Build Coastguard Worker         loadSubpassDesc.pResolveAttachments = nullptr;
389*c8dee2aaSAndroid Build Coastguard Worker         loadSubpassDesc.pDepthStencilAttachment = nullptr;
390*c8dee2aaSAndroid Build Coastguard Worker         loadSubpassDesc.preserveAttachmentCount = 0;
391*c8dee2aaSAndroid Build Coastguard Worker         loadSubpassDesc.pPreserveAttachments = nullptr;
392*c8dee2aaSAndroid Build Coastguard Worker 
393*c8dee2aaSAndroid Build Coastguard Worker         // Set up the subpass dependency
394*c8dee2aaSAndroid Build Coastguard Worker         const int mainSubpassIdx = loadMSAAFromResolve ? 1 : 0;
395*c8dee2aaSAndroid Build Coastguard Worker         dependency.srcSubpass = 0;
396*c8dee2aaSAndroid Build Coastguard Worker         dependency.dstSubpass = mainSubpassIdx;
397*c8dee2aaSAndroid Build Coastguard Worker         dependency.dependencyFlags = VK_DEPENDENCY_BY_REGION_BIT;
398*c8dee2aaSAndroid Build Coastguard Worker         dependency.srcStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
399*c8dee2aaSAndroid Build Coastguard Worker         dependency.srcAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
400*c8dee2aaSAndroid Build Coastguard Worker         dependency.dstStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
401*c8dee2aaSAndroid Build Coastguard Worker         dependency.dstAccessMask =
402*c8dee2aaSAndroid Build Coastguard Worker                 VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
403*c8dee2aaSAndroid Build Coastguard Worker     }
404*c8dee2aaSAndroid Build Coastguard Worker 
405*c8dee2aaSAndroid Build Coastguard Worker     VkSubpassDescription& mainSubpassDesc = subpassDescs.push_back();
406*c8dee2aaSAndroid Build Coastguard Worker     memset(&mainSubpassDesc, 0, sizeof(VkSubpassDescription));
407*c8dee2aaSAndroid Build Coastguard Worker     mainSubpassDesc.flags = 0;
408*c8dee2aaSAndroid Build Coastguard Worker     mainSubpassDesc.pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS;
409*c8dee2aaSAndroid Build Coastguard Worker     mainSubpassDesc.inputAttachmentCount = 0; // TODO: Add input attachment support in main subpass
410*c8dee2aaSAndroid Build Coastguard Worker     mainSubpassDesc.pInputAttachments = nullptr;
411*c8dee2aaSAndroid Build Coastguard Worker     mainSubpassDesc.colorAttachmentCount = 1;
412*c8dee2aaSAndroid Build Coastguard Worker     mainSubpassDesc.pColorAttachments = &colorRef;
413*c8dee2aaSAndroid Build Coastguard Worker     mainSubpassDesc.pResolveAttachments = &resolveRef;
414*c8dee2aaSAndroid Build Coastguard Worker     mainSubpassDesc.pDepthStencilAttachment = &depthStencilRef;
415*c8dee2aaSAndroid Build Coastguard Worker     mainSubpassDesc.preserveAttachmentCount = 0;
416*c8dee2aaSAndroid Build Coastguard Worker     mainSubpassDesc.pPreserveAttachments = nullptr;
417*c8dee2aaSAndroid Build Coastguard Worker 
418*c8dee2aaSAndroid Build Coastguard Worker     renderPassInfo.pSubpasses = subpassDescs.begin();
419*c8dee2aaSAndroid Build Coastguard Worker     renderPassInfo.dependencyCount = loadMSAAFromResolve ? 1 : 0;
420*c8dee2aaSAndroid Build Coastguard Worker     renderPassInfo.pDependencies = loadMSAAFromResolve ? &dependency : VK_NULL_HANDLE;
421*c8dee2aaSAndroid Build Coastguard Worker     renderPassInfo.attachmentCount = attachmentDescs.size();
422*c8dee2aaSAndroid Build Coastguard Worker     renderPassInfo.pAttachments = attachmentDescs.begin();
423*c8dee2aaSAndroid Build Coastguard Worker 
424*c8dee2aaSAndroid Build Coastguard Worker     VkResult result;
425*c8dee2aaSAndroid Build Coastguard Worker     VULKAN_CALL_RESULT(context,
426*c8dee2aaSAndroid Build Coastguard Worker                        result,
427*c8dee2aaSAndroid Build Coastguard Worker                        CreateRenderPass(context->device(), &renderPassInfo, nullptr, &renderPass));
428*c8dee2aaSAndroid Build Coastguard Worker     if (result != VK_SUCCESS) {
429*c8dee2aaSAndroid Build Coastguard Worker         return nullptr;
430*c8dee2aaSAndroid Build Coastguard Worker     }
431*c8dee2aaSAndroid Build Coastguard Worker     VkExtent2D granularity;
432*c8dee2aaSAndroid Build Coastguard Worker     VULKAN_CALL(context->interface(), GetRenderAreaGranularity(context->device(),
433*c8dee2aaSAndroid Build Coastguard Worker                                                                renderPass,
434*c8dee2aaSAndroid Build Coastguard Worker                                                                &granularity));
435*c8dee2aaSAndroid Build Coastguard Worker     return sk_sp<VulkanRenderPass>(new VulkanRenderPass(context, renderPass, granularity));
436*c8dee2aaSAndroid Build Coastguard Worker }
437*c8dee2aaSAndroid Build Coastguard Worker 
VulkanRenderPass(const VulkanSharedContext * context,VkRenderPass renderPass,VkExtent2D granularity)438*c8dee2aaSAndroid Build Coastguard Worker VulkanRenderPass::VulkanRenderPass(const VulkanSharedContext* context,
439*c8dee2aaSAndroid Build Coastguard Worker                                    VkRenderPass renderPass,
440*c8dee2aaSAndroid Build Coastguard Worker                                    VkExtent2D granularity)
441*c8dee2aaSAndroid Build Coastguard Worker         : Resource(context,
442*c8dee2aaSAndroid Build Coastguard Worker                    Ownership::kOwned,
443*c8dee2aaSAndroid Build Coastguard Worker                    skgpu::Budgeted::kYes,
444*c8dee2aaSAndroid Build Coastguard Worker                    /*gpuMemorySize=*/0)
445*c8dee2aaSAndroid Build Coastguard Worker         , fSharedContext(context)
446*c8dee2aaSAndroid Build Coastguard Worker         , fRenderPass(renderPass)
447*c8dee2aaSAndroid Build Coastguard Worker         , fGranularity(granularity) {}
448*c8dee2aaSAndroid Build Coastguard Worker 
freeGpuData()449*c8dee2aaSAndroid Build Coastguard Worker void VulkanRenderPass::freeGpuData() {
450*c8dee2aaSAndroid Build Coastguard Worker     VULKAN_CALL(fSharedContext->interface(),
451*c8dee2aaSAndroid Build Coastguard Worker                 DestroyRenderPass(fSharedContext->device(), fRenderPass, nullptr));
452*c8dee2aaSAndroid Build Coastguard Worker }
453*c8dee2aaSAndroid Build Coastguard Worker 
454*c8dee2aaSAndroid Build Coastguard Worker } // namespace skgpu::graphite
455