diff options
| -rw-r--r-- | src/mesa/drivers/glslcompiler/Makefile | 44 | ||||
| -rwxr-xr-x | src/mesa/drivers/glslcompiler/glslcompiler | bin | 0 -> 15243624 bytes | |||
| -rw-r--r-- | src/mesa/drivers/glslcompiler/glslcompiler.c | 353 | 
3 files changed, 397 insertions, 0 deletions
| diff --git a/src/mesa/drivers/glslcompiler/Makefile b/src/mesa/drivers/glslcompiler/Makefile new file mode 100644 index 0000000000..858457ddd4 --- /dev/null +++ b/src/mesa/drivers/glslcompiler/Makefile @@ -0,0 +1,44 @@ +# Makefile for stand-alone GL-SL compiler + +TOP = ../../../.. + +include $(TOP)/configs/current + + +PROGRAM = glslcompiler + +OBJECTS = \ +	glslcompiler.o \ +	../../glapi/glapi.o \ +	../../glapi/glthread.o \ +	../../main/dispatch.o \ +	../common/driverfuncs.o \ +	../../libmesa.a + +INCLUDES = \ +	-I$(TOP)/include \ +	-I$(TOP)/include/GL/internal \ +	-I$(TOP)/src/mesa \ +	-I$(TOP)/src/mesa/main \ +	-I$(TOP)/src/mesa/glapi \ +	-I$(TOP)/src/mesa/math \ +	-I$(TOP)/src/mesa/transform \ +	-I$(TOP)/src/mesa/shader \ +	-I$(TOP)/src/mesa/swrast \ +	-I$(TOP)/src/mesa/swrast_setup \ + + +default: $(PROGRAM) +	$(INSTALL) $(PROGRAM) $(TOP)/bin + + +glslcompiler: $(OBJECTS) +	$(CC) $(OBJECTS) -lm -lpthread -o $@ + + +glslcompiler.o: glslcompiler.c +	$(CC) -c $(CFLAGS) $(INCLUDES) glslcompiler.c -o $@ + + +clean: +	rm -f *.o *~ $(PROGRAM) diff --git a/src/mesa/drivers/glslcompiler/glslcompiler b/src/mesa/drivers/glslcompiler/glslcompilerBinary files differ new file mode 100755 index 0000000000..a9d15e8721 --- /dev/null +++ b/src/mesa/drivers/glslcompiler/glslcompiler diff --git a/src/mesa/drivers/glslcompiler/glslcompiler.c b/src/mesa/drivers/glslcompiler/glslcompiler.c new file mode 100644 index 0000000000..a27f749df7 --- /dev/null +++ b/src/mesa/drivers/glslcompiler/glslcompiler.c @@ -0,0 +1,353 @@ +/* + * Mesa 3-D graphics library + * Version:  6.5.3 + * + * Copyright (C) 1999-2007  Brian Paul, Tungsten Graphics, Inc. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL + * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN + * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +/** + * \mainpage + * + * Stand-alone Shading Language compiler.   + * Basically, a command-line program which accepts GLSL shaders and emits + * vertex/fragment programs (GPU instructions). + * + * This file is basically just a Mesa device driver but instead of building + * a shared library we build an executable. + * + * We can emit programs in three different formats: + *  1. ARB-style (GL_ARB_vertex/fragment_program) + *  2. NV-style (GL_NV_vertex/fragment_program) + *  3. debug-style (a slightly more sophisticated, internal format) + * + * Note that the ARB and NV program languages can't express all the + * features that might be used by a fragment program (examples being + * uniform and varying vars).  So, the ARB/NV programs that are + * emitted aren't always legal programs in those languages. + */ + + +#include "imports.h" +#include "context.h" +#include "extensions.h" +#include "framebuffer.h" +#include "shaders.h" +#include "shader/shader_api.h" +#include "shader/prog_print.h" +#include "drivers/common/driverfuncs.h" +#include "array_cache/acache.h" +#include "tnl/tnl.h" +#include "tnl/t_context.h" +#include "tnl/t_pipeline.h" +#include "swrast/swrast.h" +#include "swrast/s_context.h" +#include "swrast/s_triangle.h" +#include "swrast_setup/swrast_setup.h" + + +static const char *Prog = "glslcompiler"; + + +struct options { +   GLboolean LineNumbers; +   gl_prog_print_mode Mode; +   const char *VertFile; +   const char *FragFile; +   const char *OutputFile; +}; + +static struct options Options; + + +/** + * GLSL compiler driver context. (kind of an artificial thing for now) + */ +struct compiler_context +{ +   GLcontext MesaContext; +   int foo; +}; + +typedef struct compiler_context CompilerContext; + + + +static void +UpdateState(GLcontext *ctx, GLuint new_state) +{ +   /* easy - just propogate */ +   _swrast_InvalidateState( ctx, new_state ); +   _swsetup_InvalidateState( ctx, new_state ); +   _ac_InvalidateState( ctx, new_state ); +   _tnl_InvalidateState( ctx, new_state ); +} + + + +static GLboolean +CreateContext(void) +{ +   struct dd_function_table ddFuncs; +   GLvisual *vis; +   GLframebuffer *buf; +   GLcontext *ctx; +   CompilerContext *cc; + +   vis = _mesa_create_visual(GL_TRUE, GL_FALSE, GL_FALSE, /* RGB */ +                             8, 8, 8, 8,  /* color */ +                             0, 0, 0,  /* z, stencil */ +                             0, 0, 0, 0, 1);  /* accum */ +   buf = _mesa_create_framebuffer(vis); + +   cc = _mesa_calloc(sizeof(*cc)); +   if (!vis || !buf || !cc) { +      if (vis) +         _mesa_destroy_visual(vis); +      if (buf) +         _mesa_destroy_framebuffer(buf); +      return GL_FALSE; +   } + +   _mesa_init_driver_functions(&ddFuncs); +   ddFuncs.GetString = NULL;/*get_string;*/ +   ddFuncs.UpdateState = UpdateState; +   ddFuncs.GetBufferSize = NULL; + +   ctx = &cc->MesaContext; +   _mesa_initialize_context(ctx, vis, NULL, &ddFuncs, cc); +   _mesa_enable_sw_extensions(ctx); + +   if (!_swrast_CreateContext( ctx ) || +       !_ac_CreateContext( ctx ) || +       !_tnl_CreateContext( ctx ) || +       !_swsetup_CreateContext( ctx )) { +      _mesa_destroy_visual(vis); +      _mesa_free_context_data(ctx); +      _mesa_free(cc); +      return GL_FALSE; +   } +   TNL_CONTEXT(ctx)->Driver.RunPipeline = _tnl_run_pipeline; +   _swsetup_Wakeup( ctx ); + +   _mesa_make_current(ctx, buf, buf); + +   return GL_TRUE; +} + + +static void +LoadAndCompileShader(GLuint shader, const char *text) +{ +   GLint stat; +   _mesa_ShaderSourceARB(shader, 1, (const GLchar **) &text, NULL); +   _mesa_CompileShaderARB(shader); +   _mesa_GetShaderiv(shader, GL_COMPILE_STATUS, &stat); +   if (!stat) { +      GLchar log[1000]; +      GLsizei len; +      _mesa_GetShaderInfoLog(shader, 1000, &len, log); +      fprintf(stderr, "%s: problem compiling shader: %s\n", Prog, log); +      exit(1); +   } +   else { +      printf("Shader compiled OK\n"); +   } +} + + +/** + * Read a shader from a file. + */ +static void +ReadShader(GLuint shader, const char *filename) +{ +   const int max = 100*1000; +   int n; +   char *buffer = (char*) malloc(max); +   FILE *f = fopen(filename, "r"); +   if (!f) { +      fprintf(stderr, "%s: Unable to open shader file %s\n", Prog, filename); +      exit(1); +   } + +   n = fread(buffer, 1, max, f); +   /* +   printf("%s: read %d bytes from shader file %s\n", Prog, n, filename); +   */ +   if (n > 0) { +      buffer[n] = 0; +      LoadAndCompileShader(shader, buffer); +   } + +   fclose(f); +   free(buffer); +} + + +#if 0 +static void +CheckLink(GLuint prog) +{ +   GLint stat; +   _mesa_GetProgramiv(prog, GL_LINK_STATUS, &stat); +   if (!stat) { +      GLchar log[1000]; +      GLsizei len; +      _mesa_GetProgramInfoLog(prog, 1000, &len, log); +      fprintf(stderr, "%s: Linker error:\n%s\n", Prog, log); +   } +   else { +      fprintf(stderr, "%s: Link success!\n", Prog); +   } +} +#endif + + +static void +PrintShaderInstructions(GLuint shader, FILE *f) +{ +   GET_CURRENT_CONTEXT(ctx); +   struct gl_shader *sh = _mesa_lookup_shader(ctx, shader); +   GLuint i; + +   for (i = 0; i < sh->NumPrograms; i++) { +      struct gl_program *prog = sh->Programs[i]; +      _mesa_print_program_opt(prog, Options.Mode, Options.LineNumbers); +   } +} + + +static GLuint +CompileShader(const char *filename, GLenum type) +{ +   GLuint shader; + +   assert(type == GL_FRAGMENT_SHADER || +          type == GL_VERTEX_SHADER); + +   shader = _mesa_CreateShader(type); +   ReadShader(shader, filename); + +   return shader; +} + + +static void +Usage(void) +{ +   printf("Mesa GLSL stand-alone compiler\n"); +   printf("Usage:\n"); +   printf("  --vs FILE          vertex shader input filename\n"); +   printf("  --fs FILE          fragment shader input filename\n"); +   printf("  --arb              emit ARB-style instructions (the default)\n"); +   printf("  --nv               emit NV-style instructions\n"); +   printf("  --debug            emit debug-style instructions\n"); +   printf("  --number, -n       emit line numbers\n"); +   printf("  --output, -o FILE  output filename\n"); +   printf("  --help             display this information\n"); +} + + +static void +ParseOptions(int argc, char *argv[]) +{ +   int i; + +   Options.LineNumbers = GL_FALSE; +   Options.Mode = PROG_PRINT_ARB; +   Options.VertFile = NULL; +   Options.FragFile = NULL; +   Options.OutputFile = NULL; + +   for (i = 1; i < argc; i++) { +      if (strcmp(argv[i], "--vs") == 0) { +         Options.VertFile = argv[i + 1]; +         i++; +      } +      else if (strcmp(argv[i], "--fs") == 0) { +         Options.FragFile = argv[i + 1]; +         i++; +      } +      else if (strcmp(argv[i], "--arb") == 0) { +         Options.Mode = PROG_PRINT_ARB; +      } +      else if (strcmp(argv[i], "--nv") == 0) { +         Options.Mode = PROG_PRINT_NV; +      } +      else if (strcmp(argv[i], "--debug") == 0) { +         Options.Mode = PROG_PRINT_DEBUG; +      } +      else if (strcmp(argv[i], "--number") == 0 || +               strcmp(argv[i], "-n") == 0) { +         Options.LineNumbers = GL_TRUE; +      } +      else if (strcmp(argv[i], "--output") == 0 || +               strcmp(argv[i], "-o") == 0) { +         Options.OutputFile = argv[i + 1]; +         i++; +      } +      else if (strcmp(argv[i], "--help") == 0) { +         Usage(); +         exit(0); +      } +      else { +         printf("Unknown option: %s\n", argv[i]); +         Usage(); +         exit(1); +      } +   } +} + + +int +main(int argc, char *argv[]) +{ +   GLuint shader = 0; + +   if (!CreateContext()) { +      fprintf(stderr, "%s: Failed to create compiler context\n", Prog); +      exit(1); +   } + +   ParseOptions(argc, argv); + +   if (Options.VertFile) { +      shader = CompileShader(Options.VertFile, GL_VERTEX_SHADER); +   } +   else if (Options.FragFile) { +      shader = CompileShader(Options.FragFile, GL_FRAGMENT_SHADER); +   } + +   if (shader) { +      if (Options.OutputFile) { +         fclose(stdout); +         /*stdout =*/ freopen(Options.OutputFile, "w", stdout); +      } +      if (stdout) { +         PrintShaderInstructions(shader, stdout); +      } +      if (Options.OutputFile) { +         fclose(stdout); +      } +   } + +   return 0; +} | 
