[SH_TIMING_RESTRICTIONS] Restrict sampler dependent values from the tex coord and bias parameters of all sampling operations, not just texture2D.

Issue: 335
Review URL: https://codereview.appspot.com/6305049/


git-svn-id: https://angleproject.googlecode.com/svn/trunk@1167 736b8ea6-26fd-11df-bfd4-992fa37f6226
This commit is contained in:
maxvujovic@gmail.com 2012-06-25 20:39:58 +00:00
Родитель 635d6b5df9
Коммит 8b8f02dcd3
3 изменённых файлов: 61 добавлений и 16 удалений

Просмотреть файл

@ -117,6 +117,7 @@ int main(int argc, char* argv[])
switch (argv[0][3]) {
case 'i': resources.OES_EGL_image_external = 1; break;
case 'd': resources.OES_standard_derivatives = 1; break;
case 'r': resources.ARB_texture_rectangle = 1; break;
default: failCode = EFailUsage;
}
} else {
@ -220,7 +221,8 @@ void usage()
" -b=g : output GLSL code\n"
" -b=h : output HLSL code\n"
" -x=i : enable GL_OES_EGL_image_external\n"
" -x=d : enable GL_OES_EGL_standard_derivatives\n");
" -x=d : enable GL_OES_EGL_standard_derivatives\n"
" -x=r : enable ARB_texture_rectangle\n");
}
//

Просмотреть файл

@ -9,6 +9,30 @@
#include "compiler/depgraph/DependencyGraphOutput.h"
#include "compiler/timing/RestrictFragmentShaderTiming.h"
RestrictFragmentShaderTiming::RestrictFragmentShaderTiming(TInfoSinkBase& sink)
: mSink(sink)
, mNumErrors(0)
{
// Sampling ops found only in fragment shaders.
mSamplingOps.insert("texture2D(s21;vf2;f1;");
mSamplingOps.insert("texture2DProj(s21;vf3;f1;");
mSamplingOps.insert("texture2DProj(s21;vf4;f1;");
mSamplingOps.insert("textureCube(sC1;vf3;f1;");
// Sampling ops found in both vertex and fragment shaders.
mSamplingOps.insert("texture2D(s21;vf2;");
mSamplingOps.insert("texture2DProj(s21;vf3;");
mSamplingOps.insert("texture2DProj(s21;vf4;");
mSamplingOps.insert("textureCube(sC1;vf3;");
// Sampling ops provided by OES_EGL_image_external.
mSamplingOps.insert("texture2D(1;vf2;");
mSamplingOps.insert("texture2DProj(1;vf3;");
mSamplingOps.insert("texture2DProj(1;vf4;");
// Sampling ops provided by ARB_texture_rectangle.
mSamplingOps.insert("texture2DRect(1;vf2;");
mSamplingOps.insert("texture2DRectProj(1;vf3;");
mSamplingOps.insert("texture2DRectProj(1;vf4;");
}
// FIXME(mvujovic): We do not know if the execution time of built-in operations like sin, pow, etc.
// can vary based on the value of the input arguments. If so, we should restrict those as well.
void RestrictFragmentShaderTiming::enforceRestrictions(const TDependencyGraph& graph)
@ -50,18 +74,36 @@ void RestrictFragmentShaderTiming::beginError(const TIntermNode* node)
mSink.location(node->getLine());
}
bool RestrictFragmentShaderTiming::isSamplingOp(const TIntermAggregate* intermFunctionCall) const
{
return !intermFunctionCall->isUserDefined() &&
mSamplingOps.find(intermFunctionCall->getName()) != mSamplingOps.end();
}
void RestrictFragmentShaderTiming::visitArgument(TGraphArgument* parameter)
{
// FIXME(mvujovic): We should restrict sampler dependent values from being texture coordinates
// in all available sampling operations supported in GLSL ES.
// This includes overloaded signatures of texture2D, textureCube, and others.
if (parameter->getIntermFunctionCall()->getName() != "texture2D(s21;vf2;" ||
parameter->getArgumentNumber() != 1)
return;
beginError(parameter->getIntermFunctionCall());
mSink << "An expression dependent on a sampler is not permitted to be the second argument"
<< " of a texture2D call.\n";
// Texture cache access time might leak sensitive information.
// Thus, we restrict sampler dependent values from affecting the coordinate or LOD bias of a
// sampling operation.
if (isSamplingOp(parameter->getIntermFunctionCall())) {
switch (parameter->getArgumentNumber()) {
case 1:
// Second argument (coord)
beginError(parameter->getIntermFunctionCall());
mSink << "An expression dependent on a sampler is not permitted to be the"
<< " coordinate argument of a sampling operation.\n";
break;
case 2:
// Third argument (bias)
beginError(parameter->getIntermFunctionCall());
mSink << "An expression dependent on a sampler is not permitted to be the"
<< " bias argument of a sampling operation.\n";
break;
default:
// First argument (sampler)
break;
}
}
}
void RestrictFragmentShaderTiming::visitSelection(TGraphSelection* selection)

Просмотреть файл

@ -16,10 +16,7 @@ class TInfoSinkBase;
class RestrictFragmentShaderTiming : TDependencyGraphTraverser {
public:
RestrictFragmentShaderTiming(TInfoSinkBase& sink)
: mSink(sink)
, mNumErrors(0) {}
RestrictFragmentShaderTiming(TInfoSinkBase& sink);
void enforceRestrictions(const TDependencyGraph& graph);
int numErrors() const { return mNumErrors; }
@ -31,9 +28,13 @@ public:
private:
void beginError(const TIntermNode* node);
void validateUserDefinedFunctionCallUsage(const TDependencyGraph& graph);
bool isSamplingOp(const TIntermAggregate* intermFunctionCall) const;
TInfoSinkBase& mSink;
TInfoSinkBase& mSink;
int mNumErrors;
typedef std::set<TString> StringSet;
StringSet mSamplingOps;
};
#endif // COMPILER_TIMING_RESTRICT_FRAGMENT_SHADER_TIMING_H_