Hash :
91976352
Author :
Date :
2022-06-21T15:41:02
Use C++17 attributes instead of custom macros Bug: angleproject:6747 Change-Id: Iad6c7cd8a18d028e01da49b647c5d01af11e0522 Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/3718999 Reviewed-by: Cody Northrop <cnorthrop@google.com> Commit-Queue: Shahbaz Youssefi <syoussefi@chromium.org> Reviewed-by: 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 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198
//
// 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.
//
// RewriteSampleMaskVariable.cpp: Find any references to gl_SampleMask and gl_SampleMaskIn, and
// rewrite it with ANGLESampleMask or ANGLESampleMaskIn.
//
#include "compiler/translator/tree_util/RewriteSampleMaskVariable.h"
#include "common/bitset_utils.h"
#include "common/debug.h"
#include "common/utilities.h"
#include "compiler/translator/Compiler.h"
#include "compiler/translator/SymbolTable.h"
#include "compiler/translator/tree_util/BuiltIn.h"
#include "compiler/translator/tree_util/IntermNode_util.h"
#include "compiler/translator/tree_util/IntermTraverse.h"
#include "compiler/translator/tree_util/RunAtTheEndOfShader.h"
namespace sh
{
namespace
{
constexpr int kMaxIndexForSampleMaskVar = 0;
constexpr int kFullSampleMask = 0xFFFFFFFF;
// Traverse the tree and collect the redeclaration and replace all non constant index references of
// gl_SampleMask or gl_SampleMaskIn with constant index references
class GLSampleMaskRelatedReferenceTraverser : public TIntermTraverser
{
public:
GLSampleMaskRelatedReferenceTraverser(const TIntermSymbol **redeclaredSymOut,
const ImmutableString &targetStr)
: TIntermTraverser(true, false, false),
mRedeclaredSym(redeclaredSymOut),
mTargetStr(targetStr)
{
*mRedeclaredSym = nullptr;
}
bool visitDeclaration(Visit visit, TIntermDeclaration *node) override
{
// If gl_SampleMask is redeclared, we need to collect its information
const TIntermSequence &sequence = *(node->getSequence());
if (sequence.size() != 1)
{
return true;
}
TIntermTyped *variable = sequence.front()->getAsTyped();
TIntermSymbol *symbol = variable->getAsSymbolNode();
if (symbol == nullptr || symbol->getName() != mTargetStr)
{
return true;
}
*mRedeclaredSym = symbol;
return true;
}
bool visitBinary(Visit visit, TIntermBinary *node) override
{
TOperator op = node->getOp();
if (op != EOpIndexDirect && op != EOpIndexIndirect)
{
return true;
}
TIntermSymbol *left = node->getLeft()->getAsSymbolNode();
if (!left)
{
return true;
}
if (left->getName() != mTargetStr)
{
return true;
}
const TConstantUnion *constIdx = node->getRight()->getConstantValue();
if (!constIdx)
{
if (node->getRight()->hasSideEffects())
{
insertStatementInParentBlock(node->getRight());
}
queueReplacementWithParent(node, node->getRight(),
CreateIndexNode(kMaxIndexForSampleMaskVar),
OriginalNode::IS_DROPPED);
}
return true;
}
private:
const TIntermSymbol **mRedeclaredSym;
const ImmutableString mTargetStr;
};
} // anonymous namespace
[[nodiscard]] bool RewriteSampleMask(TCompiler *compiler,
TIntermBlock *root,
TSymbolTable *symbolTable,
const TIntermTyped *numSamplesUniform)
{
const TIntermSymbol *redeclaredGLSampleMask = nullptr;
GLSampleMaskRelatedReferenceTraverser indexTraverser(&redeclaredGLSampleMask,
ImmutableString("gl_SampleMask"));
root->traverse(&indexTraverser);
if (!indexTraverser.updateTree(compiler, root))
{
return false;
}
// Retrieve gl_SampleMask variable reference
// Search user redeclared it first
const TVariable *glSampleMaskVar = nullptr;
if (redeclaredGLSampleMask)
{
glSampleMaskVar = &redeclaredGLSampleMask->variable();
}
else
{
// User defined not found, find in built-in table
glSampleMaskVar = static_cast<const TVariable *>(symbolTable->findBuiltIn(
ImmutableString("gl_SampleMask"), compiler->getShaderVersion()));
}
if (!glSampleMaskVar)
{
return false;
}
// Current ANGLE assumes that the maximum number of samples is less than or equal to
// VK_SAMPLE_COUNT_32_BIT. So, the size of gl_SampleMask array is always one.
const unsigned int arraySizeOfSampleMask = glSampleMaskVar->getType().getOutermostArraySize();
ASSERT(arraySizeOfSampleMask == 1);
TIntermSymbol *glSampleMaskSymbol = new TIntermSymbol(glSampleMaskVar);
// if (ANGLEUniforms.numSamples == 1)
// {
// gl_SampleMask[0] = int(0xFFFFFFFF);
// }
TIntermConstantUnion *singleSampleCount = CreateUIntNode(1);
TIntermBinary *equalTo =
new TIntermBinary(EOpEqual, numSamplesUniform->deepCopy(), singleSampleCount);
TIntermBlock *trueBlock = new TIntermBlock();
TIntermBinary *sampleMaskVar = new TIntermBinary(EOpIndexDirect, glSampleMaskSymbol->deepCopy(),
CreateIndexNode(kMaxIndexForSampleMaskVar));
TIntermConstantUnion *fullSampleMask = CreateIndexNode(kFullSampleMask);
TIntermBinary *assignment = new TIntermBinary(EOpAssign, sampleMaskVar, fullSampleMask);
trueBlock->appendStatement(assignment);
TIntermIfElse *multiSampleOrNot = new TIntermIfElse(equalTo, trueBlock, nullptr);
return RunAtTheEndOfShader(compiler, root, multiSampleOrNot, symbolTable);
}
[[nodiscard]] bool RewriteSampleMaskIn(TCompiler *compiler,
TIntermBlock *root,
TSymbolTable *symbolTable)
{
const TIntermSymbol *redeclaredGLSampleMaskIn = nullptr;
GLSampleMaskRelatedReferenceTraverser indexTraverser(&redeclaredGLSampleMaskIn,
ImmutableString("gl_SampleMaskIn"));
root->traverse(&indexTraverser);
if (!indexTraverser.updateTree(compiler, root))
{
return false;
}
// Retrieve gl_SampleMaskIn variable reference
const TVariable *glSampleMaskInVar = nullptr;
glSampleMaskInVar = static_cast<const TVariable *>(
symbolTable->findBuiltIn(ImmutableString("gl_SampleMaskIn"), compiler->getShaderVersion()));
if (!glSampleMaskInVar)
{
return false;
}
// Current ANGLE assumes that the maximum number of samples is less than or equal to
// VK_SAMPLE_COUNT_32_BIT. So, the size of gl_SampleMask array is always one.
const unsigned int arraySizeOfSampleMaskIn =
glSampleMaskInVar->getType().getOutermostArraySize();
ASSERT(arraySizeOfSampleMaskIn == 1);
return true;
}
} // namespace sh