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