Commit 8757dead by Alexis Hetu Committed by Alexis Hétu

Ported Angle's std140 encoder to SwiftShader

Added Angle's std140 encoder to properly compute sizes and offsets of uniform blocks for the std140 standard. All layouts currently use std140 ('packed' and 'shared' are implementation dependent, so we can choose to have them be the same as std140). All uniform blocks made of simple types or arrays of simple types are properly interpreted by this code. Structs are still TBD. Change-Id: I191d7f313db5d409715b1101ea70903a7b958726 Reviewed-on: https://swiftshader-review.googlesource.com/4525Tested-by: 's avatarAlexis Hétu <sugoi@google.com> Reviewed-by: 's avatarNicolas Capens <capn@google.com>
parent 773b67af
......@@ -30,9 +30,31 @@ typedef unsigned int GLenum;
namespace glsl
{
struct BlockMemberInfo
{
BlockMemberInfo() : offset(-1), arrayStride(-1), matrixStride(-1), isRowMajorMatrix(false) {}
BlockMemberInfo(int offset, int arrayStride, int matrixStride, bool isRowMajorMatrix)
: offset(offset),
arrayStride(arrayStride),
matrixStride(matrixStride),
isRowMajorMatrix(isRowMajorMatrix)
{}
static BlockMemberInfo getDefaultBlockInfo()
{
return BlockMemberInfo(-1, -1, -1, false);
}
int offset;
int arrayStride;
int matrixStride;
bool isRowMajorMatrix;
};
struct Uniform
{
Uniform(GLenum type, GLenum precision, const std::string &name, int arraySize, int registerIndex, int offset, int blockId);
Uniform(GLenum type, GLenum precision, const std::string &name, int arraySize, int registerIndex, int blockId, const BlockMemberInfo& blockMemberInfo);
GLenum type;
GLenum precision;
......@@ -40,22 +62,19 @@ namespace glsl
int arraySize;
int registerIndex;
int offset;
int blockId;
BlockMemberInfo blockInfo;
};
typedef std::vector<Uniform> ActiveUniforms;
struct UniformBlock
{
UniformBlock(const std::string& name, const std::string& instanceName, unsigned int dataSize, unsigned int arraySize,
UniformBlock(const std::string& name, unsigned int dataSize, unsigned int arraySize,
TLayoutBlockStorage layout, bool isRowMajorLayout, int registerIndex, int blockId);
const std::string& getName() const { return (instanceName.length() > 0) ? instanceName : name; }
std::string name;
std::string instanceName;
unsigned int dataSize;
unsigned int arraySize;
TLayoutBlockStorage layout;
......@@ -67,6 +86,50 @@ namespace glsl
int blockId;
};
class BlockLayoutEncoder
{
public:
BlockLayoutEncoder(bool rowMajor);
virtual ~BlockLayoutEncoder() {}
BlockMemberInfo encodeType(const TType &type);
size_t getBlockSize() const { return mCurrentOffset * BytesPerComponent; }
virtual void enterAggregateType() = 0;
virtual void exitAggregateType() = 0;
static const size_t BytesPerComponent = 4u;
static const unsigned int ComponentsPerRegister = 4u;
static size_t getBlockRegister(const BlockMemberInfo &info);
static size_t getBlockRegisterElement(const BlockMemberInfo &info);
protected:
size_t mCurrentOffset;
bool isRowMajor;
void nextRegister();
virtual void getBlockLayoutInfo(const TType &type, unsigned int arraySize, bool isRowMajorMatrix, int *arrayStrideOut, int *matrixStrideOut) = 0;
virtual void advanceOffset(const TType &type, unsigned int arraySize, bool isRowMajorMatrix, int arrayStride, int matrixStride) = 0;
};
// Block layout according to the std140 block layout
// See "Standard Uniform Block Layout" in Section 2.11.6 of the OpenGL ES 3.0 specification
class Std140BlockEncoder : public BlockLayoutEncoder
{
public:
Std140BlockEncoder(bool rowMajor);
void enterAggregateType() override;
void exitAggregateType() override;
protected:
void getBlockLayoutInfo(const TType &type, unsigned int arraySize, bool isRowMajorMatrix, int *arrayStrideOut, int *matrixStrideOut) override;
void advanceOffset(const TType &type, unsigned int arraySize, bool isRowMajorMatrix, int arrayStride, int matrixStride) override;
};
typedef std::vector<UniformBlock> ActiveUniformBlocks;
struct Attribute
......@@ -227,7 +290,7 @@ namespace glsl
int allocate(VariableArray &list, TIntermTyped *variable);
void free(VariableArray &list, TIntermTyped *variable);
void declareUniform(const TType &type, const TString &name, int registerIndex, int offset = 0, int blockId = -1);
void declareUniform(const TType &type, const TString &name, int registerIndex, int blockId = -1, BlockLayoutEncoder* encoder = nullptr);
GLenum glVariableType(const TType &type);
GLenum glVariablePrecision(const TType &type);
......
......@@ -36,30 +36,17 @@ namespace es2
return buffer;
}
Uniform::BlockInfo::BlockInfo(const glsl::Uniform& uniform, int blockIndex, bool rowMajorLayout)
Uniform::BlockInfo::BlockInfo(const glsl::Uniform& uniform, int blockIndex)
{
static unsigned int registerSizeStd140 = 4; // std140 packing requires dword alignment
if(blockIndex >= 0)
{
index = blockIndex;
offset = uniform.offset * registerSizeStd140;
isRowMajorMatrix = rowMajorLayout;
int componentSize = UniformTypeSize(UniformComponentType(uniform.type));
int rowCount = VariableRowCount(uniform.type);
if(rowCount > 1)
{
int colCount = VariableColumnCount(uniform.type);
int matrixComponentCount = (isRowMajorMatrix ? colCount : rowCount);
matrixStride = (rowCount > 1) ? matrixComponentCount * componentSize : 0;
arrayStride = (uniform.arraySize > 0) ? matrixStride * (isRowMajorMatrix ? rowCount : colCount) : 0;
}
else
{
matrixStride = 0;
int componentCount = UniformComponentCount(uniform.type);
arrayStride = (uniform.arraySize > 0) ? componentSize * componentCount : 0;
}
offset = uniform.blockInfo.offset;
arrayStride = uniform.blockInfo.arrayStride;
matrixStride = uniform.blockInfo.matrixStride;
isRowMajorMatrix = uniform.blockInfo.isRowMajorMatrix;
}
else
{
......@@ -1445,16 +1432,14 @@ namespace es2
const glsl::Uniform &uniform = activeUniforms[uniformIndex];
unsigned int blockIndex = GL_INVALID_INDEX;
bool isRowMajorMatrix = false;
if(uniform.blockId >= 0)
{
const glsl::ActiveUniformBlocks &activeUniformBlocks = shader->activeUniformBlocks;
ASSERT(static_cast<size_t>(uniform.blockId) < activeUniformBlocks.size());
blockIndex = getUniformBlockIndex(activeUniformBlocks[uniform.blockId].getName());
blockIndex = getUniformBlockIndex(activeUniformBlocks[uniform.blockId].name);
ASSERT(blockIndex != GL_INVALID_INDEX);
isRowMajorMatrix = activeUniformBlocks[uniform.blockId].isRowMajorLayout;
}
if(!defineUniform(shader->getType(), uniform.type, uniform.precision, uniform.name, uniform.arraySize, uniform.registerIndex, Uniform::BlockInfo(uniform, blockIndex, isRowMajorMatrix)))
if(!defineUniform(shader->getType(), uniform.type, uniform.precision, uniform.name, uniform.arraySize, uniform.registerIndex, Uniform::BlockInfo(uniform, blockIndex)))
{
return false;
}
......@@ -1696,7 +1681,7 @@ namespace es2
bool Program::defineUniformBlock(const Shader *shader, const glsl::UniformBlock &block)
{
GLuint blockIndex = getUniformBlockIndex(block.getName());
GLuint blockIndex = getUniformBlockIndex(block.name);
if(blockIndex == GL_INVALID_INDEX)
{
......@@ -1709,15 +1694,17 @@ namespace es2
if(block.arraySize > 0)
{
for(unsigned int i = 0; i < block.arraySize; ++i)
int regIndex = block.registerIndex;
int regInc = block.dataSize / (glsl::BlockLayoutEncoder::BytesPerComponent * glsl::BlockLayoutEncoder::ComponentsPerRegister);
for(unsigned int i = 0; i < block.arraySize; ++i, regIndex += regInc)
{
uniformBlocks.push_back(new UniformBlock(block.getName(), i, block.dataSize, memberUniformIndexes));
uniformBlocks[uniformBlocks.size() - 1]->setRegisterIndex(shader->getType(), block.registerIndex);
uniformBlocks.push_back(new UniformBlock(block.name, i, block.dataSize, memberUniformIndexes));
uniformBlocks[uniformBlocks.size() - 1]->setRegisterIndex(shader->getType(), regIndex);
}
}
else
{
uniformBlocks.push_back(new UniformBlock(block.getName(), GL_INVALID_INDEX, block.dataSize, memberUniformIndexes));
uniformBlocks.push_back(new UniformBlock(block.name, GL_INVALID_INDEX, block.dataSize, memberUniformIndexes));
uniformBlocks[uniformBlocks.size() - 1]->setRegisterIndex(shader->getType(), block.registerIndex);
}
}
......
......@@ -36,7 +36,7 @@ namespace es2
{
struct BlockInfo
{
BlockInfo(const glsl::Uniform& uniform, int blockIndex, bool rowMajorLayout);
BlockInfo(const glsl::Uniform& uniform, int blockIndex);
int index;
int offset;
......
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