mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-05-05 05:18:08 +02:00
stand-alone GLSL compiler
This commit is contained in:
parent
501ee87180
commit
cc153541a2
3 changed files with 397 additions and 0 deletions
44
src/mesa/drivers/glslcompiler/Makefile
Normal file
44
src/mesa/drivers/glslcompiler/Makefile
Normal file
|
|
@ -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)
|
||||
BIN
src/mesa/drivers/glslcompiler/glslcompiler
Executable file
BIN
src/mesa/drivers/glslcompiler/glslcompiler
Executable file
Binary file not shown.
353
src/mesa/drivers/glslcompiler/glslcompiler.c
Normal file
353
src/mesa/drivers/glslcompiler/glslcompiler.c
Normal file
|
|
@ -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;
|
||||
}
|
||||
Loading…
Add table
Reference in a new issue