Title: [279143] trunk/Source/ThirdParty/ANGLE
Revision
279143
Author
d...@apple.com
Date
2021-06-22 13:33:10 -0700 (Tue, 22 Jun 2021)

Log Message

[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):

Modified Paths

Added Paths

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
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to