Commit 1bfa6b71 by Jamie Madill Committed by Commit Bot

Generalize GetUniformBlockInfo.

This method is useful for the Vulkan back-end as well as D3D11. It can produce a uniform block layout for the default uniform blocks as well as for interface blocks. Put it in blocklayout.h in the translator. BUG=angleproject:2167 Change-Id: I13160906921da439746c1811a623006250aaeefd Reviewed-on: https://chromium-review.googlesource.com/713941Reviewed-by: 's avatarFrank Henigman <fjhenigman@chromium.org> Reviewed-by: 's avatarGeoff Lang <geofflang@chromium.org> Commit-Queue: Jamie Madill <jmadill@chromium.org>
parent cc8e2738
...@@ -15,6 +15,19 @@ ...@@ -15,6 +15,19 @@
namespace sh namespace sh
{ {
namespace
{
bool IsRowMajorLayout(const InterfaceBlockField &var)
{
return var.isRowMajorLayout;
}
bool IsRowMajorLayout(const ShaderVariable &var)
{
return false;
}
} // anonymous namespace
BlockLayoutEncoder::BlockLayoutEncoder() : mCurrentOffset(0) BlockLayoutEncoder::BlockLayoutEncoder() : mCurrentOffset(0)
{ {
} }
...@@ -131,4 +144,67 @@ void Std140BlockEncoder::advanceOffset(GLenum type, ...@@ -131,4 +144,67 @@ void Std140BlockEncoder::advanceOffset(GLenum type,
mCurrentOffset += gl::VariableComponentCount(type); mCurrentOffset += gl::VariableComponentCount(type);
} }
} }
template <typename VarT>
void GetUniformBlockInfo(const std::vector<VarT> &fields,
const std::string &prefix,
BlockLayoutEncoder *encoder,
bool inRowMajorLayout,
BlockLayoutMap *blockLayoutMap)
{
for (const VarT &field : fields)
{
// Skip samplers.
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));
for (unsigned int arrayElement = 0; arrayElement < field.elementCount(); arrayElement++)
{
encoder->enterAggregateType();
const std::string uniformElementName =
fieldName + (field.isArray() ? ArrayString(arrayElement) : "");
GetUniformBlockInfo(field.fields, uniformElementName, encoder, rowMajorLayout,
blockLayoutMap);
encoder->exitAggregateType();
}
}
else
{
bool isRowMajorMatrix = (gl::IsMatrixType(field.type) && inRowMajorLayout);
const BlockMemberInfo &blockMemberInfo =
encoder->encodeType(field.type, field.arraySize, isRowMajorMatrix);
(*blockLayoutMap)[fieldName] = blockMemberInfo;
}
}
} }
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
...@@ -11,6 +11,7 @@ ...@@ -11,6 +11,7 @@
#define COMMON_BLOCKLAYOUT_H_ #define COMMON_BLOCKLAYOUT_H_
#include <cstddef> #include <cstddef>
#include <map>
#include <vector> #include <vector>
#include "angle_gl.h" #include "angle_gl.h"
...@@ -103,6 +104,17 @@ class Std140BlockEncoder : public BlockLayoutEncoder ...@@ -103,6 +104,17 @@ class Std140BlockEncoder : public BlockLayoutEncoder
int arrayStride, int arrayStride,
int matrixStride) override; int matrixStride) override;
}; };
}
using BlockLayoutMap = std::map<std::string, BlockMemberInfo>;
// Only valid to call with ShaderVariable, InterfaceBlockField and Uniform.
template <typename VarT>
void GetUniformBlockInfo(const std::vector<VarT> &fields,
const std::string &prefix,
sh::BlockLayoutEncoder *encoder,
bool inRowMajorLayout,
BlockLayoutMap *blockLayoutMap);
} // namespace sh
#endif // COMMON_BLOCKLAYOUT_H_ #endif // COMMON_BLOCKLAYOUT_H_
...@@ -75,52 +75,6 @@ void GetDefaultOutputLayoutFromShader( ...@@ -75,52 +75,6 @@ void GetDefaultOutputLayoutFromShader(
} }
} }
bool IsRowMajorLayout(const sh::InterfaceBlockField &var)
{
return var.isRowMajorLayout;
}
bool IsRowMajorLayout(const sh::ShaderVariable &var)
{
return false;
}
template <typename VarT>
void GetUniformBlockInfo(const std::vector<VarT> &fields,
const std::string &prefix,
sh::BlockLayoutEncoder *encoder,
bool inRowMajorLayout,
std::map<std::string, sh::BlockMemberInfo> *blockInfoOut)
{
for (const VarT &field : fields)
{
const std::string &fieldName = (prefix.empty() ? field.name : prefix + "." + field.name);
if (field.isStruct())
{
bool rowMajorLayout = (inRowMajorLayout || IsRowMajorLayout(field));
for (unsigned int arrayElement = 0; arrayElement < field.elementCount(); arrayElement++)
{
encoder->enterAggregateType();
const std::string uniformElementName =
fieldName + (field.isArray() ? ArrayString(arrayElement) : "");
GetUniformBlockInfo(field.fields, uniformElementName, encoder, rowMajorLayout,
blockInfoOut);
encoder->exitAggregateType();
}
}
else
{
bool isRowMajorMatrix = (gl::IsMatrixType(field.type) && inRowMajorLayout);
(*blockInfoOut)[fieldName] =
encoder->encodeType(field.type, field.arraySize, isRowMajorMatrix);
}
}
}
template <typename T, int cols, int rows> template <typename T, int cols, int rows>
bool TransposeExpandMatrix(T *target, const GLfloat *value) bool TransposeExpandMatrix(T *target, const GLfloat *value)
{ {
...@@ -2331,8 +2285,8 @@ size_t ProgramD3D::getUniformBlockInfo(const sh::InterfaceBlock &interfaceBlock) ...@@ -2331,8 +2285,8 @@ size_t ProgramD3D::getUniformBlockInfo(const sh::InterfaceBlock &interfaceBlock)
encoder = &hlslEncoder; encoder = &hlslEncoder;
} }
GetUniformBlockInfo(interfaceBlock.fields, interfaceBlock.fieldPrefix(), encoder, sh::GetUniformBlockInfo(interfaceBlock.fields, interfaceBlock.fieldPrefix(), encoder,
interfaceBlock.isRowMajorLayout, &mBlockInfo); interfaceBlock.isRowMajorLayout, &mBlockInfo);
return encoder->getBlockSize(); return encoder->getBlockSize();
} }
......
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