зеркало из https://github.com/AvaloniaUI/angle.git
Merge Webkit up to Oct 27 2021
Merge the following commits from Webkit. This change merges webkit from the following git commits Previous: commit 703b234524e75109ca3e94febbf63098314022f5 Author: Alex Christensen <achristensen@webkit.org> Date: Tue Sep 28 16:22:30 2021 +0000 Mostly fix Mac CMake build https://bugs.webkit.org/show_bug.cgi?id=230868 Current: commit 43d2e637f84b1e6b75c139ac64c26ca108b4f12f Author: Kimmo Kinnunen <kkinnunen@apple.com> Date: Wed Oct 27 17:43:38 2021 +0000 REGRESSION (Safari 15): Poor WebGL performance on https://downloads.scirra.com/labs/particles Commits: commit 8238f462c96e515dabd3db0e26c143b18f47340c Author: Kyle Piddington <kpiddington@apple.com> Date: Wed Oct 6 21:45:18 2021 +0000 Shadertoy "truchet district" fails to compile with error: Internal error compiling shader with Metal backend" commit 2fcb9af290e4b6c804f11ad4359555507c1492f9 Author: Kyle Piddington <kpiddington@apple.com> Date: Thu Oct 14 21:14:26 2021 +0000 https://tankionline.com/play/ html5 engine not working: crashes. (Metal shader not working) https://bugs.webkit.org/show_bug.cgi?id=231490 commit e11955a258380a875115ded16ab8963142c4023b Author: Kyle Piddington <kpiddington@apple.com> Date: Fri Oct 15 23:57:12 2021 +0000 REGRESSION (r283667): webgl/2.0.0/deqp/functional/gles3/lifetime.html fails https://bugs.webkit.org/show_bug.cgi?id=231682 commit 43d2e637f84b1e6b75c139ac64c26ca108b4f12f Author: Kimmo Kinnunen <kkinnunen@apple.com> Date: Wed Oct 27 17:43:38 2021 +0000 REGRESSION (Safari 15): Poor WebGL performance on https://downloads.scirra.com/labs/particles https://bugs.webkit.org/show_bug.cgi?id=230749 Bug: angleproject:6630 Change-Id: Icca411dc429538f839f05834f1851fbc54ef8a1d Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/3248573 Commit-Queue: Kyle Piddington <kpiddington@apple.com> Reviewed-by: Gregg Tavares <gman@chromium.org> Reviewed-by: Geoff Lang <geofflang@chromium.org>
This commit is contained in:
Родитель
683ab73891
Коммит
50fc2909d8
|
@ -409,8 +409,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/RewriteKeywords.cpp",
|
||||
"src/compiler/translator/TranslatorMetalDirect/RewriteKeywords.h",
|
||||
"src/compiler/translator/TranslatorMetalDirect/RewriteOutArgs.cpp",
|
||||
"src/compiler/translator/TranslatorMetalDirect/RewriteOutArgs.h",
|
||||
"src/compiler/translator/TranslatorMetalDirect/RewritePipelines.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/RewriteKeywords.h"
|
||||
#include "compiler/translator/TranslatorMetalDirect/RewriteOutArgs.h"
|
||||
#include "compiler/translator/TranslatorMetalDirect/RewritePipelines.h"
|
||||
#include "compiler/translator/TranslatorMetalDirect/RewriteUnaddressableReferences.h"
|
||||
|
@ -65,8 +64,8 @@ namespace
|
|||
{
|
||||
|
||||
constexpr Name kSampleMaskWriteFuncName("writeSampleMask", SymbolType::AngleInternal);
|
||||
constexpr Name kFlippedPointCoordName("flippedPointCoord", SymbolType::UserDefined);
|
||||
constexpr Name kFlippedFragCoordName("flippedFragCoord", SymbolType::UserDefined);
|
||||
constexpr Name kFlippedPointCoordName("flippedPointCoord", SymbolType::AngleInternal);
|
||||
constexpr Name kFlippedFragCoordName("flippedFragCoord", SymbolType::AngleInternal);
|
||||
|
||||
constexpr const TVariable kgl_VertexIDMetal(BuiltInId::gl_VertexID,
|
||||
ImmutableString("gl_VertexID"),
|
||||
|
@ -631,91 +630,6 @@ bool TranslatorMetalDirect::appendVertexShaderDepthCorrectionToMain(TIntermBlock
|
|||
return RunAtTheEndOfShader(this, root, assignment, &getSymbolTable());
|
||||
}
|
||||
|
||||
static std::set<ImmutableString> GetMslKeywords()
|
||||
{
|
||||
std::set<ImmutableString> keywords;
|
||||
|
||||
keywords.emplace("alignas");
|
||||
keywords.emplace("alignof");
|
||||
keywords.emplace("as_type");
|
||||
keywords.emplace("auto");
|
||||
keywords.emplace("catch");
|
||||
keywords.emplace("char");
|
||||
keywords.emplace("class");
|
||||
keywords.emplace("const_cast");
|
||||
keywords.emplace("constant");
|
||||
keywords.emplace("constexpr");
|
||||
keywords.emplace("decltype");
|
||||
keywords.emplace("delete");
|
||||
keywords.emplace("device");
|
||||
keywords.emplace("dynamic_cast");
|
||||
keywords.emplace("enum");
|
||||
keywords.emplace("explicit");
|
||||
keywords.emplace("export");
|
||||
keywords.emplace("extern");
|
||||
keywords.emplace("fragment");
|
||||
keywords.emplace("friend");
|
||||
keywords.emplace("goto");
|
||||
keywords.emplace("half");
|
||||
keywords.emplace("inline");
|
||||
keywords.emplace("int16_t");
|
||||
keywords.emplace("int32_t");
|
||||
keywords.emplace("int64_t");
|
||||
keywords.emplace("int8_t");
|
||||
keywords.emplace("kernel");
|
||||
keywords.emplace("long");
|
||||
keywords.emplace("main0");
|
||||
keywords.emplace("metal");
|
||||
keywords.emplace("mutable");
|
||||
keywords.emplace("namespace");
|
||||
keywords.emplace("new");
|
||||
keywords.emplace("noexcept");
|
||||
keywords.emplace("nullptr_t");
|
||||
keywords.emplace("nullptr");
|
||||
keywords.emplace("operator");
|
||||
keywords.emplace("override");
|
||||
keywords.emplace("private");
|
||||
keywords.emplace("protected");
|
||||
keywords.emplace("ptrdiff_t");
|
||||
keywords.emplace("public");
|
||||
keywords.emplace("ray_data");
|
||||
keywords.emplace("register");
|
||||
keywords.emplace("short");
|
||||
keywords.emplace("signed");
|
||||
keywords.emplace("size_t");
|
||||
keywords.emplace("sizeof");
|
||||
keywords.emplace("stage_in");
|
||||
keywords.emplace("static_assert");
|
||||
keywords.emplace("static_cast");
|
||||
keywords.emplace("static");
|
||||
keywords.emplace("template");
|
||||
keywords.emplace("this");
|
||||
keywords.emplace("thread_local");
|
||||
keywords.emplace("thread");
|
||||
keywords.emplace("threadgroup_imageblock");
|
||||
keywords.emplace("threadgroup");
|
||||
keywords.emplace("throw");
|
||||
keywords.emplace("try");
|
||||
keywords.emplace("typedef");
|
||||
keywords.emplace("typeid");
|
||||
keywords.emplace("typename");
|
||||
keywords.emplace("uchar");
|
||||
keywords.emplace("uint16_t");
|
||||
keywords.emplace("uint32_t");
|
||||
keywords.emplace("uint64_t");
|
||||
keywords.emplace("uint8_t");
|
||||
keywords.emplace("union");
|
||||
keywords.emplace("unsigned");
|
||||
keywords.emplace("ushort");
|
||||
keywords.emplace("using");
|
||||
keywords.emplace("vertex");
|
||||
keywords.emplace("virtual");
|
||||
keywords.emplace("volatile");
|
||||
keywords.emplace("wchar_t");
|
||||
keywords.emplace("NAN");
|
||||
return keywords;
|
||||
}
|
||||
|
||||
static inline MetalShaderType metalShaderTypeFromGLSL(sh::GLenum shaderType)
|
||||
{
|
||||
switch (shaderType)
|
||||
|
@ -756,7 +670,7 @@ bool TranslatorMetalDirect::translateImpl(TInfoSinkBase &sink,
|
|||
// is inactive.
|
||||
if (!RemoveInactiveInterfaceVariables(this, root, &getSymbolTable(), getAttributes(),
|
||||
getInputVaryings(), getOutputVariables(), getUniforms(),
|
||||
getInterfaceBlocks()))
|
||||
getInterfaceBlocks(), false))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
@ -1135,11 +1049,6 @@ bool TranslatorMetalDirect::translateImpl(TInfoSinkBase &sink,
|
|||
return false;
|
||||
}
|
||||
|
||||
if (!RewriteKeywords(*this, *root, idGen, GetMslKeywords()))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// This is the largest size required to pass all the tests in
|
||||
// (dEQP-GLES3.functional.shaders.large_constant_arrays)
|
||||
// This value could in principle be smaller.
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
#include <unordered_map>
|
||||
#include <unordered_set>
|
||||
|
||||
#include "compiler/translator/TranslatorMetalDirect/RewriteKeywords.h"
|
||||
#include "compiler/translator/TranslatorMetalDirect/IdGen.h"
|
||||
|
||||
using namespace sh;
|
||||
|
||||
|
|
|
@ -68,11 +68,22 @@ void Name::emit(TInfoSinkBase &out) const
|
|||
switch (mSymbolType)
|
||||
{
|
||||
case SymbolType::BuiltIn:
|
||||
case SymbolType::UserDefined:
|
||||
ASSERT(!mRawName.empty());
|
||||
out << mRawName;
|
||||
break;
|
||||
|
||||
case SymbolType::UserDefined:
|
||||
ASSERT(!mRawName.empty());
|
||||
if (mRawName != "main")
|
||||
{
|
||||
out << kUserDefinedNamePrefix << mRawName;
|
||||
}
|
||||
else
|
||||
{
|
||||
out << mRawName;
|
||||
}
|
||||
break;
|
||||
|
||||
case SymbolType::AngleInternal:
|
||||
ASSERT(!mRawName.empty());
|
||||
if (mRawName.beginsWith(kAngleInternalPrefix))
|
||||
|
|
|
@ -1,462 +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 <cctype>
|
||||
#include <cstring>
|
||||
#include <limits>
|
||||
#include <map>
|
||||
#include <unordered_map>
|
||||
#include <unordered_set>
|
||||
|
||||
#include "compiler/translator/TranslatorMetalDirect/AstHelpers.h"
|
||||
#include "compiler/translator/TranslatorMetalDirect/RewriteKeywords.h"
|
||||
#include "compiler/translator/tree_util/IntermRebuild.h"
|
||||
|
||||
using namespace sh;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
namespace
|
||||
{
|
||||
|
||||
template <typename T>
|
||||
using Remapping = std::unordered_map<const T *, const T *>;
|
||||
|
||||
class Rewriter : public TIntermRebuild
|
||||
{
|
||||
private:
|
||||
const std::set<ImmutableString> &mKeywords;
|
||||
IdGen &mIdGen;
|
||||
Remapping<TField> modifiedFields;
|
||||
Remapping<TFieldList> mFieldLists;
|
||||
Remapping<TFunction> mFunctions;
|
||||
Remapping<TInterfaceBlock> mInterfaceBlocks;
|
||||
Remapping<TStructure> mStructures;
|
||||
Remapping<TVariable> mVariables;
|
||||
std::map<ImmutableString, std::string> mPredefinedNames;
|
||||
std::string mNewNameBuffer;
|
||||
|
||||
private:
|
||||
template <typename T>
|
||||
ImmutableString maybeCreateNewName(T const &object)
|
||||
{
|
||||
if (needsRenaming(object, false))
|
||||
{
|
||||
auto it = mPredefinedNames.find(Name(object).rawName());
|
||||
if (it != mPredefinedNames.end())
|
||||
{
|
||||
return ImmutableString(it->second);
|
||||
}
|
||||
return mIdGen.createNewName(Name(object)).rawName();
|
||||
}
|
||||
return Name(object).rawName();
|
||||
}
|
||||
|
||||
const TField *createRenamed(const TField &field)
|
||||
{
|
||||
auto *renamed = new TField(const_cast<TType *>(&getRenamedOrOriginal(*field.type())),
|
||||
maybeCreateNewName(field), field.line(), field.symbolType());
|
||||
|
||||
return renamed;
|
||||
}
|
||||
|
||||
const TFieldList *createRenamed(const TFieldList &fieldList)
|
||||
{
|
||||
auto *renamed = new TFieldList();
|
||||
for (const TField *field : fieldList)
|
||||
{
|
||||
renamed->push_back(const_cast<TField *>(&getRenamedOrOriginal(*field)));
|
||||
}
|
||||
return renamed;
|
||||
}
|
||||
|
||||
const TFunction *createRenamed(const TFunction &function)
|
||||
{
|
||||
auto *renamed =
|
||||
new TFunction(&mSymbolTable, maybeCreateNewName(function), function.symbolType(),
|
||||
&getRenamedOrOriginal(function.getReturnType()),
|
||||
function.isKnownToNotHaveSideEffects());
|
||||
|
||||
const size_t paramCount = function.getParamCount();
|
||||
for (size_t i = 0; i < paramCount; ++i)
|
||||
{
|
||||
const TVariable ¶m = *function.getParam(i);
|
||||
renamed->addParameter(&getRenamedOrOriginal(param));
|
||||
}
|
||||
|
||||
if (function.isDefined())
|
||||
{
|
||||
renamed->setDefined();
|
||||
}
|
||||
|
||||
if (function.hasPrototypeDeclaration())
|
||||
{
|
||||
renamed->setHasPrototypeDeclaration();
|
||||
}
|
||||
|
||||
return renamed;
|
||||
}
|
||||
|
||||
const TInterfaceBlock *createRenamed(const TInterfaceBlock &interfaceBlock)
|
||||
{
|
||||
TLayoutQualifier layoutQualifier = TLayoutQualifier::Create();
|
||||
layoutQualifier.blockStorage = interfaceBlock.blockStorage();
|
||||
layoutQualifier.binding = interfaceBlock.blockBinding();
|
||||
|
||||
auto *renamed =
|
||||
new TInterfaceBlock(&mSymbolTable, maybeCreateNewName(interfaceBlock),
|
||||
&getRenamedOrOriginal(interfaceBlock.fields()), layoutQualifier,
|
||||
interfaceBlock.symbolType(), interfaceBlock.extensions());
|
||||
|
||||
return renamed;
|
||||
}
|
||||
|
||||
const TStructure *createRenamed(const TStructure &structure)
|
||||
{
|
||||
auto *renamed =
|
||||
new TStructure(&mSymbolTable, maybeCreateNewName(structure),
|
||||
&getRenamedOrOriginal(structure.fields()), structure.symbolType());
|
||||
|
||||
renamed->setAtGlobalScope(structure.atGlobalScope());
|
||||
|
||||
return renamed;
|
||||
}
|
||||
|
||||
const TType *createRenamed(const TType &type)
|
||||
{
|
||||
TType *renamed;
|
||||
|
||||
if (const TStructure *structure = type.getStruct())
|
||||
{
|
||||
renamed = new TType(&getRenamedOrOriginal(*structure), type.isStructSpecifier());
|
||||
renamed->setQualifier(type.getQualifier());
|
||||
}
|
||||
else if (const TInterfaceBlock *interfaceBlock = type.getInterfaceBlock())
|
||||
{
|
||||
renamed = new TType(&getRenamedOrOriginal(*interfaceBlock), type.getQualifier(),
|
||||
type.getLayoutQualifier());
|
||||
}
|
||||
else
|
||||
{
|
||||
UNREACHABLE(); // Can't rename built-in types.
|
||||
renamed = nullptr;
|
||||
}
|
||||
|
||||
if (type.isArray())
|
||||
{
|
||||
renamed->makeArrays(type.getArraySizes());
|
||||
}
|
||||
renamed->setPrecise(type.isPrecise());
|
||||
renamed->setInvariant(type.isInvariant());
|
||||
renamed->setMemoryQualifier(type.getMemoryQualifier());
|
||||
renamed->setLayoutQualifier(type.getLayoutQualifier());
|
||||
|
||||
return renamed;
|
||||
}
|
||||
|
||||
const TVariable *createRenamed(const TVariable &variable)
|
||||
{
|
||||
auto *renamed = new TVariable(&mSymbolTable, maybeCreateNewName(variable),
|
||||
&getRenamedOrOriginal(variable.getType()),
|
||||
variable.symbolType(), variable.extensions());
|
||||
|
||||
return renamed;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
const T *tryGetRenamedImpl(const T &object, Remapping<T> *remapping)
|
||||
{
|
||||
if (!needsRenaming(object, true))
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (remapping)
|
||||
{
|
||||
auto it = remapping->find(&object);
|
||||
if (it != remapping->end())
|
||||
{
|
||||
return it->second;
|
||||
}
|
||||
}
|
||||
|
||||
const T *renamedObject = createRenamed(object);
|
||||
|
||||
if (remapping)
|
||||
{
|
||||
(*remapping)[&object] = renamedObject;
|
||||
}
|
||||
|
||||
return renamedObject;
|
||||
}
|
||||
|
||||
const TField *tryGetRenamed(const TField &field)
|
||||
{
|
||||
return tryGetRenamedImpl(field, &modifiedFields);
|
||||
}
|
||||
|
||||
const TFieldList *tryGetRenamed(const TFieldList &fieldList)
|
||||
{
|
||||
return tryGetRenamedImpl(fieldList, &mFieldLists);
|
||||
}
|
||||
|
||||
const TFunction *tryGetRenamed(const TFunction &func)
|
||||
{
|
||||
return tryGetRenamedImpl(func, &mFunctions);
|
||||
}
|
||||
|
||||
const TInterfaceBlock *tryGetRenamed(const TInterfaceBlock &interfaceBlock)
|
||||
{
|
||||
return tryGetRenamedImpl(interfaceBlock, &mInterfaceBlocks);
|
||||
}
|
||||
|
||||
const TStructure *tryGetRenamed(const TStructure &structure)
|
||||
{
|
||||
return tryGetRenamedImpl(structure, &mStructures);
|
||||
}
|
||||
|
||||
const TType *tryGetRenamed(const TType &type)
|
||||
{
|
||||
return tryGetRenamedImpl(type, static_cast<Remapping<TType> *>(nullptr));
|
||||
}
|
||||
|
||||
const TVariable *tryGetRenamed(const TVariable &variable)
|
||||
{
|
||||
return tryGetRenamedImpl(variable, &mVariables);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
const T &getRenamedOrOriginal(const T &object)
|
||||
{
|
||||
const T *renamed = tryGetRenamed(object);
|
||||
if (renamed)
|
||||
{
|
||||
return *renamed;
|
||||
}
|
||||
return object;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
bool needsRenamingImpl(const T &object) const
|
||||
{
|
||||
const SymbolType symbolType = object.symbolType();
|
||||
switch (symbolType)
|
||||
{
|
||||
case SymbolType::BuiltIn:
|
||||
case SymbolType::AngleInternal:
|
||||
case SymbolType::Empty:
|
||||
return false;
|
||||
|
||||
case SymbolType::UserDefined:
|
||||
break;
|
||||
}
|
||||
|
||||
const ImmutableString name = Name(object).rawName();
|
||||
if (mKeywords.find(name) != mKeywords.end())
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
if (name.beginsWith(kAngleInternalPrefix))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool needsRenaming(const TField &field, bool recursive) const
|
||||
{
|
||||
return needsRenamingImpl(field) || (recursive && needsRenaming(*field.type(), true));
|
||||
}
|
||||
|
||||
bool needsRenaming(const TFieldList &fieldList, bool recursive) const
|
||||
{
|
||||
ASSERT(recursive);
|
||||
for (const TField *field : fieldList)
|
||||
{
|
||||
if (needsRenaming(*field, true))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool needsRenaming(const TFunction &function, bool recursive) const
|
||||
{
|
||||
if (needsRenamingImpl(function))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!recursive)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
const size_t paramCount = function.getParamCount();
|
||||
for (size_t i = 0; i < paramCount; ++i)
|
||||
{
|
||||
const TVariable ¶m = *function.getParam(i);
|
||||
if (needsRenaming(param, true))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool needsRenaming(const TInterfaceBlock &interfaceBlock, bool recursive) const
|
||||
{
|
||||
return needsRenamingImpl(interfaceBlock) ||
|
||||
(recursive && needsRenaming(interfaceBlock.fields(), true));
|
||||
}
|
||||
|
||||
bool needsRenaming(const TStructure &structure, bool recursive) const
|
||||
{
|
||||
return needsRenamingImpl(structure) ||
|
||||
(recursive && needsRenaming(structure.fields(), true));
|
||||
}
|
||||
|
||||
bool needsRenaming(const TType &type, bool recursive) const
|
||||
{
|
||||
if (const TStructure *structure = type.getStruct())
|
||||
{
|
||||
return needsRenaming(*structure, recursive);
|
||||
}
|
||||
else if (const TInterfaceBlock *interfaceBlock = type.getInterfaceBlock())
|
||||
{
|
||||
return needsRenaming(*interfaceBlock, recursive);
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool needsRenaming(const TVariable &variable, bool recursive) const
|
||||
{
|
||||
return needsRenamingImpl(variable) ||
|
||||
(recursive && needsRenaming(variable.getType(), true));
|
||||
}
|
||||
|
||||
public:
|
||||
Rewriter(TCompiler &compiler, IdGen &idGen, const std::set<ImmutableString> &keywords)
|
||||
: TIntermRebuild(compiler, false, true), mKeywords(keywords), mIdGen(idGen)
|
||||
{}
|
||||
|
||||
PostResult visitSymbolPost(TIntermSymbol &symbolNode) override
|
||||
{
|
||||
const TVariable &var = symbolNode.variable();
|
||||
if (needsRenaming(var, true))
|
||||
{
|
||||
const TVariable &rVar = getRenamedOrOriginal(var);
|
||||
return *new TIntermSymbol(&rVar);
|
||||
}
|
||||
return symbolNode;
|
||||
}
|
||||
|
||||
PostResult visitFunctionPrototype(TIntermFunctionPrototype &funcProtoNode)
|
||||
{
|
||||
const TFunction &func = *funcProtoNode.getFunction();
|
||||
if (needsRenaming(func, true))
|
||||
{
|
||||
const TFunction &rFunc = getRenamedOrOriginal(func);
|
||||
return *new TIntermFunctionPrototype(&rFunc);
|
||||
}
|
||||
return funcProtoNode;
|
||||
}
|
||||
|
||||
PostResult visitDeclarationPost(TIntermDeclaration &declNode) override
|
||||
{
|
||||
Declaration decl = ViewDeclaration(declNode);
|
||||
const TVariable &var = decl.symbol.variable();
|
||||
if (needsRenaming(var, true))
|
||||
{
|
||||
const TVariable &rVar = getRenamedOrOriginal(var);
|
||||
return *new TIntermDeclaration(&rVar, decl.initExpr);
|
||||
}
|
||||
return declNode;
|
||||
}
|
||||
|
||||
PostResult visitFunctionDefinitionPost(TIntermFunctionDefinition &funcDefNode) override
|
||||
{
|
||||
TIntermFunctionPrototype &funcProtoNode = *funcDefNode.getFunctionPrototype();
|
||||
const TFunction &func = *funcProtoNode.getFunction();
|
||||
if (needsRenaming(func, true))
|
||||
{
|
||||
const TFunction &rFunc = getRenamedOrOriginal(func);
|
||||
auto *rFuncProtoNode = new TIntermFunctionPrototype(&rFunc);
|
||||
return *new TIntermFunctionDefinition(rFuncProtoNode, funcDefNode.getBody());
|
||||
}
|
||||
return funcDefNode;
|
||||
}
|
||||
|
||||
PostResult visitAggregatePost(TIntermAggregate &aggregateNode) override
|
||||
{
|
||||
if (aggregateNode.isConstructor())
|
||||
{
|
||||
const TType &type = aggregateNode.getType();
|
||||
if (needsRenaming(type, true))
|
||||
{
|
||||
const TType &rType = getRenamedOrOriginal(type);
|
||||
return TIntermAggregate::CreateConstructor(rType, aggregateNode.getSequence());
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
const TFunction &func = *aggregateNode.getFunction();
|
||||
if (needsRenaming(func, true))
|
||||
{
|
||||
const TFunction &rFunc = getRenamedOrOriginal(func);
|
||||
switch (aggregateNode.getOp())
|
||||
{
|
||||
case TOperator::EOpCallFunctionInAST:
|
||||
return TIntermAggregate::CreateFunctionCall(rFunc,
|
||||
aggregateNode.getSequence());
|
||||
|
||||
case TOperator::EOpCallInternalRawFunction:
|
||||
return TIntermAggregate::CreateRawFunctionCall(rFunc,
|
||||
aggregateNode.getSequence());
|
||||
|
||||
default:
|
||||
return TIntermAggregate::CreateBuiltInFunctionCall(
|
||||
rFunc, aggregateNode.getSequence());
|
||||
}
|
||||
}
|
||||
}
|
||||
return aggregateNode;
|
||||
}
|
||||
|
||||
void predefineName(const ImmutableString name, std::string prePopulatedName)
|
||||
{
|
||||
mPredefinedNames[name] = prePopulatedName;
|
||||
}
|
||||
};
|
||||
|
||||
} // anonymous namespace
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
bool sh::RewriteKeywords(TCompiler &compiler,
|
||||
TIntermBlock &root,
|
||||
IdGen &idGen,
|
||||
const std::set<ImmutableString> &keywords)
|
||||
{
|
||||
Rewriter rewriter(compiler, idGen, keywords);
|
||||
const auto &inputAttrs = compiler.getAttributes();
|
||||
for (const auto &var : inputAttrs)
|
||||
{
|
||||
rewriter.predefineName(ImmutableString(var.name), var.mappedName);
|
||||
}
|
||||
if (!rewriter.rebuildRoot(root))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
|
@ -1,27 +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_REWRITEKEYWORDS_H_
|
||||
#define COMPILER_TRANSLATOR_TRANSLATORMETALDIRECT_REWRITEKEYWORDS_H_
|
||||
|
||||
#include <set>
|
||||
|
||||
#include "common/angleutils.h"
|
||||
#include "compiler/translator/Compiler.h"
|
||||
#include "compiler/translator/TranslatorMetalDirect/IdGen.h"
|
||||
|
||||
namespace sh
|
||||
{
|
||||
|
||||
// This walks the tree and renames all names that conflict with the input `keywords`.
|
||||
ANGLE_NO_DISCARD bool RewriteKeywords(TCompiler &compiler,
|
||||
TIntermBlock &root,
|
||||
IdGen &idGen,
|
||||
const std::set<ImmutableString> &keywords);
|
||||
|
||||
} // namespace sh
|
||||
|
||||
#endif // COMPILER_TRANSLATOR_TRANSLATORMETALDIRECT_REWRITEKEYWORDS_H_
|
|
@ -389,13 +389,12 @@ const TStructure &SymbolEnv::getTextureEnv(TBasicType samplerType)
|
|||
if (env == nullptr)
|
||||
{
|
||||
auto *textureType = new TType(samplerType);
|
||||
auto *texture = new TField(textureType, ImmutableString("texture"), kNoSourceLoc,
|
||||
SymbolType::UserDefined);
|
||||
auto *texture =
|
||||
new TField(textureType, ImmutableString("texture"), kNoSourceLoc, SymbolType::BuiltIn);
|
||||
markAsPointer(*texture, AddressSpace::Thread);
|
||||
|
||||
auto *sampler =
|
||||
new TField(new TType(&getSamplerStruct(), false), ImmutableString("sampler"),
|
||||
kNoSourceLoc, SymbolType::UserDefined);
|
||||
auto *sampler = new TField(new TType(&getSamplerStruct(), false),
|
||||
ImmutableString("sampler"), kNoSourceLoc, SymbolType::BuiltIn);
|
||||
markAsPointer(*sampler, AddressSpace::Thread);
|
||||
|
||||
std::string envName;
|
||||
|
@ -414,7 +413,7 @@ const TStructure &SymbolEnv::getSamplerStruct()
|
|||
if (!mSampler)
|
||||
{
|
||||
mSampler = new TStructure(&mSymbolTable, ImmutableString("metal::sampler"),
|
||||
new TFieldList(), SymbolType::UserDefined);
|
||||
new TFieldList(), SymbolType::BuiltIn);
|
||||
}
|
||||
return *mSampler;
|
||||
}
|
||||
|
@ -698,5 +697,5 @@ Name sh::GetTextureTypeName(TBasicType samplerType)
|
|||
|
||||
#undef HANDLE_TEXTURE_NAME
|
||||
|
||||
return Name(name, SymbolType::UserDefined);
|
||||
return Name(name, SymbolType::BuiltIn);
|
||||
}
|
||||
|
|
|
@ -856,7 +856,7 @@ bool TranslatorVulkan::translateImpl(TInfoSinkBase &sink,
|
|||
// is inactive.
|
||||
if (!RemoveInactiveInterfaceVariables(this, root, &getSymbolTable(), getAttributes(),
|
||||
getInputVaryings(), getOutputVariables(), getUniforms(),
|
||||
getInterfaceBlocks()))
|
||||
getInterfaceBlocks(), true))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -29,7 +29,8 @@ class RemoveInactiveInterfaceVariablesTraverser : public TIntermTraverser
|
|||
const std::vector<sh::ShaderVariable> &inputVaryings,
|
||||
const std::vector<sh::ShaderVariable> &outputVariables,
|
||||
const std::vector<sh::ShaderVariable> &uniforms,
|
||||
const std::vector<sh::InterfaceBlock> &interfaceBlocks);
|
||||
const std::vector<sh::InterfaceBlock> &interfaceBlocks,
|
||||
bool removeFragmentOutputs);
|
||||
|
||||
bool visitDeclaration(Visit visit, TIntermDeclaration *node) override;
|
||||
bool visitBinary(Visit visit, TIntermBinary *node) override;
|
||||
|
@ -40,6 +41,7 @@ class RemoveInactiveInterfaceVariablesTraverser : public TIntermTraverser
|
|||
const std::vector<sh::ShaderVariable> &mOutputVariables;
|
||||
const std::vector<sh::ShaderVariable> &mUniforms;
|
||||
const std::vector<sh::InterfaceBlock> &mInterfaceBlocks;
|
||||
bool mRemoveFragmentOutputs;
|
||||
};
|
||||
|
||||
RemoveInactiveInterfaceVariablesTraverser::RemoveInactiveInterfaceVariablesTraverser(
|
||||
|
@ -48,13 +50,15 @@ RemoveInactiveInterfaceVariablesTraverser::RemoveInactiveInterfaceVariablesTrave
|
|||
const std::vector<sh::ShaderVariable> &inputVaryings,
|
||||
const std::vector<sh::ShaderVariable> &outputVariables,
|
||||
const std::vector<sh::ShaderVariable> &uniforms,
|
||||
const std::vector<sh::InterfaceBlock> &interfaceBlocks)
|
||||
const std::vector<sh::InterfaceBlock> &interfaceBlocks,
|
||||
bool removeFragmentOutputs)
|
||||
: TIntermTraverser(true, false, false, symbolTable),
|
||||
mAttributes(attributes),
|
||||
mInputVaryings(inputVaryings),
|
||||
mOutputVariables(outputVariables),
|
||||
mUniforms(uniforms),
|
||||
mInterfaceBlocks(interfaceBlocks)
|
||||
mInterfaceBlocks(interfaceBlocks),
|
||||
mRemoveFragmentOutputs(removeFragmentOutputs)
|
||||
{}
|
||||
|
||||
template <typename Variable>
|
||||
|
@ -126,7 +130,8 @@ bool RemoveInactiveInterfaceVariablesTraverser::visitDeclaration(Visit visit,
|
|||
}
|
||||
else if (qualifier == EvqFragmentOut)
|
||||
{
|
||||
removeDeclaration = !IsVariableActive(mOutputVariables, asSymbol->getName());
|
||||
removeDeclaration =
|
||||
!IsVariableActive(mOutputVariables, asSymbol->getName()) && mRemoveFragmentOutputs;
|
||||
}
|
||||
|
||||
if (removeDeclaration)
|
||||
|
@ -191,10 +196,12 @@ bool RemoveInactiveInterfaceVariables(TCompiler *compiler,
|
|||
const std::vector<sh::ShaderVariable> &inputVaryings,
|
||||
const std::vector<sh::ShaderVariable> &outputVariables,
|
||||
const std::vector<sh::ShaderVariable> &uniforms,
|
||||
const std::vector<sh::InterfaceBlock> &interfaceBlocks)
|
||||
const std::vector<sh::InterfaceBlock> &interfaceBlocks,
|
||||
bool removeFragmentOutputs)
|
||||
{
|
||||
RemoveInactiveInterfaceVariablesTraverser traverser(symbolTable, attributes, inputVaryings,
|
||||
outputVariables, uniforms, interfaceBlocks);
|
||||
outputVariables, uniforms, interfaceBlocks,
|
||||
removeFragmentOutputs);
|
||||
root->traverse(&traverser);
|
||||
return traverser.updateTree(compiler, root);
|
||||
}
|
||||
|
|
|
@ -34,7 +34,8 @@ ANGLE_NO_DISCARD bool RemoveInactiveInterfaceVariables(
|
|||
const std::vector<sh::ShaderVariable> &inputVaryings,
|
||||
const std::vector<sh::ShaderVariable> &outputVariables,
|
||||
const std::vector<sh::ShaderVariable> &uniforms,
|
||||
const std::vector<sh::InterfaceBlock> &interfaceBlocks);
|
||||
const std::vector<sh::InterfaceBlock> &interfaceBlocks,
|
||||
bool removeFragmentOutputs);
|
||||
|
||||
} // namespace sh
|
||||
|
||||
|
|
|
@ -16,8 +16,9 @@ namespace rx
|
|||
{
|
||||
namespace
|
||||
{
|
||||
constexpr char kXfbBindingsMarker[] = "@@XFB-Bindings@@";
|
||||
constexpr char kXfbOutMarker[] = "ANGLE_@@XFB-OUT@@";
|
||||
constexpr char kXfbBindingsMarker[] = "@@XFB-Bindings@@";
|
||||
constexpr char kXfbOutMarker[] = "ANGLE_@@XFB-OUT@@";
|
||||
constexpr char kUserDefinedNamePrefix[] = "_u"; // Defined in GLSLANG/ShaderLang.h
|
||||
|
||||
template <size_t N>
|
||||
constexpr size_t ConstStrLen(const char (&)[N])
|
||||
|
@ -172,27 +173,18 @@ std::string updateShaderAttributes(std::string shaderSourceIn, const gl::Program
|
|||
for (int i = 0; i < regs; i++)
|
||||
{
|
||||
stream.str("");
|
||||
stream << " " << attribute.name << "_" << std::to_string(i)
|
||||
<< sh::kUnassignedAttributeString;
|
||||
attributeBindings.insert({std::string(stream.str()), i + attribute.location});
|
||||
stream.str("");
|
||||
// Any renamed attributes are marked as UserDefined (see RewriteKeywords.cpp
|
||||
// Rewriter::createRenamed)
|
||||
stream << " " << attribute.mappedName << "_" << std::to_string(i)
|
||||
<< sh::kUnassignedAttributeString;
|
||||
stream << " " << kUserDefinedNamePrefix << attribute.name << "_"
|
||||
<< std::to_string(i) << sh::kUnassignedAttributeString;
|
||||
attributeBindings.insert({std::string(stream.str()), i + attribute.location});
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
stream.str("");
|
||||
stream << " " << attribute.name << sh::kUnassignedAttributeString;
|
||||
stream << " " << kUserDefinedNamePrefix << attribute.name
|
||||
<< sh::kUnassignedAttributeString;
|
||||
attributeBindings.insert({std::string(stream.str()), attribute.location});
|
||||
stream.str("");
|
||||
// Any renamed attributes are marked as UserDefined (see RewriteKeywords.cpp
|
||||
// Rewriter::createRenamed)
|
||||
stream << " " << attribute.mappedName << sh::kUnassignedAttributeString;
|
||||
attributeBindings.insert({std::string(stream.str()), attribute.location});
|
||||
}
|
||||
}
|
||||
// Rewrite attributes
|
||||
|
@ -276,7 +268,12 @@ std::string GenerateTransformFeedbackVaryingOutput(const gl::TransformFeedbackVa
|
|||
<< ".ANGLE_xfbVerticesPerInstance) * " << stride << " + " << offset << "] = "
|
||||
<< "as_type<float>"
|
||||
<< "("
|
||||
<< "ANGLE_vertexOut." << varying.name;
|
||||
<< "ANGLE_vertexOut.";
|
||||
if (!varying.isBuiltIn())
|
||||
{
|
||||
result << kUserDefinedNamePrefix;
|
||||
}
|
||||
result << varying.name;
|
||||
|
||||
if (varying.isArray())
|
||||
{
|
||||
|
|
|
@ -63,6 +63,10 @@ class Resource : angle::NonCopyable
|
|||
bool isCPUReadMemNeedSync() const { return mUsageRef->cpuReadMemNeedSync; }
|
||||
void resetCPUReadMemNeedSync() { mUsageRef->cpuReadMemNeedSync = false; }
|
||||
|
||||
bool isCPUReadMemSyncPending() const { return mUsageRef->cpuReadMemSyncPending; }
|
||||
void setCPUReadMemSyncPending(bool value) const { mUsageRef->cpuReadMemSyncPending = value; }
|
||||
void resetCPUReadMemSyncPending() { mUsageRef->cpuReadMemSyncPending = false; }
|
||||
|
||||
bool isCPUReadMemDirty() const { return mUsageRef->cpuReadMemDirty; }
|
||||
void resetCPUReadMemDirty() { mUsageRef->cpuReadMemDirty = false; }
|
||||
|
||||
|
@ -83,6 +87,11 @@ class Resource : angle::NonCopyable
|
|||
// its content, explicit synchronization call must be invoked.
|
||||
bool cpuReadMemNeedSync = false;
|
||||
|
||||
// This flag is set when synchronization for the resource has been
|
||||
// encoded on the GPU, and a map operation must wait
|
||||
// until it's completed.
|
||||
bool cpuReadMemSyncPending = false;
|
||||
|
||||
// This flag is useful for BufferMtl to know whether it should update the shadow copy
|
||||
bool cpuReadMemDirty = false;
|
||||
};
|
||||
|
|
|
@ -42,6 +42,7 @@ void InvokeCPUMemSync(ContextMtl *context, mtl::BlitCommandEncoder *blitEncoder,
|
|||
blitEncoder->synchronizeResource(resource);
|
||||
|
||||
resource->resetCPUReadMemNeedSync();
|
||||
resource->setCPUReadMemSyncPending(true);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
@ -59,6 +60,7 @@ void EnsureCPUMemWillBeSynced(ContextMtl *context, T *resource)
|
|||
InvokeCPUMemSync(context, blitEncoder, resource);
|
||||
}
|
||||
#endif
|
||||
resource->resetCPUReadMemNeedSync();
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
@ -76,6 +78,7 @@ void Resource::reset()
|
|||
mUsageRef->cmdBufferQueueSerial = 0;
|
||||
resetCPUReadMemDirty();
|
||||
resetCPUReadMemNeedSync();
|
||||
resetCPUReadMemSyncPending();
|
||||
}
|
||||
|
||||
bool Resource::isBeingUsedByGPU(Context *context) const
|
||||
|
@ -997,7 +1000,7 @@ uint8_t *Buffer::mapWithOpt(ContextMtl *context, bool readonly, bool noSync)
|
|||
{
|
||||
mMapReadOnly = readonly;
|
||||
|
||||
if (!noSync)
|
||||
if (!noSync && (isCPUReadMemSyncPending() || isCPUReadMemNeedSync() || !readonly))
|
||||
{
|
||||
CommandQueue &cmdQueue = context->cmdQueue();
|
||||
|
||||
|
@ -1009,6 +1012,7 @@ uint8_t *Buffer::mapWithOpt(ContextMtl *context, bool readonly, bool noSync)
|
|||
}
|
||||
|
||||
cmdQueue.ensureResourceReadyForCPU(this);
|
||||
resetCPUReadMemSyncPending();
|
||||
}
|
||||
|
||||
return reinterpret_cast<uint8_t *>([get() contents]);
|
||||
|
|
Загрузка…
Ссылка в новой задаче