Implements support for boolean uniforms
TRAC #11734
Signed-off-by: Nicolas Capens
Signed-off-by: Daniel Koch
Author: Shannon Woods
git-svn-id: https://angleproject.googlecode.com/svn/trunk@121 736b8ea6-26fd-11df-bfd4-992fa37f6226
diff --git a/src/libGLESv2/Program.cpp b/src/libGLESv2/Program.cpp
index 7cdd898..fb4bd08 100644
--- a/src/libGLESv2/Program.cpp
+++ b/src/libGLESv2/Program.cpp
@@ -211,13 +211,48 @@
return false;
}
- if (mUniforms[location]->type != GL_FLOAT || mUniforms[location]->bytes < sizeof(GLfloat) * count)
+ if (mUniforms[location]->type == GL_FLOAT)
+ {
+ int arraySize = mUniforms[location]->bytes / sizeof(GLfloat);
+
+ if (arraySize == 1 && count > 1)
+ return false; // attempting to write an array to a non-array uniform is an INVALID_OPERATION
+
+ count = std::min(arraySize, count);
+
+ memcpy(mUniforms[location]->data, v, sizeof(GLfloat) * count);
+ }
+ else if (mUniforms[location]->type == GL_BOOL)
+ {
+ int arraySize = mUniforms[location]->bytes / sizeof(GLboolean);
+
+ if (arraySize == 1 && count > 1)
+ return false; // attempting to write an array to a non-array uniform is an INVALID_OPERATION
+
+ count = std::min(arraySize, count);
+ GLboolean *boolParams = new GLboolean[count];
+
+ for (int i = 0; i < count; ++i)
+ {
+ if (v[i] == 0.0f)
+ {
+ boolParams[i] = GL_FALSE;
+ }
+ else
+ {
+ boolParams[i] = GL_TRUE;
+ }
+ }
+
+ memcpy(mUniforms[location]->data, boolParams, sizeof(GLboolean) * count);
+
+ delete [] boolParams;
+ }
+ else
{
return false;
}
- memcpy(mUniforms[location]->data, v, sizeof(GLfloat) * count);
-
return true;
}
@@ -228,13 +263,48 @@
return false;
}
- if (mUniforms[location]->type != GL_FLOAT_VEC2 || mUniforms[location]->bytes < 2 * sizeof(GLfloat) * count)
+ if (mUniforms[location]->type == GL_FLOAT_VEC2)
+ {
+ int arraySize = mUniforms[location]->bytes / sizeof(GLfloat) / 2;
+
+ if (arraySize == 1 && count > 1)
+ return false; // attempting to write an array to a non-array uniform is an INVALID_OPERATION
+
+ count = std::min(arraySize, count);
+
+ memcpy(mUniforms[location]->data, v, 2 * sizeof(GLfloat) * count);
+ }
+ else if (mUniforms[location]->type == GL_BOOL_VEC2)
+ {
+ int arraySize = mUniforms[location]->bytes / sizeof(GLboolean) / 2;
+
+ if (arraySize == 1 && count > 1)
+ return false; // attempting to write an array to a non-array uniform is an INVALID_OPERATION
+
+ count = std::min(arraySize, count);
+ GLboolean *boolParams = new GLboolean[count * 2];
+
+ for (int i = 0; i < count * 2; ++i)
+ {
+ if (v[i] == 0.0f)
+ {
+ boolParams[i] = GL_FALSE;
+ }
+ else
+ {
+ boolParams[i] = GL_TRUE;
+ }
+ }
+
+ memcpy(mUniforms[location]->data, boolParams, 2 * sizeof(GLboolean) * count);
+
+ delete [] boolParams;
+ }
+ else
{
return false;
}
- memcpy(mUniforms[location]->data, v, 2 * sizeof(GLfloat) * count);
-
return true;
}
@@ -245,13 +315,48 @@
return false;
}
- if (mUniforms[location]->type != GL_FLOAT_VEC3 || mUniforms[location]->bytes < 3 * sizeof(GLfloat) * count)
+ if (mUniforms[location]->type == GL_FLOAT_VEC3)
+ {
+ int arraySize = mUniforms[location]->bytes / sizeof(GLfloat) / 3;
+
+ if (arraySize == 1 && count > 1)
+ return false; // attempting to write an array to a non-array uniform is an INVALID_OPERATION
+
+ count = std::min(arraySize, count);
+
+ memcpy(mUniforms[location]->data, v, 3 * sizeof(GLfloat) * count);
+ }
+ else if (mUniforms[location]->type == GL_BOOL_VEC3)
+ {
+ int arraySize = mUniforms[location]->bytes / sizeof(GLboolean) / 3;
+
+ if (arraySize == 1 && count > 1)
+ return false; // attempting to write an array to a non-array uniform is an INVALID_OPERATION
+
+ count = std::min(arraySize, count);
+ GLboolean *boolParams = new GLboolean[count * 3];
+
+ for (int i = 0; i < count * 3; ++i)
+ {
+ if (v[i] == 0.0f)
+ {
+ boolParams[i] = GL_FALSE;
+ }
+ else
+ {
+ boolParams[i] = GL_TRUE;
+ }
+ }
+
+ memcpy(mUniforms[location]->data, boolParams, 3 * sizeof(GLboolean) * count);
+
+ delete [] boolParams;
+ }
+ else
{
return false;
}
- memcpy(mUniforms[location]->data, v, 3 * sizeof(GLfloat) * count);
-
return true;
}
@@ -262,13 +367,48 @@
return false;
}
- if (mUniforms[location]->type != GL_FLOAT_VEC4 || mUniforms[location]->bytes < 4 * sizeof(GLfloat) * count)
+ if (mUniforms[location]->type == GL_FLOAT_VEC4)
+ {
+ int arraySize = mUniforms[location]->bytes / sizeof(GLfloat) / 4;
+
+ if (arraySize == 1 && count > 1)
+ return false; // attempting to write an array to a non-array uniform is an INVALID_OPERATION
+
+ count = std::min(arraySize, count);
+
+ memcpy(mUniforms[location]->data, v, 4 * sizeof(GLfloat) * count);
+ }
+ else if (mUniforms[location]->type == GL_BOOL_VEC4)
+ {
+ int arraySize = mUniforms[location]->bytes / sizeof(GLboolean) / 4;
+
+ if (arraySize == 1 && count > 1)
+ return false; // attempting to write an array to a non-array uniform is an INVALID_OPERATION
+
+ count = std::min(arraySize, count);
+ GLboolean *boolParams = new GLboolean[count * 4];
+
+ for (int i = 0; i < count * 4; ++i)
+ {
+ if (v[i] == 0.0f)
+ {
+ boolParams[i] = GL_FALSE;
+ }
+ else
+ {
+ boolParams[i] = GL_TRUE;
+ }
+ }
+
+ memcpy(mUniforms[location]->data, boolParams, 4 * sizeof(GLboolean) * count);
+
+ delete [] boolParams;
+ }
+ else
{
return false;
}
- memcpy(mUniforms[location]->data, v, 4 * sizeof(GLfloat) * count);
-
return true;
}
@@ -348,9 +488,14 @@
int bytes = mUniforms[location]->bytes;
GLfloat *f = (GLfloat*)mUniforms[location]->data;
GLint *i = (GLint*)mUniforms[location]->data;
+ GLboolean *b = (GLboolean*)mUniforms[location]->data;
switch (mUniforms[location]->type)
{
+ case GL_BOOL: applyUniform1bv(location, bytes / sizeof(GLboolean), b); break;
+ case GL_BOOL_VEC2: applyUniform2bv(location, bytes / 2 / sizeof(GLboolean), b); break;
+ case GL_BOOL_VEC3: applyUniform3bv(location, bytes / 3 / sizeof(GLboolean), b); break;
+ case GL_BOOL_VEC4: applyUniform4bv(location, bytes / 4 / sizeof(GLboolean), b); break;
case GL_FLOAT: applyUniform1fv(location, bytes / sizeof(GLfloat), f); break;
case GL_FLOAT_VEC2: applyUniform2fv(location, bytes / 2 / sizeof(GLfloat), f); break;
case GL_FLOAT_VEC3: applyUniform3fv(location, bytes / 3 / sizeof(GLfloat), f); break;
@@ -717,13 +862,20 @@
{
case D3DXPT_SAMPLER2D:
case D3DXPT_SAMPLERCUBE:
- case D3DXPT_BOOL:
switch (constantDescription.Columns)
{
case 1: return new Uniform(GL_INT, name, 1 * sizeof(GLint) * constantDescription.Elements);
- default:
- UNIMPLEMENTED(); // FIXME
- UNREACHABLE();
+ default: UNREACHABLE();
+ }
+ break;
+ case D3DXPT_BOOL:
+ switch (constantDescription.Columns)
+ {
+ case 1: return new Uniform(GL_BOOL, name, 1 * sizeof(GLboolean) * constantDescription.Elements);
+ case 2: return new Uniform(GL_BOOL_VEC2, name, 2 * sizeof(GLboolean) * constantDescription.Elements);
+ case 3: return new Uniform(GL_BOOL_VEC3, name, 3 * sizeof(GLboolean) * constantDescription.Elements);
+ case 4: return new Uniform(GL_BOOL_VEC4, name, 4 * sizeof(GLboolean) * constantDescription.Elements);
+ default: UNREACHABLE();
}
break;
case D3DXPT_FLOAT:
@@ -762,6 +914,132 @@
return 0;
}
+bool Program::applyUniform1bv(GLint location, GLsizei count, const GLboolean *v)
+{
+ BOOL *vector = new BOOL[count];
+ for (int i = 0; i < count; i++)
+ {
+ if (v[i] == GL_FALSE)
+ vector[i] = 0;
+ else
+ vector[i] = 1;
+ }
+
+ D3DXHANDLE constantPS = mConstantTablePS->GetConstantByName(0, mUniforms[location]->name.c_str());
+ D3DXHANDLE constantVS = mConstantTableVS->GetConstantByName(0, mUniforms[location]->name.c_str());
+ IDirect3DDevice9 *device = getDevice();
+
+ if (constantPS)
+ {
+ mConstantTablePS->SetBoolArray(device, constantPS, vector, count);
+ }
+
+ if (constantVS)
+ {
+ mConstantTableVS->SetBoolArray(device, constantVS, vector, count);
+ }
+
+ delete [] vector;
+
+ return true;
+}
+
+bool Program::applyUniform2bv(GLint location, GLsizei count, const GLboolean *v)
+{
+ D3DXVECTOR4 *vector = new D3DXVECTOR4[count];
+
+ for (int i = 0; i < count; i++)
+ {
+ vector[i] = D3DXVECTOR4((v[0] == GL_FALSE ? 0.0f : 1.0f),
+ (v[1] == GL_FALSE ? 0.0f : 1.0f), 0, 0);
+
+ v += 2;
+ }
+
+ D3DXHANDLE constantPS = mConstantTablePS->GetConstantByName(0, mUniforms[location]->name.c_str());
+ D3DXHANDLE constantVS = mConstantTableVS->GetConstantByName(0, mUniforms[location]->name.c_str());
+ IDirect3DDevice9 *device = getDevice();
+
+ if (constantPS)
+ {
+ mConstantTablePS->SetVectorArray(device, constantPS, vector, count);
+ }
+
+ if (constantVS)
+ {
+ mConstantTableVS->SetVectorArray(device, constantVS, vector, count);
+ }
+
+ delete[] vector;
+
+ return true;
+}
+
+bool Program::applyUniform3bv(GLint location, GLsizei count, const GLboolean *v)
+{
+ D3DXVECTOR4 *vector = new D3DXVECTOR4[count];
+
+ for (int i = 0; i < count; i++)
+ {
+ vector[i] = D3DXVECTOR4((v[0] == GL_FALSE ? 0.0f : 1.0f),
+ (v[1] == GL_FALSE ? 0.0f : 1.0f),
+ (v[2] == GL_FALSE ? 0.0f : 1.0f), 0);
+
+ v += 3;
+ }
+
+ D3DXHANDLE constantPS = mConstantTablePS->GetConstantByName(0, mUniforms[location]->name.c_str());
+ D3DXHANDLE constantVS = mConstantTableVS->GetConstantByName(0, mUniforms[location]->name.c_str());
+ IDirect3DDevice9 *device = getDevice();
+
+ if (constantPS)
+ {
+ mConstantTablePS->SetVectorArray(device, constantPS, vector, count);
+ }
+
+ if (constantVS)
+ {
+ mConstantTableVS->SetVectorArray(device, constantVS, vector, count);
+ }
+
+ delete[] vector;
+
+ return true;
+}
+
+bool Program::applyUniform4bv(GLint location, GLsizei count, const GLboolean *v)
+{
+ D3DXVECTOR4 *vector = new D3DXVECTOR4[count];
+
+ for (int i = 0; i < count; i++)
+ {
+ vector[i] = D3DXVECTOR4((v[0] == GL_FALSE ? 0.0f : 1.0f),
+ (v[1] == GL_FALSE ? 0.0f : 1.0f),
+ (v[2] == GL_FALSE ? 0.0f : 1.0f),
+ (v[3] == GL_FALSE ? 0.0f : 1.0f));
+
+ v += 3;
+ }
+
+ D3DXHANDLE constantPS = mConstantTablePS->GetConstantByName(0, mUniforms[location]->name.c_str());
+ D3DXHANDLE constantVS = mConstantTableVS->GetConstantByName(0, mUniforms[location]->name.c_str());
+ IDirect3DDevice9 *device = getDevice();
+
+ if (constantPS)
+ {
+ mConstantTablePS->SetVectorArray(device, constantPS, vector, count);
+ }
+
+ if (constantVS)
+ {
+ mConstantTableVS->SetVectorArray(device, constantVS, vector, count);
+ }
+
+ delete [] vector;
+
+ return true;
+}
+
bool Program::applyUniform1fv(GLint location, GLsizei count, const GLfloat *v)
{
D3DXHANDLE constantPS = mConstantTablePS->GetConstantByName(0, mUniforms[location]->name.c_str());
diff --git a/src/libGLESv2/Program.h b/src/libGLESv2/Program.h
index bf60515..a54360a 100644
--- a/src/libGLESv2/Program.h
+++ b/src/libGLESv2/Program.h
@@ -106,6 +106,10 @@
bool defineUniform(const D3DXHANDLE &constantHandle, const D3DXCONSTANT_DESC &constantDescription, std::string name = "");
bool defineUniform(const D3DXCONSTANT_DESC &constantDescription, std::string &name);
Uniform *createUniform(const D3DXCONSTANT_DESC &constantDescription, std::string &name);
+ bool applyUniform1bv(GLint location, GLsizei count, const GLboolean *v);
+ bool applyUniform2bv(GLint location, GLsizei count, const GLboolean *v);
+ bool applyUniform3bv(GLint location, GLsizei count, const GLboolean *v);
+ bool applyUniform4bv(GLint location, GLsizei count, const GLboolean *v);
bool applyUniform1fv(GLint location, GLsizei count, const GLfloat *v);
bool applyUniform2fv(GLint location, GLsizei count, const GLfloat *v);
bool applyUniform3fv(GLint location, GLsizei count, const GLfloat *v);