Pass uniform buffers active bound to uniform blocks of the active program to HLSL/D3D constant buffers.
TRAC #22892
Signed-off-by: Nicolas Capens
Signed-off-by: Shannon Woods
Author: Jamie Madill
git-svn-id: https://angleproject.googlecode.com/svn/branches/es3proto@2339 736b8ea6-26fd-11df-bfd4-992fa37f6226
diff --git a/src/libGLESv2/ProgramBinary.cpp b/src/libGLESv2/ProgramBinary.cpp
index 10283d6..584b4ac 100644
--- a/src/libGLESv2/ProgramBinary.cpp
+++ b/src/libGLESv2/ProgramBinary.cpp
@@ -22,6 +22,7 @@
#include "libGLESv2/renderer/Renderer.h"
#include "libGLESv2/renderer/VertexDataManager.h"
#include "libGLESv2/Context.h"
+#include "libGLESv2/Buffer.h"
#undef near
#undef far
@@ -317,6 +318,12 @@
return GL_INVALID_INDEX;
}
+UniformBlock *ProgramBinary::getUniformBlockByIndex(GLuint blockIndex)
+{
+ ASSERT(blockIndex < mUniformBlocks.size());
+ return mUniformBlocks[blockIndex];
+}
+
template <typename T>
bool ProgramBinary::setUniform(GLint location, GLsizei count, const T* v, GLenum targetUniformType)
{
@@ -807,6 +814,51 @@
mRenderer->applyUniforms(this, &mUniforms);
}
+bool ProgramBinary::applyUniformBuffers(const std::vector<gl::Buffer*> boundBuffers)
+{
+ const gl::Buffer *vertexUniformBuffers[gl::IMPLEMENTATION_MAX_VERTEX_SHADER_UNIFORM_BUFFERS] = {NULL};
+ const gl::Buffer *fragmentUniformBuffers[gl::IMPLEMENTATION_MAX_FRAGMENT_SHADER_UNIFORM_BUFFERS] = {NULL};
+
+ const unsigned int reservedBuffersInVS = mRenderer->getReservedVertexUniformBuffers();
+ const unsigned int reservedBuffersInFS = mRenderer->getReservedFragmentUniformBuffers();
+
+ ASSERT(boundBuffers.size() == mUniformBlocks.size());
+
+ for (unsigned int uniformBlockIndex = 0; uniformBlockIndex < mUniformBlocks.size(); uniformBlockIndex++)
+ {
+ gl::UniformBlock *uniformBlock = getUniformBlockByIndex(uniformBlockIndex);
+ gl::Buffer *uniformBuffer = boundBuffers[uniformBlockIndex];
+
+ ASSERT(uniformBlock && uniformBuffer);
+
+ if (uniformBuffer->size() < uniformBlock->dataSize)
+ {
+ // undefined behaviour
+ return false;
+ }
+
+ ASSERT(uniformBlock->isReferencedByVertexShader() || uniformBlock->isReferencedByFragmentShader());
+
+ if (uniformBlock->isReferencedByVertexShader())
+ {
+ unsigned int registerIndex = uniformBlock->vsRegisterIndex - reservedBuffersInVS;
+ ASSERT(vertexUniformBuffers[registerIndex] == NULL);
+ ASSERT(registerIndex < mRenderer->getMaxVertexShaderUniformBuffers());
+ vertexUniformBuffers[registerIndex] = uniformBuffer;
+ }
+
+ if (uniformBlock->isReferencedByFragmentShader())
+ {
+ unsigned int registerIndex = uniformBlock->psRegisterIndex - reservedBuffersInFS;
+ ASSERT(fragmentUniformBuffers[registerIndex] == NULL);
+ ASSERT(registerIndex < mRenderer->getMaxFragmentShaderUniformBuffers());
+ fragmentUniformBuffers[registerIndex] = uniformBuffer;
+ }
+ }
+
+ return mRenderer->setUniformBuffers(vertexUniformBuffers, fragmentUniformBuffers);
+}
+
// Packs varyings into generic varying registers, using the algorithm from [OpenGL ES Shading Language 1.00 rev. 17] appendix A section 7 page 111
// Returns the number of used varying registers, or -1 if unsuccesful
int ProgramBinary::packVaryings(InfoLog &infoLog, const Varying *packing[][4], FragmentShader *fragmentShader)