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
diff --git a/src/libGLESv2/ProgramBinary.cpp b/src/libGLESv2/ProgramBinary.cpp
index 90d4fab..b050167 100644
--- a/src/libGLESv2/ProgramBinary.cpp
+++ b/src/libGLESv2/ProgramBinary.cpp
@@ -107,6 +107,12 @@
delete mUniforms.back();
mUniforms.pop_back();
}
+
+ while (!mUniformBlocks.empty())
+ {
+ delete mUniformBlocks.back();
+ mUniformBlocks.pop_back();
+ }
}
unsigned int ProgramBinary::getSerial() const
@@ -1461,13 +1467,27 @@
GLenum precision;
std::string name;
unsigned int arraySize;
+ int blockIndex;
stream.read(&type);
stream.read(&precision);
stream.read(&name);
stream.read(&arraySize);
+ stream.read(&blockIndex);
- mUniforms[i] = new Uniform(type, precision, name, arraySize);
+ int offset;
+ int arrayStride;
+ int matrixStride;
+ bool isRowMajorMatrix;
+
+ stream.read(&offset);
+ stream.read(&arrayStride);
+ stream.read(&matrixStride);
+ stream.read(&isRowMajorMatrix);
+
+ 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]->vsRegisterIndex);
@@ -1481,6 +1501,39 @@
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);
for (unsigned int i = 0; i < size; ++i)
{
@@ -1592,16 +1645,43 @@
stream.write(mUsesPointSize);
stream.write(mUniforms.size());
- for (unsigned int i = 0; i < mUniforms.size(); ++i)
+ for (unsigned int uniformIndex = 0; uniformIndex < mUniforms.size(); ++uniformIndex)
{
- stream.write(mUniforms[i]->type);
- stream.write(mUniforms[i]->precision);
- stream.write(mUniforms[i]->name);
- stream.write(mUniforms[i]->arraySize);
+ const Uniform &uniform = *mUniforms[uniformIndex];
- stream.write(mUniforms[i]->psRegisterIndex);
- stream.write(mUniforms[i]->vsRegisterIndex);
- stream.write(mUniforms[i]->registerCount);
+ 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)
+ {
+ const UniformBlock& uniformBlock = *mUniformBlocks[uniformBlockIndex];
+
+ stream.write(uniformBlock.name);
+ stream.write(uniformBlock.elementIndex);
+ 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());
@@ -1748,9 +1828,9 @@
// special case for gl_DepthRange, the only built-in uniform (also a struct)
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.far", 0));
- 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.near", 0, -1, sh::BlockMemberInfo::defaultBlockInfo));
+ 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, -1, sh::BlockMemberInfo::defaultBlockInfo));
}
return success;
@@ -1914,7 +1994,7 @@
}
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)
@@ -2241,17 +2321,12 @@
case GL_UNIFORM_TYPE: return static_cast<GLint>(uniform.type);
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_BLOCK_INDEX: return uniform.blockIndex;
- case GL_UNIFORM_BLOCK_INDEX:
- case GL_UNIFORM_OFFSET:
- case GL_UNIFORM_ARRAY_STRIDE:
- case GL_UNIFORM_MATRIX_STRIDE:
- // 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;
+ case GL_UNIFORM_OFFSET: return uniform.blockInfo.offset;
+ case GL_UNIFORM_ARRAY_STRIDE: return uniform.blockInfo.arrayStride;
+ case GL_UNIFORM_MATRIX_STRIDE: return uniform.blockInfo.matrixStride;
+ case GL_UNIFORM_IS_ROW_MAJOR: return static_cast<GLint>(uniform.blockInfo.isRowMajorMatrix);
default:
UNREACHABLE();