zenilib  0.5.3.0
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
ArrayBoundsClamper.cpp
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2012 Apple Inc. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  * 1. Redistributions of source code must retain the above copyright
8  * notice, this list of conditions and the following disclaimer.
9  * 2. Redistributions in binary form must reproduce the above copyright
10  * notice, this list of conditions and the following disclaimer in the
11  * documentation and/or other materials provided with the distribution.
12  *
13  * THIS SOFTWARE IS PROVIDED BY APPLE, INC. ``AS IS'' AND ANY
14  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE, INC. OR
17  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24  */
25 
27 
28 // The built-in 'clamp' instruction only accepts floats and returns a float. I
29 // iterated a few times with our driver team who examined the output from our
30 // compiler - they said the multiple casts generates more code than a single
31 // function call. An inline ternary operator might have been better, but since
32 // the index value might be an expression itself, we'd have to make temporary
33 // variables to avoid evaluating the expression multiple times. And making
34 // temporary variables was difficult because ANGLE would then need to make more
35 // brutal changes to the expression tree.
36 
37 const char* kIntClampBegin = "// BEGIN: Generated code for array bounds clamping\n\n";
38 const char* kIntClampEnd = "// END: Generated code for array bounds clamping\n\n";
39 const char* kIntClampDefinition = "int webgl_int_clamp(int value, int minValue, int maxValue) { return ((value < minValue) ? minValue : ((value > maxValue) ? maxValue : value)); }\n\n";
40 
41 namespace {
42 
43 class ArrayBoundsClamperMarker : public TIntermTraverser {
44 public:
45  ArrayBoundsClamperMarker()
46  : mNeedsClamp(false)
47  {
48  }
49 
50  virtual bool visitBinary(Visit visit, TIntermBinary* node)
51  {
52  if (node->getOp() == EOpIndexIndirect)
53  {
54  TIntermTyped* left = node->getLeft();
55  if (left->isArray() || left->isVector() || left->isMatrix())
56  {
57  node->setAddIndexClamp();
58  mNeedsClamp = true;
59  }
60  }
61  return true;
62  }
63 
64  bool GetNeedsClamp() { return mNeedsClamp; }
65 
66 private:
67  bool mNeedsClamp;
68 };
69 
70 } // anonymous namespace
71 
73  : mClampingStrategy(SH_CLAMP_WITH_CLAMP_INTRINSIC)
74  , mArrayBoundsClampDefinitionNeeded(false)
75 {
76 }
77 
79 {
80  mClampingStrategy = clampingStrategy;
81 }
82 
84 {
85  ASSERT(root);
86 
87  ArrayBoundsClamperMarker clamper;
88  root->traverse(&clamper);
89  if (clamper.GetNeedsClamp())
90  {
91  SetArrayBoundsClampDefinitionNeeded();
92  }
93 }
94 
96 {
97  if (!mArrayBoundsClampDefinitionNeeded)
98  {
99  return;
100  }
101  if (mClampingStrategy != SH_CLAMP_WITH_USER_DEFINED_INT_CLAMP_FUNCTION)
102  {
103  return;
104  }
106 }
void MarkIndirectArrayBoundsForClamping(TIntermNode *root)
const char * kIntClampBegin
Visit
Definition: intermediate.h:524
TOperator getOp() const
Definition: intermediate.h:389
GLint left
Definition: glew.h:7291
const char * kIntClampDefinition
TIntermTyped * getLeft() const
Definition: intermediate.h:413
void SetClampingStrategy(ShArrayIndexClampingStrategy clampingStrategy)
bool isMatrix() const
Definition: intermediate.h:259
ShArrayIndexClampingStrategy
Definition: ShaderLang.h:175
bool isVector() const
Definition: intermediate.h:261
const char * kIntClampEnd
#define ASSERT(expression)
Definition: debug.h:36
virtual bool visitBinary(Visit visit, TIntermBinary *)
Definition: intermediate.h:554
virtual void traverse(TIntermTraverser *)=0
void OutputClampingFunctionDefinition(TInfoSinkBase &out) const
void setAddIndexClamp()
Definition: intermediate.h:417
bool isArray() const
Definition: intermediate.h:260
#define false
Definition: ftrandom.c:50