xref: /aosp_15_r20/external/skia/src/gpu/ganesh/vk/GrVkRenderPass.h (revision c8dee2aa9b3f27cf6c858bd81872bdeb2c07ed17)
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 #ifndef GrVkRenderPass_DEFINED
9 #define GrVkRenderPass_DEFINED
10 
11 #include "include/private/base/SkDebug.h"
12 #include "include/private/base/SkMacros.h"
13 #include "include/private/gpu/vk/SkiaVulkan.h"
14 #include "src/gpu/ganesh/GrManagedResource.h"
15 #include "src/gpu/ganesh/vk/GrVkManagedResource.h"
16 
17 #include <cinttypes>
18 #include <cstdint>
19 
20 class GrVkGpu;
21 class GrVkRenderTarget;
22 namespace skgpu {
23 class KeyBuilder;
24 }
25 
26 class GrVkRenderPass : public GrVkManagedResource {
27 public:
28     struct LoadStoreOps {
29         VkAttachmentLoadOp  fLoadOp;
30         VkAttachmentStoreOp fStoreOp;
31 
LoadStoreOpsLoadStoreOps32         LoadStoreOps(VkAttachmentLoadOp loadOp, VkAttachmentStoreOp storeOp)
33             : fLoadOp(loadOp)
34             , fStoreOp(storeOp) {}
35 
36         bool operator==(const LoadStoreOps& right) const {
37             return fLoadOp == right.fLoadOp && fStoreOp == right.fStoreOp;
38         }
39 
40         bool operator!=(const LoadStoreOps& right) const {
41             return !(*this == right);
42         }
43     };
44 
45     // Used when importing an external render pass. In this case we have to explicitly be told the
46     // color attachment index
GrVkRenderPass(const GrVkGpu * gpu,VkRenderPass renderPass,uint32_t colorAttachmentIndex)47     explicit GrVkRenderPass(const GrVkGpu* gpu, VkRenderPass renderPass,
48                             uint32_t colorAttachmentIndex)
49             : INHERITED(gpu)
50             , fRenderPass(renderPass)
51             , fAttachmentFlags(kExternal_AttachmentFlag)
52             , fSelfDepFlags(SelfDependencyFlags::kNone)
53             , fLoadFromResolve(LoadFromResolve::kNo)
54             , fClearValueCount(0)
55             , fColorAttachmentIndex(colorAttachmentIndex) {}
56 
57     struct AttachmentsDescriptor {
58         struct AttachmentDesc {
59             VkFormat fFormat;
60             int fSamples;
61             LoadStoreOps fLoadStoreOps;
62 
AttachmentDescAttachmentsDescriptor::AttachmentDesc63             AttachmentDesc()
64                 : fFormat(VK_FORMAT_UNDEFINED)
65                 , fSamples(0)
66                 , fLoadStoreOps(VK_ATTACHMENT_LOAD_OP_LOAD, VK_ATTACHMENT_STORE_OP_STORE) {}
67             bool operator==(const AttachmentDesc& right) const {
68                 return (fFormat == right.fFormat &&
69                         fSamples == right.fSamples &&
70                         fLoadStoreOps == right.fLoadStoreOps);
71             }
72             bool operator!=(const AttachmentDesc& right) const {
73                 return !(*this == right);
74             }
isCompatibleAttachmentsDescriptor::AttachmentDesc75             bool isCompatible(const AttachmentDesc& desc) const {
76                 return (fFormat == desc.fFormat && fSamples == desc.fSamples);
77             }
78         };
79         AttachmentDesc fColor;
80         AttachmentDesc fResolve;
81         AttachmentDesc fStencil;
82         uint32_t       fAttachmentCount;
83     };
84 
85     enum AttachmentFlags : uint32_t {
86         kColor_AttachmentFlag = 0x1,
87         kStencil_AttachmentFlag = 0x2,
88         kResolve_AttachmentFlag = 0x4,
89         // The external attachment flag signals that this render pass is imported from an external
90         // client. Since we don't know every attachment on the render pass we don't set any of the
91         // specific attachment flags when using external. However, the external render pass must
92         // at least have a color attachment.
93         kExternal_AttachmentFlag = 0x8,
94     };
95     SK_DECL_BITFIELD_OPS_FRIENDS(AttachmentFlags)
96 
97     enum class SelfDependencyFlags {
98         kNone =                   0,
99         kForInputAttachment =     1 << 0,
100         kForNonCoherentAdvBlend = 1 << 1,
101     };
102     SK_DECL_BITFIELD_CLASS_OPS_FRIENDS(SelfDependencyFlags);
103 
104     enum class LoadFromResolve {
105         kNo,
106         kLoad,
107     };
108 
109     static GrVkRenderPass* CreateSimple(GrVkGpu*,
110                                         AttachmentsDescriptor*,
111                                         AttachmentFlags,
112                                         SelfDependencyFlags selfDepFlags,
113                                         LoadFromResolve);
114     static GrVkRenderPass* Create(GrVkGpu*,
115                                   const GrVkRenderPass& compatibleRenderPass,
116                                   const LoadStoreOps& colorOp,
117                                   const LoadStoreOps& resolveOp,
118                                   const LoadStoreOps& stencilOp);
119 
120     // The following return the index of the render pass attachment array for the given attachment.
121     // If the render pass does not have the given attachment it will return false and not set the
122     // index value.
123     bool colorAttachmentIndex(uint32_t* index) const;
124     bool stencilAttachmentIndex(uint32_t* index) const;
hasStencilAttachment()125     bool hasStencilAttachment() const { return fAttachmentFlags & kStencil_AttachmentFlag; }
hasResolveAttachment()126     bool hasResolveAttachment() const { return fAttachmentFlags & kResolve_AttachmentFlag; }
127 
selfDependencyFlags()128     SelfDependencyFlags selfDependencyFlags() const { return fSelfDepFlags; }
loadFromResolve()129     LoadFromResolve loadFromResolve() const { return fLoadFromResolve; }
130 
131     // Returns whether or not the structure of a RenderTarget matches that of the VkRenderPass in
132     // this object. Specifically this compares that the number of attachments, format of
133     // attachments, and sample counts are all the same. This function is used in the creation of
134     // basic RenderPasses that can be used when creating a VkFrameBuffer object.
135     bool isCompatible(GrVkRenderTarget* target,
136                       SelfDependencyFlags selfDepFlags,
137                       LoadFromResolve) const;
138 
139     bool isCompatible(const GrVkRenderPass& renderPass) const;
140 
141     bool isCompatible(const AttachmentsDescriptor&,
142                       const AttachmentFlags&,
143                       SelfDependencyFlags selfDepFlags,
144                       LoadFromResolve) const;
145 
146     bool isCompatibleExternalRP(VkRenderPass) const;
147 
148     SkDEBUGCODE(bool isExternal() const { return fAttachmentFlags & kExternal_AttachmentFlag; })
149 
150     bool equalLoadStoreOps(const LoadStoreOps& colorOps,
151                            const LoadStoreOps& resolveOps,
152                            const LoadStoreOps& stencilOps) const;
153 
vkRenderPass()154     VkRenderPass vkRenderPass() const { return fRenderPass; }
155 
granularity()156     const VkExtent2D& granularity() const { return fGranularity; }
157 
158     // Returns the number of clear colors needed to begin this render pass. Currently this will
159     // either only be 0 or 1 since we only ever clear the color attachment.
clearValueCount()160     uint32_t clearValueCount() const { return fClearValueCount; }
161 
162 
163     void genKey(skgpu::KeyBuilder*) const;
164 
165     static void GenKey(skgpu::KeyBuilder*,
166                        AttachmentFlags,
167                        const AttachmentsDescriptor&,
168                        SelfDependencyFlags selfDepFlags,
169                        LoadFromResolve,
170                        uint64_t externalRenderPass);
171 
172 #ifdef SK_TRACE_MANAGED_RESOURCES
dumpInfo()173     void dumpInfo() const override {
174         SkDebugf("GrVkRenderPass: %" PRIdPTR " (%d refs)\n",
175                  (intptr_t)fRenderPass, this->getRefCnt());
176     }
177 #endif
178 
179 private:
180     GrVkRenderPass(const GrVkGpu*, VkRenderPass, AttachmentFlags, const AttachmentsDescriptor&,
181                    SelfDependencyFlags selfDepFlags, LoadFromResolve, const VkExtent2D& granularity,
182                    uint32_t clearValueCount);
183 
184     static GrVkRenderPass* Create(GrVkGpu* gpu,
185                                   AttachmentFlags,
186                                   AttachmentsDescriptor*,
187                                   const LoadStoreOps& colorOps,
188                                   const LoadStoreOps& resolveOp,
189                                   const LoadStoreOps& stencilOps,
190                                   SelfDependencyFlags selfDepFlags,
191                                   LoadFromResolve);
192 
193     void freeGPUData() const override;
194 
195     VkRenderPass          fRenderPass;
196     AttachmentFlags       fAttachmentFlags;
197     AttachmentsDescriptor fAttachmentsDescriptor;
198     SelfDependencyFlags   fSelfDepFlags;
199     LoadFromResolve       fLoadFromResolve;
200     VkExtent2D            fGranularity;
201     uint32_t              fClearValueCount;
202     // For internally created render passes we assume the color attachment index is always 0.
203     uint32_t              fColorAttachmentIndex = 0;
204 
205     using INHERITED = GrVkManagedResource;
206 };
207 
208 SK_MAKE_BITFIELD_OPS(GrVkRenderPass::AttachmentFlags)
209 SK_MAKE_BITFIELD_CLASS_OPS(GrVkRenderPass::SelfDependencyFlags)
210 
211 #endif
212