aboutsummaryrefslogtreecommitdiff
path: root/mesalib/src
diff options
context:
space:
mode:
Diffstat (limited to 'mesalib/src')
-rw-r--r--mesalib/src/SConscript2
-rw-r--r--mesalib/src/glsl/Makefile.sources1
-rw-r--r--mesalib/src/glsl/link_uniform_initializers.cpp181
-rw-r--r--mesalib/src/glsl/link_uniforms.cpp15
-rw-r--r--mesalib/src/glsl/linker.h3
-rw-r--r--mesalib/src/glsl/opt_constant_propagation.cpp21
-rw-r--r--mesalib/src/glu/sgi/libnurbs/internals/mapdesc.cc2
-rw-r--r--mesalib/src/glu/sgi/libnurbs/internals/nurbstess.cc2
-rw-r--r--mesalib/src/mesa/main/blend.c20
-rw-r--r--mesalib/src/mesa/main/context.c24
-rw-r--r--mesalib/src/mesa/main/extensions.c2
-rw-r--r--mesalib/src/mesa/main/ff_fragment_shader.cpp41
-rw-r--r--mesalib/src/mesa/main/mtypes.h5
-rw-r--r--mesalib/src/mesa/main/uniforms.c1
-rw-r--r--mesalib/src/mesa/program/ir_to_mesa.cpp111
-rw-r--r--mesalib/src/mesa/state_tracker/st_cb_texture.c2
16 files changed, 273 insertions, 160 deletions
diff --git a/mesalib/src/SConscript b/mesalib/src/SConscript
index 777ad23f2..3d0087887 100644
--- a/mesalib/src/SConscript
+++ b/mesalib/src/SConscript
@@ -22,7 +22,7 @@ SConscript('mesa/SConscript')
SConscript('mapi/vgapi/SConscript')
if not env['embedded']:
- if env['platform'] not in ['windows', 'darwin', 'haiku']:
+ if env['platform'] not in ('cygwin', 'darwin', 'freebsd', 'haiku', 'windows'):
SConscript('glx/SConscript')
if env['platform'] not in ['darwin', 'haiku', 'sunos']:
SConscript('egl/main/SConscript')
diff --git a/mesalib/src/glsl/Makefile.sources b/mesalib/src/glsl/Makefile.sources
index fba03604c..caa8ad590 100644
--- a/mesalib/src/glsl/Makefile.sources
+++ b/mesalib/src/glsl/Makefile.sources
@@ -46,6 +46,7 @@ LIBGLSL_CXX_FILES := \
linker.cpp \
link_functions.cpp \
link_uniforms.cpp \
+ link_uniform_initializers.cpp \
loop_analysis.cpp \
loop_controls.cpp \
loop_unroll.cpp \
diff --git a/mesalib/src/glsl/link_uniform_initializers.cpp b/mesalib/src/glsl/link_uniform_initializers.cpp
new file mode 100644
index 000000000..849e08097
--- /dev/null
+++ b/mesalib/src/glsl/link_uniform_initializers.cpp
@@ -0,0 +1,181 @@
+/*
+ * Copyright © 2012 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+
+#include "main/core.h"
+#include "ir.h"
+#include "linker.h"
+#include "ir_uniform.h"
+#include "glsl_symbol_table.h"
+#include "program/hash_table.h"
+
+/* These functions are put in a "private" namespace instead of being marked
+ * static so that the unit tests can access them. See
+ * http://code.google.com/p/googletest/wiki/AdvancedGuide#Testing_Private_Code
+ */
+namespace linker {
+
+gl_uniform_storage *
+get_storage(gl_uniform_storage *storage, unsigned num_storage,
+ const char *name)
+{
+ for (unsigned int i = 0; i < num_storage; i++) {
+ if (strcmp(name, storage[i].name) == 0)
+ return &storage[i];
+ }
+
+ return NULL;
+}
+
+void
+copy_constant_to_storage(union gl_constant_value *storage,
+ const ir_constant *val,
+ const enum glsl_base_type base_type,
+ const unsigned int elements)
+{
+ for (unsigned int i = 0; i < elements; i++) {
+ switch (base_type) {
+ case GLSL_TYPE_UINT:
+ storage[i].u = val->value.u[i];
+ break;
+ case GLSL_TYPE_INT:
+ case GLSL_TYPE_SAMPLER:
+ storage[i].i = val->value.i[i];
+ break;
+ case GLSL_TYPE_FLOAT:
+ storage[i].f = val->value.f[i];
+ break;
+ case GLSL_TYPE_BOOL:
+ storage[i].b = int(val->value.b[i]);
+ break;
+ default:
+ /* All other types should have already been filtered by other
+ * paths in the caller.
+ */
+ assert(!"Should not get here.");
+ break;
+ }
+ }
+}
+
+void
+set_uniform_initializer(void *mem_ctx, gl_shader_program *prog,
+ 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 = ralloc_asprintf(mem_ctx, "%s.%s", name,
+ type->fields.structure[i].name);
+ set_uniform_initializer(mem_ctx, prog, field_name,
+ field_type, field_constant);
+ field_constant = (ir_constant *)field_constant->next;
+ }
+ return;
+ } else if (type->is_array() && type->fields.array->is_record()) {
+ const glsl_type *const element_type = type->fields.array;
+
+ for (unsigned int i = 0; i < type->length; i++) {
+ const char *element_name = ralloc_asprintf(mem_ctx, "%s[%d]", name, i);
+
+ set_uniform_initializer(mem_ctx, prog, element_name,
+ element_type, val->array_elements[i]);
+ }
+ return;
+ }
+
+ struct gl_uniform_storage *const storage =
+ get_storage(prog->UniformStorage,
+ prog->NumUserUniformStorage,
+ name);
+ if (storage == NULL) {
+ assert(storage != NULL);
+ return;
+ }
+
+ if (val->type->is_array()) {
+ const enum glsl_base_type base_type =
+ val->array_elements[0]->type->base_type;
+ const unsigned int elements = val->array_elements[0]->type->components();
+ unsigned int idx = 0;
+
+ assert(val->type->length >= storage->array_elements);
+ for (unsigned int i = 0; i < storage->array_elements; i++) {
+ copy_constant_to_storage(& storage->storage[idx],
+ val->array_elements[i],
+ base_type,
+ elements);
+
+ idx += elements;
+ }
+
+ if (base_type == GLSL_TYPE_SAMPLER) {
+ for (unsigned int i = 0; i < storage->array_elements; i++) {
+ prog->SamplerUnits[storage->sampler + i] = storage->storage[i].i;
+ }
+ }
+ } else {
+ copy_constant_to_storage(storage->storage,
+ val,
+ val->type->base_type,
+ val->type->components());
+
+ if (storage->type->is_sampler())
+ prog->SamplerUnits[storage->sampler] = storage->storage[0].i;
+ }
+
+ storage->initialized = true;
+}
+}
+
+void
+link_set_uniform_initializers(struct gl_shader_program *prog)
+{
+ void *mem_ctx = NULL;
+
+ for (unsigned int i = 0; i < MESA_SHADER_TYPES; i++) {
+ struct gl_shader *shader = prog->_LinkedShaders[i];
+
+ if (shader == NULL)
+ continue;
+
+ foreach_list(node, shader->ir) {
+ ir_variable *const var = ((ir_instruction *) node)->as_variable();
+
+ if (!var || var->mode != ir_var_uniform || !var->constant_value)
+ continue;
+
+ if (!mem_ctx)
+ mem_ctx = ralloc_context(NULL);
+
+ linker::set_uniform_initializer(mem_ctx, prog, var->name,
+ var->type, var->constant_value);
+ }
+ }
+
+ ralloc_free(mem_ctx);
+}
diff --git a/mesalib/src/glsl/link_uniforms.cpp b/mesalib/src/glsl/link_uniforms.cpp
index 506b6fe1c..3cbc50510 100644
--- a/mesalib/src/glsl/link_uniforms.cpp
+++ b/mesalib/src/glsl/link_uniforms.cpp
@@ -329,9 +329,16 @@ link_assign_uniform_locations(struct gl_shader_program *prog)
prog->UniformHash = new string_to_uint_map;
}
- for (unsigned i = 0; i < Elements(prog->SamplerUnits); i++) {
- prog->SamplerUnits[i] = i;
- }
+ /* Uniforms that lack an initializer in the shader code have an initial
+ * value of zero. This includes sampler uniforms.
+ *
+ * Page 24 (page 30 of the PDF) of the GLSL 1.20 spec says:
+ *
+ * "The link time initial value is either the value of the variable's
+ * initializer, if present, or 0 if no initializer is present. Sampler
+ * types cannot have initializers."
+ */
+ memset(prog->SamplerUnits, 0, sizeof(prog->SamplerUnits));
/* First pass: Count the uniform resources used by the user-defined
* uniforms. While this happens, each active uniform will have an index
@@ -425,5 +432,7 @@ link_assign_uniform_locations(struct gl_shader_program *prog)
prog->NumUserUniformStorage = num_user_uniforms;
prog->UniformStorage = uniforms;
+ link_set_uniform_initializers(prog);
+
return;
}
diff --git a/mesalib/src/glsl/linker.h b/mesalib/src/glsl/linker.h
index 0b4c001f7..d0aaf3e1e 100644
--- a/mesalib/src/glsl/linker.h
+++ b/mesalib/src/glsl/linker.h
@@ -37,6 +37,9 @@ link_invalidate_variable_locations(gl_shader *sh, enum ir_variable_mode mode,
extern void
link_assign_uniform_locations(struct gl_shader_program *prog);
+extern void
+link_set_uniform_initializers(struct gl_shader_program *prog);
+
/**
* Class for processing all of the leaf fields of an uniform
*
diff --git a/mesalib/src/glsl/opt_constant_propagation.cpp b/mesalib/src/glsl/opt_constant_propagation.cpp
index d3812637d..2601b52f6 100644
--- a/mesalib/src/glsl/opt_constant_propagation.cpp
+++ b/mesalib/src/glsl/opt_constant_propagation.cpp
@@ -241,7 +241,26 @@ ir_constant_propagation_visitor::visit_leave(ir_assignment *ir)
if (this->in_assignee)
return visit_continue;
- kill(ir->lhs->variable_referenced(), ir->write_mask);
+ unsigned kill_mask = ir->write_mask;
+ if (ir->lhs->as_dereference_array()) {
+ /* The LHS of the assignment uses an array indexing operator (e.g. v[i]
+ * = ...;). Since we only try to constant propagate vectors and
+ * scalars, this means that either (a) array indexing is being used to
+ * select a vector component, or (b) the variable in question is neither
+ * a scalar or a vector, so we don't care about it. In the former case,
+ * we want to kill the whole vector, since in general we can't predict
+ * which vector component will be selected by array indexing. In the
+ * latter case, it doesn't matter what we do, so go ahead and kill the
+ * whole variable anyway.
+ *
+ * Note that if the array index is constant (e.g. v[2] = ...;), we could
+ * in principle be smarter, but we don't need to, because a future
+ * optimization pass will convert it to a simple assignment with the
+ * correct mask.
+ */
+ kill_mask = ~0;
+ }
+ kill(ir->lhs->variable_referenced(), kill_mask);
add_constant(ir);
diff --git a/mesalib/src/glu/sgi/libnurbs/internals/mapdesc.cc b/mesalib/src/glu/sgi/libnurbs/internals/mapdesc.cc
index d59f8fd39..0a96c5f45 100644
--- a/mesalib/src/glu/sgi/libnurbs/internals/mapdesc.cc
+++ b/mesalib/src/glu/sgi/libnurbs/internals/mapdesc.cc
@@ -90,7 +90,7 @@ Mapdesc::setBboxsize( INREAL *mat )
void
Mapdesc::identify( REAL dest[MAXCOORDS][MAXCOORDS] )
{
- memset( dest, 0, sizeof( dest ) );
+ memset( dest, 0, sizeof( REAL ) * MAXCOORDS * MAXCOORDS );
for( int i=0; i != hcoords; i++ )
dest[i][i] = 1.0;
}
diff --git a/mesalib/src/glu/sgi/libnurbs/internals/nurbstess.cc b/mesalib/src/glu/sgi/libnurbs/internals/nurbstess.cc
index 68dfd95f3..e477a8c83 100644
--- a/mesalib/src/glu/sgi/libnurbs/internals/nurbstess.cc
+++ b/mesalib/src/glu/sgi/libnurbs/internals/nurbstess.cc
@@ -505,7 +505,7 @@ NurbsTessellator::do_pwlcurve( O_pwlcurve *o_pwlcurve )
o_pwlcurve->owner = currentCurve;
}
- if( (inCurve == 2) )
+ if( inCurve == 2 )
endcurve();
}
diff --git a/mesalib/src/mesa/main/blend.c b/mesalib/src/mesa/main/blend.c
index bc446edca..5bc40a028 100644
--- a/mesalib/src/mesa/main/blend.c
+++ b/mesalib/src/mesa/main/blend.c
@@ -166,6 +166,24 @@ _mesa_BlendFunc( GLenum sfactor, GLenum dfactor )
_mesa_BlendFuncSeparateEXT(sfactor, dfactor, sfactor, dfactor);
}
+static GLboolean
+blend_factor_is_dual_src(GLenum factor)
+{
+ return (factor == GL_SRC1_COLOR ||
+ factor == GL_SRC1_ALPHA ||
+ factor == GL_ONE_MINUS_SRC1_COLOR ||
+ factor == GL_ONE_MINUS_SRC1_ALPHA);
+}
+
+static void
+update_uses_dual_src(struct gl_context *ctx, int buf)
+{
+ ctx->Color.Blend[buf]._UsesDualSrc =
+ (blend_factor_is_dual_src(ctx->Color.Blend[buf].SrcRGB) ||
+ blend_factor_is_dual_src(ctx->Color.Blend[buf].DstRGB) ||
+ blend_factor_is_dual_src(ctx->Color.Blend[buf].SrcA) ||
+ blend_factor_is_dual_src(ctx->Color.Blend[buf].DstA));
+}
/**
* Set the separate blend source/dest factors for all draw buffers.
@@ -220,6 +238,7 @@ _mesa_BlendFuncSeparateEXT( GLenum sfactorRGB, GLenum dfactorRGB,
ctx->Color.Blend[buf].DstRGB = dfactorRGB;
ctx->Color.Blend[buf].SrcA = sfactorA;
ctx->Color.Blend[buf].DstA = dfactorA;
+ update_uses_dual_src(ctx, buf);
}
ctx->Color._BlendFuncPerBuffer = GL_FALSE;
@@ -282,6 +301,7 @@ _mesa_BlendFuncSeparatei(GLuint buf, GLenum sfactorRGB, GLenum dfactorRGB,
ctx->Color.Blend[buf].DstRGB = dfactorRGB;
ctx->Color.Blend[buf].SrcA = sfactorA;
ctx->Color.Blend[buf].DstA = dfactorA;
+ update_uses_dual_src(ctx, buf);
ctx->Color._BlendFuncPerBuffer = GL_TRUE;
if (ctx->Driver.BlendFuncSeparatei) {
diff --git a/mesalib/src/mesa/main/context.c b/mesalib/src/mesa/main/context.c
index df0452cd1..3bcedecd9 100644
--- a/mesalib/src/mesa/main/context.c
+++ b/mesalib/src/mesa/main/context.c
@@ -1703,13 +1703,6 @@ _mesa_set_mvp_with_dp4( struct gl_context *ctx,
ctx->mvp_with_dp4 = flag;
}
-static GLboolean
-blend_factor_is_dual_src(GLenum factor)
-{
- return factor == GL_SRC1_COLOR || factor == GL_SRC1_ALPHA ||
- factor == GL_ONE_MINUS_SRC1_COLOR || factor == GL_ONE_MINUS_SRC1_ALPHA;
-}
-
/*
* ARB_blend_func_extended - ERRORS section
* "The error INVALID_OPERATION is generated by Begin or any procedure that
@@ -1722,16 +1715,13 @@ static GLboolean
_mesa_check_blend_func_error(struct gl_context *ctx)
{
GLuint i;
- for (i = 0; i < ctx->DrawBuffer->_NumColorDrawBuffers; i++) {
- if (blend_factor_is_dual_src(ctx->Color.Blend[i].SrcRGB) ||
- blend_factor_is_dual_src(ctx->Color.Blend[i].DstRGB) ||
- blend_factor_is_dual_src(ctx->Color.Blend[i].SrcA) ||
- blend_factor_is_dual_src(ctx->Color.Blend[i].DstA)) {
- if (i >= ctx->Const.MaxDualSourceDrawBuffers) {
- _mesa_error(ctx, GL_INVALID_OPERATION,
- "dual source blend on illegal attachment");
- return GL_FALSE;
- }
+ for (i = ctx->Const.MaxDualSourceDrawBuffers;
+ i < ctx->DrawBuffer->_NumColorDrawBuffers;
+ i++) {
+ if (ctx->Color.Blend[i]._UsesDualSrc) {
+ _mesa_error(ctx, GL_INVALID_OPERATION,
+ "dual source blend on illegal attachment");
+ return GL_FALSE;
}
}
return GL_TRUE;
diff --git a/mesalib/src/mesa/main/extensions.c b/mesalib/src/mesa/main/extensions.c
index a843a4092..cd76eeb3d 100644
--- a/mesalib/src/mesa/main/extensions.c
+++ b/mesalib/src/mesa/main/extensions.c
@@ -228,7 +228,7 @@ static const struct extension extension_table[] = {
{ "GL_OES_depth32", o(dummy_false), DISABLE, 2005 },
{ "GL_OES_depth_texture", o(ARB_depth_texture), ES2, 2006 },
#if FEATURE_OES_draw_texture
- { "GL_OES_draw_texture", o(OES_draw_texture), ES1 | ES2, 2004 },
+ { "GL_OES_draw_texture", o(OES_draw_texture), ES1, 2004 },
#endif
#if FEATURE_OES_EGL_image
/* FIXME: Mesa expects GL_OES_EGL_image to be available in OpenGL contexts. */
diff --git a/mesalib/src/mesa/main/ff_fragment_shader.cpp b/mesalib/src/mesa/main/ff_fragment_shader.cpp
index 8a42281db..0233f3802 100644
--- a/mesalib/src/mesa/main/ff_fragment_shader.cpp
+++ b/mesalib/src/mesa/main/ff_fragment_shader.cpp
@@ -1007,6 +1007,15 @@ static void load_texture( struct texenv_fragment_program *p, GLuint unit )
sampler_name,
ir_var_uniform);
p->top_instructions->push_head(sampler);
+
+ /* Set the texture unit for this sampler. The linker will pick this value
+ * up and do-the-right-thing.
+ *
+ * NOTE: The cast to int is important. Without it, the constant will have
+ * type uint, and things later on may get confused.
+ */
+ sampler->constant_value = new(p->mem_ctx) ir_constant(int(unit));
+
deref = new(p->mem_ctx) ir_dereference_variable(sampler);
tex->set_sampler(deref, glsl_type::vec4_type);
@@ -1350,38 +1359,6 @@ create_new_program(struct gl_context *ctx, struct state_key *key)
_mesa_associate_uniform_storage(ctx, p.shader_program, fp->Parameters);
- for (unsigned int i = 0; i < MAX_TEXTURE_UNITS; i++) {
- /* Enough space for 'sampler_999\0'.
- */
- char name[12];
-
- snprintf(name, sizeof(name), "sampler_%d", i);
-
- int loc = _mesa_get_uniform_location(ctx, p.shader_program, name);
- if (loc != -1) {
- unsigned base;
- unsigned idx;
-
- /* Avoid using _mesa_uniform() because it flags state
- * updates, so if we're generating this shader_program in a
- * state update, we end up recursing. Instead, just set the
- * value, which is picked up at re-link.
- */
- _mesa_uniform_split_location_offset(loc, &base, &idx);
- assert(idx == 0);
-
- struct gl_uniform_storage *const storage =
- &p.shader_program->UniformStorage[base];
-
- /* Update the storage, the SamplerUnits in the shader program, and
- * the SamplerUnits in the assembly shader.
- */
- storage->storage[idx].i = i;
- fp->SamplerUnits[storage->sampler] = i;
- p.shader_program->SamplerUnits[storage->sampler] = i;
- _mesa_propagate_uniforms_to_driver_storage(storage, 0, 1);
- }
- }
_mesa_update_shader_textures_used(p.shader_program, fp);
(void) ctx->Driver.ProgramStringNotify(ctx, fp->Target, fp);
diff --git a/mesalib/src/mesa/main/mtypes.h b/mesalib/src/mesa/main/mtypes.h
index eefe5e7e9..3a8cac9c5 100644
--- a/mesalib/src/mesa/main/mtypes.h
+++ b/mesalib/src/mesa/main/mtypes.h
@@ -755,6 +755,11 @@ struct gl_colorbuffer_attrib
GLenum DstA; /**< Alpha blend dest term */
GLenum EquationRGB; /**< GL_ADD, GL_SUBTRACT, etc. */
GLenum EquationA; /**< GL_ADD, GL_SUBTRACT, etc. */
+ /**
+ * Set if any blend factor uses SRC1. Computed at the time blend factors
+ * get set.
+ */
+ GLboolean _UsesDualSrc;
} Blend[MAX_DRAW_BUFFERS];
/** Are the blend func terms currently different for each buffer/target? */
GLboolean _BlendFuncPerBuffer;
diff --git a/mesalib/src/mesa/main/uniforms.c b/mesalib/src/mesa/main/uniforms.c
index be1e1728d..e6604b1a4 100644
--- a/mesalib/src/mesa/main/uniforms.c
+++ b/mesalib/src/mesa/main/uniforms.c
@@ -65,6 +65,7 @@ _mesa_update_shader_textures_used(struct gl_shader_program *shProg,
{
GLuint s;
+ memcpy(prog->SamplerUnits, shProg->SamplerUnits, sizeof(prog->SamplerUnits));
memset(prog->TexturesUsed, 0, sizeof(prog->TexturesUsed));
for (s = 0; s < MAX_SAMPLERS; s++) {
diff --git a/mesalib/src/mesa/program/ir_to_mesa.cpp b/mesalib/src/mesa/program/ir_to_mesa.cpp
index 840648e04..c021c6956 100644
--- a/mesalib/src/mesa/program/ir_to_mesa.cpp
+++ b/mesalib/src/mesa/program/ir_to_mesa.cpp
@@ -2526,109 +2526,18 @@ _mesa_associate_uniform_storage(struct gl_context *ctx,
4 * sizeof(float),
format,
&params->ParameterValues[i]);
- last_location = location;
- }
- }
-}
-
-static void
-set_uniform_initializer(struct gl_context *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 = ralloc_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) {
- linker_error(shader_program,
- "Couldn't find uniform for initializer %s\n", name);
- return;
- }
-
- 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 = ralloc_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);
- } else {
- _mesa_uniform(ctx, shader_program, loc, element_type->matrix_columns,
- values, element_type->gl_type);
- }
-
- loc++;
- }
-}
-
-static void
-set_uniform_initializers(struct gl_context *ctx,
- struct gl_shader_program *shader_program)
-{
- void *mem_ctx = NULL;
-
- for (unsigned int i = 0; i < MESA_SHADER_TYPES; i++) {
- struct gl_shader *shader = shader_program->_LinkedShaders[i];
-
- if (shader == NULL)
- continue;
-
- 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 = ralloc_context(NULL);
+ /* After attaching the driver's storage to the uniform, propagate any
+ * data from the linker's backing store. This will cause values from
+ * initializers in the source code to be copied over.
+ */
+ _mesa_propagate_uniforms_to_driver_storage(storage,
+ 0,
+ MAX2(1, storage->array_elements));
- set_uniform_initializer(ctx, mem_ctx, shader_program, var->name,
- var->type, var->constant_value);
+ last_location = location;
}
}
-
- ralloc_free(mem_ctx);
}
/*
@@ -3240,10 +3149,6 @@ _mesa_glsl_link_shader(struct gl_context *ctx, struct gl_shader_program *prog)
}
}
- if (prog->LinkStatus) {
- 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);
diff --git a/mesalib/src/mesa/state_tracker/st_cb_texture.c b/mesalib/src/mesa/state_tracker/st_cb_texture.c
index f9c190a68..b24f9a1ce 100644
--- a/mesalib/src/mesa/state_tracker/st_cb_texture.c
+++ b/mesalib/src/mesa/state_tracker/st_cb_texture.c
@@ -400,6 +400,8 @@ guess_and_alloc_texture(struct st_context *st,
ptLayers,
bindings);
+ stObj->lastLevel = lastLevel;
+
DBG("%s returning %d\n", __FUNCTION__, (stObj->pt != NULL));
return stObj->pt != NULL;