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.
25 /** @file standalone.cpp
27 * Standalone compiler helper lib. Used by standalone glsl_compiler and
28 * also available to drivers to implement their own standalone compiler
29 * with driver backend.
33 #include "glsl_parser_extras.h"
34 #include "ir_optimization.h"
36 #include "loop_analysis.h"
37 #include "standalone_scaffolding.h"
38 #include "standalone.h"
39 #include "util/string_to_uint_map.h"
41 static const struct standalone_options
*options
;
44 initialize_context(struct gl_context
*ctx
, gl_api api
)
46 initialize_context_to_defaults(ctx
, api
);
48 /* The standalone compiler needs to claim support for almost
49 * everything in order to compile the built-in functions.
51 ctx
->Const
.GLSLVersion
= options
->glsl_version
;
52 ctx
->Extensions
.ARB_ES3_compatibility
= true;
53 ctx
->Const
.MaxComputeWorkGroupCount
[0] = 65535;
54 ctx
->Const
.MaxComputeWorkGroupCount
[1] = 65535;
55 ctx
->Const
.MaxComputeWorkGroupCount
[2] = 65535;
56 ctx
->Const
.MaxComputeWorkGroupSize
[0] = 1024;
57 ctx
->Const
.MaxComputeWorkGroupSize
[1] = 1024;
58 ctx
->Const
.MaxComputeWorkGroupSize
[2] = 64;
59 ctx
->Const
.MaxComputeWorkGroupInvocations
= 1024;
60 ctx
->Const
.MaxComputeSharedMemorySize
= 32768;
61 ctx
->Const
.MaxComputeVariableGroupSize
[0] = 512;
62 ctx
->Const
.MaxComputeVariableGroupSize
[1] = 512;
63 ctx
->Const
.MaxComputeVariableGroupSize
[2] = 64;
64 ctx
->Const
.MaxComputeVariableGroupInvocations
= 512;
65 ctx
->Const
.Program
[MESA_SHADER_COMPUTE
].MaxTextureImageUnits
= 16;
66 ctx
->Const
.Program
[MESA_SHADER_COMPUTE
].MaxUniformComponents
= 1024;
67 ctx
->Const
.Program
[MESA_SHADER_COMPUTE
].MaxCombinedUniformComponents
= 1024;
68 ctx
->Const
.Program
[MESA_SHADER_COMPUTE
].MaxInputComponents
= 0; /* not used */
69 ctx
->Const
.Program
[MESA_SHADER_COMPUTE
].MaxOutputComponents
= 0; /* not used */
70 ctx
->Const
.Program
[MESA_SHADER_COMPUTE
].MaxAtomicBuffers
= 8;
71 ctx
->Const
.Program
[MESA_SHADER_COMPUTE
].MaxAtomicCounters
= 8;
72 ctx
->Const
.Program
[MESA_SHADER_COMPUTE
].MaxImageUniforms
= 8;
73 ctx
->Const
.Program
[MESA_SHADER_COMPUTE
].MaxUniformBlocks
= 12;
75 switch (ctx
->Const
.GLSLVersion
) {
77 ctx
->Const
.MaxClipPlanes
= 0;
78 ctx
->Const
.MaxCombinedTextureImageUnits
= 8;
79 ctx
->Const
.MaxDrawBuffers
= 2;
80 ctx
->Const
.MinProgramTexelOffset
= 0;
81 ctx
->Const
.MaxProgramTexelOffset
= 0;
82 ctx
->Const
.MaxLights
= 0;
83 ctx
->Const
.MaxTextureCoordUnits
= 0;
84 ctx
->Const
.MaxTextureUnits
= 8;
86 ctx
->Const
.Program
[MESA_SHADER_VERTEX
].MaxAttribs
= 8;
87 ctx
->Const
.Program
[MESA_SHADER_VERTEX
].MaxTextureImageUnits
= 0;
88 ctx
->Const
.Program
[MESA_SHADER_VERTEX
].MaxUniformComponents
= 128 * 4;
89 ctx
->Const
.Program
[MESA_SHADER_VERTEX
].MaxCombinedUniformComponents
= 128 * 4;
90 ctx
->Const
.Program
[MESA_SHADER_VERTEX
].MaxInputComponents
= 0; /* not used */
91 ctx
->Const
.Program
[MESA_SHADER_VERTEX
].MaxOutputComponents
= 32;
93 ctx
->Const
.Program
[MESA_SHADER_FRAGMENT
].MaxTextureImageUnits
=
94 ctx
->Const
.MaxCombinedTextureImageUnits
;
95 ctx
->Const
.Program
[MESA_SHADER_FRAGMENT
].MaxUniformComponents
= 16 * 4;
96 ctx
->Const
.Program
[MESA_SHADER_FRAGMENT
].MaxCombinedUniformComponents
= 16 * 4;
97 ctx
->Const
.Program
[MESA_SHADER_FRAGMENT
].MaxInputComponents
=
98 ctx
->Const
.Program
[MESA_SHADER_VERTEX
].MaxOutputComponents
;
99 ctx
->Const
.Program
[MESA_SHADER_FRAGMENT
].MaxOutputComponents
= 0; /* not used */
101 ctx
->Const
.MaxVarying
= ctx
->Const
.Program
[MESA_SHADER_VERTEX
].MaxOutputComponents
/ 4;
105 ctx
->Const
.MaxClipPlanes
= 6;
106 ctx
->Const
.MaxCombinedTextureImageUnits
= 2;
107 ctx
->Const
.MaxDrawBuffers
= 1;
108 ctx
->Const
.MinProgramTexelOffset
= 0;
109 ctx
->Const
.MaxProgramTexelOffset
= 0;
110 ctx
->Const
.MaxLights
= 8;
111 ctx
->Const
.MaxTextureCoordUnits
= 2;
112 ctx
->Const
.MaxTextureUnits
= 2;
114 ctx
->Const
.Program
[MESA_SHADER_VERTEX
].MaxAttribs
= 16;
115 ctx
->Const
.Program
[MESA_SHADER_VERTEX
].MaxTextureImageUnits
= 0;
116 ctx
->Const
.Program
[MESA_SHADER_VERTEX
].MaxUniformComponents
= 512;
117 ctx
->Const
.Program
[MESA_SHADER_VERTEX
].MaxCombinedUniformComponents
= 512;
118 ctx
->Const
.Program
[MESA_SHADER_VERTEX
].MaxInputComponents
= 0; /* not used */
119 ctx
->Const
.Program
[MESA_SHADER_VERTEX
].MaxOutputComponents
= 32;
121 ctx
->Const
.Program
[MESA_SHADER_FRAGMENT
].MaxTextureImageUnits
=
122 ctx
->Const
.MaxCombinedTextureImageUnits
;
123 ctx
->Const
.Program
[MESA_SHADER_FRAGMENT
].MaxUniformComponents
= 64;
124 ctx
->Const
.Program
[MESA_SHADER_FRAGMENT
].MaxCombinedUniformComponents
= 64;
125 ctx
->Const
.Program
[MESA_SHADER_FRAGMENT
].MaxInputComponents
=
126 ctx
->Const
.Program
[MESA_SHADER_VERTEX
].MaxOutputComponents
;
127 ctx
->Const
.Program
[MESA_SHADER_FRAGMENT
].MaxOutputComponents
= 0; /* not used */
129 ctx
->Const
.MaxVarying
= ctx
->Const
.Program
[MESA_SHADER_VERTEX
].MaxOutputComponents
/ 4;
133 ctx
->Const
.MaxClipPlanes
= 8;
134 ctx
->Const
.MaxCombinedTextureImageUnits
= 16;
135 ctx
->Const
.MaxDrawBuffers
= 8;
136 ctx
->Const
.MinProgramTexelOffset
= -8;
137 ctx
->Const
.MaxProgramTexelOffset
= 7;
138 ctx
->Const
.MaxLights
= 8;
139 ctx
->Const
.MaxTextureCoordUnits
= 8;
140 ctx
->Const
.MaxTextureUnits
= 2;
142 ctx
->Const
.Program
[MESA_SHADER_VERTEX
].MaxAttribs
= 16;
143 ctx
->Const
.Program
[MESA_SHADER_VERTEX
].MaxTextureImageUnits
= 16;
144 ctx
->Const
.Program
[MESA_SHADER_VERTEX
].MaxUniformComponents
= 1024;
145 ctx
->Const
.Program
[MESA_SHADER_VERTEX
].MaxCombinedUniformComponents
= 1024;
146 ctx
->Const
.Program
[MESA_SHADER_VERTEX
].MaxInputComponents
= 0; /* not used */
147 ctx
->Const
.Program
[MESA_SHADER_VERTEX
].MaxOutputComponents
= 64;
149 ctx
->Const
.Program
[MESA_SHADER_FRAGMENT
].MaxTextureImageUnits
= 16;
150 ctx
->Const
.Program
[MESA_SHADER_FRAGMENT
].MaxUniformComponents
= 1024;
151 ctx
->Const
.Program
[MESA_SHADER_FRAGMENT
].MaxCombinedUniformComponents
= 1024;
152 ctx
->Const
.Program
[MESA_SHADER_FRAGMENT
].MaxInputComponents
=
153 ctx
->Const
.Program
[MESA_SHADER_VERTEX
].MaxOutputComponents
;
154 ctx
->Const
.Program
[MESA_SHADER_FRAGMENT
].MaxOutputComponents
= 0; /* not used */
156 ctx
->Const
.MaxVarying
= ctx
->Const
.Program
[MESA_SHADER_VERTEX
].MaxOutputComponents
/ 4;
166 ctx
->Const
.MaxClipPlanes
= 8;
167 ctx
->Const
.MaxDrawBuffers
= 8;
168 ctx
->Const
.MinProgramTexelOffset
= -8;
169 ctx
->Const
.MaxProgramTexelOffset
= 7;
170 ctx
->Const
.MaxLights
= 8;
171 ctx
->Const
.MaxTextureCoordUnits
= 8;
172 ctx
->Const
.MaxTextureUnits
= 2;
174 ctx
->Const
.Program
[MESA_SHADER_VERTEX
].MaxAttribs
= 16;
175 ctx
->Const
.Program
[MESA_SHADER_VERTEX
].MaxTextureImageUnits
= 16;
176 ctx
->Const
.Program
[MESA_SHADER_VERTEX
].MaxUniformComponents
= 1024;
177 ctx
->Const
.Program
[MESA_SHADER_VERTEX
].MaxCombinedUniformComponents
= 1024;
178 ctx
->Const
.Program
[MESA_SHADER_VERTEX
].MaxInputComponents
= 0; /* not used */
179 ctx
->Const
.Program
[MESA_SHADER_VERTEX
].MaxOutputComponents
= 64;
181 ctx
->Const
.Program
[MESA_SHADER_GEOMETRY
].MaxTextureImageUnits
= 16;
182 ctx
->Const
.Program
[MESA_SHADER_GEOMETRY
].MaxUniformComponents
= 1024;
183 ctx
->Const
.Program
[MESA_SHADER_GEOMETRY
].MaxCombinedUniformComponents
= 1024;
184 ctx
->Const
.Program
[MESA_SHADER_GEOMETRY
].MaxInputComponents
=
185 ctx
->Const
.Program
[MESA_SHADER_VERTEX
].MaxOutputComponents
;
186 ctx
->Const
.Program
[MESA_SHADER_GEOMETRY
].MaxOutputComponents
= 128;
188 ctx
->Const
.Program
[MESA_SHADER_FRAGMENT
].MaxTextureImageUnits
= 16;
189 ctx
->Const
.Program
[MESA_SHADER_FRAGMENT
].MaxUniformComponents
= 1024;
190 ctx
->Const
.Program
[MESA_SHADER_FRAGMENT
].MaxCombinedUniformComponents
= 1024;
191 ctx
->Const
.Program
[MESA_SHADER_FRAGMENT
].MaxInputComponents
=
192 ctx
->Const
.Program
[MESA_SHADER_GEOMETRY
].MaxOutputComponents
;
193 ctx
->Const
.Program
[MESA_SHADER_FRAGMENT
].MaxOutputComponents
= 0; /* not used */
195 ctx
->Const
.MaxCombinedTextureImageUnits
=
196 ctx
->Const
.Program
[MESA_SHADER_VERTEX
].MaxTextureImageUnits
197 + ctx
->Const
.Program
[MESA_SHADER_GEOMETRY
].MaxTextureImageUnits
198 + ctx
->Const
.Program
[MESA_SHADER_FRAGMENT
].MaxTextureImageUnits
;
200 ctx
->Const
.MaxGeometryOutputVertices
= 256;
201 ctx
->Const
.MaxGeometryTotalOutputComponents
= 1024;
203 ctx
->Const
.MaxVarying
= 60 / 4;
206 ctx
->Const
.MaxClipPlanes
= 8;
207 ctx
->Const
.MaxCombinedTextureImageUnits
= 32;
208 ctx
->Const
.MaxDrawBuffers
= 4;
209 ctx
->Const
.MinProgramTexelOffset
= -8;
210 ctx
->Const
.MaxProgramTexelOffset
= 7;
211 ctx
->Const
.MaxLights
= 0;
212 ctx
->Const
.MaxTextureCoordUnits
= 0;
213 ctx
->Const
.MaxTextureUnits
= 0;
215 ctx
->Const
.Program
[MESA_SHADER_VERTEX
].MaxAttribs
= 16;
216 ctx
->Const
.Program
[MESA_SHADER_VERTEX
].MaxTextureImageUnits
= 16;
217 ctx
->Const
.Program
[MESA_SHADER_VERTEX
].MaxUniformComponents
= 1024;
218 ctx
->Const
.Program
[MESA_SHADER_VERTEX
].MaxCombinedUniformComponents
= 1024;
219 ctx
->Const
.Program
[MESA_SHADER_VERTEX
].MaxInputComponents
= 0; /* not used */
220 ctx
->Const
.Program
[MESA_SHADER_VERTEX
].MaxOutputComponents
= 16 * 4;
222 ctx
->Const
.Program
[MESA_SHADER_FRAGMENT
].MaxTextureImageUnits
= 16;
223 ctx
->Const
.Program
[MESA_SHADER_FRAGMENT
].MaxUniformComponents
= 224;
224 ctx
->Const
.Program
[MESA_SHADER_FRAGMENT
].MaxCombinedUniformComponents
= 224;
225 ctx
->Const
.Program
[MESA_SHADER_FRAGMENT
].MaxInputComponents
= 15 * 4;
226 ctx
->Const
.Program
[MESA_SHADER_FRAGMENT
].MaxOutputComponents
= 0; /* not used */
228 ctx
->Const
.MaxVarying
= ctx
->Const
.Program
[MESA_SHADER_FRAGMENT
].MaxInputComponents
/ 4;
232 ctx
->Const
.GenerateTemporaryNames
= true;
233 ctx
->Const
.MaxPatchVertices
= 32;
235 /* GL_ARB_explicit_uniform_location, GL_MAX_UNIFORM_LOCATIONS */
236 ctx
->Const
.MaxUserAssignableUniformLocations
=
237 4 * MESA_SHADER_STAGES
* MAX_UNIFORMS
;
239 ctx
->Driver
.NewShader
= _mesa_new_linked_shader
;
242 /* Returned string will have 'ctx' as its ralloc owner. */
244 load_text_file(void *ctx
, const char *file_name
)
248 size_t total_read
= 0;
249 FILE *fp
= fopen(file_name
, "rb");
255 fseek(fp
, 0L, SEEK_END
);
257 fseek(fp
, 0L, SEEK_SET
);
259 text
= (char *) ralloc_size(ctx
, size
+ 1);
262 size_t bytes
= fread(text
+ total_read
,
263 1, size
- total_read
, fp
);
264 if (bytes
< size
- total_read
) {
275 } while (total_read
< size
);
277 text
[total_read
] = '\0';
287 compile_shader(struct gl_context
*ctx
, struct gl_shader
*shader
)
289 struct _mesa_glsl_parse_state
*state
=
290 new(shader
) _mesa_glsl_parse_state(ctx
, shader
->Stage
, shader
);
292 _mesa_glsl_compile_shader(ctx
, shader
, options
->dump_ast
, options
->dump_hir
);
294 /* Print out the resulting IR */
295 if (!state
->error
&& options
->dump_lir
) {
296 _mesa_print_ir(stdout
, shader
->ir
, state
);
303 init_gl_program(struct gl_program
*prog
, GLenum target
)
305 mtx_init(&prog
->Mutex
, mtx_plain
);
308 prog
->Format
= GL_PROGRAM_FORMAT_ASCII_ARB
;
310 /* default mapping from samplers to texture units */
311 for (int i
= 0; i
< MAX_SAMPLERS
; i
++)
312 prog
->SamplerUnits
[i
] = i
;
315 extern "C" struct gl_shader_program
*
316 standalone_compile_shader(const struct standalone_options
*_options
,
317 unsigned num_files
, char* const* files
)
319 int status
= EXIT_SUCCESS
;
320 static struct gl_context local_ctx
;
321 struct gl_context
*ctx
= &local_ctx
;
322 bool glsl_es
= false;
326 switch (options
->glsl_version
) {
346 fprintf(stderr
, "Unrecognized GLSL version `%d'\n", options
->glsl_version
);
351 initialize_context(ctx
, API_OPENGLES2
);
353 initialize_context(ctx
, options
->glsl_version
> 130 ? API_OPENGL_CORE
: API_OPENGL_COMPAT
);
356 struct gl_shader_program
*whole_program
;
358 whole_program
= rzalloc (NULL
, struct gl_shader_program
);
359 assert(whole_program
!= NULL
);
360 whole_program
->InfoLog
= ralloc_strdup(whole_program
, "");
362 /* Created just to avoid segmentation faults */
363 whole_program
->AttributeBindings
= new string_to_uint_map
;
364 whole_program
->FragDataBindings
= new string_to_uint_map
;
365 whole_program
->FragDataIndexBindings
= new string_to_uint_map
;
367 for (unsigned i
= 0; i
< num_files
; i
++) {
368 whole_program
->Shaders
=
369 reralloc(whole_program
, whole_program
->Shaders
,
370 struct gl_shader
*, whole_program
->NumShaders
+ 1);
371 assert(whole_program
->Shaders
!= NULL
);
373 struct gl_shader
*shader
= rzalloc(whole_program
, gl_shader
);
375 whole_program
->Shaders
[whole_program
->NumShaders
] = shader
;
376 whole_program
->NumShaders
++;
378 const unsigned len
= strlen(files
[i
]);
382 const char *const ext
= & files
[i
][len
- 5];
383 /* TODO add support to read a .shader_test */
384 if (strncmp(".vert", ext
, 5) == 0 || strncmp(".glsl", ext
, 5) == 0)
385 shader
->Type
= GL_VERTEX_SHADER
;
386 else if (strncmp(".tesc", ext
, 5) == 0)
387 shader
->Type
= GL_TESS_CONTROL_SHADER
;
388 else if (strncmp(".tese", ext
, 5) == 0)
389 shader
->Type
= GL_TESS_EVALUATION_SHADER
;
390 else if (strncmp(".geom", ext
, 5) == 0)
391 shader
->Type
= GL_GEOMETRY_SHADER
;
392 else if (strncmp(".frag", ext
, 5) == 0)
393 shader
->Type
= GL_FRAGMENT_SHADER
;
394 else if (strncmp(".comp", ext
, 5) == 0)
395 shader
->Type
= GL_COMPUTE_SHADER
;
398 shader
->Stage
= _mesa_shader_enum_to_shader_stage(shader
->Type
);
400 shader
->Source
= load_text_file(whole_program
, files
[i
]);
401 if (shader
->Source
== NULL
) {
402 printf("File \"%s\" does not exist.\n", files
[i
]);
406 compile_shader(ctx
, shader
);
408 if (strlen(shader
->InfoLog
) > 0) {
409 if (!options
->just_log
)
410 printf("Info log for %s:\n", files
[i
]);
412 printf("%s", shader
->InfoLog
);
413 if (!options
->just_log
)
417 if (!shader
->CompileStatus
) {
418 status
= EXIT_FAILURE
;
423 if ((status
== EXIT_SUCCESS
) && options
->do_link
) {
424 _mesa_clear_shader_program_data(whole_program
);
426 link_shaders(ctx
, whole_program
);
427 status
= (whole_program
->LinkStatus
) ? EXIT_SUCCESS
: EXIT_FAILURE
;
429 if (strlen(whole_program
->InfoLog
) > 0) {
431 if (!options
->just_log
)
432 printf("Info log for linking:\n");
433 printf("%s", whole_program
->InfoLog
);
434 if (!options
->just_log
)
438 for (unsigned i
= 0; i
< MESA_SHADER_STAGES
; i
++) {
439 struct gl_linked_shader
*shader
= whole_program
->_LinkedShaders
[i
];
444 shader
->Program
= rzalloc(shader
, gl_program
);
445 init_gl_program(shader
->Program
, shader
->Stage
);
449 return whole_program
;
452 ralloc_free(whole_program
);
457 standalone_compiler_cleanup(struct gl_shader_program
*whole_program
)
459 for (unsigned i
= 0; i
< MESA_SHADER_STAGES
; i
++)
460 ralloc_free(whole_program
->_LinkedShaders
[i
]);
462 delete whole_program
->AttributeBindings
;
463 delete whole_program
->FragDataBindings
;
464 delete whole_program
->FragDataIndexBindings
;
466 ralloc_free(whole_program
);
467 _mesa_glsl_release_types();
468 _mesa_glsl_release_builtin_functions();