Commit bb3255b5 by Jiawei Shao Committed by Commit Bot

Remove redundant computations on combined interface block counts

This patch intends to remove redundant computations on combined interface block counts in ValidateGraphicsInterfaceBlocks. In this patch, we compute and check the number of combined interface blocks by the result of ValidateInterfaceBlocksCount directly instead of re-compute it, and if the check on max combined interface blocks failed, Program::link() can early return without entering ValidateGraphicsInterfaceBlocks. BUG=angleproject:2345 Change-Id: I7573f7c645993b4d75230a8471203a305127f2a3 Reviewed-on: https://chromium-review.googlesource.com/1031852Reviewed-by: 's avatarJiajia Qin <jiajia.qin@intel.com> Reviewed-by: 's avatarJamie Madill <jmadill@chromium.org> Reviewed-by: 's avatarCorentin Wallez <cwallez@chromium.org> Commit-Queue: Jiawei Shao <jiawei.shao@intel.com>
parent c6f82872
...@@ -259,14 +259,15 @@ bool ValidateInterfaceBlocksCount(GLuint maxInterfaceBlocks, ...@@ -259,14 +259,15 @@ bool ValidateInterfaceBlocksCount(GLuint maxInterfaceBlocks,
const std::vector<sh::InterfaceBlock> &interfaceBlocks, const std::vector<sh::InterfaceBlock> &interfaceBlocks,
ShaderType shaderType, ShaderType shaderType,
sh::BlockType blockType, sh::BlockType blockType,
GLuint *combinedInterfaceBlocksCount,
InfoLog &infoLog) InfoLog &infoLog)
{ {
GLuint blockCount = 0; GLuint blockCount = 0;
for (const sh::InterfaceBlock &block : interfaceBlocks) for (const sh::InterfaceBlock &block : interfaceBlocks)
{ {
if (block.active || block.layout != sh::BLOCKLAYOUT_PACKED) if (IsActiveInterfaceBlock(block))
{ {
blockCount += (block.arraySize ? block.arraySize : 1); blockCount += std::max(block.arraySize, 1u);
if (blockCount > maxInterfaceBlocks) if (blockCount > maxInterfaceBlocks)
{ {
LogInterfaceBlocksExceedLimit(infoLog, shaderType, blockType, maxInterfaceBlocks); LogInterfaceBlocksExceedLimit(infoLog, shaderType, blockType, maxInterfaceBlocks);
...@@ -274,6 +275,18 @@ bool ValidateInterfaceBlocksCount(GLuint maxInterfaceBlocks, ...@@ -274,6 +275,18 @@ bool ValidateInterfaceBlocksCount(GLuint maxInterfaceBlocks,
} }
} }
} }
// [OpenGL ES 3.1] Chapter 7.6.2 Page 105:
// If a uniform block is used by multiple shader stages, each such use counts separately
// against this combined limit.
// [OpenGL ES 3.1] Chapter 7.8 Page 111:
// If a shader storage block in a program is referenced by multiple shaders, each such
// reference counts separately against this combined limit.
if (combinedInterfaceBlocksCount)
{
*combinedInterfaceBlocksCount += blockCount;
}
return true; return true;
} }
...@@ -496,18 +509,13 @@ using InterfaceBlockMap = std::map<std::string, ShaderInterfaceBlock>; ...@@ -496,18 +509,13 @@ using InterfaceBlockMap = std::map<std::string, ShaderInterfaceBlock>;
void InitializeInterfaceBlockMap(const std::vector<sh::InterfaceBlock> &interfaceBlocks, void InitializeInterfaceBlockMap(const std::vector<sh::InterfaceBlock> &interfaceBlocks,
ShaderType shaderType, ShaderType shaderType,
InterfaceBlockMap *linkedInterfaceBlocks, InterfaceBlockMap *linkedInterfaceBlocks)
GLuint *blockCount)
{ {
ASSERT(linkedInterfaceBlocks && blockCount); ASSERT(linkedInterfaceBlocks);
for (const sh::InterfaceBlock &interfaceBlock : interfaceBlocks) for (const sh::InterfaceBlock &interfaceBlock : interfaceBlocks)
{ {
(*linkedInterfaceBlocks)[interfaceBlock.name] = std::make_pair(shaderType, &interfaceBlock); (*linkedInterfaceBlocks)[interfaceBlock.name] = std::make_pair(shaderType, &interfaceBlock);
if (IsActiveInterfaceBlock(interfaceBlock))
{
*blockCount += std::max(interfaceBlock.arraySize, 1u);
}
} }
} }
...@@ -516,10 +524,9 @@ bool ValidateGraphicsInterfaceBlocksPerShader( ...@@ -516,10 +524,9 @@ bool ValidateGraphicsInterfaceBlocksPerShader(
ShaderType shaderType, ShaderType shaderType,
bool webglCompatibility, bool webglCompatibility,
InterfaceBlockMap *linkedBlocks, InterfaceBlockMap *linkedBlocks,
GLuint *combinedInterfaceBlockCount,
InfoLog &infoLog) InfoLog &infoLog)
{ {
ASSERT(linkedBlocks && combinedInterfaceBlockCount); ASSERT(linkedBlocks);
for (const sh::InterfaceBlock &block : interfaceBlocksToLink) for (const sh::InterfaceBlock &block : interfaceBlocksToLink)
{ {
...@@ -542,17 +549,6 @@ bool ValidateGraphicsInterfaceBlocksPerShader( ...@@ -542,17 +549,6 @@ bool ValidateGraphicsInterfaceBlocksPerShader(
{ {
(*linkedBlocks)[block.name] = std::make_pair(shaderType, &block); (*linkedBlocks)[block.name] = std::make_pair(shaderType, &block);
} }
// [OpenGL ES 3.1] Chapter 7.6.2 Page 105:
// If a uniform block is used by multiple shader stages, each such use counts separately
// against this combined limit.
// [OpenGL ES 3.1] Chapter 7.8 Page 111:
// If a shader storage block in a program is referenced by multiple shaders, each such
// reference counts separately against this combined limit.
if (IsActiveInterfaceBlock(block))
{
*combinedInterfaceBlockCount += std::max(block.arraySize, 1u);
}
} }
return true; return true;
...@@ -561,14 +557,11 @@ bool ValidateGraphicsInterfaceBlocksPerShader( ...@@ -561,14 +557,11 @@ bool ValidateGraphicsInterfaceBlocksPerShader(
bool ValidateGraphicsInterfaceBlocks( bool ValidateGraphicsInterfaceBlocks(
const ShaderMap<const std::vector<sh::InterfaceBlock> *> &shaderInterfaceBlocks, const ShaderMap<const std::vector<sh::InterfaceBlock> *> &shaderInterfaceBlocks,
InfoLog &infoLog, InfoLog &infoLog,
bool webglCompatibility, bool webglCompatibility)
sh::BlockType blockType,
GLuint maxCombinedInterfaceBlocks)
{ {
// Check that interface blocks defined in the graphics shaders are identical // Check that interface blocks defined in the graphics shaders are identical
InterfaceBlockMap linkedInterfaceBlocks; InterfaceBlockMap linkedInterfaceBlocks;
GLuint blockCount = 0u;
bool interfaceBlockMapInitialized = false; bool interfaceBlockMapInitialized = false;
for (ShaderType shaderType : kAllGraphicsShaderTypes) for (ShaderType shaderType : kAllGraphicsShaderTypes)
...@@ -581,36 +574,17 @@ bool ValidateGraphicsInterfaceBlocks( ...@@ -581,36 +574,17 @@ bool ValidateGraphicsInterfaceBlocks(
if (!interfaceBlockMapInitialized) if (!interfaceBlockMapInitialized)
{ {
InitializeInterfaceBlockMap(*shaderInterfaceBlocks[shaderType], shaderType, InitializeInterfaceBlockMap(*shaderInterfaceBlocks[shaderType], shaderType,
&linkedInterfaceBlocks, &blockCount); &linkedInterfaceBlocks);
interfaceBlockMapInitialized = true; interfaceBlockMapInitialized = true;
} }
else if (!ValidateGraphicsInterfaceBlocksPerShader( else if (!ValidateGraphicsInterfaceBlocksPerShader(*shaderInterfaceBlocks[shaderType],
*shaderInterfaceBlocks[shaderType], shaderType, webglCompatibility, shaderType, webglCompatibility,
&linkedInterfaceBlocks, &blockCount, infoLog)) &linkedInterfaceBlocks, infoLog))
{ {
return false; return false;
} }
} }
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;
} }
...@@ -2816,7 +2790,7 @@ bool Program::linkInterfaceBlocks(const Context *context, InfoLog &infoLog) ...@@ -2816,7 +2790,7 @@ bool Program::linkInterfaceBlocks(const Context *context, InfoLog &infoLog)
if (!ValidateInterfaceBlocksCount(caps.maxComputeUniformBlocks, computeUniformBlocks, if (!ValidateInterfaceBlocksCount(caps.maxComputeUniformBlocks, computeUniformBlocks,
ShaderType::Compute, sh::BlockType::BLOCK_UNIFORM, ShaderType::Compute, sh::BlockType::BLOCK_UNIFORM,
infoLog)) nullptr, infoLog))
{ {
return false; return false;
} }
...@@ -2824,7 +2798,7 @@ bool Program::linkInterfaceBlocks(const Context *context, InfoLog &infoLog) ...@@ -2824,7 +2798,7 @@ bool Program::linkInterfaceBlocks(const Context *context, InfoLog &infoLog)
const auto &computeShaderStorageBlocks = computeShader.getShaderStorageBlocks(context); const auto &computeShaderStorageBlocks = computeShader.getShaderStorageBlocks(context);
if (!ValidateInterfaceBlocksCount(caps.maxComputeShaderStorageBlocks, if (!ValidateInterfaceBlocksCount(caps.maxComputeShaderStorageBlocks,
computeShaderStorageBlocks, ShaderType::Compute, computeShaderStorageBlocks, ShaderType::Compute,
sh::BlockType::BLOCK_BUFFER, infoLog)) sh::BlockType::BLOCK_BUFFER, nullptr, infoLog))
{ {
return false; return false;
} }
...@@ -2836,6 +2810,7 @@ bool Program::linkInterfaceBlocks(const Context *context, InfoLog &infoLog) ...@@ -2836,6 +2810,7 @@ bool Program::linkInterfaceBlocks(const Context *context, InfoLog &infoLog)
maxShaderUniformBlocks[gl::ShaderType::Fragment] = caps.maxFragmentUniformBlocks; maxShaderUniformBlocks[gl::ShaderType::Fragment] = caps.maxFragmentUniformBlocks;
maxShaderUniformBlocks[gl::ShaderType::Geometry] = caps.maxGeometryUniformBlocks; maxShaderUniformBlocks[gl::ShaderType::Geometry] = caps.maxGeometryUniformBlocks;
GLuint combinedUniformBlocksCount = 0u;
ShaderMap<const std::vector<sh::InterfaceBlock> *> graphicsShaderUniformBlocks = {}; ShaderMap<const std::vector<sh::InterfaceBlock> *> graphicsShaderUniformBlocks = {};
for (ShaderType shaderType : kAllGraphicsShaderTypes) for (ShaderType shaderType : kAllGraphicsShaderTypes)
{ {
...@@ -2847,7 +2822,8 @@ bool Program::linkInterfaceBlocks(const Context *context, InfoLog &infoLog) ...@@ -2847,7 +2822,8 @@ bool Program::linkInterfaceBlocks(const Context *context, InfoLog &infoLog)
const auto &uniformBlocks = mState.mAttachedShaders[shaderType]->getUniformBlocks(context); const auto &uniformBlocks = mState.mAttachedShaders[shaderType]->getUniformBlocks(context);
if (!ValidateInterfaceBlocksCount(maxShaderUniformBlocks[shaderType], uniformBlocks, if (!ValidateInterfaceBlocksCount(maxShaderUniformBlocks[shaderType], uniformBlocks,
shaderType, sh::BlockType::BLOCK_UNIFORM, infoLog)) shaderType, sh::BlockType::BLOCK_UNIFORM,
&combinedUniformBlocksCount, infoLog))
{ {
return false; return false;
} }
...@@ -2855,10 +2831,16 @@ bool Program::linkInterfaceBlocks(const Context *context, InfoLog &infoLog) ...@@ -2855,10 +2831,16 @@ bool Program::linkInterfaceBlocks(const Context *context, InfoLog &infoLog)
graphicsShaderUniformBlocks[shaderType] = &uniformBlocks; graphicsShaderUniformBlocks[shaderType] = &uniformBlocks;
} }
if (combinedUniformBlocksCount > caps.maxCombinedUniformBlocks)
{
infoLog << "The sum of the number of active uniform blocks exceeds "
"MAX_COMBINED_UNIFORM_BLOCKS ("
<< caps.maxCombinedUniformBlocks << ").";
return false;
}
bool webglCompatibility = context->getExtensions().webglCompatibility; bool webglCompatibility = context->getExtensions().webglCompatibility;
if (!ValidateGraphicsInterfaceBlocks(graphicsShaderUniformBlocks, infoLog, webglCompatibility, if (!ValidateGraphicsInterfaceBlocks(graphicsShaderUniformBlocks, infoLog, webglCompatibility))
sh::BlockType::BLOCK_UNIFORM,
caps.maxCombinedUniformBlocks))
{ {
return false; return false;
} }
...@@ -2870,6 +2852,7 @@ bool Program::linkInterfaceBlocks(const Context *context, InfoLog &infoLog) ...@@ -2870,6 +2852,7 @@ bool Program::linkInterfaceBlocks(const Context *context, InfoLog &infoLog)
maxShaderStorageBlocks[ShaderType::Fragment] = caps.maxFragmentShaderStorageBlocks; maxShaderStorageBlocks[ShaderType::Fragment] = caps.maxFragmentShaderStorageBlocks;
maxShaderStorageBlocks[ShaderType::Geometry] = caps.maxGeometryShaderStorageBlocks; maxShaderStorageBlocks[ShaderType::Geometry] = caps.maxGeometryShaderStorageBlocks;
GLuint combinedShaderStorageBlocksCount = 0u;
ShaderMap<const std::vector<sh::InterfaceBlock> *> graphicsShaderStorageBlocks = {}; ShaderMap<const std::vector<sh::InterfaceBlock> *> graphicsShaderStorageBlocks = {};
for (ShaderType shaderType : kAllGraphicsShaderTypes) for (ShaderType shaderType : kAllGraphicsShaderTypes)
{ {
...@@ -2880,9 +2863,9 @@ bool Program::linkInterfaceBlocks(const Context *context, InfoLog &infoLog) ...@@ -2880,9 +2863,9 @@ bool Program::linkInterfaceBlocks(const Context *context, InfoLog &infoLog)
} }
const auto &shaderStorageBlocks = shader->getShaderStorageBlocks(context); const auto &shaderStorageBlocks = shader->getShaderStorageBlocks(context);
if (!ValidateInterfaceBlocksCount(maxShaderStorageBlocks[shaderType], if (!ValidateInterfaceBlocksCount(
shaderStorageBlocks, shaderType, maxShaderStorageBlocks[shaderType], shaderStorageBlocks, shaderType,
sh::BlockType::BLOCK_BUFFER, infoLog)) sh::BlockType::BLOCK_BUFFER, &combinedShaderStorageBlocksCount, infoLog))
{ {
return false; return false;
} }
...@@ -2890,9 +2873,16 @@ bool Program::linkInterfaceBlocks(const Context *context, InfoLog &infoLog) ...@@ -2890,9 +2873,16 @@ bool Program::linkInterfaceBlocks(const Context *context, InfoLog &infoLog)
graphicsShaderStorageBlocks[shaderType] = &shaderStorageBlocks; graphicsShaderStorageBlocks[shaderType] = &shaderStorageBlocks;
} }
if (combinedShaderStorageBlocksCount > caps.maxCombinedShaderStorageBlocks)
{
infoLog << "The sum of the number of active shader storage blocks exceeds "
"MAX_COMBINED_SHADER_STORAGE_BLOCKS ("
<< caps.maxCombinedShaderStorageBlocks << ").";
return false;
}
if (!ValidateGraphicsInterfaceBlocks(graphicsShaderStorageBlocks, infoLog, if (!ValidateGraphicsInterfaceBlocks(graphicsShaderStorageBlocks, infoLog,
webglCompatibility, sh::BlockType::BLOCK_BUFFER, webglCompatibility))
caps.maxCombinedShaderStorageBlocks))
{ {
return false; return false;
} }
......
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