glsl: Fix locations of variables in patch qualified interface blocks.
[mesa.git] / src / compiler / glsl / glsl_parser.yy
index 5b6586141d868be21c35f8ebe34995cdcf50e7b2..9e1fd9e3e67f268524b1399c0bcaacf812171b1d 100644 (file)
@@ -1446,6 +1446,51 @@ layout_qualifier_id:
          }
       }
 
+      if (!$$.flags.i) {
+         static const struct {
+            const char *s;
+            uint32_t mask;
+         } map[] = {
+                 { "blend_support_multiply",       BLEND_MULTIPLY },
+                 { "blend_support_screen",         BLEND_SCREEN },
+                 { "blend_support_overlay",        BLEND_OVERLAY },
+                 { "blend_support_darken",         BLEND_DARKEN },
+                 { "blend_support_lighten",        BLEND_LIGHTEN },
+                 { "blend_support_colordodge",     BLEND_COLORDODGE },
+                 { "blend_support_colorburn",      BLEND_COLORBURN },
+                 { "blend_support_hardlight",      BLEND_HARDLIGHT },
+                 { "blend_support_softlight",      BLEND_SOFTLIGHT },
+                 { "blend_support_difference",     BLEND_DIFFERENCE },
+                 { "blend_support_exclusion",      BLEND_EXCLUSION },
+                 { "blend_support_hsl_hue",        BLEND_HSL_HUE },
+                 { "blend_support_hsl_saturation", BLEND_HSL_SATURATION },
+                 { "blend_support_hsl_color",      BLEND_HSL_COLOR },
+                 { "blend_support_hsl_luminosity", BLEND_HSL_LUMINOSITY },
+                 { "blend_support_all_equations",  BLEND_ALL },
+         };
+         for (unsigned i = 0; i < ARRAY_SIZE(map); i++) {
+            if (match_layout_qualifier($1, map[i].s, state) == 0) {
+               $$.flags.q.blend_support = 1;
+               state->fs_blend_support |= map[i].mask;
+               break;
+            }
+         }
+
+         if ($$.flags.i &&
+             !state->KHR_blend_equation_advanced_enable &&
+             !state->is_version(0, 320)) {
+            _mesa_glsl_error(& @1, state,
+                             "advanced blending layout qualifiers require "
+                             "ESSL 3.20 or KHR_blend_equation_advanced");
+         }
+
+         if ($$.flags.i && state->stage != MESA_SHADER_FRAGMENT) {
+            _mesa_glsl_error(& @1, state,
+                             "advanced blending layout qualifiers only "
+                             "valid in fragment shaders");
+         }
+      }
+
       if (!$$.flags.i) {
          _mesa_glsl_error(& @1, state, "unrecognized layout identifier "
                           "`%s'", $1);
@@ -1587,8 +1632,10 @@ layout_qualifier_id:
       if (match_layout_qualifier("invocations", $1, state) == 0) {
          $$.flags.q.invocations = 1;
          $$.invocations = new(ctx) ast_layout_expression(@1, $3);
-         if (!state->is_version(400, 0) &&
-             !state->ARB_gpu_shader5_enable) {
+         if (!state->is_version(400, 320) &&
+             !state->ARB_gpu_shader5_enable &&
+             !state->OES_geometry_shader_enable &&
+             !state->EXT_geometry_shader_enable) {
             _mesa_glsl_error(& @3, state,
                              "GL_ARB_gpu_shader5 invocations "
                              "qualifier specified", $3);
@@ -1944,6 +1991,18 @@ storage_qualifier:
           $$.xfb_buffer = state->out_qualifier->xfb_buffer;
       }
    }
+   | INOUT_TOK
+   {
+      memset(& $$, 0, sizeof($$));
+      $$.flags.q.in = 1;
+      $$.flags.q.out = 1;
+
+      if (!state->has_framebuffer_fetch() ||
+          !state->is_version(130, 300) ||
+          state->stage != MESA_SHADER_FRAGMENT)
+         _mesa_glsl_error(&@1, state, "A single interface variable cannot be "
+                          "declared as both input and output");
+   }
    | UNIFORM
    {
       memset(& $$, 0, sizeof($$));
@@ -2699,6 +2758,17 @@ interface_qualifier:
       memset(& $$, 0, sizeof($$));
       $$.flags.q.buffer = 1;
    }
+   | auxiliary_storage_qualifier interface_qualifier
+   {
+      if (!$1.flags.q.patch) {
+         _mesa_glsl_error(&@1, state, "invalid interface qualifier");
+      }
+      if ($2.has_auxiliary_storage()) {
+         _mesa_glsl_error(&@1, state, "duplicate patch qualifier");
+      }
+      $$ = $2;
+      $$.flags.q.patch = 1;
+   }
    ;
 
 instance_name_opt: