Use inlined uniform() helper function in all the glUniform*() function to

reduce duplicated code.
Finish up _program_ReadUniform() for non-float types.
Implement _mesa_GetUniformivARB().
Simplify the _program_WriteUniform() function a bit.
This commit is contained in:
Brian Paul 2006-11-03 21:30:16 +00:00
parent c64a062918
commit 2659ee9dfb
3 changed files with 193 additions and 270 deletions

View file

@ -349,299 +349,146 @@ _mesa_ValidateProgramARB(GLhandleARB programObj)
}
}
GLvoid GLAPIENTRY
_mesa_Uniform1fARB(GLint location, GLfloat v0)
/**
* Helper function for all the _mesa_Uniform*() functions below.
*/
static INLINE void
uniform(GLint location, GLsizei count, const GLvoid *values, GLenum type,
const char *caller)
{
GET_CURRENT_CONTEXT(ctx);
GET_CURRENT_LINKED_PROGRAM(pro, "glUniform1fARB");
GET_CURRENT_LINKED_PROGRAM(pro, caller);
FLUSH_VERTICES(ctx, _NEW_PROGRAM);
if (pro != NULL) {
if (!(**pro).WriteUniform(pro, location, 1, &v0, GL_FLOAT))
_mesa_error(ctx, GL_INVALID_OPERATION, "glUniform1fARB");
}
if (!pro)
return;
if (!(**pro).WriteUniform(pro, location, count, values, type))
_mesa_error(ctx, GL_INVALID_OPERATION, caller);
}
GLvoid GLAPIENTRY
_mesa_Uniform1fARB(GLint location, GLfloat v0)
{
uniform(location, 1, &v0, GL_FLOAT, "glUniform1fARB");
}
GLvoid GLAPIENTRY
_mesa_Uniform2fARB(GLint location, GLfloat v0, GLfloat v1)
{
GET_CURRENT_CONTEXT(ctx);
GET_CURRENT_LINKED_PROGRAM(pro, "glUniform2fARB");
FLUSH_VERTICES(ctx, _NEW_PROGRAM);
if (pro != NULL) {
GLfloat v[2];
v[0] = v0;
v[1] = v1;
if (!(**pro).WriteUniform(pro, location, 1, v, GL_FLOAT_VEC2))
_mesa_error(ctx, GL_INVALID_OPERATION, "glUniform2fARB");
}
GLfloat v[2];
v[0] = v0;
v[1] = v1;
uniform(location, 1, v, GL_FLOAT_VEC2, "glUniform2fARB");
}
GLvoid GLAPIENTRY
_mesa_Uniform3fARB(GLint location, GLfloat v0, GLfloat v1, GLfloat v2)
{
GET_CURRENT_CONTEXT(ctx);
GET_CURRENT_LINKED_PROGRAM(pro, "glUniform3fARB");
FLUSH_VERTICES(ctx, _NEW_PROGRAM);
if (pro != NULL) {
GLfloat v[3];
v[0] = v0;
v[1] = v1;
v[2] = v2;
if (!(**pro).WriteUniform(pro, location, 1, v, GL_FLOAT_VEC3))
_mesa_error(ctx, GL_INVALID_OPERATION, "glUniform3fARB");
}
GLfloat v[3];
v[0] = v0;
v[1] = v1;
v[2] = v2;
uniform(location, 1, v, GL_FLOAT_VEC3, "glUniform3fARB");
}
GLvoid GLAPIENTRY
_mesa_Uniform4fARB(GLint location, GLfloat v0, GLfloat v1, GLfloat v2,
GLfloat v3)
{
GET_CURRENT_CONTEXT(ctx);
GET_CURRENT_LINKED_PROGRAM(pro, "glUniform4fARB");
FLUSH_VERTICES(ctx, _NEW_PROGRAM);
if (pro != NULL) {
GLfloat v[4];
v[0] = v0;
v[1] = v1;
v[2] = v2;
v[3] = v3;
if (!(**pro).WriteUniform(pro, location, 1, v, GL_FLOAT_VEC4))
_mesa_error(ctx, GL_INVALID_OPERATION, "glUniform4fARB");
}
GLfloat v[4];
v[0] = v0;
v[1] = v1;
v[2] = v2;
v[3] = v3;
uniform(location, 1, v, GL_FLOAT_VEC4, "glUniform4fARB");
}
GLvoid GLAPIENTRY
_mesa_Uniform1iARB(GLint location, GLint v0)
{
GET_CURRENT_CONTEXT(ctx);
GET_CURRENT_LINKED_PROGRAM(pro, "glUniform1iARB");
FLUSH_VERTICES(ctx, _NEW_PROGRAM);
if (pro != NULL) {
if (!(**pro).WriteUniform(pro, location, 1, &v0, GL_INT))
_mesa_error(ctx, GL_INVALID_OPERATION, "glUniform1iARB");
}
uniform(location, 1, &v0, GL_INT, "glUniform1iARB");
}
GLvoid GLAPIENTRY
_mesa_Uniform2iARB(GLint location, GLint v0, GLint v1)
{
GET_CURRENT_CONTEXT(ctx);
GET_CURRENT_LINKED_PROGRAM(pro, "glUniform2iARB");
FLUSH_VERTICES(ctx, _NEW_PROGRAM);
if (pro != NULL) {
GLint v[2];
v[0] = v0;
v[1] = v1;
if (!(**pro).WriteUniform(pro, location, 1, v, GL_INT_VEC2))
_mesa_error(ctx, GL_INVALID_OPERATION, "glUniform2iARB");
}
GLint v[2];
v[0] = v0;
v[1] = v1;
uniform(location, 1, v, GL_INT_VEC2, "glUniform2iARB");
}
GLvoid GLAPIENTRY
_mesa_Uniform3iARB(GLint location, GLint v0, GLint v1, GLint v2)
{
GET_CURRENT_CONTEXT(ctx);
GET_CURRENT_LINKED_PROGRAM(pro, "glUniform3iARB");
FLUSH_VERTICES(ctx, _NEW_PROGRAM);
if (pro != NULL) {
GLint v[3];
v[0] = v0;
v[1] = v1;
v[2] = v2;
if (!(**pro).WriteUniform(pro, location, 1, v, GL_INT_VEC3))
_mesa_error(ctx, GL_INVALID_OPERATION, "glUniform3iARB");
}
GLint v[3];
v[0] = v0;
v[1] = v1;
v[2] = v2;
uniform(location, 1, v, GL_INT_VEC3, "glUniform3iARB");
}
GLvoid GLAPIENTRY
_mesa_Uniform4iARB(GLint location, GLint v0, GLint v1, GLint v2, GLint v3)
{
GET_CURRENT_CONTEXT(ctx);
GET_CURRENT_LINKED_PROGRAM(pro, "glUniform4iARB");
FLUSH_VERTICES(ctx, _NEW_PROGRAM);
if (pro != NULL) {
GLint v[4];
v[0] = v0;
v[1] = v1;
v[2] = v2;
v[3] = v3;
if (!(**pro).WriteUniform(pro, location, 1, v, GL_INT_VEC4))
_mesa_error(ctx, GL_INVALID_OPERATION, "glUniform4iARB");
}
GLint v[4];
v[0] = v0;
v[1] = v1;
v[2] = v2;
v[3] = v3;
uniform(location, 1, v, GL_INT_VEC4, "glUniform4iARB");
}
GLvoid GLAPIENTRY
_mesa_Uniform1fvARB(GLint location, GLsizei count, const GLfloat * value)
{
GET_CURRENT_CONTEXT(ctx);
GET_CURRENT_LINKED_PROGRAM(pro, "glUniform1fvARB");
if (value == NULL) {
_mesa_error(ctx, GL_INVALID_VALUE, "glUniform1fvARB");
return;
}
FLUSH_VERTICES(ctx, _NEW_PROGRAM);
if (pro != NULL) {
if (!(**pro).WriteUniform(pro, location, count, value, GL_FLOAT))
_mesa_error(ctx, GL_INVALID_OPERATION, "glUniform1fvARB");
}
uniform(location, count, value, GL_FLOAT, "glUniform1fvARB");
}
GLvoid GLAPIENTRY
_mesa_Uniform2fvARB(GLint location, GLsizei count, const GLfloat * value)
{
GET_CURRENT_CONTEXT(ctx);
GET_CURRENT_LINKED_PROGRAM(pro, "glUniform2fvARB");
if (value == NULL) {
_mesa_error(ctx, GL_INVALID_VALUE, "glUniform2fvARB");
return;
}
FLUSH_VERTICES(ctx, _NEW_PROGRAM);
if (pro != NULL) {
if (!(**pro).WriteUniform(pro, location, count, value, GL_FLOAT_VEC2))
_mesa_error(ctx, GL_INVALID_OPERATION, "glUniform2fvARB");
}
uniform(location, count, value, GL_FLOAT_VEC2, "glUniform2fvARB");
}
GLvoid GLAPIENTRY
_mesa_Uniform3fvARB(GLint location, GLsizei count, const GLfloat * value)
{
GET_CURRENT_CONTEXT(ctx);
GET_CURRENT_LINKED_PROGRAM(pro, "glUniform3fvARB");
if (value == NULL) {
_mesa_error(ctx, GL_INVALID_VALUE, "glUniform3fvARB");
return;
}
FLUSH_VERTICES(ctx, _NEW_PROGRAM);
if (pro != NULL) {
if (!(**pro).WriteUniform(pro, location, count, value, GL_FLOAT_VEC3))
_mesa_error(ctx, GL_INVALID_OPERATION, "glUniform3fvARB");
}
uniform(location, count, value, GL_FLOAT_VEC3, "glUniform3fvARB");
}
GLvoid GLAPIENTRY
_mesa_Uniform4fvARB(GLint location, GLsizei count, const GLfloat * value)
{
GET_CURRENT_CONTEXT(ctx);
GET_CURRENT_LINKED_PROGRAM(pro, "glUniform4fvARB");
if (value == NULL) {
_mesa_error(ctx, GL_INVALID_VALUE, "glUniform4fvARB");
return;
}
FLUSH_VERTICES(ctx, _NEW_PROGRAM);
if (pro != NULL) {
if (!(**pro).WriteUniform(pro, location, count, value, GL_FLOAT_VEC4))
_mesa_error(ctx, GL_INVALID_OPERATION, "glUniform4fvARB");
}
uniform(location, count, value, GL_FLOAT_VEC4, "glUniform4fvARB");
}
GLvoid GLAPIENTRY
_mesa_Uniform1ivARB(GLint location, GLsizei count, const GLint * value)
{
GET_CURRENT_CONTEXT(ctx);
GET_CURRENT_LINKED_PROGRAM(pro, "glUniform1ivARB");
if (value == NULL) {
_mesa_error(ctx, GL_INVALID_VALUE, "glUniform1ivARB");
return;
}
FLUSH_VERTICES(ctx, _NEW_PROGRAM);
if (pro != NULL) {
if (!(**pro).WriteUniform(pro, location, count, value, GL_INT))
_mesa_error(ctx, GL_INVALID_OPERATION, "glUniform1ivARB");
}
uniform(location, count, value, GL_INT, "glUniform1ivARB");
}
GLvoid GLAPIENTRY
_mesa_Uniform2ivARB(GLint location, GLsizei count, const GLint * value)
{
GET_CURRENT_CONTEXT(ctx);
GET_CURRENT_LINKED_PROGRAM(pro, "glUniform2ivARB");
if (value == NULL) {
_mesa_error(ctx, GL_INVALID_VALUE, "glUniform2ivARB");
return;
}
FLUSH_VERTICES(ctx, _NEW_PROGRAM);
if (pro != NULL) {
if (!(**pro).WriteUniform(pro, location, count, value, GL_INT_VEC2))
_mesa_error(ctx, GL_INVALID_OPERATION, "glUniform2ivARB");
}
uniform(location, count, value, GL_INT_VEC2, "glUniform2ivARB");
}
GLvoid GLAPIENTRY
_mesa_Uniform3ivARB(GLint location, GLsizei count, const GLint * value)
{
GET_CURRENT_CONTEXT(ctx);
GET_CURRENT_LINKED_PROGRAM(pro, "glUniform3ivARB");
if (value == NULL) {
_mesa_error(ctx, GL_INVALID_VALUE, "glUniform3ivARB");
return;
}
FLUSH_VERTICES(ctx, _NEW_PROGRAM);
if (pro != NULL) {
if (!(**pro).WriteUniform(pro, location, count, value, GL_INT_VEC3))
_mesa_error(ctx, GL_INVALID_OPERATION, "glUniform3ivARB");
}
uniform(location, count, value, GL_INT_VEC3, "glUniform3ivARB");
}
GLvoid GLAPIENTRY
_mesa_Uniform4ivARB(GLint location, GLsizei count, const GLint * value)
{
GET_CURRENT_CONTEXT(ctx);
GET_CURRENT_LINKED_PROGRAM(pro, "glUniform4ivARB");
if (value == NULL) {
_mesa_error(ctx, GL_INVALID_VALUE, "glUniform4ivARB");
return;
}
FLUSH_VERTICES(ctx, _NEW_PROGRAM);
if (pro != NULL) {
if (!(**pro).WriteUniform(pro, location, count, value, GL_INT_VEC4))
_mesa_error(ctx, GL_INVALID_OPERATION, "glUniform4ivARB");
}
uniform(location, count, value, GL_INT_VEC4, "glUniform4ivARB");
}
@ -1015,10 +862,8 @@ _mesa_GetUniformfvARB(GLhandleARB programObj, GLint location, GLfloat * params)
GET_CURRENT_CONTEXT(ctx);
GET_LINKED_PROGRAM(pro, programObj, "glGetUniformfvARB");
/* XXX error-check location here */
if (pro != NULL) {
if (!(**pro).ReadUniform(pro, location, 1, params))
if (!(**pro).ReadUniform(pro, location, 1, params, GL_FLOAT))
_mesa_error(ctx, GL_INVALID_OPERATION, "glGetUniformfvARB");
RELEASE_PROGRAM(pro);
}
@ -1031,7 +876,8 @@ _mesa_GetUniformivARB(GLhandleARB programObj, GLint location, GLint * params)
GET_LINKED_PROGRAM(pro, programObj, "glGetUniformivARB");
if (pro != NULL) {
/* TODO */
if (!(**pro).ReadUniform(pro, location, 1, params, GL_INT))
_mesa_error(ctx, GL_INVALID_OPERATION, "glGetUniformivARB");
RELEASE_PROGRAM(pro);
}
}

