• 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 *contextVk,
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 
161     angle::Result clearImmediatelyWithRenderPassOp(
162         ContextVk *contextVk,
163         const gl::Rectangle &clearArea,
164         gl::DrawBufferMask clearColorBuffers,
165         bool clearDepth,
166         bool clearStencil,
167         const VkClearColorValue &clearColorValue,
168         const VkClearDepthStencilValue &clearDepthStencilValue);
169 
170     angle::Result clearWithDraw(ContextVk *contextVk,
171                                 const gl::Rectangle &clearArea,
172                                 gl::DrawBufferMask clearColorBuffers,
173                                 bool clearDepth,
174                                 bool clearStencil,
175                                 VkColorComponentFlags colorMaskFlags,
176                                 uint8_t stencilMask,
177                                 const VkClearColorValue &clearColorValue,
178                                 const VkClearDepthStencilValue &clearDepthStencilValue);
179     void clearWithRenderPassOp(gl::DrawBufferMask clearColorBuffers,
180                                bool clearDepth,
181                                bool clearStencil,
182                                const VkClearColorValue &clearColorValue,
183                                const VkClearDepthStencilValue &clearDepthStencilValue);
184     void updateActiveColorMasks(size_t colorIndex, bool r, bool g, bool b, bool a);
185     void updateRenderPassDesc();
186     angle::Result updateColorAttachment(const gl::Context *context,
187                                         bool deferClears,
188                                         uint32_t colorIndex);
189     angle::Result invalidateImpl(ContextVk *contextVk, size_t count, const GLenum *attachments);
190     // Release all FramebufferVk objects in the cache and clear cache
191     void clearCache(ContextVk *contextVk);
192     angle::Result updateDepthStencilAttachment(const gl::Context *context, bool deferClears);
193     void updateDepthStencilAttachmentSerial(ContextVk *contextVk);
194 
195     RenderTargetVk *getReadPixelsRenderTarget(GLenum format) const;
196     VkImageAspectFlagBits getReadPixelsAspectFlags(GLenum format) const;
197 
198     angle::Result flushDeferredClears(ContextVk *contextVk, const gl::Rectangle &renderArea);
199     VkClearValue getCorrectedColorClearValue(size_t colorIndexGL,
200                                              const VkClearColorValue &clearColor) const;
201 
202     WindowSurfaceVk *mBackbuffer;
203 
204     vk::RenderPassDesc mRenderPassDesc;
205     vk::FramebufferHelper *mFramebuffer;
206     RenderTargetCache<RenderTargetVk> mRenderTargetCache;
207 
208     // These two variables are used to quickly compute if we need to do a masked clear. If a color
209     // channel is masked out, we check against the Framebuffer Attachments (RenderTargets) to see
210     // if the masked out channel is present in any of the attachments.
211     VkColorComponentFlags mActiveColorComponents;
212     gl::DrawBufferMask mActiveColorComponentMasksForClear[4];
213     vk::DynamicBuffer mReadPixelBuffer;
214 
215     // When we draw to the framebuffer, and the real format has an alpha channel but the format of
216     // the framebuffer does not, we need to mask out the alpha channel. This DrawBufferMask will
217     // contain the mask to apply to the alpha channel when drawing.
218     gl::DrawBufferMask mEmulatedAlphaAttachmentMask;
219 
220     vk::FramebufferDesc mCurrentFramebufferDesc;
221     std::unordered_map<vk::FramebufferDesc, vk::FramebufferHelper> mFramebufferCache;
222     bool mSupportDepthStencilFeedbackLoops;
223 
224     vk::ClearValuesArray mDeferredClears;
225 };
226 }  // namespace rx
227 
228 #endif  // LIBANGLE_RENDERER_VULKAN_FRAMEBUFFERVK_H_
229