Diff
Modified: trunk/Source/ThirdParty/ANGLE/ANGLE.xcodeproj/project.pbxproj (279142 => 279143)
--- trunk/Source/ThirdParty/ANGLE/ANGLE.xcodeproj/project.pbxproj 2021-06-22 20:26:10 UTC (rev 279142)
+++ trunk/Source/ThirdParty/ANGLE/ANGLE.xcodeproj/project.pbxproj 2021-06-22 20:33:10 UTC (rev 279143)
@@ -21,6 +21,7 @@
/* End PBXAggregateTarget section */
/* Begin PBXBuildFile section */
+ 3154A847266C4AFF00BF33B7 /* ImageMtl.mm in Sources */ = {isa = PBXBuildFile; fileRef = 3154A845266C4AFE00BF33B7 /* ImageMtl.mm */; };
31CD0000249184B500486F27 /* WindowSurfaceCGL.h in Headers */ = {isa = PBXBuildFile; fileRef = A31B6181230B747E001610D7 /* WindowSurfaceCGL.h */; };
31CD0001249184B500486F27 /* DeviceCGL.h in Headers */ = {isa = PBXBuildFile; fileRef = 6E31A0A2234EEED400C84784 /* DeviceCGL.h */; };
31CD0002249184B500486F27 /* IOSurfaceSurfaceCGL.h in Headers */ = {isa = PBXBuildFile; fileRef = 5CCD59712284FA820018F2D8 /* IOSurfaceSurfaceCGL.h */; };
@@ -956,6 +957,8 @@
313BCE532361133900FC39E5 /* DisplayEAGL.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = DisplayEAGL.mm; sourceTree = "<group>"; };
3153ACFE239071D900D51DD8 /* WebKitTargetConditionals.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = WebKitTargetConditionals.xcconfig; sourceTree = "<group>"; };
3153ACFF239071D900D51DD8 /* Version.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = Version.xcconfig; sourceTree = "<group>"; };
+ 3154A845266C4AFE00BF33B7 /* ImageMtl.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = ImageMtl.mm; sourceTree = "<group>"; };
+ 3154A846266C4AFF00BF33B7 /* ImageMtl.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ImageMtl.h; sourceTree = "<group>"; };
315EBD3E1FCE43BD00AC7A89 /* uniform_type_info_autogen.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = uniform_type_info_autogen.cpp; sourceTree = "<group>"; };
315EBD401FCE442600AC7A89 /* TranslatorVulkan.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = TranslatorVulkan.cpp; sourceTree = "<group>"; };
315EBD431FCE442700AC7A89 /* UtilsHLSL.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = UtilsHLSL.cpp; sourceTree = "<group>"; };
@@ -2990,6 +2993,8 @@
FF81FE8225818D6800894E24 /* DisplayMtl_api.h */,
FF81FEBC25818D6800894E24 /* FrameBufferMtl.h */,
FF81FEC925818D6800894E24 /* FrameBufferMtl.mm */,
+ 3154A846266C4AFF00BF33B7 /* ImageMtl.h */,
+ 3154A845266C4AFE00BF33B7 /* ImageMtl.mm */,
FF81FEA525818D6800894E24 /* IOSurfaceSurfaceMtl.h */,
FF81FE9E25818D6800894E24 /* IOSurfaceSurfaceMtl.mm */,
FF81FEC125818D6800894E24 /* mtl_buffer_pool.h */,
@@ -3782,6 +3787,7 @@
DF83E2932639FD83000825EF /* ImageFunctionHLSL.cpp in Sources */,
DF83E34B2639FE92000825EF /* ImageGL.cpp in Sources */,
DF83E3212639FE18000825EF /* ImageIndex.cpp in Sources */,
+ 3154A847266C4AFF00BF33B7 /* ImageMtl.mm in Sources */,
DF83E2C62639FD84000825EF /* ImmutableString_autogen.cpp in Sources */,
DF83E2992639FD83000825EF /* ImmutableStringBuilder.cpp in Sources */,
DF83E31B2639FE17000825EF /* IndexRangeCache.cpp in Sources */,
Modified: trunk/Source/ThirdParty/ANGLE/ChangeLog (279142 => 279143)
--- trunk/Source/ThirdParty/ANGLE/ChangeLog 2021-06-22 20:26:10 UTC (rev 279142)
+++ trunk/Source/ThirdParty/ANGLE/ChangeLog 2021-06-22 20:33:10 UTC (rev 279143)
@@ -1,3 +1,90 @@
+2021-06-22 Dean Jackson <d...@apple.com>
+
+ [ANGLE] Support importing external MTLTextures
+ https://bugs.webkit.org/show_bug.cgi?id=226690
+
+ Reviewed by Tim Horton.
+
+ Support MTLTextures as GL textures.
+ Merge https://chromium-review.googlesource.com/c/angle/angle/+/2820178
+
+ * ANGLE.xcodeproj/project.pbxproj:
+ * extensions/EGL_ANGLE_metal_texture_client_buffer.txt: Added.
+ * include/EGL/eglext_angle.h:
+ * src/common/utilities.cpp:
+ (egl::IsExternalImageTarget):
+ * src/libANGLE/Caps.cpp:
+ (egl::DisplayExtensions::getStrings const):
+ * src/libANGLE/Caps.h:
+ * src/libANGLE/renderer/metal/BUILD.gn:
+ * src/libANGLE/renderer/metal/DisplayMtl.h:
+ * src/libANGLE/renderer/metal/DisplayMtl.mm:
+ (rx::DisplayMtl::createImage):
+ (rx::DisplayMtl::createExternalImageSibling):
+ (rx::DisplayMtl::generateExtensions const):
+ (rx::DisplayMtl::validateImageClientBuffer const):
+ (rx::DisplayMtl::initializeExtensions const):
+ * src/libANGLE/renderer/metal/ImageMtl.h: Added.
+ (rx::TextureImageSiblingMtl::getTexture const):
+ (rx::TextureImageSiblingMtl::getFormatMtl const):
+ (rx::ImageMtl::getTexture const):
+ (rx::ImageMtl::getImageTextureType const):
+ (rx::ImageMtl::getImageLevel const):
+ (rx::ImageMtl::getImageLayer const):
+ * src/libANGLE/renderer/metal/ImageMtl.mm: Added.
+ (rx::TextureImageSiblingMtl::TextureImageSiblingMtl):
+ (rx::TextureImageSiblingMtl::~TextureImageSiblingMtl):
+ (rx::TextureImageSiblingMtl::ValidateClientBuffer):
+ (rx::TextureImageSiblingMtl::initialize):
+ (rx::TextureImageSiblingMtl::initImpl):
+ (rx::TextureImageSiblingMtl::onDestroy):
+ (rx::TextureImageSiblingMtl::getFormat const):
+ (rx::TextureImageSiblingMtl::isRenderable const):
+ (rx::TextureImageSiblingMtl::isTexturable const):
+ (rx::TextureImageSiblingMtl::getSize const):
+ (rx::TextureImageSiblingMtl::getSamples const):
+ (rx::ImageMtl::ImageMtl):
+ (rx::ImageMtl::~ImageMtl):
+ (rx::ImageMtl::onDestroy):
+ (rx::ImageMtl::initialize):
+ (rx::ImageMtl::orphan):
+ * src/libANGLE/renderer/metal/RenderBufferMtl.mm:
+ (rx::RenderbufferMtl::setStorageEGLImageTarget):
+ * src/libANGLE/renderer/metal/TextureMtl.mm:
+ (rx::TextureMtl::setEGLImageTarget):
+ * src/libANGLE/renderer/metal/gen_mtl_format_table.py:
+ (gen_image_map_switch_mac_case.gen_format_assign_code):
+ (gen_image_mtl_to_angle_switch_string):
+ (main):
+ * src/libANGLE/renderer/metal/mtl_common.h:
+ * src/libANGLE/renderer/metal/mtl_format_table_autogen.mm:
+ (rx::mtl::Format::MetalToAngleFormatID):
+ * src/libANGLE/renderer/metal/mtl_format_utils.h:
+ * src/libANGLE/validationEGL.cpp:
+ (egl::ValidateCreateImage):
+ * src/tests/BUILD.gn:
+ * src/tests/gl_tests/ImageTest.cpp:
+ (angle::TEST_P):
+ * src/tests/gl_tests/ImageTestMetal.mm: Added.
+ (angle::ScopeMetalTextureRef::ScopeMetalTextureRef):
+ (angle::ScopeMetalTextureRef::~ScopeMetalTextureRef):
+ (angle::ScopeMetalTextureRef::get const):
+ (angle::ScopeMetalTextureRef::operator id<MTLTexture> const):
+ (angle::ScopeMetalTextureRef::operator=):
+ (angle::ScopeMetalTextureRef::release):
+ (angle::CreateMetalTexture2D):
+ (angle::ImageTestMetal::ImageTestMetal):
+ (angle::ImageTestMetal::getMtlDevice):
+ (angle::ImageTestMetal::createMtlTexture2D):
+ (angle::ImageTestMetal::verifyResultsTexture):
+ (angle::ImageTestMetal::verifyResults2D):
+ (angle::ImageTestMetal::reinterpretHelper):
+ (angle::ImageTestMetal::hasImageNativeMetalTextureExt const):
+ (angle::ImageTestMetal::hasOESExt const):
+ (angle::ImageTestMetal::hasBaseExt const):
+ (angle::ImageTestMetal::sourceMetalTarget2D_helper):
+ (angle::TEST_P):
+
2021-06-17 Kyle Piddington <kpidding...@apple.com>
[Metal ANGLE] Shaders with reserved metal keywords do not translate, nor do shaders with struct and variable names that are the same except prefixed by an underscore
Added: trunk/Source/ThirdParty/ANGLE/extensions/EGL_ANGLE_metal_texture_client_buffer.txt (0 => 279143)
--- trunk/Source/ThirdParty/ANGLE/extensions/EGL_ANGLE_metal_texture_client_buffer.txt (rev 0)
+++ trunk/Source/ThirdParty/ANGLE/extensions/EGL_ANGLE_metal_texture_client_buffer.txt 2021-06-22 20:33:10 UTC (rev 279143)
@@ -0,0 +1,82 @@
+Name
+
+ ANGLE_metal_texture_client_buffer
+
+Name Strings
+
+ EGL_ANGLE_metal_texture_client_buffer
+
+Contributors
+
+ Le Hoang Quyen
+
+Contacts
+
+ Jamie Madill, Google (jmadill 'at' google 'dot' com)
+ Le Hoang Quyen (lehoangq 'at' gmail.com)
+
+Status
+
+ Draft
+
+Version
+ Version 1, Jul 19, 2020
+
+Number
+
+ EGL Extension #??
+
+Dependencies
+
+ This extension is written against the wording of the EGL 1.4
+ Specification.
+
+Overview
+
+ This extension allows creating EGL images from external metal texture objects.
+
+New Types
+
+ None
+
+New Procedures and Functions
+
+ None
+
+New Tokens
+
+ Accepted in the <target> parameter of eglCreateImageKHR:
+
+ EGL_METAL_TEXTURE_ANGLE 0x34A7
+
+Additions to Chapter 2 of the EGL 1.2 Specification (EGL Operation)
+
+ Add to section 2.5.1 "EGLImage Specification" (as defined by the
+ EGL_KHR_image_base specification), in the description of
+ eglCreateImageKHR:
+
+ "Values accepted for <target> are listed in Table aaa, below.
+
+ +----------------------------+-----------------------------------------+
+ | <target> | Notes |
+ +----------------------------+-----------------------------------------+
+ | EGL_METAL_TEXTURE_ANGLE | Used for Metal texture objects |
+ +----------------------------+-----------------------------------------+
+ Table aaa. Legal values for eglCreateImageKHR <target> parameter
+
+ ...
+
+ If <target> is EGL_METAL_TEXTURE_ANGLE, <dpy> must be a valid display, <ctx>
+ must be EGL_NO_CONTEXT, <buffer> must be a pointer to a valid MTLTexture
+ object (cast into the type EGLClientBuffer), and attributes are ignored.
+ The width and height of the pbuffer are determined by the width and height
+ of <buffer>."
+
+ If the EGL_ANGLE_device_metal extension is present, the provided Metal texture
+ object must have been created by the same Metal device queried from the
+ display. If these requirements are not met, an EGL_BAD_PARAMETER error is
+ generated."
+
+Revision History
+
+ Version 1, 2020/19/07 - First draft
Property changes on: trunk/Source/ThirdParty/ANGLE/extensions/EGL_ANGLE_metal_texture_client_buffer.txt
___________________________________________________________________
Added: svn:eol-style
+native
\ No newline at end of property
Added: svn:keywords
+Date Revision
\ No newline at end of property
Added: svn:mime-type
+text/plain
\ No newline at end of property
Modified: trunk/Source/ThirdParty/ANGLE/include/EGL/eglext_angle.h (279142 => 279143)
--- trunk/Source/ThirdParty/ANGLE/include/EGL/eglext_angle.h 2021-06-22 20:26:10 UTC (rev 279142)
+++ trunk/Source/ThirdParty/ANGLE/include/EGL/eglext_angle.h 2021-06-22 20:33:10 UTC (rev 279143)
@@ -226,6 +226,11 @@
#define EGL_BIND_TO_TEXTURE_TARGET_ANGLE 0x348D
#endif /* EGL_ANGLE_iosurface_client_buffer */
+#ifndef ANGLE_metal_texture_client_buffer
+#define ANGLE_metal_texture_client_buffer 1
+#define EGL_METAL_TEXTURE_ANGLE 0x34A7
+#endif /* ANGLE_metal_texture_client_buffer */
+
#ifndef EGL_ANGLE_create_context_extensions_enabled
#define EGL_ANGLE_create_context_extensions_enabled 1
#define EGL_EXTENSIONS_ENABLED_ANGLE 0x345F
Modified: trunk/Source/ThirdParty/ANGLE/src/common/utilities.cpp (279142 => 279143)
--- trunk/Source/ThirdParty/ANGLE/src/common/utilities.cpp 2021-06-22 20:26:10 UTC (rev 279142)
+++ trunk/Source/ThirdParty/ANGLE/src/common/utilities.cpp 2021-06-22 20:33:10 UTC (rev 279143)
@@ -1219,6 +1219,7 @@
case EGL_NATIVE_BUFFER_ANDROID:
case EGL_D3D11_TEXTURE_ANGLE:
case EGL_LINUX_DMA_BUF_EXT:
+ case EGL_METAL_TEXTURE_ANGLE:
return true;
default:
Modified: trunk/Source/ThirdParty/ANGLE/src/libANGLE/Caps.cpp (279142 => 279143)
--- trunk/Source/ThirdParty/ANGLE/src/libANGLE/Caps.cpp 2021-06-22 20:26:10 UTC (rev 279142)
+++ trunk/Source/ThirdParty/ANGLE/src/libANGLE/Caps.cpp 2021-06-22 20:33:10 UTC (rev 279143)
@@ -1417,6 +1417,7 @@
InsertExtensionString("EGL_ANGLE_program_cache_control", programCacheControl, &extensionStrings);
InsertExtensionString("EGL_ANGLE_robust_resource_initialization", robustResourceInitialization, &extensionStrings);
InsertExtensionString("EGL_ANGLE_iosurface_client_buffer", iosurfaceClientBuffer, &extensionStrings);
+ InsertExtensionString("EGL_ANGLE_metal_texture_client_buffer", mtlTextureClientBuffer, &extensionStrings);
InsertExtensionString("EGL_ANGLE_create_context_extensions_enabled", createContextExtensionsEnabled, &extensionStrings);
InsertExtensionString("EGL_ANDROID_presentation_time", presentationTime, &extensionStrings);
InsertExtensionString("EGL_ANDROID_blob_cache", blobCache, &extensionStrings);
Modified: trunk/Source/ThirdParty/ANGLE/src/libANGLE/Caps.h (279142 => 279143)
--- trunk/Source/ThirdParty/ANGLE/src/libANGLE/Caps.h 2021-06-22 20:26:10 UTC (rev 279142)
+++ trunk/Source/ThirdParty/ANGLE/src/libANGLE/Caps.h 2021-06-22 20:33:10 UTC (rev 279143)
@@ -1076,6 +1076,9 @@
// EGL_ANGLE_iosurface_client_buffer
bool iosurfaceClientBuffer = false;
+ // EGL_ANGLE_metal_texture_client_buffer
+ bool mtlTextureClientBuffer = false;
+
// EGL_ANGLE_create_context_extensions_enabled
bool createContextExtensionsEnabled = false;
Modified: trunk/Source/ThirdParty/ANGLE/src/libANGLE/renderer/metal/BUILD.gn (279142 => 279143)
--- trunk/Source/ThirdParty/ANGLE/src/libANGLE/renderer/metal/BUILD.gn 2021-06-22 20:26:10 UTC (rev 279142)
+++ trunk/Source/ThirdParty/ANGLE/src/libANGLE/renderer/metal/BUILD.gn 2021-06-22 20:33:10 UTC (rev 279143)
@@ -23,6 +23,8 @@
"FrameBufferMtl.mm",
"IOSurfaceSurfaceMtl.h",
"IOSurfaceSurfaceMtl.mm",
+ "ImageMtl.h",
+ "ImageMtl.mm",
"ProgramMtl.h",
"ProgramMtl.mm",
"QueryMtl.h",
Modified: trunk/Source/ThirdParty/ANGLE/src/libANGLE/renderer/metal/DisplayMtl.h (279142 => 279143)
--- trunk/Source/ThirdParty/ANGLE/src/libANGLE/renderer/metal/DisplayMtl.h 2021-06-22 20:26:10 UTC (rev 279142)
+++ trunk/Source/ThirdParty/ANGLE/src/libANGLE/renderer/metal/DisplayMtl.h 2021-06-22 20:33:10 UTC (rev 279143)
@@ -86,6 +86,10 @@
ShareGroupImpl *createShareGroup() override;
+ ExternalImageSiblingImpl *createExternalImageSibling(const gl::Context *context,
+ EGLenum target,
+ EGLClientBuffer buffer,
+ const egl::AttributeMap &attribs) override;
gl::Version getMaxSupportedESVersion() const override;
gl::Version getMaxConformantESVersion() const override;
@@ -100,6 +104,11 @@
bool isValidNativeWindow(EGLNativeWindowType window) const override;
+ egl::Error validateImageClientBuffer(const gl::Context *context,
+ EGLenum target,
+ EGLClientBuffer clientBuffer,
+ const egl::AttributeMap &attribs) const override;
+
egl::ConfigSet generateConfigs() override;
std::string getRendererDescription() const;
Modified: trunk/Source/ThirdParty/ANGLE/src/libANGLE/renderer/metal/DisplayMtl.mm (279142 => 279143)
--- trunk/Source/ThirdParty/ANGLE/src/libANGLE/renderer/metal/DisplayMtl.mm 2021-06-22 20:26:10 UTC (rev 279142)
+++ trunk/Source/ThirdParty/ANGLE/src/libANGLE/renderer/metal/DisplayMtl.mm 2021-06-22 20:33:10 UTC (rev 279143)
@@ -17,6 +17,7 @@
#include "libANGLE/renderer/glslang_wrapper_utils.h"
#include "libANGLE/renderer/metal/ContextMtl.h"
#include "libANGLE/renderer/metal/IOSurfaceSurfaceMtl.h"
+#include "libANGLE/renderer/metal/ImageMtl.h"
#include "libANGLE/renderer/metal/SurfaceMtl.h"
#include "libANGLE/renderer/metal/SyncMtl.h"
#include "libANGLE/renderer/metal/mtl_common.h"
@@ -347,8 +348,7 @@
EGLenum target,
const egl::AttributeMap &attribs)
{
- UNIMPLEMENTED();
- return nullptr;
+ return new ImageMtl(state, context);
}
rx::ContextImpl *DisplayMtl::createContext(const gl::State &state,
@@ -368,6 +368,22 @@
return nullptr;
}
+ExternalImageSiblingImpl *DisplayMtl::createExternalImageSibling(const gl::Context *context,
+ EGLenum target,
+ EGLClientBuffer buffer,
+ const egl::AttributeMap &attribs)
+{
+ switch (target)
+ {
+ case EGL_METAL_TEXTURE_ANGLE:
+ return new TextureImageSiblingMtl(buffer);
+
+ default:
+ UNREACHABLE();
+ return nullptr;
+ }
+}
+
gl::Version DisplayMtl::getMaxSupportedESVersion() const
{
// NOTE(hqle): Supports GLES 3.0 on iOS GPU Family 4+ for now.
@@ -418,6 +434,7 @@
outExtensions->surfacelessContext = true;
outExtensions->displayTextureShareGroup = true;
outExtensions->displaySemaphoreShareGroup = true;
+ outExtensions->mtlTextureClientBuffer = true;
if (mFeatures.hasEvents.enabled)
{
@@ -431,6 +448,10 @@
// this extension (anglebug.com/4929)
outExtensions->robustResourceInitialization = true;
outExtensions->powerPreference = true;
+
+ // EGL_KHR_image
+ outExtensions->image = true;
+ outExtensions->imageBase = true;
}
void DisplayMtl::generateCaps(egl::Caps *outCaps) const {}
@@ -559,6 +580,26 @@
}
}
+egl::Error DisplayMtl::validateImageClientBuffer(const gl::Context *context,
+ EGLenum target,
+ EGLClientBuffer clientBuffer,
+ const egl::AttributeMap &attribs) const
+{
+ switch (target)
+ {
+ case EGL_METAL_TEXTURE_ANGLE:
+ if (!TextureImageSiblingMtl::ValidateClientBuffer(this, clientBuffer))
+ {
+ return egl::EglBadAttribute();
+ }
+ break;
+ default:
+ UNREACHABLE();
+ return egl::EglBadAttribute();
+ }
+ return egl::NoError();
+}
+
gl::Caps DisplayMtl::getNativeCaps() const
{
ensureCapsInitialized();
@@ -789,7 +830,7 @@
// Enable EXT_blend_minmax
mNativeExtensions.blendMinMax = true;
- mNativeExtensions.eglImageOES = false;
+ mNativeExtensions.eglImageOES = true;
mNativeExtensions.eglImageExternalOES = false;
// NOTE(hqle): Support GL_OES_EGL_image_external_essl3.
mNativeExtensions.eglImageExternalEssl3OES = false;
Added: trunk/Source/ThirdParty/ANGLE/src/libANGLE/renderer/metal/ImageMtl.h (0 => 279143)
--- trunk/Source/ThirdParty/ANGLE/src/libANGLE/renderer/metal/ImageMtl.h (rev 0)
+++ trunk/Source/ThirdParty/ANGLE/src/libANGLE/renderer/metal/ImageMtl.h 2021-06-22 20:33:10 UTC (rev 279143)
@@ -0,0 +1,80 @@
+//
+// 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.
+//
+// ImageMtl.h:
+// Defines the class interface for ImageMtl, implementing ImageImpl.
+//
+
+#ifndef LIBANGLE_RENDERER_METAL_IMAGEMTL_H
+#define LIBANGLE_RENDERER_METAL_IMAGEMTL_H
+
+#include "libANGLE/renderer/ImageImpl.h"
+#include "libANGLE/renderer/metal/mtl_resources.h"
+
+namespace rx
+{
+
+class DisplayMtl;
+
+class TextureImageSiblingMtl : public ExternalImageSiblingImpl
+{
+ public:
+ TextureImageSiblingMtl(EGLClientBuffer buffer);
+ ~TextureImageSiblingMtl() override;
+
+ static bool ValidateClientBuffer(const DisplayMtl *display, EGLClientBuffer buffer);
+
+ egl::Error initialize(const egl::Display *display) override;
+ void onDestroy(const egl::Display *display) override;
+
+ // ExternalImageSiblingImpl interface
+ gl::Format getFormat() const override;
+ bool isRenderable(const gl::Context *context) const override;
+ bool isTexturable(const gl::Context *context) const override;
+ gl::Extents getSize() const override;
+ size_t getSamples() const override;
+
+ const mtl::TextureRef &getTexture() const { return mNativeTexture; }
+ const mtl::Format &getFormatMtl() const { return mFormat; }
+
+ private:
+ angle::Result initImpl(DisplayMtl *display);
+
+ EGLClientBuffer mBuffer;
+ gl::Format mGLFormat;
+ mtl::Format mFormat;
+
+ bool mRenderable = false;
+ bool mTextureable = false;
+
+ mtl::TextureRef mNativeTexture;
+};
+
+class ImageMtl : public ImageImpl
+{
+ public:
+ ImageMtl(const egl::ImageState &state, const gl::Context *context);
+ ~ImageMtl() override;
+ void onDestroy(const egl::Display *display) override;
+
+ egl::Error initialize(const egl::Display *display) override;
+
+ angle::Result orphan(const gl::Context *context, egl::ImageSibling *sibling) override;
+
+ const mtl::TextureRef &getTexture() const { return mNativeTexture; }
+ gl::TextureType getImageTextureType() const { return mImageTextureType; }
+ uint32_t getImageLevel() const { return mImageLevel; }
+ uint32_t getImageLayer() const { return mImageLayer; }
+
+ private:
+ gl::TextureType mImageTextureType;
+ uint32_t mImageLevel = 0;
+ uint32_t mImageLayer = 0;
+
+ mtl::TextureRef mNativeTexture;
+};
+} // namespace rx
+
+#endif /* LIBANGLE_RENDERER_METAL_IMAGEMTL_H */
Property changes on: trunk/Source/ThirdParty/ANGLE/src/libANGLE/renderer/metal/ImageMtl.h
___________________________________________________________________
Added: svn:eol-style
+native
\ No newline at end of property
Added: svn:keywords
+Date Author Id Revision HeadURL
\ No newline at end of property
Added: trunk/Source/ThirdParty/ANGLE/src/libANGLE/renderer/metal/ImageMtl.mm (0 => 279143)
--- trunk/Source/ThirdParty/ANGLE/src/libANGLE/renderer/metal/ImageMtl.mm (rev 0)
+++ trunk/Source/ThirdParty/ANGLE/src/libANGLE/renderer/metal/ImageMtl.mm 2021-06-22 20:33:10 UTC (rev 279143)
@@ -0,0 +1,168 @@
+//
+// 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.
+//
+// ImageMtl.cpp:
+// Implements the class methods for ImageMtl.
+//
+
+#include "libANGLE/renderer/metal/ImageMtl.h"
+
+#include "common/debug.h"
+#include "libANGLE/Context.h"
+#include "libANGLE/Display.h"
+#include "libANGLE/renderer/metal/ContextMtl.h"
+#include "libANGLE/renderer/metal/DisplayMtl.h"
+#include "libANGLE/renderer/metal/RenderBufferMtl.h"
+#include "libANGLE/renderer/metal/TextureMtl.h"
+
+namespace rx
+{
+
+// TextureImageSiblingMtl implementation
+TextureImageSiblingMtl::TextureImageSiblingMtl(EGLClientBuffer buffer)
+ : mBuffer(buffer), mGLFormat(GL_NONE)
+{}
+
+TextureImageSiblingMtl::~TextureImageSiblingMtl() {}
+
+// Static
+bool TextureImageSiblingMtl::ValidateClientBuffer(const DisplayMtl *display, EGLClientBuffer buffer)
+{
+ id<MTLTexture> texture = (__bridge id<MTLTexture>)(buffer);
+ if (!texture || texture.device != display->getMetalDevice())
+ {
+ return false;
+ }
+
+ if (texture.textureType != MTLTextureType2D && texture.textureType != MTLTextureTypeCube)
+ {
+ return false;
+ }
+
+ angle::FormatID angleFormatId = mtl::Format::MetalToAngleFormatID(texture.pixelFormat);
+ const mtl::Format &format = display->getPixelFormat(angleFormatId);
+ if (!format.valid())
+ {
+ ERR() << "Unrecognized format";
+ // Not supported
+ return false;
+ }
+
+ return true;
+}
+
+egl::Error TextureImageSiblingMtl::initialize(const egl::Display *display)
+{
+ DisplayMtl *displayMtl = mtl::GetImpl(display);
+ if (initImpl(displayMtl) != angle::Result::Continue)
+ {
+ return egl::EglBadParameter();
+ }
+
+ return egl::NoError();
+}
+
+angle::Result TextureImageSiblingMtl::initImpl(DisplayMtl *displayMtl)
+{
+ mNativeTexture = mtl::Texture::MakeFromMetal((__bridge id<MTLTexture>)(mBuffer));
+
+ angle::FormatID angleFormatId =
+ mtl::Format::MetalToAngleFormatID(mNativeTexture->pixelFormat());
+ mFormat = displayMtl->getPixelFormat(angleFormatId);
+
+ mGLFormat = gl::Format(mFormat.intendedAngleFormat().glInternalFormat);
+
+ mRenderable = mFormat.getCaps().depthRenderable || mFormat.getCaps().colorRenderable;
+
+ mTextureable = mFormat.getCaps().filterable || mFormat.hasDepthOrStencilBits();
+
+ return angle::Result::Continue;
+}
+
+void TextureImageSiblingMtl::onDestroy(const egl::Display *display)
+{
+ mNativeTexture = nullptr;
+}
+
+gl::Format TextureImageSiblingMtl::getFormat() const
+{
+ return mGLFormat;
+}
+
+bool TextureImageSiblingMtl::isRenderable(const gl::Context *context) const
+{
+ return mRenderable;
+}
+
+bool TextureImageSiblingMtl::isTexturable(const gl::Context *context) const
+{
+ return mTextureable;
+}
+
+gl::Extents TextureImageSiblingMtl::getSize() const
+{
+ return mNativeTexture ? mNativeTexture->sizeAt0() : gl::Extents(0, 0, 0);
+}
+
+size_t TextureImageSiblingMtl::getSamples() const
+{
+ uint32_t samples = mNativeTexture ? mNativeTexture->samples() : 0;
+ return samples > 1 ? samples : 0;
+}
+
+// ImageMtl implementation
+ImageMtl::ImageMtl(const egl::ImageState &state, const gl::Context *context) : ImageImpl(state) {}
+
+ImageMtl::~ImageMtl() {}
+
+void ImageMtl::onDestroy(const egl::Display *display)
+{
+ mNativeTexture = nullptr;
+}
+
+egl::Error ImageMtl::initialize(const egl::Display *display)
+{
+ if (mState.target == EGL_METAL_TEXTURE_ANGLE)
+ {
+ const TextureImageSiblingMtl *externalImageSibling =
+ GetImplAs<TextureImageSiblingMtl>(GetAs<egl::ExternalImageSibling>(mState.source));
+
+ mNativeTexture = externalImageSibling->getTexture();
+
+ switch (mNativeTexture->textureType())
+ {
+ case MTLTextureType2D:
+ mImageTextureType = gl::TextureType::_2D;
+ break;
+ case MTLTextureTypeCube:
+ mImageTextureType = gl::TextureType::CubeMap;
+ break;
+ default:
+ UNREACHABLE();
+ }
+
+ mImageLevel = 0;
+ mImageLayer = 0;
+ }
+ else
+ {
+ UNREACHABLE();
+ return egl::EglBadAccess();
+ }
+
+ return egl::NoError();
+}
+
+angle::Result ImageMtl::orphan(const gl::Context *context, egl::ImageSibling *sibling)
+{
+ if (sibling == mState.source)
+ {
+ mNativeTexture = nullptr;
+ }
+
+ return angle::Result::Continue;
+}
+
+} // namespace rx
Modified: trunk/Source/ThirdParty/ANGLE/src/libANGLE/renderer/metal/RenderBufferMtl.mm (279142 => 279143)
--- trunk/Source/ThirdParty/ANGLE/src/libANGLE/renderer/metal/RenderBufferMtl.mm 2021-06-22 20:26:10 UTC (rev 279142)
+++ trunk/Source/ThirdParty/ANGLE/src/libANGLE/renderer/metal/RenderBufferMtl.mm 2021-06-22 20:33:10 UTC (rev 279143)
@@ -10,6 +10,7 @@
#include "libANGLE/renderer/metal/RenderBufferMtl.h"
#include "libANGLE/renderer/metal/ContextMtl.h"
+#include "libANGLE/renderer/metal/ImageMtl.h"
#include "libANGLE/renderer/metal/mtl_format_utils.h"
#include "libANGLE/renderer/metal/mtl_utils.h"
@@ -175,9 +176,20 @@
angle::Result RenderbufferMtl::setStorageEGLImageTarget(const gl::Context *context,
egl::Image *image)
{
- // NOTE(hqle): Support EGLimage
- UNIMPLEMENTED();
- return angle::Result::Stop;
+ releaseTexture();
+
+ ContextMtl *contextMtl = mtl::GetImpl(context);
+
+ ImageMtl *imageMtl = mtl::GetImpl(image);
+ mTexture = imageMtl->getTexture();
+
+ const angle::FormatID angleFormatId =
+ angle::Format::InternalFormatToID(image->getFormat().info->sizedInternalFormat);
+ mFormat = contextMtl->getPixelFormat(angleFormatId);
+
+ mRenderTarget.set(mTexture, mtl::kZeroNativeMipLevel, 0, mFormat);
+
+ return angle::Result::Continue;
}
angle::Result RenderbufferMtl::getAttachmentRenderTarget(const gl::Context *context,
Modified: trunk/Source/ThirdParty/ANGLE/src/libANGLE/renderer/metal/TextureMtl.mm (279142 => 279143)
--- trunk/Source/ThirdParty/ANGLE/src/libANGLE/renderer/metal/TextureMtl.mm 2021-06-22 20:26:10 UTC (rev 279142)
+++ trunk/Source/ThirdParty/ANGLE/src/libANGLE/renderer/metal/TextureMtl.mm 2021-06-22 20:33:10 UTC (rev 279143)
@@ -20,6 +20,7 @@
#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"
@@ -1234,9 +1235,32 @@
gl::TextureType type,
egl::Image *image)
{
- UNIMPLEMENTED();
+ releaseTexture(true);
- return angle::Result::Stop;
+ ContextMtl *contextMtl = mtl::GetImpl(context);
+
+ ImageMtl *imageMtl = mtl::GetImpl(image);
+ if (type != imageMtl->getImageTextureType())
+ {
+ return angle::Result::Stop;
+ }
+
+ mNativeTexture = imageMtl->getTexture();
+
+ const angle::FormatID angleFormatId =
+ angle::Format::InternalFormatToID(image->getFormat().info->sizedInternalFormat);
+ mFormat = contextMtl->getPixelFormat(angleFormatId);
+
+ mSlices = mNativeTexture->cubeFacesOrArrayLength();
+
+ gl::Extents size = mNativeTexture->sizeAt0();
+ mIsPow2 = gl::isPow2(size.width) && gl::isPow2(size.height) && gl::isPow2(size.depth);
+ ANGLE_TRY(ensureSamplerStateCreated(context));
+
+ // Tell context to rebind textures
+ contextMtl->invalidateCurrentTextures();
+
+ return angle::Result::Continue;
}
angle::Result TextureMtl::setImageExternal(const gl::Context *context,
Modified: trunk/Source/ThirdParty/ANGLE/src/libANGLE/renderer/metal/gen_mtl_format_table.py (279142 => 279143)
--- trunk/Source/ThirdParty/ANGLE/src/libANGLE/renderer/metal/gen_mtl_format_table.py 2021-06-22 20:26:10 UTC (rev 279142)
+++ trunk/Source/ThirdParty/ANGLE/src/libANGLE/renderer/metal/gen_mtl_format_table.py 2021-06-22 20:33:10 UTC (rev 279143)
@@ -46,6 +46,15 @@
namespace mtl
{{
+angle::FormatID Format::MetalToAngleFormatID(MTLPixelFormat formatMtl)
+{{
+ // Actual conversion
+ switch (formatMtl)
+ {{
+{mtl_pixel_format_switch}
+ }}
+}}
+
void Format::init(const DisplayMtl *display, angle::FormatID intendedFormatId_)
{{
this->intendedFormatId = intendedFormatId_;
@@ -154,6 +163,10 @@
"""
+case_image_mtl_to_angle_template = """ case {mtl_format}:
+ return angle::FormatID::{angle_format};
+"""
+
case_vertex_format_template1 = """ case angle::FormatID::{angle_format}:
this->metalFormat = {mtl_format};
this->actualFormatId = angle::FormatID::{actual_angle_format};
@@ -304,6 +317,8 @@
# This format requires fallback when depth24Stencil8PixelFormatSupported flag is false.
# Fallback format:
actual_angle_format_fallback = mac_fallbacks[actual_angle_format]
+ fallback_condition = "metalDevice.depth24Stencil8PixelFormatSupported && \
+ !display->getFeatures().forceD24S8AsUnsupported.enabled"
# return if else block:
return image_format_assign_template2.format(
actual_angle_format=actual_angle_format,
@@ -433,6 +448,40 @@
return switch_data
+def gen_image_mtl_to_angle_switch_string(image_table):
+ angle_to_mtl = image_table["map"]
+ mac_specific_map = image_table["map_mac"]
+ ios_specific_map = image_table["map_ios"]
+
+ switch_data = ''
+
+ # Common case
+ for angle_format in sorted(angle_to_mtl.keys()):
+ switch_data += case_image_mtl_to_angle_template.format(
+ mtl_format=angle_to_mtl[angle_format], angle_format=angle_format)
+
+ # Mac specific
+ switch_data += "#if TARGET_OS_OSX || TARGET_OS_MACCATALYST\n"
+ for angle_format in sorted(mac_specific_map.keys()):
+ switch_data += case_image_mtl_to_angle_template.format(
+ mtl_format=mac_specific_map[angle_format], angle_format=angle_format)
+ switch_data += "#endif // TARGET_OS_OSX || TARGET_OS_MACCATALYST\n"
+
+ # iOS + macOS 11.0+ specific
+ switch_data += "#if TARGET_OS_IOS || TARGET_OS_TV || (TARGET_OS_OSX && (__MAC_OS_X_VERSION_MAX_ALLOWED >= 101600))\n"
+ for angle_format in sorted(ios_specific_map.keys()):
+ # ETC1_R8G8B8_UNORM_BLOCK is a duplicated of ETC2_R8G8B8_UNORM_BLOCK
+ if angle_format == 'ETC1_R8G8B8_UNORM_BLOCK':
+ continue
+ switch_data += case_image_mtl_to_angle_template.format(
+ mtl_format=ios_specific_map[angle_format], angle_format=angle_format)
+ switch_data += "#endif // TARGET_OS_IOS || TARGET_OS_TV || mac 11.0+\n"
+
+ switch_data += " default:\n"
+ switch_data += " return angle::FormatID::NONE;\n"
+ return switch_data
+
+
def gen_vertex_map_switch_case(angle_fmt, actual_angle_fmt, angle_to_mtl_map, override_packed_map):
mtl_format = angle_to_mtl_map[actual_angle_fmt]
copy_function, default_alpha, same_gl_type = get_vertex_copy_function_and_default_alpha(
@@ -555,6 +604,7 @@
map_vertex = map_json["vertex"]
image_switch_data = gen_image_map_switch_string(map_image, angle_to_gl)
+ image_mtl_to_angle_switch_data = gen_image_mtl_to_angle_switch_string(map_image)
vertex_switch_data = gen_vertex_map_switch_string(map_vertex)
Modified: trunk/Source/ThirdParty/ANGLE/src/libANGLE/renderer/metal/mtl_common.h (279142 => 279143)
--- trunk/Source/ThirdParty/ANGLE/src/libANGLE/renderer/metal/mtl_common.h 2021-06-22 20:26:10 UTC (rev 279142)
+++ trunk/Source/ThirdParty/ANGLE/src/libANGLE/renderer/metal/mtl_common.h 2021-06-22 20:33:10 UTC (rev 279143)
@@ -108,6 +108,7 @@
class ContextMtl;
class FramebufferMtl;
class BufferMtl;
+class ImageMtl;
class VertexArrayMtl;
class TextureMtl;
class ProgramMtl;
@@ -170,6 +171,13 @@
{
using ImplType = DisplayMtl;
};
+
+template <>
+struct ImplTypeHelper<egl::Image>
+{
+ using ImplType = ImageMtl;
+};
+
template <typename T>
using GetImplType = typename ImplTypeHelper<T>::ImplType;
Modified: trunk/Source/ThirdParty/ANGLE/src/libANGLE/renderer/metal/mtl_format_table_autogen.mm (279142 => 279143)
--- trunk/Source/ThirdParty/ANGLE/src/libANGLE/renderer/metal/mtl_format_table_autogen.mm 2021-06-22 20:26:10 UTC (rev 279142)
+++ trunk/Source/ThirdParty/ANGLE/src/libANGLE/renderer/metal/mtl_format_table_autogen.mm 2021-06-22 20:33:10 UTC (rev 279143)
@@ -26,6 +26,248 @@
namespace mtl
{
+angle::FormatID Format::MetalToAngleFormatID(MTLPixelFormat formatMtl)
+{
+ // Actual conversion
+ switch (formatMtl)
+ {
+ case MTLPixelFormatA8Unorm:
+ return angle::FormatID::A8_UNORM;
+ case MTLPixelFormatBGR10A2Unorm:
+ return angle::FormatID::B10G10R10A2_UNORM;
+ case MTLPixelFormatBGRA8Unorm:
+ return angle::FormatID::B8G8R8A8_UNORM;
+ case MTLPixelFormatBGRA8Unorm_sRGB:
+ return angle::FormatID::B8G8R8A8_UNORM_SRGB;
+ case MTLPixelFormatDepth32Float:
+ return angle::FormatID::D32_FLOAT;
+ case MTLPixelFormatDepth32Float_Stencil8:
+ return angle::FormatID::D32_FLOAT_S8X24_UINT;
+ case MTLPixelFormatInvalid:
+ return angle::FormatID::NONE;
+ case MTLPixelFormatRGB10A2Uint:
+ return angle::FormatID::R10G10B10A2_UINT;
+ case MTLPixelFormatRGB10A2Unorm:
+ return angle::FormatID::R10G10B10A2_UNORM;
+ case MTLPixelFormatRG11B10Float:
+ return angle::FormatID::R11G11B10_FLOAT;
+ case MTLPixelFormatRGBA16Float:
+ return angle::FormatID::R16G16B16A16_FLOAT;
+ case MTLPixelFormatRGBA16Sint:
+ return angle::FormatID::R16G16B16A16_SINT;
+ case MTLPixelFormatRGBA16Snorm:
+ return angle::FormatID::R16G16B16A16_SNORM;
+ case MTLPixelFormatRGBA16Uint:
+ return angle::FormatID::R16G16B16A16_UINT;
+ case MTLPixelFormatRGBA16Unorm:
+ return angle::FormatID::R16G16B16A16_UNORM;
+ case MTLPixelFormatRG16Float:
+ return angle::FormatID::R16G16_FLOAT;
+ case MTLPixelFormatRG16Sint:
+ return angle::FormatID::R16G16_SINT;
+ case MTLPixelFormatRG16Snorm:
+ return angle::FormatID::R16G16_SNORM;
+ case MTLPixelFormatRG16Uint:
+ return angle::FormatID::R16G16_UINT;
+ case MTLPixelFormatRG16Unorm:
+ return angle::FormatID::R16G16_UNORM;
+ case MTLPixelFormatR16Float:
+ return angle::FormatID::R16_FLOAT;
+ case MTLPixelFormatR16Sint:
+ return angle::FormatID::R16_SINT;
+ case MTLPixelFormatR16Snorm:
+ return angle::FormatID::R16_SNORM;
+ case MTLPixelFormatR16Uint:
+ return angle::FormatID::R16_UINT;
+ case MTLPixelFormatR16Unorm:
+ return angle::FormatID::R16_UNORM;
+ case MTLPixelFormatRGBA32Float:
+ return angle::FormatID::R32G32B32A32_FLOAT;
+ case MTLPixelFormatRGBA32Sint:
+ return angle::FormatID::R32G32B32A32_SINT;
+ case MTLPixelFormatRGBA32Uint:
+ return angle::FormatID::R32G32B32A32_UINT;
+ case MTLPixelFormatRG32Float:
+ return angle::FormatID::R32G32_FLOAT;
+ case MTLPixelFormatRG32Sint:
+ return angle::FormatID::R32G32_SINT;
+ case MTLPixelFormatRG32Uint:
+ return angle::FormatID::R32G32_UINT;
+ case MTLPixelFormatR32Float:
+ return angle::FormatID::R32_FLOAT;
+ case MTLPixelFormatR32Sint:
+ return angle::FormatID::R32_SINT;
+ case MTLPixelFormatR32Uint:
+ return angle::FormatID::R32_UINT;
+ case MTLPixelFormatRGBA8Sint:
+ return angle::FormatID::R8G8B8A8_SINT;
+ case MTLPixelFormatRGBA8Snorm:
+ return angle::FormatID::R8G8B8A8_SNORM;
+ case MTLPixelFormatRGBA8Uint:
+ return angle::FormatID::R8G8B8A8_UINT;
+ case MTLPixelFormatRGBA8Unorm:
+ return angle::FormatID::R8G8B8A8_UNORM;
+ case MTLPixelFormatRGBA8Unorm_sRGB:
+ return angle::FormatID::R8G8B8A8_UNORM_SRGB;
+ case MTLPixelFormatRG8Sint:
+ return angle::FormatID::R8G8_SINT;
+ case MTLPixelFormatRG8Snorm:
+ return angle::FormatID::R8G8_SNORM;
+ case MTLPixelFormatRG8Uint:
+ return angle::FormatID::R8G8_UINT;
+ case MTLPixelFormatRG8Unorm:
+ return angle::FormatID::R8G8_UNORM;
+ case MTLPixelFormatR8Sint:
+ return angle::FormatID::R8_SINT;
+ case MTLPixelFormatR8Snorm:
+ return angle::FormatID::R8_SNORM;
+ case MTLPixelFormatR8Uint:
+ return angle::FormatID::R8_UINT;
+ case MTLPixelFormatR8Unorm:
+ return angle::FormatID::R8_UNORM;
+ case MTLPixelFormatRGB9E5Float:
+ return angle::FormatID::R9G9B9E5_SHAREDEXP;
+ case MTLPixelFormatStencil8:
+ return angle::FormatID::S8_UINT;
+#if TARGET_OS_OSX || TARGET_OS_MACCATALYST
+ case MTLPixelFormatBC1_RGBA:
+ return angle::FormatID::BC1_RGBA_UNORM_BLOCK;
+ case MTLPixelFormatBC1_RGBA_sRGB:
+ return angle::FormatID::BC1_RGBA_UNORM_SRGB_BLOCK;
+ case MTLPixelFormatBC2_RGBA:
+ return angle::FormatID::BC2_RGBA_UNORM_BLOCK;
+ case MTLPixelFormatBC2_RGBA_sRGB:
+ return angle::FormatID::BC2_RGBA_UNORM_SRGB_BLOCK;
+ case MTLPixelFormatBC3_RGBA:
+ return angle::FormatID::BC3_RGBA_UNORM_BLOCK;
+ case MTLPixelFormatBC3_RGBA_sRGB:
+ return angle::FormatID::BC3_RGBA_UNORM_SRGB_BLOCK;
+ case MTLPixelFormatBC4_RSnorm:
+ return angle::FormatID::BC4_RED_SNORM_BLOCK;
+ case MTLPixelFormatBC4_RUnorm:
+ return angle::FormatID::BC4_RED_UNORM_BLOCK;
+ case MTLPixelFormatBC5_RGSnorm:
+ return angle::FormatID::BC5_RG_SNORM_BLOCK;
+ case MTLPixelFormatBC5_RGUnorm:
+ return angle::FormatID::BC5_RG_UNORM_BLOCK;
+ case MTLPixelFormatBC7_RGBAUnorm:
+ return angle::FormatID::BPTC_RGBA_UNORM_BLOCK;
+ case MTLPixelFormatBC6H_RGBFloat:
+ return angle::FormatID::BPTC_RGB_SIGNED_FLOAT_BLOCK;
+ case MTLPixelFormatBC6H_RGBUfloat:
+ return angle::FormatID::BPTC_RGB_UNSIGNED_FLOAT_BLOCK;
+ case MTLPixelFormatBC7_RGBAUnorm_sRGB:
+ return angle::FormatID::BPTC_SRGB_ALPHA_UNORM_BLOCK;
+ case MTLPixelFormatDepth16Unorm:
+ return angle::FormatID::D16_UNORM;
+ case MTLPixelFormatDepth24Unorm_Stencil8:
+ return angle::FormatID::D24_UNORM_S8_UINT;
+#endif // TARGET_OS_OSX || TARGET_OS_MACCATALYST
+#if TARGET_OS_IOS || TARGET_OS_TV || (TARGET_OS_OSX && (__MAC_OS_X_VERSION_MAX_ALLOWED >= 101600))
+ case MTLPixelFormatASTC_10x10_sRGB:
+ return angle::FormatID::ASTC_10x10_SRGB_BLOCK;
+ case MTLPixelFormatASTC_10x10_LDR:
+ return angle::FormatID::ASTC_10x10_UNORM_BLOCK;
+ case MTLPixelFormatASTC_10x5_sRGB:
+ return angle::FormatID::ASTC_10x5_SRGB_BLOCK;
+ case MTLPixelFormatASTC_10x5_LDR:
+ return angle::FormatID::ASTC_10x5_UNORM_BLOCK;
+ case MTLPixelFormatASTC_10x6_sRGB:
+ return angle::FormatID::ASTC_10x6_SRGB_BLOCK;
+ case MTLPixelFormatASTC_10x6_LDR:
+ return angle::FormatID::ASTC_10x6_UNORM_BLOCK;
+ case MTLPixelFormatASTC_10x8_sRGB:
+ return angle::FormatID::ASTC_10x8_SRGB_BLOCK;
+ case MTLPixelFormatASTC_10x8_LDR:
+ return angle::FormatID::ASTC_10x8_UNORM_BLOCK;
+ case MTLPixelFormatASTC_12x10_sRGB:
+ return angle::FormatID::ASTC_12x10_SRGB_BLOCK;
+ case MTLPixelFormatASTC_12x10_LDR:
+ return angle::FormatID::ASTC_12x10_UNORM_BLOCK;
+ case MTLPixelFormatASTC_12x12_sRGB:
+ return angle::FormatID::ASTC_12x12_SRGB_BLOCK;
+ case MTLPixelFormatASTC_12x12_LDR:
+ return angle::FormatID::ASTC_12x12_UNORM_BLOCK;
+ case MTLPixelFormatASTC_4x4_sRGB:
+ return angle::FormatID::ASTC_4x4_SRGB_BLOCK;
+ case MTLPixelFormatASTC_4x4_LDR:
+ return angle::FormatID::ASTC_4x4_UNORM_BLOCK;
+ case MTLPixelFormatASTC_5x4_sRGB:
+ return angle::FormatID::ASTC_5x4_SRGB_BLOCK;
+ case MTLPixelFormatASTC_5x4_LDR:
+ return angle::FormatID::ASTC_5x4_UNORM_BLOCK;
+ case MTLPixelFormatASTC_5x5_sRGB:
+ return angle::FormatID::ASTC_5x5_SRGB_BLOCK;
+ case MTLPixelFormatASTC_5x5_LDR:
+ return angle::FormatID::ASTC_5x5_UNORM_BLOCK;
+ case MTLPixelFormatASTC_6x5_sRGB:
+ return angle::FormatID::ASTC_6x5_SRGB_BLOCK;
+ case MTLPixelFormatASTC_6x5_LDR:
+ return angle::FormatID::ASTC_6x5_UNORM_BLOCK;
+ case MTLPixelFormatASTC_6x6_sRGB:
+ return angle::FormatID::ASTC_6x6_SRGB_BLOCK;
+ case MTLPixelFormatASTC_6x6_LDR:
+ return angle::FormatID::ASTC_6x6_UNORM_BLOCK;
+ case MTLPixelFormatASTC_8x5_sRGB:
+ return angle::FormatID::ASTC_8x5_SRGB_BLOCK;
+ case MTLPixelFormatASTC_8x5_LDR:
+ return angle::FormatID::ASTC_8x5_UNORM_BLOCK;
+ case MTLPixelFormatASTC_8x6_sRGB:
+ return angle::FormatID::ASTC_8x6_SRGB_BLOCK;
+ case MTLPixelFormatASTC_8x6_LDR:
+ return angle::FormatID::ASTC_8x6_UNORM_BLOCK;
+ case MTLPixelFormatASTC_8x8_sRGB:
+ return angle::FormatID::ASTC_8x8_SRGB_BLOCK;
+ case MTLPixelFormatASTC_8x8_LDR:
+ return angle::FormatID::ASTC_8x8_UNORM_BLOCK;
+ case MTLPixelFormatEAC_RG11Snorm:
+ return angle::FormatID::EAC_R11G11_SNORM_BLOCK;
+ case MTLPixelFormatEAC_RG11Unorm:
+ return angle::FormatID::EAC_R11G11_UNORM_BLOCK;
+ case MTLPixelFormatEAC_R11Snorm:
+ return angle::FormatID::EAC_R11_SNORM_BLOCK;
+ case MTLPixelFormatEAC_R11Unorm:
+ return angle::FormatID::EAC_R11_UNORM_BLOCK;
+ case MTLPixelFormatETC2_RGB8A1_sRGB:
+ return angle::FormatID::ETC2_R8G8B8A1_SRGB_BLOCK;
+ case MTLPixelFormatETC2_RGB8A1:
+ return angle::FormatID::ETC2_R8G8B8A1_UNORM_BLOCK;
+ case MTLPixelFormatEAC_RGBA8_sRGB:
+ return angle::FormatID::ETC2_R8G8B8A8_SRGB_BLOCK;
+ case MTLPixelFormatEAC_RGBA8:
+ return angle::FormatID::ETC2_R8G8B8A8_UNORM_BLOCK;
+ case MTLPixelFormatETC2_RGB8_sRGB:
+ return angle::FormatID::ETC2_R8G8B8_SRGB_BLOCK;
+ case MTLPixelFormatETC2_RGB8:
+ return angle::FormatID::ETC2_R8G8B8_UNORM_BLOCK;
+ case MTLPixelFormatPVRTC_RGBA_2BPP:
+ return angle::FormatID::PVRTC1_RGBA_2BPP_UNORM_BLOCK;
+ case MTLPixelFormatPVRTC_RGBA_2BPP_sRGB:
+ return angle::FormatID::PVRTC1_RGBA_2BPP_UNORM_SRGB_BLOCK;
+ case MTLPixelFormatPVRTC_RGBA_4BPP:
+ return angle::FormatID::PVRTC1_RGBA_4BPP_UNORM_BLOCK;
+ case MTLPixelFormatPVRTC_RGBA_4BPP_sRGB:
+ return angle::FormatID::PVRTC1_RGBA_4BPP_UNORM_SRGB_BLOCK;
+ case MTLPixelFormatPVRTC_RGB_2BPP:
+ return angle::FormatID::PVRTC1_RGB_2BPP_UNORM_BLOCK;
+ case MTLPixelFormatPVRTC_RGB_2BPP_sRGB:
+ return angle::FormatID::PVRTC1_RGB_2BPP_UNORM_SRGB_BLOCK;
+ case MTLPixelFormatPVRTC_RGB_4BPP:
+ return angle::FormatID::PVRTC1_RGB_4BPP_UNORM_BLOCK;
+ case MTLPixelFormatPVRTC_RGB_4BPP_sRGB:
+ return angle::FormatID::PVRTC1_RGB_4BPP_UNORM_SRGB_BLOCK;
+ case MTLPixelFormatABGR4Unorm:
+ return angle::FormatID::R4G4B4A4_UNORM;
+ case MTLPixelFormatA1BGR5Unorm:
+ return angle::FormatID::R5G5B5A1_UNORM;
+ case MTLPixelFormatB5G6R5Unorm:
+ return angle::FormatID::R5G6B5_UNORM;
+#endif // TARGET_OS_IOS || TARGET_OS_TV || mac 11.0+
+ default:
+ return angle::FormatID::NONE;
+ }
+}
+
void Format::init(const DisplayMtl *display, angle::FormatID intendedFormatId_)
{
this->intendedFormatId = intendedFormatId_;
Modified: trunk/Source/ThirdParty/ANGLE/src/libANGLE/renderer/metal/mtl_format_utils.h (279142 => 279143)
--- trunk/Source/ThirdParty/ANGLE/src/libANGLE/renderer/metal/mtl_format_utils.h 2021-06-22 20:26:10 UTC (rev 279142)
+++ trunk/Source/ThirdParty/ANGLE/src/libANGLE/renderer/metal/mtl_format_utils.h 2021-06-22 20:33:10 UTC (rev 279143)
@@ -69,6 +69,8 @@
{
Format() = default;
+ static angle::FormatID MetalToAngleFormatID(MTLPixelFormat formatMtl);
+
const gl::InternalFormat &intendedInternalFormat() const;
const gl::InternalFormat &actualInternalFormat() const;
Modified: trunk/Source/ThirdParty/ANGLE/src/libANGLE/validationEGL.cpp (279142 => 279143)
--- trunk/Source/ThirdParty/ANGLE/src/libANGLE/validationEGL.cpp 2021-06-22 20:26:10 UTC (rev 279142)
+++ trunk/Source/ThirdParty/ANGLE/src/libANGLE/validationEGL.cpp 2021-06-22 20:33:10 UTC (rev 279143)
@@ -2727,6 +2727,20 @@
}
break;
+ case EGL_METAL_TEXTURE_ANGLE:
+ if (!displayExtensions.mtlTextureClientBuffer)
+ {
+ return EglBadParameter() << "EGL_ANGLE_metal_texture_client_buffer not supported.";
+ }
+
+ if (context != nullptr)
+ {
+ return EglBadContext() << "ctx must be EGL_NO_CONTEXT.";
+ }
+
+ ANGLE_TRY(display->validateImageClientBuffer(context, target, buffer, attributes));
+ break;
+
default:
return EglBadParameter()
<< "invalid target: 0x" << std::hex << std::uppercase << target;
Modified: trunk/Source/ThirdParty/ANGLE/src/tests/BUILD.gn (279142 => 279143)
--- trunk/Source/ThirdParty/ANGLE/src/tests/BUILD.gn 2021-06-22 20:26:10 UTC (rev 279142)
+++ trunk/Source/ThirdParty/ANGLE/src/tests/BUILD.gn 2021-06-22 20:33:10 UTC (rev 279143)
@@ -155,6 +155,14 @@
"CoreFoundation.framework",
"IOSurface.framework",
]
+ ldflags = [
+ "-weak_framework",
+ "Metal",
+ ]
+ cflags_objcc = [
+ "-Wno-nullability-completeness",
+ "-Wno-unguarded-availability",
+ ]
}
if (is_win) {
sources += angle_end2end_tests_win_sources
Modified: trunk/Source/ThirdParty/ANGLE/src/tests/gl_tests/ImageTest.cpp (279142 => 279143)
--- trunk/Source/ThirdParty/ANGLE/src/tests/gl_tests/ImageTest.cpp 2021-06-22 20:26:10 UTC (rev 279142)
+++ trunk/Source/ThirdParty/ANGLE/src/tests/gl_tests/ImageTest.cpp 2021-06-22 20:33:10 UTC (rev 279143)
@@ -888,6 +888,22 @@
EXPECT_FALSE(hasExternalESSL3Ext());
}
}
+ else if (IsMetal())
+ {
+ // http://anglebug.com/5814
+ // http://anglebug.com/5841 (wrong detection of IsMetal() on macOS 11)
+ ANGLE_SKIP_TEST_IF(IsARM64());
+
+ // NOTE(hqle): Metal currently doesn't implement any image extensions besides
+ // EGL_ANGLE_metal_texture_client_buffer
+ EXPECT_TRUE(hasOESExt());
+ EXPECT_TRUE(hasBaseExt());
+ EXPECT_FALSE(hasExternalExt());
+ EXPECT_FALSE(hasExternalESSL3Ext());
+ EXPECT_FALSE(has2DTextureExt());
+ EXPECT_FALSE(has3DTextureExt());
+ EXPECT_FALSE(hasRenderbufferExt());
+ }
else
{
EXPECT_FALSE(hasOESExt());
Added: trunk/Source/ThirdParty/ANGLE/src/tests/gl_tests/ImageTestMetal.mm (0 => 279143)
--- trunk/Source/ThirdParty/ANGLE/src/tests/gl_tests/ImageTestMetal.mm (rev 0)
+++ trunk/Source/ThirdParty/ANGLE/src/tests/gl_tests/ImageTestMetal.mm 2021-06-22 20:33:10 UTC (rev 279143)
@@ -0,0 +1,360 @@
+//
+// 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.
+//
+// ImageTestMetal:
+// Tests the correctness of eglImage with native Metal texture extensions.
+//
+
+#include "test_utils/ANGLETest.h"
+
+#include "common/mathutil.h"
+#include "test_utils/gl_raii.h"
+#include "util/EGLWindow.h"
+
+#include <CoreFoundation/CoreFoundation.h>
+#include <Metal/Metal.h>
+
+namespace angle
+{
+namespace
+{
+constexpr char kOESExt[] = "GL_OES_EGL_image";
+constexpr char kBaseExt[] = "EGL_KHR_image_base";
+constexpr char kDeviceMtlExt[] = "EGL_ANGLE_device_metal";
+constexpr char kEGLMtlImageNativeTextureExt[] = "EGL_ANGLE_metal_texture_client_buffer";
+constexpr EGLint kDefaultAttribs[] = {
+ EGL_NONE,
+};
+} // anonymous namespace
+
+class ScopeMetalTextureRef : angle::NonCopyable
+{
+ public:
+ explicit ScopeMetalTextureRef(id<MTLTexture> surface) : mSurface(surface) {}
+
+ ~ScopeMetalTextureRef()
+ {
+ if (mSurface)
+ {
+ release();
+ mSurface = nullptr;
+ }
+ }
+
+ id<MTLTexture> get() const { return mSurface; }
+
+ // auto cast to MTLTexture
+ operator id<MTLTexture>() const { return mSurface; }
+ ScopeMetalTextureRef(const ScopeMetalTextureRef &other)
+ {
+ if (mSurface)
+ {
+ release();
+ }
+ mSurface = other.mSurface;
+ }
+
+ explicit ScopeMetalTextureRef(ScopeMetalTextureRef &&other)
+ {
+ if (mSurface)
+ {
+ release();
+ }
+ mSurface = other.mSurface;
+ other.mSurface = nil;
+ }
+
+ ScopeMetalTextureRef &operator=(ScopeMetalTextureRef &&other)
+ {
+ if (mSurface)
+ {
+ release();
+ }
+ mSurface = other.mSurface;
+ other.mSurface = nil;
+
+ return *this;
+ }
+
+ ScopeMetalTextureRef &operator=(const ScopeMetalTextureRef &other)
+ {
+ if (mSurface)
+ {
+ release();
+ }
+ mSurface = other.mSurface;
+
+ return *this;
+ }
+
+ private:
+ void release()
+ {
+#if !__has_feature(objc_arc)
+ [mSurface release];
+#endif
+ }
+
+ id<MTLTexture> mSurface = nil;
+};
+
+ScopeMetalTextureRef CreateMetalTexture2D(id<MTLDevice> deviceMtl,
+ int width,
+ int height,
+ MTLPixelFormat format)
+{
+ @autoreleasepool
+ {
+ MTLTextureDescriptor *desc = [MTLTextureDescriptor texture2DDescriptorWithPixelFormat:format
+ width:width
+ height:width
+ mipmapped:NO];
+ desc.usage = MTLTextureUsageShaderRead | MTLTextureUsageRenderTarget;
+
+ id<MTLTexture> texture = [deviceMtl newTextureWithDescriptor:desc];
+
+ ScopeMetalTextureRef re(texture);
+ return re;
+ }
+}
+
+class ImageTestMetal : public ANGLETest
+{
+ protected:
+ ImageTestMetal()
+ {
+ setWindowWidth(128);
+ setWindowHeight(128);
+ setConfigRedBits(8);
+ setConfigGreenBits(8);
+ setConfigBlueBits(8);
+ setConfigAlphaBits(8);
+ setConfigDepthBits(24);
+ }
+
+ void testSetUp() override
+ {
+ constexpr char kVS[] = "precision highp float;\n"
+ "attribute vec4 position;\n"
+ "varying vec2 texcoord;\n"
+ "\n"
+ "void main()\n"
+ "{\n"
+ " gl_Position = position;\n"
+ " texcoord = (position.xy * 0.5) + 0.5;\n"
+ " texcoord.y = 1.0 - texcoord.y;\n"
+ "}\n";
+
+ constexpr char kTextureFS[] = "precision highp float;\n"
+ "uniform sampler2D tex;\n"
+ "varying vec2 texcoord;\n"
+ "\n"
+ "void main()\n"
+ "{\n"
+ " gl_FragColor = texture2D(tex, texcoord);\n"
+ "}\n";
+
+ mTextureProgram = CompileProgram(kVS, kTextureFS);
+ if (mTextureProgram == 0)
+ {
+ FAIL() << "shader compilation failed.";
+ }
+
+ mTextureUniformLocation = glGetUniformLocation(mTextureProgram, "tex");
+
+ ASSERT_GL_NO_ERROR();
+ }
+
+ void testTearDown() override { glDeleteProgram(mTextureProgram); }
+
+ id<MTLDevice> getMtlDevice()
+ {
+ EGLAttrib angleDevice = 0;
+ EGLAttrib device = 0;
+ EXPECT_EGL_TRUE(
+ eglQueryDisplayAttribEXT(getEGLWindow()->getDisplay(), EGL_DEVICE_EXT, &angleDevice));
+
+ EXPECT_EGL_TRUE(eglQueryDeviceAttribEXT(reinterpret_cast<EGLDeviceEXT>(angleDevice),
+ EGL_METAL_DEVICE_ANGLE, &device));
+
+ return (__bridge id<MTLDevice>)reinterpret_cast<void *>(device);
+ }
+
+ ScopeMetalTextureRef createMtlTexture2D(int width, int height, MTLPixelFormat format)
+ {
+ id<MTLDevice> device = getMtlDevice();
+
+ return CreateMetalTexture2D(device, width, height, format);
+ }
+
+ void sourceMetalTarget2D_helper(GLubyte data[4],
+ const EGLint *attribs,
+ EGLImageKHR *imageOut,
+ GLuint *textureOut);
+
+ void verifyResultsTexture(GLuint texture,
+ GLubyte data[4],
+ GLenum textureTarget,
+ GLuint program,
+ GLuint textureUniform)
+ {
+ // Draw a quad with the target texture
+ glUseProgram(program);
+ glBindTexture(textureTarget, texture);
+ glUniform1i(textureUniform, 0);
+
+ drawQuad(program, "position", 0.5f);
+
+ // Expect that the rendered quad has the same color as the source texture
+ EXPECT_PIXEL_NEAR(0, 0, data[0], data[1], data[2], data[3], 1.0);
+ }
+
+ void verifyResults2D(GLuint texture, GLubyte data[4])
+ {
+ verifyResultsTexture(texture, data, GL_TEXTURE_2D, mTextureProgram,
+ mTextureUniformLocation);
+ }
+
+ template <typename destType, typename sourcetype>
+ destType reinterpretHelper(sourcetype source)
+ {
+ static_assert(sizeof(destType) == sizeof(size_t),
+ "destType should be the same size as a size_t");
+ size_t sourceSizeT = static_cast<size_t>(source);
+ return reinterpret_cast<destType>(sourceSizeT);
+ }
+
+ bool hasImageNativeMetalTextureExt() const
+ {
+ if (!IsMetal())
+ {
+ return false;
+ }
+ EGLAttrib angleDevice = 0;
+ eglQueryDisplayAttribEXT(getEGLWindow()->getDisplay(), EGL_DEVICE_EXT, &angleDevice);
+ if (!angleDevice)
+ {
+ return false;
+ }
+ auto extensionString = static_cast<const char *>(
+ eglQueryDeviceStringEXT(reinterpret_cast<EGLDeviceEXT>(angleDevice), EGL_EXTENSIONS));
+ if (strstr(extensionString, kDeviceMtlExt) == nullptr)
+ {
+ return false;
+ }
+ return IsEGLDisplayExtensionEnabled(getEGLWindow()->getDisplay(),
+ kEGLMtlImageNativeTextureExt);
+ }
+
+ bool hasOESExt() const { return IsGLExtensionEnabled(kOESExt); }
+
+ bool hasBaseExt() const
+ {
+ return IsEGLDisplayExtensionEnabled(getEGLWindow()->getDisplay(), kBaseExt);
+ }
+
+ GLuint mTextureProgram;
+ GLint mTextureUniformLocation;
+};
+
+void ImageTestMetal::sourceMetalTarget2D_helper(GLubyte data[4],
+ const EGLint *attribs,
+ EGLImageKHR *imageOut,
+ GLuint *textureOut)
+{
+ EGLWindow *window = getEGLWindow();
+
+ // Create MTLTexture
+ ScopeMetalTextureRef textureMtl = createMtlTexture2D(1, 1, MTLPixelFormatRGBA8Unorm);
+
+ // Create image
+ EGLImageKHR image =
+ eglCreateImageKHR(window->getDisplay(), EGL_NO_CONTEXT, EGL_METAL_TEXTURE_ANGLE,
+ reinterpret_cast<EGLClientBuffer>(textureMtl.get()), attribs);
+ ASSERT_EGL_SUCCESS();
+
+ // Write the data to the MTLTexture
+ [textureMtl.get() replaceRegion:MTLRegionMake2D(0, 0, 1, 1)
+ mipmapLevel:0
+ slice:0
+ withBytes:data
+ bytesPerRow:4
+ bytesPerImage:0];
+
+ // Create a texture target to bind the egl image
+ GLuint target;
+ glGenTextures(1, &target);
+ glBindTexture(GL_TEXTURE_2D, target);
+ glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, image);
+
+ *imageOut = image;
+ *textureOut = target;
+}
+
+// Testing source metal EGL image, target 2D texture
+TEST_P(ImageTestMetal, SourceMetalTarget2D)
+{
+ ANGLE_SKIP_TEST_IF(!hasOESExt() || !hasBaseExt());
+ ANGLE_SKIP_TEST_IF(!hasImageNativeMetalTextureExt());
+
+ EGLWindow *window = getEGLWindow();
+
+ // Create the Image
+ EGLImageKHR image;
+ GLuint texTarget;
+ GLubyte data[4] = {7, 51, 197, 231};
+ sourceMetalTarget2D_helper(data, kDefaultAttribs, &image, &texTarget);
+
+ // Use texture target bound to egl image as source and render to framebuffer
+ // Verify that data in framebuffer matches that in the egl image
+ verifyResults2D(texTarget, data);
+
+ // Clean up
+ eglDestroyImageKHR(window->getDisplay(), image);
+ glDeleteTextures(1, &texTarget);
+}
+
+// Create source metal EGL image, target 2D texture, then trigger texture respecification.
+TEST_P(ImageTestMetal, SourceMetal2DTargetTextureRespecifySize)
+{
+ ANGLE_SKIP_TEST_IF(!hasOESExt() || !hasBaseExt());
+ ANGLE_SKIP_TEST_IF(!hasImageNativeMetalTextureExt());
+
+ EGLWindow *window = getEGLWindow();
+
+ // Create the Image
+ EGLImageKHR image;
+ GLuint texTarget;
+ GLubyte data[4] = {7, 51, 197, 231};
+ sourceMetalTarget2D_helper(data, kDefaultAttribs, &image, &texTarget);
+
+ // Use texture target bound to egl image as source and render to framebuffer
+ // Verify that data in framebuffer matches that in the egl image
+ verifyResults2D(texTarget, data);
+
+ // Respecify texture size and verify results
+ std::array<GLubyte, 16> referenceColor;
+ referenceColor.fill(127);
+ glBindTexture(GL_TEXTURE_2D, texTarget);
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE,
+ referenceColor.data());
+ glTexImage2D(GL_TEXTURE_2D, 1, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE,
+ referenceColor.data());
+ ASSERT_GL_NO_ERROR();
+
+ // Expect that the target texture has the reference color values
+ verifyResults2D(texTarget, referenceColor.data());
+
+ // Clean up
+ eglDestroyImageKHR(window->getDisplay(), image);
+ glDeleteTextures(1, &texTarget);
+}
+
+// Use this to select which configurations (e.g. which renderer, which GLES major version) these
+// tests should be run against.
+ANGLE_INSTANTIATE_TEST(ImageTestMetal, ES2_METAL(), ES3_METAL());
+
+GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(ImageTestMetal);
+} // namespace angle