summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/glsl/ast.h12
-rw-r--r--src/glsl/ast_to_hir.cpp9
-rw-r--r--src/glsl/builtin_variables.cpp1
-rw-r--r--src/glsl/glsl_parser.yy20
-rw-r--r--src/glsl/ir.h1
-rw-r--r--src/glsl/ir_clone.cpp4
-rw-r--r--src/glsl/ir_set_program_inouts.cpp4
-rw-r--r--src/glsl/linker.cpp13
8 files changed, 57 insertions, 7 deletions
diff --git a/src/glsl/ast.h b/src/glsl/ast.h
index 9b1e0b19209..b096c838c06 100644
--- a/src/glsl/ast.h
+++ b/src/glsl/ast.h
@@ -363,6 +363,11 @@ struct ast_type_qualifier {
* qualifier is used.
*/
unsigned explicit_location:1;
+ /**
+ * Flag set if GL_ARB_explicit_attrib_location "index" layout
+ * qualifier is used.
+ */
+ unsigned explicit_index:1;
/** \name Layout qualifiers for GL_AMD_conservative_depth */
/** \{ */
@@ -386,6 +391,13 @@ struct ast_type_qualifier {
* This field is only valid if \c explicit_location is set.
*/
int location;
+ /**
+ * Index specified via GL_ARB_explicit_attrib_location layout
+ *
+ * \note
+ * This field is only valid if \c explicit_index is set.
+ */
+ int index;
/**
* Return true if and only if an interpolation qualifier is present.
diff --git a/src/glsl/ast_to_hir.cpp b/src/glsl/ast_to_hir.cpp
index f4dfc4ce34c..820c86c5e6b 100644
--- a/src/glsl/ast_to_hir.cpp
+++ b/src/glsl/ast_to_hir.cpp
@@ -2092,14 +2092,21 @@ apply_type_qualifier_to_variable(const struct ast_type_qualifier *qual,
} else {
var->location = qual->location;
}
+ if (qual->flags.q.explicit_index) {
+ var->explicit_index = true;
+ var->index = qual->index;
+ }
}
+ } else if (qual->flags.q.explicit_index) {
+ _mesa_glsl_error(loc, state,
+ "explicit index requires explicit location\n");
}
/* Does the declaration use the 'layout' keyword?
*/
const bool uses_layout = qual->flags.q.pixel_center_integer
|| qual->flags.q.origin_upper_left
- || qual->flags.q.explicit_location;
+ || qual->flags.q.explicit_location; /* no need for index since it relies on location */
/* Does the declaration use the deprecated 'attribute' or 'varying'
* keywords?
diff --git a/src/glsl/builtin_variables.cpp b/src/glsl/builtin_variables.cpp
index 516a69caff9..03b64c931a4 100644
--- a/src/glsl/builtin_variables.cpp
+++ b/src/glsl/builtin_variables.cpp
@@ -408,6 +408,7 @@ add_variable(exec_list *instructions, glsl_symbol_table *symtab,
var->location = slot;
var->explicit_location = (slot >= 0);
+ var->explicit_index = 0;
/* Once the variable is created an initialized, add it to the symbol table
* and add the declaration to the IR stream.
diff --git a/src/glsl/glsl_parser.yy b/src/glsl/glsl_parser.yy
index 920213c3035..5753acf3cd1 100644
--- a/src/glsl/glsl_parser.yy
+++ b/src/glsl/glsl_parser.yy
@@ -1103,8 +1103,14 @@ layout_qualifier_id_list:
if ($1.flags.q.explicit_location)
$$.location = $1.location;
+ if ($1.flags.q.explicit_index)
+ $$.index = $1.index;
+
if ($3.flags.q.explicit_location)
$$.location = $3.location;
+
+ if ($3.flags.q.explicit_index)
+ $$.index = $3.index;
}
;
@@ -1191,6 +1197,20 @@ layout_qualifier_id:
YYERROR;
}
}
+
+ if (strcmp("index", $1) == 0) {
+ got_one = true;
+
+ $$.flags.q.explicit_index = 1;
+
+ if ($3 >= 0) {
+ $$.index = $3;
+ } else {
+ _mesa_glsl_error(& @3, state,
+ "invalid index %d specified\n", $3);
+ YYERROR;
+ }
+ }
}
/* If the identifier didn't match any known layout identifiers,
diff --git a/src/glsl/ir.h b/src/glsl/ir.h
index 9450e8f8430..d6c6a607ae8 100644
--- a/src/glsl/ir.h
+++ b/src/glsl/ir.h
@@ -386,6 +386,7 @@ public:
* no effect).
*/
unsigned explicit_location:1;
+ unsigned explicit_index:1;
/**
* Does this variable have an initializer?
diff --git a/src/glsl/ir_clone.cpp b/src/glsl/ir_clone.cpp
index 26b0d8f5f3f..5a7a71cf6ba 100644
--- a/src/glsl/ir_clone.cpp
+++ b/src/glsl/ir_clone.cpp
@@ -57,6 +57,7 @@ ir_variable::clone(void *mem_ctx, struct hash_table *ht) const
var->origin_upper_left = this->origin_upper_left;
var->pixel_center_integer = this->pixel_center_integer;
var->explicit_location = this->explicit_location;
+ var->explicit_index = this->explicit_index;
var->has_initializer = this->has_initializer;
var->depth_layout = this->depth_layout;
@@ -74,6 +75,9 @@ ir_variable::clone(void *mem_ctx, struct hash_table *ht) const
if (this->explicit_location)
var->location = this->location;
+ if (this->explicit_index)
+ var->index = this->index;
+
if (this->constant_value)
var->constant_value = this->constant_value->clone(mem_ctx, ht);
diff --git a/src/glsl/ir_set_program_inouts.cpp b/src/glsl/ir_set_program_inouts.cpp
index 8c2bc30d614..8f3edb96936 100644
--- a/src/glsl/ir_set_program_inouts.cpp
+++ b/src/glsl/ir_set_program_inouts.cpp
@@ -81,12 +81,12 @@ mark(struct gl_program *prog, ir_variable *var, int offset, int len,
*/
for (int i = 0; i < len; i++) {
- GLbitfield64 bitfield = BITFIELD64_BIT(var->location + offset + i);
+ GLbitfield64 bitfield = BITFIELD64_BIT(var->location + var->index + offset + i);
if (var->mode == ir_var_in) {
prog->InputsRead |= bitfield;
if (is_fragment_shader) {
gl_fragment_program *fprog = (gl_fragment_program *) prog;
- fprog->InterpQualifier[var->location + offset + i] =
+ fprog->InterpQualifier[var->location + var->index + offset + i] =
(glsl_interp_qualifier) var->interpolation;
}
} else if (var->mode == ir_var_system_value) {
diff --git a/src/glsl/linker.cpp b/src/glsl/linker.cpp
index 49b6b8f4a5e..6ba297237c7 100644
--- a/src/glsl/linker.cpp
+++ b/src/glsl/linker.cpp
@@ -1274,10 +1274,15 @@ assign_attribute_or_color_locations(gl_shader_program *prog,
}
} else if (target_index == MESA_SHADER_FRAGMENT) {
unsigned binding;
+ unsigned index;
if (prog->FragDataBindings->get(binding, var->name)) {
assert(binding >= FRAG_RESULT_DATA0);
var->location = binding;
+
+ if (prog->FragDataIndexBindings->get(index, var->name)) {
+ var->index = index;
+ }
}
}
@@ -1288,7 +1293,7 @@ assign_attribute_or_color_locations(gl_shader_program *prog,
*/
const unsigned slots = count_attribute_slots(var->type);
if (var->location != -1) {
- if (var->location >= generic_base) {
+ if (var->location >= generic_base && var->index < 1) {
/* From page 61 of the OpenGL 4.0 spec:
*
* "LinkProgram will fail if the attribute bindings assigned
@@ -1333,8 +1338,8 @@ assign_attribute_or_color_locations(gl_shader_program *prog,
? "vertex shader input" : "fragment shader output";
linker_error(prog,
"insufficient contiguous locations "
- "available for %s `%s'", string,
- var->name);
+ "available for %s `%s' %d %d %d", string,
+ var->name, used_locations, use_mask, attr);
return false;
}
@@ -2321,7 +2326,7 @@ link_shaders(struct gl_context *ctx, struct gl_shader_program *prog)
goto done;
}
- if (!assign_attribute_or_color_locations(prog, MESA_SHADER_FRAGMENT, ctx->Const.MaxDrawBuffers)) {
+ if (!assign_attribute_or_color_locations(prog, MESA_SHADER_FRAGMENT, MAX2(ctx->Const.MaxDrawBuffers, ctx->Const.MaxDualSourceDrawBuffers))) {
goto done;
}