Commit 4ac6ea2a by Le Hoang Quyen Committed by Le Hoang Quyen

Metal: implement ANGLE_device_metal extension.

Allow user to query internal MTLDevice used by Metal back-end. Bug: angleproject:2634 Change-Id: I9b0a6eaad8c634069f43e47d5f4f88f61da35f74 Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/2757810Reviewed-by: 's avatarJonah Ryan-Davis <jonahr@google.com> Reviewed-by: 's avatarKenneth Russell <kbr@chromium.org> Reviewed-by: 's avatarJamie Madill <jmadill@chromium.org>
parent 3c98bb6a
Name
ANGLE_device_metal
Name Strings
EGL_ANGLE_device_metal
Contributors
Le Hoang Quyen
Contact
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 #XXX
Extension Type
EGL device extension
Dependencies
This extension is written against the language of EGL 1.5 as
modified by EGL_EXT_device_query.
EGL_EXT_device_query is required.
Overview
ANGLE has the ability to run GPU commands on a metal device.
This extension defines a mapping from an EGL device to a metal
device, after it's queried from an EGL display.
IP Status
No known claims.
New Types
None.
New Procedures and Functions
None.
New Tokens
Accepted as a queried <attribute> in eglQueryDeviceAttribEXT:
EGL_METAL_DEVICE_ANGLE 0x34A6
Add a new section 2.1.3 (Metal Devices) after 2.1.2 (Devices)
Somewhat analogous to an EGL device, a Metal device establishes a
namespace for Metal operations. In the Metal APIs, such devices are
represented by pointers. For more details, see the Metal
documentation.
Changes to section 3.2 (Devices)
Replace the paragraph immediately following the prototype for
eglQueryDeviceAttribEXT:
<attribute> may be EGL_METAL_DEVICE_ANGLE.
On success, EGL_TRUE is returned, and a valid MTLDevice pointer
corresponding to the EGL device is returned in <value>. This handle
is compatible with Metal API functions. If the EGL device is not currently
associated with a Metal device and <attribute> is EGL_METAL_DEVICE_ANGLE,
EGL_BAD_ATTRIBUTE is returned, and <value> is left unchanged.
Issues
None
Revision History
Version 1, Jul 19, 2020 (Le Hoang Quyen)
- Initial Draft
......@@ -333,6 +333,11 @@ EGLAPI EGLBoolean EGLAPIENTRY eglSwapBuffersWithFrameTokenANGLE(EGLDisplay dpy,
#define EGL_EAGL_CONTEXT_ANGLE 0x348C
#endif
#ifndef EGL_ANGLE_device_metal
#define EGL_ANGLE_device_metal 1
#define EGL_METAL_DEVICE_ANGLE 0x34A6
#endif /* EGL_ANGLE_device_metal */
#ifndef EGL_ANGLE_display_semaphore_share_group
#define EGL_ANGLE_display_semaphore_share_group 1
#define EGL_DISPLAY_SEMAPHORE_SHARE_GROUP_ANGLE 0x348D
......
......@@ -1491,6 +1491,7 @@ std::vector<std::string> DeviceExtensions::getStrings() const
InsertExtensionString("EGL_ANGLE_device_d3d", deviceD3D, &extensionStrings);
InsertExtensionString("EGL_ANGLE_device_cgl", deviceCGL, &extensionStrings);
InsertExtensionString("EGL_ANGLE_device_eagl", deviceEAGL, &extensionStrings);
InsertExtensionString("EGL_ANGLE_device_metal", deviceMetal, &extensionStrings);
// clang-format on
......
......@@ -1244,6 +1244,9 @@ struct DeviceExtensions
// EGL_ANGLE_device_eagl
bool deviceEAGL = false;
// EGL_ANGLE_device_metal
bool deviceMetal = false;
};
struct ClientExtensions
......
......@@ -16,6 +16,8 @@ _metal_backend_sources = [
"CompilerMtl.mm",
"ContextMtl.h",
"ContextMtl.mm",
"DeviceMtl.h",
"DeviceMtl.mm",
"DisplayMtl.h",
"DisplayMtl.mm",
"DisplayMtl_api.h",
......
//
// 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.
//
// DeviceMtl: Metal implementation of egl::Device
#ifndef LIBANGLE_RENDERER_METAL_DEVICEMTL_H_
#define LIBANGLE_RENDERER_METAL_DEVICEMTL_H_
#include "libANGLE/Device.h"
#include "libANGLE/renderer/DeviceImpl.h"
namespace rx
{
// DeviceMTL implementation, implements DeviceImpl
class DeviceMtl : public DeviceImpl
{
public:
DeviceMtl();
~DeviceMtl() override;
egl::Error initialize() override;
egl::Error getAttribute(const egl::Display *display,
EGLint attribute,
void **outValue) override;
EGLint getType() override;
void generateExtensions(egl::DeviceExtensions *outExtensions) const override;
};
} // namespace rx
#endif // LIBANGLE_RENDERER_METAL_DEVICEMTL_H_
//
// 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.
//
// DeviceMtl: Metal implementation of egl::Device
#include "libANGLE/renderer/metal/DeviceMtl.h"
#include "libANGLE/Device.h"
#include "libANGLE/Display.h"
#include "libANGLE/renderer/metal/DisplayMtl.h"
#include <EGL/eglext.h>
namespace rx
{
// DeviceMtl implementation, implements DeviceImpl
DeviceMtl::DeviceMtl() {}
DeviceMtl::~DeviceMtl() {}
egl::Error DeviceMtl::initialize()
{
return egl::NoError();
}
egl::Error DeviceMtl::getAttribute(const egl::Display *display, EGLint attribute, void **outValue)
{
DisplayMtl *displayImpl = mtl::GetImpl(display);
switch (attribute)
{
case EGL_METAL_DEVICE_ANGLE:
*outValue = displayImpl->getMetalDevice();
break;
default:
return egl::EglBadAttribute();
}
return egl::NoError();
}
EGLint DeviceMtl::getType()
{
return 0;
}
void DeviceMtl::generateExtensions(egl::DeviceExtensions *outExtensions) const
{
outExtensions->deviceMetal = true;
}
}
......@@ -50,6 +50,8 @@ class DisplayMtl : public DisplayImpl
std::string getVendorString() override;
std::string getVersionString() override;
DeviceImpl *createDevice() override;
egl::Error waitClient(const gl::Context *context) override;
egl::Error waitNative(const gl::Context *context, EGLint engine) override;
......
......@@ -15,6 +15,7 @@
#include "libANGLE/renderer/driver_utils.h"
#include "libANGLE/renderer/glslang_wrapper_utils.h"
#include "libANGLE/renderer/metal/ContextMtl.h"
#include "libANGLE/renderer/metal/DeviceMtl.h"
#include "libANGLE/renderer/metal/SurfaceMtl.h"
#include "libANGLE/renderer/metal/SyncMtl.h"
#include "libANGLE/renderer/metal/mtl_common.h"
......@@ -57,6 +58,7 @@ struct DefaultShaderAsyncInfoMtl
bool compiled = false;
};
// DisplayMtl implementation
DisplayMtl::DisplayMtl(const egl::DisplayState &state) : DisplayImpl(state), mUtils(this) {}
DisplayMtl::~DisplayMtl() {}
......@@ -162,6 +164,11 @@ std::string DisplayMtl::getVersionString()
}
}
DeviceImpl *DisplayMtl::createDevice()
{
return new DeviceMtl();
}
egl::Error DisplayMtl::waitClient(const gl::Context *context)
{
auto contextMtl = GetImplAs<ContextMtl>(context);
......
......@@ -5642,6 +5642,13 @@ bool ValidateQueryDeviceAttribEXT(const ValidationContext *val,
return false;
}
break;
case EGL_METAL_DEVICE_ANGLE:
if (!device->getExtensions().deviceMetal)
{
val->setError(EGL_BAD_ATTRIBUTE);
return false;
}
break;
case EGL_CGL_CONTEXT_ANGLE:
case EGL_CGL_PIXEL_FORMAT_ANGLE:
if (!device->getExtensions().deviceCGL)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment