Commit d2cb7cec by Jiawei Shao Committed by Commit Bot

ES31: Fix wrong method of computing combined interface blocks

This patch fixes a bug in the method of validating the number of combined interface blocks in currenct ANGLE implementation. When a resource (uniform block, shader storage block, image, atomic counter buffer, atomic counter) is used by multiple shader stages, each such use counts separately against the combined resource limit. This patch also fixes an unexpected link error in a related test by skipping the test when the number of ssbos exceeds the resouorce limit. BUG=angleproject:1951 TEST=angle_end2end_tests Change-Id: I0de439a412148e0d5ebef3c27d20e0cbd536175a Reviewed-on: https://chromium-review.googlesource.com/945143 Commit-Queue: Corentin Wallez <cwallez@chromium.org> Reviewed-by: 's avatarJiajia Qin <jiajia.qin@intel.com> Reviewed-by: 's avatarGeoff Lang <geofflang@chromium.org> Reviewed-by: 's avatarCorentin Wallez <cwallez@chromium.org>
parent e05ffdd1
...@@ -2660,13 +2660,17 @@ bool Program::ValidateGraphicsInterfaceBlocks( ...@@ -2660,13 +2660,17 @@ bool Program::ValidateGraphicsInterfaceBlocks(
return false; return false;
} }
} }
else
// [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 (fragmentInterfaceBlock.staticUse ||
fragmentInterfaceBlock.layout != sh::BLOCKLAYOUT_PACKED)
{ {
if (fragmentInterfaceBlock.staticUse || blockCount += std::max(fragmentInterfaceBlock.arraySize, 1u);
fragmentInterfaceBlock.layout != sh::BLOCKLAYOUT_PACKED)
{
blockCount += std::max(fragmentInterfaceBlock.arraySize, 1u);
}
} }
} }
......
...@@ -85,7 +85,6 @@ TEST_P(ShaderStorageBufferTest31, ExceedMaxVertexShaderStorageBlocks) ...@@ -85,7 +85,6 @@ TEST_P(ShaderStorageBufferTest31, ExceedMaxVertexShaderStorageBlocks)
// Linking should fail if the sum of the number of active shader storage blocks exceeds // Linking should fail if the sum of the number of active shader storage blocks exceeds
// MAX_COMBINED_SHADER_STORAGE_BLOCKS. // MAX_COMBINED_SHADER_STORAGE_BLOCKS.
// This case may generate linking error due to exceeding MAX_FRAGMENT_SHADER_STORAGE_BLOCKS.
TEST_P(ShaderStorageBufferTest31, ExceedMaxCombinedShaderStorageBlocks) TEST_P(ShaderStorageBufferTest31, ExceedMaxCombinedShaderStorageBlocks)
{ {
std::ostringstream vertexInstanceCount; std::ostringstream vertexInstanceCount;
...@@ -93,13 +92,25 @@ TEST_P(ShaderStorageBufferTest31, ExceedMaxCombinedShaderStorageBlocks) ...@@ -93,13 +92,25 @@ TEST_P(ShaderStorageBufferTest31, ExceedMaxCombinedShaderStorageBlocks)
glGetIntegerv(GL_MAX_VERTEX_SHADER_STORAGE_BLOCKS, &maxVertexShaderStorageBlocks); glGetIntegerv(GL_MAX_VERTEX_SHADER_STORAGE_BLOCKS, &maxVertexShaderStorageBlocks);
vertexInstanceCount << maxVertexShaderStorageBlocks; vertexInstanceCount << maxVertexShaderStorageBlocks;
GLint maxFragmentShaderStorageBlocks = 0;
glGetIntegerv(GL_MAX_FRAGMENT_SHADER_STORAGE_BLOCKS, &maxFragmentShaderStorageBlocks);
GLint maxCombinedShaderStorageBlocks = 0; GLint maxCombinedShaderStorageBlocks = 0;
glGetIntegerv(GL_MAX_COMBINED_SHADER_STORAGE_BLOCKS, &maxCombinedShaderStorageBlocks); glGetIntegerv(GL_MAX_COMBINED_SHADER_STORAGE_BLOCKS, &maxCombinedShaderStorageBlocks);
EXPECT_GL_NO_ERROR(); EXPECT_GL_NO_ERROR();
std::ostringstream fragmentInstanceCount; ASSERT_GE(maxCombinedShaderStorageBlocks, maxVertexShaderStorageBlocks);
ASSERT_GE(maxCombinedShaderStorageBlocks, maxFragmentShaderStorageBlocks);
// As SPEC allows MAX_VERTEX_SHADER_STORAGE_BLOCKS and MAX_FRAGMENT_SHADER_STORAGE_BLOCKS to be
// 0, in this situation we should skip this test to prevent these unexpected compile errors.
ANGLE_SKIP_TEST_IF(maxVertexShaderStorageBlocks == 0 || maxFragmentShaderStorageBlocks == 0);
GLint fragmentShaderStorageBlocks = GLint fragmentShaderStorageBlocks =
maxCombinedShaderStorageBlocks - maxVertexShaderStorageBlocks + 1; maxCombinedShaderStorageBlocks - maxVertexShaderStorageBlocks + 1;
ANGLE_SKIP_TEST_IF(fragmentShaderStorageBlocks > maxFragmentShaderStorageBlocks);
std::ostringstream fragmentInstanceCount;
fragmentInstanceCount << fragmentShaderStorageBlocks; fragmentInstanceCount << fragmentShaderStorageBlocks;
const std::string &vertexShaderSource = const std::string &vertexShaderSource =
......
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