| // | |
| // 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/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 = new TIntermSequence(); | |
| 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 |