Ian Romanick | a87ac25 | 2010-02-22 13:19:34 -0800 | [diff] [blame] | 1 | /* |
| 2 | * Copyright © 2008, 2009 Intel Corporation |
| 3 | * |
| 4 | * Permission is hereby granted, free of charge, to any person obtaining a |
| 5 | * copy of this software and associated documentation files (the "Software"), |
| 6 | * to deal in the Software without restriction, including without limitation |
| 7 | * the rights to use, copy, modify, merge, publish, distribute, sublicense, |
| 8 | * and/or sell copies of the Software, and to permit persons to whom the |
| 9 | * Software is furnished to do so, subject to the following conditions: |
| 10 | * |
| 11 | * The above copyright notice and this permission notice (including the next |
| 12 | * paragraph) shall be included in all copies or substantial portions of the |
| 13 | * Software. |
| 14 | * |
| 15 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
| 16 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
| 17 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL |
| 18 | * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
| 19 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING |
| 20 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER |
| 21 | * DEALINGS IN THE SOFTWARE. |
| 22 | */ |
| 23 | #include <stdio.h> |
| 24 | #include <stdarg.h> |
Ian Romanick | a87ac25 | 2010-02-22 13:19:34 -0800 | [diff] [blame] | 25 | #include <string.h> |
| 26 | #include <assert.h> |
Ian Romanick | a87ac25 | 2010-02-22 13:19:34 -0800 | [diff] [blame] | 27 | |
Kristian Høgsberg | f9995b3 | 2010-10-12 12:26:10 -0400 | [diff] [blame] | 28 | #include "main/core.h" /* for struct gl_context */ |
Jordan Justen | 4aecd8f | 2012-07-24 14:48:57 -0700 | [diff] [blame] | 29 | #include "main/context.h" |
Eric Anholt | 0343f20 | 2013-06-12 15:49:43 -0700 | [diff] [blame] | 30 | #include "main/shaderobj.h" |
Matt Turner | 9db278d | 2014-11-21 18:04:21 -0800 | [diff] [blame] | 31 | #include "util/u_atomic.h" /* for p_atomic_cmpxchg */ |
Kenneth Graunke | 1e0da62 | 2014-02-24 23:39:14 -0800 | [diff] [blame] | 32 | #include "util/ralloc.h" |
Ian Romanick | a87ac25 | 2010-02-22 13:19:34 -0800 | [diff] [blame] | 33 | #include "ast.h" |
| 34 | #include "glsl_parser_extras.h" |
Ian Romanick | d59673c | 2010-02-25 17:17:23 -0800 | [diff] [blame] | 35 | #include "glsl_parser.h" |
Eric Anholt | 2f4fe15 | 2010-08-10 13:06:49 -0700 | [diff] [blame] | 36 | #include "ir_optimization.h" |
Ian Romanick | 8df2dbf | 2010-08-26 16:45:22 -0700 | [diff] [blame] | 37 | #include "loop_analysis.h" |
Ian Romanick | a87ac25 | 2010-02-22 13:19:34 -0800 | [diff] [blame] | 38 | |
Paul Berry | d9bfaa1 | 2012-08-01 18:36:57 -0700 | [diff] [blame] | 39 | /** |
| 40 | * Format a short human-readable description of the given GLSL version. |
| 41 | */ |
| 42 | const char * |
| 43 | glsl_compute_version_string(void *mem_ctx, bool is_es, unsigned version) |
| 44 | { |
| 45 | return ralloc_asprintf(mem_ctx, "GLSL%s %d.%02d", is_es ? " ES" : "", |
| 46 | version / 100, version % 100); |
| 47 | } |
| 48 | |
Paul Berry | f8426ee | 2013-02-05 15:07:26 -0800 | [diff] [blame] | 49 | |
Chia-I Wu | 267e28b | 2014-04-22 16:58:16 +0800 | [diff] [blame] | 50 | static const unsigned known_desktop_glsl_versions[] = |
Jordan Justen | cd1b0f0 | 2014-11-24 13:56:29 -0800 | [diff] [blame] | 51 | { 110, 120, 130, 140, 150, 330, 400, 410, 420, 430, 440, 450 }; |
Paul Berry | f8426ee | 2013-02-05 15:07:26 -0800 | [diff] [blame] | 52 | |
| 53 | |
Dylan Noblesmith | 8c99906 | 2012-04-02 16:14:31 +0000 | [diff] [blame] | 54 | _mesa_glsl_parse_state::_mesa_glsl_parse_state(struct gl_context *_ctx, |
Paul Berry | 9110078 | 2014-01-07 09:46:10 -0800 | [diff] [blame] | 55 | gl_shader_stage stage, |
| 56 | void *mem_ctx) |
Paul Berry | 0fa74e8 | 2014-01-06 09:09:31 -0800 | [diff] [blame] | 57 | : ctx(_ctx), cs_input_local_size_specified(false), cs_input_local_size(), |
| 58 | switch_state() |
Ian Romanick | 2462a53 | 2010-07-18 15:59:43 -0700 | [diff] [blame] | 59 | { |
Paul Berry | 9110078 | 2014-01-07 09:46:10 -0800 | [diff] [blame] | 60 | assert(stage < MESA_SHADER_STAGES); |
| 61 | this->stage = stage; |
Ian Romanick | 2462a53 | 2010-07-18 15:59:43 -0700 | [diff] [blame] | 62 | |
| 63 | this->scanner = NULL; |
| 64 | this->translation_unit.make_empty(); |
| 65 | this->symbols = new(mem_ctx) glsl_symbol_table; |
Francisco Jerez | 43bf36b | 2013-09-11 20:07:53 -0700 | [diff] [blame] | 66 | |
Kenneth Graunke | d3073f5 | 2011-01-21 14:32:31 -0800 | [diff] [blame] | 67 | this->info_log = ralloc_strdup(mem_ctx, ""); |
Ian Romanick | 2462a53 | 2010-07-18 15:59:43 -0700 | [diff] [blame] | 68 | this->error = false; |
Dan McCabe | 5c02e2e | 2011-11-07 16:17:58 -0800 | [diff] [blame] | 69 | this->loop_nesting_ast = NULL; |
Kenneth Graunke | 814c89a | 2010-09-05 00:31:28 -0700 | [diff] [blame] | 70 | |
Ian Romanick | d9bb8b7 | 2013-08-13 09:15:01 -0700 | [diff] [blame] | 71 | this->struct_specifier_depth = 0; |
Kenneth Graunke | 5b331f6 | 2013-11-23 12:11:34 -0800 | [diff] [blame] | 72 | |
| 73 | this->uses_builtin_functions = false; |
Kenneth Graunke | 0fabf8e | 2011-09-19 18:30:15 -0700 | [diff] [blame] | 74 | |
Kenneth Graunke | 814c89a | 2010-09-05 00:31:28 -0700 | [diff] [blame] | 75 | /* Set default language version and extensions */ |
Brian Paul | dbe67d7 | 2015-03-27 10:54:10 -0600 | [diff] [blame] | 76 | this->language_version = 110; |
| 77 | this->forced_language_version = ctx->Const.ForceGLSLVersion; |
Kenneth Graunke | 719caa4 | 2010-08-16 12:34:53 -0700 | [diff] [blame] | 78 | this->es_shader = false; |
Ian Romanick | 2462a53 | 2010-07-18 15:59:43 -0700 | [diff] [blame] | 79 | this->ARB_texture_rectangle_enable = true; |
| 80 | |
Chia-I Wu | dc75458 | 2010-09-08 18:48:12 +0800 | [diff] [blame] | 81 | /* OpenGL ES 2.0 has different defaults from desktop GL. */ |
| 82 | if (ctx->API == API_OPENGLES2) { |
| 83 | this->language_version = 100; |
| 84 | this->es_shader = true; |
| 85 | this->ARB_texture_rectangle_enable = false; |
Ian Romanick | 2462a53 | 2010-07-18 15:59:43 -0700 | [diff] [blame] | 86 | } |
Chia-I Wu | dc75458 | 2010-09-08 18:48:12 +0800 | [diff] [blame] | 87 | |
| 88 | this->extensions = &ctx->Extensions; |
| 89 | |
| 90 | this->Const.MaxLights = ctx->Const.MaxLights; |
| 91 | this->Const.MaxClipPlanes = ctx->Const.MaxClipPlanes; |
| 92 | this->Const.MaxTextureUnits = ctx->Const.MaxTextureUnits; |
| 93 | this->Const.MaxTextureCoords = ctx->Const.MaxTextureCoordUnits; |
Paul Berry | 84732a9 | 2014-01-08 10:00:28 -0800 | [diff] [blame] | 94 | this->Const.MaxVertexAttribs = ctx->Const.Program[MESA_SHADER_VERTEX].MaxAttribs; |
| 95 | this->Const.MaxVertexUniformComponents = ctx->Const.Program[MESA_SHADER_VERTEX].MaxUniformComponents; |
| 96 | this->Const.MaxVertexTextureImageUnits = ctx->Const.Program[MESA_SHADER_VERTEX].MaxTextureImageUnits; |
Chia-I Wu | dc75458 | 2010-09-08 18:48:12 +0800 | [diff] [blame] | 97 | this->Const.MaxCombinedTextureImageUnits = ctx->Const.MaxCombinedTextureImageUnits; |
Paul Berry | 84732a9 | 2014-01-08 10:00:28 -0800 | [diff] [blame] | 98 | this->Const.MaxTextureImageUnits = ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxTextureImageUnits; |
| 99 | this->Const.MaxFragmentUniformComponents = ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxUniformComponents; |
Paul Berry | 5e10a5c | 2012-08-04 10:00:20 -0700 | [diff] [blame] | 100 | this->Const.MinProgramTexelOffset = ctx->Const.MinProgramTexelOffset; |
| 101 | this->Const.MaxProgramTexelOffset = ctx->Const.MaxProgramTexelOffset; |
Chia-I Wu | dc75458 | 2010-09-08 18:48:12 +0800 | [diff] [blame] | 102 | |
| 103 | this->Const.MaxDrawBuffers = ctx->Const.MaxDrawBuffers; |
Ian Romanick | 14880a5 | 2011-01-31 15:02:24 -0800 | [diff] [blame] | 104 | |
Ryan Houdek | ceecb08 | 2015-11-05 10:53:40 -0600 | [diff] [blame] | 105 | this->Const.MaxDualSourceDrawBuffers = ctx->Const.MaxDualSourceDrawBuffers; |
| 106 | |
Paul Berry | 2910a82 | 2013-07-26 11:55:52 -0700 | [diff] [blame] | 107 | /* 1.50 constants */ |
Paul Berry | 84732a9 | 2014-01-08 10:00:28 -0800 | [diff] [blame] | 108 | this->Const.MaxVertexOutputComponents = ctx->Const.Program[MESA_SHADER_VERTEX].MaxOutputComponents; |
| 109 | this->Const.MaxGeometryInputComponents = ctx->Const.Program[MESA_SHADER_GEOMETRY].MaxInputComponents; |
| 110 | this->Const.MaxGeometryOutputComponents = ctx->Const.Program[MESA_SHADER_GEOMETRY].MaxOutputComponents; |
| 111 | this->Const.MaxFragmentInputComponents = ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxInputComponents; |
| 112 | this->Const.MaxGeometryTextureImageUnits = ctx->Const.Program[MESA_SHADER_GEOMETRY].MaxTextureImageUnits; |
Paul Berry | 2910a82 | 2013-07-26 11:55:52 -0700 | [diff] [blame] | 113 | this->Const.MaxGeometryOutputVertices = ctx->Const.MaxGeometryOutputVertices; |
| 114 | this->Const.MaxGeometryTotalOutputComponents = ctx->Const.MaxGeometryTotalOutputComponents; |
Paul Berry | 84732a9 | 2014-01-08 10:00:28 -0800 | [diff] [blame] | 115 | this->Const.MaxGeometryUniformComponents = ctx->Const.Program[MESA_SHADER_GEOMETRY].MaxUniformComponents; |
Paul Berry | 2910a82 | 2013-07-26 11:55:52 -0700 | [diff] [blame] | 116 | |
Paul Berry | 84732a9 | 2014-01-08 10:00:28 -0800 | [diff] [blame] | 117 | this->Const.MaxVertexAtomicCounters = ctx->Const.Program[MESA_SHADER_VERTEX].MaxAtomicCounters; |
Chris Forbes | da7adb9 | 2014-08-17 22:37:16 +1200 | [diff] [blame] | 118 | this->Const.MaxTessControlAtomicCounters = ctx->Const.Program[MESA_SHADER_TESS_CTRL].MaxAtomicCounters; |
| 119 | this->Const.MaxTessEvaluationAtomicCounters = ctx->Const.Program[MESA_SHADER_TESS_EVAL].MaxAtomicCounters; |
Paul Berry | 84732a9 | 2014-01-08 10:00:28 -0800 | [diff] [blame] | 120 | this->Const.MaxGeometryAtomicCounters = ctx->Const.Program[MESA_SHADER_GEOMETRY].MaxAtomicCounters; |
| 121 | this->Const.MaxFragmentAtomicCounters = ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxAtomicCounters; |
Francisco Jerez | bbded5b | 2013-10-20 12:39:16 -0700 | [diff] [blame] | 122 | this->Const.MaxCombinedAtomicCounters = ctx->Const.MaxCombinedAtomicCounters; |
| 123 | this->Const.MaxAtomicBufferBindings = ctx->Const.MaxAtomicBufferBindings; |
Ian Romanick | ad14f44 | 2015-04-28 12:50:51 -0700 | [diff] [blame] | 124 | this->Const.MaxVertexAtomicCounterBuffers = |
| 125 | ctx->Const.Program[MESA_SHADER_VERTEX].MaxAtomicBuffers; |
Chris Forbes | da7adb9 | 2014-08-17 22:37:16 +1200 | [diff] [blame] | 126 | this->Const.MaxTessControlAtomicCounterBuffers = |
| 127 | ctx->Const.Program[MESA_SHADER_TESS_CTRL].MaxAtomicBuffers; |
| 128 | this->Const.MaxTessEvaluationAtomicCounterBuffers = |
| 129 | ctx->Const.Program[MESA_SHADER_TESS_EVAL].MaxAtomicBuffers; |
Ian Romanick | ad14f44 | 2015-04-28 12:50:51 -0700 | [diff] [blame] | 130 | this->Const.MaxGeometryAtomicCounterBuffers = |
| 131 | ctx->Const.Program[MESA_SHADER_GEOMETRY].MaxAtomicBuffers; |
| 132 | this->Const.MaxFragmentAtomicCounterBuffers = |
| 133 | ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxAtomicBuffers; |
| 134 | this->Const.MaxCombinedAtomicCounterBuffers = |
| 135 | ctx->Const.MaxCombinedAtomicBuffers; |
| 136 | this->Const.MaxAtomicCounterBufferSize = |
| 137 | ctx->Const.MaxAtomicBufferSize; |
Francisco Jerez | bbded5b | 2013-10-20 12:39:16 -0700 | [diff] [blame] | 138 | |
Paul Berry | 347dde8 | 2014-01-06 13:31:58 -0800 | [diff] [blame] | 139 | /* Compute shader constants */ |
Brian Paul | c16c719 | 2015-02-28 09:11:23 -0700 | [diff] [blame] | 140 | for (unsigned i = 0; i < ARRAY_SIZE(this->Const.MaxComputeWorkGroupCount); i++) |
Paul Berry | 0398b69 | 2014-01-08 01:42:58 -0800 | [diff] [blame] | 141 | this->Const.MaxComputeWorkGroupCount[i] = ctx->Const.MaxComputeWorkGroupCount[i]; |
Brian Paul | c16c719 | 2015-02-28 09:11:23 -0700 | [diff] [blame] | 142 | for (unsigned i = 0; i < ARRAY_SIZE(this->Const.MaxComputeWorkGroupSize); i++) |
Paul Berry | 347dde8 | 2014-01-06 13:31:58 -0800 | [diff] [blame] | 143 | this->Const.MaxComputeWorkGroupSize[i] = ctx->Const.MaxComputeWorkGroupSize[i]; |
| 144 | |
Francisco Jerez | 87acc7c | 2014-02-12 17:15:21 +0100 | [diff] [blame] | 145 | this->Const.MaxImageUnits = ctx->Const.MaxImageUnits; |
Francisco Jerez | 47e0d5b | 2015-08-17 19:10:46 +0300 | [diff] [blame] | 146 | this->Const.MaxCombinedShaderOutputResources = ctx->Const.MaxCombinedShaderOutputResources; |
Francisco Jerez | 87acc7c | 2014-02-12 17:15:21 +0100 | [diff] [blame] | 147 | this->Const.MaxImageSamples = ctx->Const.MaxImageSamples; |
| 148 | this->Const.MaxVertexImageUniforms = ctx->Const.Program[MESA_SHADER_VERTEX].MaxImageUniforms; |
Chris Forbes | da7adb9 | 2014-08-17 22:37:16 +1200 | [diff] [blame] | 149 | this->Const.MaxTessControlImageUniforms = ctx->Const.Program[MESA_SHADER_TESS_CTRL].MaxImageUniforms; |
| 150 | this->Const.MaxTessEvaluationImageUniforms = ctx->Const.Program[MESA_SHADER_TESS_EVAL].MaxImageUniforms; |
Francisco Jerez | 87acc7c | 2014-02-12 17:15:21 +0100 | [diff] [blame] | 151 | this->Const.MaxGeometryImageUniforms = ctx->Const.Program[MESA_SHADER_GEOMETRY].MaxImageUniforms; |
| 152 | this->Const.MaxFragmentImageUniforms = ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxImageUniforms; |
| 153 | this->Const.MaxCombinedImageUniforms = ctx->Const.MaxCombinedImageUniforms; |
| 154 | |
Maxence Le Doré | 19e05d6 | 2014-12-10 08:09:24 +0100 | [diff] [blame] | 155 | /* ARB_viewport_array */ |
| 156 | this->Const.MaxViewports = ctx->Const.MaxViewports; |
| 157 | |
Fabian Bieler | 497eb29 | 2014-03-20 22:44:43 +0100 | [diff] [blame] | 158 | /* tessellation shader constants */ |
| 159 | this->Const.MaxPatchVertices = ctx->Const.MaxPatchVertices; |
Chris Forbes | da7adb9 | 2014-08-17 22:37:16 +1200 | [diff] [blame] | 160 | this->Const.MaxTessGenLevel = ctx->Const.MaxTessGenLevel; |
| 161 | this->Const.MaxTessControlInputComponents = ctx->Const.Program[MESA_SHADER_TESS_CTRL].MaxInputComponents; |
| 162 | this->Const.MaxTessControlOutputComponents = ctx->Const.Program[MESA_SHADER_TESS_CTRL].MaxOutputComponents; |
| 163 | this->Const.MaxTessControlTextureImageUnits = ctx->Const.Program[MESA_SHADER_TESS_CTRL].MaxTextureImageUnits; |
| 164 | this->Const.MaxTessEvaluationInputComponents = ctx->Const.Program[MESA_SHADER_TESS_EVAL].MaxInputComponents; |
| 165 | this->Const.MaxTessEvaluationOutputComponents = ctx->Const.Program[MESA_SHADER_TESS_EVAL].MaxOutputComponents; |
| 166 | this->Const.MaxTessEvaluationTextureImageUnits = ctx->Const.Program[MESA_SHADER_TESS_EVAL].MaxTextureImageUnits; |
| 167 | this->Const.MaxTessPatchComponents = ctx->Const.MaxTessPatchComponents; |
| 168 | this->Const.MaxTessControlTotalOutputComponents = ctx->Const.MaxTessControlTotalOutputComponents; |
| 169 | this->Const.MaxTessControlUniformComponents = ctx->Const.Program[MESA_SHADER_TESS_CTRL].MaxUniformComponents; |
| 170 | this->Const.MaxTessEvaluationUniformComponents = ctx->Const.Program[MESA_SHADER_TESS_EVAL].MaxUniformComponents; |
Fabian Bieler | 497eb29 | 2014-03-20 22:44:43 +0100 | [diff] [blame] | 171 | |
Francisco Jerez | 43bf36b | 2013-09-11 20:07:53 -0700 | [diff] [blame] | 172 | this->current_function = NULL; |
| 173 | this->toplevel_ir = NULL; |
| 174 | this->found_return = false; |
| 175 | this->all_invariant = false; |
| 176 | this->user_structures = NULL; |
| 177 | this->num_user_structures = 0; |
Dave Airlie | 65ac360 | 2015-06-01 10:55:47 +1000 | [diff] [blame] | 178 | this->num_subroutines = 0; |
| 179 | this->subroutines = NULL; |
| 180 | this->num_subroutine_types = 0; |
| 181 | this->subroutine_types = NULL; |
Francisco Jerez | 43bf36b | 2013-09-11 20:07:53 -0700 | [diff] [blame] | 182 | |
Jordan Justen | cd1b0f0 | 2014-11-24 13:56:29 -0800 | [diff] [blame] | 183 | /* supported_versions should be large enough to support the known desktop |
Ian Romanick | 7038370 | 2015-04-28 12:13:21 -0700 | [diff] [blame] | 184 | * GLSL versions plus 3 GLES versions (ES 1.00, ES 3.00, and ES 3.10)) |
Jordan Justen | cd1b0f0 | 2014-11-24 13:56:29 -0800 | [diff] [blame] | 185 | */ |
Ian Romanick | 7038370 | 2015-04-28 12:13:21 -0700 | [diff] [blame] | 186 | STATIC_ASSERT((ARRAY_SIZE(known_desktop_glsl_versions) + 3) == |
Jordan Justen | cd1b0f0 | 2014-11-24 13:56:29 -0800 | [diff] [blame] | 187 | ARRAY_SIZE(this->supported_versions)); |
| 188 | |
Paul Berry | f8426ee | 2013-02-05 15:07:26 -0800 | [diff] [blame] | 189 | /* Populate the list of supported GLSL versions */ |
| 190 | /* FINISHME: Once the OpenGL 3.0 'forward compatible' context or |
| 191 | * the OpenGL 3.2 Core context is supported, this logic will need |
| 192 | * change. Older versions of GLSL are no longer supported |
| 193 | * outside the compatibility contexts of 3.x. |
| 194 | */ |
| 195 | this->num_supported_versions = 0; |
| 196 | if (_mesa_is_desktop_gl(ctx)) { |
| 197 | for (unsigned i = 0; i < ARRAY_SIZE(known_desktop_glsl_versions); i++) { |
| 198 | if (known_desktop_glsl_versions[i] <= ctx->Const.GLSLVersion) { |
| 199 | this->supported_versions[this->num_supported_versions].ver |
| 200 | = known_desktop_glsl_versions[i]; |
| 201 | this->supported_versions[this->num_supported_versions].es = false; |
| 202 | this->num_supported_versions++; |
| 203 | } |
| 204 | } |
| 205 | } |
| 206 | if (ctx->API == API_OPENGLES2 || ctx->Extensions.ARB_ES2_compatibility) { |
| 207 | this->supported_versions[this->num_supported_versions].ver = 100; |
| 208 | this->supported_versions[this->num_supported_versions].es = true; |
| 209 | this->num_supported_versions++; |
| 210 | } |
| 211 | if (_mesa_is_gles3(ctx) || ctx->Extensions.ARB_ES3_compatibility) { |
| 212 | this->supported_versions[this->num_supported_versions].ver = 300; |
| 213 | this->supported_versions[this->num_supported_versions].es = true; |
| 214 | this->num_supported_versions++; |
| 215 | } |
Ian Romanick | 7038370 | 2015-04-28 12:13:21 -0700 | [diff] [blame] | 216 | if (_mesa_is_gles31(ctx)) { |
| 217 | this->supported_versions[this->num_supported_versions].ver = 310; |
| 218 | this->supported_versions[this->num_supported_versions].es = true; |
| 219 | this->num_supported_versions++; |
| 220 | } |
Paul Berry | f8426ee | 2013-02-05 15:07:26 -0800 | [diff] [blame] | 221 | |
| 222 | /* Create a string for use in error messages to tell the user which GLSL |
| 223 | * versions are supported. |
| 224 | */ |
Kenneth Graunke | a7d3507 | 2011-02-01 00:20:01 -0800 | [diff] [blame] | 225 | char *supported = ralloc_strdup(this, ""); |
Paul Berry | f8426ee | 2013-02-05 15:07:26 -0800 | [diff] [blame] | 226 | for (unsigned i = 0; i < this->num_supported_versions; i++) { |
| 227 | unsigned ver = this->supported_versions[i].ver; |
| 228 | const char *const prefix = (i == 0) |
Ian Romanick | 14880a5 | 2011-01-31 15:02:24 -0800 | [diff] [blame] | 229 | ? "" |
Paul Berry | f8426ee | 2013-02-05 15:07:26 -0800 | [diff] [blame] | 230 | : ((i == this->num_supported_versions - 1) ? ", and " : ", "); |
| 231 | const char *const suffix = (this->supported_versions[i].es) ? " ES" : ""; |
Ian Romanick | 14880a5 | 2011-01-31 15:02:24 -0800 | [diff] [blame] | 232 | |
Paul Berry | f8426ee | 2013-02-05 15:07:26 -0800 | [diff] [blame] | 233 | ralloc_asprintf_append(& supported, "%s%u.%02u%s", |
Ian Romanick | 14880a5 | 2011-01-31 15:02:24 -0800 | [diff] [blame] | 234 | prefix, |
| 235 | ver / 100, ver % 100, |
Paul Berry | f8426ee | 2013-02-05 15:07:26 -0800 | [diff] [blame] | 236 | suffix); |
Ian Romanick | 14880a5 | 2011-01-31 15:02:24 -0800 | [diff] [blame] | 237 | } |
| 238 | |
| 239 | this->supported_version_string = supported; |
Eric Anholt | b9e27cc | 2012-01-18 12:14:09 -0800 | [diff] [blame] | 240 | |
| 241 | if (ctx->Const.ForceGLSLExtensionsWarn) |
| 242 | _mesa_glsl_process_extension("all", NULL, "warn", NULL, this); |
Eric Anholt | 551bdf2 | 2012-06-22 13:36:35 -0700 | [diff] [blame] | 243 | |
| 244 | this->default_uniform_qualifier = new(this) ast_type_qualifier(); |
| 245 | this->default_uniform_qualifier->flags.q.shared = 1; |
| 246 | this->default_uniform_qualifier->flags.q.column_major = 1; |
Samuel Iglesias Gonsalvez | 9c1f10b | 2015-09-03 09:47:56 +0200 | [diff] [blame] | 247 | this->default_uniform_qualifier->is_default_qualifier = true; |
Eric Anholt | 624b7ba | 2013-06-12 14:03:49 -0700 | [diff] [blame] | 248 | |
Samuel Iglesias Gonsalvez | a40f917 | 2015-09-03 12:00:16 +0200 | [diff] [blame] | 249 | this->default_shader_storage_qualifier = new(this) ast_type_qualifier(); |
| 250 | this->default_shader_storage_qualifier->flags.q.shared = 1; |
| 251 | this->default_shader_storage_qualifier->flags.q.column_major = 1; |
| 252 | this->default_shader_storage_qualifier->is_default_qualifier = true; |
| 253 | |
Anuj Phogat | 35f11e8 | 2014-02-05 15:01:58 -0800 | [diff] [blame] | 254 | this->fs_uses_gl_fragcoord = false; |
| 255 | this->fs_redeclares_gl_fragcoord = false; |
| 256 | this->fs_origin_upper_left = false; |
| 257 | this->fs_pixel_center_integer = false; |
| 258 | this->fs_redeclares_gl_fragcoord_with_no_layout_qualifiers = false; |
| 259 | |
Eric Anholt | 624b7ba | 2013-06-12 14:03:49 -0700 | [diff] [blame] | 260 | this->gs_input_prim_type_specified = false; |
Fabian Bieler | 497eb29 | 2014-03-20 22:44:43 +0100 | [diff] [blame] | 261 | this->tcs_output_vertices_specified = false; |
Francisco Jerez | 43bf36b | 2013-09-11 20:07:53 -0700 | [diff] [blame] | 262 | this->gs_input_size = 0; |
Jordan Justen | 0c558f9 | 2014-02-02 17:49:15 -0800 | [diff] [blame] | 263 | this->in_qualifier = new(this) ast_type_qualifier(); |
Eric Anholt | 624b7ba | 2013-06-12 14:03:49 -0700 | [diff] [blame] | 264 | this->out_qualifier = new(this) ast_type_qualifier(); |
Francisco Jerez | ce0e151 | 2015-01-28 17:42:37 +0200 | [diff] [blame] | 265 | this->fs_early_fragment_tests = false; |
Francisco Jerez | 6b2b4cc | 2013-11-26 12:43:13 -0800 | [diff] [blame] | 266 | memset(this->atomic_counter_offsets, 0, |
| 267 | sizeof(this->atomic_counter_offsets)); |
Marek Olšák | b0ff18b | 2014-07-08 20:20:22 +0200 | [diff] [blame] | 268 | this->allow_extension_directive_midshader = |
| 269 | ctx->Const.AllowGLSLExtensionDirectiveMidShader; |
Ian Romanick | 2462a53 | 2010-07-18 15:59:43 -0700 | [diff] [blame] | 270 | } |
| 271 | |
Paul Berry | 5d0fd32 | 2012-08-01 19:09:24 -0700 | [diff] [blame] | 272 | /** |
| 273 | * Determine whether the current GLSL version is sufficiently high to support |
| 274 | * a certain feature, and generate an error message if it isn't. |
| 275 | * |
| 276 | * \param required_glsl_version and \c required_glsl_es_version are |
| 277 | * interpreted as they are in _mesa_glsl_parse_state::is_version(). |
| 278 | * |
| 279 | * \param locp is the parser location where the error should be reported. |
| 280 | * |
| 281 | * \param fmt (and additional arguments) constitute a printf-style error |
| 282 | * message to report if the version check fails. Information about the |
| 283 | * current and required GLSL versions will be appended. So, for example, if |
| 284 | * the GLSL version being compiled is 1.20, and check_version(130, 300, locp, |
| 285 | * "foo unsupported") is called, the error message will be "foo unsupported in |
| 286 | * GLSL 1.20 (GLSL 1.30 or GLSL 3.00 ES required)". |
| 287 | */ |
| 288 | bool |
| 289 | _mesa_glsl_parse_state::check_version(unsigned required_glsl_version, |
| 290 | unsigned required_glsl_es_version, |
| 291 | YYLTYPE *locp, const char *fmt, ...) |
| 292 | { |
| 293 | if (this->is_version(required_glsl_version, required_glsl_es_version)) |
| 294 | return true; |
| 295 | |
| 296 | va_list args; |
| 297 | va_start(args, fmt); |
Dave Airlie | a9abaaa | 2012-12-16 11:47:01 +1000 | [diff] [blame] | 298 | char *problem = ralloc_vasprintf(this, fmt, args); |
Paul Berry | 5d0fd32 | 2012-08-01 19:09:24 -0700 | [diff] [blame] | 299 | va_end(args); |
| 300 | const char *glsl_version_string |
Kenneth Graunke | 12f3b3d | 2012-12-17 11:20:53 -0800 | [diff] [blame] | 301 | = glsl_compute_version_string(this, false, required_glsl_version); |
Paul Berry | 5d0fd32 | 2012-08-01 19:09:24 -0700 | [diff] [blame] | 302 | const char *glsl_es_version_string |
Kenneth Graunke | 12f3b3d | 2012-12-17 11:20:53 -0800 | [diff] [blame] | 303 | = glsl_compute_version_string(this, true, required_glsl_es_version); |
Paul Berry | 5d0fd32 | 2012-08-01 19:09:24 -0700 | [diff] [blame] | 304 | const char *requirement_string = ""; |
| 305 | if (required_glsl_version && required_glsl_es_version) { |
Dave Airlie | a9abaaa | 2012-12-16 11:47:01 +1000 | [diff] [blame] | 306 | requirement_string = ralloc_asprintf(this, " (%s or %s required)", |
Paul Berry | 5d0fd32 | 2012-08-01 19:09:24 -0700 | [diff] [blame] | 307 | glsl_version_string, |
| 308 | glsl_es_version_string); |
| 309 | } else if (required_glsl_version) { |
Dave Airlie | a9abaaa | 2012-12-16 11:47:01 +1000 | [diff] [blame] | 310 | requirement_string = ralloc_asprintf(this, " (%s required)", |
Paul Berry | 5d0fd32 | 2012-08-01 19:09:24 -0700 | [diff] [blame] | 311 | glsl_version_string); |
| 312 | } else if (required_glsl_es_version) { |
Dave Airlie | a9abaaa | 2012-12-16 11:47:01 +1000 | [diff] [blame] | 313 | requirement_string = ralloc_asprintf(this, " (%s required)", |
Paul Berry | 5d0fd32 | 2012-08-01 19:09:24 -0700 | [diff] [blame] | 314 | glsl_es_version_string); |
| 315 | } |
Paul Berry | 4d7899f | 2013-07-25 19:56:43 -0700 | [diff] [blame] | 316 | _mesa_glsl_error(locp, this, "%s in %s%s", |
Paul Berry | 5d0fd32 | 2012-08-01 19:09:24 -0700 | [diff] [blame] | 317 | problem, this->get_version_string(), |
| 318 | requirement_string); |
| 319 | |
| 320 | return false; |
| 321 | } |
| 322 | |
Paul Berry | 629b9ed | 2012-08-02 11:02:55 -0700 | [diff] [blame] | 323 | /** |
| 324 | * Process a GLSL #version directive. |
| 325 | * |
| 326 | * \param version is the integer that follows the #version token. |
Paul Berry | 2b4aedd | 2012-08-02 11:17:30 -0700 | [diff] [blame] | 327 | * |
| 328 | * \param ident is a string identifier that follows the integer, if any is |
| 329 | * present. Otherwise NULL. |
Paul Berry | 629b9ed | 2012-08-02 11:02:55 -0700 | [diff] [blame] | 330 | */ |
| 331 | void |
Paul Berry | 2b4aedd | 2012-08-02 11:17:30 -0700 | [diff] [blame] | 332 | _mesa_glsl_parse_state::process_version_directive(YYLTYPE *locp, int version, |
| 333 | const char *ident) |
Paul Berry | 629b9ed | 2012-08-02 11:02:55 -0700 | [diff] [blame] | 334 | { |
Paul Berry | 2b4aedd | 2012-08-02 11:17:30 -0700 | [diff] [blame] | 335 | bool es_token_present = false; |
| 336 | if (ident) { |
| 337 | if (strcmp(ident, "es") == 0) { |
| 338 | es_token_present = true; |
Kenneth Graunke | e203919 | 2013-06-07 21:28:59 -0700 | [diff] [blame] | 339 | } else if (version >= 150) { |
| 340 | if (strcmp(ident, "core") == 0) { |
| 341 | /* Accept the token. There's no need to record that this is |
| 342 | * a core profile shader since that's the only profile we support. |
| 343 | */ |
| 344 | } else if (strcmp(ident, "compatibility") == 0) { |
| 345 | _mesa_glsl_error(locp, this, |
Paul Berry | 4d7899f | 2013-07-25 19:56:43 -0700 | [diff] [blame] | 346 | "the compatibility profile is not supported"); |
Kenneth Graunke | e203919 | 2013-06-07 21:28:59 -0700 | [diff] [blame] | 347 | } else { |
| 348 | _mesa_glsl_error(locp, this, |
| 349 | "\"%s\" is not a valid shading language profile; " |
Paul Berry | 4d7899f | 2013-07-25 19:56:43 -0700 | [diff] [blame] | 350 | "if present, it must be \"core\"", ident); |
Kenneth Graunke | e203919 | 2013-06-07 21:28:59 -0700 | [diff] [blame] | 351 | } |
Paul Berry | 2b4aedd | 2012-08-02 11:17:30 -0700 | [diff] [blame] | 352 | } else { |
| 353 | _mesa_glsl_error(locp, this, |
Paul Berry | 4d7899f | 2013-07-25 19:56:43 -0700 | [diff] [blame] | 354 | "illegal text following version number"); |
Paul Berry | 2b4aedd | 2012-08-02 11:17:30 -0700 | [diff] [blame] | 355 | } |
| 356 | } |
| 357 | |
Paul Berry | f8426ee | 2013-02-05 15:07:26 -0800 | [diff] [blame] | 358 | this->es_shader = es_token_present; |
| 359 | if (version == 100) { |
| 360 | if (es_token_present) { |
Paul Berry | 2b4aedd | 2012-08-02 11:17:30 -0700 | [diff] [blame] | 361 | _mesa_glsl_error(locp, this, |
| 362 | "GLSL 1.00 ES should be selected using " |
Paul Berry | 4d7899f | 2013-07-25 19:56:43 -0700 | [diff] [blame] | 363 | "`#version 100'"); |
Paul Berry | f8426ee | 2013-02-05 15:07:26 -0800 | [diff] [blame] | 364 | } else { |
Paul Berry | 2b4aedd | 2012-08-02 11:17:30 -0700 | [diff] [blame] | 365 | this->es_shader = true; |
Paul Berry | 2b4aedd | 2012-08-02 11:17:30 -0700 | [diff] [blame] | 366 | } |
Paul Berry | 629b9ed | 2012-08-02 11:02:55 -0700 | [diff] [blame] | 367 | } |
| 368 | |
Anuj Phogat | c907595 | 2014-01-17 12:23:05 -0800 | [diff] [blame] | 369 | if (this->es_shader) { |
| 370 | this->ARB_texture_rectangle_enable = false; |
| 371 | } |
| 372 | |
Brian Paul | dbe67d7 | 2015-03-27 10:54:10 -0600 | [diff] [blame] | 373 | if (this->forced_language_version) |
| 374 | this->language_version = this->forced_language_version; |
| 375 | else |
| 376 | this->language_version = version; |
Paul Berry | 629b9ed | 2012-08-02 11:02:55 -0700 | [diff] [blame] | 377 | |
Paul Berry | f8426ee | 2013-02-05 15:07:26 -0800 | [diff] [blame] | 378 | bool supported = false; |
| 379 | for (unsigned i = 0; i < this->num_supported_versions; i++) { |
Brian Paul | dbe67d7 | 2015-03-27 10:54:10 -0600 | [diff] [blame] | 380 | if (this->supported_versions[i].ver == this->language_version |
Paul Berry | f8426ee | 2013-02-05 15:07:26 -0800 | [diff] [blame] | 381 | && this->supported_versions[i].es == this->es_shader) { |
| 382 | supported = true; |
| 383 | break; |
| 384 | } |
| 385 | } |
| 386 | |
Paul Berry | 629b9ed | 2012-08-02 11:02:55 -0700 | [diff] [blame] | 387 | if (!supported) { |
| 388 | _mesa_glsl_error(locp, this, "%s is not supported. " |
Paul Berry | 4d7899f | 2013-07-25 19:56:43 -0700 | [diff] [blame] | 389 | "Supported versions are: %s", |
Paul Berry | 629b9ed | 2012-08-02 11:02:55 -0700 | [diff] [blame] | 390 | this->get_version_string(), |
| 391 | this->supported_version_string); |
Paul Berry | 2b4aedd | 2012-08-02 11:17:30 -0700 | [diff] [blame] | 392 | |
| 393 | /* On exit, the language_version must be set to a valid value. |
| 394 | * Later calls to _mesa_glsl_initialize_types will misbehave if |
| 395 | * the version is invalid. |
| 396 | */ |
| 397 | switch (this->ctx->API) { |
| 398 | case API_OPENGL_COMPAT: |
| 399 | case API_OPENGL_CORE: |
| 400 | this->language_version = this->ctx->Const.GLSLVersion; |
| 401 | break; |
| 402 | |
| 403 | case API_OPENGLES: |
| 404 | assert(!"Should not get here."); |
| 405 | /* FALLTHROUGH */ |
| 406 | |
| 407 | case API_OPENGLES2: |
| 408 | this->language_version = 100; |
| 409 | break; |
| 410 | } |
Paul Berry | 629b9ed | 2012-08-02 11:02:55 -0700 | [diff] [blame] | 411 | } |
Paul Berry | 629b9ed | 2012-08-02 11:02:55 -0700 | [diff] [blame] | 412 | } |
| 413 | |
Eric Anholt | faf3dba | 2013-06-12 16:57:11 -0700 | [diff] [blame] | 414 | |
| 415 | /** |
Paul Berry | 665b8d7 | 2014-01-07 10:11:39 -0800 | [diff] [blame] | 416 | * Translate a gl_shader_stage to a short shader stage name for debug |
| 417 | * printouts and error messages. |
Eric Anholt | faf3dba | 2013-06-12 16:57:11 -0700 | [diff] [blame] | 418 | */ |
Ian Romanick | 5bfe30a | 2010-04-07 16:44:30 -0700 | [diff] [blame] | 419 | const char * |
Paul Berry | 665b8d7 | 2014-01-07 10:11:39 -0800 | [diff] [blame] | 420 | _mesa_shader_stage_to_string(unsigned stage) |
Ian Romanick | 5bfe30a | 2010-04-07 16:44:30 -0700 | [diff] [blame] | 421 | { |
Paul Berry | 665b8d7 | 2014-01-07 10:11:39 -0800 | [diff] [blame] | 422 | switch (stage) { |
Paul Berry | 7963fde | 2013-12-16 13:09:20 -0800 | [diff] [blame] | 423 | case MESA_SHADER_VERTEX: return "vertex"; |
| 424 | case MESA_SHADER_FRAGMENT: return "fragment"; |
| 425 | case MESA_SHADER_GEOMETRY: return "geometry"; |
Kenneth Graunke | 75f6ed6 | 2015-02-19 13:36:07 -0800 | [diff] [blame] | 426 | case MESA_SHADER_COMPUTE: return "compute"; |
Fabian Bieler | 497eb29 | 2014-03-20 22:44:43 +0100 | [diff] [blame] | 427 | case MESA_SHADER_TESS_CTRL: return "tess ctrl"; |
| 428 | case MESA_SHADER_TESS_EVAL: return "tess eval"; |
Ian Romanick | 5bfe30a | 2010-04-07 16:44:30 -0700 | [diff] [blame] | 429 | } |
| 430 | |
Kenneth Graunke | 75f6ed6 | 2015-02-19 13:36:07 -0800 | [diff] [blame] | 431 | unreachable("Unknown shader stage."); |
Ian Romanick | 5bfe30a | 2010-04-07 16:44:30 -0700 | [diff] [blame] | 432 | } |
| 433 | |
Kenneth Graunke | 7555d1ba | 2015-02-18 17:35:41 -0800 | [diff] [blame] | 434 | /** |
| 435 | * Translate a gl_shader_stage to a shader stage abbreviation (VS, GS, FS) |
| 436 | * for debug printouts and error messages. |
| 437 | */ |
| 438 | const char * |
| 439 | _mesa_shader_stage_to_abbrev(unsigned stage) |
| 440 | { |
| 441 | switch (stage) { |
| 442 | case MESA_SHADER_VERTEX: return "VS"; |
| 443 | case MESA_SHADER_FRAGMENT: return "FS"; |
| 444 | case MESA_SHADER_GEOMETRY: return "GS"; |
| 445 | case MESA_SHADER_COMPUTE: return "CS"; |
Fabian Bieler | 497eb29 | 2014-03-20 22:44:43 +0100 | [diff] [blame] | 446 | case MESA_SHADER_TESS_CTRL: return "TCS"; |
| 447 | case MESA_SHADER_TESS_EVAL: return "TES"; |
Kenneth Graunke | 7555d1ba | 2015-02-18 17:35:41 -0800 | [diff] [blame] | 448 | } |
| 449 | |
| 450 | unreachable("Unknown shader stage."); |
| 451 | } |
| 452 | |
Dylan Noblesmith | 48e8a01 | 2012-04-02 15:39:38 +0000 | [diff] [blame] | 453 | /* This helper function will append the given message to the shader's |
| 454 | info log and report it via GL_ARB_debug_output. Per that extension, |
| 455 | 'type' is one of the enum values classifying the message, and |
| 456 | 'id' is the implementation-defined ID of the given message. */ |
| 457 | static void |
| 458 | _mesa_glsl_msg(const YYLTYPE *locp, _mesa_glsl_parse_state *state, |
Eric Anholt | c72cf53 | 2013-02-22 15:57:25 -0800 | [diff] [blame] | 459 | GLenum type, const char *fmt, va_list ap) |
Dylan Noblesmith | 48e8a01 | 2012-04-02 15:39:38 +0000 | [diff] [blame] | 460 | { |
Eric Anholt | c72cf53 | 2013-02-22 15:57:25 -0800 | [diff] [blame] | 461 | bool error = (type == MESA_DEBUG_TYPE_ERROR); |
| 462 | GLuint msg_id = 0; |
Dylan Noblesmith | 48e8a01 | 2012-04-02 15:39:38 +0000 | [diff] [blame] | 463 | |
| 464 | assert(state->info_log != NULL); |
Dylan Noblesmith | d5a10db | 2012-04-02 16:26:05 +0000 | [diff] [blame] | 465 | |
| 466 | /* Get the offset that the new message will be written to. */ |
| 467 | int msg_offset = strlen(state->info_log); |
| 468 | |
Dylan Noblesmith | 48e8a01 | 2012-04-02 15:39:38 +0000 | [diff] [blame] | 469 | ralloc_asprintf_append(&state->info_log, "%u:%u(%u): %s: ", |
| 470 | locp->source, |
| 471 | locp->first_line, |
| 472 | locp->first_column, |
| 473 | error ? "error" : "warning"); |
| 474 | ralloc_vasprintf_append(&state->info_log, fmt, ap); |
Dylan Noblesmith | d5a10db | 2012-04-02 16:26:05 +0000 | [diff] [blame] | 475 | |
| 476 | const char *const msg = &state->info_log[msg_offset]; |
| 477 | struct gl_context *ctx = state->ctx; |
Eric Anholt | c72cf53 | 2013-02-22 15:57:25 -0800 | [diff] [blame] | 478 | |
Dylan Noblesmith | d5a10db | 2012-04-02 16:26:05 +0000 | [diff] [blame] | 479 | /* Report the error via GL_ARB_debug_output. */ |
Emil Velikov | d37ebed | 2015-11-27 13:12:59 +0000 | [diff] [blame] | 480 | _mesa_shader_debug(ctx, type, &msg_id, msg); |
Dylan Noblesmith | d5a10db | 2012-04-02 16:26:05 +0000 | [diff] [blame] | 481 | |
Dylan Noblesmith | 48e8a01 | 2012-04-02 15:39:38 +0000 | [diff] [blame] | 482 | ralloc_strcat(&state->info_log, "\n"); |
| 483 | } |
Ian Romanick | 5bfe30a | 2010-04-07 16:44:30 -0700 | [diff] [blame] | 484 | |
Ian Romanick | a87ac25 | 2010-02-22 13:19:34 -0800 | [diff] [blame] | 485 | void |
Ian Romanick | 1f58518 | 2010-03-11 14:08:33 -0800 | [diff] [blame] | 486 | _mesa_glsl_error(YYLTYPE *locp, _mesa_glsl_parse_state *state, |
| 487 | const char *fmt, ...) |
Ian Romanick | a87ac25 | 2010-02-22 13:19:34 -0800 | [diff] [blame] | 488 | { |
Ian Romanick | a87ac25 | 2010-02-22 13:19:34 -0800 | [diff] [blame] | 489 | va_list ap; |
| 490 | |
Ian Romanick | 71d0bbf | 2010-03-23 13:21:19 -0700 | [diff] [blame] | 491 | state->error = true; |
Ian Romanick | 1f58518 | 2010-03-11 14:08:33 -0800 | [diff] [blame] | 492 | |
Ian Romanick | a87ac25 | 2010-02-22 13:19:34 -0800 | [diff] [blame] | 493 | va_start(ap, fmt); |
Eric Anholt | c72cf53 | 2013-02-22 15:57:25 -0800 | [diff] [blame] | 494 | _mesa_glsl_msg(locp, state, MESA_DEBUG_TYPE_ERROR, fmt, ap); |
Ian Romanick | a87ac25 | 2010-02-22 13:19:34 -0800 | [diff] [blame] | 495 | va_end(ap); |
Ian Romanick | a87ac25 | 2010-02-22 13:19:34 -0800 | [diff] [blame] | 496 | } |
| 497 | |
| 498 | |
Ian Romanick | 56b8b21 | 2010-04-07 14:47:46 -0700 | [diff] [blame] | 499 | void |
Eric Anholt | 3623df6 | 2010-04-29 18:00:33 -0700 | [diff] [blame] | 500 | _mesa_glsl_warning(const YYLTYPE *locp, _mesa_glsl_parse_state *state, |
Ian Romanick | 56b8b21 | 2010-04-07 14:47:46 -0700 | [diff] [blame] | 501 | const char *fmt, ...) |
| 502 | { |
Ian Romanick | 56b8b21 | 2010-04-07 14:47:46 -0700 | [diff] [blame] | 503 | va_list ap; |
| 504 | |
Ian Romanick | 56b8b21 | 2010-04-07 14:47:46 -0700 | [diff] [blame] | 505 | va_start(ap, fmt); |
Eric Anholt | c72cf53 | 2013-02-22 15:57:25 -0800 | [diff] [blame] | 506 | _mesa_glsl_msg(locp, state, MESA_DEBUG_TYPE_OTHER, fmt, ap); |
Ian Romanick | 56b8b21 | 2010-04-07 14:47:46 -0700 | [diff] [blame] | 507 | va_end(ap); |
Ian Romanick | 56b8b21 | 2010-04-07 14:47:46 -0700 | [diff] [blame] | 508 | } |
| 509 | |
| 510 | |
Paul Berry | 3097715 | 2011-06-24 15:34:04 -0700 | [diff] [blame] | 511 | /** |
| 512 | * Enum representing the possible behaviors that can be specified in |
| 513 | * an #extension directive. |
| 514 | */ |
| 515 | enum ext_behavior { |
| 516 | extension_disable, |
| 517 | extension_enable, |
| 518 | extension_require, |
| 519 | extension_warn |
| 520 | }; |
Ian Romanick | e701761 | 2010-04-07 16:46:25 -0700 | [diff] [blame] | 521 | |
Paul Berry | 3097715 | 2011-06-24 15:34:04 -0700 | [diff] [blame] | 522 | /** |
| 523 | * Element type for _mesa_glsl_supported_extensions |
| 524 | */ |
| 525 | struct _mesa_glsl_extension { |
| 526 | /** |
| 527 | * Name of the extension when referred to in a GLSL extension |
| 528 | * statement |
| 529 | */ |
| 530 | const char *name; |
| 531 | |
Paul Berry | 3097715 | 2011-06-24 15:34:04 -0700 | [diff] [blame] | 532 | /** True if this extension is available to desktop GL shaders */ |
| 533 | bool avail_in_GL; |
| 534 | |
| 535 | /** True if this extension is available to GLES shaders */ |
| 536 | bool avail_in_ES; |
| 537 | |
| 538 | /** |
| 539 | * Flag in the gl_extensions struct indicating whether this |
| 540 | * extension is supported by the driver, or |
| 541 | * &gl_extensions::dummy_true if supported by all drivers. |
| 542 | * |
| 543 | * Note: the type (GLboolean gl_extensions::*) is a "pointer to |
| 544 | * member" type, the type-safe alternative to the "offsetof" macro. |
| 545 | * In a nutshell: |
| 546 | * |
| 547 | * - foo bar::* p declares p to be an "offset" to a field of type |
| 548 | * foo that exists within struct bar |
| 549 | * - &bar::baz computes the "offset" of field baz within struct bar |
| 550 | * - x.*p accesses the field of x that exists at "offset" p |
| 551 | * - x->*p is equivalent to (*x).*p |
| 552 | */ |
| 553 | const GLboolean gl_extensions::* supported_flag; |
| 554 | |
| 555 | /** |
| 556 | * Flag in the _mesa_glsl_parse_state struct that should be set |
| 557 | * when this extension is enabled. |
| 558 | * |
| 559 | * See note in _mesa_glsl_extension::supported_flag about "pointer |
| 560 | * to member" types. |
| 561 | */ |
| 562 | bool _mesa_glsl_parse_state::* enable_flag; |
| 563 | |
| 564 | /** |
| 565 | * Flag in the _mesa_glsl_parse_state struct that should be set |
| 566 | * when the shader requests "warn" behavior for this extension. |
| 567 | * |
| 568 | * See note in _mesa_glsl_extension::supported_flag about "pointer |
| 569 | * to member" types. |
| 570 | */ |
| 571 | bool _mesa_glsl_parse_state::* warn_flag; |
| 572 | |
| 573 | |
| 574 | bool compatible_with_state(const _mesa_glsl_parse_state *state) const; |
| 575 | void set_flags(_mesa_glsl_parse_state *state, ext_behavior behavior) const; |
| 576 | }; |
| 577 | |
Kenneth Graunke | 6aba035 | 2013-07-29 10:40:51 -0700 | [diff] [blame] | 578 | #define EXT(NAME, GL, ES, SUPPORTED_FLAG) \ |
| 579 | { "GL_" #NAME, GL, ES, &gl_extensions::SUPPORTED_FLAG, \ |
| 580 | &_mesa_glsl_parse_state::NAME##_enable, \ |
Paul Berry | 3097715 | 2011-06-24 15:34:04 -0700 | [diff] [blame] | 581 | &_mesa_glsl_parse_state::NAME##_warn } |
| 582 | |
| 583 | /** |
| 584 | * Table of extensions that can be enabled/disabled within a shader, |
| 585 | * and the conditions under which they are supported. |
| 586 | */ |
| 587 | static const _mesa_glsl_extension _mesa_glsl_supported_extensions[] = { |
Kenneth Graunke | 6aba035 | 2013-07-29 10:40:51 -0700 | [diff] [blame] | 588 | /* API availability */ |
| 589 | /* name GL ES supported flag */ |
Ian Romanick | 507b875 | 2014-03-26 11:43:32 -0700 | [diff] [blame] | 590 | |
| 591 | /* ARB extensions go here, sorted alphabetically. |
| 592 | */ |
Samuel Iglesias Gonsalvez | 3095ee9 | 2015-03-17 12:17:27 +0100 | [diff] [blame] | 593 | EXT(ARB_arrays_of_arrays, true, false, ARB_arrays_of_arrays), |
| 594 | EXT(ARB_compute_shader, true, false, ARB_compute_shader), |
| 595 | EXT(ARB_conservative_depth, true, false, ARB_conservative_depth), |
| 596 | EXT(ARB_derivative_control, true, false, ARB_derivative_control), |
| 597 | EXT(ARB_draw_buffers, true, false, dummy_true), |
| 598 | EXT(ARB_draw_instanced, true, false, ARB_draw_instanced), |
Timothy Arceri | 82e4f22 | 2015-10-05 00:01:45 +1100 | [diff] [blame] | 599 | EXT(ARB_enhanced_layouts, true, false, ARB_enhanced_layouts), |
Samuel Iglesias Gonsalvez | 3095ee9 | 2015-03-17 12:17:27 +0100 | [diff] [blame] | 600 | EXT(ARB_explicit_attrib_location, true, false, ARB_explicit_attrib_location), |
| 601 | EXT(ARB_explicit_uniform_location, true, false, ARB_explicit_uniform_location), |
| 602 | EXT(ARB_fragment_coord_conventions, true, false, ARB_fragment_coord_conventions), |
| 603 | EXT(ARB_fragment_layer_viewport, true, false, ARB_fragment_layer_viewport), |
| 604 | EXT(ARB_gpu_shader5, true, false, ARB_gpu_shader5), |
| 605 | EXT(ARB_gpu_shader_fp64, true, false, ARB_gpu_shader_fp64), |
| 606 | EXT(ARB_sample_shading, true, false, ARB_sample_shading), |
| 607 | EXT(ARB_separate_shader_objects, true, false, dummy_true), |
| 608 | EXT(ARB_shader_atomic_counters, true, false, ARB_shader_atomic_counters), |
| 609 | EXT(ARB_shader_bit_encoding, true, false, ARB_shader_bit_encoding), |
Emil Velikov | 51265c1 | 2015-10-02 09:56:37 +0100 | [diff] [blame] | 610 | EXT(ARB_shader_clock, true, false, ARB_shader_clock), |
Kristian Høgsberg Kristensen | 1a59aea | 2015-12-10 12:07:43 -0800 | [diff] [blame] | 611 | EXT(ARB_shader_draw_parameters, true, false, ARB_shader_draw_parameters), |
Samuel Iglesias Gonsalvez | 3095ee9 | 2015-03-17 12:17:27 +0100 | [diff] [blame] | 612 | EXT(ARB_shader_image_load_store, true, false, ARB_shader_image_load_store), |
Martin Peres | 3d93f65 | 2015-04-27 20:05:14 +0300 | [diff] [blame] | 613 | EXT(ARB_shader_image_size, true, false, ARB_shader_image_size), |
Samuel Iglesias Gonsalvez | 3095ee9 | 2015-03-17 12:17:27 +0100 | [diff] [blame] | 614 | EXT(ARB_shader_precision, true, false, ARB_shader_precision), |
| 615 | EXT(ARB_shader_stencil_export, true, false, ARB_shader_stencil_export), |
Samuel Iglesias Gonsalvez | 5b080e3 | 2015-07-14 12:23:42 +0200 | [diff] [blame] | 616 | EXT(ARB_shader_storage_buffer_object, true, true, ARB_shader_storage_buffer_object), |
Chris Forbes | cc172fd | 2014-08-10 21:31:06 +1200 | [diff] [blame] | 617 | EXT(ARB_shader_subroutine, true, false, ARB_shader_subroutine), |
Ilia Mirkin | fb18ee9 | 2015-08-27 23:06:29 -0400 | [diff] [blame] | 618 | EXT(ARB_shader_texture_image_samples, true, false, ARB_shader_texture_image_samples), |
Samuel Iglesias Gonsalvez | 3095ee9 | 2015-03-17 12:17:27 +0100 | [diff] [blame] | 619 | EXT(ARB_shader_texture_lod, true, false, ARB_shader_texture_lod), |
| 620 | EXT(ARB_shading_language_420pack, true, false, ARB_shading_language_420pack), |
| 621 | EXT(ARB_shading_language_packing, true, false, ARB_shading_language_packing), |
Fabian Bieler | 497eb29 | 2014-03-20 22:44:43 +0100 | [diff] [blame] | 622 | EXT(ARB_tessellation_shader, true, false, ARB_tessellation_shader), |
Samuel Iglesias Gonsalvez | 3095ee9 | 2015-03-17 12:17:27 +0100 | [diff] [blame] | 623 | EXT(ARB_texture_cube_map_array, true, false, ARB_texture_cube_map_array), |
| 624 | EXT(ARB_texture_gather, true, false, ARB_texture_gather), |
| 625 | EXT(ARB_texture_multisample, true, false, ARB_texture_multisample), |
| 626 | EXT(ARB_texture_query_levels, true, false, ARB_texture_query_levels), |
| 627 | EXT(ARB_texture_query_lod, true, false, ARB_texture_query_lod), |
| 628 | EXT(ARB_texture_rectangle, true, false, dummy_true), |
| 629 | EXT(ARB_uniform_buffer_object, true, false, ARB_uniform_buffer_object), |
| 630 | EXT(ARB_vertex_attrib_64bit, true, false, ARB_vertex_attrib_64bit), |
| 631 | EXT(ARB_viewport_array, true, false, ARB_viewport_array), |
Ian Romanick | 507b875 | 2014-03-26 11:43:32 -0700 | [diff] [blame] | 632 | |
| 633 | /* KHR extensions go here, sorted alphabetically. |
| 634 | */ |
| 635 | |
| 636 | /* OES extensions go here, sorted alphabetically. |
| 637 | */ |
| 638 | EXT(OES_EGL_image_external, false, true, OES_EGL_image_external), |
| 639 | EXT(OES_standard_derivatives, false, true, OES_standard_derivatives), |
Nanley Chery | 79f6830 | 2015-10-16 10:14:39 -0700 | [diff] [blame] | 640 | EXT(OES_texture_3D, false, true, dummy_true), |
Tapani Pälli | c2c64fd | 2015-08-21 09:42:10 +0300 | [diff] [blame] | 641 | EXT(OES_texture_storage_multisample_2d_array, false, true, ARB_texture_multisample), |
Ian Romanick | 507b875 | 2014-03-26 11:43:32 -0700 | [diff] [blame] | 642 | |
| 643 | /* All other extensions go here, sorted alphabetically. |
| 644 | */ |
| 645 | EXT(AMD_conservative_depth, true, false, ARB_conservative_depth), |
| 646 | EXT(AMD_shader_stencil_export, true, false, ARB_shader_stencil_export), |
| 647 | EXT(AMD_shader_trinary_minmax, true, false, dummy_true), |
Kenneth Graunke | 6aba035 | 2013-07-29 10:40:51 -0700 | [diff] [blame] | 648 | EXT(AMD_vertex_shader_layer, true, false, AMD_vertex_shader_layer), |
Ilia Mirkin | df61553 | 2014-07-02 12:12:51 -0400 | [diff] [blame] | 649 | EXT(AMD_vertex_shader_viewport_index, true, false, AMD_vertex_shader_viewport_index), |
Ryan Houdek | ceecb08 | 2015-11-05 10:53:40 -0600 | [diff] [blame] | 650 | EXT(EXT_blend_func_extended, false, true, ARB_blend_func_extended), |
Tapani Pälli | f52fe39 | 2014-11-25 06:10:30 -0500 | [diff] [blame] | 651 | EXT(EXT_draw_buffers, false, true, dummy_true), |
Ian Romanick | 7d9adef | 2014-03-26 13:11:44 -0700 | [diff] [blame] | 652 | EXT(EXT_separate_shader_objects, false, true, dummy_true), |
Ian Romanick | ea373f0 | 2013-09-12 11:40:00 -0500 | [diff] [blame] | 653 | EXT(EXT_shader_integer_mix, true, true, EXT_shader_integer_mix), |
Ian Romanick | ef54434 | 2015-11-17 15:36:15 -0800 | [diff] [blame] | 654 | EXT(EXT_shader_samples_identical, true, true, EXT_shader_samples_identical), |
Ian Romanick | 507b875 | 2014-03-26 11:43:32 -0700 | [diff] [blame] | 655 | EXT(EXT_texture_array, true, false, EXT_texture_array), |
Paul Berry | 3097715 | 2011-06-24 15:34:04 -0700 | [diff] [blame] | 656 | }; |
| 657 | |
| 658 | #undef EXT |
| 659 | |
| 660 | |
| 661 | /** |
| 662 | * Determine whether a given extension is compatible with the target, |
| 663 | * API, and extension information in the current parser state. |
| 664 | */ |
| 665 | bool _mesa_glsl_extension::compatible_with_state(const _mesa_glsl_parse_state * |
| 666 | state) const |
| 667 | { |
Paul Berry | 3097715 | 2011-06-24 15:34:04 -0700 | [diff] [blame] | 668 | /* Check that this extension matches whether we are compiling |
| 669 | * for desktop GL or GLES. |
| 670 | */ |
| 671 | if (state->es_shader) { |
| 672 | if (!this->avail_in_ES) return false; |
Ian Romanick | e701761 | 2010-04-07 16:46:25 -0700 | [diff] [blame] | 673 | } else { |
Paul Berry | 3097715 | 2011-06-24 15:34:04 -0700 | [diff] [blame] | 674 | if (!this->avail_in_GL) return false; |
Ian Romanick | 887a8b0 | 2010-04-07 16:57:56 -0700 | [diff] [blame] | 675 | } |
| 676 | |
Paul Berry | 3097715 | 2011-06-24 15:34:04 -0700 | [diff] [blame] | 677 | /* Check that this extension is supported by the OpenGL |
| 678 | * implementation. |
| 679 | * |
| 680 | * Note: the ->* operator indexes into state->extensions by the |
| 681 | * offset this->supported_flag. See |
| 682 | * _mesa_glsl_extension::supported_flag for more info. |
| 683 | */ |
| 684 | return state->extensions->*(this->supported_flag); |
| 685 | } |
Ian Romanick | 887a8b0 | 2010-04-07 16:57:56 -0700 | [diff] [blame] | 686 | |
Paul Berry | 3097715 | 2011-06-24 15:34:04 -0700 | [diff] [blame] | 687 | /** |
| 688 | * Set the appropriate flags in the parser state to establish the |
| 689 | * given behavior for this extension. |
| 690 | */ |
| 691 | void _mesa_glsl_extension::set_flags(_mesa_glsl_parse_state *state, |
| 692 | ext_behavior behavior) const |
| 693 | { |
| 694 | /* Note: the ->* operator indexes into state by the |
| 695 | * offsets this->enable_flag and this->warn_flag. See |
| 696 | * _mesa_glsl_extension::supported_flag for more info. |
| 697 | */ |
| 698 | state->*(this->enable_flag) = (behavior != extension_disable); |
| 699 | state->*(this->warn_flag) = (behavior == extension_warn); |
| 700 | } |
| 701 | |
| 702 | /** |
| 703 | * Find an extension by name in _mesa_glsl_supported_extensions. If |
| 704 | * the name is not found, return NULL. |
| 705 | */ |
| 706 | static const _mesa_glsl_extension *find_extension(const char *name) |
| 707 | { |
Brian Paul | c16c719 | 2015-02-28 09:11:23 -0700 | [diff] [blame] | 708 | for (unsigned i = 0; i < ARRAY_SIZE(_mesa_glsl_supported_extensions); ++i) { |
Paul Berry | 3097715 | 2011-06-24 15:34:04 -0700 | [diff] [blame] | 709 | if (strcmp(name, _mesa_glsl_supported_extensions[i].name) == 0) { |
| 710 | return &_mesa_glsl_supported_extensions[i]; |
| 711 | } |
| 712 | } |
| 713 | return NULL; |
| 714 | } |
| 715 | |
| 716 | |
| 717 | bool |
| 718 | _mesa_glsl_process_extension(const char *name, YYLTYPE *name_locp, |
| 719 | const char *behavior_string, YYLTYPE *behavior_locp, |
| 720 | _mesa_glsl_parse_state *state) |
| 721 | { |
| 722 | ext_behavior behavior; |
| 723 | if (strcmp(behavior_string, "warn") == 0) { |
| 724 | behavior = extension_warn; |
| 725 | } else if (strcmp(behavior_string, "require") == 0) { |
| 726 | behavior = extension_require; |
| 727 | } else if (strcmp(behavior_string, "enable") == 0) { |
| 728 | behavior = extension_enable; |
| 729 | } else if (strcmp(behavior_string, "disable") == 0) { |
| 730 | behavior = extension_disable; |
| 731 | } else { |
| 732 | _mesa_glsl_error(behavior_locp, state, |
Paul Berry | 4d7899f | 2013-07-25 19:56:43 -0700 | [diff] [blame] | 733 | "unknown extension behavior `%s'", |
Paul Berry | 3097715 | 2011-06-24 15:34:04 -0700 | [diff] [blame] | 734 | behavior_string); |
| 735 | return false; |
| 736 | } |
| 737 | |
| 738 | if (strcmp(name, "all") == 0) { |
| 739 | if ((behavior == extension_enable) || (behavior == extension_require)) { |
Paul Berry | 4d7899f | 2013-07-25 19:56:43 -0700 | [diff] [blame] | 740 | _mesa_glsl_error(name_locp, state, "cannot %s all extensions", |
Paul Berry | 3097715 | 2011-06-24 15:34:04 -0700 | [diff] [blame] | 741 | (behavior == extension_enable) |
| 742 | ? "enable" : "require"); |
Ian Romanick | e701761 | 2010-04-07 16:46:25 -0700 | [diff] [blame] | 743 | return false; |
Ian Romanick | 1799a0c | 2010-04-07 14:50:36 -0700 | [diff] [blame] | 744 | } else { |
Paul Berry | 3097715 | 2011-06-24 15:34:04 -0700 | [diff] [blame] | 745 | for (unsigned i = 0; |
Brian Paul | c16c719 | 2015-02-28 09:11:23 -0700 | [diff] [blame] | 746 | i < ARRAY_SIZE(_mesa_glsl_supported_extensions); ++i) { |
Paul Berry | 3097715 | 2011-06-24 15:34:04 -0700 | [diff] [blame] | 747 | const _mesa_glsl_extension *extension |
| 748 | = &_mesa_glsl_supported_extensions[i]; |
| 749 | if (extension->compatible_with_state(state)) { |
| 750 | _mesa_glsl_supported_extensions[i].set_flags(state, behavior); |
| 751 | } |
| 752 | } |
| 753 | } |
| 754 | } else { |
| 755 | const _mesa_glsl_extension *extension = find_extension(name); |
| 756 | if (extension && extension->compatible_with_state(state)) { |
| 757 | extension->set_flags(state, behavior); |
| 758 | } else { |
Chia-I Wu | 267e28b | 2014-04-22 16:58:16 +0800 | [diff] [blame] | 759 | static const char fmt[] = "extension `%s' unsupported in %s shader"; |
Paul Berry | 3097715 | 2011-06-24 15:34:04 -0700 | [diff] [blame] | 760 | |
| 761 | if (behavior == extension_require) { |
| 762 | _mesa_glsl_error(name_locp, state, fmt, |
Paul Berry | 665b8d7 | 2014-01-07 10:11:39 -0800 | [diff] [blame] | 763 | name, _mesa_shader_stage_to_string(state->stage)); |
Paul Berry | 3097715 | 2011-06-24 15:34:04 -0700 | [diff] [blame] | 764 | return false; |
| 765 | } else { |
| 766 | _mesa_glsl_warning(name_locp, state, fmt, |
Paul Berry | 665b8d7 | 2014-01-07 10:11:39 -0800 | [diff] [blame] | 767 | name, _mesa_shader_stage_to_string(state->stage)); |
Paul Berry | 3097715 | 2011-06-24 15:34:04 -0700 | [diff] [blame] | 768 | } |
Ian Romanick | e701761 | 2010-04-07 16:46:25 -0700 | [diff] [blame] | 769 | } |
| 770 | } |
| 771 | |
| 772 | return true; |
| 773 | } |
| 774 | |
Matt Turner | 1b0d6ae | 2013-06-29 19:29:16 -0700 | [diff] [blame] | 775 | |
| 776 | /** |
Matt Turner | 1b0d6ae | 2013-06-29 19:29:16 -0700 | [diff] [blame] | 777 | * Recurses through <type> and <expr> if <expr> is an aggregate initializer |
| 778 | * and sets <expr>'s <constructor_type> field to <type>. Gives later functions |
| 779 | * (process_array_constructor, et al) sufficient information to do type |
| 780 | * checking. |
| 781 | * |
| 782 | * Operates on assignments involving an aggregate initializer. E.g., |
| 783 | * |
| 784 | * vec4 pos = {1.0, -1.0, 0.0, 1.0}; |
| 785 | * |
| 786 | * or more ridiculously, |
| 787 | * |
| 788 | * struct S { |
| 789 | * vec4 v[2]; |
| 790 | * }; |
| 791 | * |
| 792 | * struct { |
| 793 | * S a[2], b; |
| 794 | * int c; |
| 795 | * } aggregate = { |
| 796 | * { |
| 797 | * { |
| 798 | * { |
| 799 | * {1.0, 2.0, 3.0, 4.0}, // a[0].v[0] |
| 800 | * {5.0, 6.0, 7.0, 8.0} // a[0].v[1] |
| 801 | * } // a[0].v |
| 802 | * }, // a[0] |
| 803 | * { |
| 804 | * { |
| 805 | * {1.0, 2.0, 3.0, 4.0}, // a[1].v[0] |
| 806 | * {5.0, 6.0, 7.0, 8.0} // a[1].v[1] |
| 807 | * } // a[1].v |
| 808 | * } // a[1] |
| 809 | * }, // a |
| 810 | * { |
| 811 | * { |
| 812 | * {1.0, 2.0, 3.0, 4.0}, // b.v[0] |
| 813 | * {5.0, 6.0, 7.0, 8.0} // b.v[1] |
| 814 | * } // b.v |
| 815 | * }, // b |
| 816 | * 4 // c |
| 817 | * }; |
| 818 | * |
| 819 | * This pass is necessary because the right-hand side of <type> e = { ... } |
| 820 | * doesn't contain sufficient information to determine if the types match. |
| 821 | */ |
| 822 | void |
Paul Berry | 0da1a2c | 2014-01-21 15:41:26 -0800 | [diff] [blame] | 823 | _mesa_ast_set_aggregate_type(const glsl_type *type, |
| 824 | ast_expression *expr) |
Matt Turner | 1b0d6ae | 2013-06-29 19:29:16 -0700 | [diff] [blame] | 825 | { |
Matt Turner | 1b0d6ae | 2013-06-29 19:29:16 -0700 | [diff] [blame] | 826 | ast_aggregate_initializer *ai = (ast_aggregate_initializer *)expr; |
Paul Berry | 0da1a2c | 2014-01-21 15:41:26 -0800 | [diff] [blame] | 827 | ai->constructor_type = type; |
Matt Turner | 1b0d6ae | 2013-06-29 19:29:16 -0700 | [diff] [blame] | 828 | |
| 829 | /* If the aggregate is an array, recursively set its elements' types. */ |
Paul Berry | 0da1a2c | 2014-01-21 15:41:26 -0800 | [diff] [blame] | 830 | if (type->is_array()) { |
Timothy Arceri | d67515b | 2015-04-30 20:45:54 +1000 | [diff] [blame] | 831 | /* Each array element has the type type->fields.array. |
Matt Turner | 1b0d6ae | 2013-06-29 19:29:16 -0700 | [diff] [blame] | 832 | * |
| 833 | * E.g., if <type> if struct S[2] we want to set each element's type to |
| 834 | * struct S. |
Matt Turner | 1b0d6ae | 2013-06-29 19:29:16 -0700 | [diff] [blame] | 835 | */ |
Matt Turner | 1b0d6ae | 2013-06-29 19:29:16 -0700 | [diff] [blame] | 836 | for (exec_node *expr_node = ai->expressions.head; |
| 837 | !expr_node->is_tail_sentinel(); |
| 838 | expr_node = expr_node->next) { |
| 839 | ast_expression *expr = exec_node_data(ast_expression, expr_node, |
| 840 | link); |
| 841 | |
| 842 | if (expr->oper == ast_aggregate) |
Timothy Arceri | d67515b | 2015-04-30 20:45:54 +1000 | [diff] [blame] | 843 | _mesa_ast_set_aggregate_type(type->fields.array, expr); |
Matt Turner | 1b0d6ae | 2013-06-29 19:29:16 -0700 | [diff] [blame] | 844 | } |
| 845 | |
| 846 | /* If the aggregate is a struct, recursively set its fields' types. */ |
Paul Berry | 0da1a2c | 2014-01-21 15:41:26 -0800 | [diff] [blame] | 847 | } else if (type->is_record()) { |
Matt Turner | 1b0d6ae | 2013-06-29 19:29:16 -0700 | [diff] [blame] | 848 | exec_node *expr_node = ai->expressions.head; |
| 849 | |
Paul Berry | 0da1a2c | 2014-01-21 15:41:26 -0800 | [diff] [blame] | 850 | /* Iterate through the struct's fields. */ |
| 851 | for (unsigned i = 0; !expr_node->is_tail_sentinel() && i < type->length; |
| 852 | i++, expr_node = expr_node->next) { |
| 853 | ast_expression *expr = exec_node_data(ast_expression, expr_node, |
| 854 | link); |
Matt Turner | 1b0d6ae | 2013-06-29 19:29:16 -0700 | [diff] [blame] | 855 | |
Paul Berry | 0da1a2c | 2014-01-21 15:41:26 -0800 | [diff] [blame] | 856 | if (expr->oper == ast_aggregate) { |
| 857 | _mesa_ast_set_aggregate_type(type->fields.structure[i].type, expr); |
Matt Turner | 1b0d6ae | 2013-06-29 19:29:16 -0700 | [diff] [blame] | 858 | } |
| 859 | } |
Paul Berry | 0da1a2c | 2014-01-21 15:41:26 -0800 | [diff] [blame] | 860 | /* If the aggregate is a matrix, set its columns' types. */ |
| 861 | } else if (type->is_matrix()) { |
| 862 | for (exec_node *expr_node = ai->expressions.head; |
| 863 | !expr_node->is_tail_sentinel(); |
| 864 | expr_node = expr_node->next) { |
| 865 | ast_expression *expr = exec_node_data(ast_expression, expr_node, |
| 866 | link); |
Matt Turner | 1b0d6ae | 2013-06-29 19:29:16 -0700 | [diff] [blame] | 867 | |
Paul Berry | 0da1a2c | 2014-01-21 15:41:26 -0800 | [diff] [blame] | 868 | if (expr->oper == ast_aggregate) |
| 869 | _mesa_ast_set_aggregate_type(type->column_type(), expr); |
Matt Turner | 1b0d6ae | 2013-06-29 19:29:16 -0700 | [diff] [blame] | 870 | } |
| 871 | } |
| 872 | } |
| 873 | |
Samuel Iglesias Gonsalvez | 3763a0e | 2015-09-10 10:00:12 +0200 | [diff] [blame] | 874 | void |
| 875 | _mesa_ast_process_interface_block(YYLTYPE *locp, |
| 876 | _mesa_glsl_parse_state *state, |
| 877 | ast_interface_block *const block, |
Matt Turner | 5369efe | 2015-11-23 14:22:48 -0800 | [diff] [blame] | 878 | const struct ast_type_qualifier &q) |
Samuel Iglesias Gonsalvez | 3763a0e | 2015-09-10 10:00:12 +0200 | [diff] [blame] | 879 | { |
Samuel Iglesias Gonsalvez | a40f917 | 2015-09-03 12:00:16 +0200 | [diff] [blame] | 880 | if (q.flags.q.buffer) { |
| 881 | if (!state->has_shader_storage_buffer_objects()) { |
| 882 | _mesa_glsl_error(locp, state, |
| 883 | "#version 430 / GL_ARB_shader_storage_buffer_object " |
| 884 | "required for defining shader storage blocks"); |
| 885 | } else if (state->ARB_shader_storage_buffer_object_warn) { |
| 886 | _mesa_glsl_warning(locp, state, |
| 887 | "#version 430 / GL_ARB_shader_storage_buffer_object " |
| 888 | "required for defining shader storage blocks"); |
| 889 | } |
| 890 | } else if (q.flags.q.uniform) { |
Samuel Iglesias Gonsalvez | 3763a0e | 2015-09-10 10:00:12 +0200 | [diff] [blame] | 891 | if (!state->has_uniform_buffer_objects()) { |
| 892 | _mesa_glsl_error(locp, state, |
| 893 | "#version 140 / GL_ARB_uniform_buffer_object " |
| 894 | "required for defining uniform blocks"); |
| 895 | } else if (state->ARB_uniform_buffer_object_warn) { |
| 896 | _mesa_glsl_warning(locp, state, |
| 897 | "#version 140 / GL_ARB_uniform_buffer_object " |
| 898 | "required for defining uniform blocks"); |
| 899 | } |
| 900 | } else { |
| 901 | if (state->es_shader || state->language_version < 150) { |
| 902 | _mesa_glsl_error(locp, state, |
| 903 | "#version 150 required for using " |
| 904 | "interface blocks"); |
| 905 | } |
| 906 | } |
| 907 | |
| 908 | /* From the GLSL 1.50.11 spec, section 4.3.7 ("Interface Blocks"): |
| 909 | * "It is illegal to have an input block in a vertex shader |
| 910 | * or an output block in a fragment shader" |
| 911 | */ |
| 912 | if ((state->stage == MESA_SHADER_VERTEX) && q.flags.q.in) { |
| 913 | _mesa_glsl_error(locp, state, |
| 914 | "`in' interface block is not allowed for " |
| 915 | "a vertex shader"); |
| 916 | } else if ((state->stage == MESA_SHADER_FRAGMENT) && q.flags.q.out) { |
| 917 | _mesa_glsl_error(locp, state, |
| 918 | "`out' interface block is not allowed for " |
| 919 | "a fragment shader"); |
| 920 | } |
| 921 | |
| 922 | /* Since block arrays require names, and both features are added in |
| 923 | * the same language versions, we don't have to explicitly |
| 924 | * version-check both things. |
| 925 | */ |
| 926 | if (block->instance_name != NULL) { |
| 927 | state->check_version(150, 300, locp, "interface blocks with " |
| 928 | "an instance name are not allowed"); |
| 929 | } |
| 930 | |
| 931 | uint64_t interface_type_mask; |
| 932 | struct ast_type_qualifier temp_type_qualifier; |
| 933 | |
Samuel Iglesias Gonsalvez | a40f917 | 2015-09-03 12:00:16 +0200 | [diff] [blame] | 934 | /* Get a bitmask containing only the in/out/uniform/buffer |
Samuel Iglesias Gonsalvez | 3763a0e | 2015-09-10 10:00:12 +0200 | [diff] [blame] | 935 | * flags, allowing us to ignore other irrelevant flags like |
| 936 | * interpolation qualifiers. |
| 937 | */ |
| 938 | temp_type_qualifier.flags.i = 0; |
| 939 | temp_type_qualifier.flags.q.uniform = true; |
| 940 | temp_type_qualifier.flags.q.in = true; |
| 941 | temp_type_qualifier.flags.q.out = true; |
Samuel Iglesias Gonsalvez | a40f917 | 2015-09-03 12:00:16 +0200 | [diff] [blame] | 942 | temp_type_qualifier.flags.q.buffer = true; |
Samuel Iglesias Gonsalvez | 3763a0e | 2015-09-10 10:00:12 +0200 | [diff] [blame] | 943 | interface_type_mask = temp_type_qualifier.flags.i; |
| 944 | |
| 945 | /* Get the block's interface qualifier. The interface_qualifier |
| 946 | * production rule guarantees that only one bit will be set (and |
| 947 | * it will be in/out/uniform). |
| 948 | */ |
| 949 | uint64_t block_interface_qualifier = q.flags.i; |
| 950 | |
| 951 | block->layout.flags.i |= block_interface_qualifier; |
| 952 | |
| 953 | if (state->stage == MESA_SHADER_GEOMETRY && |
| 954 | state->has_explicit_attrib_stream()) { |
| 955 | /* Assign global layout's stream value. */ |
| 956 | block->layout.flags.q.stream = 1; |
| 957 | block->layout.flags.q.explicit_stream = 0; |
| 958 | block->layout.stream = state->out_qualifier->stream; |
| 959 | } |
| 960 | |
| 961 | foreach_list_typed (ast_declarator_list, member, link, &block->declarations) { |
| 962 | ast_type_qualifier& qualifier = member->type->qualifier; |
| 963 | if ((qualifier.flags.i & interface_type_mask) == 0) { |
| 964 | /* GLSLangSpec.1.50.11, 4.3.7 (Interface Blocks): |
| 965 | * "If no optional qualifier is used in a member declaration, the |
| 966 | * qualifier of the variable is just in, out, or uniform as declared |
| 967 | * by interface-qualifier." |
| 968 | */ |
| 969 | qualifier.flags.i |= block_interface_qualifier; |
| 970 | } else if ((qualifier.flags.i & interface_type_mask) != |
| 971 | block_interface_qualifier) { |
| 972 | /* GLSLangSpec.1.50.11, 4.3.7 (Interface Blocks): |
| 973 | * "If optional qualifiers are used, they can include interpolation |
| 974 | * and storage qualifiers and they must declare an input, output, |
| 975 | * or uniform variable consistent with the interface qualifier of |
| 976 | * the block." |
| 977 | */ |
| 978 | _mesa_glsl_error(locp, state, |
| 979 | "uniform/in/out qualifier on " |
| 980 | "interface block member does not match " |
| 981 | "the interface block"); |
| 982 | } |
| 983 | |
| 984 | /* From GLSL ES 3.0, chapter 4.3.7 "Interface Blocks": |
| 985 | * |
| 986 | * "GLSL ES 3.0 does not support interface blocks for shader inputs or |
| 987 | * outputs." |
| 988 | * |
| 989 | * And from GLSL ES 3.0, chapter 4.6.1 "The invariant qualifier":. |
| 990 | * |
| 991 | * "Only variables output from a shader can be candidates for |
| 992 | * invariance." |
| 993 | * |
| 994 | * From GLSL 4.40 and GLSL 1.50, section "Interface Blocks": |
| 995 | * |
| 996 | * "If optional qualifiers are used, they can include interpolation |
| 997 | * qualifiers, auxiliary storage qualifiers, and storage qualifiers |
| 998 | * and they must declare an input, output, or uniform member |
| 999 | * consistent with the interface qualifier of the block" |
| 1000 | */ |
| 1001 | if (qualifier.flags.q.invariant) |
| 1002 | _mesa_glsl_error(locp, state, |
| 1003 | "invariant qualifiers cannot be used " |
| 1004 | "with interface blocks members"); |
| 1005 | } |
| 1006 | } |
Matt Turner | 1b0d6ae | 2013-06-29 19:29:16 -0700 | [diff] [blame] | 1007 | |
Ian Romanick | a87ac25 | 2010-02-22 13:19:34 -0800 | [diff] [blame] | 1008 | void |
| 1009 | _mesa_ast_type_qualifier_print(const struct ast_type_qualifier *q) |
| 1010 | { |
Dave Airlie | 65ac360 | 2015-06-01 10:55:47 +1000 | [diff] [blame] | 1011 | if (q->flags.q.subroutine) |
| 1012 | printf("subroutine "); |
| 1013 | |
| 1014 | if (q->flags.q.subroutine_def) { |
| 1015 | printf("subroutine ("); |
| 1016 | q->subroutine_list->print(); |
| 1017 | printf(")"); |
| 1018 | } |
| 1019 | |
Ian Romanick | e24d35a | 2010-10-05 16:38:47 -0700 | [diff] [blame] | 1020 | if (q->flags.q.constant) |
Ian Romanick | a87ac25 | 2010-02-22 13:19:34 -0800 | [diff] [blame] | 1021 | printf("const "); |
| 1022 | |
Ian Romanick | e24d35a | 2010-10-05 16:38:47 -0700 | [diff] [blame] | 1023 | if (q->flags.q.invariant) |
Ian Romanick | a87ac25 | 2010-02-22 13:19:34 -0800 | [diff] [blame] | 1024 | printf("invariant "); |
| 1025 | |
Ian Romanick | e24d35a | 2010-10-05 16:38:47 -0700 | [diff] [blame] | 1026 | if (q->flags.q.attribute) |
Ian Romanick | a87ac25 | 2010-02-22 13:19:34 -0800 | [diff] [blame] | 1027 | printf("attribute "); |
| 1028 | |
Ian Romanick | e24d35a | 2010-10-05 16:38:47 -0700 | [diff] [blame] | 1029 | if (q->flags.q.varying) |
Ian Romanick | a87ac25 | 2010-02-22 13:19:34 -0800 | [diff] [blame] | 1030 | printf("varying "); |
| 1031 | |
Ian Romanick | e24d35a | 2010-10-05 16:38:47 -0700 | [diff] [blame] | 1032 | if (q->flags.q.in && q->flags.q.out) |
Ian Romanick | a87ac25 | 2010-02-22 13:19:34 -0800 | [diff] [blame] | 1033 | printf("inout "); |
| 1034 | else { |
Ian Romanick | e24d35a | 2010-10-05 16:38:47 -0700 | [diff] [blame] | 1035 | if (q->flags.q.in) |
Ian Romanick | a87ac25 | 2010-02-22 13:19:34 -0800 | [diff] [blame] | 1036 | printf("in "); |
| 1037 | |
Ian Romanick | e24d35a | 2010-10-05 16:38:47 -0700 | [diff] [blame] | 1038 | if (q->flags.q.out) |
Ian Romanick | a87ac25 | 2010-02-22 13:19:34 -0800 | [diff] [blame] | 1039 | printf("out "); |
| 1040 | } |
| 1041 | |
Ian Romanick | e24d35a | 2010-10-05 16:38:47 -0700 | [diff] [blame] | 1042 | if (q->flags.q.centroid) |
Ian Romanick | a87ac25 | 2010-02-22 13:19:34 -0800 | [diff] [blame] | 1043 | printf("centroid "); |
Chris Forbes | 51aa15a | 2013-11-29 21:21:56 +1300 | [diff] [blame] | 1044 | if (q->flags.q.sample) |
| 1045 | printf("sample "); |
Fabian Bieler | 1009b33 | 2014-03-05 13:43:17 +0100 | [diff] [blame] | 1046 | if (q->flags.q.patch) |
| 1047 | printf("patch "); |
Ian Romanick | e24d35a | 2010-10-05 16:38:47 -0700 | [diff] [blame] | 1048 | if (q->flags.q.uniform) |
Ian Romanick | a87ac25 | 2010-02-22 13:19:34 -0800 | [diff] [blame] | 1049 | printf("uniform "); |
Kristian Høgsberg | 84fc5fe | 2015-05-13 10:53:46 +0200 | [diff] [blame] | 1050 | if (q->flags.q.buffer) |
| 1051 | printf("buffer "); |
Ian Romanick | e24d35a | 2010-10-05 16:38:47 -0700 | [diff] [blame] | 1052 | if (q->flags.q.smooth) |
Ian Romanick | a87ac25 | 2010-02-22 13:19:34 -0800 | [diff] [blame] | 1053 | printf("smooth "); |
Ian Romanick | e24d35a | 2010-10-05 16:38:47 -0700 | [diff] [blame] | 1054 | if (q->flags.q.flat) |
Ian Romanick | a87ac25 | 2010-02-22 13:19:34 -0800 | [diff] [blame] | 1055 | printf("flat "); |
Ian Romanick | e24d35a | 2010-10-05 16:38:47 -0700 | [diff] [blame] | 1056 | if (q->flags.q.noperspective) |
Ian Romanick | a87ac25 | 2010-02-22 13:19:34 -0800 | [diff] [blame] | 1057 | printf("noperspective "); |
| 1058 | } |
| 1059 | |
| 1060 | |
| 1061 | void |
| 1062 | ast_node::print(void) const |
| 1063 | { |
Ian Romanick | 03d3f3a | 2010-04-02 11:03:47 -0700 | [diff] [blame] | 1064 | printf("unhandled node "); |
Ian Romanick | a87ac25 | 2010-02-22 13:19:34 -0800 | [diff] [blame] | 1065 | } |
| 1066 | |
| 1067 | |
| 1068 | ast_node::ast_node(void) |
| 1069 | { |
Carl Worth | ec9675e | 2010-07-29 16:39:36 -0700 | [diff] [blame] | 1070 | this->location.source = 0; |
Sir Anthony | 433d562 | 2014-02-05 21:18:09 +0600 | [diff] [blame] | 1071 | this->location.first_line = 0; |
| 1072 | this->location.first_column = 0; |
| 1073 | this->location.last_line = 0; |
| 1074 | this->location.last_column = 0; |
Ian Romanick | a87ac25 | 2010-02-22 13:19:34 -0800 | [diff] [blame] | 1075 | } |
| 1076 | |
Ian Romanick | a87ac25 | 2010-02-22 13:19:34 -0800 | [diff] [blame] | 1077 | |
| 1078 | static void |
Timothy Arceri | b0c64d3 | 2014-01-23 23:22:01 +1100 | [diff] [blame] | 1079 | ast_opt_array_dimensions_print(const ast_array_specifier *array_specifier) |
Ian Romanick | a87ac25 | 2010-02-22 13:19:34 -0800 | [diff] [blame] | 1080 | { |
Timothy Arceri | b0c64d3 | 2014-01-23 23:22:01 +1100 | [diff] [blame] | 1081 | if (array_specifier) |
| 1082 | array_specifier->print(); |
Ian Romanick | a87ac25 | 2010-02-22 13:19:34 -0800 | [diff] [blame] | 1083 | } |
| 1084 | |
| 1085 | |
Ian Romanick | a87ac25 | 2010-02-22 13:19:34 -0800 | [diff] [blame] | 1086 | void |
| 1087 | ast_compound_statement::print(void) const |
| 1088 | { |
Ian Romanick | a87ac25 | 2010-02-22 13:19:34 -0800 | [diff] [blame] | 1089 | printf("{\n"); |
Iago Toral Quiroga | 1af0d9d | 2015-11-24 12:40:53 +0100 | [diff] [blame] | 1090 | |
Matt Turner | 6e217ad | 2014-06-24 22:02:24 -0700 | [diff] [blame] | 1091 | foreach_list_typed(ast_node, ast, link, &this->statements) { |
Ian Romanick | 304ea90 | 2010-05-10 11:17:53 -0700 | [diff] [blame] | 1092 | ast->print(); |
Ian Romanick | a87ac25 | 2010-02-22 13:19:34 -0800 | [diff] [blame] | 1093 | } |
| 1094 | |
| 1095 | printf("}\n"); |
| 1096 | } |
| 1097 | |
| 1098 | |
| 1099 | ast_compound_statement::ast_compound_statement(int new_scope, |
| 1100 | ast_node *statements) |
| 1101 | { |
| 1102 | this->new_scope = new_scope; |
Ian Romanick | a87ac25 | 2010-02-22 13:19:34 -0800 | [diff] [blame] | 1103 | |
| 1104 | if (statements != NULL) { |
Ian Romanick | 304ea90 | 2010-05-10 11:17:53 -0700 | [diff] [blame] | 1105 | this->statements.push_degenerate_list_at_head(&statements->link); |
Ian Romanick | a87ac25 | 2010-02-22 13:19:34 -0800 | [diff] [blame] | 1106 | } |
| 1107 | } |
| 1108 | |
| 1109 | |
| 1110 | void |
| 1111 | ast_expression::print(void) const |
| 1112 | { |
Ian Romanick | a87ac25 | 2010-02-22 13:19:34 -0800 | [diff] [blame] | 1113 | switch (oper) { |
| 1114 | case ast_assign: |
Ian Romanick | a87ac25 | 2010-02-22 13:19:34 -0800 | [diff] [blame] | 1115 | case ast_mul_assign: |
| 1116 | case ast_div_assign: |
| 1117 | case ast_mod_assign: |
| 1118 | case ast_add_assign: |
| 1119 | case ast_sub_assign: |
| 1120 | case ast_ls_assign: |
| 1121 | case ast_rs_assign: |
| 1122 | case ast_and_assign: |
| 1123 | case ast_xor_assign: |
| 1124 | case ast_or_assign: |
| 1125 | subexpressions[0]->print(); |
Ian Romanick | 88349b2 | 2010-02-22 19:10:25 -0800 | [diff] [blame] | 1126 | printf("%s ", operator_string(oper)); |
Ian Romanick | a87ac25 | 2010-02-22 13:19:34 -0800 | [diff] [blame] | 1127 | subexpressions[1]->print(); |
| 1128 | break; |
| 1129 | |
| 1130 | case ast_field_selection: |
| 1131 | subexpressions[0]->print(); |
| 1132 | printf(". %s ", primary_expression.identifier); |
| 1133 | break; |
| 1134 | |
| 1135 | case ast_plus: |
| 1136 | case ast_neg: |
| 1137 | case ast_bit_not: |
| 1138 | case ast_logic_not: |
| 1139 | case ast_pre_inc: |
| 1140 | case ast_pre_dec: |
Ian Romanick | 88349b2 | 2010-02-22 19:10:25 -0800 | [diff] [blame] | 1141 | printf("%s ", operator_string(oper)); |
Ian Romanick | a87ac25 | 2010-02-22 13:19:34 -0800 | [diff] [blame] | 1142 | subexpressions[0]->print(); |
| 1143 | break; |
| 1144 | |
| 1145 | case ast_post_inc: |
| 1146 | case ast_post_dec: |
| 1147 | subexpressions[0]->print(); |
Ian Romanick | 88349b2 | 2010-02-22 19:10:25 -0800 | [diff] [blame] | 1148 | printf("%s ", operator_string(oper)); |
Ian Romanick | a87ac25 | 2010-02-22 13:19:34 -0800 | [diff] [blame] | 1149 | break; |
| 1150 | |
| 1151 | case ast_conditional: |
| 1152 | subexpressions[0]->print(); |
| 1153 | printf("? "); |
| 1154 | subexpressions[1]->print(); |
| 1155 | printf(": "); |
Paul Berry | 26b566e | 2011-06-03 10:02:32 -0700 | [diff] [blame] | 1156 | subexpressions[2]->print(); |
Ian Romanick | a87ac25 | 2010-02-22 13:19:34 -0800 | [diff] [blame] | 1157 | break; |
| 1158 | |
| 1159 | case ast_array_index: |
| 1160 | subexpressions[0]->print(); |
| 1161 | printf("[ "); |
| 1162 | subexpressions[1]->print(); |
| 1163 | printf("] "); |
| 1164 | break; |
| 1165 | |
| 1166 | case ast_function_call: { |
Ian Romanick | a87ac25 | 2010-02-22 13:19:34 -0800 | [diff] [blame] | 1167 | subexpressions[0]->print(); |
| 1168 | printf("( "); |
| 1169 | |
Matt Turner | 6e217ad | 2014-06-24 22:02:24 -0700 | [diff] [blame] | 1170 | foreach_list_typed (ast_node, ast, link, &this->expressions) { |
| 1171 | if (&ast->link != this->expressions.get_head()) |
Ian Romanick | 2384937 | 2010-05-14 16:06:41 -0700 | [diff] [blame] | 1172 | printf(", "); |
Ian Romanick | 304ea90 | 2010-05-10 11:17:53 -0700 | [diff] [blame] | 1173 | |
Ian Romanick | 304ea90 | 2010-05-10 11:17:53 -0700 | [diff] [blame] | 1174 | ast->print(); |
Ian Romanick | a87ac25 | 2010-02-22 13:19:34 -0800 | [diff] [blame] | 1175 | } |
| 1176 | |
| 1177 | printf(") "); |
| 1178 | break; |
| 1179 | } |
| 1180 | |
| 1181 | case ast_identifier: |
| 1182 | printf("%s ", primary_expression.identifier); |
| 1183 | break; |
| 1184 | |
| 1185 | case ast_int_constant: |
| 1186 | printf("%d ", primary_expression.int_constant); |
| 1187 | break; |
| 1188 | |
| 1189 | case ast_uint_constant: |
| 1190 | printf("%u ", primary_expression.uint_constant); |
| 1191 | break; |
| 1192 | |
| 1193 | case ast_float_constant: |
| 1194 | printf("%f ", primary_expression.float_constant); |
| 1195 | break; |
| 1196 | |
Dave Airlie | ba3bab2 | 2015-02-05 12:04:58 +0200 | [diff] [blame] | 1197 | case ast_double_constant: |
| 1198 | printf("%f ", primary_expression.double_constant); |
| 1199 | break; |
| 1200 | |
Ian Romanick | a87ac25 | 2010-02-22 13:19:34 -0800 | [diff] [blame] | 1201 | case ast_bool_constant: |
| 1202 | printf("%s ", |
| 1203 | primary_expression.bool_constant |
| 1204 | ? "true" : "false"); |
| 1205 | break; |
| 1206 | |
| 1207 | case ast_sequence: { |
Ian Romanick | a87ac25 | 2010-02-22 13:19:34 -0800 | [diff] [blame] | 1208 | printf("( "); |
Matt Turner | 6e217ad | 2014-06-24 22:02:24 -0700 | [diff] [blame] | 1209 | foreach_list_typed (ast_node, ast, link, & this->expressions) { |
| 1210 | if (&ast->link != this->expressions.get_head()) |
Ian Romanick | a87ac25 | 2010-02-22 13:19:34 -0800 | [diff] [blame] | 1211 | printf(", "); |
| 1212 | |
Ian Romanick | 304ea90 | 2010-05-10 11:17:53 -0700 | [diff] [blame] | 1213 | ast->print(); |
Ian Romanick | a87ac25 | 2010-02-22 13:19:34 -0800 | [diff] [blame] | 1214 | } |
| 1215 | printf(") "); |
| 1216 | break; |
| 1217 | } |
Ian Romanick | 88349b2 | 2010-02-22 19:10:25 -0800 | [diff] [blame] | 1218 | |
Matt Turner | ae79e86 | 2013-06-29 19:27:50 -0700 | [diff] [blame] | 1219 | case ast_aggregate: { |
| 1220 | printf("{ "); |
Matt Turner | 6e217ad | 2014-06-24 22:02:24 -0700 | [diff] [blame] | 1221 | foreach_list_typed (ast_node, ast, link, & this->expressions) { |
| 1222 | if (&ast->link != this->expressions.get_head()) |
Matt Turner | ae79e86 | 2013-06-29 19:27:50 -0700 | [diff] [blame] | 1223 | printf(", "); |
| 1224 | |
Matt Turner | ae79e86 | 2013-06-29 19:27:50 -0700 | [diff] [blame] | 1225 | ast->print(); |
| 1226 | } |
| 1227 | printf("} "); |
| 1228 | break; |
| 1229 | } |
| 1230 | |
Ian Romanick | 88349b2 | 2010-02-22 19:10:25 -0800 | [diff] [blame] | 1231 | default: |
| 1232 | assert(0); |
| 1233 | break; |
Ian Romanick | a87ac25 | 2010-02-22 13:19:34 -0800 | [diff] [blame] | 1234 | } |
| 1235 | } |
| 1236 | |
| 1237 | ast_expression::ast_expression(int oper, |
| 1238 | ast_expression *ex0, |
| 1239 | ast_expression *ex1, |
Francisco Jerez | 8bd1c69 | 2013-09-20 15:36:38 -0700 | [diff] [blame] | 1240 | ast_expression *ex2) : |
| 1241 | primary_expression() |
Ian Romanick | a87ac25 | 2010-02-22 13:19:34 -0800 | [diff] [blame] | 1242 | { |
| 1243 | this->oper = ast_operators(oper); |
| 1244 | this->subexpressions[0] = ex0; |
| 1245 | this->subexpressions[1] = ex1; |
| 1246 | this->subexpressions[2] = ex2; |
Ian Romanick | fa0a9ac | 2011-12-23 09:56:03 -0800 | [diff] [blame] | 1247 | this->non_lvalue_description = NULL; |
Ian Romanick | a87ac25 | 2010-02-22 13:19:34 -0800 | [diff] [blame] | 1248 | } |
| 1249 | |
| 1250 | |
| 1251 | void |
| 1252 | ast_expression_statement::print(void) const |
| 1253 | { |
| 1254 | if (expression) |
| 1255 | expression->print(); |
| 1256 | |
| 1257 | printf("; "); |
| 1258 | } |
| 1259 | |
| 1260 | |
| 1261 | ast_expression_statement::ast_expression_statement(ast_expression *ex) : |
| 1262 | expression(ex) |
| 1263 | { |
| 1264 | /* empty */ |
| 1265 | } |
| 1266 | |
| 1267 | |
| 1268 | void |
| 1269 | ast_function::print(void) const |
| 1270 | { |
Ian Romanick | a87ac25 | 2010-02-22 13:19:34 -0800 | [diff] [blame] | 1271 | return_type->print(); |
| 1272 | printf(" %s (", identifier); |
| 1273 | |
Matt Turner | 6e217ad | 2014-06-24 22:02:24 -0700 | [diff] [blame] | 1274 | foreach_list_typed(ast_node, ast, link, & this->parameters) { |
Ian Romanick | 304ea90 | 2010-05-10 11:17:53 -0700 | [diff] [blame] | 1275 | ast->print(); |
Ian Romanick | a87ac25 | 2010-02-22 13:19:34 -0800 | [diff] [blame] | 1276 | } |
| 1277 | |
| 1278 | printf(")"); |
| 1279 | } |
| 1280 | |
| 1281 | |
| 1282 | ast_function::ast_function(void) |
Vinson Lee | cd90ebe | 2013-02-10 01:38:53 +0100 | [diff] [blame] | 1283 | : return_type(NULL), identifier(NULL), is_definition(false), |
| 1284 | signature(NULL) |
Ian Romanick | a87ac25 | 2010-02-22 13:19:34 -0800 | [diff] [blame] | 1285 | { |
Ian Romanick | 304ea90 | 2010-05-10 11:17:53 -0700 | [diff] [blame] | 1286 | /* empty */ |
Ian Romanick | a87ac25 | 2010-02-22 13:19:34 -0800 | [diff] [blame] | 1287 | } |
| 1288 | |
| 1289 | |
| 1290 | void |
| 1291 | ast_fully_specified_type::print(void) const |
| 1292 | { |
| 1293 | _mesa_ast_type_qualifier_print(& qualifier); |
| 1294 | specifier->print(); |
| 1295 | } |
| 1296 | |
| 1297 | |
| 1298 | void |
| 1299 | ast_parameter_declarator::print(void) const |
| 1300 | { |
| 1301 | type->print(); |
| 1302 | if (identifier) |
| 1303 | printf("%s ", identifier); |
Timothy Arceri | b0c64d3 | 2014-01-23 23:22:01 +1100 | [diff] [blame] | 1304 | ast_opt_array_dimensions_print(array_specifier); |
Ian Romanick | a87ac25 | 2010-02-22 13:19:34 -0800 | [diff] [blame] | 1305 | } |
| 1306 | |
| 1307 | |
| 1308 | void |
| 1309 | ast_function_definition::print(void) const |
| 1310 | { |
| 1311 | prototype->print(); |
| 1312 | body->print(); |
| 1313 | } |
| 1314 | |
| 1315 | |
| 1316 | void |
| 1317 | ast_declaration::print(void) const |
| 1318 | { |
| 1319 | printf("%s ", identifier); |
Timothy Arceri | b0c64d3 | 2014-01-23 23:22:01 +1100 | [diff] [blame] | 1320 | ast_opt_array_dimensions_print(array_specifier); |
Ian Romanick | a87ac25 | 2010-02-22 13:19:34 -0800 | [diff] [blame] | 1321 | |
| 1322 | if (initializer) { |
| 1323 | printf("= "); |
| 1324 | initializer->print(); |
| 1325 | } |
| 1326 | } |
| 1327 | |
| 1328 | |
Timothy Arceri | b0c64d3 | 2014-01-23 23:22:01 +1100 | [diff] [blame] | 1329 | ast_declaration::ast_declaration(const char *identifier, |
Timothy Arceri | bfb4875 | 2014-01-23 23:16:41 +1100 | [diff] [blame] | 1330 | ast_array_specifier *array_specifier, |
Ian Romanick | a87ac25 | 2010-02-22 13:19:34 -0800 | [diff] [blame] | 1331 | ast_expression *initializer) |
| 1332 | { |
| 1333 | this->identifier = identifier; |
Timothy Arceri | bfb4875 | 2014-01-23 23:16:41 +1100 | [diff] [blame] | 1334 | this->array_specifier = array_specifier; |
Ian Romanick | a87ac25 | 2010-02-22 13:19:34 -0800 | [diff] [blame] | 1335 | this->initializer = initializer; |
| 1336 | } |
| 1337 | |
| 1338 | |
| 1339 | void |
| 1340 | ast_declarator_list::print(void) const |
| 1341 | { |
Ian Romanick | a87ac25 | 2010-02-22 13:19:34 -0800 | [diff] [blame] | 1342 | assert(type || invariant); |
| 1343 | |
| 1344 | if (type) |
| 1345 | type->print(); |
Chris Forbes | 5ecffe5 | 2014-04-27 16:03:54 +1200 | [diff] [blame] | 1346 | else if (invariant) |
Ian Romanick | a87ac25 | 2010-02-22 13:19:34 -0800 | [diff] [blame] | 1347 | printf("invariant "); |
Chris Forbes | 5ecffe5 | 2014-04-27 16:03:54 +1200 | [diff] [blame] | 1348 | else |
| 1349 | printf("precise "); |
Ian Romanick | a87ac25 | 2010-02-22 13:19:34 -0800 | [diff] [blame] | 1350 | |
Matt Turner | 6e217ad | 2014-06-24 22:02:24 -0700 | [diff] [blame] | 1351 | foreach_list_typed (ast_node, ast, link, & this->declarations) { |
| 1352 | if (&ast->link != this->declarations.get_head()) |
Ian Romanick | a87ac25 | 2010-02-22 13:19:34 -0800 | [diff] [blame] | 1353 | printf(", "); |
| 1354 | |
Ian Romanick | 304ea90 | 2010-05-10 11:17:53 -0700 | [diff] [blame] | 1355 | ast->print(); |
Ian Romanick | a87ac25 | 2010-02-22 13:19:34 -0800 | [diff] [blame] | 1356 | } |
| 1357 | |
| 1358 | printf("; "); |
| 1359 | } |
| 1360 | |
| 1361 | |
| 1362 | ast_declarator_list::ast_declarator_list(ast_fully_specified_type *type) |
| 1363 | { |
| 1364 | this->type = type; |
Ian Romanick | 3832706 | 2010-07-01 17:10:11 -0700 | [diff] [blame] | 1365 | this->invariant = false; |
Chris Forbes | 5ecffe5 | 2014-04-27 16:03:54 +1200 | [diff] [blame] | 1366 | this->precise = false; |
Ian Romanick | a87ac25 | 2010-02-22 13:19:34 -0800 | [diff] [blame] | 1367 | } |
| 1368 | |
| 1369 | void |
| 1370 | ast_jump_statement::print(void) const |
| 1371 | { |
| 1372 | switch (mode) { |
| 1373 | case ast_continue: |
| 1374 | printf("continue; "); |
| 1375 | break; |
| 1376 | case ast_break: |
| 1377 | printf("break; "); |
| 1378 | break; |
| 1379 | case ast_return: |
| 1380 | printf("return "); |
| 1381 | if (opt_return_value) |
| 1382 | opt_return_value->print(); |
| 1383 | |
| 1384 | printf("; "); |
| 1385 | break; |
| 1386 | case ast_discard: |
| 1387 | printf("discard; "); |
| 1388 | break; |
| 1389 | } |
| 1390 | } |
| 1391 | |
| 1392 | |
| 1393 | ast_jump_statement::ast_jump_statement(int mode, ast_expression *return_value) |
Vinson Lee | fa7829c | 2013-07-14 00:57:22 -0700 | [diff] [blame] | 1394 | : opt_return_value(NULL) |
Ian Romanick | a87ac25 | 2010-02-22 13:19:34 -0800 | [diff] [blame] | 1395 | { |
| 1396 | this->mode = ast_jump_modes(mode); |
| 1397 | |
| 1398 | if (mode == ast_return) |
| 1399 | opt_return_value = return_value; |
| 1400 | } |
| 1401 | |
| 1402 | |
| 1403 | void |
| 1404 | ast_selection_statement::print(void) const |
| 1405 | { |
| 1406 | printf("if ( "); |
| 1407 | condition->print(); |
| 1408 | printf(") "); |
| 1409 | |
| 1410 | then_statement->print(); |
| 1411 | |
| 1412 | if (else_statement) { |
| 1413 | printf("else "); |
| 1414 | else_statement->print(); |
| 1415 | } |
Ian Romanick | a87ac25 | 2010-02-22 13:19:34 -0800 | [diff] [blame] | 1416 | } |
| 1417 | |
| 1418 | |
| 1419 | ast_selection_statement::ast_selection_statement(ast_expression *condition, |
| 1420 | ast_node *then_statement, |
| 1421 | ast_node *else_statement) |
| 1422 | { |
| 1423 | this->condition = condition; |
| 1424 | this->then_statement = then_statement; |
| 1425 | this->else_statement = else_statement; |
| 1426 | } |
| 1427 | |
| 1428 | |
| 1429 | void |
Dan McCabe | 85beb39 | 2011-11-07 15:11:04 -0800 | [diff] [blame] | 1430 | ast_switch_statement::print(void) const |
| 1431 | { |
| 1432 | printf("switch ( "); |
| 1433 | test_expression->print(); |
| 1434 | printf(") "); |
| 1435 | |
| 1436 | body->print(); |
| 1437 | } |
| 1438 | |
| 1439 | |
| 1440 | ast_switch_statement::ast_switch_statement(ast_expression *test_expression, |
| 1441 | ast_node *body) |
| 1442 | { |
| 1443 | this->test_expression = test_expression; |
| 1444 | this->body = body; |
| 1445 | } |
| 1446 | |
| 1447 | |
| 1448 | void |
| 1449 | ast_switch_body::print(void) const |
| 1450 | { |
| 1451 | printf("{\n"); |
| 1452 | if (stmts != NULL) { |
| 1453 | stmts->print(); |
| 1454 | } |
| 1455 | printf("}\n"); |
| 1456 | } |
| 1457 | |
| 1458 | |
| 1459 | ast_switch_body::ast_switch_body(ast_case_statement_list *stmts) |
| 1460 | { |
| 1461 | this->stmts = stmts; |
| 1462 | } |
| 1463 | |
| 1464 | |
| 1465 | void ast_case_label::print(void) const |
| 1466 | { |
| 1467 | if (test_value != NULL) { |
| 1468 | printf("case "); |
| 1469 | test_value->print(); |
| 1470 | printf(": "); |
| 1471 | } else { |
| 1472 | printf("default: "); |
| 1473 | } |
| 1474 | } |
| 1475 | |
| 1476 | |
| 1477 | ast_case_label::ast_case_label(ast_expression *test_value) |
| 1478 | { |
| 1479 | this->test_value = test_value; |
| 1480 | } |
| 1481 | |
| 1482 | |
| 1483 | void ast_case_label_list::print(void) const |
| 1484 | { |
Matt Turner | 6e217ad | 2014-06-24 22:02:24 -0700 | [diff] [blame] | 1485 | foreach_list_typed(ast_node, ast, link, & this->labels) { |
Dan McCabe | 85beb39 | 2011-11-07 15:11:04 -0800 | [diff] [blame] | 1486 | ast->print(); |
| 1487 | } |
| 1488 | printf("\n"); |
| 1489 | } |
| 1490 | |
| 1491 | |
| 1492 | ast_case_label_list::ast_case_label_list(void) |
| 1493 | { |
| 1494 | } |
| 1495 | |
| 1496 | |
| 1497 | void ast_case_statement::print(void) const |
| 1498 | { |
| 1499 | labels->print(); |
Matt Turner | 6e217ad | 2014-06-24 22:02:24 -0700 | [diff] [blame] | 1500 | foreach_list_typed(ast_node, ast, link, & this->stmts) { |
Dan McCabe | 85beb39 | 2011-11-07 15:11:04 -0800 | [diff] [blame] | 1501 | ast->print(); |
| 1502 | printf("\n"); |
| 1503 | } |
| 1504 | } |
| 1505 | |
| 1506 | |
| 1507 | ast_case_statement::ast_case_statement(ast_case_label_list *labels) |
| 1508 | { |
| 1509 | this->labels = labels; |
| 1510 | } |
| 1511 | |
| 1512 | |
| 1513 | void ast_case_statement_list::print(void) const |
| 1514 | { |
Matt Turner | 6e217ad | 2014-06-24 22:02:24 -0700 | [diff] [blame] | 1515 | foreach_list_typed(ast_node, ast, link, & this->cases) { |
Dan McCabe | 85beb39 | 2011-11-07 15:11:04 -0800 | [diff] [blame] | 1516 | ast->print(); |
| 1517 | } |
| 1518 | } |
| 1519 | |
| 1520 | |
| 1521 | ast_case_statement_list::ast_case_statement_list(void) |
| 1522 | { |
| 1523 | } |
| 1524 | |
| 1525 | |
| 1526 | void |
Ian Romanick | a87ac25 | 2010-02-22 13:19:34 -0800 | [diff] [blame] | 1527 | ast_iteration_statement::print(void) const |
| 1528 | { |
| 1529 | switch (mode) { |
| 1530 | case ast_for: |
| 1531 | printf("for( "); |
| 1532 | if (init_statement) |
| 1533 | init_statement->print(); |
| 1534 | printf("; "); |
| 1535 | |
| 1536 | if (condition) |
| 1537 | condition->print(); |
| 1538 | printf("; "); |
| 1539 | |
| 1540 | if (rest_expression) |
| 1541 | rest_expression->print(); |
| 1542 | printf(") "); |
| 1543 | |
| 1544 | body->print(); |
| 1545 | break; |
| 1546 | |
| 1547 | case ast_while: |
| 1548 | printf("while ( "); |
| 1549 | if (condition) |
| 1550 | condition->print(); |
| 1551 | printf(") "); |
| 1552 | body->print(); |
| 1553 | break; |
| 1554 | |
| 1555 | case ast_do_while: |
| 1556 | printf("do "); |
| 1557 | body->print(); |
| 1558 | printf("while ( "); |
| 1559 | if (condition) |
| 1560 | condition->print(); |
| 1561 | printf("); "); |
| 1562 | break; |
| 1563 | } |
| 1564 | } |
| 1565 | |
| 1566 | |
| 1567 | ast_iteration_statement::ast_iteration_statement(int mode, |
| 1568 | ast_node *init, |
| 1569 | ast_node *condition, |
| 1570 | ast_expression *rest_expression, |
| 1571 | ast_node *body) |
| 1572 | { |
| 1573 | this->mode = ast_iteration_modes(mode); |
| 1574 | this->init_statement = init; |
| 1575 | this->condition = condition; |
| 1576 | this->rest_expression = rest_expression; |
| 1577 | this->body = body; |
| 1578 | } |
| 1579 | |
| 1580 | |
| 1581 | void |
| 1582 | ast_struct_specifier::print(void) const |
| 1583 | { |
Ian Romanick | a87ac25 | 2010-02-22 13:19:34 -0800 | [diff] [blame] | 1584 | printf("struct %s { ", name); |
Matt Turner | 6e217ad | 2014-06-24 22:02:24 -0700 | [diff] [blame] | 1585 | foreach_list_typed(ast_node, ast, link, &this->declarations) { |
Ian Romanick | 304ea90 | 2010-05-10 11:17:53 -0700 | [diff] [blame] | 1586 | ast->print(); |
Ian Romanick | a87ac25 | 2010-02-22 13:19:34 -0800 | [diff] [blame] | 1587 | } |
| 1588 | printf("} "); |
| 1589 | } |
| 1590 | |
| 1591 | |
Kenneth Graunke | b2c0df2 | 2012-03-29 23:17:31 -0700 | [diff] [blame] | 1592 | ast_struct_specifier::ast_struct_specifier(const char *identifier, |
Eric Anholt | 912a429 | 2012-04-26 10:16:52 -0700 | [diff] [blame] | 1593 | ast_declarator_list *declarator_list) |
Ian Romanick | a87ac25 | 2010-02-22 13:19:34 -0800 | [diff] [blame] | 1594 | { |
Kenneth Graunke | ca92ae2 | 2010-09-18 11:11:09 +0200 | [diff] [blame] | 1595 | if (identifier == NULL) { |
Chia-I Wu | a670616 | 2014-08-20 14:40:28 +0800 | [diff] [blame] | 1596 | static mtx_t mutex = _MTX_INITIALIZER_NP; |
Kenneth Graunke | ca92ae2 | 2010-09-18 11:11:09 +0200 | [diff] [blame] | 1597 | static unsigned anon_count = 1; |
Chia-I Wu | a670616 | 2014-08-20 14:40:28 +0800 | [diff] [blame] | 1598 | unsigned count; |
| 1599 | |
| 1600 | mtx_lock(&mutex); |
| 1601 | count = anon_count++; |
| 1602 | mtx_unlock(&mutex); |
| 1603 | |
| 1604 | identifier = ralloc_asprintf(this, "#anon_struct_%04x", count); |
Kenneth Graunke | ca92ae2 | 2010-09-18 11:11:09 +0200 | [diff] [blame] | 1605 | } |
Ian Romanick | a87ac25 | 2010-02-22 13:19:34 -0800 | [diff] [blame] | 1606 | name = identifier; |
Ian Romanick | 304ea90 | 2010-05-10 11:17:53 -0700 | [diff] [blame] | 1607 | this->declarations.push_degenerate_list_at_head(&declarator_list->link); |
Matt Turner | 8d45caa | 2013-06-26 15:53:12 -0700 | [diff] [blame] | 1608 | is_declaration = true; |
Ian Romanick | a87ac25 | 2010-02-22 13:19:34 -0800 | [diff] [blame] | 1609 | } |
Eric Anholt | 2f4fe15 | 2010-08-10 13:06:49 -0700 | [diff] [blame] | 1610 | |
Dave Airlie | 65ac360 | 2015-06-01 10:55:47 +1000 | [diff] [blame] | 1611 | void ast_subroutine_list::print(void) const |
| 1612 | { |
| 1613 | foreach_list_typed (ast_node, ast, link, & this->declarations) { |
| 1614 | if (&ast->link != this->declarations.get_head()) |
| 1615 | printf(", "); |
| 1616 | ast->print(); |
| 1617 | } |
| 1618 | } |
| 1619 | |
Eric Anholt | 010a6a8 | 2013-06-12 17:21:44 -0700 | [diff] [blame] | 1620 | static void |
| 1621 | set_shader_inout_layout(struct gl_shader *shader, |
| 1622 | struct _mesa_glsl_parse_state *state) |
| 1623 | { |
Fabian Bieler | 497eb29 | 2014-03-20 22:44:43 +0100 | [diff] [blame] | 1624 | /* Should have been prevented by the parser. */ |
| 1625 | if (shader->Stage == MESA_SHADER_TESS_CTRL) { |
| 1626 | assert(!state->in_qualifier->flags.i); |
| 1627 | } else if (shader->Stage == MESA_SHADER_TESS_EVAL) { |
| 1628 | assert(!state->out_qualifier->flags.i); |
| 1629 | } else if (shader->Stage != MESA_SHADER_GEOMETRY) { |
Jordan Justen | 0c558f9 | 2014-02-02 17:49:15 -0800 | [diff] [blame] | 1630 | assert(!state->in_qualifier->flags.i); |
Eric Anholt | 010a6a8 | 2013-06-12 17:21:44 -0700 | [diff] [blame] | 1631 | assert(!state->out_qualifier->flags.i); |
Eric Anholt | 010a6a8 | 2013-06-12 17:21:44 -0700 | [diff] [blame] | 1632 | } |
| 1633 | |
Paul Berry | 0fa74e8 | 2014-01-06 09:09:31 -0800 | [diff] [blame] | 1634 | if (shader->Stage != MESA_SHADER_COMPUTE) { |
| 1635 | /* Should have been prevented by the parser. */ |
| 1636 | assert(!state->cs_input_local_size_specified); |
Eric Anholt | 010a6a8 | 2013-06-12 17:21:44 -0700 | [diff] [blame] | 1637 | } |
| 1638 | |
Anuj Phogat | 35f11e8 | 2014-02-05 15:01:58 -0800 | [diff] [blame] | 1639 | if (shader->Stage != MESA_SHADER_FRAGMENT) { |
| 1640 | /* Should have been prevented by the parser. */ |
| 1641 | assert(!state->fs_uses_gl_fragcoord); |
| 1642 | assert(!state->fs_redeclares_gl_fragcoord); |
| 1643 | assert(!state->fs_pixel_center_integer); |
| 1644 | assert(!state->fs_origin_upper_left); |
Francisco Jerez | ce0e151 | 2015-01-28 17:42:37 +0200 | [diff] [blame] | 1645 | assert(!state->fs_early_fragment_tests); |
Anuj Phogat | 35f11e8 | 2014-02-05 15:01:58 -0800 | [diff] [blame] | 1646 | } |
| 1647 | |
Paul Berry | 0fa74e8 | 2014-01-06 09:09:31 -0800 | [diff] [blame] | 1648 | switch (shader->Stage) { |
Fabian Bieler | 497eb29 | 2014-03-20 22:44:43 +0100 | [diff] [blame] | 1649 | case MESA_SHADER_TESS_CTRL: |
| 1650 | shader->TessCtrl.VerticesOut = 0; |
Timothy Arceri | 02d2ab2 | 2015-11-14 15:13:28 +1100 | [diff] [blame] | 1651 | if (state->tcs_output_vertices_specified) { |
| 1652 | unsigned vertices; |
| 1653 | if (state->out_qualifier->vertices-> |
| 1654 | process_qualifier_constant(state, "vertices", &vertices, |
| 1655 | false)) { |
| 1656 | |
| 1657 | YYLTYPE loc = state->out_qualifier->vertices->get_location(); |
| 1658 | if (vertices > state->Const.MaxPatchVertices) { |
| 1659 | _mesa_glsl_error(&loc, state, "vertices (%d) exceeds " |
| 1660 | "GL_MAX_PATCH_VERTICES", vertices); |
| 1661 | } |
| 1662 | shader->TessCtrl.VerticesOut = vertices; |
| 1663 | } |
| 1664 | } |
Fabian Bieler | 497eb29 | 2014-03-20 22:44:43 +0100 | [diff] [blame] | 1665 | break; |
| 1666 | case MESA_SHADER_TESS_EVAL: |
| 1667 | shader->TessEval.PrimitiveMode = PRIM_UNKNOWN; |
| 1668 | if (state->in_qualifier->flags.q.prim_type) |
| 1669 | shader->TessEval.PrimitiveMode = state->in_qualifier->prim_type; |
| 1670 | |
| 1671 | shader->TessEval.Spacing = 0; |
| 1672 | if (state->in_qualifier->flags.q.vertex_spacing) |
| 1673 | shader->TessEval.Spacing = state->in_qualifier->vertex_spacing; |
| 1674 | |
| 1675 | shader->TessEval.VertexOrder = 0; |
| 1676 | if (state->in_qualifier->flags.q.ordering) |
| 1677 | shader->TessEval.VertexOrder = state->in_qualifier->ordering; |
| 1678 | |
| 1679 | shader->TessEval.PointMode = -1; |
| 1680 | if (state->in_qualifier->flags.q.point_mode) |
| 1681 | shader->TessEval.PointMode = state->in_qualifier->point_mode; |
| 1682 | break; |
Paul Berry | 0fa74e8 | 2014-01-06 09:09:31 -0800 | [diff] [blame] | 1683 | case MESA_SHADER_GEOMETRY: |
| 1684 | shader->Geom.VerticesOut = 0; |
Timothy Arceri | 02d2ab2 | 2015-11-14 15:13:28 +1100 | [diff] [blame] | 1685 | if (state->out_qualifier->flags.q.max_vertices) { |
| 1686 | unsigned qual_max_vertices; |
| 1687 | if (state->out_qualifier->max_vertices-> |
| 1688 | process_qualifier_constant(state, "max_vertices", |
| 1689 | &qual_max_vertices, true)) { |
| 1690 | shader->Geom.VerticesOut = qual_max_vertices; |
| 1691 | } |
| 1692 | } |
Paul Berry | 0fa74e8 | 2014-01-06 09:09:31 -0800 | [diff] [blame] | 1693 | |
| 1694 | if (state->gs_input_prim_type_specified) { |
Jordan Justen | 0c558f9 | 2014-02-02 17:49:15 -0800 | [diff] [blame] | 1695 | shader->Geom.InputType = state->in_qualifier->prim_type; |
Paul Berry | 0fa74e8 | 2014-01-06 09:09:31 -0800 | [diff] [blame] | 1696 | } else { |
| 1697 | shader->Geom.InputType = PRIM_UNKNOWN; |
| 1698 | } |
| 1699 | |
| 1700 | if (state->out_qualifier->flags.q.prim_type) { |
| 1701 | shader->Geom.OutputType = state->out_qualifier->prim_type; |
| 1702 | } else { |
| 1703 | shader->Geom.OutputType = PRIM_UNKNOWN; |
| 1704 | } |
Jordan Justen | 3134020 | 2014-01-25 02:17:21 -0800 | [diff] [blame] | 1705 | |
| 1706 | shader->Geom.Invocations = 0; |
Timothy Arceri | 02d2ab2 | 2015-11-14 15:13:28 +1100 | [diff] [blame] | 1707 | if (state->in_qualifier->flags.q.invocations) { |
| 1708 | unsigned invocations; |
| 1709 | if (state->in_qualifier->invocations-> |
| 1710 | process_qualifier_constant(state, "invocations", |
| 1711 | &invocations, false)) { |
| 1712 | |
| 1713 | YYLTYPE loc = state->in_qualifier->invocations->get_location(); |
| 1714 | if (invocations > MAX_GEOMETRY_SHADER_INVOCATIONS) { |
| 1715 | _mesa_glsl_error(&loc, state, |
| 1716 | "invocations (%d) exceeds " |
| 1717 | "GL_MAX_GEOMETRY_SHADER_INVOCATIONS", |
| 1718 | invocations); |
| 1719 | } |
| 1720 | shader->Geom.Invocations = invocations; |
| 1721 | } |
| 1722 | } |
Paul Berry | 0fa74e8 | 2014-01-06 09:09:31 -0800 | [diff] [blame] | 1723 | break; |
| 1724 | |
| 1725 | case MESA_SHADER_COMPUTE: |
| 1726 | if (state->cs_input_local_size_specified) { |
| 1727 | for (int i = 0; i < 3; i++) |
| 1728 | shader->Comp.LocalSize[i] = state->cs_input_local_size[i]; |
| 1729 | } else { |
| 1730 | for (int i = 0; i < 3; i++) |
| 1731 | shader->Comp.LocalSize[i] = 0; |
| 1732 | } |
| 1733 | break; |
| 1734 | |
Anuj Phogat | 35f11e8 | 2014-02-05 15:01:58 -0800 | [diff] [blame] | 1735 | case MESA_SHADER_FRAGMENT: |
| 1736 | shader->redeclares_gl_fragcoord = state->fs_redeclares_gl_fragcoord; |
| 1737 | shader->uses_gl_fragcoord = state->fs_uses_gl_fragcoord; |
| 1738 | shader->pixel_center_integer = state->fs_pixel_center_integer; |
| 1739 | shader->origin_upper_left = state->fs_origin_upper_left; |
Anuj Phogat | 9bcb0a8 | 2014-02-10 14:12:40 -0800 | [diff] [blame] | 1740 | shader->ARB_fragment_coord_conventions_enable = |
| 1741 | state->ARB_fragment_coord_conventions_enable; |
Francisco Jerez | ce0e151 | 2015-01-28 17:42:37 +0200 | [diff] [blame] | 1742 | shader->EarlyFragmentTests = state->fs_early_fragment_tests; |
Anuj Phogat | 35f11e8 | 2014-02-05 15:01:58 -0800 | [diff] [blame] | 1743 | break; |
| 1744 | |
Paul Berry | 0fa74e8 | 2014-01-06 09:09:31 -0800 | [diff] [blame] | 1745 | default: |
| 1746 | /* Nothing to do. */ |
| 1747 | break; |
Eric Anholt | 010a6a8 | 2013-06-12 17:21:44 -0700 | [diff] [blame] | 1748 | } |
| 1749 | } |
| 1750 | |
Eric Anholt | 0343f20 | 2013-06-12 15:49:43 -0700 | [diff] [blame] | 1751 | extern "C" { |
| 1752 | |
| 1753 | void |
| 1754 | _mesa_glsl_compile_shader(struct gl_context *ctx, struct gl_shader *shader, |
| 1755 | bool dump_ast, bool dump_hir) |
| 1756 | { |
| 1757 | struct _mesa_glsl_parse_state *state = |
Paul Berry | 9110078 | 2014-01-07 09:46:10 -0800 | [diff] [blame] | 1758 | new(shader) _mesa_glsl_parse_state(ctx, shader->Stage, shader); |
Eric Anholt | 0343f20 | 2013-06-12 15:49:43 -0700 | [diff] [blame] | 1759 | const char *source = shader->Source; |
| 1760 | |
Ian Romanick | c87d09d | 2014-07-08 19:03:52 -0700 | [diff] [blame] | 1761 | if (ctx->Const.GenerateTemporaryNames) |
Matt Turner | 9db278d | 2014-11-21 18:04:21 -0800 | [diff] [blame] | 1762 | (void) p_atomic_cmpxchg(&ir_variable::temporaries_allocate_names, |
| 1763 | false, true); |
Ian Romanick | c87d09d | 2014-07-08 19:03:52 -0700 | [diff] [blame] | 1764 | |
Eric Anholt | 0343f20 | 2013-06-12 15:49:43 -0700 | [diff] [blame] | 1765 | state->error = glcpp_preprocess(state, &source, &state->info_log, |
| 1766 | &ctx->Extensions, ctx); |
| 1767 | |
| 1768 | if (!state->error) { |
| 1769 | _mesa_glsl_lexer_ctor(state, source); |
| 1770 | _mesa_glsl_parse(state); |
| 1771 | _mesa_glsl_lexer_dtor(state); |
| 1772 | } |
| 1773 | |
| 1774 | if (dump_ast) { |
Matt Turner | 6e217ad | 2014-06-24 22:02:24 -0700 | [diff] [blame] | 1775 | foreach_list_typed(ast_node, ast, link, &state->translation_unit) { |
Eric Anholt | 0343f20 | 2013-06-12 15:49:43 -0700 | [diff] [blame] | 1776 | ast->print(); |
| 1777 | } |
| 1778 | printf("\n\n"); |
| 1779 | } |
| 1780 | |
| 1781 | ralloc_free(shader->ir); |
| 1782 | shader->ir = new(shader) exec_list; |
| 1783 | if (!state->error && !state->translation_unit.is_empty()) |
| 1784 | _mesa_ast_to_hir(shader->ir, state); |
| 1785 | |
| 1786 | if (!state->error) { |
| 1787 | validate_ir_tree(shader->ir); |
| 1788 | |
| 1789 | /* Print out the unoptimized IR. */ |
| 1790 | if (dump_hir) { |
Eric Anholt | 1e3bd9f | 2014-02-20 18:00:23 -0800 | [diff] [blame] | 1791 | _mesa_print_ir(stdout, shader->ir, state); |
Eric Anholt | 0343f20 | 2013-06-12 15:49:43 -0700 | [diff] [blame] | 1792 | } |
| 1793 | } |
| 1794 | |
| 1795 | |
| 1796 | if (!state->error && !shader->ir->is_empty()) { |
| 1797 | struct gl_shader_compiler_options *options = |
Marek Olšák | 002211f | 2014-08-03 04:31:56 +0200 | [diff] [blame] | 1798 | &ctx->Const.ShaderCompilerOptions[shader->Stage]; |
Eric Anholt | 0343f20 | 2013-06-12 15:49:43 -0700 | [diff] [blame] | 1799 | |
Dave Airlie | 7dd429e | 2015-04-23 13:34:14 +1000 | [diff] [blame] | 1800 | lower_subroutine(shader->ir, state); |
Eric Anholt | 0343f20 | 2013-06-12 15:49:43 -0700 | [diff] [blame] | 1801 | /* Do some optimization at compile time to reduce shader IR size |
| 1802 | * and reduce later work if the same shader is linked multiple times |
| 1803 | */ |
Kenneth Graunke | da22221 | 2014-04-08 15:43:46 -0700 | [diff] [blame] | 1804 | while (do_common_optimization(shader->ir, false, false, options, |
Kenneth Graunke | 169c645 | 2014-04-06 23:25:00 -0700 | [diff] [blame] | 1805 | ctx->Const.NativeIntegers)) |
Eric Anholt | 0343f20 | 2013-06-12 15:49:43 -0700 | [diff] [blame] | 1806 | ; |
| 1807 | |
| 1808 | validate_ir_tree(shader->ir); |
Ian Romanick | 1012e95 | 2014-05-28 17:09:45 -0700 | [diff] [blame] | 1809 | |
| 1810 | enum ir_variable_mode other; |
| 1811 | switch (shader->Stage) { |
| 1812 | case MESA_SHADER_VERTEX: |
| 1813 | other = ir_var_shader_in; |
| 1814 | break; |
| 1815 | case MESA_SHADER_FRAGMENT: |
| 1816 | other = ir_var_shader_out; |
| 1817 | break; |
| 1818 | default: |
| 1819 | /* Something invalid to ensure optimize_dead_builtin_uniforms |
| 1820 | * doesn't remove anything other than uniforms or constants. |
| 1821 | */ |
| 1822 | other = ir_var_mode_count; |
| 1823 | break; |
| 1824 | } |
| 1825 | |
| 1826 | optimize_dead_builtin_variables(shader->ir, other); |
| 1827 | |
| 1828 | validate_ir_tree(shader->ir); |
Eric Anholt | 0343f20 | 2013-06-12 15:49:43 -0700 | [diff] [blame] | 1829 | } |
| 1830 | |
| 1831 | if (shader->InfoLog) |
| 1832 | ralloc_free(shader->InfoLog); |
| 1833 | |
Timothy Arceri | 4196af4 | 2015-11-14 14:05:30 +1100 | [diff] [blame] | 1834 | if (!state->error) |
| 1835 | set_shader_inout_layout(shader, state); |
| 1836 | |
Ian Romanick | 7b18983 | 2014-07-14 15:48:34 -0700 | [diff] [blame] | 1837 | shader->symbols = new(shader->ir) glsl_symbol_table; |
Eric Anholt | 0343f20 | 2013-06-12 15:49:43 -0700 | [diff] [blame] | 1838 | shader->CompileStatus = !state->error; |
| 1839 | shader->InfoLog = state->info_log; |
| 1840 | shader->Version = state->language_version; |
Eric Anholt | 0343f20 | 2013-06-12 15:49:43 -0700 | [diff] [blame] | 1841 | shader->IsES = state->es_shader; |
Kenneth Graunke | 5b331f6 | 2013-11-23 12:11:34 -0800 | [diff] [blame] | 1842 | shader->uses_builtin_functions = state->uses_builtin_functions; |
Eric Anholt | 0343f20 | 2013-06-12 15:49:43 -0700 | [diff] [blame] | 1843 | |
Eric Anholt | 0343f20 | 2013-06-12 15:49:43 -0700 | [diff] [blame] | 1844 | /* Retain any live IR, but trash the rest. */ |
| 1845 | reparent_ir(shader->ir, shader->ir); |
| 1846 | |
Ian Romanick | 7b18983 | 2014-07-14 15:48:34 -0700 | [diff] [blame] | 1847 | /* Destroy the symbol table. Create a new symbol table that contains only |
| 1848 | * the variables and functions that still exist in the IR. The symbol |
| 1849 | * table will be used later during linking. |
| 1850 | * |
| 1851 | * There must NOT be any freed objects still referenced by the symbol |
| 1852 | * table. That could cause the linker to dereference freed memory. |
| 1853 | * |
| 1854 | * We don't have to worry about types or interface-types here because those |
| 1855 | * are fly-weights that are looked up by glsl_type. |
| 1856 | */ |
| 1857 | foreach_in_list (ir_instruction, ir, shader->ir) { |
| 1858 | switch (ir->ir_type) { |
| 1859 | case ir_type_function: |
| 1860 | shader->symbols->add_function((ir_function *) ir); |
| 1861 | break; |
Ian Romanick | a994824 | 2014-07-08 18:53:09 -0700 | [diff] [blame] | 1862 | case ir_type_variable: { |
| 1863 | ir_variable *const var = (ir_variable *) ir; |
| 1864 | |
| 1865 | if (var->data.mode != ir_var_temporary) |
| 1866 | shader->symbols->add_variable(var); |
Ian Romanick | 7b18983 | 2014-07-14 15:48:34 -0700 | [diff] [blame] | 1867 | break; |
Ian Romanick | a994824 | 2014-07-08 18:53:09 -0700 | [diff] [blame] | 1868 | } |
Ian Romanick | 7b18983 | 2014-07-14 15:48:34 -0700 | [diff] [blame] | 1869 | default: |
| 1870 | break; |
| 1871 | } |
| 1872 | } |
| 1873 | |
Jordan Justen | 2b6cc03 | 2015-08-17 14:35:44 -0700 | [diff] [blame] | 1874 | _mesa_glsl_initialize_derived_variables(shader); |
| 1875 | |
Ian Romanick | 7b18983 | 2014-07-14 15:48:34 -0700 | [diff] [blame] | 1876 | delete state->symbols; |
Eric Anholt | 0343f20 | 2013-06-12 15:49:43 -0700 | [diff] [blame] | 1877 | ralloc_free(state); |
| 1878 | } |
| 1879 | |
| 1880 | } /* extern "C" */ |
Ian Romanick | 1d5d67f | 2011-10-21 11:17:39 -0700 | [diff] [blame] | 1881 | /** |
| 1882 | * Do the set of common optimizations passes |
| 1883 | * |
| 1884 | * \param ir List of instructions to be optimized |
| 1885 | * \param linked Is the shader linked? This enables |
| 1886 | * optimizations passes that remove code at |
| 1887 | * global scope and could cause linking to |
| 1888 | * fail. |
| 1889 | * \param uniform_locations_assigned Have locations already been assigned for |
| 1890 | * uniforms? This prevents the declarations |
| 1891 | * of unused uniforms from being removed. |
| 1892 | * The setting of this flag only matters if |
| 1893 | * \c linked is \c true. |
| 1894 | * \param max_unroll_iterations Maximum number of loop iterations to be |
Marek Olšák | fc86394 | 2013-01-31 23:29:53 +0100 | [diff] [blame] | 1895 | * unrolled. Setting to 0 disables loop |
| 1896 | * unrolling. |
Kenneth Graunke | b765740 | 2013-04-17 17:30:22 -0700 | [diff] [blame] | 1897 | * \param options The driver's preferred shader options. |
Ian Romanick | 1d5d67f | 2011-10-21 11:17:39 -0700 | [diff] [blame] | 1898 | */ |
Eric Anholt | 2f4fe15 | 2010-08-10 13:06:49 -0700 | [diff] [blame] | 1899 | bool |
Ian Romanick | 1d5d67f | 2011-10-21 11:17:39 -0700 | [diff] [blame] | 1900 | do_common_optimization(exec_list *ir, bool linked, |
| 1901 | bool uniform_locations_assigned, |
Kenneth Graunke | 169c645 | 2014-04-06 23:25:00 -0700 | [diff] [blame] | 1902 | const struct gl_shader_compiler_options *options, |
| 1903 | bool native_integers) |
Eric Anholt | 2f4fe15 | 2010-08-10 13:06:49 -0700 | [diff] [blame] | 1904 | { |
| 1905 | GLboolean progress = GL_FALSE; |
| 1906 | |
Kenneth Graunke | 63684a9 | 2010-11-18 17:54:07 -0800 | [diff] [blame] | 1907 | progress = lower_instructions(ir, SUB_TO_ADD_NEG) || progress; |
Eric Anholt | 2f4fe15 | 2010-08-10 13:06:49 -0700 | [diff] [blame] | 1908 | |
| 1909 | if (linked) { |
| 1910 | progress = do_function_inlining(ir) || progress; |
| 1911 | progress = do_dead_functions(ir) || progress; |
Eric Anholt | 60df737 | 2011-09-07 12:04:57 -0700 | [diff] [blame] | 1912 | progress = do_structure_splitting(ir) || progress; |
Eric Anholt | 2f4fe15 | 2010-08-10 13:06:49 -0700 | [diff] [blame] | 1913 | } |
Eric Anholt | 2f4fe15 | 2010-08-10 13:06:49 -0700 | [diff] [blame] | 1914 | progress = do_if_simplification(ir) || progress; |
Kenneth Graunke | edc52a8 | 2013-04-03 23:56:57 -0700 | [diff] [blame] | 1915 | progress = opt_flatten_nested_if_blocks(ir) || progress; |
Kenneth Graunke | 30f51f1 | 2014-10-22 20:48:21 -0700 | [diff] [blame] | 1916 | progress = opt_conditional_discard(ir) || progress; |
Eric Anholt | 2f4fe15 | 2010-08-10 13:06:49 -0700 | [diff] [blame] | 1917 | progress = do_copy_propagation(ir) || progress; |
Eric Anholt | 6a35cbb | 2011-04-02 20:19:20 -0700 | [diff] [blame] | 1918 | progress = do_copy_propagation_elements(ir) || progress; |
Kenneth Graunke | e413d3f | 2013-04-17 17:30:25 -0700 | [diff] [blame] | 1919 | |
Matt Turner | ebf9199 | 2014-01-03 14:48:53 -0800 | [diff] [blame] | 1920 | if (options->OptimizeForAOS && !linked) |
Kenneth Graunke | e413d3f | 2013-04-17 17:30:25 -0700 | [diff] [blame] | 1921 | progress = opt_flip_matrices(ir) || progress; |
| 1922 | |
Matt Turner | 4bd6e0d | 2013-12-21 11:28:05 -0800 | [diff] [blame] | 1923 | if (linked && options->OptimizeForAOS) { |
| 1924 | progress = do_vectorize(ir) || progress; |
| 1925 | } |
| 1926 | |
Eric Anholt | 2f4fe15 | 2010-08-10 13:06:49 -0700 | [diff] [blame] | 1927 | if (linked) |
Ian Romanick | 1d5d67f | 2011-10-21 11:17:39 -0700 | [diff] [blame] | 1928 | progress = do_dead_code(ir, uniform_locations_assigned) || progress; |
Eric Anholt | 2f4fe15 | 2010-08-10 13:06:49 -0700 | [diff] [blame] | 1929 | else |
| 1930 | progress = do_dead_code_unlinked(ir) || progress; |
| 1931 | progress = do_dead_code_local(ir) || progress; |
| 1932 | progress = do_tree_grafting(ir) || progress; |
| 1933 | progress = do_constant_propagation(ir) || progress; |
| 1934 | if (linked) |
| 1935 | progress = do_constant_variable(ir) || progress; |
| 1936 | else |
| 1937 | progress = do_constant_variable_unlinked(ir) || progress; |
| 1938 | progress = do_constant_folding(ir) || progress; |
Iago Toral Quiroga | fd31628 | 2014-07-29 12:36:31 +0300 | [diff] [blame] | 1939 | progress = do_minmax_prune(ir) || progress; |
Matt Turner | 1d9f74e | 2014-02-28 20:11:32 -0800 | [diff] [blame] | 1940 | progress = do_rebalance_tree(ir) || progress; |
Matt Turner | f043971 | 2014-02-28 17:49:20 -0800 | [diff] [blame] | 1941 | progress = do_algebraic(ir, native_integers, options) || progress; |
Luca Barbieri | 3361cba | 2010-09-07 00:24:08 +0200 | [diff] [blame] | 1942 | progress = do_lower_jumps(ir) || progress; |
Eric Anholt | 2f4fe15 | 2010-08-10 13:06:49 -0700 | [diff] [blame] | 1943 | progress = do_vec_index_to_swizzle(ir) || progress; |
Ian Romanick | ee7a6da | 2013-03-18 14:45:53 -0700 | [diff] [blame] | 1944 | progress = lower_vector_insert(ir, false) || progress; |
Eric Anholt | 2f4fe15 | 2010-08-10 13:06:49 -0700 | [diff] [blame] | 1945 | progress = do_swizzle_swizzle(ir) || progress; |
Eric Anholt | 8f8cdbf | 2010-08-13 07:16:38 -0700 | [diff] [blame] | 1946 | progress = do_noop_swizzle(ir) || progress; |
Eric Anholt | 2f4fe15 | 2010-08-10 13:06:49 -0700 | [diff] [blame] | 1947 | |
Eric Anholt | 60177d5 | 2010-10-02 22:57:17 -0700 | [diff] [blame] | 1948 | progress = optimize_split_arrays(ir, linked) || progress; |
Ian Romanick | 8f2214f | 2010-09-13 14:25:26 -0700 | [diff] [blame] | 1949 | progress = optimize_redundant_jumps(ir) || progress; |
| 1950 | |
Ian Romanick | 8df2dbf | 2010-08-26 16:45:22 -0700 | [diff] [blame] | 1951 | loop_state *ls = analyze_loop_variables(ir); |
Eric Anholt | 58c988a | 2011-01-17 22:07:55 -0800 | [diff] [blame] | 1952 | if (ls->loop_found) { |
| 1953 | progress = set_loop_controls(ir, ls) || progress; |
Kenneth Graunke | 8268a2f | 2014-04-08 19:58:36 -0700 | [diff] [blame] | 1954 | progress = unroll_loops(ir, ls, options) || progress; |
Eric Anholt | 58c988a | 2011-01-17 22:07:55 -0800 | [diff] [blame] | 1955 | } |
Ian Romanick | 8df2dbf | 2010-08-26 16:45:22 -0700 | [diff] [blame] | 1956 | delete ls; |
| 1957 | |
Eric Anholt | 2f4fe15 | 2010-08-10 13:06:49 -0700 | [diff] [blame] | 1958 | return progress; |
| 1959 | } |
Eric Anholt | b838464 | 2010-08-18 16:56:39 -0700 | [diff] [blame] | 1960 | |
| 1961 | extern "C" { |
| 1962 | |
| 1963 | /** |
| 1964 | * To be called at GL teardown time, this frees compiler datastructures. |
| 1965 | * |
| 1966 | * After calling this, any previously compiled shaders and shader |
| 1967 | * programs would be invalid. So this should happen at approximately |
| 1968 | * program exit. |
| 1969 | */ |
| 1970 | void |
| 1971 | _mesa_destroy_shader_compiler(void) |
| 1972 | { |
| 1973 | _mesa_destroy_shader_compiler_caches(); |
| 1974 | |
| 1975 | _mesa_glsl_release_types(); |
| 1976 | } |
| 1977 | |
| 1978 | /** |
| 1979 | * Releases compiler caches to trade off performance for memory. |
| 1980 | * |
| 1981 | * Intended to be used with glReleaseShaderCompiler(). |
| 1982 | */ |
| 1983 | void |
| 1984 | _mesa_destroy_shader_compiler_caches(void) |
| 1985 | { |
Kenneth Graunke | 76d2f73 | 2013-09-01 20:48:45 -0700 | [diff] [blame] | 1986 | _mesa_glsl_release_builtin_functions(); |
Eric Anholt | b838464 | 2010-08-18 16:56:39 -0700 | [diff] [blame] | 1987 | } |
| 1988 | |
| 1989 | } |