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