Commit 33b58ebb by Tim Van Patten Committed by Commit Bot

Vulkan: Give unsized arrays at least 1 entry

The function ShaderVariable::getNestedArraySize needs to return at least 1 entry for unsized arrays to ensure the shader buffer sizes are reported correctly. This also allows ANGLE to treat unsized arrays of structs and basic types the same way, allowing for the special treatment of unsized arrays in TraverseStructArrayVariable() to be removed. Bug: angleproject:3596 Test: dEQP-GLES31.functional.program_interface_query.shader_storage_block.buffer_data_size.* Change-Id: I3b2a3a68c25e0913b79e989d7c719b34ce9b75fd Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/1934952 Commit-Queue: Tim Van Patten <timvp@google.com> Reviewed-by: 's avatarCody Northrop <cnorthrop@google.com>
parent 2d5da029
......@@ -163,7 +163,15 @@ void ShaderVariable::indexIntoArray(unsigned int arrayIndex)
unsigned int ShaderVariable::getNestedArraySize(unsigned int arrayNestingIndex) const
{
ASSERT(arraySizes.size() > arrayNestingIndex);
return arraySizes[arraySizes.size() - 1u - arrayNestingIndex];
unsigned int arraySize = arraySizes[arraySizes.size() - 1u - arrayNestingIndex];
if (arraySize == 0)
{
// Unsized array, so give it at least 1 entry
arraySize = 1;
}
return arraySize;
}
unsigned int ShaderVariable::getBasicTypeElementCount() const
......
......@@ -82,8 +82,7 @@ void TraverseStructArrayVariable(const ShaderVariable &variable,
// Nested arrays are processed starting from outermost (arrayNestingIndex 0u) and ending at the
// innermost. We make a special case for unsized arrays.
const unsigned int currentArraySize = variable.getNestedArraySize(0);
unsigned int count = std::max(currentArraySize, 1u);
for (unsigned int arrayElement = 0u; arrayElement < count; ++arrayElement)
for (unsigned int arrayElement = 0u; arrayElement < currentArraySize; ++arrayElement)
{
visitor->enterArrayElement(variable, arrayElement);
ShaderVariable elementVar = variable;
......
......@@ -180,8 +180,10 @@
// Debug (test bug):
3590 SWIFTSHADER : dEQP-GLES31.functional.debug.negative_coverage.get_error.buffer.framebuffer_texture2d = FAIL
// Front-end query bugs:
3596 VULKAN : dEQP-GLES31.functional.program_interface_query.shader_storage_block.buffer_data_size.* = FAIL
// GLSL length() method returning number of bytes in an array instead of number of items
4098 SWIFTSHADER : dEQP-GLES31.functional.compute.basic.write_multiple_unsized_arr_multiple_groups = FAIL
4098 SWIFTSHADER : dEQP-GLES31.functional.compute.basic.write_multiple_unsized_arr_single_invocation = FAIL
// Not failing in last official run, but failed recently:
4110 SWIFTSHADER : dEQP-GLES31.functional.shaders.helper_invocation.* = FAIL
......
......@@ -2258,6 +2258,106 @@ void main()
EXPECT_GL_NO_ERROR();
}
// Verify the size of the buffer with unsized struct array is calculated correctly
TEST_P(ShaderStorageBufferTest31, BigStructUnsizedStructArraySize)
{
// TODO(http://anglebug.com/3596)
ANGLE_SKIP_TEST_IF(IsAMD() && IsWindows() && IsOpenGL());
constexpr char kComputeShaderSource[] =
R"(#version 310 es
layout (local_size_x=1) in;
struct S
{
mat4 m; // 4 vec4 = 16 floats
vec4 a[10]; // 10 vec4 = 40 floats
};
layout(binding=0) buffer B
{
vec4 precedingMember; // 4 floats
S precedingMemberUnsizedArray[]; // 56 floats
} b;
void main()
{
if (false)
{
b.precedingMember = vec4(1.0, 1.0, 1.0, 1.0);
}
}
)";
ANGLE_GL_COMPUTE_PROGRAM(program, kComputeShaderSource);
EXPECT_GL_NO_ERROR();
glUseProgram(program);
glDispatchCompute(1, 1, 1);
EXPECT_GL_NO_ERROR();
GLuint resourceIndex = glGetProgramResourceIndex(program, GL_SHADER_STORAGE_BLOCK, "B");
EXPECT_GL_NO_ERROR();
EXPECT_NE(resourceIndex, 0xFFFFFFFF);
GLenum property = GL_BUFFER_DATA_SIZE;
GLint queryData = -1;
glGetProgramResourceiv(program, GL_SHADER_STORAGE_BLOCK, resourceIndex, 1, &property, 1,
nullptr, &queryData);
EXPECT_GL_NO_ERROR();
// 60 * sizeof(float) = 240
// Vulkan rounds up to the required buffer alignment, so >= 240
EXPECT_GE(queryData, 240);
}
// Verify the size of the buffer with unsized float array is calculated correctly
TEST_P(ShaderStorageBufferTest31, BigStructUnsizedFloatArraySize)
{
// TODO(http://anglebug.com/3596)
ANGLE_SKIP_TEST_IF(IsAMD() && IsWindows() && IsOpenGL());
constexpr char kComputeShaderSource[] =
R"(#version 310 es
layout (local_size_x=1) in;
layout(binding=0) buffer B
{
vec4 precedingMember; // 4 floats
float precedingMemberUnsizedArray[]; // "1" float
} b;
void main()
{
if (false)
{
b.precedingMember = vec4(1.0, 1.0, 1.0, 1.0);
}
}
)";
ANGLE_GL_COMPUTE_PROGRAM(program, kComputeShaderSource);
EXPECT_GL_NO_ERROR();
glUseProgram(program);
glDispatchCompute(1, 1, 1);
EXPECT_GL_NO_ERROR();
GLuint resourceIndex = glGetProgramResourceIndex(program, GL_SHADER_STORAGE_BLOCK, "B");
EXPECT_GL_NO_ERROR();
EXPECT_NE(resourceIndex, 0xFFFFFFFF);
GLenum property = GL_BUFFER_DATA_SIZE;
GLint queryData = -1;
glGetProgramResourceiv(program, GL_SHADER_STORAGE_BLOCK, resourceIndex, 1, &property, 1,
nullptr, &queryData);
EXPECT_GL_NO_ERROR();
// 5 * sizeof(float) = 20
// Vulkan rounds up to the required buffer alignment, so >= 20
EXPECT_GE(queryData, 20);
}
ANGLE_INSTANTIATE_TEST_ES31(ShaderStorageBufferTest31);
} // namespace
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