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