}
}
-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_Uniform2fARB(GLint location, GLfloat v0, GLfloat v1)
+_mesa_Uniform1fARB(GLint location, GLfloat v0)
{
- 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;
+ uniform(location, 1, &v0, GL_FLOAT, "glUniform1fARB");
+}
- if (!(**pro).WriteUniform(pro, location, 1, v, GL_FLOAT_VEC2))
- _mesa_error(ctx, GL_INVALID_OPERATION, "glUniform2fARB");
- }
+GLvoid GLAPIENTRY
+_mesa_Uniform2fARB(GLint location, GLfloat v0, GLfloat v1)
+{
+ 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");
}
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);
}
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);
}
}
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)
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];
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;
}