Choose direct-to-Metal translator through a feature.
Define directMetalGeneration in FeaturesMtl.h. If
ANGLE_ENABLE_METAL_SPIRV is defined to 1 (still the default),
directMetalGeneration defaults to false. It can be overridden via the
standard ANGLE mechanism:
ANGLE_FEATURE_OVERRIDES_ENABLED=directMetalGeneration
It can also be overridden by instantiating angle_end2end_tests with
the directives:
WithDirectMetalGeneration(ES2_METAL())
WithDirectMetalGeneration(ES3_METAL())
These directives aren't working properly yet though. The
direct-to-Metal compiler is instantiated, but the _DirectMetalGen
versions of the tests fail. They pass when switching the Metal
backend's default behavior using the above environment variable. This
will be debugged in follow-on CLs.
Thanks to syoussefi@ for the prototype of this CL:
https://chromium-review.googlesource.com/3076129
Bug: angleproject:5505
Change-Id: I188ab89abc75bf89c5ed2d90102af311feaa1960
Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/3079083
Reviewed-by: Jamie Madill <jmadill@chromium.org>
Reviewed-by: Shahbaz Youssefi <syoussefi@chromium.org>
Commit-Queue: Kenneth Russell <kbr@chromium.org>
diff --git a/include/platform/FeaturesMtl.h b/include/platform/FeaturesMtl.h
index 40563dc..a38c611 100644
--- a/include/platform/FeaturesMtl.h
+++ b/include/platform/FeaturesMtl.h
@@ -109,6 +109,12 @@
"Direct translation to SPIR-V.", &members,
"http://anglebug.com/4889"};
+ // Generate Metal directly instead of generating SPIR-V and then using SPIR-V Cross. Transitory
+ // feature until the work is complete.
+ Feature directMetalGeneration = {"directMetalGeneration", FeatureCategory::MetalFeatures,
+ "Direct translation to Metal.", &members,
+ "http://anglebug.com/5505"};
+
Feature forceNonCSBaseMipmapGeneration = {
"force_non_cs_mipmap_gen", FeatureCategory::MetalFeatures,
"Turn this feature on to disallow Compute Shader based mipmap generation. Compute Shader "
diff --git a/src/libANGLE/renderer/metal/CompilerMtl.h b/src/libANGLE/renderer/metal/CompilerMtl.h
index f98e615..a95d1ec 100644
--- a/src/libANGLE/renderer/metal/CompilerMtl.h
+++ b/src/libANGLE/renderer/metal/CompilerMtl.h
@@ -18,12 +18,13 @@
class CompilerMtl : public CompilerImpl
{
public:
- CompilerMtl();
+ CompilerMtl(ShShaderOutput translatorOutputType);
~CompilerMtl() override;
ShShaderOutput getTranslatorOutputType() const override;
- static bool useDirectToMSLCompiler();
+ private:
+ ShShaderOutput mTranslatorOutputType;
};
} // namespace rx
diff --git a/src/libANGLE/renderer/metal/CompilerMtl.mm b/src/libANGLE/renderer/metal/CompilerMtl.mm
index 45eb7a6..853c5f5 100644
--- a/src/libANGLE/renderer/metal/CompilerMtl.mm
+++ b/src/libANGLE/renderer/metal/CompilerMtl.mm
@@ -12,52 +12,19 @@
#include <stdio.h>
#include "common/debug.h"
-#include "common/system_utils.h"
namespace rx
{
-CompilerMtl::CompilerMtl() : CompilerImpl() {}
+CompilerMtl::CompilerMtl(ShShaderOutput translatorOutputType)
+ : CompilerImpl(), mTranslatorOutputType(translatorOutputType)
+{}
CompilerMtl::~CompilerMtl() {}
ShShaderOutput CompilerMtl::getTranslatorOutputType() const
{
-#ifdef ANGLE_ENABLE_ASSERTS
- static bool outputted = false;
-#endif
-#if ANGLE_ENABLE_METAL_SPIRV
- if (useDirectToMSLCompiler())
- {
-# ifdef ANGLE_ENABLE_ASSERTS
- if (!outputted)
- {
- fprintf(stderr, "Using direct-to-Metal shader compiler\n");
- outputted = true;
- }
-# endif
- return SH_MSL_METAL_OUTPUT;
- }
- else
- {
-# ifdef ANGLE_ENABLE_ASSERTS
- if (!outputted)
- {
- fprintf(stderr, "Using SPIR-V Metal shader compiler\n");
- outputted = true;
- }
-# endif
- return SH_SPIRV_METAL_OUTPUT;
- }
-#else
- return SH_MSL_METAL_OUTPUT;
-#endif
-}
-
-bool CompilerMtl::useDirectToMSLCompiler()
-{
- static bool val = angle::GetBoolEnvironmentVar("ANGLE_USE_MSL_COMPILER");
- return val;
+ return mTranslatorOutputType;
}
} // namespace rx
diff --git a/src/libANGLE/renderer/metal/ContextMtl.mm b/src/libANGLE/renderer/metal/ContextMtl.mm
index a9bef89..722e01e 100644
--- a/src/libANGLE/renderer/metal/ContextMtl.mm
+++ b/src/libANGLE/renderer/metal/ContextMtl.mm
@@ -11,6 +11,7 @@
#include <TargetConditionals.h>
+#include "GLSLANG/ShaderLang.h"
#include "common/debug.h"
#include "libANGLE/TransformFeedback.h"
#include "libANGLE/renderer/metal/BufferMtl.h"
@@ -1121,7 +1122,9 @@
// Shader creation
CompilerImpl *ContextMtl::createCompiler()
{
- return new CompilerMtl();
+ ShShaderOutput outputType =
+ getDisplay()->useDirectToMetalCompiler() ? SH_MSL_METAL_OUTPUT : SH_SPIRV_METAL_OUTPUT;
+ return new CompilerMtl(outputType);
}
ShaderImpl *ContextMtl::createShader(const gl::ShaderState &state)
{
diff --git a/src/libANGLE/renderer/metal/DisplayMtl.h b/src/libANGLE/renderer/metal/DisplayMtl.h
index 390dc3e..d3451f0 100644
--- a/src/libANGLE/renderer/metal/DisplayMtl.h
+++ b/src/libANGLE/renderer/metal/DisplayMtl.h
@@ -164,6 +164,9 @@
#if ANGLE_MTL_EVENT_AVAILABLE
mtl::AutoObjCObj<MTLSharedEventListener> getOrCreateSharedEventListener();
#endif
+
+ bool useDirectToMetalCompiler();
+
protected:
void generateExtensions(egl::DisplayExtensions *outExtensions) const override;
void generateCaps(egl::Caps *outCaps) const override;
diff --git a/src/libANGLE/renderer/metal/DisplayMtl.mm b/src/libANGLE/renderer/metal/DisplayMtl.mm
index 50fae56..9481ab7 100644
--- a/src/libANGLE/renderer/metal/DisplayMtl.mm
+++ b/src/libANGLE/renderer/metal/DisplayMtl.mm
@@ -979,10 +979,20 @@
ANGLE_FEATURE_CONDITION((&mFeatures), forceNonCSBaseMipmapGeneration, isIntel());
+ bool defaultDirectToMetal = true;
+#if ANGLE_ENABLE_METAL_SPIRV
+ defaultDirectToMetal = false;
+#endif
+ ANGLE_FEATURE_CONDITION((&mFeatures), directMetalGeneration, defaultDirectToMetal);
+
angle::PlatformMethods *platform = ANGLEPlatformCurrent();
platform->overrideFeaturesMtl(platform, &mFeatures);
ApplyFeatureOverrides(&mFeatures, getState());
+#ifdef ANGLE_ENABLE_ASSERTS
+ fprintf(stderr, "Shader compiler output: %s\n",
+ mFeatures.directMetalGeneration.enabled ? "Metal" : "SPIR-V");
+#endif
}
angle::Result DisplayMtl::initializeShaderLibrary()
@@ -1253,4 +1263,9 @@
}
#endif
+bool DisplayMtl::useDirectToMetalCompiler()
+{
+ return mFeatures.directMetalGeneration.enabled;
+}
+
} // namespace rx
diff --git a/src/libANGLE/renderer/metal/ProgramMtl.mm b/src/libANGLE/renderer/metal/ProgramMtl.mm
index 2080247..707a3af 100644
--- a/src/libANGLE/renderer/metal/ProgramMtl.mm
+++ b/src/libANGLE/renderer/metal/ProgramMtl.mm
@@ -444,7 +444,8 @@
gl::InfoLog &infoLog)
{
#if ANGLE_ENABLE_METAL_SPIRV
- if (CompilerMtl::useDirectToMSLCompiler())
+ ContextMtl *contextMtl = mtl::GetImpl(glContext);
+ if (contextMtl->getDisplay()->useDirectToMetalCompiler())
{
return linkImplDirect(glContext, resources, infoLog);
}
@@ -595,7 +596,7 @@
{
static_assert(YES == 1, "YES should have value of 1");
#if ANGLE_ENABLE_METAL_SPIRV
- static const bool useSpirv = !CompilerMtl::useDirectToMSLCompiler();
+ static const bool useSpirv = !context->getDisplay()->useDirectToMetalCompiler();
#endif
mtl::TranslatedShaderInfo *translatedMslInfo = &mMslShaderTranslateInfo[shaderType];
diff --git a/src/tests/test_utils/angle_test_configs.cpp b/src/tests/test_utils/angle_test_configs.cpp
index cc1b68c..33b067c 100644
--- a/src/tests/test_utils/angle_test_configs.cpp
+++ b/src/tests/test_utils/angle_test_configs.cpp
@@ -278,6 +278,11 @@
stream << "_DirectSPIRVGen";
}
+ if (pp.eglParameters.directMetalGeneration == EGL_TRUE)
+ {
+ stream << "_DirectMetalGen";
+ }
+
return stream;
}
diff --git a/src/tests/test_utils/angle_test_configs.h b/src/tests/test_utils/angle_test_configs.h
index 7fb861d..1cf3693 100644
--- a/src/tests/test_utils/angle_test_configs.h
+++ b/src/tests/test_utils/angle_test_configs.h
@@ -303,6 +303,13 @@
directSPIRVGeneration.eglParameters.directSPIRVGeneration = EGL_TRUE;
return directSPIRVGeneration;
}
+
+inline PlatformParameters WithDirectMetalGeneration(const PlatformParameters ¶ms)
+{
+ PlatformParameters directMetalGeneration = params;
+ directMetalGeneration.eglParameters.directMetalGeneration = EGL_TRUE;
+ return directMetalGeneration;
+}
} // namespace angle
#endif // ANGLE_TEST_CONFIGS_H_
diff --git a/util/EGLPlatformParameters.h b/util/EGLPlatformParameters.h
index 3387174..5442522 100644
--- a/util/EGLPlatformParameters.h
+++ b/util/EGLPlatformParameters.h
@@ -65,7 +65,8 @@
robustness, emulatedPrerotation, asyncCommandQueueFeatureVulkan,
hasExplicitMemBarrierFeatureMtl, hasCheapRenderPassFeatureMtl,
forceBufferGPUStorageFeatureMtl, supportsVulkanViewportFlip, emulatedVAOs,
- directSPIRVGeneration, captureLimits, forceRobustResourceInit);
+ directSPIRVGeneration, captureLimits, forceRobustResourceInit,
+ directMetalGeneration);
}
EGLint renderer = EGL_PLATFORM_ANGLE_TYPE_DEFAULT_ANGLE;
@@ -91,6 +92,7 @@
EGLint directSPIRVGeneration = EGL_DONT_CARE;
EGLint captureLimits = EGL_DONT_CARE;
EGLint forceRobustResourceInit = EGL_DONT_CARE;
+ EGLint directMetalGeneration = EGL_DONT_CARE;
angle::PlatformMethods *platformMethods = nullptr;
};
diff --git a/util/EGLWindow.cpp b/util/EGLWindow.cpp
index edf064b..8db658e 100644
--- a/util/EGLWindow.cpp
+++ b/util/EGLWindow.cpp
@@ -259,6 +259,11 @@
enabledFeatureOverrides.push_back("directSPIRVGeneration");
}
+ if (params.directMetalGeneration == EGL_TRUE)
+ {
+ enabledFeatureOverrides.push_back("directMetalGeneration");
+ }
+
if (params.hasExplicitMemBarrierFeatureMtl == EGL_FALSE)
{
disabledFeatureOverrides.push_back("has_explicit_mem_barrier_mtl");