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)
return NoError();
}
if (!linkUniformBlocks(mInfoLog, caps))
if (!linkUniformBlocks(mInfoLog, caps, context->getExtensions().webglCompatibility))
{
return NoError();
}
......@@ -713,7 +713,7 @@ Error Program::link(const gl::Context *context)
return NoError();
}
if (!linkUniformBlocks(mInfoLog, caps))
if (!linkUniformBlocks(mInfoLog, caps, context->getExtensions().webglCompatibility))
{
return NoError();
}
......@@ -2069,10 +2069,12 @@ void Program::linkSamplerBindings()
bool Program::linkValidateInterfaceBlockFields(InfoLog &infoLog,
const std::string &uniformName,
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 (!linkValidateVariablesBase(infoLog, uniformName, vertexUniform, fragmentUniform, false))
// If webgl, validate precision of UBO fields, otherwise don't. See Khronos bug 10287.
if (!linkValidateVariablesBase(infoLog, uniformName, vertexUniform, fragmentUniform,
webglCompatibility))
{
return false;
}
......@@ -2209,7 +2211,8 @@ bool Program::validateUniformBlocksCount(GLuint maxUniformBlocks,
bool Program::validateVertexAndFragmentInterfaceBlocks(
const std::vector<sh::InterfaceBlock> &vertexInterfaceBlocks,
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
typedef std::map<std::string, const sh::InterfaceBlock *> UniformBlockMap;
......@@ -2226,7 +2229,8 @@ bool Program::validateVertexAndFragmentInterfaceBlocks(
if (entry != linkedUniformBlocks.end())
{
const sh::InterfaceBlock &vertexInterfaceBlock = *entry->second;
if (!areMatchingInterfaceBlocks(infoLog, vertexInterfaceBlock, fragmentInterfaceBlock))
if (!areMatchingInterfaceBlocks(infoLog, vertexInterfaceBlock, fragmentInterfaceBlock,
webglCompatibility))
{
return false;
}
......@@ -2235,7 +2239,7 @@ bool Program::validateVertexAndFragmentInterfaceBlocks(
return true;
}
bool Program::linkUniformBlocks(InfoLog &infoLog, const Caps &caps)
bool Program::linkUniformBlocks(InfoLog &infoLog, const Caps &caps, bool webglCompatibility)
{
if (mState.mAttachedComputeShader)
{
......@@ -2273,7 +2277,7 @@ bool Program::linkUniformBlocks(InfoLog &infoLog, const Caps &caps)
return false;
}
if (!validateVertexAndFragmentInterfaceBlocks(vertexInterfaceBlocks, fragmentInterfaceBlocks,
infoLog))
infoLog, webglCompatibility))
{
return false;
}
......@@ -2283,7 +2287,8 @@ bool Program::linkUniformBlocks(InfoLog &infoLog, const Caps &caps)
bool Program::areMatchingInterfaceBlocks(InfoLog &infoLog,
const sh::InterfaceBlock &vertexInterfaceBlock,
const sh::InterfaceBlock &fragmentInterfaceBlock) const
const sh::InterfaceBlock &fragmentInterfaceBlock,
bool webglCompatibility) const
{
const char* blockName = vertexInterfaceBlock.name.c_str();
// validate blocks for the same member types
......@@ -2322,7 +2327,8 @@ bool Program::areMatchingInterfaceBlocks(InfoLog &infoLog,
return false;
}
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;
}
......
......@@ -424,7 +424,11 @@ class Program final : angle::NonCopyable, public LabeledObject
GLsizei getTransformFeedbackVaryingMaxLength() 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 release(const Context *context);
......@@ -495,8 +499,9 @@ class Program final : angle::NonCopyable, public LabeledObject
bool validateVertexAndFragmentInterfaceBlocks(
const std::vector<sh::InterfaceBlock> &vertexInterfaceBlocks,
const std::vector<sh::InterfaceBlock> &fragmentInterfaceBlocks,
InfoLog &infoLog) const;
bool linkUniformBlocks(InfoLog &infoLog, const Caps &caps);
InfoLog &infoLog,
bool webglCompatibility) const;
bool linkUniformBlocks(InfoLog &infoLog, const Caps &caps, bool webglCompatibility);
bool linkVaryings(InfoLog &infoLog) const;
bool linkUniforms(InfoLog &infoLog, const Caps &caps, const Bindings &uniformLocationBindings);
......@@ -504,7 +509,8 @@ class Program final : angle::NonCopyable, public LabeledObject
bool areMatchingInterfaceBlocks(InfoLog &infoLog,
const sh::InterfaceBlock &vertexInterfaceBlock,
const sh::InterfaceBlock &fragmentInterfaceBlock) const;
const sh::InterfaceBlock &fragmentInterfaceBlock,
bool webglCompatibility) const;
static bool linkValidateVaryings(InfoLog &infoLog,
const std::string &varyingName,
......
......@@ -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
// tests should be run against.
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