2 * Copyright © 2008, 2009 Intel Corporation
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:
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
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.
27 * This file is the main() routine and scaffolding for producing
28 * builtin_compiler (which doesn't include builtins itself and is used
29 * to generate the profile information for builtin_function.cpp), and
30 * for glsl_compiler (which does include builtins and can be used to
31 * offline compile GLSL code and examine the resulting GLSL IR.
35 #include "glsl_parser_extras.h"
36 #include "ir_optimization.h"
38 #include "program/hash_table.h"
39 #include "loop_analysis.h"
40 #include "standalone_scaffolding.h"
42 static int glsl_version
= 330;
45 _mesa_error_no_memory(const char *caller
)
47 fprintf(stderr
, "Mesa error: out of memory in %s", caller
);
51 initialize_context(struct gl_context
*ctx
, gl_api api
)
53 initialize_context_to_defaults(ctx
, api
);
55 /* The standalone compiler needs to claim support for almost
56 * everything in order to compile the built-in functions.
58 ctx
->Const
.GLSLVersion
= glsl_version
;
59 ctx
->Extensions
.ARB_ES3_compatibility
= true;
60 ctx
->Const
.MaxComputeWorkGroupCount
[0] = 65535;
61 ctx
->Const
.MaxComputeWorkGroupCount
[1] = 65535;
62 ctx
->Const
.MaxComputeWorkGroupCount
[2] = 65535;
63 ctx
->Const
.MaxComputeWorkGroupSize
[0] = 1024;
64 ctx
->Const
.MaxComputeWorkGroupSize
[1] = 1024;
65 ctx
->Const
.MaxComputeWorkGroupSize
[2] = 64;
66 ctx
->Const
.MaxComputeWorkGroupInvocations
= 1024;
67 ctx
->Const
.Program
[MESA_SHADER_COMPUTE
].MaxTextureImageUnits
= 16;
68 ctx
->Const
.Program
[MESA_SHADER_COMPUTE
].MaxUniformComponents
= 1024;
69 ctx
->Const
.Program
[MESA_SHADER_COMPUTE
].MaxInputComponents
= 0; /* not used */
70 ctx
->Const
.Program
[MESA_SHADER_COMPUTE
].MaxOutputComponents
= 0; /* not used */
72 switch (ctx
->Const
.GLSLVersion
) {
74 ctx
->Const
.MaxClipPlanes
= 0;
75 ctx
->Const
.MaxCombinedTextureImageUnits
= 8;
76 ctx
->Const
.MaxDrawBuffers
= 2;
77 ctx
->Const
.MinProgramTexelOffset
= 0;
78 ctx
->Const
.MaxProgramTexelOffset
= 0;
79 ctx
->Const
.MaxLights
= 0;
80 ctx
->Const
.MaxTextureCoordUnits
= 0;
81 ctx
->Const
.MaxTextureUnits
= 8;
83 ctx
->Const
.Program
[MESA_SHADER_VERTEX
].MaxAttribs
= 8;
84 ctx
->Const
.Program
[MESA_SHADER_VERTEX
].MaxTextureImageUnits
= 0;
85 ctx
->Const
.Program
[MESA_SHADER_VERTEX
].MaxUniformComponents
= 128 * 4;
86 ctx
->Const
.Program
[MESA_SHADER_VERTEX
].MaxInputComponents
= 0; /* not used */
87 ctx
->Const
.Program
[MESA_SHADER_VERTEX
].MaxOutputComponents
= 32;
89 ctx
->Const
.Program
[MESA_SHADER_FRAGMENT
].MaxTextureImageUnits
=
90 ctx
->Const
.MaxCombinedTextureImageUnits
;
91 ctx
->Const
.Program
[MESA_SHADER_FRAGMENT
].MaxUniformComponents
= 16 * 4;
92 ctx
->Const
.Program
[MESA_SHADER_FRAGMENT
].MaxInputComponents
=
93 ctx
->Const
.Program
[MESA_SHADER_VERTEX
].MaxOutputComponents
;
94 ctx
->Const
.Program
[MESA_SHADER_FRAGMENT
].MaxOutputComponents
= 0; /* not used */
96 ctx
->Const
.MaxVarying
= ctx
->Const
.Program
[MESA_SHADER_VERTEX
].MaxOutputComponents
/ 4;
100 ctx
->Const
.MaxClipPlanes
= 6;
101 ctx
->Const
.MaxCombinedTextureImageUnits
= 2;
102 ctx
->Const
.MaxDrawBuffers
= 1;
103 ctx
->Const
.MinProgramTexelOffset
= 0;
104 ctx
->Const
.MaxProgramTexelOffset
= 0;
105 ctx
->Const
.MaxLights
= 8;
106 ctx
->Const
.MaxTextureCoordUnits
= 2;
107 ctx
->Const
.MaxTextureUnits
= 2;
109 ctx
->Const
.Program
[MESA_SHADER_VERTEX
].MaxAttribs
= 16;
110 ctx
->Const
.Program
[MESA_SHADER_VERTEX
].MaxTextureImageUnits
= 0;
111 ctx
->Const
.Program
[MESA_SHADER_VERTEX
].MaxUniformComponents
= 512;
112 ctx
->Const
.Program
[MESA_SHADER_VERTEX
].MaxInputComponents
= 0; /* not used */
113 ctx
->Const
.Program
[MESA_SHADER_VERTEX
].MaxOutputComponents
= 32;
115 ctx
->Const
.Program
[MESA_SHADER_FRAGMENT
].MaxTextureImageUnits
=
116 ctx
->Const
.MaxCombinedTextureImageUnits
;
117 ctx
->Const
.Program
[MESA_SHADER_FRAGMENT
].MaxUniformComponents
= 64;
118 ctx
->Const
.Program
[MESA_SHADER_FRAGMENT
].MaxInputComponents
=
119 ctx
->Const
.Program
[MESA_SHADER_VERTEX
].MaxOutputComponents
;
120 ctx
->Const
.Program
[MESA_SHADER_FRAGMENT
].MaxOutputComponents
= 0; /* not used */
122 ctx
->Const
.MaxVarying
= ctx
->Const
.Program
[MESA_SHADER_VERTEX
].MaxOutputComponents
/ 4;
126 ctx
->Const
.MaxClipPlanes
= 8;
127 ctx
->Const
.MaxCombinedTextureImageUnits
= 16;
128 ctx
->Const
.MaxDrawBuffers
= 8;
129 ctx
->Const
.MinProgramTexelOffset
= -8;
130 ctx
->Const
.MaxProgramTexelOffset
= 7;
131 ctx
->Const
.MaxLights
= 8;
132 ctx
->Const
.MaxTextureCoordUnits
= 8;
133 ctx
->Const
.MaxTextureUnits
= 2;
135 ctx
->Const
.Program
[MESA_SHADER_VERTEX
].MaxAttribs
= 16;
136 ctx
->Const
.Program
[MESA_SHADER_VERTEX
].MaxTextureImageUnits
= 16;
137 ctx
->Const
.Program
[MESA_SHADER_VERTEX
].MaxUniformComponents
= 1024;
138 ctx
->Const
.Program
[MESA_SHADER_VERTEX
].MaxInputComponents
= 0; /* not used */
139 ctx
->Const
.Program
[MESA_SHADER_VERTEX
].MaxOutputComponents
= 64;
141 ctx
->Const
.Program
[MESA_SHADER_FRAGMENT
].MaxTextureImageUnits
= 16;
142 ctx
->Const
.Program
[MESA_SHADER_FRAGMENT
].MaxUniformComponents
= 1024;
143 ctx
->Const
.Program
[MESA_SHADER_FRAGMENT
].MaxInputComponents
=
144 ctx
->Const
.Program
[MESA_SHADER_VERTEX
].MaxOutputComponents
;
145 ctx
->Const
.Program
[MESA_SHADER_FRAGMENT
].MaxOutputComponents
= 0; /* not used */
147 ctx
->Const
.MaxVarying
= ctx
->Const
.Program
[MESA_SHADER_VERTEX
].MaxOutputComponents
/ 4;
151 ctx
->Const
.MaxClipPlanes
= 8;
152 ctx
->Const
.MaxDrawBuffers
= 8;
153 ctx
->Const
.MinProgramTexelOffset
= -8;
154 ctx
->Const
.MaxProgramTexelOffset
= 7;
155 ctx
->Const
.MaxLights
= 8;
156 ctx
->Const
.MaxTextureCoordUnits
= 8;
157 ctx
->Const
.MaxTextureUnits
= 2;
159 ctx
->Const
.Program
[MESA_SHADER_VERTEX
].MaxAttribs
= 16;
160 ctx
->Const
.Program
[MESA_SHADER_VERTEX
].MaxTextureImageUnits
= 16;
161 ctx
->Const
.Program
[MESA_SHADER_VERTEX
].MaxUniformComponents
= 1024;
162 ctx
->Const
.Program
[MESA_SHADER_VERTEX
].MaxInputComponents
= 0; /* not used */
163 ctx
->Const
.Program
[MESA_SHADER_VERTEX
].MaxOutputComponents
= 64;
165 ctx
->Const
.Program
[MESA_SHADER_GEOMETRY
].MaxTextureImageUnits
= 16;
166 ctx
->Const
.Program
[MESA_SHADER_GEOMETRY
].MaxUniformComponents
= 1024;
167 ctx
->Const
.Program
[MESA_SHADER_GEOMETRY
].MaxInputComponents
=
168 ctx
->Const
.Program
[MESA_SHADER_VERTEX
].MaxOutputComponents
;
169 ctx
->Const
.Program
[MESA_SHADER_GEOMETRY
].MaxOutputComponents
= 128;
171 ctx
->Const
.Program
[MESA_SHADER_FRAGMENT
].MaxTextureImageUnits
= 16;
172 ctx
->Const
.Program
[MESA_SHADER_FRAGMENT
].MaxUniformComponents
= 1024;
173 ctx
->Const
.Program
[MESA_SHADER_FRAGMENT
].MaxInputComponents
=
174 ctx
->Const
.Program
[MESA_SHADER_GEOMETRY
].MaxOutputComponents
;
175 ctx
->Const
.Program
[MESA_SHADER_FRAGMENT
].MaxOutputComponents
= 0; /* not used */
177 ctx
->Const
.MaxCombinedTextureImageUnits
=
178 ctx
->Const
.Program
[MESA_SHADER_VERTEX
].MaxTextureImageUnits
179 + ctx
->Const
.Program
[MESA_SHADER_GEOMETRY
].MaxTextureImageUnits
180 + ctx
->Const
.Program
[MESA_SHADER_FRAGMENT
].MaxTextureImageUnits
;
182 ctx
->Const
.MaxGeometryOutputVertices
= 256;
183 ctx
->Const
.MaxGeometryTotalOutputComponents
= 1024;
185 ctx
->Const
.MaxVarying
= 60 / 4;
188 ctx
->Const
.MaxClipPlanes
= 8;
189 ctx
->Const
.MaxCombinedTextureImageUnits
= 32;
190 ctx
->Const
.MaxDrawBuffers
= 4;
191 ctx
->Const
.MinProgramTexelOffset
= -8;
192 ctx
->Const
.MaxProgramTexelOffset
= 7;
193 ctx
->Const
.MaxLights
= 0;
194 ctx
->Const
.MaxTextureCoordUnits
= 0;
195 ctx
->Const
.MaxTextureUnits
= 0;
197 ctx
->Const
.Program
[MESA_SHADER_VERTEX
].MaxAttribs
= 16;
198 ctx
->Const
.Program
[MESA_SHADER_VERTEX
].MaxTextureImageUnits
= 16;
199 ctx
->Const
.Program
[MESA_SHADER_VERTEX
].MaxUniformComponents
= 1024;
200 ctx
->Const
.Program
[MESA_SHADER_VERTEX
].MaxInputComponents
= 0; /* not used */
201 ctx
->Const
.Program
[MESA_SHADER_VERTEX
].MaxOutputComponents
= 16 * 4;
203 ctx
->Const
.Program
[MESA_SHADER_FRAGMENT
].MaxTextureImageUnits
= 16;
204 ctx
->Const
.Program
[MESA_SHADER_FRAGMENT
].MaxUniformComponents
= 224;
205 ctx
->Const
.Program
[MESA_SHADER_FRAGMENT
].MaxInputComponents
= 15 * 4;
206 ctx
->Const
.Program
[MESA_SHADER_FRAGMENT
].MaxOutputComponents
= 0; /* not used */
208 ctx
->Const
.MaxVarying
= ctx
->Const
.Program
[MESA_SHADER_FRAGMENT
].MaxInputComponents
/ 4;
212 ctx
->Const
.GenerateTemporaryNames
= true;
213 ctx
->Driver
.NewShader
= _mesa_new_shader
;
216 /* Returned string will have 'ctx' as its ralloc owner. */
218 load_text_file(void *ctx
, const char *file_name
)
222 size_t total_read
= 0;
223 FILE *fp
= fopen(file_name
, "rb");
229 fseek(fp
, 0L, SEEK_END
);
231 fseek(fp
, 0L, SEEK_SET
);
233 text
= (char *) ralloc_size(ctx
, size
+ 1);
236 size_t bytes
= fread(text
+ total_read
,
237 1, size
- total_read
, fp
);
238 if (bytes
< size
- total_read
) {
249 } while (total_read
< size
);
251 text
[total_read
] = '\0';
265 const struct option compiler_opts
[] = {
266 { "dump-ast", no_argument
, &dump_ast
, 1 },
267 { "dump-hir", no_argument
, &dump_hir
, 1 },
268 { "dump-lir", no_argument
, &dump_lir
, 1 },
269 { "link", no_argument
, &do_link
, 1 },
270 { "version", required_argument
, NULL
, 'v' },
275 * \brief Print proper usage and exit with failure.
278 usage_fail(const char *name
)
282 "usage: %s [options] <file.vert | file.geom | file.frag>\n"
284 "Possible options are:\n";
285 printf(header
, name
, name
);
286 for (const struct option
*o
= compiler_opts
; o
->name
!= 0; ++o
) {
287 printf(" --%s\n", o
->name
);
294 compile_shader(struct gl_context
*ctx
, struct gl_shader
*shader
)
296 struct _mesa_glsl_parse_state
*state
=
297 new(shader
) _mesa_glsl_parse_state(ctx
, shader
->Stage
, shader
);
299 _mesa_glsl_compile_shader(ctx
, shader
, dump_ast
, dump_hir
);
301 /* Print out the resulting IR */
302 if (!state
->error
&& dump_lir
) {
303 _mesa_print_ir(stdout
, shader
->ir
, state
);
310 main(int argc
, char **argv
)
312 int status
= EXIT_SUCCESS
;
313 struct gl_context local_ctx
;
314 struct gl_context
*ctx
= &local_ctx
;
315 bool glsl_es
= false;
319 while ((c
= getopt_long(argc
, argv
, "", compiler_opts
, &idx
)) != -1) {
322 glsl_version
= strtol(optarg
, NULL
, 10);
323 switch (glsl_version
) {
337 fprintf(stderr
, "Unrecognized GLSL version `%s'\n", optarg
);
351 initialize_context(ctx
, (glsl_es
) ? API_OPENGLES2
: API_OPENGL_COMPAT
);
353 struct gl_shader_program
*whole_program
;
355 whole_program
= rzalloc (NULL
, struct gl_shader_program
);
356 assert(whole_program
!= NULL
);
357 whole_program
->InfoLog
= ralloc_strdup(whole_program
, "");
359 /* Created just to avoid segmentation faults */
360 whole_program
->AttributeBindings
= new string_to_uint_map
;
361 whole_program
->FragDataBindings
= new string_to_uint_map
;
362 whole_program
->FragDataIndexBindings
= new string_to_uint_map
;
364 for (/* empty */; argc
> optind
; optind
++) {
365 whole_program
->Shaders
=
366 reralloc(whole_program
, whole_program
->Shaders
,
367 struct gl_shader
*, whole_program
->NumShaders
+ 1);
368 assert(whole_program
->Shaders
!= NULL
);
370 struct gl_shader
*shader
= rzalloc(whole_program
, gl_shader
);
372 whole_program
->Shaders
[whole_program
->NumShaders
] = shader
;
373 whole_program
->NumShaders
++;
375 const unsigned len
= strlen(argv
[optind
]);
379 const char *const ext
= & argv
[optind
][len
- 5];
380 if (strncmp(".vert", ext
, 5) == 0 || strncmp(".glsl", ext
, 5) == 0)
381 shader
->Type
= GL_VERTEX_SHADER
;
382 else if (strncmp(".geom", ext
, 5) == 0)
383 shader
->Type
= GL_GEOMETRY_SHADER
;
384 else if (strncmp(".frag", ext
, 5) == 0)
385 shader
->Type
= GL_FRAGMENT_SHADER
;
386 else if (strncmp(".comp", ext
, 5) == 0)
387 shader
->Type
= GL_COMPUTE_SHADER
;
390 shader
->Stage
= _mesa_shader_enum_to_shader_stage(shader
->Type
);
392 shader
->Source
= load_text_file(whole_program
, argv
[optind
]);
393 if (shader
->Source
== NULL
) {
394 printf("File \"%s\" does not exist.\n", argv
[optind
]);
398 compile_shader(ctx
, shader
);
400 if (strlen(shader
->InfoLog
) > 0)
401 printf("Info log for %s:\n%s\n", argv
[optind
], shader
->InfoLog
);
403 if (!shader
->CompileStatus
) {
404 status
= EXIT_FAILURE
;
409 if ((status
== EXIT_SUCCESS
) && do_link
) {
410 _mesa_clear_shader_program_data(whole_program
);
412 link_shaders(ctx
, whole_program
);
413 status
= (whole_program
->LinkStatus
) ? EXIT_SUCCESS
: EXIT_FAILURE
;
415 if (strlen(whole_program
->InfoLog
) > 0)
416 printf("Info log for linking:\n%s\n", whole_program
->InfoLog
);
419 for (unsigned i
= 0; i
< MESA_SHADER_STAGES
; i
++)
420 ralloc_free(whole_program
->_LinkedShaders
[i
]);
422 delete whole_program
->AttributeBindings
;
423 delete whole_program
->FragDataBindings
;
424 delete whole_program
->FragDataIndexBindings
;
426 ralloc_free(whole_program
);
427 _mesa_glsl_release_types();
428 _mesa_glsl_release_builtin_functions();