1 /*
2 * Copyright © 2008, 2009 Intel Corporation
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice (including the next
12 * paragraph) shall be included in all copies or substantial portions of the
13 * Software.
14 *
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
21 * DEALINGS IN THE SOFTWARE.
22 */
23 #include <getopt.h>
24
25 /** @file standalone.cpp
26 *
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.
30 */
31
32 #include "ast.h"
33 #include "glsl_parser_extras.h"
34 #include "ir_optimization.h"
35 #include "standalone_scaffolding.h"
36 #include "standalone.h"
37 #include "util/set.h"
38 #include "gl_nir_linker.h"
39 #include "glsl_parser_extras.h"
40 #include "builtin_functions.h"
41 #include "linker_util.h"
42 #include "main/mtypes.h"
43 #include "program/program.h"
44
45 static const struct standalone_options *options;
46
47 static const struct nir_shader_compiler_options nir_vs_options = { 0 };
48 static const struct nir_shader_compiler_options nir_fs_options = { 0 };
49
50 static void
initialize_context(struct gl_context * ctx,gl_api api)51 initialize_context(struct gl_context *ctx, gl_api api)
52 {
53 initialize_context_to_defaults(ctx, api);
54 _mesa_glsl_builtin_functions_init_or_ref();
55
56 ctx->Version = 450;
57 ctx->Const.ShaderCompilerOptions[MESA_SHADER_VERTEX].NirOptions =
58 &nir_fs_options;
59 ctx->Const.ShaderCompilerOptions[MESA_SHADER_FRAGMENT].NirOptions =
60 &nir_vs_options;
61
62 /* The standalone compiler needs to claim support for almost
63 * everything in order to compile the built-in functions.
64 */
65 ctx->Const.GLSLVersion = options->glsl_version;
66 ctx->Extensions.ARB_ES3_compatibility = true;
67 ctx->Extensions.ARB_ES3_1_compatibility = true;
68 ctx->Extensions.ARB_ES3_2_compatibility = true;
69 ctx->Const.MaxComputeWorkGroupCount[0] = 65535;
70 ctx->Const.MaxComputeWorkGroupCount[1] = 65535;
71 ctx->Const.MaxComputeWorkGroupCount[2] = 65535;
72 ctx->Const.MaxComputeWorkGroupSize[0] = 1024;
73 ctx->Const.MaxComputeWorkGroupSize[1] = 1024;
74 ctx->Const.MaxComputeWorkGroupSize[2] = 64;
75 ctx->Const.MaxComputeWorkGroupInvocations = 1024;
76 ctx->Const.MaxComputeSharedMemorySize = 32768;
77 ctx->Const.MaxComputeVariableGroupSize[0] = 512;
78 ctx->Const.MaxComputeVariableGroupSize[1] = 512;
79 ctx->Const.MaxComputeVariableGroupSize[2] = 64;
80 ctx->Const.MaxComputeVariableGroupInvocations = 512;
81 ctx->Const.Program[MESA_SHADER_COMPUTE].MaxTextureImageUnits = 16;
82 ctx->Const.Program[MESA_SHADER_COMPUTE].MaxUniformComponents = 1024;
83 ctx->Const.Program[MESA_SHADER_COMPUTE].MaxCombinedUniformComponents = 1024;
84 ctx->Const.Program[MESA_SHADER_COMPUTE].MaxInputComponents = 0; /* not used */
85 ctx->Const.Program[MESA_SHADER_COMPUTE].MaxOutputComponents = 0; /* not used */
86 ctx->Const.Program[MESA_SHADER_COMPUTE].MaxAtomicBuffers = 8;
87 ctx->Const.Program[MESA_SHADER_COMPUTE].MaxAtomicCounters = 8;
88 ctx->Const.Program[MESA_SHADER_COMPUTE].MaxImageUniforms = 8;
89 ctx->Const.Program[MESA_SHADER_COMPUTE].MaxUniformBlocks = 12;
90
91 switch (ctx->Const.GLSLVersion) {
92 case 100:
93 ctx->Const.MaxClipPlanes = 0;
94 ctx->Const.MaxCombinedTextureImageUnits = 8;
95 ctx->Const.MaxDrawBuffers = 2;
96 ctx->Const.MinProgramTexelOffset = 0;
97 ctx->Const.MaxProgramTexelOffset = 0;
98 ctx->Const.MaxLights = 0;
99 ctx->Const.MaxTextureCoordUnits = 0;
100 ctx->Const.MaxTextureUnits = 8;
101
102 ctx->Const.Program[MESA_SHADER_VERTEX].MaxAttribs = 8;
103 ctx->Const.Program[MESA_SHADER_VERTEX].MaxTextureImageUnits = 0;
104 ctx->Const.Program[MESA_SHADER_VERTEX].MaxUniformComponents = 128 * 4;
105 ctx->Const.Program[MESA_SHADER_VERTEX].MaxCombinedUniformComponents = 128 * 4;
106 ctx->Const.Program[MESA_SHADER_VERTEX].MaxInputComponents = 0; /* not used */
107 ctx->Const.Program[MESA_SHADER_VERTEX].MaxOutputComponents = 32;
108
109 ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxTextureImageUnits =
110 ctx->Const.MaxCombinedTextureImageUnits;
111 ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxUniformComponents = 16 * 4;
112 ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxCombinedUniformComponents = 16 * 4;
113 ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxInputComponents =
114 ctx->Const.Program[MESA_SHADER_VERTEX].MaxOutputComponents;
115 ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxOutputComponents = 0; /* not used */
116
117 ctx->Const.MaxVarying = ctx->Const.Program[MESA_SHADER_VERTEX].MaxOutputComponents / 4;
118 break;
119 case 110:
120 case 120:
121 ctx->Const.MaxClipPlanes = 6;
122 ctx->Const.MaxCombinedTextureImageUnits = 2;
123 ctx->Const.MaxDrawBuffers = 1;
124 ctx->Const.MinProgramTexelOffset = 0;
125 ctx->Const.MaxProgramTexelOffset = 0;
126 ctx->Const.MaxLights = 8;
127 ctx->Const.MaxTextureCoordUnits = 2;
128 ctx->Const.MaxTextureUnits = 2;
129
130 ctx->Const.Program[MESA_SHADER_VERTEX].MaxAttribs = 16;
131 ctx->Const.Program[MESA_SHADER_VERTEX].MaxTextureImageUnits = 0;
132 ctx->Const.Program[MESA_SHADER_VERTEX].MaxUniformComponents = 512;
133 ctx->Const.Program[MESA_SHADER_VERTEX].MaxCombinedUniformComponents = 512;
134 ctx->Const.Program[MESA_SHADER_VERTEX].MaxInputComponents = 0; /* not used */
135 ctx->Const.Program[MESA_SHADER_VERTEX].MaxOutputComponents = 32;
136
137 ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxTextureImageUnits =
138 ctx->Const.MaxCombinedTextureImageUnits;
139 ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxUniformComponents = 64;
140 ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxCombinedUniformComponents = 64;
141 ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxInputComponents =
142 ctx->Const.Program[MESA_SHADER_VERTEX].MaxOutputComponents;
143 ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxOutputComponents = 0; /* not used */
144
145 ctx->Const.MaxVarying = ctx->Const.Program[MESA_SHADER_VERTEX].MaxOutputComponents / 4;
146 break;
147 case 130:
148 case 140:
149 ctx->Const.MaxClipPlanes = 8;
150 ctx->Const.MaxCombinedTextureImageUnits = 16;
151 ctx->Const.MaxDrawBuffers = 8;
152 ctx->Const.MinProgramTexelOffset = -8;
153 ctx->Const.MaxProgramTexelOffset = 7;
154 ctx->Const.MaxLights = 8;
155 ctx->Const.MaxTextureCoordUnits = 8;
156 ctx->Const.MaxTextureUnits = 2;
157 ctx->Const.MaxUniformBufferBindings = 84;
158 ctx->Const.MaxVertexStreams = 4;
159 ctx->Const.MaxTransformFeedbackBuffers = 4;
160
161 ctx->Const.Program[MESA_SHADER_VERTEX].MaxAttribs = 16;
162 ctx->Const.Program[MESA_SHADER_VERTEX].MaxTextureImageUnits = 16;
163 ctx->Const.Program[MESA_SHADER_VERTEX].MaxUniformComponents = 1024;
164 ctx->Const.Program[MESA_SHADER_VERTEX].MaxCombinedUniformComponents = 1024;
165 ctx->Const.Program[MESA_SHADER_VERTEX].MaxInputComponents = 0; /* not used */
166 ctx->Const.Program[MESA_SHADER_VERTEX].MaxOutputComponents = 64;
167
168 ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxTextureImageUnits = 16;
169 ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxUniformComponents = 1024;
170 ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxCombinedUniformComponents = 1024;
171 ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxInputComponents =
172 ctx->Const.Program[MESA_SHADER_VERTEX].MaxOutputComponents;
173 ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxOutputComponents = 0; /* not used */
174
175 ctx->Const.MaxVarying = ctx->Const.Program[MESA_SHADER_VERTEX].MaxOutputComponents / 4;
176 break;
177 case 150:
178 case 330:
179 case 400:
180 case 410:
181 case 420:
182 case 430:
183 case 440:
184 case 450:
185 case 460:
186 ctx->Const.MaxClipPlanes = 8;
187 ctx->Const.MaxDrawBuffers = 8;
188 ctx->Const.MinProgramTexelOffset = -8;
189 ctx->Const.MaxProgramTexelOffset = 7;
190 ctx->Const.MaxLights = 8;
191 ctx->Const.MaxTextureCoordUnits = 8;
192 ctx->Const.MaxTextureUnits = 2;
193 ctx->Const.MaxUniformBufferBindings = 84;
194 ctx->Const.MaxVertexStreams = 4;
195 ctx->Const.MaxTransformFeedbackBuffers = 4;
196 ctx->Const.MaxShaderStorageBufferBindings = 4;
197 ctx->Const.MaxShaderStorageBlockSize = 4096;
198 ctx->Const.MaxAtomicBufferBindings = 4;
199
200 ctx->Const.Program[MESA_SHADER_VERTEX].MaxAttribs = 16;
201 ctx->Const.Program[MESA_SHADER_VERTEX].MaxTextureImageUnits = 16;
202 ctx->Const.Program[MESA_SHADER_VERTEX].MaxUniformComponents = 1024;
203 ctx->Const.Program[MESA_SHADER_VERTEX].MaxCombinedUniformComponents = 1024;
204 ctx->Const.Program[MESA_SHADER_VERTEX].MaxInputComponents = 0; /* not used */
205 ctx->Const.Program[MESA_SHADER_VERTEX].MaxOutputComponents = 64;
206
207 ctx->Const.Program[MESA_SHADER_GEOMETRY].MaxTextureImageUnits = 16;
208 ctx->Const.Program[MESA_SHADER_GEOMETRY].MaxUniformComponents = 1024;
209 ctx->Const.Program[MESA_SHADER_GEOMETRY].MaxCombinedUniformComponents = 1024;
210 ctx->Const.Program[MESA_SHADER_GEOMETRY].MaxInputComponents =
211 ctx->Const.Program[MESA_SHADER_VERTEX].MaxOutputComponents;
212 ctx->Const.Program[MESA_SHADER_GEOMETRY].MaxOutputComponents = 128;
213
214 ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxTextureImageUnits = 16;
215 ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxUniformComponents = 1024;
216 ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxCombinedUniformComponents = 1024;
217 ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxInputComponents =
218 ctx->Const.Program[MESA_SHADER_GEOMETRY].MaxOutputComponents;
219 ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxOutputComponents = 0; /* not used */
220
221 ctx->Const.MaxCombinedTextureImageUnits =
222 ctx->Const.Program[MESA_SHADER_VERTEX].MaxTextureImageUnits
223 + ctx->Const.Program[MESA_SHADER_GEOMETRY].MaxTextureImageUnits
224 + ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxTextureImageUnits;
225
226 ctx->Const.MaxGeometryOutputVertices = 256;
227 ctx->Const.MaxGeometryTotalOutputComponents = 1024;
228
229 ctx->Const.MaxVarying = 60 / 4;
230 break;
231 case 300:
232 ctx->Const.MaxClipPlanes = 8;
233 ctx->Const.MaxCombinedTextureImageUnits = 32;
234 ctx->Const.MaxDrawBuffers = 4;
235 ctx->Const.MinProgramTexelOffset = -8;
236 ctx->Const.MaxProgramTexelOffset = 7;
237 ctx->Const.MaxLights = 0;
238 ctx->Const.MaxTextureCoordUnits = 0;
239 ctx->Const.MaxTextureUnits = 0;
240 ctx->Const.MaxUniformBufferBindings = 84;
241 ctx->Const.MaxVertexStreams = 4;
242 ctx->Const.MaxTransformFeedbackBuffers = 4;
243
244 ctx->Const.Program[MESA_SHADER_VERTEX].MaxAttribs = 16;
245 ctx->Const.Program[MESA_SHADER_VERTEX].MaxTextureImageUnits = 16;
246 ctx->Const.Program[MESA_SHADER_VERTEX].MaxUniformComponents = 1024;
247 ctx->Const.Program[MESA_SHADER_VERTEX].MaxCombinedUniformComponents = 1024;
248 ctx->Const.Program[MESA_SHADER_VERTEX].MaxInputComponents = 0; /* not used */
249 ctx->Const.Program[MESA_SHADER_VERTEX].MaxOutputComponents = 16 * 4;
250
251 ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxTextureImageUnits = 16;
252 ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxUniformComponents = 224;
253 ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxCombinedUniformComponents = 224;
254 ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxInputComponents = 15 * 4;
255 ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxOutputComponents = 0; /* not used */
256
257 ctx->Const.MaxVarying = ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxInputComponents / 4;
258 break;
259 }
260
261 ctx->Const.GenerateTemporaryNames = true;
262 ctx->Const.MaxPatchVertices = 32;
263
264 /* GL_ARB_explicit_uniform_location, GL_MAX_UNIFORM_LOCATIONS */
265 ctx->Const.MaxUserAssignableUniformLocations =
266 4 * MESA_SHADER_STAGES * MAX_UNIFORMS;
267 }
268
269 /* Returned string will have 'ctx' as its ralloc owner. */
270 static char *
load_text_file(void * ctx,const char * file_name)271 load_text_file(void *ctx, const char *file_name)
272 {
273 char *text = NULL;
274 size_t size;
275 size_t total_read = 0;
276 FILE *fp = fopen(file_name, "rb");
277
278 if (!fp) {
279 return NULL;
280 }
281
282 fseek(fp, 0L, SEEK_END);
283 size = ftell(fp);
284 fseek(fp, 0L, SEEK_SET);
285
286 text = (char *) ralloc_size(ctx, size + 1);
287 if (text != NULL) {
288 do {
289 size_t bytes = fread(text + total_read,
290 1, size - total_read, fp);
291 if (bytes < size - total_read) {
292 text = NULL;
293 goto error;
294 }
295
296 if (bytes == 0) {
297 break;
298 }
299
300 total_read += bytes;
301 } while (total_read < size);
302
303 text[total_read] = '\0';
304 error:;
305 }
306
307 fclose(fp);
308
309 return text;
310 }
311
312 static void
compile_shader(struct gl_context * ctx,struct gl_shader * shader)313 compile_shader(struct gl_context *ctx, struct gl_shader *shader)
314 {
315 /* Print out the resulting IR if requested */
316 FILE *print_file = options->dump_lir ? stdout : NULL;
317
318 _mesa_glsl_compile_shader(ctx, shader, print_file, options->dump_ast,
319 options->dump_hir, true);
320 }
321
322 extern "C" struct gl_shader_program *
standalone_compile_shader(const struct standalone_options * _options,unsigned num_files,char * const * files,struct gl_context * ctx)323 standalone_compile_shader(const struct standalone_options *_options,
324 unsigned num_files, char* const* files, struct gl_context *ctx)
325 {
326 int status = EXIT_SUCCESS;
327 bool glsl_es = false;
328
329 options = _options;
330
331 switch (options->glsl_version) {
332 case 100:
333 case 300:
334 case 310:
335 case 320:
336 glsl_es = true;
337 break;
338 case 110:
339 case 120:
340 case 130:
341 case 140:
342 case 150:
343 case 330:
344 case 400:
345 case 410:
346 case 420:
347 case 430:
348 case 440:
349 case 450:
350 case 460:
351 glsl_es = false;
352 break;
353 default:
354 fprintf(stderr, "Unrecognized GLSL version `%d'\n", options->glsl_version);
355 return NULL;
356 }
357
358 if (glsl_es) {
359 initialize_context(ctx, API_OPENGLES2);
360 } else {
361 initialize_context(ctx, options->glsl_version > 130 ? API_OPENGL_CORE : API_OPENGL_COMPAT);
362 }
363
364 if (options->lower_precision) {
365 for (unsigned i = MESA_SHADER_VERTEX; i <= MESA_SHADER_COMPUTE; i++) {
366 struct gl_shader_compiler_options *options =
367 &ctx->Const.ShaderCompilerOptions[i];
368 options->LowerPrecisionFloat16 = true;
369 options->LowerPrecisionInt16 = true;
370 options->LowerPrecisionDerivatives = true;
371 options->LowerPrecisionConstants = true;
372 options->LowerPrecisionFloat16Uniforms = true;
373 }
374 }
375
376 struct gl_shader_program *whole_program = standalone_create_shader_program();
377
378 for (unsigned i = 0; i < num_files; i++) {
379 const unsigned len = strlen(files[i]);
380 if (len < 6)
381 goto fail;
382
383 const char *const ext = & files[i][len - 5];
384 /* TODO add support to read a .shader_test */
385 GLenum type;
386 if (strncmp(".vert", ext, 5) == 0 || strncmp(".glsl", ext, 5) == 0)
387 type = GL_VERTEX_SHADER;
388 else if (strncmp(".tesc", ext, 5) == 0)
389 type = GL_TESS_CONTROL_SHADER;
390 else if (strncmp(".tese", ext, 5) == 0)
391 type = GL_TESS_EVALUATION_SHADER;
392 else if (strncmp(".geom", ext, 5) == 0)
393 type = GL_GEOMETRY_SHADER;
394 else if (strncmp(".frag", ext, 5) == 0)
395 type = GL_FRAGMENT_SHADER;
396 else if (strncmp(".comp", ext, 5) == 0)
397 type = GL_COMPUTE_SHADER;
398 else
399 goto fail;
400
401 const char *source = load_text_file(whole_program, files[i]);
402 if (source == NULL) {
403 printf("File \"%s\" does not exist.\n", files[i]);
404 exit(EXIT_FAILURE);
405 }
406
407 struct gl_shader *shader = standalone_add_shader_source(ctx, whole_program, type, source);
408
409 compile_shader(ctx, shader);
410
411 if (strlen(shader->InfoLog) > 0) {
412 if (!options->just_log)
413 printf("Info log for %s:\n", files[i]);
414
415 printf("%s", shader->InfoLog);
416 if (!options->just_log)
417 printf("\n");
418 }
419
420 if (!shader->CompileStatus) {
421 status = EXIT_FAILURE;
422 break;
423 }
424 }
425
426 if (status == EXIT_SUCCESS && options->do_link) {
427 _mesa_clear_shader_program_data(ctx, whole_program);
428
429 whole_program->data->LinkStatus = LINKING_SUCCESS;
430 link_shaders_init(ctx, whole_program);
431 gl_nir_link_glsl(ctx, whole_program);
432
433 status = (whole_program->data->LinkStatus) ? EXIT_SUCCESS : EXIT_FAILURE;
434
435 if (strlen(whole_program->data->InfoLog) > 0) {
436 printf("\n");
437 if (!options->just_log)
438 printf("Info log for linking:\n");
439 printf("%s", whole_program->data->InfoLog);
440 if (!options->just_log)
441 printf("\n");
442 }
443 }
444
445 return whole_program;
446
447 fail:
448 for (unsigned i = 0; i < MESA_SHADER_STAGES; i++) {
449 if (whole_program->_LinkedShaders[i])
450 _mesa_delete_linked_shader(ctx, whole_program->_LinkedShaders[i]);
451 }
452
453 ralloc_free(whole_program);
454 return NULL;
455 }
456
457 extern "C" void
standalone_compiler_cleanup(struct gl_shader_program * whole_program)458 standalone_compiler_cleanup(struct gl_shader_program *whole_program)
459 {
460 standalone_destroy_shader_program(whole_program);
461
462 _mesa_glsl_builtin_functions_decref();
463 }
464