summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/glsl/ast_to_hir.cpp63
-rw-r--r--src/glsl/glcpp/glcpp-parse.y3
-rw-r--r--src/glsl/glsl_lexer.ll1
-rw-r--r--src/glsl/glsl_parser_extras.h17
4 files changed, 71 insertions, 13 deletions
diff --git a/src/glsl/ast_to_hir.cpp b/src/glsl/ast_to_hir.cpp
index f754652dc9c..f06baeb9f31 100644
--- a/src/glsl/ast_to_hir.cpp
+++ b/src/glsl/ast_to_hir.cpp
@@ -2123,11 +2123,16 @@ validate_explicit_location(const struct ast_type_qualifier *qual,
{
bool fail = false;
- /* In the vertex shader only shader inputs can be given explicit
- * locations.
+ /* Between GL_ARB_explicit_attrib_location an
+ * GL_ARB_separate_shader_objects, the inputs and outputs of any shader
+ * stage can be assigned explicit locations. The checking here associates
+ * the correct extension with the correct stage's input / output:
*
- * In the fragment shader only shader outputs can be given explicit
- * locations.
+ * input output
+ * ----- ------
+ * vertex explicit_loc sso
+ * geometry sso sso
+ * fragment sso explicit_loc
*/
switch (state->stage) {
case MESA_SHADER_VERTEX:
@@ -2138,16 +2143,35 @@ validate_explicit_location(const struct ast_type_qualifier *qual,
break;
}
+ if (var->data.mode == ir_var_shader_out) {
+ if (!state->check_separate_shader_objects_allowed(loc, var))
+ return;
+
+ break;
+ }
+
fail = true;
break;
case MESA_SHADER_GEOMETRY:
- _mesa_glsl_error(loc, state,
- "geometry shader variables cannot be given "
- "explicit locations");
- return;
+ if (var->data.mode == ir_var_shader_in || var->data.mode == ir_var_shader_out) {
+ if (!state->check_separate_shader_objects_allowed(loc, var))
+ return;
+
+ break;
+ }
+
+ fail = true;
+ break;
case MESA_SHADER_FRAGMENT:
+ if (var->data.mode == ir_var_shader_in) {
+ if (!state->check_separate_shader_objects_allowed(loc, var))
+ return;
+
+ break;
+ }
+
if (var->data.mode == ir_var_shader_out) {
if (!state->check_explicit_attrib_location_allowed(loc, var))
return;
@@ -2181,9 +2205,23 @@ validate_explicit_location(const struct ast_type_qualifier *qual,
* ensures that negative values stay negative.
*/
if (qual->location >= 0) {
- var->data.location = (state->stage == MESA_SHADER_VERTEX)
- ? (qual->location + VERT_ATTRIB_GENERIC0)
- : (qual->location + FRAG_RESULT_DATA0);
+ switch (state->stage) {
+ case MESA_SHADER_VERTEX:
+ var->data.location = (var->data.mode == ir_var_shader_in)
+ ? (qual->location + VERT_ATTRIB_GENERIC0)
+ : (qual->location + VARYING_SLOT_VAR0);
+ break;
+
+ case MESA_SHADER_GEOMETRY:
+ var->data.location = qual->location + VARYING_SLOT_VAR0;
+ break;
+
+ case MESA_SHADER_FRAGMENT:
+ var->data.location = (var->data.mode == ir_var_shader_out)
+ ? (qual->location + FRAG_RESULT_DATA0)
+ : (qual->location + VARYING_SLOT_VAR0);
+ break;
+ }
} else {
var->data.location = qual->location;
}
@@ -2207,8 +2245,6 @@ validate_explicit_location(const struct ast_type_qualifier *qual,
}
}
}
-
- return;
}
static void
@@ -3147,6 +3183,7 @@ ast_declarator_list::hir(exec_list *instructions,
*/
if (!state->is_version(130, 300)
&& !state->has_explicit_attrib_location()
+ && !state->has_separate_shader_objects()
&& !state->ARB_fragment_coord_conventions_enable) {
if (this->type->qualifier.flags.q.out) {
_mesa_glsl_error(& loc, state,
diff --git a/src/glsl/glcpp/glcpp-parse.y b/src/glsl/glcpp/glcpp-parse.y
index bdc598f31b8..f28d8531eb1 100644
--- a/src/glsl/glcpp/glcpp-parse.y
+++ b/src/glsl/glcpp/glcpp-parse.y
@@ -2134,6 +2134,9 @@ _glcpp_parser_handle_version_declaration(glcpp_parser_t *parser, intmax_t versio
if (extensions->ARB_texture_gather)
add_builtin_define(parser, "GL_ARB_texture_gather", 1);
+ if (extensions->ARB_separate_shader_objects)
+ add_builtin_define(parser, "GL_ARB_separate_shader_objects", 1);
+
if (extensions->ARB_shader_atomic_counters)
add_builtin_define(parser, "GL_ARB_shader_atomic_counters", 1);
diff --git a/src/glsl/glsl_lexer.ll b/src/glsl/glsl_lexer.ll
index 9f31ceeed79..9fd9b80d3e8 100644
--- a/src/glsl/glsl_lexer.ll
+++ b/src/glsl/glsl_lexer.ll
@@ -392,6 +392,7 @@ layout {
|| yyextra->AMD_conservative_depth_enable
|| yyextra->ARB_conservative_depth_enable
|| yyextra->ARB_explicit_attrib_location_enable
+ || yyextra->has_separate_shader_objects()
|| yyextra->ARB_uniform_buffer_object_enable
|| yyextra->ARB_fragment_coord_conventions_enable
|| yyextra->ARB_shading_language_420pack_enable
diff --git a/src/glsl/glsl_parser_extras.h b/src/glsl/glsl_parser_extras.h
index 884e83e2f62..300d9005117 100644
--- a/src/glsl/glsl_parser_extras.h
+++ b/src/glsl/glsl_parser_extras.h
@@ -135,6 +135,23 @@ struct _mesa_glsl_parse_state {
return true;
}
+ bool check_separate_shader_objects_allowed(YYLTYPE *locp,
+ const ir_variable *var)
+ {
+ if (!this->has_separate_shader_objects()) {
+ const char *const requirement = this->es_shader
+ ? "GL_EXT_separate_shader_objects (not supported by this "
+ "implementation)"
+ : "GL_ARB_separate_shader_objects extension or GLSL 420";
+
+ _mesa_glsl_error(locp, this, "%s explicit location requires %s",
+ mode_string(var), requirement);
+ return false;
+ }
+
+ return true;
+ }
+
bool has_explicit_attrib_location() const
{
return ARB_explicit_attrib_location_enable || is_version(330, 300);