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