diff options
author | Brian <[email protected]> | 2007-02-20 08:04:40 -0700 |
---|---|---|
committer | Brian <[email protected]> | 2007-02-20 08:04:40 -0700 |
commit | 3d001b81c23dc1981cd5f4b0885d935d2c9a098b (patch) | |
tree | 7fbfcea0358a7c4cad634860d9bf8342e0782055 | |
parent | d434019633ccc537f07ec4e7d409bc93134367c8 (diff) | |
parent | 9449a4d8945de684609663468b96b7ed3aa884b9 (diff) |
Merge branch 'glsl-compiler-1' of git+ssh://[email protected]/git/mesa/mesa into glsl-compiler-1
36 files changed, 2604 insertions, 1692 deletions
diff --git a/docs/shading.html b/docs/shading.html index c4962a32a2f..28bd645c5d5 100644 --- a/docs/shading.html +++ b/docs/shading.html @@ -15,9 +15,21 @@ OpenGL Shading Language</a>. </p> <p> -Last updated on 20 Jan 2007. +Last updated on 17 Feb 2007. </p> +<p> +Contents +</p> +<ul> +<li><a href="#unsup">Unsupported Features</a> +<li><a href="#impl">Implementation Notes</a> +<li><a href="#hints">Programming Hints</a> +<li><a href="#standalone">Stand-alone Compiler</a> +</ul> + + +<a name="unsup"> <h2>Unsupported Features</h2> <p> @@ -41,6 +53,7 @@ All other major features of the shading language should function. </p> +<a name="impl"> <h2>Implementation Notes</h2> <ul> @@ -63,6 +76,7 @@ These issues will be addressed/resolved in the future. </p> +<a name="hints"> <h2>Programming Hints</h2> <ul> @@ -111,5 +125,64 @@ These issues will be addressed/resolved in the future. </ul> +<a name="standalone"> +<h2>Stand-alone Compiler</h2> + +<p> +A unique stand-alone GLSL compiler driver has been added to Mesa. +<p> + +<p> +The stand-alone compiler (like a conventional command-line compiler) +is a tool that accepts Shading Language programs and emits low-level +GPU programs. +</p> + +<p> +This tool is useful for: +<p> +<ul> +<li>Inspecting GPU code to gain insight into compilation +<li>Generating initial GPU code for subsequent hand-tuning +<li>Debugging the GLSL compiler itself +</ul> + +<p> +(compiler build instructions TBD) +</p> + +<p> +Here's an example of using the compiler to compile a vertex shader and +emit GL_ARB_vertex_program-style instructions: +</p> +<pre> + glslcompiler --arb --linenumbers --vs vertshader.txt +</pre> +<p> +The output may look similar to this: +</p> +<pre> +!!ARBvp1.0 + 0: MOV result.texcoord[0], vertex.texcoord[0]; + 1: DP4 temp0.x, state.matrix.mvp.row[0], vertex.position; + 2: DP4 temp0.y, state.matrix.mvp.row[1], vertex.position; + 3: DP4 temp0.z, state.matrix.mvp.row[2], vertex.position; + 4: DP4 temp0.w, state.matrix.mvp.row[3], vertex.position; + 5: MOV result.position, temp0; + 6: END +</pre> + +<p> +Note that some shading language constructs (such as uniform and varying +variables) aren't expressible in ARB or NV-style programs. +Therefore, the resulting output is not always legal by definition of +those program languages. +</p> +<p> +Also note that this compiler driver is still under development. +Over time, the correctness of the GPU programs, with respect to the ARB +and NV languagues, should improve. +</p> + </BODY> </HTML> diff --git a/src/mesa/drivers/glslcompiler/Makefile b/src/mesa/drivers/glslcompiler/Makefile new file mode 100644 index 00000000000..858457ddd40 --- /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/glslcompiler Binary files differnew file mode 100755 index 00000000000..a9d15e87215 --- /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 00000000000..a27f749df7f --- /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; +} diff --git a/src/mesa/shader/prog_debug.c b/src/mesa/shader/prog_debug.c new file mode 100644 index 00000000000..e3e5396bb17 --- /dev/null +++ b/src/mesa/shader/prog_debug.c @@ -0,0 +1,265 @@ +/* + * Mesa 3-D graphics library + * Version: 6.5.3 + * + * Copyright (C) 1999-2007 Brian Paul 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. + */ + + +#include "glheader.h" +#include "context.h" +#include "macros.h" +#include "nvfragparse.h" +#include "nvvertparse.h" +#include "program.h" +#include "prog_debug.h" +#include "prog_parameter.h" +#include "prog_instruction.h" + + + +/** + * Functions for the experimental GL_MESA_program_debug extension. + */ + + +/* XXX temporary */ +GLAPI void GLAPIENTRY +glProgramCallbackMESA(GLenum target, GLprogramcallbackMESA callback, + GLvoid *data) +{ + _mesa_ProgramCallbackMESA(target, callback, data); +} + + +void +_mesa_ProgramCallbackMESA(GLenum target, GLprogramcallbackMESA callback, + GLvoid *data) +{ + GET_CURRENT_CONTEXT(ctx); + + switch (target) { + case GL_FRAGMENT_PROGRAM_ARB: + if (!ctx->Extensions.ARB_fragment_program) { + _mesa_error(ctx, GL_INVALID_ENUM, "glProgramCallbackMESA(target)"); + return; + } + ctx->FragmentProgram.Callback = callback; + ctx->FragmentProgram.CallbackData = data; + break; + case GL_FRAGMENT_PROGRAM_NV: + if (!ctx->Extensions.NV_fragment_program) { + _mesa_error(ctx, GL_INVALID_ENUM, "glProgramCallbackMESA(target)"); + return; + } + ctx->FragmentProgram.Callback = callback; + ctx->FragmentProgram.CallbackData = data; + break; + case GL_VERTEX_PROGRAM_ARB: /* == GL_VERTEX_PROGRAM_NV */ + if (!ctx->Extensions.ARB_vertex_program && + !ctx->Extensions.NV_vertex_program) { + _mesa_error(ctx, GL_INVALID_ENUM, "glProgramCallbackMESA(target)"); + return; + } + ctx->VertexProgram.Callback = callback; + ctx->VertexProgram.CallbackData = data; + break; + default: + _mesa_error(ctx, GL_INVALID_ENUM, "glProgramCallbackMESA(target)"); + return; + } +} + + +/* XXX temporary */ +GLAPI void GLAPIENTRY +glGetProgramRegisterfvMESA(GLenum target, + GLsizei len, const GLubyte *registerName, + GLfloat *v) +{ + _mesa_GetProgramRegisterfvMESA(target, len, registerName, v); +} + + +void +_mesa_GetProgramRegisterfvMESA(GLenum target, + GLsizei len, const GLubyte *registerName, + GLfloat *v) +{ + char reg[1000]; + GET_CURRENT_CONTEXT(ctx); + + /* We _should_ be inside glBegin/glEnd */ +#if 0 + if (ctx->Driver.CurrentExecPrimitive == PRIM_OUTSIDE_BEGIN_END) { + _mesa_error(ctx, GL_INVALID_OPERATION, "glGetProgramRegisterfvMESA"); + return; + } +#endif + + /* make null-terminated copy of registerName */ + len = MIN2((unsigned int) len, sizeof(reg) - 1); + _mesa_memcpy(reg, registerName, len); + reg[len] = 0; + + switch (target) { + case GL_VERTEX_PROGRAM_ARB: /* == GL_VERTEX_PROGRAM_NV */ + if (!ctx->Extensions.ARB_vertex_program && + !ctx->Extensions.NV_vertex_program) { + _mesa_error(ctx, GL_INVALID_ENUM, + "glGetProgramRegisterfvMESA(target)"); + return; + } + if (!ctx->VertexProgram._Enabled) { + _mesa_error(ctx, GL_INVALID_OPERATION, + "glGetProgramRegisterfvMESA"); + return; + } + /* GL_NV_vertex_program */ + if (reg[0] == 'R') { + /* Temp register */ + GLint i = _mesa_atoi(reg + 1); + if (i >= (GLint)ctx->Const.VertexProgram.MaxTemps) { + _mesa_error(ctx, GL_INVALID_VALUE, + "glGetProgramRegisterfvMESA(registerName)"); + return; + } +#if 0 /* FIX ME */ + ctx->Driver.GetVertexProgramRegister(ctx, PROGRAM_TEMPORARY, i, v); +#endif + } + else if (reg[0] == 'v' && reg[1] == '[') { + /* Vertex Input attribute */ + GLuint i; + for (i = 0; i < ctx->Const.VertexProgram.MaxAttribs; i++) { + const char *name = _mesa_nv_vertex_input_register_name(i); + char number[10]; + _mesa_sprintf(number, "%d", i); + if (_mesa_strncmp(reg + 2, name, 4) == 0 || + _mesa_strncmp(reg + 2, number, _mesa_strlen(number)) == 0) { +#if 0 /* FIX ME */ + ctx->Driver.GetVertexProgramRegister(ctx, PROGRAM_INPUT, + i, v); +#endif + return; + } + } + _mesa_error(ctx, GL_INVALID_VALUE, + "glGetProgramRegisterfvMESA(registerName)"); + return; + } + else if (reg[0] == 'o' && reg[1] == '[') { + /* Vertex output attribute */ + } + /* GL_ARB_vertex_program */ + else if (_mesa_strncmp(reg, "vertex.", 7) == 0) { + + } + else { + _mesa_error(ctx, GL_INVALID_VALUE, + "glGetProgramRegisterfvMESA(registerName)"); + return; + } + break; + case GL_FRAGMENT_PROGRAM_ARB: + if (!ctx->Extensions.ARB_fragment_program) { + _mesa_error(ctx, GL_INVALID_ENUM, + "glGetProgramRegisterfvMESA(target)"); + return; + } + if (!ctx->FragmentProgram._Enabled) { + _mesa_error(ctx, GL_INVALID_OPERATION, + "glGetProgramRegisterfvMESA"); + return; + } + /* XXX to do */ + break; + case GL_FRAGMENT_PROGRAM_NV: + if (!ctx->Extensions.NV_fragment_program) { + _mesa_error(ctx, GL_INVALID_ENUM, + "glGetProgramRegisterfvMESA(target)"); + return; + } + if (!ctx->FragmentProgram._Enabled) { + _mesa_error(ctx, GL_INVALID_OPERATION, + "glGetProgramRegisterfvMESA"); + return; + } + if (reg[0] == 'R') { + /* Temp register */ + GLint i = _mesa_atoi(reg + 1); + if (i >= (GLint)ctx->Const.FragmentProgram.MaxTemps) { + _mesa_error(ctx, GL_INVALID_VALUE, + "glGetProgramRegisterfvMESA(registerName)"); + return; + } + ctx->Driver.GetFragmentProgramRegister(ctx, PROGRAM_TEMPORARY, + i, v); + } + else if (reg[0] == 'f' && reg[1] == '[') { + /* Fragment input attribute */ + GLuint i; + for (i = 0; i < ctx->Const.FragmentProgram.MaxAttribs; i++) { + const char *name = _mesa_nv_fragment_input_register_name(i); + if (_mesa_strncmp(reg + 2, name, 4) == 0) { + ctx->Driver.GetFragmentProgramRegister(ctx, + PROGRAM_INPUT, i, v); + return; + } + } + _mesa_error(ctx, GL_INVALID_VALUE, + "glGetProgramRegisterfvMESA(registerName)"); + return; + } + else if (_mesa_strcmp(reg, "o[COLR]") == 0) { + /* Fragment output color */ + ctx->Driver.GetFragmentProgramRegister(ctx, PROGRAM_OUTPUT, + FRAG_RESULT_COLR, v); + } + else if (_mesa_strcmp(reg, "o[COLH]") == 0) { + /* Fragment output color */ + ctx->Driver.GetFragmentProgramRegister(ctx, PROGRAM_OUTPUT, + FRAG_RESULT_COLH, v); + } + else if (_mesa_strcmp(reg, "o[DEPR]") == 0) { + /* Fragment output depth */ + ctx->Driver.GetFragmentProgramRegister(ctx, PROGRAM_OUTPUT, + FRAG_RESULT_DEPR, v); + } + else { + /* try user-defined identifiers */ + const GLfloat *value = _mesa_lookup_parameter_value( + ctx->FragmentProgram.Current->Base.Parameters, -1, reg); + if (value) { + COPY_4V(v, value); + } + else { + _mesa_error(ctx, GL_INVALID_VALUE, + "glGetProgramRegisterfvMESA(registerName)"); + return; + } + } + break; + default: + _mesa_error(ctx, GL_INVALID_ENUM, + "glGetProgramRegisterfvMESA(target)"); + return; + } +} diff --git a/src/mesa/shader/prog_debug.h b/src/mesa/shader/prog_debug.h new file mode 100644 index 00000000000..fc400e19de1 --- /dev/null +++ b/src/mesa/shader/prog_debug.h @@ -0,0 +1,44 @@ +/* + * Mesa 3-D graphics library + * Version: 6.5.3 + * + * Copyright (C) 1999-2007 Brian Paul 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. + */ + + +#ifndef PROG_DEBUG_H +#define PROG_DEBUG_H 1 + + +/* + * GL_MESA_program_debug + */ + +extern void +_mesa_ProgramCallbackMESA(GLenum target, GLprogramcallbackMESA callback, + GLvoid *data); + +extern void +_mesa_GetProgramRegisterfvMESA(GLenum target, GLsizei len, + const GLubyte *registerName, GLfloat *v); + + + +#endif /* PROG_DEBUG_H */ diff --git a/src/mesa/shader/prog_instruction.h b/src/mesa/shader/prog_instruction.h index a9156bcad59..05265ce0ab1 100644 --- a/src/mesa/shader/prog_instruction.h +++ b/src/mesa/shader/prog_instruction.h @@ -405,7 +405,7 @@ struct prog_instruction * For IF, points to else or endif. * For ELSE, points to endif. */ - GLuint BranchTarget; + GLint BranchTarget; /** * For TEX instructions in shaders, the sampler to use for the diff --git a/src/mesa/shader/prog_parameter.c b/src/mesa/shader/prog_parameter.c index a87dafc598c..3ebd559119c 100644 --- a/src/mesa/shader/prog_parameter.c +++ b/src/mesa/shader/prog_parameter.c @@ -131,6 +131,10 @@ _mesa_add_parameter(struct gl_program_parameter_list *paramList, COPY_4V(paramList->ParameterValues[oldNum + i], values); values += 4; } + else { + /* silence valgrind */ + ASSIGN_4V(paramList->ParameterValues[oldNum + i], 0, 0, 0, 0); + } size -= 4; } @@ -493,17 +497,28 @@ _mesa_lookup_parameter_constant(const struct gl_program_parameter_list *list, } } } - else if (list->Parameters[i].Size >= vSize) { - /* see if we can match this constant */ - GLuint match = 0, j; + else if (vSize <= list->Parameters[i].Size) { + /* see if we can match this constant (with a swizzle) */ + GLuint swz[4]; + GLuint match = 0, j, k; for (j = 0; j < vSize; j++) { - if (list->ParameterValues[i][j] == v[j]) { + if (v[j] == list->ParameterValues[i][j]) { + swz[j] = j; match++; } + else { + for (k = 0; k < list->Parameters[i].Size; k++) { + if (v[j] == list->ParameterValues[i][k]) { + swz[j] = k; + match++; + break; + } + } + } } if (match == vSize) { *posOut = i; - *swizzleOut = SWIZZLE_NOOP; + *swizzleOut = MAKE_SWIZZLE4(swz[0], swz[1], swz[2], swz[3]); return GL_TRUE; } } diff --git a/src/mesa/shader/prog_print.c b/src/mesa/shader/prog_print.c index 3d4a474b052..9560ffad7da 100644 --- a/src/mesa/shader/prog_print.c +++ b/src/mesa/shader/prog_print.c @@ -37,11 +37,12 @@ #include "prog_statevars.h" + /** * Return string name for given program/register file. */ static const char * -program_file_string(enum register_file f) +file_string(enum register_file f, gl_prog_print_mode mode) { switch (f) { case PROGRAM_TEMPORARY: @@ -77,6 +78,213 @@ program_file_string(enum register_file f) /** + * Return ARB_v/f_prog-style input attrib string. + */ +static const char * +arb_input_attrib_string(GLint index, GLenum progType) +{ + const char *vertAttribs[] = { + "vertex.position", + "vertex.weight", + "vertex.normal", + "vertex.color.primary", + "vertex.color.secondary", + "vertex.fogcoord", + "vertex.(six)", + "vertex.(seven)", + "vertex.texcoord[0]", + "vertex.texcoord[1]", + "vertex.texcoord[2]", + "vertex.texcoord[3]", + "vertex.texcoord[4]", + "vertex.texcoord[5]", + "vertex.texcoord[6]", + "vertex.texcoord[7]" + }; + const char *fragAttribs[] = { + "fragment.position", + "fragment.color.primary", + "fragment.color.secondary", + "fragment.fogcoord", + "fragment.texcoord[0]", + "fragment.texcoord[1]", + "fragment.texcoord[2]", + "fragment.texcoord[3]", + "fragment.texcoord[4]", + "fragment.texcoord[5]", + "fragment.texcoord[6]", + "fragment.texcoord[7]", + "fragment.varying[0]", + "fragment.varying[1]", + "fragment.varying[2]", + "fragment.varying[3]", + "fragment.varying[4]", + "fragment.varying[5]", + "fragment.varying[6]", + "fragment.varying[7]" + }; + + if (progType == GL_VERTEX_PROGRAM_ARB) { + assert(index < sizeof(vertAttribs) / sizeof(vertAttribs[0])); + return vertAttribs[index]; + } + else { + assert(index < sizeof(fragAttribs) / sizeof(fragAttribs[0])); + return fragAttribs[index]; + } +} + + +/** + * Return ARB_v/f_prog-style output attrib string. + */ +static const char * +arb_output_attrib_string(GLint index, GLenum progType) +{ + const char *vertResults[] = { + "result.position", + "result.color.primary", + "result.color.secondary", + "result.fogcoord", + "result.texcoord[0]", + "result.texcoord[1]", + "result.texcoord[2]", + "result.texcoord[3]", + "result.texcoord[4]", + "result.texcoord[5]", + "result.texcoord[6]", + "result.texcoord[7]", + "result.varying[0]", + "result.varying[1]", + "result.varying[2]", + "result.varying[3]", + "result.varying[4]", + "result.varying[5]", + "result.varying[6]", + "result.varying[7]" + }; + const char *fragResults[] = { + "result.color", + "result.depth" + }; + + if (progType == GL_VERTEX_PROGRAM_ARB) { + assert(index < sizeof(vertResults) / sizeof(vertResults[0])); + return vertResults[index]; + } + else { + assert(index < sizeof(fragResults) / sizeof(fragResults[0])); + return fragResults[index]; + } +} + + +/** + * Return string representation of the given register. + * Note that some types of registers (like PROGRAM_UNIFORM) aren't defined + * by the ARB/NV program languages so we've taken some liberties here. + * \param file the register file (PROGRAM_INPUT, PROGRAM_TEMPORARY, etc) + * \param index number of the register in the register file + * \param mode the output format/mode/style + * \param prog pointer to containing program + */ +static const char * +reg_string(enum register_file f, GLint index, gl_prog_print_mode mode, + const struct gl_program *prog) +{ + static char str[100]; + + str[0] = 0; + + switch (mode) { + case PROG_PRINT_DEBUG: + sprintf(str, "%s[%d]", file_string(f, mode), index); + break; + + case PROG_PRINT_ARB: + switch (f) { + case PROGRAM_INPUT: + sprintf(str, "%s", arb_input_attrib_string(index, prog->Target)); + break; + case PROGRAM_OUTPUT: + sprintf(str, "%s", arb_output_attrib_string(index, prog->Target)); + break; + case PROGRAM_TEMPORARY: + sprintf(str, "temp%d", index); + break; + case PROGRAM_ENV_PARAM: + sprintf(str, "program.env[%d]", index); + break; + case PROGRAM_LOCAL_PARAM: + sprintf(str, "program.local[%d]", index); + break; + case PROGRAM_VARYING: /* extension */ + sprintf(str, "varying[%d]", index); + break; + case PROGRAM_CONSTANT: /* extension */ + sprintf(str, "constant[%d]", index); + break; + case PROGRAM_UNIFORM: /* extension */ + sprintf(str, "uniform[%d]", index); + break; + case PROGRAM_STATE_VAR: + { + struct gl_program_parameter *param + = prog->Parameters->Parameters + index; + sprintf(str, _mesa_program_state_string(param->StateIndexes)); + } + break; + case PROGRAM_ADDRESS: + sprintf(str, "A%d", index); + break; + default: + _mesa_problem(NULL, "bad file in reg_string()"); + } + break; + + case PROG_PRINT_NV: + switch (f) { + case PROGRAM_INPUT: + if (prog->Target == GL_VERTEX_PROGRAM_ARB) + sprintf(str, "v[%d]", index); + else + sprintf(str, "f[%d]", index); + break; + case PROGRAM_OUTPUT: + sprintf(str, "o[%d]", index); + break; + case PROGRAM_TEMPORARY: + sprintf(str, "R%d", index); + break; + case PROGRAM_ENV_PARAM: + sprintf(str, "c[%d]", index); + break; + case PROGRAM_VARYING: /* extension */ + sprintf(str, "varying[%d]", index); + break; + case PROGRAM_UNIFORM: /* extension */ + sprintf(str, "uniform[%d]", index); + break; + case PROGRAM_CONSTANT: /* extension */ + sprintf(str, "constant[%d]", index); + break; + case PROGRAM_STATE_VAR: /* extension */ + sprintf(str, "state[%d]", index); + break; + default: + _mesa_problem(NULL, "bad file in reg_string()"); + } + break; + + default: + _mesa_problem(NULL, "bad mode in reg_string()"); + } + + return str; +} + + +/** * Return a string representation of the given swizzle word. * If extended is true, use extended (comma-separated) format. * \param swizzle the swizzle field @@ -172,22 +380,38 @@ condcode_string(GLuint condcode) static void -print_dst_reg(const struct prog_dst_register *dstReg) +print_dst_reg(const struct prog_dst_register *dstReg, gl_prog_print_mode mode, + const struct gl_program *prog) { - _mesa_printf(" %s[%d]%s", - program_file_string((enum register_file) dstReg->File), + _mesa_printf("%s%s", + reg_string((enum register_file) dstReg->File, + dstReg->Index, mode, prog), + writemask_string(dstReg->WriteMask)); + +#if 0 + _mesa_printf("%s[%d]%s", + file_string((enum register_file) dstReg->File, mode), dstReg->Index, writemask_string(dstReg->WriteMask)); +#endif } static void -print_src_reg(const struct prog_src_register *srcReg) +print_src_reg(const struct prog_src_register *srcReg, gl_prog_print_mode mode, + const struct gl_program *prog) { + _mesa_printf("%s%s", + reg_string((enum register_file) srcReg->File, + srcReg->Index, mode, prog), + swizzle_string(srcReg->Swizzle, + srcReg->NegateBase, GL_FALSE)); +#if 0 _mesa_printf("%s[%d]%s", - program_file_string((enum register_file) srcReg->File), + file_string((enum register_file) srcReg->File, mode), srcReg->Index, swizzle_string(srcReg->Swizzle, srcReg->NegateBase, GL_FALSE)); +#endif } static void @@ -200,10 +424,11 @@ print_comment(const struct prog_instruction *inst) } -void -_mesa_print_alu_instruction(const struct prog_instruction *inst, - const char *opcode_string, - GLuint numRegs) +static void +print_alu_instruction(const struct prog_instruction *inst, + const char *opcode_string, GLuint numRegs, + gl_prog_print_mode mode, + const struct gl_program *prog) { GLuint j; @@ -215,8 +440,9 @@ _mesa_print_alu_instruction(const struct prog_instruction *inst, if (inst->SaturateMode == SATURATE_ZERO_ONE) _mesa_printf("_SAT"); + _mesa_printf(" "); if (inst->DstReg.File != PROGRAM_UNDEFINED) { - print_dst_reg(&inst->DstReg); + print_dst_reg(&inst->DstReg, mode, prog); } else { _mesa_printf(" ???"); @@ -226,7 +452,7 @@ _mesa_print_alu_instruction(const struct prog_instruction *inst, _mesa_printf(", "); for (j = 0; j < numRegs; j++) { - print_src_reg(inst->SrcReg + j); + print_src_reg(inst->SrcReg + j, mode, prog); if (j + 1 < numRegs) _mesa_printf(", "); } @@ -235,11 +461,21 @@ _mesa_print_alu_instruction(const struct prog_instruction *inst, } +void +_mesa_print_instruction(const struct prog_instruction *inst) +{ + /* note: 4th param should be ignored for PROG_PRINT_DEBUG */ + _mesa_print_instruction_opt(inst, 0, PROG_PRINT_DEBUG, NULL); +} + + /** * Print a single vertex/fragment program instruction. */ GLint -_mesa_print_instruction(const struct prog_instruction *inst, GLint indent) +_mesa_print_instruction_opt(const struct prog_instruction *inst, GLint indent, + gl_prog_print_mode mode, + const struct gl_program *prog) { GLuint i; @@ -260,7 +496,8 @@ _mesa_print_instruction(const struct prog_instruction *inst, GLint indent) if (inst->SrcReg[0].File != PROGRAM_UNDEFINED) { _mesa_printf(", "); _mesa_printf("%s[%d]%s", - program_file_string((enum register_file) inst->SrcReg[0].File), + file_string((enum register_file) inst->SrcReg[0].File, + mode), inst->SrcReg[0].Index, swizzle_string(inst->SrcReg[0].Swizzle, inst->SrcReg[0].NegateBase, GL_FALSE)); @@ -273,9 +510,11 @@ _mesa_print_instruction(const struct prog_instruction *inst, GLint indent) _mesa_printf("SWZ"); if (inst->SaturateMode == SATURATE_ZERO_ONE) _mesa_printf("_SAT"); - print_dst_reg(&inst->DstReg); + _mesa_printf(" "); + print_dst_reg(&inst->DstReg, mode, prog); _mesa_printf("%s[%d], %s", - program_file_string((enum register_file) inst->SrcReg[0].File), + file_string((enum register_file) inst->SrcReg[0].File, + mode), inst->SrcReg[0].Index, swizzle_string(inst->SrcReg[0].Swizzle, inst->SrcReg[0].NegateBase, GL_TRUE)); @@ -287,9 +526,10 @@ _mesa_print_instruction(const struct prog_instruction *inst, GLint indent) _mesa_printf("%s", _mesa_opcode_string(inst->Opcode)); if (inst->SaturateMode == SATURATE_ZERO_ONE) _mesa_printf("_SAT"); - print_dst_reg(&inst->DstReg); + _mesa_printf(" "); + print_dst_reg(&inst->DstReg, mode, prog); _mesa_printf(", "); - print_src_reg(&inst->SrcReg[0]); + print_src_reg(&inst->SrcReg[0], mode, prog); _mesa_printf(", texture[%d], ", inst->TexSrcUnit); switch (inst->TexSrcTarget) { case TEXTURE_1D_INDEX: _mesa_printf("1D"); break; @@ -304,7 +544,7 @@ _mesa_print_instruction(const struct prog_instruction *inst, GLint indent) break; case OPCODE_ARL: _mesa_printf("ARL addr.x, "); - print_src_reg(&inst->SrcReg[0]); + print_src_reg(&inst->SrcReg[0], mode, prog); print_comment(inst); break; case OPCODE_BRA: @@ -319,43 +559,48 @@ _mesa_print_instruction(const struct prog_instruction *inst, GLint indent) print_comment(inst); break; case OPCODE_IF: - _mesa_printf("IF (%s%s) (if false, goto %d)", + _mesa_printf("IF (%s%s); # (if false, goto %d)", condcode_string(inst->DstReg.CondMask), swizzle_string(inst->DstReg.CondSwizzle, 0, GL_FALSE), inst->BranchTarget); print_comment(inst); return indent + 3; case OPCODE_ELSE: - _mesa_printf("ELSE (goto %d)\n", inst->BranchTarget); + _mesa_printf("ELSE; # (goto %d)\n", inst->BranchTarget); return indent + 3; case OPCODE_ENDIF: - _mesa_printf("ENDIF\n"); + _mesa_printf("ENDIF;\n"); break; case OPCODE_BGNLOOP: - _mesa_printf("BGNLOOP (end at %d)\n", inst->BranchTarget); + _mesa_printf("BGNLOOP; # (end at %d)\n", inst->BranchTarget); return indent + 3; case OPCODE_ENDLOOP: - _mesa_printf("ENDLOOP (goto %d)\n", inst->BranchTarget); + _mesa_printf("ENDLOOP; # (goto %d)\n", inst->BranchTarget); break; case OPCODE_BRK: - /* XXX just like BRA */ - _mesa_printf("BRK (%s%s) (for loop beginning at %d)", + _mesa_printf("BRK (%s%s); #(goto %d)", + condcode_string(inst->DstReg.CondMask), + swizzle_string(inst->DstReg.CondSwizzle, 0, GL_FALSE), + inst->BranchTarget); + print_comment(inst); + break; + case OPCODE_CONT: + _mesa_printf("CONT (%s%s); #(goto %d)", condcode_string(inst->DstReg.CondMask), swizzle_string(inst->DstReg.CondSwizzle, 0, GL_FALSE), inst->BranchTarget); print_comment(inst); break; case OPCODE_BGNSUB: - _mesa_printf("SUB;\n"); + _mesa_printf("SUB"); print_comment(inst); return indent + 3; case OPCODE_ENDSUB: - _mesa_printf("ENDSUB;\n"); + _mesa_printf("ENDSUB"); print_comment(inst); break; case OPCODE_END: - _mesa_printf("END"); - print_comment(inst); + _mesa_printf("END\n"); break; case OPCODE_NOP: _mesa_printf("NOP"); @@ -364,9 +609,10 @@ _mesa_print_instruction(const struct prog_instruction *inst, GLint indent) /* XXX may need other special-case instructions */ default: /* typical alu instruction */ - _mesa_print_alu_instruction(inst, - _mesa_opcode_string(inst->Opcode), - _mesa_num_inst_src_regs(inst->Opcode)); + print_alu_instruction(inst, + _mesa_opcode_string(inst->Opcode), + _mesa_num_inst_src_regs(inst->Opcode), + mode, prog); break; } return indent; @@ -374,16 +620,50 @@ _mesa_print_instruction(const struct prog_instruction *inst, GLint indent) /** - * Print a vertx/fragment program to stdout. - * XXX this function could be greatly improved. + * Print program to stdout, default options. */ void _mesa_print_program(const struct gl_program *prog) { + _mesa_print_program_opt(prog, PROG_PRINT_DEBUG, GL_TRUE); +} + + +/** + * Print program, with options. + */ +void +_mesa_print_program_opt(const struct gl_program *prog, + gl_prog_print_mode mode, + GLboolean lineNumbers) +{ GLuint i, indent = 0; + + switch (prog->Target) { + case GL_VERTEX_PROGRAM_ARB: + if (mode == PROG_PRINT_ARB) + _mesa_printf("!!ARBvp1.0\n"); + else if (mode == PROG_PRINT_NV) + _mesa_printf("!!VP1.0\n"); + else + _mesa_printf("# Vertex Program/Shader\n"); + break; + case GL_FRAGMENT_PROGRAM_ARB: + case GL_FRAGMENT_PROGRAM_NV: + if (mode == PROG_PRINT_ARB) + _mesa_printf("!!ARBfp1.0\n"); + else if (mode == PROG_PRINT_NV) + _mesa_printf("!!FP1.0\n"); + else + _mesa_printf("# Fragment Program/Shader\n"); + break; + } + for (i = 0; i < prog->NumInstructions; i++) { - _mesa_printf("%3d: ", i); - indent = _mesa_print_instruction(prog->Instructions + i, indent); + if (lineNumbers) + _mesa_printf("%3d: ", i); + indent = _mesa_print_instruction_opt(prog->Instructions + i, + indent, mode, prog); } } @@ -418,14 +698,16 @@ _mesa_print_program_parameters(GLcontext *ctx, const struct gl_program *prog) void _mesa_print_parameter_list(const struct gl_program_parameter_list *list) { + const gl_prog_print_mode mode = PROG_PRINT_DEBUG; GLuint i; + _mesa_printf("param list %p\n", (void *) list); for (i = 0; i < list->NumParameters; i++){ struct gl_program_parameter *param = list->Parameters + i; const GLfloat *v = list->ParameterValues[i]; - _mesa_printf("param[%d] sz=%d %s %s = {%.3f, %.3f, %.3f, %.3f};\n", + _mesa_printf("param[%d] sz=%d %s %s = {%.3g, %.3g, %.3g, %.3g};\n", i, param->Size, - program_file_string(list->Parameters[i].Type), + file_string(list->Parameters[i].Type, mode), param->Name, v[0], v[1], v[2], v[3]); } } diff --git a/src/mesa/shader/prog_print.h b/src/mesa/shader/prog_print.h index 19aaa538007..79c599f5a7b 100644 --- a/src/mesa/shader/prog_print.h +++ b/src/mesa/shader/prog_print.h @@ -27,18 +27,32 @@ #define PROG_PRINT_H -extern GLint -_mesa_print_instruction(const struct prog_instruction *inst, GLint indent); +/** + * The output style to use when printing programs. + */ +typedef enum { + PROG_PRINT_ARB, + PROG_PRINT_NV, + PROG_PRINT_DEBUG +} gl_prog_print_mode; + extern void -_mesa_print_alu_instruction(const struct prog_instruction *inst, - const char *opcode_string, - GLuint numRegs); +_mesa_print_instruction(const struct prog_instruction *inst); + +extern GLint +_mesa_print_instruction_opt(const struct prog_instruction *inst, GLint indent, + gl_prog_print_mode mode, + const struct gl_program *prog); extern void _mesa_print_program(const struct gl_program *prog); extern void +_mesa_print_program_opt(const struct gl_program *prog, gl_prog_print_mode mode, + GLboolean lineNumbers); + +extern void _mesa_print_program_parameters(GLcontext *ctx, const struct gl_program *prog); extern void diff --git a/src/mesa/shader/program.c b/src/mesa/shader/program.c index 7a319496730..ae26c3cc14e 100644 --- a/src/mesa/shader/program.c +++ b/src/mesa/shader/program.c @@ -1,8 +1,8 @@ /* * Mesa 3-D graphics library - * Version: 6.5.2 + * Version: 6.5.3 * - * Copyright (C) 1999-2006 Brian Paul All Rights Reserved. + * Copyright (C) 1999-2007 Brian Paul 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"), @@ -32,25 +32,13 @@ #include "glheader.h" #include "context.h" #include "hash.h" -#include "imports.h" -#include "macros.h" -#include "mtypes.h" -#include "nvfragparse.h" #include "program.h" #include "prog_parameter.h" #include "prog_instruction.h" -#include "prog_statevars.h" -#include "nvvertparse.h" -#include "atifragshader.h" - -/**********************************************************************/ -/* Utility functions */ -/**********************************************************************/ - - -/* A pointer to this dummy program is put into the hash table when +/** + * A pointer to this dummy program is put into the hash table when * glGenPrograms is called. */ struct gl_program _mesa_DummyProgram; @@ -629,233 +617,3 @@ _mesa_GenPrograms(GLsizei n, GLuint *ids) ids[i] = first + i; } } - - -/**********************************************************************/ -/* GL_MESA_program_debug extension */ -/**********************************************************************/ - - -/* XXX temporary */ -GLAPI void GLAPIENTRY -glProgramCallbackMESA(GLenum target, GLprogramcallbackMESA callback, - GLvoid *data) -{ - _mesa_ProgramCallbackMESA(target, callback, data); -} - - -void -_mesa_ProgramCallbackMESA(GLenum target, GLprogramcallbackMESA callback, - GLvoid *data) -{ - GET_CURRENT_CONTEXT(ctx); - - switch (target) { - case GL_FRAGMENT_PROGRAM_ARB: - if (!ctx->Extensions.ARB_fragment_program) { - _mesa_error(ctx, GL_INVALID_ENUM, "glProgramCallbackMESA(target)"); - return; - } - ctx->FragmentProgram.Callback = callback; - ctx->FragmentProgram.CallbackData = data; - break; - case GL_FRAGMENT_PROGRAM_NV: - if (!ctx->Extensions.NV_fragment_program) { - _mesa_error(ctx, GL_INVALID_ENUM, "glProgramCallbackMESA(target)"); - return; - } - ctx->FragmentProgram.Callback = callback; - ctx->FragmentProgram.CallbackData = data; - break; - case GL_VERTEX_PROGRAM_ARB: /* == GL_VERTEX_PROGRAM_NV */ - if (!ctx->Extensions.ARB_vertex_program && - !ctx->Extensions.NV_vertex_program) { - _mesa_error(ctx, GL_INVALID_ENUM, "glProgramCallbackMESA(target)"); - return; - } - ctx->VertexProgram.Callback = callback; - ctx->VertexProgram.CallbackData = data; - break; - default: - _mesa_error(ctx, GL_INVALID_ENUM, "glProgramCallbackMESA(target)"); - return; - } -} - - -/* XXX temporary */ -GLAPI void GLAPIENTRY -glGetProgramRegisterfvMESA(GLenum target, - GLsizei len, const GLubyte *registerName, - GLfloat *v) -{ - _mesa_GetProgramRegisterfvMESA(target, len, registerName, v); -} - - -void -_mesa_GetProgramRegisterfvMESA(GLenum target, - GLsizei len, const GLubyte *registerName, - GLfloat *v) -{ - char reg[1000]; - GET_CURRENT_CONTEXT(ctx); - - /* We _should_ be inside glBegin/glEnd */ -#if 0 - if (ctx->Driver.CurrentExecPrimitive == PRIM_OUTSIDE_BEGIN_END) { - _mesa_error(ctx, GL_INVALID_OPERATION, "glGetProgramRegisterfvMESA"); - return; - } -#endif - - /* make null-terminated copy of registerName */ - len = MIN2((unsigned int) len, sizeof(reg) - 1); - _mesa_memcpy(reg, registerName, len); - reg[len] = 0; - - switch (target) { - case GL_VERTEX_PROGRAM_ARB: /* == GL_VERTEX_PROGRAM_NV */ - if (!ctx->Extensions.ARB_vertex_program && - !ctx->Extensions.NV_vertex_program) { - _mesa_error(ctx, GL_INVALID_ENUM, - "glGetProgramRegisterfvMESA(target)"); - return; - } - if (!ctx->VertexProgram._Enabled) { - _mesa_error(ctx, GL_INVALID_OPERATION, - "glGetProgramRegisterfvMESA"); - return; - } - /* GL_NV_vertex_program */ - if (reg[0] == 'R') { - /* Temp register */ - GLint i = _mesa_atoi(reg + 1); - if (i >= (GLint)ctx->Const.VertexProgram.MaxTemps) { - _mesa_error(ctx, GL_INVALID_VALUE, - "glGetProgramRegisterfvMESA(registerName)"); - return; - } -#if 0 /* FIX ME */ - ctx->Driver.GetVertexProgramRegister(ctx, PROGRAM_TEMPORARY, i, v); -#endif - } - else if (reg[0] == 'v' && reg[1] == '[') { - /* Vertex Input attribute */ - GLuint i; - for (i = 0; i < ctx->Const.VertexProgram.MaxAttribs; i++) { - const char *name = _mesa_nv_vertex_input_register_name(i); - char number[10]; - _mesa_sprintf(number, "%d", i); - if (_mesa_strncmp(reg + 2, name, 4) == 0 || - _mesa_strncmp(reg + 2, number, _mesa_strlen(number)) == 0) { -#if 0 /* FIX ME */ - ctx->Driver.GetVertexProgramRegister(ctx, PROGRAM_INPUT, - i, v); -#endif - return; - } - } - _mesa_error(ctx, GL_INVALID_VALUE, - "glGetProgramRegisterfvMESA(registerName)"); - return; - } - else if (reg[0] == 'o' && reg[1] == '[') { - /* Vertex output attribute */ - } - /* GL_ARB_vertex_program */ - else if (_mesa_strncmp(reg, "vertex.", 7) == 0) { - - } - else { - _mesa_error(ctx, GL_INVALID_VALUE, - "glGetProgramRegisterfvMESA(registerName)"); - return; - } - break; - case GL_FRAGMENT_PROGRAM_ARB: - if (!ctx->Extensions.ARB_fragment_program) { - _mesa_error(ctx, GL_INVALID_ENUM, - "glGetProgramRegisterfvMESA(target)"); - return; - } - if (!ctx->FragmentProgram._Enabled) { - _mesa_error(ctx, GL_INVALID_OPERATION, - "glGetProgramRegisterfvMESA"); - return; - } - /* XXX to do */ - break; - case GL_FRAGMENT_PROGRAM_NV: - if (!ctx->Extensions.NV_fragment_program) { - _mesa_error(ctx, GL_INVALID_ENUM, - "glGetProgramRegisterfvMESA(target)"); - return; - } - if (!ctx->FragmentProgram._Enabled) { - _mesa_error(ctx, GL_INVALID_OPERATION, - "glGetProgramRegisterfvMESA"); - return; - } - if (reg[0] == 'R') { - /* Temp register */ - GLint i = _mesa_atoi(reg + 1); - if (i >= (GLint)ctx->Const.FragmentProgram.MaxTemps) { - _mesa_error(ctx, GL_INVALID_VALUE, - "glGetProgramRegisterfvMESA(registerName)"); - return; - } - ctx->Driver.GetFragmentProgramRegister(ctx, PROGRAM_TEMPORARY, - i, v); - } - else if (reg[0] == 'f' && reg[1] == '[') { - /* Fragment input attribute */ - GLuint i; - for (i = 0; i < ctx->Const.FragmentProgram.MaxAttribs; i++) { - const char *name = _mesa_nv_fragment_input_register_name(i); - if (_mesa_strncmp(reg + 2, name, 4) == 0) { - ctx->Driver.GetFragmentProgramRegister(ctx, - PROGRAM_INPUT, i, v); - return; - } - } - _mesa_error(ctx, GL_INVALID_VALUE, - "glGetProgramRegisterfvMESA(registerName)"); - return; - } - else if (_mesa_strcmp(reg, "o[COLR]") == 0) { - /* Fragment output color */ - ctx->Driver.GetFragmentProgramRegister(ctx, PROGRAM_OUTPUT, - FRAG_RESULT_COLR, v); - } - else if (_mesa_strcmp(reg, "o[COLH]") == 0) { - /* Fragment output color */ - ctx->Driver.GetFragmentProgramRegister(ctx, PROGRAM_OUTPUT, - FRAG_RESULT_COLH, v); - } - else if (_mesa_strcmp(reg, "o[DEPR]") == 0) { - /* Fragment output depth */ - ctx->Driver.GetFragmentProgramRegister(ctx, PROGRAM_OUTPUT, - FRAG_RESULT_DEPR, v); - } - else { - /* try user-defined identifiers */ - const GLfloat *value = _mesa_lookup_parameter_value( - ctx->FragmentProgram.Current->Base.Parameters, -1, reg); - if (value) { - COPY_4V(v, value); - } - else { - _mesa_error(ctx, GL_INVALID_VALUE, - "glGetProgramRegisterfvMESA(registerName)"); - return; - } - } - break; - default: - _mesa_error(ctx, GL_INVALID_ENUM, - "glGetProgramRegisterfvMESA(target)"); - return; - } -} diff --git a/src/mesa/shader/program.h b/src/mesa/shader/program.h index 73f52389289..52704856ab0 100644 --- a/src/mesa/shader/program.h +++ b/src/mesa/shader/program.h @@ -1,8 +1,8 @@ /* * Mesa 3-D graphics library - * Version: 6.5.2 + * Version: 6.5.3 * - * Copyright (C) 1999-2006 Brian Paul All Rights Reserved. + * Copyright (C) 1999-2007 Brian Paul 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"), @@ -103,17 +103,4 @@ _mesa_GenPrograms(GLsizei n, GLuint *ids); -/* - * GL_MESA_program_debug - */ - -extern void -_mesa_ProgramCallbackMESA(GLenum target, GLprogramcallbackMESA callback, - GLvoid *data); - -extern void -_mesa_GetProgramRegisterfvMESA(GLenum target, GLsizei len, - const GLubyte *registerName, GLfloat *v); - - #endif /* PROGRAM_H */ diff --git a/src/mesa/shader/shader_api.c b/src/mesa/shader/shader_api.c index 842960099ea..c439f71f412 100644 --- a/src/mesa/shader/shader_api.c +++ b/src/mesa/shader/shader_api.c @@ -832,7 +832,7 @@ _mesa_link_program(GLcontext *ctx, GLuint program) return; } - _slang_link2(ctx, program, shProg); + _slang_link(ctx, program, shProg); } diff --git a/src/mesa/shader/slang/slang_codegen.c b/src/mesa/shader/slang/slang_codegen.c index a5f033d9123..a36a2d7bc94 100644 --- a/src/mesa/shader/slang/slang_codegen.c +++ b/src/mesa/shader/slang/slang_codegen.c @@ -47,8 +47,6 @@ #include "slang_print.h" -static GLboolean UseHighLevelInstructions = GL_FALSE; - static slang_ir_node * _slang_gen_operation(slang_assemble_ctx * A, slang_operation *oper); @@ -144,12 +142,12 @@ static GLboolean is_sampler_type(const slang_fully_specified_type *t) { switch (t->specifier.type) { - case slang_spec_sampler1D: - case slang_spec_sampler2D: - case slang_spec_sampler3D: - case slang_spec_samplerCube: - case slang_spec_sampler1DShadow: - case slang_spec_sampler2DShadow: + case SLANG_SPEC_SAMPLER1D: + case SLANG_SPEC_SAMPLER2D: + case SLANG_SPEC_SAMPLER3D: + case SLANG_SPEC_SAMPLERCUBE: + case SLANG_SPEC_SAMPLER1DSHADOW: + case SLANG_SPEC_SAMPLER2DSHADOW: return GL_TRUE; default: return GL_FALSE; @@ -169,49 +167,49 @@ GLuint _slang_sizeof_type_specifier(const slang_type_specifier *spec) { switch (spec->type) { - case slang_spec_void: + case SLANG_SPEC_VOID: abort(); return 0; - case slang_spec_bool: + case SLANG_SPEC_BOOL: return 1; - case slang_spec_bvec2: + case SLANG_SPEC_BVEC2: return 2; - case slang_spec_bvec3: + case SLANG_SPEC_BVEC3: return 3; - case slang_spec_bvec4: + case SLANG_SPEC_BVEC4: return 4; - case slang_spec_int: + case SLANG_SPEC_INT: return 1; - case slang_spec_ivec2: + case SLANG_SPEC_IVEC2: return 2; - case slang_spec_ivec3: + case SLANG_SPEC_IVEC3: return 3; - case slang_spec_ivec4: + case SLANG_SPEC_IVEC4: return 4; - case slang_spec_float: + case SLANG_SPEC_FLOAT: return 1; - case slang_spec_vec2: + case SLANG_SPEC_VEC2: return 2; - case slang_spec_vec3: + case SLANG_SPEC_VEC3: return 3; - case slang_spec_vec4: + case SLANG_SPEC_VEC4: return 4; - case slang_spec_mat2: + case SLANG_SPEC_MAT2: return 2 * 2; - case slang_spec_mat3: + case SLANG_SPEC_MAT3: return 3 * 3; - case slang_spec_mat4: + case SLANG_SPEC_MAT4: return 4 * 4; - case slang_spec_sampler1D: - case slang_spec_sampler2D: - case slang_spec_sampler3D: - case slang_spec_samplerCube: - case slang_spec_sampler1DShadow: - case slang_spec_sampler2DShadow: + case SLANG_SPEC_SAMPLER1D: + case SLANG_SPEC_SAMPLER2D: + case SLANG_SPEC_SAMPLER3D: + case SLANG_SPEC_SAMPLERCUBE: + case SLANG_SPEC_SAMPLER1DSHADOW: + case SLANG_SPEC_SAMPLER2DSHADOW: return 1; /* special case */ - case slang_spec_struct: + case SLANG_SPEC_STRUCT: return _slang_sizeof_struct(spec->_struct); - case slang_spec_array: + case SLANG_SPEC_ARRAY: return 1; /* XXX */ default: abort(); @@ -297,17 +295,17 @@ static GLint sampler_to_texture_index(const slang_type_specifier_type type) { switch (type) { - case slang_spec_sampler1D: + case SLANG_SPEC_SAMPLER1D: return TEXTURE_1D_INDEX; - case slang_spec_sampler2D: + case SLANG_SPEC_SAMPLER2D: return TEXTURE_2D_INDEX; - case slang_spec_sampler3D: + case SLANG_SPEC_SAMPLER3D: return TEXTURE_3D_INDEX; - case slang_spec_samplerCube: + case SLANG_SPEC_SAMPLERCUBE: return TEXTURE_CUBE_INDEX; - case slang_spec_sampler1DShadow: + case SLANG_SPEC_SAMPLER1DSHADOW: return TEXTURE_1D_INDEX; /* XXX fix */ - case slang_spec_sampler2DShadow: + case SLANG_SPEC_SAMPLER2DSHADOW: return TEXTURE_2D_INDEX; /* XXX fix */ default: return -1; @@ -489,24 +487,28 @@ static slang_asm_info AsmInfo[] = { static void _slang_free_ir_tree(slang_ir_node *n) { -#if 0 +#if 1 + GLuint i; if (!n) return; - _slang_free_ir_tree(n->Children[0]); - _slang_free_ir_tree(n->Children[1]); + for (i = 0; i < 3; i++) + _slang_free_ir_tree(n->Children[i]); + /* Do not free n->BranchNode since it's a child elsewhere */ free(n); #endif } static slang_ir_node * -new_node(slang_ir_opcode op, slang_ir_node *left, slang_ir_node *right) +new_node3(slang_ir_opcode op, + slang_ir_node *c0, slang_ir_node *c1, slang_ir_node *c2) { slang_ir_node *n = (slang_ir_node *) calloc(1, sizeof(slang_ir_node)); if (n) { n->Opcode = op; - n->Children[0] = left; - n->Children[1] = right; + n->Children[0] = c0; + n->Children[1] = c1; + n->Children[2] = c2; n->Writemask = WRITEMASK_XYZW; n->InstLocation = -1; } @@ -514,18 +516,38 @@ new_node(slang_ir_opcode op, slang_ir_node *left, slang_ir_node *right) } static slang_ir_node * +new_node2(slang_ir_opcode op, slang_ir_node *c0, slang_ir_node *c1) +{ + return new_node3(op, c0, c1, NULL); +} + +static slang_ir_node * +new_node1(slang_ir_opcode op, slang_ir_node *c0) +{ + return new_node3(op, c0, NULL, NULL); +} + +static slang_ir_node * +new_node0(slang_ir_opcode op) +{ + return new_node3(op, NULL, NULL, NULL); +} + + +static slang_ir_node * new_seq(slang_ir_node *left, slang_ir_node *right) { - /* XXX if either left or right is null, just return pointer to other?? */ - assert(left); - assert(right); - return new_node(IR_SEQ, left, right); + if (!left) + return right; + if (!right) + return left; + return new_node2(IR_SEQ, left, right); } static slang_ir_node * new_label(slang_atom labName) { - slang_ir_node *n = new_node(IR_LABEL, NULL, NULL); + slang_ir_node *n = new_node0(IR_LABEL); n->Target = (char *) labName; /*_mesa_strdup(name);*/ return n; } @@ -534,7 +556,7 @@ static slang_ir_node * new_float_literal(const float v[4]) { const GLuint size = (v[0] == v[1] && v[0] == v[2] && v[0] == v[3]) ? 1 : 4; - slang_ir_node *n = new_node(IR_FLOAT, NULL, NULL); + slang_ir_node *n = new_node0(IR_FLOAT); COPY_4V(n->Value, v); /* allocate a storage object, but compute actual location (Index) later */ n->Store = _slang_new_ir_storage(PROGRAM_CONSTANT, -1, size); @@ -550,7 +572,7 @@ new_float_literal(const float v[4]) static slang_ir_node * new_cjump(slang_atom target, GLuint zeroOrOne) { - slang_ir_node *n = new_node(zeroOrOne ? IR_CJUMP1 : IR_CJUMP0, NULL, NULL); + slang_ir_node *n = new_node0(zeroOrOne ? IR_CJUMP1 : IR_CJUMP0); if (n) n->Target = (char *) target; return n; @@ -563,7 +585,7 @@ new_cjump(slang_atom target, GLuint zeroOrOne) static slang_ir_node * new_jump(slang_atom target) { - slang_ir_node *n = new_node(IR_JUMP, NULL, NULL); + slang_ir_node *n = new_node0(IR_JUMP); if (n) n->Target = (char *) target; return n; @@ -571,75 +593,92 @@ new_jump(slang_atom target) static slang_ir_node * -new_begin_loop(void) +new_loop(slang_ir_node *body) { - slang_ir_node *n = new_node(IR_BEGIN_LOOP, NULL, NULL); - return n; + return new_node1(IR_LOOP, body); } static slang_ir_node * -new_end_loop(slang_ir_node *beginNode) +new_break(slang_ir_node *loopNode) { - slang_ir_node *n = new_node(IR_END_LOOP, NULL, NULL); - assert(beginNode); + slang_ir_node *n = new_node0(IR_BREAK); + assert(loopNode); + assert(loopNode->Opcode == IR_LOOP); if (n) { - n->BranchNode = beginNode; + /* insert this node at head of linked list */ + n->BranchNode = loopNode->BranchNode; + loopNode->BranchNode = n; } return n; } +/** + * Make new IR_BREAK_IF_TRUE or IR_BREAK_IF_FALSE node. + */ static slang_ir_node * -new_break(slang_ir_node *beginNode) +new_break_if(slang_ir_node *loopNode, slang_ir_node *cond, GLboolean breakTrue) { - slang_ir_node *n = new_node(IR_BREAK, NULL, NULL); - assert(beginNode); + slang_ir_node *n; + assert(loopNode); + assert(loopNode->Opcode == IR_LOOP); + n = new_node1(breakTrue ? IR_BREAK_IF_TRUE : IR_BREAK_IF_FALSE, cond); if (n) { - n->BranchNode = beginNode; + /* insert this node at head of linked list */ + n->BranchNode = loopNode->BranchNode; + loopNode->BranchNode = n; } return n; } /** - * Child[0] is the condition. - * XXX we might re-design IR_IF so Children[1] is the "then" body and - * Children[0] is the "else" body. + * Make new IR_CONT_IF_TRUE or IR_CONT_IF_FALSE node. */ static slang_ir_node * -new_if(slang_ir_node *cond) +new_cont_if(slang_ir_node *loopNode, slang_ir_node *cond, GLboolean contTrue) { - slang_ir_node *n = new_node(IR_IF, NULL, NULL); - assert(cond); + slang_ir_node *n; + assert(loopNode); + assert(loopNode->Opcode == IR_LOOP); + n = new_node1(contTrue ? IR_CONT_IF_TRUE : IR_CONT_IF_FALSE, cond); if (n) { - n->Children[0] = cond; + /* insert this node at head of linked list */ + n->BranchNode = loopNode->BranchNode; + loopNode->BranchNode = n; } return n; } static slang_ir_node * -new_else(slang_ir_node *ifNode) +new_cont(slang_ir_node *loopNode) { - slang_ir_node *n = new_node(IR_ELSE, NULL, NULL); - assert(ifNode); + slang_ir_node *n = new_node0(IR_CONT); + assert(loopNode); + assert(loopNode->Opcode == IR_LOOP); if (n) { - n->BranchNode = ifNode; + /* insert this node at head of linked list */ + n->BranchNode = loopNode->BranchNode; + loopNode->BranchNode = n; } return n; } static slang_ir_node * -new_endif(slang_ir_node *elseOrIfNode) +new_cond(slang_ir_node *n) { - slang_ir_node *n = new_node(IR_ENDIF, NULL, NULL); - assert(elseOrIfNode); - if (n) { - n->BranchNode = elseOrIfNode; - } - return n; + slang_ir_node *c = new_node1(IR_COND, n); + return c; +} + + +static slang_ir_node * +new_if(slang_ir_node *cond, slang_ir_node *ifPart, slang_ir_node *elsePart) +{ + return new_node3(IR_IF, cond, ifPart, elsePart); } @@ -650,7 +689,7 @@ static slang_ir_node * new_var(slang_assemble_ctx *A, slang_operation *oper, slang_atom name) { slang_variable *v = _slang_locate_variable(oper->locals, name, GL_TRUE); - slang_ir_node *n = new_node(IR_VAR, NULL, NULL); + slang_ir_node *n = new_node0(IR_VAR); if (!v) return NULL; assert(!oper->var || oper->var == v); @@ -669,9 +708,9 @@ new_var(slang_assemble_ctx *A, slang_operation *oper, slang_atom name) static GLboolean slang_is_asm_function(const slang_function *fun) { - if (fun->body->type == slang_oper_block_no_new_scope && + if (fun->body->type == SLANG_OPER_BLOCK_NO_NEW_SCOPE && fun->body->num_children == 1 && - fun->body->children[0].type == slang_oper_asm) { + fun->body->children[0].type == SLANG_OPER_ASM) { return GL_TRUE; } return GL_FALSE; @@ -690,7 +729,7 @@ slang_inline_asm_function(slang_assemble_ctx *A, GLuint i; slang_operation *inlined = slang_operation_new(1); - /*assert(oper->type == slang_oper_call); or vec4_add, etc */ + /*assert(oper->type == SLANG_OPER_CALL); or vec4_add, etc */ /* printf("Inline asm %s\n", (char*) fun->header.a_name); */ @@ -716,7 +755,7 @@ slang_inline_asm_function(slang_assemble_ctx *A, static void slang_resolve_variable(slang_operation *oper) { - if (oper->type != slang_oper_identifier) + if (oper->type != SLANG_OPER_IDENTIFIER) return; if (!oper->var) { oper->var = _slang_locate_variable(oper->locals, @@ -729,7 +768,7 @@ slang_resolve_variable(slang_operation *oper) /** - * Replace particular variables (slang_oper_identifier) with new expressions. + * Replace particular variables (SLANG_OPER_IDENTIFIER) with new expressions. */ static void slang_substitute(slang_assemble_ctx *A, slang_operation *oper, @@ -737,7 +776,7 @@ slang_substitute(slang_assemble_ctx *A, slang_operation *oper, slang_operation **substNew, GLboolean isLHS) { switch (oper->type) { - case slang_oper_variable_decl: + case SLANG_OPER_VARIABLE_DECL: { slang_variable *v = _slang_locate_variable(oper->locals, oper->a_id, GL_TRUE); @@ -754,7 +793,7 @@ slang_substitute(slang_assemble_ctx *A, slang_operation *oper, } } break; - case slang_oper_identifier: + case SLANG_OPER_IDENTIFIER: assert(oper->num_children == 0); if (1/**!isLHS XXX FIX */) { slang_atom id = oper->a_id; @@ -772,9 +811,9 @@ slang_substitute(slang_assemble_ctx *A, slang_operation *oper, /* look for a substitution */ for (i = 0; i < substCount; i++) { if (v == substOld[i]) { - /* OK, replace this slang_oper_identifier with a new expr */ + /* OK, replace this SLANG_OPER_IDENTIFIER with a new expr */ #if 0 /* DEBUG only */ - if (substNew[i]->type == slang_oper_identifier) { + if (substNew[i]->type == SLANG_OPER_IDENTIFIER) { assert(substNew[i]->var); assert(substNew[i]->var->a_name); printf("Substitute %s with %s in id node %p\n", @@ -794,7 +833,7 @@ slang_substitute(slang_assemble_ctx *A, slang_operation *oper, } break; #if 1 /* XXX rely on default case below */ - case slang_oper_return: + case SLANG_OPER_RETURN: /* do return replacement here too */ assert(oper->num_children == 0 || oper->num_children == 1); if (oper->num_children == 1) { @@ -807,23 +846,23 @@ slang_substitute(slang_assemble_ctx *A, slang_operation *oper, */ slang_operation *blockOper, *assignOper, *returnOper; blockOper = slang_operation_new(1); - blockOper->type = slang_oper_block_no_new_scope; + blockOper->type = SLANG_OPER_BLOCK_NO_NEW_SCOPE; blockOper->num_children = 2; blockOper->children = slang_operation_new(2); assignOper = blockOper->children + 0; returnOper = blockOper->children + 1; - assignOper->type = slang_oper_assign; + assignOper->type = SLANG_OPER_ASSIGN; assignOper->num_children = 2; assignOper->children = slang_operation_new(2); - assignOper->children[0].type = slang_oper_identifier; + assignOper->children[0].type = SLANG_OPER_IDENTIFIER; assignOper->children[0].a_id = slang_atom_pool_atom(A->atoms, "__retVal"); assignOper->children[0].locals->outer_scope = oper->locals; assignOper->locals = oper->locals; slang_operation_copy(&assignOper->children[1], &oper->children[0]); - returnOper->type = slang_oper_return; + returnOper->type = SLANG_OPER_RETURN; assert(returnOper->num_children == 0); /* do substitutions on the "__retVal = expr" sub-tree */ @@ -836,8 +875,8 @@ slang_substitute(slang_assemble_ctx *A, slang_operation *oper, } break; #endif - case slang_oper_assign: - case slang_oper_subscript: + case SLANG_OPER_ASSIGN: + case SLANG_OPER_SUBSCRIPT: /* special case: * child[0] can't have substitutions but child[1] can. */ @@ -846,7 +885,7 @@ slang_substitute(slang_assemble_ctx *A, slang_operation *oper, slang_substitute(A, &oper->children[1], substCount, substOld, substNew, GL_FALSE); break; - case slang_oper_field: + case SLANG_OPER_FIELD: /* XXX NEW - test */ slang_substitute(A, &oper->children[0], substCount, substOld, substNew, GL_TRUE); @@ -886,7 +925,7 @@ slang_inline_function_call(slang_assemble_ctx * A, slang_function *fun, slang_operation **substNew; GLuint substCount, numCopyIn, i; - /*assert(oper->type == slang_oper_call); (or (matrix) multiply, etc) */ + /*assert(oper->type == SLANG_OPER_CALL); (or (matrix) multiply, etc) */ assert(fun->param_count == totalArgs); /* allocate temporary arrays */ @@ -914,7 +953,7 @@ slang_inline_function_call(slang_assemble_ctx * A, slang_function *fun, slang_variable *resultVar; commaSeq = slang_operation_new(1); - commaSeq->type = slang_oper_sequence; + commaSeq->type = SLANG_OPER_SEQUENCE; assert(commaSeq->locals); commaSeq->locals->outer_scope = oper->locals->outer_scope; commaSeq->num_children = 3; @@ -932,7 +971,7 @@ slang_inline_function_call(slang_assemble_ctx * A, slang_function *fun, /* child[0] = __resultTmp declaration */ declOper = &commaSeq->children[0]; - declOper->type = slang_oper_variable_decl; + declOper->type = SLANG_OPER_VARIABLE_DECL; declOper->a_id = resultVar->a_name; declOper->locals->outer_scope = commaSeq->locals; /*** ??? **/ @@ -943,7 +982,7 @@ slang_inline_function_call(slang_assemble_ctx * A, slang_function *fun, /* child[2] = __resultTmp reference */ returnOper = &commaSeq->children[2]; - returnOper->type = slang_oper_identifier; + returnOper->type = SLANG_OPER_IDENTIFIER; returnOper->a_id = resultVar->a_name; returnOper->locals->outer_scope = commaSeq->locals; declOper->locals->outer_scope = commaSeq->locals; @@ -974,8 +1013,8 @@ slang_inline_function_call(slang_assemble_ctx * A, slang_function *fun, slang_type_qual_string(p->type.qualifier), (char *) p->a_name); */ - if (p->type.qualifier == slang_qual_inout || - p->type.qualifier == slang_qual_out) { + if (p->type.qualifier == SLANG_QUAL_INOUT || + p->type.qualifier == SLANG_QUAL_OUT) { /* an output param */ slang_operation *arg; if (i < numArgs) @@ -984,7 +1023,7 @@ slang_inline_function_call(slang_assemble_ctx * A, slang_function *fun, arg = returnOper; paramMode[i] = SUBST; - if (arg->type == slang_oper_identifier) + if (arg->type == SLANG_OPER_IDENTIFIER) slang_resolve_variable(arg); /* replace parameter 'p' with argument 'arg' */ @@ -992,10 +1031,10 @@ slang_inline_function_call(slang_assemble_ctx * A, slang_function *fun, substNew[substCount] = arg; /* will get copied */ substCount++; } - else if (p->type.qualifier == slang_qual_const) { + else if (p->type.qualifier == SLANG_QUAL_CONST) { /* a constant input param */ - if (args[i].type == slang_oper_identifier || - args[i].type == slang_oper_literal_float) { + if (args[i].type == SLANG_OPER_IDENTIFIER || + args[i].type == SLANG_OPER_LITERAL_FLOAT) { /* replace all occurances of this parameter variable with the * actual argument variable or a literal. */ @@ -1019,8 +1058,8 @@ slang_inline_function_call(slang_assemble_ctx * A, slang_function *fun, slang_operation_copy(inlined, fun->body); /*** XXX review this */ - assert(inlined->type = slang_oper_block_no_new_scope); - inlined->type = slang_oper_block_new_scope; + assert(inlined->type = SLANG_OPER_BLOCK_NO_NEW_SCOPE); + inlined->type = SLANG_OPER_BLOCK_NEW_SCOPE; #if 0 printf("======================= orig body code ======================\n"); @@ -1053,7 +1092,7 @@ slang_inline_function_call(slang_assemble_ctx * A, slang_function *fun, /* printf("COPY_IN %s from expr\n", (char*)p->a_name); */ - decl->type = slang_oper_variable_decl; + decl->type = SLANG_OPER_VARIABLE_DECL; assert(decl->locals); decl->locals = fun->parameters; decl->a_id = p->a_name; @@ -1075,7 +1114,7 @@ slang_inline_function_call(slang_assemble_ctx * A, slang_function *fun, slang_operation *lab = slang_operation_insert(&inlined->num_children, &inlined->children, inlined->num_children); - lab->type = slang_oper_label; + lab->type = SLANG_OPER_LABEL; lab->a_id = slang_atom_pool_atom(A->atoms, (char *) A->CurFunction->end_label); } @@ -1088,13 +1127,13 @@ slang_inline_function_call(slang_assemble_ctx * A, slang_function *fun, slang_operation *ass = slang_operation_insert(&inlined->num_children, &inlined->children, inlined->num_children); - ass->type = slang_oper_assign; + ass->type = SLANG_OPER_ASSIGN; ass->num_children = 2; ass->locals = _slang_variable_scope_new(inlined->locals); assert(ass->locals); ass->children = slang_operation_new(2); ass->children[0] = args[i]; /*XXX copy */ - ass->children[1].type = slang_oper_identifier; + ass->children[1].type = SLANG_OPER_IDENTIFIER; ass->children[1].a_id = p->a_name; ass->children[1].locals = _slang_variable_scope_new(ass->locals); } @@ -1222,7 +1261,7 @@ _slang_gen_asm(slang_assemble_ctx *A, slang_operation *oper, slang_ir_node *kids[3], *n; GLuint j, firstOperand; - assert(oper->type == slang_oper_asm); + assert(oper->type == SLANG_OPER_ASM); info = slang_find_asm_info((char *) oper->a_id); if (!info) { @@ -1251,9 +1290,7 @@ _slang_gen_asm(slang_assemble_ctx *A, slang_operation *oper, kids[j] = _slang_gen_operation(A, &oper->children[firstOperand + j]); } - n = new_node(info->Opcode, kids[0], kids[1]); - if (kids[2]) - n->Children[2] = kids[2]; + n = new_node3(info->Opcode, kids[0], kids[1], kids[2]); if (firstOperand) { /* Setup n->Store to be a particular location. Otherwise, storage @@ -1264,7 +1301,7 @@ _slang_gen_asm(slang_assemble_ctx *A, slang_operation *oper, slang_ir_node *n0; dest_oper = &oper->children[0]; - while /*if*/ (dest_oper->type == slang_oper_field) { + while /*if*/ (dest_oper->type == SLANG_OPER_FIELD) { /* writemask */ writemask &= /*=*/make_writemask((char*) dest_oper->a_id); dest_oper = &dest_oper->children[0]; @@ -1289,22 +1326,14 @@ static GLboolean _slang_is_noop(const slang_operation *oper) { if (!oper || - oper->type == slang_oper_void || - (oper->num_children == 1 && oper->children[0].type == slang_oper_void)) + oper->type == SLANG_OPER_VOID || + (oper->num_children == 1 && oper->children[0].type == SLANG_OPER_VOID)) return GL_TRUE; else return GL_FALSE; } -static slang_ir_node * -_slang_gen_cond(slang_ir_node *n) -{ - slang_ir_node *c = new_node(IR_COND, n, NULL); - return c; -} - - static void print_funcs(struct slang_function_scope_ *scope, const char *name) { @@ -1324,6 +1353,9 @@ print_funcs(struct slang_function_scope_ *scope, const char *name) * Return first function in the scope that has the given name. * This is the function we'll try to call when there is no exact match * between function parameters and call arguments. + * + * XXX we should really create a list of candidate functions and try + * all of them... */ static slang_function * _slang_first_function(struct slang_function_scope_ *scope, const char *name) @@ -1379,274 +1411,154 @@ _slang_gen_function_call_name(slang_assemble_ctx *A, const char *name, } -/** - * Generate IR tree for a while-loop. Use BRA-nch instruction. - */ -static slang_ir_node * -_slang_gen_while(slang_assemble_ctx * A, const slang_operation *oper) +static GLboolean +_slang_is_constant_cond(const slang_operation *oper, GLboolean *value) { - /* - * label "__startWhile" - * eval expr (child[0]), updating condcodes - * branch if false to "__endWhile" - * body code - * jump "__startWhile" - * label "__endWhile" - */ - slang_atom startAtom = slang_atom_pool_gen(A->atoms, "__startWhile"); - slang_atom endAtom = slang_atom_pool_gen(A->atoms, "__endWhile"); - slang_ir_node *startLab, *cond, *bra, *body, *jump, *endLab, *tree; - slang_atom prevLoopBreak = A->CurLoopBreak; - slang_atom prevLoopCont = A->CurLoopCont; - - /* Push this loop */ - A->CurLoopBreak = endAtom; - A->CurLoopCont = startAtom; - - startLab = new_label(startAtom); - cond = _slang_gen_operation(A, &oper->children[0]); - cond = _slang_gen_cond(cond); - tree = new_seq(startLab, cond); - - bra = new_cjump(endAtom, 0); - tree = new_seq(tree, bra); - - body = _slang_gen_operation(A, &oper->children[1]); - if (body) - tree = new_seq(tree, body); - - jump = new_jump(startAtom); - tree = new_seq(tree, jump); - - endLab = new_label(endAtom); - tree = new_seq(tree, endLab); - - /* Pop this loop */ - A->CurLoopBreak = prevLoopBreak; - A->CurLoopCont = prevLoopCont; - - return tree; + if (oper->type == SLANG_OPER_LITERAL_FLOAT || + oper->type == SLANG_OPER_LITERAL_INT || + oper->type == SLANG_OPER_LITERAL_BOOL) { + if (oper->literal[0]) + *value = GL_TRUE; + else + *value = GL_FALSE; + return GL_TRUE; + } + else if (oper->type == SLANG_OPER_EXPRESSION && + oper->num_children == 1) { + return _slang_is_constant_cond(&oper->children[0], value); + } + return GL_FALSE; } + /** - * Generate IR tree for a while-loop using high-level BGNLOOP/ENDLOOP, - * IF/ENDIF instructions. + * Generate loop code using high-level IR_LOOP instruction */ static slang_ir_node * -_slang_gen_hl_while(slang_assemble_ctx * A, const slang_operation *oper) +_slang_gen_while(slang_assemble_ctx * A, const slang_operation *oper) { /* - * BGNLOOP - * eval expr (child[0]), updating condcodes - * IF !expr THEN - * BRK - * ENDIF + * LOOP: + * BREAK if !expr (child[0]) * body code (child[1]) - * ENDLOOP */ - slang_ir_node *beginLoop, *endLoop, *ifThen, *endif; - slang_ir_node *brk, *cond, *body, *tree; + slang_ir_node *prevLoop, *loop, *cond, *breakIf, *body; + GLboolean isConst, constTrue; - beginLoop = new_begin_loop(); - - cond = _slang_gen_operation(A, &oper->children[0]); - cond = new_node(IR_NOT, cond, NULL); - cond = _slang_gen_cond(cond); + /* Check if loop condition is a constant */ + isConst = _slang_is_constant_cond(&oper->children[0], &constTrue); - ifThen = new_if(cond); - tree = new_seq(beginLoop, ifThen); + if (isConst && !constTrue) { + /* loop is never executed! */ + return new_node0(IR_NOP); + } - brk = new_break(beginLoop); - tree = new_seq(tree, brk); + loop = new_loop(NULL); - endif = new_endif(ifThen); - tree = new_seq(tree, endif); + /* save old, push new loop */ + prevLoop = A->CurLoop; + A->CurLoop = loop; + cond = new_cond(_slang_gen_operation(A, &oper->children[0])); + if (isConst && constTrue) { + /* while(nonzero constant), no conditional break */ + breakIf = NULL; + } + else { + breakIf = new_break_if(A->CurLoop, cond, GL_FALSE); + } body = _slang_gen_operation(A, &oper->children[1]); - if (body) - tree = new_seq(tree, body); + loop->Children[0] = new_seq(breakIf, body); - endLoop = new_end_loop(beginLoop); - tree = new_seq(tree, endLoop); + /* Do infinite loop detection */ + if (loop->BranchNode == 0 && isConst && constTrue) { + /* infinite loop detected */ + A->CurLoop = prevLoop; /* clean-up */ + RETURN_ERROR("Infinite loop detected!", 0); + } - return tree; + /* pop loop, restore prev */ + A->CurLoop = prevLoop; + + return loop; } /** - * Generate IR tree for a do-while-loop. + * Generate IR tree for a do-while loop using high-level LOOP, IF instructions. */ static slang_ir_node * _slang_gen_do(slang_assemble_ctx * A, const slang_operation *oper) { /* - * label "__startDo" - * code body - * eval expr (child[0]), updating condcodes - * branch if true to "__startDo" - * label "__endDo" + * LOOP: + * body code (child[0]) + * BREAK if !expr (child[1]) */ - slang_atom startAtom = slang_atom_pool_gen(A->atoms, "__startDo"); - slang_atom endAtom = slang_atom_pool_gen(A->atoms, "__endDo"); - slang_ir_node *startLab, *cond, *bra, *body, *endLab, *tree; - slang_atom prevLoopBreak = A->CurLoopBreak; - slang_atom prevLoopCont = A->CurLoopCont; - - /* Push this loop */ - A->CurLoopBreak = endAtom; - A->CurLoopCont = startAtom; + slang_ir_node *prevLoop, *loop, *cond, *breakIf, *body; + GLboolean isConst, constTrue; - startLab = new_label(startAtom); + /* Check if loop condition is a constant */ + isConst = _slang_is_constant_cond(&oper->children[0], &constTrue); - body = _slang_gen_operation(A, &oper->children[0]); - tree = new_seq(startLab, body); - - cond = _slang_gen_operation(A, &oper->children[1]); - cond = _slang_gen_cond(cond); - tree = new_seq(tree, cond); + loop = new_loop(NULL); - bra = new_cjump(startAtom, 1); - tree = new_seq(tree, bra); + /* save old, push new loop */ + prevLoop = A->CurLoop; + A->CurLoop = loop; - endLab = new_label(endAtom); - tree = new_seq(tree, endLab); + body = _slang_gen_operation(A, &oper->children[0]); + cond = new_cond(_slang_gen_operation(A, &oper->children[1])); + if (isConst && constTrue) { + /* while(nonzero constant), no conditional break */ + breakIf = NULL; + } + else { + breakIf = new_break_if(A->CurLoop, cond, GL_FALSE); + } + loop->Children[0] = new_seq(body, breakIf); - /* Pop this loop */ - A->CurLoopBreak = prevLoopBreak; - A->CurLoopCont = prevLoopCont; + /* pop loop, restore prev */ + A->CurLoop = prevLoop; - return tree; + return loop; } /** - * Generate IR tree for a for-loop. + * Generate for-loop using high-level IR_LOOP instruction. */ static slang_ir_node * _slang_gen_for(slang_assemble_ctx * A, const slang_operation *oper) { /* - * init code (child[0]) - * label "__startFor" - * eval expr (child[1]), updating condcodes - * branch if false to "__endFor" - * code body (child[3]) - * label "__continueFor" - * incr code (child[2]) - * jump "__startFor" - * label "__endFor" + * init (child[0]) + * LOOP: + * BREAK if !expr (child[1]) + * body code (child[3]) + * incr code (child[2]) // XXX continue here */ - slang_atom startAtom = slang_atom_pool_gen(A->atoms, "__startFor"); - slang_atom contAtom = slang_atom_pool_gen(A->atoms, "__continueFor"); - slang_atom endAtom = slang_atom_pool_gen(A->atoms, "__endFor"); - slang_ir_node *init, *startLab, *cond, *bra, *body, *contLab; - slang_ir_node *incr, *jump, *endLab, *tree; - slang_atom prevLoopBreak = A->CurLoopBreak; - slang_atom prevLoopCont = A->CurLoopCont; - - /* Push this loop */ - A->CurLoopBreak = endAtom; - A->CurLoopCont = contAtom; + slang_ir_node *prevLoop, *loop, *cond, *breakIf, *body, *init, *incr; init = _slang_gen_operation(A, &oper->children[0]); - startLab = new_label(startAtom); - tree = new_seq(init, startLab); - - cond = _slang_gen_operation(A, &oper->children[1]); - cond = _slang_gen_cond(cond); - tree = new_seq(tree, cond); + loop = new_loop(NULL); - bra = new_cjump(endAtom, 0); - tree = new_seq(tree, bra); + /* save old, push new loop */ + prevLoop = A->CurLoop; + A->CurLoop = loop; + cond = new_cond(_slang_gen_operation(A, &oper->children[1])); + breakIf = new_break_if(A->CurLoop, cond, GL_FALSE); body = _slang_gen_operation(A, &oper->children[3]); - tree = new_seq(tree, body); - - contLab = new_label(contAtom); - tree = new_seq(tree, contLab); - - incr = _slang_gen_operation(A, &oper->children[2]); - tree = new_seq(tree, incr); - - jump = new_jump(startAtom); - tree = new_seq(tree, jump); - - endLab = new_label(endAtom); - tree = new_seq(tree, endLab); - - /* Pop this loop */ - A->CurLoopBreak = prevLoopBreak; - A->CurLoopCont = prevLoopCont; - - return tree; -} - - -/** - * Generate IR tree for a for-loop, using high-level BGNLOOP/ENDLOOP and - * IF/ENDIF instructions. - * - * XXX note done yet! - */ -static slang_ir_node * -_slang_gen_hl_for(slang_assemble_ctx * A, const slang_operation *oper) -{ - /* - * init code (child[0]) - * BGNLOOP - * eval expr (child[1]), updating condcodes - * IF !expr THEN - * BRK - * ENDIF - * code body (child[3]) - * label "__continueFor" // jump here for "continue" - * incr code (child[2]) - * ENDLOOP - */ - slang_atom startAtom = slang_atom_pool_gen(A->atoms, "__startFor"); - slang_atom contAtom = slang_atom_pool_gen(A->atoms, "__continueFor"); - slang_atom endAtom = slang_atom_pool_gen(A->atoms, "__endFor"); - slang_ir_node *init, *startLab, *cond, *bra, *body, *contLab; - slang_ir_node *incr, *jump, *endLab, *tree; - slang_atom prevLoopBreak = A->CurLoopBreak; - slang_atom prevLoopCont = A->CurLoopCont; - - /* Push this loop */ - A->CurLoopBreak = endAtom; - A->CurLoopCont = contAtom; - - init = _slang_gen_operation(A, &oper->children[0]); - startLab = new_label(startAtom); - tree = new_seq(init, startLab); - - cond = _slang_gen_operation(A, &oper->children[1]); - cond = _slang_gen_cond(cond); - tree = new_seq(tree, cond); - - bra = new_cjump(endAtom, 0); - tree = new_seq(tree, bra); - - body = _slang_gen_operation(A, &oper->children[3]); - tree = new_seq(tree, body); - - contLab = new_label(contAtom); - tree = new_seq(tree, contLab); - incr = _slang_gen_operation(A, &oper->children[2]); - tree = new_seq(tree, incr); + loop->Children[0] = new_seq(breakIf, + new_seq(body, incr)); - jump = new_jump(startAtom); - tree = new_seq(tree, jump); - - endLab = new_label(endAtom); - tree = new_seq(tree, endLab); - - /* Pop this loop */ - A->CurLoopBreak = prevLoopBreak; - A->CurLoopCont = prevLoopCont; + /* pop loop, restore prev */ + A->CurLoop = prevLoop; - return tree; + return new_seq(init, loop); } @@ -1672,7 +1584,7 @@ _slang_gen_if(slang_assemble_ctx * A, const slang_operation *oper) slang_atom endifAtom = slang_atom_pool_gen(A->atoms, "__endif"); cond = _slang_gen_operation(A, &oper->children[0]); - cond = _slang_gen_cond(cond); + cond = new_cond(cond); /*assert(cond->Store);*/ bra = new_cjump(haveElseClause ? elseAtom : endifAtom, 0); tree = new_seq(cond, bra); @@ -1701,8 +1613,25 @@ _slang_gen_if(slang_assemble_ctx * A, const slang_operation *oper) /** + * Determine if the given operation is of a specific type. + */ +static GLboolean +is_operation_type(const const slang_operation *oper, slang_operation_type type) +{ + if (oper->type == type) + return GL_TRUE; + else if ((oper->type == SLANG_OPER_BLOCK_NEW_SCOPE || + oper->type == SLANG_OPER_BLOCK_NO_NEW_SCOPE) && + oper->num_children == 1) + return is_operation_type(&oper->children[0], type); + else + return GL_FALSE; +} + + +/** * Generate IR tree for an if/then/else conditional using high-level - * IF/ELSE/ENDIF instructions + * IR_IF instruction. */ static slang_ir_node * _slang_gen_hl_if(slang_assemble_ctx * A, const slang_operation *oper) @@ -1715,34 +1644,40 @@ _slang_gen_hl_if(slang_assemble_ctx * A, const slang_operation *oper) * else-body code * ENDIF */ - /* XXX special cases to check for: - * if body of conditiona is just a "break", emit a conditional break - * instruction. - */ const GLboolean haveElseClause = !_slang_is_noop(&oper->children[2]); - slang_ir_node *ifNode, *cond, *trueBody, *elseNode, *falseBody, *endifNode; - slang_ir_node *tree; + slang_ir_node *ifNode, *cond, *ifBody, *elseBody; cond = _slang_gen_operation(A, &oper->children[0]); - cond = _slang_gen_cond(cond); - /*assert(cond->Store);*/ - ifNode = new_if(cond); - - trueBody = _slang_gen_operation(A, &oper->children[1]); - tree = new_seq(ifNode, trueBody); + cond = new_cond(cond); - if (haveElseClause) { - elseNode = new_else(ifNode); - tree = new_seq(tree, elseNode); - - falseBody = _slang_gen_operation(A, &oper->children[2]); - tree = new_seq(tree, falseBody); + if (is_operation_type(&oper->children[1], SLANG_OPER_BREAK)) { + /* Special case: generate a conditional break */ + ifBody = new_break_if(A->CurLoop, cond, GL_TRUE); + if (haveElseClause) { + elseBody = _slang_gen_operation(A, &oper->children[2]); + return new_seq(ifBody, elseBody); + } + return ifBody; + } + else if (is_operation_type(&oper->children[1], SLANG_OPER_CONTINUE)) { + /* Special case: generate a conditional break */ + ifBody = new_cont_if(A->CurLoop, cond, GL_TRUE); + if (haveElseClause) { + elseBody = _slang_gen_operation(A, &oper->children[2]); + return new_seq(ifBody, elseBody); + } + return ifBody; + } + else { + /* general case */ + ifBody = _slang_gen_operation(A, &oper->children[1]); + if (haveElseClause) + elseBody = _slang_gen_operation(A, &oper->children[2]); + else + elseBody = NULL; + ifNode = new_if(cond, ifBody, elseBody); + return ifNode; } - - endifNode = new_endif(haveElseClause ? elseNode : ifNode); - tree = new_seq(tree, endifNode); - - return tree; } @@ -1758,7 +1693,7 @@ _slang_gen_temporary(GLint size) store = _slang_new_ir_storage(PROGRAM_TEMPORARY, -1, size); if (store) { - n = new_node(IR_VAR_DECL, NULL, NULL); + n = new_node0(IR_VAR_DECL); if (n) { n->Store = store; } @@ -1777,7 +1712,7 @@ static slang_ir_node * _slang_gen_var_decl(slang_assemble_ctx *A, slang_variable *var) { slang_ir_node *n; - n = new_node(IR_VAR_DECL, NULL, NULL); + n = new_node0(IR_VAR_DECL); if (n) { n->Var = var; slang_allocate_storage(A, n); @@ -1809,7 +1744,7 @@ _slang_gen_select(slang_assemble_ctx *A, slang_operation *oper) slang_typeinfo type; int size; - assert(oper->type == slang_oper_select); + assert(oper->type == SLANG_OPER_SELECT); assert(oper->num_children == 3); /* size of x or y's type */ @@ -1823,7 +1758,7 @@ _slang_gen_select(slang_assemble_ctx *A, slang_operation *oper) /* eval condition */ cond = _slang_gen_operation(A, &oper->children[0]); - cond = _slang_gen_cond(cond); + cond = new_cond(cond); tree = new_seq(tmpDecl, cond); /* jump if false to "alt" label */ @@ -1831,10 +1766,10 @@ _slang_gen_select(slang_assemble_ctx *A, slang_operation *oper) tree = new_seq(tree, cjump); /* evaluate child 1 (x) and assign to tmp */ - tmpVar = new_node(IR_VAR, NULL, NULL); + tmpVar = new_node0(IR_VAR); tmpVar->Store = tmpDecl->Store; body = _slang_gen_operation(A, &oper->children[1]); - assigny = new_node(IR_MOVE, tmpVar, body); + assigny = new_node2(IR_MOVE, tmpVar, body); tree = new_seq(tree, assigny); /* jump to "end" label */ @@ -1846,10 +1781,10 @@ _slang_gen_select(slang_assemble_ctx *A, slang_operation *oper) tree = new_seq(tree, altLab); /* evaluate child 2 (y) and assign to tmp */ - tmpVar = new_node(IR_VAR, NULL, NULL); + tmpVar = new_node0(IR_VAR); tmpVar->Store = tmpDecl->Store; bodx = _slang_gen_operation(A, &oper->children[2]); - assignx = new_node(IR_MOVE, tmpVar, bodx); + assignx = new_node2(IR_MOVE, tmpVar, bodx); tree = new_seq(tree, assignx); /* "end" label */ @@ -1857,7 +1792,7 @@ _slang_gen_select(slang_assemble_ctx *A, slang_operation *oper) tree = new_seq(tree, endLab); /* tmp var value */ - tmpVar = new_node(IR_VAR, NULL, NULL); + tmpVar = new_node0(IR_VAR); tmpVar->Store = tmpDecl->Store; tree = new_seq(tree, tmpVar); @@ -1876,13 +1811,13 @@ _slang_gen_logical_and(slang_assemble_ctx *A, slang_operation *oper) slang_ir_node *n; select = slang_operation_new(1); - select->type = slang_oper_select; + select->type = SLANG_OPER_SELECT; select->num_children = 3; select->children = slang_operation_new(3); slang_operation_copy(&select->children[0], &oper->children[0]); slang_operation_copy(&select->children[1], &oper->children[1]); - select->children[2].type = slang_oper_literal_bool; + select->children[2].type = SLANG_OPER_LITERAL_BOOL; ASSIGN_4V(select->children[2].literal, 0, 0, 0, 0); select->children[2].literal_size = 2; @@ -1907,12 +1842,12 @@ _slang_gen_logical_or(slang_assemble_ctx *A, slang_operation *oper) slang_ir_node *n; select = slang_operation_new(1); - select->type = slang_oper_select; + select->type = SLANG_OPER_SELECT; select->num_children = 3; select->children = slang_operation_new(3); slang_operation_copy(&select->children[0], &oper->children[0]); - select->children[1].type = slang_oper_literal_bool; + select->children[1].type = SLANG_OPER_LITERAL_BOOL; ASSIGN_4V(select->children[2].literal, 1, 1, 1, 1); slang_operation_copy(&select->children[2], &oper->children[1]); select->children[2].literal_size = 2; @@ -1936,7 +1871,7 @@ _slang_gen_return(slang_assemble_ctx * A, slang_operation *oper) { if (oper->num_children == 0 || (oper->num_children == 1 && - oper->children[0].type == slang_oper_void)) { + oper->children[0].type == SLANG_OPER_VOID)) { /* Convert from: * return; * To: @@ -1945,7 +1880,7 @@ _slang_gen_return(slang_assemble_ctx * A, slang_operation *oper) slang_ir_node *n; slang_operation gotoOp; slang_operation_construct(&gotoOp); - gotoOp.type = slang_oper_goto; + gotoOp.type = SLANG_OPER_GOTO; /* XXX don't call function? */ gotoOp.a_id = slang_atom_pool_atom(A->atoms, (char *) A->CurFunction->end_label); @@ -1979,7 +1914,7 @@ _slang_gen_return(slang_assemble_ctx * A, slang_operation *oper) #endif block = slang_operation_new(1); - block->type = slang_oper_block_no_new_scope; + block->type = SLANG_OPER_BLOCK_NO_NEW_SCOPE; block->num_children = 2; block->children = slang_operation_new(2); assert(block->locals); @@ -1987,12 +1922,12 @@ _slang_gen_return(slang_assemble_ctx * A, slang_operation *oper) /* child[0]: __retVal = expr; */ assign = &block->children[0]; - assign->type = slang_oper_assign; + assign->type = SLANG_OPER_ASSIGN; assign->locals->outer_scope = block->locals; assign->num_children = 2; assign->children = slang_operation_new(2); /* lhs (__retVal) */ - assign->children[0].type = slang_oper_identifier; + assign->children[0].type = SLANG_OPER_IDENTIFIER; assign->children[0].a_id = a_retVal; assign->children[0].locals->outer_scope = assign->locals; /* rhs (expr) */ @@ -2001,7 +1936,7 @@ _slang_gen_return(slang_assemble_ctx * A, slang_operation *oper) /* child[1]: goto __endOfFunction */ jump = &block->children[1]; - jump->type = slang_oper_goto; + jump->type = SLANG_OPER_GOTO; assert(A->CurFunction->end_label); /* XXX don't call function? */ jump->a_id = slang_atom_pool_atom(A->atoms, @@ -2049,7 +1984,7 @@ _slang_gen_declaration(slang_assemble_ctx *A, slang_operation *oper) /* XXX make copy of this initializer? */ rhs = _slang_gen_operation(A, &oper->children[0]); assert(rhs); - init = new_node(IR_MOVE, var, rhs); + init = new_node2(IR_MOVE, var, rhs); /*assert(rhs->Opcode != IR_SEQ);*/ n = new_seq(varDecl, init); } @@ -2073,7 +2008,7 @@ _slang_gen_declaration(slang_assemble_ctx *A, slang_operation *oper) rhs = _slang_gen_operation(A, v->initializer); #endif assert(rhs); - init = new_node(IR_MOVE, var, rhs); + init = new_node2(IR_MOVE, var, rhs); /* assert(rhs->Opcode != IR_SEQ); */ @@ -2200,7 +2135,7 @@ swizzle_to_writemask(GLuint swizzle, static slang_ir_node * _slang_gen_swizzle(slang_ir_node *child, GLuint swizzle) { - slang_ir_node *n = new_node(IR_SWIZZLE, child, NULL); + slang_ir_node *n = new_node1(IR_SWIZZLE, child); if (n) { n->Store = _slang_new_ir_storage(PROGRAM_UNDEFINED, -1, -1); n->Store->Swizzle = swizzle; @@ -2215,8 +2150,8 @@ _slang_gen_swizzle(slang_ir_node *child, GLuint swizzle) static slang_ir_node * _slang_gen_assignment(slang_assemble_ctx * A, slang_operation *oper) { - if (oper->children[0].type == slang_oper_identifier && - oper->children[1].type == slang_oper_call) { + if (oper->children[0].type == SLANG_OPER_IDENTIFIER && + oper->children[1].type == SLANG_OPER_CALL) { /* Special case of: x = f(a, b) * Replace with f(a, b, x) (where x == hidden __retVal out param) * @@ -2244,7 +2179,7 @@ _slang_gen_assignment(slang_assemble_ctx * A, slang_operation *oper) */ rhs = _slang_gen_swizzle(rhs, newSwizzle); } - n = new_node(IR_MOVE, lhs, rhs); + n = new_node2(IR_MOVE, lhs, rhs); n->Writemask = writemask; return n; } @@ -2285,7 +2220,7 @@ _slang_gen_field(slang_assemble_ctx * A, slang_operation *oper) n = _slang_gen_swizzle(n, swizzle); return n; } - else if (ti.spec.type == slang_spec_float) { + else if (ti.spec.type == SLANG_SPEC_FLOAT) { const GLuint rows = 1; slang_swizzle swz; slang_ir_node *n; @@ -2332,7 +2267,7 @@ _slang_gen_subscript(slang_assemble_ctx * A, slang_operation *oper) slang_ir_node *n; index = (GLint) oper->children[1].literal[0]; - if (oper->children[1].type != slang_oper_literal_int || + if (oper->children[1].type != SLANG_OPER_LITERAL_INT || index >= max) { RETURN_ERROR("Invalid array index for vector type", 0); } @@ -2365,7 +2300,7 @@ _slang_gen_subscript(slang_assemble_ctx * A, slang_operation *oper) array = _slang_gen_operation(A, &oper->children[0]); index = _slang_gen_operation(A, &oper->children[1]); if (array && index) { - elem = new_node(IR_ELEMENT, array, index); + elem = new_node2(IR_ELEMENT, array, index); elem->Store = _slang_new_ir_storage(array->Store->File, array->Store->Index, elemSize); @@ -2386,29 +2321,26 @@ static slang_ir_node * _slang_gen_operation(slang_assemble_ctx * A, slang_operation *oper) { switch (oper->type) { - case slang_oper_block_new_scope: + case SLANG_OPER_BLOCK_NEW_SCOPE: { slang_ir_node *n; _slang_push_var_table(A->vartable); - oper->type = slang_oper_block_no_new_scope; /* temp change */ + oper->type = SLANG_OPER_BLOCK_NO_NEW_SCOPE; /* temp change */ n = _slang_gen_operation(A, oper); - oper->type = slang_oper_block_new_scope; /* restore */ + oper->type = SLANG_OPER_BLOCK_NEW_SCOPE; /* restore */ _slang_pop_var_table(A->vartable); if (n) - n = new_node(IR_SCOPE, n, NULL); + n = new_node1(IR_SCOPE, n); return n; } break; - case slang_oper_block_no_new_scope: + case SLANG_OPER_BLOCK_NO_NEW_SCOPE: /* list of operations */ - /* - assert(oper->num_children > 0); - */ if (oper->num_children > 0) { slang_ir_node *n, *tree = NULL; @@ -2446,112 +2378,104 @@ _slang_gen_operation(slang_assemble_ctx * A, slang_operation *oper) return tree; } break; - case slang_oper_expression: + case SLANG_OPER_EXPRESSION: return _slang_gen_operation(A, &oper->children[0]); - break; - case slang_oper_while: - if (UseHighLevelInstructions) - return _slang_gen_hl_while(A, oper); - else - return _slang_gen_while(A, oper); - case slang_oper_do: + + case SLANG_OPER_FOR: + return _slang_gen_for(A, oper); + case SLANG_OPER_DO: return _slang_gen_do(A, oper); - case slang_oper_for: - if (UseHighLevelInstructions) - return _slang_gen_hl_for(A, oper); - else - return _slang_gen_for(A, oper); - case slang_oper_break: - if (!A->CurLoopBreak) { + case SLANG_OPER_WHILE: + return _slang_gen_while(A, oper); + case SLANG_OPER_BREAK: + if (!A->CurLoop) { RETURN_ERROR("'break' not in loop", 0); } - /* XXX emit IR_BREAK instruction */ - return new_jump(A->CurLoopBreak); - case slang_oper_continue: - if (!A->CurLoopCont) { + return new_break(A->CurLoop); + case SLANG_OPER_CONTINUE: + if (!A->CurLoop) { RETURN_ERROR("'continue' not in loop", 0); } - /* XXX emit IR_CONT instruction */ - return new_jump(A->CurLoopCont); - case slang_oper_discard: - return new_node(IR_KILL, NULL, NULL); + return new_cont(A->CurLoop); + case SLANG_OPER_DISCARD: + return new_node0(IR_KILL); - case slang_oper_equal: - return new_node(IR_SEQUAL, + case SLANG_OPER_EQUAL: + return new_node2(IR_SEQUAL, _slang_gen_operation(A, &oper->children[0]), _slang_gen_operation(A, &oper->children[1])); - case slang_oper_notequal: - return new_node(IR_SNEQUAL, + case SLANG_OPER_NOTEQUAL: + return new_node2(IR_SNEQUAL, _slang_gen_operation(A, &oper->children[0]), _slang_gen_operation(A, &oper->children[1])); - case slang_oper_greater: - return new_node(IR_SGT, + case SLANG_OPER_GREATER: + return new_node2(IR_SGT, _slang_gen_operation(A, &oper->children[0]), _slang_gen_operation(A, &oper->children[1])); - case slang_oper_less: + case SLANG_OPER_LESS: /* child[0] < child[1] ----> child[1] > child[0] */ - return new_node(IR_SGT, + return new_node2(IR_SGT, _slang_gen_operation(A, &oper->children[1]), _slang_gen_operation(A, &oper->children[0])); - case slang_oper_greaterequal: - return new_node(IR_SGE, + case SLANG_OPER_GREATERequal: + return new_node2(IR_SGE, _slang_gen_operation(A, &oper->children[0]), _slang_gen_operation(A, &oper->children[1])); - case slang_oper_lessequal: + case SLANG_OPER_LESSequal: /* child[0] <= child[1] ----> child[1] >= child[0] */ - return new_node(IR_SGE, + return new_node2(IR_SGE, _slang_gen_operation(A, &oper->children[1]), _slang_gen_operation(A, &oper->children[0])); - case slang_oper_add: + case SLANG_OPER_ADD: { slang_ir_node *n; assert(oper->num_children == 2); n = _slang_gen_function_call_name(A, "+", oper, NULL); return n; } - case slang_oper_subtract: + case SLANG_OPER_SUBTRACT: { slang_ir_node *n; assert(oper->num_children == 2); n = _slang_gen_function_call_name(A, "-", oper, NULL); return n; } - case slang_oper_multiply: + case SLANG_OPER_MULTIPLY: { slang_ir_node *n; assert(oper->num_children == 2); n = _slang_gen_function_call_name(A, "*", oper, NULL); return n; } - case slang_oper_divide: + case SLANG_OPER_DIVIDE: { slang_ir_node *n; assert(oper->num_children == 2); n = _slang_gen_function_call_name(A, "/", oper, NULL); return n; } - case slang_oper_minus: + case SLANG_OPER_MINUS: { slang_ir_node *n; assert(oper->num_children == 1); n = _slang_gen_function_call_name(A, "-", oper, NULL); return n; } - case slang_oper_plus: + case SLANG_OPER_PLUS: /* +expr --> do nothing */ return _slang_gen_operation(A, &oper->children[0]); - case slang_oper_variable_decl: + case SLANG_OPER_VARIABLE_DECL: return _slang_gen_declaration(A, oper); - case slang_oper_assign: + case SLANG_OPER_ASSIGN: return _slang_gen_assignment(A, oper); - case slang_oper_addassign: + case SLANG_OPER_ADDASSIGN: { slang_ir_node *n; assert(oper->num_children == 2); n = _slang_gen_function_call_name(A, "+=", oper, &oper->children[0]); return n; } - case slang_oper_subassign: + case SLANG_OPER_SUBASSIGN: { slang_ir_node *n; assert(oper->num_children == 2); @@ -2559,42 +2483,42 @@ _slang_gen_operation(slang_assemble_ctx * A, slang_operation *oper) return n; } break; - case slang_oper_mulassign: + case SLANG_OPER_MULASSIGN: { slang_ir_node *n; assert(oper->num_children == 2); n = _slang_gen_function_call_name(A, "*=", oper, &oper->children[0]); return n; } - case slang_oper_divassign: + case SLANG_OPER_DIVASSIGN: { slang_ir_node *n; assert(oper->num_children == 2); n = _slang_gen_function_call_name(A, "/=", oper, &oper->children[0]); return n; } - case slang_oper_logicaland: + case SLANG_OPER_LOGICALAND: { slang_ir_node *n; assert(oper->num_children == 2); n = _slang_gen_logical_and(A, oper); return n; } - case slang_oper_logicalor: + case SLANG_OPER_LOGICALOR: { slang_ir_node *n; assert(oper->num_children == 2); n = _slang_gen_logical_or(A, oper); return n; } - case slang_oper_logicalxor: + case SLANG_OPER_LOGICALXOR: { slang_ir_node *n; assert(oper->num_children == 2); n = _slang_gen_function_call_name(A, "__logicalXor", oper, NULL); return n; } - case slang_oper_not: + case SLANG_OPER_NOT: { slang_ir_node *n; assert(oper->num_children == 1); @@ -2602,7 +2526,7 @@ _slang_gen_operation(slang_assemble_ctx * A, slang_operation *oper) return n; } - case slang_oper_select: /* b ? x : y */ + case SLANG_OPER_SELECT: /* b ? x : y */ { slang_ir_node *n; assert(oper->num_children == 3); @@ -2610,61 +2534,60 @@ _slang_gen_operation(slang_assemble_ctx * A, slang_operation *oper) return n; } - case slang_oper_asm: + case SLANG_OPER_ASM: return _slang_gen_asm(A, oper, NULL); - case slang_oper_call: + case SLANG_OPER_CALL: return _slang_gen_function_call_name(A, (const char *) oper->a_id, oper, NULL); - case slang_oper_return: + case SLANG_OPER_RETURN: return _slang_gen_return(A, oper); - case slang_oper_goto: + case SLANG_OPER_GOTO: return new_jump((char*) oper->a_id); - case slang_oper_label: + case SLANG_OPER_LABEL: return new_label((char*) oper->a_id); - case slang_oper_identifier: + case SLANG_OPER_IDENTIFIER: return _slang_gen_variable(A, oper); - case slang_oper_if: - if (A->program->Target == GL_FRAGMENT_PROGRAM_ARB - && UseHighLevelInstructions) { + case SLANG_OPER_IF: + if (A->program->Target == GL_FRAGMENT_PROGRAM_ARB) { return _slang_gen_hl_if(A, oper); } else { /* XXX update tnl executor */ return _slang_gen_if(A, oper); } - case slang_oper_field: + case SLANG_OPER_FIELD: return _slang_gen_field(A, oper); - case slang_oper_subscript: + case SLANG_OPER_SUBSCRIPT: return _slang_gen_subscript(A, oper); - case slang_oper_literal_float: + case SLANG_OPER_LITERAL_FLOAT: /* fall-through */ - case slang_oper_literal_int: + case SLANG_OPER_LITERAL_INT: /* fall-through */ - case slang_oper_literal_bool: + case SLANG_OPER_LITERAL_BOOL: return new_float_literal(oper->literal); - case slang_oper_postincrement: /* var++ */ + case SLANG_OPER_POSTINCREMENT: /* var++ */ { slang_ir_node *n; assert(oper->num_children == 1); n = _slang_gen_function_call_name(A, "__postIncr", oper, NULL); return n; } - case slang_oper_postdecrement: /* var-- */ + case SLANG_OPER_POSTDECREMENT: /* var-- */ { slang_ir_node *n; assert(oper->num_children == 1); n = _slang_gen_function_call_name(A, "__postDecr", oper, NULL); return n; } - case slang_oper_preincrement: /* ++var */ + case SLANG_OPER_PREINCREMENT: /* ++var */ { slang_ir_node *n; assert(oper->num_children == 1); n = _slang_gen_function_call_name(A, "++", oper, NULL); return n; } - case slang_oper_predecrement: /* --var */ + case SLANG_OPER_PREDECREMENT: /* --var */ { slang_ir_node *n; assert(oper->num_children == 1); @@ -2672,7 +2595,7 @@ _slang_gen_operation(slang_assemble_ctx * A, slang_operation *oper) return n; } - case slang_oper_sequence: + case SLANG_OPER_SEQUENCE: { slang_ir_node *tree = NULL; GLuint i; @@ -2683,15 +2606,15 @@ _slang_gen_operation(slang_assemble_ctx * A, slang_operation *oper) return tree; } - case slang_oper_none: + case SLANG_OPER_NONE: return NULL; - case slang_oper_void: + case SLANG_OPER_VOID: return NULL; default: printf("Unhandled node type %d\n", oper->type); abort(); - return new_node(IR_NOP, NULL, NULL); + return new_node0(IR_NOP); } abort(); return NULL; @@ -2735,7 +2658,7 @@ _slang_codegen_global_variable(slang_assemble_ctx *A, slang_variable *var, store = _slang_new_ir_storage(PROGRAM_SAMPLER, samplerUniform, texIndex); if (dbg) printf("SAMPLER "); } - else if (var->type.qualifier == slang_qual_uniform) { + else if (var->type.qualifier == SLANG_QUAL_UNIFORM) { /* Uniform variable */ const GLint size = _slang_sizeof_type_specifier(&var->type.specifier); if (prog) { @@ -2752,7 +2675,7 @@ _slang_codegen_global_variable(slang_assemble_ctx *A, slang_variable *var, } if (dbg) printf("UNIFORM "); } - else if (var->type.qualifier == slang_qual_varying) { + else if (var->type.qualifier == SLANG_QUAL_VARYING) { const GLint size = 4; /* XXX fix */ if (prog) { /* user-defined varying */ @@ -2761,7 +2684,7 @@ _slang_codegen_global_variable(slang_assemble_ctx *A, slang_variable *var, } else { /* pre-defined varying, like gl_Color or gl_TexCoord */ - if (type == slang_unit_fragment_builtin) { + if (type == SLANG_UNIT_FRAGMENT_BUILTIN) { GLint index = _slang_input_index(varName, GL_FRAGMENT_PROGRAM_ARB); assert(index >= 0); store = _slang_new_ir_storage(PROGRAM_INPUT, index, size); @@ -2770,7 +2693,7 @@ _slang_codegen_global_variable(slang_assemble_ctx *A, slang_variable *var, else { GLint index = _slang_output_index(varName, GL_VERTEX_PROGRAM_ARB); assert(index >= 0); - assert(type == slang_unit_vertex_builtin); + assert(type == SLANG_UNIT_VERTEX_BUILTIN); store = _slang_new_ir_storage(PROGRAM_OUTPUT, index, size); assert(index < VERT_RESULT_MAX); } @@ -2778,7 +2701,7 @@ _slang_codegen_global_variable(slang_assemble_ctx *A, slang_variable *var, } if (dbg) printf("VARYING "); } - else if (var->type.qualifier == slang_qual_attribute) { + else if (var->type.qualifier == SLANG_QUAL_ATTRIBUTE) { if (prog) { /* user-defined vertex attribute */ const GLint size = _slang_sizeof_type_specifier(&var->type.specifier); @@ -2798,27 +2721,27 @@ _slang_codegen_global_variable(slang_assemble_ctx *A, slang_variable *var, } if (dbg) printf("ATTRIB "); } - else if (var->type.qualifier == slang_qual_fixedinput) { + else if (var->type.qualifier == SLANG_QUAL_FIXEDINPUT) { GLint index = _slang_input_index(varName, GL_FRAGMENT_PROGRAM_ARB); GLint size = 4; /* XXX? */ store = _slang_new_ir_storage(PROGRAM_INPUT, index, size); if (dbg) printf("INPUT "); } - else if (var->type.qualifier == slang_qual_fixedoutput) { - if (type == slang_unit_vertex_builtin) { + else if (var->type.qualifier == SLANG_QUAL_FIXEDOUTPUT) { + if (type == SLANG_UNIT_VERTEX_BUILTIN) { GLint index = _slang_output_index(varName, GL_VERTEX_PROGRAM_ARB); GLint size = 4; /* XXX? */ store = _slang_new_ir_storage(PROGRAM_OUTPUT, index, size); } else { - assert(type == slang_unit_fragment_builtin); + assert(type == SLANG_UNIT_FRAGMENT_BUILTIN); GLint index = _slang_output_index(varName, GL_FRAGMENT_PROGRAM_ARB); GLint size = 4; /* XXX? */ store = _slang_new_ir_storage(PROGRAM_OUTPUT, index, size); } if (dbg) printf("OUTPUT "); } - else if (var->type.qualifier == slang_qual_const && !prog) { + else if (var->type.qualifier == SLANG_QUAL_CONST && !prog) { /* pre-defined global constant, like gl_MaxLights */ const GLint size = _slang_sizeof_type_specifier(&var->type.specifier); store = _slang_new_ir_storage(PROGRAM_CONSTANT, -1, size); @@ -2836,7 +2759,7 @@ _slang_codegen_global_variable(slang_assemble_ctx *A, slang_variable *var, slang_ir_node *lhs, *rhs, *init; /* Generate IR_MOVE instruction to initialize the variable */ - lhs = new_node(IR_VAR, NULL, NULL); + lhs = new_node0(IR_VAR); lhs->Var = var; lhs->Store = n->Store; @@ -2845,7 +2768,7 @@ _slang_codegen_global_variable(slang_assemble_ctx *A, slang_variable *var, rhs = _slang_gen_operation(A, var->initializer); assert(rhs); - init = new_node(IR_MOVE, lhs, rhs); + init = new_node2(IR_MOVE, lhs, rhs); n = new_seq(n, init); } @@ -2909,7 +2832,7 @@ _slang_codegen_function(slang_assemble_ctx * A, slang_function * fun) /* Generate IR tree for the function body code */ n = _slang_gen_operation(A, fun->body); if (n) - n = new_node(IR_SCOPE, n, NULL); + n = new_node1(IR_SCOPE, n); /* pop vartable, restore previous */ _slang_pop_var_table(A->vartable); diff --git a/src/mesa/shader/slang/slang_compile.c b/src/mesa/shader/slang/slang_compile.c index 199f96e441e..f7aa297bfa6 100644 --- a/src/mesa/shader/slang/slang_compile.c +++ b/src/mesa/shader/slang/slang_compile.c @@ -162,6 +162,9 @@ slang_info_log_message(slang_info_log * log, const char *prefix, } slang_string_concat(log->text, msg); slang_string_concat(log->text, "\n"); +#if 1 + abort(); /* XXX temporary */ +#endif return 1; } @@ -214,7 +217,7 @@ slang_info_log_memory(slang_info_log * log) log->dont_free_text = 1; log->text = out_of_memory; } - abort(); + abort(); /* XXX temporary */ } /* slang_parse_ctx */ @@ -355,7 +358,7 @@ parse_array_len(slang_parse_ctx * C, slang_output_ctx * O, GLuint * len) /* evaluate compile-time expression which is array size */ _slang_simplify(&array_size, &space, C->atoms); - result = (array_size.type == slang_oper_literal_int); + result = (array_size.type == SLANG_OPER_LITERAL_INT); slang_operation_destruct(&array_size); return result; @@ -385,7 +388,7 @@ convert_to_array(slang_parse_ctx * C, slang_variable * var, { /* sized array - mark it as array, copy the specifier to the array element and * parse the expression */ - var->type.specifier.type = slang_spec_array; + var->type.specifier.type = SLANG_SPEC_ARRAY; var->type.specifier._array = (slang_type_specifier *) slang_alloc_malloc(sizeof(slang_type_specifier)); if (var->type.specifier._array == NULL) { @@ -537,25 +540,25 @@ parse_type_qualifier(slang_parse_ctx * C, slang_type_qualifier * qual) { switch (*C->I++) { case TYPE_QUALIFIER_NONE: - *qual = slang_qual_none; + *qual = SLANG_QUAL_NONE; break; case TYPE_QUALIFIER_CONST: - *qual = slang_qual_const; + *qual = SLANG_QUAL_CONST; break; case TYPE_QUALIFIER_ATTRIBUTE: - *qual = slang_qual_attribute; + *qual = SLANG_QUAL_ATTRIBUTE; break; case TYPE_QUALIFIER_VARYING: - *qual = slang_qual_varying; + *qual = SLANG_QUAL_VARYING; break; case TYPE_QUALIFIER_UNIFORM: - *qual = slang_qual_uniform; + *qual = SLANG_QUAL_UNIFORM; break; case TYPE_QUALIFIER_FIXEDOUTPUT: - *qual = slang_qual_fixedoutput; + *qual = SLANG_QUAL_FIXEDOUTPUT; break; case TYPE_QUALIFIER_FIXEDINPUT: - *qual = slang_qual_fixedinput; + *qual = SLANG_QUAL_FIXEDINPUT; break; default: return 0; @@ -595,78 +598,78 @@ parse_type_specifier(slang_parse_ctx * C, slang_output_ctx * O, { switch (*C->I++) { case TYPE_SPECIFIER_VOID: - spec->type = slang_spec_void; + spec->type = SLANG_SPEC_VOID; break; case TYPE_SPECIFIER_BOOL: - spec->type = slang_spec_bool; + spec->type = SLANG_SPEC_BOOL; break; case TYPE_SPECIFIER_BVEC2: - spec->type = slang_spec_bvec2; + spec->type = SLANG_SPEC_BVEC2; break; case TYPE_SPECIFIER_BVEC3: - spec->type = slang_spec_bvec3; + spec->type = SLANG_SPEC_BVEC3; break; case TYPE_SPECIFIER_BVEC4: - spec->type = slang_spec_bvec4; + spec->type = SLANG_SPEC_BVEC4; break; case TYPE_SPECIFIER_INT: - spec->type = slang_spec_int; + spec->type = SLANG_SPEC_INT; break; case TYPE_SPECIFIER_IVEC2: - spec->type = slang_spec_ivec2; + spec->type = SLANG_SPEC_IVEC2; break; case TYPE_SPECIFIER_IVEC3: - spec->type = slang_spec_ivec3; + spec->type = SLANG_SPEC_IVEC3; break; case TYPE_SPECIFIER_IVEC4: - spec->type = slang_spec_ivec4; + spec->type = SLANG_SPEC_IVEC4; break; case TYPE_SPECIFIER_FLOAT: - spec->type = slang_spec_float; + spec->type = SLANG_SPEC_FLOAT; break; case TYPE_SPECIFIER_VEC2: - spec->type = slang_spec_vec2; + spec->type = SLANG_SPEC_VEC2; break; case TYPE_SPECIFIER_VEC3: - spec->type = slang_spec_vec3; + spec->type = SLANG_SPEC_VEC3; break; case TYPE_SPECIFIER_VEC4: - spec->type = slang_spec_vec4; + spec->type = SLANG_SPEC_VEC4; break; case TYPE_SPECIFIER_MAT2: - spec->type = slang_spec_mat2; + spec->type = SLANG_SPEC_MAT2; break; case TYPE_SPECIFIER_MAT3: - spec->type = slang_spec_mat3; + spec->type = SLANG_SPEC_MAT3; break; case TYPE_SPECIFIER_MAT4: - spec->type = slang_spec_mat4; + spec->type = SLANG_SPEC_MAT4; break; case TYPE_SPECIFIER_SAMPLER1D: - spec->type = slang_spec_sampler1D; + spec->type = SLANG_SPEC_SAMPLER1D; break; case TYPE_SPECIFIER_SAMPLER2D: - spec->type = slang_spec_sampler2D; + spec->type = SLANG_SPEC_SAMPLER2D; break; case TYPE_SPECIFIER_SAMPLER3D: - spec->type = slang_spec_sampler3D; + spec->type = SLANG_SPEC_SAMPLER3D; break; case TYPE_SPECIFIER_SAMPLERCUBE: - spec->type = slang_spec_samplerCube; + spec->type = SLANG_SPEC_SAMPLERCUBE; break; case TYPE_SPECIFIER_SAMPLER1DSHADOW: - spec->type = slang_spec_sampler1DShadow; + spec->type = SLANG_SPEC_SAMPLER1DSHADOW; break; case TYPE_SPECIFIER_SAMPLER2DSHADOW: - spec->type = slang_spec_sampler2DShadow; + spec->type = SLANG_SPEC_SAMPLER2DSHADOW; break; case TYPE_SPECIFIER_STRUCT: - spec->type = slang_spec_struct; + spec->type = SLANG_SPEC_STRUCT; if (!parse_struct(C, O, &spec->_struct)) return 0; break; case TYPE_SPECIFIER_TYPENAME: - spec->type = slang_spec_struct; + spec->type = SLANG_SPEC_STRUCT; { slang_atom a_name; slang_struct *stru; @@ -814,7 +817,7 @@ parse_statement(slang_parse_ctx * C, slang_output_ctx * O, switch (*C->I++) { case OP_BLOCK_BEGIN_NO_NEW_SCOPE: /* parse child statements, do not create new variable scope */ - oper->type = slang_oper_block_no_new_scope; + oper->type = SLANG_OPER_BLOCK_NO_NEW_SCOPE; while (*C->I != OP_END) if (!parse_child_operation(C, O, oper, 1)) return 0; @@ -825,7 +828,7 @@ parse_statement(slang_parse_ctx * C, slang_output_ctx * O, { slang_output_ctx o = *O; - oper->type = slang_oper_block_new_scope; + oper->type = SLANG_OPER_BLOCK_NEW_SCOPE; o.vars = oper->locals; while (*C->I != OP_END) if (!parse_child_operation(C, &o, oper, 1)) @@ -837,7 +840,7 @@ parse_statement(slang_parse_ctx * C, slang_output_ctx * O, /* local variable declaration, individual declarators are stored as * children identifiers */ - oper->type = slang_oper_block_no_new_scope; + oper->type = SLANG_OPER_BLOCK_NO_NEW_SCOPE; { const unsigned int first_var = O->vars->num_variables; @@ -858,7 +861,7 @@ parse_statement(slang_parse_ctx * C, slang_output_ctx * O, } for (i = first_var; i < O->vars->num_variables; i++) { slang_operation *o = &oper->children[i - first_var]; - o->type = slang_oper_variable_decl; + o->type = SLANG_OPER_VARIABLE_DECL; o->locals->outer_scope = O->vars; o->a_id = O->vars->variables[i]->a_name; } @@ -869,7 +872,7 @@ parse_statement(slang_parse_ctx * C, slang_output_ctx * O, /* the __asm statement, parse the mnemonic and all its arguments * as expressions */ - oper->type = slang_oper_asm; + oper->type = SLANG_OPER_ASM; oper->a_id = parse_identifier(C); if (oper->a_id == SLANG_ATOM_NULL) return 0; @@ -880,26 +883,26 @@ parse_statement(slang_parse_ctx * C, slang_output_ctx * O, C->I++; break; case OP_BREAK: - oper->type = slang_oper_break; + oper->type = SLANG_OPER_BREAK; break; case OP_CONTINUE: - oper->type = slang_oper_continue; + oper->type = SLANG_OPER_CONTINUE; break; case OP_DISCARD: - oper->type = slang_oper_discard; + oper->type = SLANG_OPER_DISCARD; break; case OP_RETURN: - oper->type = slang_oper_return; + oper->type = SLANG_OPER_RETURN; if (!parse_child_operation(C, O, oper, 0)) return 0; break; case OP_EXPRESSION: - oper->type = slang_oper_expression; + oper->type = SLANG_OPER_EXPRESSION; if (!parse_child_operation(C, O, oper, 0)) return 0; break; case OP_IF: - oper->type = slang_oper_if; + oper->type = SLANG_OPER_IF; if (!parse_child_operation(C, O, oper, 0)) return 0; if (!parse_child_operation(C, O, oper, 1)) @@ -911,7 +914,7 @@ parse_statement(slang_parse_ctx * C, slang_output_ctx * O, { slang_output_ctx o = *O; - oper->type = slang_oper_while; + oper->type = SLANG_OPER_WHILE; o.vars = oper->locals; if (!parse_child_operation(C, &o, oper, 1)) return 0; @@ -920,7 +923,7 @@ parse_statement(slang_parse_ctx * C, slang_output_ctx * O, } break; case OP_DO: - oper->type = slang_oper_do; + oper->type = SLANG_OPER_DO; if (!parse_child_operation(C, O, oper, 1)) return 0; if (!parse_child_operation(C, O, oper, 0)) @@ -930,7 +933,7 @@ parse_statement(slang_parse_ctx * C, slang_output_ctx * O, { slang_output_ctx o = *O; - oper->type = slang_oper_for; + oper->type = SLANG_OPER_FOR; o.vars = oper->locals; if (!parse_child_operation(C, &o, oper, 1)) return 0; @@ -983,7 +986,7 @@ static int is_constructor_name(const char *name, slang_atom a_name, slang_struct_scope * structs) { - if (slang_type_specifier_type_from_string(name) != slang_spec_void) + if (slang_type_specifier_type_from_string(name) != SLANG_SPEC_VOID) return 1; return slang_struct_scope_find(structs, a_name, 1) != NULL; } @@ -1019,10 +1022,10 @@ parse_expression(slang_parse_ctx * C, slang_output_ctx * O, switch (op_code) { case OP_PUSH_VOID: - op->type = slang_oper_void; + op->type = SLANG_OPER_VOID; break; case OP_PUSH_BOOL: - op->type = slang_oper_literal_bool; + op->type = SLANG_OPER_LITERAL_BOOL; if (!parse_number(C, &number)) return 0; op->literal[0] = @@ -1032,7 +1035,7 @@ parse_expression(slang_parse_ctx * C, slang_output_ctx * O, op->literal_size = 1; break; case OP_PUSH_INT: - op->type = slang_oper_literal_int; + op->type = SLANG_OPER_LITERAL_INT; if (!parse_number(C, &number)) return 0; op->literal[0] = @@ -1042,7 +1045,7 @@ parse_expression(slang_parse_ctx * C, slang_output_ctx * O, op->literal_size = 1; break; case OP_PUSH_FLOAT: - op->type = slang_oper_literal_float; + op->type = SLANG_OPER_LITERAL_FLOAT; if (!parse_float(C, &op->literal[0])) return 0; op->literal[1] = @@ -1051,38 +1054,38 @@ parse_expression(slang_parse_ctx * C, slang_output_ctx * O, op->literal_size = 1; break; case OP_PUSH_IDENTIFIER: - op->type = slang_oper_identifier; + op->type = SLANG_OPER_IDENTIFIER; op->a_id = parse_identifier(C); if (op->a_id == SLANG_ATOM_NULL) return 0; break; case OP_SEQUENCE: - op->type = slang_oper_sequence; + op->type = SLANG_OPER_SEQUENCE; if (!handle_nary_expression(C, op, &ops, &num_ops, 2)) return 0; break; case OP_ASSIGN: - op->type = slang_oper_assign; + op->type = SLANG_OPER_ASSIGN; if (!handle_nary_expression(C, op, &ops, &num_ops, 2)) return 0; break; case OP_ADDASSIGN: - op->type = slang_oper_addassign; + op->type = SLANG_OPER_ADDASSIGN; if (!handle_nary_expression(C, op, &ops, &num_ops, 2)) return 0; break; case OP_SUBASSIGN: - op->type = slang_oper_subassign; + op->type = SLANG_OPER_SUBASSIGN; if (!handle_nary_expression(C, op, &ops, &num_ops, 2)) return 0; break; case OP_MULASSIGN: - op->type = slang_oper_mulassign; + op->type = SLANG_OPER_MULASSIGN; if (!handle_nary_expression(C, op, &ops, &num_ops, 2)) return 0; break; case OP_DIVASSIGN: - op->type = slang_oper_divassign; + op->type = SLANG_OPER_DIVASSIGN; if (!handle_nary_expression(C, op, &ops, &num_ops, 2)) return 0; break; @@ -1093,22 +1096,22 @@ parse_expression(slang_parse_ctx * C, slang_output_ctx * O, /*case OP_XORASSIGN: */ /*case OP_ANDASSIGN: */ case OP_SELECT: - op->type = slang_oper_select; + op->type = SLANG_OPER_SELECT; if (!handle_nary_expression(C, op, &ops, &num_ops, 3)) return 0; break; case OP_LOGICALOR: - op->type = slang_oper_logicalor; + op->type = SLANG_OPER_LOGICALOR; if (!handle_nary_expression(C, op, &ops, &num_ops, 2)) return 0; break; case OP_LOGICALXOR: - op->type = slang_oper_logicalxor; + op->type = SLANG_OPER_LOGICALXOR; if (!handle_nary_expression(C, op, &ops, &num_ops, 2)) return 0; break; case OP_LOGICALAND: - op->type = slang_oper_logicaland; + op->type = SLANG_OPER_LOGICALAND; if (!handle_nary_expression(C, op, &ops, &num_ops, 2)) return 0; break; @@ -1116,91 +1119,91 @@ parse_expression(slang_parse_ctx * C, slang_output_ctx * O, /*case OP_BITXOR: */ /*case OP_BITAND: */ case OP_EQUAL: - op->type = slang_oper_equal; + op->type = SLANG_OPER_EQUAL; if (!handle_nary_expression(C, op, &ops, &num_ops, 2)) return 0; break; case OP_NOTEQUAL: - op->type = slang_oper_notequal; + op->type = SLANG_OPER_NOTEQUAL; if (!handle_nary_expression(C, op, &ops, &num_ops, 2)) return 0; break; case OP_LESS: - op->type = slang_oper_less; + op->type = SLANG_OPER_LESS; if (!handle_nary_expression(C, op, &ops, &num_ops, 2)) return 0; break; case OP_GREATER: - op->type = slang_oper_greater; + op->type = SLANG_OPER_GREATER; if (!handle_nary_expression(C, op, &ops, &num_ops, 2)) return 0; break; case OP_LESSEQUAL: - op->type = slang_oper_lessequal; + op->type = SLANG_OPER_LESSequal; if (!handle_nary_expression(C, op, &ops, &num_ops, 2)) return 0; break; case OP_GREATEREQUAL: - op->type = slang_oper_greaterequal; + op->type = SLANG_OPER_GREATERequal; if (!handle_nary_expression(C, op, &ops, &num_ops, 2)) return 0; break; /*case OP_LSHIFT: */ /*case OP_RSHIFT: */ case OP_ADD: - op->type = slang_oper_add; + op->type = SLANG_OPER_ADD; if (!handle_nary_expression(C, op, &ops, &num_ops, 2)) return 0; break; case OP_SUBTRACT: - op->type = slang_oper_subtract; + op->type = SLANG_OPER_SUBTRACT; if (!handle_nary_expression(C, op, &ops, &num_ops, 2)) return 0; break; case OP_MULTIPLY: - op->type = slang_oper_multiply; + op->type = SLANG_OPER_MULTIPLY; if (!handle_nary_expression(C, op, &ops, &num_ops, 2)) return 0; break; case OP_DIVIDE: - op->type = slang_oper_divide; + op->type = SLANG_OPER_DIVIDE; if (!handle_nary_expression(C, op, &ops, &num_ops, 2)) return 0; break; /*case OP_MODULUS: */ case OP_PREINCREMENT: - op->type = slang_oper_preincrement; + op->type = SLANG_OPER_PREINCREMENT; if (!handle_nary_expression(C, op, &ops, &num_ops, 1)) return 0; break; case OP_PREDECREMENT: - op->type = slang_oper_predecrement; + op->type = SLANG_OPER_PREDECREMENT; if (!handle_nary_expression(C, op, &ops, &num_ops, 1)) return 0; break; case OP_PLUS: - op->type = slang_oper_plus; + op->type = SLANG_OPER_PLUS; if (!handle_nary_expression(C, op, &ops, &num_ops, 1)) return 0; break; case OP_MINUS: - op->type = slang_oper_minus; + op->type = SLANG_OPER_MINUS; if (!handle_nary_expression(C, op, &ops, &num_ops, 1)) return 0; break; case OP_NOT: - op->type = slang_oper_not; + op->type = SLANG_OPER_NOT; if (!handle_nary_expression(C, op, &ops, &num_ops, 1)) return 0; break; /*case OP_COMPLEMENT: */ case OP_SUBSCRIPT: - op->type = slang_oper_subscript; + op->type = SLANG_OPER_SUBSCRIPT; if (!handle_nary_expression(C, op, &ops, &num_ops, 2)) return 0; break; case OP_CALL: - op->type = slang_oper_call; + op->type = SLANG_OPER_CALL; op->a_id = parse_identifier(C); if (op->a_id == SLANG_ATOM_NULL) return 0; @@ -1221,7 +1224,7 @@ parse_expression(slang_parse_ctx * C, slang_output_ctx * O, } break; case OP_FIELD: - op->type = slang_oper_field; + op->type = SLANG_OPER_FIELD; op->a_id = parse_identifier(C); if (op->a_id == SLANG_ATOM_NULL) return 0; @@ -1229,12 +1232,12 @@ parse_expression(slang_parse_ctx * C, slang_output_ctx * O, return 0; break; case OP_POSTINCREMENT: - op->type = slang_oper_postincrement; + op->type = SLANG_OPER_POSTINCREMENT; if (!handle_nary_expression(C, op, &ops, &num_ops, 1)) return 0; break; case OP_POSTDECREMENT: - op->type = slang_oper_postdecrement; + op->type = SLANG_OPER_POSTDECREMENT; if (!handle_nary_expression(C, op, &ops, &num_ops, 1)) return 0; break; @@ -1270,23 +1273,23 @@ parse_parameter_declaration(slang_parse_ctx * C, slang_output_ctx * O, return 0; switch (*C->I++) { case PARAM_QUALIFIER_IN: - if (param->type.qualifier != slang_qual_const - && param->type.qualifier != slang_qual_none) { + if (param->type.qualifier != SLANG_QUAL_CONST + && param->type.qualifier != SLANG_QUAL_NONE) { slang_info_log_error(C->L, "Invalid type qualifier."); return 0; } break; case PARAM_QUALIFIER_OUT: - if (param->type.qualifier == slang_qual_none) - param->type.qualifier = slang_qual_out; + if (param->type.qualifier == SLANG_QUAL_NONE) + param->type.qualifier = SLANG_QUAL_OUT; else { slang_info_log_error(C->L, "Invalid type qualifier."); return 0; } break; case PARAM_QUALIFIER_INOUT: - if (param->type.qualifier == slang_qual_none) - param->type.qualifier = slang_qual_inout; + if (param->type.qualifier == SLANG_QUAL_NONE) + param->type.qualifier = SLANG_QUAL_INOUT; else { slang_info_log_error(C->L, "Invalid type qualifier."); return 0; @@ -1436,14 +1439,14 @@ parse_function_prototype(slang_parse_ctx * C, slang_output_ctx * O, return 0; switch (*C->I++) { case FUNCTION_ORDINARY: - func->kind = slang_func_ordinary; + func->kind = SLANG_FUNC_ORDINARY; func->header.a_name = parse_identifier(C); if (func->header.a_name == SLANG_ATOM_NULL) return 0; break; case FUNCTION_CONSTRUCTOR: - func->kind = slang_func_constructor; - if (func->header.type.specifier.type == slang_spec_struct) + func->kind = SLANG_FUNC_CONSTRUCTOR; + if (func->header.type.specifier.type == SLANG_SPEC_STRUCT) return 0; func->header.a_name = slang_atom_pool_atom(C->atoms, @@ -1455,7 +1458,7 @@ parse_function_prototype(slang_parse_ctx * C, slang_output_ctx * O, } break; case FUNCTION_OPERATOR: - func->kind = slang_func_operator; + func->kind = SLANG_FUNC_OPERATOR; func->header.a_name = parse_operator_name(C); if (func->header.a_name == SLANG_ATOM_NULL) return 0; @@ -1484,7 +1487,7 @@ parse_function_prototype(slang_parse_ctx * C, slang_output_ctx * O, assert(a_retVal); p->a_name = a_retVal; p->type = func->header.type; - p->type.qualifier = slang_qual_out; + p->type.qualifier = SLANG_QUAL_OUT; } /* function formal parameters and local variables share the same @@ -1543,7 +1546,7 @@ initialize_global(slang_assemble_ctx * A, slang_variable * var) /* construct the left side of assignment */ if (!slang_operation_construct(&op_id)) return GL_FALSE; - op_id.type = slang_oper_identifier; + op_id.type = SLANG_OPER_IDENTIFIER; op_id.a_id = var->a_name; /* put the variable into operation's scope */ @@ -1562,7 +1565,7 @@ initialize_global(slang_assemble_ctx * A, slang_variable * var) slang_operation_destruct(&op_id); return GL_FALSE; } - op_assign.type = slang_oper_assign; + op_assign.type = SLANG_OPER_ASSIGN; op_assign.children = (slang_operation *) slang_alloc_malloc(2 * sizeof(slang_operation)); if (op_assign.children == NULL) { @@ -1686,7 +1689,7 @@ parse_init_declarator(slang_parse_ctx * C, slang_output_ctx * O, /* allocate global address space for a variable with a known size */ if (C->global_scope - && !(var->type.specifier.type == slang_spec_array + && !(var->type.specifier.type == SLANG_SPEC_ARRAY && var->array_len == 0)) { if (!calculate_var_size(C, O, var)) return GL_FALSE; @@ -1882,13 +1885,13 @@ parse_code_unit(slang_parse_ctx * C, slang_code_unit * unit, GLboolean success; GLuint maxRegs; - if (unit->type == slang_unit_fragment_builtin || - unit->type == slang_unit_fragment_shader) { + if (unit->type == SLANG_UNIT_FRAGMENT_BUILTIN || + unit->type == SLANG_UNIT_FRAGMENT_SHADER) { maxRegs = ctx->Const.FragmentProgram.MaxTemps; } else { - assert(unit->type == slang_unit_vertex_builtin || - unit->type == slang_unit_vertex_shader); + assert(unit->type == SLANG_UNIT_VERTEX_BUILTIN || + unit->type == SLANG_UNIT_VERTEX_SHADER); maxRegs = ctx->Const.VertexProgram.MaxTemps; } @@ -2052,8 +2055,8 @@ compile_object(grammar * id, const char *source, slang_code_object * object, } /* set shader type - the syntax is slightly different for different shaders */ - if (type == slang_unit_fragment_shader - || type == slang_unit_fragment_builtin) + if (type == SLANG_UNIT_FRAGMENT_SHADER + || type == SLANG_UNIT_FRAGMENT_BUILTIN) grammar_set_reg8(*id, (const byte *) "shader_type", 1); else grammar_set_reg8(*id, (const byte *) "shader_type", 2); @@ -2062,33 +2065,33 @@ compile_object(grammar * id, const char *source, slang_code_object * object, grammar_set_reg8(*id, (const byte *) "parsing_builtin", 1); /* if parsing user-specified shader, load built-in library */ - if (type == slang_unit_fragment_shader || type == slang_unit_vertex_shader) { + if (type == SLANG_UNIT_FRAGMENT_SHADER || type == SLANG_UNIT_VERTEX_SHADER) { /* compile core functionality first */ if (!compile_binary(slang_core_gc, &object->builtin[SLANG_BUILTIN_CORE], - slang_unit_fragment_builtin, infolog, + SLANG_UNIT_FRAGMENT_BUILTIN, infolog, NULL, NULL, NULL)) return GL_FALSE; /* compile common functions and variables, link to core */ if (!compile_binary(slang_common_builtin_gc, &object->builtin[SLANG_BUILTIN_COMMON], - slang_unit_fragment_builtin, infolog, NULL, + SLANG_UNIT_FRAGMENT_BUILTIN, infolog, NULL, &object->builtin[SLANG_BUILTIN_CORE], NULL)) return GL_FALSE; /* compile target-specific functions and variables, link to common */ - if (type == slang_unit_fragment_shader) { + if (type == SLANG_UNIT_FRAGMENT_SHADER) { if (!compile_binary(slang_fragment_builtin_gc, &object->builtin[SLANG_BUILTIN_TARGET], - slang_unit_fragment_builtin, infolog, NULL, + SLANG_UNIT_FRAGMENT_BUILTIN, infolog, NULL, &object->builtin[SLANG_BUILTIN_COMMON], NULL)) return GL_FALSE; } - else if (type == slang_unit_vertex_shader) { + else if (type == SLANG_UNIT_VERTEX_SHADER) { if (!compile_binary(slang_vertex_builtin_gc, &object->builtin[SLANG_BUILTIN_TARGET], - slang_unit_vertex_builtin, infolog, NULL, + SLANG_UNIT_VERTEX_BUILTIN, infolog, NULL, &object->builtin[SLANG_BUILTIN_COMMON], NULL)) return GL_FALSE; } @@ -2142,11 +2145,11 @@ _slang_compile(GLcontext *ctx, struct gl_shader *shader) slang_unit_type type; if (shader->Type == GL_VERTEX_SHADER) { - type = slang_unit_vertex_shader; + type = SLANG_UNIT_VERTEX_SHADER; } else { assert(shader->Type == GL_FRAGMENT_SHADER); - type = slang_unit_fragment_shader; + type = SLANG_UNIT_FRAGMENT_SHADER; } /* XXX temporary hack */ diff --git a/src/mesa/shader/slang/slang_compile.h b/src/mesa/shader/slang/slang_compile.h index e7be7ef0697..7abb92bd3b5 100644 --- a/src/mesa/shader/slang/slang_compile.h +++ b/src/mesa/shader/slang/slang_compile.h @@ -39,17 +39,19 @@ extern "C" { typedef enum slang_unit_type_ { - slang_unit_fragment_shader, - slang_unit_vertex_shader, - slang_unit_fragment_builtin, - slang_unit_vertex_builtin + SLANG_UNIT_FRAGMENT_SHADER, + SLANG_UNIT_VERTEX_SHADER, + SLANG_UNIT_FRAGMENT_BUILTIN, + SLANG_UNIT_VERTEX_BUILTIN } slang_unit_type; + typedef struct slang_var_pool_ { - GLuint next_addr; + GLuint next_addr; } slang_var_pool; + typedef struct slang_code_unit_ { slang_variable_scope vars; @@ -59,6 +61,7 @@ typedef struct slang_code_unit_ struct slang_code_object_ *object; } slang_code_unit; + extern GLvoid _slang_code_unit_ctr (slang_code_unit *, struct slang_code_object_ *); diff --git a/src/mesa/shader/slang/slang_compile_function.c b/src/mesa/shader/slang/slang_compile_function.c index 00a85c2e7de..9b0bdaf4064 100644 --- a/src/mesa/shader/slang/slang_compile_function.c +++ b/src/mesa/shader/slang/slang_compile_function.c @@ -71,7 +71,7 @@ slang_fixup_save(slang_fixup_table *fixups, GLuint address) int slang_function_construct(slang_function * func) { - func->kind = slang_func_ordinary; + func->kind = SLANG_FUNC_ORDINARY; if (!slang_variable_construct(&func->header)) return 0; @@ -133,7 +133,7 @@ slang_function_scope_destruct(slang_function_scope * scope) GLboolean _slang_function_has_return_value(const slang_function *fun) { - return fun->header.type.specifier.type != slang_spec_void; + return fun->header.type.specifier.type != SLANG_SPEC_VOID; } @@ -179,7 +179,7 @@ slang_function_scope_find(slang_function_scope * funcs, slang_function * fun, slang_function *f = &funcs->functions[i]; const GLuint haveRetValue = 0; #if 0 - = (f->header.type.specifier.type != slang_spec_void); + = (f->header.type.specifier.type != SLANG_SPEC_VOID); #endif unsigned int j; diff --git a/src/mesa/shader/slang/slang_compile_function.h b/src/mesa/shader/slang/slang_compile_function.h index 99a6b2a0349..b60b4a223f5 100644 --- a/src/mesa/shader/slang/slang_compile_function.h +++ b/src/mesa/shader/slang/slang_compile_function.h @@ -36,9 +36,9 @@ struct slang_code_unit_; */ typedef enum slang_function_kind_ { - slang_func_ordinary, - slang_func_constructor, - slang_func_operator + SLANG_FUNC_ORDINARY, + SLANG_FUNC_CONSTRUCTOR, + SLANG_FUNC_OPERATOR } slang_function_kind; diff --git a/src/mesa/shader/slang/slang_compile_operation.c b/src/mesa/shader/slang/slang_compile_operation.c index 51a64ca30ba..288de2d4bff 100644 --- a/src/mesa/shader/slang/slang_compile_operation.c +++ b/src/mesa/shader/slang/slang_compile_operation.c @@ -38,7 +38,7 @@ GLboolean slang_operation_construct(slang_operation * oper) { - oper->type = slang_oper_none; + oper->type = SLANG_OPER_NONE; oper->children = NULL; oper->num_children = 0; oper->literal[0] = 0.0; diff --git a/src/mesa/shader/slang/slang_compile_operation.h b/src/mesa/shader/slang/slang_compile_operation.h index 3f5b1bb8f39..a59f9684561 100644 --- a/src/mesa/shader/slang/slang_compile_operation.h +++ b/src/mesa/shader/slang/slang_compile_operation.h @@ -37,70 +37,70 @@ extern "C" { */ typedef enum slang_operation_type_ { - slang_oper_none, - slang_oper_block_no_new_scope, /* "{" sequence "}" */ - slang_oper_block_new_scope, /* "{" sequence "}" */ - slang_oper_variable_decl, /* [type] [var] or [var] = [expr] */ - slang_oper_asm, - slang_oper_break, /* "break" statement */ - slang_oper_continue, /* "continue" statement */ - slang_oper_discard, /* "discard" (kill fragment) statement */ - slang_oper_return, /* "return" [expr] */ - slang_oper_goto, /* jump to label */ - slang_oper_label, /* a jump target */ - slang_oper_expression, /* [expr] */ - slang_oper_if, /* "if" [0] then [1] else [2] */ - slang_oper_while, /* "while" [cond] [body] */ - slang_oper_do, /* "do" [body] "while" [cond] */ - slang_oper_for, /* "for" [init] [while] [incr] [body] */ - slang_oper_void, /* nop */ - slang_oper_literal_bool, /* "true" or "false" */ - slang_oper_literal_int, /* integer literal */ - slang_oper_literal_float, /* float literal */ - slang_oper_identifier, /* var name, func name, etc */ - slang_oper_sequence, /* [expr] "," [expr] "," etc */ - slang_oper_assign, /* [var] "=" [expr] */ - slang_oper_addassign, /* [var] "+=" [expr] */ - slang_oper_subassign, /* [var] "-=" [expr] */ - slang_oper_mulassign, /* [var] "*=" [expr] */ - slang_oper_divassign, /* [var] "/=" [expr] */ - /*slang_oper_modassign, */ - /*slang_oper_lshassign, */ - /*slang_oper_rshassign, */ - /*slang_oper_orassign, */ - /*slang_oper_xorassign, */ - /*slang_oper_andassign, */ - slang_oper_select, /* [expr] "?" [expr] ":" [expr] */ - slang_oper_logicalor, /* [expr] "||" [expr] */ - slang_oper_logicalxor, /* [expr] "^^" [expr] */ - slang_oper_logicaland, /* [expr] "&&" [expr] */ - /*slang_oper_bitor, */ - /*slang_oper_bitxor, */ - /*slang_oper_bitand, */ - slang_oper_equal, /* [expr] "==" [expr] */ - slang_oper_notequal, /* [expr] "!=" [expr] */ - slang_oper_less, /* [expr] "<" [expr] */ - slang_oper_greater, /* [expr] ">" [expr] */ - slang_oper_lessequal, /* [expr] "<=" [expr] */ - slang_oper_greaterequal, /* [expr] ">=" [expr] */ - /*slang_oper_lshift, */ - /*slang_oper_rshift, */ - slang_oper_add, /* [expr] "+" [expr] */ - slang_oper_subtract, /* [expr] "-" [expr] */ - slang_oper_multiply, /* [expr] "*" [expr] */ - slang_oper_divide, /* [expr] "/" [expr] */ - /*slang_oper_modulus, */ - slang_oper_preincrement, /* "++" [var] */ - slang_oper_predecrement, /* "--" [var] */ - slang_oper_plus, /* "-" [expr] */ - slang_oper_minus, /* "+" [expr] */ - /*slang_oper_complement, */ - slang_oper_not, /* "!" [expr] */ - slang_oper_subscript, /* [expr] "[" [expr] "]" */ - slang_oper_call, /* [func name] [param] [param] [...] */ - slang_oper_field, /* i.e.: ".next" or ".xzy" or ".xxx" etc */ - slang_oper_postincrement, /* [var] "++" */ - slang_oper_postdecrement /* [var] "--" */ + SLANG_OPER_NONE, + SLANG_OPER_BLOCK_NO_NEW_SCOPE, /* "{" sequence "}" */ + SLANG_OPER_BLOCK_NEW_SCOPE, /* "{" sequence "}" */ + SLANG_OPER_VARIABLE_DECL, /* [type] [var] or [var] = [expr] */ + SLANG_OPER_ASM, + SLANG_OPER_BREAK, /* "break" statement */ + SLANG_OPER_CONTINUE, /* "continue" statement */ + SLANG_OPER_DISCARD, /* "discard" (kill fragment) statement */ + SLANG_OPER_RETURN, /* "return" [expr] */ + SLANG_OPER_GOTO, /* jump to label */ + SLANG_OPER_LABEL, /* a jump target */ + SLANG_OPER_EXPRESSION, /* [expr] */ + SLANG_OPER_IF, /* "if" [0] then [1] else [2] */ + SLANG_OPER_WHILE, /* "while" [cond] [body] */ + SLANG_OPER_DO, /* "do" [body] "while" [cond] */ + SLANG_OPER_FOR, /* "for" [init] [while] [incr] [body] */ + SLANG_OPER_VOID, /* nop */ + SLANG_OPER_LITERAL_BOOL, /* "true" or "false" */ + SLANG_OPER_LITERAL_INT, /* integer literal */ + SLANG_OPER_LITERAL_FLOAT, /* float literal */ + SLANG_OPER_IDENTIFIER, /* var name, func name, etc */ + SLANG_OPER_SEQUENCE, /* [expr] "," [expr] "," etc */ + SLANG_OPER_ASSIGN, /* [var] "=" [expr] */ + SLANG_OPER_ADDASSIGN, /* [var] "+=" [expr] */ + SLANG_OPER_SUBASSIGN, /* [var] "-=" [expr] */ + SLANG_OPER_MULASSIGN, /* [var] "*=" [expr] */ + SLANG_OPER_DIVASSIGN, /* [var] "/=" [expr] */ + /*SLANG_OPER_MODASSIGN, */ + /*SLANG_OPER_LSHASSIGN, */ + /*SLANG_OPER_RSHASSIGN, */ + /*SLANG_OPER_ORASSIGN, */ + /*SLANG_OPER_XORASSIGN, */ + /*SLANG_OPER_ANDASSIGN, */ + SLANG_OPER_SELECT, /* [expr] "?" [expr] ":" [expr] */ + SLANG_OPER_LOGICALOR, /* [expr] "||" [expr] */ + SLANG_OPER_LOGICALXOR, /* [expr] "^^" [expr] */ + SLANG_OPER_LOGICALAND, /* [expr] "&&" [expr] */ + /*SLANG_OPER_BITOR, */ + /*SLANG_OPER_BITXOR, */ + /*SLANG_OPER_BITAND, */ + SLANG_OPER_EQUAL, /* [expr] "==" [expr] */ + SLANG_OPER_NOTEQUAL, /* [expr] "!=" [expr] */ + SLANG_OPER_LESS, /* [expr] "<" [expr] */ + SLANG_OPER_GREATER, /* [expr] ">" [expr] */ + SLANG_OPER_LESSequal, /* [expr] "<=" [expr] */ + SLANG_OPER_GREATERequal, /* [expr] ">=" [expr] */ + /*SLANG_OPER_LSHIFT, */ + /*SLANG_OPER_RSHIFT, */ + SLANG_OPER_ADD, /* [expr] "+" [expr] */ + SLANG_OPER_SUBTRACT, /* [expr] "-" [expr] */ + SLANG_OPER_MULTIPLY, /* [expr] "*" [expr] */ + SLANG_OPER_DIVIDE, /* [expr] "/" [expr] */ + /*SLANG_OPER_MODULUS, */ + SLANG_OPER_PREINCREMENT, /* "++" [var] */ + SLANG_OPER_PREDECREMENT, /* "--" [var] */ + SLANG_OPER_PLUS, /* "-" [expr] */ + SLANG_OPER_MINUS, /* "+" [expr] */ + /*SLANG_OPER_COMPLEMENT, */ + SLANG_OPER_NOT, /* "!" [expr] */ + SLANG_OPER_SUBSCRIPT, /* [expr] "[" [expr] "]" */ + SLANG_OPER_CALL, /* [func name] [param] [param] [...] */ + SLANG_OPER_FIELD, /* i.e.: ".next" or ".xzy" or ".xxx" etc */ + SLANG_OPER_POSTINCREMENT, /* [var] "++" */ + SLANG_OPER_POSTDECREMENT /* [var] "--" */ } slang_operation_type; @@ -120,7 +120,7 @@ typedef struct slang_operation_ GLuint literal_size; /**< 1, 2, 3, or 4 */ slang_atom a_id; /**< type: asm, identifier, call, field */ slang_variable_scope *locals; /**< local vars for scope */ - struct slang_function_ *fun; /**< If type == slang_oper_call */ + struct slang_function_ *fun; /**< If type == SLANG_OPER_CALL */ struct slang_variable_ *var; /**< If type == slang_oper_identier */ } slang_operation; diff --git a/src/mesa/shader/slang/slang_compile_struct.c b/src/mesa/shader/slang/slang_compile_struct.c index 5033a6cb108..5d876b248a2 100644 --- a/src/mesa/shader/slang/slang_compile_struct.c +++ b/src/mesa/shader/slang/slang_compile_struct.c @@ -160,7 +160,7 @@ int slang_struct_equal (const slang_struct *x, const slang_struct *y) return 0; if (!slang_type_specifier_equal (&varx->type.specifier, &vary->type.specifier)) return 0; - if (varx->type.specifier.type == slang_spec_array) + if (varx->type.specifier.type == SLANG_SPEC_ARRAY) if (varx->array_len != vary->array_len) return GL_FALSE; } diff --git a/src/mesa/shader/slang/slang_compile_variable.c b/src/mesa/shader/slang/slang_compile_variable.c index 25fbc21f823..450ae163231 100644 --- a/src/mesa/shader/slang/slang_compile_variable.c +++ b/src/mesa/shader/slang/slang_compile_variable.c @@ -40,29 +40,29 @@ typedef struct } type_specifier_type_name; static const type_specifier_type_name type_specifier_type_names[] = { - {"void", slang_spec_void}, - {"bool", slang_spec_bool}, - {"bvec2", slang_spec_bvec2}, - {"bvec3", slang_spec_bvec3}, - {"bvec4", slang_spec_bvec4}, - {"int", slang_spec_int}, - {"ivec2", slang_spec_ivec2}, - {"ivec3", slang_spec_ivec3}, - {"ivec4", slang_spec_ivec4}, - {"float", slang_spec_float}, - {"vec2", slang_spec_vec2}, - {"vec3", slang_spec_vec3}, - {"vec4", slang_spec_vec4}, - {"mat2", slang_spec_mat2}, - {"mat3", slang_spec_mat3}, - {"mat4", slang_spec_mat4}, - {"sampler1D", slang_spec_sampler1D}, - {"sampler2D", slang_spec_sampler2D}, - {"sampler3D", slang_spec_sampler3D}, - {"samplerCube", slang_spec_samplerCube}, - {"sampler1DShadow", slang_spec_sampler1DShadow}, - {"sampler2DShadow", slang_spec_sampler2DShadow}, - {NULL, slang_spec_void} + {"void", SLANG_SPEC_VOID}, + {"bool", SLANG_SPEC_BOOL}, + {"bvec2", SLANG_SPEC_BVEC2}, + {"bvec3", SLANG_SPEC_BVEC3}, + {"bvec4", SLANG_SPEC_BVEC4}, + {"int", SLANG_SPEC_INT}, + {"ivec2", SLANG_SPEC_IVEC2}, + {"ivec3", SLANG_SPEC_IVEC3}, + {"ivec4", SLANG_SPEC_IVEC4}, + {"float", SLANG_SPEC_FLOAT}, + {"vec2", SLANG_SPEC_VEC2}, + {"vec3", SLANG_SPEC_VEC3}, + {"vec4", SLANG_SPEC_VEC4}, + {"mat2", SLANG_SPEC_MAT2}, + {"mat3", SLANG_SPEC_MAT3}, + {"mat4", SLANG_SPEC_MAT4}, + {"sampler1D", SLANG_SPEC_SAMPLER1D}, + {"sampler2D", SLANG_SPEC_SAMPLER2D}, + {"sampler3D", SLANG_SPEC_SAMPLER3D}, + {"samplerCube", SLANG_SPEC_SAMPLERCUBE}, + {"sampler1DShadow", SLANG_SPEC_SAMPLER1DSHADOW}, + {"sampler2DShadow", SLANG_SPEC_SAMPLER2DSHADOW}, + {NULL, SLANG_SPEC_VOID} }; slang_type_specifier_type @@ -94,7 +94,7 @@ slang_type_specifier_type_to_string(slang_type_specifier_type type) int slang_fully_specified_type_construct(slang_fully_specified_type * type) { - type->qualifier = slang_qual_none; + type->qualifier = SLANG_QUAL_NONE; slang_type_specifier_ctr(&type->specifier); return 1; } @@ -333,49 +333,49 @@ static GLenum gl_type_from_specifier(const slang_type_specifier * type) { switch (type->type) { - case slang_spec_bool: + case SLANG_SPEC_BOOL: return GL_BOOL_ARB; - case slang_spec_bvec2: + case SLANG_SPEC_BVEC2: return GL_BOOL_VEC2_ARB; - case slang_spec_bvec3: + case SLANG_SPEC_BVEC3: return GL_BOOL_VEC3_ARB; - case slang_spec_bvec4: + case SLANG_SPEC_BVEC4: return GL_BOOL_VEC4_ARB; - case slang_spec_int: + case SLANG_SPEC_INT: return GL_INT; - case slang_spec_ivec2: + case SLANG_SPEC_IVEC2: return GL_INT_VEC2_ARB; - case slang_spec_ivec3: + case SLANG_SPEC_IVEC3: return GL_INT_VEC3_ARB; - case slang_spec_ivec4: + case SLANG_SPEC_IVEC4: return GL_INT_VEC4_ARB; - case slang_spec_float: + case SLANG_SPEC_FLOAT: return GL_FLOAT; - case slang_spec_vec2: + case SLANG_SPEC_VEC2: return GL_FLOAT_VEC2_ARB; - case slang_spec_vec3: + case SLANG_SPEC_VEC3: return GL_FLOAT_VEC3_ARB; - case slang_spec_vec4: + case SLANG_SPEC_VEC4: return GL_FLOAT_VEC4_ARB; - case slang_spec_mat2: + case SLANG_SPEC_MAT2: return GL_FLOAT_MAT2_ARB; - case slang_spec_mat3: + case SLANG_SPEC_MAT3: return GL_FLOAT_MAT3_ARB; - case slang_spec_mat4: + case SLANG_SPEC_MAT4: return GL_FLOAT_MAT4_ARB; - case slang_spec_sampler1D: + case SLANG_SPEC_SAMPLER1D: return GL_SAMPLER_1D_ARB; - case slang_spec_sampler2D: + case SLANG_SPEC_SAMPLER2D: return GL_SAMPLER_2D_ARB; - case slang_spec_sampler3D: + case SLANG_SPEC_SAMPLER3D: return GL_SAMPLER_3D_ARB; - case slang_spec_samplerCube: + case SLANG_SPEC_SAMPLERCUBE: return GL_SAMPLER_CUBE_ARB; - case slang_spec_sampler1DShadow: + case SLANG_SPEC_SAMPLER1DShadow: return GL_SAMPLER_1D_SHADOW_ARB; - case slang_spec_sampler2DShadow: + case SLANG_SPEC_SAMPLER2DShadow: return GL_SAMPLER_2D_SHADOW_ARB; - case slang_spec_array: + case SLANG_SPEC_ARRAy: return gl_type_from_specifier(type->_array); default: return GL_FLOAT; diff --git a/src/mesa/shader/slang/slang_compile_variable.h b/src/mesa/shader/slang/slang_compile_variable.h index 841f9840a63..d12cfd7a401 100644 --- a/src/mesa/shader/slang/slang_compile_variable.h +++ b/src/mesa/shader/slang/slang_compile_variable.h @@ -32,15 +32,15 @@ extern "C" { typedef enum slang_type_qualifier_ { - slang_qual_none, - slang_qual_const, - slang_qual_attribute, - slang_qual_varying, - slang_qual_uniform, - slang_qual_out, - slang_qual_inout, - slang_qual_fixedoutput, /* internal */ - slang_qual_fixedinput /* internal */ + SLANG_QUAL_NONE, + SLANG_QUAL_CONST, + SLANG_QUAL_ATTRIBUTE, + SLANG_QUAL_VARYING, + SLANG_QUAL_UNIFORM, + SLANG_QUAL_OUT, + SLANG_QUAL_INOUT, + SLANG_QUAL_FIXEDOUTPUT, /* internal */ + SLANG_QUAL_FIXEDINPUT /* internal */ } slang_type_qualifier; extern slang_type_specifier_type @@ -75,7 +75,7 @@ typedef struct slang_variable_ { slang_fully_specified_type type; /**< Variable's data type */ slang_atom a_name; /**< The variable's name (char *) */ - GLuint array_len; /**< only if type == slang_spec_array */ + GLuint array_len; /**< only if type == SLANG_SPEC_ARRAy */ struct slang_operation_ *initializer; /**< Optional initializer code */ GLuint address; /**< Storage location */ GLuint size; /**< Variable's size in bytes */ diff --git a/src/mesa/shader/slang/slang_emit.c b/src/mesa/shader/slang/slang_emit.c index 3faacdd4cf8..955f428b95b 100644 --- a/src/mesa/shader/slang/slang_emit.c +++ b/src/mesa/shader/slang/slang_emit.c @@ -40,7 +40,12 @@ #define PEEPHOLE_OPTIMIZATIONS 1 -#define ANNOTATE 1 +#define ANNOTATE 0 + + +/* XXX temporarily here */ +static GLboolean EmitHighLevelInstructions = GL_TRUE; + /** @@ -56,7 +61,7 @@ typedef struct -static slang_ir_info IrInfo[] = { +static const slang_ir_info IrInfo[] = { /* binary ops */ { IR_ADD, "IR_ADD", OPCODE_ADD, 4, 2 }, { IR_SUB, "IR_SUB", OPCODE_SUB, 4, 2 }, @@ -103,8 +108,6 @@ static slang_ir_info IrInfo[] = { { IR_CJUMP0, "IR_CJUMP0", OPCODE_NOP, 0, 0 }, { IR_CJUMP1, "IR_CJUMP1", OPCODE_NOP, 0, 0 }, { IR_IF, "IR_IF", OPCODE_NOP, 0, 0 }, - { IR_ELSE, "IR_ELSE", OPCODE_NOP, 0, 0 }, - { IR_ENDIF, "IR_ENDIF", OPCODE_NOP, 0, 0 }, { IR_KILL, "IR_KILL", OPCODE_NOP, 0, 0 }, { IR_COND, "IR_COND", OPCODE_NOP, 0, 0 }, { IR_CALL, "IR_CALL", OPCODE_NOP, 0, 0 }, @@ -115,7 +118,7 @@ static slang_ir_info IrInfo[] = { { IR_TEX, "IR_TEX", OPCODE_TEX, 4, 1 }, { IR_TEXB, "IR_TEXB", OPCODE_TXB, 4, 1 }, { IR_TEXP, "IR_TEXP", OPCODE_TXP, 4, 1 }, - { IR_FLOAT, "IR_FLOAT", OPCODE_NOP, 0, 0 }, + { IR_FLOAT, "IR_FLOAT", OPCODE_NOP, 0, 0 }, /* float literal */ { IR_FIELD, "IR_FIELD", OPCODE_NOP, 0, 0 }, { IR_ELEMENT, "IR_ELEMENT", OPCODE_NOP, 0, 0 }, { IR_SWIZZLE, "IR_SWIZZLE", OPCODE_NOP, 0, 0 }, @@ -123,7 +126,7 @@ static slang_ir_info IrInfo[] = { }; -static slang_ir_info * +static const slang_ir_info * slang_find_ir_info(slang_ir_opcode opcode) { GLuint i; @@ -232,11 +235,18 @@ storage_string(const slang_ir_storage *st) } +static void +spaces(int n) +{ + while (n-- > 0) { + printf(" "); + } +} + #define IND 0 void slang_print_ir(const slang_ir_node *n, int indent) { - int i; if (!n) return; #if !IND @@ -244,8 +254,7 @@ slang_print_ir(const slang_ir_node *n, int indent) #else printf("%3d:", indent); #endif - for (i = 0; i < indent; i++) - printf(" "); + spaces(indent); switch (n->Opcode) { case IR_SEQ: @@ -289,11 +298,14 @@ slang_print_ir(const slang_ir_node *n, int indent) case IR_IF: printf("IF \n"); slang_print_ir(n->Children[0], indent+3); - break; - case IR_ELSE: - printf("ELSE\n"); - break; - case IR_ENDIF: + spaces(indent); + printf("THEN\n"); + slang_print_ir(n->Children[1], indent+3); + if (n->Children[2]) { + spaces(indent); + printf("ELSE\n"); + slang_print_ir(n->Children[2], indent+3); + } printf("ENDIF\n"); break; @@ -310,11 +322,11 @@ slang_print_ir(const slang_ir_node *n, int indent) printf("CALL\n"); break; - case IR_BEGIN_LOOP: - printf("BEGIN_LOOP\n"); - break; - case IR_END_LOOP: - printf("END_LOOP\n"); + case IR_LOOP: + printf("LOOP\n"); + slang_print_ir(n->Children[0], indent+3); + spaces(indent); + printf("ENDLOOP\n"); break; case IR_CONT: printf("CONT\n"); @@ -322,6 +334,22 @@ slang_print_ir(const slang_ir_node *n, int indent) case IR_BREAK: printf("BREAK\n"); break; + case IR_BREAK_IF_FALSE: + printf("BREAK_IF_FALSE\n"); + slang_print_ir(n->Children[0], indent+3); + break; + case IR_BREAK_IF_TRUE: + printf("BREAK_IF_TRUE\n"); + slang_print_ir(n->Children[0], indent+3); + break; + case IR_CONT_IF_FALSE: + printf("CONT_IF_FALSE\n"); + slang_print_ir(n->Children[0], indent+3); + break; + case IR_CONT_IF_TRUE: + printf("CONT_IF_TRUE\n"); + slang_print_ir(n->Children[0], indent+3); + break; case IR_VAR: printf("VAR %s%s at %s store %p\n", @@ -340,11 +368,16 @@ slang_print_ir(const slang_ir_node *n, int indent) slang_print_ir(n->Children[0], indent+3); break; case IR_FLOAT: - printf("FLOAT %f %f %f %f\n", + printf("FLOAT %g %g %g %g\n", n->Value[0], n->Value[1], n->Value[2], n->Value[3]); break; case IR_I_TO_F: - printf("INT_TO_FLOAT %d\n", (int) n->Value[0]); + printf("INT_TO_FLOAT\n"); + slang_print_ir(n->Children[0], indent+3); + break; + case IR_F_TO_I: + printf("FLOAT_TO_INT\n"); + slang_print_ir(n->Children[0], indent+3); break; case IR_SWIZZLE: printf("SWIZZLE %s of (store %p) \n", @@ -474,6 +507,7 @@ new_instruction(struct gl_program *prog, gl_inst_opcode opcode) prog->NumInstructions++; _mesa_init_instructions(inst, 1); inst->Opcode = opcode; + inst->BranchTarget = -1; /* invalid */ return inst; } @@ -513,9 +547,9 @@ storage_annotation(const slang_ir_node *n, const struct gl_program *prog) if (st->Index >= 0) { const GLfloat *val = prog->Parameters->ParameterValues[st->Index]; if (st->Swizzle == SWIZZLE_NOOP) - sprintf(s, "{%f, %f, %f, %f}", val[0], val[1], val[2], val[3]); + sprintf(s, "{%g, %g, %g, %g}", val[0], val[1], val[2], val[3]); else { - sprintf(s, "%f", val[GET_SWZ(st->Swizzle, 0)]); + sprintf(s, "%g", val[GET_SWZ(st->Swizzle, 0)]); } } break; @@ -1041,6 +1075,186 @@ emit_not(slang_var_table *vt, slang_ir_node *n, struct gl_program *prog) } +static struct prog_instruction * +emit_if(slang_var_table *vt, slang_ir_node *n, struct gl_program *prog) +{ + struct prog_instruction *ifInst; + GLuint ifInstLoc, elseInstLoc; + + emit(vt, n->Children[0], prog); /* the condition */ + ifInstLoc = prog->NumInstructions; + if (EmitHighLevelInstructions) { + ifInst = new_instruction(prog, OPCODE_IF); + ifInst->DstReg.CondMask = COND_NE; /* if cond is non-zero */ + ifInst->DstReg.CondSwizzle = SWIZZLE_X; + } + else { + /* conditional jump to else, or endif */ + ifInst = new_instruction(prog, OPCODE_BRA); + ifInst->DstReg.CondMask = COND_EQ; /* BRA if cond is zero */ + ifInst->DstReg.CondSwizzle = SWIZZLE_X; + ifInst->Comment = _mesa_strdup("if zero"); + } + + /* if body */ + emit(vt, n->Children[1], prog); + + if (n->Children[2]) { + /* have else body */ + elseInstLoc = prog->NumInstructions; + if (EmitHighLevelInstructions) { + (void) new_instruction(prog, OPCODE_ELSE); + } + else { + /* jump to endif instruction */ + struct prog_instruction *inst; + inst = new_instruction(prog, OPCODE_BRA); + inst->Comment = _mesa_strdup("else"); + inst->DstReg.CondMask = COND_TR; /* always branch */ + } + ifInst = prog->Instructions + ifInstLoc; + ifInst->BranchTarget = prog->NumInstructions; + + emit(vt, n->Children[2], prog); + } + else { + /* no else body */ + ifInst = prog->Instructions + ifInstLoc; + ifInst->BranchTarget = prog->NumInstructions + 1; + } + + if (EmitHighLevelInstructions) { + (void) new_instruction(prog, OPCODE_ENDIF); + } + + if (n->Children[2]) { + struct prog_instruction *elseInst; + elseInst = prog->Instructions + elseInstLoc; + elseInst->BranchTarget = prog->NumInstructions; + } + return NULL; +} + + +static struct prog_instruction * +emit_loop(slang_var_table *vt, slang_ir_node *n, struct gl_program *prog) +{ + struct prog_instruction *beginInst, *endInst; + GLuint beginInstLoc, endInstLoc; + slang_ir_node *ir; + + /* emit OPCODE_BGNLOOP */ + beginInstLoc = prog->NumInstructions; + if (EmitHighLevelInstructions) { + (void) new_instruction(prog, OPCODE_BGNLOOP); + } + + /* body */ + emit(vt, n->Children[0], prog); + + endInstLoc = prog->NumInstructions; + if (EmitHighLevelInstructions) { + /* emit OPCODE_ENDLOOP */ + endInst = new_instruction(prog, OPCODE_ENDLOOP); + } + else { + /* emit unconditional BRA-nch */ + endInst = new_instruction(prog, OPCODE_BRA); + endInst->DstReg.CondMask = COND_TR; /* always true */ + } + /* end instruction's BranchTarget points to top of loop */ + endInst->BranchTarget = beginInstLoc; + + if (EmitHighLevelInstructions) { + /* BGNLOOP's BranchTarget points to the ENDLOOP inst */ + beginInst = prog->Instructions + beginInstLoc; + beginInst->BranchTarget = prog->NumInstructions - 1; + } + + /* Done emitting loop code. Now walk over the loop's linked list of + * BREAK and CONT nodes, filling in their BranchTarget fields (which + * will point to the ENDLOOP+1 or BGNLOOP instructions, respectively). + */ + for (ir = n->BranchNode; ir; ir = ir->BranchNode) { + struct prog_instruction *inst = prog->Instructions + ir->InstLocation; + assert(inst->BranchTarget < 0); + if (ir->Opcode == IR_BREAK || + ir->Opcode == IR_BREAK_IF_FALSE || + ir->Opcode == IR_BREAK_IF_TRUE) { + assert(inst->Opcode == OPCODE_BRK || + inst->Opcode == OPCODE_BRA); + /* go to instruction after end of loop */ + inst->BranchTarget = endInstLoc + 1; + } + else { + assert(ir->Opcode == IR_CONT || + ir->Opcode == IR_CONT_IF_FALSE || + ir->Opcode == IR_CONT_IF_TRUE); + assert(inst->Opcode == OPCODE_CONT || + inst->Opcode == OPCODE_BRA); + /* to go instruction at top of loop */ + inst->BranchTarget = beginInstLoc; + } + } + return NULL; +} + + +/** + * "Continue" or "break" statement. + * Either OPCODE_CONT, OPCODE_BRK or OPCODE_BRA will be emitted. + */ +static struct prog_instruction * +emit_cont_break(slang_var_table *vt, slang_ir_node *n, struct gl_program *prog) +{ + gl_inst_opcode opcode; + struct prog_instruction *inst; + n->InstLocation = prog->NumInstructions; + if (EmitHighLevelInstructions) { + opcode = (n->Opcode == IR_CONT) ? OPCODE_CONT : OPCODE_BRK; + } + else { + opcode = OPCODE_BRA; + } + inst = new_instruction(prog, opcode); + inst->DstReg.CondMask = COND_TR; /* always true */ + return inst; +} + + +/** + * Conditional "continue" or "break" statement. + * Either OPCODE_CONT, OPCODE_BRK or OPCODE_BRA will be emitted. + */ +static struct prog_instruction * +emit_cont_break_if(slang_var_table *vt, slang_ir_node *n, + struct gl_program *prog, GLboolean breakTrue) +{ + gl_inst_opcode opcode; + struct prog_instruction *inst; + + /* evaluate condition expr, setting cond codes */ + inst = emit(vt, n->Children[0], prog); + assert(inst); + inst->CondUpdate = GL_TRUE; + + n->InstLocation = prog->NumInstructions; + if (EmitHighLevelInstructions) { + if (n->Opcode == IR_CONT_IF_TRUE || + n->Opcode == IR_CONT_IF_FALSE) + opcode = OPCODE_CONT; + else + opcode = OPCODE_BRK; + } + else { + opcode = OPCODE_BRA; + } + inst = new_instruction(prog, opcode); + inst->DstReg.CondMask = breakTrue ? COND_NE : COND_EQ; + return inst; +} + + /** * Remove any SWIZZLE_NIL terms from given swizzle mask (smear prev term). @@ -1180,6 +1394,12 @@ emit(slang_var_table *vt, slang_ir_node *n, struct gl_program *prog) case IR_SWIZZLE: return emit_swizzle(vt, n, prog); + case IR_I_TO_F: + { + n->Store = n->Children[0]->Store; + } + return NULL; + /* Simple arithmetic */ /* unary */ case IR_RSQ: @@ -1254,78 +1474,21 @@ emit(slang_var_table *vt, slang_ir_node *n, struct gl_program *prog) return emit_kill(prog); case IR_IF: - { - struct prog_instruction *inst; - emit(vt, n->Children[0], prog); /* the condition */ - inst = new_instruction(prog, OPCODE_IF); - inst->DstReg.CondMask = COND_NE; /* if cond is non-zero */ - inst->DstReg.CondSwizzle = SWIZZLE_X; - n->InstLocation = prog->NumInstructions - 1; - return inst; - } - case IR_ELSE: - { - struct prog_instruction *inst, *ifInst; - n->InstLocation = prog->NumInstructions; - inst = new_instruction(prog, OPCODE_ELSE); - /* point IF's BranchTarget just after this instruction */ - assert(n->BranchNode); - assert(n->BranchNode->InstLocation >= 0); - ifInst = prog->Instructions + n->BranchNode->InstLocation; - assert(ifInst->Opcode == OPCODE_IF); - ifInst->BranchTarget = prog->NumInstructions; - return inst; - } - case IR_ENDIF: - { - struct prog_instruction *inst, *elseInst; - n->InstLocation = prog->NumInstructions; - inst = new_instruction(prog, OPCODE_ENDIF); - /* point ELSE's BranchTarget to just after this inst */ - assert(n->BranchNode); - assert(n->BranchNode->InstLocation >= 0); - elseInst = prog->Instructions + n->BranchNode->InstLocation; - assert(elseInst->Opcode == OPCODE_ELSE || - elseInst->Opcode == OPCODE_IF); - elseInst->BranchTarget = prog->NumInstructions; - return inst; - } - - case IR_BEGIN_LOOP: - { - /* save location of this instruction, used by OPCODE_ENDLOOP */ - n->InstLocation = prog->NumInstructions; - (void) new_instruction(prog, OPCODE_BGNLOOP); - } - break; - case IR_END_LOOP: - { - struct prog_instruction *inst, *beginInst; - inst = new_instruction(prog, OPCODE_ENDLOOP); - assert(n->BranchNode); - assert(n->BranchNode->InstLocation >= 0); - /* The instruction BranchTarget points to top of loop */ - inst->BranchTarget = n->BranchNode->InstLocation; - /* Update BEGIN_LOOP's BranchTarget to point to this instruction */ - beginInst = prog->Instructions + n->BranchNode->InstLocation; - beginInst->BranchTarget = prog->NumInstructions - 1; - return inst; - } - case IR_CONT: - return new_instruction(prog, OPCODE_CONT); + return emit_if(vt, n, prog); + + case IR_LOOP: + return emit_loop(vt, n, prog); + case IR_BREAK_IF_FALSE: + case IR_CONT_IF_FALSE: + return emit_cont_break_if(vt, n, prog, GL_FALSE); + case IR_BREAK_IF_TRUE: + case IR_CONT_IF_TRUE: + return emit_cont_break_if(vt, n, prog, GL_TRUE); case IR_BREAK: - { - struct prog_instruction *inst; - inst = new_instruction(prog, OPCODE_BRK); - inst->DstReg.CondMask = COND_TR; /* always true */ - /* This instruction's branch target is top of loop, not bottom of - * loop because we don't know where it is yet! - */ - assert(n->BranchNode); - assert(n->BranchNode->InstLocation >= 0); - inst->BranchTarget = n->BranchNode->InstLocation; - return inst; - } + /* fall-through */ + case IR_CONT: + return emit_cont_break(vt, n, prog); + case IR_BEGIN_SUB: return new_instruction(prog, OPCODE_BGNSUB); case IR_END_SUB: @@ -1333,6 +1496,9 @@ emit(slang_var_table *vt, slang_ir_node *n, struct gl_program *prog) case IR_RETURN: return new_instruction(prog, OPCODE_RET); + case IR_NOP: + return NULL; + default: _mesa_problem(NULL, "Unexpected IR opcode in emit()\n"); abort(); diff --git a/src/mesa/shader/slang/slang_ir.h b/src/mesa/shader/slang/slang_ir.h index df5fc067790..0c827d9cd8c 100644 --- a/src/mesa/shader/slang/slang_ir.h +++ b/src/mesa/shader/slang/slang_ir.h @@ -39,7 +39,7 @@ /** - * Intermediate Representation opcode + * Intermediate Representation opcodes */ typedef enum { @@ -53,20 +53,22 @@ typedef enum IR_CJUMP1, /* conditional jump if one (or non-zero) */ IR_COND, /* conditional expression/predicate */ - IR_IF, /* high-level IF */ - IR_ELSE, /* high-level ELSE */ - IR_ENDIF, /* high-level ENDIF */ + IR_IF, /* high-level IF/then/else */ IR_BEGIN_SUB, /* begin subroutine */ IR_END_SUB, /* end subroutine */ IR_RETURN, /* return from subroutine */ IR_CALL, /* call subroutine */ - IR_BEGIN_LOOP,/* begin loop */ - IR_END_LOOP, /* end loop */ + IR_LOOP, /* high-level loop-begin / loop-end */ IR_CONT, /* continue loop */ IR_BREAK, /* break loop */ + IR_BREAK_IF_TRUE, + IR_BREAK_IF_FALSE, + IR_CONT_IF_TRUE, + IR_CONT_IF_FALSE, + IR_MOVE, IR_ADD, IR_SUB, diff --git a/src/mesa/shader/slang/slang_link.c b/src/mesa/shader/slang/slang_link.c index 017cf6078cb..23977b7c2c2 100644 --- a/src/mesa/shader/slang/slang_link.c +++ b/src/mesa/shader/slang/slang_link.c @@ -2,7 +2,7 @@ * Mesa 3-D graphics library * Version: 6.5.3 * - * Copyright (C) 2006 Brian Paul All Rights Reserved. + * Copyright (C) 2007 Brian Paul 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"), @@ -23,7 +23,7 @@ */ /** - * \file slang_link2.c + * \file slang_link.c * GLSL linker * \author Brian Paul */ @@ -298,7 +298,7 @@ _slang_resolve_branches(struct gl_program *prog) for (i = 0; i < prog->NumInstructions; i++) { struct prog_instruction *inst = prog->Instructions + i; - if (inst->Opcode == OPCODE_BRA) { + if (inst->Opcode == OPCODE_BRA && inst->BranchTarget < 0) { for (j = 0; j < numTargets; j++) { if (!strcmp(inst->Comment, targets[j].Name)) { inst->BranchTarget = targets[j].Pos; @@ -506,9 +506,9 @@ fragment_program(struct gl_program *prog) * varying storage locations. */ void -_slang_link2(GLcontext *ctx, - GLhandleARB programObj, - struct gl_shader_program *shProg) +_slang_link(GLcontext *ctx, + GLhandleARB programObj, + struct gl_shader_program *shProg) { const struct gl_vertex_program *vertProg; const struct gl_fragment_program *fragProg; @@ -530,25 +530,8 @@ _slang_link2(GLcontext *ctx, else if (shProg->Shaders[i]->Type == GL_FRAGMENT_SHADER) fragProg = fragment_program(shProg->Shaders[i]->Programs[0]); else - _mesa_problem(ctx, "unexpected shader target in slang_link2()"); + _mesa_problem(ctx, "unexpected shader target in slang_link()"); } -#if 00 - if (!vertProg || !fragProg) { - /* XXX is it legal to have one but not the other?? */ - /* XXX record error */ - shProg->LinkStatus = GL_FALSE; - return; - } - - /* XXX is this test used? */ - if (!vertProg->Base.Varying || !fragProg->Base.Varying) { - /* temporary */ - _mesa_problem(ctx, "vertex/fragment program lacks varying list!"); - abort(); - shProg->LinkStatus = GL_FALSE; - return; - } -#endif /* * Make copies of the vertex/fragment programs now since we'll be @@ -638,10 +621,6 @@ _slang_link2(GLcontext *ctx, #endif } -#if 0 - shProg->LinkStatus = (shProg->VertexProgram && shProg->FragmentProgram); -#else shProg->LinkStatus = (shProg->VertexProgram || shProg->FragmentProgram); -#endif } diff --git a/src/mesa/shader/slang/slang_link.h b/src/mesa/shader/slang/slang_link.h index edd4a097d5a..606b9e46b16 100644 --- a/src/mesa/shader/slang/slang_link.h +++ b/src/mesa/shader/slang/slang_link.h @@ -29,8 +29,8 @@ extern void -_slang_link2(GLcontext *ctx, GLhandleARB h, - struct gl_shader_program *shProg); +_slang_link(GLcontext *ctx, GLhandleARB h, + struct gl_shader_program *shProg); extern void _slang_resolve_samplers(struct gl_shader_program *shProg, diff --git a/src/mesa/shader/slang/slang_print.c b/src/mesa/shader/slang/slang_print.c index 7cfd87fb627..e53378e4613 100644 --- a/src/mesa/shader/slang/slang_print.c +++ b/src/mesa/shader/slang/slang_print.c @@ -21,31 +21,31 @@ static void print_type(const slang_fully_specified_type *t) { switch (t->qualifier) { - case slang_qual_none: + case SLANG_QUAL_NONE: /*printf("");*/ break; - case slang_qual_const: + case SLANG_QUAL_CONST: printf("const "); break; - case slang_qual_attribute: + case SLANG_QUAL_ATTRIBUTE: printf("attrib "); break; - case slang_qual_varying: + case SLANG_QUAL_VARYING: printf("varying "); break; - case slang_qual_uniform: + case SLANG_QUAL_UNIFORM: printf("uniform "); break; - case slang_qual_out: + case SLANG_QUAL_OUT: printf("output "); break; - case slang_qual_inout: + case SLANG_QUAL_INOUT: printf("inout "); break; - case slang_qual_fixedoutput: + case SLANG_QUAL_FIXEDOUTPUT: printf("fixedoutput"); break; - case slang_qual_fixedinput: + case SLANG_QUAL_FIXEDINPUT: printf("fixedinput"); break; default: @@ -53,76 +53,76 @@ print_type(const slang_fully_specified_type *t) } switch (t->specifier.type) { - case slang_spec_void: + case SLANG_SPEC_VOID: printf("void"); break; - case slang_spec_bool: + case SLANG_SPEC_BOOL: printf("bool"); break; - case slang_spec_bvec2: + case SLANG_SPEC_BVEC2: printf("bvec2"); break; - case slang_spec_bvec3: + case SLANG_SPEC_BVEC3: printf("bvec3"); break; - case slang_spec_bvec4: + case SLANG_SPEC_BVEC4: printf("bvec4"); break; - case slang_spec_int: + case SLANG_SPEC_INT: printf("int"); break; - case slang_spec_ivec2: + case SLANG_SPEC_IVEC2: printf("ivec2"); break; - case slang_spec_ivec3: + case SLANG_SPEC_IVEC3: printf("ivec3"); break; - case slang_spec_ivec4: + case SLANG_SPEC_IVEC4: printf("ivec4"); break; - case slang_spec_float: + case SLANG_SPEC_FLOAT: printf("float"); break; - case slang_spec_vec2: + case SLANG_SPEC_VEC2: printf("vec2"); break; - case slang_spec_vec3: + case SLANG_SPEC_VEC3: printf("vec3"); break; - case slang_spec_vec4: + case SLANG_SPEC_VEC4: printf("vec4"); break; - case slang_spec_mat2: + case SLANG_SPEC_MAT2: printf("mat2"); break; - case slang_spec_mat3: + case SLANG_SPEC_MAT3: printf("mat3"); break; - case slang_spec_mat4: + case SLANG_SPEC_MAT4: printf("mat4"); break; - case slang_spec_sampler1D: + case SLANG_SPEC_SAMPLER1D: printf("sampler1D"); break; - case slang_spec_sampler2D: + case SLANG_SPEC_SAMPLER2D: printf("sampler2D"); break; - case slang_spec_sampler3D: + case SLANG_SPEC_SAMPLER3D: printf("sampler3D"); break; - case slang_spec_samplerCube: + case SLANG_SPEC_SAMPLERCUBE: printf("samplerCube"); break; - case slang_spec_sampler1DShadow: + case SLANG_SPEC_SAMPLER1DSHADOW: printf("sampler1DShadow"); break; - case slang_spec_sampler2DShadow: + case SLANG_SPEC_SAMPLER2DSHADOW: printf("sampler2DShadow"); break; - case slang_spec_struct: + case SLANG_SPEC_STRUCT: printf("struct"); break; - case slang_spec_array: + case SLANG_SPEC_ARRAY: printf("array"); break; default: @@ -219,12 +219,12 @@ slang_print_tree(const slang_operation *op, int indent) switch (op->type) { - case slang_oper_none: + case SLANG_OPER_NONE: spaces(indent); - printf("slang_oper_none\n"); + printf("SLANG_OPER_NONE\n"); break; - case slang_oper_block_no_new_scope: + case SLANG_OPER_BLOCK_NO_NEW_SCOPE: spaces(indent); printf("{ locals %p outer %p\n", (void*)op->locals, (void*)op->locals->outer_scope); print_generic(op, NULL, indent+3); @@ -232,7 +232,7 @@ slang_print_tree(const slang_operation *op, int indent) printf("}\n"); break; - case slang_oper_block_new_scope: + case SLANG_OPER_BLOCK_NEW_SCOPE: spaces(indent); printf("{{ // new scope locals %p\n", (void*)op->locals); print_generic(op, NULL, indent+3); @@ -240,7 +240,7 @@ slang_print_tree(const slang_operation *op, int indent) printf("}}\n"); break; - case slang_oper_variable_decl: + case SLANG_OPER_VARIABLE_DECL: assert(op->num_children == 0 || op->num_children == 1); { slang_variable *v; @@ -282,52 +282,52 @@ slang_print_tree(const slang_operation *op, int indent) } break; - case slang_oper_asm: + case SLANG_OPER_ASM: spaces(indent); printf("ASM: %s\n", (char*) op->a_id); print_generic(op, NULL, indent+3); break; - case slang_oper_break: + case SLANG_OPER_BREAK: spaces(indent); printf("BREAK\n"); break; - case slang_oper_continue: + case SLANG_OPER_CONTINUE: spaces(indent); printf("CONTINUE\n"); break; - case slang_oper_discard: + case SLANG_OPER_DISCARD: spaces(indent); printf("DISCARD\n"); break; - case slang_oper_return: + case SLANG_OPER_RETURN: spaces(indent); printf("RETURN\n"); if (op->num_children > 0) slang_print_tree(&op->children[0], indent + 3); break; - case slang_oper_goto: + case SLANG_OPER_GOTO: spaces(indent); printf("GOTO %s\n", (char *) op->a_id); break; - case slang_oper_label: + case SLANG_OPER_LABEL: spaces(indent); printf("LABEL %s\n", (char *) op->a_id); break; - case slang_oper_expression: + case SLANG_OPER_EXPRESSION: spaces(indent); printf("EXPR: locals %p\n", (void*) op->locals); - /*print_generic(op, "slang_oper_expression", indent);*/ + /*print_generic(op, "SLANG_OPER_EXPRESSION", indent);*/ slang_print_tree(&op->children[0], indent + 3); break; - case slang_oper_if: + case SLANG_OPER_IF: spaces(indent); printf("IF\n"); slang_print_tree(&op->children[0], indent + 3); @@ -341,7 +341,7 @@ slang_print_tree(const slang_operation *op, int indent) printf("ENDIF\n"); break; - case slang_oper_while: + case SLANG_OPER_WHILE: assert(op->num_children == 2); spaces(indent); printf("WHILE cond:\n"); @@ -351,7 +351,7 @@ slang_print_tree(const slang_operation *op, int indent) slang_print_tree(&op->children[1], indent + 3); break; - case slang_oper_do: + case SLANG_OPER_DO: spaces(indent); printf("DO body:\n"); slang_print_tree(&op->children[0], indent + 3); @@ -360,7 +360,7 @@ slang_print_tree(const slang_operation *op, int indent) slang_print_tree(&op->children[1], indent + 3); break; - case slang_oper_for: + case SLANG_OPER_FOR: spaces(indent); printf("FOR init:\n"); slang_print_tree(&op->children[0], indent + 3); @@ -380,32 +380,32 @@ slang_print_tree(const slang_operation *op, int indent) */ break; - case slang_oper_void: + case SLANG_OPER_VOID: spaces(indent); printf("(oper-void)\n"); break; - case slang_oper_literal_bool: + case SLANG_OPER_LITERAL_BOOL: spaces(indent); - /*printf("slang_oper_literal_bool\n");*/ + /*printf("SLANG_OPER_LITERAL_BOOL\n");*/ printf("%s\n", op->literal[0] ? "TRUE" : "FALSE"); break; - case slang_oper_literal_int: + case SLANG_OPER_LITERAL_INT: spaces(indent); - /*printf("slang_oper_literal_int\n");*/ + /*printf("SLANG_OPER_LITERAL_INT\n");*/ printf("(%d %d %d %d)\n", (int) op->literal[0], (int) op->literal[1], (int) op->literal[2], (int) op->literal[3]); break; - case slang_oper_literal_float: + case SLANG_OPER_LITERAL_FLOAT: spaces(indent); - /*printf("slang_oper_literal_float\n");*/ + /*printf("SLANG_OPER_LITERAL_FLOAT\n");*/ printf("(%f %f %f %f)\n", op->literal[0], op->literal[1], op->literal[2], op->literal[3]); break; - case slang_oper_identifier: + case SLANG_OPER_IDENTIFIER: spaces(indent); if (op->var && op->var->a_name) printf("VAR %s (in scope %p)\n", (char *) op->var->a_name, @@ -415,49 +415,49 @@ slang_print_tree(const slang_operation *op, int indent) (void *) find_scope(op->locals, op->a_id)); break; - case slang_oper_sequence: + case SLANG_OPER_SEQUENCE: print_generic(op, "COMMA-SEQ", indent+3); break; - case slang_oper_assign: + case SLANG_OPER_ASSIGN: spaces(indent); printf("ASSIGNMENT locals %p\n", (void*)op->locals); print_binary(op, ":=", indent); break; - case slang_oper_addassign: + case SLANG_OPER_ADDASSIGN: spaces(indent); printf("ASSIGN\n"); print_binary(op, "+=", indent); break; - case slang_oper_subassign: + case SLANG_OPER_SUBASSIGN: spaces(indent); printf("ASSIGN\n"); print_binary(op, "-=", indent); break; - case slang_oper_mulassign: + case SLANG_OPER_MULASSIGN: spaces(indent); printf("ASSIGN\n"); print_binary(op, "*=", indent); break; - case slang_oper_divassign: + case SLANG_OPER_DIVASSIGN: spaces(indent); printf("ASSIGN\n"); print_binary(op, "/=", indent); break; - /*slang_oper_modassign,*/ - /*slang_oper_lshassign,*/ - /*slang_oper_rshassign,*/ - /*slang_oper_orassign,*/ - /*slang_oper_xorassign,*/ - /*slang_oper_andassign,*/ - case slang_oper_select: + /*SLANG_OPER_MODASSIGN,*/ + /*SLANG_OPER_LSHASSIGN,*/ + /*SLANG_OPER_RSHASSIGN,*/ + /*SLANG_OPER_ORASSIGN,*/ + /*SLANG_OPER_XORASSIGN,*/ + /*SLANG_OPER_ANDASSIGN,*/ + case SLANG_OPER_SELECT: spaces(indent); - printf("slang_oper_select n=%d\n", op->num_children); + printf("SLANG_OPER_SELECT n=%d\n", op->num_children); assert(op->num_children == 3); slang_print_tree(&op->children[0], indent+3); spaces(indent); @@ -468,100 +468,100 @@ slang_print_tree(const slang_operation *op, int indent) slang_print_tree(&op->children[2], indent+3); break; - case slang_oper_logicalor: + case SLANG_OPER_LOGICALOR: print_binary(op, "||", indent); break; - case slang_oper_logicalxor: + case SLANG_OPER_LOGICALXOR: print_binary(op, "^^", indent); break; - case slang_oper_logicaland: + case SLANG_OPER_LOGICALAND: print_binary(op, "&&", indent); break; - /*slang_oper_bitor*/ - /*slang_oper_bitxor*/ - /*slang_oper_bitand*/ - case slang_oper_equal: + /*SLANG_OPER_BITOR*/ + /*SLANG_OPER_BITXOR*/ + /*SLANG_OPER_BITAND*/ + case SLANG_OPER_EQUAL: print_binary(op, "==", indent); break; - case slang_oper_notequal: + case SLANG_OPER_NOTEQUAL: print_binary(op, "!=", indent); break; - case slang_oper_less: + case SLANG_OPER_LESS: print_binary(op, "<", indent); break; - case slang_oper_greater: + case SLANG_OPER_GREATER: print_binary(op, ">", indent); break; - case slang_oper_lessequal: + case SLANG_OPER_LESSequal: print_binary(op, "<=", indent); break; - case slang_oper_greaterequal: + case SLANG_OPER_GREATERequal: print_binary(op, ">=", indent); break; - /*slang_oper_lshift*/ - /*slang_oper_rshift*/ - case slang_oper_add: + /*SLANG_OPER_LSHIFT*/ + /*SLANG_OPER_RSHIFT*/ + case SLANG_OPER_ADD: print_binary(op, "+", indent); break; - case slang_oper_subtract: + case SLANG_OPER_SUBTRACT: print_binary(op, "-", indent); break; - case slang_oper_multiply: + case SLANG_OPER_MULTIPLY: print_binary(op, "*", indent); break; - case slang_oper_divide: + case SLANG_OPER_DIVIDE: print_binary(op, "/", indent); break; - /*slang_oper_modulus*/ - case slang_oper_preincrement: + /*SLANG_OPER_MODULUS*/ + case SLANG_OPER_PREINCREMENT: spaces(indent); printf("PRE++\n"); slang_print_tree(&op->children[0], indent+3); break; - case slang_oper_predecrement: + case SLANG_OPER_PREDECREMENT: spaces(indent); printf("PRE--\n"); slang_print_tree(&op->children[0], indent+3); break; - case slang_oper_plus: + case SLANG_OPER_PLUS: spaces(indent); - printf("slang_oper_plus\n"); + printf("SLANG_OPER_PLUS\n"); break; - case slang_oper_minus: + case SLANG_OPER_MINUS: spaces(indent); - printf("slang_oper_minus\n"); + printf("SLANG_OPER_MINUS\n"); break; - /*slang_oper_complement*/ - case slang_oper_not: + /*SLANG_OPER_COMPLEMENT*/ + case SLANG_OPER_NOT: spaces(indent); printf("NOT\n"); slang_print_tree(&op->children[0], indent+3); break; - case slang_oper_subscript: + case SLANG_OPER_SUBSCRIPT: spaces(indent); - printf("slang_oper_subscript\n"); + printf("SLANG_OPER_SUBSCRIPT\n"); print_generic(op, NULL, indent+3); break; - case slang_oper_call: + case SLANG_OPER_CALL: #if 0 slang_function *fun = _slang_locate_function(A->space.funcs, oper->a_id, @@ -581,19 +581,19 @@ slang_print_tree(const slang_operation *op, int indent) printf(")\n"); break; - case slang_oper_field: + case SLANG_OPER_FIELD: spaces(indent); printf("FIELD %s of\n", (char*) op->a_id); slang_print_tree(&op->children[0], indent+3); break; - case slang_oper_postincrement: + case SLANG_OPER_POSTINCREMENT: spaces(indent); printf("POST++\n"); slang_print_tree(&op->children[0], indent+3); break; - case slang_oper_postdecrement: + case SLANG_OPER_POSTDECREMENT: spaces(indent); printf("POST--\n"); slang_print_tree(&op->children[0], indent+3); @@ -637,23 +637,23 @@ const char * slang_type_qual_string(slang_type_qualifier q) { switch (q) { - case slang_qual_none: + case SLANG_QUAL_NONE: return "none"; - case slang_qual_const: + case SLANG_QUAL_CONST: return "const"; - case slang_qual_attribute: + case SLANG_QUAL_ATTRIBUTE: return "attribute"; - case slang_qual_varying: + case SLANG_QUAL_VARYING: return "varying"; - case slang_qual_uniform: + case SLANG_QUAL_UNIFORM: return "uniform"; - case slang_qual_out: + case SLANG_QUAL_OUT: return "out"; - case slang_qual_inout: + case SLANG_QUAL_INOUT: return "inout"; - case slang_qual_fixedoutput: + case SLANG_QUAL_FIXEDOUTPUT: return "fixedoutput"; - case slang_qual_fixedinput: + case SLANG_QUAL_FIXEDINPUT: return "fixedinputk"; default: return "qual?"; @@ -665,53 +665,53 @@ static const char * slang_type_string(slang_type_specifier_type t) { switch (t) { - case slang_spec_void: + case SLANG_SPEC_VOID: return "void"; - case slang_spec_bool: + case SLANG_SPEC_BOOL: return "bool"; - case slang_spec_bvec2: + case SLANG_SPEC_BVEC2: return "bvec2"; - case slang_spec_bvec3: + case SLANG_SPEC_BVEC3: return "bvec3"; - case slang_spec_bvec4: + case SLANG_SPEC_BVEC4: return "bvec4"; - case slang_spec_int: + case SLANG_SPEC_INT: return "int"; - case slang_spec_ivec2: + case SLANG_SPEC_IVEC2: return "ivec2"; - case slang_spec_ivec3: + case SLANG_SPEC_IVEC3: return "ivec3"; - case slang_spec_ivec4: + case SLANG_SPEC_IVEC4: return "ivec4"; - case slang_spec_float: + case SLANG_SPEC_FLOAT: return "float"; - case slang_spec_vec2: + case SLANG_SPEC_VEC2: return "vec2"; - case slang_spec_vec3: + case SLANG_SPEC_VEC3: return "vec3"; - case slang_spec_vec4: + case SLANG_SPEC_VEC4: return "vec4"; - case slang_spec_mat2: + case SLANG_SPEC_MAT2: return "mat2"; - case slang_spec_mat3: + case SLANG_SPEC_MAT3: return "mat3"; - case slang_spec_mat4: + case SLANG_SPEC_MAT4: return "mat4"; - case slang_spec_sampler1D: + case SLANG_SPEC_SAMPLER1D: return "sampler1D"; - case slang_spec_sampler2D: + case SLANG_SPEC_SAMPLER2D: return "sampler2D"; - case slang_spec_sampler3D: + case SLANG_SPEC_SAMPLER3D: return "sampler3D"; - case slang_spec_samplerCube: + case SLANG_SPEC_SAMPLERCUBE: return "samplerCube"; - case slang_spec_sampler1DShadow: + case SLANG_SPEC_SAMPLER1DSHADOW: return "sampler1DShadow"; - case slang_spec_sampler2DShadow: + case SLANG_SPEC_SAMPLER2DSHADOW: return "sampler2DShadow"; - case slang_spec_struct: + case SLANG_SPEC_STRUCT: return "struct"; - case slang_spec_array: + case SLANG_SPEC_ARRAY: return "array"; default: return "type?"; diff --git a/src/mesa/shader/slang/slang_simplify.c b/src/mesa/shader/slang/slang_simplify.c index 0e433281e8b..07b4ae27600 100644 --- a/src/mesa/shader/slang/slang_simplify.c +++ b/src/mesa/shader/slang/slang_simplify.c @@ -97,7 +97,7 @@ _slang_simplify(slang_operation *oper, GLboolean isBool[4]; GLuint i, n; - if (oper->type == slang_oper_identifier) { + if (oper->type == SLANG_OPER_IDENTIFIER) { /* see if it's a named constant */ GLint value = _slang_lookup_constant((char *) oper->a_id); if (value >= 0) { @@ -105,7 +105,7 @@ _slang_simplify(slang_operation *oper, oper->literal[1] = oper->literal[2] = oper->literal[3] = value; - oper->type = slang_oper_literal_int; + oper->type = SLANG_OPER_LITERAL_INT; return; } } @@ -118,49 +118,49 @@ _slang_simplify(slang_operation *oper, /* examine children */ n = MIN2(oper->num_children, 4); for (i = 0; i < n; i++) { - isFloat[i] = (oper->children[i].type == slang_oper_literal_float || - oper->children[i].type == slang_oper_literal_int); - isBool[i] = (oper->children[i].type == slang_oper_literal_bool); + isFloat[i] = (oper->children[i].type == SLANG_OPER_LITERAL_FLOAT || + oper->children[i].type == SLANG_OPER_LITERAL_INT); + isBool[i] = (oper->children[i].type == SLANG_OPER_LITERAL_BOOL); } if (oper->num_children == 2 && isFloat[0] && isFloat[1]) { /* probably simple arithmetic */ switch (oper->type) { - case slang_oper_add: + case SLANG_OPER_ADD: for (i = 0; i < 4; i++) { oper->literal[i] = oper->children[0].literal[i] + oper->children[1].literal[i]; } oper->literal_size = oper->children[0].literal_size; slang_operation_destruct(oper); - oper->type = slang_oper_literal_float; + oper->type = SLANG_OPER_LITERAL_FLOAT; return; - case slang_oper_subtract: + case SLANG_OPER_SUBTRACT: for (i = 0; i < 4; i++) { oper->literal[i] = oper->children[0].literal[i] - oper->children[1].literal[i]; } oper->literal_size = oper->children[0].literal_size; slang_operation_destruct(oper); - oper->type = slang_oper_literal_float; + oper->type = SLANG_OPER_LITERAL_FLOAT; return; - case slang_oper_multiply: + case SLANG_OPER_MULTIPLY: for (i = 0; i < 4; i++) { oper->literal[i] = oper->children[0].literal[i] * oper->children[1].literal[i]; } oper->literal_size = oper->children[0].literal_size; slang_operation_destruct(oper); - oper->type = slang_oper_literal_float; + oper->type = SLANG_OPER_LITERAL_FLOAT; return; - case slang_oper_divide: + case SLANG_OPER_DIVIDE: for (i = 0; i < 4; i++) { oper->literal[i] = oper->children[0].literal[i] / oper->children[1].literal[i]; } oper->literal_size = oper->children[0].literal_size; slang_operation_destruct(oper); - oper->type = slang_oper_literal_float; + oper->type = SLANG_OPER_LITERAL_FLOAT; return; default: ; /* nothing */ @@ -169,19 +169,19 @@ _slang_simplify(slang_operation *oper, if (oper->num_children == 1 && isFloat[0]) { switch (oper->type) { - case slang_oper_minus: + case SLANG_OPER_MINUS: for (i = 0; i < 4; i++) { oper->literal[i] = -oper->children[0].literal[i]; } oper->literal_size = oper->children[0].literal_size; slang_operation_destruct(oper); - oper->type = slang_oper_literal_float; + oper->type = SLANG_OPER_LITERAL_FLOAT; return; - case slang_oper_plus: + case SLANG_OPER_PLUS: COPY_4V(oper->literal, oper->children[0].literal); oper->literal_size = oper->children[0].literal_size; slang_operation_destruct(oper); - oper->type = slang_oper_literal_float; + oper->type = SLANG_OPER_LITERAL_FLOAT; return; default: ; /* nothing */ @@ -191,7 +191,7 @@ _slang_simplify(slang_operation *oper, if (oper->num_children == 2 && isBool[0] && isBool[1]) { /* simple boolean expression */ switch (oper->type) { - case slang_oper_logicaland: + case SLANG_OPER_LOGICALAND: for (i = 0; i < 4; i++) { const GLint a = oper->children[0].literal[i] ? 1 : 0; const GLint b = oper->children[1].literal[i] ? 1 : 0; @@ -199,9 +199,9 @@ _slang_simplify(slang_operation *oper, } oper->literal_size = oper->children[0].literal_size; slang_operation_destruct(oper); - oper->type = slang_oper_literal_bool; + oper->type = SLANG_OPER_LITERAL_BOOL; return; - case slang_oper_logicalor: + case SLANG_OPER_LOGICALOR: for (i = 0; i < 4; i++) { const GLint a = oper->children[0].literal[i] ? 1 : 0; const GLint b = oper->children[1].literal[i] ? 1 : 0; @@ -209,9 +209,9 @@ _slang_simplify(slang_operation *oper, } oper->literal_size = oper->children[0].literal_size; slang_operation_destruct(oper); - oper->type = slang_oper_literal_bool; + oper->type = SLANG_OPER_LITERAL_BOOL; return; - case slang_oper_logicalxor: + case SLANG_OPER_LOGICALXOR: for (i = 0; i < 4; i++) { const GLint a = oper->children[0].literal[i] ? 1 : 0; const GLint b = oper->children[1].literal[i] ? 1 : 0; @@ -219,7 +219,7 @@ _slang_simplify(slang_operation *oper, } oper->literal_size = oper->children[0].literal_size; slang_operation_destruct(oper); - oper->type = slang_oper_literal_bool; + oper->type = SLANG_OPER_LITERAL_BOOL; return; default: ; /* nothing */ @@ -229,7 +229,7 @@ _slang_simplify(slang_operation *oper, if (oper->num_children == 4 && isFloat[0] && isFloat[1] && isFloat[2] && isFloat[3]) { /* vec4(flt, flt, flt, flt) constructor */ - if (oper->type == slang_oper_call) { + if (oper->type == SLANG_OPER_CALL) { if (strcmp((char *) oper->a_id, "vec4") == 0) { oper->literal[0] = oper->children[0].literal[0]; oper->literal[1] = oper->children[1].literal[0]; @@ -237,7 +237,7 @@ _slang_simplify(slang_operation *oper, oper->literal[3] = oper->children[3].literal[0]; oper->literal_size = 4; slang_operation_destruct(oper); - oper->type = slang_oper_literal_float; + oper->type = SLANG_OPER_LITERAL_FLOAT; return; } } @@ -245,7 +245,7 @@ _slang_simplify(slang_operation *oper, if (oper->num_children == 3 && isFloat[0] && isFloat[1] && isFloat[2]) { /* vec3(flt, flt, flt) constructor */ - if (oper->type == slang_oper_call) { + if (oper->type == SLANG_OPER_CALL) { if (strcmp((char *) oper->a_id, "vec3") == 0) { oper->literal[0] = oper->children[0].literal[0]; oper->literal[1] = oper->children[1].literal[0]; @@ -253,7 +253,7 @@ _slang_simplify(slang_operation *oper, oper->literal[3] = oper->literal[2]; oper->literal_size = 3; slang_operation_destruct(oper); - oper->type = slang_oper_literal_float; + oper->type = SLANG_OPER_LITERAL_FLOAT; return; } } @@ -261,7 +261,7 @@ _slang_simplify(slang_operation *oper, if (oper->num_children == 2 && isFloat[0] && isFloat[1]) { /* vec2(flt, flt) constructor */ - if (oper->type == slang_oper_call) { + if (oper->type == SLANG_OPER_CALL) { if (strcmp((char *) oper->a_id, "vec2") == 0) { printf("SIMPLIFY vec2 constructor scope = %p\n", (void*) oper->locals); @@ -271,7 +271,7 @@ _slang_simplify(slang_operation *oper, oper->literal[3] = oper->literal[1]; oper->literal_size = 2; slang_operation_destruct(oper); /* XXX oper->locals goes NULL! */ - oper->type = slang_oper_literal_float; + oper->type = SLANG_OPER_LITERAL_FLOAT; assert(oper->num_children == 0); return; } @@ -305,7 +305,7 @@ _slang_adapt_call(slang_operation *callOper, const slang_function *fun, if (callOper->num_children != numParams) { /* number of arguments doesn't match number of parameters */ - if (fun->kind == slang_func_constructor) { + if (fun->kind == SLANG_FUNC_CONSTRUCTOR) { /* For constructor calls, we can try to unroll vector/matrix args * into individual floats/ints and try to match the function params. */ @@ -345,13 +345,13 @@ _slang_adapt_call(slang_operation *callOper, const slang_function *fun, /* replace arg[i+j] with subscript/index oper */ for (j = 0; j < argSz; j++) { - callOper->children[i + j].type = slang_oper_subscript; + callOper->children[i + j].type = SLANG_OPER_SUBSCRIPT; callOper->children[i + j].num_children = 2; callOper->children[i + j].children = slang_operation_new(2); slang_operation_copy(&callOper->children[i + j].children[0], &origArg); callOper->children[i + j].children[1].type - = slang_oper_literal_int; + = SLANG_OPER_LITERAL_INT; callOper->children[i + j].children[1].literal[0] = j; } @@ -408,7 +408,7 @@ _slang_adapt_call(slang_operation *callOper, const slang_function *fun, slang_operation_copy(child, &callOper->children[i]); child->locals->outer_scope = callOper->locals; - callOper->children[i].type = slang_oper_call; + callOper->children[i].type = SLANG_OPER_CALL; callOper->children[i].a_id = slang_atom_pool_atom(atoms, constructorName); callOper->children[i].num_children = 1; callOper->children[i].children = child; diff --git a/src/mesa/shader/slang/slang_storage.c b/src/mesa/shader/slang/slang_storage.c index 9f824371c52..74aff01aadb 100644 --- a/src/mesa/shader/slang/slang_storage.c +++ b/src/mesa/shader/slang/slang_storage.c @@ -36,7 +36,7 @@ GLboolean slang_storage_array_construct(slang_storage_array * arr) { - arr->type = slang_stor_aggregate; + arr->type = SLANG_STORE_AGGREGATE; arr->aggregate = NULL; arr->length = 0; return GL_TRUE; @@ -110,7 +110,7 @@ aggregate_matrix(slang_storage_aggregate * agg, slang_storage_type basic_type, slang_storage_array *arr = slang_storage_aggregate_push_new(agg); if (arr == NULL) return GL_FALSE; - arr->type = slang_stor_aggregate; + arr->type = SLANG_STORE_AGGREGATE; arr->length = dimension; arr->aggregate = (slang_storage_aggregate *) @@ -155,54 +155,54 @@ _slang_aggregate_variable(slang_storage_aggregate * agg, slang_atom_pool * atoms) { switch (spec->type) { - case slang_spec_bool: - return aggregate_vector(agg, slang_stor_bool, 1); - case slang_spec_bvec2: - return aggregate_vector(agg, slang_stor_bool, 2); - case slang_spec_bvec3: - return aggregate_vector(agg, slang_stor_bool, 3); - case slang_spec_bvec4: - return aggregate_vector(agg, slang_stor_bool, 4); - case slang_spec_int: - return aggregate_vector(agg, slang_stor_int, 1); - case slang_spec_ivec2: - return aggregate_vector(agg, slang_stor_int, 2); - case slang_spec_ivec3: - return aggregate_vector(agg, slang_stor_int, 3); - case slang_spec_ivec4: - return aggregate_vector(agg, slang_stor_int, 4); - case slang_spec_float: - return aggregate_vector(agg, slang_stor_float, 1); - case slang_spec_vec2: - return aggregate_vector(agg, slang_stor_float, 2); - case slang_spec_vec3: - return aggregate_vector(agg, slang_stor_float, 3); - case slang_spec_vec4: - return aggregate_vector(agg, slang_stor_float, 4); - case slang_spec_mat2: - return aggregate_matrix(agg, slang_stor_float, 2); - case slang_spec_mat3: - return aggregate_matrix(agg, slang_stor_float, 3); - case slang_spec_mat4: - return aggregate_matrix(agg, slang_stor_float, 4); - case slang_spec_sampler1D: - case slang_spec_sampler2D: - case slang_spec_sampler3D: - case slang_spec_samplerCube: - case slang_spec_sampler1DShadow: - case slang_spec_sampler2DShadow: - return aggregate_vector(agg, slang_stor_int, 1); - case slang_spec_struct: + case SLANG_SPEC_BOOL: + return aggregate_vector(agg, SLANG_STORE_BOOL, 1); + case SLANG_SPEC_BVEC2: + return aggregate_vector(agg, SLANG_STORE_BOOL, 2); + case SLANG_SPEC_BVEC3: + return aggregate_vector(agg, SLANG_STORE_BOOL, 3); + case SLANG_SPEC_BVEC4: + return aggregate_vector(agg, SLANG_STORE_BOOL, 4); + case SLANG_SPEC_INT: + return aggregate_vector(agg, SLANG_STORE_INT, 1); + case SLANG_SPEC_IVEC2: + return aggregate_vector(agg, SLANG_STORE_INT, 2); + case SLANG_SPEC_IVEC3: + return aggregate_vector(agg, SLANG_STORE_INT, 3); + case SLANG_SPEC_IVEC4: + return aggregate_vector(agg, SLANG_STORE_INT, 4); + case SLANG_SPEC_FLOAT: + return aggregate_vector(agg, SLANG_STORE_FLOAT, 1); + case SLANG_SPEC_VEC2: + return aggregate_vector(agg, SLANG_STORE_FLOAT, 2); + case SLANG_SPEC_VEC3: + return aggregate_vector(agg, SLANG_STORE_FLOAT, 3); + case SLANG_SPEC_VEC4: + return aggregate_vector(agg, SLANG_STORE_FLOAT, 4); + case SLANG_SPEC_MAT2: + return aggregate_matrix(agg, SLANG_STORE_FLOAT, 2); + case SLANG_SPEC_MAT3: + return aggregate_matrix(agg, SLANG_STORE_FLOAT, 3); + case SLANG_SPEC_MAT4: + return aggregate_matrix(agg, SLANG_STORE_FLOAT, 4); + case SLANG_SPEC_SAMPLER1D: + case SLANG_SPEC_SAMPLER2D: + case SLANG_SPEC_SAMPLER3D: + case SLANG_SPEC_SAMPLERCUBE: + case SLANG_SPEC_SAMPLER1DSHADOW: + case SLANG_SPEC_SAMPLER2DSHADOW: + return aggregate_vector(agg, SLANG_STORE_INT, 1); + case SLANG_SPEC_STRUCT: return aggregate_variables(agg, spec->_struct->fields, funcs, structs, vars, atoms); - case slang_spec_array: + case SLANG_SPEC_ARRAY: { slang_storage_array *arr; arr = slang_storage_aggregate_push_new(agg); if (arr == NULL) return GL_FALSE; - arr->type = slang_stor_aggregate; + arr->type = SLANG_STORE_AGGREGATE; arr->aggregate = (slang_storage_aggregate *) slang_alloc_malloc(sizeof(slang_storage_aggregate)); @@ -229,9 +229,9 @@ _slang_aggregate_variable(slang_storage_aggregate * agg, GLuint _slang_sizeof_type(slang_storage_type type) { - if (type == slang_stor_aggregate) + if (type == SLANG_STORE_AGGREGATE) return 0; - if (type == slang_stor_vec4) + if (type == SLANG_STORE_VEC4) return 4 * sizeof(GLfloat); return sizeof(GLfloat); } @@ -246,7 +246,7 @@ _slang_sizeof_aggregate(const slang_storage_aggregate * agg) slang_storage_array *arr = &agg->arrays[i]; GLuint element_size; - if (arr->type == slang_stor_aggregate) + if (arr->type == SLANG_STORE_AGGREGATE) element_size = _slang_sizeof_aggregate(arr->aggregate); else element_size = _slang_sizeof_type(arr->type); @@ -266,7 +266,7 @@ _slang_flatten_aggregate(slang_storage_aggregate * flat, GLuint j; for (j = 0; j < agg->arrays[i].length; j++) { - if (agg->arrays[i].type == slang_stor_aggregate) { + if (agg->arrays[i].type == SLANG_STORE_AGGREGATE) { if (!_slang_flatten_aggregate(flat, agg->arrays[i].aggregate)) return GL_FALSE; } @@ -274,9 +274,9 @@ _slang_flatten_aggregate(slang_storage_aggregate * flat, GLuint k, count; slang_storage_type type; - if (agg->arrays[i].type == slang_stor_vec4) { + if (agg->arrays[i].type == SLANG_STORE_VEC4) { count = 4; - type = slang_stor_float; + type = SLANG_STORE_FLOAT; } else { count = 1; diff --git a/src/mesa/shader/slang/slang_storage.h b/src/mesa/shader/slang/slang_storage.h index 5d756b52161..b02931fcc2a 100644 --- a/src/mesa/shader/slang/slang_storage.h +++ b/src/mesa/shader/slang/slang_storage.h @@ -22,7 +22,7 @@ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -#if !defined SLANG_STORAGE_H +#ifndef SLANG_STORAGE_H #define SLANG_STORAGE_H #include "slang_compile.h" @@ -47,12 +47,12 @@ typedef enum slang_storage_type_ { /* core */ - slang_stor_aggregate, - slang_stor_bool, - slang_stor_int, - slang_stor_float, + SLANG_STORE_AGGREGATE, + SLANG_STORE_BOOL, + SLANG_STORE_INT, + SLANG_STORE_FLOAT, /* vec4 */ - slang_stor_vec4 + SLANG_STORE_VEC4 } slang_storage_type; @@ -110,7 +110,7 @@ _slang_aggregate_variable(slang_storage_aggregate *agg, /* * Returns the size (in machine units) of the given storage type. - * It is an error to pass-in slang_stor_aggregate. + * It is an error to pass-in SLANG_STORE_AGGREGATE. * Returns 0 on error. */ extern GLuint @@ -135,5 +135,4 @@ _slang_flatten_aggregate (slang_storage_aggregate *, const slang_storage_aggregate *); -#endif - +#endif /* SLANG_STORAGE_H */ diff --git a/src/mesa/shader/slang/slang_typeinfo.c b/src/mesa/shader/slang/slang_typeinfo.c index eef2cb96db4..bbcc1c740c1 100644 --- a/src/mesa/shader/slang/slang_typeinfo.c +++ b/src/mesa/shader/slang/slang_typeinfo.c @@ -170,7 +170,7 @@ _slang_multiply_swizzles(slang_swizzle * dst, const slang_swizzle * left, GLvoid slang_type_specifier_ctr(slang_type_specifier * self) { - self->type = slang_spec_void; + self->type = SLANG_SPEC_VOID; self->_struct = NULL; self->_array = NULL; } @@ -196,7 +196,7 @@ slang_type_specifier_copy(slang_type_specifier * x, slang_type_specifier_ctr(&z); z.type = y->type; - if (z.type == slang_spec_struct) { + if (z.type == SLANG_SPEC_STRUCT) { z._struct = (slang_struct *) slang_alloc_malloc(sizeof(slang_struct)); if (z._struct == NULL) { slang_type_specifier_dtr(&z); @@ -212,7 +212,7 @@ slang_type_specifier_copy(slang_type_specifier * x, return GL_FALSE; } } - else if (z.type == slang_spec_array) { + else if (z.type == SLANG_SPEC_ARRAY) { z._array = (slang_type_specifier *) slang_alloc_malloc(sizeof(slang_type_specifier)); @@ -231,17 +231,44 @@ slang_type_specifier_copy(slang_type_specifier * x, return GL_TRUE; } + +/** + * Test if two types are equal. + */ GLboolean slang_type_specifier_equal(const slang_type_specifier * x, const slang_type_specifier * y) { if (x->type != y->type) - return 0; - if (x->type == slang_spec_struct) + return GL_FALSE; + if (x->type == SLANG_SPEC_STRUCT) return slang_struct_equal(x->_struct, y->_struct); - if (x->type == slang_spec_array) + if (x->type == SLANG_SPEC_ARRAY) return slang_type_specifier_equal(x->_array, y->_array); - return 1; + return GL_TRUE; +} + + +/** + * As above, but allow float/int casting. + */ +static GLboolean +slang_type_specifier_compatible(const slang_type_specifier * x, + const slang_type_specifier * y) +{ + /* special case: float == int */ + if (x->type == SLANG_SPEC_INT && y->type == SLANG_SPEC_FLOAT) { + return GL_TRUE; + } + /* XXX may need to add bool/int compatibility, etc */ + + if (x->type != y->type) + return GL_FALSE; + if (x->type == SLANG_SPEC_STRUCT) + return slang_struct_equal(x->_struct, y->_struct); + if (x->type == SLANG_SPEC_ARRAY) + return slang_type_specifier_compatible(x->_array, y->_array); + return GL_TRUE; } @@ -314,93 +341,93 @@ _slang_typeof_operation_(const slang_operation * op, ti->is_swizzled = GL_FALSE; switch (op->type) { - case slang_oper_block_no_new_scope: - case slang_oper_block_new_scope: - case slang_oper_variable_decl: - case slang_oper_asm: - case slang_oper_break: - case slang_oper_continue: - case slang_oper_discard: - case slang_oper_return: - case slang_oper_if: - case slang_oper_while: - case slang_oper_do: - case slang_oper_for: - case slang_oper_void: - ti->spec.type = slang_spec_void; + case SLANG_OPER_BLOCK_NO_NEW_SCOPE: + case SLANG_OPER_BLOCK_NEW_SCOPE: + case SLANG_OPER_VARIABLE_DECL: + case SLANG_OPER_ASM: + case SLANG_OPER_BREAK: + case SLANG_OPER_CONTINUE: + case SLANG_OPER_DISCARD: + case SLANG_OPER_RETURN: + case SLANG_OPER_IF: + case SLANG_OPER_WHILE: + case SLANG_OPER_DO: + case SLANG_OPER_FOR: + case SLANG_OPER_VOID: + ti->spec.type = SLANG_SPEC_VOID; break; - case slang_oper_expression: - case slang_oper_assign: - case slang_oper_addassign: - case slang_oper_subassign: - case slang_oper_mulassign: - case slang_oper_divassign: - case slang_oper_preincrement: - case slang_oper_predecrement: + case SLANG_OPER_EXPRESSION: + case SLANG_OPER_ASSIGN: + case SLANG_OPER_ADDASSIGN: + case SLANG_OPER_SUBASSIGN: + case SLANG_OPER_MULASSIGN: + case SLANG_OPER_DIVASSIGN: + case SLANG_OPER_PREINCREMENT: + case SLANG_OPER_PREDECREMENT: if (!_slang_typeof_operation_(op->children, space, ti, atoms)) return GL_FALSE; break; - case slang_oper_literal_bool: + case SLANG_OPER_LITERAL_BOOL: if (op->literal_size == 1) - ti->spec.type = slang_spec_bool; + ti->spec.type = SLANG_SPEC_BOOL; else if (op->literal_size == 2) - ti->spec.type = slang_spec_bvec2; + ti->spec.type = SLANG_SPEC_BVEC2; else if (op->literal_size == 3) - ti->spec.type = slang_spec_bvec3; + ti->spec.type = SLANG_SPEC_BVEC3; else if (op->literal_size == 4) - ti->spec.type = slang_spec_bvec4; + ti->spec.type = SLANG_SPEC_BVEC4; else { _mesa_problem(NULL, "Unexpected bool literal_size %d in _slang_typeof_operation()", op->literal_size); - ti->spec.type = slang_spec_bool; + ti->spec.type = SLANG_SPEC_BOOL; } break; - case slang_oper_logicalor: - case slang_oper_logicalxor: - case slang_oper_logicaland: - case slang_oper_equal: - case slang_oper_notequal: - case slang_oper_less: - case slang_oper_greater: - case slang_oper_lessequal: - case slang_oper_greaterequal: - case slang_oper_not: - ti->spec.type = slang_spec_bool; + case SLANG_OPER_LOGICALOR: + case SLANG_OPER_LOGICALXOR: + case SLANG_OPER_LOGICALAND: + case SLANG_OPER_EQUAL: + case SLANG_OPER_NOTEQUAL: + case SLANG_OPER_LESS: + case SLANG_OPER_GREATER: + case SLANG_OPER_LESSequal: + case SLANG_OPER_GREATERequal: + case SLANG_OPER_NOT: + ti->spec.type = SLANG_SPEC_BOOL; break; - case slang_oper_literal_int: + case SLANG_OPER_LITERAL_INT: if (op->literal_size == 1) - ti->spec.type = slang_spec_int; + ti->spec.type = SLANG_SPEC_INT; else if (op->literal_size == 2) - ti->spec.type = slang_spec_ivec2; + ti->spec.type = SLANG_SPEC_IVEC2; else if (op->literal_size == 3) - ti->spec.type = slang_spec_ivec3; + ti->spec.type = SLANG_SPEC_IVEC3; else if (op->literal_size == 4) - ti->spec.type = slang_spec_ivec4; + ti->spec.type = SLANG_SPEC_IVEC4; else { _mesa_problem(NULL, "Unexpected int literal_size %d in _slang_typeof_operation()", op->literal_size); - ti->spec.type = slang_spec_int; + ti->spec.type = SLANG_SPEC_INT; } break; - case slang_oper_literal_float: + case SLANG_OPER_LITERAL_FLOAT: if (op->literal_size == 1) - ti->spec.type = slang_spec_float; + ti->spec.type = SLANG_SPEC_FLOAT; else if (op->literal_size == 2) - ti->spec.type = slang_spec_vec2; + ti->spec.type = SLANG_SPEC_VEC2; else if (op->literal_size == 3) - ti->spec.type = slang_spec_vec3; + ti->spec.type = SLANG_SPEC_VEC3; else if (op->literal_size == 4) - ti->spec.type = slang_spec_vec4; + ti->spec.type = SLANG_SPEC_VEC4; else { _mesa_problem(NULL, "Unexpected float literal_size %d in _slang_typeof_operation()", op->literal_size); - ti->spec.type = slang_spec_float; + ti->spec.type = SLANG_SPEC_FLOAT; } break; - case slang_oper_identifier: + case SLANG_OPER_IDENTIFIER: { slang_variable *var; var = _slang_locate_variable(op->locals, op->a_id, GL_TRUE); @@ -412,65 +439,65 @@ _slang_typeof_operation_(const slang_operation * op, ti->array_len = var->array_len; } break; - case slang_oper_sequence: + case SLANG_OPER_SEQUENCE: /* TODO: check [0] and [1] if they match */ if (!_slang_typeof_operation_(&op->children[1], space, ti, atoms)) RETURN_NIL(); ti->can_be_referenced = GL_FALSE; ti->is_swizzled = GL_FALSE; break; - /*case slang_oper_modassign: */ - /*case slang_oper_lshassign: */ - /*case slang_oper_rshassign: */ - /*case slang_oper_orassign: */ - /*case slang_oper_xorassign: */ - /*case slang_oper_andassign: */ - case slang_oper_select: + /*case SLANG_OPER_MODASSIGN: */ + /*case SLANG_OPER_LSHASSIGN: */ + /*case SLANG_OPER_RSHASSIGN: */ + /*case SLANG_OPER_ORASSIGN: */ + /*case SLANG_OPER_XORASSIGN: */ + /*case SLANG_OPER_ANDASSIGN: */ + case SLANG_OPER_SELECT: /* TODO: check [1] and [2] if they match */ if (!_slang_typeof_operation_(&op->children[1], space, ti, atoms)) RETURN_NIL(); ti->can_be_referenced = GL_FALSE; ti->is_swizzled = GL_FALSE; break; - /*case slang_oper_bitor: */ - /*case slang_oper_bitxor: */ - /*case slang_oper_bitand: */ - /*case slang_oper_lshift: */ - /*case slang_oper_rshift: */ - case slang_oper_add: + /*case SLANG_OPER_BITOR: */ + /*case SLANG_OPER_BITXOR: */ + /*case SLANG_OPER_BITAND: */ + /*case SLANG_OPER_LSHIFT: */ + /*case SLANG_OPER_RSHIFT: */ + case SLANG_OPER_ADD: if (!typeof_existing_function("+", op->children, 2, space, &ti->spec, atoms)) RETURN_NIL(); break; - case slang_oper_subtract: + case SLANG_OPER_SUBTRACT: if (!typeof_existing_function("-", op->children, 2, space, &ti->spec, atoms)) RETURN_NIL(); break; - case slang_oper_multiply: + case SLANG_OPER_MULTIPLY: if (!typeof_existing_function("*", op->children, 2, space, &ti->spec, atoms)) RETURN_NIL(); break; - case slang_oper_divide: + case SLANG_OPER_DIVIDE: if (!typeof_existing_function("/", op->children, 2, space, &ti->spec, atoms)) RETURN_NIL(); break; - /*case slang_oper_modulus: */ - case slang_oper_plus: + /*case SLANG_OPER_MODULUS: */ + case SLANG_OPER_PLUS: if (!_slang_typeof_operation_(op->children, space, ti, atoms)) RETURN_NIL(); ti->can_be_referenced = GL_FALSE; ti->is_swizzled = GL_FALSE; break; - case slang_oper_minus: + case SLANG_OPER_MINUS: if (!typeof_existing_function("-", op->children, 1, space, &ti->spec, atoms)) RETURN_NIL(); break; - /*case slang_oper_complement: */ - case slang_oper_subscript: + /*case SLANG_OPER_COMPLEMENT: */ + case SLANG_OPER_SUBSCRIPT: { slang_typeinfo _ti; @@ -481,7 +508,7 @@ _slang_typeof_operation_(const slang_operation * op, RETURN_NIL(); } ti->can_be_referenced = _ti.can_be_referenced; - if (_ti.spec.type == slang_spec_array) { + if (_ti.spec.type == SLANG_SPEC_ARRAY) { if (!slang_type_specifier_copy(&ti->spec, _ti.spec._array)) { slang_typeinfo_destruct(&_ti); RETURN_NIL(); @@ -498,7 +525,7 @@ _slang_typeof_operation_(const slang_operation * op, slang_typeinfo_destruct(&_ti); } break; - case slang_oper_call: + case SLANG_OPER_CALL: { GLboolean exists; @@ -509,7 +536,7 @@ _slang_typeof_operation_(const slang_operation * op, slang_struct *s = slang_struct_scope_find(space->structs, op->a_id, GL_TRUE); if (s != NULL) { - ti->spec.type = slang_spec_struct; + ti->spec.type = SLANG_SPEC_STRUCT; ti->spec._struct = (slang_struct *) slang_alloc_malloc(sizeof(slang_struct)); if (ti->spec._struct == NULL) @@ -528,14 +555,14 @@ _slang_typeof_operation_(const slang_operation * op, name = slang_atom_pool_id(atoms, op->a_id); type = slang_type_specifier_type_from_string(name); - if (type == slang_spec_void) + if (type == SLANG_SPEC_VOID) RETURN_ERROR2("function not found", name, 0); ti->spec.type = type; } } } break; - case slang_oper_field: + case SLANG_OPER_FIELD: { slang_typeinfo _ti; @@ -545,7 +572,7 @@ _slang_typeof_operation_(const slang_operation * op, slang_typeinfo_destruct(&_ti); RETURN_NIL(); } - if (_ti.spec.type == slang_spec_struct) { + if (_ti.spec.type == SLANG_SPEC_STRUCT) { slang_variable *field; field = _slang_locate_variable(_ti.spec._struct->fields, op->a_id, @@ -595,14 +622,14 @@ _slang_typeof_operation_(const slang_operation * op, break; case 2: switch (base) { - case slang_spec_float: - ti->spec.type = slang_spec_vec2; + case SLANG_SPEC_FLOAT: + ti->spec.type = SLANG_SPEC_VEC2; break; - case slang_spec_int: - ti->spec.type = slang_spec_ivec2; + case SLANG_SPEC_INT: + ti->spec.type = SLANG_SPEC_IVEC2; break; - case slang_spec_bool: - ti->spec.type = slang_spec_bvec2; + case SLANG_SPEC_BOOL: + ti->spec.type = SLANG_SPEC_BVEC2; break; default: break; @@ -610,14 +637,14 @@ _slang_typeof_operation_(const slang_operation * op, break; case 3: switch (base) { - case slang_spec_float: - ti->spec.type = slang_spec_vec3; + case SLANG_SPEC_FLOAT: + ti->spec.type = SLANG_SPEC_VEC3; break; - case slang_spec_int: - ti->spec.type = slang_spec_ivec3; + case SLANG_SPEC_INT: + ti->spec.type = SLANG_SPEC_IVEC3; break; - case slang_spec_bool: - ti->spec.type = slang_spec_bvec3; + case SLANG_SPEC_BOOL: + ti->spec.type = SLANG_SPEC_BVEC3; break; default: break; @@ -625,14 +652,14 @@ _slang_typeof_operation_(const slang_operation * op, break; case 4: switch (base) { - case slang_spec_float: - ti->spec.type = slang_spec_vec4; + case SLANG_SPEC_FLOAT: + ti->spec.type = SLANG_SPEC_VEC4; break; - case slang_spec_int: - ti->spec.type = slang_spec_ivec4; + case SLANG_SPEC_INT: + ti->spec.type = SLANG_SPEC_IVEC4; break; - case slang_spec_bool: - ti->spec.type = slang_spec_bvec4; + case SLANG_SPEC_BOOL: + ti->spec.type = SLANG_SPEC_BVEC4; break; default: break; @@ -645,8 +672,8 @@ _slang_typeof_operation_(const slang_operation * op, slang_typeinfo_destruct(&_ti); } break; - case slang_oper_postincrement: - case slang_oper_postdecrement: + case SLANG_OPER_POSTINCREMENT: + case SLANG_OPER_POSTDECREMENT: if (!_slang_typeof_operation_(op->children, space, ti, atoms)) RETURN_NIL(); ti->can_be_referenced = GL_FALSE; @@ -660,12 +687,13 @@ _slang_typeof_operation_(const slang_operation * op, } - +/** + * Lookup a function according to name and parameter count/types. + */ slang_function * _slang_locate_function(const slang_function_scope * funcs, slang_atom a_name, const slang_operation * args, GLuint num_args, - const slang_name_space * space, - slang_atom_pool * atoms) + const slang_name_space * space, slang_atom_pool * atoms) { GLuint i; @@ -689,17 +717,19 @@ _slang_locate_function(const slang_function_scope * funcs, slang_atom a_name, slang_typeinfo_destruct(&ti); return NULL; } - if (!slang_type_specifier_equal(&ti.spec, - &f->parameters->variables[j/* + haveRetValue*/]->type.specifier)) { + if (!slang_type_specifier_compatible(&ti.spec, + &f->parameters->variables[j]->type.specifier)) { slang_typeinfo_destruct(&ti); break; } slang_typeinfo_destruct(&ti); - /* "out" and "inout" formal parameter requires the actual parameter to be l-value */ + /* "out" and "inout" formal parameter requires the actual + * parameter to be l-value. + */ if (!ti.can_be_referenced && - (f->parameters->variables[j/* + haveRetValue*/]->type.qualifier == slang_qual_out || - f->parameters->variables[j/* + haveRetValue*/]->type.qualifier == slang_qual_inout)) + (f->parameters->variables[j]->type.qualifier == SLANG_QUAL_OUT || + f->parameters->variables[j]->type.qualifier == SLANG_QUAL_INOUT)) break; } if (j == num_args) @@ -747,9 +777,9 @@ GLboolean _slang_type_is_matrix(slang_type_specifier_type ty) { switch (ty) { - case slang_spec_mat2: - case slang_spec_mat3: - case slang_spec_mat4: + case SLANG_SPEC_MAT2: + case SLANG_SPEC_MAT3: + case SLANG_SPEC_MAT4: return GL_TRUE; default: return GL_FALSE; @@ -765,15 +795,15 @@ GLboolean _slang_type_is_vector(slang_type_specifier_type ty) { switch (ty) { - case slang_spec_vec2: - case slang_spec_vec3: - case slang_spec_vec4: - case slang_spec_ivec2: - case slang_spec_ivec3: - case slang_spec_ivec4: - case slang_spec_bvec2: - case slang_spec_bvec3: - case slang_spec_bvec4: + case SLANG_SPEC_VEC2: + case SLANG_SPEC_VEC3: + case SLANG_SPEC_VEC4: + case SLANG_SPEC_IVEC2: + case SLANG_SPEC_IVEC3: + case SLANG_SPEC_IVEC4: + case SLANG_SPEC_BVEC2: + case SLANG_SPEC_BVEC3: + case SLANG_SPEC_BVEC4: return GL_TRUE; default: return GL_FALSE; @@ -788,29 +818,29 @@ slang_type_specifier_type _slang_type_base(slang_type_specifier_type ty) { switch (ty) { - case slang_spec_float: - case slang_spec_vec2: - case slang_spec_vec3: - case slang_spec_vec4: - return slang_spec_float; - case slang_spec_int: - case slang_spec_ivec2: - case slang_spec_ivec3: - case slang_spec_ivec4: - return slang_spec_int; - case slang_spec_bool: - case slang_spec_bvec2: - case slang_spec_bvec3: - case slang_spec_bvec4: - return slang_spec_bool; - case slang_spec_mat2: - return slang_spec_vec2; - case slang_spec_mat3: - return slang_spec_vec3; - case slang_spec_mat4: - return slang_spec_vec4; + case SLANG_SPEC_FLOAT: + case SLANG_SPEC_VEC2: + case SLANG_SPEC_VEC3: + case SLANG_SPEC_VEC4: + return SLANG_SPEC_FLOAT; + case SLANG_SPEC_INT: + case SLANG_SPEC_IVEC2: + case SLANG_SPEC_IVEC3: + case SLANG_SPEC_IVEC4: + return SLANG_SPEC_INT; + case SLANG_SPEC_BOOL: + case SLANG_SPEC_BVEC2: + case SLANG_SPEC_BVEC3: + case SLANG_SPEC_BVEC4: + return SLANG_SPEC_BOOL; + case SLANG_SPEC_MAT2: + return SLANG_SPEC_VEC2; + case SLANG_SPEC_MAT3: + return SLANG_SPEC_VEC3; + case SLANG_SPEC_MAT4: + return SLANG_SPEC_VEC4; default: - return slang_spec_void; + return SLANG_SPEC_VOID; } } @@ -822,24 +852,24 @@ GLuint _slang_type_dim(slang_type_specifier_type ty) { switch (ty) { - case slang_spec_float: - case slang_spec_int: - case slang_spec_bool: + case SLANG_SPEC_FLOAT: + case SLANG_SPEC_INT: + case SLANG_SPEC_BOOL: return 1; - case slang_spec_vec2: - case slang_spec_ivec2: - case slang_spec_bvec2: - case slang_spec_mat2: + case SLANG_SPEC_VEC2: + case SLANG_SPEC_IVEC2: + case SLANG_SPEC_BVEC2: + case SLANG_SPEC_MAT2: return 2; - case slang_spec_vec3: - case slang_spec_ivec3: - case slang_spec_bvec3: - case slang_spec_mat3: + case SLANG_SPEC_VEC3: + case SLANG_SPEC_IVEC3: + case SLANG_SPEC_BVEC3: + case SLANG_SPEC_MAT3: return 3; - case slang_spec_vec4: - case slang_spec_ivec4: - case slang_spec_bvec4: - case slang_spec_mat4: + case SLANG_SPEC_VEC4: + case SLANG_SPEC_IVEC4: + case SLANG_SPEC_BVEC4: + case SLANG_SPEC_MAT4: return 4; default: return 0; diff --git a/src/mesa/shader/slang/slang_typeinfo.h b/src/mesa/shader/slang/slang_typeinfo.h index 6e27079ff89..3115b71e085 100644 --- a/src/mesa/shader/slang/slang_typeinfo.h +++ b/src/mesa/shader/slang/slang_typeinfo.h @@ -61,8 +61,7 @@ typedef struct slang_assemble_ctx_ struct gl_program *program; slang_var_table *vartable; struct slang_function_ *CurFunction; - slang_atom CurLoopBreak; - slang_atom CurLoopCont; + struct slang_ir_node_ *CurLoop; } slang_assemble_ctx; @@ -90,30 +89,30 @@ _slang_multiply_swizzles(slang_swizzle *, const slang_swizzle *, */ typedef enum slang_type_specifier_type_ { - slang_spec_void, - slang_spec_bool, - slang_spec_bvec2, - slang_spec_bvec3, - slang_spec_bvec4, - slang_spec_int, - slang_spec_ivec2, - slang_spec_ivec3, - slang_spec_ivec4, - slang_spec_float, - slang_spec_vec2, - slang_spec_vec3, - slang_spec_vec4, - slang_spec_mat2, - slang_spec_mat3, - slang_spec_mat4, - slang_spec_sampler1D, - slang_spec_sampler2D, - slang_spec_sampler3D, - slang_spec_samplerCube, - slang_spec_sampler1DShadow, - slang_spec_sampler2DShadow, - slang_spec_struct, - slang_spec_array + SLANG_SPEC_VOID, + SLANG_SPEC_BOOL, + SLANG_SPEC_BVEC2, + SLANG_SPEC_BVEC3, + SLANG_SPEC_BVEC4, + SLANG_SPEC_INT, + SLANG_SPEC_IVEC2, + SLANG_SPEC_IVEC3, + SLANG_SPEC_IVEC4, + SLANG_SPEC_FLOAT, + SLANG_SPEC_VEC2, + SLANG_SPEC_VEC3, + SLANG_SPEC_VEC4, + SLANG_SPEC_MAT2, + SLANG_SPEC_MAT3, + SLANG_SPEC_MAT4, + SLANG_SPEC_SAMPLER1D, + SLANG_SPEC_SAMPLER2D, + SLANG_SPEC_SAMPLER3D, + SLANG_SPEC_SAMPLERCUBE, + SLANG_SPEC_SAMPLER1DSHADOW, + SLANG_SPEC_SAMPLER2DSHADOW, + SLANG_SPEC_STRUCT, + SLANG_SPEC_ARRAY } slang_type_specifier_type; diff --git a/src/mesa/sources b/src/mesa/sources index 4d8055b4bf9..b35e56abad8 100644 --- a/src/mesa/sources +++ b/src/mesa/sources @@ -158,6 +158,7 @@ SHADER_SOURCES = \ shader/nvvertexec.c \ shader/nvvertparse.c \ shader/program.c \ + shader/prog_debug.c \ shader/prog_instruction.c \ shader/prog_parameter.c \ shader/prog_print.c \ diff --git a/src/mesa/swrast/s_fragprog.c b/src/mesa/swrast/s_fragprog.c index 12c8aee6ea0..89907f73c60 100644 --- a/src/mesa/swrast/s_fragprog.c +++ b/src/mesa/swrast/s_fragprog.c @@ -418,6 +418,29 @@ test_cc(GLuint condCode, GLuint ccMaskRule) /** + * Evaluate the 4 condition codes against a predicate and return GL_TRUE + * or GL_FALSE to indicate result. + */ +static INLINE GLboolean +eval_condition(const struct fp_machine *machine, + const struct prog_instruction *inst) +{ + const GLuint swizzle = inst->DstReg.CondSwizzle; + const GLuint condMask = inst->DstReg.CondMask; + if (test_cc(machine->CondCodes[GET_SWZ(swizzle, 0)], condMask) || + test_cc(machine->CondCodes[GET_SWZ(swizzle, 1)], condMask) || + test_cc(machine->CondCodes[GET_SWZ(swizzle, 2)], condMask) || + test_cc(machine->CondCodes[GET_SWZ(swizzle, 3)], condMask)) { + return GL_TRUE; + } + else { + return GL_FALSE; + } +} + + + +/** * Store 4 floats into a register. Observe the instructions saturate and * set-condition-code flags. */ @@ -531,6 +554,7 @@ init_machine_deriv( GLcontext *ctx, _mesa_memcpy(dMachine, machine, sizeof(struct fp_machine)); if (program->Base.Target == GL_FRAGMENT_PROGRAM_NV) { + /* XXX also need to do this when using valgrind */ /* Clear temporary registers (undefined for ARB_f_p) */ _mesa_bzero( (void*) machine->Temporaries, MAX_NV_FRAGMENT_PROGRAM_TEMPS * 4 * sizeof(GLfloat)); @@ -642,7 +666,7 @@ execute_program( GLcontext *ctx, } if (DEBUG_FRAG) { - _mesa_print_instruction(inst, 0); + _mesa_print_instruction(inst); } switch (inst->Opcode) { @@ -675,9 +699,10 @@ execute_program( GLcontext *ctx, } } break; - case OPCODE_BGNLOOP: /* begin loop */ + case OPCODE_BGNLOOP: + /* no-op */ break; - case OPCODE_ENDLOOP: /* end loop */ + case OPCODE_ENDLOOP: /* subtract 1 here since pc is incremented by for(pc) loop */ pc = inst->BranchTarget - 1; /* go to matching BNGLOOP */ break; @@ -685,52 +710,25 @@ execute_program( GLcontext *ctx, break; case OPCODE_ENDSUB: /* end subroutine */ break; - case OPCODE_BRA: /* conditional branch */ - { - /* NOTE: The branch is conditional! */ - const GLuint swizzle = inst->DstReg.CondSwizzle; - const GLuint condMask = inst->DstReg.CondMask; - if (test_cc(machine->CondCodes[GET_SWZ(swizzle, 0)], condMask) || - test_cc(machine->CondCodes[GET_SWZ(swizzle, 1)], condMask) || - test_cc(machine->CondCodes[GET_SWZ(swizzle, 2)], condMask) || - test_cc(machine->CondCodes[GET_SWZ(swizzle, 3)], condMask)) { - /* take branch */ - pc = inst->BranchTarget; - /* - printf("Take branch to %u\n", pc); - */ - } - } - break; - case OPCODE_BRK: /* break out of loop */ - { - /* The location of the ENDLOOP instruction is saved in the - * BGNLOOP instruction. Get that instruction and jump to - * its BranchTarget + 1. - */ - const struct prog_instruction *loopBeginInst - = program->Base.Instructions + inst->BranchTarget; - ASSERT(loopBeginInst->Opcode == OPCODE_BGNLOOP); - ASSERT(loopBeginInst->BranchTarget >= 0); - /* we'll add one at bottom of for-loop */ - pc = loopBeginInst->BranchTarget; + case OPCODE_BRA: /* branch (conditional) */ + /* fall-through */ + case OPCODE_BRK: /* break out of loop (conditional) */ + /* fall-through */ + case OPCODE_CONT: /* continue loop (conditional) */ + if (eval_condition(machine, inst)) { + /* take branch */ + /* Subtract 1 here since we'll do pc++ at end of for-loop */ + pc = inst->BranchTarget - 1; } break; - case OPCODE_CAL: /* Call subroutine */ - { - /* NOTE: The call is conditional! */ - const GLuint swizzle = inst->DstReg.CondSwizzle; - const GLuint condMask = inst->DstReg.CondMask; - if (test_cc(machine->CondCodes[GET_SWZ(swizzle, 0)], condMask) || - test_cc(machine->CondCodes[GET_SWZ(swizzle, 1)], condMask) || - test_cc(machine->CondCodes[GET_SWZ(swizzle, 2)], condMask) || - test_cc(machine->CondCodes[GET_SWZ(swizzle, 3)], condMask)) { - if (machine->StackDepth >= MAX_PROGRAM_CALL_DEPTH) { - return GL_TRUE; /* Per GL_NV_vertex_program2 spec */ - } - machine->CallStack[machine->StackDepth++] = pc + 1; - pc = inst->BranchTarget; + case OPCODE_CAL: /* Call subroutine (conditional) */ + if (eval_condition(machine, inst)) { + /* call the subroutine */ + if (machine->StackDepth >= MAX_PROGRAM_CALL_DEPTH) { + return GL_TRUE; /* Per GL_NV_vertex_program2 spec */ } + machine->CallStack[machine->StackDepth++] = pc + 1; + pc = inst->BranchTarget; /* XXX - 1 ??? */ } break; case OPCODE_CMP: @@ -746,8 +744,6 @@ execute_program( GLcontext *ctx, store_vector4( inst, machine, result ); } break; - case OPCODE_CONT: /* continue loop */ - break; case OPCODE_COS: { GLfloat a[4], result[4]; @@ -883,29 +879,20 @@ execute_program( GLcontext *ctx, } break; case OPCODE_IF: - { - const GLuint swizzle = inst->DstReg.CondSwizzle; - const GLuint condMask = inst->DstReg.CondMask; - if (test_cc(machine->CondCodes[GET_SWZ(swizzle, 0)], condMask) || - test_cc(machine->CondCodes[GET_SWZ(swizzle, 1)], condMask) || - test_cc(machine->CondCodes[GET_SWZ(swizzle, 2)], condMask) || - test_cc(machine->CondCodes[GET_SWZ(swizzle, 3)], condMask)) { - /* do if-clause (just continue execution) */ - } - else { - /* go to the instruction after ELSE or ENDIF */ - assert(inst->BranchTarget >= 0); - pc = inst->BranchTarget - 1; - } + if (eval_condition(machine, inst)) { + /* do if-clause (just continue execution) */ } - break; - case OPCODE_ELSE: - { - /* goto ENDIF */ + else { + /* go to the instruction after ELSE or ENDIF */ assert(inst->BranchTarget >= 0); pc = inst->BranchTarget - 1; } break; + case OPCODE_ELSE: + /* goto ENDIF */ + assert(inst->BranchTarget >= 0); + pc = inst->BranchTarget - 1; + break; case OPCODE_ENDIF: /* nothing */ break; @@ -920,16 +907,9 @@ execute_program( GLcontext *ctx, store_vector4( inst, machine, result ); } break; - case OPCODE_KIL_NV: /* NV_f_p only */ - { - const GLuint swizzle = inst->DstReg.CondSwizzle; - const GLuint condMask = inst->DstReg.CondMask; - if (test_cc(machine->CondCodes[GET_SWZ(swizzle, 0)], condMask) || - test_cc(machine->CondCodes[GET_SWZ(swizzle, 1)], condMask) || - test_cc(machine->CondCodes[GET_SWZ(swizzle, 2)], condMask) || - test_cc(machine->CondCodes[GET_SWZ(swizzle, 3)], condMask)) { - return GL_FALSE; - } + case OPCODE_KIL_NV: /* NV_f_p only (conditional) */ + if (eval_condition(machine, inst)) { + return GL_FALSE; } break; case OPCODE_KIL: /* ARB_f_p only */ @@ -1215,20 +1195,12 @@ execute_program( GLcontext *ctx, store_vector4( inst, machine, result ); } break; - case OPCODE_RET: /* return from subroutine */ - { - /* NOTE: The return is conditional! */ - const GLuint swizzle = inst->DstReg.CondSwizzle; - const GLuint condMask = inst->DstReg.CondMask; - if (test_cc(machine->CondCodes[GET_SWZ(swizzle, 0)], condMask) || - test_cc(machine->CondCodes[GET_SWZ(swizzle, 1)], condMask) || - test_cc(machine->CondCodes[GET_SWZ(swizzle, 2)], condMask) || - test_cc(machine->CondCodes[GET_SWZ(swizzle, 3)], condMask)) { - if (machine->StackDepth == 0) { - return GL_TRUE; /* Per GL_NV_vertex_program2 spec */ - } - pc = machine->CallStack[--machine->StackDepth]; + case OPCODE_RET: /* return from subroutine (conditional) */ + if (eval_condition(machine, inst)) { + if (machine->StackDepth == 0) { + return GL_TRUE; /* Per GL_NV_vertex_program2 spec */ } + pc = machine->CallStack[--machine->StackDepth]; } break; case OPCODE_RFL: /* reflection vector */ diff --git a/src/mesa/tnl/t_vp_build.c b/src/mesa/tnl/t_vp_build.c index 6fb14e7caa8..47fed32904d 100644 --- a/src/mesa/tnl/t_vp_build.c +++ b/src/mesa/tnl/t_vp_build.c @@ -497,7 +497,7 @@ static void debug_insn( struct prog_instruction *inst, const char *fn, } _mesa_printf("%d:\t", line); - _mesa_print_instruction(inst, 0); + _mesa_print_instruction(inst); } } |