• 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/renderer/FramebufferImpl.h"
14 #include "libANGLE/renderer/RenderTargetCache.h"
15 #include "libANGLE/renderer/vulkan/BufferVk.h"
16 #include "libANGLE/renderer/vulkan/ResourceVk.h"
17 #include "libANGLE/renderer/vulkan/UtilsVk.h"
18 #include "libANGLE/renderer/vulkan/vk_cache_utils.h"
19 
20 namespace rx
21 {
22 class RendererVk;
23 class RenderTargetVk;
24 class WindowSurfaceVk;
25 
26 class FramebufferVk : public FramebufferImpl
27 {
28   public:
29     // Factory methods so we don't have to use constructors with overloads.
30     static FramebufferVk *CreateUserFBO(RendererVk *renderer, const gl::FramebufferState &state);
31 
32     // The passed-in SurfaceVK must be destroyed after this FBO is destroyed. Our Surface code is
33     // ref-counted on the number of 'current' contexts, so we shouldn't get any dangling surface
34     // references. See Surface::setIsCurrent(bool).
35     static FramebufferVk *CreateDefaultFBO(RendererVk *renderer,
36                                            const gl::FramebufferState &state,
37                                            WindowSurfaceVk *backbuffer);
38 
39     ~FramebufferVk() override;
40     void destroy(const gl::Context *context) override;
41 
42     angle::Result discard(const gl::Context *context,
43                           size_t count,
44                           const GLenum *attachments) override;
45     angle::Result invalidate(const gl::Context *context,
46                              size_t count,
47                              const GLenum *attachments) override;
48     angle::Result invalidateSub(const gl::Context *context,
49                                 size_t count,
50                                 const GLenum *attachments,
51                                 const gl::Rectangle &area) override;
52 
53     angle::Result clear(const gl::Context *context, GLbitfield mask) override;
54     angle::Result clearBufferfv(const gl::Context *context,
55                                 GLenum buffer,
56                                 GLint drawbuffer,
57                                 const GLfloat *values) override;
58     angle::Result clearBufferuiv(const gl::Context *context,
59                                  GLenum buffer,
60                                  GLint drawbuffer,
61                                  const GLuint *values) override;
62     angle::Result clearBufferiv(const gl::Context *context,
63                                 GLenum buffer,
64                                 GLint drawbuffer,
65                                 const GLint *values) override;
66     angle::Result clearBufferfi(const gl::Context *context,
67                                 GLenum buffer,
68                                 GLint drawbuffer,
69                                 GLfloat depth,
70                                 GLint stencil) override;
71 
72     const gl::InternalFormat &getImplementationColorReadFormat(
73         const gl::Context *context) const override;
74     angle::Result readPixels(const gl::Context *context,
75                              const gl::Rectangle &area,
76                              GLenum format,
77                              GLenum type,
78                              void *pixels) override;
79 
80     angle::Result blit(const gl::Context *context,
81                        const gl::Rectangle &sourceArea,
82                        const gl::Rectangle &destArea,
83                        GLbitfield mask,
84                        GLenum filter) override;
85 
86     bool checkStatus(const gl::Context *context) const override;
87 
88     angle::Result syncState(const gl::Context *context,
89                             GLenum binding,
90                             const gl::Framebuffer::DirtyBits &dirtyBits) override;
91 
92     angle::Result getSamplePosition(const gl::Context *context,
93                                     size_t index,
94                                     GLfloat *xy) const override;
95     RenderTargetVk *getDepthStencilRenderTarget() const;
96 
97     // Internal helper function for readPixels operations.
98     angle::Result readPixelsImpl(ContextVk *contextVk,
99                                  const gl::Rectangle &area,
100                                  const PackPixelsParams &packPixelsParams,
101                                  VkImageAspectFlagBits copyAspectFlags,
102                                  RenderTargetVk *renderTarget,
103                                  void *pixels);
104 
105     gl::Extents getReadImageExtents() const;
106     gl::Rectangle getCompleteRenderArea() const;
107     gl::Rectangle getScissoredRenderArea(ContextVk *contextVk) const;
108 
109     const gl::DrawBufferMask &getEmulatedAlphaAttachmentMask() const;
110     RenderTargetVk *getColorDrawRenderTarget(size_t colorIndex) const;
111     RenderTargetVk *getColorReadRenderTarget() const;
112 
113     angle::Result startNewRenderPass(ContextVk *context,
114                                      const gl::Rectangle &renderArea,
115                                      vk::CommandBuffer **commandBufferOut);
116 
117     RenderTargetVk *getFirstRenderTarget() const;
118     GLint getSamples() const;
119 
getRenderPassDesc()120     const vk::RenderPassDesc &getRenderPassDesc() const { return mRenderPassDesc; }
getFramebufferDesc()121     const vk::FramebufferDesc &getFramebufferDesc() const { return mCurrentFramebufferDesc; }
122     // We only support depth/stencil packed format and depthstencil attachment always follow all
123     // color attachments
getDepthStencilAttachmentIndexVk()124     size_t getDepthStencilAttachmentIndexVk() const
125     {
126         return getState().getEnabledDrawBuffers().count();
127     }
128 
129   private:
130     FramebufferVk(RendererVk *renderer,
131                   const gl::FramebufferState &state,
132                   WindowSurfaceVk *backbuffer);
133 
134     // The 'in' rectangles must be clipped to the scissor and FBO. The clipping is done in 'blit'.
135     angle::Result blitWithCommand(ContextVk *contextVk,
136                                   const gl::Rectangle &sourceArea,
137                                   const gl::Rectangle &destArea,
138                                   RenderTargetVk *readRenderTarget,
139                                   RenderTargetVk *drawRenderTarget,
140                                   GLenum filter,
141                                   bool colorBlit,
142                                   bool depthBlit,
143                                   bool stencilBlit,
144                                   bool flipX,
145                                   bool flipY);
146 
147     // Resolve color with vkCmdResolveImage
148     angle::Result resolveColorWithCommand(ContextVk *contextVk,
149                                           const UtilsVk::BlitResolveParameters &params,
150                                           vk::ImageHelper *srcImage);
151 
152     angle::Result getFramebuffer(ContextVk *contextVk, vk::Framebuffer **framebufferOut);
153 
154     angle::Result clearImpl(const gl::Context *context,
155                             gl::DrawBufferMask clearColorBuffers,
156                             bool clearDepth,
157                             bool clearStencil,
158                             const VkClearColorValue &clearColorValue,
159                             const VkClearDepthStencilValue &clearDepthStencilValue);
160     angle::Result clearWithDraw(ContextVk *contextVk,
161                                 const gl::Rectangle &clearArea,
162                                 gl::DrawBufferMask clearColorBuffers,
163                                 bool clearStencil,
164                                 VkColorComponentFlags colorMaskFlags,
165                                 uint8_t stencilMask,
166                                 const VkClearColorValue &clearColorValue,
167                                 uint8_t clearStencilValue);
168     void updateActiveColorMasks(size_t colorIndex, bool r, bool g, bool b, bool a);
169     void updateRenderPassDesc();
170     angle::Result updateColorAttachment(const gl::Context *context, size_t colorIndex);
171     angle::Result invalidateImpl(ContextVk *contextVk, size_t count, const GLenum *attachments);
172     // Release all FramebufferVk objects in the cache and clear cache
173     void clearCache(ContextVk *contextVk);
174     void updateDepthStencilAttachmentSerial(ContextVk *contextVk);
175 
176     RenderTargetVk *getReadPixelsRenderTarget(GLenum format) const;
177     VkImageAspectFlagBits getReadPixelsAspectFlags(GLenum format) const;
178 
179     WindowSurfaceVk *mBackbuffer;
180 
181     vk::RenderPassDesc mRenderPassDesc;
182     vk::FramebufferHelper *mFramebuffer;
183     RenderTargetCache<RenderTargetVk> mRenderTargetCache;
184 
185     // These two variables are used to quickly compute if we need to do a masked clear. If a color
186     // channel is masked out, we check against the Framebuffer Attachments (RenderTargets) to see
187     // if the masked out channel is present in any of the attachments.
188     VkColorComponentFlags mActiveColorComponents;
189     gl::DrawBufferMask mActiveColorComponentMasksForClear[4];
190     vk::DynamicBuffer mReadPixelBuffer;
191 
192     // When we draw to the framebuffer, and the real format has an alpha channel but the format of
193     // the framebuffer does not, we need to mask out the alpha channel. This DrawBufferMask will
194     // contain the mask to apply to the alpha channel when drawing.
195     gl::DrawBufferMask mEmulatedAlphaAttachmentMask;
196 
197     vk::FramebufferDesc mCurrentFramebufferDesc;
198     std::unordered_map<vk::FramebufferDesc, vk::FramebufferHelper> mFramebufferCache;
199     bool mSupportDepthStencilFeedbackLoops;
200 };
201 }  // namespace rx
202 
203 #endif  // LIBANGLE_RENDERER_VULKAN_FRAMEBUFFERVK_H_
204