101e04c3fSmrg/*
201e04c3fSmrg * Copyright © 2008, 2009 Intel Corporation
301e04c3fSmrg *
401e04c3fSmrg * Permission is hereby granted, free of charge, to any person obtaining a
501e04c3fSmrg * copy of this software and associated documentation files (the "Software"),
601e04c3fSmrg * to deal in the Software without restriction, including without limitation
701e04c3fSmrg * the rights to use, copy, modify, merge, publish, distribute, sublicense,
801e04c3fSmrg * and/or sell copies of the Software, and to permit persons to whom the
901e04c3fSmrg * Software is furnished to do so, subject to the following conditions:
1001e04c3fSmrg *
1101e04c3fSmrg * The above copyright notice and this permission notice (including the next
1201e04c3fSmrg * paragraph) shall be included in all copies or substantial portions of the
1301e04c3fSmrg * Software.
1401e04c3fSmrg *
1501e04c3fSmrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
1601e04c3fSmrg * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
1701e04c3fSmrg * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
1801e04c3fSmrg * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
1901e04c3fSmrg * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
2001e04c3fSmrg * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
2101e04c3fSmrg * DEALINGS IN THE SOFTWARE.
2201e04c3fSmrg */
2301e04c3fSmrg#include <inttypes.h> /* for PRIx64 macro */
2401e04c3fSmrg#include <stdio.h>
2501e04c3fSmrg#include <stdarg.h>
2601e04c3fSmrg#include <string.h>
2701e04c3fSmrg#include <assert.h>
2801e04c3fSmrg
2901e04c3fSmrg#include "main/context.h"
3001e04c3fSmrg#include "main/debug_output.h"
3101e04c3fSmrg#include "main/formats.h"
3201e04c3fSmrg#include "main/shaderobj.h"
3301e04c3fSmrg#include "util/u_atomic.h" /* for p_atomic_cmpxchg */
3401e04c3fSmrg#include "util/ralloc.h"
3501e04c3fSmrg#include "util/disk_cache.h"
3601e04c3fSmrg#include "util/mesa-sha1.h"
3701e04c3fSmrg#include "ast.h"
3801e04c3fSmrg#include "glsl_parser_extras.h"
3901e04c3fSmrg#include "glsl_parser.h"
4001e04c3fSmrg#include "ir_optimization.h"
4101e04c3fSmrg#include "loop_analysis.h"
4201e04c3fSmrg#include "builtin_functions.h"
4301e04c3fSmrg
4401e04c3fSmrg/**
4501e04c3fSmrg * Format a short human-readable description of the given GLSL version.
4601e04c3fSmrg */
4701e04c3fSmrgconst char *
4801e04c3fSmrgglsl_compute_version_string(void *mem_ctx, bool is_es, unsigned version)
4901e04c3fSmrg{
5001e04c3fSmrg   return ralloc_asprintf(mem_ctx, "GLSL%s %d.%02d", is_es ? " ES" : "",
5101e04c3fSmrg                          version / 100, version % 100);
5201e04c3fSmrg}
5301e04c3fSmrg
5401e04c3fSmrg
5501e04c3fSmrgstatic const unsigned known_desktop_glsl_versions[] =
5601e04c3fSmrg   { 110, 120, 130, 140, 150, 330, 400, 410, 420, 430, 440, 450, 460 };
5701e04c3fSmrgstatic const unsigned known_desktop_gl_versions[] =
5801e04c3fSmrg   {  20,  21,  30,  31,  32,  33,  40,  41,  42,  43,  44,  45, 46 };
5901e04c3fSmrg
6001e04c3fSmrg
6101e04c3fSmrg_mesa_glsl_parse_state::_mesa_glsl_parse_state(struct gl_context *_ctx,
6201e04c3fSmrg					       gl_shader_stage stage,
6301e04c3fSmrg                                               void *mem_ctx)
6401e04c3fSmrg   : ctx(_ctx), cs_input_local_size_specified(false), cs_input_local_size(),
65d8407755Smaya     switch_state(), warnings_enabled(true)
6601e04c3fSmrg{
6701e04c3fSmrg   assert(stage < MESA_SHADER_STAGES);
6801e04c3fSmrg   this->stage = stage;
6901e04c3fSmrg
7001e04c3fSmrg   this->scanner = NULL;
7101e04c3fSmrg   this->translation_unit.make_empty();
7201e04c3fSmrg   this->symbols = new(mem_ctx) glsl_symbol_table;
7301e04c3fSmrg
7401e04c3fSmrg   this->linalloc = linear_alloc_parent(this, 0);
7501e04c3fSmrg
7601e04c3fSmrg   this->info_log = ralloc_strdup(mem_ctx, "");
7701e04c3fSmrg   this->error = false;
7801e04c3fSmrg   this->loop_nesting_ast = NULL;
7901e04c3fSmrg
8001e04c3fSmrg   this->uses_builtin_functions = false;
8101e04c3fSmrg
8201e04c3fSmrg   /* Set default language version and extensions */
8301e04c3fSmrg   this->language_version = 110;
8401e04c3fSmrg   this->forced_language_version = ctx->Const.ForceGLSLVersion;
851463c08dSmrg   if (ctx->Const.GLSLZeroInit == 1) {
861463c08dSmrg      this->zero_init = (1u << ir_var_auto) | (1u << ir_var_temporary) | (1u << ir_var_shader_out);
871463c08dSmrg   } else if (ctx->Const.GLSLZeroInit == 2) {
881463c08dSmrg      this->zero_init = (1u << ir_var_auto) | (1u << ir_var_temporary) | (1u << ir_var_function_out);
891463c08dSmrg   } else {
901463c08dSmrg      this->zero_init = 0;
911463c08dSmrg   }
9201e04c3fSmrg   this->gl_version = 20;
9301e04c3fSmrg   this->compat_shader = true;
9401e04c3fSmrg   this->es_shader = false;
9501e04c3fSmrg   this->ARB_texture_rectangle_enable = true;
9601e04c3fSmrg
9701e04c3fSmrg   /* OpenGL ES 2.0 has different defaults from desktop GL. */
9801e04c3fSmrg   if (ctx->API == API_OPENGLES2) {
9901e04c3fSmrg      this->language_version = 100;
10001e04c3fSmrg      this->es_shader = true;
10101e04c3fSmrg      this->ARB_texture_rectangle_enable = false;
10201e04c3fSmrg   }
10301e04c3fSmrg
10401e04c3fSmrg   this->extensions = &ctx->Extensions;
10501e04c3fSmrg
10601e04c3fSmrg   this->Const.MaxLights = ctx->Const.MaxLights;
10701e04c3fSmrg   this->Const.MaxClipPlanes = ctx->Const.MaxClipPlanes;
10801e04c3fSmrg   this->Const.MaxTextureUnits = ctx->Const.MaxTextureUnits;
10901e04c3fSmrg   this->Const.MaxTextureCoords = ctx->Const.MaxTextureCoordUnits;
11001e04c3fSmrg   this->Const.MaxVertexAttribs = ctx->Const.Program[MESA_SHADER_VERTEX].MaxAttribs;
11101e04c3fSmrg   this->Const.MaxVertexUniformComponents = ctx->Const.Program[MESA_SHADER_VERTEX].MaxUniformComponents;
11201e04c3fSmrg   this->Const.MaxVertexTextureImageUnits = ctx->Const.Program[MESA_SHADER_VERTEX].MaxTextureImageUnits;
11301e04c3fSmrg   this->Const.MaxCombinedTextureImageUnits = ctx->Const.MaxCombinedTextureImageUnits;
11401e04c3fSmrg   this->Const.MaxTextureImageUnits = ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxTextureImageUnits;
11501e04c3fSmrg   this->Const.MaxFragmentUniformComponents = ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxUniformComponents;
11601e04c3fSmrg   this->Const.MinProgramTexelOffset = ctx->Const.MinProgramTexelOffset;
11701e04c3fSmrg   this->Const.MaxProgramTexelOffset = ctx->Const.MaxProgramTexelOffset;
11801e04c3fSmrg
11901e04c3fSmrg   this->Const.MaxDrawBuffers = ctx->Const.MaxDrawBuffers;
12001e04c3fSmrg
12101e04c3fSmrg   this->Const.MaxDualSourceDrawBuffers = ctx->Const.MaxDualSourceDrawBuffers;
12201e04c3fSmrg
12301e04c3fSmrg   /* 1.50 constants */
12401e04c3fSmrg   this->Const.MaxVertexOutputComponents = ctx->Const.Program[MESA_SHADER_VERTEX].MaxOutputComponents;
12501e04c3fSmrg   this->Const.MaxGeometryInputComponents = ctx->Const.Program[MESA_SHADER_GEOMETRY].MaxInputComponents;
12601e04c3fSmrg   this->Const.MaxGeometryOutputComponents = ctx->Const.Program[MESA_SHADER_GEOMETRY].MaxOutputComponents;
12701e04c3fSmrg   this->Const.MaxGeometryShaderInvocations = ctx->Const.MaxGeometryShaderInvocations;
12801e04c3fSmrg   this->Const.MaxFragmentInputComponents = ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxInputComponents;
12901e04c3fSmrg   this->Const.MaxGeometryTextureImageUnits = ctx->Const.Program[MESA_SHADER_GEOMETRY].MaxTextureImageUnits;
13001e04c3fSmrg   this->Const.MaxGeometryOutputVertices = ctx->Const.MaxGeometryOutputVertices;
13101e04c3fSmrg   this->Const.MaxGeometryTotalOutputComponents = ctx->Const.MaxGeometryTotalOutputComponents;
13201e04c3fSmrg   this->Const.MaxGeometryUniformComponents = ctx->Const.Program[MESA_SHADER_GEOMETRY].MaxUniformComponents;
13301e04c3fSmrg
13401e04c3fSmrg   this->Const.MaxVertexAtomicCounters = ctx->Const.Program[MESA_SHADER_VERTEX].MaxAtomicCounters;
13501e04c3fSmrg   this->Const.MaxTessControlAtomicCounters = ctx->Const.Program[MESA_SHADER_TESS_CTRL].MaxAtomicCounters;
13601e04c3fSmrg   this->Const.MaxTessEvaluationAtomicCounters = ctx->Const.Program[MESA_SHADER_TESS_EVAL].MaxAtomicCounters;
13701e04c3fSmrg   this->Const.MaxGeometryAtomicCounters = ctx->Const.Program[MESA_SHADER_GEOMETRY].MaxAtomicCounters;
13801e04c3fSmrg   this->Const.MaxFragmentAtomicCounters = ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxAtomicCounters;
13901e04c3fSmrg   this->Const.MaxComputeAtomicCounters = ctx->Const.Program[MESA_SHADER_COMPUTE].MaxAtomicCounters;
14001e04c3fSmrg   this->Const.MaxCombinedAtomicCounters = ctx->Const.MaxCombinedAtomicCounters;
14101e04c3fSmrg   this->Const.MaxAtomicBufferBindings = ctx->Const.MaxAtomicBufferBindings;
14201e04c3fSmrg   this->Const.MaxVertexAtomicCounterBuffers =
14301e04c3fSmrg      ctx->Const.Program[MESA_SHADER_VERTEX].MaxAtomicBuffers;
14401e04c3fSmrg   this->Const.MaxTessControlAtomicCounterBuffers =
14501e04c3fSmrg      ctx->Const.Program[MESA_SHADER_TESS_CTRL].MaxAtomicBuffers;
14601e04c3fSmrg   this->Const.MaxTessEvaluationAtomicCounterBuffers =
14701e04c3fSmrg      ctx->Const.Program[MESA_SHADER_TESS_EVAL].MaxAtomicBuffers;
14801e04c3fSmrg   this->Const.MaxGeometryAtomicCounterBuffers =
14901e04c3fSmrg      ctx->Const.Program[MESA_SHADER_GEOMETRY].MaxAtomicBuffers;
15001e04c3fSmrg   this->Const.MaxFragmentAtomicCounterBuffers =
15101e04c3fSmrg      ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxAtomicBuffers;
15201e04c3fSmrg   this->Const.MaxComputeAtomicCounterBuffers =
15301e04c3fSmrg      ctx->Const.Program[MESA_SHADER_COMPUTE].MaxAtomicBuffers;
15401e04c3fSmrg   this->Const.MaxCombinedAtomicCounterBuffers =
15501e04c3fSmrg      ctx->Const.MaxCombinedAtomicBuffers;
15601e04c3fSmrg   this->Const.MaxAtomicCounterBufferSize =
15701e04c3fSmrg      ctx->Const.MaxAtomicBufferSize;
15801e04c3fSmrg
15901e04c3fSmrg   /* ARB_enhanced_layouts constants */
16001e04c3fSmrg   this->Const.MaxTransformFeedbackBuffers = ctx->Const.MaxTransformFeedbackBuffers;
16101e04c3fSmrg   this->Const.MaxTransformFeedbackInterleavedComponents = ctx->Const.MaxTransformFeedbackInterleavedComponents;
16201e04c3fSmrg
16301e04c3fSmrg   /* Compute shader constants */
16401e04c3fSmrg   for (unsigned i = 0; i < ARRAY_SIZE(this->Const.MaxComputeWorkGroupCount); i++)
16501e04c3fSmrg      this->Const.MaxComputeWorkGroupCount[i] = ctx->Const.MaxComputeWorkGroupCount[i];
16601e04c3fSmrg   for (unsigned i = 0; i < ARRAY_SIZE(this->Const.MaxComputeWorkGroupSize); i++)
16701e04c3fSmrg      this->Const.MaxComputeWorkGroupSize[i] = ctx->Const.MaxComputeWorkGroupSize[i];
16801e04c3fSmrg
16901e04c3fSmrg   this->Const.MaxComputeTextureImageUnits = ctx->Const.Program[MESA_SHADER_COMPUTE].MaxTextureImageUnits;
17001e04c3fSmrg   this->Const.MaxComputeUniformComponents = ctx->Const.Program[MESA_SHADER_COMPUTE].MaxUniformComponents;
17101e04c3fSmrg
17201e04c3fSmrg   this->Const.MaxImageUnits = ctx->Const.MaxImageUnits;
17301e04c3fSmrg   this->Const.MaxCombinedShaderOutputResources = ctx->Const.MaxCombinedShaderOutputResources;
17401e04c3fSmrg   this->Const.MaxImageSamples = ctx->Const.MaxImageSamples;
17501e04c3fSmrg   this->Const.MaxVertexImageUniforms = ctx->Const.Program[MESA_SHADER_VERTEX].MaxImageUniforms;
17601e04c3fSmrg   this->Const.MaxTessControlImageUniforms = ctx->Const.Program[MESA_SHADER_TESS_CTRL].MaxImageUniforms;
17701e04c3fSmrg   this->Const.MaxTessEvaluationImageUniforms = ctx->Const.Program[MESA_SHADER_TESS_EVAL].MaxImageUniforms;
17801e04c3fSmrg   this->Const.MaxGeometryImageUniforms = ctx->Const.Program[MESA_SHADER_GEOMETRY].MaxImageUniforms;
17901e04c3fSmrg   this->Const.MaxFragmentImageUniforms = ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxImageUniforms;
18001e04c3fSmrg   this->Const.MaxComputeImageUniforms = ctx->Const.Program[MESA_SHADER_COMPUTE].MaxImageUniforms;
18101e04c3fSmrg   this->Const.MaxCombinedImageUniforms = ctx->Const.MaxCombinedImageUniforms;
18201e04c3fSmrg
18301e04c3fSmrg   /* ARB_viewport_array */
18401e04c3fSmrg   this->Const.MaxViewports = ctx->Const.MaxViewports;
18501e04c3fSmrg
18601e04c3fSmrg   /* tessellation shader constants */
18701e04c3fSmrg   this->Const.MaxPatchVertices = ctx->Const.MaxPatchVertices;
18801e04c3fSmrg   this->Const.MaxTessGenLevel = ctx->Const.MaxTessGenLevel;
18901e04c3fSmrg   this->Const.MaxTessControlInputComponents = ctx->Const.Program[MESA_SHADER_TESS_CTRL].MaxInputComponents;
19001e04c3fSmrg   this->Const.MaxTessControlOutputComponents = ctx->Const.Program[MESA_SHADER_TESS_CTRL].MaxOutputComponents;
19101e04c3fSmrg   this->Const.MaxTessControlTextureImageUnits = ctx->Const.Program[MESA_SHADER_TESS_CTRL].MaxTextureImageUnits;
19201e04c3fSmrg   this->Const.MaxTessEvaluationInputComponents = ctx->Const.Program[MESA_SHADER_TESS_EVAL].MaxInputComponents;
19301e04c3fSmrg   this->Const.MaxTessEvaluationOutputComponents = ctx->Const.Program[MESA_SHADER_TESS_EVAL].MaxOutputComponents;
19401e04c3fSmrg   this->Const.MaxTessEvaluationTextureImageUnits = ctx->Const.Program[MESA_SHADER_TESS_EVAL].MaxTextureImageUnits;
19501e04c3fSmrg   this->Const.MaxTessPatchComponents = ctx->Const.MaxTessPatchComponents;
19601e04c3fSmrg   this->Const.MaxTessControlTotalOutputComponents = ctx->Const.MaxTessControlTotalOutputComponents;
19701e04c3fSmrg   this->Const.MaxTessControlUniformComponents = ctx->Const.Program[MESA_SHADER_TESS_CTRL].MaxUniformComponents;
19801e04c3fSmrg   this->Const.MaxTessEvaluationUniformComponents = ctx->Const.Program[MESA_SHADER_TESS_EVAL].MaxUniformComponents;
19901e04c3fSmrg
20001e04c3fSmrg   /* GL 4.5 / OES_sample_variables */
20101e04c3fSmrg   this->Const.MaxSamples = ctx->Const.MaxSamples;
20201e04c3fSmrg
20301e04c3fSmrg   this->current_function = NULL;
20401e04c3fSmrg   this->toplevel_ir = NULL;
20501e04c3fSmrg   this->found_return = false;
2061463c08dSmrg   this->found_begin_interlock = false;
2071463c08dSmrg   this->found_end_interlock = false;
20801e04c3fSmrg   this->all_invariant = false;
20901e04c3fSmrg   this->user_structures = NULL;
21001e04c3fSmrg   this->num_user_structures = 0;
21101e04c3fSmrg   this->num_subroutines = 0;
21201e04c3fSmrg   this->subroutines = NULL;
21301e04c3fSmrg   this->num_subroutine_types = 0;
21401e04c3fSmrg   this->subroutine_types = NULL;
21501e04c3fSmrg
21601e04c3fSmrg   /* supported_versions should be large enough to support the known desktop
21701e04c3fSmrg    * GLSL versions plus 4 GLES versions (ES 1.00, ES 3.00, ES 3.10, ES 3.20)
21801e04c3fSmrg    */
21901e04c3fSmrg   STATIC_ASSERT((ARRAY_SIZE(known_desktop_glsl_versions) + 4) ==
22001e04c3fSmrg                 ARRAY_SIZE(this->supported_versions));
22101e04c3fSmrg
22201e04c3fSmrg   /* Populate the list of supported GLSL versions */
22301e04c3fSmrg   /* FINISHME: Once the OpenGL 3.0 'forward compatible' context or
22401e04c3fSmrg    * the OpenGL 3.2 Core context is supported, this logic will need
22501e04c3fSmrg    * change.  Older versions of GLSL are no longer supported
22601e04c3fSmrg    * outside the compatibility contexts of 3.x.
22701e04c3fSmrg    */
22801e04c3fSmrg   this->num_supported_versions = 0;
22901e04c3fSmrg   if (_mesa_is_desktop_gl(ctx)) {
23001e04c3fSmrg      for (unsigned i = 0; i < ARRAY_SIZE(known_desktop_glsl_versions); i++) {
23101e04c3fSmrg         if (known_desktop_glsl_versions[i] <= ctx->Const.GLSLVersion) {
23201e04c3fSmrg            this->supported_versions[this->num_supported_versions].ver
23301e04c3fSmrg               = known_desktop_glsl_versions[i];
23401e04c3fSmrg            this->supported_versions[this->num_supported_versions].gl_ver
23501e04c3fSmrg               = known_desktop_gl_versions[i];
23601e04c3fSmrg            this->supported_versions[this->num_supported_versions].es = false;
23701e04c3fSmrg            this->num_supported_versions++;
23801e04c3fSmrg         }
23901e04c3fSmrg      }
24001e04c3fSmrg   }
24101e04c3fSmrg   if (ctx->API == API_OPENGLES2 || ctx->Extensions.ARB_ES2_compatibility) {
24201e04c3fSmrg      this->supported_versions[this->num_supported_versions].ver = 100;
24301e04c3fSmrg      this->supported_versions[this->num_supported_versions].gl_ver = 20;
24401e04c3fSmrg      this->supported_versions[this->num_supported_versions].es = true;
24501e04c3fSmrg      this->num_supported_versions++;
24601e04c3fSmrg   }
24701e04c3fSmrg   if (_mesa_is_gles3(ctx) || ctx->Extensions.ARB_ES3_compatibility) {
24801e04c3fSmrg      this->supported_versions[this->num_supported_versions].ver = 300;
24901e04c3fSmrg      this->supported_versions[this->num_supported_versions].gl_ver = 30;
25001e04c3fSmrg      this->supported_versions[this->num_supported_versions].es = true;
25101e04c3fSmrg      this->num_supported_versions++;
25201e04c3fSmrg   }
25301e04c3fSmrg   if (_mesa_is_gles31(ctx) || ctx->Extensions.ARB_ES3_1_compatibility) {
25401e04c3fSmrg      this->supported_versions[this->num_supported_versions].ver = 310;
25501e04c3fSmrg      this->supported_versions[this->num_supported_versions].gl_ver = 31;
25601e04c3fSmrg      this->supported_versions[this->num_supported_versions].es = true;
25701e04c3fSmrg      this->num_supported_versions++;
25801e04c3fSmrg   }
25901e04c3fSmrg   if ((ctx->API == API_OPENGLES2 && ctx->Version >= 32) ||
26001e04c3fSmrg       ctx->Extensions.ARB_ES3_2_compatibility) {
26101e04c3fSmrg      this->supported_versions[this->num_supported_versions].ver = 320;
26201e04c3fSmrg      this->supported_versions[this->num_supported_versions].gl_ver = 32;
26301e04c3fSmrg      this->supported_versions[this->num_supported_versions].es = true;
26401e04c3fSmrg      this->num_supported_versions++;
26501e04c3fSmrg   }
26601e04c3fSmrg
26701e04c3fSmrg   /* Create a string for use in error messages to tell the user which GLSL
26801e04c3fSmrg    * versions are supported.
26901e04c3fSmrg    */
27001e04c3fSmrg   char *supported = ralloc_strdup(this, "");
27101e04c3fSmrg   for (unsigned i = 0; i < this->num_supported_versions; i++) {
27201e04c3fSmrg      unsigned ver = this->supported_versions[i].ver;
27301e04c3fSmrg      const char *const prefix = (i == 0)
27401e04c3fSmrg	 ? ""
27501e04c3fSmrg	 : ((i == this->num_supported_versions - 1) ? ", and " : ", ");
27601e04c3fSmrg      const char *const suffix = (this->supported_versions[i].es) ? " ES" : "";
27701e04c3fSmrg
27801e04c3fSmrg      ralloc_asprintf_append(& supported, "%s%u.%02u%s",
27901e04c3fSmrg			     prefix,
28001e04c3fSmrg			     ver / 100, ver % 100,
28101e04c3fSmrg			     suffix);
28201e04c3fSmrg   }
28301e04c3fSmrg
28401e04c3fSmrg   this->supported_version_string = supported;
28501e04c3fSmrg
28601e04c3fSmrg   if (ctx->Const.ForceGLSLExtensionsWarn)
28701e04c3fSmrg      _mesa_glsl_process_extension("all", NULL, "warn", NULL, this);
28801e04c3fSmrg
28901e04c3fSmrg   this->default_uniform_qualifier = new(this) ast_type_qualifier();
29001e04c3fSmrg   this->default_uniform_qualifier->flags.q.shared = 1;
29101e04c3fSmrg   this->default_uniform_qualifier->flags.q.column_major = 1;
29201e04c3fSmrg
29301e04c3fSmrg   this->default_shader_storage_qualifier = new(this) ast_type_qualifier();
29401e04c3fSmrg   this->default_shader_storage_qualifier->flags.q.shared = 1;
29501e04c3fSmrg   this->default_shader_storage_qualifier->flags.q.column_major = 1;
29601e04c3fSmrg
29701e04c3fSmrg   this->fs_uses_gl_fragcoord = false;
29801e04c3fSmrg   this->fs_redeclares_gl_fragcoord = false;
29901e04c3fSmrg   this->fs_origin_upper_left = false;
30001e04c3fSmrg   this->fs_pixel_center_integer = false;
30101e04c3fSmrg   this->fs_redeclares_gl_fragcoord_with_no_layout_qualifiers = false;
30201e04c3fSmrg
30301e04c3fSmrg   this->gs_input_prim_type_specified = false;
30401e04c3fSmrg   this->tcs_output_vertices_specified = false;
30501e04c3fSmrg   this->gs_input_size = 0;
30601e04c3fSmrg   this->in_qualifier = new(this) ast_type_qualifier();
30701e04c3fSmrg   this->out_qualifier = new(this) ast_type_qualifier();
30801e04c3fSmrg   this->fs_early_fragment_tests = false;
30901e04c3fSmrg   this->fs_inner_coverage = false;
31001e04c3fSmrg   this->fs_post_depth_coverage = false;
31101e04c3fSmrg   this->fs_pixel_interlock_ordered = false;
31201e04c3fSmrg   this->fs_pixel_interlock_unordered = false;
31301e04c3fSmrg   this->fs_sample_interlock_ordered = false;
31401e04c3fSmrg   this->fs_sample_interlock_unordered = false;
31501e04c3fSmrg   this->fs_blend_support = 0;
31601e04c3fSmrg   memset(this->atomic_counter_offsets, 0,
31701e04c3fSmrg          sizeof(this->atomic_counter_offsets));
31801e04c3fSmrg   this->allow_extension_directive_midshader =
31901e04c3fSmrg      ctx->Const.AllowGLSLExtensionDirectiveMidShader;
3201463c08dSmrg   this->allow_glsl_120_subset_in_110 =
3211463c08dSmrg      ctx->Const.AllowGLSL120SubsetIn110;
32201e04c3fSmrg   this->allow_builtin_variable_redeclaration =
32301e04c3fSmrg      ctx->Const.AllowGLSLBuiltinVariableRedeclaration;
3241463c08dSmrg   this->ignore_write_to_readonly_var =
3251463c08dSmrg      ctx->Const.GLSLIgnoreWriteToReadonlyVar;
32601e04c3fSmrg
32701e04c3fSmrg   this->cs_input_local_size_variable_specified = false;
32801e04c3fSmrg
32901e04c3fSmrg   /* ARB_bindless_texture */
33001e04c3fSmrg   this->bindless_sampler_specified = false;
33101e04c3fSmrg   this->bindless_image_specified = false;
33201e04c3fSmrg   this->bound_sampler_specified = false;
33301e04c3fSmrg   this->bound_image_specified = false;
3341463c08dSmrg
3351463c08dSmrg   this->language_version = this->forced_language_version ?
3361463c08dSmrg      this->forced_language_version : this->language_version;
3371463c08dSmrg   set_valid_gl_and_glsl_versions(NULL);
33801e04c3fSmrg}
33901e04c3fSmrg
34001e04c3fSmrg/**
34101e04c3fSmrg * Determine whether the current GLSL version is sufficiently high to support
34201e04c3fSmrg * a certain feature, and generate an error message if it isn't.
34301e04c3fSmrg *
34401e04c3fSmrg * \param required_glsl_version and \c required_glsl_es_version are
34501e04c3fSmrg * interpreted as they are in _mesa_glsl_parse_state::is_version().
34601e04c3fSmrg *
34701e04c3fSmrg * \param locp is the parser location where the error should be reported.
34801e04c3fSmrg *
34901e04c3fSmrg * \param fmt (and additional arguments) constitute a printf-style error
35001e04c3fSmrg * message to report if the version check fails.  Information about the
35101e04c3fSmrg * current and required GLSL versions will be appended.  So, for example, if
35201e04c3fSmrg * the GLSL version being compiled is 1.20, and check_version(130, 300, locp,
35301e04c3fSmrg * "foo unsupported") is called, the error message will be "foo unsupported in
35401e04c3fSmrg * GLSL 1.20 (GLSL 1.30 or GLSL 3.00 ES required)".
35501e04c3fSmrg */
35601e04c3fSmrgbool
35701e04c3fSmrg_mesa_glsl_parse_state::check_version(unsigned required_glsl_version,
35801e04c3fSmrg                                      unsigned required_glsl_es_version,
35901e04c3fSmrg                                      YYLTYPE *locp, const char *fmt, ...)
36001e04c3fSmrg{
36101e04c3fSmrg   if (this->is_version(required_glsl_version, required_glsl_es_version))
36201e04c3fSmrg      return true;
36301e04c3fSmrg
36401e04c3fSmrg   va_list args;
36501e04c3fSmrg   va_start(args, fmt);
36601e04c3fSmrg   char *problem = ralloc_vasprintf(this, fmt, args);
36701e04c3fSmrg   va_end(args);
36801e04c3fSmrg   const char *glsl_version_string
36901e04c3fSmrg      = glsl_compute_version_string(this, false, required_glsl_version);
37001e04c3fSmrg   const char *glsl_es_version_string
37101e04c3fSmrg      = glsl_compute_version_string(this, true, required_glsl_es_version);
37201e04c3fSmrg   const char *requirement_string = "";
37301e04c3fSmrg   if (required_glsl_version && required_glsl_es_version) {
37401e04c3fSmrg      requirement_string = ralloc_asprintf(this, " (%s or %s required)",
37501e04c3fSmrg                                           glsl_version_string,
37601e04c3fSmrg                                           glsl_es_version_string);
37701e04c3fSmrg   } else if (required_glsl_version) {
37801e04c3fSmrg      requirement_string = ralloc_asprintf(this, " (%s required)",
37901e04c3fSmrg                                           glsl_version_string);
38001e04c3fSmrg   } else if (required_glsl_es_version) {
38101e04c3fSmrg      requirement_string = ralloc_asprintf(this, " (%s required)",
38201e04c3fSmrg                                           glsl_es_version_string);
38301e04c3fSmrg   }
38401e04c3fSmrg   _mesa_glsl_error(locp, this, "%s in %s%s",
38501e04c3fSmrg                    problem, this->get_version_string(),
38601e04c3fSmrg                    requirement_string);
38701e04c3fSmrg
38801e04c3fSmrg   return false;
38901e04c3fSmrg}
39001e04c3fSmrg
3911463c08dSmrg/**
3921463c08dSmrg * This makes sure any GLSL versions defined or overridden are valid. If not it
3931463c08dSmrg * sets a valid value.
3941463c08dSmrg */
3951463c08dSmrgvoid
3961463c08dSmrg_mesa_glsl_parse_state::set_valid_gl_and_glsl_versions(YYLTYPE *locp)
3971463c08dSmrg{
3981463c08dSmrg   bool supported = false;
3991463c08dSmrg   for (unsigned i = 0; i < this->num_supported_versions; i++) {
4001463c08dSmrg      if (this->supported_versions[i].ver == this->language_version
4011463c08dSmrg          && this->supported_versions[i].es == this->es_shader) {
4021463c08dSmrg         this->gl_version = this->supported_versions[i].gl_ver;
4031463c08dSmrg         supported = true;
4041463c08dSmrg         break;
4051463c08dSmrg      }
4061463c08dSmrg   }
4071463c08dSmrg
4081463c08dSmrg   if (!supported) {
4091463c08dSmrg      if (locp) {
4101463c08dSmrg         _mesa_glsl_error(locp, this, "%s is not supported. "
4111463c08dSmrg                          "Supported versions are: %s",
4121463c08dSmrg                          this->get_version_string(),
4131463c08dSmrg                          this->supported_version_string);
4141463c08dSmrg      }
4151463c08dSmrg
4161463c08dSmrg      /* On exit, the language_version must be set to a valid value.
4171463c08dSmrg       * Later calls to _mesa_glsl_initialize_types will misbehave if
4181463c08dSmrg       * the version is invalid.
4191463c08dSmrg       */
4201463c08dSmrg      switch (this->ctx->API) {
4211463c08dSmrg      case API_OPENGL_COMPAT:
4221463c08dSmrg      case API_OPENGL_CORE:
4231463c08dSmrg	 this->language_version = this->ctx->Const.GLSLVersion;
4241463c08dSmrg	 break;
4251463c08dSmrg
4261463c08dSmrg      case API_OPENGLES:
4271463c08dSmrg	 FALLTHROUGH;
4281463c08dSmrg
4291463c08dSmrg      case API_OPENGLES2:
4301463c08dSmrg	 this->language_version = 100;
4311463c08dSmrg	 break;
4321463c08dSmrg      }
4331463c08dSmrg   }
4341463c08dSmrg}
4351463c08dSmrg
43601e04c3fSmrg/**
43701e04c3fSmrg * Process a GLSL #version directive.
43801e04c3fSmrg *
43901e04c3fSmrg * \param version is the integer that follows the #version token.
44001e04c3fSmrg *
44101e04c3fSmrg * \param ident is a string identifier that follows the integer, if any is
44201e04c3fSmrg * present.  Otherwise NULL.
44301e04c3fSmrg */
44401e04c3fSmrgvoid
44501e04c3fSmrg_mesa_glsl_parse_state::process_version_directive(YYLTYPE *locp, int version,
44601e04c3fSmrg                                                  const char *ident)
44701e04c3fSmrg{
44801e04c3fSmrg   bool es_token_present = false;
44901e04c3fSmrg   bool compat_token_present = false;
45001e04c3fSmrg   if (ident) {
45101e04c3fSmrg      if (strcmp(ident, "es") == 0) {
45201e04c3fSmrg         es_token_present = true;
45301e04c3fSmrg      } else if (version >= 150) {
45401e04c3fSmrg         if (strcmp(ident, "core") == 0) {
45501e04c3fSmrg            /* Accept the token.  There's no need to record that this is
45601e04c3fSmrg             * a core profile shader since that's the only profile we support.
45701e04c3fSmrg             */
45801e04c3fSmrg         } else if (strcmp(ident, "compatibility") == 0) {
45901e04c3fSmrg            compat_token_present = true;
46001e04c3fSmrg
46101e04c3fSmrg            if (this->ctx->API != API_OPENGL_COMPAT) {
46201e04c3fSmrg               _mesa_glsl_error(locp, this,
46301e04c3fSmrg                                "the compatibility profile is not supported");
46401e04c3fSmrg            }
46501e04c3fSmrg         } else {
46601e04c3fSmrg            _mesa_glsl_error(locp, this,
46701e04c3fSmrg                             "\"%s\" is not a valid shading language profile; "
46801e04c3fSmrg                             "if present, it must be \"core\"", ident);
46901e04c3fSmrg         }
47001e04c3fSmrg      } else {
47101e04c3fSmrg         _mesa_glsl_error(locp, this,
47201e04c3fSmrg                          "illegal text following version number");
47301e04c3fSmrg      }
47401e04c3fSmrg   }
47501e04c3fSmrg
47601e04c3fSmrg   this->es_shader = es_token_present;
47701e04c3fSmrg   if (version == 100) {
47801e04c3fSmrg      if (es_token_present) {
47901e04c3fSmrg         _mesa_glsl_error(locp, this,
48001e04c3fSmrg                          "GLSL 1.00 ES should be selected using "
48101e04c3fSmrg                          "`#version 100'");
48201e04c3fSmrg      } else {
48301e04c3fSmrg         this->es_shader = true;
48401e04c3fSmrg      }
48501e04c3fSmrg   }
48601e04c3fSmrg
48701e04c3fSmrg   if (this->es_shader) {
48801e04c3fSmrg      this->ARB_texture_rectangle_enable = false;
48901e04c3fSmrg   }
49001e04c3fSmrg
49101e04c3fSmrg   if (this->forced_language_version)
49201e04c3fSmrg      this->language_version = this->forced_language_version;
49301e04c3fSmrg   else
49401e04c3fSmrg      this->language_version = version;
49501e04c3fSmrg
49601e04c3fSmrg   this->compat_shader = compat_token_present ||
49701e04c3fSmrg                         (this->ctx->API == API_OPENGL_COMPAT &&
49801e04c3fSmrg                          this->language_version == 140) ||
49901e04c3fSmrg                         (!this->es_shader && this->language_version < 140);
50001e04c3fSmrg
5011463c08dSmrg   set_valid_gl_and_glsl_versions(locp);
50201e04c3fSmrg}
50301e04c3fSmrg
50401e04c3fSmrg
50501e04c3fSmrg/* This helper function will append the given message to the shader's
50601e04c3fSmrg   info log and report it via GL_ARB_debug_output. Per that extension,
50701e04c3fSmrg   'type' is one of the enum values classifying the message, and
50801e04c3fSmrg   'id' is the implementation-defined ID of the given message. */
50901e04c3fSmrgstatic void
51001e04c3fSmrg_mesa_glsl_msg(const YYLTYPE *locp, _mesa_glsl_parse_state *state,
51101e04c3fSmrg               GLenum type, const char *fmt, va_list ap)
51201e04c3fSmrg{
51301e04c3fSmrg   bool error = (type == MESA_DEBUG_TYPE_ERROR);
51401e04c3fSmrg   GLuint msg_id = 0;
51501e04c3fSmrg
51601e04c3fSmrg   assert(state->info_log != NULL);
51701e04c3fSmrg
51801e04c3fSmrg   /* Get the offset that the new message will be written to. */
51901e04c3fSmrg   int msg_offset = strlen(state->info_log);
52001e04c3fSmrg
5211463c08dSmrg   if (locp->path) {
5221463c08dSmrg      ralloc_asprintf_append(&state->info_log, "\"%s\"", locp->path);
5231463c08dSmrg   } else {
5241463c08dSmrg      ralloc_asprintf_append(&state->info_log, "%u", locp->source);
5251463c08dSmrg   }
5261463c08dSmrg   ralloc_asprintf_append(&state->info_log, ":%u(%u): %s: ",
5271463c08dSmrg                          locp->first_line, locp->first_column,
5281463c08dSmrg                          error ? "error" : "warning");
5291463c08dSmrg
53001e04c3fSmrg   ralloc_vasprintf_append(&state->info_log, fmt, ap);
53101e04c3fSmrg
53201e04c3fSmrg   const char *const msg = &state->info_log[msg_offset];
53301e04c3fSmrg   struct gl_context *ctx = state->ctx;
53401e04c3fSmrg
53501e04c3fSmrg   /* Report the error via GL_ARB_debug_output. */
53601e04c3fSmrg   _mesa_shader_debug(ctx, type, &msg_id, msg);
53701e04c3fSmrg
53801e04c3fSmrg   ralloc_strcat(&state->info_log, "\n");
53901e04c3fSmrg}
54001e04c3fSmrg
54101e04c3fSmrgvoid
54201e04c3fSmrg_mesa_glsl_error(YYLTYPE *locp, _mesa_glsl_parse_state *state,
54301e04c3fSmrg		 const char *fmt, ...)
54401e04c3fSmrg{
54501e04c3fSmrg   va_list ap;
54601e04c3fSmrg
54701e04c3fSmrg   state->error = true;
54801e04c3fSmrg
54901e04c3fSmrg   va_start(ap, fmt);
55001e04c3fSmrg   _mesa_glsl_msg(locp, state, MESA_DEBUG_TYPE_ERROR, fmt, ap);
55101e04c3fSmrg   va_end(ap);
55201e04c3fSmrg}
55301e04c3fSmrg
55401e04c3fSmrg
55501e04c3fSmrgvoid
55601e04c3fSmrg_mesa_glsl_warning(const YYLTYPE *locp, _mesa_glsl_parse_state *state,
55701e04c3fSmrg		   const char *fmt, ...)
55801e04c3fSmrg{
559d8407755Smaya   if (state->warnings_enabled) {
560d8407755Smaya      va_list ap;
56101e04c3fSmrg
562d8407755Smaya      va_start(ap, fmt);
563d8407755Smaya      _mesa_glsl_msg(locp, state, MESA_DEBUG_TYPE_OTHER, fmt, ap);
564d8407755Smaya      va_end(ap);
565d8407755Smaya   }
56601e04c3fSmrg}
56701e04c3fSmrg
56801e04c3fSmrg
56901e04c3fSmrg/**
57001e04c3fSmrg * Enum representing the possible behaviors that can be specified in
57101e04c3fSmrg * an #extension directive.
57201e04c3fSmrg */
57301e04c3fSmrgenum ext_behavior {
57401e04c3fSmrg   extension_disable,
57501e04c3fSmrg   extension_enable,
57601e04c3fSmrg   extension_require,
57701e04c3fSmrg   extension_warn
57801e04c3fSmrg};
57901e04c3fSmrg
58001e04c3fSmrg/**
58101e04c3fSmrg * Element type for _mesa_glsl_supported_extensions
58201e04c3fSmrg */
58301e04c3fSmrgstruct _mesa_glsl_extension {
58401e04c3fSmrg   /**
58501e04c3fSmrg    * Name of the extension when referred to in a GLSL extension
58601e04c3fSmrg    * statement
58701e04c3fSmrg    */
58801e04c3fSmrg   const char *name;
58901e04c3fSmrg
59001e04c3fSmrg   /**
59101e04c3fSmrg    * Whether this extension is a part of AEP
59201e04c3fSmrg    */
59301e04c3fSmrg   bool aep;
59401e04c3fSmrg
59501e04c3fSmrg   /**
59601e04c3fSmrg    * Predicate that checks whether the relevant extension is available for
59701e04c3fSmrg    * this context.
59801e04c3fSmrg    */
59901e04c3fSmrg   bool (*available_pred)(const struct gl_context *,
60001e04c3fSmrg                          gl_api api, uint8_t version);
60101e04c3fSmrg
60201e04c3fSmrg   /**
60301e04c3fSmrg    * Flag in the _mesa_glsl_parse_state struct that should be set
60401e04c3fSmrg    * when this extension is enabled.
60501e04c3fSmrg    *
60601e04c3fSmrg    * See note in _mesa_glsl_extension::supported_flag about "pointer
60701e04c3fSmrg    * to member" types.
60801e04c3fSmrg    */
60901e04c3fSmrg   bool _mesa_glsl_parse_state::* enable_flag;
61001e04c3fSmrg
61101e04c3fSmrg   /**
61201e04c3fSmrg    * Flag in the _mesa_glsl_parse_state struct that should be set
61301e04c3fSmrg    * when the shader requests "warn" behavior for this extension.
61401e04c3fSmrg    *
61501e04c3fSmrg    * See note in _mesa_glsl_extension::supported_flag about "pointer
61601e04c3fSmrg    * to member" types.
61701e04c3fSmrg    */
61801e04c3fSmrg   bool _mesa_glsl_parse_state::* warn_flag;
61901e04c3fSmrg
62001e04c3fSmrg
62101e04c3fSmrg   bool compatible_with_state(const _mesa_glsl_parse_state *state,
62201e04c3fSmrg                              gl_api api, uint8_t gl_version) const;
62301e04c3fSmrg   void set_flags(_mesa_glsl_parse_state *state, ext_behavior behavior) const;
62401e04c3fSmrg};
62501e04c3fSmrg
62601e04c3fSmrg/** Checks if the context supports a user-facing extension */
62701e04c3fSmrg#define EXT(name_str, driver_cap, ...) \
6281463c08dSmrgstatic UNUSED bool \
62901e04c3fSmrghas_##name_str(const struct gl_context *ctx, gl_api api, uint8_t version) \
63001e04c3fSmrg{ \
63101e04c3fSmrg   return ctx->Extensions.driver_cap && (version >= \
63201e04c3fSmrg          _mesa_extension_table[MESA_EXTENSION_##name_str].version[api]); \
63301e04c3fSmrg}
63401e04c3fSmrg#include "main/extensions_table.h"
63501e04c3fSmrg#undef EXT
63601e04c3fSmrg
63701e04c3fSmrg#define EXT(NAME)                                           \
63801e04c3fSmrg   { "GL_" #NAME, false, has_##NAME,                        \
63901e04c3fSmrg     &_mesa_glsl_parse_state::NAME##_enable,                \
64001e04c3fSmrg     &_mesa_glsl_parse_state::NAME##_warn }
64101e04c3fSmrg
64201e04c3fSmrg#define EXT_AEP(NAME)                                       \
64301e04c3fSmrg   { "GL_" #NAME, true, has_##NAME,                         \
64401e04c3fSmrg     &_mesa_glsl_parse_state::NAME##_enable,                \
64501e04c3fSmrg     &_mesa_glsl_parse_state::NAME##_warn }
64601e04c3fSmrg
64701e04c3fSmrg/**
64801e04c3fSmrg * Table of extensions that can be enabled/disabled within a shader,
64901e04c3fSmrg * and the conditions under which they are supported.
65001e04c3fSmrg */
65101e04c3fSmrgstatic const _mesa_glsl_extension _mesa_glsl_supported_extensions[] = {
65201e04c3fSmrg   /* ARB extensions go here, sorted alphabetically.
65301e04c3fSmrg    */
65401e04c3fSmrg   EXT(ARB_ES3_1_compatibility),
65501e04c3fSmrg   EXT(ARB_ES3_2_compatibility),
65601e04c3fSmrg   EXT(ARB_arrays_of_arrays),
65701e04c3fSmrg   EXT(ARB_bindless_texture),
65801e04c3fSmrg   EXT(ARB_compatibility),
65901e04c3fSmrg   EXT(ARB_compute_shader),
66001e04c3fSmrg   EXT(ARB_compute_variable_group_size),
66101e04c3fSmrg   EXT(ARB_conservative_depth),
66201e04c3fSmrg   EXT(ARB_cull_distance),
66301e04c3fSmrg   EXT(ARB_derivative_control),
66401e04c3fSmrg   EXT(ARB_draw_buffers),
66501e04c3fSmrg   EXT(ARB_draw_instanced),
66601e04c3fSmrg   EXT(ARB_enhanced_layouts),
66701e04c3fSmrg   EXT(ARB_explicit_attrib_location),
66801e04c3fSmrg   EXT(ARB_explicit_uniform_location),
66901e04c3fSmrg   EXT(ARB_fragment_coord_conventions),
67001e04c3fSmrg   EXT(ARB_fragment_layer_viewport),
67101e04c3fSmrg   EXT(ARB_fragment_shader_interlock),
67201e04c3fSmrg   EXT(ARB_gpu_shader5),
67301e04c3fSmrg   EXT(ARB_gpu_shader_fp64),
67401e04c3fSmrg   EXT(ARB_gpu_shader_int64),
67501e04c3fSmrg   EXT(ARB_post_depth_coverage),
67601e04c3fSmrg   EXT(ARB_sample_shading),
67701e04c3fSmrg   EXT(ARB_separate_shader_objects),
67801e04c3fSmrg   EXT(ARB_shader_atomic_counter_ops),
67901e04c3fSmrg   EXT(ARB_shader_atomic_counters),
68001e04c3fSmrg   EXT(ARB_shader_ballot),
68101e04c3fSmrg   EXT(ARB_shader_bit_encoding),
68201e04c3fSmrg   EXT(ARB_shader_clock),
68301e04c3fSmrg   EXT(ARB_shader_draw_parameters),
68401e04c3fSmrg   EXT(ARB_shader_group_vote),
68501e04c3fSmrg   EXT(ARB_shader_image_load_store),
68601e04c3fSmrg   EXT(ARB_shader_image_size),
68701e04c3fSmrg   EXT(ARB_shader_precision),
68801e04c3fSmrg   EXT(ARB_shader_stencil_export),
68901e04c3fSmrg   EXT(ARB_shader_storage_buffer_object),
69001e04c3fSmrg   EXT(ARB_shader_subroutine),
69101e04c3fSmrg   EXT(ARB_shader_texture_image_samples),
69201e04c3fSmrg   EXT(ARB_shader_texture_lod),
69301e04c3fSmrg   EXT(ARB_shader_viewport_layer_array),
69401e04c3fSmrg   EXT(ARB_shading_language_420pack),
6951463c08dSmrg   EXT(ARB_shading_language_include),
69601e04c3fSmrg   EXT(ARB_shading_language_packing),
69701e04c3fSmrg   EXT(ARB_tessellation_shader),
69801e04c3fSmrg   EXT(ARB_texture_cube_map_array),
69901e04c3fSmrg   EXT(ARB_texture_gather),
70001e04c3fSmrg   EXT(ARB_texture_multisample),
70101e04c3fSmrg   EXT(ARB_texture_query_levels),
70201e04c3fSmrg   EXT(ARB_texture_query_lod),
70301e04c3fSmrg   EXT(ARB_texture_rectangle),
70401e04c3fSmrg   EXT(ARB_uniform_buffer_object),
70501e04c3fSmrg   EXT(ARB_vertex_attrib_64bit),
70601e04c3fSmrg   EXT(ARB_viewport_array),
70701e04c3fSmrg
70801e04c3fSmrg   /* KHR extensions go here, sorted alphabetically.
70901e04c3fSmrg    */
71001e04c3fSmrg   EXT_AEP(KHR_blend_equation_advanced),
71101e04c3fSmrg
71201e04c3fSmrg   /* OES extensions go here, sorted alphabetically.
71301e04c3fSmrg    */
71401e04c3fSmrg   EXT(OES_EGL_image_external),
71501e04c3fSmrg   EXT(OES_EGL_image_external_essl3),
71601e04c3fSmrg   EXT(OES_geometry_point_size),
71701e04c3fSmrg   EXT(OES_geometry_shader),
71801e04c3fSmrg   EXT(OES_gpu_shader5),
71901e04c3fSmrg   EXT(OES_primitive_bounding_box),
72001e04c3fSmrg   EXT_AEP(OES_sample_variables),
72101e04c3fSmrg   EXT_AEP(OES_shader_image_atomic),
72201e04c3fSmrg   EXT(OES_shader_io_blocks),
72301e04c3fSmrg   EXT_AEP(OES_shader_multisample_interpolation),
72401e04c3fSmrg   EXT(OES_standard_derivatives),
72501e04c3fSmrg   EXT(OES_tessellation_point_size),
72601e04c3fSmrg   EXT(OES_tessellation_shader),
72701e04c3fSmrg   EXT(OES_texture_3D),
72801e04c3fSmrg   EXT(OES_texture_buffer),
72901e04c3fSmrg   EXT(OES_texture_cube_map_array),
73001e04c3fSmrg   EXT_AEP(OES_texture_storage_multisample_2d_array),
73101e04c3fSmrg   EXT(OES_viewport_array),
73201e04c3fSmrg
73301e04c3fSmrg   /* All other extensions go here, sorted alphabetically.
73401e04c3fSmrg    */
73501e04c3fSmrg   EXT(AMD_conservative_depth),
73601e04c3fSmrg   EXT(AMD_gpu_shader_int64),
73701e04c3fSmrg   EXT(AMD_shader_stencil_export),
73801e04c3fSmrg   EXT(AMD_shader_trinary_minmax),
739d8407755Smaya   EXT(AMD_texture_texture4),
74001e04c3fSmrg   EXT(AMD_vertex_shader_layer),
74101e04c3fSmrg   EXT(AMD_vertex_shader_viewport_index),
74201e04c3fSmrg   EXT(ANDROID_extension_pack_es31a),
74301e04c3fSmrg   EXT(EXT_blend_func_extended),
7441463c08dSmrg   EXT(EXT_demote_to_helper_invocation),
74501e04c3fSmrg   EXT(EXT_frag_depth),
74601e04c3fSmrg   EXT(EXT_draw_buffers),
7471463c08dSmrg   EXT(EXT_draw_instanced),
74801e04c3fSmrg   EXT(EXT_clip_cull_distance),
74901e04c3fSmrg   EXT(EXT_geometry_point_size),
75001e04c3fSmrg   EXT_AEP(EXT_geometry_shader),
751d8407755Smaya   EXT(EXT_gpu_shader4),
75201e04c3fSmrg   EXT_AEP(EXT_gpu_shader5),
75301e04c3fSmrg   EXT_AEP(EXT_primitive_bounding_box),
75401e04c3fSmrg   EXT(EXT_separate_shader_objects),
75501e04c3fSmrg   EXT(EXT_shader_framebuffer_fetch),
75601e04c3fSmrg   EXT(EXT_shader_framebuffer_fetch_non_coherent),
7571463c08dSmrg   EXT(EXT_shader_group_vote),
758d8407755Smaya   EXT(EXT_shader_image_load_formatted),
7591463c08dSmrg   EXT(EXT_shader_image_load_store),
760d8407755Smaya   EXT(EXT_shader_implicit_conversions),
76101e04c3fSmrg   EXT(EXT_shader_integer_mix),
76201e04c3fSmrg   EXT_AEP(EXT_shader_io_blocks),
76301e04c3fSmrg   EXT(EXT_shader_samples_identical),
76401e04c3fSmrg   EXT(EXT_tessellation_point_size),
76501e04c3fSmrg   EXT_AEP(EXT_tessellation_shader),
76601e04c3fSmrg   EXT(EXT_texture_array),
76701e04c3fSmrg   EXT_AEP(EXT_texture_buffer),
76801e04c3fSmrg   EXT_AEP(EXT_texture_cube_map_array),
769d8407755Smaya   EXT(EXT_texture_query_lod),
7701463c08dSmrg   EXT(EXT_texture_shadow_lod),
77101e04c3fSmrg   EXT(INTEL_conservative_rasterization),
77201e04c3fSmrg   EXT(INTEL_shader_atomic_float_minmax),
7731463c08dSmrg   EXT(INTEL_shader_integer_functions2),
77401e04c3fSmrg   EXT(MESA_shader_integer_functions),
775d8407755Smaya   EXT(NV_compute_shader_derivatives),
77601e04c3fSmrg   EXT(NV_fragment_shader_interlock),
77701e04c3fSmrg   EXT(NV_image_formats),
77801e04c3fSmrg   EXT(NV_shader_atomic_float),
7791463c08dSmrg   EXT(NV_shader_atomic_int64),
7801463c08dSmrg   EXT(NV_viewport_array2),
78101e04c3fSmrg};
78201e04c3fSmrg
78301e04c3fSmrg#undef EXT
78401e04c3fSmrg
78501e04c3fSmrg
78601e04c3fSmrg/**
78701e04c3fSmrg * Determine whether a given extension is compatible with the target,
78801e04c3fSmrg * API, and extension information in the current parser state.
78901e04c3fSmrg */
79001e04c3fSmrgbool _mesa_glsl_extension::compatible_with_state(
79101e04c3fSmrg      const _mesa_glsl_parse_state *state, gl_api api, uint8_t gl_version) const
79201e04c3fSmrg{
79301e04c3fSmrg   return this->available_pred(state->ctx, api, gl_version);
79401e04c3fSmrg}
79501e04c3fSmrg
79601e04c3fSmrg/**
79701e04c3fSmrg * Set the appropriate flags in the parser state to establish the
79801e04c3fSmrg * given behavior for this extension.
79901e04c3fSmrg */
80001e04c3fSmrgvoid _mesa_glsl_extension::set_flags(_mesa_glsl_parse_state *state,
80101e04c3fSmrg                                     ext_behavior behavior) const
80201e04c3fSmrg{
80301e04c3fSmrg   /* Note: the ->* operator indexes into state by the
80401e04c3fSmrg    * offsets this->enable_flag and this->warn_flag.  See
80501e04c3fSmrg    * _mesa_glsl_extension::supported_flag for more info.
80601e04c3fSmrg    */
80701e04c3fSmrg   state->*(this->enable_flag) = (behavior != extension_disable);
80801e04c3fSmrg   state->*(this->warn_flag)   = (behavior == extension_warn);
80901e04c3fSmrg}
81001e04c3fSmrg
81101e04c3fSmrg/**
81201e04c3fSmrg * Find an extension by name in _mesa_glsl_supported_extensions.  If
81301e04c3fSmrg * the name is not found, return NULL.
81401e04c3fSmrg */
81501e04c3fSmrgstatic const _mesa_glsl_extension *find_extension(const char *name)
81601e04c3fSmrg{
81701e04c3fSmrg   for (unsigned i = 0; i < ARRAY_SIZE(_mesa_glsl_supported_extensions); ++i) {
81801e04c3fSmrg      if (strcmp(name, _mesa_glsl_supported_extensions[i].name) == 0) {
81901e04c3fSmrg         return &_mesa_glsl_supported_extensions[i];
82001e04c3fSmrg      }
82101e04c3fSmrg   }
82201e04c3fSmrg   return NULL;
82301e04c3fSmrg}
82401e04c3fSmrg
82501e04c3fSmrgbool
82601e04c3fSmrg_mesa_glsl_process_extension(const char *name, YYLTYPE *name_locp,
82701e04c3fSmrg			     const char *behavior_string, YYLTYPE *behavior_locp,
82801e04c3fSmrg			     _mesa_glsl_parse_state *state)
82901e04c3fSmrg{
83001e04c3fSmrg   uint8_t gl_version = state->ctx->Extensions.Version;
83101e04c3fSmrg   gl_api api = state->ctx->API;
83201e04c3fSmrg   ext_behavior behavior;
83301e04c3fSmrg   if (strcmp(behavior_string, "warn") == 0) {
83401e04c3fSmrg      behavior = extension_warn;
83501e04c3fSmrg   } else if (strcmp(behavior_string, "require") == 0) {
83601e04c3fSmrg      behavior = extension_require;
83701e04c3fSmrg   } else if (strcmp(behavior_string, "enable") == 0) {
83801e04c3fSmrg      behavior = extension_enable;
83901e04c3fSmrg   } else if (strcmp(behavior_string, "disable") == 0) {
84001e04c3fSmrg      behavior = extension_disable;
84101e04c3fSmrg   } else {
84201e04c3fSmrg      _mesa_glsl_error(behavior_locp, state,
84301e04c3fSmrg		       "unknown extension behavior `%s'",
84401e04c3fSmrg		       behavior_string);
84501e04c3fSmrg      return false;
84601e04c3fSmrg   }
84701e04c3fSmrg
84801e04c3fSmrg   /* If we're in a desktop context but with an ES shader, use an ES API enum
84901e04c3fSmrg    * to verify extension availability.
85001e04c3fSmrg    */
85101e04c3fSmrg   if (state->es_shader && api != API_OPENGLES2)
85201e04c3fSmrg      api = API_OPENGLES2;
85301e04c3fSmrg   /* Use the language-version derived GL version to extension checks, unless
85401e04c3fSmrg    * we're using meta, which sets the version to the max.
85501e04c3fSmrg    */
85601e04c3fSmrg   if (gl_version != 0xff)
85701e04c3fSmrg      gl_version = state->gl_version;
85801e04c3fSmrg
85901e04c3fSmrg   if (strcmp(name, "all") == 0) {
86001e04c3fSmrg      if ((behavior == extension_enable) || (behavior == extension_require)) {
86101e04c3fSmrg	 _mesa_glsl_error(name_locp, state, "cannot %s all extensions",
86201e04c3fSmrg			  (behavior == extension_enable)
86301e04c3fSmrg			  ? "enable" : "require");
86401e04c3fSmrg	 return false;
86501e04c3fSmrg      } else {
86601e04c3fSmrg         for (unsigned i = 0;
86701e04c3fSmrg              i < ARRAY_SIZE(_mesa_glsl_supported_extensions); ++i) {
86801e04c3fSmrg            const _mesa_glsl_extension *extension
86901e04c3fSmrg               = &_mesa_glsl_supported_extensions[i];
87001e04c3fSmrg            if (extension->compatible_with_state(state, api, gl_version)) {
87101e04c3fSmrg               _mesa_glsl_supported_extensions[i].set_flags(state, behavior);
87201e04c3fSmrg            }
87301e04c3fSmrg         }
87401e04c3fSmrg      }
87501e04c3fSmrg   } else {
87601e04c3fSmrg      const _mesa_glsl_extension *extension = find_extension(name);
87701e04c3fSmrg      if (extension && extension->compatible_with_state(state, api, gl_version)) {
87801e04c3fSmrg         extension->set_flags(state, behavior);
87901e04c3fSmrg         if (extension->available_pred == has_ANDROID_extension_pack_es31a) {
88001e04c3fSmrg            for (unsigned i = 0;
88101e04c3fSmrg                 i < ARRAY_SIZE(_mesa_glsl_supported_extensions); ++i) {
88201e04c3fSmrg               const _mesa_glsl_extension *extension =
88301e04c3fSmrg                  &_mesa_glsl_supported_extensions[i];
88401e04c3fSmrg
88501e04c3fSmrg               if (!extension->aep)
88601e04c3fSmrg                  continue;
88701e04c3fSmrg               /* AEP should not be enabled if all of the sub-extensions can't
88801e04c3fSmrg                * also be enabled. This is not the proper layer to do such
88901e04c3fSmrg                * error-checking though.
89001e04c3fSmrg                */
89101e04c3fSmrg               assert(extension->compatible_with_state(state, api, gl_version));
89201e04c3fSmrg               extension->set_flags(state, behavior);
89301e04c3fSmrg            }
89401e04c3fSmrg         }
89501e04c3fSmrg      } else {
89601e04c3fSmrg         static const char fmt[] = "extension `%s' unsupported in %s shader";
89701e04c3fSmrg
89801e04c3fSmrg         if (behavior == extension_require) {
89901e04c3fSmrg            _mesa_glsl_error(name_locp, state, fmt,
90001e04c3fSmrg                             name, _mesa_shader_stage_to_string(state->stage));
90101e04c3fSmrg            return false;
90201e04c3fSmrg         } else {
90301e04c3fSmrg            _mesa_glsl_warning(name_locp, state, fmt,
90401e04c3fSmrg                               name, _mesa_shader_stage_to_string(state->stage));
90501e04c3fSmrg         }
90601e04c3fSmrg      }
90701e04c3fSmrg   }
90801e04c3fSmrg
90901e04c3fSmrg   return true;
91001e04c3fSmrg}
91101e04c3fSmrg
91201e04c3fSmrg
91301e04c3fSmrg/**
91401e04c3fSmrg * Recurses through <type> and <expr> if <expr> is an aggregate initializer
91501e04c3fSmrg * and sets <expr>'s <constructor_type> field to <type>. Gives later functions
91601e04c3fSmrg * (process_array_constructor, et al) sufficient information to do type
91701e04c3fSmrg * checking.
91801e04c3fSmrg *
91901e04c3fSmrg * Operates on assignments involving an aggregate initializer. E.g.,
92001e04c3fSmrg *
92101e04c3fSmrg * vec4 pos = {1.0, -1.0, 0.0, 1.0};
92201e04c3fSmrg *
92301e04c3fSmrg * or more ridiculously,
92401e04c3fSmrg *
92501e04c3fSmrg * struct S {
92601e04c3fSmrg *     vec4 v[2];
92701e04c3fSmrg * };
92801e04c3fSmrg *
92901e04c3fSmrg * struct {
93001e04c3fSmrg *     S a[2], b;
93101e04c3fSmrg *     int c;
93201e04c3fSmrg * } aggregate = {
93301e04c3fSmrg *     {
93401e04c3fSmrg *         {
93501e04c3fSmrg *             {
93601e04c3fSmrg *                 {1.0, 2.0, 3.0, 4.0}, // a[0].v[0]
93701e04c3fSmrg *                 {5.0, 6.0, 7.0, 8.0}  // a[0].v[1]
93801e04c3fSmrg *             } // a[0].v
93901e04c3fSmrg *         }, // a[0]
94001e04c3fSmrg *         {
94101e04c3fSmrg *             {
94201e04c3fSmrg *                 {1.0, 2.0, 3.0, 4.0}, // a[1].v[0]
94301e04c3fSmrg *                 {5.0, 6.0, 7.0, 8.0}  // a[1].v[1]
94401e04c3fSmrg *             } // a[1].v
94501e04c3fSmrg *         } // a[1]
94601e04c3fSmrg *     }, // a
94701e04c3fSmrg *     {
94801e04c3fSmrg *         {
94901e04c3fSmrg *             {1.0, 2.0, 3.0, 4.0}, // b.v[0]
95001e04c3fSmrg *             {5.0, 6.0, 7.0, 8.0}  // b.v[1]
95101e04c3fSmrg *         } // b.v
95201e04c3fSmrg *     }, // b
95301e04c3fSmrg *     4 // c
95401e04c3fSmrg * };
95501e04c3fSmrg *
95601e04c3fSmrg * This pass is necessary because the right-hand side of <type> e = { ... }
95701e04c3fSmrg * doesn't contain sufficient information to determine if the types match.
95801e04c3fSmrg */
95901e04c3fSmrgvoid
96001e04c3fSmrg_mesa_ast_set_aggregate_type(const glsl_type *type,
96101e04c3fSmrg                             ast_expression *expr)
96201e04c3fSmrg{
96301e04c3fSmrg   ast_aggregate_initializer *ai = (ast_aggregate_initializer *)expr;
96401e04c3fSmrg   ai->constructor_type = type;
96501e04c3fSmrg
96601e04c3fSmrg   /* If the aggregate is an array, recursively set its elements' types. */
96701e04c3fSmrg   if (type->is_array()) {
96801e04c3fSmrg      /* Each array element has the type type->fields.array.
96901e04c3fSmrg       *
97001e04c3fSmrg       * E.g., if <type> if struct S[2] we want to set each element's type to
97101e04c3fSmrg       * struct S.
97201e04c3fSmrg       */
97301e04c3fSmrg      for (exec_node *expr_node = ai->expressions.get_head_raw();
97401e04c3fSmrg           !expr_node->is_tail_sentinel();
97501e04c3fSmrg           expr_node = expr_node->next) {
97601e04c3fSmrg         ast_expression *expr = exec_node_data(ast_expression, expr_node,
97701e04c3fSmrg                                               link);
97801e04c3fSmrg
97901e04c3fSmrg         if (expr->oper == ast_aggregate)
98001e04c3fSmrg            _mesa_ast_set_aggregate_type(type->fields.array, expr);
98101e04c3fSmrg      }
98201e04c3fSmrg
98301e04c3fSmrg   /* If the aggregate is a struct, recursively set its fields' types. */
984d8407755Smaya   } else if (type->is_struct()) {
98501e04c3fSmrg      exec_node *expr_node = ai->expressions.get_head_raw();
98601e04c3fSmrg
98701e04c3fSmrg      /* Iterate through the struct's fields. */
98801e04c3fSmrg      for (unsigned i = 0; !expr_node->is_tail_sentinel() && i < type->length;
98901e04c3fSmrg           i++, expr_node = expr_node->next) {
99001e04c3fSmrg         ast_expression *expr = exec_node_data(ast_expression, expr_node,
99101e04c3fSmrg                                               link);
99201e04c3fSmrg
99301e04c3fSmrg         if (expr->oper == ast_aggregate) {
99401e04c3fSmrg            _mesa_ast_set_aggregate_type(type->fields.structure[i].type, expr);
99501e04c3fSmrg         }
99601e04c3fSmrg      }
99701e04c3fSmrg   /* If the aggregate is a matrix, set its columns' types. */
99801e04c3fSmrg   } else if (type->is_matrix()) {
99901e04c3fSmrg      for (exec_node *expr_node = ai->expressions.get_head_raw();
100001e04c3fSmrg           !expr_node->is_tail_sentinel();
100101e04c3fSmrg           expr_node = expr_node->next) {
100201e04c3fSmrg         ast_expression *expr = exec_node_data(ast_expression, expr_node,
100301e04c3fSmrg                                               link);
100401e04c3fSmrg
100501e04c3fSmrg         if (expr->oper == ast_aggregate)
100601e04c3fSmrg            _mesa_ast_set_aggregate_type(type->column_type(), expr);
100701e04c3fSmrg      }
100801e04c3fSmrg   }
100901e04c3fSmrg}
101001e04c3fSmrg
101101e04c3fSmrgvoid
101201e04c3fSmrg_mesa_ast_process_interface_block(YYLTYPE *locp,
101301e04c3fSmrg                                  _mesa_glsl_parse_state *state,
101401e04c3fSmrg                                  ast_interface_block *const block,
101501e04c3fSmrg                                  const struct ast_type_qualifier &q)
101601e04c3fSmrg{
101701e04c3fSmrg   if (q.flags.q.buffer) {
101801e04c3fSmrg      if (!state->has_shader_storage_buffer_objects()) {
101901e04c3fSmrg         _mesa_glsl_error(locp, state,
102001e04c3fSmrg                          "#version 430 / GL_ARB_shader_storage_buffer_object "
102101e04c3fSmrg                          "required for defining shader storage blocks");
102201e04c3fSmrg      } else if (state->ARB_shader_storage_buffer_object_warn) {
102301e04c3fSmrg         _mesa_glsl_warning(locp, state,
102401e04c3fSmrg                            "#version 430 / GL_ARB_shader_storage_buffer_object "
102501e04c3fSmrg                            "required for defining shader storage blocks");
102601e04c3fSmrg      }
102701e04c3fSmrg   } else if (q.flags.q.uniform) {
102801e04c3fSmrg      if (!state->has_uniform_buffer_objects()) {
102901e04c3fSmrg         _mesa_glsl_error(locp, state,
103001e04c3fSmrg                          "#version 140 / GL_ARB_uniform_buffer_object "
103101e04c3fSmrg                          "required for defining uniform blocks");
103201e04c3fSmrg      } else if (state->ARB_uniform_buffer_object_warn) {
103301e04c3fSmrg         _mesa_glsl_warning(locp, state,
103401e04c3fSmrg                            "#version 140 / GL_ARB_uniform_buffer_object "
103501e04c3fSmrg                            "required for defining uniform blocks");
103601e04c3fSmrg      }
103701e04c3fSmrg   } else {
103801e04c3fSmrg      if (!state->has_shader_io_blocks()) {
103901e04c3fSmrg         if (state->es_shader) {
104001e04c3fSmrg            _mesa_glsl_error(locp, state,
104101e04c3fSmrg                             "GL_OES_shader_io_blocks or #version 320 "
104201e04c3fSmrg                             "required for using interface blocks");
104301e04c3fSmrg         } else {
104401e04c3fSmrg            _mesa_glsl_error(locp, state,
104501e04c3fSmrg                             "#version 150 required for using "
104601e04c3fSmrg                             "interface blocks");
104701e04c3fSmrg         }
104801e04c3fSmrg      }
104901e04c3fSmrg   }
105001e04c3fSmrg
105101e04c3fSmrg   /* From the GLSL 1.50.11 spec, section 4.3.7 ("Interface Blocks"):
105201e04c3fSmrg    * "It is illegal to have an input block in a vertex shader
105301e04c3fSmrg    *  or an output block in a fragment shader"
105401e04c3fSmrg    */
105501e04c3fSmrg   if ((state->stage == MESA_SHADER_VERTEX) && q.flags.q.in) {
105601e04c3fSmrg      _mesa_glsl_error(locp, state,
105701e04c3fSmrg                       "`in' interface block is not allowed for "
105801e04c3fSmrg                       "a vertex shader");
105901e04c3fSmrg   } else if ((state->stage == MESA_SHADER_FRAGMENT) && q.flags.q.out) {
106001e04c3fSmrg      _mesa_glsl_error(locp, state,
106101e04c3fSmrg                       "`out' interface block is not allowed for "
106201e04c3fSmrg                       "a fragment shader");
106301e04c3fSmrg   }
106401e04c3fSmrg
106501e04c3fSmrg   /* Since block arrays require names, and both features are added in
106601e04c3fSmrg    * the same language versions, we don't have to explicitly
106701e04c3fSmrg    * version-check both things.
106801e04c3fSmrg    */
106901e04c3fSmrg   if (block->instance_name != NULL) {
107001e04c3fSmrg      state->check_version(150, 300, locp, "interface blocks with "
107101e04c3fSmrg                           "an instance name are not allowed");
107201e04c3fSmrg   }
107301e04c3fSmrg
107401e04c3fSmrg   ast_type_qualifier::bitset_t interface_type_mask;
107501e04c3fSmrg   struct ast_type_qualifier temp_type_qualifier;
107601e04c3fSmrg
107701e04c3fSmrg   /* Get a bitmask containing only the in/out/uniform/buffer
107801e04c3fSmrg    * flags, allowing us to ignore other irrelevant flags like
107901e04c3fSmrg    * interpolation qualifiers.
108001e04c3fSmrg    */
108101e04c3fSmrg   temp_type_qualifier.flags.i = 0;
108201e04c3fSmrg   temp_type_qualifier.flags.q.uniform = true;
108301e04c3fSmrg   temp_type_qualifier.flags.q.in = true;
108401e04c3fSmrg   temp_type_qualifier.flags.q.out = true;
108501e04c3fSmrg   temp_type_qualifier.flags.q.buffer = true;
108601e04c3fSmrg   temp_type_qualifier.flags.q.patch = true;
108701e04c3fSmrg   interface_type_mask = temp_type_qualifier.flags.i;
108801e04c3fSmrg
108901e04c3fSmrg   /* Get the block's interface qualifier.  The interface_qualifier
109001e04c3fSmrg    * production rule guarantees that only one bit will be set (and
109101e04c3fSmrg    * it will be in/out/uniform).
109201e04c3fSmrg    */
109301e04c3fSmrg   ast_type_qualifier::bitset_t block_interface_qualifier = q.flags.i;
109401e04c3fSmrg
109501e04c3fSmrg   block->default_layout.flags.i |= block_interface_qualifier;
109601e04c3fSmrg
109701e04c3fSmrg   if (state->stage == MESA_SHADER_GEOMETRY &&
109801e04c3fSmrg       state->has_explicit_attrib_stream() &&
109901e04c3fSmrg       block->default_layout.flags.q.out) {
110001e04c3fSmrg      /* Assign global layout's stream value. */
110101e04c3fSmrg      block->default_layout.flags.q.stream = 1;
110201e04c3fSmrg      block->default_layout.flags.q.explicit_stream = 0;
110301e04c3fSmrg      block->default_layout.stream = state->out_qualifier->stream;
110401e04c3fSmrg   }
110501e04c3fSmrg
110601e04c3fSmrg   if (state->has_enhanced_layouts() && block->default_layout.flags.q.out) {
110701e04c3fSmrg      /* Assign global layout's xfb_buffer value. */
110801e04c3fSmrg      block->default_layout.flags.q.xfb_buffer = 1;
110901e04c3fSmrg      block->default_layout.flags.q.explicit_xfb_buffer = 0;
111001e04c3fSmrg      block->default_layout.xfb_buffer = state->out_qualifier->xfb_buffer;
111101e04c3fSmrg   }
111201e04c3fSmrg
111301e04c3fSmrg   foreach_list_typed (ast_declarator_list, member, link, &block->declarations) {
111401e04c3fSmrg      ast_type_qualifier& qualifier = member->type->qualifier;
111501e04c3fSmrg      if ((qualifier.flags.i & interface_type_mask) == 0) {
111601e04c3fSmrg         /* GLSLangSpec.1.50.11, 4.3.7 (Interface Blocks):
111701e04c3fSmrg          * "If no optional qualifier is used in a member declaration, the
111801e04c3fSmrg          *  qualifier of the variable is just in, out, or uniform as declared
111901e04c3fSmrg          *  by interface-qualifier."
112001e04c3fSmrg          */
112101e04c3fSmrg         qualifier.flags.i |= block_interface_qualifier;
112201e04c3fSmrg      } else if ((qualifier.flags.i & interface_type_mask) !=
112301e04c3fSmrg                 block_interface_qualifier) {
112401e04c3fSmrg         /* GLSLangSpec.1.50.11, 4.3.7 (Interface Blocks):
112501e04c3fSmrg          * "If optional qualifiers are used, they can include interpolation
112601e04c3fSmrg          *  and storage qualifiers and they must declare an input, output,
112701e04c3fSmrg          *  or uniform variable consistent with the interface qualifier of
112801e04c3fSmrg          *  the block."
112901e04c3fSmrg          */
113001e04c3fSmrg         _mesa_glsl_error(locp, state,
113101e04c3fSmrg                          "uniform/in/out qualifier on "
113201e04c3fSmrg                          "interface block member does not match "
113301e04c3fSmrg                          "the interface block");
113401e04c3fSmrg      }
113501e04c3fSmrg
113601e04c3fSmrg      if (!(q.flags.q.in || q.flags.q.out) && qualifier.flags.q.invariant)
113701e04c3fSmrg         _mesa_glsl_error(locp, state,
113801e04c3fSmrg                          "invariant qualifiers can be used only "
113901e04c3fSmrg                          "in interface block members for shader "
114001e04c3fSmrg                          "inputs or outputs");
114101e04c3fSmrg   }
114201e04c3fSmrg}
114301e04c3fSmrg
114401e04c3fSmrgstatic void
114501e04c3fSmrg_mesa_ast_type_qualifier_print(const struct ast_type_qualifier *q)
114601e04c3fSmrg{
114701e04c3fSmrg   if (q->is_subroutine_decl())
114801e04c3fSmrg      printf("subroutine ");
114901e04c3fSmrg
115001e04c3fSmrg   if (q->subroutine_list) {
115101e04c3fSmrg      printf("subroutine (");
115201e04c3fSmrg      q->subroutine_list->print();
115301e04c3fSmrg      printf(")");
115401e04c3fSmrg   }
115501e04c3fSmrg
115601e04c3fSmrg   if (q->flags.q.constant)
115701e04c3fSmrg      printf("const ");
115801e04c3fSmrg
115901e04c3fSmrg   if (q->flags.q.invariant)
116001e04c3fSmrg      printf("invariant ");
116101e04c3fSmrg
116201e04c3fSmrg   if (q->flags.q.attribute)
116301e04c3fSmrg      printf("attribute ");
116401e04c3fSmrg
116501e04c3fSmrg   if (q->flags.q.varying)
116601e04c3fSmrg      printf("varying ");
116701e04c3fSmrg
116801e04c3fSmrg   if (q->flags.q.in && q->flags.q.out)
116901e04c3fSmrg      printf("inout ");
117001e04c3fSmrg   else {
117101e04c3fSmrg      if (q->flags.q.in)
117201e04c3fSmrg	 printf("in ");
117301e04c3fSmrg
117401e04c3fSmrg      if (q->flags.q.out)
117501e04c3fSmrg	 printf("out ");
117601e04c3fSmrg   }
117701e04c3fSmrg
117801e04c3fSmrg   if (q->flags.q.centroid)
117901e04c3fSmrg      printf("centroid ");
118001e04c3fSmrg   if (q->flags.q.sample)
118101e04c3fSmrg      printf("sample ");
118201e04c3fSmrg   if (q->flags.q.patch)
118301e04c3fSmrg      printf("patch ");
118401e04c3fSmrg   if (q->flags.q.uniform)
118501e04c3fSmrg      printf("uniform ");
118601e04c3fSmrg   if (q->flags.q.buffer)
118701e04c3fSmrg      printf("buffer ");
118801e04c3fSmrg   if (q->flags.q.smooth)
118901e04c3fSmrg      printf("smooth ");
119001e04c3fSmrg   if (q->flags.q.flat)
119101e04c3fSmrg      printf("flat ");
119201e04c3fSmrg   if (q->flags.q.noperspective)
119301e04c3fSmrg      printf("noperspective ");
119401e04c3fSmrg}
119501e04c3fSmrg
119601e04c3fSmrg
119701e04c3fSmrgvoid
119801e04c3fSmrgast_node::print(void) const
119901e04c3fSmrg{
120001e04c3fSmrg   printf("unhandled node ");
120101e04c3fSmrg}
120201e04c3fSmrg
120301e04c3fSmrg
120401e04c3fSmrgast_node::ast_node(void)
120501e04c3fSmrg{
12061463c08dSmrg   this->location.path = NULL;
120701e04c3fSmrg   this->location.source = 0;
120801e04c3fSmrg   this->location.first_line = 0;
120901e04c3fSmrg   this->location.first_column = 0;
121001e04c3fSmrg   this->location.last_line = 0;
121101e04c3fSmrg   this->location.last_column = 0;
121201e04c3fSmrg}
121301e04c3fSmrg
121401e04c3fSmrg
121501e04c3fSmrgstatic void
121601e04c3fSmrgast_opt_array_dimensions_print(const ast_array_specifier *array_specifier)
121701e04c3fSmrg{
121801e04c3fSmrg   if (array_specifier)
121901e04c3fSmrg      array_specifier->print();
122001e04c3fSmrg}
122101e04c3fSmrg
122201e04c3fSmrg
122301e04c3fSmrgvoid
122401e04c3fSmrgast_compound_statement::print(void) const
122501e04c3fSmrg{
122601e04c3fSmrg   printf("{\n");
122701e04c3fSmrg
122801e04c3fSmrg   foreach_list_typed(ast_node, ast, link, &this->statements) {
122901e04c3fSmrg      ast->print();
123001e04c3fSmrg   }
123101e04c3fSmrg
123201e04c3fSmrg   printf("}\n");
123301e04c3fSmrg}
123401e04c3fSmrg
123501e04c3fSmrg
123601e04c3fSmrgast_compound_statement::ast_compound_statement(int new_scope,
123701e04c3fSmrg					       ast_node *statements)
123801e04c3fSmrg{
123901e04c3fSmrg   this->new_scope = new_scope;
124001e04c3fSmrg
124101e04c3fSmrg   if (statements != NULL) {
124201e04c3fSmrg      this->statements.push_degenerate_list_at_head(&statements->link);
124301e04c3fSmrg   }
124401e04c3fSmrg}
124501e04c3fSmrg
124601e04c3fSmrg
124701e04c3fSmrgvoid
124801e04c3fSmrgast_expression::print(void) const
124901e04c3fSmrg{
125001e04c3fSmrg   switch (oper) {
125101e04c3fSmrg   case ast_assign:
125201e04c3fSmrg   case ast_mul_assign:
125301e04c3fSmrg   case ast_div_assign:
125401e04c3fSmrg   case ast_mod_assign:
125501e04c3fSmrg   case ast_add_assign:
125601e04c3fSmrg   case ast_sub_assign:
125701e04c3fSmrg   case ast_ls_assign:
125801e04c3fSmrg   case ast_rs_assign:
125901e04c3fSmrg   case ast_and_assign:
126001e04c3fSmrg   case ast_xor_assign:
126101e04c3fSmrg   case ast_or_assign:
126201e04c3fSmrg      subexpressions[0]->print();
126301e04c3fSmrg      printf("%s ", operator_string(oper));
126401e04c3fSmrg      subexpressions[1]->print();
126501e04c3fSmrg      break;
126601e04c3fSmrg
126701e04c3fSmrg   case ast_field_selection:
126801e04c3fSmrg      subexpressions[0]->print();
126901e04c3fSmrg      printf(". %s ", primary_expression.identifier);
127001e04c3fSmrg      break;
127101e04c3fSmrg
127201e04c3fSmrg   case ast_plus:
127301e04c3fSmrg   case ast_neg:
127401e04c3fSmrg   case ast_bit_not:
127501e04c3fSmrg   case ast_logic_not:
127601e04c3fSmrg   case ast_pre_inc:
127701e04c3fSmrg   case ast_pre_dec:
127801e04c3fSmrg      printf("%s ", operator_string(oper));
127901e04c3fSmrg      subexpressions[0]->print();
128001e04c3fSmrg      break;
128101e04c3fSmrg
128201e04c3fSmrg   case ast_post_inc:
128301e04c3fSmrg   case ast_post_dec:
128401e04c3fSmrg      subexpressions[0]->print();
128501e04c3fSmrg      printf("%s ", operator_string(oper));
128601e04c3fSmrg      break;
128701e04c3fSmrg
128801e04c3fSmrg   case ast_conditional:
128901e04c3fSmrg      subexpressions[0]->print();
129001e04c3fSmrg      printf("? ");
129101e04c3fSmrg      subexpressions[1]->print();
129201e04c3fSmrg      printf(": ");
129301e04c3fSmrg      subexpressions[2]->print();
129401e04c3fSmrg      break;
129501e04c3fSmrg
129601e04c3fSmrg   case ast_array_index:
129701e04c3fSmrg      subexpressions[0]->print();
129801e04c3fSmrg      printf("[ ");
129901e04c3fSmrg      subexpressions[1]->print();
130001e04c3fSmrg      printf("] ");
130101e04c3fSmrg      break;
130201e04c3fSmrg
130301e04c3fSmrg   case ast_function_call: {
130401e04c3fSmrg      subexpressions[0]->print();
130501e04c3fSmrg      printf("( ");
130601e04c3fSmrg
130701e04c3fSmrg      foreach_list_typed (ast_node, ast, link, &this->expressions) {
130801e04c3fSmrg	 if (&ast->link != this->expressions.get_head())
130901e04c3fSmrg	    printf(", ");
131001e04c3fSmrg
131101e04c3fSmrg	 ast->print();
131201e04c3fSmrg      }
131301e04c3fSmrg
131401e04c3fSmrg      printf(") ");
131501e04c3fSmrg      break;
131601e04c3fSmrg   }
131701e04c3fSmrg
131801e04c3fSmrg   case ast_identifier:
131901e04c3fSmrg      printf("%s ", primary_expression.identifier);
132001e04c3fSmrg      break;
132101e04c3fSmrg
132201e04c3fSmrg   case ast_int_constant:
132301e04c3fSmrg      printf("%d ", primary_expression.int_constant);
132401e04c3fSmrg      break;
132501e04c3fSmrg
132601e04c3fSmrg   case ast_uint_constant:
132701e04c3fSmrg      printf("%u ", primary_expression.uint_constant);
132801e04c3fSmrg      break;
132901e04c3fSmrg
133001e04c3fSmrg   case ast_float_constant:
133101e04c3fSmrg      printf("%f ", primary_expression.float_constant);
133201e04c3fSmrg      break;
133301e04c3fSmrg
133401e04c3fSmrg   case ast_double_constant:
133501e04c3fSmrg      printf("%f ", primary_expression.double_constant);
133601e04c3fSmrg      break;
133701e04c3fSmrg
133801e04c3fSmrg   case ast_int64_constant:
133901e04c3fSmrg      printf("%" PRId64 " ", primary_expression.int64_constant);
134001e04c3fSmrg      break;
134101e04c3fSmrg
134201e04c3fSmrg   case ast_uint64_constant:
134301e04c3fSmrg      printf("%" PRIu64 " ", primary_expression.uint64_constant);
134401e04c3fSmrg      break;
134501e04c3fSmrg
134601e04c3fSmrg   case ast_bool_constant:
134701e04c3fSmrg      printf("%s ",
134801e04c3fSmrg	     primary_expression.bool_constant
134901e04c3fSmrg	     ? "true" : "false");
135001e04c3fSmrg      break;
135101e04c3fSmrg
135201e04c3fSmrg   case ast_sequence: {
135301e04c3fSmrg      printf("( ");
135401e04c3fSmrg      foreach_list_typed (ast_node, ast, link, & this->expressions) {
135501e04c3fSmrg	 if (&ast->link != this->expressions.get_head())
135601e04c3fSmrg	    printf(", ");
135701e04c3fSmrg
135801e04c3fSmrg	 ast->print();
135901e04c3fSmrg      }
136001e04c3fSmrg      printf(") ");
136101e04c3fSmrg      break;
136201e04c3fSmrg   }
136301e04c3fSmrg
136401e04c3fSmrg   case ast_aggregate: {
136501e04c3fSmrg      printf("{ ");
136601e04c3fSmrg      foreach_list_typed (ast_node, ast, link, & this->expressions) {
136701e04c3fSmrg	 if (&ast->link != this->expressions.get_head())
136801e04c3fSmrg	    printf(", ");
136901e04c3fSmrg
137001e04c3fSmrg	 ast->print();
137101e04c3fSmrg      }
137201e04c3fSmrg      printf("} ");
137301e04c3fSmrg      break;
137401e04c3fSmrg   }
137501e04c3fSmrg
137601e04c3fSmrg   default:
137701e04c3fSmrg      assert(0);
137801e04c3fSmrg      break;
137901e04c3fSmrg   }
138001e04c3fSmrg}
138101e04c3fSmrg
138201e04c3fSmrgast_expression::ast_expression(int oper,
138301e04c3fSmrg			       ast_expression *ex0,
138401e04c3fSmrg			       ast_expression *ex1,
138501e04c3fSmrg			       ast_expression *ex2) :
138601e04c3fSmrg   primary_expression()
138701e04c3fSmrg{
138801e04c3fSmrg   this->oper = ast_operators(oper);
138901e04c3fSmrg   this->subexpressions[0] = ex0;
139001e04c3fSmrg   this->subexpressions[1] = ex1;
139101e04c3fSmrg   this->subexpressions[2] = ex2;
139201e04c3fSmrg   this->non_lvalue_description = NULL;
139301e04c3fSmrg   this->is_lhs = false;
139401e04c3fSmrg}
139501e04c3fSmrg
139601e04c3fSmrg
139701e04c3fSmrgvoid
139801e04c3fSmrgast_expression_statement::print(void) const
139901e04c3fSmrg{
140001e04c3fSmrg   if (expression)
140101e04c3fSmrg      expression->print();
140201e04c3fSmrg
140301e04c3fSmrg   printf("; ");
140401e04c3fSmrg}
140501e04c3fSmrg
140601e04c3fSmrg
140701e04c3fSmrgast_expression_statement::ast_expression_statement(ast_expression *ex) :
140801e04c3fSmrg   expression(ex)
140901e04c3fSmrg{
141001e04c3fSmrg   /* empty */
141101e04c3fSmrg}
141201e04c3fSmrg
141301e04c3fSmrg
141401e04c3fSmrgvoid
141501e04c3fSmrgast_function::print(void) const
141601e04c3fSmrg{
141701e04c3fSmrg   return_type->print();
141801e04c3fSmrg   printf(" %s (", identifier);
141901e04c3fSmrg
142001e04c3fSmrg   foreach_list_typed(ast_node, ast, link, & this->parameters) {
142101e04c3fSmrg      ast->print();
142201e04c3fSmrg   }
142301e04c3fSmrg
142401e04c3fSmrg   printf(")");
142501e04c3fSmrg}
142601e04c3fSmrg
142701e04c3fSmrg
142801e04c3fSmrgast_function::ast_function(void)
142901e04c3fSmrg   : return_type(NULL), identifier(NULL), is_definition(false),
143001e04c3fSmrg     signature(NULL)
143101e04c3fSmrg{
143201e04c3fSmrg   /* empty */
143301e04c3fSmrg}
143401e04c3fSmrg
143501e04c3fSmrg
143601e04c3fSmrgvoid
143701e04c3fSmrgast_fully_specified_type::print(void) const
143801e04c3fSmrg{
143901e04c3fSmrg   _mesa_ast_type_qualifier_print(& qualifier);
144001e04c3fSmrg   specifier->print();
144101e04c3fSmrg}
144201e04c3fSmrg
144301e04c3fSmrg
144401e04c3fSmrgvoid
144501e04c3fSmrgast_parameter_declarator::print(void) const
144601e04c3fSmrg{
144701e04c3fSmrg   type->print();
144801e04c3fSmrg   if (identifier)
144901e04c3fSmrg      printf("%s ", identifier);
145001e04c3fSmrg   ast_opt_array_dimensions_print(array_specifier);
145101e04c3fSmrg}
145201e04c3fSmrg
145301e04c3fSmrg
145401e04c3fSmrgvoid
145501e04c3fSmrgast_function_definition::print(void) const
145601e04c3fSmrg{
145701e04c3fSmrg   prototype->print();
145801e04c3fSmrg   body->print();
145901e04c3fSmrg}
146001e04c3fSmrg
146101e04c3fSmrg
146201e04c3fSmrgvoid
146301e04c3fSmrgast_declaration::print(void) const
146401e04c3fSmrg{
146501e04c3fSmrg   printf("%s ", identifier);
146601e04c3fSmrg   ast_opt_array_dimensions_print(array_specifier);
146701e04c3fSmrg
146801e04c3fSmrg   if (initializer) {
146901e04c3fSmrg      printf("= ");
147001e04c3fSmrg      initializer->print();
147101e04c3fSmrg   }
147201e04c3fSmrg}
147301e04c3fSmrg
147401e04c3fSmrg
147501e04c3fSmrgast_declaration::ast_declaration(const char *identifier,
147601e04c3fSmrg				 ast_array_specifier *array_specifier,
147701e04c3fSmrg				 ast_expression *initializer)
147801e04c3fSmrg{
147901e04c3fSmrg   this->identifier = identifier;
148001e04c3fSmrg   this->array_specifier = array_specifier;
148101e04c3fSmrg   this->initializer = initializer;
148201e04c3fSmrg}
148301e04c3fSmrg
148401e04c3fSmrg
148501e04c3fSmrgvoid
148601e04c3fSmrgast_declarator_list::print(void) const
148701e04c3fSmrg{
148801e04c3fSmrg   assert(type || invariant);
148901e04c3fSmrg
149001e04c3fSmrg   if (type)
149101e04c3fSmrg      type->print();
149201e04c3fSmrg   else if (invariant)
149301e04c3fSmrg      printf("invariant ");
149401e04c3fSmrg   else
149501e04c3fSmrg      printf("precise ");
149601e04c3fSmrg
149701e04c3fSmrg   foreach_list_typed (ast_node, ast, link, & this->declarations) {
149801e04c3fSmrg      if (&ast->link != this->declarations.get_head())
149901e04c3fSmrg	 printf(", ");
150001e04c3fSmrg
150101e04c3fSmrg      ast->print();
150201e04c3fSmrg   }
150301e04c3fSmrg
150401e04c3fSmrg   printf("; ");
150501e04c3fSmrg}
150601e04c3fSmrg
150701e04c3fSmrg
150801e04c3fSmrgast_declarator_list::ast_declarator_list(ast_fully_specified_type *type)
150901e04c3fSmrg{
151001e04c3fSmrg   this->type = type;
151101e04c3fSmrg   this->invariant = false;
151201e04c3fSmrg   this->precise = false;
151301e04c3fSmrg}
151401e04c3fSmrg
151501e04c3fSmrgvoid
151601e04c3fSmrgast_jump_statement::print(void) const
151701e04c3fSmrg{
151801e04c3fSmrg   switch (mode) {
151901e04c3fSmrg   case ast_continue:
152001e04c3fSmrg      printf("continue; ");
152101e04c3fSmrg      break;
152201e04c3fSmrg   case ast_break:
152301e04c3fSmrg      printf("break; ");
152401e04c3fSmrg      break;
152501e04c3fSmrg   case ast_return:
152601e04c3fSmrg      printf("return ");
152701e04c3fSmrg      if (opt_return_value)
152801e04c3fSmrg	 opt_return_value->print();
152901e04c3fSmrg
153001e04c3fSmrg      printf("; ");
153101e04c3fSmrg      break;
153201e04c3fSmrg   case ast_discard:
153301e04c3fSmrg      printf("discard; ");
153401e04c3fSmrg      break;
153501e04c3fSmrg   }
153601e04c3fSmrg}
153701e04c3fSmrg
153801e04c3fSmrg
153901e04c3fSmrgast_jump_statement::ast_jump_statement(int mode, ast_expression *return_value)
154001e04c3fSmrg   : opt_return_value(NULL)
154101e04c3fSmrg{
154201e04c3fSmrg   this->mode = ast_jump_modes(mode);
154301e04c3fSmrg
154401e04c3fSmrg   if (mode == ast_return)
154501e04c3fSmrg      opt_return_value = return_value;
154601e04c3fSmrg}
154701e04c3fSmrg
154801e04c3fSmrg
15491463c08dSmrgvoid
15501463c08dSmrgast_demote_statement::print(void) const
15511463c08dSmrg{
15521463c08dSmrg   printf("demote; ");
15531463c08dSmrg}
15541463c08dSmrg
15551463c08dSmrg
155601e04c3fSmrgvoid
155701e04c3fSmrgast_selection_statement::print(void) const
155801e04c3fSmrg{
155901e04c3fSmrg   printf("if ( ");
156001e04c3fSmrg   condition->print();
156101e04c3fSmrg   printf(") ");
156201e04c3fSmrg
156301e04c3fSmrg   then_statement->print();
156401e04c3fSmrg
156501e04c3fSmrg   if (else_statement) {
156601e04c3fSmrg      printf("else ");
156701e04c3fSmrg      else_statement->print();
156801e04c3fSmrg   }
156901e04c3fSmrg}
157001e04c3fSmrg
157101e04c3fSmrg
157201e04c3fSmrgast_selection_statement::ast_selection_statement(ast_expression *condition,
157301e04c3fSmrg						 ast_node *then_statement,
157401e04c3fSmrg						 ast_node *else_statement)
157501e04c3fSmrg{
157601e04c3fSmrg   this->condition = condition;
157701e04c3fSmrg   this->then_statement = then_statement;
157801e04c3fSmrg   this->else_statement = else_statement;
157901e04c3fSmrg}
158001e04c3fSmrg
158101e04c3fSmrg
158201e04c3fSmrgvoid
158301e04c3fSmrgast_switch_statement::print(void) const
158401e04c3fSmrg{
158501e04c3fSmrg   printf("switch ( ");
158601e04c3fSmrg   test_expression->print();
158701e04c3fSmrg   printf(") ");
158801e04c3fSmrg
158901e04c3fSmrg   body->print();
159001e04c3fSmrg}
159101e04c3fSmrg
159201e04c3fSmrg
159301e04c3fSmrgast_switch_statement::ast_switch_statement(ast_expression *test_expression,
159401e04c3fSmrg					   ast_node *body)
159501e04c3fSmrg{
159601e04c3fSmrg   this->test_expression = test_expression;
159701e04c3fSmrg   this->body = body;
15981463c08dSmrg   this->test_val = NULL;
159901e04c3fSmrg}
160001e04c3fSmrg
160101e04c3fSmrg
160201e04c3fSmrgvoid
160301e04c3fSmrgast_switch_body::print(void) const
160401e04c3fSmrg{
160501e04c3fSmrg   printf("{\n");
160601e04c3fSmrg   if (stmts != NULL) {
160701e04c3fSmrg      stmts->print();
160801e04c3fSmrg   }
160901e04c3fSmrg   printf("}\n");
161001e04c3fSmrg}
161101e04c3fSmrg
161201e04c3fSmrg
161301e04c3fSmrgast_switch_body::ast_switch_body(ast_case_statement_list *stmts)
161401e04c3fSmrg{
161501e04c3fSmrg   this->stmts = stmts;
161601e04c3fSmrg}
161701e04c3fSmrg
161801e04c3fSmrg
161901e04c3fSmrgvoid ast_case_label::print(void) const
162001e04c3fSmrg{
162101e04c3fSmrg   if (test_value != NULL) {
162201e04c3fSmrg      printf("case ");
162301e04c3fSmrg      test_value->print();
162401e04c3fSmrg      printf(": ");
162501e04c3fSmrg   } else {
162601e04c3fSmrg      printf("default: ");
162701e04c3fSmrg   }
162801e04c3fSmrg}
162901e04c3fSmrg
163001e04c3fSmrg
163101e04c3fSmrgast_case_label::ast_case_label(ast_expression *test_value)
163201e04c3fSmrg{
163301e04c3fSmrg   this->test_value = test_value;
163401e04c3fSmrg}
163501e04c3fSmrg
163601e04c3fSmrg
163701e04c3fSmrgvoid ast_case_label_list::print(void) const
163801e04c3fSmrg{
163901e04c3fSmrg   foreach_list_typed(ast_node, ast, link, & this->labels) {
164001e04c3fSmrg      ast->print();
164101e04c3fSmrg   }
164201e04c3fSmrg   printf("\n");
164301e04c3fSmrg}
164401e04c3fSmrg
164501e04c3fSmrg
164601e04c3fSmrgast_case_label_list::ast_case_label_list(void)
164701e04c3fSmrg{
164801e04c3fSmrg}
164901e04c3fSmrg
165001e04c3fSmrg
165101e04c3fSmrgvoid ast_case_statement::print(void) const
165201e04c3fSmrg{
165301e04c3fSmrg   labels->print();
165401e04c3fSmrg   foreach_list_typed(ast_node, ast, link, & this->stmts) {
165501e04c3fSmrg      ast->print();
165601e04c3fSmrg      printf("\n");
165701e04c3fSmrg   }
165801e04c3fSmrg}
165901e04c3fSmrg
166001e04c3fSmrg
166101e04c3fSmrgast_case_statement::ast_case_statement(ast_case_label_list *labels)
166201e04c3fSmrg{
166301e04c3fSmrg   this->labels = labels;
166401e04c3fSmrg}
166501e04c3fSmrg
166601e04c3fSmrg
166701e04c3fSmrgvoid ast_case_statement_list::print(void) const
166801e04c3fSmrg{
166901e04c3fSmrg   foreach_list_typed(ast_node, ast, link, & this->cases) {
167001e04c3fSmrg      ast->print();
167101e04c3fSmrg   }
167201e04c3fSmrg}
167301e04c3fSmrg
167401e04c3fSmrg
167501e04c3fSmrgast_case_statement_list::ast_case_statement_list(void)
167601e04c3fSmrg{
167701e04c3fSmrg}
167801e04c3fSmrg
167901e04c3fSmrg
168001e04c3fSmrgvoid
168101e04c3fSmrgast_iteration_statement::print(void) const
168201e04c3fSmrg{
168301e04c3fSmrg   switch (mode) {
168401e04c3fSmrg   case ast_for:
168501e04c3fSmrg      printf("for( ");
168601e04c3fSmrg      if (init_statement)
168701e04c3fSmrg	 init_statement->print();
168801e04c3fSmrg      printf("; ");
168901e04c3fSmrg
169001e04c3fSmrg      if (condition)
169101e04c3fSmrg	 condition->print();
169201e04c3fSmrg      printf("; ");
169301e04c3fSmrg
169401e04c3fSmrg      if (rest_expression)
169501e04c3fSmrg	 rest_expression->print();
169601e04c3fSmrg      printf(") ");
169701e04c3fSmrg
169801e04c3fSmrg      body->print();
169901e04c3fSmrg      break;
170001e04c3fSmrg
170101e04c3fSmrg   case ast_while:
170201e04c3fSmrg      printf("while ( ");
170301e04c3fSmrg      if (condition)
170401e04c3fSmrg	 condition->print();
170501e04c3fSmrg      printf(") ");
170601e04c3fSmrg      body->print();
170701e04c3fSmrg      break;
170801e04c3fSmrg
170901e04c3fSmrg   case ast_do_while:
171001e04c3fSmrg      printf("do ");
171101e04c3fSmrg      body->print();
171201e04c3fSmrg      printf("while ( ");
171301e04c3fSmrg      if (condition)
171401e04c3fSmrg	 condition->print();
171501e04c3fSmrg      printf("); ");
171601e04c3fSmrg      break;
171701e04c3fSmrg   }
171801e04c3fSmrg}
171901e04c3fSmrg
172001e04c3fSmrg
172101e04c3fSmrgast_iteration_statement::ast_iteration_statement(int mode,
172201e04c3fSmrg						 ast_node *init,
172301e04c3fSmrg						 ast_node *condition,
172401e04c3fSmrg						 ast_expression *rest_expression,
172501e04c3fSmrg						 ast_node *body)
172601e04c3fSmrg{
172701e04c3fSmrg   this->mode = ast_iteration_modes(mode);
172801e04c3fSmrg   this->init_statement = init;
172901e04c3fSmrg   this->condition = condition;
173001e04c3fSmrg   this->rest_expression = rest_expression;
173101e04c3fSmrg   this->body = body;
173201e04c3fSmrg}
173301e04c3fSmrg
173401e04c3fSmrg
173501e04c3fSmrgvoid
173601e04c3fSmrgast_struct_specifier::print(void) const
173701e04c3fSmrg{
173801e04c3fSmrg   printf("struct %s { ", name);
173901e04c3fSmrg   foreach_list_typed(ast_node, ast, link, &this->declarations) {
174001e04c3fSmrg      ast->print();
174101e04c3fSmrg   }
174201e04c3fSmrg   printf("} ");
174301e04c3fSmrg}
174401e04c3fSmrg
174501e04c3fSmrg
174601e04c3fSmrgast_struct_specifier::ast_struct_specifier(const char *identifier,
174701e04c3fSmrg					   ast_declarator_list *declarator_list)
174801e04c3fSmrg   : name(identifier), layout(NULL), declarations(), is_declaration(true),
174901e04c3fSmrg     type(NULL)
175001e04c3fSmrg{
175101e04c3fSmrg   this->declarations.push_degenerate_list_at_head(&declarator_list->link);
175201e04c3fSmrg}
175301e04c3fSmrg
175401e04c3fSmrgvoid ast_subroutine_list::print(void) const
175501e04c3fSmrg{
175601e04c3fSmrg   foreach_list_typed (ast_node, ast, link, & this->declarations) {
175701e04c3fSmrg      if (&ast->link != this->declarations.get_head())
175801e04c3fSmrg         printf(", ");
175901e04c3fSmrg      ast->print();
176001e04c3fSmrg   }
176101e04c3fSmrg}
176201e04c3fSmrg
176301e04c3fSmrgstatic void
176401e04c3fSmrgset_shader_inout_layout(struct gl_shader *shader,
176501e04c3fSmrg		     struct _mesa_glsl_parse_state *state)
176601e04c3fSmrg{
176701e04c3fSmrg   /* Should have been prevented by the parser. */
1768d8407755Smaya   if (shader->Stage != MESA_SHADER_GEOMETRY &&
1769d8407755Smaya       shader->Stage != MESA_SHADER_TESS_EVAL &&
1770d8407755Smaya       shader->Stage != MESA_SHADER_COMPUTE) {
177101e04c3fSmrg      assert(!state->in_qualifier->flags.i);
177201e04c3fSmrg   }
177301e04c3fSmrg
177401e04c3fSmrg   if (shader->Stage != MESA_SHADER_COMPUTE) {
177501e04c3fSmrg      /* Should have been prevented by the parser. */
177601e04c3fSmrg      assert(!state->cs_input_local_size_specified);
177701e04c3fSmrg      assert(!state->cs_input_local_size_variable_specified);
1778d8407755Smaya      assert(state->cs_derivative_group == DERIVATIVE_GROUP_NONE);
177901e04c3fSmrg   }
178001e04c3fSmrg
178101e04c3fSmrg   if (shader->Stage != MESA_SHADER_FRAGMENT) {
178201e04c3fSmrg      /* Should have been prevented by the parser. */
178301e04c3fSmrg      assert(!state->fs_uses_gl_fragcoord);
178401e04c3fSmrg      assert(!state->fs_redeclares_gl_fragcoord);
178501e04c3fSmrg      assert(!state->fs_pixel_center_integer);
178601e04c3fSmrg      assert(!state->fs_origin_upper_left);
178701e04c3fSmrg      assert(!state->fs_early_fragment_tests);
178801e04c3fSmrg      assert(!state->fs_inner_coverage);
178901e04c3fSmrg      assert(!state->fs_post_depth_coverage);
179001e04c3fSmrg      assert(!state->fs_pixel_interlock_ordered);
179101e04c3fSmrg      assert(!state->fs_pixel_interlock_unordered);
179201e04c3fSmrg      assert(!state->fs_sample_interlock_ordered);
179301e04c3fSmrg      assert(!state->fs_sample_interlock_unordered);
179401e04c3fSmrg   }
179501e04c3fSmrg
179601e04c3fSmrg   for (unsigned i = 0; i < MAX_FEEDBACK_BUFFERS; i++) {
179701e04c3fSmrg      if (state->out_qualifier->out_xfb_stride[i]) {
179801e04c3fSmrg         unsigned xfb_stride;
179901e04c3fSmrg         if (state->out_qualifier->out_xfb_stride[i]->
180001e04c3fSmrg                process_qualifier_constant(state, "xfb_stride", &xfb_stride,
180101e04c3fSmrg                true)) {
180201e04c3fSmrg            shader->TransformFeedbackBufferStride[i] = xfb_stride;
180301e04c3fSmrg         }
180401e04c3fSmrg      }
180501e04c3fSmrg   }
180601e04c3fSmrg
180701e04c3fSmrg   switch (shader->Stage) {
180801e04c3fSmrg   case MESA_SHADER_TESS_CTRL:
180901e04c3fSmrg      shader->info.TessCtrl.VerticesOut = 0;
181001e04c3fSmrg      if (state->tcs_output_vertices_specified) {
181101e04c3fSmrg         unsigned vertices;
181201e04c3fSmrg         if (state->out_qualifier->vertices->
181301e04c3fSmrg               process_qualifier_constant(state, "vertices", &vertices,
181401e04c3fSmrg                                          false)) {
181501e04c3fSmrg
181601e04c3fSmrg            YYLTYPE loc = state->out_qualifier->vertices->get_location();
181701e04c3fSmrg            if (vertices > state->Const.MaxPatchVertices) {
181801e04c3fSmrg               _mesa_glsl_error(&loc, state, "vertices (%d) exceeds "
181901e04c3fSmrg                                "GL_MAX_PATCH_VERTICES", vertices);
182001e04c3fSmrg            }
182101e04c3fSmrg            shader->info.TessCtrl.VerticesOut = vertices;
182201e04c3fSmrg         }
182301e04c3fSmrg      }
182401e04c3fSmrg      break;
182501e04c3fSmrg   case MESA_SHADER_TESS_EVAL:
182601e04c3fSmrg      shader->info.TessEval.PrimitiveMode = PRIM_UNKNOWN;
182701e04c3fSmrg      if (state->in_qualifier->flags.q.prim_type)
182801e04c3fSmrg         shader->info.TessEval.PrimitiveMode = state->in_qualifier->prim_type;
182901e04c3fSmrg
183001e04c3fSmrg      shader->info.TessEval.Spacing = TESS_SPACING_UNSPECIFIED;
183101e04c3fSmrg      if (state->in_qualifier->flags.q.vertex_spacing)
183201e04c3fSmrg         shader->info.TessEval.Spacing = state->in_qualifier->vertex_spacing;
183301e04c3fSmrg
183401e04c3fSmrg      shader->info.TessEval.VertexOrder = 0;
183501e04c3fSmrg      if (state->in_qualifier->flags.q.ordering)
183601e04c3fSmrg         shader->info.TessEval.VertexOrder = state->in_qualifier->ordering;
183701e04c3fSmrg
183801e04c3fSmrg      shader->info.TessEval.PointMode = -1;
183901e04c3fSmrg      if (state->in_qualifier->flags.q.point_mode)
184001e04c3fSmrg         shader->info.TessEval.PointMode = state->in_qualifier->point_mode;
184101e04c3fSmrg      break;
184201e04c3fSmrg   case MESA_SHADER_GEOMETRY:
184301e04c3fSmrg      shader->info.Geom.VerticesOut = -1;
184401e04c3fSmrg      if (state->out_qualifier->flags.q.max_vertices) {
184501e04c3fSmrg         unsigned qual_max_vertices;
184601e04c3fSmrg         if (state->out_qualifier->max_vertices->
184701e04c3fSmrg               process_qualifier_constant(state, "max_vertices",
184801e04c3fSmrg                                          &qual_max_vertices, true)) {
184901e04c3fSmrg
185001e04c3fSmrg            if (qual_max_vertices > state->Const.MaxGeometryOutputVertices) {
185101e04c3fSmrg               YYLTYPE loc = state->out_qualifier->max_vertices->get_location();
185201e04c3fSmrg               _mesa_glsl_error(&loc, state,
185301e04c3fSmrg                                "maximum output vertices (%d) exceeds "
185401e04c3fSmrg                                "GL_MAX_GEOMETRY_OUTPUT_VERTICES",
185501e04c3fSmrg                                qual_max_vertices);
185601e04c3fSmrg            }
185701e04c3fSmrg            shader->info.Geom.VerticesOut = qual_max_vertices;
185801e04c3fSmrg         }
185901e04c3fSmrg      }
186001e04c3fSmrg
186101e04c3fSmrg      if (state->gs_input_prim_type_specified) {
186201e04c3fSmrg         shader->info.Geom.InputType = state->in_qualifier->prim_type;
186301e04c3fSmrg      } else {
186401e04c3fSmrg         shader->info.Geom.InputType = PRIM_UNKNOWN;
186501e04c3fSmrg      }
186601e04c3fSmrg
186701e04c3fSmrg      if (state->out_qualifier->flags.q.prim_type) {
186801e04c3fSmrg         shader->info.Geom.OutputType = state->out_qualifier->prim_type;
186901e04c3fSmrg      } else {
187001e04c3fSmrg         shader->info.Geom.OutputType = PRIM_UNKNOWN;
187101e04c3fSmrg      }
187201e04c3fSmrg
187301e04c3fSmrg      shader->info.Geom.Invocations = 0;
187401e04c3fSmrg      if (state->in_qualifier->flags.q.invocations) {
187501e04c3fSmrg         unsigned invocations;
187601e04c3fSmrg         if (state->in_qualifier->invocations->
187701e04c3fSmrg               process_qualifier_constant(state, "invocations",
187801e04c3fSmrg                                          &invocations, false)) {
187901e04c3fSmrg
188001e04c3fSmrg            YYLTYPE loc = state->in_qualifier->invocations->get_location();
188101e04c3fSmrg            if (invocations > state->Const.MaxGeometryShaderInvocations) {
188201e04c3fSmrg               _mesa_glsl_error(&loc, state,
188301e04c3fSmrg                                "invocations (%d) exceeds "
188401e04c3fSmrg                                "GL_MAX_GEOMETRY_SHADER_INVOCATIONS",
188501e04c3fSmrg                                invocations);
188601e04c3fSmrg            }
188701e04c3fSmrg            shader->info.Geom.Invocations = invocations;
188801e04c3fSmrg         }
188901e04c3fSmrg      }
189001e04c3fSmrg      break;
189101e04c3fSmrg
189201e04c3fSmrg   case MESA_SHADER_COMPUTE:
189301e04c3fSmrg      if (state->cs_input_local_size_specified) {
189401e04c3fSmrg         for (int i = 0; i < 3; i++)
189501e04c3fSmrg            shader->info.Comp.LocalSize[i] = state->cs_input_local_size[i];
189601e04c3fSmrg      } else {
189701e04c3fSmrg         for (int i = 0; i < 3; i++)
189801e04c3fSmrg            shader->info.Comp.LocalSize[i] = 0;
189901e04c3fSmrg      }
190001e04c3fSmrg
190101e04c3fSmrg      shader->info.Comp.LocalSizeVariable =
190201e04c3fSmrg         state->cs_input_local_size_variable_specified;
1903d8407755Smaya
1904d8407755Smaya      shader->info.Comp.DerivativeGroup = state->cs_derivative_group;
1905d8407755Smaya
1906d8407755Smaya      if (state->NV_compute_shader_derivatives_enable) {
1907d8407755Smaya         /* We allow multiple cs_input_layout nodes, but do not store them in
1908d8407755Smaya          * a convenient place, so for now live with an empty location error.
1909d8407755Smaya          */
1910d8407755Smaya         YYLTYPE loc = {0};
1911d8407755Smaya         if (shader->info.Comp.DerivativeGroup == DERIVATIVE_GROUP_QUADS) {
1912d8407755Smaya            if (shader->info.Comp.LocalSize[0] % 2 != 0) {
1913d8407755Smaya               _mesa_glsl_error(&loc, state, "derivative_group_quadsNV must be used with a "
1914d8407755Smaya                                "local group size whose first dimension "
1915d8407755Smaya                                "is a multiple of 2\n");
1916d8407755Smaya            }
1917d8407755Smaya            if (shader->info.Comp.LocalSize[1] % 2 != 0) {
1918d8407755Smaya               _mesa_glsl_error(&loc, state, "derivative_group_quadsNV must be used with a "
1919d8407755Smaya                                "local group size whose second dimension "
1920d8407755Smaya                                "is a multiple of 2\n");
1921d8407755Smaya            }
1922d8407755Smaya         } else if (shader->info.Comp.DerivativeGroup == DERIVATIVE_GROUP_LINEAR) {
1923d8407755Smaya            if ((shader->info.Comp.LocalSize[0] *
1924d8407755Smaya                 shader->info.Comp.LocalSize[1] *
1925d8407755Smaya                 shader->info.Comp.LocalSize[2]) % 4 != 0) {
1926d8407755Smaya               _mesa_glsl_error(&loc, state, "derivative_group_linearNV must be used with a "
1927d8407755Smaya                            "local group size whose total number of invocations "
1928d8407755Smaya                            "is a multiple of 4\n");
1929d8407755Smaya            }
1930d8407755Smaya         }
1931d8407755Smaya      }
1932d8407755Smaya
193301e04c3fSmrg      break;
193401e04c3fSmrg
193501e04c3fSmrg   case MESA_SHADER_FRAGMENT:
193601e04c3fSmrg      shader->redeclares_gl_fragcoord = state->fs_redeclares_gl_fragcoord;
193701e04c3fSmrg      shader->uses_gl_fragcoord = state->fs_uses_gl_fragcoord;
193801e04c3fSmrg      shader->pixel_center_integer = state->fs_pixel_center_integer;
193901e04c3fSmrg      shader->origin_upper_left = state->fs_origin_upper_left;
194001e04c3fSmrg      shader->ARB_fragment_coord_conventions_enable =
194101e04c3fSmrg         state->ARB_fragment_coord_conventions_enable;
194201e04c3fSmrg      shader->EarlyFragmentTests = state->fs_early_fragment_tests;
194301e04c3fSmrg      shader->InnerCoverage = state->fs_inner_coverage;
194401e04c3fSmrg      shader->PostDepthCoverage = state->fs_post_depth_coverage;
194501e04c3fSmrg      shader->PixelInterlockOrdered = state->fs_pixel_interlock_ordered;
194601e04c3fSmrg      shader->PixelInterlockUnordered = state->fs_pixel_interlock_unordered;
194701e04c3fSmrg      shader->SampleInterlockOrdered = state->fs_sample_interlock_ordered;
194801e04c3fSmrg      shader->SampleInterlockUnordered = state->fs_sample_interlock_unordered;
194901e04c3fSmrg      shader->BlendSupport = state->fs_blend_support;
195001e04c3fSmrg      break;
195101e04c3fSmrg
195201e04c3fSmrg   default:
195301e04c3fSmrg      /* Nothing to do. */
195401e04c3fSmrg      break;
195501e04c3fSmrg   }
195601e04c3fSmrg
195701e04c3fSmrg   shader->bindless_sampler = state->bindless_sampler_specified;
195801e04c3fSmrg   shader->bindless_image = state->bindless_image_specified;
195901e04c3fSmrg   shader->bound_sampler = state->bound_sampler_specified;
196001e04c3fSmrg   shader->bound_image = state->bound_image_specified;
19611463c08dSmrg   shader->redeclares_gl_layer = state->redeclares_gl_layer;
19621463c08dSmrg   shader->layer_viewport_relative = state->layer_viewport_relative;
196301e04c3fSmrg}
196401e04c3fSmrg
196501e04c3fSmrg/* src can be NULL if only the symbols found in the exec_list should be
196601e04c3fSmrg * copied
196701e04c3fSmrg */
196801e04c3fSmrgvoid
196901e04c3fSmrg_mesa_glsl_copy_symbols_from_table(struct exec_list *shader_ir,
197001e04c3fSmrg                                   struct glsl_symbol_table *src,
197101e04c3fSmrg                                   struct glsl_symbol_table *dest)
197201e04c3fSmrg{
197301e04c3fSmrg   foreach_in_list (ir_instruction, ir, shader_ir) {
197401e04c3fSmrg      switch (ir->ir_type) {
197501e04c3fSmrg      case ir_type_function:
197601e04c3fSmrg         dest->add_function((ir_function *) ir);
197701e04c3fSmrg         break;
197801e04c3fSmrg      case ir_type_variable: {
197901e04c3fSmrg         ir_variable *const var = (ir_variable *) ir;
198001e04c3fSmrg
198101e04c3fSmrg         if (var->data.mode != ir_var_temporary)
198201e04c3fSmrg            dest->add_variable(var);
198301e04c3fSmrg         break;
198401e04c3fSmrg      }
198501e04c3fSmrg      default:
198601e04c3fSmrg         break;
198701e04c3fSmrg      }
198801e04c3fSmrg   }
198901e04c3fSmrg
199001e04c3fSmrg   if (src != NULL) {
199101e04c3fSmrg      /* Explicitly copy the gl_PerVertex interface definitions because these
199201e04c3fSmrg       * are needed to check they are the same during the interstage link.
199301e04c3fSmrg       * They can’t necessarily be found via the exec_list because the members
199401e04c3fSmrg       * might not be referenced. The GL spec still requires that they match
199501e04c3fSmrg       * in that case.
199601e04c3fSmrg       */
199701e04c3fSmrg      const glsl_type *iface =
199801e04c3fSmrg         src->get_interface("gl_PerVertex", ir_var_shader_in);
199901e04c3fSmrg      if (iface)
200001e04c3fSmrg         dest->add_interface(iface->name, iface, ir_var_shader_in);
200101e04c3fSmrg
200201e04c3fSmrg      iface = src->get_interface("gl_PerVertex", ir_var_shader_out);
200301e04c3fSmrg      if (iface)
200401e04c3fSmrg         dest->add_interface(iface->name, iface, ir_var_shader_out);
200501e04c3fSmrg   }
200601e04c3fSmrg}
200701e04c3fSmrg
200801e04c3fSmrgextern "C" {
200901e04c3fSmrg
201001e04c3fSmrgstatic void
201101e04c3fSmrgassign_subroutine_indexes(struct _mesa_glsl_parse_state *state)
201201e04c3fSmrg{
201301e04c3fSmrg   int j, k;
201401e04c3fSmrg   int index = 0;
201501e04c3fSmrg
201601e04c3fSmrg   for (j = 0; j < state->num_subroutines; j++) {
201701e04c3fSmrg      while (state->subroutines[j]->subroutine_index == -1) {
201801e04c3fSmrg         for (k = 0; k < state->num_subroutines; k++) {
201901e04c3fSmrg            if (state->subroutines[k]->subroutine_index == index)
202001e04c3fSmrg               break;
202101e04c3fSmrg            else if (k == state->num_subroutines - 1) {
202201e04c3fSmrg               state->subroutines[j]->subroutine_index = index;
202301e04c3fSmrg            }
202401e04c3fSmrg         }
202501e04c3fSmrg         index++;
202601e04c3fSmrg      }
202701e04c3fSmrg   }
202801e04c3fSmrg}
202901e04c3fSmrg
203001e04c3fSmrgstatic void
203101e04c3fSmrgadd_builtin_defines(struct _mesa_glsl_parse_state *state,
203201e04c3fSmrg                    void (*add_builtin_define)(struct glcpp_parser *, const char *, int),
203301e04c3fSmrg                    struct glcpp_parser *data,
203401e04c3fSmrg                    unsigned version,
203501e04c3fSmrg                    bool es)
203601e04c3fSmrg{
203701e04c3fSmrg   unsigned gl_version = state->ctx->Extensions.Version;
203801e04c3fSmrg   gl_api api = state->ctx->API;
203901e04c3fSmrg
204001e04c3fSmrg   if (gl_version != 0xff) {
204101e04c3fSmrg      unsigned i;
204201e04c3fSmrg      for (i = 0; i < state->num_supported_versions; i++) {
204301e04c3fSmrg         if (state->supported_versions[i].ver == version &&
204401e04c3fSmrg             state->supported_versions[i].es == es) {
204501e04c3fSmrg            gl_version = state->supported_versions[i].gl_ver;
204601e04c3fSmrg            break;
204701e04c3fSmrg         }
204801e04c3fSmrg      }
204901e04c3fSmrg
205001e04c3fSmrg      if (i == state->num_supported_versions)
205101e04c3fSmrg         return;
205201e04c3fSmrg   }
205301e04c3fSmrg
205401e04c3fSmrg   if (es)
205501e04c3fSmrg      api = API_OPENGLES2;
205601e04c3fSmrg
205701e04c3fSmrg   for (unsigned i = 0;
205801e04c3fSmrg        i < ARRAY_SIZE(_mesa_glsl_supported_extensions); ++i) {
205901e04c3fSmrg      const _mesa_glsl_extension *extension
206001e04c3fSmrg         = &_mesa_glsl_supported_extensions[i];
206101e04c3fSmrg      if (extension->compatible_with_state(state, api, gl_version)) {
206201e04c3fSmrg         add_builtin_define(data, extension->name, 1);
206301e04c3fSmrg      }
206401e04c3fSmrg   }
206501e04c3fSmrg}
206601e04c3fSmrg
206701e04c3fSmrg/* Implements parsing checks that we can't do during parsing */
206801e04c3fSmrgstatic void
206901e04c3fSmrgdo_late_parsing_checks(struct _mesa_glsl_parse_state *state)
207001e04c3fSmrg{
207101e04c3fSmrg   if (state->stage == MESA_SHADER_COMPUTE && !state->has_compute_shader()) {
207201e04c3fSmrg      YYLTYPE loc;
207301e04c3fSmrg      memset(&loc, 0, sizeof(loc));
207401e04c3fSmrg      _mesa_glsl_error(&loc, state, "Compute shaders require "
207501e04c3fSmrg                       "GLSL 4.30 or GLSL ES 3.10");
207601e04c3fSmrg   }
207701e04c3fSmrg}
207801e04c3fSmrg
207901e04c3fSmrgstatic void
208001e04c3fSmrgopt_shader_and_create_symbol_table(struct gl_context *ctx,
208101e04c3fSmrg                                   struct glsl_symbol_table *source_symbols,
208201e04c3fSmrg                                   struct gl_shader *shader)
208301e04c3fSmrg{
208401e04c3fSmrg   assert(shader->CompileStatus != COMPILE_FAILURE &&
208501e04c3fSmrg          !shader->ir->is_empty());
208601e04c3fSmrg
208701e04c3fSmrg   struct gl_shader_compiler_options *options =
208801e04c3fSmrg      &ctx->Const.ShaderCompilerOptions[shader->Stage];
208901e04c3fSmrg
209001e04c3fSmrg   /* Do some optimization at compile time to reduce shader IR size
209101e04c3fSmrg    * and reduce later work if the same shader is linked multiple times
209201e04c3fSmrg    */
209301e04c3fSmrg   if (ctx->Const.GLSLOptimizeConservatively) {
209401e04c3fSmrg      /* Run it just once. */
209501e04c3fSmrg      do_common_optimization(shader->ir, false, false, options,
209601e04c3fSmrg                             ctx->Const.NativeIntegers);
209701e04c3fSmrg   } else {
209801e04c3fSmrg      /* Repeat it until it stops making changes. */
209901e04c3fSmrg      while (do_common_optimization(shader->ir, false, false, options,
210001e04c3fSmrg                                    ctx->Const.NativeIntegers))
210101e04c3fSmrg         ;
210201e04c3fSmrg   }
210301e04c3fSmrg
210401e04c3fSmrg   validate_ir_tree(shader->ir);
210501e04c3fSmrg
210601e04c3fSmrg   enum ir_variable_mode other;
210701e04c3fSmrg   switch (shader->Stage) {
210801e04c3fSmrg   case MESA_SHADER_VERTEX:
210901e04c3fSmrg      other = ir_var_shader_in;
211001e04c3fSmrg      break;
211101e04c3fSmrg   case MESA_SHADER_FRAGMENT:
211201e04c3fSmrg      other = ir_var_shader_out;
211301e04c3fSmrg      break;
211401e04c3fSmrg   default:
211501e04c3fSmrg      /* Something invalid to ensure optimize_dead_builtin_uniforms
211601e04c3fSmrg       * doesn't remove anything other than uniforms or constants.
211701e04c3fSmrg       */
211801e04c3fSmrg      other = ir_var_mode_count;
211901e04c3fSmrg      break;
212001e04c3fSmrg   }
212101e04c3fSmrg
212201e04c3fSmrg   optimize_dead_builtin_variables(shader->ir, other);
212301e04c3fSmrg
212401e04c3fSmrg   validate_ir_tree(shader->ir);
212501e04c3fSmrg
212601e04c3fSmrg   /* Retain any live IR, but trash the rest. */
212701e04c3fSmrg   reparent_ir(shader->ir, shader->ir);
212801e04c3fSmrg
212901e04c3fSmrg   /* Destroy the symbol table.  Create a new symbol table that contains only
213001e04c3fSmrg    * the variables and functions that still exist in the IR.  The symbol
213101e04c3fSmrg    * table will be used later during linking.
213201e04c3fSmrg    *
213301e04c3fSmrg    * There must NOT be any freed objects still referenced by the symbol
213401e04c3fSmrg    * table.  That could cause the linker to dereference freed memory.
213501e04c3fSmrg    *
213601e04c3fSmrg    * We don't have to worry about types or interface-types here because those
213701e04c3fSmrg    * are fly-weights that are looked up by glsl_type.
213801e04c3fSmrg    */
213901e04c3fSmrg   _mesa_glsl_copy_symbols_from_table(shader->ir, source_symbols,
214001e04c3fSmrg                                      shader->symbols);
214101e04c3fSmrg}
214201e04c3fSmrg
21431463c08dSmrgstatic bool
21441463c08dSmrgcan_skip_compile(struct gl_context *ctx, struct gl_shader *shader,
21451463c08dSmrg                 const char *source, bool force_recompile,
21461463c08dSmrg                 bool source_has_shader_include)
214701e04c3fSmrg{
214801e04c3fSmrg   if (!force_recompile) {
214901e04c3fSmrg      if (ctx->Cache) {
215001e04c3fSmrg         char buf[41];
215101e04c3fSmrg         disk_cache_compute_key(ctx->Cache, source, strlen(source),
215201e04c3fSmrg                                shader->sha1);
215301e04c3fSmrg         if (disk_cache_has_key(ctx->Cache, shader->sha1)) {
215401e04c3fSmrg            /* We've seen this shader before and know it compiles */
215501e04c3fSmrg            if (ctx->_Shader->Flags & GLSL_CACHE_INFO) {
215601e04c3fSmrg               _mesa_sha1_format(buf, shader->sha1);
215701e04c3fSmrg               fprintf(stderr, "deferring compile of shader: %s\n", buf);
215801e04c3fSmrg            }
215901e04c3fSmrg            shader->CompileStatus = COMPILE_SKIPPED;
216001e04c3fSmrg
216101e04c3fSmrg            free((void *)shader->FallbackSource);
21621463c08dSmrg
21631463c08dSmrg            /* Copy pre-processed shader include to fallback source otherwise
21641463c08dSmrg             * we have no guarantee the shader include source tree has not
21651463c08dSmrg             * changed.
21661463c08dSmrg             */
21671463c08dSmrg            shader->FallbackSource = source_has_shader_include ?
21681463c08dSmrg               strdup(source) : NULL;
21691463c08dSmrg            return true;
217001e04c3fSmrg         }
217101e04c3fSmrg      }
217201e04c3fSmrg   } else {
217301e04c3fSmrg      /* We should only ever end up here if a re-compile has been forced by a
217401e04c3fSmrg       * shader cache miss. In which case we can skip the compile if its
21751463c08dSmrg       * already been done by a previous fallback or the initial compile call.
217601e04c3fSmrg       */
217701e04c3fSmrg      if (shader->CompileStatus == COMPILE_SUCCESS)
21781463c08dSmrg         return true;
217901e04c3fSmrg   }
218001e04c3fSmrg
21811463c08dSmrg   return false;
21821463c08dSmrg}
21831463c08dSmrg
21841463c08dSmrgvoid
21851463c08dSmrg_mesa_glsl_compile_shader(struct gl_context *ctx, struct gl_shader *shader,
21861463c08dSmrg                          bool dump_ast, bool dump_hir, bool force_recompile)
21871463c08dSmrg{
21881463c08dSmrg   const char *source = force_recompile && shader->FallbackSource ?
21891463c08dSmrg      shader->FallbackSource : shader->Source;
21901463c08dSmrg
21911463c08dSmrg   /* Note this will be true for shaders the have #include inside comments
21921463c08dSmrg    * however that should be rare enough not to worry about.
21931463c08dSmrg    */
21941463c08dSmrg   bool source_has_shader_include =
21951463c08dSmrg      strstr(source, "#include") == NULL ? false : true;
21961463c08dSmrg
21971463c08dSmrg   /* If there was no shader include we can check the shader cache and skip
21981463c08dSmrg    * compilation before we run the preprocessor. We never skip compiling
21991463c08dSmrg    * shaders that use ARB_shading_language_include because we would need to
22001463c08dSmrg    * keep duplicate copies of the shader include source tree and paths.
22011463c08dSmrg    */
22021463c08dSmrg   if (!source_has_shader_include &&
22031463c08dSmrg       can_skip_compile(ctx, shader, source, force_recompile, false))
22041463c08dSmrg      return;
22051463c08dSmrg
22061463c08dSmrg    struct _mesa_glsl_parse_state *state =
220701e04c3fSmrg      new(shader) _mesa_glsl_parse_state(ctx, shader->Stage, shader);
220801e04c3fSmrg
220901e04c3fSmrg   if (ctx->Const.GenerateTemporaryNames)
221001e04c3fSmrg      (void) p_atomic_cmpxchg(&ir_variable::temporaries_allocate_names,
221101e04c3fSmrg                              false, true);
221201e04c3fSmrg
22131463c08dSmrg   if (!source_has_shader_include || !force_recompile) {
22141463c08dSmrg      state->error = glcpp_preprocess(state, &source, &state->info_log,
22151463c08dSmrg                                      add_builtin_defines, state, ctx);
22161463c08dSmrg   }
22171463c08dSmrg
22181463c08dSmrg   /* Now that we have run the preprocessor we can check the shader cache and
22191463c08dSmrg    * skip compilation if possible for those shaders that contained a shader
22201463c08dSmrg    * include.
22211463c08dSmrg    */
22221463c08dSmrg   if (source_has_shader_include &&
22231463c08dSmrg       can_skip_compile(ctx, shader, source, force_recompile, true))
22241463c08dSmrg      return;
222501e04c3fSmrg
222601e04c3fSmrg   if (!state->error) {
222701e04c3fSmrg     _mesa_glsl_lexer_ctor(state, source);
222801e04c3fSmrg     _mesa_glsl_parse(state);
222901e04c3fSmrg     _mesa_glsl_lexer_dtor(state);
223001e04c3fSmrg     do_late_parsing_checks(state);
223101e04c3fSmrg   }
223201e04c3fSmrg
223301e04c3fSmrg   if (dump_ast) {
223401e04c3fSmrg      foreach_list_typed(ast_node, ast, link, &state->translation_unit) {
223501e04c3fSmrg         ast->print();
223601e04c3fSmrg      }
223701e04c3fSmrg      printf("\n\n");
223801e04c3fSmrg   }
223901e04c3fSmrg
224001e04c3fSmrg   ralloc_free(shader->ir);
224101e04c3fSmrg   shader->ir = new(shader) exec_list;
224201e04c3fSmrg   if (!state->error && !state->translation_unit.is_empty())
224301e04c3fSmrg      _mesa_ast_to_hir(shader->ir, state);
224401e04c3fSmrg
224501e04c3fSmrg   if (!state->error) {
224601e04c3fSmrg      validate_ir_tree(shader->ir);
224701e04c3fSmrg
224801e04c3fSmrg      /* Print out the unoptimized IR. */
224901e04c3fSmrg      if (dump_hir) {
225001e04c3fSmrg         _mesa_print_ir(stdout, shader->ir, state);
225101e04c3fSmrg      }
225201e04c3fSmrg   }
225301e04c3fSmrg
225401e04c3fSmrg   if (shader->InfoLog)
225501e04c3fSmrg      ralloc_free(shader->InfoLog);
225601e04c3fSmrg
225701e04c3fSmrg   if (!state->error)
225801e04c3fSmrg      set_shader_inout_layout(shader, state);
225901e04c3fSmrg
226001e04c3fSmrg   shader->symbols = new(shader->ir) glsl_symbol_table;
226101e04c3fSmrg   shader->CompileStatus = state->error ? COMPILE_FAILURE : COMPILE_SUCCESS;
226201e04c3fSmrg   shader->InfoLog = state->info_log;
226301e04c3fSmrg   shader->Version = state->language_version;
226401e04c3fSmrg   shader->IsES = state->es_shader;
226501e04c3fSmrg
22661463c08dSmrg   struct gl_shader_compiler_options *options =
22671463c08dSmrg      &ctx->Const.ShaderCompilerOptions[shader->Stage];
22681463c08dSmrg
226901e04c3fSmrg   if (!state->error && !shader->ir->is_empty()) {
22701463c08dSmrg      if (state->es_shader &&
22711463c08dSmrg          (options->LowerPrecisionFloat16 || options->LowerPrecisionInt16))
22721463c08dSmrg         lower_precision(options, shader->ir);
22731463c08dSmrg      lower_builtins(shader->ir);
227401e04c3fSmrg      assign_subroutine_indexes(state);
227501e04c3fSmrg      lower_subroutine(shader->ir, state);
2276d8407755Smaya      opt_shader_and_create_symbol_table(ctx, state->symbols, shader);
227701e04c3fSmrg   }
227801e04c3fSmrg
227901e04c3fSmrg   if (!force_recompile) {
228001e04c3fSmrg      free((void *)shader->FallbackSource);
22811463c08dSmrg
22821463c08dSmrg      /* Copy pre-processed shader include to fallback source otherwise we
22831463c08dSmrg       * have no guarantee the shader include source tree has not changed.
22841463c08dSmrg       */
22851463c08dSmrg      shader->FallbackSource = source_has_shader_include ?
22861463c08dSmrg         strdup(source) : NULL;
228701e04c3fSmrg   }
228801e04c3fSmrg
228901e04c3fSmrg   delete state->symbols;
229001e04c3fSmrg   ralloc_free(state);
2291d8407755Smaya
2292d8407755Smaya   if (ctx->Cache && shader->CompileStatus == COMPILE_SUCCESS) {
2293d8407755Smaya      char sha1_buf[41];
2294d8407755Smaya      disk_cache_put_key(ctx->Cache, shader->sha1);
2295d8407755Smaya      if (ctx->_Shader->Flags & GLSL_CACHE_INFO) {
2296d8407755Smaya         _mesa_sha1_format(sha1_buf, shader->sha1);
2297d8407755Smaya         fprintf(stderr, "marking shader: %s\n", sha1_buf);
2298d8407755Smaya      }
2299d8407755Smaya   }
230001e04c3fSmrg}
230101e04c3fSmrg
230201e04c3fSmrg} /* extern "C" */
230301e04c3fSmrg/**
230401e04c3fSmrg * Do the set of common optimizations passes
230501e04c3fSmrg *
230601e04c3fSmrg * \param ir                          List of instructions to be optimized
230701e04c3fSmrg * \param linked                      Is the shader linked?  This enables
230801e04c3fSmrg *                                    optimizations passes that remove code at
230901e04c3fSmrg *                                    global scope and could cause linking to
231001e04c3fSmrg *                                    fail.
231101e04c3fSmrg * \param uniform_locations_assigned  Have locations already been assigned for
231201e04c3fSmrg *                                    uniforms?  This prevents the declarations
231301e04c3fSmrg *                                    of unused uniforms from being removed.
231401e04c3fSmrg *                                    The setting of this flag only matters if
231501e04c3fSmrg *                                    \c linked is \c true.
231601e04c3fSmrg * \param options                     The driver's preferred shader options.
231701e04c3fSmrg * \param native_integers             Selects optimizations that depend on the
231801e04c3fSmrg *                                    implementations supporting integers
231901e04c3fSmrg *                                    natively (as opposed to supporting
232001e04c3fSmrg *                                    integers in floating point registers).
232101e04c3fSmrg */
232201e04c3fSmrgbool
232301e04c3fSmrgdo_common_optimization(exec_list *ir, bool linked,
232401e04c3fSmrg		       bool uniform_locations_assigned,
232501e04c3fSmrg                       const struct gl_shader_compiler_options *options,
232601e04c3fSmrg                       bool native_integers)
232701e04c3fSmrg{
232801e04c3fSmrg   const bool debug = false;
23291463c08dSmrg   bool progress = false;
233001e04c3fSmrg
233101e04c3fSmrg#define OPT(PASS, ...) do {                                             \
233201e04c3fSmrg      if (debug) {                                                      \
233301e04c3fSmrg         fprintf(stderr, "START GLSL optimization %s\n", #PASS);        \
233401e04c3fSmrg         const bool opt_progress = PASS(__VA_ARGS__);                   \
233501e04c3fSmrg         progress = opt_progress || progress;                           \
233601e04c3fSmrg         if (opt_progress)                                              \
233701e04c3fSmrg            _mesa_print_ir(stderr, ir, NULL);                           \
233801e04c3fSmrg         fprintf(stderr, "GLSL optimization %s: %s progress\n",         \
233901e04c3fSmrg                 #PASS, opt_progress ? "made" : "no");                  \
234001e04c3fSmrg      } else {                                                          \
234101e04c3fSmrg         progress = PASS(__VA_ARGS__) || progress;                      \
234201e04c3fSmrg      }                                                                 \
234301e04c3fSmrg   } while (false)
234401e04c3fSmrg
234501e04c3fSmrg   OPT(lower_instructions, ir, SUB_TO_ADD_NEG);
234601e04c3fSmrg
234701e04c3fSmrg   if (linked) {
234801e04c3fSmrg      OPT(do_function_inlining, ir);
234901e04c3fSmrg      OPT(do_dead_functions, ir);
235001e04c3fSmrg      OPT(do_structure_splitting, ir);
235101e04c3fSmrg   }
23521463c08dSmrg   OPT(propagate_invariance, ir);
235301e04c3fSmrg   OPT(do_if_simplification, ir);
235401e04c3fSmrg   OPT(opt_flatten_nested_if_blocks, ir);
235501e04c3fSmrg   OPT(opt_conditional_discard, ir);
235601e04c3fSmrg   OPT(do_copy_propagation_elements, ir);
235701e04c3fSmrg
235801e04c3fSmrg   if (options->OptimizeForAOS && !linked)
235901e04c3fSmrg      OPT(opt_flip_matrices, ir);
236001e04c3fSmrg
236101e04c3fSmrg   if (linked && options->OptimizeForAOS) {
236201e04c3fSmrg      OPT(do_vectorize, ir);
236301e04c3fSmrg   }
236401e04c3fSmrg
236501e04c3fSmrg   if (linked)
236601e04c3fSmrg      OPT(do_dead_code, ir, uniform_locations_assigned);
236701e04c3fSmrg   else
236801e04c3fSmrg      OPT(do_dead_code_unlinked, ir);
236901e04c3fSmrg   OPT(do_dead_code_local, ir);
237001e04c3fSmrg   OPT(do_tree_grafting, ir);
237101e04c3fSmrg   OPT(do_constant_propagation, ir);
237201e04c3fSmrg   if (linked)
237301e04c3fSmrg      OPT(do_constant_variable, ir);
237401e04c3fSmrg   else
237501e04c3fSmrg      OPT(do_constant_variable_unlinked, ir);
237601e04c3fSmrg   OPT(do_constant_folding, ir);
237701e04c3fSmrg   OPT(do_minmax_prune, ir);
237801e04c3fSmrg   OPT(do_rebalance_tree, ir);
237901e04c3fSmrg   OPT(do_algebraic, ir, native_integers, options);
238001e04c3fSmrg   OPT(do_lower_jumps, ir, true, true, options->EmitNoMainReturn,
238101e04c3fSmrg       options->EmitNoCont, options->EmitNoLoops);
238201e04c3fSmrg   OPT(do_vec_index_to_swizzle, ir);
238301e04c3fSmrg   OPT(lower_vector_insert, ir, false);
238401e04c3fSmrg   OPT(optimize_swizzles, ir);
238501e04c3fSmrg
23861463c08dSmrg   /* Some drivers only call do_common_optimization() once rather than in a
23871463c08dSmrg    * loop, and split arrays causes each element of a constant array to
23881463c08dSmrg    * dereference is own copy of the entire array initilizer. This IR is not
23891463c08dSmrg    * something that can be generated manually in a shader and is not
23901463c08dSmrg    * accounted for by NIR optimisations, the result is an exponential slow
23911463c08dSmrg    * down in compilation speed as a constant arrays element count grows. To
23921463c08dSmrg    * avoid that here we make sure to always clean up the mess split arrays
23931463c08dSmrg    * causes to constant arrays.
23941463c08dSmrg    */
23951463c08dSmrg   bool array_split = optimize_split_arrays(ir, linked);
23961463c08dSmrg   if (array_split)
23971463c08dSmrg      do_constant_propagation(ir);
23981463c08dSmrg   progress |= array_split;
23991463c08dSmrg
240001e04c3fSmrg   OPT(optimize_redundant_jumps, ir);
240101e04c3fSmrg
240201e04c3fSmrg   if (options->MaxUnrollIterations) {
240301e04c3fSmrg      loop_state *ls = analyze_loop_variables(ir);
240401e04c3fSmrg      if (ls->loop_found) {
240501e04c3fSmrg         bool loop_progress = unroll_loops(ir, ls, options);
240601e04c3fSmrg         while (loop_progress) {
240701e04c3fSmrg            loop_progress = false;
240801e04c3fSmrg            loop_progress |= do_constant_propagation(ir);
240901e04c3fSmrg            loop_progress |= do_if_simplification(ir);
241001e04c3fSmrg
241101e04c3fSmrg            /* Some drivers only call do_common_optimization() once rather
241201e04c3fSmrg             * than in a loop. So we must call do_lower_jumps() after
241301e04c3fSmrg             * unrolling a loop because for drivers that use LLVM validation
241401e04c3fSmrg             * will fail if a jump is not the last instruction in the block.
241501e04c3fSmrg             * For example the following will fail LLVM validation:
241601e04c3fSmrg             *
241701e04c3fSmrg             *   (loop (
241801e04c3fSmrg             *      ...
241901e04c3fSmrg             *   break
242001e04c3fSmrg             *   (assign  (x) (var_ref v124)  (expression int + (var_ref v124)
242101e04c3fSmrg             *      (constant int (1)) ) )
242201e04c3fSmrg             *   ))
242301e04c3fSmrg             */
242401e04c3fSmrg            loop_progress |= do_lower_jumps(ir, true, true,
242501e04c3fSmrg                                            options->EmitNoMainReturn,
242601e04c3fSmrg                                            options->EmitNoCont,
242701e04c3fSmrg                                            options->EmitNoLoops);
242801e04c3fSmrg         }
242901e04c3fSmrg         progress |= loop_progress;
243001e04c3fSmrg      }
243101e04c3fSmrg      delete ls;
243201e04c3fSmrg   }
243301e04c3fSmrg
24341463c08dSmrg   /* If the PIPE_CAP_GLSL_OPTIMIZE_CONSERVATIVELY cap is set, this pass will
24351463c08dSmrg    * only be called once rather than repeatedly until no further progress is
24361463c08dSmrg    * made.
24371463c08dSmrg    *
24381463c08dSmrg    * If an optimization pass fails to preserve the invariant flag, calling
24391463c08dSmrg    * the pass only once may result in incorrect code generation. Always call
24401463c08dSmrg    * propagate_invariance() last to avoid this possibility.
24411463c08dSmrg    */
24421463c08dSmrg   OPT(propagate_invariance, ir);
24431463c08dSmrg
244401e04c3fSmrg#undef OPT
244501e04c3fSmrg
244601e04c3fSmrg   return progress;
244701e04c3fSmrg}
2448