Update ANGLE Metal to Webkit at Sept 29 2021

This commit merges changes from Webkit into ANGLE upstream.
The following commits were used:
Current:
https://git.webkit.org/?p=WebKit.git;a=commit;h=e01d0bda8f4b7dc2fd834b92802d15d8c15735f

Previous:
https://git.webkit.org/?p=WebKit.git;a=commit;h=492f078198748e8ff248eea0bb979cf79e5f5adfj

The following commits were merged in from the Webkit Repository:
(Hashes from git://git.webkit.org/WebKit-https.git)

03ea44c78ce5665d4ec9add271260121cbc7bc6c
     Problems with drawElements in some conditions
     https://bugs.webkit.org/show_bug.cgi?id=230107
c8dc8e0c4d1109d39a62eb197b45e95132380290
     ANGLE Metal: single-component swizzles do not compile
     https://bugs.webkit.org/show_bug.cgi?id=230472
7285dbaaf5af15877d6c332b30ef7a4d67225460
     webgl-compressed-texture-s3tc-srgb.html fails on Intel+AMD Metal
     https://bugs.webkit.org/show_bug.cgi?id=229941
4c72f92967ecd2a095666fef431384c4f5f60fb4
     fragcolor-fragdata-invariant.html fails
     https://bugs.webkit.org/show_bug.cgi?id=223317
cd943145467f54e5928793c0dd3dfa2313c007dd
     ANGLE Metal index buffer restart range cache could be maintained..
     https://bugs.webkit.org/show_bug.cgi?id=227451
f075ff77e592eabd54dd659a8e13617cc5faedc8
     ANGLE Metal infinities and NaNs generated with incorrect syntax
     https://bugs.webkit.org/show_bug.cgi?id=229439
5862073269122f4b2d43d96d3922757557755e86
     [Metal ANGLE] Fix over-autorelease of
     rx::DisplayMtl::getMetalDeviceMatchingAttribute()...
     <https://webkit.org/b/229128>
85f797ad31db048cb82cbafd428ef77f0b839312 ANGLE Cocoa compiles....
     https://bugs.webkit.org/show_bug.cgi?id=228987
a67918ba279ad4842b6ae84a79c3f1c0cdc35ace Avoid infinite recursion...
     https://bugs.webkit.org/show_bug.cgi?id=228978
d341f67de0033adcf1ec6373ace6a54b06c4a031
     Cherry-pick ANGLE: Revise WebGL's shaderSource validation
     https://bugs.webkit.org/show_bug.cgi?id=228951
1e2714d981e97de8234ba055570dfdf56e8b6944
     3.5 MB system-wide footprint impact due to thread-locals...
     https://bugs.webkit.org/show_bug.cgi?id=228240
d32e5cca34081997d32504b0b56c18b9703ff3be
     Build Default Metal library offline
     https://bugs.webkit.org/show_bug.cgi?id=227333
33702279faccfd4c8d1c8a6d549925f9ca9a4e8f
     WebGL2 demo doesn't work due to failing compilation....
     https://bugs.webkit.org/show_bug.cgi?id=226865
0a075885d242db38c4e435a6597173dc3b082173
     rAF driven WebGL submits excessive amount of GPU work...
     https://bugs.webkit.org/show_bug.cgi?id=227059
f38a92b3e7c17efda269caa7066e7ffe2f828e72
     WebGL shader link error in iOS 15 beta: "Internal error..."
     https://bugs.webkit.org/show_bug.cgi?id=227723
98d48f011d561531470d97f26a022767b5452fb7
     REGRESSION (r279466):  [Big Sur] webgl/1.0.3/conformance &...
     https://bugs.webkit.org/show_bug.cgi?id=227596

Bug: angleproject:6471
Change-Id: I07166d0dc4b5c3579d98353485b3245b81c7b882
Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/3194322
Reviewed-by: Jonah Ryan-Davis <jonahr@google.com>
Reviewed-by: Kenneth Russell <kbr@chromium.org>
Commit-Queue: Jonah Ryan-Davis <jonahr@google.com>
Commit-Queue: Kyle Piddington <kpiddington@apple.com>
This commit is contained in:
Kyle Piddington 2021-09-28 17:27:57 -07:00 коммит произвёл Angle LUCI CQ
Родитель a44197b5ac
Коммит 54d4bfe5f9
32 изменённых файлов: 430 добавлений и 324 удалений

Просмотреть файл

@ -135,6 +135,10 @@ struct FeaturesMtl : FeatureSetBase
"Insert explicit casts for float/double/unsigned/signed int on macOS 10.15 with Intel "
"driver",
&members};
Feature intelDisableFastMath = {
"intel_disable_fast_math", FeatureCategory::MetalWorkarounds,
"Disable fast math in atan and invariance cases when running below macOS 12.0", &members};
};
} // namespace angle

Просмотреть файл

@ -410,8 +410,6 @@ angle_translator_lib_metal_sources = [
"src/compiler/translator/TranslatorMetalDirect/Reference.h",
"src/compiler/translator/TranslatorMetalDirect/RewriteCaseDeclarations.cpp",
"src/compiler/translator/TranslatorMetalDirect/RewriteCaseDeclarations.h",
"src/compiler/translator/TranslatorMetalDirect/RewriteGlobalQualifierDecls.cpp",
"src/compiler/translator/TranslatorMetalDirect/RewriteGlobalQualifierDecls.h",
"src/compiler/translator/TranslatorMetalDirect/RewriteKeywords.cpp",
"src/compiler/translator/TranslatorMetalDirect/RewriteKeywords.h",
"src/compiler/translator/TranslatorMetalDirect/RewriteOutArgs.cpp",

Просмотреть файл

@ -23,7 +23,6 @@
#include "compiler/translator/TranslatorMetalDirect/NameEmbeddedUniformStructsMetal.h"
#include "compiler/translator/TranslatorMetalDirect/ReduceInterfaceBlocks.h"
#include "compiler/translator/TranslatorMetalDirect/RewriteCaseDeclarations.h"
#include "compiler/translator/TranslatorMetalDirect/RewriteGlobalQualifierDecls.h"
#include "compiler/translator/TranslatorMetalDirect/RewriteKeywords.h"
#include "compiler/translator/TranslatorMetalDirect/RewriteOutArgs.h"
#include "compiler/translator/TranslatorMetalDirect/RewritePipelines.h"
@ -463,6 +462,13 @@ ANGLE_NO_DISCARD bool AppendVertexShaderPositionYCorrectionToMain(TCompiler *com
}
} // namespace
namespace mtl
{
TranslatorMetalReflection *getTranslatorMetalReflection(const TCompiler *compiler)
{
return ((TranslatorMetalDirect *)compiler)->getTranslatorMetalReflection();
}
} // namespace mtl
TranslatorMetalDirect::TranslatorMetalDirect(sh::GLenum type,
ShShaderSpec spec,
ShShaderOutput output)
@ -1143,12 +1149,6 @@ bool TranslatorMetalDirect::translateImpl(TInfoSinkBase &sink,
return false;
}
Invariants invariants;
if (!RewriteGlobalQualifierDecls(*this, *root, invariants))
{
return false;
}
if (!ConvertUnsupportedConstructorsToFunctionCalls(*this, *root))
{
return false;
@ -1206,8 +1206,8 @@ bool TranslatorMetalDirect::translateImpl(TInfoSinkBase &sink,
mValidateASTOptions.validateQualifiers = false;
PipelineStructs pipelineStructs;
if (!RewritePipelines(*this, *root, idGen, *driverUniforms, symbolEnv, invariants,
pipelineStructs))
if (!RewritePipelines(*this, *root, getInputVaryings(), getOutputVaryings(), idGen,
*driverUniforms, symbolEnv, pipelineStructs))
{
return false;
}
@ -1242,8 +1242,7 @@ bool TranslatorMetalDirect::translateImpl(TInfoSinkBase &sink,
{
return false;
}
if (!EmitMetal(*this, *root, idGen, pipelineStructs, invariants, symbolEnv, ppc,
&getSymbolTable()))
if (!EmitMetal(*this, *root, idGen, pipelineStructs, symbolEnv, ppc, &getSymbolTable()))
{
return false;
}

Просмотреть файл

@ -29,7 +29,7 @@ class DriverUniform;
class DriverUniformMetal;
class SpecConst;
class TOutputMSL;
class TranslatorMetalReflection;
typedef std::unordered_map<size_t, std::string> originalNamesMap;
typedef std::unordered_map<std::string, size_t> samplerBindingMap;
typedef std::unordered_map<std::string, size_t> textureBindingMap;
@ -42,6 +42,11 @@ struct UBOBindingInfo
};
typedef std::unordered_map<std::string, UBOBindingInfo> uniformBufferBindingMap;
namespace mtl
{
TranslatorMetalReflection *getTranslatorMetalReflection(const TCompiler *compiler);
}
class TranslatorMetalReflection
{
public:
@ -127,8 +132,10 @@ class TranslatorMetalReflection
}
void reset()
{
hasUBOs = false;
hasFlatInput = false;
hasUBOs = false;
hasFlatInput = false;
hasAtan = false;
hasInvariance = false;
originalNames.clear();
samplerBindings.clear();
textureBindings.clear();
@ -136,8 +143,10 @@ class TranslatorMetalReflection
uniformBufferBindings.clear();
}
bool hasUBOs = false;
bool hasFlatInput = false;
bool hasUBOs = false;
bool hasFlatInput = false;
bool hasAtan = false;
bool hasInvariance = false;
private:
originalNamesMap originalNames;

Просмотреть файл

@ -43,8 +43,10 @@ class Discoverer : public DiscoverEnclosingFunctionTraverser
return;
}
const TFunction *owner = discoverEnclosingFunction(symbolNode);
ASSERT(owner);
mDepFunctions.insert(owner);
if (owner)
{
mDepFunctions.insert(owner);
}
}
bool visitAggregate(Visit visit, TIntermAggregate *aggregateNode) override

