зеркало из https://github.com/AvaloniaUI/angle.git
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:
Родитель
a44197b5ac
Коммит
54d4bfe5f9
|
@ -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.
|
||||
|
|
Загрузка…
Ссылка в новой задаче