xref: /aosp_15_r20/external/skia/src/gpu/ganesh/vk/GrVkRenderTarget.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 
9 #ifndef GrVkRenderTarget_DEFINED
10 #define GrVkRenderTarget_DEFINED
11 
12 #include "include/core/SkRefCnt.h"
13 #include "include/gpu/ganesh/GrBackendSurface.h"
14 #include "include/private/base/SkAssert.h"
15 #include "include/private/base/SkTo.h"
16 #include "src/gpu/ganesh/GrRenderTarget.h"
17 #include "src/gpu/ganesh/vk/GrVkImage.h"
18 #include "src/gpu/ganesh/vk/GrVkRenderPass.h"
19 #include "src/gpu/ganesh/vk/GrVkResourceProvider.h"
20 
21 #include <cstddef>
22 #include <string_view>
23 #include <utility>
24 
25 class GrAttachment;
26 class GrProgramInfo;
27 class GrVkCaps;
28 class GrVkDescriptorSet;
29 class GrVkFramebuffer;
30 class GrVkGpu;
31 class GrVkImageView;
32 struct GrVkDrawableInfo;
33 struct GrVkImageInfo;
34 struct SkISize;
35 
36 namespace skgpu {
37 class MutableTextureState;
38 }
39 
40 class GrVkRenderTarget : public GrRenderTarget {
41 public:
42     static sk_sp<GrVkRenderTarget> MakeWrappedRenderTarget(GrVkGpu*,
43                                                            SkISize,
44                                                            int sampleCnt,
45                                                            const GrVkImageInfo&,
46                                                            sk_sp<skgpu::MutableTextureState>);
47 
48     static sk_sp<GrVkRenderTarget> MakeSecondaryCBRenderTarget(GrVkGpu*,
49                                                                SkISize,
50                                                                const GrVkDrawableInfo& vkInfo);
51 
52     ~GrVkRenderTarget() override;
53 
54     GrBackendFormat backendFormat() const override;
55 
56     using SelfDependencyFlags = GrVkRenderPass::SelfDependencyFlags;
57     using LoadFromResolve = GrVkRenderPass::LoadFromResolve;
58 
59     const GrVkFramebuffer* getFramebuffer(bool withResolve,
60                                           bool withStencil,
61                                           SelfDependencyFlags selfDepFlags,
62                                           LoadFromResolve);
getFramebuffer(const GrVkRenderPass & renderPass)63     const GrVkFramebuffer* getFramebuffer(const GrVkRenderPass& renderPass) {
64         return this->getFramebuffer(renderPass.hasResolveAttachment(),
65                                     renderPass.hasStencilAttachment(),
66                                     renderPass.selfDependencyFlags(),
67                                     renderPass.loadFromResolve());
68     }
69 
colorAttachment()70     GrVkImage* colorAttachment() const {
71         SkASSERT(!this->wrapsSecondaryCommandBuffer());
72         return fColorAttachment.get();
73     }
colorAttachmentView()74     const GrVkImageView* colorAttachmentView() const {
75         SkASSERT(!this->wrapsSecondaryCommandBuffer());
76         return this->colorAttachment()->framebufferView();
77     }
78 
resolveAttachment()79     GrVkImage* resolveAttachment() const {
80         SkASSERT(!this->wrapsSecondaryCommandBuffer());
81         return fResolveAttachment.get();
82     }
resolveAttachmentView()83     const GrVkImageView* resolveAttachmentView() const {
84         SkASSERT(!this->wrapsSecondaryCommandBuffer());
85         return fResolveAttachment->framebufferView();
86     }
87 
88     // Returns the GrVkImage of the non-msaa attachment. If the color attachment has 1 sample,
89     // then the color attachment will be returned. Otherwise, the resolve attachment is returned.
90     // Note that in this second case the resolve attachment may be null if this was created by
91     // wrapping an msaa VkImage.
92     GrVkImage* nonMSAAAttachment() const;
93 
94     // Returns the attachment that is used for all external client facing operations. This will be
95     // either a wrapped color attachment or the resolve attachment for created VkImages.
externalAttachment()96     GrVkImage* externalAttachment() const {
97         return fResolveAttachment ? fResolveAttachment.get() : fColorAttachment.get();
98     }
99 
100     const GrVkRenderPass* getSimpleRenderPass(
101             bool withResolve,
102             bool withStencil,
103             SelfDependencyFlags selfDepFlags,
104             LoadFromResolve);
105     GrVkResourceProvider::CompatibleRPHandle compatibleRenderPassHandle(
106             bool withResolve,
107             bool withStencil,
108             SelfDependencyFlags selfDepFlags,
109             LoadFromResolve);
110 
wrapsSecondaryCommandBuffer()111     bool wrapsSecondaryCommandBuffer() const { return SkToBool(fExternalFramebuffer); }
112     sk_sp<GrVkFramebuffer> externalFramebuffer() const;
113 
114     bool canAttemptStencilAttachment(bool useMSAASurface) const override;
115 
116     GrBackendRenderTarget getBackendRenderTarget() const override;
117 
118     bool getAttachmentsDescriptor(GrVkRenderPass::AttachmentsDescriptor* desc,
119                                   GrVkRenderPass::AttachmentFlags* flags,
120                                   bool withResolve,
121                                   bool withStencil);
122 
123     // Reconstruct the render target attachment information from the programInfo. This includes
124     // which attachments the render target will have (color, stencil) and the attachments' formats
125     // and sample counts - cf. getAttachmentsDescriptor.
126     static void ReconstructAttachmentsDescriptor(const GrVkCaps& vkCaps,
127                                                  const GrProgramInfo& programInfo,
128                                                  GrVkRenderPass::AttachmentsDescriptor* desc,
129                                                  GrVkRenderPass::AttachmentFlags* flags);
130 
131 protected:
132     enum class CreateType {
133         kDirectlyWrapped, // We need to register this in the ctor
134         kFromTextureRT,   // Skip registering this to cache since TexRT will handle it
135     };
136 
137     GrVkRenderTarget(GrVkGpu* gpu,
138                      SkISize dimensions,
139                      sk_sp<GrVkImage> colorAttachment,
140                      sk_sp<GrVkImage> resolveImage,
141                      CreateType createType,
142                      std::string_view label);
143 
144     void onAbandon() override;
145     void onRelease() override;
146 
147     // This returns zero since the memory should all be handled by the attachments
onGpuMemorySize()148     size_t onGpuMemorySize() const override { return 0; }
149 
onSetLabel()150     void onSetLabel() override{}
151 
152 private:
153     // For external framebuffers that wrap a secondary command buffer
154     GrVkRenderTarget(GrVkGpu* gpu,
155                      SkISize dimensions,
156                      sk_sp<GrVkFramebuffer> externalFramebuffer,
157                      std::string_view label);
158 
159     void setFlags();
160 
161     GrVkGpu* getVkGpu() const;
162 
163     GrVkImage* dynamicMSAAAttachment();
164     GrVkImage* msaaAttachment();
165 
166     std::pair<const GrVkRenderPass*, GrVkResourceProvider::CompatibleRPHandle>
167         createSimpleRenderPass(bool withResolve,
168                                bool withStencil,
169                                SelfDependencyFlags selfDepFlags,
170                                LoadFromResolve);
171     void createFramebuffer(bool withResolve,
172                            bool withStencil,
173                            SelfDependencyFlags selfDepFlags,
174                            LoadFromResolve);
175 
176     bool completeStencilAttachment(GrAttachment* stencil, bool useMSAASurface) override;
177 
178     // In Vulkan we call the release proc after we are finished with the underlying
179     // GrVkImage::Resource object (which occurs after the GPU has finished all work on it).
onSetRelease(sk_sp<RefCntedReleaseProc> releaseHelper)180     void onSetRelease(sk_sp<RefCntedReleaseProc> releaseHelper) override {
181         // Forward the release proc on to the GrVkImage of the resolve attachment if we have one,
182         // otherwise the color attachment.
183         GrVkImage* attachment =
184                 fResolveAttachment ? fResolveAttachment.get() : fColorAttachment.get();
185         attachment->setResourceRelease(std::move(releaseHelper));
186     }
187 
188     void releaseInternalObjects();
189 
190     sk_sp<GrVkImage> fColorAttachment;
191     sk_sp<GrVkImage> fResolveAttachment;
192     sk_sp<GrVkImage> fDynamicMSAAAttachment;
193 
194     // We can have a renderpass with and without resolve attachment, stencil attachment,
195     // input attachment dependency, advanced blend dependency, and loading from resolve. All 5 of
196     // these being completely orthogonal. Thus we have a total of 32 types of render passes. We then
197     // cache a framebuffer for each type of these render passes.
198     static constexpr int kNumCachedFramebuffers = 32;
199 
200     sk_sp<const GrVkFramebuffer> fCachedFramebuffers[kNumCachedFramebuffers];
201 
202     const GrVkDescriptorSet* fCachedInputDescriptorSet = nullptr;
203 
204     sk_sp<GrVkFramebuffer> fExternalFramebuffer;
205 };
206 
207 #endif
208