* The return value will encode two values, the uniform location and an
* offset (used for arrays, structs).
*/
-static GLint
-_mesa_get_uniform_location(GLcontext *ctx, GLuint program, const GLchar *name)
+GLint
+_mesa_get_uniform_location(GLcontext *ctx, struct gl_shader_program *shProg,
+ const GLchar *name)
{
GLint offset = 0, location = -1;
- struct gl_shader_program *shProg =
- _mesa_lookup_shader_program_err(ctx, program, "glGetUniformLocation");
-
- if (!shProg)
- return -1;
-
if (shProg->LinkStatus == GL_FALSE) {
_mesa_error(ctx, GL_INVALID_OPERATION, "glGetUniformfv(program)");
return -1;
/**
* Called via glUniform*() functions.
*/
-static void
-_mesa_uniform(GLcontext *ctx, GLint location, GLsizei count,
+void
+_mesa_uniform(GLcontext *ctx, struct gl_shader_program *shProg,
+ GLint location, GLsizei count,
const GLvoid *values, GLenum type)
{
- struct gl_shader_program *shProg = ctx->Shader.CurrentProgram;
struct gl_uniform *uniform;
GLint elems, offset;
* Called by glUniformMatrix*() functions.
* Note: cols=2, rows=4 ==> array[2] of vec4
*/
-static void
-_mesa_uniform_matrix(GLcontext *ctx, GLint cols, GLint rows,
+void
+_mesa_uniform_matrix(GLcontext *ctx, struct gl_shader_program *shProg,
+ GLint cols, GLint rows,
GLint location, GLsizei count,
GLboolean transpose, const GLfloat *values)
{
- struct gl_shader_program *shProg = ctx->Shader.CurrentProgram;
struct gl_uniform *uniform;
GLint offset;
_mesa_Uniform1fARB(GLint location, GLfloat v0)
{
GET_CURRENT_CONTEXT(ctx);
- _mesa_uniform(ctx, location, 1, &v0, GL_FLOAT);
+ _mesa_uniform(ctx, ctx->Shader.CurrentProgram, location, 1, &v0, GL_FLOAT);
}
void GLAPIENTRY
GLfloat v[2];
v[0] = v0;
v[1] = v1;
- _mesa_uniform(ctx, location, 1, v, GL_FLOAT_VEC2);
+ _mesa_uniform(ctx, ctx->Shader.CurrentProgram, location, 1, v, GL_FLOAT_VEC2);
}
void GLAPIENTRY
v[0] = v0;
v[1] = v1;
v[2] = v2;
- _mesa_uniform(ctx, location, 1, v, GL_FLOAT_VEC3);
+ _mesa_uniform(ctx, ctx->Shader.CurrentProgram, location, 1, v, GL_FLOAT_VEC3);
}
void GLAPIENTRY
v[1] = v1;
v[2] = v2;
v[3] = v3;
- _mesa_uniform(ctx, location, 1, v, GL_FLOAT_VEC4);
+ _mesa_uniform(ctx, ctx->Shader.CurrentProgram, location, 1, v, GL_FLOAT_VEC4);
}
void GLAPIENTRY
_mesa_Uniform1iARB(GLint location, GLint v0)
{
GET_CURRENT_CONTEXT(ctx);
- _mesa_uniform(ctx, location, 1, &v0, GL_INT);
+ _mesa_uniform(ctx, ctx->Shader.CurrentProgram, location, 1, &v0, GL_INT);
}
void GLAPIENTRY
GLint v[2];
v[0] = v0;
v[1] = v1;
- _mesa_uniform(ctx, location, 1, v, GL_INT_VEC2);
+ _mesa_uniform(ctx, ctx->Shader.CurrentProgram, location, 1, v, GL_INT_VEC2);
}
void GLAPIENTRY
v[0] = v0;
v[1] = v1;
v[2] = v2;
- _mesa_uniform(ctx, location, 1, v, GL_INT_VEC3);
+ _mesa_uniform(ctx, ctx->Shader.CurrentProgram, location, 1, v, GL_INT_VEC3);
}
void GLAPIENTRY
v[1] = v1;
v[2] = v2;
v[3] = v3;
- _mesa_uniform(ctx, location, 1, v, GL_INT_VEC4);
+ _mesa_uniform(ctx, ctx->Shader.CurrentProgram, location, 1, v, GL_INT_VEC4);
}
void GLAPIENTRY
_mesa_Uniform1fvARB(GLint location, GLsizei count, const GLfloat * value)
{
GET_CURRENT_CONTEXT(ctx);
- _mesa_uniform(ctx, location, count, value, GL_FLOAT);
+ _mesa_uniform(ctx, ctx->Shader.CurrentProgram, location, count, value, GL_FLOAT);
}
void GLAPIENTRY
_mesa_Uniform2fvARB(GLint location, GLsizei count, const GLfloat * value)
{
GET_CURRENT_CONTEXT(ctx);
- _mesa_uniform(ctx, location, count, value, GL_FLOAT_VEC2);
+ _mesa_uniform(ctx, ctx->Shader.CurrentProgram, location, count, value, GL_FLOAT_VEC2);
}
void GLAPIENTRY
_mesa_Uniform3fvARB(GLint location, GLsizei count, const GLfloat * value)
{
GET_CURRENT_CONTEXT(ctx);
- _mesa_uniform(ctx, location, count, value, GL_FLOAT_VEC3);
+ _mesa_uniform(ctx, ctx->Shader.CurrentProgram, location, count, value, GL_FLOAT_VEC3);
}
void GLAPIENTRY
_mesa_Uniform4fvARB(GLint location, GLsizei count, const GLfloat * value)
{
GET_CURRENT_CONTEXT(ctx);
- _mesa_uniform(ctx, location, count, value, GL_FLOAT_VEC4);
+ _mesa_uniform(ctx, ctx->Shader.CurrentProgram, location, count, value, GL_FLOAT_VEC4);
}
void GLAPIENTRY
_mesa_Uniform1ivARB(GLint location, GLsizei count, const GLint * value)
{
GET_CURRENT_CONTEXT(ctx);
- _mesa_uniform(ctx, location, count, value, GL_INT);
+ _mesa_uniform(ctx, ctx->Shader.CurrentProgram, location, count, value, GL_INT);
}
void GLAPIENTRY
_mesa_Uniform2ivARB(GLint location, GLsizei count, const GLint * value)
{
GET_CURRENT_CONTEXT(ctx);
- _mesa_uniform(ctx, location, count, value, GL_INT_VEC2);
+ _mesa_uniform(ctx, ctx->Shader.CurrentProgram, location, count, value, GL_INT_VEC2);
}
void GLAPIENTRY
_mesa_Uniform3ivARB(GLint location, GLsizei count, const GLint * value)
{
GET_CURRENT_CONTEXT(ctx);
- _mesa_uniform(ctx, location, count, value, GL_INT_VEC3);
+ _mesa_uniform(ctx, ctx->Shader.CurrentProgram, location, count, value, GL_INT_VEC3);
}
void GLAPIENTRY
_mesa_Uniform4ivARB(GLint location, GLsizei count, const GLint * value)
{
GET_CURRENT_CONTEXT(ctx);
- _mesa_uniform(ctx, location, count, value, GL_INT_VEC4);
+ _mesa_uniform(ctx, ctx->Shader.CurrentProgram, location, count, value, GL_INT_VEC4);
}
_mesa_Uniform1ui(GLint location, GLuint v0)
{
GET_CURRENT_CONTEXT(ctx);
- _mesa_uniform(ctx, location, 1, &v0, GL_UNSIGNED_INT);
+ _mesa_uniform(ctx, ctx->Shader.CurrentProgram, location, 1, &v0, GL_UNSIGNED_INT);
}
void GLAPIENTRY
GLuint v[2];
v[0] = v0;
v[1] = v1;
- _mesa_uniform(ctx, location, 1, v, GL_UNSIGNED_INT_VEC2);
+ _mesa_uniform(ctx, ctx->Shader.CurrentProgram, location, 1, v, GL_UNSIGNED_INT_VEC2);
}
void GLAPIENTRY
v[0] = v0;
v[1] = v1;
v[2] = v2;
- _mesa_uniform(ctx, location, 1, v, GL_UNSIGNED_INT_VEC3);
+ _mesa_uniform(ctx, ctx->Shader.CurrentProgram, location, 1, v, GL_UNSIGNED_INT_VEC3);
}
void GLAPIENTRY
v[1] = v1;
v[2] = v2;
v[3] = v3;
- _mesa_uniform(ctx, location, 1, v, GL_UNSIGNED_INT_VEC4);
+ _mesa_uniform(ctx, ctx->Shader.CurrentProgram, location, 1, v, GL_UNSIGNED_INT_VEC4);
}
void GLAPIENTRY
_mesa_Uniform1uiv(GLint location, GLsizei count, const GLuint *value)
{
GET_CURRENT_CONTEXT(ctx);
- _mesa_uniform(ctx, location, count, value, GL_UNSIGNED_INT);
+ _mesa_uniform(ctx, ctx->Shader.CurrentProgram, location, count, value, GL_UNSIGNED_INT);
}
void GLAPIENTRY
_mesa_Uniform2uiv(GLint location, GLsizei count, const GLuint *value)
{
GET_CURRENT_CONTEXT(ctx);
- _mesa_uniform(ctx, location, count, value, GL_UNSIGNED_INT_VEC2);
+ _mesa_uniform(ctx, ctx->Shader.CurrentProgram, location, count, value, GL_UNSIGNED_INT_VEC2);
}
void GLAPIENTRY
_mesa_Uniform3uiv(GLint location, GLsizei count, const GLuint *value)
{
GET_CURRENT_CONTEXT(ctx);
- _mesa_uniform(ctx, location, count, value, GL_UNSIGNED_INT_VEC3);
+ _mesa_uniform(ctx, ctx->Shader.CurrentProgram, location, count, value, GL_UNSIGNED_INT_VEC3);
}
void GLAPIENTRY
_mesa_Uniform4uiv(GLint location, GLsizei count, const GLuint *value)
{
GET_CURRENT_CONTEXT(ctx);
- _mesa_uniform(ctx, location, count, value, GL_UNSIGNED_INT_VEC4);
+ _mesa_uniform(ctx, ctx->Shader.CurrentProgram, location, count, value, GL_UNSIGNED_INT_VEC4);
}
const GLfloat * value)
{
GET_CURRENT_CONTEXT(ctx);
- _mesa_uniform_matrix(ctx, 2, 2, location, count, transpose, value);
+ _mesa_uniform_matrix(ctx, ctx->Shader.CurrentProgram,
+ 2, 2, location, count, transpose, value);
}
void GLAPIENTRY
const GLfloat * value)
{
GET_CURRENT_CONTEXT(ctx);
- _mesa_uniform_matrix(ctx, 3, 3, location, count, transpose, value);
+ _mesa_uniform_matrix(ctx, ctx->Shader.CurrentProgram,
+ 3, 3, location, count, transpose, value);
}
void GLAPIENTRY
const GLfloat * value)
{
GET_CURRENT_CONTEXT(ctx);
- _mesa_uniform_matrix(ctx, 4, 4, location, count, transpose, value);
+ _mesa_uniform_matrix(ctx, ctx->Shader.CurrentProgram,
+ 4, 4, location, count, transpose, value);
}
const GLfloat *value)
{
GET_CURRENT_CONTEXT(ctx);
- _mesa_uniform_matrix(ctx, 2, 3, location, count, transpose, value);
+ _mesa_uniform_matrix(ctx, ctx->Shader.CurrentProgram,
+ 2, 3, location, count, transpose, value);
}
void GLAPIENTRY
const GLfloat *value)
{
GET_CURRENT_CONTEXT(ctx);
- _mesa_uniform_matrix(ctx, 3, 2, location, count, transpose, value);
+ _mesa_uniform_matrix(ctx, ctx->Shader.CurrentProgram,
+ 3, 2, location, count, transpose, value);
}
void GLAPIENTRY
const GLfloat *value)
{
GET_CURRENT_CONTEXT(ctx);
- _mesa_uniform_matrix(ctx, 2, 4, location, count, transpose, value);
+ _mesa_uniform_matrix(ctx, ctx->Shader.CurrentProgram,
+ 2, 4, location, count, transpose, value);
}
void GLAPIENTRY
const GLfloat *value)
{
GET_CURRENT_CONTEXT(ctx);
- _mesa_uniform_matrix(ctx, 4, 2, location, count, transpose, value);
+ _mesa_uniform_matrix(ctx, ctx->Shader.CurrentProgram,
+ 4, 2, location, count, transpose, value);
}
void GLAPIENTRY
const GLfloat *value)
{
GET_CURRENT_CONTEXT(ctx);
- _mesa_uniform_matrix(ctx, 3, 4, location, count, transpose, value);
+ _mesa_uniform_matrix(ctx, ctx->Shader.CurrentProgram,
+ 3, 4, location, count, transpose, value);
}
void GLAPIENTRY
const GLfloat *value)
{
GET_CURRENT_CONTEXT(ctx);
- _mesa_uniform_matrix(ctx, 4, 3, location, count, transpose, value);
+ _mesa_uniform_matrix(ctx, ctx->Shader.CurrentProgram,
+ 4, 3, location, count, transpose, value);
}
GLint GLAPIENTRY
_mesa_GetUniformLocationARB(GLhandleARB programObj, const GLcharARB *name)
{
+ struct gl_shader_program *shProg;
+
GET_CURRENT_CONTEXT(ctx);
- return _mesa_get_uniform_location(ctx, programObj, name);
+
+ shProg = _mesa_lookup_shader_program_err(ctx, programObj,
+ "glGetUniformLocation");
+ if (!shProg)
+ return -1;
+
+ return _mesa_get_uniform_location(ctx, shProg, name);
}
int mul_operand);
int add_uniform(const char *name,
- const glsl_type *type,
- ir_constant *constant);
+ const glsl_type *type);
void add_aggregate_uniform(ir_instruction *ir,
const char *name,
const struct glsl_type *type,
- ir_constant *constant,
struct ir_to_mesa_dst_reg temp);
struct hash_table *sampler_map;
int
ir_to_mesa_visitor::add_uniform(const char *name,
- const glsl_type *type,
- ir_constant *constant)
+ const glsl_type *type)
{
int len;
len = type_size(type) * 4;
}
- float *values = NULL;
- if (constant && type->is_array()) {
- values = (float *)malloc(type->length * 4 * sizeof(float));
-
- assert(type->fields.array->is_scalar() ||
- type->fields.array->is_vector() ||
- !"FINISHME: uniform array initializers for non-vector");
-
- for (unsigned int i = 0; i < type->length; i++) {
- ir_constant *element = constant->array_elements[i];
- unsigned int c;
-
- for (c = 0; c < type->fields.array->vector_elements; c++) {
- switch (type->fields.array->base_type) {
- case GLSL_TYPE_FLOAT:
- values[4 * i + c] = element->value.f[c];
- break;
- case GLSL_TYPE_INT:
- values[4 * i + c] = element->value.i[c];
- break;
- case GLSL_TYPE_UINT:
- values[4 * i + c] = element->value.u[c];
- break;
- case GLSL_TYPE_BOOL:
- values[4 * i + c] = element->value.b[c];
- break;
- default:
- assert(!"not reached");
- }
- }
- }
- } else if (constant) {
- values = (float *)malloc(16 * sizeof(float));
- for (unsigned int i = 0; i < type->components(); i++) {
- switch (type->base_type) {
- case GLSL_TYPE_FLOAT:
- values[i] = constant->value.f[i];
- break;
- case GLSL_TYPE_INT:
- values[i] = constant->value.i[i];
- break;
- case GLSL_TYPE_UINT:
- values[i] = constant->value.u[i];
- break;
- case GLSL_TYPE_BOOL:
- values[i] = constant->value.b[i];
- break;
- default:
- assert(!"not reached");
- }
- }
- }
-
int loc = _mesa_add_uniform(this->prog->Parameters,
name,
len,
type->gl_type,
- values);
- free(values);
+ NULL);
return loc;
}
ir_to_mesa_visitor::add_aggregate_uniform(ir_instruction *ir,
const char *name,
const struct glsl_type *type,
- ir_constant *constant,
struct ir_to_mesa_dst_reg temp)
{
int loc;
if (type->is_record()) {
void *mem_ctx = talloc_new(NULL);
- ir_constant *field_constant = NULL;
-
- if (constant)
- field_constant = (ir_constant *)constant->components.get_head();
for (unsigned int i = 0; i < type->length; i++) {
const glsl_type *field_type = type->fields.structure[i].type;
add_aggregate_uniform(ir,
talloc_asprintf(mem_ctx, "%s.%s", name,
type->fields.structure[i].name),
- field_type, field_constant, temp);
+ field_type, temp);
temp.index += type_size(field_type);
-
- if (constant)
- field_constant = (ir_constant *)field_constant->next;
}
talloc_free(mem_ctx);
assert(type->is_vector() || type->is_scalar() || !"FINISHME: other types");
- loc = add_uniform(name, type, constant);
+ loc = add_uniform(name, type);
ir_to_mesa_src_reg uniform(PROGRAM_UNIFORM, loc, type);
this->variables.push_tail(entry);
add_aggregate_uniform(ir->var, ir->var->name, ir->var->type,
- ir->var->constant_value,
ir_to_mesa_dst_reg_from_src(temp));
break;
}
loc = add_uniform(ir->var->name,
- ir->var->type,
- ir->var->constant_value);
+ ir->var->type);
/* Always mark the uniform used at this point. If it isn't
* used, dead code elimination should have nuked the decl already.
}
}
+static void
+set_uniform_initializer(GLcontext *ctx, void *mem_ctx,
+ struct gl_shader_program *shader_program,
+ const char *name, const glsl_type *type,
+ ir_constant *val)
+{
+ if (type->is_record()) {
+ ir_constant *field_constant;
+
+ field_constant = (ir_constant *)val->components.get_head();
+
+ for (unsigned int i = 0; i < type->length; i++) {
+ const glsl_type *field_type = type->fields.structure[i].type;
+ const char *field_name = talloc_asprintf(mem_ctx, "%s.%s", name,
+ type->fields.structure[i].name);
+ set_uniform_initializer(ctx, mem_ctx, shader_program, field_name,
+ field_type, field_constant);
+ field_constant = (ir_constant *)field_constant->next;
+ }
+ return;
+ }
+
+ int loc = _mesa_get_uniform_location(ctx, shader_program, name);
+
+ if (loc == -1) {
+ shader_program->InfoLog =
+ talloc_asprintf_append(shader_program->InfoLog,
+ "Couldn't find uniform for "
+ "initializer %s\n", name);
+ shader_program->LinkStatus = false;
+ abort();
+ }
+
+ for (unsigned int i = 0; i < (type->is_array() ? type->length : 1); i++) {
+ ir_constant *element;
+ const glsl_type *element_type;
+ if (type->is_array()) {
+ element = val->array_elements[i];
+ element_type = type->fields.array;
+ } else {
+ element = val;
+ element_type = type;
+ }
+
+ void *values;
+
+ if (element_type->base_type == GLSL_TYPE_BOOL) {
+ int *conv = talloc_array(mem_ctx, int, element_type->components());
+ for (unsigned int j = 0; j < element_type->components(); j++) {
+ conv[j] = element->value.b[j];
+ }
+ values = (void *)conv;
+ element_type = glsl_type::get_instance(GLSL_TYPE_INT,
+ element_type->vector_elements,
+ 1);
+ } else {
+ values = &element->value;
+ }
+
+ if (element_type->is_matrix()) {
+ _mesa_uniform_matrix(ctx, shader_program,
+ element_type->matrix_columns,
+ element_type->vector_elements,
+ loc, 1, GL_FALSE, (GLfloat *)values);
+ loc += element_type->matrix_columns;
+ } else {
+ _mesa_uniform(ctx, shader_program, loc, element_type->matrix_columns,
+ values, element_type->gl_type);
+ loc += type_size(element_type);
+ }
+ }
+}
+
+static void
+set_uniform_initializers(GLcontext *ctx,
+ struct gl_shader_program *shader_program)
+{
+ void *mem_ctx = NULL;
+
+ for (unsigned int i = 0; i < shader_program->_NumLinkedShaders; i++) {
+ struct gl_shader *shader = shader_program->_LinkedShaders[i];
+ foreach_iter(exec_list_iterator, iter, *shader->ir) {
+ ir_instruction *ir = (ir_instruction *)iter.get();
+ ir_variable *var = ir->as_variable();
+
+ if (!var || var->mode != ir_var_uniform || !var->constant_value)
+ continue;
+
+ if (!mem_ctx)
+ mem_ctx = talloc_new(NULL);
+
+ set_uniform_initializer(ctx, mem_ctx, shader_program, var->name,
+ var->type, var->constant_value);
+ }
+ }
+
+ talloc_free(mem_ctx);
+}
+
struct gl_program *
get_mesa_program(GLcontext *ctx, struct gl_shader_program *shader_program,
struct gl_shader *shader)
}
}
+ set_uniform_initializers(ctx, prog);
+
if (ctx->Shader.Flags & GLSL_DUMP) {
if (!prog->LinkStatus) {
printf("GLSL shader program %d failed to link\n", prog->Name);