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>
This commit is contained in:
Kenneth Russell
2021-08-06 21:24:09 -07:00
committed by Angle LUCI CQ
parent 331be08ffa
commit ff64d2c7e5
11 changed files with 58 additions and 43 deletions

View File

@@ -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 "

View File

@@ -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

View File

@@ -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

View File

@@ -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 @@ 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)
{

View File

@@ -164,6 +164,9 @@ class DisplayMtl : public DisplayImpl
#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;

View File

@@ -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<MTLSharedEventListener> DisplayMtl::getOrCreateSharedEventListe
}
#endif
bool DisplayMtl::useDirectToMetalCompiler()
{
return mFeatures.directMetalGeneration.enabled;
}
} // namespace rx

View File

@@ -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];

View File

@@ -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;
}

View File

@@ -303,6 +303,13 @@ inline PlatformParameters WithDirectSPIRVGeneration(const PlatformParameters &pa
directSPIRVGeneration.eglParameters.directSPIRVGeneration = EGL_TRUE;
return directSPIRVGeneration;
}
inline PlatformParameters WithDirectMetalGeneration(const PlatformParameters &params)
{
PlatformParameters directMetalGeneration = params;
directMetalGeneration.eglParameters.directMetalGeneration = EGL_TRUE;
return directMetalGeneration;
}
} // namespace angle
#endif // ANGLE_TEST_CONFIGS_H_

View File

@@ -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;
};

View File

@@ -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");