From 94438578d219d0f701a6324cf294ee23d102a978 Mon Sep 17 00:00:00 2001 From: Timothy Arceri Date: Wed, 11 Nov 2015 06:24:53 +1100 Subject: [PATCH] glsl: validate and store component layout qualifier in GLSL IR We make use of the existing IR field location_frac used for tracking component locations. Reviewed-by: Anuj Phogat Reviewed-by: Edward O'Callaghan Reviewed-by: Kenneth Graunke --- src/compiler/glsl/ast_to_hir.cpp | 38 ++++++++++++++++++++++++++++++++++++++ src/compiler/glsl/ir.h | 5 +++++ 2 files changed, 43 insertions(+) diff --git a/src/compiler/glsl/ast_to_hir.cpp b/src/compiler/glsl/ast_to_hir.cpp index dd8e4e0..c5cd48f 100644 --- a/src/compiler/glsl/ast_to_hir.cpp +++ b/src/compiler/glsl/ast_to_hir.cpp @@ -3346,10 +3346,42 @@ apply_layout_qualifier_to_variable(const struct ast_type_qualifier *qual, if (qual->flags.q.explicit_location) { apply_explicit_location(qual, var, state, loc); + + if (qual->flags.q.explicit_component) { + unsigned qual_component; + if (process_qualifier_constant(state, loc, "component", + qual->component, &qual_component)) { + const glsl_type *type = var->type->without_array(); + unsigned components = type->component_slots(); + + if (type->is_matrix() || type->is_record()) { + _mesa_glsl_error(loc, state, "component layout qualifier " + "cannot be applied to a matrix, a structure, " + "a block, or an array containing any of " + "these."); + } else if (qual_component != 0 && + (qual_component + components - 1) > 3) { + _mesa_glsl_error(loc, state, "component overflow (%u > 3)", + (qual_component + components - 1)); + } else if (qual_component == 1 && type->is_double()) { + /* We don't bother checking for 3 as it should be caught by the + * overflow check above. + */ + _mesa_glsl_error(loc, state, "doubles cannot begin at " + "component 1 or 3"); + } else { + var->data.explicit_component = true; + var->data.location_frac = qual_component; + } + } + } } else if (qual->flags.q.explicit_index) { if (!qual->flags.q.subroutine_def) _mesa_glsl_error(loc, state, "explicit index requires explicit location"); + } else if (qual->flags.q.explicit_component) { + _mesa_glsl_error(loc, state, + "explicit component requires explicit location"); } if (qual->flags.q.explicit_binding) { @@ -7007,6 +7039,12 @@ ast_interface_block::hir(exec_list *instructions, "Interface block sets both readonly and writeonly"); } + if (this->layout.flags.q.explicit_component) { + _mesa_glsl_error(&loc, state, "component layout qualifier cannot be " + "applied to a matrix, a structure, a block, or an " + "array containing any of these."); + } + unsigned qual_stream; if (!process_qualifier_constant(state, &loc, "stream", this->layout.stream, &qual_stream) || diff --git a/src/compiler/glsl/ir.h b/src/compiler/glsl/ir.h index b1a1d56..0c319ea 100644 --- a/src/compiler/glsl/ir.h +++ b/src/compiler/glsl/ir.h @@ -703,6 +703,11 @@ public: unsigned explicit_binding:1; /** + * Was an initial component explicitly set in the shader? + */ + unsigned explicit_component:1; + + /** * Does this variable have an initializer? * * This is used by the linker to cross-validiate initializers of global -- 2.7.4