Просмотреть файл

@ -82,7 +82,6 @@ class GenMetalTraverser : public TIntermTraverser
Sink &out,
IdGen &idGen,
const PipelineStructs &pipelineStructs,
const Invariants &invariants,
SymbolEnv &symbolEnv,
TSymbolTable *symbolTable);
@ -183,7 +182,6 @@ class GenMetalTraverser : public TIntermTraverser
Sink &mOut;
const TCompiler &mCompiler;
const PipelineStructs &mPipelineStructs;
const Invariants &mInvariants;
SymbolEnv &mSymbolEnv;
IdGen &mIdGen;
int mIndentLevel = -1;
@ -200,7 +198,6 @@ class GenMetalTraverser : public TIntermTraverser
size_t mDriverUniformsBindingIndex = 0;
size_t mUBOArgumentBufferBindingIndex = 0;
};
} // anonymous namespace
GenMetalTraverser::~GenMetalTraverser()
@ -214,14 +211,12 @@ GenMetalTraverser::GenMetalTraverser(const TCompiler &compiler,
Sink &out,
IdGen &idGen,
const PipelineStructs &pipelineStructs,
const Invariants &invariants,
SymbolEnv &symbolEnv,
TSymbolTable *symbolTable)
: TIntermTraverser(true, false, false),
mOut(out),
mCompiler(compiler),
mPipelineStructs(pipelineStructs),
mInvariants(invariants),
mSymbolEnv(symbolEnv),
mIdGen(idGen),
mMainUniformBufferIndex(symbolTable->getDefaultUniformsBindingIndex()),
@ -779,9 +774,12 @@ void GenMetalTraverser::emitPostQualifier(const EmitVariableDeclarationConfig &e
const VarDecl &decl,
const TQualifier qualifier)
{
bool isInvariant = false;
switch (qualifier)
{
case TQualifier::EvqPosition:
isInvariant = decl.type().isInvariant();
ABSL_FALLTHROUGH_INTENDED;
case TQualifier::EvqFragCoord:
mOut << " [[position]]";
break;
@ -815,14 +813,12 @@ void GenMetalTraverser::emitPostQualifier(const EmitVariableDeclarationConfig &e
break;
}
const bool isInvariant =
(decl.isField() ? mInvariants.contains(decl.field())
: mInvariants.contains(decl.variable())) &&
(qualifier == TQualifier::EvqPosition || qualifier == TQualifier::EvqFragCoord);
if (isInvariant)
{
mOut << " [[invariant]]";
TranslatorMetalReflection *reflection = mtl::getTranslatorMetalReflection(&mCompiler);
reflection->hasInvariance = true;
}
}
@ -1033,7 +1029,7 @@ void GenMetalTraverser::emitFieldDeclaration(const TField &field,
{
mOut << " [[flat]]";
TranslatorMetalReflection *reflection =
((sh::TranslatorMetalDirect *)&mCompiler)->getTranslatorMetalReflection();
mtl::getTranslatorMetalReflection(&mCompiler);
reflection->hasFlatInput = true;
}
break;
@ -1164,8 +1160,7 @@ void GenMetalTraverser::emitUniformBufferDeclaration(const TField &field,
const TType &type = *field.type();
const int arraySize = type.isArray() ? type.getArraySizeProduct() : 1;
TranslatorMetalReflection *reflection =
((sh::TranslatorMetalDirect *)&mCompiler)->getTranslatorMetalReflection();
TranslatorMetalReflection *reflection = mtl::getTranslatorMetalReflection(&mCompiler);
ASSERT(type.getBasicType() == TBasicType::EbtStruct);
const TStructure *structure = type.getStruct();
const std::string originalName = reflection->getOriginalName(structure->uniqueId().get());
@ -1798,8 +1793,7 @@ void GenMetalTraverser::emitFunctionParameter(const TFunction &func, const TVari
if (isMain)
{
TranslatorMetalReflection *reflection =
((sh::TranslatorMetalDirect *)&mCompiler)->getTranslatorMetalReflection();
TranslatorMetalReflection *reflection = mtl::getTranslatorMetalReflection(&mCompiler);
if (structure)
{
if (mPipelineStructs.fragmentIn.matches(*structure) ||
@ -1985,6 +1979,11 @@ bool GenMetalTraverser::visitAggregate(Visit, TIntermAggregate *aggregateNode)
else
{
const TOperator op = aggregateNode->getOp();
if (op == EOpAtan)
{
TranslatorMetalReflection *reflection = mtl::getTranslatorMetalReflection(&mCompiler);
reflection->hasAtan = true;
}
switch (op)
{
case TOperator::EOpCallFunctionInAST:
@ -2215,7 +2214,6 @@ bool GenMetalTraverser::visitBlock(Visit, TIntermBlock *blockNode)
bool GenMetalTraverser::visitGlobalQualifierDeclaration(Visit, TIntermGlobalQualifierDeclaration *)
{
UNREACHABLE(); // RewriteGlobalQualifierDecls should have been called before this.
return false;
}
@ -2441,7 +2439,6 @@ bool sh::EmitMetal(TCompiler &compiler,
TIntermBlock &root,
IdGen &idGen,
const PipelineStructs &pipelineStructs,
const Invariants &invariants,
SymbolEnv &symbolEnv,
const ProgramPreludeConfig &ppc,
TSymbolTable *symbolTable)
@ -2501,8 +2498,7 @@ bool sh::EmitMetal(TCompiler &compiler,
#else
TInfoSinkBase &outWrapper = out;
#endif
GenMetalTraverser gen(compiler, outWrapper, idGen, pipelineStructs, invariants, symbolEnv,
symbolTable);
GenMetalTraverser gen(compiler, outWrapper, idGen, pipelineStructs, symbolEnv, symbolTable);
root.traverse(&gen);
}

Просмотреть файл

@ -11,7 +11,6 @@
#include "compiler/translator/Compiler.h"
#include "compiler/translator/TranslatorMetalDirect/IdGen.h"
#include "compiler/translator/TranslatorMetalDirect/ProgramPrelude.h"
#include "compiler/translator/TranslatorMetalDirect/RewriteGlobalQualifierDecls.h"
#include "compiler/translator/TranslatorMetalDirect/RewritePipelines.h"
#include "compiler/translator/TranslatorMetalDirect/SymbolEnv.h"
@ -23,7 +22,6 @@ ANGLE_NO_DISCARD bool EmitMetal(TCompiler &compiler,
TIntermBlock &root,
IdGen &idGen,
const PipelineStructs &pipelineStructs,
const Invariants &invariants,
SymbolEnv &symbolEnv,
const ProgramPreludeConfig &ppc,
TSymbolTable *symbolTable);

Просмотреть файл

@ -362,8 +362,7 @@ class ConvertStructState : angle::NonCopyable
const ModifiedStructMachinery *m = outMachineries.find(structure);
if (m == nullptr)
{
TranslatorMetalReflection *reflection =
((sh::TranslatorMetalDirect *)&mCompiler)->getTranslatorMetalReflection();
TranslatorMetalReflection *reflection = mtl::getTranslatorMetalReflection(&mCompiler);
reflection->addOriginalName(structure.uniqueId().get(), structure.name().data());
const Name name = idGen.createNewName(structure.name().data());
if (!TryCreateModifiedStruct(mCompiler, symbolEnv, idGen, config, structure, name,

Просмотреть файл

@ -1239,8 +1239,7 @@ struct ANGLE_SwizzleRef
template <typename T, int N>
ANGLE_ALWAYS_INLINE ANGLE_VectorElemRef<T, N> ANGLE_swizzle_ref(thread metal::vec<T, N> &vec, int i0)
{
const int is[] = { i0 };
return ANGLE_VectorElemRef<T, N>(vec, is);
return ANGLE_VectorElemRef<T, N>(vec, i0);
}
template <typename T, int N>
ANGLE_ALWAYS_INLINE ANGLE_SwizzleRef<T, N, 2> ANGLE_swizzle_ref(thread metal::vec<T, N> &vec, int i0, int i1)

Просмотреть файл

@ -1,113 +0,0 @@
//
// Copyright 2020 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.
//
#include "compiler/translator/TranslatorMetalDirect/RewriteGlobalQualifierDecls.h"
#include "compiler/translator/tree_util/IntermRebuild.h"
using namespace sh;
namespace
{
class FindDeclaredGlobals : public TIntermRebuild
{
public:
std::unordered_set<const TVariable *> mDeclaredGlobals;
FindDeclaredGlobals(TCompiler &compiler) : TIntermRebuild(compiler, true, false) {}
PreResult visitDeclarationPre(TIntermDeclaration &declNode) override
{
TIntermNode *declaratorNode = declNode.getChildNode(0);
TIntermSymbol *symbolNode = nullptr;
if (TIntermBinary *initNode = declaratorNode->getAsBinaryNode())
{
symbolNode = initNode->getLeft()->getAsSymbolNode();
}
else
{
symbolNode = declaratorNode->getAsSymbolNode();
}
ASSERT(symbolNode);
const TVariable &var = symbolNode->variable();
mDeclaredGlobals.insert(&var);
return {declNode, VisitBits::Neither};
}
PreResult visitFunctionDefinitionPre(TIntermFunctionDefinition &node) override
{
return {node, VisitBits::Neither};
}
};
class Rewriter : public TIntermRebuild
{
const std::unordered_set<const TVariable *> &mDeclaredGlobals;
Invariants &mOutInvariants;
public:
Rewriter(TCompiler &compiler,
const std::unordered_set<const TVariable *> &declaredGlobals,
Invariants &outInvariants)
: TIntermRebuild(compiler, true, false),
mDeclaredGlobals(declaredGlobals),
mOutInvariants(outInvariants)
{}
PreResult visitGlobalQualifierDeclarationPre(
TIntermGlobalQualifierDeclaration &gqDeclNode) override
{
TIntermSymbol &symbolNode = *gqDeclNode.getSymbol();
const TVariable &var = symbolNode.variable();
if (gqDeclNode.isInvariant())
{
mOutInvariants.insert(var);
}
if (mDeclaredGlobals.find(&var) == mDeclaredGlobals.end())
{
return *new TIntermDeclaration{&symbolNode};
}
return nullptr;
}
PreResult visitDeclarationPre(TIntermDeclaration &node) override
{
return {node, VisitBits::Neither};
}
PreResult visitFunctionDefinitionPre(TIntermFunctionDefinition &node) override
{
return {node, VisitBits::Neither};
}
};
} // anonymous namespace
bool sh::RewriteGlobalQualifierDecls(TCompiler &compiler,
TIntermBlock &root,
Invariants &outInvariants)
{
FindDeclaredGlobals fdg(compiler);
if (!fdg.rebuildRoot(root))
{
UNREACHABLE();
return false;
}
Rewriter rewriter(compiler, fdg.mDeclaredGlobals, outInvariants);
if (!rewriter.rebuildRoot(root))
{
return false;
}
return true;
}

Просмотреть файл

@ -1,48 +0,0 @@
//
// Copyright 2020 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.
//
#ifndef COMPILER_TRANSLATOR_TRANSLATORMETALDIRECT_REWRITEGLOBALQUALIFIERDECLS_H_
#define COMPILER_TRANSLATOR_TRANSLATORMETALDIRECT_REWRITEGLOBALQUALIFIERDECLS_H_
#include <unordered_set>
#include "compiler/translator/Compiler.h"
namespace sh
{
// Tracks TVariables and TFields that are marked as "invariant".
class Invariants
{
public:
void insert(const TVariable &var) { mInvariants.insert(&var); }
void insert(const TField &field) { mInvariants.insert(&field); }
bool contains(const TVariable &var) const
{
return mInvariants.find(&var) != mInvariants.end();
}
bool contains(const TField &field) const
{
return mInvariants.find(&field) != mInvariants.end();
}
private:
std::unordered_set<const void *> mInvariants;
};
// This rewrites TIntermGlobalQualifierDeclarations as TIntermDeclarations.
// `outInvariants` is populated with the information that would otherwise be lost by such a
// transform.
ANGLE_NO_DISCARD bool RewriteGlobalQualifierDecls(TCompiler &compiler,
TIntermBlock &root,
Invariants &outInvariants);
} // namespace sh
#endif // COMPILER_TRANSLATOR_TRANSLATORMETALDIRECT_REWRITEGLOBALQUALIFIERDECLS_H_

Просмотреть файл

@ -28,6 +28,20 @@ using namespace sh;
namespace
{
bool IsVariableInvariant(const std::vector<sh::ShaderVariable> &mVars, const ImmutableString &name)
{
for (const auto &var : mVars)
{
if (name == var.name)
{
return var.isInvariant;
}
}
// TODO(kpidington): this should be UNREACHABLE() but isn't because the translator generates
// declarations to unused built-in variables.
return false;
}
using VariableSet = std::unordered_set<const TVariable *>;
using VariableList = std::vector<const TVariable *>;
@ -61,7 +75,7 @@ class GeneratePipelineStruct : private TIntermRebuild
private:
const Pipeline &mPipeline;
SymbolEnv &mSymbolEnv;
Invariants &mInvariants;
const std::vector<sh::ShaderVariable> *mVariableInfos;
VariableList mPipelineVariableList;
IdGen &mIdGen;
PipelineStructInfo mInfo;
@ -73,9 +87,9 @@ class GeneratePipelineStruct : private TIntermRebuild
IdGen &idGen,
const Pipeline &pipeline,
SymbolEnv &symbolEnv,
Invariants &invariants)
const std::vector<sh::ShaderVariable> *variableInfos)
{
GeneratePipelineStruct self(compiler, idGen, pipeline, symbolEnv, invariants);
GeneratePipelineStruct self(compiler, idGen, pipeline, symbolEnv, variableInfos);
if (!self.exec(root))
{
return false;
@ -89,11 +103,11 @@ class GeneratePipelineStruct : private TIntermRebuild
IdGen &idGen,
const Pipeline &pipeline,
SymbolEnv &symbolEnv,
Invariants &invariants)
const std::vector<sh::ShaderVariable> *variableInfos)
: TIntermRebuild(compiler, true, true),
mPipeline(pipeline),
mSymbolEnv(symbolEnv),
mInvariants(invariants),
mVariableInfos(variableInfos),
mIdGen(idGen)
{}
@ -214,7 +228,6 @@ class GeneratePipelineStruct : private TIntermRebuild
{
for (const TVariable *var : mPipelineVariableList)
{
ASSERT(!mInvariants.contains(*var));
const TType &varType = var->getType();
const TBasicType samplerType = varType.getBasicType();
@ -248,14 +261,13 @@ class GeneratePipelineStruct : private TIntermRebuild
{
for (const TVariable *var : mPipelineVariableList)
{
auto &type = CloneType(var->getType());
auto &type = CloneType(var->getType());
if (mVariableInfos && IsVariableInvariant(*mVariableInfos, var->name()))
{
type.setInvariant(true);
}
auto *field = new TField(&type, var->name(), kNoSourceLoc, var->symbolType());
fields.push_back(field);
if (mInvariants.contains(*var))
{
mInvariants.insert(*field);
}
}
}
break;
@ -401,7 +413,7 @@ class PipelineFunctionEnv
{
std::vector<const TVariable *> variables;
TranslatorMetalReflection *reflection =
((sh::TranslatorMetalDirect *)&mCompiler)->getTranslatorMetalReflection();
mtl::getTranslatorMetalReflection(&mCompiler);
for (const TField *field : mPipelineStruct.external->fields())
{
const TStructure *textureEnv = field->type()->getStruct();
@ -853,12 +865,13 @@ bool UpdatePipelineSymbols(Pipeline::Type pipelineType,
PipelineScoped<TVariable> pipelineMainLocalVar)
{
auto map = [&](const TFunction *owner, TIntermSymbol &symbol) -> TIntermNode & {
if (!owner)
return symbol;
const TVariable &var = symbol.variable();
if (pipelineVariables.find(&var) == pipelineVariables.end())
{
return symbol;
}
ASSERT(owner);
const TVariable *structInstanceVar;
if (owner->isMain())
{
@ -883,7 +896,7 @@ bool RewritePipeline(TCompiler &compiler,
IdGen &idGen,
const Pipeline &pipeline,
SymbolEnv &symbolEnv,
Invariants &invariants,
const std::vector<sh::ShaderVariable> *variableInfo,
PipelineScoped<TStructure> &outStruct)
{
ASSERT(outStruct.isTotallyEmpty());
@ -891,7 +904,8 @@ bool RewritePipeline(TCompiler &compiler,
TSymbolTable &symbolTable = compiler.getSymbolTable();
PipelineStructInfo psi;
if (!GeneratePipelineStruct::Exec(psi, compiler, root, idGen, pipeline, symbolEnv, invariants))
if (!GeneratePipelineStruct::Exec(psi, compiler, root, idGen, pipeline, symbolEnv,
variableInfo))
{
return false;
}
@ -937,10 +951,11 @@ bool RewritePipeline(TCompiler &compiler,
bool sh::RewritePipelines(TCompiler &compiler,
TIntermBlock &root,
const std::vector<sh::ShaderVariable> &inputVaryings,
const std::vector<sh::ShaderVariable> &outputVaryings,
IdGen &idGen,
DriverUniform &angleUniformsGlobalInstanceVar,
SymbolEnv &symbolEnv,
Invariants &invariants,
PipelineStructs &outStructs)
{
struct Info
@ -948,28 +963,31 @@ bool sh::RewritePipelines(TCompiler &compiler,
Pipeline::Type pipelineType;
PipelineScoped<TStructure> &outStruct;
const TVariable *globalInstanceVar;
const std::vector<sh::ShaderVariable> *variableInfo;
};
Info infos[] = {
{Pipeline::Type::InstanceId, outStructs.instanceId, nullptr},
{Pipeline::Type::Texture, outStructs.texture, nullptr},
{Pipeline::Type::NonConstantGlobals, outStructs.nonConstantGlobals, nullptr},
{Pipeline::Type::InstanceId, outStructs.instanceId, nullptr, nullptr},
{Pipeline::Type::Texture, outStructs.texture, nullptr, nullptr},
{Pipeline::Type::NonConstantGlobals, outStructs.nonConstantGlobals, nullptr, nullptr},
{Pipeline::Type::AngleUniforms, outStructs.angleUniforms,
angleUniformsGlobalInstanceVar.getDriverUniformsVariable()},
{Pipeline::Type::UserUniforms, outStructs.userUniforms, nullptr},
{Pipeline::Type::VertexIn, outStructs.vertexIn, nullptr},
{Pipeline::Type::VertexOut, outStructs.vertexOut, nullptr},
{Pipeline::Type::FragmentIn, outStructs.fragmentIn, nullptr},
{Pipeline::Type::FragmentOut, outStructs.fragmentOut, nullptr},
{Pipeline::Type::InvocationVertexGlobals, outStructs.invocationVertexGlobals, nullptr},
{Pipeline::Type::InvocationFragmentGlobals, outStructs.invocationFragmentGlobals, nullptr},
{Pipeline::Type::UniformBuffer, outStructs.uniformBuffers, nullptr},
angleUniformsGlobalInstanceVar.getDriverUniformsVariable(), nullptr},
{Pipeline::Type::UserUniforms, outStructs.userUniforms, nullptr, nullptr},
{Pipeline::Type::VertexIn, outStructs.vertexIn, nullptr, &inputVaryings},
{Pipeline::Type::VertexOut, outStructs.vertexOut, nullptr, &outputVaryings},
{Pipeline::Type::FragmentIn, outStructs.fragmentIn, nullptr, &inputVaryings},
{Pipeline::Type::FragmentOut, outStructs.fragmentOut, nullptr, &outputVaryings},
{Pipeline::Type::InvocationVertexGlobals, outStructs.invocationVertexGlobals, nullptr,
nullptr},
{Pipeline::Type::InvocationFragmentGlobals, outStructs.invocationFragmentGlobals, nullptr,
&inputVaryings},
{Pipeline::Type::UniformBuffer, outStructs.uniformBuffers, nullptr, nullptr},
};
for (Info &info : infos)
{
Pipeline pipeline{info.pipelineType, info.globalInstanceVar};
if (!RewritePipeline(compiler, root, idGen, pipeline, symbolEnv, invariants,
if (!RewritePipeline(compiler, root, idGen, pipeline, symbolEnv, info.variableInfo,
info.outStruct))
{
return false;

Просмотреть файл

@ -11,7 +11,6 @@
#include "compiler/translator/Compiler.h"
#include "compiler/translator/TranslatorMetalDirect/IdGen.h"
#include "compiler/translator/TranslatorMetalDirect/Pipeline.h"
#include "compiler/translator/TranslatorMetalDirect/RewriteGlobalQualifierDecls.h"
#include "compiler/translator/TranslatorMetalDirect/SymbolEnv.h"
namespace sh
@ -34,10 +33,11 @@ namespace sh
// from `main`.
ANGLE_NO_DISCARD bool RewritePipelines(TCompiler &compiler,
TIntermBlock &root,
const std::vector<sh::ShaderVariable> &inputVaryings,
const std::vector<sh::ShaderVariable> &outputVariables,
IdGen &idGen,
DriverUniform &angleUniformsGlobalInstanceVar,
SymbolEnv &symbolEnv,
Invariants &invariants,
PipelineStructs &outStructs);
} // namespace sh

Просмотреть файл

@ -216,7 +216,11 @@ class Separator : public TIntermRebuild
{
return true;
}
ASSERT(expr.getType().getBasicType() != TBasicType::EbtVoid);
// https://bugs.webkit.org/show_bug.cgi?id=227723: Fix for sequence operator.
if ((expr.getType().getBasicType() == TBasicType::EbtVoid))
{
return true;
}
return false;
}
@ -615,7 +619,8 @@ class Separator : public TIntermRebuild
PostResult visitGlobalQualifierDeclarationPost(TIntermGlobalQualifierDeclaration &node) override
{
ASSERT(false); // These should be scrubbed from AST before rewriter is called.
// With the removal of RewriteGlobalQualifierDecls, we may encounter globals while
// seperating compound expressions.
pushStmt(node);
return node;
}

Просмотреть файл

@ -47,6 +47,11 @@
#include "libANGLE/renderer/Format.h"
#include "libANGLE/validationES.h"
#if defined(ANGLE_PLATFORM_APPLE)
# include <dispatch/dispatch.h>
# include "common/tls.h"
#endif
namespace gl
{
namespace
@ -315,7 +320,35 @@ bool GetSaveAndRestoreState(const egl::AttributeMap &attribs)
} // anonymous namespace
#if defined(ANGLE_PLATFORM_APPLE)
// TODO(angleproject:6479): Due to a bug in Apple's dyld loader, `thread_local` will cause
// excessive memory use. Temporarily avoid it by using pthread's thread
// local storage instead.
static TLSIndex GetCurrentValidContextTLSIndex()
{
static TLSIndex CurrentValidContextIndex = TLS_INVALID_INDEX;
static dispatch_once_t once;
dispatch_once(&once, ^{
ASSERT(CurrentValidContextIndex == TLS_INVALID_INDEX);
CurrentValidContextIndex = CreateTLSIndex();
});
return CurrentValidContextIndex;
}
Context *GetCurrentValidContextTLS()
{
TLSIndex CurrentValidContextIndex = GetCurrentValidContextTLSIndex();
ASSERT(CurrentValidContextIndex != TLS_INVALID_INDEX);
return static_cast<Context *>(GetTLSValue(CurrentValidContextIndex));
}
void SetCurrentValidContextTLS(Context *context)
{
TLSIndex CurrentValidContextIndex = GetCurrentValidContextTLSIndex();
ASSERT(CurrentValidContextIndex != TLS_INVALID_INDEX);
SetTLSValue(CurrentValidContextIndex, context);
}
#else
thread_local Context *gCurrentValidContext = nullptr;
#endif
Context::Context(egl::Display *display,
const egl::Config *config,
@ -2775,7 +2808,11 @@ void Context::setContextLost()
mSkipValidation = false;
// Make sure we update TLS.
#if defined(ANGLE_PLATFORM_APPLE)
SetCurrentValidContextTLS(nullptr);
#else
gCurrentValidContext = nullptr;
#endif
}
GLenum Context::getGraphicsResetStatus()

Просмотреть файл

@ -829,7 +829,12 @@ class ScopedContextRef
};
// Thread-local current valid context bound to the thread.
#if defined(ANGLE_PLATFORM_APPLE)
extern Context *GetCurrentValidContextTLS();
extern void SetCurrentValidContextTLS(Context *context);
#else
extern thread_local Context *gCurrentValidContext;
#endif
} // namespace gl

Просмотреть файл

@ -8,11 +8,14 @@
// iOS-specific subclass of ContextGL.
//
#include "libANGLE/renderer/gl/eagl/ContextEAGL.h"
#import "common/platform.h"
#if defined(ANGLE_ENABLE_EAGL)
#include "libANGLE/Context.h"
#include "libANGLE/Display.h"
#include "libANGLE/renderer/gl/eagl/DisplayEAGL.h"
# include "libANGLE/renderer/gl/eagl/ContextEAGL.h"
# include "libANGLE/Context.h"
# include "libANGLE/Display.h"
# include "libANGLE/renderer/gl/eagl/DisplayEAGL.h"
namespace rx
{
@ -24,3 +27,5 @@ ContextEAGL::ContextEAGL(const gl::State &state,
{}
} // namespace rx
#endif // defined(ANGLE_ENABLE_EAGL)

Просмотреть файл

@ -366,6 +366,15 @@ class ContextMtl : public ContextImpl, public mtl::Context
const void *indices,
bool xfbPass);
angle::Result setupDrawImpl(const gl::Context *context,
gl::PrimitiveMode mode,
GLint firstVertex,
GLsizei vertexOrIndexCount,
GLsizei instanceCount,
gl::DrawElementsType indexTypeOrNone,
const void *indices,
bool xfbPass);
angle::Result drawTriFanArrays(const gl::Context *context,
GLint first,
GLsizei count,

Просмотреть файл

@ -180,7 +180,8 @@ class DisplayMtl : public DisplayImpl
void initializeFeatures();
void initializeLimitations();
EGLenum EGLDrawingBufferTextureTarget();
id<MTLDevice> getMetalDeviceMatchingAttribute(const egl::AttributeMap &attribs);
mtl::AutoObjCPtr<id<MTLDevice>> getMetalDeviceMatchingAttribute(
const egl::AttributeMap &attribs);
angle::Result initializeShaderLibrary();
mtl::AutoObjCPtr<id<MTLDevice>> mMetalDevice = nil;

Просмотреть файл

@ -137,8 +137,7 @@ angle::Result DisplayMtl::initializeImpl(egl::Display *display)
{
ANGLE_MTL_OBJC_SCOPE
{
mMetalDevice =
[getMetalDeviceMatchingAttribute(display->getAttributeMap()) ANGLE_MTL_AUTORELEASE];
mMetalDevice = getMetalDeviceMatchingAttribute(display->getAttributeMap());
// If we can't create a device, fail initialization.
if (!mMetalDevice.get())
{
@ -229,14 +228,15 @@ DeviceImpl *DisplayMtl::createDevice()
return new DeviceMtl();
}
id<MTLDevice> DisplayMtl::getMetalDeviceMatchingAttribute(const egl::AttributeMap &attribs)
mtl::AutoObjCPtr<id<MTLDevice>> DisplayMtl::getMetalDeviceMatchingAttribute(
const egl::AttributeMap &attribs)
{
#if defined(ANGLE_PLATFORM_MACOS) || defined(ANGLE_PLATFORM_MACCATALYST)
const std::string anglePreferredDevice = angle::GetEnvironmentVar(kANGLEPreferredDeviceEnv);
NSArray<id<MTLDevice>> *deviceList = MTLCopyAllDevices();
auto deviceList = mtl::adoptObjCObj(MTLCopyAllDevices());
if (anglePreferredDevice != "")
{
for (id<MTLDevice> device in deviceList)
for (id<MTLDevice> device in deviceList.get())
{
if ([device.name.lowercaseString
containsString:[NSString stringWithUTF8String:anglePreferredDevice.c_str()]
@ -256,7 +256,7 @@ id<MTLDevice> DisplayMtl::getMetalDeviceMatchingAttribute(const egl::AttributeMa
#endif
// If we can't find anything, or are on a platform that doesn't support power options, create a
// default device.
return MTLCreateSystemDefaultDevice();
return mtl::adoptObjCObj(MTLCreateSystemDefaultDevice());
}
egl::Error DisplayMtl::waitClient(const gl::Context *context)
@ -908,6 +908,9 @@ void DisplayMtl::initializeExtensions() const
// GL_OES_EGL_sync
mNativeExtensions.EGLSyncOES = true;
// GL_ARB_sync
mNativeExtensions.syncARB = true;
}
}
@ -1026,6 +1029,8 @@ void DisplayMtl::initializeFeatures()
ANGLE_FEATURE_CONDITION((&mFeatures), intelExplicitBoolCastWorkaround,
isIntel() && GetMacOSVersion() < OSVersion(11, 0, 0));
ANGLE_FEATURE_CONDITION((&mFeatures), intelDisableFastMath,
isIntel() && GetMacOSVersion() < OSVersion(12, 0, 0));
ANGLE_FEATURE_CONDITION((&mFeatures), forceNonCSBaseMipmapGeneration, isIntel());
@ -1050,22 +1055,16 @@ angle::Result DisplayMtl::initializeShaderLibrary()
#ifdef ANGLE_METAL_XCODE_BUILDS_SHADERS
mDefaultShadersAsyncInfo.reset(new DefaultShaderAsyncInfoMtl);
NSString *path = [NSBundle bundleWithIdentifier:@"com.apple.WebKit"].bundlePath;
NSError *error = nullptr;
mDefaultShadersAsyncInfo->defaultShaders =
[getMetalDevice() newDefaultLibraryWithBundle:[NSBundle bundleWithPath:path] error:&error];
if (error && !mDefaultShadersAsyncInfo->defaultShaders)
{
ANGLE_MTL_OBJC_SCOPE
{
ERR() << "Internal error: newDefaultLibraryWithBundle failed. "
<< error.localizedDescription.UTF8String;
}
mDefaultShadersAsyncInfo->defaultShadersCompileError = std::move(error);
return angle::Result::Stop;
}
mDefaultShadersAsyncInfo->compiled = true;
const uint8_t *compiled_shader_binary;
size_t compiled_shader_binary_len;
compiled_shader_binary = gMetalBinaryShaders;
compiled_shader_binary_len = gMetalBinaryShaders_len;
mtl::AutoObjCPtr<NSError *> err = nil;
mtl::AutoObjCPtr<id<MTLLibrary>> mDefaultShaders = mtl::CreateShaderLibraryFromBinary(
getMetalDevice(), compiled_shader_binary, compiled_shader_binary_len, &err);
mDefaultShadersAsyncInfo->defaultShaders = std::move(mDefaultShaders.get());
mDefaultShadersAsyncInfo->defaultShadersCompileError = std::move(err.get());
mDefaultShadersAsyncInfo->compiled = true;
#else
mDefaultShadersAsyncInfo.reset(new DefaultShaderAsyncInfoMtl);

Просмотреть файл

@ -157,6 +157,11 @@ class ProgramMtl : public ProgramImpl, public mtl::RenderPipelineCacheSpecialize
return mMslShaderTranslateInfo[shaderType].metalShaderSource;
}
mtl::TranslatedShaderInfo getTranslatedShaderInfo(const gl::ShaderType shaderType) const
{
return mMslShaderTranslateInfo[shaderType];
}
bool hasFlatAttribute() const { return programHasFlatAttributes(); }
private:

Просмотреть файл

@ -728,8 +728,11 @@ angle::Result ProgramMtl::createMslShaderLib(
// Convert to actual binary shader
mtl::AutoObjCPtr<NSError *> err = nil;
translatedMslInfo->metalLibrary = mtl::CreateShaderLibrary(
mtlDevice, translatedMslInfo->metalShaderSource, substitutionMacros, &err);
bool disableFastMath = (context->getDisplay()->getFeatures().intelDisableFastMath.enabled &&
translatedMslInfo->hasInvariantOrAtan);
translatedMslInfo->metalLibrary =
mtl::CreateShaderLibrary(mtlDevice, translatedMslInfo->metalShaderSource,
substitutionMacros, !disableFastMath, &err);
if (err && !translatedMslInfo->metalLibrary)
{
std::ostringstream ss;
@ -818,6 +821,7 @@ void ProgramMtl::saveShaderInternalInfo(gl::BinaryOutputStream *stream)
{
stream->writeInt<uint32_t>(uboBinding);
}
stream->writeBool(mMslShaderTranslateInfo[shaderType].hasInvariantOrAtan);
}
for (size_t xfbBindIndex = 0; xfbBindIndex < mtl::kMaxShaderXFBs; xfbBindIndex++)
{
@ -861,7 +865,9 @@ void ProgramMtl::loadShaderInternalInfo(gl::BinaryInputStream *stream)
{
uboBinding = stream->readInt<uint32_t>();
}
mMslShaderTranslateInfo[shaderType].hasInvariantOrAtan = stream->readBool();
}
for (size_t xfbBindIndex = 0; xfbBindIndex < mtl::kMaxShaderXFBs; xfbBindIndex++)
{
stream->readInt(

Просмотреть файл

@ -170,11 +170,11 @@ angle::Result ProvokingVertexHelper::getSpecializedShader(
const mtl::ProvokingVertexComputePipelineDesc &pipelineDesc,
id<MTLFunction> *shaderOut)
{
uint indexBufferKey = buildIndexBufferKey(pipelineDesc);
MTLFunctionConstantValues *fcValues = [[MTLFunctionConstantValues alloc] init];
uint indexBufferKey = buildIndexBufferKey(pipelineDesc);
auto fcValues = mtl::adoptObjCObj([[MTLFunctionConstantValues alloc] init]);
[fcValues setConstantValue:&indexBufferKey type:MTLDataTypeUInt withName:@"fixIndexBufferKey"];
return CreateMslShader(context, mProvokingVertexLibrary, @"fixIndexBuffer", fcValues,
return CreateMslShader(context, mProvokingVertexLibrary, @"fixIndexBuffer", fcValues.get(),
shaderOut);
}
// Private command buffer

Просмотреть файл

@ -274,14 +274,21 @@ class WrappedObject
void retainAssign(T obj)
{
T retained = obj;
#if !__has_feature(objc_arc)
T retained = obj;
[retained retain];
#endif
release();
mMetalObject = obj;
}
void unretainAssign(T obj)
{
release();
mMetalObject = obj;
}
private:
void release()
{
@ -294,6 +301,18 @@ class WrappedObject
T mMetalObject = nil;
};
// Because ARC enablement is a compile-time choice, and we compile this header
// both ways, we need a separate copy of our code when ARC is enabled.
#if __has_feature(objc_arc)
# define adoptObjCObj adoptObjCObjArc
#endif
template <typename T>
class AutoObjCPtr;
template <typename T>
using AutoObjCObj = AutoObjCPtr<T *>;
template <typename U>
AutoObjCObj<U> adoptObjCObj(U *NS_RELEASES_ARGUMENT) __attribute__((__warn_unused_result__));
// This class is similar to WrappedObject, however, it allows changing the
// internal pointer with public methods.
template <typename T>
@ -359,7 +378,17 @@ class AutoObjCPtr : public WrappedObject<T>
using ParentType::retainAssign;
template <typename U>
friend AutoObjCObj<U> adoptObjCObj(U *NS_RELEASES_ARGUMENT)
__attribute__((__warn_unused_result__));
private:
enum AdoptTag
{
Adopt
};
AutoObjCPtr(T src, AdoptTag) { this->unretainAssign(src); }
void transfer(AutoObjCPtr &&src)
{
this->retainAssign(std::move(src.get()));
@ -367,8 +396,17 @@ class AutoObjCPtr : public WrappedObject<T>
}
};
template <typename T>
using AutoObjCObj = AutoObjCPtr<T *>;
template <typename U>
inline AutoObjCObj<U> adoptObjCObj(U *NS_RELEASES_ARGUMENT src)
{
#if __has_feature(objc_arc)
return src;
#elif defined(OBJC_NO_GC)
return AutoObjCPtr<U *>(src, AutoObjCPtr<U *>::Adopt);
#else
# error "ObjC GC not supported."
#endif
}
// NOTE: SharedEvent is only declared on iOS 12.0+ or mac 10.14+
#if defined(__IPHONE_12_0) || defined(__MAC_10_14)
@ -376,7 +414,7 @@ using AutoObjCObj = AutoObjCPtr<T *>;
using SharedEventRef = AutoObjCPtr<id<MTLSharedEvent>>;
#else
# define ANGLE_MTL_EVENT_AVAILABLE 0
using SharedEventRef = AutoObjCObj<NSObject>;
using SharedEventRef = AutoObjCObj<NSObject>;
#endif
// The native image index used by Metal back-end, the image index uses native mipmap level instead

Просмотреть файл

@ -34,6 +34,7 @@ struct TranslatedShaderInfo
std::array<uint32_t, kMaxGLUBOBindings> actualUBOBindings;
std::array<uint32_t, kMaxShaderXFBs> actualXFBBindings;
bool hasUBOArgumentBuffer;
bool hasInvariantOrAtan;
};
void MSLGetShaderSource(const gl::ProgramState &programState,
const gl::ProgramLinkedResources &resources,

Просмотреть файл

@ -457,6 +457,8 @@ angle::Result GlslangGetMSL(const gl::Context *glContext,
GetAssignedSamplerBindings(reflection, originalSamplerBindings, structSamplers,
&mslShaderInfoOut->at(type).actualSamplerBindings);
}
(*mslShaderInfoOut)[type].hasInvariantOrAtan =
reflection->hasAtan || reflection->hasInvariance;
}
return angle::Result::Continue;
}

Просмотреть файл

@ -575,10 +575,6 @@ class TransformFeedbackUtils
ContextMtl *contextMtl,
RenderCommandEncoder *cmdEncoder,
mtl::RenderPipelineDesc &pipelineDesc);
private:
AutoObjCPtr<id<MTLLibrary>> createMslXfbLibrary(ContextMtl *contextMtl,
const std::string &translatedMsl);
};
// RenderUtils: container class of various util classes above

Просмотреть файл

@ -3067,28 +3067,5 @@ VertexFormatConversionUtils::getFloatConverstionRenderPipeline(ContextMtl *conte
return cache.getRenderPipelineState(contextMtl, pipelineDesc);
}
AutoObjCPtr<id<MTLLibrary>> TransformFeedbackUtils::createMslXfbLibrary(
ContextMtl *contextMtl,
const std::string &translatedMsl)
{
ANGLE_MTL_OBJC_SCOPE
{
DisplayMtl *display = contextMtl->getDisplay();
id<MTLDevice> mtlDevice = display->getMetalDevice();
// Convert to actual binary shader
mtl::AutoObjCPtr<NSError *> err = nil;
mtl::AutoObjCPtr<id<MTLLibrary>> mtlShaderLib = mtl::CreateShaderLibrary(
mtlDevice, translatedMsl, @{@"TRANSFORM_FEEDBACK_ENABLED" : @"1"}, &err);
if (err && !mtlShaderLib)
{
NSLog(@"%@", err.get());
assert(0);
}
mtlShaderLib.get().label = @"TransformFeedback";
return mtlShaderLib;
}
}
} // namespace mtl
} // namespace rx

Просмотреть файл

@ -92,6 +92,7 @@ AutoObjCPtr<id<MTLLibrary>> CreateShaderLibrary(
id<MTLDevice> metalDevice,
const std::string &source,
NSDictionary<NSString *, NSObject *> *substitutionDictionary,
bool enableFastMath,
AutoObjCPtr<NSError *> *error);
AutoObjCPtr<id<MTLLibrary>> CreateShaderLibrary(id<MTLDevice> metalDevice,
@ -103,6 +104,7 @@ AutoObjCPtr<id<MTLLibrary>> CreateShaderLibrary(
const char *source,
size_t sourceLen,
NSDictionary<NSString *, NSObject *> *substitutionDictionary,
bool enableFastMath,
AutoObjCPtr<NSError *> *error);
AutoObjCPtr<id<MTLLibrary>> CreateShaderLibraryFromBinary(

Просмотреть файл

@ -133,26 +133,26 @@ void StartFrameCapture(id<MTLDevice> metalDevice, id<MTLCommandQueue> metalCmdQu
# ifdef __MAC_10_15
if (ANGLE_APPLE_AVAILABLE_XCI(10.15, 13.0, 13))
{
MTLCaptureDescriptor *captureDescriptor = [[MTLCaptureDescriptor alloc] init];
captureDescriptor.captureObject = metalDevice;
const std::string filePath = GetMetalCaptureFile();
auto captureDescriptor = mtl::adoptObjCObj([[MTLCaptureDescriptor alloc] init]);
captureDescriptor.get().captureObject = metalDevice;
const std::string filePath = GetMetalCaptureFile();
if (filePath != "")
{
const std::string numberedPath =
filePath + std::to_string(gFrameCaptured - 1) + ".gputrace";
captureDescriptor.destination = MTLCaptureDestinationGPUTraceDocument;
captureDescriptor.outputURL =
captureDescriptor.get().destination = MTLCaptureDestinationGPUTraceDocument;
captureDescriptor.get().outputURL =
[NSURL fileURLWithPath:[NSString stringWithUTF8String:numberedPath.c_str()]
isDirectory:false];
}
else
{
// This will pause execution only if application is being debugged inside Xcode
captureDescriptor.destination = MTLCaptureDestinationDeveloperTools;
captureDescriptor.get().destination = MTLCaptureDestinationDeveloperTools;
}
NSError *error;
if (![captureManager startCaptureWithDescriptor:captureDescriptor error:&error])
if (![captureManager startCaptureWithDescriptor:captureDescriptor.get() error:&error])
{
NSLog(@"Failed to start capture, error %@", error);
}
@ -161,11 +161,11 @@ void StartFrameCapture(id<MTLDevice> metalDevice, id<MTLCommandQueue> metalCmdQu
# endif // __MAC_10_15
if (ANGLE_APPLE_AVAILABLE_XCI(10.15, 13.0, 13))
{
MTLCaptureDescriptor *captureDescriptor = [[MTLCaptureDescriptor alloc] init];
captureDescriptor.captureObject = metalDevice;
auto captureDescriptor = mtl::adoptObjCObj([[MTLCaptureDescriptor alloc] init]);
captureDescriptor.get().captureObject = metalDevice;
NSError *error;
if (![captureManager startCaptureWithDescriptor:captureDescriptor error:&error])
if (![captureManager startCaptureWithDescriptor:captureDescriptor.get() error:&error])
{
NSLog(@"Failed to start capture, error %@", error);
}
@ -270,6 +270,79 @@ GLint GetSliceOrDepth(const ImageNativeIndex &index)
return std::max(layer, startDepth);
}
bool GetCompressedBufferSizeAndRowLengthForTextureWithFormat(const TextureRef &texture,
const Format &textureObjFormat,
const ImageNativeIndex &index,
size_t *bytesPerRowOut,
size_t *bytesPerImageOut)
{
gl::Extents size = texture->size(index);
GLuint bufferSizeInBytes;
uint32_t bufferRowLength;
if (!textureObjFormat.intendedInternalFormat().computeCompressedImageSize(size,
&bufferSizeInBytes))
{
return false;
}
if (!textureObjFormat.intendedInternalFormat().computeBufferRowLength(size.width,
&bufferRowLength))
{
return false;
}
*bytesPerImageOut = bufferSizeInBytes;
*bytesPerRowOut = bufferRowLength;
return true;
}
static angle::Result InitializeCompressedTextureContents(const gl::Context *context,
const TextureRef &texture,
const Format &textureObjFormat,
const ImageNativeIndex &index,
const uint layer,
const uint startDepth)
{
assert(textureObjFormat.actualAngleFormat().isBlock);
size_t bytesPerRow = 0;
size_t bytesPerImage = 0;
if (!GetCompressedBufferSizeAndRowLengthForTextureWithFormat(texture, textureObjFormat, index,
&bytesPerRow, &bytesPerImage))
{
return angle::Result::Stop;
}
ContextMtl *contextMtl = mtl::GetImpl(context);
gl::Extents extents = texture->size(index);
if (texture->isCPUAccessible())
{
angle::MemoryBuffer buffer;
if (!buffer.resize(bytesPerImage))
{
return angle::Result::Stop;
}
buffer.fill(0);
for (NSUInteger d = 0; d < static_cast<NSUInteger>(extents.depth); ++d)
{
auto mtlTextureRegion = MTLRegionMake2D(0, 0, extents.width, extents.height);
mtlTextureRegion.origin.z = d + startDepth;
texture->replaceRegion(contextMtl, mtlTextureRegion, index.getNativeLevel(), layer,
buffer.data(), bytesPerRow, 0);
}
}
else
{
mtl::BufferRef zeroBuffer;
ANGLE_TRY(mtl::Buffer::MakeBuffer(contextMtl, bytesPerImage, nullptr, &zeroBuffer));
mtl::BlitCommandEncoder *blitEncoder = contextMtl->getBlitCommandEncoder();
for (NSUInteger d = 0; d < static_cast<NSUInteger>(extents.depth); ++d)
{
auto blitOrigin = MTLOriginMake(0, 0, d + startDepth);
blitEncoder->copyBufferToTexture(zeroBuffer, 0, bytesPerRow, 0,
MTLSizeMake(extents.width, extents.height, 1), texture,
layer, index.getNativeLevel(), blitOrigin, 0);
}
blitEncoder->endEncoding();
}
return angle::Result::Continue;
}
}
angle::Result InitializeTextureContents(const gl::Context *context,
@ -291,7 +364,7 @@ angle::Result InitializeTextureContents(const gl::Context *context,
// This function is called in many places to initialize the content of a texture.
// So it's better we do the initial check here instead of let the callers do it themselves:
if (!textureObjFormat.valid() || intendedInternalFormat.compressed)
if (!textureObjFormat.valid())
{
return angle::Result::Continue;
}
@ -301,7 +374,6 @@ angle::Result InitializeTextureContents(const gl::Context *context,
// Intiialize the content to black
GLint layer, startDepth;
GetSliceAndDepth(index, &layer, &startDepth);
if (texture->isCPUAccessible() && index.getType() != gl::TextureType::_2DMultisample &&
index.getType() != gl::TextureType::_2DMultisampleArray && !forceGPUInitialization)
{
@ -346,6 +418,11 @@ angle::Result InitializeTextureContents(const gl::Context *context,
}
}
}
else if (intendedInternalFormat.compressed)
{
return InitializeCompressedTextureContents(context, texture, textureObjFormat, index, layer,
startDepth);
}
else
{
ANGLE_TRY(InitializeTextureContentsGPU(context, texture, textureObjFormat, index,
@ -704,17 +781,18 @@ AutoObjCPtr<id<MTLLibrary>> CreateShaderLibrary(
id<MTLDevice> metalDevice,
const std::string &source,
NSDictionary<NSString *, NSObject *> *substitutionMacros,
bool enableFastMath,
AutoObjCPtr<NSError *> *error)
{
return CreateShaderLibrary(metalDevice, source.c_str(), source.size(), substitutionMacros,
error);
enableFastMath, error);
}
AutoObjCPtr<id<MTLLibrary>> CreateShaderLibrary(id<MTLDevice> metalDevice,
const std::string &source,
AutoObjCPtr<NSError *> *error)
{
return CreateShaderLibrary(metalDevice, source.c_str(), source.size(), @{}, error);
return CreateShaderLibrary(metalDevice, source.c_str(), source.size(), @{}, true, error);
}
AutoObjCPtr<id<MTLLibrary>> CreateShaderLibrary(
@ -722,6 +800,7 @@ AutoObjCPtr<id<MTLLibrary>> CreateShaderLibrary(
const char *source,
size_t sourceLen,
NSDictionary<NSString *, NSObject *> *substitutionMacros,
bool enableFastMath,
AutoObjCPtr<NSError *> *errorOut)
{
ANGLE_MTL_OBJC_SCOPE
@ -741,6 +820,7 @@ AutoObjCPtr<id<MTLLibrary>> CreateShaderLibrary(
// No preserveInvariance available compiling from source, so just disable fastmath.
options.fastMathEnabled = false;
#endif
options.fastMathEnabled &= enableFastMath;
options.languageVersion = GetUserSetOrHighestMSLVersion(options.languageVersion);
options.preprocessorMacros = substitutionMacros;
auto library = [metalDevice newLibraryWithSource:nsSource options:options error:&nsError];

Просмотреть файл

@ -16,7 +16,9 @@
#include "libGLESv2/resource.h"
#include <atomic>
#if defined(ANGLE_PLATFORM_APPLE)
# include <dispatch/dispatch.h>
#endif
namespace egl
{
namespace
@ -41,17 +43,28 @@ void SetContextToAndroidOpenGLTLSSlot(gl::Context *value)
Thread *AllocateCurrentThread()
{
Thread *thread;
{
// Global thread intentionally leaked
ANGLE_SCOPED_DISABLE_LSAN();
gCurrentThread = new Thread();
thread = new Thread();
#if defined(ANGLE_PLATFORM_APPLE)
SetCurrentThreadTLS(thread);
#else
gCurrentThread = thread;
#endif
}
// Initialize fast TLS slot
SetContextToAndroidOpenGLTLSSlot(nullptr);
gl::gCurrentValidContext = nullptr;
return gCurrentThread;
#if defined(ANGLE_PLATFORM_APPLE)
gl::SetCurrentValidContextTLS(nullptr);
#else
gl::gCurrentValidContext = nullptr;
#endif
ASSERT(thread);
return thread;
}
void AllocateMutex()
@ -69,7 +82,37 @@ void AllocateMutex()
} // anonymous namespace
#if defined(ANGLE_PLATFORM_APPLE)
// TODO(angleproject:6479): Due to a bug in Apple's dyld loader, `thread_local` will cause
// excessive memory use. Temporarily avoid it by using pthread's thread
// local storage instead.
// https://bugs.webkit.org/show_bug.cgi?id=228240
static TLSIndex GetCurrentThreadTLSIndex()
{
static TLSIndex CurrentThreadIndex = TLS_INVALID_INDEX;
static dispatch_once_t once;
dispatch_once(&once, ^{
ASSERT(CurrentThreadIndex == TLS_INVALID_INDEX);
CurrentThreadIndex = CreateTLSIndex();
});
return CurrentThreadIndex;
}
Thread *GetCurrentThreadTLS()
{
TLSIndex CurrentThreadIndex = GetCurrentThreadTLSIndex();
ASSERT(CurrentThreadIndex != TLS_INVALID_INDEX);
return static_cast<Thread *>(GetTLSValue(CurrentThreadIndex));
}
void SetCurrentThreadTLS(Thread *thread)
{
TLSIndex CurrentThreadIndex = GetCurrentThreadTLSIndex();
ASSERT(CurrentThreadIndex != TLS_INVALID_INDEX);
SetTLSValue(CurrentThreadIndex, thread);
}
#else
thread_local Thread *gCurrentThread = nullptr;
#endif
angle::GlobalMutex &GetGlobalMutex()
{
@ -91,15 +134,31 @@ void SetGlobalLastContext(gl::Context *context)
// It also causes a flaky false positive in TSAN. http://crbug.com/1223970
ANGLE_NO_SANITIZE_MEMORY ANGLE_NO_SANITIZE_THREAD Thread *GetCurrentThread()
{
#if defined(ANGLE_PLATFORM_APPLE)
Thread *current = GetCurrentThreadTLS();
#else
Thread *current = gCurrentThread;
#endif
return (current ? current : AllocateCurrentThread());
}
void SetContextCurrent(Thread *thread, gl::Context *context)
{
ASSERT(gCurrentThread == thread);
#if defined(ANGLE_PLATFORM_APPLE)
Thread *currentThread = GetCurrentThreadTLS();
#else
Thread *currentThread = gCurrentThread;
#endif
ASSERT(currentThread);
currentThread->setCurrent(context);
SetContextToAndroidOpenGLTLSSlot(context);
#if defined(ANGLE_PLATFORM_APPLE)
gl::SetCurrentValidContextTLS(context);
#else
gl::gCurrentValidContext = context;
#endif
#if defined(ANGLE_FORCE_CONTEXT_CHECK_EVERY_CALL)
DirtyContextIfNeeded(context);
#endif

Просмотреть файл

@ -14,6 +14,10 @@
#include "libANGLE/Thread.h"
#include "libANGLE/features.h"
#if defined(ANGLE_PLATFORM_APPLE)
# include "common/tls.h"
#endif
#include <mutex>
namespace angle
@ -89,7 +93,12 @@ namespace egl
class Debug;
class Thread;
#if defined(ANGLE_PLATFORM_APPLE)
extern Thread *GetCurrentThreadTLS();
extern void SetCurrentThreadTLS(Thread *thread);
#else
extern thread_local Thread *gCurrentThread;
#endif
angle::GlobalMutex &GetGlobalMutex();
gl::Context *GetGlobalLastContext();
@ -125,8 +134,13 @@ ANGLE_INLINE Context *GetGlobalContext()
}
#endif
ASSERT(egl::gCurrentThread);
return egl::gCurrentThread->getContext();
#if defined(ANGLE_PLATFORM_APPLE)
egl::Thread *currentThread = egl::GetCurrentThreadTLS();
#else
egl::Thread *currentThread = egl::gCurrentThread;
#endif
ASSERT(currentThread);
return currentThread->getContext();
}
ANGLE_INLINE Context *GetValidGlobalContext()
@ -144,7 +158,11 @@ ANGLE_INLINE Context *GetValidGlobalContext()
}
#endif
#if defined(ANGLE_PLATFORM_APPLE)
return GetCurrentValidContextTLS();
#else
return gCurrentValidContext;
#endif
}
// Generate a context lost error on the context if it is non-null and lost.