zenilib  0.5.3.0
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
RestrictFragmentShaderTiming.cpp
Go to the documentation of this file.
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 
7 #include "compiler/InfoSink.h"
8 #include "compiler/ParseHelper.h"
11 
13  : mSink(sink)
14  , mNumErrors(0)
15 {
16  // Sampling ops found only in fragment shaders.
17  mSamplingOps.insert("texture2D(s21;vf2;f1;");
18  mSamplingOps.insert("texture2DProj(s21;vf3;f1;");
19  mSamplingOps.insert("texture2DProj(s21;vf4;f1;");
20  mSamplingOps.insert("textureCube(sC1;vf3;f1;");
21  // Sampling ops found in both vertex and fragment shaders.
22  mSamplingOps.insert("texture2D(s21;vf2;");
23  mSamplingOps.insert("texture2DProj(s21;vf3;");
24  mSamplingOps.insert("texture2DProj(s21;vf4;");
25  mSamplingOps.insert("textureCube(sC1;vf3;");
26  // Sampling ops provided by OES_EGL_image_external.
27  mSamplingOps.insert("texture2D(1;vf2;");
28  mSamplingOps.insert("texture2DProj(1;vf3;");
29  mSamplingOps.insert("texture2DProj(1;vf4;");
30  // Sampling ops provided by ARB_texture_rectangle.
31  mSamplingOps.insert("texture2DRect(1;vf2;");
32  mSamplingOps.insert("texture2DRectProj(1;vf3;");
33  mSamplingOps.insert("texture2DRectProj(1;vf4;");
34 }
35 
36 // FIXME(mvujovic): We do not know if the execution time of built-in operations like sin, pow, etc.
37 // can vary based on the value of the input arguments. If so, we should restrict those as well.
39 {
40  mNumErrors = 0;
41 
42  // FIXME(mvujovic): The dependency graph does not support user defined function calls right now,
43  // so we generate errors for them.
44  validateUserDefinedFunctionCallUsage(graph);
45 
46  // Starting from each sampler, traverse the dependency graph and generate an error each time we
47  // hit a node where sampler dependent values are not allowed.
48  for (TGraphSymbolVector::const_iterator iter = graph.beginSamplerSymbols();
49  iter != graph.endSamplerSymbols();
50  ++iter)
51  {
52  TGraphSymbol* samplerSymbol = *iter;
53  clearVisited();
54  samplerSymbol->traverse(this);
55  }
56 }
57 
58 void RestrictFragmentShaderTiming::validateUserDefinedFunctionCallUsage(const TDependencyGraph& graph)
59 {
60  for (TFunctionCallVector::const_iterator iter = graph.beginUserDefinedFunctionCalls();
61  iter != graph.endUserDefinedFunctionCalls();
62  ++iter)
63  {
64  TGraphFunctionCall* functionCall = *iter;
65  beginError(functionCall->getIntermFunctionCall());
66  mSink << "A call to a user defined function is not permitted.\n";
67  }
68 }
69 
70 void RestrictFragmentShaderTiming::beginError(const TIntermNode* node)
71 {
72  ++mNumErrors;
73  mSink.prefix(EPrefixError);
74  mSink.location(node->getLine());
75 }
76 
77 bool RestrictFragmentShaderTiming::isSamplingOp(const TIntermAggregate* intermFunctionCall) const
78 {
79  return !intermFunctionCall->isUserDefined() &&
80  mSamplingOps.find(intermFunctionCall->getName()) != mSamplingOps.end();
81 }
82 
84 {
85  // Texture cache access time might leak sensitive information.
86  // Thus, we restrict sampler dependent values from affecting the coordinate or LOD bias of a
87  // sampling operation.
88  if (isSamplingOp(parameter->getIntermFunctionCall())) {
89  switch (parameter->getArgumentNumber()) {
90  case 1:
91  // Second argument (coord)
92  beginError(parameter->getIntermFunctionCall());
93  mSink << "An expression dependent on a sampler is not permitted to be the"
94  << " coordinate argument of a sampling operation.\n";
95  break;
96  case 2:
97  // Third argument (bias)
98  beginError(parameter->getIntermFunctionCall());
99  mSink << "An expression dependent on a sampler is not permitted to be the"
100  << " bias argument of a sampling operation.\n";
101  break;
102  default:
103  // First argument (sampler)
104  break;
105  }
106  }
107 }
108 
110 {
111  beginError(selection->getIntermSelection());
112  mSink << "An expression dependent on a sampler is not permitted in a conditional statement.\n";
113 }
114 
116 {
117  beginError(loop->getIntermLoop());
118  mSink << "An expression dependent on a sampler is not permitted in a loop condition.\n";
119 }
120 
122 {
123  beginError(logicalOp->getIntermLogicalOp());
124  mSink << "An expression dependent on a sampler is not permitted on the left hand side of a logical "
125  << logicalOp->getOpString()
126  << " operator.\n";
127 }
bool isUserDefined() const
Definition: intermediate.h:475
GLsizei GLenum GLboolean sink
Definition: glew.h:4448
const TIntermSelection * getIntermSelection() const
TFunctionCallVector::const_iterator endUserDefinedFunctionCalls() const
const TIntermLoop * getIntermLoop() const
int getArgumentNumber() const
const TIntermAggregate * getIntermFunctionCall() const
virtual void traverse(TDependencyGraphTraverser *graphTraverser)
const TSourceLoc & getLine() const
Definition: intermediate.h:217
const TString & getName() const
Definition: intermediate.h:472
TGraphSymbolVector::const_iterator endSamplerSymbols() const
virtual void visitSelection(TGraphSelection *selection)
virtual void visitLogicalOp(TGraphLogicalOp *logicalOp)
virtual void visitArgument(TGraphArgument *parameter)
TGraphSymbolVector::const_iterator beginSamplerSymbols() const
const TIntermBinary * getIntermLogicalOp() const
const TIntermAggregate * getIntermFunctionCall() const
virtual void visitLoop(TGraphLoop *loop)
const char * getOpString() const
TFunctionCallVector::const_iterator beginUserDefinedFunctionCalls() const
void location(int file, int line)
Definition: InfoSink.cpp:34
void prefix(TPrefixType p)
Definition: InfoSink.cpp:9
void enforceRestrictions(const TDependencyGraph &graph)