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