Commit 0fbd128c by David Yen Committed by Zhenyao Mo

Extension behavior is now reset between each shader translation unit.

The extension behavior was being shared between translation units, this was causing states to be cached between shader compilers. This has been fixed now by adding a new ResetExtensionBehavior() function. A unit test has also been added for testing extensions when compiling shaders. A test has been included which tests that the internal state of the extension behavior is being reset properly. BUG=453543 Change-Id: Icb2a07019b5db972dc75cdbbdece4b7e9757c682 Reviewed-on: https://chromium-review.googlesource.com/245522Tested-by: 's avatarDavid Yen <dyen@chromium.org> Reviewed-by: 's avatarZhenyao Mo <zmo@chromium.org>
parent fcbf345b
...@@ -168,6 +168,9 @@ bool TCompiler::compile(const char* const shaderStrings[], ...@@ -168,6 +168,9 @@ bool TCompiler::compile(const char* const shaderStrings[],
if (numStrings == 0) if (numStrings == 0)
return true; return true;
// Reset the extension behavior for each compilation unit.
ResetExtensionBehavior(extensionBehavior);
// If compiling for WebGL, validate loop and indexing as well. // If compiling for WebGL, validate loop and indexing as well.
if (IsWebGLBasedSpec(shaderSpec)) if (IsWebGLBasedSpec(shaderSpec))
compileOptions |= SH_VALIDATE_LOOP_INDEXING; compileOptions |= SH_VALIDATE_LOOP_INDEXING;
......
...@@ -930,3 +930,13 @@ void InitExtensionBehavior(const ShBuiltInResources& resources, ...@@ -930,3 +930,13 @@ void InitExtensionBehavior(const ShBuiltInResources& resources,
if (resources.ARM_shader_framebuffer_fetch) if (resources.ARM_shader_framebuffer_fetch)
extBehavior["GL_ARM_shader_framebuffer_fetch"] = EBhUndefined; extBehavior["GL_ARM_shader_framebuffer_fetch"] = EBhUndefined;
} }
void ResetExtensionBehavior(TExtensionBehavior &extBehavior)
{
for (auto ext_iter = extBehavior.begin();
ext_iter != extBehavior.end();
++ext_iter)
{
ext_iter->second = EBhUndefined;
}
}
...@@ -20,4 +20,10 @@ void IdentifyBuiltIns(sh::GLenum type, ShShaderSpec spec, ...@@ -20,4 +20,10 @@ void IdentifyBuiltIns(sh::GLenum type, ShShaderSpec spec,
void InitExtensionBehavior(const ShBuiltInResources& resources, void InitExtensionBehavior(const ShBuiltInResources& resources,
TExtensionBehavior& extensionBehavior); TExtensionBehavior& extensionBehavior);
// Resets the behavior of the extensions listed in |extensionBehavior| to the
// undefined state. These extensions will only be those initially supported in
// the ShBuiltInResources object for this compiler instance. All other
// extensions will remain unsupported.
void ResetExtensionBehavior(TExtensionBehavior &extensionBehavior);
#endif // COMPILER_TRANSLATOR_INITIALIZE_H_ #endif // COMPILER_TRANSLATOR_INITIALIZE_H_
...@@ -19,6 +19,7 @@ ...@@ -19,6 +19,7 @@
'<(angle_path)/tests/compiler_tests/CollectVariables_test.cpp', '<(angle_path)/tests/compiler_tests/CollectVariables_test.cpp',
'<(angle_path)/tests/compiler_tests/DebugShaderPrecision_test.cpp', '<(angle_path)/tests/compiler_tests/DebugShaderPrecision_test.cpp',
'<(angle_path)/tests/compiler_tests/ExpressionLimit_test.cpp', '<(angle_path)/tests/compiler_tests/ExpressionLimit_test.cpp',
'<(angle_path)/tests/compiler_tests/ShaderExtension_test.cpp',
'<(angle_path)/tests/compiler_tests/NV_draw_buffers_test.cpp', '<(angle_path)/tests/compiler_tests/NV_draw_buffers_test.cpp',
'<(angle_path)/tests/compiler_tests/ShaderVariable_test.cpp', '<(angle_path)/tests/compiler_tests/ShaderVariable_test.cpp',
'<(angle_path)/tests/compiler_tests/TypeTracking_test.cpp', '<(angle_path)/tests/compiler_tests/TypeTracking_test.cpp',
......
//
// Copyright (c) 2015 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
// Extension_test.cpp
// Test that shaders need various extensions to be compiled.
//
#include "angle_gl.h"
#include "gtest/gtest.h"
#include "GLSLANG/ShaderLang.h"
static const char *FragDepthExtShdr[] =
{
// First string of the shader. The required pragma declaration.
"#extension GL_EXT_frag_depth : enable\n",
// Second string of the shader. The rest of the shader body.
"void main() { gl_FragDepthEXT = 1.0; }\n"
};
static const char *StandDerivExtShdr[] =
{
// First string of the shader. The required pragma declaration.
"#extension GL_OES_standard_derivatives : enable\n",
// Second string of the shader. The rest of the shader body.
"precision mediump float;\n"
"varying vec2 texCoord;\n"
"void main() { gl_FragColor = vec4(dFdx(texCoord.x), dFdy(texCoord.y), fwidth(texCoord.x), 1.0); }\n"
};
static const char *TextureLODShdr[] =
{
// First string of the shader. The required pragma declaration.
"#extension GL_EXT_shader_texture_lod : enable\n",
// Second string of the shader. The rest of the shader body.
"precision mediump float;\n"
"varying vec2 texCoord0v;\n"
"uniform float lod;\n"
"uniform sampler2D tex;\n"
"void main() { vec4 color = texture2DLodEXT(tex, texCoord0v, lod); }\n"
};
class ShaderExtensionTest : public testing::Test
{
public:
ShaderExtensionTest() {}
protected:
virtual void SetUp()
{
ShInitBuiltInResources(&mResources);
mCompiler = NULL;
}
virtual void TearDown()
{
DestroyCompiler();
}
void DestroyCompiler()
{
if (mCompiler)
{
ShDestruct(mCompiler);
mCompiler = NULL;
}
}
void InitializeCompiler()
{
DestroyCompiler();
mCompiler = ShConstructCompiler(GL_FRAGMENT_SHADER, SH_WEBGL_SPEC, SH_GLSL_OUTPUT, &mResources);
ASSERT_TRUE(mCompiler) << "Compiler could not be constructed.";
}
void TestShaderExtension(const char **shaderStrings, int stringCount, bool expectation)
{
bool success = ShCompile(mCompiler, shaderStrings, stringCount, 0);
const std::string& compileLog = ShGetInfoLog(mCompiler);
EXPECT_EQ(success, expectation) << compileLog;
}
protected:
ShBuiltInResources mResources;
ShHandle mCompiler;
};
TEST_F(ShaderExtensionTest, FragDepthExtRequiresExt)
{
// Extension is required to compile properly.
mResources.EXT_frag_depth = 0;
InitializeCompiler();
TestShaderExtension(FragDepthExtShdr, 2, false);
}
TEST_F(ShaderExtensionTest, FragDepthExtRequiresPragma)
{
// Pragma is required to compile properly.
mResources.EXT_frag_depth = 1;
InitializeCompiler();
TestShaderExtension(&FragDepthExtShdr[1], 1, false);
}
TEST_F(ShaderExtensionTest, FragDepthExtCompiles)
{
// Test that it compiles properly with extension enabled.
mResources.EXT_frag_depth = 1;
InitializeCompiler();
TestShaderExtension(FragDepthExtShdr, 2, true);
}
TEST_F(ShaderExtensionTest, FragDepthExtResetsInternalStates)
{
// Test that extension internal states are reset properly between compiles.
mResources.EXT_frag_depth = 1;
InitializeCompiler();
TestShaderExtension(FragDepthExtShdr, 2, true);
TestShaderExtension(&FragDepthExtShdr[1], 1, false);
TestShaderExtension(FragDepthExtShdr, 2, true);
};
TEST_F(ShaderExtensionTest, StandDerivExtRequiresExt)
{
// Extension is required to compile properly.
mResources.OES_standard_derivatives = 0;
InitializeCompiler();
TestShaderExtension(StandDerivExtShdr, 2, false);
}
TEST_F(ShaderExtensionTest, StandDerivExtRequiresPragma)
{
// Pragma is required to compile properly.
mResources.OES_standard_derivatives = 1;
InitializeCompiler();
TestShaderExtension(&StandDerivExtShdr[1], 1, false);
}
TEST_F(ShaderExtensionTest, StandDerivExtCompiles)
{
// Test that it compiles properly with extension enabled.
mResources.OES_standard_derivatives = 1;
InitializeCompiler();
TestShaderExtension(StandDerivExtShdr, 2, true);
}
TEST_F(ShaderExtensionTest, StandDerivExtResetsInternalStates)
{
// Test that extension internal states are reset properly between compiles.
mResources.OES_standard_derivatives = 1;
InitializeCompiler();
TestShaderExtension(StandDerivExtShdr, 2, true);
TestShaderExtension(&StandDerivExtShdr[1], 1, false);
TestShaderExtension(StandDerivExtShdr, 2, true);
TestShaderExtension(&StandDerivExtShdr[1], 1, false);
};
TEST_F(ShaderExtensionTest, TextureLODExtRequiresExt)
{
// Extension is required to compile properly.
mResources.EXT_shader_texture_lod = 0;
InitializeCompiler();
TestShaderExtension(TextureLODShdr, 2, false);
}
TEST_F(ShaderExtensionTest, TextureLODExtRequiresPragma)
{
// Pragma is required to compile properly.
mResources.EXT_shader_texture_lod = 1;
InitializeCompiler();
TestShaderExtension(&TextureLODShdr[1], 1, false);
}
TEST_F(ShaderExtensionTest, TextureLODExtCompiles)
{
// Test that it compiles properly with extension enabled.
mResources.EXT_shader_texture_lod = 1;
InitializeCompiler();
TestShaderExtension(TextureLODShdr, 2, true);
}
TEST_F(ShaderExtensionTest, TextureLODExtResetsInternalStates)
{
// Test that extension internal states are reset properly between compiles.
mResources.EXT_shader_texture_lod = 1;
InitializeCompiler();
TestShaderExtension(&TextureLODShdr[1], 1, false);
TestShaderExtension(TextureLODShdr, 2, true);
TestShaderExtension(&TextureLODShdr[1], 1, false);
TestShaderExtension(TextureLODShdr, 2, true);
};
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