161d4aa041f800429127aab3263c50cbc6e69ae50Ian Romanick/* 261d4aa041f800429127aab3263c50cbc6e69ae50Ian Romanick * Copyright © 2008, 2009 Intel Corporation 361d4aa041f800429127aab3263c50cbc6e69ae50Ian Romanick * 461d4aa041f800429127aab3263c50cbc6e69ae50Ian Romanick * Permission is hereby granted, free of charge, to any person obtaining a 561d4aa041f800429127aab3263c50cbc6e69ae50Ian Romanick * copy of this software and associated documentation files (the "Software"), 661d4aa041f800429127aab3263c50cbc6e69ae50Ian Romanick * to deal in the Software without restriction, including without limitation 761d4aa041f800429127aab3263c50cbc6e69ae50Ian Romanick * the rights to use, copy, modify, merge, publish, distribute, sublicense, 861d4aa041f800429127aab3263c50cbc6e69ae50Ian Romanick * and/or sell copies of the Software, and to permit persons to whom the 961d4aa041f800429127aab3263c50cbc6e69ae50Ian Romanick * Software is furnished to do so, subject to the following conditions: 1061d4aa041f800429127aab3263c50cbc6e69ae50Ian Romanick * 1161d4aa041f800429127aab3263c50cbc6e69ae50Ian Romanick * The above copyright notice and this permission notice (including the next 1261d4aa041f800429127aab3263c50cbc6e69ae50Ian Romanick * paragraph) shall be included in all copies or substantial portions of the 1361d4aa041f800429127aab3263c50cbc6e69ae50Ian Romanick * Software. 1461d4aa041f800429127aab3263c50cbc6e69ae50Ian Romanick * 1561d4aa041f800429127aab3263c50cbc6e69ae50Ian Romanick * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 1661d4aa041f800429127aab3263c50cbc6e69ae50Ian Romanick * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 1761d4aa041f800429127aab3263c50cbc6e69ae50Ian Romanick * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 1861d4aa041f800429127aab3263c50cbc6e69ae50Ian Romanick * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 1961d4aa041f800429127aab3263c50cbc6e69ae50Ian Romanick * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 2061d4aa041f800429127aab3263c50cbc6e69ae50Ian Romanick * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 2161d4aa041f800429127aab3263c50cbc6e69ae50Ian Romanick * DEALINGS IN THE SOFTWARE. 2261d4aa041f800429127aab3263c50cbc6e69ae50Ian Romanick */ 237babbdbd82701147e50a5296dd215376b7ec7da8Ian Romanick#include <getopt.h> 2461d4aa041f800429127aab3263c50cbc6e69ae50Ian Romanick 256a6cb03507da75a30224020c9193464ca5b81c5fEric Anholt/** @file main.cpp 266a6cb03507da75a30224020c9193464ca5b81c5fEric Anholt * 276a6cb03507da75a30224020c9193464ca5b81c5fEric Anholt * This file is the main() routine and scaffolding for producing 286a6cb03507da75a30224020c9193464ca5b81c5fEric Anholt * builtin_compiler (which doesn't include builtins itself and is used 296a6cb03507da75a30224020c9193464ca5b81c5fEric Anholt * to generate the profile information for builtin_function.cpp), and 306a6cb03507da75a30224020c9193464ca5b81c5fEric Anholt * for glsl_compiler (which does include builtins and can be used to 316a6cb03507da75a30224020c9193464ca5b81c5fEric Anholt * offline compile GLSL code and examine the resulting GLSL IR. 326a6cb03507da75a30224020c9193464ca5b81c5fEric Anholt */ 336a6cb03507da75a30224020c9193464ca5b81c5fEric Anholt 3461d4aa041f800429127aab3263c50cbc6e69ae50Ian Romanick#include "ast.h" 3561d4aa041f800429127aab3263c50cbc6e69ae50Ian Romanick#include "glsl_parser_extras.h" 3661d4aa041f800429127aab3263c50cbc6e69ae50Ian Romanick#include "ir_optimization.h" 3761d4aa041f800429127aab3263c50cbc6e69ae50Ian Romanick#include "ir_print_visitor.h" 388ce55dbd9207ff4338588dcba155f1a754dc8f19Ian Romanick#include "program.h" 398df2dbf91ddfd0c1590e33015e85470b67e69319Ian Romanick#include "loop_analysis.h" 40f129f618fe8a5397774484f1b7afb42d4be809a0Paul Berry#include "standalone_scaffolding.h" 413fb878722ed53d79eedb9fe68972ef32b79575d4Ian Romanick 42dc754586ca84741b4df5b72fd235c4134816854cChia-I Wustatic void 43f9995b30756140724f41daf963fa06167912be7fKristian Høgsberginitialize_context(struct gl_context *ctx, gl_api api) 44dc754586ca84741b4df5b72fd235c4134816854cChia-I Wu{ 45f129f618fe8a5397774484f1b7afb42d4be809a0Paul Berry initialize_context_to_defaults(ctx, api); 46dc754586ca84741b4df5b72fd235c4134816854cChia-I Wu 47497aab39f0dea48707f9414f318365839132ed75Eric Anholt /* The standalone compiler needs to claim support for almost 48497aab39f0dea48707f9414f318365839132ed75Eric Anholt * everything in order to compile the built-in functions. 49e5e34ab18eeaffa465094f6281dfe293b84376dbIan Romanick */ 50497aab39f0dea48707f9414f318365839132ed75Eric Anholt ctx->Const.GLSLVersion = 140; 51e5e34ab18eeaffa465094f6281dfe293b84376dbIan Romanick 52dc754586ca84741b4df5b72fd235c4134816854cChia-I Wu ctx->Const.MaxClipPlanes = 8; 53f129f618fe8a5397774484f1b7afb42d4be809a0Paul Berry ctx->Const.MaxDrawBuffers = 2; 54dc754586ca84741b4df5b72fd235c4134816854cChia-I Wu 55dc754586ca84741b4df5b72fd235c4134816854cChia-I Wu /* More than the 1.10 minimum to appease parser tests taken from 56dc754586ca84741b4df5b72fd235c4134816854cChia-I Wu * apps that (hopefully) already checked the number of coords. 57dc754586ca84741b4df5b72fd235c4134816854cChia-I Wu */ 58dc754586ca84741b4df5b72fd235c4134816854cChia-I Wu ctx->Const.MaxTextureCoordUnits = 4; 59dc754586ca84741b4df5b72fd235c4134816854cChia-I Wu 60dc754586ca84741b4df5b72fd235c4134816854cChia-I Wu ctx->Driver.NewShader = _mesa_new_shader; 61dc754586ca84741b4df5b72fd235c4134816854cChia-I Wu} 62dc754586ca84741b4df5b72fd235c4134816854cChia-I Wu 63d3073f58c17d8675a2ecdd5dfa83e5520c78e1a8Kenneth Graunke/* Returned string will have 'ctx' as its ralloc owner. */ 6461d4aa041f800429127aab3263c50cbc6e69ae50Ian Romanickstatic char * 6516b68b1952d0da14b9ce8306efa64988ce46b4b7Eric Anholtload_text_file(void *ctx, const char *file_name) 6661d4aa041f800429127aab3263c50cbc6e69ae50Ian Romanick{ 6761d4aa041f800429127aab3263c50cbc6e69ae50Ian Romanick char *text = NULL; 680035d1d902f34a88ec745925284fe3b768fac261José Fonseca size_t size; 690035d1d902f34a88ec745925284fe3b768fac261José Fonseca size_t total_read = 0; 700035d1d902f34a88ec745925284fe3b768fac261José Fonseca FILE *fp = fopen(file_name, "rb"); 7161d4aa041f800429127aab3263c50cbc6e69ae50Ian Romanick 720035d1d902f34a88ec745925284fe3b768fac261José Fonseca if (!fp) { 7361d4aa041f800429127aab3263c50cbc6e69ae50Ian Romanick return NULL; 7461d4aa041f800429127aab3263c50cbc6e69ae50Ian Romanick } 7561d4aa041f800429127aab3263c50cbc6e69ae50Ian Romanick 760035d1d902f34a88ec745925284fe3b768fac261José Fonseca fseek(fp, 0L, SEEK_END); 770035d1d902f34a88ec745925284fe3b768fac261José Fonseca size = ftell(fp); 780035d1d902f34a88ec745925284fe3b768fac261José Fonseca fseek(fp, 0L, SEEK_SET); 790035d1d902f34a88ec745925284fe3b768fac261José Fonseca 80d3073f58c17d8675a2ecdd5dfa83e5520c78e1a8Kenneth Graunke text = (char *) ralloc_size(ctx, size + 1); 810035d1d902f34a88ec745925284fe3b768fac261José Fonseca if (text != NULL) { 820035d1d902f34a88ec745925284fe3b768fac261José Fonseca do { 830035d1d902f34a88ec745925284fe3b768fac261José Fonseca size_t bytes = fread(text + total_read, 840035d1d902f34a88ec745925284fe3b768fac261José Fonseca 1, size - total_read, fp); 850035d1d902f34a88ec745925284fe3b768fac261José Fonseca if (bytes < size - total_read) { 860035d1d902f34a88ec745925284fe3b768fac261José Fonseca free(text); 870035d1d902f34a88ec745925284fe3b768fac261José Fonseca text = NULL; 880035d1d902f34a88ec745925284fe3b768fac261José Fonseca break; 890035d1d902f34a88ec745925284fe3b768fac261José Fonseca } 900035d1d902f34a88ec745925284fe3b768fac261José Fonseca 910035d1d902f34a88ec745925284fe3b768fac261José Fonseca if (bytes == 0) { 920035d1d902f34a88ec745925284fe3b768fac261José Fonseca break; 930035d1d902f34a88ec745925284fe3b768fac261José Fonseca } 940035d1d902f34a88ec745925284fe3b768fac261José Fonseca 950035d1d902f34a88ec745925284fe3b768fac261José Fonseca total_read += bytes; 960035d1d902f34a88ec745925284fe3b768fac261José Fonseca } while (total_read < size); 970035d1d902f34a88ec745925284fe3b768fac261José Fonseca 980035d1d902f34a88ec745925284fe3b768fac261José Fonseca text[total_read] = '\0'; 9961d4aa041f800429127aab3263c50cbc6e69ae50Ian Romanick } 10061d4aa041f800429127aab3263c50cbc6e69ae50Ian Romanick 1010035d1d902f34a88ec745925284fe3b768fac261José Fonseca fclose(fp); 10261d4aa041f800429127aab3263c50cbc6e69ae50Ian Romanick 10361d4aa041f800429127aab3263c50cbc6e69ae50Ian Romanick return text; 10461d4aa041f800429127aab3263c50cbc6e69ae50Ian Romanick} 10561d4aa041f800429127aab3263c50cbc6e69ae50Ian Romanick 1061a5b32ca0198488e7d616c8cd968471166a97ef3Chia-I Wuint glsl_es = 0; 1077babbdbd82701147e50a5296dd215376b7ec7da8Ian Romanickint dump_ast = 0; 10822c23dedad4e7f362ffbd990f1c2d5caf4cae75aIan Romanickint dump_hir = 0; 10981e1747ac5206948893876b7da6fdb27bff26e0fIan Romanickint dump_lir = 0; 110c648a124b20c5e37cf4041062333fc177a65f997Ian Romanickint do_link = 0; 1117babbdbd82701147e50a5296dd215376b7ec7da8Ian Romanick 1127babbdbd82701147e50a5296dd215376b7ec7da8Ian Romanickconst struct option compiler_opts[] = { 1131a5b32ca0198488e7d616c8cd968471166a97ef3Chia-I Wu { "glsl-es", 0, &glsl_es, 1 }, 1147babbdbd82701147e50a5296dd215376b7ec7da8Ian Romanick { "dump-ast", 0, &dump_ast, 1 }, 11522c23dedad4e7f362ffbd990f1c2d5caf4cae75aIan Romanick { "dump-hir", 0, &dump_hir, 1 }, 11681e1747ac5206948893876b7da6fdb27bff26e0fIan Romanick { "dump-lir", 0, &dump_lir, 1 }, 117c648a124b20c5e37cf4041062333fc177a65f997Ian Romanick { "link", 0, &do_link, 1 }, 1187babbdbd82701147e50a5296dd215376b7ec7da8Ian Romanick { NULL, 0, NULL, 0 } 1197babbdbd82701147e50a5296dd215376b7ec7da8Ian Romanick}; 1207babbdbd82701147e50a5296dd215376b7ec7da8Ian Romanick 1217819435f2ef484696560547fbc1325cb97c7174bChad Versace/** 1227819435f2ef484696560547fbc1325cb97c7174bChad Versace * \brief Print proper usage and exit with failure. 1237819435f2ef484696560547fbc1325cb97c7174bChad Versace */ 1247819435f2ef484696560547fbc1325cb97c7174bChad Versacevoid 1257819435f2ef484696560547fbc1325cb97c7174bChad Versaceusage_fail(const char *name) 1267819435f2ef484696560547fbc1325cb97c7174bChad Versace{ 1277819435f2ef484696560547fbc1325cb97c7174bChad Versace 1287819435f2ef484696560547fbc1325cb97c7174bChad Versace const char *header = 1297819435f2ef484696560547fbc1325cb97c7174bChad Versace "usage: %s [options] <file.vert | file.geom | file.frag>\n" 1307819435f2ef484696560547fbc1325cb97c7174bChad Versace "\n" 1317819435f2ef484696560547fbc1325cb97c7174bChad Versace "Possible options are:\n"; 1327819435f2ef484696560547fbc1325cb97c7174bChad Versace printf(header, name, name); 1337819435f2ef484696560547fbc1325cb97c7174bChad Versace for (const struct option *o = compiler_opts; o->name != 0; ++o) { 1347819435f2ef484696560547fbc1325cb97c7174bChad Versace printf(" --%s\n", o->name); 1357819435f2ef484696560547fbc1325cb97c7174bChad Versace } 1367819435f2ef484696560547fbc1325cb97c7174bChad Versace exit(EXIT_FAILURE); 1377819435f2ef484696560547fbc1325cb97c7174bChad Versace} 1387819435f2ef484696560547fbc1325cb97c7174bChad Versace 1397819435f2ef484696560547fbc1325cb97c7174bChad Versace 1408ce55dbd9207ff4338588dcba155f1a754dc8f19Ian Romanickvoid 141f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergcompile_shader(struct gl_context *ctx, struct gl_shader *shader) 14261d4aa041f800429127aab3263c50cbc6e69ae50Ian Romanick{ 143aa9f86ae8b3bb2172092ff9b50751677c509e6b4Kenneth Graunke struct _mesa_glsl_parse_state *state = 144dc754586ca84741b4df5b72fd235c4134816854cChia-I Wu new(shader) _mesa_glsl_parse_state(ctx, shader->Type, shader); 145f8946699ecfa5bc6566821fb855072bbdbd716b2Eric Anholt 14604ba86a536d76ef24c749e16c785c1634b9187c9Kenneth Graunke const char *source = shader->Source; 1477cfd42cefe1949af51ecced9891f415eca2c0e66Dave Airlie state->error = glcpp_preprocess(state, &source, &state->info_log, 148d42acef139740a54fe571f99b62cba7720734d8cBrian Paul state->extensions, ctx->API) != 0; 14904ba86a536d76ef24c749e16c785c1634b9187c9Kenneth Graunke 1502d2561ef9696aa5ff0c1a85e3a4a95475f927935Carl Worth if (!state->error) { 1512d2561ef9696aa5ff0c1a85e3a4a95475f927935Carl Worth _mesa_glsl_lexer_ctor(state, source); 1522d2561ef9696aa5ff0c1a85e3a4a95475f927935Carl Worth _mesa_glsl_parse(state); 1532d2561ef9696aa5ff0c1a85e3a4a95475f927935Carl Worth _mesa_glsl_lexer_dtor(state); 15404ba86a536d76ef24c749e16c785c1634b9187c9Kenneth Graunke } 15554992c30b00b13232641b5d2b6479f005a60abfdIan Romanick 1567babbdbd82701147e50a5296dd215376b7ec7da8Ian Romanick if (dump_ast) { 1572d2561ef9696aa5ff0c1a85e3a4a95475f927935Carl Worth foreach_list_const(n, &state->translation_unit) { 1587babbdbd82701147e50a5296dd215376b7ec7da8Ian Romanick ast_node *ast = exec_node_data(ast_node, n, link); 1597babbdbd82701147e50a5296dd215376b7ec7da8Ian Romanick ast->print(); 1607babbdbd82701147e50a5296dd215376b7ec7da8Ian Romanick } 1617babbdbd82701147e50a5296dd215376b7ec7da8Ian Romanick printf("\n\n"); 16261d4aa041f800429127aab3263c50cbc6e69ae50Ian Romanick } 16361d4aa041f800429127aab3263c50cbc6e69ae50Ian Romanick 16416b68b1952d0da14b9ce8306efa64988ce46b4b7Eric Anholt shader->ir = new(shader) exec_list; 1652d2561ef9696aa5ff0c1a85e3a4a95475f927935Carl Worth if (!state->error && !state->translation_unit.is_empty()) 16616b68b1952d0da14b9ce8306efa64988ce46b4b7Eric Anholt _mesa_ast_to_hir(shader->ir, state); 16754992c30b00b13232641b5d2b6479f005a60abfdIan Romanick 16822c23dedad4e7f362ffbd990f1c2d5caf4cae75aIan Romanick /* Print out the unoptimized IR. */ 16922c23dedad4e7f362ffbd990f1c2d5caf4cae75aIan Romanick if (!state->error && dump_hir) { 1705a2e0b8ce59a3d9f8fa7510546137aff40016c74Ian Romanick validate_ir_tree(shader->ir); 17116b68b1952d0da14b9ce8306efa64988ce46b4b7Eric Anholt _mesa_print_ir(shader->ir, state); 17222c23dedad4e7f362ffbd990f1c2d5caf4cae75aIan Romanick } 17322c23dedad4e7f362ffbd990f1c2d5caf4cae75aIan Romanick 17461d4aa041f800429127aab3263c50cbc6e69ae50Ian Romanick /* Optimization passes */ 17516b68b1952d0da14b9ce8306efa64988ce46b4b7Eric Anholt if (!state->error && !shader->ir->is_empty()) { 17661d4aa041f800429127aab3263c50cbc6e69ae50Ian Romanick bool progress; 17761d4aa041f800429127aab3263c50cbc6e69ae50Ian Romanick do { 1781d5d67f8adac9f94715de9804adb536d9a7ec5eeIan Romanick progress = do_common_optimization(shader->ir, false, false, 32); 17961d4aa041f800429127aab3263c50cbc6e69ae50Ian Romanick } while (progress); 1805a2e0b8ce59a3d9f8fa7510546137aff40016c74Ian Romanick 1815a2e0b8ce59a3d9f8fa7510546137aff40016c74Ian Romanick validate_ir_tree(shader->ir); 18261d4aa041f800429127aab3263c50cbc6e69ae50Ian Romanick } 18361d4aa041f800429127aab3263c50cbc6e69ae50Ian Romanick 18453cdb7e51d85d4b4a35fba3ec200b27991b8488bEric Anholt 18561d4aa041f800429127aab3263c50cbc6e69ae50Ian Romanick /* Print out the resulting IR */ 1862d2561ef9696aa5ff0c1a85e3a4a95475f927935Carl Worth if (!state->error && dump_lir) { 18716b68b1952d0da14b9ce8306efa64988ce46b4b7Eric Anholt _mesa_print_ir(shader->ir, state); 18861d4aa041f800429127aab3263c50cbc6e69ae50Ian Romanick } 18961d4aa041f800429127aab3263c50cbc6e69ae50Ian Romanick 1902d2561ef9696aa5ff0c1a85e3a4a95475f927935Carl Worth shader->symbols = state->symbols; 1912d2561ef9696aa5ff0c1a85e3a4a95475f927935Carl Worth shader->CompileStatus = !state->error; 19225f51d3b9b8c36c41cd23d2797b6a06f6e27ff86Ian Romanick shader->Version = state->language_version; 193d5be2acae379783c4aa31243e0a88a9e67e6ca7eIan Romanick memcpy(shader->builtins_to_link, state->builtins_to_link, 194d5be2acae379783c4aa31243e0a88a9e67e6ca7eIan Romanick sizeof(shader->builtins_to_link[0]) * state->num_builtins_to_link); 195d5be2acae379783c4aa31243e0a88a9e67e6ca7eIan Romanick shader->num_builtins_to_link = state->num_builtins_to_link; 196ca97bd395f476ad2b5a009f92edef4656aab3650Ian Romanick 197ca97bd395f476ad2b5a009f92edef4656aab3650Ian Romanick if (shader->InfoLog) 198d3073f58c17d8675a2ecdd5dfa83e5520c78e1a8Kenneth Graunke ralloc_free(shader->InfoLog); 199ca97bd395f476ad2b5a009f92edef4656aab3650Ian Romanick 2002d2561ef9696aa5ff0c1a85e3a4a95475f927935Carl Worth shader->InfoLog = state->info_log; 2012d2561ef9696aa5ff0c1a85e3a4a95475f927935Carl Worth 202116f1d4f95d8eb0a82b272016590549632c865b3Kenneth Graunke /* Retain any live IR, but trash the rest. */ 20360e2d06d1ccc66ad00cd7ab81c418853f21be291Ian Romanick reparent_ir(shader->ir, shader); 204116f1d4f95d8eb0a82b272016590549632c865b3Kenneth Graunke 205d3073f58c17d8675a2ecdd5dfa83e5520c78e1a8Kenneth Graunke ralloc_free(state); 206ca97bd395f476ad2b5a009f92edef4656aab3650Ian Romanick 2078ce55dbd9207ff4338588dcba155f1a754dc8f19Ian Romanick return; 2088ce55dbd9207ff4338588dcba155f1a754dc8f19Ian Romanick} 2098ce55dbd9207ff4338588dcba155f1a754dc8f19Ian Romanick 2108ce55dbd9207ff4338588dcba155f1a754dc8f19Ian Romanickint 2118ce55dbd9207ff4338588dcba155f1a754dc8f19Ian Romanickmain(int argc, char **argv) 2128ce55dbd9207ff4338588dcba155f1a754dc8f19Ian Romanick{ 2136fd9fb23de908ec52089fdc6e24af9e2ebbe126eIan Romanick int status = EXIT_SUCCESS; 214f9995b30756140724f41daf963fa06167912be7fKristian Høgsberg struct gl_context local_ctx; 215f9995b30756140724f41daf963fa06167912be7fKristian Høgsberg struct gl_context *ctx = &local_ctx; 2165d0f430e8ed01db29d11d22e4b6c3760d8c39f8fEric Anholt 2178ce55dbd9207ff4338588dcba155f1a754dc8f19Ian Romanick int c; 2188ce55dbd9207ff4338588dcba155f1a754dc8f19Ian Romanick int idx = 0; 2198ce55dbd9207ff4338588dcba155f1a754dc8f19Ian Romanick while ((c = getopt_long(argc, argv, "", compiler_opts, &idx)) != -1) 2208ce55dbd9207ff4338588dcba155f1a754dc8f19Ian Romanick /* empty */ ; 2218ce55dbd9207ff4338588dcba155f1a754dc8f19Ian Romanick 2228ce55dbd9207ff4338588dcba155f1a754dc8f19Ian Romanick 2238ce55dbd9207ff4338588dcba155f1a754dc8f19Ian Romanick if (argc <= optind) 2248ce55dbd9207ff4338588dcba155f1a754dc8f19Ian Romanick usage_fail(argv[0]); 2258ce55dbd9207ff4338588dcba155f1a754dc8f19Ian Romanick 2261a5b32ca0198488e7d616c8cd968471166a97ef3Chia-I Wu initialize_context(ctx, (glsl_es) ? API_OPENGLES2 : API_OPENGL); 227dc754586ca84741b4df5b72fd235c4134816854cChia-I Wu 228849e18153cd91d812f694b806a84008498860bc3Eric Anholt struct gl_shader_program *whole_program; 229be83eb8671e7789cbe5ca1fc8d3f5d133e2e7014Carl Worth 230d3073f58c17d8675a2ecdd5dfa83e5520c78e1a8Kenneth Graunke whole_program = rzalloc (NULL, struct gl_shader_program); 231be83eb8671e7789cbe5ca1fc8d3f5d133e2e7014Carl Worth assert(whole_program != NULL); 23289193933cbd322cd08fb54232411a8a9221fcca8Ian Romanick whole_program->InfoLog = ralloc_strdup(whole_program, ""); 2338ce55dbd9207ff4338588dcba155f1a754dc8f19Ian Romanick 2346fd9fb23de908ec52089fdc6e24af9e2ebbe126eIan Romanick for (/* empty */; argc > optind; optind++) { 235d3073f58c17d8675a2ecdd5dfa83e5520c78e1a8Kenneth Graunke whole_program->Shaders = 236d3073f58c17d8675a2ecdd5dfa83e5520c78e1a8Kenneth Graunke reralloc(whole_program, whole_program->Shaders, 237d3073f58c17d8675a2ecdd5dfa83e5520c78e1a8Kenneth Graunke struct gl_shader *, whole_program->NumShaders + 1); 238be83eb8671e7789cbe5ca1fc8d3f5d133e2e7014Carl Worth assert(whole_program->Shaders != NULL); 2398ce55dbd9207ff4338588dcba155f1a754dc8f19Ian Romanick 240d3073f58c17d8675a2ecdd5dfa83e5520c78e1a8Kenneth Graunke struct gl_shader *shader = rzalloc(whole_program, gl_shader); 2416fd9fb23de908ec52089fdc6e24af9e2ebbe126eIan Romanick 242be83eb8671e7789cbe5ca1fc8d3f5d133e2e7014Carl Worth whole_program->Shaders[whole_program->NumShaders] = shader; 243be83eb8671e7789cbe5ca1fc8d3f5d133e2e7014Carl Worth whole_program->NumShaders++; 2446fd9fb23de908ec52089fdc6e24af9e2ebbe126eIan Romanick 2456fd9fb23de908ec52089fdc6e24af9e2ebbe126eIan Romanick const unsigned len = strlen(argv[optind]); 2466fd9fb23de908ec52089fdc6e24af9e2ebbe126eIan Romanick if (len < 6) 2476fd9fb23de908ec52089fdc6e24af9e2ebbe126eIan Romanick usage_fail(argv[0]); 2488ce55dbd9207ff4338588dcba155f1a754dc8f19Ian Romanick 2496fd9fb23de908ec52089fdc6e24af9e2ebbe126eIan Romanick const char *const ext = & argv[optind][len - 5]; 2507e35d97a02cf139746ce9e85b78fe0c651139074Kenneth Graunke if (strncmp(".vert", ext, 5) == 0 || strncmp(".glsl", ext, 5) == 0) 25129e60874812ae323780cfab67b8b1365059ff4b2Kenneth Graunke shader->Type = GL_VERTEX_SHADER; 2526fd9fb23de908ec52089fdc6e24af9e2ebbe126eIan Romanick else if (strncmp(".geom", ext, 5) == 0) 25329e60874812ae323780cfab67b8b1365059ff4b2Kenneth Graunke shader->Type = GL_GEOMETRY_SHADER; 2546fd9fb23de908ec52089fdc6e24af9e2ebbe126eIan Romanick else if (strncmp(".frag", ext, 5) == 0) 25529e60874812ae323780cfab67b8b1365059ff4b2Kenneth Graunke shader->Type = GL_FRAGMENT_SHADER; 2566fd9fb23de908ec52089fdc6e24af9e2ebbe126eIan Romanick else 2576fd9fb23de908ec52089fdc6e24af9e2ebbe126eIan Romanick usage_fail(argv[0]); 2588ce55dbd9207ff4338588dcba155f1a754dc8f19Ian Romanick 25916b68b1952d0da14b9ce8306efa64988ce46b4b7Eric Anholt shader->Source = load_text_file(whole_program, argv[optind]); 2602848c4c183ea0aaca2ca0a23a13196c786403a5cKenneth Graunke if (shader->Source == NULL) { 2612848c4c183ea0aaca2ca0a23a13196c786403a5cKenneth Graunke printf("File \"%s\" does not exist.\n", argv[optind]); 2622848c4c183ea0aaca2ca0a23a13196c786403a5cKenneth Graunke exit(EXIT_FAILURE); 2632848c4c183ea0aaca2ca0a23a13196c786403a5cKenneth Graunke } 2646fd9fb23de908ec52089fdc6e24af9e2ebbe126eIan Romanick 265dc754586ca84741b4df5b72fd235c4134816854cChia-I Wu compile_shader(ctx, shader); 2666fd9fb23de908ec52089fdc6e24af9e2ebbe126eIan Romanick 26729e60874812ae323780cfab67b8b1365059ff4b2Kenneth Graunke if (!shader->CompileStatus) { 268f3eb42d200bb78afae64af6862e2b12396226707Kenneth Graunke printf("Info log for %s:\n%s\n", argv[optind], shader->InfoLog); 2696fd9fb23de908ec52089fdc6e24af9e2ebbe126eIan Romanick status = EXIT_FAILURE; 2706fd9fb23de908ec52089fdc6e24af9e2ebbe126eIan Romanick break; 2716fd9fb23de908ec52089fdc6e24af9e2ebbe126eIan Romanick } 2726fd9fb23de908ec52089fdc6e24af9e2ebbe126eIan Romanick } 27361d4aa041f800429127aab3263c50cbc6e69ae50Ian Romanick 274c648a124b20c5e37cf4041062333fc177a65f997Ian Romanick if ((status == EXIT_SUCCESS) && do_link) { 2755d0f430e8ed01db29d11d22e4b6c3760d8c39f8fEric Anholt link_shaders(ctx, whole_program); 276be83eb8671e7789cbe5ca1fc8d3f5d133e2e7014Carl Worth status = (whole_program->LinkStatus) ? EXIT_SUCCESS : EXIT_FAILURE; 2774d962e66e319191d5b94291b6f55d720df71130aIan Romanick 2784d962e66e319191d5b94291b6f55d720df71130aIan Romanick if (strlen(whole_program->InfoLog) > 0) 2794d962e66e319191d5b94291b6f55d720df71130aIan Romanick printf("Info log for linking:\n%s\n", whole_program->InfoLog); 280832dfa58b2070d60111bc1997aea86228f630e75Ian Romanick } 281832dfa58b2070d60111bc1997aea86228f630e75Ian Romanick 2823322fbaf3b5e305ce00c1d08c26965bb98e0cef0Ian Romanick for (unsigned i = 0; i < MESA_SHADER_TYPES; i++) 283d3073f58c17d8675a2ecdd5dfa83e5520c78e1a8Kenneth Graunke ralloc_free(whole_program->_LinkedShaders[i]); 2843fb878722ed53d79eedb9fe68972ef32b79575d4Ian Romanick 285d3073f58c17d8675a2ecdd5dfa83e5520c78e1a8Kenneth Graunke ralloc_free(whole_program); 286efc15f862b08a9f035c06a79bc43848cca740372Ian Romanick _mesa_glsl_release_types(); 287d5be2acae379783c4aa31243e0a88a9e67e6ca7eIan Romanick _mesa_glsl_release_functions(); 288be83eb8671e7789cbe5ca1fc8d3f5d133e2e7014Carl Worth 2896fd9fb23de908ec52089fdc6e24af9e2ebbe126eIan Romanick return status; 29061d4aa041f800429127aab3263c50cbc6e69ae50Ian Romanick} 291