diff options
Diffstat (limited to 'gfx/angle/checkout/src/compiler/translator/tree_ops/gl/ClampFragDepth.cpp')
-rw-r--r-- | gfx/angle/checkout/src/compiler/translator/tree_ops/gl/ClampFragDepth.cpp | 54 |
1 files changed, 54 insertions, 0 deletions
diff --git a/gfx/angle/checkout/src/compiler/translator/tree_ops/gl/ClampFragDepth.cpp b/gfx/angle/checkout/src/compiler/translator/tree_ops/gl/ClampFragDepth.cpp new file mode 100644 index 0000000000..309cb14752 --- /dev/null +++ b/gfx/angle/checkout/src/compiler/translator/tree_ops/gl/ClampFragDepth.cpp @@ -0,0 +1,54 @@ +// +// Copyright 2017 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. +// +// ClampFragDepth.cpp: Limit the value that is written to gl_FragDepth to the range [0.0, 1.0]. +// The clamping is run at the very end of shader execution, and is only performed if the shader +// statically accesses gl_FragDepth. +// + +#include "compiler/translator/tree_ops/gl/ClampFragDepth.h" + +#include "compiler/translator/ImmutableString.h" +#include "compiler/translator/SymbolTable.h" +#include "compiler/translator/tree_util/BuiltIn.h" +#include "compiler/translator/tree_util/FindSymbolNode.h" +#include "compiler/translator/tree_util/IntermNode_util.h" +#include "compiler/translator/tree_util/RunAtTheEndOfShader.h" + +namespace sh +{ + +bool ClampFragDepth(TCompiler *compiler, TIntermBlock *root, TSymbolTable *symbolTable) +{ + // Only clamp gl_FragDepth if it's used in the shader. + if (!FindSymbolNode(root, ImmutableString("gl_FragDepth"))) + { + return true; + } + + TIntermSymbol *fragDepthNode = new TIntermSymbol(BuiltInVariable::gl_FragDepth()); + + TIntermTyped *minFragDepthNode = CreateZeroNode(TType(EbtFloat, EbpHigh, EvqConst)); + + TConstantUnion *maxFragDepthConstant = new TConstantUnion(); + maxFragDepthConstant->setFConst(1.0); + TIntermConstantUnion *maxFragDepthNode = + new TIntermConstantUnion(maxFragDepthConstant, TType(EbtFloat, EbpHigh, EvqConst)); + + // clamp(gl_FragDepth, 0.0, 1.0) + TIntermSequence clampArguments; + clampArguments.push_back(fragDepthNode->deepCopy()); + clampArguments.push_back(minFragDepthNode); + clampArguments.push_back(maxFragDepthNode); + TIntermTyped *clampedFragDepth = + CreateBuiltInFunctionCallNode("clamp", &clampArguments, *symbolTable, 100); + + // gl_FragDepth = clamp(gl_FragDepth, 0.0, 1.0) + TIntermBinary *assignFragDepth = new TIntermBinary(EOpAssign, fragDepthNode, clampedFragDepth); + + return RunAtTheEndOfShader(compiler, root, assignFragDepth, symbolTable); +} + +} // namespace sh |