aboutsummaryrefslogtreecommitdiff
path: root/mesalib/src/glsl/linker.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'mesalib/src/glsl/linker.cpp')
-rw-r--r--mesalib/src/glsl/linker.cpp146
1 files changed, 72 insertions, 74 deletions
diff --git a/mesalib/src/glsl/linker.cpp b/mesalib/src/glsl/linker.cpp
index d802a0a9b..9463f5305 100644
--- a/mesalib/src/glsl/linker.cpp
+++ b/mesalib/src/glsl/linker.cpp
@@ -1298,71 +1298,6 @@ assign_attribute_or_color_locations(gl_shader_program *prog,
invalidate_variable_locations(sh, direction, generic_base);
- if ((target_index == MESA_SHADER_VERTEX) && (prog->Attributes != NULL)) {
- for (unsigned i = 0; i < prog->Attributes->NumParameters; i++) {
- ir_variable *const var =
- sh->symbols->get_variable(prog->Attributes->Parameters[i].Name);
-
- /* Note: attributes that occupy multiple slots, such as arrays or
- * matrices, may appear in the attrib array multiple times.
- */
- if ((var == NULL) || (var->location != -1))
- continue;
-
- /* From page 61 of the OpenGL 4.0 spec:
- *
- * "LinkProgram will fail if the attribute bindings assigned by
- * BindAttribLocation do not leave not enough space to assign a
- * location for an active matrix attribute or an active attribute
- * array, both of which require multiple contiguous generic
- * attributes."
- *
- * Previous versions of the spec contain similar language but omit the
- * bit about attribute arrays.
- *
- * Page 61 of the OpenGL 4.0 spec also says:
- *
- * "It is possible for an application to bind more than one
- * attribute name to the same location. This is referred to as
- * aliasing. This will only work if only one of the aliased
- * attributes is active in the executable program, or if no path
- * through the shader consumes more than one attribute of a set
- * of attributes aliased to the same location. A link error can
- * occur if the linker determines that every path through the
- * shader consumes multiple aliased attributes, but
- * implementations are not required to generate an error in this
- * case."
- *
- * These two paragraphs are either somewhat contradictory, or I don't
- * fully understand one or both of them.
- */
- /* FINISHME: The code as currently written does not support attribute
- * FINISHME: location aliasing (see comment above).
- */
- const int attr = prog->Attributes->Parameters[i].StateIndexes[0];
- const unsigned slots = count_attribute_slots(var->type);
-
- /* Mask representing the contiguous slots that will be used by this
- * attribute.
- */
- const unsigned use_mask = (1 << slots) - 1;
-
- /* Generate a link error if the set of bits requested for this
- * attribute overlaps any previously allocated bits.
- */
- if ((~(use_mask << attr) & used_locations) != used_locations) {
- linker_error(prog,
- "insufficient contiguous attribute locations "
- "available for vertex shader input `%s'",
- var->name);
- return false;
- }
-
- var->location = VERT_ATTRIB_GENERIC0 + attr;
- used_locations |= (use_mask << attr);
- }
- }
-
/* Temporary storage for the set of attributes that need locations assigned.
*/
struct temp_attr {
@@ -1389,28 +1324,83 @@ assign_attribute_or_color_locations(gl_shader_program *prog,
continue;
if (var->explicit_location) {
- const unsigned slots = count_attribute_slots(var->type);
- const unsigned use_mask = (1 << slots) - 1;
- const int attr = var->location - generic_base;
-
if ((var->location >= (int)(max_index + generic_base))
|| (var->location < 0)) {
linker_error(prog,
"invalid explicit location %d specified for `%s'\n",
- (var->location < 0) ? var->location : attr,
+ (var->location < 0)
+ ? var->location : var->location - generic_base,
var->name);
return false;
- } else if (var->location >= generic_base) {
- used_locations |= (use_mask << attr);
+ }
+ } else if (target_index == MESA_SHADER_VERTEX) {
+ unsigned binding;
+
+ if (prog->AttributeBindings->get(binding, var->name)) {
+ assert(binding >= VERT_ATTRIB_GENERIC0);
+ var->location = binding;
}
}
/* The location was explicitly assigned, nothing to do here.
*/
- if (var->location != -1)
+ const unsigned slots = count_attribute_slots(var->type);
+ if (var->location != -1) {
+ if (var->location >= generic_base) {
+ /* From page 61 of the OpenGL 4.0 spec:
+ *
+ * "LinkProgram will fail if the attribute bindings assigned
+ * by BindAttribLocation do not leave not enough space to
+ * assign a location for an active matrix attribute or an
+ * active attribute array, both of which require multiple
+ * contiguous generic attributes."
+ *
+ * Previous versions of the spec contain similar language but omit
+ * the bit about attribute arrays.
+ *
+ * Page 61 of the OpenGL 4.0 spec also says:
+ *
+ * "It is possible for an application to bind more than one
+ * attribute name to the same location. This is referred to as
+ * aliasing. This will only work if only one of the aliased
+ * attributes is active in the executable program, or if no
+ * path through the shader consumes more than one attribute of
+ * a set of attributes aliased to the same location. A link
+ * error can occur if the linker determines that every path
+ * through the shader consumes multiple aliased attributes,
+ * but implementations are not required to generate an error
+ * in this case."
+ *
+ * These two paragraphs are either somewhat contradictory, or I
+ * don't fully understand one or both of them.
+ */
+ /* FINISHME: The code as currently written does not support
+ * FINISHME: attribute location aliasing (see comment above).
+ */
+ /* Mask representing the contiguous slots that will be used by
+ * this attribute.
+ */
+ const unsigned attr = var->location - generic_base;
+ const unsigned use_mask = (1 << slots) - 1;
+
+ /* Generate a link error if the set of bits requested for this
+ * attribute overlaps any previously allocated bits.
+ */
+ if ((~(use_mask << attr) & used_locations) != used_locations) {
+ linker_error(prog,
+ "insufficient contiguous attribute locations "
+ "available for vertex shader input `%s'",
+ var->name);
+ return false;
+ }
+
+ used_locations |= (use_mask << attr);
+ }
+
continue;
+ }
- to_assign[num_attr].slots = count_attribute_slots(var->type);
+ to_assign[num_attr].slots = slots;
to_assign[num_attr].var = var;
num_attr++;
}
@@ -1831,6 +1821,14 @@ done:
/* Retain any live IR, but trash the rest. */
reparent_ir(prog->_LinkedShaders[i]->ir, prog->_LinkedShaders[i]->ir);
+
+ /* The symbol table in the linked shaders may contain references to
+ * variables that were removed (e.g., unused uniforms). Since it may
+ * contain junk, there is no possible valid use. Delete it and set the
+ * pointer to NULL.
+ */
+ delete prog->_LinkedShaders[i]->symbols;
+ prog->_LinkedShaders[i]->symbols = NULL;
}
ralloc_free(mem_ctx);