diff --git a/include/platform/FeaturesMtl.h b/include/platform/FeaturesMtl.h index 40563dcd6..a38c61172 100644 --- a/include/platform/FeaturesMtl.h +++ b/include/platform/FeaturesMtl.h @@ -109,6 +109,12 @@ struct FeaturesMtl : FeatureSetBase "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 f98e615e5..a95d1ec7d 100644 --- a/src/libANGLE/renderer/metal/CompilerMtl.h +++ b/src/libANGLE/renderer/metal/CompilerMtl.h @@ -18,12 +18,13 @@ namespace rx 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 45eb7a643..853c5f5a4 100644 --- a/src/libANGLE/renderer/metal/CompilerMtl.mm +++ b/src/libANGLE/renderer/metal/CompilerMtl.mm @@ -12,52 +12,19 @@ #include #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 a9bef8983..722e01efb 100644 --- a/src/libANGLE/renderer/metal/ContextMtl.mm +++ b/src/libANGLE/renderer/metal/ContextMtl.mm @@ -11,6 +11,7 @@ #include +#include "GLSLANG/ShaderLang.h" #include "common/debug.h" #include "libANGLE/TransformFeedback.h" #include "libANGLE/renderer/metal/BufferMtl.h" @@ -1121,7 +1122,9 @@ const gl::Limitations &ContextMtl::getNativeLimitations() const // 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 390dc3e87..d3451f069 100644 --- a/src/libANGLE/renderer/metal/DisplayMtl.h +++ b/src/libANGLE/renderer/metal/DisplayMtl.h @@ -164,6 +164,9 @@ class DisplayMtl : public DisplayImpl #if ANGLE_MTL_EVENT_AVAILABLE mtl::AutoObjCObj 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 50fae564c..9481ab7e3 100644 --- a/src/libANGLE/renderer/metal/DisplayMtl.mm +++ b/src/libANGLE/renderer/metal/DisplayMtl.mm @@ -979,10 +979,20 @@ void DisplayMtl::initializeFeatures() 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 @@ mtl::AutoObjCObj DisplayMtl::getOrCreateSharedEventListe } #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 208024746..707a3af86 100644 --- a/src/libANGLE/renderer/metal/ProgramMtl.mm +++ b/src/libANGLE/renderer/metal/ProgramMtl.mm @@ -444,7 +444,8 @@ angle::Result ProgramMtl::linkImpl(const gl::Context *glContext, 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 @@ angle::Result ProgramMtl::getSpecializedShader(mtl::Context *context, { 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 cc1b68ce5..33b067c90 100644 --- a/src/tests/test_utils/angle_test_configs.cpp +++ b/src/tests/test_utils/angle_test_configs.cpp @@ -278,6 +278,11 @@ std::ostream &operator<<(std::ostream &stream, const PlatformParameters &pp) 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 7fb861d01..1cf36933a 100644 --- a/src/tests/test_utils/angle_test_configs.h +++ b/src/tests/test_utils/angle_test_configs.h @@ -303,6 +303,13 @@ inline PlatformParameters WithDirectSPIRVGeneration(const PlatformParameters &pa 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 338717478..544252241 100644 --- a/util/EGLPlatformParameters.h +++ b/util/EGLPlatformParameters.h @@ -65,7 +65,8 @@ struct EGLPlatformParameters 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 @@ struct EGLPlatformParameters 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 edf064b3a..8db658e42 100644 --- a/util/EGLWindow.cpp +++ b/util/EGLWindow.cpp @@ -259,6 +259,11 @@ bool EGLWindow::initializeDisplay(OSWindow *osWindow, 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");