Add state for uniform blocks to ProgramBinary, along with loading and saving of…

Add state for uniform blocks to ProgramBinary, along with loading and saving of the new binary format. Updated Version.h with this patch. TRAC #22858 Signed-off-by: Geoff Lang Signed-off-by: Nicolas Capens Author: Jamie Madill Conflicts: src/common/version.h git-svn-id: https://angleproject.googlecode.com/svn/branches/es3proto@2306 736b8ea6-26fd-11df-bfd4-992fa37f6226
parent 38676dc1
#define MAJOR_VERSION 1 #define MAJOR_VERSION 1
#define MINOR_VERSION 1 #define MINOR_VERSION 1
#define BUILD_VERSION 0 #define BUILD_VERSION 0
#define BUILD_REVISION 2181 #define BUILD_REVISION 1990
#define STRINGIFY(x) #x #define STRINGIFY(x) #x
#define MACRO_STRINGIFY(x) STRINGIFY(x) #define MACRO_STRINGIFY(x) STRINGIFY(x)
......
...@@ -18,4 +18,14 @@ Uniform::Uniform(GLenum type, GLenum precision, const char *name, unsigned int a ...@@ -18,4 +18,14 @@ Uniform::Uniform(GLenum type, GLenum precision, const char *name, unsigned int a
this->registerIndex = registerIndex; this->registerIndex = registerIndex;
} }
BlockMemberInfo::BlockMemberInfo(int offset, int arrayStride, int matrixStride, bool isRowMajorMatrix)
: offset(offset),
arrayStride(arrayStride),
matrixStride(matrixStride),
isRowMajorMatrix(isRowMajorMatrix)
{
}
const BlockMemberInfo BlockMemberInfo::defaultBlockInfo(-1, -1, -1, false);
} }
...@@ -31,6 +31,18 @@ struct Uniform ...@@ -31,6 +31,18 @@ struct Uniform
typedef std::vector<Uniform> ActiveUniforms; typedef std::vector<Uniform> ActiveUniforms;
struct BlockMemberInfo
{
BlockMemberInfo(int offset, int arrayStride, int matrixStride, bool isRowMajorMatrix);
int offset;
int arrayStride;
int matrixStride;
bool isRowMajorMatrix;
static const BlockMemberInfo defaultBlockInfo;
};
} }
#endif // COMPILER_UNIFORM_H_ #endif // COMPILER_UNIFORM_H_
...@@ -107,6 +107,12 @@ ProgramBinary::~ProgramBinary() ...@@ -107,6 +107,12 @@ ProgramBinary::~ProgramBinary()
delete mUniforms.back(); delete mUniforms.back();
mUniforms.pop_back(); mUniforms.pop_back();
} }
while (!mUniformBlocks.empty())
{
delete mUniformBlocks.back();
mUniformBlocks.pop_back();
}
} }
unsigned int ProgramBinary::getSerial() const unsigned int ProgramBinary::getSerial() const
...@@ -1461,13 +1467,27 @@ bool ProgramBinary::load(InfoLog &infoLog, const void *binary, GLsizei length) ...@@ -1461,13 +1467,27 @@ bool ProgramBinary::load(InfoLog &infoLog, const void *binary, GLsizei length)
GLenum precision; GLenum precision;
std::string name; std::string name;
unsigned int arraySize; unsigned int arraySize;
int blockIndex;
stream.read(&type); stream.read(&type);
stream.read(&precision); stream.read(&precision);
stream.read(&name); stream.read(&name);
stream.read(&arraySize); stream.read(&arraySize);
stream.read(&blockIndex);
int offset;
int arrayStride;
int matrixStride;
bool isRowMajorMatrix;
stream.read(&offset);
stream.read(&arrayStride);
stream.read(&matrixStride);
stream.read(&isRowMajorMatrix);
mUniforms[i] = new Uniform(type, precision, name, arraySize); const sh::BlockMemberInfo blockInfo(offset, arrayStride, matrixStride, isRowMajorMatrix);
mUniforms[i] = new Uniform(type, precision, name, arraySize, blockIndex, blockInfo);
stream.read(&mUniforms[i]->psRegisterIndex); stream.read(&mUniforms[i]->psRegisterIndex);
stream.read(&mUniforms[i]->vsRegisterIndex); stream.read(&mUniforms[i]->vsRegisterIndex);
...@@ -1481,6 +1501,39 @@ bool ProgramBinary::load(InfoLog &infoLog, const void *binary, GLsizei length) ...@@ -1481,6 +1501,39 @@ bool ProgramBinary::load(InfoLog &infoLog, const void *binary, GLsizei length)
return false; return false;
} }
mUniformBlocks.resize(size);
for (unsigned int uniformBlockIndex = 0; uniformBlockIndex < size; ++uniformBlockIndex)
{
std::string name;
unsigned int elementIndex;
unsigned int dataSize;
stream.read(&name);
stream.read(&elementIndex);
stream.read(&dataSize);
mUniformBlocks[uniformBlockIndex] = new UniformBlock(name, elementIndex, dataSize);
UniformBlock& uniformBlock = *mUniformBlocks[uniformBlockIndex];
stream.read(&uniformBlock.psRegisterIndex);
stream.read(&uniformBlock.vsRegisterIndex);
size_t numMembers;
stream.read(&numMembers);
uniformBlock.memberUniformIndexes.resize(numMembers);
for (unsigned int blockMemberIndex = 0; blockMemberIndex < numMembers; blockMemberIndex++)
{
stream.read(&uniformBlock.memberUniformIndexes[blockMemberIndex]);
}
}
stream.read(&size);
if (stream.error())
{
infoLog.append("Invalid program binary.");
return false;
}
mUniformIndex.resize(size); mUniformIndex.resize(size);
for (unsigned int i = 0; i < size; ++i) for (unsigned int i = 0; i < size; ++i)
{ {
...@@ -1592,16 +1645,43 @@ bool ProgramBinary::save(void* binary, GLsizei bufSize, GLsizei *length) ...@@ -1592,16 +1645,43 @@ bool ProgramBinary::save(void* binary, GLsizei bufSize, GLsizei *length)
stream.write(mUsesPointSize); stream.write(mUsesPointSize);
stream.write(mUniforms.size()); stream.write(mUniforms.size());
for (unsigned int i = 0; i < mUniforms.size(); ++i) for (unsigned int uniformIndex = 0; uniformIndex < mUniforms.size(); ++uniformIndex)
{
const Uniform &uniform = *mUniforms[uniformIndex];
stream.write(uniform.type);
stream.write(uniform.precision);
stream.write(uniform.name);
stream.write(uniform.arraySize);
stream.write(uniform.blockIndex);
stream.write(uniform.blockInfo.offset);
stream.write(uniform.blockInfo.arrayStride);
stream.write(uniform.blockInfo.matrixStride);
stream.write(uniform.blockInfo.isRowMajorMatrix);
stream.write(uniform.psRegisterIndex);
stream.write(uniform.vsRegisterIndex);
stream.write(uniform.registerCount);
}
stream.write(mUniformBlocks.size());
for (unsigned int uniformBlockIndex = 0; uniformBlockIndex < mUniformBlocks.size(); ++uniformBlockIndex)
{ {
stream.write(mUniforms[i]->type); const UniformBlock& uniformBlock = *mUniformBlocks[uniformBlockIndex];
stream.write(mUniforms[i]->precision);
stream.write(mUniforms[i]->name);
stream.write(mUniforms[i]->arraySize);
stream.write(mUniforms[i]->psRegisterIndex); stream.write(uniformBlock.name);
stream.write(mUniforms[i]->vsRegisterIndex); stream.write(uniformBlock.elementIndex);
stream.write(mUniforms[i]->registerCount); stream.write(uniformBlock.dataSize);
stream.write(uniformBlock.memberUniformIndexes.size());
for (unsigned int blockMemberIndex = 0; blockMemberIndex < uniformBlock.memberUniformIndexes.size(); blockMemberIndex++)
{
stream.write(uniformBlock.memberUniformIndexes[blockMemberIndex]);
}
stream.write(uniformBlock.psRegisterIndex);
stream.write(uniformBlock.vsRegisterIndex);
} }
stream.write(mUniformIndex.size()); stream.write(mUniformIndex.size());
...@@ -1748,9 +1828,9 @@ bool ProgramBinary::link(InfoLog &infoLog, const AttributeBindings &attributeBin ...@@ -1748,9 +1828,9 @@ bool ProgramBinary::link(InfoLog &infoLog, const AttributeBindings &attributeBin
// special case for gl_DepthRange, the only built-in uniform (also a struct) // special case for gl_DepthRange, the only built-in uniform (also a struct)
if (vertexShader->mUsesDepthRange || fragmentShader->mUsesDepthRange) if (vertexShader->mUsesDepthRange || fragmentShader->mUsesDepthRange)
{ {
mUniforms.push_back(new Uniform(GL_FLOAT, GL_HIGH_FLOAT, "gl_DepthRange.near", 0)); mUniforms.push_back(new Uniform(GL_FLOAT, GL_HIGH_FLOAT, "gl_DepthRange.near", 0, -1, sh::BlockMemberInfo::defaultBlockInfo));
mUniforms.push_back(new Uniform(GL_FLOAT, GL_HIGH_FLOAT, "gl_DepthRange.far", 0)); mUniforms.push_back(new Uniform(GL_FLOAT, GL_HIGH_FLOAT, "gl_DepthRange.far", 0, -1, sh::BlockMemberInfo::defaultBlockInfo));
mUniforms.push_back(new Uniform(GL_FLOAT, GL_HIGH_FLOAT, "gl_DepthRange.diff", 0)); mUniforms.push_back(new Uniform(GL_FLOAT, GL_HIGH_FLOAT, "gl_DepthRange.diff", 0, -1, sh::BlockMemberInfo::defaultBlockInfo));
} }
return success; return success;
...@@ -1914,7 +1994,7 @@ bool ProgramBinary::defineUniform(GLenum shader, const sh::Uniform &constant, In ...@@ -1914,7 +1994,7 @@ bool ProgramBinary::defineUniform(GLenum shader, const sh::Uniform &constant, In
} }
else else
{ {
uniform = new Uniform(constant.type, constant.precision, constant.name, constant.arraySize); uniform = new Uniform(constant.type, constant.precision, constant.name, constant.arraySize, -1, sh::BlockMemberInfo::defaultBlockInfo);
} }
if (!uniform) if (!uniform)
...@@ -2241,17 +2321,12 @@ GLint ProgramBinary::getActiveUniformi(GLuint index, GLenum pname) const ...@@ -2241,17 +2321,12 @@ GLint ProgramBinary::getActiveUniformi(GLuint index, GLenum pname) const
case GL_UNIFORM_TYPE: return static_cast<GLint>(uniform.type); case GL_UNIFORM_TYPE: return static_cast<GLint>(uniform.type);
case GL_UNIFORM_SIZE: return static_cast<GLint>(uniform.elementCount()); case GL_UNIFORM_SIZE: return static_cast<GLint>(uniform.elementCount());
case GL_UNIFORM_NAME_LENGTH: return static_cast<GLint>(uniform.name.size() + 1); case GL_UNIFORM_NAME_LENGTH: return static_cast<GLint>(uniform.name.size() + 1);
case GL_UNIFORM_BLOCK_INDEX: return uniform.blockIndex;
case GL_UNIFORM_BLOCK_INDEX: case GL_UNIFORM_OFFSET: return uniform.blockInfo.offset;
case GL_UNIFORM_OFFSET: case GL_UNIFORM_ARRAY_STRIDE: return uniform.blockInfo.arrayStride;
case GL_UNIFORM_ARRAY_STRIDE: case GL_UNIFORM_MATRIX_STRIDE: return uniform.blockInfo.matrixStride;
case GL_UNIFORM_MATRIX_STRIDE: case GL_UNIFORM_IS_ROW_MAJOR: return static_cast<GLint>(uniform.blockInfo.isRowMajorMatrix);
// the default block gives a value of -1 for these parameters
return -1;
case GL_UNIFORM_IS_ROW_MAJOR:
// TODO: column/row major layout for uniform blocks
return 0;
default: default:
UNREACHABLE(); UNREACHABLE();
......
...@@ -184,6 +184,7 @@ class ProgramBinary : public RefCountObject ...@@ -184,6 +184,7 @@ class ProgramBinary : public RefCountObject
bool mUsesPointSize; bool mUsesPointSize;
UniformArray mUniforms; UniformArray mUniforms;
UniformBlockArray mUniformBlocks;
typedef std::vector<UniformLocation> UniformIndex; typedef std::vector<UniformLocation> UniformIndex;
UniformIndex mUniformIndex; UniformIndex mUniformIndex;
......
...@@ -12,17 +12,28 @@ ...@@ -12,17 +12,28 @@
namespace gl namespace gl
{ {
Uniform::Uniform(GLenum type, GLenum precision, const std::string &name, unsigned int arraySize) Uniform::Uniform(GLenum type, GLenum precision, const std::string &name, unsigned int arraySize, const int blockIndex, const sh::BlockMemberInfo &blockInfo)
: type(type), precision(precision), name(name), arraySize(arraySize) : type(type),
precision(precision),
name(name),
arraySize(arraySize),
blockIndex(blockIndex),
blockInfo(blockInfo),
data(NULL),
dirty(true),
psRegisterIndex(GL_INVALID_INDEX),
vsRegisterIndex(GL_INVALID_INDEX),
registerCount(0)
{ {
int bytes = gl::UniformInternalSize(type) * elementCount(); // We use data storage for default block uniforms to cache values that are sent to D3D during rendering
data = new unsigned char[bytes]; // Uniform blocks/buffers are treated separately by the Renderer (ES3 path only)
memset(data, 0, bytes); if (isInDefaultBlock())
dirty = true; {
size_t bytes = UniformInternalSize(type) * elementCount();
psRegisterIndex = GL_INVALID_INDEX; data = new unsigned char[bytes];
vsRegisterIndex = GL_INVALID_INDEX; memset(data, 0, bytes);
registerCount = VariableRowCount(type) * elementCount(); registerCount = VariableRowCount(type) * elementCount();
}
} }
Uniform::~Uniform() Uniform::~Uniform()
...@@ -50,4 +61,33 @@ bool Uniform::isReferencedByFragmentShader() const ...@@ -50,4 +61,33 @@ bool Uniform::isReferencedByFragmentShader() const
return psRegisterIndex != GL_INVALID_INDEX; return psRegisterIndex != GL_INVALID_INDEX;
} }
bool Uniform::isInDefaultBlock() const
{
return blockIndex == -1;
}
UniformBlock::UniformBlock(const std::string &name, unsigned int elementIndex, unsigned int dataSize)
: name(name),
elementIndex(elementIndex),
dataSize(dataSize),
psRegisterIndex(GL_INVALID_INDEX),
vsRegisterIndex(GL_INVALID_INDEX)
{
}
bool UniformBlock::isArrayElement() const
{
return elementIndex != GL_INVALID_INDEX;
}
bool UniformBlock::isReferencedByVertexShader() const
{
return vsRegisterIndex != GL_INVALID_INDEX;
}
bool UniformBlock::isReferencedByFragmentShader() const
{
return psRegisterIndex != GL_INVALID_INDEX;
}
} }
...@@ -15,6 +15,8 @@ ...@@ -15,6 +15,8 @@
#include <GLES2/gl2.h> #include <GLES2/gl2.h>
#include "common/debug.h" #include "common/debug.h"
#include "angletypes.h"
#include "compiler/Uniform.h"
namespace gl namespace gl
{ {
...@@ -22,7 +24,7 @@ namespace gl ...@@ -22,7 +24,7 @@ namespace gl
// Helper struct representing a single shader uniform // Helper struct representing a single shader uniform
struct Uniform struct Uniform
{ {
Uniform(GLenum type, GLenum precision, const std::string &name, unsigned int arraySize); Uniform(GLenum type, GLenum precision, const std::string &name, unsigned int arraySize, const int blockIndex, const sh::BlockMemberInfo &blockInfo);
~Uniform(); ~Uniform();
...@@ -30,11 +32,14 @@ struct Uniform ...@@ -30,11 +32,14 @@ struct Uniform
unsigned int elementCount() const; unsigned int elementCount() const;
bool isReferencedByVertexShader() const; bool isReferencedByVertexShader() const;
bool isReferencedByFragmentShader() const; bool isReferencedByFragmentShader() const;
bool isInDefaultBlock() const;
const GLenum type; const GLenum type;
const GLenum precision; const GLenum precision;
const std::string name; const std::string name;
const unsigned int arraySize; const unsigned int arraySize;
const int blockIndex;
const sh::BlockMemberInfo blockInfo;
unsigned char *data; unsigned char *data;
bool dirty; bool dirty;
...@@ -46,6 +51,28 @@ struct Uniform ...@@ -46,6 +51,28 @@ struct Uniform
typedef std::vector<Uniform*> UniformArray; typedef std::vector<Uniform*> UniformArray;
// Helper struct representing a single shader uniform block
struct UniformBlock
{
// use GL_INVALID_INDEX for non-array elements
UniformBlock(const std::string &name, unsigned int elementIndex, unsigned int dataSize);
bool isArrayElement() const;
bool isReferencedByVertexShader() const;
bool isReferencedByFragmentShader() const;
const std::string name;
const unsigned int elementIndex;
const unsigned int dataSize;
std::vector<unsigned int> memberUniformIndexes;
unsigned int psRegisterIndex;
unsigned int vsRegisterIndex;
};
typedef std::vector<UniformBlock*> UniformBlockArray;
} }
#endif // LIBGLESV2_UNIFORM_H_ #endif // LIBGLESV2_UNIFORM_H_
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