diff options
-rw-r--r-- | src/glsl/ast.h | 12 | ||||
-rw-r--r-- | src/glsl/ast_to_hir.cpp | 9 | ||||
-rw-r--r-- | src/glsl/builtin_variables.cpp | 1 | ||||
-rw-r--r-- | src/glsl/glsl_parser.yy | 20 | ||||
-rw-r--r-- | src/glsl/ir.h | 1 | ||||
-rw-r--r-- | src/glsl/ir_clone.cpp | 4 | ||||
-rw-r--r-- | src/glsl/ir_set_program_inouts.cpp | 4 | ||||
-rw-r--r-- | src/glsl/linker.cpp | 13 |
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; } |