ES31: Add BUFFER_VARIABLE and SHADER_STORAGE_BLOCK program interfaces
This patch collects the shader storage block members information.
It implements getShaderStorageBlockMemberInfo and getShaderStorageBlockSize
for OpenGL backend. Meanwhile, it implements BUFFER_VARIABLE and SHADER_STORAGE_BLOCK
interfaces for program query.
BUG=angleproject:1920
TEST=angle_end2end_tests:ProgramInterfaceTest*
dEQP-GLES31.functional.layout_binding.ssbo*
dEQP-GLES31.functional.compute.basic.empty
dEQP-GLES31.functional.compute.basic.ssbo_rw*
dEQP-GLES31.functional.compute.basic.ssbo_local_barrier*
dEQP-GLES31.functional.compute.basic.copy_image_to_ssbo_small
dEQP-GLES31.functional.compute.basic.copy_ssbo_multiple_groups
dEQP-GLES31.functional.compute.basic.copy_ssbo_multiple_invocations
dEQP-GLES31.functional.compute.basic.copy_ssbo_single_invocation
dEQP-GLES31.functional.compute.basic.copy_ssbo_to_image_small
dEQP-GLES31.functional.compute.basic.shared_var*
dEQP-GLES31.functional.compute.basic.ubo_to_ssbo*
dEQP-GLES31.functional.compute.basic.write_multiple_arr*
dEQP-GLES31.functional.compute.shared_var.basic_type.*
dEQP-GLES31.functional.compute.shared_var.work_group_size.*
dEQP-GLES31.functional.atomic_counter.*
Change-Id: Ie8b81fde5a2e919aab77adb3d137c9ff2f193409
Reviewed-on: https://chromium-review.googlesource.com/712235
Reviewed-by: Olli Etuaho <oetuaho@nvidia.com>
Reviewed-by: Jamie Madill <jmadill@chromium.org>
Commit-Queue: Jamie Madill <jmadill@chromium.org>
diff --git a/src/libANGLE/ProgramLinkedResources.cpp b/src/libANGLE/ProgramLinkedResources.cpp
index a7f64d6..7a2a5db 100644
--- a/src/libANGLE/ProgramLinkedResources.cpp
+++ b/src/libANGLE/ProgramLinkedResources.cpp
@@ -660,6 +660,7 @@
if (block.name == priorBlock.name)
{
priorBlock.setStaticUse(shaderType, true);
+ // TODO(jiajia.qin@intel.com): update the block members static use.
}
}
}
@@ -678,7 +679,9 @@
const std::vector<VarT> &fields,
const std::string &prefix,
const std::string &mappedPrefix,
- int blockIndex) const
+ int blockIndex,
+ bool outsideTopLevelArray,
+ int topLevelArraySize) const
{
for (const VarT &field : fields)
{
@@ -689,14 +692,26 @@
if (field.isStruct())
{
- for (unsigned int arrayElement = 0; arrayElement < field.elementCount(); arrayElement++)
+ int nextArraySize = topLevelArraySize;
+ unsigned int elementCount = field.elementCount();
+
+ if (outsideTopLevelArray)
+ {
+ nextArraySize = elementCount;
+ // In OpenGL ES 3.10 spec, session 7.3.1.1 'For an active shader storage block
+ // member declared as an array of an aggregate type, an entry will be generated only
+ // for the first array element, regardless of its type.'
+ elementCount = 1;
+ }
+
+ for (unsigned int arrayElement = 0; arrayElement < elementCount; arrayElement++)
{
const std::string elementName =
fullName + (field.isArray() ? ArrayString(arrayElement) : "");
const std::string elementMappedName =
fullMappedName + (field.isArray() ? ArrayString(arrayElement) : "");
defineBlockMembers(getMemberInfo, field.fields, elementName, elementMappedName,
- blockIndex);
+ blockIndex, false, nextArraySize);
}
}
else
@@ -714,7 +729,8 @@
fullMappedName += "[0]";
}
- defineBlockMember(field, fullName, fullMappedName, blockIndex, memberInfo);
+ defineBlockMember(field, fullName, fullMappedName, blockIndex, memberInfo,
+ topLevelArraySize);
}
}
}
@@ -728,11 +744,12 @@
std::vector<unsigned int> blockIndexes;
int blockIndex = static_cast<int>(mBlocksOut->size());
- // Track the first and last uniform index to determine the range of active uniforms in the
- // block.
+ // Track the first and last block member index to determine the range of active block members in
+ // the block.
size_t firstBlockMemberIndex = getCurrentBlockMemberIndex();
defineBlockMembers(getMemberInfo, interfaceBlock.fields, interfaceBlock.fieldPrefix(),
- interfaceBlock.fieldMappedPrefix(), blockIndex);
+ interfaceBlock.fieldMappedPrefix(), blockIndex,
+ interfaceBlock.blockType == sh::BlockType::BLOCK_BUFFER, 1);
size_t lastBlockMemberIndex = getCurrentBlockMemberIndex();
for (size_t blockMemberIndex = firstBlockMemberIndex; blockMemberIndex < lastBlockMemberIndex;
@@ -748,23 +765,18 @@
for (unsigned int arrayElement = 0; arrayElement < interfaceBlock.elementCount();
++arrayElement)
{
- // We don't currently have the getBlockSize implemented for SSBOs.
- // TODO(jiajia.qin@intel.com): Remove the if when we have getBlockSize for SSBOs.
- if (interfaceBlock.blockType == sh::BlockType::BLOCK_UNIFORM)
+ std::string blockArrayName = interfaceBlock.name;
+ std::string blockMappedArrayName = interfaceBlock.mappedName;
+ if (interfaceBlock.isArray())
{
- std::string blockArrayName = interfaceBlock.name;
- std::string blockMappedArrayName = interfaceBlock.mappedName;
- if (interfaceBlock.isArray())
- {
- blockArrayName += ArrayString(arrayElement);
- blockMappedArrayName += ArrayString(arrayElement);
- }
+ blockArrayName += ArrayString(arrayElement);
+ blockMappedArrayName += ArrayString(arrayElement);
+ }
- // Don't define this block at all if it's not active in the implementation.
- if (!getBlockSize(blockArrayName, blockMappedArrayName, &blockSize))
- {
- continue;
- }
+ // Don't define this block at all if it's not active in the implementation.
+ if (!getBlockSize(blockArrayName, blockMappedArrayName, &blockSize))
+ {
+ continue;
}
InterfaceBlock block(interfaceBlock.name, interfaceBlock.mappedName,
@@ -795,11 +807,13 @@
const std::string &fullName,
const std::string &fullMappedName,
int blockIndex,
- const sh::BlockMemberInfo &memberInfo) const
+ const sh::BlockMemberInfo &memberInfo,
+ int /* topLevelArraySize */) const
{
LinkedUniform newUniform(field.type, field.precision, fullName, field.arraySize, -1, -1, -1,
blockIndex, memberInfo);
newUniform.mappedName = fullMappedName;
+ // TODO(jiajia.qin@intel.com): update the block memeber static use.
// Since block uniforms have no location, we don't need to store them in the uniform locations
// list.
@@ -812,8 +826,9 @@
}
// ShaderStorageBlockLinker implementation.
-ShaderStorageBlockLinker::ShaderStorageBlockLinker(std::vector<InterfaceBlock> *blocksOut)
- : InterfaceBlockLinker(blocksOut)
+ShaderStorageBlockLinker::ShaderStorageBlockLinker(std::vector<InterfaceBlock> *blocksOut,
+ std::vector<BufferVariable> *bufferVariablesOut)
+ : InterfaceBlockLinker(blocksOut), mBufferVariablesOut(bufferVariablesOut)
{
}
@@ -825,15 +840,22 @@
const std::string &fullName,
const std::string &fullMappedName,
int blockIndex,
- const sh::BlockMemberInfo &memberInfo) const
+ const sh::BlockMemberInfo &memberInfo,
+ int topLevelArraySize) const
{
- // TODO(jiajia.qin@intel.com): Add buffer variables support.
+ BufferVariable newBufferVariable(field.type, field.precision, fullName, field.arraySize,
+ blockIndex, memberInfo);
+ newBufferVariable.mappedName = fullMappedName;
+ // TODO(jiajia.qin@intel.com): update the block memeber static use.
+
+ newBufferVariable.topLevelArraySize = topLevelArraySize;
+
+ mBufferVariablesOut->push_back(newBufferVariable);
}
size_t ShaderStorageBlockLinker::getCurrentBlockMemberIndex() const
{
- // TODO(jiajia.qin@intel.com): Add buffer variables support.
- return 0;
+ return mBufferVariablesOut->size();
}
} // namespace gl