1bf215546Sopenharmony_ci/*
2bf215546Sopenharmony_ci * Copyright © 2008, 2009 Intel Corporation
3bf215546Sopenharmony_ci *
4bf215546Sopenharmony_ci * Permission is hereby granted, free of charge, to any person obtaining a
5bf215546Sopenharmony_ci * copy of this software and associated documentation files (the "Software"),
6bf215546Sopenharmony_ci * to deal in the Software without restriction, including without limitation
7bf215546Sopenharmony_ci * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8bf215546Sopenharmony_ci * and/or sell copies of the Software, and to permit persons to whom the
9bf215546Sopenharmony_ci * Software is furnished to do so, subject to the following conditions:
10bf215546Sopenharmony_ci *
11bf215546Sopenharmony_ci * The above copyright notice and this permission notice (including the next
12bf215546Sopenharmony_ci * paragraph) shall be included in all copies or substantial portions of the
13bf215546Sopenharmony_ci * Software.
14bf215546Sopenharmony_ci *
15bf215546Sopenharmony_ci * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16bf215546Sopenharmony_ci * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17bf215546Sopenharmony_ci * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
18bf215546Sopenharmony_ci * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19bf215546Sopenharmony_ci * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20bf215546Sopenharmony_ci * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
21bf215546Sopenharmony_ci * DEALINGS IN THE SOFTWARE.
22bf215546Sopenharmony_ci */
23bf215546Sopenharmony_ci#include <getopt.h>
24bf215546Sopenharmony_ci
25bf215546Sopenharmony_ci/** @file standalone.cpp
26bf215546Sopenharmony_ci *
27bf215546Sopenharmony_ci * Standalone compiler helper lib.  Used by standalone glsl_compiler and
28bf215546Sopenharmony_ci * also available to drivers to implement their own standalone compiler
29bf215546Sopenharmony_ci * with driver backend.
30bf215546Sopenharmony_ci */
31bf215546Sopenharmony_ci
32bf215546Sopenharmony_ci#include "ast.h"
33bf215546Sopenharmony_ci#include "glsl_parser_extras.h"
34bf215546Sopenharmony_ci#include "ir_optimization.h"
35bf215546Sopenharmony_ci#include "program.h"
36bf215546Sopenharmony_ci#include "standalone_scaffolding.h"
37bf215546Sopenharmony_ci#include "standalone.h"
38bf215546Sopenharmony_ci#include "string_to_uint_map.h"
39bf215546Sopenharmony_ci#include "util/set.h"
40bf215546Sopenharmony_ci#include "linker.h"
41bf215546Sopenharmony_ci#include "glsl_parser_extras.h"
42bf215546Sopenharmony_ci#include "ir_builder_print_visitor.h"
43bf215546Sopenharmony_ci#include "builtin_functions.h"
44bf215546Sopenharmony_ci#include "opt_add_neg_to_sub.h"
45bf215546Sopenharmony_ci#include "main/mtypes.h"
46bf215546Sopenharmony_ci#include "program/program.h"
47bf215546Sopenharmony_ci
48bf215546Sopenharmony_ciclass dead_variable_visitor : public ir_hierarchical_visitor {
49bf215546Sopenharmony_cipublic:
50bf215546Sopenharmony_ci   dead_variable_visitor()
51bf215546Sopenharmony_ci   {
52bf215546Sopenharmony_ci      variables = _mesa_pointer_set_create(NULL);
53bf215546Sopenharmony_ci   }
54bf215546Sopenharmony_ci
55bf215546Sopenharmony_ci   virtual ~dead_variable_visitor()
56bf215546Sopenharmony_ci   {
57bf215546Sopenharmony_ci      _mesa_set_destroy(variables, NULL);
58bf215546Sopenharmony_ci   }
59bf215546Sopenharmony_ci
60bf215546Sopenharmony_ci   virtual ir_visitor_status visit(ir_variable *ir)
61bf215546Sopenharmony_ci   {
62bf215546Sopenharmony_ci      /* If the variable is auto or temp, add it to the set of variables that
63bf215546Sopenharmony_ci       * are candidates for removal.
64bf215546Sopenharmony_ci       */
65bf215546Sopenharmony_ci      if (ir->data.mode != ir_var_auto && ir->data.mode != ir_var_temporary)
66bf215546Sopenharmony_ci         return visit_continue;
67bf215546Sopenharmony_ci
68bf215546Sopenharmony_ci      _mesa_set_add(variables, ir);
69bf215546Sopenharmony_ci
70bf215546Sopenharmony_ci      return visit_continue;
71bf215546Sopenharmony_ci   }
72bf215546Sopenharmony_ci
73bf215546Sopenharmony_ci   virtual ir_visitor_status visit(ir_dereference_variable *ir)
74bf215546Sopenharmony_ci   {
75bf215546Sopenharmony_ci      struct set_entry *entry = _mesa_set_search(variables, ir->var);
76bf215546Sopenharmony_ci
77bf215546Sopenharmony_ci      /* If a variable is dereferenced at all, remove it from the set of
78bf215546Sopenharmony_ci       * variables that are candidates for removal.
79bf215546Sopenharmony_ci       */
80bf215546Sopenharmony_ci      if (entry != NULL)
81bf215546Sopenharmony_ci         _mesa_set_remove(variables, entry);
82bf215546Sopenharmony_ci
83bf215546Sopenharmony_ci      return visit_continue;
84bf215546Sopenharmony_ci   }
85bf215546Sopenharmony_ci
86bf215546Sopenharmony_ci   void remove_dead_variables()
87bf215546Sopenharmony_ci   {
88bf215546Sopenharmony_ci      set_foreach(variables, entry) {
89bf215546Sopenharmony_ci         ir_variable *ir = (ir_variable *) entry->key;
90bf215546Sopenharmony_ci
91bf215546Sopenharmony_ci         assert(ir->ir_type == ir_type_variable);
92bf215546Sopenharmony_ci         ir->remove();
93bf215546Sopenharmony_ci      }
94bf215546Sopenharmony_ci   }
95bf215546Sopenharmony_ci
96bf215546Sopenharmony_ciprivate:
97bf215546Sopenharmony_ci   set *variables;
98bf215546Sopenharmony_ci};
99bf215546Sopenharmony_ci
100bf215546Sopenharmony_cistatic void
101bf215546Sopenharmony_ciinit_gl_program(struct gl_program *prog, bool is_arb_asm, gl_shader_stage stage)
102bf215546Sopenharmony_ci{
103bf215546Sopenharmony_ci   prog->RefCount = 1;
104bf215546Sopenharmony_ci   prog->Format = GL_PROGRAM_FORMAT_ASCII_ARB;
105bf215546Sopenharmony_ci   prog->info.use_legacy_math_rules = is_arb_asm;
106bf215546Sopenharmony_ci   prog->info.stage = stage;
107bf215546Sopenharmony_ci}
108bf215546Sopenharmony_ci
109bf215546Sopenharmony_cistatic struct gl_program *
110bf215546Sopenharmony_cinew_program(UNUSED struct gl_context *ctx, gl_shader_stage stage,
111bf215546Sopenharmony_ci            UNUSED GLuint id, bool is_arb_asm)
112bf215546Sopenharmony_ci{
113bf215546Sopenharmony_ci   struct gl_program *prog = rzalloc(NULL, struct gl_program);
114bf215546Sopenharmony_ci   init_gl_program(prog, is_arb_asm, stage);
115bf215546Sopenharmony_ci   return prog;
116bf215546Sopenharmony_ci}
117bf215546Sopenharmony_ci
118bf215546Sopenharmony_cistatic const struct standalone_options *options;
119bf215546Sopenharmony_ci
120bf215546Sopenharmony_cistatic void
121bf215546Sopenharmony_ciinitialize_context(struct gl_context *ctx, gl_api api)
122bf215546Sopenharmony_ci{
123bf215546Sopenharmony_ci   initialize_context_to_defaults(ctx, api);
124bf215546Sopenharmony_ci   _mesa_glsl_builtin_functions_init_or_ref();
125bf215546Sopenharmony_ci
126bf215546Sopenharmony_ci   /* The standalone compiler needs to claim support for almost
127bf215546Sopenharmony_ci    * everything in order to compile the built-in functions.
128bf215546Sopenharmony_ci    */
129bf215546Sopenharmony_ci   ctx->Const.GLSLVersion = options->glsl_version;
130bf215546Sopenharmony_ci   ctx->Extensions.ARB_ES3_compatibility = true;
131bf215546Sopenharmony_ci   ctx->Extensions.ARB_ES3_1_compatibility = true;
132bf215546Sopenharmony_ci   ctx->Extensions.ARB_ES3_2_compatibility = true;
133bf215546Sopenharmony_ci   ctx->Const.MaxComputeWorkGroupCount[0] = 65535;
134bf215546Sopenharmony_ci   ctx->Const.MaxComputeWorkGroupCount[1] = 65535;
135bf215546Sopenharmony_ci   ctx->Const.MaxComputeWorkGroupCount[2] = 65535;
136bf215546Sopenharmony_ci   ctx->Const.MaxComputeWorkGroupSize[0] = 1024;
137bf215546Sopenharmony_ci   ctx->Const.MaxComputeWorkGroupSize[1] = 1024;
138bf215546Sopenharmony_ci   ctx->Const.MaxComputeWorkGroupSize[2] = 64;
139bf215546Sopenharmony_ci   ctx->Const.MaxComputeWorkGroupInvocations = 1024;
140bf215546Sopenharmony_ci   ctx->Const.MaxComputeSharedMemorySize = 32768;
141bf215546Sopenharmony_ci   ctx->Const.MaxComputeVariableGroupSize[0] = 512;
142bf215546Sopenharmony_ci   ctx->Const.MaxComputeVariableGroupSize[1] = 512;
143bf215546Sopenharmony_ci   ctx->Const.MaxComputeVariableGroupSize[2] = 64;
144bf215546Sopenharmony_ci   ctx->Const.MaxComputeVariableGroupInvocations = 512;
145bf215546Sopenharmony_ci   ctx->Const.Program[MESA_SHADER_COMPUTE].MaxTextureImageUnits = 16;
146bf215546Sopenharmony_ci   ctx->Const.Program[MESA_SHADER_COMPUTE].MaxUniformComponents = 1024;
147bf215546Sopenharmony_ci   ctx->Const.Program[MESA_SHADER_COMPUTE].MaxCombinedUniformComponents = 1024;
148bf215546Sopenharmony_ci   ctx->Const.Program[MESA_SHADER_COMPUTE].MaxInputComponents = 0; /* not used */
149bf215546Sopenharmony_ci   ctx->Const.Program[MESA_SHADER_COMPUTE].MaxOutputComponents = 0; /* not used */
150bf215546Sopenharmony_ci   ctx->Const.Program[MESA_SHADER_COMPUTE].MaxAtomicBuffers = 8;
151bf215546Sopenharmony_ci   ctx->Const.Program[MESA_SHADER_COMPUTE].MaxAtomicCounters = 8;
152bf215546Sopenharmony_ci   ctx->Const.Program[MESA_SHADER_COMPUTE].MaxImageUniforms = 8;
153bf215546Sopenharmony_ci   ctx->Const.Program[MESA_SHADER_COMPUTE].MaxUniformBlocks = 12;
154bf215546Sopenharmony_ci
155bf215546Sopenharmony_ci   switch (ctx->Const.GLSLVersion) {
156bf215546Sopenharmony_ci   case 100:
157bf215546Sopenharmony_ci      ctx->Const.MaxClipPlanes = 0;
158bf215546Sopenharmony_ci      ctx->Const.MaxCombinedTextureImageUnits = 8;
159bf215546Sopenharmony_ci      ctx->Const.MaxDrawBuffers = 2;
160bf215546Sopenharmony_ci      ctx->Const.MinProgramTexelOffset = 0;
161bf215546Sopenharmony_ci      ctx->Const.MaxProgramTexelOffset = 0;
162bf215546Sopenharmony_ci      ctx->Const.MaxLights = 0;
163bf215546Sopenharmony_ci      ctx->Const.MaxTextureCoordUnits = 0;
164bf215546Sopenharmony_ci      ctx->Const.MaxTextureUnits = 8;
165bf215546Sopenharmony_ci
166bf215546Sopenharmony_ci      ctx->Const.Program[MESA_SHADER_VERTEX].MaxAttribs = 8;
167bf215546Sopenharmony_ci      ctx->Const.Program[MESA_SHADER_VERTEX].MaxTextureImageUnits = 0;
168bf215546Sopenharmony_ci      ctx->Const.Program[MESA_SHADER_VERTEX].MaxUniformComponents = 128 * 4;
169bf215546Sopenharmony_ci      ctx->Const.Program[MESA_SHADER_VERTEX].MaxCombinedUniformComponents = 128 * 4;
170bf215546Sopenharmony_ci      ctx->Const.Program[MESA_SHADER_VERTEX].MaxInputComponents = 0; /* not used */
171bf215546Sopenharmony_ci      ctx->Const.Program[MESA_SHADER_VERTEX].MaxOutputComponents = 32;
172bf215546Sopenharmony_ci
173bf215546Sopenharmony_ci      ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxTextureImageUnits =
174bf215546Sopenharmony_ci         ctx->Const.MaxCombinedTextureImageUnits;
175bf215546Sopenharmony_ci      ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxUniformComponents = 16 * 4;
176bf215546Sopenharmony_ci      ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxCombinedUniformComponents = 16 * 4;
177bf215546Sopenharmony_ci      ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxInputComponents =
178bf215546Sopenharmony_ci         ctx->Const.Program[MESA_SHADER_VERTEX].MaxOutputComponents;
179bf215546Sopenharmony_ci      ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxOutputComponents = 0; /* not used */
180bf215546Sopenharmony_ci
181bf215546Sopenharmony_ci      ctx->Const.MaxVarying = ctx->Const.Program[MESA_SHADER_VERTEX].MaxOutputComponents / 4;
182bf215546Sopenharmony_ci      break;
183bf215546Sopenharmony_ci   case 110:
184bf215546Sopenharmony_ci   case 120:
185bf215546Sopenharmony_ci      ctx->Const.MaxClipPlanes = 6;
186bf215546Sopenharmony_ci      ctx->Const.MaxCombinedTextureImageUnits = 2;
187bf215546Sopenharmony_ci      ctx->Const.MaxDrawBuffers = 1;
188bf215546Sopenharmony_ci      ctx->Const.MinProgramTexelOffset = 0;
189bf215546Sopenharmony_ci      ctx->Const.MaxProgramTexelOffset = 0;
190bf215546Sopenharmony_ci      ctx->Const.MaxLights = 8;
191bf215546Sopenharmony_ci      ctx->Const.MaxTextureCoordUnits = 2;
192bf215546Sopenharmony_ci      ctx->Const.MaxTextureUnits = 2;
193bf215546Sopenharmony_ci
194bf215546Sopenharmony_ci      ctx->Const.Program[MESA_SHADER_VERTEX].MaxAttribs = 16;
195bf215546Sopenharmony_ci      ctx->Const.Program[MESA_SHADER_VERTEX].MaxTextureImageUnits = 0;
196bf215546Sopenharmony_ci      ctx->Const.Program[MESA_SHADER_VERTEX].MaxUniformComponents = 512;
197bf215546Sopenharmony_ci      ctx->Const.Program[MESA_SHADER_VERTEX].MaxCombinedUniformComponents = 512;
198bf215546Sopenharmony_ci      ctx->Const.Program[MESA_SHADER_VERTEX].MaxInputComponents = 0; /* not used */
199bf215546Sopenharmony_ci      ctx->Const.Program[MESA_SHADER_VERTEX].MaxOutputComponents = 32;
200bf215546Sopenharmony_ci
201bf215546Sopenharmony_ci      ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxTextureImageUnits =
202bf215546Sopenharmony_ci         ctx->Const.MaxCombinedTextureImageUnits;
203bf215546Sopenharmony_ci      ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxUniformComponents = 64;
204bf215546Sopenharmony_ci      ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxCombinedUniformComponents = 64;
205bf215546Sopenharmony_ci      ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxInputComponents =
206bf215546Sopenharmony_ci         ctx->Const.Program[MESA_SHADER_VERTEX].MaxOutputComponents;
207bf215546Sopenharmony_ci      ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxOutputComponents = 0; /* not used */
208bf215546Sopenharmony_ci
209bf215546Sopenharmony_ci      ctx->Const.MaxVarying = ctx->Const.Program[MESA_SHADER_VERTEX].MaxOutputComponents / 4;
210bf215546Sopenharmony_ci      break;
211bf215546Sopenharmony_ci   case 130:
212bf215546Sopenharmony_ci   case 140:
213bf215546Sopenharmony_ci      ctx->Const.MaxClipPlanes = 8;
214bf215546Sopenharmony_ci      ctx->Const.MaxCombinedTextureImageUnits = 16;
215bf215546Sopenharmony_ci      ctx->Const.MaxDrawBuffers = 8;
216bf215546Sopenharmony_ci      ctx->Const.MinProgramTexelOffset = -8;
217bf215546Sopenharmony_ci      ctx->Const.MaxProgramTexelOffset = 7;
218bf215546Sopenharmony_ci      ctx->Const.MaxLights = 8;
219bf215546Sopenharmony_ci      ctx->Const.MaxTextureCoordUnits = 8;
220bf215546Sopenharmony_ci      ctx->Const.MaxTextureUnits = 2;
221bf215546Sopenharmony_ci      ctx->Const.MaxUniformBufferBindings = 84;
222bf215546Sopenharmony_ci      ctx->Const.MaxVertexStreams = 4;
223bf215546Sopenharmony_ci      ctx->Const.MaxTransformFeedbackBuffers = 4;
224bf215546Sopenharmony_ci
225bf215546Sopenharmony_ci      ctx->Const.Program[MESA_SHADER_VERTEX].MaxAttribs = 16;
226bf215546Sopenharmony_ci      ctx->Const.Program[MESA_SHADER_VERTEX].MaxTextureImageUnits = 16;
227bf215546Sopenharmony_ci      ctx->Const.Program[MESA_SHADER_VERTEX].MaxUniformComponents = 1024;
228bf215546Sopenharmony_ci      ctx->Const.Program[MESA_SHADER_VERTEX].MaxCombinedUniformComponents = 1024;
229bf215546Sopenharmony_ci      ctx->Const.Program[MESA_SHADER_VERTEX].MaxInputComponents = 0; /* not used */
230bf215546Sopenharmony_ci      ctx->Const.Program[MESA_SHADER_VERTEX].MaxOutputComponents = 64;
231bf215546Sopenharmony_ci
232bf215546Sopenharmony_ci      ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxTextureImageUnits = 16;
233bf215546Sopenharmony_ci      ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxUniformComponents = 1024;
234bf215546Sopenharmony_ci      ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxCombinedUniformComponents = 1024;
235bf215546Sopenharmony_ci      ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxInputComponents =
236bf215546Sopenharmony_ci         ctx->Const.Program[MESA_SHADER_VERTEX].MaxOutputComponents;
237bf215546Sopenharmony_ci      ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxOutputComponents = 0; /* not used */
238bf215546Sopenharmony_ci
239bf215546Sopenharmony_ci      ctx->Const.MaxVarying = ctx->Const.Program[MESA_SHADER_VERTEX].MaxOutputComponents / 4;
240bf215546Sopenharmony_ci      break;
241bf215546Sopenharmony_ci   case 150:
242bf215546Sopenharmony_ci   case 330:
243bf215546Sopenharmony_ci   case 400:
244bf215546Sopenharmony_ci   case 410:
245bf215546Sopenharmony_ci   case 420:
246bf215546Sopenharmony_ci   case 430:
247bf215546Sopenharmony_ci   case 440:
248bf215546Sopenharmony_ci   case 450:
249bf215546Sopenharmony_ci   case 460:
250bf215546Sopenharmony_ci      ctx->Const.MaxClipPlanes = 8;
251bf215546Sopenharmony_ci      ctx->Const.MaxDrawBuffers = 8;
252bf215546Sopenharmony_ci      ctx->Const.MinProgramTexelOffset = -8;
253bf215546Sopenharmony_ci      ctx->Const.MaxProgramTexelOffset = 7;
254bf215546Sopenharmony_ci      ctx->Const.MaxLights = 8;
255bf215546Sopenharmony_ci      ctx->Const.MaxTextureCoordUnits = 8;
256bf215546Sopenharmony_ci      ctx->Const.MaxTextureUnits = 2;
257bf215546Sopenharmony_ci      ctx->Const.MaxUniformBufferBindings = 84;
258bf215546Sopenharmony_ci      ctx->Const.MaxVertexStreams = 4;
259bf215546Sopenharmony_ci      ctx->Const.MaxTransformFeedbackBuffers = 4;
260bf215546Sopenharmony_ci      ctx->Const.MaxShaderStorageBufferBindings = 4;
261bf215546Sopenharmony_ci      ctx->Const.MaxShaderStorageBlockSize = 4096;
262bf215546Sopenharmony_ci      ctx->Const.MaxAtomicBufferBindings = 4;
263bf215546Sopenharmony_ci
264bf215546Sopenharmony_ci      ctx->Const.Program[MESA_SHADER_VERTEX].MaxAttribs = 16;
265bf215546Sopenharmony_ci      ctx->Const.Program[MESA_SHADER_VERTEX].MaxTextureImageUnits = 16;
266bf215546Sopenharmony_ci      ctx->Const.Program[MESA_SHADER_VERTEX].MaxUniformComponents = 1024;
267bf215546Sopenharmony_ci      ctx->Const.Program[MESA_SHADER_VERTEX].MaxCombinedUniformComponents = 1024;
268bf215546Sopenharmony_ci      ctx->Const.Program[MESA_SHADER_VERTEX].MaxInputComponents = 0; /* not used */
269bf215546Sopenharmony_ci      ctx->Const.Program[MESA_SHADER_VERTEX].MaxOutputComponents = 64;
270bf215546Sopenharmony_ci
271bf215546Sopenharmony_ci      ctx->Const.Program[MESA_SHADER_GEOMETRY].MaxTextureImageUnits = 16;
272bf215546Sopenharmony_ci      ctx->Const.Program[MESA_SHADER_GEOMETRY].MaxUniformComponents = 1024;
273bf215546Sopenharmony_ci      ctx->Const.Program[MESA_SHADER_GEOMETRY].MaxCombinedUniformComponents = 1024;
274bf215546Sopenharmony_ci      ctx->Const.Program[MESA_SHADER_GEOMETRY].MaxInputComponents =
275bf215546Sopenharmony_ci         ctx->Const.Program[MESA_SHADER_VERTEX].MaxOutputComponents;
276bf215546Sopenharmony_ci      ctx->Const.Program[MESA_SHADER_GEOMETRY].MaxOutputComponents = 128;
277bf215546Sopenharmony_ci
278bf215546Sopenharmony_ci      ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxTextureImageUnits = 16;
279bf215546Sopenharmony_ci      ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxUniformComponents = 1024;
280bf215546Sopenharmony_ci      ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxCombinedUniformComponents = 1024;
281bf215546Sopenharmony_ci      ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxInputComponents =
282bf215546Sopenharmony_ci         ctx->Const.Program[MESA_SHADER_GEOMETRY].MaxOutputComponents;
283bf215546Sopenharmony_ci      ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxOutputComponents = 0; /* not used */
284bf215546Sopenharmony_ci
285bf215546Sopenharmony_ci      ctx->Const.MaxCombinedTextureImageUnits =
286bf215546Sopenharmony_ci         ctx->Const.Program[MESA_SHADER_VERTEX].MaxTextureImageUnits
287bf215546Sopenharmony_ci         + ctx->Const.Program[MESA_SHADER_GEOMETRY].MaxTextureImageUnits
288bf215546Sopenharmony_ci         + ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxTextureImageUnits;
289bf215546Sopenharmony_ci
290bf215546Sopenharmony_ci      ctx->Const.MaxGeometryOutputVertices = 256;
291bf215546Sopenharmony_ci      ctx->Const.MaxGeometryTotalOutputComponents = 1024;
292bf215546Sopenharmony_ci
293bf215546Sopenharmony_ci      ctx->Const.MaxVarying = 60 / 4;
294bf215546Sopenharmony_ci      break;
295bf215546Sopenharmony_ci   case 300:
296bf215546Sopenharmony_ci      ctx->Const.MaxClipPlanes = 8;
297bf215546Sopenharmony_ci      ctx->Const.MaxCombinedTextureImageUnits = 32;
298bf215546Sopenharmony_ci      ctx->Const.MaxDrawBuffers = 4;
299bf215546Sopenharmony_ci      ctx->Const.MinProgramTexelOffset = -8;
300bf215546Sopenharmony_ci      ctx->Const.MaxProgramTexelOffset = 7;
301bf215546Sopenharmony_ci      ctx->Const.MaxLights = 0;
302bf215546Sopenharmony_ci      ctx->Const.MaxTextureCoordUnits = 0;
303bf215546Sopenharmony_ci      ctx->Const.MaxTextureUnits = 0;
304bf215546Sopenharmony_ci      ctx->Const.MaxUniformBufferBindings = 84;
305bf215546Sopenharmony_ci      ctx->Const.MaxVertexStreams = 4;
306bf215546Sopenharmony_ci      ctx->Const.MaxTransformFeedbackBuffers = 4;
307bf215546Sopenharmony_ci
308bf215546Sopenharmony_ci      ctx->Const.Program[MESA_SHADER_VERTEX].MaxAttribs = 16;
309bf215546Sopenharmony_ci      ctx->Const.Program[MESA_SHADER_VERTEX].MaxTextureImageUnits = 16;
310bf215546Sopenharmony_ci      ctx->Const.Program[MESA_SHADER_VERTEX].MaxUniformComponents = 1024;
311bf215546Sopenharmony_ci      ctx->Const.Program[MESA_SHADER_VERTEX].MaxCombinedUniformComponents = 1024;
312bf215546Sopenharmony_ci      ctx->Const.Program[MESA_SHADER_VERTEX].MaxInputComponents = 0; /* not used */
313bf215546Sopenharmony_ci      ctx->Const.Program[MESA_SHADER_VERTEX].MaxOutputComponents = 16 * 4;
314bf215546Sopenharmony_ci
315bf215546Sopenharmony_ci      ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxTextureImageUnits = 16;
316bf215546Sopenharmony_ci      ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxUniformComponents = 224;
317bf215546Sopenharmony_ci      ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxCombinedUniformComponents = 224;
318bf215546Sopenharmony_ci      ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxInputComponents = 15 * 4;
319bf215546Sopenharmony_ci      ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxOutputComponents = 0; /* not used */
320bf215546Sopenharmony_ci
321bf215546Sopenharmony_ci      ctx->Const.MaxVarying = ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxInputComponents / 4;
322bf215546Sopenharmony_ci      break;
323bf215546Sopenharmony_ci   }
324bf215546Sopenharmony_ci
325bf215546Sopenharmony_ci   ctx->Const.GenerateTemporaryNames = true;
326bf215546Sopenharmony_ci   ctx->Const.MaxPatchVertices = 32;
327bf215546Sopenharmony_ci
328bf215546Sopenharmony_ci   /* GL_ARB_explicit_uniform_location, GL_MAX_UNIFORM_LOCATIONS */
329bf215546Sopenharmony_ci   ctx->Const.MaxUserAssignableUniformLocations =
330bf215546Sopenharmony_ci      4 * MESA_SHADER_STAGES * MAX_UNIFORMS;
331bf215546Sopenharmony_ci
332bf215546Sopenharmony_ci   ctx->Driver.NewProgram = new_program;
333bf215546Sopenharmony_ci}
334bf215546Sopenharmony_ci
335bf215546Sopenharmony_ci/* Returned string will have 'ctx' as its ralloc owner. */
336bf215546Sopenharmony_cistatic char *
337bf215546Sopenharmony_ciload_text_file(void *ctx, const char *file_name)
338bf215546Sopenharmony_ci{
339bf215546Sopenharmony_ci   char *text = NULL;
340bf215546Sopenharmony_ci   size_t size;
341bf215546Sopenharmony_ci   size_t total_read = 0;
342bf215546Sopenharmony_ci   FILE *fp = fopen(file_name, "rb");
343bf215546Sopenharmony_ci
344bf215546Sopenharmony_ci   if (!fp) {
345bf215546Sopenharmony_ci      return NULL;
346bf215546Sopenharmony_ci   }
347bf215546Sopenharmony_ci
348bf215546Sopenharmony_ci   fseek(fp, 0L, SEEK_END);
349bf215546Sopenharmony_ci   size = ftell(fp);
350bf215546Sopenharmony_ci   fseek(fp, 0L, SEEK_SET);
351bf215546Sopenharmony_ci
352bf215546Sopenharmony_ci   text = (char *) ralloc_size(ctx, size + 1);
353bf215546Sopenharmony_ci   if (text != NULL) {
354bf215546Sopenharmony_ci      do {
355bf215546Sopenharmony_ci         size_t bytes = fread(text + total_read,
356bf215546Sopenharmony_ci               1, size - total_read, fp);
357bf215546Sopenharmony_ci         if (bytes < size - total_read) {
358bf215546Sopenharmony_ci            free(text);
359bf215546Sopenharmony_ci            text = NULL;
360bf215546Sopenharmony_ci            goto error;
361bf215546Sopenharmony_ci         }
362bf215546Sopenharmony_ci
363bf215546Sopenharmony_ci         if (bytes == 0) {
364bf215546Sopenharmony_ci            break;
365bf215546Sopenharmony_ci         }
366bf215546Sopenharmony_ci
367bf215546Sopenharmony_ci         total_read += bytes;
368bf215546Sopenharmony_ci      } while (total_read < size);
369bf215546Sopenharmony_ci
370bf215546Sopenharmony_ci      text[total_read] = '\0';
371bf215546Sopenharmony_ci      error:;
372bf215546Sopenharmony_ci   }
373bf215546Sopenharmony_ci
374bf215546Sopenharmony_ci   fclose(fp);
375bf215546Sopenharmony_ci
376bf215546Sopenharmony_ci   return text;
377bf215546Sopenharmony_ci}
378bf215546Sopenharmony_ci
379bf215546Sopenharmony_cistatic void
380bf215546Sopenharmony_cicompile_shader(struct gl_context *ctx, struct gl_shader *shader)
381bf215546Sopenharmony_ci{
382bf215546Sopenharmony_ci   _mesa_glsl_compile_shader(ctx, shader, options->dump_ast,
383bf215546Sopenharmony_ci                             options->dump_hir, true);
384bf215546Sopenharmony_ci
385bf215546Sopenharmony_ci   /* Print out the resulting IR */
386bf215546Sopenharmony_ci   if (shader->CompileStatus == COMPILE_SUCCESS && options->dump_lir) {
387bf215546Sopenharmony_ci      _mesa_print_ir(stdout, shader->ir, NULL);
388bf215546Sopenharmony_ci   }
389bf215546Sopenharmony_ci
390bf215546Sopenharmony_ci   return;
391bf215546Sopenharmony_ci}
392bf215546Sopenharmony_ci
393bf215546Sopenharmony_ciextern "C" struct gl_shader_program *
394bf215546Sopenharmony_cistandalone_compile_shader(const struct standalone_options *_options,
395bf215546Sopenharmony_ci      unsigned num_files, char* const* files, struct gl_context *ctx)
396bf215546Sopenharmony_ci{
397bf215546Sopenharmony_ci   int status = EXIT_SUCCESS;
398bf215546Sopenharmony_ci   bool glsl_es = false;
399bf215546Sopenharmony_ci
400bf215546Sopenharmony_ci   options = _options;
401bf215546Sopenharmony_ci
402bf215546Sopenharmony_ci   switch (options->glsl_version) {
403bf215546Sopenharmony_ci   case 100:
404bf215546Sopenharmony_ci   case 300:
405bf215546Sopenharmony_ci      glsl_es = true;
406bf215546Sopenharmony_ci      break;
407bf215546Sopenharmony_ci   case 110:
408bf215546Sopenharmony_ci   case 120:
409bf215546Sopenharmony_ci   case 130:
410bf215546Sopenharmony_ci   case 140:
411bf215546Sopenharmony_ci   case 150:
412bf215546Sopenharmony_ci   case 330:
413bf215546Sopenharmony_ci   case 400:
414bf215546Sopenharmony_ci   case 410:
415bf215546Sopenharmony_ci   case 420:
416bf215546Sopenharmony_ci   case 430:
417bf215546Sopenharmony_ci   case 440:
418bf215546Sopenharmony_ci   case 450:
419bf215546Sopenharmony_ci   case 460:
420bf215546Sopenharmony_ci      glsl_es = false;
421bf215546Sopenharmony_ci      break;
422bf215546Sopenharmony_ci   default:
423bf215546Sopenharmony_ci      fprintf(stderr, "Unrecognized GLSL version `%d'\n", options->glsl_version);
424bf215546Sopenharmony_ci      return NULL;
425bf215546Sopenharmony_ci   }
426bf215546Sopenharmony_ci
427bf215546Sopenharmony_ci   if (glsl_es) {
428bf215546Sopenharmony_ci      initialize_context(ctx, API_OPENGLES2);
429bf215546Sopenharmony_ci   } else {
430bf215546Sopenharmony_ci      initialize_context(ctx, options->glsl_version > 130 ? API_OPENGL_CORE : API_OPENGL_COMPAT);
431bf215546Sopenharmony_ci   }
432bf215546Sopenharmony_ci
433bf215546Sopenharmony_ci   if (options->lower_precision) {
434bf215546Sopenharmony_ci      for (unsigned i = MESA_SHADER_VERTEX; i <= MESA_SHADER_COMPUTE; i++) {
435bf215546Sopenharmony_ci         struct gl_shader_compiler_options *options =
436bf215546Sopenharmony_ci            &ctx->Const.ShaderCompilerOptions[i];
437bf215546Sopenharmony_ci         options->LowerPrecisionFloat16 = true;
438bf215546Sopenharmony_ci         options->LowerPrecisionInt16 = true;
439bf215546Sopenharmony_ci         options->LowerPrecisionDerivatives = true;
440bf215546Sopenharmony_ci         options->LowerPrecisionConstants = true;
441bf215546Sopenharmony_ci         options->LowerPrecisionFloat16Uniforms = true;
442bf215546Sopenharmony_ci      }
443bf215546Sopenharmony_ci   }
444bf215546Sopenharmony_ci
445bf215546Sopenharmony_ci   struct gl_shader_program *whole_program;
446bf215546Sopenharmony_ci
447bf215546Sopenharmony_ci   whole_program = rzalloc (NULL, struct gl_shader_program);
448bf215546Sopenharmony_ci   assert(whole_program != NULL);
449bf215546Sopenharmony_ci   whole_program->data = rzalloc(whole_program, struct gl_shader_program_data);
450bf215546Sopenharmony_ci   assert(whole_program->data != NULL);
451bf215546Sopenharmony_ci   whole_program->data->InfoLog = ralloc_strdup(whole_program->data, "");
452bf215546Sopenharmony_ci
453bf215546Sopenharmony_ci   /* Created just to avoid segmentation faults */
454bf215546Sopenharmony_ci   whole_program->AttributeBindings = new string_to_uint_map;
455bf215546Sopenharmony_ci   whole_program->FragDataBindings = new string_to_uint_map;
456bf215546Sopenharmony_ci   whole_program->FragDataIndexBindings = new string_to_uint_map;
457bf215546Sopenharmony_ci
458bf215546Sopenharmony_ci   for (unsigned i = 0; i < num_files; i++) {
459bf215546Sopenharmony_ci      whole_program->Shaders =
460bf215546Sopenharmony_ci            reralloc(whole_program, whole_program->Shaders,
461bf215546Sopenharmony_ci                  struct gl_shader *, whole_program->NumShaders + 1);
462bf215546Sopenharmony_ci      assert(whole_program->Shaders != NULL);
463bf215546Sopenharmony_ci
464bf215546Sopenharmony_ci      struct gl_shader *shader = rzalloc(whole_program, gl_shader);
465bf215546Sopenharmony_ci
466bf215546Sopenharmony_ci      whole_program->Shaders[whole_program->NumShaders] = shader;
467bf215546Sopenharmony_ci      whole_program->NumShaders++;
468bf215546Sopenharmony_ci
469bf215546Sopenharmony_ci      const unsigned len = strlen(files[i]);
470bf215546Sopenharmony_ci      if (len < 6)
471bf215546Sopenharmony_ci         goto fail;
472bf215546Sopenharmony_ci
473bf215546Sopenharmony_ci      const char *const ext = & files[i][len - 5];
474bf215546Sopenharmony_ci      /* TODO add support to read a .shader_test */
475bf215546Sopenharmony_ci      if (strncmp(".vert", ext, 5) == 0 || strncmp(".glsl", ext, 5) == 0)
476bf215546Sopenharmony_ci	 shader->Type = GL_VERTEX_SHADER;
477bf215546Sopenharmony_ci      else if (strncmp(".tesc", ext, 5) == 0)
478bf215546Sopenharmony_ci	 shader->Type = GL_TESS_CONTROL_SHADER;
479bf215546Sopenharmony_ci      else if (strncmp(".tese", ext, 5) == 0)
480bf215546Sopenharmony_ci	 shader->Type = GL_TESS_EVALUATION_SHADER;
481bf215546Sopenharmony_ci      else if (strncmp(".geom", ext, 5) == 0)
482bf215546Sopenharmony_ci	 shader->Type = GL_GEOMETRY_SHADER;
483bf215546Sopenharmony_ci      else if (strncmp(".frag", ext, 5) == 0)
484bf215546Sopenharmony_ci	 shader->Type = GL_FRAGMENT_SHADER;
485bf215546Sopenharmony_ci      else if (strncmp(".comp", ext, 5) == 0)
486bf215546Sopenharmony_ci         shader->Type = GL_COMPUTE_SHADER;
487bf215546Sopenharmony_ci      else
488bf215546Sopenharmony_ci         goto fail;
489bf215546Sopenharmony_ci      shader->Stage = _mesa_shader_enum_to_shader_stage(shader->Type);
490bf215546Sopenharmony_ci
491bf215546Sopenharmony_ci      shader->Source = load_text_file(whole_program, files[i]);
492bf215546Sopenharmony_ci      if (shader->Source == NULL) {
493bf215546Sopenharmony_ci         printf("File \"%s\" does not exist.\n", files[i]);
494bf215546Sopenharmony_ci         exit(EXIT_FAILURE);
495bf215546Sopenharmony_ci      }
496bf215546Sopenharmony_ci
497bf215546Sopenharmony_ci      compile_shader(ctx, shader);
498bf215546Sopenharmony_ci
499bf215546Sopenharmony_ci      if (strlen(shader->InfoLog) > 0) {
500bf215546Sopenharmony_ci         if (!options->just_log)
501bf215546Sopenharmony_ci            printf("Info log for %s:\n", files[i]);
502bf215546Sopenharmony_ci
503bf215546Sopenharmony_ci         printf("%s", shader->InfoLog);
504bf215546Sopenharmony_ci         if (!options->just_log)
505bf215546Sopenharmony_ci            printf("\n");
506bf215546Sopenharmony_ci      }
507bf215546Sopenharmony_ci
508bf215546Sopenharmony_ci      if (!shader->CompileStatus) {
509bf215546Sopenharmony_ci         status = EXIT_FAILURE;
510bf215546Sopenharmony_ci         break;
511bf215546Sopenharmony_ci      }
512bf215546Sopenharmony_ci   }
513bf215546Sopenharmony_ci
514bf215546Sopenharmony_ci   if (status == EXIT_SUCCESS) {
515bf215546Sopenharmony_ci      _mesa_clear_shader_program_data(ctx, whole_program);
516bf215546Sopenharmony_ci
517bf215546Sopenharmony_ci      if (options->do_link)  {
518bf215546Sopenharmony_ci         link_shaders(ctx, whole_program);
519bf215546Sopenharmony_ci      } else {
520bf215546Sopenharmony_ci         const gl_shader_stage stage = whole_program->Shaders[0]->Stage;
521bf215546Sopenharmony_ci
522bf215546Sopenharmony_ci         whole_program->data->LinkStatus = LINKING_SUCCESS;
523bf215546Sopenharmony_ci         whole_program->_LinkedShaders[stage] =
524bf215546Sopenharmony_ci            link_intrastage_shaders(whole_program /* mem_ctx */,
525bf215546Sopenharmony_ci                                    ctx,
526bf215546Sopenharmony_ci                                    whole_program,
527bf215546Sopenharmony_ci                                    whole_program->Shaders,
528bf215546Sopenharmony_ci                                    1,
529bf215546Sopenharmony_ci                                    true);
530bf215546Sopenharmony_ci
531bf215546Sopenharmony_ci         /* Par-linking can fail, for example, if there are undefined external
532bf215546Sopenharmony_ci          * references.
533bf215546Sopenharmony_ci          */
534bf215546Sopenharmony_ci         if (whole_program->_LinkedShaders[stage] != NULL) {
535bf215546Sopenharmony_ci            assert(whole_program->data->LinkStatus);
536bf215546Sopenharmony_ci
537bf215546Sopenharmony_ci            struct gl_shader_compiler_options *const compiler_options =
538bf215546Sopenharmony_ci               &ctx->Const.ShaderCompilerOptions[stage];
539bf215546Sopenharmony_ci
540bf215546Sopenharmony_ci            exec_list *const ir =
541bf215546Sopenharmony_ci               whole_program->_LinkedShaders[stage]->ir;
542bf215546Sopenharmony_ci
543bf215546Sopenharmony_ci            bool progress;
544bf215546Sopenharmony_ci            do {
545bf215546Sopenharmony_ci               progress = do_function_inlining(ir);
546bf215546Sopenharmony_ci
547bf215546Sopenharmony_ci               progress = do_common_optimization(ir,
548bf215546Sopenharmony_ci                                                 false,
549bf215546Sopenharmony_ci                                                 compiler_options,
550bf215546Sopenharmony_ci                                                 true)
551bf215546Sopenharmony_ci                  && progress;
552bf215546Sopenharmony_ci            } while(progress);
553bf215546Sopenharmony_ci         }
554bf215546Sopenharmony_ci      }
555bf215546Sopenharmony_ci
556bf215546Sopenharmony_ci      status = (whole_program->data->LinkStatus) ? EXIT_SUCCESS : EXIT_FAILURE;
557bf215546Sopenharmony_ci
558bf215546Sopenharmony_ci      if (strlen(whole_program->data->InfoLog) > 0) {
559bf215546Sopenharmony_ci         printf("\n");
560bf215546Sopenharmony_ci         if (!options->just_log)
561bf215546Sopenharmony_ci            printf("Info log for linking:\n");
562bf215546Sopenharmony_ci         printf("%s", whole_program->data->InfoLog);
563bf215546Sopenharmony_ci         if (!options->just_log)
564bf215546Sopenharmony_ci            printf("\n");
565bf215546Sopenharmony_ci      }
566bf215546Sopenharmony_ci
567bf215546Sopenharmony_ci      for (unsigned i = 0; i < MESA_SHADER_STAGES; i++) {
568bf215546Sopenharmony_ci         struct gl_linked_shader *shader = whole_program->_LinkedShaders[i];
569bf215546Sopenharmony_ci
570bf215546Sopenharmony_ci         if (!shader)
571bf215546Sopenharmony_ci            continue;
572bf215546Sopenharmony_ci
573bf215546Sopenharmony_ci         add_neg_to_sub_visitor v;
574bf215546Sopenharmony_ci         visit_list_elements(&v, shader->ir);
575bf215546Sopenharmony_ci
576bf215546Sopenharmony_ci         dead_variable_visitor dv;
577bf215546Sopenharmony_ci         visit_list_elements(&dv, shader->ir);
578bf215546Sopenharmony_ci         dv.remove_dead_variables();
579bf215546Sopenharmony_ci      }
580bf215546Sopenharmony_ci
581bf215546Sopenharmony_ci      if (options->dump_builder) {
582bf215546Sopenharmony_ci         for (unsigned i = 0; i < MESA_SHADER_STAGES; i++) {
583bf215546Sopenharmony_ci            struct gl_linked_shader *shader = whole_program->_LinkedShaders[i];
584bf215546Sopenharmony_ci
585bf215546Sopenharmony_ci            if (!shader)
586bf215546Sopenharmony_ci               continue;
587bf215546Sopenharmony_ci
588bf215546Sopenharmony_ci            _mesa_print_builder_for_ir(stdout, shader->ir);
589bf215546Sopenharmony_ci         }
590bf215546Sopenharmony_ci      }
591bf215546Sopenharmony_ci   }
592bf215546Sopenharmony_ci
593bf215546Sopenharmony_ci   return whole_program;
594bf215546Sopenharmony_ci
595bf215546Sopenharmony_cifail:
596bf215546Sopenharmony_ci   for (unsigned i = 0; i < MESA_SHADER_STAGES; i++) {
597bf215546Sopenharmony_ci      if (whole_program->_LinkedShaders[i])
598bf215546Sopenharmony_ci         _mesa_delete_linked_shader(ctx, whole_program->_LinkedShaders[i]);
599bf215546Sopenharmony_ci   }
600bf215546Sopenharmony_ci
601bf215546Sopenharmony_ci   ralloc_free(whole_program);
602bf215546Sopenharmony_ci   return NULL;
603bf215546Sopenharmony_ci}
604bf215546Sopenharmony_ci
605bf215546Sopenharmony_ciextern "C" void
606bf215546Sopenharmony_cistandalone_compiler_cleanup(struct gl_shader_program *whole_program)
607bf215546Sopenharmony_ci{
608bf215546Sopenharmony_ci   for (unsigned i = 0; i < MESA_SHADER_STAGES; i++) {
609bf215546Sopenharmony_ci      if (whole_program->_LinkedShaders[i])
610bf215546Sopenharmony_ci         _mesa_delete_linked_shader(NULL, whole_program->_LinkedShaders[i]);
611bf215546Sopenharmony_ci   }
612bf215546Sopenharmony_ci
613bf215546Sopenharmony_ci   delete whole_program->AttributeBindings;
614bf215546Sopenharmony_ci   delete whole_program->FragDataBindings;
615bf215546Sopenharmony_ci   delete whole_program->FragDataIndexBindings;
616bf215546Sopenharmony_ci   delete whole_program->UniformHash;
617bf215546Sopenharmony_ci
618bf215546Sopenharmony_ci   ralloc_free(whole_program);
619bf215546Sopenharmony_ci   _mesa_glsl_builtin_functions_decref();
620bf215546Sopenharmony_ci}
621