Commit fccbac2c by Frank Henigman Committed by Commit Bot

Validate precision in uniform blocks for WebGL.

In WebGL mode turn on checking that precision qualifiers match in corresponding vertex/fragment uniform blocks. Add test for this behavior. BUG=angleproject:2015 Change-Id: Ie035138e8c46e430bdcf8fb5bbc3e0a3ab7d6391 Reviewed-on: https://chromium-review.googlesource.com/517724 Commit-Queue: Geoff Lang <geofflang@chromium.org> Reviewed-by: 's avatarJamie Madill <jmadill@chromium.org>
parent 2f348d2a
...@@ -666,7 +666,7 @@ Error Program::link(const gl::Context *context) ...@@ -666,7 +666,7 @@ Error Program::link(const gl::Context *context)
return NoError(); return NoError();
} }
if (!linkUniformBlocks(mInfoLog, caps)) if (!linkUniformBlocks(mInfoLog, caps, context->getExtensions().webglCompatibility))
{ {
return NoError(); return NoError();
} }
...@@ -713,7 +713,7 @@ Error Program::link(const gl::Context *context) ...@@ -713,7 +713,7 @@ Error Program::link(const gl::Context *context)
return NoError(); return NoError();
} }
if (!linkUniformBlocks(mInfoLog, caps)) if (!linkUniformBlocks(mInfoLog, caps, context->getExtensions().webglCompatibility))
{ {
return NoError(); return NoError();
} }
...@@ -2069,10 +2069,12 @@ void Program::linkSamplerBindings() ...@@ -2069,10 +2069,12 @@ void Program::linkSamplerBindings()
bool Program::linkValidateInterfaceBlockFields(InfoLog &infoLog, bool Program::linkValidateInterfaceBlockFields(InfoLog &infoLog,
const std::string &uniformName, const std::string &uniformName,
const sh::InterfaceBlockField &vertexUniform, const sh::InterfaceBlockField &vertexUniform,
const sh::InterfaceBlockField &fragmentUniform) const sh::InterfaceBlockField &fragmentUniform,
bool webglCompatibility)
{ {
// We don't validate precision on UBO fields. See resolution of Khronos bug 10287. // If webgl, validate precision of UBO fields, otherwise don't. See Khronos bug 10287.
if (!linkValidateVariablesBase(infoLog, uniformName, vertexUniform, fragmentUniform, false)) if (!linkValidateVariablesBase(infoLog, uniformName, vertexUniform, fragmentUniform,
webglCompatibility))
{ {
return false; return false;
} }
...@@ -2209,7 +2211,8 @@ bool Program::validateUniformBlocksCount(GLuint maxUniformBlocks, ...@@ -2209,7 +2211,8 @@ bool Program::validateUniformBlocksCount(GLuint maxUniformBlocks,
bool Program::validateVertexAndFragmentInterfaceBlocks( bool Program::validateVertexAndFragmentInterfaceBlocks(
const std::vector<sh::InterfaceBlock> &vertexInterfaceBlocks, const std::vector<sh::InterfaceBlock> &vertexInterfaceBlocks,
const std::vector<sh::InterfaceBlock> &fragmentInterfaceBlocks, const std::vector<sh::InterfaceBlock> &fragmentInterfaceBlocks,
InfoLog &infoLog) const InfoLog &infoLog,
bool webglCompatibility) const
{ {
// Check that interface blocks defined in the vertex and fragment shaders are identical // Check that interface blocks defined in the vertex and fragment shaders are identical
typedef std::map<std::string, const sh::InterfaceBlock *> UniformBlockMap; typedef std::map<std::string, const sh::InterfaceBlock *> UniformBlockMap;
...@@ -2226,7 +2229,8 @@ bool Program::validateVertexAndFragmentInterfaceBlocks( ...@@ -2226,7 +2229,8 @@ bool Program::validateVertexAndFragmentInterfaceBlocks(
if (entry != linkedUniformBlocks.end()) if (entry != linkedUniformBlocks.end())
{ {
const sh::InterfaceBlock &vertexInterfaceBlock = *entry->second; const sh::InterfaceBlock &vertexInterfaceBlock = *entry->second;
if (!areMatchingInterfaceBlocks(infoLog, vertexInterfaceBlock, fragmentInterfaceBlock)) if (!areMatchingInterfaceBlocks(infoLog, vertexInterfaceBlock, fragmentInterfaceBlock,
webglCompatibility))
{ {
return false; return false;
} }
...@@ -2235,7 +2239,7 @@ bool Program::validateVertexAndFragmentInterfaceBlocks( ...@@ -2235,7 +2239,7 @@ bool Program::validateVertexAndFragmentInterfaceBlocks(
return true; return true;
} }
bool Program::linkUniformBlocks(InfoLog &infoLog, const Caps &caps) bool Program::linkUniformBlocks(InfoLog &infoLog, const Caps &caps, bool webglCompatibility)
{ {
if (mState.mAttachedComputeShader) if (mState.mAttachedComputeShader)
{ {
...@@ -2273,7 +2277,7 @@ bool Program::linkUniformBlocks(InfoLog &infoLog, const Caps &caps) ...@@ -2273,7 +2277,7 @@ bool Program::linkUniformBlocks(InfoLog &infoLog, const Caps &caps)
return false; return false;
} }
if (!validateVertexAndFragmentInterfaceBlocks(vertexInterfaceBlocks, fragmentInterfaceBlocks, if (!validateVertexAndFragmentInterfaceBlocks(vertexInterfaceBlocks, fragmentInterfaceBlocks,
infoLog)) infoLog, webglCompatibility))
{ {
return false; return false;
} }
...@@ -2283,7 +2287,8 @@ bool Program::linkUniformBlocks(InfoLog &infoLog, const Caps &caps) ...@@ -2283,7 +2287,8 @@ bool Program::linkUniformBlocks(InfoLog &infoLog, const Caps &caps)
bool Program::areMatchingInterfaceBlocks(InfoLog &infoLog, bool Program::areMatchingInterfaceBlocks(InfoLog &infoLog,
const sh::InterfaceBlock &vertexInterfaceBlock, const sh::InterfaceBlock &vertexInterfaceBlock,
const sh::InterfaceBlock &fragmentInterfaceBlock) const const sh::InterfaceBlock &fragmentInterfaceBlock,
bool webglCompatibility) const
{ {
const char* blockName = vertexInterfaceBlock.name.c_str(); const char* blockName = vertexInterfaceBlock.name.c_str();
// validate blocks for the same member types // validate blocks for the same member types
...@@ -2322,7 +2327,8 @@ bool Program::areMatchingInterfaceBlocks(InfoLog &infoLog, ...@@ -2322,7 +2327,8 @@ bool Program::areMatchingInterfaceBlocks(InfoLog &infoLog,
return false; return false;
} }
std::string memberName = "interface block '" + vertexInterfaceBlock.name + "' member '" + vertexMember.name + "'"; std::string memberName = "interface block '" + vertexInterfaceBlock.name + "' member '" + vertexMember.name + "'";
if (!linkValidateInterfaceBlockFields(infoLog, memberName, vertexMember, fragmentMember)) if (!linkValidateInterfaceBlockFields(infoLog, memberName, vertexMember, fragmentMember,
webglCompatibility))
{ {
return false; return false;
} }
......
...@@ -424,7 +424,11 @@ class Program final : angle::NonCopyable, public LabeledObject ...@@ -424,7 +424,11 @@ class Program final : angle::NonCopyable, public LabeledObject
GLsizei getTransformFeedbackVaryingMaxLength() const; GLsizei getTransformFeedbackVaryingMaxLength() const;
GLenum getTransformFeedbackBufferMode() const; GLenum getTransformFeedbackBufferMode() const;
static bool linkValidateInterfaceBlockFields(InfoLog &infoLog, const std::string &uniformName, const sh::InterfaceBlockField &vertexUniform, const sh::InterfaceBlockField &fragmentUniform); static bool linkValidateInterfaceBlockFields(InfoLog &infoLog,
const std::string &uniformName,
const sh::InterfaceBlockField &vertexUniform,
const sh::InterfaceBlockField &fragmentUniform,
bool webglCompatibility);
void addRef(); void addRef();
void release(const Context *context); void release(const Context *context);
...@@ -495,8 +499,9 @@ class Program final : angle::NonCopyable, public LabeledObject ...@@ -495,8 +499,9 @@ class Program final : angle::NonCopyable, public LabeledObject
bool validateVertexAndFragmentInterfaceBlocks( bool validateVertexAndFragmentInterfaceBlocks(
const std::vector<sh::InterfaceBlock> &vertexInterfaceBlocks, const std::vector<sh::InterfaceBlock> &vertexInterfaceBlocks,
const std::vector<sh::InterfaceBlock> &fragmentInterfaceBlocks, const std::vector<sh::InterfaceBlock> &fragmentInterfaceBlocks,
InfoLog &infoLog) const; InfoLog &infoLog,
bool linkUniformBlocks(InfoLog &infoLog, const Caps &caps); bool webglCompatibility) const;
bool linkUniformBlocks(InfoLog &infoLog, const Caps &caps, bool webglCompatibility);
bool linkVaryings(InfoLog &infoLog) const; bool linkVaryings(InfoLog &infoLog) const;
bool linkUniforms(InfoLog &infoLog, const Caps &caps, const Bindings &uniformLocationBindings); bool linkUniforms(InfoLog &infoLog, const Caps &caps, const Bindings &uniformLocationBindings);
...@@ -504,7 +509,8 @@ class Program final : angle::NonCopyable, public LabeledObject ...@@ -504,7 +509,8 @@ class Program final : angle::NonCopyable, public LabeledObject
bool areMatchingInterfaceBlocks(InfoLog &infoLog, bool areMatchingInterfaceBlocks(InfoLog &infoLog,
const sh::InterfaceBlock &vertexInterfaceBlock, const sh::InterfaceBlock &vertexInterfaceBlock,
const sh::InterfaceBlock &fragmentInterfaceBlock) const; const sh::InterfaceBlock &fragmentInterfaceBlock,
bool webglCompatibility) const;
static bool linkValidateVaryings(InfoLog &infoLog, static bool linkValidateVaryings(InfoLog &infoLog,
const std::string &varyingName, const std::string &varyingName,
......
...@@ -2824,6 +2824,40 @@ TEST_P(WebGLCompatibilityTest, DrawBuffers) ...@@ -2824,6 +2824,40 @@ TEST_P(WebGLCompatibilityTest, DrawBuffers)
} }
} }
// Linking should fail when corresponding vertex/fragment uniform blocks have different precision
// qualifiers.
TEST_P(WebGL2CompatibilityTest, UniformBlockPrecisionMismatch)
{
const std::string vertexShader =
"#version 300 es\n"
"uniform Block { mediump vec4 val; };\n"
"void main() { gl_Position = val; }\n";
const std::string fragmentShader =
"#version 300 es\n"
"uniform Block { highp vec4 val; };\n"
"out highp vec4 out_FragColor;\n"
"void main() { out_FragColor = val; }\n";
GLuint vs = CompileShader(GL_VERTEX_SHADER, vertexShader);
ASSERT_NE(0u, vs);
GLuint fs = CompileShader(GL_FRAGMENT_SHADER, fragmentShader);
ASSERT_NE(0u, fs);
GLuint program = glCreateProgram();
glAttachShader(program, vs);
glDeleteShader(vs);
glAttachShader(program, fs);
glDeleteShader(fs);
glLinkProgram(program);
GLint linkStatus;
glGetProgramiv(program, GL_LINK_STATUS, &linkStatus);
ASSERT_EQ(0, linkStatus);
glDeleteProgram(program);
}
// Use this to select which configurations (e.g. which renderer, which GLES major version) these // Use this to select which configurations (e.g. which renderer, which GLES major version) these
// tests should be run against. // tests should be run against.
ANGLE_INSTANTIATE_TEST(WebGLCompatibilityTest, ANGLE_INSTANTIATE_TEST(WebGLCompatibilityTest,
......
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