View file

@ -105,7 +105,7 @@ struct gl2_program_intf
GLboolean (* WriteUniform) (struct gl2_program_intf **, GLint loc, GLsizei count,
const GLvoid *data, GLenum type);
GLboolean (* ReadUniform) (struct gl2_program_intf **, GLint loc, GLsizei count,
GLfloat *data);
GLvoid *data, GLenum type);
GLvoid (* GetActiveAttrib) (struct gl2_program_intf **, GLuint index, GLsizei maxLength,
GLsizei *length, GLint *size, GLenum *type, GLchar *name);
GLuint (* GetActiveAttribMaxLength) (struct gl2_program_intf **);

View file

@ -1383,6 +1383,10 @@ _program_GetUniformLocation(struct gl2_program_intf **intf,
return -1;
}
/**
* Write a uniform variable into program's memory.
* \return GL_TRUE for success, GL_FALSE if error
*/
static GLboolean
_program_WriteUniform(struct gl2_program_intf **intf, GLint loc,
GLsizei count, const GLvoid * data, GLenum type)
@ -1396,9 +1400,7 @@ _program_WriteUniform(struct gl2_program_intf **intf, GLint loc,
GLboolean convert_int_to_float = GL_FALSE;
GLboolean types_match = GL_FALSE;
if (loc == -1)
return GL_TRUE;
if (loc >= uniforms->count)
if (loc < 0 || loc >= uniforms->count)
return GL_FALSE;
uniform = &uniforms->table[loc];
@ -1460,86 +1462,161 @@ _program_WriteUniform(struct gl2_program_intf **intf, GLint loc,
break;
}
if (convert_float_to_bool) {
for (i = 0; i < SLANG_SHADER_MAX; i++)
if (uniform->address[i] != ~0) {
for (i = 0; i < SLANG_SHADER_MAX; i++) {
if (uniform->address[i] != ~0) {
void *dest
= &impl->_obj.prog.machines[i]->mem[uniform->address[i] / 4];
/* total number of values to copy */
GLuint total
= count * slang_export_data_quant_components(uniform->quant);
GLuint j;
if (convert_float_to_bool) {
const GLfloat *src = (GLfloat *) (data);
GLfloat *dst = (GLfloat *)
(&impl->_obj.prog.machines[i]->mem[uniform->address[i] / 4]);
GLuint j;
GLuint total =
count * slang_export_data_quant_components(uniform->quant);
GLfloat *dst = (GLfloat *) dest;
for (j = 0; j < total; j++)
dst[j] = src[j] != 0.0f ? 1.0f : 0.0f;
break;
}
}
else if (convert_int_to_bool) {
for (i = 0; i < SLANG_SHADER_MAX; i++)
if (uniform->address[i] != ~0) {
const GLuint *src = (GLuint *) (data);
GLfloat *dst = (GLfloat *)
(&impl->_obj.prog.machines[i]->mem[uniform->address[i] / 4]);
GLuint j;
GLuint total =
count * slang_export_data_quant_components(uniform->quant);
else if (convert_int_to_bool) {
const GLint *src = (GLint *) (data);
GLfloat *dst = (GLfloat *) dest;
for (j = 0; j < total; j++)
dst[j] = src[j] ? 1.0f : 0.0f;
break;
}
}
else if (convert_int_to_float) {
for (i = 0; i < SLANG_SHADER_MAX; i++)
if (uniform->address[i] != ~0) {
const GLuint *src = (GLuint *) (data);
GLfloat *dst = (GLfloat *)
(&impl->_obj.prog.machines[i]->mem[uniform->address[i] / 4]);
GLuint j;
GLuint total =
count * slang_export_data_quant_components(uniform->quant);
else if (convert_int_to_float) {
const GLint *src = (GLint *) (data);
GLfloat *dst = (GLfloat *) dest;
for (j = 0; j < total; j++)
dst[j] = (GLfloat) src[j];
break;
}
}
else {
for (i = 0; i < SLANG_SHADER_MAX; i++)
if (uniform->address[i] != ~0) {
_mesa_memcpy(&impl->_obj.prog.machines[i]->
mem[uniform->address[i] / 4], data,
count *
slang_export_data_quant_size(uniform->quant));
else {
_mesa_memcpy(dest, data, total * sizeof(GLfloat));
break;
}
break;
}
}
return GL_TRUE;
}
/**
* Read a uniform variable from program's memory.
* \return GL_TRUE for success, GL_FALSE if error
*/
static GLboolean
_program_ReadUniform(struct gl2_program_intf **intf, GLint loc,
GLsizei count, GLfloat *data)
GLsizei count, GLvoid *data, GLenum type)
{
struct gl2_program_impl *impl = (struct gl2_program_impl *) (intf);
const slang_uniform_bindings *uniforms = &impl->_obj.prog.uniforms;
const slang_uniform_binding *uniform;
GLint i, j;
GLuint i;
GLboolean convert_bool_to_float = GL_FALSE;
GLboolean convert_bool_to_int = GL_FALSE;
GLboolean convert_float_to_int = GL_FALSE;
GLboolean types_match = GL_FALSE;
if (loc < 0 || loc >= uniforms->count)
return GL_FALSE;
uniform = &uniforms->table[loc];
/* loop over shader types (fragment, vertex) */
if (slang_export_data_quant_struct(uniform->quant))
return GL_FALSE;
switch (slang_export_data_quant_type(uniform->quant)) {
case GL_BOOL_ARB:
types_match = (type == GL_FLOAT) || (type == GL_INT);
if (type == GL_FLOAT)
convert_bool_to_float = GL_TRUE;
else
convert_bool_to_int = GL_TRUE;
break;
case GL_BOOL_VEC2_ARB:
types_match = (type == GL_FLOAT_VEC2_ARB) || (type == GL_INT_VEC2_ARB);
if (type == GL_FLOAT_VEC2_ARB)
convert_bool_to_float = GL_TRUE;
else
convert_bool_to_int = GL_TRUE;
break;
case GL_BOOL_VEC3_ARB:
types_match = (type == GL_FLOAT_VEC3_ARB) || (type == GL_INT_VEC3_ARB);
if (type == GL_FLOAT_VEC3_ARB)
convert_bool_to_float = GL_TRUE;
else
convert_bool_to_int = GL_TRUE;
break;
case GL_BOOL_VEC4_ARB:
types_match = (type == GL_FLOAT_VEC4_ARB) || (type == GL_INT_VEC4_ARB);
if (type == GL_FLOAT_VEC4_ARB)
convert_bool_to_float = GL_TRUE;
else
convert_bool_to_int = GL_TRUE;
break;
case GL_SAMPLER_1D_ARB:
case GL_SAMPLER_2D_ARB:
case GL_SAMPLER_3D_ARB:
case GL_SAMPLER_CUBE_ARB:
case GL_SAMPLER_1D_SHADOW_ARB:
case GL_SAMPLER_2D_SHADOW_ARB:
types_match = (type == GL_INT);
break;
default:
/* uniform is a float type */
types_match = (type == GL_FLOAT);
break;
}
if (!types_match)
return GL_FALSE;
switch (type) {
case GL_INT:
case GL_INT_VEC2_ARB:
case GL_INT_VEC3_ARB:
case GL_INT_VEC4_ARB:
convert_float_to_int = GL_TRUE;
break;
}
for (i = 0; i < SLANG_SHADER_MAX; i++) {
if (uniform->address[i] != ~0) {
GLfloat *src = (GLfloat *)
(&impl->_obj.prog.machines[i]->mem[uniform->address[i] / 4]);
GLuint total =
count * slang_export_data_quant_components(uniform->quant);
for (j = 0; j < total; j++)
data[j] = src[j];
/* XXX if bools are really implemented as floats, some of this
* could probably be culled out.
*/
const void *source
= &impl->_obj.prog.machines[i]->mem[uniform->address[i] / 4];
/* total number of values to copy */
const GLuint total
= count * slang_export_data_quant_components(uniform->quant);
GLuint j;
if (convert_bool_to_float) {
GLfloat *dst = (GLfloat *) (data);
const GLfloat *src = (GLfloat *) source;
for (j = 0; j < total; j++)
dst[j] = src[j] == 0.0 ? 0.0 : 1.0;
}
else if (convert_bool_to_int) {
GLint *dst = (GLint *) (data);
const GLfloat *src = (GLfloat *) source;
for (j = 0; j < total; j++)
dst[j] = src[j] == 0.0 ? 0 : 1;
}
else if (convert_float_to_int) {
GLint *dst = (GLint *) (data);
const GLfloat *src = (GLfloat *) source;
for (j = 0; j < total; j++)
dst[j] = (GLint) src[j];
}
else {
/* no type conversion needed */
_mesa_memcpy(data, source, total * sizeof(GLfloat));
}
break;
}
}
} /* if */
} /* for */
return GL_TRUE;
}