• 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/CommandGraph.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     GLenum getImplementationColorReadFormat(const gl::Context *context) const override;
73     GLenum getImplementationColorReadType(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                             const gl::Framebuffer::DirtyBits &dirtyBits) override;
90 
91     angle::Result getSamplePosition(const gl::Context *context,
92                                     size_t index,
93                                     GLfloat *xy) const override;
94     RenderTargetVk *getDepthStencilRenderTarget() const;
95 
96     // Internal helper function for readPixels operations.
97     angle::Result readPixelsImpl(ContextVk *contextVk,
98                                  const gl::Rectangle &area,
99                                  const PackPixelsParams &packPixelsParams,
100                                  VkImageAspectFlagBits copyAspectFlags,
101                                  RenderTargetVk *renderTarget,
102                                  void *pixels);
103 
104     gl::Extents getReadImageExtents() const;
105     gl::Rectangle getCompleteRenderArea() const;
106     gl::Rectangle getScissoredRenderArea(ContextVk *contextVk) const;
107 
108     void onScissorChange(ContextVk *contextVk);
109 
110     const gl::DrawBufferMask &getEmulatedAlphaAttachmentMask() const;
111     RenderTargetVk *getColorReadRenderTarget() const;
112 
113     // This will clear the current write operation if it is complete.
appendToStartedRenderPass(Serial currentQueueSerial,const gl::Rectangle & renderArea,vk::CommandBuffer ** commandBufferOut)114     bool appendToStartedRenderPass(Serial currentQueueSerial,
115                                    const gl::Rectangle &renderArea,
116                                    vk::CommandBuffer **commandBufferOut)
117     {
118         return mFramebuffer.appendToStartedRenderPass(currentQueueSerial, renderArea,
119                                                       commandBufferOut);
120     }
121 
getFramebuffer()122     vk::FramebufferHelper *getFramebuffer() { return &mFramebuffer; }
123 
124     angle::Result startNewRenderPass(ContextVk *context,
125                                      const gl::Rectangle &renderArea,
126                                      vk::CommandBuffer **commandBufferOut);
127 
128     RenderTargetVk *getFirstRenderTarget() const;
129     GLint getSamples() const;
130 
getRenderPassDesc()131     const vk::RenderPassDesc &getRenderPassDesc() const { return mRenderPassDesc; }
132 
133   private:
134     FramebufferVk(RendererVk *renderer,
135                   const gl::FramebufferState &state,
136                   WindowSurfaceVk *backbuffer);
137 
138     // The 'in' rectangles must be clipped to the scissor and FBO. The clipping is done in 'blit'.
139     angle::Result blitWithCommand(ContextVk *contextVk,
140                                   const gl::Rectangle &sourceArea,
141                                   const gl::Rectangle &destArea,
142                                   RenderTargetVk *readRenderTarget,
143                                   RenderTargetVk *drawRenderTarget,
144                                   GLenum filter,
145                                   bool colorBlit,
146                                   bool depthBlit,
147                                   bool stencilBlit,
148                                   bool flipX,
149                                   bool flipY);
150 
151     // Resolve color with vkCmdResolveImage
152     angle::Result resolveColorWithCommand(ContextVk *contextVk,
153                                           const UtilsVk::BlitResolveParameters &params,
154                                           vk::ImageHelper *srcImage);
155 
156     angle::Result getFramebuffer(ContextVk *contextVk, vk::Framebuffer **framebufferOut);
157 
158     angle::Result clearImpl(const gl::Context *context,
159                             gl::DrawBufferMask clearColorBuffers,
160                             bool clearDepth,
161                             bool clearStencil,
162                             const VkClearColorValue &clearColorValue,
163                             const VkClearDepthStencilValue &clearDepthStencilValue);
164     angle::Result clearWithRenderPassOp(ContextVk *contextVk,
165                                         const gl::Rectangle &clearArea,
166                                         gl::DrawBufferMask clearColorBuffers,
167                                         bool clearDepth,
168                                         bool clearStencil,
169                                         const VkClearColorValue &clearColorValue,
170                                         const VkClearDepthStencilValue &clearDepthStencilValue);
171     angle::Result clearWithDraw(ContextVk *contextVk,
172                                 const gl::Rectangle &clearArea,
173                                 gl::DrawBufferMask clearColorBuffers,
174                                 bool clearStencil,
175                                 VkColorComponentFlags colorMaskFlags,
176                                 uint8_t stencilMask,
177                                 const VkClearColorValue &clearColorValue,
178                                 uint8_t clearStencilValue);
179     void updateActiveColorMasks(size_t colorIndex, bool r, bool g, bool b, bool a);
180     void updateRenderPassDesc();
181     angle::Result updateColorAttachment(const gl::Context *context, size_t colorIndex);
182     void invalidateImpl(ContextVk *contextVk, size_t count, const GLenum *attachments);
183 
184     WindowSurfaceVk *mBackbuffer;
185 
186     vk::RenderPassDesc mRenderPassDesc;
187     vk::FramebufferHelper mFramebuffer;
188     RenderTargetCache<RenderTargetVk> mRenderTargetCache;
189 
190     // These two variables are used to quickly compute if we need to do a masked clear. If a color
191     // channel is masked out, we check against the Framebuffer Attachments (RenderTargets) to see
192     // if the masked out channel is present in any of the attachments.
193     VkColorComponentFlags mActiveColorComponents;
194     gl::DrawBufferMask mActiveColorComponentMasksForClear[4];
195     vk::DynamicBuffer mReadPixelBuffer;
196 
197     // When we draw to the framebuffer, and the real format has an alpha channel but the format of
198     // the framebuffer does not, we need to mask out the alpha channel. This DrawBufferMask will
199     // contain the mask to apply to the alpha channel when drawing.
200     gl::DrawBufferMask mEmulatedAlphaAttachmentMask;
201 };
202 }  // namespace rx
203 
204 #endif  // LIBANGLE_RENDERER_VULKAN_FRAMEBUFFERVK_H_
205