10f982bb67d64673f73096f7c536a5e29756c5c6fRob Clark/*
20f982bb67d64673f73096f7c536a5e29756c5c6fRob Clark * Copyright © 2008, 2009 Intel Corporation
30f982bb67d64673f73096f7c536a5e29756c5c6fRob Clark *
40f982bb67d64673f73096f7c536a5e29756c5c6fRob Clark * Permission is hereby granted, free of charge, to any person obtaining a
50f982bb67d64673f73096f7c536a5e29756c5c6fRob Clark * copy of this software and associated documentation files (the "Software"),
60f982bb67d64673f73096f7c536a5e29756c5c6fRob Clark * to deal in the Software without restriction, including without limitation
70f982bb67d64673f73096f7c536a5e29756c5c6fRob Clark * the rights to use, copy, modify, merge, publish, distribute, sublicense,
80f982bb67d64673f73096f7c536a5e29756c5c6fRob Clark * and/or sell copies of the Software, and to permit persons to whom the
90f982bb67d64673f73096f7c536a5e29756c5c6fRob Clark * Software is furnished to do so, subject to the following conditions:
100f982bb67d64673f73096f7c536a5e29756c5c6fRob Clark *
110f982bb67d64673f73096f7c536a5e29756c5c6fRob Clark * The above copyright notice and this permission notice (including the next
120f982bb67d64673f73096f7c536a5e29756c5c6fRob Clark * paragraph) shall be included in all copies or substantial portions of the
130f982bb67d64673f73096f7c536a5e29756c5c6fRob Clark * Software.
140f982bb67d64673f73096f7c536a5e29756c5c6fRob Clark *
150f982bb67d64673f73096f7c536a5e29756c5c6fRob Clark * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
160f982bb67d64673f73096f7c536a5e29756c5c6fRob Clark * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
170f982bb67d64673f73096f7c536a5e29756c5c6fRob Clark * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
180f982bb67d64673f73096f7c536a5e29756c5c6fRob Clark * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
190f982bb67d64673f73096f7c536a5e29756c5c6fRob Clark * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
200f982bb67d64673f73096f7c536a5e29756c5c6fRob Clark * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
210f982bb67d64673f73096f7c536a5e29756c5c6fRob Clark * DEALINGS IN THE SOFTWARE.
220f982bb67d64673f73096f7c536a5e29756c5c6fRob Clark */
230f982bb67d64673f73096f7c536a5e29756c5c6fRob Clark#include <getopt.h>
240f982bb67d64673f73096f7c536a5e29756c5c6fRob Clark
250f982bb67d64673f73096f7c536a5e29756c5c6fRob Clark/** @file standalone.cpp
260f982bb67d64673f73096f7c536a5e29756c5c6fRob Clark *
270f982bb67d64673f73096f7c536a5e29756c5c6fRob Clark * Standalone compiler helper lib.  Used by standalone glsl_compiler and
280f982bb67d64673f73096f7c536a5e29756c5c6fRob Clark * also available to drivers to implement their own standalone compiler
290f982bb67d64673f73096f7c536a5e29756c5c6fRob Clark * with driver backend.
300f982bb67d64673f73096f7c536a5e29756c5c6fRob Clark */
310f982bb67d64673f73096f7c536a5e29756c5c6fRob Clark
320f982bb67d64673f73096f7c536a5e29756c5c6fRob Clark#include "ast.h"
330f982bb67d64673f73096f7c536a5e29756c5c6fRob Clark#include "glsl_parser_extras.h"
340f982bb67d64673f73096f7c536a5e29756c5c6fRob Clark#include "ir_optimization.h"
350f982bb67d64673f73096f7c536a5e29756c5c6fRob Clark#include "program.h"
360f982bb67d64673f73096f7c536a5e29756c5c6fRob Clark#include "loop_analysis.h"
370f982bb67d64673f73096f7c536a5e29756c5c6fRob Clark#include "standalone_scaffolding.h"
380f982bb67d64673f73096f7c536a5e29756c5c6fRob Clark#include "standalone.h"
3908c5b10ae904231d887f9b6c37694c0e03939a28Thomas Helland#include "util/string_to_uint_map.h"
404dc759c8c236e725ff7bbd439e19eada12bf390fIan Romanick#include "util/set.h"
41d0028b2e1c43392bb476416a1af2097ab17afe7cIan Romanick#include "linker.h"
42d0028b2e1c43392bb476416a1af2097ab17afe7cIan Romanick#include "glsl_parser_extras.h"
43e9acae8486fff4f9fe6aa111c6fa5652ebb9f8bfIan Romanick#include "ir_builder_print_visitor.h"
44f45a2a93aea0a57cf0aa8ee9ca062fcc42407a44Ian Romanick#include "opt_add_neg_to_sub.h"
450f982bb67d64673f73096f7c536a5e29756c5c6fRob Clark
464dc759c8c236e725ff7bbd439e19eada12bf390fIan Romanickclass dead_variable_visitor : public ir_hierarchical_visitor {
474dc759c8c236e725ff7bbd439e19eada12bf390fIan Romanickpublic:
484dc759c8c236e725ff7bbd439e19eada12bf390fIan Romanick   dead_variable_visitor()
494dc759c8c236e725ff7bbd439e19eada12bf390fIan Romanick   {
504dc759c8c236e725ff7bbd439e19eada12bf390fIan Romanick      variables = _mesa_set_create(NULL,
514dc759c8c236e725ff7bbd439e19eada12bf390fIan Romanick                                   _mesa_hash_pointer,
524dc759c8c236e725ff7bbd439e19eada12bf390fIan Romanick                                   _mesa_key_pointer_equal);
534dc759c8c236e725ff7bbd439e19eada12bf390fIan Romanick   }
544dc759c8c236e725ff7bbd439e19eada12bf390fIan Romanick
554dc759c8c236e725ff7bbd439e19eada12bf390fIan Romanick   virtual ~dead_variable_visitor()
564dc759c8c236e725ff7bbd439e19eada12bf390fIan Romanick   {
574dc759c8c236e725ff7bbd439e19eada12bf390fIan Romanick      _mesa_set_destroy(variables, NULL);
584dc759c8c236e725ff7bbd439e19eada12bf390fIan Romanick   }
594dc759c8c236e725ff7bbd439e19eada12bf390fIan Romanick
604dc759c8c236e725ff7bbd439e19eada12bf390fIan Romanick   virtual ir_visitor_status visit(ir_variable *ir)
614dc759c8c236e725ff7bbd439e19eada12bf390fIan Romanick   {
624dc759c8c236e725ff7bbd439e19eada12bf390fIan Romanick      /* If the variable is auto or temp, add it to the set of variables that
634dc759c8c236e725ff7bbd439e19eada12bf390fIan Romanick       * are candidates for removal.
644dc759c8c236e725ff7bbd439e19eada12bf390fIan Romanick       */
654dc759c8c236e725ff7bbd439e19eada12bf390fIan Romanick      if (ir->data.mode != ir_var_auto && ir->data.mode != ir_var_temporary)
664dc759c8c236e725ff7bbd439e19eada12bf390fIan Romanick         return visit_continue;
674dc759c8c236e725ff7bbd439e19eada12bf390fIan Romanick
684dc759c8c236e725ff7bbd439e19eada12bf390fIan Romanick      _mesa_set_add(variables, ir);
694dc759c8c236e725ff7bbd439e19eada12bf390fIan Romanick
704dc759c8c236e725ff7bbd439e19eada12bf390fIan Romanick      return visit_continue;
714dc759c8c236e725ff7bbd439e19eada12bf390fIan Romanick   }
724dc759c8c236e725ff7bbd439e19eada12bf390fIan Romanick
734dc759c8c236e725ff7bbd439e19eada12bf390fIan Romanick   virtual ir_visitor_status visit(ir_dereference_variable *ir)
744dc759c8c236e725ff7bbd439e19eada12bf390fIan Romanick   {
754dc759c8c236e725ff7bbd439e19eada12bf390fIan Romanick      struct set_entry *entry = _mesa_set_search(variables, ir->var);
764dc759c8c236e725ff7bbd439e19eada12bf390fIan Romanick
774dc759c8c236e725ff7bbd439e19eada12bf390fIan Romanick      /* If a variable is dereferenced at all, remove it from the set of
784dc759c8c236e725ff7bbd439e19eada12bf390fIan Romanick       * variables that are candidates for removal.
794dc759c8c236e725ff7bbd439e19eada12bf390fIan Romanick       */
804dc759c8c236e725ff7bbd439e19eada12bf390fIan Romanick      if (entry != NULL)
814dc759c8c236e725ff7bbd439e19eada12bf390fIan Romanick         _mesa_set_remove(variables, entry);
824dc759c8c236e725ff7bbd439e19eada12bf390fIan Romanick
834dc759c8c236e725ff7bbd439e19eada12bf390fIan Romanick      return visit_continue;
844dc759c8c236e725ff7bbd439e19eada12bf390fIan Romanick   }
854dc759c8c236e725ff7bbd439e19eada12bf390fIan Romanick
864dc759c8c236e725ff7bbd439e19eada12bf390fIan Romanick   void remove_dead_variables()
874dc759c8c236e725ff7bbd439e19eada12bf390fIan Romanick   {
884dc759c8c236e725ff7bbd439e19eada12bf390fIan Romanick      struct set_entry *entry;
894dc759c8c236e725ff7bbd439e19eada12bf390fIan Romanick
904dc759c8c236e725ff7bbd439e19eada12bf390fIan Romanick      set_foreach(variables, entry) {
914dc759c8c236e725ff7bbd439e19eada12bf390fIan Romanick         ir_variable *ir = (ir_variable *) entry->key;
924dc759c8c236e725ff7bbd439e19eada12bf390fIan Romanick
934dc759c8c236e725ff7bbd439e19eada12bf390fIan Romanick         assert(ir->ir_type == ir_type_variable);
944dc759c8c236e725ff7bbd439e19eada12bf390fIan Romanick         ir->remove();
954dc759c8c236e725ff7bbd439e19eada12bf390fIan Romanick      }
964dc759c8c236e725ff7bbd439e19eada12bf390fIan Romanick   }
974dc759c8c236e725ff7bbd439e19eada12bf390fIan Romanick
984dc759c8c236e725ff7bbd439e19eada12bf390fIan Romanickprivate:
994dc759c8c236e725ff7bbd439e19eada12bf390fIan Romanick   set *variables;
1004dc759c8c236e725ff7bbd439e19eada12bf390fIan Romanick};
1014dc759c8c236e725ff7bbd439e19eada12bf390fIan Romanick
1020c85d2fea406df033c27201ba5e7257874a67a9aTimothy Arcerivoid
103f584f3821426955b94f36c77191edcfe1b1cc7d5Timothy Arceriinit_gl_program(struct gl_program *prog, GLenum target, bool is_arb_asm)
1040c85d2fea406df033c27201ba5e7257874a67a9aTimothy Arceri{
1050c85d2fea406df033c27201ba5e7257874a67a9aTimothy Arceri   mtx_init(&prog->Mutex, mtx_plain);
1060c85d2fea406df033c27201ba5e7257874a67a9aTimothy Arceri
1070c85d2fea406df033c27201ba5e7257874a67a9aTimothy Arceri   prog->RefCount = 1;
1080c85d2fea406df033c27201ba5e7257874a67a9aTimothy Arceri   prog->Format = GL_PROGRAM_FORMAT_ASCII_ARB;
109f584f3821426955b94f36c77191edcfe1b1cc7d5Timothy Arceri   prog->is_arb_asm = is_arb_asm;
1100c85d2fea406df033c27201ba5e7257874a67a9aTimothy Arceri}
1110c85d2fea406df033c27201ba5e7257874a67a9aTimothy Arceri
1120c85d2fea406df033c27201ba5e7257874a67a9aTimothy Arceristruct gl_program *
113f584f3821426955b94f36c77191edcfe1b1cc7d5Timothy Arcerinew_program(struct gl_context *ctx, GLenum target, GLuint id, bool is_arb_asm)
1140c85d2fea406df033c27201ba5e7257874a67a9aTimothy Arceri{
1150c85d2fea406df033c27201ba5e7257874a67a9aTimothy Arceri   switch (target) {
1160c85d2fea406df033c27201ba5e7257874a67a9aTimothy Arceri   case GL_VERTEX_PROGRAM_ARB: /* == GL_VERTEX_PROGRAM_NV */
1170c85d2fea406df033c27201ba5e7257874a67a9aTimothy Arceri   case GL_GEOMETRY_PROGRAM_NV:
1180c85d2fea406df033c27201ba5e7257874a67a9aTimothy Arceri   case GL_TESS_CONTROL_PROGRAM_NV:
1190c85d2fea406df033c27201ba5e7257874a67a9aTimothy Arceri   case GL_TESS_EVALUATION_PROGRAM_NV:
1200c85d2fea406df033c27201ba5e7257874a67a9aTimothy Arceri   case GL_FRAGMENT_PROGRAM_ARB:
1210c85d2fea406df033c27201ba5e7257874a67a9aTimothy Arceri   case GL_COMPUTE_PROGRAM_NV: {
1220c85d2fea406df033c27201ba5e7257874a67a9aTimothy Arceri      struct gl_program *prog = rzalloc(NULL, struct gl_program);
123f584f3821426955b94f36c77191edcfe1b1cc7d5Timothy Arceri      init_gl_program(prog, target, is_arb_asm);
1240c85d2fea406df033c27201ba5e7257874a67a9aTimothy Arceri      return prog;
1250c85d2fea406df033c27201ba5e7257874a67a9aTimothy Arceri   }
1260c85d2fea406df033c27201ba5e7257874a67a9aTimothy Arceri   default:
1270c85d2fea406df033c27201ba5e7257874a67a9aTimothy Arceri      printf("bad target in new_program\n");
1280c85d2fea406df033c27201ba5e7257874a67a9aTimothy Arceri      return NULL;
1290c85d2fea406df033c27201ba5e7257874a67a9aTimothy Arceri   }
1300c85d2fea406df033c27201ba5e7257874a67a9aTimothy Arceri}
1310c85d2fea406df033c27201ba5e7257874a67a9aTimothy Arceri
1320f982bb67d64673f73096f7c536a5e29756c5c6fRob Clarkstatic const struct standalone_options *options;
1330f982bb67d64673f73096f7c536a5e29756c5c6fRob Clark
1340f982bb67d64673f73096f7c536a5e29756c5c6fRob Clarkstatic void
1350f982bb67d64673f73096f7c536a5e29756c5c6fRob Clarkinitialize_context(struct gl_context *ctx, gl_api api)
1360f982bb67d64673f73096f7c536a5e29756c5c6fRob Clark{
1370f982bb67d64673f73096f7c536a5e29756c5c6fRob Clark   initialize_context_to_defaults(ctx, api);
1380f982bb67d64673f73096f7c536a5e29756c5c6fRob Clark
1390f982bb67d64673f73096f7c536a5e29756c5c6fRob Clark   /* The standalone compiler needs to claim support for almost
1400f982bb67d64673f73096f7c536a5e29756c5c6fRob Clark    * everything in order to compile the built-in functions.
1410f982bb67d64673f73096f7c536a5e29756c5c6fRob Clark    */
1420f982bb67d64673f73096f7c536a5e29756c5c6fRob Clark   ctx->Const.GLSLVersion = options->glsl_version;
1430f982bb67d64673f73096f7c536a5e29756c5c6fRob Clark   ctx->Extensions.ARB_ES3_compatibility = true;
1440f982bb67d64673f73096f7c536a5e29756c5c6fRob Clark   ctx->Const.MaxComputeWorkGroupCount[0] = 65535;
1450f982bb67d64673f73096f7c536a5e29756c5c6fRob Clark   ctx->Const.MaxComputeWorkGroupCount[1] = 65535;
1460f982bb67d64673f73096f7c536a5e29756c5c6fRob Clark   ctx->Const.MaxComputeWorkGroupCount[2] = 65535;
1470f982bb67d64673f73096f7c536a5e29756c5c6fRob Clark   ctx->Const.MaxComputeWorkGroupSize[0] = 1024;
1480f982bb67d64673f73096f7c536a5e29756c5c6fRob Clark   ctx->Const.MaxComputeWorkGroupSize[1] = 1024;
1490f982bb67d64673f73096f7c536a5e29756c5c6fRob Clark   ctx->Const.MaxComputeWorkGroupSize[2] = 64;
1500f982bb67d64673f73096f7c536a5e29756c5c6fRob Clark   ctx->Const.MaxComputeWorkGroupInvocations = 1024;
1510f982bb67d64673f73096f7c536a5e29756c5c6fRob Clark   ctx->Const.MaxComputeSharedMemorySize = 32768;
152d5c8481d577030f21524ab6e0501d75ba401c887Samuel Pitoiset   ctx->Const.MaxComputeVariableGroupSize[0] = 512;
153d5c8481d577030f21524ab6e0501d75ba401c887Samuel Pitoiset   ctx->Const.MaxComputeVariableGroupSize[1] = 512;
154d5c8481d577030f21524ab6e0501d75ba401c887Samuel Pitoiset   ctx->Const.MaxComputeVariableGroupSize[2] = 64;
155d5c8481d577030f21524ab6e0501d75ba401c887Samuel Pitoiset   ctx->Const.MaxComputeVariableGroupInvocations = 512;
1560f982bb67d64673f73096f7c536a5e29756c5c6fRob Clark   ctx->Const.Program[MESA_SHADER_COMPUTE].MaxTextureImageUnits = 16;
1570f982bb67d64673f73096f7c536a5e29756c5c6fRob Clark   ctx->Const.Program[MESA_SHADER_COMPUTE].MaxUniformComponents = 1024;
1580f982bb67d64673f73096f7c536a5e29756c5c6fRob Clark   ctx->Const.Program[MESA_SHADER_COMPUTE].MaxCombinedUniformComponents = 1024;
1590f982bb67d64673f73096f7c536a5e29756c5c6fRob Clark   ctx->Const.Program[MESA_SHADER_COMPUTE].MaxInputComponents = 0; /* not used */
1600f982bb67d64673f73096f7c536a5e29756c5c6fRob Clark   ctx->Const.Program[MESA_SHADER_COMPUTE].MaxOutputComponents = 0; /* not used */
1610f982bb67d64673f73096f7c536a5e29756c5c6fRob Clark   ctx->Const.Program[MESA_SHADER_COMPUTE].MaxAtomicBuffers = 8;
1620f982bb67d64673f73096f7c536a5e29756c5c6fRob Clark   ctx->Const.Program[MESA_SHADER_COMPUTE].MaxAtomicCounters = 8;
1630f982bb67d64673f73096f7c536a5e29756c5c6fRob Clark   ctx->Const.Program[MESA_SHADER_COMPUTE].MaxImageUniforms = 8;
1640f982bb67d64673f73096f7c536a5e29756c5c6fRob Clark   ctx->Const.Program[MESA_SHADER_COMPUTE].MaxUniformBlocks = 12;
1650f982bb67d64673f73096f7c536a5e29756c5c6fRob Clark
1660f982bb67d64673f73096f7c536a5e29756c5c6fRob Clark   switch (ctx->Const.GLSLVersion) {
1670f982bb67d64673f73096f7c536a5e29756c5c6fRob Clark   case 100:
1680f982bb67d64673f73096f7c536a5e29756c5c6fRob Clark      ctx->Const.MaxClipPlanes = 0;
1690f982bb67d64673f73096f7c536a5e29756c5c6fRob Clark      ctx->Const.MaxCombinedTextureImageUnits = 8;
1700f982bb67d64673f73096f7c536a5e29756c5c6fRob Clark      ctx->Const.MaxDrawBuffers = 2;
1710f982bb67d64673f73096f7c536a5e29756c5c6fRob Clark      ctx->Const.MinProgramTexelOffset = 0;
1720f982bb67d64673f73096f7c536a5e29756c5c6fRob Clark      ctx->Const.MaxProgramTexelOffset = 0;
1730f982bb67d64673f73096f7c536a5e29756c5c6fRob Clark      ctx->Const.MaxLights = 0;
1740f982bb67d64673f73096f7c536a5e29756c5c6fRob Clark      ctx->Const.MaxTextureCoordUnits = 0;
1750f982bb67d64673f73096f7c536a5e29756c5c6fRob Clark      ctx->Const.MaxTextureUnits = 8;
1760f982bb67d64673f73096f7c536a5e29756c5c6fRob Clark
1770f982bb67d64673f73096f7c536a5e29756c5c6fRob Clark      ctx->Const.Program[MESA_SHADER_VERTEX].MaxAttribs = 8;
1780f982bb67d64673f73096f7c536a5e29756c5c6fRob Clark      ctx->Const.Program[MESA_SHADER_VERTEX].MaxTextureImageUnits = 0;
1790f982bb67d64673f73096f7c536a5e29756c5c6fRob Clark      ctx->Const.Program[MESA_SHADER_VERTEX].MaxUniformComponents = 128 * 4;
1800f982bb67d64673f73096f7c536a5e29756c5c6fRob Clark      ctx->Const.Program[MESA_SHADER_VERTEX].MaxCombinedUniformComponents = 128 * 4;
1810f982bb67d64673f73096f7c536a5e29756c5c6fRob Clark      ctx->Const.Program[MESA_SHADER_VERTEX].MaxInputComponents = 0; /* not used */
1820f982bb67d64673f73096f7c536a5e29756c5c6fRob Clark      ctx->Const.Program[MESA_SHADER_VERTEX].MaxOutputComponents = 32;
1830f982bb67d64673f73096f7c536a5e29756c5c6fRob Clark
1840f982bb67d64673f73096f7c536a5e29756c5c6fRob Clark      ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxTextureImageUnits =
1850f982bb67d64673f73096f7c536a5e29756c5c6fRob Clark         ctx->Const.MaxCombinedTextureImageUnits;
1860f982bb67d64673f73096f7c536a5e29756c5c6fRob Clark      ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxUniformComponents = 16 * 4;
1870f982bb67d64673f73096f7c536a5e29756c5c6fRob Clark      ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxCombinedUniformComponents = 16 * 4;
1880f982bb67d64673f73096f7c536a5e29756c5c6fRob Clark      ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxInputComponents =
1890f982bb67d64673f73096f7c536a5e29756c5c6fRob Clark         ctx->Const.Program[MESA_SHADER_VERTEX].MaxOutputComponents;
1900f982bb67d64673f73096f7c536a5e29756c5c6fRob Clark      ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxOutputComponents = 0; /* not used */
1910f982bb67d64673f73096f7c536a5e29756c5c6fRob Clark
1920f982bb67d64673f73096f7c536a5e29756c5c6fRob Clark      ctx->Const.MaxVarying = ctx->Const.Program[MESA_SHADER_VERTEX].MaxOutputComponents / 4;
1930f982bb67d64673f73096f7c536a5e29756c5c6fRob Clark      break;
1940f982bb67d64673f73096f7c536a5e29756c5c6fRob Clark   case 110:
1950f982bb67d64673f73096f7c536a5e29756c5c6fRob Clark   case 120:
1960f982bb67d64673f73096f7c536a5e29756c5c6fRob Clark      ctx->Const.MaxClipPlanes = 6;
1970f982bb67d64673f73096f7c536a5e29756c5c6fRob Clark      ctx->Const.MaxCombinedTextureImageUnits = 2;
1980f982bb67d64673f73096f7c536a5e29756c5c6fRob Clark      ctx->Const.MaxDrawBuffers = 1;
1990f982bb67d64673f73096f7c536a5e29756c5c6fRob Clark      ctx->Const.MinProgramTexelOffset = 0;
2000f982bb67d64673f73096f7c536a5e29756c5c6fRob Clark      ctx->Const.MaxProgramTexelOffset = 0;
2010f982bb67d64673f73096f7c536a5e29756c5c6fRob Clark      ctx->Const.MaxLights = 8;
2020f982bb67d64673f73096f7c536a5e29756c5c6fRob Clark      ctx->Const.MaxTextureCoordUnits = 2;
2030f982bb67d64673f73096f7c536a5e29756c5c6fRob Clark      ctx->Const.MaxTextureUnits = 2;
2040f982bb67d64673f73096f7c536a5e29756c5c6fRob Clark
2050f982bb67d64673f73096f7c536a5e29756c5c6fRob Clark      ctx->Const.Program[MESA_SHADER_VERTEX].MaxAttribs = 16;
2060f982bb67d64673f73096f7c536a5e29756c5c6fRob Clark      ctx->Const.Program[MESA_SHADER_VERTEX].MaxTextureImageUnits = 0;
2070f982bb67d64673f73096f7c536a5e29756c5c6fRob Clark      ctx->Const.Program[MESA_SHADER_VERTEX].MaxUniformComponents = 512;
2080f982bb67d64673f73096f7c536a5e29756c5c6fRob Clark      ctx->Const.Program[MESA_SHADER_VERTEX].MaxCombinedUniformComponents = 512;
2090f982bb67d64673f73096f7c536a5e29756c5c6fRob Clark      ctx->Const.Program[MESA_SHADER_VERTEX].MaxInputComponents = 0; /* not used */
2100f982bb67d64673f73096f7c536a5e29756c5c6fRob Clark      ctx->Const.Program[MESA_SHADER_VERTEX].MaxOutputComponents = 32;
2110f982bb67d64673f73096f7c536a5e29756c5c6fRob Clark
2120f982bb67d64673f73096f7c536a5e29756c5c6fRob Clark      ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxTextureImageUnits =
2130f982bb67d64673f73096f7c536a5e29756c5c6fRob Clark         ctx->Const.MaxCombinedTextureImageUnits;
2140f982bb67d64673f73096f7c536a5e29756c5c6fRob Clark      ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxUniformComponents = 64;
2150f982bb67d64673f73096f7c536a5e29756c5c6fRob Clark      ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxCombinedUniformComponents = 64;
2160f982bb67d64673f73096f7c536a5e29756c5c6fRob Clark      ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxInputComponents =
2170f982bb67d64673f73096f7c536a5e29756c5c6fRob Clark         ctx->Const.Program[MESA_SHADER_VERTEX].MaxOutputComponents;
2180f982bb67d64673f73096f7c536a5e29756c5c6fRob Clark      ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxOutputComponents = 0; /* not used */
2190f982bb67d64673f73096f7c536a5e29756c5c6fRob Clark
2200f982bb67d64673f73096f7c536a5e29756c5c6fRob Clark      ctx->Const.MaxVarying = ctx->Const.Program[MESA_SHADER_VERTEX].MaxOutputComponents / 4;
2210f982bb67d64673f73096f7c536a5e29756c5c6fRob Clark      break;
2220f982bb67d64673f73096f7c536a5e29756c5c6fRob Clark   case 130:
2230f982bb67d64673f73096f7c536a5e29756c5c6fRob Clark   case 140:
2240f982bb67d64673f73096f7c536a5e29756c5c6fRob Clark      ctx->Const.MaxClipPlanes = 8;
2250f982bb67d64673f73096f7c536a5e29756c5c6fRob Clark      ctx->Const.MaxCombinedTextureImageUnits = 16;
2260f982bb67d64673f73096f7c536a5e29756c5c6fRob Clark      ctx->Const.MaxDrawBuffers = 8;
2270f982bb67d64673f73096f7c536a5e29756c5c6fRob Clark      ctx->Const.MinProgramTexelOffset = -8;
2280f982bb67d64673f73096f7c536a5e29756c5c6fRob Clark      ctx->Const.MaxProgramTexelOffset = 7;
2290f982bb67d64673f73096f7c536a5e29756c5c6fRob Clark      ctx->Const.MaxLights = 8;
2300f982bb67d64673f73096f7c536a5e29756c5c6fRob Clark      ctx->Const.MaxTextureCoordUnits = 8;
2310f982bb67d64673f73096f7c536a5e29756c5c6fRob Clark      ctx->Const.MaxTextureUnits = 2;
2320f982bb67d64673f73096f7c536a5e29756c5c6fRob Clark
2330f982bb67d64673f73096f7c536a5e29756c5c6fRob Clark      ctx->Const.Program[MESA_SHADER_VERTEX].MaxAttribs = 16;
2340f982bb67d64673f73096f7c536a5e29756c5c6fRob Clark      ctx->Const.Program[MESA_SHADER_VERTEX].MaxTextureImageUnits = 16;
2350f982bb67d64673f73096f7c536a5e29756c5c6fRob Clark      ctx->Const.Program[MESA_SHADER_VERTEX].MaxUniformComponents = 1024;
2360f982bb67d64673f73096f7c536a5e29756c5c6fRob Clark      ctx->Const.Program[MESA_SHADER_VERTEX].MaxCombinedUniformComponents = 1024;
2370f982bb67d64673f73096f7c536a5e29756c5c6fRob Clark      ctx->Const.Program[MESA_SHADER_VERTEX].MaxInputComponents = 0; /* not used */
2380f982bb67d64673f73096f7c536a5e29756c5c6fRob Clark      ctx->Const.Program[MESA_SHADER_VERTEX].MaxOutputComponents = 64;
2390f982bb67d64673f73096f7c536a5e29756c5c6fRob Clark
2400f982bb67d64673f73096f7c536a5e29756c5c6fRob Clark      ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxTextureImageUnits = 16;
2410f982bb67d64673f73096f7c536a5e29756c5c6fRob Clark      ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxUniformComponents = 1024;
2420f982bb67d64673f73096f7c536a5e29756c5c6fRob Clark      ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxCombinedUniformComponents = 1024;
2430f982bb67d64673f73096f7c536a5e29756c5c6fRob Clark      ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxInputComponents =
2440f982bb67d64673f73096f7c536a5e29756c5c6fRob Clark         ctx->Const.Program[MESA_SHADER_VERTEX].MaxOutputComponents;
2450f982bb67d64673f73096f7c536a5e29756c5c6fRob Clark      ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxOutputComponents = 0; /* not used */
2460f982bb67d64673f73096f7c536a5e29756c5c6fRob Clark
2470f982bb67d64673f73096f7c536a5e29756c5c6fRob Clark      ctx->Const.MaxVarying = ctx->Const.Program[MESA_SHADER_VERTEX].MaxOutputComponents / 4;
2480f982bb67d64673f73096f7c536a5e29756c5c6fRob Clark      break;
2490f982bb67d64673f73096f7c536a5e29756c5c6fRob Clark   case 150:
2500f982bb67d64673f73096f7c536a5e29756c5c6fRob Clark   case 330:
2515f7f7d582b1d6d3696506250743fd3f6be3277b8Ian Romanick   case 400:
2525f7f7d582b1d6d3696506250743fd3f6be3277b8Ian Romanick   case 410:
2535f7f7d582b1d6d3696506250743fd3f6be3277b8Ian Romanick   case 420:
2545f7f7d582b1d6d3696506250743fd3f6be3277b8Ian Romanick   case 430:
2555f7f7d582b1d6d3696506250743fd3f6be3277b8Ian Romanick   case 440:
2565f7f7d582b1d6d3696506250743fd3f6be3277b8Ian Romanick   case 450:
2570f982bb67d64673f73096f7c536a5e29756c5c6fRob Clark      ctx->Const.MaxClipPlanes = 8;
2580f982bb67d64673f73096f7c536a5e29756c5c6fRob Clark      ctx->Const.MaxDrawBuffers = 8;
2590f982bb67d64673f73096f7c536a5e29756c5c6fRob Clark      ctx->Const.MinProgramTexelOffset = -8;
2600f982bb67d64673f73096f7c536a5e29756c5c6fRob Clark      ctx->Const.MaxProgramTexelOffset = 7;
2610f982bb67d64673f73096f7c536a5e29756c5c6fRob Clark      ctx->Const.MaxLights = 8;
2620f982bb67d64673f73096f7c536a5e29756c5c6fRob Clark      ctx->Const.MaxTextureCoordUnits = 8;
2630f982bb67d64673f73096f7c536a5e29756c5c6fRob Clark      ctx->Const.MaxTextureUnits = 2;
2640f982bb67d64673f73096f7c536a5e29756c5c6fRob Clark
2650f982bb67d64673f73096f7c536a5e29756c5c6fRob Clark      ctx->Const.Program[MESA_SHADER_VERTEX].MaxAttribs = 16;
2660f982bb67d64673f73096f7c536a5e29756c5c6fRob Clark      ctx->Const.Program[MESA_SHADER_VERTEX].MaxTextureImageUnits = 16;
2670f982bb67d64673f73096f7c536a5e29756c5c6fRob Clark      ctx->Const.Program[MESA_SHADER_VERTEX].MaxUniformComponents = 1024;
2680f982bb67d64673f73096f7c536a5e29756c5c6fRob Clark      ctx->Const.Program[MESA_SHADER_VERTEX].MaxCombinedUniformComponents = 1024;
2690f982bb67d64673f73096f7c536a5e29756c5c6fRob Clark      ctx->Const.Program[MESA_SHADER_VERTEX].MaxInputComponents = 0; /* not used */
2700f982bb67d64673f73096f7c536a5e29756c5c6fRob Clark      ctx->Const.Program[MESA_SHADER_VERTEX].MaxOutputComponents = 64;
2710f982bb67d64673f73096f7c536a5e29756c5c6fRob Clark
2720f982bb67d64673f73096f7c536a5e29756c5c6fRob Clark      ctx->Const.Program[MESA_SHADER_GEOMETRY].MaxTextureImageUnits = 16;
2730f982bb67d64673f73096f7c536a5e29756c5c6fRob Clark      ctx->Const.Program[MESA_SHADER_GEOMETRY].MaxUniformComponents = 1024;
2740f982bb67d64673f73096f7c536a5e29756c5c6fRob Clark      ctx->Const.Program[MESA_SHADER_GEOMETRY].MaxCombinedUniformComponents = 1024;
2750f982bb67d64673f73096f7c536a5e29756c5c6fRob Clark      ctx->Const.Program[MESA_SHADER_GEOMETRY].MaxInputComponents =
2760f982bb67d64673f73096f7c536a5e29756c5c6fRob Clark         ctx->Const.Program[MESA_SHADER_VERTEX].MaxOutputComponents;
2770f982bb67d64673f73096f7c536a5e29756c5c6fRob Clark      ctx->Const.Program[MESA_SHADER_GEOMETRY].MaxOutputComponents = 128;
2780f982bb67d64673f73096f7c536a5e29756c5c6fRob Clark
2790f982bb67d64673f73096f7c536a5e29756c5c6fRob Clark      ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxTextureImageUnits = 16;
2800f982bb67d64673f73096f7c536a5e29756c5c6fRob Clark      ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxUniformComponents = 1024;
2810f982bb67d64673f73096f7c536a5e29756c5c6fRob Clark      ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxCombinedUniformComponents = 1024;
2820f982bb67d64673f73096f7c536a5e29756c5c6fRob Clark      ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxInputComponents =
2830f982bb67d64673f73096f7c536a5e29756c5c6fRob Clark         ctx->Const.Program[MESA_SHADER_GEOMETRY].MaxOutputComponents;
2840f982bb67d64673f73096f7c536a5e29756c5c6fRob Clark      ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxOutputComponents = 0; /* not used */
2850f982bb67d64673f73096f7c536a5e29756c5c6fRob Clark
2860f982bb67d64673f73096f7c536a5e29756c5c6fRob Clark      ctx->Const.MaxCombinedTextureImageUnits =
2870f982bb67d64673f73096f7c536a5e29756c5c6fRob Clark         ctx->Const.Program[MESA_SHADER_VERTEX].MaxTextureImageUnits
2880f982bb67d64673f73096f7c536a5e29756c5c6fRob Clark         + ctx->Const.Program[MESA_SHADER_GEOMETRY].MaxTextureImageUnits
2890f982bb67d64673f73096f7c536a5e29756c5c6fRob Clark         + ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxTextureImageUnits;
2900f982bb67d64673f73096f7c536a5e29756c5c6fRob Clark
2910f982bb67d64673f73096f7c536a5e29756c5c6fRob Clark      ctx->Const.MaxGeometryOutputVertices = 256;
2920f982bb67d64673f73096f7c536a5e29756c5c6fRob Clark      ctx->Const.MaxGeometryTotalOutputComponents = 1024;
2930f982bb67d64673f73096f7c536a5e29756c5c6fRob Clark
2940f982bb67d64673f73096f7c536a5e29756c5c6fRob Clark      ctx->Const.MaxVarying = 60 / 4;
2950f982bb67d64673f73096f7c536a5e29756c5c6fRob Clark      break;
2960f982bb67d64673f73096f7c536a5e29756c5c6fRob Clark   case 300:
2970f982bb67d64673f73096f7c536a5e29756c5c6fRob Clark      ctx->Const.MaxClipPlanes = 8;
2980f982bb67d64673f73096f7c536a5e29756c5c6fRob Clark      ctx->Const.MaxCombinedTextureImageUnits = 32;
2990f982bb67d64673f73096f7c536a5e29756c5c6fRob Clark      ctx->Const.MaxDrawBuffers = 4;
3000f982bb67d64673f73096f7c536a5e29756c5c6fRob Clark      ctx->Const.MinProgramTexelOffset = -8;
3010f982bb67d64673f73096f7c536a5e29756c5c6fRob Clark      ctx->Const.MaxProgramTexelOffset = 7;
3020f982bb67d64673f73096f7c536a5e29756c5c6fRob Clark      ctx->Const.MaxLights = 0;
3030f982bb67d64673f73096f7c536a5e29756c5c6fRob Clark      ctx->Const.MaxTextureCoordUnits = 0;
3040f982bb67d64673f73096f7c536a5e29756c5c6fRob Clark      ctx->Const.MaxTextureUnits = 0;
3050f982bb67d64673f73096f7c536a5e29756c5c6fRob Clark
3060f982bb67d64673f73096f7c536a5e29756c5c6fRob Clark      ctx->Const.Program[MESA_SHADER_VERTEX].MaxAttribs = 16;
3070f982bb67d64673f73096f7c536a5e29756c5c6fRob Clark      ctx->Const.Program[MESA_SHADER_VERTEX].MaxTextureImageUnits = 16;
3080f982bb67d64673f73096f7c536a5e29756c5c6fRob Clark      ctx->Const.Program[MESA_SHADER_VERTEX].MaxUniformComponents = 1024;
3090f982bb67d64673f73096f7c536a5e29756c5c6fRob Clark      ctx->Const.Program[MESA_SHADER_VERTEX].MaxCombinedUniformComponents = 1024;
3100f982bb67d64673f73096f7c536a5e29756c5c6fRob Clark      ctx->Const.Program[MESA_SHADER_VERTEX].MaxInputComponents = 0; /* not used */
3110f982bb67d64673f73096f7c536a5e29756c5c6fRob Clark      ctx->Const.Program[MESA_SHADER_VERTEX].MaxOutputComponents = 16 * 4;
3120f982bb67d64673f73096f7c536a5e29756c5c6fRob Clark
3130f982bb67d64673f73096f7c536a5e29756c5c6fRob Clark      ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxTextureImageUnits = 16;
3140f982bb67d64673f73096f7c536a5e29756c5c6fRob Clark      ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxUniformComponents = 224;
3150f982bb67d64673f73096f7c536a5e29756c5c6fRob Clark      ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxCombinedUniformComponents = 224;
3160f982bb67d64673f73096f7c536a5e29756c5c6fRob Clark      ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxInputComponents = 15 * 4;
3170f982bb67d64673f73096f7c536a5e29756c5c6fRob Clark      ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxOutputComponents = 0; /* not used */
3180f982bb67d64673f73096f7c536a5e29756c5c6fRob Clark
3190f982bb67d64673f73096f7c536a5e29756c5c6fRob Clark      ctx->Const.MaxVarying = ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxInputComponents / 4;
3200f982bb67d64673f73096f7c536a5e29756c5c6fRob Clark      break;
3210f982bb67d64673f73096f7c536a5e29756c5c6fRob Clark   }
3220f982bb67d64673f73096f7c536a5e29756c5c6fRob Clark
3230f982bb67d64673f73096f7c536a5e29756c5c6fRob Clark   ctx->Const.GenerateTemporaryNames = true;
3240f982bb67d64673f73096f7c536a5e29756c5c6fRob Clark   ctx->Const.MaxPatchVertices = 32;
3250f982bb67d64673f73096f7c536a5e29756c5c6fRob Clark
32607cfe4e6aa2af646445c3e0f6be5eea60c721094Rob Clark   /* GL_ARB_explicit_uniform_location, GL_MAX_UNIFORM_LOCATIONS */
32707cfe4e6aa2af646445c3e0f6be5eea60c721094Rob Clark   ctx->Const.MaxUserAssignableUniformLocations =
32807cfe4e6aa2af646445c3e0f6be5eea60c721094Rob Clark      4 * MESA_SHADER_STAGES * MAX_UNIFORMS;
32907cfe4e6aa2af646445c3e0f6be5eea60c721094Rob Clark
3300c85d2fea406df033c27201ba5e7257874a67a9aTimothy Arceri   ctx->Driver.NewProgram = new_program;
3310f982bb67d64673f73096f7c536a5e29756c5c6fRob Clark}
3320f982bb67d64673f73096f7c536a5e29756c5c6fRob Clark
3330f982bb67d64673f73096f7c536a5e29756c5c6fRob Clark/* Returned string will have 'ctx' as its ralloc owner. */
3340f982bb67d64673f73096f7c536a5e29756c5c6fRob Clarkstatic char *
3350f982bb67d64673f73096f7c536a5e29756c5c6fRob Clarkload_text_file(void *ctx, const char *file_name)
3360f982bb67d64673f73096f7c536a5e29756c5c6fRob Clark{
3370f982bb67d64673f73096f7c536a5e29756c5c6fRob Clark   char *text = NULL;
3380f982bb67d64673f73096f7c536a5e29756c5c6fRob Clark   size_t size;
3390f982bb67d64673f73096f7c536a5e29756c5c6fRob Clark   size_t total_read = 0;
3400f982bb67d64673f73096f7c536a5e29756c5c6fRob Clark   FILE *fp = fopen(file_name, "rb");
3410f982bb67d64673f73096f7c536a5e29756c5c6fRob Clark
3420f982bb67d64673f73096f7c536a5e29756c5c6fRob Clark   if (!fp) {
3430f982bb67d64673f73096f7c536a5e29756c5c6fRob Clark      return NULL;
3440f982bb67d64673f73096f7c536a5e29756c5c6fRob Clark   }
3450f982bb67d64673f73096f7c536a5e29756c5c6fRob Clark
3460f982bb67d64673f73096f7c536a5e29756c5c6fRob Clark   fseek(fp, 0L, SEEK_END);
3470f982bb67d64673f73096f7c536a5e29756c5c6fRob Clark   size = ftell(fp);
3480f982bb67d64673f73096f7c536a5e29756c5c6fRob Clark   fseek(fp, 0L, SEEK_SET);
3490f982bb67d64673f73096f7c536a5e29756c5c6fRob Clark
3500f982bb67d64673f73096f7c536a5e29756c5c6fRob Clark   text = (char *) ralloc_size(ctx, size + 1);
3510f982bb67d64673f73096f7c536a5e29756c5c6fRob Clark   if (text != NULL) {
3520f982bb67d64673f73096f7c536a5e29756c5c6fRob Clark      do {
3530f982bb67d64673f73096f7c536a5e29756c5c6fRob Clark         size_t bytes = fread(text + total_read,
3540f982bb67d64673f73096f7c536a5e29756c5c6fRob Clark               1, size - total_read, fp);
3550f982bb67d64673f73096f7c536a5e29756c5c6fRob Clark         if (bytes < size - total_read) {
3560f982bb67d64673f73096f7c536a5e29756c5c6fRob Clark            free(text);
3570f982bb67d64673f73096f7c536a5e29756c5c6fRob Clark            text = NULL;
3580f982bb67d64673f73096f7c536a5e29756c5c6fRob Clark            goto error;
3590f982bb67d64673f73096f7c536a5e29756c5c6fRob Clark         }
3600f982bb67d64673f73096f7c536a5e29756c5c6fRob Clark
3610f982bb67d64673f73096f7c536a5e29756c5c6fRob Clark         if (bytes == 0) {
3620f982bb67d64673f73096f7c536a5e29756c5c6fRob Clark            break;
3630f982bb67d64673f73096f7c536a5e29756c5c6fRob Clark         }
3640f982bb67d64673f73096f7c536a5e29756c5c6fRob Clark
3650f982bb67d64673f73096f7c536a5e29756c5c6fRob Clark         total_read += bytes;
3660f982bb67d64673f73096f7c536a5e29756c5c6fRob Clark      } while (total_read < size);
3670f982bb67d64673f73096f7c536a5e29756c5c6fRob Clark
3680f982bb67d64673f73096f7c536a5e29756c5c6fRob Clark      text[total_read] = '\0';
3690f982bb67d64673f73096f7c536a5e29756c5c6fRob Clark      error:;
3700f982bb67d64673f73096f7c536a5e29756c5c6fRob Clark   }
3710f982bb67d64673f73096f7c536a5e29756c5c6fRob Clark
3720f982bb67d64673f73096f7c536a5e29756c5c6fRob Clark   fclose(fp);
3730f982bb67d64673f73096f7c536a5e29756c5c6fRob Clark
3740f982bb67d64673f73096f7c536a5e29756c5c6fRob Clark   return text;
3750f982bb67d64673f73096f7c536a5e29756c5c6fRob Clark}
3760f982bb67d64673f73096f7c536a5e29756c5c6fRob Clark
3770f982bb67d64673f73096f7c536a5e29756c5c6fRob Clarkvoid
3780f982bb67d64673f73096f7c536a5e29756c5c6fRob Clarkcompile_shader(struct gl_context *ctx, struct gl_shader *shader)
3790f982bb67d64673f73096f7c536a5e29756c5c6fRob Clark{
3800f982bb67d64673f73096f7c536a5e29756c5c6fRob Clark   struct _mesa_glsl_parse_state *state =
3810f982bb67d64673f73096f7c536a5e29756c5c6fRob Clark      new(shader) _mesa_glsl_parse_state(ctx, shader->Stage, shader);
3820f982bb67d64673f73096f7c536a5e29756c5c6fRob Clark
3830f982bb67d64673f73096f7c536a5e29756c5c6fRob Clark   _mesa_glsl_compile_shader(ctx, shader, options->dump_ast, options->dump_hir);
3840f982bb67d64673f73096f7c536a5e29756c5c6fRob Clark
3850f982bb67d64673f73096f7c536a5e29756c5c6fRob Clark   /* Print out the resulting IR */
3860f982bb67d64673f73096f7c536a5e29756c5c6fRob Clark   if (!state->error && options->dump_lir) {
3870f982bb67d64673f73096f7c536a5e29756c5c6fRob Clark      _mesa_print_ir(stdout, shader->ir, state);
3880f982bb67d64673f73096f7c536a5e29756c5c6fRob Clark   }
3890f982bb67d64673f73096f7c536a5e29756c5c6fRob Clark
3900f982bb67d64673f73096f7c536a5e29756c5c6fRob Clark   return;
3910f982bb67d64673f73096f7c536a5e29756c5c6fRob Clark}
3920f982bb67d64673f73096f7c536a5e29756c5c6fRob Clark
3930f982bb67d64673f73096f7c536a5e29756c5c6fRob Clarkextern "C" struct gl_shader_program *
3940f982bb67d64673f73096f7c536a5e29756c5c6fRob Clarkstandalone_compile_shader(const struct standalone_options *_options,
3950f982bb67d64673f73096f7c536a5e29756c5c6fRob Clark      unsigned num_files, char* const* files)
3960f982bb67d64673f73096f7c536a5e29756c5c6fRob Clark{
3970f982bb67d64673f73096f7c536a5e29756c5c6fRob Clark   int status = EXIT_SUCCESS;
3980f982bb67d64673f73096f7c536a5e29756c5c6fRob Clark   static struct gl_context local_ctx;
3990f982bb67d64673f73096f7c536a5e29756c5c6fRob Clark   struct gl_context *ctx = &local_ctx;
4000f982bb67d64673f73096f7c536a5e29756c5c6fRob Clark   bool glsl_es = false;
4010f982bb67d64673f73096f7c536a5e29756c5c6fRob Clark
4020f982bb67d64673f73096f7c536a5e29756c5c6fRob Clark   options = _options;
4030f982bb67d64673f73096f7c536a5e29756c5c6fRob Clark
4040f982bb67d64673f73096f7c536a5e29756c5c6fRob Clark   switch (options->glsl_version) {
4050f982bb67d64673f73096f7c536a5e29756c5c6fRob Clark   case 100:
4060f982bb67d64673f73096f7c536a5e29756c5c6fRob Clark   case 300:
4070f982bb67d64673f73096f7c536a5e29756c5c6fRob Clark      glsl_es = true;
4080f982bb67d64673f73096f7c536a5e29756c5c6fRob Clark      break;
4090f982bb67d64673f73096f7c536a5e29756c5c6fRob Clark   case 110:
4100f982bb67d64673f73096f7c536a5e29756c5c6fRob Clark   case 120:
4110f982bb67d64673f73096f7c536a5e29756c5c6fRob Clark   case 130:
4120f982bb67d64673f73096f7c536a5e29756c5c6fRob Clark   case 140:
4130f982bb67d64673f73096f7c536a5e29756c5c6fRob Clark   case 150:
4140f982bb67d64673f73096f7c536a5e29756c5c6fRob Clark   case 330:
4155f7f7d582b1d6d3696506250743fd3f6be3277b8Ian Romanick   case 400:
4165f7f7d582b1d6d3696506250743fd3f6be3277b8Ian Romanick   case 410:
4175f7f7d582b1d6d3696506250743fd3f6be3277b8Ian Romanick   case 420:
4185f7f7d582b1d6d3696506250743fd3f6be3277b8Ian Romanick   case 430:
4195f7f7d582b1d6d3696506250743fd3f6be3277b8Ian Romanick   case 440:
4205f7f7d582b1d6d3696506250743fd3f6be3277b8Ian Romanick   case 450:
4210f982bb67d64673f73096f7c536a5e29756c5c6fRob Clark      glsl_es = false;
4220f982bb67d64673f73096f7c536a5e29756c5c6fRob Clark      break;
4230f982bb67d64673f73096f7c536a5e29756c5c6fRob Clark   default:
4240f982bb67d64673f73096f7c536a5e29756c5c6fRob Clark      fprintf(stderr, "Unrecognized GLSL version `%d'\n", options->glsl_version);
4250f982bb67d64673f73096f7c536a5e29756c5c6fRob Clark      return NULL;
4260f982bb67d64673f73096f7c536a5e29756c5c6fRob Clark   }
4270f982bb67d64673f73096f7c536a5e29756c5c6fRob Clark
428798d1b8816fed0a88674c6d89d56e478519a5a55Ian Romanick   if (glsl_es) {
429798d1b8816fed0a88674c6d89d56e478519a5a55Ian Romanick      initialize_context(ctx, API_OPENGLES2);
430798d1b8816fed0a88674c6d89d56e478519a5a55Ian Romanick   } else {
431798d1b8816fed0a88674c6d89d56e478519a5a55Ian Romanick      initialize_context(ctx, options->glsl_version > 130 ? API_OPENGL_CORE : API_OPENGL_COMPAT);
432798d1b8816fed0a88674c6d89d56e478519a5a55Ian Romanick   }
4330f982bb67d64673f73096f7c536a5e29756c5c6fRob Clark
4340f982bb67d64673f73096f7c536a5e29756c5c6fRob Clark   struct gl_shader_program *whole_program;
4350f982bb67d64673f73096f7c536a5e29756c5c6fRob Clark
4360f982bb67d64673f73096f7c536a5e29756c5c6fRob Clark   whole_program = rzalloc (NULL, struct gl_shader_program);
4370f982bb67d64673f73096f7c536a5e29756c5c6fRob Clark   assert(whole_program != NULL);
438203c8794a1debc0e45019fe945d1cc55459e6c6fTimothy Arceri   whole_program->data = rzalloc(whole_program, struct gl_shader_program_data);
439203c8794a1debc0e45019fe945d1cc55459e6c6fTimothy Arceri   assert(whole_program->data != NULL);
440203c8794a1debc0e45019fe945d1cc55459e6c6fTimothy Arceri   whole_program->data->InfoLog = ralloc_strdup(whole_program->data, "");
4410f982bb67d64673f73096f7c536a5e29756c5c6fRob Clark
4420f982bb67d64673f73096f7c536a5e29756c5c6fRob Clark   /* Created just to avoid segmentation faults */
4430f982bb67d64673f73096f7c536a5e29756c5c6fRob Clark   whole_program->AttributeBindings = new string_to_uint_map;
4440f982bb67d64673f73096f7c536a5e29756c5c6fRob Clark   whole_program->FragDataBindings = new string_to_uint_map;
4450f982bb67d64673f73096f7c536a5e29756c5c6fRob Clark   whole_program->FragDataIndexBindings = new string_to_uint_map;
4460f982bb67d64673f73096f7c536a5e29756c5c6fRob Clark
4470f982bb67d64673f73096f7c536a5e29756c5c6fRob Clark   for (unsigned i = 0; i < num_files; i++) {
4480f982bb67d64673f73096f7c536a5e29756c5c6fRob Clark      whole_program->Shaders =
4490f982bb67d64673f73096f7c536a5e29756c5c6fRob Clark            reralloc(whole_program, whole_program->Shaders,
4500f982bb67d64673f73096f7c536a5e29756c5c6fRob Clark                  struct gl_shader *, whole_program->NumShaders + 1);
4510f982bb67d64673f73096f7c536a5e29756c5c6fRob Clark      assert(whole_program->Shaders != NULL);
4520f982bb67d64673f73096f7c536a5e29756c5c6fRob Clark
4530f982bb67d64673f73096f7c536a5e29756c5c6fRob Clark      struct gl_shader *shader = rzalloc(whole_program, gl_shader);
4540f982bb67d64673f73096f7c536a5e29756c5c6fRob Clark
4550f982bb67d64673f73096f7c536a5e29756c5c6fRob Clark      whole_program->Shaders[whole_program->NumShaders] = shader;
4560f982bb67d64673f73096f7c536a5e29756c5c6fRob Clark      whole_program->NumShaders++;
4570f982bb67d64673f73096f7c536a5e29756c5c6fRob Clark
4580f982bb67d64673f73096f7c536a5e29756c5c6fRob Clark      const unsigned len = strlen(files[i]);
4590f982bb67d64673f73096f7c536a5e29756c5c6fRob Clark      if (len < 6)
4600f982bb67d64673f73096f7c536a5e29756c5c6fRob Clark         goto fail;
4610f982bb67d64673f73096f7c536a5e29756c5c6fRob Clark
4620f982bb67d64673f73096f7c536a5e29756c5c6fRob Clark      const char *const ext = & files[i][len - 5];
4630f982bb67d64673f73096f7c536a5e29756c5c6fRob Clark      /* TODO add support to read a .shader_test */
4640f982bb67d64673f73096f7c536a5e29756c5c6fRob Clark      if (strncmp(".vert", ext, 5) == 0 || strncmp(".glsl", ext, 5) == 0)
4650f982bb67d64673f73096f7c536a5e29756c5c6fRob Clark	 shader->Type = GL_VERTEX_SHADER;
4660f982bb67d64673f73096f7c536a5e29756c5c6fRob Clark      else if (strncmp(".tesc", ext, 5) == 0)
4670f982bb67d64673f73096f7c536a5e29756c5c6fRob Clark	 shader->Type = GL_TESS_CONTROL_SHADER;
4680f982bb67d64673f73096f7c536a5e29756c5c6fRob Clark      else if (strncmp(".tese", ext, 5) == 0)
4690f982bb67d64673f73096f7c536a5e29756c5c6fRob Clark	 shader->Type = GL_TESS_EVALUATION_SHADER;
4700f982bb67d64673f73096f7c536a5e29756c5c6fRob Clark      else if (strncmp(".geom", ext, 5) == 0)
4710f982bb67d64673f73096f7c536a5e29756c5c6fRob Clark	 shader->Type = GL_GEOMETRY_SHADER;
4720f982bb67d64673f73096f7c536a5e29756c5c6fRob Clark      else if (strncmp(".frag", ext, 5) == 0)
4730f982bb67d64673f73096f7c536a5e29756c5c6fRob Clark	 shader->Type = GL_FRAGMENT_SHADER;
4740f982bb67d64673f73096f7c536a5e29756c5c6fRob Clark      else if (strncmp(".comp", ext, 5) == 0)
4750f982bb67d64673f73096f7c536a5e29756c5c6fRob Clark         shader->Type = GL_COMPUTE_SHADER;
4760f982bb67d64673f73096f7c536a5e29756c5c6fRob Clark      else
4770f982bb67d64673f73096f7c536a5e29756c5c6fRob Clark         goto fail;
4780f982bb67d64673f73096f7c536a5e29756c5c6fRob Clark      shader->Stage = _mesa_shader_enum_to_shader_stage(shader->Type);
4790f982bb67d64673f73096f7c536a5e29756c5c6fRob Clark
4800f982bb67d64673f73096f7c536a5e29756c5c6fRob Clark      shader->Source = load_text_file(whole_program, files[i]);
4810f982bb67d64673f73096f7c536a5e29756c5c6fRob Clark      if (shader->Source == NULL) {
4820f982bb67d64673f73096f7c536a5e29756c5c6fRob Clark         printf("File \"%s\" does not exist.\n", files[i]);
4830f982bb67d64673f73096f7c536a5e29756c5c6fRob Clark         exit(EXIT_FAILURE);
4840f982bb67d64673f73096f7c536a5e29756c5c6fRob Clark      }
4850f982bb67d64673f73096f7c536a5e29756c5c6fRob Clark
4860f982bb67d64673f73096f7c536a5e29756c5c6fRob Clark      compile_shader(ctx, shader);
4870f982bb67d64673f73096f7c536a5e29756c5c6fRob Clark
48868c23d2d046b6419c7b3bd273278235095e29daeAlejandro Piñeiro      if (strlen(shader->InfoLog) > 0) {
48968c23d2d046b6419c7b3bd273278235095e29daeAlejandro Piñeiro         if (!options->just_log)
49068c23d2d046b6419c7b3bd273278235095e29daeAlejandro Piñeiro            printf("Info log for %s:\n", files[i]);
49168c23d2d046b6419c7b3bd273278235095e29daeAlejandro Piñeiro
49268c23d2d046b6419c7b3bd273278235095e29daeAlejandro Piñeiro         printf("%s", shader->InfoLog);
49368c23d2d046b6419c7b3bd273278235095e29daeAlejandro Piñeiro         if (!options->just_log)
49468c23d2d046b6419c7b3bd273278235095e29daeAlejandro Piñeiro            printf("\n");
49568c23d2d046b6419c7b3bd273278235095e29daeAlejandro Piñeiro      }
4960f982bb67d64673f73096f7c536a5e29756c5c6fRob Clark
4970f982bb67d64673f73096f7c536a5e29756c5c6fRob Clark      if (!shader->CompileStatus) {
4980f982bb67d64673f73096f7c536a5e29756c5c6fRob Clark         status = EXIT_FAILURE;
4990f982bb67d64673f73096f7c536a5e29756c5c6fRob Clark         break;
5000f982bb67d64673f73096f7c536a5e29756c5c6fRob Clark      }
5010f982bb67d64673f73096f7c536a5e29756c5c6fRob Clark   }
5020f982bb67d64673f73096f7c536a5e29756c5c6fRob Clark
503d0028b2e1c43392bb476416a1af2097ab17afe7cIan Romanick   if (status == EXIT_SUCCESS) {
504d2861d682a235993844989f7742c9539c3e10245Timothy Arceri      _mesa_clear_shader_program_data(ctx, whole_program);
5050f982bb67d64673f73096f7c536a5e29756c5c6fRob Clark
506d0028b2e1c43392bb476416a1af2097ab17afe7cIan Romanick      if (options->do_link)  {
507d0028b2e1c43392bb476416a1af2097ab17afe7cIan Romanick         link_shaders(ctx, whole_program);
508d0028b2e1c43392bb476416a1af2097ab17afe7cIan Romanick      } else {
509d0028b2e1c43392bb476416a1af2097ab17afe7cIan Romanick         const gl_shader_stage stage = whole_program->Shaders[0]->Stage;
510d0028b2e1c43392bb476416a1af2097ab17afe7cIan Romanick
511203c8794a1debc0e45019fe945d1cc55459e6c6fTimothy Arceri         whole_program->data->LinkStatus = GL_TRUE;
512d0028b2e1c43392bb476416a1af2097ab17afe7cIan Romanick         whole_program->_LinkedShaders[stage] =
513d0028b2e1c43392bb476416a1af2097ab17afe7cIan Romanick            link_intrastage_shaders(whole_program /* mem_ctx */,
514d0028b2e1c43392bb476416a1af2097ab17afe7cIan Romanick                                    ctx,
515d0028b2e1c43392bb476416a1af2097ab17afe7cIan Romanick                                    whole_program,
516d0028b2e1c43392bb476416a1af2097ab17afe7cIan Romanick                                    whole_program->Shaders,
517d0028b2e1c43392bb476416a1af2097ab17afe7cIan Romanick                                    1,
518d0028b2e1c43392bb476416a1af2097ab17afe7cIan Romanick                                    true);
519d0028b2e1c43392bb476416a1af2097ab17afe7cIan Romanick
520d0028b2e1c43392bb476416a1af2097ab17afe7cIan Romanick         /* Par-linking can fail, for example, if there are undefined external
521d0028b2e1c43392bb476416a1af2097ab17afe7cIan Romanick          * references.
522d0028b2e1c43392bb476416a1af2097ab17afe7cIan Romanick          */
523d0028b2e1c43392bb476416a1af2097ab17afe7cIan Romanick         if (whole_program->_LinkedShaders[stage] != NULL) {
524203c8794a1debc0e45019fe945d1cc55459e6c6fTimothy Arceri            assert(whole_program->data->LinkStatus);
525d0028b2e1c43392bb476416a1af2097ab17afe7cIan Romanick
526d0028b2e1c43392bb476416a1af2097ab17afe7cIan Romanick            struct gl_shader_compiler_options *const compiler_options =
527d0028b2e1c43392bb476416a1af2097ab17afe7cIan Romanick               &ctx->Const.ShaderCompilerOptions[stage];
528d0028b2e1c43392bb476416a1af2097ab17afe7cIan Romanick
529d0028b2e1c43392bb476416a1af2097ab17afe7cIan Romanick            exec_list *const ir =
530d0028b2e1c43392bb476416a1af2097ab17afe7cIan Romanick               whole_program->_LinkedShaders[stage]->ir;
531d0028b2e1c43392bb476416a1af2097ab17afe7cIan Romanick
532d0028b2e1c43392bb476416a1af2097ab17afe7cIan Romanick            bool progress;
533d0028b2e1c43392bb476416a1af2097ab17afe7cIan Romanick            do {
534d0028b2e1c43392bb476416a1af2097ab17afe7cIan Romanick               progress = do_function_inlining(ir);
535d0028b2e1c43392bb476416a1af2097ab17afe7cIan Romanick
536d0028b2e1c43392bb476416a1af2097ab17afe7cIan Romanick               progress = do_common_optimization(ir,
537d0028b2e1c43392bb476416a1af2097ab17afe7cIan Romanick                                                 false,
538d0028b2e1c43392bb476416a1af2097ab17afe7cIan Romanick                                                 false,
539d0028b2e1c43392bb476416a1af2097ab17afe7cIan Romanick                                                 compiler_options,
540d0028b2e1c43392bb476416a1af2097ab17afe7cIan Romanick                                                 true)
541d0028b2e1c43392bb476416a1af2097ab17afe7cIan Romanick                  && progress;
542d0028b2e1c43392bb476416a1af2097ab17afe7cIan Romanick            } while(progress);
543d0028b2e1c43392bb476416a1af2097ab17afe7cIan Romanick         }
544d0028b2e1c43392bb476416a1af2097ab17afe7cIan Romanick      }
545d0028b2e1c43392bb476416a1af2097ab17afe7cIan Romanick
546203c8794a1debc0e45019fe945d1cc55459e6c6fTimothy Arceri      status = (whole_program->data->LinkStatus) ? EXIT_SUCCESS : EXIT_FAILURE;
5470f982bb67d64673f73096f7c536a5e29756c5c6fRob Clark
548203c8794a1debc0e45019fe945d1cc55459e6c6fTimothy Arceri      if (strlen(whole_program->data->InfoLog) > 0) {
54968c23d2d046b6419c7b3bd273278235095e29daeAlejandro Piñeiro         printf("\n");
55068c23d2d046b6419c7b3bd273278235095e29daeAlejandro Piñeiro         if (!options->just_log)
55168c23d2d046b6419c7b3bd273278235095e29daeAlejandro Piñeiro            printf("Info log for linking:\n");
552203c8794a1debc0e45019fe945d1cc55459e6c6fTimothy Arceri         printf("%s", whole_program->data->InfoLog);
55368c23d2d046b6419c7b3bd273278235095e29daeAlejandro Piñeiro         if (!options->just_log)
55468c23d2d046b6419c7b3bd273278235095e29daeAlejandro Piñeiro            printf("\n");
55568c23d2d046b6419c7b3bd273278235095e29daeAlejandro Piñeiro      }
5560f982bb67d64673f73096f7c536a5e29756c5c6fRob Clark
5570f982bb67d64673f73096f7c536a5e29756c5c6fRob Clark      for (unsigned i = 0; i < MESA_SHADER_STAGES; i++) {
5581fb8c6df884c2a17cf980c4ea32db4c214903b55Timothy Arceri         struct gl_linked_shader *shader = whole_program->_LinkedShaders[i];
5590f982bb67d64673f73096f7c536a5e29756c5c6fRob Clark
5600f982bb67d64673f73096f7c536a5e29756c5c6fRob Clark         if (!shader)
5610f982bb67d64673f73096f7c536a5e29756c5c6fRob Clark            continue;
5620f982bb67d64673f73096f7c536a5e29756c5c6fRob Clark
563f45a2a93aea0a57cf0aa8ee9ca062fcc42407a44Ian Romanick         add_neg_to_sub_visitor v;
564f45a2a93aea0a57cf0aa8ee9ca062fcc42407a44Ian Romanick         visit_list_elements(&v, shader->ir);
565f45a2a93aea0a57cf0aa8ee9ca062fcc42407a44Ian Romanick
5664dc759c8c236e725ff7bbd439e19eada12bf390fIan Romanick         dead_variable_visitor dv;
5674dc759c8c236e725ff7bbd439e19eada12bf390fIan Romanick         visit_list_elements(&dv, shader->ir);
5684dc759c8c236e725ff7bbd439e19eada12bf390fIan Romanick         dv.remove_dead_variables();
5690f982bb67d64673f73096f7c536a5e29756c5c6fRob Clark      }
570e9acae8486fff4f9fe6aa111c6fa5652ebb9f8bfIan Romanick
571e9acae8486fff4f9fe6aa111c6fa5652ebb9f8bfIan Romanick      if (options->dump_builder) {
572e9acae8486fff4f9fe6aa111c6fa5652ebb9f8bfIan Romanick         for (unsigned i = 0; i < MESA_SHADER_STAGES; i++) {
573e9acae8486fff4f9fe6aa111c6fa5652ebb9f8bfIan Romanick            struct gl_linked_shader *shader = whole_program->_LinkedShaders[i];
574e9acae8486fff4f9fe6aa111c6fa5652ebb9f8bfIan Romanick
575e9acae8486fff4f9fe6aa111c6fa5652ebb9f8bfIan Romanick            if (!shader)
576e9acae8486fff4f9fe6aa111c6fa5652ebb9f8bfIan Romanick               continue;
577e9acae8486fff4f9fe6aa111c6fa5652ebb9f8bfIan Romanick
578e9acae8486fff4f9fe6aa111c6fa5652ebb9f8bfIan Romanick            _mesa_print_builder_for_ir(stdout, shader->ir);
579e9acae8486fff4f9fe6aa111c6fa5652ebb9f8bfIan Romanick         }
580e9acae8486fff4f9fe6aa111c6fa5652ebb9f8bfIan Romanick      }
5810f982bb67d64673f73096f7c536a5e29756c5c6fRob Clark   }
5820f982bb67d64673f73096f7c536a5e29756c5c6fRob Clark
5830f982bb67d64673f73096f7c536a5e29756c5c6fRob Clark   return whole_program;
5840f982bb67d64673f73096f7c536a5e29756c5c6fRob Clark
5850f982bb67d64673f73096f7c536a5e29756c5c6fRob Clarkfail:
5860c85d2fea406df033c27201ba5e7257874a67a9aTimothy Arceri   for (unsigned i = 0; i < MESA_SHADER_STAGES; i++) {
5870c85d2fea406df033c27201ba5e7257874a67a9aTimothy Arceri      if (whole_program->_LinkedShaders[i])
5880c85d2fea406df033c27201ba5e7257874a67a9aTimothy Arceri         ralloc_free(whole_program->_LinkedShaders[i]->Program);
5890c85d2fea406df033c27201ba5e7257874a67a9aTimothy Arceri   }
5900c85d2fea406df033c27201ba5e7257874a67a9aTimothy Arceri
5910f982bb67d64673f73096f7c536a5e29756c5c6fRob Clark   ralloc_free(whole_program);
5920f982bb67d64673f73096f7c536a5e29756c5c6fRob Clark   return NULL;
5930f982bb67d64673f73096f7c536a5e29756c5c6fRob Clark}
5940f982bb67d64673f73096f7c536a5e29756c5c6fRob Clark
5950f982bb67d64673f73096f7c536a5e29756c5c6fRob Clarkextern "C" void
5960f982bb67d64673f73096f7c536a5e29756c5c6fRob Clarkstandalone_compiler_cleanup(struct gl_shader_program *whole_program)
5970f982bb67d64673f73096f7c536a5e29756c5c6fRob Clark{
5980c85d2fea406df033c27201ba5e7257874a67a9aTimothy Arceri   for (unsigned i = 0; i < MESA_SHADER_STAGES; i++) {
5990c85d2fea406df033c27201ba5e7257874a67a9aTimothy Arceri      if (whole_program->_LinkedShaders[i])
6000c85d2fea406df033c27201ba5e7257874a67a9aTimothy Arceri         ralloc_free(whole_program->_LinkedShaders[i]->Program);
6010c85d2fea406df033c27201ba5e7257874a67a9aTimothy Arceri   }
6020f982bb67d64673f73096f7c536a5e29756c5c6fRob Clark
6030f982bb67d64673f73096f7c536a5e29756c5c6fRob Clark   delete whole_program->AttributeBindings;
6040f982bb67d64673f73096f7c536a5e29756c5c6fRob Clark   delete whole_program->FragDataBindings;
6050f982bb67d64673f73096f7c536a5e29756c5c6fRob Clark   delete whole_program->FragDataIndexBindings;
6060f982bb67d64673f73096f7c536a5e29756c5c6fRob Clark
6070f982bb67d64673f73096f7c536a5e29756c5c6fRob Clark   ralloc_free(whole_program);
6080f982bb67d64673f73096f7c536a5e29756c5c6fRob Clark   _mesa_glsl_release_types();
6090f982bb67d64673f73096f7c536a5e29756c5c6fRob Clark   _mesa_glsl_release_builtin_functions();
6100f982bb67d64673f73096f7c536a5e29756c5c6fRob Clark}
611