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