Commit c16678a2 by Corentin Wallez Committed by Commit Bot

ASTMetadataHLSL: handle WebGL2 gradient builtins

BUG=angleproject:1915 Change-Id: Id54e6dd417a1a288c71355e74184366d1492e92b Reviewed-on: https://chromium-review.googlesource.com/446521Reviewed-by: 's avatarKenneth Russell <kbr@chromium.org> Reviewed-by: 's avatarJamie Madill <jmadill@chromium.org> Commit-Queue: Corentin Wallez <cwallez@chromium.org>
parent 6f60d05f
...@@ -32,6 +32,19 @@ class PullGradient : public TIntermTraverser ...@@ -32,6 +32,19 @@ class PullGradient : public TIntermTraverser
mDag(dag) mDag(dag)
{ {
ASSERT(index < metadataList->size()); ASSERT(index < metadataList->size());
// ESSL 100 builtin gradient functions
mGradientBuiltinFunctions.insert("texture2D");
mGradientBuiltinFunctions.insert("texture2DProj");
mGradientBuiltinFunctions.insert("textureCube");
// ESSL 300 builtin gradient functions
mGradientBuiltinFunctions.insert("texture");
mGradientBuiltinFunctions.insert("textureProj");
mGradientBuiltinFunctions.insert("textureOffset");
mGradientBuiltinFunctions.insert("textureProjOffset");
// ESSL 310 doesn't add builtin gradient functions
} }
void traverse(TIntermFunctionDefinition *node) void traverse(TIntermFunctionDefinition *node)
...@@ -89,6 +102,7 @@ class PullGradient : public TIntermTraverser ...@@ -89,6 +102,7 @@ class PullGradient : public TIntermTraverser
{ {
case EOpDFdx: case EOpDFdx:
case EOpDFdy: case EOpDFdy:
case EOpFwidth:
onGradient(); onGradient();
default: default:
break; break;
...@@ -116,7 +130,7 @@ class PullGradient : public TIntermTraverser ...@@ -116,7 +130,7 @@ class PullGradient : public TIntermTraverser
{ {
TString name = TFunction::unmangleName(node->getFunctionSymbolInfo()->getName()); TString name = TFunction::unmangleName(node->getFunctionSymbolInfo()->getName());
if (name == "texture2D" || name == "texture2DProj" || name == "textureCube") if (mGradientBuiltinFunctions.find(name) != mGradientBuiltinFunctions.end())
{ {
onGradient(); onGradient();
} }
...@@ -135,6 +149,9 @@ class PullGradient : public TIntermTraverser ...@@ -135,6 +149,9 @@ class PullGradient : public TIntermTraverser
// Contains a stack of the control flow nodes that are parents of the node being // Contains a stack of the control flow nodes that are parents of the node being
// currently visited. It is used to mark control flows using a gradient. // currently visited. It is used to mark control flows using a gradient.
std::vector<TIntermNode *> mParents; std::vector<TIntermNode *> mParents;
// A list of builtin functions that use gradients
std::set<TString> mGradientBuiltinFunctions;
}; };
// Traverses the AST of a function definition to compute the the discontinuous loops // Traverses the AST of a function definition to compute the the discontinuous loops
......
...@@ -22,21 +22,22 @@ namespace ...@@ -22,21 +22,22 @@ namespace
class UnrollFlattenTest : public testing::Test class UnrollFlattenTest : public testing::Test
{ {
public: public:
UnrollFlattenTest() {} UnrollFlattenTest() : mInputSpec(SH_GLES2_SPEC) {}
UnrollFlattenTest(ShShaderSpec inputSpec) : mInputSpec(inputSpec) {}
protected: protected:
void compile(const std::string &shaderString) void compile(const std::string &shaderString)
{ {
std::string infoLog; std::string infoLog;
bool compilationSuccess = bool compilationSuccess =
compileTestShader(GL_FRAGMENT_SHADER, SH_GLES2_SPEC, SH_HLSL_4_1_OUTPUT, shaderString, compileTestShader(GL_FRAGMENT_SHADER, mInputSpec, SH_HLSL_4_1_OUTPUT, shaderString,
SH_VARIABLES, &mTranslatedSource, &infoLog); SH_VARIABLES, &mTranslatedSource, &infoLog);
if (!compilationSuccess) if (!compilationSuccess)
{ {
FAIL() << "Shader compilation failed " << infoLog; FAIL() << "Shader compilation failed " << infoLog;
} }
// Ignore the beginning of the shader to avoid the definitions of LOOP and FLATTEN // Ignore the beginning of the shader to avoid the definitions of LOOP and FLATTEN
mCurrentPosition = static_cast<int>(mTranslatedSource.find("GL_USES_FRAG_COLOR")); mCurrentPosition = static_cast<int>(mTranslatedSource.find("cbuffer DriverConstants"));
} }
void expect(const char *patterns[], size_t count) void expect(const char *patterns[], size_t count)
...@@ -71,6 +72,7 @@ class UnrollFlattenTest : public testing::Test ...@@ -71,6 +72,7 @@ class UnrollFlattenTest : public testing::Test
static const char *FLATTEN; static const char *FLATTEN;
private: private:
ShShaderSpec mInputSpec;
std::string mTranslatedSource; std::string mTranslatedSource;
int mCurrentPosition; int mCurrentPosition;
...@@ -206,4 +208,31 @@ TEST_F(UnrollFlattenTest, GradientInDiscont) ...@@ -206,4 +208,31 @@ TEST_F(UnrollFlattenTest, GradientInDiscont)
expect(expectations, ArraySize(expectations)); expect(expectations, ArraySize(expectations));
} }
class UnrollFlattenTest_ES3 : public UnrollFlattenTest
{
public:
UnrollFlattenTest_ES3() : UnrollFlattenTest(SH_GLES3_SPEC) {}
};
// Check that we correctly detect the ES3 builtin "texture" function as a gradient operation.
TEST_F(UnrollFlattenTest_ES3, TextureBuiltin)
{
const std::string &shaderString =
"#version 300 es\n"
"precision mediump float;\n"
"uniform sampler2D tex;"
"out float fragColor;\n"
"void main() {\n"
" float a = 0.0;"
" for (int i = 0; i < 10; i++) {\n"
" if (a > 1.0) {break;}\n"
" a += texture(tex, vec2(a, 0.0)).x;"
" }\n"
" fragColor = a;\n"
"}\n";
compile(shaderString);
const char *expectations[] = {"main(", "LOOP", "Lod0("};
expect(expectations, ArraySize(expectations));
}
} }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment