Commit 0350a64c by Qin Jiajia Committed by Commit Bot

Fixed the bug using uniform block array

At the beginning of Program::defineUniformBlock, getUniformBlockSize will call getUniformBlockIndex on MacOS to check if the block is an active block with giving blockName. However, it didn't distinguish array and non-array situations and unified to use interfaceBlock.name as the blockName to call getUniformBlockIndex. It would result that INVALID_INDEX was returned when it's a block array. For example, using 'blockName' not 'blockName[0]'. In OpenGL 4.3 spec, section 7.3.1, there are following descriptions: If name exactly matches the name string of one of the active resources for programInterface, the index of the matched resource is returned. Additionally, if name would exactly match the name string of an active resource if "[0]" were appended to name, the index of the matched resource is returned. Otherwise, name is considered not to be the name of an active resource, and INVALID_INDEX is returned. So, for array block case, we use blockName appending [0] to check the activity. BUG=angleproject:1543 Change-Id: I8189b62066b779f7d392a7dba1cf5cb02a31936d Reviewed-on: https://chromium-review.googlesource.com/405830Reviewed-by: 's avatarJamie Madill <jmadill@chromium.org> Reviewed-by: 's avatarGeoff Lang <geofflang@chromium.org> Commit-Queue: Geoff Lang <geofflang@chromium.org>
parent 8f775607
...@@ -2758,7 +2758,13 @@ void Program::defineUniformBlock(const sh::InterfaceBlock &interfaceBlock, GLenu ...@@ -2758,7 +2758,13 @@ void Program::defineUniformBlock(const sh::InterfaceBlock &interfaceBlock, GLenu
size_t blockSize = 0; size_t blockSize = 0;
// Don't define this block at all if it's not active in the implementation. // Don't define this block at all if it's not active in the implementation.
if (!mProgram->getUniformBlockSize(interfaceBlock.name, &blockSize)) std::stringstream blockNameStr;
blockNameStr << interfaceBlock.name;
if (interfaceBlock.arraySize > 0)
{
blockNameStr << "[0]";
}
if (!mProgram->getUniformBlockSize(blockNameStr.str(), &blockSize))
{ {
return; return;
} }
...@@ -2804,15 +2810,10 @@ void Program::defineUniformBlock(const sh::InterfaceBlock &interfaceBlock, GLenu ...@@ -2804,15 +2810,10 @@ void Program::defineUniformBlock(const sh::InterfaceBlock &interfaceBlock, GLenu
UNREACHABLE(); UNREACHABLE();
} }
// TODO(jmadill): Determine if we can ever have an inactive array element block. // Since all block elements in an array share the same active uniforms, they will all be
size_t blockElementSize = 0; // active once any uniform member is used. So, since interfaceBlock.name[0] was active,
if (!mProgram->getUniformBlockSize(block.nameWithArrayIndex(), &blockElementSize)) // here we will add every block element in the array.
{ block.dataSize = static_cast<unsigned int>(blockSize);
continue;
}
ASSERT(blockElementSize == blockSize);
block.dataSize = static_cast<unsigned int>(blockElementSize);
mState.mUniformBlocks.push_back(block); mState.mUniformBlocks.push_back(block);
} }
} }
......
...@@ -358,43 +358,68 @@ TEST_P(UniformBufferTest, ActiveUniformNames) ...@@ -358,43 +358,68 @@ TEST_P(UniformBufferTest, ActiveUniformNames)
const std::string &vertexShaderSource = const std::string &vertexShaderSource =
"#version 300 es\n" "#version 300 es\n"
"in vec2 position;\n" "in vec2 position;\n"
"out float v;\n" "out vec2 v;\n"
"uniform blockName {\n" "uniform blockName1 {\n"
" float f;\n" " float f1;\n"
"} instanceName;\n" "} instanceName1;\n"
"uniform blockName2 {\n"
" float f2;\n"
"} instanceName2[1];\n"
"void main() {\n" "void main() {\n"
" v = instanceName.f;\n" " v = vec2(instanceName1.f1, instanceName2[0].f2);\n"
" gl_Position = vec4(position, 0, 1);\n" " gl_Position = vec4(position, 0, 1);\n"
"}"; "}";
const std::string &fragmentShaderSource = const std::string &fragmentShaderSource =
"#version 300 es\n" "#version 300 es\n"
"precision highp float;\n" "precision highp float;\n"
"in float v;\n" "in vec2 v;\n"
"out vec4 color;\n" "out vec4 color;\n"
"void main() {\n" "void main() {\n"
" color = vec4(v, 0, 0, 1);\n" " color = vec4(v, 0, 1);\n"
"}"; "}";
GLuint program = CompileProgram(vertexShaderSource, fragmentShaderSource); GLuint program = CompileProgram(vertexShaderSource, fragmentShaderSource);
ASSERT_NE(0u, program); ASSERT_NE(0u, program);
GLint activeUniformBlocks;
glGetProgramiv(program, GL_ACTIVE_UNIFORM_BLOCKS, &activeUniformBlocks);
ASSERT_EQ(2, activeUniformBlocks);
GLint maxLength;
GLsizei length;
glGetProgramiv(program, GL_ACTIVE_UNIFORM_BLOCK_MAX_NAME_LENGTH, &maxLength);
std::vector<GLchar> strBlockNameBuffer(maxLength + 1, 0);
glGetActiveUniformBlockName(program, 0, maxLength, &length, &strBlockNameBuffer[0]);
ASSERT_GL_NO_ERROR();
EXPECT_EQ("blockName1", std::string(&strBlockNameBuffer[0]));
glGetActiveUniformBlockName(program, 1, maxLength, &length, &strBlockNameBuffer[0]);
ASSERT_GL_NO_ERROR();
EXPECT_EQ("blockName2[0]", std::string(&strBlockNameBuffer[0]));
GLint activeUniforms; GLint activeUniforms;
glGetProgramiv(program, GL_ACTIVE_UNIFORMS, &activeUniforms); glGetProgramiv(program, GL_ACTIVE_UNIFORMS, &activeUniforms);
ASSERT_EQ(1, activeUniforms); ASSERT_EQ(2, activeUniforms);
GLint maxLength, size; GLint size;
GLenum type; GLenum type;
GLsizei length;
glGetProgramiv(program, GL_ACTIVE_UNIFORM_MAX_LENGTH, &maxLength); glGetProgramiv(program, GL_ACTIVE_UNIFORM_MAX_LENGTH, &maxLength);
std::vector<GLchar> strBuffer(maxLength + 1, 0); std::vector<GLchar> strUniformNameBuffer(maxLength + 1, 0);
glGetActiveUniform(program, 0, maxLength, &length, &size, &type, &strBuffer[0]); glGetActiveUniform(program, 0, maxLength, &length, &size, &type, &strUniformNameBuffer[0]);
ASSERT_GL_NO_ERROR();
EXPECT_EQ(1, size);
EXPECT_GLENUM_EQ(GL_FLOAT, type);
EXPECT_EQ("blockName1.f1", std::string(&strUniformNameBuffer[0]));
glGetActiveUniform(program, 1, maxLength, &length, &size, &type, &strUniformNameBuffer[0]);
ASSERT_GL_NO_ERROR(); ASSERT_GL_NO_ERROR();
EXPECT_EQ(1, size); EXPECT_EQ(1, size);
EXPECT_GLENUM_EQ(GL_FLOAT, type); EXPECT_GLENUM_EQ(GL_FLOAT, type);
EXPECT_EQ("blockName.f", std::string(&strBuffer[0])); EXPECT_EQ("blockName2.f2", std::string(&strUniformNameBuffer[0]));
} }
// Tests active uniforms and blocks when the layout is std140, shared and packed. // Tests active uniforms and blocks when the layout is std140, shared and packed.
......
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