Commit 8efd1268 by Jiajia Qin Committed by Commit Bot

ES31: Add max combined interface blocks validation

BUG=angleproject:1951 Change-Id: I9223964fa84cee3888fb7f5949c3e098fe2aa2b0 Reviewed-on: https://chromium-review.googlesource.com/890818 Commit-Queue: Jamie Madill <jmadill@chromium.org> Reviewed-by: 's avatarJamie Madill <jmadill@chromium.org>
parent 1776fd08
...@@ -2510,15 +2510,22 @@ bool Program::ValidateGraphicsInterfaceBlocks( ...@@ -2510,15 +2510,22 @@ bool Program::ValidateGraphicsInterfaceBlocks(
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, InfoLog &infoLog,
bool webglCompatibility) bool webglCompatibility,
sh::BlockType blockType,
GLuint maxCombinedInterfaceBlocks)
{ {
// 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 *> InterfaceBlockMap; typedef std::map<std::string, const sh::InterfaceBlock *> InterfaceBlockMap;
InterfaceBlockMap linkedInterfaceBlocks; InterfaceBlockMap linkedInterfaceBlocks;
GLuint blockCount = 0;
for (const sh::InterfaceBlock &vertexInterfaceBlock : vertexInterfaceBlocks) for (const sh::InterfaceBlock &vertexInterfaceBlock : vertexInterfaceBlocks)
{ {
linkedInterfaceBlocks[vertexInterfaceBlock.name] = &vertexInterfaceBlock; linkedInterfaceBlocks[vertexInterfaceBlock.name] = &vertexInterfaceBlock;
if (vertexInterfaceBlock.staticUse || vertexInterfaceBlock.layout != sh::BLOCKLAYOUT_PACKED)
{
blockCount += std::max(vertexInterfaceBlock.arraySize, 1u);
}
} }
for (const sh::InterfaceBlock &fragmentInterfaceBlock : fragmentInterfaceBlocks) for (const sh::InterfaceBlock &fragmentInterfaceBlock : fragmentInterfaceBlocks)
...@@ -2538,8 +2545,34 @@ bool Program::ValidateGraphicsInterfaceBlocks( ...@@ -2538,8 +2545,34 @@ bool Program::ValidateGraphicsInterfaceBlocks(
return false; return false;
} }
} }
// TODO(jiajia.qin@intel.com): Add else
// MAX_COMBINED_UNIFORM_BLOCKS/MAX_COMBINED_SHADER_STORAGE_BLOCKS validation. {
if (fragmentInterfaceBlock.staticUse ||
fragmentInterfaceBlock.layout != sh::BLOCKLAYOUT_PACKED)
{
blockCount += std::max(fragmentInterfaceBlock.arraySize, 1u);
}
}
}
if (blockCount > maxCombinedInterfaceBlocks)
{
switch (blockType)
{
case sh::BlockType::BLOCK_UNIFORM:
infoLog << "The sum of the number of active uniform blocks exceeds "
"MAX_COMBINED_UNIFORM_BLOCKS ("
<< maxCombinedInterfaceBlocks << ").";
break;
case sh::BlockType::BLOCK_BUFFER:
infoLog << "The sum of the number of active shader storage blocks exceeds "
"MAX_COMBINED_SHADER_STORAGE_BLOCKS ("
<< maxCombinedInterfaceBlocks << ").";
break;
default:
UNREACHABLE();
}
return false;
} }
return true; return true;
} }
...@@ -2596,7 +2629,8 @@ bool Program::linkInterfaceBlocks(const Context *context, InfoLog &infoLog) ...@@ -2596,7 +2629,8 @@ bool Program::linkInterfaceBlocks(const Context *context, InfoLog &infoLog)
bool webglCompatibility = context->getExtensions().webglCompatibility; bool webglCompatibility = context->getExtensions().webglCompatibility;
if (!ValidateGraphicsInterfaceBlocks(vertexUniformBlocks, fragmentUniformBlocks, infoLog, if (!ValidateGraphicsInterfaceBlocks(vertexUniformBlocks, fragmentUniformBlocks, infoLog,
webglCompatibility)) webglCompatibility, sh::BlockType::BLOCK_UNIFORM,
caps.maxCombinedUniformBlocks))
{ {
return false; return false;
} }
...@@ -2624,8 +2658,9 @@ bool Program::linkInterfaceBlocks(const Context *context, InfoLog &infoLog) ...@@ -2624,8 +2658,9 @@ bool Program::linkInterfaceBlocks(const Context *context, InfoLog &infoLog)
return false; return false;
} }
if (!ValidateGraphicsInterfaceBlocks(vertexShaderStorageBlocks, fragmentShaderStorageBlocks, if (!ValidateGraphicsInterfaceBlocks(
infoLog, webglCompatibility)) vertexShaderStorageBlocks, fragmentShaderStorageBlocks, infoLog, webglCompatibility,
sh::BlockType::BLOCK_BUFFER, caps.maxCombinedShaderStorageBlocks))
{ {
return false; return false;
} }
......
...@@ -695,7 +695,9 @@ class Program final : angle::NonCopyable, public LabeledObject ...@@ -695,7 +695,9 @@ class Program final : angle::NonCopyable, public LabeledObject
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, InfoLog &infoLog,
bool webglCompatibility); bool webglCompatibility,
sh::BlockType blockType,
GLuint maxCombinedInterfaceBlocks);
bool linkInterfaceBlocks(const Context *context, InfoLog &infoLog); bool linkInterfaceBlocks(const Context *context, InfoLog &infoLog);
bool linkVaryings(const Context *context, InfoLog &infoLog) const; bool linkVaryings(const Context *context, InfoLog &infoLog) const;
......
...@@ -58,8 +58,9 @@ TEST_P(ShaderStorageBufferTest31, MatchedBlockNameWithDifferentMemberType) ...@@ -58,8 +58,9 @@ TEST_P(ShaderStorageBufferTest31, MatchedBlockNameWithDifferentMemberType)
TEST_P(ShaderStorageBufferTest31, ExceedMaxVertexShaderStorageBlocks) TEST_P(ShaderStorageBufferTest31, ExceedMaxVertexShaderStorageBlocks)
{ {
std::ostringstream instanceCount; std::ostringstream instanceCount;
GLint maxVertexShaderStorageBlocks; GLint maxVertexShaderStorageBlocks = 0;
glGetIntegerv(GL_MAX_VERTEX_SHADER_STORAGE_BLOCKS, &maxVertexShaderStorageBlocks); glGetIntegerv(GL_MAX_VERTEX_SHADER_STORAGE_BLOCKS, &maxVertexShaderStorageBlocks);
EXPECT_GL_NO_ERROR();
instanceCount << maxVertexShaderStorageBlocks; instanceCount << maxVertexShaderStorageBlocks;
const std::string &vertexShaderSource = const std::string &vertexShaderSource =
...@@ -82,6 +83,50 @@ TEST_P(ShaderStorageBufferTest31, ExceedMaxVertexShaderStorageBlocks) ...@@ -82,6 +83,50 @@ TEST_P(ShaderStorageBufferTest31, ExceedMaxVertexShaderStorageBlocks)
EXPECT_EQ(0u, program); EXPECT_EQ(0u, program);
} }
// Linking should fail if the sum of the number of active shader storage blocks exceeds
// MAX_COMBINED_SHADER_STORAGE_BLOCKS.
// This case may generate linking error due to exceeding MAX_FRAGMENT_SHADER_STORAGE_BLOCKS.
TEST_P(ShaderStorageBufferTest31, ExceedMaxCombinedShaderStorageBlocks)
{
std::ostringstream vertexInstanceCount;
GLint maxVertexShaderStorageBlocks = 0;
glGetIntegerv(GL_MAX_VERTEX_SHADER_STORAGE_BLOCKS, &maxVertexShaderStorageBlocks);
vertexInstanceCount << maxVertexShaderStorageBlocks;
GLint maxCombinedShaderStorageBlocks = 0;
glGetIntegerv(GL_MAX_COMBINED_SHADER_STORAGE_BLOCKS, &maxCombinedShaderStorageBlocks);
EXPECT_GL_NO_ERROR();
std::ostringstream fragmentInstanceCount;
GLint fragmentShaderStorageBlocks =
maxCombinedShaderStorageBlocks - maxVertexShaderStorageBlocks + 1;
fragmentInstanceCount << fragmentShaderStorageBlocks;
const std::string &vertexShaderSource =
"#version 310 es\n"
"layout(shared) buffer blockName0 {\n"
" uint data;\n"
"} instance0[" +
vertexInstanceCount.str() +
"];\n"
"void main()\n"
"{\n"
"}\n";
const std::string &fragmentShaderSource =
"#version 310 es\n"
"layout(shared) buffer blockName1 {\n"
" uint data;\n"
"} instance1[" +
fragmentInstanceCount.str() +
"];\n"
"void main()\n"
"{\n"
"}\n";
GLuint program = CompileProgram(vertexShaderSource, fragmentShaderSource);
EXPECT_EQ(0u, program);
}
// Test shader storage buffer read write. // Test shader storage buffer read write.
TEST_P(ShaderStorageBufferTest31, ShaderStorageBufferReadWrite) TEST_P(ShaderStorageBufferTest31, ShaderStorageBufferReadWrite)
{ {
......
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