xref: /aosp_15_r20/external/angle/src/libANGLE/renderer/metal/FrameBufferMtl.h (revision 8975f5c5ed3d1c378011245431ada316dfb6f244)
1 //
2 // Copyright 2019 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 // FrameBufferMtl.h:
7 //    Defines the class interface for FrameBufferMtl, implementing FrameBufferImpl.
8 //
9 
10 #ifndef LIBANGLE_RENDERER_METAL_FRAMEBUFFERMTL_H_
11 #define LIBANGLE_RENDERER_METAL_FRAMEBUFFERMTL_H_
12 
13 #import <Metal/Metal.h>
14 
15 #include "common/FixedVector.h"
16 #include "libANGLE/renderer/FramebufferImpl.h"
17 #include "libANGLE/renderer/metal/RenderTargetMtl.h"
18 #include "libANGLE/renderer/metal/mtl_render_utils.h"
19 
20 namespace rx
21 {
22 namespace mtl
23 {
24 class RenderCommandEncoder;
25 }  // namespace mtl
26 class ContextMtl;
27 class SurfaceMtl;
28 
29 class FramebufferMtl : public FramebufferImpl
30 {
31   public:
32     explicit FramebufferMtl(const gl::FramebufferState &state, ContextMtl *context, bool flipY);
33     ~FramebufferMtl() override;
34     void destroy(const gl::Context *context) override;
35 
36     angle::Result discard(const gl::Context *context,
37                           size_t count,
38                           const GLenum *attachments) override;
39     angle::Result invalidate(const gl::Context *context,
40                              size_t count,
41                              const GLenum *attachments) override;
42     angle::Result invalidateSub(const gl::Context *context,
43                                 size_t count,
44                                 const GLenum *attachments,
45                                 const gl::Rectangle &area) override;
46 
47     angle::Result clear(const gl::Context *context, GLbitfield mask) override;
48     angle::Result clearBufferfv(const gl::Context *context,
49                                 GLenum buffer,
50                                 GLint drawbuffer,
51                                 const GLfloat *values) override;
52     angle::Result clearBufferuiv(const gl::Context *context,
53                                  GLenum buffer,
54                                  GLint drawbuffer,
55                                  const GLuint *values) override;
56     angle::Result clearBufferiv(const gl::Context *context,
57                                 GLenum buffer,
58                                 GLint drawbuffer,
59                                 const GLint *values) override;
60     angle::Result clearBufferfi(const gl::Context *context,
61                                 GLenum buffer,
62                                 GLint drawbuffer,
63                                 GLfloat depth,
64                                 GLint stencil) override;
65 
66     const gl::InternalFormat &getImplementationColorReadFormat(
67         const gl::Context *context) const override;
68     angle::Result readPixels(const gl::Context *context,
69                              const gl::Rectangle &area,
70                              GLenum format,
71                              GLenum type,
72                              const gl::PixelPackState &pack,
73                              gl::Buffer *packBuffer,
74                              void *pixels) override;
75 
76     angle::Result blit(const gl::Context *context,
77                        const gl::Rectangle &sourceArea,
78                        const gl::Rectangle &destArea,
79                        GLbitfield mask,
80                        GLenum filter) override;
81 
82     gl::FramebufferStatus checkStatus(const gl::Context *context) const override;
83 
84     angle::Result syncState(const gl::Context *context,
85                             GLenum binding,
86                             const gl::Framebuffer::DirtyBits &dirtyBits,
87                             gl::Command command) override;
88 
89     angle::Result getSamplePosition(const gl::Context *context,
90                                     size_t index,
91                                     GLfloat *xy) const override;
92 
93     RenderTargetMtl *getColorReadRenderTarget(const gl::Context *context) const;
getDepthRenderTarget()94     RenderTargetMtl *getDepthRenderTarget() const { return mDepthRenderTarget; }
getStencilRenderTarget()95     RenderTargetMtl *getStencilRenderTarget() const { return mStencilRenderTarget; }
96 
setFlipY(bool flipY)97     void setFlipY(bool flipY) { mFlipY = flipY; }
flipY()98     bool flipY() const { return mFlipY; }
99 
100     gl::Rectangle getCompleteRenderArea() const;
101     int getSamples() const;
getAttachedBackbuffer()102     WindowSurfaceMtl *getAttachedBackbuffer() const { return mBackbuffer; }
103 
104     bool renderPassHasStarted(ContextMtl *contextMtl) const;
renderPassHasDefaultWidthOrHeight()105     bool renderPassHasDefaultWidthOrHeight() const
106     {
107         return mRenderPassDesc.defaultWidth > 0 || mRenderPassDesc.defaultHeight > 0;
108     }
109     angle::Result ensureRenderPassStarted(const gl::Context *context,
110                                           mtl::RenderCommandEncoder **encoderOut);
111 
112     // Call this to notify FramebufferMtl whenever its render pass has started.
113     void onStartedDrawingToFrameBuffer(const gl::Context *context);
114     void onFrameEnd(const gl::Context *context);
115 
116     // The actual area will be adjusted based on framebuffer flipping property.
117     gl::Rectangle getCorrectFlippedReadArea(const gl::Context *context,
118                                             const gl::Rectangle &glArea) const;
119 
120     // NOTE: this method doesn't do the flipping of area. Caller must do it if needed before
121     // callling this. See getReadPixelsArea().
122     angle::Result readPixelsImpl(const gl::Context *context,
123                                  const gl::Rectangle &area,
124                                  const PackPixelsParams &packPixelsParams,
125                                  const RenderTargetMtl *renderTarget,
126                                  uint8_t *pixels) const;
setBackbuffer(WindowSurfaceMtl * backbuffer)127     void setBackbuffer(WindowSurfaceMtl *backbuffer) { mBackbuffer = backbuffer; }
getBackbuffer()128     WindowSurfaceMtl *getBackbuffer() const { return mBackbuffer; }
129 
130   private:
131     void reset();
132     angle::Result invalidateImpl(const gl::Context *context,
133                                  size_t count,
134                                  const GLenum *attachments);
135     angle::Result blitWithDraw(const gl::Context *context,
136                                FramebufferMtl *srcFrameBuffer,
137                                bool blitColorBuffer,
138                                bool blitDepthBuffer,
139                                bool blitStencilBuffer,
140                                GLenum filter,
141                                const mtl::BlitParams &baseParams);
142     angle::Result clearImpl(const gl::Context *context,
143                             gl::DrawBufferMask clearColorBuffers,
144                             mtl::ClearRectParams *clearOpts);
145 
146     angle::Result clearWithLoadOp(const gl::Context *context,
147                                   gl::DrawBufferMask clearColorBuffers,
148                                   const mtl::ClearRectParams &clearOpts);
149 
150     angle::Result clearWithLoadOpRenderPassNotStarted(const gl::Context *context,
151                                                       gl::DrawBufferMask clearColorBuffers,
152                                                       const mtl::ClearRectParams &clearOpts);
153 
154     angle::Result clearWithLoadOpRenderPassStarted(const gl::Context *context,
155                                                    gl::DrawBufferMask clearColorBuffers,
156                                                    const mtl::ClearRectParams &clearOpts,
157                                                    mtl::RenderCommandEncoder *encoder);
158 
159     angle::Result clearWithDraw(const gl::Context *context,
160                                 gl::DrawBufferMask clearColorBuffers,
161                                 const mtl::ClearRectParams &clearOpts);
162 
163     // Initialize load store options for a render pass's first start (i.e. not render pass resuming
164     // from interruptions such as those caused by a conversion compute pass)
165     void setLoadStoreActionOnRenderPassFirstStart(mtl::RenderPassAttachmentDesc *attachmentOut,
166                                                   const bool forceDepthStencilMultisampleLoad);
167 
168     // Fill RenderPassDesc with relevant attachment's info from GL front end.
169     angle::Result prepareRenderPass(const gl::Context *context,
170                                     mtl::RenderPassDesc *descOut,
171                                     gl::Command command);
172 
173     // Check if a render pass specified by the given RenderPassDesc has started or not, if not this
174     // method will start the render pass and return its render encoder.
175     angle::Result ensureRenderPassStarted(const gl::Context *context,
176                                           const mtl::RenderPassDesc &desc,
177                                           mtl::RenderCommandEncoder **encoderOut);
178 
179     angle::Result updateColorRenderTarget(const gl::Context *context, size_t colorIndexGL);
180     angle::Result updateDepthRenderTarget(const gl::Context *context);
181     angle::Result updateStencilRenderTarget(const gl::Context *context);
182     angle::Result updateCachedRenderTarget(const gl::Context *context,
183                                            const gl::FramebufferAttachment *attachment,
184                                            RenderTargetMtl **cachedRenderTarget);
185 
186     angle::Result readPixelsToPBO(const gl::Context *context,
187                                   const gl::Rectangle &area,
188                                   const PackPixelsParams &packPixelsParams,
189                                   const RenderTargetMtl *renderTarget) const;
190 
191     angle::Result readPixelsToBuffer(const gl::Context *context,
192                                      const gl::Rectangle &area,
193                                      const RenderTargetMtl *renderTarget,
194                                      bool reverseRowOrder,
195                                      const angle::Format &dstAngleFormat,
196                                      uint32_t dstBufferOffset,
197                                      uint32_t dstBufferRowPitch,
198                                      const mtl::BufferRef *dstBuffer) const;
199 
200     bool totalBitsUsedIsLessThanOrEqualToMaxBitsSupported(const gl::Context *context) const;
201 
202     RenderTargetMtl *getColorReadRenderTargetNoCache(const gl::Context *context) const;
203     angle::Result prepareForUse(const gl::Context *context) const;
204 
205     // Perform unresolve step for loading into memoryless MS attachments.
206     angle::Result unresolveIfNeeded(const gl::Context *context, mtl::RenderCommandEncoder *encoder);
207 
208     // NOTE: we cannot use RenderTargetCache here because it doesn't support separate
209     // depth & stencil attachments as of now. Separate depth & stencil could be useful to
210     // save spaces on iOS devices. See doc/PackedDepthStencilSupport.md.
211     angle::FixedVector<RenderTargetMtl *, mtl::kMaxRenderTargets> mColorRenderTargets;
212     RenderTargetMtl *mDepthRenderTarget   = nullptr;
213     RenderTargetMtl *mStencilRenderTarget = nullptr;
214     mtl::RenderPassDesc mRenderPassDesc;
215 
216     const mtl::Format *mRenderPassFirstColorAttachmentFormat = nullptr;
217     bool mRenderPassAttachmentsSameColorType                 = false;
218 
219     // Flag indicating the render pass start is a clean start or a resume from interruption such
220     // as by a compute pass.
221     bool mRenderPassCleanStart = false;
222 
223     WindowSurfaceMtl *mBackbuffer = nullptr;
224     bool mFlipY                   = false;
225 
226     mtl::BufferRef mReadPixelBuffer;
227 
228     uint64_t mStartedRenderEncoderSerial = 0;
229 };
230 }  // namespace rx
231 
232 #endif /* LIBANGLE_RENDERER_METAL_FRAMEBUFFERMTL_H */
233