Implements Uniform*i{v}

TRAC #11649 Signed-off-by: Andrew Lewycky Signed-off-by: Daniel Koch Author: Shannon Woods git-svn-id: https://angleproject.googlecode.com/svn/trunk@122 736b8ea6-26fd-11df-bfd4-992fa37f6226
parent f4a0c8e8
......@@ -419,11 +419,18 @@ bool Program::setUniformMatrix2fv(GLint location, GLsizei count, const GLfloat *
return false;
}
if (mUniforms[location]->type != GL_FLOAT_MAT2 || mUniforms[location]->bytes < 4 * sizeof(GLfloat) * count)
if (mUniforms[location]->type != GL_FLOAT_MAT2)
{
return false;
}
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, value, 4 * sizeof(GLfloat) * count);
return true;
......@@ -436,11 +443,18 @@ bool Program::setUniformMatrix3fv(GLint location, GLsizei count, const GLfloat *
return false;
}
if (mUniforms[location]->type != GL_FLOAT_MAT3 || mUniforms[location]->bytes < 9 * sizeof(GLfloat) * count)
if (mUniforms[location]->type != GL_FLOAT_MAT3)
{
return false;
}
int arraySize = mUniforms[location]->bytes / sizeof(GLfloat) / 9;
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, value, 9 * sizeof(GLfloat) * count);
return true;
......@@ -453,11 +467,18 @@ bool Program::setUniformMatrix4fv(GLint location, GLsizei count, const GLfloat *
return false;
}
if (mUniforms[location]->type != GL_FLOAT_MAT4 || mUniforms[location]->bytes < 16 * sizeof(GLfloat) * count)
if (mUniforms[location]->type != GL_FLOAT_MAT4)
{
return false;
}
int arraySize = mUniforms[location]->bytes / sizeof(GLfloat) / 16;
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, value, 16 * sizeof(GLfloat) * count);
return true;
......@@ -470,12 +491,203 @@ bool Program::setUniform1iv(GLint location, GLsizei count, const GLint *v)
return false;
}
if (mUniforms[location]->type != GL_INT || mUniforms[location]->bytes < sizeof(GLint) * count)
if (mUniforms[location]->type == GL_INT)
{
int arraySize = mUniforms[location]->bytes / sizeof(GLint);
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(GLint) * 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)
{
boolParams[i] = GL_FALSE;
}
else
{
boolParams[i] = GL_TRUE;
}
}
memcpy(mUniforms[location]->data, boolParams, sizeof(GLboolean) * count);
delete [] boolParams;
}
else
{
return false;
}
return true;
}
bool Program::setUniform2iv(GLint location, GLsizei count, const GLint *v)
{
if (location < 0 || location >= (int)mUniforms.size())
{
return false;
}
if (mUniforms[location]->type == GL_INT_VEC2)
{
int arraySize = mUniforms[location]->bytes / sizeof(GLint) / 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(GLint) * 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)
{
boolParams[i] = GL_FALSE;
}
else
{
boolParams[i] = GL_TRUE;
}
}
memcpy(mUniforms[location]->data, boolParams, 2 * sizeof(GLboolean) * count);
delete [] boolParams;
}
else
{
return false;
}
return true;
}
bool Program::setUniform3iv(GLint location, GLsizei count, const GLint *v)
{
if (location < 0 || location >= (int)mUniforms.size())
{
return false;
}
if (mUniforms[location]->type == GL_INT_VEC3)
{
int arraySize = mUniforms[location]->bytes / sizeof(GLint) / 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(GLint) * 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)
{
boolParams[i] = GL_FALSE;
}
else
{
boolParams[i] = GL_TRUE;
}
}
memcpy(mUniforms[location]->data, boolParams, 3 * sizeof(GLboolean) * count);
delete [] boolParams;
}
else
{
return false;
}
return true;
}
bool Program::setUniform4iv(GLint location, GLsizei count, const GLint *v)
{
if (location < 0 || location >= (int)mUniforms.size())
{
return false;
}
memcpy(mUniforms[location]->data, v, sizeof(GLint) * count);
if (mUniforms[location]->type == GL_INT_VEC4)
{
int arraySize = mUniforms[location]->bytes / sizeof(GLint) / 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(GLint) * 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)
{
boolParams[i] = GL_FALSE;
}
else
{
boolParams[i] = GL_TRUE;
}
}
memcpy(mUniforms[location]->data, boolParams, 4 * sizeof(GLboolean) * count);
delete [] boolParams;
}
else
{
return false;
}
return true;
}
......@@ -504,6 +716,9 @@ void Program::applyUniforms()
case GL_FLOAT_MAT3: applyUniformMatrix3fv(location, bytes / 9 / sizeof(GLfloat), f); break;
case GL_FLOAT_MAT4: applyUniformMatrix4fv(location, bytes / 16 / sizeof(GLfloat), f); break;
case GL_INT: applyUniform1iv(location, bytes / sizeof(GLint), i); break;
case GL_INT_VEC2: applyUniform2iv(location, bytes / 2 / sizeof(GLint), i); break;
case GL_INT_VEC3: applyUniform3iv(location, bytes / 3 / sizeof(GLint), i); break;
case GL_INT_VEC4: applyUniform4iv(location, bytes / 4 / sizeof(GLint), i); break;
default:
UNIMPLEMENTED(); // FIXME
UNREACHABLE();
......@@ -878,6 +1093,16 @@ Uniform *Program::createUniform(const D3DXCONSTANT_DESC &constantDescription, st
default: UNREACHABLE();
}
break;
case D3DXPT_INT:
switch (constantDescription.Columns)
{
case 1: return new Uniform(GL_INT, name, 1 * sizeof(GLint) * constantDescription.Elements);
case 2: return new Uniform(GL_INT_VEC2, name, 2 * sizeof(GLint) * constantDescription.Elements);
case 3: return new Uniform(GL_INT_VEC3, name, 3 * sizeof(GLint) * constantDescription.Elements);
case 4: return new Uniform(GL_INT_VEC4, name, 4 * sizeof(GLint) * constantDescription.Elements);
default: UNREACHABLE();
}
break;
case D3DXPT_FLOAT:
switch (constantDescription.Columns)
{
......@@ -1289,6 +1514,96 @@ bool Program::applyUniform1iv(GLint location, GLsizei count, const GLint *v)
return true;
}
bool Program::applyUniform2iv(GLint location, GLsizei count, const GLint *v)
{
D3DXVECTOR4 *vector = new D3DXVECTOR4[count];
for (int i = 0; i < count; i++)
{
vector[i] = D3DXVECTOR4((float)v[0], (float)v[1], 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::applyUniform3iv(GLint location, GLsizei count, const GLint *v)
{
D3DXVECTOR4 *vector = new D3DXVECTOR4[count];
for (int i = 0; i < count; i++)
{
vector[i] = D3DXVECTOR4((float)v[0], (float)v[1], (float)v[2], 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::applyUniform4iv(GLint location, GLsizei count, const GLint *v)
{
D3DXVECTOR4 *vector = new D3DXVECTOR4[count];
for (int i = 0; i < count; i++)
{
vector[i] = D3DXVECTOR4((float)v[0], (float)v[1], (float)v[2], (float)v[3]);
v += 4;
}
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;
}
void Program::appendToInfoLog(const char *info)
{
if (!info)
......
......@@ -65,6 +65,9 @@ class Program
bool setUniformMatrix3fv(GLint location, GLsizei count, const GLfloat *value);
bool setUniformMatrix4fv(GLint location, GLsizei count, const GLfloat *value);
bool setUniform1iv(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 setUniform4iv(GLint location, GLsizei count, const GLint *v);
void applyUniforms();
......@@ -118,6 +121,9 @@ class Program
bool applyUniformMatrix3fv(GLint location, GLsizei count, const GLfloat *value);
bool applyUniformMatrix4fv(GLint location, GLsizei count, const GLfloat *value);
bool applyUniform1iv(GLint location, GLsizei count, const GLint *v);
bool applyUniform2iv(GLint location, GLsizei count, const GLint *v);
bool applyUniform3iv(GLint location, GLsizei count, const GLint *v);
bool applyUniform4iv(GLint location, GLsizei count, const GLint *v);
void appendToInfoLog(const char *info);
......
......@@ -3472,14 +3472,14 @@ void __stdcall glUniform1fv(GLint location, GLsizei count, const GLfloat* v)
try
{
if (location == -1)
if (count < 0)
{
return;
return error(GL_INVALID_VALUE);
}
if (count < 0)
if (location == -1)
{
return error(GL_INVALID_VALUE);
return;
}
gl::Context *context = gl::getContext();
......@@ -3521,6 +3521,11 @@ void __stdcall glUniform1iv(GLint location, GLsizei count, const GLint* v)
return error(GL_INVALID_VALUE);
}
if (location == -1)
{
return;
}
gl::Context *context = gl::getContext();
if (context)
......@@ -3557,15 +3562,15 @@ void __stdcall glUniform2fv(GLint location, GLsizei count, const GLfloat* v)
try
{
if (location == -1)
{
return;
}
if (count < 0)
{
return error(GL_INVALID_VALUE);
}
if (location == -1)
{
return;
}
gl::Context *context = gl::getContext();
......@@ -3608,7 +3613,27 @@ void __stdcall glUniform2iv(GLint location, GLsizei count, const GLint* v)
return error(GL_INVALID_VALUE);
}
UNIMPLEMENTED(); // FIXME
if (location == -1)
{
return;
}
gl::Context *context = gl::getContext();
if (context)
{
gl::Program *program = context->getCurrentProgram();
if (!program)
{
return error(GL_INVALID_OPERATION);
}
if (!program->setUniform2iv(location, count, v))
{
return error(GL_INVALID_OPERATION);
}
}
}
catch(std::bad_alloc&)
{
......@@ -3680,7 +3705,27 @@ void __stdcall glUniform3iv(GLint location, GLsizei count, const GLint* v)
return error(GL_INVALID_VALUE);
}
UNIMPLEMENTED(); // FIXME
if (location == -1)
{
return;
}
gl::Context *context = gl::getContext();
if (context)
{
gl::Program *program = context->getCurrentProgram();
if (!program)
{
return error(GL_INVALID_OPERATION);
}
if (!program->setUniform3iv(location, count, v))
{
return error(GL_INVALID_OPERATION);
}
}
}
catch(std::bad_alloc&)
{
......@@ -3752,7 +3797,27 @@ void __stdcall glUniform4iv(GLint location, GLsizei count, const GLint* v)
return error(GL_INVALID_VALUE);
}
UNIMPLEMENTED(); // FIXME
if (location == -1)
{
return;
}
gl::Context *context = gl::getContext();
if (context)
{
gl::Program *program = context->getCurrentProgram();
if (!program)
{
return error(GL_INVALID_OPERATION);
}
if (!program->setUniform4iv(location, count, v))
{
return error(GL_INVALID_OPERATION);
}
}
}
catch(std::bad_alloc&)
{
......
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