• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //
2 // Copyright 2016 The ANGLE Project Authors. All rights reserved.
3 // Use of this source code is governed by a BSD-style license that can be
4 // found in the LICENSE file.
5 //
6 // FramebufferVk.h:
7 //    Defines the class interface for FramebufferVk, implementing FramebufferImpl.
8 //
9 
10 #ifndef LIBANGLE_RENDERER_VULKAN_FRAMEBUFFERVK_H_
11 #define LIBANGLE_RENDERER_VULKAN_FRAMEBUFFERVK_H_
12 
13 #include "libANGLE/angletypes.h"
14 #include "libANGLE/renderer/FramebufferImpl.h"
15 #include "libANGLE/renderer/RenderTargetCache.h"
16 #include "libANGLE/renderer/vulkan/BufferVk.h"
17 #include "libANGLE/renderer/vulkan/ResourceVk.h"
18 #include "libANGLE/renderer/vulkan/SurfaceVk.h"
19 #include "libANGLE/renderer/vulkan/UtilsVk.h"
20 #include "libANGLE/renderer/vulkan/vk_cache_utils.h"
21 #include "libANGLE/renderer/vulkan/vk_helpers.h"
22 
23 namespace rx
24 {
25 class RendererVk;
26 class RenderTargetVk;
27 class WindowSurfaceVk;
28 
29 class FramebufferVk : public FramebufferImpl
30 {
31   public:
32     FramebufferVk(RendererVk *renderer, const gl::FramebufferState &state);
33     ~FramebufferVk() override;
34     void destroy(const gl::Context *context) override;
35 
36     angle::Result discard(const gl::Context *context,
37                           size_t count,
38                           const GLenum *attachments) override;
39     angle::Result invalidate(const gl::Context *context,
40                              size_t count,
41                              const GLenum *attachments) override;
42     angle::Result invalidateSub(const gl::Context *context,
43                                 size_t count,
44                                 const GLenum *attachments,
45                                 const gl::Rectangle &area) override;
46 
47     angle::Result clear(const gl::Context *context, GLbitfield mask) override;
48     angle::Result clearBufferfv(const gl::Context *context,
49                                 GLenum buffer,
50                                 GLint drawbuffer,
51                                 const GLfloat *values) override;
52     angle::Result clearBufferuiv(const gl::Context *context,
53                                  GLenum buffer,
54                                  GLint drawbuffer,
55                                  const GLuint *values) override;
56     angle::Result clearBufferiv(const gl::Context *context,
57                                 GLenum buffer,
58                                 GLint drawbuffer,
59                                 const GLint *values) override;
60     angle::Result clearBufferfi(const gl::Context *context,
61                                 GLenum buffer,
62                                 GLint drawbuffer,
63                                 GLfloat depth,
64                                 GLint stencil) override;
65 
66     const gl::InternalFormat &getImplementationColorReadFormat(
67         const gl::Context *context) const override;
68     angle::Result readPixels(const gl::Context *context,
69                              const gl::Rectangle &area,
70                              GLenum format,
71                              GLenum type,
72                              const gl::PixelPackState &pack,
73                              gl::Buffer *packBuffer,
74                              void *pixels) override;
75 
76     angle::Result blit(const gl::Context *context,
77                        const gl::Rectangle &sourceArea,
78                        const gl::Rectangle &destArea,
79                        GLbitfield mask,
80                        GLenum filter) override;
81 
82     gl::FramebufferStatus checkStatus(const gl::Context *context) const override;
83 
84     angle::Result syncState(const gl::Context *context,
85                             GLenum binding,
86                             const gl::Framebuffer::DirtyBits &dirtyBits,
87                             gl::Command command) override;
88 
89     angle::Result getSamplePosition(const gl::Context *context,
90                                     size_t index,
91                                     GLfloat *xy) const override;
92     RenderTargetVk *getDepthStencilRenderTarget() const;
93 
94     // Internal helper function for readPixels operations.
95     angle::Result readPixelsImpl(ContextVk *contextVk,
96                                  const gl::Rectangle &area,
97                                  const PackPixelsParams &packPixelsParams,
98                                  VkImageAspectFlagBits copyAspectFlags,
99                                  RenderTargetVk *renderTarget,
100                                  void *pixels);
101 
102     gl::Extents getReadImageExtents() const;
103     gl::Rectangle getNonRotatedCompleteRenderArea() const;
104     gl::Rectangle getRotatedCompleteRenderArea(ContextVk *contextVk) const;
105     gl::Rectangle getRotatedScissoredRenderArea(ContextVk *contextVk) const;
106     // Returns render area with deferred clears in consideration. When deferred clear is used
107     // in the render pass, the render area must cover the whole framebuffer.
108     gl::Rectangle getRenderArea(ContextVk *contextVk) const;
109 
110     const gl::DrawBufferMask &getEmulatedAlphaAttachmentMask() const;
111     RenderTargetVk *getColorDrawRenderTarget(size_t colorIndexGL) const;
112     RenderTargetVk *getColorReadRenderTarget() const;
113 
114     angle::Result startNewRenderPass(ContextVk *contextVk,
115                                      const gl::Rectangle &renderArea,
116                                      vk::RenderPassCommandBuffer **commandBufferOut,
117                                      bool *renderPassDescChangedOut);
118 
119     GLint getSamples() const;
120 
getRenderPassDesc()121     const vk::RenderPassDesc &getRenderPassDesc() const { return mRenderPassDesc; }
122 
123     void updateColorResolveAttachment(
124         uint32_t colorIndexGL,
125         vk::ImageOrBufferViewSubresourceSerial resolveImageViewSerial);
126 
127     angle::Result getFramebuffer(ContextVk *contextVk,
128                                  vk::MaybeImagelessFramebuffer *framebufferOut,
129                                  RenderTargetVk *resolveRenderTargetIn,
130                                  const vk::ImageView *resolveImageViewIn,
131                                  const SwapchainResolveMode swapchainResolveMode);
132 
hasDeferredClears()133     bool hasDeferredClears() const { return !mDeferredClears.empty(); }
134     angle::Result flushDeferredClears(ContextVk *contextVk);
135 
136     void switchToFramebufferFetchMode(ContextVk *contextVk, bool hasFramebufferFetch);
137 
138     bool updateLegacyDither(ContextVk *contextVk);
139 
140     void removeColorResolveAttachment(uint32_t colorIndexGL);
141 
setBackbuffer(WindowSurfaceVk * backbuffer)142     void setBackbuffer(WindowSurfaceVk *backbuffer) { mBackbuffer = backbuffer; }
getBackbuffer()143     WindowSurfaceVk *getBackbuffer() const { return mBackbuffer; }
144 
145     void releaseCurrentFramebuffer(ContextVk *contextVk);
146 
getLastRenderPassQueueSerial()147     const QueueSerial &getLastRenderPassQueueSerial() const { return mLastRenderPassQueueSerial; }
148 
hasAnyExternalAttachments()149     bool hasAnyExternalAttachments() const { return mIsExternalColorAttachments.any(); }
150 
hasFrontBufferUsage()151     bool hasFrontBufferUsage() const
152     {
153         return (mAttachmentHasFrontBufferUsage & mState.getColorAttachmentsMask()).any();
154     }
155 
156     enum class RenderTargetImage
157     {
158         AttachmentImage,
159         ResolveImage
160     };
161 
162     struct RenderTargetInfo
163     {
RenderTargetInfoRenderTargetInfo164         RenderTargetInfo()
165             : renderTarget(nullptr), renderTargetImage(RenderTargetImage::AttachmentImage)
166         {}
RenderTargetInfoRenderTargetInfo167         RenderTargetInfo(RenderTargetVk *renderTarget, RenderTargetImage renderTargetImage)
168             : renderTarget(renderTarget), renderTargetImage(renderTargetImage)
169         {}
170         RenderTargetVk *renderTarget;
171         RenderTargetImage renderTargetImage;
172     };
173 
174     angle::Result getAttachmentsAndRenderTargets(
175         ContextVk *contextVk,
176         const vk::ImageView *resolveImageViewIn,
177         RenderTargetVk *resolveRenderTargetIn,
178         vk::FramebufferAttachmentsVector<VkImageView> *attachments,
179         vk::FramebufferAttachmentsVector<RenderTargetInfo> *renderTargetsInfoOut);
180 
181   private:
182     enum class ClearWithCommand
183     {
184         Always,
185         OptimizeWithLoadOp,
186     };
187 
188     // The 'in' rectangles must be clipped to the scissor and FBO. The clipping is done in 'blit'.
189     angle::Result blitWithCommand(ContextVk *contextVk,
190                                   const gl::Rectangle &sourceArea,
191                                   const gl::Rectangle &destArea,
192                                   RenderTargetVk *readRenderTarget,
193                                   RenderTargetVk *drawRenderTarget,
194                                   GLenum filter,
195                                   bool colorBlit,
196                                   bool depthBlit,
197                                   bool stencilBlit,
198                                   bool flipX,
199                                   bool flipY);
200 
201     // Resolve color with subpass attachment
202     angle::Result resolveColorWithSubpass(ContextVk *contextVk,
203                                           const UtilsVk::BlitResolveParameters &params);
204 
205     // Resolve color with vkCmdResolveImage
206     angle::Result resolveColorWithCommand(ContextVk *contextVk,
207                                           const UtilsVk::BlitResolveParameters &params,
208                                           vk::ImageHelper *srcImage);
209 
210     angle::Result clearImpl(const gl::Context *context,
211                             gl::DrawBufferMask clearColorBuffers,
212                             bool clearDepth,
213                             bool clearStencil,
214                             const VkClearColorValue &clearColorValue,
215                             const VkClearDepthStencilValue &clearDepthStencilValue);
216 
217     void mergeClearsWithDeferredClears(gl::DrawBufferMask clearColorBuffers,
218                                        bool clearDepth,
219                                        bool clearStencil,
220                                        const VkClearColorValue &clearColorValue,
221                                        const VkClearDepthStencilValue &clearDepthStencilValue);
222     angle::Result clearWithDraw(ContextVk *contextVk,
223                                 const gl::Rectangle &clearArea,
224                                 gl::DrawBufferMask clearColorBuffers,
225                                 bool clearDepth,
226                                 bool clearStencil,
227                                 gl::BlendStateExt::ColorMaskStorage::Type colorMasks,
228                                 uint8_t stencilMask,
229                                 const VkClearColorValue &clearColorValue,
230                                 const VkClearDepthStencilValue &clearDepthStencilValue);
231     void redeferClears(ContextVk *contextVk);
232     void redeferClearsForReadFramebuffer(ContextVk *contextVk);
233     void redeferClearsImpl(ContextVk *contextVk);
234     void clearWithCommand(ContextVk *contextVk,
235                           const gl::Rectangle &scissoredRenderArea,
236                           ClearWithCommand behavior,
237                           vk::ClearValuesArray *clears);
238     void clearWithLoadOp(ContextVk *contextVk);
239     void updateActiveColorMasks(size_t colorIndex, bool r, bool g, bool b, bool a);
240     void updateRenderPassDesc(ContextVk *contextVk);
241     angle::Result updateColorAttachment(const gl::Context *context, uint32_t colorIndex);
242     angle::Result updateDepthStencilAttachment(const gl::Context *context);
243     void updateDepthStencilAttachmentSerial(ContextVk *contextVk);
244     angle::Result flushColorAttachmentUpdates(const gl::Context *context,
245                                               bool deferClears,
246                                               uint32_t colorIndex);
247     angle::Result flushDepthStencilAttachmentUpdates(const gl::Context *context, bool deferClears);
248     angle::Result invalidateImpl(ContextVk *contextVk,
249                                  size_t count,
250                                  const GLenum *attachments,
251                                  bool isSubInvalidate,
252                                  const gl::Rectangle &invalidateArea);
253 
254     RenderTargetVk *getReadPixelsRenderTarget(GLenum format) const;
255     VkImageAspectFlagBits getReadPixelsAspectFlags(GLenum format) const;
256 
257     VkClearValue getCorrectedColorClearValue(size_t colorIndexGL,
258                                              const VkClearColorValue &clearColor) const;
259 
260     void updateLayerCount();
261 
262     void insertCache(ContextVk *contextVk,
263                      const vk::FramebufferDesc &desc,
264                      vk::FramebufferHelper &&newFramebuffer);
265 
266     WindowSurfaceVk *mBackbuffer;
267 
268     vk::RenderPassDesc mRenderPassDesc;
269     RenderTargetCache<RenderTargetVk> mRenderTargetCache;
270 
271     // This variable is used to quickly compute if we need to do a masked clear. If a color
272     // channel is masked out, we check against the Framebuffer Attachments (RenderTargets) to see
273     // if the masked out channel is present in any of the attachments.
274     gl::BlendStateExt::ColorMaskStorage::Type mActiveColorComponentMasksForClear;
275 
276     // When we draw to the framebuffer, and the real format has an alpha channel but the format of
277     // the framebuffer does not, we need to mask out the alpha channel. This DrawBufferMask will
278     // contain the mask to apply to the alpha channel when drawing.
279     gl::DrawBufferMask mEmulatedAlphaAttachmentMask;
280 
281     // mCurrentFramebufferDesc is used to detect framebuffer changes using its serials. Therefore,
282     // it must be maintained even when using the imageless framebuffer extension.
283     vk::FramebufferDesc mCurrentFramebufferDesc;
284 
285     // The framebuffer cache actually owns the Framebuffer object and manages its lifetime. We just
286     // store the current VkFramebuffer handle here that associated with mCurrentFramebufferDesc.
287     vk::Framebuffer mCurrentFramebuffer;
288 
289     vk::ClearValuesArray mDeferredClears;
290 
291     // Whether any of the color attachments are an external image such as dmabuf, AHB etc.  In such
292     // cases, some optimizations are disabled such as deferred clears because the results need to be
293     // made externally available.
294     gl::DrawBufferMask mIsExternalColorAttachments;
295     gl::DrawBufferMask mAttachmentHasFrontBufferUsage;
296 
297     bool mIsCurrentFramebufferCached;
298 
299     // Serial of the render pass this framebuffer has opened, if any.
300     QueueSerial mLastRenderPassQueueSerial;
301 };
302 }  // namespace rx
303 
304 #endif  // LIBANGLE_RENDERER_VULKAN_FRAMEBUFFERVK_H_
305