Hash :
f0286e63
Author :
Date :
2021-01-19T12:38:46
Translator: Stop allocating TIntermSequence The functions that take a TIntermSequence always copy out / Swap the contents away. This change makes all TIntermSequences live on the stack instead of being newed. Bug: angleproject:5535 Change-Id: I942f1c5e57b00199d5308183f71bd9e18b0608bd Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/2636679 Reviewed-by: Jamie Madill <jmadill@chromium.org> Reviewed-by: Tim Van Patten <timvp@google.com> Commit-Queue: Shahbaz Youssefi <syoussefi@chromium.org>
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159
//
// 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.
//
// Implementation of InterpolateAtOffset viewport transformation.
// See header for more info.
#include "compiler/translator/tree_ops/vulkan/RewriteInterpolateAtOffset.h"
#include "common/angleutils.h"
#include "compiler/translator/StaticType.h"
#include "compiler/translator/SymbolTable.h"
#include "compiler/translator/TranslatorVulkan.h"
#include "compiler/translator/tree_util/DriverUniform.h"
#include "compiler/translator/tree_util/IntermNode_util.h"
#include "compiler/translator/tree_util/IntermTraverse.h"
#include "compiler/translator/tree_util/SpecializationConstant.h"
namespace sh
{
namespace
{
class Traverser : public TIntermTraverser
{
public:
ANGLE_NO_DISCARD static bool Apply(TCompiler *compiler,
ShCompileOptions compileOptions,
TIntermNode *root,
const TSymbolTable &symbolTable,
int ShaderVersion,
SpecConst *specConst,
const DriverUniform *driverUniforms);
private:
Traverser(TSymbolTable *symbolTable,
ShCompileOptions compileOptions,
int shaderVersion,
SpecConst *specConst,
const DriverUniform *driverUniforms);
bool visitAggregate(Visit visit, TIntermAggregate *node) override;
const TSymbolTable *symbolTable = nullptr;
const int shaderVersion;
SpecConst *mRotationSpecConst = nullptr;
const DriverUniform *mDriverUniforms = nullptr;
bool mUsePreRotation = false;
};
Traverser::Traverser(TSymbolTable *symbolTable,
ShCompileOptions compileOptions,
int shaderVersion,
SpecConst *specConst,
const DriverUniform *driverUniforms)
: TIntermTraverser(true, false, false, symbolTable),
symbolTable(symbolTable),
shaderVersion(shaderVersion),
mRotationSpecConst(specConst),
mDriverUniforms(driverUniforms),
mUsePreRotation((compileOptions & SH_ADD_PRE_ROTATION) != 0)
{}
// static
bool Traverser::Apply(TCompiler *compiler,
ShCompileOptions compileOptions,
TIntermNode *root,
const TSymbolTable &symbolTable,
int shaderVersion,
SpecConst *specConst,
const DriverUniform *driverUniforms)
{
TSymbolTable *pSymbolTable = const_cast<TSymbolTable *>(&symbolTable);
Traverser traverser(pSymbolTable, compileOptions, shaderVersion, specConst, driverUniforms);
root->traverse(&traverser);
return traverser.updateTree(compiler, root);
}
bool Traverser::visitAggregate(Visit visit, TIntermAggregate *node)
{
// Decide if the node represents the call of texelFetchOffset.
if (node->getOp() != EOpCallBuiltInFunction)
{
return true;
}
ASSERT(node->getFunction()->symbolType() == SymbolType::BuiltIn);
if (node->getFunction()->name() != "interpolateAtOffset")
{
return true;
}
const TIntermSequence *sequence = node->getSequence();
ASSERT(sequence->size() == 2u);
TIntermSequence interpolateAtOffsetArguments;
// interpolant node
interpolateAtOffsetArguments.push_back(sequence->at(0));
// offset
TIntermTyped *offsetNode = sequence->at(1)->getAsTyped();
ASSERT(offsetNode->getType() == *(StaticType::GetBasic<EbtFloat, 2>()));
// If pre-rotation is enabled apply the transformation else just flip the Y-coordinate
TIntermTyped *rotatedXY;
if (mUsePreRotation)
{
rotatedXY = mRotationSpecConst->getFragRotationMultiplyFlipXY();
if (!rotatedXY)
{
TIntermTyped *flipXY = mDriverUniforms->getFlipXYRef();
TIntermTyped *fragRotation = mDriverUniforms->getFragRotationMatrixRef();
rotatedXY = new TIntermBinary(EOpMatrixTimesVector, fragRotation, flipXY);
}
}
else
{
rotatedXY = mRotationSpecConst->getFlipXY();
if (!rotatedXY)
{
rotatedXY = mDriverUniforms->getFlipXYRef();
}
}
TIntermBinary *correctedOffset = new TIntermBinary(EOpMul, offsetNode, rotatedXY);
correctedOffset->setLine(offsetNode->getLine());
interpolateAtOffsetArguments.push_back(correctedOffset);
TIntermTyped *interpolateAtOffsetNode = CreateBuiltInFunctionCallNode(
"interpolateAtOffset", &interpolateAtOffsetArguments, *symbolTable, shaderVersion);
interpolateAtOffsetNode->setLine(node->getLine());
// Replace the old node by this new node.
queueReplacement(interpolateAtOffsetNode, OriginalNode::IS_DROPPED);
return true;
}
} // anonymous namespace
bool RewriteInterpolateAtOffset(TCompiler *compiler,
ShCompileOptions compileOptions,
TIntermNode *root,
const TSymbolTable &symbolTable,
int shaderVersion,
SpecConst *specConst,
const DriverUniform *driverUniforms)
{
// interpolateAtOffset is only valid in GLSL 3.0 and later.
if (shaderVersion < 300)
{
return true;
}
return Traverser::Apply(compiler, compileOptions, root, symbolTable, shaderVersion, specConst,
driverUniforms);
}
} // namespace sh