blob: feed100822cfccdb53f0e83824d8fc1b2e8df774 [file] [log] [blame]
Ian Romanick61d4aa02010-06-14 14:46:09 -07001/*
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 */
Ian Romanick7babbdb2010-06-15 12:47:07 -070023#include <getopt.h>
Ian Romanick61d4aa02010-06-14 14:46:09 -070024
Eric Anholt6a6cb032012-04-18 14:40:10 -070025/** @file main.cpp
26 *
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.
32 */
33
Ian Romanick61d4aa02010-06-14 14:46:09 -070034#include "ast.h"
35#include "glsl_parser_extras.h"
Ian Romanick61d4aa02010-06-14 14:46:09 -070036#include "ir_optimization.h"
Ian Romanick8ce55db2010-06-17 12:01:18 -070037#include "program.h"
Ian Romanick8df2dbf2010-08-26 16:45:22 -070038#include "loop_analysis.h"
Paul Berryf129f612011-07-07 14:01:40 -070039#include "standalone_scaffolding.h"
Ian Romanick3fb87872010-07-09 14:09:34 -070040
Ian Romanick3646d652013-09-09 14:07:15 -050041static int glsl_version = 330;
42
Ian Romanick59ad2e62014-03-04 15:39:37 +020043extern "C" void
44_mesa_error_no_memory(const char *caller)
45{
46 fprintf(stderr, "Mesa error: out of memory in %s", caller);
47}
48
Chia-I Wudc754582010-09-08 18:48:12 +080049static void
Kristian Høgsbergf9995b32010-10-12 12:26:10 -040050initialize_context(struct gl_context *ctx, gl_api api)
Chia-I Wudc754582010-09-08 18:48:12 +080051{
Paul Berryf129f612011-07-07 14:01:40 -070052 initialize_context_to_defaults(ctx, api);
Chia-I Wudc754582010-09-08 18:48:12 +080053
Eric Anholt497aab32012-03-12 15:51:54 -070054 /* The standalone compiler needs to claim support for almost
55 * everything in order to compile the built-in functions.
Ian Romanicke5e34ab2011-01-31 14:52:27 -080056 */
Ian Romanick3646d652013-09-09 14:07:15 -050057 ctx->Const.GLSLVersion = glsl_version;
Paul Berry486f9552012-08-04 15:42:33 -070058 ctx->Extensions.ARB_ES3_compatibility = true;
Paul Berry0398b692014-01-08 01:42:58 -080059 ctx->Const.MaxComputeWorkGroupCount[0] = 65535;
60 ctx->Const.MaxComputeWorkGroupCount[1] = 65535;
61 ctx->Const.MaxComputeWorkGroupCount[2] = 65535;
Paul Berry347dde82014-01-06 13:31:58 -080062 ctx->Const.MaxComputeWorkGroupSize[0] = 1024;
63 ctx->Const.MaxComputeWorkGroupSize[1] = 1024;
64 ctx->Const.MaxComputeWorkGroupSize[2] = 64;
Paul Berryc85c5092014-01-06 15:11:40 -080065 ctx->Const.MaxComputeWorkGroupInvocations = 1024;
Paul Berryd861c292014-01-06 20:06:05 -080066 ctx->Const.Program[MESA_SHADER_COMPUTE].MaxTextureImageUnits = 16;
67 ctx->Const.Program[MESA_SHADER_COMPUTE].MaxUniformComponents = 1024;
68 ctx->Const.Program[MESA_SHADER_COMPUTE].MaxInputComponents = 0; /* not used */
69 ctx->Const.Program[MESA_SHADER_COMPUTE].MaxOutputComponents = 0; /* not used */
Ian Romanicke5e34ab2011-01-31 14:52:27 -080070
Ian Romanick3646d652013-09-09 14:07:15 -050071 switch (ctx->Const.GLSLVersion) {
72 case 100:
73 ctx->Const.MaxClipPlanes = 0;
74 ctx->Const.MaxCombinedTextureImageUnits = 8;
75 ctx->Const.MaxDrawBuffers = 2;
76 ctx->Const.MinProgramTexelOffset = 0;
77 ctx->Const.MaxProgramTexelOffset = 0;
78 ctx->Const.MaxLights = 0;
79 ctx->Const.MaxTextureCoordUnits = 0;
80 ctx->Const.MaxTextureUnits = 8;
Chia-I Wudc754582010-09-08 18:48:12 +080081
Paul Berry84732a92014-01-08 10:00:28 -080082 ctx->Const.Program[MESA_SHADER_VERTEX].MaxAttribs = 8;
83 ctx->Const.Program[MESA_SHADER_VERTEX].MaxTextureImageUnits = 0;
84 ctx->Const.Program[MESA_SHADER_VERTEX].MaxUniformComponents = 128 * 4;
85 ctx->Const.Program[MESA_SHADER_VERTEX].MaxInputComponents = 0; /* not used */
86 ctx->Const.Program[MESA_SHADER_VERTEX].MaxOutputComponents = 32;
Ian Romanick3646d652013-09-09 14:07:15 -050087
Paul Berry84732a92014-01-08 10:00:28 -080088 ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxTextureImageUnits =
Ian Romanick3646d652013-09-09 14:07:15 -050089 ctx->Const.MaxCombinedTextureImageUnits;
Paul Berry84732a92014-01-08 10:00:28 -080090 ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxUniformComponents = 16 * 4;
91 ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxInputComponents =
92 ctx->Const.Program[MESA_SHADER_VERTEX].MaxOutputComponents;
93 ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxOutputComponents = 0; /* not used */
Ian Romanick3646d652013-09-09 14:07:15 -050094
Paul Berry84732a92014-01-08 10:00:28 -080095 ctx->Const.MaxVarying = ctx->Const.Program[MESA_SHADER_VERTEX].MaxOutputComponents / 4;
Ian Romanick3646d652013-09-09 14:07:15 -050096 break;
97 case 110:
98 case 120:
99 ctx->Const.MaxClipPlanes = 6;
100 ctx->Const.MaxCombinedTextureImageUnits = 2;
101 ctx->Const.MaxDrawBuffers = 1;
102 ctx->Const.MinProgramTexelOffset = 0;
103 ctx->Const.MaxProgramTexelOffset = 0;
104 ctx->Const.MaxLights = 8;
105 ctx->Const.MaxTextureCoordUnits = 2;
106 ctx->Const.MaxTextureUnits = 2;
107
Paul Berry84732a92014-01-08 10:00:28 -0800108 ctx->Const.Program[MESA_SHADER_VERTEX].MaxAttribs = 16;
109 ctx->Const.Program[MESA_SHADER_VERTEX].MaxTextureImageUnits = 0;
110 ctx->Const.Program[MESA_SHADER_VERTEX].MaxUniformComponents = 512;
111 ctx->Const.Program[MESA_SHADER_VERTEX].MaxInputComponents = 0; /* not used */
112 ctx->Const.Program[MESA_SHADER_VERTEX].MaxOutputComponents = 32;
Ian Romanick3646d652013-09-09 14:07:15 -0500113
Paul Berry84732a92014-01-08 10:00:28 -0800114 ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxTextureImageUnits =
Ian Romanick3646d652013-09-09 14:07:15 -0500115 ctx->Const.MaxCombinedTextureImageUnits;
Paul Berry84732a92014-01-08 10:00:28 -0800116 ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxUniformComponents = 64;
117 ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxInputComponents =
118 ctx->Const.Program[MESA_SHADER_VERTEX].MaxOutputComponents;
119 ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxOutputComponents = 0; /* not used */
Ian Romanick3646d652013-09-09 14:07:15 -0500120
Paul Berry84732a92014-01-08 10:00:28 -0800121 ctx->Const.MaxVarying = ctx->Const.Program[MESA_SHADER_VERTEX].MaxOutputComponents / 4;
Ian Romanick3646d652013-09-09 14:07:15 -0500122 break;
123 case 130:
124 case 140:
125 ctx->Const.MaxClipPlanes = 8;
126 ctx->Const.MaxCombinedTextureImageUnits = 16;
127 ctx->Const.MaxDrawBuffers = 8;
128 ctx->Const.MinProgramTexelOffset = -8;
129 ctx->Const.MaxProgramTexelOffset = 7;
130 ctx->Const.MaxLights = 8;
131 ctx->Const.MaxTextureCoordUnits = 8;
132 ctx->Const.MaxTextureUnits = 2;
133
Paul Berry84732a92014-01-08 10:00:28 -0800134 ctx->Const.Program[MESA_SHADER_VERTEX].MaxAttribs = 16;
135 ctx->Const.Program[MESA_SHADER_VERTEX].MaxTextureImageUnits = 16;
136 ctx->Const.Program[MESA_SHADER_VERTEX].MaxUniformComponents = 1024;
137 ctx->Const.Program[MESA_SHADER_VERTEX].MaxInputComponents = 0; /* not used */
138 ctx->Const.Program[MESA_SHADER_VERTEX].MaxOutputComponents = 64;
Ian Romanick3646d652013-09-09 14:07:15 -0500139
Paul Berry84732a92014-01-08 10:00:28 -0800140 ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxTextureImageUnits = 16;
141 ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxUniformComponents = 1024;
142 ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxInputComponents =
143 ctx->Const.Program[MESA_SHADER_VERTEX].MaxOutputComponents;
144 ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxOutputComponents = 0; /* not used */
Ian Romanick3646d652013-09-09 14:07:15 -0500145
Paul Berry84732a92014-01-08 10:00:28 -0800146 ctx->Const.MaxVarying = ctx->Const.Program[MESA_SHADER_VERTEX].MaxOutputComponents / 4;
Ian Romanick3646d652013-09-09 14:07:15 -0500147 break;
148 case 150:
149 case 330:
150 ctx->Const.MaxClipPlanes = 8;
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
Paul Berry84732a92014-01-08 10:00:28 -0800158 ctx->Const.Program[MESA_SHADER_VERTEX].MaxAttribs = 16;
159 ctx->Const.Program[MESA_SHADER_VERTEX].MaxTextureImageUnits = 16;
160 ctx->Const.Program[MESA_SHADER_VERTEX].MaxUniformComponents = 1024;
161 ctx->Const.Program[MESA_SHADER_VERTEX].MaxInputComponents = 0; /* not used */
162 ctx->Const.Program[MESA_SHADER_VERTEX].MaxOutputComponents = 64;
Ian Romanick3646d652013-09-09 14:07:15 -0500163
Paul Berry84732a92014-01-08 10:00:28 -0800164 ctx->Const.Program[MESA_SHADER_GEOMETRY].MaxTextureImageUnits = 16;
165 ctx->Const.Program[MESA_SHADER_GEOMETRY].MaxUniformComponents = 1024;
166 ctx->Const.Program[MESA_SHADER_GEOMETRY].MaxInputComponents =
167 ctx->Const.Program[MESA_SHADER_VERTEX].MaxOutputComponents;
168 ctx->Const.Program[MESA_SHADER_GEOMETRY].MaxOutputComponents = 128;
Ian Romanick3646d652013-09-09 14:07:15 -0500169
Paul Berry84732a92014-01-08 10:00:28 -0800170 ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxTextureImageUnits = 16;
171 ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxUniformComponents = 1024;
172 ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxInputComponents =
173 ctx->Const.Program[MESA_SHADER_GEOMETRY].MaxOutputComponents;
174 ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxOutputComponents = 0; /* not used */
Ian Romanick3646d652013-09-09 14:07:15 -0500175
176 ctx->Const.MaxCombinedTextureImageUnits =
Paul Berry84732a92014-01-08 10:00:28 -0800177 ctx->Const.Program[MESA_SHADER_VERTEX].MaxTextureImageUnits
178 + ctx->Const.Program[MESA_SHADER_GEOMETRY].MaxTextureImageUnits
179 + ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxTextureImageUnits;
Ian Romanick3646d652013-09-09 14:07:15 -0500180
181 ctx->Const.MaxGeometryOutputVertices = 256;
182 ctx->Const.MaxGeometryTotalOutputComponents = 1024;
183
184// ctx->Const.MaxGeometryVaryingComponents = 64;
185
186 ctx->Const.MaxVarying = 60 / 4;
187 break;
188 case 300:
189 ctx->Const.MaxClipPlanes = 8;
190 ctx->Const.MaxCombinedTextureImageUnits = 32;
191 ctx->Const.MaxDrawBuffers = 4;
192 ctx->Const.MinProgramTexelOffset = -8;
193 ctx->Const.MaxProgramTexelOffset = 7;
194 ctx->Const.MaxLights = 0;
195 ctx->Const.MaxTextureCoordUnits = 0;
196 ctx->Const.MaxTextureUnits = 0;
197
Paul Berry84732a92014-01-08 10:00:28 -0800198 ctx->Const.Program[MESA_SHADER_VERTEX].MaxAttribs = 16;
199 ctx->Const.Program[MESA_SHADER_VERTEX].MaxTextureImageUnits = 16;
200 ctx->Const.Program[MESA_SHADER_VERTEX].MaxUniformComponents = 1024;
201 ctx->Const.Program[MESA_SHADER_VERTEX].MaxInputComponents = 0; /* not used */
202 ctx->Const.Program[MESA_SHADER_VERTEX].MaxOutputComponents = 16 * 4;
Ian Romanick3646d652013-09-09 14:07:15 -0500203
Paul Berry84732a92014-01-08 10:00:28 -0800204 ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxTextureImageUnits = 16;
205 ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxUniformComponents = 224;
206 ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxInputComponents = 15 * 4;
207 ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxOutputComponents = 0; /* not used */
Ian Romanick3646d652013-09-09 14:07:15 -0500208
Paul Berry84732a92014-01-08 10:00:28 -0800209 ctx->Const.MaxVarying = ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxInputComponents / 4;
Ian Romanick3646d652013-09-09 14:07:15 -0500210 break;
211 }
Chia-I Wudc754582010-09-08 18:48:12 +0800212
Ian Romanick04e13572014-07-08 18:55:27 -0700213 ctx->Const.GenerateTemporaryNames = true;
Chia-I Wudc754582010-09-08 18:48:12 +0800214 ctx->Driver.NewShader = _mesa_new_shader;
215}
216
Kenneth Graunked3073f52011-01-21 14:32:31 -0800217/* Returned string will have 'ctx' as its ralloc owner. */
Ian Romanick61d4aa02010-06-14 14:46:09 -0700218static char *
Eric Anholt16b68b12010-06-30 11:05:43 -0700219load_text_file(void *ctx, const char *file_name)
Ian Romanick61d4aa02010-06-14 14:46:09 -0700220{
221 char *text = NULL;
José Fonseca0035d1d2011-01-12 16:31:07 +0000222 size_t size;
223 size_t total_read = 0;
224 FILE *fp = fopen(file_name, "rb");
Ian Romanick61d4aa02010-06-14 14:46:09 -0700225
José Fonseca0035d1d2011-01-12 16:31:07 +0000226 if (!fp) {
Ian Romanick61d4aa02010-06-14 14:46:09 -0700227 return NULL;
228 }
229
José Fonseca0035d1d2011-01-12 16:31:07 +0000230 fseek(fp, 0L, SEEK_END);
231 size = ftell(fp);
232 fseek(fp, 0L, SEEK_SET);
Ian Romanick61d4aa02010-06-14 14:46:09 -0700233
Kenneth Graunked3073f52011-01-21 14:32:31 -0800234 text = (char *) ralloc_size(ctx, size + 1);
José Fonseca0035d1d2011-01-12 16:31:07 +0000235 if (text != NULL) {
236 do {
237 size_t bytes = fread(text + total_read,
238 1, size - total_read, fp);
239 if (bytes < size - total_read) {
240 free(text);
241 text = NULL;
Juha-Pekka Heikkila88cad832014-02-07 14:43:59 +0200242 goto error;
José Fonseca0035d1d2011-01-12 16:31:07 +0000243 }
Ian Romanick61d4aa02010-06-14 14:46:09 -0700244
José Fonseca0035d1d2011-01-12 16:31:07 +0000245 if (bytes == 0) {
246 break;
247 }
Ian Romanick61d4aa02010-06-14 14:46:09 -0700248
José Fonseca0035d1d2011-01-12 16:31:07 +0000249 total_read += bytes;
250 } while (total_read < size);
251
252 text[total_read] = '\0';
Juha-Pekka Heikkila88cad832014-02-07 14:43:59 +0200253error:;
Ian Romanick61d4aa02010-06-14 14:46:09 -0700254 }
255
José Fonseca0035d1d2011-01-12 16:31:07 +0000256 fclose(fp);
Ian Romanick61d4aa02010-06-14 14:46:09 -0700257
258 return text;
259}
260
Ian Romanick7babbdb2010-06-15 12:47:07 -0700261int dump_ast = 0;
Ian Romanick22c23de2010-06-25 15:27:47 -0700262int dump_hir = 0;
Ian Romanick81e17472010-06-15 12:51:38 -0700263int dump_lir = 0;
Ian Romanickc648a122010-06-17 19:51:48 -0700264int do_link = 0;
Ian Romanick7babbdb2010-06-15 12:47:07 -0700265
266const struct option compiler_opts[] = {
Ian Romanick257db612013-09-09 10:06:59 -0500267 { "dump-ast", no_argument, &dump_ast, 1 },
268 { "dump-hir", no_argument, &dump_hir, 1 },
269 { "dump-lir", no_argument, &dump_lir, 1 },
270 { "link", no_argument, &do_link, 1 },
Ian Romanick3646d652013-09-09 14:07:15 -0500271 { "version", required_argument, NULL, 'v' },
Ian Romanick7babbdb2010-06-15 12:47:07 -0700272 { NULL, 0, NULL, 0 }
273};
274
Chad Versace78194352010-11-17 15:28:36 -0800275/**
276 * \brief Print proper usage and exit with failure.
277 */
278void
279usage_fail(const char *name)
280{
281
282 const char *header =
283 "usage: %s [options] <file.vert | file.geom | file.frag>\n"
284 "\n"
285 "Possible options are:\n";
286 printf(header, name, name);
287 for (const struct option *o = compiler_opts; o->name != 0; ++o) {
288 printf(" --%s\n", o->name);
289 }
290 exit(EXIT_FAILURE);
291}
292
293
Ian Romanick8ce55db2010-06-17 12:01:18 -0700294void
Kristian Høgsbergf9995b32010-10-12 12:26:10 -0400295compile_shader(struct gl_context *ctx, struct gl_shader *shader)
Ian Romanick61d4aa02010-06-14 14:46:09 -0700296{
Kenneth Graunkeaa9f86a2010-07-22 16:20:36 -0700297 struct _mesa_glsl_parse_state *state =
Paul Berry91100782014-01-07 09:46:10 -0800298 new(shader) _mesa_glsl_parse_state(ctx, shader->Stage, shader);
Eric Anholtf8946692010-07-20 14:03:35 -0700299
Eric Anholt0343f202013-06-12 15:49:43 -0700300 _mesa_glsl_compile_shader(ctx, shader, dump_ast, dump_hir);
Eric Anholt53cdb7e2010-06-22 12:07:21 -0700301
Ian Romanick61d4aa02010-06-14 14:46:09 -0700302 /* Print out the resulting IR */
Carl Worth2d2561e2010-06-23 15:43:38 -0700303 if (!state->error && dump_lir) {
Eric Anholt1e3bd9f2014-02-20 18:00:23 -0800304 _mesa_print_ir(stdout, shader->ir, state);
Ian Romanick61d4aa02010-06-14 14:46:09 -0700305 }
306
Ian Romanick8ce55db2010-06-17 12:01:18 -0700307 return;
308}
Ian Romanick61d4aa02010-06-14 14:46:09 -0700309
Ian Romanick8ce55db2010-06-17 12:01:18 -0700310int
311main(int argc, char **argv)
312{
Ian Romanick6fd9fb22010-06-17 12:22:16 -0700313 int status = EXIT_SUCCESS;
Kristian Høgsbergf9995b32010-10-12 12:26:10 -0400314 struct gl_context local_ctx;
315 struct gl_context *ctx = &local_ctx;
Ian Romanick3646d652013-09-09 14:07:15 -0500316 bool glsl_es = false;
Eric Anholt5d0f4302010-08-18 12:02:35 -0700317
Ian Romanick8ce55db2010-06-17 12:01:18 -0700318 int c;
319 int idx = 0;
Ian Romanick3646d652013-09-09 14:07:15 -0500320 while ((c = getopt_long(argc, argv, "", compiler_opts, &idx)) != -1) {
321 switch (c) {
322 case 'v':
323 glsl_version = strtol(optarg, NULL, 10);
324 switch (glsl_version) {
325 case 100:
326 case 300:
327 glsl_es = true;
328 break;
329 case 110:
330 case 120:
331 case 130:
332 case 140:
333 case 150:
334 case 330:
335 glsl_es = false;
336 break;
337 default:
338 fprintf(stderr, "Unrecognized GLSL version `%s'\n", optarg);
339 usage_fail(argv[0]);
340 break;
341 }
342 break;
343 default:
344 break;
345 }
346 }
Ian Romanick8ce55db2010-06-17 12:01:18 -0700347
348
349 if (argc <= optind)
350 usage_fail(argv[0]);
351
Paul Berrydbd61352012-11-27 12:26:51 -0800352 initialize_context(ctx, (glsl_es) ? API_OPENGLES2 : API_OPENGL_COMPAT);
Chia-I Wudc754582010-09-08 18:48:12 +0800353
Eric Anholt849e1812010-06-30 11:49:17 -0700354 struct gl_shader_program *whole_program;
Carl Worthbe83eb82010-06-23 13:34:05 -0700355
Kenneth Graunked3073f52011-01-21 14:32:31 -0800356 whole_program = rzalloc (NULL, struct gl_shader_program);
Carl Worthbe83eb82010-06-23 13:34:05 -0700357 assert(whole_program != NULL);
Ian Romanick89193932011-07-28 15:10:17 -0700358 whole_program->InfoLog = ralloc_strdup(whole_program, "");
Ian Romanick8ce55db2010-06-17 12:01:18 -0700359
Ian Romanick6fd9fb22010-06-17 12:22:16 -0700360 for (/* empty */; argc > optind; optind++) {
Kenneth Graunked3073f52011-01-21 14:32:31 -0800361 whole_program->Shaders =
362 reralloc(whole_program, whole_program->Shaders,
363 struct gl_shader *, whole_program->NumShaders + 1);
Carl Worthbe83eb82010-06-23 13:34:05 -0700364 assert(whole_program->Shaders != NULL);
Ian Romanick8ce55db2010-06-17 12:01:18 -0700365
Kenneth Graunked3073f52011-01-21 14:32:31 -0800366 struct gl_shader *shader = rzalloc(whole_program, gl_shader);
Ian Romanick8ce55db2010-06-17 12:01:18 -0700367
Carl Worthbe83eb82010-06-23 13:34:05 -0700368 whole_program->Shaders[whole_program->NumShaders] = shader;
369 whole_program->NumShaders++;
Ian Romanick8ce55db2010-06-17 12:01:18 -0700370
Ian Romanick6fd9fb22010-06-17 12:22:16 -0700371 const unsigned len = strlen(argv[optind]);
372 if (len < 6)
373 usage_fail(argv[0]);
Ian Romanick8ce55db2010-06-17 12:01:18 -0700374
Ian Romanick6fd9fb22010-06-17 12:22:16 -0700375 const char *const ext = & argv[optind][len - 5];
Kenneth Graunke7e35d972012-04-16 14:40:45 -0700376 if (strncmp(".vert", ext, 5) == 0 || strncmp(".glsl", ext, 5) == 0)
Kenneth Graunke29e60872010-06-17 15:28:34 -0700377 shader->Type = GL_VERTEX_SHADER;
Ian Romanick6fd9fb22010-06-17 12:22:16 -0700378 else if (strncmp(".geom", ext, 5) == 0)
Kenneth Graunke29e60872010-06-17 15:28:34 -0700379 shader->Type = GL_GEOMETRY_SHADER;
Ian Romanick6fd9fb22010-06-17 12:22:16 -0700380 else if (strncmp(".frag", ext, 5) == 0)
Kenneth Graunke29e60872010-06-17 15:28:34 -0700381 shader->Type = GL_FRAGMENT_SHADER;
Paul Berryc15064c2014-01-07 09:00:02 -0800382 else if (strncmp(".comp", ext, 5) == 0)
383 shader->Type = GL_COMPUTE_SHADER;
Ian Romanick6fd9fb22010-06-17 12:22:16 -0700384 else
385 usage_fail(argv[0]);
Paul Berry65511e52014-01-07 10:58:56 -0800386 shader->Stage = _mesa_shader_enum_to_shader_stage(shader->Type);
Ian Romanick6fd9fb22010-06-17 12:22:16 -0700387
Eric Anholt16b68b12010-06-30 11:05:43 -0700388 shader->Source = load_text_file(whole_program, argv[optind]);
Kenneth Graunke2848c4c2010-06-16 12:10:55 -0700389 if (shader->Source == NULL) {
390 printf("File \"%s\" does not exist.\n", argv[optind]);
391 exit(EXIT_FAILURE);
392 }
Ian Romanick6fd9fb22010-06-17 12:22:16 -0700393
Chia-I Wudc754582010-09-08 18:48:12 +0800394 compile_shader(ctx, shader);
Ian Romanick6fd9fb22010-06-17 12:22:16 -0700395
Ian Romanick587cd972013-09-09 14:14:17 -0500396 if (strlen(shader->InfoLog) > 0)
Kenneth Graunkef3eb42d2010-06-19 11:31:01 -0700397 printf("Info log for %s:\n%s\n", argv[optind], shader->InfoLog);
Ian Romanick587cd972013-09-09 14:14:17 -0500398
399 if (!shader->CompileStatus) {
Ian Romanick6fd9fb22010-06-17 12:22:16 -0700400 status = EXIT_FAILURE;
401 break;
402 }
403 }
404
Ian Romanickc648a122010-06-17 19:51:48 -0700405 if ((status == EXIT_SUCCESS) && do_link) {
Eric Anholt5d0f4302010-08-18 12:02:35 -0700406 link_shaders(ctx, whole_program);
Carl Worthbe83eb82010-06-23 13:34:05 -0700407 status = (whole_program->LinkStatus) ? EXIT_SUCCESS : EXIT_FAILURE;
Ian Romanick4d962e62010-07-02 14:43:01 -0700408
409 if (strlen(whole_program->InfoLog) > 0)
410 printf("Info log for linking:\n%s\n", whole_program->InfoLog);
Ian Romanick832dfa52010-06-17 15:04:20 -0700411 }
412
Paul Berry665b8d72014-01-07 10:11:39 -0800413 for (unsigned i = 0; i < MESA_SHADER_STAGES; i++)
Kenneth Graunked3073f52011-01-21 14:32:31 -0800414 ralloc_free(whole_program->_LinkedShaders[i]);
Ian Romanick3fb87872010-07-09 14:09:34 -0700415
Kenneth Graunked3073f52011-01-21 14:32:31 -0800416 ralloc_free(whole_program);
Ian Romanickefc15f82010-06-28 13:17:18 -0700417 _mesa_glsl_release_types();
Kenneth Graunke76d2f732013-09-01 20:48:45 -0700418 _mesa_glsl_release_builtin_functions();
Carl Worthbe83eb82010-06-23 13:34:05 -0700419
Ian Romanick6fd9fb22010-06-17 12:22:16 -0700420 return status;
Ian Romanick61d4aa02010-06-14 14:46:09 -0700421}