Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | RSS feed

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