xref: /aosp_15_r20/external/angle/src/libANGLE/renderer/vulkan/FramebufferVk.h (revision 8975f5c5ed3d1c378011245431ada316dfb6f244)
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;
getLayerCount()108     uint32_t getLayerCount() const { return mCurrentFramebufferDesc.getLayerCount(); }
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     angle::Result getFramebuffer(ContextVk *contextVk, vk::RenderPassFramebuffer *framebufferOut);
124 
hasDeferredClears()125     bool hasDeferredClears() const { return !mDeferredClears.empty(); }
hasDeferredDepthClear()126     bool hasDeferredDepthClear() const { return mDeferredClears.testDepth(); }
hasDeferredStencilClear()127     bool hasDeferredStencilClear() const { return mDeferredClears.testStencil(); }
128     angle::Result flushDepthStencilDeferredClear(ContextVk *contextVk,
129                                                  VkImageAspectFlagBits aspect);
130 
131     void switchToColorFramebufferFetchMode(ContextVk *contextVk, bool hasColorFramebufferFetch);
132 
133     bool updateLegacyDither(ContextVk *contextVk);
134 
setBackbuffer(WindowSurfaceVk * backbuffer)135     void setBackbuffer(WindowSurfaceVk *backbuffer) { mBackbuffer = backbuffer; }
getBackbuffer()136     WindowSurfaceVk *getBackbuffer() const { return mBackbuffer; }
137 
138     void releaseCurrentFramebuffer(ContextVk *contextVk);
139 
getLastRenderPassQueueSerial()140     const QueueSerial &getLastRenderPassQueueSerial() const { return mLastRenderPassQueueSerial; }
141 
hasAnyExternalAttachments()142     bool hasAnyExternalAttachments() const { return mIsExternalColorAttachments.any(); }
143 
hasFrontBufferUsage()144     bool hasFrontBufferUsage() const
145     {
146         return (mAttachmentHasFrontBufferUsage & mState.getColorAttachmentsMask()).any();
147     }
148 
isFoveationEnabled()149     bool isFoveationEnabled() { return mFoveationState.isFoveated(); }
150 
151   private:
152     enum class ClearWithCommand
153     {
154         Always,
155         OptimizeWithLoadOp,
156     };
157 
158     enum class RenderTargetImage
159     {
160         Attachment,
161         Resolve,
162         FragmentShadingRate,
163     };
164 
165     struct RenderTargetInfo
166     {
RenderTargetInfoRenderTargetInfo167         RenderTargetInfo() : renderTarget(nullptr), renderTargetImage(RenderTargetImage::Attachment)
168         {}
RenderTargetInfoRenderTargetInfo169         RenderTargetInfo(RenderTargetVk *renderTarget, RenderTargetImage renderTargetImage)
170             : renderTarget(renderTarget), renderTargetImage(renderTargetImage)
171         {}
172         RenderTargetVk *renderTarget;
173         RenderTargetImage renderTargetImage;
174     };
175 
176     // Returns the attachments to be used to create a framebuffer.  The views returned in
177     // |unpackedAttachments| are not necessarily packed, but the render targets in
178     // |packedRenderTargetsInfoOut| are.  In particular, the resolve attachment views need to stay
179     // sparse to be placed in |RenderPassFramebuffer|, but the calling function will have to pack
180     // them to match the render buffers before creating a framebuffer.
181     angle::Result getAttachmentsAndRenderTargets(
182         vk::Context *context,
183         vk::FramebufferAttachmentsVector<VkImageView> *unpackedAttachments,
184         vk::FramebufferAttachmentsVector<RenderTargetInfo> *packedRenderTargetsInfoOut);
185 
186     angle::Result createNewFramebuffer(
187         ContextVk *contextVk,
188         uint32_t framebufferWidth,
189         const uint32_t framebufferHeight,
190         const uint32_t framebufferLayers,
191         const vk::FramebufferAttachmentsVector<VkImageView> &unpackedAttachments,
192         const vk::FramebufferAttachmentsVector<RenderTargetInfo> &renderTargetsInfo);
193 
194     // The 'in' rectangles must be clipped to the scissor and FBO. The clipping is done in 'blit'.
195     angle::Result blitWithCommand(ContextVk *contextVk,
196                                   const gl::Rectangle &sourceArea,
197                                   const gl::Rectangle &destArea,
198                                   RenderTargetVk *readRenderTarget,
199                                   RenderTargetVk *drawRenderTarget,
200                                   GLenum filter,
201                                   bool colorBlit,
202                                   bool depthBlit,
203                                   bool stencilBlit,
204                                   bool flipX,
205                                   bool flipY);
206 
207     // Resolve color with subpass attachment
208     angle::Result resolveColorWithSubpass(ContextVk *contextVk,
209                                           const UtilsVk::BlitResolveParameters &params);
210 
211     // Resolve depth/stencil with subpass attachment
212     angle::Result resolveDepthStencilWithSubpass(ContextVk *contextVk,
213                                                  const UtilsVk::BlitResolveParameters &params,
214                                                  VkImageAspectFlags aspects);
215 
216     // Resolve color with vkCmdResolveImage
217     angle::Result resolveColorWithCommand(ContextVk *contextVk,
218                                           const UtilsVk::BlitResolveParameters &params,
219                                           vk::ImageHelper *srcImage);
220 
221     angle::Result clearImpl(const gl::Context *context,
222                             gl::DrawBufferMask clearColorBuffers,
223                             bool clearDepth,
224                             bool clearStencil,
225                             const VkClearColorValue &clearColorValue,
226                             const VkClearDepthStencilValue &clearDepthStencilValue);
227 
228     void mergeClearsWithDeferredClears(
229         gl::DrawBufferMask clearColorBuffers,
230         bool clearDepth,
231         bool clearStencil,
232         const gl::DrawBuffersArray<VkClearColorValue> &clearColorValues,
233         const VkClearDepthStencilValue &clearDepthStencilValue);
234     angle::Result clearWithDraw(ContextVk *contextVk,
235                                 const gl::Rectangle &clearArea,
236                                 gl::DrawBufferMask clearColorBuffers,
237                                 bool clearDepth,
238                                 bool clearStencil,
239                                 gl::BlendStateExt::ColorMaskStorage::Type colorMasks,
240                                 uint8_t stencilMask,
241                                 const gl::DrawBuffersArray<VkClearColorValue> &clearColorValues,
242                                 const VkClearDepthStencilValue &clearDepthStencilValue);
243     void restageDeferredClears(ContextVk *contextVk);
244     void restageDeferredClearsForReadFramebuffer(ContextVk *contextVk);
245     void restageDeferredClearsImpl(ContextVk *contextVk);
246     angle::Result flushDeferredClears(ContextVk *contextVk);
247     void clearWithCommand(ContextVk *contextVk,
248                           const gl::Rectangle &scissoredRenderArea,
249                           ClearWithCommand behavior,
250                           vk::ClearValuesArray *clears);
251     void clearWithLoadOp(ContextVk *contextVk);
252     void updateActiveColorMasks(size_t colorIndex, bool r, bool g, bool b, bool a);
253     void updateRenderPassDesc(ContextVk *contextVk);
254     angle::Result updateColorAttachment(const gl::Context *context, uint32_t colorIndex);
255     void updateColorAttachmentColorspace(gl::SrgbWriteControlMode srgbWriteControlMode);
256     angle::Result updateDepthStencilAttachment(const gl::Context *context);
257     void updateDepthStencilAttachmentSerial(ContextVk *contextVk);
258     angle::Result flushColorAttachmentUpdates(const gl::Context *context,
259                                               bool deferClears,
260                                               uint32_t colorIndex);
261     angle::Result flushDepthStencilAttachmentUpdates(const gl::Context *context, bool deferClears);
262     angle::Result invalidateImpl(ContextVk *contextVk,
263                                  size_t count,
264                                  const GLenum *attachments,
265                                  bool isSubInvalidate,
266                                  const gl::Rectangle &invalidateArea);
267 
268     RenderTargetVk *getReadPixelsRenderTarget(GLenum format) const;
269     VkImageAspectFlagBits getReadPixelsAspectFlags(GLenum format) const;
270 
271     VkClearValue getCorrectedColorClearValue(size_t colorIndexGL,
272                                              const VkClearColorValue &clearColor) const;
273 
274     void updateLayerCount();
275 
276     angle::Result ensureFragmentShadingRateImageAndViewInitialized(
277         ContextVk *contextVk,
278         const uint32_t fragmentShadingRateAttachmentWidth,
279         const uint32_t fragmentShadingRateAttachmentHeight);
280     angle::Result generateFragmentShadingRateWithCPU(
281         ContextVk *contextVk,
282         const uint32_t fragmentShadingRateWidth,
283         const uint32_t fragmentShadingRateHeight,
284         const uint32_t fragmentShadingRateBlockWidth,
285         const uint32_t fragmentShadingRateBlockHeight,
286         const uint32_t foveatedAttachmentWidth,
287         const uint32_t foveatedAttachmentHeight,
288         const std::vector<gl::FocalPoint> &activeFocalPoints);
289     angle::Result generateFragmentShadingRateWithCompute(
290         ContextVk *contextVk,
291         const uint32_t fragmentShadingRateWidth,
292         const uint32_t fragmentShadingRateHeight,
293         const uint32_t fragmentShadingRateBlockWidth,
294         const uint32_t fragmentShadingRateBlockHeight,
295         const uint32_t foveatedAttachmentWidth,
296         const uint32_t foveatedAttachmentHeight,
297         const std::vector<gl::FocalPoint> &activeFocalPoints);
298     angle::Result updateFragmentShadingRateAttachment(ContextVk *contextVk,
299                                                       const gl::FoveationState &foveationState,
300                                                       const gl::Extents &foveatedAttachmentSize);
301     angle::Result updateFoveationState(ContextVk *contextVk,
302                                        const gl::FoveationState &newFoveationState,
303                                        const gl::Extents &foveatedAttachmentSize);
304 
305     void insertCache(ContextVk *contextVk,
306                      const vk::FramebufferDesc &desc,
307                      vk::FramebufferHelper &&newFramebuffer);
308 
309     WindowSurfaceVk *mBackbuffer;
310 
311     vk::RenderPassDesc mRenderPassDesc;
312     RenderTargetCache<RenderTargetVk> mRenderTargetCache;
313 
314     // This variable is used to quickly compute if we need to do a masked clear. If a color
315     // channel is masked out, we check against the Framebuffer Attachments (RenderTargets) to see
316     // if the masked out channel is present in any of the attachments.
317     gl::BlendStateExt::ColorMaskStorage::Type mActiveColorComponentMasksForClear;
318 
319     // When we draw to the framebuffer, and the real format has an alpha channel but the format of
320     // the framebuffer does not, we need to mask out the alpha channel. This DrawBufferMask will
321     // contain the mask to apply to the alpha channel when drawing.
322     gl::DrawBufferMask mEmulatedAlphaAttachmentMask;
323 
324     // mCurrentFramebufferDesc is used to detect framebuffer changes using its serials. Therefore,
325     // it must be maintained even when using the imageless framebuffer extension.
326     vk::FramebufferDesc mCurrentFramebufferDesc;
327 
328     // The framebuffer cache actually owns the Framebuffer object and manages its lifetime. We just
329     // store the current VkFramebuffer handle here that associated with mCurrentFramebufferDesc.
330     vk::Framebuffer mCurrentFramebuffer;
331 
332     vk::ClearValuesArray mDeferredClears;
333 
334     // Whether any of the color attachments are an external image such as dmabuf, AHB etc.  In such
335     // cases, some optimizations are disabled such as deferred clears because the results need to be
336     // made externally available.
337     gl::DrawBufferMask mIsExternalColorAttachments;
338     gl::DrawBufferMask mAttachmentHasFrontBufferUsage;
339 
340     bool mIsCurrentFramebufferCached;
341     bool mIsYUVResolve;
342 
343     gl::FoveationState mFoveationState;
344     vk::ImageHelper mFragmentShadingRateImage;
345     vk::ImageViewHelper mFragmentShadingRateImageView;
346 
347     // Serial of the render pass this framebuffer has opened, if any.
348     QueueSerial mLastRenderPassQueueSerial;
349 };
350 }  // namespace rx
351 
352 #endif  // LIBANGLE_RENDERER_VULKAN_FRAMEBUFFERVK_H_
353