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