diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-19 00:47:55 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-19 00:47:55 +0000 |
commit | 26a029d407be480d791972afb5975cf62c9360a6 (patch) | |
tree | f435a8308119effd964b339f76abb83a57c29483 /gfx/angle/checkout/src/compiler/translator/tree_ops/ClampIndirectIndices.cpp | |
parent | Initial commit. (diff) | |
download | firefox-26a029d407be480d791972afb5975cf62c9360a6.tar.xz firefox-26a029d407be480d791972afb5975cf62c9360a6.zip |
Adding upstream version 124.0.1.upstream/124.0.1
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to '')
-rw-r--r-- | gfx/angle/checkout/src/compiler/translator/tree_ops/ClampIndirectIndices.cpp | 136 |
1 files changed, 136 insertions, 0 deletions
diff --git a/gfx/angle/checkout/src/compiler/translator/tree_ops/ClampIndirectIndices.cpp b/gfx/angle/checkout/src/compiler/translator/tree_ops/ClampIndirectIndices.cpp new file mode 100644 index 0000000000..bd1997a21d --- /dev/null +++ b/gfx/angle/checkout/src/compiler/translator/tree_ops/ClampIndirectIndices.cpp @@ -0,0 +1,136 @@ +// +// Copyright 2021 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. +// +// ClampIndirectIndices.h: Add clamp to the indirect indices used on arrays. +// + +#include "compiler/translator/tree_ops/ClampIndirectIndices.h" + +#include "compiler/translator/Compiler.h" +#include "compiler/translator/StaticType.h" +#include "compiler/translator/SymbolTable.h" +#include "compiler/translator/tree_util/IntermNode_util.h" +#include "compiler/translator/tree_util/IntermTraverse.h" + +namespace sh +{ +namespace +{ +// Traverser that finds EOpIndexIndirect nodes and applies a clamp to their right-hand side +// expression. +class ClampIndirectIndicesTraverser : public TIntermTraverser +{ + public: + ClampIndirectIndicesTraverser(TCompiler *compiler, TSymbolTable *symbolTable) + : TIntermTraverser(true, false, false, symbolTable), mCompiler(compiler) + {} + + bool visitBinary(Visit visit, TIntermBinary *node) override + { + ASSERT(visit == PreVisit); + + // Only interested in EOpIndexIndirect nodes. + if (node->getOp() != EOpIndexIndirect) + { + return true; + } + + // Apply the transformation to the left and right nodes + bool valid = ClampIndirectIndices(mCompiler, node->getLeft(), mSymbolTable); + ASSERT(valid); + valid = ClampIndirectIndices(mCompiler, node->getRight(), mSymbolTable); + ASSERT(valid); + + // Generate clamp(right, 0, N), where N is the size of the array being indexed minus 1. If + // the array is runtime-sized, the length() method is called on it. + const TType &leftType = node->getLeft()->getType(); + const TType &rightType = node->getRight()->getType(); + + // Don't clamp indirect indices on unsized arrays in buffer blocks. They are covered by the + // relevant robust access behavior of the backend. + if (leftType.isUnsizedArray()) + { + return true; + } + + // On GLSL es 100, clamp is only defined for float, so float arguments are used. + // + // However, float clamp is unconditionally emitted to workaround driver bugs with integer + // clamp on Qualcomm. http://crbug.com/1217167 + // + // const bool useFloatClamp = mCompiler->getShaderVersion() == 100; + const bool useFloatClamp = true; + + TIntermConstantUnion *zero = createClampValue(0, useFloatClamp); + TIntermTyped *max; + + if (leftType.isArray()) + { + max = createClampValue(static_cast<int>(leftType.getOutermostArraySize()) - 1, + useFloatClamp); + } + else + { + ASSERT(leftType.isVector() || leftType.isMatrix()); + max = createClampValue(leftType.getNominalSize() - 1, useFloatClamp); + } + + TIntermTyped *index = node->getRight(); + // If the index node is not an int (i.e. it's a uint), or a float (if using float clamp), + // cast it. + const TBasicType requiredBasicType = useFloatClamp ? EbtFloat : EbtInt; + if (rightType.getBasicType() != requiredBasicType) + { + const TType *clampType = useFloatClamp ? StaticType::GetBasic<EbtFloat, EbpHigh>() + : StaticType::GetBasic<EbtInt, EbpHigh>(); + TIntermSequence constructorArgs = {index}; + index = TIntermAggregate::CreateConstructor(*clampType, &constructorArgs); + } + + // min(gl_PointSize, maxPointSize) + TIntermSequence args; + args.push_back(index); + args.push_back(zero); + args.push_back(max); + TIntermTyped *clamped = + CreateBuiltInFunctionCallNode("clamp", &args, *mSymbolTable, useFloatClamp ? 100 : 300); + + // Cast back to int if float clamp was used. + if (useFloatClamp) + { + TIntermSequence constructorArgs = {clamped}; + clamped = TIntermAggregate::CreateConstructor(*StaticType::GetBasic<EbtInt, EbpHigh>(), + &constructorArgs); + } + + // Replace the right node (the index) with the clamped result. + queueReplacementWithParent(node, node->getRight(), clamped, OriginalNode::IS_DROPPED); + + // Don't recurse as left and right nodes are already processed. + return false; + } + + private: + TIntermConstantUnion *createClampValue(int value, bool useFloat) + { + if (useFloat) + { + return CreateFloatNode(static_cast<float>(value), EbpHigh); + } + return CreateIndexNode(value); + } + + TCompiler *mCompiler; +}; +} // anonymous namespace + +bool ClampIndirectIndices(TCompiler *compiler, TIntermNode *root, TSymbolTable *symbolTable) +{ + ClampIndirectIndicesTraverser traverser(compiler, symbolTable); + root->traverse(&traverser); + return traverser.updateTree(compiler, root); +} + +} // namespace sh |