diff --git a/scripts/code_generation_hashes/Metal_format_table.json b/scripts/code_generation_hashes/Metal_format_table.json index 056dbdefa6..d516b5b8f4 100644 --- a/scripts/code_generation_hashes/Metal_format_table.json +++ b/scripts/code_generation_hashes/Metal_format_table.json @@ -4,9 +4,9 @@ "src/libANGLE/renderer/angle_format_map.json": "bca5e686001f6dd0af306af234a36677", "src/libANGLE/renderer/metal/gen_mtl_format_table.py": - "7e8db284f892a6bb1377ea7fb498d484", + "4c7af4111f23f6bc6424b05859aea47b", "src/libANGLE/renderer/metal/mtl_format_map.json": - "57b49eb11a5401824c256ec3475b6eed", + "86ce732999366526c9b7b248ea09c91f", "src/libANGLE/renderer/metal/mtl_format_table_autogen.mm": - "d998f8645c7bc92695652346142c1c93" + "35ee19e595ad95f6f3a36988ad5ffd28" } \ No newline at end of file diff --git a/src/libANGLE/renderer/metal/ContextMtl.h b/src/libANGLE/renderer/metal/ContextMtl.h index 053aa7be2c..c8eed54fe2 100644 --- a/src/libANGLE/renderer/metal/ContextMtl.h +++ b/src/libANGLE/renderer/metal/ContextMtl.h @@ -29,7 +29,7 @@ class FramebufferMtl; class VertexArrayMtl; class ProgramMtl; class RenderTargetMtl; -class SurfaceMtl; +class WindowSurfaceMtl; class TransformFeedbackMtl; class ContextMtl : public ContextImpl, public mtl::Context @@ -211,7 +211,7 @@ class ContextMtl : public ContextImpl, public mtl::Context void onDrawFrameBufferChangedState(const gl::Context *context, FramebufferMtl *framebuffer, bool renderPassChanged); - void onBackbufferResized(const gl::Context *context, SurfaceMtl *backbuffer); + void onBackbufferResized(const gl::Context *context, WindowSurfaceMtl *backbuffer); // Invoke by QueryMtl angle::Result onOcclusionQueryBegan(const gl::Context *context, QueryMtl *query); diff --git a/src/libANGLE/renderer/metal/ContextMtl.mm b/src/libANGLE/renderer/metal/ContextMtl.mm index 9e10f6a538..a9aa77affa 100644 --- a/src/libANGLE/renderer/metal/ContextMtl.mm +++ b/src/libANGLE/renderer/metal/ContextMtl.mm @@ -1691,7 +1691,7 @@ bool IsTransformFeedbackOnly(const gl::State &glState) } } -void ContextMtl::onBackbufferResized(const gl::Context *context, SurfaceMtl *backbuffer) +void ContextMtl::onBackbufferResized(const gl::Context *context, WindowSurfaceMtl *backbuffer) { const gl::State &glState = getState(); FramebufferMtl *framebuffer = mtl::GetImpl(glState.getDrawFramebuffer()); diff --git a/src/libANGLE/renderer/metal/DisplayMtl.mm b/src/libANGLE/renderer/metal/DisplayMtl.mm index 2f5d560000..c46829a50b 100644 --- a/src/libANGLE/renderer/metal/DisplayMtl.mm +++ b/src/libANGLE/renderer/metal/DisplayMtl.mm @@ -183,14 +183,13 @@ void generateExtensions(egl::DeviceExtensions *outExtensions) const override EGLNativeWindowType window, const egl::AttributeMap &attribs) { - return new SurfaceMtl(this, state, window, attribs); + return new WindowSurfaceMtl(this, state, window, attribs); } SurfaceImpl *DisplayMtl::createPbufferSurface(const egl::SurfaceState &state, const egl::AttributeMap &attribs) { - UNIMPLEMENTED(); - return static_cast(0); + return new PBufferSurfaceMtl(this, state, attribs); } SurfaceImpl *DisplayMtl::createPbufferFromClientBuffer(const egl::SurfaceState &state, @@ -336,9 +335,9 @@ void generateExtensions(egl::DeviceExtensions *outExtensions) const override config.sampleBuffers = 0; config.level = 0; config.bindToTextureRGB = EGL_FALSE; - config.bindToTextureRGBA = EGL_FALSE; + config.bindToTextureRGBA = EGL_TRUE; - config.surfaceType = EGL_WINDOW_BIT | EGL_SWAP_BEHAVIOR_PRESERVED_BIT; + config.surfaceType = EGL_WINDOW_BIT | EGL_PBUFFER_BIT | EGL_SWAP_BEHAVIOR_PRESERVED_BIT; #if TARGET_OS_OSX || TARGET_OS_MACCATALYST config.minSwapInterval = 0; @@ -475,7 +474,7 @@ void generateExtensions(egl::DeviceExtensions *outExtensions) const override mNativeCaps.maxElementIndex = std::numeric_limits::max() - 1; mNativeCaps.max3DTextureSize = 2048; #if TARGET_OS_OSX || TARGET_OS_MACCATALYST - mNativeCaps.max2DTextureSize = 16384; + mNativeCaps.max2DTextureSize = 16384; // On macOS exclude [[position]] from maxVaryingVectors. mNativeCaps.maxVaryingVectors = 31 - 1; mNativeCaps.maxVertexOutputComponents = mNativeCaps.maxFragmentInputComponents = 124 - 4; @@ -504,11 +503,11 @@ void generateExtensions(egl::DeviceExtensions *outExtensions) const override // on Intel and 64 on AMD for now. if ([mMetalDevice.get().name rangeOfString:@"Intel"].location != NSNotFound) { - mNativeCaps.maxAliasedPointSize = 255; + mNativeCaps.maxAliasedPointSize = 255; } else { - mNativeCaps.maxAliasedPointSize = 64; + mNativeCaps.maxAliasedPointSize = 64; } mNativeCaps.minAliasedLineWidth = 1.0f; diff --git a/src/libANGLE/renderer/metal/FrameBufferMtl.h b/src/libANGLE/renderer/metal/FrameBufferMtl.h index 08c4c0a614..0702c59e50 100644 --- a/src/libANGLE/renderer/metal/FrameBufferMtl.h +++ b/src/libANGLE/renderer/metal/FrameBufferMtl.h @@ -23,12 +23,14 @@ namespace mtl class RenderCommandEncoder; } // namespace mtl class ContextMtl; -class SurfaceMtl; +class WindowSurfaceMtl; class FramebufferMtl : public FramebufferImpl { public: - explicit FramebufferMtl(const gl::FramebufferState &state, bool flipY, SurfaceMtl *backbuffer); + explicit FramebufferMtl(const gl::FramebufferState &state, + bool flipY, + WindowSurfaceMtl *backbuffer); ~FramebufferMtl() override; void destroy(const gl::Context *context) override; @@ -93,7 +95,7 @@ class FramebufferMtl : public FramebufferImpl gl::Rectangle getCompleteRenderArea() const; int getSamples() const; - SurfaceMtl *getAttachedBackbuffer() const { return mBackbuffer; } + WindowSurfaceMtl *getAttachedBackbuffer() const { return mBackbuffer; } bool renderPassHasStarted(ContextMtl *contextMtl) const; mtl::RenderCommandEncoder *ensureRenderPassStarted(const gl::Context *context); @@ -203,8 +205,8 @@ class FramebufferMtl : public FramebufferImpl // as by a compute pass. bool mRenderPassCleanStart = false; - SurfaceMtl *mBackbuffer = nullptr; - const bool mFlipY = false; + WindowSurfaceMtl *mBackbuffer = nullptr; + const bool mFlipY = false; mtl::BufferRef mReadPixelBuffer; }; diff --git a/src/libANGLE/renderer/metal/FrameBufferMtl.mm b/src/libANGLE/renderer/metal/FrameBufferMtl.mm index 88e03aded8..4966a5620b 100644 --- a/src/libANGLE/renderer/metal/FrameBufferMtl.mm +++ b/src/libANGLE/renderer/metal/FrameBufferMtl.mm @@ -49,7 +49,7 @@ // FramebufferMtl implementation FramebufferMtl::FramebufferMtl(const gl::FramebufferState &state, bool flipY, - SurfaceMtl *backbuffer) + WindowSurfaceMtl *backbuffer) : FramebufferImpl(state), mBackbuffer(backbuffer), mFlipY(flipY) { reset(); @@ -600,8 +600,7 @@ PackPixelsParams params(flippedArea, angleFormat, outputPitch, packState.reverse case gl::Framebuffer::DIRTY_BIT_DEFAULT_SAMPLES: case gl::Framebuffer::DIRTY_BIT_DEFAULT_FIXED_SAMPLE_LOCATIONS: break; - default: - { + default: { static_assert(gl::Framebuffer::DIRTY_BIT_COLOR_ATTACHMENT_0 == 0, "FB dirty bits"); if (dirtyBit < gl::Framebuffer::DIRTY_BIT_COLOR_ATTACHMENT_MAX) { diff --git a/src/libANGLE/renderer/metal/SurfaceMtl.h b/src/libANGLE/renderer/metal/SurfaceMtl.h index 144128e6de..fc1d8f4888 100644 --- a/src/libANGLE/renderer/metal/SurfaceMtl.h +++ b/src/libANGLE/renderer/metal/SurfaceMtl.h @@ -12,6 +12,8 @@ #import #import +#include + #include "libANGLE/renderer/FramebufferImpl.h" #include "libANGLE/renderer/SurfaceImpl.h" #include "libANGLE/renderer/metal/RenderTargetMtl.h" @@ -29,7 +31,6 @@ class SurfaceMtl : public SurfaceImpl public: SurfaceMtl(DisplayMtl *display, const egl::SurfaceState &state, - EGLNativeWindowType window, const egl::AttributeMap &attribs); ~SurfaceMtl() override; @@ -55,19 +56,78 @@ class SurfaceMtl : public SurfaceImpl egl::Error releaseTexImage(const gl::Context *context, EGLint buffer) override; egl::Error getSyncValues(EGLuint64KHR *ust, EGLuint64KHR *msc, EGLuint64KHR *sbc) override; void setSwapInterval(EGLint interval) override; - void setSwapBehavior(EGLint behavior) override; void setFixedWidth(EGLint width) override; void setFixedHeight(EGLint height) override; - // width and height can change with client window resizing EGLint getWidth() const override; EGLint getHeight() const override; EGLint isPostSubBufferSupported() const override; EGLint getSwapBehavior() const override; + const mtl::TextureRef &getColorTexture() { return mColorTexture; } + const mtl::Format &getColorFormat() const { return mColorFormat; } int getSamples() const { return mSamples; } - bool preserveBuffer() const { return mRetainBuffer; } + + angle::Result getAttachmentRenderTarget(const gl::Context *context, + GLenum binding, + const gl::ImageIndex &imageIndex, + GLsizei samples, + FramebufferAttachmentRenderTarget **rtOut) override; + + protected: + // Ensure companion (MS, depth, stencil) textures' size is correct w.r.t color texture. + angle::Result ensureCompanionTexturesSizeCorrect(const gl::Context *context, + const gl::Extents &size); + angle::Result resolveColorTextureIfNeeded(const gl::Context *context); + + // Normal textures + mtl::TextureRef mColorTexture; + mtl::TextureRef mDepthTexture; + mtl::TextureRef mStencilTexture; + + // Implicit multisample texture + mtl::TextureRef mMSColorTexture; + + bool mUsePackedDepthStencil = false; + bool mAutoResolveMSColorTexture = false; + + mtl::Format mColorFormat; + mtl::Format mDepthFormat; + mtl::Format mStencilFormat; + + int mSamples = 0; + + RenderTargetMtl mColorRenderTarget; + RenderTargetMtl mColorManualResolveRenderTarget; + RenderTargetMtl mDepthRenderTarget; + RenderTargetMtl mStencilRenderTarget; +}; + +class WindowSurfaceMtl : public SurfaceMtl +{ + public: + WindowSurfaceMtl(DisplayMtl *display, + const egl::SurfaceState &state, + EGLNativeWindowType window, + const egl::AttributeMap &attribs); + ~WindowSurfaceMtl() override; + + void destroy(const egl::Display *display) override; + + egl::Error initialize(const egl::Display *display) override; + FramebufferImpl *createDefaultFramebuffer(const gl::Context *context, + const gl::FramebufferState &state) override; + + egl::Error swap(const gl::Context *context) override; + + void setSwapInterval(EGLint interval) override; + void setSwapBehavior(EGLint behavior) override; + EGLint getSwapBehavior() const override; + + // width and height can change with client window resizing + EGLint getWidth() const override; + EGLint getHeight() const override; angle::Result getAttachmentRenderTarget(const gl::Context *context, GLenum binding, @@ -77,10 +137,12 @@ class SurfaceMtl : public SurfaceImpl angle::Result ensureCurrentDrawableObtained(const gl::Context *context); + bool preserveBuffer() const { return mRetainBuffer; } + private: angle::Result swapImpl(const gl::Context *context); angle::Result obtainNextDrawable(const gl::Context *context); - angle::Result ensureTexturesSizeCorrect(const gl::Context *context); + angle::Result ensureCompanionTexturesSizeCorrect(const gl::Context *context); CGSize calcExpectedDrawableSize() const; // Check if metal layer has been resized. @@ -95,36 +157,64 @@ class SurfaceMtl : public SurfaceImpl CALayer *mLayer; mtl::AutoObjCPtr> mCurrentDrawable = nil; + // Texture for preserving content of color buffer (used when multisample texture is not + // enabled). + mtl::TextureRef mRetainedColorTexture; + + bool mRetainBuffer = false; + // Cache last known drawable size that is used by GL context. Can be used to detect resize // event. We don't use mMetalLayer.drawableSize directly since it might be changed internally by // metal runtime. CGSize mCurrentKnownDrawableSize; +}; - // Normal textures - mtl::TextureRef mDrawableTexture; - mtl::TextureRef mDepthTexture; - mtl::TextureRef mStencilTexture; +class OffscreenSurfaceMtl : public SurfaceMtl +{ + public: + OffscreenSurfaceMtl(DisplayMtl *display, + const egl::SurfaceState &state, + const egl::AttributeMap &attribs); + ~OffscreenSurfaceMtl() override; - // Implicit multisample texture - mtl::TextureRef mMSColorTexture; + void destroy(const egl::Display *display) override; - // Texture for preserving content of color buffer. - mtl::TextureRef mRetainedColorTexture; + egl::Error swap(const gl::Context *context) override; - bool mUsePackedDepthStencil = false; - bool mAutoResolveMSColorTexture = false; + egl::Error bindTexImage(const gl::Context *context, + gl::Texture *texture, + EGLint buffer) override; + egl::Error releaseTexImage(const gl::Context *context, EGLint buffer) override; - mtl::Format mColorFormat; - mtl::Format mDepthFormat; - mtl::Format mStencilFormat; + angle::Result getAttachmentRenderTarget(const gl::Context *context, + GLenum binding, + const gl::ImageIndex &imageIndex, + GLsizei samples, + FramebufferAttachmentRenderTarget **rtOut) override; - int mSamples = 0; - bool mRetainBuffer = false; + // Get or create implicit MS color texture. Used by glFramebufferTexture2DMultisampleEXT() + // after eglBindTexImage() + angle::Result getAttachmentMSColorTexture(const gl::Context *context, + GLsizei samples, + mtl::TextureRef *texOut); - RenderTargetMtl mColorRenderTarget; - RenderTargetMtl mColorManualResolveRenderTarget; - RenderTargetMtl mDepthRenderTarget; - RenderTargetMtl mStencilRenderTarget; + protected: + angle::Result ensureTexturesSizeCorrect(const gl::Context *context); + + gl::Extents mSize; + + std::unordered_map mAttachmentMSColorTextures; +}; + +class PBufferSurfaceMtl : public OffscreenSurfaceMtl +{ + public: + PBufferSurfaceMtl(DisplayMtl *display, + const egl::SurfaceState &state, + const egl::AttributeMap &attribs); + + void setFixedWidth(EGLint width) override; + void setFixedHeight(EGLint height) override; }; } // namespace rx diff --git a/src/libANGLE/renderer/metal/SurfaceMtl.mm b/src/libANGLE/renderer/metal/SurfaceMtl.mm index fc1dfab8c3..7177de4404 100644 --- a/src/libANGLE/renderer/metal/SurfaceMtl.mm +++ b/src/libANGLE/renderer/metal/SurfaceMtl.mm @@ -31,6 +31,16 @@ namespace { + +#define ANGLE_TO_EGL_TRY(EXPR) \ + do \ + { \ + if (ANGLE_UNLIKELY((EXPR) != angle::Result::Continue)) \ + { \ + return egl::EglBadSurface(); \ + } \ + } while (0) + constexpr angle::FormatID kDefaultFrameBufferDepthFormatId = angle::FormatID::D32_FLOAT; constexpr angle::FormatID kDefaultFrameBufferStencilFormatId = angle::FormatID::S8_UINT; constexpr angle::FormatID kDefaultFrameBufferDepthStencilFormatId = @@ -88,6 +98,7 @@ void InitBlitParams(const mtl::TextureRef &src, params.dstRect = params.dstScissorRect = gl::Rectangle(0, 0, params.dstTextureSize.width, params.dstTextureSize.height); } + ANGLE_MTL_UNUSED bool IsFrameCaptureEnabled() { @@ -221,30 +232,19 @@ void StopFrameCapture() } } +// SurfaceMtl implementation SurfaceMtl::SurfaceMtl(DisplayMtl *display, const egl::SurfaceState &state, - EGLNativeWindowType window, const egl::AttributeMap &attribs) - : SurfaceImpl(state), mLayer((__bridge CALayer *)(window)) + : SurfaceImpl(state) { - // NOTE(hqle): Width and height attributes is ignored for now. - mCurrentKnownDrawableSize = CGSizeMake(0, 0); - if (attribs.get(EGL_GL_COLORSPACE, EGL_GL_COLORSPACE_LINEAR) == EGL_GL_COLORSPACE_SRGB_KHR) { mColorFormat = display->getPixelFormat(angle::FormatID::B8G8R8A8_UNORM_SRGB); } else { - // https://developer.apple.com/metal/Metal-Feature-Set-Tables.pdf says that BGRA8Unorm is - // only supported if depth24Stencil8PixelFormatSupported capabilitiy is YES. Yet - // CAMetalLayer can be created with pixelFormat MTLPixelFormatBGRA8Unorm. So the mtl::Format - // used for SurfaceMtl is initialized a bit differently from normal TextureMtl's - // mtl::Format. It won't use format table, instead we initialize its values here to use - // BGRA8Unorm directly: - mColorFormat.intendedFormatId = mColorFormat.actualFormatId = - angle::FormatID::B8G8R8A8_UNORM; - mColorFormat.metalFormat = MTLPixelFormatBGRA8Unorm; + mColorFormat = display->getPixelFormat(angle::FormatID::B8G8R8A8_UNORM); } mSamples = state.config->samples; @@ -286,75 +286,27 @@ void StopFrameCapture() void SurfaceMtl::destroy(const egl::Display *display) { - mDrawableTexture = nullptr; - mDepthTexture = nullptr; - mStencilTexture = nullptr; + mColorTexture = nullptr; + mDepthTexture = nullptr; + mStencilTexture = nullptr; mMSColorTexture = nullptr; - mRetainedColorTexture = nullptr; - mColorRenderTarget.reset(); mColorManualResolveRenderTarget.reset(); mDepthRenderTarget.reset(); mStencilRenderTarget.reset(); - - mCurrentDrawable = nil; - if (mMetalLayer && mMetalLayer.get() != mLayer) - { - // If we created metal layer in SurfaceMtl::initialize(), - // we need to detach it from super layer now. - [mMetalLayer.get() removeFromSuperlayer]; - } - mMetalLayer = nil; } egl::Error SurfaceMtl::initialize(const egl::Display *display) { - DisplayMtl *displayMtl = mtl::GetImpl(display); - id metalDevice = displayMtl->getMetalDevice(); - - StartFrameCapture(metalDevice, displayMtl->cmdQueue().get()); - - ANGLE_MTL_OBJC_SCOPE - { - if ([mLayer isKindOfClass:CAMetalLayer.class]) - { - mMetalLayer.retainAssign(static_cast(mLayer)); - } - else - { - mMetalLayer = [[[CAMetalLayer alloc] init] ANGLE_MTL_AUTORELEASE]; - mMetalLayer.get().frame = mLayer.frame; - } - - mMetalLayer.get().device = metalDevice; - mMetalLayer.get().pixelFormat = mColorFormat.metalFormat; - mMetalLayer.get().framebufferOnly = NO; // Support blitting and glReadPixels - -#if TARGET_OS_OSX || TARGET_OS_MACCATALYST - // Autoresize with parent layer. - mMetalLayer.get().autoresizingMask = kCALayerWidthSizable | kCALayerHeightSizable; -#endif - - if (mMetalLayer.get() != mLayer) - { - mMetalLayer.get().contentsScale = mLayer.contentsScale; - - [mLayer addSublayer:mMetalLayer.get()]; - } - - // ensure drawableSize is set to correct value: - mMetalLayer.get().drawableSize = mCurrentKnownDrawableSize = calcExpectedDrawableSize(); - } - return egl::NoError(); } FramebufferImpl *SurfaceMtl::createDefaultFramebuffer(const gl::Context *context, const gl::FramebufferState &state) { - auto fbo = new FramebufferMtl(state, /* flipY */ true, /* backbuffer */ this); + auto fbo = new FramebufferMtl(state, /* flipY */ false, /* backbuffer */ nullptr); return fbo; } @@ -369,19 +321,15 @@ void StopFrameCapture() egl::Error SurfaceMtl::unMakeCurrent(const gl::Context *context) { + ContextMtl *contextMtl = mtl::GetImpl(context); + contextMtl->flushCommandBufer(); + StopFrameCapture(); return egl::NoError(); } egl::Error SurfaceMtl::swap(const gl::Context *context) { - angle::Result result = swapImpl(context); - - if (result != angle::Result::Continue) - { - return egl::EglBadSurface(); - } - return egl::NoError(); } @@ -419,12 +367,7 @@ void StopFrameCapture() return egl::EglBadAccess(); } -void SurfaceMtl::setSwapInterval(EGLint interval) -{ -#if TARGET_OS_OSX || TARGET_OS_MACCATALYST - mMetalLayer.get().displaySyncEnabled = interval != 0; -#endif -} +void SurfaceMtl::setSwapInterval(EGLint interval) {} void SurfaceMtl::setFixedWidth(EGLint width) { @@ -436,15 +379,22 @@ void StopFrameCapture() UNIMPLEMENTED(); } -// width and height can change with client window resizing EGLint SurfaceMtl::getWidth() const { - return static_cast(mCurrentKnownDrawableSize.width); + if (mColorTexture) + { + return static_cast(mColorTexture->width()); + } + return 0; } EGLint SurfaceMtl::getHeight() const { - return static_cast(mCurrentKnownDrawableSize.height); + if (mColorTexture) + { + return static_cast(mColorTexture->height()); + } + return 0; } EGLint SurfaceMtl::isPostSubBufferSupported() const @@ -452,14 +402,9 @@ void StopFrameCapture() return EGL_FALSE; } -void SurfaceMtl::setSwapBehavior(EGLint behavior) -{ - mRetainBuffer = behavior == EGL_BUFFER_PRESERVED; -} - EGLint SurfaceMtl::getSwapBehavior() const { - return mRetainBuffer ? EGL_BUFFER_PRESERVED : EGL_BUFFER_DESTROYED; + return EGL_BUFFER_PRESERVED; } angle::Result SurfaceMtl::getAttachmentRenderTarget(const gl::Context *context, @@ -468,8 +413,7 @@ void StopFrameCapture() GLsizei samples, FramebufferAttachmentRenderTarget **rtOut) { - ANGLE_TRY(ensureCurrentDrawableObtained(context)); - ANGLE_TRY(ensureTexturesSizeCorrect(context)); + ASSERT(mColorTexture); switch (binding) { @@ -491,53 +435,30 @@ void StopFrameCapture() return angle::Result::Continue; } -angle::Result SurfaceMtl::ensureCurrentDrawableObtained(const gl::Context *context) -{ - if (!mCurrentDrawable) - { - ANGLE_TRY(obtainNextDrawable(context)); - } - - return angle::Result::Continue; -} - -angle::Result SurfaceMtl::ensureTexturesSizeCorrect(const gl::Context *context) +angle::Result SurfaceMtl::ensureCompanionTexturesSizeCorrect(const gl::Context *context, + const gl::Extents &size) { - ASSERT(mMetalLayer); - ContextMtl *contextMtl = mtl::GetImpl(context); - gl::Extents size(static_cast(mMetalLayer.get().drawableSize.width), - static_cast(mMetalLayer.get().drawableSize.height), 1); + ASSERT(mColorTexture); - if (mSamples > 1) + if (mSamples > 1 && (!mMSColorTexture || mMSColorTexture->size() != size)) { - if (!mMSColorTexture || mMSColorTexture->size() != size) - { - mAutoResolveMSColorTexture = - contextMtl->getDisplay()->getFeatures().allowMultisampleStoreAndResolve.enabled; - ANGLE_TRY(CreateOrResizeTexture( - context, mColorFormat, size.width, size.height, mSamples, - /** renderTargetOnly */ mAutoResolveMSColorTexture, &mMSColorTexture)); + mAutoResolveMSColorTexture = + contextMtl->getDisplay()->getFeatures().allowMultisampleStoreAndResolve.enabled; + ANGLE_TRY(CreateOrResizeTexture(context, mColorFormat, size.width, size.height, mSamples, + /** renderTargetOnly */ mAutoResolveMSColorTexture, + &mMSColorTexture)); - if (mAutoResolveMSColorTexture) - { - // Use auto MSAA resolve at the end of render pass. - mColorRenderTarget.setImplicitMSTexture(mMSColorTexture); - } - else - { - mColorRenderTarget.setTexture(mMSColorTexture); - } + if (mAutoResolveMSColorTexture) + { + // Use auto MSAA resolve at the end of render pass. + mColorRenderTarget.setImplicitMSTexture(mMSColorTexture); + } + else + { + mColorRenderTarget.setTexture(mMSColorTexture); } - } - else if (mRetainBuffer && (!mRetainedColorTexture || mRetainedColorTexture->size() != size)) - { - ANGLE_TRY(CreateOrResizeTexture(context, mColorFormat, size.width, size.height, 1, - /** renderTargetOnly */ true, &mRetainedColorTexture)); - - // All drawing will be drawn to this texture instead of the main one. - mColorRenderTarget.setTexture(mRetainedColorTexture); } if (mDepthFormat.valid() && (!mDepthTexture || mDepthTexture->size() != size)) @@ -567,7 +488,193 @@ void StopFrameCapture() return angle::Result::Continue; } -CGSize SurfaceMtl::calcExpectedDrawableSize() const +angle::Result SurfaceMtl::resolveColorTextureIfNeeded(const gl::Context *context) +{ + ASSERT(mMSColorTexture); + if (!mAutoResolveMSColorTexture) + { + // Manually resolve texture + ContextMtl *contextMtl = mtl::GetImpl(context); + + mColorManualResolveRenderTarget.set(mColorTexture, 0, 0, mColorFormat); + mtl::RenderCommandEncoder *encoder = + contextMtl->getRenderCommandEncoder(mColorManualResolveRenderTarget); + ANGLE_TRY(contextMtl->getDisplay()->getUtils().blitColorWithDraw( + context, encoder, mColorFormat.actualAngleFormat(), mMSColorTexture)); + contextMtl->endEncoding(true); + mColorManualResolveRenderTarget.reset(); + } + return angle::Result::Continue; +} + +// WindowSurfaceMtl implementation. +WindowSurfaceMtl::WindowSurfaceMtl(DisplayMtl *display, + const egl::SurfaceState &state, + EGLNativeWindowType window, + const egl::AttributeMap &attribs) + : SurfaceMtl(display, state, attribs), mLayer((__bridge CALayer *)(window)) +{ + // NOTE(hqle): Width and height attributes is ignored for now. + mCurrentKnownDrawableSize = CGSizeMake(0, 0); +} + +WindowSurfaceMtl::~WindowSurfaceMtl() {} + +void WindowSurfaceMtl::destroy(const egl::Display *display) +{ + SurfaceMtl::destroy(display); + + mRetainedColorTexture = nullptr; + mRetainBuffer = false; + + mCurrentDrawable = nil; + if (mMetalLayer && mMetalLayer.get() != mLayer) + { + // If we created metal layer in WindowSurfaceMtl::initialize(), + // we need to detach it from super layer now. + [mMetalLayer.get() removeFromSuperlayer]; + } + mMetalLayer = nil; +} + +egl::Error WindowSurfaceMtl::initialize(const egl::Display *display) +{ + egl::Error re = SurfaceMtl::initialize(display); + if (re.isError()) + { + return re; + } + + DisplayMtl *displayMtl = mtl::GetImpl(display); + id metalDevice = displayMtl->getMetalDevice(); + + StartFrameCapture(metalDevice, displayMtl->cmdQueue().get()); + + ANGLE_MTL_OBJC_SCOPE + { + if ([mLayer isKindOfClass:CAMetalLayer.class]) + { + mMetalLayer.retainAssign(static_cast(mLayer)); + } + else + { + mMetalLayer = [[[CAMetalLayer alloc] init] ANGLE_MTL_AUTORELEASE]; + mMetalLayer.get().frame = mLayer.frame; + } + + mMetalLayer.get().device = metalDevice; + mMetalLayer.get().pixelFormat = mColorFormat.metalFormat; + mMetalLayer.get().framebufferOnly = NO; // Support blitting and glReadPixels + +#if TARGET_OS_OSX || TARGET_OS_MACCATALYST + // Autoresize with parent layer. + mMetalLayer.get().autoresizingMask = kCALayerWidthSizable | kCALayerHeightSizable; +#endif + + if (mMetalLayer.get() != mLayer) + { + mMetalLayer.get().contentsScale = mLayer.contentsScale; + + [mLayer addSublayer:mMetalLayer.get()]; + } + + // ensure drawableSize is set to correct value: + mMetalLayer.get().drawableSize = mCurrentKnownDrawableSize = calcExpectedDrawableSize(); + } + + return egl::NoError(); +} + +FramebufferImpl *WindowSurfaceMtl::createDefaultFramebuffer(const gl::Context *context, + const gl::FramebufferState &state) +{ + auto fbo = new FramebufferMtl(state, /* flipY */ true, /* backbuffer */ this); + + return fbo; +} + +egl::Error WindowSurfaceMtl::swap(const gl::Context *context) +{ + ANGLE_TO_EGL_TRY(swapImpl(context)); + + return egl::NoError(); +} + +void WindowSurfaceMtl::setSwapInterval(EGLint interval) +{ +#if TARGET_OS_OSX || TARGET_OS_MACCATALYST + mMetalLayer.get().displaySyncEnabled = interval != 0; +#endif +} + +void WindowSurfaceMtl::setSwapBehavior(EGLint behavior) +{ + mRetainBuffer = behavior == EGL_BUFFER_PRESERVED; +} + +// width and height can change with client window resizing +EGLint WindowSurfaceMtl::getWidth() const +{ + return static_cast(mCurrentKnownDrawableSize.width); +} + +EGLint WindowSurfaceMtl::getHeight() const +{ + return static_cast(mCurrentKnownDrawableSize.height); +} + +EGLint WindowSurfaceMtl::getSwapBehavior() const +{ + return mRetainBuffer ? EGL_BUFFER_PRESERVED : EGL_BUFFER_DESTROYED; +} + +angle::Result WindowSurfaceMtl::getAttachmentRenderTarget(const gl::Context *context, + GLenum binding, + const gl::ImageIndex &imageIndex, + GLsizei samples, + FramebufferAttachmentRenderTarget **rtOut) +{ + ANGLE_TRY(ensureCurrentDrawableObtained(context)); + ANGLE_TRY(ensureCompanionTexturesSizeCorrect(context)); + + return SurfaceMtl::getAttachmentRenderTarget(context, binding, imageIndex, samples, rtOut); +} + +angle::Result WindowSurfaceMtl::ensureCurrentDrawableObtained(const gl::Context *context) +{ + if (!mCurrentDrawable) + { + ANGLE_TRY(obtainNextDrawable(context)); + } + + return angle::Result::Continue; +} + +angle::Result WindowSurfaceMtl::ensureCompanionTexturesSizeCorrect(const gl::Context *context) +{ + ASSERT(mMetalLayer); + + gl::Extents size(static_cast(mMetalLayer.get().drawableSize.width), + static_cast(mMetalLayer.get().drawableSize.height), 1); + + ANGLE_TRY(SurfaceMtl::ensureCompanionTexturesSizeCorrect(context, size)); + + if (mRetainBuffer && !mMSColorTexture && + (!mRetainedColorTexture || mRetainedColorTexture->size() != size)) + { + // Create retained color texture (only if multisample texture is not used since multisample + // texture can preserve the content also). + ANGLE_TRY(CreateOrResizeTexture(context, mColorFormat, size.width, size.height, 1, + /** renderTargetOnly */ true, &mRetainedColorTexture)); + + // All drawing will be drawn to this texture instead of the main one. + mColorRenderTarget.setTexture(mRetainedColorTexture); + } + + return angle::Result::Continue; +} + +CGSize WindowSurfaceMtl::calcExpectedDrawableSize() const { CGSize currentLayerSize = mMetalLayer.get().bounds.size; CGFloat currentLayerContentsScale = mMetalLayer.get().contentsScale; @@ -577,7 +684,7 @@ void StopFrameCapture() return expectedDrawableSize; } -bool SurfaceMtl::checkIfLayerResized(const gl::Context *context) +bool WindowSurfaceMtl::checkIfLayerResized(const gl::Context *context) { if (mMetalLayer.get() != mLayer && mMetalLayer.get().contentsScale != mLayer.contentsScale) { @@ -602,7 +709,7 @@ void StopFrameCapture() return false; } -angle::Result SurfaceMtl::obtainNextDrawable(const gl::Context *context) +angle::Result WindowSurfaceMtl::obtainNextDrawable(const gl::Context *context) { ANGLE_MTL_OBJC_SCOPE { @@ -638,22 +745,22 @@ void StopFrameCapture() mMetalLayer.get().allowsNextDrawableTimeout = YES; } - if (!mDrawableTexture) + if (!mColorTexture) { - mDrawableTexture = mtl::Texture::MakeFromMetal(mCurrentDrawable.get().texture); + mColorTexture = mtl::Texture::MakeFromMetal(mCurrentDrawable.get().texture); ASSERT(!mColorRenderTarget.getTexture()); - mColorRenderTarget.set(mDrawableTexture, mMSColorTexture, 0, 0, mColorFormat); + mColorRenderTarget.set(mColorTexture, mMSColorTexture, 0, 0, mColorFormat); } else { - mDrawableTexture->set(mCurrentDrawable.get().texture); + mColorTexture->set(mCurrentDrawable.get().texture); } - ANGLE_MTL_LOG("Current metal drawable size=%d,%d", mDrawableTexture->width(), - mDrawableTexture->height()); + ANGLE_MTL_LOG("Current metal drawable size=%d,%d", mColorTexture->width(), + mColorTexture->height()); // Now we have to resize depth stencil buffers if required. - ANGLE_TRY(ensureTexturesSizeCorrect(context)); + ANGLE_TRY(ensureCompanionTexturesSizeCorrect(context)); // Copy old content after resize. if (preservedColorTexture || preservedDepthTexture || preservedStencilTexture) @@ -666,10 +773,10 @@ void StopFrameCapture() } } -angle::Result SurfaceMtl::copyOldContents(const gl::Context *context, - const mtl::TextureRef &oldColorTexture, - const mtl::TextureRef &oldDepthTexture, - const mtl::TextureRef &oldStencilTexture) +angle::Result WindowSurfaceMtl::copyOldContents(const gl::Context *context, + const mtl::TextureRef &oldColorTexture, + const mtl::TextureRef &oldDepthTexture, + const mtl::TextureRef &oldStencilTexture) { ContextMtl *contextMtl = mtl::GetImpl(context); @@ -753,28 +860,21 @@ void StopFrameCapture() return angle::Result::Continue; } -angle::Result SurfaceMtl::swapImpl(const gl::Context *context) +angle::Result WindowSurfaceMtl::swapImpl(const gl::Context *context) { if (mCurrentDrawable) { - ASSERT(mDrawableTexture); + ASSERT(mColorTexture); ContextMtl *contextMtl = mtl::GetImpl(context); - if (mMSColorTexture && !mAutoResolveMSColorTexture) + if (mMSColorTexture) { - // Resolve texture - mColorManualResolveRenderTarget.set(mDrawableTexture, 0, 0, mColorFormat); - mtl::RenderCommandEncoder *encoder = - contextMtl->getRenderCommandEncoder(mColorManualResolveRenderTarget); - ANGLE_TRY(contextMtl->getDisplay()->getUtils().blitColorWithDraw( - context, encoder, mColorFormat.actualAngleFormat(), mMSColorTexture)); - contextMtl->endEncoding(true); - mColorManualResolveRenderTarget.reset(); + ANGLE_TRY(resolveColorTextureIfNeeded(context)); } else if (mRetainedColorTexture) { - CopyTextureNoScale(contextMtl, mRetainedColorTexture, &mDrawableTexture); + CopyTextureNoScale(contextMtl, mRetainedColorTexture, &mColorTexture); } contextMtl->present(context, mCurrentDrawable); @@ -783,10 +883,128 @@ void StopFrameCapture() StartFrameCapture(contextMtl); // Invalidate current drawable - mDrawableTexture->set(nil); + mColorTexture->set(nil); mCurrentDrawable = nil; } return angle::Result::Continue; } + +// OffscreenSurfaceMtl implementation +OffscreenSurfaceMtl::OffscreenSurfaceMtl(DisplayMtl *display, + const egl::SurfaceState &state, + const egl::AttributeMap &attribs) + : SurfaceMtl(display, state, attribs) +{ + mSize = gl::Extents(attribs.getAsInt(EGL_WIDTH, 1), attribs.getAsInt(EGL_HEIGHT, 1), 1); +} + +OffscreenSurfaceMtl::~OffscreenSurfaceMtl() {} + +void OffscreenSurfaceMtl::destroy(const egl::Display *display) +{ + mAttachmentMSColorTextures.clear(); + SurfaceMtl::destroy(display); +} + +egl::Error OffscreenSurfaceMtl::swap(const gl::Context *context) +{ + // Check for surface resize. + ANGLE_TO_EGL_TRY(ensureTexturesSizeCorrect(context)); + + return egl::NoError(); +} + +egl::Error OffscreenSurfaceMtl::bindTexImage(const gl::Context *context, + gl::Texture *texture, + EGLint buffer) +{ + ContextMtl *contextMtl = mtl::GetImpl(context); + contextMtl->flushCommandBufer(); + + // Initialize offscreen textures if needed: + ANGLE_TO_EGL_TRY(ensureTexturesSizeCorrect(context)); + + if (mMSColorTexture) + { + ANGLE_TO_EGL_TRY(resolveColorTextureIfNeeded(context)); + } + + return egl::NoError(); +} + +egl::Error OffscreenSurfaceMtl::releaseTexImage(const gl::Context *context, EGLint buffer) +{ + ContextMtl *contextMtl = mtl::GetImpl(context); + // NOTE(hqle): Should we finishCommandBuffer or flush is enough? + contextMtl->flushCommandBufer(); + return egl::NoError(); +} + +angle::Result OffscreenSurfaceMtl::getAttachmentRenderTarget( + const gl::Context *context, + GLenum binding, + const gl::ImageIndex &imageIndex, + GLsizei samples, + FramebufferAttachmentRenderTarget **rtOut) +{ + // Initialize offscreen textures if needed: + ANGLE_TRY(ensureTexturesSizeCorrect(context)); + + return SurfaceMtl::getAttachmentRenderTarget(context, binding, imageIndex, samples, rtOut); +} + +angle::Result OffscreenSurfaceMtl::getAttachmentMSColorTexture(const gl::Context *context, + GLsizei samples, + mtl::TextureRef *texOut) +{ + mtl::TextureRef &msTexture = mAttachmentMSColorTextures[samples]; + if (msTexture) + { + if (msTexture->size() == mColorTexture->size()) + { + *texOut = msTexture; + return angle::Result::Continue; + } + } + + ContextMtl *contextMtl = mtl::GetImpl(context); + + ANGLE_TRY(mtl::Texture::Make2DMSTexture(contextMtl, mColorFormat, mSize.width, mSize.height, + samples, + /* renderTargetOnly */ true, + /* allowFormatView */ false, &msTexture)); + *texOut = msTexture; + return angle::Result::Continue; +} + +angle::Result OffscreenSurfaceMtl::ensureTexturesSizeCorrect(const gl::Context *context) +{ + if (!mColorTexture || mColorTexture->size() != mSize) + { + ANGLE_TRY(CreateOrResizeTexture(context, mColorFormat, mSize.width, mSize.height, 1, + /** renderTargetOnly */ false, &mColorTexture)); + + mColorRenderTarget.set(mColorTexture, 0, 0, mColorFormat); + } + + return ensureCompanionTexturesSizeCorrect(context, mSize); +} + +// PBufferSurfaceMtl implementation +PBufferSurfaceMtl::PBufferSurfaceMtl(DisplayMtl *display, + const egl::SurfaceState &state, + const egl::AttributeMap &attribs) + : OffscreenSurfaceMtl(display, state, attribs) +{} + +void PBufferSurfaceMtl::setFixedWidth(EGLint width) +{ + mSize.width = width; +} + +void PBufferSurfaceMtl::setFixedHeight(EGLint height) +{ + mSize.height = height; +} } diff --git a/src/libANGLE/renderer/metal/TextureMtl.h b/src/libANGLE/renderer/metal/TextureMtl.h index a56021617f..d085dac235 100644 --- a/src/libANGLE/renderer/metal/TextureMtl.h +++ b/src/libANGLE/renderer/metal/TextureMtl.h @@ -21,6 +21,8 @@ namespace rx { +class OffscreenSurfaceMtl; + struct ImageDefinitionMtl { mtl::TextureRef image; @@ -268,6 +270,7 @@ class TextureMtl : public TextureImpl // The real texture used by Metal draw calls. mtl::TextureRef mNativeTexture; id mMetalSamplerState = nil; + OffscreenSurfaceMtl *mBoundPBuffer = nullptr; // Number of slices uint32_t mSlices = 1; diff --git a/src/libANGLE/renderer/metal/TextureMtl.mm b/src/libANGLE/renderer/metal/TextureMtl.mm index c4bb408ae7..0e20e59a84 100644 --- a/src/libANGLE/renderer/metal/TextureMtl.mm +++ b/src/libANGLE/renderer/metal/TextureMtl.mm @@ -15,12 +15,14 @@ #include "common/debug.h" #include "common/mathutil.h" #include "image_util/imageformats.h" +#include "libANGLE/Surface.h" #include "libANGLE/renderer/metal/BufferMtl.h" #include "libANGLE/renderer/metal/ContextMtl.h" #include "libANGLE/renderer/metal/DisplayMtl.h" #include "libANGLE/renderer/metal/FrameBufferMtl.h" #include "libANGLE/renderer/metal/ImageMtl.h" #include "libANGLE/renderer/metal/SamplerMtl.h" +#include "libANGLE/renderer/metal/SurfaceMtl.h" #include "libANGLE/renderer/metal/mtl_common.h" #include "libANGLE/renderer/metal/mtl_format_utils.h" #include "libANGLE/renderer/metal/mtl_utils.h" @@ -61,8 +63,7 @@ { case MTLTextureType2D: return gl::ImageIndex::Make2D(level); - case MTLTextureTypeCube: - { + case MTLTextureTypeCube: { auto cubeFace = static_cast( static_cast(gl::TextureTarget::CubeMapPositiveX) + slice); return gl::ImageIndex::MakeCubeMapFace(cubeFace, level); @@ -453,6 +454,7 @@ GLenum OverrideSwizzleValue(const gl::Context *context, mNativeTexture = nullptr; mNativeSwizzleSamplingView = nullptr; + mBoundPBuffer = nullptr; mImplicitMSTextures.clear(); @@ -1144,16 +1146,26 @@ GLenum OverrideSwizzleValue(const gl::Context *context, angle::Result TextureMtl::bindTexImage(const gl::Context *context, egl::Surface *surface) { - UNIMPLEMENTED(); + releaseTexture(true); - return angle::Result::Stop; + mBoundPBuffer = GetImplAs(surface); + mNativeTexture = mBoundPBuffer->getColorTexture(); + mFormat = mBoundPBuffer->getColorFormat(); + gl::Extents size = mNativeTexture->size(); + mIsPow2 = gl::isPow2(size.width) && gl::isPow2(size.height) && gl::isPow2(size.depth); + ANGLE_TRY(ensureSamplerStateCreated(context)); + + // Tell context to rebind textures + ContextMtl *contextMtl = mtl::GetImpl(context); + contextMtl->invalidateCurrentTextures(); + + return angle::Result::Continue; } angle::Result TextureMtl::releaseTexImage(const gl::Context *context) { - UNIMPLEMENTED(); - - return angle::Result::Stop; + releaseTexture(true); + return angle::Result::Continue; } angle::Result TextureMtl::getAttachmentRenderTarget(const gl::Context *context, @@ -1169,8 +1181,7 @@ GLenum OverrideSwizzleValue(const gl::Context *context, switch (imageIndex.getType()) { - case gl::TextureType::_2D: - { + case gl::TextureType::_2D: { RenderTargetMtl &rtt = getRenderTarget(imageIndex); *rtOut = &rtt; @@ -1189,12 +1200,22 @@ GLenum OverrideSwizzleValue(const gl::Context *context, mtl::TextureRef &msTexture = getImplicitMSTexture(imageIndex); if (!msTexture || msTexture->samples() != static_cast(samples)) { - const gl::ImageDesc &desc = mState.getImageDesc(imageIndex); + if (mBoundPBuffer) + { + // NOTE(hqle): mipmapped pbuffer is not supported yet. + ASSERT(imageIndex.getLevelIndex() == 0); + ANGLE_TRY(mBoundPBuffer->getAttachmentMSColorTexture(context, samples, + &msTexture)); + } + else + { + const gl::ImageDesc &desc = mState.getImageDesc(imageIndex); - ANGLE_TRY(mtl::Texture::Make2DMSTexture( - contextMtl, mFormat, desc.size.width, desc.size.height, samples, - /* renderTargetOnly */ true, - /* allowFormatView */ false, &msTexture)); + ANGLE_TRY(mtl::Texture::Make2DMSTexture( + contextMtl, mFormat, desc.size.width, desc.size.height, samples, + /* renderTargetOnly */ true, + /* allowFormatView */ false, &msTexture)); + } ANGLE_TRY(checkForEmulatedChannels(context, mFormat, msTexture)); } @@ -1246,8 +1267,7 @@ GLenum OverrideSwizzleValue(const gl::Context *context, case gl::Texture::DIRTY_BIT_SWIZZLE_RED: case gl::Texture::DIRTY_BIT_SWIZZLE_GREEN: case gl::Texture::DIRTY_BIT_SWIZZLE_BLUE: - case gl::Texture::DIRTY_BIT_SWIZZLE_ALPHA: - { + case gl::Texture::DIRTY_BIT_SWIZZLE_ALPHA: { // Recreate swizzle view. mNativeSwizzleSamplingView = nullptr; } diff --git a/src/libANGLE/renderer/metal/mtl_format_map.json b/src/libANGLE/renderer/metal/mtl_format_map.json index 79408b0245..f29aa779f1 100644 --- a/src/libANGLE/renderer/metal/mtl_format_map.json +++ b/src/libANGLE/renderer/metal/mtl_format_map.json @@ -138,7 +138,6 @@ "EAC_R11G11_SNORM_BLOCK": "R16G16_SNORM" }, "fallbacks_mac": { - "B8G8R8A8_UNORM": "R8G8B8A8_UNORM", "D24_UNORM_S8_UINT": "D32_FLOAT_S8X24_UINT" } }, diff --git a/src/libANGLE/renderer/metal/mtl_format_table_autogen.mm b/src/libANGLE/renderer/metal/mtl_format_table_autogen.mm index 2b02765c49..aefa3dcc51 100644 --- a/src/libANGLE/renderer/metal/mtl_format_table_autogen.mm +++ b/src/libANGLE/renderer/metal/mtl_format_table_autogen.mm @@ -1,7 +1,7 @@ // GENERATED FILE - DO NOT EDIT. // Generated by gen_mtl_format_table.py using data from mtl_format_map.json // -// Copyright 2020 The ANGLE Project Authors. All rights reserved. +// Copyright 2021 The ANGLE Project Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. // @@ -210,26 +210,6 @@ this->swizzled = false; break; -#if TARGET_OS_OSX || TARGET_OS_MACCATALYST - case angle::FormatID::B8G8R8A8_UNORM: - - if (metalDevice.depth24Stencil8PixelFormatSupported) - { - this->metalFormat = MTLPixelFormatBGRA8Unorm; - this->actualFormatId = angle::FormatID::B8G8R8A8_UNORM; - this->initFunction = nullptr; - } - else - { - this->metalFormat = MTLPixelFormatRGBA8Unorm; - this->actualFormatId = angle::FormatID::R8G8B8A8_UNORM; - this->initFunction = nullptr; - } - - this->swizzled = false; - break; - -#else // TARGET_OS_OSX || TARGET_OS_MACCATALYST case angle::FormatID::B8G8R8A8_UNORM: this->metalFormat = MTLPixelFormatBGRA8Unorm; @@ -239,7 +219,6 @@ this->swizzled = false; break; -#endif // TARGET_OS_OSX || TARGET_OS_MACCATALYST case angle::FormatID::B8G8R8A8_UNORM_SRGB: this->metalFormat = MTLPixelFormatBGRA8Unorm_sRGB; diff --git a/src/tests/egl_tests/EGLSurfaceTest.cpp b/src/tests/egl_tests/EGLSurfaceTest.cpp index f95c054dec..d147aa8f37 100644 --- a/src/tests/egl_tests/EGLSurfaceTest.cpp +++ b/src/tests/egl_tests/EGLSurfaceTest.cpp @@ -811,7 +811,8 @@ ANGLE_INSTANTIATE_TEST(EGLSurfaceTest, WithNoFixture(ES2_OPENGLES()), WithNoFixture(ES3_OPENGLES()), WithNoFixture(ES2_VULKAN()), - WithNoFixture(ES3_VULKAN())); + WithNoFixture(ES3_VULKAN()), + WithNoFixture(ES2_METAL())); ANGLE_INSTANTIATE_TEST(EGLSurfaceTest3, WithNoFixture(ES3_VULKAN())); #if defined(ANGLE_ENABLE_D3D11) diff --git a/src/tests/egl_tests/EGLSurfacelessContextTest.cpp b/src/tests/egl_tests/EGLSurfacelessContextTest.cpp index 6c54518eb1..34e6059105 100644 --- a/src/tests/egl_tests/EGLSurfacelessContextTest.cpp +++ b/src/tests/egl_tests/EGLSurfacelessContextTest.cpp @@ -45,8 +45,7 @@ class EGLSurfacelessContextTest : public ANGLETest { EGLint surfaceType; eglGetConfigAttrib(mDisplay, config, EGL_SURFACE_TYPE, &surfaceType); - // NOTE(hqle): Pbuffer is not implemented yet on Metal on master branch - if (isMetal() || surfaceType & EGL_PBUFFER_BIT) + if (surfaceType & EGL_PBUFFER_BIT) { mConfig = config; break; @@ -117,8 +116,6 @@ class EGLSurfacelessContextTest : public ANGLETest return true; } - bool isMetal() const { return GetParam().getRenderer() == EGL_PLATFORM_ANGLE_TYPE_METAL_ANGLE; } - EGLContext mContext = EGL_NO_CONTEXT; EGLSurface mPbuffer = EGL_NO_SURFACE; EGLConfig mConfig = 0; @@ -217,9 +214,6 @@ TEST_P(EGLSurfacelessContextTest, ClearReadPixelsInFBO) // Test clear+readpixels in an FBO in surfaceless and in the default FBO in a pbuffer TEST_P(EGLSurfacelessContextTest, Switcheroo) { - // NOTE(hqle): Pbuffer is not implemented yet on Metal on master branch - ANGLE_SKIP_TEST_IF(isMetal()); - if (!checkExtension()) { return; diff --git a/src/tests/gl_tests/PbufferTest.cpp b/src/tests/gl_tests/PbufferTest.cpp index 5ebabda23d..2000e6a674 100644 --- a/src/tests/gl_tests/PbufferTest.cpp +++ b/src/tests/gl_tests/PbufferTest.cpp @@ -306,4 +306,5 @@ ANGLE_INSTANTIATE_TEST(PbufferTest, ES2_D3D11(), ES2_OPENGL(), ES2_OPENGLES(), - ES2_VULKAN()); + ES2_VULKAN(), + ES2_METAL());