summaryrefslogtreecommitdiffstats
path: root/src/3rdparty/angle/src/compiler/translator/blocklayout.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/3rdparty/angle/src/compiler/translator/blocklayout.cpp')
-rw-r--r--src/3rdparty/angle/src/compiler/translator/blocklayout.cpp191
1 files changed, 173 insertions, 18 deletions
diff --git a/src/3rdparty/angle/src/compiler/translator/blocklayout.cpp b/src/3rdparty/angle/src/compiler/translator/blocklayout.cpp
index ba6322848e..fd8c450c20 100644
--- a/src/3rdparty/angle/src/compiler/translator/blocklayout.cpp
+++ b/src/3rdparty/angle/src/compiler/translator/blocklayout.cpp
@@ -15,24 +15,105 @@
namespace sh
{
-BlockLayoutEncoder::BlockLayoutEncoder()
- : mCurrentOffset(0)
+namespace
{
+bool IsRowMajorLayout(const InterfaceBlockField &var)
+{
+ return var.isRowMajorLayout;
+}
+
+bool IsRowMajorLayout(const ShaderVariable &var)
+{
+ return false;
+}
+
+template <typename VarT>
+void GetUniformBlockStructMemberInfo(const std::vector<VarT> &fields,
+ const std::string &fieldName,
+ sh::BlockLayoutEncoder *encoder,
+ bool inRowMajorLayout,
+ BlockLayoutMap *blockInfoOut)
+{
+ encoder->enterAggregateType();
+ GetUniformBlockInfo(fields, fieldName, encoder, inRowMajorLayout, blockInfoOut);
+ encoder->exitAggregateType();
+}
+
+template <typename VarT>
+void GetUniformBlockStructArrayMemberInfo(const VarT &field,
+ unsigned int arrayNestingIndex,
+ const std::string &arrayName,
+ sh::BlockLayoutEncoder *encoder,
+ bool inRowMajorLayout,
+ BlockLayoutMap *blockInfoOut)
+{
+ // Nested arrays are processed starting from outermost (arrayNestingIndex 0u) and ending at the
+ // innermost.
+ const unsigned int currentArraySize = field.getNestedArraySize(arrayNestingIndex);
+ for (unsigned int arrayElement = 0u; arrayElement < currentArraySize; ++arrayElement)
+ {
+ const std::string elementName = arrayName + ArrayString(arrayElement);
+ if (arrayNestingIndex + 1u < field.arraySizes.size())
+ {
+ GetUniformBlockStructArrayMemberInfo(field, arrayNestingIndex + 1u, elementName,
+ encoder, inRowMajorLayout, blockInfoOut);
+ }
+ else
+ {
+ GetUniformBlockStructMemberInfo(field.fields, elementName, encoder, inRowMajorLayout,
+ blockInfoOut);
+ }
+ }
}
-BlockMemberInfo BlockLayoutEncoder::encodeType(GLenum type, unsigned int arraySize, bool isRowMajorMatrix)
+template <typename VarT>
+void GetUniformBlockArrayOfArraysMemberInfo(const VarT &field,
+ unsigned int arrayNestingIndex,
+ const std::string &arrayName,
+ sh::BlockLayoutEncoder *encoder,
+ bool inRowMajorLayout,
+ BlockLayoutMap *blockInfoOut)
+{
+ const unsigned int currentArraySize = field.getNestedArraySize(arrayNestingIndex);
+ for (unsigned int arrayElement = 0u; arrayElement < currentArraySize; ++arrayElement)
+ {
+ const std::string elementName = arrayName + ArrayString(arrayElement);
+ if (arrayNestingIndex + 2u < field.arraySizes.size())
+ {
+ GetUniformBlockArrayOfArraysMemberInfo(field, arrayNestingIndex + 1u, elementName,
+ encoder, inRowMajorLayout, blockInfoOut);
+ }
+ else
+ {
+ std::vector<unsigned int> innermostArraySize(
+ 1u, field.getNestedArraySize(arrayNestingIndex + 1u));
+ (*blockInfoOut)[elementName] =
+ encoder->encodeType(field.type, innermostArraySize, inRowMajorLayout);
+ }
+ }
+}
+
+} // anonymous namespace
+
+BlockLayoutEncoder::BlockLayoutEncoder() : mCurrentOffset(0)
+{
+}
+
+BlockMemberInfo BlockLayoutEncoder::encodeType(GLenum type,
+ const std::vector<unsigned int> &arraySizes,
+ bool isRowMajorMatrix)
{
int arrayStride;
int matrixStride;
- getBlockLayoutInfo(type, arraySize, isRowMajorMatrix, &arrayStride, &matrixStride);
+ getBlockLayoutInfo(type, arraySizes, isRowMajorMatrix, &arrayStride, &matrixStride);
const BlockMemberInfo memberInfo(static_cast<int>(mCurrentOffset * BytesPerComponent),
static_cast<int>(arrayStride * BytesPerComponent),
static_cast<int>(matrixStride * BytesPerComponent),
isRowMajorMatrix);
- advanceOffset(type, arraySize, isRowMajorMatrix, arrayStride, matrixStride);
+ advanceOffset(type, arraySizes, isRowMajorMatrix, arrayStride, matrixStride);
return memberInfo;
}
@@ -68,48 +149,56 @@ void Std140BlockEncoder::exitAggregateType()
nextRegister();
}
-void Std140BlockEncoder::getBlockLayoutInfo(GLenum type, unsigned int arraySize, bool isRowMajorMatrix, int *arrayStrideOut, int *matrixStrideOut)
+void Std140BlockEncoder::getBlockLayoutInfo(GLenum type,
+ const std::vector<unsigned int> &arraySizes,
+ bool isRowMajorMatrix,
+ int *arrayStrideOut,
+ int *matrixStrideOut)
{
// We assume we are only dealing with 4 byte components (no doubles or half-words currently)
ASSERT(gl::VariableComponentSize(gl::VariableComponentType(type)) == BytesPerComponent);
size_t baseAlignment = 0;
- int matrixStride = 0;
- int arrayStride = 0;
+ int matrixStride = 0;
+ int arrayStride = 0;
if (gl::IsMatrixType(type))
{
baseAlignment = ComponentsPerRegister;
- matrixStride = ComponentsPerRegister;
+ matrixStride = ComponentsPerRegister;
- if (arraySize > 0)
+ if (!arraySizes.empty())
{
const int numRegisters = gl::MatrixRegisterCount(type, isRowMajorMatrix);
- arrayStride = ComponentsPerRegister * numRegisters;
+ arrayStride = ComponentsPerRegister * numRegisters;
}
}
- else if (arraySize > 0)
+ else if (!arraySizes.empty())
{
baseAlignment = ComponentsPerRegister;
- arrayStride = ComponentsPerRegister;
+ arrayStride = ComponentsPerRegister;
}
else
{
const int numComponents = gl::VariableComponentCount(type);
- baseAlignment = (numComponents == 3 ? 4u : static_cast<size_t>(numComponents));
+ baseAlignment = (numComponents == 3 ? 4u : static_cast<size_t>(numComponents));
}
mCurrentOffset = rx::roundUp(mCurrentOffset, baseAlignment);
*matrixStrideOut = matrixStride;
- *arrayStrideOut = arrayStride;
+ *arrayStrideOut = arrayStride;
}
-void Std140BlockEncoder::advanceOffset(GLenum type, unsigned int arraySize, bool isRowMajorMatrix, int arrayStride, int matrixStride)
+void Std140BlockEncoder::advanceOffset(GLenum type,
+ const std::vector<unsigned int> &arraySizes,
+ bool isRowMajorMatrix,
+ int arrayStride,
+ int matrixStride)
{
- if (arraySize > 0)
+ if (!arraySizes.empty())
{
- mCurrentOffset += arrayStride * arraySize;
+ mCurrentOffset += arrayStride * gl::ArraySizeProduct(arraySizes);
}
else if (gl::IsMatrixType(type))
{
@@ -123,4 +212,70 @@ void Std140BlockEncoder::advanceOffset(GLenum type, unsigned int arraySize, bool
}
}
+template <typename VarT>
+void GetUniformBlockInfo(const std::vector<VarT> &fields,
+ const std::string &prefix,
+ sh::BlockLayoutEncoder *encoder,
+ bool inRowMajorLayout,
+ BlockLayoutMap *blockInfoOut)
+{
+ for (const VarT &field : fields)
+ {
+ // Skip samplers. On Vulkan we use this for the default uniform block, so samplers may be
+ // included.
+ if (gl::IsSamplerType(field.type))
+ {
+ continue;
+ }
+
+ const std::string &fieldName = (prefix.empty() ? field.name : prefix + "." + field.name);
+
+ if (field.isStruct())
+ {
+ bool rowMajorLayout = (inRowMajorLayout || IsRowMajorLayout(field));
+
+ if (field.isArray())
+ {
+ GetUniformBlockStructArrayMemberInfo(field, 0u, fieldName, encoder, rowMajorLayout,
+ blockInfoOut);
+ }
+ else
+ {
+ GetUniformBlockStructMemberInfo(field.fields, fieldName, encoder, rowMajorLayout,
+ blockInfoOut);
+ }
+ }
+ else if (field.isArrayOfArrays())
+ {
+ bool isRowMajorMatrix = (gl::IsMatrixType(field.type) && inRowMajorLayout);
+ GetUniformBlockArrayOfArraysMemberInfo(field, 0u, fieldName, encoder, isRowMajorMatrix,
+ blockInfoOut);
+ }
+ else
+ {
+ bool isRowMajorMatrix = (gl::IsMatrixType(field.type) && inRowMajorLayout);
+ (*blockInfoOut)[fieldName] =
+ encoder->encodeType(field.type, field.arraySizes, isRowMajorMatrix);
+ }
+ }
}
+
+template void GetUniformBlockInfo(const std::vector<InterfaceBlockField> &,
+ const std::string &,
+ sh::BlockLayoutEncoder *,
+ bool,
+ BlockLayoutMap *);
+
+template void GetUniformBlockInfo(const std::vector<Uniform> &,
+ const std::string &,
+ sh::BlockLayoutEncoder *,
+ bool,
+ BlockLayoutMap *);
+
+template void GetUniformBlockInfo(const std::vector<ShaderVariable> &,
+ const std::string &,
+ sh::BlockLayoutEncoder *,
+ bool,
+ BlockLayoutMap *);
+
+} // namespace sh