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