• 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/SurfaceVk.h"
18 #include "libANGLE/renderer/vulkan/UtilsVk.h"
19 #include "libANGLE/renderer/vulkan/vk_cache_utils.h"
20 #include "libANGLE/renderer/vulkan/vk_helpers.h"
21 #include "libANGLE/renderer/vulkan/vk_resource.h"
22 
23 namespace rx
24 {
25 class RenderTargetVk;
26 class WindowSurfaceVk;
27 
28 class FramebufferVk : public FramebufferImpl
29 {
30   public:
31     FramebufferVk(vk::Renderer *renderer, const gl::FramebufferState &state);
32     ~FramebufferVk() override;
33     void destroy(const gl::Context *context) override;
34 
35     angle::Result discard(const gl::Context *context,
36                           size_t count,
37                           const GLenum *attachments) override;
38     angle::Result invalidate(const gl::Context *context,
39                              size_t count,
40                              const GLenum *attachments) override;
41     angle::Result invalidateSub(const gl::Context *context,
42                                 size_t count,
43                                 const GLenum *attachments,
44                                 const gl::Rectangle &area) override;
45 
46     angle::Result clear(const gl::Context *context, GLbitfield mask) override;
47     angle::Result clearBufferfv(const gl::Context *context,
48                                 GLenum buffer,
49                                 GLint drawbuffer,
50                                 const GLfloat *values) override;
51     angle::Result clearBufferuiv(const gl::Context *context,
52                                  GLenum buffer,
53                                  GLint drawbuffer,
54                                  const GLuint *values) override;
55     angle::Result clearBufferiv(const gl::Context *context,
56                                 GLenum buffer,
57                                 GLint drawbuffer,
58                                 const GLint *values) override;
59     angle::Result clearBufferfi(const gl::Context *context,
60                                 GLenum buffer,
61                                 GLint drawbuffer,
62                                 GLfloat depth,
63                                 GLint stencil) override;
64 
65     const gl::InternalFormat &getImplementationColorReadFormat(
66         const gl::Context *context) const override;
67     angle::Result readPixels(const gl::Context *context,
68                              const gl::Rectangle &area,
69                              GLenum format,
70                              GLenum type,
71                              const gl::PixelPackState &pack,
72                              gl::Buffer *packBuffer,
73                              void *pixels) override;
74 
75     angle::Result blit(const gl::Context *context,
76                        const gl::Rectangle &sourceArea,
77                        const gl::Rectangle &destArea,
78                        GLbitfield mask,
79                        GLenum filter) override;
80 
81     gl::FramebufferStatus checkStatus(const gl::Context *context) const override;
82 
83     angle::Result syncState(const gl::Context *context,
84                             GLenum binding,
85                             const gl::Framebuffer::DirtyBits &dirtyBits,
86                             gl::Command command) override;
87 
88     angle::Result getSamplePosition(const gl::Context *context,
89                                     size_t index,
90                                     GLfloat *xy) const override;
91     RenderTargetVk *getDepthStencilRenderTarget() const;
92 
93     // Internal helper function for readPixels operations.
94     angle::Result readPixelsImpl(ContextVk *contextVk,
95                                  const gl::Rectangle &area,
96                                  const PackPixelsParams &packPixelsParams,
97                                  VkImageAspectFlagBits copyAspectFlags,
98                                  RenderTargetVk *renderTarget,
99                                  void *pixels);
100 
101     gl::Extents getReadImageExtents() const;
102     gl::Rectangle getNonRotatedCompleteRenderArea() const;
103     gl::Rectangle getRotatedCompleteRenderArea(ContextVk *contextVk) const;
104     gl::Rectangle getRotatedScissoredRenderArea(ContextVk *contextVk) const;
105     // Returns render area with deferred clears in consideration. When deferred clear is used
106     // in the render pass, the render area must cover the whole framebuffer.
107     gl::Rectangle getRenderArea(ContextVk *contextVk) const;
108 
109     const gl::DrawBufferMask &getEmulatedAlphaAttachmentMask() const;
110     RenderTargetVk *getColorDrawRenderTarget(size_t colorIndexGL) const;
111     RenderTargetVk *getColorReadRenderTarget() const;
112 
113     angle::Result startNewRenderPass(ContextVk *contextVk,
114                                      const gl::Rectangle &renderArea,
115                                      vk::RenderPassCommandBuffer **commandBufferOut,
116                                      bool *renderPassDescChangedOut);
117 
118     GLint getSamples() const;
119 
getRenderPassDesc()120     const vk::RenderPassDesc &getRenderPassDesc() const { return mRenderPassDesc; }
121 
122     angle::Result getFramebuffer(ContextVk *contextVk, vk::RenderPassFramebuffer *framebufferOut);
123 
hasDeferredClears()124     bool hasDeferredClears() const { return !mDeferredClears.empty(); }
125     angle::Result flushDeferredClears(ContextVk *contextVk);
126 
127     void switchToFramebufferFetchMode(ContextVk *contextVk, bool hasFramebufferFetch);
128 
129     bool updateLegacyDither(ContextVk *contextVk);
130 
setBackbuffer(WindowSurfaceVk * backbuffer)131     void setBackbuffer(WindowSurfaceVk *backbuffer) { mBackbuffer = backbuffer; }
getBackbuffer()132     WindowSurfaceVk *getBackbuffer() const { return mBackbuffer; }
133 
134     void releaseCurrentFramebuffer(ContextVk *contextVk);
135 
getLastRenderPassQueueSerial()136     const QueueSerial &getLastRenderPassQueueSerial() const { return mLastRenderPassQueueSerial; }
137 
hasAnyExternalAttachments()138     bool hasAnyExternalAttachments() const { return mIsExternalColorAttachments.any(); }
139 
hasFrontBufferUsage()140     bool hasFrontBufferUsage() const
141     {
142         return (mAttachmentHasFrontBufferUsage & mState.getColorAttachmentsMask()).any();
143     }
144 
isFoveationEnabled()145     bool isFoveationEnabled() { return mFoveationState.isFoveated(); }
146 
147   private:
148     enum class ClearWithCommand
149     {
150         Always,
151         OptimizeWithLoadOp,
152     };
153 
154     enum class RenderTargetImage
155     {
156         Attachment,
157         Resolve,
158         FragmentShadingRate,
159     };
160 
161     struct RenderTargetInfo
162     {
RenderTargetInfoRenderTargetInfo163         RenderTargetInfo() : renderTarget(nullptr), renderTargetImage(RenderTargetImage::Attachment)
164         {}
RenderTargetInfoRenderTargetInfo165         RenderTargetInfo(RenderTargetVk *renderTarget, RenderTargetImage renderTargetImage)
166             : renderTarget(renderTarget), renderTargetImage(renderTargetImage)
167         {}
168         RenderTargetVk *renderTarget;
169         RenderTargetImage renderTargetImage;
170     };
171 
172     // Returns the attachments to be used to create a framebuffer.  The views returned in
173     // |unpackedAttachments| are not necessarily packed, but the render targets in
174     // |packedRenderTargetsInfoOut| are.  In particular, the resolve attachment views need to stay
175     // sparse to be placed in |RenderPassFramebuffer|, but the calling function will have to pack
176     // them to match the render buffers before creating a framebuffer.
177     angle::Result getAttachmentsAndRenderTargets(
178         vk::Context *context,
179         vk::FramebufferAttachmentsVector<VkImageView> *unpackedAttachments,
180         vk::FramebufferAttachmentsVector<RenderTargetInfo> *packedRenderTargetsInfoOut);
181 
182     angle::Result createNewFramebuffer(
183         ContextVk *contextVk,
184         uint32_t framebufferWidth,
185         const uint32_t framebufferHeight,
186         const uint32_t framebufferLayers,
187         const vk::FramebufferAttachmentsVector<VkImageView> &unpackedAttachments,
188         const vk::FramebufferAttachmentsVector<RenderTargetInfo> &renderTargetsInfo);
189 
190     // The 'in' rectangles must be clipped to the scissor and FBO. The clipping is done in 'blit'.
191     angle::Result blitWithCommand(ContextVk *contextVk,
192                                   const gl::Rectangle &sourceArea,
193                                   const gl::Rectangle &destArea,
194                                   RenderTargetVk *readRenderTarget,
195                                   RenderTargetVk *drawRenderTarget,
196                                   GLenum filter,
197                                   bool colorBlit,
198                                   bool depthBlit,
199                                   bool stencilBlit,
200                                   bool flipX,
201                                   bool flipY);
202 
203     // Resolve color with subpass attachment
204     angle::Result resolveColorWithSubpass(ContextVk *contextVk,
205                                           const UtilsVk::BlitResolveParameters &params);
206 
207     // Resolve depth/stencil with subpass attachment
208     angle::Result resolveDepthStencilWithSubpass(ContextVk *contextVk,
209                                                  const UtilsVk::BlitResolveParameters &params,
210                                                  VkImageAspectFlags aspects);
211 
212     // Resolve color with vkCmdResolveImage
213     angle::Result resolveColorWithCommand(ContextVk *contextVk,
214                                           const UtilsVk::BlitResolveParameters &params,
215                                           vk::ImageHelper *srcImage);
216 
217     angle::Result clearImpl(const gl::Context *context,
218                             gl::DrawBufferMask clearColorBuffers,
219                             bool clearDepth,
220                             bool clearStencil,
221                             const VkClearColorValue &clearColorValue,
222                             const VkClearDepthStencilValue &clearDepthStencilValue);
223 
224     void mergeClearsWithDeferredClears(
225         gl::DrawBufferMask clearColorBuffers,
226         bool clearDepth,
227         bool clearStencil,
228         const gl::DrawBuffersArray<VkClearColorValue> &clearColorValues,
229         const VkClearDepthStencilValue &clearDepthStencilValue);
230     angle::Result clearWithDraw(ContextVk *contextVk,
231                                 const gl::Rectangle &clearArea,
232                                 gl::DrawBufferMask clearColorBuffers,
233                                 bool clearDepth,
234                                 bool clearStencil,
235                                 gl::BlendStateExt::ColorMaskStorage::Type colorMasks,
236                                 uint8_t stencilMask,
237                                 const gl::DrawBuffersArray<VkClearColorValue> &clearColorValues,
238                                 const VkClearDepthStencilValue &clearDepthStencilValue);
239     void restageDeferredClears(ContextVk *contextVk);
240     void restageDeferredClearsForReadFramebuffer(ContextVk *contextVk);
241     void restageDeferredClearsImpl(ContextVk *contextVk);
242     void clearWithCommand(ContextVk *contextVk,
243                           const gl::Rectangle &scissoredRenderArea,
244                           ClearWithCommand behavior,
245                           vk::ClearValuesArray *clears);
246     void clearWithLoadOp(ContextVk *contextVk);
247     void updateActiveColorMasks(size_t colorIndex, bool r, bool g, bool b, bool a);
248     void updateRenderPassDesc(ContextVk *contextVk);
249     angle::Result updateColorAttachment(const gl::Context *context, uint32_t colorIndex);
250     angle::Result updateDepthStencilAttachment(const gl::Context *context);
251     void updateDepthStencilAttachmentSerial(ContextVk *contextVk);
252     angle::Result flushColorAttachmentUpdates(const gl::Context *context,
253                                               bool deferClears,
254                                               uint32_t colorIndex);
255     angle::Result flushDepthStencilAttachmentUpdates(const gl::Context *context, bool deferClears);
256     angle::Result invalidateImpl(ContextVk *contextVk,
257                                  size_t count,
258                                  const GLenum *attachments,
259                                  bool isSubInvalidate,
260                                  const gl::Rectangle &invalidateArea);
261 
262     RenderTargetVk *getReadPixelsRenderTarget(GLenum format) const;
263     VkImageAspectFlagBits getReadPixelsAspectFlags(GLenum format) const;
264 
265     VkClearValue getCorrectedColorClearValue(size_t colorIndexGL,
266                                              const VkClearColorValue &clearColor) const;
267 
268     void updateLayerCount();
269 
270     angle::Result ensureFragmentShadingRateImageAndViewInitialized(
271         ContextVk *contextVk,
272         const uint32_t fragmentShadingRateAttachmentWidth,
273         const uint32_t fragmentShadingRateAttachmentHeight);
274     angle::Result generateFragmentShadingRateWithCPU(
275         ContextVk *contextVk,
276         const bool isGainZero,
277         const uint32_t fragmentShadingRateWidth,
278         const uint32_t fragmentShadingRateHeight,
279         const uint32_t fragmentShadingRateBlockWidth,
280         const uint32_t fragmentShadingRateBlockHeight,
281         const uint32_t foveatedAttachmentWidth,
282         const uint32_t foveatedAttachmentHeight,
283         const std::vector<gl::FocalPoint> &activeFocalPoints);
284     angle::Result updateFragmentShadingRateAttachment(ContextVk *contextVk,
285                                                       const gl::FoveationState &foveationState,
286                                                       const gl::Extents &foveatedAttachmentSize);
287     angle::Result updateFoveationState(ContextVk *contextVk,
288                                        const gl::FoveationState &newFoveationState,
289                                        const gl::Extents &foveatedAttachmentSize);
290 
291     void insertCache(ContextVk *contextVk,
292                      const vk::FramebufferDesc &desc,
293                      vk::FramebufferHelper &&newFramebuffer);
294 
295     WindowSurfaceVk *mBackbuffer;
296 
297     vk::RenderPassDesc mRenderPassDesc;
298     RenderTargetCache<RenderTargetVk> mRenderTargetCache;
299 
300     // This variable is used to quickly compute if we need to do a masked clear. If a color
301     // channel is masked out, we check against the Framebuffer Attachments (RenderTargets) to see
302     // if the masked out channel is present in any of the attachments.
303     gl::BlendStateExt::ColorMaskStorage::Type mActiveColorComponentMasksForClear;
304 
305     // When we draw to the framebuffer, and the real format has an alpha channel but the format of
306     // the framebuffer does not, we need to mask out the alpha channel. This DrawBufferMask will
307     // contain the mask to apply to the alpha channel when drawing.
308     gl::DrawBufferMask mEmulatedAlphaAttachmentMask;
309 
310     // mCurrentFramebufferDesc is used to detect framebuffer changes using its serials. Therefore,
311     // it must be maintained even when using the imageless framebuffer extension.
312     vk::FramebufferDesc mCurrentFramebufferDesc;
313 
314     // The framebuffer cache actually owns the Framebuffer object and manages its lifetime. We just
315     // store the current VkFramebuffer handle here that associated with mCurrentFramebufferDesc.
316     vk::Framebuffer mCurrentFramebuffer;
317 
318     vk::ClearValuesArray mDeferredClears;
319 
320     // Whether any of the color attachments are an external image such as dmabuf, AHB etc.  In such
321     // cases, some optimizations are disabled such as deferred clears because the results need to be
322     // made externally available.
323     gl::DrawBufferMask mIsExternalColorAttachments;
324     gl::DrawBufferMask mAttachmentHasFrontBufferUsage;
325 
326     bool mIsCurrentFramebufferCached;
327     bool mIsYUVResolve;
328 
329     gl::FoveationState mFoveationState;
330     vk::ImageHelper mFragmentShadingRateImage;
331     vk::ImageViewHelper mFragmentShadingRateImageView;
332 
333     // Serial of the render pass this framebuffer has opened, if any.
334     QueueSerial mLastRenderPassQueueSerial;
335 };
336 }  // namespace rx
337 
338 #endif  // LIBANGLE_RENDERER_VULKAN_FRAMEBUFFERVK_H_
339