Refactor ProgramBinary::setUniform[XX] to use a generic template function,…

Refactor ProgramBinary::setUniform[XX] to use a generic template function, reducing duplicated code. TRAC #22842 Signed-off-by: Geoff Lang Signed-off-by: Shanon Woods Author: Jamie Madill git-svn-id: https://angleproject.googlecode.com/svn/branches/es3proto@2141 736b8ea6-26fd-11df-bfd4-992fa37f6226
parent 8431b9c8
...@@ -247,13 +247,17 @@ GLint ProgramBinary::getUniformLocation(std::string name) ...@@ -247,13 +247,17 @@ GLint ProgramBinary::getUniformLocation(std::string name)
return -1; return -1;
} }
bool ProgramBinary::setUniform1fv(GLint location, GLsizei count, const GLfloat* v) template <typename T>
bool ProgramBinary::setUniform(GLint location, GLsizei count, const T* v, GLenum targetUniformType)
{ {
if (location < 0 || location >= (int)mUniformIndex.size()) if (location < 0 || location >= (int)mUniformIndex.size())
{ {
return false; return false;
} }
const int components = UniformComponentCount(targetUniformType);
const GLenum targetBoolType = UniformBoolVectorType(targetUniformType);
Uniform *targetUniform = mUniforms[mUniformIndex[location].index]; Uniform *targetUniform = mUniforms[mUniformIndex[location].index];
targetUniform->dirty = true; targetUniform->dirty = true;
...@@ -264,138 +268,40 @@ bool ProgramBinary::setUniform1fv(GLint location, GLsizei count, const GLfloat* ...@@ -264,138 +268,40 @@ bool ProgramBinary::setUniform1fv(GLint location, GLsizei count, const GLfloat*
count = std::min(elementCount - (int)mUniformIndex[location].element, count); count = std::min(elementCount - (int)mUniformIndex[location].element, count);
if (targetUniform->type == GL_FLOAT) if (targetUniform->type == targetUniformType)
{ {
GLfloat *target = (GLfloat*)targetUniform->data + mUniformIndex[location].element * 4; T *target = (T*)targetUniform->data + mUniformIndex[location].element * 4;
for (int i = 0; i < count; i++) for (int i = 0; i < count; i++)
{ {
target[0] = v[0]; for (int c = 0; c < components; c++)
target[1] = 0;
target[2] = 0;
target[3] = 0;
target += 4;
v += 1;
}
}
else if (targetUniform->type == GL_BOOL)
{
GLint *boolParams = (GLint*)targetUniform->data + mUniformIndex[location].element * 4;
for (int i = 0; i < count; i++)
{ {
boolParams[0] = (v[0] == 0.0f) ? GL_FALSE : GL_TRUE; target[c] = v[c];
boolParams[1] = GL_FALSE;
boolParams[2] = GL_FALSE;
boolParams[3] = GL_FALSE;
boolParams += 4;
v += 1;
}
}
else
{
return false;
} }
for (int c = components; c < 4; c++)
return true;
}
bool ProgramBinary::setUniform2fv(GLint location, GLsizei count, const GLfloat *v)
{
if (location < 0 || location >= (int)mUniformIndex.size())
{ {
return false; target[c] = 0;
} }
Uniform *targetUniform = mUniforms[mUniformIndex[location].index];
targetUniform->dirty = true;
int elementCount = targetUniform->elementCount();
if (elementCount == 1 && count > 1)
return false; // attempting to write an array to a non-array uniform is an INVALID_OPERATION
count = std::min(elementCount - (int)mUniformIndex[location].element, count);
if (targetUniform->type == GL_FLOAT_VEC2)
{
GLfloat *target = (GLfloat*)targetUniform->data + mUniformIndex[location].element * 4;
for (int i = 0; i < count; i++)
{
target[0] = v[0];
target[1] = v[1];
target[2] = 0;
target[3] = 0;
target += 4; target += 4;
v += 2; v += components;
} }
} }
else if (targetUniform->type == GL_BOOL_VEC2) else if (targetUniform->type == targetBoolType)
{ {
GLint *boolParams = (GLint*)targetUniform->data + mUniformIndex[location].element * 4; GLint *boolParams = (GLint*)targetUniform->data + mUniformIndex[location].element * 4;
for (int i = 0; i < count; i++) for (int i = 0; i < count; i++)
{ {
boolParams[0] = (v[0] == 0.0f) ? GL_FALSE : GL_TRUE; for (int c = 0; c < components; c++)
boolParams[1] = (v[1] == 0.0f) ? GL_FALSE : GL_TRUE;
boolParams[2] = GL_FALSE;
boolParams[3] = GL_FALSE;
boolParams += 4;
v += 2;
}
}
else
{
return false;
}
return true;
}
bool ProgramBinary::setUniform3fv(GLint location, GLsizei count, const GLfloat *v)
{
if (location < 0 || location >= (int)mUniformIndex.size())
{ {
return false; boolParams[c] = (v[c] == static_cast<T>(0)) ? GL_FALSE : GL_TRUE;
} }
for (int c = components; c < 4; c++)
Uniform *targetUniform = mUniforms[mUniformIndex[location].index];
targetUniform->dirty = true;
int elementCount = targetUniform->elementCount();
if (elementCount == 1 && count > 1)
return false; // attempting to write an array to a non-array uniform is an INVALID_OPERATION
count = std::min(elementCount - (int)mUniformIndex[location].element, count);
if (targetUniform->type == GL_FLOAT_VEC3)
{
GLfloat *target = (GLfloat*)targetUniform->data + mUniformIndex[location].element * 4;
for (int i = 0; i < count; i++)
{ {
target[0] = v[0]; boolParams[c] = GL_FALSE;
target[1] = v[1];
target[2] = v[2];
target[3] = 0;
target += 4;
v += 3;
}
} }
else if (targetUniform->type == GL_BOOL_VEC3)
{
GLint *boolParams = (GLint*)targetUniform->data + mUniformIndex[location].element * 4;
for (int i = 0; i < count; i++)
{
boolParams[0] = (v[0] == 0.0f) ? GL_FALSE : GL_TRUE;
boolParams[1] = (v[1] == 0.0f) ? GL_FALSE : GL_TRUE;
boolParams[2] = (v[2] == 0.0f) ? GL_FALSE : GL_TRUE;
boolParams[3] = GL_FALSE;
boolParams += 4; boolParams += 4;
v += 3; v += components;
} }
} }
else else
...@@ -406,57 +312,24 @@ bool ProgramBinary::setUniform3fv(GLint location, GLsizei count, const GLfloat * ...@@ -406,57 +312,24 @@ bool ProgramBinary::setUniform3fv(GLint location, GLsizei count, const GLfloat *
return true; return true;
} }
bool ProgramBinary::setUniform4fv(GLint location, GLsizei count, const GLfloat *v) bool ProgramBinary::setUniform1fv(GLint location, GLsizei count, const GLfloat* v)
{ {
if (location < 0 || location >= (int)mUniformIndex.size()) return setUniform(location, count, v, GL_FLOAT);
{ }
return false;
}
Uniform *targetUniform = mUniforms[mUniformIndex[location].index];
targetUniform->dirty = true;
int elementCount = targetUniform->elementCount();
if (elementCount == 1 && count > 1)
return false; // attempting to write an array to a non-array uniform is an INVALID_OPERATION
count = std::min(elementCount - (int)mUniformIndex[location].element, count);
if (targetUniform->type == GL_FLOAT_VEC4)
{
GLfloat *target = (GLfloat*)targetUniform->data + mUniformIndex[location].element * 4;
for (int i = 0; i < count; i++) bool ProgramBinary::setUniform2fv(GLint location, GLsizei count, const GLfloat *v)
{ {
target[0] = v[0]; return setUniform(location, count, v, GL_FLOAT_VEC2);
target[1] = v[1]; }
target[2] = v[2];
target[3] = v[3];
target += 4;
v += 4;
}
}
else if (targetUniform->type == GL_BOOL_VEC4)
{
GLint *boolParams = (GLint*)targetUniform->data + mUniformIndex[location].element * 4;
for (int i = 0; i < count; i++) bool ProgramBinary::setUniform3fv(GLint location, GLsizei count, const GLfloat *v)
{ {
boolParams[0] = (v[0] == 0.0f) ? GL_FALSE : GL_TRUE; return setUniform(location, count, v, GL_FLOAT_VEC3);
boolParams[1] = (v[1] == 0.0f) ? GL_FALSE : GL_TRUE; }
boolParams[2] = (v[2] == 0.0f) ? GL_FALSE : GL_TRUE;
boolParams[3] = (v[3] == 0.0f) ? GL_FALSE : GL_TRUE;
boolParams += 4;
v += 4;
}
}
else
{
return false;
}
return true; bool ProgramBinary::setUniform4fv(GLint location, GLsizei count, const GLfloat *v)
{
return setUniform(location, count, v, GL_FLOAT_VEC4);
} }
template<typename T> template<typename T>
...@@ -665,161 +538,17 @@ bool ProgramBinary::setUniform1iv(GLint location, GLsizei count, const GLint *v) ...@@ -665,161 +538,17 @@ bool ProgramBinary::setUniform1iv(GLint location, GLsizei count, const GLint *v)
bool ProgramBinary::setUniform2iv(GLint location, GLsizei count, const GLint *v) bool ProgramBinary::setUniform2iv(GLint location, GLsizei count, const GLint *v)
{ {
if (location < 0 || location >= (int)mUniformIndex.size()) return setUniform(location, count, v, GL_INT_VEC2);
{
return false;
}
Uniform *targetUniform = mUniforms[mUniformIndex[location].index];
targetUniform->dirty = true;
int elementCount = targetUniform->elementCount();
if (elementCount == 1 && count > 1)
return false; // attempting to write an array to a non-array uniform is an INVALID_OPERATION
count = std::min(elementCount - (int)mUniformIndex[location].element, count);
if (targetUniform->type == GL_INT_VEC2)
{
GLint *target = (GLint*)targetUniform->data + mUniformIndex[location].element * 4;
for (int i = 0; i < count; i++)
{
target[0] = v[0];
target[1] = v[1];
target[2] = 0;
target[3] = 0;
target += 4;
v += 2;
}
}
else if (targetUniform->type == GL_BOOL_VEC2)
{
GLint *boolParams = (GLint*)targetUniform->data + mUniformIndex[location].element * 4;
for (int i = 0; i < count; i++)
{
boolParams[0] = (v[0] == 0) ? GL_FALSE : GL_TRUE;
boolParams[1] = (v[1] == 0) ? GL_FALSE : GL_TRUE;
boolParams[2] = GL_FALSE;
boolParams[3] = GL_FALSE;
boolParams += 4;
v += 2;
}
}
else
{
return false;
}
return true;
} }
bool ProgramBinary::setUniform3iv(GLint location, GLsizei count, const GLint *v) bool ProgramBinary::setUniform3iv(GLint location, GLsizei count, const GLint *v)
{ {
if (location < 0 || location >= (int)mUniformIndex.size()) return setUniform(location, count, v, GL_INT_VEC3);
{
return false;
}
Uniform *targetUniform = mUniforms[mUniformIndex[location].index];
targetUniform->dirty = true;
int elementCount = targetUniform->elementCount();
if (elementCount == 1 && count > 1)
return false; // attempting to write an array to a non-array uniform is an INVALID_OPERATION
count = std::min(elementCount - (int)mUniformIndex[location].element, count);
if (targetUniform->type == GL_INT_VEC3)
{
GLint *target = (GLint*)targetUniform->data + mUniformIndex[location].element * 4;
for (int i = 0; i < count; i++)
{
target[0] = v[0];
target[1] = v[1];
target[2] = v[2];
target[3] = 0;
target += 4;
v += 3;
}
}
else if (targetUniform->type == GL_BOOL_VEC3)
{
GLint *boolParams = (GLint*)targetUniform->data + mUniformIndex[location].element * 4;
for (int i = 0; i < count; i++)
{
boolParams[0] = (v[0] == 0) ? GL_FALSE : GL_TRUE;
boolParams[1] = (v[1] == 0) ? GL_FALSE : GL_TRUE;
boolParams[2] = (v[2] == 0) ? GL_FALSE : GL_TRUE;
boolParams[3] = GL_FALSE;
boolParams += 4;
v += 3;
}
}
else
{
return false;
}
return true;
} }
bool ProgramBinary::setUniform4iv(GLint location, GLsizei count, const GLint *v) bool ProgramBinary::setUniform4iv(GLint location, GLsizei count, const GLint *v)
{ {
if (location < 0 || location >= (int)mUniformIndex.size()) return setUniform(location, count, v, GL_INT_VEC4);
{
return false;
}
Uniform *targetUniform = mUniforms[mUniformIndex[location].index];
targetUniform->dirty = true;
int elementCount = targetUniform->elementCount();
if (elementCount == 1 && count > 1)
return false; // attempting to write an array to a non-array uniform is an INVALID_OPERATION
count = std::min(elementCount - (int)mUniformIndex[location].element, count);
if (targetUniform->type == GL_INT_VEC4)
{
GLint *target = (GLint*)targetUniform->data + mUniformIndex[location].element * 4;
for (int i = 0; i < count; i++)
{
target[0] = v[0];
target[1] = v[1];
target[2] = v[2];
target[3] = v[3];
target += 4;
v += 4;
}
}
else if (targetUniform->type == GL_BOOL_VEC4)
{
GLint *boolParams = (GLint*)targetUniform->data + mUniformIndex[location].element * 4;
for (int i = 0; i < count; i++)
{
boolParams[0] = (v[0] == 0) ? GL_FALSE : GL_TRUE;
boolParams[1] = (v[1] == 0) ? GL_FALSE : GL_TRUE;
boolParams[2] = (v[2] == 0) ? GL_FALSE : GL_TRUE;
boolParams[3] = (v[3] == 0) ? GL_FALSE : GL_TRUE;
boolParams += 4;
v += 4;
}
}
else
{
return false;
}
return true;
} }
bool ProgramBinary::getUniformfv(GLint location, GLsizei *bufSize, GLfloat *params) bool ProgramBinary::getUniformfv(GLint location, GLsizei *bufSize, GLfloat *params)
......
...@@ -142,6 +142,9 @@ class ProgramBinary : public RefCountObject ...@@ -142,6 +142,9 @@ class ProgramBinary : public RefCountObject
std::string generateGeometryShaderHLSL(int registers, const Varying *packing[][4], FragmentShader *fragmentShader, VertexShader *vertexShader) const; std::string generateGeometryShaderHLSL(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; std::string generatePointSpriteHLSL(int registers, const Varying *packing[][4], FragmentShader *fragmentShader, VertexShader *vertexShader) const;
template <typename T>
bool setUniform(GLint location, GLsizei count, const T* v, GLenum targetUniformType);
template <int cols, int rows> template <int cols, int rows>
bool setUniformMatrixfv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value, GLenum targetUniformType); bool setUniformMatrixfv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value, GLenum targetUniformType);
......
...@@ -102,6 +102,29 @@ size_t UniformExternalSize(GLenum type) ...@@ -102,6 +102,29 @@ size_t UniformExternalSize(GLenum type)
return UniformComponentSize(UniformComponentType(type)) * UniformComponentCount(type); return UniformComponentSize(UniformComponentType(type)) * UniformComponentCount(type);
} }
GLenum UniformBoolVectorType(GLenum type)
{
switch (type)
{
case GL_FLOAT:
case GL_INT:
return GL_BOOL;
case GL_FLOAT_VEC2:
case GL_INT_VEC2:
return GL_BOOL_VEC2;
case GL_FLOAT_VEC3:
case GL_INT_VEC3:
return GL_BOOL_VEC3;
case GL_FLOAT_VEC4:
case GL_INT_VEC4:
return GL_BOOL_VEC4;
default:
UNREACHABLE();
return GL_NONE;
}
}
int VariableRowCount(GLenum type) int VariableRowCount(GLenum type)
{ {
switch (type) switch (type)
......
...@@ -26,6 +26,7 @@ int UniformComponentCount(GLenum type); ...@@ -26,6 +26,7 @@ int UniformComponentCount(GLenum type);
GLenum UniformComponentType(GLenum type); GLenum UniformComponentType(GLenum type);
size_t UniformInternalSize(GLenum type); size_t UniformInternalSize(GLenum type);
size_t UniformExternalSize(GLenum type); size_t UniformExternalSize(GLenum type);
GLenum UniformBoolVectorType(GLenum type);
int VariableRowCount(GLenum type); int VariableRowCount(GLenum type);
int VariableColumnCount(GLenum type); int VariableColumnCount(GLenum type);
......
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