// // 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