1 | // |
2 | // Copyright (c) 2017 The ANGLE Project Authors. All rights reserved. |
3 | // Use of this source code is governed by a BSD-style license that can be |
4 | // found in the LICENSE file. |
5 | // |
6 | // ClampFragDepth.cpp: Limit the value that is written to gl_FragDepth to the range [0.0, 1.0]. |
7 | // The clamping is run at the very end of shader execution, and is only performed if the shader |
8 | // statically accesses gl_FragDepth. |
9 | // |
10 | |
11 | #include "compiler/translator/tree_ops/ClampFragDepth.h" |
12 | |
13 | #include "compiler/translator/ImmutableString.h" |
14 | #include "compiler/translator/SymbolTable.h" |
15 | #include "compiler/translator/tree_util/BuiltIn_autogen.h" |
16 | #include "compiler/translator/tree_util/FindSymbolNode.h" |
17 | #include "compiler/translator/tree_util/IntermNode_util.h" |
18 | #include "compiler/translator/tree_util/RunAtTheEndOfShader.h" |
19 | |
20 | namespace sh |
21 | { |
22 | |
23 | void ClampFragDepth(TIntermBlock *root, TSymbolTable *symbolTable) |
24 | { |
25 | // Only clamp gl_FragDepth if it's used in the shader. |
26 | if (!FindSymbolNode(root, ImmutableString("gl_FragDepth" ))) |
27 | { |
28 | return; |
29 | } |
30 | |
31 | TIntermSymbol *fragDepthNode = new TIntermSymbol(BuiltInVariable::gl_FragDepth()); |
32 | |
33 | TIntermTyped *minFragDepthNode = CreateZeroNode(TType(EbtFloat, EbpHigh, EvqConst)); |
34 | |
35 | TConstantUnion *maxFragDepthConstant = new TConstantUnion(); |
36 | maxFragDepthConstant->setFConst(1.0); |
37 | TIntermConstantUnion *maxFragDepthNode = |
38 | new TIntermConstantUnion(maxFragDepthConstant, TType(EbtFloat, EbpHigh, EvqConst)); |
39 | |
40 | // clamp(gl_FragDepth, 0.0, 1.0) |
41 | TIntermSequence *clampArguments = new TIntermSequence(); |
42 | clampArguments->push_back(fragDepthNode->deepCopy()); |
43 | clampArguments->push_back(minFragDepthNode); |
44 | clampArguments->push_back(maxFragDepthNode); |
45 | TIntermTyped *clampedFragDepth = |
46 | CreateBuiltInFunctionCallNode("clamp" , clampArguments, *symbolTable, 100); |
47 | |
48 | // gl_FragDepth = clamp(gl_FragDepth, 0.0, 1.0) |
49 | TIntermBinary *assignFragDepth = new TIntermBinary(EOpAssign, fragDepthNode, clampedFragDepth); |
50 | |
51 | RunAtTheEndOfShader(root, assignFragDepth, symbolTable); |
52 | } |
53 | |
54 | } // namespace sh |
55 | |