Add support for ANGLE's Metal backend

- Disables MSL via SPIRV (we don't have the necessary DEPS)
- Adds new context type, configs, etc...
- Minor tweaks to the ANGLE test context code

Bug: angleproject:7155
Bug: skia:13272
Change-Id: I258ed19abba01ad96cfe6fca46b558af2340880e
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/534569
Reviewed-by: Greg Daniel <egdaniel@google.com>
Commit-Queue: Brian Osman <brianosman@google.com>
This commit is contained in:
Brian Osman 2022-04-26 16:51:28 -04:00 committed by SkCQ
parent 664e2c8bfa
commit 23d333bdd6
8 changed files with 55 additions and 6 deletions

1
.gn
View File

@ -3,4 +3,5 @@ script_executable = "python3"
default_args = {
angle_standalone = false
angle_enable_msl_through_spirv = false
}

View File

@ -77,7 +77,8 @@ DEF_GPUTEST_FOR_RENDERING_CONTEXTS(ResourceCacheCache, reporter, ctxInfo) {
static bool is_rendering_and_not_angle_es3(sk_gpu_test::GrContextFactory::ContextType type) {
if (type == sk_gpu_test::GrContextFactory::kANGLE_D3D11_ES3_ContextType ||
type == sk_gpu_test::GrContextFactory::kANGLE_GL_ES3_ContextType) {
type == sk_gpu_test::GrContextFactory::kANGLE_GL_ES3_ContextType ||
type == sk_gpu_test::GrContextFactory::kANGLE_Metal_ES3_ContextType) {
return false;
}
return sk_gpu_test::GrContextFactory::IsRenderingContext(type);

View File

@ -95,6 +95,8 @@ static const struct {
{ "angle_gl_es3_msaa4", "gpu", "api=angle_gl_es3,samples=4" },
{ "angle_gl_es3_msaa8", "gpu", "api=angle_gl_es3,samples=8" },
{ "angle_gl_es3_dmsaa", "gpu", "api=angle_gl_es3,dmsaa=true" },
{ "angle_mtl_es2", "gpu", "api=angle_mtl_es2" },
{ "angle_mtl_es3", "gpu", "api=angle_mtl_es3" },
{ "cmdbuffer_es2", "gpu", "api=cmdbuffer_es2" },
{ "cmdbuffer_es2_dmsaa", "gpu", "api=cmdbuffer_es2,dmsaa=true" },
{ "cmdbuffer_es3", "gpu", "api=cmdbuffer_es3" },
@ -318,6 +320,14 @@ static bool parse_option_gpu_api(const SkString& value,
*outContextType = GrContextFactory::kANGLE_GL_ES3_ContextType;
return true;
}
if (value.equals("angle_mtl_es2")) {
*outContextType = GrContextFactory::kANGLE_Metal_ES2_ContextType;
return true;
}
if (value.equals("angle_mtl_es3")) {
*outContextType = GrContextFactory::kANGLE_Metal_ES3_ContextType;
return true;
}
if (value.equals("cmdbuffer_es2")) {
*outContextType = GrContextFactory::kCommandBuffer_ES2_ContextType;
return true;

View File

@ -512,6 +512,8 @@ int main(int argc, char** argv) {
{ "angle_d3d11_es3", GrContextFactory::kANGLE_D3D11_ES3_ContextType },
{ "angle_gl_es2" , GrContextFactory::kANGLE_GL_ES2_ContextType },
{ "angle_gl_es3" , GrContextFactory::kANGLE_GL_ES3_ContextType },
{ "angle_mtl_es2" , GrContextFactory::kANGLE_Metal_ES2_ContextType },
{ "angle_mtl_es3" , GrContextFactory::kANGLE_Metal_ES3_ContextType },
{ "cmdbuffer_es2" , GrContextFactory::kCommandBuffer_ES2_ContextType },
{ "cmdbuffer_es3" , GrContextFactory::kCommandBuffer_ES3_ContextType },
{ "vk" , GrContextFactory::kVulkan_ContextType },

View File

@ -210,6 +210,14 @@ ContextInfo GrContextFactory::getContextInfoInternal(ContextType type, ContextOv
glCtx = MakeANGLETestContext(ANGLEBackend::kOpenGL, ANGLEContextVersion::kES3,
glShareContext).release();
break;
case kANGLE_Metal_ES2_ContextType:
glCtx = MakeANGLETestContext(ANGLEBackend::kMetal, ANGLEContextVersion::kES2,
glShareContext).release();
break;
case kANGLE_Metal_ES3_ContextType:
glCtx = MakeANGLETestContext(ANGLEBackend::kMetal, ANGLEContextVersion::kES3,
glShareContext).release();
break;
#endif
#ifndef SK_NO_COMMAND_BUFFER
case kCommandBuffer_ES2_ContextType:

View File

@ -42,6 +42,8 @@ public:
kANGLE_D3D11_ES3_ContextType, //! ANGLE on Direct3D11 OpenGL ES 3 context.
kANGLE_GL_ES2_ContextType, //! ANGLE on OpenGL OpenGL ES 2 context.
kANGLE_GL_ES3_ContextType, //! ANGLE on OpenGL OpenGL ES 3 context.
kANGLE_Metal_ES2_ContextType, //! ANGLE on Metal ES 2 context.
kANGLE_Metal_ES3_ContextType, //! ANGLE on Metal ES 3 context.
kCommandBuffer_ES2_ContextType, //! Chromium command buffer OpenGL ES 2 context.
kCommandBuffer_ES3_ContextType, //! Chromium command buffer OpenGL ES 3 context.
kVulkan_ContextType, //! Vulkan
@ -107,6 +109,10 @@ public:
return "ANGLE GL ES2";
case kANGLE_GL_ES3_ContextType:
return "ANGLE GL ES3";
case kANGLE_Metal_ES2_ContextType:
return "ANGLE Metal ES2";
case kANGLE_Metal_ES3_ContextType:
return "ANGLE Metal ES3";
case kCommandBuffer_ES2_ContextType:
return "Command Buffer ES2";
case kCommandBuffer_ES3_ContextType:

View File

@ -27,6 +27,7 @@
#define EGL_PLATFORM_ANGLE_TYPE_D3D9_ANGLE 0x3207
#define EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE 0x3208
#define EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE 0x320D
#define EGL_PLATFORM_ANGLE_TYPE_METAL_ANGLE 0x3489
#define EGL_CONTEXT_OPENGL_BACKWARDS_COMPATIBLE_ANGLE 0x3483
@ -83,6 +84,9 @@ void* get_angle_egl_display(void* nativeDisplay, ANGLEBackend type) {
case ANGLEBackend::kOpenGL:
typeNum = EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE;
break;
case ANGLEBackend::kMetal:
typeNum = EGL_PLATFORM_ANGLE_TYPE_METAL_ANGLE;
break;
}
const EGLint attribs[] = { EGL_PLATFORM_ANGLE_TYPE_ANGLE, typeNum, EGL_NONE };
return eglGetPlatformDisplayEXT(EGL_PLATFORM_ANGLE_ANGLE, nativeDisplay, attribs);
@ -237,11 +241,11 @@ ANGLEGLContext::ANGLEGLContext(ANGLEBackend type, ANGLEContextVersion version,
}
#else
SkASSERT(EGL_NO_DISPLAY == fDisplay);
fDisplay = get_angle_egl_display(EGL_DEFAULT_DISPLAY, type);
fDisplay = get_angle_egl_display(reinterpret_cast<void*>(EGL_DEFAULT_DISPLAY), type);
fOwnsDisplay = true;
#endif
if (EGL_NO_DISPLAY == fDisplay) {
SkDebugf("Could not create EGL display!");
SkDebugf("Could not create ANGLE EGL display!\n");
return;
}
@ -352,6 +356,9 @@ ANGLEGLContext::ANGLEGLContext(ANGLEBackend type, ANGLEContextVersion version,
case ANGLEBackend::kOpenGL:
SkASSERT(strstr(renderer, "OpenGL"));
break;
case ANGLEBackend::kMetal:
SkASSERT(strstr(renderer, "Metal"));
break;
}
#endif
if (strstr(extensions, "EGL_KHR_image")) {
@ -497,10 +504,10 @@ sk_sp<const GrGLInterface> CreateANGLEGLInterface() {
if (nullptr == gLibs.fGLLib) {
// We load the ANGLE library and never let it go
#if defined _WIN32
#if defined(SK_BUILD_FOR_WIN)
gLibs.fGLLib = SkLoadDynamicLibrary("libGLESv2.dll");
gLibs.fEGLLib = SkLoadDynamicLibrary("libEGL.dll");
#elif defined SK_BUILD_FOR_MAC
#elif defined(SK_BUILD_FOR_MAC) || defined(SK_BUILD_FOR_IOS)
gLibs.fGLLib = SkLoadDynamicLibrary("libGLESv2.dylib");
gLibs.fEGLLib = SkLoadDynamicLibrary("libEGL.dylib");
#else
@ -527,6 +534,19 @@ std::unique_ptr<GLTestContext> MakeANGLETestContext(ANGLEBackend type, ANGLECont
}
#endif
// These checks squelch spam when display creation predictably fails
#if defined(SK_BUILD_FOR_WIN)
if (ANGLEBackend::kMetal == type) {
return nullptr;
}
#endif
#if defined(SK_BUILD_FOR_MAC)
if (ANGLEBackend::kMetal != type) {
return nullptr;
}
#endif
ANGLEGLContext* angleShareContext = reinterpret_cast<ANGLEGLContext*>(shareContext);
std::unique_ptr<GLTestContext> ctx(new ANGLEGLContext(type, version,
angleShareContext, display));

View File

@ -21,7 +21,8 @@ sk_sp<const GrGLInterface> CreateANGLEGLInterface();
enum class ANGLEBackend {
kD3D9,
kD3D11,
kOpenGL
kOpenGL,
kMetal
};
enum class ANGLEContextVersion {