Add support for the transpose parameter of the glUniformMatrix family of functions in ES3.

TRAC #22839 Signed-off-by: Geoff Lang Signed-off-by: Shanon Woods Author: Jamie Madill git-svn-id: https://angleproject.googlecode.com/svn/branches/es3proto@2139 736b8ea6-26fd-11df-bfd4-992fa37f6226
parent f130616e
...@@ -490,8 +490,39 @@ void transposeMatrix(T *target, const GLfloat *value, int targetWidth, int targe ...@@ -490,8 +490,39 @@ void transposeMatrix(T *target, const GLfloat *value, int targetWidth, int targe
} }
} }
template<typename T>
void expandMatrix(T *target, const GLfloat *value, int targetWidth, int targetHeight, int srcWidth, int srcHeight)
{
int copyWidth = std::min(targetWidth, srcWidth);
int copyHeight = std::min(targetHeight, srcHeight);
for (int y = 0; y < copyHeight; y++)
{
for (int x = 0; x < copyWidth; x++)
{
target[y * targetWidth + x] = static_cast<T>(value[y * srcWidth + x]);
}
}
// clear unfilled right side
for (int y = 0; y < copyHeight; y++)
{
for (int x = copyWidth; x < targetWidth; x++)
{
target[y * targetWidth + x] = static_cast<T>(0);
}
}
// clear unfilled bottom.
for (int y = copyHeight; y < targetHeight; y++)
{
for (int x = 0; x < targetWidth; x++)
{
target[y * targetWidth + x] = static_cast<T>(0);
}
}
}
template <int cols, int rows> template <int cols, int rows>
bool ProgramBinary::setUniformMatrixfv(GLint location, GLsizei count, const GLfloat *value, GLenum targetUniformType) bool ProgramBinary::setUniformMatrixfv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value, GLenum targetUniformType)
{ {
if (location < 0 || location >= (int)mUniformIndex.size()) if (location < 0 || location >= (int)mUniformIndex.size())
{ {
...@@ -516,7 +547,15 @@ bool ProgramBinary::setUniformMatrixfv(GLint location, GLsizei count, const GLfl ...@@ -516,7 +547,15 @@ bool ProgramBinary::setUniformMatrixfv(GLint location, GLsizei count, const GLfl
for (int i = 0; i < count; i++) for (int i = 0; i < count; i++)
{ {
transposeMatrix<GLfloat>(target, value, 4, rows, rows, cols); // Internally store matrices as transposed versions to accomodate HLSL matrix indexing
if (transpose == GL_FALSE)
{
transposeMatrix<GLfloat>(target, value, 4, rows, rows, cols);
}
else
{
expandMatrix<GLfloat>(target, value, 4, rows, cols, rows);
}
target += 4 * rows; target += 4 * rows;
value += cols * rows; value += cols * rows;
} }
...@@ -524,49 +563,49 @@ bool ProgramBinary::setUniformMatrixfv(GLint location, GLsizei count, const GLfl ...@@ -524,49 +563,49 @@ bool ProgramBinary::setUniformMatrixfv(GLint location, GLsizei count, const GLfl
return true; return true;
} }
bool ProgramBinary::setUniformMatrix2fv(GLint location, GLsizei count, const GLfloat *value) bool ProgramBinary::setUniformMatrix2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value)
{ {
return setUniformMatrixfv<2, 2>(location, count, value, GL_FLOAT_MAT2); return setUniformMatrixfv<2, 2>(location, count, transpose, value, GL_FLOAT_MAT2);
} }
bool ProgramBinary::setUniformMatrix3fv(GLint location, GLsizei count, const GLfloat *value) bool ProgramBinary::setUniformMatrix3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value)
{ {
return setUniformMatrixfv<3, 3>(location, count, value, GL_FLOAT_MAT3); return setUniformMatrixfv<3, 3>(location, count, transpose, value, GL_FLOAT_MAT3);
} }
bool ProgramBinary::setUniformMatrix4fv(GLint location, GLsizei count, const GLfloat *value) bool ProgramBinary::setUniformMatrix4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value)
{ {
return setUniformMatrixfv<4, 4>(location, count, value, GL_FLOAT_MAT4); return setUniformMatrixfv<4, 4>(location, count, transpose, value, GL_FLOAT_MAT4);
} }
bool ProgramBinary::setUniformMatrix2x3fv(GLint location, GLsizei count, const GLfloat *value) bool ProgramBinary::setUniformMatrix2x3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value)
{ {
return setUniformMatrixfv<2, 3>(location, count, value, GL_FLOAT_MAT2x3); return setUniformMatrixfv<2, 3>(location, count, transpose, value, GL_FLOAT_MAT2x3);
} }
bool ProgramBinary::setUniformMatrix3x2fv(GLint location, GLsizei count, const GLfloat *value) bool ProgramBinary::setUniformMatrix3x2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value)
{ {
return setUniformMatrixfv<3, 2>(location, count, value, GL_FLOAT_MAT3x2); return setUniformMatrixfv<3, 2>(location, count, transpose, value, GL_FLOAT_MAT3x2);
} }
bool ProgramBinary::setUniformMatrix2x4fv(GLint location, GLsizei count, const GLfloat *value) bool ProgramBinary::setUniformMatrix2x4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value)
{ {
return setUniformMatrixfv<2, 4>(location, count, value, GL_FLOAT_MAT2x4); return setUniformMatrixfv<2, 4>(location, count, transpose, value, GL_FLOAT_MAT2x4);
} }
bool ProgramBinary::setUniformMatrix4x2fv(GLint location, GLsizei count, const GLfloat *value) bool ProgramBinary::setUniformMatrix4x2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value)
{ {
return setUniformMatrixfv<4, 2>(location, count, value, GL_FLOAT_MAT4x2); return setUniformMatrixfv<4, 2>(location, count, transpose, value, GL_FLOAT_MAT4x2);
} }
bool ProgramBinary::setUniformMatrix3x4fv(GLint location, GLsizei count, const GLfloat *value) bool ProgramBinary::setUniformMatrix3x4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value)
{ {
return setUniformMatrixfv<3, 4>(location, count, value, GL_FLOAT_MAT3x4); return setUniformMatrixfv<3, 4>(location, count, transpose, value, GL_FLOAT_MAT3x4);
} }
bool ProgramBinary::setUniformMatrix4x3fv(GLint location, GLsizei count, const GLfloat *value) bool ProgramBinary::setUniformMatrix4x3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value)
{ {
return setUniformMatrixfv<4, 3>(location, count, value, GL_FLOAT_MAT4x3); return setUniformMatrixfv<4, 3>(location, count, transpose, value, GL_FLOAT_MAT4x3);
} }
bool ProgramBinary::setUniform1iv(GLint location, GLsizei count, const GLint *v) bool ProgramBinary::setUniform1iv(GLint location, GLsizei count, const GLint *v)
......
...@@ -81,19 +81,19 @@ class ProgramBinary : public RefCountObject ...@@ -81,19 +81,19 @@ class ProgramBinary : public RefCountObject
bool setUniform2fv(GLint location, GLsizei count, const GLfloat *v); bool setUniform2fv(GLint location, GLsizei count, const GLfloat *v);
bool setUniform3fv(GLint location, GLsizei count, const GLfloat *v); bool setUniform3fv(GLint location, GLsizei count, const GLfloat *v);
bool setUniform4fv(GLint location, GLsizei count, const GLfloat *v); bool setUniform4fv(GLint location, GLsizei count, const GLfloat *v);
bool setUniformMatrix2fv(GLint location, GLsizei count, const GLfloat *value); bool setUniformMatrix2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
bool setUniformMatrix3fv(GLint location, GLsizei count, const GLfloat *value); bool setUniformMatrix3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
bool setUniformMatrix4fv(GLint location, GLsizei count, const GLfloat *value); bool setUniformMatrix4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
bool setUniform1iv(GLint location, GLsizei count, const GLint *v); bool setUniform1iv(GLint location, GLsizei count, const GLint *v);
bool setUniform2iv(GLint location, GLsizei count, const GLint *v); bool setUniform2iv(GLint location, GLsizei count, const GLint *v);
bool setUniform3iv(GLint location, GLsizei count, const GLint *v); bool setUniform3iv(GLint location, GLsizei count, const GLint *v);
bool setUniform4iv(GLint location, GLsizei count, const GLint *v); bool setUniform4iv(GLint location, GLsizei count, const GLint *v);
bool setUniformMatrix2x3fv(GLint location, GLsizei count, const GLfloat *value); bool setUniformMatrix2x3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
bool setUniformMatrix3x2fv(GLint location, GLsizei count, const GLfloat *value); bool setUniformMatrix3x2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
bool setUniformMatrix2x4fv(GLint location, GLsizei count, const GLfloat *value); bool setUniformMatrix2x4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
bool setUniformMatrix4x2fv(GLint location, GLsizei count, const GLfloat *value); bool setUniformMatrix4x2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
bool setUniformMatrix3x4fv(GLint location, GLsizei count, const GLfloat *value); bool setUniformMatrix3x4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
bool setUniformMatrix4x3fv(GLint location, GLsizei count, const GLfloat *value); bool setUniformMatrix4x3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
bool getUniformfv(GLint location, GLsizei *bufSize, GLfloat *params); bool getUniformfv(GLint location, GLsizei *bufSize, GLfloat *params);
bool getUniformiv(GLint location, GLsizei *bufSize, GLint *params); bool getUniformiv(GLint location, GLsizei *bufSize, GLint *params);
...@@ -143,7 +143,7 @@ class ProgramBinary : public RefCountObject ...@@ -143,7 +143,7 @@ class ProgramBinary : public RefCountObject
std::string generatePointSpriteHLSL(int registers, const Varying *packing[][4], FragmentShader *fragmentShader, VertexShader *vertexShader) const; std::string generatePointSpriteHLSL(int registers, const Varying *packing[][4], FragmentShader *fragmentShader, VertexShader *vertexShader) const;
template <int cols, int rows> template <int cols, int rows>
bool setUniformMatrixfv(GLint location, GLsizei count, const GLfloat *value, GLenum targetUniformType); bool setUniformMatrixfv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value, GLenum targetUniformType);
rx::Renderer *const mRenderer; rx::Renderer *const mRenderer;
......
...@@ -6481,7 +6481,7 @@ void __stdcall glUniformMatrix2fv(GLint location, GLsizei count, GLboolean trans ...@@ -6481,7 +6481,7 @@ void __stdcall glUniformMatrix2fv(GLint location, GLsizei count, GLboolean trans
try try
{ {
if (count < 0 || transpose != GL_FALSE) if (count < 0)
{ {
return gl::error(GL_INVALID_VALUE); return gl::error(GL_INVALID_VALUE);
} }
...@@ -6495,13 +6495,18 @@ void __stdcall glUniformMatrix2fv(GLint location, GLsizei count, GLboolean trans ...@@ -6495,13 +6495,18 @@ void __stdcall glUniformMatrix2fv(GLint location, GLsizei count, GLboolean trans
if (context) if (context)
{ {
if (transpose != GL_FALSE && context->getClientVersion() < 3)
{
return gl::error(GL_INVALID_VALUE);
}
gl::ProgramBinary *programBinary = context->getCurrentProgramBinary(); gl::ProgramBinary *programBinary = context->getCurrentProgramBinary();
if (!programBinary) if (!programBinary)
{ {
return gl::error(GL_INVALID_OPERATION); return gl::error(GL_INVALID_OPERATION);
} }
if (!programBinary->setUniformMatrix2fv(location, count, value)) if (!programBinary->setUniformMatrix2fv(location, count, transpose, value))
{ {
return gl::error(GL_INVALID_OPERATION); return gl::error(GL_INVALID_OPERATION);
} }
...@@ -6520,7 +6525,7 @@ void __stdcall glUniformMatrix3fv(GLint location, GLsizei count, GLboolean trans ...@@ -6520,7 +6525,7 @@ void __stdcall glUniformMatrix3fv(GLint location, GLsizei count, GLboolean trans
try try
{ {
if (count < 0 || transpose != GL_FALSE) if (count < 0)
{ {
return gl::error(GL_INVALID_VALUE); return gl::error(GL_INVALID_VALUE);
} }
...@@ -6534,13 +6539,18 @@ void __stdcall glUniformMatrix3fv(GLint location, GLsizei count, GLboolean trans ...@@ -6534,13 +6539,18 @@ void __stdcall glUniformMatrix3fv(GLint location, GLsizei count, GLboolean trans
if (context) if (context)
{ {
if (transpose != GL_FALSE && context->getClientVersion() < 3)
{
return gl::error(GL_INVALID_VALUE);
}
gl::ProgramBinary *programBinary = context->getCurrentProgramBinary(); gl::ProgramBinary *programBinary = context->getCurrentProgramBinary();
if (!programBinary) if (!programBinary)
{ {
return gl::error(GL_INVALID_OPERATION); return gl::error(GL_INVALID_OPERATION);
} }
if (!programBinary->setUniformMatrix3fv(location, count, value)) if (!programBinary->setUniformMatrix3fv(location, count, transpose, value))
{ {
return gl::error(GL_INVALID_OPERATION); return gl::error(GL_INVALID_OPERATION);
} }
...@@ -6559,7 +6569,7 @@ void __stdcall glUniformMatrix4fv(GLint location, GLsizei count, GLboolean trans ...@@ -6559,7 +6569,7 @@ void __stdcall glUniformMatrix4fv(GLint location, GLsizei count, GLboolean trans
try try
{ {
if (count < 0 || transpose != GL_FALSE) if (count < 0)
{ {
return gl::error(GL_INVALID_VALUE); return gl::error(GL_INVALID_VALUE);
} }
...@@ -6573,13 +6583,18 @@ void __stdcall glUniformMatrix4fv(GLint location, GLsizei count, GLboolean trans ...@@ -6573,13 +6583,18 @@ void __stdcall glUniformMatrix4fv(GLint location, GLsizei count, GLboolean trans
if (context) if (context)
{ {
if (transpose != GL_FALSE && context->getClientVersion() < 3)
{
return gl::error(GL_INVALID_VALUE);
}
gl::ProgramBinary *programBinary = context->getCurrentProgramBinary(); gl::ProgramBinary *programBinary = context->getCurrentProgramBinary();
if (!programBinary) if (!programBinary)
{ {
return gl::error(GL_INVALID_OPERATION); return gl::error(GL_INVALID_OPERATION);
} }
if (!programBinary->setUniformMatrix4fv(location, count, value)) if (!programBinary->setUniformMatrix4fv(location, count, transpose, value))
{ {
return gl::error(GL_INVALID_OPERATION); return gl::error(GL_INVALID_OPERATION);
} }
...@@ -7436,7 +7451,7 @@ void __stdcall glUniformMatrix2x3fv(GLint location, GLsizei count, GLboolean tra ...@@ -7436,7 +7451,7 @@ void __stdcall glUniformMatrix2x3fv(GLint location, GLsizei count, GLboolean tra
return gl::error(GL_INVALID_OPERATION); return gl::error(GL_INVALID_OPERATION);
} }
if (!programBinary->setUniformMatrix2x3fv(location, count, value)) if (!programBinary->setUniformMatrix2x3fv(location, count, transpose, value))
{ {
return gl::error(GL_INVALID_OPERATION); return gl::error(GL_INVALID_OPERATION);
} }
...@@ -7480,7 +7495,7 @@ void __stdcall glUniformMatrix3x2fv(GLint location, GLsizei count, GLboolean tra ...@@ -7480,7 +7495,7 @@ void __stdcall glUniformMatrix3x2fv(GLint location, GLsizei count, GLboolean tra
return gl::error(GL_INVALID_OPERATION); return gl::error(GL_INVALID_OPERATION);
} }
if (!programBinary->setUniformMatrix3x2fv(location, count, value)) if (!programBinary->setUniformMatrix3x2fv(location, count, transpose, value))
{ {
return gl::error(GL_INVALID_OPERATION); return gl::error(GL_INVALID_OPERATION);
} }
...@@ -7524,7 +7539,7 @@ void __stdcall glUniformMatrix2x4fv(GLint location, GLsizei count, GLboolean tra ...@@ -7524,7 +7539,7 @@ void __stdcall glUniformMatrix2x4fv(GLint location, GLsizei count, GLboolean tra
return gl::error(GL_INVALID_OPERATION); return gl::error(GL_INVALID_OPERATION);
} }
if (!programBinary->setUniformMatrix2x4fv(location, count, value)) if (!programBinary->setUniformMatrix2x4fv(location, count, transpose, value))
{ {
return gl::error(GL_INVALID_OPERATION); return gl::error(GL_INVALID_OPERATION);
} }
...@@ -7568,7 +7583,7 @@ void __stdcall glUniformMatrix4x2fv(GLint location, GLsizei count, GLboolean tra ...@@ -7568,7 +7583,7 @@ void __stdcall glUniformMatrix4x2fv(GLint location, GLsizei count, GLboolean tra
return gl::error(GL_INVALID_OPERATION); return gl::error(GL_INVALID_OPERATION);
} }
if (!programBinary->setUniformMatrix4x2fv(location, count, value)) if (!programBinary->setUniformMatrix4x2fv(location, count, transpose, value))
{ {
return gl::error(GL_INVALID_OPERATION); return gl::error(GL_INVALID_OPERATION);
} }
...@@ -7612,7 +7627,7 @@ void __stdcall glUniformMatrix3x4fv(GLint location, GLsizei count, GLboolean tra ...@@ -7612,7 +7627,7 @@ void __stdcall glUniformMatrix3x4fv(GLint location, GLsizei count, GLboolean tra
return gl::error(GL_INVALID_OPERATION); return gl::error(GL_INVALID_OPERATION);
} }
if (!programBinary->setUniformMatrix3x4fv(location, count, value)) if (!programBinary->setUniformMatrix3x4fv(location, count, transpose, value))
{ {
return gl::error(GL_INVALID_OPERATION); return gl::error(GL_INVALID_OPERATION);
} }
...@@ -7656,7 +7671,7 @@ void __stdcall glUniformMatrix4x3fv(GLint location, GLsizei count, GLboolean tra ...@@ -7656,7 +7671,7 @@ void __stdcall glUniformMatrix4x3fv(GLint location, GLsizei count, GLboolean tra
return gl::error(GL_INVALID_OPERATION); return gl::error(GL_INVALID_OPERATION);
} }
if (!programBinary->setUniformMatrix4x3fv(location, count, value)) if (!programBinary->setUniformMatrix4x3fv(location, count, transpose, value))
{ {
return gl::error(GL_INVALID_OPERATION); return gl::error(GL_INVALID_OPERATION);
} }
......
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