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(
const std::vector<sh::InterfaceBlock> &vertexInterfaceBlocks,
const std::vector<sh::InterfaceBlock> &fragmentInterfaceBlocks,
InfoLog &infoLog,
bool webglCompatibility)
bool webglCompatibility,
sh::BlockType blockType,
GLuint maxCombinedInterfaceBlocks)
{
// Check that interface blocks defined in the vertex and fragment shaders are identical
typedef std::map<std::string, const sh::InterfaceBlock *> InterfaceBlockMap;
InterfaceBlockMap linkedInterfaceBlocks;
GLuint blockCount = 0;
for (const sh::InterfaceBlock &vertexInterfaceBlock : vertexInterfaceBlocks)
{
linkedInterfaceBlocks[vertexInterfaceBlock.name] = &vertexInterfaceBlock;
if (vertexInterfaceBlock.staticUse || vertexInterfaceBlock.layout != sh::BLOCKLAYOUT_PACKED)
{
blockCount += std::max(vertexInterfaceBlock.arraySize, 1u);
}
}
for (const sh::InterfaceBlock &fragmentInterfaceBlock : fragmentInterfaceBlocks)
......@@ -2538,8 +2545,34 @@ bool Program::ValidateGraphicsInterfaceBlocks(
return false;
}
}
// TODO(jiajia.qin@intel.com): Add
// MAX_COMBINED_UNIFORM_BLOCKS/MAX_COMBINED_SHADER_STORAGE_BLOCKS validation.
else
{
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;
}
......@@ -2596,7 +2629,8 @@ bool Program::linkInterfaceBlocks(const Context *context, InfoLog &infoLog)
bool webglCompatibility = context->getExtensions().webglCompatibility;
if (!ValidateGraphicsInterfaceBlocks(vertexUniformBlocks, fragmentUniformBlocks, infoLog,
webglCompatibility))
webglCompatibility, sh::BlockType::BLOCK_UNIFORM,
caps.maxCombinedUniformBlocks))
{
return false;
}
......@@ -2624,8 +2658,9 @@ bool Program::linkInterfaceBlocks(const Context *context, InfoLog &infoLog)
return false;
}
if (!ValidateGraphicsInterfaceBlocks(vertexShaderStorageBlocks, fragmentShaderStorageBlocks,
infoLog, webglCompatibility))
if (!ValidateGraphicsInterfaceBlocks(
vertexShaderStorageBlocks, fragmentShaderStorageBlocks, infoLog, webglCompatibility,
sh::BlockType::BLOCK_BUFFER, caps.maxCombinedShaderStorageBlocks))
{
return false;
}
......
......@@ -695,7 +695,9 @@ class Program final : angle::NonCopyable, public LabeledObject
const std::vector<sh::InterfaceBlock> &vertexInterfaceBlocks,
const std::vector<sh::InterfaceBlock> &fragmentInterfaceBlocks,
InfoLog &infoLog,
bool webglCompatibility);
bool webglCompatibility,
sh::BlockType blockType,
GLuint maxCombinedInterfaceBlocks);
bool linkInterfaceBlocks(const Context *context, InfoLog &infoLog);
bool linkVaryings(const Context *context, InfoLog &infoLog) const;
......
......@@ -58,8 +58,9 @@ TEST_P(ShaderStorageBufferTest31, MatchedBlockNameWithDifferentMemberType)
TEST_P(ShaderStorageBufferTest31, ExceedMaxVertexShaderStorageBlocks)
{
std::ostringstream instanceCount;
GLint maxVertexShaderStorageBlocks;
GLint maxVertexShaderStorageBlocks = 0;
glGetIntegerv(GL_MAX_VERTEX_SHADER_STORAGE_BLOCKS, &maxVertexShaderStorageBlocks);
EXPECT_GL_NO_ERROR();
instanceCount << maxVertexShaderStorageBlocks;
const std::string &vertexShaderSource =
......@@ -82,6 +83,50 @@ TEST_P(ShaderStorageBufferTest31, ExceedMaxVertexShaderStorageBlocks)
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_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