Wed, 31 Dec 2014 06:09:35 +0100
Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.
1 //
2 // Copyright (c) 2012 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 // Contains analysis utilities for dealing with HLSL's lack of support for
7 // the use of intrinsic functions which (implicitly or explicitly) compute
8 // gradients of functions with discontinuities.
9 //
11 #include "compiler/DetectDiscontinuity.h"
13 #include "compiler/ParseHelper.h"
15 namespace sh
16 {
17 bool DetectLoopDiscontinuity::traverse(TIntermNode *node)
18 {
19 mLoopDepth = 0;
20 mLoopDiscontinuity = false;
21 node->traverse(this);
22 return mLoopDiscontinuity;
23 }
25 bool DetectLoopDiscontinuity::visitLoop(Visit visit, TIntermLoop *loop)
26 {
27 if (visit == PreVisit)
28 {
29 ++mLoopDepth;
30 }
31 else if (visit == PostVisit)
32 {
33 --mLoopDepth;
34 }
36 return true;
37 }
39 bool DetectLoopDiscontinuity::visitBranch(Visit visit, TIntermBranch *node)
40 {
41 if (mLoopDiscontinuity)
42 {
43 return false;
44 }
46 if (!mLoopDepth)
47 {
48 return true;
49 }
51 switch (node->getFlowOp())
52 {
53 case EOpKill:
54 break;
55 case EOpBreak:
56 case EOpContinue:
57 case EOpReturn:
58 mLoopDiscontinuity = true;
59 break;
60 default: UNREACHABLE();
61 }
63 return !mLoopDiscontinuity;
64 }
66 bool DetectLoopDiscontinuity::visitAggregate(Visit visit, TIntermAggregate *node)
67 {
68 return !mLoopDiscontinuity;
69 }
71 bool containsLoopDiscontinuity(TIntermNode *node)
72 {
73 DetectLoopDiscontinuity detectLoopDiscontinuity;
74 return detectLoopDiscontinuity.traverse(node);
75 }
77 bool DetectGradientOperation::traverse(TIntermNode *node)
78 {
79 mGradientOperation = false;
80 node->traverse(this);
81 return mGradientOperation;
82 }
84 bool DetectGradientOperation::visitUnary(Visit visit, TIntermUnary *node)
85 {
86 if (mGradientOperation)
87 {
88 return false;
89 }
91 switch (node->getOp())
92 {
93 case EOpDFdx:
94 case EOpDFdy:
95 mGradientOperation = true;
96 default:
97 break;
98 }
100 return !mGradientOperation;
101 }
103 bool DetectGradientOperation::visitAggregate(Visit visit, TIntermAggregate *node)
104 {
105 if (mGradientOperation)
106 {
107 return false;
108 }
110 if (node->getOp() == EOpFunctionCall)
111 {
112 if (!node->isUserDefined())
113 {
114 TString name = TFunction::unmangleName(node->getName());
116 if (name == "texture2D" ||
117 name == "texture2DProj" ||
118 name == "textureCube")
119 {
120 mGradientOperation = true;
121 }
122 }
123 else
124 {
125 // When a user defined function is called, we have to
126 // conservatively assume it to contain gradient operations
127 mGradientOperation = true;
128 }
129 }
131 return !mGradientOperation;
132 }
134 bool containsGradientOperation(TIntermNode *node)
135 {
136 DetectGradientOperation detectGradientOperation;
137 return detectGradientOperation.traverse(node);
138 }
139 }