diff options
311 files changed, 31224 insertions, 49338 deletions
@@ -92,6 +92,7 @@ linux-alpha-static \ linux-debug \ linux-directfb \ linux-dri \ +linux-dri-debug \ linux-dri-x86 \ linux-dri-x86-64 \ linux-dri-ppc \ diff --git a/configs/linux-dri b/configs/linux-dri index 5f945a73f1..1a9146e299 100644 --- a/configs/linux-dri +++ b/configs/linux-dri @@ -67,4 +67,4 @@ WINDOW_SYSTEM=dri # gamma are missing because they have not been converted to use the new # interface. DRI_DIRS = i810 i915tex i915 i965 mach64 mga r128 r200 r300 radeon s3v \ - savage sis tdfx trident unichrome ffb + savage sis tdfx trident unichrome ffb nouveau diff --git a/docs/contents.html b/docs/contents.html index 693145c2e3..21eca4df87 100644 --- a/docs/contents.html +++ b/docs/contents.html @@ -64,6 +64,7 @@ a:visited { <ul> <li><a href="http://sourceforge.net/projects/mesa3d" target="_parent">SourceForge homepage</a> <li><a href="repository.html" target="MainFrame">Source Code Repository</a> +<li><a href="shading.html" target="MainFrame">Shading Language</a> <li><a href="utilities.html" target="MainFrame">Utilities</a> <li><a href="helpwanted.html" target="MainFrame">Help Wanted</a> <li><a href="devinfo.html" target="MainFrame">Development Notes</a> diff --git a/docs/relnotes-6.5.3.html b/docs/relnotes-6.5.3.html index b3d2fe6455..27053c071b 100644 --- a/docs/relnotes-6.5.3.html +++ b/docs/relnotes-6.5.3.html @@ -11,8 +11,7 @@ <H1>Mesa 6.5.3 Release Notes / (in progress)</H1> <p> -Mesa 6.5.3 is a 6.5 follow-on development release mostly consisting of -bug fixes</a>. +Mesa 6.5.3 is a 6.5 follow-on development release with many internal changes. </p> @@ -24,8 +23,14 @@ TBD <h2>New features</h2> <ul> +<li>OpenGL 2.0 support. +<li>Entirely new Shading Language code generator. +<li>Much faster software execution of vertex, fragment shaders. +<li>New vertex buffer object infrastructure (replaces old array_cache code). <li>Updated glext.h file (version 39) <li>Updated glxext.h file (version 18) +<li>GL_MAX_DRAWBUFFERS is now 4 (software rendering) so + "multiple render targets" are really supported. </ul> <h2>Bug fixes</h2> @@ -33,6 +38,7 @@ TBD <li>Fog was errantly applied when a fragment shader was enabled (bug 9346) <li>glPush/PopClientAttrib didn't handle VBO bindings correctly (bug 9445) <li>With 32-bit Z buffer, the fragment Z of lines and points was sometimes wrong. +<li>GL_POST_CONVOLUTION_ALPHA_BIAS/SCALE was broken. <li>1D convolution state could effect 2D image transfers </ul> @@ -40,6 +46,7 @@ TBD <h2>Internal code changes</h2> <ul> +<li>Massive changes to the Shading Language compiler. <li>The _MaintainTnlProgram, _MaintainTexEnvProgram, _TexEnvProgram and _TnlProgram fields have been moved. <li>The ctx->FragmentProgram._Active field has been removed. @@ -53,7 +60,6 @@ fixed-function program. <h2>To Do (someday) items</h2> <ul> <li>Switch to freeglut -<li>Increase MAX_DRAWBUFFERS <li>Fix linux-glide target/driver. <li>Improved lambda and derivative calculation for frag progs. </ul> @@ -65,8 +71,8 @@ fixed-function program. Driver Status ---------------------- ---------------------- DRI drivers varies with the driver -XMesa/GLX (on Xlib) implements OpenGL 1.5 -OSMesa (off-screen) implements OpenGL 1.5 +XMesa/GLX (on Xlib) implements OpenGL 2.0 +OSMesa (off-screen) implements OpenGL 2.0 Glide (3dfx Voodoo1/2) implements OpenGL 1.3 SVGA implements OpenGL 1.3 Wind River UGL implements OpenGL 1.3 diff --git a/docs/shading.html b/docs/shading.html new file mode 100644 index 0000000000..40a6d7ac90 --- /dev/null +++ b/docs/shading.html @@ -0,0 +1,286 @@ +<HTML> + +<TITLE>Shading Language Support</TITLE> + +<link rel="stylesheet" type="text/css" href="mesa.css"></head> + +<BODY> + +<H1>Shading Language Support</H1> + +<p> +This page describes the features and status of Mesa's support for the +<a href="http://opengl.org/documentation/glsl/" target="_parent"> +OpenGL Shading Language</a>. +</p> + +<p> +Last updated on 17 Feb 2007. +</p> + +<p> +Contents +</p> +<ul> +<li><a href="#unsup">Unsupported Features</a> +<li><a href="#notes">Implementation Notes</a> +<li><a href="#hints">Programming Hints</a> +<li><a href="#standalone">Stand-alone Compiler</a> +<li><a href="#implementation">Compiler Implementation</a> +</ul> + + +<a name="unsup"> +<h2>Unsupported Features</h2> + +<p> +The following features of the shading language are not yet supported +in Mesa: +</p> + +<ul> +<li>Dereferencing arrays with non-constant indexes +<li>User-defined structs +<li>Linking of multiple shaders is not supported +<li>Integer operations are not fully implemented (most are implemented + as floating point). +<li>gl_ClipVertex +</ul> + +<p> +All other major features of the shading language should function. +</p> + + +<a name="notes"> +<h2>Implementation Notes</h2> + +<ul> +<li>Shading language programs are compiled into low-level programs + very similar to those of GL_ARB_vertex/fragment_program. +<li>All vector types (vec2, vec3, vec4, bvec2, etc) currently occupy full + float[4] registers. +<li>Float constants and variables are packed so that up to four floats + can occupy one program parameter/register. +<li>All function calls are inlined. +<li>Shaders which use too many registers will not compile. +<li>The quality of generated code is pretty good, register usage is fair. +<li>Shader error detection and reporting of errors (InfoLog) is not + very good yet. +<li>There are known memory leaks in the compiler. +</ul> + +<p> +These issues will be addressed/resolved in the future. +</p> + + +<a name="hints"> +<h2>Programming Hints</h2> + +<ul> +<li>Declare <em>in</em> function parameters as <em>const</em> whenever possible. + This improves the efficiency of function inlining. +</li> +<br> +<li>To reduce register usage, declare variables within smaller scopes. + For example, the following code: +<pre> + void main() + { + vec4 a1, a2, b1, b2; + gl_Position = expression using a1, a2. + gl_Color = expression using b1, b2; + } +</pre> + Can be rewritten as follows to use half as many registers: +<pre> + void main() + { + { + vec4 a1, a2; + gl_Position = expression using a1, a2. + } + { + vec4 b1, b2; + gl_Color = expression using b1, b2; + } + } +</pre> + Alternately, rather than using several float variables, use + a vec4 instead. Use swizzling and writemasks to access the + components of the vec4 as floats. +</li> +<br> +<li>Use the built-in library functions whenever possible. + For example, instead of writing this: +<pre> + float x = 1.0 / sqrt(y); +</pre> + Write this: +<pre> + float x = inversesqrt(y); +</pre> +</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> +To build the glslcompiler program (this will be improved someday): +</p> +<pre> + cd src/mesa + make libmesa.a + cd drivers/glslcompiler + make +</pre> + + +<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> + + + +<a name="implementation"> +<h2>Compiler Implementation</h2> + +<p> +The source code for Mesa's shading language compiler is in the +<code>src/mesa/shader/slang/</code> directory. +</p> + +<p> +The compiler follows a fairly standard design and basically works as follows: +</p> +<ul> +<li>The input string is tokenized (see grammar.c) and parsed +(see slang_compiler_*.c) to produce an Abstract Syntax Tree (AST). +The nodes in this tree are slang_operation structures +(see slang_compile_operation.h). +The nodes are decorated with symbol table, scoping and datatype information. +<li>The AST is converted into an Intermediate representation (IR) tree +(see the slang_codegen.c file). +The IR nodes represent basic GPU instructions, like add, dot product, +move, etc. +The IR tree is mostly a binary tree, but a few nodes have three or four +children. +In principle, the IR tree could be executed by doing an in-order traversal. +<li>The IR tree is traversed in-order to emit code (see slang_emit.c). +This is also when registers are allocated to store variables and temps. +<li>In the future, a pattern-matching code generator-generator may be +used for code generation. +Programs such as L-BURG (Bottom-Up Rewrite Generator) and Twig look for +patterns in IR trees, compute weights for subtrees and use the weights +to select the best instructions to represent the sub-tree. +<li>The emitted GPU instructions (see prog_instruction.h) are stored in a +gl_program object (see mtypes.h). +<li>When a fragment shader and vertex shader are linked (see slang_link.c) +the varying vars are matched up, uniforms are merged, and vertex +attributes are resolved (rewriting instructions as needed). +</ul> + +<p> +The final vertex and fragment programs may be interpreted in software +(see prog_execute.c) or translated into a specific hardware architecture +(see drivers/dri/i915/i915_fragprog.c for example). +</p> + +<h3>Code Generation Options</h3> + +<p> +Internally, there are several options that control the compiler's code +generation and instruction selection. +These options are seen in the gl_shader_state struct and may be set +by the device driver to indicate its preferences: + +<pre> +struct gl_shader_state +{ + ... + /** Driver-selectable options: */ + GLboolean EmitHighLevelInstructions; + GLboolean EmitCondCodes; + GLboolean EmitComments; +}; +</pre> + +<ul> +<li>EmitHighLevelInstructions +<br> +This option controls instruction selection for loops and conditionals. +If the option is set high-level IF/ELSE/ENDIF, LOOP/ENDLOOP, CONT/BRK +instructions will be emitted. +Otherwise, those constructs will be implemented with BRA instructions. +</li> + +<li>EmitCondCodes +<br> +If set, condition codes (ala GL_NV_fragment_program) will be used for +branching and looping. +Otherwise, ordinary registers will be used (the IF instruction will +examine the first operand's X component and do the if-part if non-zero). +This option is only relevant if EmitHighLevelInstructions is set. +</li> + +<li>EmitComments +<br> +If set, instructions will be annoted with comments to help with debugging. +Extra NOP instructions will also be inserted. +</br> + +</ul> + + +</BODY> +</HTML> diff --git a/progs/demos/Makefile b/progs/demos/Makefile index 4623d6c8d9..6369746f00 100644 --- a/progs/demos/Makefile +++ b/progs/demos/Makefile @@ -113,6 +113,10 @@ trackball.o: trackball.c trackball.h $(CC) -c -I$(INCDIR) $(CFLAGS) trackball.c +extfuncs.h: $(TOP)/progs/util/extfuncs.h + cp $< . + + reflect: reflect.o showbuffer.o readtex.o $(CC) -I$(INCDIR) $(CFLAGS) reflect.o showbuffer.o readtex.o $(APP_LIB_DEPS) -o $@ @@ -141,6 +145,9 @@ engine.o: engine.c trackball.h $(CC) -c -I$(INCDIR) $(CFLAGS) engine.c +fslight.c: extfuncs.h + + clean: -rm -f $(PROGS) -rm -f *.o *~ diff --git a/progs/demos/fslight.c b/progs/demos/fslight.c index 1c016cc75e..b03ba2315a 100644 --- a/progs/demos/fslight.c +++ b/progs/demos/fslight.c @@ -20,46 +20,37 @@ #include <GL/gl.h> #include <GL/glut.h> #include <GL/glext.h> +#include "extfuncs.h" + + +static GLint CoordAttrib = 0; + +static char *FragProgFile = NULL; +static char *VertProgFile = NULL; static GLfloat diffuse[4] = { 0.5f, 0.5f, 1.0f, 1.0f }; static GLfloat specular[4] = { 0.8f, 0.8f, 0.8f, 1.0f }; -static GLfloat lightPos[4] = { 0.0f, 10.0f, 20.0f, 1.0f }; +static GLfloat lightPos[4] = { 0.0f, 10.0f, 20.0f, 0.0f }; static GLfloat delta = 1.0f; static GLuint fragShader; static GLuint vertShader; static GLuint program; -static GLint uLightPos; static GLint uDiffuse; static GLint uSpecular; +static GLint uTexture; +static GLuint SphereList, RectList, CurList; static GLint win = 0; -static GLboolean anim = GL_TRUE; +static GLboolean anim = GL_FALSE; static GLboolean wire = GL_FALSE; static GLboolean pixelLight = GL_TRUE; static GLint t0 = 0; static GLint frames = 0; -static GLfloat xRot = 0.0f, yRot = 0.0f; - -static PFNGLCREATESHADERPROC glCreateShader_func = NULL; -static PFNGLSHADERSOURCEPROC glShaderSource_func = NULL; -static PFNGLGETSHADERSOURCEPROC glGetShaderSource_func = NULL; -static PFNGLCOMPILESHADERPROC glCompileShader_func = NULL; -static PFNGLCREATEPROGRAMPROC glCreateProgram_func = NULL; -static PFNGLDELETEPROGRAMPROC glDeleteProgram_func = NULL; -static PFNGLDELETESHADERPROC glDeleteShader_func = NULL; -static PFNGLATTACHSHADERPROC glAttachShader_func = NULL; -static PFNGLLINKPROGRAMPROC glLinkProgram_func = NULL; -static PFNGLUSEPROGRAMPROC glUseProgram_func = NULL; -static PFNGLGETUNIFORMLOCATIONPROC glGetUniformLocation_func = NULL; -static PFNGLISPROGRAMPROC glIsProgram_func = NULL; -static PFNGLISSHADERPROC glIsShader_func = NULL; -static PFNGLUNIFORM3FVPROC glUniform3fv_func = NULL; -static PFNGLUNIFORM3FVPROC glUniform4fv_func = NULL; - +static GLfloat xRot = 90.0f, yRot = 0.0f; static void @@ -69,31 +60,37 @@ normalize(GLfloat *dst, const GLfloat *src) dst[0] = src[0] / len; dst[1] = src[1] / len; dst[2] = src[2] / len; + dst[3] = src[3]; } static void Redisplay(void) { + GLfloat vec[4]; + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + /* update light position */ + normalize(vec, lightPos); + glLightfv(GL_LIGHT0, GL_POSITION, vec); if (pixelLight) { - GLfloat vec[3]; glUseProgram_func(program); - normalize(vec, lightPos); - glUniform3fv_func(uLightPos, 1, vec); glDisable(GL_LIGHTING); } else { glUseProgram_func(0); - glLightfv(GL_LIGHT0, GL_POSITION, lightPos); glEnable(GL_LIGHTING); } glPushMatrix(); glRotatef(xRot, 1.0f, 0.0f, 0.0f); glRotatef(yRot, 0.0f, 1.0f, 0.0f); + /* glutSolidSphere(2.0, 10, 5); + */ + glCallList(CurList); glPopMatrix(); glutSwapBuffers(); @@ -174,6 +171,12 @@ Key(unsigned char key, int x, int y) else glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); break; + case 'o': + if (CurList == SphereList) + CurList = RectList; + else + CurList = SphereList; + break; case 'p': pixelLight = !pixelLight; if (pixelLight) @@ -217,16 +220,246 @@ SpecialKey(int key, int x, int y) static void +TestFunctions(void) +{ + printf("Error 0x%x at line %d\n", glGetError(), __LINE__); + { + GLfloat pos[3]; + printf("Error 0x%x at line %d\n", glGetError(), __LINE__); + printf("Light pos %g %g %g\n", pos[0], pos[1], pos[2]); + } + + + { + GLfloat m[16], result[16]; + GLint mPos; + int i; + + for (i = 0; i < 16; i++) + m[i] = (float) i; + + mPos = glGetUniformLocation_func(program, "m"); + printf("Error 0x%x at line %d\n", glGetError(), __LINE__); + glUniformMatrix4fv_func(mPos, 1, GL_FALSE, m); + printf("Error 0x%x at line %d\n", glGetError(), __LINE__); + + glGetUniformfv_func(program, mPos, result); + printf("Error 0x%x at line %d\n", glGetError(), __LINE__); + + for (i = 0; i < 16; i++) { + printf("%8g %8g\n", m[i], result[i]); + } + } + + assert(glIsProgram_func(program)); + assert(glIsShader_func(fragShader)); + assert(glIsShader_func(vertShader)); + + /* attached shaders */ + { + GLuint shaders[20]; + GLsizei count; + int i; + glGetAttachedShaders_func(program, 20, &count, shaders); + for (i = 0; i < count; i++) { + printf("Attached: %u\n", shaders[i]); + assert(shaders[i] == fragShader || + shaders[i] == vertShader); + } + } + + { + GLchar log[1000]; + GLsizei len; + glGetShaderInfoLog_func(vertShader, 1000, &len, log); + printf("Vert Shader Info Log: %s\n", log); + glGetShaderInfoLog_func(fragShader, 1000, &len, log); + printf("Frag Shader Info Log: %s\n", log); + glGetProgramInfoLog_func(program, 1000, &len, log); + printf("Program Info Log: %s\n", log); + } +} + + +static void +MakeTexture(void) +{ +#define SZ0 128 +#define SZ1 64 + GLubyte image0[SZ0][SZ0][SZ0][4]; + GLubyte image1[SZ1][SZ1][SZ1][4]; + GLuint i, j, k; + + /* level 0: two-tone gray checkboard */ + for (i = 0; i < SZ0; i++) { + for (j = 0; j < SZ0; j++) { + for (k = 0; k < SZ0; k++) { + if ((i/8 + j/8 + k/8) & 1) { + image0[i][j][k][0] = + image0[i][j][k][1] = + image0[i][j][k][2] = 200; + } + else { + image0[i][j][k][0] = + image0[i][j][k][1] = + image0[i][j][k][2] = 100; + } + image0[i][j][k][3] = 255; + } + } + } + + /* level 1: two-tone green checkboard */ + for (i = 0; i < SZ1; i++) { + for (j = 0; j < SZ1; j++) { + for (k = 0; k < SZ1; k++) { + if ((i/8 + j/8 + k/8) & 1) { + image1[i][j][k][0] = 0; + image1[i][j][k][1] = 250; + image1[i][j][k][2] = 0; + } + else { + image1[i][j][k][0] = 0; + image1[i][j][k][1] = 200; + image1[i][j][k][2] = 0; + } + image1[i][j][k][3] = 255; + } + } + } + + glActiveTexture(GL_TEXTURE2); /* unit 2 */ + glBindTexture(GL_TEXTURE_2D, 42); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, SZ0, SZ0, 0, + GL_RGBA, GL_UNSIGNED_BYTE, image0); + glTexImage2D(GL_TEXTURE_2D, 1, GL_RGBA, SZ1, SZ1, 0, + GL_RGBA, GL_UNSIGNED_BYTE, image1); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 1); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + + glActiveTexture(GL_TEXTURE4); /* unit 4 */ + glBindTexture(GL_TEXTURE_3D, 43); + glTexImage3D(GL_TEXTURE_3D, 0, GL_RGBA, SZ0, SZ0, SZ0, 0, + GL_RGBA, GL_UNSIGNED_BYTE, image0); + glTexImage3D(GL_TEXTURE_3D, 1, GL_RGBA, SZ1, SZ1, SZ1, 0, + GL_RGBA, GL_UNSIGNED_BYTE, image1); + glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAX_LEVEL, 1); + glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); +} + + +static void +MakeSphere(void) +{ + GLUquadricObj *obj = gluNewQuadric(); + SphereList = glGenLists(1); + gluQuadricTexture(obj, GL_TRUE); + glNewList(SphereList, GL_COMPILE); + gluSphere(obj, 2.0f, 10, 5); + glEndList(); +} + +static void +VertAttrib(GLint index, float x, float y) +{ +#if 1 + glVertexAttrib2f_func(index, x, y); +#else + glTexCoord2f(x, y); +#endif +} + +static void +MakeRect(void) +{ + RectList = glGenLists(1); + glNewList(RectList, GL_COMPILE); + glNormal3f(0, 0, 1); + glBegin(GL_POLYGON); + VertAttrib(CoordAttrib, 0, 0); glVertex2f(-2, -2); + VertAttrib(CoordAttrib, 1, 0); glVertex2f( 2, -2); + VertAttrib(CoordAttrib, 1, 1); glVertex2f( 2, 2); + VertAttrib(CoordAttrib, 0, 1); glVertex2f(-2, 2); + glEnd(); /* XXX omit this and crash! */ + glEndList(); +} + + + +static void +LoadAndCompileShader(GLuint shader, const char *text) +{ + GLint stat; + + glShaderSource_func(shader, 1, (const GLchar **) &text, NULL); + + glCompileShader_func(shader); + + glGetShaderiv_func(shader, GL_COMPILE_STATUS, &stat); + if (!stat) { + GLchar log[1000]; + GLsizei len; + glGetShaderInfoLog_func(shader, 1000, &len, log); + fprintf(stderr, "fslight: problem compiling shader:\n%s\n", log); + exit(1); + } +} + + +/** + * 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, "fslight: Unable to open shader file %s\n", filename); + exit(1); + } + + n = fread(buffer, 1, max, f); + printf("fslight: read %d bytes from shader file %s\n", n, filename); + if (n > 0) { + buffer[n] = 0; + LoadAndCompileShader(shader, buffer); + } + + fclose(f); + free(buffer); +} + + +static void +CheckLink(GLuint prog) +{ + GLint stat; + glGetProgramiv_func(prog, GL_LINK_STATUS, &stat); + if (!stat) { + GLchar log[1000]; + GLsizei len; + glGetProgramInfoLog_func(prog, 1000, &len, log); + fprintf(stderr, "Linker error:\n%s\n", log); + } +} + + +static void Init(void) { static const char *fragShaderText = - "uniform vec3 lightPos;\n" "uniform vec4 diffuse;\n" "uniform vec4 specular;\n" "varying vec3 normal;\n" "void main() {\n" " // Compute dot product of light direction and normal vector\n" - " float dotProd = max(dot(lightPos, normalize(normal)), 0.0);\n" + " float dotProd = max(dot(gl_LightSource[0].position.xyz, \n" + " normalize(normal)), 0.0);\n" " // Compute diffuse and specular contributions\n" " gl_FragColor = diffuse * dotProd + specular * pow(dotProd, 20.0);\n" "}\n"; @@ -236,8 +469,6 @@ Init(void) " gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;\n" " normal = gl_NormalMatrix * gl_Normal;\n" "}\n"; - - const char *version; version = (const char *) glGetString(GL_VERSION); @@ -246,43 +477,55 @@ Init(void) /*exit(1);*/ } - - glCreateShader_func = (PFNGLCREATESHADERPROC) glutGetProcAddress("glCreateShader"); - glDeleteShader_func = (PFNGLDELETESHADERPROC) glutGetProcAddress("glDeleteShader"); - glDeleteProgram_func = (PFNGLDELETEPROGRAMPROC) glutGetProcAddress("glDeleteProgram"); - glShaderSource_func = (PFNGLSHADERSOURCEPROC) glutGetProcAddress("glShaderSource"); - glGetShaderSource_func = (PFNGLGETSHADERSOURCEPROC) glutGetProcAddress("glGetShaderSource"); - glCompileShader_func = (PFNGLCOMPILESHADERPROC) glutGetProcAddress("glCompileShader"); - glCreateProgram_func = (PFNGLCREATEPROGRAMPROC) glutGetProcAddress("glCreateProgram"); - glAttachShader_func = (PFNGLATTACHSHADERPROC) glutGetProcAddress("glAttachShader"); - glLinkProgram_func = (PFNGLLINKPROGRAMPROC) glutGetProcAddress("glLinkProgram"); - glUseProgram_func = (PFNGLUSEPROGRAMPROC) glutGetProcAddress("glUseProgram"); - glGetUniformLocation_func = (PFNGLGETUNIFORMLOCATIONPROC) glutGetProcAddress("glGetUniformLocation"); - glIsProgram_func = (PFNGLISPROGRAMPROC) glutGetProcAddress("glIsProgram"); - glIsShader_func = (PFNGLISSHADERPROC) glutGetProcAddress("glIsShader"); - glUniform3fv_func = (PFNGLUNIFORM3FVPROC) glutGetProcAddress("glUniform3fv"); - glUniform4fv_func = (PFNGLUNIFORM3FVPROC) glutGetProcAddress("glUniform4fv"); + GetExtensionFuncs(); fragShader = glCreateShader_func(GL_FRAGMENT_SHADER); - glShaderSource_func(fragShader, 1, &fragShaderText, NULL); - glCompileShader_func(fragShader); + if (FragProgFile) + ReadShader(fragShader, FragProgFile); + else + LoadAndCompileShader(fragShader, fragShaderText); + vertShader = glCreateShader_func(GL_VERTEX_SHADER); - glShaderSource_func(vertShader, 1, &vertShaderText, NULL); - glCompileShader_func(vertShader); + if (VertProgFile) + ReadShader(vertShader, VertProgFile); + else + LoadAndCompileShader(vertShader, vertShaderText); program = glCreateProgram_func(); glAttachShader_func(program, fragShader); glAttachShader_func(program, vertShader); glLinkProgram_func(program); + CheckLink(program); glUseProgram_func(program); - uLightPos = glGetUniformLocation_func(program, "lightPos"); uDiffuse = glGetUniformLocation_func(program, "diffuse"); uSpecular = glGetUniformLocation_func(program, "specular"); + uTexture = glGetUniformLocation_func(program, "texture"); + printf("DiffusePos %d SpecularPos %d TexturePos %d\n", + uDiffuse, uSpecular, uTexture); glUniform4fv_func(uDiffuse, 1, diffuse); glUniform4fv_func(uSpecular, 1, specular); + /* assert(glGetError() == 0);*/ + glUniform1i_func(uTexture, 2); /* use texture unit 2 */ + /*assert(glGetError() == 0);*/ + + if (CoordAttrib) { + int i; + glBindAttribLocation_func(program, CoordAttrib, "coord"); + i = glGetAttribLocation_func(program, "coord"); + assert(i >= 0); + if (i != CoordAttrib) { + printf("Hmmm, NVIDIA bug?\n"); + CoordAttrib = i; + } + else { + printf("Mesa bind attrib: coord = %d\n", i); + } + } + + /*assert(glGetError() == 0);*/ glClearColor(0.3f, 0.3f, 0.3f, 0.0f); glEnable(GL_DEPTH_TEST); @@ -292,11 +535,18 @@ Init(void) glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, specular); glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, 20.0f); + MakeSphere(); + MakeRect(); + + CurList = SphereList; + + MakeTexture(); + printf("GL_RENDERER = %s\n",(const char *) glGetString(GL_RENDERER)); printf("Press p to toggle between per-pixel and per-vertex lighting\n"); /* test glGetShaderSource() */ - { + if (0) { GLsizei len = strlen(fragShaderText) + 1; GLsizei lenOut; GLchar *src =(GLchar *) malloc(len * sizeof(GLchar)); @@ -310,6 +560,35 @@ Init(void) assert(glIsProgram_func(program)); assert(glIsShader_func(fragShader)); assert(glIsShader_func(vertShader)); + + glColor3f(1, 0, 0); + + /* for testing state vars */ + { + static GLfloat fc[4] = { 1, 1, 0, 0 }; + static GLfloat amb[4] = { 1, 0, 1, 0 }; + glFogfv(GL_FOG_COLOR, fc); + glLightfv(GL_LIGHT1, GL_AMBIENT, amb); + } + +#if 0 + TestFunctions(); +#endif +} + + +static void +ParseOptions(int argc, char *argv[]) +{ + int i; + for (i = 1; i < argc; i++) { + if (strcmp(argv[i], "-fs") == 0) { + FragProgFile = argv[i+1]; + } + else if (strcmp(argv[i], "-vs") == 0) { + VertProgFile = argv[i+1]; + } + } } @@ -318,7 +597,7 @@ main(int argc, char *argv[]) { glutInit(&argc, argv); glutInitWindowPosition( 0, 0); - glutInitWindowSize(200, 200); + glutInitWindowSize(100, 100); glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH); win = glutCreateWindow(argv[0]); glutReshapeFunc(Reshape); @@ -327,8 +606,10 @@ main(int argc, char *argv[]) glutDisplayFunc(Redisplay); if (anim) glutIdleFunc(Idle); + ParseOptions(argc, argv); Init(); glutMainLoop(); return 0; } + diff --git a/progs/glsl/CH06-brick.frag.txt b/progs/glsl/CH06-brick.frag.txt new file mode 100644 index 0000000000..06ef04e3af --- /dev/null +++ b/progs/glsl/CH06-brick.frag.txt @@ -0,0 +1,36 @@ +// +// Fragment shader for procedural bricks +// +// Authors: Dave Baldwin, Steve Koren, Randi Rost +// based on a shader by Darwyn Peachey +// +// Copyright (c) 2002-2006 3Dlabs Inc. Ltd. +// +// See 3Dlabs-License.txt for license information +// + +uniform vec3 BrickColor, MortarColor; +uniform vec2 BrickSize; +uniform vec2 BrickPct; + +varying vec2 MCposition; +varying float LightIntensity; + +void main() +{ + vec3 color; + vec2 position, useBrick; + + position = MCposition / BrickSize; + + if (fract(position.y * 0.5) > 0.5) + position.x += 0.5; + + position = fract(position); + + useBrick = step(position, BrickPct); + + color = mix(MortarColor, BrickColor, useBrick.x * useBrick.y); + color *= LightIntensity; + gl_FragColor = vec4(color, 1.0); +} diff --git a/progs/glsl/CH06-brick.vert.txt b/progs/glsl/CH06-brick.vert.txt new file mode 100644 index 0000000000..e95e6f42f0 --- /dev/null +++ b/progs/glsl/CH06-brick.vert.txt @@ -0,0 +1,41 @@ +// +// Vertex shader for procedural bricks +// +// Authors: Dave Baldwin, Steve Koren, Randi Rost +// based on a shader by Darwyn Peachey +// +// Copyright (c) 2002-2006 3Dlabs Inc. Ltd. +// +// See 3Dlabs-License.txt for license information +// + +uniform vec3 LightPosition; + +const float SpecularContribution = 0.3; +const float DiffuseContribution = 1.0 - SpecularContribution; + +varying float LightIntensity; +varying vec2 MCposition; + +void main() +{ + vec3 ecPosition = vec3(gl_ModelViewMatrix * gl_Vertex); + vec3 tnorm = normalize(gl_NormalMatrix * gl_Normal); + vec3 lightVec = normalize(LightPosition - ecPosition); + vec3 reflectVec = reflect(-lightVec, tnorm); + vec3 viewVec = normalize(-ecPosition); + float diffuse = max(dot(lightVec, tnorm), 0.0); + float spec = 0.0; + + if (diffuse > 0.0) + { + spec = max(dot(reflectVec, viewVec), 0.0); + spec = pow(spec, 16.0); + } + + LightIntensity = DiffuseContribution * diffuse + + SpecularContribution * spec; + + MCposition = gl_Vertex.xy; + gl_Position = ftransform(); +} diff --git a/progs/glsl/CH11-bumpmap.frag.txt b/progs/glsl/CH11-bumpmap.frag.txt new file mode 100644 index 0000000000..063576f5a3 --- /dev/null +++ b/progs/glsl/CH11-bumpmap.frag.txt @@ -0,0 +1,41 @@ +// +// Fragment shader for procedural bumps +// +// Authors: John Kessenich, Randi Rost +// +// Copyright (c) 2002-2006 3Dlabs Inc. Ltd. +// +// See 3Dlabs-License.txt for license information +// + +varying vec3 LightDir; +varying vec3 EyeDir; + +uniform vec3 SurfaceColor; // = (0.7, 0.6, 0.18) +uniform float BumpDensity; // = 16.0 +uniform float BumpSize; // = 0.15 +uniform float SpecularFactor; // = 0.5 + +void main() +{ + vec3 litColor; + vec2 c = BumpDensity * gl_TexCoord[0].st; + vec2 p = fract(c) - vec2(0.5); + + float d, f; + d = p.x * p.x + p.y * p.y; + f = 1.0 / sqrt(d + 1.0); + + if (d >= BumpSize) + { p = vec2(0.0); f = 1.0; } + + vec3 normDelta = vec3(p.x, p.y, 1.0) * f; + litColor = SurfaceColor * max(dot(normDelta, LightDir), 0.0); + vec3 reflectDir = reflect(LightDir, normDelta); + + float spec = max(dot(EyeDir, reflectDir), 0.0); + spec *= SpecularFactor; + litColor = min(litColor + spec, vec3(1.0)); + + gl_FragColor = vec4(litColor, 1.0); +} diff --git a/progs/glsl/CH11-bumpmap.vert.txt b/progs/glsl/CH11-bumpmap.vert.txt new file mode 100644 index 0000000000..d3d19f62ac --- /dev/null +++ b/progs/glsl/CH11-bumpmap.vert.txt @@ -0,0 +1,38 @@ +// +// Vertex shader for procedural bumps +// +// Authors: Randi Rost, John Kessenich +// +// Copyright (c) 2002-2006 3Dlabs Inc. Ltd. +// +// See 3Dlabs-License.txt for license information +// + +varying vec3 LightDir; +varying vec3 EyeDir; + +uniform vec3 LightPosition; + +attribute vec3 Tangent; + +void main() +{ + EyeDir = vec3(gl_ModelViewMatrix * gl_Vertex); + gl_Position = ftransform(); + gl_TexCoord[0] = gl_MultiTexCoord0; + + vec3 n = normalize(gl_NormalMatrix * gl_Normal); + vec3 t = normalize(gl_NormalMatrix * Tangent); + vec3 b = cross(n, t); + + vec3 v; + v.x = dot(LightPosition, t); + v.y = dot(LightPosition, b); + v.z = dot(LightPosition, n); + LightDir = normalize(v); + + v.x = dot(EyeDir, t); + v.y = dot(EyeDir, b); + v.z = dot(EyeDir, n); + EyeDir = normalize(v); +} diff --git a/progs/glsl/CH11-toyball.frag.txt b/progs/glsl/CH11-toyball.frag.txt new file mode 100644 index 0000000000..90ec1c27fc --- /dev/null +++ b/progs/glsl/CH11-toyball.frag.txt @@ -0,0 +1,75 @@ +// +// Fragment shader for procedurally generated toy ball +// +// Author: Bill Licea-Kane +// +// Copyright (c) 2002-2003 ATI Research +// +// See ATI-License.txt for license information +// + +varying vec4 ECposition; // surface position in eye coordinates +varying vec4 ECballCenter; // ball center in eye coordinates + +uniform vec4 LightDir; // light direction, should be normalized +uniform vec4 HVector; // reflection vector for infinite light source +uniform vec4 SpecularColor; +uniform vec4 Red, Yellow, Blue; + +uniform vec4 HalfSpace0; // half-spaces used to define star pattern +uniform vec4 HalfSpace1; +uniform vec4 HalfSpace2; +uniform vec4 HalfSpace3; +uniform vec4 HalfSpace4; + +uniform float InOrOutInit; // = -3 +uniform float StripeWidth; // = 0.3 +uniform float FWidth; // = 0.005 + +void main() +{ + vec4 normal; // Analytically computed normal + vec4 p; // Point in shader space + vec4 surfColor; // Computed color of the surface + float intensity; // Computed light intensity + vec4 distance; // Computed distance values + float inorout; // Counter for computing star pattern + + p.xyz = normalize(ECposition.xyz - ECballCenter.xyz); // Calculate p + p.w = 1.0; + + inorout = InOrOutInit; // initialize inorout to -3 + + distance[0] = dot(p, HalfSpace0); + distance[1] = dot(p, HalfSpace1); + distance[2] = dot(p, HalfSpace2); + distance[3] = dot(p, HalfSpace3); + + distance = smoothstep(-FWidth, FWidth, distance); + inorout += dot(distance, vec4(1.0)); + + distance.x = dot(p, HalfSpace4); + distance.y = StripeWidth - abs(p.z); + distance = smoothstep(-FWidth, FWidth, distance); + inorout += distance.x; + + inorout = clamp(inorout, 0.0, 1.0); + + surfColor = mix(Yellow, Red, inorout); + surfColor = mix(surfColor, Blue, distance.y); + + // normal = point on surface for sphere at (0,0,0) + normal = p; + + // Per fragment diffuse lighting + intensity = 0.2; // ambient + intensity += 0.8 * clamp(dot(LightDir, normal), 0.0, 1.0); + surfColor *= intensity; + + // Per fragment specular lighting + intensity = clamp(dot(HVector, normal), 0.0, 1.0); + intensity = pow(intensity, SpecularColor.a); + surfColor += SpecularColor * intensity; + + gl_FragColor = surfColor; +} diff --git a/progs/glsl/CH11-toyball.vert.txt b/progs/glsl/CH11-toyball.vert.txt new file mode 100644 index 0000000000..b7da3ac839 --- /dev/null +++ b/progs/glsl/CH11-toyball.vert.txt @@ -0,0 +1,24 @@ +// +// Fragment shader for procedurally generated toy ball +// +// Author: Bill Licea-Kane +// +// Copyright (c) 2002-2003 ATI Research +// +// See ATI-License.txt for license information +// + +varying vec4 ECposition; // surface position in eye coordinates +varying vec4 ECballCenter; // ball center in eye coordinates +uniform vec4 BallCenter; // ball center in modelling coordinates + +void main() +{ +//orig: ECposition = gl_ModelViewMatrix * gl_Vertex; + + ECposition = gl_TextureMatrix[0] * gl_Vertex; + ECposition = gl_ModelViewMatrix * ECposition; + + ECballCenter = gl_ModelViewMatrix * BallCenter; + gl_Position = ftransform(); +} diff --git a/progs/glsl/CH18-mandel.frag.txt b/progs/glsl/CH18-mandel.frag.txt new file mode 100644 index 0000000000..a472d81252 --- /dev/null +++ b/progs/glsl/CH18-mandel.frag.txt @@ -0,0 +1,55 @@ +// +// Fragment shader for drawing the Mandelbrot set +// +// Authors: Dave Baldwin, Steve Koren, Randi Rost +// based on a shader by Michael Rivero +// +// Copyright (c) 2002-2005: 3Dlabs, Inc. +// +// See 3Dlabs-License.txt for license information +// + +varying vec3 Position; +varying float LightIntensity; + +uniform float MaxIterations; +uniform float Zoom; +uniform float Xcenter; +uniform float Ycenter; +uniform vec3 InnerColor; +uniform vec3 OuterColor1; +uniform vec3 OuterColor2; + +void main() +{ + float real = Position.x * Zoom + Xcenter; + float imag = Position.y * Zoom + Ycenter; + float Creal = real; // Change this line... + float Cimag = imag; // ...and this one to get a Julia set + + float r2 = 0.0; + float iter; + +// for (iter = 0.0; iter < MaxIterations && r2 < 4.0; ++iter) + for (iter = 0.0; iter < 12 && r2 < 4.0; ++iter) + { + float tempreal = real; + + real = (tempreal * tempreal) - (imag * imag) + Creal; + imag = 2.0 * tempreal * imag + Cimag; + r2 = (real * real) + (imag * imag); + } + + // Base the color on the number of iterations + + vec3 color; + + if (r2 < 4.0) + color = InnerColor; + else + color = mix(OuterColor1, OuterColor2, fract(iter * 0.05)); + + color *= LightIntensity; + + gl_FragColor = vec4(color, 1.0); +} diff --git a/progs/glsl/CH18-mandel.vert.txt b/progs/glsl/CH18-mandel.vert.txt new file mode 100644 index 0000000000..c4ca66405d --- /dev/null +++ b/progs/glsl/CH18-mandel.vert.txt @@ -0,0 +1,35 @@ +// +// Vertex shader for drawing the Mandelbrot set +// +// Authors: Dave Baldwin, Steve Koren, Randi Rost +// based on a shader by Michael Rivero +// +// Copyright (c) 2002-2005: 3Dlabs, Inc. +// +// See 3Dlabs-License.txt for license information +// + +uniform vec3 LightPosition; +uniform float SpecularContribution; +uniform float DiffuseContribution; +uniform float Shininess; + +varying float LightIntensity; +varying vec3 Position; + +void main() +{ + vec3 ecPosition = vec3(gl_ModelViewMatrix * gl_Vertex); + vec3 tnorm = normalize(gl_NormalMatrix * gl_Normal); + vec3 lightVec = normalize(LightPosition - ecPosition); + vec3 reflectVec = reflect(-lightVec, tnorm); + vec3 viewVec = normalize(-ecPosition); + float spec = max(dot(reflectVec, viewVec), 0.0); + spec = pow(spec, Shininess); + LightIntensity = DiffuseContribution * + max(dot(lightVec, tnorm), 0.0) + + SpecularContribution * spec; + Position = vec3(gl_MultiTexCoord0 - 0.5) * 5.0; + gl_Position = ftransform(); + +}
\ No newline at end of file diff --git a/progs/glsl/Makefile b/progs/glsl/Makefile new file mode 100644 index 0000000000..e08d4102c8 --- /dev/null +++ b/progs/glsl/Makefile @@ -0,0 +1,74 @@ +# progs/demos/Makefile + +TOP = ../.. +include $(TOP)/configs/current + +INCDIR = $(TOP)/include + +OSMESA_LIBS = -L$(TOP)/$(LIB_DIR) -lglut -lOSMesa -lGLU -lGL $(APP_LIB_DEPS) + +OSMESA16_LIBS = -L$(TOP)/$(LIB_DIR) -lglut -lOSMesa16 -lGLU -lGL $(APP_LIB_DEPS) + +OSMESA32_LIBS = -L$(TOP)/$(LIB_DIR) -lglut -lOSMesa32 -lGLU -lGL $(APP_LIB_DEPS) + +LIB_DEP = $(TOP)/$(LIB_DIR)/$(GL_LIB_NAME) $(TOP)/$(LIB_DIR)/$(GLU_LIB_NAME) $(TOP)/$(LIB_DIR)/$(GLUT_LIB_NAME) + +PROGS = \ + brick \ + bump \ + mandelbrot \ + noise \ + toyball \ + texdemo1 + + +##### RULES ##### + +.SUFFIXES: +.SUFFIXES: .c + + +# make executable from .c file: +.c: $(LIB_DEP) + $(CC) -I$(INCDIR) $(CFLAGS) $< $(APP_LIB_DEPS) -o $@ + + +##### TARGETS ##### + +default: $(PROGS) + + + +##### Extra dependencies + +extfuncs.h: $(TOP)/progs/util/extfuncs.h + cp $< . + +readtex.c: $(TOP)/progs/util/readtex.c + cp $< . + +readtex.h: $(TOP)/progs/util/readtex.h + cp $< . + +readtex.o: readtex.c readtex.h + $(CC) -c -I$(INCDIR) $(CFLAGS) readtex.c + +brick.c: extfuncs.h + +bump.c: extfuncs.h + +mandelbrot.c: extfuncs.h + +toyball.c: extfuncs.h + +texdemo1: texdemo1.o readtex.o + $(CC) -I$(INCDIR) $(CFLAGS) texdemo1.o readtex.o $(APP_LIB_DEPS) -o $@ + +texdemo1.o: texdemo1.c readtex.h extfuncs.h + $(CC) -c -I$(INCDIR) $(CFLAGS) texdemo1.c + + +clean: + -rm -f $(PROGS) + -rm -f *.o *~ + -rm -f extfuncs.h diff --git a/progs/glsl/brick.c b/progs/glsl/brick.c new file mode 100644 index 0000000000..522698b5d4 --- /dev/null +++ b/progs/glsl/brick.c @@ -0,0 +1,311 @@ +/** + * "Brick" shader demo. Uses the example shaders from chapter 6 of + * the OpenGL Shading Language "orange" book. + * 10 Jan 2007 + */ + +#include <assert.h> +#include <string.h> +#include <stdio.h> +#include <stdlib.h> +#include <math.h> +#include <GL/gl.h> +#include <GL/glut.h> +#include <GL/glext.h> +#include "extfuncs.h" + + +static char *FragProgFile = "CH06-brick.frag.txt"; +static char *VertProgFile = "CH06-brick.vert.txt"; + +/* program/shader objects */ +static GLuint fragShader; +static GLuint vertShader; +static GLuint program; + + +struct uniform_info { + const char *name; + GLuint size; + GLint location; + GLfloat value[4]; +}; + +static struct uniform_info Uniforms[] = { + /* vert */ + { "LightPosition", 3, -1, { 0.1, 0.1, 9.0, 0} }, + /* frag */ + { "BrickColor", 3, -1, { 0.8, 0.2, 0.2, 0 } }, + { "MortarColor", 3, -1, { 0.6, 0.6, 0.6, 0 } }, + { "BrickSize", 2, -1, { 1.0, 0.3, 0, 0 } }, + { "BrickPct", 2, -1, { 0.9, 0.8, 0, 0 } }, + { NULL, 0, 0, { 0, 0, 0, 0 } } +}; + +static GLint win = 0; + + +static GLfloat xRot = 0.0f, yRot = 0.0f, zRot = 0.0f; + + + + +static void +Redisplay(void) +{ + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + glPushMatrix(); + glRotatef(xRot, 1.0f, 0.0f, 0.0f); + glRotatef(yRot, 0.0f, 1.0f, 0.0f); + glRotatef(zRot, 0.0f, 0.0f, 1.0f); + + glBegin(GL_POLYGON); + glTexCoord2f(0, 0); glVertex2f(-2, -2); + glTexCoord2f(1, 0); glVertex2f( 2, -2); + glTexCoord2f(1, 1); glVertex2f( 2, 2); + glTexCoord2f(0, 1); glVertex2f(-2, 2); + glEnd(); + + glPopMatrix(); + + glutSwapBuffers(); +} + + +static void +Reshape(int width, int height) +{ + glViewport(0, 0, width, height); + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + glFrustum(-1.0, 1.0, -1.0, 1.0, 5.0, 25.0); + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); + glTranslatef(0.0f, 0.0f, -15.0f); +} + + +static void +CleanUp(void) +{ + glDeleteShader_func(fragShader); + glDeleteShader_func(vertShader); + glDeleteProgram_func(program); + glutDestroyWindow(win); +} + + +static void +Key(unsigned char key, int x, int y) +{ + (void) x; + (void) y; + + switch(key) { + case 'z': + zRot -= 1.0; + break; + case 'Z': + zRot += 1.0; + break; + case 27: + CleanUp(); + exit(0); + break; + } + glutPostRedisplay(); +} + + +static void +SpecialKey(int key, int x, int y) +{ + const GLfloat step = 3.0f; + + (void) x; + (void) y; + + switch(key) { + case GLUT_KEY_UP: + xRot -= step; + break; + case GLUT_KEY_DOWN: + xRot += step; + break; + case GLUT_KEY_LEFT: + yRot -= step; + break; + case GLUT_KEY_RIGHT: + yRot += step; + break; + } + glutPostRedisplay(); +} + + + +static void +LoadAndCompileShader(GLuint shader, const char *text) +{ + GLint stat; + + glShaderSource_func(shader, 1, (const GLchar **) &text, NULL); + + glCompileShader_func(shader); + + glGetShaderiv_func(shader, GL_COMPILE_STATUS, &stat); + if (!stat) { + GLchar log[1000]; + GLsizei len; + glGetShaderInfoLog_func(shader, 1000, &len, log); + fprintf(stderr, "brick: problem compiling shader: %s\n", 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, "brick: Unable to open shader file %s\n", filename); + exit(1); + } + + n = fread(buffer, 1, max, f); + printf("brick: read %d bytes from shader file %s\n", n, filename); + if (n > 0) { + buffer[n] = 0; + LoadAndCompileShader(shader, buffer); + } + + fclose(f); + free(buffer); +} + + +static void +CheckLink(GLuint prog) +{ + GLint stat; + glGetProgramiv_func(prog, GL_LINK_STATUS, &stat); + if (!stat) { + GLchar log[1000]; + GLsizei len; + glGetProgramInfoLog_func(prog, 1000, &len, log); + fprintf(stderr, "Linker error:\n%s\n", log); + } + else { + fprintf(stderr, "Link success!\n"); + } +} + + +static void +Init(void) +{ + const char *version; + GLint i; + + version = (const char *) glGetString(GL_VERSION); + if (version[0] != '2' || version[1] != '.') { + printf("Warning: this program expects OpenGL 2.0\n"); + /*exit(1);*/ + } + + GetExtensionFuncs(); + + vertShader = glCreateShader_func(GL_VERTEX_SHADER); + ReadShader(vertShader, VertProgFile); + + fragShader = glCreateShader_func(GL_FRAGMENT_SHADER); + ReadShader(fragShader, FragProgFile); + + program = glCreateProgram_func(); + glAttachShader_func(program, fragShader); + glAttachShader_func(program, vertShader); + glLinkProgram_func(program); + CheckLink(program); + glUseProgram_func(program); + + for (i = 0; Uniforms[i].name; i++) { + Uniforms[i].location + = glGetUniformLocation_func(program, Uniforms[i].name); + printf("Uniform %s location: %d\n", Uniforms[i].name, + Uniforms[i].location); + switch (Uniforms[i].size) { + case 1: + glUniform1fv_func(Uniforms[i].location, 1, Uniforms[i].value); + break; + case 2: + glUniform2fv_func(Uniforms[i].location, 1, Uniforms[i].value); + break; + case 3: + glUniform3fv_func(Uniforms[i].location, 1, Uniforms[i].value); + break; + case 4: + glUniform4fv_func(Uniforms[i].location, 1, Uniforms[i].value); + break; + default: + abort(); + } + } + + assert(glGetError() == 0); + + glClearColor(0.4f, 0.4f, 0.8f, 0.0f); + + printf("GL_RENDERER = %s\n",(const char *) glGetString(GL_RENDERER)); + + assert(glIsProgram_func(program)); + assert(glIsShader_func(fragShader)); + assert(glIsShader_func(vertShader)); + + glColor3f(1, 0, 0); +} + + +static void +ParseOptions(int argc, char *argv[]) +{ + int i; + for (i = 1; i < argc; i++) { + if (strcmp(argv[i], "-fs") == 0) { + FragProgFile = argv[i+1]; + } + else if (strcmp(argv[i], "-vs") == 0) { + VertProgFile = argv[i+1]; + } + } +} + + +int +main(int argc, char *argv[]) +{ + glutInit(&argc, argv); + glutInitWindowPosition( 0, 0); + glutInitWindowSize(400, 400); + glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH); + win = glutCreateWindow(argv[0]); + glutReshapeFunc(Reshape); + glutKeyboardFunc(Key); + glutSpecialFunc(SpecialKey); + glutDisplayFunc(Redisplay); + ParseOptions(argc, argv); + Init(); + glutMainLoop(); + return 0; +} + diff --git a/progs/glsl/bump.c b/progs/glsl/bump.c new file mode 100644 index 0000000000..a6846acf7e --- /dev/null +++ b/progs/glsl/bump.c @@ -0,0 +1,411 @@ +/** + * Procedural Bump Mapping demo. Uses the example shaders from + * chapter 11 of the OpenGL Shading Language "orange" book. + * 16 Jan 2007 + */ + +#include <assert.h> +#include <string.h> +#include <stdio.h> +#include <stdlib.h> +#include <math.h> +#include <GL/glut.h> +#include <GL/glu.h> +#include <GL/glext.h> +#include "extfuncs.h" + + +static char *FragProgFile = "CH11-bumpmap.frag.txt"; +static char *VertProgFile = "CH11-bumpmap.vert.txt"; + +/* program/shader objects */ +static GLuint fragShader; +static GLuint vertShader; +static GLuint program; + + +struct uniform_info { + const char *name; + GLuint size; + GLint location; + GLfloat value[4]; +}; + +static struct uniform_info Uniforms[] = { + { "LightPosition", 3, -1, { 0.57737, 0.57735, 0.57735, 0.0 } }, + { "SurfaceColor", 3, -1, { 0.8, 0.8, 0.2, 0 } }, + { "BumpDensity", 1, -1, { 10.0, 0, 0, 0 } }, + { "BumpSize", 1, -1, { 0.125, 0, 0, 0 } }, + { "SpecularFactor", 1, -1, { 0.5, 0, 0, 0 } }, + { NULL, 0, 0, { 0, 0, 0, 0 } } +}; + +static GLint win = 0; + +static GLfloat xRot = 20.0f, yRot = 0.0f, zRot = 0.0f; + +static GLuint tangentAttrib; + +static GLboolean Anim = GL_FALSE; + + +static void +CheckError(int line) +{ + GLenum err = glGetError(); + if (err) { + printf("GL Error %s (0x%x) at line %d\n", + gluErrorString(err), (int) err, line); + } +} + +/* + * Draw a square, specifying normal and tangent vectors. + */ +static void +Square(GLfloat size) +{ + glNormal3f(0, 0, 1); + glVertexAttrib3f_func(tangentAttrib, 1, 0, 0); + glBegin(GL_POLYGON); + glTexCoord2f(0, 0); glVertex2f(-size, -size); + glTexCoord2f(1, 0); glVertex2f( size, -size); + glTexCoord2f(1, 1); glVertex2f( size, size); + glTexCoord2f(0, 1); glVertex2f(-size, size); + glEnd(); +} + + +static void +Cube(GLfloat size) +{ + /* +X */ + glPushMatrix(); + glRotatef(90, 0, 1, 0); + glTranslatef(0, 0, size); + Square(size); + glPopMatrix(); + + /* -X */ + glPushMatrix(); + glRotatef(-90, 0, 1, 0); + glTranslatef(0, 0, size); + Square(size); + glPopMatrix(); + + /* +Y */ + glPushMatrix(); + glRotatef(90, 1, 0, 0); + glTranslatef(0, 0, size); + Square(size); + glPopMatrix(); + + /* -Y */ + glPushMatrix(); + glRotatef(-90, 1, 0, 0); + glTranslatef(0, 0, size); + Square(size); + glPopMatrix(); + + + /* +Z */ + glPushMatrix(); + glTranslatef(0, 0, size); + Square(size); + glPopMatrix(); + + /* -Z */ + glPushMatrix(); + glRotatef(180, 0, 1, 0); + glTranslatef(0, 0, size); + Square(size); + glPopMatrix(); + +} + + +static void +Idle(void) +{ + GLint t = glutGet(GLUT_ELAPSED_TIME); + yRot = t * 0.05; + glutPostRedisplay(); +} + + +static void +Redisplay(void) +{ + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + glPushMatrix(); + glRotatef(xRot, 1.0f, 0.0f, 0.0f); + glRotatef(yRot, 0.0f, 1.0f, 0.0f); + glRotatef(zRot, 0.0f, 0.0f, 1.0f); + + Cube(1.5); + + glPopMatrix(); + + glFinish(); + glFlush(); + + CheckError(__LINE__); + + glutSwapBuffers(); +} + + +static void +Reshape(int width, int height) +{ + glViewport(0, 0, width, height); + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + glFrustum(-1.0, 1.0, -1.0, 1.0, 5.0, 25.0); + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); + glTranslatef(0.0f, 0.0f, -15.0f); +} + + +static void +CleanUp(void) +{ + glDeleteShader_func(fragShader); + glDeleteShader_func(vertShader); + glDeleteProgram_func(program); + glutDestroyWindow(win); +} + + +static void +Key(unsigned char key, int x, int y) +{ + const GLfloat step = 2.0; + (void) x; + (void) y; + + switch(key) { + case 'a': + Anim = !Anim; + glutIdleFunc(Anim ? Idle : NULL); + break; + case 'z': + zRot += step; + break; + case 'Z': + zRot -= step; + break; + case 27: + CleanUp(); + exit(0); + break; + } + glutPostRedisplay(); +} + + +static void +SpecialKey(int key, int x, int y) +{ + const GLfloat step = 2.0; + + (void) x; + (void) y; + + switch(key) { + case GLUT_KEY_UP: + xRot += step; + break; + case GLUT_KEY_DOWN: + xRot -= step; + break; + case GLUT_KEY_LEFT: + yRot -= step; + break; + case GLUT_KEY_RIGHT: + yRot += step; + break; + } + glutPostRedisplay(); +} + + + +static void +LoadAndCompileShader(GLuint shader, const char *text) +{ + GLint stat; + + glShaderSource_func(shader, 1, (const GLchar **) &text, NULL); + + glCompileShader_func(shader); + + glGetShaderiv_func(shader, GL_COMPILE_STATUS, &stat); + if (!stat) { + GLchar log[1000]; + GLsizei len; + glGetShaderInfoLog_func(shader, 1000, &len, log); + fprintf(stderr, "brick: problem compiling shader: %s\n", 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, "brick: Unable to open shader file %s\n", filename); + exit(1); + } + + n = fread(buffer, 1, max, f); + printf("brick: read %d bytes from shader file %s\n", n, filename); + if (n > 0) { + buffer[n] = 0; + LoadAndCompileShader(shader, buffer); + } + + fclose(f); + free(buffer); +} + + +static void +CheckLink(GLuint prog) +{ + GLint stat; + glGetProgramiv_func(prog, GL_LINK_STATUS, &stat); + if (!stat) { + GLchar log[1000]; + GLsizei len; + glGetProgramInfoLog_func(prog, 1000, &len, log); + fprintf(stderr, "Linker error:\n%s\n", log); + } + else { + fprintf(stderr, "Link success!\n"); + } +} + + +static void +Init(void) +{ + const char *version; + GLint i; + + version = (const char *) glGetString(GL_VERSION); + if (version[0] != '2' || version[1] != '.') { + printf("Warning: this program expects OpenGL 2.0\n"); + /*exit(1);*/ + } + printf("GL_RENDERER = %s\n",(const char *) glGetString(GL_RENDERER)); + + GetExtensionFuncs(); + + vertShader = glCreateShader_func(GL_VERTEX_SHADER); + ReadShader(vertShader, VertProgFile); + + fragShader = glCreateShader_func(GL_FRAGMENT_SHADER); + ReadShader(fragShader, FragProgFile); + + program = glCreateProgram_func(); + glAttachShader_func(program, fragShader); + glAttachShader_func(program, vertShader); + glLinkProgram_func(program); + CheckLink(program); + glUseProgram_func(program); + + assert(glIsProgram_func(program)); + assert(glIsShader_func(fragShader)); + assert(glIsShader_func(vertShader)); + + assert(glGetError() == 0); + + CheckError(__LINE__); + + for (i = 0; Uniforms[i].name; i++) { + Uniforms[i].location + = glGetUniformLocation_func(program, Uniforms[i].name); + printf("Uniform %s location: %d\n", Uniforms[i].name, + Uniforms[i].location); + switch (Uniforms[i].size) { + case 1: + glUniform1fv_func(Uniforms[i].location, 1, Uniforms[i].value); + break; + case 2: + glUniform2fv_func(Uniforms[i].location, 1, Uniforms[i].value); + break; + case 3: + glUniform3fv_func(Uniforms[i].location, 1, Uniforms[i].value); + break; + case 4: + glUniform4fv_func(Uniforms[i].location, 1, Uniforms[i].value); + break; + default: + abort(); + } + } + + CheckError(__LINE__); + + tangentAttrib = glGetAttribLocation_func(program, "Tangent"); + printf("Tangent Attrib: %d\n", tangentAttrib); + + assert(tangentAttrib >= 0); + + CheckError(__LINE__); + + glClearColor(0.4f, 0.4f, 0.8f, 0.0f); + + glEnable(GL_DEPTH_TEST); + + glColor3f(1, 0, 0); +} + + +static void +ParseOptions(int argc, char *argv[]) +{ + int i; + for (i = 1; i < argc; i++) { + if (strcmp(argv[i], "-fs") == 0) { + FragProgFile = argv[i+1]; + } + else if (strcmp(argv[i], "-vs") == 0) { + VertProgFile = argv[i+1]; + } + } +} + + +int +main(int argc, char *argv[]) +{ + glutInit(&argc, argv); + glutInitWindowPosition( 0, 0); + glutInitWindowSize(400, 400); + glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH); + win = glutCreateWindow(argv[0]); + glutReshapeFunc(Reshape); + glutKeyboardFunc(Key); + glutSpecialFunc(SpecialKey); + glutDisplayFunc(Redisplay); + ParseOptions(argc, argv); + Init(); + glutMainLoop(); + return 0; +} + diff --git a/progs/glsl/cubemap.frag.txt b/progs/glsl/cubemap.frag.txt new file mode 100644 index 0000000000..9c27648aaf --- /dev/null +++ b/progs/glsl/cubemap.frag.txt @@ -0,0 +1,18 @@ +// Fragment shader for cube-texture reflection mapping +// Brian Paul + + +uniform samplerCube cubeTex; +varying vec3 normal; +uniform vec3 lightPos; + +void main() +{ + // simple diffuse, specular lighting: + vec3 lp = normalize(lightPos); + float dp = dot(lp, normalize(normal)); + float spec = pow(dp, 5.0); + + // final color: + gl_FragColor = dp * textureCube(cubeTex, gl_TexCoord[0].xyz, 0.0) + spec; +} diff --git a/progs/glsl/mandelbrot.c b/progs/glsl/mandelbrot.c new file mode 100644 index 0000000000..7a2bad6dde --- /dev/null +++ b/progs/glsl/mandelbrot.c @@ -0,0 +1,328 @@ +/** + * "Mandelbrot" shader demo. Uses the example shaders from + * chapter 15 (or 18) of the OpenGL Shading Language "orange" book. + * 15 Jan 2007 + */ + +#include <assert.h> +#include <string.h> +#include <stdio.h> +#include <stdlib.h> +#include <math.h> +#include <GL/gl.h> +#include <GL/glut.h> +#include <GL/glext.h> +#include "extfuncs.h" + + +static char *FragProgFile = "CH18-mandel.frag.txt"; +static char *VertProgFile = "CH18-mandel.vert.txt"; + +/* program/shader objects */ +static GLuint fragShader; +static GLuint vertShader; +static GLuint program; + + +struct uniform_info { + const char *name; + GLuint size; + GLint location; + GLfloat value[4]; +}; + +static struct uniform_info Uniforms[] = { + /* vert */ + { "LightPosition", 3, -1, { 0.1, 0.1, 9.0, 0} }, + { "SpecularContribution", 1, -1, { 0.5, 0, 0, 0 } }, + { "DiffuseContribution", 1, -1, { 0.5, 0, 0, 0 } }, + { "Shininess", 1, -1, { 20.0, 0, 0, 0 } }, + /* frag */ + { "MaxIterations", 1, -1, { 12, 0, 0, 0 } }, + { "Zoom", 1, -1, { 0.125, 0, 0, 0 } }, + { "Xcenter", 1, -1, { -1.5, 0, 0, 0 } }, + { "Ycenter", 1, -1, { .005, 0, 0, 0 } }, + { "InnerColor", 3, -1, { 1, 0, 0, 0 } }, + { "OuterColor1", 3, -1, { 0, 1, 0, 0 } }, + { "OuterColor2", 3, -1, { 0, 0, 1, 0 } }, + { NULL, 0, 0, { 0, 0, 0, 0 } } +}; + +static GLint win = 0; + +static GLfloat xRot = 0.0f, yRot = 0.0f, zRot = 0.0f; + +static GLint uZoom, uXcenter, uYcenter; +static GLfloat zoom = 1.0, xCenter = -1.5, yCenter = 0.0; + + +static void +Redisplay(void) +{ + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + /* set interactive uniform parameters */ + glUniform1fv_func(uZoom, 1, &zoom); + glUniform1fv_func(uXcenter, 1, &xCenter); + glUniform1fv_func(uYcenter, 1, &yCenter); + + glPushMatrix(); + glRotatef(xRot, 1.0f, 0.0f, 0.0f); + glRotatef(yRot, 0.0f, 1.0f, 0.0f); + glRotatef(zRot, 0.0f, 0.0f, 1.0f); + + glBegin(GL_POLYGON); + glTexCoord2f(0, 0); glVertex2f(-1, -1); + glTexCoord2f(1, 0); glVertex2f( 1, -1); + glTexCoord2f(1, 1); glVertex2f( 1, 1); + glTexCoord2f(0, 1); glVertex2f(-1, 1); + glEnd(); + + glPopMatrix(); + + glFinish(); + glFlush(); + glutSwapBuffers(); +} + + +static void +Reshape(int width, int height) +{ + glViewport(0, 0, width, height); + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + glFrustum(-1.0, 1.0, -1.0, 1.0, 5.0, 25.0); + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); + glTranslatef(0.0f, 0.0f, -6.0f); +} + + +static void +CleanUp(void) +{ + glDeleteShader_func(fragShader); + glDeleteShader_func(vertShader); + glDeleteProgram_func(program); + glutDestroyWindow(win); +} + + +static void +Key(unsigned char key, int x, int y) +{ + (void) x; + (void) y; + + switch(key) { + case 'z': + zoom *= 0.9; + break; + case 'Z': + zoom /= 0.9; + break; + case 27: + CleanUp(); + exit(0); + break; + } + glutPostRedisplay(); +} + + +static void +SpecialKey(int key, int x, int y) +{ + const GLfloat step = 0.1 * zoom; + + (void) x; + (void) y; + + switch(key) { + case GLUT_KEY_UP: + yCenter += step; + break; + case GLUT_KEY_DOWN: + yCenter -= step; + break; + case GLUT_KEY_LEFT: + xCenter -= step; + break; + case GLUT_KEY_RIGHT: + xCenter += step; + break; + } + glutPostRedisplay(); +} + + + +static void +LoadAndCompileShader(GLuint shader, const char *text) +{ + GLint stat; + + glShaderSource_func(shader, 1, (const GLchar **) &text, NULL); + + glCompileShader_func(shader); + + glGetShaderiv_func(shader, GL_COMPILE_STATUS, &stat); + if (!stat) { + GLchar log[1000]; + GLsizei len; + glGetShaderInfoLog_func(shader, 1000, &len, log); + fprintf(stderr, "brick: problem compiling shader: %s\n", 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, "brick: Unable to open shader file %s\n", filename); + exit(1); + } + + n = fread(buffer, 1, max, f); + printf("brick: read %d bytes from shader file %s\n", n, filename); + if (n > 0) { + buffer[n] = 0; + LoadAndCompileShader(shader, buffer); + } + + fclose(f); + free(buffer); +} + + +static void +CheckLink(GLuint prog) +{ + GLint stat; + glGetProgramiv_func(prog, GL_LINK_STATUS, &stat); + if (!stat) { + GLchar log[1000]; + GLsizei len; + glGetProgramInfoLog_func(prog, 1000, &len, log); + fprintf(stderr, "Linker error:\n%s\n", log); + } + else { + fprintf(stderr, "Link success!\n"); + } +} + + +static void +Init(void) +{ + const char *version; + GLint i; + + version = (const char *) glGetString(GL_VERSION); + if (version[0] != '2' || version[1] != '.') { + printf("Warning: this program expects OpenGL 2.0\n"); + /*exit(1);*/ + } + + GetExtensionFuncs(); + + vertShader = glCreateShader_func(GL_VERTEX_SHADER); + ReadShader(vertShader, VertProgFile); + + fragShader = glCreateShader_func(GL_FRAGMENT_SHADER); + ReadShader(fragShader, FragProgFile); + + program = glCreateProgram_func(); + glAttachShader_func(program, fragShader); + glAttachShader_func(program, vertShader); + glLinkProgram_func(program); + CheckLink(program); + glUseProgram_func(program); + + for (i = 0; Uniforms[i].name; i++) { + Uniforms[i].location + = glGetUniformLocation_func(program, Uniforms[i].name); + printf("Uniform %s location: %d\n", Uniforms[i].name, + Uniforms[i].location); + switch (Uniforms[i].size) { + case 1: + glUniform1fv_func(Uniforms[i].location, 1, Uniforms[i].value); + break; + case 2: + glUniform2fv_func(Uniforms[i].location, 1, Uniforms[i].value); + break; + case 3: + glUniform3fv_func(Uniforms[i].location, 1, Uniforms[i].value); + break; + case 4: + glUniform4fv_func(Uniforms[i].location, 1, Uniforms[i].value); + break; + default: + abort(); + } + } + + uZoom = glGetUniformLocation_func(program, "Zoom"); + uXcenter = glGetUniformLocation_func(program, "Xcenter"); + uYcenter = glGetUniformLocation_func(program, "Ycenter"); + + assert(glGetError() == 0); + + glClearColor(0.4f, 0.4f, 0.8f, 0.0f); + + printf("GL_RENDERER = %s\n",(const char *) glGetString(GL_RENDERER)); + + assert(glIsProgram_func(program)); + assert(glIsShader_func(fragShader)); + assert(glIsShader_func(vertShader)); + + glColor3f(1, 0, 0); +} + + +static void +ParseOptions(int argc, char *argv[]) +{ + int i; + for (i = 1; i < argc; i++) { + if (strcmp(argv[i], "-fs") == 0) { + FragProgFile = argv[i+1]; + } + else if (strcmp(argv[i], "-vs") == 0) { + VertProgFile = argv[i+1]; + } + } +} + + +int +main(int argc, char *argv[]) +{ + glutInit(&argc, argv); + glutInitWindowPosition( 0, 0); + glutInitWindowSize(400, 400); + glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH); + win = glutCreateWindow(argv[0]); + glutReshapeFunc(Reshape); + glutKeyboardFunc(Key); + glutSpecialFunc(SpecialKey); + glutDisplayFunc(Redisplay); + ParseOptions(argc, argv); + Init(); + glutMainLoop(); + return 0; +} + diff --git a/progs/glsl/noise.c b/progs/glsl/noise.c new file mode 100644 index 0000000000..a26a805944 --- /dev/null +++ b/progs/glsl/noise.c @@ -0,0 +1,297 @@ +/** + * Test noise() functions. + * 28 Jan 2007 + */ + +#include <assert.h> +#include <string.h> +#include <stdio.h> +#include <stdlib.h> +#include <math.h> +#include <GL/gl.h> +#include <GL/glut.h> +#include <GL/glext.h> +#include "extfuncs.h" + + +static const char *VertShaderText = + "void main() {\n" + " gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;\n" + " gl_TexCoord[0] = gl_MultiTexCoord0;\n" + "}\n"; + +static const char *FragShaderText = + "uniform vec4 Scale, Bias;\n" + "uniform float Slice;\n" + "void main()\n" + "{\n" + " vec4 scale = vec4(5.0);\n" + " vec4 p;\n" + " p.xy = gl_TexCoord[0].xy;\n" + " p.z = Slice;\n" + " vec4 n = noise4(p * scale);\n" + " gl_FragColor = n * Scale + Bias;\n" + "}\n"; + + +struct uniform_info { + const char *name; + GLuint size; + GLint location; + GLfloat value[4]; +}; + +static struct uniform_info Uniforms[] = { + { "Scale", 4, -1, { 0.5, 0.4, 0.0, 0} }, + { "Bias", 4, -1, { 0.5, 0.3, 0.0, 0} }, + { "Slice", 1, -1, { 0.5, 0, 0, 0} }, + { NULL, 0, 0, { 0, 0, 0, 0 } } +}; + +/* program/shader objects */ +static GLuint fragShader; +static GLuint vertShader; +static GLuint program; + +static GLint win = 0; +static GLfloat xRot = 0.0f, yRot = 0.0f, zRot = 0.0f; +static GLfloat Slice = 0.0; +static GLboolean Anim = GL_FALSE; + + +static void +Idle(void) +{ + Slice += 0.01; + glutPostRedisplay(); +} + + +static void +Redisplay(void) +{ + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + glUniform1fv_func(Uniforms[2].location, 1, &Slice); + + glPushMatrix(); + glRotatef(xRot, 1.0f, 0.0f, 0.0f); + glRotatef(yRot, 0.0f, 1.0f, 0.0f); + glRotatef(zRot, 0.0f, 0.0f, 1.0f); + + glBegin(GL_POLYGON); + glTexCoord2f(0, 0); glVertex2f(-2, -2); + glTexCoord2f(1, 0); glVertex2f( 2, -2); + glTexCoord2f(1, 1); glVertex2f( 2, 2); + glTexCoord2f(0, 1); glVertex2f(-2, 2); + glEnd(); + + glPopMatrix(); + + glutSwapBuffers(); +} + + +static void +Reshape(int width, int height) +{ + glViewport(0, 0, width, height); + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + glFrustum(-1.0, 1.0, -1.0, 1.0, 5.0, 25.0); + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); + glTranslatef(0.0f, 0.0f, -15.0f); +} + + +static void +CleanUp(void) +{ + glDeleteShader_func(fragShader); + glDeleteShader_func(vertShader); + glDeleteProgram_func(program); + glutDestroyWindow(win); +} + + +static void +Key(unsigned char key, int x, int y) +{ + const GLfloat step = 0.01; + (void) x; + (void) y; + + switch(key) { + case 'a': + Anim = !Anim; + glutIdleFunc(Anim ? Idle : NULL); + case 's': + Slice -= step; + break; + case 'S': + Slice += step; + break; + case 'z': + zRot -= 1.0; + break; + case 'Z': + zRot += 1.0; + break; + case 27: + CleanUp(); + exit(0); + break; + } + glutPostRedisplay(); +} + + +static void +SpecialKey(int key, int x, int y) +{ + const GLfloat step = 3.0f; + + (void) x; + (void) y; + + switch(key) { + case GLUT_KEY_UP: + xRot -= step; + break; + case GLUT_KEY_DOWN: + xRot += step; + break; + case GLUT_KEY_LEFT: + yRot -= step; + break; + case GLUT_KEY_RIGHT: + yRot += step; + break; + } + glutPostRedisplay(); +} + + + +static void +LoadAndCompileShader(GLuint shader, const char *text) +{ + GLint stat; + + glShaderSource_func(shader, 1, (const GLchar **) &text, NULL); + + glCompileShader_func(shader); + + glGetShaderiv_func(shader, GL_COMPILE_STATUS, &stat); + if (!stat) { + GLchar log[1000]; + GLsizei len; + glGetShaderInfoLog_func(shader, 1000, &len, log); + fprintf(stderr, "brick: problem compiling shader: %s\n", log); + exit(1); + } + else { + printf("Shader compiled OK\n"); + } +} + + +static void +CheckLink(GLuint prog) +{ + GLint stat; + glGetProgramiv_func(prog, GL_LINK_STATUS, &stat); + if (!stat) { + GLchar log[1000]; + GLsizei len; + glGetProgramInfoLog_func(prog, 1000, &len, log); + fprintf(stderr, "Linker error:\n%s\n", log); + } + else { + fprintf(stderr, "Link success!\n"); + } +} + + +static void +Init(void) +{ + const char *version; + GLint i; + + version = (const char *) glGetString(GL_VERSION); + if (version[0] != '2' || version[1] != '.') { + printf("Warning: this program expects OpenGL 2.0\n"); + /*exit(1);*/ + } + + GetExtensionFuncs(); + + vertShader = glCreateShader_func(GL_VERTEX_SHADER); + LoadAndCompileShader(vertShader, VertShaderText); + + fragShader = glCreateShader_func(GL_FRAGMENT_SHADER); + LoadAndCompileShader(fragShader, FragShaderText); + + program = glCreateProgram_func(); + glAttachShader_func(program, fragShader); + glAttachShader_func(program, vertShader); + glLinkProgram_func(program); + CheckLink(program); + glUseProgram_func(program); + + for (i = 0; Uniforms[i].name; i++) { + Uniforms[i].location + = glGetUniformLocation_func(program, Uniforms[i].name); + printf("Uniform %s location: %d\n", Uniforms[i].name, + Uniforms[i].location); + switch (Uniforms[i].size) { + case 1: + glUniform1fv_func(Uniforms[i].location, 1, Uniforms[i].value); + break; + case 2: + glUniform2fv_func(Uniforms[i].location, 1, Uniforms[i].value); + break; + case 3: + glUniform3fv_func(Uniforms[i].location, 1, Uniforms[i].value); + break; + case 4: + glUniform4fv_func(Uniforms[i].location, 1, Uniforms[i].value); + break; + default: + abort(); + } + } + + assert(glGetError() == 0); + + glClearColor(0.4f, 0.4f, 0.8f, 0.0f); + + printf("GL_RENDERER = %s\n",(const char *) glGetString(GL_RENDERER)); + + assert(glIsProgram_func(program)); + assert(glIsShader_func(fragShader)); + assert(glIsShader_func(vertShader)); + + glColor3f(1, 0, 0); +} + + +int +main(int argc, char *argv[]) +{ + glutInit(&argc, argv); + glutInitWindowPosition( 0, 0); + glutInitWindowSize(400, 400); + glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH); + win = glutCreateWindow(argv[0]); + glutReshapeFunc(Reshape); + glutKeyboardFunc(Key); + glutSpecialFunc(SpecialKey); + glutDisplayFunc(Redisplay); + Init(); + glutMainLoop(); + return 0; +} + diff --git a/progs/glsl/reflect.vert.txt b/progs/glsl/reflect.vert.txt new file mode 100644 index 0000000000..402be38bf7 --- /dev/null +++ b/progs/glsl/reflect.vert.txt @@ -0,0 +1,19 @@ +// Vertex shader for cube-texture reflection mapping +// Brian Paul + + +varying vec3 normal; + +void main() +{ + vec3 n = gl_NormalMatrix * gl_Normal; + vec3 u = normalize(vec3(gl_ModelViewMatrix * gl_Vertex)); + float two_n_dot_u = 2.0 * dot(n, u); + vec4 f; + f.xyz = u - n * two_n_dot_u; + + // outputs + normal = n; + gl_TexCoord[0] = gl_TextureMatrix[0] * f; + gl_Position = ftransform(); +} diff --git a/progs/glsl/shadowtex.frag.txt b/progs/glsl/shadowtex.frag.txt new file mode 100644 index 0000000000..a6a80da47f --- /dev/null +++ b/progs/glsl/shadowtex.frag.txt @@ -0,0 +1,21 @@ +// Fragment shader for 2D texture with shadow attenuation +// Brian Paul + + +uniform sampler2D tex2d; +uniform vec3 lightPos; + +void main() +{ + // XXX should compute this from lightPos + vec2 shadowCenter = vec2(-0.25, -0.25); + + // d = distance from center + float d = distance(gl_TexCoord[0].xy, shadowCenter); + + // attenuate and clamp + d = clamp(d * d * d, 0.0, 2.0); + + // modulate texture by d for shadow effect + gl_FragColor = d * texture2D(tex2d, gl_TexCoord[0].xy, 0.0); +} diff --git a/progs/glsl/simple.vert.txt b/progs/glsl/simple.vert.txt new file mode 100644 index 0000000000..a0abe0dc0b --- /dev/null +++ b/progs/glsl/simple.vert.txt @@ -0,0 +1,9 @@ +// Simple vertex shader +// Brian Paul + + +void main() +{ + gl_TexCoord[0] = gl_MultiTexCoord0; + gl_Position = ftransform(); +} diff --git a/progs/glsl/texdemo1.c b/progs/glsl/texdemo1.c new file mode 100644 index 0000000000..d29ecf452b --- /dev/null +++ b/progs/glsl/texdemo1.c @@ -0,0 +1,570 @@ +/** + * Test texturing with GL shading language. + * + * 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"), + * 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 <assert.h> +#include <math.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include "GL/glut.h" +#include "readtex.h" +#include "extfuncs.h" + +static const char *Demo = "texdemo1"; + +static const char *ReflectVertFile = "reflect.vert.txt"; +static const char *CubeFragFile = "cubemap.frag.txt"; + +static const char *SimpleVertFile = "simple.vert.txt"; +static const char *SimpleTexFragFile = "shadowtex.frag.txt"; + +static const char *GroundImage = "../images/tile.rgb"; + +static GLuint Program1, Program2; + +static GLfloat TexXrot = 0, TexYrot = 0; +static GLfloat Xrot = 20.0, Yrot = 20.0, Zrot = 0.0; +static GLfloat EyeDist = 10; +static GLboolean Anim = GL_TRUE; + + +struct uniform_info { + const char *name; + GLuint size; + GLint location; + GLenum type; /**< GL_FLOAT or GL_INT */ + GLfloat value[4]; +}; + +static struct uniform_info ReflectUniforms[] = { + { "cubeTex", 1, -1, GL_INT, { 0, 0, 0, 0 } }, + { "lightPos", 3, -1, GL_FLOAT, { 10, 10, 20, 0 } }, + { NULL, 0, 0, 0, { 0, 0, 0, 0 } } +}; + +static struct uniform_info SimpleUniforms[] = { + { "tex2d", 1, -1, GL_INT, { 1, 0, 0, 0 } }, + { "lightPos", 3, -1, GL_FLOAT, { 10, 10, 20, 0 } }, + { NULL, 0, 0, 0, { 0, 0, 0, 0 } } +}; + + +static void +CheckError(int line) +{ + GLenum err = glGetError(); + if (err) { + printf("GL Error %s (0x%x) at line %d\n", + gluErrorString(err), (int) err, line); + } +} + + +static void +DrawGround(GLfloat size) +{ + glPushMatrix(); + glRotatef(90, 1, 0, 0); + glNormal3f(0, 0, 1); + glBegin(GL_POLYGON); + glTexCoord2f(-2, -2); glVertex2f(-size, -size); + glTexCoord2f( 2, -2); glVertex2f( size, -size); + glTexCoord2f( 2, 2); glVertex2f( size, size); + glTexCoord2f(-2, 2); glVertex2f(-size, size); + glEnd(); + glPopMatrix(); +} + + +static void +draw(void) +{ + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + glEnable(GL_TEXTURE_2D); + + glPushMatrix(); /* modelview matrix */ + glTranslatef(0.0, 0.0, -EyeDist); + glRotatef(Xrot, 1, 0, 0); + glRotatef(Yrot, 0, 1, 0); + glRotatef(Zrot, 0, 0, 1); + + /* sphere w/ reflection map */ + glPushMatrix(); + glTranslatef(0, 1, 0); + glUseProgram_func(Program1); + + /* setup texture matrix */ + glActiveTexture(GL_TEXTURE0); + glMatrixMode(GL_TEXTURE); + glLoadIdentity(); + glRotatef(-TexYrot, 0, 1, 0); + glRotatef(-TexXrot, 1, 0, 0); + + glEnable(GL_TEXTURE_GEN_S); + glEnable(GL_TEXTURE_GEN_T); + glEnable(GL_TEXTURE_GEN_R); + glutSolidSphere(2.0, 20, 20); + + glLoadIdentity(); /* texture matrix */ + glMatrixMode(GL_MODELVIEW); + glPopMatrix(); + + /* ground */ + glUseProgram_func(Program2); + glTranslatef(0, -1.0, 0); + DrawGround(5); + + glPopMatrix(); + + glutSwapBuffers(); +} + + +static void +idle(void) +{ + GLfloat t = 0.05 * glutGet(GLUT_ELAPSED_TIME); + TexYrot = t; + glutPostRedisplay(); +} + + +static void +key(unsigned char k, int x, int y) +{ + (void) x; + (void) y; + switch (k) { + case ' ': + case 'a': + Anim = !Anim; + if (Anim) + glutIdleFunc(idle); + else + glutIdleFunc(NULL); + break; + case 'z': + EyeDist -= 0.5; + if (EyeDist < 6.0) + EyeDist = 6.0; + break; + case 'Z': + EyeDist += 0.5; + if (EyeDist > 90.0) + EyeDist = 90; + break; + case 27: + exit(0); + } + glutPostRedisplay(); +} + + +static void +specialkey(int key, int x, int y) +{ + GLfloat step = 2.0; + (void) x; + (void) y; + switch (key) { + case GLUT_KEY_UP: + Xrot += step; + break; + case GLUT_KEY_DOWN: + Xrot -= step; + break; + case GLUT_KEY_LEFT: + Yrot -= step; + break; + case GLUT_KEY_RIGHT: + Yrot += step; + break; + } + glutPostRedisplay(); +} + + +/* new window size or exposure */ +static void +Reshape(int width, int height) +{ + GLfloat ar = (float) width / (float) height; + glViewport(0, 0, (GLint)width, (GLint)height); + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + glFrustum(-2.0*ar, 2.0*ar, -2.0, 2.0, 4.0, 100.0); + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); +} + + +static void +InitCheckers(void) +{ +#define CUBE_TEX_SIZE 64 + GLubyte image[CUBE_TEX_SIZE][CUBE_TEX_SIZE][3]; + static const GLubyte colors[6][3] = { + { 255, 0, 0 }, /* face 0 - red */ + { 0, 255, 255 }, /* face 1 - cyan */ + { 0, 255, 0 }, /* face 2 - green */ + { 255, 0, 255 }, /* face 3 - purple */ + { 0, 0, 255 }, /* face 4 - blue */ + { 255, 255, 0 } /* face 5 - yellow */ + }; + static const GLenum targets[6] = { + GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB, + GL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB, + GL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB, + GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB, + GL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB, + GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB + }; + + GLint i, j, f; + + glPixelStorei(GL_UNPACK_ALIGNMENT, 1); + + /* make colored checkerboard cube faces */ + for (f = 0; f < 6; f++) { + for (i = 0; i < CUBE_TEX_SIZE; i++) { + for (j = 0; j < CUBE_TEX_SIZE; j++) { + if ((i/4 + j/4) & 1) { + image[i][j][0] = colors[f][0]; + image[i][j][1] = colors[f][1]; + image[i][j][2] = colors[f][2]; + } + else { + image[i][j][0] = 255; + image[i][j][1] = 255; + image[i][j][2] = 255; + } + } + } + + glTexImage2D(targets[f], 0, GL_RGB, CUBE_TEX_SIZE, CUBE_TEX_SIZE, 0, + GL_RGB, GL_UNSIGNED_BYTE, image); + } +} + + +static void +LoadFace(GLenum target, const char *filename, + GLboolean flipTB, GLboolean flipLR) +{ + GLint w, h; + GLenum format; + GLubyte *img = LoadRGBImage(filename, &w, &h, &format); + if (!img) { + printf("Error: couldn't load texture image %s\n", filename); + exit(1); + } + assert(format == GL_RGB); + + /* <sigh> the way the texture cube mapping works, we have to flip + * images to make things look right. + */ + if (flipTB) { + const int stride = 3 * w; + GLubyte temp[3*1024]; + int i; + for (i = 0; i < h / 2; i++) { + memcpy(temp, img + i * stride, stride); + memcpy(img + i * stride, img + (h - i - 1) * stride, stride); + memcpy(img + (h - i - 1) * stride, temp, stride); + } + } + if (flipLR) { + const int stride = 3 * w; + GLubyte temp[3]; + GLubyte *row; + int i, j; + for (i = 0; i < h; i++) { + row = img + i * stride; + for (j = 0; j < w / 2; j++) { + int k = w - j - 1; + temp[0] = row[j*3+0]; + temp[1] = row[j*3+1]; + temp[2] = row[j*3+2]; + row[j*3+0] = row[k*3+0]; + row[j*3+1] = row[k*3+1]; + row[j*3+2] = row[k*3+2]; + row[k*3+0] = temp[0]; + row[k*3+1] = temp[1]; + row[k*3+2] = temp[2]; + } + } + } + + gluBuild2DMipmaps(target, GL_RGB, w, h, format, GL_UNSIGNED_BYTE, img); + free(img); +} + + +static void +LoadEnvmaps(void) +{ + LoadFace(GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB, "right.rgb", GL_TRUE, GL_FALSE); + LoadFace(GL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB, "left.rgb", GL_TRUE, GL_FALSE); + LoadFace(GL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB, "top.rgb", GL_FALSE, GL_TRUE); + LoadFace(GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB, "bottom.rgb", GL_FALSE, GL_TRUE); + LoadFace(GL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB, "front.rgb", GL_TRUE, GL_FALSE); + LoadFace(GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB, "back.rgb", GL_TRUE, GL_FALSE); +} + + +static void +InitTextures(GLboolean useImageFiles) +{ + GLenum filter; + + /* + * Env map + */ + glActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_CUBE_MAP, 1); + if (useImageFiles) { + LoadEnvmaps(); + filter = GL_LINEAR; + } + else { + InitCheckers(); + filter = GL_NEAREST; + } + glTexParameteri(GL_TEXTURE_CUBE_MAP_ARB, GL_TEXTURE_MIN_FILTER, filter); + glTexParameteri(GL_TEXTURE_CUBE_MAP_ARB, GL_TEXTURE_MAG_FILTER, filter); + glTexParameteri(GL_TEXTURE_CUBE_MAP_ARB, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_CUBE_MAP_ARB, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + + /* + * Ground texture + */ + { + GLint imgWidth, imgHeight; + GLenum imgFormat; + GLubyte *image = NULL; + + image = LoadRGBImage(GroundImage, &imgWidth, &imgHeight, &imgFormat); + if (!image) { + printf("Couldn't read %s\n", GroundImage); + exit(0); + } + + glActiveTexture(GL_TEXTURE1); + glBindTexture(GL_TEXTURE_2D, 2); + gluBuild2DMipmaps(GL_TEXTURE_2D, 3, imgWidth, imgHeight, + imgFormat, GL_UNSIGNED_BYTE, image); + free(image); + + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + } +} + + +static void +LoadAndCompileShader(GLuint shader, const char *text) +{ + GLint stat; + + glShaderSource_func(shader, 1, (const GLchar **) &text, NULL); + + glCompileShader_func(shader); + + glGetShaderiv_func(shader, GL_COMPILE_STATUS, &stat); + if (!stat) { + GLchar log[1000]; + GLsizei len; + glGetShaderInfoLog_func(shader, 1000, &len, log); + fprintf(stderr, "%s: problem compiling shader: %s\n", Demo, 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", Demo, filename); + exit(1); + } + + n = fread(buffer, 1, max, f); + printf("%s: read %d bytes from shader file %s\n", Demo, n, filename); + if (n > 0) { + buffer[n] = 0; + LoadAndCompileShader(shader, buffer); + } + + fclose(f); + free(buffer); +} + + +static void +CheckLink(GLuint prog) +{ + GLint stat; + glGetProgramiv_func(prog, GL_LINK_STATUS, &stat); + if (!stat) { + GLchar log[1000]; + GLsizei len; + glGetProgramInfoLog_func(prog, 1000, &len, log); + fprintf(stderr, "Linker error:\n%s\n", log); + } + else { + fprintf(stderr, "Link success!\n"); + } +} + + +static GLuint +CreateProgram(const char *vertProgFile, const char *fragProgFile, + struct uniform_info *uniforms) +{ + GLuint fragShader = 0, vertShader = 0, program = 0; + GLint i; + + program = glCreateProgram_func(); + if (vertProgFile) { + vertShader = glCreateShader_func(GL_VERTEX_SHADER); + ReadShader(vertShader, vertProgFile); + glAttachShader_func(program, vertShader); + } + + if (fragProgFile) { + fragShader = glCreateShader_func(GL_FRAGMENT_SHADER); + ReadShader(fragShader, fragProgFile); + glAttachShader_func(program, fragShader); + } + + glLinkProgram_func(program); + CheckLink(program); + + glUseProgram_func(program); + + assert(glIsProgram_func(program)); + assert(glIsShader_func(fragShader)); + assert(glIsShader_func(vertShader)); + + CheckError(__LINE__); + for (i = 0; uniforms[i].name; i++) { + uniforms[i].location + = glGetUniformLocation_func(program, uniforms[i].name); + printf("Uniform %s location: %d\n", uniforms[i].name, + uniforms[i].location); + + switch (uniforms[i].size) { + case 1: + if (uniforms[i].type == GL_INT) + glUniform1i_func(uniforms[i].location, + (GLint) uniforms[i].value[0]); + else + glUniform1fv_func(uniforms[i].location, 1, uniforms[i].value); + break; + case 2: + glUniform2fv_func(uniforms[i].location, 1, uniforms[i].value); + break; + case 3: + glUniform3fv_func(uniforms[i].location, 1, uniforms[i].value); + break; + case 4: + glUniform4fv_func(uniforms[i].location, 1, uniforms[i].value); + break; + default: + abort(); + } + } + + CheckError(__LINE__); + + return program; +} + + +static void +InitPrograms(void) +{ + Program1 = CreateProgram(ReflectVertFile, CubeFragFile, ReflectUniforms); + Program2 = CreateProgram(SimpleVertFile, SimpleTexFragFile, SimpleUniforms); +} + + +static void +Init(GLboolean useImageFiles) +{ + const char *version = (const char *) glGetString(GL_VERSION); + + if (version[0] != '2' || version[1] != '.') { + printf("Warning: this program expects OpenGL 2.0\n"); + /*exit(1);*/ + } + printf("GL_RENDERER = %s\n",(const char *) glGetString(GL_RENDERER)); + + GetExtensionFuncs(); + + InitTextures(useImageFiles); + InitPrograms(); + + glEnable(GL_DEPTH_TEST); + + glClearColor(.6, .6, .9, 0); + glColor3f(1.0, 1.0, 1.0); +} + + +int +main(int argc, char *argv[]) +{ + glutInit(&argc, argv); + glutInitWindowSize(500, 400); + glutInitDisplayMode(GLUT_RGB | GLUT_DEPTH | GLUT_DOUBLE); + glutCreateWindow(Demo); + glutReshapeFunc(Reshape); + glutKeyboardFunc(key); + glutSpecialFunc(specialkey); + glutDisplayFunc(draw); + if (Anim) + glutIdleFunc(idle); + if (argc > 1 && strcmp(argv[1] , "-i") == 0) + Init(1); + else + Init(0); + glutMainLoop(); + return 0; +} diff --git a/progs/glsl/toyball.c b/progs/glsl/toyball.c new file mode 100644 index 0000000000..cef52c04a6 --- /dev/null +++ b/progs/glsl/toyball.c @@ -0,0 +1,339 @@ +/** + * "Toy Ball" shader demo. Uses the example shaders from + * chapter 11 of the OpenGL Shading Language "orange" book. + * 16 Jan 2007 + */ + +#include <assert.h> +#include <string.h> +#include <stdio.h> +#include <stdlib.h> +#include <math.h> +#include <GL/gl.h> +#include <GL/glut.h> +#include <GL/glext.h> +#include "extfuncs.h" + + +static char *FragProgFile = "CH11-toyball.frag.txt"; +static char *VertProgFile = "CH11-toyball.vert.txt"; + +/* program/shader objects */ +static GLuint fragShader; +static GLuint vertShader; +static GLuint program; + + +struct uniform_info { + const char *name; + GLuint size; + GLint location; + GLfloat value[4]; +}; + +static struct uniform_info Uniforms[] = { + { "LightDir", 4, -1, { 0.57737, 0.57735, 0.57735, 0.0 } }, + { "HVector", 4, -1, { 0.32506, 0.32506, 0.88808, 0.0 } }, + { "BallCenter", 4, -1, { 0.0, 0.0, 0.0, 1.0 } }, + { "SpecularColor", 4, -1, { 0.4, 0.4, 0.4, 60.0 } }, + { "Red", 4, -1, { 0.6, 0.0, 0.0, 1.0 } }, + { "Blue", 4, -1, { 0.0, 0.3, 0.6, 1.0 } }, + { "Yellow", 4, -1, { 0.6, 0.5, 0.0, 1.0 } }, + { "HalfSpace0", 4, -1, { 1.0, 0.0, 0.0, 0.2 } }, + { "HalfSpace1", 4, -1, { 0.309016994, 0.951056516, 0.0, 0.2 } }, + { "HalfSpace2", 4, -1, { -0.809016994, 0.587785252, 0.0, 0.2 } }, + { "HalfSpace3", 4, -1, { -0.809016994, -0.587785252, 0.0, 0.2 } }, + { "HalfSpace4", 4, -1, { 0.309116994, -0.951056516, 0.0, 0.2 } }, + { "InOrOutInit", 1, -1, { -3.0, 0, 0, 0 } }, + { "StripeWidth", 1, -1, { 0.3, 0, 0, 0 } }, + { "FWidth", 1, -1, { 0.005, 0, 0, 0 } }, + { NULL, 0, 0, { 0, 0, 0, 0 } } +}; + +static GLint win = 0; +static GLboolean Anim = GL_FALSE; +static GLfloat TexRot = 0.0; +static GLfloat xRot = 0.0f, yRot = 0.0f, zRot = 0.0f; + + +static void +Idle(void) +{ + TexRot += 2.0; + if (TexRot > 360.0) + TexRot -= 360.0; + glutPostRedisplay(); +} + + +static void +Redisplay(void) +{ + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + glPushMatrix(); + glRotatef(xRot, 1.0f, 0.0f, 0.0f); + glRotatef(yRot, 0.0f, 1.0f, 0.0f); + glRotatef(zRot, 0.0f, 0.0f, 1.0f); + + glMatrixMode(GL_TEXTURE); + glLoadIdentity(); + glRotatef(TexRot, 0.0f, 1.0f, 0.0f); + glMatrixMode(GL_MODELVIEW); + + glutSolidSphere(2.0, 20, 10); + + glPopMatrix(); + + glFinish(); + glFlush(); + glutSwapBuffers(); +} + + +static void +Reshape(int width, int height) +{ + glViewport(0, 0, width, height); + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + glFrustum(-1.0, 1.0, -1.0, 1.0, 5.0, 25.0); + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); + glTranslatef(0.0f, 0.0f, -15.0f); +} + + +static void +CleanUp(void) +{ + glDeleteShader_func(fragShader); + glDeleteShader_func(vertShader); + glDeleteProgram_func(program); + glutDestroyWindow(win); +} + + +static void +Key(unsigned char key, int x, int y) +{ + const GLfloat step = 2.0; + (void) x; + (void) y; + + switch(key) { + case 'a': + Anim = !Anim; + if (Anim) + glutIdleFunc(Idle); + else + glutIdleFunc(NULL); + break; + case 'z': + zRot += step; + break; + case 'Z': + zRot -= step; + break; + case 27: + CleanUp(); + exit(0); + break; + } + glutPostRedisplay(); +} + + +static void +SpecialKey(int key, int x, int y) +{ + const GLfloat step = 2.0; + + (void) x; + (void) y; + + switch(key) { + case GLUT_KEY_UP: + xRot += step; + break; + case GLUT_KEY_DOWN: + xRot -= step; + break; + case GLUT_KEY_LEFT: + yRot -= step; + break; + case GLUT_KEY_RIGHT: + yRot += step; + break; + } + glutPostRedisplay(); +} + + + +static void +LoadAndCompileShader(GLuint shader, const char *text) +{ + GLint stat; + + glShaderSource_func(shader, 1, (const GLchar **) &text, NULL); + + glCompileShader_func(shader); + + glGetShaderiv_func(shader, GL_COMPILE_STATUS, &stat); + if (!stat) { + GLchar log[1000]; + GLsizei len; + glGetShaderInfoLog_func(shader, 1000, &len, log); + fprintf(stderr, "brick: problem compiling shader: %s\n", 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, "brick: Unable to open shader file %s\n", filename); + exit(1); + } + + n = fread(buffer, 1, max, f); + printf("brick: read %d bytes from shader file %s\n", n, filename); + if (n > 0) { + buffer[n] = 0; + LoadAndCompileShader(shader, buffer); + } + + fclose(f); + free(buffer); +} + + +static void +CheckLink(GLuint prog) +{ + GLint stat; + glGetProgramiv_func(prog, GL_LINK_STATUS, &stat); + if (!stat) { + GLchar log[1000]; + GLsizei len; + glGetProgramInfoLog_func(prog, 1000, &len, log); + fprintf(stderr, "Linker error:\n%s\n", log); + } + else { + fprintf(stderr, "Link success!\n"); + } +} + + +static void +Init(void) +{ + const char *version; + GLint i; + + version = (const char *) glGetString(GL_VERSION); + if (version[0] != '2' || version[1] != '.') { + printf("Warning: this program expects OpenGL 2.0\n"); + /*exit(1);*/ + } + printf("GL_RENDERER = %s\n",(const char *) glGetString(GL_RENDERER)); + + GetExtensionFuncs(); + + vertShader = glCreateShader_func(GL_VERTEX_SHADER); + ReadShader(vertShader, VertProgFile); + + fragShader = glCreateShader_func(GL_FRAGMENT_SHADER); + ReadShader(fragShader, FragProgFile); + + program = glCreateProgram_func(); + glAttachShader_func(program, fragShader); + glAttachShader_func(program, vertShader); + glLinkProgram_func(program); + CheckLink(program); + glUseProgram_func(program); + + assert(glIsProgram_func(program)); + assert(glIsShader_func(fragShader)); + assert(glIsShader_func(vertShader)); + + + for (i = 0; Uniforms[i].name; i++) { + Uniforms[i].location + = glGetUniformLocation_func(program, Uniforms[i].name); + printf("Uniform %s location: %d\n", Uniforms[i].name, + Uniforms[i].location); + switch (Uniforms[i].size) { + case 1: + glUniform1fv_func(Uniforms[i].location, 1, Uniforms[i].value); + break; + case 2: + glUniform2fv_func(Uniforms[i].location, 1, Uniforms[i].value); + break; + case 3: + glUniform3fv_func(Uniforms[i].location, 1, Uniforms[i].value); + break; + case 4: + glUniform4fv_func(Uniforms[i].location, 1, Uniforms[i].value); + break; + default: + abort(); + } + } + + assert(glGetError() == 0); + + glClearColor(0.4f, 0.4f, 0.8f, 0.0f); + + glEnable(GL_DEPTH_TEST); + + glColor3f(1, 0, 0); +} + + +static void +ParseOptions(int argc, char *argv[]) +{ + int i; + for (i = 1; i < argc; i++) { + if (strcmp(argv[i], "-fs") == 0) { + FragProgFile = argv[i+1]; + } + else if (strcmp(argv[i], "-vs") == 0) { + VertProgFile = argv[i+1]; + } + } +} + + +int +main(int argc, char *argv[]) +{ + glutInit(&argc, argv); + glutInitWindowPosition( 0, 0); + glutInitWindowSize(400, 400); + glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH); + win = glutCreateWindow(argv[0]); + glutReshapeFunc(Reshape); + glutKeyboardFunc(Key); + glutSpecialFunc(SpecialKey); + glutDisplayFunc(Redisplay); + ParseOptions(argc, argv); + Init(); + glutMainLoop(); + return 0; +} + diff --git a/progs/tests/Makefile b/progs/tests/Makefile index 3a22285250..9edef74fb2 100644 --- a/progs/tests/Makefile +++ b/progs/tests/Makefile @@ -33,6 +33,7 @@ SOURCES = \ crossbar.c \ cva.c \ dinoshade.c \ + drawbuffers.c \ floattex.c \ fbotest1.c \ fbotest2.c \ @@ -122,6 +123,12 @@ afsmultiarb: afsmultiarb.o readtex.o afsmultiarb.o: afsmultiarb.c readtex.h $(CC) -c $(INCLUDES) $(CFLAGS) $(DEFINES) $< -o $@ +drawbuffers: drawbuffers.o + $(CC) $(CFLAGS) drawbuffers.o $(LIBS) -o $@ + +drawbuffers.o: drawbuffers.c extfuncs.h + $(CC) -c $(INCLUDES) $(CFLAGS) $(DEFINES) $< -o $@ + texrect: texrect.o readtex.o $(CC) $(CFLAGS) texrect.o readtex.o $(LIBS) -o $@ @@ -150,6 +157,8 @@ readtex.h: $(TOP)/progs/util/readtex.h readtex.c: $(TOP)/progs/util/readtex.c ln -s $(TOP)/progs/util/readtex.c . +extfuncs.h: $(TOP)/progs/util/extfuncs.h + ln -s $(TOP)/progs/util/extfuncs.h . diff --git a/progs/tests/drawbuffers.c b/progs/tests/drawbuffers.c new file mode 100644 index 0000000000..8583bac0dd --- /dev/null +++ b/progs/tests/drawbuffers.c @@ -0,0 +1,298 @@ +/* + * Test GL_ARB_draw_buffers, GL_EXT_framebuffer_object + * and GLSL's gl_FragData[]. + * + * Brian Paul + * 11 March 2007 + */ + + +#define GL_GLEXT_PROTOTYPES +#include <assert.h> +#include <stdio.h> +#include <stdlib.h> +#include <math.h> +#include <GL/glut.h> +#include "extfuncs.h" + +static int Win; +static int Width = 400, Height = 400; +static GLuint FBobject, RBobjects[3]; +static GLfloat Xrot = 0.0, Yrot = 0.0; + + +static void +CheckError(int line) +{ + GLenum err = glGetError(); + if (err) { + printf("GL Error 0x%x at line %d\n", (int) err, line); + } +} + + +static void +Display(void) +{ + GLubyte *buffer = malloc(Width * Height * 4); + static const GLenum buffers[2] = { + GL_COLOR_ATTACHMENT0_EXT, + GL_COLOR_ATTACHMENT1_EXT + }; + + /* draw to user framebuffer */ + glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, FBobject); + + /* Clear color buffer 0 (blue) */ + glDrawBuffer(GL_COLOR_ATTACHMENT0_EXT); + glClearColor(0.5, 0.5, 1.0, 0.0); + glClear(GL_COLOR_BUFFER_BIT); + + /* Clear color buffer 1 (1 - blue) */ + glDrawBuffer(GL_COLOR_ATTACHMENT1_EXT); + glClearColor(0.5, 0.5, 0.0, 0.0); + glClear(GL_COLOR_BUFFER_BIT); + + glClear(GL_DEPTH_BUFFER_BIT); + + /* draw to two buffers w/ fragment shader */ + glDrawBuffersARB(2, buffers); + + glPushMatrix(); + glRotatef(Xrot, 1, 0, 0); + glRotatef(Yrot, 0, 1, 0); + glutSolidTorus(0.75, 2.0, 10, 20); + glPopMatrix(); + + /* read from user framebuffer */ + /* bottom half = colorbuffer 0 */ + glReadBuffer(GL_COLOR_ATTACHMENT0_EXT); + glReadPixels(0, 0, Width, Height / 2, GL_RGBA, GL_UNSIGNED_BYTE, + buffer); + /* top half = colorbuffer 1 */ + glReadBuffer(GL_COLOR_ATTACHMENT1_EXT); + glReadPixels(0, Height/2, Width, Height / 2, GL_RGBA, GL_UNSIGNED_BYTE, + buffer + Width * Height / 2 * 4); + + /* draw to window */ + glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0); + glWindowPos2iARB(0, 0); + glDrawPixels(Width, Height, GL_RGBA, GL_UNSIGNED_BYTE, buffer); + + free(buffer); + glutSwapBuffers(); + CheckError(__LINE__); +} + + +static void +Reshape(int width, int height) +{ + float ar = (float) width / (float) height; + + glViewport(0, 0, width, height); + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + glFrustum(-ar, ar, -1.0, 1.0, 5.0, 35.0); + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); + glTranslatef(0.0, 0.0, -20.0); + + Width = width; + Height = height; + + glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, RBobjects[0]); + glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_RGB, Width, Height); + glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, RBobjects[1]); + glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_RGB, Width, Height); + glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, RBobjects[2]); + glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_DEPTH_COMPONENT, + Width, Height); +} + + +static void +CleanUp(void) +{ + glDeleteFramebuffersEXT(1, &FBobject); + glDeleteRenderbuffersEXT(3, RBobjects); + glutDestroyWindow(Win); + exit(0); +} + + +static void +Key(unsigned char key, int x, int y) +{ + (void) x; + (void) y; + switch (key) { + case 'x': + Xrot += 5.0; + break; + case 'y': + Yrot += 5.0; + break; + case 27: + CleanUp(); + break; + } + glutPostRedisplay(); +} + + +static void +CheckExtensions(void) +{ + const char *version = (const char *) glGetString(GL_VERSION); + GLint numBuf; + + if (!glutExtensionSupported("GL_EXT_framebuffer_object")) { + printf("Sorry, GL_EXT_framebuffer_object is required!\n"); + exit(1); + } + if (!glutExtensionSupported("GL_ARB_draw_buffers")) { + printf("Sorry, GL_ARB_draw_buffers is required!\n"); + exit(1); + } + if (version[0] != '2') { + printf("Sorry, OpenGL 2.0 is required!\n"); + exit(1); + } + + glGetIntegerv(GL_MAX_DRAW_BUFFERS_ARB, &numBuf); + printf("GL_MAX_DRAW_BUFFERS_ARB = %d\n", numBuf); + if (numBuf < 2) { + printf("Sorry, GL_MAX_DRAW_BUFFERS_ARB needs to be >= 2\n"); + exit(1); + } + + printf("GL_RENDERER = %s\n", (char *) glGetString(GL_RENDERER)); +} + + +static void +SetupRenderbuffers(void) +{ + glGenFramebuffersEXT(1, &FBobject); + glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, FBobject); + + glGenRenderbuffersEXT(3, RBobjects); + + glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, RBobjects[0]); + glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_RGB, Width, Height); + + glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, RBobjects[1]); + glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_RGB, Width, Height); + + glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, RBobjects[2]); + glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_DEPTH_COMPONENT, + Width, Height); + + glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, + GL_RENDERBUFFER_EXT, RBobjects[0]); + glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT1_EXT, + GL_RENDERBUFFER_EXT, RBobjects[1]); + glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, + GL_RENDERBUFFER_EXT, RBobjects[2]); + + CheckError(__LINE__); +} + + +static GLuint +LoadAndCompileShader(GLenum target, const char *text) +{ + GLint stat; + GLuint shader = glCreateShader_func(target); + glShaderSource_func(shader, 1, (const GLchar **) &text, NULL); + glCompileShader_func(shader); + glGetShaderiv_func(shader, GL_COMPILE_STATUS, &stat); + if (!stat) { + GLchar log[1000]; + GLsizei len; + glGetShaderInfoLog_func(shader, 1000, &len, log); + fprintf(stderr, "drawbuffers: problem compiling shader:\n%s\n", log); + exit(1); + } + return shader; +} + + +static void +CheckLink(GLuint prog) +{ + GLint stat; + glGetProgramiv_func(prog, GL_LINK_STATUS, &stat); + if (!stat) { + GLchar log[1000]; + GLsizei len; + glGetProgramInfoLog_func(prog, 1000, &len, log); + fprintf(stderr, "drawbuffers: shader link error:\n%s\n", log); + } +} + + +static void +SetupShaders(void) +{ + /* second color output = 1 - first color */ + static const char *fragShaderText = + "void main() {\n" + " gl_FragData[0] = gl_Color; \n" + " gl_FragData[1] = vec4(1.0) - gl_Color; \n" + "}\n"; + + GLuint fragShader, program; + + fragShader = LoadAndCompileShader(GL_FRAGMENT_SHADER, fragShaderText); + program = glCreateProgram_func(); + + glAttachShader_func(program, fragShader); + glLinkProgram_func(program); + CheckLink(program); + glUseProgram_func(program); +} + + +static void +SetupLighting(void) +{ + static const GLfloat frontMat[4] = { 1.0, 0.5, 0.5, 1.0 }; + static const GLfloat backMat[4] = { 1.0, 0.5, 0.5, 1.0 }; + + glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, frontMat); + glMaterialfv(GL_BACK, GL_AMBIENT_AND_DIFFUSE, backMat); + glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, 1); + glEnable(GL_LIGHT0); + glEnable(GL_LIGHTING); +} + + +static void +Init(void) +{ + CheckExtensions(); + GetExtensionFuncs(); + SetupRenderbuffers(); + SetupShaders(); + SetupLighting(); + glEnable(GL_DEPTH_TEST); +} + + +int +main(int argc, char *argv[]) +{ + glutInit(&argc, argv); + glutInitWindowPosition(0, 0); + glutInitWindowSize(Width, Height); + glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE); + Win = glutCreateWindow(argv[0]); + glutReshapeFunc(Reshape); + glutKeyboardFunc(Key); + glutDisplayFunc(Display); + Init(); + glutMainLoop(); + return 0; +} diff --git a/progs/util/extfuncs.h b/progs/util/extfuncs.h new file mode 100644 index 0000000000..f5ea5feaa8 --- /dev/null +++ b/progs/util/extfuncs.h @@ -0,0 +1,118 @@ +/** + * Utility for getting OpenGL extension function pointers + * Meant to be #included. + */ + +/* OpenGL 2.0 */ +static PFNGLATTACHSHADERPROC glAttachShader_func = NULL; +static PFNGLBINDATTRIBLOCATIONPROC glBindAttribLocation_func = NULL; +static PFNGLCOMPILESHADERPROC glCompileShader_func = NULL; +static PFNGLCREATEPROGRAMPROC glCreateProgram_func = NULL; +static PFNGLCREATESHADERPROC glCreateShader_func = NULL; +static PFNGLDELETEPROGRAMPROC glDeleteProgram_func = NULL; +static PFNGLDELETESHADERPROC glDeleteShader_func = NULL; +static PFNGLGETATTACHEDSHADERSPROC glGetAttachedShaders_func = NULL; +static PFNGLGETATTRIBLOCATIONPROC glGetAttribLocation_func = NULL; +static PFNGLGETPROGRAMINFOLOGPROC glGetProgramInfoLog_func = NULL; +static PFNGLGETSHADERINFOLOGPROC glGetShaderInfoLog_func = NULL; +static PFNGLGETSHADERIVPROC glGetShaderiv_func = NULL; +static PFNGLGETPROGRAMIVPROC glGetProgramiv_func = NULL; +static PFNGLGETSHADERSOURCEPROC glGetShaderSource_func = NULL; +static PFNGLGETUNIFORMFVPROC glGetUniformfv_func = NULL; +static PFNGLGETUNIFORMLOCATIONPROC glGetUniformLocation_func = NULL; +static PFNGLISPROGRAMPROC glIsProgram_func = NULL; +static PFNGLISSHADERPROC glIsShader_func = NULL; +static PFNGLLINKPROGRAMPROC glLinkProgram_func = NULL; +static PFNGLSHADERSOURCEPROC glShaderSource_func = NULL; +static PFNGLUNIFORM1IPROC glUniform1i_func = NULL; +static PFNGLUNIFORM1FVPROC glUniform1fv_func = NULL; +static PFNGLUNIFORM2FVPROC glUniform2fv_func = NULL; +static PFNGLUNIFORM3FVPROC glUniform3fv_func = NULL; +static PFNGLUNIFORM4FVPROC glUniform4fv_func = NULL; +static PFNGLUNIFORMMATRIX2FVPROC glUniformMatrix2fv_func = NULL; +static PFNGLUNIFORMMATRIX3FVPROC glUniformMatrix3fv_func = NULL; +static PFNGLUNIFORMMATRIX4FVPROC glUniformMatrix4fv_func = NULL; +static PFNGLUSEPROGRAMPROC glUseProgram_func = NULL; +static PFNGLVERTEXATTRIB1FPROC glVertexAttrib1f_func = NULL; +static PFNGLVERTEXATTRIB2FPROC glVertexAttrib2f_func = NULL; +static PFNGLVERTEXATTRIB3FPROC glVertexAttrib3f_func = NULL; +static PFNGLVERTEXATTRIB4FPROC glVertexAttrib4f_func = NULL; + + +/* GL_ARB_vertex/fragment_program */ +static PFNGLBINDPROGRAMARBPROC glBindProgramARB_func = NULL; +static PFNGLDELETEPROGRAMSARBPROC glDeleteProgramsARB_func = NULL; +static PFNGLGENPROGRAMSARBPROC glGenProgramsARB_func = NULL; +static PFNGLGETPROGRAMLOCALPARAMETERDVARBPROC glGetProgramLocalParameterdvARB_func = NULL; +static PFNGLISPROGRAMARBPROC glIsProgramARB_func = NULL; +static PFNGLPROGRAMLOCALPARAMETER4DARBPROC glProgramLocalParameter4dARB_func = NULL; +static PFNGLPROGRAMLOCALPARAMETER4FVARBPROC glProgramLocalParameter4fvARB_func = NULL; +static PFNGLPROGRAMSTRINGARBPROC glProgramStringARB_func = NULL; +static PFNGLVERTEXATTRIB1FARBPROC glVertexAttrib1fARB_func = NULL; + +/* GL_APPLE_vertex_array_object */ +static PFNGLBINDVERTEXARRAYAPPLEPROC glBindVertexArrayAPPLE_func = NULL; +static PFNGLDELETEVERTEXARRAYSAPPLEPROC glDeleteVertexArraysAPPLE_func = NULL; +static PFNGLGENVERTEXARRAYSAPPLEPROC glGenVertexArraysAPPLE_func = NULL; +static PFNGLISVERTEXARRAYAPPLEPROC glIsVertexArrayAPPLE_func = NULL; + + + +static void +GetExtensionFuncs(void) +{ + /* OpenGL 2.0 */ + glAttachShader_func = (PFNGLATTACHSHADERPROC) glutGetProcAddress("glAttachShader"); + glBindAttribLocation_func = (PFNGLBINDATTRIBLOCATIONPROC) glutGetProcAddress("glBindAttribLocation"); + glCompileShader_func = (PFNGLCOMPILESHADERPROC) glutGetProcAddress("glCompileShader"); + glCreateProgram_func = (PFNGLCREATEPROGRAMPROC) glutGetProcAddress("glCreateProgram"); + glCreateShader_func = (PFNGLCREATESHADERPROC) glutGetProcAddress("glCreateShader"); + glDeleteProgram_func = (PFNGLDELETEPROGRAMPROC) glutGetProcAddress("glDeleteProgram"); + glDeleteShader_func = (PFNGLDELETESHADERPROC) glutGetProcAddress("glDeleteShader"); + glGetAttachedShaders_func = (PFNGLGETATTACHEDSHADERSPROC) glutGetProcAddress("glGetAttachedShaders"); + glGetAttribLocation_func = (PFNGLGETATTRIBLOCATIONPROC) glutGetProcAddress("glGetAttribLocation"); + glGetProgramInfoLog_func = (PFNGLGETPROGRAMINFOLOGPROC) glutGetProcAddress("glGetProgramInfoLog"); + glGetShaderInfoLog_func = (PFNGLGETSHADERINFOLOGPROC) glutGetProcAddress("glGetShaderInfoLog"); + glGetProgramiv_func = (PFNGLGETPROGRAMIVPROC) glutGetProcAddress("glGetProgramiv"); + glGetShaderiv_func = (PFNGLGETSHADERIVPROC) glutGetProcAddress("glGetShaderiv"); + glGetShaderSource_func = (PFNGLGETSHADERSOURCEPROC) glutGetProcAddress("glGetShaderSource"); + glGetUniformLocation_func = (PFNGLGETUNIFORMLOCATIONPROC) glutGetProcAddress("glGetUniformLocation"); + glGetUniformfv_func = (PFNGLGETUNIFORMFVPROC) glutGetProcAddress("glGetUniformfv"); + glIsProgram_func = (PFNGLISPROGRAMPROC) glutGetProcAddress("glIsProgram"); + glIsShader_func = (PFNGLISSHADERPROC) glutGetProcAddress("glIsShader"); + glLinkProgram_func = (PFNGLLINKPROGRAMPROC) glutGetProcAddress("glLinkProgram"); + glShaderSource_func = (PFNGLSHADERSOURCEPROC) glutGetProcAddress("glShaderSource"); + glUniform1i_func = (PFNGLUNIFORM1IPROC) glutGetProcAddress("glUniform1i"); + glUniform1fv_func = (PFNGLUNIFORM1FVPROC) glutGetProcAddress("glUniform1fv"); + glUniform2fv_func = (PFNGLUNIFORM2FVPROC) glutGetProcAddress("glUniform2fv"); + glUniform3fv_func = (PFNGLUNIFORM3FVPROC) glutGetProcAddress("glUniform3fv"); + glUniform4fv_func = (PFNGLUNIFORM3FVPROC) glutGetProcAddress("glUniform4fv"); + glUniformMatrix2fv_func = (PFNGLUNIFORMMATRIX2FVPROC) glutGetProcAddress("glUniformMatrix2fv"); + glUniformMatrix3fv_func = (PFNGLUNIFORMMATRIX3FVPROC) glutGetProcAddress("glUniformMatrix3fv"); + glUniformMatrix4fv_func = (PFNGLUNIFORMMATRIX4FVPROC) glutGetProcAddress("glUniformMatrix4fv"); + glUseProgram_func = (PFNGLUSEPROGRAMPROC) glutGetProcAddress("glUseProgram"); + glVertexAttrib1f_func = (PFNGLVERTEXATTRIB1FPROC) glutGetProcAddress("glVertexAttrib1f"); + glVertexAttrib2f_func = (PFNGLVERTEXATTRIB2FPROC) glutGetProcAddress("glVertexAttrib2f"); + glVertexAttrib3f_func = (PFNGLVERTEXATTRIB3FPROC) glutGetProcAddress("glVertexAttrib3f"); + glVertexAttrib4f_func = (PFNGLVERTEXATTRIB4FPROC) glutGetProcAddress("glVertexAttrib4f"); + + + /* GL_ARB_vertex/fragment_program */ + glBindProgramARB_func = (PFNGLBINDPROGRAMARBPROC) glutGetProcAddress("glBindProgramARB"); + glDeleteProgramsARB_func = (PFNGLDELETEPROGRAMSARBPROC) glutGetProcAddress("glDeleteProgramsARB"); + glGenProgramsARB_func = (PFNGLGENPROGRAMSARBPROC) glutGetProcAddress("glGenProgramsARB"); + glGetProgramLocalParameterdvARB_func = (PFNGLGETPROGRAMLOCALPARAMETERDVARBPROC) glutGetProcAddress("glGetProgramLocalParameterdvARB"); + glIsProgramARB_func = (PFNGLISPROGRAMARBPROC) glutGetProcAddress("glIsProgramARB"); + glProgramLocalParameter4dARB_func = (PFNGLPROGRAMLOCALPARAMETER4DARBPROC) glutGetProcAddress("glProgramLocalParameter4dARB"); + glProgramLocalParameter4fvARB_func = (PFNGLPROGRAMLOCALPARAMETER4FVARBPROC) glutGetProcAddress("glProgramLocalParameter4fvARB"); + glProgramStringARB_func = (PFNGLPROGRAMSTRINGARBPROC) glutGetProcAddress("glProgramStringARB"); + glVertexAttrib1fARB_func = (PFNGLVERTEXATTRIB1FARBPROC) glutGetProcAddress("glVertexAttrib1fARB"); + + /* GL_APPLE_vertex_array_object */ + glBindVertexArrayAPPLE_func = (PFNGLBINDVERTEXARRAYAPPLEPROC) glutGetProcAddress("glBindVertexArrayAPPLE"); + glDeleteVertexArraysAPPLE_func = (PFNGLDELETEVERTEXARRAYSAPPLEPROC) glutGetProcAddress("glDeleteVertexArraysAPPLE"); + glGenVertexArraysAPPLE_func = (PFNGLGENVERTEXARRAYSAPPLEPROC) glutGetProcAddress("glGenVertexArraysAPPLE"); + glIsVertexArrayAPPLE_func = (PFNGLISVERTEXARRAYAPPLEPROC) glutGetProcAddress("glIsVertexArrayAPPLE"); + +} + diff --git a/src/mesa/drivers/common/driverfuncs.c b/src/mesa/drivers/common/driverfuncs.c index 1e44904b93..f543de183a 100644 --- a/src/mesa/drivers/common/driverfuncs.c +++ b/src/mesa/drivers/common/driverfuncs.c @@ -1,8 +1,8 @@ /* * Mesa 3-D graphics library - * Version: 6.5 + * Version: 6.5.3 * - * Copyright (C) 1999-2005 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"), @@ -30,6 +30,7 @@ #include "framebuffer.h" #include "occlude.h" #include "program.h" +#include "prog_execute.h" #include "renderbuffer.h" #include "texcompress.h" #include "texformat.h" @@ -43,6 +44,7 @@ #include "fbobject.h" #include "texrender.h" #endif +#include "shader_api.h" #include "arrayobj.h" #include "driverfuncs.h" @@ -127,7 +129,7 @@ _mesa_init_driver_functions(struct dd_function_table *driver) driver->NewProgram = _mesa_new_program; driver->DeleteProgram = _mesa_delete_program; #if FEATURE_MESA_program_debug - driver->GetFragmentProgramRegister = _swrast_get_program_register; + driver->GetProgramRegister = _mesa_get_program_register; #endif /* FEATURE_MESA_program_debug */ /* simple state commands */ @@ -248,4 +250,45 @@ _mesa_init_driver_functions(struct dd_function_table *driver) driver->EndList = NULL; driver->BeginCallList = NULL; driver->EndCallList = NULL; + + + /* XXX temporary here */ + _mesa_init_glsl_driver_functions(driver); +} + + +/** + * Plug in Mesa's GLSL functions. + */ +void +_mesa_init_glsl_driver_functions(struct dd_function_table *driver) +{ + driver->AttachShader = _mesa_attach_shader; + driver->BindAttribLocation = _mesa_bind_attrib_location; + driver->CompileShader = _mesa_compile_shader; + driver->CreateProgram = _mesa_create_program; + driver->CreateShader = _mesa_create_shader; + driver->DeleteProgram2 = _mesa_delete_program2; + driver->DeleteShader = _mesa_delete_shader; + driver->DetachShader = _mesa_detach_shader; + driver->GetActiveAttrib = _mesa_get_active_attrib; + driver->GetActiveUniform = _mesa_get_active_uniform; + driver->GetAttachedShaders = _mesa_get_attached_shaders; + driver->GetAttribLocation = _mesa_get_attrib_location; + driver->GetHandle = _mesa_get_handle; + driver->GetProgramiv = _mesa_get_programiv; + driver->GetProgramInfoLog = _mesa_get_program_info_log; + driver->GetShaderiv = _mesa_get_shaderiv; + driver->GetShaderInfoLog = _mesa_get_shader_info_log; + driver->GetShaderSource = _mesa_get_shader_source; + driver->GetUniformfv = _mesa_get_uniformfv; + driver->GetUniformLocation = _mesa_get_uniform_location; + driver->IsProgram = _mesa_is_program; + driver->IsShader = _mesa_is_shader; + driver->LinkProgram = _mesa_link_program; + driver->ShaderSource = _mesa_shader_source; + driver->Uniform = _mesa_uniform; + driver->UniformMatrix = _mesa_uniform_matrix; + driver->UseProgram = _mesa_use_program; + driver->ValidateProgram = _mesa_validate_program; } diff --git a/src/mesa/drivers/common/driverfuncs.h b/src/mesa/drivers/common/driverfuncs.h index 64f56d91f9..50f2b4271d 100644 --- a/src/mesa/drivers/common/driverfuncs.h +++ b/src/mesa/drivers/common/driverfuncs.h @@ -1,8 +1,8 @@ /* * Mesa 3-D graphics library - * Version: 6.1 + * Version: 6.5.3 * - * Copyright (C) 1999-2004 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"), @@ -29,4 +29,8 @@ extern void _mesa_init_driver_functions(struct dd_function_table *driver); + +extern void +_mesa_init_glsl_driver_functions(struct dd_function_table *driver); + #endif diff --git a/src/mesa/drivers/dri/i915/i915_context.c b/src/mesa/drivers/dri/i915/i915_context.c index 6ec34e5bde..4ab9d2686c 100644 --- a/src/mesa/drivers/dri/i915/i915_context.c +++ b/src/mesa/drivers/dri/i915/i915_context.c @@ -167,8 +167,7 @@ GLboolean i915CreateContext( const __GLcontextModes *mesaVis, I915_MAX_TEX_INSN); ctx->Const.FragmentProgram.MaxNativeTexIndirections = I915_MAX_TEX_INDIRECT; ctx->Const.FragmentProgram.MaxNativeAddressRegs = 0; /* I don't think we have one */ - ctx->_MaintainTexEnvProgram = 1; - ctx->_UseTexEnvProgram = 1; + ctx->FragmentProgram._MaintainTexEnvProgram = GL_TRUE; driInitExtensions( ctx, i915_extensions, GL_FALSE ); diff --git a/src/mesa/drivers/dri/i915/i915_fragprog.c b/src/mesa/drivers/dri/i915/i915_fragprog.c index ef14f3eef7..a28c8bb6fc 100644 --- a/src/mesa/drivers/dri/i915/i915_fragprog.c +++ b/src/mesa/drivers/dri/i915/i915_fragprog.c @@ -37,7 +37,8 @@ #include "i915_context.h" #include "i915_program.h" -#include "program_instruction.h" +#include "prog_instruction.h" +#include "prog_parameter.h" #include "program.h" #include "programopt.h" @@ -782,9 +783,6 @@ static void fixup_depth_write( struct i915_fragment_program *p ) } -#define FRAG_BIT_TEX(n) (FRAG_BIT_TEX0 << (n)) - - static void check_wpos( struct i915_fragment_program *p ) { GLuint inputs = p->FragProg.Base.InputsRead; diff --git a/src/mesa/drivers/dri/i915/i915_program.c b/src/mesa/drivers/dri/i915/i915_program.c index 9c13290d11..6849112444 100644 --- a/src/mesa/drivers/dri/i915/i915_program.c +++ b/src/mesa/drivers/dri/i915/i915_program.c @@ -430,17 +430,17 @@ void i915_fini_program( struct i915_fragment_program *p ) if (p->error) { p->FragProg.Base.NumNativeInstructions = 0; - p->FragProg.NumNativeAluInstructions = 0; - p->FragProg.NumNativeTexInstructions = 0; - p->FragProg.NumNativeTexIndirections = 0; + p->FragProg.Base.NumNativeAluInstructions = 0; + p->FragProg.Base.NumNativeTexInstructions = 0; + p->FragProg.Base.NumNativeTexIndirections = 0; } else { p->FragProg.Base.NumNativeInstructions = (p->nr_alu_insn + p->nr_tex_insn + p->nr_decl_insn); - p->FragProg.NumNativeAluInstructions = p->nr_alu_insn; - p->FragProg.NumNativeTexInstructions = p->nr_tex_insn; - p->FragProg.NumNativeTexIndirections = p->nr_tex_indirect; + p->FragProg.Base.NumNativeAluInstructions = p->nr_alu_insn; + p->FragProg.Base.NumNativeTexInstructions = p->nr_tex_insn; + p->FragProg.Base.NumNativeTexIndirections = p->nr_tex_indirect; } p->declarations[0] |= program_size + decl_size - 2; diff --git a/src/mesa/drivers/dri/i915/i915_state.c b/src/mesa/drivers/dri/i915/i915_state.c index 5e00e6597b..d126208ce0 100644 --- a/src/mesa/drivers/dri/i915/i915_state.c +++ b/src/mesa/drivers/dri/i915/i915_state.c @@ -531,7 +531,7 @@ void i915_update_fog( GLcontext *ctx ) GLboolean enabled; GLboolean try_pixel_fog; - if (ctx->FragmentProgram._Active) { + if (ctx->FragmentProgram._Enabled) { /* Pull in static fog state from program */ mode = ctx->FragmentProgram._Current->FogOption; diff --git a/src/mesa/drivers/dri/i915/i915_vtbl.c b/src/mesa/drivers/dri/i915/i915_vtbl.c index b533e153be..c920fc47ea 100644 --- a/src/mesa/drivers/dri/i915/i915_vtbl.c +++ b/src/mesa/drivers/dri/i915/i915_vtbl.c @@ -46,10 +46,10 @@ static void i915_render_start( intelContextPtr intel ) GLcontext *ctx = &intel->ctx; i915ContextPtr i915 = I915_CONTEXT(intel); - if (ctx->FragmentProgram._Active) + if (ctx->FragmentProgram._Current) i915ValidateFragmentProgram( i915 ); else { - assert(!ctx->_MaintainTexEnvProgram); + assert(!ctx->FragmentProgram._MaintainTexEnvProgram); i915ValidateTextureProgram( i915 ); } } diff --git a/src/mesa/drivers/dri/i915tex/i915_context.c b/src/mesa/drivers/dri/i915tex/i915_context.c index 9b4d72eab3..d4187238f3 100644 --- a/src/mesa/drivers/dri/i915tex/i915_context.c +++ b/src/mesa/drivers/dri/i915tex/i915_context.c @@ -157,8 +157,8 @@ i915CreateContext(const __GLcontextModes * mesaVis, I915_MAX_TEX_INDIRECT; ctx->Const.FragmentProgram.MaxNativeAddressRegs = 0; /* I don't think we have one */ - ctx->_MaintainTexEnvProgram = 1; - ctx->_UseTexEnvProgram = 1; + ctx->FragmentProgram._MaintainTexEnvProgram = GL_TRUE; + /*ctx->_UseTexEnvProgram = 1;*/ driInitExtensions(ctx, i915_extensions, GL_FALSE); diff --git a/src/mesa/drivers/dri/i915tex/i915_fragprog.c b/src/mesa/drivers/dri/i915tex/i915_fragprog.c index 8772e70230..cbea6092a8 100644 --- a/src/mesa/drivers/dri/i915tex/i915_fragprog.c +++ b/src/mesa/drivers/dri/i915tex/i915_fragprog.c @@ -37,7 +37,8 @@ #include "i915_context.h" #include "i915_program.h" -#include "program_instruction.h" +#include "prog_instruction.h" +#include "prog_parameter.h" #include "program.h" #include "programopt.h" @@ -772,9 +773,6 @@ fixup_depth_write(struct i915_fragment_program *p) } -#define FRAG_BIT_TEX(n) (FRAG_BIT_TEX0 << (n)) - - static void check_wpos(struct i915_fragment_program *p) { diff --git a/src/mesa/drivers/dri/i915tex/i915_program.c b/src/mesa/drivers/dri/i915tex/i915_program.c index 0be89d3320..ed45e4f806 100644 --- a/src/mesa/drivers/dri/i915tex/i915_program.c +++ b/src/mesa/drivers/dri/i915tex/i915_program.c @@ -446,17 +446,17 @@ i915_fini_program(struct i915_fragment_program *p) if (p->error) { p->FragProg.Base.NumNativeInstructions = 0; - p->FragProg.NumNativeAluInstructions = 0; - p->FragProg.NumNativeTexInstructions = 0; - p->FragProg.NumNativeTexIndirections = 0; + p->FragProg.Base.NumNativeAluInstructions = 0; + p->FragProg.Base.NumNativeTexInstructions = 0; + p->FragProg.Base.NumNativeTexIndirections = 0; } else { p->FragProg.Base.NumNativeInstructions = (p->nr_alu_insn + p->nr_tex_insn + p->nr_decl_insn); - p->FragProg.NumNativeAluInstructions = p->nr_alu_insn; - p->FragProg.NumNativeTexInstructions = p->nr_tex_insn; - p->FragProg.NumNativeTexIndirections = p->nr_tex_indirect; + p->FragProg.Base.NumNativeAluInstructions = p->nr_alu_insn; + p->FragProg.Base.NumNativeTexInstructions = p->nr_tex_insn; + p->FragProg.Base.NumNativeTexIndirections = p->nr_tex_indirect; } p->declarations[0] |= program_size + decl_size - 2; diff --git a/src/mesa/drivers/dri/i915tex/i915_state.c b/src/mesa/drivers/dri/i915tex/i915_state.c index 1fafadced0..c2c2ff366f 100644 --- a/src/mesa/drivers/dri/i915tex/i915_state.c +++ b/src/mesa/drivers/dri/i915tex/i915_state.c @@ -561,7 +561,7 @@ i915_update_fog(GLcontext * ctx) GLboolean enabled; GLboolean try_pixel_fog; - if (ctx->FragmentProgram._Active) { + if (ctx->FragmentProgram._Enabled) { /* Pull in static fog state from program */ mode = ctx->FragmentProgram._Current->FogOption; diff --git a/src/mesa/drivers/dri/i965/brw_context.c b/src/mesa/drivers/dri/i965/brw_context.c index 6faee65542..397a9bd3f5 100644 --- a/src/mesa/drivers/dri/i965/brw_context.c +++ b/src/mesa/drivers/dri/i965/brw_context.c @@ -148,7 +148,7 @@ GLboolean brwCreateContext( const __GLcontextModes *mesaVis, brw->emit_state_always = 0; - ctx->_MaintainTexEnvProgram = 1; + ctx->FragmentProgram._MaintainTexEnvProgram = 1; brw_draw_init( brw ); diff --git a/src/mesa/drivers/dri/i965/brw_curbe.c b/src/mesa/drivers/dri/i965/brw_curbe.c index 4352c3bcb0..3f0aaa1f86 100644 --- a/src/mesa/drivers/dri/i965/brw_curbe.c +++ b/src/mesa/drivers/dri/i965/brw_curbe.c @@ -35,7 +35,8 @@ #include "context.h" #include "macros.h" #include "enums.h" -#include "shader/program.h" +#include "shader/prog_parameter.h" +#include "shader/prog_statevars.h" #include "intel_batchbuffer.h" #include "brw_context.h" #include "brw_defines.h" diff --git a/src/mesa/drivers/dri/i965/brw_eu.h b/src/mesa/drivers/dri/i965/brw_eu.h index d4dbcf38a7..52f89d577c 100644 --- a/src/mesa/drivers/dri/i965/brw_eu.h +++ b/src/mesa/drivers/dri/i965/brw_eu.h @@ -35,7 +35,7 @@ #include "brw_structs.h" #include "brw_defines.h" -#include "shader/program.h" +#include "shader/prog_instruction.h" #define BRW_SWIZZLE4(a,b,c,d) (((a)<<0) | ((b)<<2) | ((c)<<4) | ((d)<<6)) #define BRW_GET_SWZ(swz, idx) (((swz) >> ((idx)*2)) & 0x3) diff --git a/src/mesa/drivers/dri/i965/brw_metaops.c b/src/mesa/drivers/dri/i965/brw_metaops.c index 1579762b6d..6e030f191e 100644 --- a/src/mesa/drivers/dri/i965/brw_metaops.c +++ b/src/mesa/drivers/dri/i965/brw_metaops.c @@ -35,8 +35,6 @@ #include "glheader.h" #include "context.h" #include "macros.h" -#include "enums.h" -#include "dd.h" #include "shader/arbprogparse.h" diff --git a/src/mesa/drivers/dri/i965/brw_util.c b/src/mesa/drivers/dri/i965/brw_util.c index 9d12c26486..b6deee2376 100644 --- a/src/mesa/drivers/dri/i965/brw_util.c +++ b/src/mesa/drivers/dri/i965/brw_util.c @@ -30,9 +30,9 @@ */ -#include "brw_util.h" #include "mtypes.h" -#include "shader/program.h" +#include "shader/prog_parameter.h" +#include "brw_util.h" #include "brw_defines.h" GLuint brw_count_bits( GLuint val ) @@ -45,7 +45,7 @@ GLuint brw_count_bits( GLuint val ) } -static GLuint brw_parameter_state_flags(const enum state_index state[]) +static GLuint brw_parameter_state_flags(const gl_state_index state[]) { switch (state[0]) { case STATE_MATERIAL: @@ -70,22 +70,16 @@ static GLuint brw_parameter_state_flags(const enum state_index state[]) case STATE_POINT_ATTENUATION: return _NEW_POINT; - case STATE_MATRIX: - switch (state[1]) { - case STATE_MODELVIEW: - return _NEW_MODELVIEW; - case STATE_PROJECTION: - return _NEW_PROJECTION; - case STATE_MVP: - return _NEW_MODELVIEW | _NEW_PROJECTION; - case STATE_TEXTURE: - return _NEW_TEXTURE_MATRIX; - case STATE_PROGRAM: - return _NEW_TRACK_MATRIX; - default: - assert(0); - return 0; - } + case STATE_MODELVIEW_MATRIX: + return _NEW_MODELVIEW; + case STATE_PROJECTION_MATRIX: + return _NEW_PROJECTION; + case STATE_MVP_MATRIX: + return _NEW_MODELVIEW | _NEW_PROJECTION; + case STATE_TEXTURE_MATRIX: + return _NEW_TEXTURE_MATRIX; + case STATE_PROGRAM_MATRIX: + return _NEW_TRACK_MATRIX; case STATE_DEPTH_RANGE: return _NEW_VIEWPORT; diff --git a/src/mesa/drivers/dri/i965/brw_vs.c b/src/mesa/drivers/dri/i965/brw_vs.c index 74c9d88e46..e173f6fce3 100644 --- a/src/mesa/drivers/dri/i965/brw_vs.c +++ b/src/mesa/drivers/dri/i965/brw_vs.c @@ -34,8 +34,7 @@ #include "brw_vs.h" #include "brw_util.h" #include "brw_state.h" -#include "program.h" -#include "shader/arbprogparse.h" +#include "shader/prog_print.h" diff --git a/src/mesa/drivers/dri/i965/brw_vs_constval.c b/src/mesa/drivers/dri/i965/brw_vs_constval.c index 528e164db8..caef042f1c 100644 --- a/src/mesa/drivers/dri/i965/brw_vs_constval.c +++ b/src/mesa/drivers/dri/i965/brw_vs_constval.c @@ -30,10 +30,8 @@ */ -#include "brw_context.h" -#include "program.h" -#include "program_instruction.h" #include "macros.h" +#include "brw_context.h" #include "brw_vs.h" /* Component is active if it may diverge from [0,0,0,1]. Undef values diff --git a/src/mesa/drivers/dri/i965/brw_vs_emit.c b/src/mesa/drivers/dri/i965/brw_vs_emit.c index ffdb843e85..6eb11b19ad 100644 --- a/src/mesa/drivers/dri/i965/brw_vs_emit.c +++ b/src/mesa/drivers/dri/i965/brw_vs_emit.c @@ -30,10 +30,11 @@ */ -#include "brw_context.h" #include "program.h" -#include "program_instruction.h" #include "macros.h" +#include "shader/prog_parameter.h" +#include "shader/prog_print.h" +#include "brw_context.h" #include "brw_vs.h" diff --git a/src/mesa/drivers/dri/i965/brw_vs_tnl.c b/src/mesa/drivers/dri/i965/brw_vs_tnl.c index dd1664bf33..35adc4846a 100644 --- a/src/mesa/drivers/dri/i965/brw_vs_tnl.c +++ b/src/mesa/drivers/dri/i965/brw_vs_tnl.c @@ -33,12 +33,11 @@ #include "glheader.h" #include "macros.h" #include "enums.h" +#include "shader/prog_parameter.h" +#include "shader/prog_print.h" #include "brw_vs.h" #include "brw_state.h" -#include "shader/program.h" -#include "shader/program_instruction.h" -#include "shader/arbprogparse.h" struct state_key { unsigned light_global_enabled:1; @@ -398,11 +397,14 @@ static struct ureg register_const4f( struct tnl_program *p, { GLfloat values[4]; GLint idx; + GLuint swizzle; values[0] = s0; values[1] = s1; values[2] = s2; values[3] = s3; - idx = _mesa_add_unnamed_constant( p->program->Base.Parameters, values, 4 ); + idx = _mesa_add_unnamed_constant( p->program->Base.Parameters, values, 4, + &swizzle); + /* XXX what about swizzle? */ return make_ureg(PROGRAM_STATE_VAR, idx); } @@ -424,40 +426,37 @@ static struct ureg get_identity_param( struct tnl_program *p ) return p->identity; } -static struct ureg register_param6( struct tnl_program *p, - GLint s0, - GLint s1, - GLint s2, - GLint s3, - GLint s4, - GLint s5) +static struct ureg register_param5( struct tnl_program *p, + GLint s0, + GLint s1, + GLint s2, + GLint s3, + GLint s4) { - GLint tokens[6]; + gl_state_index tokens[STATE_LENGTH]; GLint idx; tokens[0] = s0; tokens[1] = s1; tokens[2] = s2; tokens[3] = s3; tokens[4] = s4; - tokens[5] = s5; idx = _mesa_add_state_reference( p->program->Base.Parameters, tokens ); return make_ureg(PROGRAM_STATE_VAR, idx); } -#define register_param1(p,s0) register_param6(p,s0,0,0,0,0,0) -#define register_param2(p,s0,s1) register_param6(p,s0,s1,0,0,0,0) -#define register_param3(p,s0,s1,s2) register_param6(p,s0,s1,s2,0,0,0) -#define register_param4(p,s0,s1,s2,s3) register_param6(p,s0,s1,s2,s3,0,0) +#define register_param1(p,s0) register_param5(p,s0,0,0,0,0) +#define register_param2(p,s0,s1) register_param5(p,s0,s1,0,0,0) +#define register_param3(p,s0,s1,s2) register_param5(p,s0,s1,s2,0,0) +#define register_param4(p,s0,s1,s2,s3) register_param5(p,s0,s1,s2,s3,0) -static void register_matrix_param6( struct tnl_program *p, - GLint s0, - GLint s1, - GLint s2, - GLint s3, - GLint s4, - GLint s5, +static void register_matrix_param5( struct tnl_program *p, + GLint s0, /* matrix name */ + GLint s1, /* texture matrix number */ + GLint s2, /* first row */ + GLint s3, /* last row */ + GLint s4, /* modifier */ struct ureg *matrix ) { GLint i; @@ -465,8 +464,8 @@ static void register_matrix_param6( struct tnl_program *p, /* This is a bit sad as the support is there to pull the whole * matrix out in one go: */ - for (i = 0; i <= s4 - s3; i++) - matrix[i] = register_param6( p, s0, s1, s2, i, i, s5 ); + for (i = 0; i <= s3 - s2; i++) + matrix[i] = register_param5( p, s0, s1, i, i, s4 ); } @@ -650,13 +649,13 @@ static struct ureg get_eye_position( struct tnl_program *p ) p->eye_position = reserve_temp(p); if (PREFER_DP4) { - register_matrix_param6( p, STATE_MATRIX, STATE_MODELVIEW, 0, 0, 3, - STATE_MATRIX, modelview ); + register_matrix_param5( p, STATE_MODELVIEW_MATRIX, 0, 0, 3, + 0, modelview ); emit_matrix_transform_vec4(p, p->eye_position, modelview, pos); } else { - register_matrix_param6( p, STATE_MATRIX, STATE_MODELVIEW, 0, 0, 3, + register_matrix_param5( p, STATE_MODELVIEW_MATRIX, 0, 0, 3, STATE_MATRIX_TRANSPOSE, modelview ); emit_transpose_matrix_transform_vec4(p, p->eye_position, modelview, pos); @@ -710,7 +709,7 @@ static struct ureg get_eye_normal( struct tnl_program *p ) struct ureg normal = register_input(p, VERT_ATTRIB_NORMAL ); struct ureg mvinv[3]; - register_matrix_param6( p, STATE_MATRIX, STATE_MODELVIEW, 0, 0, 2, + register_matrix_param5( p, STATE_MODELVIEW_MATRIX, 0, 0, 2, STATE_MATRIX_INVTRANS, mvinv ); p->eye_normal = reserve_temp(p); @@ -745,12 +744,12 @@ static void build_hpos( struct tnl_program *p ) struct ureg mvp[4]; if (PREFER_DP4) { - register_matrix_param6( p, STATE_MATRIX, STATE_MVP, 0, 0, 3, - STATE_MATRIX, mvp ); + register_matrix_param5( p, STATE_MVP_MATRIX, 0, 0, 3, + 0, mvp ); emit_matrix_transform_vec4( p, hpos, mvp, pos ); } else { - register_matrix_param6( p, STATE_MATRIX, STATE_MVP, 0, 0, 3, + register_matrix_param5( p, STATE_MVP_MATRIX, 0, 0, 3, STATE_MATRIX_TRANSPOSE, mvp ); emit_transpose_matrix_transform_vec4( p, hpos, mvp, pos ); } @@ -894,7 +893,7 @@ static struct ureg calculate_light_attenuation( struct tnl_program *p, /* Need to add some addtional parameters to allow lighting in object - * space - STATE_SPOT_DIRECTION and STATE_HALF implicitly assume eye + * space - STATE_SPOT_DIRECTION and STATE_HALF_VECTOR implicitly assume eye * space lighting. */ static void build_lighting( struct tnl_program *p ) @@ -993,7 +992,7 @@ static void build_lighting( struct tnl_program *p ) emit_op2(p, OPCODE_SUB, half, 0, VPpli, eye_hat); emit_normalize_vec3(p, half, half); } else { - half = register_param3(p, STATE_LIGHT, i, STATE_HALF); + half = register_param3(p, STATE_LIGHT, i, STATE_HALF_VECTOR); } } else { @@ -1360,13 +1359,13 @@ static void build_texture_transform( struct tnl_program *p ) out_texgen : register_input(p, VERT_ATTRIB_TEX0+i)); if (PREFER_DP4) { - register_matrix_param6( p, STATE_MATRIX, STATE_TEXTURE, i, - 0, 3, STATE_MATRIX, texmat ); + register_matrix_param5( p, STATE_TEXTURE_MATRIX, i, 0, 3, + 0, texmat ); emit_matrix_transform_vec4( p, out, texmat, in ); } else { - register_matrix_param6( p, STATE_MATRIX, STATE_TEXTURE, i, - 0, 3, STATE_MATRIX_TRANSPOSE, texmat ); + register_matrix_param5( p, STATE_TEXTURE_MATRIX, i, 0, 3, + STATE_MATRIX_TRANSPOSE, texmat ); emit_transpose_matrix_transform_vec4( p, out, texmat, in ); } } diff --git a/src/mesa/drivers/dri/i965/brw_wm.c b/src/mesa/drivers/dri/i965/brw_wm.c index 0f842d289d..1497dc7968 100644 --- a/src/mesa/drivers/dri/i965/brw_wm.c +++ b/src/mesa/drivers/dri/i965/brw_wm.c @@ -36,10 +36,6 @@ #include "brw_state.h" #include "brw_hal.h" -#include "program.h" -#include "program_instruction.h" -#include "arbprogparse.h" - GLuint brw_wm_nr_args( GLuint opcode ) { diff --git a/src/mesa/drivers/dri/i965/brw_wm.h b/src/mesa/drivers/dri/i965/brw_wm.h index ec6ad6105c..f5fddfdb68 100644 --- a/src/mesa/drivers/dri/i965/brw_wm.h +++ b/src/mesa/drivers/dri/i965/brw_wm.h @@ -36,7 +36,7 @@ #include "brw_context.h" #include "brw_eu.h" -#include "program_instruction.h" +#include "prog_instruction.h" /* A big lookup table is used to figure out which and how many * additional regs will inserted before the main payload in the WM diff --git a/src/mesa/drivers/dri/i965/brw_wm_debug.c b/src/mesa/drivers/dri/i965/brw_wm_debug.c index 9a6154b333..f31d0974ec 100644 --- a/src/mesa/drivers/dri/i965/brw_wm_debug.c +++ b/src/mesa/drivers/dri/i965/brw_wm_debug.c @@ -32,9 +32,6 @@ #include "brw_context.h" #include "brw_wm.h" -#include "program.h" -#include "shader/arbprogparse.h" -#include "shader/program_instruction.h" void brw_wm_print_value( struct brw_wm_compile *c, diff --git a/src/mesa/drivers/dri/i965/brw_wm_emit.c b/src/mesa/drivers/dri/i965/brw_wm_emit.c index d96a9b717c..fd60515972 100644 --- a/src/mesa/drivers/dri/i965/brw_wm_emit.c +++ b/src/mesa/drivers/dri/i965/brw_wm_emit.c @@ -30,10 +30,8 @@ */ -#include "brw_context.h" -#include "program.h" -#include "program_instruction.h" #include "macros.h" +#include "brw_context.h" #include "brw_wm.h" #define SATURATE (1<<5) diff --git a/src/mesa/drivers/dri/i965/brw_wm_fp.c b/src/mesa/drivers/dri/i965/brw_wm_fp.c index ba2dbeccde..ff97d87dc4 100644 --- a/src/mesa/drivers/dri/i965/brw_wm_fp.c +++ b/src/mesa/drivers/dri/i965/brw_wm_fp.c @@ -37,9 +37,10 @@ #include "brw_wm.h" #include "brw_util.h" -#include "shader/program.h" -#include "shader/program_instruction.h" -#include "shader/arbprogparse.h" +#include "shader/prog_parameter.h" +#include "shader/prog_print.h" +#include "shader/prog_statevars.h" + #define FIRST_INTERNAL_TEMP MAX_NV_FRAGMENT_PROGRAM_TEMPS @@ -370,23 +371,21 @@ static void emit_interp( struct brw_wm_compile *c, * harm and it's not as if the parameter handling isn't a big hack * anyway. */ -static struct prog_src_register search_or_add_param6( struct brw_wm_compile *c, - GLint s0, - GLint s1, - GLint s2, - GLint s3, - GLint s4, - GLint s5) +static struct prog_src_register search_or_add_param5(struct brw_wm_compile *c, + GLint s0, + GLint s1, + GLint s2, + GLint s3, + GLint s4) { struct gl_program_parameter_list *paramList = c->fp->program.Base.Parameters; - GLint tokens[6]; + gl_state_index tokens[STATE_LENGTH]; GLuint idx; tokens[0] = s0; tokens[1] = s1; tokens[2] = s2; tokens[3] = s3; tokens[4] = s4; - tokens[5] = s5; for (idx = 0; idx < paramList->NumParameters; idx++) { if (paramList->Parameters[idx].Type == PROGRAM_STATE_VAR && @@ -413,6 +412,7 @@ static struct prog_src_register search_or_add_const4f( struct brw_wm_compile *c, struct gl_program_parameter_list *paramList = c->fp->program.Base.Parameters; GLfloat values[4]; GLuint idx; + GLuint swizzle; values[0] = s0; values[1] = s1; @@ -432,8 +432,8 @@ static struct prog_src_register search_or_add_const4f( struct brw_wm_compile *c, return src_reg(PROGRAM_STATE_VAR, idx); } - idx = _mesa_add_unnamed_constant( paramList, values, 4 ); - + idx = _mesa_add_unnamed_constant( paramList, values, 4, &swizzle ); + /* XXX what about swizzle? */ return src_reg(PROGRAM_STATE_VAR, idx); } @@ -527,11 +527,11 @@ static void precalc_tex( struct brw_wm_compile *c, if (inst->TexSrcTarget == TEXTURE_RECT_INDEX) { struct prog_src_register scale = - search_or_add_param6( c, + search_or_add_param5( c, STATE_INTERNAL, STATE_TEXRECT_SCALE, inst->TexSrcUnit, - 0,0,0 ); + 0,0 ); tmpcoord = get_temp(c); @@ -724,7 +724,7 @@ static void fog_blend( struct brw_wm_compile *c, struct prog_src_register fog_factor ) { struct prog_dst_register outcolor = dst_reg(PROGRAM_OUTPUT, FRAG_RESULT_COLR); - struct prog_src_register fogcolor = search_or_add_param6( c, STATE_FOG_COLOR, 0,0,0,0,0 ); + struct prog_src_register fogcolor = search_or_add_param5( c, STATE_FOG_COLOR, 0,0,0,0 ); /* color.xyz = LRP fog_factor.xxxx, output_color, fog_color */ diff --git a/src/mesa/drivers/dri/i965/brw_wm_pass0.c b/src/mesa/drivers/dri/i965/brw_wm_pass0.c index 36b69b7068..00f6f6b9a4 100644 --- a/src/mesa/drivers/dri/i965/brw_wm_pass0.c +++ b/src/mesa/drivers/dri/i965/brw_wm_pass0.c @@ -32,9 +32,7 @@ #include "brw_context.h" #include "brw_wm.h" -#include "program.h" -#include "arbprogparse.h" -#include "program_instruction.h" +#include "shader/prog_parameter.h" diff --git a/src/mesa/drivers/dri/i965/brw_wm_pass1.c b/src/mesa/drivers/dri/i965/brw_wm_pass1.c index 21d0881d57..d668def700 100644 --- a/src/mesa/drivers/dri/i965/brw_wm_pass1.c +++ b/src/mesa/drivers/dri/i965/brw_wm_pass1.c @@ -32,9 +32,6 @@ #include "brw_context.h" #include "brw_wm.h" -#include "program.h" -#include "arbprogparse.h" -#include "program_instruction.h" static GLuint get_tracked_mask(struct brw_wm_compile *c, diff --git a/src/mesa/drivers/dri/i965/brw_wm_pass2.c b/src/mesa/drivers/dri/i965/brw_wm_pass2.c index cb8d51fb5c..a1edbd6168 100644 --- a/src/mesa/drivers/dri/i965/brw_wm_pass2.c +++ b/src/mesa/drivers/dri/i965/brw_wm_pass2.c @@ -32,9 +32,7 @@ #include "brw_context.h" #include "brw_wm.h" -#include "program.h" -#include "arbprogparse.h" -#include "program_instruction.h" + /* Use these to force spilling so that that functionality can be * tested with known-good examples rather than having to construct new diff --git a/src/mesa/drivers/dri/mach64/mach64_native_vb.c b/src/mesa/drivers/dri/mach64/mach64_native_vb.c index 7872c206f5..519ec81e54 100644 --- a/src/mesa/drivers/dri/mach64/mach64_native_vb.c +++ b/src/mesa/drivers/dri/mach64/mach64_native_vb.c @@ -52,14 +52,14 @@ void TAG(translate_vertex)(GLcontext *ctx, { float rhw = 1.0 / LE32_IN_FLOAT( p + 2 ); - dst->texcoord[1][0] = rhw*LE32_IN_FLOAT( p++ ); - dst->texcoord[1][1] = rhw*LE32_IN_FLOAT( p++ ); + dst->attrib[FRAG_ATTRIB_TEX1][0] = rhw*LE32_IN_FLOAT( p++ ); + dst->attrib[FRAG_ATTRIB_TEX1][1] = rhw*LE32_IN_FLOAT( p++ ); } #else - dst->texcoord[1][0] = LE32_IN_FLOAT( p++ ); - dst->texcoord[1][1] = LE32_IN_FLOAT( p++ ); + dst->attrib[FRAG_ATTRIB_TEX1][0] = LE32_IN_FLOAT( p++ ); + dst->attrib[FRAG_ATTRIB_TEX1][1] = LE32_IN_FLOAT( p++ ); #endif - dst->texcoord[1][3] = 1.0; + dst->attrib[FRAG_ATTRIB_TEX1][3] = 1.0; p++; case TEX0_VERTEX_FORMAT: @@ -67,14 +67,14 @@ void TAG(translate_vertex)(GLcontext *ctx, { float rhw = 1.0 / LE32_IN_FLOAT( p + 2 ); - dst->texcoord[0][0] = rhw*LE32_IN_FLOAT( p++ ); - dst->texcoord[0][1] = rhw*LE32_IN_FLOAT( p++ ); + dst->attrib[FRAG_ATTRIB_TEX0][0] = rhw*LE32_IN_FLOAT( p++ ); + dst->attrib[FRAG_ATTRIB_TEX0][1] = rhw*LE32_IN_FLOAT( p++ ); } #else - dst->texcoord[0][0] = LE32_IN_FLOAT( p++ ); - dst->texcoord[0][1] = LE32_IN_FLOAT( p++ ); + dst->attrib[FRAG_ATTRIB_TEX0][0] = LE32_IN_FLOAT( p++ ); + dst->attrib[FRAG_ATTRIB_TEX0][1] = LE32_IN_FLOAT( p++ ); #endif - dst->texcoord[0][3] = 1.0; + dst->attrib[FRAG_ATTRIB_TEX0][3] = 1.0; dst->win[3] = LE32_IN_FLOAT( p++ ); case NOTEX_VERTEX_FORMAT: diff --git a/src/mesa/drivers/dri/nouveau/nouveau_context.c b/src/mesa/drivers/dri/nouveau/nouveau_context.c index f217c4404e..8e11eb6134 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_context.c +++ b/src/mesa/drivers/dri/nouveau/nouveau_context.c @@ -201,7 +201,7 @@ GLboolean nouveauCreateContext( const __GLcontextModes *glVisual, nouveauShaderInitFuncs(ctx); /* Install Mesa's fixed-function texenv shader support */ if (nmesa->screen->card->type >= NV_40) - ctx->_MaintainTexEnvProgram = GL_TRUE; + ctx->FragmentProgram._MaintainTexEnvProgram = GL_TRUE; /* Initialize the swrast */ _swrast_CreateContext( ctx ); diff --git a/src/mesa/drivers/dri/nouveau/nouveau_shader.c b/src/mesa/drivers/dri/nouveau/nouveau_shader.c index 3d5b6843a1..b6837c5de1 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_shader.c +++ b/src/mesa/drivers/dri/nouveau/nouveau_shader.c @@ -35,9 +35,10 @@ #include "enums.h" #include "extensions.h" -#include "program.h" +#include "shader/program.h" +#include "shader/prog_instruction.h" +/*#include "shader/arbprogparse.h"*/ #include "tnl/tnl.h" -#include "shader/arbprogparse.h" #include "nouveau_context.h" #include "nouveau_shader.h" diff --git a/src/mesa/drivers/dri/nouveau/nouveau_shader_0.c b/src/mesa/drivers/dri/nouveau/nouveau_shader_0.c index 7c2e2b9443..8c203cc664 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_shader_0.c +++ b/src/mesa/drivers/dri/nouveau/nouveau_shader_0.c @@ -34,9 +34,10 @@ #include "macros.h" #include "enums.h" -#include "program.h" -#include "programopt.h" -#include "program_instruction.h" +#include "shader/prog_instruction.h" +#include "shader/prog_parameter.h" +#include "shader/prog_statevars.h" +#include "shader/programopt.h" #include "nouveau_context.h" #include "nouveau_shader.h" @@ -428,8 +429,10 @@ pass0_fixup_swizzle(nvsPtr nvs, nvsFragmentHeader *parent, int fpos, if (!rec->swzconst_done) { struct gl_program *prog = &nvs->mesa.vp.Base; + GLuint swizzle; rec->swzconst_id = _mesa_add_unnamed_constant(prog->Parameters, - sc, 4); + sc, 4, &swizzle); + /* XXX what about swizzle? */ rec->swzconst_done = 1; COPY_4V(nvs->params[rec->swzconst_id].val, sc); } @@ -839,7 +842,8 @@ pass0_vp_insert_ff_clip_planes(GLcontext *ctx, nouveauShader *nvs) nvsInstruction *nvsinst; GLuint fpos = 0; nvsRegister opos, epos, eqn, mv[4]; - GLint tokens[6] = { STATE_MATRIX, STATE_MODELVIEW, 0, 0, 0, 0 }; + gl_state_index tokens[STATE_LENGTH] + = { STATE_MODELVIEW_MATRIX, 0, 0, 0, 0 }; GLint id; int i; @@ -847,7 +851,7 @@ pass0_vp_insert_ff_clip_planes(GLcontext *ctx, nouveauShader *nvs) pass0_make_reg(nvs, &opos, NVS_FILE_ATTRIB, NVS_FR_POSITION); pass0_make_reg(nvs, &epos, NVS_FILE_TEMP , -1); for (i=0; i<4; i++) { - tokens[3] = tokens[4] = i; + tokens[2] = tokens[3] = i; id = _mesa_add_state_reference(prog->Parameters, tokens); pass0_make_reg(nvs, &mv[i], NVS_FILE_CONST, id); } diff --git a/src/mesa/drivers/dri/nouveau/nouveau_shader_2.c b/src/mesa/drivers/dri/nouveau/nouveau_shader_2.c index 130ef35e57..cd27daca88 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_shader_2.c +++ b/src/mesa/drivers/dri/nouveau/nouveau_shader_2.c @@ -34,7 +34,8 @@ #include "macros.h" #include "enums.h" -#include "program.h" +#include "shader/prog_parameter.h" +#include "shader/prog_print.h" #include "nouveau_context.h" #include "nouveau_shader.h" diff --git a/src/mesa/drivers/dri/r200/r200_vertprog.c b/src/mesa/drivers/dri/r200/r200_vertprog.c index 4960d481d5..6089d617c6 100644 --- a/src/mesa/drivers/dri/r200/r200_vertprog.c +++ b/src/mesa/drivers/dri/r200/r200_vertprog.c @@ -34,14 +34,16 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. #include "macros.h" #include "enums.h" #include "program.h" +#include "shader/prog_instruction.h" +#include "shader/prog_parameter.h" +#include "shader/prog_statevars.h" +#include "shader/programopt.h" +#include "tnl/tnl.h" #include "r200_context.h" #include "r200_vertprog.h" #include "r200_ioctl.h" #include "r200_tcl.h" -#include "program_instruction.h" -#include "programopt.h" -#include "tnl/tnl.h" #if SWIZZLE_X != VSF_IN_COMPONENT_X || \ SWIZZLE_Y != VSF_IN_COMPONENT_Y || \ @@ -462,7 +464,7 @@ static GLboolean r200_translate_vertex_program(GLcontext *ctx, struct r200_verte base e isn't directly available neither. */ if ((mesa_vp->Base.OutputsWritten & (1 << VERT_RESULT_FOGC)) && !vp->fogpidx) { struct gl_program_parameter_list *paramList; - GLint tokens[6] = { STATE_FOG_PARAMS, 0, 0, 0, 0, 0 }; + gl_state_index tokens[STATE_LENGTH] = { STATE_FOG_PARAMS, 0, 0, 0, 0 }; paramList = mesa_vp->Base.Parameters; vp->fogpidx = _mesa_add_state_reference(paramList, tokens); } diff --git a/src/mesa/drivers/dri/r300/r300_context.c b/src/mesa/drivers/dri/r300/r300_context.c index 68c8f5b87d..1f8d95078f 100644 --- a/src/mesa/drivers/dri/r300/r300_context.c +++ b/src/mesa/drivers/dri/r300/r300_context.c @@ -331,7 +331,7 @@ GLboolean r300CreateContext(const __GLcontextModes * glVisual, ctx->Const.FragmentProgram.MaxNativeTexIndirections = PFS_MAX_TEX_INDIRECT; ctx->Const.FragmentProgram.MaxNativeAddressRegs = 0; /* and these are?? */ _tnl_ProgramCacheInit(ctx); - ctx->_MaintainTexEnvProgram = GL_TRUE; + ctx->FragmentProgram._MaintainTexEnvProgram = GL_TRUE; driInitExtensions(ctx, card_extensions, GL_TRUE); diff --git a/src/mesa/drivers/dri/r300/r300_fragprog.c b/src/mesa/drivers/dri/r300/r300_fragprog.c index e01f56d99d..77f95605e4 100644 --- a/src/mesa/drivers/dri/r300/r300_fragprog.c +++ b/src/mesa/drivers/dri/r300/r300_fragprog.c @@ -43,9 +43,10 @@ #include "glheader.h" #include "macros.h" #include "enums.h" +#include "shader/prog_instruction.h" +#include "shader/prog_parameter.h" +#include "shader/prog_print.h" -#include "program.h" -#include "program_instruction.h" #include "r300_context.h" #include "r300_fragprog.h" #include "r300_reg.h" diff --git a/src/mesa/drivers/dri/r300/r300_fragprog.h b/src/mesa/drivers/dri/r300/r300_fragprog.h index 73986abc3c..d883aee2d7 100644 --- a/src/mesa/drivers/dri/r300/r300_fragprog.h +++ b/src/mesa/drivers/dri/r300/r300_fragprog.h @@ -36,10 +36,11 @@ #include "glheader.h" #include "macros.h" #include "enums.h" +#include "shader/program.h" +#include "shader/prog_instruction.h" -#include "program.h" #include "r300_context.h" -#include "program_instruction.h" + #if 0 /* representation of a register for emit_arith/swizzle */ diff --git a/src/mesa/drivers/dri/r300/r300_state.c b/src/mesa/drivers/dri/r300/r300_state.c index 17658efdb2..ff3c51c5ed 100644 --- a/src/mesa/drivers/dri/r300/r300_state.c +++ b/src/mesa/drivers/dri/r300/r300_state.c @@ -46,6 +46,8 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include "api_arrayelt.h" #include "swrast/swrast.h" #include "swrast_setup/swrast_setup.h" +#include "shader/prog_parameter.h" +#include "shader/prog_statevars.h" #include "vbo/vbo.h" #include "tnl/tnl.h" #include "texformat.h" @@ -1055,8 +1057,10 @@ r300UpdateDrawBuffer(GLcontext *ctx) #endif } -static void r300FetchStateParameter(GLcontext *ctx, const enum state_index state[], - GLfloat *value) +static void +r300FetchStateParameter(GLcontext *ctx, + const gl_state_index state[STATE_LENGTH], + GLfloat *value) { r300ContextPtr r300 = R300_CONTEXT(ctx); diff --git a/src/mesa/drivers/dri/r300/r300_vertprog.c b/src/mesa/drivers/dri/r300/r300_vertprog.c index 092ebb1140..aa2f20127b 100644 --- a/src/mesa/drivers/dri/r300/r300_vertprog.c +++ b/src/mesa/drivers/dri/r300/r300_vertprog.c @@ -33,11 +33,13 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. #include "macros.h" #include "enums.h" #include "program.h" -#include "nvvertexec.h" +#include "shader/prog_instruction.h" +#include "shader/prog_parameter.h" +#include "shader/prog_statevars.h" +#include "tnl/tnl.h" #include "r300_context.h" #include "r300_program.h" -#include "program_instruction.h" #if SWIZZLE_X != VSF_IN_COMPONENT_X || \ SWIZZLE_Y != VSF_IN_COMPONENT_Y || \ @@ -103,7 +105,7 @@ int r300VertexProgUpdateParams(GLcontext *ctx, struct r300_vertex_program_cont * struct gl_program_parameter_list *paramList; if (mesa_vp->IsNVProgram) { - _mesa_init_vp_per_primitive_registers(ctx); + _mesa_load_tracked_matrices(ctx); for (pi=0; pi < MAX_NV_VERTEX_PROGRAM_PARAMS; pi++) { *dst++=ctx->VertexProgram.Parameters[pi][0]; @@ -880,7 +882,7 @@ static void position_invariant(struct gl_program *prog) struct gl_program_parameter_list *paramList; int i; - GLint tokens[6] = { STATE_MATRIX, STATE_MVP, 0, 0, 0, STATE_MATRIX }; + gl_state_index tokens[STATE_LENGTH] = { STATE_MVP_MATRIX, 0, 0, 0, 0 }; #ifdef PREFER_DP4 tokens[5] = STATE_MATRIX; diff --git a/src/mesa/drivers/dri/s3v/s3v_tritmp.h b/src/mesa/drivers/dri/s3v/s3v_tritmp.h index 16318f4c40..696fc02250 100644 --- a/src/mesa/drivers/dri/s3v/s3v_tritmp.h +++ b/src/mesa/drivers/dri/s3v/s3v_tritmp.h @@ -407,17 +407,17 @@ do { \ ctx->Texture.Unit[0]._Current->DriverData); \ deltwx = deltwy = wstart = deltdx = deltdy = dstart = 0; \ \ - u0 = (v[idx[0]].texcoord[0][0] \ + u0 = (v[idx[0]].attrib[FRAG_ATTRIB_TEX0][0] \ * (GLfloat)(t->image[0].image->Width) * 256.0); \ - u1 = (v[idx[1]].texcoord[0][0] \ + u1 = (v[idx[1]].attrib[FRAG_ATTRIB_TEX0][0] \ * (GLfloat)(t->globj->Image[0][0]->Width) * 256.0); \ - u2 = (v[idx[2]].texcoord[0][0] \ + u2 = (v[idx[2]].attrib[FRAG_ATTRIB_TEX0][0] \ * (GLfloat)(t->globj->Image[0][0]->Width) * 256.0); \ - v0 = (v[idx[0]].texcoord[0][1] \ + v0 = (v[idx[0]].attrib[FRAG_ATTRIB_TEX0][1] \ * (GLfloat)(t->globj->Image[0][0]->Height) * 256.0); \ - v1 = (v[idx[1]].texcoord[0][1] \ + v1 = (v[idx[1]].attrib[FRAG_ATTRIB_TEX0][1] \ * (GLfloat)(t->globj->Image[0][0]->Height) * 256.0); \ - v2 = (v[idx[2]].texcoord[0][1] \ + v2 = (v[idx[2]].attrib[FRAG_ATTRIB_TEX0][1] \ * (GLfloat)(t->globj->Image[0][0]->Height) * 256.0); \ \ w0 = (v[idx[0]].win[3]); \ @@ -485,23 +485,23 @@ do { \ GLfloat sxy, suv; \ int lev; \ \ - suv = (v[idx[0]].texcoord[0][0] - \ - v[idx[2]].texcoord[0][0]) * \ - (v[idx[1]].texcoord[0][1] - \ - v[idx[2]].texcoord[0][1]) - \ - (v[idx[1]].texcoord[0][0] - \ - v[idx[2]].texcoord[0][0]) * \ - (v[idx[0]].texcoord[0][1] - \ - v[idx[2]].texcoord[0][2]); \ -\ - sxy = (v[idx[0]].texcoord[0][0] - \ - v[idx[2]].texcoord[0][0]) * \ - (v[idx[1]].texcoord[0][1] - \ - v[idx[2]].texcoord[0][1]) - \ - (v[idx[1]].texcoord[0][0] - \ - v[idx[2]].texcoord[0][0]) * \ - (v[idx[0]].texcoord[0][1] - \ - v[idx[2]].texcoord[0][2]); \ + suv = (v[idx[0]].attrib[FRAG_ATTRIB_TEX0][0] - \ + v[idx[2]].attrib[FRAG_ATTRIB_TEX0][0]) * \ + (v[idx[1]].attrib[FRAG_ATTRIB_TEX0][1] - \ + v[idx[2]].attrib[FRAG_ATTRIB_TEX0][1]) - \ + (v[idx[1]].attrib[FRAG_ATTRIB_TEX0][0] - \ + v[idx[2]].attrib[FRAG_ATTRIB_TEX0][0]) * \ + (v[idx[0]].attrib[FRAG_ATTRIB_TEX0][1] - \ + v[idx[2]].attrib[FRAG_ATTRIB_TEX0][2]); \ +\ + sxy = (v[idx[0]].attrib[FRAG_ATTRIB_TEX0][0] - \ + v[idx[2]].attrib[FRAG_ATTRIB_TEX0][0]) * \ + (v[idx[1]].attrib[FRAG_ATTRIB_TEX0][1] - \ + v[idx[2]].attrib[FRAG_ATTRIB_TEX0][1]) - \ + (v[idx[1]].attrib[FRAG_ATTRIB_TEX0][0] - \ + v[idx[2]].attrib[FRAG_ATTRIB_TEX0][0]) * \ + (v[idx[0]].attrib[FRAG_ATTRIB_TEX0][1] - \ + v[idx[2]].attrib[FRAG_ATTRIB_TEX0][2]); \ \ if (sxy < 0) sxy *= -1.0; \ if (suv < 0) suv *= -1.0; \ diff --git a/src/mesa/drivers/dri/tdfx/tdfx_tris.c b/src/mesa/drivers/dri/tdfx/tdfx_tris.c index ac8daf4749..4ba2f40b9e 100644 --- a/src/mesa/drivers/dri/tdfx/tdfx_tris.c +++ b/src/mesa/drivers/dri/tdfx/tdfx_tris.c @@ -165,21 +165,21 @@ tdfx_translate_vertex( GLcontext *ctx, const tdfxVertex *src, SWvertex *dst) dst->color[2] = src->color[0]; dst->color[3] = src->color[3]; - dst->texcoord[0][0] = 1.0 / fxMesa->sScale0 * w * src->tu0; - dst->texcoord[0][1] = 1.0 / fxMesa->tScale0 * w * src->tv0; + dst->attrib[FRAG_ATTRIB_TEX0][0] = 1.0 / fxMesa->sScale0 * w * src->tu0; + dst->attrib[FRAG_ATTRIB_TEX0][1] = 1.0 / fxMesa->tScale0 * w * src->tv0; if (fxMesa->vertexFormat == TDFX_LAYOUT_PROJ1 || fxMesa->vertexFormat == TDFX_LAYOUT_PROJ2) { - dst->texcoord[0][3] = w * src->tq0; + dst->attrib[FRAG_ATTRIB_TEX0][3] = w * src->tq0; } else { - dst->texcoord[0][3] = 1.0; + dst->attrib[FRAG_ATTRIB_TEX0][3] = 1.0; } if (fxMesa->SetupIndex & TDFX_TEX1_BIT) { - dst->texcoord[1][0] = 1.0 / fxMesa->sScale1 * w * src->tu1; - dst->texcoord[1][1] = 1.0 / fxMesa->tScale1 * w * src->tv1; + dst->attrib[FRAG_ATTRIB_TEX1][0] = 1.0 / fxMesa->sScale1 * w * src->tu1; + dst->attrib[FRAG_ATTRIB_TEX1][1] = 1.0 / fxMesa->tScale1 * w * src->tv1; if (fxMesa->vertexFormat == TDFX_LAYOUT_PROJ2) { - dst->texcoord[1][3] = w * src->tq1; + dst->attrib[FRAG_ATTRIB_TEX1][3] = w * src->tq1; } else { - dst->texcoord[1][3] = 1.0; + dst->attrib[FRAG_ATTRIB_TEX1][3] = 1.0; } } } diff --git a/src/mesa/drivers/dri/trident/trident_context.h b/src/mesa/drivers/dri/trident/trident_context.h index b1e68b0166..1d3ca84400 100644 --- a/src/mesa/drivers/dri/trident/trident_context.h +++ b/src/mesa/drivers/dri/trident/trident_context.h @@ -179,7 +179,7 @@ struct trident_context { GLuint vertex_format; GLuint vertex_size; GLuint vertex_stride_shift; - char *verts; + GLubyte *verts; GLint tmu_source[2]; diff --git a/src/mesa/drivers/glslcompiler/Makefile b/src/mesa/drivers/glslcompiler/Makefile new file mode 100644 index 0000000000..858457ddd4 --- /dev/null +++ b/src/mesa/drivers/glslcompiler/Makefile @@ -0,0 +1,44 @@ +# Makefile for stand-alone GL-SL compiler + +TOP = ../../../.. + +include $(TOP)/configs/current + + +PROGRAM = glslcompiler + +OBJECTS = \ + glslcompiler.o \ + ../../glapi/glapi.o \ + ../../glapi/glthread.o \ + ../../main/dispatch.o \ + ../common/driverfuncs.o \ + ../../libmesa.a + +INCLUDES = \ + -I$(TOP)/include \ + -I$(TOP)/include/GL/internal \ + -I$(TOP)/src/mesa \ + -I$(TOP)/src/mesa/main \ + -I$(TOP)/src/mesa/glapi \ + -I$(TOP)/src/mesa/math \ + -I$(TOP)/src/mesa/transform \ + -I$(TOP)/src/mesa/shader \ + -I$(TOP)/src/mesa/swrast \ + -I$(TOP)/src/mesa/swrast_setup \ + + +default: $(PROGRAM) + $(INSTALL) $(PROGRAM) $(TOP)/bin + + +glslcompiler: $(OBJECTS) + $(CC) $(OBJECTS) -lm -lpthread -o $@ + + +glslcompiler.o: glslcompiler.c + $(CC) -c $(CFLAGS) $(INCLUDES) glslcompiler.c -o $@ + + +clean: + rm -f *.o *~ $(PROGRAM) diff --git a/src/mesa/drivers/glslcompiler/glslcompiler.c b/src/mesa/drivers/glslcompiler/glslcompiler.c new file mode 100644 index 0000000000..016b53d57a --- /dev/null +++ b/src/mesa/drivers/glslcompiler/glslcompiler.c @@ -0,0 +1,358 @@ +/* + * 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 "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" +#include "vbo/vbo.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 ); + _tnl_InvalidateState( ctx, new_state ); + _vbo_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 ) || + !_vbo_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; + + if (argc == 1) { + Usage(); + exit(0); + } + + 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/main/colortab.c b/src/mesa/main/colortab.c index d8c4136f49..610acba306 100644 --- a/src/mesa/main/colortab.c +++ b/src/mesa/main/colortab.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"), @@ -678,6 +678,10 @@ _mesa_GetColorTable( GLenum target, GLenum format, ASSERT(table); + if (table->Size <= 0) { + return; + } + switch (table->_BaseFormat) { case GL_ALPHA: { diff --git a/src/mesa/main/config.h b/src/mesa/main/config.h index 13c6281f07..8ea2d2c615 100644 --- a/src/mesa/main/config.h +++ b/src/mesa/main/config.h @@ -196,21 +196,19 @@ /** For any program target/extension */ /*@{*/ #define MAX_PROGRAM_LOCAL_PARAMS 128 /* KW: power of two */ +#define MAX_PROGRAM_ENV_PARAMS 128 #define MAX_PROGRAM_MATRICES 8 #define MAX_PROGRAM_MATRIX_STACK_DEPTH 4 #define MAX_PROGRAM_CALL_DEPTH 8 -/*@}*/ - -/** For GL_ARB_fragment_shader */ -/*@{*/ -#define MAX_FRAGMENT_UNIFORM_COMPONENTS 64 +#define MAX_PROGRAM_TEMPS 128 +#define MAX_PROGRAM_ADDRESS_REGS 2 +#define MAX_UNIFORMS 128 +#define MAX_VARYING 8 /*@}*/ /** For GL_ARB_vertex_shader */ /*@{*/ #define MAX_VERTEX_ATTRIBS 16 -#define MAX_VERTEX_UNIFORM_COMPONENTS 512 -#define MAX_VARYING_FLOATS 32 #define MAX_VERTEX_TEXTURE_IMAGE_UNITS 0 #define MAX_COMBINED_TEXTURE_IMAGE_UNITS (MAX_TEXTURE_IMAGE_UNITS + MAX_VERTEX_TEXTURE_IMAGE_UNITS) /*@}*/ @@ -218,7 +216,7 @@ /** For GL_ARB_draw_buffers */ /*@{*/ -#define MAX_DRAW_BUFFERS 1 +#define MAX_DRAW_BUFFERS 4 /*@}*/ diff --git a/src/mesa/main/context.c b/src/mesa/main/context.c index 135c814c0a..72c85de7ba 100644 --- a/src/mesa/main/context.c +++ b/src/mesa/main/context.c @@ -132,7 +132,7 @@ #include "math/m_xform.h" #include "math/mathmod.h" #endif -#include "shaderobjects.h" +#include "shader_api.h" #ifdef USE_SPARC_ASM #include "sparc/sparc.h" @@ -701,7 +701,7 @@ alloc_shared_state( GLcontext *ctx ) ss->ArrayObjects = _mesa_NewHashTable(); #if FEATURE_ARB_shader_objects - ss->GL2Objects = _mesa_NewHashTable (); + ss->ShaderObjects = _mesa_NewHashTable(); #endif ss->Default1D = (*ctx->Driver.NewTextureObject)(ctx, 0, GL_TEXTURE_1D); @@ -778,8 +778,8 @@ alloc_shared_state( GLcontext *ctx ) _mesa_DeleteHashTable (ss->ArrayObjects); #if FEATURE_ARB_shader_objects - if (ss->GL2Objects) - _mesa_DeleteHashTable (ss->GL2Objects); + if (ss->ShaderObjects) + _mesa_DeleteHashTable (ss->ShaderObjects); #endif #if FEATURE_EXT_framebuffer_object @@ -873,13 +873,22 @@ delete_arrayobj_cb(GLuint id, void *data, void *userData) } /** - * Callback for deleting an shader object. Called by _mesa_HashDeleteAll(). + * Callback for deleting shader and shader programs objects. + * Called by _mesa_HashDeleteAll(). */ static void -delete_shaderobj_cb(GLuint id, void *data, void *userData) +delete_shader_cb(GLuint id, void *data, void *userData) { - /* XXX probably need to fix this */ - _mesa_free(data); + GLcontext *ctx = (GLcontext *) userData; + struct gl_shader *sh = (struct gl_shader *) data; + if (sh->Type == GL_FRAGMENT_SHADER || sh->Type == GL_VERTEX_SHADER) { + _mesa_free_shader(ctx, sh); + } + else { + struct gl_shader_program *shProg = (struct gl_shader_program *) data; + ASSERT(shProg->Type == GL_SHADER_PROGRAM); + _mesa_free_shader_program(ctx, shProg); + } } @@ -944,8 +953,8 @@ free_shared_state( GLcontext *ctx, struct gl_shared_state *ss ) _mesa_DeleteHashTable(ss->ArrayObjects); #if FEATURE_ARB_shader_objects - _mesa_HashDeleteAll(ss->GL2Objects, delete_shaderobj_cb, ctx); - _mesa_DeleteHashTable(ss->GL2Objects); + _mesa_HashDeleteAll(ss->ShaderObjects, delete_shader_cb, ctx); + _mesa_DeleteHashTable(ss->ShaderObjects); #endif #if FEATURE_EXT_framebuffer_object @@ -963,7 +972,7 @@ free_shared_state( GLcontext *ctx, struct gl_shared_state *ss ) * Initialize fields of gl_current_attrib (aka ctx->Current.*) */ static void -_mesa_init_current( GLcontext *ctx ) +_mesa_init_current(GLcontext *ctx) { GLuint i; @@ -1005,7 +1014,7 @@ init_natives(struct gl_program_constants *prog) * some of these values (such as number of texture units). */ static void -_mesa_init_constants( GLcontext *ctx ) +_mesa_init_constants(GLcontext *ctx) { assert(ctx); @@ -1058,9 +1067,10 @@ _mesa_init_constants( GLcontext *ctx ) ctx->Const.VertexProgram.MaxLocalParams = MAX_PROGRAM_LOCAL_PARAMS; ctx->Const.VertexProgram.MaxEnvParams = MAX_NV_VERTEX_PROGRAM_PARAMS; ctx->Const.VertexProgram.MaxAddressRegs = MAX_VERTEX_PROGRAM_ADDRESS_REGS; - ctx->Const.VertexProgram.MaxUniformComponents = MAX_VERTEX_UNIFORM_COMPONENTS; + ctx->Const.VertexProgram.MaxUniformComponents = 4 * MAX_UNIFORMS; init_natives(&ctx->Const.VertexProgram); #endif + #if FEATURE_ARB_fragment_program ctx->Const.FragmentProgram.MaxInstructions = MAX_NV_FRAGMENT_PROGRAM_INSTRUCTIONS; ctx->Const.FragmentProgram.MaxAluInstructions = MAX_FRAGMENT_PROGRAM_ALU_INSTRUCTIONS; @@ -1072,7 +1082,7 @@ _mesa_init_constants( GLcontext *ctx ) ctx->Const.FragmentProgram.MaxLocalParams = MAX_PROGRAM_LOCAL_PARAMS; ctx->Const.FragmentProgram.MaxEnvParams = MAX_NV_FRAGMENT_PROGRAM_PARAMS; ctx->Const.FragmentProgram.MaxAddressRegs = MAX_FRAGMENT_PROGRAM_ADDRESS_REGS; - ctx->Const.FragmentProgram.MaxUniformComponents = MAX_FRAGMENT_UNIFORM_COMPONENTS; + ctx->Const.FragmentProgram.MaxUniformComponents = 4 * MAX_UNIFORMS; init_natives(&ctx->Const.FragmentProgram); #endif ctx->Const.MaxProgramMatrices = MAX_PROGRAM_MATRICES; @@ -1095,7 +1105,7 @@ _mesa_init_constants( GLcontext *ctx ) #if FEATURE_ARB_vertex_shader ctx->Const.MaxVertexTextureImageUnits = MAX_VERTEX_TEXTURE_IMAGE_UNITS; - ctx->Const.MaxVaryingFloats = MAX_VARYING_FLOATS; + ctx->Const.MaxVarying = MAX_VARYING; #endif /* sanity checks */ @@ -1103,6 +1113,11 @@ _mesa_init_constants( GLcontext *ctx ) ctx->Const.MaxTextureCoordUnits)); ASSERT(ctx->Const.FragmentProgram.MaxLocalParams <= MAX_PROGRAM_LOCAL_PARAMS); ASSERT(ctx->Const.VertexProgram.MaxLocalParams <= MAX_PROGRAM_LOCAL_PARAMS); + + ASSERT(MAX_NV_FRAGMENT_PROGRAM_TEMPS <= MAX_PROGRAM_TEMPS); + ASSERT(MAX_NV_VERTEX_PROGRAM_TEMPS <= MAX_PROGRAM_TEMPS); + ASSERT(MAX_NV_VERTEX_PROGRAM_INPUTS <= VERT_ATTRIB_MAX); + ASSERT(MAX_NV_VERTEX_PROGRAM_OUTPUTS <= VERT_RESULT_MAX); } @@ -1144,7 +1159,7 @@ check_context_limits(GLcontext *ctx) * functions for the more complex data structures. */ static GLboolean -init_attrib_groups( GLcontext *ctx ) +init_attrib_groups(GLcontext *ctx) { assert(ctx); @@ -1180,7 +1195,7 @@ init_attrib_groups( GLcontext *ctx ) _mesa_init_query( ctx ); _mesa_init_rastpos( ctx ); _mesa_init_scissor( ctx ); - _mesa_init_shaderobjects (ctx); + _mesa_init_shader_state( ctx ); _mesa_init_stencil( ctx ); _mesa_init_transform( ctx ); _mesa_init_varray( ctx ); @@ -1267,11 +1282,11 @@ alloc_dispatch_table(void) * \param driverContext pointer to driver-specific context data */ GLboolean -_mesa_initialize_context( GLcontext *ctx, - const GLvisual *visual, - GLcontext *share_list, - const struct dd_function_table *driverFunctions, - void *driverContext ) +_mesa_initialize_context(GLcontext *ctx, + const GLvisual *visual, + GLcontext *share_list, + const struct dd_function_table *driverFunctions, + void *driverContext) { ASSERT(driverContext); assert(driverFunctions->NewTextureObject); @@ -1340,12 +1355,14 @@ _mesa_initialize_context( GLcontext *ctx, ctx->TnlModule.SwapCount = 0; #endif - ctx->_MaintainTexEnvProgram = (_mesa_getenv("MESA_TEX_PROG") != NULL); - ctx->_UseTexEnvProgram = ctx->_MaintainTexEnvProgram; - - ctx->_MaintainTnlProgram = (_mesa_getenv("MESA_TNL_PROG") != NULL); - if (ctx->_MaintainTnlProgram) - ctx->_MaintainTexEnvProgram = 1; /* this is required... */ + ctx->VertexProgram._MaintainTnlProgram + = (_mesa_getenv("MESA_TNL_PROG") != NULL); + if (ctx->VertexProgram._MaintainTnlProgram) + /* this is required... */ + ctx->FragmentProgram._MaintainTexEnvProgram = GL_TRUE; + else + ctx->FragmentProgram._MaintainTexEnvProgram + = (_mesa_getenv("MESA_TEX_PROG") != NULL); ctx->FirstTimeCurrent = GL_TRUE; @@ -1368,11 +1385,10 @@ _mesa_initialize_context( GLcontext *ctx, * \return pointer to a new __GLcontextRec or NULL if error. */ GLcontext * -_mesa_create_context( const GLvisual *visual, - GLcontext *share_list, - const struct dd_function_table *driverFunctions, - void *driverContext ) - +_mesa_create_context(const GLvisual *visual, + GLcontext *share_list, + const struct dd_function_table *driverFunctions, + void *driverContext) { GLcontext *ctx; @@ -1423,6 +1439,7 @@ _mesa_free_context_data( GLcontext *ctx ) _mesa_free_viewport_data( ctx ); _mesa_free_colortables_data( ctx ); _mesa_free_program_data(ctx); + _mesa_free_shader_state(ctx); _mesa_free_query_data(ctx); #if FEATURE_ARB_vertex_buffer_object @@ -1696,6 +1713,30 @@ _mesa_make_current( GLcontext *newCtx, GLframebuffer *drawBuffer, } } +#if 0 /** XXX enable this someday */ + if (oldCtx && oldCtx != newCtx) { + /* unbind old context's draw/read buffers */ + if (oldCtx->DrawBuffer && oldCtx->DrawBuffer->Name == 0) { + oldCtx->DrawBuffer->RefCount--; + oldCtx->DrawBuffer = NULL; + } + if (oldCtx->ReadBuffer && oldCtx->ReadBuffer->Name == 0) { + oldCtx->ReadBuffer->RefCount--; + oldCtx->ReadBuffer = NULL; + } + if (oldCtx->WinSysDrawBuffer) { + ASSERT(oldCtx->WinSysDrawBuffer->Name == 0); + oldCtx->WinSysDrawBuffer->RefCount--; + oldCtx->WinSysDrawBuffer = NULL; + } + if (oldCtx->WinSysReadBuffer) { + ASSERT(oldCtx->WinSysReadBuffer->Name == 0); + oldCtx->WinSysReadBuffer->RefCount--; + oldCtx->WinSysReadBuffer = NULL; + } + } +#endif + /* We used to call _glapi_check_multithread() here. Now do it in drivers */ _glapi_set_context((void *) newCtx); ASSERT(_mesa_get_current_context() == newCtx); @@ -1813,12 +1854,11 @@ _mesa_share_state(GLcontext *ctx, GLcontext *ctxToShare) /** - * Get current context for the calling thread. - * - * \return pointer to the current GL context. + * \return pointer to the current GL context for this thread. * * Calls _glapi_get_context(). This isn't the fastest way to get the current - * context. If you need speed, see the #GET_CURRENT_CONTEXT macro in context.h. + * context. If you need speed, see the #GET_CURRENT_CONTEXT macro in + * context.h. */ GLcontext * _mesa_get_current_context( void ) @@ -1826,6 +1866,7 @@ _mesa_get_current_context( void ) return (GLcontext *) _glapi_get_context(); } + /** * Get context's current API dispatch table. * @@ -1865,7 +1906,7 @@ _mesa_get_dispatch(GLcontext *ctx) * This is called via _mesa_error(). */ void -_mesa_record_error( GLcontext *ctx, GLenum error ) +_mesa_record_error(GLcontext *ctx, GLenum error) { if (!ctx) return; @@ -1876,10 +1917,11 @@ _mesa_record_error( GLcontext *ctx, GLenum error ) /* Call device driver's error handler, if any. This is used on the Mac. */ if (ctx->Driver.Error) { - (*ctx->Driver.Error)( ctx ); + ctx->Driver.Error(ctx); } } + /** * Execute glFinish(). * @@ -1887,15 +1929,16 @@ _mesa_record_error( GLcontext *ctx, GLenum error ) * dd_function_table::Finish driver callback, if not NULL. */ void GLAPIENTRY -_mesa_Finish( void ) +_mesa_Finish(void) { GET_CURRENT_CONTEXT(ctx); ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); if (ctx->Driver.Finish) { - (*ctx->Driver.Finish)( ctx ); + ctx->Driver.Finish(ctx); } } + /** * Execute glFlush(). * @@ -1903,12 +1946,12 @@ _mesa_Finish( void ) * dd_function_table::Flush driver callback, if not NULL. */ void GLAPIENTRY -_mesa_Flush( void ) +_mesa_Flush(void) { GET_CURRENT_CONTEXT(ctx); ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); if (ctx->Driver.Flush) { - (*ctx->Driver.Flush)( ctx ); + ctx->Driver.Flush(ctx); } } diff --git a/src/mesa/main/dd.h b/src/mesa/main/dd.h index 1de2542bee..88f33943b3 100644 --- a/src/mesa/main/dd.h +++ b/src/mesa/main/dd.h @@ -570,9 +570,9 @@ struct dd_function_table { /** Notify driver that a program string has been specified. */ void (*ProgramStringNotify)(GLcontext *ctx, GLenum target, struct gl_program *prog); - /** Get value of a fragment program register during program execution. */ - void (*GetFragmentProgramRegister)(GLcontext *ctx, enum register_file file, - GLuint index, GLfloat val[4]); + /** Get value of a program register during program execution. */ + void (*GetProgramRegister)(GLcontext *ctx, enum register_file file, + GLuint index, GLfloat val[4]); /** Query if program can be loaded onto hardware */ GLboolean (*IsProgramNative)(GLcontext *ctx, GLenum target, @@ -821,6 +821,58 @@ struct dd_function_table { void (*BindArrayObject)(GLcontext *ctx, struct gl_array_object *obj); /*@}*/ + /** + * \name GLSL-related functions (ARB extensions and OpenGL 2.x) + */ + /*@{*/ + void (*AttachShader)(GLcontext *ctx, GLuint program, GLuint shader); + void (*BindAttribLocation)(GLcontext *ctx, GLuint program, GLuint index, + const GLcharARB *name); + void (*CompileShader)(GLcontext *ctx, GLuint shader); + GLuint (*CreateShader)(GLcontext *ctx, GLenum type); + GLuint (*CreateProgram)(GLcontext *ctx); + void (*DeleteProgram2)(GLcontext *ctx, GLuint program); + void (*DeleteShader)(GLcontext *ctx, GLuint shader); + void (*DetachShader)(GLcontext *ctx, GLuint program, GLuint shader); + void (*GetActiveAttrib)(GLcontext *ctx, GLuint program, GLuint index, + GLsizei maxLength, GLsizei * length, GLint * size, + GLenum * type, GLcharARB * name); + void (*GetActiveUniform)(GLcontext *ctx, GLuint program, GLuint index, + GLsizei maxLength, GLsizei *length, GLint *size, + GLenum *type, GLcharARB *name); + void (*GetAttachedShaders)(GLcontext *ctx, GLuint program, GLsizei maxCount, + GLsizei *count, GLuint *obj); + GLint (*GetAttribLocation)(GLcontext *ctx, GLuint program, + const GLcharARB *name); + GLuint (*GetHandle)(GLcontext *ctx, GLenum pname); + void (*GetProgramiv)(GLcontext *ctx, GLuint program, + GLenum pname, GLint *params); + void (*GetProgramInfoLog)(GLcontext *ctx, GLuint program, GLsizei bufSize, + GLsizei *length, GLchar *infoLog); + void (*GetShaderiv)(GLcontext *ctx, GLuint shader, + GLenum pname, GLint *params); + void (*GetShaderInfoLog)(GLcontext *ctx, GLuint shader, GLsizei bufSize, + GLsizei *length, GLchar *infoLog); + void (*GetShaderSource)(GLcontext *ctx, GLuint shader, GLsizei maxLength, + GLsizei *length, GLcharARB *sourceOut); + void (*GetUniformfv)(GLcontext *ctx, GLuint program, GLint location, + GLfloat *params); + GLint (*GetUniformLocation)(GLcontext *ctx, GLuint program, + const GLcharARB *name); + GLboolean (*IsProgram)(GLcontext *ctx, GLuint name); + GLboolean (*IsShader)(GLcontext *ctx, GLuint name); + void (*LinkProgram)(GLcontext *ctx, GLuint program); + void (*ShaderSource)(GLcontext *ctx, GLuint shader, const GLchar *source); + void (*Uniform)(GLcontext *ctx, GLint location, GLsizei count, + const GLvoid *values, GLenum type); + void (*UniformMatrix)(GLcontext *ctx, GLint cols, GLint rows, + GLenum matrixType, GLint location, GLsizei count, + GLboolean transpose, const GLfloat *values); + void (*UseProgram)(GLcontext *ctx, GLuint program); + void (*ValidateProgram)(GLcontext *ctx, GLuint program); + /* XXX many more to come */ + /*@}*/ + /** * \name Support for multiple T&L engines diff --git a/src/mesa/main/get.c b/src/mesa/main/get.c index 4eda349134..eb81ee4a52 100644 --- a/src/mesa/main/get.c +++ b/src/mesa/main/get.c @@ -1878,7 +1878,7 @@ _mesa_GetBooleanv( GLenum pname, GLboolean *params ) break; case GL_MAX_VARYING_FLOATS_ARB: CHECK_EXT1(ARB_vertex_shader, "GetBooleanv"); - params[0] = INT_TO_BOOLEAN(ctx->Const.MaxVaryingFloats); + params[0] = INT_TO_BOOLEAN(ctx->Const.MaxVarying * 4); break; case GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS_ARB: CHECK_EXT1(ARB_vertex_shader, "GetBooleanv"); @@ -1888,6 +1888,10 @@ _mesa_GetBooleanv( GLenum pname, GLboolean *params ) CHECK_EXT1(ARB_vertex_shader, "GetBooleanv"); params[0] = INT_TO_BOOLEAN(MAX_COMBINED_TEXTURE_IMAGE_UNITS); break; + case GL_CURRENT_PROGRAM: + CHECK_EXT1(ARB_shader_objects, "GetBooleanv"); + params[0] = INT_TO_BOOLEAN(ctx->Shader.CurrentProgram ? ctx->Shader.CurrentProgram->Name : 0); + break; default: _mesa_error(ctx, GL_INVALID_ENUM, "glGetBooleanv(pname=0x%x)", pname); } @@ -3705,7 +3709,7 @@ _mesa_GetFloatv( GLenum pname, GLfloat *params ) break; case GL_MAX_VARYING_FLOATS_ARB: CHECK_EXT1(ARB_vertex_shader, "GetFloatv"); - params[0] = (GLfloat)(ctx->Const.MaxVaryingFloats); + params[0] = (GLfloat)(ctx->Const.MaxVarying * 4); break; case GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS_ARB: CHECK_EXT1(ARB_vertex_shader, "GetFloatv"); @@ -3715,6 +3719,10 @@ _mesa_GetFloatv( GLenum pname, GLfloat *params ) CHECK_EXT1(ARB_vertex_shader, "GetFloatv"); params[0] = (GLfloat)(MAX_COMBINED_TEXTURE_IMAGE_UNITS); break; + case GL_CURRENT_PROGRAM: + CHECK_EXT1(ARB_shader_objects, "GetFloatv"); + params[0] = (GLfloat)(ctx->Shader.CurrentProgram ? ctx->Shader.CurrentProgram->Name : 0); + break; default: _mesa_error(ctx, GL_INVALID_ENUM, "glGetFloatv(pname=0x%x)", pname); } @@ -5532,7 +5540,7 @@ _mesa_GetIntegerv( GLenum pname, GLint *params ) break; case GL_MAX_VARYING_FLOATS_ARB: CHECK_EXT1(ARB_vertex_shader, "GetIntegerv"); - params[0] = ctx->Const.MaxVaryingFloats; + params[0] = ctx->Const.MaxVarying * 4; break; case GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS_ARB: CHECK_EXT1(ARB_vertex_shader, "GetIntegerv"); @@ -5542,6 +5550,10 @@ _mesa_GetIntegerv( GLenum pname, GLint *params ) CHECK_EXT1(ARB_vertex_shader, "GetIntegerv"); params[0] = MAX_COMBINED_TEXTURE_IMAGE_UNITS; break; + case GL_CURRENT_PROGRAM: + CHECK_EXT1(ARB_shader_objects, "GetIntegerv"); + params[0] = ctx->Shader.CurrentProgram ? ctx->Shader.CurrentProgram->Name : 0; + break; default: _mesa_error(ctx, GL_INVALID_ENUM, "glGetIntegerv(pname=0x%x)", pname); } diff --git a/src/mesa/main/get_gen.py b/src/mesa/main/get_gen.py index 0b6cd3e5c5..33be768999 100644 --- a/src/mesa/main/get_gen.py +++ b/src/mesa/main/get_gen.py @@ -989,11 +989,18 @@ StateVars = [ ["ctx->Const.VertexProgram.MaxUniformComponents"], "", ["ARB_vertex_shader"] ), ( "GL_MAX_VARYING_FLOATS_ARB", GLint, - ["ctx->Const.MaxVaryingFloats"], "", ["ARB_vertex_shader"] ), + ["ctx->Const.MaxVarying * 4"], "", ["ARB_vertex_shader"] ), ( "GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS_ARB", GLint, ["ctx->Const.MaxVertexTextureImageUnits"], "", ["ARB_vertex_shader"] ), ( "GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS_ARB", GLint, - ["MAX_COMBINED_TEXTURE_IMAGE_UNITS"], "", ["ARB_vertex_shader"] ) + ["MAX_COMBINED_TEXTURE_IMAGE_UNITS"], "", ["ARB_vertex_shader"] ), + + # GL_ARB_shader_objects + # Actually, this token isn't part of GL_ARB_shader_objects, but is + # close enough for now. + ( "GL_CURRENT_PROGRAM", GLint, + ["ctx->Shader.CurrentProgram ? ctx->Shader.CurrentProgram->Name : 0"], + "", ["ARB_shader_objects"] ) ] diff --git a/src/mesa/main/getstring.c b/src/mesa/main/getstring.c index 0c925ed761..973649da0d 100644 --- a/src/mesa/main/getstring.c +++ b/src/mesa/main/getstring.c @@ -54,8 +54,8 @@ _mesa_GetString( GLenum name ) static const char *version_1_3 = "1.3 Mesa " MESA_VERSION_STRING; static const char *version_1_4 = "1.4 Mesa " MESA_VERSION_STRING; static const char *version_1_5 = "1.5 Mesa " MESA_VERSION_STRING; - static const char *version_2_0 = "1.5 Mesa " MESA_VERSION_STRING; - static const char *version_2_1 = "1.5 Mesa " MESA_VERSION_STRING; + static const char *version_2_0 = "2.0 Mesa " MESA_VERSION_STRING; + static const char *version_2_1 = "2.1 Mesa " MESA_VERSION_STRING; #if FEATURE_ARB_shading_language_100 static const char *sl_version_110 = "1.10 Mesa " MESA_VERSION_STRING; diff --git a/src/mesa/main/imports.c b/src/mesa/main/imports.c index 890d1a4e32..e2d44fa07c 100644 --- a/src/mesa/main/imports.c +++ b/src/mesa/main/imports.c @@ -849,15 +849,23 @@ _mesa_strncmp( const char *s1, const char *s2, size_t n ) return strncmp(s1, s2, n); } -/** Implemented using _mesa_malloc() and _mesa_strcpy */ +/** + * Implemented using _mesa_malloc() and _mesa_strcpy. + * Note that NULL is handled accordingly. + */ char * _mesa_strdup( const char *s ) { - size_t l = _mesa_strlen(s); - char *s2 = (char *) _mesa_malloc(l + 1); - if (s2) - _mesa_strcpy(s2, s); - return s2; + if (s) { + size_t l = _mesa_strlen(s); + char *s2 = (char *) _mesa_malloc(l + 1); + if (s2) + _mesa_strcpy(s2, s); + return s2; + } + else { + return NULL; + } } /** Wrapper around atoi() */ diff --git a/src/mesa/main/matrix.c b/src/mesa/main/matrix.c index b2aa83e189..0f96f94909 100644 --- a/src/mesa/main/matrix.c +++ b/src/mesa/main/matrix.c @@ -1,8 +1,8 @@ /* * Mesa 3-D graphics library - * Version: 6.3 + * Version: 6.5.3 * - * Copyright (C) 1999-2005 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"), @@ -230,7 +230,7 @@ void GLAPIENTRY _mesa_PushMatrix( void ) { GET_CURRENT_CONTEXT(ctx); - struct matrix_stack *stack = ctx->CurrentStack; + struct gl_matrix_stack *stack = ctx->CurrentStack; ASSERT_OUTSIDE_BEGIN_END(ctx); if (MESA_VERBOSE&VERBOSE_API) @@ -270,7 +270,7 @@ void GLAPIENTRY _mesa_PopMatrix( void ) { GET_CURRENT_CONTEXT(ctx); - struct matrix_stack *stack = ctx->CurrentStack; + struct gl_matrix_stack *stack = ctx->CurrentStack; ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); if (MESA_VERBOSE&VERBOSE_API) @@ -766,7 +766,7 @@ void _mesa_update_modelview_project( GLcontext *ctx, GLuint new_state ) * initialize it. */ static void -init_matrix_stack( struct matrix_stack *stack, +init_matrix_stack( struct gl_matrix_stack *stack, GLuint maxDepth, GLuint dirtyFlag ) { GLuint i; @@ -792,7 +792,7 @@ init_matrix_stack( struct matrix_stack *stack, * frees the array. */ static void -free_matrix_stack( struct matrix_stack *stack ) +free_matrix_stack( struct gl_matrix_stack *stack ) { GLuint i; for (i = 0; i < stack->MaxDepth; i++) { diff --git a/src/mesa/main/mtypes.h b/src/mesa/main/mtypes.h index df77c6cbf9..828b0f2384 100644 --- a/src/mesa/main/mtypes.h +++ b/src/mesa/main/mtypes.h @@ -7,9 +7,9 @@ /* * Mesa 3-D graphics library - * Version: 6.5 + * 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"), @@ -45,6 +45,12 @@ /** + * Special, internal token + */ +#define GL_SHADER_PROGRAM 0x9999 + + +/** * Color channel data type. */ #if CHAN_BITS == 8 @@ -213,22 +219,6 @@ enum #define VERT_BIT_GENERIC(g) (1 << (VERT_ATTRIB_GENERIC0 + (g))) /*@}*/ -/** - * GLSL allows shader writers to allocate vertex result attributes (varyings) in - * single float component granularity. This is in contrast to vertex / fragment - * programs, where result attributes (actually texcoords) were allocated - * in 4-component vectors of floats granularity. - * For performance reasons, it would be optimal to stick with this scheme on a scalar - * processor. Varyings will likely be allocated as 3-component vectors, so statistically - * we win 2 floats. - * The constant VARYINGS_PER_VECTOR tells us how much of float components we pack into - * one result vector. For scalar processor it would be 1, for vector processor - 4. - * - * NOTE: Currently we pack varyings into vertex attributes. - */ -#define VARYINGS_PER_VECTOR 2 -#define VARYING_EMIT_STYLE EMIT_2F -#define MAX_VARYING_VECTORS ((MAX_VARYING_FLOATS + VARYINGS_PER_VECTOR - 1) / VARYINGS_PER_VECTOR) /** * Indexes for vertex program result attributes @@ -250,7 +240,8 @@ enum #define VERT_RESULT_BFC0 13 #define VERT_RESULT_BFC1 14 #define VERT_RESULT_EDGE 15 -#define VERT_RESULT_MAX 16 +#define VERT_RESULT_VAR0 16 /**< shader varying */ +#define VERT_RESULT_MAX (VERT_RESULT_VAR0 + MAX_VARYING) /*@}*/ @@ -271,7 +262,8 @@ enum FRAG_ATTRIB_TEX5 = 9, FRAG_ATTRIB_TEX6 = 10, FRAG_ATTRIB_TEX7 = 11, - FRAG_ATTRIB_MAX = 12 + FRAG_ATTRIB_VAR0 = 12, /**< shader varying */ + FRAG_ATTRIB_MAX = (FRAG_ATTRIB_VAR0 + MAX_VARYING) }; /** @@ -290,6 +282,10 @@ enum #define FRAG_BIT_TEX5 (1 << FRAG_ATTRIB_TEX5) #define FRAG_BIT_TEX6 (1 << FRAG_ATTRIB_TEX6) #define FRAG_BIT_TEX7 (1 << FRAG_ATTRIB_TEX7) +#define FRAG_BIT_VAR0 (1 << FRAG_ATTRIB_VAR0) + +#define FRAG_BIT_TEX(U) (FRAG_BIT_TEX0 << (U)) +#define FRAG_BIT_VAR(V) (FRAG_BIT_VAR0 << (V)) #define FRAG_BITS_TEX_ANY (FRAG_BIT_TEX0| \ FRAG_BIT_TEX1| \ @@ -305,12 +301,14 @@ enum /** * Fragment program results */ -/*@{*/ -#define FRAG_RESULT_COLR 0 -#define FRAG_RESULT_COLH 1 -#define FRAG_RESULT_DEPR 2 -#define FRAG_RESULT_MAX 3 -/*@}*/ +enum +{ + FRAG_RESULT_COLR = 0, + FRAG_RESULT_COLH = 1, + FRAG_RESULT_DEPR = 2, + FRAG_RESULT_DATA0 = 3, + FRAG_RESULT_MAX = (FRAG_RESULT_DATA0 + MAX_DRAW_BUFFERS) +}; /** @@ -1829,22 +1827,31 @@ struct gl_evaluators /** * Names of the various vertex/fragment program register files, etc. + * * NOTE: first four tokens must fit into 2 bits (see t_vb_arbprogram.c) * All values should fit in a 4-bit field. + * + * NOTE: PROGRAM_ENV_PARAM, PROGRAM_STATE_VAR, PROGRAM_NAMED_PARAM, + * PROGRAM_CONSTANT, and PROGRAM_UNIFORM can all be considered to + * be "uniform" variables since they can only be set outside glBegin/End. + * They're also all stored in the same Parameters array. */ enum register_file { - PROGRAM_TEMPORARY = 0, - PROGRAM_LOCAL_PARAM = 1, - PROGRAM_ENV_PARAM = 2, - PROGRAM_STATE_VAR = 3, - PROGRAM_INPUT = 4, - PROGRAM_OUTPUT = 5, - PROGRAM_NAMED_PARAM = 6, - PROGRAM_CONSTANT = 7, - PROGRAM_WRITE_ONLY = 8, - PROGRAM_ADDRESS = 9, - PROGRAM_UNDEFINED = 10, /* invalid value */ + PROGRAM_TEMPORARY = 0, /**< machine->Temporary[] */ + PROGRAM_LOCAL_PARAM = 1, /**< gl_program->LocalParams[] */ + PROGRAM_ENV_PARAM = 2, /**< gl_program->Parameters[] */ + PROGRAM_STATE_VAR = 3, /**< gl_program->Parameters[] */ + PROGRAM_INPUT = 4, /**< machine->Inputs[] */ + PROGRAM_OUTPUT = 5, /**< machine->Outputs[] */ + PROGRAM_NAMED_PARAM = 6, /**< gl_program->Parameters[] */ + PROGRAM_CONSTANT = 7, /**< gl_program->Parameters[] */ + PROGRAM_UNIFORM = 8, /**< gl_program->Parameters[] */ + PROGRAM_VARYING = 9, /**< machine->Inputs[]/Outputs[] */ + PROGRAM_WRITE_ONLY = 10, /**< A dummy, write-only register */ + PROGRAM_ADDRESS = 11, /**< machine->AddressReg */ + PROGRAM_SAMPLER = 12, /**< for shader samplers, compile-time only */ + PROGRAM_UNDEFINED = 13, /**< Invalid value */ PROGRAM_FILE_MAX }; @@ -1860,22 +1867,28 @@ struct gl_program_parameter_list; struct gl_program { GLuint Id; - GLubyte *String; /**< Null-terminated program text */ + GLubyte *String; /**< Null-terminated program text */ GLint RefCount; - GLenum Target; - GLenum Format; /**< String encoding format */ + GLenum Target; /**< GL_VERTEX/FRAGMENT_PROGRAM_ARB, GL_FRAGMENT_PROGRAM_NV */ + GLenum Format; /**< String encoding format */ GLboolean Resident; struct prog_instruction *Instructions; - GLbitfield InputsRead; /* Bitmask of which input regs are read */ - GLbitfield OutputsWritten; /* Bitmask of which output regs are written to */ + GLbitfield InputsRead; /**< Bitmask of which input regs are read */ + GLbitfield OutputsWritten; /**< Bitmask of which output regs are written to */ + GLbitfield TexturesUsed[MAX_TEXTURE_IMAGE_UNITS]; /**< TEXTURE_x_BIT bitmask */ /** Named parameters, constants, etc. from program text */ struct gl_program_parameter_list *Parameters; /** Numbered local parameters */ GLfloat LocalParams[MAX_PROGRAM_LOCAL_PARAMS][4]; + /** Vertex/fragment shader varying vars */ + struct gl_program_parameter_list *Varying; + /** Vertex program user-defined attributes */ + struct gl_program_parameter_list *Attributes; + /** Logical counts */ /*@{*/ GLuint NumInstructions; @@ -1883,6 +1896,9 @@ struct gl_program GLuint NumParameters; GLuint NumAttributes; GLuint NumAddressRegs; + GLuint NumAluInstructions; + GLuint NumTexInstructions; + GLuint NumTexIndirections; /*@}*/ /** Native, actual h/w counts */ /*@{*/ @@ -1891,6 +1907,9 @@ struct gl_program GLuint NumNativeParameters; GLuint NumNativeAttributes; GLuint NumNativeAddressRegs; + GLuint NumNativeAluInstructions; + GLuint NumNativeTexInstructions; + GLuint NumNativeTexIndirections; /*@}*/ }; @@ -1909,13 +1928,6 @@ struct gl_vertex_program struct gl_fragment_program { struct gl_program Base; /**< base class */ - GLbitfield TexturesUsed[MAX_TEXTURE_IMAGE_UNITS]; /**< TEXTURE_x_BIT bitmask */ - GLuint NumAluInstructions; /**< GL_ARB_fragment_program */ - GLuint NumTexInstructions; - GLuint NumTexIndirections; - GLuint NumNativeAluInstructions; /**< GL_ARB_fragment_program */ - GLuint NumNativeTexInstructions; - GLuint NumNativeTexIndirections; GLenum FogOption; GLboolean UsesKill; }; @@ -1940,16 +1952,24 @@ struct gl_vertex_program_state GLboolean _Enabled; /**< Enabled and valid program? */ GLboolean PointSizeEnabled; /**< GL_VERTEX_PROGRAM_POINT_SIZE_ARB/NV */ GLboolean TwoSideEnabled; /**< GL_VERTEX_PROGRAM_TWO_SIDE_ARB/NV */ - struct gl_vertex_program *Current; /**< ptr to currently bound program */ - const struct gl_vertex_program *_Current; /**< ptr to currently bound - program, including internal - (t_vp_build.c) programs */ + struct gl_vertex_program *Current; /**< user-bound vertex program */ - GLfloat Parameters[MAX_NV_VERTEX_PROGRAM_PARAMS][4]; /**< Env params */ + /** Currently enabled and valid program (including internal programs + * and compiled shader programs). + */ + struct gl_vertex_program *_Current; + + GLfloat Parameters[MAX_PROGRAM_ENV_PARAMS][4]; /**< Env params */ /* For GL_NV_vertex_program only: */ - GLenum TrackMatrix[MAX_NV_VERTEX_PROGRAM_PARAMS / 4]; - GLenum TrackMatrixTransform[MAX_NV_VERTEX_PROGRAM_PARAMS / 4]; + GLenum TrackMatrix[MAX_PROGRAM_ENV_PARAMS / 4]; + GLenum TrackMatrixTransform[MAX_PROGRAM_ENV_PARAMS / 4]; + + /** Should fixed-function T&L be implemented with a vertex prog? */ + GLboolean _MaintainTnlProgram; + + /** Program to emulate fixed-function T&L (see above) */ + struct gl_vertex_program *_TnlProgram; #if FEATURE_MESA_program_debug GLprogramcallbackMESA Callback; @@ -1967,11 +1987,20 @@ struct gl_fragment_program_state { GLboolean Enabled; /**< User-set fragment program enable flag */ GLboolean _Enabled; /**< Fragment program enabled and valid? */ - GLboolean _Active; /**< Is a user program or internal program active? */ - struct gl_fragment_program *Current; /**< User-bound program */ - const struct gl_fragment_program *_Current; /**< currently active program - (including internal programs) */ - GLfloat Parameters[MAX_NV_FRAGMENT_PROGRAM_PARAMS][4]; /**< Env params */ + struct gl_fragment_program *Current; /**< User-bound fragment program */ + + /** Currently enabled and valid program (including internal programs + * and compiled shader programs). + */ + struct gl_fragment_program *_Current; + + GLfloat Parameters[MAX_PROGRAM_ENV_PARAMS][4]; /**< Env params */ + + /** Should fixed-function texturing be implemented with a fragment prog? */ + GLboolean _MaintainTexEnvProgram; + + /** Program to emulate fixed-function texture env/combine (see above) */ + struct gl_fragment_program *_TexEnvProgram; #if FEATURE_MESA_program_debug GLprogramcallbackMESA Callback; @@ -2048,14 +2077,60 @@ struct gl_query_state }; + /** - * Context state for vertex/fragment shaders. + * A GLSL shader object. */ -struct gl_shader_objects_state +struct gl_shader { - struct gl2_program_intf **CurrentProgram; - GLboolean _VertexShaderPresent; - GLboolean _FragmentShaderPresent; + GLenum Type; /**< GL_FRAGMENT_SHADER || GL_VERTEX_SHADER (first field!) */ + GLuint Name; /**< AKA the handle */ + GLint RefCount; /**< Reference count */ + GLboolean DeletePending; + + const GLchar *Source; /**< Source code string */ + GLboolean CompileStatus; + GLuint NumPrograms; /**< size of Programs[] array */ + struct gl_program **Programs; /**< Post-compile assembly code */ + GLchar *InfoLog; +}; + + +/** + * A GLSL program object. Basically a linked collection of "shaders". + */ +struct gl_shader_program +{ + GLenum Type; /**< Always GL_SHADER_PROGRAM (internal token) */ + GLuint Name; /**< aka handle or ID */ + GLint RefCount; /**< Reference count */ + GLboolean DeletePending; + + GLuint NumShaders; /**< number of attached shaders */ + struct gl_shader **Shaders; /**< List of attached the shaders */ + + /* post-link info: */ + struct gl_vertex_program *VertexProgram; /**< Linked vertex program */ + struct gl_fragment_program *FragmentProgram; /**< Linked fragment prog */ + struct gl_program_parameter_list *Uniforms; /**< Plus constants, etc */ + struct gl_program_parameter_list *Varying; + struct gl_program_parameter_list *Attributes; /**< Vertex attributes */ + GLboolean LinkStatus; /**< GL_LINK_STATUS */ + GLboolean Validated; + GLchar *InfoLog; +}; + + +/** + * Context state for GLSL vertex/fragment shaders. + */ +struct gl_shader_state +{ + struct gl_shader_program *CurrentProgram; /**< The user-bound program */ + /** Driver-selectable options: */ + GLboolean EmitHighLevelInstructions; /**< IF/ELSE/ENDIF vs. BRA, etc. */ + GLboolean EmitCondCodes; /**< Use condition codes? */ + GLboolean EmitComments; /**< Annotated instructions */ }; @@ -2116,7 +2191,8 @@ struct gl_shared_state #endif #if FEATURE_ARB_shader_objects - struct _mesa_HashTable *GL2Objects; + /** Table of both gl_shader and gl_shader_program objects */ + struct _mesa_HashTable *ShaderObjects; #endif #if FEATURE_EXT_framebuffer_object @@ -2396,7 +2472,7 @@ struct gl_constants GLuint MaxRenderbufferSize; /* GL_ARB_vertex_shader */ GLuint MaxVertexTextureImageUnits; - GLuint MaxVaryingFloats; + GLuint MaxVarying; }; @@ -2534,7 +2610,7 @@ struct gl_extensions /** * A stack of matrices (projection, modelview, color, texture, etc). */ -struct matrix_stack +struct gl_matrix_stack { GLmatrix *Top; /**< points into Stack */ GLmatrix *Stack; /**< array [MaxDepth] of GLmatrix */ @@ -2765,7 +2841,7 @@ struct mesa_display_list /** * State used during display list compilation and execution. */ -struct mesa_list_state +struct gl_dlist_state { struct mesa_display_list *CallStack[MAX_LIST_NESTING]; GLuint CallDepth; /**< Current recursion calling depth */ @@ -2837,26 +2913,25 @@ struct __GLcontextRec struct dd_function_table Driver; void *DriverCtx; /**< Points to device driver context/state */ - void *DriverMgrCtx; /**< Points to device driver manager (optional)*/ /** Core/Driver constants */ struct gl_constants Const; /** \name The various 4x4 matrix stacks */ /*@{*/ - struct matrix_stack ModelviewMatrixStack; - struct matrix_stack ProjectionMatrixStack; - struct matrix_stack ColorMatrixStack; - struct matrix_stack TextureMatrixStack[MAX_TEXTURE_COORD_UNITS]; - struct matrix_stack ProgramMatrixStack[MAX_PROGRAM_MATRICES]; - struct matrix_stack *CurrentStack; /**< Points to one of the above stacks */ + struct gl_matrix_stack ModelviewMatrixStack; + struct gl_matrix_stack ProjectionMatrixStack; + struct gl_matrix_stack ColorMatrixStack; + struct gl_matrix_stack TextureMatrixStack[MAX_TEXTURE_COORD_UNITS]; + struct gl_matrix_stack ProgramMatrixStack[MAX_PROGRAM_MATRICES]; + struct gl_matrix_stack *CurrentStack; /**< Points to one of the above stacks */ /*@}*/ /** Combined modelview and projection matrix */ GLmatrix _ModelProjectMatrix; /** \name Display lists */ - struct mesa_list_state ListState; + struct gl_dlist_state ListState; GLboolean ExecuteFlag; /**< Execute GL commands? */ GLboolean CompileFlag; /**< Compile GL commands into display list? */ @@ -2939,16 +3014,9 @@ struct __GLcontextRec struct gl_fragment_program_state FragmentProgram; /**< GL_ARB/NV_vertex_program */ struct gl_ati_fragment_shader_state ATIFragmentShader; /**< GL_ATI_fragment_shader */ - struct gl_fragment_program *_TexEnvProgram; /**< Texture state as fragment program */ - struct gl_vertex_program *_TnlProgram; /**< Fixed func TNL state as vertex program */ - - GLboolean _MaintainTnlProgram; - GLboolean _MaintainTexEnvProgram; - GLboolean _UseTexEnvProgram; - struct gl_query_state Query; /**< GL_ARB_occlusion_query */ - struct gl_shader_objects_state ShaderObjects; /* GL_ARB_shader_objects */ + struct gl_shader_state Shader; /**< GLSL shader object state */ /*@}*/ #if FEATURE_EXT_framebuffer_object diff --git a/src/mesa/main/pixel.c b/src/mesa/main/pixel.c index b9e23d80b6..eb4fd6e7c9 100644 --- a/src/mesa/main/pixel.c +++ b/src/mesa/main/pixel.c @@ -911,16 +911,16 @@ _mesa_PixelTransferf( GLenum pname, GLfloat param ) ctx->Pixel.PostConvolutionBias[2] = param; break; case GL_POST_CONVOLUTION_ALPHA_SCALE: - if (ctx->Pixel.PostConvolutionScale[2] == param) + if (ctx->Pixel.PostConvolutionScale[3] == param) return; FLUSH_VERTICES(ctx, _NEW_PIXEL); - ctx->Pixel.PostConvolutionScale[2] = param; + ctx->Pixel.PostConvolutionScale[3] = param; break; case GL_POST_CONVOLUTION_ALPHA_BIAS: - if (ctx->Pixel.PostConvolutionBias[2] == param) + if (ctx->Pixel.PostConvolutionBias[3] == param) return; FLUSH_VERTICES(ctx, _NEW_PIXEL); - ctx->Pixel.PostConvolutionBias[2] = param; + ctx->Pixel.PostConvolutionBias[3] = param; break; default: _mesa_error( ctx, GL_INVALID_ENUM, "glPixelTransfer(pname)" ); diff --git a/src/mesa/main/shaders.c b/src/mesa/main/shaders.c new file mode 100644 index 0000000000..58be1f46e5 --- /dev/null +++ b/src/mesa/main/shaders.c @@ -0,0 +1,680 @@ +/* + * Mesa 3-D graphics library + * Version: 6.5.3 + * + * Copyright (C) 2004-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 "shaders.h" + + +/** + * These are basically just wrappers/adaptors for calling the + * ctx->Driver.foobar() GLSL-related functions. + * + * Things are biased toward the OpenGL 2.0 functions rather than the + * ARB extensions (i.e. the ARB functions are layered on the 2.0 functions). + * + * The general idea here is to allow enough modularity such that a + * completely different GLSL implemenation can be plugged in and co-exist + * with Mesa's native GLSL code. + */ + + + +void GLAPIENTRY +_mesa_AttachObjectARB(GLhandleARB program, GLhandleARB shader) +{ + GET_CURRENT_CONTEXT(ctx); + ctx->Driver.AttachShader(ctx, program, shader); +} + + +void GLAPIENTRY +_mesa_AttachShader(GLuint program, GLuint shader) +{ + GET_CURRENT_CONTEXT(ctx); + ctx->Driver.AttachShader(ctx, program, shader); +} + + +void GLAPIENTRY +_mesa_BindAttribLocationARB(GLhandleARB program, GLuint index, + const GLcharARB *name) +{ + GET_CURRENT_CONTEXT(ctx); + ctx->Driver.BindAttribLocation(ctx, program, index, name); +} + + +void GLAPIENTRY +_mesa_CompileShaderARB(GLhandleARB shaderObj) +{ + GET_CURRENT_CONTEXT(ctx); + ctx->Driver.CompileShader(ctx, shaderObj); +} + + +GLuint GLAPIENTRY +_mesa_CreateShader(GLenum type) +{ + GET_CURRENT_CONTEXT(ctx); + return ctx->Driver.CreateShader(ctx, type); +} + + +GLhandleARB APIENTRY +_mesa_CreateShaderObjectARB(GLenum type) +{ + GET_CURRENT_CONTEXT(ctx); + return ctx->Driver.CreateShader(ctx, type); +} + + +GLuint GLAPIENTRY +_mesa_CreateProgram(void) +{ + GET_CURRENT_CONTEXT(ctx); + return ctx->Driver.CreateProgram(ctx); +} + + +GLhandleARB APIENTRY +_mesa_CreateProgramObjectARB(void) +{ + GET_CURRENT_CONTEXT(ctx); + return ctx->Driver.CreateProgram(ctx); +} + + +void GLAPIENTRY +_mesa_DeleteObjectARB(GLhandleARB obj) +{ + if (obj) { + GET_CURRENT_CONTEXT(ctx); + if (ctx->Driver.IsProgram(ctx, obj)) { + ctx->Driver.DeleteProgram2(ctx, obj); + } + else if (ctx->Driver.IsShader(ctx, obj)) { + ctx->Driver.DeleteShader(ctx, obj); + } + else { + /* error? */ + } + } +} + + +void GLAPIENTRY +_mesa_DeleteProgram(GLuint name) +{ + if (name) { + GET_CURRENT_CONTEXT(ctx); + ctx->Driver.DeleteProgram2(ctx, name); + } +} + + +void GLAPIENTRY +_mesa_DeleteShader(GLuint name) +{ + if (name) { + GET_CURRENT_CONTEXT(ctx); + ctx->Driver.DeleteShader(ctx, name); + } +} + + +void GLAPIENTRY +_mesa_DetachObjectARB(GLhandleARB program, GLhandleARB shader) +{ + GET_CURRENT_CONTEXT(ctx); + ctx->Driver.DetachShader(ctx, program, shader); +} + + +void GLAPIENTRY +_mesa_DetachShader(GLuint program, GLuint shader) +{ + GET_CURRENT_CONTEXT(ctx); + ctx->Driver.DetachShader(ctx, program, shader); +} + + +void GLAPIENTRY +_mesa_GetActiveAttribARB(GLhandleARB program, GLuint index, + GLsizei maxLength, GLsizei * length, GLint * size, + GLenum * type, GLcharARB * name) +{ + GET_CURRENT_CONTEXT(ctx); + ctx->Driver.GetActiveAttrib(ctx, program, index, maxLength, length, size, + type, name); +} + + +void GLAPIENTRY +_mesa_GetActiveUniformARB(GLhandleARB program, GLuint index, + GLsizei maxLength, GLsizei * length, GLint * size, + GLenum * type, GLcharARB * name) +{ + GET_CURRENT_CONTEXT(ctx); + ctx->Driver.GetActiveUniform(ctx, program, index, maxLength, length, size, + type, name); +} + + +void GLAPIENTRY +_mesa_GetAttachedObjectsARB(GLhandleARB container, GLsizei maxCount, + GLsizei * count, GLhandleARB * obj) +{ + GET_CURRENT_CONTEXT(ctx); + ctx->Driver.GetAttachedShaders(ctx, container, maxCount, count, obj); +} + + +void GLAPIENTRY +_mesa_GetAttachedShaders(GLuint program, GLsizei maxCount, + GLsizei *count, GLuint *obj) +{ + GET_CURRENT_CONTEXT(ctx); + ctx->Driver.GetAttachedShaders(ctx, program, maxCount, count, obj); +} + + +GLint GLAPIENTRY +_mesa_GetAttribLocationARB(GLhandleARB program, const GLcharARB * name) +{ + GET_CURRENT_CONTEXT(ctx); + return ctx->Driver.GetAttribLocation(ctx, program, name); +} + + +void GLAPIENTRY +_mesa_GetInfoLogARB(GLhandleARB object, GLsizei maxLength, GLsizei * length, + GLcharARB * infoLog) +{ + GET_CURRENT_CONTEXT(ctx); + /* Implement in terms of GetProgramInfoLog, GetShaderInfoLog */ + if (ctx->Driver.IsProgram(ctx, object)) { + ctx->Driver.GetProgramInfoLog(ctx, object, maxLength, length, infoLog); + } + else if (ctx->Driver.IsShader(ctx, object)) { + ctx->Driver.GetShaderInfoLog(ctx, object, maxLength, length, infoLog); + } + else { + _mesa_error(ctx, GL_INVALID_OPERATION, "glGetInfoLogARB"); + } +} + + +void GLAPIENTRY +_mesa_GetObjectParameterivARB(GLhandleARB object, GLenum pname, GLint *params) +{ + GET_CURRENT_CONTEXT(ctx); + /* Implement in terms of GetProgramiv, GetShaderiv */ + if (ctx->Driver.IsProgram(ctx, object)) { + ctx->Driver.GetProgramiv(ctx, object, pname, params); + } + else if (ctx->Driver.IsShader(ctx, object)) { + ctx->Driver.GetShaderiv(ctx, object, pname, params); + } + else { + _mesa_error(ctx, GL_INVALID_OPERATION, "glGetObjectParameterivARB"); + } +} + + +void GLAPIENTRY +_mesa_GetObjectParameterfvARB(GLhandleARB object, GLenum pname, + GLfloat *params) +{ + GLint iparams[1]; /* XXX is one element enough? */ + _mesa_GetObjectParameterivARB(object, pname, iparams); + params[0] = (GLfloat) iparams[0]; +} + + +void GLAPIENTRY +_mesa_GetProgramiv(GLuint program, GLenum pname, GLint *params) +{ + GET_CURRENT_CONTEXT(ctx); + ctx->Driver.GetProgramiv(ctx, program, pname, params); +} + + +void GLAPIENTRY +_mesa_GetShaderiv(GLuint shader, GLenum pname, GLint *params) +{ + GET_CURRENT_CONTEXT(ctx); + ctx->Driver.GetShaderiv(ctx, shader, pname, params); +} + + +void GLAPIENTRY +_mesa_GetProgramInfoLog(GLuint program, GLsizei bufSize, + GLsizei *length, GLchar *infoLog) +{ + GET_CURRENT_CONTEXT(ctx); + ctx->Driver.GetProgramInfoLog(ctx, program, bufSize, length, infoLog); +} + + +void GLAPIENTRY +_mesa_GetShaderInfoLog(GLuint shader, GLsizei bufSize, + GLsizei *length, GLchar *infoLog) +{ + GET_CURRENT_CONTEXT(ctx); + ctx->Driver.GetShaderInfoLog(ctx, shader, bufSize, length, infoLog); +} + + +void GLAPIENTRY +_mesa_GetShaderSourceARB(GLhandleARB shader, GLsizei maxLength, + GLsizei *length, GLcharARB *sourceOut) +{ + GET_CURRENT_CONTEXT(ctx); + ctx->Driver.GetShaderSource(ctx, shader, maxLength, length, sourceOut); +} + + +void GLAPIENTRY +_mesa_GetUniformfvARB(GLhandleARB program, GLint location, GLfloat * params) +{ + GET_CURRENT_CONTEXT(ctx); + ctx->Driver.GetUniformfv(ctx, program, location, params); +} + + +void GLAPIENTRY +_mesa_GetUniformivARB(GLhandleARB program, GLint location, GLint * params) +{ + GET_CURRENT_CONTEXT(ctx); + GLfloat fparams[16]; /* XXX is 16 enough? */ + GLuint i; + ctx->Driver.GetUniformfv(ctx, program, location, fparams); + for (i = 0; i < 16; i++) + params[i] = (GLint) fparams[i]; /* XXX correct? */ +} + + + +#if 0 +GLint APIENTRY +_mesa_GetUniformLocation(GLuint program, const GLcharARB *name) +{ + GET_CURRENT_CONTEXT(ctx); + return ctx->Driver.GetUniformLocation(ctx, program, name); +} +#endif + + +GLhandleARB GLAPIENTRY +_mesa_GetHandleARB(GLenum pname) +{ + GET_CURRENT_CONTEXT(ctx); + return ctx->Driver.GetHandle(ctx, pname); +} + + +GLint APIENTRY +_mesa_GetUniformLocationARB(GLhandleARB programObj, const GLcharARB *name) +{ + GET_CURRENT_CONTEXT(ctx); + return ctx->Driver.GetUniformLocation(ctx, programObj, name); +} + + +GLboolean GLAPIENTRY +_mesa_IsProgram(GLuint name) +{ + GET_CURRENT_CONTEXT(ctx); + return ctx->Driver.IsProgram(ctx, name); +} + + +GLboolean GLAPIENTRY +_mesa_IsShader(GLuint name) +{ + GET_CURRENT_CONTEXT(ctx); + return ctx->Driver.IsShader(ctx, name); +} + + +void GLAPIENTRY +_mesa_LinkProgramARB(GLhandleARB programObj) +{ + GET_CURRENT_CONTEXT(ctx); + ctx->Driver.LinkProgram(ctx, programObj); +} + + +/** + * Called via glShaderSource() and glShaderSourceARB() API functions. + * Basically, concatenate the source code strings into one long string + * and pass it to ctx->Driver.ShaderSource(). + */ +void GLAPIENTRY +_mesa_ShaderSourceARB(GLhandleARB shaderObj, GLsizei count, + const GLcharARB ** string, const GLint * length) +{ + GET_CURRENT_CONTEXT(ctx); + GLint *offsets; + GLsizei i, totalLength; + GLcharARB *source; + + if (string == NULL) { + _mesa_error(ctx, GL_INVALID_VALUE, "glShaderSourceARB"); + return; + } + + /* + * This array holds offsets of where the appropriate string ends, thus the + * last element will be set to the total length of the source code. + */ + offsets = (GLint *) _mesa_malloc(count * sizeof(GLint)); + if (offsets == NULL) { + _mesa_error(ctx, GL_OUT_OF_MEMORY, "glShaderSourceARB"); + return; + } + + for (i = 0; i < count; i++) { + if (string[i] == NULL) { + _mesa_free((GLvoid *) offsets); + _mesa_error(ctx, GL_INVALID_VALUE, "glShaderSourceARB(null string)"); + return; + } + if (length == NULL || length[i] < 0) + offsets[i] = _mesa_strlen(string[i]); + else + offsets[i] = length[i]; + /* accumulate string lengths */ + if (i > 0) + offsets[i] += offsets[i - 1]; + } + + /* Total length of source string is sum off all strings plus two. + * One extra byte for terminating zero, another extra byte to silence + * valgrind warnings in the parser/grammer code. + */ + totalLength = offsets[count - 1] + 2; + source = (GLcharARB *) _mesa_malloc(totalLength * sizeof(GLcharARB)); + if (source == NULL) { + _mesa_free((GLvoid *) offsets); + _mesa_error(ctx, GL_OUT_OF_MEMORY, "glShaderSourceARB"); + return; + } + + for (i = 0; i < count; i++) { + GLint start = (i > 0) ? offsets[i - 1] : 0; + _mesa_memcpy(source + start, string[i], + (offsets[i] - start) * sizeof(GLcharARB)); + } + source[totalLength - 1] = '\0'; + source[totalLength - 2] = '\0'; + + ctx->Driver.ShaderSource(ctx, shaderObj, source); + + _mesa_free(offsets); +} + + +void GLAPIENTRY +_mesa_Uniform1fARB(GLint location, GLfloat v0) +{ + GET_CURRENT_CONTEXT(ctx); + ctx->Driver.Uniform(ctx, location, 1, &v0, GL_FLOAT); +} + +void GLAPIENTRY +_mesa_Uniform2fARB(GLint location, GLfloat v0, GLfloat v1) +{ + GET_CURRENT_CONTEXT(ctx); + GLfloat v[2]; + v[0] = v0; + v[1] = v1; + ctx->Driver.Uniform(ctx, location, 1, v, GL_FLOAT_VEC2); +} + +void GLAPIENTRY +_mesa_Uniform3fARB(GLint location, GLfloat v0, GLfloat v1, GLfloat v2) +{ + GET_CURRENT_CONTEXT(ctx); + GLfloat v[3]; + v[0] = v0; + v[1] = v1; + v[2] = v2; + ctx->Driver.Uniform(ctx, location, 1, v, GL_FLOAT_VEC3); +} + +void GLAPIENTRY +_mesa_Uniform4fARB(GLint location, GLfloat v0, GLfloat v1, GLfloat v2, + GLfloat v3) +{ + GET_CURRENT_CONTEXT(ctx); + GLfloat v[4]; + v[0] = v0; + v[1] = v1; + v[2] = v2; + v[3] = v3; + ctx->Driver.Uniform(ctx, location, 1, v, GL_FLOAT_VEC4); +} + +void GLAPIENTRY +_mesa_Uniform1iARB(GLint location, GLint v0) +{ + GET_CURRENT_CONTEXT(ctx); + ctx->Driver.Uniform(ctx, location, 1, &v0, GL_INT); +} + +void GLAPIENTRY +_mesa_Uniform2iARB(GLint location, GLint v0, GLint v1) +{ + GET_CURRENT_CONTEXT(ctx); + GLint v[2]; + v[0] = v0; + v[1] = v1; + ctx->Driver.Uniform(ctx, location, 1, v, GL_INT_VEC2); +} + +void GLAPIENTRY +_mesa_Uniform3iARB(GLint location, GLint v0, GLint v1, GLint v2) +{ + GET_CURRENT_CONTEXT(ctx); + GLint v[3]; + v[0] = v0; + v[1] = v1; + v[2] = v2; + ctx->Driver.Uniform(ctx, location, 1, v, GL_INT_VEC3); +} + +void GLAPIENTRY +_mesa_Uniform4iARB(GLint location, GLint v0, GLint v1, GLint v2, GLint v3) +{ + GET_CURRENT_CONTEXT(ctx); + GLint v[4]; + v[0] = v0; + v[1] = v1; + v[2] = v2; + v[3] = v3; + ctx->Driver.Uniform(ctx, location, 1, v, GL_INT_VEC4); +} + +void GLAPIENTRY +_mesa_Uniform1fvARB(GLint location, GLsizei count, const GLfloat * value) +{ + GET_CURRENT_CONTEXT(ctx); + ctx->Driver.Uniform(ctx, location, count, value, GL_FLOAT); +} + +void GLAPIENTRY +_mesa_Uniform2fvARB(GLint location, GLsizei count, const GLfloat * value) +{ + GET_CURRENT_CONTEXT(ctx); + ctx->Driver.Uniform(ctx, location, count, value, GL_FLOAT_VEC2); +} + +void GLAPIENTRY +_mesa_Uniform3fvARB(GLint location, GLsizei count, const GLfloat * value) +{ + GET_CURRENT_CONTEXT(ctx); + ctx->Driver.Uniform(ctx, location, count, value, GL_FLOAT_VEC3); +} + +void GLAPIENTRY +_mesa_Uniform4fvARB(GLint location, GLsizei count, const GLfloat * value) +{ + GET_CURRENT_CONTEXT(ctx); + ctx->Driver.Uniform(ctx, location, count, value, GL_FLOAT_VEC4); +} + +void GLAPIENTRY +_mesa_Uniform1ivARB(GLint location, GLsizei count, const GLint * value) +{ + GET_CURRENT_CONTEXT(ctx); + ctx->Driver.Uniform(ctx, location, count, value, GL_INT); +} + +void GLAPIENTRY +_mesa_Uniform2ivARB(GLint location, GLsizei count, const GLint * value) +{ + GET_CURRENT_CONTEXT(ctx); + ctx->Driver.Uniform(ctx, location, count, value, GL_INT_VEC2); +} + +void GLAPIENTRY +_mesa_Uniform3ivARB(GLint location, GLsizei count, const GLint * value) +{ + GET_CURRENT_CONTEXT(ctx); + ctx->Driver.Uniform(ctx, location, count, value, GL_INT_VEC3); +} + +void GLAPIENTRY +_mesa_Uniform4ivARB(GLint location, GLsizei count, const GLint * value) +{ + GET_CURRENT_CONTEXT(ctx); + ctx->Driver.Uniform(ctx, location, count, value, GL_INT_VEC4); +} + + +void GLAPIENTRY +_mesa_UniformMatrix2fvARB(GLint location, GLsizei count, GLboolean transpose, + const GLfloat * value) +{ + GET_CURRENT_CONTEXT(ctx); + ctx->Driver.UniformMatrix(ctx, 2, 2, GL_FLOAT_MAT2, + location, count, transpose, value); +} + +void GLAPIENTRY +_mesa_UniformMatrix3fvARB(GLint location, GLsizei count, GLboolean transpose, + const GLfloat * value) +{ + GET_CURRENT_CONTEXT(ctx); + ctx->Driver.UniformMatrix(ctx, 3, 3, GL_FLOAT_MAT3, + location, count, transpose, value); +} + +void GLAPIENTRY +_mesa_UniformMatrix4fvARB(GLint location, GLsizei count, GLboolean transpose, + const GLfloat * value) +{ + GET_CURRENT_CONTEXT(ctx); + ctx->Driver.UniformMatrix(ctx, 4, 4, GL_FLOAT_MAT4, + location, count, transpose, value); +} + + +/** + * Non-square UniformMatrix are OpenGL 2.1 + */ +void GLAPIENTRY +_mesa_UniformMatrix2x3fv(GLint location, GLsizei count, GLboolean transpose, + const GLfloat *value) +{ + GET_CURRENT_CONTEXT(ctx); + ctx->Driver.UniformMatrix(ctx, 2, 3, GL_FLOAT_MAT2x3, + location, count, transpose, value); +} + +void GLAPIENTRY +_mesa_UniformMatrix3x2fv(GLint location, GLsizei count, GLboolean transpose, + const GLfloat *value) +{ + GET_CURRENT_CONTEXT(ctx); + ctx->Driver.UniformMatrix(ctx, 3, 2, GL_FLOAT_MAT3x2, + location, count, transpose, value); +} + +void GLAPIENTRY +_mesa_UniformMatrix2x4fv(GLint location, GLsizei count, GLboolean transpose, + const GLfloat *value) +{ + GET_CURRENT_CONTEXT(ctx); + ctx->Driver.UniformMatrix(ctx, 2, 4, GL_FLOAT_MAT2x4, + location, count, transpose, value); +} + +void GLAPIENTRY +_mesa_UniformMatrix4x2fv(GLint location, GLsizei count, GLboolean transpose, + const GLfloat *value) +{ + GET_CURRENT_CONTEXT(ctx); + ctx->Driver.UniformMatrix(ctx, 4, 2, GL_FLOAT_MAT4x2, + location, count, transpose, value); +} + +void GLAPIENTRY +_mesa_UniformMatrix3x4fv(GLint location, GLsizei count, GLboolean transpose, + const GLfloat *value) +{ + GET_CURRENT_CONTEXT(ctx); + ctx->Driver.UniformMatrix(ctx, 3, 4, GL_FLOAT_MAT3x4, + location, count, transpose, value); +} + +void GLAPIENTRY +_mesa_UniformMatrix4x3fv(GLint location, GLsizei count, GLboolean transpose, + const GLfloat *value) +{ + GET_CURRENT_CONTEXT(ctx); + ctx->Driver.UniformMatrix(ctx, 4, 3, GL_FLOAT_MAT4x3, + location, count, transpose, value); +} + + +void GLAPIENTRY +_mesa_UseProgramObjectARB(GLhandleARB program) +{ + GET_CURRENT_CONTEXT(ctx); + FLUSH_VERTICES(ctx, _NEW_PROGRAM); + ctx->Driver.UseProgram(ctx, program); +} + + +void GLAPIENTRY +_mesa_ValidateProgramARB(GLhandleARB program) +{ + GET_CURRENT_CONTEXT(ctx); + ctx->Driver.ValidateProgram(ctx, program); +} + diff --git a/src/mesa/shader/shaderobjects.h b/src/mesa/main/shaders.h index 09ba807255..17339ccf62 100644 --- a/src/mesa/shader/shaderobjects.h +++ b/src/mesa/main/shaders.h @@ -1,8 +1,8 @@ /* * Mesa 3-D graphics library - * Version: 6.5 + * Version: 6.5.3 * - * Copyright (C) 2004-2006 Brian Paul All Rights Reserved. + * Copyright (C) 2004-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"), @@ -22,124 +22,13 @@ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -#ifndef SHADEROBJECTS_H -#define SHADEROBJECTS_H -#include "context.h" +#ifndef SHADERS_H +#define SHADERS_H -#if FEATURE_ARB_shader_objects -/** - * gl2 unique interface identifier. - * Each gl2 interface has its own interface id used for object queries. - */ -enum gl2_uiid -{ - UIID_UNKNOWN, /* supported by all objects */ - UIID_GENERIC, /* generic object */ - UIID_CONTAINER, /* contains generic objects */ - UIID_SHADER, /* shader object */ - UIID_FRAGMENT_SHADER, /* fragment shader */ - UIID_VERTEX_SHADER, /* vertex shader */ - UIID_PROGRAM, /* program object */ - UIID_3DLABS_SHHANDLE, /* encapsulates 3DLabs' ShHandle */ - UIID_DEBUG /* debug object */ -}; - -struct gl2_unknown_intf -{ - GLvoid (* AddRef) (struct gl2_unknown_intf **); - GLvoid (* Release) (struct gl2_unknown_intf **); - struct gl2_unknown_intf **(* QueryInterface) (struct gl2_unknown_intf **, enum gl2_uiid uiid); -}; - -struct gl2_generic_intf -{ - struct gl2_unknown_intf _unknown; - GLvoid (* Delete) (struct gl2_generic_intf **); - GLenum (* GetType) (struct gl2_generic_intf **); - GLhandleARB (* GetName) (struct gl2_generic_intf **); - GLboolean (* GetDeleteStatus) (struct gl2_generic_intf **); - GLvoid (* GetInfoLog) (struct gl2_generic_intf **, GLsizei, GLcharARB *); - GLsizei (* GetInfoLogLength) (struct gl2_generic_intf **); -}; - -struct gl2_container_intf -{ - struct gl2_generic_intf _generic; - GLboolean (* Attach) (struct gl2_container_intf **, struct gl2_generic_intf **); - GLboolean (* Detach) (struct gl2_container_intf **, struct gl2_generic_intf **); - GLsizei (* GetAttachedCount) (struct gl2_container_intf **); - struct gl2_generic_intf **(* GetAttached) (struct gl2_container_intf **, GLuint); -}; - -struct gl2_shader_intf -{ - struct gl2_generic_intf _generic; - GLenum (* GetSubType) (struct gl2_shader_intf **); - GLboolean (* GetCompileStatus) (struct gl2_shader_intf **); - GLvoid (* SetSource) (struct gl2_shader_intf **, GLcharARB *, GLint *, GLsizei); - const GLcharARB *(* GetSource) (struct gl2_shader_intf **); - GLvoid (* Compile) (struct gl2_shader_intf **); -}; - -struct gl2_program_intf -{ - struct gl2_container_intf _container; - GLboolean (* GetLinkStatus) (struct gl2_program_intf **); - GLboolean (* GetValidateStatus) (struct gl2_program_intf **); - GLvoid (* Link) (struct gl2_program_intf **); - GLvoid (* Validate) (struct gl2_program_intf **); - GLvoid (* UpdateFixedUniforms) (struct gl2_program_intf **); - GLvoid (* UpdateFixedAttrib) (struct gl2_program_intf **, GLuint, GLvoid *, GLuint, GLuint, - GLboolean); - GLvoid (* UpdateFixedVarying) (struct gl2_program_intf **, GLuint, GLvoid *, GLuint, GLuint, - GLboolean); - GLvoid (* GetTextureImageUsage) (struct gl2_program_intf **, GLbitfield *); - GLboolean (* IsShaderPresent) (struct gl2_program_intf **, GLenum); - GLvoid (* GetActiveUniform) (struct gl2_program_intf **, GLuint index, GLsizei maxLength, - GLsizei *length, GLint *size, GLenum *type, GLchar *name); - GLuint (* GetActiveUniformMaxLength) (struct gl2_program_intf **); - GLuint (* GetActiveUniformCount) (struct gl2_program_intf **); - GLint (* GetUniformLocation) (struct gl2_program_intf **, const GLchar *name); - GLboolean (* WriteUniform) (struct gl2_program_intf **, GLint loc, GLsizei count, - const GLvoid *data, GLenum type); - GLboolean (* ReadUniform) (struct gl2_program_intf **, GLint loc, GLsizei count, - GLvoid *data, GLenum type); - GLvoid (* GetActiveAttrib) (struct gl2_program_intf **, GLuint index, GLsizei maxLength, - GLsizei *length, GLint *size, GLenum *type, GLchar *name); - GLuint (* GetActiveAttribMaxLength) (struct gl2_program_intf **); - GLuint (* GetActiveAttribCount) (struct gl2_program_intf **); - GLint (* GetAttribLocation) (struct gl2_program_intf **, const GLchar *name); - GLvoid (* OverrideAttribBinding) (struct gl2_program_intf **, GLuint, const GLchar *); - GLvoid (* WriteAttrib) (struct gl2_program_intf **, GLuint, const GLfloat *); - GLvoid (* UpdateVarying) (struct gl2_program_intf **, GLuint, GLfloat *, GLboolean); -}; - -struct gl2_fragment_shader_intf -{ - struct gl2_shader_intf _shader; -}; - -struct gl2_vertex_shader_intf -{ - struct gl2_shader_intf _shader; -}; - -struct gl2_3dlabs_shhandle_intf -{ - struct gl2_unknown_intf _unknown; - GLvoid *(* GetShHandle) (struct gl2_3dlabs_shhandle_intf **); -}; - -struct gl2_debug_intf -{ - struct gl2_generic_intf _generic; - GLvoid (* ClearDebugLog) (struct gl2_debug_intf **, GLenum logType, GLenum shaderType); - GLvoid (* GetDebugLog) (struct gl2_debug_intf **, GLenum logType, GLenum shaderType, - GLsizei maxLength, GLsizei *length, GLcharARB *infoLog); - GLsizei (* GetDebugLogLength) (struct gl2_debug_intf **, GLenum logType, GLenum shaderType); -}; +#include "glheader.h" +#include "mtypes.h" extern void GLAPIENTRY @@ -344,10 +233,4 @@ _mesa_UniformMatrix4x3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); - -#endif /* FEATURE_ARB_shader_objects */ - -extern void -_mesa_init_shaderobjects (GLcontext *ctx); - -#endif /* SHADEROBJECTS_H */ +#endif /* SHADERS_H */ diff --git a/src/mesa/main/state.c b/src/mesa/main/state.c index f4f73a5089..6ed7ae6c7d 100644 --- a/src/mesa/main/state.c +++ b/src/mesa/main/state.c @@ -93,7 +93,7 @@ #include "texenvprogram.h" #endif #if FEATURE_ARB_shader_objects -#include "shaderobjects.h" +#include "shaders.h" #endif #include "debug.h" #include "dispatch.h" @@ -832,11 +832,7 @@ update_arrays( GLcontext *ctx ) /* find min of _MaxElement values for all enabled arrays */ /* 0 */ - if (ctx->ShaderObjects._VertexShaderPresent - && ctx->Array.ArrayObj->VertexAttrib[VERT_ATTRIB_GENERIC0].Enabled) { - min = ctx->Array.ArrayObj->VertexAttrib[VERT_ATTRIB_GENERIC0]._MaxElement; - } - else if (ctx->VertexProgram._Enabled + if (ctx->VertexProgram._Current && ctx->Array.ArrayObj->VertexAttrib[VERT_ATTRIB_POS].Enabled) { min = ctx->Array.ArrayObj->VertexAttrib[VERT_ATTRIB_POS]._MaxElement; } @@ -920,7 +916,7 @@ update_arrays( GLcontext *ctx ) } /* 16..31 */ - if (ctx->ShaderObjects._VertexShaderPresent) { + if (ctx->VertexProgram._Current) { for (i = VERT_ATTRIB_GENERIC0; i < VERT_ATTRIB_MAX; i++) { if (ctx->Array.ArrayObj->VertexAttrib[i].Enabled) { min = MIN2(min, ctx->Array.ArrayObj->VertexAttrib[i]._MaxElement); @@ -943,30 +939,66 @@ update_arrays( GLcontext *ctx ) static void update_program(GLcontext *ctx) { - /* For now, just set the _Enabled (really enabled) flags. - * In the future we may have to check other state to be sure we really - * have a runable program or shader. - */ + const struct gl_shader_program *shProg = ctx->Shader.CurrentProgram; + + /* These _Enabled flags indicate if the program is enabled AND valid. */ ctx->VertexProgram._Enabled = ctx->VertexProgram.Enabled && ctx->VertexProgram.Current->Base.Instructions; ctx->FragmentProgram._Enabled = ctx->FragmentProgram.Enabled && ctx->FragmentProgram.Current->Base.Instructions; ctx->ATIFragmentShader._Enabled = ctx->ATIFragmentShader.Enabled && ctx->ATIFragmentShader.Current->Instructions; - - ctx->FragmentProgram._Current = ctx->FragmentProgram.Current; - ctx->FragmentProgram._Active = ctx->FragmentProgram._Enabled; - if (ctx->_MaintainTexEnvProgram && !ctx->FragmentProgram._Enabled) { -#if 0 - if (!ctx->_TexEnvProgram) - ctx->_TexEnvProgram = (struct gl_fragment_program *) - ctx->Driver.NewProgram(ctx, GL_FRAGMENT_PROGRAM_ARB, 0); - ctx->FragmentProgram._Current = ctx->_TexEnvProgram; -#endif + /* + * Set the ctx->VertexProgram._Current and ctx->FragmentProgram._Current + * pointers to the programs that should be enabled/used. + * + * These programs may come from several sources. The priority is as + * follows: + * 1. OpenGL 2.0/ARB vertex/fragment shaders + * 2. ARB/NV vertex/fragment programs + * 3. Programs derived from fixed-function state. + */ - if (ctx->_UseTexEnvProgram) - ctx->FragmentProgram._Active = GL_TRUE; + ctx->FragmentProgram._Current = NULL; + + if (shProg && shProg->LinkStatus) { + /* Use shader programs */ + ctx->VertexProgram._Current = shProg->VertexProgram; + ctx->FragmentProgram._Current = shProg->FragmentProgram; + } + else { + if (ctx->VertexProgram._Enabled) { + /* use user-defined vertex program */ + ctx->VertexProgram._Current = ctx->VertexProgram.Current; + } + else if (ctx->VertexProgram._MaintainTnlProgram) { + /* Use vertex program generated from fixed-function state. + * The _Current pointer will get set in + * _tnl_UpdateFixedFunctionProgram() later if appropriate. + */ + ctx->VertexProgram._Current = NULL; + } + else { + /* no vertex program */ + ctx->VertexProgram._Current = NULL; + } + + if (ctx->FragmentProgram._Enabled) { + /* use user-defined vertex program */ + ctx->FragmentProgram._Current = ctx->FragmentProgram.Current; + } + else if (ctx->FragmentProgram._MaintainTexEnvProgram) { + /* Use fragment program generated from fixed-function state. + * The _Current pointer will get set in _mesa_UpdateTexEnvProgram() + * later if appropriate. + */ + ctx->FragmentProgram._Current = NULL; + } + else { + /* no fragment program */ + ctx->FragmentProgram._Current = NULL; + } } } @@ -1003,6 +1035,7 @@ update_color(GLcontext *ctx) } + /** * Update the ctx->_TriangleCaps bitfield. * XXX that bitfield should really go away someday! @@ -1133,7 +1166,7 @@ _mesa_update_state_locked( GLcontext *ctx ) | _NEW_STENCIL | _DD_NEW_SEPARATE_SPECULAR)) update_tricaps( ctx, new_state ); - if (ctx->_MaintainTexEnvProgram) { + if (ctx->FragmentProgram._MaintainTexEnvProgram) { if (new_state & (_NEW_TEXTURE | _DD_NEW_SEPARATE_SPECULAR | _NEW_FOG)) _mesa_UpdateTexEnvProgram(ctx); } diff --git a/src/mesa/main/texenvprogram.c b/src/mesa/main/texenvprogram.c index d1994f76d1..0c6fa82f11 100644 --- a/src/mesa/main/texenvprogram.c +++ b/src/mesa/main/texenvprogram.c @@ -28,11 +28,12 @@ #include "glheader.h" #include "macros.h" #include "enums.h" +#include "prog_parameter.h" +#include "prog_instruction.h" +#include "prog_print.h" +#include "prog_statevars.h" #include "texenvprogram.h" -#include "shader/program.h" -#include "shader/program_instruction.h" - /** * According to Glean's texCombine test, no more than 21 instructions * are needed. Allow a few extra just in case. @@ -410,31 +411,29 @@ static void release_temps( struct texenv_fragment_program *p ) } -static struct ureg register_param6( struct texenv_fragment_program *p, +static struct ureg register_param5( struct texenv_fragment_program *p, GLint s0, GLint s1, GLint s2, GLint s3, - GLint s4, - GLint s5) + GLint s4) { - GLint tokens[6]; + gl_state_index tokens[STATE_LENGTH]; GLuint idx; tokens[0] = s0; tokens[1] = s1; tokens[2] = s2; tokens[3] = s3; tokens[4] = s4; - tokens[5] = s5; idx = _mesa_add_state_reference( p->program->Base.Parameters, tokens ); return make_ureg(PROGRAM_STATE_VAR, idx); } -#define register_param1(p,s0) register_param6(p,s0,0,0,0,0,0) -#define register_param2(p,s0,s1) register_param6(p,s0,s1,0,0,0,0) -#define register_param3(p,s0,s1,s2) register_param6(p,s0,s1,s2,0,0,0) -#define register_param4(p,s0,s1,s2,s3) register_param6(p,s0,s1,s2,s3,0,0) +#define register_param1(p,s0) register_param5(p,s0,0,0,0,0) +#define register_param2(p,s0,s1) register_param5(p,s0,s1,0,0,0) +#define register_param3(p,s0,s1,s2) register_param5(p,s0,s1,s2,0,0) +#define register_param4(p,s0,s1,s2,s3) register_param5(p,s0,s1,s2,s3,0) static struct ureg register_input( struct texenv_fragment_program *p, GLuint input ) @@ -523,7 +522,7 @@ static struct ureg emit_arith( struct texenv_fragment_program *p, if (dest.file == PROGRAM_TEMPORARY) p->alu_temps |= 1 << dest.idx; - p->program->NumAluInstructions++; + p->program->Base.NumAluInstructions++; return dest; } @@ -545,7 +544,7 @@ static struct ureg emit_texld( struct texenv_fragment_program *p, inst->TexSrcTarget = tex_idx; inst->TexSrcUnit = tex_unit; - p->program->NumTexInstructions++; + p->program->Base.NumTexInstructions++; /* Is this a texture indirection? */ @@ -553,7 +552,7 @@ static struct ureg emit_texld( struct texenv_fragment_program *p, (p->temps_output & (1<<coord.idx))) || (dest.file == PROGRAM_TEMPORARY && (p->alu_temps & (1<<dest.idx)))) { - p->program->NumTexIndirections++; + p->program->Base.NumTexIndirections++; p->temps_output = 1<<coord.idx; p->alu_temps = 0; assert(0); /* KW: texture env crossbar */ @@ -570,12 +569,14 @@ static struct ureg register_const4f( struct texenv_fragment_program *p, GLfloat s3) { GLfloat values[4]; - GLuint idx; + GLuint idx, swizzle; values[0] = s0; values[1] = s1; values[2] = s2; values[3] = s3; - idx = _mesa_add_unnamed_constant( p->program->Base.Parameters, values, 4 ); + idx = _mesa_add_unnamed_constant( p->program->Base.Parameters, values, 4, + &swizzle ); + ASSERT(swizzle == SWIZZLE_NOOP); return make_ureg(PROGRAM_STATE_VAR, idx); } @@ -1010,9 +1011,9 @@ create_new_program(GLcontext *ctx, struct state_key *key, */ p.program->Base.Instructions = instBuffer; p.program->Base.Target = GL_FRAGMENT_PROGRAM_ARB; - p.program->NumTexIndirections = 1; /* correct? */ - p.program->NumTexInstructions = 0; - p.program->NumAluInstructions = 0; + p.program->Base.NumTexIndirections = 1; /* correct? */ + p.program->Base.NumTexInstructions = 0; + p.program->Base.NumAluInstructions = 0; p.program->Base.String = NULL; p.program->Base.NumInstructions = p.program->Base.NumTemporaries = @@ -1083,13 +1084,13 @@ create_new_program(GLcontext *ctx, struct state_key *key, } else p.program->FogOption = GL_NONE; - if (p.program->NumTexIndirections > ctx->Const.FragmentProgram.MaxTexIndirections) + if (p.program->Base.NumTexIndirections > ctx->Const.FragmentProgram.MaxTexIndirections) program_error(&p, "Exceeded max nr indirect texture lookups"); - if (p.program->NumTexInstructions > ctx->Const.FragmentProgram.MaxTexInstructions) + if (p.program->Base.NumTexInstructions > ctx->Const.FragmentProgram.MaxTexInstructions) program_error(&p, "Exceeded max TEX instructions"); - if (p.program->NumAluInstructions > ctx->Const.FragmentProgram.MaxAluInstructions) + if (p.program->Base.NumAluInstructions > ctx->Const.FragmentProgram.MaxAluInstructions) program_error(&p, "Exceeded max ALU instructions"); ASSERT(p.program->Base.NumInstructions <= MAX_INSTRUCTIONS); @@ -1221,32 +1222,49 @@ static GLuint hash_key( const struct state_key *key ) return hash; } -void _mesa_UpdateTexEnvProgram( GLcontext *ctx ) + +/** + * If _MaintainTexEnvProgram is set we'll generate a fragment program that + * implements the current texture env/combine mode. + * This function generates that program and puts it into effect. + */ +void +_mesa_UpdateTexEnvProgram( GLcontext *ctx ) { struct state_key key; GLuint hash; const struct gl_fragment_program *prev = ctx->FragmentProgram._Current; - if (!ctx->FragmentProgram._Enabled) { + ASSERT(ctx->FragmentProgram._MaintainTexEnvProgram); + + /* If a conventional fragment program/shader isn't in effect... */ + if (!ctx->FragmentProgram._Enabled && + !ctx->Shader.CurrentProgram) { make_state_key(ctx, &key); hash = hash_key(&key); ctx->FragmentProgram._Current = - ctx->_TexEnvProgram = - search_cache(&ctx->Texture.env_fp_cache, hash, &key, sizeof(key)); - - if (!ctx->_TexEnvProgram) { - if (0) _mesa_printf("Building new texenv proggy for key %x\n", hash); - - ctx->FragmentProgram._Current = ctx->_TexEnvProgram = - (struct gl_fragment_program *) - ctx->Driver.NewProgram(ctx, GL_FRAGMENT_PROGRAM_ARB, 0); - - create_new_program(ctx, &key, ctx->_TexEnvProgram); + ctx->FragmentProgram._TexEnvProgram = + search_cache(&ctx->Texture.env_fp_cache, hash, &key, sizeof(key)); + + if (!ctx->FragmentProgram._TexEnvProgram) { + if (0) + _mesa_printf("Building new texenv proggy for key %x\n", hash); + + /* create new tex env program */ + ctx->FragmentProgram._Current = + ctx->FragmentProgram._TexEnvProgram = + (struct gl_fragment_program *) + ctx->Driver.NewProgram(ctx, GL_FRAGMENT_PROGRAM_ARB, 0); - cache_item(&ctx->Texture.env_fp_cache, hash, &key, ctx->_TexEnvProgram); - } else { - if (0) _mesa_printf("Found existing texenv program for key %x\n", hash); + create_new_program(ctx, &key, ctx->FragmentProgram._TexEnvProgram); + + cache_item(&ctx->Texture.env_fp_cache, hash, &key, + ctx->FragmentProgram._TexEnvProgram); + } + else { + if (0) + _mesa_printf("Found existing texenv program for key %x\n", hash); } } else { @@ -1258,7 +1276,7 @@ void _mesa_UpdateTexEnvProgram( GLcontext *ctx ) */ if (ctx->FragmentProgram._Current != prev && ctx->Driver.BindProgram) { ctx->Driver.BindProgram(ctx, GL_FRAGMENT_PROGRAM_ARB, - (struct gl_program *) ctx->FragmentProgram._Current); + (struct gl_program *) ctx->FragmentProgram._Current); } } diff --git a/src/mesa/main/texstate.c b/src/mesa/main/texstate.c index bcedcafe19..bed2c1220a 100644 --- a/src/mesa/main/texstate.c +++ b/src/mesa/main/texstate.c @@ -1,8 +1,8 @@ /* * Mesa 3-D graphics library - * Version: 6.5.1 + * 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"), @@ -41,8 +41,6 @@ #include "texenvprogram.h" #include "mtypes.h" #include "math/m_xform.h" -#include "shaderobjects.h" - #define ENUM_TO_FLOAT(X) ((GLfloat)(GLint)(X)) @@ -2919,11 +2917,18 @@ static void update_texture_state( GLcontext *ctx ) { GLuint unit; + struct gl_fragment_program *fprog; -#if FEATURE_ARB_fragment_shader - struct gl2_program_intf **prog = ctx->ShaderObjects.CurrentProgram; - GLbitfield progteximageusage[MAX_TEXTURE_IMAGE_UNITS]; -#endif + if (ctx->Shader.CurrentProgram && + ctx->Shader.CurrentProgram->LinkStatus) { + fprog = ctx->Shader.CurrentProgram->FragmentProgram; + } + else if (ctx->FragmentProgram._Enabled) { + fprog = ctx->FragmentProgram.Current; + } + else { + fprog = NULL; + } ctx->NewState |= _NEW_TEXTURE; /* TODO: only set this if there are * actual changes. @@ -2934,17 +2939,6 @@ update_texture_state( GLcontext *ctx ) ctx->Texture._TexMatEnabled = 0; ctx->Texture._TexGenEnabled = 0; -#if FEATURE_ARB_fragment_shader - /* - * Grab texture image usage state from shader program. It must be - * grabbed every time uniform sampler changes, so maybe there is a - * better place to perform these rather expensive computations. - */ - if (ctx->ShaderObjects._FragmentShaderPresent) { - (**prog).GetTextureImageUsage (prog, progteximageusage); - } -#endif /* FEATURE_ARB_fragment_shader */ - /* * Update texture unit state. */ @@ -2956,15 +2950,14 @@ update_texture_state( GLcontext *ctx ) texUnit->_ReallyEnabled = 0; texUnit->_GenFlags = 0; - /* Get the bitmask of texture enables */ -#if FEATURE_ARB_fragment_shader - if (ctx->ShaderObjects._FragmentShaderPresent) { - enableBits = progteximageusage[unit]; - } - else -#endif - if (ctx->FragmentProgram._Enabled) { - enableBits = ctx->FragmentProgram.Current->TexturesUsed[unit]; + /* Get the bitmask of texture enables. + * enableBits will be a mask of the TEXTURE_*_BIT flags indicating + * which texture targets are enabled (fixed function) or referenced + * by a fragment shader/program. When multiple flags are set, we'll + * settle on the one with highest priority (see texture_override below). + */ + if (fprog) { + enableBits = fprog->Base.TexturesUsed[unit]; } else { if (!texUnit->Enabled) @@ -3081,21 +3074,23 @@ update_texture_state( GLcontext *ctx ) ctx->Texture._TexMatEnabled |= ENABLE_TEXMAT(unit); } - ctx->Texture._EnabledCoordUnits = ctx->Texture._EnabledUnits; - /* Fragment programs may need texture coordinates but not the - * corresponding texture images. - */ - if (ctx->ShaderObjects.CurrentProgram != NULL) { - ctx->Texture._EnabledCoordUnits |= (1 << ctx->Const.MaxTextureCoordUnits) - 1; + /* Determine which texture coordinate sets are actually needed */ + if (fprog) { + const GLuint coordMask = (1 << MAX_TEXTURE_COORD_UNITS) - 1; + ctx->Texture._EnabledCoordUnits + = (fprog->Base.InputsRead >> FRAG_ATTRIB_TEX0) & coordMask; } - else if (ctx->FragmentProgram._Enabled) { - ctx->Texture._EnabledCoordUnits |= - (ctx->FragmentProgram.Current->Base.InputsRead >> FRAG_ATTRIB_TEX0); + else { + ctx->Texture._EnabledCoordUnits = ctx->Texture._EnabledUnits; } } -void _mesa_update_texture( GLcontext *ctx, GLuint new_state ) +/** + * Update texture-related derived state. + */ +void +_mesa_update_texture( GLcontext *ctx, GLuint new_state ) { if (new_state & _NEW_TEXTURE_MATRIX) update_texture_matrices( ctx ); diff --git a/src/mesa/shader/arbprogparse.c b/src/mesa/shader/arbprogparse.c index c6ea5c4f97..5027264f03 100644 --- a/src/mesa/shader/arbprogparse.c +++ b/src/mesa/shader/arbprogparse.c @@ -1,8 +1,8 @@ /* * Mesa 3-D graphics library - * Version: 6.5.1 + * 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"), @@ -35,10 +35,12 @@ #include "arbprogparse.h" #include "grammar_mesa.h" #include "program.h" +#include "prog_parameter.h" +#include "prog_statevars.h" #include "context.h" #include "macros.h" #include "mtypes.h" -#include "program_instruction.h" +#include "prog_instruction.h" /* For ARB programs, use the NV instruction limits */ @@ -1008,7 +1010,7 @@ parse_matrix (GLcontext * ctx, const GLubyte ** inst, struct arb_program *Progra switch (mat) { case MATRIX_MODELVIEW: - *matrix = STATE_MODELVIEW; + *matrix = STATE_MODELVIEW_MATRIX; *matrix_idx = parse_integer (inst, Program); if (*matrix_idx > 0) { program_error(ctx, Program->Position, @@ -1018,15 +1020,15 @@ parse_matrix (GLcontext * ctx, const GLubyte ** inst, struct arb_program *Progra break; case MATRIX_PROJECTION: - *matrix = STATE_PROJECTION; + *matrix = STATE_PROJECTION_MATRIX; break; case MATRIX_MVP: - *matrix = STATE_MVP; + *matrix = STATE_MVP_MATRIX; break; case MATRIX_TEXTURE: - *matrix = STATE_TEXTURE; + *matrix = STATE_TEXTURE_MATRIX; *matrix_idx = parse_integer (inst, Program); if (*matrix_idx >= (GLint) ctx->Const.MaxTextureUnits) { program_error(ctx, Program->Position, "Invalid Texture Unit"); @@ -1044,7 +1046,7 @@ parse_matrix (GLcontext * ctx, const GLubyte ** inst, struct arb_program *Progra break; case MATRIX_PROGRAM: - *matrix = STATE_PROGRAM; + *matrix = STATE_PROGRAM_MATRIX; *matrix_idx = parse_integer (inst, Program); if (*matrix_idx >= (GLint) ctx->Const.MaxProgramMatrices) { program_error(ctx, Program->Position, "Invalid Program Matrix"); @@ -1083,7 +1085,8 @@ parse_matrix (GLcontext * ctx, const GLubyte ** inst, struct arb_program *Progra */ static GLuint parse_state_single_item (GLcontext * ctx, const GLubyte ** inst, - struct arb_program *Program, GLint * state_tokens) + struct arb_program *Program, + gl_state_index state_tokens[STATE_LENGTH]) { switch (*(*inst)++) { case STATE_MATERIAL_PARSER: @@ -1136,7 +1139,7 @@ parse_state_single_item (GLcontext * ctx, const GLubyte ** inst, state_tokens[2] = STATE_ATTENUATION; break; case LIGHT_HALF: - state_tokens[2] = STATE_HALF; + state_tokens[2] = STATE_HALF_VECTOR; break; case LIGHT_SPOT_DIRECTION: state_tokens[2] = STATE_SPOT_DIRECTION; @@ -1265,7 +1268,8 @@ parse_state_single_item (GLcontext * ctx, const GLubyte ** inst, case STATE_CLIP_PLANE: state_tokens[0] = STATE_CLIPPLANE; state_tokens[1] = parse_integer (inst, Program); - if (parse_clipplane_num (ctx, inst, Program, &state_tokens[1])) + if (parse_clipplane_num (ctx, inst, Program, + (GLint *) &state_tokens[1])) return 1; break; @@ -1283,17 +1287,17 @@ parse_state_single_item (GLcontext * ctx, const GLubyte ** inst, /* XXX: I think this is the correct format for a matrix row */ case STATE_MATRIX_ROWS: - state_tokens[0] = STATE_MATRIX; - if (parse_matrix - (ctx, inst, Program, &state_tokens[1], &state_tokens[2], - &state_tokens[5])) + if (parse_matrix(ctx, inst, Program, + (GLint *) &state_tokens[0], + (GLint *) &state_tokens[1], + (GLint *) &state_tokens[4])) return 1; - state_tokens[3] = parse_integer (inst, Program); /* The first row to grab */ + state_tokens[2] = parse_integer (inst, Program); /* The first row to grab */ if ((**inst) != 0) { /* Either the last row, 0 */ - state_tokens[4] = parse_integer (inst, Program); - if (state_tokens[4] < state_tokens[3]) { + state_tokens[3] = parse_integer (inst, Program); + if (state_tokens[3] < state_tokens[2]) { program_error(ctx, Program->Position, "Second matrix index less than the first"); /* state_tokens[4] vs. state_tokens[3] */ @@ -1301,7 +1305,7 @@ parse_state_single_item (GLcontext * ctx, const GLubyte ** inst, } } else { - state_tokens[4] = state_tokens[3]; + state_tokens[3] = state_tokens[2]; (*inst)++; } break; @@ -1342,7 +1346,8 @@ parse_state_single_item (GLcontext * ctx, const GLubyte ** inst, */ static GLuint parse_program_single_item (GLcontext * ctx, const GLubyte ** inst, - struct arb_program *Program, GLint * state_tokens) + struct arb_program *Program, + gl_state_index state_tokens[STATE_LENGTH]) { if (Program->Base.Target == GL_FRAGMENT_PROGRAM_ARB) state_tokens[0] = STATE_FRAGMENT_PROGRAM; @@ -1459,7 +1464,7 @@ parse_attrib_binding(GLcontext * ctx, const GLubyte ** inst, break; case FRAGMENT_ATTRIB_TEXCOORD: { - GLuint texcoord; + GLuint texcoord = 0; err = parse_texcoord_num (ctx, inst, Program, &texcoord); *inputReg = FRAG_ATTRIB_TEX0 + texcoord; } @@ -1520,7 +1525,7 @@ parse_attrib_binding(GLcontext * ctx, const GLubyte ** inst, case VERTEX_ATTRIB_TEXCOORD: { - GLuint unit; + GLuint unit = 0; err = parse_texcoord_num (ctx, inst, Program, &unit); *inputReg = VERT_ATTRIB_TEX0 + unit; } @@ -1717,7 +1722,7 @@ parse_param_elements (GLcontext * ctx, const GLubyte ** inst, { GLint idx; GLuint err = 0; - GLint state_tokens[6]; + gl_state_index state_tokens[STATE_LENGTH]; GLfloat const_values[4]; switch (*(*inst)++) { @@ -1728,14 +1733,18 @@ parse_param_elements (GLcontext * ctx, const GLubyte ** inst, /* If we adding STATE_MATRIX that has multiple rows, we need to * unroll it and call _mesa_add_state_reference() for each row */ - if ((state_tokens[0] == STATE_MATRIX) - && (state_tokens[3] != state_tokens[4])) { + if ((state_tokens[0] == STATE_MODELVIEW_MATRIX || + state_tokens[0] == STATE_PROJECTION_MATRIX || + state_tokens[0] == STATE_MVP_MATRIX || + state_tokens[0] == STATE_TEXTURE_MATRIX || + state_tokens[0] == STATE_PROGRAM_MATRIX) + && (state_tokens[2] != state_tokens[3])) { GLint row; - GLint first_row = state_tokens[3]; - GLint last_row = state_tokens[4]; + const GLint first_row = state_tokens[2]; + const GLint last_row = state_tokens[3]; for (row = first_row; row <= last_row; row++) { - state_tokens[3] = state_tokens[4] = row; + state_tokens[2] = state_tokens[3] = row; idx = _mesa_add_state_reference(Program->Base.Parameters, state_tokens); @@ -3329,198 +3338,18 @@ parse_vp_instruction (GLcontext * ctx, const GLubyte ** inst, #if DEBUG_PARSING static GLvoid -print_state_token (GLint token) -{ - switch (token) { - case STATE_MATERIAL: - fprintf (stderr, "STATE_MATERIAL "); - break; - case STATE_LIGHT: - fprintf (stderr, "STATE_LIGHT "); - break; - - case STATE_LIGHTMODEL_AMBIENT: - fprintf (stderr, "STATE_AMBIENT "); - break; - - case STATE_LIGHTMODEL_SCENECOLOR: - fprintf (stderr, "STATE_SCENECOLOR "); - break; - - case STATE_LIGHTPROD: - fprintf (stderr, "STATE_LIGHTPROD "); - break; - - case STATE_TEXGEN: - fprintf (stderr, "STATE_TEXGEN "); - break; - - case STATE_FOG_COLOR: - fprintf (stderr, "STATE_FOG_COLOR "); - break; - - case STATE_FOG_PARAMS: - fprintf (stderr, "STATE_FOG_PARAMS "); - break; - - case STATE_CLIPPLANE: - fprintf (stderr, "STATE_CLIPPLANE "); - break; - - case STATE_POINT_SIZE: - fprintf (stderr, "STATE_POINT_SIZE "); - break; - - case STATE_POINT_ATTENUATION: - fprintf (stderr, "STATE_ATTENUATION "); - break; - - case STATE_MATRIX: - fprintf (stderr, "STATE_MATRIX "); - break; - - case STATE_MODELVIEW: - fprintf (stderr, "STATE_MODELVIEW "); - break; - - case STATE_PROJECTION: - fprintf (stderr, "STATE_PROJECTION "); - break; - - case STATE_MVP: - fprintf (stderr, "STATE_MVP "); - break; - - case STATE_TEXTURE: - fprintf (stderr, "STATE_TEXTURE "); - break; - - case STATE_PROGRAM: - fprintf (stderr, "STATE_PROGRAM "); - break; - - case STATE_MATRIX_INVERSE: - fprintf (stderr, "STATE_INVERSE "); - break; - - case STATE_MATRIX_TRANSPOSE: - fprintf (stderr, "STATE_TRANSPOSE "); - break; - - case STATE_MATRIX_INVTRANS: - fprintf (stderr, "STATE_INVTRANS "); - break; - - case STATE_AMBIENT: - fprintf (stderr, "STATE_AMBIENT "); - break; - - case STATE_DIFFUSE: - fprintf (stderr, "STATE_DIFFUSE "); - break; - - case STATE_SPECULAR: - fprintf (stderr, "STATE_SPECULAR "); - break; - - case STATE_EMISSION: - fprintf (stderr, "STATE_EMISSION "); - break; - - case STATE_SHININESS: - fprintf (stderr, "STATE_SHININESS "); - break; - - case STATE_HALF: - fprintf (stderr, "STATE_HALF "); - break; - - case STATE_POSITION: - fprintf (stderr, "STATE_POSITION "); - break; - - case STATE_ATTENUATION: - fprintf (stderr, "STATE_ATTENUATION "); - break; - - case STATE_SPOT_DIRECTION: - fprintf (stderr, "STATE_DIRECTION "); - break; - - case STATE_TEXGEN_EYE_S: - fprintf (stderr, "STATE_TEXGEN_EYE_S "); - break; - - case STATE_TEXGEN_EYE_T: - fprintf (stderr, "STATE_TEXGEN_EYE_T "); - break; - - case STATE_TEXGEN_EYE_R: - fprintf (stderr, "STATE_TEXGEN_EYE_R "); - break; - - case STATE_TEXGEN_EYE_Q: - fprintf (stderr, "STATE_TEXGEN_EYE_Q "); - break; - - case STATE_TEXGEN_OBJECT_S: - fprintf (stderr, "STATE_TEXGEN_EYE_S "); - break; - - case STATE_TEXGEN_OBJECT_T: - fprintf (stderr, "STATE_TEXGEN_OBJECT_T "); - break; - - case STATE_TEXGEN_OBJECT_R: - fprintf (stderr, "STATE_TEXGEN_OBJECT_R "); - break; - - case STATE_TEXGEN_OBJECT_Q: - fprintf (stderr, "STATE_TEXGEN_OBJECT_Q "); - break; - - case STATE_TEXENV_COLOR: - fprintf (stderr, "STATE_TEXENV_COLOR "); - break; - - case STATE_DEPTH_RANGE: - fprintf (stderr, "STATE_DEPTH_RANGE "); - break; - - case STATE_VERTEX_PROGRAM: - fprintf (stderr, "STATE_VERTEX_PROGRAM "); - break; - - case STATE_FRAGMENT_PROGRAM: - fprintf (stderr, "STATE_FRAGMENT_PROGRAM "); - break; - - case STATE_ENV: - fprintf (stderr, "STATE_ENV "); - break; - - case STATE_LOCAL: - fprintf (stderr, "STATE_LOCAL "); - break; - - } - fprintf (stderr, "[%d] ", token); -} - - -static GLvoid debug_variables (GLcontext * ctx, struct var_cache *vc_head, struct arb_program *Program) { struct var_cache *vc; GLint a, b; - fprintf (stderr, "debug_variables, vc_head: %x\n", vc_head); + fprintf (stderr, "debug_variables, vc_head: %p\n", (void*) vc_head); /* First of all, print out the contents of the var_cache */ vc = vc_head; while (vc) { - fprintf (stderr, "[%x]\n", vc); + fprintf (stderr, "[%p]\n", (void*) vc); switch (vc->type) { case vt_none: fprintf (stderr, "UNDEFINED %s\n", vc->name); @@ -3535,27 +3364,20 @@ debug_variables (GLcontext * ctx, struct var_cache *vc_head, b = vc->param_binding_begin; for (a = 0; a < vc->param_binding_length; a++) { fprintf (stderr, "%s\n", - Program->Parameters->Parameters[a + b].Name); - if (Program->Parameters->Parameters[a + b].Type == STATE) { - print_state_token (Program->Parameters->Parameters[a + b]. - StateIndexes[0]); - print_state_token (Program->Parameters->Parameters[a + b]. - StateIndexes[1]); - print_state_token (Program->Parameters->Parameters[a + b]. - StateIndexes[2]); - print_state_token (Program->Parameters->Parameters[a + b]. - StateIndexes[3]); - print_state_token (Program->Parameters->Parameters[a + b]. - StateIndexes[4]); - print_state_token (Program->Parameters->Parameters[a + b]. - StateIndexes[5]); + Program->Base.Parameters->Parameters[a + b].Name); + if (Program->Base.Parameters->Parameters[a + b].Type == PROGRAM_STATE_VAR) { + const char *s; + s = _mesa_program_state_string(Program->Base.Parameters->Parameters + [a + b].StateIndexes); + fprintf(stderr, "%s\n", s); + _mesa_free((char *) s); } else fprintf (stderr, "%f %f %f %f\n", - Program->Parameters->Parameters[a + b].Values[0], - Program->Parameters->Parameters[a + b].Values[1], - Program->Parameters->Parameters[a + b].Values[2], - Program->Parameters->Parameters[a + b].Values[3]); + Program->Base.Parameters->ParameterValues[a + b][0], + Program->Base.Parameters->ParameterValues[a + b][1], + Program->Base.Parameters->ParameterValues[a + b][2], + Program->Base.Parameters->ParameterValues[a + b][3]); } break; case vt_temp: @@ -3568,9 +3390,12 @@ debug_variables (GLcontext * ctx, struct var_cache *vc_head, break; case vt_alias: fprintf (stderr, "ALIAS %s\n", vc->name); - fprintf (stderr, " binding: 0x%x (%s)\n", - vc->alias_binding, vc->alias_binding->name); + fprintf (stderr, " binding: 0x%p (%s)\n", + (void*) vc->alias_binding, vc->alias_binding->name); break; + default: + /* nothing */ + ; } vc = vc->next; } @@ -4027,16 +3852,16 @@ _mesa_parse_arb_fragment_program(GLcontext* ctx, GLenum target, program->Base.NumNativeParameters = ap.Base.NumNativeParameters; program->Base.NumNativeAttributes = ap.Base.NumNativeAttributes; program->Base.NumNativeAddressRegs = ap.Base.NumNativeAddressRegs; - program->NumAluInstructions = ap.NumAluInstructions; - program->NumTexInstructions = ap.NumTexInstructions; - program->NumTexIndirections = ap.NumTexIndirections; - program->NumNativeAluInstructions = ap.NumAluInstructions; - program->NumNativeTexInstructions = ap.NumTexInstructions; - program->NumNativeTexIndirections = ap.NumTexIndirections; + program->Base.NumAluInstructions = ap.Base.NumAluInstructions; + program->Base.NumTexInstructions = ap.Base.NumTexInstructions; + program->Base.NumTexIndirections = ap.Base.NumTexIndirections; + program->Base.NumNativeAluInstructions = ap.Base.NumAluInstructions; + program->Base.NumNativeTexInstructions = ap.Base.NumTexInstructions; + program->Base.NumNativeTexIndirections = ap.Base.NumTexIndirections; program->Base.InputsRead = ap.Base.InputsRead; program->Base.OutputsWritten = ap.Base.OutputsWritten; for (i = 0; i < MAX_TEXTURE_IMAGE_UNITS; i++) - program->TexturesUsed[i] = ap.TexturesUsed[i]; + program->Base.TexturesUsed[i] = ap.TexturesUsed[i]; program->FogOption = ap.FogOption; program->UsesKill = ap.UsesKill; diff --git a/src/mesa/shader/arbprogram.c b/src/mesa/shader/arbprogram.c index 91f3a5e8ee..5583f16ce8 100644 --- a/src/mesa/shader/arbprogram.c +++ b/src/mesa/shader/arbprogram.c @@ -720,22 +720,22 @@ _mesa_GetProgramivARB(GLenum target, GLenum pname, GLint *params) const struct gl_fragment_program *fp = ctx->FragmentProgram.Current; switch (pname) { case GL_PROGRAM_ALU_INSTRUCTIONS_ARB: - *params = fp->NumNativeAluInstructions; + *params = fp->Base.NumNativeAluInstructions; return; case GL_PROGRAM_NATIVE_ALU_INSTRUCTIONS_ARB: - *params = fp->NumAluInstructions; + *params = fp->Base.NumAluInstructions; return; case GL_PROGRAM_TEX_INSTRUCTIONS_ARB: - *params = fp->NumTexInstructions; + *params = fp->Base.NumTexInstructions; return; case GL_PROGRAM_NATIVE_TEX_INSTRUCTIONS_ARB: - *params = fp->NumNativeTexInstructions; + *params = fp->Base.NumNativeTexInstructions; return; case GL_PROGRAM_TEX_INDIRECTIONS_ARB: - *params = fp->NumTexIndirections; + *params = fp->Base.NumTexIndirections; return; case GL_PROGRAM_NATIVE_TEX_INDIRECTIONS_ARB: - *params = fp->NumNativeTexIndirections; + *params = fp->Base.NumNativeTexIndirections; return; case GL_MAX_PROGRAM_ALU_INSTRUCTIONS_ARB: *params = limits->MaxAluInstructions; diff --git a/src/mesa/shader/asmopcodes.reg b/src/mesa/shader/asmopcodes.reg deleted file mode 100644 index efd8918f21..0000000000 --- a/src/mesa/shader/asmopcodes.reg +++ /dev/null @@ -1,78 +0,0 @@ -/* */
-/* ARB program opcode registry */
-/* each instruction code has its own unique number */
-/* this registry exists to ensure that this relation retains */
-/* */
-
-/* GL_ARB_vertex_program */
-ABS 0x00
-ADD 0x01
-ARL 0x02
-DP3 0x03
-DP4 0x04
-DPH 0x05
-DST 0x06
-EX2 0x07
-EXP 0x08
-FLR 0x09
-FRC 0x0A
-LG2 0x0B
-LIT 0x0C
-LOG 0x0D
-MAD 0x0E
-MAX 0x0F
-MIN 0x10
-MOV 0x11
-MUL 0x12
-POW 0x13
-RCP 0x14
-RSQ 0x15
-SGE 0x16
-SLT 0x17
-SUB 0x18
-SWZ 0x19
-XPD 0x1A
-
-/* GL_ARB_fragment_program */
-ABS_SAT 0x1B
-ADD_SAT 0x1C
-CMP 0x1D
-CMP_SAT 0x1E
-COS 0x1F
-COS_SAT 0x20
-DP3_SAT 0x21
-DP4_SAT 0x22
-DPH_SAT 0x23
-DST_SAT 0x24
-EX2_SAT 0x25
-FLR_SAT 0x26
-FRC_SAT 0x27
-KIL 0x28
-LG2_SAT 0x29
-LIT_SAT 0x2A
-LRP 0x2B
-LRP_SAT 0x2C
-MAD_SAT 0x2D
-MAX_SAT 0x2E
-MIN_SAT 0x2F
-MOV_SAT 0x30
-MUL_SAT 0x31
-POW_SAT 0x32
-RCP_SAT 0x33
-RSQ_SAT 0x34
-SCS 0x35
-SCS_SAT 0x36
-SGE_SAT 0x37
-SIN 0x38
-SIN_SAT 0x39
-SLT_SAT 0x3A
-SUB_SAT 0x3B
-SWZ_SAT 0x3C
-TEX 0x3D
-TEX_SAT 0x3E
-TXB 0x3F
-TXB_SAT 0x40
-TXP 0x41
-TXP_SAT 0x42
-XPD_SAT 0x43
-
diff --git a/src/mesa/shader/grammar/grammar.c b/src/mesa/shader/grammar/grammar.c index 7f2ee42d21..989e954491 100644 --- a/src/mesa/shader/grammar/grammar.c +++ b/src/mesa/shader/grammar/grammar.c @@ -260,6 +260,8 @@ first). */ +#include <stdio.h> + static void mem_free (void **); /* @@ -2797,10 +2799,16 @@ static void grammar_load_state_destroy (grammar_load_state **gr) } } + +static void error_msg(int line, const char *msg) +{ + fprintf(stderr, "Error in grammar_load_from_text() at line %d: %s\n", line, msg); +} + + /* the API */ - grammar grammar_load_from_text (const byte *text) { grammar_load_state *g = NULL; @@ -2809,13 +2817,16 @@ grammar grammar_load_from_text (const byte *text) clear_last_error (); grammar_load_state_create (&g); - if (g == NULL) + if (g == NULL) { + error_msg(__LINE__, ""); return 0; + } dict_create (&g->di); if (g->di == NULL) { grammar_load_state_destroy (&g); + error_msg(__LINE__, ""); return 0; } @@ -2829,6 +2840,7 @@ grammar grammar_load_from_text (const byte *text) if (get_identifier (&text, &g->syntax_symbol)) { grammar_load_state_destroy (&g); + error_msg(__LINE__, ""); return 0; } eat_spaces (&text); @@ -2848,6 +2860,7 @@ grammar grammar_load_from_text (const byte *text) if (get_identifier (&text, &symbol)) { grammar_load_state_destroy (&g); + error_msg(__LINE__, ""); return 0; } eat_spaces (&text); @@ -2862,6 +2875,7 @@ grammar grammar_load_from_text (const byte *text) if (get_emtcode (&text, &ma)) { grammar_load_state_destroy (&g); + error_msg(__LINE__, ""); return 0; } @@ -2877,6 +2891,7 @@ grammar grammar_load_from_text (const byte *text) if (get_regbyte (&text, &ma)) { grammar_load_state_destroy (&g); + error_msg(__LINE__, ""); return 0; } @@ -2892,6 +2907,7 @@ grammar grammar_load_from_text (const byte *text) if (get_errtext (&text, &ma)) { grammar_load_state_destroy (&g); + error_msg(__LINE__, ""); return 0; } @@ -2905,12 +2921,14 @@ grammar grammar_load_from_text (const byte *text) if (g->di->m_string != NULL) { grammar_load_state_destroy (&g); + error_msg(__LINE__, ""); return 0; } if (get_identifier (&text, &g->string_symbol)) { grammar_load_state_destroy (&g); + error_msg(__LINE__, ""); return 0; } @@ -2927,6 +2945,7 @@ grammar grammar_load_from_text (const byte *text) if (get_rule (&text, &ru, g->maps, g->mapb)) { grammar_load_state_destroy (&g); + error_msg(__LINE__, ""); return 0; } @@ -2940,6 +2959,7 @@ grammar grammar_load_from_text (const byte *text) if (ma == NULL) { grammar_load_state_destroy (&g); + error_msg(__LINE__, ""); return 0; } @@ -2953,6 +2973,7 @@ grammar grammar_load_from_text (const byte *text) g->di->m_regbytes)) { grammar_load_state_destroy (&g); + error_msg(__LINE__, "update_dependencies() failed"); return 0; } diff --git a/src/mesa/shader/grammar/grammar_crt.c b/src/mesa/shader/grammar/grammar_crt.c index bdf2da9b2e..bdf2da9b2e 100755..100644 --- a/src/mesa/shader/grammar/grammar_crt.c +++ b/src/mesa/shader/grammar/grammar_crt.c diff --git a/src/mesa/shader/grammar/grammar_crt.h b/src/mesa/shader/grammar/grammar_crt.h index 492711e96a..492711e96a 100755..100644 --- a/src/mesa/shader/grammar/grammar_crt.h +++ b/src/mesa/shader/grammar/grammar_crt.h diff --git a/src/mesa/shader/nvfragparse.c b/src/mesa/shader/nvfragparse.c index 79e6dbd87b..ffa7ba4701 100644 --- a/src/mesa/shader/nvfragparse.c +++ b/src/mesa/shader/nvfragparse.c @@ -39,13 +39,11 @@ #include "glheader.h" #include "context.h" -#include "hash.h" #include "imports.h" #include "macros.h" -#include "mtypes.h" -#include "program_instruction.h" +#include "prog_parameter.h" +#include "prog_instruction.h" #include "nvfragparse.h" -#include "nvprogram.h" #include "program.h" @@ -1038,21 +1036,25 @@ Parse_VectorSrc(struct parse_state *parseState, else if (IsDigit(token[0]) || token[0] == '-' || token[0] == '+' || token[0] == '.'){ /* literal scalar constant */ GLfloat values[4]; - GLuint paramIndex; + GLuint paramIndex, swizzle; if (!Parse_ScalarConstant(parseState, values)) RETURN_ERROR; - paramIndex = _mesa_add_unnamed_constant(parseState->parameters, values, 4); + paramIndex = _mesa_add_unnamed_constant(parseState->parameters, + values, 4, NULL); + ASSERT(swizzle == SWIZZLE_NOOP); srcReg->File = PROGRAM_NAMED_PARAM; srcReg->Index = paramIndex; } else if (token[0] == '{'){ /* literal vector constant */ GLfloat values[4]; - GLuint paramIndex; + GLuint paramIndex, swizzle; (void) Parse_String(parseState, "{"); if (!Parse_VectorConstant(parseState, values)) RETURN_ERROR; - paramIndex = _mesa_add_unnamed_constant(parseState->parameters, values, 4); + paramIndex = _mesa_add_unnamed_constant(parseState->parameters, + values, 4, NULL); + ASSERT(swizzle == SWIZZLE_NOOP); srcReg->File = PROGRAM_NAMED_PARAM; srcReg->Index = paramIndex; } @@ -1138,11 +1140,13 @@ Parse_ScalarSrcReg(struct parse_state *parseState, else if (token[0] == '{') { /* vector literal */ GLfloat values[4]; - GLuint paramIndex; + GLuint paramIndex, swizzle; (void) Parse_String(parseState, "{"); if (!Parse_VectorConstant(parseState, values)) RETURN_ERROR; - paramIndex = _mesa_add_unnamed_constant(parseState->parameters, values, 4); + paramIndex = _mesa_add_unnamed_constant(parseState->parameters, + values, 4, NULL); + ASSERT(swizzle == SWIZZLE_NOOP); srcReg->File = PROGRAM_NAMED_PARAM; srcReg->Index = paramIndex; } @@ -1163,10 +1167,12 @@ Parse_ScalarSrcReg(struct parse_state *parseState, else if (IsDigit(token[0])) { /* scalar literal */ GLfloat values[4]; - GLuint paramIndex; + GLuint paramIndex, swizzle; if (!Parse_ScalarConstant(parseState, values)) RETURN_ERROR; - paramIndex = _mesa_add_unnamed_constant(parseState->parameters, values, 4); + paramIndex = _mesa_add_unnamed_constant(parseState->parameters, + values, 4, NULL); + ASSERT(swizzle == SWIZZLE_NOOP); srcReg->Index = paramIndex; srcReg->File = PROGRAM_NAMED_PARAM; needSuffix = GL_FALSE; @@ -1539,8 +1545,7 @@ _mesa_parse_nv_fragment_program(GLcontext *ctx, GLenum dstTarget, _mesa_error(ctx, GL_OUT_OF_MEMORY, "glLoadProgramNV"); return; /* out of memory */ } - _mesa_memcpy(newInst, instBuffer, - parseState.numInst * sizeof(struct prog_instruction)); + _mesa_copy_instructions(newInst, instBuffer, parseState.numInst); /* install the program */ program->Base.Target = target; @@ -1557,7 +1562,7 @@ _mesa_parse_nv_fragment_program(GLcontext *ctx, GLenum dstTarget, program->Base.InputsRead = parseState.inputsRead; program->Base.OutputsWritten = parseState.outputsWritten; for (u = 0; u < ctx->Const.MaxTextureImageUnits; u++) - program->TexturesUsed[u] = parseState.texturesUsed[u]; + program->Base.TexturesUsed[u] = parseState.texturesUsed[u]; /* save program parameters */ program->Base.Parameters = parseState.parameters; diff --git a/src/mesa/shader/nvprogram.c b/src/mesa/shader/nvprogram.c index 4f160b1431..337784bfe2 100644 --- a/src/mesa/shader/nvprogram.c +++ b/src/mesa/shader/nvprogram.c @@ -42,10 +42,9 @@ #include "hash.h" #include "imports.h" #include "macros.h" -#include "mtypes.h" +#include "prog_parameter.h" +#include "prog_instruction.h" #include "nvfragparse.h" -#include "program_instruction.h" -#include "nvvertexec.h" #include "nvvertparse.h" #include "nvprogram.h" #include "program.h" @@ -77,7 +76,7 @@ _mesa_ExecuteProgramNV(GLenum target, GLuint id, const GLfloat *params) return; } - _mesa_exec_vertex_state_program(ctx, vprog, params); + _mesa_problem(ctx, "glExecuteProgramNV() not supported"); } diff --git a/src/mesa/shader/nvvertexec.c b/src/mesa/shader/nvvertexec.c deleted file mode 100644 index 10962d7e14..0000000000 --- a/src/mesa/shader/nvvertexec.c +++ /dev/null @@ -1,835 +0,0 @@ -/* - * Mesa 3-D graphics library - * Version: 6.5.2 - * - * Copyright (C) 1999-2006 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. - */ - -/** - * \file nvvertexec.c - * Code to execute vertex programs. - * \author Brian Paul - */ - -#include "glheader.h" -#include "context.h" -#include "imports.h" -#include "macros.h" -#include "mtypes.h" -#include "nvvertexec.h" -#include "program_instruction.h" -#include "program.h" -#include "math/m_matrix.h" - - -static const GLfloat ZeroVec[4] = { 0.0F, 0.0F, 0.0F, 0.0F }; - - -/** - * Load/initialize the vertex program registers which need to be set - * per-vertex. - */ -void -_mesa_init_vp_per_vertex_registers(GLcontext *ctx, struct vp_machine *machine) -{ - /* Input registers get initialized from the current vertex attribs */ - MEMCPY(machine->Inputs, ctx->Current.Attrib, - MAX_VERTEX_PROGRAM_ATTRIBS * 4 * sizeof(GLfloat)); - - if (ctx->VertexProgram.Current->IsNVProgram) { - GLuint i; - /* Output/result regs are initialized to [0,0,0,1] */ - for (i = 0; i < MAX_NV_VERTEX_PROGRAM_OUTPUTS; i++) { - ASSIGN_4V(machine->Outputs[i], 0.0F, 0.0F, 0.0F, 1.0F); - } - /* Temp regs are initialized to [0,0,0,0] */ - for (i = 0; i < MAX_NV_VERTEX_PROGRAM_TEMPS; i++) { - ASSIGN_4V(machine->Temporaries[i], 0.0F, 0.0F, 0.0F, 0.0F); - } - ASSIGN_4V(machine->AddressReg, 0, 0, 0, 0); - } -} - - - -/** - * Copy the 16 elements of a matrix into four consecutive program - * registers starting at 'pos'. - */ -static void -load_matrix(GLfloat registers[][4], GLuint pos, const GLfloat mat[16]) -{ - GLuint i; - for (i = 0; i < 4; i++) { - registers[pos + i][0] = mat[0 + i]; - registers[pos + i][1] = mat[4 + i]; - registers[pos + i][2] = mat[8 + i]; - registers[pos + i][3] = mat[12 + i]; - } -} - - -/** - * As above, but transpose the matrix. - */ -static void -load_transpose_matrix(GLfloat registers[][4], GLuint pos, - const GLfloat mat[16]) -{ - MEMCPY(registers[pos], mat, 16 * sizeof(GLfloat)); -} - - -/** - * Load program parameter registers with tracked matrices (if NV program) - * or GL state values (if ARB program). - * This needs to be done per glBegin/glEnd, not per-vertex. - */ -void -_mesa_init_vp_per_primitive_registers(GLcontext *ctx) -{ - if (ctx->VertexProgram.Current->IsNVProgram) { - GLuint i; - - for (i = 0; i < MAX_NV_VERTEX_PROGRAM_PARAMS / 4; i++) { - /* point 'mat' at source matrix */ - GLmatrix *mat; - if (ctx->VertexProgram.TrackMatrix[i] == GL_MODELVIEW) { - mat = ctx->ModelviewMatrixStack.Top; - } - else if (ctx->VertexProgram.TrackMatrix[i] == GL_PROJECTION) { - mat = ctx->ProjectionMatrixStack.Top; - } - else if (ctx->VertexProgram.TrackMatrix[i] == GL_TEXTURE) { - mat = ctx->TextureMatrixStack[ctx->Texture.CurrentUnit].Top; - } - else if (ctx->VertexProgram.TrackMatrix[i] == GL_COLOR) { - mat = ctx->ColorMatrixStack.Top; - } - else if (ctx->VertexProgram.TrackMatrix[i]==GL_MODELVIEW_PROJECTION_NV) { - /* XXX verify the combined matrix is up to date */ - mat = &ctx->_ModelProjectMatrix; - } - else if (ctx->VertexProgram.TrackMatrix[i] >= GL_MATRIX0_NV && - ctx->VertexProgram.TrackMatrix[i] <= GL_MATRIX7_NV) { - GLuint n = ctx->VertexProgram.TrackMatrix[i] - GL_MATRIX0_NV; - ASSERT(n < MAX_PROGRAM_MATRICES); - mat = ctx->ProgramMatrixStack[n].Top; - } - else { - /* no matrix is tracked, but we leave the register values as-is */ - assert(ctx->VertexProgram.TrackMatrix[i] == GL_NONE); - continue; - } - - /* load the matrix values into sequential registers */ - if (ctx->VertexProgram.TrackMatrixTransform[i] == GL_IDENTITY_NV) { - load_matrix(ctx->VertexProgram.Parameters, i*4, mat->m); - } - else if (ctx->VertexProgram.TrackMatrixTransform[i] == GL_INVERSE_NV) { - _math_matrix_analyse(mat); /* update the inverse */ - ASSERT(!_math_matrix_is_dirty(mat)); - load_matrix(ctx->VertexProgram.Parameters, i*4, mat->inv); - } - else if (ctx->VertexProgram.TrackMatrixTransform[i] == GL_TRANSPOSE_NV) { - load_transpose_matrix(ctx->VertexProgram.Parameters, i*4, mat->m); - } - else { - assert(ctx->VertexProgram.TrackMatrixTransform[i] - == GL_INVERSE_TRANSPOSE_NV); - _math_matrix_analyse(mat); /* update the inverse */ - ASSERT(!_math_matrix_is_dirty(mat)); - load_transpose_matrix(ctx->VertexProgram.Parameters, i*4, mat->inv); - } - } - } - else { - /* ARB vertex program */ - if (ctx->VertexProgram.Current->Base.Parameters) { - /* Grab the state GL state and put into registers */ - _mesa_load_state_parameters(ctx, - ctx->VertexProgram.Current->Base.Parameters); - } - } -} - - - -/** - * For debugging. Dump the current vertex program machine registers. - */ -void -_mesa_dump_vp_state( const struct gl_vertex_program_state *state, - const struct vp_machine *machine) -{ - int i; - _mesa_printf("VertexIn:\n"); - for (i = 0; i < MAX_NV_VERTEX_PROGRAM_INPUTS; i++) { - _mesa_printf("%d: %f %f %f %f ", i, - machine->Inputs[i][0], - machine->Inputs[i][1], - machine->Inputs[i][2], - machine->Inputs[i][3]); - } - _mesa_printf("\n"); - - _mesa_printf("VertexOut:\n"); - for (i = 0; i < MAX_NV_VERTEX_PROGRAM_OUTPUTS; i++) { - _mesa_printf("%d: %f %f %f %f ", i, - machine->Outputs[i][0], - machine->Outputs[i][1], - machine->Outputs[i][2], - machine->Outputs[i][3]); - } - _mesa_printf("\n"); - - _mesa_printf("Registers:\n"); - for (i = 0; i < MAX_NV_VERTEX_PROGRAM_TEMPS; i++) { - _mesa_printf("%d: %f %f %f %f ", i, - machine->Temporaries[i][0], - machine->Temporaries[i][1], - machine->Temporaries[i][2], - machine->Temporaries[i][3]); - } - _mesa_printf("\n"); - - _mesa_printf("Parameters:\n"); - for (i = 0; i < MAX_NV_VERTEX_PROGRAM_PARAMS; i++) { - _mesa_printf("%d: %f %f %f %f ", i, - state->Parameters[i][0], - state->Parameters[i][1], - state->Parameters[i][2], - state->Parameters[i][3]); - } - _mesa_printf("\n"); -} - - - -/** - * Return a pointer to the 4-element float vector specified by the given - * source register. - */ -static INLINE const GLfloat * -get_register_pointer( GLcontext *ctx, - const struct prog_src_register *source, - struct vp_machine *machine, - const struct gl_vertex_program *program ) -{ - if (source->RelAddr) { - const GLint reg = source->Index + machine->AddressReg[0]; - ASSERT( (source->File == PROGRAM_ENV_PARAM) || - (source->File == PROGRAM_STATE_VAR) ); - if (reg < 0 || reg > MAX_NV_VERTEX_PROGRAM_PARAMS) - return ZeroVec; - else if (source->File == PROGRAM_ENV_PARAM) - return ctx->VertexProgram.Parameters[reg]; - else { - ASSERT(source->File == PROGRAM_LOCAL_PARAM); - return program->Base.Parameters->ParameterValues[reg]; - } - } - else { - switch (source->File) { - case PROGRAM_TEMPORARY: - ASSERT(source->Index < MAX_NV_VERTEX_PROGRAM_TEMPS); - return machine->Temporaries[source->Index]; - case PROGRAM_INPUT: - ASSERT(source->Index < MAX_NV_VERTEX_PROGRAM_INPUTS); - return machine->Inputs[source->Index]; - case PROGRAM_OUTPUT: - /* This is only needed for the PRINT instruction */ - ASSERT(source->Index < MAX_NV_VERTEX_PROGRAM_OUTPUTS); - return machine->Outputs[source->Index]; - case PROGRAM_LOCAL_PARAM: - ASSERT(source->Index < MAX_PROGRAM_LOCAL_PARAMS); - return program->Base.LocalParams[source->Index]; - case PROGRAM_ENV_PARAM: - ASSERT(source->Index < MAX_NV_VERTEX_PROGRAM_PARAMS); - return ctx->VertexProgram.Parameters[source->Index]; - case PROGRAM_STATE_VAR: - ASSERT(source->Index < program->Base.Parameters->NumParameters); - return program->Base.Parameters->ParameterValues[source->Index]; - default: - _mesa_problem(NULL, - "Bad source register file in get_register_pointer"); - return NULL; - } - } - return NULL; -} - - -/** - * Fetch a 4-element float vector from the given source register. - * Apply swizzling and negating as needed. - */ -static INLINE void -fetch_vector4( GLcontext *ctx, - const struct prog_src_register *source, - struct vp_machine *machine, - const struct gl_vertex_program *program, - GLfloat result[4] ) -{ - const GLfloat *src = get_register_pointer(ctx, source, machine, program); - ASSERT(src); - result[0] = src[GET_SWZ(source->Swizzle, 0)]; - result[1] = src[GET_SWZ(source->Swizzle, 1)]; - result[2] = src[GET_SWZ(source->Swizzle, 2)]; - result[3] = src[GET_SWZ(source->Swizzle, 3)]; - if (source->NegateBase) { - result[0] = -result[0]; - result[1] = -result[1]; - result[2] = -result[2]; - result[3] = -result[3]; - } -} - - - -/** - * As above, but only return result[0] element. - */ -static INLINE void -fetch_vector1( GLcontext *ctx, - const struct prog_src_register *source, - struct vp_machine *machine, - const struct gl_vertex_program *program, - GLfloat result[4] ) -{ - const GLfloat *src = get_register_pointer(ctx, source, machine, program); - ASSERT(src); - result[0] = src[GET_SWZ(source->Swizzle, 0)]; - if (source->NegateBase) { - result[0] = -result[0]; - } -} - - -/** - * Store 4 floats into a register. - */ -static void -store_vector4( const struct prog_instruction *inst, - struct vp_machine *machine, - const GLfloat value[4] ) -{ - const struct prog_dst_register *dest = &(inst->DstReg); - GLfloat *dst; - switch (dest->File) { - case PROGRAM_OUTPUT: - dst = machine->Outputs[dest->Index]; - break; - case PROGRAM_TEMPORARY: - dst = machine->Temporaries[dest->Index]; - break; - case PROGRAM_ENV_PARAM: - /* Only for VP state programs */ - { - /* a slight hack */ - GET_CURRENT_CONTEXT(ctx); - dst = ctx->VertexProgram.Parameters[dest->Index]; - } - break; - default: - _mesa_problem(NULL, "Invalid register file in store_vector4(file=%d)", - dest->File); - return; - } - - if (dest->WriteMask & WRITEMASK_X) - dst[0] = value[0]; - if (dest->WriteMask & WRITEMASK_Y) - dst[1] = value[1]; - if (dest->WriteMask & WRITEMASK_Z) - dst[2] = value[2]; - if (dest->WriteMask & WRITEMASK_W) - dst[3] = value[3]; -} - - -/** - * Set x to positive or negative infinity. - */ -#if defined(USE_IEEE) || defined(_WIN32) -#define SET_POS_INFINITY(x) ( *((GLuint *) (void *)&x) = 0x7F800000 ) -#define SET_NEG_INFINITY(x) ( *((GLuint *) (void *)&x) = 0xFF800000 ) -#elif defined(VMS) -#define SET_POS_INFINITY(x) x = __MAXFLOAT -#define SET_NEG_INFINITY(x) x = -__MAXFLOAT -#else -#define SET_POS_INFINITY(x) x = (GLfloat) HUGE_VAL -#define SET_NEG_INFINITY(x) x = (GLfloat) -HUGE_VAL -#endif - -#define SET_FLOAT_BITS(x, bits) ((fi_type *) (void *) &(x))->i = bits - - -/** - * Execute the given vertex program - */ -void -_mesa_exec_vertex_program(GLcontext *ctx, - struct vp_machine *machine, - const struct gl_vertex_program *program) -{ - const struct prog_instruction *inst; - - ctx->_CurrentProgram = GL_VERTEX_PROGRAM_ARB; /* or NV, doesn't matter */ - - /* If the program is position invariant, multiply the input position - * by the MVP matrix and store in the vertex position result register. - */ - if (ctx->VertexProgram.Current->IsPositionInvariant) { - TRANSFORM_POINT( machine->Outputs[VERT_RESULT_HPOS], - ctx->_ModelProjectMatrix.m, - machine->Inputs[VERT_ATTRIB_POS]); - - /* XXX: This could go elsewhere */ - ctx->VertexProgram.Current->Base.OutputsWritten |= VERT_BIT_POS; - } - - for (inst = program->Base.Instructions; ; inst++) { - - if (ctx->VertexProgram.CallbackEnabled && - ctx->VertexProgram.Callback) { - ctx->VertexProgram.CurrentPosition = inst->StringPos; - ctx->VertexProgram.Callback(program->Base.Target, - ctx->VertexProgram.CallbackData); - } - - switch (inst->Opcode) { - case OPCODE_MOV: - { - GLfloat t[4]; - fetch_vector4( ctx, &inst->SrcReg[0], machine, program, t ); - store_vector4( inst, machine, t ); - } - break; - case OPCODE_LIT: - { - const GLfloat epsilon = 1.0F / 256.0F; /* per NV spec */ - GLfloat t[4], lit[4]; - fetch_vector4( ctx, &inst->SrcReg[0], machine, program, t ); - t[0] = MAX2(t[0], 0.0F); - t[1] = MAX2(t[1], 0.0F); - t[3] = CLAMP(t[3], -(128.0F - epsilon), (128.0F - epsilon)); - lit[0] = 1.0; - lit[1] = t[0]; - lit[2] = (t[0] > 0.0) ? (GLfloat) _mesa_pow(t[1], t[3]) : 0.0F; - lit[3] = 1.0; - store_vector4( inst, machine, lit ); - } - break; - case OPCODE_RCP: - { - GLfloat t[4]; - fetch_vector1( ctx, &inst->SrcReg[0], machine, program, t ); - if (t[0] != 1.0F) - t[0] = 1.0F / t[0]; /* div by zero is infinity! */ - t[1] = t[2] = t[3] = t[0]; - store_vector4( inst, machine, t ); - } - break; - case OPCODE_RSQ: - { - GLfloat t[4]; - fetch_vector1( ctx, &inst->SrcReg[0], machine, program, t ); - t[0] = INV_SQRTF(FABSF(t[0])); - t[1] = t[2] = t[3] = t[0]; - store_vector4( inst, machine, t ); - } - break; - case OPCODE_EXP: - { - GLfloat t[4], q[4], floor_t0; - fetch_vector1( ctx, &inst->SrcReg[0], machine, program, t ); - floor_t0 = FLOORF(t[0]); - if (floor_t0 > FLT_MAX_EXP) { - SET_POS_INFINITY(q[0]); - SET_POS_INFINITY(q[2]); - } - else if (floor_t0 < FLT_MIN_EXP) { - q[0] = 0.0F; - q[2] = 0.0F; - } - else { -#ifdef USE_IEEE - GLint ii = (GLint) floor_t0; - ii = (ii < 23) + 0x3f800000; - SET_FLOAT_BITS(q[0], ii); - q[0] = *((GLfloat *) (void *)&ii); -#else - q[0] = (GLfloat) pow(2.0, floor_t0); -#endif - q[2] = (GLfloat) (q[0] * LOG2(q[1])); - } - q[1] = t[0] - floor_t0; - q[3] = 1.0F; - store_vector4( inst, machine, q ); - } - break; - case OPCODE_LOG: - { - GLfloat t[4], q[4], abs_t0; - fetch_vector1( ctx, &inst->SrcReg[0], machine, program, t ); - abs_t0 = FABSF(t[0]); - if (abs_t0 != 0.0F) { - /* Since we really can't handle infinite values on VMS - * like other OSes we'll use __MAXFLOAT to represent - * infinity. This may need some tweaking. - */ -#ifdef VMS - if (abs_t0 == __MAXFLOAT) -#else - if (IS_INF_OR_NAN(abs_t0)) -#endif - { - SET_POS_INFINITY(q[0]); - q[1] = 1.0F; - SET_POS_INFINITY(q[2]); - } - else { - int exponent; - GLfloat mantissa = FREXPF(t[0], &exponent); - q[0] = (GLfloat) (exponent - 1); - q[1] = (GLfloat) (2.0 * mantissa); /* map [.5, 1) -> [1, 2) */ - q[2] = (GLfloat) (q[0] + LOG2(q[1])); - } - } - else { - SET_NEG_INFINITY(q[0]); - q[1] = 1.0F; - SET_NEG_INFINITY(q[2]); - } - q[3] = 1.0; - store_vector4( inst, machine, q ); - } - break; - case OPCODE_MUL: - { - GLfloat t[4], u[4], prod[4]; - fetch_vector4( ctx, &inst->SrcReg[0], machine, program, t ); - fetch_vector4( ctx, &inst->SrcReg[1], machine, program, u ); - prod[0] = t[0] * u[0]; - prod[1] = t[1] * u[1]; - prod[2] = t[2] * u[2]; - prod[3] = t[3] * u[3]; - store_vector4( inst, machine, prod ); - } - break; - case OPCODE_ADD: - { - GLfloat t[4], u[4], sum[4]; - fetch_vector4( ctx, &inst->SrcReg[0], machine, program, t ); - fetch_vector4( ctx, &inst->SrcReg[1], machine, program, u ); - sum[0] = t[0] + u[0]; - sum[1] = t[1] + u[1]; - sum[2] = t[2] + u[2]; - sum[3] = t[3] + u[3]; - store_vector4( inst, machine, sum ); - } - break; - case OPCODE_DP3: - { - GLfloat t[4], u[4], dot[4]; - fetch_vector4( ctx, &inst->SrcReg[0], machine, program, t ); - fetch_vector4( ctx, &inst->SrcReg[1], machine, program, u ); - dot[0] = t[0] * u[0] + t[1] * u[1] + t[2] * u[2]; - dot[1] = dot[2] = dot[3] = dot[0]; - store_vector4( inst, machine, dot ); - } - break; - case OPCODE_DP4: - { - GLfloat t[4], u[4], dot[4]; - fetch_vector4( ctx, &inst->SrcReg[0], machine, program, t ); - fetch_vector4( ctx, &inst->SrcReg[1], machine, program, u ); - dot[0] = t[0] * u[0] + t[1] * u[1] + t[2] * u[2] + t[3] * u[3]; - dot[1] = dot[2] = dot[3] = dot[0]; - store_vector4( inst, machine, dot ); - } - break; - case OPCODE_DST: - { - GLfloat t[4], u[4], dst[4]; - fetch_vector4( ctx, &inst->SrcReg[0], machine, program, t ); - fetch_vector4( ctx, &inst->SrcReg[1], machine, program, u ); - dst[0] = 1.0F; - dst[1] = t[1] * u[1]; - dst[2] = t[2]; - dst[3] = u[3]; - store_vector4( inst, machine, dst ); - } - break; - case OPCODE_MIN: - { - GLfloat t[4], u[4], min[4]; - fetch_vector4( ctx, &inst->SrcReg[0], machine, program, t ); - fetch_vector4( ctx, &inst->SrcReg[1], machine, program, u ); - min[0] = (t[0] < u[0]) ? t[0] : u[0]; - min[1] = (t[1] < u[1]) ? t[1] : u[1]; - min[2] = (t[2] < u[2]) ? t[2] : u[2]; - min[3] = (t[3] < u[3]) ? t[3] : u[3]; - store_vector4( inst, machine, min ); - } - break; - case OPCODE_MAX: - { - GLfloat t[4], u[4], max[4]; - fetch_vector4( ctx, &inst->SrcReg[0], machine, program, t ); - fetch_vector4( ctx, &inst->SrcReg[1], machine, program, u ); - max[0] = (t[0] > u[0]) ? t[0] : u[0]; - max[1] = (t[1] > u[1]) ? t[1] : u[1]; - max[2] = (t[2] > u[2]) ? t[2] : u[2]; - max[3] = (t[3] > u[3]) ? t[3] : u[3]; - store_vector4( inst, machine, max ); - } - break; - case OPCODE_SLT: - { - GLfloat t[4], u[4], slt[4]; - fetch_vector4( ctx, &inst->SrcReg[0], machine, program, t ); - fetch_vector4( ctx, &inst->SrcReg[1], machine, program, u ); - slt[0] = (t[0] < u[0]) ? 1.0F : 0.0F; - slt[1] = (t[1] < u[1]) ? 1.0F : 0.0F; - slt[2] = (t[2] < u[2]) ? 1.0F : 0.0F; - slt[3] = (t[3] < u[3]) ? 1.0F : 0.0F; - store_vector4( inst, machine, slt ); - } - break; - case OPCODE_SGE: - { - GLfloat t[4], u[4], sge[4]; - fetch_vector4( ctx, &inst->SrcReg[0], machine, program, t ); - fetch_vector4( ctx, &inst->SrcReg[1], machine, program, u ); - sge[0] = (t[0] >= u[0]) ? 1.0F : 0.0F; - sge[1] = (t[1] >= u[1]) ? 1.0F : 0.0F; - sge[2] = (t[2] >= u[2]) ? 1.0F : 0.0F; - sge[3] = (t[3] >= u[3]) ? 1.0F : 0.0F; - store_vector4( inst, machine, sge ); - } - break; - case OPCODE_MAD: - { - GLfloat t[4], u[4], v[4], sum[4]; - fetch_vector4( ctx, &inst->SrcReg[0], machine, program, t ); - fetch_vector4( ctx, &inst->SrcReg[1], machine, program, u ); - fetch_vector4( ctx, &inst->SrcReg[2], machine, program, v ); - sum[0] = t[0] * u[0] + v[0]; - sum[1] = t[1] * u[1] + v[1]; - sum[2] = t[2] * u[2] + v[2]; - sum[3] = t[3] * u[3] + v[3]; - store_vector4( inst, machine, sum ); - } - break; - case OPCODE_ARL: - { - GLfloat t[4]; - fetch_vector4( ctx, &inst->SrcReg[0], machine, program, t ); - machine->AddressReg[0] = (GLint) FLOORF(t[0]); - } - break; - case OPCODE_DPH: - { - GLfloat t[4], u[4], dot[4]; - fetch_vector4( ctx, &inst->SrcReg[0], machine, program, t ); - fetch_vector4( ctx, &inst->SrcReg[1], machine, program, u ); - dot[0] = t[0] * u[0] + t[1] * u[1] + t[2] * u[2] + u[3]; - dot[1] = dot[2] = dot[3] = dot[0]; - store_vector4( inst, machine, dot ); - } - break; - case OPCODE_RCC: - { - GLfloat t[4], u; - fetch_vector1( ctx, &inst->SrcReg[0], machine, program, t ); - if (t[0] == 1.0F) - u = 1.0F; - else - u = 1.0F / t[0]; - if (u > 0.0F) { - if (u > 1.884467e+019F) { - u = 1.884467e+019F; /* IEEE 32-bit binary value 0x5F800000 */ - } - else if (u < 5.42101e-020F) { - u = 5.42101e-020F; /* IEEE 32-bit binary value 0x1F800000 */ - } - } - else { - if (u < -1.884467e+019F) { - u = -1.884467e+019F; /* IEEE 32-bit binary value 0xDF800000 */ - } - else if (u > -5.42101e-020F) { - u = -5.42101e-020F; /* IEEE 32-bit binary value 0x9F800000 */ - } - } - t[0] = t[1] = t[2] = t[3] = u; - store_vector4( inst, machine, t ); - } - break; - case OPCODE_SUB: /* GL_NV_vertex_program1_1 */ - { - GLfloat t[4], u[4], sum[4]; - fetch_vector4( ctx, &inst->SrcReg[0], machine, program, t ); - fetch_vector4( ctx, &inst->SrcReg[1], machine, program, u ); - sum[0] = t[0] - u[0]; - sum[1] = t[1] - u[1]; - sum[2] = t[2] - u[2]; - sum[3] = t[3] - u[3]; - store_vector4( inst, machine, sum ); - } - break; - case OPCODE_ABS: /* GL_NV_vertex_program1_1 */ - { - GLfloat t[4]; - fetch_vector4( ctx, &inst->SrcReg[0], machine, program, t ); - if (t[0] < 0.0) t[0] = -t[0]; - if (t[1] < 0.0) t[1] = -t[1]; - if (t[2] < 0.0) t[2] = -t[2]; - if (t[3] < 0.0) t[3] = -t[3]; - store_vector4( inst, machine, t ); - } - break; - case OPCODE_FLR: /* GL_ARB_vertex_program */ - { - GLfloat t[4]; - fetch_vector4( ctx, &inst->SrcReg[0], machine, program, t ); - t[0] = FLOORF(t[0]); - t[1] = FLOORF(t[1]); - t[2] = FLOORF(t[2]); - t[3] = FLOORF(t[3]); - store_vector4( inst, machine, t ); - } - break; - case OPCODE_FRC: /* GL_ARB_vertex_program */ - { - GLfloat t[4]; - fetch_vector4( ctx, &inst->SrcReg[0], machine, program, t ); - t[0] = t[0] - FLOORF(t[0]); - t[1] = t[1] - FLOORF(t[1]); - t[2] = t[2] - FLOORF(t[2]); - t[3] = t[3] - FLOORF(t[3]); - store_vector4( inst, machine, t ); - } - break; - case OPCODE_EX2: /* GL_ARB_vertex_program */ - { - GLfloat t[4]; - fetch_vector1( ctx, &inst->SrcReg[0], machine, program, t ); - t[0] = t[1] = t[2] = t[3] = (GLfloat)_mesa_pow(2.0, t[0]); - store_vector4( inst, machine, t ); - } - break; - case OPCODE_LG2: /* GL_ARB_vertex_program */ - { - GLfloat t[4]; - fetch_vector1( ctx, &inst->SrcReg[0], machine, program, t ); - t[0] = t[1] = t[2] = t[3] = LOG2(t[0]); - store_vector4( inst, machine, t ); - } - break; - case OPCODE_POW: /* GL_ARB_vertex_program */ - { - GLfloat t[4], u[4]; - fetch_vector1( ctx, &inst->SrcReg[0], machine, program, t ); - fetch_vector1( ctx, &inst->SrcReg[1], machine, program, u ); - t[0] = t[1] = t[2] = t[3] = (GLfloat)_mesa_pow(t[0], u[0]); - store_vector4( inst, machine, t ); - } - break; - case OPCODE_XPD: /* GL_ARB_vertex_program */ - { - GLfloat t[4], u[4], cross[4]; - fetch_vector4( ctx, &inst->SrcReg[0], machine, program, t ); - fetch_vector4( ctx, &inst->SrcReg[1], machine, program, u ); - cross[0] = t[1] * u[2] - t[2] * u[1]; - cross[1] = t[2] * u[0] - t[0] * u[2]; - cross[2] = t[0] * u[1] - t[1] * u[0]; - store_vector4( inst, machine, cross ); - } - break; - case OPCODE_SWZ: /* GL_ARB_vertex_program */ - { - const struct prog_src_register *source = &inst->SrcReg[0]; - const GLfloat *src = get_register_pointer(ctx, source, - machine, program); - GLfloat result[4]; - GLuint i; - - /* do extended swizzling here */ - for (i = 0; i < 4; i++) { - const GLuint swz = GET_SWZ(source->Swizzle, i); - if (swz == SWIZZLE_ZERO) - result[i] = 0.0; - else if (swz == SWIZZLE_ONE) - result[i] = 1.0; - else { - ASSERT(swz >= 0); - ASSERT(swz <= 3); - result[i] = src[swz]; - } - if (source->NegateBase & (1 << i)) - result[i] = -result[i]; - } - store_vector4( inst, machine, result ); - } - break; - case OPCODE_PRINT: - if (inst->SrcReg[0].File) { - GLfloat t[4]; - fetch_vector4( ctx, &inst->SrcReg[0], machine, program, t ); - _mesa_printf("%s%g, %g, %g, %g\n", - (char *) inst->Data, t[0], t[1], t[2], t[3]); - } - else { - _mesa_printf("%s\n", (char *) inst->Data); - } - break; - case OPCODE_END: - ctx->_CurrentProgram = 0; - return; - default: - /* bad instruction opcode */ - _mesa_problem(ctx, "Bad VP Opcode in _mesa_exec_vertex_program"); - ctx->_CurrentProgram = 0; - return; - } /* switch */ - } /* for */ - - ctx->_CurrentProgram = 0; -} - - -/** - * Execute a vertex state program. - * \sa _mesa_ExecuteProgramNV - */ -void -_mesa_exec_vertex_state_program(GLcontext *ctx, - struct gl_vertex_program *vprog, - const GLfloat *params) -{ - struct vp_machine machine; - _mesa_init_vp_per_vertex_registers(ctx, &machine); - _mesa_init_vp_per_primitive_registers(ctx); - COPY_4V(machine.Inputs[VERT_ATTRIB_POS], params); - _mesa_exec_vertex_program(ctx, &machine, vprog); -} diff --git a/src/mesa/shader/nvvertparse.c b/src/mesa/shader/nvvertparse.c index 6d395c6011..ac96d4a60e 100644 --- a/src/mesa/shader/nvvertparse.c +++ b/src/mesa/shader/nvvertparse.c @@ -39,13 +39,11 @@ #include "glheader.h" #include "context.h" -#include "hash.h" #include "imports.h" #include "macros.h" -#include "mtypes.h" #include "nvprogram.h" #include "nvvertparse.h" -#include "program_instruction.h" +#include "prog_instruction.h" #include "program.h" @@ -1380,8 +1378,7 @@ _mesa_parse_nv_vertex_program(GLcontext *ctx, GLenum dstTarget, _mesa_free(programString); return; /* out of memory */ } - _mesa_memcpy(newInst, instBuffer, - parseState.numInst * sizeof(struct prog_instruction)); + _mesa_copy_instructions(newInst, instBuffer, parseState.numInst); /* install the program */ program->Base.Target = target; diff --git a/src/mesa/shader/prog_debug.c b/src/mesa/shader/prog_debug.c new file mode 100644 index 0000000000..57929fcbca --- /dev/null +++ b/src/mesa/shader/prog_debug.c @@ -0,0 +1,259 @@ +/* + * 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; + } + ctx->Driver.GetProgramRegister(ctx, PROGRAM_TEMPORARY, i, v); + } + 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) { + ctx->Driver.GetProgramRegister(ctx, PROGRAM_INPUT, i, v); + 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.GetProgramRegister(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.GetProgramRegister(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.GetProgramRegister(ctx, PROGRAM_OUTPUT, + FRAG_RESULT_COLR, v); + } + else if (_mesa_strcmp(reg, "o[COLH]") == 0) { + /* Fragment output color */ + ctx->Driver.GetProgramRegister(ctx, PROGRAM_OUTPUT, + FRAG_RESULT_COLH, v); + } + else if (_mesa_strcmp(reg, "o[DEPR]") == 0) { + /* Fragment output depth */ + ctx->Driver.GetProgramRegister(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/swrast/s_arbshader.h b/src/mesa/shader/prog_debug.h index 5df80c870b..fc400e19de 100644 --- a/src/mesa/swrast/s_arbshader.h +++ b/src/mesa/shader/prog_debug.h @@ -1,8 +1,8 @@ /* * Mesa 3-D graphics library - * Version: 6.5 + * Version: 6.5.3 * - * Copyright (C) 2006 David Airlie 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"), @@ -17,22 +17,28 @@ * 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 - * DAVID AIRLIE BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN + * 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 S_ARBSHADER_H -#define S_ARBSHADER_H +#ifndef PROG_DEBUG_H +#define PROG_DEBUG_H 1 -#include "s_context.h" -#if FEATURE_ARB_fragment_shader +/* + * GL_MESA_program_debug + */ + +extern void +_mesa_ProgramCallbackMESA(GLenum target, GLprogramcallbackMESA callback, + GLvoid *data); -extern void _swrast_exec_arbshader (GLcontext *ctx, SWspan *span); +extern void +_mesa_GetProgramRegisterfvMESA(GLenum target, GLsizei len, + const GLubyte *registerName, GLfloat *v); -#endif /* FEATURE_ARB_fragment_shader */ -#endif +#endif /* PROG_DEBUG_H */ diff --git a/src/mesa/shader/prog_execute.c b/src/mesa/shader/prog_execute.c new file mode 100644 index 0000000000..f881d477ca --- /dev/null +++ b/src/mesa/shader/prog_execute.c @@ -0,0 +1,1748 @@ +/* + * 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. + */ + +/** + * \file prog_execute.c + * Software interpreter for vertex/fragment programs. + * \author Brian Paul + */ + +/* + * NOTE: we do everything in single-precision floating point; we don't + * currently observe the single/half/fixed-precision qualifiers. + * + */ + + +#include "glheader.h" +#include "colormac.h" +#include "context.h" +#include "program.h" +#include "prog_execute.h" +#include "prog_instruction.h" +#include "prog_parameter.h" +#include "prog_print.h" +#include "slang_library_noise.h" + + +/* See comments below for info about this */ +#define LAMBDA_ZERO 1 + +/* debug predicate */ +#define DEBUG_PROG 0 + + +/** + * Set x to positive or negative infinity. + */ +#if defined(USE_IEEE) || defined(_WIN32) +#define SET_POS_INFINITY(x) ( *((GLuint *) (void *)&x) = 0x7F800000 ) +#define SET_NEG_INFINITY(x) ( *((GLuint *) (void *)&x) = 0xFF800000 ) +#elif defined(VMS) +#define SET_POS_INFINITY(x) x = __MAXFLOAT +#define SET_NEG_INFINITY(x) x = -__MAXFLOAT +#else +#define SET_POS_INFINITY(x) x = (GLfloat) HUGE_VAL +#define SET_NEG_INFINITY(x) x = (GLfloat) -HUGE_VAL +#endif + +#define SET_FLOAT_BITS(x, bits) ((fi_type *) (void *) &(x))->i = bits + + +static const GLfloat ZeroVec[4] = { 0.0F, 0.0F, 0.0F, 0.0F }; + + + +/** + * Return a pointer to the 4-element float vector specified by the given + * source register. + */ +static INLINE const GLfloat * +get_register_pointer(const struct prog_src_register *source, + const struct gl_program_machine *machine) +{ + if (source->RelAddr) { + const GLint reg = source->Index + machine->AddressReg[0][0]; + if (source->File == PROGRAM_ENV_PARAM) + if (reg < 0 || reg >= MAX_PROGRAM_ENV_PARAMS) + return ZeroVec; + else + return machine->EnvParams[reg]; + else { + const struct gl_program_parameter_list *params; + ASSERT(source->File == PROGRAM_LOCAL_PARAM || + source->File == PROGRAM_STATE_VAR); + params = machine->CurProgram->Parameters; + if (reg < 0 || reg >= params->NumParameters) + return ZeroVec; + else + return params->ParameterValues[reg]; + } + } + + switch (source->File) { + case PROGRAM_TEMPORARY: + ASSERT(source->Index < MAX_PROGRAM_TEMPS); + return machine->Temporaries[source->Index]; + + case PROGRAM_INPUT: + if (machine->CurProgram->Target == GL_VERTEX_PROGRAM_ARB) { + ASSERT(source->Index < VERT_ATTRIB_MAX); + return machine->VertAttribs[source->Index]; + } + else { + ASSERT(source->Index < FRAG_ATTRIB_MAX); + return machine->Attribs[source->Index][machine->CurElement]; + } + + case PROGRAM_OUTPUT: + ASSERT(source->Index < MAX_PROGRAM_OUTPUTS); + return machine->Outputs[source->Index]; + + case PROGRAM_LOCAL_PARAM: + ASSERT(source->Index < MAX_PROGRAM_LOCAL_PARAMS); + return machine->CurProgram->LocalParams[source->Index]; + + case PROGRAM_ENV_PARAM: + ASSERT(source->Index < MAX_PROGRAM_ENV_PARAMS); + return machine->EnvParams[source->Index]; + + case PROGRAM_STATE_VAR: + /* Fallthrough */ + case PROGRAM_CONSTANT: + /* Fallthrough */ + case PROGRAM_UNIFORM: + /* Fallthrough */ + case PROGRAM_NAMED_PARAM: + ASSERT(source->Index < + (GLint) machine->CurProgram->Parameters->NumParameters); + return machine->CurProgram->Parameters->ParameterValues[source->Index]; + + default: + _mesa_problem(NULL, + "Invalid input register file %d in get_register_pointer()", + source->File); + return NULL; + } +} + + +#if FEATURE_MESA_program_debug +static struct gl_program_machine *CurrentMachine = NULL; + +/** + * For GL_MESA_program_debug. + * Return current value (4*GLfloat) of a program register. + * Called via ctx->Driver.GetProgramRegister(). + */ +void +_mesa_get_program_register(GLcontext *ctx, enum register_file file, + GLuint index, GLfloat val[4]) +{ + if (CurrentMachine) { + struct prog_src_register src; + const GLfloat *reg; + src.File = file; + src.Index = index; + reg = get_register_pointer(&src, CurrentMachine); + COPY_4V(val, reg); + } +} +#endif /* FEATURE_MESA_program_debug */ + + +/** + * Fetch a 4-element float vector from the given source register. + * Apply swizzling and negating as needed. + */ +static void +fetch_vector4(const struct prog_src_register *source, + const struct gl_program_machine *machine, GLfloat result[4]) +{ + const GLfloat *src = get_register_pointer(source, machine); + ASSERT(src); + + if (source->Swizzle == SWIZZLE_NOOP) { + /* no swizzling */ + COPY_4V(result, src); + } + else { + ASSERT(GET_SWZ(source->Swizzle, 0) <= 3); + ASSERT(GET_SWZ(source->Swizzle, 1) <= 3); + ASSERT(GET_SWZ(source->Swizzle, 2) <= 3); + ASSERT(GET_SWZ(source->Swizzle, 3) <= 3); + result[0] = src[GET_SWZ(source->Swizzle, 0)]; + result[1] = src[GET_SWZ(source->Swizzle, 1)]; + result[2] = src[GET_SWZ(source->Swizzle, 2)]; + result[3] = src[GET_SWZ(source->Swizzle, 3)]; + } + + if (source->NegateBase) { + result[0] = -result[0]; + result[1] = -result[1]; + result[2] = -result[2]; + result[3] = -result[3]; + } + if (source->Abs) { + result[0] = FABSF(result[0]); + result[1] = FABSF(result[1]); + result[2] = FABSF(result[2]); + result[3] = FABSF(result[3]); + } + if (source->NegateAbs) { + result[0] = -result[0]; + result[1] = -result[1]; + result[2] = -result[2]; + result[3] = -result[3]; + } +} + +#if 0 +/** + * Fetch the derivative with respect to X for the given register. + * \return GL_TRUE if it was easily computed or GL_FALSE if we + * need to execute another instance of the program (ugh)! + */ +static GLboolean +fetch_vector4_deriv(GLcontext * ctx, + const struct prog_src_register *source, + const SWspan * span, + char xOrY, GLint column, GLfloat result[4]) +{ + GLfloat src[4]; + + ASSERT(xOrY == 'X' || xOrY == 'Y'); + + switch (source->Index) { + case FRAG_ATTRIB_WPOS: + if (xOrY == 'X') { + src[0] = 1.0; + src[1] = 0.0; + src[2] = span->attrStepX[FRAG_ATTRIB_WPOS][2] + / ctx->DrawBuffer->_DepthMaxF; + src[3] = span->attrStepX[FRAG_ATTRIB_WPOS][3]; + } + else { + src[0] = 0.0; + src[1] = 1.0; + src[2] = span->attrStepY[FRAG_ATTRIB_WPOS][2] + / ctx->DrawBuffer->_DepthMaxF; + src[3] = span->attrStepY[FRAG_ATTRIB_WPOS][3]; + } + break; + case FRAG_ATTRIB_COL0: + case FRAG_ATTRIB_COL1: + if (xOrY == 'X') { + src[0] = span->attrStepX[source->Index][0] * (1.0F / CHAN_MAXF); + src[1] = span->attrStepX[source->Index][1] * (1.0F / CHAN_MAXF); + src[2] = span->attrStepX[source->Index][2] * (1.0F / CHAN_MAXF); + src[3] = span->attrStepX[source->Index][3] * (1.0F / CHAN_MAXF); + } + else { + src[0] = span->attrStepY[source->Index][0] * (1.0F / CHAN_MAXF); + src[1] = span->attrStepY[source->Index][1] * (1.0F / CHAN_MAXF); + src[2] = span->attrStepY[source->Index][2] * (1.0F / CHAN_MAXF); + src[3] = span->attrStepY[source->Index][3] * (1.0F / CHAN_MAXF); + } + break; + case FRAG_ATTRIB_FOGC: + if (xOrY == 'X') { + src[0] = span->attrStepX[FRAG_ATTRIB_FOGC][0] * (1.0F / CHAN_MAXF); + src[1] = 0.0; + src[2] = 0.0; + src[3] = 0.0; + } + else { + src[0] = span->attrStepY[FRAG_ATTRIB_FOGC][0] * (1.0F / CHAN_MAXF); + src[1] = 0.0; + src[2] = 0.0; + src[3] = 0.0; + } + break; + default: + assert(source->Index < FRAG_ATTRIB_MAX); + /* texcoord or varying */ + if (xOrY == 'X') { + /* this is a little tricky - I think I've got it right */ + const GLfloat invQ = 1.0f / (span->attrStart[source->Index][3] + + + span->attrStepX[source->Index][3] * + column); + src[0] = span->attrStepX[source->Index][0] * invQ; + src[1] = span->attrStepX[source->Index][1] * invQ; + src[2] = span->attrStepX[source->Index][2] * invQ; + src[3] = span->attrStepX[source->Index][3] * invQ; + } + else { + /* Tricky, as above, but in Y direction */ + const GLfloat invQ = 1.0f / (span->attrStart[source->Index][3] + + span->attrStepY[source->Index][3]); + src[0] = span->attrStepY[source->Index][0] * invQ; + src[1] = span->attrStepY[source->Index][1] * invQ; + src[2] = span->attrStepY[source->Index][2] * invQ; + src[3] = span->attrStepY[source->Index][3] * invQ; + } + break; + } + + result[0] = src[GET_SWZ(source->Swizzle, 0)]; + result[1] = src[GET_SWZ(source->Swizzle, 1)]; + result[2] = src[GET_SWZ(source->Swizzle, 2)]; + result[3] = src[GET_SWZ(source->Swizzle, 3)]; + + if (source->NegateBase) { + result[0] = -result[0]; + result[1] = -result[1]; + result[2] = -result[2]; + result[3] = -result[3]; + } + if (source->Abs) { + result[0] = FABSF(result[0]); + result[1] = FABSF(result[1]); + result[2] = FABSF(result[2]); + result[3] = FABSF(result[3]); + } + if (source->NegateAbs) { + result[0] = -result[0]; + result[1] = -result[1]; + result[2] = -result[2]; + result[3] = -result[3]; + } + return GL_TRUE; +} +#endif + + +/** + * As above, but only return result[0] element. + */ +static void +fetch_vector1(const struct prog_src_register *source, + const struct gl_program_machine *machine, GLfloat result[4]) +{ + const GLfloat *src = get_register_pointer(source, machine); + ASSERT(src); + + result[0] = src[GET_SWZ(source->Swizzle, 0)]; + + if (source->NegateBase) { + result[0] = -result[0]; + } + if (source->Abs) { + result[0] = FABSF(result[0]); + } + if (source->NegateAbs) { + result[0] = -result[0]; + } +} + + +/** + * Test value against zero and return GT, LT, EQ or UN if NaN. + */ +static INLINE GLuint +generate_cc(float value) +{ + if (value != value) + return COND_UN; /* NaN */ + if (value > 0.0F) + return COND_GT; + if (value < 0.0F) + return COND_LT; + return COND_EQ; +} + + +/** + * Test if the ccMaskRule is satisfied by the given condition code. + * Used to mask destination writes according to the current condition code. + */ +static INLINE GLboolean +test_cc(GLuint condCode, GLuint ccMaskRule) +{ + switch (ccMaskRule) { + case COND_EQ: return (condCode == COND_EQ); + case COND_NE: return (condCode != COND_EQ); + case COND_LT: return (condCode == COND_LT); + case COND_GE: return (condCode == COND_GT || condCode == COND_EQ); + case COND_LE: return (condCode == COND_LT || condCode == COND_EQ); + case COND_GT: return (condCode == COND_GT); + case COND_TR: return GL_TRUE; + case COND_FL: return GL_FALSE; + default: return GL_TRUE; + } +} + + +/** + * 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 gl_program_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. + */ +static void +store_vector4(const struct prog_instruction *inst, + struct gl_program_machine *machine, const GLfloat value[4]) +{ + const struct prog_dst_register *dest = &(inst->DstReg); + const GLboolean clamp = inst->SaturateMode == SATURATE_ZERO_ONE; + GLfloat *dstReg; + GLfloat dummyReg[4]; + GLfloat clampedValue[4]; + GLuint writeMask = dest->WriteMask; + + switch (dest->File) { + case PROGRAM_OUTPUT: + ASSERT(dest->Index < MAX_PROGRAM_OUTPUTS); + dstReg = machine->Outputs[dest->Index]; + break; + case PROGRAM_TEMPORARY: + ASSERT(dest->Index < MAX_PROGRAM_TEMPS); + dstReg = machine->Temporaries[dest->Index]; + break; + case PROGRAM_WRITE_ONLY: + dstReg = dummyReg; + return; + default: + _mesa_problem(NULL, "bad register file in store_vector4(fp)"); + return; + } + +#if 0 + if (value[0] > 1.0e10 || + IS_INF_OR_NAN(value[0]) || + IS_INF_OR_NAN(value[1]) || + IS_INF_OR_NAN(value[2]) || IS_INF_OR_NAN(value[3])) + printf("store %g %g %g %g\n", value[0], value[1], value[2], value[3]); +#endif + + if (clamp) { + clampedValue[0] = CLAMP(value[0], 0.0F, 1.0F); + clampedValue[1] = CLAMP(value[1], 0.0F, 1.0F); + clampedValue[2] = CLAMP(value[2], 0.0F, 1.0F); + clampedValue[3] = CLAMP(value[3], 0.0F, 1.0F); + value = clampedValue; + } + + if (dest->CondMask != COND_TR) { + /* condition codes may turn off some writes */ + if (writeMask & WRITEMASK_X) { + if (!test_cc(machine->CondCodes[GET_SWZ(dest->CondSwizzle, 0)], + dest->CondMask)) + writeMask &= ~WRITEMASK_X; + } + if (writeMask & WRITEMASK_Y) { + if (!test_cc(machine->CondCodes[GET_SWZ(dest->CondSwizzle, 1)], + dest->CondMask)) + writeMask &= ~WRITEMASK_Y; + } + if (writeMask & WRITEMASK_Z) { + if (!test_cc(machine->CondCodes[GET_SWZ(dest->CondSwizzle, 2)], + dest->CondMask)) + writeMask &= ~WRITEMASK_Z; + } + if (writeMask & WRITEMASK_W) { + if (!test_cc(machine->CondCodes[GET_SWZ(dest->CondSwizzle, 3)], + dest->CondMask)) + writeMask &= ~WRITEMASK_W; + } + } + + if (writeMask & WRITEMASK_X) + dstReg[0] = value[0]; + if (writeMask & WRITEMASK_Y) + dstReg[1] = value[1]; + if (writeMask & WRITEMASK_Z) + dstReg[2] = value[2]; + if (writeMask & WRITEMASK_W) + dstReg[3] = value[3]; + + if (inst->CondUpdate) { + if (writeMask & WRITEMASK_X) + machine->CondCodes[0] = generate_cc(value[0]); + if (writeMask & WRITEMASK_Y) + machine->CondCodes[1] = generate_cc(value[1]); + if (writeMask & WRITEMASK_Z) + machine->CondCodes[2] = generate_cc(value[2]); + if (writeMask & WRITEMASK_W) + machine->CondCodes[3] = generate_cc(value[3]); + } +} + + +#if 0 +/** + * Initialize a new machine state instance from an existing one, adding + * the partial derivatives onto the input registers. + * Used to implement DDX and DDY instructions in non-trivial cases. + */ +static void +init_machine_deriv(GLcontext * ctx, + const struct gl_program_machine *machine, + const struct gl_fragment_program *program, + const SWspan * span, char xOrY, + struct gl_program_machine *dMachine) +{ + GLuint attr; + + ASSERT(xOrY == 'X' || xOrY == 'Y'); + + /* copy existing machine */ + _mesa_memcpy(dMachine, machine, sizeof(struct gl_program_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_PROGRAM_TEMPS * 4 * sizeof(GLfloat)); + } + + /* Add derivatives */ + if (program->Base.InputsRead & FRAG_BIT_WPOS) { + GLfloat *wpos = machine->Attribs[FRAG_ATTRIB_WPOS][machine->CurElement]; + if (xOrY == 'X') { + wpos[0] += 1.0F; + wpos[1] += 0.0F; + wpos[2] += span->attrStepX[FRAG_ATTRIB_WPOS][2]; + wpos[3] += span->attrStepX[FRAG_ATTRIB_WPOS][3]; + } + else { + wpos[0] += 0.0F; + wpos[1] += 1.0F; + wpos[2] += span->attrStepY[FRAG_ATTRIB_WPOS][2]; + wpos[3] += span->attrStepY[FRAG_ATTRIB_WPOS][3]; + } + } + + /* primary, secondary colors */ + for (attr = FRAG_ATTRIB_COL0; attr <= FRAG_ATTRIB_COL1; attr++) { + if (program->Base.InputsRead & (1 << attr)) { + GLfloat *col = machine->Attribs[attr][machine->CurElement]; + if (xOrY == 'X') { + col[0] += span->attrStepX[attr][0] * (1.0F / CHAN_MAXF); + col[1] += span->attrStepX[attr][1] * (1.0F / CHAN_MAXF); + col[2] += span->attrStepX[attr][2] * (1.0F / CHAN_MAXF); + col[3] += span->attrStepX[attr][3] * (1.0F / CHAN_MAXF); + } + else { + col[0] += span->attrStepY[attr][0] * (1.0F / CHAN_MAXF); + col[1] += span->attrStepY[attr][1] * (1.0F / CHAN_MAXF); + col[2] += span->attrStepY[attr][2] * (1.0F / CHAN_MAXF); + col[3] += span->attrStepY[attr][3] * (1.0F / CHAN_MAXF); + } + } + } + if (program->Base.InputsRead & FRAG_BIT_FOGC) { + GLfloat *fogc = machine->Attribs[FRAG_ATTRIB_FOGC][machine->CurElement]; + if (xOrY == 'X') { + fogc[0] += span->attrStepX[FRAG_ATTRIB_FOGC][0]; + } + else { + fogc[0] += span->attrStepY[FRAG_ATTRIB_FOGC][0]; + } + } + /* texcoord and varying vars */ + for (attr = FRAG_ATTRIB_TEX0; attr < FRAG_ATTRIB_MAX; attr++) { + if (program->Base.InputsRead & (1 << attr)) { + GLfloat *val = machine->Attribs[attr][machine->CurElement]; + /* XXX perspective-correct interpolation */ + if (xOrY == 'X') { + val[0] += span->attrStepX[attr][0]; + val[1] += span->attrStepX[attr][1]; + val[2] += span->attrStepX[attr][2]; + val[3] += span->attrStepX[attr][3]; + } + else { + val[0] += span->attrStepY[attr][0]; + val[1] += span->attrStepY[attr][1]; + val[2] += span->attrStepY[attr][2]; + val[3] += span->attrStepY[attr][3]; + } + } + } + + /* init condition codes */ + dMachine->CondCodes[0] = COND_EQ; + dMachine->CondCodes[1] = COND_EQ; + dMachine->CondCodes[2] = COND_EQ; + dMachine->CondCodes[3] = COND_EQ; +} +#endif + + +/** + * Execute the given vertex/fragment program. + * + * \param ctx rendering context + * \param program the program to execute + * \param machine machine state (must be initialized) + * \return GL_TRUE if program completed or GL_FALSE if program executed KIL. + */ +GLboolean +_mesa_execute_program(GLcontext * ctx, + const struct gl_program *program, + struct gl_program_machine *machine) +{ + const GLuint numInst = program->NumInstructions; + const GLuint maxExec = 10000; + GLint pc, numExec = 0; + + machine->CurProgram = program; + + if (DEBUG_PROG) { + printf("execute program %u --------------------\n", program->Id); + } + +#if FEATURE_MESA_program_debug + CurrentMachine = machine; +#endif + + if (program->Target == GL_VERTEX_PROGRAM_ARB) { + machine->EnvParams = ctx->VertexProgram.Parameters; + } + else { + machine->EnvParams = ctx->FragmentProgram.Parameters; + } + + for (pc = 0; pc < numInst; pc++) { + const struct prog_instruction *inst = program->Instructions + pc; + +#if FEATURE_MESA_program_debug + if (ctx->FragmentProgram.CallbackEnabled && + ctx->FragmentProgram.Callback) { + ctx->FragmentProgram.CurrentPosition = inst->StringPos; + ctx->FragmentProgram.Callback(program->Target, + ctx->FragmentProgram.CallbackData); + } +#endif + + if (DEBUG_PROG) { + _mesa_print_instruction(inst); + } + + switch (inst->Opcode) { + case OPCODE_ABS: + { + GLfloat a[4], result[4]; + fetch_vector4(&inst->SrcReg[0], machine, a); + result[0] = FABSF(a[0]); + result[1] = FABSF(a[1]); + result[2] = FABSF(a[2]); + result[3] = FABSF(a[3]); + store_vector4(inst, machine, result); + } + break; + case OPCODE_ADD: + { + GLfloat a[4], b[4], result[4]; + fetch_vector4(&inst->SrcReg[0], machine, a); + fetch_vector4(&inst->SrcReg[1], machine, b); + result[0] = a[0] + b[0]; + result[1] = a[1] + b[1]; + result[2] = a[2] + b[2]; + result[3] = a[3] + b[3]; + store_vector4(inst, machine, result); + if (DEBUG_PROG) { + printf("ADD (%g %g %g %g) = (%g %g %g %g) + (%g %g %g %g)\n", + result[0], result[1], result[2], result[3], + a[0], a[1], a[2], a[3], b[0], b[1], b[2], b[3]); + } + } + break; + case OPCODE_ARL: + { + GLfloat t[4]; + fetch_vector4(&inst->SrcReg[0], machine, t); + machine->AddressReg[0][0] = (GLint) FLOORF(t[0]); + } + break; + case OPCODE_BGNLOOP: + /* no-op */ + break; + case OPCODE_ENDLOOP: + /* subtract 1 here since pc is incremented by for(pc) loop */ + pc = inst->BranchTarget - 1; /* go to matching BNGLOOP */ + break; + case OPCODE_BGNSUB: /* begin subroutine */ + break; + case OPCODE_ENDSUB: /* end subroutine */ + break; + 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_BRK0: /* Break if zero */ + /* fall-through */ + case OPCODE_CONT0: /* Continue if zero */ + { + GLfloat a[4]; + fetch_vector1(&inst->SrcReg[0], machine, a); + if (a[0] == 0.0) { + /* take branch */ + /* Subtract 1 here since we'll do pc++ at end of for-loop */ + pc = inst->BranchTarget - 1; + } + } + break; + case OPCODE_BRK1: /* Break if non-zero */ + /* fall-through */ + case OPCODE_CONT1: /* Continue if non-zero */ + { + GLfloat a[4]; + fetch_vector1(&inst->SrcReg[0], machine, a); + if (a[0] != 0.0) { + /* 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 (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: + { + GLfloat a[4], b[4], c[4], result[4]; + fetch_vector4(&inst->SrcReg[0], machine, a); + fetch_vector4(&inst->SrcReg[1], machine, b); + fetch_vector4(&inst->SrcReg[2], machine, c); + result[0] = a[0] < 0.0F ? b[0] : c[0]; + result[1] = a[1] < 0.0F ? b[1] : c[1]; + result[2] = a[2] < 0.0F ? b[2] : c[2]; + result[3] = a[3] < 0.0F ? b[3] : c[3]; + store_vector4(inst, machine, result); + } + break; + case OPCODE_COS: + { + GLfloat a[4], result[4]; + fetch_vector1(&inst->SrcReg[0], machine, a); + result[0] = result[1] = result[2] = result[3] + = (GLfloat) _mesa_cos(a[0]); + store_vector4(inst, machine, result); + } + break; + case OPCODE_DDX: /* Partial derivative with respect to X */ + { +#if 0 + GLfloat a[4], aNext[4], result[4]; + struct gl_program_machine dMachine; + if (!fetch_vector4_deriv(ctx, &inst->SrcReg[0], span, 'X', + column, result)) { + /* This is tricky. Make a copy of the current machine state, + * increment the input registers by the dx or dy partial + * derivatives, then re-execute the program up to the + * preceeding instruction, then fetch the source register. + * Finally, find the difference in the register values for + * the original and derivative runs. + */ + fetch_vector4(&inst->SrcReg[0], machine, program, a); + init_machine_deriv(ctx, machine, program, span, + 'X', &dMachine); + execute_program(ctx, program, pc, &dMachine, span, column); + fetch_vector4(&inst->SrcReg[0], &dMachine, program, + aNext); + result[0] = aNext[0] - a[0]; + result[1] = aNext[1] - a[1]; + result[2] = aNext[2] - a[2]; + result[3] = aNext[3] - a[3]; + } + store_vector4(inst, machine, result); +#else + store_vector4(inst, machine, ZeroVec); +#endif + } + break; + case OPCODE_DDY: /* Partial derivative with respect to Y */ + { +#if 0 + GLfloat a[4], aNext[4], result[4]; + struct gl_program_machine dMachine; + if (!fetch_vector4_deriv(ctx, &inst->SrcReg[0], span, 'Y', + column, result)) { + init_machine_deriv(ctx, machine, program, span, + 'Y', &dMachine); + fetch_vector4(&inst->SrcReg[0], machine, program, a); + execute_program(ctx, program, pc, &dMachine, span, column); + fetch_vector4(&inst->SrcReg[0], &dMachine, program, + aNext); + result[0] = aNext[0] - a[0]; + result[1] = aNext[1] - a[1]; + result[2] = aNext[2] - a[2]; + result[3] = aNext[3] - a[3]; + } + store_vector4(inst, machine, result); +#else + store_vector4(inst, machine, ZeroVec); +#endif + } + break; + case OPCODE_DP3: + { + GLfloat a[4], b[4], result[4]; + fetch_vector4(&inst->SrcReg[0], machine, a); + fetch_vector4(&inst->SrcReg[1], machine, b); + result[0] = result[1] = result[2] = result[3] = DOT3(a, b); + store_vector4(inst, machine, result); + if (DEBUG_PROG) { + printf("DP3 %g = (%g %g %g) . (%g %g %g)\n", + result[0], a[0], a[1], a[2], b[0], b[1], b[2]); + } + } + break; + case OPCODE_DP4: + { + GLfloat a[4], b[4], result[4]; + fetch_vector4(&inst->SrcReg[0], machine, a); + fetch_vector4(&inst->SrcReg[1], machine, b); + result[0] = result[1] = result[2] = result[3] = DOT4(a, b); + store_vector4(inst, machine, result); + if (DEBUG_PROG) { + printf("DP4 %g = (%g, %g %g %g) . (%g, %g %g %g)\n", + result[0], a[0], a[1], a[2], a[3], + b[0], b[1], b[2], b[3]); + } + } + break; + case OPCODE_DPH: + { + GLfloat a[4], b[4], result[4]; + fetch_vector4(&inst->SrcReg[0], machine, a); + fetch_vector4(&inst->SrcReg[1], machine, b); + result[0] = result[1] = result[2] = result[3] = + a[0] * b[0] + a[1] * b[1] + a[2] * b[2] + b[3]; + store_vector4(inst, machine, result); + } + break; + case OPCODE_DST: /* Distance vector */ + { + GLfloat a[4], b[4], result[4]; + fetch_vector4(&inst->SrcReg[0], machine, a); + fetch_vector4(&inst->SrcReg[1], machine, b); + result[0] = 1.0F; + result[1] = a[1] * b[1]; + result[2] = a[2]; + result[3] = b[3]; + store_vector4(inst, machine, result); + } + break; + case OPCODE_EXP: + { + GLfloat t[4], q[4], floor_t0; + fetch_vector1(&inst->SrcReg[0], machine, t); + floor_t0 = FLOORF(t[0]); + if (floor_t0 > FLT_MAX_EXP) { + SET_POS_INFINITY(q[0]); + SET_POS_INFINITY(q[2]); + } + else if (floor_t0 < FLT_MIN_EXP) { + q[0] = 0.0F; + q[2] = 0.0F; + } + else { + q[0] = LDEXPF(1.0, (int) floor_t0); + /* Note: GL_NV_vertex_program expects + * result.z = result.x * APPX(result.y) + * We do what the ARB extension says. + */ + q[2] = pow(2.0, t[0]); + } + q[1] = t[0] - floor_t0; + q[3] = 1.0F; + store_vector4( inst, machine, q ); + } + break; + case OPCODE_EX2: /* Exponential base 2 */ + { + GLfloat a[4], result[4]; + fetch_vector1(&inst->SrcReg[0], machine, a); + result[0] = result[1] = result[2] = result[3] = + (GLfloat) _mesa_pow(2.0, a[0]); + store_vector4(inst, machine, result); + } + break; + case OPCODE_FLR: + { + GLfloat a[4], result[4]; + fetch_vector4(&inst->SrcReg[0], machine, a); + result[0] = FLOORF(a[0]); + result[1] = FLOORF(a[1]); + result[2] = FLOORF(a[2]); + result[3] = FLOORF(a[3]); + store_vector4(inst, machine, result); + } + break; + case OPCODE_FRC: + { + GLfloat a[4], result[4]; + fetch_vector4(&inst->SrcReg[0], machine, a); + result[0] = a[0] - FLOORF(a[0]); + result[1] = a[1] - FLOORF(a[1]); + result[2] = a[2] - FLOORF(a[2]); + result[3] = a[3] - FLOORF(a[3]); + store_vector4(inst, machine, result); + } + break; + case OPCODE_IF: + { + GLboolean cond; + /* eval condition */ + if (inst->SrcReg[0].File != PROGRAM_UNDEFINED) { + GLfloat a[4]; + fetch_vector1(&inst->SrcReg[0], machine, a); + cond = (a[0] != 0.0); + } + else { + cond = eval_condition(machine, inst); + } + /* do if/else */ + if (cond) { + /* do if-clause (just continue execution) */ + } + 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; + case OPCODE_INT: /* float to int */ + { + GLfloat a[4], result[4]; + fetch_vector4(&inst->SrcReg[0], machine, a); + result[0] = (GLfloat) (GLint) a[0]; + result[1] = (GLfloat) (GLint) a[1]; + result[2] = (GLfloat) (GLint) a[2]; + result[3] = (GLfloat) (GLint) a[3]; + store_vector4(inst, machine, result); + } + break; + 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 */ + { + GLfloat a[4]; + fetch_vector4(&inst->SrcReg[0], machine, a); + if (a[0] < 0.0F || a[1] < 0.0F || a[2] < 0.0F || a[3] < 0.0F) { + return GL_FALSE; + } + } + break; + case OPCODE_LG2: /* log base 2 */ + { + GLfloat a[4], result[4]; + fetch_vector1(&inst->SrcReg[0], machine, a); + result[0] = result[1] = result[2] = result[3] = LOG2(a[0]); + store_vector4(inst, machine, result); + } + break; + case OPCODE_LIT: + { + const GLfloat epsilon = 1.0F / 256.0F; /* from NV VP spec */ + GLfloat a[4], result[4]; + fetch_vector4(&inst->SrcReg[0], machine, a); + a[0] = MAX2(a[0], 0.0F); + a[1] = MAX2(a[1], 0.0F); + /* XXX ARB version clamps a[3], NV version doesn't */ + a[3] = CLAMP(a[3], -(128.0F - epsilon), (128.0F - epsilon)); + result[0] = 1.0F; + result[1] = a[0]; + /* XXX we could probably just use pow() here */ + if (a[0] > 0.0F) { + if (a[1] == 0.0 && a[3] == 0.0) + result[2] = 1.0; + else + result[2] = EXPF(a[3] * LOGF(a[1])); + } + else { + result[2] = 0.0; + } + result[3] = 1.0F; + store_vector4(inst, machine, result); + if (DEBUG_PROG) { + printf("LIT (%g %g %g %g) : (%g %g %g %g)\n", + result[0], result[1], result[2], result[3], + a[0], a[1], a[2], a[3]); + } + } + break; + case OPCODE_LOG: + { + GLfloat t[4], q[4], abs_t0; + fetch_vector1(&inst->SrcReg[0], machine, t); + abs_t0 = FABSF(t[0]); + if (abs_t0 != 0.0F) { + /* Since we really can't handle infinite values on VMS + * like other OSes we'll use __MAXFLOAT to represent + * infinity. This may need some tweaking. + */ +#ifdef VMS + if (abs_t0 == __MAXFLOAT) +#else + if (IS_INF_OR_NAN(abs_t0)) +#endif + { + SET_POS_INFINITY(q[0]); + q[1] = 1.0F; + SET_POS_INFINITY(q[2]); + } + else { + int exponent; + GLfloat mantissa = FREXPF(t[0], &exponent); + q[0] = (GLfloat) (exponent - 1); + q[1] = (GLfloat) (2.0 * mantissa); /* map [.5, 1) -> [1, 2) */ + q[2] = (GLfloat) (q[0] + LOG2(q[1])); + } + } + else { + SET_NEG_INFINITY(q[0]); + q[1] = 1.0F; + SET_NEG_INFINITY(q[2]); + } + q[3] = 1.0; + store_vector4(inst, machine, q); + } + break; + case OPCODE_LRP: + { + GLfloat a[4], b[4], c[4], result[4]; + fetch_vector4(&inst->SrcReg[0], machine, a); + fetch_vector4(&inst->SrcReg[1], machine, b); + fetch_vector4(&inst->SrcReg[2], machine, c); + result[0] = a[0] * b[0] + (1.0F - a[0]) * c[0]; + result[1] = a[1] * b[1] + (1.0F - a[1]) * c[1]; + result[2] = a[2] * b[2] + (1.0F - a[2]) * c[2]; + result[3] = a[3] * b[3] + (1.0F - a[3]) * c[3]; + store_vector4(inst, machine, result); + if (DEBUG_PROG) { + printf("LRP (%g %g %g %g) = (%g %g %g %g), " + "(%g %g %g %g), (%g %g %g %g)\n", + result[0], result[1], result[2], result[3], + a[0], a[1], a[2], a[3], + b[0], b[1], b[2], b[3], c[0], c[1], c[2], c[3]); + } + } + break; + case OPCODE_MAD: + { + GLfloat a[4], b[4], c[4], result[4]; + fetch_vector4(&inst->SrcReg[0], machine, a); + fetch_vector4(&inst->SrcReg[1], machine, b); + fetch_vector4(&inst->SrcReg[2], machine, c); + result[0] = a[0] * b[0] + c[0]; + result[1] = a[1] * b[1] + c[1]; + result[2] = a[2] * b[2] + c[2]; + result[3] = a[3] * b[3] + c[3]; + store_vector4(inst, machine, result); + if (DEBUG_PROG) { + printf("MAD (%g %g %g %g) = (%g %g %g %g) * " + "(%g %g %g %g) + (%g %g %g %g)\n", + result[0], result[1], result[2], result[3], + a[0], a[1], a[2], a[3], + b[0], b[1], b[2], b[3], c[0], c[1], c[2], c[3]); + } + } + break; + case OPCODE_MAX: + { + GLfloat a[4], b[4], result[4]; + fetch_vector4(&inst->SrcReg[0], machine, a); + fetch_vector4(&inst->SrcReg[1], machine, b); + result[0] = MAX2(a[0], b[0]); + result[1] = MAX2(a[1], b[1]); + result[2] = MAX2(a[2], b[2]); + result[3] = MAX2(a[3], b[3]); + store_vector4(inst, machine, result); + if (DEBUG_PROG) { + printf("MAX (%g %g %g %g) = (%g %g %g %g), (%g %g %g %g)\n", + result[0], result[1], result[2], result[3], + a[0], a[1], a[2], a[3], b[0], b[1], b[2], b[3]); + } + } + break; + case OPCODE_MIN: + { + GLfloat a[4], b[4], result[4]; + fetch_vector4(&inst->SrcReg[0], machine, a); + fetch_vector4(&inst->SrcReg[1], machine, b); + result[0] = MIN2(a[0], b[0]); + result[1] = MIN2(a[1], b[1]); + result[2] = MIN2(a[2], b[2]); + result[3] = MIN2(a[3], b[3]); + store_vector4(inst, machine, result); + } + break; + case OPCODE_MOV: + { + GLfloat result[4]; + fetch_vector4(&inst->SrcReg[0], machine, result); + store_vector4(inst, machine, result); + if (DEBUG_PROG) { + printf("MOV (%g %g %g %g)\n", + result[0], result[1], result[2], result[3]); + } + } + break; + case OPCODE_MUL: + { + GLfloat a[4], b[4], result[4]; + fetch_vector4(&inst->SrcReg[0], machine, a); + fetch_vector4(&inst->SrcReg[1], machine, b); + result[0] = a[0] * b[0]; + result[1] = a[1] * b[1]; + result[2] = a[2] * b[2]; + result[3] = a[3] * b[3]; + store_vector4(inst, machine, result); + if (DEBUG_PROG) { + printf("MUL (%g %g %g %g) = (%g %g %g %g) * (%g %g %g %g)\n", + result[0], result[1], result[2], result[3], + a[0], a[1], a[2], a[3], b[0], b[1], b[2], b[3]); + } + } + break; + case OPCODE_NOISE1: + { + GLfloat a[4], result[4]; + fetch_vector1(&inst->SrcReg[0], machine, a); + result[0] = + result[1] = + result[2] = result[3] = _slang_library_noise1(a[0]); + store_vector4(inst, machine, result); + } + break; + case OPCODE_NOISE2: + { + GLfloat a[4], result[4]; + fetch_vector4(&inst->SrcReg[0], machine, a); + result[0] = + result[1] = + result[2] = result[3] = _slang_library_noise2(a[0], a[1]); + store_vector4(inst, machine, result); + } + break; + case OPCODE_NOISE3: + { + GLfloat a[4], result[4]; + fetch_vector4(&inst->SrcReg[0], machine, a); + result[0] = + result[1] = + result[2] = + result[3] = _slang_library_noise3(a[0], a[1], a[2]); + store_vector4(inst, machine, result); + } + break; + case OPCODE_NOISE4: + { + GLfloat a[4], result[4]; + fetch_vector4(&inst->SrcReg[0], machine, a); + result[0] = + result[1] = + result[2] = + result[3] = _slang_library_noise4(a[0], a[1], a[2], a[3]); + store_vector4(inst, machine, result); + } + break; + case OPCODE_NOP: + break; + case OPCODE_PK2H: /* pack two 16-bit floats in one 32-bit float */ + { + GLfloat a[4], result[4]; + GLhalfNV hx, hy; + GLuint *rawResult = (GLuint *) result; + GLuint twoHalves; + fetch_vector4(&inst->SrcReg[0], machine, a); + hx = _mesa_float_to_half(a[0]); + hy = _mesa_float_to_half(a[1]); + twoHalves = hx | (hy << 16); + rawResult[0] = rawResult[1] = rawResult[2] = rawResult[3] + = twoHalves; + store_vector4(inst, machine, result); + } + break; + case OPCODE_PK2US: /* pack two GLushorts into one 32-bit float */ + { + GLfloat a[4], result[4]; + GLuint usx, usy, *rawResult = (GLuint *) result; + fetch_vector4(&inst->SrcReg[0], machine, a); + a[0] = CLAMP(a[0], 0.0F, 1.0F); + a[1] = CLAMP(a[1], 0.0F, 1.0F); + usx = IROUND(a[0] * 65535.0F); + usy = IROUND(a[1] * 65535.0F); + rawResult[0] = rawResult[1] = rawResult[2] = rawResult[3] + = usx | (usy << 16); + store_vector4(inst, machine, result); + } + break; + case OPCODE_PK4B: /* pack four GLbytes into one 32-bit float */ + { + GLfloat a[4], result[4]; + GLuint ubx, uby, ubz, ubw, *rawResult = (GLuint *) result; + fetch_vector4(&inst->SrcReg[0], machine, a); + a[0] = CLAMP(a[0], -128.0F / 127.0F, 1.0F); + a[1] = CLAMP(a[1], -128.0F / 127.0F, 1.0F); + a[2] = CLAMP(a[2], -128.0F / 127.0F, 1.0F); + a[3] = CLAMP(a[3], -128.0F / 127.0F, 1.0F); + ubx = IROUND(127.0F * a[0] + 128.0F); + uby = IROUND(127.0F * a[1] + 128.0F); + ubz = IROUND(127.0F * a[2] + 128.0F); + ubw = IROUND(127.0F * a[3] + 128.0F); + rawResult[0] = rawResult[1] = rawResult[2] = rawResult[3] + = ubx | (uby << 8) | (ubz << 16) | (ubw << 24); + store_vector4(inst, machine, result); + } + break; + case OPCODE_PK4UB: /* pack four GLubytes into one 32-bit float */ + { + GLfloat a[4], result[4]; + GLuint ubx, uby, ubz, ubw, *rawResult = (GLuint *) result; + fetch_vector4(&inst->SrcReg[0], machine, a); + a[0] = CLAMP(a[0], 0.0F, 1.0F); + a[1] = CLAMP(a[1], 0.0F, 1.0F); + a[2] = CLAMP(a[2], 0.0F, 1.0F); + a[3] = CLAMP(a[3], 0.0F, 1.0F); + ubx = IROUND(255.0F * a[0]); + uby = IROUND(255.0F * a[1]); + ubz = IROUND(255.0F * a[2]); + ubw = IROUND(255.0F * a[3]); + rawResult[0] = rawResult[1] = rawResult[2] = rawResult[3] + = ubx | (uby << 8) | (ubz << 16) | (ubw << 24); + store_vector4(inst, machine, result); + } + break; + case OPCODE_POW: + { + GLfloat a[4], b[4], result[4]; + fetch_vector1(&inst->SrcReg[0], machine, a); + fetch_vector1(&inst->SrcReg[1], machine, b); + result[0] = result[1] = result[2] = result[3] + = (GLfloat) _mesa_pow(a[0], b[0]); + store_vector4(inst, machine, result); + } + break; + case OPCODE_RCP: + { + GLfloat a[4], result[4]; + fetch_vector1(&inst->SrcReg[0], machine, a); + if (DEBUG_PROG) { + if (a[0] == 0) + printf("RCP(0)\n"); + else if (IS_INF_OR_NAN(a[0])) + printf("RCP(inf)\n"); + } + result[0] = result[1] = result[2] = result[3] = 1.0F / a[0]; + store_vector4(inst, machine, result); + } + break; + 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 */ + { + GLfloat axis[4], dir[4], result[4], tmpX, tmpW; + fetch_vector4(&inst->SrcReg[0], machine, axis); + fetch_vector4(&inst->SrcReg[1], machine, dir); + tmpW = DOT3(axis, axis); + tmpX = (2.0F * DOT3(axis, dir)) / tmpW; + result[0] = tmpX * axis[0] - dir[0]; + result[1] = tmpX * axis[1] - dir[1]; + result[2] = tmpX * axis[2] - dir[2]; + /* result[3] is never written! XXX enforce in parser! */ + store_vector4(inst, machine, result); + } + break; + case OPCODE_RSQ: /* 1 / sqrt() */ + { + GLfloat a[4], result[4]; + fetch_vector1(&inst->SrcReg[0], machine, a); + a[0] = FABSF(a[0]); + result[0] = result[1] = result[2] = result[3] = INV_SQRTF(a[0]); + store_vector4(inst, machine, result); + if (DEBUG_PROG) { + printf("RSQ %g = 1/sqrt(|%g|)\n", result[0], a[0]); + } + } + break; + case OPCODE_SCS: /* sine and cos */ + { + GLfloat a[4], result[4]; + fetch_vector1(&inst->SrcReg[0], machine, a); + result[0] = (GLfloat) _mesa_cos(a[0]); + result[1] = (GLfloat) _mesa_sin(a[0]); + result[2] = 0.0; /* undefined! */ + result[3] = 0.0; /* undefined! */ + store_vector4(inst, machine, result); + } + break; + case OPCODE_SEQ: /* set on equal */ + { + GLfloat a[4], b[4], result[4]; + fetch_vector4(&inst->SrcReg[0], machine, a); + fetch_vector4(&inst->SrcReg[1], machine, b); + result[0] = (a[0] == b[0]) ? 1.0F : 0.0F; + result[1] = (a[1] == b[1]) ? 1.0F : 0.0F; + result[2] = (a[2] == b[2]) ? 1.0F : 0.0F; + result[3] = (a[3] == b[3]) ? 1.0F : 0.0F; + store_vector4(inst, machine, result); + if (DEBUG_PROG) { + printf("SEQ (%g %g %g %g) = (%g %g %g %g) == (%g %g %g %g)\n", + result[0], result[1], result[2], result[3], + a[0], a[1], a[2], a[3], + b[0], b[1], b[2], b[3]); + } + } + break; + case OPCODE_SFL: /* set false, operands ignored */ + { + static const GLfloat result[4] = { 0.0F, 0.0F, 0.0F, 0.0F }; + store_vector4(inst, machine, result); + } + break; + case OPCODE_SGE: /* set on greater or equal */ + { + GLfloat a[4], b[4], result[4]; + fetch_vector4(&inst->SrcReg[0], machine, a); + fetch_vector4(&inst->SrcReg[1], machine, b); + result[0] = (a[0] >= b[0]) ? 1.0F : 0.0F; + result[1] = (a[1] >= b[1]) ? 1.0F : 0.0F; + result[2] = (a[2] >= b[2]) ? 1.0F : 0.0F; + result[3] = (a[3] >= b[3]) ? 1.0F : 0.0F; + store_vector4(inst, machine, result); + if (DEBUG_PROG) { + printf("SGE (%g %g %g %g) = (%g %g %g %g) >= (%g %g %g %g)\n", + result[0], result[1], result[2], result[3], + a[0], a[1], a[2], a[3], + b[0], b[1], b[2], b[3]); + } + } + break; + case OPCODE_SGT: /* set on greater */ + { + GLfloat a[4], b[4], result[4]; + fetch_vector4(&inst->SrcReg[0], machine, a); + fetch_vector4(&inst->SrcReg[1], machine, b); + result[0] = (a[0] > b[0]) ? 1.0F : 0.0F; + result[1] = (a[1] > b[1]) ? 1.0F : 0.0F; + result[2] = (a[2] > b[2]) ? 1.0F : 0.0F; + result[3] = (a[3] > b[3]) ? 1.0F : 0.0F; + store_vector4(inst, machine, result); + if (DEBUG_PROG) { + printf("SGT (%g %g %g %g) = (%g %g %g %g) > (%g %g %g %g)\n", + result[0], result[1], result[2], result[3], + a[0], a[1], a[2], a[3], + b[0], b[1], b[2], b[3]); + } + } + break; + case OPCODE_SIN: + { + GLfloat a[4], result[4]; + fetch_vector1(&inst->SrcReg[0], machine, a); + result[0] = result[1] = result[2] = result[3] + = (GLfloat) _mesa_sin(a[0]); + store_vector4(inst, machine, result); + } + break; + case OPCODE_SLE: /* set on less or equal */ + { + GLfloat a[4], b[4], result[4]; + fetch_vector4(&inst->SrcReg[0], machine, a); + fetch_vector4(&inst->SrcReg[1], machine, b); + result[0] = (a[0] <= b[0]) ? 1.0F : 0.0F; + result[1] = (a[1] <= b[1]) ? 1.0F : 0.0F; + result[2] = (a[2] <= b[2]) ? 1.0F : 0.0F; + result[3] = (a[3] <= b[3]) ? 1.0F : 0.0F; + store_vector4(inst, machine, result); + if (DEBUG_PROG) { + printf("SLE (%g %g %g %g) = (%g %g %g %g) <= (%g %g %g %g)\n", + result[0], result[1], result[2], result[3], + a[0], a[1], a[2], a[3], + b[0], b[1], b[2], b[3]); + } + } + break; + case OPCODE_SLT: /* set on less */ + { + GLfloat a[4], b[4], result[4]; + fetch_vector4(&inst->SrcReg[0], machine, a); + fetch_vector4(&inst->SrcReg[1], machine, b); + result[0] = (a[0] < b[0]) ? 1.0F : 0.0F; + result[1] = (a[1] < b[1]) ? 1.0F : 0.0F; + result[2] = (a[2] < b[2]) ? 1.0F : 0.0F; + result[3] = (a[3] < b[3]) ? 1.0F : 0.0F; + store_vector4(inst, machine, result); + if (DEBUG_PROG) { + printf("SLT (%g %g %g %g) = (%g %g %g %g) < (%g %g %g %g)\n", + result[0], result[1], result[2], result[3], + a[0], a[1], a[2], a[3], + b[0], b[1], b[2], b[3]); + } + } + break; + case OPCODE_SNE: /* set on not equal */ + { + GLfloat a[4], b[4], result[4]; + fetch_vector4(&inst->SrcReg[0], machine, a); + fetch_vector4(&inst->SrcReg[1], machine, b); + result[0] = (a[0] != b[0]) ? 1.0F : 0.0F; + result[1] = (a[1] != b[1]) ? 1.0F : 0.0F; + result[2] = (a[2] != b[2]) ? 1.0F : 0.0F; + result[3] = (a[3] != b[3]) ? 1.0F : 0.0F; + store_vector4(inst, machine, result); + if (DEBUG_PROG) { + printf("SNE (%g %g %g %g) = (%g %g %g %g) != (%g %g %g %g)\n", + result[0], result[1], result[2], result[3], + a[0], a[1], a[2], a[3], + b[0], b[1], b[2], b[3]); + } + } + break; + case OPCODE_STR: /* set true, operands ignored */ + { + static const GLfloat result[4] = { 1.0F, 1.0F, 1.0F, 1.0F }; + store_vector4(inst, machine, result); + } + break; + case OPCODE_SUB: + { + GLfloat a[4], b[4], result[4]; + fetch_vector4(&inst->SrcReg[0], machine, a); + fetch_vector4(&inst->SrcReg[1], machine, b); + result[0] = a[0] - b[0]; + result[1] = a[1] - b[1]; + result[2] = a[2] - b[2]; + result[3] = a[3] - b[3]; + store_vector4(inst, machine, result); + if (DEBUG_PROG) { + printf("SUB (%g %g %g %g) = (%g %g %g %g) - (%g %g %g %g)\n", + result[0], result[1], result[2], result[3], + a[0], a[1], a[2], a[3], b[0], b[1], b[2], b[3]); + } + } + break; + case OPCODE_SWZ: /* extended swizzle */ + { + const struct prog_src_register *source = &inst->SrcReg[0]; + const GLfloat *src = get_register_pointer(source, machine); + GLfloat result[4]; + GLuint i; + for (i = 0; i < 4; i++) { + const GLuint swz = GET_SWZ(source->Swizzle, i); + if (swz == SWIZZLE_ZERO) + result[i] = 0.0; + else if (swz == SWIZZLE_ONE) + result[i] = 1.0; + else { + ASSERT(swz >= 0); + ASSERT(swz <= 3); + result[i] = src[swz]; + } + if (source->NegateBase & (1 << i)) + result[i] = -result[i]; + } + store_vector4(inst, machine, result); + } + break; + case OPCODE_TEX: /* Both ARB and NV frag prog */ + /* Texel lookup */ + { + /* Note: only use the precomputed lambda value when we're + * sampling texture unit [K] with texcoord[K]. + * Otherwise, the lambda value may have no relation to the + * instruction's texcoord or texture image. Using the wrong + * lambda is usually bad news. + * The rest of the time, just use zero (until we get a more + * sophisticated way of computing lambda). + */ + GLfloat coord[4], color[4], lambda; +#if 0 + if (inst->SrcReg[0].File == PROGRAM_INPUT && + inst->SrcReg[0].Index == FRAG_ATTRIB_TEX0 + inst->TexSrcUnit) + lambda = span->array->lambda[inst->TexSrcUnit][column]; + else +#endif + lambda = 0.0; + fetch_vector4(&inst->SrcReg[0], machine, coord); + machine->FetchTexelLod(ctx, coord, lambda, inst->TexSrcUnit, + color); + if (DEBUG_PROG) { + printf("TEX (%g, %g, %g, %g) = texture[%d][%g, %g, %g, %g], " + "lod %f\n", + color[0], color[1], color[2], color[3], + inst->TexSrcUnit, + coord[0], coord[1], coord[2], coord[3], lambda); + } + store_vector4(inst, machine, color); + } + break; + case OPCODE_TXB: /* GL_ARB_fragment_program only */ + /* Texel lookup with LOD bias */ + { + const struct gl_texture_unit *texUnit + = &ctx->Texture.Unit[inst->TexSrcUnit]; + GLfloat coord[4], color[4], lambda, bias; +#if 0 + if (inst->SrcReg[0].File == PROGRAM_INPUT && + inst->SrcReg[0].Index == FRAG_ATTRIB_TEX0 + inst->TexSrcUnit) + lambda = span->array->lambda[inst->TexSrcUnit][column]; + else +#endif + lambda = 0.0; + fetch_vector4(&inst->SrcReg[0], machine, coord); + /* coord[3] is the bias to add to lambda */ + bias = texUnit->LodBias + coord[3]; + if (texUnit->_Current) + bias += texUnit->_Current->LodBias; + machine->FetchTexelLod(ctx, coord, lambda + bias, + inst->TexSrcUnit, color); + store_vector4(inst, machine, color); + } + break; + case OPCODE_TXD: /* GL_NV_fragment_program only */ + /* Texture lookup w/ partial derivatives for LOD */ + { + GLfloat texcoord[4], dtdx[4], dtdy[4], color[4]; + fetch_vector4(&inst->SrcReg[0], machine, texcoord); + fetch_vector4(&inst->SrcReg[1], machine, dtdx); + fetch_vector4(&inst->SrcReg[2], machine, dtdy); + machine->FetchTexelDeriv(ctx, texcoord, dtdx, dtdy, + inst->TexSrcUnit, color); + store_vector4(inst, machine, color); + } + break; + case OPCODE_TXP: /* GL_ARB_fragment_program only */ + /* Texture lookup w/ projective divide */ + { + GLfloat texcoord[4], color[4], lambda; +#if 0 + if (inst->SrcReg[0].File == PROGRAM_INPUT && + inst->SrcReg[0].Index == FRAG_ATTRIB_TEX0 + inst->TexSrcUnit) + lambda = span->array->lambda[inst->TexSrcUnit][column]; + else +#endif + lambda = 0.0; + fetch_vector4(&inst->SrcReg[0], machine, texcoord); + /* Not so sure about this test - if texcoord[3] is + * zero, we'd probably be fine except for an ASSERT in + * IROUND_POS() which gets triggered by the inf values created. + */ + if (texcoord[3] != 0.0) { + texcoord[0] /= texcoord[3]; + texcoord[1] /= texcoord[3]; + texcoord[2] /= texcoord[3]; + } + machine->FetchTexelLod(ctx, texcoord, lambda, + inst->TexSrcUnit, color); + store_vector4(inst, machine, color); + } + break; + case OPCODE_TXP_NV: /* GL_NV_fragment_program only */ + /* Texture lookup w/ projective divide */ + { + GLfloat texcoord[4], color[4], lambda; +#if 0 + if (inst->SrcReg[0].File == PROGRAM_INPUT && + inst->SrcReg[0].Index == FRAG_ATTRIB_TEX0 + inst->TexSrcUnit) + lambda = span->array->lambda[inst->TexSrcUnit][column]; + else +#endif + lambda = 0.0; + fetch_vector4(&inst->SrcReg[0], machine, texcoord); + if (inst->TexSrcTarget != TEXTURE_CUBE_INDEX && + texcoord[3] != 0.0) { + texcoord[0] /= texcoord[3]; + texcoord[1] /= texcoord[3]; + texcoord[2] /= texcoord[3]; + } + machine->FetchTexelLod(ctx, texcoord, lambda, + inst->TexSrcUnit, color); + store_vector4(inst, machine, color); + } + break; + case OPCODE_UP2H: /* unpack two 16-bit floats */ + { + GLfloat a[4], result[4]; + const GLuint *rawBits = (const GLuint *) a; + GLhalfNV hx, hy; + fetch_vector1(&inst->SrcReg[0], machine, a); + hx = rawBits[0] & 0xffff; + hy = rawBits[0] >> 16; + result[0] = result[2] = _mesa_half_to_float(hx); + result[1] = result[3] = _mesa_half_to_float(hy); + store_vector4(inst, machine, result); + } + break; + case OPCODE_UP2US: /* unpack two GLushorts */ + { + GLfloat a[4], result[4]; + const GLuint *rawBits = (const GLuint *) a; + GLushort usx, usy; + fetch_vector1(&inst->SrcReg[0], machine, a); + usx = rawBits[0] & 0xffff; + usy = rawBits[0] >> 16; + result[0] = result[2] = usx * (1.0f / 65535.0f); + result[1] = result[3] = usy * (1.0f / 65535.0f); + store_vector4(inst, machine, result); + } + break; + case OPCODE_UP4B: /* unpack four GLbytes */ + { + GLfloat a[4], result[4]; + const GLuint *rawBits = (const GLuint *) a; + fetch_vector1(&inst->SrcReg[0], machine, a); + result[0] = (((rawBits[0] >> 0) & 0xff) - 128) / 127.0F; + result[1] = (((rawBits[0] >> 8) & 0xff) - 128) / 127.0F; + result[2] = (((rawBits[0] >> 16) & 0xff) - 128) / 127.0F; + result[3] = (((rawBits[0] >> 24) & 0xff) - 128) / 127.0F; + store_vector4(inst, machine, result); + } + break; + case OPCODE_UP4UB: /* unpack four GLubytes */ + { + GLfloat a[4], result[4]; + const GLuint *rawBits = (const GLuint *) a; + fetch_vector1(&inst->SrcReg[0], machine, a); + result[0] = ((rawBits[0] >> 0) & 0xff) / 255.0F; + result[1] = ((rawBits[0] >> 8) & 0xff) / 255.0F; + result[2] = ((rawBits[0] >> 16) & 0xff) / 255.0F; + result[3] = ((rawBits[0] >> 24) & 0xff) / 255.0F; + store_vector4(inst, machine, result); + } + break; + case OPCODE_XPD: /* cross product */ + { + GLfloat a[4], b[4], result[4]; + fetch_vector4(&inst->SrcReg[0], machine, a); + fetch_vector4(&inst->SrcReg[1], machine, b); + result[0] = a[1] * b[2] - a[2] * b[1]; + result[1] = a[2] * b[0] - a[0] * b[2]; + result[2] = a[0] * b[1] - a[1] * b[0]; + result[3] = 1.0; + store_vector4(inst, machine, result); + if (DEBUG_PROG) { + printf("XPD (%g %g %g %g) = (%g %g %g) X (%g %g %g)\n", + result[0], result[1], result[2], result[3], + a[0], a[1], a[2], b[0], b[1], b[2]); + } + } + break; + case OPCODE_X2D: /* 2-D matrix transform */ + { + GLfloat a[4], b[4], c[4], result[4]; + fetch_vector4(&inst->SrcReg[0], machine, a); + fetch_vector4(&inst->SrcReg[1], machine, b); + fetch_vector4(&inst->SrcReg[2], machine, c); + result[0] = a[0] + b[0] * c[0] + b[1] * c[1]; + result[1] = a[1] + b[0] * c[2] + b[1] * c[3]; + result[2] = a[2] + b[0] * c[0] + b[1] * c[1]; + result[3] = a[3] + b[0] * c[2] + b[1] * c[3]; + store_vector4(inst, machine, result); + } + break; + case OPCODE_PRINT: + { + if (inst->SrcReg[0].File != -1) { + GLfloat a[4]; + fetch_vector4(&inst->SrcReg[0], machine, a); + _mesa_printf("%s%g, %g, %g, %g\n", (const char *) inst->Data, + a[0], a[1], a[2], a[3]); + } + else { + _mesa_printf("%s\n", (const char *) inst->Data); + } + } + break; + case OPCODE_END: + return GL_TRUE; + default: + _mesa_problem(ctx, "Bad opcode %d in _mesa_exec_fragment_program", + inst->Opcode); + return GL_TRUE; /* return value doesn't matter */ + + } + + numExec++; + if (numExec > maxExec) { + _mesa_problem(ctx, "Infinite loop detected in fragment program"); + return GL_TRUE; + } + + } /* for pc */ + +#if FEATURE_MESA_program_debug + CurrentMachine = NULL; +#endif + + return GL_TRUE; +} diff --git a/src/mesa/shader/prog_execute.h b/src/mesa/shader/prog_execute.h new file mode 100644 index 0000000000..47845e9111 --- /dev/null +++ b/src/mesa/shader/prog_execute.h @@ -0,0 +1,81 @@ +/* + * 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_EXECUTE_H +#define PROG_EXECUTE_H + + +typedef void (*FetchTexelLodFunc)(GLcontext *ctx, const GLfloat texcoord[4], + GLfloat lambda, GLuint unit, GLfloat color[4]); + +typedef void (*FetchTexelDerivFunc)(GLcontext *ctx, const GLfloat texcoord[4], + const GLfloat texdx[4], + const GLfloat texdy[4], + GLuint unit, GLfloat color[4]); + + +/** The larger of VERT_RESULT_MAX, FRAG_RESULT_MAX */ +#define MAX_PROGRAM_OUTPUTS VERT_RESULT_MAX + + +/** + * Virtual machine state used during execution of vertex/fragment programs. + */ +struct gl_program_machine +{ + const struct gl_program *CurProgram; + + /** Fragment Input attributes */ + GLfloat (*Attribs)[MAX_WIDTH][4]; + GLuint CurElement; /**< Index into Attribs arrays */ + + /** Vertex Input attribs */ + GLfloat VertAttribs[VERT_ATTRIB_MAX][4]; + + GLfloat Temporaries[MAX_PROGRAM_TEMPS][4]; + GLfloat Outputs[MAX_PROGRAM_OUTPUTS][4]; + GLfloat (*EnvParams)[4]; /**< Vertex or Fragment env parameters */ + GLuint CondCodes[4]; /**< COND_* value for x/y/z/w */ + GLint AddressReg[MAX_PROGRAM_ADDRESS_REGS][4]; + + GLuint CallStack[MAX_PROGRAM_CALL_DEPTH]; /**< For CAL/RET instructions */ + GLuint StackDepth; /**< Index/ptr to top of CallStack[] */ + + /** Texture fetch functions */ + FetchTexelLodFunc FetchTexelLod; + FetchTexelDerivFunc FetchTexelDeriv; +}; + + +extern void +_mesa_get_program_register(GLcontext *ctx, enum register_file file, + GLuint index, GLfloat val[4]); + +extern GLboolean +_mesa_execute_program(GLcontext *ctx, + const struct gl_program *program, + struct gl_program_machine *machine); + + +#endif /* PROG_EXECUTE_H */ diff --git a/src/mesa/shader/prog_instruction.c b/src/mesa/shader/prog_instruction.c new file mode 100644 index 0000000000..272caf6c74 --- /dev/null +++ b/src/mesa/shader/prog_instruction.c @@ -0,0 +1,243 @@ +/* + * Mesa 3-D graphics library + * Version: 6.5.3 + * + * Copyright (C) 1999-2005 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 "imports.h" +#include "mtypes.h" +#include "prog_instruction.h" + + +/** + * Initialize program instruction fields to defaults. + * \param inst first instruction to initialize + * \param count number of instructions to initialize + */ +void +_mesa_init_instructions(struct prog_instruction *inst, GLuint count) +{ + GLuint i; + + _mesa_bzero(inst, count * sizeof(struct prog_instruction)); + + for (i = 0; i < count; i++) { + inst[i].SrcReg[0].File = PROGRAM_UNDEFINED; + inst[i].SrcReg[0].Swizzle = SWIZZLE_NOOP; + inst[i].SrcReg[1].File = PROGRAM_UNDEFINED; + inst[i].SrcReg[1].Swizzle = SWIZZLE_NOOP; + inst[i].SrcReg[2].File = PROGRAM_UNDEFINED; + inst[i].SrcReg[2].Swizzle = SWIZZLE_NOOP; + + inst[i].DstReg.File = PROGRAM_UNDEFINED; + inst[i].DstReg.WriteMask = WRITEMASK_XYZW; + inst[i].DstReg.CondMask = COND_TR; + inst[i].DstReg.CondSwizzle = SWIZZLE_NOOP; + + inst[i].SaturateMode = SATURATE_OFF; + inst[i].Precision = FLOAT32; + } +} + + +/** + * Allocate an array of program instructions. + * \param numInst number of instructions + * \return pointer to instruction memory + */ +struct prog_instruction * +_mesa_alloc_instructions(GLuint numInst) +{ + return (struct prog_instruction *) + _mesa_calloc(numInst * sizeof(struct prog_instruction)); +} + + +/** + * Reallocate memory storing an array of program instructions. + * This is used when we need to append additional instructions onto an + * program. + * \param oldInst pointer to first of old/src instructions + * \param numOldInst number of instructions at <oldInst> + * \param numNewInst desired size of new instruction array. + * \return pointer to start of new instruction array. + */ +struct prog_instruction * +_mesa_realloc_instructions(struct prog_instruction *oldInst, + GLuint numOldInst, GLuint numNewInst) +{ + struct prog_instruction *newInst; + + newInst = (struct prog_instruction *) + _mesa_realloc(oldInst, + numOldInst * sizeof(struct prog_instruction), + numNewInst * sizeof(struct prog_instruction)); + + return newInst; +} + + +/** + * Copy an array of program instructions. + * \param dest pointer to destination. + * \param src pointer to source. + * \param n number of instructions to copy. + * \return pointer to destination. + */ +struct prog_instruction * +_mesa_copy_instructions(struct prog_instruction *dest, + const struct prog_instruction *src, GLuint n) +{ + return _mesa_memcpy(dest, src, n * sizeof(struct prog_instruction)); +} + + +/** + * Basic info about each instruction + */ +struct instruction_info +{ + gl_inst_opcode Opcode; + const char *Name; + GLuint NumSrcRegs; +}; + +/** + * Instruction info + * \note Opcode should equal array index! + */ +static const struct instruction_info InstInfo[MAX_OPCODE] = { + { OPCODE_NOP, "NOP", 0 }, + { OPCODE_ABS, "ABS", 1 }, + { OPCODE_ADD, "ADD", 2 }, + { OPCODE_ARA, "ARA", 1 }, + { OPCODE_ARL, "ARL", 1 }, + { OPCODE_ARL_NV, "ARL", 1 }, + { OPCODE_ARR, "ARL", 1 }, + { OPCODE_BGNLOOP,"BGNLOOP", 0 }, + { OPCODE_BGNSUB, "BGNSUB", 0 }, + { OPCODE_BRA, "BRA", 0 }, + { OPCODE_BRK, "BRK", 0 }, + { OPCODE_BRK0, "BRK0", 1 }, + { OPCODE_BRK1, "BRK1", 1 }, + { OPCODE_CAL, "CAL", 0 }, + { OPCODE_CMP, "CMP", 3 }, + { OPCODE_CONT, "CONT", 0 }, + { OPCODE_CONT0, "CONT0", 1 }, + { OPCODE_CONT1, "CONT1", 1 }, + { OPCODE_COS, "COS", 1 }, + { OPCODE_DDX, "DDX", 1 }, + { OPCODE_DDY, "DDY", 1 }, + { OPCODE_DP3, "DP3", 2 }, + { OPCODE_DP4, "DP4", 2 }, + { OPCODE_DPH, "DPH", 2 }, + { OPCODE_DST, "DST", 2 }, + { OPCODE_ELSE, "ELSE", 0 }, + { OPCODE_END, "END", 0 }, + { OPCODE_ENDIF, "ENDIF", 0 }, + { OPCODE_ENDLOOP,"ENDLOOP", 0 }, + { OPCODE_ENDSUB, "ENDSUB", 0 }, + { OPCODE_EX2, "EX2", 1 }, + { OPCODE_EXP, "EXP", 1 }, + { OPCODE_FLR, "FLR", 1 }, + { OPCODE_FRC, "FRC", 1 }, + { OPCODE_IF, "IF", 0 }, + { OPCODE_INT, "INT", 1 }, + { OPCODE_KIL, "KIL", 1 }, + { OPCODE_KIL_NV, "KIL", 0 }, + { OPCODE_LG2, "LG2", 1 }, + { OPCODE_LIT, "LIT", 1 }, + { OPCODE_LOG, "LOG", 1 }, + { OPCODE_LRP, "LRP", 3 }, + { OPCODE_MAD, "MAD", 3 }, + { OPCODE_MAX, "MAX", 2 }, + { OPCODE_MIN, "MIN", 2 }, + { OPCODE_MOV, "MOV", 1 }, + { OPCODE_MUL, "MUL", 2 }, + { OPCODE_NOISE1, "NOISE1", 1 }, + { OPCODE_NOISE2, "NOISE2", 1 }, + { OPCODE_NOISE3, "NOISE3", 1 }, + { OPCODE_NOISE4, "NOISE4", 1 }, + { OPCODE_PK2H, "PK2H", 1 }, + { OPCODE_PK2US, "PK2US", 1 }, + { OPCODE_PK4B, "PK4B", 1 }, + { OPCODE_PK4UB, "PK4UB", 1 }, + { OPCODE_POW, "POW", 2 }, + { OPCODE_POPA, "POPA", 0 }, + { OPCODE_PRINT, "PRINT", 1 }, + { OPCODE_PUSHA, "PUSHA", 0 }, + { OPCODE_RCC, "RCC", 1 }, + { OPCODE_RCP, "RCP", 1 }, + { OPCODE_RET, "RET", 0 }, + { OPCODE_RFL, "RFL", 1 }, + { OPCODE_RSQ, "RSQ", 1 }, + { OPCODE_SCS, "SCS", 1 }, + { OPCODE_SEQ, "SEQ", 2 }, + { OPCODE_SFL, "SFL", 0 }, + { OPCODE_SGE, "SGE", 2 }, + { OPCODE_SGT, "SGT", 2 }, + { OPCODE_SIN, "SIN", 1 }, + { OPCODE_SLE, "SLE", 2 }, + { OPCODE_SLT, "SLT", 2 }, + { OPCODE_SNE, "SNE", 2 }, + { OPCODE_SSG, "SSG", 1 }, + { OPCODE_STR, "STR", 0 }, + { OPCODE_SUB, "SUB", 2 }, + { OPCODE_SWZ, "SWZ", 1 }, + { OPCODE_TEX, "TEX", 1 }, + { OPCODE_TXB, "TXB", 1 }, + { OPCODE_TXD, "TXD", 3 }, + { OPCODE_TXL, "TXL", 1 }, + { OPCODE_TXP, "TXP", 1 }, + { OPCODE_TXP_NV, "TXP", 1 }, + { OPCODE_UP2H, "UP2H", 1 }, + { OPCODE_UP2US, "UP2US", 1 }, + { OPCODE_UP4B, "UP4B", 1 }, + { OPCODE_UP4UB, "UP4UB", 1 }, + { OPCODE_X2D, "X2D", 3 }, + { OPCODE_XPD, "XPD", 2 } +}; + + +/** + * Return the number of src registers for the given instruction/opcode. + */ +GLuint +_mesa_num_inst_src_regs(gl_inst_opcode opcode) +{ + ASSERT(opcode == InstInfo[opcode].Opcode); + ASSERT(OPCODE_XPD == InstInfo[OPCODE_XPD].Opcode); + return InstInfo[opcode].NumSrcRegs; +} + + +/** + * Return string name for given program opcode. + */ +const char * +_mesa_opcode_string(gl_inst_opcode opcode) +{ + ASSERT(opcode < MAX_OPCODE); + return InstInfo[opcode].Name; +} + diff --git a/src/mesa/shader/prog_instruction.h b/src/mesa/shader/prog_instruction.h new file mode 100644 index 0000000000..dc2d2dc29b --- /dev/null +++ b/src/mesa/shader/prog_instruction.h @@ -0,0 +1,451 @@ +/* + * 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. + */ + + +/** + * \file prog_instruction.h + * + * Vertex/fragment program instruction datatypes and constants. + * + * \author Brian Paul + * \author Keith Whitwell + * \author Ian Romanick <idr@us.ibm.com> + */ + + +#ifndef PROG_INSTRUCTION_H +#define PROG_INSTRUCTION_H + + +/** + * Swizzle indexes. + * Do not change! + */ +/*@{*/ +#define SWIZZLE_X 0 +#define SWIZZLE_Y 1 +#define SWIZZLE_Z 2 +#define SWIZZLE_W 3 +#define SWIZZLE_ZERO 4 /**< For SWZ instruction only */ +#define SWIZZLE_ONE 5 /**< For SWZ instruction only */ +#define SWIZZLE_NIL 7 /**< used during shader code gen (undefined value) */ +/*@}*/ + +#define MAKE_SWIZZLE4(a,b,c,d) (((a)<<0) | ((b)<<3) | ((c)<<6) | ((d)<<9)) +#define SWIZZLE_NOOP MAKE_SWIZZLE4(0,1,2,3) +#define GET_SWZ(swz, idx) (((swz) >> ((idx)*3)) & 0x7) +#define GET_BIT(msk, idx) (((msk) >> (idx)) & 0x1) + +#define SWIZZLE_XYZW MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_Y, SWIZZLE_Z, SWIZZLE_W) +#define SWIZZLE_XXXX MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_X, SWIZZLE_X, SWIZZLE_X) +#define SWIZZLE_YYYY MAKE_SWIZZLE4(SWIZZLE_Y, SWIZZLE_Y, SWIZZLE_Y, SWIZZLE_Y) +#define SWIZZLE_ZZZZ MAKE_SWIZZLE4(SWIZZLE_Z, SWIZZLE_Z, SWIZZLE_Z, SWIZZLE_Z) +#define SWIZZLE_WWWW MAKE_SWIZZLE4(SWIZZLE_W, SWIZZLE_W, SWIZZLE_W, SWIZZLE_W) + + +/** + * Writemask values, 1 bit per component. + */ +/*@{*/ +#define WRITEMASK_X 0x1 +#define WRITEMASK_Y 0x2 +#define WRITEMASK_XY 0x3 +#define WRITEMASK_Z 0x4 +#define WRITEMASK_XZ 0x5 +#define WRITEMASK_YZ 0x6 +#define WRITEMASK_XYZ 0x7 +#define WRITEMASK_W 0x8 +#define WRITEMASK_XW 0x9 +#define WRITEMASK_YW 0xa +#define WRITEMASK_XYW 0xb +#define WRITEMASK_ZW 0xc +#define WRITEMASK_XZW 0xd +#define WRITEMASK_YZW 0xe +#define WRITEMASK_XYZW 0xf +/*@}*/ + + +/** + * Condition codes + */ +/*@{*/ +#define COND_GT 1 /**< greater than zero */ +#define COND_EQ 2 /**< equal to zero */ +#define COND_LT 3 /**< less than zero */ +#define COND_UN 4 /**< unordered (NaN) */ +#define COND_GE 5 /**< greater then or equal to zero */ +#define COND_LE 6 /**< less then or equal to zero */ +#define COND_NE 7 /**< not equal to zero */ +#define COND_TR 8 /**< always true */ +#define COND_FL 9 /**< always false */ +/*@}*/ + + +/** + * Instruction precision for GL_NV_fragment_program + */ +/*@{*/ +#define FLOAT32 0x1 +#define FLOAT16 0x2 +#define FIXED12 0x4 +/*@}*/ + + +/** + * Saturation modes when storing values. + */ +/*@{*/ +#define SATURATE_OFF 0 +#define SATURATE_ZERO_ONE 1 +#define SATURATE_PLUS_MINUS_ONE 2 +/*@}*/ + + +/** + * Per-component negation masks + */ +/*@{*/ +#define NEGATE_X 0x1 +#define NEGATE_Y 0x2 +#define NEGATE_Z 0x4 +#define NEGATE_W 0x8 +#define NEGATE_XYZW 0xf +#define NEGATE_NONE 0x0 +/*@}*/ + + +/** + * Program instruction opcodes, for both vertex and fragment programs. + * \note changes to this opcode list must be reflected in t_vb_arbprogram.c + */ +typedef enum prog_opcode { + /* ARB_vp ARB_fp NV_vp NV_fp GLSL */ + /*------------------------------------------*/ + OPCODE_NOP = 0, /* X */ + OPCODE_ABS, /* X X 1.1 X */ + OPCODE_ADD, /* X X X X X */ + OPCODE_ARA, /* 2 */ + OPCODE_ARL, /* X X */ + OPCODE_ARL_NV, /* 2 */ + OPCODE_ARR, /* 2 */ + OPCODE_BGNLOOP, /* opt */ + OPCODE_BGNSUB, /* opt */ + OPCODE_BRA, /* 2 X */ + OPCODE_BRK, /* 2 opt */ + OPCODE_BRK0, /* opt */ + OPCODE_BRK1, /* opt */ + OPCODE_CAL, /* 2 2 */ + OPCODE_CMP, /* X */ + OPCODE_CONT, /* opt */ + OPCODE_CONT0, /* opt */ + OPCODE_CONT1, /* opt */ + OPCODE_COS, /* X 2 X X */ + OPCODE_DDX, /* X X */ + OPCODE_DDY, /* X X */ + OPCODE_DP3, /* X X X X X */ + OPCODE_DP4, /* X X X X X */ + OPCODE_DPH, /* X X 1.1 */ + OPCODE_DST, /* X X X X */ + OPCODE_ELSE, /* X */ + OPCODE_END, /* X X X X opt */ + OPCODE_ENDIF, /* opt */ + OPCODE_ENDLOOP, /* opt */ + OPCODE_ENDSUB, /* opt */ + OPCODE_EX2, /* X X 2 X X */ + OPCODE_EXP, /* X X X */ + OPCODE_FLR, /* X X 2 X X */ + OPCODE_FRC, /* X X 2 X X */ + OPCODE_IF, /* opt */ + OPCODE_INT, /* X */ + OPCODE_KIL, /* X */ + OPCODE_KIL_NV, /* X X */ + OPCODE_LG2, /* X X 2 X X */ + OPCODE_LIT, /* X X X X */ + OPCODE_LOG, /* X X X */ + OPCODE_LRP, /* X X */ + OPCODE_MAD, /* X X X X X */ + OPCODE_MAX, /* X X X X X */ + OPCODE_MIN, /* X X X X X */ + OPCODE_MOV, /* X X X X X */ + OPCODE_MUL, /* X X X X X */ + OPCODE_NOISE1, /* X */ + OPCODE_NOISE2, /* X */ + OPCODE_NOISE3, /* X */ + OPCODE_NOISE4, /* X */ + OPCODE_PK2H, /* X */ + OPCODE_PK2US, /* X */ + OPCODE_PK4B, /* X */ + OPCODE_PK4UB, /* X */ + OPCODE_POW, /* X X X X */ + OPCODE_POPA, /* 3 */ + OPCODE_PRINT, /* X X */ + OPCODE_PUSHA, /* 3 */ + OPCODE_RCC, /* 1.1 */ + OPCODE_RCP, /* X X X X X */ + OPCODE_RET, /* 2 2 */ + OPCODE_RFL, /* X X */ + OPCODE_RSQ, /* X X X X X */ + OPCODE_SCS, /* X */ + OPCODE_SEQ, /* 2 X X */ + OPCODE_SFL, /* 2 X */ + OPCODE_SGE, /* X X X X X */ + OPCODE_SGT, /* 2 X X */ + OPCODE_SIN, /* X 2 X X */ + OPCODE_SLE, /* 2 X X */ + OPCODE_SLT, /* X X X X X */ + OPCODE_SNE, /* 2 X X */ + OPCODE_SSG, /* 2 */ + OPCODE_STR, /* 2 X */ + OPCODE_SUB, /* X X 1.1 X X */ + OPCODE_SWZ, /* X X */ + OPCODE_TEX, /* X 3 X X */ + OPCODE_TXB, /* X 3 X */ + OPCODE_TXD, /* X X */ + OPCODE_TXL, /* 3 2 X */ + OPCODE_TXP, /* X X */ + OPCODE_TXP_NV, /* 3 X */ + OPCODE_UP2H, /* X */ + OPCODE_UP2US, /* X */ + OPCODE_UP4B, /* X */ + OPCODE_UP4UB, /* X */ + OPCODE_X2D, /* X */ + OPCODE_XPD, /* X X X */ + MAX_OPCODE +} gl_inst_opcode; + + +/** + * Instruction source register. + */ +struct prog_src_register +{ + GLuint File:4; /**< One of the PROGRAM_* register file values. */ + GLint Index:9; /**< May be negative for relative addressing. */ + GLuint Swizzle:12; + GLuint RelAddr:1; + + /** + * \name Source register "sign" control. + * + * The ARB and NV extensions allow varrying degrees of control over the + * sign of the source vector components. These values allow enough control + * for all flavors of the extensions. + */ + /*@{*/ + /** + * Per-component negation for the SWZ instruction. For non-SWZ + * instructions the only possible values are NEGATE_XYZW and NEGATE_NONE. + * + * \since + * ARB_vertex_program, ARB_fragment_program + */ + GLuint NegateBase:4; + + /** + * Take the component-wise absolute value. + * + * \since + * NV_fragment_program, NV_fragment_program_option, NV_vertex_program2, + * NV_vertex_program2_option. + */ + GLuint Abs:1; + + /** + * Post-absolute value negation (all components). + */ + GLuint NegateAbs:1; + /*@}*/ +}; + + +/** + * Instruction destination register. + */ +struct prog_dst_register +{ + /** + * One of the PROGRAM_* register file values. + */ + GLuint File:4; + + GLuint Index:8; + GLuint WriteMask:4; + + /** + * \name Conditional destination update control. + * + * \since + * NV_fragment_program, NV_fragment_program_option, NV_vertex_program2, + * NV_vertex_program2_option. + */ + /*@{*/ + /** + * Takes one of the 9 possible condition values (EQ, FL, GT, GE, LE, LT, + * NE, TR, or UN). Dest reg is only written to if the matching + * (swizzled) condition code value passes. When a conditional update mask + * is not specified, this will be \c COND_TR. + */ + GLuint CondMask:4; + + /** + * Condition code swizzle value. + */ + GLuint CondSwizzle:12; + + /** + * Selects the condition code register to use for conditional destination + * update masking. In NV_fragmnet_program or NV_vertex_program2 mode, only + * condition code register 0 is available. In NV_vertex_program3 mode, + * condition code registers 0 and 1 are available. + */ + GLuint CondSrc:1; + /*@}*/ + + GLuint pad:31; +}; + + +/** + * Vertex/fragment program instruction. + */ +struct prog_instruction +{ + gl_inst_opcode Opcode; +#if FEATURE_MESA_program_debug + GLshort StringPos; +#endif + /** + * Arbitrary data. Used for the PRINT, CAL, and BRA instructions. + */ + void *Data; + + struct prog_src_register SrcReg[3]; + struct prog_dst_register DstReg; + + /** + * Indicates that the instruction should update the condition code + * register. + * + * \since + * NV_fragment_program, NV_fragment_program_option, NV_vertex_program2, + * NV_vertex_program2_option. + */ + GLuint CondUpdate:1; + + /** + * If prog_instruction::CondUpdate is \c GL_TRUE, this value selects the + * condition code register that is to be updated. + * + * In GL_NV_fragment_program or GL_NV_vertex_program2 mode, only condition + * code register 0 is available. In GL_NV_vertex_program3 mode, condition + * code registers 0 and 1 are available. + * + * \since + * NV_fragment_program, NV_fragment_program_option, NV_vertex_program2, + * NV_vertex_program2_option. + */ + GLuint CondDst:1; + + /** + * Saturate each value of the vectored result to the range [0,1] or the + * range [-1,1]. \c SSAT mode (i.e., saturation to the range [-1,1]) is + * only available in NV_fragment_program2 mode. + * Value is one of the SATURATE_* tokens. + * + * \since + * NV_fragment_program, NV_fragment_program_option, NV_vertex_program3. + */ + GLuint SaturateMode:2; + + /** + * Per-instruction selectable precision. + * + * \since + * NV_fragment_program, NV_fragment_program_option. + */ + GLuint Precision:3; + + /** + * \name Texture source controls. + * + * The texture source controls are only used with the \c TEX, \c TXD, + * \c TXL, and \c TXP instructions. + * + * \since + * ARB_fragment_program, NV_fragment_program, NV_vertex_program3. + */ + /*@{*/ + /** + * Source texture unit. OpenGL supports a maximum of 32 texture + * units. + */ + GLuint TexSrcUnit:5; + + /** + * Source texture target, one of TEXTURE_{1D,2D,3D,CUBE,RECT}_INDEX. + */ + GLuint TexSrcTarget:3; + /*@}*/ + + /** + * For BRA and CAL instructions, the location to jump to. + * For BGNLOOP, points to ENDLOOP (and vice-versa). + * For BRK, points to BGNLOOP (which points to ENDLOOP). + * For IF, points to else or endif. + * For ELSE, points to endif. + */ + GLint BranchTarget; + + /** + * For TEX instructions in shaders, the sampler to use for the + * texture lookup. + */ + GLint Sampler; + + const char *Comment; +}; + + +extern void +_mesa_init_instructions(struct prog_instruction *inst, GLuint count); + +extern struct prog_instruction * +_mesa_alloc_instructions(GLuint numInst); + +extern struct prog_instruction * +_mesa_realloc_instructions(struct prog_instruction *oldInst, + GLuint numOldInst, GLuint numNewInst); + +extern struct prog_instruction * +_mesa_copy_instructions(struct prog_instruction *dest, + const struct prog_instruction *src, GLuint n); + +extern GLuint +_mesa_num_inst_src_regs(gl_inst_opcode opcode); + +extern const char * +_mesa_opcode_string(gl_inst_opcode opcode); + + +#endif /* PROG_INSTRUCTION_H */ diff --git a/src/mesa/shader/prog_parameter.c b/src/mesa/shader/prog_parameter.c new file mode 100644 index 0000000000..adffafdd71 --- /dev/null +++ b/src/mesa/shader/prog_parameter.c @@ -0,0 +1,600 @@ +/* + * 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. + */ + +/** + * \file prog_parameter.c + * Program parameter lists and functions. + * \author Brian Paul + */ + + +#include "glheader.h" +#include "imports.h" +#include "macros.h" +#include "prog_instruction.h" +#include "prog_parameter.h" +#include "prog_statevars.h" + + +struct gl_program_parameter_list * +_mesa_new_parameter_list(void) +{ + return (struct gl_program_parameter_list *) + _mesa_calloc(sizeof(struct gl_program_parameter_list)); +} + + +/** + * Free a parameter list and all its parameters + */ +void +_mesa_free_parameter_list(struct gl_program_parameter_list *paramList) +{ + GLuint i; + for (i = 0; i < paramList->NumParameters; i++) { + if (paramList->Parameters[i].Name) + _mesa_free((void *) paramList->Parameters[i].Name); + } + _mesa_free(paramList->Parameters); + if (paramList->ParameterValues) + _mesa_align_free(paramList->ParameterValues); + _mesa_free(paramList); +} + + + +/** + * Add a new parameter to a parameter list. + * Note that parameter values are usually 4-element GLfloat vectors. + * When size > 4 we'll allocate a sequential block of parameters to + * store all the values (in blocks of 4). + * + * \param paramList the list to add the parameter to + * \param type type of parameter, such as + * \param name the parameter name, will be duplicated/copied! + * \param size number of elements in 'values' vector (1..4, or more) + * \param values initial parameter value, up to 4 GLfloats, or NULL + * \param state state indexes, or NULL + * \return index of new parameter in the list, or -1 if error (out of mem) + */ +GLint +_mesa_add_parameter(struct gl_program_parameter_list *paramList, + enum register_file type, const char *name, + GLuint size, const GLfloat *values, + const gl_state_index state[STATE_LENGTH]) +{ + const GLuint oldNum = paramList->NumParameters; + const GLuint sz4 = (size + 3) / 4; /* no. of new param slots needed */ + + assert(size > 0); + + if (oldNum + sz4 > paramList->Size) { + /* Need to grow the parameter list array (alloc some extra) */ + paramList->Size = paramList->Size + 4 * sz4; + + /* realloc arrays */ + paramList->Parameters = (struct gl_program_parameter *) + _mesa_realloc(paramList->Parameters, + oldNum * sizeof(struct gl_program_parameter), + paramList->Size * sizeof(struct gl_program_parameter)); + + paramList->ParameterValues = (GLfloat (*)[4]) + _mesa_align_realloc(paramList->ParameterValues, /* old buf */ + oldNum * 4 * sizeof(GLfloat), /* old size */ + paramList->Size * 4 *sizeof(GLfloat), /* new sz */ + 16); + } + + if (!paramList->Parameters || + !paramList->ParameterValues) { + /* out of memory */ + paramList->NumParameters = 0; + paramList->Size = 0; + return -1; + } + else { + GLuint i; + + paramList->NumParameters = oldNum + sz4; + + _mesa_memset(¶mList->Parameters[oldNum], 0, + sz4 * sizeof(struct gl_program_parameter)); + + for (i = 0; i < sz4; i++) { + struct gl_program_parameter *p = paramList->Parameters + oldNum + i; + p->Name = name ? _mesa_strdup(name) : NULL; + p->Type = type; + p->Size = size; + if (values) { + COPY_4V(paramList->ParameterValues[oldNum + i], values); + values += 4; + } + else { + /* silence valgrind */ + ASSIGN_4V(paramList->ParameterValues[oldNum + i], 0, 0, 0, 0); + } + size -= 4; + } + + if (state) { + for (i = 0; i < STATE_LENGTH; i++) + paramList->Parameters[oldNum].StateIndexes[i] = state[i]; + } + + return (GLint) oldNum; + } +} + + +/** + * Add a new named program parameter (Ex: NV_fragment_program DEFINE statement) + * \return index of the new entry in the parameter list + */ +GLint +_mesa_add_named_parameter(struct gl_program_parameter_list *paramList, + const char *name, const GLfloat values[4]) +{ + return _mesa_add_parameter(paramList, PROGRAM_NAMED_PARAM, name, + 4, values, NULL); + +} + + +/** + * Add a new named constant to the parameter list. + * This will be used when the program contains something like this: + * PARAM myVals = { 0, 1, 2, 3 }; + * + * \param paramList the parameter list + * \param name the name for the constant + * \param values four float values + * \return index/position of the new parameter in the parameter list + */ +GLint +_mesa_add_named_constant(struct gl_program_parameter_list *paramList, + const char *name, const GLfloat values[4], + GLuint size) +{ +#if 0 /* disable this for now -- we need to save the name! */ + GLint pos; + GLuint swizzle; + ASSERT(size == 4); /* XXX future feature */ + /* check if we already have this constant */ + if (_mesa_lookup_parameter_constant(paramList, values, 4, &pos, &swizzle)) { + return pos; + } +#endif + size = 4; /** XXX fix */ + return _mesa_add_parameter(paramList, PROGRAM_CONSTANT, name, + size, values, NULL); +} + + +/** + * Add a new unnamed constant to the parameter list. This will be used + * when a fragment/vertex program contains something like this: + * MOV r, { 0, 1, 2, 3 }; + * We'll search the parameter list for an existing instance of the + * constant. If swizzleOut is non-null, we'll try swizzling when + * looking for a match. + * + * \param paramList the parameter list + * \param values four float values + * \param swizzleOut returns swizzle mask for accessing the constant + * \return index/position of the new parameter in the parameter list. + */ +GLint +_mesa_add_unnamed_constant(struct gl_program_parameter_list *paramList, + const GLfloat values[4], GLuint size, + GLuint *swizzleOut) +{ + GLint pos; + ASSERT(size >= 1); + ASSERT(size <= 4); + + if (_mesa_lookup_parameter_constant(paramList, values, + size, &pos, swizzleOut)) { + return pos; + } + + /* Look for empty space in an already unnamed constant parameter + * to add this constant. This will only work for single-element + * constants because we rely on smearing (i.e. .yyyy or .zzzz). + */ + if (size == 1 && swizzleOut) { + for (pos = 0; pos < (GLint) paramList->NumParameters; pos++) { + struct gl_program_parameter *p = paramList->Parameters + pos; + if (p->Type == PROGRAM_CONSTANT && p->Size + size <= 4) { + /* ok, found room */ + GLfloat *pVal = paramList->ParameterValues[pos]; + GLuint swz = p->Size; /* 1, 2 or 3 for Y, Z, W */ + pVal[p->Size] = values[0]; + p->Size++; + *swizzleOut = MAKE_SWIZZLE4(swz, swz, swz, swz); + return pos; + } + } + } + + /* add a new parameter to store this constant */ + pos = _mesa_add_parameter(paramList, PROGRAM_CONSTANT, NULL, + size, values, NULL); + if (pos >= 0 && swizzleOut) { + if (size == 1) + *swizzleOut = SWIZZLE_XXXX; + else + *swizzleOut = SWIZZLE_NOOP; + } + return pos; +} + + +GLint +_mesa_add_uniform(struct gl_program_parameter_list *paramList, + const char *name, GLuint size) +{ + GLint i = _mesa_lookup_parameter_index(paramList, -1, name); + if (i >= 0 && paramList->Parameters[i].Type == PROGRAM_UNIFORM) { + /* already in list */ + return i; + } + else { + i = _mesa_add_parameter(paramList, PROGRAM_UNIFORM, name, + size, NULL, NULL); + + return i; + } +} + + +GLint +_mesa_add_sampler(struct gl_program_parameter_list *paramList, + const char *name) +{ + GLint i = _mesa_lookup_parameter_index(paramList, -1, name); + if (i >= 0 && paramList->Parameters[i].Type == PROGRAM_SAMPLER) { + /* already in list */ + return i; + } + else { + const GLint size = 1; + i = _mesa_add_parameter(paramList, PROGRAM_SAMPLER, name, + size, NULL, NULL); + return i; + } +} + + +/** + * Add parameter representing a varying variable. + */ +GLint +_mesa_add_varying(struct gl_program_parameter_list *paramList, + const char *name, GLuint size) +{ + GLint i = _mesa_lookup_parameter_index(paramList, -1, name); + if (i >= 0 && paramList->Parameters[i].Type == PROGRAM_VARYING) { + /* already in list */ + return i; + } + else { + assert(size == 4); + i = _mesa_add_parameter(paramList, PROGRAM_VARYING, name, + size, NULL, NULL); + return i; + } +} + + +/** + * Add parameter representing a vertex program attribute. + * \param size size of attribute (in floats), may be -1 if unknown + * \param attrib the attribute index, or -1 if unknown + */ +GLint +_mesa_add_attribute(struct gl_program_parameter_list *paramList, + const char *name, GLint size, GLint attrib) +{ + GLint i = _mesa_lookup_parameter_index(paramList, -1, name); + if (i >= 0) { + /* replace */ + if (attrib < 0) + attrib = i; + paramList->Parameters[i].StateIndexes[0] = attrib; + } + else { + /* add */ + gl_state_index state[STATE_LENGTH]; + state[0] = (gl_state_index) attrib; + if (size < 0) + size = 4; + i = _mesa_add_parameter(paramList, PROGRAM_INPUT, name, + size, NULL, state); + } + return i; +} + + + +#if 0 /* not used yet */ +/** + * Returns the number of 4-component registers needed to store a piece + * of GL state. For matrices this may be as many as 4 registers, + * everything else needs + * just 1 register. + */ +static GLuint +sizeof_state_reference(const GLint *stateTokens) +{ + if (stateTokens[0] == STATE_MATRIX) { + GLuint rows = stateTokens[4] - stateTokens[3] + 1; + assert(rows >= 1); + assert(rows <= 4); + return rows; + } + else { + return 1; + } +} +#endif + + +/** + * Add a new state reference to the parameter list. + * This will be used when the program contains something like this: + * PARAM ambient = state.material.front.ambient; + * + * \param paramList the parameter list + * \param state an array of 6 (STATE_LENGTH) state tokens + * \return index of the new parameter. + */ +GLint +_mesa_add_state_reference(struct gl_program_parameter_list *paramList, + const gl_state_index stateTokens[STATE_LENGTH]) +{ + const GLuint size = 4; /* XXX fix */ + const char *name; + GLint index; + + /* Check if the state reference is already in the list */ + for (index = 0; index < (GLint) paramList->NumParameters; index++) { + GLuint i, match = 0; + for (i = 0; i < STATE_LENGTH; i++) { + if (paramList->Parameters[index].StateIndexes[i] == stateTokens[i]) { + match++; + } + else { + break; + } + } + if (match == STATE_LENGTH) { + /* this state reference is already in the parameter list */ + return index; + } + } + + name = _mesa_program_state_string(stateTokens); + index = _mesa_add_parameter(paramList, PROGRAM_STATE_VAR, name, + size, NULL, (gl_state_index *) stateTokens); + paramList->StateFlags |= _mesa_program_state_flags(stateTokens); + + /* free name string here since we duplicated it in add_parameter() */ + _mesa_free((void *) name); + + return index; +} + + +/** + * Lookup a parameter value by name in the given parameter list. + * \return pointer to the float[4] values. + */ +GLfloat * +_mesa_lookup_parameter_value(const struct gl_program_parameter_list *paramList, + GLsizei nameLen, const char *name) +{ + GLuint i = _mesa_lookup_parameter_index(paramList, nameLen, name); + if (i < 0) + return NULL; + else + return paramList->ParameterValues[i]; +} + + +/** + * Given a program parameter name, find its position in the list of parameters. + * \param paramList the parameter list to search + * \param nameLen length of name (in chars). + * If length is negative, assume that name is null-terminated. + * \param name the name to search for + * \return index of parameter in the list. + */ +GLint +_mesa_lookup_parameter_index(const struct gl_program_parameter_list *paramList, + GLsizei nameLen, const char *name) +{ + GLint i; + + if (!paramList) + return -1; + + if (nameLen == -1) { + /* name is null-terminated */ + for (i = 0; i < (GLint) paramList->NumParameters; i++) { + if (paramList->Parameters[i].Name && + _mesa_strcmp(paramList->Parameters[i].Name, name) == 0) + return i; + } + } + else { + /* name is not null-terminated, use nameLen */ + for (i = 0; i < (GLint) paramList->NumParameters; i++) { + if (paramList->Parameters[i].Name && + _mesa_strncmp(paramList->Parameters[i].Name, name, nameLen) == 0 + && _mesa_strlen(paramList->Parameters[i].Name) == (size_t)nameLen) + return i; + } + } + return -1; +} + + +/** + * Look for a float vector in the given parameter list. The float vector + * may be of length 1, 2, 3 or 4. If swizzleOut is non-null, we'll try + * swizzling to find a match. + * \param list the parameter list to search + * \param v the float vector to search for + * \param size number of element in v + * \param posOut returns the position of the constant, if found + * \param swizzleOut returns a swizzle mask describing location of the + * vector elements if found. + * \return GL_TRUE if found, GL_FALSE if not found + */ +GLboolean +_mesa_lookup_parameter_constant(const struct gl_program_parameter_list *list, + const GLfloat v[], GLuint vSize, + GLint *posOut, GLuint *swizzleOut) +{ + GLuint i; + + assert(vSize >= 1); + assert(vSize <= 4); + + if (!list) + return -1; + + for (i = 0; i < list->NumParameters; i++) { + if (list->Parameters[i].Type == PROGRAM_CONSTANT) { + if (!swizzleOut) { + /* swizzle not allowed */ + GLuint j, match = 0; + for (j = 0; j < vSize; j++) { + if (v[j] == list->ParameterValues[i][j]) + match++; + } + if (match == vSize) { + *posOut = i; + return GL_TRUE; + } + } + else { + /* try matching w/ swizzle */ + if (vSize == 1) { + /* look for v[0] anywhere within float[4] value */ + GLuint j; + for (j = 0; j < 4; j++) { + if (list->ParameterValues[i][j] == v[0]) { + /* found it */ + *posOut = i; + *swizzleOut = MAKE_SWIZZLE4(j, j, j, j); + return GL_TRUE; + } + } + } + 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 (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 = MAKE_SWIZZLE4(swz[0], swz[1], swz[2], swz[3]); + return GL_TRUE; + } + } + } + } + } + + *posOut = -1; + return GL_FALSE; +} + + +struct gl_program_parameter_list * +_mesa_clone_parameter_list(const struct gl_program_parameter_list *list) +{ + struct gl_program_parameter_list *clone; + GLuint i; + + clone = _mesa_new_parameter_list(); + if (!clone) + return NULL; + + /** Not too efficient, but correct */ + for (i = 0; i < list->NumParameters; i++) { + struct gl_program_parameter *p = list->Parameters + i; + GLuint size = MIN2(p->Size, 4); + GLint j = _mesa_add_parameter(clone, p->Type, p->Name, + size, list->ParameterValues[i], NULL); + ASSERT(j >= 0); + /* copy state indexes */ + if (p->Type == PROGRAM_STATE_VAR) { + GLint k; + struct gl_program_parameter *q = clone->Parameters + j; + for (k = 0; k < STATE_LENGTH; k++) { + q->StateIndexes[k] = p->StateIndexes[k]; + } + } + else { + clone->Parameters[j].Size = p->Size; + } + } + + return clone; +} + + +/** + * Find longest name of any parameter in list. + */ +GLuint +_mesa_parameter_longest_name(const struct gl_program_parameter_list *list) +{ + GLuint i, maxLen = 0; + if (!list) + return 0; + for (i = 0; i < list->NumParameters; i++) { + GLuint len = _mesa_strlen(list->Parameters[i].Name); + if (len > maxLen) + maxLen = len; + } + return maxLen; +} + diff --git a/src/mesa/shader/prog_parameter.h b/src/mesa/shader/prog_parameter.h new file mode 100644 index 0000000000..3d32a64f38 --- /dev/null +++ b/src/mesa/shader/prog_parameter.h @@ -0,0 +1,136 @@ +/* + * 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. + */ + +/** + * \file prog_parameter.c + * Program parameter lists and functions. + * \author Brian Paul + */ + +#ifndef PROG_PARAMETER_H +#define PROG_PARAMETER_H + +#include "mtypes.h" +#include "prog_statevars.h" + + +/** + * Program parameter. + * Used for NV_fragment_program for "DEFINE"d constants and "DECLARE"d + * parameters. + * Also used by ARB_vertex/fragment_programs for state variables, etc. + * Used by shaders for uniforms, constants, varying vars, etc. + */ +struct gl_program_parameter +{ + const char *Name; /**< Null-terminated string */ + enum register_file Type; /**< PROGRAM_NAMED_PARAM, CONSTANT or STATE_VAR */ + GLuint Size; /**< Number of components (1..4) */ + /** + * A sequence of STATE_* tokens and integers to identify GL state. + */ + gl_state_index StateIndexes[STATE_LENGTH]; +}; + + +/** + * List of gl_program_parameter instances. + */ +struct gl_program_parameter_list +{ + GLuint Size; /**< allocated size of Parameters, ParameterValues */ + GLuint NumParameters; /**< number of parameters in arrays */ + struct gl_program_parameter *Parameters; /**< Array [Size] */ + GLfloat (*ParameterValues)[4]; /**< Array [Size] of GLfloat[4] */ + GLbitfield StateFlags; /**< _NEW_* flags indicating which state changes + might invalidate ParameterValues[] */ +}; + + +extern struct gl_program_parameter_list * +_mesa_new_parameter_list(void); + +extern void +_mesa_free_parameter_list(struct gl_program_parameter_list *paramList); + +extern struct gl_program_parameter_list * +_mesa_clone_parameter_list(const struct gl_program_parameter_list *list); + +extern GLint +_mesa_add_parameter(struct gl_program_parameter_list *paramList, + enum register_file type, const char *name, + GLuint size, const GLfloat *values, + const gl_state_index state[STATE_LENGTH]); + +extern GLint +_mesa_add_named_parameter(struct gl_program_parameter_list *paramList, + const char *name, const GLfloat values[4]); + +extern GLint +_mesa_add_named_constant(struct gl_program_parameter_list *paramList, + const char *name, const GLfloat values[4], + GLuint size); + +extern GLint +_mesa_add_unnamed_constant(struct gl_program_parameter_list *paramList, + const GLfloat values[4], GLuint size, + GLuint *swizzleOut); + +extern GLint +_mesa_add_uniform(struct gl_program_parameter_list *paramList, + const char *name, GLuint size); + +extern GLint +_mesa_add_sampler(struct gl_program_parameter_list *paramList, + const char *name); + +extern GLint +_mesa_add_varying(struct gl_program_parameter_list *paramList, + const char *name, GLuint size); + +extern GLint +_mesa_add_attribute(struct gl_program_parameter_list *paramList, + const char *name, GLint size, GLint attrib); + +extern GLint +_mesa_add_state_reference(struct gl_program_parameter_list *paramList, + const gl_state_index stateTokens[STATE_LENGTH]); + +extern GLfloat * +_mesa_lookup_parameter_value(const struct gl_program_parameter_list *paramList, + GLsizei nameLen, const char *name); + +extern GLint +_mesa_lookup_parameter_index(const struct gl_program_parameter_list *paramList, + GLsizei nameLen, const char *name); + +extern GLboolean +_mesa_lookup_parameter_constant(const struct gl_program_parameter_list *list, + const GLfloat v[], GLuint vSize, + GLint *posOut, GLuint *swizzleOut); + +extern GLuint +_mesa_parameter_longest_name(const struct gl_program_parameter_list *list); + +#endif /* PROG_PARAMETER_H */ diff --git a/src/mesa/shader/prog_print.c b/src/mesa/shader/prog_print.c new file mode 100644 index 0000000000..3f7ad47e05 --- /dev/null +++ b/src/mesa/shader/prog_print.c @@ -0,0 +1,749 @@ +/* + * 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. + */ + +/** + * \file prog_print.c + * Print vertex/fragment programs - for debugging. + * \author Brian Paul + */ + +#include "glheader.h" +#include "context.h" +#include "imports.h" +#include "prog_instruction.h" +#include "prog_parameter.h" +#include "prog_print.h" +#include "prog_statevars.h" + + + +/** + * Return string name for given program/register file. + */ +static const char * +file_string(enum register_file f, gl_prog_print_mode mode) +{ + switch (f) { + case PROGRAM_TEMPORARY: + return "TEMP"; + case PROGRAM_LOCAL_PARAM: + return "LOCAL"; + case PROGRAM_ENV_PARAM: + return "ENV"; + case PROGRAM_STATE_VAR: + return "STATE"; + case PROGRAM_INPUT: + return "INPUT"; + case PROGRAM_OUTPUT: + return "OUTPUT"; + case PROGRAM_NAMED_PARAM: + return "NAMED"; + case PROGRAM_CONSTANT: + return "CONST"; + case PROGRAM_UNIFORM: + return "UNIFORM"; + case PROGRAM_VARYING: + return "VARYING"; + case PROGRAM_WRITE_ONLY: + return "WRITE_ONLY"; + case PROGRAM_ADDRESS: + return "ADDR"; + case PROGRAM_SAMPLER: + return "SAMPLER"; + default: + return "Unknown program file!"; + } +} + + +/** + * 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 + * \param negateBase 4-bit negation vector + * \param extended if true, also allow 0, 1 values + */ +const char * +_mesa_swizzle_string(GLuint swizzle, GLuint negateBase, GLboolean extended) +{ + static const char swz[] = "xyzw01?!"; + static char s[20]; + GLuint i = 0; + + if (!extended && swizzle == SWIZZLE_NOOP && negateBase == 0) + return ""; /* no swizzle/negation */ + + if (!extended) + s[i++] = '.'; + + if (negateBase & 0x1) + s[i++] = '-'; + s[i++] = swz[GET_SWZ(swizzle, 0)]; + + if (extended) { + s[i++] = ','; + } + + if (negateBase & 0x2) + s[i++] = '-'; + s[i++] = swz[GET_SWZ(swizzle, 1)]; + + if (extended) { + s[i++] = ','; + } + + if (negateBase & 0x4) + s[i++] = '-'; + s[i++] = swz[GET_SWZ(swizzle, 2)]; + + if (extended) { + s[i++] = ','; + } + + if (negateBase & 0x8) + s[i++] = '-'; + s[i++] = swz[GET_SWZ(swizzle, 3)]; + + s[i] = 0; + return s; +} + + +static const char * +writemask_string(GLuint writeMask) +{ + static char s[10]; + GLuint i = 0; + + if (writeMask == WRITEMASK_XYZW) + return ""; + + s[i++] = '.'; + if (writeMask & WRITEMASK_X) + s[i++] = 'x'; + if (writeMask & WRITEMASK_Y) + s[i++] = 'y'; + if (writeMask & WRITEMASK_Z) + s[i++] = 'z'; + if (writeMask & WRITEMASK_W) + s[i++] = 'w'; + + s[i] = 0; + return s; +} + + +static const char * +condcode_string(GLuint condcode) +{ + switch (condcode) { + case COND_GT: return "GT"; + case COND_EQ: return "EQ"; + case COND_LT: return "LT"; + case COND_UN: return "UN"; + case COND_GE: return "GE"; + case COND_LE: return "LE"; + case COND_NE: return "NE"; + case COND_TR: return "TR"; + case COND_FL: return "FL"; + default: return "cond???"; + } +} + + +static void +print_dst_reg(const struct prog_dst_register *dstReg, gl_prog_print_mode mode, + const struct gl_program *prog) +{ + _mesa_printf("%s%s", + reg_string((enum register_file) dstReg->File, + dstReg->Index, mode, prog), + writemask_string(dstReg->WriteMask)); + + if (dstReg->CondMask != COND_TR) { + _mesa_printf(" (%s.%s)", + condcode_string(dstReg->CondMask), + _mesa_swizzle_string(dstReg->CondSwizzle, GL_FALSE, GL_FALSE)); + } + +#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, 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), + _mesa_swizzle_string(srcReg->Swizzle, + srcReg->NegateBase, GL_FALSE)); +#if 0 + _mesa_printf("%s[%d]%s", + file_string((enum register_file) srcReg->File, mode), + srcReg->Index, + _mesa_swizzle_string(srcReg->Swizzle, + srcReg->NegateBase, GL_FALSE)); +#endif +} + +static void +print_comment(const struct prog_instruction *inst) +{ + if (inst->Comment) + _mesa_printf("; # %s\n", inst->Comment); + else + _mesa_printf(";\n"); +} + + +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; + + _mesa_printf("%s", opcode_string); + if (inst->CondUpdate) + _mesa_printf(".C"); + + /* frag prog only */ + if (inst->SaturateMode == SATURATE_ZERO_ONE) + _mesa_printf("_SAT"); + + _mesa_printf(" "); + if (inst->DstReg.File != PROGRAM_UNDEFINED) { + print_dst_reg(&inst->DstReg, mode, prog); + } + else { + _mesa_printf(" ???"); + } + + if (numRegs > 0) + _mesa_printf(", "); + + for (j = 0; j < numRegs; j++) { + print_src_reg(inst->SrcReg + j, mode, prog); + if (j + 1 < numRegs) + _mesa_printf(", "); + } + + print_comment(inst); +} + + +void +_mesa_print_alu_instruction(const struct prog_instruction *inst, + const char *opcode_string, GLuint numRegs) +{ + print_alu_instruction(inst, opcode_string, numRegs, PROG_PRINT_DEBUG, NULL); +} + + +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_opt(const struct prog_instruction *inst, GLint indent, + gl_prog_print_mode mode, + const struct gl_program *prog) +{ + GLint i; + + if (inst->Opcode == OPCODE_ELSE || + inst->Opcode == OPCODE_ENDIF || + inst->Opcode == OPCODE_ENDLOOP || + inst->Opcode == OPCODE_ENDSUB) { + indent -= 3; + } + for (i = 0; i < indent; i++) { + _mesa_printf(" "); + } + + switch (inst->Opcode) { + case OPCODE_PRINT: + _mesa_printf("PRINT '%s'", inst->Data); + if (inst->SrcReg[0].File != PROGRAM_UNDEFINED) { + _mesa_printf(", "); + _mesa_printf("%s[%d]%s", + file_string((enum register_file) inst->SrcReg[0].File, + mode), + inst->SrcReg[0].Index, + _mesa_swizzle_string(inst->SrcReg[0].Swizzle, + inst->SrcReg[0].NegateBase, GL_FALSE)); + } + if (inst->Comment) + _mesa_printf(" # %s", inst->Comment); + print_comment(inst); + break; + case OPCODE_SWZ: + _mesa_printf("SWZ"); + if (inst->SaturateMode == SATURATE_ZERO_ONE) + _mesa_printf("_SAT"); + _mesa_printf(" "); + print_dst_reg(&inst->DstReg, mode, prog); + _mesa_printf("%s[%d], %s", + file_string((enum register_file) inst->SrcReg[0].File, + mode), + inst->SrcReg[0].Index, + _mesa_swizzle_string(inst->SrcReg[0].Swizzle, + inst->SrcReg[0].NegateBase, GL_TRUE)); + print_comment(inst); + break; + case OPCODE_TEX: + case OPCODE_TXP: + case OPCODE_TXB: + _mesa_printf("%s", _mesa_opcode_string(inst->Opcode)); + if (inst->SaturateMode == SATURATE_ZERO_ONE) + _mesa_printf("_SAT"); + _mesa_printf(" "); + print_dst_reg(&inst->DstReg, mode, prog); + _mesa_printf(", "); + 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; + case TEXTURE_2D_INDEX: _mesa_printf("2D"); break; + case TEXTURE_3D_INDEX: _mesa_printf("3D"); break; + case TEXTURE_CUBE_INDEX: _mesa_printf("CUBE"); break; + case TEXTURE_RECT_INDEX: _mesa_printf("RECT"); break; + default: + ; + } + print_comment(inst); + break; + case OPCODE_ARL: + _mesa_printf("ARL addr.x, "); + print_src_reg(&inst->SrcReg[0], mode, prog); + print_comment(inst); + break; + case OPCODE_BRA: + _mesa_printf("BRA %u (%s%s)", + inst->BranchTarget, + condcode_string(inst->DstReg.CondMask), + _mesa_swizzle_string(inst->DstReg.CondSwizzle, 0, GL_FALSE)); + print_comment(inst); + break; + case OPCODE_CAL: + _mesa_printf("CAL %u", inst->BranchTarget); + print_comment(inst); + break; + case OPCODE_IF: + if (inst->SrcReg[0].File != PROGRAM_UNDEFINED) { + /* Use ordinary register */ + _mesa_printf("IF "); + print_src_reg(&inst->SrcReg[0], mode, prog); + _mesa_printf("; "); + } + else { + /* Use cond codes */ + _mesa_printf("IF (%s%s);", + condcode_string(inst->DstReg.CondMask), + _mesa_swizzle_string(inst->DstReg.CondSwizzle, + 0, GL_FALSE)); + } + _mesa_printf(" # (if false, goto %d)", inst->BranchTarget); + print_comment(inst); + return indent + 3; + case OPCODE_ELSE: + _mesa_printf("ELSE; # (goto %d)\n", inst->BranchTarget); + return indent + 3; + case OPCODE_ENDIF: + _mesa_printf("ENDIF;\n"); + break; + case OPCODE_BGNLOOP: + _mesa_printf("BGNLOOP; # (end at %d)\n", inst->BranchTarget); + return indent + 3; + case OPCODE_ENDLOOP: + _mesa_printf("ENDLOOP; # (goto %d)\n", inst->BranchTarget); + break; + case OPCODE_BRK: + case OPCODE_CONT: + _mesa_printf("%s (%s%s); # (goto %d)", + _mesa_opcode_string(inst->Opcode), + condcode_string(inst->DstReg.CondMask), + _mesa_swizzle_string(inst->DstReg.CondSwizzle, 0, GL_FALSE), + inst->BranchTarget); + print_comment(inst); + break; + + case OPCODE_BRK0: + case OPCODE_BRK1: + case OPCODE_CONT0: + case OPCODE_CONT1: + _mesa_printf("%s ", _mesa_opcode_string(inst->Opcode)); + print_src_reg(&inst->SrcReg[0], mode, prog); + _mesa_printf("; "); + _mesa_printf(" # (goto %d)", inst->BranchTarget); + print_comment(inst); + break; + + case OPCODE_BGNSUB: + _mesa_printf("SUB"); + print_comment(inst); + return indent + 3; + case OPCODE_ENDSUB: + _mesa_printf("ENDSUB"); + print_comment(inst); + break; + case OPCODE_END: + _mesa_printf("END\n"); + break; + case OPCODE_NOP: + if (mode == PROG_PRINT_DEBUG) { + _mesa_printf("NOP"); + print_comment(inst); + } + else if (inst->Comment) { + /* ARB/NV extensions don't have NOP instruction */ + _mesa_printf("# %s\n", inst->Comment); + } + break; + /* XXX may need other special-case instructions */ + default: + /* typical alu instruction */ + print_alu_instruction(inst, + _mesa_opcode_string(inst->Opcode), + _mesa_num_inst_src_regs(inst->Opcode), + mode, prog); + break; + } + return indent; +} + + +/** + * 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++) { + if (lineNumbers) + _mesa_printf("%3d: ", i); + indent = _mesa_print_instruction_opt(prog->Instructions + i, + indent, mode, prog); + } +} + + +/** + * Print all of a program's parameters. + */ +void +_mesa_print_program_parameters(GLcontext *ctx, const struct gl_program *prog) +{ + _mesa_printf("InputsRead: 0x%x\n", prog->InputsRead); + _mesa_printf("OutputsWritten: 0x%x\n", prog->OutputsWritten); + _mesa_printf("NumInstructions=%d\n", prog->NumInstructions); + _mesa_printf("NumTemporaries=%d\n", prog->NumTemporaries); + _mesa_printf("NumParameters=%d\n", prog->NumParameters); + _mesa_printf("NumAttributes=%d\n", prog->NumAttributes); + _mesa_printf("NumAddressRegs=%d\n", prog->NumAddressRegs); + + _mesa_load_state_parameters(ctx, prog->Parameters); + +#if 0 + _mesa_printf("Local Params:\n"); + for (i = 0; i < MAX_PROGRAM_LOCAL_PARAMS; i++){ + const GLfloat *p = prog->LocalParams[i]; + _mesa_printf("%2d: %f, %f, %f, %f\n", i, p[0], p[1], p[2], p[3]); + } +#endif + _mesa_print_parameter_list(prog->Parameters); +} + + +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 = {%.3g, %.3g, %.3g, %.3g};\n", + i, param->Size, + file_string(list->Parameters[i].Type, mode), + param->Name, v[0], v[1], v[2], v[3]); + } +} diff --git a/src/mesa/shader/nvvertexec.h b/src/mesa/shader/prog_print.h index b1cf31bd3c..9c7607f9d5 100644 --- a/src/mesa/shader/nvvertexec.h +++ b/src/mesa/shader/prog_print.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"), @@ -20,48 +20,50 @@ * 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. - * - * Authors: - * Brian Paul */ -#ifndef NVVERTEXEC_H -#define NVVERTEXEC_H + +#ifndef PROG_PRINT_H +#define PROG_PRINT_H /** - * Virtual vertex program machine state. - * Only used during program execution. + * The output style to use when printing programs. */ -struct vp_machine -{ - GLfloat Temporaries[MAX_NV_VERTEX_PROGRAM_TEMPS][4]; - GLfloat Inputs[MAX_NV_VERTEX_PROGRAM_INPUTS][4]; - GLuint InputsSize[MAX_NV_VERTEX_PROGRAM_INPUTS]; - GLfloat Outputs[MAX_NV_VERTEX_PROGRAM_OUTPUTS][4]; - GLint AddressReg[4]; -}; +typedef enum { + PROG_PRINT_ARB, + PROG_PRINT_NV, + PROG_PRINT_DEBUG +} gl_prog_print_mode; + +extern const char * +_mesa_swizzle_string(GLuint swizzle, GLuint negateBase, GLboolean extended); +extern void +_mesa_print_alu_instruction(const struct prog_instruction *inst, + const char *opcode_string, GLuint numRegs); extern void -_mesa_init_vp_per_vertex_registers(GLcontext *ctx, struct vp_machine *machine); +_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_init_vp_per_primitive_registers(GLcontext *ctx); +_mesa_print_program(const struct gl_program *prog); extern void -_mesa_exec_vertex_program(GLcontext *ctx, - struct vp_machine *machine, - const struct gl_vertex_program *program); +_mesa_print_program_opt(const struct gl_program *prog, gl_prog_print_mode mode, + GLboolean lineNumbers); extern void -_mesa_exec_vertex_state_program(GLcontext *ctx, - struct gl_vertex_program *vprog, - const GLfloat *params); +_mesa_print_program_parameters(GLcontext *ctx, const struct gl_program *prog); extern void -_mesa_dump_vp_state( const struct gl_vertex_program_state *state, - const struct vp_machine *machine); +_mesa_print_parameter_list(const struct gl_program_parameter_list *list); + -#endif +#endif /* PROG_PRINT_H */ diff --git a/src/mesa/shader/prog_statevars.c b/src/mesa/shader/prog_statevars.c new file mode 100644 index 0000000000..953fbb9b9f --- /dev/null +++ b/src/mesa/shader/prog_statevars.c @@ -0,0 +1,824 @@ +/* + * 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. + */ + +/** + * \file prog_statevars.c + * Program state variable management. + * \author Brian Paul + */ + + +#include "glheader.h" +#include "context.h" +#include "hash.h" +#include "imports.h" +#include "macros.h" +#include "mtypes.h" +#include "prog_statevars.h" +#include "prog_parameter.h" +#include "nvvertparse.h" + + +/** + * Use the list of tokens in the state[] array to find global GL state + * and return it in <value>. Usually, four values are returned in <value> + * but matrix queries may return as many as 16 values. + * This function is used for ARB vertex/fragment programs. + * The program parser will produce the state[] values. + */ +static void +_mesa_fetch_state(GLcontext *ctx, const gl_state_index state[], + GLfloat *value) +{ + switch (state[0]) { + case STATE_MATERIAL: + { + /* state[1] is either 0=front or 1=back side */ + const GLuint face = (GLuint) state[1]; + const struct gl_material *mat = &ctx->Light.Material; + ASSERT(face == 0 || face == 1); + /* we rely on tokens numbered so that _BACK_ == _FRONT_+ 1 */ + ASSERT(MAT_ATTRIB_FRONT_AMBIENT + 1 == MAT_ATTRIB_BACK_AMBIENT); + /* XXX we could get rid of this switch entirely with a little + * work in arbprogparse.c's parse_state_single_item(). + */ + /* state[2] is the material attribute */ + switch (state[2]) { + case STATE_AMBIENT: + COPY_4V(value, mat->Attrib[MAT_ATTRIB_FRONT_AMBIENT + face]); + return; + case STATE_DIFFUSE: + COPY_4V(value, mat->Attrib[MAT_ATTRIB_FRONT_DIFFUSE + face]); + return; + case STATE_SPECULAR: + COPY_4V(value, mat->Attrib[MAT_ATTRIB_FRONT_SPECULAR + face]); + return; + case STATE_EMISSION: + COPY_4V(value, mat->Attrib[MAT_ATTRIB_FRONT_EMISSION + face]); + return; + case STATE_SHININESS: + value[0] = mat->Attrib[MAT_ATTRIB_FRONT_SHININESS + face][0]; + value[1] = 0.0F; + value[2] = 0.0F; + value[3] = 1.0F; + return; + default: + _mesa_problem(ctx, "Invalid material state in fetch_state"); + return; + } + } + case STATE_LIGHT: + { + /* state[1] is the light number */ + const GLuint ln = (GLuint) state[1]; + /* state[2] is the light attribute */ + switch (state[2]) { + case STATE_AMBIENT: + COPY_4V(value, ctx->Light.Light[ln].Ambient); + return; + case STATE_DIFFUSE: + COPY_4V(value, ctx->Light.Light[ln].Diffuse); + return; + case STATE_SPECULAR: + COPY_4V(value, ctx->Light.Light[ln].Specular); + return; + case STATE_POSITION: + COPY_4V(value, ctx->Light.Light[ln].EyePosition); + return; + case STATE_ATTENUATION: + value[0] = ctx->Light.Light[ln].ConstantAttenuation; + value[1] = ctx->Light.Light[ln].LinearAttenuation; + value[2] = ctx->Light.Light[ln].QuadraticAttenuation; + value[3] = ctx->Light.Light[ln].SpotExponent; + return; + case STATE_SPOT_DIRECTION: + COPY_3V(value, ctx->Light.Light[ln].EyeDirection); + value[3] = ctx->Light.Light[ln]._CosCutoff; + return; + case STATE_SPOT_CUTOFF: + value[0] = ctx->Light.Light[ln].SpotCutoff; + return; + case STATE_HALF_VECTOR: + { + GLfloat eye_z[] = {0, 0, 1}; + + /* Compute infinite half angle vector: + * half-vector = light_position + (0, 0, 1) + * and then normalize. w = 0 + * + * light.EyePosition.w should be 0 for infinite lights. + */ + ADD_3V(value, eye_z, ctx->Light.Light[ln].EyePosition); + NORMALIZE_3FV(value); + value[3] = 0; + } + return; + case STATE_POSITION_NORMALIZED: + COPY_4V(value, ctx->Light.Light[ln].EyePosition); + NORMALIZE_3FV( value ); + return; + default: + _mesa_problem(ctx, "Invalid light state in fetch_state"); + return; + } + } + case STATE_LIGHTMODEL_AMBIENT: + COPY_4V(value, ctx->Light.Model.Ambient); + return; + case STATE_LIGHTMODEL_SCENECOLOR: + if (state[1] == 0) { + /* front */ + GLint i; + for (i = 0; i < 3; i++) { + value[i] = ctx->Light.Model.Ambient[i] + * ctx->Light.Material.Attrib[MAT_ATTRIB_FRONT_AMBIENT][i] + + ctx->Light.Material.Attrib[MAT_ATTRIB_FRONT_EMISSION][i]; + } + value[3] = ctx->Light.Material.Attrib[MAT_ATTRIB_FRONT_DIFFUSE][3]; + } + else { + /* back */ + GLint i; + for (i = 0; i < 3; i++) { + value[i] = ctx->Light.Model.Ambient[i] + * ctx->Light.Material.Attrib[MAT_ATTRIB_BACK_AMBIENT][i] + + ctx->Light.Material.Attrib[MAT_ATTRIB_BACK_EMISSION][i]; + } + value[3] = ctx->Light.Material.Attrib[MAT_ATTRIB_BACK_DIFFUSE][3]; + } + return; + case STATE_LIGHTPROD: + { + const GLuint ln = (GLuint) state[1]; + const GLuint face = (GLuint) state[2]; + GLint i; + ASSERT(face == 0 || face == 1); + switch (state[3]) { + case STATE_AMBIENT: + for (i = 0; i < 3; i++) { + value[i] = ctx->Light.Light[ln].Ambient[i] * + ctx->Light.Material.Attrib[MAT_ATTRIB_FRONT_AMBIENT+face][i]; + } + /* [3] = material alpha */ + value[3] = ctx->Light.Material.Attrib[MAT_ATTRIB_FRONT_DIFFUSE+face][3]; + return; + case STATE_DIFFUSE: + for (i = 0; i < 3; i++) { + value[i] = ctx->Light.Light[ln].Diffuse[i] * + ctx->Light.Material.Attrib[MAT_ATTRIB_FRONT_DIFFUSE+face][i]; + } + /* [3] = material alpha */ + value[3] = ctx->Light.Material.Attrib[MAT_ATTRIB_FRONT_DIFFUSE+face][3]; + return; + case STATE_SPECULAR: + for (i = 0; i < 3; i++) { + value[i] = ctx->Light.Light[ln].Specular[i] * + ctx->Light.Material.Attrib[MAT_ATTRIB_FRONT_SPECULAR+face][i]; + } + /* [3] = material alpha */ + value[3] = ctx->Light.Material.Attrib[MAT_ATTRIB_FRONT_DIFFUSE+face][3]; + return; + default: + _mesa_problem(ctx, "Invalid lightprod state in fetch_state"); + return; + } + } + case STATE_TEXGEN: + { + /* state[1] is the texture unit */ + const GLuint unit = (GLuint) state[1]; + /* state[2] is the texgen attribute */ + switch (state[2]) { + case STATE_TEXGEN_EYE_S: + COPY_4V(value, ctx->Texture.Unit[unit].EyePlaneS); + return; + case STATE_TEXGEN_EYE_T: + COPY_4V(value, ctx->Texture.Unit[unit].EyePlaneT); + return; + case STATE_TEXGEN_EYE_R: + COPY_4V(value, ctx->Texture.Unit[unit].EyePlaneR); + return; + case STATE_TEXGEN_EYE_Q: + COPY_4V(value, ctx->Texture.Unit[unit].EyePlaneQ); + return; + case STATE_TEXGEN_OBJECT_S: + COPY_4V(value, ctx->Texture.Unit[unit].ObjectPlaneS); + return; + case STATE_TEXGEN_OBJECT_T: + COPY_4V(value, ctx->Texture.Unit[unit].ObjectPlaneT); + return; + case STATE_TEXGEN_OBJECT_R: + COPY_4V(value, ctx->Texture.Unit[unit].ObjectPlaneR); + return; + case STATE_TEXGEN_OBJECT_Q: + COPY_4V(value, ctx->Texture.Unit[unit].ObjectPlaneQ); + return; + default: + _mesa_problem(ctx, "Invalid texgen state in fetch_state"); + return; + } + } + case STATE_TEXENV_COLOR: + { + /* state[1] is the texture unit */ + const GLuint unit = (GLuint) state[1]; + COPY_4V(value, ctx->Texture.Unit[unit].EnvColor); + } + return; + case STATE_FOG_COLOR: + COPY_4V(value, ctx->Fog.Color); + return; + case STATE_FOG_PARAMS: + value[0] = ctx->Fog.Density; + value[1] = ctx->Fog.Start; + value[2] = ctx->Fog.End; + value[3] = 1.0F / (ctx->Fog.End - ctx->Fog.Start); + return; + case STATE_CLIPPLANE: + { + const GLuint plane = (GLuint) state[1]; + COPY_4V(value, ctx->Transform.EyeUserPlane[plane]); + } + return; + case STATE_POINT_SIZE: + value[0] = ctx->Point.Size; + value[1] = ctx->Point.MinSize; + value[2] = ctx->Point.MaxSize; + value[3] = ctx->Point.Threshold; + return; + case STATE_POINT_ATTENUATION: + value[0] = ctx->Point.Params[0]; + value[1] = ctx->Point.Params[1]; + value[2] = ctx->Point.Params[2]; + value[3] = 1.0F; + return; + case STATE_MODELVIEW_MATRIX: + case STATE_PROJECTION_MATRIX: + case STATE_MVP_MATRIX: + case STATE_TEXTURE_MATRIX: + case STATE_PROGRAM_MATRIX: + { + /* state[0] = modelview, projection, texture, etc. */ + /* state[1] = which texture matrix or program matrix */ + /* state[2] = first row to fetch */ + /* state[3] = last row to fetch */ + /* state[4] = transpose, inverse or invtrans */ + const GLmatrix *matrix; + const gl_state_index mat = state[0]; + const GLuint index = (GLuint) state[1]; + const GLuint firstRow = (GLuint) state[2]; + const GLuint lastRow = (GLuint) state[3]; + const gl_state_index modifier = state[4]; + const GLfloat *m; + GLuint row, i; + ASSERT(firstRow >= 0); + ASSERT(firstRow < 4); + ASSERT(lastRow >= 0); + ASSERT(lastRow < 4); + if (mat == STATE_MODELVIEW_MATRIX) { + matrix = ctx->ModelviewMatrixStack.Top; + } + else if (mat == STATE_PROJECTION_MATRIX) { + matrix = ctx->ProjectionMatrixStack.Top; + } + else if (mat == STATE_MVP_MATRIX) { + matrix = &ctx->_ModelProjectMatrix; + } + else if (mat == STATE_TEXTURE_MATRIX) { + matrix = ctx->TextureMatrixStack[index].Top; + } + else if (mat == STATE_PROGRAM_MATRIX) { + matrix = ctx->ProgramMatrixStack[index].Top; + } + else { + _mesa_problem(ctx, "Bad matrix name in _mesa_fetch_state()"); + return; + } + if (modifier == STATE_MATRIX_INVERSE || + modifier == STATE_MATRIX_INVTRANS) { + /* Be sure inverse is up to date: + */ + _math_matrix_alloc_inv( (GLmatrix *) matrix ); + _math_matrix_analyse( (GLmatrix*) matrix ); + m = matrix->inv; + } + else { + m = matrix->m; + } + if (modifier == STATE_MATRIX_TRANSPOSE || + modifier == STATE_MATRIX_INVTRANS) { + for (i = 0, row = firstRow; row <= lastRow; row++) { + value[i++] = m[row * 4 + 0]; + value[i++] = m[row * 4 + 1]; + value[i++] = m[row * 4 + 2]; + value[i++] = m[row * 4 + 3]; + } + } + else { + for (i = 0, row = firstRow; row <= lastRow; row++) { + value[i++] = m[row + 0]; + value[i++] = m[row + 4]; + value[i++] = m[row + 8]; + value[i++] = m[row + 12]; + } + } + } + return; + case STATE_DEPTH_RANGE: + value[0] = ctx->Viewport.Near; /* near */ + value[1] = ctx->Viewport.Far; /* far */ + value[2] = ctx->Viewport.Far - ctx->Viewport.Near; /* far - near */ + value[3] = 0; + return; + case STATE_FRAGMENT_PROGRAM: + { + /* state[1] = {STATE_ENV, STATE_LOCAL} */ + /* state[2] = parameter index */ + const int idx = (int) state[2]; + switch (state[1]) { + case STATE_ENV: + COPY_4V(value, ctx->FragmentProgram.Parameters[idx]); + break; + case STATE_LOCAL: + COPY_4V(value, ctx->FragmentProgram.Current->Base.LocalParams[idx]); + break; + default: + _mesa_problem(ctx, "Bad state switch in _mesa_fetch_state()"); + return; + } + } + return; + + case STATE_VERTEX_PROGRAM: + { + /* state[1] = {STATE_ENV, STATE_LOCAL} */ + /* state[2] = parameter index */ + const int idx = (int) state[2]; + switch (state[1]) { + case STATE_ENV: + COPY_4V(value, ctx->VertexProgram.Parameters[idx]); + break; + case STATE_LOCAL: + COPY_4V(value, ctx->VertexProgram.Current->Base.LocalParams[idx]); + break; + default: + _mesa_problem(ctx, "Bad state switch in _mesa_fetch_state()"); + return; + } + } + return; + + case STATE_NORMAL_SCALE: + ASSIGN_4V(value, ctx->_ModelViewInvScale, 0, 0, 1); + return; + + case STATE_INTERNAL: + switch (state[1]) { + case STATE_NORMAL_SCALE: + ASSIGN_4V(value, ctx->_ModelViewInvScale, 0, 0, 1); + return; + case STATE_TEXRECT_SCALE: + { + const int unit = (int) state[2]; + const struct gl_texture_object *texObj + = ctx->Texture.Unit[unit]._Current; + if (texObj) { + struct gl_texture_image *texImage = texObj->Image[0][0]; + ASSIGN_4V(value, 1.0 / texImage->Width, + 1.0 / texImage->Height, + 0.0, 1.0); + } + } + return; + case STATE_FOG_PARAMS_OPTIMIZED: + /* for simpler per-vertex/pixel fog calcs. POW (for EXP/EXP2 fog) + * might be more expensive than EX2 on some hw, plus it needs + * another constant (e) anyway. Linear fog can now be done with a + * single MAD. + * linear: fogcoord * -1/(end-start) + end/(end-start) + * exp: 2^-(density/ln(2) * fogcoord) + * exp2: 2^-((density/(ln(2)^2) * fogcoord)^2) + */ + value[0] = -1.0F / (ctx->Fog.End - ctx->Fog.Start); + value[1] = ctx->Fog.End / (ctx->Fog.End - ctx->Fog.Start); + value[2] = ctx->Fog.Density * ONE_DIV_LN2; + value[3] = ctx->Fog.Density * ONE_DIV_SQRT_LN2; + return; + case STATE_SPOT_DIR_NORMALIZED: { + /* here, state[2] is the light number */ + /* pre-normalize spot dir */ + const GLuint ln = (GLuint) state[2]; + COPY_3V(value, ctx->Light.Light[ln].EyeDirection); + NORMALIZE_3FV(value); + value[3] = ctx->Light.Light[ln]._CosCutoff; + return; + } + default: + /* unknown state indexes are silently ignored + * should be handled by the driver. + */ + return; + } + return; + + default: + _mesa_problem(ctx, "Invalid state in _mesa_fetch_state"); + return; + } +} + + +/** + * Return a bitmask of the Mesa state flags (_NEW_* values) which would + * indicate that the given context state may have changed. + * The bitmask is used during validation to determine if we need to update + * vertex/fragment program parameters (like "state.material.color") when + * some GL state has changed. + */ +GLbitfield +_mesa_program_state_flags(const gl_state_index state[STATE_LENGTH]) +{ + switch (state[0]) { + case STATE_MATERIAL: + case STATE_LIGHT: + case STATE_LIGHTMODEL_AMBIENT: + case STATE_LIGHTMODEL_SCENECOLOR: + case STATE_LIGHTPROD: + return _NEW_LIGHT; + + case STATE_TEXGEN: + case STATE_TEXENV_COLOR: + return _NEW_TEXTURE; + + case STATE_FOG_COLOR: + case STATE_FOG_PARAMS: + return _NEW_FOG; + + case STATE_CLIPPLANE: + return _NEW_TRANSFORM; + + case STATE_POINT_SIZE: + case STATE_POINT_ATTENUATION: + return _NEW_POINT; + + case STATE_MODELVIEW_MATRIX: + return _NEW_MODELVIEW; + case STATE_PROJECTION_MATRIX: + return _NEW_PROJECTION; + case STATE_MVP_MATRIX: + return _NEW_MODELVIEW | _NEW_PROJECTION; + case STATE_TEXTURE_MATRIX: + return _NEW_TEXTURE_MATRIX; + case STATE_PROGRAM_MATRIX: + return _NEW_TRACK_MATRIX; + + case STATE_DEPTH_RANGE: + return _NEW_VIEWPORT; + + case STATE_FRAGMENT_PROGRAM: + case STATE_VERTEX_PROGRAM: + return _NEW_PROGRAM; + + case STATE_NORMAL_SCALE: + return _NEW_MODELVIEW; + + case STATE_INTERNAL: + switch (state[1]) { + case STATE_TEXRECT_SCALE: + return _NEW_TEXTURE; + default: + /* unknown state indexes are silently ignored and + * no flag set, since it is handled by the driver. + */ + return 0; + } + + default: + _mesa_problem(NULL, "unexpected state[0] in make_state_flags()"); + return 0; + } +} + + +static void +append(char *dst, const char *src) +{ + while (*dst) + dst++; + while (*src) + *dst++ = *src++; + *dst = 0; +} + + +static void +append_token(char *dst, gl_state_index k) +{ + switch (k) { + case STATE_MATERIAL: + append(dst, "material"); + break; + case STATE_LIGHT: + append(dst, "light"); + break; + case STATE_LIGHTMODEL_AMBIENT: + append(dst, "lightmodel.ambient"); + break; + case STATE_LIGHTMODEL_SCENECOLOR: + break; + case STATE_LIGHTPROD: + append(dst, "lightprod"); + break; + case STATE_TEXGEN: + append(dst, "texgen"); + break; + case STATE_FOG_COLOR: + append(dst, "fog.color"); + break; + case STATE_FOG_PARAMS: + append(dst, "fog.params"); + break; + case STATE_CLIPPLANE: + append(dst, "clip"); + break; + case STATE_POINT_SIZE: + append(dst, "point.size"); + break; + case STATE_POINT_ATTENUATION: + append(dst, "point.attenuation"); + break; + case STATE_MODELVIEW_MATRIX: + append(dst, "matrix.modelview"); + break; + case STATE_PROJECTION_MATRIX: + append(dst, "matrix.projection"); + break; + case STATE_MVP_MATRIX: + append(dst, "matrix.mvp"); + break; + case STATE_TEXTURE_MATRIX: + append(dst, "matrix.texture"); + break; + case STATE_PROGRAM_MATRIX: + append(dst, "matrix.program"); + break; + case STATE_MATRIX_INVERSE: + append(dst, ".inverse"); + break; + case STATE_MATRIX_TRANSPOSE: + append(dst, ".transpose"); + break; + case STATE_MATRIX_INVTRANS: + append(dst, ".invtrans"); + break; + case STATE_AMBIENT: + append(dst, ".ambient"); + break; + case STATE_DIFFUSE: + append(dst, ".diffuse"); + break; + case STATE_SPECULAR: + append(dst, ".specular"); + break; + case STATE_EMISSION: + append(dst, ".emission"); + break; + case STATE_SHININESS: + append(dst, "lshininess"); + break; + case STATE_HALF_VECTOR: + append(dst, ".half"); + break; + case STATE_POSITION: + append(dst, ".position"); + break; + case STATE_ATTENUATION: + append(dst, ".attenuation"); + break; + case STATE_SPOT_DIRECTION: + append(dst, ".spot.direction"); + break; + case STATE_SPOT_CUTOFF: + append(dst, ".spot.cutoff"); + break; + case STATE_TEXGEN_EYE_S: + append(dst, "eye.s"); + break; + case STATE_TEXGEN_EYE_T: + append(dst, "eye.t"); + break; + case STATE_TEXGEN_EYE_R: + append(dst, "eye.r"); + break; + case STATE_TEXGEN_EYE_Q: + append(dst, "eye.q"); + break; + case STATE_TEXGEN_OBJECT_S: + append(dst, "object.s"); + break; + case STATE_TEXGEN_OBJECT_T: + append(dst, "object.t"); + break; + case STATE_TEXGEN_OBJECT_R: + append(dst, "object.r"); + break; + case STATE_TEXGEN_OBJECT_Q: + append(dst, "object.q"); + break; + case STATE_TEXENV_COLOR: + append(dst, "texenv"); + break; + case STATE_DEPTH_RANGE: + append(dst, "depth.range"); + break; + case STATE_VERTEX_PROGRAM: + case STATE_FRAGMENT_PROGRAM: + break; + case STATE_ENV: + append(dst, "env"); + break; + case STATE_LOCAL: + append(dst, "local"); + break; + case STATE_NORMAL_SCALE: + append(dst, "normalScale"); + break; + case STATE_INTERNAL: + case STATE_POSITION_NORMALIZED: + append(dst, "(internal)"); + break; + default: + ; + } +} + +static void +append_face(char *dst, GLint face) +{ + if (face == 0) + append(dst, "front."); + else + append(dst, "back."); +} + +static void +append_index(char *dst, GLint index) +{ + char s[20]; + _mesa_sprintf(s, "[%d]", index); + append(dst, s); +} + +/** + * Make a string from the given state vector. + * For example, return "state.matrix.texture[2].inverse". + * Use _mesa_free() to deallocate the string. + */ +const char * +_mesa_program_state_string(const gl_state_index state[STATE_LENGTH]) +{ + char str[1000] = ""; + char tmp[30]; + + append(str, "state."); + append_token(str, (gl_state_index) state[0]); + + switch (state[0]) { + case STATE_MATERIAL: + append_face(str, state[1]); + append_token(str, (gl_state_index) state[2]); + break; + case STATE_LIGHT: + append_index(str, state[1]); /* light number [i]. */ + append_token(str, (gl_state_index) state[2]); /* coefficients */ + break; + case STATE_LIGHTMODEL_AMBIENT: + append(str, "lightmodel.ambient"); + break; + case STATE_LIGHTMODEL_SCENECOLOR: + if (state[1] == 0) { + append(str, "lightmodel.front.scenecolor"); + } + else { + append(str, "lightmodel.back.scenecolor"); + } + break; + case STATE_LIGHTPROD: + append_index(str, state[1]); /* light number [i]. */ + append_face(str, state[2]); + append_token(str, (gl_state_index) state[3]); + break; + case STATE_TEXGEN: + append_index(str, state[1]); /* tex unit [i] */ + append_token(str, (gl_state_index) state[2]); /* plane coef */ + break; + case STATE_TEXENV_COLOR: + append_index(str, state[1]); /* tex unit [i] */ + append(str, "color"); + break; + case STATE_CLIPPLANE: + append_index(str, state[1]); /* plane [i] */ + append(str, ".plane"); + break; + case STATE_MODELVIEW_MATRIX: + case STATE_PROJECTION_MATRIX: + case STATE_MVP_MATRIX: + case STATE_TEXTURE_MATRIX: + case STATE_PROGRAM_MATRIX: + { + /* state[0] = modelview, projection, texture, etc. */ + /* state[1] = which texture matrix or program matrix */ + /* state[2] = first row to fetch */ + /* state[3] = last row to fetch */ + /* state[4] = transpose, inverse or invtrans */ + const gl_state_index mat = (gl_state_index) state[0]; + const GLuint index = (GLuint) state[1]; + const GLuint firstRow = (GLuint) state[2]; + const GLuint lastRow = (GLuint) state[3]; + const gl_state_index modifier = (gl_state_index) state[4]; + if (index || + mat == STATE_TEXTURE_MATRIX || + mat == STATE_PROGRAM_MATRIX) + append_index(str, index); + if (modifier) + append_token(str, modifier); + if (firstRow == lastRow) + _mesa_sprintf(tmp, ".row[%d]", firstRow); + else + _mesa_sprintf(tmp, ".row[%d..%d]", firstRow, lastRow); + append(str, tmp); + } + break; + case STATE_POINT_SIZE: + break; + case STATE_POINT_ATTENUATION: + break; + case STATE_FOG_PARAMS: + break; + case STATE_FOG_COLOR: + break; + case STATE_DEPTH_RANGE: + break; + case STATE_FRAGMENT_PROGRAM: + case STATE_VERTEX_PROGRAM: + /* state[1] = {STATE_ENV, STATE_LOCAL} */ + /* state[2] = parameter index */ + append_token(str, (gl_state_index) state[1]); + append_index(str, state[2]); + break; + case STATE_INTERNAL: + break; + default: + _mesa_problem(NULL, "Invalid state in _mesa_program_state_string"); + break; + } + + return _mesa_strdup(str); +} + + +/** + * Loop over all the parameters in a parameter list. If the parameter + * is a GL state reference, look up the current value of that state + * variable and put it into the parameter's Value[4] array. + * This would be called at glBegin time when using a fragment program. + */ +void +_mesa_load_state_parameters(GLcontext *ctx, + struct gl_program_parameter_list *paramList) +{ + GLuint i; + + if (!paramList) + return; + + for (i = 0; i < paramList->NumParameters; i++) { + if (paramList->Parameters[i].Type == PROGRAM_STATE_VAR) { + _mesa_fetch_state(ctx, + (gl_state_index *) paramList->Parameters[i].StateIndexes, + paramList->ParameterValues[i]); + } + } +} + diff --git a/src/mesa/shader/prog_statevars.h b/src/mesa/shader/prog_statevars.h new file mode 100644 index 0000000000..3281a4a2a0 --- /dev/null +++ b/src/mesa/shader/prog_statevars.h @@ -0,0 +1,129 @@ +/* + * Mesa 3-D graphics library + * Version: 6.5.2 + * + * Copyright (C) 1999-2006 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_STATEVARS_H +#define PROG_STATEVARS_H + +#include "mtypes.h" + + +/** + * Number of STATE_* values we need to address any GL state. + * Used to dimension arrays. + */ +#define STATE_LENGTH 5 + + +/** + * Used for describing GL state referenced from inside ARB vertex and + * fragment programs. + * A string such as "state.light[0].ambient" gets translated into a + * sequence of tokens such as [ STATE_LIGHT, 0, STATE_AMBIENT ]. + * + * For state that's an array, like STATE_CLIPPLANE, the 2nd token [1] should + * always be the array index. + */ +typedef enum gl_state_index_ { + STATE_MATERIAL = 100, /* start at 100 so small ints are seen as ints */ + + STATE_LIGHT, + STATE_LIGHTMODEL_AMBIENT, + STATE_LIGHTMODEL_SCENECOLOR, + STATE_LIGHTPROD, + + STATE_TEXGEN, + + STATE_FOG_COLOR, + STATE_FOG_PARAMS, + + STATE_CLIPPLANE, + + STATE_POINT_SIZE, + STATE_POINT_ATTENUATION, + + STATE_MODELVIEW_MATRIX, + STATE_PROJECTION_MATRIX, + STATE_MVP_MATRIX, + STATE_TEXTURE_MATRIX, + STATE_PROGRAM_MATRIX, + STATE_MATRIX_INVERSE, + STATE_MATRIX_TRANSPOSE, + STATE_MATRIX_INVTRANS, + + STATE_AMBIENT, + STATE_DIFFUSE, + STATE_SPECULAR, + STATE_EMISSION, + STATE_SHININESS, + STATE_HALF_VECTOR, + + STATE_POSITION, + STATE_ATTENUATION, + STATE_SPOT_DIRECTION, + STATE_SPOT_CUTOFF, + + STATE_TEXGEN_EYE_S, + STATE_TEXGEN_EYE_T, + STATE_TEXGEN_EYE_R, + STATE_TEXGEN_EYE_Q, + STATE_TEXGEN_OBJECT_S, + STATE_TEXGEN_OBJECT_T, + STATE_TEXGEN_OBJECT_R, + STATE_TEXGEN_OBJECT_Q, + + STATE_TEXENV_COLOR, + + STATE_DEPTH_RANGE, + + STATE_VERTEX_PROGRAM, + STATE_FRAGMENT_PROGRAM, + + STATE_ENV, + STATE_LOCAL, + + STATE_INTERNAL, /* Mesa additions */ + STATE_NORMAL_SCALE, + STATE_TEXRECT_SCALE, + STATE_POSITION_NORMALIZED, /* normalized light position */ + STATE_FOG_PARAMS_OPTIMIZED, /* for faster fog calc */ + STATE_SPOT_DIR_NORMALIZED, /* pre-normalized spot dir */ + STATE_INTERNAL_DRIVER /* first available state index for drivers (must be last) */ +} gl_state_index; + + + +extern void +_mesa_load_state_parameters(GLcontext *ctx, + struct gl_program_parameter_list *paramList); + + +extern GLbitfield +_mesa_program_state_flags(const gl_state_index state[STATE_LENGTH]); + + +extern const char * +_mesa_program_state_string(const gl_state_index state[STATE_LENGTH]); + + +#endif /* PROG_STATEVARS_H */ diff --git a/src/mesa/shader/program.c b/src/mesa/shader/program.c index 98daf7062f..e872d78611 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,29 +32,13 @@ #include "glheader.h" #include "context.h" #include "hash.h" -#include "imports.h" -#include "macros.h" -#include "mtypes.h" #include "program.h" -#include "nvfragparse.h" -#include "program_instruction.h" -#include "nvvertparse.h" -#include "atifragshader.h" +#include "prog_parameter.h" +#include "prog_instruction.h" -static const char * -make_state_string(const GLint stateTokens[6]); - -static GLbitfield -make_state_flags(const GLint state[]); - - -/**********************************************************************/ -/* 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; @@ -203,6 +187,7 @@ _mesa_init_program_struct( GLcontext *ctx, struct gl_program *prog, { (void) ctx; if (prog) { + _mesa_bzero(prog, sizeof(*prog)); prog->Id = id; prog->Target = target; prog->Resident = GL_TRUE; @@ -303,6 +288,12 @@ _mesa_delete_program(GLcontext *ctx, struct gl_program *prog) if (prog->Parameters) { _mesa_free_parameter_list(prog->Parameters); } + if (prog->Varying) { + _mesa_free_parameter_list(prog->Varying); + } + if (prog->Attributes) { + _mesa_free_parameter_list(prog->Attributes); + } /* XXX this is a little ugly */ if (prog->Target == GL_VERTEX_PROGRAM_ARB) { @@ -330,1556 +321,86 @@ _mesa_lookup_program(GLcontext *ctx, GLuint id) } -/**********************************************************************/ -/* Program parameter functions */ -/**********************************************************************/ - -struct gl_program_parameter_list * -_mesa_new_parameter_list(void) -{ - return (struct gl_program_parameter_list *) - _mesa_calloc(sizeof(struct gl_program_parameter_list)); -} - - /** - * Free a parameter list and all its parameters + * Return a copy of a program. + * XXX Problem here if the program object is actually OO-derivation + * made by a device driver. */ -void -_mesa_free_parameter_list(struct gl_program_parameter_list *paramList) -{ - GLuint i; - for (i = 0; i < paramList->NumParameters; i++) { - if (paramList->Parameters[i].Name) - _mesa_free((void *) paramList->Parameters[i].Name); - } - _mesa_free(paramList->Parameters); - if (paramList->ParameterValues) - _mesa_align_free(paramList->ParameterValues); - _mesa_free(paramList); -} - - -/** - * Add a new parameter to a parameter list. - * \param paramList the list to add the parameter to - * \param name the parameter name, will be duplicated/copied! - * \param values initial parameter value, 4 GLfloats - * \param type type of parameter, such as - * \return index of new parameter in the list, or -1 if error (out of mem) - */ -static GLint -add_parameter(struct gl_program_parameter_list *paramList, - const char *name, const GLfloat values[4], - enum register_file type) -{ - const GLuint n = paramList->NumParameters; - - if (n == paramList->Size) { - /* Need to grow the parameter list array */ - if (paramList->Size == 0) - paramList->Size = 8; - else - paramList->Size *= 2; - - /* realloc arrays */ - paramList->Parameters = (struct gl_program_parameter *) - _mesa_realloc(paramList->Parameters, - n * sizeof(struct gl_program_parameter), - paramList->Size * sizeof(struct gl_program_parameter)); - - paramList->ParameterValues = (GLfloat (*)[4]) - _mesa_align_realloc(paramList->ParameterValues, /* old buf */ - n * 4 * sizeof(GLfloat), /* old size */ - paramList->Size * 4 *sizeof(GLfloat), /* new sz */ - 16); - } - - if (!paramList->Parameters || - !paramList->ParameterValues) { - /* out of memory */ - paramList->NumParameters = 0; - paramList->Size = 0; - return -1; - } - else { - paramList->NumParameters = n + 1; - - _mesa_memset(¶mList->Parameters[n], 0, - sizeof(struct gl_program_parameter)); - - paramList->Parameters[n].Name = name ? _mesa_strdup(name) : NULL; - paramList->Parameters[n].Type = type; - if (values) - COPY_4V(paramList->ParameterValues[n], values); - return (GLint) n; - } -} - - -/** - * Add a new named program parameter (Ex: NV_fragment_program DEFINE statement) - * \return index of the new entry in the parameter list - */ -GLint -_mesa_add_named_parameter(struct gl_program_parameter_list *paramList, - const char *name, const GLfloat values[4]) -{ - return add_parameter(paramList, name, values, PROGRAM_NAMED_PARAM); -} - - -/** - * Add a new named constant to the parameter list. - * This will be used when the program contains something like this: - * PARAM myVals = { 0, 1, 2, 3 }; - * - * \param paramList the parameter list - * \param name the name for the constant - * \param values four float values - * \return index/position of the new parameter in the parameter list - */ -GLint -_mesa_add_named_constant(struct gl_program_parameter_list *paramList, - const char *name, const GLfloat values[4], - GLuint size) -{ -#if 0 /* disable this for now -- we need to save the name! */ - GLuint pos, swizzle; - ASSERT(size == 4); /* XXX future feature */ - /* check if we already have this constant */ - if (_mesa_lookup_parameter_constant(paramList, values, 4, &pos, &swizzle)) { - return pos; - } -#endif - return add_parameter(paramList, name, values, PROGRAM_CONSTANT); -} - - -/** - * Add a new unnamed constant to the parameter list. - * This will be used when the program contains something like this: - * MOV r, { 0, 1, 2, 3 }; - * - * \param paramList the parameter list - * \param values four float values - * \return index/position of the new parameter in the parameter list. - */ -GLint -_mesa_add_unnamed_constant(struct gl_program_parameter_list *paramList, - const GLfloat values[4], GLuint size) -{ - GLuint pos, swizzle; - ASSERT(size == 4); /* XXX future feature */ - /* check if we already have this constant */ - if (_mesa_lookup_parameter_constant(paramList, values, 4, &pos, &swizzle)) { - return pos; - } - return add_parameter(paramList, NULL, values, PROGRAM_CONSTANT); -} - - -/** - * Add a new state reference to the parameter list. - * This will be used when the program contains something like this: - * PARAM ambient = state.material.front.ambient; - * - * \param paramList the parameter list - * \param state an array of 6 state tokens - * \return index of the new parameter. - */ -GLint -_mesa_add_state_reference(struct gl_program_parameter_list *paramList, - const GLint *stateTokens) -{ - /* XXX we should probably search the current parameter list to see if - * the new state reference is already present. - */ - GLint index; - const char *name = make_state_string(stateTokens); - - index = add_parameter(paramList, name, NULL, PROGRAM_STATE_VAR); - if (index >= 0) { - GLuint i; - for (i = 0; i < 6; i++) { - paramList->Parameters[index].StateIndexes[i] - = (enum state_index) stateTokens[i]; - } - paramList->StateFlags |= make_state_flags(stateTokens); - } - - /* free name string here since we duplicated it in add_parameter() */ - _mesa_free((void *) name); - - return index; -} - - -/** - * Lookup a parameter value by name in the given parameter list. - * \return pointer to the float[4] values. - */ -GLfloat * -_mesa_lookup_parameter_value(const struct gl_program_parameter_list *paramList, - GLsizei nameLen, const char *name) +struct gl_program * +_mesa_clone_program(GLcontext *ctx, const struct gl_program *prog) { - GLuint i; + struct gl_program *clone; - if (!paramList) + clone = _mesa_new_program(ctx, prog->Target, prog->Id); + if (!clone) return NULL; - if (nameLen == -1) { - /* name is null-terminated */ - for (i = 0; i < paramList->NumParameters; i++) { - if (paramList->Parameters[i].Name && - _mesa_strcmp(paramList->Parameters[i].Name, name) == 0) - return paramList->ParameterValues[i]; - } - } - else { - /* name is not null-terminated, use nameLen */ - for (i = 0; i < paramList->NumParameters; i++) { - if (paramList->Parameters[i].Name && - _mesa_strncmp(paramList->Parameters[i].Name, name, nameLen) == 0 - && _mesa_strlen(paramList->Parameters[i].Name) == (size_t)nameLen) - return paramList->ParameterValues[i]; - } - } - return NULL; -} - - -/** - * Given a program parameter name, find its position in the list of parameters. - * \param paramList the parameter list to search - * \param nameLen length of name (in chars). - * If length is negative, assume that name is null-terminated. - * \param name the name to search for - * \return index of parameter in the list. - */ -GLint -_mesa_lookup_parameter_index(const struct gl_program_parameter_list *paramList, - GLsizei nameLen, const char *name) -{ - GLint i; - - if (!paramList) - return -1; - - if (nameLen == -1) { - /* name is null-terminated */ - for (i = 0; i < (GLint) paramList->NumParameters; i++) { - if (paramList->Parameters[i].Name && - _mesa_strcmp(paramList->Parameters[i].Name, name) == 0) - return i; - } - } - else { - /* name is not null-terminated, use nameLen */ - for (i = 0; i < (GLint) paramList->NumParameters; i++) { - if (paramList->Parameters[i].Name && - _mesa_strncmp(paramList->Parameters[i].Name, name, nameLen) == 0 - && _mesa_strlen(paramList->Parameters[i].Name) == (size_t)nameLen) - return i; - } - } - return -1; -} - - -/** - * Look for a float vector in the given parameter list. The float vector - * may be of length 1, 2, 3 or 4. - * \param paramList the parameter list to search - * \param v the float vector to search for - * \param size number of element in v - * \param posOut returns the position of the constant, if found - * \param swizzleOut returns a swizzle mask describing location of the - * vector elements if found - * \return GL_TRUE if found, GL_FALSE if not found - */ -GLboolean -_mesa_lookup_parameter_constant(const struct gl_program_parameter_list *paramList, - const GLfloat v[], GLsizei vSize, - GLuint *posOut, GLuint *swizzleOut) -{ - GLuint i; - - assert(vSize >= 1); - assert(vSize <= 4); - - if (!paramList) - return -1; - - for (i = 0; i < paramList->NumParameters; i++) { - if (paramList->Parameters[i].Type == PROGRAM_CONSTANT) { - const GLint maxShift = 4 - vSize; - GLint shift, j; - for (shift = 0; shift <= maxShift; shift++) { - GLint matched = 0; - GLuint swizzle[4]; - swizzle[0] = swizzle[1] = swizzle[2] = swizzle[3] = 0; - /* XXX we could do out-of-order swizzle matches too, someday */ - for (j = 0; j < vSize; j++) { - assert(shift + j < 4); - if (paramList->ParameterValues[i][shift + j] == v[j]) { - matched++; - swizzle[j] = shift + j; - } - } - if (matched == vSize) { - /* found! */ - *posOut = i; - *swizzleOut = MAKE_SWIZZLE4(swizzle[0], swizzle[1], - swizzle[2], swizzle[3]); - return GL_TRUE; - } - } - } + assert(clone->Target == prog->Target); + clone->String = (GLubyte *) _mesa_strdup((char *) prog->String); + clone->RefCount = 1; + clone->Format = prog->Format; + clone->Instructions = _mesa_alloc_instructions(prog->NumInstructions); + if (!clone->Instructions) { + _mesa_delete_program(ctx, clone); + return NULL; } - - return GL_FALSE; -} - - -/** - * Use the list of tokens in the state[] array to find global GL state - * and return it in <value>. Usually, four values are returned in <value> - * but matrix queries may return as many as 16 values. - * This function is used for ARB vertex/fragment programs. - * The program parser will produce the state[] values. - */ -static void -_mesa_fetch_state(GLcontext *ctx, const enum state_index state[], - GLfloat *value) -{ - switch (state[0]) { - case STATE_MATERIAL: + _mesa_copy_instructions(clone->Instructions, prog->Instructions, + prog->NumInstructions); + clone->InputsRead = prog->InputsRead; + clone->OutputsWritten = prog->OutputsWritten; + memcpy(clone->TexturesUsed, prog->TexturesUsed, sizeof(prog->TexturesUsed)); + + if (prog->Parameters) + clone->Parameters = _mesa_clone_parameter_list(prog->Parameters); + memcpy(clone->LocalParams, prog->LocalParams, sizeof(clone->LocalParams)); + if (prog->Varying) + clone->Varying = _mesa_clone_parameter_list(prog->Varying); + if (prog->Attributes) + clone->Attributes = _mesa_clone_parameter_list(prog->Attributes); + memcpy(clone->LocalParams, prog->LocalParams, sizeof(clone->LocalParams)); + clone->NumInstructions = prog->NumInstructions; + clone->NumTemporaries = prog->NumTemporaries; + clone->NumParameters = prog->NumParameters; + clone->NumAttributes = prog->NumAttributes; + clone->NumAddressRegs = prog->NumAddressRegs; + clone->NumNativeInstructions = prog->NumNativeInstructions; + clone->NumNativeTemporaries = prog->NumNativeTemporaries; + clone->NumNativeParameters = prog->NumNativeParameters; + clone->NumNativeAttributes = prog->NumNativeAttributes; + clone->NumNativeAddressRegs = prog->NumNativeAddressRegs; + clone->NumAluInstructions = prog->NumAluInstructions; + clone->NumTexInstructions = prog->NumTexInstructions; + clone->NumTexIndirections = prog->NumTexIndirections; + clone->NumNativeAluInstructions = prog->NumNativeAluInstructions; + clone->NumNativeTexInstructions = prog->NumNativeTexInstructions; + clone->NumNativeTexIndirections = prog->NumNativeTexIndirections; + + switch (prog->Target) { + case GL_VERTEX_PROGRAM_ARB: { - /* state[1] is either 0=front or 1=back side */ - const GLuint face = (GLuint) state[1]; - const struct gl_material *mat = &ctx->Light.Material; - ASSERT(face == 0 || face == 1); - /* we rely on tokens numbered so that _BACK_ == _FRONT_+ 1 */ - ASSERT(MAT_ATTRIB_FRONT_AMBIENT + 1 == MAT_ATTRIB_BACK_AMBIENT); - /* XXX we could get rid of this switch entirely with a little - * work in arbprogparse.c's parse_state_single_item(). - */ - /* state[2] is the material attribute */ - switch (state[2]) { - case STATE_AMBIENT: - COPY_4V(value, mat->Attrib[MAT_ATTRIB_FRONT_AMBIENT + face]); - return; - case STATE_DIFFUSE: - COPY_4V(value, mat->Attrib[MAT_ATTRIB_FRONT_DIFFUSE + face]); - return; - case STATE_SPECULAR: - COPY_4V(value, mat->Attrib[MAT_ATTRIB_FRONT_SPECULAR + face]); - return; - case STATE_EMISSION: - COPY_4V(value, mat->Attrib[MAT_ATTRIB_FRONT_EMISSION + face]); - return; - case STATE_SHININESS: - value[0] = mat->Attrib[MAT_ATTRIB_FRONT_SHININESS + face][0]; - value[1] = 0.0F; - value[2] = 0.0F; - value[3] = 1.0F; - return; - default: - _mesa_problem(ctx, "Invalid material state in fetch_state"); - return; - } + const struct gl_vertex_program *vp + = (const struct gl_vertex_program *) prog; + struct gl_vertex_program *vpc = (struct gl_vertex_program *) clone; + vpc->IsPositionInvariant = vp->IsPositionInvariant; } - case STATE_LIGHT: - { - /* state[1] is the light number */ - const GLuint ln = (GLuint) state[1]; - /* state[2] is the light attribute */ - switch (state[2]) { - case STATE_AMBIENT: - COPY_4V(value, ctx->Light.Light[ln].Ambient); - return; - case STATE_DIFFUSE: - COPY_4V(value, ctx->Light.Light[ln].Diffuse); - return; - case STATE_SPECULAR: - COPY_4V(value, ctx->Light.Light[ln].Specular); - return; - case STATE_POSITION: - COPY_4V(value, ctx->Light.Light[ln].EyePosition); - return; - case STATE_ATTENUATION: - value[0] = ctx->Light.Light[ln].ConstantAttenuation; - value[1] = ctx->Light.Light[ln].LinearAttenuation; - value[2] = ctx->Light.Light[ln].QuadraticAttenuation; - value[3] = ctx->Light.Light[ln].SpotExponent; - return; - case STATE_SPOT_DIRECTION: - COPY_3V(value, ctx->Light.Light[ln].EyeDirection); - value[3] = ctx->Light.Light[ln]._CosCutoff; - return; - case STATE_HALF: - { - GLfloat eye_z[] = {0, 0, 1}; - - /* Compute infinite half angle vector: - * half-vector = light_position + (0, 0, 1) - * and then normalize. w = 0 - * - * light.EyePosition.w should be 0 for infinite lights. - */ - ADD_3V(value, eye_z, ctx->Light.Light[ln].EyePosition); - NORMALIZE_3FV(value); - value[3] = 0; - } - return; - case STATE_POSITION_NORMALIZED: - COPY_4V(value, ctx->Light.Light[ln].EyePosition); - NORMALIZE_3FV( value ); - return; - default: - _mesa_problem(ctx, "Invalid light state in fetch_state"); - return; - } - } - case STATE_LIGHTMODEL_AMBIENT: - COPY_4V(value, ctx->Light.Model.Ambient); - return; - case STATE_LIGHTMODEL_SCENECOLOR: - if (state[1] == 0) { - /* front */ - GLint i; - for (i = 0; i < 3; i++) { - value[i] = ctx->Light.Model.Ambient[i] - * ctx->Light.Material.Attrib[MAT_ATTRIB_FRONT_AMBIENT][i] - + ctx->Light.Material.Attrib[MAT_ATTRIB_FRONT_EMISSION][i]; - } - value[3] = ctx->Light.Material.Attrib[MAT_ATTRIB_FRONT_DIFFUSE][3]; - } - else { - /* back */ - GLint i; - for (i = 0; i < 3; i++) { - value[i] = ctx->Light.Model.Ambient[i] - * ctx->Light.Material.Attrib[MAT_ATTRIB_BACK_AMBIENT][i] - + ctx->Light.Material.Attrib[MAT_ATTRIB_BACK_EMISSION][i]; - } - value[3] = ctx->Light.Material.Attrib[MAT_ATTRIB_BACK_DIFFUSE][3]; - } - return; - case STATE_LIGHTPROD: - { - const GLuint ln = (GLuint) state[1]; - const GLuint face = (GLuint) state[2]; - GLint i; - ASSERT(face == 0 || face == 1); - switch (state[3]) { - case STATE_AMBIENT: - for (i = 0; i < 3; i++) { - value[i] = ctx->Light.Light[ln].Ambient[i] * - ctx->Light.Material.Attrib[MAT_ATTRIB_FRONT_AMBIENT+face][i]; - } - /* [3] = material alpha */ - value[3] = ctx->Light.Material.Attrib[MAT_ATTRIB_FRONT_DIFFUSE+face][3]; - return; - case STATE_DIFFUSE: - for (i = 0; i < 3; i++) { - value[i] = ctx->Light.Light[ln].Diffuse[i] * - ctx->Light.Material.Attrib[MAT_ATTRIB_FRONT_DIFFUSE+face][i]; - } - /* [3] = material alpha */ - value[3] = ctx->Light.Material.Attrib[MAT_ATTRIB_FRONT_DIFFUSE+face][3]; - return; - case STATE_SPECULAR: - for (i = 0; i < 3; i++) { - value[i] = ctx->Light.Light[ln].Specular[i] * - ctx->Light.Material.Attrib[MAT_ATTRIB_FRONT_SPECULAR+face][i]; - } - /* [3] = material alpha */ - value[3] = ctx->Light.Material.Attrib[MAT_ATTRIB_FRONT_DIFFUSE+face][3]; - return; - default: - _mesa_problem(ctx, "Invalid lightprod state in fetch_state"); - return; - } - } - case STATE_TEXGEN: - { - /* state[1] is the texture unit */ - const GLuint unit = (GLuint) state[1]; - /* state[2] is the texgen attribute */ - switch (state[2]) { - case STATE_TEXGEN_EYE_S: - COPY_4V(value, ctx->Texture.Unit[unit].EyePlaneS); - return; - case STATE_TEXGEN_EYE_T: - COPY_4V(value, ctx->Texture.Unit[unit].EyePlaneT); - return; - case STATE_TEXGEN_EYE_R: - COPY_4V(value, ctx->Texture.Unit[unit].EyePlaneR); - return; - case STATE_TEXGEN_EYE_Q: - COPY_4V(value, ctx->Texture.Unit[unit].EyePlaneQ); - return; - case STATE_TEXGEN_OBJECT_S: - COPY_4V(value, ctx->Texture.Unit[unit].ObjectPlaneS); - return; - case STATE_TEXGEN_OBJECT_T: - COPY_4V(value, ctx->Texture.Unit[unit].ObjectPlaneT); - return; - case STATE_TEXGEN_OBJECT_R: - COPY_4V(value, ctx->Texture.Unit[unit].ObjectPlaneR); - return; - case STATE_TEXGEN_OBJECT_Q: - COPY_4V(value, ctx->Texture.Unit[unit].ObjectPlaneQ); - return; - default: - _mesa_problem(ctx, "Invalid texgen state in fetch_state"); - return; - } - } - case STATE_TEXENV_COLOR: - { - /* state[1] is the texture unit */ - const GLuint unit = (GLuint) state[1]; - COPY_4V(value, ctx->Texture.Unit[unit].EnvColor); - } - return; - case STATE_FOG_COLOR: - COPY_4V(value, ctx->Fog.Color); - return; - case STATE_FOG_PARAMS: - value[0] = ctx->Fog.Density; - value[1] = ctx->Fog.Start; - value[2] = ctx->Fog.End; - value[3] = 1.0F / (ctx->Fog.End - ctx->Fog.Start); - return; - case STATE_CLIPPLANE: - { - const GLuint plane = (GLuint) state[1]; - COPY_4V(value, ctx->Transform.EyeUserPlane[plane]); - } - return; - case STATE_POINT_SIZE: - value[0] = ctx->Point.Size; - value[1] = ctx->Point.MinSize; - value[2] = ctx->Point.MaxSize; - value[3] = ctx->Point.Threshold; - return; - case STATE_POINT_ATTENUATION: - value[0] = ctx->Point.Params[0]; - value[1] = ctx->Point.Params[1]; - value[2] = ctx->Point.Params[2]; - value[3] = 1.0F; - return; - case STATE_MATRIX: - { - /* state[1] = modelview, projection, texture, etc. */ - /* state[2] = which texture matrix or program matrix */ - /* state[3] = first column to fetch */ - /* state[4] = last column to fetch */ - /* state[5] = transpose, inverse or invtrans */ - - const GLmatrix *matrix; - const enum state_index mat = state[1]; - const GLuint index = (GLuint) state[2]; - const GLuint first = (GLuint) state[3]; - const GLuint last = (GLuint) state[4]; - const enum state_index modifier = state[5]; - const GLfloat *m; - GLuint row, i; - if (mat == STATE_MODELVIEW) { - matrix = ctx->ModelviewMatrixStack.Top; - } - else if (mat == STATE_PROJECTION) { - matrix = ctx->ProjectionMatrixStack.Top; - } - else if (mat == STATE_MVP) { - matrix = &ctx->_ModelProjectMatrix; - } - else if (mat == STATE_TEXTURE) { - matrix = ctx->TextureMatrixStack[index].Top; - } - else if (mat == STATE_PROGRAM) { - matrix = ctx->ProgramMatrixStack[index].Top; - } - else { - _mesa_problem(ctx, "Bad matrix name in _mesa_fetch_state()"); - return; - } - if (modifier == STATE_MATRIX_INVERSE || - modifier == STATE_MATRIX_INVTRANS) { - /* Be sure inverse is up to date: - */ - _math_matrix_alloc_inv( (GLmatrix *) matrix ); - _math_matrix_analyse( (GLmatrix*) matrix ); - m = matrix->inv; - } - else { - m = matrix->m; - } - if (modifier == STATE_MATRIX_TRANSPOSE || - modifier == STATE_MATRIX_INVTRANS) { - for (i = 0, row = first; row <= last; row++) { - value[i++] = m[row * 4 + 0]; - value[i++] = m[row * 4 + 1]; - value[i++] = m[row * 4 + 2]; - value[i++] = m[row * 4 + 3]; - } - } - else { - for (i = 0, row = first; row <= last; row++) { - value[i++] = m[row + 0]; - value[i++] = m[row + 4]; - value[i++] = m[row + 8]; - value[i++] = m[row + 12]; - } - } - } - return; - case STATE_DEPTH_RANGE: - value[0] = ctx->Viewport.Near; /* near */ - value[1] = ctx->Viewport.Far; /* far */ - value[2] = ctx->Viewport.Far - ctx->Viewport.Near; /* far - near */ - value[3] = 0; - return; - case STATE_FRAGMENT_PROGRAM: - { - /* state[1] = {STATE_ENV, STATE_LOCAL} */ - /* state[2] = parameter index */ - const int idx = (int) state[2]; - switch (state[1]) { - case STATE_ENV: - COPY_4V(value, ctx->FragmentProgram.Parameters[idx]); - break; - case STATE_LOCAL: - COPY_4V(value, ctx->FragmentProgram.Current->Base.LocalParams[idx]); - break; - default: - _mesa_problem(ctx, "Bad state switch in _mesa_fetch_state()"); - return; - } - } - return; - - case STATE_VERTEX_PROGRAM: - { - /* state[1] = {STATE_ENV, STATE_LOCAL} */ - /* state[2] = parameter index */ - const int idx = (int) state[2]; - switch (state[1]) { - case STATE_ENV: - COPY_4V(value, ctx->VertexProgram.Parameters[idx]); - break; - case STATE_LOCAL: - COPY_4V(value, ctx->VertexProgram.Current->Base.LocalParams[idx]); - break; - default: - _mesa_problem(ctx, "Bad state switch in _mesa_fetch_state()"); - return; - } - } - return; - - case STATE_INTERNAL: - { - switch (state[1]) { - case STATE_NORMAL_SCALE: - ASSIGN_4V(value, ctx->_ModelViewInvScale, 0, 0, 1); - break; - case STATE_TEXRECT_SCALE: { - const int unit = (int) state[2]; - const struct gl_texture_object *texObj = ctx->Texture.Unit[unit]._Current; - if (texObj) { - struct gl_texture_image *texImage = texObj->Image[0][0]; - ASSIGN_4V(value, 1.0 / texImage->Width, 1.0 / texImage->Height, 0, 1); - } - break; - } - case STATE_FOG_PARAMS_OPTIMIZED: - /* for simpler per-vertex/pixel fog calcs. POW - (for EXP/EXP2 fog) might be more expensive than EX2 on some hw, - plus it needs another constant (e) anyway. Linear fog can now be - done with a single MAD. - linear: fogcoord * -1/(end-start) + end/(end-start) - exp: 2^-(density/ln(2) * fogcoord) - exp2: 2^-((density/(ln(2)^2) * fogcoord)^2) */ - value[0] = -1.0F / (ctx->Fog.End - ctx->Fog.Start); - value[1] = ctx->Fog.End / (ctx->Fog.End - ctx->Fog.Start); - value[2] = ctx->Fog.Density * ONE_DIV_LN2; - value[3] = ctx->Fog.Density * ONE_DIV_SQRT_LN2; - break; - case STATE_SPOT_DIR_NORMALIZED: { - /* here, state[2] is the light number */ - /* pre-normalize spot dir */ - const GLuint ln = (GLuint) state[2]; - value[0] = ctx->Light.Light[ln].EyeDirection[0]; - value[1] = ctx->Light.Light[ln].EyeDirection[1]; - value[2] = ctx->Light.Light[ln].EyeDirection[2]; - NORMALIZE_3FV(value); - value[3] = ctx->Light.Light[ln]._CosCutoff; - break; - } - default: - /* unknown state indexes are silently ignored - * should be handled by the driver. - */ - return; - } - } - return; - - default: - _mesa_problem(ctx, "Invalid state in _mesa_fetch_state"); - return; - } -} - - -/** - * Return a bitmask of the Mesa state flags (_NEW_* values) which would - * indicate that the given context state may have changed. - * The bitmask is used during validation to determine if we need to update - * vertex/fragment program parameters (like "state.material.color") when - * some GL state has changed. - */ -static GLbitfield -make_state_flags(const GLint state[]) -{ - switch (state[0]) { - case STATE_MATERIAL: - case STATE_LIGHT: - case STATE_LIGHTMODEL_AMBIENT: - case STATE_LIGHTMODEL_SCENECOLOR: - case STATE_LIGHTPROD: - return _NEW_LIGHT; - - case STATE_TEXGEN: - case STATE_TEXENV_COLOR: - return _NEW_TEXTURE; - - case STATE_FOG_COLOR: - case STATE_FOG_PARAMS: - return _NEW_FOG; - - case STATE_CLIPPLANE: - return _NEW_TRANSFORM; - - case STATE_POINT_SIZE: - case STATE_POINT_ATTENUATION: - return _NEW_POINT; - - case STATE_MATRIX: - switch (state[1]) { - case STATE_MODELVIEW: - return _NEW_MODELVIEW; - case STATE_PROJECTION: - return _NEW_PROJECTION; - case STATE_MVP: - return _NEW_MODELVIEW | _NEW_PROJECTION; - case STATE_TEXTURE: - return _NEW_TEXTURE_MATRIX; - case STATE_PROGRAM: - return _NEW_TRACK_MATRIX; - default: - _mesa_problem(NULL, "unexpected matrix in make_state_flags()"); - return 0; - } - - case STATE_DEPTH_RANGE: - return _NEW_VIEWPORT; - - case STATE_FRAGMENT_PROGRAM: - case STATE_VERTEX_PROGRAM: - return _NEW_PROGRAM; - - case STATE_INTERNAL: - switch (state[1]) { - case STATE_NORMAL_SCALE: - return _NEW_MODELVIEW; - case STATE_TEXRECT_SCALE: - return _NEW_TEXTURE; - case STATE_FOG_PARAMS_OPTIMIZED: - return _NEW_FOG; - case STATE_SPOT_DIR_NORMALIZED: - return _NEW_LIGHT; - default: - /* unknown state indexes are silently ignored and - * no flag set, since it is handled by the driver. - */ - return 0; - } - - default: - _mesa_problem(NULL, "unexpected state[0] in make_state_flags()"); - return 0; - } -} - - -static void -append(char *dst, const char *src) -{ - while (*dst) - dst++; - while (*src) - *dst++ = *src++; - *dst = 0; -} - - -static void -append_token(char *dst, enum state_index k) -{ - switch (k) { - case STATE_MATERIAL: - append(dst, "material."); - break; - case STATE_LIGHT: - append(dst, "light"); - break; - case STATE_LIGHTMODEL_AMBIENT: - append(dst, "lightmodel.ambient"); - break; - case STATE_LIGHTMODEL_SCENECOLOR: - break; - case STATE_LIGHTPROD: - append(dst, "lightprod"); - break; - case STATE_TEXGEN: - append(dst, "texgen"); - break; - case STATE_FOG_COLOR: - append(dst, "fog.color"); - break; - case STATE_FOG_PARAMS: - append(dst, "fog.params"); - break; - case STATE_CLIPPLANE: - append(dst, "clip"); - break; - case STATE_POINT_SIZE: - append(dst, "point.size"); - break; - case STATE_POINT_ATTENUATION: - append(dst, "point.attenuation"); - break; - case STATE_MATRIX: - append(dst, "matrix."); - break; - case STATE_MODELVIEW: - append(dst, "modelview"); - break; - case STATE_PROJECTION: - append(dst, "projection"); - break; - case STATE_MVP: - append(dst, "mvp"); - break; - case STATE_TEXTURE: - append(dst, "texture"); - break; - case STATE_PROGRAM: - append(dst, "program"); - break; - case STATE_MATRIX_INVERSE: - append(dst, ".inverse"); - break; - case STATE_MATRIX_TRANSPOSE: - append(dst, ".transpose"); - break; - case STATE_MATRIX_INVTRANS: - append(dst, ".invtrans"); - break; - case STATE_AMBIENT: - append(dst, "ambient"); - break; - case STATE_DIFFUSE: - append(dst, "diffuse"); - break; - case STATE_SPECULAR: - append(dst, "specular"); - break; - case STATE_EMISSION: - append(dst, "emission"); - break; - case STATE_SHININESS: - append(dst, "shininess"); - break; - case STATE_HALF: - append(dst, "half"); - break; - case STATE_POSITION: - append(dst, ".position"); - break; - case STATE_ATTENUATION: - append(dst, ".attenuation"); - break; - case STATE_SPOT_DIRECTION: - append(dst, ".spot.direction"); - break; - case STATE_TEXGEN_EYE_S: - append(dst, "eye.s"); - break; - case STATE_TEXGEN_EYE_T: - append(dst, "eye.t"); - break; - case STATE_TEXGEN_EYE_R: - append(dst, "eye.r"); - break; - case STATE_TEXGEN_EYE_Q: - append(dst, "eye.q"); - break; - case STATE_TEXGEN_OBJECT_S: - append(dst, "object.s"); - break; - case STATE_TEXGEN_OBJECT_T: - append(dst, "object.t"); - break; - case STATE_TEXGEN_OBJECT_R: - append(dst, "object.r"); - break; - case STATE_TEXGEN_OBJECT_Q: - append(dst, "object.q"); - break; - case STATE_TEXENV_COLOR: - append(dst, "texenv"); - break; - case STATE_DEPTH_RANGE: - append(dst, "depth.range"); - break; - case STATE_VERTEX_PROGRAM: - case STATE_FRAGMENT_PROGRAM: - break; - case STATE_ENV: - append(dst, "env"); break; - case STATE_LOCAL: - append(dst, "local"); - break; - case STATE_INTERNAL: - case STATE_NORMAL_SCALE: - case STATE_POSITION_NORMALIZED: - case STATE_FOG_PARAMS_OPTIMIZED: - case STATE_SPOT_DIR_NORMALIZED: - append(dst, "(internal)"); - break; - default: - ; - } -} - -static void -append_face(char *dst, GLint face) -{ - if (face == 0) - append(dst, "front."); - else - append(dst, "back."); -} - -static void -append_index(char *dst, GLint index) -{ - char s[20]; - _mesa_sprintf(s, "[%d].", index); - append(dst, s); -} - -/** - * Make a string from the given state vector. - * For example, return "state.matrix.texture[2].inverse". - * Use _mesa_free() to deallocate the string. - */ -static const char * -make_state_string(const GLint state[6]) -{ - char str[1000] = ""; - char tmp[30]; - - append(str, "state."); - append_token(str, (enum state_index) state[0]); - - switch (state[0]) { - case STATE_MATERIAL: - append_face(str, state[1]); - append_token(str, (enum state_index) state[2]); - break; - case STATE_LIGHT: - append(str, "light"); - append_index(str, state[1]); /* light number [i]. */ - append_token(str, (enum state_index) state[2]); /* coefficients */ - break; - case STATE_LIGHTMODEL_AMBIENT: - append(str, "lightmodel.ambient"); - break; - case STATE_LIGHTMODEL_SCENECOLOR: - if (state[1] == 0) { - append(str, "lightmodel.front.scenecolor"); - } - else { - append(str, "lightmodel.back.scenecolor"); - } - break; - case STATE_LIGHTPROD: - append_index(str, state[1]); /* light number [i]. */ - append_face(str, state[2]); - append_token(str, (enum state_index) state[3]); - break; - case STATE_TEXGEN: - append_index(str, state[1]); /* tex unit [i] */ - append_token(str, (enum state_index) state[2]); /* plane coef */ - break; - case STATE_TEXENV_COLOR: - append_index(str, state[1]); /* tex unit [i] */ - append(str, "color"); - break; - case STATE_FOG_COLOR: - case STATE_FOG_PARAMS: - break; - case STATE_CLIPPLANE: - append_index(str, state[1]); /* plane [i] */ - append(str, "plane"); - break; - case STATE_POINT_SIZE: - case STATE_POINT_ATTENUATION: - break; - case STATE_MATRIX: + case GL_FRAGMENT_PROGRAM_ARB: { - /* state[1] = modelview, projection, texture, etc. */ - /* state[2] = which texture matrix or program matrix */ - /* state[3] = first column to fetch */ - /* state[4] = last column to fetch */ - /* state[5] = transpose, inverse or invtrans */ - const enum state_index mat = (enum state_index) state[1]; - const GLuint index = (GLuint) state[2]; - const GLuint first = (GLuint) state[3]; - const GLuint last = (GLuint) state[4]; - const enum state_index modifier = (enum state_index) state[5]; - append_token(str, mat); - if (index) - append_index(str, index); - if (modifier) - append_token(str, modifier); - if (first == last) - _mesa_sprintf(tmp, ".row[%d]", first); - else - _mesa_sprintf(tmp, ".row[%d..%d]", first, last); - append(str, tmp); - } - break; - case STATE_DEPTH_RANGE: - break; - case STATE_FRAGMENT_PROGRAM: - case STATE_VERTEX_PROGRAM: - /* state[1] = {STATE_ENV, STATE_LOCAL} */ - /* state[2] = parameter index */ - append_token(str, (enum state_index) state[1]); - append_index(str, state[2]); - break; - case STATE_INTERNAL: - break; - default: - _mesa_problem(NULL, "Invalid state in make_state_string"); - break; - } - - return _mesa_strdup(str); -} - - -/** - * Loop over all the parameters in a parameter list. If the parameter - * is a GL state reference, look up the current value of that state - * variable and put it into the parameter's Value[4] array. - * This would be called at glBegin time when using a fragment program. - */ -void -_mesa_load_state_parameters(GLcontext *ctx, - struct gl_program_parameter_list *paramList) -{ - GLuint i; - - if (!paramList) - return; - - for (i = 0; i < paramList->NumParameters; i++) { - if (paramList->Parameters[i].Type == PROGRAM_STATE_VAR) { - _mesa_fetch_state(ctx, - paramList->Parameters[i].StateIndexes, - paramList->ParameterValues[i]); - } - } -} - - -/** - * Initialize program instruction fields to defaults. - * \param inst first instruction to initialize - * \param count number of instructions to initialize - */ -void -_mesa_init_instructions(struct prog_instruction *inst, GLuint count) -{ - GLuint i; - - _mesa_bzero(inst, count * sizeof(struct prog_instruction)); - - for (i = 0; i < count; i++) { - inst[i].SrcReg[0].File = PROGRAM_UNDEFINED; - inst[i].SrcReg[0].Swizzle = SWIZZLE_NOOP; - inst[i].SrcReg[1].File = PROGRAM_UNDEFINED; - inst[i].SrcReg[1].Swizzle = SWIZZLE_NOOP; - inst[i].SrcReg[2].File = PROGRAM_UNDEFINED; - inst[i].SrcReg[2].Swizzle = SWIZZLE_NOOP; - - inst[i].DstReg.File = PROGRAM_UNDEFINED; - inst[i].DstReg.WriteMask = WRITEMASK_XYZW; - inst[i].DstReg.CondMask = COND_TR; - inst[i].DstReg.CondSwizzle = SWIZZLE_NOOP; - - inst[i].SaturateMode = SATURATE_OFF; - inst[i].Precision = FLOAT32; - } -} - - -/** - * Allocate an array of program instructions. - * \param numInst number of instructions - * \return pointer to instruction memory - */ -struct prog_instruction * -_mesa_alloc_instructions(GLuint numInst) -{ - return (struct prog_instruction *) - _mesa_calloc(numInst * sizeof(struct prog_instruction)); -} - - -/** - * Reallocate memory storing an array of program instructions. - * This is used when we need to append additional instructions onto an - * program. - * \param oldInst pointer to first of old/src instructions - * \param numOldInst number of instructions at <oldInst> - * \param numNewInst desired size of new instruction array. - * \return pointer to start of new instruction array. - */ -struct prog_instruction * -_mesa_realloc_instructions(struct prog_instruction *oldInst, - GLuint numOldInst, GLuint numNewInst) -{ - struct prog_instruction *newInst; - - newInst = (struct prog_instruction *) - _mesa_realloc(oldInst, - numOldInst * sizeof(struct prog_instruction), - numNewInst * sizeof(struct prog_instruction)); - - return newInst; -} - -/** - * Copy an array of program instructions. - * \param dest pointer to destination. - * \param src pointer to source. - * \param n number of instructions to copy. - * \return pointer to destination. - */ -struct prog_instruction * -_mesa_copy_instructions (struct prog_instruction *dest, - const struct prog_instruction *src, GLuint n) -{ - return _mesa_memcpy (dest, src, n * sizeof (struct prog_instruction)); -} - - -/** - * Basic info about each instruction - */ -struct instruction_info -{ - enum prog_opcode Opcode; - const char *Name; - GLuint NumSrcRegs; -}; - -/** - * Instruction info - * \note Opcode should equal array index! - */ -static const struct instruction_info InstInfo[MAX_OPCODE] = { - { OPCODE_ABS, "ABS", 1 }, - { OPCODE_ADD, "ADD", 2 }, - { OPCODE_ARA, "ARA", 1 }, - { OPCODE_ARL, "ARL", 1 }, - { OPCODE_ARL_NV, "ARL", 1 }, - { OPCODE_ARR, "ARL", 1 }, - { OPCODE_BRA, "BRA", 1 }, - { OPCODE_CAL, "CAL", 1 }, - { OPCODE_CMP, "CMP", 3 }, - { OPCODE_COS, "COS", 1 }, - { OPCODE_DDX, "DDX", 1 }, - { OPCODE_DDY, "DDY", 1 }, - { OPCODE_DP3, "DP3", 2 }, - { OPCODE_DP4, "DP4", 2 }, - { OPCODE_DPH, "DPH", 2 }, - { OPCODE_DST, "DST", 2 }, - { OPCODE_END, "END", 0 }, - { OPCODE_EX2, "EX2", 1 }, - { OPCODE_EXP, "EXP", 1 }, - { OPCODE_FLR, "FLR", 1 }, - { OPCODE_FRC, "FRC", 1 }, - { OPCODE_KIL, "KIL", 1 }, - { OPCODE_KIL_NV, "KIL", 0 }, - { OPCODE_LG2, "LG2", 1 }, - { OPCODE_LIT, "LIT", 1 }, - { OPCODE_LOG, "LOG", 1 }, - { OPCODE_LRP, "LRP", 3 }, - { OPCODE_MAD, "MAD", 3 }, - { OPCODE_MAX, "MAX", 2 }, - { OPCODE_MIN, "MIN", 2 }, - { OPCODE_MOV, "MOV", 1 }, - { OPCODE_MUL, "MUL", 2 }, - { OPCODE_PK2H, "PK2H", 1 }, - { OPCODE_PK2US, "PK2US", 1 }, - { OPCODE_PK4B, "PK4B", 1 }, - { OPCODE_PK4UB, "PK4UB", 1 }, - { OPCODE_POW, "POW", 2 }, - { OPCODE_POPA, "POPA", 0 }, - { OPCODE_PRINT, "PRINT", 1 }, - { OPCODE_PUSHA, "PUSHA", 0 }, - { OPCODE_RCC, "RCC", 1 }, - { OPCODE_RCP, "RCP", 1 }, - { OPCODE_RET, "RET", 1 }, - { OPCODE_RFL, "RFL", 1 }, - { OPCODE_RSQ, "RSQ", 1 }, - { OPCODE_SCS, "SCS", 1 }, - { OPCODE_SEQ, "SEQ", 2 }, - { OPCODE_SFL, "SFL", 0 }, - { OPCODE_SGE, "SGE", 2 }, - { OPCODE_SGT, "SGT", 2 }, - { OPCODE_SIN, "SIN", 1 }, - { OPCODE_SLE, "SLE", 2 }, - { OPCODE_SLT, "SLT", 2 }, - { OPCODE_SNE, "SNE", 2 }, - { OPCODE_SSG, "SSG", 1 }, - { OPCODE_STR, "STR", 0 }, - { OPCODE_SUB, "SUB", 2 }, - { OPCODE_SWZ, "SWZ", 1 }, - { OPCODE_TEX, "TEX", 1 }, - { OPCODE_TXB, "TXB", 1 }, - { OPCODE_TXD, "TXD", 3 }, - { OPCODE_TXL, "TXL", 1 }, - { OPCODE_TXP, "TXP", 1 }, - { OPCODE_TXP_NV, "TXP", 1 }, - { OPCODE_UP2H, "UP2H", 1 }, - { OPCODE_UP2US, "UP2US", 1 }, - { OPCODE_UP4B, "UP4B", 1 }, - { OPCODE_UP4UB, "UP4UB", 1 }, - { OPCODE_X2D, "X2D", 3 }, - { OPCODE_XPD, "XPD", 2 } -}; - - -/** - * Return the number of src registers for the given instruction/opcode. - */ -GLuint -_mesa_num_inst_src_regs(enum prog_opcode opcode) -{ - ASSERT(opcode == InstInfo[opcode].Opcode); - return InstInfo[opcode].NumSrcRegs; -} - - -/** - * Return string name for given program opcode. - */ -const char * -_mesa_opcode_string(enum prog_opcode opcode) -{ - ASSERT(opcode < MAX_OPCODE); - return InstInfo[opcode].Name; -} - -/** - * Return string name for given program/register file. - */ -static const char * -program_file_string(enum register_file f) -{ - switch (f) { - case PROGRAM_TEMPORARY: - return "TEMP"; - case PROGRAM_LOCAL_PARAM: - return "LOCAL"; - case PROGRAM_ENV_PARAM: - return "ENV"; - case PROGRAM_STATE_VAR: - return "STATE"; - case PROGRAM_INPUT: - return "INPUT"; - case PROGRAM_OUTPUT: - return "OUTPUT"; - case PROGRAM_NAMED_PARAM: - return "NAMED"; - case PROGRAM_CONSTANT: - return "CONST"; - case PROGRAM_WRITE_ONLY: - return "WRITE_ONLY"; - case PROGRAM_ADDRESS: - return "ADDR"; - default: - return "!unkown!"; - } -} - - -/** - * Return a string representation of the given swizzle word. - * If extended is true, use extended (comma-separated) format. - */ -static const char * -swizzle_string(GLuint swizzle, GLuint negateBase, GLboolean extended) -{ - static const char swz[] = "xyzw01"; - static char s[20]; - GLuint i = 0; - - if (!extended && swizzle == SWIZZLE_NOOP && negateBase == 0) - return ""; /* no swizzle/negation */ - - if (!extended) - s[i++] = '.'; - - if (negateBase & 0x1) - s[i++] = '-'; - s[i++] = swz[GET_SWZ(swizzle, 0)]; - - if (extended) { - s[i++] = ','; - } - - if (negateBase & 0x2) - s[i++] = '-'; - s[i++] = swz[GET_SWZ(swizzle, 1)]; - - if (extended) { - s[i++] = ','; - } - - if (negateBase & 0x4) - s[i++] = '-'; - s[i++] = swz[GET_SWZ(swizzle, 2)]; - - if (extended) { - s[i++] = ','; - } - - if (negateBase & 0x8) - s[i++] = '-'; - s[i++] = swz[GET_SWZ(swizzle, 3)]; - - s[i] = 0; - return s; -} - - -static const char * -writemask_string(GLuint writeMask) -{ - static char s[10]; - GLuint i = 0; - - if (writeMask == WRITEMASK_XYZW) - return ""; - - s[i++] = '.'; - if (writeMask & WRITEMASK_X) - s[i++] = 'x'; - if (writeMask & WRITEMASK_Y) - s[i++] = 'y'; - if (writeMask & WRITEMASK_Z) - s[i++] = 'z'; - if (writeMask & WRITEMASK_W) - s[i++] = 'w'; - - s[i] = 0; - return s; -} - -static void -print_dst_reg(const struct prog_dst_register *dstReg) -{ - _mesa_printf(" %s[%d]%s", - program_file_string((enum register_file) dstReg->File), - dstReg->Index, - writemask_string(dstReg->WriteMask)); -} - -static void -print_src_reg(const struct prog_src_register *srcReg) -{ - _mesa_printf("%s[%d]%s", - program_file_string((enum register_file) srcReg->File), - srcReg->Index, - swizzle_string(srcReg->Swizzle, - srcReg->NegateBase, GL_FALSE)); -} - -void -_mesa_print_alu_instruction(const struct prog_instruction *inst, - const char *opcode_string, - GLuint numRegs) -{ - GLuint j; - - _mesa_printf("%s", opcode_string); - - /* frag prog only */ - if (inst->SaturateMode == SATURATE_ZERO_ONE) - _mesa_printf("_SAT"); - - if (inst->DstReg.File != PROGRAM_UNDEFINED) { - _mesa_printf(" %s[%d]%s", - program_file_string((enum register_file) inst->DstReg.File), - inst->DstReg.Index, - writemask_string(inst->DstReg.WriteMask)); - } - - if (numRegs > 0) - _mesa_printf(", "); - - for (j = 0; j < numRegs; j++) { - print_src_reg(inst->SrcReg + j); - if (j + 1 < numRegs) - _mesa_printf(", "); - } - - _mesa_printf(";\n"); -} - - -/** - * Print a single vertex/fragment program instruction. - */ -void -_mesa_print_instruction(const struct prog_instruction *inst) -{ - switch (inst->Opcode) { - case OPCODE_PRINT: - _mesa_printf("PRINT '%s'", inst->Data); - if (inst->SrcReg[0].File != PROGRAM_UNDEFINED) { - _mesa_printf(", "); - _mesa_printf("%s[%d]%s", - program_file_string((enum register_file) inst->SrcReg[0].File), - inst->SrcReg[0].Index, - swizzle_string(inst->SrcReg[0].Swizzle, - inst->SrcReg[0].NegateBase, GL_FALSE)); + const struct gl_fragment_program *fp + = (const struct gl_fragment_program *) prog; + struct gl_fragment_program *fpc = (struct gl_fragment_program *) clone; + fpc->FogOption = fp->FogOption; + fpc->UsesKill = fp->UsesKill; } - _mesa_printf(";\n"); break; - case OPCODE_SWZ: - _mesa_printf("SWZ"); - if (inst->SaturateMode == SATURATE_ZERO_ONE) - _mesa_printf("_SAT"); - print_dst_reg(&inst->DstReg); - _mesa_printf("%s[%d], %s;\n", - program_file_string((enum register_file) inst->SrcReg[0].File), - inst->SrcReg[0].Index, - swizzle_string(inst->SrcReg[0].Swizzle, - inst->SrcReg[0].NegateBase, GL_TRUE)); - break; - case OPCODE_TEX: - case OPCODE_TXP: - case OPCODE_TXB: - _mesa_printf("%s", _mesa_opcode_string(inst->Opcode)); - if (inst->SaturateMode == SATURATE_ZERO_ONE) - _mesa_printf("_SAT"); - _mesa_printf(" "); - print_dst_reg(&inst->DstReg); - _mesa_printf(", "); - print_src_reg(&inst->SrcReg[0]); - _mesa_printf(", texture[%d], ", inst->TexSrcUnit); - switch (inst->TexSrcTarget) { - case TEXTURE_1D_INDEX: _mesa_printf("1D"); break; - case TEXTURE_2D_INDEX: _mesa_printf("2D"); break; - case TEXTURE_3D_INDEX: _mesa_printf("3D"); break; - case TEXTURE_CUBE_INDEX: _mesa_printf("CUBE"); break; - case TEXTURE_RECT_INDEX: _mesa_printf("RECT"); break; - default: - ; - } - _mesa_printf("\n"); - break; - case OPCODE_ARL: - _mesa_printf("ARL addr.x, "); - print_src_reg(&inst->SrcReg[0]); - _mesa_printf(";\n"); - break; - case OPCODE_END: - _mesa_printf("END;\n"); - break; - /* XXX may need for 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)); - break; + _mesa_problem(NULL, "Unexpected target in _mesa_clone_program"); } -} - -/** - * Print a vertx/fragment program to stdout. - * XXX this function could be greatly improved. - */ -void -_mesa_print_program(const struct gl_program *prog) -{ - GLuint i; - for (i = 0; i < prog->NumInstructions; i++) { - _mesa_printf("%3d: ", i); - _mesa_print_instruction(prog->Instructions + i); - } + return clone; } -/** - * Print all of a program's parameters. - */ -void -_mesa_print_program_parameters(GLcontext *ctx, const struct gl_program *prog) -{ - GLuint i; - - _mesa_printf("NumInstructions=%d\n", prog->NumInstructions); - _mesa_printf("NumTemporaries=%d\n", prog->NumTemporaries); - _mesa_printf("NumParameters=%d\n", prog->NumParameters); - _mesa_printf("NumAttributes=%d\n", prog->NumAttributes); - _mesa_printf("NumAddressRegs=%d\n", prog->NumAddressRegs); - - _mesa_load_state_parameters(ctx, prog->Parameters); - -#if 0 - _mesa_printf("Local Params:\n"); - for (i = 0; i < MAX_PROGRAM_LOCAL_PARAMS; i++){ - const GLfloat *p = prog->LocalParams[i]; - _mesa_printf("%2d: %f, %f, %f, %f\n", i, p[0], p[1], p[2], p[3]); - } -#endif - - for (i = 0; i < prog->Parameters->NumParameters; i++){ - struct gl_program_parameter *param = prog->Parameters->Parameters + i; - const GLfloat *v = prog->Parameters->ParameterValues[i]; - _mesa_printf("param[%d] %s = {%.3f, %.3f, %.3f, %.3f};\n", - i, param->Name, v[0], v[1], v[2], v[3]); - } -} - /** * Mixing ARB and NV vertex/fragment programs can be tricky. @@ -1991,14 +512,10 @@ _mesa_BindProgram(GLenum target, GLuint id) /* bind newProg */ if (target == GL_VERTEX_PROGRAM_ARB) { /* == GL_VERTEX_PROGRAM_NV */ - if (ctx->VertexProgram._Current == ctx->VertexProgram.Current) - ctx->VertexProgram._Current = (struct gl_vertex_program *) newProg; ctx->VertexProgram.Current = (struct gl_vertex_program *) newProg; } else if (target == GL_FRAGMENT_PROGRAM_NV || target == GL_FRAGMENT_PROGRAM_ARB) { - if (ctx->FragmentProgram._Current == ctx->FragmentProgram.Current) - ctx->FragmentProgram._Current = (struct gl_fragment_program *) newProg; ctx->FragmentProgram.Current = (struct gl_fragment_program *) newProg; } newProg->RefCount++; @@ -2017,7 +534,7 @@ _mesa_BindProgram(GLenum target, GLuint id) * \note Not compiled into display lists. * \note Called by both glDeleteProgramsNV and glDeleteProgramsARB. */ -void GLAPIENTRY +void GLAPIENTRY _mesa_DeletePrograms(GLsizei n, const GLuint *ids) { GLint i; @@ -2102,233 +619,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 7746289621..52704856ab 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"), @@ -43,44 +43,6 @@ #include "mtypes.h" -/* for GL_ARB_v_p and GL_ARB_f_p SWZ instruction */ -#define SWIZZLE_X 0 -#define SWIZZLE_Y 1 -#define SWIZZLE_Z 2 -#define SWIZZLE_W 3 -#define SWIZZLE_ZERO 4 /* keep these values together: KW */ -#define SWIZZLE_ONE 5 /* keep these values together: KW */ - -#define MAKE_SWIZZLE4(a,b,c,d) (((a)<<0) | ((b)<<3) | ((c)<<6) | ((d)<<9)) -#define SWIZZLE_NOOP MAKE_SWIZZLE4(0,1,2,3) - -#define SWIZZLE_XYZW MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_Y, SWIZZLE_Z, SWIZZLE_W) -#define SWIZZLE_XXXX MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_X, SWIZZLE_X, SWIZZLE_X) -#define SWIZZLE_YYYY MAKE_SWIZZLE4(SWIZZLE_Y, SWIZZLE_Y, SWIZZLE_Y, SWIZZLE_Y) -#define SWIZZLE_ZZZZ MAKE_SWIZZLE4(SWIZZLE_Z, SWIZZLE_Z, SWIZZLE_Z, SWIZZLE_Z) -#define SWIZZLE_WWWW MAKE_SWIZZLE4(SWIZZLE_W, SWIZZLE_W, SWIZZLE_W, SWIZZLE_W) - -#define GET_SWZ(swz, idx) (((swz) >> ((idx)*3)) & 0x7) -#define GET_BIT(msk, idx) (((msk) >> (idx)) & 0x1) - - -#define WRITEMASK_X 0x1 -#define WRITEMASK_Y 0x2 -#define WRITEMASK_XY 0x3 -#define WRITEMASK_Z 0x4 -#define WRITEMASK_XZ 0x5 -#define WRITEMASK_YZ 0x6 -#define WRITEMASK_XYZ 0x7 -#define WRITEMASK_W 0x8 -#define WRITEMASK_XW 0x9 -#define WRITEMASK_YW 0xa -#define WRITEMASK_XYW 0xb -#define WRITEMASK_ZW 0xc -#define WRITEMASK_XZW 0xd -#define WRITEMASK_YZW 0xe -#define WRITEMASK_XYZW 0xf - - extern struct gl_program _mesa_DummyProgram; @@ -121,177 +83,9 @@ _mesa_delete_program(GLcontext *ctx, struct gl_program *prog); extern struct gl_program * _mesa_lookup_program(GLcontext *ctx, GLuint id); -extern struct prog_instruction * -_mesa_alloc_instructions(GLuint numInst); - -extern struct prog_instruction * -_mesa_realloc_instructions(struct prog_instruction *oldInst, - GLuint numOldInst, GLuint numNewInst); - -extern struct prog_instruction * -_mesa_copy_instructions (struct prog_instruction *dest, - const struct prog_instruction *src, GLuint n); - -/** - * Used for describing GL state referenced from inside ARB vertex and - * fragment programs. - * A string such as "state.light[0].ambient" gets translated into a - * sequence of tokens such as [ STATE_LIGHT, 0, STATE_AMBIENT ]. - */ -enum state_index { - STATE_MATERIAL, - - STATE_LIGHT, - STATE_LIGHTMODEL_AMBIENT, - STATE_LIGHTMODEL_SCENECOLOR, - STATE_LIGHTPROD, - - STATE_TEXGEN, - - STATE_FOG_COLOR, - STATE_FOG_PARAMS, - - STATE_CLIPPLANE, - - STATE_POINT_SIZE, - STATE_POINT_ATTENUATION, - STATE_MATRIX, - STATE_MODELVIEW, - STATE_PROJECTION, - STATE_MVP, - STATE_TEXTURE, - STATE_PROGRAM, - STATE_MATRIX_INVERSE, - STATE_MATRIX_TRANSPOSE, - STATE_MATRIX_INVTRANS, - - STATE_AMBIENT, - STATE_DIFFUSE, - STATE_SPECULAR, - STATE_EMISSION, - STATE_SHININESS, - STATE_HALF, - - STATE_POSITION, - STATE_ATTENUATION, - STATE_SPOT_DIRECTION, - - STATE_TEXGEN_EYE_S, - STATE_TEXGEN_EYE_T, - STATE_TEXGEN_EYE_R, - STATE_TEXGEN_EYE_Q, - STATE_TEXGEN_OBJECT_S, - STATE_TEXGEN_OBJECT_T, - STATE_TEXGEN_OBJECT_R, - STATE_TEXGEN_OBJECT_Q, - - STATE_TEXENV_COLOR, - - STATE_DEPTH_RANGE, - - STATE_VERTEX_PROGRAM, - STATE_FRAGMENT_PROGRAM, - - STATE_ENV, - STATE_LOCAL, - - STATE_INTERNAL, /* Mesa additions */ - STATE_NORMAL_SCALE, - STATE_TEXRECT_SCALE, - STATE_POSITION_NORMALIZED, /* normalized light position */ - STATE_FOG_PARAMS_OPTIMIZED, /* for faster fog calc */ - STATE_SPOT_DIR_NORMALIZED, /* pre-normalized spot dir */ - STATE_INTERNAL_DRIVER /* first available state index for drivers (must be last) */ -}; - - - -/** - * Named program parameters - * Used for NV_fragment_program "DEFINE"d constants and "DECLARE"d parameters, - * and ARB_fragment_program global state references. For the later, Name - * might be "state.light[0].diffuse", for example. - */ -struct gl_program_parameter -{ - const char *Name; /**< Null-terminated string */ - enum register_file Type; /**< PROGRAM_NAMED_PARAM, CONSTANT or STATE_VAR */ - enum state_index StateIndexes[6]; /**< Global state reference */ -}; - - -/** - * A list of the above program_parameter instances. - */ -struct gl_program_parameter_list -{ - GLuint Size; /**< allocated size of Parameters, ParameterValues */ - GLuint NumParameters; /**< number of parameters in arrays */ - struct gl_program_parameter *Parameters; /**< Array [Size] */ - GLfloat (*ParameterValues)[4]; /**< Array [Size] of GLfloat[4] */ - GLbitfield StateFlags; /**< _NEW_* flags indicating which state changes - might invalidate ParameterValues[] */ -}; - - -/* - * Program parameter functions - */ - -extern struct gl_program_parameter_list * -_mesa_new_parameter_list(void); - -extern void -_mesa_free_parameter_list(struct gl_program_parameter_list *paramList); - -extern GLint -_mesa_add_named_parameter(struct gl_program_parameter_list *paramList, - const char *name, const GLfloat values[4]); - -extern GLint -_mesa_add_named_constant(struct gl_program_parameter_list *paramList, - const char *name, const GLfloat values[4], - GLuint size); - -extern GLint -_mesa_add_unnamed_constant(struct gl_program_parameter_list *paramList, - const GLfloat values[4], GLuint size); - -extern GLint -_mesa_add_state_reference(struct gl_program_parameter_list *paramList, - const GLint *stateTokens); - -extern GLfloat * -_mesa_lookup_parameter_value(const struct gl_program_parameter_list *paramList, - GLsizei nameLen, const char *name); - -extern GLint -_mesa_lookup_parameter_index(const struct gl_program_parameter_list *paramList, - GLsizei nameLen, const char *name); - -extern GLboolean -_mesa_lookup_parameter_constant(const struct gl_program_parameter_list *paramList, - const GLfloat v[], GLsizei vSize, - GLuint *posOut, GLuint *swizzleOut); - -extern void -_mesa_load_state_parameters(GLcontext *ctx, - struct gl_program_parameter_list *paramList); - -extern void -_mesa_print_instruction(const struct prog_instruction *inst); - -void -_mesa_print_alu_instruction(const struct prog_instruction *inst, - const char *opcode_string, - GLuint numRegs); - -extern void -_mesa_print_program(const struct gl_program *prog); - -extern void -_mesa_print_program_parameters(GLcontext *ctx, const struct gl_program *prog); +extern struct gl_program * +_mesa_clone_program(GLcontext *ctx, const struct gl_program *prog); /* @@ -309,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/program_instruction.h b/src/mesa/shader/program_instruction.h deleted file mode 100644 index ad3a6d4dd4..0000000000 --- a/src/mesa/shader/program_instruction.h +++ /dev/null @@ -1,360 +0,0 @@ -/* - * Mesa 3-D graphics library - * Version: 6.5 - * - * Copyright (C) 1999-2005 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. - */ - - -/** - * \file prog_instruction.h - * - * Private vertex program types and constants only used by files - * related to vertex programs. - * - * \author Brian Paul - * \author Keith Whitwell - * \author Ian Romanick <idr@us.ibm.com> - */ - - -#ifndef PROG_INSTRUCTION_H -#define PROG_INSTRUCTION_H - -/** - * Condition codes for GL_NV_fragment_program - */ -/*@{*/ -#define COND_GT 1 /* greater than zero */ -#define COND_EQ 2 /* equal to zero */ -#define COND_LT 3 /* less than zero */ -#define COND_UN 4 /* unordered (NaN) */ -#define COND_GE 5 /* greater then or equal to zero */ -#define COND_LE 6 /* less then or equal to zero */ -#define COND_NE 7 /* not equal to zero */ -#define COND_TR 8 /* always true */ -#define COND_FL 9 /* always false */ -/*@}*/ - - -/** - * Instruction precision for GL_NV_fragment_program - */ -/*@{*/ -#define FLOAT32 0x1 -#define FLOAT16 0x2 -#define FIXED12 0x4 -/*@}*/ - - -/** - * Saturation modes when storing values. - */ -/*@{*/ -#define SATURATE_OFF 0 -#define SATURATE_ZERO_ONE 1 -#define SATURATE_PLUS_MINUS_ONE 2 -/*@}*/ - - -/** - * Per-component negation masks - */ -/*@{*/ -#define NEGATE_X 0x1 -#define NEGATE_Y 0x2 -#define NEGATE_Z 0x4 -#define NEGATE_W 0x8 -#define NEGATE_XYZW 0xf -#define NEGATE_NONE 0x0 -/*@}*/ - - -/** - * Program instruction opcodes, for both vertex and fragment programs. - * \note changes to this opcode list must be reflected in t_vb_arbprogram.c - */ - /* ARB_vp ARB_fp NV_vp NV_fp */ -enum prog_opcode { /*---------------------------------*/ - OPCODE_ABS, /* X X 1.1 */ - OPCODE_ADD, /* X X X X */ - OPCODE_ARA, /* 2 */ - OPCODE_ARL, /* X X */ - OPCODE_ARL_NV, /* 2 */ - OPCODE_ARR, /* 2 */ - OPCODE_BRA, /* 2 */ - OPCODE_CAL, /* 2 2 */ - OPCODE_CMP, /* X */ - OPCODE_COS, /* X 2 X */ - OPCODE_DDX, /* X */ - OPCODE_DDY, /* X */ - OPCODE_DP3, /* X X X X */ - OPCODE_DP4, /* X X X X */ - OPCODE_DPH, /* X X 1.1 */ - OPCODE_DST, /* X X X X */ - OPCODE_END, /* X X X X */ - OPCODE_EX2, /* X X 2 X */ - OPCODE_EXP, /* X X */ - OPCODE_FLR, /* X X 2 X */ - OPCODE_FRC, /* X X 2 X */ - OPCODE_KIL, /* X */ - OPCODE_KIL_NV, /* X */ - OPCODE_LG2, /* X X 2 X */ - OPCODE_LIT, /* X X X X */ - OPCODE_LOG, /* X X */ - OPCODE_LRP, /* X X */ - OPCODE_MAD, /* X X X X */ - OPCODE_MAX, /* X X X X */ - OPCODE_MIN, /* X X X X */ - OPCODE_MOV, /* X X X X */ - OPCODE_MUL, /* X X X X */ - OPCODE_PK2H, /* X */ - OPCODE_PK2US, /* X */ - OPCODE_PK4B, /* X */ - OPCODE_PK4UB, /* X */ - OPCODE_POW, /* X X X */ - OPCODE_POPA, /* 3 */ - OPCODE_PRINT, /* X X */ - OPCODE_PUSHA, /* 3 */ - OPCODE_RCC, /* 1.1 */ - OPCODE_RCP, /* X X X X */ - OPCODE_RET, /* 2 2 */ - OPCODE_RFL, /* X X */ - OPCODE_RSQ, /* X X X X */ - OPCODE_SCS, /* X */ - OPCODE_SEQ, /* 2 X */ - OPCODE_SFL, /* 2 X */ - OPCODE_SGE, /* X X X X */ - OPCODE_SGT, /* 2 X */ - OPCODE_SIN, /* X 2 X */ - OPCODE_SLE, /* 2 X */ - OPCODE_SLT, /* X X X X */ - OPCODE_SNE, /* 2 X */ - OPCODE_SSG, /* 2 */ - OPCODE_STR, /* 2 X */ - OPCODE_SUB, /* X X 1.1 X */ - OPCODE_SWZ, /* X X */ - OPCODE_TEX, /* X 3 X */ - OPCODE_TXB, /* X 3 */ - OPCODE_TXD, /* X */ - OPCODE_TXL, /* 3 2 */ - OPCODE_TXP, /* X */ - OPCODE_TXP_NV, /* 3 X */ - OPCODE_UP2H, /* X */ - OPCODE_UP2US, /* X */ - OPCODE_UP4B, /* X */ - OPCODE_UP4UB, /* X */ - OPCODE_X2D, /* X */ - OPCODE_XPD, /* X X */ - MAX_OPCODE -}; - - -/** - * Instruction source register. - */ -struct prog_src_register -{ - GLuint File:4; /**< One of the PROGRAM_* register file values. */ - GLint Index:9; /**< May be negative for relative addressing. */ - GLuint Swizzle:12; - GLuint RelAddr:1; - - /** - * \name Source register "sign" control. - * - * The ARB and NV extensions allow varrying degrees of control over the - * sign of the source vector components. These values allow enough control - * for all flavors of the extensions. - */ - /*@{*/ - /** - * Per-component negation for the SWZ instruction. For non-SWZ - * instructions the only possible values are NEGATE_XYZW and NEGATE_NONE. - * - * \since - * ARB_vertex_program, ARB_fragment_program - */ - GLuint NegateBase:4; - - /** - * Take the component-wise absolute value. - * - * \since - * NV_fragment_program, NV_fragment_program_option, NV_vertex_program2, - * NV_vertex_program2_option. - */ - GLuint Abs:1; - - /** - * Post-absolute value negation (all components). - */ - GLuint NegateAbs:1; - /*@}*/ -}; - - -/** - * Instruction destination register. - */ -struct prog_dst_register -{ - /** - * One of the PROGRAM_* register file values. - */ - GLuint File:4; - - GLuint Index:8; - GLuint WriteMask:4; - - /** - * \name Conditional destination update control. - * - * \since - * NV_fragment_program, NV_fragment_program_option, NV_vertex_program2, - * NV_vertex_program2_option. - */ - /*@{*/ - /** - * Takes one of the 9 possible condition values (EQ, FL, GT, GE, LE, LT, - * NE, TR, or UN). Destination update is enabled if the matching - * (swizzled) condition code value passes. When a conditional update mask - * is not specified, this will be \c COND_TR. - */ - GLuint CondMask:4; - - /** - * Condition code swizzle value. - */ - GLuint CondSwizzle:12; - - /** - * Selects the condition code register to use for conditional destination - * update masking. In NV_fragmnet_program or NV_vertex_program2 mode, only - * condition code register 0 is available. In NV_vertex_program3 mode, - * condition code registers 0 and 1 are available. - */ - GLuint CondSrc:1; - /*@}*/ - - GLuint pad:31; -}; - - -/** - * Vertex/fragment program instruction. - */ -struct prog_instruction -{ - enum prog_opcode Opcode; -#if FEATURE_MESA_program_debug - GLshort StringPos; -#endif - /** - * Arbitrary data. Used for the PRINT, CAL, and BRA instructions. - */ - void *Data; - - struct prog_src_register SrcReg[3]; - struct prog_dst_register DstReg; - - /** - * Indicates that the instruction should update the condition code - * register. - * - * \since - * NV_fragment_program, NV_fragment_program_option, NV_vertex_program2, - * NV_vertex_program2_option. - */ - GLuint CondUpdate:1; - - /** - * If prog_instruction::CondUpdate is \c GL_TRUE, this value selects the - * condition code register that is to be updated. - * - * In GL_NV_fragment_program or GL_NV_vertex_program2 mode, only condition - * code register 0 is available. In GL_NV_vertex_program3 mode, condition - * code registers 0 and 1 are available. - * - * \since - * NV_fragment_program, NV_fragment_program_option, NV_vertex_program2, - * NV_vertex_program2_option. - */ - GLuint CondDst:1; - - /** - * Saturate each value of the vectored result to the range [0,1] or the - * range [-1,1]. \c SSAT mode (i.e., saturation to the range [-1,1]) is - * only available in NV_fragment_program2 mode. - * Value is one of the SATURATE_* tokens. - * - * \since - * NV_fragment_program, NV_fragment_program_option, NV_vertex_program3. - */ - GLuint SaturateMode:2; - - /** - * Per-instruction selectable precision. - * - * \since - * NV_fragment_program, NV_fragment_program_option. - */ - GLuint Precision:3; - - /** - * \name Texture source controls. - * - * The texture source controls are only used with the \c TEX, \c TXD, - * \c TXL, and \c TXP instructions. - * - * \since - * ARB_fragment_program, NV_fragment_program, NV_vertex_program3. - */ - /*@{*/ - /** - * Source texture unit. OpenGL supports a maximum of 32 texture - * units. - */ - GLuint TexSrcUnit:5; - - /** - * Source texture target, one of TEXTURE_{1D,2D,3D,CUBE,RECT}_INDEX. - */ - GLuint TexSrcTarget:3; - /*@}*/ - - /** - * For BRA and CAL instructions, the location to jump to. - */ - GLuint BranchTarget; -}; - - -extern void -_mesa_init_instructions(struct prog_instruction *inst, GLuint count); - -extern GLuint -_mesa_num_inst_src_regs(enum prog_opcode opcode); - -extern const char * -_mesa_opcode_string(enum prog_opcode opcode); - - -#endif /* PROG_INSTRUCTION_H */ diff --git a/src/mesa/shader/programopt.c b/src/mesa/shader/programopt.c index fed8e5b758..f1d8ce3065 100644 --- a/src/mesa/shader/programopt.c +++ b/src/mesa/shader/programopt.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"), @@ -33,11 +33,10 @@ #include "glheader.h" #include "context.h" -#include "imports.h" -#include "mtypes.h" -#include "program.h" +#include "prog_parameter.h" +#include "prog_statevars.h" #include "programopt.h" -#include "program_instruction.h" +#include "prog_instruction.h" /** @@ -57,11 +56,11 @@ _mesa_insert_mvp_code(GLcontext *ctx, struct gl_vertex_program *vprog) * Setup state references for the modelview/projection matrix. * XXX we should check if these state vars are already declared. */ - static const GLint mvpState[4][5] = { - { STATE_MATRIX, STATE_MVP, 0, 0, 0 }, /* state.matrix.mvp.row[0] */ - { STATE_MATRIX, STATE_MVP, 0, 1, 1 }, /* state.matrix.mvp.row[1] */ - { STATE_MATRIX, STATE_MVP, 0, 2, 2 }, /* state.matrix.mvp.row[2] */ - { STATE_MATRIX, STATE_MVP, 0, 3, 3 }, /* state.matrix.mvp.row[3] */ + static const gl_state_index mvpState[4][STATE_LENGTH] = { + { STATE_MVP_MATRIX, 0, 0, 0, 0 }, /* state.matrix.mvp.row[0] */ + { STATE_MVP_MATRIX, 0, 1, 1, 0 }, /* state.matrix.mvp.row[1] */ + { STATE_MVP_MATRIX, 0, 2, 2, 0 }, /* state.matrix.mvp.row[2] */ + { STATE_MVP_MATRIX, 0, 3, 3, 0 }, /* state.matrix.mvp.row[3] */ }; GLint mvpRef[4]; @@ -125,9 +124,10 @@ _mesa_insert_mvp_code(GLcontext *ctx, struct gl_vertex_program *vprog) void _mesa_append_fog_code(GLcontext *ctx, struct gl_fragment_program *fprog) { - static const GLint fogPStateOpt[] = { STATE_INTERNAL, - STATE_FOG_PARAMS_OPTIMIZED, 0, 0, 0 }; - static const GLint fogColorState[] = { STATE_FOG_COLOR, 0, 0, 0, 0 }; + static const gl_state_index fogPStateOpt[STATE_LENGTH] + = { STATE_INTERNAL, STATE_FOG_PARAMS_OPTIMIZED, 0, 0, 0 }; + static const gl_state_index fogColorState[STATE_LENGTH] + = { STATE_FOG_COLOR, 0, 0, 0, 0}; struct prog_instruction *newInst, *inst; const GLuint origLen = fprog->Base.NumInstructions; const GLuint newLen = origLen + 5; @@ -150,8 +150,7 @@ _mesa_append_fog_code(GLcontext *ctx, struct gl_fragment_program *fprog) } /* Copy orig instructions into new instruction buffer */ - _mesa_memcpy(newInst, fprog->Base.Instructions, - origLen * sizeof(struct prog_instruction)); + _mesa_copy_instructions(newInst, fprog->Base.Instructions, origLen); /* PARAM fogParamsRefOpt = internal optimized fog params; */ fogPRefOpt @@ -283,3 +282,85 @@ _mesa_append_fog_code(GLcontext *ctx, struct gl_fragment_program *fprog) fprog->Base.InputsRead |= FRAG_BIT_FOGC; /* XXX do this? fprog->FogOption = GL_NONE; */ } + + + +static GLboolean +is_texture_instruction(const struct prog_instruction *inst) +{ + switch (inst->Opcode) { + case OPCODE_TEX: + case OPCODE_TXB: + case OPCODE_TXD: + case OPCODE_TXL: + case OPCODE_TXP: + case OPCODE_TXP_NV: + return GL_TRUE; + default: + return GL_FALSE; + } +} + + +/** + * Count the number of texure indirections in the given program. + * The program's NumTexIndirections field will be updated. + * See the GL_ARB_fragment_program spec (issue 24) for details. + * XXX we count texture indirections in texenvprogram.c (maybe use this code + * instead and elsewhere). + */ +void +_mesa_count_texture_indirections(struct gl_program *prog) +{ + GLuint indirections = 1; + GLbitfield tempsOutput = 0x0; + GLbitfield aluTemps = 0x0; + GLuint i; + + for (i = 0; i < prog->NumInstructions; i++) { + const struct prog_instruction *inst = prog->Instructions + i; + + if (is_texture_instruction(inst)) { + if (((inst->SrcReg[0].File == PROGRAM_TEMPORARY) && + (tempsOutput & (1 << inst->SrcReg[0].Index))) || + ((inst->Opcode != OPCODE_KIL) && + (inst->DstReg.File == PROGRAM_TEMPORARY) && + (aluTemps & (1 << inst->DstReg.Index)))) + { + indirections++; + tempsOutput = 0x0; + aluTemps = 0x0; + } + } + else { + GLuint j; + for (j = 0; j < 3; j++) { + if (inst->SrcReg[j].File == PROGRAM_TEMPORARY) + aluTemps |= (1 << inst->SrcReg[j].Index); + } + if (inst->DstReg.File == PROGRAM_TEMPORARY) + aluTemps |= (1 << inst->DstReg.Index); + } + + if ((inst->Opcode != OPCODE_KIL) && (inst->DstReg.File == PROGRAM_TEMPORARY)) + tempsOutput |= (1 << inst->DstReg.Index); + } + + prog->NumTexIndirections = indirections; +} + + +/** + * Count number of texture instructions in given program and update the + * program's NumTexInstructions field. + */ +void +_mesa_count_texture_instructions(struct gl_program *prog) +{ + GLuint i; + prog->NumTexInstructions = 0; + for (i = 0; i < prog->NumInstructions; i++) { + prog->NumTexInstructions += is_texture_instruction(prog->Instructions + i); + } +} + diff --git a/src/mesa/shader/programopt.h b/src/mesa/shader/programopt.h index efaf29b937..ce63644bbf 100644 --- a/src/mesa/shader/programopt.h +++ b/src/mesa/shader/programopt.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"), @@ -33,5 +33,11 @@ _mesa_insert_mvp_code(GLcontext *ctx, struct gl_vertex_program *vprog); extern void _mesa_append_fog_code(GLcontext *ctx, struct gl_fragment_program *fprog); +extern void +_mesa_count_texture_indirections(struct gl_program *prog); + +extern void +_mesa_count_texture_instructions(struct gl_program *prog); + #endif /* PROGRAMOPT_H */ diff --git a/src/mesa/shader/shader_api.c b/src/mesa/shader/shader_api.c new file mode 100644 index 0000000000..1831d0fb2e --- /dev/null +++ b/src/mesa/shader/shader_api.c @@ -0,0 +1,1081 @@ +/* + * Mesa 3-D graphics library + * Version: 6.5.3 + * + * Copyright (C) 2004-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. + */ + +/** + * \file shader_api.c + * Implementation of GLSL-related API functions + * \author Brian Paul + */ + +/** + * XXX things to do: + * 1. Check that the right error code is generated for all _mesa_error() calls. + * 2. Insert FLUSH_VERTICES calls in various places + */ + + +#include "glheader.h" +#include "context.h" +#include "hash.h" +#include "program.h" +#include "prog_parameter.h" +#include "prog_print.h" +#include "prog_statevars.h" +#include "shader_api.h" + +#include "slang_compile.h" +#include "slang_link.h" + + + +/** + * Allocate a new gl_shader_program object, initialize it. + */ +struct gl_shader_program * +_mesa_new_shader_program(GLcontext *ctx, GLuint name) +{ + struct gl_shader_program *shProg; + shProg = CALLOC_STRUCT(gl_shader_program); + if (shProg) { + shProg->Type = GL_SHADER_PROGRAM; + shProg->Name = name; + shProg->RefCount = 1; + shProg->Attributes = _mesa_new_parameter_list(); + } + return shProg; +} + + +/** + * Free the data that hangs off a shader program object, but not the object + * itself. + */ +void +_mesa_free_shader_program_data(GLcontext *ctx, + struct gl_shader_program *shProg) +{ + assert(shProg->Type == GL_SHADER_PROGRAM); + + if (shProg->VertexProgram) { + if (shProg->VertexProgram->Base.Parameters == shProg->Uniforms) { + /* to prevent a double-free in the next call */ + shProg->VertexProgram->Base.Parameters = NULL; + } + _mesa_delete_program(ctx, &shProg->VertexProgram->Base); + shProg->VertexProgram = NULL; + } + + if (shProg->FragmentProgram) { + if (shProg->FragmentProgram->Base.Parameters == shProg->Uniforms) { + /* to prevent a double-free in the next call */ + shProg->FragmentProgram->Base.Parameters = NULL; + } + _mesa_delete_program(ctx, &shProg->FragmentProgram->Base); + shProg->FragmentProgram = NULL; + } + + + if (shProg->Uniforms) { + _mesa_free_parameter_list(shProg->Uniforms); + shProg->Uniforms = NULL; + } + + if (shProg->Varying) { + _mesa_free_parameter_list(shProg->Varying); + shProg->Varying = NULL; + } +} + + +/** + * Free/delete a shader program object. + */ +void +_mesa_free_shader_program(GLcontext *ctx, struct gl_shader_program *shProg) +{ + _mesa_free_shader_program_data(ctx, shProg); + if (shProg->Shaders) { + _mesa_free(shProg->Shaders); + shProg->Shaders = NULL; + } + _mesa_free(shProg); +} + + +/** + * Lookup a GLSL program object. + */ +struct gl_shader_program * +_mesa_lookup_shader_program(GLcontext *ctx, GLuint name) +{ + struct gl_shader_program *shProg; + if (name) { + shProg = (struct gl_shader_program *) + _mesa_HashLookup(ctx->Shared->ShaderObjects, name); + /* Note that both gl_shader and gl_shader_program objects are kept + * in the same hash table. Check the object's type to be sure it's + * what we're expecting. + */ + if (shProg && shProg->Type != GL_SHADER_PROGRAM) { + return NULL; + } + return shProg; + } + return NULL; +} + + +/** + * Allocate a new gl_shader object, initialize it. + */ +struct gl_shader * +_mesa_new_shader(GLcontext *ctx, GLuint name, GLenum type) +{ + struct gl_shader *shader; + assert(type == GL_FRAGMENT_SHADER || type == GL_VERTEX_SHADER); + shader = CALLOC_STRUCT(gl_shader); + if (shader) { + shader->Type = type; + shader->Name = name; + shader->RefCount = 1; + } + return shader; +} + + +void +_mesa_free_shader(GLcontext *ctx, struct gl_shader *sh) +{ + GLuint i; + if (sh->Source) + _mesa_free((void *) sh->Source); + if (sh->InfoLog) + _mesa_free(sh->InfoLog); + for (i = 0; i < sh->NumPrograms; i++) { + assert(sh->Programs[i]); + _mesa_delete_program(ctx, sh->Programs[i]); + } + if (sh->Programs) + _mesa_free(sh->Programs); + _mesa_free(sh); +} + + +/** + * Lookup a GLSL shader object. + */ +struct gl_shader * +_mesa_lookup_shader(GLcontext *ctx, GLuint name) +{ + if (name) { + struct gl_shader *sh = (struct gl_shader *) + _mesa_HashLookup(ctx->Shared->ShaderObjects, name); + /* Note that both gl_shader and gl_shader_program objects are kept + * in the same hash table. Check the object's type to be sure it's + * what we're expecting. + */ + if (sh && sh->Type == GL_SHADER_PROGRAM) { + assert(sh->Type == GL_VERTEX_SHADER || + sh->Type == GL_FRAGMENT_SHADER); + return NULL; + } + return sh; + } + return NULL; +} + + +/** + * Initialize context's shader state. + */ +void +_mesa_init_shader_state(GLcontext * ctx) +{ + /* Device drivers may override these to control what kind of instructions + * are generated by the GLSL compiler. + */ + ctx->Shader.EmitHighLevelInstructions = GL_TRUE; + ctx->Shader.EmitCondCodes = GL_TRUE; /* XXX probably want GL_FALSE... */ + ctx->Shader.EmitComments = GL_FALSE; +} + + +/** + * Free the per-context shader-related state. + */ +void +_mesa_free_shader_state(GLcontext *ctx) +{ + if (ctx->Shader.CurrentProgram) { + ctx->Shader.CurrentProgram->RefCount--; + if (ctx->Shader.CurrentProgram->RefCount <= 0) { + _mesa_free_shader_program(ctx, ctx->Shader.CurrentProgram); + ctx->Shader.CurrentProgram = NULL; + } + } +} + + +/** + * Copy string from <src> to <dst>, up to maxLength characters, returning + * length of <dst> in <length>. + * \param src the strings source + * \param maxLength max chars to copy + * \param length returns number of chars copied + * \param dst the string destination + */ +static void +copy_string(GLchar *dst, GLsizei maxLength, GLsizei *length, const GLchar *src) +{ + GLsizei len; + for (len = 0; len < maxLength - 1 && src && src[len]; len++) + dst[len] = src[len]; + if (maxLength > 0) + dst[len] = 0; + if (length) + *length = len; +} + + +/** + * Called via ctx->Driver.AttachShader() + */ +void +_mesa_attach_shader(GLcontext *ctx, GLuint program, GLuint shader) +{ + struct gl_shader_program *shProg + = _mesa_lookup_shader_program(ctx, program); + struct gl_shader *sh = _mesa_lookup_shader(ctx, shader); + const GLuint n = shProg->NumShaders; + GLuint i; + + if (!shProg || !sh) { + _mesa_error(ctx, GL_INVALID_VALUE, + "glAttachShader(bad program or shader name)"); + return; + } + + for (i = 0; i < n; i++) { + if (shProg->Shaders[i] == sh) { + /* already attached */ + return; + } + } + + /* grow list */ + shProg->Shaders = (struct gl_shader **) + _mesa_realloc(shProg->Shaders, + n * sizeof(struct gl_shader *), + (n + 1) * sizeof(struct gl_shader *)); + if (!shProg->Shaders) { + _mesa_error(ctx, GL_OUT_OF_MEMORY, "glAttachShader"); + return; + } + + /* append */ + shProg->Shaders[n] = sh; + sh->RefCount++; + shProg->NumShaders++; +} + + +void +_mesa_bind_attrib_location(GLcontext *ctx, GLuint program, GLuint index, + const GLchar *name) +{ + struct gl_shader_program *shProg + = _mesa_lookup_shader_program(ctx, program); + const GLint size = -1; /* unknown size */ + GLint i, oldIndex; + + if (!shProg) { + _mesa_error(ctx, GL_INVALID_VALUE, "glBindAttribLocation(program)"); + return; + } + + if (!name) + return; + + if (strncmp(name, "gl_", 3) == 0) { + _mesa_error(ctx, GL_INVALID_OPERATION, + "glBindAttribLocation(illegal name)"); + return; + } + + oldIndex = _mesa_get_attrib_location(ctx, program, name); + + /* this will replace the current value if it's already in the list */ + i = _mesa_add_attribute(shProg->Attributes, name, size, index); + if (i < 0) { + _mesa_error(ctx, GL_OUT_OF_MEMORY, "glBindAttribLocation"); + } + + if (shProg->VertexProgram && oldIndex >= 0) { + _slang_remap_attribute(&shProg->VertexProgram->Base, oldIndex, index); + } + +#if 0 + printf("===== post BindAttrib:\n"); + _mesa_print_program(&shProg->VertexProgram->Base); +#endif +} + + +GLuint +_mesa_create_shader(GLcontext *ctx, GLenum type) +{ + struct gl_shader *sh; + GLuint name; + + name = _mesa_HashFindFreeKeyBlock(ctx->Shared->ShaderObjects, 1); + + switch (type) { + case GL_FRAGMENT_SHADER: + case GL_VERTEX_SHADER: + sh = _mesa_new_shader(ctx, name, type); + break; + default: + _mesa_error(ctx, GL_INVALID_ENUM, "CreateShader(type)"); + return 0; + } + + _mesa_HashInsert(ctx->Shared->ShaderObjects, name, sh); + + return name; +} + + +GLuint +_mesa_create_program(GLcontext *ctx) +{ + GLuint name; + struct gl_shader_program *shProg; + + name = _mesa_HashFindFreeKeyBlock(ctx->Shared->ShaderObjects, 1); + shProg = _mesa_new_shader_program(ctx, name); + + _mesa_HashInsert(ctx->Shared->ShaderObjects, name, shProg); + + return name; +} + + +void +_mesa_delete_program2(GLcontext *ctx, GLuint name) +{ + struct gl_shader_program *shProg; + + shProg = _mesa_lookup_shader_program(ctx, name); + if (!shProg) { + _mesa_error(ctx, GL_INVALID_VALUE, "glDeleteProgram(name)"); + return; + } + + /* always remove from hash table */ + _mesa_HashRemove(ctx->Shared->ShaderObjects, name); + + shProg->DeletePending = GL_TRUE; + + /* decrement refcount, delete if zero */ + shProg->RefCount--; + if (shProg->RefCount <= 0) { + _mesa_free_shader_program(ctx, shProg); + } +} + + +void +_mesa_delete_shader(GLcontext *ctx, GLuint shader) +{ + struct gl_shader *sh = _mesa_lookup_shader(ctx, shader); + if (!sh) { + return; + } + + sh->DeletePending = GL_TRUE; + sh->RefCount--; + if (sh->RefCount <= 0) { + _mesa_free_shader(ctx, sh); + } +} + + +void +_mesa_detach_shader(GLcontext *ctx, GLuint program, GLuint shader) +{ + struct gl_shader_program *shProg + = _mesa_lookup_shader_program(ctx, program); + const GLuint n = shProg->NumShaders; + GLuint i, j; + + if (!shProg) { + _mesa_error(ctx, GL_INVALID_VALUE, + "glDetachShader(bad program or shader name)"); + return; + } + + for (i = 0; i < n; i++) { + if (shProg->Shaders[i]->Name == shader) { + struct gl_shader **newList; + /* found it */ + + shProg->Shaders[i]->RefCount--; + if (shProg->Shaders[i]->RefCount == 0) { + /* delete now */ + _mesa_free_shader(ctx, shProg->Shaders[i]); + } + + /* alloc new, smaller array */ + newList = (struct gl_shader **) + _mesa_malloc((n - 1) * sizeof(struct gl_shader *)); + if (!newList) { + _mesa_error(ctx, GL_OUT_OF_MEMORY, "glDetachShader"); + return; + } + for (j = 0; j < i; j++) { + newList[j] = shProg->Shaders[j]; + } + while (++i < n) + newList[j++] = shProg->Shaders[i]; + _mesa_free(shProg->Shaders); + + shProg->Shaders = newList; + return; + } + } + + /* not found */ + _mesa_error(ctx, GL_INVALID_VALUE, + "glDetachShader(shader not found)"); +} + + +void +_mesa_get_active_attrib(GLcontext *ctx, GLuint program, GLuint index, + GLsizei maxLength, GLsizei *length, GLint *size, + GLenum *type, GLchar *nameOut) +{ + static const GLenum vec_types[] = { + GL_FLOAT, GL_FLOAT_VEC2, GL_FLOAT_VEC3, GL_FLOAT_VEC4 + }; + struct gl_shader_program *shProg + = _mesa_lookup_shader_program(ctx, program); + GLint sz; + + if (!shProg) { + _mesa_error(ctx, GL_INVALID_VALUE, "glGetActiveUniform"); + return; + } + + if (!shProg->Attributes || index >= shProg->Attributes->NumParameters) { + _mesa_error(ctx, GL_INVALID_VALUE, "glGetActiveUniform(index)"); + return; + } + + copy_string(nameOut, maxLength, length, + shProg->Attributes->Parameters[index].Name); + sz = shProg->Attributes->Parameters[index].Size; + if (size) + *size = sz; + if (type) + *type = vec_types[sz]; /* XXX this is a temporary hack */ +} + + +/** + * Called via ctx->Driver.GetActiveUniform(). + */ +void +_mesa_get_active_uniform(GLcontext *ctx, GLuint program, GLuint index, + GLsizei maxLength, GLsizei *length, GLint *size, + GLenum *type, GLchar *nameOut) +{ + static const GLenum vec_types[] = { + GL_FLOAT, GL_FLOAT_VEC2, GL_FLOAT_VEC3, GL_FLOAT_VEC4 + }; + struct gl_shader_program *shProg + = _mesa_lookup_shader_program(ctx, program); + GLint sz; + + if (!shProg) { + _mesa_error(ctx, GL_INVALID_VALUE, "glGetActiveUniform"); + return; + } + + if (!shProg->Uniforms || index >= shProg->Uniforms->NumParameters) { + _mesa_error(ctx, GL_INVALID_VALUE, "glGetActiveUniform(index)"); + return; + } + + copy_string(nameOut, maxLength, length, + shProg->Uniforms->Parameters[index].Name); + sz = shProg->Uniforms->Parameters[index].Size; + if (size) + *size = sz; + if (type) + *type = vec_types[sz]; /* XXX this is a temporary hack */ +} + + +/** + * Called via ctx->Driver.GetAttachedShaders(). + */ +void +_mesa_get_attached_shaders(GLcontext *ctx, GLuint program, GLsizei maxCount, + GLsizei *count, GLuint *obj) +{ + struct gl_shader_program *shProg + = _mesa_lookup_shader_program(ctx, program); + if (shProg) { + GLint i; + for (i = 0; i < maxCount && i < shProg->NumShaders; i++) { + obj[i] = shProg->Shaders[i]->Name; + } + if (count) + *count = i; + } + else { + _mesa_error(ctx, GL_INVALID_VALUE, "glGetAttachedShaders"); + } +} + + +GLint +_mesa_get_attrib_location(GLcontext *ctx, GLuint program, + const GLchar *name) +{ + struct gl_shader_program *shProg + = _mesa_lookup_shader_program(ctx, program); + + if (!shProg) { + _mesa_error(ctx, GL_INVALID_VALUE, "glGetAttribLocation"); + return -1; + } + + if (!shProg->LinkStatus) { + _mesa_error(ctx, GL_INVALID_OPERATION, + "glGetAttribLocation(program not linked)"); + return -1; + } + + if (!name) + return -1; + + if (shProg->Attributes) { + GLint i = _mesa_lookup_parameter_index(shProg->Attributes, -1, name); + if (i >= 0) { + return shProg->Attributes->Parameters[i].StateIndexes[0]; + } + } + return -1; +} + + +GLuint +_mesa_get_handle(GLcontext *ctx, GLenum pname) +{ +#if 0 + GET_CURRENT_CONTEXT(ctx); + + switch (pname) { + case GL_PROGRAM_OBJECT_ARB: + { + struct gl2_program_intf **pro = ctx->Shader.CurrentProgram; + + if (pro != NULL) + return (**pro)._container._generic. + GetName((struct gl2_generic_intf **) (pro)); + } + break; + default: + _mesa_error(ctx, GL_INVALID_ENUM, "glGetHandleARB"); + } +#endif + return 0; +} + + +void +_mesa_get_programiv(GLcontext *ctx, GLuint program, + GLenum pname, GLint *params) +{ + struct gl_shader_program *shProg + = _mesa_lookup_shader_program(ctx, program); + + if (!shProg) { + _mesa_error(ctx, GL_INVALID_VALUE, "glGetProgramiv(program)"); + return; + } + + switch (pname) { + case GL_DELETE_STATUS: + *params = shProg->DeletePending; + break; + case GL_LINK_STATUS: + *params = shProg->LinkStatus; + break; + case GL_VALIDATE_STATUS: + *params = shProg->Validated; + break; + case GL_INFO_LOG_LENGTH: + *params = shProg->InfoLog ? strlen(shProg->InfoLog) : 0; + break; + case GL_ATTACHED_SHADERS: + *params = shProg->NumShaders; + break; + case GL_ACTIVE_ATTRIBUTES: + *params = shProg->Attributes ? shProg->Attributes->NumParameters : 0; + break; + case GL_ACTIVE_ATTRIBUTE_MAX_LENGTH: + *params = _mesa_parameter_longest_name(shProg->Attributes); + break; + case GL_ACTIVE_UNIFORMS: + *params = shProg->Uniforms ? shProg->Uniforms->NumParameters : 0; + break; + case GL_ACTIVE_UNIFORM_MAX_LENGTH: + *params = _mesa_parameter_longest_name(shProg->Uniforms); + break; + default: + _mesa_error(ctx, GL_INVALID_ENUM, "glGetProgramiv(pname)"); + return; + } +} + + +void +_mesa_get_shaderiv(GLcontext *ctx, GLuint name, GLenum pname, GLint *params) +{ + struct gl_shader *shader = _mesa_lookup_shader(ctx, name); + + if (!shader) { + _mesa_error(ctx, GL_INVALID_VALUE, "glGetShaderiv(shader)"); + return; + } + + switch (pname) { + case GL_SHADER_TYPE: + *params = shader->Type; + break; + case GL_DELETE_STATUS: + *params = shader->DeletePending; + break; + case GL_COMPILE_STATUS: + *params = shader->CompileStatus; + break; + case GL_INFO_LOG_LENGTH: + *params = shader->InfoLog ? strlen(shader->InfoLog) : 0; + break; + case GL_SHADER_SOURCE_LENGTH: + *params = shader->Source ? strlen((char *) shader->Source) : 0; + break; + default: + _mesa_error(ctx, GL_INVALID_ENUM, "glGetShaderiv(pname)"); + return; + } +} + + +void +_mesa_get_program_info_log(GLcontext *ctx, GLuint program, GLsizei bufSize, + GLsizei *length, GLchar *infoLog) +{ + struct gl_shader_program *shProg + = _mesa_lookup_shader_program(ctx, program); + if (!shProg) { + _mesa_error(ctx, GL_INVALID_VALUE, "glGetProgramInfoLog(program)"); + return; + } + copy_string(infoLog, bufSize, length, shProg->InfoLog); +} + + +void +_mesa_get_shader_info_log(GLcontext *ctx, GLuint shader, GLsizei bufSize, + GLsizei *length, GLchar *infoLog) +{ + struct gl_shader *sh = _mesa_lookup_shader(ctx, shader); + if (!sh) { + _mesa_error(ctx, GL_INVALID_VALUE, "glGetShaderInfoLog(shader)"); + return; + } + copy_string(infoLog, bufSize, length, sh->InfoLog); +} + + +/** + * Called via ctx->Driver.GetShaderSource(). + */ +void +_mesa_get_shader_source(GLcontext *ctx, GLuint shader, GLsizei maxLength, + GLsizei *length, GLchar *sourceOut) +{ + struct gl_shader *sh = _mesa_lookup_shader(ctx, shader); + if (!sh) { + _mesa_error(ctx, GL_INVALID_VALUE, "glGetShaderSource(shader)"); + return; + } + copy_string(sourceOut, maxLength, length, sh->Source); +} + + +/** + * Called via ctx->Driver.GetUniformfv(). + */ +void +_mesa_get_uniformfv(GLcontext *ctx, GLuint program, GLint location, + GLfloat *params) +{ + struct gl_shader_program *shProg + = _mesa_lookup_shader_program(ctx, program); + if (shProg) { + GLint i; + if (location >= 0 && location < shProg->Uniforms->NumParameters) { + for (i = 0; i < shProg->Uniforms->Parameters[location].Size; i++) { + params[i] = shProg->Uniforms->ParameterValues[location][i]; + } + } + else { + _mesa_error(ctx, GL_INVALID_VALUE, "glGetUniformfv(location)"); + } + } + else { + _mesa_error(ctx, GL_INVALID_VALUE, "glGetUniformfv(program)"); + } +} + + +/** + * Called via ctx->Driver.GetUniformLocation(). + */ +GLint +_mesa_get_uniform_location(GLcontext *ctx, GLuint program, const GLchar *name) +{ + struct gl_shader_program *shProg + = _mesa_lookup_shader_program(ctx, program); + if (shProg) { + GLuint loc; + for (loc = 0; loc < shProg->Uniforms->NumParameters; loc++) { + const struct gl_program_parameter *u + = shProg->Uniforms->Parameters + loc; + /* XXX this is a temporary simplification / short-cut. + * We need to handle things like "e.c[0].b" as seen in the + * GLSL orange book, page 189. + */ + if ((u->Type == PROGRAM_UNIFORM || + u->Type == PROGRAM_SAMPLER) && !strcmp(u->Name, name)) { + return loc; + } + } + } + return -1; + +} + + +GLboolean +_mesa_is_program(GLcontext *ctx, GLuint name) +{ + struct gl_shader_program *shProg = _mesa_lookup_shader_program(ctx, name); + return shProg ? GL_TRUE : GL_FALSE; +} + + +GLboolean +_mesa_is_shader(GLcontext *ctx, GLuint name) +{ + struct gl_shader *shader = _mesa_lookup_shader(ctx, name); + return shader ? GL_TRUE : GL_FALSE; +} + + + +/** + * Called via ctx->Driver.ShaderSource() + */ +void +_mesa_shader_source(GLcontext *ctx, GLuint shader, const GLchar *source) +{ + struct gl_shader *sh = _mesa_lookup_shader(ctx, shader); + if (!sh) { + _mesa_error(ctx, GL_INVALID_VALUE, "glShaderSource(shaderObj)"); + return; + } + + /* free old shader source string and install new one */ + if (sh->Source) { + _mesa_free((void *) sh->Source); + } + sh->Source = source; + sh->CompileStatus = GL_FALSE; +} + + +/** + * Called via ctx->Driver.CompileShader() + */ +void +_mesa_compile_shader(GLcontext *ctx, GLuint shaderObj) +{ + struct gl_shader *sh = _mesa_lookup_shader(ctx, shaderObj); + + if (!sh) { + _mesa_error(ctx, GL_INVALID_VALUE, "glCompileShader(shaderObj)"); + return; + } + + sh->CompileStatus = _slang_compile(ctx, sh); +} + + +/** + * Called via ctx->Driver.LinkProgram() + */ +void +_mesa_link_program(GLcontext *ctx, GLuint program) +{ + struct gl_shader_program *shProg; + + shProg = _mesa_lookup_shader_program(ctx, program); + if (!shProg) { + _mesa_error(ctx, GL_INVALID_VALUE, "glLinkProgram(program)"); + return; + } + + _slang_link(ctx, program, shProg); +} + + +/** + * Called via ctx->Driver.UseProgram() + */ +void +_mesa_use_program(GLcontext *ctx, GLuint program) +{ + if (ctx->Shader.CurrentProgram && + ctx->Shader.CurrentProgram->Name == program) { + /* no-op */ + return; + } + + FLUSH_VERTICES(ctx, _NEW_PROGRAM); + + /* unbind old */ + if (ctx->Shader.CurrentProgram) { + ctx->Shader.CurrentProgram->RefCount--; + if (ctx->Shader.CurrentProgram->RefCount <= 0) { + _mesa_free_shader_program(ctx, ctx->Shader.CurrentProgram); + } + ctx->Shader.CurrentProgram = NULL; + } + + if (program) { + struct gl_shader_program *shProg; + shProg = _mesa_lookup_shader_program(ctx, program); + if (!shProg) { + _mesa_error(ctx, GL_INVALID_VALUE, + "glUseProgramObjectARB(programObj)"); + return; + } + ctx->Shader.CurrentProgram = shProg; + shProg->RefCount++; + } + else { + /* don't use a shader program */ + ctx->Shader.CurrentProgram = NULL; + } +} + + +/** + * Called via ctx->Driver.Uniform(). + */ +void +_mesa_uniform(GLcontext *ctx, GLint location, GLsizei count, + const GLvoid *values, GLenum type) +{ + struct gl_shader_program *shProg = ctx->Shader.CurrentProgram; + GLint elems, i, k; + + if (!shProg || !shProg->LinkStatus) { + _mesa_error(ctx, GL_INVALID_OPERATION, "glUniform(program not linked)"); + return; + } + + if (location < 0 || location >= (GLint) shProg->Uniforms->NumParameters) { + _mesa_error(ctx, GL_INVALID_VALUE, "glUniform(location)"); + return; + } + + FLUSH_VERTICES(ctx, _NEW_PROGRAM); + + /* + * If we're setting a sampler, we must use glUniformi1()! + */ + if (shProg->Uniforms->Parameters[location].Type == PROGRAM_SAMPLER) { + if (type != GL_INT || count != 1) { + _mesa_error(ctx, GL_INVALID_OPERATION, + "glUniform(only glUniform1i can be used " + "to set sampler uniforms)"); + return; + } + } + + if (count < 0) { + _mesa_error(ctx, GL_INVALID_VALUE, "glUniform(count < 0)"); + return; + } + + switch (type) { + case GL_FLOAT: + case GL_INT: + elems = 1; + break; + case GL_FLOAT_VEC2: + case GL_INT_VEC2: + elems = 2; + break; + case GL_FLOAT_VEC3: + case GL_INT_VEC3: + elems = 3; + break; + case GL_FLOAT_VEC4: + case GL_INT_VEC4: + elems = 4; + break; + default: + _mesa_problem(ctx, "Invalid type in _mesa_uniform"); + return; + } + + if (count * elems > shProg->Uniforms->Parameters[location].Size) { + _mesa_error(ctx, GL_INVALID_OPERATION, "glUniform(count too large)"); + return; + } + + for (k = 0; k < count; k++) { + GLfloat *uniformVal = shProg->Uniforms->ParameterValues[location + k]; + if (type == GL_INT || + type == GL_INT_VEC2 || + type == GL_INT_VEC3 || + type == GL_INT_VEC4) { + const GLint *iValues = ((const GLint *) values) + k * elems; + for (i = 0; i < elems; i++) { + uniformVal[i] = (GLfloat) iValues[i]; + } + } + else { + const GLfloat *fValues = ((const GLfloat *) values) + k * elems; + for (i = 0; i < elems; i++) { + uniformVal[i] = fValues[i]; + } + } + } + + if (shProg->Uniforms->Parameters[location].Type == PROGRAM_SAMPLER) { + if (shProg->VertexProgram) + _slang_resolve_samplers(shProg, &shProg->VertexProgram->Base); + if (shProg->FragmentProgram) + _slang_resolve_samplers(shProg, &shProg->FragmentProgram->Base); + FLUSH_VERTICES(ctx, _NEW_TEXTURE); + } +} + + +/** + * Called by ctx->Driver.UniformMatrix(). + */ +void +_mesa_uniform_matrix(GLcontext *ctx, GLint cols, GLint rows, + GLenum matrixType, GLint location, GLsizei count, + GLboolean transpose, const GLfloat *values) +{ + struct gl_shader_program *shProg = ctx->Shader.CurrentProgram; + if (!shProg || !shProg->LinkStatus) { + _mesa_error(ctx, GL_INVALID_OPERATION, + "glUniformMatrix(program not linked)"); + return; + } + if (location < 0 || location >= shProg->Uniforms->NumParameters) { + _mesa_error(ctx, GL_INVALID_VALUE, "glUniformMatrix(location)"); + return; + } + if (values == NULL) { + _mesa_error(ctx, GL_INVALID_VALUE, "glUniformMatrix"); + return; + } + + FLUSH_VERTICES(ctx, _NEW_PROGRAM); + + /* + * Note: the _columns_ of a matrix are stored in program registers, not + * the rows. + */ + /* XXXX need to test 3x3 and 2x2 matrices... */ + if (transpose) { + GLuint row, col; + for (col = 0; col < cols; col++) { + GLfloat *v = shProg->Uniforms->ParameterValues[location + col]; + for (row = 0; row < rows; row++) { + v[row] = values[row * cols + col]; + } + } + } + else { + GLuint row, col; + for (col = 0; col < cols; col++) { + GLfloat *v = shProg->Uniforms->ParameterValues[location + col]; + for (row = 0; row < rows; row++) { + v[row] = values[col * rows + row]; + } + } + } +} + + +void +_mesa_validate_program(GLcontext *ctx, GLuint program) +{ + struct gl_shader_program *shProg; + shProg = _mesa_lookup_shader_program(ctx, program); + if (!shProg) { + _mesa_error(ctx, GL_INVALID_VALUE, "glValidateProgram(program)"); + return; + } + /* XXX temporary */ + shProg->Validated = GL_TRUE; + + /* From the GL spec: + any two active samplers in the current program object are of + different types, but refer to the same texture image unit, + + any active sampler in the current program object refers to a texture + image unit where fixed-function fragment processing accesses a + texture target that does not match the sampler type, or + + the sum of the number of active samplers in the program and the + number of texture image units enabled for fixed-function fragment + processing exceeds the combined limit on the total number of texture + image units allowed. + */ +} diff --git a/src/mesa/shader/shader_api.h b/src/mesa/shader/shader_api.h new file mode 100644 index 0000000000..16ed1a0c10 --- /dev/null +++ b/src/mesa/shader/shader_api.h @@ -0,0 +1,172 @@ +/* + * Mesa 3-D graphics library + * Version: 6.5 + * + * Copyright (C) 2004-2006 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 SHADER_API_H +#define SHADER_API_H + + +#include "glheader.h" +#include "mtypes.h" + + +/** + * Internal functions + */ + +extern void +_mesa_init_shader_state(GLcontext * ctx); + +extern void +_mesa_free_shader_state(GLcontext *ctx); + +extern struct gl_shader_program * +_mesa_new_shader_program(GLcontext *ctx, GLuint name); + +extern void +_mesa_free_shader_program_data(GLcontext *ctx, + struct gl_shader_program *shProg); + +extern void +_mesa_free_shader_program(GLcontext *ctx, struct gl_shader_program *shProg); + +extern struct gl_shader_program * +_mesa_lookup_shader_program(GLcontext *ctx, GLuint name); + + +extern struct gl_shader * +_mesa_new_shader(GLcontext *ctx, GLuint name, GLenum type); + +extern void +_mesa_free_shader(GLcontext *ctx, struct gl_shader *sh); + +extern struct gl_shader * +_mesa_lookup_shader(GLcontext *ctx, GLuint name); + + +/** + * API/Driver functions + */ + +extern void +_mesa_attach_shader(GLcontext *ctx, GLuint program, GLuint shader); + +extern void +_mesa_bind_attrib_location(GLcontext *ctx, GLuint program, GLuint index, + const GLchar *name); + +extern void +_mesa_compile_shader(GLcontext *ctx, GLuint shaderObj); + +extern GLuint +_mesa_create_shader(GLcontext *ctx, GLenum type); + +extern GLuint +_mesa_create_program(GLcontext *ctx); + +extern void +_mesa_delete_program2(GLcontext *ctx, GLuint name); + +extern void +_mesa_delete_shader(GLcontext *ctx, GLuint shader); + +extern void +_mesa_detach_shader(GLcontext *ctx, GLuint program, GLuint shader); + +extern void +_mesa_get_active_attrib(GLcontext *ctx, GLuint program, GLuint index, + GLsizei maxLength, GLsizei *length, GLint *size, + GLenum *type, GLchar *name); + +extern void +_mesa_get_active_uniform(GLcontext *ctx, GLuint program, GLuint index, + GLsizei maxLength, GLsizei *length, GLint *size, + GLenum *type, GLchar *name); + +extern void +_mesa_get_attached_shaders(GLcontext *ctx, GLuint program, GLsizei maxCount, + GLsizei *count, GLuint *obj); + +extern GLint +_mesa_get_attrib_location(GLcontext *ctx, GLuint program, + const GLchar *name); + +extern GLuint +_mesa_get_handle(GLcontext *ctx, GLenum pname); + +extern void +_mesa_get_programiv(GLcontext *ctx, GLuint program, + GLenum pname, GLint *params); + +extern void +_mesa_get_program_info_log(GLcontext *ctx, GLuint program, GLsizei bufSize, + GLsizei *length, GLchar *infoLog); + +extern void +_mesa_get_shaderiv(GLcontext *ctx, GLuint shader, GLenum pname, GLint *params); + +extern void +_mesa_get_shader_info_log(GLcontext *ctx, GLuint shader, GLsizei bufSize, + GLsizei *length, GLchar *infoLog); + +extern void +_mesa_get_shader_source(GLcontext *ctx, GLuint shader, GLsizei maxLength, + GLsizei *length, GLchar *sourceOut); + +extern void +_mesa_get_uniformfv(GLcontext *ctx, GLuint program, GLint location, + GLfloat *params); + +extern GLint +_mesa_get_uniform_location(GLcontext *ctx, GLuint program, const GLchar *name); + +extern GLboolean +_mesa_is_program(GLcontext *ctx, GLuint name); + +extern GLboolean +_mesa_is_shader(GLcontext *ctx, GLuint name); + +extern void +_mesa_link_program(GLcontext *ctx, GLuint program); + +extern void +_mesa_shader_source(GLcontext *ctx, GLuint shader, const GLchar *source); + +extern void +_mesa_uniform(GLcontext *ctx, GLint location, GLsizei count, + const GLvoid *values, GLenum type); + +void +_mesa_uniform_matrix(GLcontext *ctx, GLint cols, GLint rows, + GLenum matrixType, GLint location, GLsizei count, + GLboolean transpose, const GLfloat *values); + +extern void +_mesa_use_program(GLcontext *ctx, GLuint program); + +extern void +_mesa_validate_program(GLcontext *ctx, GLuint program); + + +#endif /* SHADER_API_H */ diff --git a/src/mesa/shader/shaderobjects.c b/src/mesa/shader/shaderobjects.c deleted file mode 100644 index da4d5c8472..0000000000 --- a/src/mesa/shader/shaderobjects.c +++ /dev/null @@ -1,1191 +0,0 @@ -/* - * Mesa 3-D graphics library - * Version: 6.5 - * - * Copyright (C) 2004-2006 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. - */ - -/** - * \file shaderobjects.c - * ARB_shader_objects state management functions - * \author Michal Krol - */ - - -#include "glheader.h" -#include "context.h" -#include "hash.h" -#include "shaderobjects.h" -#include "shaderobjects_3dlabs.h" - - -#if FEATURE_ARB_shader_objects - -#define RELEASE_GENERIC(x)\ - (**x)._unknown.Release ((struct gl2_unknown_intf **) (x)) - -#define RELEASE_CONTAINER(x)\ - (**x)._generic._unknown.Release ((struct gl2_unknown_intf **) (x)) - -#define RELEASE_PROGRAM(x)\ - (**x)._container._generic._unknown.Release ((struct gl2_unknown_intf **) (x)) - -#define RELEASE_SHADER(x)\ - (**x)._generic._unknown.Release ((struct gl2_unknown_intf **) (x)) - - - -static struct gl2_unknown_intf ** -lookup_handle(GLcontext * ctx, GLhandleARB handle, enum gl2_uiid uiid, - const char *function) -{ - struct gl2_unknown_intf **unk; - - /* - * Note: _mesa_HashLookup() requires non-zero input values, so the - * passed-in handle value must be checked beforehand. - */ - if (handle == 0) { - _mesa_error(ctx, GL_INVALID_VALUE, function); - return NULL; - } - _glthread_LOCK_MUTEX(ctx->Shared->Mutex); - unk = (struct gl2_unknown_intf **) _mesa_HashLookup(ctx->Shared->GL2Objects, - handle); - _glthread_UNLOCK_MUTEX(ctx->Shared->Mutex); - - if (unk == NULL) { - _mesa_error(ctx, GL_INVALID_VALUE, function); - } - else { - unk = (**unk).QueryInterface(unk, uiid); - if (unk == NULL) - _mesa_error(ctx, GL_INVALID_OPERATION, function); - } - return unk; -} - -#define GET_GENERIC(x, handle, function)\ - struct gl2_generic_intf **x = (struct gl2_generic_intf **)\ - lookup_handle (ctx, handle, UIID_GENERIC, function); - -#define GET_CONTAINER(x, handle, function)\ - struct gl2_container_intf **x = (struct gl2_container_intf **)\ - lookup_handle (ctx, handle, UIID_CONTAINER, function); - -#define GET_PROGRAM(x, handle, function)\ - struct gl2_program_intf **x = (struct gl2_program_intf **)\ - lookup_handle (ctx, handle, UIID_PROGRAM, function); - -#define GET_SHADER(x, handle, function)\ - struct gl2_shader_intf **x = (struct gl2_shader_intf **)\ - lookup_handle (ctx, handle, UIID_SHADER, function); - - -#define GET_LINKED_PROGRAM(x, handle, function) \ - GET_PROGRAM(x, handle, function); \ - if (x && (**x).GetLinkStatus(x) == GL_FALSE) { \ - RELEASE_PROGRAM(x); \ - _mesa_error(ctx, GL_INVALID_OPERATION, function); \ - x = NULL; \ - } - -#define GET_CURRENT_LINKED_PROGRAM(x, function) \ - struct gl2_program_intf **x = ctx->ShaderObjects.CurrentProgram; \ - if (!x || (**x).GetLinkStatus(x) == GL_FALSE) { \ - _mesa_error(ctx, GL_INVALID_OPERATION, function); \ - return; \ - } - - - -#define IS_NAME_WITH_GL_PREFIX(x) ((x)[0] == 'g' && (x)[1] == 'l' && (x)[2] == '_') - - -GLvoid GLAPIENTRY -_mesa_DeleteObjectARB(GLhandleARB obj) -{ - if (obj != 0) { - GET_CURRENT_CONTEXT(ctx); - GET_GENERIC(gen, obj, "glDeleteObjectARB"); - - if (gen != NULL) { - (**gen).Delete(gen); - RELEASE_GENERIC(gen); - } - } -} - -GLhandleARB GLAPIENTRY -_mesa_GetHandleARB(GLenum pname) -{ - GET_CURRENT_CONTEXT(ctx); - - switch (pname) { - case GL_PROGRAM_OBJECT_ARB: - { - struct gl2_program_intf **pro = ctx->ShaderObjects.CurrentProgram; - - if (pro != NULL) - return (**pro)._container._generic. - GetName((struct gl2_generic_intf **) (pro)); - } - break; - default: - _mesa_error(ctx, GL_INVALID_ENUM, "glGetHandleARB"); - } - - return 0; -} - -GLvoid GLAPIENTRY -_mesa_DetachObjectARB(GLhandleARB containerObj, GLhandleARB attachedObj) -{ - GET_CURRENT_CONTEXT(ctx); - GET_CONTAINER(con, containerObj, "glDetachObjectARB"); - - if (con != NULL) { - GET_GENERIC(att, attachedObj, "glDetachObjectARB"); - - if (att != NULL) { - (**con).Detach(con, att); - RELEASE_GENERIC(att); - } - RELEASE_CONTAINER(con); - } -} - -GLhandleARB GLAPIENTRY -_mesa_CreateShaderObjectARB(GLenum shaderType) -{ - return _mesa_3dlabs_create_shader_object(shaderType); -} - -GLvoid GLAPIENTRY -_mesa_ShaderSourceARB(GLhandleARB shaderObj, GLsizei count, - const GLcharARB ** string, const GLint * length) -{ - GET_CURRENT_CONTEXT(ctx); - GLint *offsets; - GLsizei i; - GLcharARB *source; - GET_SHADER(sha, shaderObj, "glShaderSourceARB"); - - if (sha == NULL) - return; - - if (string == NULL) { - RELEASE_SHADER(sha); - _mesa_error(ctx, GL_INVALID_VALUE, "glShaderSourceARB"); - return; - } - - /* - * This array holds offsets of where the appropriate string ends, thus the last - * element will be set to the total length of the source code. - */ - offsets = (GLint *) _mesa_malloc(count * sizeof(GLint)); - if (offsets == NULL) { - RELEASE_SHADER(sha); - _mesa_error(ctx, GL_OUT_OF_MEMORY, "glShaderSourceARB"); - return; - } - - for (i = 0; i < count; i++) { - if (string[i] == NULL) { - _mesa_free((GLvoid *) offsets); - RELEASE_SHADER(sha); - _mesa_error(ctx, GL_INVALID_VALUE, "glShaderSourceARB"); - return; - } - if (length == NULL || length[i] < 0) - offsets[i] = _mesa_strlen(string[i]); - else - offsets[i] = length[i]; - /* accumulate string lengths */ - if (i > 0) - offsets[i] += offsets[i - 1]; - } - - source = - (GLcharARB *) _mesa_malloc((offsets[count - 1] + 1) * - sizeof(GLcharARB)); - if (source == NULL) { - _mesa_free((GLvoid *) offsets); - RELEASE_SHADER(sha); - _mesa_error(ctx, GL_OUT_OF_MEMORY, "glShaderSourceARB"); - return; - } - - for (i = 0; i < count; i++) { - GLint start = (i > 0) ? offsets[i - 1] : 0; - _mesa_memcpy(source + start, string[i], - (offsets[i] - start) * sizeof(GLcharARB)); - } - source[offsets[count - 1]] = '\0'; - - (**sha).SetSource(sha, source, offsets, count); - RELEASE_SHADER(sha); -} - -GLvoid GLAPIENTRY -_mesa_CompileShaderARB(GLhandleARB shaderObj) -{ - GET_CURRENT_CONTEXT(ctx); - GET_SHADER(sha, shaderObj, "glCompileShaderARB"); - - if (sha != NULL) { - (**sha).Compile(sha); - RELEASE_SHADER(sha); - } -} - -GLhandleARB GLAPIENTRY -_mesa_CreateProgramObjectARB(GLvoid) -{ - return _mesa_3dlabs_create_program_object(); -} - -GLvoid GLAPIENTRY -_mesa_AttachObjectARB(GLhandleARB containerObj, GLhandleARB obj) -{ - GET_CURRENT_CONTEXT(ctx); - GET_CONTAINER(con, containerObj, "glAttachObjectARB"); - - if (con != NULL) { - GET_GENERIC(att, obj, "glAttachObjectARB"); - - if (att != NULL) { - (**con).Attach(con, att); - RELEASE_GENERIC(att); - } - RELEASE_CONTAINER(con); - } -} - -GLvoid GLAPIENTRY -_mesa_LinkProgramARB(GLhandleARB programObj) -{ - GET_CURRENT_CONTEXT(ctx); - GET_PROGRAM(pro, programObj, "glLinkProgramARB"); - - if (pro != NULL) { - (**pro).Link(pro); - if (pro == ctx->ShaderObjects.CurrentProgram) { - if ((**pro).GetLinkStatus(pro)) - _mesa_UseProgramObjectARB(programObj); - else - _mesa_UseProgramObjectARB(0); - } - RELEASE_PROGRAM(pro); - } -} - -GLvoid GLAPIENTRY -_mesa_UseProgramObjectARB(GLhandleARB programObj) -{ - GET_CURRENT_CONTEXT(ctx); - struct gl2_program_intf **program = NULL; - - FLUSH_VERTICES(ctx, _NEW_PROGRAM); - - if (programObj != 0) { - GET_PROGRAM(pro, programObj, "glUseProgramObjectARB(program)"); - - if (pro == NULL) - return; - - if ((**pro).GetLinkStatus(pro) == GL_FALSE) { - RELEASE_PROGRAM(pro); - _mesa_error(ctx, GL_INVALID_OPERATION, "glUseProgramObjectARB(not linked)"); - return; - } - - program = pro; - - ctx->ShaderObjects._VertexShaderPresent = - (**pro).IsShaderPresent(pro, GL_VERTEX_SHADER_ARB); - ctx->ShaderObjects._FragmentShaderPresent = - (**pro).IsShaderPresent(pro, GL_FRAGMENT_SHADER_ARB); - } - else { - ctx->ShaderObjects._VertexShaderPresent = GL_FALSE; - ctx->ShaderObjects._FragmentShaderPresent = GL_FALSE; - } - - if (ctx->ShaderObjects.CurrentProgram != NULL) - RELEASE_PROGRAM(ctx->ShaderObjects.CurrentProgram); - ctx->ShaderObjects.CurrentProgram = program; -} - -GLvoid GLAPIENTRY -_mesa_ValidateProgramARB(GLhandleARB programObj) -{ - GET_CURRENT_CONTEXT(ctx); - GET_PROGRAM(pro, programObj, "glValidateProgramARB"); - - if (pro != NULL) { - (**pro).Validate(pro); - RELEASE_PROGRAM(pro); - } -} - - -/** - * Helper function for all the _mesa_Uniform*() functions below. - */ -static INLINE void -uniform(GLint location, GLsizei count, const GLvoid *values, GLenum type, - const char *caller) -{ - GET_CURRENT_CONTEXT(ctx); - GET_CURRENT_LINKED_PROGRAM(pro, caller); - - FLUSH_VERTICES(ctx, _NEW_PROGRAM); - - if (!(**pro).WriteUniform(pro, location, count, values, type)) - _mesa_error(ctx, GL_INVALID_OPERATION, caller); -} - - -GLvoid GLAPIENTRY -_mesa_Uniform1fARB(GLint location, GLfloat v0) -{ - uniform(location, 1, &v0, GL_FLOAT, "glUniform1fARB"); -} - -GLvoid GLAPIENTRY -_mesa_Uniform2fARB(GLint location, GLfloat v0, GLfloat v1) -{ - GLfloat v[2]; - v[0] = v0; - v[1] = v1; - uniform(location, 1, v, GL_FLOAT_VEC2, "glUniform2fARB"); -} - -GLvoid GLAPIENTRY -_mesa_Uniform3fARB(GLint location, GLfloat v0, GLfloat v1, GLfloat v2) -{ - GLfloat v[3]; - v[0] = v0; - v[1] = v1; - v[2] = v2; - uniform(location, 1, v, GL_FLOAT_VEC3, "glUniform3fARB"); -} - -GLvoid GLAPIENTRY -_mesa_Uniform4fARB(GLint location, GLfloat v0, GLfloat v1, GLfloat v2, - GLfloat v3) -{ - GLfloat v[4]; - v[0] = v0; - v[1] = v1; - v[2] = v2; - v[3] = v3; - uniform(location, 1, v, GL_FLOAT_VEC4, "glUniform4fARB"); -} - -GLvoid GLAPIENTRY -_mesa_Uniform1iARB(GLint location, GLint v0) -{ - uniform(location, 1, &v0, GL_INT, "glUniform1iARB"); -} - -GLvoid GLAPIENTRY -_mesa_Uniform2iARB(GLint location, GLint v0, GLint v1) -{ - GLint v[2]; - v[0] = v0; - v[1] = v1; - uniform(location, 1, v, GL_INT_VEC2, "glUniform2iARB"); -} - -GLvoid GLAPIENTRY -_mesa_Uniform3iARB(GLint location, GLint v0, GLint v1, GLint v2) -{ - GLint v[3]; - v[0] = v0; - v[1] = v1; - v[2] = v2; - uniform(location, 1, v, GL_INT_VEC3, "glUniform3iARB"); -} - -GLvoid GLAPIENTRY -_mesa_Uniform4iARB(GLint location, GLint v0, GLint v1, GLint v2, GLint v3) -{ - GLint v[4]; - v[0] = v0; - v[1] = v1; - v[2] = v2; - v[3] = v3; - uniform(location, 1, v, GL_INT_VEC4, "glUniform4iARB"); -} - -GLvoid GLAPIENTRY -_mesa_Uniform1fvARB(GLint location, GLsizei count, const GLfloat * value) -{ - uniform(location, count, value, GL_FLOAT, "glUniform1fvARB"); -} - -GLvoid GLAPIENTRY -_mesa_Uniform2fvARB(GLint location, GLsizei count, const GLfloat * value) -{ - uniform(location, count, value, GL_FLOAT_VEC2, "glUniform2fvARB"); -} - -GLvoid GLAPIENTRY -_mesa_Uniform3fvARB(GLint location, GLsizei count, const GLfloat * value) -{ - uniform(location, count, value, GL_FLOAT_VEC3, "glUniform3fvARB"); -} - -GLvoid GLAPIENTRY -_mesa_Uniform4fvARB(GLint location, GLsizei count, const GLfloat * value) -{ - uniform(location, count, value, GL_FLOAT_VEC4, "glUniform4fvARB"); -} - -GLvoid GLAPIENTRY -_mesa_Uniform1ivARB(GLint location, GLsizei count, const GLint * value) -{ - uniform(location, count, value, GL_INT, "glUniform1ivARB"); -} - -GLvoid GLAPIENTRY -_mesa_Uniform2ivARB(GLint location, GLsizei count, const GLint * value) -{ - uniform(location, count, value, GL_INT_VEC2, "glUniform2ivARB"); -} - -GLvoid GLAPIENTRY -_mesa_Uniform3ivARB(GLint location, GLsizei count, const GLint * value) -{ - uniform(location, count, value, GL_INT_VEC3, "glUniform3ivARB"); -} - -GLvoid GLAPIENTRY -_mesa_Uniform4ivARB(GLint location, GLsizei count, const GLint * value) -{ - uniform(location, count, value, GL_INT_VEC4, "glUniform4ivARB"); -} - - -/** - * Helper function used by UniformMatrix**vARB() functions below. - */ -static void -uniform_matrix(GLint cols, GLint rows, const char *caller, - GLenum matrixType, - GLint location, GLsizei count, GLboolean transpose, - const GLfloat *values) -{ - const GLint matElements = rows * cols; - GET_CURRENT_CONTEXT(ctx); - GET_CURRENT_LINKED_PROGRAM(pro, caller); - - if (values == NULL) { - _mesa_error(ctx, GL_INVALID_VALUE, caller); - return; - } - - FLUSH_VERTICES(ctx, _NEW_PROGRAM); - - if (transpose) { - GLfloat *trans, *pt; - const GLfloat *pv; - GLint i, j, k; - - trans = (GLfloat *) _mesa_malloc(count * matElements * sizeof(GLfloat)); - if (!trans) { - _mesa_error(ctx, GL_OUT_OF_MEMORY, caller); - return; - } - - pt = trans; - pv = values; - for (i = 0; i < count; i++) { - /* transpose from pv matrix into pt matrix */ - for (j = 0; j < cols; j++) { - for (k = 0; k < rows; k++) { - /* XXX verify this */ - pt[j * rows + k] = pv[k * cols + j]; - } - } - pt += matElements; - pv += matElements; - } - - if (!(**pro).WriteUniform(pro, location, count, trans, matrixType)) - _mesa_error(ctx, GL_INVALID_OPERATION, caller); - _mesa_free(trans); - } - else { - if (!(**pro).WriteUniform(pro, location, count, values, matrixType)) - _mesa_error(ctx, GL_INVALID_OPERATION, caller); - } -} - - -GLvoid GLAPIENTRY -_mesa_UniformMatrix2fvARB(GLint location, GLsizei count, GLboolean transpose, - const GLfloat * value) -{ - uniform_matrix(2, 2, "glUniformMatrix2fvARB", GL_FLOAT_MAT2, - location, count, transpose, value); -} - -GLvoid GLAPIENTRY -_mesa_UniformMatrix3fvARB(GLint location, GLsizei count, GLboolean transpose, - const GLfloat * value) -{ - uniform_matrix(3, 3, "glUniformMatrix3fvARB", GL_FLOAT_MAT3, - location, count, transpose, value); -} - -GLvoid GLAPIENTRY -_mesa_UniformMatrix4fvARB(GLint location, GLsizei count, GLboolean transpose, - const GLfloat * value) -{ - uniform_matrix(4, 4, "glUniformMatrix4fvARB", GL_FLOAT_MAT4, - location, count, transpose, value); -} - -static GLboolean -_mesa_get_object_parameter(GLhandleARB obj, GLenum pname, GLvoid * params, - GLboolean * integral, GLint * size) -{ - GET_CURRENT_CONTEXT(ctx); - GLint *ipar = (GLint *) params; - - /* set default values */ - *integral = GL_TRUE; /* indicates param type, TRUE: GLint, FALSE: GLfloat */ - *size = 1; /* param array size */ - - switch (pname) { - case GL_OBJECT_TYPE_ARB: - case GL_OBJECT_DELETE_STATUS_ARB: - case GL_OBJECT_INFO_LOG_LENGTH_ARB: - { - GET_GENERIC(gen, obj, "glGetObjectParameterivARB"); - - if (gen == NULL) - return GL_FALSE; - - switch (pname) { - case GL_OBJECT_TYPE_ARB: - *ipar = (**gen).GetType(gen); - break; - case GL_OBJECT_DELETE_STATUS_ARB: - *ipar = (**gen).GetDeleteStatus(gen); - break; - case GL_OBJECT_INFO_LOG_LENGTH_ARB: - *ipar = (**gen).GetInfoLogLength(gen); - break; - } - - RELEASE_GENERIC(gen); - } - break; - case GL_OBJECT_SUBTYPE_ARB: - case GL_OBJECT_COMPILE_STATUS_ARB: - case GL_OBJECT_SHADER_SOURCE_LENGTH_ARB: - { - GET_SHADER(sha, obj, "glGetObjectParameterivARB"); - - if (sha == NULL) - return GL_FALSE; - - switch (pname) { - case GL_OBJECT_SUBTYPE_ARB: - *ipar = (**sha).GetSubType(sha); - break; - case GL_OBJECT_COMPILE_STATUS_ARB: - *ipar = (**sha).GetCompileStatus(sha); - break; - case GL_OBJECT_SHADER_SOURCE_LENGTH_ARB: - { - const GLcharARB *src = (**sha).GetSource(sha); - if (src == NULL) - *ipar = 0; - else - *ipar = _mesa_strlen(src) + 1; - } - break; - } - - RELEASE_SHADER(sha); - } - break; - case GL_OBJECT_LINK_STATUS_ARB: - case GL_OBJECT_VALIDATE_STATUS_ARB: - case GL_OBJECT_ATTACHED_OBJECTS_ARB: - case GL_OBJECT_ACTIVE_UNIFORMS_ARB: - case GL_OBJECT_ACTIVE_UNIFORM_MAX_LENGTH_ARB: - { - GET_PROGRAM(pro, obj, "glGetObjectParameterivARB"); - - if (pro == NULL) - return GL_FALSE; - - switch (pname) { - case GL_OBJECT_LINK_STATUS_ARB: - *ipar = (**pro).GetLinkStatus(pro); - break; - case GL_OBJECT_VALIDATE_STATUS_ARB: - *ipar = (**pro).GetValidateStatus(pro); - break; - case GL_OBJECT_ATTACHED_OBJECTS_ARB: - *ipar = - (**pro)._container. - GetAttachedCount((struct gl2_container_intf **) (pro)); - break; - case GL_OBJECT_ACTIVE_UNIFORMS_ARB: - *ipar = (**pro).GetActiveUniformCount(pro); - break; - case GL_OBJECT_ACTIVE_UNIFORM_MAX_LENGTH_ARB: - *ipar = (**pro).GetActiveUniformMaxLength(pro); - break; - case GL_OBJECT_ACTIVE_ATTRIBUTES_ARB: - *ipar = (**pro).GetActiveAttribCount(pro); - break; - case GL_OBJECT_ACTIVE_ATTRIBUTE_MAX_LENGTH_ARB: - *ipar = (**pro).GetActiveAttribMaxLength(pro); - break; - } - - RELEASE_PROGRAM(pro); - } - break; - default: - _mesa_error(ctx, GL_INVALID_ENUM, "glGetObjectParameterivARB"); - return GL_FALSE; - } - - return GL_TRUE; -} - -GLvoid GLAPIENTRY -_mesa_GetObjectParameterfvARB(GLhandleARB obj, GLenum pname, GLfloat * params) -{ - GET_CURRENT_CONTEXT(ctx); - GLboolean integral; - GLint size; - - if (params == NULL) { - _mesa_error(ctx, GL_INVALID_VALUE, "glGetObjectParameterfvARB"); - return; - } - - assert(sizeof(GLfloat) == sizeof(GLint)); - - if (_mesa_get_object_parameter(obj, pname, (GLvoid *) params, - &integral, &size)) { - if (integral) { - GLint i; - for (i = 0; i < size; i++) - params[i] = (GLfloat) ((GLint *) params)[i]; - } - } -} - -GLvoid GLAPIENTRY -_mesa_GetObjectParameterivARB(GLhandleARB obj, GLenum pname, GLint * params) -{ - GET_CURRENT_CONTEXT(ctx); - GLboolean integral; - GLint size; - - if (params == NULL) { - _mesa_error(ctx, GL_INVALID_VALUE, "glGetObjectParameterivARB"); - return; - } - - assert(sizeof(GLfloat) == sizeof(GLint)); - - if (_mesa_get_object_parameter(obj, pname, (GLvoid *) params, - &integral, &size)) { - if (!integral) { - GLint i; - for (i = 0; i < size; i++) - params[i] = (GLint) ((GLfloat *) params)[i]; - } - } -} - - -/** - * Copy string from <src> to <dst>, up to maxLength characters, returning - * length of <dst> in <length>. - * \param src the strings source - * \param maxLength max chars to copy - * \param length returns numberof chars copied - * \param dst the string destination - */ -static GLvoid -copy_string(const GLcharARB * src, GLsizei maxLength, GLsizei * length, - GLcharARB * dst) -{ - GLsizei len; - for (len = 0; len < maxLength - 1 && src && src[len]; len++) - dst[len] = src[len]; - if (maxLength > 0) - dst[len] = 0; - if (length) - *length = len; -} - - -GLvoid GLAPIENTRY -_mesa_GetInfoLogARB(GLhandleARB obj, GLsizei maxLength, GLsizei * length, - GLcharARB * infoLog) -{ - GET_CURRENT_CONTEXT(ctx); - GET_GENERIC(gen, obj, "glGetInfoLogARB"); - - if (gen == NULL) - return; - - if (infoLog == NULL) - _mesa_error(ctx, GL_INVALID_VALUE, "glGetInfoLogARB"); - else { - GLsizei actualsize = (**gen).GetInfoLogLength(gen); - if (actualsize > maxLength) - actualsize = maxLength; - (**gen).GetInfoLog(gen, actualsize, infoLog); - if (length != NULL) - *length = (actualsize > 0) ? actualsize - 1 : 0; - } - RELEASE_GENERIC(gen); -} - -GLvoid GLAPIENTRY -_mesa_GetAttachedObjectsARB(GLhandleARB containerObj, GLsizei maxCount, - GLsizei * count, GLhandleARB * obj) -{ - GET_CURRENT_CONTEXT(ctx); - GET_CONTAINER(con, containerObj, "glGetAttachedObjectsARB"); - - if (con == NULL) - return; - - if (obj == NULL) - _mesa_error(ctx, GL_INVALID_VALUE, "glGetAttachedObjectsARB"); - else { - GLsizei cnt, i; - - cnt = (**con).GetAttachedCount(con); - if (cnt > maxCount) - cnt = maxCount; - if (count != NULL) - *count = cnt; - - for (i = 0; i < cnt; i++) { - struct gl2_generic_intf **x = (**con).GetAttached(con, i); - obj[i] = (**x).GetName(x); - RELEASE_GENERIC(x); - } - } - RELEASE_CONTAINER(con); -} - -GLint GLAPIENTRY -_mesa_GetUniformLocationARB(GLhandleARB programObj, const GLcharARB * name) -{ - GET_CURRENT_CONTEXT(ctx); - GLint loc = -1; - GET_LINKED_PROGRAM(pro, programObj, "glGetUniformLocationARB"); - - if (!pro) - return -1; - - if (name == NULL) - _mesa_error(ctx, GL_INVALID_VALUE, "glGetUniformLocationARB"); - else { - if (!IS_NAME_WITH_GL_PREFIX(name)) - loc = (**pro).GetUniformLocation(pro, name); - } - RELEASE_PROGRAM(pro); - return loc; -} - -GLvoid GLAPIENTRY -_mesa_GetActiveUniformARB(GLhandleARB programObj, GLuint index, - GLsizei maxLength, GLsizei * length, GLint * size, - GLenum * type, GLcharARB * name) -{ - GET_CURRENT_CONTEXT(ctx); - GET_PROGRAM(pro, programObj, "glGetActiveUniformARB"); - - if (pro == NULL) - return; - - if (size == NULL || type == NULL || name == NULL) - _mesa_error(ctx, GL_INVALID_VALUE, "glGetActiveUniformARB"); - else { - if (index < (**pro).GetActiveUniformCount(pro)) - (**pro).GetActiveUniform(pro, index, maxLength, length, size, type, - name); - else - _mesa_error(ctx, GL_INVALID_VALUE, "glGetActiveUniformARB"); - } - RELEASE_PROGRAM(pro); -} - -GLvoid GLAPIENTRY -_mesa_GetUniformfvARB(GLhandleARB programObj, GLint location, GLfloat * params) -{ - GET_CURRENT_CONTEXT(ctx); - GET_LINKED_PROGRAM(pro, programObj, "glGetUniformfvARB"); - - if (!pro) - return; - - if (!(**pro).ReadUniform(pro, location, 1, params, GL_FLOAT)) - _mesa_error(ctx, GL_INVALID_OPERATION, "glGetUniformfvARB"); - - RELEASE_PROGRAM(pro); -} - -GLvoid GLAPIENTRY -_mesa_GetUniformivARB(GLhandleARB programObj, GLint location, GLint * params) -{ - GET_CURRENT_CONTEXT(ctx); - GET_LINKED_PROGRAM(pro, programObj, "glGetUniformivARB"); - - if (!pro) - return; - - if (!(**pro).ReadUniform(pro, location, 1, params, GL_INT)) - _mesa_error(ctx, GL_INVALID_OPERATION, "glGetUniformivARB"); - RELEASE_PROGRAM(pro); -} - -GLvoid GLAPIENTRY -_mesa_GetShaderSourceARB(GLhandleARB obj, GLsizei maxLength, GLsizei * length, - GLcharARB * source) -{ - GET_CURRENT_CONTEXT(ctx); - GET_SHADER(sha, obj, "glGetShaderSourceARB"); - - if (sha == NULL) - return; - - if (source == NULL) - _mesa_error(ctx, GL_INVALID_VALUE, "glGetShaderSourceARB"); - else - copy_string((**sha).GetSource(sha), maxLength, length, source); - RELEASE_SHADER(sha); -} - -/* GL_ARB_vertex_shader */ - -GLvoid GLAPIENTRY -_mesa_BindAttribLocationARB(GLhandleARB programObj, GLuint index, - const GLcharARB * name) -{ - GET_CURRENT_CONTEXT(ctx); - GET_PROGRAM(pro, programObj, "glBindAttribLocationARB"); - - if (pro == NULL) - return; - - if (name == NULL || index >= MAX_VERTEX_ATTRIBS) - _mesa_error(ctx, GL_INVALID_VALUE, "glBindAttribLocationARB"); - else if (IS_NAME_WITH_GL_PREFIX(name)) - _mesa_error(ctx, GL_INVALID_OPERATION, "glBindAttribLocationARB"); - else - (**pro).OverrideAttribBinding(pro, index, name); - RELEASE_PROGRAM(pro); -} - -GLvoid GLAPIENTRY -_mesa_GetActiveAttribARB(GLhandleARB programObj, GLuint index, - GLsizei maxLength, GLsizei * length, GLint * size, - GLenum * type, GLcharARB * name) -{ - GET_CURRENT_CONTEXT(ctx); - GET_PROGRAM(pro, programObj, "glGetActiveAttribARB"); - - if (pro == NULL) - return; - - if (name == NULL || index >= (**pro).GetActiveAttribCount(pro)) - _mesa_error(ctx, GL_INVALID_VALUE, "glGetActiveAttribARB"); - else - (**pro).GetActiveAttrib(pro, index, maxLength, length, size, type, - name); - RELEASE_PROGRAM(pro); -} - -GLint GLAPIENTRY -_mesa_GetAttribLocationARB(GLhandleARB programObj, const GLcharARB * name) -{ - GET_CURRENT_CONTEXT(ctx); - GLint loc = -1; - GET_LINKED_PROGRAM(pro, programObj, "glGetAttribLocationARB"); - - if (!pro) - return -1; - - if (name == NULL) - _mesa_error(ctx, GL_INVALID_VALUE, "glGetAttribLocationARB"); - else if (!IS_NAME_WITH_GL_PREFIX(name)) - loc = (**pro).GetAttribLocation(pro, name); - RELEASE_PROGRAM(pro); - return loc; -} - - -/** - ** OpenGL 2.0 functions which basically wrap the ARB_shader functions - **/ - -void GLAPIENTRY -_mesa_AttachShader(GLuint program, GLuint shader) -{ - _mesa_AttachObjectARB(program, shader); -} - - -GLuint GLAPIENTRY -_mesa_CreateShader(GLenum type) -{ - return (GLuint) _mesa_CreateShaderObjectARB(type); -} - -GLuint GLAPIENTRY -_mesa_CreateProgram(void) -{ - return (GLuint) _mesa_CreateProgramObjectARB(); -} - -void GLAPIENTRY -_mesa_DeleteProgram(GLuint program) -{ - _mesa_DeleteObjectARB(program); -} - - -void GLAPIENTRY -_mesa_DeleteShader(GLuint shader) -{ - _mesa_DeleteObjectARB(shader); -} - -void GLAPIENTRY -_mesa_DetachShader(GLuint program, GLuint shader) -{ - _mesa_DetachObjectARB(program, shader); -} - -void GLAPIENTRY -_mesa_GetAttachedShaders(GLuint program, GLsizei maxCount, - GLsizei *count, GLuint *obj) -{ - _mesa_GetAttachedObjectsARB(program, maxCount, count, obj); -} - -void GLAPIENTRY -_mesa_GetProgramiv(GLuint program, GLenum pname, GLint *params) -{ - GET_CURRENT_CONTEXT(ctx); - GET_PROGRAM(pro, program, "glGetProgramiv"); - - if (!pro) - return; - - switch (pname) { - case GL_DELETE_STATUS: - *params = (**pro)._container._generic.GetDeleteStatus((struct gl2_generic_intf **) pro); - break; - case GL_LINK_STATUS: - *params = (**pro).GetLinkStatus(pro); - break; - case GL_VALIDATE_STATUS: - *params = (**pro).GetValidateStatus(pro); - break; - case GL_INFO_LOG_LENGTH: - *params = (**pro)._container._generic.GetInfoLogLength( (struct gl2_generic_intf **) pro ); - break; - case GL_ATTACHED_SHADERS: - *params = (**pro)._container.GetAttachedCount( (struct gl2_container_intf **) pro ); - break; - case GL_ACTIVE_ATTRIBUTES: - *params = (**pro).GetActiveAttribCount(pro); - break; - case GL_ACTIVE_ATTRIBUTE_MAX_LENGTH: - *params = (**pro).GetActiveAttribMaxLength(pro); - break; - case GL_ACTIVE_UNIFORMS: - *params = (**pro).GetActiveUniformCount(pro); - break; - case GL_ACTIVE_UNIFORM_MAX_LENGTH: - *params = (**pro).GetActiveUniformMaxLength(pro); - break; - default: - _mesa_error(ctx, GL_INVALID_ENUM, "glGetProgramiv(pname)"); - return; - } -} - -void GLAPIENTRY -_mesa_GetProgramInfoLog(GLuint program, GLsizei bufSize, - GLsizei *length, GLchar *infoLog) -{ - _mesa_GetInfoLogARB(program, bufSize, length, infoLog); -} - -void GLAPIENTRY -_mesa_GetShaderiv(GLuint shader, GLenum pname, GLint *params) -{ - GET_CURRENT_CONTEXT(ctx); - GET_SHADER(sh, shader, "glGetShaderiv"); - - if (!sh) - return; - - switch (pname) { - case GL_SHADER_TYPE: - *params = (**sh).GetSubType(sh); - break; - case GL_DELETE_STATUS: - *params = (**sh)._generic.GetDeleteStatus((struct gl2_generic_intf **) sh); - break; - case GL_COMPILE_STATUS: - *params = (**sh).GetCompileStatus(sh); - break; - case GL_INFO_LOG_LENGTH: - *params = (**sh)._generic.GetInfoLogLength((struct gl2_generic_intf **)sh); - break; - case GL_SHADER_SOURCE_LENGTH: - { - const GLchar *src = (**sh).GetSource(sh); - *params = src ? (_mesa_strlen(src) + 1) : 0; - } - break; - default: - _mesa_error(ctx, GL_INVALID_ENUM, "glGetShaderiv(pname)"); - return; - } -} - -void GLAPIENTRY -_mesa_GetShaderInfoLog(GLuint shader, GLsizei bufSize, - GLsizei *length, GLchar *infoLog) -{ - _mesa_GetInfoLogARB(shader, bufSize, length, infoLog); -} - -GLboolean GLAPIENTRY -_mesa_IsProgram(GLuint program) -{ - GET_CURRENT_CONTEXT(ctx); - GET_PROGRAM(pro, program, "glIsProgram"); - if (pro) { - RELEASE_PROGRAM(pro); - return GL_TRUE; - } - else { - return GL_FALSE; - } -} - -GLboolean GLAPIENTRY -_mesa_IsShader(GLuint shader) -{ - GET_CURRENT_CONTEXT(ctx); - GET_SHADER(sh, shader, "glIsProgram"); - if (sh) { - RELEASE_SHADER(sh); - return GL_TRUE; - } - else { - return GL_FALSE; - } -} - - -/** - ** 2.1 functions - **/ - -void GLAPIENTRY -_mesa_UniformMatrix2x3fv(GLint location, GLsizei count, GLboolean transpose, - const GLfloat *value) -{ - uniform_matrix(2, 3, "glUniformMatrix2x3fv", GL_FLOAT_MAT2x3, - location, count, transpose, value); -} - -void GLAPIENTRY -_mesa_UniformMatrix3x2fv(GLint location, GLsizei count, GLboolean transpose, - const GLfloat *value) -{ - uniform_matrix(3, 2, "glUniformMatrix3x2fv", GL_FLOAT_MAT3x2, - location, count, transpose, value); -} - -void GLAPIENTRY -_mesa_UniformMatrix2x4fv(GLint location, GLsizei count, GLboolean transpose, - const GLfloat *value) -{ - uniform_matrix(2, 4, "glUniformMatrix2x4fv", GL_FLOAT_MAT2x4, - location, count, transpose, value); -} - -void GLAPIENTRY -_mesa_UniformMatrix4x2fv(GLint location, GLsizei count, GLboolean transpose, - const GLfloat *value) -{ - uniform_matrix(4, 2, "glUniformMatrix4x2fv", GL_FLOAT_MAT4x2, - location, count, transpose, value); -} - -void GLAPIENTRY -_mesa_UniformMatrix3x4fv(GLint location, GLsizei count, GLboolean transpose, - const GLfloat *value) -{ - uniform_matrix(3, 4, "glUniformMatrix3x4fv", GL_FLOAT_MAT3x4, - location, count, transpose, value); -} - -void GLAPIENTRY -_mesa_UniformMatrix4x3fv(GLint location, GLsizei count, GLboolean transpose, - const GLfloat *value) -{ - uniform_matrix(4, 3, "glUniformMatrix4x3fv", GL_FLOAT_MAT4x3, - location, count, transpose, value); -} - - - - - -#endif - -GLvoid -_mesa_init_shaderobjects(GLcontext * ctx) -{ - ctx->ShaderObjects.CurrentProgram = NULL; - ctx->ShaderObjects._FragmentShaderPresent = GL_FALSE; - ctx->ShaderObjects._VertexShaderPresent = GL_FALSE; - - _mesa_init_shaderobjects_3dlabs(ctx); -} diff --git a/src/mesa/shader/shaderobjects_3dlabs.c b/src/mesa/shader/shaderobjects_3dlabs.c deleted file mode 100755 index 3ead1a1784..0000000000 --- a/src/mesa/shader/shaderobjects_3dlabs.c +++ /dev/null @@ -1,2144 +0,0 @@ -/* - * Mesa 3-D graphics library - * Version: 6.5 - * - * Copyright (C) 2005-2006 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. - */ - -/** - * \file shaderobjects_3dlabs.c - * shader objects definitions for 3dlabs compiler - * \author Michal Krol - */ - -/* Set this to 1 when we are ready to use 3dlabs' front-end */ -#define USE_3DLABS_FRONTEND 0 - -#include "imports.h" -#include "hash.h" -#include "macros.h" -#include "shaderobjects.h" -#include "shaderobjects_3dlabs.h" - -#if USE_3DLABS_FRONTEND -#include "slang_mesa.h" -#include "Public/ShaderLang.h" -#else -#include "slang_link.h" -#endif - -#if FEATURE_ARB_shader_objects - -struct gl2_unknown_obj -{ - GLuint reference_count; - void (*_destructor) (struct gl2_unknown_intf **); -}; - -struct gl2_unknown_impl -{ - struct gl2_unknown_intf *_vftbl; - struct gl2_unknown_obj _obj; -}; - -static void -_unknown_destructor(struct gl2_unknown_intf **intf) -{ -} - -static void -_unknown_AddRef(struct gl2_unknown_intf **intf) -{ - struct gl2_unknown_impl *impl = (struct gl2_unknown_impl *) intf; - - impl->_obj.reference_count++; -} - -static void -_unknown_Release(struct gl2_unknown_intf **intf) -{ - struct gl2_unknown_impl *impl = (struct gl2_unknown_impl *) intf; - - impl->_obj.reference_count--; - if (impl->_obj.reference_count == 0) { - impl->_obj._destructor(intf); - _mesa_free((void *) intf); - } -} - -static struct gl2_unknown_intf ** -_unknown_QueryInterface(struct gl2_unknown_intf **intf, enum gl2_uiid uiid) -{ - if (uiid == UIID_UNKNOWN) { - (**intf).AddRef(intf); - return intf; - } - return NULL; -} - -static struct gl2_unknown_intf _unknown_vftbl = { - _unknown_AddRef, - _unknown_Release, - _unknown_QueryInterface -}; - -static void -_unknown_constructor(struct gl2_unknown_impl *impl) -{ - impl->_vftbl = &_unknown_vftbl; - impl->_obj.reference_count = 1; - impl->_obj._destructor = _unknown_destructor; -} - -struct gl2_unkinner_obj -{ - struct gl2_unknown_intf **unkouter; -}; - -struct gl2_unkinner_impl -{ - struct gl2_unknown_intf *_vftbl; - struct gl2_unkinner_obj _obj; -}; - -static void -_unkinner_destructor(struct gl2_unknown_intf **intf) -{ -} - -static void -_unkinner_AddRef(struct gl2_unknown_intf **intf) -{ - struct gl2_unkinner_impl *impl = (struct gl2_unkinner_impl *) intf; - - (**impl->_obj.unkouter).AddRef(impl->_obj.unkouter); -} - -static void -_unkinner_Release(struct gl2_unknown_intf **intf) -{ - struct gl2_unkinner_impl *impl = (struct gl2_unkinner_impl *) intf; - - (**impl->_obj.unkouter).Release(impl->_obj.unkouter); -} - -static struct gl2_unknown_intf ** -_unkinner_QueryInterface(struct gl2_unknown_intf **intf, enum gl2_uiid uiid) -{ - struct gl2_unkinner_impl *impl = (struct gl2_unkinner_impl *) intf; - - return (**impl->_obj.unkouter).QueryInterface(impl->_obj.unkouter, uiid); -} - -static struct gl2_unknown_intf _unkinner_vftbl = { - _unkinner_AddRef, - _unkinner_Release, - _unkinner_QueryInterface -}; - -static void -_unkinner_constructor(struct gl2_unkinner_impl *impl, - struct gl2_unknown_intf **outer) -{ - impl->_vftbl = &_unkinner_vftbl; - impl->_obj.unkouter = outer; -} - -struct gl2_generic_obj -{ - struct gl2_unknown_obj _unknown; - GLhandleARB name; - GLboolean delete_status; - GLcharARB *info_log; -}; - -struct gl2_generic_impl -{ - struct gl2_generic_intf *_vftbl; - struct gl2_generic_obj _obj; -}; - -static void -_generic_destructor(struct gl2_unknown_intf **intf) -{ - GET_CURRENT_CONTEXT(ctx); - struct gl2_generic_impl *impl = (struct gl2_generic_impl *) intf; - - _mesa_free((void *) impl->_obj.info_log); - - _glthread_LOCK_MUTEX(ctx->Shared->Mutex); - _mesa_HashRemove(ctx->Shared->GL2Objects, impl->_obj.name); - _glthread_UNLOCK_MUTEX(ctx->Shared->Mutex); - - _unknown_destructor(intf); -} - -static struct gl2_unknown_intf ** -_generic_QueryInterface(struct gl2_unknown_intf **intf, enum gl2_uiid uiid) -{ - if (uiid == UIID_GENERIC) { - (**intf).AddRef(intf); - return intf; - } - return _unknown_QueryInterface(intf, uiid); -} - -static void -_generic_Delete(struct gl2_generic_intf **intf) -{ - struct gl2_generic_impl *impl = (struct gl2_generic_impl *) intf; - - if (impl->_obj.delete_status == GL_FALSE) { - impl->_obj.delete_status = GL_TRUE; - (**intf)._unknown.Release((struct gl2_unknown_intf **) intf); - } -} - -static GLhandleARB -_generic_GetName(struct gl2_generic_intf **intf) -{ - struct gl2_generic_impl *impl = (struct gl2_generic_impl *) intf; - - return impl->_obj.name; -} - -static GLboolean -_generic_GetDeleteStatus(struct gl2_generic_intf **intf) -{ - struct gl2_generic_impl *impl = (struct gl2_generic_impl *) intf; - - return impl->_obj.delete_status; -} - -static GLvoid -_generic_GetInfoLog(struct gl2_generic_intf **intf, GLsizei maxlen, - GLcharARB * infolog) -{ - struct gl2_generic_impl *impl = (struct gl2_generic_impl *) (intf); - - if (maxlen > 0) { - _mesa_strncpy(infolog, impl->_obj.info_log, maxlen - 1); - infolog[maxlen - 1] = '\0'; - } -} - -static GLsizei -_generic_GetInfoLogLength(struct gl2_generic_intf **intf) -{ - struct gl2_generic_impl *impl = (struct gl2_generic_impl *) (intf); - - if (impl->_obj.info_log == NULL) - return 1; - return _mesa_strlen(impl->_obj.info_log) + 1; -} - -static struct gl2_generic_intf _generic_vftbl = { - { - _unknown_AddRef, - _unknown_Release, - _generic_QueryInterface}, - _generic_Delete, - NULL, /* abstract GetType */ - _generic_GetName, - _generic_GetDeleteStatus, - _generic_GetInfoLog, - _generic_GetInfoLogLength -}; - -static void -_generic_constructor(struct gl2_generic_impl *impl) -{ - GET_CURRENT_CONTEXT(ctx); - - _unknown_constructor((struct gl2_unknown_impl *) impl); - impl->_vftbl = &_generic_vftbl; - impl->_obj._unknown._destructor = _generic_destructor; - impl->_obj.delete_status = GL_FALSE; - impl->_obj.info_log = NULL; - - _glthread_LOCK_MUTEX(ctx->Shared->Mutex); - impl->_obj.name = _mesa_HashFindFreeKeyBlock(ctx->Shared->GL2Objects, 1); - _mesa_HashInsert(ctx->Shared->GL2Objects, impl->_obj.name, (void *) impl); - _glthread_UNLOCK_MUTEX(ctx->Shared->Mutex); -} - -struct gl2_container_obj -{ - struct gl2_generic_obj _generic; - struct gl2_generic_intf ***attached; - GLuint attached_count; -}; - -struct gl2_container_impl -{ - struct gl2_container_intf *_vftbl; - struct gl2_container_obj _obj; -}; - -static void -_container_destructor(struct gl2_unknown_intf **intf) -{ - struct gl2_container_impl *impl = (struct gl2_container_impl *) intf; - GLuint i; - - for (i = 0; i < impl->_obj.attached_count; i++) { - struct gl2_generic_intf **x = impl->_obj.attached[i]; - (**x)._unknown.Release((struct gl2_unknown_intf **) x); - } - - _generic_destructor(intf); -} - -static struct gl2_unknown_intf ** -_container_QueryInterface(struct gl2_unknown_intf **intf, enum gl2_uiid uiid) -{ - if (uiid == UIID_CONTAINER) { - (**intf).AddRef(intf); - return intf; - } - return _generic_QueryInterface(intf, uiid); -} - -static GLboolean -_container_Attach(struct gl2_container_intf **intf, - struct gl2_generic_intf **att) -{ - GET_CURRENT_CONTEXT(ctx); - struct gl2_container_impl *impl = (struct gl2_container_impl *) intf; - GLuint i; - - for (i = 0; i < impl->_obj.attached_count; i++) - if (impl->_obj.attached[i] == att) { - _mesa_error(ctx, GL_INVALID_OPERATION, "_container_Attach"); - return GL_FALSE; - } - - impl->_obj.attached = (struct gl2_generic_intf ***) - _mesa_realloc(impl->_obj.attached, - impl->_obj.attached_count * sizeof(*impl->_obj.attached), - (impl->_obj.attached_count + 1) * sizeof(*impl->_obj.attached)); - if (impl->_obj.attached == NULL) - return GL_FALSE; - - impl->_obj.attached[impl->_obj.attached_count] = att; - impl->_obj.attached_count++; - (**att)._unknown.AddRef((struct gl2_unknown_intf **) att); - return GL_TRUE; -} - -static GLboolean -_container_Detach(struct gl2_container_intf **intf, - struct gl2_generic_intf **att) -{ - GET_CURRENT_CONTEXT(ctx); - struct gl2_container_impl *impl = (struct gl2_container_impl *) intf; - GLuint i, j; - - for (i = 0; i < impl->_obj.attached_count; i++) - if (impl->_obj.attached[i] == att) { - for (j = i; j < impl->_obj.attached_count - 1; j++) - impl->_obj.attached[j] = impl->_obj.attached[j + 1]; - impl->_obj.attached = (struct gl2_generic_intf ***) - _mesa_realloc(impl->_obj.attached, - impl->_obj.attached_count * sizeof(*impl->_obj.attached), - (impl->_obj.attached_count - 1) * sizeof(*impl->_obj.attached)); - impl->_obj.attached_count--; - (**att)._unknown.Release((struct gl2_unknown_intf **) att); - return GL_TRUE; - } - - _mesa_error(ctx, GL_INVALID_OPERATION, "_container_Detach"); - return GL_FALSE; -} - -static GLsizei -_container_GetAttachedCount(struct gl2_container_intf **intf) -{ - struct gl2_container_impl *impl = (struct gl2_container_impl *) intf; - - return impl->_obj.attached_count; -} - -static struct gl2_generic_intf ** -_container_GetAttached(struct gl2_container_intf **intf, GLuint index) -{ - struct gl2_container_impl *impl = (struct gl2_container_impl *) intf; - - (**impl->_obj.attached[index])._unknown.AddRef((struct gl2_unknown_intf **) - impl->_obj.attached[index]); - return impl->_obj.attached[index]; -} - -static struct gl2_container_intf _container_vftbl = { - { - { - _unknown_AddRef, - _unknown_Release, - _container_QueryInterface - }, - _generic_Delete, - NULL, /* abstract GetType */ - _generic_GetName, - _generic_GetDeleteStatus, - _generic_GetInfoLog, - _generic_GetInfoLogLength - }, - _container_Attach, - _container_Detach, - _container_GetAttachedCount, - _container_GetAttached -}; - -static void -_container_constructor(struct gl2_container_impl *impl) -{ - _generic_constructor((struct gl2_generic_impl *) impl); - impl->_vftbl = &_container_vftbl; - impl->_obj._generic._unknown._destructor = _container_destructor; - impl->_obj.attached = NULL; - impl->_obj.attached_count = 0; -} - -struct gl2_3dlabs_shhandle_obj -{ - struct gl2_unkinner_obj _unknown; -#if USE_3DLABS_FRONTEND - ShHandle handle; -#endif -}; - -struct gl2_3dlabs_shhandle_impl -{ - struct gl2_3dlabs_shhandle_intf *_vftbl; - struct gl2_3dlabs_shhandle_obj _obj; -}; - -static void -_3dlabs_shhandle_destructor(struct gl2_unknown_intf **intf) -{ -#if USE_3DLABS_FRONTEND - struct gl2_3dlabs_shhandle_impl *impl = - (struct gl2_3dlabs_shhandle_impl *) intf; - ShDestruct(impl->_obj.handle); -#endif - _unkinner_destructor(intf); -} - -static GLvoid * -_3dlabs_shhandle_GetShHandle(struct gl2_3dlabs_shhandle_intf **intf) -{ -#if USE_3DLABS_FRONTEND - struct gl2_3dlabs_shhandle_impl *impl = - (struct gl2_3dlabs_shhandle_impl *) intf; - return impl->_obj.handle; -#else - return NULL; -#endif -} - -static struct gl2_3dlabs_shhandle_intf _3dlabs_shhandle_vftbl = { - { - _unkinner_AddRef, - _unkinner_Release, - _unkinner_QueryInterface}, - _3dlabs_shhandle_GetShHandle -}; - -static void -_3dlabs_shhandle_constructor(struct gl2_3dlabs_shhandle_impl *impl, - struct gl2_unknown_intf **outer) -{ - _unkinner_constructor((struct gl2_unkinner_impl *) impl, outer); - impl->_vftbl = &_3dlabs_shhandle_vftbl; -#if USE_3DLABS_FRONTEND - impl->_obj.handle = NULL; -#endif -} - -struct gl2_shader_obj -{ - struct gl2_generic_obj _generic; - struct gl2_3dlabs_shhandle_impl _3dlabs_shhandle; - GLboolean compile_status; - GLcharARB *source; - GLint *offsets; - GLsizei offset_count; - slang_code_object code; -}; - -struct gl2_shader_impl -{ - struct gl2_shader_intf *_vftbl; - struct gl2_shader_obj _obj; -}; - -static void -_shader_destructor(struct gl2_unknown_intf **intf) -{ - struct gl2_shader_impl *impl = (struct gl2_shader_impl *) intf; - - _mesa_free((void *) impl->_obj.source); - _mesa_free((void *) impl->_obj.offsets); - _slang_code_object_dtr(&impl->_obj.code); - _3dlabs_shhandle_destructor((struct gl2_unknown_intf **) &impl->_obj. - _3dlabs_shhandle._vftbl); - _generic_destructor(intf); -} - -static struct gl2_unknown_intf ** -_shader_QueryInterface(struct gl2_unknown_intf **intf, enum gl2_uiid uiid) -{ -#if USE_3DLABS_FRONTEND - struct gl2_shader_impl *impl = (struct gl2_shader_impl *) intf; -#endif - - if (uiid == UIID_SHADER) { - (**intf).AddRef(intf); - return intf; - } -#if USE_3DLABS_FRONTEND - if (uiid == UIID_3DLABS_SHHANDLE) { - (**intf).AddRef(intf); - return (struct gl2_unknown_intf **) &impl->_obj._3dlabs_shhandle._vftbl; - } -#endif - return _generic_QueryInterface(intf, uiid); -} - -static GLenum -_shader_GetType(struct gl2_generic_intf **intf) -{ - return GL_SHADER_OBJECT_ARB; -} - -static GLvoid -_shader_GetInfoLog(struct gl2_generic_intf **intf, GLsizei maxlen, - GLcharARB * infolog) -{ - struct gl2_shader_impl *impl = (struct gl2_shader_impl *) (intf); - - if (maxlen > 0) { - if (impl->_obj._generic.info_log != NULL) { - GLsizei len = _mesa_strlen(impl->_obj._generic.info_log); - if (len > maxlen - 1) - len = maxlen - 1; - _mesa_memcpy(infolog, impl->_obj._generic.info_log, len); - infolog += len; - maxlen -= len; - } - if (impl->_obj.code.machine.infolog != NULL && - impl->_obj.code.machine.infolog->text != NULL) { - GLsizei len = _mesa_strlen(impl->_obj.code.machine.infolog->text); - if (len > maxlen - 1) - len = maxlen - 1; - _mesa_memcpy(infolog, impl->_obj.code.machine.infolog->text, len); - } - infolog[maxlen - 1] = '\0'; - } -} - -static GLsizei -_shader_GetInfoLogLength(struct gl2_generic_intf **intf) -{ - struct gl2_shader_impl *impl = (struct gl2_shader_impl *) (intf); - GLsizei length = 1; - - if (impl->_obj._generic.info_log != NULL) - length += _mesa_strlen(impl->_obj._generic.info_log); - if (impl->_obj.code.machine.infolog != NULL && - impl->_obj.code.machine.infolog->text != NULL) - length += _mesa_strlen(impl->_obj.code.machine.infolog->text); - return length; -} - -static GLboolean -_shader_GetCompileStatus(struct gl2_shader_intf **intf) -{ - struct gl2_shader_impl *impl = (struct gl2_shader_impl *) intf; - - return impl->_obj.compile_status; -} - -static GLvoid -_shader_SetSource(struct gl2_shader_intf **intf, GLcharARB * src, GLint * off, - GLsizei cnt) -{ - struct gl2_shader_impl *impl = (struct gl2_shader_impl *) intf; - - _mesa_free((void *) impl->_obj.source); - impl->_obj.source = src; - _mesa_free((void *) impl->_obj.offsets); - impl->_obj.offsets = off; - impl->_obj.offset_count = cnt; -} - -static const GLcharARB * -_shader_GetSource(struct gl2_shader_intf **intf) -{ - struct gl2_shader_impl *impl = (struct gl2_shader_impl *) intf; - - return impl->_obj.source; -} - -static GLvoid -_shader_Compile(struct gl2_shader_intf **intf) -{ - struct gl2_shader_impl *impl = (struct gl2_shader_impl *) intf; -#if USE_3DLABS_FRONTEND - char **strings; - TBuiltInResource res; -#else - slang_unit_type type; - slang_info_log info_log; -#endif - - impl->_obj.compile_status = GL_FALSE; - _mesa_free((void *) impl->_obj._generic.info_log); - impl->_obj._generic.info_log = NULL; - -#if USE_3DLABS_FRONTEND - /* 3dlabs compiler expects us to feed it with null-terminated string array, - we've got only one big string with offsets, so we must split it; but when - there's only one string to deal with, we pass its address directly */ - - if (impl->_obj.offset_count <= 1) - strings = &impl->_obj.source; - else { - GLsizei i, offset = 0; - - strings = - (char **) _mesa_malloc(impl->_obj.offset_count * sizeof(char *)); - if (strings == NULL) - return; - - for (i = 0; i < impl->_obj.offset_count; i++) { - GLsizei size = impl->_obj.offsets[i] - offset; - - strings[i] = (char *) _mesa_malloc((size + 1) * sizeof(char)); - if (strings[i] == NULL) { - GLsizei j; - - for (j = 0; j < i; j++) - _mesa_free(strings[j]); - _mesa_free(strings); - return; - } - - _mesa_memcpy(strings[i], impl->_obj.source + offset, - size * sizeof(char)); - strings[i][size] = '\0'; - offset = impl->_obj.offsets[i]; - } - } - - /* TODO set these fields to some REAL numbers */ - res.maxLights = 8; - res.maxClipPlanes = 6; - res.maxTextureUnits = 2; - res.maxTextureCoords = 2; - res.maxVertexAttribs = 8; - res.maxVertexUniformComponents = 64; - res.maxVaryingFloats = 8; - res.maxVertexTextureImageUnits = 2; - res.maxCombinedTextureImageUnits = 2; - res.maxTextureImageUnits = 2; - res.maxFragmentUniformComponents = 64; - res.maxDrawBuffers = 1; - - if (ShCompile - (impl->_obj._3dlabs_shhandle._obj.handle, strings, - impl->_obj.offset_count, EShOptFull, &res, 0)) - impl->_obj.compile_status = GL_TRUE; - if (impl->_obj.offset_count > 1) { - GLsizei i; - - for (i = 0; i < impl->_obj.offset_count; i++) - _mesa_free(strings[i]); - _mesa_free(strings); - } - - impl->_obj._generic.info_log = - _mesa_strdup(ShGetInfoLog(impl->_obj._3dlabs_shhandle._obj.handle)); -#else - if (impl->_vftbl->GetSubType(intf) == GL_FRAGMENT_SHADER) - type = slang_unit_fragment_shader; - else - type = slang_unit_vertex_shader; - slang_info_log_construct(&info_log); - if (_slang_compile(impl->_obj.source, &impl->_obj.code, type, &info_log)) - impl->_obj.compile_status = GL_TRUE; - if (info_log.text != NULL) - impl->_obj._generic.info_log = _mesa_strdup(info_log.text); - else if (impl->_obj.compile_status) - impl->_obj._generic.info_log = _mesa_strdup("Compile OK.\n"); - else - impl->_obj._generic.info_log = _mesa_strdup("Compile failed.\n"); - slang_info_log_destruct(&info_log); -#endif -} - -static struct gl2_shader_intf _shader_vftbl = { - { - { - _unknown_AddRef, - _unknown_Release, - _shader_QueryInterface - }, - _generic_Delete, - _shader_GetType, - _generic_GetName, - _generic_GetDeleteStatus, - _shader_GetInfoLog, - _shader_GetInfoLogLength - }, - NULL, /* abstract GetSubType */ - _shader_GetCompileStatus, - _shader_SetSource, - _shader_GetSource, - _shader_Compile -}; - -static void -_shader_constructor(struct gl2_shader_impl *impl) -{ - _generic_constructor((struct gl2_generic_impl *) impl); - _3dlabs_shhandle_constructor(&impl->_obj._3dlabs_shhandle, - (struct gl2_unknown_intf **) - &impl->_vftbl); - impl->_vftbl = &_shader_vftbl; - impl->_obj._generic._unknown._destructor = _shader_destructor; - impl->_obj.compile_status = GL_FALSE; - impl->_obj.source = NULL; - impl->_obj.offsets = NULL; - impl->_obj.offset_count = 0; - _slang_code_object_ctr(&impl->_obj.code); -} - -struct gl2_program_obj -{ - struct gl2_container_obj _container; - GLboolean link_status; - GLboolean validate_status; -#if USE_3DLABS_FRONTEND - ShHandle linker; - ShHandle uniforms; -#endif - slang_program prog; -}; - -struct gl2_program_impl -{ - struct gl2_program_intf *_vftbl; - struct gl2_program_obj _obj; -}; - -static void -_program_destructor(struct gl2_unknown_intf **intf) -{ - struct gl2_program_impl *impl = (struct gl2_program_impl *) intf; -#if USE_3DLABS_FRONTEND - ShDestruct(impl->_obj.linker); - ShDestruct(impl->_obj.uniforms); -#endif - _container_destructor(intf); - _slang_program_dtr(&impl->_obj.prog); -} - -static struct gl2_unknown_intf ** -_program_QueryInterface(struct gl2_unknown_intf **intf, enum gl2_uiid uiid) -{ - if (uiid == UIID_PROGRAM) { - (**intf).AddRef(intf); - return intf; - } - return _container_QueryInterface(intf, uiid); -} - -static GLenum -_program_GetType(struct gl2_generic_intf **intf) -{ - return GL_PROGRAM_OBJECT_ARB; -} - -static GLboolean -_program_Attach(struct gl2_container_intf **intf, - struct gl2_generic_intf **att) -{ - GET_CURRENT_CONTEXT(ctx); - struct gl2_unknown_intf **sha; - - sha = - (**att)._unknown.QueryInterface((struct gl2_unknown_intf **) att, - UIID_SHADER); - if (sha == NULL) { - _mesa_error(ctx, GL_INVALID_OPERATION, "_program_Attach"); - return GL_FALSE; - } - - (**sha).Release(sha); - return _container_Attach(intf, att); -} - -static GLboolean -_program_GetLinkStatus(struct gl2_program_intf **intf) -{ - struct gl2_program_impl *impl = (struct gl2_program_impl *) intf; - - return impl->_obj.link_status; -} - -static GLboolean -_program_GetValidateStatus(struct gl2_program_intf **intf) -{ - struct gl2_program_impl *impl = (struct gl2_program_impl *) intf; - - return impl->_obj.validate_status; -} - -static GLvoid -_program_Link(struct gl2_program_intf **intf) -{ - struct gl2_program_impl *impl = (struct gl2_program_impl *) intf; -#if USE_3DLABS_FRONTEND - ShHandle *handles; -#endif - GLuint i, count; - slang_code_object *code[2]; - GLboolean all_compiled = GL_TRUE; - - impl->_obj.link_status = GL_FALSE; - _mesa_free((void *) impl->_obj._container._generic.info_log); - impl->_obj._container._generic.info_log = NULL; - _slang_program_rst(&impl->_obj.prog); - -#if USE_3DLABS_FRONTEND - handles = - (ShHandle *) _mesa_malloc(impl->_obj._container.attached_count * - sizeof(ShHandle)); - if (handles == NULL) - return; - - for (i = 0; i < impl->_obj._container.attached_count; i++) { - struct gl2_generic_intf **gen = impl->_obj._container.attached[i]; - struct gl2_3dlabs_shhandle_intf **sh; - - sh = - (struct gl2_3dlabs_shhandle_intf **) (**gen)._unknown. - QueryInterface((struct gl2_unknown_intf **) gen, - UIID_3DLABS_SHHANDLE); - if (sh != NULL) { - handles[i] = (**sh).GetShHandle(sh); - (**sh)._unknown.Release((struct gl2_unknown_intf **) sh); - } - else { - _mesa_free(handles); - return; - } - } - - if (ShLink(impl->_obj.linker, handles, impl->_obj._container.attached_count, - impl->_obj.uniforms, NULL, NULL)) - impl->_obj.link_status = GL_TRUE; - - impl->_obj._container._generic.info_log = - _mesa_strdup(ShGetInfoLog(impl->_obj.linker)); -#else - count = impl->_obj._container.attached_count; - if (count > 2) - return; - - for (i = 0; i < count; i++) { - struct gl2_generic_intf **obj; - struct gl2_unknown_intf **unk; - struct gl2_shader_impl *sha; - - obj = impl->_obj._container.attached[i]; - unk = - (**obj)._unknown.QueryInterface((struct gl2_unknown_intf **) obj, - UIID_SHADER); - if (unk == NULL) - return; - sha = (struct gl2_shader_impl *) unk; - code[i] = &sha->_obj.code; - all_compiled = all_compiled && sha->_obj.compile_status; - (**unk).Release(unk); - } - - impl->_obj.link_status = all_compiled; - if (!impl->_obj.link_status) { - impl->_obj._container._generic.info_log = - _mesa_strdup - ("Error: One or more shaders has not successfully compiled.\n"); - return; - } - - impl->_obj.link_status = _slang_link(&impl->_obj.prog, code, count); - if (!impl->_obj.link_status) { - impl->_obj._container._generic.info_log = - _mesa_strdup("Link failed.\n"); - return; - } - - impl->_obj._container._generic.info_log = _mesa_strdup("Link OK.\n"); -#endif -} - -static GLvoid -_program_Validate(struct gl2_program_intf **intf) -{ - struct gl2_program_impl *impl = (struct gl2_program_impl *) intf; - - impl->_obj.validate_status = GL_FALSE; - _mesa_free((void *) impl->_obj._container._generic.info_log); - impl->_obj._container._generic.info_log = NULL; - - /* TODO validate */ -} - -static GLvoid -write_common_fixed(slang_program * pro, GLuint index, const GLvoid * src, - GLuint off, GLuint size) -{ - GLuint i; - - for (i = 0; i < SLANG_SHADER_MAX; i++) { - GLuint addr; - - addr = pro->common_fixed_entries[i][index]; - if (addr != ~0) { - GLubyte *dst; - - dst = (GLubyte *) pro->machines[i]->mem + addr + off * size; - _mesa_memcpy(dst, src, size); - } - } -} - -static GLvoid -write_common_fixed_mat4(slang_program * pro, GLmatrix * matrix, GLuint off, - GLuint i, GLuint ii, GLuint it, GLuint iit) -{ - GLfloat mat[16]; - - /* we want inverse matrix */ - if (!matrix->inv) { - /* allocate inverse matrix and make it dirty */ - _math_matrix_alloc_inv(matrix); - _math_matrix_loadf(matrix, matrix->m); - } - _math_matrix_analyse(matrix); - - write_common_fixed(pro, i, matrix->m, off, 16 * sizeof(GLfloat)); - - /* inverse */ - write_common_fixed(pro, ii, matrix->inv, off, 16 * sizeof(GLfloat)); - - /* transpose */ - _math_transposef(mat, matrix->m); - write_common_fixed(pro, it, mat, off, 16 * sizeof(GLfloat)); - - /* inverse transpose */ - _math_transposef(mat, matrix->inv); - write_common_fixed(pro, iit, mat, off, 16 * sizeof(GLfloat)); -} - -static GLvoid -write_common_fixed_material(GLcontext * ctx, slang_program * pro, GLuint i, - GLuint e, GLuint a, GLuint d, GLuint sp, - GLuint sh) -{ - GLfloat v[17]; - - COPY_4FV(v, ctx->Light.Material.Attrib[e]); - COPY_4FV((v + 4), ctx->Light.Material.Attrib[a]); - COPY_4FV((v + 8), ctx->Light.Material.Attrib[d]); - COPY_4FV((v + 12), ctx->Light.Material.Attrib[sp]); - v[16] = ctx->Light.Material.Attrib[sh][0]; - write_common_fixed(pro, i, v, 0, 17 * sizeof(GLfloat)); -} - -static GLvoid -write_common_fixed_light_model_product(GLcontext * ctx, slang_program * pro, - GLuint i, GLuint e, GLuint a) -{ - GLfloat v[4]; - - SCALE_4V(v, ctx->Light.Material.Attrib[a], ctx->Light.Model.Ambient); - ACC_4V(v, ctx->Light.Material.Attrib[e]); - write_common_fixed(pro, i, v, 0, 4 * sizeof(GLfloat)); -} - -static GLvoid -write_common_fixed_light_product(GLcontext * ctx, slang_program * pro, - GLuint off, GLuint i, GLuint a, GLuint d, - GLuint s) -{ - GLfloat v[12]; - - SCALE_4V(v, ctx->Light.Light[off].Ambient, ctx->Light.Material.Attrib[a]); - SCALE_4V((v + 4), ctx->Light.Light[off].Diffuse, - ctx->Light.Material.Attrib[d]); - SCALE_4V((v + 8), ctx->Light.Light[off].Specular, - ctx->Light.Material.Attrib[s]); - write_common_fixed(pro, i, v, off, 12 * sizeof(GLfloat)); -} - -static GLvoid -_program_UpdateFixedUniforms(struct gl2_program_intf **intf) -{ - GET_CURRENT_CONTEXT(ctx); - struct gl2_program_impl *impl = (struct gl2_program_impl *) intf; - slang_program *pro = &impl->_obj.prog; - GLuint i; - GLfloat v[29]; - GLfloat *p; - - /* MODELVIEW matrix */ - write_common_fixed_mat4(pro, ctx->ModelviewMatrixStack.Top, 0, - SLANG_COMMON_FIXED_MODELVIEWMATRIX, - SLANG_COMMON_FIXED_MODELVIEWMATRIXINVERSE, - SLANG_COMMON_FIXED_MODELVIEWMATRIXTRANSPOSE, - SLANG_COMMON_FIXED_MODELVIEWMATRIXINVERSETRANSPOSE); - - /* PROJECTION matrix */ - write_common_fixed_mat4(pro, ctx->ProjectionMatrixStack.Top, 0, - SLANG_COMMON_FIXED_PROJECTIONMATRIX, - SLANG_COMMON_FIXED_PROJECTIONMATRIXINVERSE, - SLANG_COMMON_FIXED_PROJECTIONMATRIXTRANSPOSE, - SLANG_COMMON_FIXED_PROJECTIONMATRIXINVERSETRANSPOSE); - - /* MVP matrix */ - write_common_fixed_mat4(pro, &ctx->_ModelProjectMatrix, 0, - SLANG_COMMON_FIXED_MODELVIEWPROJECTIONMATRIX, - SLANG_COMMON_FIXED_MODELVIEWPROJECTIONMATRIXINVERSE, - SLANG_COMMON_FIXED_MODELVIEWPROJECTIONMATRIXTRANSPOSE, - SLANG_COMMON_FIXED_MODELVIEWPROJECTIONMATRIXINVERSETRANSPOSE); - - for (i = 0; i < ctx->Const.MaxTextureCoordUnits; i++) { - /* TEXTURE matrix */ - write_common_fixed_mat4(pro, ctx->TextureMatrixStack[i].Top, i, - SLANG_COMMON_FIXED_TEXTUREMATRIX, - SLANG_COMMON_FIXED_TEXTUREMATRIXINVERSE, - SLANG_COMMON_FIXED_TEXTUREMATRIXTRANSPOSE, - SLANG_COMMON_FIXED_TEXTUREMATRIXINVERSETRANSPOSE); - - /* EYE_PLANE texture-coordinate generation */ - write_common_fixed(pro, SLANG_COMMON_FIXED_EYEPLANES, - ctx->Texture.Unit[i].EyePlaneS, i, - 4 * sizeof(GLfloat)); - write_common_fixed(pro, SLANG_COMMON_FIXED_EYEPLANET, - ctx->Texture.Unit[i].EyePlaneT, i, - 4 * sizeof(GLfloat)); - write_common_fixed(pro, SLANG_COMMON_FIXED_EYEPLANER, - ctx->Texture.Unit[i].EyePlaneR, i, - 4 * sizeof(GLfloat)); - write_common_fixed(pro, SLANG_COMMON_FIXED_EYEPLANEQ, - ctx->Texture.Unit[i].EyePlaneQ, i, - 4 * sizeof(GLfloat)); - - /* OBJECT_PLANE texture-coordinate generation */ - write_common_fixed(pro, SLANG_COMMON_FIXED_OBJECTPLANES, - ctx->Texture.Unit[i].ObjectPlaneS, i, - 4 * sizeof(GLfloat)); - write_common_fixed(pro, SLANG_COMMON_FIXED_OBJECTPLANET, - ctx->Texture.Unit[i].ObjectPlaneT, i, - 4 * sizeof(GLfloat)); - write_common_fixed(pro, SLANG_COMMON_FIXED_OBJECTPLANER, - ctx->Texture.Unit[i].ObjectPlaneR, i, - 4 * sizeof(GLfloat)); - write_common_fixed(pro, SLANG_COMMON_FIXED_OBJECTPLANEQ, - ctx->Texture.Unit[i].ObjectPlaneQ, i, - 4 * sizeof(GLfloat)); - } - - /* NORMAL matrix - upper 3x3 inverse transpose of MODELVIEW matrix */ - p = ctx->ModelviewMatrixStack.Top->inv; - v[0] = p[0]; - v[1] = p[4]; - v[2] = p[8]; - v[3] = p[1]; - v[4] = p[5]; - v[5] = p[9]; - v[6] = p[2]; - v[7] = p[6]; - v[8] = p[10]; - write_common_fixed(pro, SLANG_COMMON_FIXED_NORMALMATRIX, v, 0, - 9 * sizeof(GLfloat)); - - /* normal scale */ - write_common_fixed(pro, SLANG_COMMON_FIXED_NORMALSCALE, - &ctx->_ModelViewInvScale, 0, sizeof(GLfloat)); - - /* depth range parameters */ - v[0] = ctx->Viewport.Near; - v[1] = ctx->Viewport.Far; - v[2] = ctx->Viewport.Far - ctx->Viewport.Near; - write_common_fixed(pro, SLANG_COMMON_FIXED_DEPTHRANGE, v, 0, - 3 * sizeof(GLfloat)); - - /* CLIP_PLANEi */ - for (i = 0; i < ctx->Const.MaxClipPlanes; i++) { - write_common_fixed(pro, SLANG_COMMON_FIXED_CLIPPLANE, - ctx->Transform.EyeUserPlane[i], i, - 4 * sizeof(GLfloat)); - } - - /* point parameters */ - v[0] = ctx->Point.Size; - v[1] = ctx->Point.MinSize; - v[2] = ctx->Point.MaxSize; - v[3] = ctx->Point.Threshold; - COPY_3FV((v + 4), ctx->Point.Params); - write_common_fixed(pro, SLANG_COMMON_FIXED_POINT, v, 0, - 7 * sizeof(GLfloat)); - - /* material parameters */ - write_common_fixed_material(ctx, pro, SLANG_COMMON_FIXED_FRONTMATERIAL, - MAT_ATTRIB_FRONT_EMISSION, - MAT_ATTRIB_FRONT_AMBIENT, - MAT_ATTRIB_FRONT_DIFFUSE, - MAT_ATTRIB_FRONT_SPECULAR, - MAT_ATTRIB_FRONT_SHININESS); - write_common_fixed_material(ctx, pro, SLANG_COMMON_FIXED_BACKMATERIAL, - MAT_ATTRIB_BACK_EMISSION, - MAT_ATTRIB_BACK_AMBIENT, - MAT_ATTRIB_BACK_DIFFUSE, - MAT_ATTRIB_BACK_SPECULAR, - MAT_ATTRIB_BACK_SHININESS); - - for (i = 0; i < ctx->Const.MaxLights; i++) { - /* light source parameters */ - COPY_4FV(v, ctx->Light.Light[i].Ambient); - COPY_4FV((v + 4), ctx->Light.Light[i].Diffuse); - COPY_4FV((v + 8), ctx->Light.Light[i].Specular); - COPY_4FV((v + 12), ctx->Light.Light[i].EyePosition); - COPY_2FV((v + 16), ctx->Light.Light[i].EyePosition); - v[18] = ctx->Light.Light[i].EyePosition[2] + 1.0f; - NORMALIZE_3FV((v + 16)); - v[19] = 0.0f; - COPY_3V((v + 20), ctx->Light.Light[i].EyeDirection); - v[23] = ctx->Light.Light[i].SpotExponent; - v[24] = ctx->Light.Light[i].SpotCutoff; - v[25] = ctx->Light.Light[i]._CosCutoffNeg; - v[26] = ctx->Light.Light[i].ConstantAttenuation; - v[27] = ctx->Light.Light[i].LinearAttenuation; - v[28] = ctx->Light.Light[i].QuadraticAttenuation; - write_common_fixed(pro, SLANG_COMMON_FIXED_LIGHTSOURCE, v, i, - 29 * sizeof(GLfloat)); - - /* light product */ - write_common_fixed_light_product(ctx, pro, i, - SLANG_COMMON_FIXED_FRONTLIGHTPRODUCT, - MAT_ATTRIB_FRONT_AMBIENT, - MAT_ATTRIB_FRONT_DIFFUSE, - MAT_ATTRIB_FRONT_SPECULAR); - write_common_fixed_light_product(ctx, pro, i, - SLANG_COMMON_FIXED_BACKLIGHTPRODUCT, - MAT_ATTRIB_BACK_AMBIENT, - MAT_ATTRIB_BACK_DIFFUSE, - MAT_ATTRIB_BACK_SPECULAR); - } - - /* light model parameters */ - write_common_fixed(pro, SLANG_COMMON_FIXED_LIGHTMODEL, - ctx->Light.Model.Ambient, 0, 4 * sizeof(GLfloat)); - - /* light model product */ - write_common_fixed_light_model_product(ctx, pro, - SLANG_COMMON_FIXED_FRONTLIGHTMODELPRODUCT, - MAT_ATTRIB_FRONT_EMISSION, - MAT_ATTRIB_FRONT_AMBIENT); - write_common_fixed_light_model_product(ctx, pro, - SLANG_COMMON_FIXED_BACKLIGHTMODELPRODUCT, - MAT_ATTRIB_BACK_EMISSION, - MAT_ATTRIB_BACK_AMBIENT); - - /* TEXTURE_ENV_COLOR */ - for (i = 0; i < ctx->Const.MaxTextureImageUnits; i++) { - write_common_fixed(pro, SLANG_COMMON_FIXED_TEXTUREENVCOLOR, - ctx->Texture.Unit[i].EnvColor, i, - 4 * sizeof(GLfloat)); - } - - /* fog parameters */ - COPY_4FV(v, ctx->Fog.Color); - v[4] = ctx->Fog.Density; - v[5] = ctx->Fog.Start; - v[6] = ctx->Fog.End; - v[7] = ctx->Fog._Scale; - write_common_fixed(pro, SLANG_COMMON_FIXED_FOG, v, 0, 8 * sizeof(GLfloat)); -} - -static GLvoid -_program_UpdateFixedAttrib(struct gl2_program_intf **intf, GLuint index, - GLvoid * data, GLuint offset, GLuint size, - GLboolean write) -{ - struct gl2_program_impl *impl = (struct gl2_program_impl *) intf; - slang_program *pro = &impl->_obj.prog; - GLuint addr; - - addr = pro->vertex_fixed_entries[index]; - if (addr != ~0) { - GLubyte *mem; - - mem = - (GLubyte *) pro->machines[SLANG_SHADER_VERTEX]->mem + addr + - offset * size; - if (write) - _mesa_memcpy(mem, data, size); - else - _mesa_memcpy(data, mem, size); - } -} - - -/** - * Called during fragment shader execution to either load a varying - * register with values, or fetch values from a varying register. - * \param intf the internal program? - * \param index which varying register, one of the SLANG_FRAGMENT_FIXED_* - * values for example. - * \param data source values to load (or dest to write to) - * \param offset indicates a texture unit or generic varying attribute - * \param size number of bytes to copy - * \param write if true, write to the varying register, else store values - * in 'data' - */ -static GLvoid -_program_UpdateFixedVarying(struct gl2_program_intf **intf, GLuint index, - GLvoid * data, - GLuint offset, GLuint size, GLboolean write) -{ - struct gl2_program_impl *impl = (struct gl2_program_impl *) intf; - slang_program *pro = &impl->_obj.prog; - GLuint addr; - - addr = pro->fragment_fixed_entries[index]; - if (addr != ~0) { - GLubyte *mem; - - mem = - (GLubyte *) pro->machines[SLANG_SHADER_FRAGMENT]->mem + addr + - offset * size; - if (write) - _mesa_memcpy(mem, data, size); - else - _mesa_memcpy(data, mem, size); - } -} - -static GLvoid -_program_GetTextureImageUsage(struct gl2_program_intf **intf, - GLbitfield * teximageusage) -{ - GET_CURRENT_CONTEXT(ctx); - struct gl2_program_impl *impl = (struct gl2_program_impl *) intf; - slang_program *pro = &impl->_obj.prog; - GLuint i; - - for (i = 0; i < ctx->Const.MaxTextureImageUnits; i++) - teximageusage[i] = 0; - - for (i = 0; i < pro->texture_usage.count; i++) { - GLuint n, addr, j; - - n = slang_export_data_quant_elements(pro->texture_usage.table[i].quant); - addr = pro->texture_usage.table[i].frag_address; - for (j = 0; j < n; j++) { - GLubyte *mem; - GLuint image; - - mem = - (GLubyte *) pro->machines[SLANG_SHADER_FRAGMENT]->mem + addr + - j * 4; - image = (GLuint) * ((GLfloat *) mem); - if (image >= 0 && image < ctx->Const.MaxTextureImageUnits) { - switch (slang_export_data_quant_type - (pro->texture_usage.table[i].quant)) { - case GL_SAMPLER_1D_ARB: - case GL_SAMPLER_1D_SHADOW_ARB: - teximageusage[image] |= TEXTURE_1D_BIT; - break; - case GL_SAMPLER_2D_ARB: - case GL_SAMPLER_2D_SHADOW_ARB: - teximageusage[image] |= TEXTURE_2D_BIT; - break; - case GL_SAMPLER_3D_ARB: - teximageusage[image] |= TEXTURE_3D_BIT; - break; - case GL_SAMPLER_CUBE_ARB: - teximageusage[image] |= TEXTURE_CUBE_BIT; - break; - } - } - } - } - - /* TODO: make sure that for 0<=i<=MaxTextureImageUint bitcount(teximageuint[i])<=0 */ -} - -static GLboolean -_program_IsShaderPresent(struct gl2_program_intf **intf, GLenum subtype) -{ - struct gl2_program_impl *impl = (struct gl2_program_impl *) intf; - slang_program *pro = &impl->_obj.prog; - - switch (subtype) { - case GL_VERTEX_SHADER_ARB: - return pro->machines[SLANG_SHADER_VERTEX] != NULL; - case GL_FRAGMENT_SHADER_ARB: - return pro->machines[SLANG_SHADER_FRAGMENT] != NULL; - default: - return GL_FALSE; - } -} - -static GLvoid -get_active_variable(slang_active_variable * var, GLsizei maxLength, - GLsizei * length, GLint * size, GLenum * type, - GLchar * name) -{ - GLsizei len; - - len = _mesa_strlen(var->name); - if (len >= maxLength) - len = maxLength - 1; - if (length != NULL) - *length = len; - *size = slang_export_data_quant_elements(var->quant); - *type = slang_export_data_quant_type(var->quant); - _mesa_memcpy(name, var->name, len); - name[len] = '\0'; -} - -static GLuint -get_active_variable_max_length(slang_active_variables * vars) -{ - GLuint i, len = 0; - - for (i = 0; i < vars->count; i++) { - GLuint n = _mesa_strlen(vars->table[i].name); - if (n > len) - len = n; - } - return len; -} - -static GLvoid -_program_GetActiveUniform(struct gl2_program_intf **intf, GLuint index, - GLsizei maxLength, GLsizei * length, GLint * size, - GLenum * type, GLchar * name) -{ - struct gl2_program_impl *impl = (struct gl2_program_impl *) (intf); - slang_active_variable *u = &impl->_obj.prog.active_uniforms.table[index]; - - get_active_variable(u, maxLength, length, size, type, name); -} - -static GLuint -_program_GetActiveUniformMaxLength(struct gl2_program_intf **intf) -{ - struct gl2_program_impl *impl = (struct gl2_program_impl *) (intf); - - return get_active_variable_max_length(&impl->_obj.prog.active_uniforms); -} - -static GLuint -_program_GetActiveUniformCount(struct gl2_program_intf **intf) -{ - struct gl2_program_impl *impl = (struct gl2_program_impl *) (intf); - - return impl->_obj.prog.active_uniforms.count; -} - -static GLint -_program_GetUniformLocation(struct gl2_program_intf **intf, - const GLchar * name) -{ - struct gl2_program_impl *impl = (struct gl2_program_impl *) (intf); - slang_uniform_bindings *bind = &impl->_obj.prog.uniforms; - GLuint i; - - for (i = 0; i < bind->count; i++) - if (_mesa_strcmp(bind->table[i].name, name) == 0) - return i; - return -1; -} - -/** - * Write a uniform variable into program's memory. - * \return GL_TRUE for success, GL_FALSE if error - */ -static GLboolean -_program_WriteUniform(struct gl2_program_intf **intf, GLint loc, - GLsizei count, const GLvoid * data, GLenum type) -{ - struct gl2_program_impl *impl = (struct gl2_program_impl *) (intf); - slang_uniform_bindings *uniforms = &impl->_obj.prog.uniforms; - slang_uniform_binding *uniform; - GLuint i; - GLboolean convert_float_to_bool = GL_FALSE; - GLboolean convert_int_to_bool = GL_FALSE; - GLboolean convert_int_to_float = GL_FALSE; - GLboolean types_match = GL_FALSE; - - if (loc < 0 || loc >= uniforms->count) - return GL_FALSE; - - uniform = &uniforms->table[loc]; - /* TODO: check sizes */ - if (slang_export_data_quant_struct(uniform->quant)) - return GL_FALSE; - - switch (slang_export_data_quant_type(uniform->quant)) { - case GL_BOOL_ARB: - types_match = (type == GL_FLOAT) || (type == GL_INT); - if (type == GL_FLOAT) - convert_float_to_bool = GL_TRUE; - else - convert_int_to_bool = GL_TRUE; - break; - case GL_BOOL_VEC2_ARB: - types_match = (type == GL_FLOAT_VEC2_ARB) || (type == GL_INT_VEC2_ARB); - if (type == GL_FLOAT_VEC2_ARB) - convert_float_to_bool = GL_TRUE; - else - convert_int_to_bool = GL_TRUE; - break; - case GL_BOOL_VEC3_ARB: - types_match = (type == GL_FLOAT_VEC3_ARB) || (type == GL_INT_VEC3_ARB); - if (type == GL_FLOAT_VEC3_ARB) - convert_float_to_bool = GL_TRUE; - else - convert_int_to_bool = GL_TRUE; - break; - case GL_BOOL_VEC4_ARB: - types_match = (type == GL_FLOAT_VEC4_ARB) || (type == GL_INT_VEC4_ARB); - if (type == GL_FLOAT_VEC4_ARB) - convert_float_to_bool = GL_TRUE; - else - convert_int_to_bool = GL_TRUE; - break; - case GL_SAMPLER_1D_ARB: - case GL_SAMPLER_2D_ARB: - case GL_SAMPLER_3D_ARB: - case GL_SAMPLER_CUBE_ARB: - case GL_SAMPLER_1D_SHADOW_ARB: - case GL_SAMPLER_2D_SHADOW_ARB: - types_match = (type == GL_INT); - break; - default: - types_match = (type == slang_export_data_quant_type(uniform->quant)); - break; - } - - if (!types_match) - return GL_FALSE; - - switch (type) { - case GL_INT: - case GL_INT_VEC2_ARB: - case GL_INT_VEC3_ARB: - case GL_INT_VEC4_ARB: - convert_int_to_float = GL_TRUE; - break; - } - - for (i = 0; i < SLANG_SHADER_MAX; i++) { - if (uniform->address[i] != ~0) { - void *dest - = &impl->_obj.prog.machines[i]->mem[uniform->address[i] / 4]; - /* total number of values to copy */ - GLuint total - = count * slang_export_data_quant_components(uniform->quant); - GLuint j; - if (convert_float_to_bool) { - const GLfloat *src = (GLfloat *) (data); - GLfloat *dst = (GLfloat *) dest; - for (j = 0; j < total; j++) - dst[j] = src[j] != 0.0f ? 1.0f : 0.0f; - break; - } - else if (convert_int_to_bool) { - const GLint *src = (GLint *) (data); - GLfloat *dst = (GLfloat *) dest; - for (j = 0; j < total; j++) - dst[j] = src[j] ? 1.0f : 0.0f; - break; - } - else if (convert_int_to_float) { - const GLint *src = (GLint *) (data); - GLfloat *dst = (GLfloat *) dest; - for (j = 0; j < total; j++) - dst[j] = (GLfloat) src[j]; - break; - } - else { - _mesa_memcpy(dest, data, total * sizeof(GLfloat)); - break; - } - break; - } - } - return GL_TRUE; -} - -/** - * Read a uniform variable from program's memory. - * \return GL_TRUE for success, GL_FALSE if error - */ -static GLboolean -_program_ReadUniform(struct gl2_program_intf **intf, GLint loc, - GLsizei count, GLvoid *data, GLenum type) -{ - struct gl2_program_impl *impl = (struct gl2_program_impl *) (intf); - const slang_uniform_bindings *uniforms = &impl->_obj.prog.uniforms; - const slang_uniform_binding *uniform; - GLuint i; - GLboolean convert_bool_to_float = GL_FALSE; - GLboolean convert_bool_to_int = GL_FALSE; - GLboolean convert_float_to_int = GL_FALSE; - GLboolean types_match = GL_FALSE; - - if (loc < 0 || loc >= uniforms->count) - return GL_FALSE; - - uniform = &uniforms->table[loc]; - - if (slang_export_data_quant_struct(uniform->quant)) - return GL_FALSE; - - switch (slang_export_data_quant_type(uniform->quant)) { - case GL_BOOL_ARB: - types_match = (type == GL_FLOAT) || (type == GL_INT); - if (type == GL_FLOAT) - convert_bool_to_float = GL_TRUE; - else - convert_bool_to_int = GL_TRUE; - break; - case GL_BOOL_VEC2_ARB: - types_match = (type == GL_FLOAT_VEC2_ARB) || (type == GL_INT_VEC2_ARB); - if (type == GL_FLOAT_VEC2_ARB) - convert_bool_to_float = GL_TRUE; - else - convert_bool_to_int = GL_TRUE; - break; - case GL_BOOL_VEC3_ARB: - types_match = (type == GL_FLOAT_VEC3_ARB) || (type == GL_INT_VEC3_ARB); - if (type == GL_FLOAT_VEC3_ARB) - convert_bool_to_float = GL_TRUE; - else - convert_bool_to_int = GL_TRUE; - break; - case GL_BOOL_VEC4_ARB: - types_match = (type == GL_FLOAT_VEC4_ARB) || (type == GL_INT_VEC4_ARB); - if (type == GL_FLOAT_VEC4_ARB) - convert_bool_to_float = GL_TRUE; - else - convert_bool_to_int = GL_TRUE; - break; - case GL_SAMPLER_1D_ARB: - case GL_SAMPLER_2D_ARB: - case GL_SAMPLER_3D_ARB: - case GL_SAMPLER_CUBE_ARB: - case GL_SAMPLER_1D_SHADOW_ARB: - case GL_SAMPLER_2D_SHADOW_ARB: - types_match = (type == GL_INT); - break; - default: - /* uniform is a float type */ - types_match = (type == GL_FLOAT); - break; - } - - if (!types_match) - return GL_FALSE; - - switch (type) { - case GL_INT: - case GL_INT_VEC2_ARB: - case GL_INT_VEC3_ARB: - case GL_INT_VEC4_ARB: - convert_float_to_int = GL_TRUE; - break; - } - - for (i = 0; i < SLANG_SHADER_MAX; i++) { - if (uniform->address[i] != ~0) { - /* XXX if bools are really implemented as floats, some of this - * could probably be culled out. - */ - const void *source - = &impl->_obj.prog.machines[i]->mem[uniform->address[i] / 4]; - /* total number of values to copy */ - const GLuint total - = count * slang_export_data_quant_components(uniform->quant); - GLuint j; - if (convert_bool_to_float) { - GLfloat *dst = (GLfloat *) (data); - const GLfloat *src = (GLfloat *) source; - for (j = 0; j < total; j++) - dst[j] = src[j] == 0.0 ? 0.0 : 1.0; - } - else if (convert_bool_to_int) { - GLint *dst = (GLint *) (data); - const GLfloat *src = (GLfloat *) source; - for (j = 0; j < total; j++) - dst[j] = src[j] == 0.0 ? 0 : 1; - } - else if (convert_float_to_int) { - GLint *dst = (GLint *) (data); - const GLfloat *src = (GLfloat *) source; - for (j = 0; j < total; j++) - dst[j] = (GLint) src[j]; - } - else { - /* no type conversion needed */ - _mesa_memcpy(data, source, total * sizeof(GLfloat)); - } - break; - } /* if */ - } /* for */ - - return GL_TRUE; -} - - -static GLvoid -_program_GetActiveAttrib(struct gl2_program_intf **intf, GLuint index, - GLsizei maxLength, GLsizei * length, GLint * size, - GLenum * type, GLchar * name) -{ - struct gl2_program_impl *impl = (struct gl2_program_impl *) (intf); - slang_active_variable *a = &impl->_obj.prog.active_attribs.table[index]; - - get_active_variable(a, maxLength, length, size, type, name); -} - -static GLuint -_program_GetActiveAttribMaxLength(struct gl2_program_intf **intf) -{ - struct gl2_program_impl *impl = (struct gl2_program_impl *) (intf); - - return get_active_variable_max_length(&impl->_obj.prog.active_attribs); -} - -static GLuint -_program_GetActiveAttribCount(struct gl2_program_intf **intf) -{ - struct gl2_program_impl *impl = (struct gl2_program_impl *) (intf); - - return impl->_obj.prog.active_attribs.count; -} - -static GLint -_program_GetAttribLocation(struct gl2_program_intf **intf, - const GLchar * name) -{ - struct gl2_program_impl *impl = (struct gl2_program_impl *) (intf); - slang_attrib_bindings *attribs = &impl->_obj.prog.attribs; - GLuint i; - - for (i = 0; i < attribs->binding_count; i++) - if (_mesa_strcmp(attribs->bindings[i].name, name) == 0) - return attribs->bindings[i].first_slot_index; - return -1; -} - -static GLvoid -_program_OverrideAttribBinding(struct gl2_program_intf **intf, GLuint index, - const GLchar * name) -{ - GET_CURRENT_CONTEXT(ctx); - struct gl2_program_impl *impl = (struct gl2_program_impl *) (intf); - slang_program *pro = &impl->_obj.prog; - - if (!_slang_attrib_overrides_add(&pro->attrib_overrides, index, name)) - _mesa_error(ctx, GL_OUT_OF_MEMORY, "_program_OverrideAttribBinding"); -} - -static GLvoid -_program_WriteAttrib(struct gl2_program_intf **intf, GLuint index, - const GLfloat * value) -{ - struct gl2_program_impl *impl = (struct gl2_program_impl *) (intf); - slang_program *pro = &impl->_obj.prog; - slang_attrib_slot *slot = &pro->attribs.slots[index]; - - /* - * Generic attributes can be allocated in a shader with scalar, vec - * or mat type. For scalar and vec types (specifically float, vec2 - * and vec3) this is simple - just ignore the extra components. For - * mat type this is more complicated - the vertex_shader spec - * requires to store every column of a matrix in a separate attrib - * slot. To prvent from overwriting data from neighbouring matrix - * columns, the "fill" information is kept to know how many - * components to copy. - */ - - if (slot->addr != ~0) - _mesa_memcpy(&pro->machines[SLANG_SHADER_VERTEX]->mem[slot->addr / 4]. - _float, value, slot->fill * sizeof(GLfloat)); -} - -static GLvoid -_program_UpdateVarying(struct gl2_program_intf **intf, GLuint index, - GLfloat * value, GLboolean vert) -{ - struct gl2_program_impl *impl = (struct gl2_program_impl *) intf; - slang_program *pro = &impl->_obj.prog; - GLuint addr; - - if (index >= pro->varyings.slot_count) - return; - if (vert) - addr = pro->varyings.slots[index].vert_addr / 4; - else - addr = pro->varyings.slots[index].frag_addr / 4; - if (addr != ~0) { - if (vert) - *value = pro->machines[SLANG_SHADER_VERTEX]->mem[addr]._float; - else - pro->machines[SLANG_SHADER_FRAGMENT]->mem[addr]._float = *value; - } -} - -static struct gl2_program_intf _program_vftbl = { - { - { - { - _unknown_AddRef, - _unknown_Release, - _program_QueryInterface - }, - _generic_Delete, - _program_GetType, - _generic_GetName, - _generic_GetDeleteStatus, - _generic_GetInfoLog, - _generic_GetInfoLogLength - }, - _program_Attach, - _container_Detach, - _container_GetAttachedCount, - _container_GetAttached - }, - _program_GetLinkStatus, - _program_GetValidateStatus, - _program_Link, - _program_Validate, - _program_UpdateFixedUniforms, - _program_UpdateFixedAttrib, - _program_UpdateFixedVarying, - _program_GetTextureImageUsage, - _program_IsShaderPresent, - _program_GetActiveUniform, - _program_GetActiveUniformMaxLength, - _program_GetActiveUniformCount, - _program_GetUniformLocation, - _program_WriteUniform, - _program_ReadUniform, - _program_GetActiveAttrib, - _program_GetActiveAttribMaxLength, - _program_GetActiveAttribCount, - _program_GetAttribLocation, - _program_OverrideAttribBinding, - _program_WriteAttrib, - _program_UpdateVarying -}; - -static void -_program_constructor(struct gl2_program_impl *impl) -{ - _container_constructor((struct gl2_container_impl *) impl); - impl->_vftbl = &_program_vftbl; - impl->_obj._container._generic._unknown._destructor = _program_destructor; - impl->_obj.link_status = GL_FALSE; - impl->_obj.validate_status = GL_FALSE; -#if USE_3DLABS_FRONTEND - impl->_obj.linker = ShConstructLinker(EShExVertexFragment, 0); - impl->_obj.uniforms = ShConstructUniformMap(); -#endif - _slang_program_ctr(&impl->_obj.prog); -} - -struct gl2_fragment_shader_obj -{ - struct gl2_shader_obj _shader; -}; - -struct gl2_fragment_shader_impl -{ - struct gl2_fragment_shader_intf *_vftbl; - struct gl2_fragment_shader_obj _obj; -}; - -static void -_fragment_shader_destructor(struct gl2_unknown_intf **intf) -{ - struct gl2_fragment_shader_impl *impl = - (struct gl2_fragment_shader_impl *) intf; - - (void) impl; - /* TODO free fragment shader data */ - - _shader_destructor(intf); -} - -static struct gl2_unknown_intf ** -_fragment_shader_QueryInterface(struct gl2_unknown_intf **intf, - enum gl2_uiid uiid) -{ - if (uiid == UIID_FRAGMENT_SHADER) { - (**intf).AddRef(intf); - return intf; - } - return _shader_QueryInterface(intf, uiid); -} - -static GLenum -_fragment_shader_GetSubType(struct gl2_shader_intf **intf) -{ - return GL_FRAGMENT_SHADER_ARB; -} - -static struct gl2_fragment_shader_intf _fragment_shader_vftbl = { - { - { - { - _unknown_AddRef, - _unknown_Release, - _fragment_shader_QueryInterface - }, - _generic_Delete, - _shader_GetType, - _generic_GetName, - _generic_GetDeleteStatus, - _shader_GetInfoLog, - _shader_GetInfoLogLength - }, - _fragment_shader_GetSubType, - _shader_GetCompileStatus, - _shader_SetSource, - _shader_GetSource, - _shader_Compile - } -}; - -static void -_fragment_shader_constructor(struct gl2_fragment_shader_impl *impl) -{ - _shader_constructor((struct gl2_shader_impl *) impl); - impl->_vftbl = &_fragment_shader_vftbl; - impl->_obj._shader._generic._unknown._destructor = - _fragment_shader_destructor; -#if USE_3DLABS_FRONTEND - impl->_obj._shader._3dlabs_shhandle._obj.handle = - ShConstructCompiler(EShLangFragment, 0); -#endif -} - -struct gl2_vertex_shader_obj -{ - struct gl2_shader_obj _shader; -}; - -struct gl2_vertex_shader_impl -{ - struct gl2_vertex_shader_intf *_vftbl; - struct gl2_vertex_shader_obj _obj; -}; - -static void -_vertex_shader_destructor(struct gl2_unknown_intf **intf) -{ - struct gl2_vertex_shader_impl *impl = - (struct gl2_vertex_shader_impl *) intf; - - (void) impl; - /* TODO free vertex shader data */ - - _shader_destructor(intf); -} - -static struct gl2_unknown_intf ** -_vertex_shader_QueryInterface(struct gl2_unknown_intf **intf, - enum gl2_uiid uiid) -{ - if (uiid == UIID_VERTEX_SHADER) { - (**intf).AddRef(intf); - return intf; - } - return _shader_QueryInterface(intf, uiid); -} - -static GLenum -_vertex_shader_GetSubType(struct gl2_shader_intf **intf) -{ - return GL_VERTEX_SHADER_ARB; -} - -static struct gl2_vertex_shader_intf _vertex_shader_vftbl = { - { - { - { - _unknown_AddRef, - _unknown_Release, - _vertex_shader_QueryInterface - }, - _generic_Delete, - _shader_GetType, - _generic_GetName, - _generic_GetDeleteStatus, - _shader_GetInfoLog, - _shader_GetInfoLogLength - }, - _vertex_shader_GetSubType, - _shader_GetCompileStatus, - _shader_SetSource, - _shader_GetSource, - _shader_Compile - } -}; - -static void -_vertex_shader_constructor(struct gl2_vertex_shader_impl *impl) -{ - _shader_constructor((struct gl2_shader_impl *) impl); - impl->_vftbl = &_vertex_shader_vftbl; - impl->_obj._shader._generic._unknown._destructor = - _vertex_shader_destructor; -#if USE_3DLABS_FRONTEND - impl->_obj._shader._3dlabs_shhandle._obj.handle = - ShConstructCompiler(EShLangVertex, 0); -#endif -} - -struct gl2_debug_obj -{ - struct gl2_generic_obj _generic; -}; - -struct gl2_debug_impl -{ - struct gl2_debug_intf *_vftbl; - struct gl2_debug_obj _obj; -}; - -static GLvoid -_debug_destructor(struct gl2_unknown_intf **intf) -{ - struct gl2_debug_impl *impl = (struct gl2_debug_impl *) (intf); - - (void) (impl); - /* TODO */ - - _generic_destructor(intf); -} - -static struct gl2_unknown_intf ** -_debug_QueryInterface(struct gl2_unknown_intf **intf, enum gl2_uiid uiid) -{ - if (uiid == UIID_DEBUG) { - (**intf).AddRef(intf); - return intf; - } - return _generic_QueryInterface(intf, uiid); -} - -static GLenum -_debug_GetType(struct gl2_generic_intf **intf) -{ - return /*GL_DEBUG_OBJECT_MESA */ 0; -} - -static GLvoid -_debug_ClearDebugLog(struct gl2_debug_intf **intf, GLenum logType, - GLenum shaderType) -{ - struct gl2_debug_impl *impl = (struct gl2_debug_impl *) (intf); - - (void) (impl); - /* TODO */ -} - -static GLvoid -_debug_GetDebugLog(struct gl2_debug_intf **intf, GLenum logType, - GLenum shaderType, GLsizei maxLength, GLsizei * length, - GLcharARB * infoLog) -{ - struct gl2_debug_impl *impl = (struct gl2_debug_impl *) (intf); - - (void) (impl); - /* TODO */ -} - -static GLsizei -_debug_GetDebugLogLength(struct gl2_debug_intf **intf, GLenum logType, - GLenum shaderType) -{ - struct gl2_debug_impl *impl = (struct gl2_debug_impl *) (intf); - - (void) (impl); - /* TODO */ - - return 0; -} - -static struct gl2_debug_intf _debug_vftbl = { - { - { - _unknown_AddRef, - _unknown_Release, - _debug_QueryInterface - }, - _generic_Delete, - _debug_GetType, - _generic_GetName, - _generic_GetDeleteStatus, - _generic_GetInfoLog, - _generic_GetInfoLogLength - }, - _debug_ClearDebugLog, - _debug_GetDebugLog, - _debug_GetDebugLogLength -}; - -static GLvoid -_debug_constructor(struct gl2_debug_impl *impl) -{ - _generic_constructor((struct gl2_generic_impl *) (impl)); - impl->_vftbl = &_debug_vftbl; - impl->_obj._generic._unknown._destructor = _debug_destructor; -} - -GLhandleARB -_mesa_3dlabs_create_shader_object(GLenum shaderType) -{ - switch (shaderType) { - case GL_FRAGMENT_SHADER_ARB: - { - struct gl2_fragment_shader_impl *x = - (struct gl2_fragment_shader_impl *) - _mesa_malloc(sizeof(struct gl2_fragment_shader_impl)); - - if (x != NULL) { - _fragment_shader_constructor(x); - return x->_obj._shader._generic.name; - } - } - break; - case GL_VERTEX_SHADER_ARB: - { - struct gl2_vertex_shader_impl *x = (struct gl2_vertex_shader_impl *) - _mesa_malloc(sizeof(struct gl2_vertex_shader_impl)); - - if (x != NULL) { - _vertex_shader_constructor(x); - return x->_obj._shader._generic.name; - } - } - break; - } - - return 0; -} - -GLhandleARB -_mesa_3dlabs_create_program_object(void) -{ - struct gl2_program_impl *x = (struct gl2_program_impl *) - _mesa_malloc(sizeof(struct gl2_program_impl)); - - if (x != NULL) { - _program_constructor(x); - return x->_obj._container._generic.name; - } - - return 0; -} - -GLhandleARB -_mesa_3dlabs_create_debug_object(GLvoid) -{ - struct gl2_debug_impl *obj; - - obj = - (struct gl2_debug_impl *) (_mesa_malloc(sizeof(struct gl2_debug_impl))); - if (obj != NULL) { - _debug_constructor(obj); - return obj->_obj._generic.name; - } - return 0; -} - -#include "slang_assemble.h" -#include "slang_execute.h" - -int -_slang_fetch_discard(struct gl2_program_intf **pro, GLboolean * val) -{ - struct gl2_program_impl *impl; - - impl = (struct gl2_program_impl *) pro; - *val = - impl->_obj.prog.machines[SLANG_SHADER_FRAGMENT]-> - kill ? GL_TRUE : GL_FALSE; - return 1; -} - -static GLvoid -exec_shader(struct gl2_program_intf **pro, GLuint i) -{ - struct gl2_program_impl *impl; - slang_program *p; - - impl = (struct gl2_program_impl *) pro; - p = &impl->_obj.prog; - - slang_machine_init(p->machines[i]); - p->machines[i]->ip = p->code[i][SLANG_COMMON_CODE_MAIN]; - - _slang_execute2(p->assemblies[i], p->machines[i]); -} - -GLvoid -_slang_exec_fragment_shader(struct gl2_program_intf **pro) -{ - exec_shader(pro, SLANG_SHADER_FRAGMENT); -} - -GLvoid -_slang_exec_vertex_shader(struct gl2_program_intf **pro) -{ - exec_shader(pro, SLANG_SHADER_VERTEX); -} - -#endif - -void -_mesa_init_shaderobjects_3dlabs(GLcontext * ctx) -{ -#if USE_3DLABS_FRONTEND - _glslang_3dlabs_InitProcess(); - _glslang_3dlabs_ShInitialize(); -#endif -} diff --git a/src/mesa/shader/slang/Include/BaseTypes.h b/src/mesa/shader/slang/Include/BaseTypes.h deleted file mode 100755 index c5bf8de17f..0000000000 --- a/src/mesa/shader/slang/Include/BaseTypes.h +++ /dev/null @@ -1,133 +0,0 @@ -//
-//Copyright (C) 2002-2005 3Dlabs Inc. Ltd.
-//All rights reserved.
-//
-//Redistribution and use in source and binary forms, with or without
-//modification, are permitted provided that the following conditions
-//are met:
-//
-// Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//
-// Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-//
-// Neither the name of 3Dlabs Inc. Ltd. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-//THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-//"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-//LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
-//FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
-//COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
-//INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
-//BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
-//LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
-//CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-//LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
-//ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
-//POSSIBILITY OF SUCH DAMAGE.
-//
-
-#ifndef _BASICTYPES_INCLUDED_
-#define _BASICTYPES_INCLUDED_
-
-//
-// Basic type. Arrays, vectors, etc., are orthogonal to this.
-//
-enum TBasicType {
- EbtVoid,
- EbtFloat,
- EbtInt,
- EbtBool,
- EbtSampler1D,
- EbtSampler2D,
- EbtSampler3D,
- EbtSamplerCube,
- EbtSampler1DShadow,
- EbtSampler2DShadow,
- EbtStruct,
- EbtAddress
-};
-
-__inline bool IsSampler(TBasicType type)
-{
- return type >= EbtSampler1D && type <= EbtSampler2DShadow;
-}
-
-//
-// Qualifiers and built-ins. These are mainly used to see what can be read
-// or written, and by the machine dependent translator to know which registers
-// to allocate variables in. Since built-ins tend to go to different registers
-// than varying or uniform, it makes sense they are peers, not sub-classes.
-//
-enum TQualifier {
- EvqTemporary, // For temporaries (within a function), read/write
- EvqGlobal, // For globals read/write
- EvqConst, // User defined constants and non-output parameters in functions
- EvqAttribute, // Readonly
- EvqVaryingIn, // readonly, fragment shaders only
- EvqVaryingOut, // vertex shaders only read/write
- EvqUniform, // Readonly, vertex and fragment
-
- // pack/unpack input and output
- EvqInput,
- EvqOutput,
-
- // parameters
- EvqIn,
- EvqOut,
- EvqInOut,
- EvqConstReadOnly,
-
- // built-ins written by vertex shader
- EvqPosition,
- EvqPointSize,
- EvqClipVertex,
-
- // built-ins read by fragment shader
- EvqFace,
- EvqFragCoord,
-
- // built-ins written by fragment shader
- EvqFragColor,
- EvqFragDepth,
-
- // end of list
- EvqLast
-};
-
-//
-// This is just for debug print out, carried along with the definitions above.
-//
-__inline const char* getQualifierString(TQualifier q)
-{
- switch (q) {
- case EvqTemporary: return "Temporary"; break;
- case EvqGlobal: return "Global"; break;
- case EvqConst: return "const"; break;
- case EvqConstReadOnly: return "const"; break;
- case EvqAttribute: return "attribute"; break;
- case EvqVaryingIn: return "varying"; break;
- case EvqVaryingOut: return "varying"; break;
- case EvqUniform: return "uniform"; break;
- case EvqIn: return "in"; break;
- case EvqOut: return "out"; break;
- case EvqInOut: return "inout"; break;
- case EvqInput: return "input"; break;
- case EvqOutput: return "output"; break;
- case EvqPosition: return "Position"; break;
- case EvqPointSize: return "PointSize"; break;
- case EvqClipVertex: return "ClipVertex"; break;
- case EvqFace: return "Face"; break;
- case EvqFragCoord: return "FragCoord"; break;
- case EvqFragColor: return "FragColor"; break;
- case EvqFragDepth: return "FragDepth"; break;
- default: return "unknown qualifier";
- }
-}
-
-#endif // _BASICTYPES_INCLUDED_
diff --git a/src/mesa/shader/slang/Include/Common.h b/src/mesa/shader/slang/Include/Common.h deleted file mode 100755 index 4a9c0d34a7..0000000000 --- a/src/mesa/shader/slang/Include/Common.h +++ /dev/null @@ -1,288 +0,0 @@ -//
-//Copyright (C) 2002-2005 3Dlabs Inc. Ltd.
-//All rights reserved.
-//
-//Redistribution and use in source and binary forms, with or without
-//modification, are permitted provided that the following conditions
-//are met:
-//
-// Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//
-// Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-//
-// Neither the name of 3Dlabs Inc. Ltd. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-//THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-//"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-//LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
-//FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
-//COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
-//INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
-//BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
-//LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
-//CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-//LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
-//ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
-//POSSIBILITY OF SUCH DAMAGE.
-//
-
-#ifndef _COMMON_INCLUDED_
-#define _COMMON_INCLUDED_
-
-#ifdef _WIN32
- #include <basetsd.h>
-#elif defined (solaris)
- #include <sys/int_types.h>
- #define UINT_PTR uintptr_t
-#else
- #include <stdint.h>
- #define UINT_PTR uintptr_t
-#endif
-
-/* windows only pragma */
-#ifdef _MSC_VER
- #pragma warning(disable : 4786) // Don't warn about too long identifiers
- #pragma warning(disable : 4514) // unused inline method
- #pragma warning(disable : 4201) // nameless union
-#endif
-
-//
-// Doing the push and pop below for warnings does not leave the warning state
-// the way it was. This seems like a defect in the compiler. We would like
-// to do this, but since it does not work correctly right now, it is turned
-// off.
-//
-//??#pragma warning(push, 3)
-
- #include <set>
- #include <vector>
- #include <map>
- #include <list>
- #include <string>
- #include <stdio.h>
-
-//??#pragma warning(pop)
-
-typedef int TSourceLoc;
-
-#include <assert.h>
-#include "PoolAlloc.h"
-
-//
-// Put POOL_ALLOCATOR_NEW_DELETE in base classes to make them use this scheme.
-//
-#define POOL_ALLOCATOR_NEW_DELETE(A) \
- void* operator new(size_t s) { return (A).allocate(s); } \
- void* operator new(size_t, void *_Where) { return (_Where); } \
- void operator delete(void*) { } \
- void operator delete(void *, void *) { } \
- void* operator new[](size_t s) { return (A).allocate(s); } \
- void* operator new[](size_t, void *_Where) { return (_Where); } \
- void operator delete[](void*) { } \
- void operator delete[](void *, void *) { }
-
-#ifdef _M_AMD64
-//
-// The current version of STL that comes with the PSDK (as required for the AMD64 compiler)
-// has a very old version of the STL which is very out of date. As a result, various additions needed
-// making to it to get the compilers compiling!
-//
-
-//
-// A new version of the Map template class - the operator[] now returns the correct type reference
-//
-template <class _K, class _Ty, class _Pr = std::less<_K>, class _A = std::allocator<_Ty> >
-class TBaseMap : public std::map <_K, _Ty, _Pr, _A >
-{
-public :
- _Ty& operator[] (const _K& _Kv)
- {
- iterator _P = insert(value_type(_Kv, _Ty())).first;
- return ((*_P).second);
- }
-
- explicit TBaseMap(const _Pr& _Pred = _Pr(), const _A& _Al = _A())
- : std::map<_K, _Ty, _Pr, _A >(_Pred, _Al) {};
-
-
-};
-
-//
-// A new version of the List template class - the begin function now checks for NULL to eliminate access violations
-//
-template <class _Ty, class _A = std::allocator<_Ty> >
-class TBaseList : public std::list <_Ty, _A >
-{
-public :
- iterator begin()
- {
- return (iterator(_Head == 0 ? 0 : _Acc::_Next(_Head)));
- }
-
- const_iterator begin() const
- {
- return (const_iterator(_Head == 0 ? 0 : _Acc::_Next(_Head)));
- }
-
- //
- // These are required - apparently!
- //
- explicit TBaseList(const _A& _Al = _A())
- : std::list<_Ty, _A >(_Al) {};
- explicit TBaseList(size_type _N, const _Ty& _V = _Ty(), const _A& _Al = _A())
- : std::list<_Ty, _A >(N, _V, _Al) {};
-
-};
-
-//
-// A new version of the set class - this defines the required insert method
-//
-template<class _K, class _Pr = std::less<_K>, class _A = std::allocator<_K> >
-class TBaseSet : public std::set <_K, _Pr, _A>
-{
-public :
-
- //
- // This method wasn't defined
- //
- template<class _Iter>
- void insert(_Iter _First, _Iter _Last)
- { // insert [_First, _Last)
- for (; _First != _Last; ++_First)
- this->insert(*_First);
- }
-
- //
- // These methods were not resolved if I declared the previous method??
- //
- _Pairib insert(const value_type& _X)
- {
- _Imp::_Pairib _Ans = _Tr.insert(_X);
- return (_Pairib(_Ans.first, _Ans.second));
- }
-
- iterator insert(iterator _P, const value_type& _X)
- {
- return (_Tr.insert((_Imp::iterator&)_P, _X));
- }
-
- void insert(_It _F, _It _L)
- {
- for (; _F != _L; ++_F)
- _Tr.insert(*_F);
- }
-
-};
-
-#else
-
-#define TBaseMap std::map
-#define TBaseList std::list
-#define TBaseSet std::set
-
-#endif //_M_AMD64
-
-//
-// Pool version of string.
-//
-typedef pool_allocator<char> TStringAllocator;
-typedef std::basic_string <char, std::char_traits<char>, TStringAllocator > TString;
-inline TString* NewPoolTString(const char* s)
-{
- void* memory = GlobalPoolAllocator.allocate(sizeof(TString));
- return new(memory) TString(s);
-}
-
-//
-// Pool allocator versions of vectors, lists, and maps
-//
-template <class T> class TVector : public std::vector<T, pool_allocator<T> > {
-public:
- typedef typename std::vector<T, pool_allocator<T> >::size_type size_type;
- TVector() : std::vector<T, pool_allocator<T> >() {}
- TVector(const pool_allocator<T>& a) : std::vector<T, pool_allocator<T> >(a) {}
- TVector(size_type i): std::vector<T, pool_allocator<T> >(i) {}
-};
-
-template <class T> class TList : public TBaseList <T, pool_allocator<T> > {
-public:
- typedef typename TBaseList<T, pool_allocator<T> >::size_type size_type;
- TList() : TBaseList<T, pool_allocator<T> >() {}
- TList(const pool_allocator<T>& a) : TBaseList<T, pool_allocator<T> >(a) {}
- TList(size_type i): TBaseList<T, pool_allocator<T> >(i) {}
-};
-
-// This is called TStlSet, because TSet is taken by an existing compiler class.
-template <class T, class CMP> class TStlSet : public std::set<T, CMP, pool_allocator<T> > {
- // No pool allocator versions of constructors in std::set.
-};
-
-
-template <class K, class D, class CMP = std::less<K> > class TMap :
- public TBaseMap<K, D, CMP, pool_allocator<std::pair<K, D> > > {
-public:
- typedef pool_allocator<std::pair <K, D> > tAllocator;
-
- TMap() : TBaseMap<K, D, CMP, tAllocator >() {}
-/*
- TMap(const tAllocator& a) : TBaseMap<K, D, CMP, tAllocator >(key_compare(), a) {}
-*/
- TMap(const tAllocator& a) : TBaseMap<K, D, CMP, tAllocator >() {}
-};
-
-//
-// Persistent string memory. Should only be used for strings that survive
-// across compiles/links.
-//
-typedef std::basic_string<char> TPersistString;
-
-//
-// templatized min and max functions.
-//
-template <class T> T Min(const T a, const T b) { return a < b ? a : b; }
-template <class T> T Max(const T a, const T b) { return a > b ? a : b; }
-
-//
-// Create a TString object from an integer.
-//
-inline const TString String(const int i, const int base = 10)
-{
- char text[16]; // 32 bit ints are at most 10 digits in base 10
-
- #ifdef _WIN32
- itoa(i, text, base);
- #else
- // we assume base 10 for all cases
- sprintf(text, "%d", i);
- #endif
-
- return text;
-}
-
-const unsigned int SourceLocLineMask = 0xffff;
-const unsigned int SourceLocStringShift = 16;
-
-__inline TPersistString FormatSourceLoc(const TSourceLoc loc)
-{
- char locText[64];
-
- int string = loc >> SourceLocStringShift;
- int line = loc & SourceLocLineMask;
-
- if (line)
- sprintf(locText, "%d:%d", string, line);
- else
- sprintf(locText, "%d:? ", string);
-
- return TPersistString(locText);
-}
-typedef TMap<TString, TString> TPragmaTable;
-typedef TMap<TString, TString>::tAllocator TPragmaTableAllocator;
-
-#endif // _COMMON_INCLUDED_
diff --git a/src/mesa/shader/slang/Include/ConstantUnion.h b/src/mesa/shader/slang/Include/ConstantUnion.h deleted file mode 100755 index a60ae114f6..0000000000 --- a/src/mesa/shader/slang/Include/ConstantUnion.h +++ /dev/null @@ -1,50 +0,0 @@ -//
-//Copyright (C) 2002-2005 3Dlabs Inc. Ltd.
-//All rights reserved.
-//
-//Redistribution and use in source and binary forms, with or without
-//modification, are permitted provided that the following conditions
-//are met:
-//
-// Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//
-// Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-//
-// Neither the name of 3Dlabs Inc. Ltd. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-//THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-//"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-//LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
-//FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
-//COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
-//INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
-//BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
-//LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
-//CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-//LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
-//ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
-//POSSIBILITY OF SUCH DAMAGE.
-//
-
-#ifndef _CONSTANT_UNION_INCLUDED_
-#define _CONSTANT_UNION_INCLUDED_
-
-
-class constUnion {
-public:
-
- POOL_ALLOCATOR_NEW_DELETE(GlobalPoolAllocator)
- union {
- int iConst; // used for ivec
- bool bConst; // used for bvec
- float fConst; // used for vec, mat
- } ;
-};
-
-#endif // _CONSTANT_UNION_INCLUDED_
diff --git a/src/mesa/shader/slang/Include/InfoSink.h b/src/mesa/shader/slang/Include/InfoSink.h deleted file mode 100755 index 14d44a34ad..0000000000 --- a/src/mesa/shader/slang/Include/InfoSink.h +++ /dev/null @@ -1,135 +0,0 @@ -//
-//Copyright (C) 2002-2005 3Dlabs Inc. Ltd.
-//All rights reserved.
-//
-//Redistribution and use in source and binary forms, with or without
-//modification, are permitted provided that the following conditions
-//are met:
-//
-// Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//
-// Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-//
-// Neither the name of 3Dlabs Inc. Ltd. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-//THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-//"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-//LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
-//FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
-//COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
-//INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
-//BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
-//LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
-//CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-//LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
-//ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
-//POSSIBILITY OF SUCH DAMAGE.
-//
-
-#ifndef _INFOSINK_INCLUDED_
-#define _INFOSINK_INCLUDED_
-
-#include "../Include/Common.h"
-#include <math.h>
-
-//
-// TPrefixType is used to centralize how info log messages start.
-// See below.
-//
-enum TPrefixType {
- EPrefixNone,
- EPrefixWarning,
- EPrefixError,
- EPrefixInternalError,
- EPrefixUnimplemented
-};
-
-enum TOutputStream {
- ENull = 0,
- EDebugger = 0x01,
- EStdOut = 0x02,
- EString = 0x04
-};
-//
-// Encapsulate info logs for all objects that have them.
-//
-// The methods are a general set of tools for getting a variety of
-// messages and types inserted into the log.
-//
-class TInfoSinkBase {
-public:
- TInfoSinkBase() : outputStream(4) {}
- void erase() { sink.erase(); }
- TInfoSinkBase& operator<<(const TPersistString& t) { append(t); return *this; }
- TInfoSinkBase& operator<<(char c) { append(1, c); return *this; }
- TInfoSinkBase& operator<<(const char* s) { append(s); return *this; }
- TInfoSinkBase& operator<<(int n) { append(String(n)); return *this; }
- TInfoSinkBase& operator<<(const unsigned int n) { append(String(n)); return *this; }
- TInfoSinkBase& operator<<(float n) { char buf[40];
- sprintf(buf, (fabs(n) > 1e-8 && fabs(n) < 1e8) || n == 0.0f ?
- "%f" : "%g", n);
- append(buf);
- return *this; }
- TInfoSinkBase& operator+(const TPersistString& t) { append(t); return *this; }
- TInfoSinkBase& operator+(const TString& t) { append(t); return *this; }
- TInfoSinkBase& operator<<(const TString& t) { append(t); return *this; }
- TInfoSinkBase& operator+(const char* s) { append(s); return *this; }
- const char* c_str() const { return sink.c_str(); }
- void prefix(TPrefixType message) {
- switch(message) {
- case EPrefixNone: break;
- case EPrefixWarning: append("WARNING: "); break;
- case EPrefixError: append("ERROR: "); break;
- case EPrefixInternalError: append("INTERNAL ERROR: "); break;
- case EPrefixUnimplemented: append("UNIMPLEMENTED: "); break;
- default: append("UNKOWN ERROR: "); break;
- }
- }
- void location(TSourceLoc loc) {
- append(FormatSourceLoc(loc).c_str());
- append(": ");
- }
- void message(TPrefixType message, const char* s) {
- prefix(message);
- append(s);
- append("\n");
- }
- void message(TPrefixType message, const char* s, TSourceLoc loc) {
- prefix(message);
- location(loc);
- append(s);
- append("\n");
- }
-
- void setOutputStream(int output = 4)
- {
- outputStream = output;
- }
-
-protected:
- void append(const char *s);
-
- void append(int count, char c);
- void append(const TPersistString& t);
- void append(const TString& t);
-
- void checkMem(size_t growth) { if (sink.capacity() < sink.size() + growth + 2)
- sink.reserve(sink.capacity() + sink.capacity() / 2); }
- void appendToStream(const char* s);
- TPersistString sink;
- int outputStream;
-};
-
-class TInfoSink {
-public:
- TInfoSinkBase info;
- TInfoSinkBase debug;
-};
-
-#endif // _INFOSINK_INCLUDED_
diff --git a/src/mesa/shader/slang/Include/InitializeGlobals.h b/src/mesa/shader/slang/Include/InitializeGlobals.h deleted file mode 100755 index 3d9a42a2b5..0000000000 --- a/src/mesa/shader/slang/Include/InitializeGlobals.h +++ /dev/null @@ -1,43 +0,0 @@ -//
-//Copyright (C) 2002-2005 3Dlabs Inc. Ltd.
-//All rights reserved.
-//
-//Redistribution and use in source and binary forms, with or without
-//modification, are permitted provided that the following conditions
-//are met:
-//
-// Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//
-// Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-//
-// Neither the name of 3Dlabs Inc. Ltd. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-//THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-//"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-//LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
-//FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
-//COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
-//INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
-//BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
-//LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
-//CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-//LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
-//ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
-//POSSIBILITY OF SUCH DAMAGE.
-//
-
-#ifndef __INITIALIZE_GLOBALS_INCLUDED_
-#define __INITIALIZE_GLOBALS_INCLUDED_
-
-void InitializeGlobalPools();
-void FreeGlobalPools();
-bool InitializePoolIndex();
-void FreePoolIndex();
-
-#endif // __INITIALIZE_GLOBALS_INCLUDED_
diff --git a/src/mesa/shader/slang/Include/InitializeParseContext.h b/src/mesa/shader/slang/Include/InitializeParseContext.h deleted file mode 100755 index 7d565b3132..0000000000 --- a/src/mesa/shader/slang/Include/InitializeParseContext.h +++ /dev/null @@ -1,44 +0,0 @@ -//
-//Copyright (C) 2002-2005 3Dlabs Inc. Ltd.
-//All rights reserved.
-//
-//Redistribution and use in source and binary forms, with or without
-//modification, are permitted provided that the following conditions
-//are met:
-//
-// Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//
-// Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-//
-// Neither the name of 3Dlabs Inc. Ltd. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-//THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-//"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-//LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
-//FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
-//COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
-//INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
-//BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
-//LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
-//CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-//LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
-//ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
-//POSSIBILITY OF SUCH DAMAGE.
-//
-
-#ifndef __INITIALIZE_PARSE_CONTEXT_INCLUDED_
-#define __INITIALIZE_PARSE_CONTEXT_INCLUDED_
-#include "osinclude.h"
-
-bool InitializeParseContextIndex();
-bool InitializeGlobalParseContext();
-bool FreeParseContext();
-bool FreeParseContextIndex();
-
-#endif // __INITIALIZE_PARSE_CONTEXT_INCLUDED_
diff --git a/src/mesa/shader/slang/Include/PoolAlloc.h b/src/mesa/shader/slang/Include/PoolAlloc.h deleted file mode 100755 index e224d3b867..0000000000 --- a/src/mesa/shader/slang/Include/PoolAlloc.h +++ /dev/null @@ -1,346 +0,0 @@ -//
-//Copyright (C) 2002-2005 3Dlabs Inc. Ltd.
-//All rights reserved.
-//
-//Redistribution and use in source and binary forms, with or without
-//modification, are permitted provided that the following conditions
-//are met:
-//
-// Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//
-// Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-//
-// Neither the name of 3Dlabs Inc. Ltd. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-//THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-//"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-//LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
-//FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
-//COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
-//INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
-//BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
-//LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
-//CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-//LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
-//ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
-//POSSIBILITY OF SUCH DAMAGE.
-//
-
-#ifndef _POOLALLOC_INCLUDED_
-#define _POOLALLOC_INCLUDED_
-
-#ifdef _DEBUG
-# define GUARD_BLOCKS // define to enable guard block sanity checking
-#endif
-
-//
-// This header defines an allocator that can be used to efficiently
-// allocate a large number of small requests for heap memory, with the
-// intention that they are not individually deallocated, but rather
-// collectively deallocated at one time.
-//
-// This simultaneously
-//
-// * Makes each individual allocation much more efficient; the
-// typical allocation is trivial.
-// * Completely avoids the cost of doing individual deallocation.
-// * Saves the trouble of tracking down and plugging a large class of leaks.
-//
-// Individual classes can use this allocator by supplying their own
-// new and delete methods.
-//
-// STL containers can use this allocator by using the pool_allocator
-// class as the allocator (second) template argument.
-//
-
-#include <stddef.h>
-#include <vector>
-
-// If we are using guard blocks, we must track each indivual
-// allocation. If we aren't using guard blocks, these
-// never get instantiated, so won't have any impact.
-//
-
-class TAllocation {
-public:
- TAllocation(size_t size, unsigned char* mem, TAllocation* prev = 0) :
- size(size), mem(mem), prevAlloc(prev) {
- // Allocations are bracketed:
- // [allocationHeader][initialGuardBlock][userData][finalGuardBlock]
- // This would be cleaner with if (guardBlockSize)..., but that
- // makes the compiler print warnings about 0 length memsets,
- // even with the if() protecting them.
-# ifdef GUARD_BLOCKS
- memset(preGuard(), guardBlockBeginVal, guardBlockSize);
- memset(data(), userDataFill, size);
- memset(postGuard(), guardBlockEndVal, guardBlockSize);
-# endif
- }
-
- void check() const {
- checkGuardBlock(preGuard(), guardBlockBeginVal, "before");
- checkGuardBlock(postGuard(), guardBlockEndVal, "after");
- }
-
- void checkAllocList() const;
-
- // Return total size needed to accomodate user buffer of 'size',
- // plus our tracking data.
- inline static size_t allocationSize(size_t size) {
- return size + 2 * guardBlockSize + headerSize();
- }
-
- // Offset from surrounding buffer to get to user data buffer.
- inline static unsigned char* offsetAllocation(unsigned char* m) {
- return m + guardBlockSize + headerSize();
- }
-
-private:
- void checkGuardBlock(unsigned char* blockMem, unsigned char val, char* locText) const;
-
- // Find offsets to pre and post guard blocks, and user data buffer
- unsigned char* preGuard() const { return mem + headerSize(); }
- unsigned char* data() const { return preGuard() + guardBlockSize; }
- unsigned char* postGuard() const { return data() + size; }
-
- size_t size; // size of the user data area
- unsigned char* mem; // beginning of our allocation (pts to header)
- TAllocation* prevAlloc; // prior allocation in the chain
-
- // Support MSVC++ 6.0
- const static unsigned char guardBlockBeginVal;
- const static unsigned char guardBlockEndVal;
- const static unsigned char userDataFill;
-
-# ifdef GUARD_BLOCKS
- const static size_t guardBlockSize;
- inline static size_t headerSize() { return sizeof(TAllocation); }
-# else
- const static size_t guardBlockSize;
- inline static size_t headerSize() { return 0; }
-# endif
-};
-
-//
-// There are several stacks. One is to track the pushing and popping
-// of the user, and not yet implemented. The others are simply a
-// repositories of free pages or used pages.
-//
-// Page stacks are linked together with a simple header at the beginning
-// of each allocation obtained from the underlying OS. Multi-page allocations
-// are returned to the OS. Individual page allocations are kept for future
-// re-use.
-//
-// The "page size" used is not, nor must it match, the underlying OS
-// page size. But, having it be about that size or equal to a set of
-// pages is likely most optimal.
-//
-class TPoolAllocator {
-public:
- TPoolAllocator(bool global = false, int growthIncrement = 8*1024, int allocationAlignment = 16);
-
- //
- // Don't call the destructor just to free up the memory, call pop()
- //
- ~TPoolAllocator();
-
- //
- // Call push() to establish a new place to pop memory too. Does not
- // have to be called to get things started.
- //
- void push();
-
- //
- // Call pop() to free all memory allocated since the last call to push(),
- // or if no last call to push, frees all memory since first allocation.
- //
- void pop();
-
- //
- // Call popAll() to free all memory allocated.
- //
- void popAll();
-
- //
- // Call allocate() to actually acquire memory. Returns 0 if no memory
- // available, otherwise a properly aligned pointer to 'numBytes' of memory.
- //
- void* allocate(size_t numBytes);
-
- //
- // There is no deallocate. The point of this class is that
- // deallocation can be skipped by the user of it, as the model
- // of use is to simultaneously deallocate everything at once
- // by calling pop(), and to not have to solve memory leak problems.
- //
-
-protected:
- friend struct tHeader;
-
- struct tHeader {
- tHeader(tHeader* nextPage, size_t pageCount) :
-#ifdef GUARD_BLOCKS
- lastAllocation(0),
-#endif
- nextPage(nextPage), pageCount(pageCount) { }
-
- ~tHeader() {
-#ifdef GUARD_BLOCKS
- if (lastAllocation)
- lastAllocation->checkAllocList();
-#endif
- }
-
- tHeader* nextPage;
- size_t pageCount;
-#ifdef GUARD_BLOCKS
- TAllocation* lastAllocation;
-#endif
- };
-
- struct tAllocState {
- size_t offset;
- tHeader* page;
- };
- typedef std::vector<tAllocState> tAllocStack;
-
- // Track allocations if and only if we're using guard blocks
- void* initializeAllocation(tHeader* block, unsigned char* memory, size_t numBytes) {
-# ifdef GUARD_BLOCKS
- new(memory) TAllocation(numBytes, memory, block->lastAllocation);
- block->lastAllocation = reinterpret_cast<TAllocation*>(memory);
-# endif
-
- // This is optimized entirely away if GUARD_BLOCKS is not defined.
- return TAllocation::offsetAllocation(memory);
- }
-
- bool global; // should be true if this object is globally scoped
- size_t pageSize; // granularity of allocation from the OS
- size_t alignment; // all returned allocations will be aligned at
- // this granularity, which will be a power of 2
- size_t alignmentMask;
- size_t headerSkip; // amount of memory to skip to make room for the
- // header (basically, size of header, rounded
- // up to make it aligned
- size_t currentPageOffset; // next offset in top of inUseList to allocate from
- tHeader* freeList; // list of popped memory
- tHeader* inUseList; // list of all memory currently being used
- tAllocStack stack; // stack of where to allocate from, to partition pool
-
- int numCalls; // just an interesting statistic
- size_t totalBytes; // just an interesting statistic
-private:
- TPoolAllocator& operator=(const TPoolAllocator&); // dont allow assignment operator
- TPoolAllocator(const TPoolAllocator&); // dont allow default copy constructor
-};
-
-
-//
-// There could potentially be many pools with pops happening at
-// different times. But a simple use is to have a global pop
-// with everyone using the same global allocator.
-//
-typedef TPoolAllocator* PoolAllocatorPointer;
-extern TPoolAllocator& GetGlobalPoolAllocator();
-#define GlobalPoolAllocator GetGlobalPoolAllocator()
-struct TThreadGlobalPools
-{
- TPoolAllocator* globalPoolAllocator;
-};
-
-//
-// This STL compatible allocator is intended to be used as the allocator
-// parameter to templatized STL containers, like vector and map.
-//
-// It will use the pools for allocation, and not
-// do any deallocation, but will still do destruction.
-//
-template<class T>
-class pool_allocator {
-public:
- typedef size_t size_type;
- typedef ptrdiff_t difference_type;
- typedef T *pointer;
- typedef const T *const_pointer;
- typedef T& reference;
- typedef const T& const_reference;
- typedef T value_type;
- template<class Other>
- struct rebind {
- typedef pool_allocator<Other> other;
- };
- pointer address(reference x) const { return &x; }
- const_pointer address(const_reference x) const { return &x; }
-
-#ifdef USING_SGI_STL
- pool_allocator() { }
-#else
- pool_allocator() : allocator(GlobalPoolAllocator) { }
- pool_allocator(TPoolAllocator& a) : allocator(a) { }
- pool_allocator(const pool_allocator<T>& p) : allocator(p.allocator) { }
-#endif
-
-#if defined(_MSC_VER) && _MSC_VER >= 1300
- template<class Other>
-#ifdef USING_SGI_STL
- pool_allocator(const pool_allocator<Other>& p) /*: allocator(p.getAllocator())*/ { }
-#else
- pool_allocator(const pool_allocator<Other>& p) : allocator(p.getAllocator()) { }
-#endif
-#endif
-
-#ifndef _WIN32
- template<class Other>
- pool_allocator(const pool_allocator<Other>& p) : allocator(p.getAllocator()) { }
-#endif
-
-#ifdef USING_SGI_STL
- static pointer allocate(size_type n) {
- return reinterpret_cast<pointer>(getAllocator().allocate(n)); }
- pointer allocate(size_type n, const void*) {
- return reinterpret_cast<pointer>(getAllocator().allocate(n)); }
-
- static void deallocate(void*, size_type) { }
- static void deallocate(pointer, size_type) { }
-#else
- pointer allocate(size_type n) {
- return reinterpret_cast<pointer>(getAllocator().allocate(n * sizeof(T))); }
- pointer allocate(size_type n, const void*) {
- return reinterpret_cast<pointer>(getAllocator().allocate(n * sizeof(T))); }
-
- void deallocate(void*, size_type) { }
- void deallocate(pointer, size_type) { }
-#endif
-
- pointer _Charalloc(size_t n) {
- return reinterpret_cast<pointer>(getAllocator().allocate(n)); }
-
- void construct(pointer p, const T& val) { new ((void *)p) T(val); }
- void destroy(pointer p) { p->T::~T(); }
-
- bool operator==(const pool_allocator& rhs) const { return &getAllocator() == &rhs.getAllocator(); }
- bool operator!=(const pool_allocator& rhs) const { return &getAllocator() != &rhs.getAllocator(); }
-
- size_type max_size() const { return static_cast<size_type>(-1) / sizeof(T); }
- size_type max_size(int size) const { return static_cast<size_type>(-1) / size; }
-
-#ifdef USING_SGI_STL
- //void setAllocator(TPoolAllocator* a) { allocator = a; }
- static TPoolAllocator& getAllocator() { return GlobalPoolAllocator; }
-#else
- void setAllocator(TPoolAllocator* a) { allocator = *a; }
- TPoolAllocator& getAllocator() const { return allocator; }
-
-protected:
- TPoolAllocator& allocator;
-#endif
-};
-
-#endif // _POOLALLOC_INCLUDED_
diff --git a/src/mesa/shader/slang/Include/ResourceLimits.h b/src/mesa/shader/slang/Include/ResourceLimits.h deleted file mode 100755 index ef24244c28..0000000000 --- a/src/mesa/shader/slang/Include/ResourceLimits.h +++ /dev/null @@ -1,61 +0,0 @@ -/*
-//Copyright (C) 2002-2005 3Dlabs Inc. Ltd.
-//All rights reserved.
-//
-//Redistribution and use in source and binary forms, with or without
-//modification, are permitted provided that the following conditions
-//are met:
-//
-// Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//
-// Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-//
-// Neither the name of 3Dlabs Inc. Ltd. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-//THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-//"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-//LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
-//FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
-//COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
-//INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
-//BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
-//LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
-//CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-//LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
-//ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
-//POSSIBILITY OF SUCH DAMAGE.
-*/
-
-#ifndef _RESOURCE_LIMITS_INCLUDED_
-#define _RESOURCE_LIMITS_INCLUDED_
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-typedef struct TBuiltInResource_ {
- int maxLights;
- int maxClipPlanes;
- int maxTextureUnits;
- int maxTextureCoords;
- int maxVertexAttribs;
- int maxVertexUniformComponents;
- int maxVaryingFloats;
- int maxVertexTextureImageUnits;
- int maxCombinedTextureImageUnits;
- int maxTextureImageUnits;
- int maxFragmentUniformComponents;
- int maxDrawBuffers;
-} TBuiltInResource;
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _RESOURCE_LIMITS_INCLUDED_ */
diff --git a/src/mesa/shader/slang/Include/ShHandle.h b/src/mesa/shader/slang/Include/ShHandle.h deleted file mode 100755 index 82c0314f34..0000000000 --- a/src/mesa/shader/slang/Include/ShHandle.h +++ /dev/null @@ -1,177 +0,0 @@ -//
-//Copyright (C) 2002-2005 3Dlabs Inc. Ltd.
-//All rights reserved.
-//
-//Redistribution and use in source and binary forms, with or without
-//modification, are permitted provided that the following conditions
-//are met:
-//
-// Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//
-// Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-//
-// Neither the name of 3Dlabs Inc. Ltd. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-//THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-//"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-//LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
-//FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
-//COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
-//INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
-//BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
-//LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
-//CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-//LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
-//ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
-//POSSIBILITY OF SUCH DAMAGE.
-//
-
-#ifndef _SHHANDLE_INCLUDED_
-#define _SHHANDLE_INCLUDED_
-
-//
-// Machine independent part of the compiler private objects
-// sent as ShHandle to the driver.
-//
-// This should not be included by driver code.
-//
-
-#define SH_EXPORTING
-#include "../Public/ShaderLangExt.h"
-#include "InfoSink.h"
-
-class TCompiler;
-class TLinker;
-class TUniformMap;
-namespace Lf {
- class TBindingList;
- class TLinker;
- class TLibrary;
-}
-
-//
-// The base class used to back handles returned to the driver.
-//
-class TShHandleBase {
-public:
- TShHandleBase() { }
- virtual ~TShHandleBase() { }
- virtual TCompiler* getAsCompiler() { return 0; }
- virtual TLinker* getAsLinker() { return 0; }
- virtual Lf::TLinker* getAsNewLinker() { return 0; }
- virtual TUniformMap* getAsUniformMap() { return 0; }
- virtual Lf::TBindingList* getAsBindingList() { return 0; }
- virtual Lf::TLibrary* getAsLibrary() { return 0; }
-};
-//
-// The base class for the machine dependent linker to derive from
-// for managing where uniforms live.
-//
-class TUniformMap : public TShHandleBase {
-public:
- TUniformMap() { }
- virtual ~TUniformMap() { }
- virtual TUniformMap* getAsUniformMap() { return this; }
- virtual int getLocation(const char* name) = 0;
- virtual TInfoSink& getInfoSink() { return infoSink; }
- TInfoSink infoSink;
-};
-
-class TIntermNode;
-
-//
-// The base class for the machine dependent compiler to derive from
-// for managing object code from the compile.
-//
-class TCompiler : public TShHandleBase {
-public:
- TCompiler(EShLanguage l, TInfoSink& sink) : infoSink(sink) , language(l), haveValidObjectCode(false) { }
- virtual ~TCompiler() { }
- EShLanguage getLanguage() { return language; }
- virtual TInfoSink& getInfoSink() { return infoSink; }
-
- virtual bool compile(TIntermNode* root) = 0;
-
- virtual TCompiler* getAsCompiler() { return this; }
- virtual bool linkable() { return haveValidObjectCode; }
-
- TInfoSink& infoSink;
-protected:
- EShLanguage language;
- bool haveValidObjectCode;
-};
-
-//
-// Link operations are base on a list of compile results...
-//
-typedef TVector<TCompiler*> TCompilerList;
-typedef TVector<TShHandleBase*> THandleList;
-
-//
-// The base class for the machine dependent linker to derive from
-// to manage the resulting executable.
-//
-
-class TLinker : public TShHandleBase {
-public:
- TLinker(EShExecutable e, TInfoSink& iSink) :
- infoSink(iSink),
- executable(e),
- haveReturnableObjectCode(false),
- appAttributeBindings(0),
- fixedAttributeBindings(0),
- excludedAttributes(0),
- excludedCount(0),
- uniformBindings(0) { }
- virtual TLinker* getAsLinker() { return this; }
- virtual ~TLinker() { }
- virtual bool link(TCompilerList&, TUniformMap*) = 0;
- virtual bool link(THandleList&) { return false; }
- virtual void setAppAttributeBindings(const ShBindingTable* t) { appAttributeBindings = t; }
- virtual void setFixedAttributeBindings(const ShBindingTable* t) { fixedAttributeBindings = t; }
- virtual void getAttributeBindings(ShBindingTable const **t) const = 0;
- virtual void setExcludedAttributes(const int* attributes, int count) { excludedAttributes = attributes; excludedCount = count; }
- virtual ShBindingTable* getUniformBindings() const { return uniformBindings; }
- virtual const void* getObjectCode() const { return 0; } // a real compiler would be returning object code here
- virtual TInfoSink& getInfoSink() { return infoSink; }
- TInfoSink& infoSink;
-protected:
- EShExecutable executable;
- bool haveReturnableObjectCode; // true when objectCode is acceptable to send to driver
-
- const ShBindingTable* appAttributeBindings;
- const ShBindingTable* fixedAttributeBindings;
- const int* excludedAttributes;
- int excludedCount;
- ShBindingTable* uniformBindings; // created by the linker
-};
-
-//
-// This is the interface between the machine independent code
-// and the machine dependent code.
-//
-// The machine dependent code should derive from the classes
-// above. Then Construct*() and Delete*() will create and
-// destroy the machine dependent objects, which contain the
-// above machine independent information.
-//
-TCompiler* ConstructCompiler(EShLanguage, int);
-
-TShHandleBase* ConstructLinker(EShExecutable, int);
-TShHandleBase* ConstructBindings();
-TShHandleBase* ConstructLibrary();
-void DeleteLinker(TShHandleBase*);
-
-TUniformMap* ConstructUniformMap();
-void DeleteCompiler(TCompiler*);
-
-void DeleteUniformMap(TUniformMap*);
-void freeTargetDependentData(void*);
-
-#endif // _SHHANDLE_INCLUDED_
diff --git a/src/mesa/shader/slang/Include/Types.h b/src/mesa/shader/slang/Include/Types.h deleted file mode 100755 index 9415879afe..0000000000 --- a/src/mesa/shader/slang/Include/Types.h +++ /dev/null @@ -1,297 +0,0 @@ -//
-//Copyright (C) 2002-2005 3Dlabs Inc. Ltd.
-//All rights reserved.
-//
-//Redistribution and use in source and binary forms, with or without
-//modification, are permitted provided that the following conditions
-//are met:
-//
-// Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//
-// Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-//
-// Neither the name of 3Dlabs Inc. Ltd. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-//THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-//"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-//LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
-//FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
-//COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
-//INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
-//BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
-//LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
-//CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-//LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
-//ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
-//POSSIBILITY OF SUCH DAMAGE.
-//
-
-#ifndef _TYPES_INCLUDED
-#define _TYPES_INCLUDED
-
-#include "../Include/Common.h"
-#include "../Include/BaseTypes.h"
-
-//
-// Need to have association of line numbers to types in a list for building structs.
-//
-class TType;
-struct TTypeLine {
- TType* type;
- int line;
-};
-typedef TVector<TTypeLine> TTypeList;
-
-inline TTypeList* NewPoolTTypeList()
-{
- void* memory = GlobalPoolAllocator.allocate(sizeof(TTypeList));
- return new(memory) TTypeList;
-}
-
-//
-// This is a workaround for a problem with the yacc stack, It can't have
-// types that the compiler thinks non-trivial constructors. It should
-// just be used while recognizing the grammar, not anything else. Pointers
-// could be used, but also trying to avoid lots of memory management overhead.
-//
-// Not as bad as it looks, there is no actual assumption that the fields
-// match up or are name the same or anything like that.
-//
-class TPublicType {
-public:
- TBasicType type;
- TQualifier qualifier;
- int size; // size of vector or matrix, not size of array
- bool matrix;
- bool array;
- TType* userDef;
- int line;
-};
-
-typedef std::map<TTypeList*, TTypeList*> TStructureMap;
-typedef std::map<TTypeList*, TTypeList*>::iterator TStructureMapIterator;
-//
-// Base class for things that have a type.
-//
-class TType {
-public:
- POOL_ALLOCATOR_NEW_DELETE(GlobalPoolAllocator)
- explicit TType(TBasicType t, TQualifier q = EvqTemporary, int s = 1, bool m = false, bool a = false) :
- type(t), qualifier(q), size(s), matrix(m), array(a), arraySize(0), structure(0),
- structureSize(0), maxArraySize(0), arrayInformationType(0), fieldName(0), typeName(0), mangled(0)
- { }
- explicit TType(TPublicType p) :
- type(p.type), qualifier(p.qualifier), size(p.size), matrix(p.matrix), array(p.array), arraySize(0),
- structure(0), structureSize(0), maxArraySize(0), arrayInformationType(0), fieldName(0), typeName(0), mangled(0)
- {
- if (p.userDef) {
- structure = p.userDef->getStruct();
- structureSize = setStructSize(p.userDef->getStruct());
- typeName = NewPoolTString(p.userDef->getTypeName().c_str());
- }
- }
- explicit TType(TTypeList* userDef, TString n) :
- type(EbtStruct), qualifier(EvqTemporary), size(1), matrix(false), array(false), arraySize(0),
- structure(userDef), maxArraySize(0), arrayInformationType(0), fieldName(0), mangled(0) {
- structureSize = setStructSize(userDef);
- typeName = NewPoolTString(n.c_str());
- }
- explicit TType() {}
- virtual ~TType() {}
-
- TType (const TType& type) { *this = type; }
-
- void copyType(const TType& copyOf, TStructureMap& remapper)
- {
- type = copyOf.type;
- qualifier = copyOf.qualifier;
- size = copyOf.size;
- matrix = copyOf.matrix;
- array = copyOf.array;
- arraySize = copyOf.arraySize;
-
- TStructureMapIterator iter;
- if (copyOf.structure) {
- if ((iter = remapper.find(structure)) == remapper.end()) {
- // create the new structure here
- structure = NewPoolTTypeList();
- for (unsigned int i = 0; i < copyOf.structure->size(); ++i) {
- TTypeLine typeLine;
- typeLine.line = (*copyOf.structure)[i].line;
- typeLine.type = (*copyOf.structure)[i].type->clone(remapper);
- structure->push_back(typeLine);
- }
- } else {
- structure = iter->second;
- }
- } else
- structure = 0;
-
- fieldName = 0;
- if (copyOf.fieldName)
- fieldName = NewPoolTString(copyOf.fieldName->c_str());
- typeName = 0;
- if (copyOf.typeName)
- typeName = NewPoolTString(copyOf.typeName->c_str());
-
- mangled = 0;
- if (copyOf.mangled)
- mangled = NewPoolTString(copyOf.mangled->c_str());
-
- structureSize = copyOf.structureSize;
- maxArraySize = copyOf.maxArraySize;
- assert (copyOf.arrayInformationType == 0);
- arrayInformationType = 0; // arrayInformationType should not be set for builtIn symbol table level
- }
-
- TType* clone(TStructureMap& remapper)
- {
- TType *newType = new TType();
- newType->copyType(*this, remapper);
-
- return newType;
- }
-
- int setStructSize(TTypeList* userDef)
- {
- int stSize = 0;
- for (TTypeList::iterator tl = userDef->begin(); tl != userDef->end(); tl++) {
- if (((*tl).type)->isArray()) {
- if (((*tl).type)->getStruct()) {
- int structSize = setStructSize(((*tl).type)->getStruct());
- stSize += structSize * ((*tl).type)->getArraySize();
- } else {
- stSize += ((*tl).type)->getInstanceSize() * ((*tl).type)->getArraySize();
- }
- } else if (((*tl).type)->isMatrix() || ((*tl).type)->isVector()){
- stSize += ((*tl).type)->getInstanceSize();
- } else if (((*tl).type)->getStruct()) {
- //?? We should actually be calling getStructSize() function and not setStructSize. This problem occurs in case
- // of nested/embedded structs.
- stSize += setStructSize(((*tl).type)->getStruct());
- } else
- stSize += 1;
- }
- structureSize = stSize;
- return stSize;
- }
-
- virtual void setType(TBasicType t, int s, bool m, bool a, int aS = 0)
- { type = t; size = s; matrix = m; array = a; arraySize = aS; }
- virtual void setType(TBasicType t, int s, bool m, TType* userDef = 0)
- { type = t;
- size = s;
- matrix = m;
- if (userDef)
- structure = userDef->getStruct();
- // leave array information intact.
- }
- virtual void setTypeName(const TString& n) { typeName = NewPoolTString(n.c_str()); }
- virtual void setFieldName(const TString& n) { fieldName = NewPoolTString(n.c_str()); }
- virtual const TString& getTypeName() const
- {
- assert (typeName);
- return *typeName;
- }
-
- virtual const TString& getFieldName() const
- {
- assert (fieldName);
- return *fieldName;
- }
-
- virtual TBasicType getBasicType() const { return type; }
- virtual TQualifier getQualifier() const { return qualifier; }
- virtual void changeQualifier(TQualifier q) { qualifier = q; }
-
- // One-dimensional size of single instance type
- virtual int getNominalSize() const { return size; }
-
- // Full-dimensional size of single instance of type
- virtual int getInstanceSize() const
- {
- if (matrix)
- return size * size;
- else
- return size;
- }
-
- virtual bool isMatrix() const { return matrix ? true : false; }
- virtual bool isArray() const { return array ? true : false; }
- int getArraySize() const { return arraySize; }
- void setArraySize(int s) { array = true; arraySize = s; }
- void setMaxArraySize (int s) { maxArraySize = s; }
- int getMaxArraySize () const { return maxArraySize; }
- void setArrayInformationType(TType* t) { arrayInformationType = t; }
- TType* getArrayInformationType() { return arrayInformationType; }
- virtual bool isVector() const { return size > 1 && !matrix; }
- static char* getBasicString(TBasicType t) {
- switch (t) {
- case EbtVoid: return "void"; break;
- case EbtFloat: return "float"; break;
- case EbtInt: return "int"; break;
- case EbtBool: return "bool"; break;
- case EbtSampler1D: return "sampler1D"; break;
- case EbtSampler2D: return "sampler2D"; break;
- case EbtSampler3D: return "sampler3D"; break;
- case EbtSamplerCube: return "samplerCube"; break;
- case EbtSampler1DShadow: return "sampler1DShadow"; break;
- case EbtSampler2DShadow: return "sampler2DShadow"; break;
- case EbtStruct: return "structure"; break;
- default: return "unknown type";
- }
- }
- const char* getBasicString() const { return TType::getBasicString(type); }
- const char* getQualifierString() const { return ::getQualifierString(qualifier); }
- TTypeList* getStruct() { return structure; }
- int getStructSize() const { return structureSize; }
- TTypeList* getStruct() const { return structure; }
- TString& getMangledName() {
- if (!mangled) {
- mangled = NewPoolTString("");
- buildMangledName(*mangled);
- *mangled+=';';
- }
-
- return *mangled;
- }
- bool operator==(const TType& right) const {
- return type == right.type &&
- size == right.size &&
- matrix == right.matrix &&
- array == right.array &&
- structure == right.structure;
- // don't check the qualifier, it's not ever what's being sought after
- }
- bool operator!=(const TType& right) const {
- return !operator==(right);
- }
- TString getCompleteString() const;
-
-protected:
- void buildMangledName(TString&);
-
- TBasicType type : 6;
- TQualifier qualifier : 7;
- int size : 8; // size of vector or matrix, not size of array
- unsigned int matrix : 1;
- unsigned int array : 1;
-
- int arraySize;
- TTypeList* structure; // 0 unless this is a struct
- int structureSize;
- int maxArraySize;
- TType* arrayInformationType;
- TString *fieldName; // for structure field names
- TString *typeName; // for structure field type name
- TString *mangled;
-
-};
-
-#endif // _TYPES_INCLUDED_
diff --git a/src/mesa/shader/slang/Include/intermediate.h b/src/mesa/shader/slang/Include/intermediate.h deleted file mode 100755 index 13e22c2749..0000000000 --- a/src/mesa/shader/slang/Include/intermediate.h +++ /dev/null @@ -1,516 +0,0 @@ -//
-//Copyright (C) 2002-2005 3Dlabs Inc. Ltd.
-//All rights reserved.
-//
-//Redistribution and use in source and binary forms, with or without
-//modification, are permitted provided that the following conditions
-//are met:
-//
-// Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//
-// Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-//
-// Neither the name of 3Dlabs Inc. Ltd. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-//THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-//"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-//LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
-//FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
-//COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
-//INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
-//BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
-//LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
-//CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-//LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
-//ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
-//POSSIBILITY OF SUCH DAMAGE.
-//
-
-//
-// Definition of the in-memory high-level intermediate representation
-// of shaders. This is a tree that parser creates.
-//
-// Nodes in the tree are defined as a hierarchy of classes derived from
-// TIntermNode. Each is a node in a tree. There is no preset branching factor;
-// each node can have it's own type of list of children.
-//
-
-#ifndef __INTERMEDIATE_H
-#define __INTERMEDIATE_H
-
-#include "../Include/Common.h"
-#include "../Include/Types.h"
-#include "../Include/ConstantUnion.h"
-
-//
-// Operators used by the high-level (parse tree) representation.
-//
-enum TOperator {
- EOpNull, // if in a node, should only mean a node is still being built
- EOpSequence, // denotes a list of statements, or parameters, etc.
- EOpFunctionCall,
- EOpFunction, // For function definition
- EOpParameters, // an aggregate listing the parameters to a function
-
- //
- // Unary operators
- //
-
- EOpNegative,
- EOpLogicalNot,
- EOpVectorLogicalNot,
- EOpBitwiseNot,
-
- EOpPostIncrement,
- EOpPostDecrement,
- EOpPreIncrement,
- EOpPreDecrement,
-
- EOpConvIntToBool,
- EOpConvFloatToBool,
- EOpConvBoolToFloat,
- EOpConvIntToFloat,
- EOpConvFloatToInt,
- EOpConvBoolToInt,
-
- //
- // binary operations
- //
-
- EOpAdd,
- EOpSub,
- EOpMul,
- EOpDiv,
- EOpMod,
- EOpRightShift,
- EOpLeftShift,
- EOpAnd,
- EOpInclusiveOr,
- EOpExclusiveOr,
- EOpEqual,
- EOpNotEqual,
- EOpVectorEqual,
- EOpVectorNotEqual,
- EOpLessThan,
- EOpGreaterThan,
- EOpLessThanEqual,
- EOpGreaterThanEqual,
- EOpComma,
-
- EOpVectorTimesScalar,
- EOpVectorTimesMatrix,
- EOpMatrixTimesVector,
- EOpMatrixTimesScalar,
-
- EOpLogicalOr,
- EOpLogicalXor,
- EOpLogicalAnd,
-
- EOpIndexDirect,
- EOpIndexIndirect,
- EOpIndexDirectStruct,
-
- EOpVectorSwizzle,
-
- //
- // Built-in functions potentially mapped to operators
- //
-
- EOpRadians,
- EOpDegrees,
- EOpSin,
- EOpCos,
- EOpTan,
- EOpAsin,
- EOpAcos,
- EOpAtan,
-
- EOpPow,
- EOpExp,
- EOpLog,
- EOpExp2,
- EOpLog2,
- EOpSqrt,
- EOpInverseSqrt,
-
- EOpAbs,
- EOpSign,
- EOpFloor,
- EOpCeil,
- EOpFract,
- EOpMin,
- EOpMax,
- EOpClamp,
- EOpMix,
- EOpStep,
- EOpSmoothStep,
-
- EOpLength,
- EOpDistance,
- EOpDot,
- EOpCross,
- EOpNormalize,
- EOpFaceForward,
- EOpReflect,
- EOpRefract,
-
- EOpDPdx, // Fragment only
- EOpDPdy, // Fragment only
- EOpFwidth, // Fragment only
-
- EOpMatrixTimesMatrix,
-
- EOpAny,
- EOpAll,
-
- EOpItof, // pack/unpack only
- EOpFtoi, // pack/unpack only
- EOpSkipPixels, // pack/unpack only
- EOpReadInput, // unpack only
- EOpWritePixel, // unpack only
- EOpBitmapLsb, // unpack only
- EOpBitmapMsb, // unpack only
- EOpWriteOutput, // pack only
- EOpReadPixel, // pack only
-
- //
- // Branch
- //
-
- EOpKill, // Fragment only
- EOpReturn,
- EOpBreak,
- EOpContinue,
-
- //
- // Constructors
- //
-
- EOpConstructInt,
- EOpConstructBool,
- EOpConstructFloat,
- EOpConstructVec2,
- EOpConstructVec3,
- EOpConstructVec4,
- EOpConstructBVec2,
- EOpConstructBVec3,
- EOpConstructBVec4,
- EOpConstructIVec2,
- EOpConstructIVec3,
- EOpConstructIVec4,
- EOpConstructMat2,
- EOpConstructMat3,
- EOpConstructMat4,
- EOpConstructStruct,
-
- //
- // moves
- //
-
- EOpAssign,
- EOpAddAssign,
- EOpSubAssign,
- EOpMulAssign,
- EOpVectorTimesMatrixAssign,
- EOpVectorTimesScalarAssign,
- EOpMatrixTimesScalarAssign,
- EOpMatrixTimesMatrixAssign,
- EOpDivAssign,
- EOpModAssign,
- EOpAndAssign,
- EOpInclusiveOrAssign,
- EOpExclusiveOrAssign,
- EOpLeftShiftAssign,
- EOpRightShiftAssign
-};
-
-class TIntermTraverser;
-class TIntermAggregate;
-class TIntermBinary;
-class TIntermConstantUnion;
-class TIntermSelection;
-class TIntermTyped;
-class TIntermSymbol;
-class TInfoSink;
-
-//
-// Base class for the tree nodes
-//
-class TIntermNode {
-public:
- POOL_ALLOCATOR_NEW_DELETE(GlobalPoolAllocator)
-
- TIntermNode() : line(0) {}
- virtual TSourceLoc getLine() const { return line; }
- virtual void setLine(TSourceLoc l) { line = l; }
- virtual void traverse(TIntermTraverser*) = 0;
- virtual TIntermTyped* getAsTyped() { return 0; }
- virtual TIntermConstantUnion* getAsConstantUnion() { return 0; }
- virtual TIntermAggregate* getAsAggregate() { return 0; }
- virtual TIntermBinary* getAsBinaryNode() { return 0; }
- virtual TIntermSelection* getAsSelectionNode() { return 0; }
- virtual TIntermSymbol* getAsSymbolNode() { return 0; }
- virtual ~TIntermNode() { }
-protected:
- TSourceLoc line;
-};
-
-//
-// This is just to help yacc.
-//
-struct TIntermNodePair {
- TIntermNode* node1;
- TIntermNode* node2;
-};
-
-class TIntermSymbol;
-class TIntermBinary;
-
-//
-// Intermediate class for nodes that have a type.
-//
-class TIntermTyped : public TIntermNode {
-public:
- TIntermTyped(const TType& t) : type(t) { }
- virtual TIntermTyped* getAsTyped() { return this; }
- virtual void setType(const TType& t) { type = t; }
- virtual TType getType() const { return type; }
- virtual TType* getTypePointer() { return &type; }
-
- virtual TBasicType getBasicType() const { return type.getBasicType(); }
- virtual TQualifier getQualifier() const { return type.getQualifier(); }
- virtual int getNominalSize() const { return type.getNominalSize(); }
- virtual int getSize() const { return type.getInstanceSize(); }
- virtual bool isMatrix() const { return type.isMatrix(); }
- virtual bool isArray() const { return type.isArray(); }
- virtual bool isVector() const { return type.isVector(); }
- const char* getBasicString() const { return type.getBasicString(); }
- const char* getQualifierString() const { return type.getQualifierString(); }
- TString getCompleteString() const { return type.getCompleteString(); }
-
-protected:
- TType type;
-};
-
-//
-// Handle for, do-while, and while loops.
-//
-class TIntermLoop : public TIntermNode {
-public:
- TIntermLoop(TIntermNode* aBody, TIntermTyped* aTest, TIntermTyped* aTerminal, bool testFirst) :
- body(aBody),
- test(aTest),
- terminal(aTerminal),
- first(testFirst) { }
- virtual void traverse(TIntermTraverser*);
- TIntermNode* getBody() { return body; }
- TIntermTyped* getTest() { return test; }
- TIntermTyped* getTerminal() { return terminal; }
- bool testFirst() { return first; }
-protected:
- TIntermNode* body; // code to loop over
- TIntermTyped* test; // exit condition associated with loop, could be 0 for 'for' loops
- TIntermTyped* terminal; // exists for for-loops
- bool first; // true for while and for, not for do-while
-};
-
-//
-// Handle break, continue, return, and kill.
-//
-class TIntermBranch : public TIntermNode {
-public:
- TIntermBranch(TOperator op, TIntermTyped* e) :
- flowOp(op),
- expression(e) { }
- virtual void traverse(TIntermTraverser*);
- TOperator getFlowOp() { return flowOp; }
- TIntermTyped* getExpression() { return expression; }
-protected:
- TOperator flowOp;
- TIntermTyped* expression; // non-zero except for "return exp;" statements
-};
-
-//
-// Nodes that correspond to symbols or constants in the source code.
-//
-class TIntermSymbol : public TIntermTyped {
-public:
- // if symbol is initialized as symbol(sym), the memory comes from the poolallocator of sym. If sym comes from
- // per process globalpoolallocator, then it causes increased memory usage per compile
- // it is essential to use "symbol = sym" to assign to symbol
- TIntermSymbol(int i, const TString& sym, const TType& t) :
- TIntermTyped(t), id(i) { symbol = sym;}
- virtual int getId() const { return id; }
- virtual const TString& getSymbol() const { return symbol; }
- virtual void traverse(TIntermTraverser*);
- virtual TIntermSymbol* getAsSymbolNode() { return this; }
-protected:
- int id;
- TString symbol;
-};
-
-class TIntermConstantUnion : public TIntermTyped {
-public:
- TIntermConstantUnion(constUnion *unionPointer, const TType& t) : TIntermTyped(t), unionArrayPointer(unionPointer) { }
- constUnion* getUnionArrayPointer() const { return unionArrayPointer; }
- void setUnionArrayPointer(constUnion *c) { unionArrayPointer = c; }
- virtual TIntermConstantUnion* getAsConstantUnion() { return this; }
- virtual void traverse(TIntermTraverser* );
- virtual TIntermTyped* fold(TOperator, TIntermTyped*, TInfoSink&, bool);
-protected:
- constUnion *unionArrayPointer;
-};
-
-//
-// Intermediate class for node types that hold operators.
-//
-class TIntermOperator : public TIntermTyped {
-public:
- TOperator getOp() { return op; }
- bool modifiesState() const;
- bool isConstructor() const;
- virtual bool promote(TInfoSink&) { return true; }
-protected:
- TIntermOperator(TOperator o) : TIntermTyped(TType(EbtFloat)), op(o) {}
- TIntermOperator(TOperator o, TType& t) : TIntermTyped(t), op(o) {}
- TOperator op;
-};
-
-//
-// Nodes for all the basic binary math operators.
-//
-class TIntermBinary : public TIntermOperator {
-public:
- TIntermBinary(TOperator o) : TIntermOperator(o) {}
- virtual void traverse(TIntermTraverser*);
- virtual void setLeft(TIntermTyped* n) { left = n; }
- virtual void setRight(TIntermTyped* n) { right = n; }
- virtual TIntermTyped* getLeft() const { return left; }
- virtual TIntermTyped* getRight() const { return right; }
- virtual TIntermBinary* getAsBinaryNode() { return this; }
- virtual bool promote(TInfoSink&);
-protected:
- TIntermTyped* left;
- TIntermTyped* right;
-};
-
-//
-// Nodes for unary math operators.
-//
-class TIntermUnary : public TIntermOperator {
-public:
- TIntermUnary(TOperator o, TType& t) : TIntermOperator(o, t), operand(0) {}
- TIntermUnary(TOperator o) : TIntermOperator(o), operand(0) {}
- virtual void traverse(TIntermTraverser*);
- virtual void setOperand(TIntermTyped* o) { operand = o; }
- virtual TIntermTyped* getOperand() { return operand; }
- virtual bool promote(TInfoSink&);
-protected:
- TIntermTyped* operand;
-};
-
-typedef TVector<TIntermNode*> TIntermSequence;
-typedef TVector<int> TQualifierList;
-//
-// Nodes that operate on an arbitrary sized set of children.
-//
-class TIntermAggregate : public TIntermOperator {
-public:
- TIntermAggregate() : TIntermOperator(EOpNull), userDefined(false), pragmaTable(0) { }
- TIntermAggregate(TOperator o) : TIntermOperator(o), pragmaTable(0) { }
- ~TIntermAggregate() { delete pragmaTable; }
- virtual TIntermAggregate* getAsAggregate() { return this; }
- virtual void setOperator(TOperator o) { op = o; }
- virtual TIntermSequence& getSequence() { return sequence; }
- virtual void setName(const TString& n) { name = n; }
- virtual const TString& getName() const { return name; }
- virtual void traverse(TIntermTraverser*);
- virtual void setUserDefined() { userDefined = true; }
- virtual bool isUserDefined() { return userDefined; }
- virtual TQualifierList& getQualifier() { return qualifier; }
- void setOptimize(bool o) { optimize = o; }
- void setDebug(bool d) { debug = d; }
- bool getOptimize() { return optimize; }
- bool getDebug() { return debug; }
- void addToPragmaTable(const TPragmaTable& pTable);
- const TPragmaTable& getPragmaTable() const { return *pragmaTable; }
-protected:
- TIntermAggregate(const TIntermAggregate&); // disallow copy constructor
- TIntermAggregate& operator=(const TIntermAggregate&); // disallow assignment operator
- TIntermSequence sequence;
- TQualifierList qualifier;
- TString name;
- bool userDefined; // used for user defined function names
- bool optimize;
- bool debug;
- TPragmaTable *pragmaTable;
-};
-
-//
-// For if tests. Simplified since there is no switch statement.
-//
-class TIntermSelection : public TIntermTyped {
-public:
- TIntermSelection(TIntermTyped* cond, TIntermNode* trueB, TIntermNode* falseB) :
- TIntermTyped(TType(EbtVoid)), condition(cond), trueBlock(trueB), falseBlock(falseB) {}
- TIntermSelection(TIntermTyped* cond, TIntermNode* trueB, TIntermNode* falseB, const TType& type) :
- TIntermTyped(type), condition(cond), trueBlock(trueB), falseBlock(falseB) {}
- virtual void traverse(TIntermTraverser*);
- virtual TIntermNode* getCondition() const { return condition; }
- virtual TIntermNode* getTrueBlock() const { return trueBlock; }
- virtual TIntermNode* getFalseBlock() const { return falseBlock; }
- virtual TIntermSelection* getAsSelectionNode() { return this; }
-protected:
- TIntermTyped* condition;
- TIntermNode* trueBlock;
- TIntermNode* falseBlock;
-};
-
-//
-// For traversing the tree. User should derive from this,
-// put their traversal specific data in it, and then pass
-// it to a Traverse method.
-//
-// When using this, just fill in the methods for nodes you want visited.
-// Return false from a pre-visit to skip visiting that node's subtree.
-//
-class TIntermTraverser {
-public:
- POOL_ALLOCATOR_NEW_DELETE(GlobalPoolAllocator)
-
- TIntermTraverser() :
- visitSymbol(0),
- visitConstantUnion(0),
- visitBinary(0),
- visitUnary(0),
- visitSelection(0),
- visitAggregate(0),
- visitLoop(0),
- visitBranch(0),
- depth(0),
- preVisit(true),
- postVisit(false),
- rightToLeft(false) {}
-
- void (*visitSymbol)(TIntermSymbol*, TIntermTraverser*);
- void (*visitConstantUnion)(TIntermConstantUnion*, TIntermTraverser*);
- bool (*visitBinary)(bool preVisit, TIntermBinary*, TIntermTraverser*);
- bool (*visitUnary)(bool preVisit, TIntermUnary*, TIntermTraverser*);
- bool (*visitSelection)(bool preVisit, TIntermSelection*, TIntermTraverser*);
- bool (*visitAggregate)(bool preVisit, TIntermAggregate*, TIntermTraverser*);
- bool (*visitLoop)(bool preVisit, TIntermLoop*, TIntermTraverser*);
- bool (*visitBranch)(bool preVisit, TIntermBranch*, TIntermTraverser*);
-
- int depth;
- bool preVisit;
- bool postVisit;
- bool rightToLeft;
-};
-
-#endif // __INTERMEDIATE_H
diff --git a/src/mesa/shader/slang/MachineIndependent/Gen_glslang.cpp b/src/mesa/shader/slang/MachineIndependent/Gen_glslang.cpp deleted file mode 100755 index e54af8bd9f..0000000000 --- a/src/mesa/shader/slang/MachineIndependent/Gen_glslang.cpp +++ /dev/null @@ -1,2942 +0,0 @@ -#line 2 "Gen_glslang.cpp" -/* A lexical scanner generated by flex */ - -/* Scanner skeleton version: - * $Header: /home/krh/git/sync/mesa-cvs-repo/Mesa/src/mesa/shader/slang/MachineIndependent/Gen_glslang.cpp,v 1.3 2005/03/18 14:30:27 michal Exp $ - */ - -#define FLEX_SCANNER -#define YY_FLEX_MAJOR_VERSION 2 -#define YY_FLEX_MINOR_VERSION 5 - -#include <stdio.h> -#include <unistd.h> - - -/* cfront 1.2 defines "c_plusplus" instead of "__cplusplus" */ -#ifdef c_plusplus -#ifndef __cplusplus -#define __cplusplus -#endif -#endif - - -#ifdef __cplusplus - -#include <stdlib.h> - -/* Use prototypes in function declarations. */ -#define YY_USE_PROTOS - -/* The "const" storage-class-modifier is valid. */ -#define YY_USE_CONST - -#else /* ! __cplusplus */ - -#if __STDC__ - -#define YY_USE_PROTOS -#define YY_USE_CONST - -#endif /* __STDC__ */ -#endif /* ! __cplusplus */ - -#ifdef __TURBOC__ - #pragma warn -rch - #pragma warn -use -#include <io.h> -#include <stdlib.h> -#define YY_USE_CONST -#define YY_USE_PROTOS -#endif - -#ifdef YY_USE_CONST -#define yyconst const -#else -#define yyconst -#endif - - -#ifdef YY_USE_PROTOS -#define YY_PROTO(proto) proto -#else -#define YY_PROTO(proto) () -#endif - -/* Returned upon end-of-file. */ -#define YY_NULL 0 - -/* Promotes a possibly negative, possibly signed char to an unsigned - * integer for use as an array index. If the signed char is negative, - * we want to instead treat it as an 8-bit unsigned char, hence the - * double cast. - */ -#define YY_SC_TO_UI(c) ((unsigned int) (unsigned char) c) - -/* Enter a start condition. This macro really ought to take a parameter, - * but we do it the disgusting crufty way forced on us by the ()-less - * definition of BEGIN. - */ -#define BEGIN yy_start = 1 + 2 * - -/* Translate the current start state into a value that can be later handed - * to BEGIN to return to the state. The YYSTATE alias is for lex - * compatibility. - */ -#define YY_START ((yy_start - 1) / 2) -#define YYSTATE YY_START - -/* Action number for EOF rule of a given start state. */ -#define YY_STATE_EOF(state) (YY_END_OF_BUFFER + state + 1) - -/* Special action meaning "start processing a new file". */ -#define YY_NEW_FILE yyrestart( yyin ) - -#define YY_END_OF_BUFFER_CHAR 0 - -/* Size of default input buffer. */ -#define YY_BUF_SIZE 16384 - -typedef struct yy_buffer_state *YY_BUFFER_STATE; - -extern int yyleng; -extern FILE *yyin, *yyout; - -#define EOB_ACT_CONTINUE_SCAN 0 -#define EOB_ACT_END_OF_FILE 1 -#define EOB_ACT_LAST_MATCH 2 - -/* The funky do-while in the following #define is used to turn the definition - * int a single C statement (which needs a semi-colon terminator). This - * avoids problems with code like: - * - * if ( condition_holds ) - * yyless( 5 ); - * else - * do_something_else(); - * - * Prior to using the do-while the compiler would get upset at the - * "else" because it interpreted the "if" statement as being all - * done when it reached the ';' after the yyless() call. - */ - -/* Return all but the first 'n' matched characters back to the input stream. */ - -#define yyless(n) \ - do \ - { \ - /* Undo effects of setting up yytext. */ \ - *yy_cp = yy_hold_char; \ - YY_RESTORE_YY_MORE_OFFSET \ - yy_c_buf_p = yy_cp = yy_bp + n - YY_MORE_ADJ; \ - YY_DO_BEFORE_ACTION; /* set up yytext again */ \ - } \ - while ( 0 ) - -#define unput(c) yyunput( c, yytext_ptr ) - -/* The following is because we cannot portably get our hands on size_t - * (without autoconf's help, which isn't available because we want - * flex-generated scanners to compile on their own). - */ -typedef unsigned int yy_size_t; - - -struct yy_buffer_state - { - FILE *yy_input_file; - - char *yy_ch_buf; /* input buffer */ - char *yy_buf_pos; /* current position in input buffer */ - - /* Size of input buffer in bytes, not including room for EOB - * characters. - */ - yy_size_t yy_buf_size; - - /* Number of characters read into yy_ch_buf, not including EOB - * characters. - */ - int yy_n_chars; - - /* Whether we "own" the buffer - i.e., we know we created it, - * and can realloc() it to grow it, and should free() it to - * delete it. - */ - int yy_is_our_buffer; - - /* Whether this is an "interactive" input source; if so, and - * if we're using stdio for input, then we want to use getc() - * instead of fread(), to make sure we stop fetching input after - * each newline. - */ - int yy_is_interactive; - - /* Whether we're considered to be at the beginning of a line. - * If so, '^' rules will be active on the next match, otherwise - * not. - */ - int yy_at_bol; - - /* Whether to try to fill the input buffer when we reach the - * end of it. - */ - int yy_fill_buffer; - - int yy_buffer_status; -#define YY_BUFFER_NEW 0 -#define YY_BUFFER_NORMAL 1 - /* When an EOF's been seen but there's still some text to process - * then we mark the buffer as YY_EOF_PENDING, to indicate that we - * shouldn't try reading from the input source any more. We might - * still have a bunch of tokens to match, though, because of - * possible backing-up. - * - * When we actually see the EOF, we change the status to "new" - * (via yyrestart()), so that the user can continue scanning by - * just pointing yyin at a new input file. - */ -#define YY_BUFFER_EOF_PENDING 2 - }; - -static YY_BUFFER_STATE yy_current_buffer = 0; - -/* We provide macros for accessing buffer states in case in the - * future we want to put the buffer states in a more general - * "scanner state". - */ -#define YY_CURRENT_BUFFER yy_current_buffer - - -/* yy_hold_char holds the character lost when yytext is formed. */ -static char yy_hold_char; - -static int yy_n_chars; /* number of characters read into yy_ch_buf */ - - -int yyleng; - -/* Points to current character in buffer. */ -static char *yy_c_buf_p = (char *) 0; -static int yy_init = 1; /* whether we need to initialize */ -static int yy_start = 0; /* start state number */ - -/* Flag which is used to allow yywrap()'s to do buffer switches - * instead of setting up a fresh yyin. A bit of a hack ... - */ -static int yy_did_buffer_switch_on_eof; - -void yyrestart YY_PROTO(( FILE *input_file )); - -void yy_switch_to_buffer YY_PROTO(( YY_BUFFER_STATE new_buffer )); -void yy_load_buffer_state YY_PROTO(( void )); -YY_BUFFER_STATE yy_create_buffer YY_PROTO(( FILE *file, int size )); -void yy_delete_buffer YY_PROTO(( YY_BUFFER_STATE b )); -void yy_init_buffer YY_PROTO(( YY_BUFFER_STATE b, FILE *file )); -void yy_flush_buffer YY_PROTO(( YY_BUFFER_STATE b )); -#define YY_FLUSH_BUFFER yy_flush_buffer( yy_current_buffer ) - -YY_BUFFER_STATE yy_scan_buffer YY_PROTO(( char *base, yy_size_t size )); -YY_BUFFER_STATE yy_scan_string YY_PROTO(( yyconst char *yy_str )); -YY_BUFFER_STATE yy_scan_bytes YY_PROTO(( yyconst char *bytes, int len )); - -static void *yy_flex_alloc YY_PROTO(( yy_size_t )); -static void *yy_flex_realloc YY_PROTO(( void *, yy_size_t )); -static void yy_flex_free YY_PROTO(( void * )); - -#define yy_new_buffer yy_create_buffer - -#define yy_set_interactive(is_interactive) \ - { \ - if ( ! yy_current_buffer ) \ - yy_current_buffer = yy_create_buffer( yyin, YY_BUF_SIZE ); \ - yy_current_buffer->yy_is_interactive = is_interactive; \ - } - -#define yy_set_bol(at_bol) \ - { \ - if ( ! yy_current_buffer ) \ - yy_current_buffer = yy_create_buffer( yyin, YY_BUF_SIZE ); \ - yy_current_buffer->yy_at_bol = at_bol; \ - } - -#define YY_AT_BOL() (yy_current_buffer->yy_at_bol) - - -#define yywrap() 1 -#define YY_SKIP_YYWRAP -typedef unsigned char YY_CHAR; -FILE *yyin = (FILE *) 0, *yyout = (FILE *) 0; -typedef int yy_state_type; -extern char *yytext; -#define yytext_ptr yytext - -static yy_state_type yy_get_previous_state YY_PROTO(( void )); -static yy_state_type yy_try_NUL_trans YY_PROTO(( yy_state_type current_state )); -static int yy_get_next_buffer YY_PROTO(( void )); -static void yy_fatal_error YY_PROTO(( yyconst char msg[] )); - -/* Done after the current pattern has been matched and before the - * corresponding action - sets up yytext. - */ -#define YY_DO_BEFORE_ACTION \ - yytext_ptr = yy_bp; \ - yyleng = (int) (yy_cp - yy_bp); \ - yy_hold_char = *yy_cp; \ - *yy_cp = '\0'; \ - yy_c_buf_p = yy_cp; - -#define YY_NUM_RULES 144 -#define YY_END_OF_BUFFER 145 -static yyconst short int yy_accept[428] = - { 0, - 0, 0, 0, 0, 145, 143, 142, 142, 127, 133, - 138, 122, 123, 131, 130, 119, 128, 126, 132, 143, - 143, 120, 116, 134, 121, 135, 139, 143, 124, 125, - 137, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 117, 136, 118, 129, 141, 144, 143, 143, 113, - 99, 118, 107, 102, 97, 105, 95, 106, 96, 0, - 94, 0, 98, 90, 0, 0, 0, 125, 117, 124, - 114, 110, 112, 111, 115, 86, 103, 109, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, - - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 11, 13, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 104, 108, 140, - 93, 0, 1, 92, 0, 0, 88, 89, 0, 100, - 101, 0, 0, 43, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 9, 0, 0, 0, 0, 0, 0, 0, 17, - 0, 0, 0, 0, 0, 14, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 87, 86, 0, 19, 0, 0, - 83, 0, 0, 0, 0, 0, 0, 0, 12, 46, - 0, 0, 0, 0, 0, 51, 65, 0, 0, 0, - 0, 0, 0, 62, 24, 25, 26, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 49, 20, 0, 0, 0, 0, 0, 0, 27, 28, - 29, 18, 0, 0, 140, 0, 0, 92, 0, 0, - 0, 0, 6, 33, 34, 35, 44, 3, 0, 0, - 0, 0, 76, 77, 78, 0, 21, 66, 16, 73, - - 74, 75, 70, 71, 72, 0, 15, 68, 0, 30, - 31, 32, 0, 0, 0, 0, 0, 0, 0, 63, - 0, 0, 0, 0, 0, 0, 0, 45, 0, 85, - 0, 0, 10, 0, 0, 91, 0, 0, 0, 0, - 64, 59, 54, 0, 0, 0, 69, 50, 57, 23, - 0, 82, 58, 42, 52, 0, 0, 0, 0, 0, - 0, 93, 92, 0, 0, 53, 22, 0, 0, 0, - 0, 0, 0, 47, 4, 0, 5, 0, 0, 7, - 60, 0, 0, 55, 0, 0, 0, 0, 48, 67, - 56, 2, 61, 84, 36, 37, 38, 0, 0, 0, - - 0, 0, 0, 0, 0, 0, 0, 39, 0, 0, - 0, 0, 0, 79, 0, 80, 0, 0, 0, 40, - 0, 41, 0, 0, 0, 81, 0 - } ; - -static yyconst int yy_ec[256] = - { 0, - 1, 1, 1, 1, 1, 1, 1, 1, 2, 3, - 2, 2, 4, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 2, 5, 1, 1, 1, 6, 7, 1, 8, - 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, - 19, 20, 21, 21, 21, 22, 22, 23, 24, 25, - 26, 27, 28, 1, 29, 29, 30, 31, 32, 29, - 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, - 33, 34, 35, 33, 33, 33, 33, 36, 33, 33, - 37, 1, 38, 39, 33, 1, 40, 41, 42, 43, - - 44, 45, 46, 47, 48, 33, 49, 50, 51, 52, - 53, 54, 33, 55, 56, 57, 58, 59, 60, 61, - 62, 63, 64, 65, 66, 67, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1 - } ; - -static yyconst int yy_meta[68] = - { 0, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, - 2, 2, 1, 1, 1, 1, 1, 1, 2, 2, - 2, 2, 3, 3, 3, 3, 1, 1, 1, 2, - 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 1, 1, 1, 1 - } ; - -static yyconst short int yy_base[432] = - { 0, - 0, 0, 67, 0, 678, 679, 679, 679, 651, 109, - 130, 679, 679, 650, 127, 679, 126, 124, 139, 151, - 671, 647, 679, 151, 647, 121, 679, 668, 679, 679, - 124, 147, 154, 155, 158, 171, 174, 157, 156, 184, - 175, 160, 178, 162, 176, 181, 190, 197, 193, 195, - 179, 679, 193, 679, 679, 679, 679, 656, 666, 679, - 679, 679, 679, 679, 679, 679, 679, 679, 679, 665, - 679, 665, 679, 246, 663, 662, 0, 679, 679, 679, - 639, 679, 679, 679, 638, 253, 679, 679, 612, 605, - 608, 616, 615, 602, 617, 604, 610, 598, 595, 608, - - 595, 592, 592, 598, 586, 593, 590, 600, 586, 592, - 597, 679, 136, 596, 587, 581, 586, 588, 578, 592, - 592, 575, 580, 577, 566, 200, 580, 576, 578, 567, - 570, 136, 575, 567, 579, 203, 572, 679, 679, 263, - 275, 616, 679, 282, 614, 311, 318, 325, 613, 679, - 679, 612, 611, 679, 559, 563, 572, 569, 553, 553, - 200, 568, 565, 565, 563, 560, 552, 558, 545, 556, - 559, 679, 556, 544, 551, 553, 546, 535, 534, 547, - 548, 543, 268, 544, 535, 532, 536, 534, 525, 528, - 526, 536, 522, 520, 520, 522, 519, 530, 529, 201, - - 524, 519, 508, 290, 526, 528, 517, 562, 561, 337, - 560, 349, 356, 559, 0, 363, 514, 679, 512, 293, - 679, 504, 502, 510, 499, 516, 505, 297, 679, 679, - 499, 509, 509, 494, 368, 679, 679, 371, 498, 492, - 491, 492, 374, 679, 679, 679, 679, 490, 495, 486, - 499, 494, 486, 490, 482, 485, 489, 494, 493, 484, - 679, 679, 490, 479, 479, 484, 483, 480, 679, 679, - 679, 679, 470, 482, 379, 386, 521, 393, 400, 520, - 422, 482, 679, 679, 679, 679, 679, 679, 470, 471, - 465, 475, 679, 679, 679, 466, 679, 679, 679, 679, - - 679, 679, 679, 679, 679, 473, 679, 679, 471, 679, - 679, 679, 461, 466, 456, 469, 469, 458, 465, 679, - 463, 465, 449, 458, 464, 459, 447, 679, 449, 679, - 448, 451, 679, 429, 448, 679, 440, 439, 439, 452, - 679, 454, 679, 453, 452, 439, 679, 679, 679, 679, - 435, 679, 679, 679, 679, 432, 443, 436, 442, 439, - 434, 679, 679, 426, 438, 679, 679, 431, 438, 437, - 419, 441, 418, 679, 679, 418, 679, 413, 412, 679, - 679, 411, 410, 679, 422, 405, 404, 376, 679, 679, - 679, 679, 679, 679, 397, 242, 397, 389, 382, 384, - - 380, 380, 379, 324, 321, 321, 310, 679, 308, 292, - 282, 266, 268, 285, 265, 679, 246, 258, 229, 679, - 221, 679, 199, 145, 131, 679, 679, 471, 179, 473, - 475 - } ; - -static yyconst short int yy_def[432] = - { 0, - 427, 1, 427, 3, 427, 427, 427, 427, 427, 427, - 427, 427, 427, 427, 427, 427, 427, 427, 427, 427, - 427, 427, 427, 427, 427, 427, 427, 427, 427, 427, - 427, 427, 427, 427, 427, 427, 427, 427, 427, 427, - 427, 427, 427, 427, 427, 427, 427, 427, 427, 427, - 427, 427, 427, 427, 427, 427, 427, 427, 427, 427, - 427, 427, 427, 427, 427, 427, 427, 427, 427, 427, - 427, 428, 427, 427, 427, 427, 429, 427, 427, 427, - 427, 427, 427, 427, 427, 430, 427, 427, 427, 427, - 427, 427, 427, 427, 427, 427, 427, 427, 427, 427, - - 427, 427, 427, 427, 427, 427, 427, 427, 427, 427, - 427, 427, 427, 427, 427, 427, 427, 427, 427, 427, - 427, 427, 427, 427, 427, 427, 427, 427, 427, 427, - 427, 427, 427, 427, 427, 427, 427, 427, 427, 431, - 427, 428, 427, 427, 427, 427, 427, 427, 427, 427, - 427, 427, 427, 427, 427, 427, 427, 427, 427, 427, - 427, 427, 427, 427, 427, 427, 427, 427, 427, 427, - 427, 427, 427, 427, 427, 427, 427, 427, 427, 427, - 427, 427, 427, 427, 427, 427, 427, 427, 427, 427, - 427, 427, 427, 427, 427, 427, 427, 427, 427, 427, - - 427, 427, 427, 427, 427, 427, 427, 427, 427, 427, - 427, 427, 427, 427, 429, 430, 427, 427, 427, 427, - 427, 427, 427, 427, 427, 427, 427, 427, 427, 427, - 427, 427, 427, 427, 427, 427, 427, 427, 427, 427, - 427, 427, 427, 427, 427, 427, 427, 427, 427, 427, - 427, 427, 427, 427, 427, 427, 427, 427, 427, 427, - 427, 427, 427, 427, 427, 427, 427, 427, 427, 427, - 427, 427, 427, 427, 431, 427, 427, 427, 427, 427, - 427, 427, 427, 427, 427, 427, 427, 427, 427, 427, - 427, 427, 427, 427, 427, 427, 427, 427, 427, 427, - - 427, 427, 427, 427, 427, 427, 427, 427, 427, 427, - 427, 427, 427, 427, 427, 427, 427, 427, 427, 427, - 427, 427, 427, 427, 427, 427, 427, 427, 427, 427, - 427, 427, 427, 427, 427, 427, 427, 427, 427, 427, - 427, 427, 427, 427, 427, 427, 427, 427, 427, 427, - 427, 427, 427, 427, 427, 427, 427, 427, 427, 427, - 427, 427, 427, 427, 427, 427, 427, 427, 427, 427, - 427, 427, 427, 427, 427, 427, 427, 427, 427, 427, - 427, 427, 427, 427, 427, 427, 427, 427, 427, 427, - 427, 427, 427, 427, 427, 427, 427, 427, 427, 427, - - 427, 427, 427, 427, 427, 427, 427, 427, 427, 427, - 427, 427, 427, 427, 427, 427, 427, 427, 427, 427, - 427, 427, 427, 427, 427, 427, 0, 427, 427, 427, - 427 - } ; - -static yyconst short int yy_nxt[747] = - { 0, - 6, 7, 8, 7, 9, 10, 11, 12, 13, 14, - 15, 16, 17, 18, 19, 20, 21, 21, 21, 21, - 21, 21, 22, 23, 24, 25, 26, 27, 28, 28, - 28, 28, 28, 28, 28, 28, 29, 30, 31, 32, - 33, 34, 35, 36, 37, 38, 39, 40, 28, 41, - 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, - 28, 28, 28, 52, 53, 54, 55, 6, 56, 57, - 56, 6, 6, 6, 6, 6, 6, 6, 6, 6, - 6, 58, 6, 6, 6, 6, 6, 6, 6, 6, - 6, 6, 6, 6, 6, 59, 59, 59, 59, 59, - - 59, 59, 59, 6, 6, 6, 59, 59, 59, 59, - 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, - 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, - 6, 6, 6, 6, 61, 62, 63, 66, 68, 70, - 70, 70, 70, 70, 70, 70, 84, 85, 71, 87, - 86, 69, 67, 72, 74, 64, 79, 86, 86, 86, - 86, 86, 88, 86, 73, 86, 75, 75, 75, 75, - 75, 75, 76, 80, 86, 81, 82, 86, 86, 86, - 149, 86, 86, 200, 86, 177, 77, 86, 178, 179, - 426, 201, 180, 86, 94, 110, 86, 425, 86, 116, - - 86, 97, 89, 90, 95, 98, 91, 96, 92, 109, - 99, 77, 93, 104, 111, 120, 100, 117, 138, 119, - 101, 105, 102, 106, 122, 137, 107, 115, 112, 123, - 118, 103, 108, 121, 134, 113, 124, 125, 135, 193, - 128, 424, 114, 129, 132, 264, 126, 136, 133, 127, - 205, 130, 206, 265, 194, 223, 224, 139, 131, 144, - 423, 145, 145, 145, 145, 145, 145, 145, 152, 152, - 152, 152, 152, 152, 152, 400, 401, 146, 208, 208, - 208, 208, 208, 208, 208, 245, 246, 247, 422, 146, - 70, 70, 70, 70, 70, 70, 70, 211, 211, 211, - - 211, 211, 211, 211, 421, 420, 210, 269, 270, 271, - 284, 285, 286, 212, 293, 294, 295, 419, 210, 418, - 417, 213, 416, 213, 415, 212, 214, 214, 214, 214, - 214, 214, 214, 75, 75, 75, 75, 75, 75, 76, - 76, 76, 76, 76, 76, 76, 76, 276, 414, 276, - 413, 412, 277, 277, 277, 277, 277, 277, 277, 279, - 411, 279, 410, 409, 280, 280, 280, 280, 280, 280, - 280, 214, 214, 214, 214, 214, 214, 214, 152, 152, - 152, 152, 152, 152, 152, 300, 301, 302, 303, 304, - 305, 310, 311, 312, 208, 208, 208, 208, 208, 208, - - 208, 277, 277, 277, 277, 277, 277, 277, 211, 211, - 211, 211, 211, 211, 211, 280, 280, 280, 280, 280, - 280, 280, 408, 407, 212, 336, 406, 405, 404, 403, - 402, 399, 362, 398, 397, 396, 212, 214, 214, 214, - 214, 214, 214, 214, 277, 277, 277, 277, 277, 277, - 277, 363, 395, 394, 393, 392, 391, 385, 386, 387, - 390, 389, 384, 280, 280, 280, 280, 280, 280, 280, - 388, 142, 142, 142, 153, 153, 209, 209, 383, 382, - 381, 380, 379, 378, 377, 376, 375, 374, 373, 372, - 371, 370, 369, 368, 367, 366, 365, 364, 361, 360, - - 359, 358, 357, 356, 355, 354, 353, 352, 351, 350, - 349, 348, 347, 346, 345, 344, 343, 342, 341, 340, - 339, 338, 337, 335, 334, 333, 332, 331, 330, 329, - 328, 327, 326, 325, 324, 323, 322, 321, 320, 319, - 318, 317, 316, 315, 314, 313, 309, 308, 307, 306, - 299, 298, 297, 296, 292, 291, 290, 289, 288, 287, - 283, 282, 281, 278, 275, 275, 274, 273, 272, 268, - 267, 266, 263, 262, 261, 260, 259, 258, 257, 256, - 255, 254, 253, 252, 251, 250, 249, 248, 244, 243, - 242, 241, 240, 239, 238, 237, 236, 235, 234, 233, - - 232, 231, 230, 229, 228, 227, 226, 225, 222, 221, - 220, 219, 218, 217, 216, 216, 215, 74, 143, 207, - 204, 203, 202, 199, 198, 197, 196, 195, 192, 191, - 190, 189, 188, 187, 186, 185, 184, 183, 182, 181, - 176, 175, 174, 173, 172, 171, 170, 169, 168, 167, - 166, 165, 164, 163, 162, 161, 160, 159, 158, 157, - 156, 155, 154, 151, 150, 148, 147, 143, 141, 140, - 72, 86, 83, 78, 74, 65, 60, 427, 5, 427, - 427, 427, 427, 427, 427, 427, 427, 427, 427, 427, - 427, 427, 427, 427, 427, 427, 427, 427, 427, 427, - - 427, 427, 427, 427, 427, 427, 427, 427, 427, 427, - 427, 427, 427, 427, 427, 427, 427, 427, 427, 427, - 427, 427, 427, 427, 427, 427, 427, 427, 427, 427, - 427, 427, 427, 427, 427, 427, 427, 427, 427, 427, - 427, 427, 427, 427, 427, 427 - } ; - -static yyconst short int yy_chk[747] = - { 0, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, - - 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 10, 10, 11, 15, 17, 18, - 18, 18, 18, 18, 18, 18, 26, 26, 19, 31, - 32, 17, 15, 19, 20, 11, 24, 33, 34, 39, - 38, 35, 31, 42, 19, 44, 20, 20, 20, 20, - 20, 20, 20, 24, 36, 24, 24, 37, 41, 45, - 429, 43, 51, 132, 46, 113, 20, 40, 113, 113, - 425, 132, 113, 47, 34, 39, 49, 424, 50, 42, - - 48, 35, 32, 32, 34, 35, 33, 34, 33, 38, - 35, 20, 33, 37, 39, 45, 35, 43, 53, 44, - 36, 37, 36, 37, 46, 51, 37, 41, 40, 47, - 43, 36, 37, 45, 50, 40, 47, 47, 50, 126, - 48, 423, 40, 48, 49, 200, 47, 50, 49, 47, - 136, 48, 136, 200, 126, 161, 161, 53, 48, 74, - 421, 74, 74, 74, 74, 74, 74, 74, 86, 86, - 86, 86, 86, 86, 86, 396, 396, 74, 140, 140, - 140, 140, 140, 140, 140, 183, 183, 183, 419, 74, - 141, 141, 141, 141, 141, 141, 141, 144, 144, 144, - - 144, 144, 144, 144, 418, 417, 141, 204, 204, 204, - 220, 220, 220, 144, 228, 228, 228, 415, 141, 414, - 413, 146, 412, 146, 411, 144, 146, 146, 146, 146, - 146, 146, 146, 147, 147, 147, 147, 147, 147, 147, - 148, 148, 148, 148, 148, 148, 148, 210, 410, 210, - 409, 407, 210, 210, 210, 210, 210, 210, 210, 212, - 406, 212, 405, 404, 212, 212, 212, 212, 212, 212, - 212, 213, 213, 213, 213, 213, 213, 213, 216, 216, - 216, 216, 216, 216, 216, 235, 235, 235, 238, 238, - 238, 243, 243, 243, 275, 275, 275, 275, 275, 275, - - 275, 276, 276, 276, 276, 276, 276, 276, 278, 278, - 278, 278, 278, 278, 278, 279, 279, 279, 279, 279, - 279, 279, 403, 402, 278, 281, 401, 400, 399, 398, - 397, 395, 334, 388, 387, 386, 278, 281, 281, 281, - 281, 281, 281, 281, 334, 334, 334, 334, 334, 334, - 334, 335, 385, 383, 382, 379, 378, 372, 372, 372, - 376, 373, 371, 335, 335, 335, 335, 335, 335, 335, - 372, 428, 428, 428, 430, 430, 431, 431, 370, 369, - 368, 365, 364, 361, 360, 359, 358, 357, 356, 351, - 346, 345, 344, 342, 340, 339, 338, 337, 332, 331, - - 329, 327, 326, 325, 324, 323, 322, 321, 319, 318, - 317, 316, 315, 314, 313, 309, 306, 296, 292, 291, - 290, 289, 282, 280, 277, 274, 273, 268, 267, 266, - 265, 264, 263, 260, 259, 258, 257, 256, 255, 254, - 253, 252, 251, 250, 249, 248, 242, 241, 240, 239, - 234, 233, 232, 231, 227, 226, 225, 224, 223, 222, - 219, 217, 214, 211, 209, 208, 207, 206, 205, 203, - 202, 201, 199, 198, 197, 196, 195, 194, 193, 192, - 191, 190, 189, 188, 187, 186, 185, 184, 182, 181, - 180, 179, 178, 177, 176, 175, 174, 173, 171, 170, - - 169, 168, 167, 166, 165, 164, 163, 162, 160, 159, - 158, 157, 156, 155, 153, 152, 149, 145, 142, 137, - 135, 134, 133, 131, 130, 129, 128, 127, 125, 124, - 123, 122, 121, 120, 119, 118, 117, 116, 115, 114, - 111, 110, 109, 108, 107, 106, 105, 104, 103, 102, - 101, 100, 99, 98, 97, 96, 95, 94, 93, 92, - 91, 90, 89, 85, 81, 76, 75, 72, 70, 59, - 58, 28, 25, 22, 21, 14, 9, 5, 427, 427, - 427, 427, 427, 427, 427, 427, 427, 427, 427, 427, - 427, 427, 427, 427, 427, 427, 427, 427, 427, 427, - - 427, 427, 427, 427, 427, 427, 427, 427, 427, 427, - 427, 427, 427, 427, 427, 427, 427, 427, 427, 427, - 427, 427, 427, 427, 427, 427, 427, 427, 427, 427, - 427, 427, 427, 427, 427, 427, 427, 427, 427, 427, - 427, 427, 427, 427, 427, 427 - } ; - -static yy_state_type yy_last_accepting_state; -static char *yy_last_accepting_cpos; - -/* The intent behind this definition is that it'll catch - * any uses of REJECT which flex missed. - */ -#define REJECT reject_used_but_not_detected -#define yymore() yymore_used_but_not_detected -#define YY_MORE_ADJ 0 -#define YY_RESTORE_YY_MORE_OFFSET -char *yytext; -#line 1 "glslang.l" -#define INITIAL 0 -/*
-//
-//Copyright (C) 2002-2005 3Dlabs Inc. Ltd.
-//All rights reserved.
-//
-//Redistribution and use in source and binary forms, with or without
-//modification, are permitted provided that the following conditions
-//are met:
-//
-// Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//
-// Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-//
-// Neither the name of 3Dlabs Inc. Ltd. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-//THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-//"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-//LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
-//FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
-//COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
-//INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
-//BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
-//LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
-//CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-//LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
-//ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
-//POSSIBILITY OF SUCH DAMAGE.
-//
-*/
-/* Based on
-ANSI C grammar, Lex specification
-
-In 1985, Jeff Lee published this Lex specification together with a Yacc
-grammar for the April 30, 1985 ANSI C draft. Tom Stockfisch reposted
-both to net.sources in 1987; that original, as mentioned in the answer
-to question 17.25 of the comp.lang.c FAQ, can be ftp'ed from ftp.uu.net,
-file usenet/net.sources/ansi.c.grammar.Z.
-
-I intend to keep this version as close to the current C Standard grammar
-as possible; please let me know if you discover discrepancies.
-
-Jutta Degener, 1995
-*/
-#define YY_NO_UNPUT 1 -#line 59 "glslang.l" -#include <stdio.h>
-#include <stdlib.h>
-#include "ParseHelper.h"
-#include "glslang_tab.h"
-
-/* windows only pragma */
-#ifdef _MSC_VER
-#pragma warning(disable : 4102)
-#endif
-
-int yy_input(char* buf, int max_size);
-TSourceLoc yylineno;
-
-#ifdef _WIN32
- extern int yyparse(TParseContext&);
- #define YY_DECL int yylex(YYSTYPE* pyylval, TParseContext& parseContext)
-#else
- extern int yyparse(void*);
- #define YY_DECL int yylex(YYSTYPE* pyylval, void* parseContextLocal)
- #define parseContext (*((TParseContext*)(parseContextLocal)))
-#endif
-
-#define YY_INPUT(buf,result,max_size) (result = yy_input(buf, max_size))
-
-#define YY_NEVER_INTERACTIVE 1 -#define FIELDS 1 -
-#line 753 "Gen_glslang.cpp" - -/* Macros after this point can all be overridden by user definitions in - * section 1. - */ - -#ifndef YY_SKIP_YYWRAP -#ifdef __cplusplus -extern "C" int yywrap YY_PROTO(( void )); -#else -extern int yywrap YY_PROTO(( void )); -#endif -#endif - -#ifndef YY_NO_UNPUT -static void yyunput YY_PROTO(( int c, char *buf_ptr )); -#endif - -#ifndef yytext_ptr -static void yy_flex_strncpy YY_PROTO(( char *, yyconst char *, int )); -#endif - -#ifdef YY_NEED_STRLEN -static int yy_flex_strlen YY_PROTO(( yyconst char * )); -#endif - -#ifndef YY_NO_INPUT -#ifdef __cplusplus -static int yyinput YY_PROTO(( void )); -#else -static int input YY_PROTO(( void )); -#endif -#endif - -#if YY_STACK_USED -static int yy_start_stack_ptr = 0; -static int yy_start_stack_depth = 0; -static int *yy_start_stack = 0; -#ifndef YY_NO_PUSH_STATE -static void yy_push_state YY_PROTO(( int new_state )); -#endif -#ifndef YY_NO_POP_STATE -static void yy_pop_state YY_PROTO(( void )); -#endif -#ifndef YY_NO_TOP_STATE -static int yy_top_state YY_PROTO(( void )); -#endif - -#else -#define YY_NO_PUSH_STATE 1 -#define YY_NO_POP_STATE 1 -#define YY_NO_TOP_STATE 1 -#endif - -#ifdef YY_MALLOC_DECL -YY_MALLOC_DECL -#else -#if __STDC__ -#ifndef __cplusplus -#include <stdlib.h> -#endif -#else -/* Just try to get by without declaring the routines. This will fail - * miserably on non-ANSI systems for which sizeof(size_t) != sizeof(int) - * or sizeof(void*) != sizeof(int). - */ -#endif -#endif - -/* Amount of stuff to slurp up with each read. */ -#ifndef YY_READ_BUF_SIZE -#define YY_READ_BUF_SIZE 8192 -#endif - -/* Copy whatever the last rule matched to the standard output. */ - -#ifndef ECHO -/* This used to be an fputs(), but since the string might contain NUL's, - * we now use fwrite(). - */ -#define ECHO (void) fwrite( yytext, yyleng, 1, yyout ) -#endif - -/* Gets input and stuffs it into "buf". number of characters read, or YY_NULL, - * is returned in "result". - */ -#ifndef YY_INPUT -#define YY_INPUT(buf,result,max_size) \ - if ( yy_current_buffer->yy_is_interactive ) \ - { \ - int c = '*', n; \ - for ( n = 0; n < max_size && \ - (c = getc( yyin )) != EOF && c != '\n'; ++n ) \ - buf[n] = (char) c; \ - if ( c == '\n' ) \ - buf[n++] = (char) c; \ - if ( c == EOF && ferror( yyin ) ) \ - YY_FATAL_ERROR( "input in flex scanner failed" ); \ - result = n; \ - } \ - else if ( ((result = fread( buf, 1, max_size, yyin )) == 0) \ - && ferror( yyin ) ) \ - YY_FATAL_ERROR( "input in flex scanner failed" ); -#endif - -/* No semi-colon after return; correct usage is to write "yyterminate();" - - * we don't want an extra ';' after the "return" because that will cause - * some compilers to complain about unreachable statements. - */ -#ifndef yyterminate -#define yyterminate() return YY_NULL -#endif - -/* Number of entries by which start-condition stack grows. */ -#ifndef YY_START_STACK_INCR -#define YY_START_STACK_INCR 25 -#endif - -/* Report a fatal error. */ -#ifndef YY_FATAL_ERROR -#define YY_FATAL_ERROR(msg) yy_fatal_error( msg ) -#endif - -/* Default declaration of generated scanner - a define so the user can - * easily add parameters. - */ -#ifndef YY_DECL -#define YY_DECL int yylex YY_PROTO(( void )) -#endif - -/* Code executed at the beginning of each rule, after yytext and yyleng - * have been set up. - */ -#ifndef YY_USER_ACTION -#define YY_USER_ACTION -#endif - -/* Code executed at the end of each rule. */ -#ifndef YY_BREAK -#define YY_BREAK break; -#endif - -#define YY_RULE_SETUP \ - YY_USER_ACTION - -YY_DECL - { - register yy_state_type yy_current_state; - register char *yy_cp, *yy_bp; - register int yy_act; - -#line 91 "glslang.l" - -#line 906 "Gen_glslang.cpp" - - if ( yy_init ) - { - yy_init = 0; - -#ifdef YY_USER_INIT - YY_USER_INIT; -#endif - - if ( ! yy_start ) - yy_start = 1; /* first start state */ - - if ( ! yyin ) - yyin = stdin; - - if ( ! yyout ) - yyout = stdout; - - if ( ! yy_current_buffer ) - yy_current_buffer = - yy_create_buffer( yyin, YY_BUF_SIZE ); - - yy_load_buffer_state(); - } - - while ( 1 ) /* loops until end-of-file is reached */ - { - yy_cp = yy_c_buf_p; - - /* Support of yytext. */ - *yy_cp = yy_hold_char; - - /* yy_bp points to the position in yy_ch_buf of the start of - * the current run. - */ - yy_bp = yy_cp; - - yy_current_state = yy_start; -yy_match: - do - { - register YY_CHAR yy_c = yy_ec[YY_SC_TO_UI(*yy_cp)]; - if ( yy_accept[yy_current_state] ) - { - yy_last_accepting_state = yy_current_state; - yy_last_accepting_cpos = yy_cp; - } - while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) - { - yy_current_state = (int) yy_def[yy_current_state]; - if ( yy_current_state >= 428 ) - yy_c = yy_meta[(unsigned int) yy_c]; - } - yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; - ++yy_cp; - } - while ( yy_base[yy_current_state] != 679 ); - -yy_find_action: - yy_act = yy_accept[yy_current_state]; - if ( yy_act == 0 ) - { /* have to back up */ - yy_cp = yy_last_accepting_cpos; - yy_current_state = yy_last_accepting_state; - yy_act = yy_accept[yy_current_state]; - } - - YY_DO_BEFORE_ACTION; - - -do_action: /* This label is used only to access EOF actions. */ - - - switch ( yy_act ) - { /* beginning of action switch */ - case 0: /* must back up */ - /* undo the effects of YY_DO_BEFORE_ACTION */ - *yy_cp = yy_hold_char; - yy_cp = yy_last_accepting_cpos; - yy_current_state = yy_last_accepting_state; - goto yy_find_action; - -case 1: -YY_RULE_SETUP -#line 92 "glslang.l" -{ /* ?? carriage and/or line-feed? */ };
- YY_BREAK -case 2: -YY_RULE_SETUP -#line 94 "glslang.l" -{ pyylval->lex.line = yylineno; return(ATTRIBUTE); }
- YY_BREAK -case 3: -YY_RULE_SETUP -#line 95 "glslang.l" -{ pyylval->lex.line = yylineno; return(CONST_QUAL); }
- YY_BREAK -case 4: -YY_RULE_SETUP -#line 96 "glslang.l" -{ pyylval->lex.line = yylineno; return(UNIFORM); }
- YY_BREAK -case 5: -YY_RULE_SETUP -#line 97 "glslang.l" -{ pyylval->lex.line = yylineno; return(VARYING); }
- YY_BREAK -case 6: -YY_RULE_SETUP -#line 99 "glslang.l" -{ pyylval->lex.line = yylineno; return(BREAK); }
- YY_BREAK -case 7: -YY_RULE_SETUP -#line 100 "glslang.l" -{ pyylval->lex.line = yylineno; return(CONTINUE); }
- YY_BREAK -case 8: -YY_RULE_SETUP -#line 101 "glslang.l" -{ pyylval->lex.line = yylineno; return(DO); }
- YY_BREAK -case 9: -YY_RULE_SETUP -#line 102 "glslang.l" -{ pyylval->lex.line = yylineno; return(FOR); }
- YY_BREAK -case 10: -YY_RULE_SETUP -#line 103 "glslang.l" -{ pyylval->lex.line = yylineno; return(WHILE); }
- YY_BREAK -case 11: -YY_RULE_SETUP -#line 105 "glslang.l" -{ pyylval->lex.line = yylineno; return(IF); }
- YY_BREAK -case 12: -YY_RULE_SETUP -#line 106 "glslang.l" -{ pyylval->lex.line = yylineno; return(ELSE); }
- YY_BREAK -case 13: -YY_RULE_SETUP -#line 108 "glslang.l" -{ pyylval->lex.line = yylineno; return(IN_QUAL); }
- YY_BREAK -case 14: -YY_RULE_SETUP -#line 109 "glslang.l" -{ pyylval->lex.line = yylineno; return(OUT_QUAL); }
- YY_BREAK -case 15: -YY_RULE_SETUP -#line 110 "glslang.l" -{ pyylval->lex.line = yylineno; return(INOUT_QUAL); }
- YY_BREAK -case 16: -YY_RULE_SETUP -#line 112 "glslang.l" -{ pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return(FLOAT_TYPE); }
- YY_BREAK -case 17: -YY_RULE_SETUP -#line 113 "glslang.l" -{ pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return(INT_TYPE); }
- YY_BREAK -case 18: -YY_RULE_SETUP -#line 114 "glslang.l" -{ pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return(VOID_TYPE); }
- YY_BREAK -case 19: -YY_RULE_SETUP -#line 115 "glslang.l" -{ pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return(BOOL_TYPE); }
- YY_BREAK -case 20: -YY_RULE_SETUP -#line 116 "glslang.l" -{ pyylval->lex.line = yylineno; pyylval->lex.b = true; return(BOOLCONSTANT); }
- YY_BREAK -case 21: -YY_RULE_SETUP -#line 117 "glslang.l" -{ pyylval->lex.line = yylineno; pyylval->lex.b = false; return(BOOLCONSTANT); }
- YY_BREAK -case 22: -YY_RULE_SETUP -#line 119 "glslang.l" -{ pyylval->lex.line = yylineno; return(DISCARD); }
- YY_BREAK -case 23: -YY_RULE_SETUP -#line 120 "glslang.l" -{ pyylval->lex.line = yylineno; return(RETURN); }
- YY_BREAK -case 24: -YY_RULE_SETUP -#line 122 "glslang.l" -{ pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return(MATRIX2); }
- YY_BREAK -case 25: -YY_RULE_SETUP -#line 123 "glslang.l" -{ pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return(MATRIX3); }
- YY_BREAK -case 26: -YY_RULE_SETUP -#line 124 "glslang.l" -{ pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return(MATRIX4); }
- YY_BREAK -case 27: -YY_RULE_SETUP -#line 126 "glslang.l" -{ pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return (VEC2); }
- YY_BREAK -case 28: -YY_RULE_SETUP -#line 127 "glslang.l" -{ pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return (VEC3); }
- YY_BREAK -case 29: -YY_RULE_SETUP -#line 128 "glslang.l" -{ pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return (VEC4); }
- YY_BREAK -case 30: -YY_RULE_SETUP -#line 129 "glslang.l" -{ pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return (IVEC2); }
- YY_BREAK -case 31: -YY_RULE_SETUP -#line 130 "glslang.l" -{ pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return (IVEC3); }
- YY_BREAK -case 32: -YY_RULE_SETUP -#line 131 "glslang.l" -{ pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return (IVEC4); }
- YY_BREAK -case 33: -YY_RULE_SETUP -#line 132 "glslang.l" -{ pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return (BVEC2); }
- YY_BREAK -case 34: -YY_RULE_SETUP -#line 133 "glslang.l" -{ pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return (BVEC3); }
- YY_BREAK -case 35: -YY_RULE_SETUP -#line 134 "glslang.l" -{ pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return (BVEC4); }
- YY_BREAK -case 36: -YY_RULE_SETUP -#line 136 "glslang.l" -{ pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return SAMPLER1D; }
- YY_BREAK -case 37: -YY_RULE_SETUP -#line 137 "glslang.l" -{ pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return SAMPLER2D; }
- YY_BREAK -case 38: -YY_RULE_SETUP -#line 138 "glslang.l" -{ pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return SAMPLER3D; }
- YY_BREAK -case 39: -YY_RULE_SETUP -#line 139 "glslang.l" -{ pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return SAMPLERCUBE; }
- YY_BREAK -case 40: -YY_RULE_SETUP -#line 140 "glslang.l" -{ pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return SAMPLER1DSHADOW; }
- YY_BREAK -case 41: -YY_RULE_SETUP -#line 141 "glslang.l" -{ pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return SAMPLER2DSHADOW; }
- YY_BREAK -case 42: -YY_RULE_SETUP -#line 143 "glslang.l" -{ pyylval->lex.line = yylineno; return(STRUCT); }
- YY_BREAK -case 43: -YY_RULE_SETUP -#line 145 "glslang.l" -{ PaReservedWord(); return 0; }
- YY_BREAK -case 44: -YY_RULE_SETUP -#line 147 "glslang.l" -{ PaReservedWord(); return 0; }
- YY_BREAK -case 45: -YY_RULE_SETUP -#line 148 "glslang.l" -{ PaReservedWord(); return 0; }
- YY_BREAK -case 46: -YY_RULE_SETUP -#line 149 "glslang.l" -{ PaReservedWord(); return 0; }
- YY_BREAK -case 47: -YY_RULE_SETUP -#line 150 "glslang.l" -{ PaReservedWord(); return 0; }
- YY_BREAK -case 48: -YY_RULE_SETUP -#line 151 "glslang.l" -{ PaReservedWord(); return 0; }
- YY_BREAK -case 49: -YY_RULE_SETUP -#line 152 "glslang.l" -{ PaReservedWord(); return 0; }
- YY_BREAK -case 50: -YY_RULE_SETUP -#line 153 "glslang.l" -{ PaReservedWord(); return 0; }
- YY_BREAK -case 51: -YY_RULE_SETUP -#line 155 "glslang.l" -{ PaReservedWord(); return 0; }
- YY_BREAK -case 52: -YY_RULE_SETUP -#line 156 "glslang.l" -{ PaReservedWord(); return 0; }
- YY_BREAK -case 53: -YY_RULE_SETUP -#line 157 "glslang.l" -{ PaReservedWord(); return 0; }
- YY_BREAK -case 54: -YY_RULE_SETUP -#line 159 "glslang.l" -{ PaReservedWord(); return 0; }
- YY_BREAK -case 55: -YY_RULE_SETUP -#line 160 "glslang.l" -{ PaReservedWord(); return 0; }
- YY_BREAK -case 56: -YY_RULE_SETUP -#line 161 "glslang.l" -{ PaReservedWord(); return 0; }
- YY_BREAK -case 57: -YY_RULE_SETUP -#line 162 "glslang.l" -{ PaReservedWord(); return 0; }
- YY_BREAK -case 58: -YY_RULE_SETUP -#line 163 "glslang.l" -{ PaReservedWord(); return 0; }
- YY_BREAK -case 59: -YY_RULE_SETUP -#line 164 "glslang.l" -{ PaReservedWord(); return 0; }
- YY_BREAK -case 60: -YY_RULE_SETUP -#line 165 "glslang.l" -{ PaReservedWord(); return 0; }
- YY_BREAK -case 61: -YY_RULE_SETUP -#line 166 "glslang.l" -{ PaReservedWord(); return 0; }
- YY_BREAK -case 62: -YY_RULE_SETUP -#line 168 "glslang.l" -{ PaReservedWord(); return 0; }
- YY_BREAK -case 63: -YY_RULE_SETUP -#line 169 "glslang.l" -{ PaReservedWord(); return 0; }
- YY_BREAK -case 64: -YY_RULE_SETUP -#line 170 "glslang.l" -{ PaReservedWord(); return 0; }
- YY_BREAK -case 65: -YY_RULE_SETUP -#line 171 "glslang.l" -{ PaReservedWord(); return 0; }
- YY_BREAK -case 66: -YY_RULE_SETUP -#line 172 "glslang.l" -{ PaReservedWord(); return 0; }
- YY_BREAK -case 67: -YY_RULE_SETUP -#line 173 "glslang.l" -{ PaReservedWord(); return 0; }
- YY_BREAK -case 68: -YY_RULE_SETUP -#line 175 "glslang.l" -{ PaReservedWord(); return 0; }
- YY_BREAK -case 69: -YY_RULE_SETUP -#line 176 "glslang.l" -{ PaReservedWord(); return 0; }
- YY_BREAK -case 70: -YY_RULE_SETUP -#line 178 "glslang.l" -{ PaReservedWord(); return 0; }
- YY_BREAK -case 71: -YY_RULE_SETUP -#line 179 "glslang.l" -{ PaReservedWord(); return 0; }
- YY_BREAK -case 72: -YY_RULE_SETUP -#line 180 "glslang.l" -{ PaReservedWord(); return 0; }
- YY_BREAK -case 73: -YY_RULE_SETUP -#line 181 "glslang.l" -{ PaReservedWord(); return 0; }
- YY_BREAK -case 74: -YY_RULE_SETUP -#line 182 "glslang.l" -{ PaReservedWord(); return 0; }
- YY_BREAK -case 75: -YY_RULE_SETUP -#line 183 "glslang.l" -{ PaReservedWord(); return 0; }
- YY_BREAK -case 76: -YY_RULE_SETUP -#line 184 "glslang.l" -{ PaReservedWord(); return 0; }
- YY_BREAK -case 77: -YY_RULE_SETUP -#line 185 "glslang.l" -{ PaReservedWord(); return 0; }
- YY_BREAK -case 78: -YY_RULE_SETUP -#line 186 "glslang.l" -{ PaReservedWord(); return 0; }
- YY_BREAK -case 79: -YY_RULE_SETUP -#line 188 "glslang.l" -{ PaReservedWord(); return 0; }
- YY_BREAK -case 80: -YY_RULE_SETUP -#line 189 "glslang.l" -{ PaReservedWord(); return 0; }
- YY_BREAK -case 81: -YY_RULE_SETUP -#line 190 "glslang.l" -{ PaReservedWord(); return 0; }
- YY_BREAK -case 82: -YY_RULE_SETUP -#line 192 "glslang.l" -{ PaReservedWord(); return 0; }
- YY_BREAK -case 83: -YY_RULE_SETUP -#line 193 "glslang.l" -{ PaReservedWord(); return 0; }
- YY_BREAK -case 84: -YY_RULE_SETUP -#line 195 "glslang.l" -{ PaReservedWord(); return 0; }
- YY_BREAK -case 85: -YY_RULE_SETUP -#line 196 "glslang.l" -{ PaReservedWord(); return 0; }
- YY_BREAK -case 86: -YY_RULE_SETUP -#line 198 "glslang.l" -{
- pyylval->lex.line = yylineno;
- pyylval->lex.string = NewPoolTString(yytext);
- return PaIdentOrType(*pyylval->lex.string, parseContext, pyylval->lex.symbol);
-}
- YY_BREAK -case 87: -YY_RULE_SETUP -#line 204 "glslang.l" -{ pyylval->lex.line = yylineno; pyylval->lex.i = strtol(yytext, 0, 0); return(INTCONSTANT); }
- YY_BREAK -case 88: -YY_RULE_SETUP -#line 205 "glslang.l" -{ pyylval->lex.line = yylineno; pyylval->lex.i = strtol(yytext, 0, 0); return(INTCONSTANT); }
- YY_BREAK -case 89: -YY_RULE_SETUP -#line 206 "glslang.l" -{ pyylval->lex.line = yylineno; parseContext.error(yylineno, "Invalid Octal number.", yytext, "", ""); parseContext.recover(); return 0;}
- YY_BREAK -case 90: -YY_RULE_SETUP -#line 207 "glslang.l" -{ pyylval->lex.line = yylineno; pyylval->lex.i = strtol(yytext, 0, 0); return(INTCONSTANT); }
- YY_BREAK -case 91: -YY_RULE_SETUP -#line 209 "glslang.l" -{ pyylval->lex.line = yylineno; pyylval->lex.f = static_cast<float>(atof(yytext)); return(FLOATCONSTANT); }
- YY_BREAK -case 92: -YY_RULE_SETUP -#line 210 "glslang.l" -{ pyylval->lex.line = yylineno; pyylval->lex.f = static_cast<float>(atof(yytext)); return(FLOATCONSTANT); }
- YY_BREAK -case 93: -YY_RULE_SETUP -#line 211 "glslang.l" -{ pyylval->lex.line = yylineno; pyylval->lex.f = static_cast<float>(atof(yytext)); return(FLOATCONSTANT); }
- YY_BREAK -case 94: -YY_RULE_SETUP -#line 213 "glslang.l" -{ int ret = PaParseComment(pyylval->lex.line, parseContext); if (!ret) return ret; }
- YY_BREAK -case 95: -YY_RULE_SETUP -#line 215 "glslang.l" -{ pyylval->lex.line = yylineno; return(ADD_ASSIGN); }
- YY_BREAK -case 96: -YY_RULE_SETUP -#line 216 "glslang.l" -{ pyylval->lex.line = yylineno; return(SUB_ASSIGN); }
- YY_BREAK -case 97: -YY_RULE_SETUP -#line 217 "glslang.l" -{ pyylval->lex.line = yylineno; return(MUL_ASSIGN); }
- YY_BREAK -case 98: -YY_RULE_SETUP -#line 218 "glslang.l" -{ pyylval->lex.line = yylineno; return(DIV_ASSIGN); }
- YY_BREAK -case 99: -YY_RULE_SETUP -#line 219 "glslang.l" -{ pyylval->lex.line = yylineno; return(MOD_ASSIGN); }
- YY_BREAK -case 100: -YY_RULE_SETUP -#line 220 "glslang.l" -{ pyylval->lex.line = yylineno; return(LEFT_ASSIGN); }
- YY_BREAK -case 101: -YY_RULE_SETUP -#line 221 "glslang.l" -{ pyylval->lex.line = yylineno; return(RIGHT_ASSIGN); }
- YY_BREAK -case 102: -YY_RULE_SETUP -#line 222 "glslang.l" -{ pyylval->lex.line = yylineno; return(AND_ASSIGN); }
- YY_BREAK -case 103: -YY_RULE_SETUP -#line 223 "glslang.l" -{ pyylval->lex.line = yylineno; return(XOR_ASSIGN); }
- YY_BREAK -case 104: -YY_RULE_SETUP -#line 224 "glslang.l" -{ pyylval->lex.line = yylineno; return(OR_ASSIGN); }
- YY_BREAK -case 105: -YY_RULE_SETUP -#line 226 "glslang.l" -{ pyylval->lex.line = yylineno; return(INC_OP); }
- YY_BREAK -case 106: -YY_RULE_SETUP -#line 227 "glslang.l" -{ pyylval->lex.line = yylineno; return(DEC_OP); }
- YY_BREAK -case 107: -YY_RULE_SETUP -#line 228 "glslang.l" -{ pyylval->lex.line = yylineno; return(AND_OP); }
- YY_BREAK -case 108: -YY_RULE_SETUP -#line 229 "glslang.l" -{ pyylval->lex.line = yylineno; return(OR_OP); }
- YY_BREAK -case 109: -YY_RULE_SETUP -#line 230 "glslang.l" -{ pyylval->lex.line = yylineno; return(XOR_OP); }
- YY_BREAK -case 110: -YY_RULE_SETUP -#line 231 "glslang.l" -{ pyylval->lex.line = yylineno; return(LE_OP); }
- YY_BREAK -case 111: -YY_RULE_SETUP -#line 232 "glslang.l" -{ pyylval->lex.line = yylineno; return(GE_OP); }
- YY_BREAK -case 112: -YY_RULE_SETUP -#line 233 "glslang.l" -{ pyylval->lex.line = yylineno; return(EQ_OP); }
- YY_BREAK -case 113: -YY_RULE_SETUP -#line 234 "glslang.l" -{ pyylval->lex.line = yylineno; return(NE_OP); }
- YY_BREAK -case 114: -YY_RULE_SETUP -#line 235 "glslang.l" -{ pyylval->lex.line = yylineno; return(LEFT_OP); }
- YY_BREAK -case 115: -YY_RULE_SETUP -#line 236 "glslang.l" -{ pyylval->lex.line = yylineno; return(RIGHT_OP); }
- YY_BREAK -case 116: -YY_RULE_SETUP -#line 237 "glslang.l" -{ pyylval->lex.line = yylineno; parseContext.lexAfterType = false; return(SEMICOLON); }
- YY_BREAK -case 117: -YY_RULE_SETUP -#line 238 "glslang.l" -{ pyylval->lex.line = yylineno; parseContext.lexAfterType = false; return(LEFT_BRACE); }
- YY_BREAK -case 118: -YY_RULE_SETUP -#line 239 "glslang.l" -{ pyylval->lex.line = yylineno; return(RIGHT_BRACE); }
- YY_BREAK -case 119: -YY_RULE_SETUP -#line 240 "glslang.l" -{ pyylval->lex.line = yylineno; if (parseContext.inTypeParen) parseContext.lexAfterType = false; return(COMMA); }
- YY_BREAK -case 120: -YY_RULE_SETUP -#line 241 "glslang.l" -{ pyylval->lex.line = yylineno; return(COLON); }
- YY_BREAK -case 121: -YY_RULE_SETUP -#line 242 "glslang.l" -{ pyylval->lex.line = yylineno; parseContext.lexAfterType = false; return(EQUAL); }
- YY_BREAK -case 122: -YY_RULE_SETUP -#line 243 "glslang.l" -{ pyylval->lex.line = yylineno; parseContext.lexAfterType = false; parseContext.inTypeParen = true; return(LEFT_PAREN); }
- YY_BREAK -case 123: -YY_RULE_SETUP -#line 244 "glslang.l" -{ pyylval->lex.line = yylineno; parseContext.inTypeParen = false; return(RIGHT_PAREN); }
- YY_BREAK -case 124: -YY_RULE_SETUP -#line 245 "glslang.l" -{ pyylval->lex.line = yylineno; return(LEFT_BRACKET); }
- YY_BREAK -case 125: -YY_RULE_SETUP -#line 246 "glslang.l" -{ pyylval->lex.line = yylineno; return(RIGHT_BRACKET); }
- YY_BREAK -case 126: -YY_RULE_SETUP -#line 247 "glslang.l" -{ BEGIN(FIELDS); return(DOT); }
- YY_BREAK -case 127: -YY_RULE_SETUP -#line 248 "glslang.l" -{ pyylval->lex.line = yylineno; return(BANG); }
- YY_BREAK -case 128: -YY_RULE_SETUP -#line 249 "glslang.l" -{ pyylval->lex.line = yylineno; return(DASH); }
- YY_BREAK -case 129: -YY_RULE_SETUP -#line 250 "glslang.l" -{ pyylval->lex.line = yylineno; return(TILDE); }
- YY_BREAK -case 130: -YY_RULE_SETUP -#line 251 "glslang.l" -{ pyylval->lex.line = yylineno; return(PLUS); }
- YY_BREAK -case 131: -YY_RULE_SETUP -#line 252 "glslang.l" -{ pyylval->lex.line = yylineno; return(STAR); }
- YY_BREAK -case 132: -YY_RULE_SETUP -#line 253 "glslang.l" -{ pyylval->lex.line = yylineno; return(SLASH); }
- YY_BREAK -case 133: -YY_RULE_SETUP -#line 254 "glslang.l" -{ pyylval->lex.line = yylineno; return(PERCENT); }
- YY_BREAK -case 134: -YY_RULE_SETUP -#line 255 "glslang.l" -{ pyylval->lex.line = yylineno; return(LEFT_ANGLE); }
- YY_BREAK -case 135: -YY_RULE_SETUP -#line 256 "glslang.l" -{ pyylval->lex.line = yylineno; return(RIGHT_ANGLE); }
- YY_BREAK -case 136: -YY_RULE_SETUP -#line 257 "glslang.l" -{ pyylval->lex.line = yylineno; return(VERTICAL_BAR); }
- YY_BREAK -case 137: -YY_RULE_SETUP -#line 258 "glslang.l" -{ pyylval->lex.line = yylineno; return(CARET); }
- YY_BREAK -case 138: -YY_RULE_SETUP -#line 259 "glslang.l" -{ pyylval->lex.line = yylineno; return(AMPERSAND); }
- YY_BREAK -case 139: -YY_RULE_SETUP -#line 260 "glslang.l" -{ pyylval->lex.line = yylineno; return(QUESTION); }
- YY_BREAK -case 140: -YY_RULE_SETUP -#line 262 "glslang.l" -{
-BEGIN(INITIAL);
- pyylval->lex.line = yylineno;
- pyylval->lex.string = NewPoolTString(yytext);
- return FIELD_SELECTION; }
- YY_BREAK -case 141: -YY_RULE_SETUP -#line 267 "glslang.l" -{}
- YY_BREAK -case 142: -YY_RULE_SETUP -#line 269 "glslang.l" -{ }
- YY_BREAK -case YY_STATE_EOF(INITIAL): -case YY_STATE_EOF(FIELDS): -#line 270 "glslang.l" -{ (&parseContext)->AfterEOF = true; yy_delete_buffer(YY_CURRENT_BUFFER); yyterminate();}
- YY_BREAK -case 143: -YY_RULE_SETUP -#line 271 "glslang.l" -{ parseContext.infoSink.info << "FLEX: Unknown char " << yytext << "\n";
- return 0; }
- YY_BREAK -case 144: -YY_RULE_SETUP -#line 274 "glslang.l" -ECHO; - YY_BREAK -#line 1723 "Gen_glslang.cpp" - - case YY_END_OF_BUFFER: - { - /* Amount of text matched not including the EOB char. */ - int yy_amount_of_matched_text = (int) (yy_cp - yytext_ptr) - 1; - - /* Undo the effects of YY_DO_BEFORE_ACTION. */ - *yy_cp = yy_hold_char; - YY_RESTORE_YY_MORE_OFFSET - - if ( yy_current_buffer->yy_buffer_status == YY_BUFFER_NEW ) - { - /* We're scanning a new file or input source. It's - * possible that this happened because the user - * just pointed yyin at a new source and called - * yylex(). If so, then we have to assure - * consistency between yy_current_buffer and our - * globals. Here is the right place to do so, because - * this is the first action (other than possibly a - * back-up) that will match for the new input source. - */ - yy_n_chars = yy_current_buffer->yy_n_chars; - yy_current_buffer->yy_input_file = yyin; - yy_current_buffer->yy_buffer_status = YY_BUFFER_NORMAL; - } - - /* Note that here we test for yy_c_buf_p "<=" to the position - * of the first EOB in the buffer, since yy_c_buf_p will - * already have been incremented past the NUL character - * (since all states make transitions on EOB to the - * end-of-buffer state). Contrast this with the test - * in input(). - */ - if ( yy_c_buf_p <= &yy_current_buffer->yy_ch_buf[yy_n_chars] ) - { /* This was really a NUL. */ - yy_state_type yy_next_state; - - yy_c_buf_p = yytext_ptr + yy_amount_of_matched_text; - - yy_current_state = yy_get_previous_state(); - - /* Okay, we're now positioned to make the NUL - * transition. We couldn't have - * yy_get_previous_state() go ahead and do it - * for us because it doesn't know how to deal - * with the possibility of jamming (and we don't - * want to build jamming into it because then it - * will run more slowly). - */ - - yy_next_state = yy_try_NUL_trans( yy_current_state ); - - yy_bp = yytext_ptr + YY_MORE_ADJ; - - if ( yy_next_state ) - { - /* Consume the NUL. */ - yy_cp = ++yy_c_buf_p; - yy_current_state = yy_next_state; - goto yy_match; - } - - else - { - yy_cp = yy_c_buf_p; - goto yy_find_action; - } - } - - else switch ( yy_get_next_buffer() ) - { - case EOB_ACT_END_OF_FILE: - { - yy_did_buffer_switch_on_eof = 0; - - if ( yywrap() ) - { - /* Note: because we've taken care in - * yy_get_next_buffer() to have set up - * yytext, we can now set up - * yy_c_buf_p so that if some total - * hoser (like flex itself) wants to - * call the scanner after we return the - * YY_NULL, it'll still work - another - * YY_NULL will get returned. - */ - yy_c_buf_p = yytext_ptr + YY_MORE_ADJ; - - yy_act = YY_STATE_EOF(YY_START); - goto do_action; - } - - else - { - if ( ! yy_did_buffer_switch_on_eof ) - YY_NEW_FILE; - } - break; - } - - case EOB_ACT_CONTINUE_SCAN: - yy_c_buf_p = - yytext_ptr + yy_amount_of_matched_text; - - yy_current_state = yy_get_previous_state(); - - yy_cp = yy_c_buf_p; - yy_bp = yytext_ptr + YY_MORE_ADJ; - goto yy_match; - - case EOB_ACT_LAST_MATCH: - yy_c_buf_p = - &yy_current_buffer->yy_ch_buf[yy_n_chars]; - - yy_current_state = yy_get_previous_state(); - - yy_cp = yy_c_buf_p; - yy_bp = yytext_ptr + YY_MORE_ADJ; - goto yy_find_action; - } - break; - } - - default: - YY_FATAL_ERROR( - "fatal flex scanner internal error--no action found" ); - } /* end of action switch */ - } /* end of scanning one token */ - } /* end of yylex */ - - -/* yy_get_next_buffer - try to read in a new buffer - * - * Returns a code representing an action: - * EOB_ACT_LAST_MATCH - - * EOB_ACT_CONTINUE_SCAN - continue scanning from current position - * EOB_ACT_END_OF_FILE - end of file - */ - -static int yy_get_next_buffer() - { - register char *dest = yy_current_buffer->yy_ch_buf; - register char *source = yytext_ptr; - register int number_to_move, i; - int ret_val; - - if ( yy_c_buf_p > &yy_current_buffer->yy_ch_buf[yy_n_chars + 1] ) - YY_FATAL_ERROR( - "fatal flex scanner internal error--end of buffer missed" ); - - if ( yy_current_buffer->yy_fill_buffer == 0 ) - { /* Don't try to fill the buffer, so this is an EOF. */ - if ( yy_c_buf_p - yytext_ptr - YY_MORE_ADJ == 1 ) - { - /* We matched a single character, the EOB, so - * treat this as a final EOF. - */ - return EOB_ACT_END_OF_FILE; - } - - else - { - /* We matched some text prior to the EOB, first - * process it. - */ - return EOB_ACT_LAST_MATCH; - } - } - - /* Try to read more data. */ - - /* First move last chars to start of buffer. */ - number_to_move = (int) (yy_c_buf_p - yytext_ptr) - 1; - - for ( i = 0; i < number_to_move; ++i ) - *(dest++) = *(source++); - - if ( yy_current_buffer->yy_buffer_status == YY_BUFFER_EOF_PENDING ) - /* don't do the read, it's not guaranteed to return an EOF, - * just force an EOF - */ - yy_current_buffer->yy_n_chars = yy_n_chars = 0; - - else - { - int num_to_read = - yy_current_buffer->yy_buf_size - number_to_move - 1; - - while ( num_to_read <= 0 ) - { /* Not enough room in the buffer - grow it. */ -#ifdef YY_USES_REJECT - YY_FATAL_ERROR( -"input buffer overflow, can't enlarge buffer because scanner uses REJECT" ); -#else - - /* just a shorter name for the current buffer */ - YY_BUFFER_STATE b = yy_current_buffer; - - int yy_c_buf_p_offset = - (int) (yy_c_buf_p - b->yy_ch_buf); - - if ( b->yy_is_our_buffer ) - { - int new_size = b->yy_buf_size * 2; - - if ( new_size <= 0 ) - b->yy_buf_size += b->yy_buf_size / 8; - else - b->yy_buf_size *= 2; - - b->yy_ch_buf = (char *) - /* Include room in for 2 EOB chars. */ - yy_flex_realloc( (void *) b->yy_ch_buf, - b->yy_buf_size + 2 ); - } - else - /* Can't grow it, we don't own it. */ - b->yy_ch_buf = 0; - - if ( ! b->yy_ch_buf ) - YY_FATAL_ERROR( - "fatal error - scanner input buffer overflow" ); - - yy_c_buf_p = &b->yy_ch_buf[yy_c_buf_p_offset]; - - num_to_read = yy_current_buffer->yy_buf_size - - number_to_move - 1; -#endif - } - - if ( num_to_read > YY_READ_BUF_SIZE ) - num_to_read = YY_READ_BUF_SIZE; - - /* Read in more data. */ - YY_INPUT( (&yy_current_buffer->yy_ch_buf[number_to_move]), - yy_n_chars, num_to_read ); - - yy_current_buffer->yy_n_chars = yy_n_chars; - } - - if ( yy_n_chars == 0 ) - { - if ( number_to_move == YY_MORE_ADJ ) - { - ret_val = EOB_ACT_END_OF_FILE; - yyrestart( yyin ); - } - - else - { - ret_val = EOB_ACT_LAST_MATCH; - yy_current_buffer->yy_buffer_status = - YY_BUFFER_EOF_PENDING; - } - } - - else - ret_val = EOB_ACT_CONTINUE_SCAN; - - yy_n_chars += number_to_move; - yy_current_buffer->yy_ch_buf[yy_n_chars] = YY_END_OF_BUFFER_CHAR; - yy_current_buffer->yy_ch_buf[yy_n_chars + 1] = YY_END_OF_BUFFER_CHAR; - - yytext_ptr = &yy_current_buffer->yy_ch_buf[0]; - - return ret_val; - } - - -/* yy_get_previous_state - get the state just before the EOB char was reached */ - -static yy_state_type yy_get_previous_state() - { - register yy_state_type yy_current_state; - register char *yy_cp; - - yy_current_state = yy_start; - - for ( yy_cp = yytext_ptr + YY_MORE_ADJ; yy_cp < yy_c_buf_p; ++yy_cp ) - { - register YY_CHAR yy_c = (*yy_cp ? yy_ec[YY_SC_TO_UI(*yy_cp)] : 1); - if ( yy_accept[yy_current_state] ) - { - yy_last_accepting_state = yy_current_state; - yy_last_accepting_cpos = yy_cp; - } - while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) - { - yy_current_state = (int) yy_def[yy_current_state]; - if ( yy_current_state >= 428 ) - yy_c = yy_meta[(unsigned int) yy_c]; - } - yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; - } - - return yy_current_state; - } - - -/* yy_try_NUL_trans - try to make a transition on the NUL character - * - * synopsis - * next_state = yy_try_NUL_trans( current_state ); - */ - -#ifdef YY_USE_PROTOS -static yy_state_type yy_try_NUL_trans( yy_state_type yy_current_state ) -#else -static yy_state_type yy_try_NUL_trans( yy_current_state ) -yy_state_type yy_current_state; -#endif - { - register int yy_is_jam; - register char *yy_cp = yy_c_buf_p; - - register YY_CHAR yy_c = 1; - if ( yy_accept[yy_current_state] ) - { - yy_last_accepting_state = yy_current_state; - yy_last_accepting_cpos = yy_cp; - } - while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) - { - yy_current_state = (int) yy_def[yy_current_state]; - if ( yy_current_state >= 428 ) - yy_c = yy_meta[(unsigned int) yy_c]; - } - yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; - yy_is_jam = (yy_current_state == 427); - - return yy_is_jam ? 0 : yy_current_state; - } - - -#ifndef YY_NO_UNPUT -#ifdef YY_USE_PROTOS -static void yyunput( int c, register char *yy_bp ) -#else -static void yyunput( c, yy_bp ) -int c; -register char *yy_bp; -#endif - { - register char *yy_cp = yy_c_buf_p; - - /* undo effects of setting up yytext */ - *yy_cp = yy_hold_char; - - if ( yy_cp < yy_current_buffer->yy_ch_buf + 2 ) - { /* need to shift things up to make room */ - /* +2 for EOB chars. */ - register int number_to_move = yy_n_chars + 2; - register char *dest = &yy_current_buffer->yy_ch_buf[ - yy_current_buffer->yy_buf_size + 2]; - register char *source = - &yy_current_buffer->yy_ch_buf[number_to_move]; - - while ( source > yy_current_buffer->yy_ch_buf ) - *--dest = *--source; - - yy_cp += (int) (dest - source); - yy_bp += (int) (dest - source); - yy_current_buffer->yy_n_chars = - yy_n_chars = yy_current_buffer->yy_buf_size; - - if ( yy_cp < yy_current_buffer->yy_ch_buf + 2 ) - YY_FATAL_ERROR( "flex scanner push-back overflow" ); - } - - *--yy_cp = (char) c; - - - yytext_ptr = yy_bp; - yy_hold_char = *yy_cp; - yy_c_buf_p = yy_cp; - } -#endif /* ifndef YY_NO_UNPUT */ - - -#ifdef __cplusplus -static int yyinput() -#else -static int input() -#endif - { - int c; - - *yy_c_buf_p = yy_hold_char; - - if ( *yy_c_buf_p == YY_END_OF_BUFFER_CHAR ) - { - /* yy_c_buf_p now points to the character we want to return. - * If this occurs *before* the EOB characters, then it's a - * valid NUL; if not, then we've hit the end of the buffer. - */ - if ( yy_c_buf_p < &yy_current_buffer->yy_ch_buf[yy_n_chars] ) - /* This was really a NUL. */ - *yy_c_buf_p = '\0'; - - else - { /* need more input */ - int offset = yy_c_buf_p - yytext_ptr; - ++yy_c_buf_p; - - switch ( yy_get_next_buffer() ) - { - case EOB_ACT_LAST_MATCH: - /* This happens because yy_g_n_b() - * sees that we've accumulated a - * token and flags that we need to - * try matching the token before - * proceeding. But for input(), - * there's no matching to consider. - * So convert the EOB_ACT_LAST_MATCH - * to EOB_ACT_END_OF_FILE. - */ - - /* Reset buffer status. */ - yyrestart( yyin ); - - /* fall through */ - - case EOB_ACT_END_OF_FILE: - { - if ( yywrap() ) - return EOF; - - if ( ! yy_did_buffer_switch_on_eof ) - YY_NEW_FILE; -#ifdef __cplusplus - return yyinput(); -#else - return input(); -#endif - } - - case EOB_ACT_CONTINUE_SCAN: - yy_c_buf_p = yytext_ptr + offset; - break; - } - } - } - - c = *(unsigned char *) yy_c_buf_p; /* cast for 8-bit char's */ - *yy_c_buf_p = '\0'; /* preserve yytext */ - yy_hold_char = *++yy_c_buf_p; - - - return c; - } - - -#ifdef YY_USE_PROTOS -void yyrestart( FILE *input_file ) -#else -void yyrestart( input_file ) -FILE *input_file; -#endif - { - if ( ! yy_current_buffer ) - yy_current_buffer = yy_create_buffer( yyin, YY_BUF_SIZE ); - - yy_init_buffer( yy_current_buffer, input_file ); - yy_load_buffer_state(); - } - - -#ifdef YY_USE_PROTOS -void yy_switch_to_buffer( YY_BUFFER_STATE new_buffer ) -#else -void yy_switch_to_buffer( new_buffer ) -YY_BUFFER_STATE new_buffer; -#endif - { - if ( yy_current_buffer == new_buffer ) - return; - - if ( yy_current_buffer ) - { - /* Flush out information for old buffer. */ - *yy_c_buf_p = yy_hold_char; - yy_current_buffer->yy_buf_pos = yy_c_buf_p; - yy_current_buffer->yy_n_chars = yy_n_chars; - } - - yy_current_buffer = new_buffer; - yy_load_buffer_state(); - - /* We don't actually know whether we did this switch during - * EOF (yywrap()) processing, but the only time this flag - * is looked at is after yywrap() is called, so it's safe - * to go ahead and always set it. - */ - yy_did_buffer_switch_on_eof = 1; - } - - -#ifdef YY_USE_PROTOS -void yy_load_buffer_state( void ) -#else -void yy_load_buffer_state() -#endif - { - yy_n_chars = yy_current_buffer->yy_n_chars; - yytext_ptr = yy_c_buf_p = yy_current_buffer->yy_buf_pos; - yyin = yy_current_buffer->yy_input_file; - yy_hold_char = *yy_c_buf_p; - } - - -#ifdef YY_USE_PROTOS -YY_BUFFER_STATE yy_create_buffer( FILE *file, int size ) -#else -YY_BUFFER_STATE yy_create_buffer( file, size ) -FILE *file; -int size; -#endif - { - YY_BUFFER_STATE b; - - b = (YY_BUFFER_STATE) yy_flex_alloc( sizeof( struct yy_buffer_state ) ); - if ( ! b ) - YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" ); - - b->yy_buf_size = size; - - /* yy_ch_buf has to be 2 characters longer than the size given because - * we need to put in 2 end-of-buffer characters. - */ - b->yy_ch_buf = (char *) yy_flex_alloc( b->yy_buf_size + 2 ); - if ( ! b->yy_ch_buf ) - YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" ); - - b->yy_is_our_buffer = 1; - - yy_init_buffer( b, file ); - - return b; - } - - -#ifdef YY_USE_PROTOS -void yy_delete_buffer( YY_BUFFER_STATE b ) -#else -void yy_delete_buffer( b ) -YY_BUFFER_STATE b; -#endif - { - if ( ! b ) - return; - - if ( b == yy_current_buffer ) - yy_current_buffer = (YY_BUFFER_STATE) 0; - - if ( b->yy_is_our_buffer ) - yy_flex_free( (void *) b->yy_ch_buf ); - - yy_flex_free( (void *) b ); - } - - - -#ifdef YY_USE_PROTOS -void yy_init_buffer( YY_BUFFER_STATE b, FILE *file ) -#else -void yy_init_buffer( b, file ) -YY_BUFFER_STATE b; -FILE *file; -#endif - - - { - yy_flush_buffer( b ); - - b->yy_input_file = file; - b->yy_fill_buffer = 1; - -#if YY_ALWAYS_INTERACTIVE - b->yy_is_interactive = 1; -#else -#if YY_NEVER_INTERACTIVE - b->yy_is_interactive = 0; -#else - b->yy_is_interactive = file ? (isatty( fileno(file) ) > 0) : 0; -#endif -#endif - } - - -#ifdef YY_USE_PROTOS -void yy_flush_buffer( YY_BUFFER_STATE b ) -#else -void yy_flush_buffer( b ) -YY_BUFFER_STATE b; -#endif - - { - if ( ! b ) - return; - - b->yy_n_chars = 0; - - /* We always need two end-of-buffer characters. The first causes - * a transition to the end-of-buffer state. The second causes - * a jam in that state. - */ - b->yy_ch_buf[0] = YY_END_OF_BUFFER_CHAR; - b->yy_ch_buf[1] = YY_END_OF_BUFFER_CHAR; - - b->yy_buf_pos = &b->yy_ch_buf[0]; - - b->yy_at_bol = 1; - b->yy_buffer_status = YY_BUFFER_NEW; - - if ( b == yy_current_buffer ) - yy_load_buffer_state(); - } - - -#ifndef YY_NO_SCAN_BUFFER -#ifdef YY_USE_PROTOS -YY_BUFFER_STATE yy_scan_buffer( char *base, yy_size_t size ) -#else -YY_BUFFER_STATE yy_scan_buffer( base, size ) -char *base; -yy_size_t size; -#endif - { - YY_BUFFER_STATE b; - - if ( size < 2 || - base[size-2] != YY_END_OF_BUFFER_CHAR || - base[size-1] != YY_END_OF_BUFFER_CHAR ) - /* They forgot to leave room for the EOB's. */ - return 0; - - b = (YY_BUFFER_STATE) yy_flex_alloc( sizeof( struct yy_buffer_state ) ); - if ( ! b ) - YY_FATAL_ERROR( "out of dynamic memory in yy_scan_buffer()" ); - - b->yy_buf_size = size - 2; /* "- 2" to take care of EOB's */ - b->yy_buf_pos = b->yy_ch_buf = base; - b->yy_is_our_buffer = 0; - b->yy_input_file = 0; - b->yy_n_chars = b->yy_buf_size; - b->yy_is_interactive = 0; - b->yy_at_bol = 1; - b->yy_fill_buffer = 0; - b->yy_buffer_status = YY_BUFFER_NEW; - - yy_switch_to_buffer( b ); - - return b; - } -#endif - - -#ifndef YY_NO_SCAN_STRING -#ifdef YY_USE_PROTOS -YY_BUFFER_STATE yy_scan_string( yyconst char *yy_str ) -#else -YY_BUFFER_STATE yy_scan_string( yy_str ) -yyconst char *yy_str; -#endif - { - int len; - for ( len = 0; yy_str[len]; ++len ) - ; - - return yy_scan_bytes( yy_str, len ); - } -#endif - - -#ifndef YY_NO_SCAN_BYTES -#ifdef YY_USE_PROTOS -YY_BUFFER_STATE yy_scan_bytes( yyconst char *bytes, int len ) -#else -YY_BUFFER_STATE yy_scan_bytes( bytes, len ) -yyconst char *bytes; -int len; -#endif - { - YY_BUFFER_STATE b; - char *buf; - yy_size_t n; - int i; - - /* Get memory for full buffer, including space for trailing EOB's. */ - n = len + 2; - buf = (char *) yy_flex_alloc( n ); - if ( ! buf ) - YY_FATAL_ERROR( "out of dynamic memory in yy_scan_bytes()" ); - - for ( i = 0; i < len; ++i ) - buf[i] = bytes[i]; - - buf[len] = buf[len+1] = YY_END_OF_BUFFER_CHAR; - - b = yy_scan_buffer( buf, n ); - if ( ! b ) - YY_FATAL_ERROR( "bad buffer in yy_scan_bytes()" ); - - /* It's okay to grow etc. this buffer, and we should throw it - * away when we're done. - */ - b->yy_is_our_buffer = 1; - - return b; - } -#endif - - -#ifndef YY_NO_PUSH_STATE -#ifdef YY_USE_PROTOS -static void yy_push_state( int new_state ) -#else -static void yy_push_state( new_state ) -int new_state; -#endif - { - if ( yy_start_stack_ptr >= yy_start_stack_depth ) - { - yy_size_t new_size; - - yy_start_stack_depth += YY_START_STACK_INCR; - new_size = yy_start_stack_depth * sizeof( int ); - - if ( ! yy_start_stack ) - yy_start_stack = (int *) yy_flex_alloc( new_size ); - - else - yy_start_stack = (int *) yy_flex_realloc( - (void *) yy_start_stack, new_size ); - - if ( ! yy_start_stack ) - YY_FATAL_ERROR( - "out of memory expanding start-condition stack" ); - } - - yy_start_stack[yy_start_stack_ptr++] = YY_START; - - BEGIN(new_state); - } -#endif - - -#ifndef YY_NO_POP_STATE -static void yy_pop_state() - { - if ( --yy_start_stack_ptr < 0 ) - YY_FATAL_ERROR( "start-condition stack underflow" ); - - BEGIN(yy_start_stack[yy_start_stack_ptr]); - } -#endif - - -#ifndef YY_NO_TOP_STATE -static int yy_top_state() - { - return yy_start_stack[yy_start_stack_ptr - 1]; - } -#endif - -#ifndef YY_EXIT_FAILURE -#define YY_EXIT_FAILURE 2 -#endif - -#ifdef YY_USE_PROTOS -static void yy_fatal_error( yyconst char msg[] ) -#else -static void yy_fatal_error( msg ) -char msg[]; -#endif - { - (void) fprintf( stderr, "%s\n", msg ); - exit( YY_EXIT_FAILURE ); - } - - - -/* Redefine yyless() so it works in section 3 code. */ - -#undef yyless -#define yyless(n) \ - do \ - { \ - /* Undo effects of setting up yytext. */ \ - yytext[yyleng] = yy_hold_char; \ - yy_c_buf_p = yytext + n; \ - yy_hold_char = *yy_c_buf_p; \ - *yy_c_buf_p = '\0'; \ - yyleng = n; \ - } \ - while ( 0 ) - - -/* Internal utility routines. */ - -#ifndef yytext_ptr -#ifdef YY_USE_PROTOS -static void yy_flex_strncpy( char *s1, yyconst char *s2, int n ) -#else -static void yy_flex_strncpy( s1, s2, n ) -char *s1; -yyconst char *s2; -int n; -#endif - { - register int i; - for ( i = 0; i < n; ++i ) - s1[i] = s2[i]; - } -#endif - -#ifdef YY_NEED_STRLEN -#ifdef YY_USE_PROTOS -static int yy_flex_strlen( yyconst char *s ) -#else -static int yy_flex_strlen( s ) -yyconst char *s; -#endif - { - register int n; - for ( n = 0; s[n]; ++n ) - ; - - return n; - } -#endif - - -#ifdef YY_USE_PROTOS -static void *yy_flex_alloc( yy_size_t size ) -#else -static void *yy_flex_alloc( size ) -yy_size_t size; -#endif - { - return (void *) malloc( size ); - } - -#ifdef YY_USE_PROTOS -static void *yy_flex_realloc( void *ptr, yy_size_t size ) -#else -static void *yy_flex_realloc( ptr, size ) -void *ptr; -yy_size_t size; -#endif - { - /* The cast to (char *) in the following accommodates both - * implementations that use char* generic pointers, and those - * that use void* generic pointers. It works with the latter - * because both ANSI C and C++ allow castless assignment from - * any pointer type to void*, and deal with argument conversions - * as though doing an assignment. - */ - return (void *) realloc( (char *) ptr, size ); - } - -#ifdef YY_USE_PROTOS -static void yy_flex_free( void *ptr ) -#else -static void yy_flex_free( ptr ) -void *ptr; -#endif - { - free( ptr ); - } - -#if YY_MAIN -int main() - { - yylex(); - return 0; - } -#endif -#line 274 "glslang.l" - -
-
-//Including Pre-processor.
-extern "C" {
- #include "./preprocessor/preprocess.h"
-}
-
-//
-// The YY_INPUT macro just calls this. Maybe this could be just put into
-// the macro directly.
-//
-
-int yy_input(char* buf, int max_size)
-{
- char *char_token =NULL;
- int len;
-
- if ((len = yylex_CPP(buf, max_size)) == 0)
- return 0;
- if (len >= max_size)
- YY_FATAL_ERROR( "input buffer overflow, can't enlarge buffer because scanner uses REJECT" );
-
- buf[len] = ' ';
- return len+1;
-}
-
-
-//
-// Parse an array of strings using yyparse. We set up globals used by
-// yywrap.
-//
-// Returns 0 for success, as per yyparse().
-//
-int PaParseStrings(char* argv[], int strLen[], int argc, TParseContext& parseContextLocal)
-{
- int argv0len;
- ScanFromString(argv[0]);
-
- //Storing the Current Compiler Parse context into the cpp structure.
- cpp->pC = (void*)&parseContextLocal;
-
- if (!argv || argc == 0 || !argv[0])
- return 1;
-
- if (!strLen) {
- argv0len = (int) strlen(argv[0]);
- strLen = &argv0len;
- }
- yyrestart(0);
- (&parseContextLocal)->AfterEOF = false;
- cpp->PaWhichStr = 0;
- cpp->PaArgv = argv;
- cpp->PaArgc = argc;
- cpp->PaStrLen = strLen;
- yylineno = 1;
-
- if (*cpp->PaStrLen >= 0) {
- int ret;
- #ifdef _WIN32
- ret = yyparse(parseContextLocal);
- #else
- ret = yyparse((void*)(&parseContextLocal));
- #endif
- if (cpp->CompileError == 1 || parseContextLocal.recoveredFromError || parseContextLocal.numErrors > 0)
- return 1;
- else
- return 0;
- }
- else
- return 0;
-}
-
-void yyerror(char *s)
-{
- if (((TParseContext *)cpp->pC)->AfterEOF) {
- if (cpp->tokensBeforeEOF == 1) {
- GlobalParseContext->error(yylineno, "syntax error", "pre-mature EOF", s, "");
- GlobalParseContext->recover();
- }
- } else {
- GlobalParseContext->error(yylineno, "syntax error", yytext, s, "");
- GlobalParseContext->recover();
- }
-}
-
-void PaReservedWord()
-{
- GlobalParseContext->error(yylineno, "Reserved word.", yytext, "", "");
- GlobalParseContext->recover();
-}
-
-int PaIdentOrType(TString& id, TParseContext& parseContextLocal, TSymbol*& symbol)
-{
- symbol = parseContextLocal.symbolTable.find(id);
- if (parseContextLocal.lexAfterType == false && symbol && symbol->isVariable()) {
- TVariable* variable = static_cast<TVariable*>(symbol);
- if (variable->isUserType()) {
- parseContextLocal.lexAfterType = true;
- return TYPE_NAME;
- }
- }
-
- return IDENTIFIER;
-}
-
-int PaParseComment(int &lineno, TParseContext& parseContextLocal)
-{
- int transitionFlag = 0;
- int nextChar;
-
- while (transitionFlag != 2) {
- nextChar = yyinput();
- if (nextChar == '\n')
- lineno++;
- switch (nextChar) {
- case '*' :
- transitionFlag = 1;
- break;
- case '/' : /* if star is the previous character, then it is the end of comment */
- if (transitionFlag == 1) {
- return 1 ;
- }
- break;
- case EOF :
- /* Raise error message here */
- parseContextLocal.error(yylineno, "End of shader found before end of comment.", "", "", "");
- GlobalParseContext->recover();
- return YY_NULL;
- default : /* Any other character will be a part of the comment */
- transitionFlag = 0;
- }
- }
- return 1;
-}
-
-extern "C" {
-
-void CPPDebugLogMsg(const char *msg)
-{
- ((TParseContext *)cpp->pC)->infoSink.debug.message(EPrefixNone, msg);
-}
-
-void CPPWarningToInfoLog(const char *msg)
-{
- ((TParseContext *)cpp->pC)->infoSink.info.message(EPrefixWarning, msg, yylineno);
-}
-
-void CPPShInfoLogMsg(const char *msg)
-{
- ((TParseContext *)cpp->pC)->error(yylineno,"", "",msg,"");
- GlobalParseContext->recover();
-}
-
-void CPPErrorToInfoLog(char *msg)
-{
- ((TParseContext *)cpp->pC)->error(yylineno,"syntax error", "",msg,"");
- GlobalParseContext->recover();
-}
-
-void SetLineNumber(int line)
-{
- yylineno &= ~SourceLocLineMask;
- yylineno |= line;
-}
-
-void SetStringNumber(int string)
-{
- yylineno = (string << SourceLocStringShift) | (yylineno & SourceLocLineMask);
-}
-
-int GetStringNumber(void)
-{
- return yylineno >> 16;
-}
-
-int GetLineNumber(void)
-{
- return yylineno & SourceLocLineMask;
-}
-
-void IncLineNumber(void)
-{
- if ((yylineno & SourceLocLineMask) <= SourceLocLineMask)
- ++yylineno;
-}
-
-void DecLineNumber(void)
-{
- if ((yylineno & SourceLocLineMask) > 0)
- --yylineno;
-}
-
-void HandlePragma(const char **tokens, int numTokens)
-{
- if (!strcmp(tokens[0], "optimize")) {
- if (numTokens != 4) {
- CPPShInfoLogMsg("optimize pragma syntax is incorrect");
- return;
- }
-
- if (strcmp(tokens[1], "(")) {
- CPPShInfoLogMsg("\"(\" expected after 'optimize' keyword");
- return;
- }
-
- if (!strcmp(tokens[2], "on"))
- ((TParseContext *)cpp->pC)->contextPragma.optimize = true;
- else if (!strcmp(tokens[2], "off"))
- ((TParseContext *)cpp->pC)->contextPragma.optimize = false;
- else {
- CPPShInfoLogMsg("\"on\" or \"off\" expected after '(' for 'optimize' pragma");
- return;
- }
-
- if (strcmp(tokens[3], ")")) {
- CPPShInfoLogMsg("\")\" expected to end 'optimize' pragma");
- return;
- }
- } else if (!strcmp(tokens[0], "debug")) {
- if (numTokens != 4) {
- CPPShInfoLogMsg("debug pragma syntax is incorrect");
- return;
- }
-
- if (strcmp(tokens[1], "(")) {
- CPPShInfoLogMsg("\"(\" expected after 'debug' keyword");
- return;
- }
-
- if (!strcmp(tokens[2], "on"))
- ((TParseContext *)cpp->pC)->contextPragma.debug = true;
- else if (!strcmp(tokens[2], "off"))
- ((TParseContext *)cpp->pC)->contextPragma.debug = false;
- else {
- CPPShInfoLogMsg("\"on\" or \"off\" expected after '(' for 'debug' pragma");
- return;
- }
-
- if (strcmp(tokens[3], ")")) {
- CPPShInfoLogMsg("\")\" expected to end 'debug' pragma");
- return;
- }
- } else {
- /*
- // implementation specific pragma
- // use ((TParseContext *)cpp->pC)->contextPragma.pragmaTable to store the information about pragma
- // For now, just ignore the pragma that the implementation cannot recognize
- // An Example of one such implementation for a pragma that has a syntax like
- // #pragma pragmaname(pragmavalue)
- // This implementation stores the current pragmavalue against the pragma name in pragmaTable.
- if (numTokens == 4 && !strcmp(tokens[1], "(") && !strcmp(tokens[3], ")")) {
- TPragmaTable& pragmaTable = ((TParseContext *)cpp->pC)->contextPragma.pragmaTable;
- TPragmaTable::iterator iter;
- iter = pragmaTable.find(TString(tokens[0]));
- if (iter != pragmaTable.end()) {
- iter->second = tokens[2];
- } else {
- pragmaTable[tokens[0]] = tokens[2];
- }
- }
- */
- }
-}
-
-void StoreStr(char *string)
-{
- TString strSrc;
- strSrc = TString(string);
-
- ((TParseContext *)cpp->pC)->HashErrMsg = ((TParseContext *)cpp->pC)->HashErrMsg + " " + strSrc;
-}
-
-const char* GetStrfromTStr(void)
-{
- cpp->ErrMsg = (((TParseContext *)cpp->pC)->HashErrMsg).c_str();
- return cpp->ErrMsg;
-}
-
-void ResetTString(void)
-{
- ((TParseContext *)cpp->pC)->HashErrMsg = "";
-}
-
-TBehavior GetBehavior(const char* behavior)
-{
- if (!strcmp("require", behavior))
- return EBhRequire;
- else if (!strcmp("enable", behavior))
- return EBhEnable;
- else if (!strcmp("disable", behavior))
- return EBhDisable;
- else if (!strcmp("warn", behavior))
- return EBhWarn;
- else {
- CPPShInfoLogMsg((TString("behavior '") + behavior + "' is not supported").c_str());
- return EBhDisable;
- }
-}
-
-void updateExtensionBehavior(const char* extName, const char* behavior)
-{
- TBehavior behaviorVal = GetBehavior(behavior);
- TMap<TString, TBehavior>:: iterator iter;
- TString msg;
-
- // special cased for all extension
- if (!strcmp(extName, "all")) {
- if (behaviorVal == EBhRequire || behaviorVal == EBhEnable) {
- CPPShInfoLogMsg("extension 'all' cannot have 'require' or 'enable' behavior");
- return;
- } else {
- for (iter = ((TParseContext *)cpp->pC)->extensionBehavior.begin(); iter != ((TParseContext *)cpp->pC)->extensionBehavior.end(); ++iter)
- iter->second = behaviorVal;
- }
- } else {
- iter = ((TParseContext *)cpp->pC)->extensionBehavior.find(TString(extName));
- if (iter == ((TParseContext *)cpp->pC)->extensionBehavior.end()) {
- switch (behaviorVal) {
- case EBhRequire:
- CPPShInfoLogMsg((TString("extension '") + extName + "' is not supported").c_str());
- break;
- case EBhEnable:
- case EBhWarn:
- case EBhDisable:
- msg = TString("extension '") + extName + "' is not supported";
- ((TParseContext *)cpp->pC)->infoSink.info.message(EPrefixWarning, msg.c_str(), yylineno);
- break;
- }
- return;
- } else
- iter->second = behaviorVal;
- }
-}
-
-}
-
-void setInitialState()
-{
- yy_start = 1;
-}
diff --git a/src/mesa/shader/slang/MachineIndependent/Gen_glslang_tab.cpp b/src/mesa/shader/slang/MachineIndependent/Gen_glslang_tab.cpp deleted file mode 100755 index 69aa608726..0000000000 --- a/src/mesa/shader/slang/MachineIndependent/Gen_glslang_tab.cpp +++ /dev/null @@ -1,4354 +0,0 @@ -/* A Bison parser, made by GNU Bison 1.875. */ - -/* Skeleton parser for Yacc-like parsing with Bison, - Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002 Free Software Foundation, Inc. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2, or (at your option) - any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, - Boston, MA 02111-1307, USA. */ - -/* As a special exception, when this file is copied by Bison into a - Bison output file, you may use that output file without restriction. - This special exception was added by the Free Software Foundation - in version 1.24 of Bison. */ - -/* Written by Richard Stallman by simplifying the original so called - ``semantic'' parser. */ - -/* All symbols defined below should begin with yy or YY, to avoid - infringing on user name space. This should be done even for local - variables, as they might otherwise be expanded by user macros. - There are some unavoidable exceptions within include files to - define necessary library symbols; they are noted "INFRINGES ON - USER NAME SPACE" below. */ - -/* Identify Bison output. */ -#define YYBISON 1 - -/* Skeleton name. */ -#define YYSKELETON_NAME "yacc.c" - -/* Pure parsers. */ -#define YYPURE 1 - -/* Using locations. */ -#define YYLSP_NEEDED 0 - - - -/* Tokens. */ -#ifndef YYTOKENTYPE -# define YYTOKENTYPE - /* Put the tokens into the symbol table, so that GDB and other debuggers - know about them. */ - enum yytokentype { - ATTRIBUTE = 258, - CONST_QUAL = 259, - BOOL_TYPE = 260, - FLOAT_TYPE = 261, - INT_TYPE = 262, - BREAK = 263, - CONTINUE = 264, - DO = 265, - ELSE = 266, - FOR = 267, - IF = 268, - DISCARD = 269, - RETURN = 270, - BVEC2 = 271, - BVEC3 = 272, - BVEC4 = 273, - IVEC2 = 274, - IVEC3 = 275, - IVEC4 = 276, - VEC2 = 277, - VEC3 = 278, - VEC4 = 279, - MATRIX2 = 280, - MATRIX3 = 281, - MATRIX4 = 282, - IN_QUAL = 283, - OUT_QUAL = 284, - INOUT_QUAL = 285, - UNIFORM = 286, - VARYING = 287, - STRUCT = 288, - VOID_TYPE = 289, - WHILE = 290, - SAMPLER1D = 291, - SAMPLER2D = 292, - SAMPLER3D = 293, - SAMPLERCUBE = 294, - SAMPLER1DSHADOW = 295, - SAMPLER2DSHADOW = 296, - IDENTIFIER = 297, - TYPE_NAME = 298, - FLOATCONSTANT = 299, - INTCONSTANT = 300, - BOOLCONSTANT = 301, - FIELD_SELECTION = 302, - LEFT_OP = 303, - RIGHT_OP = 304, - INC_OP = 305, - DEC_OP = 306, - LE_OP = 307, - GE_OP = 308, - EQ_OP = 309, - NE_OP = 310, - AND_OP = 311, - OR_OP = 312, - XOR_OP = 313, - MUL_ASSIGN = 314, - DIV_ASSIGN = 315, - ADD_ASSIGN = 316, - MOD_ASSIGN = 317, - LEFT_ASSIGN = 318, - RIGHT_ASSIGN = 319, - AND_ASSIGN = 320, - XOR_ASSIGN = 321, - OR_ASSIGN = 322, - SUB_ASSIGN = 323, - LEFT_PAREN = 324, - RIGHT_PAREN = 325, - LEFT_BRACKET = 326, - RIGHT_BRACKET = 327, - LEFT_BRACE = 328, - RIGHT_BRACE = 329, - DOT = 330, - COMMA = 331, - COLON = 332, - EQUAL = 333, - SEMICOLON = 334, - BANG = 335, - DASH = 336, - TILDE = 337, - PLUS = 338, - STAR = 339, - SLASH = 340, - PERCENT = 341, - LEFT_ANGLE = 342, - RIGHT_ANGLE = 343, - VERTICAL_BAR = 344, - CARET = 345, - AMPERSAND = 346, - QUESTION = 347 - }; -#endif -#define ATTRIBUTE 258 -#define CONST_QUAL 259 -#define BOOL_TYPE 260 -#define FLOAT_TYPE 261 -#define INT_TYPE 262 -#define BREAK 263 -#define CONTINUE 264 -#define DO 265 -#define ELSE 266 -#define FOR 267 -#define IF 268 -#define DISCARD 269 -#define RETURN 270 -#define BVEC2 271 -#define BVEC3 272 -#define BVEC4 273 -#define IVEC2 274 -#define IVEC3 275 -#define IVEC4 276 -#define VEC2 277 -#define VEC3 278 -#define VEC4 279 -#define MATRIX2 280 -#define MATRIX3 281 -#define MATRIX4 282 -#define IN_QUAL 283 -#define OUT_QUAL 284 -#define INOUT_QUAL 285 -#define UNIFORM 286 -#define VARYING 287 -#define STRUCT 288 -#define VOID_TYPE 289 -#define WHILE 290 -#define SAMPLER1D 291 -#define SAMPLER2D 292 -#define SAMPLER3D 293 -#define SAMPLERCUBE 294 -#define SAMPLER1DSHADOW 295 -#define SAMPLER2DSHADOW 296 -#define IDENTIFIER 297 -#define TYPE_NAME 298 -#define FLOATCONSTANT 299 -#define INTCONSTANT 300 -#define BOOLCONSTANT 301 -#define FIELD_SELECTION 302 -#define LEFT_OP 303 -#define RIGHT_OP 304 -#define INC_OP 305 -#define DEC_OP 306 -#define LE_OP 307 -#define GE_OP 308 -#define EQ_OP 309 -#define NE_OP 310 -#define AND_OP 311 -#define OR_OP 312 -#define XOR_OP 313 -#define MUL_ASSIGN 314 -#define DIV_ASSIGN 315 -#define ADD_ASSIGN 316 -#define MOD_ASSIGN 317 -#define LEFT_ASSIGN 318 -#define RIGHT_ASSIGN 319 -#define AND_ASSIGN 320 -#define XOR_ASSIGN 321 -#define OR_ASSIGN 322 -#define SUB_ASSIGN 323 -#define LEFT_PAREN 324 -#define RIGHT_PAREN 325 -#define LEFT_BRACKET 326 -#define RIGHT_BRACKET 327 -#define LEFT_BRACE 328 -#define RIGHT_BRACE 329 -#define DOT 330 -#define COMMA 331 -#define COLON 332 -#define EQUAL 333 -#define SEMICOLON 334 -#define BANG 335 -#define DASH 336 -#define TILDE 337 -#define PLUS 338 -#define STAR 339 -#define SLASH 340 -#define PERCENT 341 -#define LEFT_ANGLE 342 -#define RIGHT_ANGLE 343 -#define VERTICAL_BAR 344 -#define CARET 345 -#define AMPERSAND 346 -#define QUESTION 347 - - - - -/* Copy the first part of user declarations. */ -#line 39 "glslang.y" - - -/* Based on: -ANSI C Yacc grammar - -In 1985, Jeff Lee published his Yacc grammar (which is accompanied by a -matching Lex specification) for the April 30, 1985 draft version of the -ANSI C standard. Tom Stockfisch reposted it to net.sources in 1987; that -original, as mentioned in the answer to question 17.25 of the comp.lang.c -FAQ, can be ftp'ed from ftp.uu.net, file usenet/net.sources/ansi.c.grammar.Z. - -I intend to keep this version as close to the current C Standard grammar as -possible; please let me know if you discover discrepancies. - -Jutta Degener, 1995 -*/ - -#include "SymbolTable.h" -#include "ParseHelper.h" -#include "../Public/ShaderLang.h" - -#ifdef _WIN32 - #define YYPARSE_PARAM parseContext - #define YYPARSE_PARAM_DECL TParseContext& - #define YY_DECL int yylex(YYSTYPE* pyylval, TParseContext& parseContext) - #define YYLEX_PARAM parseContext -#else - #define YYPARSE_PARAM parseContextLocal - #define parseContext (*((TParseContext*)(parseContextLocal))) - #define YY_DECL int yylex(YYSTYPE* pyylval, void* parseContextLocal) - #define YYLEX_PARAM (void*)(parseContextLocal) - extern void yyerror(char*); -#endif - -#define FRAG_VERT_ONLY(S, L) { \ - if (parseContext.language != EShLangFragment && \ - parseContext.language != EShLangVertex) { \ - parseContext.error(L, " supported in vertex/fragment shaders only ", S, "", ""); \ - parseContext.recover(); \ - } \ -} - -#define VERTEX_ONLY(S, L) { \ - if (parseContext.language != EShLangVertex) { \ - parseContext.error(L, " supported in vertex shaders only ", S, "", ""); \ - parseContext.recover(); \ - } \ -} - -#define FRAG_ONLY(S, L) { \ - if (parseContext.language != EShLangFragment) { \ - parseContext.error(L, " supported in fragment shaders only ", S, "", ""); \ - parseContext.recover(); \ - } \ -} - -#define PACK_ONLY(S, L) { \ - if (parseContext.language != EShLangPack) { \ - parseContext.error(L, " supported in pack shaders only ", S, "", ""); \ - parseContext.recover(); \ - } \ -} - -#define UNPACK_ONLY(S, L) { \ - if (parseContext.language != EShLangUnpack) { \ - parseContext.error(L, " supported in unpack shaders only ", S, "", ""); \ - parseContext.recover(); \ - } \ -} - -#define PACK_UNPACK_ONLY(S, L) { \ - if (parseContext.language != EShLangUnpack && \ - parseContext.language != EShLangPack) { \ - parseContext.error(L, " supported in pack/unpack shaders only ", S, "", ""); \ - parseContext.recover(); \ - } \ -} - - -/* Enabling traces. */ -#ifndef YYDEBUG -# define YYDEBUG 1 -#endif - -/* Enabling verbose error messages. */ -#ifdef YYERROR_VERBOSE -# undef YYERROR_VERBOSE -# define YYERROR_VERBOSE 1 -#else -# define YYERROR_VERBOSE 0 -#endif - -#if ! defined (YYSTYPE) && ! defined (YYSTYPE_IS_DECLARED) -#line 117 "glslang.y" -typedef union YYSTYPE { - struct { - TSourceLoc line; - union { - TString *string; - float f; - int i; - bool b; - }; - TSymbol* symbol; - } lex; - struct { - TSourceLoc line; - TOperator op; - union { - TIntermNode* intermNode; - TIntermNodePair nodePair; - TIntermTyped* intermTypedNode; - TIntermAggregate* intermAggregate; - }; - union { - TPublicType type; - TQualifier qualifier; - TFunction* function; - TParameter param; - TTypeLine typeLine; - TTypeList* typeList; - }; - } interm; -} YYSTYPE; -/* Line 191 of yacc.c. */ -#line 369 "glslang.tab.c" -# define yystype YYSTYPE /* obsolescent; will be withdrawn */ -# define YYSTYPE_IS_DECLARED 1 -# define YYSTYPE_IS_TRIVIAL 1 -#endif - - - -/* Copy the second part of user declarations. */ -#line 148 "glslang.y" - -#ifndef _WIN32 - extern int yylex(YYSTYPE*, void*); -#endif - - -/* Line 214 of yacc.c. */ -#line 386 "glslang.tab.c" - -#if ! defined (yyoverflow) || YYERROR_VERBOSE - -/* The parser invokes alloca or malloc; define the necessary symbols. */ - -# if YYSTACK_USE_ALLOCA -# define YYSTACK_ALLOC alloca -# else -# ifndef YYSTACK_USE_ALLOCA -# if defined (alloca) || defined (_ALLOCA_H) -# define YYSTACK_ALLOC alloca -# else -# ifdef __GNUC__ -# define YYSTACK_ALLOC __builtin_alloca -# endif -# endif -# endif -# endif - -# ifdef YYSTACK_ALLOC - /* Pacify GCC's `empty if-body' warning. */ -# define YYSTACK_FREE(Ptr) do { /* empty */; } while (0) -# else -# if defined (__STDC__) || defined (__cplusplus) -# include <stdlib.h> /* INFRINGES ON USER NAME SPACE */ -# define YYSIZE_T size_t -# endif -# define YYSTACK_ALLOC malloc -# define YYSTACK_FREE free -# endif -#endif /* ! defined (yyoverflow) || YYERROR_VERBOSE */ - - -#if (! defined (yyoverflow) \ - && (! defined (__cplusplus) \ - || (YYSTYPE_IS_TRIVIAL))) - -/* A type that is properly aligned for any stack member. */ -union yyalloc -{ - short yyss; - YYSTYPE yyvs; - }; - -/* The size of the maximum gap between one aligned stack and the next. */ -# define YYSTACK_GAP_MAXIMUM (sizeof (union yyalloc) - 1) - -/* The size of an array large to enough to hold all stacks, each with - N elements. */ -# define YYSTACK_BYTES(N) \ - ((N) * (sizeof (short) + sizeof (YYSTYPE)) \ - + YYSTACK_GAP_MAXIMUM) - -/* Copy COUNT objects from FROM to TO. The source and destination do - not overlap. */ -# ifndef YYCOPY -# if 1 < __GNUC__ -# define YYCOPY(To, From, Count) \ - __builtin_memcpy (To, From, (Count) * sizeof (*(From))) -# else -# define YYCOPY(To, From, Count) \ - do \ - { \ - register YYSIZE_T yyi; \ - for (yyi = 0; yyi < (Count); yyi++) \ - (To)[yyi] = (From)[yyi]; \ - } \ - while (0) -# endif -# endif - -/* Relocate STACK from its old location to the new one. The - local variables YYSIZE and YYSTACKSIZE give the old and new number of - elements in the stack, and YYPTR gives the new location of the - stack. Advance YYPTR to a properly aligned location for the next - stack. */ -# define YYSTACK_RELOCATE(Stack) \ - do \ - { \ - YYSIZE_T yynewbytes; \ - YYCOPY (&yyptr->Stack, Stack, yysize); \ - Stack = &yyptr->Stack; \ - yynewbytes = yystacksize * sizeof (*Stack) + YYSTACK_GAP_MAXIMUM; \ - yyptr += yynewbytes / sizeof (*yyptr); \ - } \ - while (0) - -#endif - -#if defined (__STDC__) || defined (__cplusplus) - typedef signed char yysigned_char; -#else - typedef short yysigned_char; -#endif - -/* YYFINAL -- State number of the termination state. */ -#define YYFINAL 59 -/* YYLAST -- Last index in YYTABLE. */ -#define YYLAST 1231 - -/* YYNTOKENS -- Number of terminals. */ -#define YYNTOKENS 93 -/* YYNNTS -- Number of nonterminals. */ -#define YYNNTS 75 -/* YYNRULES -- Number of rules. */ -#define YYNRULES 214 -/* YYNRULES -- Number of states. */ -#define YYNSTATES 331 - -/* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX. */ -#define YYUNDEFTOK 2 -#define YYMAXUTOK 347 - -#define YYTRANSLATE(YYX) \ - ((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK) - -/* YYTRANSLATE[YYLEX] -- Bison symbol number corresponding to YYLEX. */ -static const unsigned char yytranslate[] = -{ - 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 1, 2, 3, 4, - 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, - 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, - 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, - 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, - 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, - 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, - 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, - 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, - 85, 86, 87, 88, 89, 90, 91, 92 -}; - -#if YYDEBUG -/* YYPRHS[YYN] -- Index of the first RHS symbol of rule number YYN in - YYRHS. */ -static const unsigned short yyprhs[] = -{ - 0, 0, 3, 5, 7, 9, 11, 13, 17, 19, - 24, 26, 30, 33, 36, 38, 40, 43, 46, 49, - 51, 54, 58, 61, 63, 65, 67, 69, 71, 73, - 75, 77, 79, 81, 83, 85, 87, 89, 91, 93, - 95, 97, 99, 102, 105, 108, 110, 112, 114, 116, - 118, 122, 126, 130, 132, 136, 140, 142, 146, 150, - 152, 156, 160, 164, 168, 170, 174, 178, 180, 184, - 186, 190, 192, 196, 198, 202, 204, 208, 210, 214, - 216, 222, 224, 228, 230, 232, 234, 236, 238, 240, - 242, 244, 246, 248, 250, 252, 256, 258, 261, 264, - 267, 269, 271, 274, 278, 282, 285, 291, 295, 298, - 302, 305, 306, 308, 310, 312, 314, 319, 321, 325, - 331, 338, 344, 346, 349, 354, 360, 365, 367, 370, - 372, 374, 376, 378, 380, 382, 384, 386, 388, 390, - 392, 394, 396, 398, 400, 402, 404, 406, 408, 410, - 412, 414, 416, 418, 420, 422, 424, 426, 432, 437, - 439, 442, 446, 448, 452, 454, 459, 461, 463, 465, - 467, 469, 471, 473, 475, 477, 480, 481, 482, 488, - 490, 492, 495, 499, 501, 504, 506, 509, 515, 519, - 521, 523, 528, 529, 536, 537, 546, 547, 555, 557, - 559, 561, 562, 565, 569, 572, 575, 578, 582, 585, - 587, 590, 592, 594, 595 -}; - -/* YYRHS -- A `-1'-separated list of the rules' RHS. */ -static const short yyrhs[] = -{ - 164, 0, -1, 42, -1, 94, -1, 45, -1, 44, - -1, 46, -1, 69, 121, 70, -1, 95, -1, 96, - 71, 97, 72, -1, 98, -1, 96, 75, 47, -1, - 96, 50, -1, 96, 51, -1, 121, -1, 99, -1, - 101, 70, -1, 100, 70, -1, 102, 34, -1, 102, - -1, 102, 119, -1, 101, 76, 119, -1, 103, 69, - -1, 104, -1, 42, -1, 6, -1, 7, -1, 5, - -1, 22, -1, 23, -1, 24, -1, 16, -1, 17, - -1, 18, -1, 19, -1, 20, -1, 21, -1, 25, - -1, 26, -1, 27, -1, 43, -1, 96, -1, 50, - 105, -1, 51, 105, -1, 106, 105, -1, 83, -1, - 81, -1, 80, -1, 82, -1, 105, -1, 107, 84, - 105, -1, 107, 85, 105, -1, 107, 86, 105, -1, - 107, -1, 108, 83, 107, -1, 108, 81, 107, -1, - 108, -1, 109, 48, 108, -1, 109, 49, 108, -1, - 109, -1, 110, 87, 109, -1, 110, 88, 109, -1, - 110, 52, 109, -1, 110, 53, 109, -1, 110, -1, - 111, 54, 110, -1, 111, 55, 110, -1, 111, -1, - 112, 91, 111, -1, 112, -1, 113, 90, 112, -1, - 113, -1, 114, 89, 113, -1, 114, -1, 115, 56, - 114, -1, 115, -1, 116, 58, 115, -1, 116, -1, - 117, 57, 116, -1, 117, -1, 117, 92, 121, 77, - 119, -1, 118, -1, 105, 120, 119, -1, 78, -1, - 59, -1, 60, -1, 62, -1, 61, -1, 68, -1, - 63, -1, 64, -1, 65, -1, 66, -1, 67, -1, - 119, -1, 121, 76, 119, -1, 118, -1, 124, 79, - -1, 132, 79, -1, 125, 70, -1, 127, -1, 126, - -1, 127, 129, -1, 126, 76, 129, -1, 134, 42, - 69, -1, 136, 42, -1, 136, 42, 71, 122, 72, - -1, 135, 130, 128, -1, 130, 128, -1, 135, 130, - 131, -1, 130, 131, -1, -1, 28, -1, 29, -1, - 30, -1, 136, -1, 136, 71, 122, 72, -1, 133, - -1, 132, 76, 42, -1, 132, 76, 42, 71, 72, - -1, 132, 76, 42, 71, 122, 72, -1, 132, 76, - 42, 78, 142, -1, 134, -1, 134, 42, -1, 134, - 42, 71, 72, -1, 134, 42, 71, 122, 72, -1, - 134, 42, 78, 142, -1, 136, -1, 135, 136, -1, - 4, -1, 3, -1, 32, -1, 31, -1, 34, -1, - 6, -1, 7, -1, 5, -1, 22, -1, 23, -1, - 24, -1, 16, -1, 17, -1, 18, -1, 19, -1, - 20, -1, 21, -1, 25, -1, 26, -1, 27, -1, - 36, -1, 37, -1, 38, -1, 39, -1, 40, -1, - 41, -1, 137, -1, 43, -1, 33, 42, 73, 138, - 74, -1, 33, 73, 138, 74, -1, 139, -1, 138, - 139, -1, 136, 140, 79, -1, 141, -1, 140, 76, - 141, -1, 42, -1, 42, 71, 122, 72, -1, 119, - -1, 123, -1, 146, -1, 145, -1, 143, -1, 152, - -1, 153, -1, 156, -1, 163, -1, 73, 74, -1, - -1, -1, 73, 147, 151, 148, 74, -1, 150, -1, - 145, -1, 73, 74, -1, 73, 151, 74, -1, 144, - -1, 151, 144, -1, 79, -1, 121, 79, -1, 13, - 69, 121, 70, 154, -1, 144, 11, 144, -1, 144, - -1, 121, -1, 134, 42, 78, 142, -1, -1, 35, - 69, 157, 155, 70, 149, -1, -1, 10, 158, 144, - 35, 69, 121, 70, 79, -1, -1, 12, 69, 159, - 160, 162, 70, 149, -1, 152, -1, 143, -1, 155, - -1, -1, 161, 79, -1, 161, 79, 121, -1, 9, - 79, -1, 8, 79, -1, 15, 79, -1, 15, 121, - 79, -1, 14, 79, -1, 165, -1, 164, 165, -1, - 166, -1, 123, -1, -1, 124, 167, 150, -1 -}; - -/* YYRLINE[YYN] -- source line where rule number YYN was defined. */ -static const unsigned short yyrline[] = -{ - 0, 210, 210, 245, 248, 261, 266, 271, 277, 280, - 348, 351, 460, 470, 483, 491, 586, 590, 597, 601, - 608, 614, 623, 629, 640, 656, 657, 658, 659, 660, - 661, 662, 663, 664, 665, 666, 667, 668, 669, 670, - 671, 682, 685, 695, 705, 727, 728, 729, 730, 736, - 737, 746, 755, 767, 768, 776, 787, 788, 797, 809, - 810, 820, 830, 840, 853, 854, 864, 877, 878, 890, - 891, 903, 904, 916, 917, 930, 931, 944, 945, 958, - 959, 976, 977, 990, 991, 992, 993, 994, 995, 996, - 997, 998, 999, 1000, 1004, 1007, 1018, 1026, 1027, 1035, - 1071, 1074, 1081, 1089, 1110, 1129, 1140, 1167, 1172, 1182, - 1187, 1197, 1200, 1203, 1206, 1212, 1217, 1235, 1238, 1246, - 1254, 1262, 1284, 1288, 1297, 1306, 1315, 1405, 1408, 1425, - 1429, 1436, 1444, 1453, 1458, 1463, 1468, 1479, 1484, 1489, - 1494, 1499, 1504, 1509, 1514, 1519, 1524, 1530, 1536, 1542, - 1548, 1554, 1560, 1566, 1572, 1578, 1583, 1596, 1606, 1614, - 1617, 1632, 1650, 1654, 1660, 1665, 1681, 1685, 1689, 1690, - 1696, 1697, 1698, 1699, 1700, 1704, 1705, 1705, 1705, 1713, - 1714, 1719, 1722, 1730, 1733, 1739, 1740, 1744, 1752, 1756, - 1766, 1771, 1788, 1788, 1793, 1793, 1800, 1800, 1813, 1816, - 1822, 1825, 1831, 1835, 1842, 1849, 1856, 1863, 1874, 1883, - 1887, 1894, 1897, 1903, 1903 -}; -#endif - -#if YYDEBUG || YYERROR_VERBOSE -/* YYTNME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM. - First, the terminals, then, starting at YYNTOKENS, nonterminals. */ -static const char *const yytname[] = -{ - "$end", "error", "$undefined", "ATTRIBUTE", "CONST_QUAL", "BOOL_TYPE", - "FLOAT_TYPE", "INT_TYPE", "BREAK", "CONTINUE", "DO", "ELSE", "FOR", - "IF", "DISCARD", "RETURN", "BVEC2", "BVEC3", "BVEC4", "IVEC2", "IVEC3", - "IVEC4", "VEC2", "VEC3", "VEC4", "MATRIX2", "MATRIX3", "MATRIX4", - "IN_QUAL", "OUT_QUAL", "INOUT_QUAL", "UNIFORM", "VARYING", "STRUCT", - "VOID_TYPE", "WHILE", "SAMPLER1D", "SAMPLER2D", "SAMPLER3D", - "SAMPLERCUBE", "SAMPLER1DSHADOW", "SAMPLER2DSHADOW", "IDENTIFIER", - "TYPE_NAME", "FLOATCONSTANT", "INTCONSTANT", "BOOLCONSTANT", - "FIELD_SELECTION", "LEFT_OP", "RIGHT_OP", "INC_OP", "DEC_OP", "LE_OP", - "GE_OP", "EQ_OP", "NE_OP", "AND_OP", "OR_OP", "XOR_OP", "MUL_ASSIGN", - "DIV_ASSIGN", "ADD_ASSIGN", "MOD_ASSIGN", "LEFT_ASSIGN", "RIGHT_ASSIGN", - "AND_ASSIGN", "XOR_ASSIGN", "OR_ASSIGN", "SUB_ASSIGN", "LEFT_PAREN", - "RIGHT_PAREN", "LEFT_BRACKET", "RIGHT_BRACKET", "LEFT_BRACE", - "RIGHT_BRACE", "DOT", "COMMA", "COLON", "EQUAL", "SEMICOLON", "BANG", - "DASH", "TILDE", "PLUS", "STAR", "SLASH", "PERCENT", "LEFT_ANGLE", - "RIGHT_ANGLE", "VERTICAL_BAR", "CARET", "AMPERSAND", "QUESTION", - "$accept", "variable_identifier", "primary_expression", - "postfix_expression", "integer_expression", "function_call", - "function_call_generic", "function_call_header_no_parameters", - "function_call_header_with_parameters", "function_call_header", - "function_identifier", "constructor_identifier", "unary_expression", - "unary_operator", "multiplicative_expression", "additive_expression", - "shift_expression", "relational_expression", "equality_expression", - "and_expression", "exclusive_or_expression", "inclusive_or_expression", - "logical_and_expression", "logical_xor_expression", - "logical_or_expression", "conditional_expression", - "assignment_expression", "assignment_operator", "expression", - "constant_expression", "declaration", "function_prototype", - "function_declarator", "function_header_with_parameters", - "function_header", "parameter_declarator", "parameter_declaration", - "parameter_qualifier", "parameter_type_specifier", - "init_declarator_list", "single_declaration", "fully_specified_type", - "type_qualifier", "type_specifier", "struct_specifier", - "struct_declaration_list", "struct_declaration", - "struct_declarator_list", "struct_declarator", "initializer", - "declaration_statement", "statement", "simple_statement", - "compound_statement", "@1", "@2", "statement_no_new_scope", - "compound_statement_no_new_scope", "statement_list", - "expression_statement", "selection_statement", - "selection_rest_statement", "condition", "iteration_statement", "@3", - "@4", "@5", "for_init_statement", "conditionopt", "for_rest_statement", - "jump_statement", "translation_unit", "external_declaration", - "function_definition", "@6", 0 -}; -#endif - -# ifdef YYPRINT -/* YYTOKNUM[YYLEX-NUM] -- Internal token number corresponding to - token YYLEX-NUM. */ -static const unsigned short yytoknum[] = -{ - 0, 256, 257, 258, 259, 260, 261, 262, 263, 264, - 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, - 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, - 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, - 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, - 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, - 315, 316, 317, 318, 319, 320, 321, 322, 323, 324, - 325, 326, 327, 328, 329, 330, 331, 332, 333, 334, - 335, 336, 337, 338, 339, 340, 341, 342, 343, 344, - 345, 346, 347 -}; -# endif - -/* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */ -static const unsigned char yyr1[] = -{ - 0, 93, 94, 95, 95, 95, 95, 95, 96, 96, - 96, 96, 96, 96, 97, 98, 99, 99, 100, 100, - 101, 101, 102, 103, 103, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 105, 105, 105, 105, 106, 106, 106, 106, 107, - 107, 107, 107, 108, 108, 108, 109, 109, 109, 110, - 110, 110, 110, 110, 111, 111, 111, 112, 112, 113, - 113, 114, 114, 115, 115, 116, 116, 117, 117, 118, - 118, 119, 119, 120, 120, 120, 120, 120, 120, 120, - 120, 120, 120, 120, 121, 121, 122, 123, 123, 124, - 125, 125, 126, 126, 127, 128, 128, 129, 129, 129, - 129, 130, 130, 130, 130, 131, 131, 132, 132, 132, - 132, 132, 133, 133, 133, 133, 133, 134, 134, 135, - 135, 135, 135, 136, 136, 136, 136, 136, 136, 136, - 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, - 136, 136, 136, 136, 136, 136, 136, 137, 137, 138, - 138, 139, 140, 140, 141, 141, 142, 143, 144, 144, - 145, 145, 145, 145, 145, 146, 147, 148, 146, 149, - 149, 150, 150, 151, 151, 152, 152, 153, 154, 154, - 155, 155, 157, 156, 158, 156, 159, 156, 160, 160, - 161, 161, 162, 162, 163, 163, 163, 163, 163, 164, - 164, 165, 165, 167, 166 -}; - -/* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN. */ -static const unsigned char yyr2[] = -{ - 0, 2, 1, 1, 1, 1, 1, 3, 1, 4, - 1, 3, 2, 2, 1, 1, 2, 2, 2, 1, - 2, 3, 2, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 2, 2, 2, 1, 1, 1, 1, 1, - 3, 3, 3, 1, 3, 3, 1, 3, 3, 1, - 3, 3, 3, 3, 1, 3, 3, 1, 3, 1, - 3, 1, 3, 1, 3, 1, 3, 1, 3, 1, - 5, 1, 3, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 3, 1, 2, 2, 2, - 1, 1, 2, 3, 3, 2, 5, 3, 2, 3, - 2, 0, 1, 1, 1, 1, 4, 1, 3, 5, - 6, 5, 1, 2, 4, 5, 4, 1, 2, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 5, 4, 1, - 2, 3, 1, 3, 1, 4, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 2, 0, 0, 5, 1, - 1, 2, 3, 1, 2, 1, 2, 5, 3, 1, - 1, 4, 0, 6, 0, 8, 0, 7, 1, 1, - 1, 0, 2, 3, 2, 2, 2, 3, 2, 1, - 2, 1, 1, 0, 3 -}; - -/* YYDEFACT[STATE-NAME] -- Default rule to reduce with in state - STATE-NUM when YYTABLE doesn't specify something else to do. Zero - means the default is an error. */ -static const unsigned char yydefact[] = -{ - 0, 130, 129, 136, 134, 135, 140, 141, 142, 143, - 144, 145, 137, 138, 139, 146, 147, 148, 132, 131, - 0, 133, 149, 150, 151, 152, 153, 154, 156, 212, - 213, 0, 101, 111, 0, 117, 122, 0, 127, 155, - 0, 209, 211, 0, 0, 97, 0, 99, 111, 112, - 113, 114, 102, 0, 111, 0, 98, 123, 128, 1, - 210, 0, 0, 0, 159, 0, 214, 103, 108, 110, - 115, 0, 118, 104, 0, 0, 0, 164, 0, 162, - 158, 160, 136, 134, 135, 0, 0, 194, 0, 0, - 0, 0, 140, 141, 142, 143, 144, 145, 137, 138, - 139, 146, 147, 148, 0, 2, 156, 5, 4, 6, - 0, 0, 0, 176, 181, 185, 47, 46, 48, 45, - 3, 8, 41, 10, 15, 0, 0, 19, 0, 23, - 49, 0, 53, 56, 59, 64, 67, 69, 71, 73, - 75, 77, 79, 81, 94, 0, 167, 0, 170, 183, - 169, 168, 0, 171, 172, 173, 174, 105, 0, 107, - 109, 0, 0, 27, 25, 26, 31, 32, 33, 34, - 35, 36, 28, 29, 30, 37, 38, 39, 40, 124, - 49, 96, 0, 166, 126, 157, 0, 0, 161, 205, - 204, 0, 196, 0, 208, 206, 0, 192, 42, 43, - 0, 175, 0, 12, 13, 0, 0, 17, 16, 0, - 18, 20, 22, 84, 85, 87, 86, 89, 90, 91, - 92, 93, 88, 83, 0, 44, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 186, 182, 184, - 0, 0, 119, 0, 121, 125, 0, 163, 0, 0, - 0, 207, 0, 7, 177, 0, 14, 11, 21, 82, - 50, 51, 52, 55, 54, 57, 58, 62, 63, 60, - 61, 65, 66, 68, 70, 72, 74, 76, 78, 0, - 95, 0, 116, 120, 165, 0, 199, 198, 201, 0, - 190, 0, 0, 0, 9, 0, 106, 0, 200, 0, - 0, 189, 187, 0, 0, 178, 80, 0, 202, 0, - 0, 0, 180, 193, 179, 0, 203, 197, 188, 191, - 195 -}; - -/* YYDEFGOTO[NTERM-NUM]. */ -static const short yydefgoto[] = -{ - -1, 120, 121, 122, 265, 123, 124, 125, 126, 127, - 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, - 138, 139, 140, 141, 142, 143, 144, 224, 145, 182, - 146, 147, 31, 32, 33, 68, 52, 53, 69, 34, - 35, 36, 37, 38, 39, 63, 64, 78, 79, 184, - 148, 149, 150, 151, 202, 303, 323, 324, 152, 153, - 154, 312, 302, 155, 262, 191, 259, 298, 309, 310, - 156, 40, 41, 42, 46 -}; - -/* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing - STATE-NUM. */ -#define YYPACT_NINF -297 -static const short yypact[] = -{ - 1149, -297, -297, -297, -297, -297, -297, -297, -297, -297, - -297, -297, -297, -297, -297, -297, -297, -297, -297, -297, - -27, -297, -297, -297, -297, -297, -297, -297, -297, -297, - -42, -28, -32, 4, 18, -297, 19, 1188, -297, -297, - 1108, -297, -297, -10, 1188, -297, -3, -297, 36, -297, - -297, -297, -297, 1188, 83, 33, -297, -9, -297, -297, - -297, 1188, 39, 1025, -297, 235, -297, -297, -297, -297, - -18, 1188, -52, -297, 685, 957, 1064, -17, 20, -297, - -297, -297, 29, 45, 63, 21, 23, -297, 75, 77, - 66, 753, 78, 79, 81, 82, 84, 85, 87, 89, - 90, 91, 93, 94, 95, 96, 97, -297, -297, -297, - 957, 957, 957, 120, -297, -297, -297, -297, -297, -297, - -297, -297, 5, -297, -297, 98, 1, 821, 100, -297, - 57, 957, 42, -56, 37, -40, 76, 61, 80, 106, - 111, 138, -41, -297, -297, 30, -297, -42, -297, -297, - -297, -297, 316, -297, -297, -297, -297, 127, 957, -297, - -297, 889, 957, -297, -297, -297, -297, -297, -297, -297, - -297, -297, -297, -297, -297, -297, -297, -297, -297, -297, - -297, -297, 128, -297, -297, -297, 957, 39, -297, -297, - -297, 397, -297, 957, -297, -297, 31, -297, -297, -297, - 3, -297, 397, -297, -297, 957, 152, -297, -297, 957, - -297, -297, -297, -297, -297, -297, -297, -297, -297, -297, - -297, -297, -297, -297, 957, -297, 957, 957, 957, 957, - 957, 957, 957, 957, 957, 957, 957, 957, 957, 957, - 957, 957, 957, 957, 957, 957, 957, -297, -297, -297, - 957, 129, -297, 130, -297, -297, 131, -297, 169, 549, - 12, -297, 617, -297, 397, 133, 134, -297, -297, -297, - -297, -297, -297, 42, 42, -56, -56, 37, 37, 37, - 37, -40, -40, 76, 61, 80, 106, 111, 138, 60, - -297, 135, -297, -297, -297, 137, -297, -297, 617, 397, - 134, 167, 141, 140, -297, 957, -297, 957, -297, 136, - 142, 205, -297, 143, 478, -297, -297, 13, 957, 478, - 397, 957, -297, -297, -297, 139, 134, -297, -297, -297, - -297 -}; - -/* YYPGOTO[NTERM-NUM]. */ -static const short yypgoto[] = -{ - -297, -297, -297, -297, -297, -297, -297, -297, -297, -297, - -297, -297, -53, -297, -91, -89, -143, -97, -20, -16, - -21, -15, -14, -22, -297, -57, -75, -297, -90, -155, - 9, 10, -297, -297, -297, 154, 175, 172, 160, -297, - -297, -257, -19, -33, -297, 171, -4, -297, 46, -160, - -25, -107, -296, -297, -297, -297, -84, 190, 35, 6, - -297, -297, -35, -297, -297, -297, -297, -297, -297, -297, - -297, -297, 224, -297, -297 -}; - -/* YYTABLE[YYPACT[STATE-NUM]]. What to do in state STATE-NUM. If - positive, shift that token. If negative, reduce the rule which - number is the opposite. If zero, do what YYDEFACT says. - If YYTABLE_NINF, syntax error. */ -#define YYTABLE_NINF -101 -static const short yytable[] = -{ - 183, 196, 254, 251, 58, 301, 253, 1, 2, 29, - 30, 62, 233, 234, 54, 43, 244, 181, 322, 161, - 70, 180, 200, 322, 157, 229, 162, 230, 62, 54, - 62, 256, 49, 50, 51, 18, 19, 45, 70, 1, - 2, 301, 47, 62, 48, 249, 44, 235, 236, 29, - 30, 245, 211, 158, 186, 203, 204, 198, 199, 81, - 73, 57, 74, 61, 49, 50, 51, 18, 19, 75, - 65, 208, 81, 263, -100, 72, 205, 209, 225, 246, - 206, 77, 299, 325, 258, 231, 232, 183, 246, 246, - 277, 278, 279, 280, 55, 291, 187, 56, -27, 188, - 189, 181, 190, 260, 181, 180, 246, 246, 180, 247, - 261, 49, 50, 51, -25, 266, 213, 214, 215, 216, - 217, 218, 219, 220, 221, 222, 226, 227, 228, 181, - 237, 238, -26, 180, 268, 223, 246, 305, 273, 274, - 281, 282, 275, 276, 192, 194, 193, -31, -32, 269, - -33, -34, 239, -35, -36, 289, -28, 249, -29, -30, - -37, 329, -38, -39, 197, -24, -40, 242, 207, 212, - 240, 290, 300, 270, 271, 272, 180, 180, 180, 180, - 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, - 180, 180, 311, 181, 201, 241, 243, 180, 250, 267, - 255, 292, 293, 294, 295, 304, 307, 306, 300, 313, - 246, 314, 319, 328, 315, 318, 320, 317, 330, 283, - 285, 321, 288, 67, 284, 159, 71, 286, 326, 287, - 316, 160, 76, 257, 296, 327, 66, 264, 1, 2, - 82, 83, 84, 85, 86, 87, 183, 88, 89, 90, - 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, - 101, 102, 103, 308, 60, 297, 18, 19, 20, 21, - 104, 22, 23, 24, 25, 26, 27, 105, 106, 107, - 108, 109, 0, 0, 0, 110, 111, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 112, 0, 0, 0, 113, 114, - 0, 0, 0, 0, 115, 116, 117, 118, 119, 1, - 2, 82, 83, 84, 85, 86, 87, 0, 88, 89, - 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, - 100, 101, 102, 103, 0, 0, 0, 18, 19, 20, - 21, 104, 22, 23, 24, 25, 26, 27, 105, 106, - 107, 108, 109, 0, 0, 0, 110, 111, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 112, 0, 0, 0, 113, - 248, 0, 0, 0, 0, 115, 116, 117, 118, 119, - 1, 2, 82, 83, 84, 85, 86, 87, 0, 88, - 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, - 99, 100, 101, 102, 103, 0, 0, 0, 18, 19, - 20, 21, 104, 22, 23, 24, 25, 26, 27, 105, - 106, 107, 108, 109, 0, 0, 0, 110, 111, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 112, 0, 0, 0, - 113, 0, 0, 0, 0, 0, 115, 116, 117, 118, - 119, 1, 2, 82, 83, 84, 85, 86, 87, 0, - 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, - 98, 99, 100, 101, 102, 103, 0, 0, 0, 18, - 19, 20, 21, 104, 22, 23, 24, 25, 26, 27, - 105, 106, 107, 108, 109, 0, 0, 0, 110, 111, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 112, 0, 0, - 0, 65, 1, 2, 82, 83, 84, 115, 116, 117, - 118, 119, 0, 0, 0, 92, 93, 94, 95, 96, - 97, 98, 99, 100, 101, 102, 103, 0, 0, 0, - 18, 19, 20, 21, 0, 22, 23, 24, 25, 26, - 27, 105, 106, 107, 108, 109, 0, 0, 0, 110, - 111, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 112, 0, - 1, 2, 82, 83, 84, 0, 0, 0, 115, 116, - 117, 118, 119, 92, 93, 94, 95, 96, 97, 98, - 99, 100, 101, 102, 103, 0, 0, 0, 18, 19, - 20, 21, 0, 22, 23, 24, 25, 26, 27, 105, - 106, 107, 108, 109, 0, 0, 0, 110, 111, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 112, 0, 0, 0, - 163, 164, 165, 0, 0, 0, 0, 116, 117, 118, - 119, 166, 167, 168, 169, 170, 171, 172, 173, 174, - 175, 176, 177, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 105, 178, 107, - 108, 109, 0, 0, 0, 110, 111, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 112, 0, 0, 179, 163, 164, - 165, 0, 0, 0, 0, 116, 117, 118, 119, 166, - 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, - 177, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 105, 178, 107, 108, 109, - 0, 0, 0, 110, 111, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 112, 0, 0, 0, 163, 164, 165, 0, - 0, 0, 195, 116, 117, 118, 119, 166, 167, 168, - 169, 170, 171, 172, 173, 174, 175, 176, 177, 0, - 0, 0, 0, 0, 0, 210, 0, 0, 0, 0, - 0, 0, 0, 105, 178, 107, 108, 109, 0, 0, - 0, 110, 111, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 112, 0, 0, 0, 163, 164, 165, 0, 0, 0, - 0, 116, 117, 118, 119, 166, 167, 168, 169, 170, - 171, 172, 173, 174, 175, 176, 177, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 105, 178, 107, 108, 109, 0, 0, 0, 110, - 111, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 112, 0, - 0, 252, 163, 164, 165, 0, 0, 0, 0, 116, - 117, 118, 119, 166, 167, 168, 169, 170, 171, 172, - 173, 174, 175, 176, 177, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 105, - 178, 107, 108, 109, 0, 0, 0, 110, 111, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 112, 0, 0, 0, - 3, 4, 5, 0, 0, 0, 0, 116, 117, 118, - 119, 6, 7, 8, 9, 10, 11, 12, 13, 14, - 15, 16, 17, 0, 0, 0, 0, 0, 20, 21, - 0, 22, 23, 24, 25, 26, 27, 0, 28, 3, - 4, 5, 0, 0, 0, 0, 0, 0, 0, 0, - 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, - 16, 17, 0, 0, 0, 0, 0, 20, 21, 80, - 22, 23, 24, 25, 26, 27, 0, 28, 59, 0, - 0, 1, 2, 3, 4, 5, 0, 0, 0, 0, - 0, 0, 0, 0, 6, 7, 8, 9, 10, 11, - 12, 13, 14, 15, 16, 17, 0, 0, 185, 18, - 19, 20, 21, 0, 22, 23, 24, 25, 26, 27, - 0, 28, 1, 2, 3, 4, 5, 0, 0, 0, - 0, 0, 0, 0, 0, 6, 7, 8, 9, 10, - 11, 12, 13, 14, 15, 16, 17, 0, 0, 0, - 18, 19, 20, 21, 0, 22, 23, 24, 25, 26, - 27, 0, 28, 3, 4, 5, 0, 0, 0, 0, - 0, 0, 0, 0, 6, 7, 8, 9, 10, 11, - 12, 13, 14, 15, 16, 17, 0, 0, 0, 0, - 0, 20, 21, 0, 22, 23, 24, 25, 26, 27, - 0, 28 -}; - -static const short yycheck[] = -{ - 75, 91, 162, 158, 37, 262, 161, 3, 4, 0, - 0, 44, 52, 53, 33, 42, 57, 74, 314, 71, - 53, 74, 112, 319, 42, 81, 78, 83, 61, 48, - 63, 186, 28, 29, 30, 31, 32, 79, 71, 3, - 4, 298, 70, 76, 76, 152, 73, 87, 88, 40, - 40, 92, 127, 71, 71, 50, 51, 110, 111, 63, - 69, 42, 71, 73, 28, 29, 30, 31, 32, 78, - 73, 70, 76, 70, 70, 42, 71, 76, 131, 76, - 75, 42, 70, 70, 191, 48, 49, 162, 76, 76, - 233, 234, 235, 236, 76, 250, 76, 79, 69, 79, - 79, 158, 79, 193, 161, 158, 76, 76, 161, 79, - 79, 28, 29, 30, 69, 205, 59, 60, 61, 62, - 63, 64, 65, 66, 67, 68, 84, 85, 86, 186, - 54, 55, 69, 186, 209, 78, 76, 77, 229, 230, - 237, 238, 231, 232, 69, 79, 69, 69, 69, 224, - 69, 69, 91, 69, 69, 245, 69, 264, 69, 69, - 69, 321, 69, 69, 69, 69, 69, 56, 70, 69, - 90, 246, 262, 226, 227, 228, 229, 230, 231, 232, - 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, - 243, 244, 299, 250, 74, 89, 58, 250, 71, 47, - 72, 72, 72, 72, 35, 72, 69, 72, 298, 42, - 76, 70, 70, 320, 74, 79, 11, 307, 79, 239, - 241, 78, 244, 48, 240, 71, 54, 242, 318, 243, - 305, 71, 61, 187, 259, 319, 46, 202, 3, 4, - 5, 6, 7, 8, 9, 10, 321, 12, 13, 14, - 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, - 25, 26, 27, 298, 40, 259, 31, 32, 33, 34, - 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, - 45, 46, -1, -1, -1, 50, 51, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, 69, -1, -1, -1, 73, 74, - -1, -1, -1, -1, 79, 80, 81, 82, 83, 3, - 4, 5, 6, 7, 8, 9, 10, -1, 12, 13, - 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, - 24, 25, 26, 27, -1, -1, -1, 31, 32, 33, - 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, - 44, 45, 46, -1, -1, -1, 50, 51, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, 69, -1, -1, -1, 73, - 74, -1, -1, -1, -1, 79, 80, 81, 82, 83, - 3, 4, 5, 6, 7, 8, 9, 10, -1, 12, - 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, - 23, 24, 25, 26, 27, -1, -1, -1, 31, 32, - 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, - 43, 44, 45, 46, -1, -1, -1, 50, 51, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, 69, -1, -1, -1, - 73, -1, -1, -1, -1, -1, 79, 80, 81, 82, - 83, 3, 4, 5, 6, 7, 8, 9, 10, -1, - 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, - 22, 23, 24, 25, 26, 27, -1, -1, -1, 31, - 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, - 42, 43, 44, 45, 46, -1, -1, -1, 50, 51, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, 69, -1, -1, - -1, 73, 3, 4, 5, 6, 7, 79, 80, 81, - 82, 83, -1, -1, -1, 16, 17, 18, 19, 20, - 21, 22, 23, 24, 25, 26, 27, -1, -1, -1, - 31, 32, 33, 34, -1, 36, 37, 38, 39, 40, - 41, 42, 43, 44, 45, 46, -1, -1, -1, 50, - 51, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, 69, -1, - 3, 4, 5, 6, 7, -1, -1, -1, 79, 80, - 81, 82, 83, 16, 17, 18, 19, 20, 21, 22, - 23, 24, 25, 26, 27, -1, -1, -1, 31, 32, - 33, 34, -1, 36, 37, 38, 39, 40, 41, 42, - 43, 44, 45, 46, -1, -1, -1, 50, 51, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, 69, -1, -1, -1, - 5, 6, 7, -1, -1, -1, -1, 80, 81, 82, - 83, 16, 17, 18, 19, 20, 21, 22, 23, 24, - 25, 26, 27, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, 42, 43, 44, - 45, 46, -1, -1, -1, 50, 51, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, 69, -1, -1, 72, 5, 6, - 7, -1, -1, -1, -1, 80, 81, 82, 83, 16, - 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, - 27, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, 42, 43, 44, 45, 46, - -1, -1, -1, 50, 51, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, 69, -1, -1, -1, 5, 6, 7, -1, - -1, -1, 79, 80, 81, 82, 83, 16, 17, 18, - 19, 20, 21, 22, 23, 24, 25, 26, 27, -1, - -1, -1, -1, -1, -1, 34, -1, -1, -1, -1, - -1, -1, -1, 42, 43, 44, 45, 46, -1, -1, - -1, 50, 51, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - 69, -1, -1, -1, 5, 6, 7, -1, -1, -1, - -1, 80, 81, 82, 83, 16, 17, 18, 19, 20, - 21, 22, 23, 24, 25, 26, 27, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, 42, 43, 44, 45, 46, -1, -1, -1, 50, - 51, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, 69, -1, - -1, 72, 5, 6, 7, -1, -1, -1, -1, 80, - 81, 82, 83, 16, 17, 18, 19, 20, 21, 22, - 23, 24, 25, 26, 27, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, 42, - 43, 44, 45, 46, -1, -1, -1, 50, 51, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, 69, -1, -1, -1, - 5, 6, 7, -1, -1, -1, -1, 80, 81, 82, - 83, 16, 17, 18, 19, 20, 21, 22, 23, 24, - 25, 26, 27, -1, -1, -1, -1, -1, 33, 34, - -1, 36, 37, 38, 39, 40, 41, -1, 43, 5, - 6, 7, -1, -1, -1, -1, -1, -1, -1, -1, - 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, - 26, 27, -1, -1, -1, -1, -1, 33, 34, 74, - 36, 37, 38, 39, 40, 41, -1, 43, 0, -1, - -1, 3, 4, 5, 6, 7, -1, -1, -1, -1, - -1, -1, -1, -1, 16, 17, 18, 19, 20, 21, - 22, 23, 24, 25, 26, 27, -1, -1, 74, 31, - 32, 33, 34, -1, 36, 37, 38, 39, 40, 41, - -1, 43, 3, 4, 5, 6, 7, -1, -1, -1, - -1, -1, -1, -1, -1, 16, 17, 18, 19, 20, - 21, 22, 23, 24, 25, 26, 27, -1, -1, -1, - 31, 32, 33, 34, -1, 36, 37, 38, 39, 40, - 41, -1, 43, 5, 6, 7, -1, -1, -1, -1, - -1, -1, -1, -1, 16, 17, 18, 19, 20, 21, - 22, 23, 24, 25, 26, 27, -1, -1, -1, -1, - -1, 33, 34, -1, 36, 37, 38, 39, 40, 41, - -1, 43 -}; - -/* YYSTOS[STATE-NUM] -- The (internal number of the) accessing - symbol of state STATE-NUM. */ -static const unsigned char yystos[] = -{ - 0, 3, 4, 5, 6, 7, 16, 17, 18, 19, - 20, 21, 22, 23, 24, 25, 26, 27, 31, 32, - 33, 34, 36, 37, 38, 39, 40, 41, 43, 123, - 124, 125, 126, 127, 132, 133, 134, 135, 136, 137, - 164, 165, 166, 42, 73, 79, 167, 70, 76, 28, - 29, 30, 129, 130, 135, 76, 79, 42, 136, 0, - 165, 73, 136, 138, 139, 73, 150, 129, 128, 131, - 136, 130, 42, 69, 71, 78, 138, 42, 140, 141, - 74, 139, 5, 6, 7, 8, 9, 10, 12, 13, - 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, - 24, 25, 26, 27, 35, 42, 43, 44, 45, 46, - 50, 51, 69, 73, 74, 79, 80, 81, 82, 83, - 94, 95, 96, 98, 99, 100, 101, 102, 103, 104, - 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, - 115, 116, 117, 118, 119, 121, 123, 124, 143, 144, - 145, 146, 151, 152, 153, 156, 163, 42, 71, 128, - 131, 71, 78, 5, 6, 7, 16, 17, 18, 19, - 20, 21, 22, 23, 24, 25, 26, 27, 43, 72, - 105, 118, 122, 119, 142, 74, 71, 76, 79, 79, - 79, 158, 69, 69, 79, 79, 121, 69, 105, 105, - 121, 74, 147, 50, 51, 71, 75, 70, 70, 76, - 34, 119, 69, 59, 60, 61, 62, 63, 64, 65, - 66, 67, 68, 78, 120, 105, 84, 85, 86, 81, - 83, 48, 49, 52, 53, 87, 88, 54, 55, 91, - 90, 89, 56, 58, 57, 92, 76, 79, 74, 144, - 71, 122, 72, 122, 142, 72, 122, 141, 144, 159, - 121, 79, 157, 70, 151, 97, 121, 47, 119, 119, - 105, 105, 105, 107, 107, 108, 108, 109, 109, 109, - 109, 110, 110, 111, 112, 113, 114, 115, 116, 121, - 119, 122, 72, 72, 72, 35, 143, 152, 160, 70, - 121, 134, 155, 148, 72, 77, 72, 69, 155, 161, - 162, 144, 154, 42, 70, 74, 119, 121, 79, 70, - 11, 78, 145, 149, 150, 70, 121, 149, 144, 142, - 79 -}; - -#if ! defined (YYSIZE_T) && defined (__SIZE_TYPE__) -# define YYSIZE_T __SIZE_TYPE__ -#endif -#if ! defined (YYSIZE_T) && defined (size_t) -# define YYSIZE_T size_t -#endif -#if ! defined (YYSIZE_T) -# if defined (__STDC__) || defined (__cplusplus) -# include <stddef.h> /* INFRINGES ON USER NAME SPACE */ -# define YYSIZE_T size_t -# endif -#endif -#if ! defined (YYSIZE_T) -# define YYSIZE_T unsigned int -#endif - -#define yyerrok (yyerrstatus = 0) -#define yyclearin (yychar = YYEMPTY) -#define YYEMPTY (-2) -#define YYEOF 0 - -#define YYACCEPT goto yyacceptlab -#define YYABORT goto yyabortlab -#define YYERROR goto yyerrlab1 - - -/* Like YYERROR except do call yyerror. This remains here temporarily - to ease the transition to the new meaning of YYERROR, for GCC. - Once GCC version 2 has supplanted version 1, this can go. */ - -#define YYFAIL goto yyerrlab - -#define YYRECOVERING() (!!yyerrstatus) - -#define YYBACKUP(Token, Value) \ -do \ - if (yychar == YYEMPTY && yylen == 1) \ - { \ - yychar = (Token); \ - yylval = (Value); \ - yytoken = YYTRANSLATE (yychar); \ - YYPOPSTACK; \ - goto yybackup; \ - } \ - else \ - { \ - yyerror ("syntax error: cannot back up");\ - YYERROR; \ - } \ -while (0) - -#define YYTERROR 1 -#define YYERRCODE 256 - -/* YYLLOC_DEFAULT -- Compute the default location (before the actions - are run). */ - -#ifndef YYLLOC_DEFAULT -# define YYLLOC_DEFAULT(Current, Rhs, N) \ - Current.first_line = Rhs[1].first_line; \ - Current.first_column = Rhs[1].first_column; \ - Current.last_line = Rhs[N].last_line; \ - Current.last_column = Rhs[N].last_column; -#endif - -/* YYLEX -- calling `yylex' with the right arguments. */ - -#ifdef YYLEX_PARAM -# define YYLEX yylex (&yylval, YYLEX_PARAM) -#else -# define YYLEX yylex (&yylval) -#endif - -/* Enable debugging if requested. */ -#if YYDEBUG - -# ifndef YYFPRINTF -# include <stdio.h> /* INFRINGES ON USER NAME SPACE */ -# define YYFPRINTF fprintf -# endif - -# define YYDPRINTF(Args) \ -do { \ - if (yydebug) \ - YYFPRINTF Args; \ -} while (0) - -# define YYDSYMPRINT(Args) \ -do { \ - if (yydebug) \ - yysymprint Args; \ -} while (0) - -# define YYDSYMPRINTF(Title, Token, Value, Location) \ -do { \ - if (yydebug) \ - { \ - YYFPRINTF (stderr, "%s ", Title); \ - yysymprint (stderr, \ - Token, Value); \ - YYFPRINTF (stderr, "\n"); \ - } \ -} while (0) - -/*------------------------------------------------------------------. -| yy_stack_print -- Print the state stack from its BOTTOM up to its | -| TOP (cinluded). | -`------------------------------------------------------------------*/ - -#if defined (__STDC__) || defined (__cplusplus) -static void -yy_stack_print (short *bottom, short *top) -#else -static void -yy_stack_print (bottom, top) - short *bottom; - short *top; -#endif -{ - YYFPRINTF (stderr, "Stack now"); - for (/* Nothing. */; bottom <= top; ++bottom) - YYFPRINTF (stderr, " %d", *bottom); - YYFPRINTF (stderr, "\n"); -} - -# define YY_STACK_PRINT(Bottom, Top) \ -do { \ - if (yydebug) \ - yy_stack_print ((Bottom), (Top)); \ -} while (0) - - -/*------------------------------------------------. -| Report that the YYRULE is going to be reduced. | -`------------------------------------------------*/ - -#if defined (__STDC__) || defined (__cplusplus) -static void -yy_reduce_print (int yyrule) -#else -static void -yy_reduce_print (yyrule) - int yyrule; -#endif -{ - int yyi; - unsigned int yylineno = yyrline[yyrule]; - YYFPRINTF (stderr, "Reducing stack by rule %d (line %u), ", - yyrule - 1, yylineno); - /* Print the symbols being reduced, and their result. */ - for (yyi = yyprhs[yyrule]; 0 <= yyrhs[yyi]; yyi++) - YYFPRINTF (stderr, "%s ", yytname [yyrhs[yyi]]); - YYFPRINTF (stderr, "-> %s\n", yytname [yyr1[yyrule]]); -} - -# define YY_REDUCE_PRINT(Rule) \ -do { \ - if (yydebug) \ - yy_reduce_print (Rule); \ -} while (0) - -/* Nonzero means print parse trace. It is left uninitialized so that - multiple parsers can coexist. */ -int yydebug; -#else /* !YYDEBUG */ -# define YYDPRINTF(Args) -# define YYDSYMPRINT(Args) -# define YYDSYMPRINTF(Title, Token, Value, Location) -# define YY_STACK_PRINT(Bottom, Top) -# define YY_REDUCE_PRINT(Rule) -#endif /* !YYDEBUG */ - - -/* YYINITDEPTH -- initial size of the parser's stacks. */ -#ifndef YYINITDEPTH -# define YYINITDEPTH 200 -#endif - -/* YYMAXDEPTH -- maximum size the stacks can grow to (effective only - if the built-in stack extension method is used). - - Do not make this value too large; the results are undefined if - SIZE_MAX < YYSTACK_BYTES (YYMAXDEPTH) - evaluated with infinite-precision integer arithmetic. */ - -#if YYMAXDEPTH == 0 -# undef YYMAXDEPTH -#endif - -#ifndef YYMAXDEPTH -# define YYMAXDEPTH 10000 -#endif - - - -#if YYERROR_VERBOSE - -# ifndef yystrlen -# if defined (__GLIBC__) && defined (_STRING_H) -# define yystrlen strlen -# else -/* Return the length of YYSTR. */ -static YYSIZE_T -# if defined (__STDC__) || defined (__cplusplus) -yystrlen (const char *yystr) -# else -yystrlen (yystr) - const char *yystr; -# endif -{ - register const char *yys = yystr; - - while (*yys++ != '\0') - continue; - - return yys - yystr - 1; -} -# endif -# endif - -# ifndef yystpcpy -# if defined (__GLIBC__) && defined (_STRING_H) && defined (_GNU_SOURCE) -# define yystpcpy stpcpy -# else -/* Copy YYSRC to YYDEST, returning the address of the terminating '\0' in - YYDEST. */ -static char * -# if defined (__STDC__) || defined (__cplusplus) -yystpcpy (char *yydest, const char *yysrc) -# else -yystpcpy (yydest, yysrc) - char *yydest; - const char *yysrc; -# endif -{ - register char *yyd = yydest; - register const char *yys = yysrc; - - while ((*yyd++ = *yys++) != '\0') - continue; - - return yyd - 1; -} -# endif -# endif - -#endif /* !YYERROR_VERBOSE */ - - - -#if YYDEBUG -/*--------------------------------. -| Print this symbol on YYOUTPUT. | -`--------------------------------*/ - -#if defined (__STDC__) || defined (__cplusplus) -static void -yysymprint (FILE *yyoutput, int yytype, YYSTYPE *yyvaluep) -#else -static void -yysymprint (yyoutput, yytype, yyvaluep) - FILE *yyoutput; - int yytype; - YYSTYPE *yyvaluep; -#endif -{ - /* Pacify ``unused variable'' warnings. */ - (void) yyvaluep; - - if (yytype < YYNTOKENS) - { - YYFPRINTF (yyoutput, "token %s (", yytname[yytype]); -# ifdef YYPRINT - YYPRINT (yyoutput, yytoknum[yytype], *yyvaluep); -# endif - } - else - YYFPRINTF (yyoutput, "nterm %s (", yytname[yytype]); - - switch (yytype) - { - default: - break; - } - YYFPRINTF (yyoutput, ")"); -} - -#endif /* ! YYDEBUG */ -/*-----------------------------------------------. -| Release the memory associated to this symbol. | -`-----------------------------------------------*/ - -#if defined (__STDC__) || defined (__cplusplus) -static void -yydestruct (int yytype, YYSTYPE *yyvaluep) -#else -static void -yydestruct (yytype, yyvaluep) - int yytype; - YYSTYPE *yyvaluep; -#endif -{ - /* Pacify ``unused variable'' warnings. */ - (void) yyvaluep; - - switch (yytype) - { - - default: - break; - } -} - - -/* Prevent warnings from -Wmissing-prototypes. */ - -#ifdef YYPARSE_PARAM -# if defined (__STDC__) || defined (__cplusplus) -int yyparse (void *YYPARSE_PARAM); -# else -int yyparse (); -# endif -#else /* ! YYPARSE_PARAM */ -#if defined (__STDC__) || defined (__cplusplus) -int yyparse (void); -#else -int yyparse (); -#endif -#endif /* ! YYPARSE_PARAM */ - - - - - - -/*----------. -| yyparse. | -`----------*/ - -#ifdef YYPARSE_PARAM -# if defined (__STDC__) || defined (__cplusplus) -int yyparse (void *YYPARSE_PARAM) -# else -int yyparse (YYPARSE_PARAM) - void *YYPARSE_PARAM; -# endif -#else /* ! YYPARSE_PARAM */ -#if defined (__STDC__) || defined (__cplusplus) -int -yyparse (void) -#else -int -yyparse () - -#endif -#endif -{ - /* The lookahead symbol. */ -int yychar; - -/* The semantic value of the lookahead symbol. */ -YYSTYPE yylval; - -/* Number of syntax errors so far. */ -int yynerrs; - - register int yystate; - register int yyn; - int yyresult; - /* Number of tokens to shift before error messages enabled. */ - int yyerrstatus; - /* Lookahead token as an internal (translated) token number. */ - int yytoken = 0; - - /* Three stacks and their tools: - `yyss': related to states, - `yyvs': related to semantic values, - `yyls': related to locations. - - Refer to the stacks thru separate pointers, to allow yyoverflow - to reallocate them elsewhere. */ - - /* The state stack. */ - short yyssa[YYINITDEPTH]; - short *yyss = yyssa; - register short *yyssp; - - /* The semantic value stack. */ - YYSTYPE yyvsa[YYINITDEPTH]; - YYSTYPE *yyvs = yyvsa; - register YYSTYPE *yyvsp; - - - -#define YYPOPSTACK (yyvsp--, yyssp--) - - YYSIZE_T yystacksize = YYINITDEPTH; - - /* The variables used to return semantic value and location from the - action routines. */ - YYSTYPE yyval; - - - /* When reducing, the number of symbols on the RHS of the reduced - rule. */ - int yylen; - - YYDPRINTF ((stderr, "Starting parse\n")); - - yystate = 0; - yyerrstatus = 0; - yynerrs = 0; - yychar = YYEMPTY; /* Cause a token to be read. */ - - /* Initialize stack pointers. - Waste one element of value and location stack - so that they stay on the same level as the state stack. - The wasted elements are never initialized. */ - - yyssp = yyss; - yyvsp = yyvs; - - goto yysetstate; - -/*------------------------------------------------------------. -| yynewstate -- Push a new state, which is found in yystate. | -`------------------------------------------------------------*/ - yynewstate: - /* In all cases, when you get here, the value and location stacks - have just been pushed. so pushing a state here evens the stacks. - */ - yyssp++; - - yysetstate: - *yyssp = yystate; - - if (yyss + yystacksize - 1 <= yyssp) - { - /* Get the current used size of the three stacks, in elements. */ - YYSIZE_T yysize = yyssp - yyss + 1; - -#ifdef yyoverflow - { - /* Give user a chance to reallocate the stack. Use copies of - these so that the &'s don't force the real ones into - memory. */ - YYSTYPE *yyvs1 = yyvs; - short *yyss1 = yyss; - - - /* Each stack pointer address is followed by the size of the - data in use in that stack, in bytes. This used to be a - conditional around just the two extra args, but that might - be undefined if yyoverflow is a macro. */ - yyoverflow ("parser stack overflow", - &yyss1, yysize * sizeof (*yyssp), - &yyvs1, yysize * sizeof (*yyvsp), - - &yystacksize); - - yyss = yyss1; - yyvs = yyvs1; - } -#else /* no yyoverflow */ -# ifndef YYSTACK_RELOCATE - goto yyoverflowlab; -# else - /* Extend the stack our own way. */ - if (YYMAXDEPTH <= yystacksize) - goto yyoverflowlab; - yystacksize *= 2; - if (YYMAXDEPTH < yystacksize) - yystacksize = YYMAXDEPTH; - - { - short *yyss1 = yyss; - union yyalloc *yyptr = - (union yyalloc *) YYSTACK_ALLOC (YYSTACK_BYTES (yystacksize)); - if (! yyptr) - goto yyoverflowlab; - YYSTACK_RELOCATE (yyss); - YYSTACK_RELOCATE (yyvs); - -# undef YYSTACK_RELOCATE - if (yyss1 != yyssa) - YYSTACK_FREE (yyss1); - } -# endif -#endif /* no yyoverflow */ - - yyssp = yyss + yysize - 1; - yyvsp = yyvs + yysize - 1; - - - YYDPRINTF ((stderr, "Stack size increased to %lu\n", - (unsigned long int) yystacksize)); - - if (yyss + yystacksize - 1 <= yyssp) - YYABORT; - } - - YYDPRINTF ((stderr, "Entering state %d\n", yystate)); - - goto yybackup; - -/*-----------. -| yybackup. | -`-----------*/ -yybackup: - -/* Do appropriate processing given the current state. */ -/* Read a lookahead token if we need one and don't already have one. */ -/* yyresume: */ - - /* First try to decide what to do without reference to lookahead token. */ - - yyn = yypact[yystate]; - if (yyn == YYPACT_NINF) - goto yydefault; - - /* Not known => get a lookahead token if don't already have one. */ - - /* YYCHAR is either YYEMPTY or YYEOF or a valid lookahead symbol. */ - if (yychar == YYEMPTY) - { - YYDPRINTF ((stderr, "Reading a token: ")); - yychar = YYLEX; - } - - if (yychar <= YYEOF) - { - yychar = yytoken = YYEOF; - YYDPRINTF ((stderr, "Now at end of input.\n")); - } - else - { - yytoken = YYTRANSLATE (yychar); - YYDSYMPRINTF ("Next token is", yytoken, &yylval, &yylloc); - } - - /* If the proper action on seeing token YYTOKEN is to reduce or to - detect an error, take that action. */ - yyn += yytoken; - if (yyn < 0 || YYLAST < yyn || yycheck[yyn] != yytoken) - goto yydefault; - yyn = yytable[yyn]; - if (yyn <= 0) - { - if (yyn == 0 || yyn == YYTABLE_NINF) - goto yyerrlab; - yyn = -yyn; - goto yyreduce; - } - - if (yyn == YYFINAL) - YYACCEPT; - - /* Shift the lookahead token. */ - YYDPRINTF ((stderr, "Shifting token %s, ", yytname[yytoken])); - - /* Discard the token being shifted unless it is eof. */ - if (yychar != YYEOF) - yychar = YYEMPTY; - - *++yyvsp = yylval; - - - /* Count tokens shifted since error; after three, turn off error - status. */ - if (yyerrstatus) - yyerrstatus--; - - yystate = yyn; - goto yynewstate; - - -/*-----------------------------------------------------------. -| yydefault -- do the default action for the current state. | -`-----------------------------------------------------------*/ -yydefault: - yyn = yydefact[yystate]; - if (yyn == 0) - goto yyerrlab; - goto yyreduce; - - -/*-----------------------------. -| yyreduce -- Do a reduction. | -`-----------------------------*/ -yyreduce: - /* yyn is the number of a rule to reduce with. */ - yylen = yyr2[yyn]; - - /* If YYLEN is nonzero, implement the default value of the action: - `$$ = $1'. - - Otherwise, the following line sets YYVAL to garbage. - This behavior is undocumented and Bison - users should not rely upon it. Assigning to YYVAL - unconditionally makes the parser a bit smaller, and it avoids a - GCC warning that YYVAL may be used uninitialized. */ - yyval = yyvsp[1-yylen]; - - - YY_REDUCE_PRINT (yyn); - switch (yyn) - { - case 2: -#line 210 "glslang.y" - { - // The symbol table search was done in the lexical phase - const TSymbol* symbol = yyvsp[0].lex.symbol; - const TVariable* variable; - if (symbol == 0) { - parseContext.error(yyvsp[0].lex.line, "undeclared identifier", yyvsp[0].lex.string->c_str(), ""); - parseContext.recover(); - TType type(EbtFloat); - TVariable* fakeVariable = new TVariable(yyvsp[0].lex.string, type); - parseContext.symbolTable.insert(*fakeVariable); - variable = fakeVariable; - } else { - // This identifier can only be a variable type symbol - if (! symbol->isVariable()) { - parseContext.error(yyvsp[0].lex.line, "variable expected", yyvsp[0].lex.string->c_str(), ""); - parseContext.recover(); - } - variable = static_cast<const TVariable*>(symbol); - } - - // don't delete $1.string, it's used by error recovery, and the pool - // pop will reclaim the memory - - if (variable->getType().getQualifier() == EvqConst ) { - constUnion* constArray = variable->getConstPointer(); - TType t(variable->getType()); - yyval.interm.intermTypedNode = parseContext.intermediate.addConstantUnion(constArray, t, yyvsp[0].lex.line); - } else - yyval.interm.intermTypedNode = parseContext.intermediate.addSymbol(variable->getUniqueId(), - variable->getName(), - variable->getType(), yyvsp[0].lex.line); - ;} - break; - - case 3: -#line 245 "glslang.y" - { - yyval.interm.intermTypedNode = yyvsp[0].interm.intermTypedNode; - ;} - break; - - case 4: -#line 248 "glslang.y" - { - // - // INT_TYPE is only 16-bit plus sign bit for vertex/fragment shaders, - // check for overflow for constants - // - if (abs(yyvsp[0].lex.i) >= (1 << 16)) { - parseContext.error(yyvsp[0].lex.line, " integer constant overflow", "", ""); - parseContext.recover(); - } - constUnion *unionArray = new constUnion[1]; - unionArray->iConst = yyvsp[0].lex.i; - yyval.interm.intermTypedNode = parseContext.intermediate.addConstantUnion(unionArray, TType(EbtInt, EvqConst), yyvsp[0].lex.line); - ;} - break; - - case 5: -#line 261 "glslang.y" - { - constUnion *unionArray = new constUnion[1]; - unionArray->fConst = yyvsp[0].lex.f; - yyval.interm.intermTypedNode = parseContext.intermediate.addConstantUnion(unionArray, TType(EbtFloat, EvqConst), yyvsp[0].lex.line); - ;} - break; - - case 6: -#line 266 "glslang.y" - { - constUnion *unionArray = new constUnion[1]; - unionArray->bConst = yyvsp[0].lex.b; - yyval.interm.intermTypedNode = parseContext.intermediate.addConstantUnion(unionArray, TType(EbtBool, EvqConst), yyvsp[0].lex.line); - ;} - break; - - case 7: -#line 271 "glslang.y" - { - yyval.interm.intermTypedNode = yyvsp[-1].interm.intermTypedNode; - ;} - break; - - case 8: -#line 277 "glslang.y" - { - yyval.interm.intermTypedNode = yyvsp[0].interm.intermTypedNode; - ;} - break; - - case 9: -#line 280 "glslang.y" - { - if (!yyvsp[-3].interm.intermTypedNode->isArray() && !yyvsp[-3].interm.intermTypedNode->isMatrix() && !yyvsp[-3].interm.intermTypedNode->isVector()) { - if (yyvsp[-3].interm.intermTypedNode->getAsSymbolNode()) - parseContext.error(yyvsp[-2].lex.line, " left of '[' is not of type array, matrix, or vector ", yyvsp[-3].interm.intermTypedNode->getAsSymbolNode()->getSymbol().c_str(), ""); - else - parseContext.error(yyvsp[-2].lex.line, " left of '[' is not of type array, matrix, or vector ", "expression", ""); - parseContext.recover(); - } - if (yyvsp[-3].interm.intermTypedNode->getType().getQualifier() == EvqConst && !yyvsp[-3].interm.intermTypedNode->isArray() && yyvsp[-1].interm.intermTypedNode->getQualifier() == EvqConst) { - if (yyvsp[-3].interm.intermTypedNode->isVector()) { // constant folding for vectors - TVectorFields fields; - fields.num = 1; - fields.offsets[0] = yyvsp[-1].interm.intermTypedNode->getAsConstantUnion()->getUnionArrayPointer()->iConst; // need to do it this way because v.xy sends fields integer array - yyval.interm.intermTypedNode = parseContext.addConstVectorNode(fields, yyvsp[-3].interm.intermTypedNode, yyvsp[-2].lex.line); - } else if (yyvsp[-3].interm.intermTypedNode->isMatrix()) { // constant folding for matrices - yyval.interm.intermTypedNode = parseContext.addConstMatrixNode(yyvsp[-1].interm.intermTypedNode->getAsConstantUnion()->getUnionArrayPointer()->iConst, yyvsp[-3].interm.intermTypedNode, yyvsp[-2].lex.line); - } - } else { - if (yyvsp[-1].interm.intermTypedNode->getQualifier() == EvqConst) { - if ((yyvsp[-3].interm.intermTypedNode->isVector() || yyvsp[-3].interm.intermTypedNode->isMatrix()) && yyvsp[-3].interm.intermTypedNode->getType().getNominalSize() <= yyvsp[-1].interm.intermTypedNode->getAsConstantUnion()->getUnionArrayPointer()->iConst && !yyvsp[-3].interm.intermTypedNode->isArray() ) { - parseContext.error(yyvsp[-2].lex.line, "", "[", "field selection out of range '%d'", yyvsp[-1].interm.intermTypedNode->getAsConstantUnion()->getUnionArrayPointer()->iConst); - parseContext.recover(); - } else { - if (yyvsp[-3].interm.intermTypedNode->isArray()) { - if (yyvsp[-3].interm.intermTypedNode->getType().getArraySize() == 0) { - if (yyvsp[-3].interm.intermTypedNode->getType().getMaxArraySize() <= yyvsp[-1].interm.intermTypedNode->getAsConstantUnion()->getUnionArrayPointer()->iConst) { - if (parseContext.arraySetMaxSize(yyvsp[-3].interm.intermTypedNode->getAsSymbolNode(), yyvsp[-3].interm.intermTypedNode->getTypePointer(), yyvsp[-1].interm.intermTypedNode->getAsConstantUnion()->getUnionArrayPointer()->iConst, true, yyvsp[-2].lex.line)) - parseContext.recover(); - } else { - if (parseContext.arraySetMaxSize(yyvsp[-3].interm.intermTypedNode->getAsSymbolNode(), yyvsp[-3].interm.intermTypedNode->getTypePointer(), 0, false, yyvsp[-2].lex.line)) - parseContext.recover(); - } - } else if ( yyvsp[-1].interm.intermTypedNode->getAsConstantUnion()->getUnionArrayPointer()->iConst >= yyvsp[-3].interm.intermTypedNode->getType().getArraySize()) { - parseContext.error(yyvsp[-2].lex.line, "", "[", "array index out of range '%d'", yyvsp[-1].interm.intermTypedNode->getAsConstantUnion()->getUnionArrayPointer()->iConst); - parseContext.recover(); - } - } - yyval.interm.intermTypedNode = parseContext.intermediate.addIndex(EOpIndexDirect, yyvsp[-3].interm.intermTypedNode, yyvsp[-1].interm.intermTypedNode, yyvsp[-2].lex.line); - } - } else { - if (yyvsp[-3].interm.intermTypedNode->isArray() && yyvsp[-3].interm.intermTypedNode->getType().getArraySize() == 0) { - parseContext.error(yyvsp[-2].lex.line, "", "[", "array must be redeclared with a size before being indexed with a variable"); - parseContext.recover(); - } - - yyval.interm.intermTypedNode = parseContext.intermediate.addIndex(EOpIndexIndirect, yyvsp[-3].interm.intermTypedNode, yyvsp[-1].interm.intermTypedNode, yyvsp[-2].lex.line); - } - } - if (yyval.interm.intermTypedNode == 0) { - constUnion *unionArray = new constUnion[1]; - unionArray->fConst = 0.0; - yyval.interm.intermTypedNode = parseContext.intermediate.addConstantUnion(unionArray, TType(EbtFloat, EvqConst), yyvsp[-2].lex.line); - } else if (yyvsp[-3].interm.intermTypedNode->isArray()) { - if (yyvsp[-3].interm.intermTypedNode->getType().getStruct()) - yyval.interm.intermTypedNode->setType(TType(yyvsp[-3].interm.intermTypedNode->getType().getStruct(), yyvsp[-3].interm.intermTypedNode->getType().getTypeName())); - else - yyval.interm.intermTypedNode->setType(TType(yyvsp[-3].interm.intermTypedNode->getBasicType(), EvqTemporary, yyvsp[-3].interm.intermTypedNode->getNominalSize(), yyvsp[-3].interm.intermTypedNode->isMatrix())); - } else if (yyvsp[-3].interm.intermTypedNode->isMatrix() && yyvsp[-3].interm.intermTypedNode->getType().getQualifier() == EvqConst) - yyval.interm.intermTypedNode->setType(TType(yyvsp[-3].interm.intermTypedNode->getBasicType(), EvqConst, yyvsp[-3].interm.intermTypedNode->getNominalSize())); - else if (yyvsp[-3].interm.intermTypedNode->isMatrix()) - yyval.interm.intermTypedNode->setType(TType(yyvsp[-3].interm.intermTypedNode->getBasicType(), EvqTemporary, yyvsp[-3].interm.intermTypedNode->getNominalSize())); - else if (yyvsp[-3].interm.intermTypedNode->isVector() && yyvsp[-3].interm.intermTypedNode->getType().getQualifier() == EvqConst) - yyval.interm.intermTypedNode->setType(TType(yyvsp[-3].interm.intermTypedNode->getBasicType(), EvqConst)); - else if (yyvsp[-3].interm.intermTypedNode->isVector()) - yyval.interm.intermTypedNode->setType(TType(yyvsp[-3].interm.intermTypedNode->getBasicType(), EvqTemporary)); - else - yyval.interm.intermTypedNode->setType(yyvsp[-3].interm.intermTypedNode->getType()); - ;} - break; - - case 10: -#line 348 "glslang.y" - { - yyval.interm.intermTypedNode = yyvsp[0].interm.intermTypedNode; - ;} - break; - - case 11: -#line 351 "glslang.y" - { - if (yyvsp[-2].interm.intermTypedNode->isArray()) { - parseContext.error(yyvsp[0].lex.line, "cannot apply dot operator to an array", ".", ""); - parseContext.recover(); - } - - if (yyvsp[-2].interm.intermTypedNode->isVector()) { - TVectorFields fields; - if (! parseContext.parseVectorFields(*yyvsp[0].lex.string, yyvsp[-2].interm.intermTypedNode->getNominalSize(), fields, yyvsp[0].lex.line)) { - fields.num = 1; - fields.offsets[0] = 0; - parseContext.recover(); - } - - if (yyvsp[-2].interm.intermTypedNode->getType().getQualifier() == EvqConst) { // constant folding for vector fields - yyval.interm.intermTypedNode = parseContext.addConstVectorNode(fields, yyvsp[-2].interm.intermTypedNode, yyvsp[0].lex.line); - if (yyval.interm.intermTypedNode == 0) { - parseContext.recover(); - yyval.interm.intermTypedNode = yyvsp[-2].interm.intermTypedNode; - } - else - yyval.interm.intermTypedNode->setType(TType(yyvsp[-2].interm.intermTypedNode->getBasicType(), EvqConst, (int) (*yyvsp[0].lex.string).size())); - } else { - if (fields.num == 1) { - constUnion *unionArray = new constUnion[1]; - unionArray->iConst = fields.offsets[0]; - TIntermTyped* index = parseContext.intermediate.addConstantUnion(unionArray, TType(EbtInt, EvqConst), yyvsp[0].lex.line); - yyval.interm.intermTypedNode = parseContext.intermediate.addIndex(EOpIndexDirect, yyvsp[-2].interm.intermTypedNode, index, yyvsp[-1].lex.line); - yyval.interm.intermTypedNode->setType(TType(yyvsp[-2].interm.intermTypedNode->getBasicType())); - } else { - TString vectorString = *yyvsp[0].lex.string; - TIntermTyped* index = parseContext.intermediate.addSwizzle(fields, yyvsp[0].lex.line); - yyval.interm.intermTypedNode = parseContext.intermediate.addIndex(EOpVectorSwizzle, yyvsp[-2].interm.intermTypedNode, index, yyvsp[-1].lex.line); - yyval.interm.intermTypedNode->setType(TType(yyvsp[-2].interm.intermTypedNode->getBasicType(),EvqTemporary, (int) vectorString.size())); - } - } - } else if (yyvsp[-2].interm.intermTypedNode->isMatrix()) { - TMatrixFields fields; - if (! parseContext.parseMatrixFields(*yyvsp[0].lex.string, yyvsp[-2].interm.intermTypedNode->getNominalSize(), fields, yyvsp[0].lex.line)) { - fields.wholeRow = false; - fields.wholeCol = false; - fields.row = 0; - fields.col = 0; - parseContext.recover(); - } - - if (fields.wholeRow || fields.wholeCol) { - parseContext.error(yyvsp[-1].lex.line, " non-scalar fields not implemented yet", ".", ""); - parseContext.recover(); - constUnion *unionArray = new constUnion[1]; - unionArray->iConst = 0; - TIntermTyped* index = parseContext.intermediate.addConstantUnion(unionArray, TType(EbtInt, EvqConst), yyvsp[0].lex.line); - yyval.interm.intermTypedNode = parseContext.intermediate.addIndex(EOpIndexDirect, yyvsp[-2].interm.intermTypedNode, index, yyvsp[-1].lex.line); - yyval.interm.intermTypedNode->setType(TType(yyvsp[-2].interm.intermTypedNode->getBasicType(), EvqTemporary, yyvsp[-2].interm.intermTypedNode->getNominalSize())); - } else { - constUnion *unionArray = new constUnion[1]; - unionArray->iConst = fields.col * yyvsp[-2].interm.intermTypedNode->getNominalSize() + fields.row; - TIntermTyped* index = parseContext.intermediate.addConstantUnion(unionArray, TType(EbtInt, EvqConst), yyvsp[0].lex.line); - yyval.interm.intermTypedNode = parseContext.intermediate.addIndex(EOpIndexDirect, yyvsp[-2].interm.intermTypedNode, index, yyvsp[-1].lex.line); - yyval.interm.intermTypedNode->setType(TType(yyvsp[-2].interm.intermTypedNode->getBasicType())); - } - } else if (yyvsp[-2].interm.intermTypedNode->getBasicType() == EbtStruct) { - bool fieldFound = false; - TTypeList* fields = yyvsp[-2].interm.intermTypedNode->getType().getStruct(); - if (fields == 0) { - parseContext.error(yyvsp[-1].lex.line, "structure has no fields", "Internal Error", ""); - parseContext.recover(); - yyval.interm.intermTypedNode = yyvsp[-2].interm.intermTypedNode; - } else { - unsigned int i; - for (i = 0; i < fields->size(); ++i) { - if ((*fields)[i].type->getFieldName() == *yyvsp[0].lex.string) { - fieldFound = true; - break; - } - } - if (fieldFound) { - if (yyvsp[-2].interm.intermTypedNode->getType().getQualifier() == EvqConst) { - yyval.interm.intermTypedNode = parseContext.addConstStruct(*yyvsp[0].lex.string, yyvsp[-2].interm.intermTypedNode, yyvsp[-1].lex.line); - if (yyval.interm.intermTypedNode == 0) { - parseContext.recover(); - yyval.interm.intermTypedNode = yyvsp[-2].interm.intermTypedNode; - } - else { - yyval.interm.intermTypedNode->setType(*(*fields)[i].type); - // change the qualifier of the return type, not of the structure field - // as the structure definition is shared between various structures. - yyval.interm.intermTypedNode->getTypePointer()->changeQualifier(EvqConst); - } - } else { - constUnion *unionArray = new constUnion[1]; - unionArray->iConst = i; - TIntermTyped* index = parseContext.intermediate.addConstantUnion(unionArray, TType(EbtInt, EvqConst), yyvsp[0].lex.line); - yyval.interm.intermTypedNode = parseContext.intermediate.addIndex(EOpIndexDirectStruct, yyvsp[-2].interm.intermTypedNode, index, yyvsp[-1].lex.line); - yyval.interm.intermTypedNode->setType(*(*fields)[i].type); - } - } else { - parseContext.error(yyvsp[-1].lex.line, " no such field in structure", yyvsp[0].lex.string->c_str(), ""); - parseContext.recover(); - yyval.interm.intermTypedNode = yyvsp[-2].interm.intermTypedNode; - } - } - } else { - parseContext.error(yyvsp[-1].lex.line, " field selection requires structure, vector, or matrix on left hand side", yyvsp[0].lex.string->c_str(), ""); - parseContext.recover(); - yyval.interm.intermTypedNode = yyvsp[-2].interm.intermTypedNode; - } - // don't delete $3.string, it's from the pool - ;} - break; - - case 12: -#line 460 "glslang.y" - { - if (parseContext.lValueErrorCheck(yyvsp[0].lex.line, "++", yyvsp[-1].interm.intermTypedNode)) - parseContext.recover(); - yyval.interm.intermTypedNode = parseContext.intermediate.addUnaryMath(EOpPostIncrement, yyvsp[-1].interm.intermTypedNode, yyvsp[0].lex.line, parseContext.symbolTable); - if (yyval.interm.intermTypedNode == 0) { - parseContext.unaryOpError(yyvsp[0].lex.line, "++", yyvsp[-1].interm.intermTypedNode->getCompleteString()); - parseContext.recover(); - yyval.interm.intermTypedNode = yyvsp[-1].interm.intermTypedNode; - } - ;} - break; - - case 13: -#line 470 "glslang.y" - { - if (parseContext.lValueErrorCheck(yyvsp[0].lex.line, "--", yyvsp[-1].interm.intermTypedNode)) - parseContext.recover(); - yyval.interm.intermTypedNode = parseContext.intermediate.addUnaryMath(EOpPostDecrement, yyvsp[-1].interm.intermTypedNode, yyvsp[0].lex.line, parseContext.symbolTable); - if (yyval.interm.intermTypedNode == 0) { - parseContext.unaryOpError(yyvsp[0].lex.line, "--", yyvsp[-1].interm.intermTypedNode->getCompleteString()); - parseContext.recover(); - yyval.interm.intermTypedNode = yyvsp[-1].interm.intermTypedNode; - } - ;} - break; - - case 14: -#line 483 "glslang.y" - { - if (parseContext.integerErrorCheck(yyvsp[0].interm.intermTypedNode, "[]")) - parseContext.recover(); - yyval.interm.intermTypedNode = yyvsp[0].interm.intermTypedNode; - ;} - break; - - case 15: -#line 491 "glslang.y" - { - TFunction* fnCall = yyvsp[0].interm.function; - TOperator op = fnCall->getBuiltInOp(); - - if (op != EOpNull) { - // - // Then this should be a constructor. - // - TType type(EbtVoid); // use this to get the type back - if (parseContext.constructorErrorCheck(yyvsp[0].interm.line, yyvsp[0].interm.intermNode, *fnCall, op, &type)) { - yyval.interm.intermTypedNode = 0; - } else { - // - // It's a constructor, of type 'type'. - // - yyval.interm.intermTypedNode = parseContext.addConstructor(yyvsp[0].interm.intermNode, &type, op, fnCall, yyvsp[0].interm.line); - } - - if (yyval.interm.intermTypedNode == 0) { - parseContext.recover(); - yyval.interm.intermTypedNode = parseContext.intermediate.setAggregateOperator(0, op, yyvsp[0].interm.line); - } - yyval.interm.intermTypedNode->setType(type); - } else { - // - // Not a constructor. Find it in the symbol table. - // - const TFunction* fnCandidate; - bool builtIn; - fnCandidate = parseContext.findFunction(yyvsp[0].interm.line, fnCall, &builtIn); - if (fnCandidate) { - // - // A declared function. But, it might still map to a built-in - // operation. - // - op = fnCandidate->getBuiltInOp(); - if (builtIn && op != EOpNull) { - // - // A function call mapped to a built-in operation. - // - if (fnCandidate->getParamCount() == 1) { - // - // Treat it like a built-in unary operator. - // - yyval.interm.intermTypedNode = parseContext.intermediate.addUnaryMath(op, yyvsp[0].interm.intermNode, 0, parseContext.symbolTable); - if (yyval.interm.intermTypedNode == 0) { - parseContext.error(yyvsp[0].interm.intermNode->getLine(), " wrong operand type", "Internal Error", - "built in unary operator function. Type: %s", - static_cast<TIntermTyped*>(yyvsp[0].interm.intermNode)->getCompleteString().c_str()); - YYERROR; - } - } else { - yyval.interm.intermTypedNode = parseContext.intermediate.setAggregateOperator(yyvsp[0].interm.intermAggregate, op, yyvsp[0].interm.line); - } - } else { - // This is a real function call - - yyval.interm.intermTypedNode = parseContext.intermediate.setAggregateOperator(yyvsp[0].interm.intermAggregate, EOpFunctionCall, yyvsp[0].interm.line); - yyval.interm.intermTypedNode->setType(fnCandidate->getReturnType()); - - // this is how we know whether the given function is a builtIn function or a user defined function - // if builtIn == false, it's a userDefined -> could be an overloaded builtIn function also - // if builtIn == true, it's definitely a builtIn function with EOpNull - if (!builtIn) - yyval.interm.intermTypedNode->getAsAggregate()->setUserDefined(); - yyval.interm.intermTypedNode->getAsAggregate()->setName(fnCandidate->getMangledName()); - - TQualifier qual; - TQualifierList& qualifierList = yyval.interm.intermTypedNode->getAsAggregate()->getQualifier(); - for (int i = 0; i < fnCandidate->getParamCount(); ++i) { - qual = (*fnCandidate)[i].type->getQualifier(); - if (qual == EvqOut || qual == EvqInOut) { - if (parseContext.lValueErrorCheck(yyval.interm.intermTypedNode->getLine(), "assign", yyval.interm.intermTypedNode->getAsAggregate()->getSequence()[i]->getAsTyped())) { - parseContext.error(yyvsp[0].interm.intermNode->getLine(), "Constant value cannot be passed for 'out' or 'inout' parameters.", "Error", ""); - parseContext.recover(); - } - } - qualifierList.push_back(qual); - } - } - yyval.interm.intermTypedNode->setType(fnCandidate->getReturnType()); - } else { - // error message was put out by PaFindFunction() - // Put on a dummy node for error recovery - constUnion *unionArray = new constUnion[1]; - unionArray->fConst = 0.0; - yyval.interm.intermTypedNode = parseContext.intermediate.addConstantUnion(unionArray, TType(EbtFloat, EvqConst), yyvsp[0].interm.line); - parseContext.recover(); - } - } - delete fnCall; - ;} - break; - - case 16: -#line 586 "glslang.y" - { - yyval.interm = yyvsp[-1].interm; - yyval.interm.line = yyvsp[0].lex.line; - ;} - break; - - case 17: -#line 590 "glslang.y" - { - yyval.interm = yyvsp[-1].interm; - yyval.interm.line = yyvsp[0].lex.line; - ;} - break; - - case 18: -#line 597 "glslang.y" - { - yyval.interm.function = yyvsp[-1].interm.function; - yyval.interm.intermNode = 0; - ;} - break; - - case 19: -#line 601 "glslang.y" - { - yyval.interm.function = yyvsp[0].interm.function; - yyval.interm.intermNode = 0; - ;} - break; - - case 20: -#line 608 "glslang.y" - { - TParameter param = { 0, new TType(yyvsp[0].interm.intermTypedNode->getType()) }; - yyvsp[-1].interm.function->addParameter(param); - yyval.interm.function = yyvsp[-1].interm.function; - yyval.interm.intermNode = yyvsp[0].interm.intermTypedNode; - ;} - break; - - case 21: -#line 614 "glslang.y" - { - TParameter param = { 0, new TType(yyvsp[0].interm.intermTypedNode->getType()) }; - yyvsp[-2].interm.function->addParameter(param); - yyval.interm.function = yyvsp[-2].interm.function; - yyval.interm.intermNode = parseContext.intermediate.growAggregate(yyvsp[-2].interm.intermNode, yyvsp[0].interm.intermTypedNode, yyvsp[-1].lex.line); - ;} - break; - - case 22: -#line 623 "glslang.y" - { - yyval.interm.function = yyvsp[-1].interm.function; - ;} - break; - - case 23: -#line 629 "glslang.y" - { - if (yyvsp[0].interm.op == EOpConstructStruct) { - TString tempString = ""; - TFunction *function = new TFunction(&tempString, *(yyvsp[0].interm.type.userDef), yyvsp[0].interm.op); - yyval.interm.function = function; - } - else { - TFunction *function = new TFunction(yyvsp[0].interm.op); - yyval.interm.function = function; - } - ;} - break; - - case 24: -#line 640 "glslang.y" - { - if (parseContext.reservedErrorCheck(yyvsp[0].lex.line, *yyvsp[0].lex.string)) - parseContext.recover(); - TType type(EbtVoid); - TFunction *function = new TFunction(yyvsp[0].lex.string, type); - yyval.interm.function = function; - ;} - break; - - case 25: -#line 656 "glslang.y" - { yyval.interm.line = yyvsp[0].lex.line; yyval.interm.op = EOpConstructFloat; ;} - break; - - case 26: -#line 657 "glslang.y" - { yyval.interm.line = yyvsp[0].lex.line; yyval.interm.op = EOpConstructInt; ;} - break; - - case 27: -#line 658 "glslang.y" - { yyval.interm.line = yyvsp[0].lex.line; yyval.interm.op = EOpConstructBool; ;} - break; - - case 28: -#line 659 "glslang.y" - { yyval.interm.line = yyvsp[0].lex.line; yyval.interm.op = EOpConstructVec2; ;} - break; - - case 29: -#line 660 "glslang.y" - { yyval.interm.line = yyvsp[0].lex.line; yyval.interm.op = EOpConstructVec3; ;} - break; - - case 30: -#line 661 "glslang.y" - { yyval.interm.line = yyvsp[0].lex.line; yyval.interm.op = EOpConstructVec4; ;} - break; - - case 31: -#line 662 "glslang.y" - { FRAG_VERT_ONLY("bvec2", yyvsp[0].lex.line); yyval.interm.line = yyvsp[0].lex.line; yyval.interm.op = EOpConstructBVec2; ;} - break; - - case 32: -#line 663 "glslang.y" - { FRAG_VERT_ONLY("bvec3", yyvsp[0].lex.line); yyval.interm.line = yyvsp[0].lex.line; yyval.interm.op = EOpConstructBVec3; ;} - break; - - case 33: -#line 664 "glslang.y" - { FRAG_VERT_ONLY("bvec4", yyvsp[0].lex.line); yyval.interm.line = yyvsp[0].lex.line; yyval.interm.op = EOpConstructBVec4; ;} - break; - - case 34: -#line 665 "glslang.y" - { FRAG_VERT_ONLY("ivec2", yyvsp[0].lex.line); yyval.interm.line = yyvsp[0].lex.line; yyval.interm.op = EOpConstructIVec2; ;} - break; - - case 35: -#line 666 "glslang.y" - { FRAG_VERT_ONLY("ivec3", yyvsp[0].lex.line); yyval.interm.line = yyvsp[0].lex.line; yyval.interm.op = EOpConstructIVec3; ;} - break; - - case 36: -#line 667 "glslang.y" - { FRAG_VERT_ONLY("ivec4", yyvsp[0].lex.line); yyval.interm.line = yyvsp[0].lex.line; yyval.interm.op = EOpConstructIVec4; ;} - break; - - case 37: -#line 668 "glslang.y" - { FRAG_VERT_ONLY("mat2", yyvsp[0].lex.line); yyval.interm.line = yyvsp[0].lex.line; yyval.interm.op = EOpConstructMat2; ;} - break; - - case 38: -#line 669 "glslang.y" - { FRAG_VERT_ONLY("mat3", yyvsp[0].lex.line); yyval.interm.line = yyvsp[0].lex.line; yyval.interm.op = EOpConstructMat3; ;} - break; - - case 39: -#line 670 "glslang.y" - { FRAG_VERT_ONLY("mat4", yyvsp[0].lex.line); yyval.interm.line = yyvsp[0].lex.line; yyval.interm.op = EOpConstructMat4; ;} - break; - - case 40: -#line 671 "glslang.y" - { - TType& structure = static_cast<TVariable*>(yyvsp[0].lex.symbol)->getType(); - TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; - TPublicType t = { EbtStruct, qual, 1, false, false, &structure, yyvsp[0].lex.line }; - yyval.interm.type = t; - yyval.interm.line = yyvsp[0].lex.line; - yyval.interm.op = EOpConstructStruct; - ;} - break; - - case 41: -#line 682 "glslang.y" - { - yyval.interm.intermTypedNode = yyvsp[0].interm.intermTypedNode; - ;} - break; - - case 42: -#line 685 "glslang.y" - { - if (parseContext.lValueErrorCheck(yyvsp[-1].lex.line, "++", yyvsp[0].interm.intermTypedNode)) - parseContext.recover(); - yyval.interm.intermTypedNode = parseContext.intermediate.addUnaryMath(EOpPreIncrement, yyvsp[0].interm.intermTypedNode, yyvsp[-1].lex.line, parseContext.symbolTable); - if (yyval.interm.intermTypedNode == 0) { - parseContext.unaryOpError(yyvsp[-1].lex.line, "++", yyvsp[0].interm.intermTypedNode->getCompleteString()); - parseContext.recover(); - yyval.interm.intermTypedNode = yyvsp[0].interm.intermTypedNode; - } - ;} - break; - - case 43: -#line 695 "glslang.y" - { - if (parseContext.lValueErrorCheck(yyvsp[-1].lex.line, "--", yyvsp[0].interm.intermTypedNode)) - parseContext.recover(); - yyval.interm.intermTypedNode = parseContext.intermediate.addUnaryMath(EOpPreDecrement, yyvsp[0].interm.intermTypedNode, yyvsp[-1].lex.line, parseContext.symbolTable); - if (yyval.interm.intermTypedNode == 0) { - parseContext.unaryOpError(yyvsp[-1].lex.line, "--", yyvsp[0].interm.intermTypedNode->getCompleteString()); - parseContext.recover(); - yyval.interm.intermTypedNode = yyvsp[0].interm.intermTypedNode; - } - ;} - break; - - case 44: -#line 705 "glslang.y" - { - if (yyvsp[-1].interm.op != EOpNull) { - yyval.interm.intermTypedNode = parseContext.intermediate.addUnaryMath(yyvsp[-1].interm.op, yyvsp[0].interm.intermTypedNode, yyvsp[-1].interm.line, parseContext.symbolTable); - if (yyval.interm.intermTypedNode == 0) { - char* errorOp = ""; - switch(yyvsp[-1].interm.op) { - case EOpNegative: errorOp = "-"; break; - case EOpLogicalNot: errorOp = "!"; break; - case EOpBitwiseNot: errorOp = "~"; break; - default: break; - } - parseContext.unaryOpError(yyvsp[-1].interm.line, errorOp, yyvsp[0].interm.intermTypedNode->getCompleteString()); - parseContext.recover(); - yyval.interm.intermTypedNode = yyvsp[0].interm.intermTypedNode; - } - } else - yyval.interm.intermTypedNode = yyvsp[0].interm.intermTypedNode; - ;} - break; - - case 45: -#line 727 "glslang.y" - { yyval.interm.line = yyvsp[0].lex.line; yyval.interm.op = EOpNull; ;} - break; - - case 46: -#line 728 "glslang.y" - { yyval.interm.line = yyvsp[0].lex.line; yyval.interm.op = EOpNegative; ;} - break; - - case 47: -#line 729 "glslang.y" - { yyval.interm.line = yyvsp[0].lex.line; yyval.interm.op = EOpLogicalNot; ;} - break; - - case 48: -#line 730 "glslang.y" - { PACK_UNPACK_ONLY("~", yyvsp[0].lex.line); - yyval.interm.line = yyvsp[0].lex.line; yyval.interm.op = EOpBitwiseNot; ;} - break; - - case 49: -#line 736 "glslang.y" - { yyval.interm.intermTypedNode = yyvsp[0].interm.intermTypedNode; ;} - break; - - case 50: -#line 737 "glslang.y" - { - FRAG_VERT_ONLY("*", yyvsp[-1].lex.line); - yyval.interm.intermTypedNode = parseContext.intermediate.addBinaryMath(EOpMul, yyvsp[-2].interm.intermTypedNode, yyvsp[0].interm.intermTypedNode, yyvsp[-1].lex.line, parseContext.symbolTable); - if (yyval.interm.intermTypedNode == 0) { - parseContext.binaryOpError(yyvsp[-1].lex.line, "*", yyvsp[-2].interm.intermTypedNode->getCompleteString(), yyvsp[0].interm.intermTypedNode->getCompleteString()); - parseContext.recover(); - yyval.interm.intermTypedNode = yyvsp[-2].interm.intermTypedNode; - } - ;} - break; - - case 51: -#line 746 "glslang.y" - { - FRAG_VERT_ONLY("/", yyvsp[-1].lex.line); - yyval.interm.intermTypedNode = parseContext.intermediate.addBinaryMath(EOpDiv, yyvsp[-2].interm.intermTypedNode, yyvsp[0].interm.intermTypedNode, yyvsp[-1].lex.line, parseContext.symbolTable); - if (yyval.interm.intermTypedNode == 0) { - parseContext.binaryOpError(yyvsp[-1].lex.line, "/", yyvsp[-2].interm.intermTypedNode->getCompleteString(), yyvsp[0].interm.intermTypedNode->getCompleteString()); - parseContext.recover(); - yyval.interm.intermTypedNode = yyvsp[-2].interm.intermTypedNode; - } - ;} - break; - - case 52: -#line 755 "glslang.y" - { - PACK_UNPACK_ONLY("%", yyvsp[-1].lex.line); - yyval.interm.intermTypedNode = parseContext.intermediate.addBinaryMath(EOpMod, yyvsp[-2].interm.intermTypedNode, yyvsp[0].interm.intermTypedNode, yyvsp[-1].lex.line, parseContext.symbolTable); - if (yyval.interm.intermTypedNode == 0) { - parseContext.binaryOpError(yyvsp[-1].lex.line, "%", yyvsp[-2].interm.intermTypedNode->getCompleteString(), yyvsp[0].interm.intermTypedNode->getCompleteString()); - parseContext.recover(); - yyval.interm.intermTypedNode = yyvsp[-2].interm.intermTypedNode; - } - ;} - break; - - case 53: -#line 767 "glslang.y" - { yyval.interm.intermTypedNode = yyvsp[0].interm.intermTypedNode; ;} - break; - - case 54: -#line 768 "glslang.y" - { - yyval.interm.intermTypedNode = parseContext.intermediate.addBinaryMath(EOpAdd, yyvsp[-2].interm.intermTypedNode, yyvsp[0].interm.intermTypedNode, yyvsp[-1].lex.line, parseContext.symbolTable); - if (yyval.interm.intermTypedNode == 0) { - parseContext.binaryOpError(yyvsp[-1].lex.line, "+", yyvsp[-2].interm.intermTypedNode->getCompleteString(), yyvsp[0].interm.intermTypedNode->getCompleteString()); - parseContext.recover(); - yyval.interm.intermTypedNode = yyvsp[-2].interm.intermTypedNode; - } - ;} - break; - - case 55: -#line 776 "glslang.y" - { - yyval.interm.intermTypedNode = parseContext.intermediate.addBinaryMath(EOpSub, yyvsp[-2].interm.intermTypedNode, yyvsp[0].interm.intermTypedNode, yyvsp[-1].lex.line, parseContext.symbolTable); - if (yyval.interm.intermTypedNode == 0) { - parseContext.binaryOpError(yyvsp[-1].lex.line, "-", yyvsp[-2].interm.intermTypedNode->getCompleteString(), yyvsp[0].interm.intermTypedNode->getCompleteString()); - parseContext.recover(); - yyval.interm.intermTypedNode = yyvsp[-2].interm.intermTypedNode; - } - ;} - break; - - case 56: -#line 787 "glslang.y" - { yyval.interm.intermTypedNode = yyvsp[0].interm.intermTypedNode; ;} - break; - - case 57: -#line 788 "glslang.y" - { - PACK_UNPACK_ONLY("<<", yyvsp[-1].lex.line); - yyval.interm.intermTypedNode = parseContext.intermediate.addBinaryMath(EOpLeftShift, yyvsp[-2].interm.intermTypedNode, yyvsp[0].interm.intermTypedNode, yyvsp[-1].lex.line, parseContext.symbolTable); - if (yyval.interm.intermTypedNode == 0) { - parseContext.binaryOpError(yyvsp[-1].lex.line, "<<", yyvsp[-2].interm.intermTypedNode->getCompleteString(), yyvsp[0].interm.intermTypedNode->getCompleteString()); - parseContext.recover(); - yyval.interm.intermTypedNode = yyvsp[-2].interm.intermTypedNode; - } - ;} - break; - - case 58: -#line 797 "glslang.y" - { - PACK_UNPACK_ONLY(">>", yyvsp[-1].lex.line); - yyval.interm.intermTypedNode = parseContext.intermediate.addBinaryMath(EOpRightShift, yyvsp[-2].interm.intermTypedNode, yyvsp[0].interm.intermTypedNode, yyvsp[-1].lex.line, parseContext.symbolTable); - if (yyval.interm.intermTypedNode == 0) { - parseContext.binaryOpError(yyvsp[-1].lex.line, ">>", yyvsp[-2].interm.intermTypedNode->getCompleteString(), yyvsp[0].interm.intermTypedNode->getCompleteString()); - parseContext.recover(); - yyval.interm.intermTypedNode = yyvsp[-2].interm.intermTypedNode; - } - ;} - break; - - case 59: -#line 809 "glslang.y" - { yyval.interm.intermTypedNode = yyvsp[0].interm.intermTypedNode; ;} - break; - - case 60: -#line 810 "glslang.y" - { - yyval.interm.intermTypedNode = parseContext.intermediate.addBinaryMath(EOpLessThan, yyvsp[-2].interm.intermTypedNode, yyvsp[0].interm.intermTypedNode, yyvsp[-1].lex.line, parseContext.symbolTable); - if (yyval.interm.intermTypedNode == 0) { - parseContext.binaryOpError(yyvsp[-1].lex.line, "<", yyvsp[-2].interm.intermTypedNode->getCompleteString(), yyvsp[0].interm.intermTypedNode->getCompleteString()); - parseContext.recover(); - constUnion *unionArray = new constUnion[1]; - unionArray->bConst = false; - yyval.interm.intermTypedNode = parseContext.intermediate.addConstantUnion(unionArray, TType(EbtBool, EvqConst), yyvsp[-1].lex.line); - } - ;} - break; - - case 61: -#line 820 "glslang.y" - { - yyval.interm.intermTypedNode = parseContext.intermediate.addBinaryMath(EOpGreaterThan, yyvsp[-2].interm.intermTypedNode, yyvsp[0].interm.intermTypedNode, yyvsp[-1].lex.line, parseContext.symbolTable); - if (yyval.interm.intermTypedNode == 0) { - parseContext.binaryOpError(yyvsp[-1].lex.line, ">", yyvsp[-2].interm.intermTypedNode->getCompleteString(), yyvsp[0].interm.intermTypedNode->getCompleteString()); - parseContext.recover(); - constUnion *unionArray = new constUnion[1]; - unionArray->bConst = false; - yyval.interm.intermTypedNode = parseContext.intermediate.addConstantUnion(unionArray, TType(EbtBool, EvqConst), yyvsp[-1].lex.line); - } - ;} - break; - - case 62: -#line 830 "glslang.y" - { - yyval.interm.intermTypedNode = parseContext.intermediate.addBinaryMath(EOpLessThanEqual, yyvsp[-2].interm.intermTypedNode, yyvsp[0].interm.intermTypedNode, yyvsp[-1].lex.line, parseContext.symbolTable); - if (yyval.interm.intermTypedNode == 0) { - parseContext.binaryOpError(yyvsp[-1].lex.line, "<=", yyvsp[-2].interm.intermTypedNode->getCompleteString(), yyvsp[0].interm.intermTypedNode->getCompleteString()); - parseContext.recover(); - constUnion *unionArray = new constUnion[1]; - unionArray->bConst = false; - yyval.interm.intermTypedNode = parseContext.intermediate.addConstantUnion(unionArray, TType(EbtBool, EvqConst), yyvsp[-1].lex.line); - } - ;} - break; - - case 63: -#line 840 "glslang.y" - { - yyval.interm.intermTypedNode = parseContext.intermediate.addBinaryMath(EOpGreaterThanEqual, yyvsp[-2].interm.intermTypedNode, yyvsp[0].interm.intermTypedNode, yyvsp[-1].lex.line, parseContext.symbolTable); - if (yyval.interm.intermTypedNode == 0) { - parseContext.binaryOpError(yyvsp[-1].lex.line, ">=", yyvsp[-2].interm.intermTypedNode->getCompleteString(), yyvsp[0].interm.intermTypedNode->getCompleteString()); - parseContext.recover(); - constUnion *unionArray = new constUnion[1]; - unionArray->bConst = false; - yyval.interm.intermTypedNode = parseContext.intermediate.addConstantUnion(unionArray, TType(EbtBool, EvqConst), yyvsp[-1].lex.line); - } - ;} - break; - - case 64: -#line 853 "glslang.y" - { yyval.interm.intermTypedNode = yyvsp[0].interm.intermTypedNode; ;} - break; - - case 65: -#line 854 "glslang.y" - { - yyval.interm.intermTypedNode = parseContext.intermediate.addBinaryMath(EOpEqual, yyvsp[-2].interm.intermTypedNode, yyvsp[0].interm.intermTypedNode, yyvsp[-1].lex.line, parseContext.symbolTable); - if (yyval.interm.intermTypedNode == 0) { - parseContext.binaryOpError(yyvsp[-1].lex.line, "==", yyvsp[-2].interm.intermTypedNode->getCompleteString(), yyvsp[0].interm.intermTypedNode->getCompleteString()); - parseContext.recover(); - constUnion *unionArray = new constUnion[1]; - unionArray->bConst = false; - yyval.interm.intermTypedNode = parseContext.intermediate.addConstantUnion(unionArray, TType(EbtBool, EvqConst), yyvsp[-1].lex.line); - } - ;} - break; - - case 66: -#line 864 "glslang.y" - { - yyval.interm.intermTypedNode = parseContext.intermediate.addBinaryMath(EOpNotEqual, yyvsp[-2].interm.intermTypedNode, yyvsp[0].interm.intermTypedNode, yyvsp[-1].lex.line, parseContext.symbolTable); - if (yyval.interm.intermTypedNode == 0) { - parseContext.binaryOpError(yyvsp[-1].lex.line, "!=", yyvsp[-2].interm.intermTypedNode->getCompleteString(), yyvsp[0].interm.intermTypedNode->getCompleteString()); - parseContext.recover(); - constUnion *unionArray = new constUnion[1]; - unionArray->bConst = false; - yyval.interm.intermTypedNode = parseContext.intermediate.addConstantUnion(unionArray, TType(EbtBool, EvqConst), yyvsp[-1].lex.line); - } - ;} - break; - - case 67: -#line 877 "glslang.y" - { yyval.interm.intermTypedNode = yyvsp[0].interm.intermTypedNode; ;} - break; - - case 68: -#line 878 "glslang.y" - { - PACK_UNPACK_ONLY("&", yyvsp[-1].lex.line); - yyval.interm.intermTypedNode = parseContext.intermediate.addBinaryMath(EOpAnd, yyvsp[-2].interm.intermTypedNode, yyvsp[0].interm.intermTypedNode, yyvsp[-1].lex.line, parseContext.symbolTable); - if (yyval.interm.intermTypedNode == 0) { - parseContext.binaryOpError(yyvsp[-1].lex.line, "&", yyvsp[-2].interm.intermTypedNode->getCompleteString(), yyvsp[0].interm.intermTypedNode->getCompleteString()); - parseContext.recover(); - yyval.interm.intermTypedNode = yyvsp[-2].interm.intermTypedNode; - } - ;} - break; - - case 69: -#line 890 "glslang.y" - { yyval.interm.intermTypedNode = yyvsp[0].interm.intermTypedNode; ;} - break; - - case 70: -#line 891 "glslang.y" - { - PACK_UNPACK_ONLY("^", yyvsp[-1].lex.line); - yyval.interm.intermTypedNode = parseContext.intermediate.addBinaryMath(EOpExclusiveOr, yyvsp[-2].interm.intermTypedNode, yyvsp[0].interm.intermTypedNode, yyvsp[-1].lex.line, parseContext.symbolTable); - if (yyval.interm.intermTypedNode == 0) { - parseContext.binaryOpError(yyvsp[-1].lex.line, "^", yyvsp[-2].interm.intermTypedNode->getCompleteString(), yyvsp[0].interm.intermTypedNode->getCompleteString()); - parseContext.recover(); - yyval.interm.intermTypedNode = yyvsp[-2].interm.intermTypedNode; - } - ;} - break; - - case 71: -#line 903 "glslang.y" - { yyval.interm.intermTypedNode = yyvsp[0].interm.intermTypedNode; ;} - break; - - case 72: -#line 904 "glslang.y" - { - PACK_UNPACK_ONLY("|", yyvsp[-1].lex.line); - yyval.interm.intermTypedNode = parseContext.intermediate.addBinaryMath(EOpInclusiveOr, yyvsp[-2].interm.intermTypedNode, yyvsp[0].interm.intermTypedNode, yyvsp[-1].lex.line, parseContext.symbolTable); - if (yyval.interm.intermTypedNode == 0) { - parseContext.binaryOpError(yyvsp[-1].lex.line, "|", yyvsp[-2].interm.intermTypedNode->getCompleteString(), yyvsp[0].interm.intermTypedNode->getCompleteString()); - parseContext.recover(); - yyval.interm.intermTypedNode = yyvsp[-2].interm.intermTypedNode; - } - ;} - break; - - case 73: -#line 916 "glslang.y" - { yyval.interm.intermTypedNode = yyvsp[0].interm.intermTypedNode; ;} - break; - - case 74: -#line 917 "glslang.y" - { - yyval.interm.intermTypedNode = parseContext.intermediate.addBinaryMath(EOpLogicalAnd, yyvsp[-2].interm.intermTypedNode, yyvsp[0].interm.intermTypedNode, yyvsp[-1].lex.line, parseContext.symbolTable); - if (yyval.interm.intermTypedNode == 0) { - parseContext.binaryOpError(yyvsp[-1].lex.line, "&&", yyvsp[-2].interm.intermTypedNode->getCompleteString(), yyvsp[0].interm.intermTypedNode->getCompleteString()); - parseContext.recover(); - constUnion *unionArray = new constUnion[1]; - unionArray->bConst = false; - yyval.interm.intermTypedNode = parseContext.intermediate.addConstantUnion(unionArray, TType(EbtBool, EvqConst), yyvsp[-1].lex.line); - } - ;} - break; - - case 75: -#line 930 "glslang.y" - { yyval.interm.intermTypedNode = yyvsp[0].interm.intermTypedNode; ;} - break; - - case 76: -#line 931 "glslang.y" - { - yyval.interm.intermTypedNode = parseContext.intermediate.addBinaryMath(EOpLogicalXor, yyvsp[-2].interm.intermTypedNode, yyvsp[0].interm.intermTypedNode, yyvsp[-1].lex.line, parseContext.symbolTable); - if (yyval.interm.intermTypedNode == 0) { - parseContext.binaryOpError(yyvsp[-1].lex.line, "^^", yyvsp[-2].interm.intermTypedNode->getCompleteString(), yyvsp[0].interm.intermTypedNode->getCompleteString()); - parseContext.recover(); - constUnion *unionArray = new constUnion[1]; - unionArray->bConst = false; - yyval.interm.intermTypedNode = parseContext.intermediate.addConstantUnion(unionArray, TType(EbtBool, EvqConst), yyvsp[-1].lex.line); - } - ;} - break; - - case 77: -#line 944 "glslang.y" - { yyval.interm.intermTypedNode = yyvsp[0].interm.intermTypedNode; ;} - break; - - case 78: -#line 945 "glslang.y" - { - yyval.interm.intermTypedNode = parseContext.intermediate.addBinaryMath(EOpLogicalOr, yyvsp[-2].interm.intermTypedNode, yyvsp[0].interm.intermTypedNode, yyvsp[-1].lex.line, parseContext.symbolTable); - if (yyval.interm.intermTypedNode == 0) { - parseContext.binaryOpError(yyvsp[-1].lex.line, "||", yyvsp[-2].interm.intermTypedNode->getCompleteString(), yyvsp[0].interm.intermTypedNode->getCompleteString()); - parseContext.recover(); - constUnion *unionArray = new constUnion[1]; - unionArray->bConst = false; - yyval.interm.intermTypedNode = parseContext.intermediate.addConstantUnion(unionArray, TType(EbtBool, EvqConst), yyvsp[-1].lex.line); - } - ;} - break; - - case 79: -#line 958 "glslang.y" - { yyval.interm.intermTypedNode = yyvsp[0].interm.intermTypedNode; ;} - break; - - case 80: -#line 959 "glslang.y" - { - if (parseContext.boolErrorCheck(yyvsp[-3].lex.line, yyvsp[-4].interm.intermTypedNode)) - parseContext.recover(); - - yyval.interm.intermTypedNode = parseContext.intermediate.addSelection(yyvsp[-4].interm.intermTypedNode, yyvsp[-2].interm.intermTypedNode, yyvsp[0].interm.intermTypedNode, yyvsp[-3].lex.line); - if (yyvsp[-2].interm.intermTypedNode->getType() != yyvsp[0].interm.intermTypedNode->getType()) - yyval.interm.intermTypedNode = 0; - - if (yyval.interm.intermTypedNode == 0) { - parseContext.binaryOpError(yyvsp[-3].lex.line, ":", yyvsp[-2].interm.intermTypedNode->getCompleteString(), yyvsp[0].interm.intermTypedNode->getCompleteString()); - parseContext.recover(); - yyval.interm.intermTypedNode = yyvsp[0].interm.intermTypedNode; - } - ;} - break; - - case 81: -#line 976 "glslang.y" - { yyval.interm.intermTypedNode = yyvsp[0].interm.intermTypedNode; ;} - break; - - case 82: -#line 977 "glslang.y" - { - if (parseContext.lValueErrorCheck(yyvsp[-1].interm.line, "assign", yyvsp[-2].interm.intermTypedNode)) - parseContext.recover(); - yyval.interm.intermTypedNode = parseContext.intermediate.addAssign(yyvsp[-1].interm.op, yyvsp[-2].interm.intermTypedNode, yyvsp[0].interm.intermTypedNode, yyvsp[-1].interm.line); - if (yyval.interm.intermTypedNode == 0) { - parseContext.assignError(yyvsp[-1].interm.line, "assign", yyvsp[-2].interm.intermTypedNode->getCompleteString(), yyvsp[0].interm.intermTypedNode->getCompleteString()); - parseContext.recover(); - yyval.interm.intermTypedNode = yyvsp[-2].interm.intermTypedNode; - } - ;} - break; - - case 83: -#line 990 "glslang.y" - { yyval.interm.line = yyvsp[0].lex.line; yyval.interm.op = EOpAssign; ;} - break; - - case 84: -#line 991 "glslang.y" - { FRAG_VERT_ONLY("*=", yyvsp[0].lex.line); yyval.interm.line = yyvsp[0].lex.line; yyval.interm.op = EOpMulAssign; ;} - break; - - case 85: -#line 992 "glslang.y" - { FRAG_VERT_ONLY("/=", yyvsp[0].lex.line); yyval.interm.line = yyvsp[0].lex.line; yyval.interm.op = EOpDivAssign; ;} - break; - - case 86: -#line 993 "glslang.y" - { PACK_UNPACK_ONLY("%=", yyvsp[0].lex.line); yyval.interm.line = yyvsp[0].lex.line; yyval.interm.op = EOpModAssign; ;} - break; - - case 87: -#line 994 "glslang.y" - { yyval.interm.line = yyvsp[0].lex.line; yyval.interm.op = EOpAddAssign; ;} - break; - - case 88: -#line 995 "glslang.y" - { yyval.interm.line = yyvsp[0].lex.line; yyval.interm.op = EOpSubAssign; ;} - break; - - case 89: -#line 996 "glslang.y" - { PACK_UNPACK_ONLY("<<=", yyvsp[0].lex.line); yyval.interm.line = yyvsp[0].lex.line; yyval.interm.op = EOpLeftShiftAssign; ;} - break; - - case 90: -#line 997 "glslang.y" - { PACK_UNPACK_ONLY("<<=", yyvsp[0].lex.line); yyval.interm.line = yyvsp[0].lex.line; yyval.interm.op = EOpRightShiftAssign; ;} - break; - - case 91: -#line 998 "glslang.y" - { PACK_UNPACK_ONLY("&=", yyvsp[0].lex.line); yyval.interm.line = yyvsp[0].lex.line; yyval.interm.op = EOpAndAssign; ;} - break; - - case 92: -#line 999 "glslang.y" - { PACK_UNPACK_ONLY("^=", yyvsp[0].lex.line); yyval.interm.line = yyvsp[0].lex.line; yyval.interm.op = EOpExclusiveOrAssign; ;} - break; - - case 93: -#line 1000 "glslang.y" - { PACK_UNPACK_ONLY("|=", yyvsp[0].lex.line); yyval.interm.line = yyvsp[0].lex.line; yyval.interm.op = EOpInclusiveOrAssign; ;} - break; - - case 94: -#line 1004 "glslang.y" - { - yyval.interm.intermTypedNode = yyvsp[0].interm.intermTypedNode; - ;} - break; - - case 95: -#line 1007 "glslang.y" - { - yyval.interm.intermTypedNode = parseContext.intermediate.addComma(yyvsp[-2].interm.intermTypedNode, yyvsp[0].interm.intermTypedNode, yyvsp[-1].lex.line); - if (yyval.interm.intermTypedNode == 0) { - parseContext.binaryOpError(yyvsp[-1].lex.line, ",", yyvsp[-2].interm.intermTypedNode->getCompleteString(), yyvsp[0].interm.intermTypedNode->getCompleteString()); - parseContext.recover(); - yyval.interm.intermTypedNode = yyvsp[0].interm.intermTypedNode; - } - ;} - break; - - case 96: -#line 1018 "glslang.y" - { - if (parseContext.constErrorCheck(yyvsp[0].interm.intermTypedNode)) - parseContext.recover(); - yyval.interm.intermTypedNode = yyvsp[0].interm.intermTypedNode; - ;} - break; - - case 97: -#line 1026 "glslang.y" - { yyval.interm.intermNode = 0; ;} - break; - - case 98: -#line 1027 "glslang.y" - { - if (yyvsp[-1].interm.intermAggregate) - yyvsp[-1].interm.intermAggregate->setOperator(EOpSequence); - yyval.interm.intermNode = yyvsp[-1].interm.intermAggregate; - ;} - break; - - case 99: -#line 1035 "glslang.y" - { - // - // Multiple declarations of the same function are allowed. - // - // If this is a definition, the definition production code will check for redefinitions - // (we don't know at this point if it's a definition or not). - // - // Redeclarations are allowed. But, return types and parameter qualifiers must match. - // - TFunction* prevDec = static_cast<TFunction*>(parseContext.symbolTable.find(yyvsp[-1].interm.function->getMangledName())); - if (prevDec) { - if (prevDec->getReturnType() != yyvsp[-1].interm.function->getReturnType()) { - parseContext.error(yyvsp[0].lex.line, "overloaded functions must have the same return type", yyvsp[-1].interm.function->getReturnType().getBasicString(), ""); - parseContext.recover(); - } - for (int i = 0; i < prevDec->getParamCount(); ++i) { - if ((*prevDec)[i].type->getQualifier() != (*yyvsp[-1].interm.function)[i].type->getQualifier()) { - parseContext.error(yyvsp[0].lex.line, "overloaded functions must have the same parameter qualifiers", (*yyvsp[-1].interm.function)[i].type->getQualifierString(), ""); - parseContext.recover(); - } - } - } - - // - // If this is a redeclaration, it could also be a definition, - // in which case, we want to use the variable names from this one, and not the one that's - // being redeclared. So, pass back up this declaration, not the one in the symbol table. - // - yyval.interm.function = yyvsp[-1].interm.function; - yyval.interm.line = yyvsp[0].lex.line; - - parseContext.symbolTable.insert(*yyval.interm.function); - ;} - break; - - case 100: -#line 1071 "glslang.y" - { - yyval.interm.function = yyvsp[0].interm.function; - ;} - break; - - case 101: -#line 1074 "glslang.y" - { - yyval.interm.function = yyvsp[0].interm.function; - ;} - break; - - case 102: -#line 1081 "glslang.y" - { - // Add the parameter - yyval.interm.function = yyvsp[-1].interm.function; - if (yyvsp[0].interm.param.type->getBasicType() != EbtVoid) - yyvsp[-1].interm.function->addParameter(yyvsp[0].interm.param); - else - delete yyvsp[0].interm.param.type; - ;} - break; - - case 103: -#line 1089 "glslang.y" - { - // - // Only first parameter of one-parameter functions can be void - // The check for named parameters not being void is done in parameter_declarator - // - if (yyvsp[0].interm.param.type->getBasicType() == EbtVoid) { - // - // This parameter > first is void - // - parseContext.error(yyvsp[-1].lex.line, "cannot be an argument type except for '(void)'", "void", ""); - parseContext.recover(); - delete yyvsp[0].interm.param.type; - } else { - // Add the parameter - yyval.interm.function = yyvsp[-2].interm.function; - yyvsp[-2].interm.function->addParameter(yyvsp[0].interm.param); - } - ;} - break; - - case 104: -#line 1110 "glslang.y" - { - if (yyvsp[-2].interm.type.qualifier != EvqGlobal && yyvsp[-2].interm.type.qualifier != EvqTemporary) { - parseContext.error(yyvsp[-1].lex.line, "no qualifiers allowed for function return", getQualifierString(yyvsp[-2].interm.type.qualifier), ""); - parseContext.recover(); - } - // make sure a sampler is not involved as well... - if (parseContext.structQualifierErrorCheck(yyvsp[-1].lex.line, yyvsp[-2].interm.type)) - parseContext.recover(); - - // Add the function as a prototype after parsing it (we do not support recursion) - TFunction *function; - TType type(yyvsp[-2].interm.type); - function = new TFunction(yyvsp[-1].lex.string, type); - yyval.interm.function = function; - ;} - break; - - case 105: -#line 1129 "glslang.y" - { - if (yyvsp[-1].interm.type.type == EbtVoid) { - parseContext.error(yyvsp[0].lex.line, "illegal use of type 'void'", yyvsp[0].lex.string->c_str(), ""); - parseContext.recover(); - } - if (parseContext.reservedErrorCheck(yyvsp[0].lex.line, *yyvsp[0].lex.string)) - parseContext.recover(); - TParameter param = {yyvsp[0].lex.string, new TType(yyvsp[-1].interm.type)}; - yyval.interm.line = yyvsp[0].lex.line; - yyval.interm.param = param; - ;} - break; - - case 106: -#line 1140 "glslang.y" - { - // Check that we can make an array out of this type - if (yyvsp[-4].interm.type.array) { - parseContext.error(yyvsp[-2].lex.line, "cannot declare arrays of this type", TType(yyvsp[-4].interm.type).getCompleteString().c_str(), ""); - parseContext.recover(); - } - if (parseContext.reservedErrorCheck(yyvsp[-3].lex.line, *yyvsp[-3].lex.string)) - parseContext.recover(); - yyvsp[-4].interm.type.array = true; - TType* type = new TType(yyvsp[-4].interm.type); - if (yyvsp[-1].interm.intermTypedNode->getAsConstantUnion()) - type->setArraySize(yyvsp[-1].interm.intermTypedNode->getAsConstantUnion()->getUnionArrayPointer()->iConst); - TParameter param = { yyvsp[-3].lex.string, type }; - yyval.interm.line = yyvsp[-3].lex.line; - yyval.interm.param = param; - ;} - break; - - case 107: -#line 1167 "glslang.y" - { - yyval.interm = yyvsp[0].interm; - if (parseContext.paramErrorCheck(yyvsp[0].interm.line, yyvsp[-2].interm.type.qualifier, yyvsp[-1].interm.qualifier, yyval.interm.param.type)) - parseContext.recover(); - ;} - break; - - case 108: -#line 1172 "glslang.y" - { - yyval.interm = yyvsp[0].interm; - if (parseContext.parameterSamplerErrorCheck(yyvsp[0].interm.line, yyvsp[-1].interm.qualifier, *yyvsp[0].interm.param.type)) - parseContext.recover(); - if (parseContext.paramErrorCheck(yyvsp[0].interm.line, EvqTemporary, yyvsp[-1].interm.qualifier, yyval.interm.param.type)) - parseContext.recover(); - ;} - break; - - case 109: -#line 1182 "glslang.y" - { - yyval.interm = yyvsp[0].interm; - if (parseContext.paramErrorCheck(yyvsp[0].interm.line, yyvsp[-2].interm.type.qualifier, yyvsp[-1].interm.qualifier, yyval.interm.param.type)) - parseContext.recover(); - ;} - break; - - case 110: -#line 1187 "glslang.y" - { - yyval.interm = yyvsp[0].interm; - if (parseContext.parameterSamplerErrorCheck(yyvsp[0].interm.line, yyvsp[-1].interm.qualifier, *yyvsp[0].interm.param.type)) - parseContext.recover(); - if (parseContext.paramErrorCheck(yyvsp[0].interm.line, EvqTemporary, yyvsp[-1].interm.qualifier, yyval.interm.param.type)) - parseContext.recover(); - ;} - break; - - case 111: -#line 1197 "glslang.y" - { - yyval.interm.qualifier = EvqIn; - ;} - break; - - case 112: -#line 1200 "glslang.y" - { - yyval.interm.qualifier = EvqIn; - ;} - break; - - case 113: -#line 1203 "glslang.y" - { - yyval.interm.qualifier = EvqOut; - ;} - break; - - case 114: -#line 1206 "glslang.y" - { - yyval.interm.qualifier = EvqInOut; - ;} - break; - - case 115: -#line 1212 "glslang.y" - { - TParameter param = { 0, new TType(yyvsp[0].interm.type) }; - yyval.interm.param = param; - - ;} - break; - - case 116: -#line 1217 "glslang.y" - { - // Check that we can make an array out of this type - if (yyvsp[-3].interm.type.array) { - parseContext.error(yyvsp[-2].lex.line, "cannot declare arrays of this type", TType(yyvsp[-3].interm.type).getCompleteString().c_str(), ""); - parseContext.recover(); - } - yyvsp[-3].interm.type.array = true; - TType* type = new TType(yyvsp[-3].interm.type); - if (yyvsp[-1].interm.intermTypedNode->getAsConstantUnion()) - type->setArraySize(yyvsp[-1].interm.intermTypedNode->getAsConstantUnion()->getUnionArrayPointer()->iConst); - - TParameter param = { 0, type }; - yyval.interm.line = yyvsp[-2].lex.line; - yyval.interm.param = param; - ;} - break; - - case 117: -#line 1235 "glslang.y" - { - yyval.interm = yyvsp[0].interm; - ;} - break; - - case 118: -#line 1238 "glslang.y" - { - yyval.interm = yyvsp[-2].interm; - if (parseContext.structQualifierErrorCheck(yyvsp[0].lex.line, yyvsp[-2].interm.type)) - parseContext.recover(); - - if (parseContext.nonInitErrorCheck(yyvsp[0].lex.line, *yyvsp[0].lex.string, yyval.interm.type)) - parseContext.recover(); - ;} - break; - - case 119: -#line 1246 "glslang.y" - { - yyval.interm = yyvsp[-4].interm; - if (parseContext.structQualifierErrorCheck(yyvsp[-2].lex.line, yyvsp[-4].interm.type)) - parseContext.recover(); - - if (parseContext.arrayErrorCheck(yyvsp[-1].lex.line, *yyvsp[-2].lex.string, yyval.interm.type, 0)) - parseContext.recover(); - ;} - break; - - case 120: -#line 1254 "glslang.y" - { - yyval.interm = yyvsp[-5].interm; - if (parseContext.structQualifierErrorCheck(yyvsp[-3].lex.line, yyvsp[-5].interm.type)) - parseContext.recover(); - - if (parseContext.arrayErrorCheck(yyvsp[-2].lex.line, *yyvsp[-3].lex.string, yyval.interm.type, yyvsp[-1].interm.intermTypedNode)) - parseContext.recover(); - ;} - break; - - case 121: -#line 1262 "glslang.y" - { - yyval.interm = yyvsp[-4].interm; - if (parseContext.structQualifierErrorCheck(yyvsp[-2].lex.line, yyvsp[-4].interm.type)) - parseContext.recover(); - - TIntermNode* intermNode; - if (!parseContext.executeInitializer(yyvsp[-2].lex.line, *yyvsp[-2].lex.string, yyvsp[-4].interm.type, yyvsp[0].interm.intermTypedNode, intermNode)) { - // - // build the intermediate representation - // - if (intermNode) - yyval.interm.intermAggregate = parseContext.intermediate.growAggregate(yyvsp[-4].interm.intermNode, intermNode, yyvsp[-1].lex.line); - else - yyval.interm.intermAggregate = yyvsp[-4].interm.intermAggregate; - } else { - parseContext.recover(); - yyval.interm.intermAggregate = 0; - } - ;} - break; - - case 122: -#line 1284 "glslang.y" - { - yyval.interm.type = yyvsp[0].interm.type; - yyval.interm.intermAggregate = 0; - ;} - break; - - case 123: -#line 1288 "glslang.y" - { - yyval.interm.intermAggregate = 0; - yyval.interm.type = yyvsp[-1].interm.type; - if (parseContext.structQualifierErrorCheck(yyvsp[0].lex.line, yyvsp[-1].interm.type)) - parseContext.recover(); - - if (parseContext.nonInitErrorCheck(yyvsp[0].lex.line, *yyvsp[0].lex.string, yyval.interm.type)) - parseContext.recover(); - ;} - break; - - case 124: -#line 1297 "glslang.y" - { - yyval.interm.intermAggregate = 0; - yyval.interm.type = yyvsp[-3].interm.type; - if (parseContext.structQualifierErrorCheck(yyvsp[-2].lex.line, yyvsp[-3].interm.type)) - parseContext.recover(); - - if (parseContext.arrayErrorCheck(yyvsp[-1].lex.line, *yyvsp[-2].lex.string, yyval.interm.type, 0)) - parseContext.recover(); - ;} - break; - - case 125: -#line 1306 "glslang.y" - { - yyval.interm.intermAggregate = 0; - yyval.interm.type = yyvsp[-4].interm.type; - if (parseContext.structQualifierErrorCheck(yyvsp[-3].lex.line, yyvsp[-4].interm.type)) - parseContext.recover(); - - if (parseContext.arrayErrorCheck(yyvsp[-2].lex.line, *yyvsp[-3].lex.string, yyval.interm.type, yyvsp[-1].interm.intermTypedNode)) - parseContext.recover(); - ;} - break; - - case 126: -#line 1315 "glslang.y" - { - yyval.interm.type = yyvsp[-3].interm.type; - if (parseContext.structQualifierErrorCheck(yyvsp[-2].lex.line, yyvsp[-3].interm.type)) - parseContext.recover(); - - TIntermNode* intermNode; - if (!parseContext.executeInitializer(yyvsp[-2].lex.line, *yyvsp[-2].lex.string, yyvsp[-3].interm.type, yyvsp[0].interm.intermTypedNode, intermNode)) { - // - // Build intermediate representation - // - if (intermNode) - yyval.interm.intermAggregate = parseContext.intermediate.makeAggregate(intermNode, yyvsp[-1].lex.line); - else - yyval.interm.intermAggregate = 0; - } else { - parseContext.recover(); - yyval.interm.intermAggregate = 0; - } - ;} - break; - - case 127: -#line 1405 "glslang.y" - { - yyval.interm.type = yyvsp[0].interm.type; - ;} - break; - - case 128: -#line 1408 "glslang.y" - { - TPublicType t = { yyvsp[0].interm.type.type, yyvsp[-1].interm.type.qualifier, yyvsp[0].interm.type.size, yyvsp[0].interm.type.matrix, false, yyvsp[0].interm.type.userDef, 0 }; - if (yyvsp[-1].interm.type.qualifier == EvqAttribute && - (yyvsp[0].interm.type.type == EbtBool || yyvsp[0].interm.type.type == EbtInt)) { - parseContext.error(yyvsp[0].interm.type.line, "cannot be bool or int", getQualifierString(yyvsp[-1].interm.type.qualifier), ""); - parseContext.recover(); - } - if ((yyvsp[-1].interm.type.qualifier == EvqVaryingIn || yyvsp[-1].interm.type.qualifier == EvqVaryingOut) && - (yyvsp[0].interm.type.type == EbtBool || yyvsp[0].interm.type.type == EbtInt)) { - parseContext.error(yyvsp[0].interm.type.line, "cannot be bool or int", getQualifierString(yyvsp[-1].interm.type.qualifier), ""); - parseContext.recover(); - } - yyval.interm.type = t; - ;} - break; - - case 129: -#line 1425 "glslang.y" - { - TPublicType t = { EbtVoid, EvqConst, 1, false, false, 0 }; - yyval.interm.type = t; - ;} - break; - - case 130: -#line 1429 "glslang.y" - { - VERTEX_ONLY("attribute", yyvsp[0].lex.line); - if (parseContext.globalErrorCheck(yyvsp[0].lex.line, parseContext.symbolTable.atGlobalLevel(), "attribute")) - parseContext.recover(); - TPublicType t = { EbtVoid, EvqAttribute, 1, false, false, 0 }; - yyval.interm.type = t; - ;} - break; - - case 131: -#line 1436 "glslang.y" - { - if (parseContext.globalErrorCheck(yyvsp[0].lex.line, parseContext.symbolTable.atGlobalLevel(), "varying")) - parseContext.recover(); - TPublicType t = { EbtVoid, EvqVaryingIn, 1, false, false, 0 }; - if (parseContext.language == EShLangVertex) - t.qualifier = EvqVaryingOut; - yyval.interm.type = t; - ;} - break; - - case 132: -#line 1444 "glslang.y" - { - if (parseContext.globalErrorCheck(yyvsp[0].lex.line, parseContext.symbolTable.atGlobalLevel(), "uniform")) - parseContext.recover(); - TPublicType t = { EbtVoid, EvqUniform, 1, false, false, 0 }; - yyval.interm.type = t; - ;} - break; - - case 133: -#line 1453 "glslang.y" - { - TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; - TPublicType t = { EbtVoid, qual, 1, false, false, 0, yyvsp[0].lex.line }; - yyval.interm.type = t; - ;} - break; - - case 134: -#line 1458 "glslang.y" - { - TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; - TPublicType t = { EbtFloat, qual, 1, false, false, 0, yyvsp[0].lex.line }; - yyval.interm.type = t; - ;} - break; - - case 135: -#line 1463 "glslang.y" - { - TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; - TPublicType t = { EbtInt, qual, 1, false, false, 0, yyvsp[0].lex.line }; - yyval.interm.type = t; - ;} - break; - - case 136: -#line 1468 "glslang.y" - { - TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; - TPublicType t = { EbtBool, qual, 1, false, false, 0, yyvsp[0].lex.line }; - yyval.interm.type = t; - ;} - break; - - case 137: -#line 1479 "glslang.y" - { - TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; - TPublicType t = { EbtFloat, qual, 2, false, false, 0, yyvsp[0].lex.line }; - yyval.interm.type = t; - ;} - break; - - case 138: -#line 1484 "glslang.y" - { - TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; - TPublicType t = { EbtFloat, qual, 3, false, false, 0, yyvsp[0].lex.line }; - yyval.interm.type = t; - ;} - break; - - case 139: -#line 1489 "glslang.y" - { - TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; - TPublicType t = { EbtFloat, qual, 4, false, false, 0, yyvsp[0].lex.line }; - yyval.interm.type = t; - ;} - break; - - case 140: -#line 1494 "glslang.y" - { - TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; - TPublicType t = { EbtBool, qual, 2, false, false, 0, yyvsp[0].lex.line }; - yyval.interm.type = t; - ;} - break; - - case 141: -#line 1499 "glslang.y" - { - TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; - TPublicType t = { EbtBool, qual, 3, false, false, 0, yyvsp[0].lex.line }; - yyval.interm.type = t; - ;} - break; - - case 142: -#line 1504 "glslang.y" - { - TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; - TPublicType t = { EbtBool, qual, 4, false, false, 0, yyvsp[0].lex.line }; - yyval.interm.type = t; - ;} - break; - - case 143: -#line 1509 "glslang.y" - { - TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; - TPublicType t = { EbtInt, qual, 2, false, false, 0, yyvsp[0].lex.line }; - yyval.interm.type = t; - ;} - break; - - case 144: -#line 1514 "glslang.y" - { - TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; - TPublicType t = { EbtInt, qual, 3, false, false, 0, yyvsp[0].lex.line }; - yyval.interm.type = t; - ;} - break; - - case 145: -#line 1519 "glslang.y" - { - TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; - TPublicType t = { EbtInt, qual, 4, false, false, 0, yyvsp[0].lex.line }; - yyval.interm.type = t; - ;} - break; - - case 146: -#line 1524 "glslang.y" - { - FRAG_VERT_ONLY("mat2", yyvsp[0].lex.line); - TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; - TPublicType t = { EbtFloat, qual, 2, true, false, 0, yyvsp[0].lex.line }; - yyval.interm.type = t; - ;} - break; - - case 147: -#line 1530 "glslang.y" - { - FRAG_VERT_ONLY("mat3", yyvsp[0].lex.line); - TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; - TPublicType t = { EbtFloat, qual, 3, true, false, 0, yyvsp[0].lex.line }; - yyval.interm.type = t; - ;} - break; - - case 148: -#line 1536 "glslang.y" - { - FRAG_VERT_ONLY("mat4", yyvsp[0].lex.line); - TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; - TPublicType t = { EbtFloat, qual, 4, true, false, 0, yyvsp[0].lex.line }; - yyval.interm.type = t; - ;} - break; - - case 149: -#line 1542 "glslang.y" - { - FRAG_VERT_ONLY("sampler1D", yyvsp[0].lex.line); - TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; - TPublicType t = { EbtSampler1D, qual, 1, false, false, 0, yyvsp[0].lex.line }; - yyval.interm.type = t; - ;} - break; - - case 150: -#line 1548 "glslang.y" - { - FRAG_VERT_ONLY("sampler2D", yyvsp[0].lex.line); - TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; - TPublicType t = { EbtSampler2D, qual, 1, false, false, 0, yyvsp[0].lex.line }; - yyval.interm.type = t; - ;} - break; - - case 151: -#line 1554 "glslang.y" - { - FRAG_VERT_ONLY("sampler3D", yyvsp[0].lex.line); - TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; - TPublicType t = { EbtSampler3D, qual, 1, false, false, 0, yyvsp[0].lex.line }; - yyval.interm.type = t; - ;} - break; - - case 152: -#line 1560 "glslang.y" - { - FRAG_VERT_ONLY("samplerCube", yyvsp[0].lex.line); - TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; - TPublicType t = { EbtSamplerCube, qual, 1, false, false, 0, yyvsp[0].lex.line }; - yyval.interm.type = t; - ;} - break; - - case 153: -#line 1566 "glslang.y" - { - FRAG_VERT_ONLY("sampler1DShadow", yyvsp[0].lex.line); - TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; - TPublicType t = { EbtSampler1DShadow, qual, 1, false, false, 0, yyvsp[0].lex.line }; - yyval.interm.type = t; - ;} - break; - - case 154: -#line 1572 "glslang.y" - { - FRAG_VERT_ONLY("sampler2DShadow", yyvsp[0].lex.line); - TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; - TPublicType t = { EbtSampler2DShadow, qual, 1, false, false, 0, yyvsp[0].lex.line }; - yyval.interm.type = t; - ;} - break; - - case 155: -#line 1578 "glslang.y" - { - FRAG_VERT_ONLY("struct", yyvsp[0].interm.type.line); - yyval.interm.type = yyvsp[0].interm.type; - yyval.interm.type.qualifier = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; - ;} - break; - - case 156: -#line 1583 "glslang.y" - { - // - // This is for user defined type names. The lexical phase looked up the - // type. - // - TType& structure = static_cast<TVariable*>(yyvsp[0].lex.symbol)->getType(); - TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; - TPublicType t = { EbtStruct, qual, 1, false, false, &structure, yyvsp[0].lex.line }; - yyval.interm.type = t; - ;} - break; - - case 157: -#line 1596 "glslang.y" - { - TType* structure = new TType(yyvsp[-1].interm.typeList, *yyvsp[-3].lex.string); - TVariable* userTypeDef = new TVariable(yyvsp[-3].lex.string, *structure, true); - if (! parseContext.symbolTable.insert(*userTypeDef)) { - parseContext.error(yyvsp[-3].lex.line, "redefinition", yyvsp[-3].lex.string->c_str(), "struct"); - parseContext.recover(); - } - TPublicType t = { EbtStruct, EvqTemporary, 1, false, false, structure, yyvsp[-4].lex.line }; - yyval.interm.type = t; - ;} - break; - - case 158: -#line 1606 "glslang.y" - { - TType* structure = new TType(yyvsp[-1].interm.typeList, TString("")); - TPublicType t = { EbtStruct, EvqTemporary, 1, false, false, structure, yyvsp[-3].lex.line }; - yyval.interm.type = t; - ;} - break; - - case 159: -#line 1614 "glslang.y" - { - yyval.interm.typeList = yyvsp[0].interm.typeList; - ;} - break; - - case 160: -#line 1617 "glslang.y" - { - yyval.interm.typeList = yyvsp[-1].interm.typeList; - for (unsigned int i = 0; i < yyvsp[0].interm.typeList->size(); ++i) { - for (unsigned int j = 0; j < yyval.interm.typeList->size(); ++j) { - if ((*yyval.interm.typeList)[j].type->getFieldName() == (*yyvsp[0].interm.typeList)[i].type->getFieldName()) { - parseContext.error((*yyvsp[0].interm.typeList)[i].line, "duplicate field name in structure:", "struct", (*yyvsp[0].interm.typeList)[i].type->getFieldName().c_str()); - parseContext.recover(); - } - } - yyval.interm.typeList->push_back((*yyvsp[0].interm.typeList)[i]); - } - ;} - break; - - case 161: -#line 1632 "glslang.y" - { - yyval.interm.typeList = yyvsp[-1].interm.typeList; - - if (parseContext.voidErrorCheck(yyvsp[-2].interm.type.line, (*yyvsp[-1].interm.typeList)[0].type->getFieldName(), yyvsp[-2].interm.type)) { - parseContext.recover(); - } - for (unsigned int i = 0; i < yyval.interm.typeList->size(); ++i) { - // - // Careful not to replace already know aspects of type, like array-ness - // - (*yyval.interm.typeList)[i].type->setType(yyvsp[-2].interm.type.type, yyvsp[-2].interm.type.size, yyvsp[-2].interm.type.matrix, yyvsp[-2].interm.type.userDef); - if (yyvsp[-2].interm.type.userDef) - (*yyval.interm.typeList)[i].type->setTypeName(yyvsp[-2].interm.type.userDef->getTypeName()); - } - ;} - break; - - case 162: -#line 1650 "glslang.y" - { - yyval.interm.typeList = NewPoolTTypeList(); - yyval.interm.typeList->push_back(yyvsp[0].interm.typeLine); - ;} - break; - - case 163: -#line 1654 "glslang.y" - { - yyval.interm.typeList->push_back(yyvsp[0].interm.typeLine); - ;} - break; - - case 164: -#line 1660 "glslang.y" - { - yyval.interm.typeLine.type = new TType(EbtVoid); - yyval.interm.typeLine.line = yyvsp[0].lex.line; - yyval.interm.typeLine.type->setFieldName(*yyvsp[0].lex.string); - ;} - break; - - case 165: -#line 1665 "glslang.y" - { - yyval.interm.typeLine.type = new TType(EbtVoid); - yyval.interm.typeLine.line = yyvsp[-3].lex.line; - yyval.interm.typeLine.type->setFieldName(*yyvsp[-3].lex.string); - - if (yyvsp[-1].interm.intermTypedNode->getAsConstantUnion() == 0 || yyvsp[-1].interm.intermTypedNode->getAsConstantUnion()->getBasicType() != EbtInt || - yyvsp[-1].interm.intermTypedNode->getAsConstantUnion()->getUnionArrayPointer()->iConst <= 0) { - parseContext.error(yyvsp[-2].lex.line, "structure field array size must be a positive integer", yyvsp[-3].lex.string->c_str(), ""); - parseContext.recover(); - } else { - yyval.interm.typeLine.type->setArraySize(yyvsp[-1].interm.intermTypedNode->getAsConstantUnion()->getUnionArrayPointer()->iConst); - } - ;} - break; - - case 166: -#line 1681 "glslang.y" - { yyval.interm.intermTypedNode = yyvsp[0].interm.intermTypedNode; ;} - break; - - case 167: -#line 1685 "glslang.y" - { yyval.interm.intermNode = yyvsp[0].interm.intermNode; ;} - break; - - case 168: -#line 1689 "glslang.y" - { yyval.interm.intermNode = yyvsp[0].interm.intermAggregate; ;} - break; - - case 169: -#line 1690 "glslang.y" - { yyval.interm.intermNode = yyvsp[0].interm.intermNode; ;} - break; - - case 170: -#line 1696 "glslang.y" - { yyval.interm.intermNode = yyvsp[0].interm.intermNode; ;} - break; - - case 171: -#line 1697 "glslang.y" - { yyval.interm.intermNode = yyvsp[0].interm.intermNode; ;} - break; - - case 172: -#line 1698 "glslang.y" - { yyval.interm.intermNode = yyvsp[0].interm.intermNode; ;} - break; - - case 173: -#line 1699 "glslang.y" - { yyval.interm.intermNode = yyvsp[0].interm.intermNode; ;} - break; - - case 174: -#line 1700 "glslang.y" - { yyval.interm.intermNode = yyvsp[0].interm.intermNode; ;} - break; - - case 175: -#line 1704 "glslang.y" - { yyval.interm.intermAggregate = 0; ;} - break; - - case 176: -#line 1705 "glslang.y" - { parseContext.symbolTable.push(); ;} - break; - - case 177: -#line 1705 "glslang.y" - { parseContext.symbolTable.pop(); ;} - break; - - case 178: -#line 1705 "glslang.y" - { - if (yyvsp[-2].interm.intermAggregate != 0) - yyvsp[-2].interm.intermAggregate->setOperator(EOpSequence); - yyval.interm.intermAggregate = yyvsp[-2].interm.intermAggregate; - ;} - break; - - case 179: -#line 1713 "glslang.y" - { yyval.interm.intermNode = yyvsp[0].interm.intermNode; ;} - break; - - case 180: -#line 1714 "glslang.y" - { yyval.interm.intermNode = yyvsp[0].interm.intermNode; ;} - break; - - case 181: -#line 1719 "glslang.y" - { - yyval.interm.intermNode = 0; - ;} - break; - - case 182: -#line 1722 "glslang.y" - { - if (yyvsp[-1].interm.intermAggregate) - yyvsp[-1].interm.intermAggregate->setOperator(EOpSequence); - yyval.interm.intermNode = yyvsp[-1].interm.intermAggregate; - ;} - break; - - case 183: -#line 1730 "glslang.y" - { - yyval.interm.intermAggregate = parseContext.intermediate.makeAggregate(yyvsp[0].interm.intermNode, 0); - ;} - break; - - case 184: -#line 1733 "glslang.y" - { - yyval.interm.intermAggregate = parseContext.intermediate.growAggregate(yyvsp[-1].interm.intermAggregate, yyvsp[0].interm.intermNode, 0); - ;} - break; - - case 185: -#line 1739 "glslang.y" - { yyval.interm.intermNode = 0; ;} - break; - - case 186: -#line 1740 "glslang.y" - { yyval.interm.intermNode = static_cast<TIntermNode*>(yyvsp[-1].interm.intermTypedNode); ;} - break; - - case 187: -#line 1744 "glslang.y" - { - if (parseContext.boolErrorCheck(yyvsp[-4].lex.line, yyvsp[-2].interm.intermTypedNode)) - parseContext.recover(); - yyval.interm.intermNode = parseContext.intermediate.addSelection(yyvsp[-2].interm.intermTypedNode, yyvsp[0].interm.nodePair, yyvsp[-4].lex.line); - ;} - break; - - case 188: -#line 1752 "glslang.y" - { - yyval.interm.nodePair.node1 = yyvsp[-2].interm.intermNode; - yyval.interm.nodePair.node2 = yyvsp[0].interm.intermNode; - ;} - break; - - case 189: -#line 1756 "glslang.y" - { - yyval.interm.nodePair.node1 = yyvsp[0].interm.intermNode; - yyval.interm.nodePair.node2 = 0; - ;} - break; - - case 190: -#line 1766 "glslang.y" - { - yyval.interm.intermTypedNode = yyvsp[0].interm.intermTypedNode; - if (parseContext.boolErrorCheck(yyvsp[0].interm.intermTypedNode->getLine(), yyvsp[0].interm.intermTypedNode)) - parseContext.recover(); - ;} - break; - - case 191: -#line 1771 "glslang.y" - { - TIntermNode* intermNode; - if (parseContext.structQualifierErrorCheck(yyvsp[-2].lex.line, yyvsp[-3].interm.type)) - parseContext.recover(); - if (parseContext.boolErrorCheck(yyvsp[-2].lex.line, yyvsp[-3].interm.type)) - parseContext.recover(); - - if (!parseContext.executeInitializer(yyvsp[-2].lex.line, *yyvsp[-2].lex.string, yyvsp[-3].interm.type, yyvsp[0].interm.intermTypedNode, intermNode)) - yyval.interm.intermTypedNode = yyvsp[0].interm.intermTypedNode; - else { - parseContext.recover(); - yyval.interm.intermTypedNode = 0; - } - ;} - break; - - case 192: -#line 1788 "glslang.y" - { parseContext.symbolTable.push(); ++parseContext.loopNestingLevel; ;} - break; - - case 193: -#line 1788 "glslang.y" - { - parseContext.symbolTable.pop(); - yyval.interm.intermNode = parseContext.intermediate.addLoop(yyvsp[0].interm.intermNode, yyvsp[-2].interm.intermTypedNode, 0, true, yyvsp[-5].lex.line); - --parseContext.loopNestingLevel; - ;} - break; - - case 194: -#line 1793 "glslang.y" - { ++parseContext.loopNestingLevel; ;} - break; - - case 195: -#line 1793 "glslang.y" - { - if (parseContext.boolErrorCheck(yyvsp[0].lex.line, yyvsp[-2].interm.intermTypedNode)) - parseContext.recover(); - - yyval.interm.intermNode = parseContext.intermediate.addLoop(yyvsp[-5].interm.intermNode, yyvsp[-2].interm.intermTypedNode, 0, false, yyvsp[-4].lex.line); - --parseContext.loopNestingLevel; - ;} - break; - - case 196: -#line 1800 "glslang.y" - { parseContext.symbolTable.push(); ++parseContext.loopNestingLevel; ;} - break; - - case 197: -#line 1800 "glslang.y" - { - parseContext.symbolTable.pop(); - yyval.interm.intermNode = parseContext.intermediate.makeAggregate(yyvsp[-3].interm.intermNode, yyvsp[-5].lex.line); - yyval.interm.intermNode = parseContext.intermediate.growAggregate( - yyval.interm.intermNode, - parseContext.intermediate.addLoop(yyvsp[0].interm.intermNode, reinterpret_cast<TIntermTyped*>(yyvsp[-2].interm.nodePair.node1), reinterpret_cast<TIntermTyped*>(yyvsp[-2].interm.nodePair.node2), true, yyvsp[-6].lex.line), - yyvsp[-6].lex.line); - yyval.interm.intermNode->getAsAggregate()->setOperator(EOpSequence); - --parseContext.loopNestingLevel; - ;} - break; - - case 198: -#line 1813 "glslang.y" - { - yyval.interm.intermNode = yyvsp[0].interm.intermNode; - ;} - break; - - case 199: -#line 1816 "glslang.y" - { - yyval.interm.intermNode = yyvsp[0].interm.intermNode; - ;} - break; - - case 200: -#line 1822 "glslang.y" - { - yyval.interm.intermTypedNode = yyvsp[0].interm.intermTypedNode; - ;} - break; - - case 201: -#line 1825 "glslang.y" - { - yyval.interm.intermTypedNode = 0; - ;} - break; - - case 202: -#line 1831 "glslang.y" - { - yyval.interm.nodePair.node1 = yyvsp[-1].interm.intermTypedNode; - yyval.interm.nodePair.node2 = 0; - ;} - break; - - case 203: -#line 1835 "glslang.y" - { - yyval.interm.nodePair.node1 = yyvsp[-2].interm.intermTypedNode; - yyval.interm.nodePair.node2 = yyvsp[0].interm.intermTypedNode; - ;} - break; - - case 204: -#line 1842 "glslang.y" - { - if (parseContext.loopNestingLevel <= 0) { - parseContext.error(yyvsp[-1].lex.line, "continue statement only allowed in loops", "", ""); - parseContext.recover(); - } - yyval.interm.intermNode = parseContext.intermediate.addBranch(EOpContinue, yyvsp[-1].lex.line); - ;} - break; - - case 205: -#line 1849 "glslang.y" - { - if (parseContext.loopNestingLevel <= 0) { - parseContext.error(yyvsp[-1].lex.line, "break statement only allowed in loops", "", ""); - parseContext.recover(); - } - yyval.interm.intermNode = parseContext.intermediate.addBranch(EOpBreak, yyvsp[-1].lex.line); - ;} - break; - - case 206: -#line 1856 "glslang.y" - { - yyval.interm.intermNode = parseContext.intermediate.addBranch(EOpReturn, yyvsp[-1].lex.line); - if (parseContext.currentFunctionType->getBasicType() != EbtVoid) { - parseContext.error(yyvsp[-1].lex.line, "non-void function must return a value", "return", ""); - parseContext.recover(); - } - ;} - break; - - case 207: -#line 1863 "glslang.y" - { - yyval.interm.intermNode = parseContext.intermediate.addBranch(EOpReturn, yyvsp[-1].interm.intermTypedNode, yyvsp[-2].lex.line); - parseContext.functionReturnsValue = true; - if (parseContext.currentFunctionType->getBasicType() == EbtVoid) { - parseContext.error(yyvsp[-2].lex.line, "void function cannot return a value", "return", ""); - parseContext.recover(); - } else if (*(parseContext.currentFunctionType) != yyvsp[-1].interm.intermTypedNode->getType()) { - parseContext.error(yyvsp[-2].lex.line, "function return is not matching type:", "return", ""); - parseContext.recover(); - } - ;} - break; - - case 208: -#line 1874 "glslang.y" - { - FRAG_ONLY("discard", yyvsp[-1].lex.line); - yyval.interm.intermNode = parseContext.intermediate.addBranch(EOpKill, yyvsp[-1].lex.line); - ;} - break; - - case 209: -#line 1883 "glslang.y" - { - yyval.interm.intermNode = yyvsp[0].interm.intermNode; - parseContext.treeRoot = yyval.interm.intermNode; - ;} - break; - - case 210: -#line 1887 "glslang.y" - { - yyval.interm.intermNode = parseContext.intermediate.growAggregate(yyvsp[-1].interm.intermNode, yyvsp[0].interm.intermNode, 0); - parseContext.treeRoot = yyval.interm.intermNode; - ;} - break; - - case 211: -#line 1894 "glslang.y" - { - yyval.interm.intermNode = yyvsp[0].interm.intermNode; - ;} - break; - - case 212: -#line 1897 "glslang.y" - { - yyval.interm.intermNode = yyvsp[0].interm.intermNode; - ;} - break; - - case 213: -#line 1903 "glslang.y" - { - TFunction& function = *(yyvsp[0].interm.function); - TFunction* prevDec = static_cast<TFunction*>(parseContext.symbolTable.find(function.getMangledName())); - // - // Note: 'prevDec' could be 'function' if this is the first time we've seen function - // as it would have just been put in the symbol table. Otherwise, we're looking up - // an earlier occurance. - // - if (prevDec->isDefined()) { - // - // Then this function already has a body. - // - parseContext.error(yyvsp[0].interm.line, "function already has a body", function.getName().c_str(), ""); - parseContext.recover(); - } - prevDec->setDefined(); - - // - // Raise error message if main function takes any parameters or return anything other than void - // - if (function.getName() == "main") { - if (function.getParamCount() > 0) { - parseContext.error(yyvsp[0].interm.line, "function cannot take any parameter(s)", function.getName().c_str(), ""); - parseContext.recover(); - } - if (function.getReturnType().getBasicType() != EbtVoid) { - parseContext.error(yyvsp[0].interm.line, "", function.getReturnType().getBasicString(), "main function cannot return a value" ); - parseContext.recover(); - } - } - - // - // New symbol table scope for body of function plus its arguments - // - parseContext.symbolTable.push(); - - // - // Remember the return type for later checking for RETURN statements. - // - parseContext.currentFunctionType = &(prevDec->getReturnType()); - parseContext.functionReturnsValue = false; - - // - // Insert parameters into the symbol table. - // If the parameter has no name, it's not an error, just don't insert it - // (could be used for unused args). - // - // Also, accumulate the list of parameters into the HIL, so lower level code - // knows where to find parameters. - // - TIntermAggregate* paramNodes = new TIntermAggregate; - for (int i = 0; i < function.getParamCount(); i++) { - TParameter& param = function[i]; - if (param.name != 0) { - TVariable *variable = new TVariable(param.name, *param.type); - // - // Insert the parameters with name in the symbol table. - // - if (! parseContext.symbolTable.insert(*variable)) { - parseContext.error(yyvsp[0].interm.line, "redefinition", variable->getName().c_str(), ""); - parseContext.recover(); - delete variable; - } - // - // Transfer ownership of name pointer to symbol table. - // - param.name = 0; - - // - // Add the parameter to the HIL - // - paramNodes = parseContext.intermediate.growAggregate( - paramNodes, - parseContext.intermediate.addSymbol(variable->getUniqueId(), - variable->getName(), - variable->getType(), yyvsp[0].interm.line), - yyvsp[0].interm.line); - } else { - paramNodes = parseContext.intermediate.growAggregate(paramNodes, parseContext.intermediate.addSymbol(0, "", *param.type, yyvsp[0].interm.line), yyvsp[0].interm.line); - } - } - parseContext.intermediate.setAggregateOperator(paramNodes, EOpParameters, yyvsp[0].interm.line); - yyvsp[0].interm.intermAggregate = paramNodes; - parseContext.loopNestingLevel = 0; - ;} - break; - - case 214: -#line 1988 "glslang.y" - { - //?? Check that all paths return a value if return type != void ? - // May be best done as post process phase on intermediate code - if (parseContext.currentFunctionType->getBasicType() != EbtVoid && ! parseContext.functionReturnsValue) { - parseContext.error(yyvsp[-2].interm.line, "function does not return a value:", "", yyvsp[-2].interm.function->getName().c_str()); - parseContext.recover(); - } - parseContext.symbolTable.pop(); - yyval.interm.intermNode = parseContext.intermediate.growAggregate(yyvsp[-2].interm.intermAggregate, yyvsp[0].interm.intermNode, 0); - parseContext.intermediate.setAggregateOperator(yyval.interm.intermNode, EOpFunction, yyvsp[-2].interm.line); - yyval.interm.intermNode->getAsAggregate()->setName(yyvsp[-2].interm.function->getMangledName().c_str()); - yyval.interm.intermNode->getAsAggregate()->setType(yyvsp[-2].interm.function->getReturnType()); - - // store the pragma information for debug and optimize and other vendor specific - // information. This information can be queried from the parse tree - yyval.interm.intermNode->getAsAggregate()->setOptimize(parseContext.contextPragma.optimize); - yyval.interm.intermNode->getAsAggregate()->setDebug(parseContext.contextPragma.debug); - yyval.interm.intermNode->getAsAggregate()->addToPragmaTable(parseContext.contextPragma.pragmaTable); - ;} - break; - - - } - -/* Line 999 of yacc.c. */ -#line 4158 "glslang.tab.c" - - yyvsp -= yylen; - yyssp -= yylen; - - - YY_STACK_PRINT (yyss, yyssp); - - *++yyvsp = yyval; - - - /* Now `shift' the result of the reduction. Determine what state - that goes to, based on the state we popped back to and the rule - number reduced by. */ - - yyn = yyr1[yyn]; - - yystate = yypgoto[yyn - YYNTOKENS] + *yyssp; - if (0 <= yystate && yystate <= YYLAST && yycheck[yystate] == *yyssp) - yystate = yytable[yystate]; - else - yystate = yydefgoto[yyn - YYNTOKENS]; - - goto yynewstate; - - -/*------------------------------------. -| yyerrlab -- here on detecting error | -`------------------------------------*/ -yyerrlab: - /* If not already recovering from an error, report this error. */ - if (!yyerrstatus) - { - ++yynerrs; -#if YYERROR_VERBOSE - yyn = yypact[yystate]; - - if (YYPACT_NINF < yyn && yyn < YYLAST) - { - YYSIZE_T yysize = 0; - int yytype = YYTRANSLATE (yychar); - char *yymsg; - int yyx, yycount; - - yycount = 0; - /* Start YYX at -YYN if negative to avoid negative indexes in - YYCHECK. */ - for (yyx = yyn < 0 ? -yyn : 0; - yyx < (int) (sizeof (yytname) / sizeof (char *)); yyx++) - if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR) - yysize += yystrlen (yytname[yyx]) + 15, yycount++; - yysize += yystrlen ("syntax error, unexpected ") + 1; - yysize += yystrlen (yytname[yytype]); - yymsg = (char *) YYSTACK_ALLOC (yysize); - if (yymsg != 0) - { - char *yyp = yystpcpy (yymsg, "syntax error, unexpected "); - yyp = yystpcpy (yyp, yytname[yytype]); - - if (yycount < 5) - { - yycount = 0; - for (yyx = yyn < 0 ? -yyn : 0; - yyx < (int) (sizeof (yytname) / sizeof (char *)); - yyx++) - if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR) - { - const char *yyq = ! yycount ? ", expecting " : " or "; - yyp = yystpcpy (yyp, yyq); - yyp = yystpcpy (yyp, yytname[yyx]); - yycount++; - } - } - yyerror (yymsg); - YYSTACK_FREE (yymsg); - } - else - yyerror ("syntax error; also virtual memory exhausted"); - } - else -#endif /* YYERROR_VERBOSE */ - yyerror ("syntax error"); - } - - - - if (yyerrstatus == 3) - { - /* If just tried and failed to reuse lookahead token after an - error, discard it. */ - - /* Return failure if at end of input. */ - if (yychar == YYEOF) - { - /* Pop the error token. */ - YYPOPSTACK; - /* Pop the rest of the stack. */ - while (yyss < yyssp) - { - YYDSYMPRINTF ("Error: popping", yystos[*yyssp], yyvsp, yylsp); - yydestruct (yystos[*yyssp], yyvsp); - YYPOPSTACK; - } - YYABORT; - } - - YYDSYMPRINTF ("Error: discarding", yytoken, &yylval, &yylloc); - yydestruct (yytoken, &yylval); - yychar = YYEMPTY; - - } - - /* Else will try to reuse lookahead token after shifting the error - token. */ - goto yyerrlab1; - - -/*----------------------------------------------------. -| yyerrlab1 -- error raised explicitly by an action. | -`----------------------------------------------------*/ -yyerrlab1: - yyerrstatus = 3; /* Each real token shifted decrements this. */ - - for (;;) - { - yyn = yypact[yystate]; - if (yyn != YYPACT_NINF) - { - yyn += YYTERROR; - if (0 <= yyn && yyn <= YYLAST && yycheck[yyn] == YYTERROR) - { - yyn = yytable[yyn]; - if (0 < yyn) - break; - } - } - - /* Pop the current state because it cannot handle the error token. */ - if (yyssp == yyss) - YYABORT; - - YYDSYMPRINTF ("Error: popping", yystos[*yyssp], yyvsp, yylsp); - yydestruct (yystos[yystate], yyvsp); - yyvsp--; - yystate = *--yyssp; - - YY_STACK_PRINT (yyss, yyssp); - } - - if (yyn == YYFINAL) - YYACCEPT; - - YYDPRINTF ((stderr, "Shifting error token, ")); - - *++yyvsp = yylval; - - - yystate = yyn; - goto yynewstate; - - -/*-------------------------------------. -| yyacceptlab -- YYACCEPT comes here. | -`-------------------------------------*/ -yyacceptlab: - yyresult = 0; - goto yyreturn; - -/*-----------------------------------. -| yyabortlab -- YYABORT comes here. | -`-----------------------------------*/ -yyabortlab: - yyresult = 1; - goto yyreturn; - -#ifndef yyoverflow -/*----------------------------------------------. -| yyoverflowlab -- parser overflow comes here. | -`----------------------------------------------*/ -yyoverflowlab: - yyerror ("parser stack overflow"); - yyresult = 2; - /* Fall through. */ -#endif - -yyreturn: -#ifndef yyoverflow - if (yyss != yyssa) - YYSTACK_FREE (yyss); -#endif - return yyresult; -} - - -#line 209 "glslang.y" - - diff --git a/src/mesa/shader/slang/MachineIndependent/InfoSink.cpp b/src/mesa/shader/slang/MachineIndependent/InfoSink.cpp deleted file mode 100755 index 9a1aaa26f9..0000000000 --- a/src/mesa/shader/slang/MachineIndependent/InfoSink.cpp +++ /dev/null @@ -1,107 +0,0 @@ -//
-//Copyright (C) 2002-2005 3Dlabs Inc. Ltd.
-//All rights reserved.
-//
-//Redistribution and use in source and binary forms, with or without
-//modification, are permitted provided that the following conditions
-//are met:
-//
-// Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//
-// Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-//
-// Neither the name of 3Dlabs Inc. Ltd. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-//THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-//"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-//LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
-//FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
-//COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
-//INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
-//BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
-//LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
-//CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-//LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
-//ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
-//POSSIBILITY OF SUCH DAMAGE.
-//
-
-#include "Include/InfoSink.h"
-
-#ifdef _WIN32
- #include <windows.h>
-#endif
-
-void TInfoSinkBase::append(const char *s)
-{
- if (outputStream & EString) {
- checkMem(strlen(s));
- sink.append(s);
- }
-
-#ifdef _WIN32
- if (outputStream & EDebugger)
- OutputDebugString(s);
-#endif
-
- if (outputStream & EStdOut)
- fprintf(stdout, "%s", s);
-}
-
-void TInfoSinkBase::append(int count, char c)
-{
- if (outputStream & EString) {
- checkMem(count);
- sink.append(count, c);
- }
-
-#ifdef _WIN32
- if (outputStream & EDebugger) {
- char str[2];
- str[0] = c;
- str[1] = '\0';
- OutputDebugString(str);
- }
-#endif
-
- if (outputStream & EStdOut)
- fprintf(stdout, "%c", c);
-}
-
-void TInfoSinkBase::append(const TPersistString& t)
-{
- if (outputStream & EString) {
- checkMem(t.size());
- sink.append(t);
- }
-
-#ifdef _WIN32
- if (outputStream & EDebugger)
- OutputDebugString(t.c_str());
-#endif
-
- if (outputStream & EStdOut)
- fprintf(stdout, "%s", t.c_str());
-}
-
-void TInfoSinkBase::append(const TString& t)
-{
- if (outputStream & EString) {
- checkMem(t.size());
- sink.append(t.c_str());
- }
-
-#ifdef _WIN32
- if (outputStream & EDebugger)
- OutputDebugString(t.c_str());
-#endif
-
- if (outputStream & EStdOut)
- fprintf(stdout, "%s", t.c_str());
-}
diff --git a/src/mesa/shader/slang/MachineIndependent/Initialize.cpp b/src/mesa/shader/slang/MachineIndependent/Initialize.cpp deleted file mode 100755 index 0913e531af..0000000000 --- a/src/mesa/shader/slang/MachineIndependent/Initialize.cpp +++ /dev/null @@ -1,948 +0,0 @@ -//
-//Copyright (C) 2002-2005 3Dlabs Inc. Ltd.
-//All rights reserved.
-//
-//Redistribution and use in source and binary forms, with or without
-//modification, are permitted provided that the following conditions
-//are met:
-//
-// Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//
-// Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-//
-// Neither the name of 3Dlabs Inc. Ltd. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-//THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-//"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-//LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
-//FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
-//COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
-//INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
-//BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
-//LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
-//CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-//LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
-//ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
-//POSSIBILITY OF SUCH DAMAGE.
-//
-
-//
-// Create strings that declare built-in definitions, add built-ins that
-// cannot be expressed in the files, and establish mappings between
-// built-in functions and operators.
-//
-
-#include "../Include/intermediate.h"
-#include "Initialize.h"
-
-void TBuiltIns::initialize()
-{
- //
- // Initialize all the built-in strings for parsing.
- //
- TString BuiltInFunctions;
- TString BuiltInFunctionsVertex;
- TString BuiltInFunctionsFragment;
- TString StandardVertexVaryings;
- TString StandardFragmentVaryings;
- TString StandardVertexAttributes;
- TString StandardUniforms;
-
- {
- //============================================================================
- //
- // Prototypes for built-in functions seen by both vertex and fragment shaders.
- //
- //============================================================================
-
- TString& s = BuiltInFunctions;
-
- //
- // Angle and Trigonometric Functions.
- //
- s.append(TString("float radians(float degrees);"));
- s.append(TString("vec2 radians(vec2 degrees);"));
- s.append(TString("vec3 radians(vec3 degrees);"));
- s.append(TString("vec4 radians(vec4 degrees);"));
-
- s.append(TString("float degrees(float radians);"));
- s.append(TString("vec2 degrees(vec2 radians);"));
- s.append(TString("vec3 degrees(vec3 radians);"));
- s.append(TString("vec4 degrees(vec4 radians);"));
-
- s.append(TString("float sin(float angle);"));
- s.append(TString("vec2 sin(vec2 angle);"));
- s.append(TString("vec3 sin(vec3 angle);"));
- s.append(TString("vec4 sin(vec4 angle);"));
-
- s.append(TString("float cos(float angle);"));
- s.append(TString("vec2 cos(vec2 angle);"));
- s.append(TString("vec3 cos(vec3 angle);"));
- s.append(TString("vec4 cos(vec4 angle);"));
-
- s.append(TString("float tan(float angle);"));
- s.append(TString("vec2 tan(vec2 angle);"));
- s.append(TString("vec3 tan(vec3 angle);"));
- s.append(TString("vec4 tan(vec4 angle);"));
-
- s.append(TString("float asin(float x);"));
- s.append(TString("vec2 asin(vec2 x);"));
- s.append(TString("vec3 asin(vec3 x);"));
- s.append(TString("vec4 asin(vec4 x);"));
-
- s.append(TString("float acos(float x);"));
- s.append(TString("vec2 acos(vec2 x);"));
- s.append(TString("vec3 acos(vec3 x);"));
- s.append(TString("vec4 acos(vec4 x);"));
-
- s.append(TString("float atan(float y, float x);"));
- s.append(TString("vec2 atan(vec2 y, vec2 x);"));
- s.append(TString("vec3 atan(vec3 y, vec3 x);"));
- s.append(TString("vec4 atan(vec4 y, vec4 x);"));
-
- s.append(TString("float atan(float y_over_x);"));
- s.append(TString("vec2 atan(vec2 y_over_x);"));
- s.append(TString("vec3 atan(vec3 y_over_x);"));
- s.append(TString("vec4 atan(vec4 y_over_x);"));
-
- //
- // Exponential Functions.
- //
- s.append(TString("float pow(float x, float y);"));
- s.append(TString("vec2 pow(vec2 x, vec2 y);"));
- s.append(TString("vec3 pow(vec3 x, vec3 y);"));
- s.append(TString("vec4 pow(vec4 x, vec4 y);"));
-
- s.append(TString("float exp(float x);"));
- s.append(TString("vec2 exp(vec2 x);"));
- s.append(TString("vec3 exp(vec3 x);"));
- s.append(TString("vec4 exp(vec4 x);"));
-
- s.append(TString("float log(float x);"));
- s.append(TString("vec2 log(vec2 x);"));
- s.append(TString("vec3 log(vec3 x);"));
- s.append(TString("vec4 log(vec4 x);"));
-
- s.append(TString("float exp2(float x);"));
- s.append(TString("vec2 exp2(vec2 x);"));
- s.append(TString("vec3 exp2(vec3 x);"));
- s.append(TString("vec4 exp2(vec4 x);"));
-
- s.append(TString("float log2(float x);"));
- s.append(TString("vec2 log2(vec2 x);"));
- s.append(TString("vec3 log2(vec3 x);"));
- s.append(TString("vec4 log2(vec4 x);"));
-
- s.append(TString("float sqrt(float x);"));
- s.append(TString("vec2 sqrt(vec2 x);"));
- s.append(TString("vec3 sqrt(vec3 x);"));
- s.append(TString("vec4 sqrt(vec4 x);"));
-
- s.append(TString("float inversesqrt(float x);"));
- s.append(TString("vec2 inversesqrt(vec2 x);"));
- s.append(TString("vec3 inversesqrt(vec3 x);"));
- s.append(TString("vec4 inversesqrt(vec4 x);"));
-
- //
- // Common Functions.
- //
- s.append(TString("float abs(float x);"));
- s.append(TString("vec2 abs(vec2 x);"));
- s.append(TString("vec3 abs(vec3 x);"));
- s.append(TString("vec4 abs(vec4 x);"));
-
- s.append(TString("float sign(float x);"));
- s.append(TString("vec2 sign(vec2 x);"));
- s.append(TString("vec3 sign(vec3 x);"));
- s.append(TString("vec4 sign(vec4 x);"));
-
- s.append(TString("float floor(float x);"));
- s.append(TString("vec2 floor(vec2 x);"));
- s.append(TString("vec3 floor(vec3 x);"));
- s.append(TString("vec4 floor(vec4 x);"));
-
- s.append(TString("float ceil(float x);"));
- s.append(TString("vec2 ceil(vec2 x);"));
- s.append(TString("vec3 ceil(vec3 x);"));
- s.append(TString("vec4 ceil(vec4 x);"));
-
- s.append(TString("float fract(float x);"));
- s.append(TString("vec2 fract(vec2 x);"));
- s.append(TString("vec3 fract(vec3 x);"));
- s.append(TString("vec4 fract(vec4 x);"));
-
- s.append(TString("float mod(float x, float y);"));
- s.append(TString("vec2 mod(vec2 x, float y);"));
- s.append(TString("vec3 mod(vec3 x, float y);"));
- s.append(TString("vec4 mod(vec4 x, float y);"));
- s.append(TString("vec2 mod(vec2 x, vec2 y);"));
- s.append(TString("vec3 mod(vec3 x, vec3 y);"));
- s.append(TString("vec4 mod(vec4 x, vec4 y);"));
-
- s.append(TString("float min(float x, float y);"));
- s.append(TString("vec2 min(vec2 x, float y);"));
- s.append(TString("vec3 min(vec3 x, float y);"));
- s.append(TString("vec4 min(vec4 x, float y);"));
- s.append(TString("vec2 min(vec2 x, vec2 y);"));
- s.append(TString("vec3 min(vec3 x, vec3 y);"));
- s.append(TString("vec4 min(vec4 x, vec4 y);"));
-
- s.append(TString("float max(float x, float y);"));
- s.append(TString("vec2 max(vec2 x, float y);"));
- s.append(TString("vec3 max(vec3 x, float y);"));
- s.append(TString("vec4 max(vec4 x, float y);"));
- s.append(TString("vec2 max(vec2 x, vec2 y);"));
- s.append(TString("vec3 max(vec3 x, vec3 y);"));
- s.append(TString("vec4 max(vec4 x, vec4 y);"));
-
- s.append(TString("float clamp(float x, float minVal, float maxVal);"));
- s.append(TString("vec2 clamp(vec2 x, float minVal, float maxVal);"));
- s.append(TString("vec3 clamp(vec3 x, float minVal, float maxVal);"));
- s.append(TString("vec4 clamp(vec4 x, float minVal, float maxVal);"));
- s.append(TString("vec2 clamp(vec2 x, vec2 minVal, vec2 maxVal);"));
- s.append(TString("vec3 clamp(vec3 x, vec3 minVal, vec3 maxVal);"));
- s.append(TString("vec4 clamp(vec4 x, vec4 minVal, vec4 maxVal);"));
-
- s.append(TString("float mix(float x, float y, float a);"));
- s.append(TString("vec2 mix(vec2 x, vec2 y, float a);"));
- s.append(TString("vec3 mix(vec3 x, vec3 y, float a);"));
- s.append(TString("vec4 mix(vec4 x, vec4 y, float a);"));
- s.append(TString("vec2 mix(vec2 x, vec2 y, vec2 a);"));
- s.append(TString("vec3 mix(vec3 x, vec3 y, vec3 a);"));
- s.append(TString("vec4 mix(vec4 x, vec4 y, vec4 a);"));
-
- s.append(TString("float step(float edge, float x);"));
- s.append(TString("vec2 step(vec2 edge, vec2 x);"));
- s.append(TString("vec3 step(vec3 edge, vec3 x);"));
- s.append(TString("vec4 step(vec4 edge, vec4 x);"));
- s.append(TString("vec2 step(float edge, vec2 x);"));
- s.append(TString("vec3 step(float edge, vec3 x);"));
- s.append(TString("vec4 step(float edge, vec4 x);"));
-
- s.append(TString("float smoothstep(float edge0, float edge1, float x);"));
- s.append(TString("vec2 smoothstep(vec2 edge0, vec2 edge1, vec2 x);"));
- s.append(TString("vec3 smoothstep(vec3 edge0, vec3 edge1, vec3 x);"));
- s.append(TString("vec4 smoothstep(vec4 edge0, vec4 edge1, vec4 x);"));
- s.append(TString("vec2 smoothstep(float edge0, float edge1, vec2 x);"));
- s.append(TString("vec3 smoothstep(float edge0, float edge1, vec3 x);"));
- s.append(TString("vec4 smoothstep(float edge0, float edge1, vec4 x);"));
-
- //
- // Geometric Functions.
- //
- s.append(TString("float length(float x);"));
- s.append(TString("float length(vec2 x);"));
- s.append(TString("float length(vec3 x);"));
- s.append(TString("float length(vec4 x);"));
-
- s.append(TString("float distance(float p0, float p1);"));
- s.append(TString("float distance(vec2 p0, vec2 p1);"));
- s.append(TString("float distance(vec3 p0, vec3 p1);"));
- s.append(TString("float distance(vec4 p0, vec4 p1);"));
-
- s.append(TString("float dot(float x, float y);"));
- s.append(TString("float dot(vec2 x, vec2 y);"));
- s.append(TString("float dot(vec3 x, vec3 y);"));
- s.append(TString("float dot(vec4 x, vec4 y);"));
-
- s.append(TString("vec3 cross(vec3 x, vec3 y);"));
- s.append(TString("float normalize(float x);"));
- s.append(TString("vec2 normalize(vec2 x);"));
- s.append(TString("vec3 normalize(vec3 x);"));
- s.append(TString("vec4 normalize(vec4 x);"));
-
- s.append(TString("float faceforward(float N, float I, float Nref);"));
- s.append(TString("vec2 faceforward(vec2 N, vec2 I, vec2 Nref);"));
- s.append(TString("vec3 faceforward(vec3 N, vec3 I, vec3 Nref);"));
- s.append(TString("vec4 faceforward(vec4 N, vec4 I, vec4 Nref);"));
-
- s.append(TString("float reflect(float I, float N);"));
- s.append(TString("vec2 reflect(vec2 I, vec2 N);"));
- s.append(TString("vec3 reflect(vec3 I, vec3 N);"));
- s.append(TString("vec4 reflect(vec4 I, vec4 N);"));
-
- s.append(TString("float refract(float I, float N, float eta);"));
- s.append(TString("vec2 refract(vec2 I, vec2 N, float eta);"));
- s.append(TString("vec3 refract(vec3 I, vec3 N, float eta);"));
- s.append(TString("vec4 refract(vec4 I, vec4 N, float eta);"));
-
- //
- // Matrix Functions.
- //
- s.append(TString("mat2 matrixCompMult(mat2 x, mat2 y);"));
- s.append(TString("mat3 matrixCompMult(mat3 x, mat3 y);"));
- s.append(TString("mat4 matrixCompMult(mat4 x, mat4 y);"));
-
- //
- // Vector relational functions.
- //
- s.append(TString("bvec2 lessThan(vec2 x, vec2 y);"));
- s.append(TString("bvec3 lessThan(vec3 x, vec3 y);"));
- s.append(TString("bvec4 lessThan(vec4 x, vec4 y);"));
-
- s.append(TString("bvec2 lessThan(ivec2 x, ivec2 y);"));
- s.append(TString("bvec3 lessThan(ivec3 x, ivec3 y);"));
- s.append(TString("bvec4 lessThan(ivec4 x, ivec4 y);"));
-
- s.append(TString("bvec2 lessThanEqual(vec2 x, vec2 y);"));
- s.append(TString("bvec3 lessThanEqual(vec3 x, vec3 y);"));
- s.append(TString("bvec4 lessThanEqual(vec4 x, vec4 y);"));
-
- s.append(TString("bvec2 lessThanEqual(ivec2 x, ivec2 y);"));
- s.append(TString("bvec3 lessThanEqual(ivec3 x, ivec3 y);"));
- s.append(TString("bvec4 lessThanEqual(ivec4 x, ivec4 y);"));
-
- s.append(TString("bvec2 greaterThan(vec2 x, vec2 y);"));
- s.append(TString("bvec3 greaterThan(vec3 x, vec3 y);"));
- s.append(TString("bvec4 greaterThan(vec4 x, vec4 y);"));
-
- s.append(TString("bvec2 greaterThan(ivec2 x, ivec2 y);"));
- s.append(TString("bvec3 greaterThan(ivec3 x, ivec3 y);"));
- s.append(TString("bvec4 greaterThan(ivec4 x, ivec4 y);"));
-
- s.append(TString("bvec2 greaterThanEqual(vec2 x, vec2 y);"));
- s.append(TString("bvec3 greaterThanEqual(vec3 x, vec3 y);"));
- s.append(TString("bvec4 greaterThanEqual(vec4 x, vec4 y);"));
-
- s.append(TString("bvec2 greaterThanEqual(ivec2 x, ivec2 y);"));
- s.append(TString("bvec3 greaterThanEqual(ivec3 x, ivec3 y);"));
- s.append(TString("bvec4 greaterThanEqual(ivec4 x, ivec4 y);"));
-
- s.append(TString("bvec2 equal(vec2 x, vec2 y);"));
- s.append(TString("bvec3 equal(vec3 x, vec3 y);"));
- s.append(TString("bvec4 equal(vec4 x, vec4 y);"));
-
- s.append(TString("bvec2 equal(ivec2 x, ivec2 y);"));
- s.append(TString("bvec3 equal(ivec3 x, ivec3 y);"));
- s.append(TString("bvec4 equal(ivec4 x, ivec4 y);"));
-
- s.append(TString("bvec2 equal(bvec2 x, bvec2 y);"));
- s.append(TString("bvec3 equal(bvec3 x, bvec3 y);"));
- s.append(TString("bvec4 equal(bvec4 x, bvec4 y);"));
-
- s.append(TString("bvec2 notEqual(vec2 x, vec2 y);"));
- s.append(TString("bvec3 notEqual(vec3 x, vec3 y);"));
- s.append(TString("bvec4 notEqual(vec4 x, vec4 y);"));
-
- s.append(TString("bvec2 notEqual(ivec2 x, ivec2 y);"));
- s.append(TString("bvec3 notEqual(ivec3 x, ivec3 y);"));
- s.append(TString("bvec4 notEqual(ivec4 x, ivec4 y);"));
-
- s.append(TString("bvec2 notEqual(bvec2 x, bvec2 y);"));
- s.append(TString("bvec3 notEqual(bvec3 x, bvec3 y);"));
- s.append(TString("bvec4 notEqual(bvec4 x, bvec4 y);"));
-
- s.append(TString("bool any(bvec2 x);"));
- s.append(TString("bool any(bvec3 x);"));
- s.append(TString("bool any(bvec4 x);"));
-
- s.append(TString("bool all(bvec2 x);"));
- s.append(TString("bool all(bvec3 x);"));
- s.append(TString("bool all(bvec4 x);"));
-
- s.append(TString("bvec2 not(bvec2 x);"));
- s.append(TString("bvec3 not(bvec3 x);"));
- s.append(TString("bvec4 not(bvec4 x);"));
-
- //
- // Texture Functions.
- //
- s.append(TString("vec4 texture1D(sampler1D sampler, float coord);"));
- s.append(TString("vec4 texture1DProj(sampler1D sampler, vec2 coord);"));
- s.append(TString("vec4 texture1DProj(sampler1D sampler, vec4 coord);"));
-
- s.append(TString("vec4 texture2D(sampler2D sampler, vec2 coord);"));
- s.append(TString("vec4 texture2DProj(sampler2D sampler, vec3 coord);"));
- s.append(TString("vec4 texture2DProj(sampler2D sampler, vec4 coord);"));
-
- s.append(TString("vec4 texture3D(sampler3D sampler, vec3 coord);"));
- s.append(TString("vec4 texture3DProj(sampler3D sampler, vec4 coord);"));
-
- s.append(TString("vec4 textureCube(samplerCube sampler, vec3 coord);"));
-
- s.append(TString("vec4 shadow1D(sampler1DShadow sampler, vec3 coord);"));
-
- s.append(TString("vec4 shadow2D(sampler2DShadow sampler, vec3 coord);"));
-
- s.append(TString("vec4 shadow1DProj(sampler1DShadow sampler, vec4 coord);"));
-
- s.append(TString("vec4 shadow2DProj(sampler2DShadow sampler, vec4 coord);"));
-
-
- //
- // Noise functions.
- //
- s.append(TString("float noise1(float x);"));
- s.append(TString("float noise1(vec2 x);"));
- s.append(TString("float noise1(vec3 x);"));
- s.append(TString("float noise1(vec4 x);"));
-
- s.append(TString("vec2 noise2(float x);"));
- s.append(TString("vec2 noise2(vec2 x);"));
- s.append(TString("vec2 noise2(vec3 x);"));
- s.append(TString("vec2 noise2(vec4 x);"));
-
- s.append(TString("vec3 noise3(float x);"));
- s.append(TString("vec3 noise3(vec2 x);"));
- s.append(TString("vec3 noise3(vec3 x);"));
- s.append(TString("vec3 noise3(vec4 x);"));
-
- s.append(TString("vec4 noise4(float x);"));
- s.append(TString("vec4 noise4(vec2 x);"));
- s.append(TString("vec4 noise4(vec3 x);"));
- s.append(TString("vec4 noise4(vec4 x);"));
-
- s.append(TString("\n"));
- }
- {
- //============================================================================
- //
- // Prototypes for built-in functions seen by vertex shaders only.
- //
- //============================================================================
-
- TString& s = BuiltInFunctionsVertex;
-
- //
- // Geometric Functions.
- //
- s.append(TString("vec4 ftransform();"));
-
- //
- // Texture Functions.
- //
- s.append(TString("vec4 texture1DLod(sampler1D sampler, float coord, float lod);"));
- s.append(TString("vec4 texture1DProjLod(sampler1D sampler, vec2 coord, float lod);"));
- s.append(TString("vec4 texture1DProjLod(sampler1D sampler, vec4 coord, float lod);"));
-
- s.append(TString("vec4 texture2DLod(sampler2D sampler, vec2 coord, float lod);"));
- s.append(TString("vec4 texture2DProjLod(sampler2D sampler, vec3 coord, float lod);"));
- s.append(TString("vec4 texture2DProjLod(sampler2D sampler, vec4 coord, float lod);"));
-
- s.append(TString("vec4 texture3DLod(sampler3D sampler, vec3 coord, float lod);"));
- s.append(TString("vec4 texture3DProjLod(sampler3D sampler, vec4 coord, float lod);"));
- s.append(TString("vec4 textureCubeLod(samplerCube sampler, vec3 coord, float lod);"));
-
- s.append(TString("vec4 shadow1DLod(sampler1DShadow sampler, vec3 coord, float lod);"));
- s.append(TString("vec4 shadow2DLod(sampler2DShadow sampler, vec3 coord, float lod);"));
- s.append(TString("vec4 shadow1DProjLod(sampler1DShadow sampler, vec4 coord, float lod);"));
- s.append(TString("vec4 shadow2DProjLod(sampler2DShadow sampler, vec4 coord, float lod);"));
-
- s.append(TString("\n"));
- }
- {
- //============================================================================
- //
- // Prototypes for built-in functions seen by fragment shaders only.
- //
- //============================================================================
-
- TString& s = BuiltInFunctionsFragment;
-
- //
- // Texture Functions.
- //
- s.append(TString("vec4 texture1D(sampler1D sampler, float coord, float bias);"));
- s.append(TString("vec4 texture1DProj(sampler1D sampler, vec2 coord, float bias);"));
- s.append(TString("vec4 texture1DProj(sampler1D sampler, vec4 coord, float bias);"));
-
- s.append(TString("vec4 texture2D(sampler2D sampler, vec2 coord, float bias);"));
- s.append(TString("vec4 texture2DProj(sampler2D sampler, vec3 coord, float bias);"));
- s.append(TString("vec4 texture2DProj(sampler2D sampler, vec4 coord, float bias);"));
-
- s.append(TString("vec4 texture3D(sampler3D sampler, vec3 coord, float bias);"));
- s.append(TString("vec4 texture3DProj(sampler3D sampler, vec4 coord, float bias);"));
- s.append(TString("vec4 textureCube(samplerCube sampler, vec3 coord, float bias);"));
-
- s.append(TString("vec4 shadow1D(sampler1DShadow sampler, vec3 coord, float bias);"));
- s.append(TString("vec4 shadow2D(sampler2DShadow sampler, vec3 coord, float bias);"));
- s.append(TString("vec4 shadow1DProj(sampler1DShadow sampler, vec4 coord, float bias);"));
- s.append(TString("vec4 shadow2DProj(sampler2DShadow sampler, vec4 coord, float bias);"));
-
- s.append(TString("float dFdx(float p);"));
- s.append(TString("vec2 dFdx(vec2 p);"));
- s.append(TString("vec3 dFdx(vec3 p);"));
- s.append(TString("vec4 dFdx(vec4 p);"));
-
- s.append(TString("float dFdy(float p);"));
- s.append(TString("vec2 dFdy(vec2 p);"));
- s.append(TString("vec3 dFdy(vec3 p);"));
- s.append(TString("vec4 dFdy(vec4 p);"));
-
- s.append(TString("float fwidth(float p);"));
- s.append(TString("vec2 fwidth(vec2 p);"));
- s.append(TString("vec3 fwidth(vec3 p);"));
- s.append(TString("vec4 fwidth(vec4 p);"));
-
- s.append(TString("\n"));
- }
- {
- //============================================================================
- //
- // Standard Uniforms
- //
- //============================================================================
-
- TString& s = StandardUniforms;
-
-
- //
- // OpenGL'uniform' state. Page numbers are in reference to version
- // 1.4 of the OpenGL specification.
- //
-
- //
- // Matrix state. p. 31, 32, 37, 39, 40.
- //
- s.append(TString("uniform mat4 gl_ModelViewMatrix;"));
- s.append(TString("uniform mat4 gl_ProjectionMatrix;"));
- s.append(TString("uniform mat4 gl_ModelViewProjectionMatrix;"));
-
- //
- // Derived matrix state that provides inverse and transposed versions
- // of the matrices above.
- //
- s.append(TString("uniform mat3 gl_NormalMatrix;"));
-
- s.append(TString("uniform mat4 gl_ModelViewMatrixInverse;"));
- s.append(TString("uniform mat4 gl_ProjectionMatrixInverse;"));
- s.append(TString("uniform mat4 gl_ModelViewProjectionMatrixInverse;"));
-
- s.append(TString("uniform mat4 gl_ModelViewMatrixTranspose;"));
- s.append(TString("uniform mat4 gl_ProjectionMatrixTranspose;"));
- s.append(TString("uniform mat4 gl_ModelViewProjectionMatrixTranspose;"));
-
- s.append(TString("uniform mat4 gl_ModelViewMatrixInverseTranspose;"));
- s.append(TString("uniform mat4 gl_ProjectionMatrixInverseTranspose;"));
- s.append(TString("uniform mat4 gl_ModelViewProjectionMatrixInverseTranspose;"));
-
- //
- // Normal scaling p. 39.
- //
- s.append(TString("uniform float gl_NormalScale;"));
-
- //
- // Depth range in window coordinates, p. 33
- //
- s.append(TString("struct gl_DepthRangeParameters {"));
- s.append(TString(" float near;")); // n
- s.append(TString(" float far;")); // f
- s.append(TString(" float diff;")); // f - n
- s.append(TString("};"));
- s.append(TString("uniform gl_DepthRangeParameters gl_DepthRange;"));
-
-
- //
- // Point Size, p. 66, 67.
- //
- s.append(TString("struct gl_PointParameters {"));
- s.append(TString(" float size;"));
- s.append(TString(" float sizeMin;"));
- s.append(TString(" float sizeMax;"));
- s.append(TString(" float fadeThresholdSize;"));
- s.append(TString(" float distanceConstantAttenuation;"));
- s.append(TString(" float distanceLinearAttenuation;"));
- s.append(TString(" float distanceQuadraticAttenuation;"));
- s.append(TString("};"));
-
- s.append(TString("uniform gl_PointParameters gl_Point;"));
-
- //
- // Material State p. 50, 55.
- //
- s.append(TString("struct gl_MaterialParameters {"));
- s.append(TString(" vec4 emission;")); // Ecm
- s.append(TString(" vec4 ambient;")); // Acm
- s.append(TString(" vec4 diffuse;")); // Dcm
- s.append(TString(" vec4 specular;")); // Scm
- s.append(TString(" float shininess;")); // Srm
- s.append(TString("};"));
- s.append(TString("uniform gl_MaterialParameters gl_FrontMaterial;"));
- s.append(TString("uniform gl_MaterialParameters gl_BackMaterial;"));
-
- //
- // Light State p 50, 53, 55.
- //
-
- s.append(TString("struct gl_LightSourceParameters {"));
- s.append(TString(" vec4 ambient;")); // Acli
- s.append(TString(" vec4 diffuse;")); // Dcli
- s.append(TString(" vec4 specular;")); // Scli
- s.append(TString(" vec4 position;")); // Ppli
- s.append(TString(" vec4 halfVector;")); // Derived: Hi
- s.append(TString(" vec3 spotDirection;")); // Sdli
- s.append(TString(" float spotExponent;")); // Srli
- s.append(TString(" float spotCutoff;")); // Crli
- // (range: [0.0,90.0], 180.0)
- s.append(TString(" float spotCosCutoff;")); // Derived: cos(Crli)
- // (range: [1.0,0.0],-1.0)
- s.append(TString(" float constantAttenuation;")); // K0
- s.append(TString(" float linearAttenuation;")); // K1
- s.append(TString(" float quadraticAttenuation;"));// K2
- s.append(TString("};"));
-
-
- s.append(TString("struct gl_LightModelParameters {"));
- s.append(TString(" vec4 ambient;")); // Acs
- s.append(TString("};"));
-
- s.append(TString("uniform gl_LightModelParameters gl_LightModel;"));
-
- //
- // Derived state from products of light and material.
- //
-
- s.append(TString("struct gl_LightModelProducts {"));
- s.append(TString(" vec4 sceneColor;")); // Derived. Ecm + Acm * Acs
- s.append(TString("};"));
-
- s.append(TString("uniform gl_LightModelProducts gl_FrontLightModelProduct;"));
- s.append(TString("uniform gl_LightModelProducts gl_BackLightModelProduct;"));
-
- s.append(TString("struct gl_LightProducts {"));
- s.append(TString(" vec4 ambient;")); // Acm * Acli
- s.append(TString(" vec4 diffuse;")); // Dcm * Dcli
- s.append(TString(" vec4 specular;")); // Scm * Scli
- s.append(TString("};"));
-
-
-
-
- //
- // Fog p. 161
- //
- s.append(TString("struct gl_FogParameters {"));
- s.append(TString(" vec4 color;"));
- s.append(TString(" float density;"));
- s.append(TString(" float start;"));
- s.append(TString(" float end;"));
- s.append(TString(" float scale;")); // 1 / (gl_FogEnd - gl_FogStart)
- s.append(TString("};"));
-
- s.append(TString("uniform gl_FogParameters gl_Fog;"));
-
- s.append(TString("\n"));
- }
- {
- //============================================================================
- //
- // Vertex attributes, p. 19.
- //
- //============================================================================
-
- TString& s = StandardVertexAttributes;
-
- s.append(TString("attribute vec4 gl_Color;"));
- s.append(TString("attribute vec4 gl_SecondaryColor;"));
- s.append(TString("attribute vec3 gl_Normal;"));
- s.append(TString("attribute vec4 gl_Vertex;"));
- s.append(TString("attribute vec4 gl_MultiTexCoord0;"));
- s.append(TString("attribute vec4 gl_MultiTexCoord1;"));
- s.append(TString("attribute vec4 gl_MultiTexCoord2;"));
- s.append(TString("attribute vec4 gl_MultiTexCoord3;"));
- s.append(TString("attribute vec4 gl_MultiTexCoord4;"));
- s.append(TString("attribute vec4 gl_MultiTexCoord5;"));
- s.append(TString("attribute vec4 gl_MultiTexCoord6;"));
- s.append(TString("attribute vec4 gl_MultiTexCoord7;"));
- s.append(TString("attribute float gl_FogCoord;"));
-
- s.append(TString("\n"));
- }
- {
- //============================================================================
- //
- // Define the output varying interface from the vertex shader.
- //
- //============================================================================
-
- TString& s = StandardVertexVaryings;
-
- s.append(TString("varying vec4 gl_FrontColor;"));
- s.append(TString("varying vec4 gl_BackColor;"));
- s.append(TString("varying vec4 gl_FrontSecondaryColor;"));
- s.append(TString("varying vec4 gl_BackSecondaryColor;"));
- s.append(TString("varying vec4 gl_TexCoord[];"));
- s.append(TString("varying float gl_FogFragCoord;"));
-
- s.append(TString("\n"));
- }
- {
- //============================================================================
- //
- // Define the input varying interface to the fragment shader.
- //
- //============================================================================
-
- TString& s = StandardFragmentVaryings;
-
- s.append(TString("varying vec4 gl_Color;"));
- s.append(TString("varying vec4 gl_SecondaryColor;"));
- s.append(TString("varying vec4 gl_TexCoord[];"));
- s.append(TString("varying float gl_FogFragCoord;"));
-
- s.append(TString("\n"));
- }
-
- builtInStrings[EShLangFragment].push_back(BuiltInFunctions.c_str());
- builtInStrings[EShLangFragment].push_back(BuiltInFunctionsFragment);
- builtInStrings[EShLangFragment].push_back(StandardUniforms);
- builtInStrings[EShLangFragment].push_back(StandardFragmentVaryings);
-
- builtInStrings[EShLangVertex].push_back(BuiltInFunctions);
- builtInStrings[EShLangVertex].push_back(BuiltInFunctionsVertex);
- builtInStrings[EShLangVertex].push_back(StandardVertexVaryings);
- builtInStrings[EShLangVertex].push_back(StandardVertexAttributes);
- builtInStrings[EShLangVertex].push_back(StandardUniforms);
-}
-
-
-void TBuiltIns::initialize(const TBuiltInResource &resources)
-{
- //
- // Initialize all the built-in strings for parsing.
- //
- TString StandardUniforms;
-
- {
- //============================================================================
- //
- // Standard Uniforms
- //
- //============================================================================
-
- TString& s = StandardUniforms;
-
- //
- // Implementation dependent constants. The example values below
- // are the minimum values allowed for these maximums.
- //
- char builtInConstant[80];
- sprintf(builtInConstant, "const int gl_MaxLights = %d;", resources.maxLights); // GL 1.0
- s.append(TString(builtInConstant));
-
- sprintf(builtInConstant, "const int gl_MaxClipPlanes = %d;", resources.maxClipPlanes); // GL 1.0
- s.append(TString(builtInConstant));
-
- sprintf(builtInConstant, "const int gl_MaxTextureUnits = %d;", resources.maxTextureUnits); // GL 1.2
- s.append(TString(builtInConstant));
-
- sprintf(builtInConstant, "const int gl_MaxTextureCoords = %d;", resources.maxTextureCoords); // ARB_fragment_program
- s.append(TString(builtInConstant));
-
- sprintf(builtInConstant, "const int gl_MaxVertexAttribs = %d;", resources.maxVertexAttribs); // ARB_vertex_shader
- s.append(TString(builtInConstant));
-
- sprintf(builtInConstant, "const int gl_MaxVertexUniformComponents = %d;", resources.maxVertexUniformComponents); // ARB_vertex_shader
- s.append(TString(builtInConstant));
-
- sprintf(builtInConstant, "const int gl_MaxVaryingFloats = %d;", resources.maxVaryingFloats); // ARB_vertex_shader
- s.append(TString(builtInConstant));
-
- sprintf(builtInConstant, "const int gl_MaxVertexTextureImageUnits = %d;", resources.maxVertexTextureImageUnits); // ARB_vertex_shader
- s.append(TString(builtInConstant));
-
- sprintf(builtInConstant, "const int gl_MaxCombinedTextureImageUnits = %d;", resources.maxCombinedTextureImageUnits); // ARB_vertex_shader
- s.append(TString(builtInConstant));
-
- sprintf(builtInConstant, "const int gl_MaxTextureImageUnits = %d;", resources.maxTextureImageUnits); // ARB_fragment_shader
- s.append(TString(builtInConstant));
-
- sprintf(builtInConstant, "const int gl_MaxFragmentUniformComponents = %d;", resources.maxFragmentUniformComponents); // ARB_fragment_shader
- s.append(TString(builtInConstant));
-
- sprintf(builtInConstant, "const int gl_MaxDrawBuffers = %d;", resources.maxDrawBuffers); // proposed ARB_draw_buffers
- s.append(TString(builtInConstant));
-
- //
- // OpenGL'uniform' state. Page numbers are in reference to version
- // 1.4 of the OpenGL specification.
- //
-
- //
- // Matrix state. p. 31, 32, 37, 39, 40.
- //
- s.append(TString("uniform mat4 gl_TextureMatrix[gl_MaxTextureCoords];"));
-
- //
- // Derived matrix state that provides inverse and transposed versions
- // of the matrices above.
- //
- s.append(TString("uniform mat4 gl_TextureMatrixInverse[gl_MaxTextureCoords];"));
-
- s.append(TString("uniform mat4 gl_TextureMatrixTranspose[gl_MaxTextureCoords];"));
-
- s.append(TString("uniform mat4 gl_TextureMatrixInverseTranspose[gl_MaxTextureCoords];"));
-
- //
- // Clip planes p. 42.
- //
- s.append(TString("uniform vec4 gl_ClipPlane[gl_MaxClipPlanes];"));
-
- //
- // Light State p 50, 53, 55.
- //
- s.append(TString("uniform gl_LightSourceParameters gl_LightSource[gl_MaxLights];"));
-
- //
- // Derived state from products of light.
- //
- s.append(TString("uniform gl_LightProducts gl_FrontLightProduct[gl_MaxLights];"));
- s.append(TString("uniform gl_LightProducts gl_BackLightProduct[gl_MaxLights];"));
-
- //
- // Textureg Environment and Generation, p. 152, p. 40-42.
- //
- s.append(TString("uniform vec4 gl_TextureEnvColor[gl_MaxTextureImageUnits];"));
- s.append(TString("uniform vec4 gl_EyePlaneS[gl_MaxTextureCoords];"));
- s.append(TString("uniform vec4 gl_EyePlaneT[gl_MaxTextureCoords];"));
- s.append(TString("uniform vec4 gl_EyePlaneR[gl_MaxTextureCoords];"));
- s.append(TString("uniform vec4 gl_EyePlaneQ[gl_MaxTextureCoords];"));
- s.append(TString("uniform vec4 gl_ObjectPlaneS[gl_MaxTextureCoords];"));
- s.append(TString("uniform vec4 gl_ObjectPlaneT[gl_MaxTextureCoords];"));
- s.append(TString("uniform vec4 gl_ObjectPlaneR[gl_MaxTextureCoords];"));
- s.append(TString("uniform vec4 gl_ObjectPlaneQ[gl_MaxTextureCoords];"));
-
- s.append(TString("\n"));
- }
-
- builtInStrings[EShLangFragment].push_back(StandardUniforms);
- builtInStrings[EShLangVertex].push_back(StandardUniforms);
-}
-
-void IdentifyBuiltIns(EShLanguage language, TSymbolTable& symbolTable)
-{
- //
- // First, insert some special built-in variables that are not in
- // the built-in header files.
- //
- switch(language) {
-
- case EShLangFragment: {
- symbolTable.insert(*new TVariable(NewPoolTString("gl_FrontFacing"), TType(EbtBool, EvqFace, 1)));
- symbolTable.insert(*new TVariable(NewPoolTString("gl_FragCoord"), TType(EbtFloat, EvqFragCoord, 4)));
- symbolTable.insert(*new TVariable(NewPoolTString("gl_FragColor"), TType(EbtFloat, EvqFragColor, 4)));
- symbolTable.insert(*new TVariable(NewPoolTString("gl_FragDepth"), TType(EbtFloat, EvqFragDepth, 1)));
-
- }
- break;
-
- case EShLangVertex:
- symbolTable.insert(*new TVariable(NewPoolTString("gl_Position"), TType(EbtFloat, EvqPosition, 4)));
- symbolTable.insert(*new TVariable(NewPoolTString("gl_PointSize"), TType(EbtFloat, EvqPointSize, 1)));
- symbolTable.insert(*new TVariable(NewPoolTString("gl_ClipVertex"), TType(EbtFloat, EvqClipVertex, 4)));
- break;
- default: break;
- }
-
- //
- // Next, identify which built-ins from the already loaded headers have
- // a mapping to an operator. Those that are not identified as such are
- // expected to be resolved through a library of functions, versus as
- // operations.
- //
- symbolTable.relateToOperator("not", EOpVectorLogicalNot);
-
- symbolTable.relateToOperator("matrixCompMult", EOpMul);
- symbolTable.relateToOperator("mod", EOpMod);
-
- symbolTable.relateToOperator("equal", EOpVectorEqual);
- symbolTable.relateToOperator("notEqual", EOpVectorNotEqual);
- symbolTable.relateToOperator("lessThan", EOpLessThan);
- symbolTable.relateToOperator("greaterThan", EOpGreaterThan);
- symbolTable.relateToOperator("lessThanEqual", EOpLessThanEqual);
- symbolTable.relateToOperator("greaterThanEqual", EOpGreaterThanEqual);
-
- symbolTable.relateToOperator("radians", EOpRadians);
- symbolTable.relateToOperator("degrees", EOpDegrees);
- symbolTable.relateToOperator("sin", EOpSin);
- symbolTable.relateToOperator("cos", EOpCos);
- symbolTable.relateToOperator("tan", EOpTan);
- symbolTable.relateToOperator("asin", EOpAsin);
- symbolTable.relateToOperator("acos", EOpAcos);
- symbolTable.relateToOperator("atan", EOpAtan);
-
- symbolTable.relateToOperator("pow", EOpPow);
- symbolTable.relateToOperator("exp2", EOpExp2);
- symbolTable.relateToOperator("log", EOpLog);
- symbolTable.relateToOperator("exp", EOpExp);
- symbolTable.relateToOperator("log2", EOpLog2);
- symbolTable.relateToOperator("sqrt", EOpSqrt);
- symbolTable.relateToOperator("inversesqrt", EOpInverseSqrt);
-
- symbolTable.relateToOperator("abs", EOpAbs);
- symbolTable.relateToOperator("sign", EOpSign);
- symbolTable.relateToOperator("floor", EOpFloor);
- symbolTable.relateToOperator("ceil", EOpCeil);
- symbolTable.relateToOperator("fract", EOpFract);
- symbolTable.relateToOperator("min", EOpMin);
- symbolTable.relateToOperator("max", EOpMax);
- symbolTable.relateToOperator("clamp", EOpClamp);
- symbolTable.relateToOperator("mix", EOpMix);
- symbolTable.relateToOperator("step", EOpStep);
- symbolTable.relateToOperator("smoothstep", EOpSmoothStep);
-
- symbolTable.relateToOperator("length", EOpLength);
- symbolTable.relateToOperator("distance", EOpDistance);
- symbolTable.relateToOperator("dot", EOpDot);
- symbolTable.relateToOperator("cross", EOpCross);
- symbolTable.relateToOperator("normalize", EOpNormalize);
- symbolTable.relateToOperator("forward", EOpFaceForward);
- symbolTable.relateToOperator("reflect", EOpReflect);
- symbolTable.relateToOperator("refract", EOpRefract);
-
- symbolTable.relateToOperator("any", EOpAny);
- symbolTable.relateToOperator("all", EOpAll);
-
- switch(language) {
-
- case EShLangVertex:
- break;
-
- case EShLangFragment:
- symbolTable.relateToOperator("dFdx", EOpDPdx);
- symbolTable.relateToOperator("dFdy", EOpDPdy);
- symbolTable.relateToOperator("fwidth", EOpFwidth);
-
- break;
-
- case EShLangPack:
- case EShLangUnpack:
- symbolTable.relateToOperator("itof", EOpItof);
- symbolTable.relateToOperator("ftoi", EOpFtoi);
- symbolTable.relateToOperator("skipPixels", EOpSkipPixels);
- symbolTable.relateToOperator("readInput", EOpReadInput);
- symbolTable.relateToOperator("writePixel", EOpWritePixel);
- symbolTable.relateToOperator("bitmapLSB", EOpBitmapLsb);
- symbolTable.relateToOperator("bitmapMSB", EOpBitmapMsb);
- symbolTable.relateToOperator("writeOutput", EOpWriteOutput);
- symbolTable.relateToOperator("readPixel", EOpReadPixel);
- break;
- default: assert (false && "Language not supported");
- }
-}
-
-void IdentifyBuiltIns(EShLanguage language, TSymbolTable& symbolTable, const TBuiltInResource &resources)
-{
- //
- // First, insert some special built-in variables that are not in
- // the built-in header files.
- //
- switch(language) {
-
- case EShLangFragment: {
- // Set up gl_FragData. The array size.
- TType fragData(EbtFloat, EvqFragColor, 4, false, true);
- fragData.setArraySize(resources.maxDrawBuffers);
- symbolTable.insert(*new TVariable(NewPoolTString("gl_FragData"), fragData));
- }
- break;
-
- default: break;
- }
-}
diff --git a/src/mesa/shader/slang/MachineIndependent/Initialize.h b/src/mesa/shader/slang/MachineIndependent/Initialize.h deleted file mode 100755 index b273f06cae..0000000000 --- a/src/mesa/shader/slang/MachineIndependent/Initialize.h +++ /dev/null @@ -1,58 +0,0 @@ -//
-//Copyright (C) 2002-2005 3Dlabs Inc. Ltd.
-//All rights reserved.
-//
-//Redistribution and use in source and binary forms, with or without
-//modification, are permitted provided that the following conditions
-//are met:
-//
-// Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//
-// Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-//
-// Neither the name of 3Dlabs Inc. Ltd. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-//THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-//"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-//LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
-//FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
-//COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
-//INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
-//BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
-//LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
-//CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-//LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
-//ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
-//POSSIBILITY OF SUCH DAMAGE.
-//
-
-#ifndef _INITIALIZE_INCLUDED_
-#define _INITIALIZE_INCLUDED_
-
-#include "Include/ResourceLimits.h"
-#include "../Include/Common.h"
-#include "../Include/ShHandle.h"
-#include "SymbolTable.h"
-
-typedef TVector<TString> TBuiltInStrings;
-
-class TBuiltIns {
-public:
- POOL_ALLOCATOR_NEW_DELETE(GlobalPoolAllocator)
- void initialize();
- void initialize(const TBuiltInResource& resources);
- TBuiltInStrings* getBuiltInStrings() { return builtInStrings; }
-protected:
- TBuiltInStrings builtInStrings[EShLangCount];
-};
-
-void IdentifyBuiltIns(EShLanguage, TSymbolTable&);
-void IdentifyBuiltIns(EShLanguage, TSymbolTable&, const TBuiltInResource &resources);
-
-#endif // _INITIALIZE_INCLUDED_
diff --git a/src/mesa/shader/slang/MachineIndependent/IntermTraverse.cpp b/src/mesa/shader/slang/MachineIndependent/IntermTraverse.cpp deleted file mode 100755 index da77806ddc..0000000000 --- a/src/mesa/shader/slang/MachineIndependent/IntermTraverse.cpp +++ /dev/null @@ -1,243 +0,0 @@ -//
-//Copyright (C) 2002-2005 3Dlabs Inc. Ltd.
-//All rights reserved.
-//
-//Redistribution and use in source and binary forms, with or without
-//modification, are permitted provided that the following conditions
-//are met:
-//
-// Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//
-// Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-//
-// Neither the name of 3Dlabs Inc. Ltd. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-//THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-//"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-//LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
-//FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
-//COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
-//INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
-//BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
-//LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
-//CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-//LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
-//ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
-//POSSIBILITY OF SUCH DAMAGE.
-//
-
-#include "../Include/intermediate.h"
-
-//
-// Traverse the intermediate representation tree, and
-// call a node type specific function for each node.
-// Done recursively through the member function Traverse().
-// Node types can be skipped if their function to call is 0,
-// but their subtree will still be traversed.
-// Nodes with children can have their whole subtree skipped
-// if preVisit is turned on and the type specific function
-// returns false.
-//
-// preVisit, postVisit, and rightToLeft control what order
-// nodes are visited in.
-//
-
-//
-// Traversal functions for terminals are straighforward....
-//
-void TIntermSymbol::traverse(TIntermTraverser* it)
-{
- if (it->visitSymbol)
- it->visitSymbol(this, it);
-}
-
-void TIntermConstantUnion::traverse(TIntermTraverser* it)
-{
- if (it->visitConstantUnion)
- it->visitConstantUnion(this, it);
-}
-
-//
-// Traverse a binary node.
-//
-void TIntermBinary::traverse(TIntermTraverser* it)
-{
- bool visit = true;
-
- //
- // visit the node before children if pre-visiting.
- //
- if (it->preVisit && it->visitBinary)
- visit = it->visitBinary(true, this, it);
-
- //
- // Visit the children, in the right order.
- //
- if (visit) {
- ++it->depth;
- if (it->rightToLeft) {
- if (right)
- right->traverse(it);
- if (left)
- left->traverse(it);
- } else {
- if (left)
- left->traverse(it);
- if (right)
- right->traverse(it);
- }
- --it->depth;
- }
-
- //
- // Visit the node after the children, if requested and the traversal
- // hasn't been cancelled yet.
- //
- if (visit && it->postVisit && it->visitBinary)
- it->visitBinary(false, this, it);
-}
-
-//
-// Traverse a unary node. Same comments in binary node apply here.
-//
-void TIntermUnary::traverse(TIntermTraverser* it)
-{
- bool visit = true;
-
- if (it->preVisit && it->visitUnary)
- visit = it->visitUnary(true, this, it);
-
- if (visit) {
- ++it->depth;
- operand->traverse(it);
- --it->depth;
- }
-
- if (visit && it->postVisit && it->visitUnary)
- it->visitUnary(false, this, it);
-}
-
-//
-// Traverse an aggregate node. Same comments in binary node apply here.
-//
-void TIntermAggregate::traverse(TIntermTraverser* it)
-{
- bool visit = true;
-
- if (it->preVisit && it->visitAggregate)
- visit = it->visitAggregate(true, this, it);
-
- if (visit) {
- ++it->depth;
-
- TIntermSequence::iterator sit;
- if (it->rightToLeft) {
- sit = sequence.end();
- while (sit != sequence.begin()) {
- --sit;
- (*sit)->traverse(it);
- }
- } else {
- for (sit = sequence.begin(); sit != sequence.end(); ++sit)
- (*sit)->traverse(it);
- }
-
- --it->depth;
- }
-
- if (visit && it->postVisit && it->visitAggregate)
- it->visitAggregate(false, this, it);
-}
-
-//
-// Traverse a selection node. Same comments in binary node apply here.
-//
-void TIntermSelection::traverse(TIntermTraverser* it)
-{
- bool visit = true;
-
- if (it->preVisit && it->visitSelection)
- visit = it->visitSelection(true, this, it);
-
- if (visit) {
- ++it->depth;
- if (it->rightToLeft) {
- if (falseBlock)
- falseBlock->traverse(it);
- if (trueBlock)
- trueBlock->traverse(it);
- condition->traverse(it);
- } else {
- condition->traverse(it);
- if (trueBlock)
- trueBlock->traverse(it);
- if (falseBlock)
- falseBlock->traverse(it);
- }
- --it->depth;
- }
-
- if (visit && it->postVisit && it->visitSelection)
- it->visitSelection(false, this, it);
-}
-
-//
-// Traverse a loop node. Same comments in binary node apply here.
-//
-void TIntermLoop::traverse(TIntermTraverser* it)
-{
- bool visit = true;
-
- if (it->preVisit && it->visitLoop)
- visit = it->visitLoop(true, this, it);
-
- if (visit) {
- ++it->depth;
- if (it->rightToLeft) {
- if (terminal)
- terminal->traverse(it);
- if (body)
- body->traverse(it);
- if (test)
- test->traverse(it);
- } else {
- if (test)
- test->traverse(it);
- if (body)
- body->traverse(it);
- if (terminal)
- terminal->traverse(it);
- }
- --it->depth;
- }
-
- if (visit && it->postVisit && it->visitLoop)
- it->visitLoop(false, this, it);
-}
-
-//
-// Traverse a branch node. Same comments in binary node apply here.
-//
-void TIntermBranch::traverse(TIntermTraverser* it)
-{
- bool visit = true;
-
- if (it->preVisit && it->visitBranch)
- visit = it->visitBranch(true, this, it);
-
- if (visit && expression) {
- ++it->depth;
- expression->traverse(it);
- --it->depth;
- }
-
- if (visit && it->postVisit && it->visitBranch)
- it->visitBranch(false, this, it);
-}
-
diff --git a/src/mesa/shader/slang/MachineIndependent/Intermediate.cpp b/src/mesa/shader/slang/MachineIndependent/Intermediate.cpp deleted file mode 100755 index 056fe17de0..0000000000 --- a/src/mesa/shader/slang/MachineIndependent/Intermediate.cpp +++ /dev/null @@ -1,2110 +0,0 @@ -//
-//Copyright (C) 2002-2005 3Dlabs Inc. Ltd.
-//All rights reserved.
-//
-//Redistribution and use in source and binary forms, with or without
-//modification, are permitted provided that the following conditions
-//are met:
-//
-// Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//
-// Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-//
-// Neither the name of 3Dlabs Inc. Ltd. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-//THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-//"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-//LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
-//FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
-//COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
-//INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
-//BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
-//LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
-//CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-//LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
-//ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
-//POSSIBILITY OF SUCH DAMAGE.
-//
-
-//
-// Build the intermediate representation.
-//
-
-#include "../Include/ShHandle.h"
-#include "localintermediate.h"
-#include "QualifierAlive.h"
-#include "RemoveTree.h"
-#include <float.h>
-
-////////////////////////////////////////////////////////////////////////////
-//
-// First set of functions are to help build the intermediate representation.
-// These functions are not member functions of the nodes.
-// They are called from parser productions.
-//
-/////////////////////////////////////////////////////////////////////////////
-
-//
-// Add a terminal node for an identifier in an expression.
-//
-// Returns the added node.
-//
-TIntermSymbol* TIntermediate::addSymbol(int id, const TString& name, const TType& type, TSourceLoc line)
-{
- TIntermSymbol* node = new TIntermSymbol(id, name, type);
- node->setLine(line);
-
- return node;
-}
-
-//
-// Connect two nodes with a new parent that does a binary operation on the nodes.
-//
-// Returns the added node.
-//
-TIntermTyped* TIntermediate::addBinaryMath(TOperator op, TIntermTyped* left, TIntermTyped* right, TSourceLoc line, TSymbolTable& symbolTable)
-{
- switch (op) {
- case EOpLessThan:
- case EOpGreaterThan:
- case EOpLessThanEqual:
- case EOpGreaterThanEqual:
- if (left->getType().isMatrix() || left->getType().isArray() || left->getType().isVector() || left->getType().getBasicType() == EbtStruct) {
- return 0;
- }
- break;
- case EOpLogicalOr:
- case EOpLogicalXor:
- case EOpLogicalAnd:
- if (left->getType().getBasicType() != EbtBool || left->getType().isMatrix() || left->getType().isArray() || left->getType().isVector()) {
- return 0;
- }
- break;
- case EOpAdd:
- case EOpSub:
- case EOpDiv:
- case EOpMul:
- if (left->getType().getBasicType() == EbtStruct || left->getType().getBasicType() == EbtBool)
- return 0;
- default: break;
- }
-
- //
- // First try converting the children to compatible types.
- //
-
- if (!(left->getType().getStruct() && right->getType().getStruct())) {
- TIntermTyped* child = addConversion(op, left->getType(), right);
- if (child)
- right = child;
- else {
- child = addConversion(op, right->getType(), left);
- if (child)
- left = child;
- else
- return 0;
- }
- } else {
- if (left->getType() != right->getType())
- return 0;
- }
-
-
- //
- // Need a new node holding things together then. Make
- // one and promote it to the right type.
- //
- TIntermBinary* node = new TIntermBinary(op);
- if (line == 0)
- line = right->getLine();
- node->setLine(line);
-
- node->setLeft(left);
- node->setRight(right);
- if (! node->promote(infoSink))
- return 0;
-
- TIntermConstantUnion *leftTempConstant = left->getAsConstantUnion();
- TIntermConstantUnion *rightTempConstant = right->getAsConstantUnion();
-
- if (leftTempConstant)
- leftTempConstant = copyConstUnion(left->getAsConstantUnion())->getAsConstantUnion();
-
- if (rightTempConstant)
- rightTempConstant = copyConstUnion(right->getAsConstantUnion())->getAsConstantUnion();
-
- if (right->getType().getQualifier() == EvqConst && left->getType().getQualifier() == EvqConst) {
- if (right->getAsAggregate()) {
- rightTempConstant = changeAggrToTempConst(right->getAsAggregate(), symbolTable, line);
- if (rightTempConstant->getUnionArrayPointer() == 0)
- return 0;
- }
-
- if (left->getAsAggregate()) {
- leftTempConstant = changeAggrToTempConst(left->getAsAggregate(), symbolTable, line);
- if (leftTempConstant->getUnionArrayPointer() == 0)
- return 0;
- }
- }
-
- //
- // See if we can fold constants.
- //
-
- TIntermTyped* typedReturnNode = 0;
- if ( leftTempConstant && rightTempConstant) {
- if (leftTempConstant->getSize() == 1 && rightTempConstant->getSize() > 1)
- typedReturnNode = rightTempConstant->fold(node->getOp(), leftTempConstant, infoSink, false);
- else
- typedReturnNode = leftTempConstant->fold(node->getOp(), rightTempConstant, infoSink, true);
-
- if (typedReturnNode)
- return typedReturnNode;
- else {
- node->setLeft(leftTempConstant);
- node->setRight(rightTempConstant);
- }
- } else if (leftTempConstant) {
- node->setLeft(copyConstUnion(leftTempConstant));
- } else if (rightTempConstant) {
- node->setRight(rightTempConstant);
- }
-
- return node;
-}
-
-//
-// Connect two nodes through an assignment.
-//
-// Returns the added node.
-//
-TIntermTyped* TIntermediate::addAssign(TOperator op, TIntermTyped* left, TIntermTyped* right, TSourceLoc line)
-{
- //
- // Like adding binary math, except the conversion can only go
- // from right to left.
- //
- TIntermBinary* node = new TIntermBinary(op);
- if (line == 0)
- line = left->getLine();
- node->setLine(line);
-
- if (right->getAsConstantUnion()) { // if the right node of assignment is a TempConstant node, allocate its own new space and remove the pointer to the symbol table value
- right = copyConstUnion(right->getAsConstantUnion()) ;
- if (right == 0)
- return 0;
- }
-
- TIntermTyped* child = addConversion(op, left->getType(), right);
- if (child == 0)
- return 0;
-
- node->setLeft(left);
- node->setRight(child);
- if (! node->promote(infoSink))
- return 0;
-
- return node;
-}
-
-//
-// Connect two nodes through an index operator, where the left node is the base
-// of an array or struct, and the right node is a direct or indirect offset.
-//
-// Returns the added node.
-// The caller should set the type of the returned node.
-//
-TIntermTyped* TIntermediate::addIndex(TOperator op, TIntermTyped* base, TIntermTyped* index, TSourceLoc line)
-{
- TIntermBinary* node = new TIntermBinary(op);
- if (line == 0)
- line = index->getLine();
- node->setLine(line);
- node->setLeft(base);
- node->setRight(index);
-
- // caller should set the type
-
- return node;
-}
-
-//
-// Add one node as the parent of another that it operates on.
-//
-// Returns the added node.
-//
-TIntermTyped* TIntermediate::addUnaryMath(TOperator op, TIntermNode* childNode, TSourceLoc line, TSymbolTable& symbolTable)
-{
- TIntermUnary* node;
- TIntermTyped* child = childNode->getAsTyped();
-
- if (child == 0) {
- infoSink.info.message(EPrefixInternalError, "Bad type in AddUnaryMath", line);
- return 0;
- }
-
- switch (op) {
- case EOpLogicalNot:
- if (child->getType().getBasicType() != EbtBool || child->getType().isMatrix() || child->getType().isArray() || child->getType().isVector()) {
- return 0;
- }
- break;
-
- case EOpPostIncrement:
- case EOpPreIncrement:
- case EOpPostDecrement:
- case EOpPreDecrement:
- case EOpNegative:
- if (child->getType().getBasicType() == EbtStruct)
- return 0;
- default: break;
- }
-
- //
- // Do we need to promote the operand?
- //
- // Note: Implicit promotions were removed from the language.
- //
- TBasicType newType = EbtVoid;
- switch (op) {
- case EOpConstructInt: newType = EbtInt; break;
- case EOpConstructBool: newType = EbtBool; break;
- case EOpConstructFloat: newType = EbtFloat; break;
- default: break;
- }
-
- if (newType != EbtVoid) {
- child = addConversion(op, TType(newType, EvqTemporary, child->getNominalSize(),
- child->isMatrix(),
- child->isArray()),
- child);
- if (child == 0)
- return 0;
- }
-
- //
- // For constructors, we are now done, it's all in the conversion.
- //
- switch (op) {
- case EOpConstructInt:
- case EOpConstructBool:
- case EOpConstructFloat:
- return child;
- default: break;
- }
-
- if (child->getAsConstantUnion())
- child = copyConstUnion(child->getAsConstantUnion());
-
- if (child->getAsAggregate() && child->getType().getQualifier() == EvqConst) {
- child = changeAggrToTempConst(child->getAsAggregate(), symbolTable, line);
- if (child->getAsConstantUnion()->getUnionArrayPointer() == 0)
- return 0;
- }
-
- TIntermConstantUnion *childTempConstant = child->getAsConstantUnion();
-
- //
- // Make a new node for the operator.
- //
- node = new TIntermUnary(op);
- if (line == 0)
- line = child->getLine();
- node->setLine(line);
- node->setOperand(child);
-
- if (! node->promote(infoSink))
- return 0;
-
- if (childTempConstant) {
- TIntermTyped* newChild = childTempConstant->fold(op, 0, infoSink, true);
-
- if (newChild) {
- return newChild;
- }
- }
-
- return node;
-}
-
-//
-// This is the safe way to change the operator on an aggregate, as it
-// does lots of error checking and fixing. Especially for establishing
-// a function call's operation on it's set of parameters. Sequences
-// of instructions are also aggregates, but they just direnctly set
-// their operator to EOpSequence.
-//
-// Returns an aggregate node, which could be the one passed in if
-// it was already an aggregate.
-//
-TIntermAggregate* TIntermediate::setAggregateOperator(TIntermNode* node, TOperator op, TSourceLoc line)
-{
- TIntermAggregate* aggNode;
-
- //
- // Make sure we have an aggregate. If not turn it into one.
- //
- if (node) {
- aggNode = node->getAsAggregate();
- if (aggNode == 0 || aggNode->getOp() != EOpNull) {
- //
- // Make an aggregate containing this node.
- //
- aggNode = new TIntermAggregate();
- aggNode->getSequence().push_back(node);
- if (line == 0)
- line = node->getLine();
- }
- } else
- aggNode = new TIntermAggregate();
-
- //
- // Set the operator.
- //
- aggNode->setOperator(op);
- if (line != 0)
- aggNode->setLine(line);
-
- return aggNode;
-}
-
-//
-// Convert one type to another.
-//
-// Returns the node representing the conversion, which could be the same
-// node passed in if no conversion was needed.
-//
-// Return 0 if a conversion can't be done.
-//
-TIntermTyped* TIntermediate::addConversion(TOperator op, const TType& type, TIntermTyped* node)
-{
- //
- // Does the base type allow operation?
- //
- switch (node->getBasicType()) {
- case EbtVoid:
- case EbtSampler1D:
- case EbtSampler2D:
- case EbtSampler3D:
- case EbtSamplerCube:
- case EbtSampler1DShadow:
- case EbtSampler2DShadow:
- return 0;
- default: break;
- }
-
- //
- // Otherwise, if types are identical, no problem
- //
- if (type == node->getType())
- return node;
-
- //
- // If one's a structure, then no conversions.
- //
- if (type.getStruct() || node->getType().getStruct())
- return 0;
-
- TBasicType promoteTo;
-
- switch (op) {
- //
- // Explicit conversions
- //
- case EOpConstructBool:
- promoteTo = EbtBool;
- break;
- case EOpConstructFloat:
- promoteTo = EbtFloat;
- break;
- case EOpConstructInt:
- promoteTo = EbtInt;
- break;
- default:
- //
- // implicit conversions were removed from the language.
- //
- if (type.getBasicType() != node->getType().getBasicType())
- return 0;
- //
- // Size and structure could still differ, but that's
- // handled by operator promotion.
- //
- return node;
- }
-
- //
- // Do conversion.
- //
- bool allConstant = true;
- // check to see if there is an aggregate node
- if (node->getAsAggregate()) {
- if (node->getAsAggregate()->getOp() != EOpFunctionCall) {
- // if the aggregate node is a constructor or a comma operator, look at its children, if they are constant
- // convert them into the right type
- TIntermSequence &sequenceVector = node->getAsAggregate()->getSequence() ;
- for (TIntermSequence::iterator p = sequenceVector.begin();
- p != sequenceVector.end(); p++) {
- if (!(*p)->getAsTyped()->getAsConstantUnion())
- allConstant = false;
- }
- } else
- allConstant = false;
- }
- if (allConstant && node->getAsAggregate()) { // we can do the constant folding here as all the nodes of the aggregate are const
- TIntermSequence &sequenceVector = node->getAsAggregate()->getSequence() ;
- for (TIntermSequence::iterator p = sequenceVector.begin();
- p != sequenceVector.end(); p++) {
- TIntermTyped* newNode = 0;
- constUnion *unionArray = new constUnion[1];
-
- switch (promoteTo) {
- case EbtFloat:
- switch ((*p)->getAsTyped()->getType().getBasicType()) {
-
- case EbtInt:
- unionArray->fConst = static_cast<float>((*p)->getAsTyped()->getAsConstantUnion()->getUnionArrayPointer()->iConst);
- newNode = addConstantUnion(unionArray, TType(EbtFloat, EvqConst), node->getLine()); break;
- case EbtBool:
- unionArray->fConst = static_cast<float>((*p)->getAsTyped()->getAsConstantUnion()->getUnionArrayPointer()->bConst);
- newNode = newNode = addConstantUnion(unionArray, TType(EbtFloat, EvqConst), node->getLine()); break;
- default:
- infoSink.info.message(EPrefixInternalError, "Bad promotion node", node->getLine());
- return 0;
- }
- break;
- case EbtInt:
- switch ((*p)->getAsTyped()->getType().getBasicType()) {
- case EbtFloat:
- unionArray->iConst = static_cast<int>((*p)->getAsTyped()->getAsConstantUnion()->getUnionArrayPointer()->fConst);
- newNode = addConstantUnion(unionArray, TType(EbtInt, EvqConst), node->getLine());
- break;
- case EbtBool:
- unionArray->iConst = static_cast<int>((*p)->getAsTyped()->getAsConstantUnion()->getUnionArrayPointer()->bConst);
- newNode = addConstantUnion(unionArray, TType(EbtInt, EvqConst), node->getLine());
- break;
- default:
- infoSink.info.message(EPrefixInternalError, "Bad promotion node", node->getLine());
- return 0;
- }
- break;
- case EbtBool:
- switch ((*p)->getAsTyped()->getType().getBasicType()) {
- case EbtFloat:
- unionArray->bConst = (*p)->getAsTyped()->getAsConstantUnion()->getUnionArrayPointer()->fConst != 0.0 ;
- newNode = addConstantUnion(unionArray, TType(EbtBool, EvqConst), node->getLine());
- break;
- case EbtInt:
- unionArray->bConst = (*p)->getAsTyped()->getAsConstantUnion()->getUnionArrayPointer()->iConst != 0 ;
- newNode = addConstantUnion(unionArray, TType(EbtBool, EvqConst), node->getLine());
- break;
- default:
- infoSink.info.message(EPrefixInternalError, "Bad promotion node", node->getLine());
- return 0;
- }
- break;
- default:
- infoSink.info.message(EPrefixInternalError, "Bad promotion node", node->getLine());
- return 0;
- }
- if (newNode) {
- sequenceVector.erase(p);
- sequenceVector.insert(p, newNode);
- }
- }
- return node->getAsAggregate();
- } else if (node->getAsConstantUnion()) {
-
- return (promoteConstantUnion(promoteTo, node->getAsConstantUnion()));
- } else {
-
- //
- // Add a new newNode for the conversion.
- //
- TIntermUnary* newNode = 0;
-
- TOperator newOp = EOpNull;
- switch (promoteTo) {
- case EbtFloat:
- switch (node->getBasicType()) {
- case EbtInt: newOp = EOpConvIntToFloat; break;
- case EbtBool: newOp = EOpConvBoolToFloat; break;
- default:
- infoSink.info.message(EPrefixInternalError, "Bad promotion node", node->getLine());
- return 0;
- }
- break;
- case EbtBool:
- switch (node->getBasicType()) {
- case EbtInt: newOp = EOpConvIntToBool; break;
- case EbtFloat: newOp = EOpConvFloatToBool; break;
- default:
- infoSink.info.message(EPrefixInternalError, "Bad promotion node", node->getLine());
- return 0;
- }
- break;
- case EbtInt:
- switch (node->getBasicType()) {
- case EbtBool: newOp = EOpConvBoolToInt; break;
- case EbtFloat: newOp = EOpConvFloatToInt; break;
- default:
- infoSink.info.message(EPrefixInternalError, "Bad promotion node", node->getLine());
- return 0;
- }
- break;
- default:
- infoSink.info.message(EPrefixInternalError, "Bad promotion type", node->getLine());
- return 0;
- }
-
- TType type(promoteTo, EvqTemporary, node->getNominalSize(), node->isMatrix(), node->isArray());
- newNode = new TIntermUnary(newOp, type);
- newNode->setLine(node->getLine());
- newNode->setOperand(node);
-
- return newNode;
- }
-}
-
-//
-// Safe way to combine two nodes into an aggregate. Works with null pointers,
-// a node that's not a aggregate yet, etc.
-//
-// Returns the resulting aggregate, unless 0 was passed in for
-// both existing nodes.
-//
-TIntermAggregate* TIntermediate::growAggregate(TIntermNode* left, TIntermNode* right, TSourceLoc line)
-{
- if (left == 0 && right == 0)
- return 0;
-
- TIntermAggregate* aggNode = 0;
- if (left)
- aggNode = left->getAsAggregate();
- if (!aggNode || aggNode->getOp() != EOpNull) {
- aggNode = new TIntermAggregate;
- if (left)
- aggNode->getSequence().push_back(left);
- }
-
- if (right)
- aggNode->getSequence().push_back(right);
-
- if (line != 0)
- aggNode->setLine(line);
-
- return aggNode;
-}
-
-//
-// Turn an existing node into an aggregate.
-//
-// Returns an aggregate, unless 0 was passed in for the existing node.
-//
-TIntermAggregate* TIntermediate::makeAggregate(TIntermNode* node, TSourceLoc line)
-{
- if (node == 0)
- return 0;
-
- TIntermAggregate* aggNode = new TIntermAggregate;
- aggNode->getSequence().push_back(node);
-
- if (line != 0)
- aggNode->setLine(line);
- else
- aggNode->setLine(node->getLine());
-
- return aggNode;
-}
-
-//
-// For "if" test nodes. There are three children; a condition,
-// a true path, and a false path. The two paths are in the
-// nodePair.
-//
-// Returns the selection node created.
-//
-TIntermNode* TIntermediate::addSelection(TIntermTyped* cond, TIntermNodePair nodePair, TSourceLoc line)
-{
- //
- // For compile time constant selections, prune the code and
- // test now.
- //
-
- if (cond->getAsTyped() && cond->getAsTyped()->getAsConstantUnion()) {
- if (cond->getAsTyped()->getAsConstantUnion()->getUnionArrayPointer()->bConst)
- return nodePair.node1;
- else
- return nodePair.node2;
- }
-
- TIntermSelection* node = new TIntermSelection(cond, nodePair.node1, nodePair.node2);
- node->setLine(line);
-
- return node;
-}
-
-
-TIntermTyped* TIntermediate::addComma(TIntermTyped* left, TIntermTyped* right, TSourceLoc line)
-{
- if (left->getType().getQualifier() == EvqConst && right->getType().getQualifier() == EvqConst) {
- return right;
- } else {
- TIntermTyped *commaAggregate = growAggregate(left, right, line);
- commaAggregate->getAsAggregate()->setOperator(EOpComma);
- commaAggregate->setType(right->getType());
- commaAggregate->getTypePointer()->changeQualifier(EvqTemporary);
- return commaAggregate;
- }
-}
-
-//
-// For "?:" test nodes. There are three children; a condition,
-// a true path, and a false path. The two paths are specified
-// as separate parameters.
-//
-// Returns the selection node created, or 0 if one could not be.
-//
-TIntermTyped* TIntermediate::addSelection(TIntermTyped* cond, TIntermTyped* trueBlock, TIntermTyped* falseBlock, TSourceLoc line)
-{
- //
- // Get compatible types.
- //
- TIntermTyped* child = addConversion(EOpSequence, trueBlock->getType(), falseBlock);
- if (child)
- falseBlock = child;
- else {
- child = addConversion(EOpSequence, falseBlock->getType(), trueBlock);
- if (child)
- trueBlock = child;
- else
- return 0;
- }
-
- //
- // See if condition is constant, and select now.
- //
-
- if (cond->getAsConstantUnion()) {
- if (cond->getAsConstantUnion()->getUnionArrayPointer()->bConst)
- return trueBlock;
- else
- return falseBlock;
- }
-
- //
- // Make a selection node.
- //
- TIntermSelection* node = new TIntermSelection(cond, trueBlock, falseBlock, trueBlock->getType());
- node->setLine(line);
-
- return node;
-}
-
-//
-// Constant terminal nodes. Has a union that contains bool, float or int constants
-//
-// Returns the constant union node created.
-//
-
-TIntermConstantUnion* TIntermediate::addConstantUnion(constUnion* unionArrayPointer, const TType& t, TSourceLoc line)
-{
- TIntermConstantUnion* node = new TIntermConstantUnion(unionArrayPointer, t);
- node->setLine(line);
-
- return node;
-}
-
-TIntermTyped* TIntermediate::addSwizzle(TVectorFields& fields, TSourceLoc line)
-{
-
- TIntermAggregate* node = new TIntermAggregate(EOpSequence);
-
- node->setLine(line);
- TIntermConstantUnion* constIntNode;
- TIntermSequence &sequenceVector = node->getSequence();
- constUnion* unionArray;
-
- for (int i = 0; i < fields.num; i++) {
- unionArray = new constUnion[1];
- unionArray->iConst = fields.offsets[i];
- constIntNode = addConstantUnion(unionArray, TType(EbtInt, EvqConst), line);
- sequenceVector.push_back(constIntNode);
- }
-
- return node;
-}
-
-//
-// Create loop nodes.
-//
-TIntermNode* TIntermediate::addLoop(TIntermNode* body, TIntermTyped* test, TIntermTyped* terminal, bool testFirst, TSourceLoc line)
-{
- TIntermNode* node = new TIntermLoop(body, test, terminal, testFirst);
- node->setLine(line);
-
- return node;
-}
-
-//
-// Add branches.
-//
-TIntermBranch* TIntermediate::addBranch(TOperator branchOp, TSourceLoc line)
-{
- return addBranch(branchOp, 0, line);
-}
-
-TIntermBranch* TIntermediate::addBranch(TOperator branchOp, TIntermTyped* expression, TSourceLoc line)
-{
- TIntermBranch* node = new TIntermBranch(branchOp, expression);
- node->setLine(line);
-
- return node;
-}
-
-//
-// This is to be executed once the final root is put on top by the parsing
-// process.
-//
-bool TIntermediate::postProcess(TIntermNode* root, EShLanguage language)
-{
- if (root == 0)
- return true;
-
- //
- // First, finish off the top level sequence, if any
- //
- TIntermAggregate* aggRoot = root->getAsAggregate();
- if (aggRoot && aggRoot->getOp() == EOpNull)
- aggRoot->setOperator(EOpSequence);
-
- return true;
-}
-
-//
-// This deletes the tree.
-//
-void TIntermediate::remove(TIntermNode* root)
-{
- if (root)
- RemoveAllTreeNodes(root);
-}
-
-////////////////////////////////////////////////////////////////
-//
-// Member functions of the nodes used for building the tree.
-//
-////////////////////////////////////////////////////////////////
-
-//
-// Say whether or not an operation node changes the value of a variable.
-//
-// Returns true if state is modified.
-//
-bool TIntermOperator::modifiesState() const
-{
- switch (op) {
- case EOpPostIncrement:
- case EOpPostDecrement:
- case EOpPreIncrement:
- case EOpPreDecrement:
- case EOpAssign:
- case EOpAddAssign:
- case EOpSubAssign:
- case EOpMulAssign:
- case EOpVectorTimesMatrixAssign:
- case EOpVectorTimesScalarAssign:
- case EOpMatrixTimesScalarAssign:
- case EOpMatrixTimesMatrixAssign:
- case EOpDivAssign:
- case EOpModAssign:
- case EOpAndAssign:
- case EOpInclusiveOrAssign:
- case EOpExclusiveOrAssign:
- case EOpLeftShiftAssign:
- case EOpRightShiftAssign:
- return true;
- default:
- return false;
- }
-}
-
-//
-// returns true if the operator is for one of the constructors
-//
-bool TIntermOperator::isConstructor() const
-{
- switch (op) {
- case EOpConstructVec2:
- case EOpConstructVec3:
- case EOpConstructVec4:
- case EOpConstructMat2:
- case EOpConstructMat3:
- case EOpConstructMat4:
- case EOpConstructFloat:
- case EOpConstructIVec2:
- case EOpConstructIVec3:
- case EOpConstructIVec4:
- case EOpConstructInt:
- case EOpConstructBVec2:
- case EOpConstructBVec3:
- case EOpConstructBVec4:
- case EOpConstructBool:
- case EOpConstructStruct:
- return true;
- default:
- return false;
- }
-}
-//
-// Make sure the type of a unary operator is appropriate for its
-// combination of operation and operand type.
-//
-// Returns false in nothing makes sense.
-//
-bool TIntermUnary::promote(TInfoSink&)
-{
- switch (op) {
- case EOpLogicalNot:
- if (operand->getBasicType() != EbtBool)
- return false;
- break;
- case EOpBitwiseNot:
- if (operand->getBasicType() != EbtInt)
- return false;
- break;
- case EOpNegative:
- case EOpPostIncrement:
- case EOpPostDecrement:
- case EOpPreIncrement:
- case EOpPreDecrement:
- if (operand->getBasicType() == EbtBool)
- return false;
- break;
-
- // operators for built-ins are already type checked against their prototype
- case EOpAny:
- case EOpAll:
- case EOpVectorLogicalNot:
- return true;
-
- default:
- if (operand->getBasicType() != EbtFloat)
- return false;
- }
-
- setType(operand->getType());
-
- return true;
-}
-
-//
-// Establishes the type of the resultant operation, as well as
-// makes the operator the correct one for the operands.
-//
-// Returns false if operator can't work on operands.
-//
-bool TIntermBinary::promote(TInfoSink& infoSink)
-{
- int size = left->getNominalSize();
- if (right->getNominalSize() > size)
- size = right->getNominalSize();
-
- TBasicType type = left->getBasicType();
-
- //
- // Don't operate on arrays.
- //
- if (left->isArray() || right->isArray())
- return false;
-
- //
- // Base assumption: just make the type the same as the left
- // operand. Then only deviations from this need be coded.
- //
- setType(TType(type, EvqTemporary, left->getNominalSize(), left->isMatrix()));
-
- //
- // All scalars. Code after this test assumes this case is removed!
- //
- if (size == 1) {
-
- switch (op) {
-
- //
- // Promote to conditional
- //
- case EOpEqual:
- case EOpNotEqual:
- case EOpLessThan:
- case EOpGreaterThan:
- case EOpLessThanEqual:
- case EOpGreaterThanEqual:
- setType(TType(EbtBool));
- break;
-
- //
- // And and Or operate on conditionals
- //
- case EOpLogicalAnd:
- case EOpLogicalOr:
- if (left->getBasicType() != EbtBool || right->getBasicType() != EbtBool)
- return false;
- setType(TType(EbtBool));
- break;
-
- //
- // Check for integer only operands.
- //
- case EOpMod:
- case EOpRightShift:
- case EOpLeftShift:
- case EOpAnd:
- case EOpInclusiveOr:
- case EOpExclusiveOr:
- if (left->getBasicType() != EbtInt || right->getBasicType() != EbtInt)
- return false;
- break;
- case EOpModAssign:
- case EOpAndAssign:
- case EOpInclusiveOrAssign:
- case EOpExclusiveOrAssign:
- case EOpLeftShiftAssign:
- case EOpRightShiftAssign:
- if (left->getBasicType() != EbtInt || right->getBasicType() != EbtInt)
- return false;
- // fall through
-
- //
- // Everything else should have matching types
- //
- default:
- if (left->getBasicType() != right->getBasicType() ||
- left->isMatrix() != right->isMatrix())
- return false;
- }
-
- return true;
- }
-
- //
- // Are the sizes compatible?
- //
- if ( left->getNominalSize() != size && left->getNominalSize() != 1 ||
- right->getNominalSize() != size && right->getNominalSize() != 1)
- return false;
-
- //
- // Can these two operands be combined?
- //
- switch (op) {
- case EOpMul:
- if (!left->isMatrix() && right->isMatrix()) {
- if (left->isVector())
- op = EOpVectorTimesMatrix;
- else {
- op = EOpMatrixTimesScalar;
- setType(TType(type, EvqTemporary, size, true));
- }
- } else if (left->isMatrix() && !right->isMatrix()) {
- if (right->isVector()) {
- op = EOpMatrixTimesVector;
- setType(TType(type, EvqTemporary, size, false));
- } else {
- op = EOpMatrixTimesScalar;
- }
- } else if (left->isMatrix() && right->isMatrix()) {
- op = EOpMatrixTimesMatrix;
- } else if (!left->isMatrix() && !right->isMatrix()) {
- if (left->isVector() && right->isVector()) {
- // leave as component product
- } else if (left->isVector() || right->isVector()) {
- op = EOpVectorTimesScalar;
- setType(TType(type, EvqTemporary, size, false));
- }
- } else {
- infoSink.info.message(EPrefixInternalError, "Missing elses", getLine());
- return false;
- }
- break;
- case EOpMulAssign:
- if (!left->isMatrix() && right->isMatrix()) {
- if (left->isVector())
- op = EOpVectorTimesMatrixAssign;
- else {
- return false;
- }
- } else if (left->isMatrix() && !right->isMatrix()) {
- if (right->isVector()) {
- return false;
- } else {
- op = EOpMatrixTimesScalarAssign;
- }
- } else if (left->isMatrix() && right->isMatrix()) {
- op = EOpMatrixTimesMatrixAssign;
- } else if (!left->isMatrix() && !right->isMatrix()) {
- if (left->isVector() && right->isVector()) {
- // leave as component product
- } else if (left->isVector() || right->isVector()) {
- if (! left->isVector())
- return false;
- op = EOpVectorTimesScalarAssign;
- setType(TType(type, EvqTemporary, size, false));
- }
- } else {
- infoSink.info.message(EPrefixInternalError, "Missing elses", getLine());
- return false;
- }
- break;
- case EOpAssign:
- if (left->getNominalSize() != right->getNominalSize())
- return false;
- // fall through
- case EOpAdd:
- case EOpSub:
- case EOpDiv:
- case EOpMod:
- case EOpAddAssign:
- case EOpSubAssign:
- case EOpDivAssign:
- case EOpModAssign:
- if (left->isMatrix() && right->isVector() ||
- left->isVector() && right->isMatrix() ||
- left->getBasicType() != right->getBasicType())
- return false;
- setType(TType(type, EvqTemporary, size, left->isMatrix() || right->isMatrix()));
- break;
-
- case EOpEqual:
- case EOpNotEqual:
- case EOpLessThan:
- case EOpGreaterThan:
- case EOpLessThanEqual:
- case EOpGreaterThanEqual:
- if (left->isMatrix() && right->isVector() ||
- left->isVector() && right->isMatrix() ||
- left->getBasicType() != right->getBasicType())
- return false;
- setType(TType(EbtBool));
- break;
-
-default:
- return false;
- }
-
- //
- // One more check for assignment. The Resulting type has to match the left operand.
- //
- switch (op) {
- case EOpAssign:
- case EOpAddAssign:
- case EOpSubAssign:
- case EOpMulAssign:
- case EOpDivAssign:
- case EOpModAssign:
- case EOpAndAssign:
- case EOpInclusiveOrAssign:
- case EOpExclusiveOrAssign:
- case EOpLeftShiftAssign:
- case EOpRightShiftAssign:
- if (getType() != left->getType())
- return false;
- break;
- default:
- break;
- }
-
- return true;
-}
-
-bool compareStructure(const TType& leftNodeType, constUnion* rightUnionArray, constUnion* leftUnionArray, int& index)
-{
- TTypeList* fields = leftNodeType.getStruct();
-
- size_t structSize = fields->size();
-
- for (size_t j = 0; j < structSize; j++) {
- int size = (*fields)[j].type->getInstanceSize();
- for (int i = 0; i < size; i++) {
- switch ((*fields)[j].type->getBasicType()) {
- case EbtFloat:
- if (leftUnionArray[index].fConst != rightUnionArray[index].fConst)
- return false;
- index++;
- break;
- case EbtInt:
- if (leftUnionArray[index].iConst != rightUnionArray[index].iConst)
- return false;
- index++;
- break;
- case EbtBool:
- if (leftUnionArray[index].bConst != rightUnionArray[index].bConst)
- return false;
- index++;
- break;
- case EbtStruct:
- if (!compareStructure(*(*fields)[j].type, rightUnionArray, leftUnionArray, index))
- return false;
- break;
- default:
- assert(true && "Cannot compare");
- break;
- }
-
- }
- }
- return true;
-}
-
-//
-// The fold functions see if an operation on a constant can be done in place,
-// without generating run-time code.
-//
-// Returns the node to keep using, which may or may not be the node passed in.
-//
-
-TIntermTyped* TIntermConstantUnion::fold(TOperator op, TIntermTyped* constantNode, TInfoSink& infoSink, bool leftOperand)
-{
- constUnion *unionArray = this->getUnionArrayPointer();
-
- if (constantNode) {
- if (constantNode->getAsConstantUnion() && constantNode->getSize() == 1 && constantNode->getType().getBasicType() != EbtStruct
- && this->getSize() > 1) {
- TIntermConstantUnion *node = constantNode->getAsConstantUnion();
- TIntermConstantUnion *newNode;
- constUnion* tempConstArray;
- switch(op) {
- case EOpAdd:
- tempConstArray = new constUnion[this->getSize()];
- {// support MSVC++6.0
- for (int i = 0; i < this->getSize(); i++) {
- switch (this->getType().getBasicType()) {
- case EbtFloat: tempConstArray[i].fConst = unionArray[i].fConst + node->getUnionArrayPointer()->fConst; break;
- case EbtInt: tempConstArray[i].iConst = unionArray[i].iConst + node->getUnionArrayPointer()->iConst; break;
- default:
- infoSink.info.message(EPrefixInternalError, "Constant folding cannot be done for \"+\"", this->getLine());
- return 0;
- }
- }
- }
- break;
- case EOpMatrixTimesScalar:
- case EOpVectorTimesScalar:
- tempConstArray = new constUnion[this->getSize()];
- {// support MSVC++6.0
- for (int i = 0; i < this->getSize(); i++) {
- switch (this->getType().getBasicType()) {
- case EbtFloat: tempConstArray[i].fConst = unionArray[i].fConst * node->getUnionArrayPointer()->fConst; break;
- case EbtInt: tempConstArray[i].iConst = unionArray[i].iConst * node->getUnionArrayPointer()->iConst; break;
- default:
- infoSink.info.message(EPrefixInternalError, "Constant folding cannot be done for \"*\"", this->getLine());
- return 0;
- }
- }
- }
- break;
- case EOpSub:
- tempConstArray = new constUnion[this->getSize()];
- {// support MSVC++6.0
- for (int i = 0; i < this->getSize(); i++) {
- switch (this->getType().getBasicType()) {
- case EbtFloat:
- if (leftOperand)
- tempConstArray[i].fConst = unionArray[i].fConst - node->getUnionArrayPointer()->fConst;
- else
- tempConstArray[i].fConst = node->getUnionArrayPointer()->fConst - unionArray[i].fConst;
- break;
-
- case EbtInt:
- if (leftOperand)
- tempConstArray[i].iConst = unionArray[i].iConst - node->getUnionArrayPointer()->iConst;
- else
- tempConstArray[i].iConst = node->getUnionArrayPointer()->iConst - unionArray[i].iConst;
- break;
- default:
- infoSink.info.message(EPrefixInternalError, "Constant folding cannot be done for \"-\"", this->getLine());
- return 0;
- }
- }
- }
- break;
-
- case EOpDiv:
- tempConstArray = new constUnion[this->getSize()];
- {// support MSVC++6.0
- for (int i = 0; i < this->getSize(); i++) {
- switch (this->getType().getBasicType()) {
- case EbtFloat:
- if (leftOperand) {
- if (node->getUnionArrayPointer()->fConst == 0.0) {
- infoSink.info.message(EPrefixWarning, "Divide by zero error during constant folding", this->getLine());
- tempConstArray[i].fConst = FLT_MAX;
- } else
- tempConstArray[i].fConst = unionArray[i].fConst / node->getUnionArrayPointer()->fConst;
- } else {
- if (unionArray[i].fConst == 0.0) {
- infoSink.info.message(EPrefixWarning, "Divide by zero error during constant folding", this->getLine());
- tempConstArray[i].fConst = FLT_MAX;
- } else
- tempConstArray[i].fConst = node->getUnionArrayPointer()->fConst / unionArray[i].fConst;
- }
- break;
-
- case EbtInt:
- if (leftOperand) {
- if (node->getUnionArrayPointer()->iConst == 0) {
- infoSink.info.message(EPrefixWarning, "Divide by zero error during constant folding", this->getLine());
- tempConstArray[i].iConst = INT_MAX;
- } else
- tempConstArray[i].iConst = unionArray[i].iConst / node->getUnionArrayPointer()->iConst;
- } else {
- if (unionArray[i].iConst == 0) {
- infoSink.info.message(EPrefixWarning, "Divide by zero error during constant folding", this->getLine());
- tempConstArray[i].iConst = INT_MAX;
- } else
- tempConstArray[i].iConst = node->getUnionArrayPointer()->iConst / unionArray[i].iConst;
- }
- break;
- default:
- infoSink.info.message(EPrefixInternalError, "Constant folding cannot be done for \"/\"", this->getLine());
- return 0;
- }
- }
- }
- break;
-
- case EOpLogicalAnd: // this code is written for possible future use, will not get executed currently
- tempConstArray = new constUnion[this->getSize()];
- {// support MSVC++6.0
- for (int i = 0; i < this->getSize(); i++) {
- switch (this->getType().getBasicType()) {
- case EbtBool: tempConstArray[i].bConst = unionArray[i].bConst && node->getUnionArrayPointer()->bConst; break;
- default:
- infoSink.info.message(EPrefixInternalError, "Constant folding cannot be done for \"&&\"", this->getLine());
- return 0;
- }
- }
- }
- break;
-
- case EOpLogicalXor: // this code is written for possible future use, will not get executed currently
- tempConstArray = new constUnion[this->getSize()];
- {// support MSVC++6.0
- for (int i = 0; i < this->getSize(); i++) {
- switch (this->getType().getBasicType()) {
- case EbtBool: tempConstArray[i].bConst = unionArray[i].bConst ^ node->getUnionArrayPointer()->bConst; break;
- default:
- infoSink.info.message(EPrefixInternalError, "Constant folding cannot be done for \"^^\"", this->getLine());
- return 0;
- }
- }
- }
- break;
-
- case EOpLogicalOr: // this code is written for possible future use, will not get executed currently
- tempConstArray = new constUnion[this->getSize()];
- {// support MSVC++6.0
- for (int i = 0; i < this->getSize(); i++) {
- switch (this->getType().getBasicType()) {
- case EbtBool: tempConstArray[i].bConst = unionArray[i].bConst || node->getUnionArrayPointer()->bConst; break;
- default:
- infoSink.info.message(EPrefixInternalError, "Constant folding cannot be done for \"||\"", this->getLine());
- return 0;
- }
- }
- }
- break;
-
- default:
- infoSink.info.message(EPrefixInternalError, "Invalid operator for constant folding", this->getLine());
- return 0;
- }
- newNode = new TIntermConstantUnion(tempConstArray, this->getType());
- newNode->setLine(this->getLine());
-
- return newNode;
- } else if (constantNode->getAsConstantUnion() && (this->getSize() > 1 || this->getType().getBasicType() == EbtStruct)) {
- TIntermConstantUnion *node = constantNode->getAsConstantUnion();
- constUnion *rightUnionArray = node->getUnionArrayPointer();
- constUnion* tempConstArray = 0;
- TIntermConstantUnion *tempNode;
- int index = 0;
- bool boolNodeFlag = false;
- switch(op) {
- case EOpAdd:
- tempConstArray = new constUnion[this->getSize()];
- {// support MSVC++6.0
- for (int i = 0; i < this->getSize(); i++) {
- switch (this->getType().getBasicType()) {
- case EbtFloat: tempConstArray[i].fConst = unionArray[i].fConst + rightUnionArray[i].fConst; break;
- case EbtInt: tempConstArray[i].iConst = unionArray[i].iConst + rightUnionArray[i].iConst; break;
- default:
- infoSink.info.message(EPrefixInternalError, "Constant folding cannot be done for \"+\"", this->getLine());
- return 0;
- }
- }
- }
- break;
- case EOpSub:
- tempConstArray = new constUnion[this->getSize()];
- {// support MSVC++6.0
- for (int i = 0; i < this->getSize(); i++) {
- switch (this->getType().getBasicType()) {
- case EbtFloat:
- if (leftOperand)
- tempConstArray[i].fConst = unionArray[i].fConst - rightUnionArray[i].fConst;
- else
- tempConstArray[i].fConst = rightUnionArray[i].fConst - unionArray[i].fConst;
- break;
-
- case EbtInt:
- if (leftOperand)
- tempConstArray[i].iConst = unionArray[i].iConst - rightUnionArray[i].iConst;
- else
- tempConstArray[i].iConst = rightUnionArray[i].iConst - unionArray[i].iConst;
- break;
-
- default:
- infoSink.info.message(EPrefixInternalError, "Constant folding cannot be done for \"-\"", this->getLine());
- return 0;
- }
- }
- }
- break;
- case EOpMul:
- if (this->isVector()) { // two vectors multiplied together
- int size = this->getSize();
- tempConstArray = new constUnion[size];
-
- for (int i = 0; i < size; i++) {
- switch (this->getType().getBasicType()) {
- case EbtFloat: tempConstArray[i].fConst = unionArray[i].fConst * rightUnionArray[i].fConst; break;
- case EbtInt: tempConstArray[i].iConst = unionArray[i].iConst * rightUnionArray[i].iConst; break;
- default:
- infoSink.info.message(EPrefixInternalError, "Constant folding cannot be done for vector multiply", this->getLine());
- return 0;
- }
- }
- }
- break;
- case EOpMatrixTimesMatrix:
- if (this->getType().getBasicType() != EbtFloat || node->getBasicType() != EbtFloat) {
- infoSink.info.message(EPrefixInternalError, "Constant Folding cannot be done for matrix multiply", this->getLine());
- return 0;
- }
- {// support MSVC++6.0
- int size = this->getNominalSize();
- tempConstArray = new constUnion[size*size];
- for (int row = 0; row < size; row++) {
- for (int column = 0; column < size; column++) {
- tempConstArray[size * column + row].fConst = 0.0;
- for (int i = 0; i < size; i++) {
- tempConstArray[size * column + row].fConst += unionArray[i * size + row].fConst * (rightUnionArray[column * size + i].fConst);
- }
- }
- }
- }
- break;
- case EOpDiv:
- tempConstArray = new constUnion[this->getSize()];
- {// support MSVC++6.0
- for (int i = 0; i < this->getSize(); i++) {
- switch (this->getType().getBasicType()) {
- case EbtFloat:
- if (leftOperand) {
- if (rightUnionArray[i].fConst == 0.0) {
- infoSink.info.message(EPrefixWarning, "Divide by zero error during constant folding", this->getLine());
- tempConstArray[i].fConst = FLT_MAX;
- } else
- tempConstArray[i].fConst = unionArray[i].fConst / rightUnionArray[i].fConst;
- } else {
- if (unionArray[i].fConst == 0.0) {
- infoSink.info.message(EPrefixWarning, "Divide by zero error during constant folding", this->getLine());
- tempConstArray[i].fConst = FLT_MAX;
- } else
- tempConstArray[i].fConst = rightUnionArray[i].fConst / unionArray[i].fConst;
- }
- break;
-
- case EbtInt:
- if (leftOperand) {
- if (rightUnionArray[i].iConst == 0) {
- infoSink.info.message(EPrefixWarning, "Divide by zero error during constant folding", this->getLine());
- tempConstArray[i].iConst = INT_MAX;
- } else
- tempConstArray[i].iConst = unionArray[i].iConst / rightUnionArray[i].iConst;
- } else {
- if (unionArray[i].iConst == 0) {
- infoSink.info.message(EPrefixWarning, "Divide by zero error during constant folding", this->getLine());
- tempConstArray[i].iConst = INT_MAX;
- } else
- tempConstArray[i].iConst = rightUnionArray[i].iConst / unionArray[i].iConst;
- }
- break;
- default:
- infoSink.info.message(EPrefixInternalError, "Constant folding cannot be done for \"/\"", this->getLine());
- return 0;
- }
- }
- }
- break;
-
- case EOpMatrixTimesVector:
- if (node->getBasicType() != EbtFloat) {
- infoSink.info.message(EPrefixInternalError, "Constant Folding cannot be done for matrix times vector", this->getLine());
- return 0;
- }
- tempConstArray = new constUnion[this->getNominalSize()];
-
- {// support MSVC++6.0
- for (int size = this->getNominalSize(), i = 0; i < size; i++) {
- tempConstArray[i].fConst = 0.0;
- for (int j = 0; j < size; j++) {
- tempConstArray[i].fConst += ((unionArray[j*size + i].fConst) * rightUnionArray[j].fConst);
- }
- }
- }
-
- tempNode = new TIntermConstantUnion(tempConstArray, node->getType());
- tempNode->setLine(this->getLine());
-
- return tempNode;
-
- case EOpVectorTimesMatrix:
- if (this->getType().getBasicType() != EbtFloat) {
- infoSink.info.message(EPrefixInternalError, "Constant Folding cannot be done for vector times matrix", this->getLine());
- return 0;
- }
-
- tempConstArray = new constUnion[this->getNominalSize()];
- {// support MSVC++6.0
- for (int size = this->getNominalSize(), i = 0; i < size; i++) {
- tempConstArray[i].fConst = 0.0;
- for (int j = 0; j < size; j++) {
- tempConstArray[i].fConst += ((unionArray[j].fConst) * rightUnionArray[i*size + j].fConst);
- }
- }
- }
- break;
-
- case EOpLogicalAnd: // this code is written for possible future use, will not get executed currently
- tempConstArray = new constUnion[this->getSize()];
- {// support MSVC++6.0
- for (int i = 0; i < this->getSize(); i++) {
- switch (this->getType().getBasicType()) {
- case EbtBool: tempConstArray[i].bConst = unionArray[i].bConst && rightUnionArray[i].bConst; break;
- default:
- infoSink.info.message(EPrefixInternalError, "Constant folding cannot be done for \"&&\"", this->getLine());
- return 0;
- }
- }
- }
- break;
-
- case EOpLogicalXor: // this code is written for possible future use, will not get executed currently
- tempConstArray = new constUnion[this->getSize()];
- {// support MSVC++6.0
- for (int i = 0; i < this->getSize(); i++) {
- switch (this->getType().getBasicType()) {
- case EbtBool: tempConstArray[i].bConst = unionArray[i].bConst ^ rightUnionArray[i].bConst; break;
- default:
- infoSink.info.message(EPrefixInternalError, "Constant folding cannot be done for \"^^\"", this->getLine());
- return 0;
- }
- }
- }
- break;
-
- case EOpLogicalOr: // this code is written for possible future use, will not get executed currently
- tempConstArray = new constUnion[this->getSize()];
- {// support MSVC++6.0
- for (int i = 0; i < this->getSize(); i++) {
- switch (this->getType().getBasicType()) {
- case EbtBool: tempConstArray[i].bConst = unionArray[i].bConst || rightUnionArray[i].bConst; break;
- default:
- infoSink.info.message(EPrefixInternalError, "Constant folding cannot be done for \"||\"", this->getLine());
- return 0;
- }
- }
- }
- break;
-
- case EOpEqual:
-
- switch (this->getType().getBasicType()) {
- case EbtFloat:
- {// support MSVC++6.0
- for (int i = 0; i < this->getSize(); i++) {
- if (unionArray[i].fConst != rightUnionArray[i].fConst) {
- boolNodeFlag = true;
- break; // break out of for loop
- }
- }
- }
- break;
-
- case EbtInt:
- {// support MSVC++6.0
- for (int i = 0; i < this->getSize(); i++) {
- if (unionArray[i].iConst != rightUnionArray[i].iConst) {
- boolNodeFlag = true;
- break; // break out of for loop
- }
- }
- }
- break;
- case EbtBool:
- {// support MSVC++6.0
- for (int i = 0; i < this->getSize(); i++) {
- if (unionArray[i].bConst != rightUnionArray[i].bConst) {
- boolNodeFlag = true;
- break; // break out of for loop
- }
- }
- }
- break;
- case EbtStruct:
- if (!compareStructure(node->getType(), node->getUnionArrayPointer(), unionArray, index))
- boolNodeFlag = true;
- break;
-
- default:
- infoSink.info.message(EPrefixInternalError, "Constant folding cannot be done for \"==\"", this->getLine());
- return 0;
- }
-
- tempConstArray = new constUnion[1];
- if (!boolNodeFlag) {
- tempConstArray->bConst = true;
- }
- else {
- tempConstArray->bConst = false;
- }
-
- tempNode = new TIntermConstantUnion(tempConstArray, TType(EbtBool, EvqConst));
- tempNode->setLine(this->getLine());
-
- return tempNode;
-
- case EOpNotEqual:
- switch (this->getType().getBasicType()) {
- case EbtFloat:
- {// support MSVC++6.0
- for (int i = 0; i < this->getSize(); i++) {
- if (unionArray[i].fConst == rightUnionArray[i].fConst) {
- boolNodeFlag = true;
- break; // break out of for loop
- }
- }
- }
- break;
-
- case EbtInt:
- {// support MSVC++6.0
- for (int i = 0; i < this->getSize(); i++) {
- if (unionArray[i].iConst == rightUnionArray[i].iConst) {
- boolNodeFlag = true;
- break; // break out of for loop
- }
- }
- }
- break;
- case EbtBool:
- {// support MSVC++6.0
- for (int i = 0; i < this->getSize(); i++) {
- if (unionArray[i].bConst == rightUnionArray[i].bConst) {
- boolNodeFlag = true;
- break; // break out of for loop
- }
- }
- }
- break;
- case EbtStruct:
- if (compareStructure(node->getType(), node->getUnionArrayPointer(), unionArray, index))
- boolNodeFlag = true;
- break;
- default:
- infoSink.info.message(EPrefixInternalError, "Constant folding cannot be done for \"!=\"", this->getLine());
- return 0;
- }
-
- tempConstArray = new constUnion[1];
- if (!boolNodeFlag) {
- tempConstArray->bConst = true;
- }
- else {
- tempConstArray->bConst = false;
- }
-
- tempNode = new TIntermConstantUnion(tempConstArray, TType(EbtBool, EvqConst));
- tempNode->setLine(this->getLine());
-
- return tempNode;
-
- default:
- infoSink.info.message(EPrefixInternalError, "Invalid operator for constant folding", this->getLine());
- return 0;
- }
- tempNode = new TIntermConstantUnion(tempConstArray, this->getType());
- tempNode->setLine(this->getLine());
-
- return tempNode;
- } else if (this->getSize() == 1 && this->getType().getBasicType() != EbtStruct
- && constantNode->getSize() == 1 && constantNode->getType().getBasicType() != EbtStruct ) { // scalar constant folding
- constUnion *unionArray = new constUnion[1];
- TIntermConstantUnion* newNode = 0;
-
- switch (this->getType().getBasicType()) {
- case EbtInt:
- {
- //
- // Dealing with two operands, us and constant.
- //
- // Do Binary operations.
- //
- int rightValue = constantNode->getAsConstantUnion()->getUnionArrayPointer()->iConst;
- int leftValue = this->getUnionArrayPointer()->iConst;
- //int line = this->getLine();
-
- switch(op) {
- //?? add constant intrinsics
- case EOpAdd: unionArray->iConst = leftValue + rightValue; break;
- case EOpSub: unionArray->iConst = leftValue - rightValue; break;
- case EOpMul: unionArray->iConst = leftValue * rightValue; break;
- case EOpDiv:
- if (rightValue == 0) {
- infoSink.info.message(EPrefixWarning, "Divide by zero error during constant folding", this->getLine());
- unionArray->iConst = INT_MAX;
- } else
- unionArray->iConst = leftValue / rightValue; break;
-
- case EOpMod: unionArray->iConst = leftValue % rightValue; break;
-
- case EOpRightShift: unionArray->iConst = leftValue >> rightValue; break;
- case EOpLeftShift: unionArray->iConst = leftValue << rightValue; break;
-
- case EOpAnd: unionArray->iConst = leftValue & rightValue; break;
- case EOpInclusiveOr: unionArray->iConst = leftValue | rightValue; break;
- case EOpExclusiveOr: unionArray->iConst = leftValue ^ rightValue; break;
-
- // the following assume it's okay to have memory leaks
- case EOpEqual:
- unionArray->bConst = leftValue == rightValue;
- newNode = new TIntermConstantUnion(unionArray, TType(EbtBool, EvqConst));
- break;
- case EOpNotEqual:
- unionArray->bConst = leftValue != rightValue;
- newNode = new TIntermConstantUnion(unionArray, TType(EbtBool, EvqConst));
- break;
- case EOpLessThan:
- unionArray->bConst = leftValue < rightValue;
- newNode = new TIntermConstantUnion(unionArray, TType(EbtBool, EvqConst));
- break;
- case EOpGreaterThan:
- unionArray->bConst = leftValue > rightValue;
- newNode = new TIntermConstantUnion(unionArray, TType(EbtBool, EvqConst));
- break;
- case EOpLessThanEqual:
- unionArray->bConst = leftValue <= rightValue;
- newNode = new TIntermConstantUnion(unionArray, TType(EbtBool, EvqConst));
- break;
- case EOpGreaterThanEqual:
- unionArray->bConst = leftValue >= rightValue;
- newNode = new TIntermConstantUnion(unionArray, TType(EbtBool, EvqConst));
- break;
-
- default:
- //infoSink.info.message(EPrefixInternalError, "Binary operation not folded into constant int", line);
- return 0;
- }
- if (!newNode) {
- newNode = new TIntermConstantUnion(unionArray, TType(EbtInt, EvqConst));
- }
- newNode->setLine(constantNode->getLine());
- return newNode;
- }
- case EbtFloat:
- {
- float rightValue = constantNode->getAsConstantUnion()->getUnionArrayPointer()->fConst;
- float leftValue = this->getUnionArrayPointer()->fConst;
-
- switch(op) {
- //?? add constant intrinsics
- case EOpAdd: unionArray->fConst = leftValue + rightValue; break;
- case EOpSub: unionArray->fConst = leftValue - rightValue; break;
- case EOpMul: unionArray->fConst = leftValue * rightValue; break;
- case EOpDiv:
- if (rightValue == 0.0) {
- infoSink.info.message(EPrefixWarning, "Divide by zero error during constant folding", this->getLine());
- unionArray->fConst = FLT_MAX;
- } else
- unionArray->fConst = leftValue / rightValue; break;
-
- // the following assume it's okay to have memory leaks (cleaned up by pool allocator)
- case EOpEqual:
- unionArray->bConst = leftValue == rightValue;
- newNode = new TIntermConstantUnion(unionArray, TType(EbtBool, EvqConst));
- break;
- case EOpNotEqual:
- unionArray->bConst = leftValue != rightValue;
- newNode = new TIntermConstantUnion(unionArray, TType(EbtBool, EvqConst));
- break;
- case EOpLessThan:
- unionArray->bConst = leftValue < rightValue;
- newNode = new TIntermConstantUnion(unionArray, TType(EbtBool, EvqConst));
- break;
- case EOpGreaterThan:
- unionArray->bConst = leftValue > rightValue;
- newNode = new TIntermConstantUnion(unionArray, TType(EbtBool, EvqConst));
- break;
- case EOpLessThanEqual:
- unionArray->bConst = leftValue <= rightValue;
- newNode = new TIntermConstantUnion(unionArray, TType(EbtBool, EvqConst));
- break;
- case EOpGreaterThanEqual:
- unionArray->bConst = leftValue >= rightValue;
- newNode = new TIntermConstantUnion(unionArray, TType(EbtBool, EvqConst));
- break;
-
- default:
- //infoSink.info.message(EPrefixInternalError, "Binary operation not folded into constant float", line);
- return 0;
- }
- if (!newNode) {
- newNode = new TIntermConstantUnion(unionArray, TType(EbtFloat, EvqConst));
- }
- newNode->setLine(constantNode->getLine());
- return newNode;
- }
- case EbtBool:
- {
- bool rightValue = constantNode->getAsConstantUnion()->getUnionArrayPointer()->bConst;
- bool leftValue = this->getUnionArrayPointer()->bConst;
-
- switch(op) {
- //?? add constant intrinsics
- case EOpLogicalAnd: unionArray->bConst = leftValue & rightValue; break;
- case EOpLogicalXor: unionArray->bConst = leftValue ^ rightValue; break;
- case EOpLogicalOr: unionArray->bConst = leftValue | rightValue; break;
- default:
- infoSink.info.message(EPrefixInternalError, "Binary operator cannot be folded into constant bool", line);
- return 0;
- }
- newNode = new TIntermConstantUnion(unionArray, TType(EbtBool, EvqConst));
- newNode->setLine(constantNode->getLine());
- return newNode;
- }
- default:
- infoSink.info.message(EPrefixInternalError, "Cannot fold constant", this->getLine());
- return 0;
- }
- }
- } else {
- //
- // Do unary operations
- //
- TIntermConstantUnion *newNode = 0;
- constUnion* tempConstArray = new constUnion[this->getSize()];
- if (this->getSize() > 1) {
- for (int i = 0; i < this->getSize(); i++) {
- switch(op) {
- case EOpNegative:
- switch (this->getType().getBasicType()) {
- case EbtFloat: tempConstArray[i].fConst = -(unionArray[i].fConst); break;
- case EbtInt: tempConstArray[i].iConst = -(unionArray[i].iConst); break;
- default:
- infoSink.info.message(EPrefixInternalError, "Unary operation not folded into constant", this->getLine());
- return 0;
- }
- break;
- case EOpLogicalNot: // this code is written for possible future use, will not get executed currently
- switch (this->getType().getBasicType()) {
- case EbtBool: tempConstArray[i].bConst = !(unionArray[i].bConst); break;
- default:
- infoSink.info.message(EPrefixInternalError, "Unary operation not folded into constant", this->getLine());
- return 0;
- }
- break;
- default:
- return 0;
- }
- }
- newNode = new TIntermConstantUnion(tempConstArray, this->getType());
- newNode->setLine(this->getLine());
- return newNode;
- } else {
- switch(op) {
- //?? add constant intrinsics
- case EOpNegative:
- switch (this->getType().getBasicType()) {
- case EbtInt:
- tempConstArray->iConst = -(this->getUnionArrayPointer()->iConst);
- newNode = new TIntermConstantUnion(tempConstArray, TType(EbtInt, EvqConst));
- break;
- case EbtFloat:
- tempConstArray->fConst = -(this->getUnionArrayPointer()->fConst);
- newNode = new TIntermConstantUnion(tempConstArray, TType(EbtFloat, EvqConst));
- break;
- default:
- infoSink.info.message(EPrefixInternalError, "Unary operation not folded into constant", line);
- return 0;
- }
- break;
- case EOpLogicalNot:
- switch (this->getType().getBasicType()) {
- case EbtBool:
- tempConstArray->bConst = !this->getUnionArrayPointer()->bConst;
- newNode = new TIntermConstantUnion(tempConstArray, TType(EbtBool, EvqConst));
- break;
- default:
- infoSink.info.message(EPrefixInternalError, "Unary operation not folded into constant", line);
- return 0;
- }
- break;
- default:
- return 0;
- }
- newNode->setLine(this->getLine());
- return newNode;
-
- }
- }
-
- return this;
-}
-
-TIntermConstantUnion* TIntermediate::changeAggrToTempConst(TIntermAggregate* node, TSymbolTable& symbolTable, TSourceLoc line)
-{
- constUnion* unionArray = new constUnion[node->getType().getInstanceSize()];
- bool returnVal;
-
- if (node->getSequence().size() == 1 && node->getSequence()[0]->getAsTyped()->getAsConstantUnion()) {
- returnVal = parseConstTree(line, node, unionArray, node->getOp(), symbolTable, node->getType(), true);
- }
- else {
- returnVal = parseConstTree(line, node, unionArray, node->getOp(), symbolTable, node->getType());
- }
-
- if (returnVal)
- unionArray = 0;
-
- return (addConstantUnion(unionArray, node->getType(), node->getLine()));
-}
-
-TIntermTyped* TIntermediate::copyConstUnion(TIntermConstantUnion* node)
-{
- constUnion *unionArray = node->getUnionArrayPointer();
-
- if (!unionArray)
- return 0;
-
- int size;
- if (node->getType().getBasicType() == EbtStruct)
- //?? We should actually be calling getStructSize() function and not setStructSize. This problem occurs in case
- // of nested/embedded structs.
- size = node->getType().setStructSize(node->getType().getStruct());
- //size = node->getType().getStructSize();
- else
- size = node->getType().getInstanceSize();
-
- constUnion *newSpace = new constUnion[size];
-
- for (int i = 0; i < size; i++)
- newSpace[i] = unionArray[i];
-
- node->setUnionArrayPointer(newSpace);
- return node;
-}
-
-TIntermTyped* TIntermediate::promoteConstantUnion(TBasicType promoteTo, TIntermConstantUnion* node)
-{
- constUnion *rightUnionArray = node->getUnionArrayPointer();
- int size = node->getType().getInstanceSize();
-
- constUnion *leftUnionArray = new constUnion[size];
-
- for (int i=0; i < size; i++) {
-
- switch (promoteTo) {
- case EbtFloat:
- switch (node->getType().getBasicType()) {
- case EbtInt:
- (leftUnionArray[i]).fConst = static_cast<float>(rightUnionArray[i].iConst);
- break;
- case EbtBool:
- (leftUnionArray[i]).fConst = static_cast<float>(rightUnionArray[i].bConst);
- break;
- case EbtFloat:
- (leftUnionArray[i]).fConst = rightUnionArray[i].fConst;
- break;
- default:
- infoSink.info.message(EPrefixInternalError, "Cannot promote", node->getLine());
- return 0;
- }
- break;
- case EbtInt:
- switch (node->getType().getBasicType()) {
- case EbtInt:
- (leftUnionArray[i]).iConst = rightUnionArray[i].iConst;
- break;
- case EbtBool:
- (leftUnionArray[i]).iConst = static_cast<int>(rightUnionArray[i].bConst);
- break;
- case EbtFloat:
- (leftUnionArray[i]).iConst = static_cast<int>(rightUnionArray[i].fConst);
- break;
- default:
- infoSink.info.message(EPrefixInternalError, "Cannot promote", node->getLine());
- return 0;
- }
- break;
- case EbtBool:
- switch (node->getType().getBasicType()) {
- case EbtInt:
- (leftUnionArray[i]).bConst = rightUnionArray[i].iConst != 0;
- break;
- case EbtBool:
- (leftUnionArray[i]).bConst = rightUnionArray[i].bConst;
- break;
- case EbtFloat:
- (leftUnionArray[i]).bConst = rightUnionArray[i].fConst != 0.0;
- break;
- default:
- infoSink.info.message(EPrefixInternalError, "Cannot promote", node->getLine());
- return 0;
- }
-
- break;
- default:
- infoSink.info.message(EPrefixInternalError, "Incorrect data type found", node->getLine());
- return 0;
- }
-
- }
-
- const TType& t = node->getType();
-
- return addConstantUnion(leftUnionArray, TType(promoteTo, t.getQualifier(), t.getNominalSize(), t.isMatrix(), t.isArray()), node->getLine());
-}
-
-//
-// This method inserts the child nodes into the parent node at the given location specified
-// by parentNodeIter. offset tells the integer offset into the parent vector that points to
-// the child node. sequenceVector is the parent vector.
-// Returns reference to the last inserted child node
-// increments the offset based on the number of child nodes added
-//
-void TIntermediate::removeChildNode(TIntermSequence &parentSequence, TType& parentType, int& offset, TIntermSequence::iterator& parentNodeIter, TIntermAggregate* child)
-{
- if (!child)
- return;
-
- parentNodeIter = parentSequence.begin() + offset;
-
- TIntermSequence& childSequence = child->getSequence();
- int oldSize = static_cast<int>(parentSequence.size());
- if (childSequence.size() == 1) {
- if (!removeMatrixConstNode(parentSequence, parentType, child, offset)) {
- for (int i = 0; i < child->getType().getInstanceSize(); i++) {
- constUnion* constantUnion = new constUnion[1];
- *constantUnion = *(childSequence[0]->getAsConstantUnion()->getUnionArrayPointer());
- TIntermConstantUnion *constant = new TIntermConstantUnion(constantUnion,
- childSequence[0]->getAsConstantUnion()->getType());
- constant->setLine(child->getLine());
- parentNodeIter = parentSequence.begin() + offset;
- parentSequence.insert(parentNodeIter, constant);
- }
- }
- } else
- parentSequence.insert(parentNodeIter, childSequence.begin(), childSequence.end());
-
- int newSize = static_cast<int>(parentSequence.size());
- offset = offset + newSize - oldSize;
- parentNodeIter = parentSequence.begin() + offset;
- parentNodeIter = parentSequence.erase(parentNodeIter);
- offset--;
- parentNodeIter--;
-}
-
-//
-// The parent has only one child node. This method is not implemented
-// for parent that is a structure
-//
-TIntermTyped* TIntermediate::removeChildNode(TIntermTyped* parent, TType* parentType, TIntermAggregate* child)
-{
- TIntermTyped* resultNode = 0;
-
- if (parentType->getInstanceSize() == 1) {
- resultNode = child->getSequence()[0]->getAsTyped();
- } else {
- int size = parentType->getInstanceSize();
- TIntermSequence& parentSequence = parent->getAsAggregate()->getSequence();
- TIntermSequence& childSequence = child->getSequence();
-
- if (childSequence.size() == 1) {
- if (!removeMatrixConstNode(parentSequence, *parentType, child, 1))
- parentSequence.push_back(child->getSequence()[0]);
- } else {
- for (int i = 0; i < size; i++) {
- parentSequence.push_back(child->getSequence()[i]);
- }
- }
- parentSequence.erase(parentSequence.begin());
-
- return parent;
- }
-
- return resultNode;
-}
-
-bool TIntermediate::removeMatrixConstNode(TIntermSequence &parentSequence, TType& parentType, TIntermAggregate* child, int offset)
-{
- if (!child)
- return false;
-
- TIntermSequence::iterator parentNodeIter;
- TIntermSequence &childSequence = child->getSequence();
-
- switch (child->getOp()) {
- case EOpConstructMat2:
- case EOpConstructMat3:
- case EOpConstructMat4:
- {// support MSVC++6.0
- for (int i = 0; i < child->getType().getInstanceSize(); i++) {
- constUnion* constantUnion = new constUnion[1];
- if (i % (child->getType().getNominalSize() + 1) == 0) {
- *constantUnion = *(childSequence[0]->getAsConstantUnion()->getUnionArrayPointer());
- } else {
- switch (parentType.getBasicType()) {
- case EbtInt: constantUnion->iConst = 0; break;
- case EbtFloat: constantUnion->fConst = 0.0; break;
- case EbtBool: constantUnion->bConst = false; break;
- default: ; /* default added by BrianP */
- }
- }
- TIntermConstantUnion *constant = new TIntermConstantUnion(constantUnion,
- childSequence[0]->getAsConstantUnion()->getType());
- constant->setLine(child->getLine());
- parentNodeIter = parentSequence.begin() + offset + i;
- parentSequence.insert(parentNodeIter, constant);
- }
- }
- return true;
- default:
- return false;
- }
-}
-
-void TIntermAggregate::addToPragmaTable(const TPragmaTable& pTable)
-{
- assert (!pragmaTable);
- pragmaTable = new TPragmaTable();
- *pragmaTable = pTable;
-}
-
diff --git a/src/mesa/shader/slang/MachineIndependent/MMap.h b/src/mesa/shader/slang/MachineIndependent/MMap.h deleted file mode 100755 index 66703cdd9b..0000000000 --- a/src/mesa/shader/slang/MachineIndependent/MMap.h +++ /dev/null @@ -1,84 +0,0 @@ -//
-//Copyright (C) 2002-2005 3Dlabs Inc. Ltd.
-//All rights reserved.
-//
-//Redistribution and use in source and binary forms, with or without
-//modification, are permitted provided that the following conditions
-//are met:
-//
-// Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//
-// Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-//
-// Neither the name of 3Dlabs Inc. Ltd. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-//THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-//"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-//LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
-//FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
-//COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
-//INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
-//BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
-//LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
-//CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-//LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
-//ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
-//POSSIBILITY OF SUCH DAMAGE.
-//
-
-#ifndef _MMAP_INCLUDED_
-#define _MMAP_INCLUDED_
-
-//
-// Encapsulate memory mapped files
-//
-
-class TMMap {
-public:
- TMMap(const char* fileName) :
- fSize(-1), // -1 is the error value returned by GetFileSize()
- fp(NULL),
- fBuff(0) // 0 is the error value returned by MapViewOfFile()
- {
- if ((fp = fopen(fileName, "r")) == NULL)
- return;
- char c = getc(fp);
- fSize = 0;
- while (c != EOF) {
- fSize++;
- c = getc(fp);
- }
- if (c == EOF)
- fSize++;
- rewind(fp);
- fBuff = (char*)malloc(sizeof(char) * fSize);
- int count = 0;
- c = getc(fp);
- while (c != EOF) {
- fBuff[count++] = c;
- c = getc(fp);
- }
- fBuff[count++] = c;
- }
-
- char* getData() { return fBuff; }
- int getSize() { return fSize; }
-
- ~TMMap() {
- if (fp != NULL)
- fclose(fp);
- }
-
-private:
- int fSize; // size of file to map in
- FILE *fp;
- char* fBuff; // the actual data;
-};
-
-#endif // _MMAP_INCLUDED_
diff --git a/src/mesa/shader/slang/MachineIndependent/ParseHelper.cpp b/src/mesa/shader/slang/MachineIndependent/ParseHelper.cpp deleted file mode 100755 index cfc42746ae..0000000000 --- a/src/mesa/shader/slang/MachineIndependent/ParseHelper.cpp +++ /dev/null @@ -1,1452 +0,0 @@ -//
-//Copyright (C) 2002-2005 3Dlabs Inc. Ltd.
-//All rights reserved.
-//
-//Redistribution and use in source and binary forms, with or without
-//modification, are permitted provided that the following conditions
-//are met:
-//
-// Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//
-// Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-//
-// Neither the name of 3Dlabs Inc. Ltd. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-//THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-//"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-//LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
-//FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
-//COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
-//INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
-//BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
-//LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
-//CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-//LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
-//ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
-//POSSIBILITY OF SUCH DAMAGE.
-//
-
-#include "ParseHelper.h"
-#include "Include/InitializeParseContext.h"
-#include "osinclude.h"
-#include <stdarg.h>
-///////////////////////////////////////////////////////////////////////
-//
-// Sub- vector and matrix fields
-//
-////////////////////////////////////////////////////////////////////////
-
-//
-// Look at a '.' field selector string and change it into offsets
-// for a vector.
-//
-bool TParseContext::parseVectorFields(const TString& compString, int vecSize, TVectorFields& fields, int line)
-{
- fields.num = (int) compString.size();
- if (fields.num > 4) {
- error(line, "illegal vector field selection", compString.c_str(), "");
- return false;
- }
-
- enum {
- exyzw,
- ergba,
- estpq
- } fieldSet[4];
-
- for (int i = 0; i < fields.num; ++i) {
- switch (compString[i]) {
- case 'x':
- fields.offsets[i] = 0;
- fieldSet[i] = exyzw;
- break;
- case 'r':
- fields.offsets[i] = 0;
- fieldSet[i] = ergba;
- break;
- case 's':
- fields.offsets[i] = 0;
- fieldSet[i] = estpq;
- break;
- case 'y':
- fields.offsets[i] = 1;
- fieldSet[i] = exyzw;
- break;
- case 'g':
- fields.offsets[i] = 1;
- fieldSet[i] = ergba;
- break;
- case 't':
- fields.offsets[i] = 1;
- fieldSet[i] = estpq;
- break;
- case 'z':
- fields.offsets[i] = 2;
- fieldSet[i] = exyzw;
- break;
- case 'b':
- fields.offsets[i] = 2;
- fieldSet[i] = ergba;
- break;
- case 'p':
- fields.offsets[i] = 2;
- fieldSet[i] = estpq;
- break;
-
- case 'w':
- fields.offsets[i] = 3;
- fieldSet[i] = exyzw;
- break;
- case 'a':
- fields.offsets[i] = 3;
- fieldSet[i] = ergba;
- break;
- case 'q':
- fields.offsets[i] = 3;
- fieldSet[i] = estpq;
- break;
- default:
- error(line, "illegal vector field selection", compString.c_str(), "");
- return false;
- }
- }
-
- for (int i = 0; i < fields.num; ++i) {
- if (fields.offsets[i] >= vecSize) {
- error(line, "vector field selection out of range", compString.c_str(), "");
- return false;
- }
-
- if (i > 0) {
- if (fieldSet[i] != fieldSet[i-1]) {
- error(line, "illegal - vector component fields not from the same set", compString.c_str(), "");
- return false;
- }
- }
- }
-
- return true;
-}
-
-
-//
-// Look at a '.' field selector string and change it into offsets
-// for a matrix.
-//
-bool TParseContext::parseMatrixFields(const TString& compString, int matSize, TMatrixFields& fields, int line)
-{
- fields.wholeRow = false;
- fields.wholeCol = false;
- fields.row = -1;
- fields.col = -1;
-
- if (compString.size() != 2) {
- error(line, "illegal length of matrix field selection", compString.c_str(), "");
- return false;
- }
-
- if (compString[0] == '_') {
- if (compString[1] < '0' || compString[1] > '3') {
- error(line, "illegal matrix field selection", compString.c_str(), "");
- return false;
- }
- fields.wholeCol = true;
- fields.col = compString[1] - '0';
- } else if (compString[1] == '_') {
- if (compString[0] < '0' || compString[0] > '3') {
- error(line, "illegal matrix field selection", compString.c_str(), "");
- return false;
- }
- fields.wholeRow = true;
- fields.row = compString[0] - '0';
- } else {
- if (compString[0] < '0' || compString[0] > '3' ||
- compString[1] < '0' || compString[1] > '3') {
- error(line, "illegal matrix field selection", compString.c_str(), "");
- return false;
- }
- fields.row = compString[0] - '0';
- fields.col = compString[1] - '0';
- }
-
- if (fields.row >= matSize || fields.col >= matSize) {
- error(line, "matrix field selection out of range", compString.c_str(), "");
- return false;
- }
-
- return true;
-}
-
-///////////////////////////////////////////////////////////////////////
-//
-// Errors
-//
-////////////////////////////////////////////////////////////////////////
-
-//
-// Track whether errors have occurred.
-//
-void TParseContext::recover()
-{
- recoveredFromError = true;
-}
-
-//
-// Used by flex/bison to output all syntax and parsing errors.
-//
-void C_DECL TParseContext::error(TSourceLoc nLine, const char *szReason, const char *szToken,
- const char *szExtraInfoFormat, ...)
-{
- char szExtraInfo[400];
- va_list marker;
-
- va_start(marker, szExtraInfoFormat);
-
- _vsnprintf(szExtraInfo, sizeof(szExtraInfo), szExtraInfoFormat, marker);
-
- /* VC++ format: file(linenum) : error #: 'token' : extrainfo */
- infoSink.info.prefix(EPrefixError);
- infoSink.info.location(nLine);
- infoSink.info << "'" << szToken << "' : " << szReason << " " << szExtraInfo << "\n";
-
- va_end(marker);
-
- ++numErrors;
-}
-
-//
-// Same error message for all places assignments don't work.
-//
-void TParseContext::assignError(int line, const char* op, TString left, TString right)
-{
- error(line, "", op, "cannot convert from '%s' to '%s'",
- right.c_str(), left.c_str());
-}
-
-//
-// Same error message for all places unary operations don't work.
-//
-void TParseContext::unaryOpError(int line, char* op, TString operand)
-{
- error(line, " wrong operand type", op,
- "no operation '%s' exists that takes an operand of type %s (or there is no acceptable conversion)",
- op, operand.c_str());
-}
-
-//
-// Same error message for all binary operations don't work.
-//
-void TParseContext::binaryOpError(int line, char* op, TString left, TString right)
-{
- error(line, " wrong operand types ", op,
- "no operation '%s' exists that takes a left-hand operand of type '%s' and "
- "a right operand of type '%s' (or there is no acceptable conversion)",
- op, left.c_str(), right.c_str());
-}
-
-//
-// Both test and if necessary, spit out an error, to see if the node is really
-// an l-value that can be operated on this way.
-//
-// Returns true if the was an error.
-//
-bool TParseContext::lValueErrorCheck(int line, char* op, TIntermTyped* node)
-{
- TIntermSymbol* symNode = node->getAsSymbolNode();
- TIntermBinary* binaryNode = node->getAsBinaryNode();
-
- if (binaryNode) {
- bool errorReturn;
-
- switch(binaryNode->getOp()) {
- case EOpIndexDirect:
- case EOpIndexIndirect:
- case EOpIndexDirectStruct:
- return lValueErrorCheck(line, op, binaryNode->getLeft());
- case EOpVectorSwizzle:
- errorReturn = lValueErrorCheck(line, op, binaryNode->getLeft());
- if (!errorReturn) {
- int offset[4] = {0,0,0,0};
-
- TIntermTyped* rightNode = binaryNode->getRight();
- TIntermAggregate *aggrNode = rightNode->getAsAggregate();
-
- for (TIntermSequence::iterator p = aggrNode->getSequence().begin();
- p != aggrNode->getSequence().end(); p++) {
- int value = (*p)->getAsTyped()->getAsConstantUnion()->getUnionArrayPointer()->iConst;
- offset[value]++;
- if (offset[value] > 1) {
- error(line, " l-value of swizzle cannot have duplicate components", op, "", "");
-
- return true;
- }
- }
- }
-
- return errorReturn;
- default:
- break;
- }
- error(line, " l-value required", op, "", "");
-
- return true;
- }
-
-
- const char* symbol = 0;
- if (symNode != 0)
- symbol = symNode->getSymbol().c_str();
-
- char* message = 0;
- switch (node->getQualifier()) {
- case EvqConst: message = "can't modify a const"; break;
- case EvqConstReadOnly: message = "can't modify a const"; break;
- case EvqAttribute: message = "can't modify an attribute"; break;
- case EvqUniform: message = "can't modify a uniform"; break;
- case EvqVaryingIn: message = "can't modify a varying"; break;
- case EvqInput: message = "can't modify an input"; break;
- case EvqFace: message = "can't modify gl_FrontFace"; break;
- case EvqFragCoord: message = "can't modify gl_FragCoord"; break;
- default:
-
- //
- // Type that can't be written to?
- //
- switch (node->getBasicType()) {
- case EbtSampler1D:
- case EbtSampler2D:
- case EbtSampler3D:
- case EbtSamplerCube:
- case EbtSampler1DShadow:
- case EbtSampler2DShadow:
- message = "can't modify a sampler";
- break;
- case EbtVoid:
- message = "can't modify void";
- break;
- default:
- break;
- }
- }
-
- if (message == 0 && binaryNode == 0 && symNode == 0) {
- error(line, " l-value required", op, "", "");
-
- return true;
- }
-
-
- //
- // Everything else is okay, no error.
- //
- if (message == 0)
- return false;
-
- //
- // If we get here, we have an error and a message.
- //
- if (symNode)
- error(line, " l-value required", op, "\"%s\" (%s)", symbol, message);
- else
- error(line, " l-value required", op, "(%s)", message);
-
- return true;
-}
-
-//
-// Both test, and if necessary spit out an error, to see if the node is really
-// a constant.
-//
-// Returns true if the was an error.
-//
-bool TParseContext::constErrorCheck(TIntermTyped* node)
-{
- if (node->getQualifier() == EvqConst)
- return false;
-
- error(node->getLine(), "constant expression required", "", "");
-
- return true;
-}
-
-//
-// Both test, and if necessary spit out an error, to see if the node is really
-// an integer.
-//
-// Returns true if the was an error.
-//
-bool TParseContext::integerErrorCheck(TIntermTyped* node, char* token)
-{
- if (node->getBasicType() == EbtInt && node->getNominalSize() == 1)
- return false;
-
- error(node->getLine(), "integer expression required", token, "");
-
- return true;
-}
-
-//
-// Both test, and if necessary spit out an error, to see if we are currently
-// globally scoped.
-//
-// Returns true if the was an error.
-//
-bool TParseContext::globalErrorCheck(int line, bool global, char* token)
-{
- if (global)
- return false;
-
- error(line, "only allowed at global scope", token, "");
-
- return true;
-}
-
-//
-// For now, keep it simple: if it starts "gl_", it's reserved, independent
-// of scope. Except, if the symbol table is at the built-in push-level,
-// which is when we are parsing built-ins.
-//
-// Returns true if there was an error.
-//
-bool TParseContext::reservedErrorCheck(int line, const TString& identifier)
-{
- if (symbolTable.atBuiltInLevel() ||
- identifier.substr(0, 3) != TString("gl_"))
- return false;
-
- error(line, "reserved built-in name", "gl_", "");
-
- return true;
-}
-
-//
-// Make sure there is enough data provided to the constructor to build
-// something of the type of the constructor. Also returns the type of
-// the constructor.
-//
-// Returns true if there was an error in construction.
-//
-bool TParseContext::constructorErrorCheck(int line, TIntermNode* node, TFunction& function, TOperator op, TType* type)
-{
- switch(op) {
- case EOpConstructInt: *type = TType(EbtInt); break;
- case EOpConstructBool: *type = TType(EbtBool); break;
- case EOpConstructFloat: *type = TType(EbtFloat); break;
- case EOpConstructVec2: *type = TType(EbtFloat, EvqTemporary, 2); break;
- case EOpConstructVec3: *type = TType(EbtFloat, EvqTemporary, 3); break;
- case EOpConstructVec4: *type = TType(EbtFloat, EvqTemporary, 4); break;
- case EOpConstructBVec2: *type = TType(EbtBool, EvqTemporary, 2); break;
- case EOpConstructBVec3: *type = TType(EbtBool, EvqTemporary, 3); break;
- case EOpConstructBVec4: *type = TType(EbtBool, EvqTemporary, 4); break;
- case EOpConstructIVec2: *type = TType(EbtInt, EvqTemporary, 2); break;
- case EOpConstructIVec3: *type = TType(EbtInt, EvqTemporary, 3); break;
- case EOpConstructIVec4: *type = TType(EbtInt, EvqTemporary, 4); break;
- case EOpConstructMat2: *type = TType(EbtFloat, EvqTemporary, 2, true); break;
- case EOpConstructMat3: *type = TType(EbtFloat, EvqTemporary, 3, true); break;
- case EOpConstructMat4: *type = TType(EbtFloat, EvqTemporary, 4, true); break;
- case EOpConstructStruct: *type = TType(function.getReturnType().getStruct(), function.getReturnType().getTypeName()); break;
- default:
- error(line, "expected constructor", "Internal Error", "");
- return true;
- }
-
- bool constructingMatrix = false;
- switch(op) {
- case EOpConstructMat2:
- case EOpConstructMat3:
- case EOpConstructMat4:
- constructingMatrix = true;
- break;
- default:
- break;
- }
-
- //
- // Note: It's okay to have too many components available, but not okay to have unused
- // arguments. 'full' will go to true when enough args have been seen. If we loop
- // again, there is an extra argument, so 'overfull' will become true.
- //
-
- int size = 0;
- bool constType = true;
- bool full = false;
- bool overFull = false;
- bool matrixInMatrix = false;
- for (int i = 0; i < function.getParamCount(); ++i) {
- size += function[i].type->getInstanceSize();
- if (constructingMatrix && function[i].type->isMatrix())
- matrixInMatrix = true;
- if (full)
- overFull = true;
- if (op != EOpConstructStruct && size >= type->getInstanceSize())
- full = true;
- if (function[i].type->getQualifier() != EvqConst)
- constType = false;
- }
-
- if (constType)
- type->changeQualifier(EvqConst);
-
- if (matrixInMatrix) {
- error(line, "constructing matrix from matrix", "constructor", "(reserved)");
- return true;
- }
-
- if (overFull) {
- error(line, "too many arguments", "constructor", "");
- return true;
- }
-
- if (size != 1 && size < type->getInstanceSize() || (size < 1) && op == EOpConstructStruct) {
- error(line, "not enough data provided for construction", "constructor", "");
- return true;
- }
-
- TIntermTyped* typed = node->getAsTyped();
- if (typed == 0) {
- error(line, "constructor argument does not have a type", "constructor", "");
- return true;
- }
- if (op != EOpConstructStruct && IsSampler(typed->getBasicType())) {
- error(line, "cannot convert a sampler", "constructor", "");
- return true;
- }
- if (typed->getBasicType() == EbtVoid) {
- error(line, "cannot convert a void", "constructor", "");
- return true;
- }
-
- return false;
-}
-
-// This function checks to see if a void variable has been declared and raise an error message for such a case
-//
-// returns true in case of an error
-//
-bool TParseContext::voidErrorCheck(int line, const TString& identifier, const TPublicType& pubType)
-{
- if (pubType.type == EbtVoid) {
- error(line, "illegal use of type 'void'", identifier.c_str(), "");
- return true;
- }
-
- return false;
-}
-
-// This function checks to see if the node (for the expression) contains a scalar boolean expression or not
-//
-// returns true in case of an error
-//
-bool TParseContext::boolErrorCheck(int line, const TIntermTyped* type)
-{
- if (type->getBasicType() != EbtBool || type->isArray() || type->isMatrix() || type->isVector()) {
- error(line, "boolean expression expected", "", "");
- return true;
- }
-
- return false;
-}
-
-// This function checks to see if the node (for the expression) contains a scalar boolean expression or not
-//
-// returns true in case of an error
-//
-bool TParseContext::boolErrorCheck(int line, const TPublicType& pType)
-{
- if (pType.type != EbtBool || pType.array || pType.matrix || (pType.size > 1)) {
- error(line, "boolean expression expected", "", "");
- return true;
- }
-
- return false;
-}
-
-bool TParseContext::samplerErrorCheck(int line, const TPublicType& pType, const char* reason)
-{
- if (pType.type == EbtStruct) {
- if (containsSampler(*pType.userDef)) {
- error(line, reason, TType::getBasicString(pType.type), "(structure contains a sampler)");
-
- return true;
- }
-
- return false;
- } else if (IsSampler(pType.type)) {
- error(line, reason, TType::getBasicString(pType.type), "");
-
- return true;
- }
-
- return false;
-}
-
-bool TParseContext::structQualifierErrorCheck(int line, const TPublicType& pType)
-{
- if ((pType.qualifier == EvqVaryingIn || pType.qualifier == EvqVaryingOut || pType.qualifier == EvqAttribute) &&
- pType.type == EbtStruct) {
- error(line, "cannot be used with a structure", getQualifierString(pType.qualifier), "");
-
- return true;
- }
-
- if (pType.qualifier != EvqUniform && samplerErrorCheck(line, pType, "samplers must be uniform"))
- return true;
-
- return false;
-}
-
-bool TParseContext::parameterSamplerErrorCheck(int line, TQualifier qualifier, const TType& type)
-{
- if ((qualifier == EvqOut || qualifier == EvqInOut) &&
- type.getBasicType() != EbtStruct && IsSampler(type.getBasicType())) {
- error(line, "samplers cannot be output parameters", type.getBasicString(), "");
- return true;
- }
-
- return false;
-}
-
-bool TParseContext::containsSampler(TType& type)
-{
- if (IsSampler(type.getBasicType()))
- return true;
-
- if (type.getBasicType() == EbtStruct) {
- TTypeList& structure = *type.getStruct();
- for (unsigned int i = 0; i < structure.size(); ++i) {
- if (containsSampler(*structure[i].type))
- return true;
- }
- }
-
- return false;
-}
-
-bool TParseContext::insertBuiltInArrayAtGlobalLevel()
-{
- TString *name = NewPoolTString("gl_TexCoord");
- TSymbol* symbol = symbolTable.find(*name);
- if (!symbol) {
- error(0, "INTERNAL ERROR finding symbol", name->c_str(), "");
- return true;
- }
- TVariable* variable = static_cast<TVariable*>(symbol);
-
- TVariable* newVariable = new TVariable(name, variable->getType());
-
- if (! symbolTable.insert(*newVariable)) {
- delete newVariable;
- error(0, "INTERNAL ERROR inserting new symbol", name->c_str(), "");
- return true;
- }
-
- return false;
-}
-
-//
-// Do all the semantic checking for declaring an array, with and
-// without a size, and make the right changes to the symbol table.
-//
-// size == 0 means no specified size.
-//
-// Returns true if there was an error.
-//
-bool TParseContext::arrayErrorCheck(int line, TString& identifier, TPublicType type, TIntermTyped* size)
-{
- //
- // Don't check for reserved word use until after we know it's not in the symbol table,
- // because reserved arrays can be redeclared.
- //
-
- //
- // Can the type be an array?
- //
- if (type.array || type.qualifier == EvqAttribute || type.qualifier == EvqConst) {
- error(line, "cannot declare arrays of this type", TType(type).getCompleteString().c_str(), "");
- return true;
- }
- type.array = true;
-
- //
- // size will be 0 if there is no size declared, otherwise it contains the size
- // declared.
- //
- TIntermConstantUnion* constant = 0;
- if (size) {
- constant = size->getAsConstantUnion();
- if (constant == 0 || constant->getBasicType() != EbtInt || constant->getUnionArrayPointer()->iConst <= 0) {
- error(line, "array size must be a positive integer", identifier.c_str(), "");
- return true;
- }
- }
-
- bool builtIn = false;
- bool sameScope = false;
- TSymbol* symbol = symbolTable.find(identifier, &builtIn, &sameScope);
- if (symbol == 0 || !sameScope) {
- if (reservedErrorCheck(line, identifier))
- return true;
-
- TVariable* variable = new TVariable(&identifier, TType(type));
-
- if (size)
- variable->getType().setArraySize(constant->getUnionArrayPointer()->iConst);
-
- if (! symbolTable.insert(*variable)) {
- delete variable;
- error(line, "INTERNAL ERROR inserting new symbol", identifier.c_str(), "");
- return true;
- }
- } else {
- if (! symbol->isVariable()) {
- error(line, "variable expected", identifier.c_str(), "");
- return true;
- }
-
- TVariable* variable = static_cast<TVariable*>(symbol);
- if (! variable->getType().isArray()) {
- error(line, "redeclaring non-array as array", identifier.c_str(), "");
- return true;
- }
- if (variable->getType().getArraySize() > 0) {
- error(line, "redeclaration of array with size", identifier.c_str(), "");
- return true;
- }
-
- if (variable->getType() != TType(type)) {
- error(line, "redeclaration of array with a different type", identifier.c_str(), "");
- return true;
- }
-
- TType* t = variable->getArrayInformationType();
- while (t != 0) {
- if (t->getMaxArraySize() > constant->getUnionArrayPointer()->iConst) {
- error(line, "higher index value already used for the array", identifier.c_str(), "");
- return true;
- }
- t->setArraySize(constant->getUnionArrayPointer()->iConst);
- t = t->getArrayInformationType();
- }
-
- if (size)
- variable->getType().setArraySize(constant->getUnionArrayPointer()->iConst);
- }
-
- if (voidErrorCheck(line, identifier, type))
- return true;
-
- return false;
-}
-
-bool TParseContext::arraySetMaxSize(TIntermSymbol *node, TType* type, int size, bool updateFlag, TSourceLoc line)
-{
- bool builtIn = false;
- TSymbol* symbol = symbolTable.find(node->getSymbol(), &builtIn);
- if (symbol == 0) {
- error(line, " undeclared identifier", node->getSymbol().c_str(), "");
- return true;
- }
- TVariable* variable = static_cast<TVariable*>(symbol);
-
- type->setArrayInformationType(variable->getArrayInformationType());
- variable->updateArrayInformationType(type);
-
- // we dont want to update the maxArraySize when this flag is not set, we just want to include this
- // node type in the chain of node types so that its updated when a higher maxArraySize comes in.
- if (!updateFlag)
- return false;
-
- size++;
- variable->getType().setMaxArraySize(size);
- type->setMaxArraySize(size);
- TType* tt = type;
-
- while(tt->getArrayInformationType() != 0) {
- tt = tt->getArrayInformationType();
- tt->setMaxArraySize(size);
- }
-
- return false;
-}
-
-//
-// Do semantic checking for a variable declaration that has no initializer,
-// and update the symbol table.
-//
-// Returns true if there was an error.
-//
-bool TParseContext::nonInitErrorCheck(int line, TString& identifier, TPublicType& type)
-{
- if (reservedErrorCheck(line, identifier))
- recover();
-
- //
- // Make the qualifier make sense, error is issued in a little bit.
- //
- bool constError = false;
- if (type.qualifier == EvqConst) {
- type.qualifier = EvqTemporary;
- constError = true;
- }
-
- TVariable* variable = new TVariable(&identifier, TType(type));
-
- if (! symbolTable.insert(*variable)) {
- error(line, "redefinition", variable->getName().c_str(), "");
- delete variable;
- return true;
- }
- if (constError) {
- error(line, "variables with qualifier 'const' must be initialized", identifier.c_str(), "");
- return true;
- }
-
- if (voidErrorCheck(line, identifier, type))
- return true;
-
- return false;
-}
-
-bool TParseContext::paramErrorCheck(int line, TQualifier qualifier, TQualifier paramQualifier, TType* type)
-{
- if (qualifier != EvqConst && qualifier != EvqTemporary) {
- error(line, "qualifier not allowed on function parameter", getQualifierString(qualifier), "");
- return true;
- }
- if (qualifier == EvqConst && paramQualifier != EvqIn) {
- error(line, "qualifier not allowed with ", getQualifierString(qualifier), getQualifierString(paramQualifier));
- return true;
- }
-
- if (qualifier == EvqConst)
- type->changeQualifier(EvqConstReadOnly);
- else
- type->changeQualifier(paramQualifier);
-
- return false;
-}
-
-/////////////////////////////////////////////////////////////////////////////////
-//
-// Non-Errors.
-//
-/////////////////////////////////////////////////////////////////////////////////
-
-//
-// Look up a function name in the symbol table, and make sure it is a function.
-//
-// Return the function symbol if found, otherwise 0.
-//
-const TFunction* TParseContext::findFunction(int line, TFunction* call, bool *builtIn)
-{
- const TSymbol* symbol = symbolTable.find(call->getMangledName(), builtIn);
-
- if (symbol == 0) {
- error(line, "no matching overloaded function found", call->getName().c_str(), "");
- return 0;
- }
-
- if (! symbol->isFunction()) {
- error(line, "function name expected", call->getName().c_str(), "");
- return 0;
- }
-
- const TFunction* function = static_cast<const TFunction*>(symbol);
-
- return function;
-}
-//
-// Initializers show up in several places in the grammar. Have one set of
-// code to handle them here.
-//
-bool TParseContext::executeInitializer(TSourceLoc line, TString& identifier, TPublicType& pType,
- TIntermTyped* initializer, TIntermNode*& intermNode)
-{
- if (reservedErrorCheck(line, identifier))
- return true;
-
- if (voidErrorCheck(line, identifier, pType))
- return true;
-
- //
- // add variable to symbol table
- //
- TVariable* variable = new TVariable(&identifier, TType(pType));
- if (! symbolTable.insert(*variable)) {
- error(line, "redefinition", variable->getName().c_str(), "");
- return true;
- // don't delete variable, it's used by error recovery, and the pool
- // pop will take care of the memory
- }
-
- //
- // identifier must be of type constant, a global, or a temporary
- //
- TQualifier qualifier = variable->getType().getQualifier();
- if ((qualifier != EvqTemporary) && (qualifier != EvqGlobal) && (qualifier != EvqConst)) {
- error(line, " cannot initialize this type of qualifier ", variable->getType().getQualifierString(), "");
- return true;
- }
- //
- // test for and propagate constant
- //
-
- if (qualifier == EvqConst) {
- if (qualifier != initializer->getType().getQualifier()) {
- error(line, " assigning non-constant to", "=", "'%s'", variable->getType().getCompleteString().c_str());
- variable->getType().changeQualifier(EvqTemporary);
- return true;
- }
- if (TType(pType) != initializer->getType()) {
- error(line, " non-matching types for const initializer ",
- variable->getType().getQualifierString(), "");
- variable->getType().changeQualifier(EvqTemporary);
- return true;
- }
- if (initializer->getAsConstantUnion()) {
- constUnion* unionArray = variable->getConstPointer();
-
- if (pType.size == 1 && TType(pType).getBasicType() != EbtStruct) {
- switch (pType.type ) {
- case EbtInt:
- unionArray->iConst = (initializer->getAsConstantUnion()->getUnionArrayPointer())[0].iConst;
- break;
- case EbtFloat:
- unionArray->fConst = (initializer->getAsConstantUnion()->getUnionArrayPointer())[0].fConst;
- break;
- case EbtBool:
- unionArray->bConst = (initializer->getAsConstantUnion()->getUnionArrayPointer())[0].bConst;
- break;
- default:
- error(line, " cannot initialize constant of this type", "", "");
- return true;
- }
- } else {
- variable->shareConstPointer(initializer->getAsConstantUnion()->getUnionArrayPointer());
- }
- } else if (initializer->getAsAggregate()) {
- bool returnVal = false;
- constUnion* unionArray = variable->getConstPointer();
- if (initializer->getAsAggregate()->getSequence().size() == 1 && initializer->getAsAggregate()->getSequence()[0]->getAsTyped()->getAsConstantUnion()) {
- returnVal = intermediate.parseConstTree(line, initializer, unionArray, initializer->getAsAggregate()->getOp(), symbolTable, variable->getType(), true);
- }
- else {
- returnVal = intermediate.parseConstTree(line, initializer, unionArray, initializer->getAsAggregate()->getOp(), symbolTable, variable->getType());
- }
- intermNode = 0;
- constUnion *arrayUnion = unionArray;
- if (returnVal) {
- arrayUnion = 0;
- variable->getType().changeQualifier(EvqTemporary);
- }
- return returnVal;
- } else if (initializer->getAsSymbolNode()) {
- const TSymbol* symbol = symbolTable.find(initializer->getAsSymbolNode()->getSymbol());
- const TVariable* tVar = static_cast<const TVariable*>(symbol);
-
- constUnion* constArray = tVar->getConstPointer();
- variable->shareConstPointer(constArray);
- } else {
- error(line, " assigning non-constant to", "=", "'%s'", variable->getType().getCompleteString().c_str());
- variable->getType().changeQualifier(EvqTemporary);
- return true;
- }
- }
-
- if (qualifier != EvqConst) {
- TIntermSymbol* intermSymbol = intermediate.addSymbol(variable->getUniqueId(), variable->getName(), variable->getType(), line);
- intermNode = intermediate.addAssign(EOpAssign, intermSymbol, initializer, line);
- if (intermNode == 0) {
- assignError(line, "=", intermSymbol->getCompleteString(), initializer->getCompleteString());
- return true;
- }
- } else
- intermNode = 0;
-
- return false;
-}
-
-//
-// This method checks to see if the given aggregate node has all its children nodes as constants
-// This method does not test if structure members are constant
-//
-bool TParseContext::canNodeBeRemoved(TIntermNode* childNode)
-{
- TIntermAggregate *aggrNode = childNode->getAsAggregate();
- if (!aggrNode)
- return false;
-
- if (!aggrNode->isConstructor() || aggrNode->getOp() == EOpConstructStruct)
- return false;
-
- bool allConstant = true;
-
- // check if all the child nodes are constants so that they can be inserted into
- // the parent node
- if (aggrNode) {
- TIntermSequence &childSequenceVector = aggrNode->getSequence() ;
- for (TIntermSequence::iterator p = childSequenceVector.begin();
- p != childSequenceVector.end(); p++) {
- if (!(*p)->getAsTyped()->getAsConstantUnion())
- return false;
- }
- }
-
- return allConstant;
-}
-
-// This function is used to test for the correctness of the parameters passed to various constructor functions
-// and also convert them to the right datatype if it is allowed and required.
-//
-// Returns 0 for an error or the constructed node (aggregate or typed) for no error.
-//
-TIntermTyped* TParseContext::addConstructor(TIntermNode* node, TType* type, TOperator op, TFunction* fnCall, TSourceLoc line)
-{
- if (node == 0)
- return 0;
-
- TIntermAggregate* aggrNode = node->getAsAggregate();
-
- TTypeList::iterator list;
- TTypeList* structure = 0; // Store the information (vector) about the return type of the structure.
- if (op == EOpConstructStruct) {
- const TType& ttype = fnCall->getReturnType();
- structure = ttype.getStruct();
- list = (*structure).begin();
- }
-
- bool singleArg;
- if (aggrNode) {
- if (aggrNode->getOp() != EOpNull || aggrNode->getSequence().size() == 1)
- singleArg = true;
- else
- singleArg = false;
- } else
- singleArg = true;
-
- TIntermTyped *newNode;
- if (singleArg) {
- if (op == EOpConstructStruct) {
- // If structure constructor is being called for only one parameter inside the structure,
- // we need to call constructStruct function once.
- if (structure->size() != 1) {
- error(line, "Number of constructor parameters does not match the number of structure fields", "constructor", "");
-
- return 0;
- } else
- return constructStruct(node, (*list).type, 1, node->getLine(), false);
- } else {
- newNode = constructBuiltIn(type, op, node, node->getLine(), false);
- if (newNode && newNode->getAsAggregate()) {
- if (canNodeBeRemoved(newNode->getAsAggregate()->getSequence()[0])) {
- TIntermAggregate* returnAggNode = newNode->getAsAggregate()->getSequence()[0]->getAsAggregate();
- newNode = intermediate.removeChildNode(newNode, type, returnAggNode);
- }
- }
- return newNode;
- }
- }
-
- //
- // Handle list of arguments.
- //
- TIntermSequence &sequenceVector = aggrNode->getSequence() ; // Stores the information about the parameter to the constructor
- // if the structure constructor contains more than one parameter, then construct
- // each parameter
- if (op == EOpConstructStruct) {
- if (structure->size() != sequenceVector.size()) { // If the number of parameters to the constructor does not match the expected number of parameters
- error(line, "Number of constructor parameters does not match the number of structure fields", "constructor", "");
-
- return 0;
- }
- }
-
- int paramCount = 0; // keeps a track of the constructor parameter number being checked
-
- // for each parameter to the constructor call, check to see if the right type is passed or convert them
- // to the right type if possible (and allowed).
- // for structure constructors, just check if the right type is passed, no conversion is allowed.
-
- for (TIntermSequence::iterator p = sequenceVector.begin();
- p != sequenceVector.end(); p++, paramCount++) {
- bool move = false;
- if (op == EOpConstructStruct) {
- newNode = constructStruct(*p, (list[paramCount]).type, paramCount+1, node->getLine(), true);
- if (newNode)
- move = true;
- } else {
- newNode = constructBuiltIn(type, op, *p, node->getLine(), true);
-
- if (newNode) {
- if (canNodeBeRemoved(newNode))
- intermediate.removeChildNode(sequenceVector, *type, paramCount, p, newNode->getAsAggregate());
- else
- move = true;
- }
- }
- if (move) {
- sequenceVector.erase(p);
- sequenceVector.insert(p, newNode);
- }
- }
-
- return intermediate.setAggregateOperator(aggrNode, op, line);
-}
-
-// Function for constructor implementation. Calls addUnaryMath with appropriate EOp value
-// for the parameter to the constructor (passed to this function). Essentially, it converts
-// the parameter types correctly. If a constructor expects an int (like ivec2) and is passed a
-// float, then float is converted to int.
-//
-// Returns 0 for an error or the constructed node.
-//
-TIntermTyped* TParseContext::constructBuiltIn(TType* type, TOperator op, TIntermNode* node, TSourceLoc line, bool subset)
-{
- TIntermTyped* newNode;
- TOperator basicOp;
-
- //
- // First, convert types as needed.
- //
- switch (op) {
- case EOpConstructVec2:
- case EOpConstructVec3:
- case EOpConstructVec4:
- case EOpConstructMat2:
- case EOpConstructMat3:
- case EOpConstructMat4:
- case EOpConstructFloat:
- basicOp = EOpConstructFloat;
- break;
-
- case EOpConstructIVec2:
- case EOpConstructIVec3:
- case EOpConstructIVec4:
- case EOpConstructInt:
- basicOp = EOpConstructInt;
- break;
-
- case EOpConstructBVec2:
- case EOpConstructBVec3:
- case EOpConstructBVec4:
- case EOpConstructBool:
- basicOp = EOpConstructBool;
- break;
-
- default:
- error(line, "unsupported construction", "", "");
- recover();
-
- return 0;
- }
- newNode = intermediate.addUnaryMath(basicOp, node, node->getLine(), symbolTable);
- if (newNode == 0) {
- error(line, "can't convert", "constructor", "");
- return 0;
- }
-
- //
- // Now, if there still isn't an operation to do the construction, and we need one, add one.
- //
-
- // Otherwise, skip out early.
- if (subset || newNode != node && newNode->getType() == *type)
- return newNode;
-
- // setAggregateOperator will insert a new node for the constructor, as needed.
- return intermediate.setAggregateOperator(newNode, op, line);
-}
-
-// This function tests for the type of the parameters to the structures constructors. Raises
-// an error message if the expected type does not match the parameter passed to the constructor.
-//
-// Returns 0 for an error or the input node itself if the expected and the given parameter types match.
-//
-TIntermTyped* TParseContext::constructStruct(TIntermNode* node, TType* type, int paramCount, TSourceLoc line, bool subset)
-{
- if (*type == node->getAsTyped()->getType()) {
- if (subset)
- return node->getAsTyped();
- else
- return intermediate.setAggregateOperator(node->getAsTyped(), EOpConstructStruct, line);
- } else {
- error(line, "", "constructor", "cannot convert parameter %d from '%s' to '%s'", paramCount,
- node->getAsTyped()->getType().getBasicString(), type->getBasicString());
- recover();
- }
-
- return 0;
-}
-
-//
-// This function returns the tree representation for the vector field(s) being accessed from contant vector.
-// If only one component of vector is accessed (v.x or v[0] where v is a contant vector), then a contant node is
-// returned, else an aggregate node is returned (for v.xy). The input to this function could either be the symbol
-// node or it could be the intermediate tree representation of accessing fields in a constant structure or column of
-// a constant matrix.
-//
-TIntermTyped* TParseContext::addConstVectorNode(TVectorFields& fields, TIntermTyped* node, TSourceLoc line)
-{
- TIntermTyped* typedNode;
- TIntermConstantUnion* tempConstantNode = node->getAsConstantUnion();
- TIntermAggregate* aggregateNode = node->getAsAggregate();
-
- constUnion *unionArray;
- if (tempConstantNode) {
- unionArray = tempConstantNode->getUnionArrayPointer();
-
- if (!unionArray) { // this error message should never be raised
- infoSink.info.message(EPrefixInternalError, "constUnion not initialized in addConstVectorNode function", line);
- recover();
-
- return node;
- }
- } else if (aggregateNode) { // if an aggregate node is present, the value has to be taken from the parse tree
- // for a case like vec(4).xz
- unionArray = new constUnion[aggregateNode->getType().getInstanceSize()];
-
- bool returnVal = false;
- if (aggregateNode->getAsAggregate()->getSequence().size() == 1 && aggregateNode->getAsAggregate()->getSequence()[0]->getAsTyped()->getAsConstantUnion()) {
- returnVal = intermediate.parseConstTree(line, aggregateNode, unionArray, aggregateNode->getOp(), symbolTable, aggregateNode->getType(), true);
- }
- else {
- returnVal = intermediate.parseConstTree(line, aggregateNode, unionArray, aggregateNode->getOp(), symbolTable, aggregateNode->getType());
- }
-
- if (returnVal)
- return 0;
-
- } else { // The node has to be either a symbol node or an aggregate node or a tempConstant node, else, its an error
- error(line, "No aggregate or constant union node available", "Internal Error", "");
- recover();
-
- return 0;
- }
-
- constUnion* constArray = new constUnion[fields.num];
-
- for (int i = 0; i < fields.num; i++) {
- if (fields.offsets[i] >= node->getType().getInstanceSize()) {
- error(line, "", "[", "vector field selection out of range '%d'", fields.offsets[i]);
- recover();
- fields.offsets[i] = 0;
- }
-
- constArray[i] = unionArray[fields.offsets[i]];
-
- }
- typedNode = intermediate.addConstantUnion(constArray, node->getType(), line);
- return typedNode;
-}
-
-//
-// This function returns the column being accessed from a constant matrix. The values are retrieved from
-// the symbol table and parse-tree is built for a vector (each column of a matrix is a vector). The input
-// to the function could either be a symbol node (m[0] where m is a constant matrix)that represents a
-// constant matrix or it could be the tree representation of the constant matrix (s.m1[0] where s is a constant structure)
-//
-TIntermTyped* TParseContext::addConstMatrixNode(int index, TIntermTyped* node, TSourceLoc line)
-{
- TIntermTyped* typedNode;
- TIntermConstantUnion* tempConstantNode = node->getAsConstantUnion();
- TIntermAggregate* aggregateNode = node->getAsAggregate();
-
- if (index >= node->getType().getNominalSize()) {
- error(line, "", "[", "matrix field selection out of range '%d'", index);
- recover();
- index = 0;
- }
-
- if (tempConstantNode) {
- constUnion* unionArray = tempConstantNode->getUnionArrayPointer();
- int size = tempConstantNode->getType().getNominalSize();
- typedNode = intermediate.addConstantUnion(&unionArray[size*index], tempConstantNode->getType(), line);
- } else if (aggregateNode) {
- // for a case like mat4(5)[0]
- constUnion* unionArray = new constUnion[aggregateNode->getType().getInstanceSize()];
- int size = aggregateNode->getType().getNominalSize();
-
- bool returnVal = false;
- if (aggregateNode->getAsAggregate()->getSequence().size() == 1 && aggregateNode->getAsAggregate()->getSequence()[0]->getAsTyped()->getAsConstantUnion()) {
- returnVal = intermediate.parseConstTree(line, aggregateNode, unionArray, aggregateNode->getOp(), symbolTable, aggregateNode->getType(), true);
- }
- else {
- returnVal = intermediate.parseConstTree(line, aggregateNode, unionArray, aggregateNode->getOp(), symbolTable, aggregateNode->getType());
- }
-
- if (!returnVal)
- typedNode = intermediate.addConstantUnion(&unionArray[size*index], aggregateNode->getType(), line);
- else
- return 0;
-
- } else {
- error(line, "No Aggregate or Constant Union node available", "Internal Error", "");
- recover();
-
- return 0;
- }
-
- return typedNode;
-}
-
-//
-// This function returns the value of a particular field inside a constant structure from the symbol table.
-// If there is an embedded/nested struct, it appropriately calls addConstStructNested or addConstStructFromAggr
-// function and returns the parse-tree with the values of the embedded/nested struct.
-//
-TIntermTyped* TParseContext::addConstStruct(TString& identifier, TIntermTyped* node, TSourceLoc line)
-{
- TTypeList* fields = node->getType().getStruct();
- TIntermTyped *typedNode;
- int instanceSize = 0;
- unsigned int index = 0;
- TIntermConstantUnion *tempConstantNode = node->getAsConstantUnion();
- TIntermAggregate* aggregateNode = node->getAsAggregate();
-
- for ( index = 0; index < fields->size(); ++index) {
- if ((*fields)[index].type->getFieldName() == identifier) {
- break;
- } else {
- if ((*fields)[index].type->getStruct())
- //?? We should actually be calling getStructSize() function and not setStructSize. This problem occurs in case
- // of nested/embedded structs.
- instanceSize += (*fields)[index].type->setStructSize((*fields)[index].type->getStruct());
- else
- instanceSize += (*fields)[index].type->getInstanceSize();
- }
- }
-
- if (tempConstantNode) {
- constUnion* constArray = tempConstantNode->getUnionArrayPointer();
-
- typedNode = intermediate.addConstantUnion(constArray+instanceSize, tempConstantNode->getType(), line); // type will be changed in the calling function
- } else if (aggregateNode) {
- // for a case like constStruct(1,v3).i where structure fields is int i and vec3 v3.
-
- constUnion* unionArray = new constUnion[aggregateNode->getType().getStructSize()];
-
- bool returnVal = false;
- if (aggregateNode->getAsAggregate()->getSequence().size() == 1 && aggregateNode->getAsAggregate()->getSequence()[0]->getAsTyped()->getAsConstantUnion()) {
- returnVal = intermediate.parseConstTree(line, aggregateNode, unionArray, aggregateNode->getOp(), symbolTable, aggregateNode->getType(), true);
- }
- else {
- returnVal = intermediate.parseConstTree(line, aggregateNode, unionArray, aggregateNode->getOp(), symbolTable, aggregateNode->getType());
- }
-
- if (!returnVal)
- typedNode = intermediate.addConstantUnion(unionArray+instanceSize, aggregateNode->getType(), line);
- else
- return 0;
-
- } else {
- error(line, "No Aggregate or Constant Union node available", "Internal Error", "");
- recover();
-
- return 0;
- }
-
- return typedNode;
-}
-
-//
-// Initialize all supported extensions to disable
-//
-void TParseContext::initializeExtensionBehavior()
-{
- //
- // example code: extensionBehavior["test"] = EDisable; // where "test" is the name of
- // supported extension
- //
-}
-
-OS_TLSIndex GlobalParseContextIndex = OS_INVALID_TLS_INDEX;
-
-bool InitializeParseContextIndex()
-{
- if (GlobalParseContextIndex != OS_INVALID_TLS_INDEX) {
- assert(0 && "InitializeParseContextIndex(): Parse Context already initalised");
- return false;
- }
-
- //
- // Allocate a TLS index.
- //
- GlobalParseContextIndex = OS_AllocTLSIndex();
-
- if (GlobalParseContextIndex == OS_INVALID_TLS_INDEX) {
- assert(0 && "InitializeParseContextIndex(): Parse Context already initalised");
- return false;
- }
-
- return true;
-}
-
-bool InitializeGlobalParseContext()
-{
- if (GlobalParseContextIndex == OS_INVALID_TLS_INDEX) {
- assert(0 && "InitializeGlobalParseContext(): Parse Context index not initalised");
- return false;
- }
-
- TThreadParseContext *lpParseContext = static_cast<TThreadParseContext *>(OS_GetTLSValue(GlobalParseContextIndex));
- if (lpParseContext != 0) {
- assert(0 && "InitializeParseContextIndex(): Parse Context already initalised");
- return false;
- }
-
- TThreadParseContext *lpThreadData = new TThreadParseContext();
- if (lpThreadData == 0) {
- assert(0 && "InitializeGlobalParseContext(): Unable to create thread parse context");
- return false;
- }
-
- lpThreadData->lpGlobalParseContext = 0;
- OS_SetTLSValue(GlobalParseContextIndex, lpThreadData);
-
- return true;
-}
-
-TParseContextPointer& GetGlobalParseContext()
-{
- //
- // Minimal error checking for speed
- //
-
- TThreadParseContext *lpParseContext = static_cast<TThreadParseContext *>(OS_GetTLSValue(GlobalParseContextIndex));
-
- return lpParseContext->lpGlobalParseContext;
-}
-
-bool FreeParseContext()
-{
- if (GlobalParseContextIndex == OS_INVALID_TLS_INDEX) {
- assert(0 && "FreeParseContext(): Parse Context index not initalised");
- return false;
- }
-
- TThreadParseContext *lpParseContext = static_cast<TThreadParseContext *>(OS_GetTLSValue(GlobalParseContextIndex));
- if (lpParseContext)
- delete lpParseContext;
-
- return true;
-}
-
-bool FreeParseContextIndex()
-{
- OS_TLSIndex tlsiIndex = GlobalParseContextIndex;
-
- if (GlobalParseContextIndex == OS_INVALID_TLS_INDEX) {
- assert(0 && "FreeParseContextIndex(): Parse Context index not initalised");
- return false;
- }
-
- GlobalParseContextIndex = OS_INVALID_TLS_INDEX;
-
- return OS_FreeTLSIndex(tlsiIndex);
-}
diff --git a/src/mesa/shader/slang/MachineIndependent/ParseHelper.h b/src/mesa/shader/slang/MachineIndependent/ParseHelper.h deleted file mode 100755 index 00552b8554..0000000000 --- a/src/mesa/shader/slang/MachineIndependent/ParseHelper.h +++ /dev/null @@ -1,143 +0,0 @@ -//
-//Copyright (C) 2002-2005 3Dlabs Inc. Ltd.
-//All rights reserved.
-//
-//Redistribution and use in source and binary forms, with or without
-//modification, are permitted provided that the following conditions
-//are met:
-//
-// Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//
-// Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-//
-// Neither the name of 3Dlabs Inc. Ltd. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-//THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-//"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-//LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
-//FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
-//COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
-//INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
-//BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
-//LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
-//CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-//LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
-//ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
-//POSSIBILITY OF SUCH DAMAGE.
-//
-#ifndef _PARSER_HELPER_INCLUDED_
-#define _PARSER_HELPER_INCLUDED_
-
-#include "../Include/ShHandle.h"
-#include "SymbolTable.h"
-#include "localintermediate.h"
-
-struct TMatrixFields {
- bool wholeRow;
- bool wholeCol;
- int row;
- int col;
-};
-
-typedef enum {
- EBhRequire,
- EBhEnable,
- EBhWarn,
- EBhDisable
-} TBehavior;
-
-struct TPragma {
- TPragma(bool o, bool d) : optimize(o), debug(d) { }
- bool optimize;
- bool debug;
- TPragmaTable pragmaTable;
-};
-
-//
-// The following are extra variables needed during parsing, grouped together so
-// they can be passed to the parser without needing a global.
-//
-struct TParseContext {
- TParseContext(TSymbolTable& symt, TIntermediate& interm, EShLanguage L, TInfoSink& is) :
- intermediate(interm), symbolTable(symt), infoSink(is), language(L), treeRoot(0),
- recoveredFromError(false), numErrors(0), lexAfterType(false), loopNestingLevel(0),
- inTypeParen(false), contextPragma(true, false) { }
- TIntermediate& intermediate; // to hold and build a parse tree
- TSymbolTable& symbolTable; // symbol table that goes with the language currently being parsed
- TInfoSink& infoSink;
- EShLanguage language; // vertex or fragment language (future: pack or unpack)
- TIntermNode* treeRoot; // root of parse tree being created
- bool recoveredFromError; // true if a parse error has occurred, but we continue to parse
- int numErrors;
- bool lexAfterType; // true if we've recognized a type, so can only be looking for an identifier
- int loopNestingLevel; // 0 if outside all loops
- bool inTypeParen; // true if in parentheses, looking only for an identifier
- const TType* currentFunctionType; // the return type of the function that's currently being parsed
- bool functionReturnsValue; // true if a non-void function has a return
- TMap<TString, TBehavior> extensionBehavior;
- void initializeExtensionBehavior();
-
- void C_DECL error(TSourceLoc, const char *szReason, const char *szToken,
- const char *szExtraInfoFormat, ...);
- bool reservedErrorCheck(int line, const TString& identifier);
- void recover();
-
- bool parseVectorFields(const TString&, int vecSize, TVectorFields&, int line);
- bool parseMatrixFields(const TString&, int matSize, TMatrixFields&, int line);
- void assignError(int line, const char* op, TString left, TString right);
- void unaryOpError(int line, char* op, TString operand);
- void binaryOpError(int line, char* op, TString left, TString right);
- bool lValueErrorCheck(int line, char* op, TIntermTyped*);
- bool constErrorCheck(TIntermTyped* node);
- bool integerErrorCheck(TIntermTyped* node, char* token);
- bool globalErrorCheck(int line, bool global, char* token);
- bool constructorErrorCheck(int line, TIntermNode*, TFunction&, TOperator, TType*);
- bool arrayErrorCheck(int line, TString& identifier, TPublicType type, TIntermTyped* size);
- bool insertBuiltInArrayAtGlobalLevel();
- bool voidErrorCheck(int, const TString&, const TPublicType&);
- bool boolErrorCheck(int, const TIntermTyped*);
- bool boolErrorCheck(int, const TPublicType&);
- bool samplerErrorCheck(int line, const TPublicType& pType, const char* reason);
- bool structQualifierErrorCheck(int line, const TPublicType& pType);
- bool parameterSamplerErrorCheck(int line, TQualifier qualifier, const TType& type);
- bool containsSampler(TType& type);
- bool nonInitErrorCheck(int line, TString& identifier, TPublicType& type);
- bool paramErrorCheck(int line, TQualifier qualifier, TQualifier paramQualifier, TType* type);
- const TFunction* findFunction(int line, TFunction* pfnCall, bool *builtIn = 0);
- bool executeInitializer(TSourceLoc line, TString& identifier, TPublicType& pType,
- TIntermTyped* initializer, TIntermNode*& intermNode);
- bool canNodeBeRemoved(TIntermNode*);
- TIntermTyped* addConstructor(TIntermNode*, TType*, TOperator, TFunction*, TSourceLoc);
- TIntermTyped* constructStruct(TIntermNode*, TType*, int, TSourceLoc, bool subset);
- TIntermTyped* constructBuiltIn(TType*, TOperator, TIntermNode*, TSourceLoc, bool subset);
- TIntermTyped* addConstVectorNode(TVectorFields&, TIntermTyped*, TSourceLoc);
- TIntermTyped* addConstMatrixNode(int , TIntermTyped*, TSourceLoc);
- TIntermTyped* addConstStruct(TString& , TIntermTyped*, TSourceLoc);
- bool arraySetMaxSize(TIntermSymbol*, TType*, int, bool, TSourceLoc);
- struct TPragma contextPragma;
- TString HashErrMsg;
- bool AfterEOF;
-};
-
-int PaParseStrings(char* argv[], int strLen[], int argc, TParseContext&);
-void PaReservedWord();
-int PaIdentOrType(TString& id, TParseContext&, TSymbol*&);
-int PaParseComment(int &lineno, TParseContext&);
-void setInitialState();
-
-typedef TParseContext* TParseContextPointer;
-extern TParseContextPointer& GetGlobalParseContext();
-#define GlobalParseContext GetGlobalParseContext()
-
-typedef struct TThreadParseContextRec
-{
- TParseContext *lpGlobalParseContext;
-} TThreadParseContext;
-
-#endif // _PARSER_HELPER_INCLUDED_
diff --git a/src/mesa/shader/slang/MachineIndependent/PoolAlloc.cpp b/src/mesa/shader/slang/MachineIndependent/PoolAlloc.cpp deleted file mode 100755 index ba717fce12..0000000000 --- a/src/mesa/shader/slang/MachineIndependent/PoolAlloc.cpp +++ /dev/null @@ -1,349 +0,0 @@ -//
-//Copyright (C) 2002-2005 3Dlabs Inc. Ltd.
-//All rights reserved.
-//
-//Redistribution and use in source and binary forms, with or without
-//modification, are permitted provided that the following conditions
-//are met:
-//
-// Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//
-// Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-//
-// Neither the name of 3Dlabs Inc. Ltd. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-//THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-//"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-//LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
-//FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
-//COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
-//INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
-//BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
-//LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
-//CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-//LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
-//ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
-//POSSIBILITY OF SUCH DAMAGE.
-//
-
-#include "../Include/PoolAlloc.h"
-#include "../Include/Common.h"
-
-#include "Include/InitializeGlobals.h"
-#include "osinclude.h"
-
-OS_TLSIndex PoolIndex;
-
-void InitializeGlobalPools()
-{
- TThreadGlobalPools* globalPools= static_cast<TThreadGlobalPools*>(OS_GetTLSValue(PoolIndex));
- if (globalPools)
- return;
-
- TPoolAllocator *globalPoolAllocator = new TPoolAllocator(true);
-
- TThreadGlobalPools* threadData = new TThreadGlobalPools();
-
- threadData->globalPoolAllocator = globalPoolAllocator;
-
- OS_SetTLSValue(PoolIndex, threadData);
- globalPoolAllocator->push();
-}
-
-void FreeGlobalPools()
-{
- // Release the allocated memory for this thread.
- TThreadGlobalPools* globalPools= static_cast<TThreadGlobalPools*>(OS_GetTLSValue(PoolIndex));
- if (!globalPools)
- return;
-
- GlobalPoolAllocator.popAll();
- delete &GlobalPoolAllocator;
- delete globalPools;
-}
-
-bool InitializePoolIndex()
-{
- // Allocate a TLS index.
- if ((PoolIndex = OS_AllocTLSIndex()) == OS_INVALID_TLS_INDEX)
- return false;
-
- return true;
-}
-
-void FreePoolIndex()
-{
- // Release the TLS index.
- OS_FreeTLSIndex(PoolIndex);
-}
-
-TPoolAllocator& GetGlobalPoolAllocator()
-{
- TThreadGlobalPools* threadData = static_cast<TThreadGlobalPools*>(OS_GetTLSValue(PoolIndex));
-
- return *threadData->globalPoolAllocator;
-}
-
-void SetGlobalPoolAllocatorPtr(TPoolAllocator* poolAllocator)
-{
- TThreadGlobalPools* threadData = static_cast<TThreadGlobalPools*>(OS_GetTLSValue(PoolIndex));
-
- threadData->globalPoolAllocator = poolAllocator;
-}
-
-//
-// Implement the functionality of the TPoolAllocator class, which
-// is documented in PoolAlloc.h.
-//
-TPoolAllocator::TPoolAllocator(bool g, int growthIncrement, int allocationAlignment) :
- global(g),
- pageSize(growthIncrement),
- alignment(allocationAlignment),
- freeList(0),
- inUseList(0),
- numCalls(0)
-{
- //
- // Don't allow page sizes we know are smaller than all common
- // OS page sizes.
- //
- if (pageSize < 4*1024)
- pageSize = 4*1024;
-
- //
- // A large currentPageOffset indicates a new page needs to
- // be obtained to allocate memory.
- //
- currentPageOffset = pageSize;
-
- //
- // Adjust alignment to be at least pointer aligned and
- // power of 2.
- //
- size_t minAlign = sizeof(void*);
- alignment &= ~(minAlign - 1);
- if (alignment < minAlign)
- alignment = minAlign;
- size_t a = 1;
- while (a < alignment)
- a <<= 1;
- alignment = a;
- alignmentMask = a - 1;
-
- //
- // Align header skip
- //
- headerSkip = minAlign;
- if (headerSkip < sizeof(tHeader)) {
- headerSkip = (sizeof(tHeader) + alignmentMask) & ~alignmentMask;
- }
-
- //
- // Put a marker at the beginning of the stack. We won't
- // pop() past this.
- //
- tAllocState start = { currentPageOffset, 0 };
- stack.push_back(start);
-}
-
-TPoolAllocator::~TPoolAllocator()
-{
- if (!global) {
- //
- // Then we know that this object is not being
- // allocated after other, globally scoped objects
- // that depend on it. So we can delete the "in use" memory.
- //
- while (inUseList) {
- tHeader* next = inUseList->nextPage;
- inUseList->~tHeader();
- delete [] reinterpret_cast<char*>(inUseList);
- inUseList = next;
- }
- }
-
- //
- // Always delete the free list memory - it can't be being
- // (correctly) referenced, whether the pool allocator was
- // global or not. We should not check the guard blocks
- // here, because we did it already when the block was
- // placed into the free list.
- //
- while (freeList) {
- tHeader* next = freeList->nextPage;
- delete [] reinterpret_cast<char*>(freeList);
- freeList = next;
- }
-}
-
-// Support MSVC++ 6.0
-const unsigned char TAllocation::guardBlockBeginVal = 0xfb;
-const unsigned char TAllocation::guardBlockEndVal = 0xfe;
-const unsigned char TAllocation::userDataFill = 0xcd;
-
-# ifdef GUARD_BLOCKS
- const size_t TAllocation::guardBlockSize = 16;
-# else
- const size_t TAllocation::guardBlockSize = 0;
-# endif
-
-//
-// Check a single guard block for damage
-//
-void TAllocation::checkGuardBlock(unsigned char* blockMem, unsigned char val, char* locText) const
-{
- for (int x = 0; x < guardBlockSize; x++) {
- if (blockMem[x] != val) {
- char assertMsg[80];
-
- // We don't print the assert message. It's here just to be helpful.
- sprintf(assertMsg, "PoolAlloc: Damage %s %u byte allocation at 0x%p\n",
- locText, size, data());
- assert(0 && "PoolAlloc: Damage in guard block");
- }
- }
-}
-
-
-void TPoolAllocator::push()
-{
- tAllocState state = { currentPageOffset, inUseList };
-
- stack.push_back(state);
-
- //
- // Indicate there is no current page to allocate from.
- //
- currentPageOffset = pageSize;
-}
-
-//
-// Do a mass-deallocation of all the individual allocations
-// that have occurred since the last push(), or since the
-// last pop(), or since the object's creation.
-//
-// The deallocated pages are saved for future allocations.
-//
-void TPoolAllocator::pop()
-{
- if (stack.size() < 1)
- return;
-
- tHeader* page = stack.back().page;
- currentPageOffset = stack.back().offset;
-
- while (inUseList != page) {
- // invoke destructor to free allocation list
- inUseList->~tHeader();
-
- tHeader* nextInUse = inUseList->nextPage;
- if (inUseList->pageCount > 1)
- delete [] reinterpret_cast<char*>(inUseList);
- else {
- inUseList->nextPage = freeList;
- freeList = inUseList;
- }
- inUseList = nextInUse;
- }
-
- stack.pop_back();
-}
-
-//
-// Do a mass-deallocation of all the individual allocations
-// that have occurred.
-//
-void TPoolAllocator::popAll()
-{
- while (stack.size() > 0)
- pop();
-}
-
-void* TPoolAllocator::allocate(size_t numBytes)
-{
- // If we are using guard blocks, all allocations are bracketed by
- // them: [guardblock][allocation][guardblock]. numBytes is how
- // much memory the caller asked for. allocationSize is the total
- // size including guard blocks. In release build,
- // guardBlockSize=0 and this all gets optimized away.
- size_t allocationSize = TAllocation::allocationSize(numBytes);
-
- //
- // Just keep some interesting statistics.
- //
- ++numCalls;
- totalBytes += numBytes;
-
- //
- // Do the allocation, most likely case first, for efficiency.
- // This step could be moved to be inline sometime.
- //
- if (currentPageOffset + allocationSize <= pageSize) {
- //
- // Safe to allocate from currentPageOffset.
- //
- unsigned char* memory = reinterpret_cast<unsigned char *>(inUseList) + currentPageOffset;
- currentPageOffset += allocationSize;
- currentPageOffset = (currentPageOffset + alignmentMask) & ~alignmentMask;
-
- return initializeAllocation(inUseList, memory, numBytes);
- }
-
- if (allocationSize + headerSkip > pageSize) {
- //
- // Do a multi-page allocation. Don't mix these with the others.
- // The OS is efficient and allocating and free-ing multiple pages.
- //
- size_t numBytesToAlloc = allocationSize + headerSkip;
- tHeader* memory = reinterpret_cast<tHeader*>(::new char[numBytesToAlloc]);
- if (memory == 0)
- return 0;
-
- // Use placement-new to initialize header
- new(memory) tHeader(inUseList, (numBytesToAlloc + pageSize - 1) / pageSize);
- inUseList = memory;
-
- currentPageOffset = pageSize; // make next allocation come from a new page
-
- // No guard blocks for multi-page allocations (yet)
- return reinterpret_cast<void*>(reinterpret_cast<UINT_PTR>(memory) + headerSkip);
- }
-
- //
- // Need a simple page to allocate from.
- //
- tHeader* memory;
- if (freeList) {
- memory = freeList;
- freeList = freeList->nextPage;
- } else {
- memory = reinterpret_cast<tHeader*>(::new char[pageSize]);
- if (memory == 0)
- return 0;
- }
-
- // Use placement-new to initialize header
- new(memory) tHeader(inUseList, 1);
- inUseList = memory;
-
- unsigned char* ret = reinterpret_cast<unsigned char *>(inUseList) + headerSkip;
- currentPageOffset = (headerSkip + allocationSize + alignmentMask) & ~alignmentMask;
-
- return initializeAllocation(inUseList, ret, numBytes);
-}
-
-
-//
-// Check all allocations in a list for damage by calling check on each.
-//
-void TAllocation::checkAllocList() const
-{
- for (const TAllocation* alloc = this; alloc != 0; alloc = alloc->prevAlloc)
- alloc->check();
-}
diff --git a/src/mesa/shader/slang/MachineIndependent/QualifierAlive.cpp b/src/mesa/shader/slang/MachineIndependent/QualifierAlive.cpp deleted file mode 100755 index 2897f48b19..0000000000 --- a/src/mesa/shader/slang/MachineIndependent/QualifierAlive.cpp +++ /dev/null @@ -1,91 +0,0 @@ -//
-//Copyright (C) 2002-2005 3Dlabs Inc. Ltd.
-//All rights reserved.
-//
-//Redistribution and use in source and binary forms, with or without
-//modification, are permitted provided that the following conditions
-//are met:
-//
-// Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//
-// Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-//
-// Neither the name of 3Dlabs Inc. Ltd. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-//THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-//"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-//LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
-//FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
-//COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
-//INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
-//BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
-//LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
-//CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-//LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
-//ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
-//POSSIBILITY OF SUCH DAMAGE.
-//
-
-#include "../Include/intermediate.h"
-
-class TAliveTraverser : public TIntermTraverser {
-public:
- TAliveTraverser(TQualifier q) : TIntermTraverser(), found(false), qualifier(q)
- {
- visitSymbol = AliveSymbol;
- visitSelection = AliveSelection;
- rightToLeft = true;
- }
- bool wasFound() { return found; }
-protected:
- bool found;
- TQualifier qualifier;
-
- friend void AliveSymbol(TIntermSymbol*, TIntermTraverser*);
- friend bool AliveSelection(bool, TIntermSelection*, TIntermTraverser*);
-};
-
-//
-// Report whether or not a variable of the given qualifier type
-// is guaranteed written. Not always possible to determine if
-// it is written conditionally.
-//
-// ?? It does not do this well yet, this is just a place holder
-// that simply determines if it was reference at all, anywhere.
-//
-bool QualifierWritten(TIntermNode* node, TQualifier qualifier)
-{
- TAliveTraverser it(qualifier);
-
- if (node)
- node->traverse(&it);
-
- return it.wasFound();
-}
-
-void AliveSymbol(TIntermSymbol* node, TIntermTraverser* it)
-{
- TAliveTraverser* lit = static_cast<TAliveTraverser*>(it);
-
- //
- // If it's what we're looking for, record it.
- //
- if (node->getQualifier() == lit->qualifier)
- lit->found = true;
-}
-
-bool AliveSelection(bool preVisit, TIntermSelection* node, TIntermTraverser* it)
-{
- TAliveTraverser* lit = static_cast<TAliveTraverser*>(it);
-
- if (lit->wasFound())
- return false;
-
- return true;
-}
diff --git a/src/mesa/shader/slang/MachineIndependent/QualifierAlive.h b/src/mesa/shader/slang/MachineIndependent/QualifierAlive.h deleted file mode 100755 index 73e902cd0d..0000000000 --- a/src/mesa/shader/slang/MachineIndependent/QualifierAlive.h +++ /dev/null @@ -1,35 +0,0 @@ -//
-//Copyright (C) 2002-2005 3Dlabs Inc. Ltd.
-//All rights reserved.
-//
-//Redistribution and use in source and binary forms, with or without
-//modification, are permitted provided that the following conditions
-//are met:
-//
-// Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//
-// Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-//
-// Neither the name of 3Dlabs Inc. Ltd. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-//THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-//"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-//LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
-//FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
-//COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
-//INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
-//BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
-//LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
-//CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-//LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
-//ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
-//POSSIBILITY OF SUCH DAMAGE.
-//
-
-bool QualifierWritten(TIntermNode* root, TQualifier);
diff --git a/src/mesa/shader/slang/MachineIndependent/RemoveTree.cpp b/src/mesa/shader/slang/MachineIndependent/RemoveTree.cpp deleted file mode 100755 index 2435a485b6..0000000000 --- a/src/mesa/shader/slang/MachineIndependent/RemoveTree.cpp +++ /dev/null @@ -1,98 +0,0 @@ -//
-//Copyright (C) 2002-2005 3Dlabs Inc. Ltd.
-//All rights reserved.
-//
-//Redistribution and use in source and binary forms, with or without
-//modification, are permitted provided that the following conditions
-//are met:
-//
-// Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//
-// Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-//
-// Neither the name of 3Dlabs Inc. Ltd. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-//THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-//"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-//LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
-//FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
-//COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
-//INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
-//BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
-//LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
-//CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-//LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
-//ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
-//POSSIBILITY OF SUCH DAMAGE.
-//
-
-#include "../Include/intermediate.h"
-#include "RemoveTree.h"
-//
-// Code to recursively delete the intermediate tree.
-//
-
-void RemoveSymbol(TIntermSymbol* node, TIntermTraverser* it)
-{
- delete node;
-}
-
-bool RemoveBinary(bool /*preVisit*/ , TIntermBinary* node, TIntermTraverser*)
-{
- delete node;
-
- return true;
-}
-
-bool RemoveUnary(bool /*preVisit */, TIntermUnary* node, TIntermTraverser*)
-{
- delete node;
-
- return true;
-}
-
-bool RemoveAggregate(bool /*preVisit*/ , TIntermAggregate* node, TIntermTraverser*)
-{
- delete node;
-
- return true;
-}
-
-bool RemoveSelection(bool /*preVisit*/ , TIntermSelection* node, TIntermTraverser*)
-{
- delete node;
-
- return true;
-}
-
-void RemoveConstantUnion(TIntermConstantUnion* node, TIntermTraverser*)
-{
- delete node;
-}
-
-//
-// Entry point.
-//
-void RemoveAllTreeNodes(TIntermNode* root)
-{
- TIntermTraverser it;
-
- it.visitAggregate = RemoveAggregate;
- it.visitBinary = RemoveBinary;
- it.visitConstantUnion = RemoveConstantUnion;
- it.visitSelection = RemoveSelection;
- it.visitSymbol = RemoveSymbol;
- it.visitUnary = RemoveUnary;
-
- it.preVisit = false;
- it.postVisit = true;
-
- root->traverse(&it);
-}
-
diff --git a/src/mesa/shader/slang/MachineIndependent/RemoveTree.h b/src/mesa/shader/slang/MachineIndependent/RemoveTree.h deleted file mode 100755 index 171092f1ab..0000000000 --- a/src/mesa/shader/slang/MachineIndependent/RemoveTree.h +++ /dev/null @@ -1,35 +0,0 @@ -//
-//Copyright (C) 2002-2005 3Dlabs Inc. Ltd.
-//All rights reserved.
-//
-//Redistribution and use in source and binary forms, with or without
-//modification, are permitted provided that the following conditions
-//are met:
-//
-// Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//
-// Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-//
-// Neither the name of 3Dlabs Inc. Ltd. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-//THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-//"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-//LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
-//FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
-//COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
-//INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
-//BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
-//LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
-//CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-//LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
-//ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
-//POSSIBILITY OF SUCH DAMAGE.
-//
-
-void RemoveAllTreeNodes(TIntermNode*);
diff --git a/src/mesa/shader/slang/MachineIndependent/ShaderLang.cpp b/src/mesa/shader/slang/MachineIndependent/ShaderLang.cpp deleted file mode 100755 index 3f37e15f37..0000000000 --- a/src/mesa/shader/slang/MachineIndependent/ShaderLang.cpp +++ /dev/null @@ -1,607 +0,0 @@ -//
-//Copyright (C) 2002-2005 3Dlabs Inc. Ltd.
-//All rights reserved.
-//
-//Redistribution and use in source and binary forms, with or without
-//modification, are permitted provided that the following conditions
-//are met:
-//
-// Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//
-// Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-//
-// Neither the name of 3Dlabs Inc. Ltd. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-//THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-//"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-//LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
-//FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
-//COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
-//INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
-//BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
-//LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
-//CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-//LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
-//ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
-//POSSIBILITY OF SUCH DAMAGE.
-//
-
-//
-// Implement the top-level of interface to the compiler/linker,
-// as defined in ShaderLang.h
-//
-#include "SymbolTable.h"
-#include "ParseHelper.h"
-#include "../Include/ShHandle.h"
-#include "Initialisation.h"
-
-#define SH_EXPORTING
-#include "../Public/ShaderLangExt.h"
-
-#include "Include/ResourceLimits.h"
-#include "Initialize.h"
-
-extern "C" int InitPreprocessor(void);
-extern "C" int FinalizePreprocessor(void);
-extern void SetGlobalPoolAllocatorPtr(TPoolAllocator* poolAllocator);
-
-bool generateBuiltInSymbolTable(const TBuiltInResource* resources, TInfoSink&, TSymbolTable*, EShLanguage language = EShLangCount);
-bool initializeSymbolTable(TBuiltInStrings* BuiltInStrings, EShLanguage language, TInfoSink& infoSink, const TBuiltInResource *resources, TSymbolTable*);
-
-//
-// A symbol table for each language. Each has a different
-// set of built-ins, and we want to preserve that from
-// compile to compile.
-//
-TSymbolTable SymbolTables[EShLangCount];
-
-TPoolAllocator* PerProcessGPA = 0;
-//
-// This is the platform independent interface between an OGL driver
-// and the shading language compiler/linker.
-//
-
-//
-// Driver must call this first, once, before doing any other
-// compiler/linker operations.
-//
-int ShInitialize()
-{
- TInfoSink infoSink;
- bool ret = true;
-
- if (!InitProcess())
- return 0;
-
- // This method should be called once per process. If its called by multiple threads, then
- // we need to have thread synchronization code around the initialization of per process
- // global pool allocator
- if (!PerProcessGPA) {
- TPoolAllocator *builtInPoolAllocator = new TPoolAllocator(true);
- builtInPoolAllocator->push();
- TPoolAllocator* gPoolAllocator = &GlobalPoolAllocator;
- SetGlobalPoolAllocatorPtr(builtInPoolAllocator);
-
- TSymbolTable symTables[EShLangCount];
- generateBuiltInSymbolTable(0, infoSink, symTables);
-
- PerProcessGPA = new TPoolAllocator(true);
- PerProcessGPA->push();
- SetGlobalPoolAllocatorPtr(PerProcessGPA);
-
- SymbolTables[EShLangVertex].copyTable(symTables[EShLangVertex]);
- SymbolTables[EShLangFragment].copyTable(symTables[EShLangFragment]);
-
- SetGlobalPoolAllocatorPtr(gPoolAllocator);
-
- symTables[EShLangVertex].pop();
- symTables[EShLangFragment].pop();
-
- builtInPoolAllocator->popAll();
- delete builtInPoolAllocator;
-
- }
-
- return ret ? 1 : 0;
-}
-
-//
-// Driver calls these to create and destroy compiler/linker
-// objects.
-//
-
-ShHandle ShConstructCompiler(const EShLanguage language, int debugOptions)
-{
- if (!InitThread())
- return 0;
-
- TShHandleBase* base = static_cast<TShHandleBase*>(ConstructCompiler(language, debugOptions));
-
- return reinterpret_cast<void*>(base);
-}
-
-ShHandle ShConstructLinker(const EShExecutable executable, int debugOptions)
-{
- if (!InitThread())
- return 0;
-
- TShHandleBase* base = static_cast<TShHandleBase*>(ConstructLinker(executable, debugOptions));
-
- return reinterpret_cast<void*>(base);
-}
-
-ShHandle ShConstructUniformMap()
-{
- if (!InitThread())
- return 0;
-
- TShHandleBase* base = static_cast<TShHandleBase*>(ConstructUniformMap());
-
- return reinterpret_cast<void*>(base);
-}
-
-void ShDestruct(ShHandle handle)
-{
- if (handle == 0)
- return;
-
- TShHandleBase* base = static_cast<TShHandleBase*>(handle);
-
- if (base->getAsCompiler())
- DeleteCompiler(base->getAsCompiler());
- else if (base->getAsLinker())
- DeleteLinker(base->getAsLinker());
- else if (base->getAsUniformMap())
- DeleteUniformMap(base->getAsUniformMap());
-}
-
-//
-// Cleanup symbol tables
-//
-int __fastcall ShFinalize()
-{
- if (PerProcessGPA) {
- PerProcessGPA->popAll();
- delete PerProcessGPA;
- }
- return 1;
-}
-
-//
-// This function should be called only once by the Master Dll. Currently, this is being called for each thread
-// which is incorrect. This is required to keep the Sh interface working for now and will eventually be called
-// from master dll once.
-//
-bool generateBuiltInSymbolTable(const TBuiltInResource* resources, TInfoSink& infoSink, TSymbolTable* symbolTables, EShLanguage language)
-{
- TBuiltIns builtIns;
-
- if (resources) {
- builtIns.initialize(*resources);
- initializeSymbolTable(builtIns.getBuiltInStrings(), language, infoSink, resources, symbolTables);
- } else {
- builtIns.initialize();
- initializeSymbolTable(builtIns.getBuiltInStrings(), EShLangVertex, infoSink, resources, symbolTables);
- initializeSymbolTable(builtIns.getBuiltInStrings(), EShLangFragment, infoSink, resources, symbolTables);
- }
-
- return true;
-}
-
-bool initializeSymbolTable(TBuiltInStrings* BuiltInStrings, EShLanguage language, TInfoSink& infoSink, const TBuiltInResource* resources, TSymbolTable* symbolTables)
-{
- TIntermediate intermediate(infoSink);
- TSymbolTable* symbolTable;
-
- if (resources)
- symbolTable = symbolTables;
- else
- symbolTable = &symbolTables[language];
-
- TParseContext parseContext(*symbolTable, intermediate, language, infoSink);
-
- GlobalParseContext = &parseContext;
-
- setInitialState();
-
- assert (symbolTable->isEmpty() || symbolTable->atSharedBuiltInLevel());
-
- //
- // Parse the built-ins. This should only happen once per
- // language symbol table.
- //
- // Push the symbol table to give it an initial scope. This
- // push should not have a corresponding pop, so that built-ins
- // are preserved, and the test for an empty table fails.
- //
-
- symbolTable->push();
-
- //Initialize the Preprocessor
- int ret = InitPreprocessor();
- if (ret) {
- infoSink.info.message(EPrefixInternalError, "Unable to intialize the Preprocessor");
- return false;
- }
-
- for (TBuiltInStrings::iterator i = BuiltInStrings[parseContext.language].begin();
- i != BuiltInStrings[parseContext.language].end();
- ++i) {
- const char* builtInShaders[1];
- int builtInLengths[1];
-
- builtInShaders[0] = (*i).c_str();
- builtInLengths[0] = (int) (*i).size();
-
- if (PaParseStrings(const_cast<char**>(builtInShaders), builtInLengths, 1, parseContext) != 0) {
- infoSink.info.message(EPrefixInternalError, "Unable to parse built-ins");
- return false;
- }
- }
-
- if (resources) {
- IdentifyBuiltIns(parseContext.language, *symbolTable, *resources);
- } else {
- IdentifyBuiltIns(parseContext.language, *symbolTable);
- }
-
- FinalizePreprocessor();
-
- return true;
-}
-
-
-//
-// Do an actual compile on the given strings. The result is left
-// in the given compile object.
-//
-// Return: The return value of ShCompile is really boolean, indicating
-// success or failure.
-//
-int ShCompile(
- const ShHandle handle,
- const char* const shaderStrings[],
- const int numStrings,
- const EShOptimizationLevel optLevel,
- const TBuiltInResource* resources,
- int debugOptions
- )
-{
- if (!InitThread())
- return 0;
-
- if (handle == 0)
- return 0;
-
- TShHandleBase* base = reinterpret_cast<TShHandleBase*>(handle);
- TCompiler* compiler = base->getAsCompiler();
- if (compiler == 0)
- return 0;
-
- GlobalPoolAllocator.push();
- compiler->infoSink.info.erase();
- compiler->infoSink.debug.erase();
-
- if (numStrings == 0)
- return 1;
-
- TIntermediate intermediate(compiler->infoSink);
- TSymbolTable symbolTable(SymbolTables[compiler->getLanguage()]);
-
- generateBuiltInSymbolTable(resources, compiler->infoSink, &symbolTable, compiler->getLanguage());
-
- TParseContext parseContext(symbolTable, intermediate, compiler->getLanguage(), compiler->infoSink);
- parseContext.initializeExtensionBehavior();
-
- GlobalParseContext = &parseContext;
-
- setInitialState();
-
- InitPreprocessor();
- //
- // Parse the application's shaders. All the following symbol table
- // work will be throw-away, so push a new allocation scope that can
- // be thrown away, then push a scope for the current shader's globals.
- //
- bool success = true;
-
- symbolTable.push();
- if (!symbolTable.atGlobalLevel())
- parseContext.infoSink.info.message(EPrefixInternalError, "Wrong symbol table level");
-
- if (parseContext.insertBuiltInArrayAtGlobalLevel())
- success = false;
-
- int ret = PaParseStrings(const_cast<char**>(shaderStrings), 0, numStrings, parseContext);
- if (ret)
- success = false;
-
- if (success && parseContext.treeRoot) {
- if (optLevel == EShOptNoGeneration)
- parseContext.infoSink.info.message(EPrefixNone, "No errors. No code generation or linking was requested.");
- else {
- success = intermediate.postProcess(parseContext.treeRoot, parseContext.language);
-
- if (success) {
-
- if (debugOptions & EDebugOpIntermediate)
- intermediate.outputTree(parseContext.treeRoot);
-
- //
- // Call the machine dependent compiler
- //
- if (! compiler->compile(parseContext.treeRoot))
- success = false;
- }
- }
- } else if (!success) {
- parseContext.infoSink.info.prefix(EPrefixError);
- parseContext.infoSink.info << parseContext.numErrors << " compilation errors. No code generated.\n\n";
- success = false;
- if (debugOptions & EDebugOpIntermediate)
- intermediate.outputTree(parseContext.treeRoot);
- }
-
- intermediate.remove(parseContext.treeRoot);
-
- //
- // Ensure symbol table is returned to the built-in level,
- // throwing away all but the built-ins.
- //
- while (! symbolTable.atSharedBuiltInLevel())
- symbolTable.pop();
-
- FinalizePreprocessor();
- //
- // Throw away all the temporary memory used by the compilation process.
- //
- GlobalPoolAllocator.pop();
-
- return success ? 1 : 0;
-}
-
-//
-// Do an actual link on the given compile objects.
-//
-// Return: The return value of is really boolean, indicating
-// success or failure.
-//
-int ShLink(
- const ShHandle linkHandle,
- const ShHandle compHandles[],
- const int numHandles,
- ShHandle uniformMapHandle,
- short int** uniformsAccessed,
- int* numUniformsAccessed)
-
-{
- if (!InitThread())
- return 0;
-
- TShHandleBase* base = reinterpret_cast<TShHandleBase*>(linkHandle);
- TLinker* linker = static_cast<TLinker*>(base->getAsLinker());
- if (linker == 0)
- return 0;
-
- int returnValue;
- GlobalPoolAllocator.push();
- returnValue = ShLinkExt(linkHandle, compHandles, numHandles);
- GlobalPoolAllocator.pop();
-
- if (returnValue)
- return 1;
-
- return 0;
-}
-//
-// This link method will be eventually used once the ICD supports the new linker interface
-//
-int ShLinkExt(
- const ShHandle linkHandle,
- const ShHandle compHandles[],
- const int numHandles)
-{
- if (linkHandle == 0 || numHandles == 0)
- return 0;
-
- THandleList cObjects;
-
- {// support MSVC++6.0
- for (int i = 0; i < numHandles; ++i) {
- if (compHandles[i] == 0)
- return 0;
- TShHandleBase* base = reinterpret_cast<TShHandleBase*>(compHandles[i]);
- if (base->getAsLinker()) {
- cObjects.push_back(base->getAsLinker());
- }
- if (base->getAsCompiler())
- cObjects.push_back(base->getAsCompiler());
-
-
- if (cObjects[i] == 0)
- return 0;
- }
- }
-
- TShHandleBase* base = reinterpret_cast<TShHandleBase*>(linkHandle);
- TLinker* linker = static_cast<TLinker*>(base->getAsLinker());
-
- if (linker == 0)
- return 0;
-
- linker->infoSink.info.erase();
-
- {// support MSVC++6.0
- for (int i = 0; i < numHandles; ++i) {
- if (cObjects[i]->getAsCompiler()) {
- if (! cObjects[i]->getAsCompiler()->linkable()) {
- linker->infoSink.info.message(EPrefixError, "Not all shaders have valid object code.");
- return 0;
- }
- }
- }
- }
-
- bool ret = linker->link(cObjects);
-
- return ret ? 1 : 0;
-}
-
-//
-// ShSetEncrpytionMethod is a place-holder for specifying
-// how source code is encrypted.
-//
-void ShSetEncryptionMethod(ShHandle handle)
-{
- if (handle == 0)
- return;
-}
-
-//
-// Return any compiler/linker/uniformmap log of messages for the application.
-//
-const char* ShGetInfoLog(const ShHandle handle)
-{
- if (!InitThread())
- return 0;
-
- if (handle == 0)
- return 0;
-
- TShHandleBase* base = static_cast<TShHandleBase*>(handle);
- TInfoSink* infoSink;
-
- if (base->getAsCompiler())
- infoSink = &(base->getAsCompiler()->getInfoSink());
- else if (base->getAsLinker())
- infoSink = &(base->getAsLinker()->getInfoSink());
-
- infoSink->info << infoSink->debug.c_str();
- return infoSink->info.c_str();
-}
-
-//
-// Return the resulting binary code from the link process. Structure
-// is machine dependent.
-//
-const void* ShGetExecutable(const ShHandle handle)
-{
- if (!InitThread())
- return 0;
-
- if (handle == 0)
- return 0;
-
- TShHandleBase* base = reinterpret_cast<TShHandleBase*>(handle);
-
- TLinker* linker = static_cast<TLinker*>(base->getAsLinker());
- if (linker == 0)
- return 0;
-
- return linker->getObjectCode();
-}
-
-//
-// Let the linker know where the application said it's attributes are bound.
-// The linker does not use these values, they are remapped by the ICD or
-// hardware. It just needs them to know what's aliased.
-//
-// Return: The return value of is really boolean, indicating
-// success or failure.
-//
-// This is to preserve the old linker API, P20 code can use the generic
-// ShConstructBinding() and ShAddBinding() APIs
-//
-int ShSetVirtualAttributeBindings(const ShHandle handle, const ShBindingTable* table)
-{
- if (!InitThread())
- return 0;
-
- if (handle == 0)
- return 0;
-
- TShHandleBase* base = reinterpret_cast<TShHandleBase*>(handle);
- TLinker* linker = static_cast<TLinker*>(base->getAsLinker());
-
- if (linker == 0)
- return 0;
-
- linker->setAppAttributeBindings(table);
-
- return 1;
-}
-
-//
-// Let the linker know where the predefined attributes have to live.
-// This is to preserve the old linker API, P20 code can use the generic
-// ShConstructBinding() and ShAddBinding() APIs
-//
-int ShSetFixedAttributeBindings(const ShHandle handle, const ShBindingTable* table)
-{
- if (!InitThread())
- return 0;
-
- if (handle == 0)
- return 0;
-
- TShHandleBase* base = reinterpret_cast<TShHandleBase*>(handle);
- TLinker* linker = static_cast<TLinker*>(base->getAsLinker());
-
- if (linker == 0)
- return 0;
-
- linker->setFixedAttributeBindings(table);
- return 1;
-}
-
-//
-// Some attribute locations are off-limits to the linker...
-//
-int ShExcludeAttributes(const ShHandle handle, int *attributes, int count)
-{
- if (!InitThread())
- return 0;
-
- if (handle == 0)
- return 0;
-
- TShHandleBase* base = reinterpret_cast<TShHandleBase*>(handle);
- TLinker* linker = static_cast<TLinker*>(base->getAsLinker());
- if (linker == 0)
- return 0;
-
- linker->setExcludedAttributes(attributes, count);
-
- return 1;
-}
-
-//
-// Return the index for OpenGL to use for knowing where a uniform lives.
-//
-// Return: The return value of is really boolean, indicating
-// success or failure.
-//
-// We dont have to change this code for now since the TUniformMap being
-// passed back to ICD by the linker is the same as being used for the old P10 linker
-//
-int ShGetUniformLocation(const ShHandle handle, const char* name)
-{
- if (!InitThread())
- return 0;
-
- if (handle == 0)
- return -1;
-
- TShHandleBase* base = reinterpret_cast<TShHandleBase*>(handle);
- TUniformMap* uniformMap= base->getAsUniformMap();
- if (uniformMap == 0)
- return -1;
-
- return uniformMap->getLocation(name);
-}
diff --git a/src/mesa/shader/slang/MachineIndependent/SymbolTable.cpp b/src/mesa/shader/slang/MachineIndependent/SymbolTable.cpp deleted file mode 100755 index 0e052c2ea7..0000000000 --- a/src/mesa/shader/slang/MachineIndependent/SymbolTable.cpp +++ /dev/null @@ -1,235 +0,0 @@ -//
-//Copyright (C) 2002-2005 3Dlabs Inc. Ltd.
-//All rights reserved.
-//
-//Redistribution and use in source and binary forms, with or without
-//modification, are permitted provided that the following conditions
-//are met:
-//
-// Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//
-// Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-//
-// Neither the name of 3Dlabs Inc. Ltd. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-//THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-//"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-//LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
-//FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
-//COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
-//INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
-//BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
-//LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
-//CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-//LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
-//ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
-//POSSIBILITY OF SUCH DAMAGE.
-//
-
-//
-// Symbol table for parsing. Most functionaliy and main ideas
-// are documented in the header file.
-//
-
-#include "SymbolTable.h"
-
-//
-// TType helper function needs a place to live.
-//
-
-//
-// Recursively generate mangled names.
-//
-void TType::buildMangledName(TString& mangledName)
-{
- if (isMatrix())
- mangledName += 'm';
- else if (isVector())
- mangledName += 'v';
-
- switch (type) {
- case EbtFloat: mangledName += 'f'; break;
- case EbtInt: mangledName += 'i'; break;
- case EbtBool: mangledName += 'b'; break;
- case EbtSampler1D: mangledName += "s1"; break;
- case EbtSampler2D: mangledName += "s2"; break;
- case EbtSampler3D: mangledName += "s3"; break;
- case EbtSamplerCube: mangledName += "sC"; break;
- case EbtSampler1DShadow: mangledName += "sS1"; break;
- case EbtSampler2DShadow: mangledName += "sS2"; break;
- case EbtStruct:
- mangledName += "struct-";
- if (typeName)
- mangledName += *typeName;
- {// support MSVC++6.0
- for (unsigned int i = 0; i < structure->size(); ++i) {
- mangledName += '-';
- (*structure)[i].type->buildMangledName(mangledName);
- }
- }
- default:
- break;
- }
-
- mangledName += static_cast<char>('0' + getNominalSize());
- if (isArray()) {
- char buf[10];
- sprintf(buf, "%d", arraySize);
- mangledName += '[';
- mangledName += buf;
- mangledName += ']';
- }
-}
-
-//
-// Dump functions.
-//
-
-void TVariable::dump(TInfoSink& infoSink) const
-{
- infoSink.debug << getName().c_str() << ": " << type.getQualifierString() << " " << type.getBasicString();
- if (type.isArray()) {
- infoSink.debug << "[0]";
- }
- infoSink.debug << "\n";
-}
-
-void TFunction::dump(TInfoSink &infoSink) const
-{
- infoSink.debug << getName().c_str() << ": " << returnType.getBasicString() << " " << getMangledName().c_str() << "\n";
-}
-
-void TSymbolTableLevel::dump(TInfoSink &infoSink) const
-{
- tLevel::const_iterator it;
- for (it = level.begin(); it != level.end(); ++it)
- (*it).second->dump(infoSink);
-}
-
-void TSymbolTable::dump(TInfoSink &infoSink) const
-{
- for (int level = currentLevel(); level >= 0; --level) {
- infoSink.debug << "LEVEL " << level << "\n";
- table[level]->dump(infoSink);
- }
-}
-
-//
-// Functions have buried pointers to delete.
-//
-TFunction::~TFunction()
-{
- for (TParamList::iterator i = parameters.begin(); i != parameters.end(); ++i)
- delete (*i).type;
-}
-
-//
-// Symbol table levels are a map of pointers to symbols that have to be deleted.
-//
-TSymbolTableLevel::~TSymbolTableLevel()
-{
- for (tLevel::iterator it = level.begin(); it != level.end(); ++it)
- delete (*it).second;
-}
-
-//
-// Change all function entries in the table with the non-mangled name
-// to be related to the provided built-in operation. This is a low
-// performance operation, and only intended for symbol tables that
-// live across a large number of compiles.
-//
-void TSymbolTableLevel::relateToOperator(const char* name, TOperator op)
-{
- tLevel::iterator it;
- for (it = level.begin(); it != level.end(); ++it) {
- if ((*it).second->isFunction()) {
- TFunction* function = static_cast<TFunction*>((*it).second);
- if (function->getName() == name)
- function->relateToOperator(op);
- }
- }
-}
-
-
-TSymbol::TSymbol(const TSymbol& copyOf)
-{
- name = NewPoolTString(copyOf.name->c_str());
- uniqueId = copyOf.uniqueId;
-}
-
-TVariable::TVariable(const TVariable& copyOf, TStructureMap& remapper) : TSymbol(copyOf)
-{
- type.copyType(copyOf.type, remapper);
- userType = copyOf.userType;
- // for builtIn symbol table level, unionArray and arrayInformation pointers should be NULL
- assert(copyOf.arrayInformationType == 0);
- arrayInformationType = 0;
-
- if (copyOf.unionArray) {
- assert(!copyOf.type.getStruct());
- assert(copyOf.type.getInstanceSize() == 1);
- unionArray = new constUnion[1];
- switch (type.getBasicType()) {
- case EbtFloat: unionArray[0].fConst = copyOf.unionArray[0].fConst; break;
- case EbtInt: unionArray[0].iConst = copyOf.unionArray[0].iConst; break;
- case EbtBool: unionArray[0].bConst = copyOf.unionArray[0].bConst; break;
- default:
- assert (false && "Unknown type");
- }
- } else
- unionArray = 0;
-}
-
-TVariable* TVariable::clone(TStructureMap& remapper)
-{
- TVariable *variable = new TVariable(*this, remapper);
-
- return variable;
-}
-
-TFunction::TFunction(const TFunction& copyOf, TStructureMap& remapper) : TSymbol(copyOf)
-{
- for (unsigned int i = 0; i < copyOf.parameters.size(); ++i) {
- TParameter param;
- parameters.push_back(param);
- parameters.back().copyParam(copyOf.parameters[i], remapper);
- }
-
- returnType.copyType(copyOf.returnType, remapper);
- mangledName = copyOf.mangledName;
- op = copyOf.op;
- defined = copyOf.defined;
-}
-
-TFunction* TFunction::clone(TStructureMap& remapper)
-{
- TFunction *function = new TFunction(*this, remapper);
-
- return function;
-}
-
-TSymbolTableLevel* TSymbolTableLevel::clone(TStructureMap& remapper)
-{
- TSymbolTableLevel *symTableLevel = new TSymbolTableLevel();
- tLevel::iterator iter;
- for (iter = level.begin(); iter != level.end(); ++iter) {
- symTableLevel->insert(*iter->second->clone(remapper));
- }
-
- return symTableLevel;
-}
-
-void TSymbolTable::copyTable(const TSymbolTable& copyOf)
-{
- TStructureMap remapper;
- uniqueId = copyOf.uniqueId;
- for (unsigned int i = 0; i < copyOf.table.size(); ++i) {
- table.push_back(copyOf.table[i]->clone(remapper));
- }
-}
diff --git a/src/mesa/shader/slang/MachineIndependent/SymbolTable.h b/src/mesa/shader/slang/MachineIndependent/SymbolTable.h deleted file mode 100755 index 7e4ff68247..0000000000 --- a/src/mesa/shader/slang/MachineIndependent/SymbolTable.h +++ /dev/null @@ -1,320 +0,0 @@ -//
-//Copyright (C) 2002-2005 3Dlabs Inc. Ltd.
-//All rights reserved.
-//
-//Redistribution and use in source and binary forms, with or without
-//modification, are permitted provided that the following conditions
-//are met:
-//
-// Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//
-// Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-//
-// Neither the name of 3Dlabs Inc. Ltd. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-//THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-//"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-//LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
-//FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
-//COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
-//INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
-//BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
-//LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
-//CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-//LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
-//ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
-//POSSIBILITY OF SUCH DAMAGE.
-//
-
-#ifndef _SYMBOL_TABLE_INCLUDED_
-#define _SYMBOL_TABLE_INCLUDED_
-
-//
-// Symbol table for parsing. Has these design characteristics:
-//
-// * Same symbol table can be used to compile many shaders, to preserve
-// effort of creating and loading with the large numbers of built-in
-// symbols.
-//
-// * Name mangling will be used to give each function a unique name
-// so that symbol table lookups are never ambiguous. This allows
-// a simpler symbol table structure.
-//
-// * Pushing and popping of scope, so symbol table will really be a stack
-// of symbol tables. Searched from the top, with new inserts going into
-// the top.
-//
-// * Constants: Compile time constant symbols will keep their values
-// in the symbol table. The parser can substitute constants at parse
-// time, including doing constant folding and constant propagation.
-//
-// * No temporaries: Temporaries made from operations (+, --, .xy, etc.)
-// are tracked in the intermediate representation, not the symbol table.
-//
-
-#include "Include/Common.h"
-#include "Include/intermediate.h"
-#include "Include/InfoSink.h"
-
-//
-// Symbol base class. (Can build functions or variables out of these...)
-//
-class TSymbol {
-public:
- POOL_ALLOCATOR_NEW_DELETE(GlobalPoolAllocator)
- TSymbol(const TString *n) : name(n) { }
- virtual ~TSymbol() { /* don't delete name, it's from the pool */ }
- const TString& getName() const { return *name; }
- virtual const TString& getMangledName() const { return getName(); }
- virtual bool isFunction() const { return false; }
- virtual bool isVariable() const { return false; }
- void setUniqueId(int id) { uniqueId = id; }
- int getUniqueId() const { return uniqueId; }
- virtual void dump(TInfoSink &infoSink) const = 0;
- TSymbol(const TSymbol&);
- virtual TSymbol* clone(TStructureMap& remapper) = 0;
-
-protected:
- const TString *name;
- unsigned int uniqueId; // For real comparing during code generation
-};
-
-//
-// Variable class, meaning a symbol that's not a function.
-//
-// There could be a separate class heirarchy for Constant variables;
-// Only one of int, bool, or float, (or none) is correct for
-// any particular use, but it's easy to do this way, and doesn't
-// seem worth having separate classes, and "getConst" can't simply return
-// different values for different types polymorphically, so this is
-// just simple and pragmatic.
-//
-class TVariable : public TSymbol {
-public:
- TVariable(const TString *name, const TType& t, bool uT = false ) : TSymbol(name), type(t), userType(uT), unionArray(0), arrayInformationType(0) { }
- virtual ~TVariable() { }
- virtual bool isVariable() const { return true; }
- TType& getType() { return type; }
- const TType& getType() const { return type; }
- bool isUserType() const { return userType; }
- void changeQualifier(TQualifier qualifier) { type.changeQualifier(qualifier); }
- void updateArrayInformationType(TType *t) { arrayInformationType = t; }
- TType* getArrayInformationType() { return arrayInformationType; }
-
- virtual void dump(TInfoSink &infoSink) const;
-
- constUnion* getConstPointer() {
- if (!unionArray) {
- if (!type.getStruct())
- unionArray = new constUnion[type.getInstanceSize()];
- else
- unionArray = new constUnion[type.getStructSize()];
- }
- return unionArray;
- }
-
- constUnion* getConstPointer() const { return unionArray; }
-
- void shareConstPointer( constUnion *constArray)
- {
- delete unionArray;
- unionArray = constArray;
- }
- TVariable(const TVariable&, TStructureMap& remapper); // copy constructor
- virtual TVariable* clone(TStructureMap& remapper);
-
-protected:
- TType type;
- bool userType;
- // we are assuming that Pool Allocator will free the memory allocated to unionArray
- // when this object is destroyed
- constUnion *unionArray;
- TType *arrayInformationType; // this is used for updating maxArraySize in all the references to a given symbol
-};
-
-//
-// The function sub-class of symbols and the parser will need to
-// share this definition of a function parameter.
-//
-struct TParameter {
- TString *name;
- TType* type;
- void copyParam(const TParameter& param, TStructureMap& remapper) {
- name = NewPoolTString(param.name->c_str());
- type = param.type->clone(remapper);
- }
-};
-
-//
-// The function sub-class of a symbol.
-//
-class TFunction : public TSymbol {
-public:
- TFunction(TOperator o) :
- TSymbol(0),
- returnType(TType(EbtVoid)),
- op(o),
- defined(false) { }
- TFunction(const TString *name, TType& retType, TOperator tOp = EOpNull) :
- TSymbol(name),
- returnType(retType),
- mangledName(*name + '('),
- op(tOp),
- defined(false) { }
- virtual ~TFunction();
- virtual bool isFunction() const { return true; }
-
- void addParameter(TParameter& p)
- {
- parameters.push_back(p);
- mangledName = mangledName + p.type->getMangledName();
- }
-
- const TString& getMangledName() const { return mangledName; }
- const TType& getReturnType() const { return returnType; }
- void relateToOperator(TOperator o) { op = o; }
- TOperator getBuiltInOp() const { return op; }
- void setDefined() { defined = true; }
- bool isDefined() { return defined; }
-
- int getParamCount() const { return static_cast<int>(parameters.size()); }
- TParameter& operator [](int i) { return parameters[i]; }
- const TParameter& operator [](int i) const { return parameters[i]; }
-
- virtual void dump(TInfoSink &infoSink) const;
- TFunction(const TFunction&, TStructureMap& remapper);
- virtual TFunction* clone(TStructureMap& remapper);
-
-protected:
- typedef TVector<TParameter> TParamList;
- TParamList parameters;
- TType returnType;
- TString mangledName;
- TOperator op;
- bool defined;
-};
-
-
-class TSymbolTableLevel {
-public:
- POOL_ALLOCATOR_NEW_DELETE(GlobalPoolAllocator)
- TSymbolTableLevel() { }
- ~TSymbolTableLevel();
-
- bool insert(TSymbol& symbol)
- {
- //
- // returning true means symbol was added to the table
- //
- tInsertResult result;
- result = level.insert(tLevelPair(symbol.getMangledName(), &symbol));
-
- return result.second;
- }
-
- TSymbol* find(const TString& name) const
- {
- tLevel::const_iterator it = level.find(name);
- if (it == level.end())
- return 0;
- else
- return (*it).second;
- }
-
- void relateToOperator(const char* name, TOperator op);
- void dump(TInfoSink &infoSink) const;
- TSymbolTableLevel* clone(TStructureMap& remapper);
-
-protected:
- typedef std::map<TString, TSymbol*, std::less<TString>, pool_allocator<std::pair<const TString, TSymbol*> > > tLevel;
- typedef const tLevel::value_type tLevelPair;
- typedef std::pair<tLevel::iterator, bool> tInsertResult;
-
- tLevel level;
-};
-
-class TSymbolTable {
-public:
- TSymbolTable() : uniqueId(0)
- {
- //
- // The symbol table cannot be used until push() is called, but
- // the lack of an initial call to push() can be used to detect
- // that the symbol table has not been preloaded with built-ins.
- //
- }
-
- TSymbolTable(TSymbolTable& symTable)
- {
- table.push_back(symTable.table[0]);
- uniqueId = symTable.uniqueId;
- }
-
- ~TSymbolTable()
- {
- // level 0 is always built In symbols, so we never pop that out
- while (table.size() > 1)
- pop();
- }
-
- //
- // When the symbol table is initialized with the built-ins, there should
- // 'push' calls, so that built-ins are at level 0 and the shader
- // globals are at level 1.
- //
- bool isEmpty() { return table.size() == 0; }
- bool atBuiltInLevel() { return atSharedBuiltInLevel() || atDynamicBuiltInLevel(); }
- bool atSharedBuiltInLevel() { return table.size() == 1; }
- bool atGlobalLevel() { return table.size() <= 3; }
- void push() {
- table.push_back(new TSymbolTableLevel);
- }
-
- void pop() {
- delete table[currentLevel()];
- table.pop_back();
- }
-
- bool insert(TSymbol& symbol)
- {
- symbol.setUniqueId(++uniqueId);
- return table[currentLevel()]->insert(symbol);
- }
-
- TSymbol* find(const TString& name, bool* builtIn = 0, bool *sameScope = 0)
- {
- int level = currentLevel();
- TSymbol* symbol;
- do {
- symbol = table[level]->find(name);
- --level;
- } while (symbol == 0 && level >= 0);
- level++;
- if (builtIn)
- *builtIn = level == 0;
- if (sameScope)
- *sameScope = level == currentLevel();
- return symbol;
- }
-
- TSymbolTableLevel* getGlobalLevel() { assert (table.size() >= 3); return table[2]; }
- void relateToOperator(const char* name, TOperator op) { table[0]->relateToOperator(name, op); }
- int getMaxSymbolId() { return uniqueId; }
- void dump(TInfoSink &infoSink) const;
- void copyTable(const TSymbolTable& copyOf);
-
-protected:
- int currentLevel() const { return static_cast<int>(table.size()) - 1; }
- bool atDynamicBuiltInLevel() { return table.size() == 2; }
-
- std::vector<TSymbolTableLevel*> table;
- int uniqueId; // for unique identification in code generation
-};
-
-#endif // _SYMBOL_TABLE_INCLUDED_
diff --git a/src/mesa/shader/slang/MachineIndependent/glslang.l b/src/mesa/shader/slang/MachineIndependent/glslang.l deleted file mode 100644 index f6cd3ca663..0000000000 --- a/src/mesa/shader/slang/MachineIndependent/glslang.l +++ /dev/null @@ -1,614 +0,0 @@ -/*
-//
-//Copyright (C) 2002-2005 3Dlabs Inc. Ltd.
-//All rights reserved.
-//
-//Redistribution and use in source and binary forms, with or without
-//modification, are permitted provided that the following conditions
-//are met:
-//
-// Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//
-// Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-//
-// Neither the name of 3Dlabs Inc. Ltd. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-//THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-//"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-//LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
-//FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
-//COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
-//INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
-//BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
-//LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
-//CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-//LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
-//ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
-//POSSIBILITY OF SUCH DAMAGE.
-//
-*/
-/* Based on
-ANSI C grammar, Lex specification
-
-In 1985, Jeff Lee published this Lex specification together with a Yacc
-grammar for the April 30, 1985 ANSI C draft. Tom Stockfisch reposted
-both to net.sources in 1987; that original, as mentioned in the answer
-to question 17.25 of the comp.lang.c FAQ, can be ftp'ed from ftp.uu.net,
-file usenet/net.sources/ansi.c.grammar.Z.
-
-I intend to keep this version as close to the current C Standard grammar
-as possible; please let me know if you discover discrepancies.
-
-Jutta Degener, 1995
-*/
-
-D [0-9]
-L [a-zA-Z_]
-H [a-fA-F0-9]
-E [Ee][+-]?{D}+
-O [0-7]
-
-%option nounput
-%{
-#include <stdio.h>
-#include <stdlib.h>
-#include "ParseHelper.h"
-#include "glslang_tab.h"
-
-/* windows only pragma */
-#ifdef _MSC_VER
-#pragma warning(disable : 4102)
-#endif
-
-int yy_input(char* buf, int max_size);
-TSourceLoc yylineno;
-
-#ifdef _WIN32
- extern int yyparse(TParseContext&);
- #define YY_DECL int yylex(YYSTYPE* pyylval, TParseContext& parseContext)
-#else
- extern int yyparse(void*);
- #define YY_DECL int yylex(YYSTYPE* pyylval, void* parseContextLocal)
- #define parseContext (*((TParseContext*)(parseContextLocal)))
-#endif
-
-#define YY_INPUT(buf,result,max_size) (result = yy_input(buf, max_size))
-
-%}
-
-%option noyywrap
-%option never-interactive
-%option outfile="Gen_glslang.cpp"
-%x FIELDS
-
-
-%%
-<*>"//"[^\n]*"\n" { /* ?? carriage and/or line-feed? */ };
-
-"attribute" { pyylval->lex.line = yylineno; return(ATTRIBUTE); }
-"const" { pyylval->lex.line = yylineno; return(CONST_QUAL); }
-"uniform" { pyylval->lex.line = yylineno; return(UNIFORM); }
-"varying" { pyylval->lex.line = yylineno; return(VARYING); }
-
-"break" { pyylval->lex.line = yylineno; return(BREAK); }
-"continue" { pyylval->lex.line = yylineno; return(CONTINUE); }
-"do" { pyylval->lex.line = yylineno; return(DO); }
-"for" { pyylval->lex.line = yylineno; return(FOR); }
-"while" { pyylval->lex.line = yylineno; return(WHILE); }
-
-"if" { pyylval->lex.line = yylineno; return(IF); }
-"else" { pyylval->lex.line = yylineno; return(ELSE); }
-
-"in" { pyylval->lex.line = yylineno; return(IN_QUAL); }
-"out" { pyylval->lex.line = yylineno; return(OUT_QUAL); }
-"inout" { pyylval->lex.line = yylineno; return(INOUT_QUAL); }
-
-"float" { pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return(FLOAT_TYPE); }
-"int" { pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return(INT_TYPE); }
-"void" { pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return(VOID_TYPE); }
-"bool" { pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return(BOOL_TYPE); }
-"true" { pyylval->lex.line = yylineno; pyylval->lex.b = true; return(BOOLCONSTANT); }
-"false" { pyylval->lex.line = yylineno; pyylval->lex.b = false; return(BOOLCONSTANT); }
-
-"discard" { pyylval->lex.line = yylineno; return(DISCARD); }
-"return" { pyylval->lex.line = yylineno; return(RETURN); }
-
-"mat2" { pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return(MATRIX2); }
-"mat3" { pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return(MATRIX3); }
-"mat4" { pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return(MATRIX4); }
-
-"vec2" { pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return (VEC2); }
-"vec3" { pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return (VEC3); }
-"vec4" { pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return (VEC4); }
-"ivec2" { pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return (IVEC2); }
-"ivec3" { pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return (IVEC3); }
-"ivec4" { pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return (IVEC4); }
-"bvec2" { pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return (BVEC2); }
-"bvec3" { pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return (BVEC3); }
-"bvec4" { pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return (BVEC4); }
-
-"sampler1D" { pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return SAMPLER1D; }
-"sampler2D" { pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return SAMPLER2D; }
-"sampler3D" { pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return SAMPLER3D; }
-"samplerCube" { pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return SAMPLERCUBE; }
-"sampler1DShadow" { pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return SAMPLER1DSHADOW; }
-"sampler2DShadow" { pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return SAMPLER2DSHADOW; }
-
-"struct" { pyylval->lex.line = yylineno; return(STRUCT); }
-
-"asm" { PaReservedWord(); return 0; }
-
-"class" { PaReservedWord(); return 0; }
-"union" { PaReservedWord(); return 0; }
-"enum" { PaReservedWord(); return 0; }
-"typedef" { PaReservedWord(); return 0; }
-"template" { PaReservedWord(); return 0; }
-"this" { PaReservedWord(); return 0; }
-"packed" { PaReservedWord(); return 0; }
-
-"goto" { PaReservedWord(); return 0; }
-"switch" { PaReservedWord(); return 0; }
-"default" { PaReservedWord(); return 0; }
-
-"inline" { PaReservedWord(); return 0; }
-"noinline" { PaReservedWord(); return 0; }
-"volatile" { PaReservedWord(); return 0; }
-"public" { PaReservedWord(); return 0; }
-"static" { PaReservedWord(); return 0; }
-"extern" { PaReservedWord(); return 0; }
-"external" { PaReservedWord(); return 0; }
-"interface" { PaReservedWord(); return 0; }
-
-"long" { PaReservedWord(); return 0; }
-"short" { PaReservedWord(); return 0; }
-"double" { PaReservedWord(); return 0; }
-"half" { PaReservedWord(); return 0; }
-"fixed" { PaReservedWord(); return 0; }
-"unsigned" { PaReservedWord(); return 0; }
-
-"input" { PaReservedWord(); return 0; }
-"output" { PaReservedWord(); return 0; }
-
-"hvec2" { PaReservedWord(); return 0; }
-"hvec3" { PaReservedWord(); return 0; }
-"hvec4" { PaReservedWord(); return 0; }
-"fvec2" { PaReservedWord(); return 0; }
-"fvec3" { PaReservedWord(); return 0; }
-"fvec4" { PaReservedWord(); return 0; }
-"dvec2" { PaReservedWord(); return 0; }
-"dvec3" { PaReservedWord(); return 0; }
-"dvec4" { PaReservedWord(); return 0; }
-
-"sampler2DRect" { PaReservedWord(); return 0; }
-"sampler3DRect" { PaReservedWord(); return 0; }
-"sampler2DRectShadow" { PaReservedWord(); return 0; }
-
-"sizeof" { PaReservedWord(); return 0; }
-"cast" { PaReservedWord(); return 0; }
-
-"namespace" { PaReservedWord(); return 0; }
-"using" { PaReservedWord(); return 0; }
-
-{L}({L}|{D})* {
- pyylval->lex.line = yylineno;
- pyylval->lex.string = NewPoolTString(yytext);
- return PaIdentOrType(*pyylval->lex.string, parseContext, pyylval->lex.symbol);
-}
-
-0[xX]{H}+ { pyylval->lex.line = yylineno; pyylval->lex.i = strtol(yytext, 0, 0); return(INTCONSTANT); }
-0{O}+ { pyylval->lex.line = yylineno; pyylval->lex.i = strtol(yytext, 0, 0); return(INTCONSTANT); }
-0{D}+ { pyylval->lex.line = yylineno; parseContext.error(yylineno, "Invalid Octal number.", yytext, "", ""); parseContext.recover(); return 0;}
-{D}+ { pyylval->lex.line = yylineno; pyylval->lex.i = strtol(yytext, 0, 0); return(INTCONSTANT); }
-
-{D}+{E} { pyylval->lex.line = yylineno; pyylval->lex.f = static_cast<float>(atof(yytext)); return(FLOATCONSTANT); }
-{D}+"."{D}*({E})? { pyylval->lex.line = yylineno; pyylval->lex.f = static_cast<float>(atof(yytext)); return(FLOATCONSTANT); }
-"."{D}+({E})? { pyylval->lex.line = yylineno; pyylval->lex.f = static_cast<float>(atof(yytext)); return(FLOATCONSTANT); }
-
-"/*" { int ret = PaParseComment(pyylval->lex.line, parseContext); if (!ret) return ret; }
-
-"+=" { pyylval->lex.line = yylineno; return(ADD_ASSIGN); }
-"-=" { pyylval->lex.line = yylineno; return(SUB_ASSIGN); }
-"*=" { pyylval->lex.line = yylineno; return(MUL_ASSIGN); }
-"/=" { pyylval->lex.line = yylineno; return(DIV_ASSIGN); }
-"%=" { pyylval->lex.line = yylineno; return(MOD_ASSIGN); }
-"<<=" { pyylval->lex.line = yylineno; return(LEFT_ASSIGN); }
-">>=" { pyylval->lex.line = yylineno; return(RIGHT_ASSIGN); }
-"&=" { pyylval->lex.line = yylineno; return(AND_ASSIGN); }
-"^=" { pyylval->lex.line = yylineno; return(XOR_ASSIGN); }
-"|=" { pyylval->lex.line = yylineno; return(OR_ASSIGN); }
-
-"++" { pyylval->lex.line = yylineno; return(INC_OP); }
-"--" { pyylval->lex.line = yylineno; return(DEC_OP); }
-"&&" { pyylval->lex.line = yylineno; return(AND_OP); }
-"||" { pyylval->lex.line = yylineno; return(OR_OP); }
-"^^" { pyylval->lex.line = yylineno; return(XOR_OP); }
-"<=" { pyylval->lex.line = yylineno; return(LE_OP); }
-">=" { pyylval->lex.line = yylineno; return(GE_OP); }
-"==" { pyylval->lex.line = yylineno; return(EQ_OP); }
-"!=" { pyylval->lex.line = yylineno; return(NE_OP); }
-"<<" { pyylval->lex.line = yylineno; return(LEFT_OP); }
-">>" { pyylval->lex.line = yylineno; return(RIGHT_OP); }
-";" { pyylval->lex.line = yylineno; parseContext.lexAfterType = false; return(SEMICOLON); }
-("{"|"<%") { pyylval->lex.line = yylineno; parseContext.lexAfterType = false; return(LEFT_BRACE); }
-("}"|"%>") { pyylval->lex.line = yylineno; return(RIGHT_BRACE); }
-"," { pyylval->lex.line = yylineno; if (parseContext.inTypeParen) parseContext.lexAfterType = false; return(COMMA); }
-":" { pyylval->lex.line = yylineno; return(COLON); }
-"=" { pyylval->lex.line = yylineno; parseContext.lexAfterType = false; return(EQUAL); }
-"(" { pyylval->lex.line = yylineno; parseContext.lexAfterType = false; parseContext.inTypeParen = true; return(LEFT_PAREN); }
-")" { pyylval->lex.line = yylineno; parseContext.inTypeParen = false; return(RIGHT_PAREN); }
-("["|"<:") { pyylval->lex.line = yylineno; return(LEFT_BRACKET); }
-("]"|":>") { pyylval->lex.line = yylineno; return(RIGHT_BRACKET); }
-"." { BEGIN(FIELDS); return(DOT); }
-"!" { pyylval->lex.line = yylineno; return(BANG); }
-"-" { pyylval->lex.line = yylineno; return(DASH); }
-"~" { pyylval->lex.line = yylineno; return(TILDE); }
-"+" { pyylval->lex.line = yylineno; return(PLUS); }
-"*" { pyylval->lex.line = yylineno; return(STAR); }
-"/" { pyylval->lex.line = yylineno; return(SLASH); }
-"%" { pyylval->lex.line = yylineno; return(PERCENT); }
-"<" { pyylval->lex.line = yylineno; return(LEFT_ANGLE); }
-">" { pyylval->lex.line = yylineno; return(RIGHT_ANGLE); }
-"|" { pyylval->lex.line = yylineno; return(VERTICAL_BAR); }
-"^" { pyylval->lex.line = yylineno; return(CARET); }
-"&" { pyylval->lex.line = yylineno; return(AMPERSAND); }
-"?" { pyylval->lex.line = yylineno; return(QUESTION); }
-
-<FIELDS>{L}({L}|{D})* {
-BEGIN(INITIAL);
- pyylval->lex.line = yylineno;
- pyylval->lex.string = NewPoolTString(yytext);
- return FIELD_SELECTION; }
-<FIELDS>[ \t\v\f\r] {}
-
-[ \t\v\n\f\r] { }
-<*><<EOF>> { (&parseContext)->AfterEOF = true; yy_delete_buffer(YY_CURRENT_BUFFER); yyterminate();}
-<*>. { parseContext.infoSink.info << "FLEX: Unknown char " << yytext << "\n";
- return 0; }
-
-%%
-
-
-//Including Pre-processor.
-extern "C" {
- #include "./preprocessor/preprocess.h"
-}
-
-//
-// The YY_INPUT macro just calls this. Maybe this could be just put into
-// the macro directly.
-//
-
-int yy_input(char* buf, int max_size)
-{
- char *char_token =NULL;
- int len;
-
- if ((len = yylex_CPP(buf, max_size)) == 0)
- return 0;
- if (len >= max_size)
- YY_FATAL_ERROR( "input buffer overflow, can't enlarge buffer because scanner uses REJECT" );
-
- buf[len] = ' ';
- return len+1;
-}
-
-
-//
-// Parse an array of strings using yyparse. We set up globals used by
-// yywrap.
-//
-// Returns 0 for success, as per yyparse().
-//
-int PaParseStrings(char* argv[], int strLen[], int argc, TParseContext& parseContextLocal)
-{
- int argv0len;
- ScanFromString(argv[0]);
-
- //Storing the Current Compiler Parse context into the cpp structure.
- cpp->pC = (void*)&parseContextLocal;
-
- if (!argv || argc == 0 || !argv[0])
- return 1;
-
- if (!strLen) {
- argv0len = (int) strlen(argv[0]);
- strLen = &argv0len;
- }
- yyrestart(0);
- (&parseContextLocal)->AfterEOF = false;
- cpp->PaWhichStr = 0;
- cpp->PaArgv = argv;
- cpp->PaArgc = argc;
- cpp->PaStrLen = strLen;
- yylineno = 1;
-
- if (*cpp->PaStrLen >= 0) {
- int ret;
- #ifdef _WIN32
- ret = yyparse(parseContextLocal);
- #else
- ret = yyparse((void*)(&parseContextLocal));
- #endif
- if (cpp->CompileError == 1 || parseContextLocal.recoveredFromError || parseContextLocal.numErrors > 0)
- return 1;
- else
- return 0;
- }
- else
- return 0;
-}
-
-void yyerror(char *s)
-{
- if (((TParseContext *)cpp->pC)->AfterEOF) {
- if (cpp->tokensBeforeEOF == 1) {
- GlobalParseContext->error(yylineno, "syntax error", "pre-mature EOF", s, "");
- GlobalParseContext->recover();
- }
- } else {
- GlobalParseContext->error(yylineno, "syntax error", yytext, s, "");
- GlobalParseContext->recover();
- }
-}
-
-void PaReservedWord()
-{
- GlobalParseContext->error(yylineno, "Reserved word.", yytext, "", "");
- GlobalParseContext->recover();
-}
-
-int PaIdentOrType(TString& id, TParseContext& parseContextLocal, TSymbol*& symbol)
-{
- symbol = parseContextLocal.symbolTable.find(id);
- if (parseContextLocal.lexAfterType == false && symbol && symbol->isVariable()) {
- TVariable* variable = static_cast<TVariable*>(symbol);
- if (variable->isUserType()) {
- parseContextLocal.lexAfterType = true;
- return TYPE_NAME;
- }
- }
-
- return IDENTIFIER;
-}
-
-int PaParseComment(int &lineno, TParseContext& parseContextLocal)
-{
- int transitionFlag = 0;
- int nextChar;
-
- while (transitionFlag != 2) {
- nextChar = yyinput();
- if (nextChar == '\n')
- lineno++;
- switch (nextChar) {
- case '*' :
- transitionFlag = 1;
- break;
- case '/' : /* if star is the previous character, then it is the end of comment */
- if (transitionFlag == 1) {
- return 1 ;
- }
- break;
- case EOF :
- /* Raise error message here */
- parseContextLocal.error(yylineno, "End of shader found before end of comment.", "", "", "");
- GlobalParseContext->recover();
- return YY_NULL;
- default : /* Any other character will be a part of the comment */
- transitionFlag = 0;
- }
- }
- return 1;
-}
-
-extern "C" {
-
-void CPPDebugLogMsg(const char *msg)
-{
- ((TParseContext *)cpp->pC)->infoSink.debug.message(EPrefixNone, msg);
-}
-
-void CPPWarningToInfoLog(const char *msg)
-{
- ((TParseContext *)cpp->pC)->infoSink.info.message(EPrefixWarning, msg, yylineno);
-}
-
-void CPPShInfoLogMsg(const char *msg)
-{
- ((TParseContext *)cpp->pC)->error(yylineno,"", "",msg,"");
- GlobalParseContext->recover();
-}
-
-void CPPErrorToInfoLog(char *msg)
-{
- ((TParseContext *)cpp->pC)->error(yylineno,"syntax error", "",msg,"");
- GlobalParseContext->recover();
-}
-
-void SetLineNumber(int line)
-{
- yylineno &= ~SourceLocLineMask;
- yylineno |= line;
-}
-
-void SetStringNumber(int string)
-{
- yylineno = (string << SourceLocStringShift) | (yylineno & SourceLocLineMask);
-}
-
-int GetStringNumber(void)
-{
- return yylineno >> 16;
-}
-
-int GetLineNumber(void)
-{
- return yylineno & SourceLocLineMask;
-}
-
-void IncLineNumber(void)
-{
- if ((yylineno & SourceLocLineMask) <= SourceLocLineMask)
- ++yylineno;
-}
-
-void DecLineNumber(void)
-{
- if ((yylineno & SourceLocLineMask) > 0)
- --yylineno;
-}
-
-void HandlePragma(const char **tokens, int numTokens)
-{
- if (!strcmp(tokens[0], "optimize")) {
- if (numTokens != 4) {
- CPPShInfoLogMsg("optimize pragma syntax is incorrect");
- return;
- }
-
- if (strcmp(tokens[1], "(")) {
- CPPShInfoLogMsg("\"(\" expected after 'optimize' keyword");
- return;
- }
-
- if (!strcmp(tokens[2], "on"))
- ((TParseContext *)cpp->pC)->contextPragma.optimize = true;
- else if (!strcmp(tokens[2], "off"))
- ((TParseContext *)cpp->pC)->contextPragma.optimize = false;
- else {
- CPPShInfoLogMsg("\"on\" or \"off\" expected after '(' for 'optimize' pragma");
- return;
- }
-
- if (strcmp(tokens[3], ")")) {
- CPPShInfoLogMsg("\")\" expected to end 'optimize' pragma");
- return;
- }
- } else if (!strcmp(tokens[0], "debug")) {
- if (numTokens != 4) {
- CPPShInfoLogMsg("debug pragma syntax is incorrect");
- return;
- }
-
- if (strcmp(tokens[1], "(")) {
- CPPShInfoLogMsg("\"(\" expected after 'debug' keyword");
- return;
- }
-
- if (!strcmp(tokens[2], "on"))
- ((TParseContext *)cpp->pC)->contextPragma.debug = true;
- else if (!strcmp(tokens[2], "off"))
- ((TParseContext *)cpp->pC)->contextPragma.debug = false;
- else {
- CPPShInfoLogMsg("\"on\" or \"off\" expected after '(' for 'debug' pragma");
- return;
- }
-
- if (strcmp(tokens[3], ")")) {
- CPPShInfoLogMsg("\")\" expected to end 'debug' pragma");
- return;
- }
- } else {
- /*
- // implementation specific pragma
- // use ((TParseContext *)cpp->pC)->contextPragma.pragmaTable to store the information about pragma
- // For now, just ignore the pragma that the implementation cannot recognize
- // An Example of one such implementation for a pragma that has a syntax like
- // #pragma pragmaname(pragmavalue)
- // This implementation stores the current pragmavalue against the pragma name in pragmaTable.
- if (numTokens == 4 && !strcmp(tokens[1], "(") && !strcmp(tokens[3], ")")) {
- TPragmaTable& pragmaTable = ((TParseContext *)cpp->pC)->contextPragma.pragmaTable;
- TPragmaTable::iterator iter;
- iter = pragmaTable.find(TString(tokens[0]));
- if (iter != pragmaTable.end()) {
- iter->second = tokens[2];
- } else {
- pragmaTable[tokens[0]] = tokens[2];
- }
- }
- */
- }
-}
-
-void StoreStr(char *string)
-{
- TString strSrc;
- strSrc = TString(string);
-
- ((TParseContext *)cpp->pC)->HashErrMsg = ((TParseContext *)cpp->pC)->HashErrMsg + " " + strSrc;
-}
-
-const char* GetStrfromTStr(void)
-{
- cpp->ErrMsg = (((TParseContext *)cpp->pC)->HashErrMsg).c_str();
- return cpp->ErrMsg;
-}
-
-void ResetTString(void)
-{
- ((TParseContext *)cpp->pC)->HashErrMsg = "";
-}
-
-TBehavior GetBehavior(const char* behavior)
-{
- if (!strcmp("require", behavior))
- return EBhRequire;
- else if (!strcmp("enable", behavior))
- return EBhEnable;
- else if (!strcmp("disable", behavior))
- return EBhDisable;
- else if (!strcmp("warn", behavior))
- return EBhWarn;
- else {
- CPPShInfoLogMsg((TString("behavior '") + behavior + "' is not supported").c_str());
- return EBhDisable;
- }
-}
-
-void updateExtensionBehavior(const char* extName, const char* behavior)
-{
- TBehavior behaviorVal = GetBehavior(behavior);
- TMap<TString, TBehavior>:: iterator iter;
- TString msg;
-
- // special cased for all extension
- if (!strcmp(extName, "all")) {
- if (behaviorVal == EBhRequire || behaviorVal == EBhEnable) {
- CPPShInfoLogMsg("extension 'all' cannot have 'require' or 'enable' behavior");
- return;
- } else {
- for (iter = ((TParseContext *)cpp->pC)->extensionBehavior.begin(); iter != ((TParseContext *)cpp->pC)->extensionBehavior.end(); ++iter)
- iter->second = behaviorVal;
- }
- } else {
- iter = ((TParseContext *)cpp->pC)->extensionBehavior.find(TString(extName));
- if (iter == ((TParseContext *)cpp->pC)->extensionBehavior.end()) {
- switch (behaviorVal) {
- case EBhRequire:
- CPPShInfoLogMsg((TString("extension '") + extName + "' is not supported").c_str());
- break;
- case EBhEnable:
- case EBhWarn:
- case EBhDisable:
- msg = TString("extension '") + extName + "' is not supported";
- ((TParseContext *)cpp->pC)->infoSink.info.message(EPrefixWarning, msg.c_str(), yylineno);
- break;
- }
- return;
- } else
- iter->second = behaviorVal;
- }
-}
-
-}
-
-void setInitialState()
-{
- yy_start = 1;
-}
diff --git a/src/mesa/shader/slang/MachineIndependent/glslang.y b/src/mesa/shader/slang/MachineIndependent/glslang.y deleted file mode 100644 index d2dc1db376..0000000000 --- a/src/mesa/shader/slang/MachineIndependent/glslang.y +++ /dev/null @@ -1,2009 +0,0 @@ -//
-//Copyright (C) 2002-2005 3Dlabs Inc. Ltd.
-//All rights reserved.
-//
-//Redistribution and use in source and binary forms, with or without
-//modification, are permitted provided that the following conditions
-//are met:
-//
-// Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//
-// Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-//
-// Neither the name of 3Dlabs Inc. Ltd. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-//THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-//"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-//LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
-//FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
-//COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
-//INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
-//BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
-//LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
-//CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-//LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
-//ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
-//POSSIBILITY OF SUCH DAMAGE.
-//
-
-/**
- * This is bison grammar and production code for parsing the OpenGL 2.0 shading
- * languages.
- */
-%{
-
-/* Based on:
-ANSI C Yacc grammar
-
-In 1985, Jeff Lee published his Yacc grammar (which is accompanied by a
-matching Lex specification) for the April 30, 1985 draft version of the
-ANSI C standard. Tom Stockfisch reposted it to net.sources in 1987; that
-original, as mentioned in the answer to question 17.25 of the comp.lang.c
-FAQ, can be ftp'ed from ftp.uu.net, file usenet/net.sources/ansi.c.grammar.Z.
-
-I intend to keep this version as close to the current C Standard grammar as
-possible; please let me know if you discover discrepancies.
-
-Jutta Degener, 1995
-*/
-
-#include "SymbolTable.h"
-#include "ParseHelper.h"
-#include "../Public/ShaderLang.h"
-
-#ifdef _WIN32
- #define YYPARSE_PARAM parseContext
- #define YYPARSE_PARAM_DECL TParseContext&
- #define YY_DECL int yylex(YYSTYPE* pyylval, TParseContext& parseContext)
- #define YYLEX_PARAM parseContext
-#else
- #define YYPARSE_PARAM parseContextLocal
- #define parseContext (*((TParseContext*)(parseContextLocal)))
- #define YY_DECL int yylex(YYSTYPE* pyylval, void* parseContextLocal)
- #define YYLEX_PARAM (void*)(parseContextLocal)
- extern void yyerror(char*);
-#endif
-
-#define FRAG_VERT_ONLY(S, L) { \
- if (parseContext.language != EShLangFragment && \
- parseContext.language != EShLangVertex) { \
- parseContext.error(L, " supported in vertex/fragment shaders only ", S, "", ""); \
- parseContext.recover(); \
- } \
-}
-
-#define VERTEX_ONLY(S, L) { \
- if (parseContext.language != EShLangVertex) { \
- parseContext.error(L, " supported in vertex shaders only ", S, "", ""); \
- parseContext.recover(); \
- } \
-}
-
-#define FRAG_ONLY(S, L) { \
- if (parseContext.language != EShLangFragment) { \
- parseContext.error(L, " supported in fragment shaders only ", S, "", ""); \
- parseContext.recover(); \
- } \
-}
-
-#define PACK_ONLY(S, L) { \
- if (parseContext.language != EShLangPack) { \
- parseContext.error(L, " supported in pack shaders only ", S, "", ""); \
- parseContext.recover(); \
- } \
-}
-
-#define UNPACK_ONLY(S, L) { \
- if (parseContext.language != EShLangUnpack) { \
- parseContext.error(L, " supported in unpack shaders only ", S, "", ""); \
- parseContext.recover(); \
- } \
-}
-
-#define PACK_UNPACK_ONLY(S, L) { \
- if (parseContext.language != EShLangUnpack && \
- parseContext.language != EShLangPack) { \
- parseContext.error(L, " supported in pack/unpack shaders only ", S, "", ""); \
- parseContext.recover(); \
- } \
-}
-%}
-%union {
- struct {
- TSourceLoc line;
- union {
- TString *string;
- float f;
- int i;
- bool b;
- };
- TSymbol* symbol;
- } lex;
- struct {
- TSourceLoc line;
- TOperator op;
- union {
- TIntermNode* intermNode;
- TIntermNodePair nodePair;
- TIntermTyped* intermTypedNode;
- TIntermAggregate* intermAggregate;
- };
- union {
- TPublicType type;
- TQualifier qualifier;
- TFunction* function;
- TParameter param;
- TTypeLine typeLine;
- TTypeList* typeList;
- };
- } interm;
-}
-
-%{
-#ifndef _WIN32
- extern int yylex(YYSTYPE*, void*);
-#endif
-%}
-
-%pure_parser /* Just in case is called from multiple threads */
-%expect 1 /* One shift reduce conflict because of if | else */
-%token <lex> ATTRIBUTE CONST_QUAL BOOL_TYPE FLOAT_TYPE INT_TYPE
-%token <lex> BREAK CONTINUE DO ELSE FOR IF DISCARD RETURN
-%token <lex> BVEC2 BVEC3 BVEC4 IVEC2 IVEC3 IVEC4 VEC2 VEC3 VEC4
-%token <lex> MATRIX2 MATRIX3 MATRIX4 IN_QUAL OUT_QUAL INOUT_QUAL UNIFORM VARYING
-%token <lex> STRUCT VOID_TYPE WHILE
-%token <lex> SAMPLER1D SAMPLER2D SAMPLER3D SAMPLERCUBE SAMPLER1DSHADOW SAMPLER2DSHADOW
-
-%token <lex> IDENTIFIER TYPE_NAME FLOATCONSTANT INTCONSTANT BOOLCONSTANT
-%token <lex> FIELD_SELECTION
-%token <lex> LEFT_OP RIGHT_OP
-%token <lex> INC_OP DEC_OP LE_OP GE_OP EQ_OP NE_OP
-%token <lex> AND_OP OR_OP XOR_OP MUL_ASSIGN DIV_ASSIGN ADD_ASSIGN
-%token <lex> MOD_ASSIGN LEFT_ASSIGN RIGHT_ASSIGN AND_ASSIGN XOR_ASSIGN OR_ASSIGN
-%token <lex> SUB_ASSIGN
-
-%token <lex> LEFT_PAREN RIGHT_PAREN LEFT_BRACKET RIGHT_BRACKET LEFT_BRACE RIGHT_BRACE DOT
-%token <lex> COMMA COLON EQUAL SEMICOLON BANG DASH TILDE PLUS STAR SLASH PERCENT
-%token <lex> LEFT_ANGLE RIGHT_ANGLE VERTICAL_BAR CARET AMPERSAND QUESTION
-
-%type <interm> assignment_operator constructor_identifier unary_operator
-%type <interm.intermTypedNode> variable_identifier primary_expression postfix_expression
-%type <interm.intermTypedNode> expression integer_expression assignment_expression
-%type <interm.intermTypedNode> unary_expression multiplicative_expression additive_expression
-%type <interm.intermTypedNode> relational_expression equality_expression
-%type <interm.intermTypedNode> conditional_expression constant_expression
-%type <interm.intermTypedNode> logical_or_expression logical_xor_expression logical_and_expression
-%type <interm.intermTypedNode> shift_expression and_expression exclusive_or_expression inclusive_or_expression
-%type <interm.intermTypedNode> function_call initializer condition conditionopt
-
-%type <interm.intermNode> translation_unit function_definition
-%type <interm.intermNode> statement simple_statement
-%type <interm.intermAggregate> statement_list compound_statement
-%type <interm.intermNode> declaration_statement selection_statement expression_statement
-%type <interm.intermNode> declaration external_declaration
-%type <interm.intermNode> for_init_statement compound_statement_no_new_scope
-%type <interm.nodePair> selection_rest_statement for_rest_statement
-%type <interm.intermNode> iteration_statement jump_statement statement_no_new_scope
-%type <interm> single_declaration init_declarator_list
-
-%type <interm> parameter_declaration parameter_declarator parameter_type_specifier
-%type <interm.qualifier> parameter_qualifier
-
-%type <interm.type> type_qualifier fully_specified_type type_specifier
-%type <interm.type> struct_specifier
-%type <interm.typeLine> struct_declarator
-%type <interm.typeList> struct_declarator_list struct_declaration struct_declaration_list
-%type <interm.function> function_header function_declarator function_identifier
-%type <interm.function> function_header_with_parameters function_call_header
-%type <interm> function_call_header_with_parameters function_call_header_no_parameters function_call_generic function_prototype
-
-%start translation_unit
-%%
-
-variable_identifier
- : IDENTIFIER {
- // The symbol table search was done in the lexical phase
- const TSymbol* symbol = $1.symbol;
- const TVariable* variable;
- if (symbol == 0) {
- parseContext.error($1.line, "undeclared identifier", $1.string->c_str(), "");
- parseContext.recover();
- TType type(EbtFloat);
- TVariable* fakeVariable = new TVariable($1.string, type);
- parseContext.symbolTable.insert(*fakeVariable);
- variable = fakeVariable;
- } else {
- // This identifier can only be a variable type symbol
- if (! symbol->isVariable()) {
- parseContext.error($1.line, "variable expected", $1.string->c_str(), "");
- parseContext.recover();
- }
- variable = static_cast<const TVariable*>(symbol);
- }
-
- // don't delete $1.string, it's used by error recovery, and the pool
- // pop will reclaim the memory
-
- if (variable->getType().getQualifier() == EvqConst ) {
- constUnion* constArray = variable->getConstPointer();
- TType t(variable->getType());
- $$ = parseContext.intermediate.addConstantUnion(constArray, t, $1.line);
- } else
- $$ = parseContext.intermediate.addSymbol(variable->getUniqueId(),
- variable->getName(),
- variable->getType(), $1.line);
- }
- ;
-
-primary_expression
- : variable_identifier {
- $$ = $1;
- }
- | INTCONSTANT {
- //
- // INT_TYPE is only 16-bit plus sign bit for vertex/fragment shaders,
- // check for overflow for constants
- //
- if (abs($1.i) >= (1 << 16)) {
- parseContext.error($1.line, " integer constant overflow", "", "");
- parseContext.recover();
- }
- constUnion *unionArray = new constUnion[1];
- unionArray->iConst = $1.i;
- $$ = parseContext.intermediate.addConstantUnion(unionArray, TType(EbtInt, EvqConst), $1.line);
- }
- | FLOATCONSTANT {
- constUnion *unionArray = new constUnion[1];
- unionArray->fConst = $1.f;
- $$ = parseContext.intermediate.addConstantUnion(unionArray, TType(EbtFloat, EvqConst), $1.line);
- }
- | BOOLCONSTANT {
- constUnion *unionArray = new constUnion[1];
- unionArray->bConst = $1.b;
- $$ = parseContext.intermediate.addConstantUnion(unionArray, TType(EbtBool, EvqConst), $1.line);
- }
- | LEFT_PAREN expression RIGHT_PAREN {
- $$ = $2;
- }
- ;
-
-postfix_expression
- : primary_expression {
- $$ = $1;
- }
- | postfix_expression LEFT_BRACKET integer_expression RIGHT_BRACKET {
- if (!$1->isArray() && !$1->isMatrix() && !$1->isVector()) {
- if ($1->getAsSymbolNode())
- parseContext.error($2.line, " left of '[' is not of type array, matrix, or vector ", $1->getAsSymbolNode()->getSymbol().c_str(), "");
- else
- parseContext.error($2.line, " left of '[' is not of type array, matrix, or vector ", "expression", "");
- parseContext.recover();
- }
- if ($1->getType().getQualifier() == EvqConst && !$1->isArray() && $3->getQualifier() == EvqConst) {
- if ($1->isVector()) { // constant folding for vectors
- TVectorFields fields;
- fields.num = 1;
- fields.offsets[0] = $3->getAsConstantUnion()->getUnionArrayPointer()->iConst; // need to do it this way because v.xy sends fields integer array
- $$ = parseContext.addConstVectorNode(fields, $1, $2.line);
- } else if ($1->isMatrix()) { // constant folding for matrices
- $$ = parseContext.addConstMatrixNode($3->getAsConstantUnion()->getUnionArrayPointer()->iConst, $1, $2.line);
- }
- } else {
- if ($3->getQualifier() == EvqConst) {
- if (($1->isVector() || $1->isMatrix()) && $1->getType().getNominalSize() <= $3->getAsConstantUnion()->getUnionArrayPointer()->iConst && !$1->isArray() ) {
- parseContext.error($2.line, "", "[", "field selection out of range '%d'", $3->getAsConstantUnion()->getUnionArrayPointer()->iConst);
- parseContext.recover();
- } else {
- if ($1->isArray()) {
- if ($1->getType().getArraySize() == 0) {
- if ($1->getType().getMaxArraySize() <= $3->getAsConstantUnion()->getUnionArrayPointer()->iConst) {
- if (parseContext.arraySetMaxSize($1->getAsSymbolNode(), $1->getTypePointer(), $3->getAsConstantUnion()->getUnionArrayPointer()->iConst, true, $2.line))
- parseContext.recover();
- } else {
- if (parseContext.arraySetMaxSize($1->getAsSymbolNode(), $1->getTypePointer(), 0, false, $2.line))
- parseContext.recover();
- }
- } else if ( $3->getAsConstantUnion()->getUnionArrayPointer()->iConst >= $1->getType().getArraySize()) {
- parseContext.error($2.line, "", "[", "array index out of range '%d'", $3->getAsConstantUnion()->getUnionArrayPointer()->iConst);
- parseContext.recover();
- }
- }
- $$ = parseContext.intermediate.addIndex(EOpIndexDirect, $1, $3, $2.line);
- }
- } else {
- if ($1->isArray() && $1->getType().getArraySize() == 0) {
- parseContext.error($2.line, "", "[", "array must be redeclared with a size before being indexed with a variable");
- parseContext.recover();
- }
-
- $$ = parseContext.intermediate.addIndex(EOpIndexIndirect, $1, $3, $2.line);
- }
- }
- if ($$ == 0) {
- constUnion *unionArray = new constUnion[1];
- unionArray->fConst = 0.0;
- $$ = parseContext.intermediate.addConstantUnion(unionArray, TType(EbtFloat, EvqConst), $2.line);
- } else if ($1->isArray()) {
- if ($1->getType().getStruct())
- $$->setType(TType($1->getType().getStruct(), $1->getType().getTypeName()));
- else
- $$->setType(TType($1->getBasicType(), EvqTemporary, $1->getNominalSize(), $1->isMatrix()));
- } else if ($1->isMatrix() && $1->getType().getQualifier() == EvqConst)
- $$->setType(TType($1->getBasicType(), EvqConst, $1->getNominalSize()));
- else if ($1->isMatrix())
- $$->setType(TType($1->getBasicType(), EvqTemporary, $1->getNominalSize()));
- else if ($1->isVector() && $1->getType().getQualifier() == EvqConst)
- $$->setType(TType($1->getBasicType(), EvqConst));
- else if ($1->isVector())
- $$->setType(TType($1->getBasicType(), EvqTemporary));
- else
- $$->setType($1->getType());
- }
- | function_call {
- $$ = $1;
- }
- | postfix_expression DOT FIELD_SELECTION {
- if ($1->isArray()) {
- parseContext.error($3.line, "cannot apply dot operator to an array", ".", "");
- parseContext.recover();
- }
-
- if ($1->isVector()) {
- TVectorFields fields;
- if (! parseContext.parseVectorFields(*$3.string, $1->getNominalSize(), fields, $3.line)) {
- fields.num = 1;
- fields.offsets[0] = 0;
- parseContext.recover();
- }
-
- if ($1->getType().getQualifier() == EvqConst) { // constant folding for vector fields
- $$ = parseContext.addConstVectorNode(fields, $1, $3.line);
- if ($$ == 0) {
- parseContext.recover();
- $$ = $1;
- }
- else
- $$->setType(TType($1->getBasicType(), EvqConst, (int) (*$3.string).size()));
- } else {
- if (fields.num == 1) {
- constUnion *unionArray = new constUnion[1];
- unionArray->iConst = fields.offsets[0];
- TIntermTyped* index = parseContext.intermediate.addConstantUnion(unionArray, TType(EbtInt, EvqConst), $3.line);
- $$ = parseContext.intermediate.addIndex(EOpIndexDirect, $1, index, $2.line);
- $$->setType(TType($1->getBasicType()));
- } else {
- TString vectorString = *$3.string;
- TIntermTyped* index = parseContext.intermediate.addSwizzle(fields, $3.line);
- $$ = parseContext.intermediate.addIndex(EOpVectorSwizzle, $1, index, $2.line);
- $$->setType(TType($1->getBasicType(),EvqTemporary, (int) vectorString.size()));
- }
- }
- } else if ($1->isMatrix()) {
- TMatrixFields fields;
- if (! parseContext.parseMatrixFields(*$3.string, $1->getNominalSize(), fields, $3.line)) {
- fields.wholeRow = false;
- fields.wholeCol = false;
- fields.row = 0;
- fields.col = 0;
- parseContext.recover();
- }
-
- if (fields.wholeRow || fields.wholeCol) {
- parseContext.error($2.line, " non-scalar fields not implemented yet", ".", "");
- parseContext.recover();
- constUnion *unionArray = new constUnion[1];
- unionArray->iConst = 0;
- TIntermTyped* index = parseContext.intermediate.addConstantUnion(unionArray, TType(EbtInt, EvqConst), $3.line);
- $$ = parseContext.intermediate.addIndex(EOpIndexDirect, $1, index, $2.line);
- $$->setType(TType($1->getBasicType(), EvqTemporary, $1->getNominalSize()));
- } else {
- constUnion *unionArray = new constUnion[1];
- unionArray->iConst = fields.col * $1->getNominalSize() + fields.row;
- TIntermTyped* index = parseContext.intermediate.addConstantUnion(unionArray, TType(EbtInt, EvqConst), $3.line);
- $$ = parseContext.intermediate.addIndex(EOpIndexDirect, $1, index, $2.line);
- $$->setType(TType($1->getBasicType()));
- }
- } else if ($1->getBasicType() == EbtStruct) {
- bool fieldFound = false;
- TTypeList* fields = $1->getType().getStruct();
- if (fields == 0) {
- parseContext.error($2.line, "structure has no fields", "Internal Error", "");
- parseContext.recover();
- $$ = $1;
- } else {
- unsigned int i;
- for (i = 0; i < fields->size(); ++i) {
- if ((*fields)[i].type->getFieldName() == *$3.string) {
- fieldFound = true;
- break;
- }
- }
- if (fieldFound) {
- if ($1->getType().getQualifier() == EvqConst) {
- $$ = parseContext.addConstStruct(*$3.string, $1, $2.line);
- if ($$ == 0) {
- parseContext.recover();
- $$ = $1;
- }
- else {
- $$->setType(*(*fields)[i].type);
- // change the qualifier of the return type, not of the structure field
- // as the structure definition is shared between various structures.
- $$->getTypePointer()->changeQualifier(EvqConst);
- }
- } else {
- constUnion *unionArray = new constUnion[1];
- unionArray->iConst = i;
- TIntermTyped* index = parseContext.intermediate.addConstantUnion(unionArray, TType(EbtInt, EvqConst), $3.line);
- $$ = parseContext.intermediate.addIndex(EOpIndexDirectStruct, $1, index, $2.line);
- $$->setType(*(*fields)[i].type);
- }
- } else {
- parseContext.error($2.line, " no such field in structure", $3.string->c_str(), "");
- parseContext.recover();
- $$ = $1;
- }
- }
- } else {
- parseContext.error($2.line, " field selection requires structure, vector, or matrix on left hand side", $3.string->c_str(), "");
- parseContext.recover();
- $$ = $1;
- }
- // don't delete $3.string, it's from the pool
- }
- | postfix_expression INC_OP {
- if (parseContext.lValueErrorCheck($2.line, "++", $1))
- parseContext.recover();
- $$ = parseContext.intermediate.addUnaryMath(EOpPostIncrement, $1, $2.line, parseContext.symbolTable);
- if ($$ == 0) {
- parseContext.unaryOpError($2.line, "++", $1->getCompleteString());
- parseContext.recover();
- $$ = $1;
- }
- }
- | postfix_expression DEC_OP {
- if (parseContext.lValueErrorCheck($2.line, "--", $1))
- parseContext.recover();
- $$ = parseContext.intermediate.addUnaryMath(EOpPostDecrement, $1, $2.line, parseContext.symbolTable);
- if ($$ == 0) {
- parseContext.unaryOpError($2.line, "--", $1->getCompleteString());
- parseContext.recover();
- $$ = $1;
- }
- }
- ;
-
-integer_expression
- : expression {
- if (parseContext.integerErrorCheck($1, "[]"))
- parseContext.recover();
- $$ = $1;
- }
- ;
-
-function_call
- : function_call_generic {
- TFunction* fnCall = $1.function;
- TOperator op = fnCall->getBuiltInOp();
-
- if (op != EOpNull) {
- //
- // Then this should be a constructor.
- //
- TType type(EbtVoid); // use this to get the type back
- if (parseContext.constructorErrorCheck($1.line, $1.intermNode, *fnCall, op, &type)) {
- $$ = 0;
- } else {
- //
- // It's a constructor, of type 'type'.
- //
- $$ = parseContext.addConstructor($1.intermNode, &type, op, fnCall, $1.line);
- }
-
- if ($$ == 0) {
- parseContext.recover();
- $$ = parseContext.intermediate.setAggregateOperator(0, op, $1.line);
- }
- $$->setType(type);
- } else {
- //
- // Not a constructor. Find it in the symbol table.
- //
- const TFunction* fnCandidate;
- bool builtIn;
- fnCandidate = parseContext.findFunction($1.line, fnCall, &builtIn);
- if (fnCandidate) {
- //
- // A declared function. But, it might still map to a built-in
- // operation.
- //
- op = fnCandidate->getBuiltInOp();
- if (builtIn && op != EOpNull) {
- //
- // A function call mapped to a built-in operation.
- //
- if (fnCandidate->getParamCount() == 1) {
- //
- // Treat it like a built-in unary operator.
- //
- $$ = parseContext.intermediate.addUnaryMath(op, $1.intermNode, 0, parseContext.symbolTable);
- if ($$ == 0) {
- parseContext.error($1.intermNode->getLine(), " wrong operand type", "Internal Error",
- "built in unary operator function. Type: %s",
- static_cast<TIntermTyped*>($1.intermNode)->getCompleteString().c_str());
- YYERROR;
- }
- } else {
- $$ = parseContext.intermediate.setAggregateOperator($1.intermAggregate, op, $1.line);
- }
- } else {
- // This is a real function call
-
- $$ = parseContext.intermediate.setAggregateOperator($1.intermAggregate, EOpFunctionCall, $1.line);
- $$->setType(fnCandidate->getReturnType());
-
- // this is how we know whether the given function is a builtIn function or a user defined function
- // if builtIn == false, it's a userDefined -> could be an overloaded builtIn function also
- // if builtIn == true, it's definitely a builtIn function with EOpNull
- if (!builtIn)
- $$->getAsAggregate()->setUserDefined();
- $$->getAsAggregate()->setName(fnCandidate->getMangledName());
-
- TQualifier qual;
- TQualifierList& qualifierList = $$->getAsAggregate()->getQualifier();
- for (int i = 0; i < fnCandidate->getParamCount(); ++i) {
- qual = (*fnCandidate)[i].type->getQualifier();
- if (qual == EvqOut || qual == EvqInOut) {
- if (parseContext.lValueErrorCheck($$->getLine(), "assign", $$->getAsAggregate()->getSequence()[i]->getAsTyped())) {
- parseContext.error($1.intermNode->getLine(), "Constant value cannot be passed for 'out' or 'inout' parameters.", "Error", "");
- parseContext.recover();
- }
- }
- qualifierList.push_back(qual);
- }
- }
- $$->setType(fnCandidate->getReturnType());
- } else {
- // error message was put out by PaFindFunction()
- // Put on a dummy node for error recovery
- constUnion *unionArray = new constUnion[1];
- unionArray->fConst = 0.0;
- $$ = parseContext.intermediate.addConstantUnion(unionArray, TType(EbtFloat, EvqConst), $1.line);
- parseContext.recover();
- }
- }
- delete fnCall;
- }
- ;
-
-function_call_generic
- : function_call_header_with_parameters RIGHT_PAREN {
- $$ = $1;
- $$.line = $2.line;
- }
- | function_call_header_no_parameters RIGHT_PAREN {
- $$ = $1;
- $$.line = $2.line;
- }
- ;
-
-function_call_header_no_parameters
- : function_call_header VOID_TYPE {
- $$.function = $1;
- $$.intermNode = 0;
- }
- | function_call_header {
- $$.function = $1;
- $$.intermNode = 0;
- }
- ;
-
-function_call_header_with_parameters
- : function_call_header assignment_expression {
- TParameter param = { 0, new TType($2->getType()) };
- $1->addParameter(param);
- $$.function = $1;
- $$.intermNode = $2;
- }
- | function_call_header_with_parameters COMMA assignment_expression {
- TParameter param = { 0, new TType($3->getType()) };
- $1.function->addParameter(param);
- $$.function = $1.function;
- $$.intermNode = parseContext.intermediate.growAggregate($1.intermNode, $3, $2.line);
- }
- ;
-
-function_call_header
- : function_identifier LEFT_PAREN {
- $$ = $1;
- }
- ;
-
-function_identifier
- : constructor_identifier {
- if ($1.op == EOpConstructStruct) {
- TString tempString = "";
- TFunction *function = new TFunction(&tempString, *($1.type.userDef), $1.op);
- $$ = function;
- }
- else {
- TFunction *function = new TFunction($1.op);
- $$ = function;
- }
- }
- | IDENTIFIER {
- if (parseContext.reservedErrorCheck($1.line, *$1.string))
- parseContext.recover();
- TType type(EbtVoid);
- TFunction *function = new TFunction($1.string, type);
- $$ = function;
- }
- ;
-
-// Grammar Note: Constructors look like functions, but lexical anaylsis recognized most of them as keywords.
-
-//
-// Don't go through the symbol table for constructors.
-// Their parameters will be verified algorithmically.
-//
-constructor_identifier
- : FLOAT_TYPE { $$.line = $1.line; $$.op = EOpConstructFloat; }
- | INT_TYPE { $$.line = $1.line; $$.op = EOpConstructInt; }
- | BOOL_TYPE { $$.line = $1.line; $$.op = EOpConstructBool; }
- | VEC2 { $$.line = $1.line; $$.op = EOpConstructVec2; }
- | VEC3 { $$.line = $1.line; $$.op = EOpConstructVec3; }
- | VEC4 { $$.line = $1.line; $$.op = EOpConstructVec4; }
- | BVEC2 { FRAG_VERT_ONLY("bvec2", $1.line); $$.line = $1.line; $$.op = EOpConstructBVec2; }
- | BVEC3 { FRAG_VERT_ONLY("bvec3", $1.line); $$.line = $1.line; $$.op = EOpConstructBVec3; }
- | BVEC4 { FRAG_VERT_ONLY("bvec4", $1.line); $$.line = $1.line; $$.op = EOpConstructBVec4; }
- | IVEC2 { FRAG_VERT_ONLY("ivec2", $1.line); $$.line = $1.line; $$.op = EOpConstructIVec2; }
- | IVEC3 { FRAG_VERT_ONLY("ivec3", $1.line); $$.line = $1.line; $$.op = EOpConstructIVec3; }
- | IVEC4 { FRAG_VERT_ONLY("ivec4", $1.line); $$.line = $1.line; $$.op = EOpConstructIVec4; }
- | MATRIX2 { FRAG_VERT_ONLY("mat2", $1.line); $$.line = $1.line; $$.op = EOpConstructMat2; }
- | MATRIX3 { FRAG_VERT_ONLY("mat3", $1.line); $$.line = $1.line; $$.op = EOpConstructMat3; }
- | MATRIX4 { FRAG_VERT_ONLY("mat4", $1.line); $$.line = $1.line; $$.op = EOpConstructMat4; }
- | TYPE_NAME {
- TType& structure = static_cast<TVariable*>($1.symbol)->getType();
- TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
- TPublicType t = { EbtStruct, qual, 1, false, false, &structure, $1.line };
- $$.type = t;
- $$.line = $1.line;
- $$.op = EOpConstructStruct;
- }
- ;
-
-unary_expression
- : postfix_expression {
- $$ = $1;
- }
- | INC_OP unary_expression {
- if (parseContext.lValueErrorCheck($1.line, "++", $2))
- parseContext.recover();
- $$ = parseContext.intermediate.addUnaryMath(EOpPreIncrement, $2, $1.line, parseContext.symbolTable);
- if ($$ == 0) {
- parseContext.unaryOpError($1.line, "++", $2->getCompleteString());
- parseContext.recover();
- $$ = $2;
- }
- }
- | DEC_OP unary_expression {
- if (parseContext.lValueErrorCheck($1.line, "--", $2))
- parseContext.recover();
- $$ = parseContext.intermediate.addUnaryMath(EOpPreDecrement, $2, $1.line, parseContext.symbolTable);
- if ($$ == 0) {
- parseContext.unaryOpError($1.line, "--", $2->getCompleteString());
- parseContext.recover();
- $$ = $2;
- }
- }
- | unary_operator unary_expression {
- if ($1.op != EOpNull) {
- $$ = parseContext.intermediate.addUnaryMath($1.op, $2, $1.line, parseContext.symbolTable);
- if ($$ == 0) {
- char* errorOp = "";
- switch($1.op) {
- case EOpNegative: errorOp = "-"; break;
- case EOpLogicalNot: errorOp = "!"; break;
- case EOpBitwiseNot: errorOp = "~"; break;
- default: break;
- }
- parseContext.unaryOpError($1.line, errorOp, $2->getCompleteString());
- parseContext.recover();
- $$ = $2;
- }
- } else
- $$ = $2;
- }
- ;
-// Grammar Note: No traditional style type casts.
-
-unary_operator
- : PLUS { $$.line = $1.line; $$.op = EOpNull; }
- | DASH { $$.line = $1.line; $$.op = EOpNegative; }
- | BANG { $$.line = $1.line; $$.op = EOpLogicalNot; }
- | TILDE { PACK_UNPACK_ONLY("~", $1.line);
- $$.line = $1.line; $$.op = EOpBitwiseNot; }
- ;
-// Grammar Note: No '*' or '&' unary ops. Pointers are not supported.
-
-multiplicative_expression
- : unary_expression { $$ = $1; }
- | multiplicative_expression STAR unary_expression {
- FRAG_VERT_ONLY("*", $2.line);
- $$ = parseContext.intermediate.addBinaryMath(EOpMul, $1, $3, $2.line, parseContext.symbolTable);
- if ($$ == 0) {
- parseContext.binaryOpError($2.line, "*", $1->getCompleteString(), $3->getCompleteString());
- parseContext.recover();
- $$ = $1;
- }
- }
- | multiplicative_expression SLASH unary_expression {
- FRAG_VERT_ONLY("/", $2.line);
- $$ = parseContext.intermediate.addBinaryMath(EOpDiv, $1, $3, $2.line, parseContext.symbolTable);
- if ($$ == 0) {
- parseContext.binaryOpError($2.line, "/", $1->getCompleteString(), $3->getCompleteString());
- parseContext.recover();
- $$ = $1;
- }
- }
- | multiplicative_expression PERCENT unary_expression {
- PACK_UNPACK_ONLY("%", $2.line);
- $$ = parseContext.intermediate.addBinaryMath(EOpMod, $1, $3, $2.line, parseContext.symbolTable);
- if ($$ == 0) {
- parseContext.binaryOpError($2.line, "%", $1->getCompleteString(), $3->getCompleteString());
- parseContext.recover();
- $$ = $1;
- }
- }
- ;
-
-additive_expression
- : multiplicative_expression { $$ = $1; }
- | additive_expression PLUS multiplicative_expression {
- $$ = parseContext.intermediate.addBinaryMath(EOpAdd, $1, $3, $2.line, parseContext.symbolTable);
- if ($$ == 0) {
- parseContext.binaryOpError($2.line, "+", $1->getCompleteString(), $3->getCompleteString());
- parseContext.recover();
- $$ = $1;
- }
- }
- | additive_expression DASH multiplicative_expression {
- $$ = parseContext.intermediate.addBinaryMath(EOpSub, $1, $3, $2.line, parseContext.symbolTable);
- if ($$ == 0) {
- parseContext.binaryOpError($2.line, "-", $1->getCompleteString(), $3->getCompleteString());
- parseContext.recover();
- $$ = $1;
- }
- }
- ;
-
-shift_expression
- : additive_expression { $$ = $1; }
- | shift_expression LEFT_OP additive_expression {
- PACK_UNPACK_ONLY("<<", $2.line);
- $$ = parseContext.intermediate.addBinaryMath(EOpLeftShift, $1, $3, $2.line, parseContext.symbolTable);
- if ($$ == 0) {
- parseContext.binaryOpError($2.line, "<<", $1->getCompleteString(), $3->getCompleteString());
- parseContext.recover();
- $$ = $1;
- }
- }
- | shift_expression RIGHT_OP additive_expression {
- PACK_UNPACK_ONLY(">>", $2.line);
- $$ = parseContext.intermediate.addBinaryMath(EOpRightShift, $1, $3, $2.line, parseContext.symbolTable);
- if ($$ == 0) {
- parseContext.binaryOpError($2.line, ">>", $1->getCompleteString(), $3->getCompleteString());
- parseContext.recover();
- $$ = $1;
- }
- }
- ;
-
-relational_expression
- : shift_expression { $$ = $1; }
- | relational_expression LEFT_ANGLE shift_expression {
- $$ = parseContext.intermediate.addBinaryMath(EOpLessThan, $1, $3, $2.line, parseContext.symbolTable);
- if ($$ == 0) {
- parseContext.binaryOpError($2.line, "<", $1->getCompleteString(), $3->getCompleteString());
- parseContext.recover();
- constUnion *unionArray = new constUnion[1];
- unionArray->bConst = false;
- $$ = parseContext.intermediate.addConstantUnion(unionArray, TType(EbtBool, EvqConst), $2.line);
- }
- }
- | relational_expression RIGHT_ANGLE shift_expression {
- $$ = parseContext.intermediate.addBinaryMath(EOpGreaterThan, $1, $3, $2.line, parseContext.symbolTable);
- if ($$ == 0) {
- parseContext.binaryOpError($2.line, ">", $1->getCompleteString(), $3->getCompleteString());
- parseContext.recover();
- constUnion *unionArray = new constUnion[1];
- unionArray->bConst = false;
- $$ = parseContext.intermediate.addConstantUnion(unionArray, TType(EbtBool, EvqConst), $2.line);
- }
- }
- | relational_expression LE_OP shift_expression {
- $$ = parseContext.intermediate.addBinaryMath(EOpLessThanEqual, $1, $3, $2.line, parseContext.symbolTable);
- if ($$ == 0) {
- parseContext.binaryOpError($2.line, "<=", $1->getCompleteString(), $3->getCompleteString());
- parseContext.recover();
- constUnion *unionArray = new constUnion[1];
- unionArray->bConst = false;
- $$ = parseContext.intermediate.addConstantUnion(unionArray, TType(EbtBool, EvqConst), $2.line);
- }
- }
- | relational_expression GE_OP shift_expression {
- $$ = parseContext.intermediate.addBinaryMath(EOpGreaterThanEqual, $1, $3, $2.line, parseContext.symbolTable);
- if ($$ == 0) {
- parseContext.binaryOpError($2.line, ">=", $1->getCompleteString(), $3->getCompleteString());
- parseContext.recover();
- constUnion *unionArray = new constUnion[1];
- unionArray->bConst = false;
- $$ = parseContext.intermediate.addConstantUnion(unionArray, TType(EbtBool, EvqConst), $2.line);
- }
- }
- ;
-
-equality_expression
- : relational_expression { $$ = $1; }
- | equality_expression EQ_OP relational_expression {
- $$ = parseContext.intermediate.addBinaryMath(EOpEqual, $1, $3, $2.line, parseContext.symbolTable);
- if ($$ == 0) {
- parseContext.binaryOpError($2.line, "==", $1->getCompleteString(), $3->getCompleteString());
- parseContext.recover();
- constUnion *unionArray = new constUnion[1];
- unionArray->bConst = false;
- $$ = parseContext.intermediate.addConstantUnion(unionArray, TType(EbtBool, EvqConst), $2.line);
- }
- }
- | equality_expression NE_OP relational_expression {
- $$ = parseContext.intermediate.addBinaryMath(EOpNotEqual, $1, $3, $2.line, parseContext.symbolTable);
- if ($$ == 0) {
- parseContext.binaryOpError($2.line, "!=", $1->getCompleteString(), $3->getCompleteString());
- parseContext.recover();
- constUnion *unionArray = new constUnion[1];
- unionArray->bConst = false;
- $$ = parseContext.intermediate.addConstantUnion(unionArray, TType(EbtBool, EvqConst), $2.line);
- }
- }
- ;
-
-and_expression
- : equality_expression { $$ = $1; }
- | and_expression AMPERSAND equality_expression {
- PACK_UNPACK_ONLY("&", $2.line);
- $$ = parseContext.intermediate.addBinaryMath(EOpAnd, $1, $3, $2.line, parseContext.symbolTable);
- if ($$ == 0) {
- parseContext.binaryOpError($2.line, "&", $1->getCompleteString(), $3->getCompleteString());
- parseContext.recover();
- $$ = $1;
- }
- }
- ;
-
-exclusive_or_expression
- : and_expression { $$ = $1; }
- | exclusive_or_expression CARET and_expression {
- PACK_UNPACK_ONLY("^", $2.line);
- $$ = parseContext.intermediate.addBinaryMath(EOpExclusiveOr, $1, $3, $2.line, parseContext.symbolTable);
- if ($$ == 0) {
- parseContext.binaryOpError($2.line, "^", $1->getCompleteString(), $3->getCompleteString());
- parseContext.recover();
- $$ = $1;
- }
- }
- ;
-
-inclusive_or_expression
- : exclusive_or_expression { $$ = $1; }
- | inclusive_or_expression VERTICAL_BAR exclusive_or_expression {
- PACK_UNPACK_ONLY("|", $2.line);
- $$ = parseContext.intermediate.addBinaryMath(EOpInclusiveOr, $1, $3, $2.line, parseContext.symbolTable);
- if ($$ == 0) {
- parseContext.binaryOpError($2.line, "|", $1->getCompleteString(), $3->getCompleteString());
- parseContext.recover();
- $$ = $1;
- }
- }
- ;
-
-logical_and_expression
- : inclusive_or_expression { $$ = $1; }
- | logical_and_expression AND_OP inclusive_or_expression {
- $$ = parseContext.intermediate.addBinaryMath(EOpLogicalAnd, $1, $3, $2.line, parseContext.symbolTable);
- if ($$ == 0) {
- parseContext.binaryOpError($2.line, "&&", $1->getCompleteString(), $3->getCompleteString());
- parseContext.recover();
- constUnion *unionArray = new constUnion[1];
- unionArray->bConst = false;
- $$ = parseContext.intermediate.addConstantUnion(unionArray, TType(EbtBool, EvqConst), $2.line);
- }
- }
- ;
-
-logical_xor_expression
- : logical_and_expression { $$ = $1; }
- | logical_xor_expression XOR_OP logical_and_expression {
- $$ = parseContext.intermediate.addBinaryMath(EOpLogicalXor, $1, $3, $2.line, parseContext.symbolTable);
- if ($$ == 0) {
- parseContext.binaryOpError($2.line, "^^", $1->getCompleteString(), $3->getCompleteString());
- parseContext.recover();
- constUnion *unionArray = new constUnion[1];
- unionArray->bConst = false;
- $$ = parseContext.intermediate.addConstantUnion(unionArray, TType(EbtBool, EvqConst), $2.line);
- }
- }
- ;
-
-logical_or_expression
- : logical_xor_expression { $$ = $1; }
- | logical_or_expression OR_OP logical_xor_expression {
- $$ = parseContext.intermediate.addBinaryMath(EOpLogicalOr, $1, $3, $2.line, parseContext.symbolTable);
- if ($$ == 0) {
- parseContext.binaryOpError($2.line, "||", $1->getCompleteString(), $3->getCompleteString());
- parseContext.recover();
- constUnion *unionArray = new constUnion[1];
- unionArray->bConst = false;
- $$ = parseContext.intermediate.addConstantUnion(unionArray, TType(EbtBool, EvqConst), $2.line);
- }
- }
- ;
-
-conditional_expression
- : logical_or_expression { $$ = $1; }
- | logical_or_expression QUESTION expression COLON assignment_expression {
- if (parseContext.boolErrorCheck($2.line, $1))
- parseContext.recover();
-
- $$ = parseContext.intermediate.addSelection($1, $3, $5, $2.line);
- if ($3->getType() != $5->getType())
- $$ = 0;
-
- if ($$ == 0) {
- parseContext.binaryOpError($2.line, ":", $3->getCompleteString(), $5->getCompleteString());
- parseContext.recover();
- $$ = $5;
- }
- }
- ;
-
-assignment_expression
- : conditional_expression { $$ = $1; }
- | unary_expression assignment_operator assignment_expression {
- if (parseContext.lValueErrorCheck($2.line, "assign", $1))
- parseContext.recover();
- $$ = parseContext.intermediate.addAssign($2.op, $1, $3, $2.line);
- if ($$ == 0) {
- parseContext.assignError($2.line, "assign", $1->getCompleteString(), $3->getCompleteString());
- parseContext.recover();
- $$ = $1;
- }
- }
- ;
-
-assignment_operator
- : EQUAL { $$.line = $1.line; $$.op = EOpAssign; }
- | MUL_ASSIGN { FRAG_VERT_ONLY("*=", $1.line); $$.line = $1.line; $$.op = EOpMulAssign; }
- | DIV_ASSIGN { FRAG_VERT_ONLY("/=", $1.line); $$.line = $1.line; $$.op = EOpDivAssign; }
- | MOD_ASSIGN { PACK_UNPACK_ONLY("%=", $1.line); $$.line = $1.line; $$.op = EOpModAssign; }
- | ADD_ASSIGN { $$.line = $1.line; $$.op = EOpAddAssign; }
- | SUB_ASSIGN { $$.line = $1.line; $$.op = EOpSubAssign; }
- | LEFT_ASSIGN { PACK_UNPACK_ONLY("<<=", $1.line); $$.line = $1.line; $$.op = EOpLeftShiftAssign; }
- | RIGHT_ASSIGN { PACK_UNPACK_ONLY("<<=", $1.line); $$.line = $1.line; $$.op = EOpRightShiftAssign; }
- | AND_ASSIGN { PACK_UNPACK_ONLY("&=", $1.line); $$.line = $1.line; $$.op = EOpAndAssign; }
- | XOR_ASSIGN { PACK_UNPACK_ONLY("^=", $1.line); $$.line = $1.line; $$.op = EOpExclusiveOrAssign; }
- | OR_ASSIGN { PACK_UNPACK_ONLY("|=", $1.line); $$.line = $1.line; $$.op = EOpInclusiveOrAssign; }
- ;
-
-expression
- : assignment_expression {
- $$ = $1;
- }
- | expression COMMA assignment_expression {
- $$ = parseContext.intermediate.addComma($1, $3, $2.line);
- if ($$ == 0) {
- parseContext.binaryOpError($2.line, ",", $1->getCompleteString(), $3->getCompleteString());
- parseContext.recover();
- $$ = $3;
- }
- }
- ;
-
-constant_expression
- : conditional_expression {
- if (parseContext.constErrorCheck($1))
- parseContext.recover();
- $$ = $1;
- }
- ;
-
-declaration
- : function_prototype SEMICOLON { $$ = 0; }
- | init_declarator_list SEMICOLON {
- if ($1.intermAggregate)
- $1.intermAggregate->setOperator(EOpSequence);
- $$ = $1.intermAggregate;
- }
- ;
-
-function_prototype
- : function_declarator RIGHT_PAREN {
- //
- // Multiple declarations of the same function are allowed.
- //
- // If this is a definition, the definition production code will check for redefinitions
- // (we don't know at this point if it's a definition or not).
- //
- // Redeclarations are allowed. But, return types and parameter qualifiers must match.
- //
- TFunction* prevDec = static_cast<TFunction*>(parseContext.symbolTable.find($1->getMangledName()));
- if (prevDec) {
- if (prevDec->getReturnType() != $1->getReturnType()) {
- parseContext.error($2.line, "overloaded functions must have the same return type", $1->getReturnType().getBasicString(), "");
- parseContext.recover();
- }
- for (int i = 0; i < prevDec->getParamCount(); ++i) {
- if ((*prevDec)[i].type->getQualifier() != (*$1)[i].type->getQualifier()) {
- parseContext.error($2.line, "overloaded functions must have the same parameter qualifiers", (*$1)[i].type->getQualifierString(), "");
- parseContext.recover();
- }
- }
- }
-
- //
- // If this is a redeclaration, it could also be a definition,
- // in which case, we want to use the variable names from this one, and not the one that's
- // being redeclared. So, pass back up this declaration, not the one in the symbol table.
- //
- $$.function = $1;
- $$.line = $2.line;
-
- parseContext.symbolTable.insert(*$$.function);
- }
- ;
-
-function_declarator
- : function_header {
- $$ = $1;
- }
- | function_header_with_parameters {
- $$ = $1;
- }
- ;
-
-
-function_header_with_parameters
- : function_header parameter_declaration {
- // Add the parameter
- $$ = $1;
- if ($2.param.type->getBasicType() != EbtVoid)
- $1->addParameter($2.param);
- else
- delete $2.param.type;
- }
- | function_header_with_parameters COMMA parameter_declaration {
- //
- // Only first parameter of one-parameter functions can be void
- // The check for named parameters not being void is done in parameter_declarator
- //
- if ($3.param.type->getBasicType() == EbtVoid) {
- //
- // This parameter > first is void
- //
- parseContext.error($2.line, "cannot be an argument type except for '(void)'", "void", "");
- parseContext.recover();
- delete $3.param.type;
- } else {
- // Add the parameter
- $$ = $1;
- $1->addParameter($3.param);
- }
- }
- ;
-
-function_header
- : fully_specified_type IDENTIFIER LEFT_PAREN {
- if ($1.qualifier != EvqGlobal && $1.qualifier != EvqTemporary) {
- parseContext.error($2.line, "no qualifiers allowed for function return", getQualifierString($1.qualifier), "");
- parseContext.recover();
- }
- // make sure a sampler is not involved as well...
- if (parseContext.structQualifierErrorCheck($2.line, $1))
- parseContext.recover();
-
- // Add the function as a prototype after parsing it (we do not support recursion)
- TFunction *function;
- TType type($1);
- function = new TFunction($2.string, type);
- $$ = function;
- }
- ;
-
-parameter_declarator
- // Type + name
- : type_specifier IDENTIFIER {
- if ($1.type == EbtVoid) {
- parseContext.error($2.line, "illegal use of type 'void'", $2.string->c_str(), "");
- parseContext.recover();
- }
- if (parseContext.reservedErrorCheck($2.line, *$2.string))
- parseContext.recover();
- TParameter param = {$2.string, new TType($1)};
- $$.line = $2.line;
- $$.param = param;
- }
- | type_specifier IDENTIFIER LEFT_BRACKET constant_expression RIGHT_BRACKET {
- // Check that we can make an array out of this type
- if ($1.array) {
- parseContext.error($3.line, "cannot declare arrays of this type", TType($1).getCompleteString().c_str(), "");
- parseContext.recover();
- }
- if (parseContext.reservedErrorCheck($2.line, *$2.string))
- parseContext.recover();
- $1.array = true;
- TType* type = new TType($1);
- if ($4->getAsConstantUnion())
- type->setArraySize($4->getAsConstantUnion()->getUnionArrayPointer()->iConst);
- TParameter param = { $2.string, type };
- $$.line = $2.line;
- $$.param = param;
- }
- ;
-
-parameter_declaration
- //
- // The only parameter qualifier a parameter can have are
- // IN_QUAL, OUT_QUAL, INOUT_QUAL, or CONST.
- //
-
- //
- // Type + name
- //
- : type_qualifier parameter_qualifier parameter_declarator {
- $$ = $3;
- if (parseContext.paramErrorCheck($3.line, $1.qualifier, $2, $$.param.type))
- parseContext.recover();
- }
- | parameter_qualifier parameter_declarator {
- $$ = $2;
- if (parseContext.parameterSamplerErrorCheck($2.line, $1, *$2.param.type))
- parseContext.recover();
- if (parseContext.paramErrorCheck($2.line, EvqTemporary, $1, $$.param.type))
- parseContext.recover();
- }
- //
- // Only type
- //
- | type_qualifier parameter_qualifier parameter_type_specifier {
- $$ = $3;
- if (parseContext.paramErrorCheck($3.line, $1.qualifier, $2, $$.param.type))
- parseContext.recover();
- }
- | parameter_qualifier parameter_type_specifier {
- $$ = $2;
- if (parseContext.parameterSamplerErrorCheck($2.line, $1, *$2.param.type))
- parseContext.recover();
- if (parseContext.paramErrorCheck($2.line, EvqTemporary, $1, $$.param.type))
- parseContext.recover();
- }
- ;
-
-parameter_qualifier
- : /* empty */ {
- $$ = EvqIn;
- }
- | IN_QUAL {
- $$ = EvqIn;
- }
- | OUT_QUAL {
- $$ = EvqOut;
- }
- | INOUT_QUAL {
- $$ = EvqInOut;
- }
- ;
-
-parameter_type_specifier
- : type_specifier {
- TParameter param = { 0, new TType($1) };
- $$.param = param;
-
- }
- | type_specifier LEFT_BRACKET constant_expression RIGHT_BRACKET {
- // Check that we can make an array out of this type
- if ($1.array) {
- parseContext.error($2.line, "cannot declare arrays of this type", TType($1).getCompleteString().c_str(), "");
- parseContext.recover();
- }
- $1.array = true;
- TType* type = new TType($1);
- if ($3->getAsConstantUnion())
- type->setArraySize($3->getAsConstantUnion()->getUnionArrayPointer()->iConst);
-
- TParameter param = { 0, type };
- $$.line = $2.line;
- $$.param = param;
- }
- ;
-
-init_declarator_list
- : single_declaration {
- $$ = $1;
- }
- | init_declarator_list COMMA IDENTIFIER {
- $$ = $1;
- if (parseContext.structQualifierErrorCheck($3.line, $1.type))
- parseContext.recover();
-
- if (parseContext.nonInitErrorCheck($3.line, *$3.string, $$.type))
- parseContext.recover();
- }
- | init_declarator_list COMMA IDENTIFIER LEFT_BRACKET RIGHT_BRACKET {
- $$ = $1;
- if (parseContext.structQualifierErrorCheck($3.line, $1.type))
- parseContext.recover();
-
- if (parseContext.arrayErrorCheck($4.line, *$3.string, $$.type, 0))
- parseContext.recover();
- }
- | init_declarator_list COMMA IDENTIFIER LEFT_BRACKET constant_expression RIGHT_BRACKET {
- $$ = $1;
- if (parseContext.structQualifierErrorCheck($3.line, $1.type))
- parseContext.recover();
-
- if (parseContext.arrayErrorCheck($4.line, *$3.string, $$.type, $5))
- parseContext.recover();
- }
- | init_declarator_list COMMA IDENTIFIER EQUAL initializer {
- $$ = $1;
- if (parseContext.structQualifierErrorCheck($3.line, $1.type))
- parseContext.recover();
-
- TIntermNode* intermNode;
- if (!parseContext.executeInitializer($3.line, *$3.string, $1.type, $5, intermNode)) {
- //
- // build the intermediate representation
- //
- if (intermNode)
- $$.intermAggregate = parseContext.intermediate.growAggregate($1.intermNode, intermNode, $4.line);
- else
- $$.intermAggregate = $1.intermAggregate;
- } else {
- parseContext.recover();
- $$.intermAggregate = 0;
- }
- }
- ;
-
-single_declaration
- : fully_specified_type {
- $$.type = $1;
- $$.intermAggregate = 0;
- }
- | fully_specified_type IDENTIFIER {
- $$.intermAggregate = 0;
- $$.type = $1;
- if (parseContext.structQualifierErrorCheck($2.line, $1))
- parseContext.recover();
-
- if (parseContext.nonInitErrorCheck($2.line, *$2.string, $$.type))
- parseContext.recover();
- }
- | fully_specified_type IDENTIFIER LEFT_BRACKET RIGHT_BRACKET {
- $$.intermAggregate = 0;
- $$.type = $1;
- if (parseContext.structQualifierErrorCheck($2.line, $1))
- parseContext.recover();
-
- if (parseContext.arrayErrorCheck($3.line, *$2.string, $$.type, 0))
- parseContext.recover();
- }
- | fully_specified_type IDENTIFIER LEFT_BRACKET constant_expression RIGHT_BRACKET {
- $$.intermAggregate = 0;
- $$.type = $1;
- if (parseContext.structQualifierErrorCheck($2.line, $1))
- parseContext.recover();
-
- if (parseContext.arrayErrorCheck($3.line, *$2.string, $$.type, $4))
- parseContext.recover();
- }
- | fully_specified_type IDENTIFIER EQUAL initializer {
- $$.type = $1;
- if (parseContext.structQualifierErrorCheck($2.line, $1))
- parseContext.recover();
-
- TIntermNode* intermNode;
- if (!parseContext.executeInitializer($2.line, *$2.string, $1, $4, intermNode)) {
- //
- // Build intermediate representation
- //
- if (intermNode)
- $$.intermAggregate = parseContext.intermediate.makeAggregate(intermNode, $3.line);
- else
- $$.intermAggregate = 0;
- } else {
- parseContext.recover();
- $$.intermAggregate = 0;
- }
- }
-
-//
-// Place holder for the pack/unpack languages.
-//
-// | buffer_specifier {
-// $$.intermAggregate = 0;
-// }
- ;
-
-// Grammar Note: No 'enum', or 'typedef'.
-
-//
-// Place holder for the pack/unpack languages.
-//
-//%type <interm> buffer_declaration
-//%type <interm.type> buffer_specifier input_or_output buffer_declaration_list
-//buffer_specifier
-// : input_or_output LEFT_BRACE buffer_declaration_list RIGHT_BRACE {
-// }
-// ;
-//
-//input_or_output
-// : INPUT {
-// if (parseContext.globalErrorCheck($1.line, parseContext.symbolTable.atGlobalLevel(), "input"))
-// parseContext.recover();
-// UNPACK_ONLY("input", $1.line);
-// $$.qualifier = EvqInput;
-// }
-// | OUTPUT {
-// if (parseContext.globalErrorCheck($1.line, parseContext.symbolTable.atGlobalLevel(), "output"))
-// parseContext.recover();
-// PACK_ONLY("output", $1.line);
-// $$.qualifier = EvqOutput;
-// }
-// ;
-
-//
-// Place holder for the pack/unpack languages.
-//
-//buffer_declaration_list
-// : buffer_declaration {
-// }
-// | buffer_declaration_list buffer_declaration {
-// }
-// ;
-
-//
-// Input/output semantics:
-// float must be 16 or 32 bits
-// float alignment restrictions?
-// check for only one input and only one output
-// sum of bitfields has to be multiple of 32
-//
-
-//
-// Place holder for the pack/unpack languages.
-//
-//buffer_declaration
-// : type_specifier IDENTIFIER COLON constant_expression SEMICOLON {
-// if (parseContext.reservedErrorCheck($2.line, *$2.string, parseContext))
-// parseContext.recover();
-// $$.variable = new TVariable($2.string, $1);
-// if (! parseContext.symbolTable.insert(*$$.variable)) {
-// parseContext.error($2.line, "redefinition", $$.variable->getName().c_str(), "");
-// parseContext.recover();
-// // don't have to delete $$.variable, the pool pop will take care of it
-// }
-// }
-// ;
-
-fully_specified_type
- : type_specifier {
- $$ = $1;
- }
- | type_qualifier type_specifier {
- TPublicType t = { $2.type, $1.qualifier, $2.size, $2.matrix, false, $2.userDef, 0 };
- if ($1.qualifier == EvqAttribute &&
- ($2.type == EbtBool || $2.type == EbtInt)) {
- parseContext.error($2.line, "cannot be bool or int", getQualifierString($1.qualifier), "");
- parseContext.recover();
- }
- if (($1.qualifier == EvqVaryingIn || $1.qualifier == EvqVaryingOut) &&
- ($2.type == EbtBool || $2.type == EbtInt)) {
- parseContext.error($2.line, "cannot be bool or int", getQualifierString($1.qualifier), "");
- parseContext.recover();
- }
- $$ = t;
- }
- ;
-
-type_qualifier
- : CONST_QUAL {
- TPublicType t = { EbtVoid, EvqConst, 1, false, false, 0 };
- $$ = t;
- }
- | ATTRIBUTE {
- VERTEX_ONLY("attribute", $1.line);
- if (parseContext.globalErrorCheck($1.line, parseContext.symbolTable.atGlobalLevel(), "attribute"))
- parseContext.recover();
- TPublicType t = { EbtVoid, EvqAttribute, 1, false, false, 0 };
- $$ = t;
- }
- | VARYING {
- if (parseContext.globalErrorCheck($1.line, parseContext.symbolTable.atGlobalLevel(), "varying"))
- parseContext.recover();
- TPublicType t = { EbtVoid, EvqVaryingIn, 1, false, false, 0 };
- if (parseContext.language == EShLangVertex)
- t.qualifier = EvqVaryingOut;
- $$ = t;
- }
- | UNIFORM {
- if (parseContext.globalErrorCheck($1.line, parseContext.symbolTable.atGlobalLevel(), "uniform"))
- parseContext.recover();
- TPublicType t = { EbtVoid, EvqUniform, 1, false, false, 0 };
- $$ = t;
- }
- ;
-
-type_specifier
- : VOID_TYPE {
- TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
- TPublicType t = { EbtVoid, qual, 1, false, false, 0, $1.line };
- $$ = t;
- }
- | FLOAT_TYPE {
- TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
- TPublicType t = { EbtFloat, qual, 1, false, false, 0, $1.line };
- $$ = t;
- }
- | INT_TYPE {
- TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
- TPublicType t = { EbtInt, qual, 1, false, false, 0, $1.line };
- $$ = t;
- }
- | BOOL_TYPE {
- TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
- TPublicType t = { EbtBool, qual, 1, false, false, 0, $1.line };
- $$ = t;
- }
-// | UNSIGNED INT_TYPE {
-// PACK_UNPACK_ONLY("unsigned", $1.line);
-// TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
-// TPublicType t = { EbtInt, qual, 1, false, false, 0, $1.line };
-// $$ = t;
-// }
- | VEC2 {
- TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
- TPublicType t = { EbtFloat, qual, 2, false, false, 0, $1.line };
- $$ = t;
- }
- | VEC3 {
- TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
- TPublicType t = { EbtFloat, qual, 3, false, false, 0, $1.line };
- $$ = t;
- }
- | VEC4 {
- TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
- TPublicType t = { EbtFloat, qual, 4, false, false, 0, $1.line };
- $$ = t;
- }
- | BVEC2 {
- TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
- TPublicType t = { EbtBool, qual, 2, false, false, 0, $1.line };
- $$ = t;
- }
- | BVEC3 {
- TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
- TPublicType t = { EbtBool, qual, 3, false, false, 0, $1.line };
- $$ = t;
- }
- | BVEC4 {
- TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
- TPublicType t = { EbtBool, qual, 4, false, false, 0, $1.line };
- $$ = t;
- }
- | IVEC2 {
- TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
- TPublicType t = { EbtInt, qual, 2, false, false, 0, $1.line };
- $$ = t;
- }
- | IVEC3 {
- TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
- TPublicType t = { EbtInt, qual, 3, false, false, 0, $1.line };
- $$ = t;
- }
- | IVEC4 {
- TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
- TPublicType t = { EbtInt, qual, 4, false, false, 0, $1.line };
- $$ = t;
- }
- | MATRIX2 {
- FRAG_VERT_ONLY("mat2", $1.line);
- TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
- TPublicType t = { EbtFloat, qual, 2, true, false, 0, $1.line };
- $$ = t;
- }
- | MATRIX3 {
- FRAG_VERT_ONLY("mat3", $1.line);
- TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
- TPublicType t = { EbtFloat, qual, 3, true, false, 0, $1.line };
- $$ = t;
- }
- | MATRIX4 {
- FRAG_VERT_ONLY("mat4", $1.line);
- TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
- TPublicType t = { EbtFloat, qual, 4, true, false, 0, $1.line };
- $$ = t;
- }
- | SAMPLER1D {
- FRAG_VERT_ONLY("sampler1D", $1.line);
- TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
- TPublicType t = { EbtSampler1D, qual, 1, false, false, 0, $1.line };
- $$ = t;
- }
- | SAMPLER2D {
- FRAG_VERT_ONLY("sampler2D", $1.line);
- TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
- TPublicType t = { EbtSampler2D, qual, 1, false, false, 0, $1.line };
- $$ = t;
- }
- | SAMPLER3D {
- FRAG_VERT_ONLY("sampler3D", $1.line);
- TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
- TPublicType t = { EbtSampler3D, qual, 1, false, false, 0, $1.line };
- $$ = t;
- }
- | SAMPLERCUBE {
- FRAG_VERT_ONLY("samplerCube", $1.line);
- TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
- TPublicType t = { EbtSamplerCube, qual, 1, false, false, 0, $1.line };
- $$ = t;
- }
- | SAMPLER1DSHADOW {
- FRAG_VERT_ONLY("sampler1DShadow", $1.line);
- TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
- TPublicType t = { EbtSampler1DShadow, qual, 1, false, false, 0, $1.line };
- $$ = t;
- }
- | SAMPLER2DSHADOW {
- FRAG_VERT_ONLY("sampler2DShadow", $1.line);
- TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
- TPublicType t = { EbtSampler2DShadow, qual, 1, false, false, 0, $1.line };
- $$ = t;
- }
- | struct_specifier {
- FRAG_VERT_ONLY("struct", $1.line);
- $$ = $1;
- $$.qualifier = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
- }
- | TYPE_NAME {
- //
- // This is for user defined type names. The lexical phase looked up the
- // type.
- //
- TType& structure = static_cast<TVariable*>($1.symbol)->getType();
- TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
- TPublicType t = { EbtStruct, qual, 1, false, false, &structure, $1.line };
- $$ = t;
- }
- ;
-
-struct_specifier
- : STRUCT IDENTIFIER LEFT_BRACE struct_declaration_list RIGHT_BRACE {
- TType* structure = new TType($4, *$2.string);
- TVariable* userTypeDef = new TVariable($2.string, *structure, true);
- if (! parseContext.symbolTable.insert(*userTypeDef)) {
- parseContext.error($2.line, "redefinition", $2.string->c_str(), "struct");
- parseContext.recover();
- }
- TPublicType t = { EbtStruct, EvqTemporary, 1, false, false, structure, $1.line };
- $$ = t;
- }
- | STRUCT LEFT_BRACE struct_declaration_list RIGHT_BRACE {
- TType* structure = new TType($3, TString(""));
- TPublicType t = { EbtStruct, EvqTemporary, 1, false, false, structure, $1.line };
- $$ = t;
- }
- ;
-
-struct_declaration_list
- : struct_declaration {
- $$ = $1;
- }
- | struct_declaration_list struct_declaration {
- $$ = $1;
- for (unsigned int i = 0; i < $2->size(); ++i) {
- for (unsigned int j = 0; j < $$->size(); ++j) {
- if ((*$$)[j].type->getFieldName() == (*$2)[i].type->getFieldName()) {
- parseContext.error((*$2)[i].line, "duplicate field name in structure:", "struct", (*$2)[i].type->getFieldName().c_str());
- parseContext.recover();
- }
- }
- $$->push_back((*$2)[i]);
- }
- }
- ;
-
-struct_declaration
- : type_specifier struct_declarator_list SEMICOLON {
- $$ = $2;
-
- if (parseContext.voidErrorCheck($1.line, (*$2)[0].type->getFieldName(), $1)) {
- parseContext.recover();
- }
- for (unsigned int i = 0; i < $$->size(); ++i) {
- //
- // Careful not to replace already know aspects of type, like array-ness
- //
- (*$$)[i].type->setType($1.type, $1.size, $1.matrix, $1.userDef);
- if ($1.userDef)
- (*$$)[i].type->setTypeName($1.userDef->getTypeName());
- }
- }
- ;
-
-struct_declarator_list
- : struct_declarator {
- $$ = NewPoolTTypeList();
- $$->push_back($1);
- }
- | struct_declarator_list COMMA struct_declarator {
- $$->push_back($3);
- }
- ;
-
-struct_declarator
- : IDENTIFIER {
- $$.type = new TType(EbtVoid);
- $$.line = $1.line;
- $$.type->setFieldName(*$1.string);
- }
- | IDENTIFIER LEFT_BRACKET constant_expression RIGHT_BRACKET {
- $$.type = new TType(EbtVoid);
- $$.line = $1.line;
- $$.type->setFieldName(*$1.string);
-
- if ($3->getAsConstantUnion() == 0 || $3->getAsConstantUnion()->getBasicType() != EbtInt ||
- $3->getAsConstantUnion()->getUnionArrayPointer()->iConst <= 0) {
- parseContext.error($2.line, "structure field array size must be a positive integer", $1.string->c_str(), "");
- parseContext.recover();
- } else {
- $$.type->setArraySize($3->getAsConstantUnion()->getUnionArrayPointer()->iConst);
- }
- }
- ;
-
-initializer
- : assignment_expression { $$ = $1; }
- ;
-
-declaration_statement
- : declaration { $$ = $1; }
- ;
-
-statement
- : compound_statement { $$ = $1; }
- | simple_statement { $$ = $1; }
- ;
-
-// Grammar Note: No labeled statements; 'goto' is not supported.
-
-simple_statement
- : declaration_statement { $$ = $1; }
- | expression_statement { $$ = $1; }
- | selection_statement { $$ = $1; }
- | iteration_statement { $$ = $1; }
- | jump_statement { $$ = $1; }
- ;
-
-compound_statement
- : LEFT_BRACE RIGHT_BRACE { $$ = 0; }
- | LEFT_BRACE { parseContext.symbolTable.push(); } statement_list { parseContext.symbolTable.pop(); } RIGHT_BRACE {
- if ($3 != 0)
- $3->setOperator(EOpSequence);
- $$ = $3;
- }
- ;
-
-statement_no_new_scope
- : compound_statement_no_new_scope { $$ = $1; }
- | simple_statement { $$ = $1; }
- ;
-
-compound_statement_no_new_scope
- // Statement that doesn't create a new scope, for selection_statement, iteration_statement
- : LEFT_BRACE RIGHT_BRACE {
- $$ = 0;
- }
- | LEFT_BRACE statement_list RIGHT_BRACE {
- if ($2)
- $2->setOperator(EOpSequence);
- $$ = $2;
- }
- ;
-
-statement_list
- : statement {
- $$ = parseContext.intermediate.makeAggregate($1, 0);
- }
- | statement_list statement {
- $$ = parseContext.intermediate.growAggregate($1, $2, 0);
- }
- ;
-
-expression_statement
- : SEMICOLON { $$ = 0; }
- | expression SEMICOLON { $$ = static_cast<TIntermNode*>($1); }
- ;
-
-selection_statement
- : IF LEFT_PAREN expression RIGHT_PAREN selection_rest_statement {
- if (parseContext.boolErrorCheck($1.line, $3))
- parseContext.recover();
- $$ = parseContext.intermediate.addSelection($3, $5, $1.line);
- }
- ;
-
-selection_rest_statement
- : statement ELSE statement {
- $$.node1 = $1;
- $$.node2 = $3;
- }
- | statement {
- $$.node1 = $1;
- $$.node2 = 0;
- }
- ;
-
-// Grammar Note: No 'switch'. Switch statements not supported.
-
-condition
- // In 1996 c++ draft, conditions can include single declarations
- : expression {
- $$ = $1;
- if (parseContext.boolErrorCheck($1->getLine(), $1))
- parseContext.recover();
- }
- | fully_specified_type IDENTIFIER EQUAL initializer {
- TIntermNode* intermNode;
- if (parseContext.structQualifierErrorCheck($2.line, $1))
- parseContext.recover();
- if (parseContext.boolErrorCheck($2.line, $1))
- parseContext.recover();
-
- if (!parseContext.executeInitializer($2.line, *$2.string, $1, $4, intermNode))
- $$ = $4;
- else {
- parseContext.recover();
- $$ = 0;
- }
- }
- ;
-
-iteration_statement
- : WHILE LEFT_PAREN { parseContext.symbolTable.push(); ++parseContext.loopNestingLevel; } condition RIGHT_PAREN statement_no_new_scope {
- parseContext.symbolTable.pop();
- $$ = parseContext.intermediate.addLoop($6, $4, 0, true, $1.line);
- --parseContext.loopNestingLevel;
- }
- | DO { ++parseContext.loopNestingLevel; } statement WHILE LEFT_PAREN expression RIGHT_PAREN SEMICOLON {
- if (parseContext.boolErrorCheck($8.line, $6))
- parseContext.recover();
-
- $$ = parseContext.intermediate.addLoop($3, $6, 0, false, $4.line);
- --parseContext.loopNestingLevel;
- }
- | FOR LEFT_PAREN { parseContext.symbolTable.push(); ++parseContext.loopNestingLevel; } for_init_statement for_rest_statement RIGHT_PAREN statement_no_new_scope {
- parseContext.symbolTable.pop();
- $$ = parseContext.intermediate.makeAggregate($4, $2.line);
- $$ = parseContext.intermediate.growAggregate(
- $$,
- parseContext.intermediate.addLoop($7, reinterpret_cast<TIntermTyped*>($5.node1), reinterpret_cast<TIntermTyped*>($5.node2), true, $1.line),
- $1.line);
- $$->getAsAggregate()->setOperator(EOpSequence);
- --parseContext.loopNestingLevel;
- }
- ;
-
-for_init_statement
- : expression_statement {
- $$ = $1;
- }
- | declaration_statement {
- $$ = $1;
- }
- ;
-
-conditionopt
- : condition {
- $$ = $1;
- }
- | /* May be null */ {
- $$ = 0;
- }
- ;
-
-for_rest_statement
- : conditionopt SEMICOLON {
- $$.node1 = $1;
- $$.node2 = 0;
- }
- | conditionopt SEMICOLON expression {
- $$.node1 = $1;
- $$.node2 = $3;
- }
- ;
-
-jump_statement
- : CONTINUE SEMICOLON {
- if (parseContext.loopNestingLevel <= 0) {
- parseContext.error($1.line, "continue statement only allowed in loops", "", "");
- parseContext.recover();
- }
- $$ = parseContext.intermediate.addBranch(EOpContinue, $1.line);
- }
- | BREAK SEMICOLON {
- if (parseContext.loopNestingLevel <= 0) {
- parseContext.error($1.line, "break statement only allowed in loops", "", "");
- parseContext.recover();
- }
- $$ = parseContext.intermediate.addBranch(EOpBreak, $1.line);
- }
- | RETURN SEMICOLON {
- $$ = parseContext.intermediate.addBranch(EOpReturn, $1.line);
- if (parseContext.currentFunctionType->getBasicType() != EbtVoid) {
- parseContext.error($1.line, "non-void function must return a value", "return", "");
- parseContext.recover();
- }
- }
- | RETURN expression SEMICOLON {
- $$ = parseContext.intermediate.addBranch(EOpReturn, $2, $1.line);
- parseContext.functionReturnsValue = true;
- if (parseContext.currentFunctionType->getBasicType() == EbtVoid) {
- parseContext.error($1.line, "void function cannot return a value", "return", "");
- parseContext.recover();
- } else if (*(parseContext.currentFunctionType) != $2->getType()) {
- parseContext.error($1.line, "function return is not matching type:", "return", "");
- parseContext.recover();
- }
- }
- | DISCARD SEMICOLON {
- FRAG_ONLY("discard", $1.line);
- $$ = parseContext.intermediate.addBranch(EOpKill, $1.line);
- }
- ;
-
-// Grammar Note: No 'goto'. Gotos are not supported.
-
-translation_unit
- : external_declaration {
- $$ = $1;
- parseContext.treeRoot = $$;
- }
- | translation_unit external_declaration {
- $$ = parseContext.intermediate.growAggregate($1, $2, 0);
- parseContext.treeRoot = $$;
- }
- ;
-
-external_declaration
- : function_definition {
- $$ = $1;
- }
- | declaration {
- $$ = $1;
- }
- ;
-
-function_definition
- : function_prototype {
- TFunction& function = *($1.function);
- TFunction* prevDec = static_cast<TFunction*>(parseContext.symbolTable.find(function.getMangledName()));
- //
- // Note: 'prevDec' could be 'function' if this is the first time we've seen function
- // as it would have just been put in the symbol table. Otherwise, we're looking up
- // an earlier occurance.
- //
- if (prevDec->isDefined()) {
- //
- // Then this function already has a body.
- //
- parseContext.error($1.line, "function already has a body", function.getName().c_str(), "");
- parseContext.recover();
- }
- prevDec->setDefined();
-
- //
- // Raise error message if main function takes any parameters or return anything other than void
- //
- if (function.getName() == "main") {
- if (function.getParamCount() > 0) {
- parseContext.error($1.line, "function cannot take any parameter(s)", function.getName().c_str(), "");
- parseContext.recover();
- }
- if (function.getReturnType().getBasicType() != EbtVoid) {
- parseContext.error($1.line, "", function.getReturnType().getBasicString(), "main function cannot return a value" );
- parseContext.recover();
- }
- }
-
- //
- // New symbol table scope for body of function plus its arguments
- //
- parseContext.symbolTable.push();
-
- //
- // Remember the return type for later checking for RETURN statements.
- //
- parseContext.currentFunctionType = &(prevDec->getReturnType());
- parseContext.functionReturnsValue = false;
-
- //
- // Insert parameters into the symbol table.
- // If the parameter has no name, it's not an error, just don't insert it
- // (could be used for unused args).
- //
- // Also, accumulate the list of parameters into the HIL, so lower level code
- // knows where to find parameters.
- //
- TIntermAggregate* paramNodes = new TIntermAggregate;
- for (int i = 0; i < function.getParamCount(); i++) {
- TParameter& param = function[i];
- if (param.name != 0) {
- TVariable *variable = new TVariable(param.name, *param.type);
- //
- // Insert the parameters with name in the symbol table.
- //
- if (! parseContext.symbolTable.insert(*variable)) {
- parseContext.error($1.line, "redefinition", variable->getName().c_str(), "");
- parseContext.recover();
- delete variable;
- }
- //
- // Transfer ownership of name pointer to symbol table.
- //
- param.name = 0;
-
- //
- // Add the parameter to the HIL
- //
- paramNodes = parseContext.intermediate.growAggregate(
- paramNodes,
- parseContext.intermediate.addSymbol(variable->getUniqueId(),
- variable->getName(),
- variable->getType(), $1.line),
- $1.line);
- } else {
- paramNodes = parseContext.intermediate.growAggregate(paramNodes, parseContext.intermediate.addSymbol(0, "", *param.type, $1.line), $1.line);
- }
- }
- parseContext.intermediate.setAggregateOperator(paramNodes, EOpParameters, $1.line);
- $1.intermAggregate = paramNodes;
- parseContext.loopNestingLevel = 0;
- }
- compound_statement_no_new_scope {
- //?? Check that all paths return a value if return type != void ?
- // May be best done as post process phase on intermediate code
- if (parseContext.currentFunctionType->getBasicType() != EbtVoid && ! parseContext.functionReturnsValue) {
- parseContext.error($1.line, "function does not return a value:", "", $1.function->getName().c_str());
- parseContext.recover();
- }
- parseContext.symbolTable.pop();
- $$ = parseContext.intermediate.growAggregate($1.intermAggregate, $3, 0);
- parseContext.intermediate.setAggregateOperator($$, EOpFunction, $1.line);
- $$->getAsAggregate()->setName($1.function->getMangledName().c_str());
- $$->getAsAggregate()->setType($1.function->getReturnType());
-
- // store the pragma information for debug and optimize and other vendor specific
- // information. This information can be queried from the parse tree
- $$->getAsAggregate()->setOptimize(parseContext.contextPragma.optimize);
- $$->getAsAggregate()->setDebug(parseContext.contextPragma.debug);
- $$->getAsAggregate()->addToPragmaTable(parseContext.contextPragma.pragmaTable);
- }
- ;
-
-%%
diff --git a/src/mesa/shader/slang/MachineIndependent/glslang_tab.h b/src/mesa/shader/slang/MachineIndependent/glslang_tab.h deleted file mode 100755 index 97d827fe90..0000000000 --- a/src/mesa/shader/slang/MachineIndependent/glslang_tab.h +++ /dev/null @@ -1,260 +0,0 @@ -/* A Bison parser, made by GNU Bison 1.875. */ - -/* Skeleton parser for Yacc-like parsing with Bison, - Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002 Free Software Foundation, Inc. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2, or (at your option) - any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, - Boston, MA 02111-1307, USA. */ - -/* As a special exception, when this file is copied by Bison into a - Bison output file, you may use that output file without restriction. - This special exception was added by the Free Software Foundation - in version 1.24 of Bison. */ - -/* Tokens. */ -#ifndef YYTOKENTYPE -# define YYTOKENTYPE - /* Put the tokens into the symbol table, so that GDB and other debuggers - know about them. */ - enum yytokentype { - ATTRIBUTE = 258, - CONST_QUAL = 259, - BOOL_TYPE = 260, - FLOAT_TYPE = 261, - INT_TYPE = 262, - BREAK = 263, - CONTINUE = 264, - DO = 265, - ELSE = 266, - FOR = 267, - IF = 268, - DISCARD = 269, - RETURN = 270, - BVEC2 = 271, - BVEC3 = 272, - BVEC4 = 273, - IVEC2 = 274, - IVEC3 = 275, - IVEC4 = 276, - VEC2 = 277, - VEC3 = 278, - VEC4 = 279, - MATRIX2 = 280, - MATRIX3 = 281, - MATRIX4 = 282, - IN_QUAL = 283, - OUT_QUAL = 284, - INOUT_QUAL = 285, - UNIFORM = 286, - VARYING = 287, - STRUCT = 288, - VOID_TYPE = 289, - WHILE = 290, - SAMPLER1D = 291, - SAMPLER2D = 292, - SAMPLER3D = 293, - SAMPLERCUBE = 294, - SAMPLER1DSHADOW = 295, - SAMPLER2DSHADOW = 296, - IDENTIFIER = 297, - TYPE_NAME = 298, - FLOATCONSTANT = 299, - INTCONSTANT = 300, - BOOLCONSTANT = 301, - FIELD_SELECTION = 302, - LEFT_OP = 303, - RIGHT_OP = 304, - INC_OP = 305, - DEC_OP = 306, - LE_OP = 307, - GE_OP = 308, - EQ_OP = 309, - NE_OP = 310, - AND_OP = 311, - OR_OP = 312, - XOR_OP = 313, - MUL_ASSIGN = 314, - DIV_ASSIGN = 315, - ADD_ASSIGN = 316, - MOD_ASSIGN = 317, - LEFT_ASSIGN = 318, - RIGHT_ASSIGN = 319, - AND_ASSIGN = 320, - XOR_ASSIGN = 321, - OR_ASSIGN = 322, - SUB_ASSIGN = 323, - LEFT_PAREN = 324, - RIGHT_PAREN = 325, - LEFT_BRACKET = 326, - RIGHT_BRACKET = 327, - LEFT_BRACE = 328, - RIGHT_BRACE = 329, - DOT = 330, - COMMA = 331, - COLON = 332, - EQUAL = 333, - SEMICOLON = 334, - BANG = 335, - DASH = 336, - TILDE = 337, - PLUS = 338, - STAR = 339, - SLASH = 340, - PERCENT = 341, - LEFT_ANGLE = 342, - RIGHT_ANGLE = 343, - VERTICAL_BAR = 344, - CARET = 345, - AMPERSAND = 346, - QUESTION = 347 - }; -#endif -#define ATTRIBUTE 258 -#define CONST_QUAL 259 -#define BOOL_TYPE 260 -#define FLOAT_TYPE 261 -#define INT_TYPE 262 -#define BREAK 263 -#define CONTINUE 264 -#define DO 265 -#define ELSE 266 -#define FOR 267 -#define IF 268 -#define DISCARD 269 -#define RETURN 270 -#define BVEC2 271 -#define BVEC3 272 -#define BVEC4 273 -#define IVEC2 274 -#define IVEC3 275 -#define IVEC4 276 -#define VEC2 277 -#define VEC3 278 -#define VEC4 279 -#define MATRIX2 280 -#define MATRIX3 281 -#define MATRIX4 282 -#define IN_QUAL 283 -#define OUT_QUAL 284 -#define INOUT_QUAL 285 -#define UNIFORM 286 -#define VARYING 287 -#define STRUCT 288 -#define VOID_TYPE 289 -#define WHILE 290 -#define SAMPLER1D 291 -#define SAMPLER2D 292 -#define SAMPLER3D 293 -#define SAMPLERCUBE 294 -#define SAMPLER1DSHADOW 295 -#define SAMPLER2DSHADOW 296 -#define IDENTIFIER 297 -#define TYPE_NAME 298 -#define FLOATCONSTANT 299 -#define INTCONSTANT 300 -#define BOOLCONSTANT 301 -#define FIELD_SELECTION 302 -#define LEFT_OP 303 -#define RIGHT_OP 304 -#define INC_OP 305 -#define DEC_OP 306 -#define LE_OP 307 -#define GE_OP 308 -#define EQ_OP 309 -#define NE_OP 310 -#define AND_OP 311 -#define OR_OP 312 -#define XOR_OP 313 -#define MUL_ASSIGN 314 -#define DIV_ASSIGN 315 -#define ADD_ASSIGN 316 -#define MOD_ASSIGN 317 -#define LEFT_ASSIGN 318 -#define RIGHT_ASSIGN 319 -#define AND_ASSIGN 320 -#define XOR_ASSIGN 321 -#define OR_ASSIGN 322 -#define SUB_ASSIGN 323 -#define LEFT_PAREN 324 -#define RIGHT_PAREN 325 -#define LEFT_BRACKET 326 -#define RIGHT_BRACKET 327 -#define LEFT_BRACE 328 -#define RIGHT_BRACE 329 -#define DOT 330 -#define COMMA 331 -#define COLON 332 -#define EQUAL 333 -#define SEMICOLON 334 -#define BANG 335 -#define DASH 336 -#define TILDE 337 -#define PLUS 338 -#define STAR 339 -#define SLASH 340 -#define PERCENT 341 -#define LEFT_ANGLE 342 -#define RIGHT_ANGLE 343 -#define VERTICAL_BAR 344 -#define CARET 345 -#define AMPERSAND 346 -#define QUESTION 347 - - - - -#if ! defined (YYSTYPE) && ! defined (YYSTYPE_IS_DECLARED) -#line 117 "glslang.y" -typedef union YYSTYPE { - struct { - TSourceLoc line; - union { - TString *string; - float f; - int i; - bool b; - }; - TSymbol* symbol; - } lex; - struct { - TSourceLoc line; - TOperator op; - union { - TIntermNode* intermNode; - TIntermNodePair nodePair; - TIntermTyped* intermTypedNode; - TIntermAggregate* intermAggregate; - }; - union { - TPublicType type; - TQualifier qualifier; - TFunction* function; - TParameter param; - TTypeLine typeLine; - TTypeList* typeList; - }; - } interm; -} YYSTYPE; -/* Line 1240 of yacc.c. */ -#line 251 "glslang.tab.h" -# define yystype YYSTYPE /* obsolescent; will be withdrawn */ -# define YYSTYPE_IS_DECLARED 1 -# define YYSTYPE_IS_TRIVIAL 1 -#endif - - - - - diff --git a/src/mesa/shader/slang/MachineIndependent/intermOut.cpp b/src/mesa/shader/slang/MachineIndependent/intermOut.cpp deleted file mode 100755 index e75608c45a..0000000000 --- a/src/mesa/shader/slang/MachineIndependent/intermOut.cpp +++ /dev/null @@ -1,496 +0,0 @@ -//
-//Copyright (C) 2002-2005 3Dlabs Inc. Ltd.
-//All rights reserved.
-//
-//Redistribution and use in source and binary forms, with or without
-//modification, are permitted provided that the following conditions
-//are met:
-//
-// Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//
-// Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-//
-// Neither the name of 3Dlabs Inc. Ltd. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-//THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-//"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-//LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
-//FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
-//COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
-//INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
-//BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
-//LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
-//CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-//LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
-//ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
-//POSSIBILITY OF SUCH DAMAGE.
-//
-
-#include "localintermediate.h"
-#include "../Include/ShHandle.h"
-
-//
-// Two purposes:
-// 1. Show an example of how to iterate tree. Functions can
-// also directly call Traverse() on children themselves to
-// have finer grained control over the process than shown here.
-// See the last function for how to get started.
-// 2. Print out a text based description of the tree.
-//
-
-//
-// Use this class to carry along data from node to node in
-// the traversal
-//
-class TOutputTraverser : public TIntermTraverser {
-public:
- TOutputTraverser(TInfoSink& i) : infoSink(i) { }
- TInfoSink& infoSink;
-};
-
-TString TType::getCompleteString() const
-{
- char buf[100];
- char *p = &buf[0];
-
- if (qualifier != EvqTemporary && qualifier != EvqGlobal)
- p += sprintf(p, "%s ", getQualifierString());
- if (array)
- p += sprintf(p, "array of ");
- if (matrix)
- p += sprintf(p, "%dX%d matrix of ", size, size);
- else if (size > 1)
- p += sprintf(p, "%d-component vector of ", size);
-
- sprintf(p, "%s", getBasicString());
-
- return TString(buf);
-}
-
-//
-// Helper functions for printing, not part of traversing.
-//
-
-void OutputTreeText(TInfoSink& infoSink, TIntermNode* node, const int depth)
-{
- int i;
-
- infoSink.debug << FormatSourceLoc(node->getLine());
-
- for (i = 0; i < depth; ++i)
- infoSink.debug << " ";
-}
-
-//
-// The rest of the file are the traversal functions. The last one
-// is the one that starts the traversal.
-//
-// Return true from interior nodes to have the external traversal
-// continue on to children. If you process children yourself,
-// return false.
-//
-
-void OutputSymbol(TIntermSymbol* node, TIntermTraverser* it)
-{
- TOutputTraverser* oit = static_cast<TOutputTraverser*>(it);
-
- OutputTreeText(oit->infoSink, node, oit->depth);
-
- char buf[100];
- sprintf(buf, "'%s' (%s)\n",
- node->getSymbol().c_str(),
- node->getCompleteString().c_str());
-
- oit->infoSink.debug << buf;
-}
-
-bool OutputBinary(bool /* preVisit */, TIntermBinary* node, TIntermTraverser* it)
-{
- TOutputTraverser* oit = static_cast<TOutputTraverser*>(it);
- TInfoSink& out = oit->infoSink;
-
- OutputTreeText(out, node, oit->depth);
-
- switch (node->getOp()) {
- case EOpAssign: out.debug << "move second child to first child"; break;
- case EOpAddAssign: out.debug << "add second child into first child"; break;
- case EOpSubAssign: out.debug << "subtract second child into first child"; break;
- case EOpMulAssign: out.debug << "multiply second child into first child"; break;
- case EOpVectorTimesMatrixAssign: out.debug << "matrix mult second child into first child"; break;
- case EOpVectorTimesScalarAssign: out.debug << "vector scale second child into first child"; break;
- case EOpMatrixTimesScalarAssign: out.debug << "matrix scale second child into first child"; break;
- case EOpMatrixTimesMatrixAssign: out.debug << "matrix mult second child into first child"; break;
- case EOpDivAssign: out.debug << "divide second child into first child"; break;
- case EOpModAssign: out.debug << "mod second child into first child"; break;
- case EOpAndAssign: out.debug << "and second child into first child"; break;
- case EOpInclusiveOrAssign: out.debug << "or second child into first child"; break;
- case EOpExclusiveOrAssign: out.debug << "exclusive or second child into first child"; break;
- case EOpLeftShiftAssign: out.debug << "left shift second child into first child"; break;
- case EOpRightShiftAssign: out.debug << "right shift second child into first child"; break;
-
- case EOpIndexDirect: out.debug << "direct index"; break;
- case EOpIndexIndirect: out.debug << "indirect index"; break;
- case EOpIndexDirectStruct: out.debug << "direct index for structure"; break;
- case EOpVectorSwizzle: out.debug << "vector swizzle"; break;
-
- case EOpAdd: out.debug << "add"; break;
- case EOpSub: out.debug << "subtract"; break;
- case EOpMul: out.debug << "component-wise multiply"; break;
- case EOpDiv: out.debug << "divide"; break;
- case EOpMod: out.debug << "mod"; break;
- case EOpRightShift: out.debug << "right-shift"; break;
- case EOpLeftShift: out.debug << "left-shift"; break;
- case EOpAnd: out.debug << "bitwise and"; break;
- case EOpInclusiveOr: out.debug << "inclusive-or"; break;
- case EOpExclusiveOr: out.debug << "exclusive-or"; break;
- case EOpEqual: out.debug << "Compare Equal"; break;
- case EOpNotEqual: out.debug << "Compare Not Equal"; break;
- case EOpLessThan: out.debug << "Compare Less Than"; break;
- case EOpGreaterThan: out.debug << "Compare Greater Than"; break;
- case EOpLessThanEqual: out.debug << "Compare Less Than or Equal"; break;
- case EOpGreaterThanEqual: out.debug << "Compare Greater Than or Equal"; break;
-
- case EOpVectorTimesScalar: out.debug << "vector-scale"; break;
- case EOpVectorTimesMatrix: out.debug << "vector-times-matrix"; break;
- case EOpMatrixTimesVector: out.debug << "matrix-times-vector"; break;
- case EOpMatrixTimesScalar: out.debug << "matrix-scale"; break;
- case EOpMatrixTimesMatrix: out.debug << "matrix-multiply"; break;
-
- case EOpLogicalOr: out.debug << "logical-or"; break;
- case EOpLogicalXor: out.debug << "logical-xor"; break;
- case EOpLogicalAnd: out.debug << "logical-and"; break;
- default: out.debug << "<unknown op>";
- }
-
- out.debug << " (" << node->getCompleteString() << ")";
-
- out.debug << "\n";
-
- return true;
-}
-
-bool OutputUnary(bool /* preVisit */, TIntermUnary* node, TIntermTraverser* it)
-{
- TOutputTraverser* oit = static_cast<TOutputTraverser*>(it);
- TInfoSink& out = oit->infoSink;
-
- OutputTreeText(out, node, oit->depth);
-
- switch (node->getOp()) {
- case EOpNegative: out.debug << "Negate value"; break;
- case EOpVectorLogicalNot:
- case EOpLogicalNot: out.debug << "Negate conditional"; break;
- case EOpBitwiseNot: out.debug << "Bitwise not"; break;
-
- case EOpPostIncrement: out.debug << "Post-Increment"; break;
- case EOpPostDecrement: out.debug << "Post-Decrement"; break;
- case EOpPreIncrement: out.debug << "Pre-Increment"; break;
- case EOpPreDecrement: out.debug << "Pre-Decrement"; break;
-
- case EOpConvIntToBool: out.debug << "Convert int to bool"; break;
- case EOpConvFloatToBool:out.debug << "Convert float to bool";break;
- case EOpConvBoolToFloat:out.debug << "Convert bool to float";break;
- case EOpConvIntToFloat: out.debug << "Convert int to float"; break;
- case EOpConvFloatToInt: out.debug << "Convert float to int"; break;
- case EOpConvBoolToInt: out.debug << "Convert bool to int"; break;
-
- case EOpRadians: out.debug << "radians"; break;
- case EOpDegrees: out.debug << "degrees"; break;
- case EOpSin: out.debug << "sine"; break;
- case EOpCos: out.debug << "cosine"; break;
- case EOpTan: out.debug << "tangent"; break;
- case EOpAsin: out.debug << "arc sine"; break;
- case EOpAcos: out.debug << "arc cosine"; break;
- case EOpAtan: out.debug << "arc tangent"; break;
-
- case EOpExp: out.debug << "exp"; break;
- case EOpLog: out.debug << "log"; break;
- case EOpExp2: out.debug << "exp2"; break;
- case EOpLog2: out.debug << "log2"; break;
- case EOpSqrt: out.debug << "sqrt"; break;
- case EOpInverseSqrt: out.debug << "inverse sqrt"; break;
-
- case EOpAbs: out.debug << "Absolute value"; break;
- case EOpSign: out.debug << "Sign"; break;
- case EOpFloor: out.debug << "Floor"; break;
- case EOpCeil: out.debug << "Ceiling"; break;
- case EOpFract: out.debug << "Fraction"; break;
-
- case EOpLength: out.debug << "length"; break;
- case EOpNormalize: out.debug << "normalize"; break;
- case EOpDPdx: out.debug << "dPdx"; break;
- case EOpDPdy: out.debug << "dPdy"; break;
- case EOpFwidth: out.debug << "fwidth"; break;
-
- case EOpAny: out.debug << "any"; break;
- case EOpAll: out.debug << "all"; break;
-
- default: out.debug.message(EPrefixError, "Bad unary op");
- }
-
- out.debug << " (" << node->getCompleteString() << ")";
-
- out.debug << "\n";
-
- return true;
-}
-
-bool OutputAggregate(bool /* preVisit */, TIntermAggregate* node, TIntermTraverser* it)
-{
- TOutputTraverser* oit = static_cast<TOutputTraverser*>(it);
- TInfoSink& out = oit->infoSink;
-
- if (node->getOp() == EOpNull) {
- out.debug.message(EPrefixError, "node is still EOpNull!");
- return true;
- }
-
- OutputTreeText(out, node, oit->depth);
-
- switch (node->getOp()) {
- case EOpSequence: out.debug << "Sequence\n"; return true;
- case EOpComma: out.debug << "Comma\n"; return true;
- case EOpFunction: out.debug << "Function Definition: " << node->getName(); break;
- case EOpFunctionCall: out.debug << "Function Call: " << node->getName(); break;
- case EOpParameters: out.debug << "Function Parameters: "; break;
-
- case EOpConstructFloat: out.debug << "Construct float"; break;
- case EOpConstructVec2: out.debug << "Construct vec2"; break;
- case EOpConstructVec3: out.debug << "Construct vec3"; break;
- case EOpConstructVec4: out.debug << "Construct vec4"; break;
- case EOpConstructBool: out.debug << "Construct bool"; break;
- case EOpConstructBVec2: out.debug << "Construct bvec2"; break;
- case EOpConstructBVec3: out.debug << "Construct bvec3"; break;
- case EOpConstructBVec4: out.debug << "Construct bvec4"; break;
- case EOpConstructInt: out.debug << "Construct int"; break;
- case EOpConstructIVec2: out.debug << "Construct ivec2"; break;
- case EOpConstructIVec3: out.debug << "Construct ivec3"; break;
- case EOpConstructIVec4: out.debug << "Construct ivec4"; break;
- case EOpConstructMat2: out.debug << "Construct mat2"; break;
- case EOpConstructMat3: out.debug << "Construct mat3"; break;
- case EOpConstructMat4: out.debug << "Construct mat4"; break;
- case EOpConstructStruct: out.debug << "Construct structure"; break;
-
- case EOpLessThan: out.debug << "Compare Less Than"; break;
- case EOpGreaterThan: out.debug << "Compare Greater Than"; break;
- case EOpLessThanEqual: out.debug << "Compare Less Than or Equal"; break;
- case EOpGreaterThanEqual: out.debug << "Compare Greater Than or Equal"; break;
- case EOpVectorEqual: out.debug << "Equal"; break;
- case EOpVectorNotEqual: out.debug << "NotEqual"; break;
-
- case EOpMod: out.debug << "mod"; break;
- case EOpPow: out.debug << "pow"; break;
-
- case EOpAtan: out.debug << "arc tangent"; break;
-
- case EOpMin: out.debug << "min"; break;
- case EOpMax: out.debug << "max"; break;
- case EOpClamp: out.debug << "clamp"; break;
- case EOpMix: out.debug << "mix"; break;
- case EOpStep: out.debug << "step"; break;
- case EOpSmoothStep: out.debug << "smoothstep"; break;
-
- case EOpDistance: out.debug << "distance"; break;
- case EOpDot: out.debug << "dot-product"; break;
- case EOpCross: out.debug << "cross-product"; break;
- case EOpFaceForward: out.debug << "face-forward"; break;
- case EOpReflect: out.debug << "reflect"; break;
- case EOpRefract: out.debug << "refract"; break;
- case EOpMul: out.debug << "component-wise multiply"; break;
-
- case EOpItof: out.debug << "itof"; break;
- case EOpFtoi: out.debug << "ftoi"; break;
- case EOpSkipPixels: out.debug << "skipPixels"; break;
- case EOpReadInput: out.debug << "readInput"; break;
- case EOpWritePixel: out.debug << "writePixel"; break;
- case EOpBitmapLsb: out.debug << "bitmapLSB"; break;
- case EOpBitmapMsb: out.debug << "bitmapMSB"; break;
- case EOpWriteOutput: out.debug << "writeOutput"; break;
- case EOpReadPixel: out.debug << "readPixel"; break;
-
- default: out.debug.message(EPrefixError, "Bad aggregation op");
- }
-
- if (node->getOp() != EOpSequence && node->getOp() != EOpParameters)
- out.debug << " (" << node->getCompleteString() << ")";
-
- out.debug << "\n";
-
- return true;
-}
-
-bool OutputSelection(bool /* preVisit */, TIntermSelection* node, TIntermTraverser* it)
-{
- TOutputTraverser* oit = static_cast<TOutputTraverser*>(it);
- TInfoSink& out = oit->infoSink;
-
- OutputTreeText(out, node, oit->depth);
-
- out.debug << "Test condition and select";
- out.debug << " (" << node->getCompleteString() << ")\n";
-
- ++oit->depth;
-
- OutputTreeText(oit->infoSink, node, oit->depth);
- out.debug << "Condition\n";
- node->getCondition()->traverse(it);
-
- OutputTreeText(oit->infoSink, node, oit->depth);
- if (node->getTrueBlock()) {
- out.debug << "true case\n";
- node->getTrueBlock()->traverse(it);
- } else
- out.debug << "true case is null\n";
-
- if (node->getFalseBlock()) {
- OutputTreeText(oit->infoSink, node, oit->depth);
- out.debug << "false case\n";
- node->getFalseBlock()->traverse(it);
- }
-
- --oit->depth;
-
- return false;
-}
-
-void OutputConstantUnion(TIntermConstantUnion* node, TIntermTraverser* it)
-{
- TOutputTraverser* oit = static_cast<TOutputTraverser*>(it);
- TInfoSink& out = oit->infoSink;
-
- int size = 0;
- if (node->getType().getBasicType() == EbtStruct)
- size = node->getType().getStructSize();
- else
- size = node->getType().getInstanceSize();
-
- for (int i = 0; i < size; i++) {
- OutputTreeText(out, node, oit->depth);
- switch (node->getType().getBasicType()) {
- case EbtBool:
- if (node->getUnionArrayPointer()[i].bConst)
- out.debug << "true";
- else
- out.debug << "false";
-
- out.debug << " (" << "const bool" << ")";
-
- out.debug << "\n";
- break;
- case EbtFloat:
- {
- char buf[300];
- sprintf(buf, "%f (%s)", node->getUnionArrayPointer()[i].fConst, "const float");
-
- out.debug << buf << "\n";
- }
- break;
- case EbtInt:
- {
- char buf[300];
- sprintf(buf, "%d (%s)", node->getUnionArrayPointer()[i].iConst, "const int");
-
- out.debug << buf << "\n";
- break;
- }
- default:
- out.info.message(EPrefixInternalError, "Unknown constant", node->getLine());
- break;
- }
- }
-}
-
-bool OutputLoop(bool /* preVisit */, TIntermLoop* node, TIntermTraverser* it)
-{
- TOutputTraverser* oit = static_cast<TOutputTraverser*>(it);
- TInfoSink& out = oit->infoSink;
-
- OutputTreeText(out, node, oit->depth);
-
- out.debug << "Loop with condition ";
- if (! node->testFirst())
- out.debug << "not ";
- out.debug << "tested first\n";
-
- ++oit->depth;
-
- OutputTreeText(oit->infoSink, node, oit->depth);
- if (node->getTest()) {
- out.debug << "Loop Condition\n";
- node->getTest()->traverse(it);
- } else
- out.debug << "No loop condition\n";
-
- OutputTreeText(oit->infoSink, node, oit->depth);
- if (node->getBody()) {
- out.debug << "Loop Body\n";
- node->getBody()->traverse(it);
- } else
- out.debug << "No loop body\n";
-
- if (node->getTerminal()) {
- OutputTreeText(oit->infoSink, node, oit->depth);
- out.debug << "Loop Terminal Expression\n";
- node->getTerminal()->traverse(it);
- }
-
- --oit->depth;
-
- return false;
-}
-
-bool OutputBranch(bool /* previsit*/, TIntermBranch* node, TIntermTraverser* it)
-{
- TOutputTraverser* oit = static_cast<TOutputTraverser*>(it);
- TInfoSink& out = oit->infoSink;
-
- OutputTreeText(out, node, oit->depth);
-
- switch (node->getFlowOp()) {
- case EOpKill: out.debug << "Branch: Kill"; break;
- case EOpBreak: out.debug << "Branch: Break"; break;
- case EOpContinue: out.debug << "Branch: Continue"; break;
- case EOpReturn: out.debug << "Branch: Return"; break;
- default: out.debug << "Branch: Unknown Branch"; break;
- }
-
- if (node->getExpression()) {
- out.debug << " with expression\n";
- ++oit->depth;
- node->getExpression()->traverse(it);
- --oit->depth;
- } else
- out.debug << "\n";
-
- return false;
-}
-
-//
-// This function is the one to call externally to start the traversal.
-// Individual functions can be initialized to 0 to skip processing of that
-// type of node. It's children will still be processed.
-//
-void TIntermediate::outputTree(TIntermNode* root)
-{
- if (root == 0)
- return;
-
- TOutputTraverser it(infoSink);
-
- it.visitAggregate = OutputAggregate;
- it.visitBinary = OutputBinary;
- it.visitConstantUnion = OutputConstantUnion;
- it.visitSelection = OutputSelection;
- it.visitSymbol = OutputSymbol;
- it.visitUnary = OutputUnary;
- it.visitLoop = OutputLoop;
- it.visitBranch = OutputBranch;
-
- root->traverse(&it);
-}
diff --git a/src/mesa/shader/slang/MachineIndependent/localintermediate.h b/src/mesa/shader/slang/MachineIndependent/localintermediate.h deleted file mode 100755 index 5b4e5ea118..0000000000 --- a/src/mesa/shader/slang/MachineIndependent/localintermediate.h +++ /dev/null @@ -1,91 +0,0 @@ -//
-//Copyright (C) 2002-2005 3Dlabs Inc. Ltd.
-//All rights reserved.
-//
-//Redistribution and use in source and binary forms, with or without
-//modification, are permitted provided that the following conditions
-//are met:
-//
-// Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//
-// Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-//
-// Neither the name of 3Dlabs Inc. Ltd. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-//THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-//"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-//LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
-//FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
-//COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
-//INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
-//BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
-//LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
-//CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-//LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
-//ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
-//POSSIBILITY OF SUCH DAMAGE.
-//
-
-#ifndef _LOCAL_INTERMEDIATE_INCLUDED_
-#define _LOCAL_INTERMEDIATE_INCLUDED_
-
-#include "../Include/intermediate.h"
-#include "../Public/ShaderLang.h"
-#include "SymbolTable.h"
-
-struct TVectorFields {
- int offsets[4];
- int num;
-};
-
-//
-// Set of helper functions to help parse and build the tree.
-//
-class TInfoSink;
-class TIntermediate {
-public:
- POOL_ALLOCATOR_NEW_DELETE(GlobalPoolAllocator)
-
- TIntermediate(TInfoSink& i) : infoSink(i) { }
- TIntermSymbol* addSymbol(int Id, const TString&, const TType&, TSourceLoc);
- TIntermTyped* addConversion(TOperator, const TType&, TIntermTyped*);
- TIntermTyped* addBinaryMath(TOperator op, TIntermTyped* left, TIntermTyped* right, TSourceLoc, TSymbolTable&);
- TIntermTyped* addAssign(TOperator op, TIntermTyped* left, TIntermTyped* right, TSourceLoc);
- TIntermTyped* addIndex(TOperator op, TIntermTyped* base, TIntermTyped* index, TSourceLoc);
- TIntermTyped* addUnaryMath(TOperator op, TIntermNode* child, TSourceLoc, TSymbolTable&);
- TIntermAggregate* growAggregate(TIntermNode* left, TIntermNode* right, TSourceLoc);
- TIntermAggregate* makeAggregate(TIntermNode* node, TSourceLoc);
- TIntermAggregate* setAggregateOperator(TIntermNode*, TOperator, TSourceLoc);
- TIntermNode* addSelection(TIntermTyped* cond, TIntermNodePair code, TSourceLoc);
- TIntermTyped* addSelection(TIntermTyped* cond, TIntermTyped* trueBlock, TIntermTyped* falseBlock, TSourceLoc);
- TIntermTyped* addComma(TIntermTyped* left, TIntermTyped* right, TSourceLoc);
- TIntermConstantUnion* addConstantUnion(constUnion*, const TType&, TSourceLoc);
- TIntermTyped* promoteConstantUnion(TBasicType, TIntermConstantUnion*) ;
- TIntermTyped* copyConstUnion(TIntermConstantUnion*) ;
- TIntermConstantUnion* changeAggrToTempConst(TIntermAggregate*, TSymbolTable&, TSourceLoc );
- bool parseConstTree(TSourceLoc, TIntermNode*, constUnion*, TOperator, TSymbolTable&, TType, bool singleConstantParam = false);
- TIntermNode* addLoop(TIntermNode*, TIntermTyped*, TIntermTyped*, bool testFirst, TSourceLoc);
- TIntermBranch* addBranch(TOperator, TSourceLoc);
- TIntermBranch* addBranch(TOperator, TIntermTyped*, TSourceLoc);
- TIntermTyped* addSwizzle(TVectorFields&, TSourceLoc);
- bool postProcess(TIntermNode*, EShLanguage);
- void remove(TIntermNode*);
- void outputTree(TIntermNode*);
- void removeChildNode(TIntermSequence&, TType&, int&, TIntermSequence::iterator&, TIntermAggregate*);
- TIntermTyped* removeChildNode(TIntermTyped*, TType*, TIntermAggregate*);
- bool removeMatrixConstNode(TIntermSequence&, TType&, TIntermAggregate*, int);
-
-protected:
- TInfoSink& infoSink;
-
-private:
- void operator=(TIntermediate&); // prevent assignments
-};
-
-#endif // _LOCAL_INTERMEDIATE_INCLUDED_
diff --git a/src/mesa/shader/slang/MachineIndependent/parseConst.cpp b/src/mesa/shader/slang/MachineIndependent/parseConst.cpp deleted file mode 100755 index 1ea91b3c52..0000000000 --- a/src/mesa/shader/slang/MachineIndependent/parseConst.cpp +++ /dev/null @@ -1,344 +0,0 @@ -//
-//Copyright (C) 2002-2005 3Dlabs Inc. Ltd.
-//All rights reserved.
-//
-//Redistribution and use in source and binary forms, with or without
-//modification, are permitted provided that the following conditions
-//are met:
-//
-// Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//
-// Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-//
-// Neither the name of 3Dlabs Inc. Ltd. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-//THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-//"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-//LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
-//FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
-//COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
-//INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
-//BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
-//LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
-//CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-//LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
-//ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
-//POSSIBILITY OF SUCH DAMAGE.
-//
-
-#include "ParseHelper.h"
-
-//
-// Use this class to carry along data from node to node in
-// the traversal
-//
-class TConstTraverser : public TIntermTraverser {
-public:
- TConstTraverser(constUnion* cUnion, bool singleConstParam, TOperator constructType, TInfoSink& sink, TSymbolTable& symTable, TType& t) : unionArray(cUnion), type(t),
- constructorType(constructType), singleConstantParam(singleConstParam), infoSink(sink), symbolTable(symTable), error(false), isMatrix(false), matrixSize(0) { index = 0; tOp = EOpNull;}
- int index ;
- constUnion *unionArray;
- TOperator tOp;
- TType type;
- TOperator constructorType;
- bool singleConstantParam;
- TInfoSink& infoSink;
- TSymbolTable& symbolTable;
- bool error;
- int size; // size of the constructor ( 4 for vec4)
- bool isMatrix;
- int matrixSize; // dimension of the matrix (nominal size and not the instance size)
-};
-
-//
-// The rest of the file are the traversal functions. The last one
-// is the one that starts the traversal.
-//
-// Return true from interior nodes to have the external traversal
-// continue on to children. If you process children yourself,
-// return false.
-//
-
-void ParseSymbol(TIntermSymbol* node, TIntermTraverser* it)
-{
- TConstTraverser* oit = static_cast<TConstTraverser*>(it);
- TQualifier qualifier = node->getType().getQualifier();
- constUnion* unionArray = oit->unionArray;
- int instanceSize;
- if (oit->type.getBasicType() == EbtStruct)
- instanceSize = oit->type.getStructSize();
- else
- instanceSize = oit->type.getInstanceSize();
-
- if (oit->index >= instanceSize)
- return;
-
- if (qualifier != EvqConst) {
- char buf[200];
- sprintf(buf, "'constructor' : assigning non-constant to %s", oit->type.getCompleteString().c_str());
- oit->infoSink.info.message(EPrefixError, buf, node->getLine());
- oit->error = true;
- return ;
- }
- TSymbol* symbol = oit->symbolTable.find(node->getSymbol());
- TVariable* tVar = static_cast<TVariable*>(symbol);
-
- constUnion* constArray = tVar->getConstPointer();
- if (!constArray) {
- char buf[200];
- sprintf(buf, "'constructor' : constant '%s' has not been initialized correctly", node->getSymbol().c_str());
- oit->infoSink.info.message(EPrefixError, buf, node->getLine());
- oit->error = true;
- return;
- }
- int symbolSize;
-
- if (tVar->getType().getBasicType() == EbtStruct)
- symbolSize = tVar->getType().getStructSize();
- else
- symbolSize = tVar->getType().getInstanceSize();
-
- // for constructors such as ivec4(vec4), if vec4 is a symbol node, then the appropriate conversion is required as the
- // types do not match
- for (int i = 0; i < symbolSize; i++) {
- if (oit->index >= instanceSize)
- return;
- if (tVar->getType().getBasicType() == oit->type.getBasicType() || oit->type.getBasicType() == EbtStruct)
- (unionArray[oit->index]) = constArray[i];
- else {
- switch (tVar->getType().getBasicType()) {
- case EbtFloat:
- switch (oit->type.getBasicType()) {
- case EbtInt: unionArray[oit->index].iConst = static_cast<int> (constArray[i].fConst); break;
- case EbtBool: unionArray[oit->index].bConst = constArray[i].fConst != 0.0; break;
- default: oit->infoSink.info.message(EPrefixInternalError, "Incorrect type, cannot parse symbol", node->getLine()); break;
- }
- break;
- case EbtInt:
- switch (oit->type.getBasicType()) {
- case EbtFloat: unionArray[oit->index].fConst = static_cast<float>(constArray[i].iConst); break;
- case EbtBool: unionArray[oit->index].bConst = constArray[i].iConst != 0 ; break;
- default: oit->infoSink.info.message(EPrefixInternalError, "Incorrect type, cannot parse symbol", node->getLine()); break;
- }
- break;
- case EbtBool:
- switch (oit->type.getBasicType()) {
- case EbtFloat: unionArray[oit->index].fConst = static_cast<float>(constArray[i].bConst); break;
- case EbtInt: unionArray[oit->index].iConst = static_cast<int> (constArray[i].bConst); break;
- default: oit->infoSink.info.message(EPrefixInternalError, "Incorrect type, cannot parse symbol", node->getLine()); break;
- }
- break;
- default: oit->infoSink.info.message(EPrefixInternalError, "Incorrect type, cannot parse symbol", node->getLine()); break;
- }
- }
- (oit->index)++;
- }
-}
-
-bool ParseBinary(bool /* preVisit */, TIntermBinary* node, TIntermTraverser* it)
-{
- TConstTraverser* oit = static_cast<TConstTraverser*>(it);
-
- TQualifier qualifier = node->getType().getQualifier();
-
- if (qualifier != EvqConst) {
- char buf[200];
- sprintf(buf, "'constructor' : assigning non-constant to %s", oit->type.getCompleteString().c_str());
- oit->infoSink.info.message(EPrefixError, buf, node->getLine());
- oit->error = true;
- return false;
- }
-
- oit->infoSink.info.message(EPrefixInternalError, "Binary Node found in constant constructor", node->getLine());
-
- return false;
-}
-
-bool ParseUnary(bool /* preVisit */, TIntermUnary* node, TIntermTraverser* it)
-{
- TConstTraverser* oit = static_cast<TConstTraverser*>(it);
-
- char buf[200];
- sprintf(buf, "'constructor' : assigning non-constant to '%s'", oit->type.getCompleteString().c_str());
- oit->infoSink.info.message(EPrefixError, buf, node->getLine());
- oit->error = true;
- return false;
-}
-
-bool ParseAggregate(bool /* preVisit */, TIntermAggregate* node, TIntermTraverser* it)
-{
- TConstTraverser* oit = static_cast<TConstTraverser*>(it);
-
- if (!node->isConstructor() && node->getOp() != EOpComma) {
- char buf[200];
- sprintf(buf, "'constructor' : assigning non-constant to '%s'", oit->type.getCompleteString().c_str());
- oit->infoSink.info.message(EPrefixError, buf, node->getLine());
- oit->error = true;
- return false;
- }
-
- if (node->getSequence().size() == 0) {
- oit->error = true;
- return false;
- }
-
- bool flag = node->getSequence().size() == 1 && node->getSequence()[0]->getAsTyped()->getAsConstantUnion();
- if (flag)
- {
- oit->singleConstantParam = true;
- oit->constructorType = node->getOp();
- if (node->getType().getBasicType() == EbtStruct)
- oit->size = node->getType().getStructSize();
- else
- oit->size = node->getType().getInstanceSize();
- if (node->getType().isMatrix()) {
- oit->isMatrix = true;
- oit->matrixSize = node->getType().getNominalSize();
- }
- }
-
- for (TIntermSequence::iterator p = node->getSequence().begin();
- p != node->getSequence().end(); p++) {
-
- if (node->getOp() == EOpComma)
- oit->index = 0;
-
- (*p)->traverse(oit);
- }
- if (flag)
- {
- oit->singleConstantParam = false;
- oit->constructorType = EOpNull;
- oit->size = 0;
- oit->isMatrix = false;
- oit->matrixSize = 0;
- }
- return false;
-}
-
-bool ParseSelection(bool /* preVisit */, TIntermSelection* node, TIntermTraverser* it)
-{
- TConstTraverser* oit = static_cast<TConstTraverser*>(it);
- oit->infoSink.info.message(EPrefixInternalError, "Selection Node found in constant constructor", node->getLine());
- oit->error = true;
- return false;
-}
-
-void ParseConstantUnion(TIntermConstantUnion* node, TIntermTraverser* it)
-{
- TConstTraverser* oit = static_cast<TConstTraverser*>(it);
- constUnion* leftUnionArray = oit->unionArray;
- int instanceSize;
- if (oit->type.getBasicType() == EbtStruct)
- instanceSize = oit->type.getStructSize();
- else
- instanceSize = oit->type.getInstanceSize();
-
- if (oit->index >= instanceSize)
- return;
-
- if (!oit->singleConstantParam) {
- int size;
- if (node->getType().getBasicType() == EbtStruct)
- size = node->getType().getStructSize();
- else
- size = node->getType().getInstanceSize();
-
- constUnion *rightUnionArray = node->getUnionArrayPointer();
- for (int i=0; i < size; i++) {
- if (oit->index >= instanceSize)
- return;
- leftUnionArray[oit->index] = rightUnionArray[i];
-
- (oit->index)++;
- }
- } else {
- int size, totalSize, matrixSize;
- bool isMatrix = false;
- size = oit->size;
- matrixSize = oit->matrixSize;
- isMatrix = oit->isMatrix;
- totalSize = oit->index + size ;
- constUnion *rightUnionArray = node->getUnionArrayPointer();
- if (!isMatrix) {
- int count = 0;
- for (int i = oit->index; i < totalSize; i++) {
- if (i >= instanceSize)
- return;
-
- leftUnionArray[i] = rightUnionArray[count];
-
- (oit->index)++;
- if (node->getType().getBasicType() == EbtStruct && node->getType().getStructSize() > 1 ||
- node->getType().getBasicType() != EbtStruct && node->getType().getInstanceSize() > 1)
- count++;
- }
- } else { // for matrix constructors
- int count = 0;
- int index = oit->index;
- for (int i = index; i < totalSize; i++) {
- if (i >= instanceSize)
- return;
- if (index - i == 0 || (i - index) % (matrixSize + 1) == 0 )
- leftUnionArray[i] = rightUnionArray[count];
- else
- leftUnionArray[i].fConst = 0.0;
-
- (oit->index)++;
- if (node->getType().getBasicType() == EbtStruct && node->getType().getStructSize() > 1 ||
- node->getType().getBasicType() != EbtStruct && node->getType().getInstanceSize() > 1)
- count++;
- }
- }
- }
-}
-
-bool ParseLoop(bool /* preVisit */, TIntermLoop* node, TIntermTraverser* it)
-{
- TConstTraverser* oit = static_cast<TConstTraverser*>(it);
- oit->infoSink.info.message(EPrefixInternalError, "Loop Node found in constant constructor", node->getLine());
- oit->error = true;
- return false;
-}
-
-bool ParseBranch(bool /* previsit*/, TIntermBranch* node, TIntermTraverser* it)
-{
- TConstTraverser* oit = static_cast<TConstTraverser*>(it);
- oit->infoSink.info.message(EPrefixInternalError, "Branch Node found in constant constructor", node->getLine());
- oit->error = true;
- return false;
-}
-
-//
-// This function is the one to call externally to start the traversal.
-// Individual functions can be initialized to 0 to skip processing of that
-// type of node. It's children will still be processed.
-//
-bool TIntermediate::parseConstTree(TSourceLoc line, TIntermNode* root, constUnion* unionArray, TOperator constructorType, TSymbolTable& symbolTable, TType t, bool singleConstantParam)
-{
- if (root == 0)
- return false;
-
- TConstTraverser it(unionArray, singleConstantParam, constructorType, infoSink, symbolTable, t);
-
- it.visitAggregate = ParseAggregate;
- it.visitBinary = ParseBinary;
- it.visitConstantUnion = ParseConstantUnion;
- it.visitSelection = ParseSelection;
- it.visitSymbol = ParseSymbol;
- it.visitUnary = ParseUnary;
- it.visitLoop = ParseLoop;
- it.visitBranch = ParseBranch;
-
- root->traverse(&it);
- if (it.error)
- return true;
- else
- return false;
-}
diff --git a/src/mesa/shader/slang/MachineIndependent/preprocessor/atom.c b/src/mesa/shader/slang/MachineIndependent/preprocessor/atom.c deleted file mode 100755 index b409c99bb7..0000000000 --- a/src/mesa/shader/slang/MachineIndependent/preprocessor/atom.c +++ /dev/null @@ -1,768 +0,0 @@ -/* */ -/*Copyright (C) 2002-2005 3Dlabs Inc. Ltd. */ -/*All rights reserved. */ -/* */ -/*Redistribution and use in source and binary forms, with or without */ -/*modification, are permitted provided that the following conditions */ -/*are met: */ -/* */ -/* Redistributions of source code must retain the above copyright */ -/* notice, this list of conditions and the following disclaimer. */ -/* */ -/* Redistributions in binary form must reproduce the above */ -/* copyright notice, this list of conditions and the following */ -/* disclaimer in the documentation and/or other materials provided */ -/* with the distribution. */ -/* */ -/* Neither the name of 3Dlabs Inc. Ltd. nor the names of its */ -/* contributors may be used to endorse or promote products derived */ -/* from this software without specific prior written permission. */ -/* */ -/*THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS */ -/*"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT */ -/*LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS */ -/*FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE */ -/*COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, */ -/*INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, */ -/*BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; */ -/*LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER */ -/*CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT */ -/*LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN */ -/*ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE */ -/*POSSIBILITY OF SUCH DAMAGE. */ -/* */ -/****************************************************************************\
-Copyright (c) 2002, NVIDIA Corporation.
-
-NVIDIA Corporation("NVIDIA") supplies this software to you in
-consideration of your agreement to the following terms, and your use,
-installation, modification or redistribution of this NVIDIA software
-constitutes acceptance of these terms. If you do not agree with these
-terms, please do not use, install, modify or redistribute this NVIDIA
-software.
-
-In consideration of your agreement to abide by the following terms, and
-subject to these terms, NVIDIA grants you a personal, non-exclusive
-license, under NVIDIA's copyrights in this original NVIDIA software (the
-"NVIDIA Software"), to use, reproduce, modify and redistribute the
-NVIDIA Software, with or without modifications, in source and/or binary
-forms; provided that if you redistribute the NVIDIA Software, you must
-retain the copyright notice of NVIDIA, this notice and the following
-text and disclaimers in all such redistributions of the NVIDIA Software.
-Neither the name, trademarks, service marks nor logos of NVIDIA
-Corporation may be used to endorse or promote products derived from the
-NVIDIA Software without specific prior written permission from NVIDIA.
-Except as expressly stated in this notice, no other rights or licenses
-express or implied, are granted by NVIDIA herein, including but not
-limited to any patent rights that may be infringed by your derivative
-works or by other works in which the NVIDIA Software may be
-incorporated. No hardware is licensed hereunder.
-
-THE NVIDIA SOFTWARE IS BEING PROVIDED ON AN "AS IS" BASIS, WITHOUT
-WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED,
-INCLUDING WITHOUT LIMITATION, WARRANTIES OR CONDITIONS OF TITLE,
-NON-INFRINGEMENT, MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR
-ITS USE AND OPERATION EITHER ALONE OR IN COMBINATION WITH OTHER
-PRODUCTS.
-
-IN NO EVENT SHALL NVIDIA BE LIABLE FOR ANY SPECIAL, INDIRECT,
-INCIDENTAL, EXEMPLARY, CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
-TO, LOST PROFITS; PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
-USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) OR ARISING IN ANY WAY
-OUT OF THE USE, REPRODUCTION, MODIFICATION AND/OR DISTRIBUTION OF THE
-NVIDIA SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER THEORY OF CONTRACT,
-TORT (INCLUDING NEGLIGENCE), STRICT LIABILITY OR OTHERWISE, EVEN IF
-NVIDIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-\****************************************************************************/
-
-/* */ -/* atom.c */ -/* */ -
-#include <assert.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-
-#include "slglobals.h"
-
-#undef malloc
-#undef realloc
-#undef free
-
-/*///////////////////////////////////////////////////////////////////////////////////////////// */ -/*//////////////////////////////////////// String table: ////////////////////////////////////// */ -/*///////////////////////////////////////////////////////////////////////////////////////////// */ -
-static const struct {
- int val;
- const char *str;
-} tokens[] = {
- { CPP_AND_OP, "&&" },
- { CPP_AND_ASSIGN, "&=" },
- { CPP_SUB_ASSIGN, "-=" },
- { CPP_MOD_ASSIGN, "%=" },
- { CPP_ADD_ASSIGN, "+=" },
- { CPP_DIV_ASSIGN, "/=" },
- { CPP_MUL_ASSIGN, "*=" },
- { CPP_RIGHT_BRACKET, ":>" },
- { CPP_EQ_OP, "==" },
- { CPP_XOR_OP, "^^" },
- { CPP_XOR_ASSIGN, "^=" },
- { CPP_FLOATCONSTANT, "<float-const>" },
- { CPP_GE_OP, ">=" },
- { CPP_RIGHT_OP, ">>" },
- { CPP_RIGHT_ASSIGN, ">>=" },
- { CPP_IDENTIFIER, "<ident>" },
- { CPP_INTCONSTANT, "<int-const>" },
- { CPP_LE_OP, "<=" },
- { CPP_LEFT_OP, "<<" },
- { CPP_LEFT_ASSIGN, "<<=" },
- { CPP_LEFT_BRACKET, "<:" },
- { CPP_LEFT_BRACE, "<%" },
- { CPP_DEC_OP, "--" },
- { CPP_RIGHT_BRACE, "%>" },
- { CPP_NE_OP, "!=" },
- { CPP_OR_OP, "||" },
- { CPP_OR_ASSIGN, "|=" },
- { CPP_INC_OP, "++" },
- { CPP_STRCONSTANT, "<string-const>" },
- { CPP_TYPEIDENTIFIER, "<type-ident>" },
-};
-
-/*///////////////////////////////////////////////////////////////////////////////////////////// */ -/*//////////////////////////////////////// String table: ////////////////////////////////////// */ -/*///////////////////////////////////////////////////////////////////////////////////////////// */ -
-#define INIT_STRING_TABLE_SIZE 16384
-
-typedef struct StringTable_Rec {
- char *strings;
- int nextFree;
- int size;
-} StringTable;
-
-/*
- * InitStringTable() - Initialize the string table.
- *
- */
-
-static int InitStringTable(StringTable *stable)
-{
- stable->strings = (char *) malloc(INIT_STRING_TABLE_SIZE);
- if (!stable->strings)
- return 0;
- /* Zero-th offset means "empty" so don't use it. */ - stable->nextFree = 1;
- stable->size = INIT_STRING_TABLE_SIZE;
- return 1;
-} /* InitStringTable */ -
-/*
- * FreeStringTable() - Free the string table.
- *
- */
-
-static void FreeStringTable(StringTable *stable)
-{
- if (stable->strings)
- free(stable->strings);
- stable->strings = NULL;
- stable->nextFree = 0;
- stable->size = 0;
-} /* FreeStringTable */ -
-/*
- * HashString() - Hash a string with the base hash function.
- *
- */
-
-static int HashString(const char *s)
-{
- int hval = 0;
-
- while (*s) {
- hval = (hval*13507 + *s*197) ^ (hval >> 2);
- s++;
- }
- return hval & 0x7fffffff;
-} /* HashString */ -
-/*
- * HashString2() - Hash a string with the incrimenting hash function.
- *
- */
-
-static int HashString2(const char *s)
-{
- int hval = 0;
-
- while (*s) {
- hval = (hval*729 + *s*37) ^ (hval >> 1);
- s++;
- }
- return hval;
-} /* HashString2 */ -
-/*
- * AddString() - Add a string to a string table. Return it's offset.
- *
- */
-
-static int AddString(StringTable *stable, const char *s)
-{
- int len, loc;
- char *str;
-
- len = (int) strlen(s);
- if (stable->nextFree + len + 1 >= stable->size) {
- assert(stable->size < 1000000);
- str = (char *) malloc(stable->size*2);
- memcpy(str, stable->strings, stable->size);
- free(stable->strings);
- stable->strings = str;
- }
- loc = stable->nextFree;
- strcpy(&stable->strings[loc], s);
- stable->nextFree += len + 1;
- return loc;
-} /* AddString */ -
-/*///////////////////////////////////////////////////////////////////////////////////////////// */ -/*///////////////////////////////////////// Hash table: /////////////////////////////////////// */ -/*///////////////////////////////////////////////////////////////////////////////////////////// */ -
-#define INIT_HASH_TABLE_SIZE 2047
-#define HASH_TABLE_MAX_COLLISIONS 3
-
-typedef struct HashEntry_Rec {
- int index; /* String table offset of string representation */ - int value; /* Atom (symbol) value */ -} HashEntry;
-
-typedef struct HashTable_Rec {
- HashEntry *entry;
- int size;
- int entries;
- int counts[HASH_TABLE_MAX_COLLISIONS + 1];
-} HashTable;
-
-/*
- * InitHashTable() - Initialize the hash table.
- *
- */
-
-static int InitHashTable(HashTable *htable, int fsize)
-{
- int ii;
-
- htable->entry = (HashEntry *) malloc(sizeof(HashEntry)*fsize);
- if (!htable->entry)
- return 0;
- htable->size = fsize;
- for (ii = 0; ii < fsize; ii++) {
- htable->entry[ii].index = 0;
- htable->entry[ii].value = 0;
- }
- htable->entries = 0;
- for (ii = 0; ii <= HASH_TABLE_MAX_COLLISIONS; ii++)
- htable->counts[ii] = 0;
- return 1;
-} /* InitHashTable */ -
-/*
- * FreeHashTable() - Free the hash table.
- *
- */
-
-static void FreeHashTable(HashTable *htable)
-{
- if (htable->entry)
- free(htable->entry);
- htable->entry = NULL;
- htable->size = 0;
- htable->entries = 0;
-} /* FreeHashTable */ -
-/*
- * Empty() - See if a hash table entry is empty.
- *
- */
-
-static int Empty(HashTable *htable, int hashloc)
-{
- assert(hashloc >= 0 && hashloc < htable->size);
- if (htable->entry[hashloc].index == 0) {
- return 1;
- } else {
- return 0;
- }
-} /* Empty */ -
-/*
- * Match() - See if a hash table entry is matches a string.
- *
- */
-
-static int Match(HashTable *htable, StringTable *stable, const char *s, int hashloc)
-{
- int strloc;
-
- strloc = htable->entry[hashloc].index;
- if (!strcmp(s, &stable->strings[strloc])) {
- return 1;
- } else {
- return 0;
- }
-} /* Match */ -
-/*///////////////////////////////////////////////////////////////////////////////////////////// */ -/*///////////////////////////////////////// Atom table: /////////////////////////////////////// */ -/*///////////////////////////////////////////////////////////////////////////////////////////// */ -
-#define INIT_ATOM_TABLE_SIZE 1024
-
-
-struct AtomTable_Rec {
- StringTable stable; /* String table. */ - HashTable htable; /* Hashes string to atom number and token value. Multiple strings can */ - /* have the same token value but each unique string is a unique atom. */ - int *amap; /* Maps atom value to offset in string table. Atoms all map to unique */ - /* strings except for some undefined values in the lower, fixed part */ - /* of the atom table that map to "<undefined>". The lowest 256 atoms */ - /* correspond to single character ASCII values except for alphanumeric */ - /* characters and '_', which can be other tokens. Next come the */ - /* language tokens with their atom values equal to the token value. */ - /* Then come predefined atoms, followed by user specified identifiers. */ - int *arev; /* Reversed atom for symbol table use. */ - int nextFree;
- int size;
-};
-
-static AtomTable latable = { { 0 } };
-AtomTable *atable = &latable;
-
-static int AddAtomFixed(AtomTable *atable, const char *s, int atom);
-
-/*
- * GrowAtomTable() - Grow the atom table to at least "size" if it's smaller.
- *
- */
-
-static int GrowAtomTable(AtomTable *atable, int size)
-{
- int *newmap, *newrev;
-
- if (atable->size < size) {
- if (atable->amap) {
- newmap = realloc(atable->amap, sizeof(int)*size);
- newrev = realloc(atable->arev, sizeof(int)*size);
- } else {
- newmap = malloc(sizeof(int)*size);
- newrev = malloc(sizeof(int)*size);
- atable->size = 0;
- }
- if (!newmap || !newrev) {
- /* failed to grow -- error */
- if (newmap)
- atable->amap = newmap;
- if (newrev)
- atable->amap = newrev;
- return -1;
- }
- memset(&newmap[atable->size], 0, (size - atable->size) * sizeof(int));
- memset(&newrev[atable->size], 0, (size - atable->size) * sizeof(int));
- atable->amap = newmap;
- atable->arev = newrev;
- atable->size = size;
- }
- return 0;
-} /* GrowAtomTable */ -
-/*
- * lReverse() - Reverse the bottom 20 bits of a 32 bit int.
- *
- */
-
-static int lReverse(int fval)
-{
- unsigned int in = fval;
- int result = 0, cnt = 0;
-
- while(in) {
- result <<= 1;
- result |= in&1;
- in >>= 1;
- cnt++;
- }
-
- /* Don't use all 31 bits. One million atoms is plenty and sometimes the */ - /* upper bits are used for other things. */ -
- if (cnt < 20)
- result <<= 20 - cnt;
- return result;
-} /* lReverse */ -
-/*
- * AllocateAtom() - Allocate a new atom. Associated with the "undefined" value of -1.
- *
- */
-
-static int AllocateAtom(AtomTable *atable)
-{
- if (atable->nextFree >= atable->size)
- GrowAtomTable(atable, atable->nextFree*2);
- atable->amap[atable->nextFree] = -1;
- atable->arev[atable->nextFree] = lReverse(atable->nextFree);
- atable->nextFree++;
- return atable->nextFree - 1;
-} /* AllocateAtom */ -
-/*
- * SetAtomValue() - Allocate a new atom associated with "hashindex".
- *
- */
-
-static void SetAtomValue(AtomTable *atable, int atomnumber, int hashindex)
-{
- atable->amap[atomnumber] = atable->htable.entry[hashindex].index;
- atable->htable.entry[hashindex].value = atomnumber;
-} /* SetAtomValue */ -
-/*
- * FindHashLoc() - Find the hash location for this string. Return -1 it hash table is full.
- *
- */
-
-static int FindHashLoc(AtomTable *atable, const char *s)
-{
- int hashloc, hashdelta, count;
- int FoundEmptySlot = 0;
- int collision[HASH_TABLE_MAX_COLLISIONS + 1];
-
- hashloc = HashString(s) % atable->htable.size;
- if (!Empty(&atable->htable, hashloc)) {
- if (Match(&atable->htable, &atable->stable, s, hashloc))
- return hashloc;
- collision[0] = hashloc;
- hashdelta = HashString2(s);
- count = 0;
- while (count < HASH_TABLE_MAX_COLLISIONS) {
- hashloc = ((hashloc + hashdelta) & 0x7fffffff) % atable->htable.size;
- if (!Empty(&atable->htable, hashloc)) {
- if (Match(&atable->htable, &atable->stable, s, hashloc)) {
- return hashloc;
- }
- } else {
- FoundEmptySlot = 1;
- break;
- }
- count++;
- collision[count] = hashloc;
- }
-
- if (!FoundEmptySlot) {
- if (cpp->options.DumpAtomTable) {
- int ii;
- char str[200];
- sprintf(str, "*** Hash failed with more than %d collisions. Must increase hash table size. ***",
- HASH_TABLE_MAX_COLLISIONS);
- CPPShInfoLogMsg(str);
-
- sprintf(str, "*** New string \"%s\", hash=%04x, delta=%04x", s, collision[0], hashdelta);
- CPPShInfoLogMsg(str);
- for (ii = 0; ii <= HASH_TABLE_MAX_COLLISIONS; ii++) {
- sprintf(str, "*** Collides on try %d at hash entry %04x with \"%s\"",
- ii + 1, collision[ii], GetAtomString(atable, atable->htable.entry[collision[ii]].value));
- CPPShInfoLogMsg(str);
- }
- }
- return -1;
- } else {
- atable->htable.counts[count]++;
- }
- }
- return hashloc;
-} /* FindHashLoc */ -
-/*
- * IncreaseHashTableSize()
- *
- */
-
-static int IncreaseHashTableSize(AtomTable *atable)
-{
- int ii, strloc, oldhashloc, value, size;
- AtomTable oldtable;
- char *s;
-
- /* Save the old atom table and create a new one: */ -
- oldtable = *atable;
- size = oldtable.htable.size*2 + 1;
- if (!InitAtomTable(atable, size))
- return 0;
-
- /* Add all the existing values to the new atom table preserving their atom values: */ -
- for (ii = atable->nextFree; ii < oldtable.nextFree; ii++) {
- strloc = oldtable.amap[ii];
- s = &oldtable.stable.strings[strloc];
- oldhashloc = FindHashLoc(&oldtable, s);
- assert(oldhashloc >= 0);
- value = oldtable.htable.entry[oldhashloc].value;
- AddAtomFixed(atable, s, value);
- }
- FreeAtomTable(&oldtable);
- return 1;
-} /* IncreaseHashTableSize */ -
-/*
- * LookUpAddStringHash() - Lookup a string in the hash table. If it's not there, add it and
- * initialize the atom value in the hash table to 0. Return the hash table index.
- */
-
-static int LookUpAddStringHash(AtomTable *atable, const char *s)
-{
- int hashloc, strloc;
-
- while(1) {
- hashloc = FindHashLoc(atable, s);
- if (hashloc >= 0)
- break;
- IncreaseHashTableSize(atable);
- }
-
- if (Empty(&atable->htable, hashloc)) {
- atable->htable.entries++;
- strloc = AddString(&atable->stable, s);
- atable->htable.entry[hashloc].index = strloc;
- atable->htable.entry[hashloc].value = 0;
- }
- return hashloc;
-} /* LookUpAddStringHash */ -
-/*
- * LookUpAddString() - Lookup a string in the hash table. If it's not there, add it and
- * initialize the atom value in the hash table to the next atom number.
- * Return the atom value of string.
- */
-
-int LookUpAddString(AtomTable *atable, const char *s)
-{
- int hashindex, atom;
-
- hashindex = LookUpAddStringHash(atable, s);
- atom = atable->htable.entry[hashindex].value;
- if (atom == 0) {
- atom = AllocateAtom(atable);
- SetAtomValue(atable, atom, hashindex);
- }
- return atom;
-} /* LookUpAddString */ -
-/*
- * GetAtomString()
- *
- */
-
-const char *GetAtomString(AtomTable *atable, int atom)
-{
- int soffset;
-
- if (atom > 0 && atom < atable->nextFree) {
- soffset = atable->amap[atom];
- if (soffset > 0 && soffset < atable->stable.nextFree) {
- return &atable->stable.strings[soffset];
- } else {
- return "<internal error: bad soffset>";
- }
- } else {
- if (atom == 0) {
- return "<null atom>";
- } else {
- if (atom == EOF) {
- return "<EOF>";
- } else {
- return "<invalid atom>";
- }
- }
- }
-} /* GetAtomString */ -
-/*
- * GetReversedAtom()
- *
- */
-
-int GetReversedAtom(AtomTable *atable, int atom)
-{
- if (atom > 0 && atom < atable->nextFree) {
- return atable->arev[atom];
- } else {
- return 0;
- }
-} /* GetReversedAtom */ -
-/*
- * AddAtom() - Add a string to the atom, hash and string tables if it isn't already there.
- * Return it's atom index.
- */
-
-int AddAtom(AtomTable *atable, const char *s)
-{
- int atom;
-
- atom = LookUpAddString(atable, s);
- return atom;
-} /* AddAtom */ -
-/*
- * AddAtomFixed() - Add an atom to the hash and string tables if it isn't already there.
- * Assign it the atom value of "atom".
- */
-
-static int AddAtomFixed(AtomTable *atable, const char *s, int atom)
-{
- int hashindex, lsize;
-
- hashindex = LookUpAddStringHash(atable, s);
- if (atable->nextFree >= atable->size || atom >= atable->size) {
- lsize = atable->size*2;
- if (lsize <= atom)
- lsize = atom + 1;
- GrowAtomTable(atable, lsize);
- }
- atable->amap[atom] = atable->htable.entry[hashindex].index;
- atable->htable.entry[hashindex].value = atom;
- /*if (atom >= atable->nextFree) */ - /* atable->nextFree = atom + 1; */ - while (atom >= atable->nextFree) {
- atable->arev[atable->nextFree] = lReverse(atable->nextFree);
- atable->nextFree++;
- }
- return atom;
-} /* AddAtomFixed */ -
-/*
- * InitAtomTable() - Initialize the atom table.
- *
- */
-
-int InitAtomTable(AtomTable *atable, int htsize)
-{
- int ii;
-
- htsize = htsize <= 0 ? INIT_HASH_TABLE_SIZE : htsize;
- if (!InitStringTable(&atable->stable))
- return 0;
- if (!InitHashTable(&atable->htable, htsize))
- return 0;
-
- atable->nextFree = 0;
- atable->amap = NULL;
- atable->size = 0;
- GrowAtomTable(atable, INIT_ATOM_TABLE_SIZE);
- if (!atable->amap)
- return 0;
-
- /* Initialize lower part of atom table to "<undefined>" atom: */ -
- AddAtomFixed(atable, "<undefined>", 0);
- for (ii = 0; ii < FIRST_USER_TOKEN_SY; ii++)
- atable->amap[ii] = atable->amap[0];
-
- /* Add single character tokens to the atom table: */ -
- {
- const char *s = "~!%^&*()-+=|,.<>/?;:[]{}#";
- char t[2];
-
- t[1] = '\0';
- while (*s) {
- t[0] = *s;
- AddAtomFixed(atable, t, s[0]);
- s++;
- }
- }
-
- /* Add multiple character scanner tokens : */ -
- for (ii = 0; ii < sizeof(tokens)/sizeof(tokens[0]); ii++)
- AddAtomFixed(atable, tokens[ii].str, tokens[ii].val);
-
- /* Add error symbol if running in error mode: */ -
- if (cpp->options.ErrorMode)
- AddAtomFixed(atable, "error", ERROR_SY);
-
- AddAtom(atable, "<*** end fixed atoms ***>");
-
- return 1;
-} /* InitAtomTable */ -
-/*///////////////////////////////////////////////////////////////////////////////////////////// */ -/*//////////////////////////////// Debug Printing Functions: ////////////////////////////////// */ -/*///////////////////////////////////////////////////////////////////////////////////////////// */ -
-/*
- * PrintAtomTable()
- *
- */
-
-void PrintAtomTable(AtomTable *atable)
-{
- int ii;
- char str[200];
-
- for (ii = 0; ii < atable->nextFree; ii++) {
- sprintf(str, "%d: \"%s\"", ii, &atable->stable.strings[atable->amap[ii]]);
- CPPDebugLogMsg(str);
- }
- sprintf(str, "Hash table: size=%d, entries=%d, collisions=",
- atable->htable.size, atable->htable.entries);
- CPPDebugLogMsg(str);
- for (ii = 0; ii < HASH_TABLE_MAX_COLLISIONS; ii++) {
- sprintf(str, " %d", atable->htable.counts[ii]);
- CPPDebugLogMsg(str);
- }
-
-} /* PrintAtomTable */ -
-
-/*
- * GetStringOfAtom()
- *
- */
-
-char* GetStringOfAtom(AtomTable *atable, int atom)
-{
- char* chr_str;
- chr_str=&atable->stable.strings[atable->amap[atom]];
- return chr_str;
-} /* GetStringOfAtom */ -
-/*
- * FreeAtomTable() - Free the atom table and associated memory
- *
- */
-
-void FreeAtomTable(AtomTable *atable)
-{
- FreeStringTable(&atable->stable);
- FreeHashTable(&atable->htable);
- if (atable->amap)
- free(atable->amap);
- if (atable->arev)
- free(atable->arev);
- atable->amap = NULL;
- atable->arev = NULL;
- atable->nextFree = 0;
- atable->size = 0;
-} /* FreeAtomTable */ -
-/*///////////////////////////////////////////////////////////////////////////////////////////// */ -/*/////////////////////////////////////// End of atom.c /////////////////////////////////////// */ -/*///////////////////////////////////////////////////////////////////////////////////////////// */ -
diff --git a/src/mesa/shader/slang/MachineIndependent/preprocessor/atom.h b/src/mesa/shader/slang/MachineIndependent/preprocessor/atom.h deleted file mode 100755 index 4e509d6ba4..0000000000 --- a/src/mesa/shader/slang/MachineIndependent/preprocessor/atom.h +++ /dev/null @@ -1,96 +0,0 @@ -/* */ -/*Copyright (C) 2002-2005 3Dlabs Inc. Ltd. */ -/*All rights reserved. */ -/* */ -/*Redistribution and use in source and binary forms, with or without */ -/*modification, are permitted provided that the following conditions */ -/*are met: */ -/* */ -/* Redistributions of source code must retain the above copyright */ -/* notice, this list of conditions and the following disclaimer. */ -/* */ -/* Redistributions in binary form must reproduce the above */ -/* copyright notice, this list of conditions and the following */ -/* disclaimer in the documentation and/or other materials provided */ -/* with the distribution. */ -/* */ -/* Neither the name of 3Dlabs Inc. Ltd. nor the names of its */ -/* contributors may be used to endorse or promote products derived */ -/* from this software without specific prior written permission. */ -/* */ -/*THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS */ -/*"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT */ -/*LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS */ -/*FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE */ -/*COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, */ -/*INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, */ -/*BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; */ -/*LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER */ -/*CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT */ -/*LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN */ -/*ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE */ -/*POSSIBILITY OF SUCH DAMAGE. */ -/* */ -/****************************************************************************\
-Copyright (c) 2002, NVIDIA Corporation.
-
-NVIDIA Corporation("NVIDIA") supplies this software to you in
-consideration of your agreement to the following terms, and your use,
-installation, modification or redistribution of this NVIDIA software
-constitutes acceptance of these terms. If you do not agree with these
-terms, please do not use, install, modify or redistribute this NVIDIA
-software.
-
-In consideration of your agreement to abide by the following terms, and
-subject to these terms, NVIDIA grants you a personal, non-exclusive
-license, under NVIDIA's copyrights in this original NVIDIA software (the
-"NVIDIA Software"), to use, reproduce, modify and redistribute the
-NVIDIA Software, with or without modifications, in source and/or binary
-forms; provided that if you redistribute the NVIDIA Software, you must
-retain the copyright notice of NVIDIA, this notice and the following
-text and disclaimers in all such redistributions of the NVIDIA Software.
-Neither the name, trademarks, service marks nor logos of NVIDIA
-Corporation may be used to endorse or promote products derived from the
-NVIDIA Software without specific prior written permission from NVIDIA.
-Except as expressly stated in this notice, no other rights or licenses
-express or implied, are granted by NVIDIA herein, including but not
-limited to any patent rights that may be infringed by your derivative
-works or by other works in which the NVIDIA Software may be
-incorporated. No hardware is licensed hereunder.
-
-THE NVIDIA SOFTWARE IS BEING PROVIDED ON AN "AS IS" BASIS, WITHOUT
-WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED,
-INCLUDING WITHOUT LIMITATION, WARRANTIES OR CONDITIONS OF TITLE,
-NON-INFRINGEMENT, MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR
-ITS USE AND OPERATION EITHER ALONE OR IN COMBINATION WITH OTHER
-PRODUCTS.
-
-IN NO EVENT SHALL NVIDIA BE LIABLE FOR ANY SPECIAL, INDIRECT,
-INCIDENTAL, EXEMPLARY, CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
-TO, LOST PROFITS; PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
-USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) OR ARISING IN ANY WAY
-OUT OF THE USE, REPRODUCTION, MODIFICATION AND/OR DISTRIBUTION OF THE
-NVIDIA SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER THEORY OF CONTRACT,
-TORT (INCLUDING NEGLIGENCE), STRICT LIABILITY OR OTHERWISE, EVEN IF
-NVIDIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-\****************************************************************************/
-/* */ -/* atom.h */ -/* */ -
-#if !defined(__ATOM_H)
-#define __ATOM_H 1
-
-typedef struct AtomTable_Rec AtomTable;
-
-extern AtomTable *atable;
-
-int InitAtomTable(AtomTable *atable, int htsize);
-void FreeAtomTable(AtomTable *atable);
-int AddAtom(AtomTable *atable, const char *s);
-void PrintAtomTable(AtomTable *atable);
-int LookUpAddString(AtomTable *atable, const char *s);
-const char *GetAtomString(AtomTable *atable, int atom);
-int GetReversedAtom(AtomTable *atable, int atom);
-char* GetStringOfAtom(AtomTable *atable, int atom);
-#endif /* !defined(__ATOM_H) */ diff --git a/src/mesa/shader/slang/MachineIndependent/preprocessor/compile.h b/src/mesa/shader/slang/MachineIndependent/preprocessor/compile.h deleted file mode 100755 index 24673461e6..0000000000 --- a/src/mesa/shader/slang/MachineIndependent/preprocessor/compile.h +++ /dev/null @@ -1,132 +0,0 @@ -/* */ -/*Copyright (C) 2002-2005 3Dlabs Inc. Ltd. */ -/*All rights reserved. */ -/* */ -/*Redistribution and use in source and binary forms, with or without */ -/*modification, are permitted provided that the following conditions */ -/*are met: */ -/* */ -/* Redistributions of source code must retain the above copyright */ -/* notice, this list of conditions and the following disclaimer. */ -/* */ -/* Redistributions in binary form must reproduce the above */ -/* copyright notice, this list of conditions and the following */ -/* disclaimer in the documentation and/or other materials provided */ -/* with the distribution. */ -/* */ -/* Neither the name of 3Dlabs Inc. Ltd. nor the names of its */ -/* contributors may be used to endorse or promote products derived */ -/* from this software without specific prior written permission. */ -/* */ -/*THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS */ -/*"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT */ -/*LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS */ -/*FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE */ -/*COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, */ -/*INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, */ -/*BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; */ -/*LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER */ -/*CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT */ -/*LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN */ -/*ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE */ -/*POSSIBILITY OF SUCH DAMAGE. */ -/* */ -/****************************************************************************\
-Copyright (c) 2002, NVIDIA Corporation.
-
-NVIDIA Corporation("NVIDIA") supplies this software to you in
-consideration of your agreement to the following terms, and your use,
-installation, modification or redistribution of this NVIDIA software
-constitutes acceptance of these terms. If you do not agree with these
-terms, please do not use, install, modify or redistribute this NVIDIA
-software.
-
-In consideration of your agreement to abide by the following terms, and
-subject to these terms, NVIDIA grants you a personal, non-exclusive
-license, under NVIDIA's copyrights in this original NVIDIA software (the
-"NVIDIA Software"), to use, reproduce, modify and redistribute the
-NVIDIA Software, with or without modifications, in source and/or binary
-forms; provided that if you redistribute the NVIDIA Software, you must
-retain the copyright notice of NVIDIA, this notice and the following
-text and disclaimers in all such redistributions of the NVIDIA Software.
-Neither the name, trademarks, service marks nor logos of NVIDIA
-Corporation may be used to endorse or promote products derived from the
-NVIDIA Software without specific prior written permission from NVIDIA.
-Except as expressly stated in this notice, no other rights or licenses
-express or implied, are granted by NVIDIA herein, including but not
-limited to any patent rights that may be infringed by your derivative
-works or by other works in which the NVIDIA Software may be
-incorporated. No hardware is licensed hereunder.
-
-THE NVIDIA SOFTWARE IS BEING PROVIDED ON AN "AS IS" BASIS, WITHOUT
-WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED,
-INCLUDING WITHOUT LIMITATION, WARRANTIES OR CONDITIONS OF TITLE,
-NON-INFRINGEMENT, MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR
-ITS USE AND OPERATION EITHER ALONE OR IN COMBINATION WITH OTHER
-PRODUCTS.
-
-IN NO EVENT SHALL NVIDIA BE LIABLE FOR ANY SPECIAL, INDIRECT,
-INCIDENTAL, EXEMPLARY, CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
-TO, LOST PROFITS; PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
-USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) OR ARISING IN ANY WAY
-OUT OF THE USE, REPRODUCTION, MODIFICATION AND/OR DISTRIBUTION OF THE
-NVIDIA SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER THEORY OF CONTRACT,
-TORT (INCLUDING NEGLIGENCE), STRICT LIABILITY OR OTHERWISE, EVEN IF
-NVIDIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-\****************************************************************************/
-/* */ -/* compile.h */ -/* */ -
-#if !defined(__COMPILE_H)
-#define __COMPILE_H 1
-
-int InitCPPStruct(void);
-
-typedef struct Options_Rec{
- const char *profileString;
- int ErrorMode;
- int Quiet;
-
- /* Debug The Compiler options: */ - int DumpAtomTable;
-} Options;
-
-struct CPPStruct_Rec {
- /* Public members */ - SourceLoc *pLastSourceLoc; /* Set at the start of each statement by the tree walkers */ - Options options; /* Compile options and parameters */ -
- /* Private members */ - SourceLoc lastSourceLoc;
-
- /* Scanner data: */ -
- SourceLoc *tokenLoc; /* Source location of most recent token seen by the scanner */ - int mostRecentToken; /* Most recent token seen by the scanner */ - InputSrc *currentInput;
- int previous_token;
- int notAVersionToken; /* used to make sure that #version is the first token seen in the file, if present */ -
- void *pC; /* storing the parseContext of the compile object in cpp. */ -
- /* Private members: */ - SourceLoc ltokenLoc;
- int ifdepth; /*current #if-#else-#endif nesting in the cpp.c file (pre-processor) */ - int elsedepth[64]; /*Keep a track of #if depth..Max allowed is 64. */ - int elsetracker; /*#if-#else and #endif constructs...Counter. */ - const char *ErrMsg;
- int CompileError; /*Indicate compile error when #error, #else,#elif mismatch. */ -
- /* */ - /* Globals used to communicate between PaParseStrings() and yy_input()and */ - /* also across the files.(gen_glslang.cpp and scanner.c) */ - /* */ - int PaWhichStr; /* which string we're parsing */ - int* PaStrLen; /* array of lengths of the PaArgv strings */ - int PaArgc; /* count of strings in the array */ - char** PaArgv; /* our array of strings to parse */ - unsigned int tokensBeforeEOF : 1;
-};
-
-#endif /* !defined(__COMPILE_H) */ diff --git a/src/mesa/shader/slang/MachineIndependent/preprocessor/cpp.c b/src/mesa/shader/slang/MachineIndependent/preprocessor/cpp.c deleted file mode 100755 index f8da59b382..0000000000 --- a/src/mesa/shader/slang/MachineIndependent/preprocessor/cpp.c +++ /dev/null @@ -1,1037 +0,0 @@ -/* */ -/*Copyright (C) 2002-2005 3Dlabs Inc. Ltd. */ -/*All rights reserved. */ -/* */ -/*Redistribution and use in source and binary forms, with or without */ -/*modification, are permitted provided that the following conditions */ -/*are met: */ -/* */ -/* Redistributions of source code must retain the above copyright */ -/* notice, this list of conditions and the following disclaimer. */ -/* */ -/* Redistributions in binary form must reproduce the above */ -/* copyright notice, this list of conditions and the following */ -/* disclaimer in the documentation and/or other materials provided */ -/* with the distribution. */ -/* */ -/* Neither the name of 3Dlabs Inc. Ltd. nor the names of its */ -/* contributors may be used to endorse or promote products derived */ -/* from this software without specific prior written permission. */ -/* */ -/*THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS */ -/*"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT */ -/*LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS */ -/*FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE */ -/*COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, */ -/*INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, */ -/*BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; */ -/*LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER */ -/*CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT */ -/*LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN */ -/*ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE */ -/*POSSIBILITY OF SUCH DAMAGE. */ -/* */ -/****************************************************************************\
-Copyright (c) 2002, NVIDIA Corporation.
-
-NVIDIA Corporation("NVIDIA") supplies this software to you in
-consideration of your agreement to the following terms, and your use,
-installation, modification or redistribution of this NVIDIA software
-constitutes acceptance of these terms. If you do not agree with these
-terms, please do not use, install, modify or redistribute this NVIDIA
-software.
-
-In consideration of your agreement to abide by the following terms, and
-subject to these terms, NVIDIA grants you a personal, non-exclusive
-license, under NVIDIA's copyrights in this original NVIDIA software (the
-"NVIDIA Software"), to use, reproduce, modify and redistribute the
-NVIDIA Software, with or without modifications, in source and/or binary
-forms; provided that if you redistribute the NVIDIA Software, you must
-retain the copyright notice of NVIDIA, this notice and the following
-text and disclaimers in all such redistributions of the NVIDIA Software.
-Neither the name, trademarks, service marks nor logos of NVIDIA
-Corporation may be used to endorse or promote products derived from the
-NVIDIA Software without specific prior written permission from NVIDIA.
-Except as expressly stated in this notice, no other rights or licenses
-express or implied, are granted by NVIDIA herein, including but not
-limited to any patent rights that may be infringed by your derivative
-works or by other works in which the NVIDIA Software may be
-incorporated. No hardware is licensed hereunder.
-
-THE NVIDIA SOFTWARE IS BEING PROVIDED ON AN "AS IS" BASIS, WITHOUT
-WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED,
-INCLUDING WITHOUT LIMITATION, WARRANTIES OR CONDITIONS OF TITLE,
-NON-INFRINGEMENT, MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR
-ITS USE AND OPERATION EITHER ALONE OR IN COMBINATION WITH OTHER
-PRODUCTS.
-
-IN NO EVENT SHALL NVIDIA BE LIABLE FOR ANY SPECIAL, INDIRECT,
-INCIDENTAL, EXEMPLARY, CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
-TO, LOST PROFITS; PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
-USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) OR ARISING IN ANY WAY
-OUT OF THE USE, REPRODUCTION, MODIFICATION AND/OR DISTRIBUTION OF THE
-NVIDIA SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER THEORY OF CONTRACT,
-TORT (INCLUDING NEGLIGENCE), STRICT LIABILITY OR OTHERWISE, EVEN IF
-NVIDIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-\****************************************************************************/
-/* */ -/* cpp.c */ -/* */ -
-#include <stdarg.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <ctype.h>
-
-#include "slglobals.h"
-
-static int CPPif(yystypepp * yylvalpp);
-
-/* Don't use memory.c's replacements, as we clean up properly here */
-#undef malloc
-#undef free
-
-static int bindAtom = 0;
-static int constAtom = 0;
-static int defaultAtom = 0;
-static int defineAtom = 0;
-static int definedAtom = 0;
-static int elseAtom = 0;
-static int elifAtom = 0;
-static int endifAtom = 0;
-static int ifAtom = 0;
-static int ifdefAtom = 0;
-static int ifndefAtom = 0;
-static int includeAtom = 0;
-static int lineAtom = 0;
-static int pragmaAtom = 0;
-static int texunitAtom = 0;
-static int undefAtom = 0;
-static int errorAtom = 0;
-static int __LINE__Atom = 0;
-static int __FILE__Atom = 0;
-static int __VERSION__Atom = 0;
-static int versionAtom = 0;
-static int extensionAtom = 0;
-
-static Scope *macros = 0;
-#define MAX_MACRO_ARGS 64
-#define MAX_IF_NESTING 64
-
-static SourceLoc ifloc; /* outermost #if */
-
-int InitCPP(void)
-{
- char buffer[64], *t;
- const char *f;
- /* Add various atoms needed by the CPP line scanner: */ - bindAtom = LookUpAddString(atable, "bind");
- constAtom = LookUpAddString(atable, "const");
- defaultAtom = LookUpAddString(atable, "default");
- defineAtom = LookUpAddString(atable, "define");
- definedAtom = LookUpAddString(atable, "defined");
- elifAtom = LookUpAddString(atable, "elif");
- elseAtom = LookUpAddString(atable, "else");
- endifAtom = LookUpAddString(atable, "endif");
- ifAtom = LookUpAddString(atable, "if");
- ifdefAtom = LookUpAddString(atable, "ifdef");
- ifndefAtom = LookUpAddString(atable, "ifndef");
- includeAtom = LookUpAddString(atable, "include");
- lineAtom = LookUpAddString(atable, "line");
- pragmaAtom = LookUpAddString(atable, "pragma");
- texunitAtom = LookUpAddString(atable, "texunit");
- undefAtom = LookUpAddString(atable, "undef");
- errorAtom = LookUpAddString(atable, "error");
- __LINE__Atom = LookUpAddString(atable, "__LINE__");
- __FILE__Atom = LookUpAddString(atable, "__FILE__");
- __VERSION__Atom = LookUpAddString(atable, "__VERSION__");
- versionAtom = LookUpAddString(atable, "version");
- extensionAtom = LookUpAddString(atable, "extension");
- macros = NewScopeInPool(mem_CreatePool(0, 0));
- strcpy(buffer, "PROFILE_");
- t = buffer + strlen(buffer);
- f = cpp->options.profileString;
- while ((isalnum(*f) || *f == '_') && t < buffer + sizeof(buffer) - 1)
- *t++ = toupper(*f++);
- *t = 0;
- return 1;
-} /* InitCPP */ -
-int FreeCPP(void)
-{
- if (macros)
- {
- mem_FreePool(macros->pool);
- macros = 0;
- }
-
- return 1;
-}
-
-int FinalCPP(void)
-{
- if (cpp->ifdepth)
- CPPErrorToInfoLog("#if mismatch");
- return 1;
-}
-
-static int CPPdefine(yystypepp * yylvalpp)
-{
- int token, name, args[MAX_MACRO_ARGS], argc;
- const char *message;
- MacroSymbol mac;
- Symbol *symb;
- SourceLoc dummyLoc;
- memset(&mac, 0, sizeof(mac));
- token = cpp->currentInput->scan(cpp->currentInput, yylvalpp);
- if (token != CPP_IDENTIFIER) {
- CPPErrorToInfoLog("#define");
- return token;
- }
- name = yylvalpp->sc_ident;
- token = cpp->currentInput->scan(cpp->currentInput, yylvalpp);
- if (token == '(' && !yylvalpp->sc_int) {
- /* gather arguments */ - argc = 0;
- do {
- token = cpp->currentInput->scan(cpp->currentInput, yylvalpp);
- if (argc == 0 && token == ')') break;
- if (token != CPP_IDENTIFIER) {
- CPPErrorToInfoLog("#define");
- return token;
- }
- if (argc < MAX_MACRO_ARGS)
- args[argc++] = yylvalpp->sc_ident;
- token = cpp->currentInput->scan(cpp->currentInput, yylvalpp);
- } while (token == ',');
- if (token != ')') {
- CPPErrorToInfoLog("#define");
- return token;
- }
- mac.argc = argc;
- mac.args = mem_Alloc(macros->pool, argc * sizeof(int));
- memcpy(mac.args, args, argc * sizeof(int));
- token = cpp->currentInput->scan(cpp->currentInput, yylvalpp);
- }
- mac.body = NewTokenStream(GetAtomString(atable, name));
- while (token != '\n') {
- while (token == '\\') {
- token = cpp->currentInput->scan(cpp->currentInput, yylvalpp);
- if (token == '\n')
- token = cpp->currentInput->scan(cpp->currentInput, yylvalpp);
- else
- RecordToken(mac.body, '\\', yylvalpp);
- }
- RecordToken(mac.body, token, yylvalpp);
- token = cpp->currentInput->scan(cpp->currentInput, yylvalpp);
- };
-
- symb = LookUpSymbol(macros, name);
- if (symb) {
- if (!symb->details.mac.undef) {
- /* already defined -- need to make sure they are identical */ - if (symb->details.mac.argc != mac.argc) goto error;
- for (argc=0; argc < mac.argc; argc++)
- if (symb->details.mac.args[argc] != mac.args[argc])
- goto error;
- RewindTokenStream(symb->details.mac.body);
- RewindTokenStream(mac.body);
- do {
- int old_lval, old_token;
- old_token = ReadToken(symb->details.mac.body, yylvalpp);
- old_lval = yylvalpp->sc_int;
- token = ReadToken(mac.body, yylvalpp);
- if (token != old_token || yylvalpp->sc_int != old_lval) {
- error:
- StoreStr("Macro Redefined");
- StoreStr(GetStringOfAtom(atable,name));
- message=GetStrfromTStr();
- DecLineNumber();
- CPPShInfoLogMsg(message);
- IncLineNumber();
- ResetTString();
- break; }
- } while (token > 0);
- }
- FreeMacro(&symb->details.mac);
- } else {
- dummyLoc.file = 0;
- dummyLoc.line = 0;
- symb = AddSymbol(&dummyLoc, macros, name, MACRO_S);
- }
- symb->details.mac = mac;
- return '\n';
-} /* CPPdefine */ -
-static int CPPundef(yystypepp * yylvalpp)
-{
- int token = cpp->currentInput->scan(cpp->currentInput, yylvalpp);
- Symbol *symb;
- if(token == '\n'){
- CPPErrorToInfoLog("#undef");
- return token;
- }
- if (token != CPP_IDENTIFIER)
- goto error;
- symb = LookUpSymbol(macros, yylvalpp->sc_ident);
- if (symb) {
- symb->details.mac.undef = 1;
- }
- token = cpp->currentInput->scan(cpp->currentInput, yylvalpp);
- if (token != '\n') {
- error:
- CPPErrorToInfoLog("#undef");
- }
- return token;
-} /* CPPundef */ -
-/* CPPelse -- skip forward to appropriate spot. This is actually used
-** to skip to and #endif after seeing an #else, AND to skip to a #else,
-** #elif, or #endif after a #if/#ifdef/#ifndef/#elif test was false
-*/
-
-static int CPPelse(int matchelse, yystypepp * yylvalpp)
-{
- int atom,depth=0;
- int token = cpp->currentInput->scan(cpp->currentInput, yylvalpp);
-
- while (token > 0) {
- if (token != '#') {
- while (token != '\n')
- token = cpp->currentInput->scan(cpp->currentInput, yylvalpp);
-
- token = cpp->currentInput->scan(cpp->currentInput, yylvalpp);
- continue;
- }
- if ((token = cpp->currentInput->scan(cpp->currentInput, yylvalpp)) != CPP_IDENTIFIER)
- continue;
- atom = yylvalpp->sc_ident;
- if (atom == ifAtom || atom == ifdefAtom || atom == ifndefAtom){
- depth++; cpp->ifdepth++; cpp->elsetracker++;
- }
- else if (atom == endifAtom) {
- if(--depth<=0){
- cpp->elsedepth[cpp->elsetracker]=0;
- --cpp->elsetracker;
- if (cpp->ifdepth)
- --cpp->ifdepth;
- break;
- }
- --cpp->elsetracker;
- --cpp->ifdepth;
- }
- else if (((int)(matchelse) != 0)&& depth==0) {
- if (atom == elseAtom ) {
- token = cpp->currentInput->scan(cpp->currentInput, yylvalpp);
- if (token != '\n') {
- CPPWarningToInfoLog("unexpected tokens following #else preprocessor directive - expected a newline");
- while (token != '\n')
- token = cpp->currentInput->scan(cpp->currentInput, yylvalpp);
- }
- break;
- }
- else if (atom == elifAtom) {
- /* we decrement cpp->ifdepth here, because CPPif will increment
- * it and we really want to leave it alone */
- if (cpp->ifdepth){
- --cpp->ifdepth;
- --cpp->elsetracker;
- }
- return CPPif(yylvalpp);
- }
- }
- else if((atom==elseAtom) && (!ChkCorrectElseNesting())){
- CPPErrorToInfoLog("#else after a #else");
- cpp->CompileError=1;
- }
- };
- return token;
-}
-
-enum eval_prec {
- MIN_PREC,
- COND, LOGOR, LOGAND, OR, XOR, AND, EQUAL, RELATION, SHIFT, ADD, MUL, UNARY,
- MAX_PREC
-};
-
-static int op_logor(int a, int b) { return a || b; }
-static int op_logand(int a, int b) { return a && b; }
-static int op_or(int a, int b) { return a | b; }
-static int op_xor(int a, int b) { return a ^ b; }
-static int op_and(int a, int b) { return a & b; }
-static int op_eq(int a, int b) { return a == b; }
-static int op_ne(int a, int b) { return a != b; }
-static int op_ge(int a, int b) { return a >= b; }
-static int op_le(int a, int b) { return a <= b; }
-static int op_gt(int a, int b) { return a > b; }
-static int op_lt(int a, int b) { return a < b; }
-static int op_shl(int a, int b) { return a << b; }
-static int op_shr(int a, int b) { return a >> b; }
-static int op_add(int a, int b) { return a + b; }
-static int op_sub(int a, int b) { return a - b; }
-static int op_mul(int a, int b) { return a * b; }
-static int op_div(int a, int b) { return a / b; }
-static int op_mod(int a, int b) { return a % b; }
-static int op_pos(int a) { return a; }
-static int op_neg(int a) { return -a; }
-static int op_cmpl(int a) { return ~a; }
-static int op_not(int a) { return !a; }
-
-struct {
- int token, prec, (*op)(int, int);
-} binop[] = {
- { CPP_OR_OP, LOGOR, op_logor },
- { CPP_AND_OP, LOGAND, op_logand },
- { '|', OR, op_or },
- { '^', XOR, op_xor },
- { '&', AND, op_and },
- { CPP_EQ_OP, EQUAL, op_eq },
- { CPP_NE_OP, EQUAL, op_ne },
- { '>', RELATION, op_gt },
- { CPP_GE_OP, RELATION, op_ge },
- { '<', RELATION, op_lt },
- { CPP_LE_OP, RELATION, op_le },
- { CPP_LEFT_OP, SHIFT, op_shl },
- { CPP_RIGHT_OP, SHIFT, op_shr },
- { '+', ADD, op_add },
- { '-', ADD, op_sub },
- { '*', MUL, op_mul },
- { '/', MUL, op_div },
- { '%', MUL, op_mod },
-};
-
-struct {
- int token, (*op)(int);
-} unop[] = {
- { '+', op_pos },
- { '-', op_neg },
- { '~', op_cmpl },
- { '!', op_not },
-};
-
-#define ALEN(A) (sizeof(A)/sizeof(A[0]))
-
-static int eval(int token, int prec, int *res, int *err, yystypepp * yylvalpp)
-{
- int i, val;
- Symbol *s;
- if (token == CPP_IDENTIFIER) {
- if (yylvalpp->sc_ident == definedAtom) {
- int needclose = 0;
- token = cpp->currentInput->scan(cpp->currentInput, yylvalpp);
- if (token == '(') {
- needclose = 1;
- token = cpp->currentInput->scan(cpp->currentInput, yylvalpp);
- }
- if (token != CPP_IDENTIFIER)
- goto error;
- *res = (s = LookUpSymbol(macros, yylvalpp->sc_ident))
- ? !s->details.mac.undef : 0;
- token = cpp->currentInput->scan(cpp->currentInput, yylvalpp);
- if (needclose) {
- if (token != ')')
- goto error;
- token = cpp->currentInput->scan(cpp->currentInput, yylvalpp);
- }
- } else if (MacroExpand(yylvalpp->sc_ident, yylvalpp)) {
- token = cpp->currentInput->scan(cpp->currentInput, yylvalpp);
- return eval(token, prec, res, err, yylvalpp);
- } else {
- goto error;
- }
- } else if (token == CPP_INTCONSTANT) {
- *res = yylvalpp->sc_int;
- token = cpp->currentInput->scan(cpp->currentInput, yylvalpp);
- } else if (token == '(') {
- token = cpp->currentInput->scan(cpp->currentInput, yylvalpp);
- token = eval(token, MIN_PREC, res, err, yylvalpp);
- if (!*err) {
- if (token != ')')
- goto error;
- token = cpp->currentInput->scan(cpp->currentInput, yylvalpp);
- }
- } else {
- for (i = ALEN(unop) - 1; i >= 0; i--) {
- if (unop[i].token == token)
- break;
- }
- if (i >= 0) {
- token = cpp->currentInput->scan(cpp->currentInput, yylvalpp);
- token = eval(token, UNARY, res, err, yylvalpp);
- *res = unop[i].op(*res);
- } else {
- goto error;
- }
- }
- while (!*err) {
- if (token == ')' || token == '\n') break;
- for (i = ALEN(binop) - 1; i >= 0; i--) {
- if (binop[i].token == token)
- break;
- }
- if (i < 0 || binop[i].prec <= prec)
- break;
- val = *res;
- token = cpp->currentInput->scan(cpp->currentInput, yylvalpp);
- token = eval(token, binop[i].prec, res, err, yylvalpp);
- *res = binop[i].op(val, *res);
- }
- return token;
-error:
- CPPErrorToInfoLog("incorrect preprocessor directive");
- *err = 1;
- *res = 0;
- return token;
-} /* eval */ -
-static int CPPif(yystypepp * yylvalpp) {
- int token = cpp->currentInput->scan(cpp->currentInput, yylvalpp);
- int res = 0, err = 0;
- cpp->elsetracker++;
- if (!cpp->ifdepth++)
- ifloc = *cpp->tokenLoc;
- if(cpp->ifdepth >MAX_IF_NESTING){
- CPPErrorToInfoLog("max #if nesting depth exceeded");
- return 0;
- }
- token = eval(token, MIN_PREC, &res, &err, yylvalpp);
- if (token != '\n') {
- CPPWarningToInfoLog("unexpected tokens following the preprocessor directive - expected a newline");
- while (token != '\n')
- token = cpp->currentInput->scan(cpp->currentInput, yylvalpp);
- }
- if (!res && !err) {
- token = CPPelse(1, yylvalpp);
- }
-
- return token;
-} /* CPPif */ -
-static int CPPifdef(int defined, yystypepp * yylvalpp)
-{
- int token = cpp->currentInput->scan(cpp->currentInput, yylvalpp);
- int name = yylvalpp->sc_ident;
- if(++cpp->ifdepth >MAX_IF_NESTING){
- CPPErrorToInfoLog("max #if nesting depth exceeded");
- return 0;
- }
- cpp->elsetracker++;
- if (token != CPP_IDENTIFIER) {
- defined ? CPPErrorToInfoLog("ifdef"):CPPErrorToInfoLog("ifndef");
- } else {
- Symbol *s = LookUpSymbol(macros, name);
- token = cpp->currentInput->scan(cpp->currentInput, yylvalpp);
- if (token != '\n') {
- CPPWarningToInfoLog("unexpected tokens following #ifdef preprocessor directive - expected a newline");
- while (token != '\n')
- token = cpp->currentInput->scan(cpp->currentInput, yylvalpp);
- }
- if (((s && !s->details.mac.undef) ? 1 : 0) != defined)
- token = CPPelse(1, yylvalpp);
- }
- return token;
-} /* CPPifdef */ -
-static int CPPline(yystypepp * yylvalpp)
-{
- int token = cpp->currentInput->scan(cpp->currentInput, yylvalpp);
- if(token=='\n'){
- DecLineNumber();
- CPPErrorToInfoLog("#line");
- IncLineNumber();
- return token;
- }
- else if (token == CPP_INTCONSTANT) {
- yylvalpp->sc_int=atoi(yylvalpp->symbol_name);
- SetLineNumber(yylvalpp->sc_int);
- token = cpp->currentInput->scan(cpp->currentInput, yylvalpp);
-
- if (token == CPP_INTCONSTANT) {
- yylvalpp->sc_int=atoi(yylvalpp->symbol_name);
- SetStringNumber(yylvalpp->sc_int);
- token = cpp->currentInput->scan(cpp->currentInput, yylvalpp);
- if(token!='\n')
- CPPErrorToInfoLog("#line");
- }
- else if (token == '\n'){
- return token;
- }
- else{
- CPPErrorToInfoLog("#line");
- }
- }
- else{
- CPPErrorToInfoLog("#line");
- }
- return token;
-}
-
-static int CPPerror(yystypepp * yylvalpp) {
-
- int token = cpp->currentInput->scan(cpp->currentInput, yylvalpp);
- const char *message;
-
- while (token != '\n') {
- if (token == CPP_FLOATCONSTANT || token == CPP_INTCONSTANT){
- StoreStr(yylvalpp->symbol_name);
- }else if(token == CPP_IDENTIFIER || token == CPP_STRCONSTANT){
- StoreStr(GetStringOfAtom(atable,yylvalpp->sc_ident));
- }else {
- StoreStr(GetStringOfAtom(atable,token));
- }
- token = cpp->currentInput->scan(cpp->currentInput, yylvalpp);
- }
- DecLineNumber();
- /*store this msg into the shader's information log..set the Compile Error flag!!!! */ - message=GetStrfromTStr();
- CPPShInfoLogMsg(message);
- ResetTString();
- cpp->CompileError=1;
- IncLineNumber();
- return '\n';
-}/*CPPerror */ -
-static int CPPpragma(yystypepp * yylvalpp)
-{
- char SrcStrName[2];
- char** allTokens;
- int tokenCount = 0;
- int maxTokenCount = 10;
- const char* SrcStr;
- int i;
-
- int token = cpp->currentInput->scan(cpp->currentInput, yylvalpp);
-
- if (token=='\n') {
- DecLineNumber();
- CPPErrorToInfoLog("#pragma");
- IncLineNumber();
- return token;
- }
-
- allTokens = (char**)malloc(sizeof(char*) * maxTokenCount);
-
- while (token != '\n') {
- if (tokenCount >= maxTokenCount) {
- maxTokenCount *= 2;
- allTokens = (char**)realloc((char**)allTokens, sizeof(char*) * maxTokenCount);
- }
- switch (token) {
- case CPP_IDENTIFIER:
- SrcStr = GetAtomString(atable, yylvalpp->sc_ident);
- allTokens[tokenCount] = (char*)malloc(strlen(SrcStr) + 1);
- strcpy(allTokens[tokenCount++], SrcStr);
- break;
- case CPP_INTCONSTANT:
- SrcStr = yylvalpp->symbol_name;
- allTokens[tokenCount] = (char*)malloc(strlen(SrcStr) + 1);
- strcpy(allTokens[tokenCount++], SrcStr);
- break;
- case CPP_FLOATCONSTANT:
- SrcStr = yylvalpp->symbol_name;
- allTokens[tokenCount] = (char*)malloc(strlen(SrcStr) + 1);
- strcpy(allTokens[tokenCount++], SrcStr);
- break;
- case -1:
- /* EOF */ - CPPShInfoLogMsg("#pragma directive must end with a newline");
- return token;
- default:
- SrcStrName[0] = token;
- SrcStrName[1] = '\0';
- allTokens[tokenCount] = (char*)malloc(2);
- strcpy(allTokens[tokenCount++], SrcStrName);
- }
- token = cpp->currentInput->scan(cpp->currentInput, yylvalpp);
- }
-
- cpp->currentInput->ungetch(cpp->currentInput, token, yylvalpp);
- HandlePragma(allTokens, tokenCount);
- token = cpp->currentInput->scan(cpp->currentInput, yylvalpp);
-
- for (i = 0; i < tokenCount; ++i) {
- free (allTokens[i]);
- }
- free (allTokens);
-
- return token;
-} /* CPPpragma */ -
-#define GL2_VERSION_NUMBER 110
-
-static int CPPversion(yystypepp * yylvalpp)
-{
-
- int token = cpp->currentInput->scan(cpp->currentInput, yylvalpp);
-
- if (cpp->notAVersionToken == 1)
- CPPShInfoLogMsg("#version must occur before any other statement in the program");
-
- if(token=='\n'){
- DecLineNumber();
- CPPErrorToInfoLog("#version");
- IncLineNumber();
- return token;
- }
- if (token != CPP_INTCONSTANT)
- CPPErrorToInfoLog("#version");
-
- yylvalpp->sc_int=atoi(yylvalpp->symbol_name);
- /*SetVersionNumber(yylvalpp->sc_int); */ -
- if (yylvalpp->sc_int != GL2_VERSION_NUMBER)
- CPPShInfoLogMsg("Version number not supported by GL2");
-
- token = cpp->currentInput->scan(cpp->currentInput, yylvalpp);
-
- if (token == '\n'){
- return token;
- }
- else{
- CPPErrorToInfoLog("#version");
- }
- return token;
-} /* CPPversion */ -
-static int CPPextension(yystypepp * yylvalpp)
-{
-
- int token = cpp->currentInput->scan(cpp->currentInput, yylvalpp);
- char extensionName[80];
-
- if(token=='\n'){
- DecLineNumber();
- CPPShInfoLogMsg("extension name not specified");
- IncLineNumber();
- return token;
- }
-
- if (token != CPP_IDENTIFIER)
- CPPErrorToInfoLog("#extension");
-
- strcpy(extensionName, GetAtomString(atable, yylvalpp->sc_ident));
-
- token = cpp->currentInput->scan(cpp->currentInput, yylvalpp);
- if (token != ':') {
- CPPShInfoLogMsg("':' missing after extension name");
- return token;
- }
-
- token = cpp->currentInput->scan(cpp->currentInput, yylvalpp);
- if (token != CPP_IDENTIFIER) {
- CPPShInfoLogMsg("behavior for extension not specified");
- return token;
- }
-
- updateExtensionBehavior(extensionName, GetAtomString(atable, yylvalpp->sc_ident));
-
- token = cpp->currentInput->scan(cpp->currentInput, yylvalpp);
- if (token == '\n'){
- return token;
- }
- else{
- CPPErrorToInfoLog("#extension");
- }
- return token;
-} /* CPPextension */ -
-int readCPPline(yystypepp * yylvalpp)
-{
- int token = cpp->currentInput->scan(cpp->currentInput, yylvalpp);
- const char *message;
- int isVersion = 0;
-
- if (token == CPP_IDENTIFIER) {
- if (yylvalpp->sc_ident == defineAtom) {
- token = CPPdefine(yylvalpp);
- } else if (yylvalpp->sc_ident == elseAtom) {
- if(ChkCorrectElseNesting()){
- if (!cpp->ifdepth ){
- CPPErrorToInfoLog("#else mismatch");
- cpp->CompileError=1;
- }
- token = cpp->currentInput->scan(cpp->currentInput, yylvalpp);
- if (token != '\n') {
- CPPWarningToInfoLog("unexpected tokens following #else preprocessor directive - expected a newline");
- while (token != '\n')
- token = cpp->currentInput->scan(cpp->currentInput, yylvalpp);
- }
- token = CPPelse(0, yylvalpp);
- }else{
- CPPErrorToInfoLog("#else after a #else");
- cpp->ifdepth=0;
- cpp->notAVersionToken = 1;
- return 0;
- }
- } else if (yylvalpp->sc_ident == elifAtom) {
- if (!cpp->ifdepth){
- CPPErrorToInfoLog("#elif mismatch");
- cpp->CompileError=1;
- }
- /* this token is really a dont care, but we still need to eat the tokens */ - token = cpp->currentInput->scan(cpp->currentInput, yylvalpp);
- while (token != '\n')
- token = cpp->currentInput->scan(cpp->currentInput, yylvalpp);
- token = CPPelse(0, yylvalpp);
- } else if (yylvalpp->sc_ident == endifAtom) {
- cpp->elsedepth[cpp->elsetracker]=0;
- --cpp->elsetracker;
- if (!cpp->ifdepth){
- CPPErrorToInfoLog("#endif mismatch");
- cpp->CompileError=1;
- }
- else
- --cpp->ifdepth;
- } else if (yylvalpp->sc_ident == ifAtom) {
- token = CPPif(yylvalpp);
- } else if (yylvalpp->sc_ident == ifdefAtom) {
- token = CPPifdef(1, yylvalpp);
- } else if (yylvalpp->sc_ident == ifndefAtom) {
- token = CPPifdef(0, yylvalpp);
- } else if (yylvalpp->sc_ident == lineAtom) {
- token = CPPline(yylvalpp);
- } else if (yylvalpp->sc_ident == pragmaAtom) {
- token = CPPpragma(yylvalpp);
- } else if (yylvalpp->sc_ident == undefAtom) {
- token = CPPundef(yylvalpp);
- } else if (yylvalpp->sc_ident == errorAtom) {
- token = CPPerror(yylvalpp);
- } else if (yylvalpp->sc_ident == versionAtom) {
- token = CPPversion(yylvalpp);
- isVersion = 1;
- } else if (yylvalpp->sc_ident == extensionAtom) {
- token = CPPextension(yylvalpp);
- } else {
- StoreStr("Invalid Directive");
- StoreStr(GetStringOfAtom(atable,yylvalpp->sc_ident));
- message=GetStrfromTStr();
- CPPShInfoLogMsg(message);
- ResetTString();
- }
- }
- while (token != '\n' && token != 0 && token != EOF) {
- token = cpp->currentInput->scan(cpp->currentInput, yylvalpp);
- }
-
- cpp->notAVersionToken = !isVersion;
-
- return token;
-} /* readCPPline */ -
-void FreeMacro(MacroSymbol *s) {
- DeleteTokenStream(s->body);
-}
-
-static int eof_scan(InputSrc *in, yystypepp * yylvalpp) { return -1; }
-static void noop(InputSrc *in, int ch, yystypepp * yylvalpp) { }
-
-static void PushEofSrc() {
- InputSrc *in = malloc(sizeof(InputSrc));
- memset(in, 0, sizeof(InputSrc));
- in->scan = eof_scan;
- in->getch = eof_scan;
- in->ungetch = noop;
- in->prev = cpp->currentInput;
- cpp->currentInput = in;
-}
-
-static void PopEofSrc() {
- if (cpp->currentInput->scan == eof_scan) {
- InputSrc *in = cpp->currentInput;
- cpp->currentInput = in->prev;
- free(in);
- }
-}
-
-static TokenStream *PrescanMacroArg(TokenStream *a, yystypepp * yylvalpp) {
- int token;
- TokenStream *n;
- RewindTokenStream(a);
- do {
- token = ReadToken(a, yylvalpp);
- if (token == CPP_IDENTIFIER && LookUpSymbol(macros, yylvalpp->sc_ident))
- break;
- } while (token > 0);
- if (token <= 0) return a;
- n = NewTokenStream("macro arg");
- PushEofSrc();
- ReadFromTokenStream(a, 0, 0);
- while ((token = cpp->currentInput->scan(cpp->currentInput, yylvalpp)) > 0) {
- if (token == CPP_IDENTIFIER && MacroExpand(yylvalpp->sc_ident, yylvalpp))
- continue;
- RecordToken(n, token, yylvalpp);
- }
- PopEofSrc();
- DeleteTokenStream(a);
- return n;
-} /* PrescanMacroArg */ -
-typedef struct MacroInputSrc {
- InputSrc base;
- MacroSymbol *mac;
- TokenStream **args;
-} MacroInputSrc;
-
-/* macro_scan ---
-** return the next token for a macro expanion, handling macro args
-*/
-static int macro_scan(MacroInputSrc *in, yystypepp * yylvalpp) {
- int i;
- int token = ReadToken(in->mac->body, yylvalpp);
- if (token == CPP_IDENTIFIER) {
- for (i = in->mac->argc-1; i>=0; i--)
- if (in->mac->args[i] == yylvalpp->sc_ident) break;
- if (i >= 0) {
- ReadFromTokenStream(in->args[i], yylvalpp->sc_ident, 0);
- return cpp->currentInput->scan(cpp->currentInput, yylvalpp);
- }
- }
- if (token > 0) return token;
- in->mac->busy = 0;
- cpp->currentInput = in->base.prev;
- if (in->args) {
- for (i=in->mac->argc-1; i>=0; i--)
- DeleteTokenStream(in->args[i]);
- free(in->args);
- }
- free(in);
- return cpp->currentInput->scan(cpp->currentInput, yylvalpp);
-} /* macro_scan */ -
-/* MacroExpand
-** check an identifier (atom) to see if it a macro that should be expanded.
-** If it is, push an InputSrc that will produce the appropriate expansion
-** and return TRUE. If not, return FALSE.
-*/
-
-int MacroExpand(int atom, yystypepp * yylvalpp)
-{
- Symbol *sym = LookUpSymbol(macros, atom);
- MacroInputSrc *in;
- int i,j, token, depth=0;
- const char *message;
- if (atom == __LINE__Atom) {
- yylvalpp->sc_int = GetLineNumber();
- sprintf(yylvalpp->symbol_name,"%d",yylvalpp->sc_int);
- UngetToken(CPP_INTCONSTANT, yylvalpp);
- return 1;
- }
- if (atom == __FILE__Atom) {
- yylvalpp->sc_int = GetStringNumber();
- sprintf(yylvalpp->symbol_name,"%d",yylvalpp->sc_int);
- UngetToken(CPP_INTCONSTANT, yylvalpp);
- return 1;
- }
- if (atom == __VERSION__Atom) {
- strcpy(yylvalpp->symbol_name,"100");
- yylvalpp->sc_int = atoi(yylvalpp->symbol_name);
- UngetToken(CPP_INTCONSTANT, yylvalpp);
- return 1;
- }
- if (!sym || sym->details.mac.undef) return 0;
- if (sym->details.mac.busy) return 0; /* no recursive expansions */ - in = malloc(sizeof(*in));
- memset(in, 0, sizeof(*in));
- in->base.scan = (void *)macro_scan;
- in->base.line = cpp->currentInput->line;
- in->base.name = cpp->currentInput->name;
- in->mac = &sym->details.mac;
- if (sym->details.mac.args) {
- token = cpp->currentInput->scan(cpp->currentInput, yylvalpp);
- if (token != '(') {
- UngetToken(token, yylvalpp);
- yylvalpp->sc_ident = atom;
- return 0;
- }
- in->args = malloc(in->mac->argc * sizeof(TokenStream *));
- for (i=0; i<in->mac->argc; i++)
- in->args[i] = NewTokenStream("macro arg");
- i=0;j=0;
- do{
- depth = 0;
- while(1) {
- token = cpp->currentInput->scan(cpp->currentInput, yylvalpp);
- if (token <= 0) {
- StoreStr("EOF in Macro ");
- StoreStr(GetStringOfAtom(atable,atom));
- message=GetStrfromTStr();
- CPPShInfoLogMsg(message);
- ResetTString();
- return 1;
- }
- if((in->mac->argc==0) && (token!=')')) break;
- if (depth == 0 && (token == ',' || token == ')')) break;
- if (token == '(') depth++;
- if (token == ')') depth--;
- RecordToken(in->args[i], token, yylvalpp);
- j=1;
- }
- if (token == ')') {
- if((in->mac->argc==1) &&j==0)
- break;
- i++;
- break;
- }
- i++;
- }while(i < in->mac->argc);
-
- if (i < in->mac->argc) {
- StoreStr("Too few args in Macro ");
- StoreStr(GetStringOfAtom(atable,atom));
- message=GetStrfromTStr();
- CPPShInfoLogMsg(message);
- ResetTString();
- } else if (token != ')') {
- depth=0;
- while (token >= 0 && (depth > 0 || token != ')')) {
- if (token == ')') depth--;
- token = cpp->currentInput->scan(cpp->currentInput, yylvalpp);
- if (token == '(') depth++;
- }
-
- if (token <= 0) {
- StoreStr("EOF in Macro ");
- StoreStr(GetStringOfAtom(atable,atom));
- message=GetStrfromTStr();
- CPPShInfoLogMsg(message);
- ResetTString();
- return 1;
- }
- StoreStr("Too many args in Macro ");
- StoreStr(GetStringOfAtom(atable,atom));
- message=GetStrfromTStr();
- CPPShInfoLogMsg(message);
- ResetTString();
- }
- for (i=0; i<in->mac->argc; i++) {
- in->args[i] = PrescanMacroArg(in->args[i], yylvalpp);
- }
- }
-#if 0
- printf(" <%s:%d>found macro %s\n", GetAtomString(atable, loc.file),
- loc.line, GetAtomString(atable, atom));
- for (i=0; i<in->mac->argc; i++) {
- printf("\targ %s = '", GetAtomString(atable, in->mac->args[i]));
- DumpTokenStream(stdout, in->args[i]);
- printf("'\n");
- }
-#endif
- /*retain the input source*/
- in->base.prev = cpp->currentInput;
- sym->details.mac.busy = 1;
- RewindTokenStream(sym->details.mac.body);
- cpp->currentInput = &in->base;
- return 1;
-} /* MacroExpand */ -
-int ChkCorrectElseNesting(void)
-{
- if(cpp->elsedepth[cpp->elsetracker]==0){
- cpp->elsedepth[cpp->elsetracker]=1;
- return 1;
- }
- return 0;
-}
-
-
diff --git a/src/mesa/shader/slang/MachineIndependent/preprocessor/cpp.h b/src/mesa/shader/slang/MachineIndependent/preprocessor/cpp.h deleted file mode 100755 index 03449a17a9..0000000000 --- a/src/mesa/shader/slang/MachineIndependent/preprocessor/cpp.h +++ /dev/null @@ -1,119 +0,0 @@ -/* */ -/*Copyright (C) 2002-2005 3Dlabs Inc. Ltd. */ -/*All rights reserved. */ -/* */ -/*Redistribution and use in source and binary forms, with or without */ -/*modification, are permitted provided that the following conditions */ -/*are met: */ -/* */ -/* Redistributions of source code must retain the above copyright */ -/* notice, this list of conditions and the following disclaimer. */ -/* */ -/* Redistributions in binary form must reproduce the above */ -/* copyright notice, this list of conditions and the following */ -/* disclaimer in the documentation and/or other materials provided */ -/* with the distribution. */ -/* */ -/* Neither the name of 3Dlabs Inc. Ltd. nor the names of its */ -/* contributors may be used to endorse or promote products derived */ -/* from this software without specific prior written permission. */ -/* */ -/*THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS */ -/*"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT */ -/*LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS */ -/*FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE */ -/*COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, */ -/*INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, */ -/*BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; */ -/*LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER */ -/*CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT */ -/*LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN */ -/*ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE */ -/*POSSIBILITY OF SUCH DAMAGE. */ -/* */ -/****************************************************************************\
-Copyright (c) 2002, NVIDIA Corporation.
-
-NVIDIA Corporation("NVIDIA") supplies this software to you in
-consideration of your agreement to the following terms, and your use,
-installation, modification or redistribution of this NVIDIA software
-constitutes acceptance of these terms. If you do not agree with these
-terms, please do not use, install, modify or redistribute this NVIDIA
-software.
-
-In consideration of your agreement to abide by the following terms, and
-subject to these terms, NVIDIA grants you a personal, non-exclusive
-license, under NVIDIA's copyrights in this original NVIDIA software (the
-"NVIDIA Software"), to use, reproduce, modify and redistribute the
-NVIDIA Software, with or without modifications, in source and/or binary
-forms; provided that if you redistribute the NVIDIA Software, you must
-retain the copyright notice of NVIDIA, this notice and the following
-text and disclaimers in all such redistributions of the NVIDIA Software.
-Neither the name, trademarks, service marks nor logos of NVIDIA
-Corporation may be used to endorse or promote products derived from the
-NVIDIA Software without specific prior written permission from NVIDIA.
-Except as expressly stated in this notice, no other rights or licenses
-express or implied, are granted by NVIDIA herein, including but not
-limited to any patent rights that may be infringed by your derivative
-works or by other works in which the NVIDIA Software may be
-incorporated. No hardware is licensed hereunder.
-
-THE NVIDIA SOFTWARE IS BEING PROVIDED ON AN "AS IS" BASIS, WITHOUT
-WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED,
-INCLUDING WITHOUT LIMITATION, WARRANTIES OR CONDITIONS OF TITLE,
-NON-INFRINGEMENT, MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR
-ITS USE AND OPERATION EITHER ALONE OR IN COMBINATION WITH OTHER
-PRODUCTS.
-
-IN NO EVENT SHALL NVIDIA BE LIABLE FOR ANY SPECIAL, INDIRECT,
-INCIDENTAL, EXEMPLARY, CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
-TO, LOST PROFITS; PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
-USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) OR ARISING IN ANY WAY
-OUT OF THE USE, REPRODUCTION, MODIFICATION AND/OR DISTRIBUTION OF THE
-NVIDIA SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER THEORY OF CONTRACT,
-TORT (INCLUDING NEGLIGENCE), STRICT LIABILITY OR OTHERWISE, EVEN IF
-NVIDIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-\****************************************************************************/
-/* */ -/* cpp.h */ -/* */ -
-#if !defined(__CPP_H)
-#define __CPP_H 1
-
-#include "parser.h"
-#include "tokens.h"
-
-int InitCPP(void);
-int FinalCPP(void);
-int readCPPline(yystypepp * yylvalpp);
-int MacroExpand(int atom, yystypepp * yylvalpp);
-int ChkCorrectElseNesting(void);
-
-typedef struct MacroSymbol {
- int argc;
- int *args;
- TokenStream *body;
- unsigned busy:1;
- unsigned undef:1;
-} MacroSymbol;
-
-void FreeMacro(MacroSymbol *);
-int PredefineMacro(char *);
-
-void CPPDebugLogMsg(const char *msg); /* Prints information into debug log */ -void CPPShInfoLogMsg(const char*); /* Store cpp Err Msg into Sh.Info.Log */ -void CPPWarningToInfoLog(const char *msg); /* Prints warning messages into info log */ -void HandlePragma(const char**, int numTokens); /* #pragma directive container. */ -void ResetTString(void); /* #error Message as TString. */ -void CPPErrorToInfoLog(char*); /* Stick all cpp errors into Sh.Info.log . */ -void StoreStr(char*); /* Store the TString in Parse Context. */ -void SetLineNumber(int); /* Set line number. */ -void SetStringNumber(int); /* Set string number. */ -int GetLineNumber(void); /* Get the current String Number. */ -int GetStringNumber(void); /* Get the current String Number. */ -const char* GetStrfromTStr(void); /* Convert TString to String. */ -void updateExtensionBehavior(const char* extName, const char* behavior);
-int FreeCPP(void);
-
-#endif /* !(defined(__CPP_H) */ diff --git a/src/mesa/shader/slang/MachineIndependent/preprocessor/cpp_comment_fix.c b/src/mesa/shader/slang/MachineIndependent/preprocessor/cpp_comment_fix.c deleted file mode 100644 index 0c3073590d..0000000000 --- a/src/mesa/shader/slang/MachineIndependent/preprocessor/cpp_comment_fix.c +++ /dev/null @@ -1,76 +0,0 @@ -/* converts c++ to c comments */ -/* usage: ./cpp_comment_fix source */ - -#include <stdio.h> - -int main (int argc, char *argv[]) -{ - FILE *f; - int c; - char *buf = NULL; - int size = 0, i = 0; - - f = fopen (argv[1], "r"); - while ((c = fgetc (f)) != EOF) - { - buf = (void *) realloc (buf, size + 1); - buf[size] = c; - size++; - } - fclose (f); - - f = fopen (argv[1], "w"); - - while (i < size) - { - if (buf[i] == '/') - { - if (buf[i+1] == '/') - { - fprintf (f, "/*"); - i+=2; - while (buf[i] != '\n' && buf[i] != '\r' && i < size) - fprintf (f, "%c", buf[i++]); - fprintf (f, " */\n"); - if (i < size && buf[i] == '\n') - i++; - else if (i < size && buf[i] == '\r') - i+=2; - } - else - { - fprintf (f, "/"); - i++; - - if (buf[i] == '*') - { - fprintf (f, "*"); - i++; - - for (;;) - { - if (buf[i] == '*' && buf[i+1] == '/') - { - fprintf (f, "*/"); - i+=2; - break; - } - else - { - fprintf (f, "%c", buf[i]); - i++; - } - } - } - } - } - else - { - fprintf (f, "%c", buf[i]); - i++; - } - } - fclose (f); - return 0; -} - diff --git a/src/mesa/shader/slang/MachineIndependent/preprocessor/cppstruct.c b/src/mesa/shader/slang/MachineIndependent/preprocessor/cppstruct.c deleted file mode 100755 index c55b3f7c70..0000000000 --- a/src/mesa/shader/slang/MachineIndependent/preprocessor/cppstruct.c +++ /dev/null @@ -1,185 +0,0 @@ -/* */ -/*Copyright (C) 2002-2005 3Dlabs Inc. Ltd. */ -/*All rights reserved. */ -/* */ -/*Redistribution and use in source and binary forms, with or without */ -/*modification, are permitted provided that the following conditions */ -/*are met: */ -/* */ -/* Redistributions of source code must retain the above copyright */ -/* notice, this list of conditions and the following disclaimer. */ -/* */ -/* Redistributions in binary form must reproduce the above */ -/* copyright notice, this list of conditions and the following */ -/* disclaimer in the documentation and/or other materials provided */ -/* with the distribution. */ -/* */ -/* Neither the name of 3Dlabs Inc. Ltd. nor the names of its */ -/* contributors may be used to endorse or promote products derived */ -/* from this software without specific prior written permission. */ -/* */ -/*THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS */ -/*"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT */ -/*LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS */ -/*FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE */ -/*COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, */ -/*INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, */ -/*BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; */ -/*LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER */ -/*CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT */ -/*LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN */ -/*ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE */ -/*POSSIBILITY OF SUCH DAMAGE. */ -/* */ -/****************************************************************************\
-Copyright (c) 2002, NVIDIA Corporation.
-
-NVIDIA Corporation("NVIDIA") supplies this software to you in
-consideration of your agreement to the following terms, and your use,
-installation, modification or redistribution of this NVIDIA software
-constitutes acceptance of these terms. If you do not agree with these
-terms, please do not use, install, modify or redistribute this NVIDIA
-software.
-
-In consideration of your agreement to abide by the following terms, and
-subject to these terms, NVIDIA grants you a personal, non-exclusive
-license, under NVIDIA's copyrights in this original NVIDIA software (the
-"NVIDIA Software"), to use, reproduce, modify and redistribute the
-NVIDIA Software, with or without modifications, in source and/or binary
-forms; provided that if you redistribute the NVIDIA Software, you must
-retain the copyright notice of NVIDIA, this notice and the following
-text and disclaimers in all such redistributions of the NVIDIA Software.
-Neither the name, trademarks, service marks nor logos of NVIDIA
-Corporation may be used to endorse or promote products derived from the
-NVIDIA Software without specific prior written permission from NVIDIA.
-Except as expressly stated in this notice, no other rights or licenses
-express or implied, are granted by NVIDIA herein, including but not
-limited to any patent rights that may be infringed by your derivative
-works or by other works in which the NVIDIA Software may be
-incorporated. No hardware is licensed hereunder.
-
-THE NVIDIA SOFTWARE IS BEING PROVIDED ON AN "AS IS" BASIS, WITHOUT
-WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED,
-INCLUDING WITHOUT LIMITATION, WARRANTIES OR CONDITIONS OF TITLE,
-NON-INFRINGEMENT, MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR
-ITS USE AND OPERATION EITHER ALONE OR IN COMBINATION WITH OTHER
-PRODUCTS.
-
-IN NO EVENT SHALL NVIDIA BE LIABLE FOR ANY SPECIAL, INDIRECT,
-INCIDENTAL, EXEMPLARY, CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
-TO, LOST PROFITS; PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
-USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) OR ARISING IN ANY WAY
-OUT OF THE USE, REPRODUCTION, MODIFICATION AND/OR DISTRIBUTION OF THE
-NVIDIA SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER THEORY OF CONTRACT,
-TORT (INCLUDING NEGLIGENCE), STRICT LIABILITY OR OTHERWISE, EVEN IF
-NVIDIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-\****************************************************************************/
-/* */ -/* cppstruct.c */ -/* */ -
-#include <stdio.h>
-#include <stdlib.h>
-
-#include "slglobals.h"
-
-CPPStruct *cpp = NULL;
-static int refCount = 0;
-
-int InitPreprocessor(void);
-int ResetPreprocessor(void);
-int FreeCPPStruct(void);
-int FinalizePreprocessor(void);
-
-/*
- * InitCPPStruct() - Initilaize the CPP structure.
- *
- */
-
-int InitCPPStruct(void)
-{
- int len;
- char *p;
-
- cpp = (CPPStruct *) malloc(sizeof(CPPStruct));
- if (cpp == NULL)
- return 0;
-
- refCount++;
-
- /* Initialize public members: */ - cpp->pLastSourceLoc = &cpp->lastSourceLoc;
-
- p = (char *) &cpp->options;
- len = sizeof(cpp->options);
- while (--len >= 0)
- p[len] = 0;
-
- ResetPreprocessor();
- return 1;
-} /* InitCPPStruct */ -
-int ResetPreprocessor(void)
-{
- /* Initialize private members: */ -
- cpp->lastSourceLoc.file = 0;
- cpp->lastSourceLoc.line = 0;
- cpp->pC=0;
- cpp->CompileError=0;
- cpp->ifdepth=0;
- for(cpp->elsetracker=0; cpp->elsetracker<64; cpp->elsetracker++)
- cpp->elsedepth[cpp->elsetracker]=0;
- cpp->elsetracker=0;
- cpp->tokensBeforeEOF = 0;
- return 1;
-}
-
-/*Intializing the Preprocessor. */ -
-int InitPreprocessor(void)
-{
- # define CPP_STUFF true
- # ifdef CPP_STUFF
- FreeCPPStruct();
- InitCPPStruct();
- cpp->options.Quiet = 1;
- cpp->options.profileString = "generic";
- if (!InitAtomTable(atable, 0))
- return 1;
- if (!InitScanner(cpp))
- return 1;
- # endif
- return 0;
-}
-
-/*FreeCPPStruct() - Free the CPP structure. */ -
-int FreeCPPStruct(void)
-{
- if (refCount)
- {
- free(cpp);
- refCount--;
- }
-
- return 1;
-}
-
-/*Finalizing the Preprocessor. */ -
-int FinalizePreprocessor(void)
-{
- # define CPP_STUFF true
- # ifdef CPP_STUFF
- FreeAtomTable(atable);
- FreeCPPStruct();
- FreeScanner();
- # endif
- return 0;
-}
-
-
-/*///////////////////////////////////////////////////////////////////////////////////////////// */ -/*//////////////////////////////////// End of cppstruct.c ////////////////////////////////////// */ -/*///////////////////////////////////////////////////////////////////////////////////////////// */ diff --git a/src/mesa/shader/slang/MachineIndependent/preprocessor/memory.c b/src/mesa/shader/slang/MachineIndependent/preprocessor/memory.c deleted file mode 100755 index ed0f4fb4b9..0000000000 --- a/src/mesa/shader/slang/MachineIndependent/preprocessor/memory.c +++ /dev/null @@ -1,191 +0,0 @@ -/* */ -/*Copyright (C) 2002-2005 3Dlabs Inc. Ltd. */ -/*All rights reserved. */ -/* */ -/*Redistribution and use in source and binary forms, with or without */ -/*modification, are permitted provided that the following conditions */ -/*are met: */ -/* */ -/* Redistributions of source code must retain the above copyright */ -/* notice, this list of conditions and the following disclaimer. */ -/* */ -/* Redistributions in binary form must reproduce the above */ -/* copyright notice, this list of conditions and the following */ -/* disclaimer in the documentation and/or other materials provided */ -/* with the distribution. */ -/* */ -/* Neither the name of 3Dlabs Inc. Ltd. nor the names of its */ -/* contributors may be used to endorse or promote products derived */ -/* from this software without specific prior written permission. */ -/* */ -/*THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS */ -/*"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT */ -/*LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS */ -/*FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE */ -/*COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, */ -/*INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, */ -/*BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; */ -/*LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER */ -/*CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT */ -/*LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN */ -/*ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE */ -/*POSSIBILITY OF SUCH DAMAGE. */ -/* */ -/****************************************************************************\
-Copyright (c) 2002, NVIDIA Corporation.
-
-NVIDIA Corporation("NVIDIA") supplies this software to you in
-consideration of your agreement to the following terms, and your use,
-installation, modification or redistribution of this NVIDIA software
-constitutes acceptance of these terms. If you do not agree with these
-terms, please do not use, install, modify or redistribute this NVIDIA
-software.
-
-In consideration of your agreement to abide by the following terms, and
-subject to these terms, NVIDIA grants you a personal, non-exclusive
-license, under NVIDIA's copyrights in this original NVIDIA software (the
-"NVIDIA Software"), to use, reproduce, modify and redistribute the
-NVIDIA Software, with or without modifications, in source and/or binary
-forms; provided that if you redistribute the NVIDIA Software, you must
-retain the copyright notice of NVIDIA, this notice and the following
-text and disclaimers in all such redistributions of the NVIDIA Software.
-Neither the name, trademarks, service marks nor logos of NVIDIA
-Corporation may be used to endorse or promote products derived from the
-NVIDIA Software without specific prior written permission from NVIDIA.
-Except as expressly stated in this notice, no other rights or licenses
-express or implied, are granted by NVIDIA herein, including but not
-limited to any patent rights that may be infringed by your derivative
-works or by other works in which the NVIDIA Software may be
-incorporated. No hardware is licensed hereunder.
-
-THE NVIDIA SOFTWARE IS BEING PROVIDED ON AN "AS IS" BASIS, WITHOUT
-WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED,
-INCLUDING WITHOUT LIMITATION, WARRANTIES OR CONDITIONS OF TITLE,
-NON-INFRINGEMENT, MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR
-ITS USE AND OPERATION EITHER ALONE OR IN COMBINATION WITH OTHER
-PRODUCTS.
-
-IN NO EVENT SHALL NVIDIA BE LIABLE FOR ANY SPECIAL, INDIRECT,
-INCIDENTAL, EXEMPLARY, CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
-TO, LOST PROFITS; PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
-USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) OR ARISING IN ANY WAY
-OUT OF THE USE, REPRODUCTION, MODIFICATION AND/OR DISTRIBUTION OF THE
-NVIDIA SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER THEORY OF CONTRACT,
-TORT (INCLUDING NEGLIGENCE), STRICT LIABILITY OR OTHERWISE, EVEN IF
-NVIDIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-\****************************************************************************/
-/* */ -#include <stddef.h>
-#include <stdlib.h>
-#include <string.h>
-
-#ifdef __STDC99__
-#include <stdint.h>
-#elif defined (_WIN64)
-typedef unsigned __int64 uintptr_t;
-#else
-typedef unsigned int uintptr_t;
-#endif
-
-#include "memory.h"
-
-/* default alignment and chunksize, if called with 0 arguments */ -#define CHUNKSIZE (64*1024)
-#define ALIGN 8
-
-/* we need to call the `real' malloc and free, not our replacements */ -#undef malloc
-#undef free
-
-struct chunk {
- struct chunk *next;
-};
-
-struct cleanup {
- struct cleanup *next;
- void (*fn)(void *);
- void *arg;
-};
-
-struct MemoryPool_rec {
- struct chunk *next;
- uintptr_t free, end;
- size_t chunksize;
- uintptr_t alignmask;
- struct cleanup *cleanup;
-};
-
-MemoryPool *mem_CreatePool(size_t chunksize, unsigned int align)
-{
- MemoryPool *pool;
-
- if (align == 0) align = ALIGN;
- if (chunksize == 0) chunksize = CHUNKSIZE;
- if (align & (align-1)) return 0;
- if (chunksize < sizeof(MemoryPool)) return 0;
- if (chunksize & (align-1)) return 0;
- if (!(pool = malloc(chunksize))) return 0;
- pool->next = 0;
- pool->chunksize = chunksize;
- pool->alignmask = (uintptr_t)(align)-1;
- pool->free = ((uintptr_t)(pool + 1) + pool->alignmask) & ~pool->alignmask;
- pool->end = (uintptr_t)pool + chunksize;
- pool->cleanup = 0;
- return pool;
-}
-
-void mem_FreePool(MemoryPool *pool)
-{
- struct cleanup *cleanup;
- struct chunk *p, *next;
-
- for (cleanup = pool->cleanup; cleanup; cleanup = cleanup->next) {
- cleanup->fn(cleanup->arg);
- }
- for (p = (struct chunk *)pool; p; p = next) {
- next = p->next;
- free(p);
- }
-}
-
-void *mem_Alloc(MemoryPool *pool, size_t size)
-{
- struct chunk *ch;
- void *rv = (void *)pool->free;
- size = (size + pool->alignmask) & ~pool->alignmask;
- if (size <= 0) size = pool->alignmask;
- pool->free += size;
- if (pool->free > pool->end || pool->free < (uintptr_t)rv) {
- size_t minreq = (size + sizeof(struct chunk) + pool->alignmask)
- & ~pool->alignmask;
- pool->free = (uintptr_t)rv;
- if (minreq >= pool->chunksize) {
- /* request size is too big for the chunksize, so allocate it as */ - /* a single chunk of the right size */ - ch = malloc(minreq);
- if (!ch) return 0;
- } else {
- ch = malloc(pool->chunksize);
- if (!ch) return 0;
- pool->free = (uintptr_t)ch + minreq;
- pool->end = (uintptr_t)ch + pool->chunksize;
- }
- ch->next = pool->next;
- pool->next = ch;
- rv = (void *)(((uintptr_t)(ch+1) + pool->alignmask) & ~pool->alignmask);
- }
- return rv;
-}
-
-int mem_AddCleanup(MemoryPool *pool, void (*fn)(void *), void *arg) {
- struct cleanup *cleanup;
-
- pool->free = (pool->free + sizeof(void *) - 1) & ~(sizeof(void *)-1);
- cleanup = mem_Alloc(pool, sizeof(struct cleanup));
- if (!cleanup) return -1;
- cleanup->next = pool->cleanup;
- cleanup->fn = fn;
- cleanup->arg = arg;
- pool->cleanup = cleanup;
- return 0;
-}
diff --git a/src/mesa/shader/slang/MachineIndependent/preprocessor/memory.h b/src/mesa/shader/slang/MachineIndependent/preprocessor/memory.h deleted file mode 100755 index 89a57e24c9..0000000000 --- a/src/mesa/shader/slang/MachineIndependent/preprocessor/memory.h +++ /dev/null @@ -1,89 +0,0 @@ -/* */ -/*Copyright (C) 2002-2005 3Dlabs Inc. Ltd. */ -/*All rights reserved. */ -/* */ -/*Redistribution and use in source and binary forms, with or without */ -/*modification, are permitted provided that the following conditions */ -/*are met: */ -/* */ -/* Redistributions of source code must retain the above copyright */ -/* notice, this list of conditions and the following disclaimer. */ -/* */ -/* Redistributions in binary form must reproduce the above */ -/* copyright notice, this list of conditions and the following */ -/* disclaimer in the documentation and/or other materials provided */ -/* with the distribution. */ -/* */ -/* Neither the name of 3Dlabs Inc. Ltd. nor the names of its */ -/* contributors may be used to endorse or promote products derived */ -/* from this software without specific prior written permission. */ -/* */ -/*THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS */ -/*"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT */ -/*LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS */ -/*FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE */ -/*COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, */ -/*INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, */ -/*BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; */ -/*LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER */ -/*CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT */ -/*LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN */ -/*ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE */ -/*POSSIBILITY OF SUCH DAMAGE. */ -/* */ -/****************************************************************************\
-Copyright (c) 2002, NVIDIA Corporation.
-
-NVIDIA Corporation("NVIDIA") supplies this software to you in
-consideration of your agreement to the following terms, and your use,
-installation, modification or redistribution of this NVIDIA software
-constitutes acceptance of these terms. If you do not agree with these
-terms, please do not use, install, modify or redistribute this NVIDIA
-software.
-
-In consideration of your agreement to abide by the following terms, and
-subject to these terms, NVIDIA grants you a personal, non-exclusive
-license, under NVIDIA's copyrights in this original NVIDIA software (the
-"NVIDIA Software"), to use, reproduce, modify and redistribute the
-NVIDIA Software, with or without modifications, in source and/or binary
-forms; provided that if you redistribute the NVIDIA Software, you must
-retain the copyright notice of NVIDIA, this notice and the following
-text and disclaimers in all such redistributions of the NVIDIA Software.
-Neither the name, trademarks, service marks nor logos of NVIDIA
-Corporation may be used to endorse or promote products derived from the
-NVIDIA Software without specific prior written permission from NVIDIA.
-Except as expressly stated in this notice, no other rights or licenses
-express or implied, are granted by NVIDIA herein, including but not
-limited to any patent rights that may be infringed by your derivative
-works or by other works in which the NVIDIA Software may be
-incorporated. No hardware is licensed hereunder.
-
-THE NVIDIA SOFTWARE IS BEING PROVIDED ON AN "AS IS" BASIS, WITHOUT
-WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED,
-INCLUDING WITHOUT LIMITATION, WARRANTIES OR CONDITIONS OF TITLE,
-NON-INFRINGEMENT, MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR
-ITS USE AND OPERATION EITHER ALONE OR IN COMBINATION WITH OTHER
-PRODUCTS.
-
-IN NO EVENT SHALL NVIDIA BE LIABLE FOR ANY SPECIAL, INDIRECT,
-INCIDENTAL, EXEMPLARY, CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
-TO, LOST PROFITS; PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
-USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) OR ARISING IN ANY WAY
-OUT OF THE USE, REPRODUCTION, MODIFICATION AND/OR DISTRIBUTION OF THE
-NVIDIA SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER THEORY OF CONTRACT,
-TORT (INCLUDING NEGLIGENCE), STRICT LIABILITY OR OTHERWISE, EVEN IF
-NVIDIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-\****************************************************************************/
-/* */ -#ifndef __MEMORY_H
-#define __MEMORY_H
-
-typedef struct MemoryPool_rec MemoryPool;
-
-extern MemoryPool *mem_CreatePool(size_t chunksize, unsigned align);
-extern void mem_FreePool(MemoryPool *);
-extern void *mem_Alloc(MemoryPool *p, size_t size);
-extern void *mem_Realloc(MemoryPool *p, void *old, size_t oldsize, size_t newsize);
-extern int mem_AddCleanup(MemoryPool *p, void (*fn)(void *), void *arg);
-
-#endif /* __MEMORY_H */
diff --git a/src/mesa/shader/slang/MachineIndependent/preprocessor/parser.h b/src/mesa/shader/slang/MachineIndependent/preprocessor/parser.h deleted file mode 100755 index 5f70bdd1ac..0000000000 --- a/src/mesa/shader/slang/MachineIndependent/preprocessor/parser.h +++ /dev/null @@ -1,126 +0,0 @@ -/* */ -/*Copyright (C) 2002-2005 3Dlabs Inc. Ltd. */ -/*All rights reserved. */ -/* */ -/*Redistribution and use in source and binary forms, with or without */ -/*modification, are permitted provided that the following conditions */ -/*are met: */ -/* */ -/* Redistributions of source code must retain the above copyright */ -/* notice, this list of conditions and the following disclaimer. */ -/* */ -/* Redistributions in binary form must reproduce the above */ -/* copyright notice, this list of conditions and the following */ -/* disclaimer in the documentation and/or other materials provided */ -/* with the distribution. */ -/* */ -/* Neither the name of 3Dlabs Inc. Ltd. nor the names of its */ -/* contributors may be used to endorse or promote products derived */ -/* from this software without specific prior written permission. */ -/* */ -/*THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS */ -/*"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT */ -/*LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS */ -/*FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE */ -/*COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, */ -/*INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, */ -/*BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; */ -/*LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER */ -/*CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT */ -/*LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN */ -/*ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE */ -/*POSSIBILITY OF SUCH DAMAGE. */ -/* */ -/****************************************************************************\
-Copyright (c) 2002, NVIDIA Corporation.
-
-NVIDIA Corporation("NVIDIA") supplies this software to you in
-consideration of your agreement to the following terms, and your use,
-installation, modification or redistribution of this NVIDIA software
-constitutes acceptance of these terms. If you do not agree with these
-terms, please do not use, install, modify or redistribute this NVIDIA
-software.
-
-In consideration of your agreement to abide by the following terms, and
-subject to these terms, NVIDIA grants you a personal, non-exclusive
-license, under NVIDIA's copyrights in this original NVIDIA software (the
-"NVIDIA Software"), to use, reproduce, modify and redistribute the
-NVIDIA Software, with or without modifications, in source and/or binary
-forms; provided that if you redistribute the NVIDIA Software, you must
-retain the copyright notice of NVIDIA, this notice and the following
-text and disclaimers in all such redistributions of the NVIDIA Software.
-Neither the name, trademarks, service marks nor logos of NVIDIA
-Corporation may be used to endorse or promote products derived from the
-NVIDIA Software without specific prior written permission from NVIDIA.
-Except as expressly stated in this notice, no other rights or licenses
-express or implied, are granted by NVIDIA herein, including but not
-limited to any patent rights that may be infringed by your derivative
-works or by other works in which the NVIDIA Software may be
-incorporated. No hardware is licensed hereunder.
-
-THE NVIDIA SOFTWARE IS BEING PROVIDED ON AN "AS IS" BASIS, WITHOUT
-WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED,
-INCLUDING WITHOUT LIMITATION, WARRANTIES OR CONDITIONS OF TITLE,
-NON-INFRINGEMENT, MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR
-ITS USE AND OPERATION EITHER ALONE OR IN COMBINATION WITH OTHER
-PRODUCTS.
-
-IN NO EVENT SHALL NVIDIA BE LIABLE FOR ANY SPECIAL, INDIRECT,
-INCIDENTAL, EXEMPLARY, CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
-TO, LOST PROFITS; PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
-USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) OR ARISING IN ANY WAY
-OUT OF THE USE, REPRODUCTION, MODIFICATION AND/OR DISTRIBUTION OF THE
-NVIDIA SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER THEORY OF CONTRACT,
-TORT (INCLUDING NEGLIGENCE), STRICT LIABILITY OR OTHERWISE, EVEN IF
-NVIDIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-\****************************************************************************/
-
-#ifndef BISON_PARSER_H
-# define BISON_PARSER_H
-
-#ifndef yystypepp
-typedef struct {
- int sc_int;
- float sc_fval;
- int sc_ident;
- char symbol_name[MAX_SYMBOL_NAME_LEN+1];
-} yystypepp;
-
-# define YYSTYPE_IS_TRIVIAL 1
-#endif
-# define CPP_AND_OP 257
-# define CPP_SUB_ASSIGN 259
-# define CPP_MOD_ASSIGN 260
-# define CPP_ADD_ASSIGN 261
-# define CPP_DIV_ASSIGN 262
-# define CPP_MUL_ASSIGN 263
-# define CPP_EQ_OP 264
-# define CPP_XOR_OP 265
-# define ERROR_SY 266
-# define CPP_FLOATCONSTANT 267
-# define CPP_GE_OP 268
-# define CPP_RIGHT_OP 269
-# define CPP_IDENTIFIER 270
-# define CPP_INTCONSTANT 271
-# define CPP_LE_OP 272
-# define CPP_LEFT_OP 273
-# define CPP_DEC_OP 274
-# define CPP_NE_OP 275
-# define CPP_OR_OP 276
-# define CPP_INC_OP 277
-# define CPP_STRCONSTANT 278
-# define CPP_TYPEIDENTIFIER 279
-
-# define FIRST_USER_TOKEN_SY 289
-
-# define CPP_RIGHT_ASSIGN 280
-# define CPP_LEFT_ASSIGN 281
-# define CPP_AND_ASSIGN 282
-# define CPP_OR_ASSIGN 283
-# define CPP_XOR_ASSIGN 284
-# define CPP_LEFT_BRACKET 285
-# define CPP_RIGHT_BRACKET 286
-# define CPP_LEFT_BRACE 287
-# define CPP_RIGHT_BRACE 288
-
-#endif /* not BISON_PARSER_H */
diff --git a/src/mesa/shader/slang/MachineIndependent/preprocessor/preprocess.h b/src/mesa/shader/slang/MachineIndependent/preprocessor/preprocess.h deleted file mode 100755 index 63996d6695..0000000000 --- a/src/mesa/shader/slang/MachineIndependent/preprocessor/preprocess.h +++ /dev/null @@ -1,84 +0,0 @@ -/* */ -/*Copyright (C) 2002-2005 3Dlabs Inc. Ltd. */ -/*All rights reserved. */ -/* */ -/*Redistribution and use in source and binary forms, with or without */ -/*modification, are permitted provided that the following conditions */ -/*are met: */ -/* */ -/* Redistributions of source code must retain the above copyright */ -/* notice, this list of conditions and the following disclaimer. */ -/* */ -/* Redistributions in binary form must reproduce the above */ -/* copyright notice, this list of conditions and the following */ -/* disclaimer in the documentation and/or other materials provided */ -/* with the distribution. */ -/* */ -/* Neither the name of 3Dlabs Inc. Ltd. nor the names of its */ -/* contributors may be used to endorse or promote products derived */ -/* from this software without specific prior written permission. */ -/* */ -/*THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS */ -/*"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT */ -/*LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS */ -/*FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE */ -/*COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, */ -/*INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, */ -/*BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; */ -/*LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER */ -/*CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT */ -/*LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN */ -/*ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE */ -/*POSSIBILITY OF SUCH DAMAGE. */ -/* */ -/****************************************************************************\
-Copyright (c) 2002, NVIDIA Corporation.
-
-NVIDIA Corporation("NVIDIA") supplies this software to you in
-consideration of your agreement to the following terms, and your use,
-installation, modification or redistribution of this NVIDIA software
-constitutes acceptance of these terms. If you do not agree with these
-terms, please do not use, install, modify or redistribute this NVIDIA
-software.
-
-In consideration of your agreement to abide by the following terms, and
-subject to these terms, NVIDIA grants you a personal, non-exclusive
-license, under NVIDIA's copyrights in this original NVIDIA software (the
-"NVIDIA Software"), to use, reproduce, modify and redistribute the
-NVIDIA Software, with or without modifications, in source and/or binary
-forms; provided that if you redistribute the NVIDIA Software, you must
-retain the copyright notice of NVIDIA, this notice and the following
-text and disclaimers in all such redistributions of the NVIDIA Software.
-Neither the name, trademarks, service marks nor logos of NVIDIA
-Corporation may be used to endorse or promote products derived from the
-NVIDIA Software without specific prior written permission from NVIDIA.
-Except as expressly stated in this notice, no other rights or licenses
-express or implied, are granted by NVIDIA herein, including but not
-limited to any patent rights that may be infringed by your derivative
-works or by other works in which the NVIDIA Software may be
-incorporated. No hardware is licensed hereunder.
-
-THE NVIDIA SOFTWARE IS BEING PROVIDED ON AN "AS IS" BASIS, WITHOUT
-WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED,
-INCLUDING WITHOUT LIMITATION, WARRANTIES OR CONDITIONS OF TITLE,
-NON-INFRINGEMENT, MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR
-ITS USE AND OPERATION EITHER ALONE OR IN COMBINATION WITH OTHER
-PRODUCTS.
-
-IN NO EVENT SHALL NVIDIA BE LIABLE FOR ANY SPECIAL, INDIRECT,
-INCIDENTAL, EXEMPLARY, CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
-TO, LOST PROFITS; PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
-USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) OR ARISING IN ANY WAY
-OUT OF THE USE, REPRODUCTION, MODIFICATION AND/OR DISTRIBUTION OF THE
-NVIDIA SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER THEORY OF CONTRACT,
-TORT (INCLUDING NEGLIGENCE), STRICT LIABILITY OR OTHERWISE, EVEN IF
-NVIDIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-\****************************************************************************/
-
-# include "slglobals.h"
-extern CPPStruct *cpp;
-int InitCPPStruct(void);
-int InitScanner(CPPStruct *cpp);
-int InitAtomTable(AtomTable *atable, int htsize);
-int ScanFromString(char *s);
-char* GetStringOfAtom(AtomTable *atable, int atom);
diff --git a/src/mesa/shader/slang/MachineIndependent/preprocessor/scanner.c b/src/mesa/shader/slang/MachineIndependent/preprocessor/scanner.c deleted file mode 100755 index d80e37b8e9..0000000000 --- a/src/mesa/shader/slang/MachineIndependent/preprocessor/scanner.c +++ /dev/null @@ -1,789 +0,0 @@ -/* */ -/*Copyright (C) 2002-2005 3Dlabs Inc. Ltd. */ -/*All rights reserved. */ -/* */ -/*Redistribution and use in source and binary forms, with or without */ -/*modification, are permitted provided that the following conditions */ -/*are met: */ -/* */ -/* Redistributions of source code must retain the above copyright */ -/* notice, this list of conditions and the following disclaimer. */ -/* */ -/* Redistributions in binary form must reproduce the above */ -/* copyright notice, this list of conditions and the following */ -/* disclaimer in the documentation and/or other materials provided */ -/* with the distribution. */ -/* */ -/* Neither the name of 3Dlabs Inc. Ltd. nor the names of its */ -/* contributors may be used to endorse or promote products derived */ -/* from this software without specific prior written permission. */ -/* */ -/*THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS */ -/*"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT */ -/*LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS */ -/*FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE */ -/*COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, */ -/*INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, */ -/*BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; */ -/*LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER */ -/*CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT */ -/*LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN */ -/*ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE */ -/*POSSIBILITY OF SUCH DAMAGE. */ -/* */ -/****************************************************************************\
-Copyright (c) 2002, NVIDIA Corporation.
-
-NVIDIA Corporation("NVIDIA") supplies this software to you in
-consideration of your agreement to the following terms, and your use,
-installation, modification or redistribution of this NVIDIA software
-constitutes acceptance of these terms. If you do not agree with these
-terms, please do not use, install, modify or redistribute this NVIDIA
-software.
-
-In consideration of your agreement to abide by the following terms, and
-subject to these terms, NVIDIA grants you a personal, non-exclusive
-license, under NVIDIA's copyrights in this original NVIDIA software (the
-"NVIDIA Software"), to use, reproduce, modify and redistribute the
-NVIDIA Software, with or without modifications, in source and/or binary
-forms; provided that if you redistribute the NVIDIA Software, you must
-retain the copyright notice of NVIDIA, this notice and the following
-text and disclaimers in all such redistributions of the NVIDIA Software.
-Neither the name, trademarks, service marks nor logos of NVIDIA
-Corporation may be used to endorse or promote products derived from the
-NVIDIA Software without specific prior written permission from NVIDIA.
-Except as expressly stated in this notice, no other rights or licenses
-express or implied, are granted by NVIDIA herein, including but not
-limited to any patent rights that may be infringed by your derivative
-works or by other works in which the NVIDIA Software may be
-incorporated. No hardware is licensed hereunder.
-
-THE NVIDIA SOFTWARE IS BEING PROVIDED ON AN "AS IS" BASIS, WITHOUT
-WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED,
-INCLUDING WITHOUT LIMITATION, WARRANTIES OR CONDITIONS OF TITLE,
-NON-INFRINGEMENT, MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR
-ITS USE AND OPERATION EITHER ALONE OR IN COMBINATION WITH OTHER
-PRODUCTS.
-
-IN NO EVENT SHALL NVIDIA BE LIABLE FOR ANY SPECIAL, INDIRECT,
-INCIDENTAL, EXEMPLARY, CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
-TO, LOST PROFITS; PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
-USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) OR ARISING IN ANY WAY
-OUT OF THE USE, REPRODUCTION, MODIFICATION AND/OR DISTRIBUTION OF THE
-NVIDIA SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER THEORY OF CONTRACT,
-TORT (INCLUDING NEGLIGENCE), STRICT LIABILITY OR OTHERWISE, EVEN IF
-NVIDIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-\****************************************************************************/
-/* */ -/* scanner.c */ -/* */ -
-#include <stdarg.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#if 0
- #include <ieeefp.h>
- #else
- #define isinff(x) (((*(long *)&(x) & 0x7f800000L)==0x7f800000L) && \
- ((*(long *)&(x) & 0x007fffffL)==0000000000L))
-#endif
-
-#include "slglobals.h"
-
-
-typedef struct StringInputSrc {
- InputSrc base;
- char *p;
-} StringInputSrc;
-
-static int eof_scan(InputSrc *is, yystypepp * yylvalpp)
-{
- return EOF;
-} /* eof_scan */ -
-static void noop(InputSrc *in, int ch, yystypepp * yylvalpp) {}
-
-static InputSrc eof_inputsrc = { 0, &eof_scan, &eof_scan, &noop };
-
-static int byte_scan(InputSrc *, yystypepp * yylvalpp);
-
-#define EOL_SY '\n'
-
-#if defined(_WIN32)
- #define DBG_BREAKPOINT() __asm int 3
- #elif defined(_M_AMD64)
- #define DBG_BREAKPOINT() assert(!"Dbg_Breakpoint");
- #else
- #define DBG_BREAKPOINT()
- #endif
-
- #if defined(_WIN32) && !defined(_M_AMD64)
- __int64 RDTSC ( void ) {
-
- __int64 v;
-
- __asm __emit 0x0f
- __asm __emit 0x31
- __asm mov dword ptr v, eax
- __asm mov dword ptr v+4, edx
-
- return v;
- }
-#endif
-
-
-int InitScanner(CPPStruct *cpp)
-{
- /* Add various atoms needed by the CPP line scanner: */ - if (!InitCPP())
- return 0;
-
- cpp->mostRecentToken = 0;
- cpp->tokenLoc = &cpp->ltokenLoc;
-
- cpp->ltokenLoc.file = 0;
- cpp->ltokenLoc.line = 0;
-
- cpp->currentInput = &eof_inputsrc;
- cpp->previous_token = '\n';
- cpp->notAVersionToken = 0;
-
- return 1;
-} /* InitScanner */ -
-int FreeScanner(void)
-{
- return (FreeCPP());
-}
-
-/*
- * str_getch()
- * takes care of reading from multiple strings.
- * returns the next-char from the input stream.
- * returns EOF when the complete shader is parsed.
- */
-static int str_getch(StringInputSrc *in)
-{
- for(;;){
- if (*in->p){
- if (*in->p == '\n') {
- in->base.line++;
- IncLineNumber();
- }
- return *in->p++;
- }
- if(++(cpp->PaWhichStr) < cpp->PaArgc){
- free(in);
- SetStringNumber(cpp->PaWhichStr);
- SetLineNumber(1);
- ScanFromString(cpp->PaArgv[cpp->PaWhichStr]);
- in=(StringInputSrc*)cpp->currentInput;
- continue;
- }
- else{
- cpp->currentInput = in->base.prev;
- cpp->PaWhichStr=0;
- free(in);
- return EOF;
- }
- }
-} /* str_getch */ -
-static void str_ungetch(StringInputSrc *in, int ch, yystypepp *type) {
- if (in->p[-1] == ch)in->p--;
- else {
- *(in->p)='\0'; /*this would take care of shifting to the previous string. */ - cpp->PaWhichStr--;
- }
- if (ch == '\n') {
- in->base.line--;
- DecLineNumber();
- }
-} /* str_ungetch */ -
-int ScanFromString(char *s)
-{
-
- StringInputSrc *in = malloc(sizeof(StringInputSrc));
- memset(in, 0, sizeof(StringInputSrc));
- in->p = s;
- in->base.line = 1;
- in->base.scan = byte_scan;
- in->base.getch = (int (*)(InputSrc *, yystypepp *))str_getch;
- in->base.ungetch = (void (*)(InputSrc *, int, yystypepp *))str_ungetch;
- in->base.prev = cpp->currentInput;
- cpp->currentInput = &in->base;
-
- return 1;
-} /* ScanFromString; */ -
-
-/*///////////////////////////////////////////////////////////////////////////////////////////// */ -/*///////////////////////////////// Floating point constants: ///////////////////////////////// */ -/*///////////////////////////////////////////////////////////////////////////////////////////// */ -/*
- * lBuildFloatValue() - Quick and dirty conversion to floating point. Since all
- * we need is single precision this should be quite precise.
- */
-
-static float lBuildFloatValue(const char *str, int len, int exp)
-{
- double val, expval, ten;
- int ii, llen, absexp;
- float rv;
-
- val = 0.0;
- llen = len;
- for (ii = 0; ii < len; ii++)
- val = val*10.0 + (str[ii] - '0');
- if (exp != 0) {
- absexp = exp > 0 ? exp : -exp;
- expval = 1.0f;
- ten = 10.0;
- while (absexp) {
- if (absexp & 1)
- expval *= ten;
- ten *= ten;
- absexp >>= 1;
- }
- if (exp >= 0) {
- val *= expval;
- } else {
- val /= expval;
- }
- }
- rv = (float)val;
- if (isinff(rv)) {
- CPPErrorToInfoLog(" ERROR___FP_CONST_OVERFLOW");
- }
- return rv;
-} /* lBuildFloatValue */ -
-
-/*
- * lFloatConst() - Scan a floating point constant. Assumes that the scanner
- * has seen at least one digit, followed by either a decimal '.' or the
- * letter 'e'.
- */
-
-static int lFloatConst(char *str, int len, int ch, yystypepp * yylvalpp)
-{
- int HasDecimal, declen, exp, ExpSign;
- int str_len;
- float lval;
-
- HasDecimal = 0;
- declen = 0;
- exp = 0;
-
- str_len=len;
- if (ch == '.') {
- str[len++]=ch;
- HasDecimal = 1;
- ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp);
- while (ch >= '0' && ch <= '9') {
- if (len < MAX_SYMBOL_NAME_LEN) {
- declen++;
- if (len > 0 || ch != '0') {
- str[len] = ch;
- len++;str_len++;
- }
- ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp);
- } else {
- CPPErrorToInfoLog("ERROR___FP_CONST_TOO_LONG");
- len = 1,str_len=1;
- }
- }
- }
-
- /* Exponent: */ -
- if (ch == 'e' || ch == 'E') {
- ExpSign = 1;
- str[len++]=ch;
- ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp);
- if (ch == '+') {
- str[len++]=ch;
- ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp);
- } else if (ch == '-') {
- ExpSign = -1;
- str[len++]=ch;
- ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp);
- }
- if (ch >= '0' && ch <= '9') {
- while (ch >= '0' && ch <= '9') {
- exp = exp*10 + ch - '0';
- str[len++]=ch;
- ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp);
- }
- } else {
- CPPErrorToInfoLog("ERROR___ERROR_IN_EXPONENT");
- }
- exp *= ExpSign;
- }
-
- if (len == 0) {
- lval = 0.0f;
- strcpy(str,"0.0");
- } else {
- str[len]='\0';
- lval = lBuildFloatValue(str, str_len, exp - declen);
- }
- /* Suffix: */ -
- yylvalpp->sc_fval = lval;
- strcpy(yylvalpp->symbol_name,str);
- cpp->currentInput->ungetch(cpp->currentInput, ch, yylvalpp);
- return CPP_FLOATCONSTANT;
-} /* lFloatConst */ -
-/*///////////////////////////////////////////////////////////////////////////////////////////// */ -/*/////////////////////////////////////// Normal Scanner ////////////////////////////////////// */ -/*///////////////////////////////////////////////////////////////////////////////////////////// */ -
-static int byte_scan(InputSrc *in, yystypepp * yylvalpp)
-{
- char symbol_name[MAX_SYMBOL_NAME_LEN + 1];
- char string_val[MAX_STRING_LEN + 1];
- int AlreadyComplained;
- int len, ch, ii, ival = 0;
-
- for (;;) {
- yylvalpp->sc_int = 0;
- ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp);
-
- while (ch == ' ' || ch == '\t' || ch == '\r') {
- yylvalpp->sc_int = 1;
- ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp);
- }
-
- cpp->ltokenLoc.file = cpp->currentInput->name;
- cpp->ltokenLoc.line = cpp->currentInput->line;
- len = 0;
- switch (ch) {
- default:
- return ch; /* Single character token */ - case EOF:
- return -1;
- case 'A': case 'B': case 'C': case 'D': case 'E':
- case 'F': case 'G': case 'H': case 'I': case 'J':
- case 'K': case 'L': case 'M': case 'N': case 'O':
- case 'P': case 'Q': case 'R': case 'S': case 'T':
- case 'U': case 'V': case 'W': case 'X': case 'Y':
- case 'Z': case '_':
- case 'a': case 'b': case 'c': case 'd': case 'e':
- case 'f': case 'g': case 'h': case 'i': case 'j':
- case 'k': case 'l': case 'm': case 'n': case 'o':
- case 'p': case 'q': case 'r': case 's': case 't':
- case 'u': case 'v': case 'w': case 'x': case 'y':
- case 'z':
- do {
- if (len < MAX_SYMBOL_NAME_LEN) {
- symbol_name[len] = ch;
- len++;
- ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp);
- } else {
- ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp);
- }
- } while ((ch >= 'a' && ch <= 'z') ||
- (ch >= 'A' && ch <= 'Z') ||
- (ch >= '0' && ch <= '9') ||
- ch == '_');
- if (len >= MAX_SYMBOL_NAME_LEN)
- len = MAX_SYMBOL_NAME_LEN - 1;
- symbol_name[len] = '\0';
- cpp->currentInput->ungetch(cpp->currentInput, ch, yylvalpp);
- yylvalpp->sc_ident = LookUpAddString(atable, symbol_name);
- return CPP_IDENTIFIER;
- break;
- case '0':
- yylvalpp->symbol_name[len++] = ch;
- ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp);
- if (ch == 'x' || ch == 'X') {
- yylvalpp->symbol_name[len++] = ch;
- ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp);
- if ((ch >= '0' && ch <= '9') ||
- (ch >= 'A' && ch <= 'F') ||
- (ch >= 'a' && ch <= 'f'))
- {
- AlreadyComplained = 0;
- ival = 0;
- do {
- yylvalpp->symbol_name[len++] = ch;
- if (ival <= 0x0fffffff) {
- if (ch >= '0' && ch <= '9') {
- ii = ch - '0';
- } else if (ch >= 'A' && ch <= 'F') {
- ii = ch - 'A' + 10;
- } else {
- ii = ch - 'a' + 10;
- }
- ival = (ival << 4) | ii;
- } else {
- if (!AlreadyComplained)
- CPPErrorToInfoLog("ERROR___HEX_CONST_OVERFLOW");
- AlreadyComplained = 1;
- }
- ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp);
- } while ((ch >= '0' && ch <= '9') ||
- (ch >= 'A' && ch <= 'F') ||
- (ch >= 'a' && ch <= 'f'));
- } else {
- CPPErrorToInfoLog("ERROR___ERROR_IN_HEX_CONSTANT");
- }
- yylvalpp->symbol_name[len] = '\0';
- cpp->currentInput->ungetch(cpp->currentInput, ch, yylvalpp);
- yylvalpp->sc_int = ival;
- return CPP_INTCONSTANT;
- } else if (ch >= '0' && ch <= '7') { /* octal integer constants */ - AlreadyComplained = 0;
- ival = 0;
- do {
- yylvalpp->symbol_name[len++] = ch;
- if (ival <= 0x1fffffff) {
- ii = ch - '0';
- ival = (ival << 3) | ii;
- } else {
- if (!AlreadyComplained)
- CPPErrorToInfoLog("ERROR___OCT_CONST_OVERFLOW");
- AlreadyComplained = 1;
- }
- ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp);
- } while (ch >= '0' && ch <= '7');
- if (ch == '.' || ch == 'e' || ch == 'f' || ch == 'h' || ch == 'x'|| ch == 'E')
- return lFloatConst(yylvalpp->symbol_name, len, ch, yylvalpp);
- yylvalpp->symbol_name[len] = '\0';
- cpp->currentInput->ungetch(cpp->currentInput, ch, yylvalpp);
- yylvalpp->sc_int = ival;
- return CPP_INTCONSTANT;
- } else {
- cpp->currentInput->ungetch(cpp->currentInput, ch, yylvalpp);
- ch = '0';
- }
- /* Fall through... */ - case '1': case '2': case '3': case '4':
- case '5': case '6': case '7': case '8': case '9':
- do {
- if (len < MAX_SYMBOL_NAME_LEN) {
- if (len > 0 || ch != '0') {
- yylvalpp->symbol_name[len] = ch;
- len++;
- }
- ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp);
- }
- } while (ch >= '0' && ch <= '9');
- if (ch == '.' || ch == 'e' || ch == 'f' || ch == 'h' || ch == 'x'|| ch == 'E') {
- return lFloatConst(yylvalpp->symbol_name, len, ch, yylvalpp);
- } else {
- yylvalpp->symbol_name[len] = '\0';
- cpp->currentInput->ungetch(cpp->currentInput, ch, yylvalpp);
- ival = 0;
- AlreadyComplained = 0;
- for (ii = 0; ii < len; ii++) {
- ch = yylvalpp->symbol_name[ii] - '0';
- if ((ival > 214748364) || (ival == 214748364 && ch >= 8)) {
- if (!AlreadyComplained)
- CPPErrorToInfoLog("ERROR___INTEGER_CONST_OVERFLOW");
- AlreadyComplained = 1;
- }
- ival = ival*10 + ch;
- }
- yylvalpp->sc_int = ival;
- if(ival==0)
- strcpy(yylvalpp->symbol_name,"0");
- return CPP_INTCONSTANT;
- }
- break;
- case '-':
- ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp);
- if (ch == '-') {
- return CPP_DEC_OP;
- } else if (ch == '=') {
- return CPP_SUB_ASSIGN;
- } else {
- cpp->currentInput->ungetch(cpp->currentInput, ch, yylvalpp);
- return '-';
- }
- case '+':
- ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp);
- if (ch == '+') {
- return CPP_INC_OP;
- } else if (ch == '=') {
- return CPP_ADD_ASSIGN;
- } else {
- cpp->currentInput->ungetch(cpp->currentInput, ch, yylvalpp);
- return '+';
- }
- case '*':
- ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp);
- if (ch == '=') {
- return CPP_MUL_ASSIGN;
- } else {
- cpp->currentInput->ungetch(cpp->currentInput, ch, yylvalpp);
- return '*';
- }
- case '%':
- ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp);
- if (ch == '=') {
- return CPP_MOD_ASSIGN;
- } else if (ch == '>'){
- return CPP_RIGHT_BRACE;
- } else {
- cpp->currentInput->ungetch(cpp->currentInput, ch, yylvalpp);
- return '%';
- }
- case ':':
- ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp);
- if (ch == '>') {
- return CPP_RIGHT_BRACKET;
- } else {
- cpp->currentInput->ungetch(cpp->currentInput, ch, yylvalpp);
- return ':';
- }
- case '^':
- ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp);
- if (ch == '^') {
- return CPP_XOR_OP;
- } else {
- if (ch == '=')
- return CPP_XOR_ASSIGN;
- else{
- cpp->currentInput->ungetch(cpp->currentInput, ch, yylvalpp);
- return '^';
- }
- }
-
- case '=':
- ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp);
- if (ch == '=') {
- return CPP_EQ_OP;
- } else {
- cpp->currentInput->ungetch(cpp->currentInput, ch, yylvalpp);
- return '=';
- }
- case '!':
- ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp);
- if (ch == '=') {
- return CPP_NE_OP;
- } else {
- cpp->currentInput->ungetch(cpp->currentInput, ch, yylvalpp);
- return '!';
- }
- case '|':
- ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp);
- if (ch == '|') {
- return CPP_OR_OP;
- } else {
- if (ch == '=')
- return CPP_OR_ASSIGN;
- else{
- cpp->currentInput->ungetch(cpp->currentInput, ch, yylvalpp);
- return '|';
- }
- }
- case '&':
- ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp);
- if (ch == '&') {
- return CPP_AND_OP;
- } else {
- if (ch == '=')
- return CPP_AND_ASSIGN;
- else{
- cpp->currentInput->ungetch(cpp->currentInput, ch, yylvalpp);
- return '&';
- }
- }
- case '<':
- ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp);
- if (ch == '<') {
- ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp);
- if(ch == '=')
- return CPP_LEFT_ASSIGN;
- else{
- cpp->currentInput->ungetch(cpp->currentInput, ch, yylvalpp);
- return CPP_LEFT_OP;
- }
- } else {
- if (ch == '=') {
- return CPP_LE_OP;
- } else {
- if (ch == '%')
- return CPP_LEFT_BRACE;
- else if (ch == ':')
- return CPP_LEFT_BRACKET;
- else{
- cpp->currentInput->ungetch(cpp->currentInput, ch, yylvalpp);
- return '<';
- }
- }
- }
- case '>':
- ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp);
- if (ch == '>') {
- ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp);
- if(ch == '=')
- return CPP_RIGHT_ASSIGN;
- else{
- cpp->currentInput->ungetch(cpp->currentInput, ch, yylvalpp);
- return CPP_RIGHT_OP;
- }
- } else {
- if (ch == '=') {
- return CPP_GE_OP;
- } else {
- cpp->currentInput->ungetch(cpp->currentInput, ch, yylvalpp);
- return '>';
- }
- }
- case '.':
- ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp);
- if (ch >= '0' && ch <= '9') {
- cpp->currentInput->ungetch(cpp->currentInput, ch, yylvalpp);
- return lFloatConst(yylvalpp->symbol_name, 0, '.', yylvalpp);
- } else {
- if (ch == '.') {
- return -1; /* Special EOF hack */ - } else {
- cpp->currentInput->ungetch(cpp->currentInput, ch, yylvalpp);
- return '.';
- }
- }
- case '/':
- ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp);
- if (ch == '/') {
- do {
- ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp);
- } while (ch != '\n' && ch != EOF);
- if (ch == EOF)
- return -1;
- return '\n';
- } else if (ch == '*') {
- int nlcount = 0;
- ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp);
- do {
- while (ch != '*') {
- if (ch == '\n') nlcount++;
- if (ch == EOF) {
- CPPErrorToInfoLog("ERROR___EOF_IN_COMMENT");
- return -1;
- }
- ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp);
- }
- ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp);
- if (ch == EOF) {
- CPPErrorToInfoLog("ERROR___EOF_IN_COMMENT");
- return -1;
- }
- } while (ch != '/');
- if (nlcount) {
- return '\n';
- }
- /* Go try it again... */ - } else if (ch == '=') {
- return CPP_DIV_ASSIGN;
- } else {
- cpp->currentInput->ungetch(cpp->currentInput, ch, yylvalpp);
- return '/';
- }
- break;
- case '"':
- ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp);
- while (ch != '"' && ch != '\n' && ch != EOF) {
- if (ch == '\\') {
- ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp);
- if (ch == '\n' || ch == EOF) {
- break;
- }
- }
- if (len < MAX_STRING_LEN) {
- string_val[len] = ch;
- len++;
- ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp);
- }
- };
- string_val[len] = '\0';
- if (ch == '"') {
- yylvalpp->sc_ident = LookUpAddString(atable, string_val);
- return CPP_STRCONSTANT;
- } else {
- CPPErrorToInfoLog("ERROR___CPP_EOL_IN_STRING");
- return ERROR_SY;
- }
- }
- }
-} /* byte_scan */ -
-int yylex_CPP(char* buf, int maxSize)
-{
- yystypepp yylvalpp;
- int token = '\n';
-
- for(;;) {
-
- char* tokenString = 0;
- token = cpp->currentInput->scan(cpp->currentInput, &yylvalpp);
- if(check_EOF(token))
- return 0;
- if (token == '#' && (cpp->previous_token == '\n'||cpp->previous_token==0)) {
- token = readCPPline(&yylvalpp);
- if(check_EOF(token))
- return 0;
- continue;
- }
- cpp->previous_token = token;
- /* expand macros */ - if (token == CPP_IDENTIFIER && MacroExpand(yylvalpp.sc_ident, &yylvalpp)) {
- cpp->notAVersionToken = 1;
- continue;
- }
-
- if (token == '\n')
- continue;
-
- if (token == CPP_IDENTIFIER) {
- cpp->notAVersionToken = 1;
- tokenString = GetStringOfAtom(atable,yylvalpp.sc_ident);
- } else if (token == CPP_FLOATCONSTANT||token == CPP_INTCONSTANT){
- cpp->notAVersionToken = 1;
- tokenString = yylvalpp.symbol_name;
- } else {
- cpp->notAVersionToken = 1;
- tokenString = GetStringOfAtom(atable,token);
- }
-
- if (tokenString) {
- if ((signed)strlen(tokenString) >= maxSize) {
- cpp->tokensBeforeEOF = 1;
- return maxSize;
- } else if (strlen(tokenString) > 0) {
- strcpy(buf, tokenString);
- cpp->tokensBeforeEOF = 1;
- return (int)strlen(tokenString);
- }
-
- return 0;
- }
- }
-
- return 0;
-} /* yylex */ -
-/*Checks if the token just read is EOF or not. */ -int check_EOF(int token)
-{
- if(token==-1){
- if(cpp->ifdepth >0){
- CPPErrorToInfoLog("#endif missing!! Compilation stopped");
- cpp->CompileError=1;
- }
- return 1;
- }
- return 0;
-}
-
-/*///////////////////////////////////////////////////////////////////////////////////////////// */ -/*///////////////////////////////////// End of scanner.c ////////////////////////////////////// */ -/*///////////////////////////////////////////////////////////////////////////////////////////// */ -
diff --git a/src/mesa/shader/slang/MachineIndependent/preprocessor/scanner.h b/src/mesa/shader/slang/MachineIndependent/preprocessor/scanner.h deleted file mode 100755 index 15472b5bf1..0000000000 --- a/src/mesa/shader/slang/MachineIndependent/preprocessor/scanner.h +++ /dev/null @@ -1,118 +0,0 @@ -/* */ -/*Copyright (C) 2002-2005 3Dlabs Inc. Ltd. */ -/*All rights reserved. */ -/* */ -/*Redistribution and use in source and binary forms, with or without */ -/*modification, are permitted provided that the following conditions */ -/*are met: */ -/* */ -/* Redistributions of source code must retain the above copyright */ -/* notice, this list of conditions and the following disclaimer. */ -/* */ -/* Redistributions in binary form must reproduce the above */ -/* copyright notice, this list of conditions and the following */ -/* disclaimer in the documentation and/or other materials provided */ -/* with the distribution. */ -/* */ -/* Neither the name of 3Dlabs Inc. Ltd. nor the names of its */ -/* contributors may be used to endorse or promote products derived */ -/* from this software without specific prior written permission. */ -/* */ -/*THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS */ -/*"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT */ -/*LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS */ -/*FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE */ -/*COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, */ -/*INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, */ -/*BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; */ -/*LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER */ -/*CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT */ -/*LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN */ -/*ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE */ -/*POSSIBILITY OF SUCH DAMAGE. */ -/* */ -/****************************************************************************\
-Copyright (c) 2002, NVIDIA Corporation.
-
-NVIDIA Corporation("NVIDIA") supplies this software to you in
-consideration of your agreement to the following terms, and your use,
-installation, modification or redistribution of this NVIDIA software
-constitutes acceptance of these terms. If you do not agree with these
-terms, please do not use, install, modify or redistribute this NVIDIA
-software.
-
-In consideration of your agreement to abide by the following terms, and
-subject to these terms, NVIDIA grants you a personal, non-exclusive
-license, under NVIDIA's copyrights in this original NVIDIA software (the
-"NVIDIA Software"), to use, reproduce, modify and redistribute the
-NVIDIA Software, with or without modifications, in source and/or binary
-forms; provided that if you redistribute the NVIDIA Software, you must
-retain the copyright notice of NVIDIA, this notice and the following
-text and disclaimers in all such redistributions of the NVIDIA Software.
-Neither the name, trademarks, service marks nor logos of NVIDIA
-Corporation may be used to endorse or promote products derived from the
-NVIDIA Software without specific prior written permission from NVIDIA.
-Except as expressly stated in this notice, no other rights or licenses
-express or implied, are granted by NVIDIA herein, including but not
-limited to any patent rights that may be infringed by your derivative
-works or by other works in which the NVIDIA Software may be
-incorporated. No hardware is licensed hereunder.
-
-THE NVIDIA SOFTWARE IS BEING PROVIDED ON AN "AS IS" BASIS, WITHOUT
-WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED,
-INCLUDING WITHOUT LIMITATION, WARRANTIES OR CONDITIONS OF TITLE,
-NON-INFRINGEMENT, MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR
-ITS USE AND OPERATION EITHER ALONE OR IN COMBINATION WITH OTHER
-PRODUCTS.
-
-IN NO EVENT SHALL NVIDIA BE LIABLE FOR ANY SPECIAL, INDIRECT,
-INCIDENTAL, EXEMPLARY, CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
-TO, LOST PROFITS; PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
-USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) OR ARISING IN ANY WAY
-OUT OF THE USE, REPRODUCTION, MODIFICATION AND/OR DISTRIBUTION OF THE
-NVIDIA SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER THEORY OF CONTRACT,
-TORT (INCLUDING NEGLIGENCE), STRICT LIABILITY OR OTHERWISE, EVEN IF
-NVIDIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-\****************************************************************************/
-/* */ -/* scanner.h */ -/* */ -
-#if !defined(__SCANNER_H)
-#define __SCANNER_H 1
-
-#define MAX_SYMBOL_NAME_LEN 128
-#define MAX_STRING_LEN 512
-
-#include "parser.h"
-
-/* Not really atom table stuff but needed first... */ -
-typedef struct SourceLoc_Rec {
- unsigned short file, line;
-} SourceLoc;
-
-int yyparse (void);
-
-int yylex_CPP(char* buf, int maxSize);
-
-typedef struct InputSrc {
- struct InputSrc *prev;
- int (*scan)(struct InputSrc *, yystypepp *);
- int (*getch)(struct InputSrc *, yystypepp *);
- void (*ungetch)(struct InputSrc *, int, yystypepp *);
- int name; /* atom */
- int line;
-} InputSrc;
-
-int InitScanner(CPPStruct *cpp); /* Intialise the cpp scanner. */ -int ScanFromString(char *); /* Start scanning the input from the string mentioned. */ -int check_EOF(int); /* check if we hit a EOF abruptly */ -void CPPErrorToInfoLog(char *); /* sticking the msg,line into the Shader's.Info.log */ -void SetLineNumber(int);
-void SetStringNumber(int);
-void IncLineNumber(void);
-void DecLineNumber(void);
-int FreeScanner(void); /* Free the cpp scanner */ -#endif /* !(defined(__SCANNER_H) */ -
diff --git a/src/mesa/shader/slang/MachineIndependent/preprocessor/slglobals.h b/src/mesa/shader/slang/MachineIndependent/preprocessor/slglobals.h deleted file mode 100755 index 667ada6a29..0000000000 --- a/src/mesa/shader/slang/MachineIndependent/preprocessor/slglobals.h +++ /dev/null @@ -1,115 +0,0 @@ -/* */ -/*Copyright (C) 2002-2005 3Dlabs Inc. Ltd. */ -/*All rights reserved. */ -/* */ -/*Redistribution and use in source and binary forms, with or without */ -/*modification, are permitted provided that the following conditions */ -/*are met: */ -/* */ -/* Redistributions of source code must retain the above copyright */ -/* notice, this list of conditions and the following disclaimer. */ -/* */ -/* Redistributions in binary form must reproduce the above */ -/* copyright notice, this list of conditions and the following */ -/* disclaimer in the documentation and/or other materials provided */ -/* with the distribution. */ -/* */ -/* Neither the name of 3Dlabs Inc. Ltd. nor the names of its */ -/* contributors may be used to endorse or promote products derived */ -/* from this software without specific prior written permission. */ -/* */ -/*THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS */ -/*"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT */ -/*LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS */ -/*FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE */ -/*COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, */ -/*INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, */ -/*BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; */ -/*LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER */ -/*CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT */ -/*LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN */ -/*ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE */ -/*POSSIBILITY OF SUCH DAMAGE. */ -/* */ -/****************************************************************************\
-Copyright (c) 2002, NVIDIA Corporation.
-
-NVIDIA Corporation("NVIDIA") supplies this software to you in
-consideration of your agreement to the following terms, and your use,
-installation, modification or redistribution of this NVIDIA software
-constitutes acceptance of these terms. If you do not agree with these
-terms, please do not use, install, modify or redistribute this NVIDIA
-software.
-
-In consideration of your agreement to abide by the following terms, and
-subject to these terms, NVIDIA grants you a personal, non-exclusive
-license, under NVIDIA's copyrights in this original NVIDIA software (the
-"NVIDIA Software"), to use, reproduce, modify and redistribute the
-NVIDIA Software, with or without modifications, in source and/or binary
-forms; provided that if you redistribute the NVIDIA Software, you must
-retain the copyright notice of NVIDIA, this notice and the following
-text and disclaimers in all such redistributions of the NVIDIA Software.
-Neither the name, trademarks, service marks nor logos of NVIDIA
-Corporation may be used to endorse or promote products derived from the
-NVIDIA Software without specific prior written permission from NVIDIA.
-Except as expressly stated in this notice, no other rights or licenses
-express or implied, are granted by NVIDIA herein, including but not
-limited to any patent rights that may be infringed by your derivative
-works or by other works in which the NVIDIA Software may be
-incorporated. No hardware is licensed hereunder.
-
-THE NVIDIA SOFTWARE IS BEING PROVIDED ON AN "AS IS" BASIS, WITHOUT
-WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED,
-INCLUDING WITHOUT LIMITATION, WARRANTIES OR CONDITIONS OF TITLE,
-NON-INFRINGEMENT, MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR
-ITS USE AND OPERATION EITHER ALONE OR IN COMBINATION WITH OTHER
-PRODUCTS.
-
-IN NO EVENT SHALL NVIDIA BE LIABLE FOR ANY SPECIAL, INDIRECT,
-INCIDENTAL, EXEMPLARY, CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
-TO, LOST PROFITS; PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
-USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) OR ARISING IN ANY WAY
-OUT OF THE USE, REPRODUCTION, MODIFICATION AND/OR DISTRIBUTION OF THE
-NVIDIA SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER THEORY OF CONTRACT,
-TORT (INCLUDING NEGLIGENCE), STRICT LIABILITY OR OTHERWISE, EVEN IF
-NVIDIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-\****************************************************************************/
-/* */ -/* slglobals.h */ -/* */ -
-#if !defined(__SLGLOBALS_H)
-#define __SLGLOBALS_H 1
-
-typedef struct CPPStruct_Rec CPPStruct;
-
-extern CPPStruct *cpp;
-
-#undef CPPC_DEBUG_THE_COMPILER
-#if defined(_DEBUG)
-#define CPPC_DEBUG_THE_COMPILER 1
-#endif
-
-#undef CPPC_ENABLE_TOOLS
-#define CPPC_ENABLE_TOOLS 1
-
-#include "memory.h"
-#include "atom.h"
-#include "scanner.h"
-#include "cpp.h"
-#include "tokens.h"
-#include "symbols.h"
-#include "compile.h"
-#if !defined(NO_PARSER)
-#include "parser.h"
-#endif
-
-#if !defined(NULL)
-#define NULL 0
-#endif
-
-#endif /* !(defined(__SLGLOBALS_H) */ -
-
-
-
diff --git a/src/mesa/shader/slang/MachineIndependent/preprocessor/symbols.c b/src/mesa/shader/slang/MachineIndependent/preprocessor/symbols.c deleted file mode 100755 index e807fe3434..0000000000 --- a/src/mesa/shader/slang/MachineIndependent/preprocessor/symbols.c +++ /dev/null @@ -1,318 +0,0 @@ -/* */ -/*Copyright (C) 2002-2005 3Dlabs Inc. Ltd. */ -/*All rights reserved. */ -/* */ -/*Redistribution and use in source and binary forms, with or without */ -/*modification, are permitted provided that the following conditions */ -/*are met: */ -/* */ -/* Redistributions of source code must retain the above copyright */ -/* notice, this list of conditions and the following disclaimer. */ -/* */ -/* Redistributions in binary form must reproduce the above */ -/* copyright notice, this list of conditions and the following */ -/* disclaimer in the documentation and/or other materials provided */ -/* with the distribution. */ -/* */ -/* Neither the name of 3Dlabs Inc. Ltd. nor the names of its */ -/* contributors may be used to endorse or promote products derived */ -/* from this software without specific prior written permission. */ -/* */ -/*THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS */ -/*"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT */ -/*LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS */ -/*FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE */ -/*COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, */ -/*INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, */ -/*BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; */ -/*LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER */ -/*CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT */ -/*LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN */ -/*ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE */ -/*POSSIBILITY OF SUCH DAMAGE. */ -/* */ -/****************************************************************************\
-Copyright (c) 2002, NVIDIA Corporation.
-
-NVIDIA Corporation("NVIDIA") supplies this software to you in
-consideration of your agreement to the following terms, and your use,
-installation, modification or redistribution of this NVIDIA software
-constitutes acceptance of these terms. If you do not agree with these
-terms, please do not use, install, modify or redistribute this NVIDIA
-software.
-
-In consideration of your agreement to abide by the following terms, and
-subject to these terms, NVIDIA grants you a personal, non-exclusive
-license, under NVIDIA's copyrights in this original NVIDIA software (the
-"NVIDIA Software"), to use, reproduce, modify and redistribute the
-NVIDIA Software, with or without modifications, in source and/or binary
-forms; provided that if you redistribute the NVIDIA Software, you must
-retain the copyright notice of NVIDIA, this notice and the following
-text and disclaimers in all such redistributions of the NVIDIA Software.
-Neither the name, trademarks, service marks nor logos of NVIDIA
-Corporation may be used to endorse or promote products derived from the
-NVIDIA Software without specific prior written permission from NVIDIA.
-Except as expressly stated in this notice, no other rights or licenses
-express or implied, are granted by NVIDIA herein, including but not
-limited to any patent rights that may be infringed by your derivative
-works or by other works in which the NVIDIA Software may be
-incorporated. No hardware is licensed hereunder.
-
-THE NVIDIA SOFTWARE IS BEING PROVIDED ON AN "AS IS" BASIS, WITHOUT
-WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED,
-INCLUDING WITHOUT LIMITATION, WARRANTIES OR CONDITIONS OF TITLE,
-NON-INFRINGEMENT, MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR
-ITS USE AND OPERATION EITHER ALONE OR IN COMBINATION WITH OTHER
-PRODUCTS.
-
-IN NO EVENT SHALL NVIDIA BE LIABLE FOR ANY SPECIAL, INDIRECT,
-INCIDENTAL, EXEMPLARY, CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
-TO, LOST PROFITS; PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
-USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) OR ARISING IN ANY WAY
-OUT OF THE USE, REPRODUCTION, MODIFICATION AND/OR DISTRIBUTION OF THE
-NVIDIA SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER THEORY OF CONTRACT,
-TORT (INCLUDING NEGLIGENCE), STRICT LIABILITY OR OTHERWISE, EVEN IF
-NVIDIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-\****************************************************************************/
-/* */ -/* symbols.c */ -/* */ -
-#include <assert.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-
-#include "slglobals.h"
-
-/*///////////////////////////////////////////////////////////////////////////////////////////// */ -/*///////////////////////////////// Symbol Table Variables: /////////////////////////////////// */ -/*///////////////////////////////////////////////////////////////////////////////////////////// */ -
-Scope *ScopeList = NULL;
-Scope *CurrentScope = NULL;
-Scope *GlobalScope = NULL;
-
-static void unlinkScope(void *_scope) {
- Scope *scope = _scope;
-
- if (scope->next)
- scope->next->prev = scope->prev;
- if (scope->prev)
- scope->prev->next = scope->next;
- else
- ScopeList = scope->next;
-}
-
-/*
- * NewScope()
- *
- */
-Scope *NewScopeInPool(MemoryPool *pool)
-{
- Scope *lScope;
-
- lScope = mem_Alloc(pool, sizeof(Scope));
- lScope->pool = pool;
- lScope->parent = NULL;
- lScope->funScope = NULL;
- lScope->symbols = NULL;
-
- lScope->level = 0;
-
- lScope->programs = NULL;
- if ((lScope->next = ScopeList))
- ScopeList->prev = lScope;
- lScope->prev = 0;
- ScopeList = lScope;
- mem_AddCleanup(pool, unlinkScope, lScope);
- return lScope;
-} /* NewScope */ -
-/*
- * PushScope()
- *
- */
-
-void PushScope(Scope *fScope)
-{
- Scope *lScope;
-
- if (CurrentScope) {
- fScope->level = CurrentScope->level + 1;
- if (fScope->level == 1) {
- if (!GlobalScope) {
- /* HACK - CTD -- if GlobalScope==NULL and level==1, we're
- * defining a function in the superglobal scope. Things
- * will break if we leave the level as 1, so we arbitrarily
- * set it to 2 */
- fScope->level = 2;
- }
- }
- if (fScope->level >= 2) {
- lScope = fScope;
- while (lScope->level > 2)
- lScope = lScope->next;
- fScope->funScope = lScope;
- }
- } else {
- fScope->level = 0;
- }
- fScope->parent = CurrentScope;
- CurrentScope = fScope;
-} /* PushScope */ -
-/*
- * PopScope()
- *
- */
-
-Scope *PopScope(void)
-{
- Scope *lScope;
-
- lScope = CurrentScope;
- if (CurrentScope)
- CurrentScope = CurrentScope->parent;
- return lScope;
-} /* PopScope */ -
-/*
- * NewSymbol() - Allocate a new symbol node;
- *
- */
-
-Symbol *NewSymbol(SourceLoc *loc, Scope *fScope, int name, symbolkind kind)
-{
- Symbol *lSymb;
- char *pch;
- int ii;
-
- lSymb = (Symbol *) mem_Alloc(fScope->pool, sizeof(Symbol));
- lSymb->left = NULL;
- lSymb->right = NULL;
- lSymb->next = NULL;
- lSymb->name = name;
- lSymb->loc = *loc;
- lSymb->kind = kind;
-
- /* Clear union area: */ -
- pch = (char *) &lSymb->details;
- for (ii = 0; ii < sizeof(lSymb->details); ii++)
- *pch++ = 0;
- return lSymb;
-} /* NewSymbol */ -
-/*
- * lAddToTree() - Using a binary tree is not a good idea for basic atom values because they
- * are generated in order. We'll fix this later (by reversing the bit pattern).
- */
-
-static void lAddToTree(Symbol **fSymbols, Symbol *fSymb)
-{
- Symbol *lSymb;
- int lrev, frev;
-
- lSymb = *fSymbols;
- if (lSymb) {
- frev = GetReversedAtom(atable, fSymb->name);
- while (lSymb) {
- lrev = GetReversedAtom(atable, lSymb->name);
- if (lrev == frev) {
- CPPErrorToInfoLog("GetAtomString(atable, fSymb->name)");
- break;
- } else {
- if (lrev > frev) {
- if (lSymb->left) {
- lSymb = lSymb->left;
- } else {
- lSymb->left = fSymb;
- break;
- }
- } else {
- if (lSymb->right) {
- lSymb = lSymb->right;
- } else {
- lSymb->right = fSymb;
- break;
- }
- }
- }
- }
- } else {
- *fSymbols = fSymb;
- }
-} /* lAddToTree */ -
-
-/*
- * AddSymbol() - Add a variable, type, or function name to a scope.
- *
- */
-
-Symbol *AddSymbol(SourceLoc *loc, Scope *fScope, int atom, symbolkind kind)
-{
- Symbol *lSymb;
-
- if (!fScope)
- fScope = CurrentScope;
- lSymb = NewSymbol(loc, fScope, atom, kind);
- lAddToTree(&fScope->symbols, lSymb);
- return lSymb;
-} /* AddSymbol */ -
-
-/*********************************************************************************************/
-/************************************ Symbol Semantic Functions ******************************/
-/*********************************************************************************************/
-
-/*
- * LookUpLocalSymbol()
- *
- */
-
-Symbol *LookUpLocalSymbol(Scope *fScope, int atom)
-{
- Symbol *lSymb;
- int rname, ratom;
-
- ratom = GetReversedAtom(atable, atom);
- if (!fScope)
- fScope = CurrentScope;
- lSymb = fScope->symbols;
- while (lSymb) {
- rname = GetReversedAtom(atable, lSymb->name);
- if (rname == ratom) {
- return lSymb;
- } else {
- if (rname > ratom) {
- lSymb = lSymb->left;
- } else {
- lSymb = lSymb->right;
- }
- }
- }
- return NULL;
-} /* LookUpLocalSymbol */ -
-/*
- * LookUpSymbol()
- *
- */
-
-Symbol *LookUpSymbol(Scope *fScope, int atom)
-{
- Symbol *lSymb;
-
- if (!fScope)
- fScope = CurrentScope;
- while (fScope) {
- lSymb = LookUpLocalSymbol(fScope, atom);
- if (lSymb)
- return lSymb;
- fScope = fScope->parent;
- }
- return NULL;
-} /* LookUpSymbol */ -
diff --git a/src/mesa/shader/slang/MachineIndependent/preprocessor/symbols.h b/src/mesa/shader/slang/MachineIndependent/preprocessor/symbols.h deleted file mode 100755 index 65cba9d6c9..0000000000 --- a/src/mesa/shader/slang/MachineIndependent/preprocessor/symbols.h +++ /dev/null @@ -1,145 +0,0 @@ -/* */ -/*Copyright (C) 2002-2005 3Dlabs Inc. Ltd. */ -/*All rights reserved. */ -/* */ -/*Redistribution and use in source and binary forms, with or without */ -/*modification, are permitted provided that the following conditions */ -/*are met: */ -/* */ -/* Redistributions of source code must retain the above copyright */ -/* notice, this list of conditions and the following disclaimer. */ -/* */ -/* Redistributions in binary form must reproduce the above */ -/* copyright notice, this list of conditions and the following */ -/* disclaimer in the documentation and/or other materials provided */ -/* with the distribution. */ -/* */ -/* Neither the name of 3Dlabs Inc. Ltd. nor the names of its */ -/* contributors may be used to endorse or promote products derived */ -/* from this software without specific prior written permission. */ -/* */ -/*THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS */ -/*"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT */ -/*LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS */ -/*FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE */ -/*COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, */ -/*INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, */ -/*BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; */ -/*LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER */ -/*CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT */ -/*LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN */ -/*ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE */ -/*POSSIBILITY OF SUCH DAMAGE. */ -/* */ -/****************************************************************************\
-Copyright (c) 2002, NVIDIA Corporation.
-
-NVIDIA Corporation("NVIDIA") supplies this software to you in
-consideration of your agreement to the following terms, and your use,
-installation, modification or redistribution of this NVIDIA software
-constitutes acceptance of these terms. If you do not agree with these
-terms, please do not use, install, modify or redistribute this NVIDIA
-software.
-
-In consideration of your agreement to abide by the following terms, and
-subject to these terms, NVIDIA grants you a personal, non-exclusive
-license, under NVIDIA's copyrights in this original NVIDIA software (the
-"NVIDIA Software"), to use, reproduce, modify and redistribute the
-NVIDIA Software, with or without modifications, in source and/or binary
-forms; provided that if you redistribute the NVIDIA Software, you must
-retain the copyright notice of NVIDIA, this notice and the following
-text and disclaimers in all such redistributions of the NVIDIA Software.
-Neither the name, trademarks, service marks nor logos of NVIDIA
-Corporation may be used to endorse or promote products derived from the
-NVIDIA Software without specific prior written permission from NVIDIA.
-Except as expressly stated in this notice, no other rights or licenses
-express or implied, are granted by NVIDIA herein, including but not
-limited to any patent rights that may be infringed by your derivative
-works or by other works in which the NVIDIA Software may be
-incorporated. No hardware is licensed hereunder.
-
-THE NVIDIA SOFTWARE IS BEING PROVIDED ON AN "AS IS" BASIS, WITHOUT
-WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED,
-INCLUDING WITHOUT LIMITATION, WARRANTIES OR CONDITIONS OF TITLE,
-NON-INFRINGEMENT, MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR
-ITS USE AND OPERATION EITHER ALONE OR IN COMBINATION WITH OTHER
-PRODUCTS.
-
-IN NO EVENT SHALL NVIDIA BE LIABLE FOR ANY SPECIAL, INDIRECT,
-INCIDENTAL, EXEMPLARY, CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
-TO, LOST PROFITS; PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
-USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) OR ARISING IN ANY WAY
-OUT OF THE USE, REPRODUCTION, MODIFICATION AND/OR DISTRIBUTION OF THE
-NVIDIA SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER THEORY OF CONTRACT,
-TORT (INCLUDING NEGLIGENCE), STRICT LIABILITY OR OTHERWISE, EVEN IF
-NVIDIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-\****************************************************************************/
-/* */ -/* symbols.h */ -/* */ -
-#if !defined(__SYMBOLS_H)
-#define __SYMBOLS_H 1
-
-#include "memory.h"
-
-typedef enum symbolkind {
- MACRO_S
-} symbolkind;
-
-/* Typedefs for things defined here in "symbols.h": */ -
-typedef struct Scope_Rec Scope;
-typedef struct Symbol_Rec Symbol;
-
-typedef struct SymbolList_Rec {
- struct SymbolList_Rec *next;
- Symbol *symb;
-} SymbolList;
-
-struct Scope_Rec {
- Scope *next, *prev; /* doubly-linked list of all scopes */ - Scope *parent;
- Scope *funScope; /* Points to base scope of enclosing function */ - MemoryPool *pool; /* pool used for allocation in this scope */ - Symbol *symbols;
-
- int level; /* 0 = super globals, 1 = globals, etc. */ -
- /* Only used at global scope (level 1): */ - SymbolList *programs; /* List of programs for this compilation. */ -};
-
-
-/* Symbol table is a simple binary tree. */ -
-#include "cpp.h" /* to get MacroSymbol def */ -
-struct Symbol_Rec {
- Symbol *left, *right;
- Symbol *next;
- int name; /* Name atom */ - SourceLoc loc;
- symbolkind kind;
- union {
- MacroSymbol mac;
- } details;
-};
-
-extern Scope *CurrentScope;
-extern Scope *GlobalScope;
-extern Scope *ScopeList;
-
-Scope *NewScopeInPool(MemoryPool *);
-#define NewScope() NewScopeInPool(CurrentScope->pool)
-void PushScope(Scope *fScope);
-Scope *PopScope(void);
-Symbol *NewSymbol(SourceLoc *loc, Scope *fScope, int name, symbolkind kind);
-Symbol *AddSymbol(SourceLoc *loc, Scope *fScope, int atom, symbolkind kind);
-Symbol *LookUpLocalSymbol(Scope *fScope, int atom);
-Symbol *LookUpSymbol(Scope *fScope, int atom);
-void CPPErrorToInfoLog(char *);
-
-
-#endif /* !defined(__SYMBOLS_H) */ -
diff --git a/src/mesa/shader/slang/MachineIndependent/preprocessor/tokens.c b/src/mesa/shader/slang/MachineIndependent/preprocessor/tokens.c deleted file mode 100755 index 815277db55..0000000000 --- a/src/mesa/shader/slang/MachineIndependent/preprocessor/tokens.c +++ /dev/null @@ -1,462 +0,0 @@ -/* */ -/*Copyright (C) 2002-2005 3Dlabs Inc. Ltd. */ -/*All rights reserved. */ -/* */ -/*Redistribution and use in source and binary forms, with or without */ -/*modification, are permitted provided that the following conditions */ -/*are met: */ -/* */ -/* Redistributions of source code must retain the above copyright */ -/* notice, this list of conditions and the following disclaimer. */ -/* */ -/* Redistributions in binary form must reproduce the above */ -/* copyright notice, this list of conditions and the following */ -/* disclaimer in the documentation and/or other materials provided */ -/* with the distribution. */ -/* */ -/* Neither the name of 3Dlabs Inc. Ltd. nor the names of its */ -/* contributors may be used to endorse or promote products derived */ -/* from this software without specific prior written permission. */ -/* */ -/*THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS */ -/*"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT */ -/*LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS */ -/*FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE */ -/*COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, */ -/*INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, */ -/*BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; */ -/*LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER */ -/*CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT */ -/*LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN */ -/*ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE */ -/*POSSIBILITY OF SUCH DAMAGE. */ -/* */ -/****************************************************************************\
-Copyright (c) 2002, NVIDIA Corporation.
-
-NVIDIA Corporation("NVIDIA") supplies this software to you in
-consideration of your agreement to the following terms, and your use,
-installation, modification or redistribution of this NVIDIA software
-constitutes acceptance of these terms. If you do not agree with these
-terms, please do not use, install, modify or redistribute this NVIDIA
-software.
-
-In consideration of your agreement to abide by the following terms, and
-subject to these terms, NVIDIA grants you a personal, non-exclusive
-license, under NVIDIA's copyrights in this original NVIDIA software (the
-"NVIDIA Software"), to use, reproduce, modify and redistribute the
-NVIDIA Software, with or without modifications, in source and/or binary
-forms; provided that if you redistribute the NVIDIA Software, you must
-retain the copyright notice of NVIDIA, this notice and the following
-text and disclaimers in all such redistributions of the NVIDIA Software.
-Neither the name, trademarks, service marks nor logos of NVIDIA
-Corporation may be used to endorse or promote products derived from the
-NVIDIA Software without specific prior written permission from NVIDIA.
-Except as expressly stated in this notice, no other rights or licenses
-express or implied, are granted by NVIDIA herein, including but not
-limited to any patent rights that may be infringed by your derivative
-works or by other works in which the NVIDIA Software may be
-incorporated. No hardware is licensed hereunder.
-
-THE NVIDIA SOFTWARE IS BEING PROVIDED ON AN "AS IS" BASIS, WITHOUT
-WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED,
-INCLUDING WITHOUT LIMITATION, WARRANTIES OR CONDITIONS OF TITLE,
-NON-INFRINGEMENT, MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR
-ITS USE AND OPERATION EITHER ALONE OR IN COMBINATION WITH OTHER
-PRODUCTS.
-
-IN NO EVENT SHALL NVIDIA BE LIABLE FOR ANY SPECIAL, INDIRECT,
-INCIDENTAL, EXEMPLARY, CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
-TO, LOST PROFITS; PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
-USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) OR ARISING IN ANY WAY
-OUT OF THE USE, REPRODUCTION, MODIFICATION AND/OR DISTRIBUTION OF THE
-NVIDIA SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER THEORY OF CONTRACT,
-TORT (INCLUDING NEGLIGENCE), STRICT LIABILITY OR OTHERWISE, EVEN IF
-NVIDIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-\****************************************************************************/
-/* */ -/* tokens.c */ -/* */ -
-#include <assert.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-#include <ctype.h>
-
-#include "slglobals.h"
-
-/*///////////////////////////////////////////////////////////////////////////////////////////// */ -/*////////////////////// Preprocessor and Token Recorder and Playback: //////////////////////// */ -/*///////////////////////////////////////////////////////////////////////////////////////////// */ -
-/*
- * idstr()
- * Copy a string to a malloc'ed block and convert it into something suitable
- * for an ID
- *
- */
-
-static char *idstr(const char *fstr)
-{
- size_t len;
- char *str, *t;
- const char *f;
-
- len = strlen(fstr);
- str = (char *) malloc(len + 1);
- for (f=fstr, t=str; *f; f++) {
- if (isalnum(*f)) *t++ = *f;
- else if (*f == '.' || *f == '/') *t++ = '_';
- }
- *t = 0;
- return str;
-} /* idstr */ -
-
-/*
- * lNewBlock()
- *
- */
-
-static TokenBlock *lNewBlock(TokenStream *fTok)
-{
- TokenBlock *lBlock;
-
- lBlock = (TokenBlock *) malloc(sizeof(TokenBlock) + 256);
- lBlock->count = 0;
- lBlock->current = 0;
- lBlock->data = (unsigned char *) lBlock + sizeof(TokenBlock);
- lBlock->max = 256;
- lBlock->next = NULL;
- if (fTok->head) {
- fTok->current->next = lBlock;
- } else {
- fTok->head = lBlock;
- }
- fTok->current = lBlock;
- return lBlock;
-} /* lNewBlock */ -
-/*
- * lAddByte()
- *
- */
-
-static void lAddByte(TokenStream *fTok, unsigned char fVal)
-{
- TokenBlock *lBlock;
- lBlock = fTok->current;
- if (lBlock->count >= lBlock->max)
- lBlock = lNewBlock(fTok);
- lBlock->data[lBlock->count++] = fVal;
-} /* lAddByte */ -
-
-
-/*
- * lReadByte() - Get the next byte from a stream.
- *
- */
-
-static int lReadByte(TokenStream *pTok)
-{
- TokenBlock *lBlock;
- int lval = -1;
-
- lBlock = pTok->current;
- if (lBlock) {
- if (lBlock->current >= lBlock->count) {
- lBlock = lBlock->next;
- if (lBlock)
- lBlock->current = 0;
- pTok->current = lBlock;
- }
- if (lBlock)
- lval = lBlock->data[lBlock->current++];
- }
- return lval;
-} /* lReadByte */ -
-/*///////////////////////////////////// Global Functions:////////////////////////////////////// */ -
-/*
- * NewTokenStream()
- *
- */
-
-TokenStream *NewTokenStream(const char *name)
-{
- TokenStream *pTok;
-
- pTok = (TokenStream *) malloc(sizeof(TokenStream));
- pTok->next = NULL;
- pTok->name = idstr(name);
- pTok->head = NULL;
- pTok->current = NULL;
- lNewBlock(pTok);
- return pTok;
-} /* NewTokenStream */ -
-/*
- * DeleteTokenStream()
- *
- */
-
-void DeleteTokenStream(TokenStream *pTok)
-{
- TokenBlock *pBlock, *nBlock;
-
- if (pTok) {
- pBlock = pTok->head;
- while (pBlock) {
- nBlock = pBlock->next;
- free(pBlock);
- pBlock = nBlock;
- }
- if (pTok->name)
- free(pTok->name);
- free(pTok);
- }
-} /* DeleteTokenStream */ -
-/*
- * RecordToken() - Add a token to the end of a list for later playback or printout.
- *
- */
-
-void RecordToken(TokenStream *pTok, int token, yystypepp * yylvalpp)
-{
- const char *s;
- unsigned char *str=NULL;
-
- if (token > 256)
- lAddByte(pTok, (unsigned char)((token & 0x7f) + 0x80));
- else
- lAddByte(pTok, (unsigned char)(token & 0x7f));
- switch (token) {
- case CPP_IDENTIFIER:
- case CPP_TYPEIDENTIFIER:
- case CPP_STRCONSTANT:
- s = GetAtomString(atable, yylvalpp->sc_ident);
- while (*s)
- lAddByte(pTok, (unsigned char) *s++);
- lAddByte(pTok, 0);
- break;
- case CPP_FLOATCONSTANT:
- case CPP_INTCONSTANT:
- str=yylvalpp->symbol_name;
- while (*str){
- lAddByte(pTok,(unsigned char) *str);
- *str++;
- }
- lAddByte(pTok, 0);
- break;
- case '(':
- lAddByte(pTok, (unsigned char)(yylvalpp->sc_int ? 1 : 0));
- default:
- break;
- }
-} /* RecordToken */ -
-/*
- * RewindTokenStream() - Reset a token stream in preperation for reading.
- *
- */
-
-void RewindTokenStream(TokenStream *pTok)
-{
- if (pTok->head) {
- pTok->current = pTok->head;
- pTok->current->current = 0;
- }
-} /* RewindTokenStream */ -
-/*
- * ReadToken() - Read the next token from a stream.
- *
- */
-
-int ReadToken(TokenStream *pTok, yystypepp * yylvalpp)
-{
- char symbol_name[MAX_SYMBOL_NAME_LEN + 1];
- char string_val[MAX_STRING_LEN + 1];
- int ltoken, len;
- char ch;
-
- ltoken = lReadByte(pTok);
- if (ltoken >= 0) {
- if (ltoken > 127)
- ltoken += 128;
- switch (ltoken) {
- case CPP_IDENTIFIER:
- case CPP_TYPEIDENTIFIER:
- len = 0;
- ch = lReadByte(pTok);
- while ((ch >= 'a' && ch <= 'z') ||
- (ch >= 'A' && ch <= 'Z') ||
- (ch >= '0' && ch <= '9') ||
- ch == '_')
- {
- if (len < MAX_SYMBOL_NAME_LEN) {
- symbol_name[len] = ch;
- len++;
- ch = lReadByte(pTok);
- }
- }
- symbol_name[len] = '\0';
- assert(ch == '\0');
- yylvalpp->sc_ident = LookUpAddString(atable, symbol_name);
- return CPP_IDENTIFIER;
- break;
- case CPP_STRCONSTANT:
- len = 0;
- while ((ch = lReadByte(pTok)) != 0)
- if (len < MAX_STRING_LEN)
- string_val[len++] = ch;
- string_val[len] = 0;
- yylvalpp->sc_ident = LookUpAddString(atable, string_val);
- break;
- case CPP_FLOATCONSTANT:
- len = 0;
- ch = lReadByte(pTok);
- while ((ch >= '0' && ch <= '9')||(ch=='e'||ch=='E'||ch=='.')||(ch=='+'||ch=='-'))
- {
- if (len < MAX_SYMBOL_NAME_LEN) {
- symbol_name[len] = ch;
- len++;
- ch = lReadByte(pTok);
- }
- }
- symbol_name[len] = '\0';
- assert(ch == '\0');
- strcpy(yylvalpp->symbol_name,symbol_name);
- yylvalpp->sc_fval=(float)atof(yylvalpp->symbol_name);
- break;
- case CPP_INTCONSTANT:
- len = 0;
- ch = lReadByte(pTok);
- while ((ch >= '0' && ch <= '9'))
- {
- if (len < MAX_SYMBOL_NAME_LEN) {
- symbol_name[len] = ch;
- len++;
- ch = lReadByte(pTok);
- }
- }
- symbol_name[len] = '\0';
- assert(ch == '\0');
- strcpy(yylvalpp->symbol_name,symbol_name);
- yylvalpp->sc_int=atoi(yylvalpp->symbol_name);
- break;
- case '(':
- yylvalpp->sc_int = lReadByte(pTok);
- break;
- }
- return ltoken;
- }
- return EOF_SY;
-} /* ReadToken */ -
-typedef struct TokenInputSrc {
- InputSrc base;
- TokenStream *tokens;
- int (*final)(CPPStruct *);
-} TokenInputSrc;
-
-static int scan_token(TokenInputSrc *in, yystypepp * yylvalpp)
-{
- int token = ReadToken(in->tokens, yylvalpp);
- int (*final)(CPPStruct *);
- cpp->tokenLoc->file = cpp->currentInput->name;
- cpp->tokenLoc->line = cpp->currentInput->line;
- if (token == '\n') {
- in->base.line++;
- return token;
- }
- if (token > 0) return token;
- cpp->currentInput = in->base.prev;
- final = in->final;
- free(in);
- if (final && !final(cpp)) return -1;
- return cpp->currentInput->scan(cpp->currentInput, yylvalpp);
-}
-
-int ReadFromTokenStream(TokenStream *ts, int name, int (*final)(CPPStruct *))
-{
- TokenInputSrc *in = malloc(sizeof(TokenInputSrc));
- memset(in, 0, sizeof(TokenInputSrc));
- in->base.name = name;
- in->base.prev = cpp->currentInput;
- in->base.scan = (int (*)(InputSrc *, yystypepp *))scan_token;
- in->base.line = 1;
- in->tokens = ts;
- in->final = final;
- RewindTokenStream(ts);
- cpp->currentInput = &in->base;
- return 1;
-}
-
-typedef struct UngotToken {
- InputSrc base;
- int token;
- yystypepp lval;
-} UngotToken;
-
-static int reget_token(UngotToken *t, yystypepp * yylvalpp)
-{
- int token = t->token;
- *yylvalpp = t->lval;
- cpp->currentInput = t->base.prev;
- free(t);
- return token;
-}
-
-void UngetToken(int token, yystypepp * yylvalpp) {
- UngotToken *t = malloc(sizeof(UngotToken));
- memset(t, 0, sizeof(UngotToken));
- t->token = token;
- t->lval = *yylvalpp;
- t->base.scan = (void *)reget_token;
- t->base.prev = cpp->currentInput;
- t->base.name = cpp->currentInput->name;
- t->base.line = cpp->currentInput->line;
- cpp->currentInput = &t->base;
-}
-
-
-void DumpTokenStream(FILE *fp, TokenStream *s, yystypepp * yylvalpp) {
- int token;
- char str[100];
-
- if (fp == 0) fp = stdout;
- RewindTokenStream(s);
- while ((token = ReadToken(s, yylvalpp)) > 0) {
- switch (token) {
- case CPP_IDENTIFIER:
- case CPP_TYPEIDENTIFIER:
- sprintf(str, "%s ", GetAtomString(atable, yylvalpp->sc_ident));
- break;
- case CPP_STRCONSTANT:
- sprintf(str, "\"%s\"", GetAtomString(atable, yylvalpp->sc_ident));
- break;
- case CPP_FLOATCONSTANT:
- /*printf("%g9.6 ", yylvalpp->sc_fval); */ - break;
- case CPP_INTCONSTANT:
- /*printf("%d ", yylvalpp->sc_int); */ - break;
- default:
- if (token >= 127)
- sprintf(str, "%s ", GetAtomString(atable, token));
- else
- sprintf(str, "%c", token);
- break;
- }
- CPPDebugLogMsg(str);
- }
-}
-
-/*///////////////////////////////////////////////////////////////////////////////////////////// */ -/*///////////////////////////////////// End of tokens.c /////////////////////////////////////// */ -/*///////////////////////////////////////////////////////////////////////////////////////////// */ diff --git a/src/mesa/shader/slang/MachineIndependent/preprocessor/tokens.h b/src/mesa/shader/slang/MachineIndependent/preprocessor/tokens.h deleted file mode 100755 index 0a25bf7c88..0000000000 --- a/src/mesa/shader/slang/MachineIndependent/preprocessor/tokens.h +++ /dev/null @@ -1,122 +0,0 @@ -/* */ -/*Copyright (C) 2002-2005 3Dlabs Inc. Ltd. */ -/*All rights reserved. */ -/* */ -/*Redistribution and use in source and binary forms, with or without */ -/*modification, are permitted provided that the following conditions */ -/*are met: */ -/* */ -/* Redistributions of source code must retain the above copyright */ -/* notice, this list of conditions and the following disclaimer. */ -/* */ -/* Redistributions in binary form must reproduce the above */ -/* copyright notice, this list of conditions and the following */ -/* disclaimer in the documentation and/or other materials provided */ -/* with the distribution. */ -/* */ -/* Neither the name of 3Dlabs Inc. Ltd. nor the names of its */ -/* contributors may be used to endorse or promote products derived */ -/* from this software without specific prior written permission. */ -/* */ -/*THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS */ -/*"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT */ -/*LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS */ -/*FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE */ -/*COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, */ -/*INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, */ -/*BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; */ -/*LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER */ -/*CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT */ -/*LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN */ -/*ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE */ -/*POSSIBILITY OF SUCH DAMAGE. */ -/* */ -/****************************************************************************\
-Copyright (c) 2002, NVIDIA Corporation.
-
-NVIDIA Corporation("NVIDIA") supplies this software to you in
-consideration of your agreement to the following terms, and your use,
-installation, modification or redistribution of this NVIDIA software
-constitutes acceptance of these terms. If you do not agree with these
-terms, please do not use, install, modify or redistribute this NVIDIA
-software.
-
-In consideration of your agreement to abide by the following terms, and
-subject to these terms, NVIDIA grants you a personal, non-exclusive
-license, under NVIDIA's copyrights in this original NVIDIA software (the
-"NVIDIA Software"), to use, reproduce, modify and redistribute the
-NVIDIA Software, with or without modifications, in source and/or binary
-forms; provided that if you redistribute the NVIDIA Software, you must
-retain the copyright notice of NVIDIA, this notice and the following
-text and disclaimers in all such redistributions of the NVIDIA Software.
-Neither the name, trademarks, service marks nor logos of NVIDIA
-Corporation may be used to endorse or promote products derived from the
-NVIDIA Software without specific prior written permission from NVIDIA.
-Except as expressly stated in this notice, no other rights or licenses
-express or implied, are granted by NVIDIA herein, including but not
-limited to any patent rights that may be infringed by your derivative
-works or by other works in which the NVIDIA Software may be
-incorporated. No hardware is licensed hereunder.
-
-THE NVIDIA SOFTWARE IS BEING PROVIDED ON AN "AS IS" BASIS, WITHOUT
-WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED,
-INCLUDING WITHOUT LIMITATION, WARRANTIES OR CONDITIONS OF TITLE,
-NON-INFRINGEMENT, MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR
-ITS USE AND OPERATION EITHER ALONE OR IN COMBINATION WITH OTHER
-PRODUCTS.
-
-IN NO EVENT SHALL NVIDIA BE LIABLE FOR ANY SPECIAL, INDIRECT,
-INCIDENTAL, EXEMPLARY, CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
-TO, LOST PROFITS; PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
-USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) OR ARISING IN ANY WAY
-OUT OF THE USE, REPRODUCTION, MODIFICATION AND/OR DISTRIBUTION OF THE
-NVIDIA SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER THEORY OF CONTRACT,
-TORT (INCLUDING NEGLIGENCE), STRICT LIABILITY OR OTHERWISE, EVEN IF
-NVIDIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-\****************************************************************************/
-/* */ -/* tokens.h */ -/* */ -
-#if !defined(__TOKENS_H)
-#define __TOKENS_H 1
-
-#include "parser.h"
-
-#define EOF_SY (-1)
-
-typedef struct TokenBlock_Rec TokenBlock;
-
-typedef struct TokenStream_Rec {
- struct TokenStream_Rec *next;
- char *name;
- TokenBlock *head;
- TokenBlock *current;
-} TokenStream;
-
-struct TokenBlock_Rec {
- TokenBlock *next;
- int current;
- int count;
- int max;
- unsigned char *data;
-};
-
-extern TokenStream stdlib_cpp_stream;
-
-
-TokenStream *NewTokenStream(const char *name);
-void DeleteTokenStream(TokenStream *pTok);
-void RecordToken(TokenStream *pTok, int token, yystypepp * yylvalpp);
-void RewindTokenStream(TokenStream *pTok);
-int ReadToken(TokenStream *pTok, yystypepp * yylvalpp);
-int ReadFromTokenStream(TokenStream *pTok, int name, int (*final)(CPPStruct *));
-void UngetToken(int, yystypepp * yylvalpp);
-
-#if defined(CPPC_ENABLE_TOOLS)
-
-void DumpTokenStream(FILE *, TokenStream *, yystypepp * yylvalpp);
-
-#endif /* defined(CPPC_ENABLE_TOOLS) */ -
-#endif /* !defined(__TOKENS_H) */ diff --git a/src/mesa/shader/slang/MachineIndependent/unistd.h b/src/mesa/shader/slang/MachineIndependent/unistd.h deleted file mode 100755 index efadd63fd9..0000000000 --- a/src/mesa/shader/slang/MachineIndependent/unistd.h +++ /dev/null @@ -1 +0,0 @@ -// This is a NULL file and is meant to be empty
diff --git a/src/mesa/shader/slang/OGLCompilersDLL/Initialisation.cpp b/src/mesa/shader/slang/OGLCompilersDLL/Initialisation.cpp deleted file mode 100755 index 2e6f8c69ba..0000000000 --- a/src/mesa/shader/slang/OGLCompilersDLL/Initialisation.cpp +++ /dev/null @@ -1,151 +0,0 @@ -//
-//Copyright (C) 2002-2005 3Dlabs Inc. Ltd.
-//All rights reserved.
-//
-//Redistribution and use in source and binary forms, with or without
-//modification, are permitted provided that the following conditions
-//are met:
-//
-// Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//
-// Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-//
-// Neither the name of 3Dlabs Inc. Ltd. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-//THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-//"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-//LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
-//FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
-//COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
-//INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
-//BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
-//LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
-//CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-//LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
-//ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
-//POSSIBILITY OF SUCH DAMAGE.
-//
-
-#define SH_EXPORTING
-#include "Initialisation.h"
-#include "Include/InitializeGlobals.h"
-#include "Include/InitializeParseContext.h"
-#include "Public/ShaderLang.h"
-
-OS_TLSIndex GlobalProcessFlag = OS_INVALID_TLS_INDEX;
-
-bool InitProcess()
-{
- if (GlobalProcessFlag != OS_INVALID_TLS_INDEX) {
- //
- // Function is re-entrant.
- //
- return true;
- }
-
- GlobalProcessFlag = OS_AllocTLSIndex();
-
- if (GlobalProcessFlag == OS_INVALID_TLS_INDEX) {
- assert (0 && "InitProcess(): Failed to allocate TLS area for init flag");
- return false;
- }
-
- if (!InitializePoolIndex()) {
- assert (0 && "InitProcess(): Failed to initalize global pool");
- return false;
- }
-
- if (!InitializeParseContextIndex()) {
- assert (0 && "InitProcess(): Failed to initalize parse context");
- return false;
- }
-
- InitThread();
- return true;
-}
-
-
-bool InitThread()
-{
- //
- // This function is re-entrant
- //
- if (GlobalProcessFlag == OS_INVALID_TLS_INDEX) {
- assert(0 && "InitThread(): Process hasn't been initalised.");
- return false;
- }
-
- if (OS_GetTLSValue(GlobalProcessFlag) != 0) {
- return true;
- }
-
- InitializeGlobalPools();
-
- if(!InitializeGlobalParseContext())
- return false;
-
- if(!OS_SetTLSValue(GlobalProcessFlag, (void *)1)) {
- assert(0 && "InitThread(): Unable to set init flag.");
- return false;
- }
-
- return true;
-}
-
-
-bool DetachThread()
-{
- bool retFlag = true;
-
- if (GlobalProcessFlag == OS_INVALID_TLS_INDEX) {
- assert(0 && "DetachThread(): Process hasn't been initalised.");
- return false;
- }
-
- //
- // Function is re-entrant and this thread may not have been initalised.
- //
- if (OS_GetTLSValue(GlobalProcessFlag) != 0)
- {
- if(!OS_SetTLSValue(GlobalProcessFlag, (void *)0)) {
- assert(0 && "DetachThread(): Unable to clear init flag.");
- retFlag = false;
- }
-
- FreeGlobalPools();
-
- if (!FreeParseContext())
- retFlag = false;
- }
-
- return retFlag;
-}
-
-bool DetachProcess()
-{
- bool retFlag = true;
-
- if (GlobalProcessFlag == OS_INVALID_TLS_INDEX)
- return true;
-
- ShFinalize();
-
- retFlag = DetachThread();
-
- FreePoolIndex();
-
- if(!FreeParseContextIndex())
- retFlag = false;
-
- OS_FreeTLSIndex(GlobalProcessFlag);
- GlobalProcessFlag = OS_INVALID_TLS_INDEX;
-
- return retFlag;
-}
-
diff --git a/src/mesa/shader/slang/OGLCompilersDLL/Initialisation.h b/src/mesa/shader/slang/OGLCompilersDLL/Initialisation.h deleted file mode 100755 index 1cfd97eeb3..0000000000 --- a/src/mesa/shader/slang/OGLCompilersDLL/Initialisation.h +++ /dev/null @@ -1,47 +0,0 @@ -//
-//Copyright (C) 2002-2005 3Dlabs Inc. Ltd.
-//All rights reserved.
-//
-//Redistribution and use in source and binary forms, with or without
-//modification, are permitted provided that the following conditions
-//are met:
-//
-// Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//
-// Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-//
-// Neither the name of 3Dlabs Inc. Ltd. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-//THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-//"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-//LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
-//FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
-//COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
-//INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
-//BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
-//LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
-//CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-//LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
-//ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
-//POSSIBILITY OF SUCH DAMAGE.
-//
-#ifndef __INITIALISATION_H
-#define __INITIALISATION_H
-
-
-#include "osinclude.h"
-
-
-bool InitProcess();
-bool InitThread();
-bool DetachThread();
-bool DetachProcess();
-
-#endif // __INITIALISATION_H
-
diff --git a/src/mesa/shader/slang/OSDependent/Linux/osinclude.h b/src/mesa/shader/slang/OSDependent/Linux/osinclude.h deleted file mode 100755 index 8b20b961c0..0000000000 --- a/src/mesa/shader/slang/OSDependent/Linux/osinclude.h +++ /dev/null @@ -1,78 +0,0 @@ -//
-//Copyright (C) 2002-2005 3Dlabs Inc. Ltd.
-//All rights reserved.
-//
-//Redistribution and use in source and binary forms, with or without
-//modification, are permitted provided that the following conditions
-//are met:
-//
-// Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//
-// Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-//
-// Neither the name of 3Dlabs Inc. Ltd. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-//THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-//"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-//LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
-//FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
-//COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
-//INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
-//BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
-//LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
-//CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-//LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
-//ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
-//POSSIBILITY OF SUCH DAMAGE.
-//
-
-#ifndef __OSINCLUDE_H
-#define __OSINCLUDE_H
-
-//
-// This file contains any Linux specific functions.
-//
-
-/* WORKAROUND: linux builds seem not to define "linux" */
-/*#if !(defined(linux))
-#error Trying to include a Linux specific file in a non-Linux build.
-#endif*/
-
-#include <pthread.h>
-#include <semaphore.h>
-#include <assert.h>
-#include <errno.h>
-#include "Include/InitializeGlobals.h"
-#include "Include/PoolAlloc.h"
-
-#define _vsnprintf vsnprintf
-
-void DetachThreadLinux(void *);
-
-//
-// Thread Local Storage Operations
-//
-typedef unsigned int OS_TLSIndex;
-#define OS_INVALID_TLS_INDEX 0xFFFFFFFF
-
-OS_TLSIndex OS_AllocTLSIndex();
-bool OS_SetTLSValue(OS_TLSIndex nIndex, void *lpvValue);
-bool OS_FreeTLSIndex(OS_TLSIndex nIndex);
-
-
-inline void * OS_GetTLSValue(OS_TLSIndex nIndex)
-{
- //
- // This function should return 0 if nIndex is invalid.
- //
- assert(nIndex != OS_INVALID_TLS_INDEX);
- return (pthread_getspecific(nIndex));
-}
-
-#endif // __OSINCLUDE_H
diff --git a/src/mesa/shader/slang/OSDependent/Linux/ossource.cpp b/src/mesa/shader/slang/OSDependent/Linux/ossource.cpp deleted file mode 100755 index 4bcd66a315..0000000000 --- a/src/mesa/shader/slang/OSDependent/Linux/ossource.cpp +++ /dev/null @@ -1,140 +0,0 @@ -//
-//Copyright (C) 2002-2005 3Dlabs Inc. Ltd.
-//All rights reserved.
-//
-//Redistribution and use in source and binary forms, with or without
-//modification, are permitted provided that the following conditions
-//are met:
-//
-// Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//
-// Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-//
-// Neither the name of 3Dlabs Inc. Ltd. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-//THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-//"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-//LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
-//FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
-//COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
-//INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
-//BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
-//LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
-//CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-//LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
-//ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
-//POSSIBILITY OF SUCH DAMAGE.
-//
-
-//
-// This file contains the Linux specific functions
-//
-#include "osinclude.h"
-#include "Initialisation.h"
-
-/*#if !(defined(linux))
-#error Trying to build a Linux specific file in a non-Linux build.
-#endif*/
-
-//
-// Thread cleanup
-//
-
-//
-// Wrapper for Linux call to DetachThread. This is required as pthread_cleanup_push() expects
-// the cleanup routine to return void.
-//
-void DetachThreadLinux(void *)
-{
- DetachThread();
-}
-
-
-//
-// Registers cleanup handler, sets cancel type and state, and excecutes the thread specific
-// cleanup handler. This function will be called in the Standalone.cpp for regression
-// testing. When OpenGL applications are run with the driver code, Linux OS does the
-// thread cleanup.
-//
-void OS_CleanupThreadData(void)
-{
- int old_cancel_state, old_cancel_type;
- void *cleanupArg = NULL;
-
- //
- // Set thread cancel state and push cleanup handler.
- //
- pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, &old_cancel_state);
- pthread_cleanup_push(DetachThreadLinux, (void *) cleanupArg);
-
- //
- // Put the thread in deferred cancellation mode.
- //
- pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, &old_cancel_type);
-
- //
- // Pop cleanup handler and execute it prior to unregistering the cleanup handler.
- //
- pthread_cleanup_pop(1);
-
- //
- // Restore the thread's previous cancellation mode.
- //
- pthread_setcanceltype(old_cancel_state, NULL);
-}
-
-
-//
-// Thread Local Storage Operations
-//
-OS_TLSIndex OS_AllocTLSIndex()
-{
- pthread_key_t pPoolIndex;
-
- //
- // Create global pool key.
- //
- if ((pthread_key_create(&pPoolIndex, NULL)) != 0) {
- assert(0 && "OS_AllocTLSIndex(): Unable to allocate Thread Local Storage");
- return false;
- }
- else
- return pPoolIndex;
-}
-
-
-bool OS_SetTLSValue(OS_TLSIndex nIndex, void *lpvValue)
-{
- if (nIndex == OS_INVALID_TLS_INDEX) {
- assert(0 && "OS_SetTLSValue(): Invalid TLS Index");
- return false;
- }
-
- if (pthread_setspecific(nIndex, lpvValue) == 0)
- return true;
- else
- return false;
-}
-
-
-bool OS_FreeTLSIndex(OS_TLSIndex nIndex)
-{
- if (nIndex == OS_INVALID_TLS_INDEX) {
- assert(0 && "OS_SetTLSValue(): Invalid TLS Index");
- return false;
- }
-
- //
- // Delete the global pool key.
- //
- if (pthread_key_delete(nIndex) == 0)
- return true;
- else
- return false;
-}
diff --git a/src/mesa/shader/slang/OSDependent/Windows/osinclude.h b/src/mesa/shader/slang/OSDependent/Windows/osinclude.h deleted file mode 100755 index 97a9e9f3df..0000000000 --- a/src/mesa/shader/slang/OSDependent/Windows/osinclude.h +++ /dev/null @@ -1,68 +0,0 @@ -//
-//Copyright (C) 2002-2005 3Dlabs Inc. Ltd.
-//All rights reserved.
-//
-//Redistribution and use in source and binary forms, with or without
-//modification, are permitted provided that the following conditions
-//are met:
-//
-// Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//
-// Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-//
-// Neither the name of 3Dlabs Inc. Ltd. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-//THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-//"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-//LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
-//FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
-//COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
-//INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
-//BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
-//LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
-//CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-//LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
-//ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
-//POSSIBILITY OF SUCH DAMAGE.
-//
-
-#ifndef __OSINCLUDE_H
-#define __OSINCLUDE_H
-
-//
-// This file contains contains the window's specific datatypes and
-// declares any windows specific functions.
-//
-
-#if !(defined(_WIN32) || defined(_WIN64))
-#error Trying to include a windows specific file in a non windows build.
-#endif
-
-#define STRICT
-#define VC_EXTRALEAN 1
-#include <windows.h>
-#include <assert.h>
-
-//
-// Thread Local Storage Operations
-//
-typedef DWORD OS_TLSIndex;
-#define OS_INVALID_TLS_INDEX (TLS_OUT_OF_INDEXES)
-
-OS_TLSIndex OS_AllocTLSIndex();
-bool OS_SetTLSValue(OS_TLSIndex nIndex, void *lpvValue);
-bool OS_FreeTLSIndex(OS_TLSIndex nIndex);
-
-inline void* OS_GetTLSValue(OS_TLSIndex nIndex)
-{
- assert(nIndex != OS_INVALID_TLS_INDEX);
- return TlsGetValue(nIndex);
-}
-
-#endif // __OSINCLUDE_H
diff --git a/src/mesa/shader/slang/OSDependent/Windows/ossource.cpp b/src/mesa/shader/slang/OSDependent/Windows/ossource.cpp deleted file mode 100755 index 35d086614c..0000000000 --- a/src/mesa/shader/slang/OSDependent/Windows/ossource.cpp +++ /dev/null @@ -1,119 +0,0 @@ -//
-//Copyright (C) 2002-2005 3Dlabs Inc. Ltd.
-//All rights reserved.
-//
-//Redistribution and use in source and binary forms, with or without
-//modification, are permitted provided that the following conditions
-//are met:
-//
-// Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//
-// Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-//
-// Neither the name of 3Dlabs Inc. Ltd. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-//THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-//"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-//LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
-//FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
-//COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
-//INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
-//BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
-//LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
-//CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-//LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
-//ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
-//POSSIBILITY OF SUCH DAMAGE.
-//
-
-#include "Initialisation.h"
-
-//
-// This file contains contains the window's specific functions
-//
-
-#if !(defined(_WIN32) || defined(_WIN64))
-#error Trying to build a windows specific file in a non windows build.
-#endif
-
-BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
-{
- switch (fdwReason)
- {
- case DLL_PROCESS_ATTACH:
- if (!InitProcess())
- return false;
- break;
- case DLL_THREAD_ATTACH:
- if (!InitThread())
- return false;
- break;
-
- case DLL_THREAD_DETACH:
-
- if (!DetachThread())
- return false;
- break;
-
- case DLL_PROCESS_DETACH:
-
- DetachProcess();
- break;
-
- default:
- assert(0 && "DllMain(): Reason for calling DLL Main is unknown");
- return false;
- }
-
- return true;
-}
-
-//
-// Thread Local Storage Operations
-//
-OS_TLSIndex OS_AllocTLSIndex()
-{
- DWORD dwIndex = TlsAlloc();
- if (dwIndex == TLS_OUT_OF_INDEXES) {
- assert(0 && "OS_AllocTLSIndex(): Unable to allocate Thread Local Storage");
- return (OS_INVALID_TLS_INDEX);
- }
-
- return dwIndex;
-}
-
-
-bool OS_SetTLSValue(OS_TLSIndex nIndex, void *lpvValue)
-{
- if (nIndex == OS_INVALID_TLS_INDEX)
- {
- assert(0 && "OS_SetTLSValue(): Invalid TLS Index");
- return false;
- }
-
- if (TlsSetValue(nIndex, lpvValue))
- return true;
- else
- return false;
-}
-
-
-bool OS_FreeTLSIndex(OS_TLSIndex nIndex)
-{
- if (nIndex == OS_INVALID_TLS_INDEX) {
- assert(0 && "OS_SetTLSValue(): Invalid TLS Index");
- return false;
- }
-
- if (TlsFree(nIndex))
- return true;
- else
- return false;
-}
-
diff --git a/src/mesa/shader/slang/Public/ShaderLang.h b/src/mesa/shader/slang/Public/ShaderLang.h deleted file mode 100755 index 34b1688e87..0000000000 --- a/src/mesa/shader/slang/Public/ShaderLang.h +++ /dev/null @@ -1,212 +0,0 @@ -/*
-//Copyright (C) 2002-2005 3Dlabs Inc. Ltd.
-//All rights reserved.
-//
-//Redistribution and use in source and binary forms, with or without
-//modification, are permitted provided that the following conditions
-//are met:
-//
-// Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//
-// Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-//
-// Neither the name of 3Dlabs Inc. Ltd. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-//THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-//"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-//LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
-//FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
-//COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
-//INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
-//BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
-//LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
-//CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-//LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
-//ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
-//POSSIBILITY OF SUCH DAMAGE.
-*/
-#ifndef _COMPILER_INTERFACE_INCLUDED_
-#define _COMPILER_INTERFACE_INCLUDED_
-
-#include "../Include/ResourceLimits.h"
-
-#ifdef _WIN32
-#define C_DECL __cdecl
-/*#ifdef SH_EXPORTING
- #define SH_IMPORT_EXPORT __declspec(dllexport)
-#else
- #define SH_IMPORT_EXPORT __declspec(dllimport)
-#endif*/
-/* disable DLL linking */
-#define SH_IMPORT_EXPORT
-#else
-#define SH_IMPORT_EXPORT
-#define __fastcall
-#define C_DECL
-#endif
-
-/*
-// This is the platform independent interface between an OGL driver
-// and the shading language compiler/linker.
-*/
-
-#ifdef __cplusplus
- extern "C" {
-#endif
-
-/*
-// Driver must call this first, once, before doing any other
-// compiler/linker operations.
-*/
-SH_IMPORT_EXPORT int ShInitialize();
-/*
-// Driver should call this at shutdown.
-*/
-SH_IMPORT_EXPORT int __fastcall ShFinalize();
-
-/*
-// Types of languages the compiler can consume.
-*/
-typedef enum {
- EShLangVertex,
- EShLangFragment,
- EShLangPack,
- EShLangUnpack,
- EShLangCount
-} EShLanguage;
-
-/*
-// Types of output the linker will create.
-*/
-typedef enum {
- EShExVertexFragment,
- EShExPackFragment,
- EShExUnpackFragment,
- EShExFragment
-} EShExecutable;
-
-/*
-// Optimization level for the compiler.
-*/
-typedef enum {
- EShOptNoGeneration,
- EShOptNone,
- EShOptSimple, /* Optimizations that can be done quickly */
- EShOptFull /* Optimizations that will take more time */
-} EShOptimizationLevel;
-
-/*
-// Build a table for bindings. This can be used for locating
-// attributes, uniforms, globals, etc., as needed.
-*/
-typedef struct {
- char* name;
- int binding;
-} ShBinding;
-
-typedef struct {
- int numBindings;
- ShBinding* bindings; /* array of bindings */
-} ShBindingTable;
-
-/*
-// ShHandle held by but opaque to the driver. It is allocated,
-// managed, and de-allocated by the compiler/linker. It's contents
-// are defined by and used by the compiler and linker. For example,
-// symbol table information and object code passed from the compiler
-// to the linker can be stored where ShHandle points.
-//
-// If handle creation fails, 0 will be returned.
-*/
-typedef void* ShHandle;
-
-/*
-// Driver calls these to create and destroy compiler/linker
-// objects.
-*/
-SH_IMPORT_EXPORT ShHandle ShConstructCompiler(const EShLanguage, int debugOptions); /* one per shader */
-SH_IMPORT_EXPORT ShHandle ShConstructLinker(const EShExecutable, int debugOptions); /* one per shader pair */
-SH_IMPORT_EXPORT ShHandle ShConstructUniformMap(); /* one per uniform namespace (currently entire program object) */
-SH_IMPORT_EXPORT void ShDestruct(ShHandle);
-
-/*
-// The return value of ShCompile is boolean, indicating
-// success or failure.
-//
-// The info-log should be written by ShCompile into
-// ShHandle, so it can answer future queries.
-*/
-SH_IMPORT_EXPORT int ShCompile(
- const ShHandle,
- const char* const shaderStrings[],
- const int numStrings,
- const EShOptimizationLevel,
- const TBuiltInResource *resources,
- int debugOptions
- );
-
-
-/*
-// Similar to ShCompile, but accepts an opaque handle to an
-// intermediate language structure.
-*/
-SH_IMPORT_EXPORT int ShCompileIntermediate(
- ShHandle compiler,
- ShHandle intermediate,
- const EShOptimizationLevel,
- int debuggable /* boolean */
- );
-
-SH_IMPORT_EXPORT int ShLink(
- const ShHandle, /* linker object */
- const ShHandle h[], /* compiler objects to link together */
- const int numHandles,
- ShHandle uniformMap, /* updated with new uniforms */
- short int** uniformsAccessed, /* returned with indexes of uniforms accessed */
- int* numUniformsAccessed);
-
-/*
-// ShSetEncrpytionMethod is a place-holder for specifying
-// how source code is encrypted.
-*/
-SH_IMPORT_EXPORT void ShSetEncryptionMethod(ShHandle);
-
-/*
-// All the following return 0 if the information is not
-// available in the object passed down, or the object is bad.
-*/
-SH_IMPORT_EXPORT const char* ShGetInfoLog(const ShHandle);
-SH_IMPORT_EXPORT const void* ShGetExecutable(const ShHandle);
-SH_IMPORT_EXPORT int ShSetVirtualAttributeBindings(const ShHandle, const ShBindingTable*); /* to detect user aliasing */
-SH_IMPORT_EXPORT int ShSetFixedAttributeBindings(const ShHandle, const ShBindingTable*); /* to force any physical mappings */
-SH_IMPORT_EXPORT int ShGetPhysicalAttributeBindings(const ShHandle, const ShBindingTable**); /* for all attributes */
-/*
-// Tell the linker to never assign a vertex attribute to this list of physical attributes
-*/
-SH_IMPORT_EXPORT int ShExcludeAttributes(const ShHandle, int *attributes, int count);
-
-/*
-// Returns the location ID of the named uniform.
-// Returns -1 if error.
-*/
-SH_IMPORT_EXPORT int ShGetUniformLocation(const ShHandle uniformMap, const char* name);
-
-enum TDebugOptions {
- EDebugOpNone = 0x000,
- EDebugOpIntermediate = 0x001,
- EDebugOpAssembly = 0x002,
- EDebugOpObjectCode = 0x004,
- EDebugOpLinkMaps = 0x008
-};
-
-#ifdef __cplusplus
- }
-#endif
-
-#endif /* _COMPILER_INTERFACE_INCLUDED_ */
diff --git a/src/mesa/shader/slang/Public/ShaderLangExt.h b/src/mesa/shader/slang/Public/ShaderLangExt.h deleted file mode 100755 index e44b5f99af..0000000000 --- a/src/mesa/shader/slang/Public/ShaderLangExt.h +++ /dev/null @@ -1,57 +0,0 @@ -//
-//Copyright (C) 2002-2004 3Dlabs Inc. Ltd.
-//All rights reserved.
-//
-//Redistribution and use in source and binary forms, with or without
-//modification, are permitted provided that the following conditions
-//are met:
-//
-// Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//
-// Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-//
-// Neither the name of 3Dlabs Inc. Ltd. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-//THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-//"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-//LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
-//FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
-//COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
-//INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
-//BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
-//LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
-//CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-//LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
-//ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
-//POSSIBILITY OF SUCH DAMAGE.
-//
-#ifndef _SHADERLANG_EXTENSION_INCLUDED_
-#define _SHADERLANG_EXTENSION_INCLUDED_
-
-#include "ShaderLang.h"
-
-//
-// This is the platform independent interface between an OGL driver
-// and the shading language compiler/linker.
-//
-
-#ifdef __cplusplus
- extern "C" {
-#endif
-
-SH_IMPORT_EXPORT int ShLinkExt(
- const ShHandle, // linker object
- const ShHandle h[], // compiler objects to link together
- const int numHandles);
-
-#ifdef __cplusplus
- }
-#endif
-
-#endif // _SHADERLANG_EXTENSION_INCLUDED_
diff --git a/src/mesa/shader/slang/library/Makefile b/src/mesa/shader/slang/library/Makefile index 92a313d7b0..dc67b59088 100644 --- a/src/mesa/shader/slang/library/Makefile +++ b/src/mesa/shader/slang/library/Makefile @@ -21,7 +21,7 @@ clean: syntax: slang_pp_directives_syn.h slang_pp_expression_syn.h slang_shader_syn.h slang_pp_version_syn.h -builtin: builtin_110 builtin_120 builtin_vec4 +builtin: builtin_110 builtin_120 # # executables @@ -29,7 +29,7 @@ builtin: builtin_110 builtin_120 builtin_vec4 syn_to_c: syn_to_c.c $(CC) syn_to_c.c -o syn_to_c - + gc_to_bin: gc_to_bin.c slang_shader_syn.h $(CC) gc_to_bin.c -o gc_to_bin @@ -57,7 +57,6 @@ builtin_110: slang_common_builtin_gc.h slang_core_gc.h slang_fragment_builtin_gc builtin_120: slang_120_core_gc.h slang_builtin_120_common_gc.h slang_builtin_120_fragment_gc.h -builtin_vec4: slang_builtin_vec4_gc.h slang_120_core_gc.h: gc_to_bin slang_120_core.gc ./gc_to_bin 1 slang_120_core.gc slang_120_core_gc.h @@ -68,9 +67,6 @@ slang_builtin_120_common_gc.h: gc_to_bin slang_builtin_120_common.gc slang_builtin_120_fragment_gc.h: gc_to_bin slang_builtin_120_fragment.gc ./gc_to_bin 1 slang_builtin_120_fragment.gc slang_builtin_120_fragment_gc.h -slang_builtin_vec4_gc.h: gc_to_bin slang_builtin_vec4.gc - ./gc_to_bin 1 slang_builtin_vec4.gc slang_builtin_vec4_gc.h - slang_common_builtin_gc.h: gc_to_bin slang_common_builtin.gc ./gc_to_bin 1 slang_common_builtin.gc slang_common_builtin_gc.h diff --git a/src/mesa/shader/slang/library/gc_to_bin.c b/src/mesa/shader/slang/library/gc_to_bin.c index ce9a6541ac..8aef7b5412 100755..100644 --- a/src/mesa/shader/slang/library/gc_to_bin.c +++ b/src/mesa/shader/slang/library/gc_to_bin.c @@ -68,11 +68,14 @@ int main (int argc, char *argv[]) grammar id; id = grammar_load_from_text ((const byte *) slang_shader_syn); - if (id == 0) + if (id == 0) { + fprintf(stderr, "Error loading grammar from text\n"); return 1; + } grammar_set_reg8 (id, (const byte *) "parsing_builtin", 1); grammar_set_reg8 (id, (const byte *) "shader_type", atoi (argv[1])); if (gc_to_bin (id, argv[2], argv[3])) { + fprintf(stderr, "Error in gc_to_bin %s %s\n", argv[2], argv[3]); grammar_destroy (id); return 1; } diff --git a/src/mesa/shader/slang/library/slang_120_core.gc b/src/mesa/shader/slang/library/slang_120_core.gc index cf5d44e8ce..cf5d44e8ce 100755..100644 --- a/src/mesa/shader/slang/library/slang_120_core.gc +++ b/src/mesa/shader/slang/library/slang_120_core.gc diff --git a/src/mesa/shader/slang/library/slang_builtin_120_common.gc b/src/mesa/shader/slang/library/slang_builtin_120_common.gc index c6264c3b47..c6264c3b47 100755..100644 --- a/src/mesa/shader/slang/library/slang_builtin_120_common.gc +++ b/src/mesa/shader/slang/library/slang_builtin_120_common.gc diff --git a/src/mesa/shader/slang/library/slang_builtin_120_fragment.gc b/src/mesa/shader/slang/library/slang_builtin_120_fragment.gc index 7d516046a1..7d516046a1 100755..100644 --- a/src/mesa/shader/slang/library/slang_builtin_120_fragment.gc +++ b/src/mesa/shader/slang/library/slang_builtin_120_fragment.gc diff --git a/src/mesa/shader/slang/library/slang_builtin_vec4.gc b/src/mesa/shader/slang/library/slang_builtin_vec4.gc deleted file mode 100755 index d549c0133a..0000000000 --- a/src/mesa/shader/slang/library/slang_builtin_vec4.gc +++ /dev/null @@ -1,220 +0,0 @@ -/* - * Mesa 3-D graphics library - * Version: 6.5 - * - * Copyright (C) 2006 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. - */ - -// -// This file overrides most of the standard built-in functions that operate on vec4 data type. -// This file also overrides most commonly used functions that do not neccessarily operate -// on vec4 data type, like dot(vec3,vec3). Those are adapted to vec4 instructions and are believed -// to execute faster. -// This file replaces parts of the core.gc and common.gc, so it must be included somewhere after -// the common.gc file. -// -// Assembly instructions required: -// float_to_vec4 -// vec4_add -// vec4_subtract -// vec4_multiply -// vec4_divide -// vec4_negate -// vec4_dot -// - - -vec4 __constructor (const float f) { - vec4 v; - __asm float_to_vec4 v, f; - return v; -} - - -void __operator += (inout vec4 v, const vec4 u) { - __asm vec4_add v, u; -} - -void __operator -= (inout vec4 v, const vec4 u) { - __asm vec4_subtract v, u; -} - -void __operator *= (inout vec4 v, const vec4 u) { - __asm vec4_multiply v, u; -} - -void __operator /= (inout vec4 v, const vec4 u) { - __asm vec4_divide v, u; -} - - -void __operator += (inout vec4 v, const float a) { - vec4 u; - __asm float_to_vec4 u, a; - __asm vec4_add v, u; -} - -void __operator -= (inout vec4 v, const float a) { - vec4 u; - __asm float_to_vec4 u, a; - __asm vec4_subtract v, u; -} - -void __operator *= (inout vec4 v, const float a) { - vec4 u; - __asm float_to_vec4 u, a; - __asm vec4_multiply v, u; -} - -void __operator /= (inout vec4 v, const float a) { - vec4 u; - __asm float_to_vec4 u, a; - __asm vec4_divide v, u; -} - - -vec4 __operator + (vec4 v, const vec4 u) { - __asm vec4_add v, u; - return v; -} - -vec4 __operator - (vec4 v, const vec4 u) { - __asm vec4_subtract v, u; - return v; -} - -vec4 __operator * (vec4 v, const vec4 u) { - __asm vec4_multiply v, u; - return v; -} - -vec4 __operator / (vec4 v, const vec4 u) { - __asm vec4_divide v, u; - return v; -} - - -vec4 __operator + (const float a, const vec4 u) { - vec4 v; - __asm float_to_vec4 v, a; - __asm vec4_add v, u; - return v; -} - -vec4 __operator + (const vec4 v, const float b) { - vec4 u; - __asm float_to_vec4 u, b; - __asm vec4_add u, v; - return u; -} - -vec4 __operator - (const float a, const vec4 u) { - vec4 v; - __asm float_to_vec4 v, a; - __asm vec4_subtract v, u; - return v; -} - -vec4 __operator - (vec4 v, const float b) { - vec4 u; - __asm float_to_vec4 u, b; - __asm vec4_subtract v, u; - return v; -} - -vec4 __operator * (const float a, const vec4 u) { - vec4 v; - __asm float_to_vec4 v, a; - __asm vec4_multiply v, u; - return v; -} - -vec4 __operator * (const vec4 v, const float b) { - vec4 u; - __asm float_to_vec4 u, b; - __asm vec4_multiply u, v; - return u; -} - -vec4 __operator / (const float a, const vec4 u) { - vec4 v; - __asm float_to_vec4 v, a; - __asm vec4_divide v, u; - return v; -} - -vec4 __operator / (vec4 v, const float b) { - vec4 u; - __asm float_to_vec4 u, b; - __asm vec4_divide v, u; - return v; -} - - -vec4 __operator - (vec4 v) { - __asm vec4_negate v; - return v; -} - - -float dot (vec3 v, vec3 u) { - vec4 v4 = vec4 (v, 0.0); - vec4 u4 = vec4 (u, 0.0); - __asm vec4_dot v4, u4; - return v4.x; -} - -float dot (vec4 v, vec4 u) { - __asm vec4_dot v, u; - return v.x; -} - - -float length (vec3 v) { - vec4 u = vec4 (v, 0.0); - __asm vec4_dot u, u; - return sqrt (u.x); -} - -float length (vec4 v) { - __asm vec4_dot v, v; - return sqrt (v.x); -} - - -vec3 normalize (vec3 v) { - vec4 u = vec4 (v, 0.0); - vec4 w = u; - __asm vec4_dot u, u; - float l = sqrt (u.x); - __asm float_to_vec4 u, l; - __asm vec4_divide w, u; - return w.xyz; -} - -vec4 normalize (vec4 v) { - vec4 w = v; - __asm vec4_dot v, v; - float l = sqrt (v.x); - __asm float_to_vec4 v, l; - __asm vec4_divide w, v; - return w; -} - diff --git a/src/mesa/shader/slang/library/slang_builtin_vec4_gc.h b/src/mesa/shader/slang/library/slang_builtin_vec4_gc.h deleted file mode 100644 index 9c3bae2644..0000000000 --- a/src/mesa/shader/slang/library/slang_builtin_vec4_gc.h +++ /dev/null @@ -1,62 +0,0 @@ - -/* DO NOT EDIT - THIS FILE IS AUTOMATICALLY GENERATED FROM THE FOLLOWING FILE: */ -/* slang_builtin_vec4.gc */ - -3,1,0,12,1,1,1,0,9,102,0,0,0,1,3,2,0,12,1,118,0,0,0,4,102,108,111,97,116,95,116,111,95,118,101,99, -52,0,18,118,0,0,18,102,0,0,0,8,18,118,0,0,0,1,0,0,2,1,1,0,2,12,118,0,0,1,1,0,12,117,0,0,0,1,4,118, -101,99,52,95,97,100,100,0,18,118,0,0,18,117,0,0,0,0,1,0,0,2,2,1,0,2,12,118,0,0,1,1,0,12,117,0,0,0, -1,4,118,101,99,52,95,115,117,98,116,114,97,99,116,0,18,118,0,0,18,117,0,0,0,0,1,0,0,2,3,1,0,2,12, -118,0,0,1,1,0,12,117,0,0,0,1,4,118,101,99,52,95,109,117,108,116,105,112,108,121,0,18,118,0,0,18, -117,0,0,0,0,1,0,0,2,4,1,0,2,12,118,0,0,1,1,0,12,117,0,0,0,1,4,118,101,99,52,95,100,105,118,105,100, -101,0,18,118,0,0,18,117,0,0,0,0,1,0,0,2,1,1,0,2,12,118,0,0,1,1,0,9,97,0,0,0,1,3,2,0,12,1,117,0,0,0, -4,102,108,111,97,116,95,116,111,95,118,101,99,52,0,18,117,0,0,18,97,0,0,0,4,118,101,99,52,95,97, -100,100,0,18,118,0,0,18,117,0,0,0,0,1,0,0,2,2,1,0,2,12,118,0,0,1,1,0,9,97,0,0,0,1,3,2,0,12,1,117,0, -0,0,4,102,108,111,97,116,95,116,111,95,118,101,99,52,0,18,117,0,0,18,97,0,0,0,4,118,101,99,52,95, -115,117,98,116,114,97,99,116,0,18,118,0,0,18,117,0,0,0,0,1,0,0,2,3,1,0,2,12,118,0,0,1,1,0,9,97,0,0, -0,1,3,2,0,12,1,117,0,0,0,4,102,108,111,97,116,95,116,111,95,118,101,99,52,0,18,117,0,0,18,97,0,0,0, -4,118,101,99,52,95,109,117,108,116,105,112,108,121,0,18,118,0,0,18,117,0,0,0,0,1,0,0,2,4,1,0,2,12, -118,0,0,1,1,0,9,97,0,0,0,1,3,2,0,12,1,117,0,0,0,4,102,108,111,97,116,95,116,111,95,118,101,99,52,0, -18,117,0,0,18,97,0,0,0,4,118,101,99,52,95,100,105,118,105,100,101,0,18,118,0,0,18,117,0,0,0,0,1,0, -12,2,26,1,0,0,12,118,0,0,1,1,0,12,117,0,0,0,1,4,118,101,99,52,95,97,100,100,0,18,118,0,0,18,117,0, -0,0,8,18,118,0,0,0,1,0,12,2,27,1,0,0,12,118,0,0,1,1,0,12,117,0,0,0,1,4,118,101,99,52,95,115,117,98, -116,114,97,99,116,0,18,118,0,0,18,117,0,0,0,8,18,118,0,0,0,1,0,12,2,21,1,0,0,12,118,0,0,1,1,0,12, -117,0,0,0,1,4,118,101,99,52,95,109,117,108,116,105,112,108,121,0,18,118,0,0,18,117,0,0,0,8,18,118, -0,0,0,1,0,12,2,22,1,0,0,12,118,0,0,1,1,0,12,117,0,0,0,1,4,118,101,99,52,95,100,105,118,105,100,101, -0,18,118,0,0,18,117,0,0,0,8,18,118,0,0,0,1,0,12,2,26,1,1,0,9,97,0,0,1,1,0,12,117,0,0,0,1,3,2,0,12, -1,118,0,0,0,4,102,108,111,97,116,95,116,111,95,118,101,99,52,0,18,118,0,0,18,97,0,0,0,4,118,101,99, -52,95,97,100,100,0,18,118,0,0,18,117,0,0,0,8,18,118,0,0,0,1,0,12,2,26,1,1,0,12,118,0,0,1,1,0,9,98, -0,0,0,1,3,2,0,12,1,117,0,0,0,4,102,108,111,97,116,95,116,111,95,118,101,99,52,0,18,117,0,0,18,98,0, -0,0,4,118,101,99,52,95,97,100,100,0,18,117,0,0,18,118,0,0,0,8,18,117,0,0,0,1,0,12,2,27,1,1,0,9,97, -0,0,1,1,0,12,117,0,0,0,1,3,2,0,12,1,118,0,0,0,4,102,108,111,97,116,95,116,111,95,118,101,99,52,0, -18,118,0,0,18,97,0,0,0,4,118,101,99,52,95,115,117,98,116,114,97,99,116,0,18,118,0,0,18,117,0,0,0,8, -18,118,0,0,0,1,0,12,2,27,1,0,0,12,118,0,0,1,1,0,9,98,0,0,0,1,3,2,0,12,1,117,0,0,0,4,102,108,111,97, -116,95,116,111,95,118,101,99,52,0,18,117,0,0,18,98,0,0,0,4,118,101,99,52,95,115,117,98,116,114,97, -99,116,0,18,118,0,0,18,117,0,0,0,8,18,118,0,0,0,1,0,12,2,21,1,1,0,9,97,0,0,1,1,0,12,117,0,0,0,1,3, -2,0,12,1,118,0,0,0,4,102,108,111,97,116,95,116,111,95,118,101,99,52,0,18,118,0,0,18,97,0,0,0,4,118, -101,99,52,95,109,117,108,116,105,112,108,121,0,18,118,0,0,18,117,0,0,0,8,18,118,0,0,0,1,0,12,2,21, -1,1,0,12,118,0,0,1,1,0,9,98,0,0,0,1,3,2,0,12,1,117,0,0,0,4,102,108,111,97,116,95,116,111,95,118, -101,99,52,0,18,117,0,0,18,98,0,0,0,4,118,101,99,52,95,109,117,108,116,105,112,108,121,0,18,117,0,0, -18,118,0,0,0,8,18,117,0,0,0,1,0,12,2,22,1,1,0,9,97,0,0,1,1,0,12,117,0,0,0,1,3,2,0,12,1,118,0,0,0,4, -102,108,111,97,116,95,116,111,95,118,101,99,52,0,18,118,0,0,18,97,0,0,0,4,118,101,99,52,95,100,105, -118,105,100,101,0,18,118,0,0,18,117,0,0,0,8,18,118,0,0,0,1,0,12,2,22,1,0,0,12,118,0,0,1,1,0,9,98,0, -0,0,1,3,2,0,12,1,117,0,0,0,4,102,108,111,97,116,95,116,111,95,118,101,99,52,0,18,117,0,0,18,98,0,0, -0,4,118,101,99,52,95,100,105,118,105,100,101,0,18,118,0,0,18,117,0,0,0,8,18,118,0,0,0,1,0,12,2,27, -1,0,0,12,118,0,0,0,1,4,118,101,99,52,95,110,101,103,97,116,101,0,18,118,0,0,0,8,18,118,0,0,0,1,0,9, -0,100,111,116,0,1,0,0,11,118,0,0,1,0,0,11,117,0,0,0,1,3,2,0,12,1,118,52,0,2,58,118,101,99,52,0,18, -118,0,0,17,48,0,48,0,0,0,0,0,0,3,2,0,12,1,117,52,0,2,58,118,101,99,52,0,18,117,0,0,17,48,0,48,0,0, -0,0,0,0,4,118,101,99,52,95,100,111,116,0,18,118,52,0,0,18,117,52,0,0,0,8,18,118,52,0,59,120,0,0,0, -1,0,9,0,100,111,116,0,1,0,0,12,118,0,0,1,0,0,12,117,0,0,0,1,4,118,101,99,52,95,100,111,116,0,18, -118,0,0,18,117,0,0,0,8,18,118,0,59,120,0,0,0,1,0,9,0,108,101,110,103,116,104,0,1,0,0,11,118,0,0,0, -1,3,2,0,12,1,117,0,2,58,118,101,99,52,0,18,118,0,0,17,48,0,48,0,0,0,0,0,0,4,118,101,99,52,95,100, -111,116,0,18,117,0,0,18,117,0,0,0,8,58,115,113,114,116,0,18,117,0,59,120,0,0,0,0,0,1,0,9,0,108,101, -110,103,116,104,0,1,0,0,12,118,0,0,0,1,4,118,101,99,52,95,100,111,116,0,18,118,0,0,18,118,0,0,0,8, -58,115,113,114,116,0,18,118,0,59,120,0,0,0,0,0,1,0,11,0,110,111,114,109,97,108,105,122,101,0,1,0,0, -11,118,0,0,0,1,3,2,0,12,1,117,0,2,58,118,101,99,52,0,18,118,0,0,17,48,0,48,0,0,0,0,0,0,3,2,0,12,1, -119,0,2,18,117,0,0,0,4,118,101,99,52,95,100,111,116,0,18,117,0,0,18,117,0,0,0,3,2,0,9,1,108,0,2,58, -115,113,114,116,0,18,117,0,59,120,0,0,0,0,0,4,102,108,111,97,116,95,116,111,95,118,101,99,52,0,18, -117,0,0,18,108,0,0,0,4,118,101,99,52,95,100,105,118,105,100,101,0,18,119,0,0,18,117,0,0,0,8,18,119, -0,59,120,121,122,0,0,0,1,0,12,0,110,111,114,109,97,108,105,122,101,0,1,0,0,12,118,0,0,0,1,3,2,0,12, -1,119,0,2,18,118,0,0,0,4,118,101,99,52,95,100,111,116,0,18,118,0,0,18,118,0,0,0,3,2,0,9,1,108,0,2, -58,115,113,114,116,0,18,118,0,59,120,0,0,0,0,0,4,102,108,111,97,116,95,116,111,95,118,101,99,52,0, -18,118,0,0,18,108,0,0,0,4,118,101,99,52,95,100,105,118,105,100,101,0,18,119,0,0,18,118,0,0,0,8,18, -119,0,0,0,0 diff --git a/src/mesa/shader/slang/library/slang_common_builtin.gc b/src/mesa/shader/slang/library/slang_common_builtin.gc index 768cef5474..42a5d723b4 100755..100644 --- a/src/mesa/shader/slang/library/slang_common_builtin.gc +++ b/src/mesa/shader/slang/library/slang_common_builtin.gc @@ -26,6 +26,8 @@ // From Shader Spec, ver. 1.10, rev. 59 // +//bp: XXX these will probably go away since the value needs to be +//determined at runtime and may vary from one GLcontext to another... const int gl_MaxLights = 8; const int gl_MaxClipPlanes = 6; const int gl_MaxTextureUnits = 8; @@ -45,6 +47,7 @@ uniform mat4 gl_ModelViewProjectionMatrix; uniform mat4 gl_TextureMatrix[gl_MaxTextureCoords]; uniform mat3 gl_NormalMatrix; +uniform mat3 __NormalMatrixTranspose; // Mesa only uniform mat4 gl_ModelViewMatrixInverse; uniform mat4 gl_ProjectionMatrixInverse; @@ -155,128 +158,159 @@ struct gl_FogParameters { uniform gl_FogParameters gl_Fog; + + + + // // 8.1 Angle and Trigonometry Functions // -float radians (float deg) { - return 3.141593 * deg / 180.0; +//// radians + +float radians(const float deg) +{ + const float c = 3.1415926 / 180.0; + __asm vec4_multiply __retVal.x, deg, c; } -vec2 radians (vec2 deg) { - return vec2 (3.141593) * deg / vec2 (180.0); +vec2 radians(const vec2 deg) +{ + const float c = 3.1415926 / 180.0; + __asm vec4_multiply __retVal.xy, deg.xy, c.xx; } -vec3 radians (vec3 deg) { - return vec3 (3.141593) * deg / vec3 (180.0); +vec3 radians(const vec3 deg) +{ + const float c = 3.1415926 / 180.0; + __asm vec4_multiply __retVal.xyz, deg.xyz, c.xxx; } -vec4 radians (vec4 deg) { - return vec4 (3.141593) * deg / vec4 (180.0); +vec4 radians(const vec4 deg) +{ + const float c = 3.1415926 / 180.0; + __asm vec4_multiply __retVal, deg, c.xxxx; } -float degrees (float rad) { - return 180.0 * rad / 3.141593; + +//// degrees + +float degrees(const float rad) +{ + const float c = 180.0 / 3.1415926; + __asm vec4_multiply __retVal.x, rad, c; } -vec2 degrees (vec2 rad) { - return vec2 (180.0) * rad / vec2 (3.141593); +vec2 degrees(const vec2 rad) +{ + const float c = 3.1415926 / 180.0; + __asm vec4_multiply __retVal.xy, rad.xy, c.xx; } -vec3 degrees (vec3 rad) { - return vec3 (180.0) * rad / vec3 (3.141593); +vec3 degrees(const vec3 rad) +{ + const float c = 3.1415926 / 180.0; + __asm vec4_multiply __retVal.xyz, rad.xyz, c.xxx; } -vec4 degrees (vec4 rad) { - return vec4 (180.0) * rad / vec4 (3.141593); +vec4 degrees(const vec4 rad) +{ + const float c = 3.1415926 / 180.0; + __asm vec4_multiply __retVal, rad, c.xxxx; } -float sin (float angle) { - float x; - __asm float_sine x, angle; - return x; + +//// sin + +float sin(const float radians) +{ + __asm float_sine __retVal.x, radians; } -vec2 sin (vec2 angle) { - return vec2 ( - sin (angle.x), - sin (angle.y) - ); +vec2 sin(const vec2 radians) +{ + __asm float_sine __retVal.x, radians.x; + __asm float_sine __retVal.y, radians.y; } -vec3 sin (vec3 angle) { - return vec3 ( - sin (angle.x), - sin (angle.y), - sin (angle.z) - ); +vec3 sin(const vec3 radians) +{ + __asm float_sine __retVal.x, radians.x; + __asm float_sine __retVal.y, radians.y; + __asm float_sine __retVal.z, radians.z; } -vec4 sin (vec4 angle) { - return vec4 ( - sin (angle.x), - sin (angle.y), - sin (angle.z), - sin (angle.w) - ); +vec4 sin(const vec4 radians) +{ + __asm float_sine __retVal.x, radians.x; + __asm float_sine __retVal.y, radians.y; + __asm float_sine __retVal.z, radians.z; + __asm float_sine __retVal.w, radians.w; } -float cos (float angle) { - return sin (angle + 1.5708); + +//// cos + +float cos(const float radians) +{ + __asm float_cosine __retVal.x, radians; } -vec2 cos (vec2 angle) { - return vec2 ( - cos (angle.x), - cos (angle.y) - ); +vec2 cos(const vec2 radians) +{ + __asm float_cosine __retVal.x, radians.x; + __asm float_cosine __retVal.y, radians.y; } -vec3 cos (vec3 angle) { - return vec3 ( - cos (angle.x), - cos (angle.y), - cos (angle.z) - ); +vec3 cos(const vec3 radians) +{ + __asm float_cosine __retVal.x, radians.x; + __asm float_cosine __retVal.y, radians.y; + __asm float_cosine __retVal.z, radians.z; } -vec4 cos (vec4 angle) { - return vec4 ( - cos (angle.x), - cos (angle.y), - cos (angle.z), - cos (angle.w) - ); +vec4 cos(const vec4 radians) +{ + __asm float_cosine __retVal.x, radians.x; + __asm float_cosine __retVal.y, radians.y; + __asm float_cosine __retVal.z, radians.z; + __asm float_cosine __retVal.w, radians.w; } -float tan (float angle) { - return sin (angle) / cos (angle); + + +//// tan + +float tan(const float angle) +{ + const float s = sin(angle); + const float c = cos(angle); + return s / c; } -vec2 tan (vec2 angle) { - return vec2 ( - tan (angle.x), - tan (angle.y) - ); +vec2 tan(const vec2 angle) +{ + const vec2 s = sin(angle); + const vec2 c = cos(angle); + return s / c; } -vec3 tan (vec3 angle) { - return vec3 ( - tan (angle.x), - tan (angle.y), - tan (angle.z) - ); +vec3 tan(const vec3 angle) +{ + const vec3 s = sin(angle); + const vec3 c = cos(angle); + return s / c; } -vec4 tan (vec4 angle) { - return vec4 ( - tan (angle.x), - tan (angle.y), - tan (angle.z), - tan (angle.w) - ); +vec4 tan(const vec4 angle) +{ + const vec4 s = sin(angle); + const vec4 c = cos(angle); + return s / c; } + + float asin (float x) { float y; __asm float_arcsine y, x; @@ -404,675 +438,872 @@ vec4 atan (vec4 u, vec4 v) { // 8.2 Exponential Functions // -float pow (float x, float y) { - float p; - __asm float_power p, x, y; - return p; +//// pow + +float pow(const float a, const float b) +{ + __asm float_power __retVal.x, a, b; } -vec2 pow (vec2 v, vec2 u) { - return vec2 ( - pow (v.x, u.x), - pow (v.y, u.y) - ); +vec2 pow(const vec2 a, const vec2 b) +{ + __asm float_power __retVal.x, a.x, b.x; + __asm float_power __retVal.y, a.y, b.y; } -vec3 pow (vec3 v, vec3 u) { - return vec3 ( - pow (v.x, u.x), - pow (v.y, u.y), - pow (v.z, u.z) - ); +vec3 pow(const vec3 a, const vec3 b) +{ + __asm float_power __retVal.x, a.x, b.x; + __asm float_power __retVal.y, a.y, b.y; + __asm float_power __retVal.z, a.z, b.z; } -vec4 pow (vec4 v, vec4 u) { - return vec4 ( - pow (v.x, u.x), - pow (v.y, u.y), - pow (v.z, u.z), - pow (v.w, u.w) - ); +vec4 pow(const vec4 a, const vec4 b) +{ + __asm float_power __retVal.x, a.x, b.x; + __asm float_power __retVal.y, a.y, b.y; + __asm float_power __retVal.z, a.z, b.z; + __asm float_power __retVal.w, a.w, b.w; } -float exp (float x) { - return pow (2.71828183, x); + +//// exp + +float exp(const float a) +{ + __asm float_exp __retVal.x, a; } -vec2 exp (vec2 v) { - return pow (vec2 (2.71828183), v); +vec2 exp(const vec2 a) +{ + __asm float_exp __retVal.x, a.x; + __asm float_exp __retVal.y, a.y; } -vec3 exp (vec3 v) { - return pow (vec3 (2.71828183), v); +vec3 exp(const vec3 a) +{ + __asm float_exp __retVal.x, a.x; + __asm float_exp __retVal.y, a.y; + __asm float_exp __retVal.z, a.z; } -vec4 exp (vec4 v) { - return pow (vec4 (2.71828183), v); +vec4 exp(const vec4 a) +{ + __asm float_exp __retVal.x, a.x; + __asm float_exp __retVal.y, a.y; + __asm float_exp __retVal.z, a.z; + __asm float_exp __retVal.w, a.w; } -float log2 (float x) { - float y; - __asm float_log2 y, x; - return y; + + +//// log2 + +float log2(const float x) +{ + __asm float_log2 __retVal.x, x; } -vec2 log2 (vec2 v) { - return vec2 ( - log2 (v.x), - log2 (v.y) - ); +vec2 log2(const vec2 v) +{ + __asm float_log2 __retVal.x, v.x; + __asm float_log2 __retVal.y, v.y; } -vec3 log2 (vec3 v) { - return vec3 ( - log2 (v.x), - log2 (v.y), - log2 (v.z) - ); +vec3 log2(const vec3 v) +{ + __asm float_log2 __retVal.x, v.x; + __asm float_log2 __retVal.y, v.y; + __asm float_log2 __retVal.z, v.z; } -vec4 log2 (vec4 v) { - return vec4 ( - log2 (v.x), - log2 (v.y), - log2 (v.z), - log2 (v.w) - ); +vec4 log2(const vec4 v) +{ + __asm float_log2 __retVal.x, v.x; + __asm float_log2 __retVal.y, v.y; + __asm float_log2 __retVal.z, v.z; + __asm float_log2 __retVal.w, v.w; } -float log (float x) { - return log2 (x) / log2 (2.71828183); + +//// log (natural log) + +float log(const float x) +{ + // note: logBaseB(x) = logBaseN(x) / logBaseN(B) + // compute log(x) = log2(x) / log2(e) + // c = 1.0 / log2(e) = 0.693147181 + const float c = 0.693147181; + return log2(x) * c; } -vec2 log (vec2 v) { - return log2 (v) / log2 (vec2 (2.71828183)); +vec2 log(const vec2 v) +{ + const float c = 0.693147181; + return log2(v) * c; } -vec3 log (vec3 v) { - return log2 (v) / log2 (vec3 (2.71828183)); +vec3 log(const vec3 v) +{ + const float c = 0.693147181; + return log2(v) * c; } -vec4 log (vec4 v) { - return log2 (v) / log2 (vec4 (2.71828183)); +vec4 log(const vec4 v) +{ + const float c = 0.693147181; + return log2(v) * c; } -float exp2 (float x) { - return pow (2.0, x); + +//// exp2 + +float exp2(const float a) +{ + __asm float_exp2 __retVal.x, a; } -vec2 exp2 (vec2 v) { - return pow (vec2 (2.0), v); +vec2 exp2(const vec2 a) +{ + __asm float_exp2 __retVal.x, a.x; + __asm float_exp2 __retVal.y, a.y; } -vec3 exp2 (vec3 v) { - return pow (vec3 (2.0), v); +vec3 exp2(const vec3 a) +{ + __asm float_exp2 __retVal.x, a.x; + __asm float_exp2 __retVal.y, a.y; + __asm float_exp2 __retVal.z, a.z; } -vec4 exp2 (vec4 v) { - return pow (vec4 (2.0), v); +vec4 exp2(const vec4 a) +{ + __asm float_exp2 __retVal.x, a.x; + __asm float_exp2 __retVal.y, a.y; + __asm float_exp2 __retVal.z, a.z; + __asm float_exp2 __retVal.w, a.w; } -float sqrt (float x) { - return pow (x, 0.5); + +//// sqrt + +float sqrt(const float x) +{ + float r; + __asm float_rsq r, x; + __asm float_rcp __retVal.x, r; } -vec2 sqrt (vec2 v) { - return pow (v, vec2 (0.5)); +vec2 sqrt(const vec2 v) +{ + float r; + __asm float_rsq r, v.x; + __asm float_rcp __retVal.x, r; + __asm float_rsq r, v.y; + __asm float_rcp __retVal.y, r; } -vec3 sqrt (vec3 v) { - return pow (v, vec3 (0.5)); +vec3 sqrt(const vec3 v) +{ + float r; + __asm float_rsq r, v.x; + __asm float_rcp __retVal.x, r; + __asm float_rsq r, v.y; + __asm float_rcp __retVal.y, r; + __asm float_rsq r, v.z; + __asm float_rcp __retVal.z, r; } -vec4 sqrt (vec4 v) { - return pow (v, vec4 (0.5)); +vec4 sqrt(const vec4 v) +{ + float r; + __asm float_rsq r, v.x; + __asm float_rcp __retVal.x, r; + __asm float_rsq r, v.y; + __asm float_rcp __retVal.y, r; + __asm float_rsq r, v.z; + __asm float_rcp __retVal.z, r; + __asm float_rsq r, v.w; + __asm float_rcp __retVal.w, r; } -float inversesqrt (float x) { - return 1.0 / sqrt (x); + +//// inversesqrt + +float inversesqrt(const float x) +{ + __asm float_rsq __retVal.x, x; +} + +vec2 inversesqrt(const vec2 v) +{ + __asm float_rsq __retVal.x, v.x; + __asm float_rsq __retVal.y, v.y; } -vec2 inversesqrt (vec2 v) { - return vec2 (1.0) / sqrt (v); +vec3 inversesqrt(const vec3 v) +{ + __asm float_rsq __retVal.x, v.x; + __asm float_rsq __retVal.y, v.y; + __asm float_rsq __retVal.z, v.z; } -vec3 inversesqrt (vec3 v) { - return vec3 (1.0) / sqrt (v); +vec4 inversesqrt(const vec4 v) +{ + __asm float_rsq __retVal.x, v.x; + __asm float_rsq __retVal.y, v.y; + __asm float_rsq __retVal.z, v.z; + __asm float_rsq __retVal.w, v.w; +} + + +//// normalize + +float normalize(const float x) +{ + __retVal.x = 1.0; } -vec4 inversesqrt (vec4 v) { - return vec4 (1.0) / sqrt (v); +vec2 normalize(const vec2 v) +{ + const float s = inversesqrt(dot(v, v)); + __asm vec4_multiply __retVal.xy, v, s.xx; } +vec3 normalize(const vec3 v) +{ +// const float s = inversesqrt(dot(v, v)); +// __retVal = v * s; +// XXX note, we _could_ use __retVal.w instead of tmp and and save a +// register, but that's actually a compilation error because v is a vec3 +// and the .w suffix is illegal. Oh well. + float tmp; + __asm vec3_dot tmp, v, v; + __asm float_rsq tmp, tmp; + __asm vec4_multiply __retVal.xyz, v, tmp.xxx; +} + +vec4 normalize(const vec4 v) +{ + float tmp; + __asm vec4_dot tmp, v, v; + __asm float_rsq tmp, tmp; + __asm vec4_multiply __retVal.xyz, v, tmp.xxx; +} + + + // // 8.3 Common Functions // -float abs (float x) { - return x >= 0.0 ? x : -x; + +//// abs + +float abs(const float a) +{ + __asm vec4_abs __retVal.x, a; } -vec2 abs (vec2 v) { - return vec2 ( - abs (v.x), - abs (v.y) - ); +vec2 abs(const vec2 a) +{ + __asm vec4_abs __retVal.xy, a; } -vec3 abs (vec3 v) { - return vec3 ( - abs (v.x), - abs (v.y), - abs (v.z) - ); +vec3 abs(const vec3 a) +{ + __asm vec4_abs __retVal.xyz, a; } -vec4 abs (vec4 v) { - return vec4 ( - abs (v.x), - abs (v.y), - abs (v.z), - abs (v.w) - ); +vec4 abs(const vec4 a) +{ + __asm vec4_abs __retVal, a; } -float sign (float x) { - return x > 0.0 ? 1.0 : x < 0.0 ? -1.0 : 0.0; + +//// sign + +float sign(const float x) +{ + float p, n; + __asm vec4_sgt p.x, x, 0.0; // p = (x > 0) + __asm vec4_sgt n.x, 0.0, x; // n = (x < 0) + __asm vec4_subtract __retVal.x, p, n; // sign = p - n } -vec2 sign (vec2 v) { - return vec2 ( - sign (v.x), - sign (v.y) - ); +vec2 sign(const vec2 v) +{ + vec2 p, n; + __asm vec4_sgt p.xy, v, 0.0; + __asm vec4_sgt n.xy, 0.0, v; + __asm vec4_subtract __retVal.xy, p, n; } -vec3 sign (vec3 v) { - return vec3 ( - sign (v.x), - sign (v.y), - sign (v.z) - ); +vec3 sign(const vec3 v) +{ + vec3 p, n; + __asm vec4_sgt p.xyz, v, 0.0; + __asm vec4_sgt n.xyz, 0.0, v; + __asm vec4_subtract __retVal.xyz, p, n; } -vec4 sign (vec4 v) { - return vec4 ( - sign (v.x), - sign (v.y), - sign (v.z), - sign (v.w) - ); +vec4 sign(const vec4 v) +{ + vec4 p, n; + __asm vec4_sgt p, v, 0.0; + __asm vec4_sgt n, 0.0, v; + __asm vec4_subtract __retVal, p, n; } -float floor (float x) { - float y; - __asm float_floor y, x; - return y; + +//// floor + +float floor(const float a) +{ + __asm vec4_floor __retVal.x, a; } -vec2 floor (vec2 v) { - return vec2 ( - floor (v.x), - floor (v.y) - ); +vec2 floor(const vec2 a) +{ + __asm vec4_floor __retVal.xy, a; } -vec3 floor (vec3 v) { - return vec3 ( - floor (v.x), - floor (v.y), - floor (v.z) - ); +vec3 floor(const vec3 a) +{ + __asm vec4_floor __retVal.xyz, a; } -vec4 floor (vec4 v) { - return vec4 ( - floor (v.x), - floor (v.y), - floor (v.z), - floor (v.w) - ); +vec4 floor(const vec4 a) +{ + __asm vec4_floor __retVal, a; } -float ceil (float x) { - float y; - __asm float_ceil y, x; - return y; + +//// ceil + +float ceil(const float a) +{ + // XXX this could be improved + float b = -a; + __asm vec4_floor b, b; + __retVal.x = -b; } -vec2 ceil (vec2 v) { - return vec2 ( - ceil (v.x), - ceil (v.y) - ); +vec2 ceil(const vec2 a) +{ + vec2 b = -a; + __asm vec4_floor b, b; + __retVal.xy = -b; } -vec3 ceil (vec3 v) { - return vec3 ( - ceil (v.x), - ceil (v.y), - ceil (v.z) - ); +vec3 ceil(const vec3 a) +{ + vec3 b = -a; + __asm vec4_floor b, b; + __retVal.xyz = -b; } -vec4 ceil (vec4 v) { - return vec4 ( - ceil (v.x), - ceil (v.y), - ceil (v.z), - ceil (v.w) - ); +vec4 ceil(const vec4 a) +{ + vec4 b = -a; + __asm vec4_floor b, b; + __retVal = -b; } -float fract (float x) { - return x - floor (x); + +//// fract + +float fract(const float a) +{ + __asm vec4_frac __retVal.x, a; } -vec2 fract (vec2 v) { - return v - floor (v); +vec2 fract(const vec2 a) +{ + __asm vec4_frac __retVal.xy, a; } -vec3 fract (vec3 v) { - return v - floor (v); +vec3 fract(const vec3 a) +{ + __asm vec4_frac __retVal.xyz, a; } -vec4 fract (vec4 v) { - return v - floor (v); +vec4 fract(const vec4 a) +{ + __asm vec4_frac __retVal, a; } -float mod (float x, float y) { - return x - y * floor (x / y); + +//// mod (very untested!) + +float mod(const float a, const float b) +{ + float oneOverB; + __asm float_rcp oneOverB, b; + __retVal.x = a - b * floor(a * oneOverB); } -vec2 mod (vec2 v, float u) { - return v - u * floor (v / u); +vec2 mod(const vec2 a, const float b) +{ + float oneOverB; + __asm float_rcp oneOverB, b; + __retVal.xy = a - b * floor(a * oneOverB); } -vec3 mod (vec3 v, float u) { - return v - u * floor (v / u); +vec3 mod(const vec3 a, const float b) +{ + float oneOverB; + __asm float_rcp oneOverB, b; + __retVal.xyz = a - b * floor(a * oneOverB); } -vec4 mod (vec4 v, float u) { - return v - u * floor (v / u); +vec4 mod(const vec4 a, const float b) +{ + float oneOverB; + __asm float_rcp oneOverB, b; + __retVal = a - b * floor(a * oneOverB); } -vec2 mod (vec2 v, vec2 u) { - return v - u * floor (v / u); +vec2 mod(const vec2 a, const vec2 b) +{ + float oneOverBx, oneOverBy; + __asm float_rcp oneOverBx, b.x; + __asm float_rcp oneOverBy, b.y; + __retVal.x = a.x - b.x * floor(a.x * oneOverBx); + __retVal.y = a.y - b.y * floor(a.y * oneOverBy); } -vec3 mod (vec3 v, vec3 u) { - return v - u * floor (v / u); +vec3 mod(const vec3 a, const vec3 b) +{ + float oneOverBx, oneOverBy, oneOverBz; + __asm float_rcp oneOverBx, b.x; + __asm float_rcp oneOverBy, b.y; + __asm float_rcp oneOverBz, b.z; + __retVal.x = a.x - b.x * floor(a.x * oneOverBx); + __retVal.y = a.y - b.y * floor(a.y * oneOverBy); + __retVal.z = a.z - b.z * floor(a.z * oneOverBz); } -vec4 mod (vec4 v, vec4 u) { - return v - u * floor (v / u); +vec4 mod(const vec4 a, const vec4 b) +{ + float oneOverBx, oneOverBy, oneOverBz, oneOverBw; + __asm float_rcp oneOverBx, b.x; + __asm float_rcp oneOverBy, b.y; + __asm float_rcp oneOverBz, b.z; + __asm float_rcp oneOverBw, b.w; + __retVal.x = a.x - b.x * floor(a.x * oneOverBx); + __retVal.y = a.y - b.y * floor(a.y * oneOverBy); + __retVal.z = a.z - b.z * floor(a.z * oneOverBz); + __retVal.w = a.w - b.w * floor(a.w * oneOverBz); } -float min (float x, float y) { - return x < y ? x : y; + +//// min + +float min(const float a, const float b) +{ + __asm vec4_min __retVal.x, a.x, b.x; } -vec2 min (vec2 v, vec2 u) { - return vec2 ( - min (v.x, u.x), - min (v.y, u.y) - ); +vec2 min(const vec2 a, const vec2 b) +{ + __asm vec4_min __retVal.xy, a.xy, b.xy; } -vec3 min (vec3 v, vec3 u) { - return vec3 ( - min (v.x, u.x), - min (v.y, u.y), - min (v.z, u.z) - ); +vec3 min(const vec3 a, const vec3 b) +{ + __asm vec4_min __retVal.xyz, a.xyz, b.xyz; } -vec4 min (vec4 v, vec4 u) { - return vec4 ( - min (v.x, u.x), - min (v.y, u.y), - min (v.z, u.z), - min (v.w, u.w) - ); +vec4 min(const vec4 a, const vec4 b) +{ + __asm vec4_min __retVal, a, b; } -vec2 min (vec2 v, float y) { - return min (v, vec2 (y)); +vec2 min(const vec2 a, const float b) +{ + __asm vec4_min __retVal, a.xy, b.xx; } -vec3 min (vec3 v, float y) { - return min (v, vec3 (y)); +vec3 min(const vec3 a, const float b) +{ + __asm vec4_min __retVal, a.xyz, b.xxx; } -vec4 min (vec4 v, float y) { - return min (v, vec4 (y)); +vec4 min(const vec4 a, const float b) +{ + __asm vec4_min __retVal, a, b.xxxx; } -float max (float x, float y) { - return x < y ? y : x; + +//// max + +float max(const float a, const float b) +{ + __asm vec4_max __retVal.x, a.x, b.x; } -vec2 max (vec2 v, vec2 u) { - return vec2 ( - max (v.x, u.x), - max (v.y, u.y) - ); +vec2 max(const vec2 a, const vec2 b) +{ + __asm vec4_max __retVal.xy, a.xy, b.xy; } -vec3 max (vec3 v, vec3 u) { - return vec3 ( - max (v.x, u.x), - max (v.y, u.y), - max (v.z, u.z) - ); +vec3 max(const vec3 a, const vec3 b) +{ + __asm vec4_max __retVal.xyz, a.xyz, b.xyz; } -vec4 max (vec4 v, vec4 u) { - return vec4 ( - max (v.x, u.x), - max (v.y, u.y), - max (v.z, u.z), - max (v.w, u.w) - ); +vec4 max(const vec4 a, const vec4 b) +{ + __asm vec4_max __retVal, a, b; } -vec2 max (vec2 v, float y) { - return max (v, vec2 (y)); +vec2 max(const vec2 a, const float b) +{ + __asm vec4_max __retVal, a.xy, b.xx; } -vec3 max (vec3 v, float y) { - return max (v, vec3 (y)); +vec3 max(const vec3 a, const float b) +{ + __asm vec4_max __retVal, a.xyz, b.xxx; } -vec4 max (vec4 v, float y) { - return max (v, vec4 (y)); +vec4 max(const vec4 a, const float b) +{ + __asm vec4_max __retVal, a, b.xxxx; } -float clamp (float x, float minVal, float maxVal) { - return min (max (x, minVal), maxVal); + +//// clamp + +float clamp(const float val, const float minVal, const float maxVal) +{ + __asm vec4_clamp __retVal, val, minVal, maxVal; } -vec2 clamp (vec2 x, float minVal, float maxVal) { - return min (max (x, minVal), maxVal); +vec2 clamp(const vec2 val, const float minVal, const float maxVal) +{ + __asm vec4_clamp __retVal, val, minVal, maxVal; } -vec3 clamp (vec3 x, float minVal, float maxVal) { - return min (max (x, minVal), maxVal); +vec3 clamp(const vec3 val, const float minVal, const float maxVal) +{ + __asm vec4_clamp __retVal, val, minVal, maxVal; } -vec4 clamp (vec4 x, float minVal, float maxVal) { - return min (max (x, minVal), maxVal); +vec4 clamp(const vec4 val, const float minVal, const float maxVal) +{ + __asm vec4_clamp __retVal, val, minVal, maxVal; } -vec2 clamp (vec2 x, vec2 minVal, vec2 maxVal) { - return min (max (x, minVal), maxVal); +vec2 clamp(const vec2 val, const vec2 minVal, const vec2 maxVal) +{ + __asm vec4_clamp __retVal, val, minVal, maxVal; } -vec3 clamp (vec3 x, vec3 minVal, vec3 maxVal) { - return min (max (x, minVal), maxVal); +vec3 clamp(const vec3 val, const vec3 minVal, const vec3 maxVal) +{ + __asm vec4_clamp __retVal, val, minVal, maxVal; } -vec4 clamp (vec4 x, vec4 minVal, vec4 maxVal) { - return min (max (x, minVal), maxVal); +vec4 clamp(const vec4 val, const vec4 minVal, const vec4 maxVal) +{ + __asm vec4_clamp __retVal, val, minVal, maxVal; } -float mix (float x, float y, float a) { - return x * (1.0 - a) + y * a; + +//// mix + +float mix(const float x, const float y, const float a) +{ + __asm vec4_lrp __retVal, a, y, x; } -vec2 mix (vec2 x, vec2 y, float a) { - return x * (1.0 - a) + y * a; +vec2 mix(const vec2 x, const vec2 y, const float a) +{ + __asm vec4_lrp __retVal, a, y, x; } -vec3 mix (vec3 x, vec3 y, float a) { - return x * (1.0 - a) + y * a; +vec3 mix(const vec3 x, const vec3 y, const float a) +{ + __asm vec4_lrp __retVal, a, y, x; } -vec4 mix (vec4 x, vec4 y, float a) { - return x * (1.0 - a) + y * a; +vec4 mix(const vec4 x, const vec4 y, const float a) +{ + __asm vec4_lrp __retVal, a, y, x; } -vec2 mix (vec2 x, vec2 y, vec2 a) { - return x * (1.0 - a) + y * a; +vec2 mix(const vec2 x, const vec2 y, const vec2 a) +{ + __asm vec4_lrp __retVal, a, y, x; } -vec3 mix (vec3 x, vec3 y, vec3 a) { - return x * (1.0 - a) + y * a; +vec3 mix(const vec3 x, const vec3 y, const vec3 a) +{ + __asm vec4_lrp __retVal, a, y, x; } -vec4 mix (vec4 x, vec4 y, vec4 a) { - return x * (1.0 - a) + y * a; +vec4 mix(const vec4 x, const vec4 y, const vec4 a) +{ + __asm vec4_lrp __retVal, a, y, x; } -float step (float edge, float x) { - return x < edge ? 0.0 : 1.0; + +//// step (untested) + +float step(const float edge, const float x) +{ + __asm vec4_sgt __retVal.x, x, edge; } -vec2 step (vec2 edge, vec2 v) { - return vec2 ( - step (edge.x, v.x), - step (edge.y, v.y) - ); +vec2 step(const vec2 edge, const vec2 x) +{ + __asm vec4_sgt __retVal.xy, x, edge; } -vec3 step (vec3 edge, vec3 v) { - return vec3 ( - step (edge.x, v.x), - step (edge.y, v.y), - step (edge.z, v.z) - ); +vec3 step(const vec3 edge, const vec3 x) +{ + __asm vec4_sgt __retVal.xyz, x, edge; } -vec4 step (vec4 edge, vec4 v) { - return vec4 ( - step (edge.x, v.x), - step (edge.y, v.y), - step (edge.z, v.z), - step (edge.w, v.w) - ); +vec4 step(const vec4 edge, const vec4 x) +{ + __asm vec4_sgt __retVal, x, edge; } -vec2 step (float edge, vec2 v) { - return step (vec2 (edge), v); +vec2 step(const float edge, const vec2 v) +{ + __asm vec4_sgt __retVal.xy, v, edge.xx; } -vec3 step (float edge, vec3 v) { - return step (vec3 (edge), v); +vec3 step(const float edge, const vec3 v) +{ + __asm vec4_sgt __retVal.xyz, v, edge.xxx; } -vec4 step (float edge, vec4 v) { - return step (vec4 (edge), v); +vec4 step(const float edge, const vec4 v) +{ + __asm vec4_sgt __retVal, v, edge.xxxx; } -float smoothstep (float edge0, float edge1, float x) { - float t = clamp ((x - edge0) / (edge1 - edge0), 0.0, 1.0); + +//// smoothstep (untested) + +float smoothstep(const float edge0, const float edge1, const float x) +{ + float t = clamp((x - edge0) / (edge1 - edge0), 0.0, 1.0); return t * t * (3.0 - 2.0 * t); } -vec2 smoothstep (vec2 edge0, vec2 edge1, vec2 v) { - return vec2 ( - smoothstep (edge0.x, edge1.x, v.x), - smoothstep (edge0.y, edge1.y, v.y) - ); +vec2 smoothstep(const vec2 edge0, const vec2 edge1, const vec2 v) +{ + vec2 t = clamp((v - edge0) / (edge1 - edge0), 0.0, 1.0); + return t * t * (3.0 - 2.0 * t); } -vec3 smoothstep (vec3 edge0, vec3 edge1, vec3 v) { - return vec3 ( - smoothstep (edge0.x, edge1.x, v.x), - smoothstep (edge0.y, edge1.y, v.y), - smoothstep (edge0.z, edge1.z, v.z) - ); +vec3 smoothstep(const vec3 edge0, const vec3 edge1, const vec3 v) +{ + vec3 t = clamp((v - edge0) / (edge1 - edge0), 0.0, 1.0); + return t * t * (3.0 - 2.0 * t); } -vec4 smoothstep (vec4 edge0, vec4 edge1, vec4 v) { - return vec4 ( - smoothstep (edge0.x, edge1.x, v.x), - smoothstep (edge0.y, edge1.y, v.y), - smoothstep (edge0.z, edge1.z, v.z), - smoothstep (edge0.w, edge1.w, v.w) - ); +vec4 smoothstep(const vec4 edge0, const vec4 edge1, const vec4 v) +{ + vec4 t = clamp((v - edge0) / (edge1 - edge0), 0.0, 1.0); + return t * t * (3.0 - 2.0 * t); } -vec2 smoothstep (float edge0, float edge1, vec2 v) { - return vec2 ( - smoothstep (edge0, edge1, v.x), - smoothstep (edge0, edge1, v.y) - ); +vec2 smoothstep(const float edge0, const float edge1, const vec2 v) +{ + vec2 t = clamp((v - edge0) / (edge1 - edge0), 0.0, 1.0); + return t * t * (3.0 - 2.0 * t); } -vec3 smoothstep (float edge0, float edge1, vec3 v) { - return vec3 ( - smoothstep (edge0, edge1, v.x), - smoothstep (edge0, edge1, v.y), - smoothstep (edge0, edge1, v.z) - ); +vec3 smoothstep(const float edge0, const float edge1, const vec3 v) +{ + vec3 t = clamp((v - edge0) / (edge1 - edge0), 0.0, 1.0); + return t * t * (3.0 - 2.0 * t); } -vec4 smoothstep (float edge0, float edge1, vec4 v) { - return vec4 ( - smoothstep (edge0, edge1, v.x), - smoothstep (edge0, edge1, v.y), - smoothstep (edge0, edge1, v.z), - smoothstep (edge0, edge1, v.w) - ); +vec4 smoothstep(const float edge0, const float edge1, const vec4 v) +{ + vec4 t = clamp((v - edge0) / (edge1 - edge0), 0.0, 1.0); + return t * t * (3.0 - 2.0 * t); } + + // // 8.4 Geometric Functions // -float dot (float x, float y) { - return x * y; -} -float dot (vec2 v, vec2 u) { - return v.x * u.x + v.y * u.y; -} +//// length -float dot (vec3 v, vec3 u) { - return v.x * u.x + v.y * u.y + v.z * u.z; +float length(const float x) +{ + return abs(x); } -float dot (vec4 v, vec4 u) { - return v.x * u.x + v.y * u.y + v.z * u.z + v.w * u.w; +float length(const vec2 v) +{ + float r; + const float p = dot(v, v); // p = v.x * v.x + v.y * v.y + __asm float_rsq r, p; // r = 1 / sqrt(p) + __asm float_rcp __retVal.x, r; // retVal = 1 / r } -float length (float x) { - return sqrt (dot (x, x)); +float length(const vec3 v) +{ + float r; + const float p = dot(v, v); // p = v.x * v.x + v.y * v.y + v.z * v.z + __asm float_rsq r, p; // r = 1 / sqrt(p) + __asm float_rcp __retVal.x, r; // retVal = 1 / r } -float length (vec2 v) { - return sqrt (dot (v, v)); +float length(const vec4 v) +{ + float r; + const float p = dot(v, v); // p = v.x * v.x + v.y * v.y + ... + __asm float_rsq r, p; // r = 1 / sqrt(p) + __asm float_rcp __retVal.x, r; // retVal = 1 / r } -float length (vec3 v) { - return sqrt (dot (v, v)); -} -float length (vec4 v) { - return sqrt (dot (v, v)); -} +//// distance -float distance (float x, float y) { - return length (x - y); +float distance(const float x, const float y) +{ + const float d = x - y; + __retVal = length(d); } -float distance (vec2 v, vec2 u) { - return length (v - u); +float distance(const vec2 v, const vec2 u) +{ + const vec2 d2 = v - u; + __retVal = length(d2); } -float distance (vec3 v, vec3 u) { - return length (v - u); +float distance(const vec3 v, const vec3 u) +{ + const vec3 d3 = v - u; + __retVal = length(d3); } -float distance (vec4 v, vec4 u) { - return length (v - u); +float distance(const vec4 v, const vec4 u) +{ + const vec4 d4 = v - u; + __retVal = length(d4); } -vec3 cross (vec3 v, vec3 u) { - return vec3 ( - v.y * u.z - u.y * v.z, - v.z * u.x - u.z * v.x, - v.x * u.y - u.x * v.y - ); -} -float normalize (float x) { - return 1.0; -} +//// cross -vec2 normalize (vec2 v) { - return v / length (v); +vec3 cross(const vec3 v, const vec3 u) +{ + __asm vec3_cross __retVal.xyz, v, u; } -vec3 normalize (vec3 v) { - return v / length (v); -} -vec4 normalize (vec4 v) { - return v / length (v); -} +//// faceforward -float faceforward (float N, float I, float Nref) { - return dot (Nref, I) < 0.0 ? N : -N; +float faceforward(const float N, const float I, const float Nref) +{ + // this could probably be done better + const float d = dot(Nref, I); + float s; + __asm vec4_sgt s.x, 0.0, d; // s = (0.0 > d) ? 1 : 0 + return mix(-N, N, s); } -vec2 faceforward (vec2 N, vec2 I, vec2 Nref) { - return dot (Nref, I) < 0.0 ? N : -N; +vec2 faceforward(const vec2 N, const vec2 I, const vec2 Nref) +{ + // this could probably be done better + const float d = dot(Nref, I); + float s; + __asm vec4_sgt s.x, 0.0, d; // s = (0.0 > d) ? 1 : 0 + return mix(-N, N, s); } -vec3 faceforward (vec3 N, vec3 I, vec3 Nref) { - return dot (Nref, I) < 0.0 ? N : -N; +vec3 faceforward(const vec3 N, const vec3 I, const vec3 Nref) +{ + // this could probably be done better + const float d = dot(Nref, I); + float s; + __asm vec4_sgt s.x, 0.0, d; // s = (0.0 > d) ? 1 : 0 + return mix(-N, N, s); } -vec4 faceforward (vec4 N, vec4 I, vec4 Nref) { - return dot (Nref, I) < 0.0 ? N : -N; +vec4 faceforward(const vec4 N, const vec4 I, const vec4 Nref) +{ + // this could probably be done better + const float d = dot(Nref, I); + float s; + __asm vec4_sgt s.x, 0.0, d; // s = (0.0 > d) ? 1 : 0 + return mix(-N, N, s); } -float reflect (float I, float N) { - return I - 2.0 * dot (N, I) * N; + +//// reflect + +float reflect(const float I, const float N) +{ + return I - 2.0 * dot(N, I) * N; } -vec2 reflect (vec2 I, vec2 N) { - return I - 2.0 * dot (N, I) * N; +vec2 reflect(const vec2 I, const vec2 N) +{ + return I - 2.0 * dot(N, I) * N; } -vec3 reflect (vec3 I, vec3 N) { - return I - 2.0 * dot (N, I) * N; +vec3 reflect(const vec3 I, const vec3 N) +{ + return I - 2.0 * dot(N, I) * N; } -vec4 reflect (vec4 I, vec4 N) { - return I - 2.0 * dot (N, I) * N; +vec4 reflect(const vec4 I, const vec4 N) +{ + return I - 2.0 * dot(N, I) * N; } -float refract (float I, float N, float eta) { - float k = 1.0 - eta * eta * (1.0 - dot (N, I) * dot (N, I)); - if (k < 0.0) - return 0.0; - return eta * I - (eta * dot (N, I) + sqrt (k)) * N; +//// refract + +float refract(const float I, const float N, const float eta) +{ + float k = 1.0 - eta * eta * (1.0 - dot(N, I) * dot(N, I)); + if (k < 0.0) + return 0.0; + return eta * I - (eta * dot(N, I) + sqrt(k)) * N; } -vec2 refract (vec2 I, vec2 N, float eta) { - float k = 1.0 - eta * eta * (1.0 - dot (N, I) * dot (N, I)); - if (k < 0.0) - return 0.0; - return eta * I - (eta * dot (N, I) + sqrt (k)) * N; +vec2 refract(const vec2 I, const vec2 N, const float eta) +{ + float k = 1.0 - eta * eta * (1.0 - dot(N, I) * dot(N, I)); + if (k < 0.0) + return 0.0; + return eta * I - (eta * dot(N, I) + sqrt(k)) * N; } -vec3 refract (vec3 I, vec3 N, float eta) { - float k = 1.0 - eta * eta * (1.0 - dot (N, I) * dot (N, I)); - if (k < 0.0) - return 0.0; - return eta * I - (eta * dot (N, I) + sqrt (k)) * N; +vec3 refract(const vec3 I, const vec3 N, const float eta) +{ + float k = 1.0 - eta * eta * (1.0 - dot(N, I) * dot(N, I)); + if (k < 0.0) + return 0.0; + return eta * I - (eta * dot(N, I) + sqrt(k)) * N; } -vec4 refract (vec4 I, vec4 N, float eta) { - float k = 1.0 - eta * eta * (1.0 - dot (N, I) * dot (N, I)); - if (k < 0.0) - return 0.0; - return eta * I - (eta * dot (N, I) + sqrt (k)) * N; +vec4 refract(const vec4 I, const vec4 N, const float eta) +{ + float k = 1.0 - eta * eta * (1.0 - dot(N, I) * dot(N, I)); + if (k < 0.0) + return 0.0; + return eta * I - (eta * dot(N, I) + sqrt(k)) * N; } + + + // // 8.5 Matrix Functions // @@ -1089,238 +1320,346 @@ mat4 matrixCompMult (mat4 m, mat4 n) { return mat4 (m[0] * n[0], m[1] * n[1], m[2] * n[2], m[3] * n[3]); } + + + // // 8.6 Vector Relational Functions // -bvec2 lessThan (vec2 v, vec2 u) { - return bvec2 (v.x < u.x, v.y < u.y); +//// lessThan + +bvec2 lessThan(const vec2 u, const vec2 v) +{ + __asm vec4_slt __retVal.xy, u, v; } -bvec3 lessThan (vec3 v, vec3 u) { - return bvec3 (v.x < u.x, v.y < u.y, v.z < u.z); +bvec3 lessThan(const vec3 u, const vec3 v) +{ + __asm vec4_slt __retVal.xyz, u, v; } -bvec4 lessThan (vec4 v, vec4 u) { - return bvec4 (v.x < u.x, v.y < u.y, v.z < u.z, v.w < u.w); +bvec4 lessThan(const vec4 u, const vec4 v) +{ + __asm vec4_slt __retVal, u, v; } -bvec2 lessThan (ivec2 v, ivec2 u) { - return bvec2 (v.x < u.x, v.y < u.y); +bvec2 lessThan(const ivec2 u, const ivec2 v) +{ + __asm vec4_slt __retVal.xy, u, v; } -bvec3 lessThan (ivec3 v, ivec3 u) { - return bvec3 (v.x < u.x, v.y < u.y, v.z < u.z); +bvec3 lessThan(const ivec3 u, const ivec3 v) +{ + __asm vec4_slt __retVal.xyz, u, v; } -bvec4 lessThan (ivec4 v, ivec4 u) { - return bvec4 (v.x < u.x, v.y < u.y, v.z < u.z, v.w < u.w); +bvec4 lessThan(const ivec4 u, const ivec4 v) +{ + __asm vec4_slt __retVal, u, v; } -bvec2 lessThanEqual (vec2 v, vec2 u) { - return bvec2 (v.x <= u.x, v.y <= u.y); + +//// lessThanEqual + +bvec2 lessThanEqual(const vec2 u, const vec2 v) +{ + __asm vec4_sle __retVal.xy, u, v; } -bvec3 lessThanEqual (vec3 v, vec3 u) { - return bvec3 (v.x <= u.x, v.y <= u.y, v.z <= u.z); +bvec3 lessThanEqual(const vec3 u, const vec3 v) +{ + __asm vec4_sle __retVal.xyz, u, v; } -bvec4 lessThanEqual (vec4 v, vec4 u) { - return bvec4 (v.x <= u.x, v.y <= u.y, v.z <= u.z, v.w <= u.w); +bvec4 lessThanEqual(const vec4 u, const vec4 v) +{ + __asm vec4_sle __retVal, u, v; } -bvec2 lessThanEqual (ivec2 v, ivec2 u) { - return bvec2 (v.x <= u.x, v.y <= u.y); +bvec2 lessThanEqual(const ivec2 u, const ivec2 v) +{ + __asm vec4_sle __retVal.xy, u, v; } -bvec3 lessThanEqual (ivec3 v, ivec3 u) { - return bvec3 (v.x <= u.x, v.y <= u.y, v.z <= u.z); +bvec3 lessThanEqual(const ivec3 u, const ivec3 v) +{ + __asm vec4_sle __retVal.xyz, u, v; } -bvec4 lessThanEqual (ivec4 v, ivec4 u) { - return bvec4 (v.x <= u.x, v.y <= u.y, v.z <= u.z, v.w <= u.w); +bvec4 lessThanEqual(const ivec4 u, const ivec4 v) +{ + __asm vec4_sle __retVal, u, v; } -bvec2 greaterThan (vec2 v, vec2 u) { - return bvec2 (v.x > u.x, v.y > u.y); + +//// greaterThan + +bvec2 greaterThan(const vec2 u, const vec2 v) +{ + __asm vec4_sgt __retVal.xy, u, v; } -bvec3 greaterThan (vec3 v, vec3 u) { - return bvec3 (v.x > u.x, v.y > u.y, v.z > u.z); +bvec3 greaterThan(const vec3 u, const vec3 v) +{ + __asm vec4_sgt __retVal.xyz, u, v; } -bvec4 greaterThan (vec4 v, vec4 u) { - return bvec4 (v.x > u.x, v.y > u.y, v.z > u.z, v.w > u.w); +bvec4 greaterThan(const vec4 u, const vec4 v) +{ + __asm vec4_sgt __retVal, u, v; } -bvec2 greaterThan (ivec2 v, ivec2 u) { - return bvec2 (v.x > u.x, v.y > u.y); +bvec2 greaterThan(const ivec2 u, const ivec2 v) +{ + __asm vec4_sgt __retVal.xy, u, v; } -bvec3 greaterThan (ivec3 v, ivec3 u) { - return bvec3 (v.x > u.x, v.y > u.y, v.z > u.z); +bvec3 greaterThan(const ivec3 u, const ivec3 v) +{ + __asm vec4_sgt __retVal.xyz, u, v; } -bvec4 greaterThan (ivec4 v, ivec4 u) { - return bvec4 (v.x > u.x, v.y > u.y, v.z > u.z, v.w > u.w); +bvec4 greaterThan(const ivec4 u, const ivec4 v) +{ + __asm vec4_sgt __retVal, u, v; } -bvec2 greaterThanEqual (vec2 v, vec2 u) { - return bvec2 (v.x >= u.x, v.y >= u.y); + +//// greaterThanEqual + +bvec2 greaterThanEqual(const vec2 u, const vec2 v) +{ + __asm vec4_sge __retVal.xy, u, v; } -bvec3 greaterThanEqual (vec3 v, vec3 u) { - return bvec3 (v.x >= u.x, v.y >= u.y, v.z >= u.z); +bvec3 greaterThanEqual(const vec3 u, const vec3 v) +{ + __asm vec4_sge __retVal.xyz, u, v; } -bvec4 greaterThanEqual (vec4 v, vec4 u) { - return bvec4 (v.x >= u.x, v.y >= u.y, v.z >= u.z, v.w >= u.w); +bvec4 greaterThanEqual(const vec4 u, const vec4 v) +{ + __asm vec4_sge __retVal, u, v; } -bvec2 greaterThanEqual (ivec2 v, ivec2 u) { - return bvec2 (v.x >= u.x, v.y >= u.y); +bvec2 greaterThanEqual(const ivec2 u, const ivec2 v) +{ + __asm vec4_sge __retVal.xy, u, v; } -bvec3 greaterThanEqual (ivec3 v, ivec3 u) { - return bvec3 (v.x >= u.x, v.y >= u.y, v.z >= u.z); +bvec3 greaterThanEqual(const ivec3 u, const ivec3 v) +{ + __asm vec4_sge __retVal.xyz, u, v; } -bvec4 greaterThanEqual (ivec4 v, ivec4 u) { - return bvec4 (v.x >= u.x, v.y >= u.y, v.z >= u.z, v.w >= u.w); +bvec4 greaterThanEqual(const ivec4 u, const ivec4 v) +{ + __asm vec4_sge __retVal, u, v; } -bvec2 equal (vec2 v, vec2 u) { - return bvec2 (v.x == u.x, v.y == u.y); + +//// equal + +bvec2 equal(const vec2 u, const vec2 v) +{ + __asm vec4_seq __retVal.xy, u, v; } -bvec3 equal (vec3 v, vec3 u) { - return bvec3 (v.x == u.x, v.y == u.y, v.z == u.z); +bvec3 equal(const vec3 u, const vec3 v) +{ + __asm vec4_seq __retVal.xyz, u, v; } -bvec4 equal (vec4 v, vec4 u) { - return bvec4 (v.x == u.x, v.y == u.y, v.z == u.z, v.w == u.w); +bvec4 equal(const vec4 u, const vec4 v) +{ + __asm vec4_seq __retVal, u, v; } -bvec2 equal (ivec2 v, ivec2 u) { - return bvec2 (v.x == u.x, v.y == u.y); +bvec2 equal(const ivec2 u, const ivec2 v) +{ + __asm vec4_seq __retVal.xy, u, v; } -bvec3 equal (ivec3 v, ivec3 u) { - return bvec3 (v.x == u.x, v.y == u.y, v.z == u.z); +bvec3 equal(const ivec3 u, const ivec3 v) +{ + __asm vec4_seq __retVal.xyz, u, v; } -bvec4 equal (ivec4 v, ivec4 u) { - return bvec4 (v.x == u.x, v.y == u.y, v.z == u.z, v.w == u.w); +bvec4 equal(const ivec4 u, const ivec4 v) +{ + __asm vec4_seq __retVal, u, v; } -bvec2 notEqual (vec2 v, vec2 u) { - return bvec2 (v.x != u.x, v.y != u.y); + +//// notEqual + +bvec2 notEqual(const vec2 u, const vec2 v) +{ + __asm vec4_sne __retVal.xy, u, v; } -bvec3 notEqual (vec3 v, vec3 u) { - return bvec3 (v.x != u.x, v.y != u.y, v.z != u.z); +bvec3 notEqual(const vec3 u, const vec3 v) +{ + __asm vec4_sne __retVal.xyz, u, v; } -bvec4 notEqual (vec4 v, vec4 u) { - return bvec4 (v.x != u.x, v.y != u.y, v.z != u.z, v.w != u.w); +bvec4 notEqual(const vec4 u, const vec4 v) +{ + __asm vec4_sne __retVal, u, v; } -bvec2 notEqual (ivec2 v, ivec2 u) { - return bvec2 (v.x != u.x, v.y != u.y); +bvec2 notEqual(const ivec2 u, const ivec2 v) +{ + __asm vec4_sne __retVal.xy, u, v; } -bvec3 notEqual (ivec3 v, ivec3 u) { - return bvec3 (v.x != u.x, v.y != u.y, v.z != u.z); +bvec3 notEqual(const ivec3 u, const ivec3 v) +{ + __asm vec4_sne __retVal.xyz, u, v; } -bvec4 notEqual (ivec4 v, ivec4 u) { - return bvec4 (v.x != u.x, v.y != u.y, v.z != u.z, v.w != u.w); +bvec4 notEqual(const ivec4 u, const ivec4 v) +{ + __asm vec4_sne __retVal, u, v; } -bool any (bvec2 v) { - return v.x || v.y; + +//// any + +bool any(const bvec2 v) +{ + float sum; + __asm vec4_add sum.x, v.x, v.y; + __asm vec4_sne __retVal.x, sum.x, 0.0; } -bool any (bvec3 v) { - return v.x || v.y || v.z; +bool any(const bvec3 v) +{ + float sum; + __asm vec4_add sum.x, v.x, v.y; + __asm vec4_add sum.x, sum.x, v.z; + __asm vec4_sne __retVal.x, sum.x, 0.0; } -bool any (bvec4 v) { - return v.x || v.y || v.z || v.w; +bool any(const bvec4 v) +{ + float sum; + __asm vec4_add sum.x, v.x, v.y; + __asm vec4_add sum.x, sum.x, v.z; + __asm vec4_add sum.x, sum.x, v.w; + __asm vec4_sne __retVal.x, sum.x, 0.0; } -bool all (bvec2 v) { + +//// all + +bool all (const vec2 v) +{ + float prod; + __asm vec4_multiply prod.x, v.x, v.y; + __asm vec4_sne __retVal.x, prod.x, 0.0; return v.x && v.y; } -bool all (bvec3 v) { - return v.x && v.y && v.z; +bool all (const bvec3 v) +{ + float prod; + __asm vec4_multiply prod.x, v.x, v.y; + __asm vec4_multiply prod.x, prod.x, v.z; + __asm vec4_sne __retVal.x, prod.x, 0.0; } -bool all (bvec4 v) { - return v.x && v.y && v.z && v.w; +bool all (const bvec4 v) +{ + float prod; + __asm vec4_multiply prod.x, v.x, v.y; + __asm vec4_multiply prod.x, prod.x, v.z; + __asm vec4_multiply prod.x, prod.x, v.w; + __asm vec4_sne __retVal.x, prod.x, 0.0; } -bvec2 not (bvec2 v) { - return bvec2 (!v.x, !v.y); + + +//// not + +bvec2 not (const bvec2 v) +{ + __asm vec4_seq __retVal.xy, v, 0.0; } -bvec3 not (bvec3 v) { - return bvec3 (!v.x, !v.y, !v.z); +bvec3 not (const bvec3 v) +{ + __asm vec4_seq __retVal.xyz, v, 0.0; } -bvec4 not (bvec4 v) { - return bvec4 (!v.x, !v.y, !v.z, !v.w); +bvec4 not (const bvec4 v) +{ + __asm vec4_seq __retVal, v, 0.0; } -// -// 8.7 Texture Lookup Functions -// -vec4 texture1D (sampler1D sampler, float coord) { - vec4 texel; - __asm vec4_tex1d texel, sampler, coord, 0.0; - return texel; + +//// Texture Lookup Functions (for both fragment and vertex shaders) + +vec4 texture1D(const sampler1D sampler, const float coord) +{ + __asm vec4_tex1d __retVal, sampler, coord; } -vec4 texture1DProj (sampler1D sampler, vec2 coord) { - return texture1D (sampler, coord.s / coord.t); +vec4 texture1DProj(const sampler1D sampler, const vec2 coord) +{ + // new coord with .z moved to .w + vec4 coord4; + coord4.x = coord.x; + coord4.w = coord.y; + __asm vec4_texp1d __retVal, sampler, coord4; } -vec4 texture1DProj (sampler1D sampler, vec4 coord) { - return texture1D (sampler, coord.s / coord.q); +vec4 texture1DProj(const sampler1D sampler, const vec4 coord) +{ + __asm vec4_texp1d __retVal, sampler, coord; } -vec4 texture2D (sampler2D sampler, vec2 coord) { - vec4 texel; - __asm vec4_tex2d texel, sampler, coord, 0.0; - return texel; + +vec4 texture2D(const sampler2D sampler, const vec2 coord) +{ + __asm vec4_tex2d __retVal, sampler, coord; } -vec4 texture2DProj (sampler2D sampler, vec3 coord) { - return texture2D (sampler, vec2 (coord.s / coord.p, coord.t / coord.p)); +vec4 texture2DProj(const sampler2D sampler, const vec3 coord) +{ + // new coord with .z moved to .w + vec4 coord4; + coord4.xy = coord.xy; + coord4.w = coord.z; + __asm vec4_texp2d __retVal, sampler, coord4; } -vec4 texture2DProj (sampler2D sampler, vec4 coord) { - return texture2D (sampler, vec2 (coord.s / coord.q, coord.t / coord.q)); +vec4 texture2DProj(const sampler2D sampler, const vec4 coord) +{ + __asm vec4_texp2d __retVal, sampler, coord; } -vec4 texture3D (sampler3D sampler, vec3 coord) { - vec4 texel; - __asm vec4_tex3d texel, sampler, coord, 0.0; - return texel; + +vec4 texture3D(const sampler3D sampler, const vec3 coord) +{ + __asm vec4_tex3d __retVal, sampler, coord; } -vec4 texture3DProj (sampler3D sampler, vec4 coord) { - return texture3D (sampler, vec3 (coord.s / coord.q, coord.t / coord.q, coord.p / coord.q)); +vec4 texture3DProj(const sampler3D sampler, const vec4 coord) +{ + __asm vec4_texp3d __retVal, sampler, coord; } -vec4 textureCube (samplerCube sampler, vec3 coord) { - vec4 texel; - __asm vec4_texcube texel, sampler, coord, 0.0; - return texel; + +vec4 textureCube(const samplerCube sampler, const vec3 coord) +{ + __asm vec4_texcube __retVal, sampler, coord; } + + vec4 shadow1D (sampler1DShadow sampler, vec3 coord) { vec4 texel; __asm vec4_shad1d texel, sampler, coord, 0.0; @@ -1347,123 +1686,107 @@ vec4 shadow2DProj (sampler2DShadow sampler, vec4 coord) { // AUTHOR: Stefan Gustavson (stegu@itn.liu.se), Nov 26, 2005 // -float noise1 (float x) { - float a; - __asm float_noise1 a, x; - return a; +float noise1(const float x) +{ + __asm float_noise1 __retVal, x; } -float noise1 (vec2 x) { - float a; - __asm float_noise2 a, x; - return a; -} -float noise1 (vec3 x) { - float a; - __asm float_noise3 a, x; - return a; +float noise1(const vec2 x) +{ + __asm float_noise2 __retVal, x; } -float noise1 (vec4 x) { - float a; - __asm float_noise4 a, x; - return a; +float noise1(const vec3 x) +{ + __asm float_noise3 __retVal, x; } -vec2 noise2 (float x) { - return vec2 ( - noise1 (x), - noise1 (x + 19.34) - ); +float noise1(const vec4 x) +{ + __asm float_noise4 __retVal, x; } -vec2 noise2 (vec2 x) { - return vec2 ( - noise1 (x), - noise1 (x + vec2 (19.34, 7.66)) - ); +vec2 noise2(const float x) +{ + __retVal.x = noise1(x); + __retVal.y = noise1(x + 19.34); } -vec2 noise2 (vec3 x) { - return vec2 ( - noise1 (x), - noise1 (x + vec3 (19.34, 7.66, 3.23)) - ); +vec2 noise2(const vec2 x) +{ + __retVal.x = noise1(x); + __retVal.y = noise1(x + vec2(19.34, 7.66)); } -vec2 noise2 (vec4 x) { - return vec2 ( - noise1 (x), - noise1 (x + vec4 (19.34, 7.66, 3.23, 2.77)) - ); +vec2 noise2(const vec3 x) +{ + __retVal.x = noise1(x); + __retVal.y = noise1(x + vec3(19.34, 7.66, 3.23)); } -vec3 noise3 (float x) { - return vec3 ( - noise1 (x), - noise1 (x + 19.34), - noise1 (x + 5.47) - ); +vec2 noise2(const vec4 x) +{ + __retVal.x = noise1(x); + __retVal.y = noise1(x + vec4(19.34, 7.66, 3.23, 2.77)); } -vec3 noise3 (vec2 x) { - return vec3 ( - noise1 (x), - noise1 (x + vec2 (19.34, 7.66)), - noise1 (x + vec2 (5.47, 17.85)) - ); +vec3 noise3(const float x) +{ + __retVal.x = noise1(x); + __retVal.y = noise1(x + 19.34); + __retVal.z = noise1(x + 5.47); } -vec3 noise3 (vec3 x) { - return vec3 ( - noise1 (x), - noise1 (x + vec3 (19.34, 7.66, 3.23)), - noise1 (x + vec3 (5.47, 17.85, 11.04)) - ); +vec3 noise3(const vec2 x) +{ + __retVal.x = noise1(x); + __retVal.y = noise1(x + vec2(19.34, 7.66)); + __retVal.z = noise1(x + vec2(5.47, 17.85)); } -vec3 noise3 (vec4 x) { - return vec3 ( - noise1 (x), - noise1 (x + vec4 (19.34, 7.66, 3.23, 2.77)), - noise1 (x + vec4 (5.47, 17.85, 11.04, 13.19)) - ); +vec3 noise3(const vec3 x) +{ + __retVal.x = noise1(x); + __retVal.y = noise1(x + vec3(19.34, 7.66, 3.23)); + __retVal.z = noise1(x + vec3(5.47, 17.85, 11.04)); } -vec4 noise4 (float x) { - return vec4 ( - noise1 (x), - noise1 (x + 19.34), - noise1 (x + 5.47), - noise1 (x + 23.54) - ); +vec3 noise3(const vec4 x) +{ + __retVal.x = noise1(x); + __retVal.y = noise1(x + vec4(19.34, 7.66, 3.23, 2.77)); + __retVal.z = noise1(x + vec4(5.47, 17.85, 11.04, 13.19)); } -vec4 noise4 (vec2 x) { - return vec4 ( - noise1 (x), - noise1 (x + vec2 (19.34, 7.66)), - noise1 (x + vec2 (5.47, 17.85)), - noise1 (x + vec2 (23.54, 29.11)) - ); +vec4 noise4(const float x) +{ + __retVal.x = noise1(x); + __retVal.y = noise1(x + 19.34); + __retVal.z = noise1(x + 5.47); + __retVal.w = noise1(x + 23.54); } -vec4 noise4 (vec3 x) { - return vec4 ( - noise1 (x), - noise1 (x + vec3 (19.34, 7.66, 3.23)), - noise1 (x + vec3 (5.47, 17.85, 11.04)), - noise1 (x + vec3 (23.54, 29.11, 31.91)) - ); +vec4 noise4(const vec2 x) +{ + __retVal.x = noise1(x); + __retVal.y = noise1(x + vec2 (19.34, 7.66)); + __retVal.z = noise1(x + vec2 (5.47, 17.85)); + __retVal.w = noise1(x + vec2 (23.54, 29.11)); } -vec4 noise4 (vec4 x) { - return vec4 ( - noise1 (x), - noise1 (x + vec4 (19.34, 7.66, 3.23, 2.77)), - noise1 (x + vec4 (5.47, 17.85, 11.04, 13.19)), - noise1 (x + vec4 (23.54, 29.11, 31.91, 37.48)) - ); +vec4 noise4(const vec3 x) +{ + __retVal.x = noise1(x); + __retVal.y = noise1(x + vec3(19.34, 7.66, 3.23)); + __retVal.z = noise1(x + vec3(5.47, 17.85, 11.04)); + __retVal.w = noise1(x + vec3(23.54, 29.11, 31.91)); } +vec4 noise4(const vec4 x) +{ + __retVal.x = noise1(x); + __retVal.y = noise1(x + vec4(19.34, 7.66, 3.23, 2.77)); + __retVal.z = noise1(x + vec4(5.47, 17.85, 11.04, 13.19)); + __retVal.w = noise1(x + vec4(23.54, 29.11, 31.91, 37.48)); +} diff --git a/src/mesa/shader/slang/library/slang_common_builtin_gc.h b/src/mesa/shader/slang/library/slang_common_builtin_gc.h index e5876528e1..417f1fce86 100644 --- a/src/mesa/shader/slang/library/slang_common_builtin_gc.h +++ b/src/mesa/shader/slang/library/slang_common_builtin_gc.h @@ -21,627 +21,757 @@ 119,80,114,111,106,101,99,116,105,111,110,77,97,116,114,105,120,0,0,0,2,2,4,15,1,103,108,95,84,101, 120,116,117,114,101,77,97,116,114,105,120,0,3,18,103,108,95,77,97,120,84,101,120,116,117,114,101, 67,111,111,114,100,115,0,0,0,2,2,4,14,1,103,108,95,78,111,114,109,97,108,77,97,116,114,105,120,0,0, -0,2,2,4,15,1,103,108,95,77,111,100,101,108,86,105,101,119,77,97,116,114,105,120,73,110,118,101,114, -115,101,0,0,0,2,2,4,15,1,103,108,95,80,114,111,106,101,99,116,105,111,110,77,97,116,114,105,120,73, -110,118,101,114,115,101,0,0,0,2,2,4,15,1,103,108,95,77,111,100,101,108,86,105,101,119,80,114,111, -106,101,99,116,105,111,110,77,97,116,114,105,120,73,110,118,101,114,115,101,0,0,0,2,2,4,15,1,103, -108,95,84,101,120,116,117,114,101,77,97,116,114,105,120,73,110,118,101,114,115,101,0,3,18,103,108, -95,77,97,120,84,101,120,116,117,114,101,67,111,111,114,100,115,0,0,0,2,2,4,15,1,103,108,95,77,111, -100,101,108,86,105,101,119,77,97,116,114,105,120,84,114,97,110,115,112,111,115,101,0,0,0,2,2,4,15, -1,103,108,95,80,114,111,106,101,99,116,105,111,110,77,97,116,114,105,120,84,114,97,110,115,112,111, -115,101,0,0,0,2,2,4,15,1,103,108,95,77,111,100,101,108,86,105,101,119,80,114,111,106,101,99,116, -105,111,110,77,97,116,114,105,120,84,114,97,110,115,112,111,115,101,0,0,0,2,2,4,15,1,103,108,95,84, -101,120,116,117,114,101,77,97,116,114,105,120,84,114,97,110,115,112,111,115,101,0,3,18,103,108,95, -77,97,120,84,101,120,116,117,114,101,67,111,111,114,100,115,0,0,0,2,2,4,15,1,103,108,95,77,111,100, -101,108,86,105,101,119,77,97,116,114,105,120,73,110,118,101,114,115,101,84,114,97,110,115,112,111, -115,101,0,0,0,2,2,4,15,1,103,108,95,80,114,111,106,101,99,116,105,111,110,77,97,116,114,105,120,73, -110,118,101,114,115,101,84,114,97,110,115,112,111,115,101,0,0,0,2,2,4,15,1,103,108,95,77,111,100, -101,108,86,105,101,119,80,114,111,106,101,99,116,105,111,110,77,97,116,114,105,120,73,110,118,101, -114,115,101,84,114,97,110,115,112,111,115,101,0,0,0,2,2,4,15,1,103,108,95,84,101,120,116,117,114, -101,77,97,116,114,105,120,73,110,118,101,114,115,101,84,114,97,110,115,112,111,115,101,0,3,18,103, -108,95,77,97,120,84,101,120,116,117,114,101,67,111,111,114,100,115,0,0,0,2,2,4,9,1,103,108,95,78, -111,114,109,97,108,83,99,97,108,101,0,0,0,2,2,0,22,103,108,95,68,101,112,116,104,82,97,110,103,101, -80,97,114,97,109,101,116,101,114,115,0,9,110,101,97,114,0,0,0,1,9,102,97,114,0,0,0,1,9,100,105,102, -102,0,0,0,0,0,0,2,2,4,23,103,108,95,68,101,112,116,104,82,97,110,103,101,80,97,114,97,109,101,116, -101,114,115,0,1,103,108,95,68,101,112,116,104,82,97,110,103,101,0,0,0,2,2,4,12,1,103,108,95,67,108, -105,112,80,108,97,110,101,0,3,18,103,108,95,77,97,120,67,108,105,112,80,108,97,110,101,115,0,0,0,2, -2,0,22,103,108,95,80,111,105,110,116,80,97,114,97,109,101,116,101,114,115,0,9,115,105,122,101,0,0, -0,1,9,115,105,122,101,77,105,110,0,0,0,1,9,115,105,122,101,77,97,120,0,0,0,1,9,102,97,100,101,84, -104,114,101,115,104,111,108,100,83,105,122,101,0,0,0,1,9,100,105,115,116,97,110,99,101,67,111,110, -115,116,97,110,116,65,116,116,101,110,117,97,116,105,111,110,0,0,0,1,9,100,105,115,116,97,110,99, -101,76,105,110,101,97,114,65,116,116,101,110,117,97,116,105,111,110,0,0,0,1,9,100,105,115,116,97, -110,99,101,81,117,97,100,114,97,116,105,99,65,116,116,101,110,117,97,116,105,111,110,0,0,0,0,0,0,2, -2,4,23,103,108,95,80,111,105,110,116,80,97,114,97,109,101,116,101,114,115,0,1,103,108,95,80,111, -105,110,116,0,0,0,2,2,0,22,103,108,95,77,97,116,101,114,105,97,108,80,97,114,97,109,101,116,101, -114,115,0,12,101,109,105,115,115,105,111,110,0,0,0,1,12,97,109,98,105,101,110,116,0,0,0,1,12,100, -105,102,102,117,115,101,0,0,0,1,12,115,112,101,99,117,108,97,114,0,0,0,1,9,115,104,105,110,105,110, -101,115,115,0,0,0,0,0,0,2,2,4,23,103,108,95,77,97,116,101,114,105,97,108,80,97,114,97,109,101,116, -101,114,115,0,1,103,108,95,70,114,111,110,116,77,97,116,101,114,105,97,108,0,0,0,2,2,4,23,103,108, -95,77,97,116,101,114,105,97,108,80,97,114,97,109,101,116,101,114,115,0,1,103,108,95,66,97,99,107, -77,97,116,101,114,105,97,108,0,0,0,2,2,0,22,103,108,95,76,105,103,104,116,83,111,117,114,99,101,80, -97,114,97,109,101,116,101,114,115,0,12,97,109,98,105,101,110,116,0,0,0,1,12,100,105,102,102,117, -115,101,0,0,0,1,12,115,112,101,99,117,108,97,114,0,0,0,1,12,112,111,115,105,116,105,111,110,0,0,0, -1,12,104,97,108,102,86,101,99,116,111,114,0,0,0,1,11,115,112,111,116,68,105,114,101,99,116,105,111, -110,0,0,0,1,9,115,112,111,116,69,120,112,111,110,101,110,116,0,0,0,1,9,115,112,111,116,67,117,116, -111,102,102,0,0,0,1,9,115,112,111,116,67,111,115,67,117,116,111,102,102,0,0,0,1,9,99,111,110,115, -116,97,110,116,65,116,116,101,110,117,97,116,105,111,110,0,0,0,1,9,108,105,110,101,97,114,65,116, -116,101,110,117,97,116,105,111,110,0,0,0,1,9,113,117,97,100,114,97,116,105,99,65,116,116,101,110, -117,97,116,105,111,110,0,0,0,0,0,0,2,2,4,23,103,108,95,76,105,103,104,116,83,111,117,114,99,101,80, -97,114,97,109,101,116,101,114,115,0,1,103,108,95,76,105,103,104,116,83,111,117,114,99,101,0,3,18, -103,108,95,77,97,120,76,105,103,104,116,115,0,0,0,2,2,0,22,103,108,95,76,105,103,104,116,77,111, -100,101,108,80,97,114,97,109,101,116,101,114,115,0,12,97,109,98,105,101,110,116,0,0,0,0,0,0,2,2,4, -23,103,108,95,76,105,103,104,116,77,111,100,101,108,80,97,114,97,109,101,116,101,114,115,0,1,103, -108,95,76,105,103,104,116,77,111,100,101,108,0,0,0,2,2,0,22,103,108,95,76,105,103,104,116,77,111, -100,101,108,80,114,111,100,117,99,116,115,0,12,115,99,101,110,101,67,111,108,111,114,0,0,0,0,0,0,2, -2,4,23,103,108,95,76,105,103,104,116,77,111,100,101,108,80,114,111,100,117,99,116,115,0,1,103,108, -95,70,114,111,110,116,76,105,103,104,116,77,111,100,101,108,80,114,111,100,117,99,116,0,0,0,2,2,4, -23,103,108,95,76,105,103,104,116,77,111,100,101,108,80,114,111,100,117,99,116,115,0,1,103,108,95, -66,97,99,107,76,105,103,104,116,77,111,100,101,108,80,114,111,100,117,99,116,0,0,0,2,2,0,22,103, -108,95,76,105,103,104,116,80,114,111,100,117,99,116,115,0,12,97,109,98,105,101,110,116,0,0,0,1,12, -100,105,102,102,117,115,101,0,0,0,1,12,115,112,101,99,117,108,97,114,0,0,0,0,0,0,2,2,4,23,103,108, -95,76,105,103,104,116,80,114,111,100,117,99,116,115,0,1,103,108,95,70,114,111,110,116,76,105,103, -104,116,80,114,111,100,117,99,116,0,3,18,103,108,95,77,97,120,76,105,103,104,116,115,0,0,0,2,2,4, -23,103,108,95,76,105,103,104,116,80,114,111,100,117,99,116,115,0,1,103,108,95,66,97,99,107,76,105, -103,104,116,80,114,111,100,117,99,116,0,3,18,103,108,95,77,97,120,76,105,103,104,116,115,0,0,0,2,2, -4,12,1,103,108,95,84,101,120,116,117,114,101,69,110,118,67,111,108,111,114,0,3,18,103,108,95,77,97, -120,84,101,120,116,117,114,101,73,109,97,103,101,85,110,105,116,115,0,0,0,2,2,4,12,1,103,108,95,69, -121,101,80,108,97,110,101,83,0,3,18,103,108,95,77,97,120,84,101,120,116,117,114,101,67,111,111,114, -100,115,0,0,0,2,2,4,12,1,103,108,95,69,121,101,80,108,97,110,101,84,0,3,18,103,108,95,77,97,120,84, -101,120,116,117,114,101,67,111,111,114,100,115,0,0,0,2,2,4,12,1,103,108,95,69,121,101,80,108,97, -110,101,82,0,3,18,103,108,95,77,97,120,84,101,120,116,117,114,101,67,111,111,114,100,115,0,0,0,2,2, -4,12,1,103,108,95,69,121,101,80,108,97,110,101,81,0,3,18,103,108,95,77,97,120,84,101,120,116,117, -114,101,67,111,111,114,100,115,0,0,0,2,2,4,12,1,103,108,95,79,98,106,101,99,116,80,108,97,110,101, -83,0,3,18,103,108,95,77,97,120,84,101,120,116,117,114,101,67,111,111,114,100,115,0,0,0,2,2,4,12,1, -103,108,95,79,98,106,101,99,116,80,108,97,110,101,84,0,3,18,103,108,95,77,97,120,84,101,120,116, -117,114,101,67,111,111,114,100,115,0,0,0,2,2,4,12,1,103,108,95,79,98,106,101,99,116,80,108,97,110, -101,82,0,3,18,103,108,95,77,97,120,84,101,120,116,117,114,101,67,111,111,114,100,115,0,0,0,2,2,4, -12,1,103,108,95,79,98,106,101,99,116,80,108,97,110,101,81,0,3,18,103,108,95,77,97,120,84,101,120, -116,117,114,101,67,111,111,114,100,115,0,0,0,2,2,0,22,103,108,95,70,111,103,80,97,114,97,109,101, -116,101,114,115,0,12,99,111,108,111,114,0,0,0,1,9,100,101,110,115,105,116,121,0,0,0,1,9,115,116,97, -114,116,0,0,0,1,9,101,110,100,0,0,0,1,9,115,99,97,108,101,0,0,0,0,0,0,2,2,4,23,103,108,95,70,111, -103,80,97,114,97,109,101,116,101,114,115,0,1,103,108,95,70,111,103,0,0,0,1,0,9,0,114,97,100,105,97, -110,115,0,1,0,0,9,100,101,103,0,0,0,1,8,17,51,0,49,52,49,53,57,51,0,0,18,100,101,103,0,48,17,49,56, -48,0,48,0,0,49,0,0,1,0,10,0,114,97,100,105,97,110,115,0,1,0,0,10,100,101,103,0,0,0,1,8,58,118,101, -99,50,0,17,51,0,49,52,49,53,57,51,0,0,0,0,18,100,101,103,0,48,58,118,101,99,50,0,17,49,56,48,0,48, -0,0,0,0,49,0,0,1,0,11,0,114,97,100,105,97,110,115,0,1,0,0,11,100,101,103,0,0,0,1,8,58,118,101,99, -51,0,17,51,0,49,52,49,53,57,51,0,0,0,0,18,100,101,103,0,48,58,118,101,99,51,0,17,49,56,48,0,48,0,0, -0,0,49,0,0,1,0,12,0,114,97,100,105,97,110,115,0,1,0,0,12,100,101,103,0,0,0,1,8,58,118,101,99,52,0, -17,51,0,49,52,49,53,57,51,0,0,0,0,18,100,101,103,0,48,58,118,101,99,52,0,17,49,56,48,0,48,0,0,0,0, -49,0,0,1,0,9,0,100,101,103,114,101,101,115,0,1,0,0,9,114,97,100,0,0,0,1,8,17,49,56,48,0,48,0,0,18, -114,97,100,0,48,17,51,0,49,52,49,53,57,51,0,0,49,0,0,1,0,10,0,100,101,103,114,101,101,115,0,1,0,0, -10,114,97,100,0,0,0,1,8,58,118,101,99,50,0,17,49,56,48,0,48,0,0,0,0,18,114,97,100,0,48,58,118,101, -99,50,0,17,51,0,49,52,49,53,57,51,0,0,0,0,49,0,0,1,0,11,0,100,101,103,114,101,101,115,0,1,0,0,11, -114,97,100,0,0,0,1,8,58,118,101,99,51,0,17,49,56,48,0,48,0,0,0,0,18,114,97,100,0,48,58,118,101,99, -51,0,17,51,0,49,52,49,53,57,51,0,0,0,0,49,0,0,1,0,12,0,100,101,103,114,101,101,115,0,1,0,0,12,114, -97,100,0,0,0,1,8,58,118,101,99,52,0,17,49,56,48,0,48,0,0,0,0,18,114,97,100,0,48,58,118,101,99,52,0, -17,51,0,49,52,49,53,57,51,0,0,0,0,49,0,0,1,0,9,0,115,105,110,0,1,0,0,9,97,110,103,108,101,0,0,0,1, -3,2,0,9,1,120,0,0,0,4,102,108,111,97,116,95,115,105,110,101,0,18,120,0,0,18,97,110,103,108,101,0,0, -0,8,18,120,0,0,0,1,0,10,0,115,105,110,0,1,0,0,10,97,110,103,108,101,0,0,0,1,8,58,118,101,99,50,0, -58,115,105,110,0,18,97,110,103,108,101,0,59,120,0,0,0,0,58,115,105,110,0,18,97,110,103,108,101,0, -59,121,0,0,0,0,0,0,0,1,0,11,0,115,105,110,0,1,0,0,11,97,110,103,108,101,0,0,0,1,8,58,118,101,99,51, -0,58,115,105,110,0,18,97,110,103,108,101,0,59,120,0,0,0,0,58,115,105,110,0,18,97,110,103,108,101,0, -59,121,0,0,0,0,58,115,105,110,0,18,97,110,103,108,101,0,59,122,0,0,0,0,0,0,0,1,0,12,0,115,105,110, -0,1,0,0,12,97,110,103,108,101,0,0,0,1,8,58,118,101,99,52,0,58,115,105,110,0,18,97,110,103,108,101, -0,59,120,0,0,0,0,58,115,105,110,0,18,97,110,103,108,101,0,59,121,0,0,0,0,58,115,105,110,0,18,97, -110,103,108,101,0,59,122,0,0,0,0,58,115,105,110,0,18,97,110,103,108,101,0,59,119,0,0,0,0,0,0,0,1,0, -9,0,99,111,115,0,1,0,0,9,97,110,103,108,101,0,0,0,1,8,58,115,105,110,0,18,97,110,103,108,101,0,17, -49,0,53,55,48,56,0,0,46,0,0,0,0,1,0,10,0,99,111,115,0,1,0,0,10,97,110,103,108,101,0,0,0,1,8,58,118, -101,99,50,0,58,99,111,115,0,18,97,110,103,108,101,0,59,120,0,0,0,0,58,99,111,115,0,18,97,110,103, -108,101,0,59,121,0,0,0,0,0,0,0,1,0,11,0,99,111,115,0,1,0,0,11,97,110,103,108,101,0,0,0,1,8,58,118, -101,99,51,0,58,99,111,115,0,18,97,110,103,108,101,0,59,120,0,0,0,0,58,99,111,115,0,18,97,110,103, -108,101,0,59,121,0,0,0,0,58,99,111,115,0,18,97,110,103,108,101,0,59,122,0,0,0,0,0,0,0,1,0,12,0,99, -111,115,0,1,0,0,12,97,110,103,108,101,0,0,0,1,8,58,118,101,99,52,0,58,99,111,115,0,18,97,110,103, -108,101,0,59,120,0,0,0,0,58,99,111,115,0,18,97,110,103,108,101,0,59,121,0,0,0,0,58,99,111,115,0,18, -97,110,103,108,101,0,59,122,0,0,0,0,58,99,111,115,0,18,97,110,103,108,101,0,59,119,0,0,0,0,0,0,0,1, -0,9,0,116,97,110,0,1,0,0,9,97,110,103,108,101,0,0,0,1,8,58,115,105,110,0,18,97,110,103,108,101,0,0, -0,58,99,111,115,0,18,97,110,103,108,101,0,0,0,49,0,0,1,0,10,0,116,97,110,0,1,0,0,10,97,110,103,108, -101,0,0,0,1,8,58,118,101,99,50,0,58,116,97,110,0,18,97,110,103,108,101,0,59,120,0,0,0,0,58,116,97, -110,0,18,97,110,103,108,101,0,59,121,0,0,0,0,0,0,0,1,0,11,0,116,97,110,0,1,0,0,11,97,110,103,108, -101,0,0,0,1,8,58,118,101,99,51,0,58,116,97,110,0,18,97,110,103,108,101,0,59,120,0,0,0,0,58,116,97, -110,0,18,97,110,103,108,101,0,59,121,0,0,0,0,58,116,97,110,0,18,97,110,103,108,101,0,59,122,0,0,0, -0,0,0,0,1,0,12,0,116,97,110,0,1,0,0,12,97,110,103,108,101,0,0,0,1,8,58,118,101,99,52,0,58,116,97, -110,0,18,97,110,103,108,101,0,59,120,0,0,0,0,58,116,97,110,0,18,97,110,103,108,101,0,59,121,0,0,0, -0,58,116,97,110,0,18,97,110,103,108,101,0,59,122,0,0,0,0,58,116,97,110,0,18,97,110,103,108,101,0, -59,119,0,0,0,0,0,0,0,1,0,9,0,97,115,105,110,0,1,0,0,9,120,0,0,0,1,3,2,0,9,1,121,0,0,0,4,102,108, -111,97,116,95,97,114,99,115,105,110,101,0,18,121,0,0,18,120,0,0,0,8,18,121,0,0,0,1,0,10,0,97,115, -105,110,0,1,0,0,10,118,0,0,0,1,8,58,118,101,99,50,0,58,97,115,105,110,0,18,118,0,59,120,0,0,0,0,58, -97,115,105,110,0,18,118,0,59,121,0,0,0,0,0,0,0,1,0,11,0,97,115,105,110,0,1,0,0,11,118,0,0,0,1,8,58, -118,101,99,51,0,58,97,115,105,110,0,18,118,0,59,120,0,0,0,0,58,97,115,105,110,0,18,118,0,59,121,0, -0,0,0,58,97,115,105,110,0,18,118,0,59,122,0,0,0,0,0,0,0,1,0,12,0,97,115,105,110,0,1,0,0,12,118,0,0, -0,1,8,58,118,101,99,52,0,58,97,115,105,110,0,18,118,0,59,120,0,0,0,0,58,97,115,105,110,0,18,118,0, -59,121,0,0,0,0,58,97,115,105,110,0,18,118,0,59,122,0,0,0,0,58,97,115,105,110,0,18,118,0,59,119,0,0, -0,0,0,0,0,1,0,9,0,97,99,111,115,0,1,0,0,9,120,0,0,0,1,8,17,49,0,53,55,48,56,0,0,58,97,115,105,110, -0,18,120,0,0,0,47,0,0,1,0,10,0,97,99,111,115,0,1,0,0,10,118,0,0,0,1,8,58,118,101,99,50,0,58,97,99, -111,115,0,18,118,0,59,120,0,0,0,0,58,97,99,111,115,0,18,118,0,59,121,0,0,0,0,0,0,0,1,0,11,0,97,99, -111,115,0,1,0,0,11,118,0,0,0,1,8,58,118,101,99,51,0,58,97,99,111,115,0,18,118,0,59,120,0,0,0,0,58, -97,99,111,115,0,18,118,0,59,121,0,0,0,0,58,97,99,111,115,0,18,118,0,59,122,0,0,0,0,0,0,0,1,0,12,0, -97,99,111,115,0,1,0,0,12,118,0,0,0,1,8,58,118,101,99,52,0,58,97,99,111,115,0,18,118,0,59,120,0,0,0, -0,58,97,99,111,115,0,18,118,0,59,121,0,0,0,0,58,97,99,111,115,0,18,118,0,59,122,0,0,0,0,58,97,99, -111,115,0,18,118,0,59,119,0,0,0,0,0,0,0,1,0,9,0,97,116,97,110,0,1,0,0,9,121,95,111,118,101,114,95, -120,0,0,0,1,3,2,0,9,1,122,0,0,0,4,102,108,111,97,116,95,97,114,99,116,97,110,0,18,122,0,0,18,121, -95,111,118,101,114,95,120,0,0,0,8,18,122,0,0,0,1,0,10,0,97,116,97,110,0,1,0,0,10,121,95,111,118, -101,114,95,120,0,0,0,1,8,58,118,101,99,50,0,58,97,116,97,110,0,18,121,95,111,118,101,114,95,120,0, -59,120,0,0,0,0,58,97,116,97,110,0,18,121,95,111,118,101,114,95,120,0,59,121,0,0,0,0,0,0,0,1,0,11,0, -97,116,97,110,0,1,0,0,11,121,95,111,118,101,114,95,120,0,0,0,1,8,58,118,101,99,51,0,58,97,116,97, -110,0,18,121,95,111,118,101,114,95,120,0,59,120,0,0,0,0,58,97,116,97,110,0,18,121,95,111,118,101, -114,95,120,0,59,121,0,0,0,0,58,97,116,97,110,0,18,121,95,111,118,101,114,95,120,0,59,122,0,0,0,0,0, -0,0,1,0,12,0,97,116,97,110,0,1,0,0,12,121,95,111,118,101,114,95,120,0,0,0,1,8,58,118,101,99,52,0, -58,97,116,97,110,0,18,121,95,111,118,101,114,95,120,0,59,120,0,0,0,0,58,97,116,97,110,0,18,121,95, -111,118,101,114,95,120,0,59,121,0,0,0,0,58,97,116,97,110,0,18,121,95,111,118,101,114,95,120,0,59, -122,0,0,0,0,58,97,116,97,110,0,18,121,95,111,118,101,114,95,120,0,59,119,0,0,0,0,0,0,0,1,0,9,0,97, -116,97,110,0,1,0,0,9,121,0,0,1,0,0,9,120,0,0,0,1,3,2,0,9,1,122,0,2,58,97,116,97,110,0,18,121,0,18, -120,0,49,0,0,0,0,10,18,120,0,17,48,0,48,0,0,40,0,2,10,18,121,0,17,48,0,48,0,0,40,0,8,18,122,0,17, -51,0,49,52,49,53,57,51,0,0,47,0,9,14,0,8,18,122,0,17,51,0,49,52,49,53,57,51,0,0,46,0,0,9,14,0,8,18, -122,0,0,0,1,0,10,0,97,116,97,110,0,1,0,0,10,117,0,0,1,0,0,10,118,0,0,0,1,8,58,118,101,99,50,0,58, -97,116,97,110,0,18,117,0,59,120,0,0,18,118,0,59,120,0,0,0,0,58,97,116,97,110,0,18,117,0,59,121,0,0, -18,118,0,59,121,0,0,0,0,0,0,0,1,0,11,0,97,116,97,110,0,1,0,0,11,117,0,0,1,0,0,11,118,0,0,0,1,8,58, -118,101,99,51,0,58,97,116,97,110,0,18,117,0,59,120,0,0,18,118,0,59,120,0,0,0,0,58,97,116,97,110,0, +0,2,2,4,14,1,95,95,78,111,114,109,97,108,77,97,116,114,105,120,84,114,97,110,115,112,111,115,101,0, +0,0,2,2,4,15,1,103,108,95,77,111,100,101,108,86,105,101,119,77,97,116,114,105,120,73,110,118,101, +114,115,101,0,0,0,2,2,4,15,1,103,108,95,80,114,111,106,101,99,116,105,111,110,77,97,116,114,105, +120,73,110,118,101,114,115,101,0,0,0,2,2,4,15,1,103,108,95,77,111,100,101,108,86,105,101,119,80, +114,111,106,101,99,116,105,111,110,77,97,116,114,105,120,73,110,118,101,114,115,101,0,0,0,2,2,4,15, +1,103,108,95,84,101,120,116,117,114,101,77,97,116,114,105,120,73,110,118,101,114,115,101,0,3,18, +103,108,95,77,97,120,84,101,120,116,117,114,101,67,111,111,114,100,115,0,0,0,2,2,4,15,1,103,108,95, +77,111,100,101,108,86,105,101,119,77,97,116,114,105,120,84,114,97,110,115,112,111,115,101,0,0,0,2, +2,4,15,1,103,108,95,80,114,111,106,101,99,116,105,111,110,77,97,116,114,105,120,84,114,97,110,115, +112,111,115,101,0,0,0,2,2,4,15,1,103,108,95,77,111,100,101,108,86,105,101,119,80,114,111,106,101, +99,116,105,111,110,77,97,116,114,105,120,84,114,97,110,115,112,111,115,101,0,0,0,2,2,4,15,1,103, +108,95,84,101,120,116,117,114,101,77,97,116,114,105,120,84,114,97,110,115,112,111,115,101,0,3,18, +103,108,95,77,97,120,84,101,120,116,117,114,101,67,111,111,114,100,115,0,0,0,2,2,4,15,1,103,108,95, +77,111,100,101,108,86,105,101,119,77,97,116,114,105,120,73,110,118,101,114,115,101,84,114,97,110, +115,112,111,115,101,0,0,0,2,2,4,15,1,103,108,95,80,114,111,106,101,99,116,105,111,110,77,97,116, +114,105,120,73,110,118,101,114,115,101,84,114,97,110,115,112,111,115,101,0,0,0,2,2,4,15,1,103,108, +95,77,111,100,101,108,86,105,101,119,80,114,111,106,101,99,116,105,111,110,77,97,116,114,105,120, +73,110,118,101,114,115,101,84,114,97,110,115,112,111,115,101,0,0,0,2,2,4,15,1,103,108,95,84,101, +120,116,117,114,101,77,97,116,114,105,120,73,110,118,101,114,115,101,84,114,97,110,115,112,111,115, +101,0,3,18,103,108,95,77,97,120,84,101,120,116,117,114,101,67,111,111,114,100,115,0,0,0,2,2,4,9,1, +103,108,95,78,111,114,109,97,108,83,99,97,108,101,0,0,0,2,2,0,24,103,108,95,68,101,112,116,104,82, +97,110,103,101,80,97,114,97,109,101,116,101,114,115,0,9,110,101,97,114,0,0,0,1,9,102,97,114,0,0,0, +1,9,100,105,102,102,0,0,0,0,0,0,2,2,4,25,103,108,95,68,101,112,116,104,82,97,110,103,101,80,97,114, +97,109,101,116,101,114,115,0,1,103,108,95,68,101,112,116,104,82,97,110,103,101,0,0,0,2,2,4,12,1, +103,108,95,67,108,105,112,80,108,97,110,101,0,3,18,103,108,95,77,97,120,67,108,105,112,80,108,97, +110,101,115,0,0,0,2,2,0,24,103,108,95,80,111,105,110,116,80,97,114,97,109,101,116,101,114,115,0,9, +115,105,122,101,0,0,0,1,9,115,105,122,101,77,105,110,0,0,0,1,9,115,105,122,101,77,97,120,0,0,0,1,9, +102,97,100,101,84,104,114,101,115,104,111,108,100,83,105,122,101,0,0,0,1,9,100,105,115,116,97,110, +99,101,67,111,110,115,116,97,110,116,65,116,116,101,110,117,97,116,105,111,110,0,0,0,1,9,100,105, +115,116,97,110,99,101,76,105,110,101,97,114,65,116,116,101,110,117,97,116,105,111,110,0,0,0,1,9, +100,105,115,116,97,110,99,101,81,117,97,100,114,97,116,105,99,65,116,116,101,110,117,97,116,105, +111,110,0,0,0,0,0,0,2,2,4,25,103,108,95,80,111,105,110,116,80,97,114,97,109,101,116,101,114,115,0, +1,103,108,95,80,111,105,110,116,0,0,0,2,2,0,24,103,108,95,77,97,116,101,114,105,97,108,80,97,114, +97,109,101,116,101,114,115,0,12,101,109,105,115,115,105,111,110,0,0,0,1,12,97,109,98,105,101,110, +116,0,0,0,1,12,100,105,102,102,117,115,101,0,0,0,1,12,115,112,101,99,117,108,97,114,0,0,0,1,9,115, +104,105,110,105,110,101,115,115,0,0,0,0,0,0,2,2,4,25,103,108,95,77,97,116,101,114,105,97,108,80,97, +114,97,109,101,116,101,114,115,0,1,103,108,95,70,114,111,110,116,77,97,116,101,114,105,97,108,0,0, +0,2,2,4,25,103,108,95,77,97,116,101,114,105,97,108,80,97,114,97,109,101,116,101,114,115,0,1,103, +108,95,66,97,99,107,77,97,116,101,114,105,97,108,0,0,0,2,2,0,24,103,108,95,76,105,103,104,116,83, +111,117,114,99,101,80,97,114,97,109,101,116,101,114,115,0,12,97,109,98,105,101,110,116,0,0,0,1,12, +100,105,102,102,117,115,101,0,0,0,1,12,115,112,101,99,117,108,97,114,0,0,0,1,12,112,111,115,105, +116,105,111,110,0,0,0,1,12,104,97,108,102,86,101,99,116,111,114,0,0,0,1,11,115,112,111,116,68,105, +114,101,99,116,105,111,110,0,0,0,1,9,115,112,111,116,69,120,112,111,110,101,110,116,0,0,0,1,9,115, +112,111,116,67,117,116,111,102,102,0,0,0,1,9,115,112,111,116,67,111,115,67,117,116,111,102,102,0,0, +0,1,9,99,111,110,115,116,97,110,116,65,116,116,101,110,117,97,116,105,111,110,0,0,0,1,9,108,105, +110,101,97,114,65,116,116,101,110,117,97,116,105,111,110,0,0,0,1,9,113,117,97,100,114,97,116,105, +99,65,116,116,101,110,117,97,116,105,111,110,0,0,0,0,0,0,2,2,4,25,103,108,95,76,105,103,104,116,83, +111,117,114,99,101,80,97,114,97,109,101,116,101,114,115,0,1,103,108,95,76,105,103,104,116,83,111, +117,114,99,101,0,3,18,103,108,95,77,97,120,76,105,103,104,116,115,0,0,0,2,2,0,24,103,108,95,76,105, +103,104,116,77,111,100,101,108,80,97,114,97,109,101,116,101,114,115,0,12,97,109,98,105,101,110,116, +0,0,0,0,0,0,2,2,4,25,103,108,95,76,105,103,104,116,77,111,100,101,108,80,97,114,97,109,101,116,101, +114,115,0,1,103,108,95,76,105,103,104,116,77,111,100,101,108,0,0,0,2,2,0,24,103,108,95,76,105,103, +104,116,77,111,100,101,108,80,114,111,100,117,99,116,115,0,12,115,99,101,110,101,67,111,108,111, +114,0,0,0,0,0,0,2,2,4,25,103,108,95,76,105,103,104,116,77,111,100,101,108,80,114,111,100,117,99, +116,115,0,1,103,108,95,70,114,111,110,116,76,105,103,104,116,77,111,100,101,108,80,114,111,100,117, +99,116,0,0,0,2,2,4,25,103,108,95,76,105,103,104,116,77,111,100,101,108,80,114,111,100,117,99,116, +115,0,1,103,108,95,66,97,99,107,76,105,103,104,116,77,111,100,101,108,80,114,111,100,117,99,116,0, +0,0,2,2,0,24,103,108,95,76,105,103,104,116,80,114,111,100,117,99,116,115,0,12,97,109,98,105,101, +110,116,0,0,0,1,12,100,105,102,102,117,115,101,0,0,0,1,12,115,112,101,99,117,108,97,114,0,0,0,0,0, +0,2,2,4,25,103,108,95,76,105,103,104,116,80,114,111,100,117,99,116,115,0,1,103,108,95,70,114,111, +110,116,76,105,103,104,116,80,114,111,100,117,99,116,0,3,18,103,108,95,77,97,120,76,105,103,104, +116,115,0,0,0,2,2,4,25,103,108,95,76,105,103,104,116,80,114,111,100,117,99,116,115,0,1,103,108,95, +66,97,99,107,76,105,103,104,116,80,114,111,100,117,99,116,0,3,18,103,108,95,77,97,120,76,105,103, +104,116,115,0,0,0,2,2,4,12,1,103,108,95,84,101,120,116,117,114,101,69,110,118,67,111,108,111,114,0, +3,18,103,108,95,77,97,120,84,101,120,116,117,114,101,73,109,97,103,101,85,110,105,116,115,0,0,0,2, +2,4,12,1,103,108,95,69,121,101,80,108,97,110,101,83,0,3,18,103,108,95,77,97,120,84,101,120,116,117, +114,101,67,111,111,114,100,115,0,0,0,2,2,4,12,1,103,108,95,69,121,101,80,108,97,110,101,84,0,3,18, +103,108,95,77,97,120,84,101,120,116,117,114,101,67,111,111,114,100,115,0,0,0,2,2,4,12,1,103,108,95, +69,121,101,80,108,97,110,101,82,0,3,18,103,108,95,77,97,120,84,101,120,116,117,114,101,67,111,111, +114,100,115,0,0,0,2,2,4,12,1,103,108,95,69,121,101,80,108,97,110,101,81,0,3,18,103,108,95,77,97, +120,84,101,120,116,117,114,101,67,111,111,114,100,115,0,0,0,2,2,4,12,1,103,108,95,79,98,106,101,99, +116,80,108,97,110,101,83,0,3,18,103,108,95,77,97,120,84,101,120,116,117,114,101,67,111,111,114,100, +115,0,0,0,2,2,4,12,1,103,108,95,79,98,106,101,99,116,80,108,97,110,101,84,0,3,18,103,108,95,77,97, +120,84,101,120,116,117,114,101,67,111,111,114,100,115,0,0,0,2,2,4,12,1,103,108,95,79,98,106,101,99, +116,80,108,97,110,101,82,0,3,18,103,108,95,77,97,120,84,101,120,116,117,114,101,67,111,111,114,100, +115,0,0,0,2,2,4,12,1,103,108,95,79,98,106,101,99,116,80,108,97,110,101,81,0,3,18,103,108,95,77,97, +120,84,101,120,116,117,114,101,67,111,111,114,100,115,0,0,0,2,2,0,24,103,108,95,70,111,103,80,97, +114,97,109,101,116,101,114,115,0,12,99,111,108,111,114,0,0,0,1,9,100,101,110,115,105,116,121,0,0,0, +1,9,115,116,97,114,116,0,0,0,1,9,101,110,100,0,0,0,1,9,115,99,97,108,101,0,0,0,0,0,0,2,2,4,25,103, +108,95,70,111,103,80,97,114,97,109,101,116,101,114,115,0,1,103,108,95,70,111,103,0,0,0,1,0,9,0,114, +97,100,105,97,110,115,0,1,1,0,9,100,101,103,0,0,0,1,3,2,1,9,1,99,0,2,17,51,0,49,52,49,53,57,50,54, +0,0,17,49,56,48,0,48,0,0,49,0,0,4,118,101,99,52,95,109,117,108,116,105,112,108,121,0,18,95,95,114, +101,116,86,97,108,0,59,120,0,0,18,100,101,103,0,0,18,99,0,0,0,0,1,0,10,0,114,97,100,105,97,110,115, +0,1,1,0,10,100,101,103,0,0,0,1,3,2,1,9,1,99,0,2,17,51,0,49,52,49,53,57,50,54,0,0,17,49,56,48,0,48, +0,0,49,0,0,4,118,101,99,52,95,109,117,108,116,105,112,108,121,0,18,95,95,114,101,116,86,97,108,0, +59,120,121,0,0,18,100,101,103,0,59,120,121,0,0,18,99,0,59,120,120,0,0,0,0,1,0,11,0,114,97,100,105, +97,110,115,0,1,1,0,11,100,101,103,0,0,0,1,3,2,1,9,1,99,0,2,17,51,0,49,52,49,53,57,50,54,0,0,17,49, +56,48,0,48,0,0,49,0,0,4,118,101,99,52,95,109,117,108,116,105,112,108,121,0,18,95,95,114,101,116,86, +97,108,0,59,120,121,122,0,0,18,100,101,103,0,59,120,121,122,0,0,18,99,0,59,120,120,120,0,0,0,0,1,0, +12,0,114,97,100,105,97,110,115,0,1,1,0,12,100,101,103,0,0,0,1,3,2,1,9,1,99,0,2,17,51,0,49,52,49,53, +57,50,54,0,0,17,49,56,48,0,48,0,0,49,0,0,4,118,101,99,52,95,109,117,108,116,105,112,108,121,0,18, +95,95,114,101,116,86,97,108,0,0,18,100,101,103,0,0,18,99,0,59,120,120,120,120,0,0,0,0,1,0,9,0,100, +101,103,114,101,101,115,0,1,1,0,9,114,97,100,0,0,0,1,3,2,1,9,1,99,0,2,17,49,56,48,0,48,0,0,17,51,0, +49,52,49,53,57,50,54,0,0,49,0,0,4,118,101,99,52,95,109,117,108,116,105,112,108,121,0,18,95,95,114, +101,116,86,97,108,0,59,120,0,0,18,114,97,100,0,0,18,99,0,0,0,0,1,0,10,0,100,101,103,114,101,101, +115,0,1,1,0,10,114,97,100,0,0,0,1,3,2,1,9,1,99,0,2,17,51,0,49,52,49,53,57,50,54,0,0,17,49,56,48,0, +48,0,0,49,0,0,4,118,101,99,52,95,109,117,108,116,105,112,108,121,0,18,95,95,114,101,116,86,97,108, +0,59,120,121,0,0,18,114,97,100,0,59,120,121,0,0,18,99,0,59,120,120,0,0,0,0,1,0,11,0,100,101,103, +114,101,101,115,0,1,1,0,11,114,97,100,0,0,0,1,3,2,1,9,1,99,0,2,17,51,0,49,52,49,53,57,50,54,0,0,17, +49,56,48,0,48,0,0,49,0,0,4,118,101,99,52,95,109,117,108,116,105,112,108,121,0,18,95,95,114,101,116, +86,97,108,0,59,120,121,122,0,0,18,114,97,100,0,59,120,121,122,0,0,18,99,0,59,120,120,120,0,0,0,0,1, +0,12,0,100,101,103,114,101,101,115,0,1,1,0,12,114,97,100,0,0,0,1,3,2,1,9,1,99,0,2,17,51,0,49,52,49, +53,57,50,54,0,0,17,49,56,48,0,48,0,0,49,0,0,4,118,101,99,52,95,109,117,108,116,105,112,108,121,0, +18,95,95,114,101,116,86,97,108,0,0,18,114,97,100,0,0,18,99,0,59,120,120,120,120,0,0,0,0,1,0,9,0, +115,105,110,0,1,1,0,9,114,97,100,105,97,110,115,0,0,0,1,4,102,108,111,97,116,95,115,105,110,101,0, +18,95,95,114,101,116,86,97,108,0,59,120,0,0,18,114,97,100,105,97,110,115,0,0,0,0,1,0,10,0,115,105, +110,0,1,1,0,10,114,97,100,105,97,110,115,0,0,0,1,4,102,108,111,97,116,95,115,105,110,101,0,18,95, +95,114,101,116,86,97,108,0,59,120,0,0,18,114,97,100,105,97,110,115,0,59,120,0,0,0,4,102,108,111,97, +116,95,115,105,110,101,0,18,95,95,114,101,116,86,97,108,0,59,121,0,0,18,114,97,100,105,97,110,115, +0,59,121,0,0,0,0,1,0,11,0,115,105,110,0,1,1,0,11,114,97,100,105,97,110,115,0,0,0,1,4,102,108,111, +97,116,95,115,105,110,101,0,18,95,95,114,101,116,86,97,108,0,59,120,0,0,18,114,97,100,105,97,110, +115,0,59,120,0,0,0,4,102,108,111,97,116,95,115,105,110,101,0,18,95,95,114,101,116,86,97,108,0,59, +121,0,0,18,114,97,100,105,97,110,115,0,59,121,0,0,0,4,102,108,111,97,116,95,115,105,110,101,0,18, +95,95,114,101,116,86,97,108,0,59,122,0,0,18,114,97,100,105,97,110,115,0,59,122,0,0,0,0,1,0,12,0, +115,105,110,0,1,1,0,12,114,97,100,105,97,110,115,0,0,0,1,4,102,108,111,97,116,95,115,105,110,101,0, +18,95,95,114,101,116,86,97,108,0,59,120,0,0,18,114,97,100,105,97,110,115,0,59,120,0,0,0,4,102,108, +111,97,116,95,115,105,110,101,0,18,95,95,114,101,116,86,97,108,0,59,121,0,0,18,114,97,100,105,97, +110,115,0,59,121,0,0,0,4,102,108,111,97,116,95,115,105,110,101,0,18,95,95,114,101,116,86,97,108,0, +59,122,0,0,18,114,97,100,105,97,110,115,0,59,122,0,0,0,4,102,108,111,97,116,95,115,105,110,101,0, +18,95,95,114,101,116,86,97,108,0,59,119,0,0,18,114,97,100,105,97,110,115,0,59,119,0,0,0,0,1,0,9,0, +99,111,115,0,1,1,0,9,114,97,100,105,97,110,115,0,0,0,1,4,102,108,111,97,116,95,99,111,115,105,110, +101,0,18,95,95,114,101,116,86,97,108,0,59,120,0,0,18,114,97,100,105,97,110,115,0,0,0,0,1,0,10,0,99, +111,115,0,1,1,0,10,114,97,100,105,97,110,115,0,0,0,1,4,102,108,111,97,116,95,99,111,115,105,110, +101,0,18,95,95,114,101,116,86,97,108,0,59,120,0,0,18,114,97,100,105,97,110,115,0,59,120,0,0,0,4, +102,108,111,97,116,95,99,111,115,105,110,101,0,18,95,95,114,101,116,86,97,108,0,59,121,0,0,18,114, +97,100,105,97,110,115,0,59,121,0,0,0,0,1,0,11,0,99,111,115,0,1,1,0,11,114,97,100,105,97,110,115,0, +0,0,1,4,102,108,111,97,116,95,99,111,115,105,110,101,0,18,95,95,114,101,116,86,97,108,0,59,120,0,0, +18,114,97,100,105,97,110,115,0,59,120,0,0,0,4,102,108,111,97,116,95,99,111,115,105,110,101,0,18,95, +95,114,101,116,86,97,108,0,59,121,0,0,18,114,97,100,105,97,110,115,0,59,121,0,0,0,4,102,108,111,97, +116,95,99,111,115,105,110,101,0,18,95,95,114,101,116,86,97,108,0,59,122,0,0,18,114,97,100,105,97, +110,115,0,59,122,0,0,0,0,1,0,12,0,99,111,115,0,1,1,0,12,114,97,100,105,97,110,115,0,0,0,1,4,102, +108,111,97,116,95,99,111,115,105,110,101,0,18,95,95,114,101,116,86,97,108,0,59,120,0,0,18,114,97, +100,105,97,110,115,0,59,120,0,0,0,4,102,108,111,97,116,95,99,111,115,105,110,101,0,18,95,95,114, +101,116,86,97,108,0,59,121,0,0,18,114,97,100,105,97,110,115,0,59,121,0,0,0,4,102,108,111,97,116,95, +99,111,115,105,110,101,0,18,95,95,114,101,116,86,97,108,0,59,122,0,0,18,114,97,100,105,97,110,115, +0,59,122,0,0,0,4,102,108,111,97,116,95,99,111,115,105,110,101,0,18,95,95,114,101,116,86,97,108,0, +59,119,0,0,18,114,97,100,105,97,110,115,0,59,119,0,0,0,0,1,0,9,0,116,97,110,0,1,1,0,9,97,110,103, +108,101,0,0,0,1,3,2,1,9,1,115,0,2,58,115,105,110,0,18,97,110,103,108,101,0,0,0,0,0,3,2,1,9,1,99,0, +2,58,99,111,115,0,18,97,110,103,108,101,0,0,0,0,0,8,18,115,0,18,99,0,49,0,0,1,0,10,0,116,97,110,0, +1,1,0,10,97,110,103,108,101,0,0,0,1,3,2,1,10,1,115,0,2,58,115,105,110,0,18,97,110,103,108,101,0,0, +0,0,0,3,2,1,10,1,99,0,2,58,99,111,115,0,18,97,110,103,108,101,0,0,0,0,0,8,18,115,0,18,99,0,49,0,0, +1,0,11,0,116,97,110,0,1,1,0,11,97,110,103,108,101,0,0,0,1,3,2,1,11,1,115,0,2,58,115,105,110,0,18, +97,110,103,108,101,0,0,0,0,0,3,2,1,11,1,99,0,2,58,99,111,115,0,18,97,110,103,108,101,0,0,0,0,0,8, +18,115,0,18,99,0,49,0,0,1,0,12,0,116,97,110,0,1,1,0,12,97,110,103,108,101,0,0,0,1,3,2,1,12,1,115,0, +2,58,115,105,110,0,18,97,110,103,108,101,0,0,0,0,0,3,2,1,12,1,99,0,2,58,99,111,115,0,18,97,110,103, +108,101,0,0,0,0,0,8,18,115,0,18,99,0,49,0,0,1,0,9,0,97,115,105,110,0,1,0,0,9,120,0,0,0,1,3,2,0,9,1, +121,0,0,0,4,102,108,111,97,116,95,97,114,99,115,105,110,101,0,18,121,0,0,18,120,0,0,0,8,18,121,0,0, +0,1,0,10,0,97,115,105,110,0,1,0,0,10,118,0,0,0,1,8,58,118,101,99,50,0,58,97,115,105,110,0,18,118,0, +59,120,0,0,0,0,58,97,115,105,110,0,18,118,0,59,121,0,0,0,0,0,0,0,1,0,11,0,97,115,105,110,0,1,0,0, +11,118,0,0,0,1,8,58,118,101,99,51,0,58,97,115,105,110,0,18,118,0,59,120,0,0,0,0,58,97,115,105,110, +0,18,118,0,59,121,0,0,0,0,58,97,115,105,110,0,18,118,0,59,122,0,0,0,0,0,0,0,1,0,12,0,97,115,105, +110,0,1,0,0,12,118,0,0,0,1,8,58,118,101,99,52,0,58,97,115,105,110,0,18,118,0,59,120,0,0,0,0,58,97, +115,105,110,0,18,118,0,59,121,0,0,0,0,58,97,115,105,110,0,18,118,0,59,122,0,0,0,0,58,97,115,105, +110,0,18,118,0,59,119,0,0,0,0,0,0,0,1,0,9,0,97,99,111,115,0,1,0,0,9,120,0,0,0,1,8,17,49,0,53,55,48, +56,0,0,58,97,115,105,110,0,18,120,0,0,0,47,0,0,1,0,10,0,97,99,111,115,0,1,0,0,10,118,0,0,0,1,8,58, +118,101,99,50,0,58,97,99,111,115,0,18,118,0,59,120,0,0,0,0,58,97,99,111,115,0,18,118,0,59,121,0,0, +0,0,0,0,0,1,0,11,0,97,99,111,115,0,1,0,0,11,118,0,0,0,1,8,58,118,101,99,51,0,58,97,99,111,115,0,18, +118,0,59,120,0,0,0,0,58,97,99,111,115,0,18,118,0,59,121,0,0,0,0,58,97,99,111,115,0,18,118,0,59,122, +0,0,0,0,0,0,0,1,0,12,0,97,99,111,115,0,1,0,0,12,118,0,0,0,1,8,58,118,101,99,52,0,58,97,99,111,115, +0,18,118,0,59,120,0,0,0,0,58,97,99,111,115,0,18,118,0,59,121,0,0,0,0,58,97,99,111,115,0,18,118,0, +59,122,0,0,0,0,58,97,99,111,115,0,18,118,0,59,119,0,0,0,0,0,0,0,1,0,9,0,97,116,97,110,0,1,0,0,9, +121,95,111,118,101,114,95,120,0,0,0,1,3,2,0,9,1,122,0,0,0,4,102,108,111,97,116,95,97,114,99,116,97, +110,0,18,122,0,0,18,121,95,111,118,101,114,95,120,0,0,0,8,18,122,0,0,0,1,0,10,0,97,116,97,110,0,1, +0,0,10,121,95,111,118,101,114,95,120,0,0,0,1,8,58,118,101,99,50,0,58,97,116,97,110,0,18,121,95,111, +118,101,114,95,120,0,59,120,0,0,0,0,58,97,116,97,110,0,18,121,95,111,118,101,114,95,120,0,59,121,0, +0,0,0,0,0,0,1,0,11,0,97,116,97,110,0,1,0,0,11,121,95,111,118,101,114,95,120,0,0,0,1,8,58,118,101, +99,51,0,58,97,116,97,110,0,18,121,95,111,118,101,114,95,120,0,59,120,0,0,0,0,58,97,116,97,110,0,18, +121,95,111,118,101,114,95,120,0,59,121,0,0,0,0,58,97,116,97,110,0,18,121,95,111,118,101,114,95,120, +0,59,122,0,0,0,0,0,0,0,1,0,12,0,97,116,97,110,0,1,0,0,12,121,95,111,118,101,114,95,120,0,0,0,1,8, +58,118,101,99,52,0,58,97,116,97,110,0,18,121,95,111,118,101,114,95,120,0,59,120,0,0,0,0,58,97,116, +97,110,0,18,121,95,111,118,101,114,95,120,0,59,121,0,0,0,0,58,97,116,97,110,0,18,121,95,111,118, +101,114,95,120,0,59,122,0,0,0,0,58,97,116,97,110,0,18,121,95,111,118,101,114,95,120,0,59,119,0,0,0, +0,0,0,0,1,0,9,0,97,116,97,110,0,1,0,0,9,121,0,0,1,0,0,9,120,0,0,0,1,3,2,0,9,1,122,0,2,58,97,116,97, +110,0,18,121,0,18,120,0,49,0,0,0,0,10,18,120,0,17,48,0,48,0,0,40,0,2,10,18,121,0,17,48,0,48,0,0,40, +0,8,18,122,0,17,51,0,49,52,49,53,57,51,0,0,47,0,9,14,0,8,18,122,0,17,51,0,49,52,49,53,57,51,0,0,46, +0,0,9,14,0,8,18,122,0,0,0,1,0,10,0,97,116,97,110,0,1,0,0,10,117,0,0,1,0,0,10,118,0,0,0,1,8,58,118, +101,99,50,0,58,97,116,97,110,0,18,117,0,59,120,0,0,18,118,0,59,120,0,0,0,0,58,97,116,97,110,0,18, +117,0,59,121,0,0,18,118,0,59,121,0,0,0,0,0,0,0,1,0,11,0,97,116,97,110,0,1,0,0,11,117,0,0,1,0,0,11, +118,0,0,0,1,8,58,118,101,99,51,0,58,97,116,97,110,0,18,117,0,59,120,0,0,18,118,0,59,120,0,0,0,0,58, +97,116,97,110,0,18,117,0,59,121,0,0,18,118,0,59,121,0,0,0,0,58,97,116,97,110,0,18,117,0,59,122,0,0, +18,118,0,59,122,0,0,0,0,0,0,0,1,0,12,0,97,116,97,110,0,1,0,0,12,117,0,0,1,0,0,12,118,0,0,0,1,8,58, +118,101,99,52,0,58,97,116,97,110,0,18,117,0,59,120,0,0,18,118,0,59,120,0,0,0,0,58,97,116,97,110,0, 18,117,0,59,121,0,0,18,118,0,59,121,0,0,0,0,58,97,116,97,110,0,18,117,0,59,122,0,0,18,118,0,59,122, -0,0,0,0,0,0,0,1,0,12,0,97,116,97,110,0,1,0,0,12,117,0,0,1,0,0,12,118,0,0,0,1,8,58,118,101,99,52,0, -58,97,116,97,110,0,18,117,0,59,120,0,0,18,118,0,59,120,0,0,0,0,58,97,116,97,110,0,18,117,0,59,121, -0,0,18,118,0,59,121,0,0,0,0,58,97,116,97,110,0,18,117,0,59,122,0,0,18,118,0,59,122,0,0,0,0,58,97, -116,97,110,0,18,117,0,59,119,0,0,18,118,0,59,119,0,0,0,0,0,0,0,1,0,9,0,112,111,119,0,1,0,0,9,120,0, -0,1,0,0,9,121,0,0,0,1,3,2,0,9,1,112,0,0,0,4,102,108,111,97,116,95,112,111,119,101,114,0,18,112,0,0, -18,120,0,0,18,121,0,0,0,8,18,112,0,0,0,1,0,10,0,112,111,119,0,1,0,0,10,118,0,0,1,0,0,10,117,0,0,0, -1,8,58,118,101,99,50,0,58,112,111,119,0,18,118,0,59,120,0,0,18,117,0,59,120,0,0,0,0,58,112,111,119, -0,18,118,0,59,121,0,0,18,117,0,59,121,0,0,0,0,0,0,0,1,0,11,0,112,111,119,0,1,0,0,11,118,0,0,1,0,0, -11,117,0,0,0,1,8,58,118,101,99,51,0,58,112,111,119,0,18,118,0,59,120,0,0,18,117,0,59,120,0,0,0,0, -58,112,111,119,0,18,118,0,59,121,0,0,18,117,0,59,121,0,0,0,0,58,112,111,119,0,18,118,0,59,122,0,0, -18,117,0,59,122,0,0,0,0,0,0,0,1,0,12,0,112,111,119,0,1,0,0,12,118,0,0,1,0,0,12,117,0,0,0,1,8,58, -118,101,99,52,0,58,112,111,119,0,18,118,0,59,120,0,0,18,117,0,59,120,0,0,0,0,58,112,111,119,0,18, -118,0,59,121,0,0,18,117,0,59,121,0,0,0,0,58,112,111,119,0,18,118,0,59,122,0,0,18,117,0,59,122,0,0, -0,0,58,112,111,119,0,18,118,0,59,119,0,0,18,117,0,59,119,0,0,0,0,0,0,0,1,0,9,0,101,120,112,0,1,0,0, -9,120,0,0,0,1,8,58,112,111,119,0,17,50,0,55,49,56,50,56,49,56,51,0,0,0,18,120,0,0,0,0,0,1,0,10,0, -101,120,112,0,1,0,0,10,118,0,0,0,1,8,58,112,111,119,0,58,118,101,99,50,0,17,50,0,55,49,56,50,56,49, -56,51,0,0,0,0,0,18,118,0,0,0,0,0,1,0,11,0,101,120,112,0,1,0,0,11,118,0,0,0,1,8,58,112,111,119,0,58, -118,101,99,51,0,17,50,0,55,49,56,50,56,49,56,51,0,0,0,0,0,18,118,0,0,0,0,0,1,0,12,0,101,120,112,0, -1,0,0,12,118,0,0,0,1,8,58,112,111,119,0,58,118,101,99,52,0,17,50,0,55,49,56,50,56,49,56,51,0,0,0,0, -0,18,118,0,0,0,0,0,1,0,9,0,108,111,103,50,0,1,0,0,9,120,0,0,0,1,3,2,0,9,1,121,0,0,0,4,102,108,111, -97,116,95,108,111,103,50,0,18,121,0,0,18,120,0,0,0,8,18,121,0,0,0,1,0,10,0,108,111,103,50,0,1,0,0, -10,118,0,0,0,1,8,58,118,101,99,50,0,58,108,111,103,50,0,18,118,0,59,120,0,0,0,0,58,108,111,103,50, -0,18,118,0,59,121,0,0,0,0,0,0,0,1,0,11,0,108,111,103,50,0,1,0,0,11,118,0,0,0,1,8,58,118,101,99,51, -0,58,108,111,103,50,0,18,118,0,59,120,0,0,0,0,58,108,111,103,50,0,18,118,0,59,121,0,0,0,0,58,108, -111,103,50,0,18,118,0,59,122,0,0,0,0,0,0,0,1,0,12,0,108,111,103,50,0,1,0,0,12,118,0,0,0,1,8,58,118, -101,99,52,0,58,108,111,103,50,0,18,118,0,59,120,0,0,0,0,58,108,111,103,50,0,18,118,0,59,121,0,0,0, -0,58,108,111,103,50,0,18,118,0,59,122,0,0,0,0,58,108,111,103,50,0,18,118,0,59,119,0,0,0,0,0,0,0,1, -0,9,0,108,111,103,0,1,0,0,9,120,0,0,0,1,8,58,108,111,103,50,0,18,120,0,0,0,58,108,111,103,50,0,17, -50,0,55,49,56,50,56,49,56,51,0,0,0,0,49,0,0,1,0,10,0,108,111,103,0,1,0,0,10,118,0,0,0,1,8,58,108, -111,103,50,0,18,118,0,0,0,58,108,111,103,50,0,58,118,101,99,50,0,17,50,0,55,49,56,50,56,49,56,51,0, -0,0,0,0,0,49,0,0,1,0,11,0,108,111,103,0,1,0,0,11,118,0,0,0,1,8,58,108,111,103,50,0,18,118,0,0,0,58, -108,111,103,50,0,58,118,101,99,51,0,17,50,0,55,49,56,50,56,49,56,51,0,0,0,0,0,0,49,0,0,1,0,12,0, -108,111,103,0,1,0,0,12,118,0,0,0,1,8,58,108,111,103,50,0,18,118,0,0,0,58,108,111,103,50,0,58,118, -101,99,52,0,17,50,0,55,49,56,50,56,49,56,51,0,0,0,0,0,0,49,0,0,1,0,9,0,101,120,112,50,0,1,0,0,9, -120,0,0,0,1,8,58,112,111,119,0,17,50,0,48,0,0,0,18,120,0,0,0,0,0,1,0,10,0,101,120,112,50,0,1,0,0, -10,118,0,0,0,1,8,58,112,111,119,0,58,118,101,99,50,0,17,50,0,48,0,0,0,0,0,18,118,0,0,0,0,0,1,0,11, -0,101,120,112,50,0,1,0,0,11,118,0,0,0,1,8,58,112,111,119,0,58,118,101,99,51,0,17,50,0,48,0,0,0,0,0, -18,118,0,0,0,0,0,1,0,12,0,101,120,112,50,0,1,0,0,12,118,0,0,0,1,8,58,112,111,119,0,58,118,101,99, -52,0,17,50,0,48,0,0,0,0,0,18,118,0,0,0,0,0,1,0,9,0,115,113,114,116,0,1,0,0,9,120,0,0,0,1,8,58,112, -111,119,0,18,120,0,0,17,48,0,53,0,0,0,0,0,0,1,0,10,0,115,113,114,116,0,1,0,0,10,118,0,0,0,1,8,58, -112,111,119,0,18,118,0,0,58,118,101,99,50,0,17,48,0,53,0,0,0,0,0,0,0,0,1,0,11,0,115,113,114,116,0, -1,0,0,11,118,0,0,0,1,8,58,112,111,119,0,18,118,0,0,58,118,101,99,51,0,17,48,0,53,0,0,0,0,0,0,0,0,1, -0,12,0,115,113,114,116,0,1,0,0,12,118,0,0,0,1,8,58,112,111,119,0,18,118,0,0,58,118,101,99,52,0,17, -48,0,53,0,0,0,0,0,0,0,0,1,0,9,0,105,110,118,101,114,115,101,115,113,114,116,0,1,0,0,9,120,0,0,0,1, -8,17,49,0,48,0,0,58,115,113,114,116,0,18,120,0,0,0,49,0,0,1,0,10,0,105,110,118,101,114,115,101,115, -113,114,116,0,1,0,0,10,118,0,0,0,1,8,58,118,101,99,50,0,17,49,0,48,0,0,0,0,58,115,113,114,116,0,18, -118,0,0,0,49,0,0,1,0,11,0,105,110,118,101,114,115,101,115,113,114,116,0,1,0,0,11,118,0,0,0,1,8,58, -118,101,99,51,0,17,49,0,48,0,0,0,0,58,115,113,114,116,0,18,118,0,0,0,49,0,0,1,0,12,0,105,110,118, -101,114,115,101,115,113,114,116,0,1,0,0,12,118,0,0,0,1,8,58,118,101,99,52,0,17,49,0,48,0,0,0,0,58, -115,113,114,116,0,18,118,0,0,0,49,0,0,1,0,9,0,97,98,115,0,1,0,0,9,120,0,0,0,1,8,18,120,0,17,48,0, -48,0,0,43,18,120,0,18,120,0,54,31,0,0,1,0,10,0,97,98,115,0,1,0,0,10,118,0,0,0,1,8,58,118,101,99,50, -0,58,97,98,115,0,18,118,0,59,120,0,0,0,0,58,97,98,115,0,18,118,0,59,121,0,0,0,0,0,0,0,1,0,11,0,97, -98,115,0,1,0,0,11,118,0,0,0,1,8,58,118,101,99,51,0,58,97,98,115,0,18,118,0,59,120,0,0,0,0,58,97,98, -115,0,18,118,0,59,121,0,0,0,0,58,97,98,115,0,18,118,0,59,122,0,0,0,0,0,0,0,1,0,12,0,97,98,115,0,1, -0,0,12,118,0,0,0,1,8,58,118,101,99,52,0,58,97,98,115,0,18,118,0,59,120,0,0,0,0,58,97,98,115,0,18, -118,0,59,121,0,0,0,0,58,97,98,115,0,18,118,0,59,122,0,0,0,0,58,97,98,115,0,18,118,0,59,119,0,0,0,0, -0,0,0,1,0,9,0,115,105,103,110,0,1,0,0,9,120,0,0,0,1,8,18,120,0,17,48,0,48,0,0,41,17,49,0,48,0,0,18, -120,0,17,48,0,48,0,0,40,17,49,0,48,0,0,54,17,48,0,48,0,0,31,31,0,0,1,0,10,0,115,105,103,110,0,1,0, -0,10,118,0,0,0,1,8,58,118,101,99,50,0,58,115,105,103,110,0,18,118,0,59,120,0,0,0,0,58,115,105,103, -110,0,18,118,0,59,121,0,0,0,0,0,0,0,1,0,11,0,115,105,103,110,0,1,0,0,11,118,0,0,0,1,8,58,118,101, -99,51,0,58,115,105,103,110,0,18,118,0,59,120,0,0,0,0,58,115,105,103,110,0,18,118,0,59,121,0,0,0,0, -58,115,105,103,110,0,18,118,0,59,122,0,0,0,0,0,0,0,1,0,12,0,115,105,103,110,0,1,0,0,12,118,0,0,0,1, -8,58,118,101,99,52,0,58,115,105,103,110,0,18,118,0,59,120,0,0,0,0,58,115,105,103,110,0,18,118,0,59, -121,0,0,0,0,58,115,105,103,110,0,18,118,0,59,122,0,0,0,0,58,115,105,103,110,0,18,118,0,59,119,0,0, -0,0,0,0,0,1,0,9,0,102,108,111,111,114,0,1,0,0,9,120,0,0,0,1,3,2,0,9,1,121,0,0,0,4,102,108,111,97, -116,95,102,108,111,111,114,0,18,121,0,0,18,120,0,0,0,8,18,121,0,0,0,1,0,10,0,102,108,111,111,114,0, -1,0,0,10,118,0,0,0,1,8,58,118,101,99,50,0,58,102,108,111,111,114,0,18,118,0,59,120,0,0,0,0,58,102, -108,111,111,114,0,18,118,0,59,121,0,0,0,0,0,0,0,1,0,11,0,102,108,111,111,114,0,1,0,0,11,118,0,0,0, -1,8,58,118,101,99,51,0,58,102,108,111,111,114,0,18,118,0,59,120,0,0,0,0,58,102,108,111,111,114,0, -18,118,0,59,121,0,0,0,0,58,102,108,111,111,114,0,18,118,0,59,122,0,0,0,0,0,0,0,1,0,12,0,102,108, -111,111,114,0,1,0,0,12,118,0,0,0,1,8,58,118,101,99,52,0,58,102,108,111,111,114,0,18,118,0,59,120,0, -0,0,0,58,102,108,111,111,114,0,18,118,0,59,121,0,0,0,0,58,102,108,111,111,114,0,18,118,0,59,122,0, -0,0,0,58,102,108,111,111,114,0,18,118,0,59,119,0,0,0,0,0,0,0,1,0,9,0,99,101,105,108,0,1,0,0,9,120, -0,0,0,1,3,2,0,9,1,121,0,0,0,4,102,108,111,97,116,95,99,101,105,108,0,18,121,0,0,18,120,0,0,0,8,18, -121,0,0,0,1,0,10,0,99,101,105,108,0,1,0,0,10,118,0,0,0,1,8,58,118,101,99,50,0,58,99,101,105,108,0, -18,118,0,59,120,0,0,0,0,58,99,101,105,108,0,18,118,0,59,121,0,0,0,0,0,0,0,1,0,11,0,99,101,105,108, -0,1,0,0,11,118,0,0,0,1,8,58,118,101,99,51,0,58,99,101,105,108,0,18,118,0,59,120,0,0,0,0,58,99,101, -105,108,0,18,118,0,59,121,0,0,0,0,58,99,101,105,108,0,18,118,0,59,122,0,0,0,0,0,0,0,1,0,12,0,99, -101,105,108,0,1,0,0,12,118,0,0,0,1,8,58,118,101,99,52,0,58,99,101,105,108,0,18,118,0,59,120,0,0,0, -0,58,99,101,105,108,0,18,118,0,59,121,0,0,0,0,58,99,101,105,108,0,18,118,0,59,122,0,0,0,0,58,99, -101,105,108,0,18,118,0,59,119,0,0,0,0,0,0,0,1,0,9,0,102,114,97,99,116,0,1,0,0,9,120,0,0,0,1,8,18, -120,0,58,102,108,111,111,114,0,18,120,0,0,0,47,0,0,1,0,10,0,102,114,97,99,116,0,1,0,0,10,118,0,0,0, -1,8,18,118,0,58,102,108,111,111,114,0,18,118,0,0,0,47,0,0,1,0,11,0,102,114,97,99,116,0,1,0,0,11, -118,0,0,0,1,8,18,118,0,58,102,108,111,111,114,0,18,118,0,0,0,47,0,0,1,0,12,0,102,114,97,99,116,0,1, -0,0,12,118,0,0,0,1,8,18,118,0,58,102,108,111,111,114,0,18,118,0,0,0,47,0,0,1,0,9,0,109,111,100,0,1, -0,0,9,120,0,0,1,0,0,9,121,0,0,0,1,8,18,120,0,18,121,0,58,102,108,111,111,114,0,18,120,0,18,121,0, -49,0,0,48,47,0,0,1,0,10,0,109,111,100,0,1,0,0,10,118,0,0,1,0,0,9,117,0,0,0,1,8,18,118,0,18,117,0, -58,102,108,111,111,114,0,18,118,0,18,117,0,49,0,0,48,47,0,0,1,0,11,0,109,111,100,0,1,0,0,11,118,0, -0,1,0,0,9,117,0,0,0,1,8,18,118,0,18,117,0,58,102,108,111,111,114,0,18,118,0,18,117,0,49,0,0,48,47, -0,0,1,0,12,0,109,111,100,0,1,0,0,12,118,0,0,1,0,0,9,117,0,0,0,1,8,18,118,0,18,117,0,58,102,108,111, -111,114,0,18,118,0,18,117,0,49,0,0,48,47,0,0,1,0,10,0,109,111,100,0,1,0,0,10,118,0,0,1,0,0,10,117, -0,0,0,1,8,18,118,0,18,117,0,58,102,108,111,111,114,0,18,118,0,18,117,0,49,0,0,48,47,0,0,1,0,11,0, -109,111,100,0,1,0,0,11,118,0,0,1,0,0,11,117,0,0,0,1,8,18,118,0,18,117,0,58,102,108,111,111,114,0, -18,118,0,18,117,0,49,0,0,48,47,0,0,1,0,12,0,109,111,100,0,1,0,0,12,118,0,0,1,0,0,12,117,0,0,0,1,8, -18,118,0,18,117,0,58,102,108,111,111,114,0,18,118,0,18,117,0,49,0,0,48,47,0,0,1,0,9,0,109,105,110, -0,1,0,0,9,120,0,0,1,0,0,9,121,0,0,0,1,8,18,120,0,18,121,0,40,18,120,0,18,121,0,31,0,0,1,0,10,0,109, -105,110,0,1,0,0,10,118,0,0,1,0,0,10,117,0,0,0,1,8,58,118,101,99,50,0,58,109,105,110,0,18,118,0,59, -120,0,0,18,117,0,59,120,0,0,0,0,58,109,105,110,0,18,118,0,59,121,0,0,18,117,0,59,121,0,0,0,0,0,0,0, -1,0,11,0,109,105,110,0,1,0,0,11,118,0,0,1,0,0,11,117,0,0,0,1,8,58,118,101,99,51,0,58,109,105,110,0, -18,118,0,59,120,0,0,18,117,0,59,120,0,0,0,0,58,109,105,110,0,18,118,0,59,121,0,0,18,117,0,59,121,0, -0,0,0,58,109,105,110,0,18,118,0,59,122,0,0,18,117,0,59,122,0,0,0,0,0,0,0,1,0,12,0,109,105,110,0,1, -0,0,12,118,0,0,1,0,0,12,117,0,0,0,1,8,58,118,101,99,52,0,58,109,105,110,0,18,118,0,59,120,0,0,18, -117,0,59,120,0,0,0,0,58,109,105,110,0,18,118,0,59,121,0,0,18,117,0,59,121,0,0,0,0,58,109,105,110,0, -18,118,0,59,122,0,0,18,117,0,59,122,0,0,0,0,58,109,105,110,0,18,118,0,59,119,0,0,18,117,0,59,119,0, -0,0,0,0,0,0,1,0,10,0,109,105,110,0,1,0,0,10,118,0,0,1,0,0,9,121,0,0,0,1,8,58,109,105,110,0,18,118, -0,0,58,118,101,99,50,0,18,121,0,0,0,0,0,0,0,1,0,11,0,109,105,110,0,1,0,0,11,118,0,0,1,0,0,9,121,0, -0,0,1,8,58,109,105,110,0,18,118,0,0,58,118,101,99,51,0,18,121,0,0,0,0,0,0,0,1,0,12,0,109,105,110,0, -1,0,0,12,118,0,0,1,0,0,9,121,0,0,0,1,8,58,109,105,110,0,18,118,0,0,58,118,101,99,52,0,18,121,0,0,0, -0,0,0,0,1,0,9,0,109,97,120,0,1,0,0,9,120,0,0,1,0,0,9,121,0,0,0,1,8,18,120,0,18,121,0,40,18,121,0, -18,120,0,31,0,0,1,0,10,0,109,97,120,0,1,0,0,10,118,0,0,1,0,0,10,117,0,0,0,1,8,58,118,101,99,50,0, -58,109,97,120,0,18,118,0,59,120,0,0,18,117,0,59,120,0,0,0,0,58,109,97,120,0,18,118,0,59,121,0,0,18, -117,0,59,121,0,0,0,0,0,0,0,1,0,11,0,109,97,120,0,1,0,0,11,118,0,0,1,0,0,11,117,0,0,0,1,8,58,118, -101,99,51,0,58,109,97,120,0,18,118,0,59,120,0,0,18,117,0,59,120,0,0,0,0,58,109,97,120,0,18,118,0, -59,121,0,0,18,117,0,59,121,0,0,0,0,58,109,97,120,0,18,118,0,59,122,0,0,18,117,0,59,122,0,0,0,0,0,0, -0,1,0,12,0,109,97,120,0,1,0,0,12,118,0,0,1,0,0,12,117,0,0,0,1,8,58,118,101,99,52,0,58,109,97,120,0, -18,118,0,59,120,0,0,18,117,0,59,120,0,0,0,0,58,109,97,120,0,18,118,0,59,121,0,0,18,117,0,59,121,0, -0,0,0,58,109,97,120,0,18,118,0,59,122,0,0,18,117,0,59,122,0,0,0,0,58,109,97,120,0,18,118,0,59,119, -0,0,18,117,0,59,119,0,0,0,0,0,0,0,1,0,10,0,109,97,120,0,1,0,0,10,118,0,0,1,0,0,9,121,0,0,0,1,8,58, -109,97,120,0,18,118,0,0,58,118,101,99,50,0,18,121,0,0,0,0,0,0,0,1,0,11,0,109,97,120,0,1,0,0,11,118, -0,0,1,0,0,9,121,0,0,0,1,8,58,109,97,120,0,18,118,0,0,58,118,101,99,51,0,18,121,0,0,0,0,0,0,0,1,0, -12,0,109,97,120,0,1,0,0,12,118,0,0,1,0,0,9,121,0,0,0,1,8,58,109,97,120,0,18,118,0,0,58,118,101,99, -52,0,18,121,0,0,0,0,0,0,0,1,0,9,0,99,108,97,109,112,0,1,0,0,9,120,0,0,1,0,0,9,109,105,110,86,97, -108,0,0,1,0,0,9,109,97,120,86,97,108,0,0,0,1,8,58,109,105,110,0,58,109,97,120,0,18,120,0,0,18,109, -105,110,86,97,108,0,0,0,0,18,109,97,120,86,97,108,0,0,0,0,0,1,0,10,0,99,108,97,109,112,0,1,0,0,10, -120,0,0,1,0,0,9,109,105,110,86,97,108,0,0,1,0,0,9,109,97,120,86,97,108,0,0,0,1,8,58,109,105,110,0, -58,109,97,120,0,18,120,0,0,18,109,105,110,86,97,108,0,0,0,0,18,109,97,120,86,97,108,0,0,0,0,0,1,0, -11,0,99,108,97,109,112,0,1,0,0,11,120,0,0,1,0,0,9,109,105,110,86,97,108,0,0,1,0,0,9,109,97,120,86, -97,108,0,0,0,1,8,58,109,105,110,0,58,109,97,120,0,18,120,0,0,18,109,105,110,86,97,108,0,0,0,0,18, -109,97,120,86,97,108,0,0,0,0,0,1,0,12,0,99,108,97,109,112,0,1,0,0,12,120,0,0,1,0,0,9,109,105,110, -86,97,108,0,0,1,0,0,9,109,97,120,86,97,108,0,0,0,1,8,58,109,105,110,0,58,109,97,120,0,18,120,0,0, -18,109,105,110,86,97,108,0,0,0,0,18,109,97,120,86,97,108,0,0,0,0,0,1,0,10,0,99,108,97,109,112,0,1, -0,0,10,120,0,0,1,0,0,10,109,105,110,86,97,108,0,0,1,0,0,10,109,97,120,86,97,108,0,0,0,1,8,58,109, -105,110,0,58,109,97,120,0,18,120,0,0,18,109,105,110,86,97,108,0,0,0,0,18,109,97,120,86,97,108,0,0, -0,0,0,1,0,11,0,99,108,97,109,112,0,1,0,0,11,120,0,0,1,0,0,11,109,105,110,86,97,108,0,0,1,0,0,11, -109,97,120,86,97,108,0,0,0,1,8,58,109,105,110,0,58,109,97,120,0,18,120,0,0,18,109,105,110,86,97, -108,0,0,0,0,18,109,97,120,86,97,108,0,0,0,0,0,1,0,12,0,99,108,97,109,112,0,1,0,0,12,120,0,0,1,0,0, -12,109,105,110,86,97,108,0,0,1,0,0,12,109,97,120,86,97,108,0,0,0,1,8,58,109,105,110,0,58,109,97, -120,0,18,120,0,0,18,109,105,110,86,97,108,0,0,0,0,18,109,97,120,86,97,108,0,0,0,0,0,1,0,9,0,109, -105,120,0,1,0,0,9,120,0,0,1,0,0,9,121,0,0,1,0,0,9,97,0,0,0,1,8,18,120,0,17,49,0,48,0,0,18,97,0,47, -48,18,121,0,18,97,0,48,46,0,0,1,0,10,0,109,105,120,0,1,0,0,10,120,0,0,1,0,0,10,121,0,0,1,0,0,9,97, -0,0,0,1,8,18,120,0,17,49,0,48,0,0,18,97,0,47,48,18,121,0,18,97,0,48,46,0,0,1,0,11,0,109,105,120,0, -1,0,0,11,120,0,0,1,0,0,11,121,0,0,1,0,0,9,97,0,0,0,1,8,18,120,0,17,49,0,48,0,0,18,97,0,47,48,18, -121,0,18,97,0,48,46,0,0,1,0,12,0,109,105,120,0,1,0,0,12,120,0,0,1,0,0,12,121,0,0,1,0,0,9,97,0,0,0, -1,8,18,120,0,17,49,0,48,0,0,18,97,0,47,48,18,121,0,18,97,0,48,46,0,0,1,0,10,0,109,105,120,0,1,0,0, -10,120,0,0,1,0,0,10,121,0,0,1,0,0,10,97,0,0,0,1,8,18,120,0,17,49,0,48,0,0,18,97,0,47,48,18,121,0, -18,97,0,48,46,0,0,1,0,11,0,109,105,120,0,1,0,0,11,120,0,0,1,0,0,11,121,0,0,1,0,0,11,97,0,0,0,1,8, -18,120,0,17,49,0,48,0,0,18,97,0,47,48,18,121,0,18,97,0,48,46,0,0,1,0,12,0,109,105,120,0,1,0,0,12, -120,0,0,1,0,0,12,121,0,0,1,0,0,12,97,0,0,0,1,8,18,120,0,17,49,0,48,0,0,18,97,0,47,48,18,121,0,18, -97,0,48,46,0,0,1,0,9,0,115,116,101,112,0,1,0,0,9,101,100,103,101,0,0,1,0,0,9,120,0,0,0,1,8,18,120, -0,18,101,100,103,101,0,40,17,48,0,48,0,0,17,49,0,48,0,0,31,0,0,1,0,10,0,115,116,101,112,0,1,0,0,10, -101,100,103,101,0,0,1,0,0,10,118,0,0,0,1,8,58,118,101,99,50,0,58,115,116,101,112,0,18,101,100,103, -101,0,59,120,0,0,18,118,0,59,120,0,0,0,0,58,115,116,101,112,0,18,101,100,103,101,0,59,121,0,0,18, -118,0,59,121,0,0,0,0,0,0,0,1,0,11,0,115,116,101,112,0,1,0,0,11,101,100,103,101,0,0,1,0,0,11,118,0, -0,0,1,8,58,118,101,99,51,0,58,115,116,101,112,0,18,101,100,103,101,0,59,120,0,0,18,118,0,59,120,0, -0,0,0,58,115,116,101,112,0,18,101,100,103,101,0,59,121,0,0,18,118,0,59,121,0,0,0,0,58,115,116,101, -112,0,18,101,100,103,101,0,59,122,0,0,18,118,0,59,122,0,0,0,0,0,0,0,1,0,12,0,115,116,101,112,0,1,0, -0,12,101,100,103,101,0,0,1,0,0,12,118,0,0,0,1,8,58,118,101,99,52,0,58,115,116,101,112,0,18,101,100, -103,101,0,59,120,0,0,18,118,0,59,120,0,0,0,0,58,115,116,101,112,0,18,101,100,103,101,0,59,121,0,0, -18,118,0,59,121,0,0,0,0,58,115,116,101,112,0,18,101,100,103,101,0,59,122,0,0,18,118,0,59,122,0,0,0, -0,58,115,116,101,112,0,18,101,100,103,101,0,59,119,0,0,18,118,0,59,119,0,0,0,0,0,0,0,1,0,10,0,115, -116,101,112,0,1,0,0,9,101,100,103,101,0,0,1,0,0,10,118,0,0,0,1,8,58,115,116,101,112,0,58,118,101, -99,50,0,18,101,100,103,101,0,0,0,0,18,118,0,0,0,0,0,1,0,11,0,115,116,101,112,0,1,0,0,9,101,100,103, -101,0,0,1,0,0,11,118,0,0,0,1,8,58,115,116,101,112,0,58,118,101,99,51,0,18,101,100,103,101,0,0,0,0, -18,118,0,0,0,0,0,1,0,12,0,115,116,101,112,0,1,0,0,9,101,100,103,101,0,0,1,0,0,12,118,0,0,0,1,8,58, -115,116,101,112,0,58,118,101,99,52,0,18,101,100,103,101,0,0,0,0,18,118,0,0,0,0,0,1,0,9,0,115,109, -111,111,116,104,115,116,101,112,0,1,0,0,9,101,100,103,101,48,0,0,1,0,0,9,101,100,103,101,49,0,0,1, -0,0,9,120,0,0,0,1,3,2,0,9,1,116,0,2,58,99,108,97,109,112,0,18,120,0,18,101,100,103,101,48,0,47,18, -101,100,103,101,49,0,18,101,100,103,101,48,0,47,49,0,17,48,0,48,0,0,0,17,49,0,48,0,0,0,0,0,0,8,18, -116,0,18,116,0,48,17,51,0,48,0,0,17,50,0,48,0,0,18,116,0,48,47,48,0,0,1,0,10,0,115,109,111,111,116, -104,115,116,101,112,0,1,0,0,10,101,100,103,101,48,0,0,1,0,0,10,101,100,103,101,49,0,0,1,0,0,10,118, -0,0,0,1,8,58,118,101,99,50,0,58,115,109,111,111,116,104,115,116,101,112,0,18,101,100,103,101,48,0, -59,120,0,0,18,101,100,103,101,49,0,59,120,0,0,18,118,0,59,120,0,0,0,0,58,115,109,111,111,116,104, -115,116,101,112,0,18,101,100,103,101,48,0,59,121,0,0,18,101,100,103,101,49,0,59,121,0,0,18,118,0, -59,121,0,0,0,0,0,0,0,1,0,11,0,115,109,111,111,116,104,115,116,101,112,0,1,0,0,11,101,100,103,101, -48,0,0,1,0,0,11,101,100,103,101,49,0,0,1,0,0,11,118,0,0,0,1,8,58,118,101,99,51,0,58,115,109,111, -111,116,104,115,116,101,112,0,18,101,100,103,101,48,0,59,120,0,0,18,101,100,103,101,49,0,59,120,0, -0,18,118,0,59,120,0,0,0,0,58,115,109,111,111,116,104,115,116,101,112,0,18,101,100,103,101,48,0,59, -121,0,0,18,101,100,103,101,49,0,59,121,0,0,18,118,0,59,121,0,0,0,0,58,115,109,111,111,116,104,115, -116,101,112,0,18,101,100,103,101,48,0,59,122,0,0,18,101,100,103,101,49,0,59,122,0,0,18,118,0,59, -122,0,0,0,0,0,0,0,1,0,12,0,115,109,111,111,116,104,115,116,101,112,0,1,0,0,12,101,100,103,101,48,0, -0,1,0,0,12,101,100,103,101,49,0,0,1,0,0,12,118,0,0,0,1,8,58,118,101,99,52,0,58,115,109,111,111,116, -104,115,116,101,112,0,18,101,100,103,101,48,0,59,120,0,0,18,101,100,103,101,49,0,59,120,0,0,18,118, -0,59,120,0,0,0,0,58,115,109,111,111,116,104,115,116,101,112,0,18,101,100,103,101,48,0,59,121,0,0, -18,101,100,103,101,49,0,59,121,0,0,18,118,0,59,121,0,0,0,0,58,115,109,111,111,116,104,115,116,101, -112,0,18,101,100,103,101,48,0,59,122,0,0,18,101,100,103,101,49,0,59,122,0,0,18,118,0,59,122,0,0,0, -0,58,115,109,111,111,116,104,115,116,101,112,0,18,101,100,103,101,48,0,59,119,0,0,18,101,100,103, -101,49,0,59,119,0,0,18,118,0,59,119,0,0,0,0,0,0,0,1,0,10,0,115,109,111,111,116,104,115,116,101,112, -0,1,0,0,9,101,100,103,101,48,0,0,1,0,0,9,101,100,103,101,49,0,0,1,0,0,10,118,0,0,0,1,8,58,118,101, -99,50,0,58,115,109,111,111,116,104,115,116,101,112,0,18,101,100,103,101,48,0,0,18,101,100,103,101, -49,0,0,18,118,0,59,120,0,0,0,0,58,115,109,111,111,116,104,115,116,101,112,0,18,101,100,103,101,48, -0,0,18,101,100,103,101,49,0,0,18,118,0,59,121,0,0,0,0,0,0,0,1,0,11,0,115,109,111,111,116,104,115, -116,101,112,0,1,0,0,9,101,100,103,101,48,0,0,1,0,0,9,101,100,103,101,49,0,0,1,0,0,11,118,0,0,0,1,8, -58,118,101,99,51,0,58,115,109,111,111,116,104,115,116,101,112,0,18,101,100,103,101,48,0,0,18,101, -100,103,101,49,0,0,18,118,0,59,120,0,0,0,0,58,115,109,111,111,116,104,115,116,101,112,0,18,101,100, -103,101,48,0,0,18,101,100,103,101,49,0,0,18,118,0,59,121,0,0,0,0,58,115,109,111,111,116,104,115, -116,101,112,0,18,101,100,103,101,48,0,0,18,101,100,103,101,49,0,0,18,118,0,59,122,0,0,0,0,0,0,0,1, -0,12,0,115,109,111,111,116,104,115,116,101,112,0,1,0,0,9,101,100,103,101,48,0,0,1,0,0,9,101,100, -103,101,49,0,0,1,0,0,12,118,0,0,0,1,8,58,118,101,99,52,0,58,115,109,111,111,116,104,115,116,101, -112,0,18,101,100,103,101,48,0,0,18,101,100,103,101,49,0,0,18,118,0,59,120,0,0,0,0,58,115,109,111, -111,116,104,115,116,101,112,0,18,101,100,103,101,48,0,0,18,101,100,103,101,49,0,0,18,118,0,59,121, -0,0,0,0,58,115,109,111,111,116,104,115,116,101,112,0,18,101,100,103,101,48,0,0,18,101,100,103,101, -49,0,0,18,118,0,59,122,0,0,0,0,58,115,109,111,111,116,104,115,116,101,112,0,18,101,100,103,101,48, -0,0,18,101,100,103,101,49,0,0,18,118,0,59,119,0,0,0,0,0,0,0,1,0,9,0,100,111,116,0,1,0,0,9,120,0,0, -1,0,0,9,121,0,0,0,1,8,18,120,0,18,121,0,48,0,0,1,0,9,0,100,111,116,0,1,0,0,10,118,0,0,1,0,0,10,117, -0,0,0,1,8,18,118,0,59,120,0,18,117,0,59,120,0,48,18,118,0,59,121,0,18,117,0,59,121,0,48,46,0,0,1,0, -9,0,100,111,116,0,1,0,0,11,118,0,0,1,0,0,11,117,0,0,0,1,8,18,118,0,59,120,0,18,117,0,59,120,0,48, -18,118,0,59,121,0,18,117,0,59,121,0,48,46,18,118,0,59,122,0,18,117,0,59,122,0,48,46,0,0,1,0,9,0, -100,111,116,0,1,0,0,12,118,0,0,1,0,0,12,117,0,0,0,1,8,18,118,0,59,120,0,18,117,0,59,120,0,48,18, -118,0,59,121,0,18,117,0,59,121,0,48,46,18,118,0,59,122,0,18,117,0,59,122,0,48,46,18,118,0,59,119,0, -18,117,0,59,119,0,48,46,0,0,1,0,9,0,108,101,110,103,116,104,0,1,0,0,9,120,0,0,0,1,8,58,115,113,114, -116,0,58,100,111,116,0,18,120,0,0,18,120,0,0,0,0,0,0,0,1,0,9,0,108,101,110,103,116,104,0,1,0,0,10, -118,0,0,0,1,8,58,115,113,114,116,0,58,100,111,116,0,18,118,0,0,18,118,0,0,0,0,0,0,0,1,0,9,0,108, -101,110,103,116,104,0,1,0,0,11,118,0,0,0,1,8,58,115,113,114,116,0,58,100,111,116,0,18,118,0,0,18, -118,0,0,0,0,0,0,0,1,0,9,0,108,101,110,103,116,104,0,1,0,0,12,118,0,0,0,1,8,58,115,113,114,116,0,58, -100,111,116,0,18,118,0,0,18,118,0,0,0,0,0,0,0,1,0,9,0,100,105,115,116,97,110,99,101,0,1,0,0,9,120, -0,0,1,0,0,9,121,0,0,0,1,8,58,108,101,110,103,116,104,0,18,120,0,18,121,0,47,0,0,0,0,1,0,9,0,100, -105,115,116,97,110,99,101,0,1,0,0,10,118,0,0,1,0,0,10,117,0,0,0,1,8,58,108,101,110,103,116,104,0, -18,118,0,18,117,0,47,0,0,0,0,1,0,9,0,100,105,115,116,97,110,99,101,0,1,0,0,11,118,0,0,1,0,0,11,117, -0,0,0,1,8,58,108,101,110,103,116,104,0,18,118,0,18,117,0,47,0,0,0,0,1,0,9,0,100,105,115,116,97,110, -99,101,0,1,0,0,12,118,0,0,1,0,0,12,117,0,0,0,1,8,58,108,101,110,103,116,104,0,18,118,0,18,117,0,47, -0,0,0,0,1,0,11,0,99,114,111,115,115,0,1,0,0,11,118,0,0,1,0,0,11,117,0,0,0,1,8,58,118,101,99,51,0, -18,118,0,59,121,0,18,117,0,59,122,0,48,18,117,0,59,121,0,18,118,0,59,122,0,48,47,0,18,118,0,59,122, -0,18,117,0,59,120,0,48,18,117,0,59,122,0,18,118,0,59,120,0,48,47,0,18,118,0,59,120,0,18,117,0,59, -121,0,48,18,117,0,59,120,0,18,118,0,59,121,0,48,47,0,0,0,0,1,0,9,0,110,111,114,109,97,108,105,122, -101,0,1,0,0,9,120,0,0,0,1,8,17,49,0,48,0,0,0,0,1,0,10,0,110,111,114,109,97,108,105,122,101,0,1,0,0, -10,118,0,0,0,1,8,18,118,0,58,108,101,110,103,116,104,0,18,118,0,0,0,49,0,0,1,0,11,0,110,111,114, -109,97,108,105,122,101,0,1,0,0,11,118,0,0,0,1,8,18,118,0,58,108,101,110,103,116,104,0,18,118,0,0,0, -49,0,0,1,0,12,0,110,111,114,109,97,108,105,122,101,0,1,0,0,12,118,0,0,0,1,8,18,118,0,58,108,101, -110,103,116,104,0,18,118,0,0,0,49,0,0,1,0,9,0,102,97,99,101,102,111,114,119,97,114,100,0,1,0,0,9, -78,0,0,1,0,0,9,73,0,0,1,0,0,9,78,114,101,102,0,0,0,1,8,58,100,111,116,0,18,78,114,101,102,0,0,18, -73,0,0,0,17,48,0,48,0,0,40,18,78,0,18,78,0,54,31,0,0,1,0,10,0,102,97,99,101,102,111,114,119,97,114, -100,0,1,0,0,10,78,0,0,1,0,0,10,73,0,0,1,0,0,10,78,114,101,102,0,0,0,1,8,58,100,111,116,0,18,78,114, -101,102,0,0,18,73,0,0,0,17,48,0,48,0,0,40,18,78,0,18,78,0,54,31,0,0,1,0,11,0,102,97,99,101,102,111, -114,119,97,114,100,0,1,0,0,11,78,0,0,1,0,0,11,73,0,0,1,0,0,11,78,114,101,102,0,0,0,1,8,58,100,111, -116,0,18,78,114,101,102,0,0,18,73,0,0,0,17,48,0,48,0,0,40,18,78,0,18,78,0,54,31,0,0,1,0,12,0,102, -97,99,101,102,111,114,119,97,114,100,0,1,0,0,12,78,0,0,1,0,0,12,73,0,0,1,0,0,12,78,114,101,102,0,0, -0,1,8,58,100,111,116,0,18,78,114,101,102,0,0,18,73,0,0,0,17,48,0,48,0,0,40,18,78,0,18,78,0,54,31,0, -0,1,0,9,0,114,101,102,108,101,99,116,0,1,0,0,9,73,0,0,1,0,0,9,78,0,0,0,1,8,18,73,0,17,50,0,48,0,0, -58,100,111,116,0,18,78,0,0,18,73,0,0,0,48,18,78,0,48,47,0,0,1,0,10,0,114,101,102,108,101,99,116,0, -1,0,0,10,73,0,0,1,0,0,10,78,0,0,0,1,8,18,73,0,17,50,0,48,0,0,58,100,111,116,0,18,78,0,0,18,73,0,0, -0,48,18,78,0,48,47,0,0,1,0,11,0,114,101,102,108,101,99,116,0,1,0,0,11,73,0,0,1,0,0,11,78,0,0,0,1,8, -18,73,0,17,50,0,48,0,0,58,100,111,116,0,18,78,0,0,18,73,0,0,0,48,18,78,0,48,47,0,0,1,0,12,0,114, -101,102,108,101,99,116,0,1,0,0,12,73,0,0,1,0,0,12,78,0,0,0,1,8,18,73,0,17,50,0,48,0,0,58,100,111, -116,0,18,78,0,0,18,73,0,0,0,48,18,78,0,48,47,0,0,1,0,9,0,114,101,102,114,97,99,116,0,1,0,0,9,73,0, -0,1,0,0,9,78,0,0,1,0,0,9,101,116,97,0,0,0,1,3,2,0,9,1,107,0,2,17,49,0,48,0,0,18,101,116,97,0,18, -101,116,97,0,48,17,49,0,48,0,0,58,100,111,116,0,18,78,0,0,18,73,0,0,0,58,100,111,116,0,18,78,0,0, -18,73,0,0,0,48,47,48,47,0,0,10,18,107,0,17,48,0,48,0,0,40,0,8,17,48,0,48,0,0,0,9,14,0,8,18,101,116, -97,0,18,73,0,48,18,101,116,97,0,58,100,111,116,0,18,78,0,0,18,73,0,0,0,48,58,115,113,114,116,0,18, -107,0,0,0,46,18,78,0,48,47,0,0,1,0,10,0,114,101,102,114,97,99,116,0,1,0,0,10,73,0,0,1,0,0,10,78,0, -0,1,0,0,9,101,116,97,0,0,0,1,3,2,0,9,1,107,0,2,17,49,0,48,0,0,18,101,116,97,0,18,101,116,97,0,48, -17,49,0,48,0,0,58,100,111,116,0,18,78,0,0,18,73,0,0,0,58,100,111,116,0,18,78,0,0,18,73,0,0,0,48,47, -48,47,0,0,10,18,107,0,17,48,0,48,0,0,40,0,8,17,48,0,48,0,0,0,9,14,0,8,18,101,116,97,0,18,73,0,48, -18,101,116,97,0,58,100,111,116,0,18,78,0,0,18,73,0,0,0,48,58,115,113,114,116,0,18,107,0,0,0,46,18, -78,0,48,47,0,0,1,0,11,0,114,101,102,114,97,99,116,0,1,0,0,11,73,0,0,1,0,0,11,78,0,0,1,0,0,9,101, -116,97,0,0,0,1,3,2,0,9,1,107,0,2,17,49,0,48,0,0,18,101,116,97,0,18,101,116,97,0,48,17,49,0,48,0,0, -58,100,111,116,0,18,78,0,0,18,73,0,0,0,58,100,111,116,0,18,78,0,0,18,73,0,0,0,48,47,48,47,0,0,10, -18,107,0,17,48,0,48,0,0,40,0,8,17,48,0,48,0,0,0,9,14,0,8,18,101,116,97,0,18,73,0,48,18,101,116,97, -0,58,100,111,116,0,18,78,0,0,18,73,0,0,0,48,58,115,113,114,116,0,18,107,0,0,0,46,18,78,0,48,47,0,0, -1,0,12,0,114,101,102,114,97,99,116,0,1,0,0,12,73,0,0,1,0,0,12,78,0,0,1,0,0,9,101,116,97,0,0,0,1,3, -2,0,9,1,107,0,2,17,49,0,48,0,0,18,101,116,97,0,18,101,116,97,0,48,17,49,0,48,0,0,58,100,111,116,0, -18,78,0,0,18,73,0,0,0,58,100,111,116,0,18,78,0,0,18,73,0,0,0,48,47,48,47,0,0,10,18,107,0,17,48,0, -48,0,0,40,0,8,17,48,0,48,0,0,0,9,14,0,8,18,101,116,97,0,18,73,0,48,18,101,116,97,0,58,100,111,116, -0,18,78,0,0,18,73,0,0,0,48,58,115,113,114,116,0,18,107,0,0,0,46,18,78,0,48,47,0,0,1,0,13,0,109,97, -116,114,105,120,67,111,109,112,77,117,108,116,0,1,0,0,13,109,0,0,1,0,0,13,110,0,0,0,1,8,58,109,97, -116,50,0,18,109,0,16,8,48,0,57,18,110,0,16,8,48,0,57,48,0,18,109,0,16,10,49,0,57,18,110,0,16,10,49, -0,57,48,0,0,0,0,1,0,14,0,109,97,116,114,105,120,67,111,109,112,77,117,108,116,0,1,0,0,14,109,0,0,1, -0,0,14,110,0,0,0,1,8,58,109,97,116,51,0,18,109,0,16,8,48,0,57,18,110,0,16,8,48,0,57,48,0,18,109,0, -16,10,49,0,57,18,110,0,16,10,49,0,57,48,0,18,109,0,16,10,50,0,57,18,110,0,16,10,50,0,57,48,0,0,0,0, -1,0,15,0,109,97,116,114,105,120,67,111,109,112,77,117,108,116,0,1,0,0,15,109,0,0,1,0,0,15,110,0,0, -0,1,8,58,109,97,116,52,0,18,109,0,16,8,48,0,57,18,110,0,16,8,48,0,57,48,0,18,109,0,16,10,49,0,57, -18,110,0,16,10,49,0,57,48,0,18,109,0,16,10,50,0,57,18,110,0,16,10,50,0,57,48,0,18,109,0,16,10,51,0, -57,18,110,0,16,10,51,0,57,48,0,0,0,0,1,0,2,0,108,101,115,115,84,104,97,110,0,1,0,0,10,118,0,0,1,0, -0,10,117,0,0,0,1,8,58,98,118,101,99,50,0,18,118,0,59,120,0,18,117,0,59,120,0,40,0,18,118,0,59,121, -0,18,117,0,59,121,0,40,0,0,0,0,1,0,3,0,108,101,115,115,84,104,97,110,0,1,0,0,11,118,0,0,1,0,0,11, -117,0,0,0,1,8,58,98,118,101,99,51,0,18,118,0,59,120,0,18,117,0,59,120,0,40,0,18,118,0,59,121,0,18, -117,0,59,121,0,40,0,18,118,0,59,122,0,18,117,0,59,122,0,40,0,0,0,0,1,0,4,0,108,101,115,115,84,104, -97,110,0,1,0,0,12,118,0,0,1,0,0,12,117,0,0,0,1,8,58,98,118,101,99,52,0,18,118,0,59,120,0,18,117,0, -59,120,0,40,0,18,118,0,59,121,0,18,117,0,59,121,0,40,0,18,118,0,59,122,0,18,117,0,59,122,0,40,0,18, -118,0,59,119,0,18,117,0,59,119,0,40,0,0,0,0,1,0,2,0,108,101,115,115,84,104,97,110,0,1,0,0,6,118,0, -0,1,0,0,6,117,0,0,0,1,8,58,98,118,101,99,50,0,18,118,0,59,120,0,18,117,0,59,120,0,40,0,18,118,0,59, -121,0,18,117,0,59,121,0,40,0,0,0,0,1,0,3,0,108,101,115,115,84,104,97,110,0,1,0,0,7,118,0,0,1,0,0,7, -117,0,0,0,1,8,58,98,118,101,99,51,0,18,118,0,59,120,0,18,117,0,59,120,0,40,0,18,118,0,59,121,0,18, -117,0,59,121,0,40,0,18,118,0,59,122,0,18,117,0,59,122,0,40,0,0,0,0,1,0,4,0,108,101,115,115,84,104, -97,110,0,1,0,0,8,118,0,0,1,0,0,8,117,0,0,0,1,8,58,98,118,101,99,52,0,18,118,0,59,120,0,18,117,0,59, -120,0,40,0,18,118,0,59,121,0,18,117,0,59,121,0,40,0,18,118,0,59,122,0,18,117,0,59,122,0,40,0,18, -118,0,59,119,0,18,117,0,59,119,0,40,0,0,0,0,1,0,2,0,108,101,115,115,84,104,97,110,69,113,117,97, -108,0,1,0,0,10,118,0,0,1,0,0,10,117,0,0,0,1,8,58,98,118,101,99,50,0,18,118,0,59,120,0,18,117,0,59, -120,0,42,0,18,118,0,59,121,0,18,117,0,59,121,0,42,0,0,0,0,1,0,3,0,108,101,115,115,84,104,97,110,69, -113,117,97,108,0,1,0,0,11,118,0,0,1,0,0,11,117,0,0,0,1,8,58,98,118,101,99,51,0,18,118,0,59,120,0, -18,117,0,59,120,0,42,0,18,118,0,59,121,0,18,117,0,59,121,0,42,0,18,118,0,59,122,0,18,117,0,59,122, -0,42,0,0,0,0,1,0,4,0,108,101,115,115,84,104,97,110,69,113,117,97,108,0,1,0,0,12,118,0,0,1,0,0,12, -117,0,0,0,1,8,58,98,118,101,99,52,0,18,118,0,59,120,0,18,117,0,59,120,0,42,0,18,118,0,59,121,0,18, -117,0,59,121,0,42,0,18,118,0,59,122,0,18,117,0,59,122,0,42,0,18,118,0,59,119,0,18,117,0,59,119,0, -42,0,0,0,0,1,0,2,0,108,101,115,115,84,104,97,110,69,113,117,97,108,0,1,0,0,6,118,0,0,1,0,0,6,117,0, -0,0,1,8,58,98,118,101,99,50,0,18,118,0,59,120,0,18,117,0,59,120,0,42,0,18,118,0,59,121,0,18,117,0, -59,121,0,42,0,0,0,0,1,0,3,0,108,101,115,115,84,104,97,110,69,113,117,97,108,0,1,0,0,7,118,0,0,1,0, -0,7,117,0,0,0,1,8,58,98,118,101,99,51,0,18,118,0,59,120,0,18,117,0,59,120,0,42,0,18,118,0,59,121,0, -18,117,0,59,121,0,42,0,18,118,0,59,122,0,18,117,0,59,122,0,42,0,0,0,0,1,0,4,0,108,101,115,115,84, -104,97,110,69,113,117,97,108,0,1,0,0,8,118,0,0,1,0,0,8,117,0,0,0,1,8,58,98,118,101,99,52,0,18,118, -0,59,120,0,18,117,0,59,120,0,42,0,18,118,0,59,121,0,18,117,0,59,121,0,42,0,18,118,0,59,122,0,18, -117,0,59,122,0,42,0,18,118,0,59,119,0,18,117,0,59,119,0,42,0,0,0,0,1,0,2,0,103,114,101,97,116,101, -114,84,104,97,110,0,1,0,0,10,118,0,0,1,0,0,10,117,0,0,0,1,8,58,98,118,101,99,50,0,18,118,0,59,120, -0,18,117,0,59,120,0,41,0,18,118,0,59,121,0,18,117,0,59,121,0,41,0,0,0,0,1,0,3,0,103,114,101,97,116, -101,114,84,104,97,110,0,1,0,0,11,118,0,0,1,0,0,11,117,0,0,0,1,8,58,98,118,101,99,51,0,18,118,0,59, -120,0,18,117,0,59,120,0,41,0,18,118,0,59,121,0,18,117,0,59,121,0,41,0,18,118,0,59,122,0,18,117,0, -59,122,0,41,0,0,0,0,1,0,4,0,103,114,101,97,116,101,114,84,104,97,110,0,1,0,0,12,118,0,0,1,0,0,12, -117,0,0,0,1,8,58,98,118,101,99,52,0,18,118,0,59,120,0,18,117,0,59,120,0,41,0,18,118,0,59,121,0,18, -117,0,59,121,0,41,0,18,118,0,59,122,0,18,117,0,59,122,0,41,0,18,118,0,59,119,0,18,117,0,59,119,0, -41,0,0,0,0,1,0,2,0,103,114,101,97,116,101,114,84,104,97,110,0,1,0,0,6,118,0,0,1,0,0,6,117,0,0,0,1, -8,58,98,118,101,99,50,0,18,118,0,59,120,0,18,117,0,59,120,0,41,0,18,118,0,59,121,0,18,117,0,59,121, -0,41,0,0,0,0,1,0,3,0,103,114,101,97,116,101,114,84,104,97,110,0,1,0,0,7,118,0,0,1,0,0,7,117,0,0,0, -1,8,58,98,118,101,99,51,0,18,118,0,59,120,0,18,117,0,59,120,0,41,0,18,118,0,59,121,0,18,117,0,59, -121,0,41,0,18,118,0,59,122,0,18,117,0,59,122,0,41,0,0,0,0,1,0,4,0,103,114,101,97,116,101,114,84, -104,97,110,0,1,0,0,8,118,0,0,1,0,0,8,117,0,0,0,1,8,58,98,118,101,99,52,0,18,118,0,59,120,0,18,117, -0,59,120,0,41,0,18,118,0,59,121,0,18,117,0,59,121,0,41,0,18,118,0,59,122,0,18,117,0,59,122,0,41,0, -18,118,0,59,119,0,18,117,0,59,119,0,41,0,0,0,0,1,0,2,0,103,114,101,97,116,101,114,84,104,97,110,69, -113,117,97,108,0,1,0,0,10,118,0,0,1,0,0,10,117,0,0,0,1,8,58,98,118,101,99,50,0,18,118,0,59,120,0, -18,117,0,59,120,0,43,0,18,118,0,59,121,0,18,117,0,59,121,0,43,0,0,0,0,1,0,3,0,103,114,101,97,116, -101,114,84,104,97,110,69,113,117,97,108,0,1,0,0,11,118,0,0,1,0,0,11,117,0,0,0,1,8,58,98,118,101,99, -51,0,18,118,0,59,120,0,18,117,0,59,120,0,43,0,18,118,0,59,121,0,18,117,0,59,121,0,43,0,18,118,0,59, -122,0,18,117,0,59,122,0,43,0,0,0,0,1,0,4,0,103,114,101,97,116,101,114,84,104,97,110,69,113,117,97, -108,0,1,0,0,12,118,0,0,1,0,0,12,117,0,0,0,1,8,58,98,118,101,99,52,0,18,118,0,59,120,0,18,117,0,59, -120,0,43,0,18,118,0,59,121,0,18,117,0,59,121,0,43,0,18,118,0,59,122,0,18,117,0,59,122,0,43,0,18, -118,0,59,119,0,18,117,0,59,119,0,43,0,0,0,0,1,0,2,0,103,114,101,97,116,101,114,84,104,97,110,69, -113,117,97,108,0,1,0,0,6,118,0,0,1,0,0,6,117,0,0,0,1,8,58,98,118,101,99,50,0,18,118,0,59,120,0,18, -117,0,59,120,0,43,0,18,118,0,59,121,0,18,117,0,59,121,0,43,0,0,0,0,1,0,3,0,103,114,101,97,116,101, -114,84,104,97,110,69,113,117,97,108,0,1,0,0,7,118,0,0,1,0,0,7,117,0,0,0,1,8,58,98,118,101,99,51,0, -18,118,0,59,120,0,18,117,0,59,120,0,43,0,18,118,0,59,121,0,18,117,0,59,121,0,43,0,18,118,0,59,122, -0,18,117,0,59,122,0,43,0,0,0,0,1,0,4,0,103,114,101,97,116,101,114,84,104,97,110,69,113,117,97,108, -0,1,0,0,8,118,0,0,1,0,0,8,117,0,0,0,1,8,58,98,118,101,99,52,0,18,118,0,59,120,0,18,117,0,59,120,0, -43,0,18,118,0,59,121,0,18,117,0,59,121,0,43,0,18,118,0,59,122,0,18,117,0,59,122,0,43,0,18,118,0,59, -119,0,18,117,0,59,119,0,43,0,0,0,0,1,0,2,0,101,113,117,97,108,0,1,0,0,10,118,0,0,1,0,0,10,117,0,0, -0,1,8,58,98,118,101,99,50,0,18,118,0,59,120,0,18,117,0,59,120,0,38,0,18,118,0,59,121,0,18,117,0,59, -121,0,38,0,0,0,0,1,0,3,0,101,113,117,97,108,0,1,0,0,11,118,0,0,1,0,0,11,117,0,0,0,1,8,58,98,118, -101,99,51,0,18,118,0,59,120,0,18,117,0,59,120,0,38,0,18,118,0,59,121,0,18,117,0,59,121,0,38,0,18, -118,0,59,122,0,18,117,0,59,122,0,38,0,0,0,0,1,0,4,0,101,113,117,97,108,0,1,0,0,12,118,0,0,1,0,0,12, -117,0,0,0,1,8,58,98,118,101,99,52,0,18,118,0,59,120,0,18,117,0,59,120,0,38,0,18,118,0,59,121,0,18, -117,0,59,121,0,38,0,18,118,0,59,122,0,18,117,0,59,122,0,38,0,18,118,0,59,119,0,18,117,0,59,119,0, -38,0,0,0,0,1,0,2,0,101,113,117,97,108,0,1,0,0,6,118,0,0,1,0,0,6,117,0,0,0,1,8,58,98,118,101,99,50, -0,18,118,0,59,120,0,18,117,0,59,120,0,38,0,18,118,0,59,121,0,18,117,0,59,121,0,38,0,0,0,0,1,0,3,0, -101,113,117,97,108,0,1,0,0,7,118,0,0,1,0,0,7,117,0,0,0,1,8,58,98,118,101,99,51,0,18,118,0,59,120,0, -18,117,0,59,120,0,38,0,18,118,0,59,121,0,18,117,0,59,121,0,38,0,18,118,0,59,122,0,18,117,0,59,122, -0,38,0,0,0,0,1,0,4,0,101,113,117,97,108,0,1,0,0,8,118,0,0,1,0,0,8,117,0,0,0,1,8,58,98,118,101,99, -52,0,18,118,0,59,120,0,18,117,0,59,120,0,38,0,18,118,0,59,121,0,18,117,0,59,121,0,38,0,18,118,0,59, -122,0,18,117,0,59,122,0,38,0,18,118,0,59,119,0,18,117,0,59,119,0,38,0,0,0,0,1,0,2,0,110,111,116,69, -113,117,97,108,0,1,0,0,10,118,0,0,1,0,0,10,117,0,0,0,1,8,58,98,118,101,99,50,0,18,118,0,59,120,0, -18,117,0,59,120,0,39,0,18,118,0,59,121,0,18,117,0,59,121,0,39,0,0,0,0,1,0,3,0,110,111,116,69,113, -117,97,108,0,1,0,0,11,118,0,0,1,0,0,11,117,0,0,0,1,8,58,98,118,101,99,51,0,18,118,0,59,120,0,18, -117,0,59,120,0,39,0,18,118,0,59,121,0,18,117,0,59,121,0,39,0,18,118,0,59,122,0,18,117,0,59,122,0, -39,0,0,0,0,1,0,4,0,110,111,116,69,113,117,97,108,0,1,0,0,12,118,0,0,1,0,0,12,117,0,0,0,1,8,58,98, -118,101,99,52,0,18,118,0,59,120,0,18,117,0,59,120,0,39,0,18,118,0,59,121,0,18,117,0,59,121,0,39,0, -18,118,0,59,122,0,18,117,0,59,122,0,39,0,18,118,0,59,119,0,18,117,0,59,119,0,39,0,0,0,0,1,0,2,0, -110,111,116,69,113,117,97,108,0,1,0,0,6,118,0,0,1,0,0,6,117,0,0,0,1,8,58,98,118,101,99,50,0,18,118, -0,59,120,0,18,117,0,59,120,0,39,0,18,118,0,59,121,0,18,117,0,59,121,0,39,0,0,0,0,1,0,3,0,110,111, -116,69,113,117,97,108,0,1,0,0,7,118,0,0,1,0,0,7,117,0,0,0,1,8,58,98,118,101,99,51,0,18,118,0,59, -120,0,18,117,0,59,120,0,39,0,18,118,0,59,121,0,18,117,0,59,121,0,39,0,18,118,0,59,122,0,18,117,0, -59,122,0,39,0,0,0,0,1,0,4,0,110,111,116,69,113,117,97,108,0,1,0,0,8,118,0,0,1,0,0,8,117,0,0,0,1,8, -58,98,118,101,99,52,0,18,118,0,59,120,0,18,117,0,59,120,0,39,0,18,118,0,59,121,0,18,117,0,59,121,0, -39,0,18,118,0,59,122,0,18,117,0,59,122,0,39,0,18,118,0,59,119,0,18,117,0,59,119,0,39,0,0,0,0,1,0,1, -0,97,110,121,0,1,0,0,2,118,0,0,0,1,8,18,118,0,59,120,0,18,118,0,59,121,0,32,0,0,1,0,1,0,97,110,121, -0,1,0,0,3,118,0,0,0,1,8,18,118,0,59,120,0,18,118,0,59,121,0,32,18,118,0,59,122,0,32,0,0,1,0,1,0,97, -110,121,0,1,0,0,4,118,0,0,0,1,8,18,118,0,59,120,0,18,118,0,59,121,0,32,18,118,0,59,122,0,32,18,118, -0,59,119,0,32,0,0,1,0,1,0,97,108,108,0,1,0,0,2,118,0,0,0,1,8,18,118,0,59,120,0,18,118,0,59,121,0, -34,0,0,1,0,1,0,97,108,108,0,1,0,0,3,118,0,0,0,1,8,18,118,0,59,120,0,18,118,0,59,121,0,34,18,118,0, -59,122,0,34,0,0,1,0,1,0,97,108,108,0,1,0,0,4,118,0,0,0,1,8,18,118,0,59,120,0,18,118,0,59,121,0,34, -18,118,0,59,122,0,34,18,118,0,59,119,0,34,0,0,1,0,2,0,110,111,116,0,1,0,0,2,118,0,0,0,1,8,58,98, -118,101,99,50,0,18,118,0,59,120,0,56,0,18,118,0,59,121,0,56,0,0,0,0,1,0,3,0,110,111,116,0,1,0,0,3, -118,0,0,0,1,8,58,98,118,101,99,51,0,18,118,0,59,120,0,56,0,18,118,0,59,121,0,56,0,18,118,0,59,122, -0,56,0,0,0,0,1,0,4,0,110,111,116,0,1,0,0,4,118,0,0,0,1,8,58,98,118,101,99,52,0,18,118,0,59,120,0, -56,0,18,118,0,59,121,0,56,0,18,118,0,59,122,0,56,0,18,118,0,59,119,0,56,0,0,0,0,1,0,12,0,116,101, -120,116,117,114,101,49,68,0,1,0,0,16,115,97,109,112,108,101,114,0,0,1,0,0,9,99,111,111,114,100,0,0, -0,1,3,2,0,12,1,116,101,120,101,108,0,0,0,4,118,101,99,52,95,116,101,120,49,100,0,18,116,101,120, -101,108,0,0,18,115,97,109,112,108,101,114,0,0,18,99,111,111,114,100,0,0,17,48,0,48,0,0,0,0,8,18, -116,101,120,101,108,0,0,0,1,0,12,0,116,101,120,116,117,114,101,49,68,80,114,111,106,0,1,0,0,16,115, -97,109,112,108,101,114,0,0,1,0,0,10,99,111,111,114,100,0,0,0,1,8,58,116,101,120,116,117,114,101,49, -68,0,18,115,97,109,112,108,101,114,0,0,18,99,111,111,114,100,0,59,115,0,18,99,111,111,114,100,0,59, -116,0,49,0,0,0,0,1,0,12,0,116,101,120,116,117,114,101,49,68,80,114,111,106,0,1,0,0,16,115,97,109, -112,108,101,114,0,0,1,0,0,12,99,111,111,114,100,0,0,0,1,8,58,116,101,120,116,117,114,101,49,68,0, -18,115,97,109,112,108,101,114,0,0,18,99,111,111,114,100,0,59,115,0,18,99,111,111,114,100,0,59,113, -0,49,0,0,0,0,1,0,12,0,116,101,120,116,117,114,101,50,68,0,1,0,0,17,115,97,109,112,108,101,114,0,0, -1,0,0,10,99,111,111,114,100,0,0,0,1,3,2,0,12,1,116,101,120,101,108,0,0,0,4,118,101,99,52,95,116, -101,120,50,100,0,18,116,101,120,101,108,0,0,18,115,97,109,112,108,101,114,0,0,18,99,111,111,114, -100,0,0,17,48,0,48,0,0,0,0,8,18,116,101,120,101,108,0,0,0,1,0,12,0,116,101,120,116,117,114,101,50, -68,80,114,111,106,0,1,0,0,17,115,97,109,112,108,101,114,0,0,1,0,0,11,99,111,111,114,100,0,0,0,1,8, -58,116,101,120,116,117,114,101,50,68,0,18,115,97,109,112,108,101,114,0,0,58,118,101,99,50,0,18,99, -111,111,114,100,0,59,115,0,18,99,111,111,114,100,0,59,112,0,49,0,18,99,111,111,114,100,0,59,116,0, -18,99,111,111,114,100,0,59,112,0,49,0,0,0,0,0,0,1,0,12,0,116,101,120,116,117,114,101,50,68,80,114, -111,106,0,1,0,0,17,115,97,109,112,108,101,114,0,0,1,0,0,12,99,111,111,114,100,0,0,0,1,8,58,116,101, -120,116,117,114,101,50,68,0,18,115,97,109,112,108,101,114,0,0,58,118,101,99,50,0,18,99,111,111,114, -100,0,59,115,0,18,99,111,111,114,100,0,59,113,0,49,0,18,99,111,111,114,100,0,59,116,0,18,99,111, -111,114,100,0,59,113,0,49,0,0,0,0,0,0,1,0,12,0,116,101,120,116,117,114,101,51,68,0,1,0,0,18,115,97, +0,0,0,0,58,97,116,97,110,0,18,117,0,59,119,0,0,18,118,0,59,119,0,0,0,0,0,0,0,1,0,9,0,112,111,119,0, +1,1,0,9,97,0,0,1,1,0,9,98,0,0,0,1,4,102,108,111,97,116,95,112,111,119,101,114,0,18,95,95,114,101, +116,86,97,108,0,59,120,0,0,18,97,0,0,18,98,0,0,0,0,1,0,10,0,112,111,119,0,1,1,0,10,97,0,0,1,1,0,10, +98,0,0,0,1,4,102,108,111,97,116,95,112,111,119,101,114,0,18,95,95,114,101,116,86,97,108,0,59,120,0, +0,18,97,0,59,120,0,0,18,98,0,59,120,0,0,0,4,102,108,111,97,116,95,112,111,119,101,114,0,18,95,95, +114,101,116,86,97,108,0,59,121,0,0,18,97,0,59,121,0,0,18,98,0,59,121,0,0,0,0,1,0,11,0,112,111,119, +0,1,1,0,11,97,0,0,1,1,0,11,98,0,0,0,1,4,102,108,111,97,116,95,112,111,119,101,114,0,18,95,95,114, +101,116,86,97,108,0,59,120,0,0,18,97,0,59,120,0,0,18,98,0,59,120,0,0,0,4,102,108,111,97,116,95,112, +111,119,101,114,0,18,95,95,114,101,116,86,97,108,0,59,121,0,0,18,97,0,59,121,0,0,18,98,0,59,121,0, +0,0,4,102,108,111,97,116,95,112,111,119,101,114,0,18,95,95,114,101,116,86,97,108,0,59,122,0,0,18, +97,0,59,122,0,0,18,98,0,59,122,0,0,0,0,1,0,12,0,112,111,119,0,1,1,0,12,97,0,0,1,1,0,12,98,0,0,0,1, +4,102,108,111,97,116,95,112,111,119,101,114,0,18,95,95,114,101,116,86,97,108,0,59,120,0,0,18,97,0, +59,120,0,0,18,98,0,59,120,0,0,0,4,102,108,111,97,116,95,112,111,119,101,114,0,18,95,95,114,101,116, +86,97,108,0,59,121,0,0,18,97,0,59,121,0,0,18,98,0,59,121,0,0,0,4,102,108,111,97,116,95,112,111,119, +101,114,0,18,95,95,114,101,116,86,97,108,0,59,122,0,0,18,97,0,59,122,0,0,18,98,0,59,122,0,0,0,4, +102,108,111,97,116,95,112,111,119,101,114,0,18,95,95,114,101,116,86,97,108,0,59,119,0,0,18,97,0,59, +119,0,0,18,98,0,59,119,0,0,0,0,1,0,9,0,101,120,112,0,1,1,0,9,97,0,0,0,1,4,102,108,111,97,116,95, +101,120,112,0,18,95,95,114,101,116,86,97,108,0,59,120,0,0,18,97,0,0,0,0,1,0,10,0,101,120,112,0,1,1, +0,10,97,0,0,0,1,4,102,108,111,97,116,95,101,120,112,0,18,95,95,114,101,116,86,97,108,0,59,120,0,0, +18,97,0,59,120,0,0,0,4,102,108,111,97,116,95,101,120,112,0,18,95,95,114,101,116,86,97,108,0,59,121, +0,0,18,97,0,59,121,0,0,0,0,1,0,11,0,101,120,112,0,1,1,0,11,97,0,0,0,1,4,102,108,111,97,116,95,101, +120,112,0,18,95,95,114,101,116,86,97,108,0,59,120,0,0,18,97,0,59,120,0,0,0,4,102,108,111,97,116,95, +101,120,112,0,18,95,95,114,101,116,86,97,108,0,59,121,0,0,18,97,0,59,121,0,0,0,4,102,108,111,97, +116,95,101,120,112,0,18,95,95,114,101,116,86,97,108,0,59,122,0,0,18,97,0,59,122,0,0,0,0,1,0,12,0, +101,120,112,0,1,1,0,12,97,0,0,0,1,4,102,108,111,97,116,95,101,120,112,0,18,95,95,114,101,116,86,97, +108,0,59,120,0,0,18,97,0,59,120,0,0,0,4,102,108,111,97,116,95,101,120,112,0,18,95,95,114,101,116, +86,97,108,0,59,121,0,0,18,97,0,59,121,0,0,0,4,102,108,111,97,116,95,101,120,112,0,18,95,95,114,101, +116,86,97,108,0,59,122,0,0,18,97,0,59,122,0,0,0,4,102,108,111,97,116,95,101,120,112,0,18,95,95,114, +101,116,86,97,108,0,59,119,0,0,18,97,0,59,119,0,0,0,0,1,0,9,0,108,111,103,50,0,1,1,0,9,120,0,0,0,1, +4,102,108,111,97,116,95,108,111,103,50,0,18,95,95,114,101,116,86,97,108,0,59,120,0,0,18,120,0,0,0, +0,1,0,10,0,108,111,103,50,0,1,1,0,10,118,0,0,0,1,4,102,108,111,97,116,95,108,111,103,50,0,18,95,95, +114,101,116,86,97,108,0,59,120,0,0,18,118,0,59,120,0,0,0,4,102,108,111,97,116,95,108,111,103,50,0, +18,95,95,114,101,116,86,97,108,0,59,121,0,0,18,118,0,59,121,0,0,0,0,1,0,11,0,108,111,103,50,0,1,1, +0,11,118,0,0,0,1,4,102,108,111,97,116,95,108,111,103,50,0,18,95,95,114,101,116,86,97,108,0,59,120, +0,0,18,118,0,59,120,0,0,0,4,102,108,111,97,116,95,108,111,103,50,0,18,95,95,114,101,116,86,97,108, +0,59,121,0,0,18,118,0,59,121,0,0,0,4,102,108,111,97,116,95,108,111,103,50,0,18,95,95,114,101,116, +86,97,108,0,59,122,0,0,18,118,0,59,122,0,0,0,0,1,0,12,0,108,111,103,50,0,1,1,0,12,118,0,0,0,1,4, +102,108,111,97,116,95,108,111,103,50,0,18,95,95,114,101,116,86,97,108,0,59,120,0,0,18,118,0,59,120, +0,0,0,4,102,108,111,97,116,95,108,111,103,50,0,18,95,95,114,101,116,86,97,108,0,59,121,0,0,18,118, +0,59,121,0,0,0,4,102,108,111,97,116,95,108,111,103,50,0,18,95,95,114,101,116,86,97,108,0,59,122,0, +0,18,118,0,59,122,0,0,0,4,102,108,111,97,116,95,108,111,103,50,0,18,95,95,114,101,116,86,97,108,0, +59,119,0,0,18,118,0,59,119,0,0,0,0,1,0,9,0,108,111,103,0,1,1,0,9,120,0,0,0,1,3,2,1,9,1,99,0,2,17, +48,0,54,57,51,49,52,55,49,56,49,0,0,0,0,8,58,108,111,103,50,0,18,120,0,0,0,18,99,0,48,0,0,1,0,10,0, +108,111,103,0,1,1,0,10,118,0,0,0,1,3,2,1,9,1,99,0,2,17,48,0,54,57,51,49,52,55,49,56,49,0,0,0,0,8, +58,108,111,103,50,0,18,118,0,0,0,18,99,0,48,0,0,1,0,11,0,108,111,103,0,1,1,0,11,118,0,0,0,1,3,2,1, +9,1,99,0,2,17,48,0,54,57,51,49,52,55,49,56,49,0,0,0,0,8,58,108,111,103,50,0,18,118,0,0,0,18,99,0, +48,0,0,1,0,12,0,108,111,103,0,1,1,0,12,118,0,0,0,1,3,2,1,9,1,99,0,2,17,48,0,54,57,51,49,52,55,49, +56,49,0,0,0,0,8,58,108,111,103,50,0,18,118,0,0,0,18,99,0,48,0,0,1,0,9,0,101,120,112,50,0,1,1,0,9, +97,0,0,0,1,4,102,108,111,97,116,95,101,120,112,50,0,18,95,95,114,101,116,86,97,108,0,59,120,0,0,18, +97,0,0,0,0,1,0,10,0,101,120,112,50,0,1,1,0,10,97,0,0,0,1,4,102,108,111,97,116,95,101,120,112,50,0, +18,95,95,114,101,116,86,97,108,0,59,120,0,0,18,97,0,59,120,0,0,0,4,102,108,111,97,116,95,101,120, +112,50,0,18,95,95,114,101,116,86,97,108,0,59,121,0,0,18,97,0,59,121,0,0,0,0,1,0,11,0,101,120,112, +50,0,1,1,0,11,97,0,0,0,1,4,102,108,111,97,116,95,101,120,112,50,0,18,95,95,114,101,116,86,97,108,0, +59,120,0,0,18,97,0,59,120,0,0,0,4,102,108,111,97,116,95,101,120,112,50,0,18,95,95,114,101,116,86, +97,108,0,59,121,0,0,18,97,0,59,121,0,0,0,4,102,108,111,97,116,95,101,120,112,50,0,18,95,95,114,101, +116,86,97,108,0,59,122,0,0,18,97,0,59,122,0,0,0,0,1,0,12,0,101,120,112,50,0,1,1,0,12,97,0,0,0,1,4, +102,108,111,97,116,95,101,120,112,50,0,18,95,95,114,101,116,86,97,108,0,59,120,0,0,18,97,0,59,120, +0,0,0,4,102,108,111,97,116,95,101,120,112,50,0,18,95,95,114,101,116,86,97,108,0,59,121,0,0,18,97,0, +59,121,0,0,0,4,102,108,111,97,116,95,101,120,112,50,0,18,95,95,114,101,116,86,97,108,0,59,122,0,0, +18,97,0,59,122,0,0,0,4,102,108,111,97,116,95,101,120,112,50,0,18,95,95,114,101,116,86,97,108,0,59, +119,0,0,18,97,0,59,119,0,0,0,0,1,0,9,0,115,113,114,116,0,1,1,0,9,120,0,0,0,1,3,2,0,9,1,114,0,0,0,4, +102,108,111,97,116,95,114,115,113,0,18,114,0,0,18,120,0,0,0,4,102,108,111,97,116,95,114,99,112,0, +18,95,95,114,101,116,86,97,108,0,59,120,0,0,18,114,0,0,0,0,1,0,10,0,115,113,114,116,0,1,1,0,10,118, +0,0,0,1,3,2,0,9,1,114,0,0,0,4,102,108,111,97,116,95,114,115,113,0,18,114,0,0,18,118,0,59,120,0,0,0, +4,102,108,111,97,116,95,114,99,112,0,18,95,95,114,101,116,86,97,108,0,59,120,0,0,18,114,0,0,0,4, +102,108,111,97,116,95,114,115,113,0,18,114,0,0,18,118,0,59,121,0,0,0,4,102,108,111,97,116,95,114, +99,112,0,18,95,95,114,101,116,86,97,108,0,59,121,0,0,18,114,0,0,0,0,1,0,11,0,115,113,114,116,0,1,1, +0,11,118,0,0,0,1,3,2,0,9,1,114,0,0,0,4,102,108,111,97,116,95,114,115,113,0,18,114,0,0,18,118,0,59, +120,0,0,0,4,102,108,111,97,116,95,114,99,112,0,18,95,95,114,101,116,86,97,108,0,59,120,0,0,18,114, +0,0,0,4,102,108,111,97,116,95,114,115,113,0,18,114,0,0,18,118,0,59,121,0,0,0,4,102,108,111,97,116, +95,114,99,112,0,18,95,95,114,101,116,86,97,108,0,59,121,0,0,18,114,0,0,0,4,102,108,111,97,116,95, +114,115,113,0,18,114,0,0,18,118,0,59,122,0,0,0,4,102,108,111,97,116,95,114,99,112,0,18,95,95,114, +101,116,86,97,108,0,59,122,0,0,18,114,0,0,0,0,1,0,12,0,115,113,114,116,0,1,1,0,12,118,0,0,0,1,3,2, +0,9,1,114,0,0,0,4,102,108,111,97,116,95,114,115,113,0,18,114,0,0,18,118,0,59,120,0,0,0,4,102,108, +111,97,116,95,114,99,112,0,18,95,95,114,101,116,86,97,108,0,59,120,0,0,18,114,0,0,0,4,102,108,111, +97,116,95,114,115,113,0,18,114,0,0,18,118,0,59,121,0,0,0,4,102,108,111,97,116,95,114,99,112,0,18, +95,95,114,101,116,86,97,108,0,59,121,0,0,18,114,0,0,0,4,102,108,111,97,116,95,114,115,113,0,18,114, +0,0,18,118,0,59,122,0,0,0,4,102,108,111,97,116,95,114,99,112,0,18,95,95,114,101,116,86,97,108,0,59, +122,0,0,18,114,0,0,0,4,102,108,111,97,116,95,114,115,113,0,18,114,0,0,18,118,0,59,119,0,0,0,4,102, +108,111,97,116,95,114,99,112,0,18,95,95,114,101,116,86,97,108,0,59,119,0,0,18,114,0,0,0,0,1,0,9,0, +105,110,118,101,114,115,101,115,113,114,116,0,1,1,0,9,120,0,0,0,1,4,102,108,111,97,116,95,114,115, +113,0,18,95,95,114,101,116,86,97,108,0,59,120,0,0,18,120,0,0,0,0,1,0,10,0,105,110,118,101,114,115, +101,115,113,114,116,0,1,1,0,10,118,0,0,0,1,4,102,108,111,97,116,95,114,115,113,0,18,95,95,114,101, +116,86,97,108,0,59,120,0,0,18,118,0,59,120,0,0,0,4,102,108,111,97,116,95,114,115,113,0,18,95,95, +114,101,116,86,97,108,0,59,121,0,0,18,118,0,59,121,0,0,0,0,1,0,11,0,105,110,118,101,114,115,101, +115,113,114,116,0,1,1,0,11,118,0,0,0,1,4,102,108,111,97,116,95,114,115,113,0,18,95,95,114,101,116, +86,97,108,0,59,120,0,0,18,118,0,59,120,0,0,0,4,102,108,111,97,116,95,114,115,113,0,18,95,95,114, +101,116,86,97,108,0,59,121,0,0,18,118,0,59,121,0,0,0,4,102,108,111,97,116,95,114,115,113,0,18,95, +95,114,101,116,86,97,108,0,59,122,0,0,18,118,0,59,122,0,0,0,0,1,0,12,0,105,110,118,101,114,115,101, +115,113,114,116,0,1,1,0,12,118,0,0,0,1,4,102,108,111,97,116,95,114,115,113,0,18,95,95,114,101,116, +86,97,108,0,59,120,0,0,18,118,0,59,120,0,0,0,4,102,108,111,97,116,95,114,115,113,0,18,95,95,114, +101,116,86,97,108,0,59,121,0,0,18,118,0,59,121,0,0,0,4,102,108,111,97,116,95,114,115,113,0,18,95, +95,114,101,116,86,97,108,0,59,122,0,0,18,118,0,59,122,0,0,0,4,102,108,111,97,116,95,114,115,113,0, +18,95,95,114,101,116,86,97,108,0,59,119,0,0,18,118,0,59,119,0,0,0,0,1,0,9,0,110,111,114,109,97,108, +105,122,101,0,1,1,0,9,120,0,0,0,1,9,18,95,95,114,101,116,86,97,108,0,59,120,0,17,49,0,48,0,0,20,0, +0,1,0,10,0,110,111,114,109,97,108,105,122,101,0,1,1,0,10,118,0,0,0,1,3,2,1,9,1,115,0,2,58,105,110, +118,101,114,115,101,115,113,114,116,0,58,100,111,116,0,18,118,0,0,18,118,0,0,0,0,0,0,0,4,118,101, +99,52,95,109,117,108,116,105,112,108,121,0,18,95,95,114,101,116,86,97,108,0,59,120,121,0,0,18,118, +0,0,18,115,0,59,120,120,0,0,0,0,1,0,11,0,110,111,114,109,97,108,105,122,101,0,1,1,0,11,118,0,0,0,1, +3,2,0,9,1,116,109,112,0,0,0,4,118,101,99,51,95,100,111,116,0,18,116,109,112,0,0,18,118,0,0,18,118, +0,0,0,4,102,108,111,97,116,95,114,115,113,0,18,116,109,112,0,0,18,116,109,112,0,0,0,4,118,101,99, +52,95,109,117,108,116,105,112,108,121,0,18,95,95,114,101,116,86,97,108,0,59,120,121,122,0,0,18,118, +0,0,18,116,109,112,0,59,120,120,120,0,0,0,0,1,0,12,0,110,111,114,109,97,108,105,122,101,0,1,1,0,12, +118,0,0,0,1,3,2,0,9,1,116,109,112,0,0,0,4,118,101,99,52,95,100,111,116,0,18,116,109,112,0,0,18,118, +0,0,18,118,0,0,0,4,102,108,111,97,116,95,114,115,113,0,18,116,109,112,0,0,18,116,109,112,0,0,0,4, +118,101,99,52,95,109,117,108,116,105,112,108,121,0,18,95,95,114,101,116,86,97,108,0,59,120,121,122, +0,0,18,118,0,0,18,116,109,112,0,59,120,120,120,0,0,0,0,1,0,9,0,97,98,115,0,1,1,0,9,97,0,0,0,1,4, +118,101,99,52,95,97,98,115,0,18,95,95,114,101,116,86,97,108,0,59,120,0,0,18,97,0,0,0,0,1,0,10,0,97, +98,115,0,1,1,0,10,97,0,0,0,1,4,118,101,99,52,95,97,98,115,0,18,95,95,114,101,116,86,97,108,0,59, +120,121,0,0,18,97,0,0,0,0,1,0,11,0,97,98,115,0,1,1,0,11,97,0,0,0,1,4,118,101,99,52,95,97,98,115,0, +18,95,95,114,101,116,86,97,108,0,59,120,121,122,0,0,18,97,0,0,0,0,1,0,12,0,97,98,115,0,1,1,0,12,97, +0,0,0,1,4,118,101,99,52,95,97,98,115,0,18,95,95,114,101,116,86,97,108,0,0,18,97,0,0,0,0,1,0,9,0, +115,105,103,110,0,1,1,0,9,120,0,0,0,1,3,2,0,9,1,112,0,0,1,1,110,0,0,0,4,118,101,99,52,95,115,103, +116,0,18,112,0,59,120,0,0,18,120,0,0,17,48,0,48,0,0,0,0,4,118,101,99,52,95,115,103,116,0,18,110,0, +59,120,0,0,17,48,0,48,0,0,0,18,120,0,0,0,4,118,101,99,52,95,115,117,98,116,114,97,99,116,0,18,95, +95,114,101,116,86,97,108,0,59,120,0,0,18,112,0,0,18,110,0,0,0,0,1,0,10,0,115,105,103,110,0,1,1,0, +10,118,0,0,0,1,3,2,0,10,1,112,0,0,1,1,110,0,0,0,4,118,101,99,52,95,115,103,116,0,18,112,0,59,120, +121,0,0,18,118,0,0,17,48,0,48,0,0,0,0,4,118,101,99,52,95,115,103,116,0,18,110,0,59,120,121,0,0,17, +48,0,48,0,0,0,18,118,0,0,0,4,118,101,99,52,95,115,117,98,116,114,97,99,116,0,18,95,95,114,101,116, +86,97,108,0,59,120,121,0,0,18,112,0,0,18,110,0,0,0,0,1,0,11,0,115,105,103,110,0,1,1,0,11,118,0,0,0, +1,3,2,0,11,1,112,0,0,1,1,110,0,0,0,4,118,101,99,52,95,115,103,116,0,18,112,0,59,120,121,122,0,0,18, +118,0,0,17,48,0,48,0,0,0,0,4,118,101,99,52,95,115,103,116,0,18,110,0,59,120,121,122,0,0,17,48,0,48, +0,0,0,18,118,0,0,0,4,118,101,99,52,95,115,117,98,116,114,97,99,116,0,18,95,95,114,101,116,86,97, +108,0,59,120,121,122,0,0,18,112,0,0,18,110,0,0,0,0,1,0,12,0,115,105,103,110,0,1,1,0,12,118,0,0,0,1, +3,2,0,12,1,112,0,0,1,1,110,0,0,0,4,118,101,99,52,95,115,103,116,0,18,112,0,0,18,118,0,0,17,48,0,48, +0,0,0,0,4,118,101,99,52,95,115,103,116,0,18,110,0,0,17,48,0,48,0,0,0,18,118,0,0,0,4,118,101,99,52, +95,115,117,98,116,114,97,99,116,0,18,95,95,114,101,116,86,97,108,0,0,18,112,0,0,18,110,0,0,0,0,1,0, +9,0,102,108,111,111,114,0,1,1,0,9,97,0,0,0,1,4,118,101,99,52,95,102,108,111,111,114,0,18,95,95,114, +101,116,86,97,108,0,59,120,0,0,18,97,0,0,0,0,1,0,10,0,102,108,111,111,114,0,1,1,0,10,97,0,0,0,1,4, +118,101,99,52,95,102,108,111,111,114,0,18,95,95,114,101,116,86,97,108,0,59,120,121,0,0,18,97,0,0,0, +0,1,0,11,0,102,108,111,111,114,0,1,1,0,11,97,0,0,0,1,4,118,101,99,52,95,102,108,111,111,114,0,18, +95,95,114,101,116,86,97,108,0,59,120,121,122,0,0,18,97,0,0,0,0,1,0,12,0,102,108,111,111,114,0,1,1, +0,12,97,0,0,0,1,4,118,101,99,52,95,102,108,111,111,114,0,18,95,95,114,101,116,86,97,108,0,0,18,97, +0,0,0,0,1,0,9,0,99,101,105,108,0,1,1,0,9,97,0,0,0,1,3,2,0,9,1,98,0,2,18,97,0,54,0,0,4,118,101,99, +52,95,102,108,111,111,114,0,18,98,0,0,18,98,0,0,0,9,18,95,95,114,101,116,86,97,108,0,59,120,0,18, +98,0,54,20,0,0,1,0,10,0,99,101,105,108,0,1,1,0,10,97,0,0,0,1,3,2,0,10,1,98,0,2,18,97,0,54,0,0,4, +118,101,99,52,95,102,108,111,111,114,0,18,98,0,0,18,98,0,0,0,9,18,95,95,114,101,116,86,97,108,0,59, +120,121,0,18,98,0,54,20,0,0,1,0,11,0,99,101,105,108,0,1,1,0,11,97,0,0,0,1,3,2,0,11,1,98,0,2,18,97, +0,54,0,0,4,118,101,99,52,95,102,108,111,111,114,0,18,98,0,0,18,98,0,0,0,9,18,95,95,114,101,116,86, +97,108,0,59,120,121,122,0,18,98,0,54,20,0,0,1,0,12,0,99,101,105,108,0,1,1,0,12,97,0,0,0,1,3,2,0,12, +1,98,0,2,18,97,0,54,0,0,4,118,101,99,52,95,102,108,111,111,114,0,18,98,0,0,18,98,0,0,0,9,18,95,95, +114,101,116,86,97,108,0,18,98,0,54,20,0,0,1,0,9,0,102,114,97,99,116,0,1,1,0,9,97,0,0,0,1,4,118,101, +99,52,95,102,114,97,99,0,18,95,95,114,101,116,86,97,108,0,59,120,0,0,18,97,0,0,0,0,1,0,10,0,102, +114,97,99,116,0,1,1,0,10,97,0,0,0,1,4,118,101,99,52,95,102,114,97,99,0,18,95,95,114,101,116,86,97, +108,0,59,120,121,0,0,18,97,0,0,0,0,1,0,11,0,102,114,97,99,116,0,1,1,0,11,97,0,0,0,1,4,118,101,99, +52,95,102,114,97,99,0,18,95,95,114,101,116,86,97,108,0,59,120,121,122,0,0,18,97,0,0,0,0,1,0,12,0, +102,114,97,99,116,0,1,1,0,12,97,0,0,0,1,4,118,101,99,52,95,102,114,97,99,0,18,95,95,114,101,116,86, +97,108,0,0,18,97,0,0,0,0,1,0,9,0,109,111,100,0,1,1,0,9,97,0,0,1,1,0,9,98,0,0,0,1,3,2,0,9,1,111,110, +101,79,118,101,114,66,0,0,0,4,102,108,111,97,116,95,114,99,112,0,18,111,110,101,79,118,101,114,66, +0,0,18,98,0,0,0,9,18,95,95,114,101,116,86,97,108,0,59,120,0,18,97,0,18,98,0,58,102,108,111,111,114, +0,18,97,0,18,111,110,101,79,118,101,114,66,0,48,0,0,48,47,20,0,0,1,0,10,0,109,111,100,0,1,1,0,10, +97,0,0,1,1,0,9,98,0,0,0,1,3,2,0,9,1,111,110,101,79,118,101,114,66,0,0,0,4,102,108,111,97,116,95, +114,99,112,0,18,111,110,101,79,118,101,114,66,0,0,18,98,0,0,0,9,18,95,95,114,101,116,86,97,108,0, +59,120,121,0,18,97,0,18,98,0,58,102,108,111,111,114,0,18,97,0,18,111,110,101,79,118,101,114,66,0, +48,0,0,48,47,20,0,0,1,0,11,0,109,111,100,0,1,1,0,11,97,0,0,1,1,0,9,98,0,0,0,1,3,2,0,9,1,111,110, +101,79,118,101,114,66,0,0,0,4,102,108,111,97,116,95,114,99,112,0,18,111,110,101,79,118,101,114,66, +0,0,18,98,0,0,0,9,18,95,95,114,101,116,86,97,108,0,59,120,121,122,0,18,97,0,18,98,0,58,102,108,111, +111,114,0,18,97,0,18,111,110,101,79,118,101,114,66,0,48,0,0,48,47,20,0,0,1,0,12,0,109,111,100,0,1, +1,0,12,97,0,0,1,1,0,9,98,0,0,0,1,3,2,0,9,1,111,110,101,79,118,101,114,66,0,0,0,4,102,108,111,97, +116,95,114,99,112,0,18,111,110,101,79,118,101,114,66,0,0,18,98,0,0,0,9,18,95,95,114,101,116,86,97, +108,0,18,97,0,18,98,0,58,102,108,111,111,114,0,18,97,0,18,111,110,101,79,118,101,114,66,0,48,0,0, +48,47,20,0,0,1,0,10,0,109,111,100,0,1,1,0,10,97,0,0,1,1,0,10,98,0,0,0,1,3,2,0,9,1,111,110,101,79, +118,101,114,66,120,0,0,1,1,111,110,101,79,118,101,114,66,121,0,0,0,4,102,108,111,97,116,95,114,99, +112,0,18,111,110,101,79,118,101,114,66,120,0,0,18,98,0,59,120,0,0,0,4,102,108,111,97,116,95,114,99, +112,0,18,111,110,101,79,118,101,114,66,121,0,0,18,98,0,59,121,0,0,0,9,18,95,95,114,101,116,86,97, +108,0,59,120,0,18,97,0,59,120,0,18,98,0,59,120,0,58,102,108,111,111,114,0,18,97,0,59,120,0,18,111, +110,101,79,118,101,114,66,120,0,48,0,0,48,47,20,0,9,18,95,95,114,101,116,86,97,108,0,59,121,0,18, +97,0,59,121,0,18,98,0,59,121,0,58,102,108,111,111,114,0,18,97,0,59,121,0,18,111,110,101,79,118,101, +114,66,121,0,48,0,0,48,47,20,0,0,1,0,11,0,109,111,100,0,1,1,0,11,97,0,0,1,1,0,11,98,0,0,0,1,3,2,0, +9,1,111,110,101,79,118,101,114,66,120,0,0,1,1,111,110,101,79,118,101,114,66,121,0,0,1,1,111,110, +101,79,118,101,114,66,122,0,0,0,4,102,108,111,97,116,95,114,99,112,0,18,111,110,101,79,118,101,114, +66,120,0,0,18,98,0,59,120,0,0,0,4,102,108,111,97,116,95,114,99,112,0,18,111,110,101,79,118,101,114, +66,121,0,0,18,98,0,59,121,0,0,0,4,102,108,111,97,116,95,114,99,112,0,18,111,110,101,79,118,101,114, +66,122,0,0,18,98,0,59,122,0,0,0,9,18,95,95,114,101,116,86,97,108,0,59,120,0,18,97,0,59,120,0,18,98, +0,59,120,0,58,102,108,111,111,114,0,18,97,0,59,120,0,18,111,110,101,79,118,101,114,66,120,0,48,0,0, +48,47,20,0,9,18,95,95,114,101,116,86,97,108,0,59,121,0,18,97,0,59,121,0,18,98,0,59,121,0,58,102, +108,111,111,114,0,18,97,0,59,121,0,18,111,110,101,79,118,101,114,66,121,0,48,0,0,48,47,20,0,9,18, +95,95,114,101,116,86,97,108,0,59,122,0,18,97,0,59,122,0,18,98,0,59,122,0,58,102,108,111,111,114,0, +18,97,0,59,122,0,18,111,110,101,79,118,101,114,66,122,0,48,0,0,48,47,20,0,0,1,0,12,0,109,111,100,0, +1,1,0,12,97,0,0,1,1,0,12,98,0,0,0,1,3,2,0,9,1,111,110,101,79,118,101,114,66,120,0,0,1,1,111,110, +101,79,118,101,114,66,121,0,0,1,1,111,110,101,79,118,101,114,66,122,0,0,1,1,111,110,101,79,118,101, +114,66,119,0,0,0,4,102,108,111,97,116,95,114,99,112,0,18,111,110,101,79,118,101,114,66,120,0,0,18, +98,0,59,120,0,0,0,4,102,108,111,97,116,95,114,99,112,0,18,111,110,101,79,118,101,114,66,121,0,0,18, +98,0,59,121,0,0,0,4,102,108,111,97,116,95,114,99,112,0,18,111,110,101,79,118,101,114,66,122,0,0,18, +98,0,59,122,0,0,0,4,102,108,111,97,116,95,114,99,112,0,18,111,110,101,79,118,101,114,66,119,0,0,18, +98,0,59,119,0,0,0,9,18,95,95,114,101,116,86,97,108,0,59,120,0,18,97,0,59,120,0,18,98,0,59,120,0,58, +102,108,111,111,114,0,18,97,0,59,120,0,18,111,110,101,79,118,101,114,66,120,0,48,0,0,48,47,20,0,9, +18,95,95,114,101,116,86,97,108,0,59,121,0,18,97,0,59,121,0,18,98,0,59,121,0,58,102,108,111,111,114, +0,18,97,0,59,121,0,18,111,110,101,79,118,101,114,66,121,0,48,0,0,48,47,20,0,9,18,95,95,114,101,116, +86,97,108,0,59,122,0,18,97,0,59,122,0,18,98,0,59,122,0,58,102,108,111,111,114,0,18,97,0,59,122,0, +18,111,110,101,79,118,101,114,66,122,0,48,0,0,48,47,20,0,9,18,95,95,114,101,116,86,97,108,0,59,119, +0,18,97,0,59,119,0,18,98,0,59,119,0,58,102,108,111,111,114,0,18,97,0,59,119,0,18,111,110,101,79, +118,101,114,66,122,0,48,0,0,48,47,20,0,0,1,0,9,0,109,105,110,0,1,1,0,9,97,0,0,1,1,0,9,98,0,0,0,1,4, +118,101,99,52,95,109,105,110,0,18,95,95,114,101,116,86,97,108,0,59,120,0,0,18,97,0,59,120,0,0,18, +98,0,59,120,0,0,0,0,1,0,10,0,109,105,110,0,1,1,0,10,97,0,0,1,1,0,10,98,0,0,0,1,4,118,101,99,52,95, +109,105,110,0,18,95,95,114,101,116,86,97,108,0,59,120,121,0,0,18,97,0,59,120,121,0,0,18,98,0,59, +120,121,0,0,0,0,1,0,11,0,109,105,110,0,1,1,0,11,97,0,0,1,1,0,11,98,0,0,0,1,4,118,101,99,52,95,109, +105,110,0,18,95,95,114,101,116,86,97,108,0,59,120,121,122,0,0,18,97,0,59,120,121,122,0,0,18,98,0, +59,120,121,122,0,0,0,0,1,0,12,0,109,105,110,0,1,1,0,12,97,0,0,1,1,0,12,98,0,0,0,1,4,118,101,99,52, +95,109,105,110,0,18,95,95,114,101,116,86,97,108,0,0,18,97,0,0,18,98,0,0,0,0,1,0,10,0,109,105,110,0, +1,1,0,10,97,0,0,1,1,0,9,98,0,0,0,1,4,118,101,99,52,95,109,105,110,0,18,95,95,114,101,116,86,97,108, +0,0,18,97,0,59,120,121,0,0,18,98,0,59,120,120,0,0,0,0,1,0,11,0,109,105,110,0,1,1,0,11,97,0,0,1,1,0, +9,98,0,0,0,1,4,118,101,99,52,95,109,105,110,0,18,95,95,114,101,116,86,97,108,0,0,18,97,0,59,120, +121,122,0,0,18,98,0,59,120,120,120,0,0,0,0,1,0,12,0,109,105,110,0,1,1,0,12,97,0,0,1,1,0,9,98,0,0,0, +1,4,118,101,99,52,95,109,105,110,0,18,95,95,114,101,116,86,97,108,0,0,18,97,0,0,18,98,0,59,120,120, +120,120,0,0,0,0,1,0,9,0,109,97,120,0,1,1,0,9,97,0,0,1,1,0,9,98,0,0,0,1,4,118,101,99,52,95,109,97, +120,0,18,95,95,114,101,116,86,97,108,0,59,120,0,0,18,97,0,59,120,0,0,18,98,0,59,120,0,0,0,0,1,0,10, +0,109,97,120,0,1,1,0,10,97,0,0,1,1,0,10,98,0,0,0,1,4,118,101,99,52,95,109,97,120,0,18,95,95,114, +101,116,86,97,108,0,59,120,121,0,0,18,97,0,59,120,121,0,0,18,98,0,59,120,121,0,0,0,0,1,0,11,0,109, +97,120,0,1,1,0,11,97,0,0,1,1,0,11,98,0,0,0,1,4,118,101,99,52,95,109,97,120,0,18,95,95,114,101,116, +86,97,108,0,59,120,121,122,0,0,18,97,0,59,120,121,122,0,0,18,98,0,59,120,121,122,0,0,0,0,1,0,12,0, +109,97,120,0,1,1,0,12,97,0,0,1,1,0,12,98,0,0,0,1,4,118,101,99,52,95,109,97,120,0,18,95,95,114,101, +116,86,97,108,0,0,18,97,0,0,18,98,0,0,0,0,1,0,10,0,109,97,120,0,1,1,0,10,97,0,0,1,1,0,9,98,0,0,0,1, +4,118,101,99,52,95,109,97,120,0,18,95,95,114,101,116,86,97,108,0,0,18,97,0,59,120,121,0,0,18,98,0, +59,120,120,0,0,0,0,1,0,11,0,109,97,120,0,1,1,0,11,97,0,0,1,1,0,9,98,0,0,0,1,4,118,101,99,52,95,109, +97,120,0,18,95,95,114,101,116,86,97,108,0,0,18,97,0,59,120,121,122,0,0,18,98,0,59,120,120,120,0,0, +0,0,1,0,12,0,109,97,120,0,1,1,0,12,97,0,0,1,1,0,9,98,0,0,0,1,4,118,101,99,52,95,109,97,120,0,18,95, +95,114,101,116,86,97,108,0,0,18,97,0,0,18,98,0,59,120,120,120,120,0,0,0,0,1,0,9,0,99,108,97,109, +112,0,1,1,0,9,118,97,108,0,0,1,1,0,9,109,105,110,86,97,108,0,0,1,1,0,9,109,97,120,86,97,108,0,0,0, +1,4,118,101,99,52,95,99,108,97,109,112,0,18,95,95,114,101,116,86,97,108,0,0,18,118,97,108,0,0,18, +109,105,110,86,97,108,0,0,18,109,97,120,86,97,108,0,0,0,0,1,0,10,0,99,108,97,109,112,0,1,1,0,10, +118,97,108,0,0,1,1,0,9,109,105,110,86,97,108,0,0,1,1,0,9,109,97,120,86,97,108,0,0,0,1,4,118,101,99, +52,95,99,108,97,109,112,0,18,95,95,114,101,116,86,97,108,0,0,18,118,97,108,0,0,18,109,105,110,86, +97,108,0,0,18,109,97,120,86,97,108,0,0,0,0,1,0,11,0,99,108,97,109,112,0,1,1,0,11,118,97,108,0,0,1, +1,0,9,109,105,110,86,97,108,0,0,1,1,0,9,109,97,120,86,97,108,0,0,0,1,4,118,101,99,52,95,99,108,97, +109,112,0,18,95,95,114,101,116,86,97,108,0,0,18,118,97,108,0,0,18,109,105,110,86,97,108,0,0,18,109, +97,120,86,97,108,0,0,0,0,1,0,12,0,99,108,97,109,112,0,1,1,0,12,118,97,108,0,0,1,1,0,9,109,105,110, +86,97,108,0,0,1,1,0,9,109,97,120,86,97,108,0,0,0,1,4,118,101,99,52,95,99,108,97,109,112,0,18,95,95, +114,101,116,86,97,108,0,0,18,118,97,108,0,0,18,109,105,110,86,97,108,0,0,18,109,97,120,86,97,108,0, +0,0,0,1,0,10,0,99,108,97,109,112,0,1,1,0,10,118,97,108,0,0,1,1,0,10,109,105,110,86,97,108,0,0,1,1, +0,10,109,97,120,86,97,108,0,0,0,1,4,118,101,99,52,95,99,108,97,109,112,0,18,95,95,114,101,116,86, +97,108,0,0,18,118,97,108,0,0,18,109,105,110,86,97,108,0,0,18,109,97,120,86,97,108,0,0,0,0,1,0,11,0, +99,108,97,109,112,0,1,1,0,11,118,97,108,0,0,1,1,0,11,109,105,110,86,97,108,0,0,1,1,0,11,109,97,120, +86,97,108,0,0,0,1,4,118,101,99,52,95,99,108,97,109,112,0,18,95,95,114,101,116,86,97,108,0,0,18,118, +97,108,0,0,18,109,105,110,86,97,108,0,0,18,109,97,120,86,97,108,0,0,0,0,1,0,12,0,99,108,97,109,112, +0,1,1,0,12,118,97,108,0,0,1,1,0,12,109,105,110,86,97,108,0,0,1,1,0,12,109,97,120,86,97,108,0,0,0,1, +4,118,101,99,52,95,99,108,97,109,112,0,18,95,95,114,101,116,86,97,108,0,0,18,118,97,108,0,0,18,109, +105,110,86,97,108,0,0,18,109,97,120,86,97,108,0,0,0,0,1,0,9,0,109,105,120,0,1,1,0,9,120,0,0,1,1,0, +9,121,0,0,1,1,0,9,97,0,0,0,1,4,118,101,99,52,95,108,114,112,0,18,95,95,114,101,116,86,97,108,0,0, +18,97,0,0,18,121,0,0,18,120,0,0,0,0,1,0,10,0,109,105,120,0,1,1,0,10,120,0,0,1,1,0,10,121,0,0,1,1,0, +9,97,0,0,0,1,4,118,101,99,52,95,108,114,112,0,18,95,95,114,101,116,86,97,108,0,0,18,97,0,0,18,121, +0,0,18,120,0,0,0,0,1,0,11,0,109,105,120,0,1,1,0,11,120,0,0,1,1,0,11,121,0,0,1,1,0,9,97,0,0,0,1,4, +118,101,99,52,95,108,114,112,0,18,95,95,114,101,116,86,97,108,0,0,18,97,0,0,18,121,0,0,18,120,0,0, +0,0,1,0,12,0,109,105,120,0,1,1,0,12,120,0,0,1,1,0,12,121,0,0,1,1,0,9,97,0,0,0,1,4,118,101,99,52,95, +108,114,112,0,18,95,95,114,101,116,86,97,108,0,0,18,97,0,0,18,121,0,0,18,120,0,0,0,0,1,0,10,0,109, +105,120,0,1,1,0,10,120,0,0,1,1,0,10,121,0,0,1,1,0,10,97,0,0,0,1,4,118,101,99,52,95,108,114,112,0, +18,95,95,114,101,116,86,97,108,0,0,18,97,0,0,18,121,0,0,18,120,0,0,0,0,1,0,11,0,109,105,120,0,1,1, +0,11,120,0,0,1,1,0,11,121,0,0,1,1,0,11,97,0,0,0,1,4,118,101,99,52,95,108,114,112,0,18,95,95,114, +101,116,86,97,108,0,0,18,97,0,0,18,121,0,0,18,120,0,0,0,0,1,0,12,0,109,105,120,0,1,1,0,12,120,0,0, +1,1,0,12,121,0,0,1,1,0,12,97,0,0,0,1,4,118,101,99,52,95,108,114,112,0,18,95,95,114,101,116,86,97, +108,0,0,18,97,0,0,18,121,0,0,18,120,0,0,0,0,1,0,9,0,115,116,101,112,0,1,1,0,9,101,100,103,101,0,0, +1,1,0,9,120,0,0,0,1,4,118,101,99,52,95,115,103,116,0,18,95,95,114,101,116,86,97,108,0,59,120,0,0, +18,120,0,0,18,101,100,103,101,0,0,0,0,1,0,10,0,115,116,101,112,0,1,1,0,10,101,100,103,101,0,0,1,1, +0,10,120,0,0,0,1,4,118,101,99,52,95,115,103,116,0,18,95,95,114,101,116,86,97,108,0,59,120,121,0,0, +18,120,0,0,18,101,100,103,101,0,0,0,0,1,0,11,0,115,116,101,112,0,1,1,0,11,101,100,103,101,0,0,1,1, +0,11,120,0,0,0,1,4,118,101,99,52,95,115,103,116,0,18,95,95,114,101,116,86,97,108,0,59,120,121,122, +0,0,18,120,0,0,18,101,100,103,101,0,0,0,0,1,0,12,0,115,116,101,112,0,1,1,0,12,101,100,103,101,0,0, +1,1,0,12,120,0,0,0,1,4,118,101,99,52,95,115,103,116,0,18,95,95,114,101,116,86,97,108,0,0,18,120,0, +0,18,101,100,103,101,0,0,0,0,1,0,10,0,115,116,101,112,0,1,1,0,9,101,100,103,101,0,0,1,1,0,10,118,0, +0,0,1,4,118,101,99,52,95,115,103,116,0,18,95,95,114,101,116,86,97,108,0,59,120,121,0,0,18,118,0,0, +18,101,100,103,101,0,59,120,120,0,0,0,0,1,0,11,0,115,116,101,112,0,1,1,0,9,101,100,103,101,0,0,1,1, +0,11,118,0,0,0,1,4,118,101,99,52,95,115,103,116,0,18,95,95,114,101,116,86,97,108,0,59,120,121,122, +0,0,18,118,0,0,18,101,100,103,101,0,59,120,120,120,0,0,0,0,1,0,12,0,115,116,101,112,0,1,1,0,9,101, +100,103,101,0,0,1,1,0,12,118,0,0,0,1,4,118,101,99,52,95,115,103,116,0,18,95,95,114,101,116,86,97, +108,0,0,18,118,0,0,18,101,100,103,101,0,59,120,120,120,120,0,0,0,0,1,0,9,0,115,109,111,111,116,104, +115,116,101,112,0,1,1,0,9,101,100,103,101,48,0,0,1,1,0,9,101,100,103,101,49,0,0,1,1,0,9,120,0,0,0, +1,3,2,0,9,1,116,0,2,58,99,108,97,109,112,0,18,120,0,18,101,100,103,101,48,0,47,18,101,100,103,101, +49,0,18,101,100,103,101,48,0,47,49,0,17,48,0,48,0,0,0,17,49,0,48,0,0,0,0,0,0,8,18,116,0,18,116,0, +48,17,51,0,48,0,0,17,50,0,48,0,0,18,116,0,48,47,48,0,0,1,0,10,0,115,109,111,111,116,104,115,116, +101,112,0,1,1,0,10,101,100,103,101,48,0,0,1,1,0,10,101,100,103,101,49,0,0,1,1,0,10,118,0,0,0,1,3,2, +0,10,1,116,0,2,58,99,108,97,109,112,0,18,118,0,18,101,100,103,101,48,0,47,18,101,100,103,101,49,0, +18,101,100,103,101,48,0,47,49,0,17,48,0,48,0,0,0,17,49,0,48,0,0,0,0,0,0,8,18,116,0,18,116,0,48,17, +51,0,48,0,0,17,50,0,48,0,0,18,116,0,48,47,48,0,0,1,0,11,0,115,109,111,111,116,104,115,116,101,112, +0,1,1,0,11,101,100,103,101,48,0,0,1,1,0,11,101,100,103,101,49,0,0,1,1,0,11,118,0,0,0,1,3,2,0,11,1, +116,0,2,58,99,108,97,109,112,0,18,118,0,18,101,100,103,101,48,0,47,18,101,100,103,101,49,0,18,101, +100,103,101,48,0,47,49,0,17,48,0,48,0,0,0,17,49,0,48,0,0,0,0,0,0,8,18,116,0,18,116,0,48,17,51,0,48, +0,0,17,50,0,48,0,0,18,116,0,48,47,48,0,0,1,0,12,0,115,109,111,111,116,104,115,116,101,112,0,1,1,0, +12,101,100,103,101,48,0,0,1,1,0,12,101,100,103,101,49,0,0,1,1,0,12,118,0,0,0,1,3,2,0,12,1,116,0,2, +58,99,108,97,109,112,0,18,118,0,18,101,100,103,101,48,0,47,18,101,100,103,101,49,0,18,101,100,103, +101,48,0,47,49,0,17,48,0,48,0,0,0,17,49,0,48,0,0,0,0,0,0,8,18,116,0,18,116,0,48,17,51,0,48,0,0,17, +50,0,48,0,0,18,116,0,48,47,48,0,0,1,0,10,0,115,109,111,111,116,104,115,116,101,112,0,1,1,0,9,101, +100,103,101,48,0,0,1,1,0,9,101,100,103,101,49,0,0,1,1,0,10,118,0,0,0,1,3,2,0,10,1,116,0,2,58,99, +108,97,109,112,0,18,118,0,18,101,100,103,101,48,0,47,18,101,100,103,101,49,0,18,101,100,103,101,48, +0,47,49,0,17,48,0,48,0,0,0,17,49,0,48,0,0,0,0,0,0,8,18,116,0,18,116,0,48,17,51,0,48,0,0,17,50,0,48, +0,0,18,116,0,48,47,48,0,0,1,0,11,0,115,109,111,111,116,104,115,116,101,112,0,1,1,0,9,101,100,103, +101,48,0,0,1,1,0,9,101,100,103,101,49,0,0,1,1,0,11,118,0,0,0,1,3,2,0,11,1,116,0,2,58,99,108,97,109, +112,0,18,118,0,18,101,100,103,101,48,0,47,18,101,100,103,101,49,0,18,101,100,103,101,48,0,47,49,0, +17,48,0,48,0,0,0,17,49,0,48,0,0,0,0,0,0,8,18,116,0,18,116,0,48,17,51,0,48,0,0,17,50,0,48,0,0,18, +116,0,48,47,48,0,0,1,0,12,0,115,109,111,111,116,104,115,116,101,112,0,1,1,0,9,101,100,103,101,48,0, +0,1,1,0,9,101,100,103,101,49,0,0,1,1,0,12,118,0,0,0,1,3,2,0,12,1,116,0,2,58,99,108,97,109,112,0,18, +118,0,18,101,100,103,101,48,0,47,18,101,100,103,101,49,0,18,101,100,103,101,48,0,47,49,0,17,48,0, +48,0,0,0,17,49,0,48,0,0,0,0,0,0,8,18,116,0,18,116,0,48,17,51,0,48,0,0,17,50,0,48,0,0,18,116,0,48, +47,48,0,0,1,0,9,0,108,101,110,103,116,104,0,1,1,0,9,120,0,0,0,1,8,58,97,98,115,0,18,120,0,0,0,0,0, +1,0,9,0,108,101,110,103,116,104,0,1,1,0,10,118,0,0,0,1,3,2,0,9,1,114,0,0,0,3,2,1,9,1,112,0,2,58, +100,111,116,0,18,118,0,0,18,118,0,0,0,0,0,4,102,108,111,97,116,95,114,115,113,0,18,114,0,0,18,112, +0,0,0,4,102,108,111,97,116,95,114,99,112,0,18,95,95,114,101,116,86,97,108,0,59,120,0,0,18,114,0,0, +0,0,1,0,9,0,108,101,110,103,116,104,0,1,1,0,11,118,0,0,0,1,3,2,0,9,1,114,0,0,0,3,2,1,9,1,112,0,2, +58,100,111,116,0,18,118,0,0,18,118,0,0,0,0,0,4,102,108,111,97,116,95,114,115,113,0,18,114,0,0,18, +112,0,0,0,4,102,108,111,97,116,95,114,99,112,0,18,95,95,114,101,116,86,97,108,0,59,120,0,0,18,114, +0,0,0,0,1,0,9,0,108,101,110,103,116,104,0,1,1,0,12,118,0,0,0,1,3,2,0,9,1,114,0,0,0,3,2,1,9,1,112,0, +2,58,100,111,116,0,18,118,0,0,18,118,0,0,0,0,0,4,102,108,111,97,116,95,114,115,113,0,18,114,0,0,18, +112,0,0,0,4,102,108,111,97,116,95,114,99,112,0,18,95,95,114,101,116,86,97,108,0,59,120,0,0,18,114, +0,0,0,0,1,0,9,0,100,105,115,116,97,110,99,101,0,1,1,0,9,120,0,0,1,1,0,9,121,0,0,0,1,3,2,1,9,1,100, +0,2,18,120,0,18,121,0,47,0,0,9,18,95,95,114,101,116,86,97,108,0,58,108,101,110,103,116,104,0,18, +100,0,0,0,20,0,0,1,0,9,0,100,105,115,116,97,110,99,101,0,1,1,0,10,118,0,0,1,1,0,10,117,0,0,0,1,3,2, +1,10,1,100,50,0,2,18,118,0,18,117,0,47,0,0,9,18,95,95,114,101,116,86,97,108,0,58,108,101,110,103, +116,104,0,18,100,50,0,0,0,20,0,0,1,0,9,0,100,105,115,116,97,110,99,101,0,1,1,0,11,118,0,0,1,1,0,11, +117,0,0,0,1,3,2,1,11,1,100,51,0,2,18,118,0,18,117,0,47,0,0,9,18,95,95,114,101,116,86,97,108,0,58, +108,101,110,103,116,104,0,18,100,51,0,0,0,20,0,0,1,0,9,0,100,105,115,116,97,110,99,101,0,1,1,0,12, +118,0,0,1,1,0,12,117,0,0,0,1,3,2,1,12,1,100,52,0,2,18,118,0,18,117,0,47,0,0,9,18,95,95,114,101,116, +86,97,108,0,58,108,101,110,103,116,104,0,18,100,52,0,0,0,20,0,0,1,0,11,0,99,114,111,115,115,0,1,1, +0,11,118,0,0,1,1,0,11,117,0,0,0,1,4,118,101,99,51,95,99,114,111,115,115,0,18,95,95,114,101,116,86, +97,108,0,59,120,121,122,0,0,18,118,0,0,18,117,0,0,0,0,1,0,9,0,102,97,99,101,102,111,114,119,97,114, +100,0,1,1,0,9,78,0,0,1,1,0,9,73,0,0,1,1,0,9,78,114,101,102,0,0,0,1,3,2,1,9,1,100,0,2,58,100,111, +116,0,18,78,114,101,102,0,0,18,73,0,0,0,0,0,3,2,0,9,1,115,0,0,0,4,118,101,99,52,95,115,103,116,0, +18,115,0,59,120,0,0,17,48,0,48,0,0,0,18,100,0,0,0,8,58,109,105,120,0,18,78,0,54,0,18,78,0,0,18,115, +0,0,0,0,0,1,0,10,0,102,97,99,101,102,111,114,119,97,114,100,0,1,1,0,10,78,0,0,1,1,0,10,73,0,0,1,1, +0,10,78,114,101,102,0,0,0,1,3,2,1,9,1,100,0,2,58,100,111,116,0,18,78,114,101,102,0,0,18,73,0,0,0,0, +0,3,2,0,9,1,115,0,0,0,4,118,101,99,52,95,115,103,116,0,18,115,0,59,120,0,0,17,48,0,48,0,0,0,18,100, +0,0,0,8,58,109,105,120,0,18,78,0,54,0,18,78,0,0,18,115,0,0,0,0,0,1,0,11,0,102,97,99,101,102,111, +114,119,97,114,100,0,1,1,0,11,78,0,0,1,1,0,11,73,0,0,1,1,0,11,78,114,101,102,0,0,0,1,3,2,1,9,1,100, +0,2,58,100,111,116,0,18,78,114,101,102,0,0,18,73,0,0,0,0,0,3,2,0,9,1,115,0,0,0,4,118,101,99,52,95, +115,103,116,0,18,115,0,59,120,0,0,17,48,0,48,0,0,0,18,100,0,0,0,8,58,109,105,120,0,18,78,0,54,0,18, +78,0,0,18,115,0,0,0,0,0,1,0,12,0,102,97,99,101,102,111,114,119,97,114,100,0,1,1,0,12,78,0,0,1,1,0, +12,73,0,0,1,1,0,12,78,114,101,102,0,0,0,1,3,2,1,9,1,100,0,2,58,100,111,116,0,18,78,114,101,102,0,0, +18,73,0,0,0,0,0,3,2,0,9,1,115,0,0,0,4,118,101,99,52,95,115,103,116,0,18,115,0,59,120,0,0,17,48,0, +48,0,0,0,18,100,0,0,0,8,58,109,105,120,0,18,78,0,54,0,18,78,0,0,18,115,0,0,0,0,0,1,0,9,0,114,101, +102,108,101,99,116,0,1,1,0,9,73,0,0,1,1,0,9,78,0,0,0,1,8,18,73,0,17,50,0,48,0,0,58,100,111,116,0, +18,78,0,0,18,73,0,0,0,48,18,78,0,48,47,0,0,1,0,10,0,114,101,102,108,101,99,116,0,1,1,0,10,73,0,0,1, +1,0,10,78,0,0,0,1,8,18,73,0,17,50,0,48,0,0,58,100,111,116,0,18,78,0,0,18,73,0,0,0,48,18,78,0,48,47, +0,0,1,0,11,0,114,101,102,108,101,99,116,0,1,1,0,11,73,0,0,1,1,0,11,78,0,0,0,1,8,18,73,0,17,50,0,48, +0,0,58,100,111,116,0,18,78,0,0,18,73,0,0,0,48,18,78,0,48,47,0,0,1,0,12,0,114,101,102,108,101,99, +116,0,1,1,0,12,73,0,0,1,1,0,12,78,0,0,0,1,8,18,73,0,17,50,0,48,0,0,58,100,111,116,0,18,78,0,0,18, +73,0,0,0,48,18,78,0,48,47,0,0,1,0,9,0,114,101,102,114,97,99,116,0,1,1,0,9,73,0,0,1,1,0,9,78,0,0,1, +1,0,9,101,116,97,0,0,0,1,3,2,0,9,1,107,0,2,17,49,0,48,0,0,18,101,116,97,0,18,101,116,97,0,48,17,49, +0,48,0,0,58,100,111,116,0,18,78,0,0,18,73,0,0,0,58,100,111,116,0,18,78,0,0,18,73,0,0,0,48,47,48,47, +0,0,10,18,107,0,17,48,0,48,0,0,40,0,8,17,48,0,48,0,0,0,9,14,0,8,18,101,116,97,0,18,73,0,48,18,101, +116,97,0,58,100,111,116,0,18,78,0,0,18,73,0,0,0,48,58,115,113,114,116,0,18,107,0,0,0,46,18,78,0,48, +47,0,0,1,0,10,0,114,101,102,114,97,99,116,0,1,1,0,10,73,0,0,1,1,0,10,78,0,0,1,1,0,9,101,116,97,0,0, +0,1,3,2,0,9,1,107,0,2,17,49,0,48,0,0,18,101,116,97,0,18,101,116,97,0,48,17,49,0,48,0,0,58,100,111, +116,0,18,78,0,0,18,73,0,0,0,58,100,111,116,0,18,78,0,0,18,73,0,0,0,48,47,48,47,0,0,10,18,107,0,17, +48,0,48,0,0,40,0,8,17,48,0,48,0,0,0,9,14,0,8,18,101,116,97,0,18,73,0,48,18,101,116,97,0,58,100,111, +116,0,18,78,0,0,18,73,0,0,0,48,58,115,113,114,116,0,18,107,0,0,0,46,18,78,0,48,47,0,0,1,0,11,0,114, +101,102,114,97,99,116,0,1,1,0,11,73,0,0,1,1,0,11,78,0,0,1,1,0,9,101,116,97,0,0,0,1,3,2,0,9,1,107,0, +2,17,49,0,48,0,0,18,101,116,97,0,18,101,116,97,0,48,17,49,0,48,0,0,58,100,111,116,0,18,78,0,0,18, +73,0,0,0,58,100,111,116,0,18,78,0,0,18,73,0,0,0,48,47,48,47,0,0,10,18,107,0,17,48,0,48,0,0,40,0,8, +17,48,0,48,0,0,0,9,14,0,8,18,101,116,97,0,18,73,0,48,18,101,116,97,0,58,100,111,116,0,18,78,0,0,18, +73,0,0,0,48,58,115,113,114,116,0,18,107,0,0,0,46,18,78,0,48,47,0,0,1,0,12,0,114,101,102,114,97,99, +116,0,1,1,0,12,73,0,0,1,1,0,12,78,0,0,1,1,0,9,101,116,97,0,0,0,1,3,2,0,9,1,107,0,2,17,49,0,48,0,0, +18,101,116,97,0,18,101,116,97,0,48,17,49,0,48,0,0,58,100,111,116,0,18,78,0,0,18,73,0,0,0,58,100, +111,116,0,18,78,0,0,18,73,0,0,0,48,47,48,47,0,0,10,18,107,0,17,48,0,48,0,0,40,0,8,17,48,0,48,0,0,0, +9,14,0,8,18,101,116,97,0,18,73,0,48,18,101,116,97,0,58,100,111,116,0,18,78,0,0,18,73,0,0,0,48,58, +115,113,114,116,0,18,107,0,0,0,46,18,78,0,48,47,0,0,1,0,13,0,109,97,116,114,105,120,67,111,109,112, +77,117,108,116,0,1,0,0,13,109,0,0,1,0,0,13,110,0,0,0,1,8,58,109,97,116,50,0,18,109,0,16,8,48,0,57, +18,110,0,16,8,48,0,57,48,0,18,109,0,16,10,49,0,57,18,110,0,16,10,49,0,57,48,0,0,0,0,1,0,14,0,109, +97,116,114,105,120,67,111,109,112,77,117,108,116,0,1,0,0,14,109,0,0,1,0,0,14,110,0,0,0,1,8,58,109, +97,116,51,0,18,109,0,16,8,48,0,57,18,110,0,16,8,48,0,57,48,0,18,109,0,16,10,49,0,57,18,110,0,16,10, +49,0,57,48,0,18,109,0,16,10,50,0,57,18,110,0,16,10,50,0,57,48,0,0,0,0,1,0,15,0,109,97,116,114,105, +120,67,111,109,112,77,117,108,116,0,1,0,0,15,109,0,0,1,0,0,15,110,0,0,0,1,8,58,109,97,116,52,0,18, +109,0,16,8,48,0,57,18,110,0,16,8,48,0,57,48,0,18,109,0,16,10,49,0,57,18,110,0,16,10,49,0,57,48,0, +18,109,0,16,10,50,0,57,18,110,0,16,10,50,0,57,48,0,18,109,0,16,10,51,0,57,18,110,0,16,10,51,0,57, +48,0,0,0,0,1,0,2,0,108,101,115,115,84,104,97,110,0,1,1,0,10,117,0,0,1,1,0,10,118,0,0,0,1,4,118,101, +99,52,95,115,108,116,0,18,95,95,114,101,116,86,97,108,0,59,120,121,0,0,18,117,0,0,18,118,0,0,0,0,1, +0,3,0,108,101,115,115,84,104,97,110,0,1,1,0,11,117,0,0,1,1,0,11,118,0,0,0,1,4,118,101,99,52,95,115, +108,116,0,18,95,95,114,101,116,86,97,108,0,59,120,121,122,0,0,18,117,0,0,18,118,0,0,0,0,1,0,4,0, +108,101,115,115,84,104,97,110,0,1,1,0,12,117,0,0,1,1,0,12,118,0,0,0,1,4,118,101,99,52,95,115,108, +116,0,18,95,95,114,101,116,86,97,108,0,0,18,117,0,0,18,118,0,0,0,0,1,0,2,0,108,101,115,115,84,104, +97,110,0,1,1,0,6,117,0,0,1,1,0,6,118,0,0,0,1,4,118,101,99,52,95,115,108,116,0,18,95,95,114,101,116, +86,97,108,0,59,120,121,0,0,18,117,0,0,18,118,0,0,0,0,1,0,3,0,108,101,115,115,84,104,97,110,0,1,1,0, +7,117,0,0,1,1,0,7,118,0,0,0,1,4,118,101,99,52,95,115,108,116,0,18,95,95,114,101,116,86,97,108,0,59, +120,121,122,0,0,18,117,0,0,18,118,0,0,0,0,1,0,4,0,108,101,115,115,84,104,97,110,0,1,1,0,8,117,0,0, +1,1,0,8,118,0,0,0,1,4,118,101,99,52,95,115,108,116,0,18,95,95,114,101,116,86,97,108,0,0,18,117,0,0, +18,118,0,0,0,0,1,0,2,0,108,101,115,115,84,104,97,110,69,113,117,97,108,0,1,1,0,10,117,0,0,1,1,0,10, +118,0,0,0,1,4,118,101,99,52,95,115,108,101,0,18,95,95,114,101,116,86,97,108,0,59,120,121,0,0,18, +117,0,0,18,118,0,0,0,0,1,0,3,0,108,101,115,115,84,104,97,110,69,113,117,97,108,0,1,1,0,11,117,0,0, +1,1,0,11,118,0,0,0,1,4,118,101,99,52,95,115,108,101,0,18,95,95,114,101,116,86,97,108,0,59,120,121, +122,0,0,18,117,0,0,18,118,0,0,0,0,1,0,4,0,108,101,115,115,84,104,97,110,69,113,117,97,108,0,1,1,0, +12,117,0,0,1,1,0,12,118,0,0,0,1,4,118,101,99,52,95,115,108,101,0,18,95,95,114,101,116,86,97,108,0, +0,18,117,0,0,18,118,0,0,0,0,1,0,2,0,108,101,115,115,84,104,97,110,69,113,117,97,108,0,1,1,0,6,117, +0,0,1,1,0,6,118,0,0,0,1,4,118,101,99,52,95,115,108,101,0,18,95,95,114,101,116,86,97,108,0,59,120, +121,0,0,18,117,0,0,18,118,0,0,0,0,1,0,3,0,108,101,115,115,84,104,97,110,69,113,117,97,108,0,1,1,0, +7,117,0,0,1,1,0,7,118,0,0,0,1,4,118,101,99,52,95,115,108,101,0,18,95,95,114,101,116,86,97,108,0,59, +120,121,122,0,0,18,117,0,0,18,118,0,0,0,0,1,0,4,0,108,101,115,115,84,104,97,110,69,113,117,97,108, +0,1,1,0,8,117,0,0,1,1,0,8,118,0,0,0,1,4,118,101,99,52,95,115,108,101,0,18,95,95,114,101,116,86,97, +108,0,0,18,117,0,0,18,118,0,0,0,0,1,0,2,0,103,114,101,97,116,101,114,84,104,97,110,0,1,1,0,10,117, +0,0,1,1,0,10,118,0,0,0,1,4,118,101,99,52,95,115,103,116,0,18,95,95,114,101,116,86,97,108,0,59,120, +121,0,0,18,117,0,0,18,118,0,0,0,0,1,0,3,0,103,114,101,97,116,101,114,84,104,97,110,0,1,1,0,11,117, +0,0,1,1,0,11,118,0,0,0,1,4,118,101,99,52,95,115,103,116,0,18,95,95,114,101,116,86,97,108,0,59,120, +121,122,0,0,18,117,0,0,18,118,0,0,0,0,1,0,4,0,103,114,101,97,116,101,114,84,104,97,110,0,1,1,0,12, +117,0,0,1,1,0,12,118,0,0,0,1,4,118,101,99,52,95,115,103,116,0,18,95,95,114,101,116,86,97,108,0,0, +18,117,0,0,18,118,0,0,0,0,1,0,2,0,103,114,101,97,116,101,114,84,104,97,110,0,1,1,0,6,117,0,0,1,1,0, +6,118,0,0,0,1,4,118,101,99,52,95,115,103,116,0,18,95,95,114,101,116,86,97,108,0,59,120,121,0,0,18, +117,0,0,18,118,0,0,0,0,1,0,3,0,103,114,101,97,116,101,114,84,104,97,110,0,1,1,0,7,117,0,0,1,1,0,7, +118,0,0,0,1,4,118,101,99,52,95,115,103,116,0,18,95,95,114,101,116,86,97,108,0,59,120,121,122,0,0, +18,117,0,0,18,118,0,0,0,0,1,0,4,0,103,114,101,97,116,101,114,84,104,97,110,0,1,1,0,8,117,0,0,1,1,0, +8,118,0,0,0,1,4,118,101,99,52,95,115,103,116,0,18,95,95,114,101,116,86,97,108,0,0,18,117,0,0,18, +118,0,0,0,0,1,0,2,0,103,114,101,97,116,101,114,84,104,97,110,69,113,117,97,108,0,1,1,0,10,117,0,0, +1,1,0,10,118,0,0,0,1,4,118,101,99,52,95,115,103,101,0,18,95,95,114,101,116,86,97,108,0,59,120,121, +0,0,18,117,0,0,18,118,0,0,0,0,1,0,3,0,103,114,101,97,116,101,114,84,104,97,110,69,113,117,97,108,0, +1,1,0,11,117,0,0,1,1,0,11,118,0,0,0,1,4,118,101,99,52,95,115,103,101,0,18,95,95,114,101,116,86,97, +108,0,59,120,121,122,0,0,18,117,0,0,18,118,0,0,0,0,1,0,4,0,103,114,101,97,116,101,114,84,104,97, +110,69,113,117,97,108,0,1,1,0,12,117,0,0,1,1,0,12,118,0,0,0,1,4,118,101,99,52,95,115,103,101,0,18, +95,95,114,101,116,86,97,108,0,0,18,117,0,0,18,118,0,0,0,0,1,0,2,0,103,114,101,97,116,101,114,84, +104,97,110,69,113,117,97,108,0,1,1,0,6,117,0,0,1,1,0,6,118,0,0,0,1,4,118,101,99,52,95,115,103,101, +0,18,95,95,114,101,116,86,97,108,0,59,120,121,0,0,18,117,0,0,18,118,0,0,0,0,1,0,3,0,103,114,101,97, +116,101,114,84,104,97,110,69,113,117,97,108,0,1,1,0,7,117,0,0,1,1,0,7,118,0,0,0,1,4,118,101,99,52, +95,115,103,101,0,18,95,95,114,101,116,86,97,108,0,59,120,121,122,0,0,18,117,0,0,18,118,0,0,0,0,1,0, +4,0,103,114,101,97,116,101,114,84,104,97,110,69,113,117,97,108,0,1,1,0,8,117,0,0,1,1,0,8,118,0,0,0, +1,4,118,101,99,52,95,115,103,101,0,18,95,95,114,101,116,86,97,108,0,0,18,117,0,0,18,118,0,0,0,0,1, +0,2,0,101,113,117,97,108,0,1,1,0,10,117,0,0,1,1,0,10,118,0,0,0,1,4,118,101,99,52,95,115,101,113,0, +18,95,95,114,101,116,86,97,108,0,59,120,121,0,0,18,117,0,0,18,118,0,0,0,0,1,0,3,0,101,113,117,97, +108,0,1,1,0,11,117,0,0,1,1,0,11,118,0,0,0,1,4,118,101,99,52,95,115,101,113,0,18,95,95,114,101,116, +86,97,108,0,59,120,121,122,0,0,18,117,0,0,18,118,0,0,0,0,1,0,4,0,101,113,117,97,108,0,1,1,0,12,117, +0,0,1,1,0,12,118,0,0,0,1,4,118,101,99,52,95,115,101,113,0,18,95,95,114,101,116,86,97,108,0,0,18, +117,0,0,18,118,0,0,0,0,1,0,2,0,101,113,117,97,108,0,1,1,0,6,117,0,0,1,1,0,6,118,0,0,0,1,4,118,101, +99,52,95,115,101,113,0,18,95,95,114,101,116,86,97,108,0,59,120,121,0,0,18,117,0,0,18,118,0,0,0,0,1, +0,3,0,101,113,117,97,108,0,1,1,0,7,117,0,0,1,1,0,7,118,0,0,0,1,4,118,101,99,52,95,115,101,113,0,18, +95,95,114,101,116,86,97,108,0,59,120,121,122,0,0,18,117,0,0,18,118,0,0,0,0,1,0,4,0,101,113,117,97, +108,0,1,1,0,8,117,0,0,1,1,0,8,118,0,0,0,1,4,118,101,99,52,95,115,101,113,0,18,95,95,114,101,116,86, +97,108,0,0,18,117,0,0,18,118,0,0,0,0,1,0,2,0,110,111,116,69,113,117,97,108,0,1,1,0,10,117,0,0,1,1, +0,10,118,0,0,0,1,4,118,101,99,52,95,115,110,101,0,18,95,95,114,101,116,86,97,108,0,59,120,121,0,0, +18,117,0,0,18,118,0,0,0,0,1,0,3,0,110,111,116,69,113,117,97,108,0,1,1,0,11,117,0,0,1,1,0,11,118,0, +0,0,1,4,118,101,99,52,95,115,110,101,0,18,95,95,114,101,116,86,97,108,0,59,120,121,122,0,0,18,117, +0,0,18,118,0,0,0,0,1,0,4,0,110,111,116,69,113,117,97,108,0,1,1,0,12,117,0,0,1,1,0,12,118,0,0,0,1,4, +118,101,99,52,95,115,110,101,0,18,95,95,114,101,116,86,97,108,0,0,18,117,0,0,18,118,0,0,0,0,1,0,2, +0,110,111,116,69,113,117,97,108,0,1,1,0,6,117,0,0,1,1,0,6,118,0,0,0,1,4,118,101,99,52,95,115,110, +101,0,18,95,95,114,101,116,86,97,108,0,59,120,121,0,0,18,117,0,0,18,118,0,0,0,0,1,0,3,0,110,111, +116,69,113,117,97,108,0,1,1,0,7,117,0,0,1,1,0,7,118,0,0,0,1,4,118,101,99,52,95,115,110,101,0,18,95, +95,114,101,116,86,97,108,0,59,120,121,122,0,0,18,117,0,0,18,118,0,0,0,0,1,0,4,0,110,111,116,69,113, +117,97,108,0,1,1,0,8,117,0,0,1,1,0,8,118,0,0,0,1,4,118,101,99,52,95,115,110,101,0,18,95,95,114,101, +116,86,97,108,0,0,18,117,0,0,18,118,0,0,0,0,1,0,1,0,97,110,121,0,1,1,0,2,118,0,0,0,1,3,2,0,9,1,115, +117,109,0,0,0,4,118,101,99,52,95,97,100,100,0,18,115,117,109,0,59,120,0,0,18,118,0,59,120,0,0,18, +118,0,59,121,0,0,0,4,118,101,99,52,95,115,110,101,0,18,95,95,114,101,116,86,97,108,0,59,120,0,0,18, +115,117,109,0,59,120,0,0,17,48,0,48,0,0,0,0,0,1,0,1,0,97,110,121,0,1,1,0,3,118,0,0,0,1,3,2,0,9,1, +115,117,109,0,0,0,4,118,101,99,52,95,97,100,100,0,18,115,117,109,0,59,120,0,0,18,118,0,59,120,0,0, +18,118,0,59,121,0,0,0,4,118,101,99,52,95,97,100,100,0,18,115,117,109,0,59,120,0,0,18,115,117,109,0, +59,120,0,0,18,118,0,59,122,0,0,0,4,118,101,99,52,95,115,110,101,0,18,95,95,114,101,116,86,97,108,0, +59,120,0,0,18,115,117,109,0,59,120,0,0,17,48,0,48,0,0,0,0,0,1,0,1,0,97,110,121,0,1,1,0,4,118,0,0,0, +1,3,2,0,9,1,115,117,109,0,0,0,4,118,101,99,52,95,97,100,100,0,18,115,117,109,0,59,120,0,0,18,118,0, +59,120,0,0,18,118,0,59,121,0,0,0,4,118,101,99,52,95,97,100,100,0,18,115,117,109,0,59,120,0,0,18, +115,117,109,0,59,120,0,0,18,118,0,59,122,0,0,0,4,118,101,99,52,95,97,100,100,0,18,115,117,109,0,59, +120,0,0,18,115,117,109,0,59,120,0,0,18,118,0,59,119,0,0,0,4,118,101,99,52,95,115,110,101,0,18,95, +95,114,101,116,86,97,108,0,59,120,0,0,18,115,117,109,0,59,120,0,0,17,48,0,48,0,0,0,0,0,1,0,1,0,97, +108,108,0,1,1,0,10,118,0,0,0,1,3,2,0,9,1,112,114,111,100,0,0,0,4,118,101,99,52,95,109,117,108,116, +105,112,108,121,0,18,112,114,111,100,0,59,120,0,0,18,118,0,59,120,0,0,18,118,0,59,121,0,0,0,4,118, +101,99,52,95,115,110,101,0,18,95,95,114,101,116,86,97,108,0,59,120,0,0,18,112,114,111,100,0,59,120, +0,0,17,48,0,48,0,0,0,0,8,18,118,0,59,120,0,18,118,0,59,121,0,34,0,0,1,0,1,0,97,108,108,0,1,1,0,3, +118,0,0,0,1,3,2,0,9,1,112,114,111,100,0,0,0,4,118,101,99,52,95,109,117,108,116,105,112,108,121,0, +18,112,114,111,100,0,59,120,0,0,18,118,0,59,120,0,0,18,118,0,59,121,0,0,0,4,118,101,99,52,95,109, +117,108,116,105,112,108,121,0,18,112,114,111,100,0,59,120,0,0,18,112,114,111,100,0,59,120,0,0,18, +118,0,59,122,0,0,0,4,118,101,99,52,95,115,110,101,0,18,95,95,114,101,116,86,97,108,0,59,120,0,0,18, +112,114,111,100,0,59,120,0,0,17,48,0,48,0,0,0,0,0,1,0,1,0,97,108,108,0,1,1,0,4,118,0,0,0,1,3,2,0,9, +1,112,114,111,100,0,0,0,4,118,101,99,52,95,109,117,108,116,105,112,108,121,0,18,112,114,111,100,0, +59,120,0,0,18,118,0,59,120,0,0,18,118,0,59,121,0,0,0,4,118,101,99,52,95,109,117,108,116,105,112, +108,121,0,18,112,114,111,100,0,59,120,0,0,18,112,114,111,100,0,59,120,0,0,18,118,0,59,122,0,0,0,4, +118,101,99,52,95,109,117,108,116,105,112,108,121,0,18,112,114,111,100,0,59,120,0,0,18,112,114,111, +100,0,59,120,0,0,18,118,0,59,119,0,0,0,4,118,101,99,52,95,115,110,101,0,18,95,95,114,101,116,86,97, +108,0,59,120,0,0,18,112,114,111,100,0,59,120,0,0,17,48,0,48,0,0,0,0,0,1,0,2,0,110,111,116,0,1,1,0, +2,118,0,0,0,1,4,118,101,99,52,95,115,101,113,0,18,95,95,114,101,116,86,97,108,0,59,120,121,0,0,18, +118,0,0,17,48,0,48,0,0,0,0,0,1,0,3,0,110,111,116,0,1,1,0,3,118,0,0,0,1,4,118,101,99,52,95,115,101, +113,0,18,95,95,114,101,116,86,97,108,0,59,120,121,122,0,0,18,118,0,0,17,48,0,48,0,0,0,0,0,1,0,4,0, +110,111,116,0,1,1,0,4,118,0,0,0,1,4,118,101,99,52,95,115,101,113,0,18,95,95,114,101,116,86,97,108, +0,0,18,118,0,0,17,48,0,48,0,0,0,0,0,1,0,12,0,116,101,120,116,117,114,101,49,68,0,1,1,0,16,115,97, +109,112,108,101,114,0,0,1,1,0,9,99,111,111,114,100,0,0,0,1,4,118,101,99,52,95,116,101,120,49,100,0, +18,95,95,114,101,116,86,97,108,0,0,18,115,97,109,112,108,101,114,0,0,18,99,111,111,114,100,0,0,0,0, +1,0,12,0,116,101,120,116,117,114,101,49,68,80,114,111,106,0,1,1,0,16,115,97,109,112,108,101,114,0, +0,1,1,0,10,99,111,111,114,100,0,0,0,1,3,2,0,12,1,99,111,111,114,100,52,0,0,0,9,18,99,111,111,114, +100,52,0,59,120,0,18,99,111,111,114,100,0,59,120,0,20,0,9,18,99,111,111,114,100,52,0,59,119,0,18, +99,111,111,114,100,0,59,121,0,20,0,4,118,101,99,52,95,116,101,120,112,49,100,0,18,95,95,114,101, +116,86,97,108,0,0,18,115,97,109,112,108,101,114,0,0,18,99,111,111,114,100,52,0,0,0,0,1,0,12,0,116, +101,120,116,117,114,101,49,68,80,114,111,106,0,1,1,0,16,115,97,109,112,108,101,114,0,0,1,1,0,12,99, +111,111,114,100,0,0,0,1,4,118,101,99,52,95,116,101,120,112,49,100,0,18,95,95,114,101,116,86,97,108, +0,0,18,115,97,109,112,108,101,114,0,0,18,99,111,111,114,100,0,0,0,0,1,0,12,0,116,101,120,116,117, +114,101,50,68,0,1,1,0,17,115,97,109,112,108,101,114,0,0,1,1,0,10,99,111,111,114,100,0,0,0,1,4,118, +101,99,52,95,116,101,120,50,100,0,18,95,95,114,101,116,86,97,108,0,0,18,115,97,109,112,108,101,114, +0,0,18,99,111,111,114,100,0,0,0,0,1,0,12,0,116,101,120,116,117,114,101,50,68,80,114,111,106,0,1,1, +0,17,115,97,109,112,108,101,114,0,0,1,1,0,11,99,111,111,114,100,0,0,0,1,3,2,0,12,1,99,111,111,114, +100,52,0,0,0,9,18,99,111,111,114,100,52,0,59,120,121,0,18,99,111,111,114,100,0,59,120,121,0,20,0,9, +18,99,111,111,114,100,52,0,59,119,0,18,99,111,111,114,100,0,59,122,0,20,0,4,118,101,99,52,95,116, +101,120,112,50,100,0,18,95,95,114,101,116,86,97,108,0,0,18,115,97,109,112,108,101,114,0,0,18,99, +111,111,114,100,52,0,0,0,0,1,0,12,0,116,101,120,116,117,114,101,50,68,80,114,111,106,0,1,1,0,17, +115,97,109,112,108,101,114,0,0,1,1,0,12,99,111,111,114,100,0,0,0,1,4,118,101,99,52,95,116,101,120, +112,50,100,0,18,95,95,114,101,116,86,97,108,0,0,18,115,97,109,112,108,101,114,0,0,18,99,111,111, +114,100,0,0,0,0,1,0,12,0,116,101,120,116,117,114,101,51,68,0,1,1,0,18,115,97,109,112,108,101,114,0, +0,1,1,0,11,99,111,111,114,100,0,0,0,1,4,118,101,99,52,95,116,101,120,51,100,0,18,95,95,114,101,116, +86,97,108,0,0,18,115,97,109,112,108,101,114,0,0,18,99,111,111,114,100,0,0,0,0,1,0,12,0,116,101,120, +116,117,114,101,51,68,80,114,111,106,0,1,1,0,18,115,97,109,112,108,101,114,0,0,1,1,0,12,99,111,111, +114,100,0,0,0,1,4,118,101,99,52,95,116,101,120,112,51,100,0,18,95,95,114,101,116,86,97,108,0,0,18, +115,97,109,112,108,101,114,0,0,18,99,111,111,114,100,0,0,0,0,1,0,12,0,116,101,120,116,117,114,101, +67,117,98,101,0,1,1,0,19,115,97,109,112,108,101,114,0,0,1,1,0,11,99,111,111,114,100,0,0,0,1,4,118, +101,99,52,95,116,101,120,99,117,98,101,0,18,95,95,114,101,116,86,97,108,0,0,18,115,97,109,112,108, +101,114,0,0,18,99,111,111,114,100,0,0,0,0,1,0,12,0,115,104,97,100,111,119,49,68,0,1,0,0,20,115,97, 109,112,108,101,114,0,0,1,0,0,11,99,111,111,114,100,0,0,0,1,3,2,0,12,1,116,101,120,101,108,0,0,0,4, -118,101,99,52,95,116,101,120,51,100,0,18,116,101,120,101,108,0,0,18,115,97,109,112,108,101,114,0,0, -18,99,111,111,114,100,0,0,17,48,0,48,0,0,0,0,8,18,116,101,120,101,108,0,0,0,1,0,12,0,116,101,120, -116,117,114,101,51,68,80,114,111,106,0,1,0,0,18,115,97,109,112,108,101,114,0,0,1,0,0,12,99,111,111, -114,100,0,0,0,1,8,58,116,101,120,116,117,114,101,51,68,0,18,115,97,109,112,108,101,114,0,0,58,118, -101,99,51,0,18,99,111,111,114,100,0,59,115,0,18,99,111,111,114,100,0,59,113,0,49,0,18,99,111,111, -114,100,0,59,116,0,18,99,111,111,114,100,0,59,113,0,49,0,18,99,111,111,114,100,0,59,112,0,18,99, -111,111,114,100,0,59,113,0,49,0,0,0,0,0,0,1,0,12,0,116,101,120,116,117,114,101,67,117,98,101,0,1,0, -0,19,115,97,109,112,108,101,114,0,0,1,0,0,11,99,111,111,114,100,0,0,0,1,3,2,0,12,1,116,101,120,101, -108,0,0,0,4,118,101,99,52,95,116,101,120,99,117,98,101,0,18,116,101,120,101,108,0,0,18,115,97,109, -112,108,101,114,0,0,18,99,111,111,114,100,0,0,17,48,0,48,0,0,0,0,8,18,116,101,120,101,108,0,0,0,1, -0,12,0,115,104,97,100,111,119,49,68,0,1,0,0,20,115,97,109,112,108,101,114,0,0,1,0,0,11,99,111,111, -114,100,0,0,0,1,3,2,0,12,1,116,101,120,101,108,0,0,0,4,118,101,99,52,95,115,104,97,100,49,100,0,18, -116,101,120,101,108,0,0,18,115,97,109,112,108,101,114,0,0,18,99,111,111,114,100,0,0,17,48,0,48,0,0, -0,0,8,18,116,101,120,101,108,0,0,0,1,0,12,0,115,104,97,100,111,119,49,68,80,114,111,106,0,1,0,0,20, -115,97,109,112,108,101,114,0,0,1,0,0,12,99,111,111,114,100,0,0,0,1,8,58,115,104,97,100,111,119,49, -68,0,18,115,97,109,112,108,101,114,0,0,58,118,101,99,51,0,18,99,111,111,114,100,0,59,115,0,18,99, -111,111,114,100,0,59,113,0,49,0,17,48,0,48,0,0,0,18,99,111,111,114,100,0,59,112,0,18,99,111,111, -114,100,0,59,113,0,49,0,0,0,0,0,0,1,0,12,0,115,104,97,100,111,119,50,68,0,1,0,0,21,115,97,109,112, -108,101,114,0,0,1,0,0,11,99,111,111,114,100,0,0,0,1,3,2,0,12,1,116,101,120,101,108,0,0,0,4,118,101, -99,52,95,115,104,97,100,50,100,0,18,116,101,120,101,108,0,0,18,115,97,109,112,108,101,114,0,0,18, -99,111,111,114,100,0,0,17,48,0,48,0,0,0,0,8,18,116,101,120,101,108,0,0,0,1,0,12,0,115,104,97,100, -111,119,50,68,80,114,111,106,0,1,0,0,21,115,97,109,112,108,101,114,0,0,1,0,0,12,99,111,111,114,100, -0,0,0,1,8,58,115,104,97,100,111,119,50,68,0,18,115,97,109,112,108,101,114,0,0,58,118,101,99,51,0, -18,99,111,111,114,100,0,59,115,0,18,99,111,111,114,100,0,59,113,0,49,0,18,99,111,111,114,100,0,59, -116,0,18,99,111,111,114,100,0,59,113,0,49,0,18,99,111,111,114,100,0,59,112,0,18,99,111,111,114,100, -0,59,113,0,49,0,0,0,0,0,0,1,0,9,0,110,111,105,115,101,49,0,1,0,0,9,120,0,0,0,1,3,2,0,9,1,97,0,0,0, -4,102,108,111,97,116,95,110,111,105,115,101,49,0,18,97,0,0,18,120,0,0,0,8,18,97,0,0,0,1,0,9,0,110, -111,105,115,101,49,0,1,0,0,10,120,0,0,0,1,3,2,0,9,1,97,0,0,0,4,102,108,111,97,116,95,110,111,105, -115,101,50,0,18,97,0,0,18,120,0,0,0,8,18,97,0,0,0,1,0,9,0,110,111,105,115,101,49,0,1,0,0,11,120,0, -0,0,1,3,2,0,9,1,97,0,0,0,4,102,108,111,97,116,95,110,111,105,115,101,51,0,18,97,0,0,18,120,0,0,0,8, -18,97,0,0,0,1,0,9,0,110,111,105,115,101,49,0,1,0,0,12,120,0,0,0,1,3,2,0,9,1,97,0,0,0,4,102,108,111, -97,116,95,110,111,105,115,101,52,0,18,97,0,0,18,120,0,0,0,8,18,97,0,0,0,1,0,10,0,110,111,105,115, -101,50,0,1,0,0,9,120,0,0,0,1,8,58,118,101,99,50,0,58,110,111,105,115,101,49,0,18,120,0,0,0,0,58, -110,111,105,115,101,49,0,18,120,0,17,49,57,0,51,52,0,0,46,0,0,0,0,0,0,1,0,10,0,110,111,105,115,101, -50,0,1,0,0,10,120,0,0,0,1,8,58,118,101,99,50,0,58,110,111,105,115,101,49,0,18,120,0,0,0,0,58,110, -111,105,115,101,49,0,18,120,0,58,118,101,99,50,0,17,49,57,0,51,52,0,0,0,17,55,0,54,54,0,0,0,0,46,0, -0,0,0,0,0,1,0,10,0,110,111,105,115,101,50,0,1,0,0,11,120,0,0,0,1,8,58,118,101,99,50,0,58,110,111, -105,115,101,49,0,18,120,0,0,0,0,58,110,111,105,115,101,49,0,18,120,0,58,118,101,99,51,0,17,49,57,0, -51,52,0,0,0,17,55,0,54,54,0,0,0,17,51,0,50,51,0,0,0,0,46,0,0,0,0,0,0,1,0,10,0,110,111,105,115,101, -50,0,1,0,0,12,120,0,0,0,1,8,58,118,101,99,50,0,58,110,111,105,115,101,49,0,18,120,0,0,0,0,58,110, -111,105,115,101,49,0,18,120,0,58,118,101,99,52,0,17,49,57,0,51,52,0,0,0,17,55,0,54,54,0,0,0,17,51, -0,50,51,0,0,0,17,50,0,55,55,0,0,0,0,46,0,0,0,0,0,0,1,0,11,0,110,111,105,115,101,51,0,1,0,0,9,120,0, -0,0,1,8,58,118,101,99,51,0,58,110,111,105,115,101,49,0,18,120,0,0,0,0,58,110,111,105,115,101,49,0, -18,120,0,17,49,57,0,51,52,0,0,46,0,0,0,58,110,111,105,115,101,49,0,18,120,0,17,53,0,52,55,0,0,46,0, -0,0,0,0,0,1,0,11,0,110,111,105,115,101,51,0,1,0,0,10,120,0,0,0,1,8,58,118,101,99,51,0,58,110,111, -105,115,101,49,0,18,120,0,0,0,0,58,110,111,105,115,101,49,0,18,120,0,58,118,101,99,50,0,17,49,57,0, -51,52,0,0,0,17,55,0,54,54,0,0,0,0,46,0,0,0,58,110,111,105,115,101,49,0,18,120,0,58,118,101,99,50,0, -17,53,0,52,55,0,0,0,17,49,55,0,56,53,0,0,0,0,46,0,0,0,0,0,0,1,0,11,0,110,111,105,115,101,51,0,1,0, -0,11,120,0,0,0,1,8,58,118,101,99,51,0,58,110,111,105,115,101,49,0,18,120,0,0,0,0,58,110,111,105, -115,101,49,0,18,120,0,58,118,101,99,51,0,17,49,57,0,51,52,0,0,0,17,55,0,54,54,0,0,0,17,51,0,50,51, -0,0,0,0,46,0,0,0,58,110,111,105,115,101,49,0,18,120,0,58,118,101,99,51,0,17,53,0,52,55,0,0,0,17,49, -55,0,56,53,0,0,0,17,49,49,0,48,52,0,0,0,0,46,0,0,0,0,0,0,1,0,11,0,110,111,105,115,101,51,0,1,0,0, -12,120,0,0,0,1,8,58,118,101,99,51,0,58,110,111,105,115,101,49,0,18,120,0,0,0,0,58,110,111,105,115, -101,49,0,18,120,0,58,118,101,99,52,0,17,49,57,0,51,52,0,0,0,17,55,0,54,54,0,0,0,17,51,0,50,51,0,0, -0,17,50,0,55,55,0,0,0,0,46,0,0,0,58,110,111,105,115,101,49,0,18,120,0,58,118,101,99,52,0,17,53,0, -52,55,0,0,0,17,49,55,0,56,53,0,0,0,17,49,49,0,48,52,0,0,0,17,49,51,0,49,57,0,0,0,0,46,0,0,0,0,0,0, -1,0,12,0,110,111,105,115,101,52,0,1,0,0,9,120,0,0,0,1,8,58,118,101,99,52,0,58,110,111,105,115,101, -49,0,18,120,0,0,0,0,58,110,111,105,115,101,49,0,18,120,0,17,49,57,0,51,52,0,0,46,0,0,0,58,110,111, -105,115,101,49,0,18,120,0,17,53,0,52,55,0,0,46,0,0,0,58,110,111,105,115,101,49,0,18,120,0,17,50,51, -0,53,52,0,0,46,0,0,0,0,0,0,1,0,12,0,110,111,105,115,101,52,0,1,0,0,10,120,0,0,0,1,8,58,118,101,99, -52,0,58,110,111,105,115,101,49,0,18,120,0,0,0,0,58,110,111,105,115,101,49,0,18,120,0,58,118,101,99, -50,0,17,49,57,0,51,52,0,0,0,17,55,0,54,54,0,0,0,0,46,0,0,0,58,110,111,105,115,101,49,0,18,120,0,58, -118,101,99,50,0,17,53,0,52,55,0,0,0,17,49,55,0,56,53,0,0,0,0,46,0,0,0,58,110,111,105,115,101,49,0, -18,120,0,58,118,101,99,50,0,17,50,51,0,53,52,0,0,0,17,50,57,0,49,49,0,0,0,0,46,0,0,0,0,0,0,1,0,12, -0,110,111,105,115,101,52,0,1,0,0,11,120,0,0,0,1,8,58,118,101,99,52,0,58,110,111,105,115,101,49,0, -18,120,0,0,0,0,58,110,111,105,115,101,49,0,18,120,0,58,118,101,99,51,0,17,49,57,0,51,52,0,0,0,17, -55,0,54,54,0,0,0,17,51,0,50,51,0,0,0,0,46,0,0,0,58,110,111,105,115,101,49,0,18,120,0,58,118,101,99, -51,0,17,53,0,52,55,0,0,0,17,49,55,0,56,53,0,0,0,17,49,49,0,48,52,0,0,0,0,46,0,0,0,58,110,111,105, -115,101,49,0,18,120,0,58,118,101,99,51,0,17,50,51,0,53,52,0,0,0,17,50,57,0,49,49,0,0,0,17,51,49,0, -57,49,0,0,0,0,46,0,0,0,0,0,0,1,0,12,0,110,111,105,115,101,52,0,1,0,0,12,120,0,0,0,1,8,58,118,101, -99,52,0,58,110,111,105,115,101,49,0,18,120,0,0,0,0,58,110,111,105,115,101,49,0,18,120,0,58,118,101, -99,52,0,17,49,57,0,51,52,0,0,0,17,55,0,54,54,0,0,0,17,51,0,50,51,0,0,0,17,50,0,55,55,0,0,0,0,46,0, -0,0,58,110,111,105,115,101,49,0,18,120,0,58,118,101,99,52,0,17,53,0,52,55,0,0,0,17,49,55,0,56,53,0, -0,0,17,49,49,0,48,52,0,0,0,17,49,51,0,49,57,0,0,0,0,46,0,0,0,58,110,111,105,115,101,49,0,18,120,0, -58,118,101,99,52,0,17,50,51,0,53,52,0,0,0,17,50,57,0,49,49,0,0,0,17,51,49,0,57,49,0,0,0,17,51,55,0, -52,56,0,0,0,0,46,0,0,0,0,0,0,0 +118,101,99,52,95,115,104,97,100,49,100,0,18,116,101,120,101,108,0,0,18,115,97,109,112,108,101,114, +0,0,18,99,111,111,114,100,0,0,17,48,0,48,0,0,0,0,8,18,116,101,120,101,108,0,0,0,1,0,12,0,115,104, +97,100,111,119,49,68,80,114,111,106,0,1,0,0,20,115,97,109,112,108,101,114,0,0,1,0,0,12,99,111,111, +114,100,0,0,0,1,8,58,115,104,97,100,111,119,49,68,0,18,115,97,109,112,108,101,114,0,0,58,118,101, +99,51,0,18,99,111,111,114,100,0,59,115,0,18,99,111,111,114,100,0,59,113,0,49,0,17,48,0,48,0,0,0,18, +99,111,111,114,100,0,59,112,0,18,99,111,111,114,100,0,59,113,0,49,0,0,0,0,0,0,1,0,12,0,115,104,97, +100,111,119,50,68,0,1,0,0,21,115,97,109,112,108,101,114,0,0,1,0,0,11,99,111,111,114,100,0,0,0,1,3, +2,0,12,1,116,101,120,101,108,0,0,0,4,118,101,99,52,95,115,104,97,100,50,100,0,18,116,101,120,101, +108,0,0,18,115,97,109,112,108,101,114,0,0,18,99,111,111,114,100,0,0,17,48,0,48,0,0,0,0,8,18,116, +101,120,101,108,0,0,0,1,0,12,0,115,104,97,100,111,119,50,68,80,114,111,106,0,1,0,0,21,115,97,109, +112,108,101,114,0,0,1,0,0,12,99,111,111,114,100,0,0,0,1,8,58,115,104,97,100,111,119,50,68,0,18,115, +97,109,112,108,101,114,0,0,58,118,101,99,51,0,18,99,111,111,114,100,0,59,115,0,18,99,111,111,114, +100,0,59,113,0,49,0,18,99,111,111,114,100,0,59,116,0,18,99,111,111,114,100,0,59,113,0,49,0,18,99, +111,111,114,100,0,59,112,0,18,99,111,111,114,100,0,59,113,0,49,0,0,0,0,0,0,1,0,9,0,110,111,105,115, +101,49,0,1,1,0,9,120,0,0,0,1,4,102,108,111,97,116,95,110,111,105,115,101,49,0,18,95,95,114,101,116, +86,97,108,0,0,18,120,0,0,0,0,1,0,9,0,110,111,105,115,101,49,0,1,1,0,10,120,0,0,0,1,4,102,108,111, +97,116,95,110,111,105,115,101,50,0,18,95,95,114,101,116,86,97,108,0,0,18,120,0,0,0,0,1,0,9,0,110, +111,105,115,101,49,0,1,1,0,11,120,0,0,0,1,4,102,108,111,97,116,95,110,111,105,115,101,51,0,18,95, +95,114,101,116,86,97,108,0,0,18,120,0,0,0,0,1,0,9,0,110,111,105,115,101,49,0,1,1,0,12,120,0,0,0,1, +4,102,108,111,97,116,95,110,111,105,115,101,52,0,18,95,95,114,101,116,86,97,108,0,0,18,120,0,0,0,0, +1,0,10,0,110,111,105,115,101,50,0,1,1,0,9,120,0,0,0,1,9,18,95,95,114,101,116,86,97,108,0,59,120,0, +58,110,111,105,115,101,49,0,18,120,0,0,0,20,0,9,18,95,95,114,101,116,86,97,108,0,59,121,0,58,110, +111,105,115,101,49,0,18,120,0,17,49,57,0,51,52,0,0,46,0,0,20,0,0,1,0,10,0,110,111,105,115,101,50,0, +1,1,0,10,120,0,0,0,1,9,18,95,95,114,101,116,86,97,108,0,59,120,0,58,110,111,105,115,101,49,0,18, +120,0,0,0,20,0,9,18,95,95,114,101,116,86,97,108,0,59,121,0,58,110,111,105,115,101,49,0,18,120,0,58, +118,101,99,50,0,17,49,57,0,51,52,0,0,0,17,55,0,54,54,0,0,0,0,46,0,0,20,0,0,1,0,10,0,110,111,105, +115,101,50,0,1,1,0,11,120,0,0,0,1,9,18,95,95,114,101,116,86,97,108,0,59,120,0,58,110,111,105,115, +101,49,0,18,120,0,0,0,20,0,9,18,95,95,114,101,116,86,97,108,0,59,121,0,58,110,111,105,115,101,49,0, +18,120,0,58,118,101,99,51,0,17,49,57,0,51,52,0,0,0,17,55,0,54,54,0,0,0,17,51,0,50,51,0,0,0,0,46,0, +0,20,0,0,1,0,10,0,110,111,105,115,101,50,0,1,1,0,12,120,0,0,0,1,9,18,95,95,114,101,116,86,97,108,0, +59,120,0,58,110,111,105,115,101,49,0,18,120,0,0,0,20,0,9,18,95,95,114,101,116,86,97,108,0,59,121,0, +58,110,111,105,115,101,49,0,18,120,0,58,118,101,99,52,0,17,49,57,0,51,52,0,0,0,17,55,0,54,54,0,0,0, +17,51,0,50,51,0,0,0,17,50,0,55,55,0,0,0,0,46,0,0,20,0,0,1,0,11,0,110,111,105,115,101,51,0,1,1,0,9, +120,0,0,0,1,9,18,95,95,114,101,116,86,97,108,0,59,120,0,58,110,111,105,115,101,49,0,18,120,0,0,0, +20,0,9,18,95,95,114,101,116,86,97,108,0,59,121,0,58,110,111,105,115,101,49,0,18,120,0,17,49,57,0, +51,52,0,0,46,0,0,20,0,9,18,95,95,114,101,116,86,97,108,0,59,122,0,58,110,111,105,115,101,49,0,18, +120,0,17,53,0,52,55,0,0,46,0,0,20,0,0,1,0,11,0,110,111,105,115,101,51,0,1,1,0,10,120,0,0,0,1,9,18, +95,95,114,101,116,86,97,108,0,59,120,0,58,110,111,105,115,101,49,0,18,120,0,0,0,20,0,9,18,95,95, +114,101,116,86,97,108,0,59,121,0,58,110,111,105,115,101,49,0,18,120,0,58,118,101,99,50,0,17,49,57, +0,51,52,0,0,0,17,55,0,54,54,0,0,0,0,46,0,0,20,0,9,18,95,95,114,101,116,86,97,108,0,59,122,0,58,110, +111,105,115,101,49,0,18,120,0,58,118,101,99,50,0,17,53,0,52,55,0,0,0,17,49,55,0,56,53,0,0,0,0,46,0, +0,20,0,0,1,0,11,0,110,111,105,115,101,51,0,1,1,0,11,120,0,0,0,1,9,18,95,95,114,101,116,86,97,108,0, +59,120,0,58,110,111,105,115,101,49,0,18,120,0,0,0,20,0,9,18,95,95,114,101,116,86,97,108,0,59,121,0, +58,110,111,105,115,101,49,0,18,120,0,58,118,101,99,51,0,17,49,57,0,51,52,0,0,0,17,55,0,54,54,0,0,0, +17,51,0,50,51,0,0,0,0,46,0,0,20,0,9,18,95,95,114,101,116,86,97,108,0,59,122,0,58,110,111,105,115, +101,49,0,18,120,0,58,118,101,99,51,0,17,53,0,52,55,0,0,0,17,49,55,0,56,53,0,0,0,17,49,49,0,48,52,0, +0,0,0,46,0,0,20,0,0,1,0,11,0,110,111,105,115,101,51,0,1,1,0,12,120,0,0,0,1,9,18,95,95,114,101,116, +86,97,108,0,59,120,0,58,110,111,105,115,101,49,0,18,120,0,0,0,20,0,9,18,95,95,114,101,116,86,97, +108,0,59,121,0,58,110,111,105,115,101,49,0,18,120,0,58,118,101,99,52,0,17,49,57,0,51,52,0,0,0,17, +55,0,54,54,0,0,0,17,51,0,50,51,0,0,0,17,50,0,55,55,0,0,0,0,46,0,0,20,0,9,18,95,95,114,101,116,86, +97,108,0,59,122,0,58,110,111,105,115,101,49,0,18,120,0,58,118,101,99,52,0,17,53,0,52,55,0,0,0,17, +49,55,0,56,53,0,0,0,17,49,49,0,48,52,0,0,0,17,49,51,0,49,57,0,0,0,0,46,0,0,20,0,0,1,0,12,0,110,111, +105,115,101,52,0,1,1,0,9,120,0,0,0,1,9,18,95,95,114,101,116,86,97,108,0,59,120,0,58,110,111,105, +115,101,49,0,18,120,0,0,0,20,0,9,18,95,95,114,101,116,86,97,108,0,59,121,0,58,110,111,105,115,101, +49,0,18,120,0,17,49,57,0,51,52,0,0,46,0,0,20,0,9,18,95,95,114,101,116,86,97,108,0,59,122,0,58,110, +111,105,115,101,49,0,18,120,0,17,53,0,52,55,0,0,46,0,0,20,0,9,18,95,95,114,101,116,86,97,108,0,59, +119,0,58,110,111,105,115,101,49,0,18,120,0,17,50,51,0,53,52,0,0,46,0,0,20,0,0,1,0,12,0,110,111,105, +115,101,52,0,1,1,0,10,120,0,0,0,1,9,18,95,95,114,101,116,86,97,108,0,59,120,0,58,110,111,105,115, +101,49,0,18,120,0,0,0,20,0,9,18,95,95,114,101,116,86,97,108,0,59,121,0,58,110,111,105,115,101,49,0, +18,120,0,58,118,101,99,50,0,17,49,57,0,51,52,0,0,0,17,55,0,54,54,0,0,0,0,46,0,0,20,0,9,18,95,95, +114,101,116,86,97,108,0,59,122,0,58,110,111,105,115,101,49,0,18,120,0,58,118,101,99,50,0,17,53,0, +52,55,0,0,0,17,49,55,0,56,53,0,0,0,0,46,0,0,20,0,9,18,95,95,114,101,116,86,97,108,0,59,119,0,58, +110,111,105,115,101,49,0,18,120,0,58,118,101,99,50,0,17,50,51,0,53,52,0,0,0,17,50,57,0,49,49,0,0,0, +0,46,0,0,20,0,0,1,0,12,0,110,111,105,115,101,52,0,1,1,0,11,120,0,0,0,1,9,18,95,95,114,101,116,86, +97,108,0,59,120,0,58,110,111,105,115,101,49,0,18,120,0,0,0,20,0,9,18,95,95,114,101,116,86,97,108,0, +59,121,0,58,110,111,105,115,101,49,0,18,120,0,58,118,101,99,51,0,17,49,57,0,51,52,0,0,0,17,55,0,54, +54,0,0,0,17,51,0,50,51,0,0,0,0,46,0,0,20,0,9,18,95,95,114,101,116,86,97,108,0,59,122,0,58,110,111, +105,115,101,49,0,18,120,0,58,118,101,99,51,0,17,53,0,52,55,0,0,0,17,49,55,0,56,53,0,0,0,17,49,49,0, +48,52,0,0,0,0,46,0,0,20,0,9,18,95,95,114,101,116,86,97,108,0,59,119,0,58,110,111,105,115,101,49,0, +18,120,0,58,118,101,99,51,0,17,50,51,0,53,52,0,0,0,17,50,57,0,49,49,0,0,0,17,51,49,0,57,49,0,0,0,0, +46,0,0,20,0,0,1,0,12,0,110,111,105,115,101,52,0,1,1,0,12,120,0,0,0,1,9,18,95,95,114,101,116,86,97, +108,0,59,120,0,58,110,111,105,115,101,49,0,18,120,0,0,0,20,0,9,18,95,95,114,101,116,86,97,108,0,59, +121,0,58,110,111,105,115,101,49,0,18,120,0,58,118,101,99,52,0,17,49,57,0,51,52,0,0,0,17,55,0,54,54, +0,0,0,17,51,0,50,51,0,0,0,17,50,0,55,55,0,0,0,0,46,0,0,20,0,9,18,95,95,114,101,116,86,97,108,0,59, +122,0,58,110,111,105,115,101,49,0,18,120,0,58,118,101,99,52,0,17,53,0,52,55,0,0,0,17,49,55,0,56,53, +0,0,0,17,49,49,0,48,52,0,0,0,17,49,51,0,49,57,0,0,0,0,46,0,0,20,0,9,18,95,95,114,101,116,86,97,108, +0,59,119,0,58,110,111,105,115,101,49,0,18,120,0,58,118,101,99,52,0,17,50,51,0,53,52,0,0,0,17,50,57, +0,49,49,0,0,0,17,51,49,0,57,49,0,0,0,17,51,55,0,52,56,0,0,0,0,46,0,0,20,0,0,0 diff --git a/src/mesa/shader/slang/library/slang_core.gc b/src/mesa/shader/slang/library/slang_core.gc index 7a721a5a1d..927ca048d7 100755..100644 --- a/src/mesa/shader/slang/library/slang_core.gc +++ b/src/mesa/shader/slang/library/slang_core.gc @@ -23,1493 +23,2460 @@ */ // -// This file defines nearly all constructors and operators for built-in data types, using -// extended language syntax. In general, compiler treats constructors and operators as -// ordinary functions with some exceptions. For example, the language does not allow -// functions to be called in constant expressions - here the exception is made to allow it. +// This file defines nearly all constructors and operators for built-in data +// types, using extended language syntax. In general, compiler treats +// constructors and operators as ordinary functions with some exceptions. +// For example, the language does not allow functions to be called in +// constant expressions - here the exception is made to allow it. // -// Each implementation provides its own version of this file. Each implementation can define -// the required set of operators and constructors in its own fashion. +// Each implementation provides its own version of this file. Each +// implementation can define the required set of operators and constructors +// in its own fashion. // -// The extended language syntax is only present when compiling this file. It is implicitly -// included at the very beginning of the compiled shader, so no built-in functions can be -// used. +// The extended language syntax is only present when compiling this file. +// It is implicitly included at the very beginning of the compiled shader, +// so no built-in functions can be used. // -// To communicate with the implementation, a special extended "__asm" keyword is used, followed -// by an instruction name (any valid identifier), a destination variable identifier and a -// a list of zero or more source variable identifiers. A variable identifier is a variable name -// declared earlier in the code (as a function parameter, local or global variable). -// An instruction name designates an instruction that must be exported by the implementation. -// Each instruction receives data from source variable identifiers and returns data in the -// destination variable identifier. +// To communicate with the implementation, a special extended "__asm" keyword +// is used, followed by an instruction name (any valid identifier), a +// destination variable identifier and a list of zero or more source +// variable identifiers. // -// It is up to the implementation how to define a particular operator or constructor. If it is -// expected to being used rarely, it can be defined in terms of other operators and constructors, +// A variable identifier is a variable name declared earlier in the code +// (as a function parameter, local or global variable). +// +// An instruction name designates an instruction that must be exported +// by the implementation. Each instruction receives data from source +// variable identifiers and returns data in the destination variable +// identifier. +// +// It is up to the implementation how to define a particular operator +// or constructor. If it is expected to being used rarely, it can be +// defined in terms of other operators and constructors, // for example: // // ivec2 __operator + (const ivec2 x, const ivec2 y) { // return ivec2 (x[0] + y[0], x[1] + y[1]); // } // -// If a particular operator or constructor is expected to be used very often or is an atomic -// operation (that is, an operation that cannot be expressed in terms of other operations or -// would create a dependency cycle) it must be defined using one or more __asm constructs. +// If a particular operator or constructor is expected to be used very +// often or is an atomic operation (that is, an operation that cannot be +// expressed in terms of other operations or would create a dependency +// cycle) it must be defined using one or more __asm constructs. // -// Each implementation must define constructors for all scalar types (bool, float, int). -// There are 9 scalar-to-scalar constructors (including identity constructors). However, -// since the language introduces special constructors (like matrix constructor with a single +// Each implementation must define constructors for all scalar types +// (bool, float, int). There are 9 scalar-to-scalar constructors +// (including identity constructors). However, since the language +// introduces special constructors (like matrix constructor with a single // scalar value), implementations must also implement these cases. // The compiler provides the following algorithm when resolving a constructor: // - try to find a constructor with a prototype matching ours, -// - if no constructor is found and this is a scalar-to-scalar constructor, raise an error, +// - if no constructor is found and this is a scalar-to-scalar constructor, +// raise an error, // - if a constructor is found, execute it and return, -// - count the size of the constructor parameter list - if it is less than the size of -// our constructor's type, raise an error, -// - for each parameter in the list do a recursive constructor matching for appropriate -// scalar fields in the constructed variable, +// - count the size of the constructor parameter list - if it is less than +// the size of our constructor's type, raise an error, +// - for each parameter in the list do a recursive constructor matching for +// appropriate scalar fields in the constructed variable, // -// Each implementation must also define a set of operators that deal with built-in data types. +// Each implementation must also define a set of operators that deal with +// built-in data types. // There are four kinds of operators: -// 1) Operators that are implemented only by the compiler: "()" (function call), "," (sequence) -// and "?:" (selection). -// 2) Operators that are implemented by the compiler by expressing it in terms of other operators: +// 1) Operators that are implemented only by the compiler: "()" (function +// call), "," (sequence) and "?:" (selection). +// 2) Operators that are implemented by the compiler by expressing it in +// terms of other operators: // - "." (field selection) - translated to subscript access, -// - "&&" (logical and) - translated to "<left_expr> ? <right_expr> : false", +// - "&&" (logical and) - translated to "<left_expr> ? <right_expr> : +// false", // - "||" (logical or) - translated to "<left_expr> ? true : <right_expr>", -// 3) Operators that can be defined by the implementation and if the required prototype is not -// found, standard behaviour is used: -// - "==", "!=", "=" (equality, assignment) - compare or assign matching fields one-by-one; -// note that at least operators for scalar data types must be defined by the implementation -// to get it work, -// 4) All other operators not mentioned above. If no required prototype is found, an error is -// raised. An implementation must follow the language specification to provide all valid -// operator prototypes. +// 3) Operators that can be defined by the implementation and if the required +// prototype is not found, standard behaviour is used: +// - "==", "!=", "=" (equality, assignment) - compare or assign +// matching fields one-by-one; +// note that at least operators for scalar data types must be defined +// by the implementation to get it work, +// 4) All other operators not mentioned above. If no required prototype is +// found, an error is raised. An implementation must follow the language +// specification to provide all valid operator prototypes. // -int __constructor (const float f) { - int i; - __asm float_to_int i, f; - return i; + + +//// Basic, scalar constructors/casts + +int __constructor(const float f) +{ + __asm float_to_int __retVal, f; } -bool __constructor (const int i) { - return i != 0; +bool __constructor(const int i) +{ + const float zero = 0.0; + __asm vec4_seq __retVal, i, zero; } -bool __constructor (const float f) { - return f != 0.0; +bool __constructor(const float f) +{ + const float zero = 0.0; + __asm vec4_seq __retVal, i, zero; } -int __constructor (const bool b) { - return b ? 1 : 0; +int __constructor(const bool b) +{ + __retVal = b; } -float __constructor (const bool b) { - return b ? 1.0 : 0.0; +float __constructor(const bool b) +{ + __retVal = b; } -float __constructor (const int i) { - float f; - __asm int_to_float f, i; - return f; +float __constructor(const int i) +{ + __asm int_to_float __retVal, i; } -bool __constructor (const bool b) { - return b; +bool __constructor(const bool b) +{ + __retVal = b; } -int __constructor (const int i) { - return i; +int __constructor(const int i) +{ + __retVal = i; } -float __constructor (const float f) { - return f; +float __constructor(const float f) +{ + __retVal = f; } -vec2 __constructor (const float f) { - return vec2 (f, f); + +//// vec2 constructors + +vec2 __constructor(const float x, const float y) +{ + __retVal.x = x; + __retVal.y = y; } -vec2 __constructor (const int i) { - float x; - __asm int_to_float x, i; - return vec2 (x); +vec2 __constructor(const float f) +{ + __retVal.xy = f.xx; } -vec2 __constructor (const bool b) { - return vec2 (b ? 1.0 : 0.0); +vec2 __constructor(const int i) +{ + __retVal.xy = i.xx; } -vec3 __constructor (const float f) { - return vec3 (f, f, f); +vec2 __constructor(const bool b) +{ + __retVal.xy = b.xx; } -vec3 __constructor (const int i) { - float x; - __asm int_to_float x, i; - return vec3 (x); +vec2 __constructor(const vec3 v) +{ + __retVal.xy = v.xy; } -vec3 __constructor (const bool b) { - return vec3 (b ? 1.0 : 0.0); + +//// vec3 constructors + +vec3 __constructor(const float x, const float y, const float z) +{ + __retVal.x = x; + __retVal.y = y; + __retVal.z = z; } -vec4 __constructor (const float f) { - return vec4 (f, f, f, f); +vec3 __constructor(const float f) +{ + __retVal.xyz = f.xxx; } -vec4 __constructor (const int i) { - float x; - __asm int_to_float x, i; - return vec4 (x); +vec3 __constructor(const int i) +{ + __asm int_to_float __retVal.xyz, i.xxx; } -vec4 __constructor (const bool b) { - return vec4 (b ? 1.0 : 0.0); +vec3 __constructor(const bool b) +{ + __retVal.xyz = b.xxx; } -ivec2 __constructor (const int i) { - return ivec2 (i, i); +vec3 __constructor(const vec4 v) +{ + __retVal.xyz = v.xyz; } -ivec2 __constructor (const float f) { - return ivec2 (int (f)); + +//// vec4 constructors + +vec4 __constructor(const float x, const float y, const float z, const float w) +{ + __retVal.x = x; + __retVal.y = y; + __retVal.z = z; + __retVal.w = w; } -ivec2 __constructor (const bool b) { - return ivec2 (int (b)); +vec4 __constructor(const float f) +{ + __retVal = f.xxxx; } -ivec3 __constructor (const int i) { - return ivec3 (i, i, i); +vec4 __constructor(const int i) +{ + __retVal = i.xxxx; } -ivec3 __constructor (const float f) { - return ivec3 (int (f)); +vec4 __constructor(const bool b) +{ + __retVal = b.xxxx; } -ivec3 __constructor (const bool b) { - return ivec3 (int (b)); +vec4 __constructor(const vec3 v3, const float f) +{ + // XXX this constructor shouldn't be needed anymore + __retVal.xyz = v3; + __retVal.w = f; } -ivec4 __constructor (const int i) { - return ivec4 (i, i, i, i); + +//// ivec2 constructors + +ivec2 __constructor(const int i, const int j) +{ + __retVal.x = i; + __retVal.y = j; } -ivec4 __constructor (const float f) { - return ivec4 (int (f)); +ivec2 __constructor(const int i) +{ + __retVal.xy = i.xx; } -ivec4 __constructor (const bool b) { - return ivec4 (int (b)); +ivec2 __constructor(const float f) +{ + __asm float_to_int __retVal.xy, f.xx; } -bvec2 __constructor (const bool b) { - return bvec2 (b, b); +ivec2 __constructor(const bool b) +{ + __asm float_to_int __retVal.xy, b.xx; } -bvec2 __constructor (const float f) { - return bvec2 (bool (f)); + +//// ivec3 constructors + +ivec3 __constructor(const int i, const int j, const int k) +{ + __retVal.x = i; + __retVal.y = j; + __retVal.z = k; } -bvec2 __constructor (const int i) { - return bvec2 (bool (i)); +ivec3 __constructor(const int i) +{ + __retVal.xyz = i.xxx; } -bvec3 __constructor (const bool b) { - return bvec3 (b, b, b); +ivec3 __constructor(const float f) +{ + __retVal.xyz = f.xxx; } -bvec3 __constructor (const float f) { - return bvec3 (bool (f)); +ivec3 __constructor(const bool b) +{ + __retVal.xyz = b.xxx; } -bvec3 __constructor (const int i) { - return bvec3 (bool (i)); + +//// ivec4 constructors + +ivec4 __constructor(const int x, const int y, const int z, const int w) +{ + __retVal.x = x; + __retVal.y = y; + __retVal.z = z; + __retVal.w = w; } -bvec4 __constructor (const bool b) { - return bvec4 (b, b, b, b); +ivec4 __constructor(const int i) +{ + __retVal = i.xxxx; } -bvec4 __constructor (const float f) { - return bvec4 (bool (f)); +ivec4 __constructor(const float f) +{ + __asm float_to_int __retVal, f.xxxx; } -bvec4 __constructor (const int i) { - return bvec4 (bool (i)); +ivec4 __constructor(const bool b) +{ + __retVal = b.xxxx; } -mat2 __constructor (const float f) { - return mat2 (f, 0.0, 0.0, f); + +//// bvec2 constructors + +bvec2 __constructor(const bool b1, const bool b2) +{ + __retVal.x = b1; + __retVal.y = b2; } -mat2 __constructor (const int i) { - float x; - __asm int_to_float x, i; - return mat2 (x); +bvec2 __constructor(const bool b) +{ + __retVal.xy = b.xx; } -mat2 __constructor (const bool b) { - return mat2 (b ? 1.0 : 0.0); +bvec2 __constructor(const float f) +{ + const vec2 zero = vec2(0.0, 0.0); + __asm vec4_seq __retVal.xy, f.xx, zero; } -mat3 __constructor (const float f) { - return mat3 (f, 0.0, 0.0, 0.0, f, 0.0, 0.0, 0.0, f); +bvec2 __constructor(const int i) +{ + const ivec2 zero = ivec2(0, 0); + __asm vec4_seq __retVal.xy, i.xx, zero; } -mat3 __constructor (const int i) { - float x; - __asm int_to_float x, i; - return mat3 (x); + +//// bvec3 constructors + +bvec3 __constructor(const bool b1, const bool b2, const bool b3) +{ + __retVal.x = b1; + __retVal.y = b2; + __retVal.z = b3; } -mat3 __constructor (const bool b) { - return mat3 (b ? 1.0 : 0.0); +bvec3 __constructor(const bool b) +{ + __retVal.xyz = b.xxx; } -mat4 __constructor (const float f) { - return mat4 (f, 0.0, 0.0, 0.0, 0.0, f, 0.0, 0.0, 0.0, 0.0, f, 0.0, 0.0, 0.0, 0.0, f); +bvec3 __constructor(const float f) +{ + const vec3 zero = vec3(0.0, 0.0, 0.0); + __asm vec4_seq __retVal.xyz, f.xxx, zero; } -mat4 __constructor (const int i) { - float x; - __asm int_to_float x, i; - return mat4 (x); +bvec3 __constructor(const int i) +{ + const ivec3 zero = ivec3(0, 0, 0); + __asm vec4_seq __retVal.xyz, i.xxx, zero; } -mat4 __constructor (const bool b) { - return mat4 (b ? 1.0 : 0.0); + +//// bvec4 constructors + +bvec4 __constructor(const bool b1, const bool b2, const bool b3, const bool b4) +{ + __retVal.x = b1; + __retVal.y = b2; + __retVal.z = b3; + __retVal.w = b4; } -void __operator += (inout float a, const float b) { - __asm float_add a, a, b; +bvec4 __constructor(const bool b) +{ + __retVal.xyzw = b.xxxx; } -float __operator - (const float a) { - float b; - __asm float_negate b, a; - return b; +bvec4 __constructor(const float f) +{ + const vec4 zero = vec4(0.0, 0.0, 0.0, 0.0); + __asm vec4_seq __retVal, f.xxxx, zero; } -void __operator -= (inout float a, const float b) { - float c; - __asm float_negate c, b; - __asm float_add a, a, c; +bvec4 __constructor(const int i) +{ + const ivec4 zero = ivec4(0, 0, 0, 0); + __asm vec4_seq __retVal, i.xxxx, zero; } -void __operator *= (inout float a, const float b) { - __asm float_multiply a, a, b; + + +//// mat2 constructors + +mat2 __constructor(const float m00, const float m10, + const float m01, const float m11) +{ + __retVal[0].x = m00; + __retVal[0].y = m10; + __retVal[1].x = m01; + __retVal[1].y = m11; } -void __operator /= (inout float a, const float b) { - __asm float_divide a, a, b; +mat2 __constructor(const float f) +{ + __retVal[0].x = f; + __retVal[0].y = 0.0; + __retVal[1].x = 0.0; + __retVal[1].y = f; } -float __operator + (const float a, const float b) { - float c; - __asm float_add c, a, b; - return c; +mat2 __constructor(const int i) +{ + return mat2(float(i)); } -void __operator += (inout int a, const int b) { - a = int (float (a) + float (b)); +mat2 __constructor(const bool b) +{ + return mat2(float(b)); } -int __operator - (const int a) { - float x; - int b; - __asm int_to_float x, a; - __asm float_negate x, x; - __asm float_to_int b, x; - return b; +mat2 __constructor(const vec2 c0, const vec2 c1) +{ + __retVal[0] = c0; + __retVal[1] = c1; } -void __operator -= (inout int a, const int b) { - a += -b; + +//// mat3 constructors + +mat3 __constructor(const float m00, const float m10, const float m20, + const float m01, const float m11, const float m21, + const float m02, const float m12, const float m22) +{ + __retVal[0].x = m00; + __retVal[0].y = m10; + __retVal[0].z = m20; + __retVal[1].x = m01; + __retVal[1].y = m11; + __retVal[1].z = m21; + __retVal[2].x = m02; + __retVal[2].y = m12; + __retVal[2].z = m22; } -float __operator * (const float a, const float b) { - float c; - __asm float_multiply c, a, b; - return c; +mat3 __constructor(const float f) +{ + vec2 v = vec2(f, 0.0); + __retVal[0] = v.xyy; + __retVal[1] = v.yxy; + __retVal[2] = v.yyx; } -void __operator *= (inout int a, const int b) { - a = int (float (a) * float (b)); +mat3 __constructor(const int i) +{ + return mat3(float(i)); } -float __operator / (const float a, const float b) { - float c; - __asm float_divide c, a, b; - return c; +mat3 __constructor(const bool b) +{ + return mat3(float(b)); } -void __operator /= (inout int a, const int b) { - a = int (float (a) / float (b)); +mat3 __constructor(const vec3 c0, const vec3 c1, const vec3 c2) +{ + __retVal[0] = c0; + __retVal[1] = c1; + __retVal[2] = c2; } -void __operator += (inout vec2 v, const vec2 u) { - v.x += u.x; - v.y += u.y; + +//// mat4 constructors + +mat4 __constructor(const float m00, const float m10, const float m20, const float m30, + const float m01, const float m11, const float m21, const float m31, + const float m02, const float m12, const float m22, const float m32, + const float m03, const float m13, const float m23, const float m33) +{ + __retVal[0].x = m00; + __retVal[0].y = m10; + __retVal[0].z = m20; + __retVal[0].w = m30; + __retVal[1].x = m01; + __retVal[1].y = m11; + __retVal[1].z = m21; + __retVal[1].w = m31; + __retVal[2].x = m02; + __retVal[2].y = m12; + __retVal[2].z = m22; + __retVal[2].w = m32; + __retVal[3].x = m03; + __retVal[3].y = m13; + __retVal[3].z = m23; + __retVal[3].w = m33; } -void __operator -= (inout vec2 v, const vec2 u) { - v.x -= u.x; - v.y -= u.y; + +mat4 __constructor(const float f) +{ + vec2 v = vec2(f, 0.0); + __retVal[0] = v.xyyy; + __retVal[1] = v.yxyy; + __retVal[2] = v.yyxy; + __retVal[3] = v.yyyx; } -void __operator *= (inout vec2 v, const vec2 u) { - v.x *= u.x; - v.y *= u.y; +mat4 __constructor(const int i) +{ + return mat4(float(i)); } -void __operator /= (inout vec2 v, const vec2 u) { - v.x /= u.x; - v.y /= u.y; +mat4 __constructor(const bool b) +{ + return mat4(float(b)); } -void __operator += (inout vec3 v, const vec3 u) { - v.x += u.x; - v.y += u.y; - v.z += u.z; +mat4 __constructor(const vec4 c0, const vec4 c1, const vec4 c2, const vec4 c3) +{ + __retVal[0] = c0; + __retVal[1] = c1; + __retVal[2] = c2; + __retVal[3] = c3; } -void __operator -= (inout vec3 v, const vec3 u) { - v.x -= u.x; - v.y -= u.y; - v.z -= u.z; + + +//// Basic int operators + +int __operator + (const int a, const int b) +{ +// XXX If we ever have int registers, we'll do something like this: +// XXX For now, mostly treat ints as floats. +// float x, y; +// __asm int_to_float x, a; +// __asm int_to_float y, b; +// __asm vec4_add x.x, x.x, y.x; +// __asm float_to_int __retVal, x; + float x; + __asm vec4_add x, a, b; + __asm float_to_int __retVal, x; } -void __operator *= (inout vec3 v, const vec3 u) { - v.x *= u.x; - v.y *= u.y; - v.z *= u.z; +int __operator - (const int a, const int b) +{ + float x; + __asm vec4_subtract x, a, b; + __asm float_to_int __retVal, x; } -void __operator /= (inout vec3 v, const vec3 u) { - v.x /= u.x; - v.y /= u.y; - v.z /= u.z; +int __operator * (const int a, const int b) +{ + float x; + __asm vec4_multiply x, a, b; + __asm float_to_int __retVal, x; } -void __operator += (inout vec4 v, const vec4 u) { - v.x += u.x; - v.y += u.y; - v.z += u.z; - v.w += u.w; +int __operator / (const int a, const int b) +{ + float bInv, x; + __asm float_rcp bInv, b; + __asm vec4_multiply x, a, bInv; + __asm float_to_int __retVal, x; } -void __operator -= (inout vec4 v, const vec4 u) { - v.x -= u.x; - v.y -= u.y; - v.z -= u.z; - v.w -= u.w; + +//// Basic ivec2 operators + +ivec2 __operator + (const ivec2 a, const ivec2 b) +{ + vec2 x; + __asm vec4_add x, a, b; + __asm float_to_int __retVal, x; } -void __operator *= (inout vec4 v, const vec4 u) { - v.x *= u.x; - v.y *= u.y; - v.z *= u.z; - v.w *= u.w; +ivec2 __operator - (const ivec2 a, const ivec2 b) +{ + vec2 x; + __asm vec4_subtract x, a, b; + __asm float_to_int __retVal, x; } -void __operator /= (inout vec4 v, const vec4 u) { - v.x /= u.x; - v.y /= u.y; - v.z /= u.z; - v.w /= u.w; +ivec2 __operator * (const ivec2 a, const ivec2 b) +{ + vec2 x; + __asm vec4_multiply x, a, b; + __asm float_to_int __retVal, x; } -void __operator += (inout ivec2 v, const ivec2 u) { - v.x += u.x; - v.y += u.y; +ivec2 __operator / (const ivec2 a, const ivec2 b) +{ + vec2 bInv, x; + __asm float_rcp bInv.x, b.x; + __asm float_rcp bInv.y, b.y; + __asm vec4_multiply x, a, bInv; + __asm float_to_int __retVal, x; } -void __operator -= (inout ivec2 v, const ivec2 u) { - v.x -= u.x; - v.y -= u.y; + +//// Basic ivec3 operators + +ivec3 __operator + (const ivec3 a, const ivec3 b) +{ + vec3 x; + __asm vec4_add x, a, b; + __asm float_to_int __retVal, x; } -void __operator *= (inout ivec2 v, const ivec2 u) { - v.x *= u.x; - v.y *= u.y; +ivec3 __operator - (const ivec3 a, const ivec3 b) +{ + vec3 x; + __asm vec4_subtract x, a, b; + __asm float_to_int __retVal, x; } -void __operator /= (inout ivec2 v, const ivec2 u) { - v.x /= u.x; - v.y /= u.y; +ivec3 __operator * (const ivec3 a, const ivec3 b) +{ + vec3 x; + __asm vec4_multiply x, a, b; + __asm float_to_int __retVal, x; } -void __operator += (inout ivec3 v, const ivec3 u) { - v.x += u.x; - v.y += u.y; - v.z += u.z; +ivec3 __operator / (const ivec3 a, const ivec3 b) +{ + vec3 bInv, x; + __asm float_rcp bInv.x, b.x; + __asm float_rcp bInv.y, b.y; + __asm float_rcp bInv.z, b.z; + __asm vec4_multiply x, a, bInv; + __asm float_to_int __retVal, x; } -void __operator -= (inout ivec3 v, const ivec3 u) { - v.x -= u.x; - v.y -= u.y; - v.z -= u.z; + +//// Basic ivec4 operators + +ivec4 __operator + (const ivec4 a, const ivec4 b) +{ + vec3 x; + __asm vec4_add x, a, b; + __asm float_to_int __retVal, x; } -void __operator *= (inout ivec3 v, const ivec3 u) { - v.x *= u.x; - v.y *= u.y; - v.z *= u.z; +ivec4 __operator - (const ivec4 a, const ivec4 b) +{ + vec4 x; + __asm vec4_subtract x, a, b; + __asm float_to_int __retVal, x; } -void __operator /= (inout ivec3 v, const ivec3 u) { - v.x /= u.x; - v.y /= u.y; - v.z /= u.z; +ivec4 __operator * (const ivec4 a, const ivec4 b) +{ + vec4 x; + __asm vec4_multiply x, a, b; + __asm float_to_int __retVal, x; } -void __operator += (inout ivec4 v, const ivec4 u) { - v.x += u.x; - v.y += u.y; - v.z += u.z; - v.w += u.w; +ivec4 __operator / (const ivec4 a, const ivec4 b) +{ + vec4 bInv, x; + __asm float_rcp bInv.x, b.x; + __asm float_rcp bInv.y, b.y; + __asm float_rcp bInv.z, b.z; + __asm float_rcp bInv.w, b.w; + __asm vec4_multiply x, a, bInv; + __asm float_to_int __retVal, x; } -void __operator -= (inout ivec4 v, const ivec4 u) { - v.x -= u.x; - v.y -= u.y; - v.z -= u.z; - v.w -= u.w; + +//// Basic float operators + +float __operator + (const float a, const float b) +{ + __asm vec4_add __retVal.x, a, b; } -void __operator *= (inout ivec4 v, const ivec4 u) { - v.x *= u.x; - v.y *= u.y; - v.z *= u.z; - v.w *= u.w; +float __operator - (const float a, const float b) +{ + __asm vec4_subtract __retVal.x, a, b; } -void __operator /= (inout ivec4 v, const ivec4 u) { - v.x /= u.x; - v.y /= u.y; - v.z /= u.z; - v.w /= u.w; +float __operator * (const float a, const float b) +{ + __asm vec4_multiply __retVal.x, a, b; } -void __operator += (inout mat2 m, const mat2 n) { - m[0] += n[0]; - m[1] += n[1]; +float __operator / (const float a, const float b) +{ + float bInv; + __asm float_rcp bInv.x, b.x; + __asm vec4_multiply __retVal.x, a, bInv; } -void __operator -= (inout mat2 m, const mat2 n) { - m[0] -= n[0]; - m[1] -= n[1]; + +//// Basic vec2 operators + +vec2 __operator + (const vec2 v, const vec2 u) +{ + __asm vec4_add __retVal.xy, v, u; } -vec2 __operator * (const mat2 m, const vec2 v) { - return vec2 ( - v.x * m[0].x + v.y * m[1].x, - v.x * m[0].y + v.y * m[1].y - ); +vec2 __operator - (const vec2 v, const vec2 u) +{ + __asm vec4_subtract __retVal.xy, v, u; } -mat2 __operator * (const mat2 m, const mat2 n) { - return mat2 (m * n[0], m * n[1]); +vec2 __operator * (const vec2 v, const vec2 u) +{ + __asm vec4_multiply __retVal.xy, v, u; } -void __operator *= (inout mat2 m, const mat2 n) { - m = m * n; +vec2 __operator / (const vec2 v, const vec2 u) +{ + vec2 w; // = 1 / u + __asm float_rcp w.x, u.x; + __asm float_rcp w.y, u.y; + __asm vec4_multiply __retVal.xy, v, w; } -void __operator /= (inout mat2 m, const mat2 n) { - m[0] /= n[0]; - m[1] /= n[1]; + +//// Basic vec3 operators + +vec3 __operator + (const vec3 v, const vec3 u) +{ + __asm vec4_add __retVal.xyz, v, u; } -void __operator += (inout mat3 m, const mat3 n) { - m[0] += n[0]; - m[1] += n[1]; - m[2] += n[2]; +vec3 __operator - (const vec3 v, const vec3 u) +{ + __asm vec4_subtract __retVal.xyz, v, u; } -void __operator -= (inout mat3 m, const mat3 n) { - m[0] -= n[0]; - m[1] -= n[1]; - m[2] -= n[2]; +vec3 __operator * (const vec3 v, const vec3 u) +{ + __asm vec4_multiply __retVal.xyz, v, u; } -vec3 __operator * (const mat3 m, const vec3 v) { - return vec3 ( - v.x * m[0].x + v.y * m[1].x + v.z * m[2].x, - v.x * m[0].y + v.y * m[1].y + v.z * m[2].y, - v.x * m[0].z + v.y * m[1].z + v.z * m[2].z - ); +vec3 __operator / (const vec3 v, const vec3 u) +{ + vec3 w; // = 1 / u + __asm float_rcp w.x, u.x; + __asm float_rcp w.y, u.y; + __asm float_rcp w.z, u.z; + __asm vec4_multiply __retVal.xyz, v, w; } -mat3 __operator * (const mat3 m, const mat3 n) { - return mat3 (m * n[0], m * n[1], m * n[2]); + +//// Basic vec4 operators + +vec4 __operator + (const vec4 v, const vec4 u) +{ + __asm vec4_add __retVal, v, u; } -void __operator *= (inout mat3 m, const mat3 n) { - m = m * n; +vec4 __operator - (const vec4 v, const vec4 u) +{ + __asm vec4_subtract __retVal, v, u; } -void __operator /= (inout mat3 m, const mat3 n) { - m[0] /= n[0]; - m[1] /= n[1]; - m[2] /= n[2]; +vec4 __operator * (const vec4 v, const vec4 u) +{ + __asm vec4_multiply __retVal, v, u; } -void __operator += (inout mat4 m, const mat4 n) { - m[0] += n[0]; - m[1] += n[1]; - m[2] += n[2]; - m[3] += n[3]; +vec4 __operator / (const vec4 v, const vec4 u) +{ + vec4 w; // = 1 / u + __asm float_rcp w.x, u.x; + __asm float_rcp w.y, u.y; + __asm float_rcp w.z, u.z; + __asm float_rcp w.w, u.w; + __asm vec4_multiply __retVal, v, w; } -void __operator -= (inout mat4 m, const mat4 n) { - m[0] -= n[0]; - m[1] -= n[1]; - m[2] -= n[2]; - m[3] -= n[3]; + + + +//// Basic vec2/float operators + +vec2 __operator + (const float a, const vec2 u) +{ + __asm vec4_add __retVal.xy, a.xx, u.xy; } -vec4 __operator * (const mat4 m, const vec4 v) { - return vec4 ( - v.x * m[0].x + v.y * m[1].x + v.z * m[2].x + v.w * m[3].x, - v.x * m[0].y + v.y * m[1].y + v.z * m[2].y + v.w * m[3].y, - v.x * m[0].z + v.y * m[1].z + v.z * m[2].z + v.w * m[3].z, - v.x * m[0].w + v.y * m[1].w + v.z * m[2].w + v.w * m[3].w - ); +vec2 __operator + (const vec2 v, const float b) +{ + __asm vec4_add __retVal.xy, v.xy, b.xx; } -mat4 __operator * (const mat4 m, const mat4 n) { - return mat4 (m * n[0], m * n[1], m * n[2], m * n[3]); +vec2 __operator - (const float a, const vec2 u) +{ + __asm vec4_subtract __retVal.xy, a.xx, u.xy; } -void __operator *= (inout mat4 m, const mat4 n) { - m = m * n; +vec2 __operator - (const vec2 v, const float b) +{ + __asm vec4_subtract __retVal.xy, v.xy, b.xx; } -void __operator /= (inout mat4 m, const mat4 n) { - m[0] /= n[0]; - m[1] /= n[1]; - m[2] /= n[2]; - m[3] /= n[3]; +vec2 __operator * (const float a, const vec2 u) +{ + __asm vec4_multiply __retVal.xy, a.xx, u.xy; } -void __operator += (inout vec2 v, const float a) { - v.x += a; - v.y += a; +vec2 __operator * (const vec2 v, const float b) +{ + __asm vec4_multiply __retVal.xy, v.xy, b.xx; } -void __operator -= (inout vec2 v, const float a) { - v.x -= a; - v.y -= a; +vec2 __operator / (const float a, const vec2 u) +{ + vec2 invU; + __asm float_rcp invU.x, u.x; + __asm float_rcp invU.y, u.y; + __asm vec4_multiply __retVal.xy, a.xx, invU.xy; } -void __operator *= (inout vec2 v, const float a) { - v.x *= a; - v.y *= a; +vec2 __operator / (const vec2 v, const float b) +{ + float invB; + __asm float_rcp invB, b; + __asm vec4_multiply __retVal.xy, v.xy, invB.xx; } -void __operator /= (inout vec2 v, const float a) { - v.x /= a; - v.y /= a; + +//// Basic vec3/float operators + +vec3 __operator + (const float a, const vec3 u) +{ + __asm vec4_add __retVal.xyz, a.xxx, u.xyz; } -void __operator += (inout vec3 v, const float a) { - v.x += a; - v.y += a; - v.z += a; +vec3 __operator + (const vec3 v, const float b) +{ + __asm vec4_add __retVal.xyz, v.xyz, b.xxx; } -void __operator -= (inout vec3 v, const float a) { - v.x -= a; - v.y -= a; - v.z -= a; +vec3 __operator - (const float a, const vec3 u) +{ + __asm vec4_subtract __retVal.xyz, a.xxx, u.xyz; } -void __operator *= (inout vec3 v, const float a) { - v.x *= a; - v.y *= a; - v.z *= a; +vec3 __operator - (const vec3 v, const float b) +{ + __asm vec4_subtract __retVal.xyz, v.xyz, b.xxx; } -void __operator /= (inout vec3 v, const float a) { - v.x /= a; - v.y /= a; - v.z /= a; +vec3 __operator * (const float a, const vec3 u) +{ + __asm vec4_multiply __retVal.xyz, a.xxx, u.xyz; } -void __operator += (inout vec4 v, const float a) { - v.x += a; - v.y += a; - v.z += a; - v.w += a; +vec3 __operator * (const vec3 v, const float b) +{ + __asm vec4_multiply __retVal.xyz, v.xyz, b.xxx; } -void __operator -= (inout vec4 v, const float a) { - v.x -= a; - v.y -= a; - v.z -= a; - v.w -= a; +vec3 __operator / (const float a, const vec3 u) +{ + vec3 invU; + __asm float_rcp invU.x, u.x; + __asm float_rcp invU.y, u.y; + __asm float_rcp invU.z, u.z; + __asm vec4_multiply __retVal.xyz, a.xxx, invU.xyz; } -void __operator *= (inout vec4 v, const float a) { - v.x *= a; - v.y *= a; - v.z *= a; - v.w *= a; +vec3 __operator / (const vec3 v, const float b) +{ + float invB; + __asm float_rcp invB, b; + __asm vec4_multiply __retVal.xyz, v.xyz, invB.xxx; } -void __operator /= (inout vec4 v, const float a) { - v.x /= a; - v.y /= a; - v.z /= a; - v.w /= a; + +//// Basic vec4/float operators + +vec4 __operator + (const float a, const vec4 u) +{ + __asm vec4_add __retVal, a.xxxx, u; } -void __operator += (inout mat2 m, const float a) { - m[0] += a; - m[1] += a; +vec4 __operator + (const vec4 v, const float b) +{ + __asm vec4_add __retVal, v, b.xxxx; } -void __operator -= (inout mat2 m, const float a) { - m[0] -= a; - m[1] -= a; +vec4 __operator - (const float a, const vec4 u) +{ + __asm vec4_subtract __retVal, a.xxxx, u; } -void __operator *= (inout mat2 m, const float a) { - m[0] *= a; - m[1] *= a; +vec4 __operator - (const vec4 v, const float b) +{ + __asm vec4_subtract __retVal, v, b.xxxx; } -void __operator /= (inout mat2 m, const float a) { - m[0] /= a; - m[1] /= a; +vec4 __operator * (const float a, const vec4 u) +{ + __asm vec4_multiply __retVal, a.xxxx, u; } -void __operator += (inout mat3 m, const float a) { - m[0] += a; - m[1] += a; - m[2] += a; +vec4 __operator * (const vec4 v, const float b) +{ + __asm vec4_multiply __retVal, v, b.xxxx; } -void __operator -= (inout mat3 m, const float a) { - m[0] -= a; - m[1] -= a; - m[2] -= a; +vec4 __operator / (const float a, const vec4 u) +{ + vec4 invU; + __asm float_rcp invU.x, u.x; + __asm float_rcp invU.y, u.y; + __asm float_rcp invU.z, u.z; + __asm float_rcp invU.w, u.w; + __asm vec4_multiply __retVal, a.xxxx, invU; } -void __operator *= (inout mat3 m, const float a) { - m[0] *= a; - m[1] *= a; - m[2] *= a; +vec4 __operator / (const vec4 v, const float b) +{ + float invB; + __asm float_rcp invB, b; + __asm vec4_multiply __retVal, v, invB.xxxx; } -void __operator /= (inout mat3 m, const float a) { - m[0] /= a; - m[1] /= a; - m[2] /= a; + + +//// Basic ivec2/int operators + +ivec2 __operator + (const int a, const ivec2 u) +{ + __retVal = ivec2(a) + u; } -void __operator += (inout mat4 m, const float a) { - m[0] += a; - m[1] += a; - m[2] += a; - m[3] += a; +ivec2 __operator + (const ivec2 v, const int b) +{ + __retVal = v + ivec2(b); } -void __operator -= (inout mat4 m, const float a) { - m[0] -= a; - m[1] -= a; - m[2] -= a; - m[3] -= a; +ivec2 __operator - (const int a, const ivec2 u) +{ + __retVal = ivec2(a) - u; } -void __operator *= (inout mat4 m, const float a) { - m[0] *= a; - m[1] *= a; - m[2] *= a; - m[3] *= a; +ivec2 __operator - (const ivec2 v, const int b) +{ + __retVal = v - ivec2(b); } -void __operator /= (inout mat4 m, const float a) { - m[0] /= a; - m[1] /= a; - m[2] /= a; - m[3] /= a; +ivec2 __operator * (const int a, const ivec2 u) +{ + __retVal = ivec2(a) * u; } -vec2 __operator * (const vec2 v, const mat2 m) { - return vec2 ( - v.x * m[0].x + v.y * m[0].y, - v.x * m[1].x + v.y * m[1].y - ); +ivec2 __operator * (const ivec2 v, const int b) +{ + __retVal = v * ivec2(b); } -void __operator *= (inout vec2 v, const mat2 m) { - v = v * m; +ivec2 __operator / (const int a, const ivec2 u) +{ + __retVal = ivec2(a) / u; } -vec3 __operator * (const vec3 v, const mat3 m) { - return vec3 ( - v.x * m[0].x + v.y * m[0].y + v.z * m[0].z, - v.x * m[1].x + v.y * m[1].y + v.z * m[1].z, - v.x * m[2].x + v.y * m[2].y + v.z * m[2].z - ); +ivec2 __operator / (const ivec2 v, const int b) +{ + __retVal = v / ivec2(b); } -void __operator *= (inout vec3 v, const mat3 m) { - v = v * m; + +//// Basic ivec3/int operators + +ivec3 __operator + (const int a, const ivec3 u) +{ + __retVal = ivec3(a) + u; } -vec4 __operator * (const vec4 v, const mat4 m) { - return vec4 ( - v.x * m[0].x + v.y * m[0].y + v.z * m[0].z + v.w * m[0].w, - v.x * m[1].x + v.y * m[1].y + v.z * m[1].z + v.w * m[1].w, - v.x * m[2].x + v.y * m[2].y + v.z * m[2].z + v.w * m[2].w, - v.x * m[3].x + v.y * m[3].y + v.z * m[3].z + v.w * m[3].w - ); +ivec3 __operator + (const ivec3 v, const int b) +{ + __retVal = v + ivec3(b); } -void __operator *= (inout vec4 v, const mat4 m) { - v = v * m; +ivec3 __operator - (const int a, const ivec3 u) +{ + __retVal = ivec3(a) - u; } -float __operator - (const float a, const float b) { - float c; - __asm float_negate c, b; - __asm float_add c, a, c; - return c; +ivec3 __operator - (const ivec3 v, const int b) +{ + __retVal = v - ivec3(b); } -int __operator + (const int a, const int b) { - float x, y; - int c; - __asm int_to_float x, a; - __asm int_to_float y, b; - __asm float_add x, x, y; - __asm float_to_int c, x; - return c; +ivec3 __operator * (const int a, const ivec3 u) +{ + __retVal = ivec3(a) * u; } -int __operator - (const int a, const int b) { - float x, y; - int c; - __asm int_to_float x, a; - __asm int_to_float y, b; - __asm float_negate y, y; - __asm float_add x, x, y; - __asm float_to_int c, x; - return c; +ivec3 __operator * (const ivec3 v, const int b) +{ + __retVal = v * ivec3(b); } -int __operator * (const int a, const int b) { - float x, y; - int c; - __asm int_to_float x, a; - __asm int_to_float y, b; - __asm float_multiply x, x, y; - __asm float_to_int c, x; - return c; +ivec3 __operator / (const int a, const ivec3 u) +{ + __retVal = ivec3(a) / u; } -int __operator / (const int a, const int b) { - float x, y; - int c; - __asm int_to_float x, a; - __asm int_to_float y, b; - __asm float_divide x, x, y; - __asm float_to_int c, x; - return c; +ivec3 __operator / (const ivec3 v, const int b) +{ + __retVal = v / ivec3(b); +} + + +//// Basic ivec4/int operators + +ivec4 __operator + (const int a, const ivec4 u) +{ + __retVal = ivec4(a) + u; +} + +ivec4 __operator + (const ivec4 v, const int b) +{ + __retVal = v + ivec4(b); +} + +ivec4 __operator - (const int a, const ivec4 u) +{ + __retVal = ivec4(a) - u; +} + +ivec4 __operator - (const ivec4 v, const int b) +{ + __retVal = v - ivec4(b); +} + +ivec4 __operator * (const int a, const ivec4 u) +{ + __retVal = ivec4(a) * u; +} + +ivec4 __operator * (const ivec4 v, const int b) +{ + __retVal = v * ivec4(b); +} + +ivec4 __operator / (const int a, const ivec4 u) +{ + __retVal = ivec4(a) / u; +} + +ivec4 __operator / (const ivec4 v, const int b) +{ + __retVal = v / ivec4(b); +} + + + + +//// Unary negation operator + +int __operator - (const int a) +{ + __asm vec4_negate __retVal.x, a; +} + +ivec2 __operator - (const ivec2 v) +{ + __asm vec4_negate __retVal, v; +} + +ivec3 __operator - (const ivec3 v) +{ + __asm vec4_negate __retVal, v; +} + +ivec4 __operator - (const ivec4 v) +{ + __asm vec4_negate __retVal, v; } -vec2 __operator + (const vec2 v, const vec2 u) { - return vec2 (v.x + u.x, v.y + u.y); +float __operator - (const float a) +{ + __asm vec4_negate __retVal.x, a; } -vec2 __operator - (const vec2 v, const vec2 u) { - return vec2 (v.x - u.x, v.y - u.y); +vec2 __operator - (const vec2 v) +{ + __asm vec4_negate __retVal.xy, v.xy; } -vec2 __operator * (const vec2 v, const vec2 u) { - return vec2 (v.x * u.x, v.y * u.y); +vec3 __operator - (const vec3 v) +{ + __asm vec4_negate __retVal.xyz, v.xyz; } -vec2 __operator / (const vec2 v, const vec2 u) { - return vec2 (v.x / u.x, v.y / u.y); +vec4 __operator - (const vec4 v) +{ + __asm vec4_negate __retVal, v; } -vec3 __operator + (const vec3 v, const vec3 u) { - return vec3 (v.x + u.x, v.y + u.y, v.z + u.z); +mat2 __operator - (const mat2 m) +{ + __retVal[0] = -m[0]; + __retVal[1] = -m[1]; } -vec3 __operator - (const vec3 v, const vec3 u) { - return vec3 (v.x - u.x, v.y - u.y, v.z - u.z); +mat3 __operator - (const mat3 m) +{ + __retVal[0] = -m[0]; + __retVal[1] = -m[1]; + __retVal[2] = -m[2]; } -vec3 __operator * (const vec3 v, const vec3 u) { - return vec3 (v.x * u.x, v.y * u.y, v.z * u.z); +mat4 __operator - (const mat4 m) +{ + __retVal[0] = -m[0]; + __retVal[1] = -m[1]; + __retVal[2] = -m[2]; + __retVal[3] = -m[3]; } -vec3 __operator / (const vec3 v, const vec3 u) { - return vec3 (v.x / u.x, v.y / u.y, v.z / u.z); + + +//// dot product + +float dot(const float a, const float b) +{ + __retVal = a * b; } -vec4 __operator + (const vec4 v, const vec4 u) { - return vec4 (v.x + u.x, v.y + u.y, v.z + u.z, v.w + u.w); +float dot(const vec2 a, const vec2 b) +{ + __retVal = a.x * b.x + a.y * b.y; } -vec4 __operator - (const vec4 v, const vec4 u) { - return vec4 (v.x - u.x, v.y - u.y, v.z - u.z, v.w - u.w); +float dot(const vec3 a, const vec3 b) +{ + __asm vec3_dot __retVal, a, b; } -vec4 __operator * (const vec4 v, const vec4 u) { - return vec4 (v.x * u.x, v.y * u.y, v.z * u.z, v.w * u.w); +float dot(const vec4 a, const vec4 b) +{ + __asm vec4_dot __retVal, a, b; } -vec4 __operator / (const vec4 v, const vec4 u) { - return vec4 (v.x / u.x, v.y / u.y, v.z / u.z, v.w / u.w); + + +//// int assignment operators + +void __operator += (inout int a, const int b) +{ + __asm vec4_add a, a, b; } -ivec2 __operator + (const ivec2 v, const ivec2 u) { - return ivec2 (v.x + u.x, v.y + u.y); +void __operator -= (inout int a, const int b) +{ + __asm vec4_subtract a, a, b; } -ivec2 __operator - (const ivec2 v, const ivec2 u) { - return ivec2 (v.x - u.x, v.y - u.y); +void __operator *= (inout int a, const int b) +{ + __asm vec4_multiply a, a, b; } -ivec2 __operator * (const ivec2 v, const ivec2 u) { - return ivec2 (v.x * u.x, v.y * u.y); +void __operator /= (inout int a, const int b) +{ + float invB; + __asm float_rcp invB, b; + __asm vec4_multiply a, a, invB; } -ivec2 __operator / (const ivec2 v, const ivec2 u) { - return ivec2 (v.x / u.x, v.y / u.y); + +//// ivec2 assignment operators + +void __operator += (inout ivec2 v, const ivec2 u) +{ + __asm vec4_add v, v, u; } -ivec3 __operator + (const ivec3 v, const ivec3 u) { - return ivec3 (v.x + u.x, v.y + u.y, v.z + u.z); +void __operator -= (inout ivec2 v, const ivec2 u) +{ + __asm vec4_subtract v, v, u; } -ivec3 __operator - (const ivec3 v, const ivec3 u) { - return ivec3 (v.x - u.x, v.y - u.y, v.z - u.z); +void __operator *= (inout ivec2 v, const ivec2 u) +{ + __asm vec4_multiply v, v, u; } -ivec3 __operator * (const ivec3 v, const ivec3 u) { - return ivec3 (v.x * u.x, v.y * u.y, v.z * u.z); +void __operator /= (inout ivec2 v, const ivec2 u) +{ + ivec2 inv, z; + __asm float_rcp inv.x, u.x; + __asm float_rcp inv.y, u.y; + __asm vec4_multiply z, v, inv; + __asm float_to_int __retVal, z; } -ivec3 __operator / (const ivec3 v, const ivec3 u) { - return ivec3 (v.x / u.x, v.y / u.y, v.z / u.z); + +//// ivec3 assignment operators + +void __operator += (inout ivec3 v, const ivec3 u) +{ + __asm vec4_add v, v, u; } -ivec4 __operator + (const ivec4 v, const ivec4 u) { - return ivec4 (v.x + u.x, v.y + u.y, v.z + u.z, v.w + u.w); +void __operator -= (inout ivec3 v, const ivec3 u) +{ + __asm vec4_subtract v, v, u; } -ivec4 __operator - (const ivec4 v, const ivec4 u) { - return ivec4 (v.x - u.x, v.y - u.y, v.z - u.z, v.w - u.w); +void __operator *= (inout ivec3 v, const ivec3 u) +{ + __asm vec4_multiply v, v, u; } -ivec4 __operator * (const ivec4 v, const ivec4 u) { - return ivec4 (v.x * u.x, v.y * u.y, v.z * u.z, v.w * u.w); +void __operator /= (inout ivec3 v, const ivec3 u) +{ + ivec3 inv, z; + __asm float_rcp inv.x, u.x; + __asm float_rcp inv.y, u.y; + __asm vec4_multiply z, v, inv; + __asm float_to_int __retVal, z; } -ivec4 __operator / (const ivec4 v, const ivec4 u) { - return ivec4 (v.x / u.x, v.y / u.y, v.z / u.z, v.w / u.w); + +//// ivec4 assignment operators + +void __operator += (inout ivec4 v, const ivec4 u) +{ + __asm vec4_add v, v, u; } -mat2 __operator + (const mat2 m, const mat2 n) { - return mat2 (m[0] + n[0], m[1] + n[1]); +void __operator -= (inout ivec4 v, const ivec4 u) +{ + __asm vec4_subtract v, v, u; } -mat2 __operator - (const mat2 m, const mat2 n) { - return mat2 (m[0] - n[0], m[1] - n[1]); +void __operator *= (inout ivec4 v, const ivec4 u) +{ + __asm vec4_multiply v, v, u; } -mat2 __operator / (const mat2 m, const mat2 n) { - return mat2 (m[0] / n[0], m[1] / n[1]); +void __operator /= (inout ivec4 v, const ivec4 u) +{ + ivec4 inv, z; + __asm float_rcp inv.x, u.x; + __asm float_rcp inv.y, u.y; + __asm vec4_multiply z, v, inv; + __asm float_to_int __retVal, z; } -mat3 __operator + (const mat3 m, const mat3 n) { - return mat3 (m[0] + n[0], m[1] + n[1], m[2] + n[2]); + +//// float assignment operators + +void __operator += (inout float a, const float b) +{ + __asm vec4_add a.x, a.x, b; } -mat3 __operator - (const mat3 m, const mat3 n) { - return mat3 (m[0] - n[0], m[1] - n[1], m[2] - n[2]); +void __operator -= (inout float a, const float b) +{ + __asm vec4_subtract a.x, a, b; } -mat3 __operator / (const mat3 m, const mat3 n) { - return mat3 (m[0] / n[0], m[1] / n[1], m[2] / n[2]); +void __operator *= (inout float a, const float b) +{ + __asm vec4_multiply a.x, a, b; } -mat4 __operator + (const mat4 m, const mat4 n) { - return mat4 (m[0] + n[0], m[1] + n[1], m[2] + n[2], m[3] + n[3]); +void __operator /= (inout float a, const float b) +{ + float w; // = 1 / b + __asm float_rcp w.x, b; + __asm vec4_multiply a.x, a, w; } -mat4 __operator - (const mat4 m, const mat4 n) { - return mat4 (m[0] - n[0], m[1] - n[1], m[2] - n[2], m[3] - n[3]); + +//// vec2 assignment operators + +void __operator += (inout vec2 v, const vec2 u) +{ + __asm vec4_add v.xy, v.xy, u.xy; } -mat4 __operator / (const mat4 m, const mat4 n) { - return mat4 (m[0] / n[0], m[1] / n[1], m[2] / n[2], m[3] / n[3]); +void __operator -= (inout vec2 v, const vec2 u) +{ + __asm vec4_subtract v.xy, v.xy, u.xy; } -vec2 __operator + (const float a, const vec2 u) { - return vec2 (a + u.x, a + u.y); +void __operator *= (inout vec2 v, const vec2 u) +{ + __asm vec4_multiply v.xy, v.xy, u.xy; } -vec2 __operator + (const vec2 v, const float b) { - return vec2 (v.x + b, v.y + b); +void __operator /= (inout vec2 v, const vec2 u) +{ + vec2 w; + __asm float_rcp w.x, u.x; + __asm float_rcp w.y, u.y; + __asm vec4_multiply v.xy, v.xy, w.xy; } -vec2 __operator - (const float a, const vec2 u) { - return vec2 (a - u.x, a - u.y); + +//// vec3 assignment operators + +void __operator += (inout vec3 v, const vec3 u) +{ + __asm vec4_add v.xyz, v, u; } -vec2 __operator - (const vec2 v, const float b) { - return vec2 (v.x - b, v.y - b); +void __operator -= (inout vec3 v, const vec3 u) +{ + __asm vec4_subtract v.xyz, v, u; } -vec2 __operator * (const float a, const vec2 u) { - return vec2 (a * u.x, a * u.y); +void __operator *= (inout vec3 v, const vec3 u) +{ + __asm vec4_multiply v.xyz, v, u; } -vec2 __operator * (const vec2 v, const float b) { - return vec2 (v.x * b, v.y * b); +void __operator /= (inout vec3 v, const vec3 u) +{ + vec3 w; + __asm float_rcp w.x, u.x; + __asm float_rcp w.y, u.y; + __asm float_rcp w.z, u.z; + __asm vec4_multiply v.xyz, v.xyz, w.xyz; } -vec2 __operator / (const float a, const vec2 u) { - return vec2 (a / u.x, a / u.y); + +//// vec4 assignment operators + +void __operator += (inout vec4 v, const vec4 u) +{ + __asm vec4_add v, v, u; } -vec2 __operator / (const vec2 v, const float b) { - return vec2 (v.x / b, v.y / b); +void __operator -= (inout vec4 v, const vec4 u) +{ + __asm vec4_subtract v, v, u; } -vec3 __operator + (const float a, const vec3 u) { - return vec3 (a + u.x, a + u.y, a + u.z); +void __operator *= (inout vec4 v, const vec4 u) +{ + __asm vec4_multiply v, v, u; } -vec3 __operator + (const vec3 v, const float b) { - return vec3 (v.x + b, v.y + b, v.z + b); +void __operator /= (inout vec4 v, const vec4 u) +{ + vec4 w; + __asm float_rcp w.x, u.x; + __asm float_rcp w.y, u.y; + __asm float_rcp w.z, u.z; + __asm float_rcp w.w, u.w; + __asm vec4_multiply v, v, w; } -vec3 __operator - (const float a, const vec3 u) { - return vec3 (a - u.x, a - u.y, a - u.z); + + +//// ivec2/int assignment operators + +void __operator += (inout ivec2 v, const int a) +{ + __asm vec4_add v.xy, v.xy, a.xx; } -vec3 __operator - (const vec3 v, const float b) { - return vec3 (v.x - b, v.y - b, v.z - b); +void __operator -= (inout ivec2 v, const int a) +{ + __asm vec4_subtract v.xy, v.xy, a.xx; } -vec3 __operator * (const float a, const vec3 u) { - return vec3 (a * u.x, a * u.y, a * u.z); +void __operator *= (inout ivec2 v, const int a) +{ + __asm vec4_multiply v.xy, v.xy, a.xx; + v.x *= a; + v.y *= a; } -vec3 __operator * (const vec3 v, const float b) { - return vec3 (v.x * b, v.y * b, v.z * b); +void __operator /= (inout ivec2 v, const int a) +{ +// XXX rcp + v.x /= a; + v.y /= a; } -vec3 __operator / (const float a, const vec3 u) { - return vec3 (a / u.x, a / u.y, a / u.z); + +//// ivec3/int assignment operators + +void __operator += (inout ivec3 v, const int a) +{ + __asm vec4_add v.xyz, v.xyz, a.xxx; } -vec3 __operator / (const vec3 v, const float b) { - return vec3 (v.x / b, v.y / b, v.z / b); +void __operator -= (inout ivec3 v, const int a) +{ + __asm vec4_subtract v.xyz, v.xyz, a.xxx; } -vec4 __operator + (const float a, const vec4 u) { - return vec4 (a + u.x, a + u.y, a + u.z, a + u.w); +void __operator *= (inout ivec3 v, const int a) +{ + __asm vec4_multiply v.xyz, v.xyz, a.xxx; } -vec4 __operator + (const vec4 v, const float b) { - return vec4 (v.x + b, v.y + b, v.z + b, v.w + b); +void __operator /= (inout ivec3 v, const int a) +{ + // XXX rcp + v.x /= a; + v.y /= a; + v.z /= a; } -vec4 __operator - (const float a, const vec4 u) { - return vec4 (a - u.x, a - u.y, a - u.z, a - u.w); + +//// ivec4/int assignment operators + +void __operator += (inout ivec4 v, const int a) +{ + __asm vec4_add v, v, a.xxxx; } -vec4 __operator - (const vec4 v, const float b) { - return vec4 (v.x - b, v.y - b, v.z - b, v.w - b); +void __operator -= (inout ivec4 v, const int a) +{ + __asm vec4_subtract v, v, a.xxxx; } -vec4 __operator * (const float a, const vec4 u) { - return vec4 (a * u.x, a * u.y, a * u.z, a * u.w); +void __operator *= (inout ivec4 v, const int a) +{ + __asm vec4_multiply v, v, a.xxxx; } -vec4 __operator * (const vec4 v, const float b) { - return vec4 (v.x * b, v.y * b, v.z * b, v.w * b); +void __operator /= (inout ivec4 v, const int a) +{ + v.x /= a; + v.y /= a; + v.z /= a; + v.w /= a; } -vec4 __operator / (const float a, const vec4 u) { - return vec4 (a / u.x, a / u.y, a / u.z, a / u.w); + + +//// vec2/float assignment operators + +void __operator += (inout vec2 v, const float a) +{ + __asm vec4_add v.xy, v, a.xx; } -vec4 __operator / (const vec4 v, const float b) { - return vec4 (v.x / b, v.y / b, v.z / b, v.w / b); +void __operator -= (inout vec2 v, const float a) +{ + __asm vec4_subtract v.xy, v, a.xx; } -mat2 __operator + (const float a, const mat2 n) { - return mat2 (a + n[0], a + n[1]); +void __operator *= (inout vec2 v, const float a) +{ + __asm vec4_multiply v.xy, v, a.xx; } -mat2 __operator + (const mat2 m, const float b) { - return mat2 (m[0] + b, m[1] + b); +void __operator /= (inout vec2 v, const float a) +{ + float invA; + __asm float_rcp invA, a; + __asm vec4_multiply v.xy, v.xy, a.xx; } -mat2 __operator - (const float a, const mat2 n) { - return mat2 (a - n[0], a - n[1]); + +//// vec3/float assignment operators + +void __operator += (inout vec3 v, const float a) +{ + __asm vec4_add v.xyz, v, a.xxx; } -mat2 __operator - (const mat2 m, const float b) { - return mat2 (m[0] - b, m[1] - b); +void __operator -= (inout vec3 v, const float a) +{ + __asm vec4_subtract v.xyz, v, a.xxx; } -mat2 __operator * (const float a, const mat2 n) { - return mat2 (a * n[0], a * n[1]); +void __operator *= (inout vec3 v, const float a) +{ + __asm vec4_multiply v.xyz, v, a.xxx; } -mat2 __operator * (const mat2 m, const float b) { - return mat2 (m[0] * b, m[1] * b); +void __operator /= (inout vec3 v, const float a) +{ + float invA; + __asm float_rcp invA, a; + __asm vec4_multiply v.xyz, v.xyz, a.xxx; } -mat2 __operator / (const float a, const mat2 n) { - return mat2 (a / n[0], a / n[1]); + +//// vec4/float assignment operators + +void __operator += (inout vec4 v, const float a) +{ + __asm vec4_add v, v, a.xxxx; } -mat2 __operator / (const mat2 m, const float b) { - return mat2 (m[0] / b, m[1] / b); +void __operator -= (inout vec4 v, const float a) +{ + __asm vec4_subtract v, v, a.xxxx; } -mat3 __operator + (const float a, const mat3 n) { - return mat3 (a + n[0], a + n[1], a + n[2]); +void __operator *= (inout vec4 v, const float a) +{ + __asm vec4_multiply v, v, a.xxxx; } -mat3 __operator + (const mat3 m, const float b) { - return mat3 (m[0] + b, m[1] + b, m[2] + b); +void __operator /= (inout vec4 v, const float a) +{ + float invA; + __asm float_rcp invA, a; + __asm vec4_multiply v, v, a.xxxx; } -mat3 __operator - (const float a, const mat3 n) { - return mat3 (a - n[0], a - n[1], a - n[2]); + + + + +//// Basic mat2 operations + +mat2 __operator + (const mat2 m, const mat2 n) +{ + __retVal[0] = m[0] + n[0]; + __retVal[1] = m[1] + n[1]; } -mat3 __operator - (const mat3 m, const float b) { - return mat3 (m[0] - b, m[1] - b, m[2] - b); +mat2 __operator - (const mat2 m, const mat2 n) +{ + __retVal[0] = m[0] - n[0]; + __retVal[1] = m[1] - n[1]; } -mat3 __operator * (const float a, const mat3 n) { - return mat3 (a * n[0], a * n[1], a * n[2]); +mat2 __operator * (const mat2 m, const mat2 n) +{ + vec2 mRow0, mRow1; + mRow0.x = m[0].x; + mRow0.y = m[1].x; + mRow1.x = m[0].y; + mRow1.y = m[1].y; + __retVal[0].x = dot(mRow0, n[0]); + __retVal[1].x = dot(mRow0, n[1]); + __retVal[0].y = dot(mRow1, n[0]); + __retVal[1].y = dot(mRow1, n[1]); } -mat3 __operator * (const mat3 m, const float b) { - return mat3 (m[0] * b, m[1] * b, m[2] * b); +mat2 __operator / (const mat2 m, const mat2 n) +{ + __retVal[0] = m[0] / n[0]; + __retVal[1] = m[1] / n[1]; } -mat3 __operator / (const float a, const mat3 n) { - return mat3 (a / n[0], a / n[1], a / n[2]); + +//// Basic mat3 operations + +mat3 __operator + (const mat3 m, const mat3 n) +{ + __retVal[0] = m[0] + n[0]; + __retVal[1] = m[1] + n[1]; + __retVal[2] = m[2] + n[2]; } -mat3 __operator / (const mat3 m, const float b) { - return mat3 (m[0] / b, m[1] / b, m[2] / b); +mat3 __operator - (const mat3 m, const mat3 n) +{ + __retVal[0] = m[0] - n[0]; + __retVal[1] = m[1] - n[1]; + __retVal[2] = m[2] - n[2]; +} + +mat3 __operator * (const mat3 m, const mat3 n) +{ + // sub-blocks to reduce register usage + { + vec3 mRow0; + mRow0.x = m[0].x; + mRow0.y = m[1].x; + mRow0.z = m[2].x; + __retVal[0].x = dot(mRow0, n[0]); + __retVal[1].x = dot(mRow0, n[1]); + __retVal[2].x = dot(mRow0, n[2]); + } + { + vec3 mRow1; + mRow1.x = m[0].y; + mRow1.y = m[1].y; + mRow1.z = m[2].y; + __retVal[0].y = dot(mRow1, n[0]); + __retVal[1].y = dot(mRow1, n[1]); + __retVal[2].y = dot(mRow1, n[2]); + } + { + vec3 mRow2; + mRow2.x = m[0].z; + mRow2.y = m[1].z; + mRow2.z = m[2].z; + __retVal[0].z = dot(mRow2, n[0]); + __retVal[1].z = dot(mRow2, n[1]); + __retVal[2].z = dot(mRow2, n[2]); + } +} + +mat3 __operator / (const mat3 m, const mat3 n) +{ + __retVal[0] = m[0] / n[0]; + __retVal[1] = m[1] / n[1]; + __retVal[2] = m[2] / n[2]; +} + + +//// Basic mat4 operations + +mat4 __operator + (const mat4 m, const mat4 n) +{ + __retVal[0] = m[0] + n[0]; + __retVal[1] = m[1] + n[1]; + __retVal[2] = m[2] + n[2]; + __retVal[3] = m[3] + n[3]; +} + +mat4 __operator - (const mat4 m, const mat4 n) +{ + __retVal[0] = m[0] - n[0]; + __retVal[1] = m[1] - n[1]; + __retVal[2] = m[2] - n[2]; + __retVal[3] = m[3] - n[3]; +} + +mat4 __operator * (const mat4 m, const mat4 n) +{ + // sub-blocks to reduce temporary usage + { + vec4 mRow0; + mRow0.x = m[0].x; + mRow0.y = m[1].x; + mRow0.z = m[2].x; + mRow0.w = m[3].x; + __retVal[0].x = dot(mRow0, n[0]); + __retVal[1].x = dot(mRow0, n[1]); + __retVal[2].x = dot(mRow0, n[2]); + __retVal[3].x = dot(mRow0, n[3]); + } + { + vec4 mRow1; + mRow1.x = m[0].y; + mRow1.y = m[1].y; + mRow1.z = m[2].y; + mRow1.w = m[3].y; + __retVal[0].y = dot(mRow1, n[0]); + __retVal[1].y = dot(mRow1, n[1]); + __retVal[2].y = dot(mRow1, n[2]); + __retVal[3].y = dot(mRow1, n[3]); + } + { + vec4 mRow2; + mRow2.x = m[0].z; + mRow2.y = m[1].z; + mRow2.z = m[2].z; + mRow2.w = m[3].z; + __retVal[0].z = dot(mRow2, n[0]); + __retVal[1].z = dot(mRow2, n[1]); + __retVal[2].z = dot(mRow2, n[2]); + __retVal[3].z = dot(mRow2, n[3]); + } + { + vec4 mRow3; + mRow3.x = m[0].w; + mRow3.y = m[1].w; + mRow3.z = m[2].w; + mRow3.w = m[3].w; + __retVal[0].w = dot(mRow3, n[0]); + __retVal[1].w = dot(mRow3, n[1]); + __retVal[2].w = dot(mRow3, n[2]); + __retVal[3].w = dot(mRow3, n[3]); + } +} + +mat4 __operator / (const mat4 m, const mat4 n) +{ + __retVal[0] = m[0] / n[0]; + __retVal[1] = m[1] / n[1]; + __retVal[2] = m[2] / n[2]; + __retVal[3] = m[3] / n[3]; +} + + +//// mat2/float operations + +mat2 __operator + (const float a, const mat2 n) +{ + __retVal[0] = a + n[0]; + __retVal[1] = a + n[1]; +} + +mat2 __operator + (const mat2 m, const float b) +{ + __retVal[0] = m[0] + b; + __retVal[1] = m[1] + b; } -mat4 __operator + (const float a, const mat4 n) { - return mat4 (a + n[0], a + n[1], a + n[2], a + n[3]); +mat2 __operator - (const float a, const mat2 n) +{ + __retVal[0] = a - n[0]; + __retVal[1] = a - n[1]; } -mat4 __operator + (const mat4 m, const float b) { - return mat4 (m[0] + b, m[1] + b, m[2] + b, m[3] + b); +mat2 __operator - (const mat2 m, const float b) +{ + __retVal[0] = m[0] - b; + __retVal[1] = m[1] - b; +} + +mat2 __operator * (const float a, const mat2 n) +{ + __retVal[0] = a * n[0]; + __retVal[1] = a * n[1]; } -mat4 __operator - (const float a, const mat4 n) { - return mat4 (a - n[0], a - n[1], a - n[2], a - n[3]); +mat2 __operator * (const mat2 m, const float b) +{ + __retVal[0] = m[0] * b; + __retVal[1] = m[1] * b; +} + +mat2 __operator / (const float a, const mat2 n) +{ + __retVal[0] = a / n[0]; + __retVal[1] = a / n[1]; } -mat4 __operator - (const mat4 m, const float b) { - return mat4 (m[0] - b, m[1] - b, m[2] - b, m[3] - b); +mat2 __operator / (const mat2 m, const float b) +{ + __retVal[0] = m[0] / b; + __retVal[1] = m[1] / b; } -mat4 __operator * (const float a, const mat4 n) { - return mat4 (a * n[0], a * n[1], a * n[2], a * n[3]); + +//// mat3/float operations + +mat3 __operator + (const float a, const mat3 n) +{ + __retVal[0] = a + n[0]; + __retVal[1] = a + n[1]; + __retVal[2] = a + n[2]; } -mat4 __operator * (const mat4 m, const float b) { - return mat4 (m[0] * b, m[1] * b, m[2] * b, m[3] * b); +mat3 __operator + (const mat3 m, const float b) +{ + __retVal[0] = m[0] + b; + __retVal[1] = m[1] + b; + __retVal[2] = m[2] + b; } -mat4 __operator / (const float a, const mat4 n) { - return mat4 (a / n[0], a / n[1], a / n[2], a / n[3]); +mat3 __operator - (const float a, const mat3 n) +{ + __retVal[0] = a - n[0]; + __retVal[1] = a - n[1]; + __retVal[2] = a - n[2]; } -mat4 __operator / (const mat4 m, const float b) { - return mat4 (m[0] / b, m[1] / b, m[2] / b, m[3] / b); +mat3 __operator - (const mat3 m, const float b) +{ + __retVal[0] = m[0] - b; + __retVal[1] = m[1] - b; + __retVal[2] = m[2] - b; } -ivec2 __operator + (const int a, const ivec2 u) { - return ivec2 (a) + u; +mat3 __operator * (const float a, const mat3 n) +{ + __retVal[0] = a * n[0]; + __retVal[1] = a * n[1]; + __retVal[2] = a * n[2]; } -ivec2 __operator + (const ivec2 v, const int b) { - return v + ivec2 (b); +mat3 __operator * (const mat3 m, const float b) +{ + __retVal[0] = m[0] * b; + __retVal[1] = m[1] * b; + __retVal[2] = m[2] * b; } -ivec2 __operator - (const int a, const ivec2 u) { - return ivec2 (a) - u; +mat3 __operator / (const float a, const mat3 n) +{ + __retVal[0] = a / n[0]; + __retVal[1] = a / n[1]; + __retVal[2] = a / n[2]; } -ivec2 __operator - (const ivec2 v, const int b) { - return v - ivec2 (b); +mat3 __operator / (const mat3 m, const float b) +{ + __retVal[0] = m[0] / b; + __retVal[1] = m[1] / b; + __retVal[2] = m[2] / b; } -ivec2 __operator * (const int a, const ivec2 u) { - return ivec2 (a) * u; + +//// mat4/float operations + +mat4 __operator + (const float a, const mat4 n) +{ + __retVal[0] = a + n[0]; + __retVal[1] = a + n[1]; + __retVal[2] = a + n[2]; + __retVal[3] = a + n[3]; } -ivec2 __operator * (const ivec2 v, const int b) { - return v * ivec2 (b); +mat4 __operator + (const mat4 m, const float b) +{ + __retVal[0] = m[0] + b; + __retVal[1] = m[1] + b; + __retVal[2] = m[2] + b; + __retVal[3] = m[3] + b; } -ivec2 __operator / (const int a, const ivec2 u) { - return ivec2 (a) / u; +mat4 __operator - (const float a, const mat4 n) +{ + __retVal[0] = a - n[0]; + __retVal[1] = a - n[1]; + __retVal[2] = a - n[2]; + __retVal[3] = a - n[3]; } -ivec2 __operator / (const ivec2 v, const int b) { - return v / ivec2 (b); +mat4 __operator - (const mat4 m, const float b) +{ + __retVal[0] = m[0] - b; + __retVal[1] = m[1] - b; + __retVal[2] = m[2] - b; + __retVal[3] = m[3] - b; } -ivec3 __operator + (const int a, const ivec3 u) { - return ivec3 (a) + u; +mat4 __operator * (const float a, const mat4 n) +{ + __retVal[0] = a * n[0]; + __retVal[1] = a * n[1]; + __retVal[2] = a * n[2]; + __retVal[3] = a * n[3]; +} + +mat4 __operator * (const mat4 m, const float b) +{ + __retVal[0] = m[0] * b; + __retVal[1] = m[1] * b; + __retVal[2] = m[2] * b; + __retVal[3] = m[3] * b; +} + +mat4 __operator / (const float a, const mat4 n) +{ + __retVal[0] = a / n[0]; + __retVal[1] = a / n[1]; + __retVal[2] = a / n[2]; + __retVal[3] = a / n[3]; +} + +mat4 __operator / (const mat4 m, const float b) +{ + __retVal[0] = m[0] / b; + __retVal[1] = m[1] / b; + __retVal[2] = m[2] / b; + __retVal[3] = m[3] / b; +} + + + +//// matrix / vector products + +vec2 __operator * (const mat2 m, const vec2 v) +{ + vec2 r0, r1; + r0.x = m[0].x; + r0.y = m[1].x; + r1.x = m[0].y; + r1.y = m[1].y; + __retVal.x = dot(r0, v); + __retVal.y = dot(r1, v); +} + +vec2 __operator * (const vec2 v, const mat2 m) +{ + __retVal.x = dot(v, m[0]); + __retVal.y = dot(v, m[1]); +} + +vec3 __operator * (const mat3 m, const vec3 v) +{ + { + vec3 r0; + r0.x = m[0].x; + r0.y = m[1].x; + r0.z = m[2].x; + __asm vec3_dot __retVal.x, r0, v; + } + { + vec3 r1; + r1.x = m[0].y; + r1.y = m[1].y; + r1.z = m[2].y; + __asm vec3_dot __retVal.y, r1, v; + } + { + vec3 r2; + r2.x = m[0].z; + r2.y = m[1].z; + r2.z = m[2].z; + __asm vec3_dot __retVal.z, r2, v; + } +} + +vec3 __operator * (const vec3 v, const mat3 m) +{ + __retVal.x = dot(v, m[0]); + __retVal.y = dot(v, m[1]); + __retVal.z = dot(v, m[2]); +} + +vec4 __operator * (const mat4 m, const vec4 v) +{ + // extract rows, then do dot product + { + vec4 r0; + r0.x = m[0].x; + r0.y = m[1].x; + r0.z = m[2].x; + r0.w = m[3].x; + __asm vec4_dot __retVal.x, r0, v; + } + { + vec4 r1; + r1.x = m[0].y; + r1.y = m[1].y; + r1.z = m[2].y; + r1.w = m[3].y; + __asm vec4_dot __retVal.y, r1, v; + } + { + vec4 r2; + r2.x = m[0].z; + r2.y = m[1].z; + r2.z = m[2].z; + r2.w = m[3].z; + __asm vec4_dot __retVal.z, r2, v; + } + { + vec4 r3; + r3.x = m[0].w; + r3.y = m[1].w; + r3.z = m[2].w; + r3.w = m[3].w; + __asm vec4_dot __retVal.w, r3, v; + } +} + +vec4 __operator * (const vec4 v, const mat4 m) +{ + //mm + __retVal.x = dot(v, m[0]); + __retVal.y = dot(v, m[1]); + __retVal.z = dot(v, m[2]); + __retVal.w = dot(v, m[3]); +} + + + +//// mat2 assignment operators + +void __operator += (inout mat2 m, const mat2 n) +{ + m[0] += n[0]; + m[1] += n[1]; } -ivec3 __operator + (const ivec3 v, const int b) { - return v + ivec3 (b); +void __operator -= (inout mat2 m, const mat2 n) +{ + m[0] -= n[0]; + m[1] -= n[1]; } -ivec3 __operator - (const int a, const ivec3 u) { - return ivec3 (a) - u; +void __operator *= (inout mat2 m, const mat2 n) +{ + m = m * n; } -ivec3 __operator - (const ivec3 v, const int b) { - return v - ivec3 (b); +void __operator /= (inout mat2 m, const mat2 n) +{ + m[0] /= n[0]; + m[1] /= n[1]; } -ivec3 __operator * (const int a, const ivec3 u) { - return ivec3 (a) * u; + +//// mat3 assignment operators + +void __operator += (inout mat3 m, const mat3 n) +{ + m[0] += n[0]; + m[1] += n[1]; + m[2] += n[2]; } -ivec3 __operator * (const ivec3 v, const int b) { - return v * ivec3 (b); +void __operator -= (inout mat3 m, const mat3 n) +{ + m[0] -= n[0]; + m[1] -= n[1]; + m[2] -= n[2]; } -ivec3 __operator / (const int a, const ivec3 u) { - return ivec3 (a) / u; +void __operator *= (inout mat3 m, const mat3 n) +{ + m = m * n; } -ivec3 __operator / (const ivec3 v, const int b) { - return v / ivec3 (b); +void __operator /= (inout mat3 m, const mat3 n) +{ + m[0] /= n[0]; + m[1] /= n[1]; + m[2] /= n[2]; } -ivec4 __operator + (const int a, const ivec4 u) { - return ivec4 (a) + u; + +// mat4 assignment operators + +void __operator += (inout mat4 m, const mat4 n) +{ + m[0] += n[0]; + m[1] += n[1]; + m[2] += n[2]; + m[3] += n[3]; } -ivec4 __operator + (const ivec4 v, const int b) { - return v + ivec4 (b); +void __operator -= (inout mat4 m, const mat4 n) { + m[0] -= n[0]; + m[1] -= n[1]; + m[2] -= n[2]; + m[3] -= n[3]; +} + +void __operator *= (inout mat4 m, const mat4 n) +{ + m = m * n; } -ivec4 __operator - (const int a, const ivec4 u) { - return ivec4 (a) - u; +void __operator /= (inout mat4 m, const mat4 n) +{ + m[0] /= n[0]; + m[1] /= n[1]; + m[2] /= n[2]; + m[3] /= n[3]; +} + + +//// mat2/float assignment operators + +void __operator += (inout mat2 m, const float a) { + m[0] += a; + m[1] += a; } -ivec4 __operator - (const ivec4 v, const int b) { - return v - ivec4 (b); +void __operator -= (inout mat2 m, const float a) { + m[0] -= a; + m[1] -= a; } -ivec4 __operator * (const int a, const ivec4 u) { - return ivec4 (a) * u; +void __operator *= (inout mat2 m, const float a) { + m[0] *= a; + m[1] *= a; } -ivec4 __operator * (const ivec4 v, const int b) { - return v * ivec4 (b); +void __operator /= (inout mat2 m, const float a) { + m[0] /= a; + m[1] /= a; } -ivec4 __operator / (const int a, const ivec4 u) { - return ivec4 (a) / u; + +//// mat3/float assignment operators + +void __operator += (inout mat3 m, const float a) { + m[0] += a; + m[1] += a; + m[2] += a; } -ivec4 __operator / (const ivec4 v, const int b) { - return v / ivec4 (b); +void __operator -= (inout mat3 m, const float a) { + m[0] -= a; + m[1] -= a; + m[2] -= a; } -vec2 __operator - (const vec2 v) { - return vec2 (-v.x, -v.y); +void __operator *= (inout mat3 m, const float a) { + m[0] *= a; + m[1] *= a; + m[2] *= a; } -vec3 __operator - (const vec3 v) { - return vec3 (-v.x, -v.y, -v.z); +void __operator /= (inout mat3 m, const float a) { + m[0] /= a; + m[1] /= a; + m[2] /= a; } -vec4 __operator - (const vec4 v) { - return vec4 (-v.x, -v.y, -v.z, -v.w); + +//// mat4/float assignment operators + +void __operator += (inout mat4 m, const float a) { + m[0] += a; + m[1] += a; + m[2] += a; + m[3] += a; } -ivec2 __operator - (const ivec2 v) { - return ivec2 (-v.x, -v.y); +void __operator -= (inout mat4 m, const float a) { + m[0] -= a; + m[1] -= a; + m[2] -= a; + m[3] -= a; } -ivec3 __operator - (const ivec3 v) { - return ivec3 (-v.x, -v.y, -v.z); +void __operator *= (inout mat4 m, const float a) { + m[0] *= a; + m[1] *= a; + m[2] *= a; + m[3] *= a; } -ivec4 __operator - (const ivec4 v) { - return ivec4 (-v.x, -v.y, -v.z, -v.w); +void __operator /= (inout mat4 m, const float a) { + m[0] /= a; + m[1] /= a; + m[2] /= a; + m[3] /= a; } -mat2 __operator - (const mat2 m) { - return mat2 (-m[0], -m[1]); + + +//// vec/mat assignment operators + +void __operator *= (inout vec2 v, const mat2 m) +{ + v = v * m; } -mat3 __operator - (const mat3 m) { - return mat3 (-m[0], -m[1], -m[2]); +void __operator *= (inout vec3 v, const mat3 m) +{ + v = v * m; } -mat4 __operator - (const mat4 m) { - return mat4 (-m[0], -m[1], -m[2], -m[3]); +void __operator *= (inout vec4 v, const mat4 m) +{ + v = v * m; } -void __operator -- (inout float a) { - a -= 1.0; + + +//// pre-decrement operators + +int __operator --(inout int a) +{ + a = a - 1; + __retVal = a; } -void __operator -- (inout int a) { - a -= 1; +ivec2 __operator --(inout ivec2 v) +{ + v = v - ivec2(1); + __retVal = v; } -void __operator -- (inout vec2 v) { - --v.x; - --v.y; +ivec3 __operator --(inout ivec3 v) +{ + v = v - ivec3(1); + __retVal = v; } -void __operator -- (inout vec3 v) { - --v.x; - --v.y; - --v.z; +ivec4 __operator --(inout ivec4 v) +{ + v = v - ivec4(1); + __retVal = v; } -void __operator -- (inout vec4 v) { - --v.x; - --v.y; - --v.z; - --v.w; + +float __operator --(inout float a) +{ + a = a - 1.0; + __retVal = a; } -void __operator -- (inout ivec2 v) { - --v.x; - --v.y; +vec2 __operator --(inout vec2 v) +{ + v = v - vec2(1.0); + __retVal = v; } -void __operator -- (inout ivec3 v) { - --v.x; - --v.y; - --v.z; +vec3 __operator --(inout vec3 v) +{ + v = v - vec3(1.0); + __retVal = v; } -void __operator -- (inout ivec4 v) { - --v.x; - --v.y; - --v.z; - --v.w; +vec4 __operator --(inout vec4 v) +{ + v = v - vec4(1.0); + __retVal = v; } -void __operator -- (inout mat2 m) { - --m[0]; - --m[1]; + +mat2 __operator --(inout mat2 m) +{ + m[0] = m[0] - vec2(1.0); + m[1] = m[1] - vec2(1.0); + __retVal = m; } -void __operator -- (inout mat3 m) { - --m[0]; - --m[1]; - --m[2]; +mat3 __operator --(inout mat3 m) +{ + m[0] = m[0] - vec3(1.0); + m[1] = m[1] - vec3(1.0); + m[2] = m[2] - vec3(1.0); + __retVal = m; } -void __operator -- (inout mat4 m) { - --m[0]; - --m[1]; - --m[2]; - --m[3]; +mat4 __operator --(inout mat4 m) +{ + m[0] = m[0] - vec4(1.0); + m[1] = m[1] - vec4(1.0); + m[2] = m[2] - vec4(1.0); + m[3] = m[3] - vec4(1.0); + __retVal = m; } -void __operator ++ (inout float a) { - a += 1.0; + +//// pre-increment operators + +int __operator ++(inout int a) +{ + a = a + 1; + __retVal = a; } -void __operator ++ (inout int a) { - a += 1; +ivec2 __operator ++(inout ivec2 v) +{ + v = v + ivec2(1); + __retVal = v; } -void __operator ++ (inout vec2 v) { - ++v.x; - ++v.y; +ivec3 __operator ++(inout ivec3 v) +{ + v = v + ivec3(1); + __retVal = v; } -void __operator ++ (inout vec3 v) { - ++v.x; - ++v.y; - ++v.z; +ivec4 __operator ++(inout ivec4 v) +{ + v = v + ivec4(1); + __retVal = v; } -void __operator ++ (inout vec4 v) { - ++v.x; - ++v.y; - ++v.z; - ++v.w; + +float __operator ++(inout float a) +{ + a = a + 1.0; + __retVal = a; } -void __operator ++ (inout ivec2 v) { - ++v.x; - ++v.y; +vec2 __operator ++(inout vec2 v) +{ + v = v + vec2(1.0); + __retVal = v; } -void __operator ++ (inout ivec3 v) { - ++v.x; - ++v.y; - ++v.z; +vec3 __operator ++(inout vec3 v) +{ + v = v + vec3(1.0); + __retVal = v; } -void __operator ++ (inout ivec4 v) { - ++v.x; - ++v.y; - ++v.z; - ++v.w; +vec4 __operator ++(inout vec4 v) +{ + v = v + vec4(1.0); + __retVal = v; } -void __operator ++ (inout mat2 m) { - ++m[0]; - ++m[1]; + +mat2 __operator ++(inout mat2 m) +{ + m[0] = m[0] + vec2(1.0); + m[1] = m[1] + vec2(1.0); + __retVal = m; } -void __operator ++ (inout mat3 m) { - ++m[0]; - ++m[1]; - ++m[2]; +mat3 __operator ++(inout mat3 m) +{ + m[0] = m[0] + vec3(1.0); + m[1] = m[1] + vec3(1.0); + m[2] = m[2] + vec3(1.0); + __retVal = m; } -void __operator ++ (inout mat4 m) { - ++m[0]; - ++m[1]; - ++m[2]; - ++m[3]; +mat4 __operator ++(inout mat4 m) +{ + m[0] = m[0] + vec4(1.0); + m[1] = m[1] + vec4(1.0); + m[2] = m[2] + vec4(1.0); + m[3] = m[3] + vec4(1.0); + __retVal = m; } -// -// NOTE: postfix increment and decrement operators take additional dummy int parameter to -// distinguish their prototypes from prefix ones. -// -float __operator -- (inout float a, const int) { - float b = a; - --a; - return b; + +//// post-decrement + +int __postDecr(inout int a) +{ + __retVal = a; + a = a - 1; } -int __operator -- (inout int a, const int) { - int b = a; - --a; - return b; +ivec2 __postDecr(inout ivec2 v) +{ + __retVal = v; + v = v - ivec2(1); } -vec2 __operator -- (inout vec2 v, const int) { - return vec2 (v.x--, v.y--); +ivec3 __postDecr(inout ivec3 v) +{ + __retVal = v; + v = v - ivec3(1); } -vec3 __operator -- (inout vec3 v, const int) { - return vec3 (v.x--, v.y--, v.z--); +ivec4 __postDecr(inout ivec4 v) +{ + __retVal = v; + v = v - ivec4(1); } -vec4 __operator -- (inout vec4 v, const int) { - return vec4 (v.x--, v.y--, v.z--, v.w--); + +float __postDecr(inout float a) +{ + __retVal = a; + a = a - 1.0; } -ivec2 __operator -- (inout ivec2 v, const int) { - return ivec2 (v.x--, v.y--); +vec2 __postDecr(inout vec2 v) +{ + __retVal = v; + v = v - vec2(1.0); } -ivec3 __operator -- (inout ivec3 v, const int) { - return ivec3 (v.x--, v.y--, v.z--); +vec3 __postDecr(inout vec3 v) +{ + __retVal = v; + v = v - vec3(1.0); } -ivec4 __operator -- (inout ivec4 v, const int) { - return ivec4 (v.x--, v.y--, v.z--, v.w--); +vec4 __postDecr(inout vec4 v) +{ + __retVal = v; + v = v - vec4(1.0); } -mat2 __operator -- (inout mat2 m, const int) { - return mat2 (m[0]--, m[1]--); + +mat2 __postDecr(inout mat2 m) +{ + __retVal = m; + m[0] = m[0] - vec2(1.0); + m[1] = m[1] - vec2(1.0); } -mat3 __operator -- (inout mat3 m, const int) { - return mat3 (m[0]--, m[1]--, m[2]--); +mat3 __postDecr(inout mat3 m) +{ + __retVal = m; + m[0] = m[0] - vec3(1.0); + m[1] = m[1] - vec3(1.0); + m[2] = m[2] - vec3(1.0); } -mat4 __operator -- (inout mat4 m, const int) { - return mat4 (m[0]--, m[1]--, m[2]--, m[3]--); +mat4 __postDecr(inout mat4 m) +{ + __retVal = m; + m[0] = m[0] - vec4(1.0); + m[1] = m[1] - vec4(1.0); + m[2] = m[2] - vec4(1.0); + m[3] = m[3] - vec4(1.0); } -float __operator ++ (inout float a, const int) { - float b = a; - ++a; - return b; + +//// post-increment + +float __postIncr(inout float a) +{ + __retVal = a; + a = a + 1; } -int __operator ++ (inout int a, const int) { - int b = a; - ++a; - return b; +vec2 __postIncr(inout vec2 v) +{ + __retVal = v; + v = v + vec2(1.0); } -vec2 __operator ++ (inout vec2 v, const int) { - return vec2 (v.x++, v.y++); +vec3 __postIncr(inout vec3 v) +{ + __retVal = v; + v = v + vec3(1.0); } -vec3 __operator ++ (inout vec3 v, const int) { - return vec3 (v.x++, v.y++, v.z++); +vec4 __postIncr(inout vec4 v) +{ + __retVal = v; + v = v + vec4(1.0); } -vec4 __operator ++ (inout vec4 v, const int) { - return vec4 (v.x++, v.y++, v.z++, v.w++); + +int __postIncr(inout int a) +{ + __retVal = a; + a = a + 1; } -ivec2 __operator ++ (inout ivec2 v, const int) { - return ivec2 (v.x++, v.y++); +ivec2 __postIncr(inout ivec2 v) +{ + __retVal = v; + v = v + ivec2(1); } -ivec3 __operator ++ (inout ivec3 v, const int) { - return ivec3 (v.x++, v.y++, v.z++); +ivec3 __postIncr(inout ivec3 v) +{ + __retVal = v; + v = v + ivec3(1); } -ivec4 __operator ++ (inout ivec4 v, const int) { - return ivec4 (v.x++, v.y++, v.z++, v.w++); +ivec4 __postIncr(inout ivec4 v) +{ + __retVal = v; + v = v + ivec3(1); } -mat2 __operator ++ (inout mat2 m, const int) { - return mat2 (m[0]++, m[1]++); + +mat2 __postIncr(inout mat2 m) +{ + mat2 n = m; + m[0] = m[0] + vec2(1.0); + m[1] = m[1] + vec2(1.0); + return n; } -mat3 __operator ++ (inout mat3 m, const int) { - return mat3 (m[0]++, m[1]++, m[2]++); +mat3 __postIncr(inout mat3 m) +{ + mat3 n = m; + m[0] = m[0] + vec3(1.0); + m[1] = m[1] + vec3(1.0); + m[2] = m[2] + vec3(1.0); + return n; } -mat4 __operator ++ (inout mat4 m, const int) { - return mat4 (m[0]++, m[1]++, m[2]++, m[3]++); +mat4 __postIncr(inout mat4 m) +{ + mat4 n = m; + m[0] = m[0] + vec4(1.0); + m[1] = m[1] + vec4(1.0); + m[2] = m[2] + vec4(1.0); + m[3] = m[3] + vec4(1.0); + return n; } -bool __operator < (const float a, const float b) { - bool c; - __asm float_less c, a, b; - return c; + + +//// inequality operators + + +// XXX are the inequality operators for floats/ints really needed???? +bool __operator < (const float a, const float b) +{ + __asm vec4_sgt __retVal.x, b, a; } + bool __operator < (const int a, const int b) { return float (a) < float (b); } @@ -1546,25 +2513,25 @@ bool __operator <= (const int a, const int b) { return float (a) <= float (b); } -bool __operator ^^ (const bool a, const bool b) { - return a != b; -} -// -// These operators are handled internally by the compiler: -// -// bool __operator && (bool a, bool b) { -// return a ? b : false; -// } -// bool __operator || (bool a, bool b) { -// return a ? true : b; -// } -// -bool __operator ! (const bool a) { - return a == false; +bool __logicalNot(const bool a) +{ + if (a) + return false; + return true; +} + +bool __logicalXor(const bool a, const bool b) +{ + // XXX return a != b; + if (a) + return __logicalNot(b); + return b; } + + // // MESA-specific extension functions. // diff --git a/src/mesa/shader/slang/library/slang_core_gc.h b/src/mesa/shader/slang/library/slang_core_gc.h index a7aaa317fa..042566696b 100644 --- a/src/mesa/shader/slang/library/slang_core_gc.h +++ b/src/mesa/shader/slang/library/slang_core_gc.h @@ -2,544 +2,866 @@ /* DO NOT EDIT - THIS FILE IS AUTOMATICALLY GENERATED FROM THE FOLLOWING FILE: */ /* slang_core.gc */ -3,1,0,5,1,1,1,0,9,102,0,0,0,1,3,2,0,5,1,105,0,0,0,4,102,108,111,97,116,95,116,111,95,105,110,116,0, -18,105,0,0,18,102,0,0,0,8,18,105,0,0,0,1,0,1,1,1,1,0,5,105,0,0,0,1,8,18,105,0,16,8,48,0,39,0,0,1,0, -1,1,1,1,0,9,102,0,0,0,1,8,18,102,0,17,48,0,48,0,0,39,0,0,1,0,5,1,1,1,0,1,98,0,0,0,1,8,18,98,0,16, -10,49,0,16,8,48,0,31,0,0,1,0,9,1,1,1,0,1,98,0,0,0,1,8,18,98,0,17,49,0,48,0,0,17,48,0,48,0,0,31,0,0, -1,0,9,1,1,1,0,5,105,0,0,0,1,3,2,0,9,1,102,0,0,0,4,105,110,116,95,116,111,95,102,108,111,97,116,0, -18,102,0,0,18,105,0,0,0,8,18,102,0,0,0,1,0,1,1,1,1,0,1,98,0,0,0,1,8,18,98,0,0,0,1,0,5,1,1,1,0,5, -105,0,0,0,1,8,18,105,0,0,0,1,0,9,1,1,1,0,9,102,0,0,0,1,8,18,102,0,0,0,1,0,10,1,1,1,0,9,102,0,0,0,1, -8,58,118,101,99,50,0,18,102,0,0,18,102,0,0,0,0,0,1,0,10,1,1,1,0,5,105,0,0,0,1,3,2,0,9,1,120,0,0,0, -4,105,110,116,95,116,111,95,102,108,111,97,116,0,18,120,0,0,18,105,0,0,0,8,58,118,101,99,50,0,18, -120,0,0,0,0,0,1,0,10,1,1,1,0,1,98,0,0,0,1,8,58,118,101,99,50,0,18,98,0,17,49,0,48,0,0,17,48,0,48,0, -0,31,0,0,0,0,1,0,11,1,1,1,0,9,102,0,0,0,1,8,58,118,101,99,51,0,18,102,0,0,18,102,0,0,18,102,0,0,0, -0,0,1,0,11,1,1,1,0,5,105,0,0,0,1,3,2,0,9,1,120,0,0,0,4,105,110,116,95,116,111,95,102,108,111,97, -116,0,18,120,0,0,18,105,0,0,0,8,58,118,101,99,51,0,18,120,0,0,0,0,0,1,0,11,1,1,1,0,1,98,0,0,0,1,8, -58,118,101,99,51,0,18,98,0,17,49,0,48,0,0,17,48,0,48,0,0,31,0,0,0,0,1,0,12,1,1,1,0,9,102,0,0,0,1,8, -58,118,101,99,52,0,18,102,0,0,18,102,0,0,18,102,0,0,18,102,0,0,0,0,0,1,0,12,1,1,1,0,5,105,0,0,0,1, -3,2,0,9,1,120,0,0,0,4,105,110,116,95,116,111,95,102,108,111,97,116,0,18,120,0,0,18,105,0,0,0,8,58, -118,101,99,52,0,18,120,0,0,0,0,0,1,0,12,1,1,1,0,1,98,0,0,0,1,8,58,118,101,99,52,0,18,98,0,17,49,0, -48,0,0,17,48,0,48,0,0,31,0,0,0,0,1,0,6,1,1,1,0,5,105,0,0,0,1,8,58,105,118,101,99,50,0,18,105,0,0, -18,105,0,0,0,0,0,1,0,6,1,1,1,0,9,102,0,0,0,1,8,58,105,118,101,99,50,0,58,105,110,116,0,18,102,0,0, -0,0,0,0,0,1,0,6,1,1,1,0,1,98,0,0,0,1,8,58,105,118,101,99,50,0,58,105,110,116,0,18,98,0,0,0,0,0,0,0, -1,0,7,1,1,1,0,5,105,0,0,0,1,8,58,105,118,101,99,51,0,18,105,0,0,18,105,0,0,18,105,0,0,0,0,0,1,0,7, -1,1,1,0,9,102,0,0,0,1,8,58,105,118,101,99,51,0,58,105,110,116,0,18,102,0,0,0,0,0,0,0,1,0,7,1,1,1,0, -1,98,0,0,0,1,8,58,105,118,101,99,51,0,58,105,110,116,0,18,98,0,0,0,0,0,0,0,1,0,8,1,1,1,0,5,105,0,0, -0,1,8,58,105,118,101,99,52,0,18,105,0,0,18,105,0,0,18,105,0,0,18,105,0,0,0,0,0,1,0,8,1,1,1,0,9,102, -0,0,0,1,8,58,105,118,101,99,52,0,58,105,110,116,0,18,102,0,0,0,0,0,0,0,1,0,8,1,1,1,0,1,98,0,0,0,1, -8,58,105,118,101,99,52,0,58,105,110,116,0,18,98,0,0,0,0,0,0,0,1,0,2,1,1,1,0,1,98,0,0,0,1,8,58,98, -118,101,99,50,0,18,98,0,0,18,98,0,0,0,0,0,1,0,2,1,1,1,0,9,102,0,0,0,1,8,58,98,118,101,99,50,0,58, -98,111,111,108,0,18,102,0,0,0,0,0,0,0,1,0,2,1,1,1,0,5,105,0,0,0,1,8,58,98,118,101,99,50,0,58,98, -111,111,108,0,18,105,0,0,0,0,0,0,0,1,0,3,1,1,1,0,1,98,0,0,0,1,8,58,98,118,101,99,51,0,18,98,0,0,18, -98,0,0,18,98,0,0,0,0,0,1,0,3,1,1,1,0,9,102,0,0,0,1,8,58,98,118,101,99,51,0,58,98,111,111,108,0,18, -102,0,0,0,0,0,0,0,1,0,3,1,1,1,0,5,105,0,0,0,1,8,58,98,118,101,99,51,0,58,98,111,111,108,0,18,105,0, -0,0,0,0,0,0,1,0,4,1,1,1,0,1,98,0,0,0,1,8,58,98,118,101,99,52,0,18,98,0,0,18,98,0,0,18,98,0,0,18,98, -0,0,0,0,0,1,0,4,1,1,1,0,9,102,0,0,0,1,8,58,98,118,101,99,52,0,58,98,111,111,108,0,18,102,0,0,0,0,0, -0,0,1,0,4,1,1,1,0,5,105,0,0,0,1,8,58,98,118,101,99,52,0,58,98,111,111,108,0,18,105,0,0,0,0,0,0,0,1, -0,13,1,1,1,0,9,102,0,0,0,1,8,58,109,97,116,50,0,18,102,0,0,17,48,0,48,0,0,0,17,48,0,48,0,0,0,18, -102,0,0,0,0,0,1,0,13,1,1,1,0,5,105,0,0,0,1,3,2,0,9,1,120,0,0,0,4,105,110,116,95,116,111,95,102,108, -111,97,116,0,18,120,0,0,18,105,0,0,0,8,58,109,97,116,50,0,18,120,0,0,0,0,0,1,0,13,1,1,1,0,1,98,0,0, -0,1,8,58,109,97,116,50,0,18,98,0,17,49,0,48,0,0,17,48,0,48,0,0,31,0,0,0,0,1,0,14,1,1,1,0,9,102,0,0, -0,1,8,58,109,97,116,51,0,18,102,0,0,17,48,0,48,0,0,0,17,48,0,48,0,0,0,17,48,0,48,0,0,0,18,102,0,0, -17,48,0,48,0,0,0,17,48,0,48,0,0,0,17,48,0,48,0,0,0,18,102,0,0,0,0,0,1,0,14,1,1,1,0,5,105,0,0,0,1,3, -2,0,9,1,120,0,0,0,4,105,110,116,95,116,111,95,102,108,111,97,116,0,18,120,0,0,18,105,0,0,0,8,58, -109,97,116,51,0,18,120,0,0,0,0,0,1,0,14,1,1,1,0,1,98,0,0,0,1,8,58,109,97,116,51,0,18,98,0,17,49,0, -48,0,0,17,48,0,48,0,0,31,0,0,0,0,1,0,15,1,1,1,0,9,102,0,0,0,1,8,58,109,97,116,52,0,18,102,0,0,17, -48,0,48,0,0,0,17,48,0,48,0,0,0,17,48,0,48,0,0,0,17,48,0,48,0,0,0,18,102,0,0,17,48,0,48,0,0,0,17,48, -0,48,0,0,0,17,48,0,48,0,0,0,17,48,0,48,0,0,0,18,102,0,0,17,48,0,48,0,0,0,17,48,0,48,0,0,0,17,48,0, -48,0,0,0,17,48,0,48,0,0,0,18,102,0,0,0,0,0,1,0,15,1,1,1,0,5,105,0,0,0,1,3,2,0,9,1,120,0,0,0,4,105, -110,116,95,116,111,95,102,108,111,97,116,0,18,120,0,0,18,105,0,0,0,8,58,109,97,116,52,0,18,120,0,0, -0,0,0,1,0,15,1,1,1,0,1,98,0,0,0,1,8,58,109,97,116,52,0,18,98,0,17,49,0,48,0,0,17,48,0,48,0,0,31,0, -0,0,0,1,0,0,2,1,1,0,2,9,97,0,0,1,1,0,9,98,0,0,0,1,4,102,108,111,97,116,95,97,100,100,0,18,97,0,0, -18,97,0,0,18,98,0,0,0,0,1,0,9,2,27,1,1,0,9,97,0,0,0,1,3,2,0,9,1,98,0,0,0,4,102,108,111,97,116,95, -110,101,103,97,116,101,0,18,98,0,0,18,97,0,0,0,8,18,98,0,0,0,1,0,0,2,2,1,0,2,9,97,0,0,1,1,0,9,98,0, -0,0,1,3,2,0,9,1,99,0,0,0,4,102,108,111,97,116,95,110,101,103,97,116,101,0,18,99,0,0,18,98,0,0,0,4, -102,108,111,97,116,95,97,100,100,0,18,97,0,0,18,97,0,0,18,99,0,0,0,0,1,0,0,2,3,1,0,2,9,97,0,0,1,1, -0,9,98,0,0,0,1,4,102,108,111,97,116,95,109,117,108,116,105,112,108,121,0,18,97,0,0,18,97,0,0,18,98, -0,0,0,0,1,0,0,2,4,1,0,2,9,97,0,0,1,1,0,9,98,0,0,0,1,4,102,108,111,97,116,95,100,105,118,105,100, -101,0,18,97,0,0,18,97,0,0,18,98,0,0,0,0,1,0,9,2,26,1,1,0,9,97,0,0,1,1,0,9,98,0,0,0,1,3,2,0,9,1,99, -0,0,0,4,102,108,111,97,116,95,97,100,100,0,18,99,0,0,18,97,0,0,18,98,0,0,0,8,18,99,0,0,0,1,0,0,2,1, -1,0,2,5,97,0,0,1,1,0,5,98,0,0,0,1,9,18,97,0,58,105,110,116,0,58,102,108,111,97,116,0,18,97,0,0,0, -58,102,108,111,97,116,0,18,98,0,0,0,46,0,0,20,0,0,1,0,5,2,27,1,1,0,5,97,0,0,0,1,3,2,0,9,1,120,0,0, -0,3,2,0,5,1,98,0,0,0,4,105,110,116,95,116,111,95,102,108,111,97,116,0,18,120,0,0,18,97,0,0,0,4,102, -108,111,97,116,95,110,101,103,97,116,101,0,18,120,0,0,18,120,0,0,0,4,102,108,111,97,116,95,116,111, -95,105,110,116,0,18,98,0,0,18,120,0,0,0,8,18,98,0,0,0,1,0,0,2,2,1,0,2,5,97,0,0,1,1,0,5,98,0,0,0,1, -9,18,97,0,18,98,0,54,21,0,0,1,0,9,2,21,1,1,0,9,97,0,0,1,1,0,9,98,0,0,0,1,3,2,0,9,1,99,0,0,0,4,102, -108,111,97,116,95,109,117,108,116,105,112,108,121,0,18,99,0,0,18,97,0,0,18,98,0,0,0,8,18,99,0,0,0, -1,0,0,2,3,1,0,2,5,97,0,0,1,1,0,5,98,0,0,0,1,9,18,97,0,58,105,110,116,0,58,102,108,111,97,116,0,18, -97,0,0,0,58,102,108,111,97,116,0,18,98,0,0,0,48,0,0,20,0,0,1,0,9,2,22,1,1,0,9,97,0,0,1,1,0,9,98,0, -0,0,1,3,2,0,9,1,99,0,0,0,4,102,108,111,97,116,95,100,105,118,105,100,101,0,18,99,0,0,18,97,0,0,18, -98,0,0,0,8,18,99,0,0,0,1,0,0,2,4,1,0,2,5,97,0,0,1,1,0,5,98,0,0,0,1,9,18,97,0,58,105,110,116,0,58, -102,108,111,97,116,0,18,97,0,0,0,58,102,108,111,97,116,0,18,98,0,0,0,49,0,0,20,0,0,1,0,0,2,1,1,0,2, -10,118,0,0,1,1,0,10,117,0,0,0,1,9,18,118,0,59,120,0,18,117,0,59,120,0,21,0,9,18,118,0,59,121,0,18, -117,0,59,121,0,21,0,0,1,0,0,2,2,1,0,2,10,118,0,0,1,1,0,10,117,0,0,0,1,9,18,118,0,59,120,0,18,117,0, -59,120,0,22,0,9,18,118,0,59,121,0,18,117,0,59,121,0,22,0,0,1,0,0,2,3,1,0,2,10,118,0,0,1,1,0,10,117, -0,0,0,1,9,18,118,0,59,120,0,18,117,0,59,120,0,23,0,9,18,118,0,59,121,0,18,117,0,59,121,0,23,0,0,1, -0,0,2,4,1,0,2,10,118,0,0,1,1,0,10,117,0,0,0,1,9,18,118,0,59,120,0,18,117,0,59,120,0,24,0,9,18,118, -0,59,121,0,18,117,0,59,121,0,24,0,0,1,0,0,2,1,1,0,2,11,118,0,0,1,1,0,11,117,0,0,0,1,9,18,118,0,59, -120,0,18,117,0,59,120,0,21,0,9,18,118,0,59,121,0,18,117,0,59,121,0,21,0,9,18,118,0,59,122,0,18,117, -0,59,122,0,21,0,0,1,0,0,2,2,1,0,2,11,118,0,0,1,1,0,11,117,0,0,0,1,9,18,118,0,59,120,0,18,117,0,59, -120,0,22,0,9,18,118,0,59,121,0,18,117,0,59,121,0,22,0,9,18,118,0,59,122,0,18,117,0,59,122,0,22,0,0, -1,0,0,2,3,1,0,2,11,118,0,0,1,1,0,11,117,0,0,0,1,9,18,118,0,59,120,0,18,117,0,59,120,0,23,0,9,18, -118,0,59,121,0,18,117,0,59,121,0,23,0,9,18,118,0,59,122,0,18,117,0,59,122,0,23,0,0,1,0,0,2,4,1,0,2, -11,118,0,0,1,1,0,11,117,0,0,0,1,9,18,118,0,59,120,0,18,117,0,59,120,0,24,0,9,18,118,0,59,121,0,18, -117,0,59,121,0,24,0,9,18,118,0,59,122,0,18,117,0,59,122,0,24,0,0,1,0,0,2,1,1,0,2,12,118,0,0,1,1,0, -12,117,0,0,0,1,9,18,118,0,59,120,0,18,117,0,59,120,0,21,0,9,18,118,0,59,121,0,18,117,0,59,121,0,21, -0,9,18,118,0,59,122,0,18,117,0,59,122,0,21,0,9,18,118,0,59,119,0,18,117,0,59,119,0,21,0,0,1,0,0,2, -2,1,0,2,12,118,0,0,1,1,0,12,117,0,0,0,1,9,18,118,0,59,120,0,18,117,0,59,120,0,22,0,9,18,118,0,59, -121,0,18,117,0,59,121,0,22,0,9,18,118,0,59,122,0,18,117,0,59,122,0,22,0,9,18,118,0,59,119,0,18,117, -0,59,119,0,22,0,0,1,0,0,2,3,1,0,2,12,118,0,0,1,1,0,12,117,0,0,0,1,9,18,118,0,59,120,0,18,117,0,59, -120,0,23,0,9,18,118,0,59,121,0,18,117,0,59,121,0,23,0,9,18,118,0,59,122,0,18,117,0,59,122,0,23,0,9, -18,118,0,59,119,0,18,117,0,59,119,0,23,0,0,1,0,0,2,4,1,0,2,12,118,0,0,1,1,0,12,117,0,0,0,1,9,18, -118,0,59,120,0,18,117,0,59,120,0,24,0,9,18,118,0,59,121,0,18,117,0,59,121,0,24,0,9,18,118,0,59,122, -0,18,117,0,59,122,0,24,0,9,18,118,0,59,119,0,18,117,0,59,119,0,24,0,0,1,0,0,2,1,1,0,2,6,118,0,0,1, -1,0,6,117,0,0,0,1,9,18,118,0,59,120,0,18,117,0,59,120,0,21,0,9,18,118,0,59,121,0,18,117,0,59,121,0, -21,0,0,1,0,0,2,2,1,0,2,6,118,0,0,1,1,0,6,117,0,0,0,1,9,18,118,0,59,120,0,18,117,0,59,120,0,22,0,9, -18,118,0,59,121,0,18,117,0,59,121,0,22,0,0,1,0,0,2,3,1,0,2,6,118,0,0,1,1,0,6,117,0,0,0,1,9,18,118, -0,59,120,0,18,117,0,59,120,0,23,0,9,18,118,0,59,121,0,18,117,0,59,121,0,23,0,0,1,0,0,2,4,1,0,2,6, -118,0,0,1,1,0,6,117,0,0,0,1,9,18,118,0,59,120,0,18,117,0,59,120,0,24,0,9,18,118,0,59,121,0,18,117, -0,59,121,0,24,0,0,1,0,0,2,1,1,0,2,7,118,0,0,1,1,0,7,117,0,0,0,1,9,18,118,0,59,120,0,18,117,0,59, -120,0,21,0,9,18,118,0,59,121,0,18,117,0,59,121,0,21,0,9,18,118,0,59,122,0,18,117,0,59,122,0,21,0,0, -1,0,0,2,2,1,0,2,7,118,0,0,1,1,0,7,117,0,0,0,1,9,18,118,0,59,120,0,18,117,0,59,120,0,22,0,9,18,118, -0,59,121,0,18,117,0,59,121,0,22,0,9,18,118,0,59,122,0,18,117,0,59,122,0,22,0,0,1,0,0,2,3,1,0,2,7, -118,0,0,1,1,0,7,117,0,0,0,1,9,18,118,0,59,120,0,18,117,0,59,120,0,23,0,9,18,118,0,59,121,0,18,117, -0,59,121,0,23,0,9,18,118,0,59,122,0,18,117,0,59,122,0,23,0,0,1,0,0,2,4,1,0,2,7,118,0,0,1,1,0,7,117, -0,0,0,1,9,18,118,0,59,120,0,18,117,0,59,120,0,24,0,9,18,118,0,59,121,0,18,117,0,59,121,0,24,0,9,18, -118,0,59,122,0,18,117,0,59,122,0,24,0,0,1,0,0,2,1,1,0,2,8,118,0,0,1,1,0,8,117,0,0,0,1,9,18,118,0, -59,120,0,18,117,0,59,120,0,21,0,9,18,118,0,59,121,0,18,117,0,59,121,0,21,0,9,18,118,0,59,122,0,18, -117,0,59,122,0,21,0,9,18,118,0,59,119,0,18,117,0,59,119,0,21,0,0,1,0,0,2,2,1,0,2,8,118,0,0,1,1,0,8, -117,0,0,0,1,9,18,118,0,59,120,0,18,117,0,59,120,0,22,0,9,18,118,0,59,121,0,18,117,0,59,121,0,22,0, -9,18,118,0,59,122,0,18,117,0,59,122,0,22,0,9,18,118,0,59,119,0,18,117,0,59,119,0,22,0,0,1,0,0,2,3, -1,0,2,8,118,0,0,1,1,0,8,117,0,0,0,1,9,18,118,0,59,120,0,18,117,0,59,120,0,23,0,9,18,118,0,59,121,0, -18,117,0,59,121,0,23,0,9,18,118,0,59,122,0,18,117,0,59,122,0,23,0,9,18,118,0,59,119,0,18,117,0,59, -119,0,23,0,0,1,0,0,2,4,1,0,2,8,118,0,0,1,1,0,8,117,0,0,0,1,9,18,118,0,59,120,0,18,117,0,59,120,0, -24,0,9,18,118,0,59,121,0,18,117,0,59,121,0,24,0,9,18,118,0,59,122,0,18,117,0,59,122,0,24,0,9,18, -118,0,59,119,0,18,117,0,59,119,0,24,0,0,1,0,0,2,1,1,0,2,13,109,0,0,1,1,0,13,110,0,0,0,1,9,18,109,0, -16,8,48,0,57,18,110,0,16,8,48,0,57,21,0,9,18,109,0,16,10,49,0,57,18,110,0,16,10,49,0,57,21,0,0,1,0, -0,2,2,1,0,2,13,109,0,0,1,1,0,13,110,0,0,0,1,9,18,109,0,16,8,48,0,57,18,110,0,16,8,48,0,57,22,0,9, -18,109,0,16,10,49,0,57,18,110,0,16,10,49,0,57,22,0,0,1,0,10,2,21,1,1,0,13,109,0,0,1,1,0,10,118,0,0, -0,1,8,58,118,101,99,50,0,18,118,0,59,120,0,18,109,0,16,8,48,0,57,59,120,0,48,18,118,0,59,121,0,18, -109,0,16,10,49,0,57,59,120,0,48,46,0,18,118,0,59,120,0,18,109,0,16,8,48,0,57,59,121,0,48,18,118,0, -59,121,0,18,109,0,16,10,49,0,57,59,121,0,48,46,0,0,0,0,1,0,13,2,21,1,1,0,13,109,0,0,1,1,0,13,110,0, -0,0,1,8,58,109,97,116,50,0,18,109,0,18,110,0,16,8,48,0,57,48,0,18,109,0,18,110,0,16,10,49,0,57,48, -0,0,0,0,1,0,0,2,3,1,0,2,13,109,0,0,1,1,0,13,110,0,0,0,1,9,18,109,0,18,109,0,18,110,0,48,20,0,0,1,0, -0,2,4,1,0,2,13,109,0,0,1,1,0,13,110,0,0,0,1,9,18,109,0,16,8,48,0,57,18,110,0,16,8,48,0,57,24,0,9, -18,109,0,16,10,49,0,57,18,110,0,16,10,49,0,57,24,0,0,1,0,0,2,1,1,0,2,14,109,0,0,1,1,0,14,110,0,0,0, -1,9,18,109,0,16,8,48,0,57,18,110,0,16,8,48,0,57,21,0,9,18,109,0,16,10,49,0,57,18,110,0,16,10,49,0, -57,21,0,9,18,109,0,16,10,50,0,57,18,110,0,16,10,50,0,57,21,0,0,1,0,0,2,2,1,0,2,14,109,0,0,1,1,0,14, -110,0,0,0,1,9,18,109,0,16,8,48,0,57,18,110,0,16,8,48,0,57,22,0,9,18,109,0,16,10,49,0,57,18,110,0, -16,10,49,0,57,22,0,9,18,109,0,16,10,50,0,57,18,110,0,16,10,50,0,57,22,0,0,1,0,11,2,21,1,1,0,14,109, -0,0,1,1,0,11,118,0,0,0,1,8,58,118,101,99,51,0,18,118,0,59,120,0,18,109,0,16,8,48,0,57,59,120,0,48, -18,118,0,59,121,0,18,109,0,16,10,49,0,57,59,120,0,48,46,18,118,0,59,122,0,18,109,0,16,10,50,0,57, -59,120,0,48,46,0,18,118,0,59,120,0,18,109,0,16,8,48,0,57,59,121,0,48,18,118,0,59,121,0,18,109,0,16, -10,49,0,57,59,121,0,48,46,18,118,0,59,122,0,18,109,0,16,10,50,0,57,59,121,0,48,46,0,18,118,0,59, -120,0,18,109,0,16,8,48,0,57,59,122,0,48,18,118,0,59,121,0,18,109,0,16,10,49,0,57,59,122,0,48,46,18, -118,0,59,122,0,18,109,0,16,10,50,0,57,59,122,0,48,46,0,0,0,0,1,0,14,2,21,1,1,0,14,109,0,0,1,1,0,14, -110,0,0,0,1,8,58,109,97,116,51,0,18,109,0,18,110,0,16,8,48,0,57,48,0,18,109,0,18,110,0,16,10,49,0, -57,48,0,18,109,0,18,110,0,16,10,50,0,57,48,0,0,0,0,1,0,0,2,3,1,0,2,14,109,0,0,1,1,0,14,110,0,0,0,1, -9,18,109,0,18,109,0,18,110,0,48,20,0,0,1,0,0,2,4,1,0,2,14,109,0,0,1,1,0,14,110,0,0,0,1,9,18,109,0, -16,8,48,0,57,18,110,0,16,8,48,0,57,24,0,9,18,109,0,16,10,49,0,57,18,110,0,16,10,49,0,57,24,0,9,18, -109,0,16,10,50,0,57,18,110,0,16,10,50,0,57,24,0,0,1,0,0,2,1,1,0,2,15,109,0,0,1,1,0,15,110,0,0,0,1, -9,18,109,0,16,8,48,0,57,18,110,0,16,8,48,0,57,21,0,9,18,109,0,16,10,49,0,57,18,110,0,16,10,49,0,57, -21,0,9,18,109,0,16,10,50,0,57,18,110,0,16,10,50,0,57,21,0,9,18,109,0,16,10,51,0,57,18,110,0,16,10, -51,0,57,21,0,0,1,0,0,2,2,1,0,2,15,109,0,0,1,1,0,15,110,0,0,0,1,9,18,109,0,16,8,48,0,57,18,110,0,16, -8,48,0,57,22,0,9,18,109,0,16,10,49,0,57,18,110,0,16,10,49,0,57,22,0,9,18,109,0,16,10,50,0,57,18, -110,0,16,10,50,0,57,22,0,9,18,109,0,16,10,51,0,57,18,110,0,16,10,51,0,57,22,0,0,1,0,12,2,21,1,1,0, -15,109,0,0,1,1,0,12,118,0,0,0,1,8,58,118,101,99,52,0,18,118,0,59,120,0,18,109,0,16,8,48,0,57,59, -120,0,48,18,118,0,59,121,0,18,109,0,16,10,49,0,57,59,120,0,48,46,18,118,0,59,122,0,18,109,0,16,10, -50,0,57,59,120,0,48,46,18,118,0,59,119,0,18,109,0,16,10,51,0,57,59,120,0,48,46,0,18,118,0,59,120,0, -18,109,0,16,8,48,0,57,59,121,0,48,18,118,0,59,121,0,18,109,0,16,10,49,0,57,59,121,0,48,46,18,118,0, -59,122,0,18,109,0,16,10,50,0,57,59,121,0,48,46,18,118,0,59,119,0,18,109,0,16,10,51,0,57,59,121,0, -48,46,0,18,118,0,59,120,0,18,109,0,16,8,48,0,57,59,122,0,48,18,118,0,59,121,0,18,109,0,16,10,49,0, -57,59,122,0,48,46,18,118,0,59,122,0,18,109,0,16,10,50,0,57,59,122,0,48,46,18,118,0,59,119,0,18,109, -0,16,10,51,0,57,59,122,0,48,46,0,18,118,0,59,120,0,18,109,0,16,8,48,0,57,59,119,0,48,18,118,0,59, -121,0,18,109,0,16,10,49,0,57,59,119,0,48,46,18,118,0,59,122,0,18,109,0,16,10,50,0,57,59,119,0,48, -46,18,118,0,59,119,0,18,109,0,16,10,51,0,57,59,119,0,48,46,0,0,0,0,1,0,15,2,21,1,1,0,15,109,0,0,1, -1,0,15,110,0,0,0,1,8,58,109,97,116,52,0,18,109,0,18,110,0,16,8,48,0,57,48,0,18,109,0,18,110,0,16, -10,49,0,57,48,0,18,109,0,18,110,0,16,10,50,0,57,48,0,18,109,0,18,110,0,16,10,51,0,57,48,0,0,0,0,1, -0,0,2,3,1,0,2,15,109,0,0,1,1,0,15,110,0,0,0,1,9,18,109,0,18,109,0,18,110,0,48,20,0,0,1,0,0,2,4,1,0, -2,15,109,0,0,1,1,0,15,110,0,0,0,1,9,18,109,0,16,8,48,0,57,18,110,0,16,8,48,0,57,24,0,9,18,109,0,16, -10,49,0,57,18,110,0,16,10,49,0,57,24,0,9,18,109,0,16,10,50,0,57,18,110,0,16,10,50,0,57,24,0,9,18, -109,0,16,10,51,0,57,18,110,0,16,10,51,0,57,24,0,0,1,0,0,2,1,1,0,2,10,118,0,0,1,1,0,9,97,0,0,0,1,9, -18,118,0,59,120,0,18,97,0,21,0,9,18,118,0,59,121,0,18,97,0,21,0,0,1,0,0,2,2,1,0,2,10,118,0,0,1,1,0, -9,97,0,0,0,1,9,18,118,0,59,120,0,18,97,0,22,0,9,18,118,0,59,121,0,18,97,0,22,0,0,1,0,0,2,3,1,0,2, -10,118,0,0,1,1,0,9,97,0,0,0,1,9,18,118,0,59,120,0,18,97,0,23,0,9,18,118,0,59,121,0,18,97,0,23,0,0, -1,0,0,2,4,1,0,2,10,118,0,0,1,1,0,9,97,0,0,0,1,9,18,118,0,59,120,0,18,97,0,24,0,9,18,118,0,59,121,0, -18,97,0,24,0,0,1,0,0,2,1,1,0,2,11,118,0,0,1,1,0,9,97,0,0,0,1,9,18,118,0,59,120,0,18,97,0,21,0,9,18, -118,0,59,121,0,18,97,0,21,0,9,18,118,0,59,122,0,18,97,0,21,0,0,1,0,0,2,2,1,0,2,11,118,0,0,1,1,0,9, -97,0,0,0,1,9,18,118,0,59,120,0,18,97,0,22,0,9,18,118,0,59,121,0,18,97,0,22,0,9,18,118,0,59,122,0, -18,97,0,22,0,0,1,0,0,2,3,1,0,2,11,118,0,0,1,1,0,9,97,0,0,0,1,9,18,118,0,59,120,0,18,97,0,23,0,9,18, -118,0,59,121,0,18,97,0,23,0,9,18,118,0,59,122,0,18,97,0,23,0,0,1,0,0,2,4,1,0,2,11,118,0,0,1,1,0,9, -97,0,0,0,1,9,18,118,0,59,120,0,18,97,0,24,0,9,18,118,0,59,121,0,18,97,0,24,0,9,18,118,0,59,122,0, -18,97,0,24,0,0,1,0,0,2,1,1,0,2,12,118,0,0,1,1,0,9,97,0,0,0,1,9,18,118,0,59,120,0,18,97,0,21,0,9,18, -118,0,59,121,0,18,97,0,21,0,9,18,118,0,59,122,0,18,97,0,21,0,9,18,118,0,59,119,0,18,97,0,21,0,0,1, -0,0,2,2,1,0,2,12,118,0,0,1,1,0,9,97,0,0,0,1,9,18,118,0,59,120,0,18,97,0,22,0,9,18,118,0,59,121,0, -18,97,0,22,0,9,18,118,0,59,122,0,18,97,0,22,0,9,18,118,0,59,119,0,18,97,0,22,0,0,1,0,0,2,3,1,0,2, -12,118,0,0,1,1,0,9,97,0,0,0,1,9,18,118,0,59,120,0,18,97,0,23,0,9,18,118,0,59,121,0,18,97,0,23,0,9, -18,118,0,59,122,0,18,97,0,23,0,9,18,118,0,59,119,0,18,97,0,23,0,0,1,0,0,2,4,1,0,2,12,118,0,0,1,1,0, -9,97,0,0,0,1,9,18,118,0,59,120,0,18,97,0,24,0,9,18,118,0,59,121,0,18,97,0,24,0,9,18,118,0,59,122,0, -18,97,0,24,0,9,18,118,0,59,119,0,18,97,0,24,0,0,1,0,0,2,1,1,0,2,13,109,0,0,1,1,0,9,97,0,0,0,1,9,18, -109,0,16,8,48,0,57,18,97,0,21,0,9,18,109,0,16,10,49,0,57,18,97,0,21,0,0,1,0,0,2,2,1,0,2,13,109,0,0, -1,1,0,9,97,0,0,0,1,9,18,109,0,16,8,48,0,57,18,97,0,22,0,9,18,109,0,16,10,49,0,57,18,97,0,22,0,0,1, -0,0,2,3,1,0,2,13,109,0,0,1,1,0,9,97,0,0,0,1,9,18,109,0,16,8,48,0,57,18,97,0,23,0,9,18,109,0,16,10, -49,0,57,18,97,0,23,0,0,1,0,0,2,4,1,0,2,13,109,0,0,1,1,0,9,97,0,0,0,1,9,18,109,0,16,8,48,0,57,18,97, -0,24,0,9,18,109,0,16,10,49,0,57,18,97,0,24,0,0,1,0,0,2,1,1,0,2,14,109,0,0,1,1,0,9,97,0,0,0,1,9,18, -109,0,16,8,48,0,57,18,97,0,21,0,9,18,109,0,16,10,49,0,57,18,97,0,21,0,9,18,109,0,16,10,50,0,57,18, -97,0,21,0,0,1,0,0,2,2,1,0,2,14,109,0,0,1,1,0,9,97,0,0,0,1,9,18,109,0,16,8,48,0,57,18,97,0,22,0,9, -18,109,0,16,10,49,0,57,18,97,0,22,0,9,18,109,0,16,10,50,0,57,18,97,0,22,0,0,1,0,0,2,3,1,0,2,14,109, +3,1,0,5,1,1,1,0,9,102,0,0,0,1,4,102,108,111,97,116,95,116,111,95,105,110,116,0,18,95,95,114,101, +116,86,97,108,0,0,18,102,0,0,0,0,1,0,1,1,1,1,0,5,105,0,0,0,1,3,2,1,9,1,122,101,114,111,0,2,17,48,0, +48,0,0,0,0,4,118,101,99,52,95,115,101,113,0,18,95,95,114,101,116,86,97,108,0,0,18,105,0,0,18,122, +101,114,111,0,0,0,0,1,0,1,1,1,1,0,9,102,0,0,0,1,3,2,1,9,1,122,101,114,111,0,2,17,48,0,48,0,0,0,0,4, +118,101,99,52,95,115,101,113,0,18,95,95,114,101,116,86,97,108,0,0,18,105,0,0,18,122,101,114,111,0, +0,0,0,1,0,5,1,1,1,0,1,98,0,0,0,1,9,18,95,95,114,101,116,86,97,108,0,18,98,0,20,0,0,1,0,9,1,1,1,0,1, +98,0,0,0,1,9,18,95,95,114,101,116,86,97,108,0,18,98,0,20,0,0,1,0,9,1,1,1,0,5,105,0,0,0,1,4,105,110, +116,95,116,111,95,102,108,111,97,116,0,18,95,95,114,101,116,86,97,108,0,0,18,105,0,0,0,0,1,0,1,1,1, +1,0,1,98,0,0,0,1,9,18,95,95,114,101,116,86,97,108,0,18,98,0,20,0,0,1,0,5,1,1,1,0,5,105,0,0,0,1,9, +18,95,95,114,101,116,86,97,108,0,18,105,0,20,0,0,1,0,9,1,1,1,0,9,102,0,0,0,1,9,18,95,95,114,101, +116,86,97,108,0,18,102,0,20,0,0,1,0,10,1,1,1,0,9,120,0,0,1,1,0,9,121,0,0,0,1,9,18,95,95,114,101, +116,86,97,108,0,59,120,0,18,120,0,20,0,9,18,95,95,114,101,116,86,97,108,0,59,121,0,18,121,0,20,0,0, +1,0,10,1,1,1,0,9,102,0,0,0,1,9,18,95,95,114,101,116,86,97,108,0,59,120,121,0,18,102,0,59,120,120,0, +20,0,0,1,0,10,1,1,1,0,5,105,0,0,0,1,9,18,95,95,114,101,116,86,97,108,0,59,120,121,0,18,105,0,59, +120,120,0,20,0,0,1,0,10,1,1,1,0,1,98,0,0,0,1,9,18,95,95,114,101,116,86,97,108,0,59,120,121,0,18,98, +0,59,120,120,0,20,0,0,1,0,10,1,1,1,0,11,118,0,0,0,1,9,18,95,95,114,101,116,86,97,108,0,59,120,121, +0,18,118,0,59,120,121,0,20,0,0,1,0,11,1,1,1,0,9,120,0,0,1,1,0,9,121,0,0,1,1,0,9,122,0,0,0,1,9,18, +95,95,114,101,116,86,97,108,0,59,120,0,18,120,0,20,0,9,18,95,95,114,101,116,86,97,108,0,59,121,0, +18,121,0,20,0,9,18,95,95,114,101,116,86,97,108,0,59,122,0,18,122,0,20,0,0,1,0,11,1,1,1,0,9,102,0,0, +0,1,9,18,95,95,114,101,116,86,97,108,0,59,120,121,122,0,18,102,0,59,120,120,120,0,20,0,0,1,0,11,1, +1,1,0,5,105,0,0,0,1,4,105,110,116,95,116,111,95,102,108,111,97,116,0,18,95,95,114,101,116,86,97, +108,0,59,120,121,122,0,0,18,105,0,59,120,120,120,0,0,0,0,1,0,11,1,1,1,0,1,98,0,0,0,1,9,18,95,95, +114,101,116,86,97,108,0,59,120,121,122,0,18,98,0,59,120,120,120,0,20,0,0,1,0,11,1,1,1,0,12,118,0,0, +0,1,9,18,95,95,114,101,116,86,97,108,0,59,120,121,122,0,18,118,0,59,120,121,122,0,20,0,0,1,0,12,1, +1,1,0,9,120,0,0,1,1,0,9,121,0,0,1,1,0,9,122,0,0,1,1,0,9,119,0,0,0,1,9,18,95,95,114,101,116,86,97, +108,0,59,120,0,18,120,0,20,0,9,18,95,95,114,101,116,86,97,108,0,59,121,0,18,121,0,20,0,9,18,95,95, +114,101,116,86,97,108,0,59,122,0,18,122,0,20,0,9,18,95,95,114,101,116,86,97,108,0,59,119,0,18,119, +0,20,0,0,1,0,12,1,1,1,0,9,102,0,0,0,1,9,18,95,95,114,101,116,86,97,108,0,18,102,0,59,120,120,120, +120,0,20,0,0,1,0,12,1,1,1,0,5,105,0,0,0,1,9,18,95,95,114,101,116,86,97,108,0,18,105,0,59,120,120, +120,120,0,20,0,0,1,0,12,1,1,1,0,1,98,0,0,0,1,9,18,95,95,114,101,116,86,97,108,0,18,98,0,59,120,120, +120,120,0,20,0,0,1,0,12,1,1,1,0,11,118,51,0,0,1,1,0,9,102,0,0,0,1,9,18,95,95,114,101,116,86,97,108, +0,59,120,121,122,0,18,118,51,0,20,0,9,18,95,95,114,101,116,86,97,108,0,59,119,0,18,102,0,20,0,0,1, +0,6,1,1,1,0,5,105,0,0,1,1,0,5,106,0,0,0,1,9,18,95,95,114,101,116,86,97,108,0,59,120,0,18,105,0,20, +0,9,18,95,95,114,101,116,86,97,108,0,59,121,0,18,106,0,20,0,0,1,0,6,1,1,1,0,5,105,0,0,0,1,9,18,95, +95,114,101,116,86,97,108,0,59,120,121,0,18,105,0,59,120,120,0,20,0,0,1,0,6,1,1,1,0,9,102,0,0,0,1,4, +102,108,111,97,116,95,116,111,95,105,110,116,0,18,95,95,114,101,116,86,97,108,0,59,120,121,0,0,18, +102,0,59,120,120,0,0,0,0,1,0,6,1,1,1,0,1,98,0,0,0,1,4,102,108,111,97,116,95,116,111,95,105,110,116, +0,18,95,95,114,101,116,86,97,108,0,59,120,121,0,0,18,98,0,59,120,120,0,0,0,0,1,0,7,1,1,1,0,5,105,0, +0,1,1,0,5,106,0,0,1,1,0,5,107,0,0,0,1,9,18,95,95,114,101,116,86,97,108,0,59,120,0,18,105,0,20,0,9, +18,95,95,114,101,116,86,97,108,0,59,121,0,18,106,0,20,0,9,18,95,95,114,101,116,86,97,108,0,59,122, +0,18,107,0,20,0,0,1,0,7,1,1,1,0,5,105,0,0,0,1,9,18,95,95,114,101,116,86,97,108,0,59,120,121,122,0, +18,105,0,59,120,120,120,0,20,0,0,1,0,7,1,1,1,0,9,102,0,0,0,1,9,18,95,95,114,101,116,86,97,108,0,59, +120,121,122,0,18,102,0,59,120,120,120,0,20,0,0,1,0,7,1,1,1,0,1,98,0,0,0,1,9,18,95,95,114,101,116, +86,97,108,0,59,120,121,122,0,18,98,0,59,120,120,120,0,20,0,0,1,0,8,1,1,1,0,5,120,0,0,1,1,0,5,121,0, +0,1,1,0,5,122,0,0,1,1,0,5,119,0,0,0,1,9,18,95,95,114,101,116,86,97,108,0,59,120,0,18,120,0,20,0,9, +18,95,95,114,101,116,86,97,108,0,59,121,0,18,121,0,20,0,9,18,95,95,114,101,116,86,97,108,0,59,122, +0,18,122,0,20,0,9,18,95,95,114,101,116,86,97,108,0,59,119,0,18,119,0,20,0,0,1,0,8,1,1,1,0,5,105,0, +0,0,1,9,18,95,95,114,101,116,86,97,108,0,18,105,0,59,120,120,120,120,0,20,0,0,1,0,8,1,1,1,0,9,102, +0,0,0,1,4,102,108,111,97,116,95,116,111,95,105,110,116,0,18,95,95,114,101,116,86,97,108,0,0,18,102, +0,59,120,120,120,120,0,0,0,0,1,0,8,1,1,1,0,1,98,0,0,0,1,9,18,95,95,114,101,116,86,97,108,0,18,98,0, +59,120,120,120,120,0,20,0,0,1,0,2,1,1,1,0,1,98,49,0,0,1,1,0,1,98,50,0,0,0,1,9,18,95,95,114,101,116, +86,97,108,0,59,120,0,18,98,49,0,20,0,9,18,95,95,114,101,116,86,97,108,0,59,121,0,18,98,50,0,20,0,0, +1,0,2,1,1,1,0,1,98,0,0,0,1,9,18,95,95,114,101,116,86,97,108,0,59,120,121,0,18,98,0,59,120,120,0,20, +0,0,1,0,2,1,1,1,0,9,102,0,0,0,1,3,2,1,10,1,122,101,114,111,0,2,58,118,101,99,50,0,17,48,0,48,0,0,0, +17,48,0,48,0,0,0,0,0,0,4,118,101,99,52,95,115,101,113,0,18,95,95,114,101,116,86,97,108,0,59,120, +121,0,0,18,102,0,59,120,120,0,0,18,122,101,114,111,0,0,0,0,1,0,2,1,1,1,0,5,105,0,0,0,1,3,2,1,6,1, +122,101,114,111,0,2,58,105,118,101,99,50,0,16,8,48,0,0,16,8,48,0,0,0,0,0,4,118,101,99,52,95,115, +101,113,0,18,95,95,114,101,116,86,97,108,0,59,120,121,0,0,18,105,0,59,120,120,0,0,18,122,101,114, +111,0,0,0,0,1,0,3,1,1,1,0,1,98,49,0,0,1,1,0,1,98,50,0,0,1,1,0,1,98,51,0,0,0,1,9,18,95,95,114,101, +116,86,97,108,0,59,120,0,18,98,49,0,20,0,9,18,95,95,114,101,116,86,97,108,0,59,121,0,18,98,50,0,20, +0,9,18,95,95,114,101,116,86,97,108,0,59,122,0,18,98,51,0,20,0,0,1,0,3,1,1,1,0,1,98,0,0,0,1,9,18,95, +95,114,101,116,86,97,108,0,59,120,121,122,0,18,98,0,59,120,120,120,0,20,0,0,1,0,3,1,1,1,0,9,102,0, +0,0,1,3,2,1,11,1,122,101,114,111,0,2,58,118,101,99,51,0,17,48,0,48,0,0,0,17,48,0,48,0,0,0,17,48,0, +48,0,0,0,0,0,0,4,118,101,99,52,95,115,101,113,0,18,95,95,114,101,116,86,97,108,0,59,120,121,122,0, +0,18,102,0,59,120,120,120,0,0,18,122,101,114,111,0,0,0,0,1,0,3,1,1,1,0,5,105,0,0,0,1,3,2,1,7,1,122, +101,114,111,0,2,58,105,118,101,99,51,0,16,8,48,0,0,16,8,48,0,0,16,8,48,0,0,0,0,0,4,118,101,99,52, +95,115,101,113,0,18,95,95,114,101,116,86,97,108,0,59,120,121,122,0,0,18,105,0,59,120,120,120,0,0, +18,122,101,114,111,0,0,0,0,1,0,4,1,1,1,0,1,98,49,0,0,1,1,0,1,98,50,0,0,1,1,0,1,98,51,0,0,1,1,0,1, +98,52,0,0,0,1,9,18,95,95,114,101,116,86,97,108,0,59,120,0,18,98,49,0,20,0,9,18,95,95,114,101,116, +86,97,108,0,59,121,0,18,98,50,0,20,0,9,18,95,95,114,101,116,86,97,108,0,59,122,0,18,98,51,0,20,0,9, +18,95,95,114,101,116,86,97,108,0,59,119,0,18,98,52,0,20,0,0,1,0,4,1,1,1,0,1,98,0,0,0,1,9,18,95,95, +114,101,116,86,97,108,0,59,120,121,122,119,0,18,98,0,59,120,120,120,120,0,20,0,0,1,0,4,1,1,1,0,9, +102,0,0,0,1,3,2,1,12,1,122,101,114,111,0,2,58,118,101,99,52,0,17,48,0,48,0,0,0,17,48,0,48,0,0,0,17, +48,0,48,0,0,0,17,48,0,48,0,0,0,0,0,0,4,118,101,99,52,95,115,101,113,0,18,95,95,114,101,116,86,97, +108,0,0,18,102,0,59,120,120,120,120,0,0,18,122,101,114,111,0,0,0,0,1,0,4,1,1,1,0,5,105,0,0,0,1,3,2, +1,8,1,122,101,114,111,0,2,58,105,118,101,99,52,0,16,8,48,0,0,16,8,48,0,0,16,8,48,0,0,16,8,48,0,0,0, +0,0,4,118,101,99,52,95,115,101,113,0,18,95,95,114,101,116,86,97,108,0,0,18,105,0,59,120,120,120, +120,0,0,18,122,101,114,111,0,0,0,0,1,0,13,1,1,1,0,9,109,48,48,0,0,1,1,0,9,109,49,48,0,0,1,1,0,9, +109,48,49,0,0,1,1,0,9,109,49,49,0,0,0,1,9,18,95,95,114,101,116,86,97,108,0,16,8,48,0,57,59,120,0, +18,109,48,48,0,20,0,9,18,95,95,114,101,116,86,97,108,0,16,8,48,0,57,59,121,0,18,109,49,48,0,20,0,9, +18,95,95,114,101,116,86,97,108,0,16,10,49,0,57,59,120,0,18,109,48,49,0,20,0,9,18,95,95,114,101,116, +86,97,108,0,16,10,49,0,57,59,121,0,18,109,49,49,0,20,0,0,1,0,13,1,1,1,0,9,102,0,0,0,1,9,18,95,95, +114,101,116,86,97,108,0,16,8,48,0,57,59,120,0,18,102,0,20,0,9,18,95,95,114,101,116,86,97,108,0,16, +8,48,0,57,59,121,0,17,48,0,48,0,0,20,0,9,18,95,95,114,101,116,86,97,108,0,16,10,49,0,57,59,120,0, +17,48,0,48,0,0,20,0,9,18,95,95,114,101,116,86,97,108,0,16,10,49,0,57,59,121,0,18,102,0,20,0,0,1,0, +13,1,1,1,0,5,105,0,0,0,1,8,58,109,97,116,50,0,58,102,108,111,97,116,0,18,105,0,0,0,0,0,0,0,1,0,13, +1,1,1,0,1,98,0,0,0,1,8,58,109,97,116,50,0,58,102,108,111,97,116,0,18,98,0,0,0,0,0,0,0,1,0,13,1,1,1, +0,10,99,48,0,0,1,1,0,10,99,49,0,0,0,1,9,18,95,95,114,101,116,86,97,108,0,16,8,48,0,57,18,99,48,0, +20,0,9,18,95,95,114,101,116,86,97,108,0,16,10,49,0,57,18,99,49,0,20,0,0,1,0,14,1,1,1,0,9,109,48,48, +0,0,1,1,0,9,109,49,48,0,0,1,1,0,9,109,50,48,0,0,1,1,0,9,109,48,49,0,0,1,1,0,9,109,49,49,0,0,1,1,0, +9,109,50,49,0,0,1,1,0,9,109,48,50,0,0,1,1,0,9,109,49,50,0,0,1,1,0,9,109,50,50,0,0,0,1,9,18,95,95, +114,101,116,86,97,108,0,16,8,48,0,57,59,120,0,18,109,48,48,0,20,0,9,18,95,95,114,101,116,86,97,108, +0,16,8,48,0,57,59,121,0,18,109,49,48,0,20,0,9,18,95,95,114,101,116,86,97,108,0,16,8,48,0,57,59,122, +0,18,109,50,48,0,20,0,9,18,95,95,114,101,116,86,97,108,0,16,10,49,0,57,59,120,0,18,109,48,49,0,20, +0,9,18,95,95,114,101,116,86,97,108,0,16,10,49,0,57,59,121,0,18,109,49,49,0,20,0,9,18,95,95,114,101, +116,86,97,108,0,16,10,49,0,57,59,122,0,18,109,50,49,0,20,0,9,18,95,95,114,101,116,86,97,108,0,16, +10,50,0,57,59,120,0,18,109,48,50,0,20,0,9,18,95,95,114,101,116,86,97,108,0,16,10,50,0,57,59,121,0, +18,109,49,50,0,20,0,9,18,95,95,114,101,116,86,97,108,0,16,10,50,0,57,59,122,0,18,109,50,50,0,20,0, +0,1,0,14,1,1,1,0,9,102,0,0,0,1,3,2,0,10,1,118,0,2,58,118,101,99,50,0,18,102,0,0,17,48,0,48,0,0,0,0, +0,0,9,18,95,95,114,101,116,86,97,108,0,16,8,48,0,57,18,118,0,59,120,121,121,0,20,0,9,18,95,95,114, +101,116,86,97,108,0,16,10,49,0,57,18,118,0,59,121,120,121,0,20,0,9,18,95,95,114,101,116,86,97,108, +0,16,10,50,0,57,18,118,0,59,121,121,120,0,20,0,0,1,0,14,1,1,1,0,5,105,0,0,0,1,8,58,109,97,116,51,0, +58,102,108,111,97,116,0,18,105,0,0,0,0,0,0,0,1,0,14,1,1,1,0,1,98,0,0,0,1,8,58,109,97,116,51,0,58, +102,108,111,97,116,0,18,98,0,0,0,0,0,0,0,1,0,14,1,1,1,0,11,99,48,0,0,1,1,0,11,99,49,0,0,1,1,0,11, +99,50,0,0,0,1,9,18,95,95,114,101,116,86,97,108,0,16,8,48,0,57,18,99,48,0,20,0,9,18,95,95,114,101, +116,86,97,108,0,16,10,49,0,57,18,99,49,0,20,0,9,18,95,95,114,101,116,86,97,108,0,16,10,50,0,57,18, +99,50,0,20,0,0,1,0,15,1,1,1,0,9,109,48,48,0,0,1,1,0,9,109,49,48,0,0,1,1,0,9,109,50,48,0,0,1,1,0,9, +109,51,48,0,0,1,1,0,9,109,48,49,0,0,1,1,0,9,109,49,49,0,0,1,1,0,9,109,50,49,0,0,1,1,0,9,109,51,49, +0,0,1,1,0,9,109,48,50,0,0,1,1,0,9,109,49,50,0,0,1,1,0,9,109,50,50,0,0,1,1,0,9,109,51,50,0,0,1,1,0, +9,109,48,51,0,0,1,1,0,9,109,49,51,0,0,1,1,0,9,109,50,51,0,0,1,1,0,9,109,51,51,0,0,0,1,9,18,95,95, +114,101,116,86,97,108,0,16,8,48,0,57,59,120,0,18,109,48,48,0,20,0,9,18,95,95,114,101,116,86,97,108, +0,16,8,48,0,57,59,121,0,18,109,49,48,0,20,0,9,18,95,95,114,101,116,86,97,108,0,16,8,48,0,57,59,122, +0,18,109,50,48,0,20,0,9,18,95,95,114,101,116,86,97,108,0,16,8,48,0,57,59,119,0,18,109,51,48,0,20,0, +9,18,95,95,114,101,116,86,97,108,0,16,10,49,0,57,59,120,0,18,109,48,49,0,20,0,9,18,95,95,114,101, +116,86,97,108,0,16,10,49,0,57,59,121,0,18,109,49,49,0,20,0,9,18,95,95,114,101,116,86,97,108,0,16, +10,49,0,57,59,122,0,18,109,50,49,0,20,0,9,18,95,95,114,101,116,86,97,108,0,16,10,49,0,57,59,119,0, +18,109,51,49,0,20,0,9,18,95,95,114,101,116,86,97,108,0,16,10,50,0,57,59,120,0,18,109,48,50,0,20,0, +9,18,95,95,114,101,116,86,97,108,0,16,10,50,0,57,59,121,0,18,109,49,50,0,20,0,9,18,95,95,114,101, +116,86,97,108,0,16,10,50,0,57,59,122,0,18,109,50,50,0,20,0,9,18,95,95,114,101,116,86,97,108,0,16, +10,50,0,57,59,119,0,18,109,51,50,0,20,0,9,18,95,95,114,101,116,86,97,108,0,16,10,51,0,57,59,120,0, +18,109,48,51,0,20,0,9,18,95,95,114,101,116,86,97,108,0,16,10,51,0,57,59,121,0,18,109,49,51,0,20,0, +9,18,95,95,114,101,116,86,97,108,0,16,10,51,0,57,59,122,0,18,109,50,51,0,20,0,9,18,95,95,114,101, +116,86,97,108,0,16,10,51,0,57,59,119,0,18,109,51,51,0,20,0,0,1,0,15,1,1,1,0,9,102,0,0,0,1,3,2,0,10, +1,118,0,2,58,118,101,99,50,0,18,102,0,0,17,48,0,48,0,0,0,0,0,0,9,18,95,95,114,101,116,86,97,108,0, +16,8,48,0,57,18,118,0,59,120,121,121,121,0,20,0,9,18,95,95,114,101,116,86,97,108,0,16,10,49,0,57, +18,118,0,59,121,120,121,121,0,20,0,9,18,95,95,114,101,116,86,97,108,0,16,10,50,0,57,18,118,0,59, +121,121,120,121,0,20,0,9,18,95,95,114,101,116,86,97,108,0,16,10,51,0,57,18,118,0,59,121,121,121, +120,0,20,0,0,1,0,15,1,1,1,0,5,105,0,0,0,1,8,58,109,97,116,52,0,58,102,108,111,97,116,0,18,105,0,0, +0,0,0,0,0,1,0,15,1,1,1,0,1,98,0,0,0,1,8,58,109,97,116,52,0,58,102,108,111,97,116,0,18,98,0,0,0,0,0, +0,0,1,0,15,1,1,1,0,12,99,48,0,0,1,1,0,12,99,49,0,0,1,1,0,12,99,50,0,0,1,1,0,12,99,51,0,0,0,1,9,18, +95,95,114,101,116,86,97,108,0,16,8,48,0,57,18,99,48,0,20,0,9,18,95,95,114,101,116,86,97,108,0,16, +10,49,0,57,18,99,49,0,20,0,9,18,95,95,114,101,116,86,97,108,0,16,10,50,0,57,18,99,50,0,20,0,9,18, +95,95,114,101,116,86,97,108,0,16,10,51,0,57,18,99,51,0,20,0,0,1,0,5,2,26,1,1,0,5,97,0,0,1,1,0,5,98, +0,0,0,1,3,2,0,9,1,120,0,0,0,4,118,101,99,52,95,97,100,100,0,18,120,0,0,18,97,0,0,18,98,0,0,0,4,102, +108,111,97,116,95,116,111,95,105,110,116,0,18,95,95,114,101,116,86,97,108,0,0,18,120,0,0,0,0,1,0,5, +2,27,1,1,0,5,97,0,0,1,1,0,5,98,0,0,0,1,3,2,0,9,1,120,0,0,0,4,118,101,99,52,95,115,117,98,116,114, +97,99,116,0,18,120,0,0,18,97,0,0,18,98,0,0,0,4,102,108,111,97,116,95,116,111,95,105,110,116,0,18, +95,95,114,101,116,86,97,108,0,0,18,120,0,0,0,0,1,0,5,2,21,1,1,0,5,97,0,0,1,1,0,5,98,0,0,0,1,3,2,0, +9,1,120,0,0,0,4,118,101,99,52,95,109,117,108,116,105,112,108,121,0,18,120,0,0,18,97,0,0,18,98,0,0, +0,4,102,108,111,97,116,95,116,111,95,105,110,116,0,18,95,95,114,101,116,86,97,108,0,0,18,120,0,0,0, +0,1,0,5,2,22,1,1,0,5,97,0,0,1,1,0,5,98,0,0,0,1,3,2,0,9,1,98,73,110,118,0,0,1,1,120,0,0,0,4,102,108, +111,97,116,95,114,99,112,0,18,98,73,110,118,0,0,18,98,0,0,0,4,118,101,99,52,95,109,117,108,116,105, +112,108,121,0,18,120,0,0,18,97,0,0,18,98,73,110,118,0,0,0,4,102,108,111,97,116,95,116,111,95,105, +110,116,0,18,95,95,114,101,116,86,97,108,0,0,18,120,0,0,0,0,1,0,6,2,26,1,1,0,6,97,0,0,1,1,0,6,98,0, +0,0,1,3,2,0,10,1,120,0,0,0,4,118,101,99,52,95,97,100,100,0,18,120,0,0,18,97,0,0,18,98,0,0,0,4,102, +108,111,97,116,95,116,111,95,105,110,116,0,18,95,95,114,101,116,86,97,108,0,0,18,120,0,0,0,0,1,0,6, +2,27,1,1,0,6,97,0,0,1,1,0,6,98,0,0,0,1,3,2,0,10,1,120,0,0,0,4,118,101,99,52,95,115,117,98,116,114, +97,99,116,0,18,120,0,0,18,97,0,0,18,98,0,0,0,4,102,108,111,97,116,95,116,111,95,105,110,116,0,18, +95,95,114,101,116,86,97,108,0,0,18,120,0,0,0,0,1,0,6,2,21,1,1,0,6,97,0,0,1,1,0,6,98,0,0,0,1,3,2,0, +10,1,120,0,0,0,4,118,101,99,52,95,109,117,108,116,105,112,108,121,0,18,120,0,0,18,97,0,0,18,98,0,0, +0,4,102,108,111,97,116,95,116,111,95,105,110,116,0,18,95,95,114,101,116,86,97,108,0,0,18,120,0,0,0, +0,1,0,6,2,22,1,1,0,6,97,0,0,1,1,0,6,98,0,0,0,1,3,2,0,10,1,98,73,110,118,0,0,1,1,120,0,0,0,4,102, +108,111,97,116,95,114,99,112,0,18,98,73,110,118,0,59,120,0,0,18,98,0,59,120,0,0,0,4,102,108,111,97, +116,95,114,99,112,0,18,98,73,110,118,0,59,121,0,0,18,98,0,59,121,0,0,0,4,118,101,99,52,95,109,117, +108,116,105,112,108,121,0,18,120,0,0,18,97,0,0,18,98,73,110,118,0,0,0,4,102,108,111,97,116,95,116, +111,95,105,110,116,0,18,95,95,114,101,116,86,97,108,0,0,18,120,0,0,0,0,1,0,7,2,26,1,1,0,7,97,0,0,1, +1,0,7,98,0,0,0,1,3,2,0,11,1,120,0,0,0,4,118,101,99,52,95,97,100,100,0,18,120,0,0,18,97,0,0,18,98,0, +0,0,4,102,108,111,97,116,95,116,111,95,105,110,116,0,18,95,95,114,101,116,86,97,108,0,0,18,120,0,0, +0,0,1,0,7,2,27,1,1,0,7,97,0,0,1,1,0,7,98,0,0,0,1,3,2,0,11,1,120,0,0,0,4,118,101,99,52,95,115,117, +98,116,114,97,99,116,0,18,120,0,0,18,97,0,0,18,98,0,0,0,4,102,108,111,97,116,95,116,111,95,105,110, +116,0,18,95,95,114,101,116,86,97,108,0,0,18,120,0,0,0,0,1,0,7,2,21,1,1,0,7,97,0,0,1,1,0,7,98,0,0,0, +1,3,2,0,11,1,120,0,0,0,4,118,101,99,52,95,109,117,108,116,105,112,108,121,0,18,120,0,0,18,97,0,0, +18,98,0,0,0,4,102,108,111,97,116,95,116,111,95,105,110,116,0,18,95,95,114,101,116,86,97,108,0,0,18, +120,0,0,0,0,1,0,7,2,22,1,1,0,7,97,0,0,1,1,0,7,98,0,0,0,1,3,2,0,11,1,98,73,110,118,0,0,1,1,120,0,0, +0,4,102,108,111,97,116,95,114,99,112,0,18,98,73,110,118,0,59,120,0,0,18,98,0,59,120,0,0,0,4,102, +108,111,97,116,95,114,99,112,0,18,98,73,110,118,0,59,121,0,0,18,98,0,59,121,0,0,0,4,102,108,111,97, +116,95,114,99,112,0,18,98,73,110,118,0,59,122,0,0,18,98,0,59,122,0,0,0,4,118,101,99,52,95,109,117, +108,116,105,112,108,121,0,18,120,0,0,18,97,0,0,18,98,73,110,118,0,0,0,4,102,108,111,97,116,95,116, +111,95,105,110,116,0,18,95,95,114,101,116,86,97,108,0,0,18,120,0,0,0,0,1,0,8,2,26,1,1,0,8,97,0,0,1, +1,0,8,98,0,0,0,1,3,2,0,11,1,120,0,0,0,4,118,101,99,52,95,97,100,100,0,18,120,0,0,18,97,0,0,18,98,0, +0,0,4,102,108,111,97,116,95,116,111,95,105,110,116,0,18,95,95,114,101,116,86,97,108,0,0,18,120,0,0, +0,0,1,0,8,2,27,1,1,0,8,97,0,0,1,1,0,8,98,0,0,0,1,3,2,0,12,1,120,0,0,0,4,118,101,99,52,95,115,117, +98,116,114,97,99,116,0,18,120,0,0,18,97,0,0,18,98,0,0,0,4,102,108,111,97,116,95,116,111,95,105,110, +116,0,18,95,95,114,101,116,86,97,108,0,0,18,120,0,0,0,0,1,0,8,2,21,1,1,0,8,97,0,0,1,1,0,8,98,0,0,0, +1,3,2,0,12,1,120,0,0,0,4,118,101,99,52,95,109,117,108,116,105,112,108,121,0,18,120,0,0,18,97,0,0, +18,98,0,0,0,4,102,108,111,97,116,95,116,111,95,105,110,116,0,18,95,95,114,101,116,86,97,108,0,0,18, +120,0,0,0,0,1,0,8,2,22,1,1,0,8,97,0,0,1,1,0,8,98,0,0,0,1,3,2,0,12,1,98,73,110,118,0,0,1,1,120,0,0, +0,4,102,108,111,97,116,95,114,99,112,0,18,98,73,110,118,0,59,120,0,0,18,98,0,59,120,0,0,0,4,102, +108,111,97,116,95,114,99,112,0,18,98,73,110,118,0,59,121,0,0,18,98,0,59,121,0,0,0,4,102,108,111,97, +116,95,114,99,112,0,18,98,73,110,118,0,59,122,0,0,18,98,0,59,122,0,0,0,4,102,108,111,97,116,95,114, +99,112,0,18,98,73,110,118,0,59,119,0,0,18,98,0,59,119,0,0,0,4,118,101,99,52,95,109,117,108,116,105, +112,108,121,0,18,120,0,0,18,97,0,0,18,98,73,110,118,0,0,0,4,102,108,111,97,116,95,116,111,95,105, +110,116,0,18,95,95,114,101,116,86,97,108,0,0,18,120,0,0,0,0,1,0,9,2,26,1,1,0,9,97,0,0,1,1,0,9,98,0, +0,0,1,4,118,101,99,52,95,97,100,100,0,18,95,95,114,101,116,86,97,108,0,59,120,0,0,18,97,0,0,18,98, +0,0,0,0,1,0,9,2,27,1,1,0,9,97,0,0,1,1,0,9,98,0,0,0,1,4,118,101,99,52,95,115,117,98,116,114,97,99, +116,0,18,95,95,114,101,116,86,97,108,0,59,120,0,0,18,97,0,0,18,98,0,0,0,0,1,0,9,2,21,1,1,0,9,97,0, +0,1,1,0,9,98,0,0,0,1,4,118,101,99,52,95,109,117,108,116,105,112,108,121,0,18,95,95,114,101,116,86, +97,108,0,59,120,0,0,18,97,0,0,18,98,0,0,0,0,1,0,9,2,22,1,1,0,9,97,0,0,1,1,0,9,98,0,0,0,1,3,2,0,9,1, +98,73,110,118,0,0,0,4,102,108,111,97,116,95,114,99,112,0,18,98,73,110,118,0,59,120,0,0,18,98,0,59, +120,0,0,0,4,118,101,99,52,95,109,117,108,116,105,112,108,121,0,18,95,95,114,101,116,86,97,108,0,59, +120,0,0,18,97,0,0,18,98,73,110,118,0,0,0,0,1,0,10,2,26,1,1,0,10,118,0,0,1,1,0,10,117,0,0,0,1,4,118, +101,99,52,95,97,100,100,0,18,95,95,114,101,116,86,97,108,0,59,120,121,0,0,18,118,0,0,18,117,0,0,0, +0,1,0,10,2,27,1,1,0,10,118,0,0,1,1,0,10,117,0,0,0,1,4,118,101,99,52,95,115,117,98,116,114,97,99, +116,0,18,95,95,114,101,116,86,97,108,0,59,120,121,0,0,18,118,0,0,18,117,0,0,0,0,1,0,10,2,21,1,1,0, +10,118,0,0,1,1,0,10,117,0,0,0,1,4,118,101,99,52,95,109,117,108,116,105,112,108,121,0,18,95,95,114, +101,116,86,97,108,0,59,120,121,0,0,18,118,0,0,18,117,0,0,0,0,1,0,10,2,22,1,1,0,10,118,0,0,1,1,0,10, +117,0,0,0,1,3,2,0,10,1,119,0,0,0,4,102,108,111,97,116,95,114,99,112,0,18,119,0,59,120,0,0,18,117,0, +59,120,0,0,0,4,102,108,111,97,116,95,114,99,112,0,18,119,0,59,121,0,0,18,117,0,59,121,0,0,0,4,118, +101,99,52,95,109,117,108,116,105,112,108,121,0,18,95,95,114,101,116,86,97,108,0,59,120,121,0,0,18, +118,0,0,18,119,0,0,0,0,1,0,11,2,26,1,1,0,11,118,0,0,1,1,0,11,117,0,0,0,1,4,118,101,99,52,95,97,100, +100,0,18,95,95,114,101,116,86,97,108,0,59,120,121,122,0,0,18,118,0,0,18,117,0,0,0,0,1,0,11,2,27,1, +1,0,11,118,0,0,1,1,0,11,117,0,0,0,1,4,118,101,99,52,95,115,117,98,116,114,97,99,116,0,18,95,95,114, +101,116,86,97,108,0,59,120,121,122,0,0,18,118,0,0,18,117,0,0,0,0,1,0,11,2,21,1,1,0,11,118,0,0,1,1, +0,11,117,0,0,0,1,4,118,101,99,52,95,109,117,108,116,105,112,108,121,0,18,95,95,114,101,116,86,97, +108,0,59,120,121,122,0,0,18,118,0,0,18,117,0,0,0,0,1,0,11,2,22,1,1,0,11,118,0,0,1,1,0,11,117,0,0,0, +1,3,2,0,11,1,119,0,0,0,4,102,108,111,97,116,95,114,99,112,0,18,119,0,59,120,0,0,18,117,0,59,120,0, +0,0,4,102,108,111,97,116,95,114,99,112,0,18,119,0,59,121,0,0,18,117,0,59,121,0,0,0,4,102,108,111, +97,116,95,114,99,112,0,18,119,0,59,122,0,0,18,117,0,59,122,0,0,0,4,118,101,99,52,95,109,117,108, +116,105,112,108,121,0,18,95,95,114,101,116,86,97,108,0,59,120,121,122,0,0,18,118,0,0,18,119,0,0,0, +0,1,0,12,2,26,1,1,0,12,118,0,0,1,1,0,12,117,0,0,0,1,4,118,101,99,52,95,97,100,100,0,18,95,95,114, +101,116,86,97,108,0,0,18,118,0,0,18,117,0,0,0,0,1,0,12,2,27,1,1,0,12,118,0,0,1,1,0,12,117,0,0,0,1, +4,118,101,99,52,95,115,117,98,116,114,97,99,116,0,18,95,95,114,101,116,86,97,108,0,0,18,118,0,0,18, +117,0,0,0,0,1,0,12,2,21,1,1,0,12,118,0,0,1,1,0,12,117,0,0,0,1,4,118,101,99,52,95,109,117,108,116, +105,112,108,121,0,18,95,95,114,101,116,86,97,108,0,0,18,118,0,0,18,117,0,0,0,0,1,0,12,2,22,1,1,0, +12,118,0,0,1,1,0,12,117,0,0,0,1,3,2,0,12,1,119,0,0,0,4,102,108,111,97,116,95,114,99,112,0,18,119,0, +59,120,0,0,18,117,0,59,120,0,0,0,4,102,108,111,97,116,95,114,99,112,0,18,119,0,59,121,0,0,18,117,0, +59,121,0,0,0,4,102,108,111,97,116,95,114,99,112,0,18,119,0,59,122,0,0,18,117,0,59,122,0,0,0,4,102, +108,111,97,116,95,114,99,112,0,18,119,0,59,119,0,0,18,117,0,59,119,0,0,0,4,118,101,99,52,95,109, +117,108,116,105,112,108,121,0,18,95,95,114,101,116,86,97,108,0,0,18,118,0,0,18,119,0,0,0,0,1,0,10, +2,26,1,1,0,9,97,0,0,1,1,0,10,117,0,0,0,1,4,118,101,99,52,95,97,100,100,0,18,95,95,114,101,116,86, +97,108,0,59,120,121,0,0,18,97,0,59,120,120,0,0,18,117,0,59,120,121,0,0,0,0,1,0,10,2,26,1,1,0,10, +118,0,0,1,1,0,9,98,0,0,0,1,4,118,101,99,52,95,97,100,100,0,18,95,95,114,101,116,86,97,108,0,59,120, +121,0,0,18,118,0,59,120,121,0,0,18,98,0,59,120,120,0,0,0,0,1,0,10,2,27,1,1,0,9,97,0,0,1,1,0,10,117, +0,0,0,1,4,118,101,99,52,95,115,117,98,116,114,97,99,116,0,18,95,95,114,101,116,86,97,108,0,59,120, +121,0,0,18,97,0,59,120,120,0,0,18,117,0,59,120,121,0,0,0,0,1,0,10,2,27,1,1,0,10,118,0,0,1,1,0,9,98, +0,0,0,1,4,118,101,99,52,95,115,117,98,116,114,97,99,116,0,18,95,95,114,101,116,86,97,108,0,59,120, +121,0,0,18,118,0,59,120,121,0,0,18,98,0,59,120,120,0,0,0,0,1,0,10,2,21,1,1,0,9,97,0,0,1,1,0,10,117, +0,0,0,1,4,118,101,99,52,95,109,117,108,116,105,112,108,121,0,18,95,95,114,101,116,86,97,108,0,59, +120,121,0,0,18,97,0,59,120,120,0,0,18,117,0,59,120,121,0,0,0,0,1,0,10,2,21,1,1,0,10,118,0,0,1,1,0, +9,98,0,0,0,1,4,118,101,99,52,95,109,117,108,116,105,112,108,121,0,18,95,95,114,101,116,86,97,108,0, +59,120,121,0,0,18,118,0,59,120,121,0,0,18,98,0,59,120,120,0,0,0,0,1,0,10,2,22,1,1,0,9,97,0,0,1,1,0, +10,117,0,0,0,1,3,2,0,10,1,105,110,118,85,0,0,0,4,102,108,111,97,116,95,114,99,112,0,18,105,110,118, +85,0,59,120,0,0,18,117,0,59,120,0,0,0,4,102,108,111,97,116,95,114,99,112,0,18,105,110,118,85,0,59, +121,0,0,18,117,0,59,121,0,0,0,4,118,101,99,52,95,109,117,108,116,105,112,108,121,0,18,95,95,114, +101,116,86,97,108,0,59,120,121,0,0,18,97,0,59,120,120,0,0,18,105,110,118,85,0,59,120,121,0,0,0,0,1, +0,10,2,22,1,1,0,10,118,0,0,1,1,0,9,98,0,0,0,1,3,2,0,9,1,105,110,118,66,0,0,0,4,102,108,111,97,116, +95,114,99,112,0,18,105,110,118,66,0,0,18,98,0,0,0,4,118,101,99,52,95,109,117,108,116,105,112,108, +121,0,18,95,95,114,101,116,86,97,108,0,59,120,121,0,0,18,118,0,59,120,121,0,0,18,105,110,118,66,0, +59,120,120,0,0,0,0,1,0,11,2,26,1,1,0,9,97,0,0,1,1,0,11,117,0,0,0,1,4,118,101,99,52,95,97,100,100,0, +18,95,95,114,101,116,86,97,108,0,59,120,121,122,0,0,18,97,0,59,120,120,120,0,0,18,117,0,59,120,121, +122,0,0,0,0,1,0,11,2,26,1,1,0,11,118,0,0,1,1,0,9,98,0,0,0,1,4,118,101,99,52,95,97,100,100,0,18,95, +95,114,101,116,86,97,108,0,59,120,121,122,0,0,18,118,0,59,120,121,122,0,0,18,98,0,59,120,120,120,0, +0,0,0,1,0,11,2,27,1,1,0,9,97,0,0,1,1,0,11,117,0,0,0,1,4,118,101,99,52,95,115,117,98,116,114,97,99, +116,0,18,95,95,114,101,116,86,97,108,0,59,120,121,122,0,0,18,97,0,59,120,120,120,0,0,18,117,0,59, +120,121,122,0,0,0,0,1,0,11,2,27,1,1,0,11,118,0,0,1,1,0,9,98,0,0,0,1,4,118,101,99,52,95,115,117,98, +116,114,97,99,116,0,18,95,95,114,101,116,86,97,108,0,59,120,121,122,0,0,18,118,0,59,120,121,122,0, +0,18,98,0,59,120,120,120,0,0,0,0,1,0,11,2,21,1,1,0,9,97,0,0,1,1,0,11,117,0,0,0,1,4,118,101,99,52, +95,109,117,108,116,105,112,108,121,0,18,95,95,114,101,116,86,97,108,0,59,120,121,122,0,0,18,97,0, +59,120,120,120,0,0,18,117,0,59,120,121,122,0,0,0,0,1,0,11,2,21,1,1,0,11,118,0,0,1,1,0,9,98,0,0,0,1, +4,118,101,99,52,95,109,117,108,116,105,112,108,121,0,18,95,95,114,101,116,86,97,108,0,59,120,121, +122,0,0,18,118,0,59,120,121,122,0,0,18,98,0,59,120,120,120,0,0,0,0,1,0,11,2,22,1,1,0,9,97,0,0,1,1, +0,11,117,0,0,0,1,3,2,0,11,1,105,110,118,85,0,0,0,4,102,108,111,97,116,95,114,99,112,0,18,105,110, +118,85,0,59,120,0,0,18,117,0,59,120,0,0,0,4,102,108,111,97,116,95,114,99,112,0,18,105,110,118,85,0, +59,121,0,0,18,117,0,59,121,0,0,0,4,102,108,111,97,116,95,114,99,112,0,18,105,110,118,85,0,59,122,0, +0,18,117,0,59,122,0,0,0,4,118,101,99,52,95,109,117,108,116,105,112,108,121,0,18,95,95,114,101,116, +86,97,108,0,59,120,121,122,0,0,18,97,0,59,120,120,120,0,0,18,105,110,118,85,0,59,120,121,122,0,0,0, +0,1,0,11,2,22,1,1,0,11,118,0,0,1,1,0,9,98,0,0,0,1,3,2,0,9,1,105,110,118,66,0,0,0,4,102,108,111,97, +116,95,114,99,112,0,18,105,110,118,66,0,0,18,98,0,0,0,4,118,101,99,52,95,109,117,108,116,105,112, +108,121,0,18,95,95,114,101,116,86,97,108,0,59,120,121,122,0,0,18,118,0,59,120,121,122,0,0,18,105, +110,118,66,0,59,120,120,120,0,0,0,0,1,0,12,2,26,1,1,0,9,97,0,0,1,1,0,12,117,0,0,0,1,4,118,101,99, +52,95,97,100,100,0,18,95,95,114,101,116,86,97,108,0,0,18,97,0,59,120,120,120,120,0,0,18,117,0,0,0, +0,1,0,12,2,26,1,1,0,12,118,0,0,1,1,0,9,98,0,0,0,1,4,118,101,99,52,95,97,100,100,0,18,95,95,114,101, +116,86,97,108,0,0,18,118,0,0,18,98,0,59,120,120,120,120,0,0,0,0,1,0,12,2,27,1,1,0,9,97,0,0,1,1,0, +12,117,0,0,0,1,4,118,101,99,52,95,115,117,98,116,114,97,99,116,0,18,95,95,114,101,116,86,97,108,0, +0,18,97,0,59,120,120,120,120,0,0,18,117,0,0,0,0,1,0,12,2,27,1,1,0,12,118,0,0,1,1,0,9,98,0,0,0,1,4, +118,101,99,52,95,115,117,98,116,114,97,99,116,0,18,95,95,114,101,116,86,97,108,0,0,18,118,0,0,18, +98,0,59,120,120,120,120,0,0,0,0,1,0,12,2,21,1,1,0,9,97,0,0,1,1,0,12,117,0,0,0,1,4,118,101,99,52,95, +109,117,108,116,105,112,108,121,0,18,95,95,114,101,116,86,97,108,0,0,18,97,0,59,120,120,120,120,0, +0,18,117,0,0,0,0,1,0,12,2,21,1,1,0,12,118,0,0,1,1,0,9,98,0,0,0,1,4,118,101,99,52,95,109,117,108, +116,105,112,108,121,0,18,95,95,114,101,116,86,97,108,0,0,18,118,0,0,18,98,0,59,120,120,120,120,0,0, +0,0,1,0,12,2,22,1,1,0,9,97,0,0,1,1,0,12,117,0,0,0,1,3,2,0,12,1,105,110,118,85,0,0,0,4,102,108,111, +97,116,95,114,99,112,0,18,105,110,118,85,0,59,120,0,0,18,117,0,59,120,0,0,0,4,102,108,111,97,116, +95,114,99,112,0,18,105,110,118,85,0,59,121,0,0,18,117,0,59,121,0,0,0,4,102,108,111,97,116,95,114, +99,112,0,18,105,110,118,85,0,59,122,0,0,18,117,0,59,122,0,0,0,4,102,108,111,97,116,95,114,99,112,0, +18,105,110,118,85,0,59,119,0,0,18,117,0,59,119,0,0,0,4,118,101,99,52,95,109,117,108,116,105,112, +108,121,0,18,95,95,114,101,116,86,97,108,0,0,18,97,0,59,120,120,120,120,0,0,18,105,110,118,85,0,0, +0,0,1,0,12,2,22,1,1,0,12,118,0,0,1,1,0,9,98,0,0,0,1,3,2,0,9,1,105,110,118,66,0,0,0,4,102,108,111, +97,116,95,114,99,112,0,18,105,110,118,66,0,0,18,98,0,0,0,4,118,101,99,52,95,109,117,108,116,105, +112,108,121,0,18,95,95,114,101,116,86,97,108,0,0,18,118,0,0,18,105,110,118,66,0,59,120,120,120,120, +0,0,0,0,1,0,6,2,26,1,1,0,5,97,0,0,1,1,0,6,117,0,0,0,1,9,18,95,95,114,101,116,86,97,108,0,58,105, +118,101,99,50,0,18,97,0,0,0,18,117,0,46,20,0,0,1,0,6,2,26,1,1,0,6,118,0,0,1,1,0,5,98,0,0,0,1,9,18, +95,95,114,101,116,86,97,108,0,18,118,0,58,105,118,101,99,50,0,18,98,0,0,0,46,20,0,0,1,0,6,2,27,1,1, +0,5,97,0,0,1,1,0,6,117,0,0,0,1,9,18,95,95,114,101,116,86,97,108,0,58,105,118,101,99,50,0,18,97,0,0, +0,18,117,0,47,20,0,0,1,0,6,2,27,1,1,0,6,118,0,0,1,1,0,5,98,0,0,0,1,9,18,95,95,114,101,116,86,97, +108,0,18,118,0,58,105,118,101,99,50,0,18,98,0,0,0,47,20,0,0,1,0,6,2,21,1,1,0,5,97,0,0,1,1,0,6,117, +0,0,0,1,9,18,95,95,114,101,116,86,97,108,0,58,105,118,101,99,50,0,18,97,0,0,0,18,117,0,48,20,0,0,1, +0,6,2,21,1,1,0,6,118,0,0,1,1,0,5,98,0,0,0,1,9,18,95,95,114,101,116,86,97,108,0,18,118,0,58,105,118, +101,99,50,0,18,98,0,0,0,48,20,0,0,1,0,6,2,22,1,1,0,5,97,0,0,1,1,0,6,117,0,0,0,1,9,18,95,95,114,101, +116,86,97,108,0,58,105,118,101,99,50,0,18,97,0,0,0,18,117,0,49,20,0,0,1,0,6,2,22,1,1,0,6,118,0,0,1, +1,0,5,98,0,0,0,1,9,18,95,95,114,101,116,86,97,108,0,18,118,0,58,105,118,101,99,50,0,18,98,0,0,0,49, +20,0,0,1,0,7,2,26,1,1,0,5,97,0,0,1,1,0,7,117,0,0,0,1,9,18,95,95,114,101,116,86,97,108,0,58,105,118, +101,99,51,0,18,97,0,0,0,18,117,0,46,20,0,0,1,0,7,2,26,1,1,0,7,118,0,0,1,1,0,5,98,0,0,0,1,9,18,95, +95,114,101,116,86,97,108,0,18,118,0,58,105,118,101,99,51,0,18,98,0,0,0,46,20,0,0,1,0,7,2,27,1,1,0, +5,97,0,0,1,1,0,7,117,0,0,0,1,9,18,95,95,114,101,116,86,97,108,0,58,105,118,101,99,51,0,18,97,0,0,0, +18,117,0,47,20,0,0,1,0,7,2,27,1,1,0,7,118,0,0,1,1,0,5,98,0,0,0,1,9,18,95,95,114,101,116,86,97,108, +0,18,118,0,58,105,118,101,99,51,0,18,98,0,0,0,47,20,0,0,1,0,7,2,21,1,1,0,5,97,0,0,1,1,0,7,117,0,0, +0,1,9,18,95,95,114,101,116,86,97,108,0,58,105,118,101,99,51,0,18,97,0,0,0,18,117,0,48,20,0,0,1,0,7, +2,21,1,1,0,7,118,0,0,1,1,0,5,98,0,0,0,1,9,18,95,95,114,101,116,86,97,108,0,18,118,0,58,105,118,101, +99,51,0,18,98,0,0,0,48,20,0,0,1,0,7,2,22,1,1,0,5,97,0,0,1,1,0,7,117,0,0,0,1,9,18,95,95,114,101,116, +86,97,108,0,58,105,118,101,99,51,0,18,97,0,0,0,18,117,0,49,20,0,0,1,0,7,2,22,1,1,0,7,118,0,0,1,1,0, +5,98,0,0,0,1,9,18,95,95,114,101,116,86,97,108,0,18,118,0,58,105,118,101,99,51,0,18,98,0,0,0,49,20, +0,0,1,0,8,2,26,1,1,0,5,97,0,0,1,1,0,8,117,0,0,0,1,9,18,95,95,114,101,116,86,97,108,0,58,105,118, +101,99,52,0,18,97,0,0,0,18,117,0,46,20,0,0,1,0,8,2,26,1,1,0,8,118,0,0,1,1,0,5,98,0,0,0,1,9,18,95, +95,114,101,116,86,97,108,0,18,118,0,58,105,118,101,99,52,0,18,98,0,0,0,46,20,0,0,1,0,8,2,27,1,1,0, +5,97,0,0,1,1,0,8,117,0,0,0,1,9,18,95,95,114,101,116,86,97,108,0,58,105,118,101,99,52,0,18,97,0,0,0, +18,117,0,47,20,0,0,1,0,8,2,27,1,1,0,8,118,0,0,1,1,0,5,98,0,0,0,1,9,18,95,95,114,101,116,86,97,108, +0,18,118,0,58,105,118,101,99,52,0,18,98,0,0,0,47,20,0,0,1,0,8,2,21,1,1,0,5,97,0,0,1,1,0,8,117,0,0, +0,1,9,18,95,95,114,101,116,86,97,108,0,58,105,118,101,99,52,0,18,97,0,0,0,18,117,0,48,20,0,0,1,0,8, +2,21,1,1,0,8,118,0,0,1,1,0,5,98,0,0,0,1,9,18,95,95,114,101,116,86,97,108,0,18,118,0,58,105,118,101, +99,52,0,18,98,0,0,0,48,20,0,0,1,0,8,2,22,1,1,0,5,97,0,0,1,1,0,8,117,0,0,0,1,9,18,95,95,114,101,116, +86,97,108,0,58,105,118,101,99,52,0,18,97,0,0,0,18,117,0,49,20,0,0,1,0,8,2,22,1,1,0,8,118,0,0,1,1,0, +5,98,0,0,0,1,9,18,95,95,114,101,116,86,97,108,0,18,118,0,58,105,118,101,99,52,0,18,98,0,0,0,49,20, +0,0,1,0,5,2,27,1,1,0,5,97,0,0,0,1,4,118,101,99,52,95,110,101,103,97,116,101,0,18,95,95,114,101,116, +86,97,108,0,59,120,0,0,18,97,0,0,0,0,1,0,6,2,27,1,1,0,6,118,0,0,0,1,4,118,101,99,52,95,110,101,103, +97,116,101,0,18,95,95,114,101,116,86,97,108,0,0,18,118,0,0,0,0,1,0,7,2,27,1,1,0,7,118,0,0,0,1,4, +118,101,99,52,95,110,101,103,97,116,101,0,18,95,95,114,101,116,86,97,108,0,0,18,118,0,0,0,0,1,0,8, +2,27,1,1,0,8,118,0,0,0,1,4,118,101,99,52,95,110,101,103,97,116,101,0,18,95,95,114,101,116,86,97, +108,0,0,18,118,0,0,0,0,1,0,9,2,27,1,1,0,9,97,0,0,0,1,4,118,101,99,52,95,110,101,103,97,116,101,0, +18,95,95,114,101,116,86,97,108,0,59,120,0,0,18,97,0,0,0,0,1,0,10,2,27,1,1,0,10,118,0,0,0,1,4,118, +101,99,52,95,110,101,103,97,116,101,0,18,95,95,114,101,116,86,97,108,0,59,120,121,0,0,18,118,0,59, +120,121,0,0,0,0,1,0,11,2,27,1,1,0,11,118,0,0,0,1,4,118,101,99,52,95,110,101,103,97,116,101,0,18,95, +95,114,101,116,86,97,108,0,59,120,121,122,0,0,18,118,0,59,120,121,122,0,0,0,0,1,0,12,2,27,1,1,0,12, +118,0,0,0,1,4,118,101,99,52,95,110,101,103,97,116,101,0,18,95,95,114,101,116,86,97,108,0,0,18,118, +0,0,0,0,1,0,13,2,27,1,1,0,13,109,0,0,0,1,9,18,95,95,114,101,116,86,97,108,0,16,8,48,0,57,18,109,0, +16,8,48,0,57,54,20,0,9,18,95,95,114,101,116,86,97,108,0,16,10,49,0,57,18,109,0,16,10,49,0,57,54,20, +0,0,1,0,14,2,27,1,1,0,14,109,0,0,0,1,9,18,95,95,114,101,116,86,97,108,0,16,8,48,0,57,18,109,0,16,8, +48,0,57,54,20,0,9,18,95,95,114,101,116,86,97,108,0,16,10,49,0,57,18,109,0,16,10,49,0,57,54,20,0,9, +18,95,95,114,101,116,86,97,108,0,16,10,50,0,57,18,109,0,16,10,50,0,57,54,20,0,0,1,0,15,2,27,1,1,0, +15,109,0,0,0,1,9,18,95,95,114,101,116,86,97,108,0,16,8,48,0,57,18,109,0,16,8,48,0,57,54,20,0,9,18, +95,95,114,101,116,86,97,108,0,16,10,49,0,57,18,109,0,16,10,49,0,57,54,20,0,9,18,95,95,114,101,116, +86,97,108,0,16,10,50,0,57,18,109,0,16,10,50,0,57,54,20,0,9,18,95,95,114,101,116,86,97,108,0,16,10, +51,0,57,18,109,0,16,10,51,0,57,54,20,0,0,1,0,9,0,100,111,116,0,1,1,0,9,97,0,0,1,1,0,9,98,0,0,0,1,9, +18,95,95,114,101,116,86,97,108,0,18,97,0,18,98,0,48,20,0,0,1,0,9,0,100,111,116,0,1,1,0,10,97,0,0,1, +1,0,10,98,0,0,0,1,9,18,95,95,114,101,116,86,97,108,0,18,97,0,59,120,0,18,98,0,59,120,0,48,18,97,0, +59,121,0,18,98,0,59,121,0,48,46,20,0,0,1,0,9,0,100,111,116,0,1,1,0,11,97,0,0,1,1,0,11,98,0,0,0,1,4, +118,101,99,51,95,100,111,116,0,18,95,95,114,101,116,86,97,108,0,0,18,97,0,0,18,98,0,0,0,0,1,0,9,0, +100,111,116,0,1,1,0,12,97,0,0,1,1,0,12,98,0,0,0,1,4,118,101,99,52,95,100,111,116,0,18,95,95,114, +101,116,86,97,108,0,0,18,97,0,0,18,98,0,0,0,0,1,0,0,2,1,1,0,2,5,97,0,0,1,1,0,5,98,0,0,0,1,4,118, +101,99,52,95,97,100,100,0,18,97,0,0,18,97,0,0,18,98,0,0,0,0,1,0,0,2,2,1,0,2,5,97,0,0,1,1,0,5,98,0, +0,0,1,4,118,101,99,52,95,115,117,98,116,114,97,99,116,0,18,97,0,0,18,97,0,0,18,98,0,0,0,0,1,0,0,2, +3,1,0,2,5,97,0,0,1,1,0,5,98,0,0,0,1,4,118,101,99,52,95,109,117,108,116,105,112,108,121,0,18,97,0,0, +18,97,0,0,18,98,0,0,0,0,1,0,0,2,4,1,0,2,5,97,0,0,1,1,0,5,98,0,0,0,1,3,2,0,9,1,105,110,118,66,0,0,0, +4,102,108,111,97,116,95,114,99,112,0,18,105,110,118,66,0,0,18,98,0,0,0,4,118,101,99,52,95,109,117, +108,116,105,112,108,121,0,18,97,0,0,18,97,0,0,18,105,110,118,66,0,0,0,0,1,0,0,2,1,1,0,2,6,118,0,0, +1,1,0,6,117,0,0,0,1,4,118,101,99,52,95,97,100,100,0,18,118,0,0,18,118,0,0,18,117,0,0,0,0,1,0,0,2,2, +1,0,2,6,118,0,0,1,1,0,6,117,0,0,0,1,4,118,101,99,52,95,115,117,98,116,114,97,99,116,0,18,118,0,0, +18,118,0,0,18,117,0,0,0,0,1,0,0,2,3,1,0,2,6,118,0,0,1,1,0,6,117,0,0,0,1,4,118,101,99,52,95,109,117, +108,116,105,112,108,121,0,18,118,0,0,18,118,0,0,18,117,0,0,0,0,1,0,0,2,4,1,0,2,6,118,0,0,1,1,0,6, +117,0,0,0,1,3,2,0,6,1,105,110,118,0,0,1,1,122,0,0,0,4,102,108,111,97,116,95,114,99,112,0,18,105, +110,118,0,59,120,0,0,18,117,0,59,120,0,0,0,4,102,108,111,97,116,95,114,99,112,0,18,105,110,118,0, +59,121,0,0,18,117,0,59,121,0,0,0,4,118,101,99,52,95,109,117,108,116,105,112,108,121,0,18,122,0,0, +18,118,0,0,18,105,110,118,0,0,0,4,102,108,111,97,116,95,116,111,95,105,110,116,0,18,95,95,114,101, +116,86,97,108,0,0,18,122,0,0,0,0,1,0,0,2,1,1,0,2,7,118,0,0,1,1,0,7,117,0,0,0,1,4,118,101,99,52,95, +97,100,100,0,18,118,0,0,18,118,0,0,18,117,0,0,0,0,1,0,0,2,2,1,0,2,7,118,0,0,1,1,0,7,117,0,0,0,1,4, +118,101,99,52,95,115,117,98,116,114,97,99,116,0,18,118,0,0,18,118,0,0,18,117,0,0,0,0,1,0,0,2,3,1,0, +2,7,118,0,0,1,1,0,7,117,0,0,0,1,4,118,101,99,52,95,109,117,108,116,105,112,108,121,0,18,118,0,0,18, +118,0,0,18,117,0,0,0,0,1,0,0,2,4,1,0,2,7,118,0,0,1,1,0,7,117,0,0,0,1,3,2,0,7,1,105,110,118,0,0,1,1, +122,0,0,0,4,102,108,111,97,116,95,114,99,112,0,18,105,110,118,0,59,120,0,0,18,117,0,59,120,0,0,0,4, +102,108,111,97,116,95,114,99,112,0,18,105,110,118,0,59,121,0,0,18,117,0,59,121,0,0,0,4,118,101,99, +52,95,109,117,108,116,105,112,108,121,0,18,122,0,0,18,118,0,0,18,105,110,118,0,0,0,4,102,108,111, +97,116,95,116,111,95,105,110,116,0,18,95,95,114,101,116,86,97,108,0,0,18,122,0,0,0,0,1,0,0,2,1,1,0, +2,8,118,0,0,1,1,0,8,117,0,0,0,1,4,118,101,99,52,95,97,100,100,0,18,118,0,0,18,118,0,0,18,117,0,0,0, +0,1,0,0,2,2,1,0,2,8,118,0,0,1,1,0,8,117,0,0,0,1,4,118,101,99,52,95,115,117,98,116,114,97,99,116,0, +18,118,0,0,18,118,0,0,18,117,0,0,0,0,1,0,0,2,3,1,0,2,8,118,0,0,1,1,0,8,117,0,0,0,1,4,118,101,99,52, +95,109,117,108,116,105,112,108,121,0,18,118,0,0,18,118,0,0,18,117,0,0,0,0,1,0,0,2,4,1,0,2,8,118,0, +0,1,1,0,8,117,0,0,0,1,3,2,0,8,1,105,110,118,0,0,1,1,122,0,0,0,4,102,108,111,97,116,95,114,99,112,0, +18,105,110,118,0,59,120,0,0,18,117,0,59,120,0,0,0,4,102,108,111,97,116,95,114,99,112,0,18,105,110, +118,0,59,121,0,0,18,117,0,59,121,0,0,0,4,118,101,99,52,95,109,117,108,116,105,112,108,121,0,18,122, +0,0,18,118,0,0,18,105,110,118,0,0,0,4,102,108,111,97,116,95,116,111,95,105,110,116,0,18,95,95,114, +101,116,86,97,108,0,0,18,122,0,0,0,0,1,0,0,2,1,1,0,2,9,97,0,0,1,1,0,9,98,0,0,0,1,4,118,101,99,52, +95,97,100,100,0,18,97,0,59,120,0,0,18,97,0,59,120,0,0,18,98,0,0,0,0,1,0,0,2,2,1,0,2,9,97,0,0,1,1,0, +9,98,0,0,0,1,4,118,101,99,52,95,115,117,98,116,114,97,99,116,0,18,97,0,59,120,0,0,18,97,0,0,18,98, +0,0,0,0,1,0,0,2,3,1,0,2,9,97,0,0,1,1,0,9,98,0,0,0,1,4,118,101,99,52,95,109,117,108,116,105,112,108, +121,0,18,97,0,59,120,0,0,18,97,0,0,18,98,0,0,0,0,1,0,0,2,4,1,0,2,9,97,0,0,1,1,0,9,98,0,0,0,1,3,2,0, +9,1,119,0,0,0,4,102,108,111,97,116,95,114,99,112,0,18,119,0,59,120,0,0,18,98,0,0,0,4,118,101,99,52, +95,109,117,108,116,105,112,108,121,0,18,97,0,59,120,0,0,18,97,0,0,18,119,0,0,0,0,1,0,0,2,1,1,0,2, +10,118,0,0,1,1,0,10,117,0,0,0,1,4,118,101,99,52,95,97,100,100,0,18,118,0,59,120,121,0,0,18,118,0, +59,120,121,0,0,18,117,0,59,120,121,0,0,0,0,1,0,0,2,2,1,0,2,10,118,0,0,1,1,0,10,117,0,0,0,1,4,118, +101,99,52,95,115,117,98,116,114,97,99,116,0,18,118,0,59,120,121,0,0,18,118,0,59,120,121,0,0,18,117, +0,59,120,121,0,0,0,0,1,0,0,2,3,1,0,2,10,118,0,0,1,1,0,10,117,0,0,0,1,4,118,101,99,52,95,109,117, +108,116,105,112,108,121,0,18,118,0,59,120,121,0,0,18,118,0,59,120,121,0,0,18,117,0,59,120,121,0,0, +0,0,1,0,0,2,4,1,0,2,10,118,0,0,1,1,0,10,117,0,0,0,1,3,2,0,10,1,119,0,0,0,4,102,108,111,97,116,95, +114,99,112,0,18,119,0,59,120,0,0,18,117,0,59,120,0,0,0,4,102,108,111,97,116,95,114,99,112,0,18,119, +0,59,121,0,0,18,117,0,59,121,0,0,0,4,118,101,99,52,95,109,117,108,116,105,112,108,121,0,18,118,0, +59,120,121,0,0,18,118,0,59,120,121,0,0,18,119,0,59,120,121,0,0,0,0,1,0,0,2,1,1,0,2,11,118,0,0,1,1, +0,11,117,0,0,0,1,4,118,101,99,52,95,97,100,100,0,18,118,0,59,120,121,122,0,0,18,118,0,0,18,117,0,0, +0,0,1,0,0,2,2,1,0,2,11,118,0,0,1,1,0,11,117,0,0,0,1,4,118,101,99,52,95,115,117,98,116,114,97,99, +116,0,18,118,0,59,120,121,122,0,0,18,118,0,0,18,117,0,0,0,0,1,0,0,2,3,1,0,2,11,118,0,0,1,1,0,11, +117,0,0,0,1,4,118,101,99,52,95,109,117,108,116,105,112,108,121,0,18,118,0,59,120,121,122,0,0,18, +118,0,0,18,117,0,0,0,0,1,0,0,2,4,1,0,2,11,118,0,0,1,1,0,11,117,0,0,0,1,3,2,0,11,1,119,0,0,0,4,102, +108,111,97,116,95,114,99,112,0,18,119,0,59,120,0,0,18,117,0,59,120,0,0,0,4,102,108,111,97,116,95, +114,99,112,0,18,119,0,59,121,0,0,18,117,0,59,121,0,0,0,4,102,108,111,97,116,95,114,99,112,0,18,119, +0,59,122,0,0,18,117,0,59,122,0,0,0,4,118,101,99,52,95,109,117,108,116,105,112,108,121,0,18,118,0, +59,120,121,122,0,0,18,118,0,59,120,121,122,0,0,18,119,0,59,120,121,122,0,0,0,0,1,0,0,2,1,1,0,2,12, +118,0,0,1,1,0,12,117,0,0,0,1,4,118,101,99,52,95,97,100,100,0,18,118,0,0,18,118,0,0,18,117,0,0,0,0, +1,0,0,2,2,1,0,2,12,118,0,0,1,1,0,12,117,0,0,0,1,4,118,101,99,52,95,115,117,98,116,114,97,99,116,0, +18,118,0,0,18,118,0,0,18,117,0,0,0,0,1,0,0,2,3,1,0,2,12,118,0,0,1,1,0,12,117,0,0,0,1,4,118,101,99, +52,95,109,117,108,116,105,112,108,121,0,18,118,0,0,18,118,0,0,18,117,0,0,0,0,1,0,0,2,4,1,0,2,12, +118,0,0,1,1,0,12,117,0,0,0,1,3,2,0,12,1,119,0,0,0,4,102,108,111,97,116,95,114,99,112,0,18,119,0,59, +120,0,0,18,117,0,59,120,0,0,0,4,102,108,111,97,116,95,114,99,112,0,18,119,0,59,121,0,0,18,117,0,59, +121,0,0,0,4,102,108,111,97,116,95,114,99,112,0,18,119,0,59,122,0,0,18,117,0,59,122,0,0,0,4,102,108, +111,97,116,95,114,99,112,0,18,119,0,59,119,0,0,18,117,0,59,119,0,0,0,4,118,101,99,52,95,109,117, +108,116,105,112,108,121,0,18,118,0,0,18,118,0,0,18,119,0,0,0,0,1,0,0,2,1,1,0,2,6,118,0,0,1,1,0,5, +97,0,0,0,1,4,118,101,99,52,95,97,100,100,0,18,118,0,59,120,121,0,0,18,118,0,59,120,121,0,0,18,97,0, +59,120,120,0,0,0,0,1,0,0,2,2,1,0,2,6,118,0,0,1,1,0,5,97,0,0,0,1,4,118,101,99,52,95,115,117,98,116, +114,97,99,116,0,18,118,0,59,120,121,0,0,18,118,0,59,120,121,0,0,18,97,0,59,120,120,0,0,0,0,1,0,0,2, +3,1,0,2,6,118,0,0,1,1,0,5,97,0,0,0,1,4,118,101,99,52,95,109,117,108,116,105,112,108,121,0,18,118,0, +59,120,121,0,0,18,118,0,59,120,121,0,0,18,97,0,59,120,120,0,0,0,9,18,118,0,59,120,0,18,97,0,23,0,9, +18,118,0,59,121,0,18,97,0,23,0,0,1,0,0,2,4,1,0,2,6,118,0,0,1,1,0,5,97,0,0,0,1,9,18,118,0,59,120,0, +18,97,0,24,0,9,18,118,0,59,121,0,18,97,0,24,0,0,1,0,0,2,1,1,0,2,7,118,0,0,1,1,0,5,97,0,0,0,1,4,118, +101,99,52,95,97,100,100,0,18,118,0,59,120,121,122,0,0,18,118,0,59,120,121,122,0,0,18,97,0,59,120, +120,120,0,0,0,0,1,0,0,2,2,1,0,2,7,118,0,0,1,1,0,5,97,0,0,0,1,4,118,101,99,52,95,115,117,98,116,114, +97,99,116,0,18,118,0,59,120,121,122,0,0,18,118,0,59,120,121,122,0,0,18,97,0,59,120,120,120,0,0,0,0, +1,0,0,2,3,1,0,2,7,118,0,0,1,1,0,5,97,0,0,0,1,4,118,101,99,52,95,109,117,108,116,105,112,108,121,0, +18,118,0,59,120,121,122,0,0,18,118,0,59,120,121,122,0,0,18,97,0,59,120,120,120,0,0,0,0,1,0,0,2,4,1, +0,2,7,118,0,0,1,1,0,5,97,0,0,0,1,9,18,118,0,59,120,0,18,97,0,24,0,9,18,118,0,59,121,0,18,97,0,24,0, +9,18,118,0,59,122,0,18,97,0,24,0,0,1,0,0,2,1,1,0,2,8,118,0,0,1,1,0,5,97,0,0,0,1,4,118,101,99,52,95, +97,100,100,0,18,118,0,0,18,118,0,0,18,97,0,59,120,120,120,120,0,0,0,0,1,0,0,2,2,1,0,2,8,118,0,0,1, +1,0,5,97,0,0,0,1,4,118,101,99,52,95,115,117,98,116,114,97,99,116,0,18,118,0,0,18,118,0,0,18,97,0, +59,120,120,120,120,0,0,0,0,1,0,0,2,3,1,0,2,8,118,0,0,1,1,0,5,97,0,0,0,1,4,118,101,99,52,95,109,117, +108,116,105,112,108,121,0,18,118,0,0,18,118,0,0,18,97,0,59,120,120,120,120,0,0,0,0,1,0,0,2,4,1,0,2, +8,118,0,0,1,1,0,5,97,0,0,0,1,9,18,118,0,59,120,0,18,97,0,24,0,9,18,118,0,59,121,0,18,97,0,24,0,9, +18,118,0,59,122,0,18,97,0,24,0,9,18,118,0,59,119,0,18,97,0,24,0,0,1,0,0,2,1,1,0,2,10,118,0,0,1,1,0, +9,97,0,0,0,1,4,118,101,99,52,95,97,100,100,0,18,118,0,59,120,121,0,0,18,118,0,0,18,97,0,59,120,120, +0,0,0,0,1,0,0,2,2,1,0,2,10,118,0,0,1,1,0,9,97,0,0,0,1,4,118,101,99,52,95,115,117,98,116,114,97,99, +116,0,18,118,0,59,120,121,0,0,18,118,0,0,18,97,0,59,120,120,0,0,0,0,1,0,0,2,3,1,0,2,10,118,0,0,1,1, +0,9,97,0,0,0,1,4,118,101,99,52,95,109,117,108,116,105,112,108,121,0,18,118,0,59,120,121,0,0,18,118, +0,0,18,97,0,59,120,120,0,0,0,0,1,0,0,2,4,1,0,2,10,118,0,0,1,1,0,9,97,0,0,0,1,3,2,0,9,1,105,110,118, +65,0,0,0,4,102,108,111,97,116,95,114,99,112,0,18,105,110,118,65,0,0,18,97,0,0,0,4,118,101,99,52,95, +109,117,108,116,105,112,108,121,0,18,118,0,59,120,121,0,0,18,118,0,59,120,121,0,0,18,97,0,59,120, +120,0,0,0,0,1,0,0,2,1,1,0,2,11,118,0,0,1,1,0,9,97,0,0,0,1,4,118,101,99,52,95,97,100,100,0,18,118,0, +59,120,121,122,0,0,18,118,0,0,18,97,0,59,120,120,120,0,0,0,0,1,0,0,2,2,1,0,2,11,118,0,0,1,1,0,9,97, +0,0,0,1,4,118,101,99,52,95,115,117,98,116,114,97,99,116,0,18,118,0,59,120,121,122,0,0,18,118,0,0, +18,97,0,59,120,120,120,0,0,0,0,1,0,0,2,3,1,0,2,11,118,0,0,1,1,0,9,97,0,0,0,1,4,118,101,99,52,95, +109,117,108,116,105,112,108,121,0,18,118,0,59,120,121,122,0,0,18,118,0,0,18,97,0,59,120,120,120,0, +0,0,0,1,0,0,2,4,1,0,2,11,118,0,0,1,1,0,9,97,0,0,0,1,3,2,0,9,1,105,110,118,65,0,0,0,4,102,108,111, +97,116,95,114,99,112,0,18,105,110,118,65,0,0,18,97,0,0,0,4,118,101,99,52,95,109,117,108,116,105, +112,108,121,0,18,118,0,59,120,121,122,0,0,18,118,0,59,120,121,122,0,0,18,97,0,59,120,120,120,0,0,0, +0,1,0,0,2,1,1,0,2,12,118,0,0,1,1,0,9,97,0,0,0,1,4,118,101,99,52,95,97,100,100,0,18,118,0,0,18,118, +0,0,18,97,0,59,120,120,120,120,0,0,0,0,1,0,0,2,2,1,0,2,12,118,0,0,1,1,0,9,97,0,0,0,1,4,118,101,99, +52,95,115,117,98,116,114,97,99,116,0,18,118,0,0,18,118,0,0,18,97,0,59,120,120,120,120,0,0,0,0,1,0, +0,2,3,1,0,2,12,118,0,0,1,1,0,9,97,0,0,0,1,4,118,101,99,52,95,109,117,108,116,105,112,108,121,0,18, +118,0,0,18,118,0,0,18,97,0,59,120,120,120,120,0,0,0,0,1,0,0,2,4,1,0,2,12,118,0,0,1,1,0,9,97,0,0,0, +1,3,2,0,9,1,105,110,118,65,0,0,0,4,102,108,111,97,116,95,114,99,112,0,18,105,110,118,65,0,0,18,97, +0,0,0,4,118,101,99,52,95,109,117,108,116,105,112,108,121,0,18,118,0,0,18,118,0,0,18,97,0,59,120, +120,120,120,0,0,0,0,1,0,13,2,26,1,1,0,13,109,0,0,1,1,0,13,110,0,0,0,1,9,18,95,95,114,101,116,86,97, +108,0,16,8,48,0,57,18,109,0,16,8,48,0,57,18,110,0,16,8,48,0,57,46,20,0,9,18,95,95,114,101,116,86, +97,108,0,16,10,49,0,57,18,109,0,16,10,49,0,57,18,110,0,16,10,49,0,57,46,20,0,0,1,0,13,2,27,1,1,0, +13,109,0,0,1,1,0,13,110,0,0,0,1,9,18,95,95,114,101,116,86,97,108,0,16,8,48,0,57,18,109,0,16,8,48,0, +57,18,110,0,16,8,48,0,57,47,20,0,9,18,95,95,114,101,116,86,97,108,0,16,10,49,0,57,18,109,0,16,10, +49,0,57,18,110,0,16,10,49,0,57,47,20,0,0,1,0,13,2,21,1,1,0,13,109,0,0,1,1,0,13,110,0,0,0,1,3,2,0, +10,1,109,82,111,119,48,0,0,1,1,109,82,111,119,49,0,0,0,9,18,109,82,111,119,48,0,59,120,0,18,109,0, +16,8,48,0,57,59,120,0,20,0,9,18,109,82,111,119,48,0,59,121,0,18,109,0,16,10,49,0,57,59,120,0,20,0, +9,18,109,82,111,119,49,0,59,120,0,18,109,0,16,8,48,0,57,59,121,0,20,0,9,18,109,82,111,119,49,0,59, +121,0,18,109,0,16,10,49,0,57,59,121,0,20,0,9,18,95,95,114,101,116,86,97,108,0,16,8,48,0,57,59,120, +0,58,100,111,116,0,18,109,82,111,119,48,0,0,18,110,0,16,8,48,0,57,0,0,20,0,9,18,95,95,114,101,116, +86,97,108,0,16,10,49,0,57,59,120,0,58,100,111,116,0,18,109,82,111,119,48,0,0,18,110,0,16,10,49,0, +57,0,0,20,0,9,18,95,95,114,101,116,86,97,108,0,16,8,48,0,57,59,121,0,58,100,111,116,0,18,109,82, +111,119,49,0,0,18,110,0,16,8,48,0,57,0,0,20,0,9,18,95,95,114,101,116,86,97,108,0,16,10,49,0,57,59, +121,0,58,100,111,116,0,18,109,82,111,119,49,0,0,18,110,0,16,10,49,0,57,0,0,20,0,0,1,0,13,2,22,1,1, +0,13,109,0,0,1,1,0,13,110,0,0,0,1,9,18,95,95,114,101,116,86,97,108,0,16,8,48,0,57,18,109,0,16,8,48, +0,57,18,110,0,16,8,48,0,57,49,20,0,9,18,95,95,114,101,116,86,97,108,0,16,10,49,0,57,18,109,0,16,10, +49,0,57,18,110,0,16,10,49,0,57,49,20,0,0,1,0,14,2,26,1,1,0,14,109,0,0,1,1,0,14,110,0,0,0,1,9,18,95, +95,114,101,116,86,97,108,0,16,8,48,0,57,18,109,0,16,8,48,0,57,18,110,0,16,8,48,0,57,46,20,0,9,18, +95,95,114,101,116,86,97,108,0,16,10,49,0,57,18,109,0,16,10,49,0,57,18,110,0,16,10,49,0,57,46,20,0, +9,18,95,95,114,101,116,86,97,108,0,16,10,50,0,57,18,109,0,16,10,50,0,57,18,110,0,16,10,50,0,57,46, +20,0,0,1,0,14,2,27,1,1,0,14,109,0,0,1,1,0,14,110,0,0,0,1,9,18,95,95,114,101,116,86,97,108,0,16,8, +48,0,57,18,109,0,16,8,48,0,57,18,110,0,16,8,48,0,57,47,20,0,9,18,95,95,114,101,116,86,97,108,0,16, +10,49,0,57,18,109,0,16,10,49,0,57,18,110,0,16,10,49,0,57,47,20,0,9,18,95,95,114,101,116,86,97,108, +0,16,10,50,0,57,18,109,0,16,10,50,0,57,18,110,0,16,10,50,0,57,47,20,0,0,1,0,14,2,21,1,1,0,14,109,0, +0,1,1,0,14,110,0,0,0,1,2,3,2,0,11,1,109,82,111,119,48,0,0,0,9,18,109,82,111,119,48,0,59,120,0,18, +109,0,16,8,48,0,57,59,120,0,20,0,9,18,109,82,111,119,48,0,59,121,0,18,109,0,16,10,49,0,57,59,120,0, +20,0,9,18,109,82,111,119,48,0,59,122,0,18,109,0,16,10,50,0,57,59,120,0,20,0,9,18,95,95,114,101,116, +86,97,108,0,16,8,48,0,57,59,120,0,58,100,111,116,0,18,109,82,111,119,48,0,0,18,110,0,16,8,48,0,57, +0,0,20,0,9,18,95,95,114,101,116,86,97,108,0,16,10,49,0,57,59,120,0,58,100,111,116,0,18,109,82,111, +119,48,0,0,18,110,0,16,10,49,0,57,0,0,20,0,9,18,95,95,114,101,116,86,97,108,0,16,10,50,0,57,59,120, +0,58,100,111,116,0,18,109,82,111,119,48,0,0,18,110,0,16,10,50,0,57,0,0,20,0,0,2,3,2,0,11,1,109,82, +111,119,49,0,0,0,9,18,109,82,111,119,49,0,59,120,0,18,109,0,16,8,48,0,57,59,121,0,20,0,9,18,109,82, +111,119,49,0,59,121,0,18,109,0,16,10,49,0,57,59,121,0,20,0,9,18,109,82,111,119,49,0,59,122,0,18, +109,0,16,10,50,0,57,59,121,0,20,0,9,18,95,95,114,101,116,86,97,108,0,16,8,48,0,57,59,121,0,58,100, +111,116,0,18,109,82,111,119,49,0,0,18,110,0,16,8,48,0,57,0,0,20,0,9,18,95,95,114,101,116,86,97,108, +0,16,10,49,0,57,59,121,0,58,100,111,116,0,18,109,82,111,119,49,0,0,18,110,0,16,10,49,0,57,0,0,20,0, +9,18,95,95,114,101,116,86,97,108,0,16,10,50,0,57,59,121,0,58,100,111,116,0,18,109,82,111,119,49,0, +0,18,110,0,16,10,50,0,57,0,0,20,0,0,2,3,2,0,11,1,109,82,111,119,50,0,0,0,9,18,109,82,111,119,50,0, +59,120,0,18,109,0,16,8,48,0,57,59,122,0,20,0,9,18,109,82,111,119,50,0,59,121,0,18,109,0,16,10,49,0, +57,59,122,0,20,0,9,18,109,82,111,119,50,0,59,122,0,18,109,0,16,10,50,0,57,59,122,0,20,0,9,18,95,95, +114,101,116,86,97,108,0,16,8,48,0,57,59,122,0,58,100,111,116,0,18,109,82,111,119,50,0,0,18,110,0, +16,8,48,0,57,0,0,20,0,9,18,95,95,114,101,116,86,97,108,0,16,10,49,0,57,59,122,0,58,100,111,116,0, +18,109,82,111,119,50,0,0,18,110,0,16,10,49,0,57,0,0,20,0,9,18,95,95,114,101,116,86,97,108,0,16,10, +50,0,57,59,122,0,58,100,111,116,0,18,109,82,111,119,50,0,0,18,110,0,16,10,50,0,57,0,0,20,0,0,0,1,0, +14,2,22,1,1,0,14,109,0,0,1,1,0,14,110,0,0,0,1,9,18,95,95,114,101,116,86,97,108,0,16,8,48,0,57,18, +109,0,16,8,48,0,57,18,110,0,16,8,48,0,57,49,20,0,9,18,95,95,114,101,116,86,97,108,0,16,10,49,0,57, +18,109,0,16,10,49,0,57,18,110,0,16,10,49,0,57,49,20,0,9,18,95,95,114,101,116,86,97,108,0,16,10,50, +0,57,18,109,0,16,10,50,0,57,18,110,0,16,10,50,0,57,49,20,0,0,1,0,15,2,26,1,1,0,15,109,0,0,1,1,0,15, +110,0,0,0,1,9,18,95,95,114,101,116,86,97,108,0,16,8,48,0,57,18,109,0,16,8,48,0,57,18,110,0,16,8,48, +0,57,46,20,0,9,18,95,95,114,101,116,86,97,108,0,16,10,49,0,57,18,109,0,16,10,49,0,57,18,110,0,16, +10,49,0,57,46,20,0,9,18,95,95,114,101,116,86,97,108,0,16,10,50,0,57,18,109,0,16,10,50,0,57,18,110, +0,16,10,50,0,57,46,20,0,9,18,95,95,114,101,116,86,97,108,0,16,10,51,0,57,18,109,0,16,10,51,0,57,18, +110,0,16,10,51,0,57,46,20,0,0,1,0,15,2,27,1,1,0,15,109,0,0,1,1,0,15,110,0,0,0,1,9,18,95,95,114,101, +116,86,97,108,0,16,8,48,0,57,18,109,0,16,8,48,0,57,18,110,0,16,8,48,0,57,47,20,0,9,18,95,95,114, +101,116,86,97,108,0,16,10,49,0,57,18,109,0,16,10,49,0,57,18,110,0,16,10,49,0,57,47,20,0,9,18,95,95, +114,101,116,86,97,108,0,16,10,50,0,57,18,109,0,16,10,50,0,57,18,110,0,16,10,50,0,57,47,20,0,9,18, +95,95,114,101,116,86,97,108,0,16,10,51,0,57,18,109,0,16,10,51,0,57,18,110,0,16,10,51,0,57,47,20,0, +0,1,0,15,2,21,1,1,0,15,109,0,0,1,1,0,15,110,0,0,0,1,2,3,2,0,12,1,109,82,111,119,48,0,0,0,9,18,109, +82,111,119,48,0,59,120,0,18,109,0,16,8,48,0,57,59,120,0,20,0,9,18,109,82,111,119,48,0,59,121,0,18, +109,0,16,10,49,0,57,59,120,0,20,0,9,18,109,82,111,119,48,0,59,122,0,18,109,0,16,10,50,0,57,59,120, +0,20,0,9,18,109,82,111,119,48,0,59,119,0,18,109,0,16,10,51,0,57,59,120,0,20,0,9,18,95,95,114,101, +116,86,97,108,0,16,8,48,0,57,59,120,0,58,100,111,116,0,18,109,82,111,119,48,0,0,18,110,0,16,8,48,0, +57,0,0,20,0,9,18,95,95,114,101,116,86,97,108,0,16,10,49,0,57,59,120,0,58,100,111,116,0,18,109,82, +111,119,48,0,0,18,110,0,16,10,49,0,57,0,0,20,0,9,18,95,95,114,101,116,86,97,108,0,16,10,50,0,57,59, +120,0,58,100,111,116,0,18,109,82,111,119,48,0,0,18,110,0,16,10,50,0,57,0,0,20,0,9,18,95,95,114,101, +116,86,97,108,0,16,10,51,0,57,59,120,0,58,100,111,116,0,18,109,82,111,119,48,0,0,18,110,0,16,10,51, +0,57,0,0,20,0,0,2,3,2,0,12,1,109,82,111,119,49,0,0,0,9,18,109,82,111,119,49,0,59,120,0,18,109,0,16, +8,48,0,57,59,121,0,20,0,9,18,109,82,111,119,49,0,59,121,0,18,109,0,16,10,49,0,57,59,121,0,20,0,9, +18,109,82,111,119,49,0,59,122,0,18,109,0,16,10,50,0,57,59,121,0,20,0,9,18,109,82,111,119,49,0,59, +119,0,18,109,0,16,10,51,0,57,59,121,0,20,0,9,18,95,95,114,101,116,86,97,108,0,16,8,48,0,57,59,121, +0,58,100,111,116,0,18,109,82,111,119,49,0,0,18,110,0,16,8,48,0,57,0,0,20,0,9,18,95,95,114,101,116, +86,97,108,0,16,10,49,0,57,59,121,0,58,100,111,116,0,18,109,82,111,119,49,0,0,18,110,0,16,10,49,0, +57,0,0,20,0,9,18,95,95,114,101,116,86,97,108,0,16,10,50,0,57,59,121,0,58,100,111,116,0,18,109,82, +111,119,49,0,0,18,110,0,16,10,50,0,57,0,0,20,0,9,18,95,95,114,101,116,86,97,108,0,16,10,51,0,57,59, +121,0,58,100,111,116,0,18,109,82,111,119,49,0,0,18,110,0,16,10,51,0,57,0,0,20,0,0,2,3,2,0,12,1,109, +82,111,119,50,0,0,0,9,18,109,82,111,119,50,0,59,120,0,18,109,0,16,8,48,0,57,59,122,0,20,0,9,18,109, +82,111,119,50,0,59,121,0,18,109,0,16,10,49,0,57,59,122,0,20,0,9,18,109,82,111,119,50,0,59,122,0,18, +109,0,16,10,50,0,57,59,122,0,20,0,9,18,109,82,111,119,50,0,59,119,0,18,109,0,16,10,51,0,57,59,122, +0,20,0,9,18,95,95,114,101,116,86,97,108,0,16,8,48,0,57,59,122,0,58,100,111,116,0,18,109,82,111,119, +50,0,0,18,110,0,16,8,48,0,57,0,0,20,0,9,18,95,95,114,101,116,86,97,108,0,16,10,49,0,57,59,122,0,58, +100,111,116,0,18,109,82,111,119,50,0,0,18,110,0,16,10,49,0,57,0,0,20,0,9,18,95,95,114,101,116,86, +97,108,0,16,10,50,0,57,59,122,0,58,100,111,116,0,18,109,82,111,119,50,0,0,18,110,0,16,10,50,0,57,0, +0,20,0,9,18,95,95,114,101,116,86,97,108,0,16,10,51,0,57,59,122,0,58,100,111,116,0,18,109,82,111, +119,50,0,0,18,110,0,16,10,51,0,57,0,0,20,0,0,2,3,2,0,12,1,109,82,111,119,51,0,0,0,9,18,109,82,111, +119,51,0,59,120,0,18,109,0,16,8,48,0,57,59,119,0,20,0,9,18,109,82,111,119,51,0,59,121,0,18,109,0, +16,10,49,0,57,59,119,0,20,0,9,18,109,82,111,119,51,0,59,122,0,18,109,0,16,10,50,0,57,59,119,0,20,0, +9,18,109,82,111,119,51,0,59,119,0,18,109,0,16,10,51,0,57,59,119,0,20,0,9,18,95,95,114,101,116,86, +97,108,0,16,8,48,0,57,59,119,0,58,100,111,116,0,18,109,82,111,119,51,0,0,18,110,0,16,8,48,0,57,0,0, +20,0,9,18,95,95,114,101,116,86,97,108,0,16,10,49,0,57,59,119,0,58,100,111,116,0,18,109,82,111,119, +51,0,0,18,110,0,16,10,49,0,57,0,0,20,0,9,18,95,95,114,101,116,86,97,108,0,16,10,50,0,57,59,119,0, +58,100,111,116,0,18,109,82,111,119,51,0,0,18,110,0,16,10,50,0,57,0,0,20,0,9,18,95,95,114,101,116, +86,97,108,0,16,10,51,0,57,59,119,0,58,100,111,116,0,18,109,82,111,119,51,0,0,18,110,0,16,10,51,0, +57,0,0,20,0,0,0,1,0,15,2,22,1,1,0,15,109,0,0,1,1,0,15,110,0,0,0,1,9,18,95,95,114,101,116,86,97,108, +0,16,8,48,0,57,18,109,0,16,8,48,0,57,18,110,0,16,8,48,0,57,49,20,0,9,18,95,95,114,101,116,86,97, +108,0,16,10,49,0,57,18,109,0,16,10,49,0,57,18,110,0,16,10,49,0,57,49,20,0,9,18,95,95,114,101,116, +86,97,108,0,16,10,50,0,57,18,109,0,16,10,50,0,57,18,110,0,16,10,50,0,57,49,20,0,9,18,95,95,114,101, +116,86,97,108,0,16,10,51,0,57,18,109,0,16,10,51,0,57,18,110,0,16,10,51,0,57,49,20,0,0,1,0,13,2,26, +1,1,0,9,97,0,0,1,1,0,13,110,0,0,0,1,9,18,95,95,114,101,116,86,97,108,0,16,8,48,0,57,18,97,0,18,110, +0,16,8,48,0,57,46,20,0,9,18,95,95,114,101,116,86,97,108,0,16,10,49,0,57,18,97,0,18,110,0,16,10,49, +0,57,46,20,0,0,1,0,13,2,26,1,1,0,13,109,0,0,1,1,0,9,98,0,0,0,1,9,18,95,95,114,101,116,86,97,108,0, +16,8,48,0,57,18,109,0,16,8,48,0,57,18,98,0,46,20,0,9,18,95,95,114,101,116,86,97,108,0,16,10,49,0, +57,18,109,0,16,10,49,0,57,18,98,0,46,20,0,0,1,0,13,2,27,1,1,0,9,97,0,0,1,1,0,13,110,0,0,0,1,9,18, +95,95,114,101,116,86,97,108,0,16,8,48,0,57,18,97,0,18,110,0,16,8,48,0,57,47,20,0,9,18,95,95,114, +101,116,86,97,108,0,16,10,49,0,57,18,97,0,18,110,0,16,10,49,0,57,47,20,0,0,1,0,13,2,27,1,1,0,13, +109,0,0,1,1,0,9,98,0,0,0,1,9,18,95,95,114,101,116,86,97,108,0,16,8,48,0,57,18,109,0,16,8,48,0,57, +18,98,0,47,20,0,9,18,95,95,114,101,116,86,97,108,0,16,10,49,0,57,18,109,0,16,10,49,0,57,18,98,0,47, +20,0,0,1,0,13,2,21,1,1,0,9,97,0,0,1,1,0,13,110,0,0,0,1,9,18,95,95,114,101,116,86,97,108,0,16,8,48, +0,57,18,97,0,18,110,0,16,8,48,0,57,48,20,0,9,18,95,95,114,101,116,86,97,108,0,16,10,49,0,57,18,97, +0,18,110,0,16,10,49,0,57,48,20,0,0,1,0,13,2,21,1,1,0,13,109,0,0,1,1,0,9,98,0,0,0,1,9,18,95,95,114, +101,116,86,97,108,0,16,8,48,0,57,18,109,0,16,8,48,0,57,18,98,0,48,20,0,9,18,95,95,114,101,116,86, +97,108,0,16,10,49,0,57,18,109,0,16,10,49,0,57,18,98,0,48,20,0,0,1,0,13,2,22,1,1,0,9,97,0,0,1,1,0, +13,110,0,0,0,1,9,18,95,95,114,101,116,86,97,108,0,16,8,48,0,57,18,97,0,18,110,0,16,8,48,0,57,49,20, +0,9,18,95,95,114,101,116,86,97,108,0,16,10,49,0,57,18,97,0,18,110,0,16,10,49,0,57,49,20,0,0,1,0,13, +2,22,1,1,0,13,109,0,0,1,1,0,9,98,0,0,0,1,9,18,95,95,114,101,116,86,97,108,0,16,8,48,0,57,18,109,0, +16,8,48,0,57,18,98,0,49,20,0,9,18,95,95,114,101,116,86,97,108,0,16,10,49,0,57,18,109,0,16,10,49,0, +57,18,98,0,49,20,0,0,1,0,14,2,26,1,1,0,9,97,0,0,1,1,0,14,110,0,0,0,1,9,18,95,95,114,101,116,86,97, +108,0,16,8,48,0,57,18,97,0,18,110,0,16,8,48,0,57,46,20,0,9,18,95,95,114,101,116,86,97,108,0,16,10, +49,0,57,18,97,0,18,110,0,16,10,49,0,57,46,20,0,9,18,95,95,114,101,116,86,97,108,0,16,10,50,0,57,18, +97,0,18,110,0,16,10,50,0,57,46,20,0,0,1,0,14,2,26,1,1,0,14,109,0,0,1,1,0,9,98,0,0,0,1,9,18,95,95, +114,101,116,86,97,108,0,16,8,48,0,57,18,109,0,16,8,48,0,57,18,98,0,46,20,0,9,18,95,95,114,101,116, +86,97,108,0,16,10,49,0,57,18,109,0,16,10,49,0,57,18,98,0,46,20,0,9,18,95,95,114,101,116,86,97,108, +0,16,10,50,0,57,18,109,0,16,10,50,0,57,18,98,0,46,20,0,0,1,0,14,2,27,1,1,0,9,97,0,0,1,1,0,14,110,0, +0,0,1,9,18,95,95,114,101,116,86,97,108,0,16,8,48,0,57,18,97,0,18,110,0,16,8,48,0,57,47,20,0,9,18, +95,95,114,101,116,86,97,108,0,16,10,49,0,57,18,97,0,18,110,0,16,10,49,0,57,47,20,0,9,18,95,95,114, +101,116,86,97,108,0,16,10,50,0,57,18,97,0,18,110,0,16,10,50,0,57,47,20,0,0,1,0,14,2,27,1,1,0,14, +109,0,0,1,1,0,9,98,0,0,0,1,9,18,95,95,114,101,116,86,97,108,0,16,8,48,0,57,18,109,0,16,8,48,0,57, +18,98,0,47,20,0,9,18,95,95,114,101,116,86,97,108,0,16,10,49,0,57,18,109,0,16,10,49,0,57,18,98,0,47, +20,0,9,18,95,95,114,101,116,86,97,108,0,16,10,50,0,57,18,109,0,16,10,50,0,57,18,98,0,47,20,0,0,1,0, +14,2,21,1,1,0,9,97,0,0,1,1,0,14,110,0,0,0,1,9,18,95,95,114,101,116,86,97,108,0,16,8,48,0,57,18,97, +0,18,110,0,16,8,48,0,57,48,20,0,9,18,95,95,114,101,116,86,97,108,0,16,10,49,0,57,18,97,0,18,110,0, +16,10,49,0,57,48,20,0,9,18,95,95,114,101,116,86,97,108,0,16,10,50,0,57,18,97,0,18,110,0,16,10,50,0, +57,48,20,0,0,1,0,14,2,21,1,1,0,14,109,0,0,1,1,0,9,98,0,0,0,1,9,18,95,95,114,101,116,86,97,108,0,16, +8,48,0,57,18,109,0,16,8,48,0,57,18,98,0,48,20,0,9,18,95,95,114,101,116,86,97,108,0,16,10,49,0,57, +18,109,0,16,10,49,0,57,18,98,0,48,20,0,9,18,95,95,114,101,116,86,97,108,0,16,10,50,0,57,18,109,0, +16,10,50,0,57,18,98,0,48,20,0,0,1,0,14,2,22,1,1,0,9,97,0,0,1,1,0,14,110,0,0,0,1,9,18,95,95,114,101, +116,86,97,108,0,16,8,48,0,57,18,97,0,18,110,0,16,8,48,0,57,49,20,0,9,18,95,95,114,101,116,86,97, +108,0,16,10,49,0,57,18,97,0,18,110,0,16,10,49,0,57,49,20,0,9,18,95,95,114,101,116,86,97,108,0,16, +10,50,0,57,18,97,0,18,110,0,16,10,50,0,57,49,20,0,0,1,0,14,2,22,1,1,0,14,109,0,0,1,1,0,9,98,0,0,0, +1,9,18,95,95,114,101,116,86,97,108,0,16,8,48,0,57,18,109,0,16,8,48,0,57,18,98,0,49,20,0,9,18,95,95, +114,101,116,86,97,108,0,16,10,49,0,57,18,109,0,16,10,49,0,57,18,98,0,49,20,0,9,18,95,95,114,101, +116,86,97,108,0,16,10,50,0,57,18,109,0,16,10,50,0,57,18,98,0,49,20,0,0,1,0,15,2,26,1,1,0,9,97,0,0, +1,1,0,15,110,0,0,0,1,9,18,95,95,114,101,116,86,97,108,0,16,8,48,0,57,18,97,0,18,110,0,16,8,48,0,57, +46,20,0,9,18,95,95,114,101,116,86,97,108,0,16,10,49,0,57,18,97,0,18,110,0,16,10,49,0,57,46,20,0,9, +18,95,95,114,101,116,86,97,108,0,16,10,50,0,57,18,97,0,18,110,0,16,10,50,0,57,46,20,0,9,18,95,95, +114,101,116,86,97,108,0,16,10,51,0,57,18,97,0,18,110,0,16,10,51,0,57,46,20,0,0,1,0,15,2,26,1,1,0, +15,109,0,0,1,1,0,9,98,0,0,0,1,9,18,95,95,114,101,116,86,97,108,0,16,8,48,0,57,18,109,0,16,8,48,0, +57,18,98,0,46,20,0,9,18,95,95,114,101,116,86,97,108,0,16,10,49,0,57,18,109,0,16,10,49,0,57,18,98,0, +46,20,0,9,18,95,95,114,101,116,86,97,108,0,16,10,50,0,57,18,109,0,16,10,50,0,57,18,98,0,46,20,0,9, +18,95,95,114,101,116,86,97,108,0,16,10,51,0,57,18,109,0,16,10,51,0,57,18,98,0,46,20,0,0,1,0,15,2, +27,1,1,0,9,97,0,0,1,1,0,15,110,0,0,0,1,9,18,95,95,114,101,116,86,97,108,0,16,8,48,0,57,18,97,0,18, +110,0,16,8,48,0,57,47,20,0,9,18,95,95,114,101,116,86,97,108,0,16,10,49,0,57,18,97,0,18,110,0,16,10, +49,0,57,47,20,0,9,18,95,95,114,101,116,86,97,108,0,16,10,50,0,57,18,97,0,18,110,0,16,10,50,0,57,47, +20,0,9,18,95,95,114,101,116,86,97,108,0,16,10,51,0,57,18,97,0,18,110,0,16,10,51,0,57,47,20,0,0,1,0, +15,2,27,1,1,0,15,109,0,0,1,1,0,9,98,0,0,0,1,9,18,95,95,114,101,116,86,97,108,0,16,8,48,0,57,18,109, +0,16,8,48,0,57,18,98,0,47,20,0,9,18,95,95,114,101,116,86,97,108,0,16,10,49,0,57,18,109,0,16,10,49, +0,57,18,98,0,47,20,0,9,18,95,95,114,101,116,86,97,108,0,16,10,50,0,57,18,109,0,16,10,50,0,57,18,98, +0,47,20,0,9,18,95,95,114,101,116,86,97,108,0,16,10,51,0,57,18,109,0,16,10,51,0,57,18,98,0,47,20,0, +0,1,0,15,2,21,1,1,0,9,97,0,0,1,1,0,15,110,0,0,0,1,9,18,95,95,114,101,116,86,97,108,0,16,8,48,0,57, +18,97,0,18,110,0,16,8,48,0,57,48,20,0,9,18,95,95,114,101,116,86,97,108,0,16,10,49,0,57,18,97,0,18, +110,0,16,10,49,0,57,48,20,0,9,18,95,95,114,101,116,86,97,108,0,16,10,50,0,57,18,97,0,18,110,0,16, +10,50,0,57,48,20,0,9,18,95,95,114,101,116,86,97,108,0,16,10,51,0,57,18,97,0,18,110,0,16,10,51,0,57, +48,20,0,0,1,0,15,2,21,1,1,0,15,109,0,0,1,1,0,9,98,0,0,0,1,9,18,95,95,114,101,116,86,97,108,0,16,8, +48,0,57,18,109,0,16,8,48,0,57,18,98,0,48,20,0,9,18,95,95,114,101,116,86,97,108,0,16,10,49,0,57,18, +109,0,16,10,49,0,57,18,98,0,48,20,0,9,18,95,95,114,101,116,86,97,108,0,16,10,50,0,57,18,109,0,16, +10,50,0,57,18,98,0,48,20,0,9,18,95,95,114,101,116,86,97,108,0,16,10,51,0,57,18,109,0,16,10,51,0,57, +18,98,0,48,20,0,0,1,0,15,2,22,1,1,0,9,97,0,0,1,1,0,15,110,0,0,0,1,9,18,95,95,114,101,116,86,97,108, +0,16,8,48,0,57,18,97,0,18,110,0,16,8,48,0,57,49,20,0,9,18,95,95,114,101,116,86,97,108,0,16,10,49,0, +57,18,97,0,18,110,0,16,10,49,0,57,49,20,0,9,18,95,95,114,101,116,86,97,108,0,16,10,50,0,57,18,97,0, +18,110,0,16,10,50,0,57,49,20,0,9,18,95,95,114,101,116,86,97,108,0,16,10,51,0,57,18,97,0,18,110,0, +16,10,51,0,57,49,20,0,0,1,0,15,2,22,1,1,0,15,109,0,0,1,1,0,9,98,0,0,0,1,9,18,95,95,114,101,116,86, +97,108,0,16,8,48,0,57,18,109,0,16,8,48,0,57,18,98,0,49,20,0,9,18,95,95,114,101,116,86,97,108,0,16, +10,49,0,57,18,109,0,16,10,49,0,57,18,98,0,49,20,0,9,18,95,95,114,101,116,86,97,108,0,16,10,50,0,57, +18,109,0,16,10,50,0,57,18,98,0,49,20,0,9,18,95,95,114,101,116,86,97,108,0,16,10,51,0,57,18,109,0, +16,10,51,0,57,18,98,0,49,20,0,0,1,0,10,2,21,1,1,0,13,109,0,0,1,1,0,10,118,0,0,0,1,3,2,0,10,1,114, +48,0,0,1,1,114,49,0,0,0,9,18,114,48,0,59,120,0,18,109,0,16,8,48,0,57,59,120,0,20,0,9,18,114,48,0, +59,121,0,18,109,0,16,10,49,0,57,59,120,0,20,0,9,18,114,49,0,59,120,0,18,109,0,16,8,48,0,57,59,121, +0,20,0,9,18,114,49,0,59,121,0,18,109,0,16,10,49,0,57,59,121,0,20,0,9,18,95,95,114,101,116,86,97, +108,0,59,120,0,58,100,111,116,0,18,114,48,0,0,18,118,0,0,0,20,0,9,18,95,95,114,101,116,86,97,108,0, +59,121,0,58,100,111,116,0,18,114,49,0,0,18,118,0,0,0,20,0,0,1,0,10,2,21,1,1,0,10,118,0,0,1,1,0,13, +109,0,0,0,1,9,18,95,95,114,101,116,86,97,108,0,59,120,0,58,100,111,116,0,18,118,0,0,18,109,0,16,8, +48,0,57,0,0,20,0,9,18,95,95,114,101,116,86,97,108,0,59,121,0,58,100,111,116,0,18,118,0,0,18,109,0, +16,10,49,0,57,0,0,20,0,0,1,0,11,2,21,1,1,0,14,109,0,0,1,1,0,11,118,0,0,0,1,2,3,2,0,11,1,114,48,0,0, +0,9,18,114,48,0,59,120,0,18,109,0,16,8,48,0,57,59,120,0,20,0,9,18,114,48,0,59,121,0,18,109,0,16,10, +49,0,57,59,120,0,20,0,9,18,114,48,0,59,122,0,18,109,0,16,10,50,0,57,59,120,0,20,0,4,118,101,99,51, +95,100,111,116,0,18,95,95,114,101,116,86,97,108,0,59,120,0,0,18,114,48,0,0,18,118,0,0,0,0,2,3,2,0, +11,1,114,49,0,0,0,9,18,114,49,0,59,120,0,18,109,0,16,8,48,0,57,59,121,0,20,0,9,18,114,49,0,59,121, +0,18,109,0,16,10,49,0,57,59,121,0,20,0,9,18,114,49,0,59,122,0,18,109,0,16,10,50,0,57,59,121,0,20,0, +4,118,101,99,51,95,100,111,116,0,18,95,95,114,101,116,86,97,108,0,59,121,0,0,18,114,49,0,0,18,118, +0,0,0,0,2,3,2,0,11,1,114,50,0,0,0,9,18,114,50,0,59,120,0,18,109,0,16,8,48,0,57,59,122,0,20,0,9,18, +114,50,0,59,121,0,18,109,0,16,10,49,0,57,59,122,0,20,0,9,18,114,50,0,59,122,0,18,109,0,16,10,50,0, +57,59,122,0,20,0,4,118,101,99,51,95,100,111,116,0,18,95,95,114,101,116,86,97,108,0,59,122,0,0,18, +114,50,0,0,18,118,0,0,0,0,0,1,0,11,2,21,1,1,0,11,118,0,0,1,1,0,14,109,0,0,0,1,9,18,95,95,114,101, +116,86,97,108,0,59,120,0,58,100,111,116,0,18,118,0,0,18,109,0,16,8,48,0,57,0,0,20,0,9,18,95,95,114, +101,116,86,97,108,0,59,121,0,58,100,111,116,0,18,118,0,0,18,109,0,16,10,49,0,57,0,0,20,0,9,18,95, +95,114,101,116,86,97,108,0,59,122,0,58,100,111,116,0,18,118,0,0,18,109,0,16,10,50,0,57,0,0,20,0,0, +1,0,12,2,21,1,1,0,15,109,0,0,1,1,0,12,118,0,0,0,1,2,3,2,0,12,1,114,48,0,0,0,9,18,114,48,0,59,120,0, +18,109,0,16,8,48,0,57,59,120,0,20,0,9,18,114,48,0,59,121,0,18,109,0,16,10,49,0,57,59,120,0,20,0,9, +18,114,48,0,59,122,0,18,109,0,16,10,50,0,57,59,120,0,20,0,9,18,114,48,0,59,119,0,18,109,0,16,10,51, +0,57,59,120,0,20,0,4,118,101,99,52,95,100,111,116,0,18,95,95,114,101,116,86,97,108,0,59,120,0,0,18, +114,48,0,0,18,118,0,0,0,0,2,3,2,0,12,1,114,49,0,0,0,9,18,114,49,0,59,120,0,18,109,0,16,8,48,0,57, +59,121,0,20,0,9,18,114,49,0,59,121,0,18,109,0,16,10,49,0,57,59,121,0,20,0,9,18,114,49,0,59,122,0, +18,109,0,16,10,50,0,57,59,121,0,20,0,9,18,114,49,0,59,119,0,18,109,0,16,10,51,0,57,59,121,0,20,0,4, +118,101,99,52,95,100,111,116,0,18,95,95,114,101,116,86,97,108,0,59,121,0,0,18,114,49,0,0,18,118,0, +0,0,0,2,3,2,0,12,1,114,50,0,0,0,9,18,114,50,0,59,120,0,18,109,0,16,8,48,0,57,59,122,0,20,0,9,18, +114,50,0,59,121,0,18,109,0,16,10,49,0,57,59,122,0,20,0,9,18,114,50,0,59,122,0,18,109,0,16,10,50,0, +57,59,122,0,20,0,9,18,114,50,0,59,119,0,18,109,0,16,10,51,0,57,59,122,0,20,0,4,118,101,99,52,95, +100,111,116,0,18,95,95,114,101,116,86,97,108,0,59,122,0,0,18,114,50,0,0,18,118,0,0,0,0,2,3,2,0,12, +1,114,51,0,0,0,9,18,114,51,0,59,120,0,18,109,0,16,8,48,0,57,59,119,0,20,0,9,18,114,51,0,59,121,0, +18,109,0,16,10,49,0,57,59,119,0,20,0,9,18,114,51,0,59,122,0,18,109,0,16,10,50,0,57,59,119,0,20,0,9, +18,114,51,0,59,119,0,18,109,0,16,10,51,0,57,59,119,0,20,0,4,118,101,99,52,95,100,111,116,0,18,95, +95,114,101,116,86,97,108,0,59,119,0,0,18,114,51,0,0,18,118,0,0,0,0,0,1,0,12,2,21,1,1,0,12,118,0,0, +1,1,0,15,109,0,0,0,1,9,18,95,95,114,101,116,86,97,108,0,59,120,0,58,100,111,116,0,18,118,0,0,18, +109,0,16,8,48,0,57,0,0,20,0,9,18,95,95,114,101,116,86,97,108,0,59,121,0,58,100,111,116,0,18,118,0, +0,18,109,0,16,10,49,0,57,0,0,20,0,9,18,95,95,114,101,116,86,97,108,0,59,122,0,58,100,111,116,0,18, +118,0,0,18,109,0,16,10,50,0,57,0,0,20,0,9,18,95,95,114,101,116,86,97,108,0,59,119,0,58,100,111,116, +0,18,118,0,0,18,109,0,16,10,51,0,57,0,0,20,0,0,1,0,0,2,1,1,0,2,13,109,0,0,1,1,0,13,110,0,0,0,1,9, +18,109,0,16,8,48,0,57,18,110,0,16,8,48,0,57,21,0,9,18,109,0,16,10,49,0,57,18,110,0,16,10,49,0,57, +21,0,0,1,0,0,2,2,1,0,2,13,109,0,0,1,1,0,13,110,0,0,0,1,9,18,109,0,16,8,48,0,57,18,110,0,16,8,48,0, +57,22,0,9,18,109,0,16,10,49,0,57,18,110,0,16,10,49,0,57,22,0,0,1,0,0,2,3,1,0,2,13,109,0,0,1,1,0,13, +110,0,0,0,1,9,18,109,0,18,109,0,18,110,0,48,20,0,0,1,0,0,2,4,1,0,2,13,109,0,0,1,1,0,13,110,0,0,0,1, +9,18,109,0,16,8,48,0,57,18,110,0,16,8,48,0,57,24,0,9,18,109,0,16,10,49,0,57,18,110,0,16,10,49,0,57, +24,0,0,1,0,0,2,1,1,0,2,14,109,0,0,1,1,0,14,110,0,0,0,1,9,18,109,0,16,8,48,0,57,18,110,0,16,8,48,0, +57,21,0,9,18,109,0,16,10,49,0,57,18,110,0,16,10,49,0,57,21,0,9,18,109,0,16,10,50,0,57,18,110,0,16, +10,50,0,57,21,0,0,1,0,0,2,2,1,0,2,14,109,0,0,1,1,0,14,110,0,0,0,1,9,18,109,0,16,8,48,0,57,18,110,0, +16,8,48,0,57,22,0,9,18,109,0,16,10,49,0,57,18,110,0,16,10,49,0,57,22,0,9,18,109,0,16,10,50,0,57,18, +110,0,16,10,50,0,57,22,0,0,1,0,0,2,3,1,0,2,14,109,0,0,1,1,0,14,110,0,0,0,1,9,18,109,0,18,109,0,18, +110,0,48,20,0,0,1,0,0,2,4,1,0,2,14,109,0,0,1,1,0,14,110,0,0,0,1,9,18,109,0,16,8,48,0,57,18,110,0, +16,8,48,0,57,24,0,9,18,109,0,16,10,49,0,57,18,110,0,16,10,49,0,57,24,0,9,18,109,0,16,10,50,0,57,18, +110,0,16,10,50,0,57,24,0,0,1,0,0,2,1,1,0,2,15,109,0,0,1,1,0,15,110,0,0,0,1,9,18,109,0,16,8,48,0,57, +18,110,0,16,8,48,0,57,21,0,9,18,109,0,16,10,49,0,57,18,110,0,16,10,49,0,57,21,0,9,18,109,0,16,10, +50,0,57,18,110,0,16,10,50,0,57,21,0,9,18,109,0,16,10,51,0,57,18,110,0,16,10,51,0,57,21,0,0,1,0,0,2, +2,1,0,2,15,109,0,0,1,1,0,15,110,0,0,0,1,9,18,109,0,16,8,48,0,57,18,110,0,16,8,48,0,57,22,0,9,18, +109,0,16,10,49,0,57,18,110,0,16,10,49,0,57,22,0,9,18,109,0,16,10,50,0,57,18,110,0,16,10,50,0,57,22, +0,9,18,109,0,16,10,51,0,57,18,110,0,16,10,51,0,57,22,0,0,1,0,0,2,3,1,0,2,15,109,0,0,1,1,0,15,110,0, +0,0,1,9,18,109,0,18,109,0,18,110,0,48,20,0,0,1,0,0,2,4,1,0,2,15,109,0,0,1,1,0,15,110,0,0,0,1,9,18, +109,0,16,8,48,0,57,18,110,0,16,8,48,0,57,24,0,9,18,109,0,16,10,49,0,57,18,110,0,16,10,49,0,57,24,0, +9,18,109,0,16,10,50,0,57,18,110,0,16,10,50,0,57,24,0,9,18,109,0,16,10,51,0,57,18,110,0,16,10,51,0, +57,24,0,0,1,0,0,2,1,1,0,2,13,109,0,0,1,1,0,9,97,0,0,0,1,9,18,109,0,16,8,48,0,57,18,97,0,21,0,9,18, +109,0,16,10,49,0,57,18,97,0,21,0,0,1,0,0,2,2,1,0,2,13,109,0,0,1,1,0,9,97,0,0,0,1,9,18,109,0,16,8, +48,0,57,18,97,0,22,0,9,18,109,0,16,10,49,0,57,18,97,0,22,0,0,1,0,0,2,3,1,0,2,13,109,0,0,1,1,0,9,97, +0,0,0,1,9,18,109,0,16,8,48,0,57,18,97,0,23,0,9,18,109,0,16,10,49,0,57,18,97,0,23,0,0,1,0,0,2,4,1,0, +2,13,109,0,0,1,1,0,9,97,0,0,0,1,9,18,109,0,16,8,48,0,57,18,97,0,24,0,9,18,109,0,16,10,49,0,57,18, +97,0,24,0,0,1,0,0,2,1,1,0,2,14,109,0,0,1,1,0,9,97,0,0,0,1,9,18,109,0,16,8,48,0,57,18,97,0,21,0,9, +18,109,0,16,10,49,0,57,18,97,0,21,0,9,18,109,0,16,10,50,0,57,18,97,0,21,0,0,1,0,0,2,2,1,0,2,14,109, +0,0,1,1,0,9,97,0,0,0,1,9,18,109,0,16,8,48,0,57,18,97,0,22,0,9,18,109,0,16,10,49,0,57,18,97,0,22,0, +9,18,109,0,16,10,50,0,57,18,97,0,22,0,0,1,0,0,2,3,1,0,2,14,109,0,0,1,1,0,9,97,0,0,0,1,9,18,109,0, +16,8,48,0,57,18,97,0,23,0,9,18,109,0,16,10,49,0,57,18,97,0,23,0,9,18,109,0,16,10,50,0,57,18,97,0, +23,0,0,1,0,0,2,4,1,0,2,14,109,0,0,1,1,0,9,97,0,0,0,1,9,18,109,0,16,8,48,0,57,18,97,0,24,0,9,18,109, +0,16,10,49,0,57,18,97,0,24,0,9,18,109,0,16,10,50,0,57,18,97,0,24,0,0,1,0,0,2,1,1,0,2,15,109,0,0,1, +1,0,9,97,0,0,0,1,9,18,109,0,16,8,48,0,57,18,97,0,21,0,9,18,109,0,16,10,49,0,57,18,97,0,21,0,9,18, +109,0,16,10,50,0,57,18,97,0,21,0,9,18,109,0,16,10,51,0,57,18,97,0,21,0,0,1,0,0,2,2,1,0,2,15,109,0, +0,1,1,0,9,97,0,0,0,1,9,18,109,0,16,8,48,0,57,18,97,0,22,0,9,18,109,0,16,10,49,0,57,18,97,0,22,0,9, +18,109,0,16,10,50,0,57,18,97,0,22,0,9,18,109,0,16,10,51,0,57,18,97,0,22,0,0,1,0,0,2,3,1,0,2,15,109, 0,0,1,1,0,9,97,0,0,0,1,9,18,109,0,16,8,48,0,57,18,97,0,23,0,9,18,109,0,16,10,49,0,57,18,97,0,23,0, -9,18,109,0,16,10,50,0,57,18,97,0,23,0,0,1,0,0,2,4,1,0,2,14,109,0,0,1,1,0,9,97,0,0,0,1,9,18,109,0, -16,8,48,0,57,18,97,0,24,0,9,18,109,0,16,10,49,0,57,18,97,0,24,0,9,18,109,0,16,10,50,0,57,18,97,0, -24,0,0,1,0,0,2,1,1,0,2,15,109,0,0,1,1,0,9,97,0,0,0,1,9,18,109,0,16,8,48,0,57,18,97,0,21,0,9,18,109, -0,16,10,49,0,57,18,97,0,21,0,9,18,109,0,16,10,50,0,57,18,97,0,21,0,9,18,109,0,16,10,51,0,57,18,97, -0,21,0,0,1,0,0,2,2,1,0,2,15,109,0,0,1,1,0,9,97,0,0,0,1,9,18,109,0,16,8,48,0,57,18,97,0,22,0,9,18, -109,0,16,10,49,0,57,18,97,0,22,0,9,18,109,0,16,10,50,0,57,18,97,0,22,0,9,18,109,0,16,10,51,0,57,18, -97,0,22,0,0,1,0,0,2,3,1,0,2,15,109,0,0,1,1,0,9,97,0,0,0,1,9,18,109,0,16,8,48,0,57,18,97,0,23,0,9, -18,109,0,16,10,49,0,57,18,97,0,23,0,9,18,109,0,16,10,50,0,57,18,97,0,23,0,9,18,109,0,16,10,51,0,57, -18,97,0,23,0,0,1,0,0,2,4,1,0,2,15,109,0,0,1,1,0,9,97,0,0,0,1,9,18,109,0,16,8,48,0,57,18,97,0,24,0, -9,18,109,0,16,10,49,0,57,18,97,0,24,0,9,18,109,0,16,10,50,0,57,18,97,0,24,0,9,18,109,0,16,10,51,0, -57,18,97,0,24,0,0,1,0,10,2,21,1,1,0,10,118,0,0,1,1,0,13,109,0,0,0,1,8,58,118,101,99,50,0,18,118,0, -59,120,0,18,109,0,16,8,48,0,57,59,120,0,48,18,118,0,59,121,0,18,109,0,16,8,48,0,57,59,121,0,48,46, -0,18,118,0,59,120,0,18,109,0,16,10,49,0,57,59,120,0,48,18,118,0,59,121,0,18,109,0,16,10,49,0,57,59, -121,0,48,46,0,0,0,0,1,0,0,2,3,1,0,2,10,118,0,0,1,1,0,13,109,0,0,0,1,9,18,118,0,18,118,0,18,109,0, -48,20,0,0,1,0,11,2,21,1,1,0,11,118,0,0,1,1,0,14,109,0,0,0,1,8,58,118,101,99,51,0,18,118,0,59,120,0, -18,109,0,16,8,48,0,57,59,120,0,48,18,118,0,59,121,0,18,109,0,16,8,48,0,57,59,121,0,48,46,18,118,0, -59,122,0,18,109,0,16,8,48,0,57,59,122,0,48,46,0,18,118,0,59,120,0,18,109,0,16,10,49,0,57,59,120,0, -48,18,118,0,59,121,0,18,109,0,16,10,49,0,57,59,121,0,48,46,18,118,0,59,122,0,18,109,0,16,10,49,0, -57,59,122,0,48,46,0,18,118,0,59,120,0,18,109,0,16,10,50,0,57,59,120,0,48,18,118,0,59,121,0,18,109, -0,16,10,50,0,57,59,121,0,48,46,18,118,0,59,122,0,18,109,0,16,10,50,0,57,59,122,0,48,46,0,0,0,0,1,0, -0,2,3,1,0,2,11,118,0,0,1,1,0,14,109,0,0,0,1,9,18,118,0,18,118,0,18,109,0,48,20,0,0,1,0,12,2,21,1,1, -0,12,118,0,0,1,1,0,15,109,0,0,0,1,8,58,118,101,99,52,0,18,118,0,59,120,0,18,109,0,16,8,48,0,57,59, -120,0,48,18,118,0,59,121,0,18,109,0,16,8,48,0,57,59,121,0,48,46,18,118,0,59,122,0,18,109,0,16,8,48, -0,57,59,122,0,48,46,18,118,0,59,119,0,18,109,0,16,8,48,0,57,59,119,0,48,46,0,18,118,0,59,120,0,18, -109,0,16,10,49,0,57,59,120,0,48,18,118,0,59,121,0,18,109,0,16,10,49,0,57,59,121,0,48,46,18,118,0, -59,122,0,18,109,0,16,10,49,0,57,59,122,0,48,46,18,118,0,59,119,0,18,109,0,16,10,49,0,57,59,119,0, -48,46,0,18,118,0,59,120,0,18,109,0,16,10,50,0,57,59,120,0,48,18,118,0,59,121,0,18,109,0,16,10,50,0, -57,59,121,0,48,46,18,118,0,59,122,0,18,109,0,16,10,50,0,57,59,122,0,48,46,18,118,0,59,119,0,18,109, -0,16,10,50,0,57,59,119,0,48,46,0,18,118,0,59,120,0,18,109,0,16,10,51,0,57,59,120,0,48,18,118,0,59, -121,0,18,109,0,16,10,51,0,57,59,121,0,48,46,18,118,0,59,122,0,18,109,0,16,10,51,0,57,59,122,0,48, -46,18,118,0,59,119,0,18,109,0,16,10,51,0,57,59,119,0,48,46,0,0,0,0,1,0,0,2,3,1,0,2,12,118,0,0,1,1, -0,15,109,0,0,0,1,9,18,118,0,18,118,0,18,109,0,48,20,0,0,1,0,9,2,27,1,1,0,9,97,0,0,1,1,0,9,98,0,0,0, -1,3,2,0,9,1,99,0,0,0,4,102,108,111,97,116,95,110,101,103,97,116,101,0,18,99,0,0,18,98,0,0,0,4,102, -108,111,97,116,95,97,100,100,0,18,99,0,0,18,97,0,0,18,99,0,0,0,8,18,99,0,0,0,1,0,5,2,26,1,1,0,5,97, -0,0,1,1,0,5,98,0,0,0,1,3,2,0,9,1,120,0,0,1,1,121,0,0,0,3,2,0,5,1,99,0,0,0,4,105,110,116,95,116,111, -95,102,108,111,97,116,0,18,120,0,0,18,97,0,0,0,4,105,110,116,95,116,111,95,102,108,111,97,116,0,18, -121,0,0,18,98,0,0,0,4,102,108,111,97,116,95,97,100,100,0,18,120,0,0,18,120,0,0,18,121,0,0,0,4,102, -108,111,97,116,95,116,111,95,105,110,116,0,18,99,0,0,18,120,0,0,0,8,18,99,0,0,0,1,0,5,2,27,1,1,0,5, -97,0,0,1,1,0,5,98,0,0,0,1,3,2,0,9,1,120,0,0,1,1,121,0,0,0,3,2,0,5,1,99,0,0,0,4,105,110,116,95,116, -111,95,102,108,111,97,116,0,18,120,0,0,18,97,0,0,0,4,105,110,116,95,116,111,95,102,108,111,97,116, -0,18,121,0,0,18,98,0,0,0,4,102,108,111,97,116,95,110,101,103,97,116,101,0,18,121,0,0,18,121,0,0,0, -4,102,108,111,97,116,95,97,100,100,0,18,120,0,0,18,120,0,0,18,121,0,0,0,4,102,108,111,97,116,95, -116,111,95,105,110,116,0,18,99,0,0,18,120,0,0,0,8,18,99,0,0,0,1,0,5,2,21,1,1,0,5,97,0,0,1,1,0,5,98, -0,0,0,1,3,2,0,9,1,120,0,0,1,1,121,0,0,0,3,2,0,5,1,99,0,0,0,4,105,110,116,95,116,111,95,102,108,111, -97,116,0,18,120,0,0,18,97,0,0,0,4,105,110,116,95,116,111,95,102,108,111,97,116,0,18,121,0,0,18,98, -0,0,0,4,102,108,111,97,116,95,109,117,108,116,105,112,108,121,0,18,120,0,0,18,120,0,0,18,121,0,0,0, -4,102,108,111,97,116,95,116,111,95,105,110,116,0,18,99,0,0,18,120,0,0,0,8,18,99,0,0,0,1,0,5,2,22,1, -1,0,5,97,0,0,1,1,0,5,98,0,0,0,1,3,2,0,9,1,120,0,0,1,1,121,0,0,0,3,2,0,5,1,99,0,0,0,4,105,110,116, -95,116,111,95,102,108,111,97,116,0,18,120,0,0,18,97,0,0,0,4,105,110,116,95,116,111,95,102,108,111, -97,116,0,18,121,0,0,18,98,0,0,0,4,102,108,111,97,116,95,100,105,118,105,100,101,0,18,120,0,0,18, -120,0,0,18,121,0,0,0,4,102,108,111,97,116,95,116,111,95,105,110,116,0,18,99,0,0,18,120,0,0,0,8,18, -99,0,0,0,1,0,10,2,26,1,1,0,10,118,0,0,1,1,0,10,117,0,0,0,1,8,58,118,101,99,50,0,18,118,0,59,120,0, -18,117,0,59,120,0,46,0,18,118,0,59,121,0,18,117,0,59,121,0,46,0,0,0,0,1,0,10,2,27,1,1,0,10,118,0,0, -1,1,0,10,117,0,0,0,1,8,58,118,101,99,50,0,18,118,0,59,120,0,18,117,0,59,120,0,47,0,18,118,0,59,121, -0,18,117,0,59,121,0,47,0,0,0,0,1,0,10,2,21,1,1,0,10,118,0,0,1,1,0,10,117,0,0,0,1,8,58,118,101,99, -50,0,18,118,0,59,120,0,18,117,0,59,120,0,48,0,18,118,0,59,121,0,18,117,0,59,121,0,48,0,0,0,0,1,0, -10,2,22,1,1,0,10,118,0,0,1,1,0,10,117,0,0,0,1,8,58,118,101,99,50,0,18,118,0,59,120,0,18,117,0,59, -120,0,49,0,18,118,0,59,121,0,18,117,0,59,121,0,49,0,0,0,0,1,0,11,2,26,1,1,0,11,118,0,0,1,1,0,11, -117,0,0,0,1,8,58,118,101,99,51,0,18,118,0,59,120,0,18,117,0,59,120,0,46,0,18,118,0,59,121,0,18,117, -0,59,121,0,46,0,18,118,0,59,122,0,18,117,0,59,122,0,46,0,0,0,0,1,0,11,2,27,1,1,0,11,118,0,0,1,1,0, -11,117,0,0,0,1,8,58,118,101,99,51,0,18,118,0,59,120,0,18,117,0,59,120,0,47,0,18,118,0,59,121,0,18, -117,0,59,121,0,47,0,18,118,0,59,122,0,18,117,0,59,122,0,47,0,0,0,0,1,0,11,2,21,1,1,0,11,118,0,0,1, -1,0,11,117,0,0,0,1,8,58,118,101,99,51,0,18,118,0,59,120,0,18,117,0,59,120,0,48,0,18,118,0,59,121,0, -18,117,0,59,121,0,48,0,18,118,0,59,122,0,18,117,0,59,122,0,48,0,0,0,0,1,0,11,2,22,1,1,0,11,118,0,0, -1,1,0,11,117,0,0,0,1,8,58,118,101,99,51,0,18,118,0,59,120,0,18,117,0,59,120,0,49,0,18,118,0,59,121, -0,18,117,0,59,121,0,49,0,18,118,0,59,122,0,18,117,0,59,122,0,49,0,0,0,0,1,0,12,2,26,1,1,0,12,118,0, -0,1,1,0,12,117,0,0,0,1,8,58,118,101,99,52,0,18,118,0,59,120,0,18,117,0,59,120,0,46,0,18,118,0,59, -121,0,18,117,0,59,121,0,46,0,18,118,0,59,122,0,18,117,0,59,122,0,46,0,18,118,0,59,119,0,18,117,0, -59,119,0,46,0,0,0,0,1,0,12,2,27,1,1,0,12,118,0,0,1,1,0,12,117,0,0,0,1,8,58,118,101,99,52,0,18,118, -0,59,120,0,18,117,0,59,120,0,47,0,18,118,0,59,121,0,18,117,0,59,121,0,47,0,18,118,0,59,122,0,18, -117,0,59,122,0,47,0,18,118,0,59,119,0,18,117,0,59,119,0,47,0,0,0,0,1,0,12,2,21,1,1,0,12,118,0,0,1, -1,0,12,117,0,0,0,1,8,58,118,101,99,52,0,18,118,0,59,120,0,18,117,0,59,120,0,48,0,18,118,0,59,121,0, -18,117,0,59,121,0,48,0,18,118,0,59,122,0,18,117,0,59,122,0,48,0,18,118,0,59,119,0,18,117,0,59,119, -0,48,0,0,0,0,1,0,12,2,22,1,1,0,12,118,0,0,1,1,0,12,117,0,0,0,1,8,58,118,101,99,52,0,18,118,0,59, -120,0,18,117,0,59,120,0,49,0,18,118,0,59,121,0,18,117,0,59,121,0,49,0,18,118,0,59,122,0,18,117,0, -59,122,0,49,0,18,118,0,59,119,0,18,117,0,59,119,0,49,0,0,0,0,1,0,6,2,26,1,1,0,6,118,0,0,1,1,0,6, -117,0,0,0,1,8,58,105,118,101,99,50,0,18,118,0,59,120,0,18,117,0,59,120,0,46,0,18,118,0,59,121,0,18, -117,0,59,121,0,46,0,0,0,0,1,0,6,2,27,1,1,0,6,118,0,0,1,1,0,6,117,0,0,0,1,8,58,105,118,101,99,50,0, -18,118,0,59,120,0,18,117,0,59,120,0,47,0,18,118,0,59,121,0,18,117,0,59,121,0,47,0,0,0,0,1,0,6,2,21, -1,1,0,6,118,0,0,1,1,0,6,117,0,0,0,1,8,58,105,118,101,99,50,0,18,118,0,59,120,0,18,117,0,59,120,0, -48,0,18,118,0,59,121,0,18,117,0,59,121,0,48,0,0,0,0,1,0,6,2,22,1,1,0,6,118,0,0,1,1,0,6,117,0,0,0,1, -8,58,105,118,101,99,50,0,18,118,0,59,120,0,18,117,0,59,120,0,49,0,18,118,0,59,121,0,18,117,0,59, -121,0,49,0,0,0,0,1,0,7,2,26,1,1,0,7,118,0,0,1,1,0,7,117,0,0,0,1,8,58,105,118,101,99,51,0,18,118,0, -59,120,0,18,117,0,59,120,0,46,0,18,118,0,59,121,0,18,117,0,59,121,0,46,0,18,118,0,59,122,0,18,117, -0,59,122,0,46,0,0,0,0,1,0,7,2,27,1,1,0,7,118,0,0,1,1,0,7,117,0,0,0,1,8,58,105,118,101,99,51,0,18, -118,0,59,120,0,18,117,0,59,120,0,47,0,18,118,0,59,121,0,18,117,0,59,121,0,47,0,18,118,0,59,122,0, -18,117,0,59,122,0,47,0,0,0,0,1,0,7,2,21,1,1,0,7,118,0,0,1,1,0,7,117,0,0,0,1,8,58,105,118,101,99,51, -0,18,118,0,59,120,0,18,117,0,59,120,0,48,0,18,118,0,59,121,0,18,117,0,59,121,0,48,0,18,118,0,59, -122,0,18,117,0,59,122,0,48,0,0,0,0,1,0,7,2,22,1,1,0,7,118,0,0,1,1,0,7,117,0,0,0,1,8,58,105,118,101, -99,51,0,18,118,0,59,120,0,18,117,0,59,120,0,49,0,18,118,0,59,121,0,18,117,0,59,121,0,49,0,18,118,0, -59,122,0,18,117,0,59,122,0,49,0,0,0,0,1,0,8,2,26,1,1,0,8,118,0,0,1,1,0,8,117,0,0,0,1,8,58,105,118, -101,99,52,0,18,118,0,59,120,0,18,117,0,59,120,0,46,0,18,118,0,59,121,0,18,117,0,59,121,0,46,0,18, -118,0,59,122,0,18,117,0,59,122,0,46,0,18,118,0,59,119,0,18,117,0,59,119,0,46,0,0,0,0,1,0,8,2,27,1, -1,0,8,118,0,0,1,1,0,8,117,0,0,0,1,8,58,105,118,101,99,52,0,18,118,0,59,120,0,18,117,0,59,120,0,47, -0,18,118,0,59,121,0,18,117,0,59,121,0,47,0,18,118,0,59,122,0,18,117,0,59,122,0,47,0,18,118,0,59, -119,0,18,117,0,59,119,0,47,0,0,0,0,1,0,8,2,21,1,1,0,8,118,0,0,1,1,0,8,117,0,0,0,1,8,58,105,118,101, -99,52,0,18,118,0,59,120,0,18,117,0,59,120,0,48,0,18,118,0,59,121,0,18,117,0,59,121,0,48,0,18,118,0, -59,122,0,18,117,0,59,122,0,48,0,18,118,0,59,119,0,18,117,0,59,119,0,48,0,0,0,0,1,0,8,2,22,1,1,0,8, -118,0,0,1,1,0,8,117,0,0,0,1,8,58,105,118,101,99,52,0,18,118,0,59,120,0,18,117,0,59,120,0,49,0,18, -118,0,59,121,0,18,117,0,59,121,0,49,0,18,118,0,59,122,0,18,117,0,59,122,0,49,0,18,118,0,59,119,0, -18,117,0,59,119,0,49,0,0,0,0,1,0,13,2,26,1,1,0,13,109,0,0,1,1,0,13,110,0,0,0,1,8,58,109,97,116,50, -0,18,109,0,16,8,48,0,57,18,110,0,16,8,48,0,57,46,0,18,109,0,16,10,49,0,57,18,110,0,16,10,49,0,57, -46,0,0,0,0,1,0,13,2,27,1,1,0,13,109,0,0,1,1,0,13,110,0,0,0,1,8,58,109,97,116,50,0,18,109,0,16,8,48, -0,57,18,110,0,16,8,48,0,57,47,0,18,109,0,16,10,49,0,57,18,110,0,16,10,49,0,57,47,0,0,0,0,1,0,13,2, -22,1,1,0,13,109,0,0,1,1,0,13,110,0,0,0,1,8,58,109,97,116,50,0,18,109,0,16,8,48,0,57,18,110,0,16,8, -48,0,57,49,0,18,109,0,16,10,49,0,57,18,110,0,16,10,49,0,57,49,0,0,0,0,1,0,14,2,26,1,1,0,14,109,0,0, -1,1,0,14,110,0,0,0,1,8,58,109,97,116,51,0,18,109,0,16,8,48,0,57,18,110,0,16,8,48,0,57,46,0,18,109, -0,16,10,49,0,57,18,110,0,16,10,49,0,57,46,0,18,109,0,16,10,50,0,57,18,110,0,16,10,50,0,57,46,0,0,0, -0,1,0,14,2,27,1,1,0,14,109,0,0,1,1,0,14,110,0,0,0,1,8,58,109,97,116,51,0,18,109,0,16,8,48,0,57,18, -110,0,16,8,48,0,57,47,0,18,109,0,16,10,49,0,57,18,110,0,16,10,49,0,57,47,0,18,109,0,16,10,50,0,57, -18,110,0,16,10,50,0,57,47,0,0,0,0,1,0,14,2,22,1,1,0,14,109,0,0,1,1,0,14,110,0,0,0,1,8,58,109,97, -116,51,0,18,109,0,16,8,48,0,57,18,110,0,16,8,48,0,57,49,0,18,109,0,16,10,49,0,57,18,110,0,16,10,49, -0,57,49,0,18,109,0,16,10,50,0,57,18,110,0,16,10,50,0,57,49,0,0,0,0,1,0,15,2,26,1,1,0,15,109,0,0,1, -1,0,15,110,0,0,0,1,8,58,109,97,116,52,0,18,109,0,16,8,48,0,57,18,110,0,16,8,48,0,57,46,0,18,109,0, -16,10,49,0,57,18,110,0,16,10,49,0,57,46,0,18,109,0,16,10,50,0,57,18,110,0,16,10,50,0,57,46,0,18, -109,0,16,10,51,0,57,18,110,0,16,10,51,0,57,46,0,0,0,0,1,0,15,2,27,1,1,0,15,109,0,0,1,1,0,15,110,0, -0,0,1,8,58,109,97,116,52,0,18,109,0,16,8,48,0,57,18,110,0,16,8,48,0,57,47,0,18,109,0,16,10,49,0,57, -18,110,0,16,10,49,0,57,47,0,18,109,0,16,10,50,0,57,18,110,0,16,10,50,0,57,47,0,18,109,0,16,10,51,0, -57,18,110,0,16,10,51,0,57,47,0,0,0,0,1,0,15,2,22,1,1,0,15,109,0,0,1,1,0,15,110,0,0,0,1,8,58,109,97, -116,52,0,18,109,0,16,8,48,0,57,18,110,0,16,8,48,0,57,49,0,18,109,0,16,10,49,0,57,18,110,0,16,10,49, -0,57,49,0,18,109,0,16,10,50,0,57,18,110,0,16,10,50,0,57,49,0,18,109,0,16,10,51,0,57,18,110,0,16,10, -51,0,57,49,0,0,0,0,1,0,10,2,26,1,1,0,9,97,0,0,1,1,0,10,117,0,0,0,1,8,58,118,101,99,50,0,18,97,0,18, -117,0,59,120,0,46,0,18,97,0,18,117,0,59,121,0,46,0,0,0,0,1,0,10,2,26,1,1,0,10,118,0,0,1,1,0,9,98,0, -0,0,1,8,58,118,101,99,50,0,18,118,0,59,120,0,18,98,0,46,0,18,118,0,59,121,0,18,98,0,46,0,0,0,0,1,0, -10,2,27,1,1,0,9,97,0,0,1,1,0,10,117,0,0,0,1,8,58,118,101,99,50,0,18,97,0,18,117,0,59,120,0,47,0,18, -97,0,18,117,0,59,121,0,47,0,0,0,0,1,0,10,2,27,1,1,0,10,118,0,0,1,1,0,9,98,0,0,0,1,8,58,118,101,99, -50,0,18,118,0,59,120,0,18,98,0,47,0,18,118,0,59,121,0,18,98,0,47,0,0,0,0,1,0,10,2,21,1,1,0,9,97,0, -0,1,1,0,10,117,0,0,0,1,8,58,118,101,99,50,0,18,97,0,18,117,0,59,120,0,48,0,18,97,0,18,117,0,59,121, -0,48,0,0,0,0,1,0,10,2,21,1,1,0,10,118,0,0,1,1,0,9,98,0,0,0,1,8,58,118,101,99,50,0,18,118,0,59,120, -0,18,98,0,48,0,18,118,0,59,121,0,18,98,0,48,0,0,0,0,1,0,10,2,22,1,1,0,9,97,0,0,1,1,0,10,117,0,0,0, -1,8,58,118,101,99,50,0,18,97,0,18,117,0,59,120,0,49,0,18,97,0,18,117,0,59,121,0,49,0,0,0,0,1,0,10, -2,22,1,1,0,10,118,0,0,1,1,0,9,98,0,0,0,1,8,58,118,101,99,50,0,18,118,0,59,120,0,18,98,0,49,0,18, -118,0,59,121,0,18,98,0,49,0,0,0,0,1,0,11,2,26,1,1,0,9,97,0,0,1,1,0,11,117,0,0,0,1,8,58,118,101,99, -51,0,18,97,0,18,117,0,59,120,0,46,0,18,97,0,18,117,0,59,121,0,46,0,18,97,0,18,117,0,59,122,0,46,0, -0,0,0,1,0,11,2,26,1,1,0,11,118,0,0,1,1,0,9,98,0,0,0,1,8,58,118,101,99,51,0,18,118,0,59,120,0,18,98, -0,46,0,18,118,0,59,121,0,18,98,0,46,0,18,118,0,59,122,0,18,98,0,46,0,0,0,0,1,0,11,2,27,1,1,0,9,97, -0,0,1,1,0,11,117,0,0,0,1,8,58,118,101,99,51,0,18,97,0,18,117,0,59,120,0,47,0,18,97,0,18,117,0,59, -121,0,47,0,18,97,0,18,117,0,59,122,0,47,0,0,0,0,1,0,11,2,27,1,1,0,11,118,0,0,1,1,0,9,98,0,0,0,1,8, -58,118,101,99,51,0,18,118,0,59,120,0,18,98,0,47,0,18,118,0,59,121,0,18,98,0,47,0,18,118,0,59,122,0, -18,98,0,47,0,0,0,0,1,0,11,2,21,1,1,0,9,97,0,0,1,1,0,11,117,0,0,0,1,8,58,118,101,99,51,0,18,97,0,18, -117,0,59,120,0,48,0,18,97,0,18,117,0,59,121,0,48,0,18,97,0,18,117,0,59,122,0,48,0,0,0,0,1,0,11,2, -21,1,1,0,11,118,0,0,1,1,0,9,98,0,0,0,1,8,58,118,101,99,51,0,18,118,0,59,120,0,18,98,0,48,0,18,118, -0,59,121,0,18,98,0,48,0,18,118,0,59,122,0,18,98,0,48,0,0,0,0,1,0,11,2,22,1,1,0,9,97,0,0,1,1,0,11, -117,0,0,0,1,8,58,118,101,99,51,0,18,97,0,18,117,0,59,120,0,49,0,18,97,0,18,117,0,59,121,0,49,0,18, -97,0,18,117,0,59,122,0,49,0,0,0,0,1,0,11,2,22,1,1,0,11,118,0,0,1,1,0,9,98,0,0,0,1,8,58,118,101,99, -51,0,18,118,0,59,120,0,18,98,0,49,0,18,118,0,59,121,0,18,98,0,49,0,18,118,0,59,122,0,18,98,0,49,0, -0,0,0,1,0,12,2,26,1,1,0,9,97,0,0,1,1,0,12,117,0,0,0,1,8,58,118,101,99,52,0,18,97,0,18,117,0,59,120, -0,46,0,18,97,0,18,117,0,59,121,0,46,0,18,97,0,18,117,0,59,122,0,46,0,18,97,0,18,117,0,59,119,0,46, -0,0,0,0,1,0,12,2,26,1,1,0,12,118,0,0,1,1,0,9,98,0,0,0,1,8,58,118,101,99,52,0,18,118,0,59,120,0,18, -98,0,46,0,18,118,0,59,121,0,18,98,0,46,0,18,118,0,59,122,0,18,98,0,46,0,18,118,0,59,119,0,18,98,0, -46,0,0,0,0,1,0,12,2,27,1,1,0,9,97,0,0,1,1,0,12,117,0,0,0,1,8,58,118,101,99,52,0,18,97,0,18,117,0, -59,120,0,47,0,18,97,0,18,117,0,59,121,0,47,0,18,97,0,18,117,0,59,122,0,47,0,18,97,0,18,117,0,59, -119,0,47,0,0,0,0,1,0,12,2,27,1,1,0,12,118,0,0,1,1,0,9,98,0,0,0,1,8,58,118,101,99,52,0,18,118,0,59, -120,0,18,98,0,47,0,18,118,0,59,121,0,18,98,0,47,0,18,118,0,59,122,0,18,98,0,47,0,18,118,0,59,119,0, -18,98,0,47,0,0,0,0,1,0,12,2,21,1,1,0,9,97,0,0,1,1,0,12,117,0,0,0,1,8,58,118,101,99,52,0,18,97,0,18, -117,0,59,120,0,48,0,18,97,0,18,117,0,59,121,0,48,0,18,97,0,18,117,0,59,122,0,48,0,18,97,0,18,117,0, -59,119,0,48,0,0,0,0,1,0,12,2,21,1,1,0,12,118,0,0,1,1,0,9,98,0,0,0,1,8,58,118,101,99,52,0,18,118,0, -59,120,0,18,98,0,48,0,18,118,0,59,121,0,18,98,0,48,0,18,118,0,59,122,0,18,98,0,48,0,18,118,0,59, -119,0,18,98,0,48,0,0,0,0,1,0,12,2,22,1,1,0,9,97,0,0,1,1,0,12,117,0,0,0,1,8,58,118,101,99,52,0,18, -97,0,18,117,0,59,120,0,49,0,18,97,0,18,117,0,59,121,0,49,0,18,97,0,18,117,0,59,122,0,49,0,18,97,0, -18,117,0,59,119,0,49,0,0,0,0,1,0,12,2,22,1,1,0,12,118,0,0,1,1,0,9,98,0,0,0,1,8,58,118,101,99,52,0, -18,118,0,59,120,0,18,98,0,49,0,18,118,0,59,121,0,18,98,0,49,0,18,118,0,59,122,0,18,98,0,49,0,18, -118,0,59,119,0,18,98,0,49,0,0,0,0,1,0,13,2,26,1,1,0,9,97,0,0,1,1,0,13,110,0,0,0,1,8,58,109,97,116, -50,0,18,97,0,18,110,0,16,8,48,0,57,46,0,18,97,0,18,110,0,16,10,49,0,57,46,0,0,0,0,1,0,13,2,26,1,1, -0,13,109,0,0,1,1,0,9,98,0,0,0,1,8,58,109,97,116,50,0,18,109,0,16,8,48,0,57,18,98,0,46,0,18,109,0, -16,10,49,0,57,18,98,0,46,0,0,0,0,1,0,13,2,27,1,1,0,9,97,0,0,1,1,0,13,110,0,0,0,1,8,58,109,97,116, -50,0,18,97,0,18,110,0,16,8,48,0,57,47,0,18,97,0,18,110,0,16,10,49,0,57,47,0,0,0,0,1,0,13,2,27,1,1, -0,13,109,0,0,1,1,0,9,98,0,0,0,1,8,58,109,97,116,50,0,18,109,0,16,8,48,0,57,18,98,0,47,0,18,109,0, -16,10,49,0,57,18,98,0,47,0,0,0,0,1,0,13,2,21,1,1,0,9,97,0,0,1,1,0,13,110,0,0,0,1,8,58,109,97,116, -50,0,18,97,0,18,110,0,16,8,48,0,57,48,0,18,97,0,18,110,0,16,10,49,0,57,48,0,0,0,0,1,0,13,2,21,1,1, -0,13,109,0,0,1,1,0,9,98,0,0,0,1,8,58,109,97,116,50,0,18,109,0,16,8,48,0,57,18,98,0,48,0,18,109,0, -16,10,49,0,57,18,98,0,48,0,0,0,0,1,0,13,2,22,1,1,0,9,97,0,0,1,1,0,13,110,0,0,0,1,8,58,109,97,116, -50,0,18,97,0,18,110,0,16,8,48,0,57,49,0,18,97,0,18,110,0,16,10,49,0,57,49,0,0,0,0,1,0,13,2,22,1,1, -0,13,109,0,0,1,1,0,9,98,0,0,0,1,8,58,109,97,116,50,0,18,109,0,16,8,48,0,57,18,98,0,49,0,18,109,0, -16,10,49,0,57,18,98,0,49,0,0,0,0,1,0,14,2,26,1,1,0,9,97,0,0,1,1,0,14,110,0,0,0,1,8,58,109,97,116, -51,0,18,97,0,18,110,0,16,8,48,0,57,46,0,18,97,0,18,110,0,16,10,49,0,57,46,0,18,97,0,18,110,0,16,10, -50,0,57,46,0,0,0,0,1,0,14,2,26,1,1,0,14,109,0,0,1,1,0,9,98,0,0,0,1,8,58,109,97,116,51,0,18,109,0, -16,8,48,0,57,18,98,0,46,0,18,109,0,16,10,49,0,57,18,98,0,46,0,18,109,0,16,10,50,0,57,18,98,0,46,0, -0,0,0,1,0,14,2,27,1,1,0,9,97,0,0,1,1,0,14,110,0,0,0,1,8,58,109,97,116,51,0,18,97,0,18,110,0,16,8, -48,0,57,47,0,18,97,0,18,110,0,16,10,49,0,57,47,0,18,97,0,18,110,0,16,10,50,0,57,47,0,0,0,0,1,0,14, -2,27,1,1,0,14,109,0,0,1,1,0,9,98,0,0,0,1,8,58,109,97,116,51,0,18,109,0,16,8,48,0,57,18,98,0,47,0, -18,109,0,16,10,49,0,57,18,98,0,47,0,18,109,0,16,10,50,0,57,18,98,0,47,0,0,0,0,1,0,14,2,21,1,1,0,9, -97,0,0,1,1,0,14,110,0,0,0,1,8,58,109,97,116,51,0,18,97,0,18,110,0,16,8,48,0,57,48,0,18,97,0,18,110, -0,16,10,49,0,57,48,0,18,97,0,18,110,0,16,10,50,0,57,48,0,0,0,0,1,0,14,2,21,1,1,0,14,109,0,0,1,1,0, -9,98,0,0,0,1,8,58,109,97,116,51,0,18,109,0,16,8,48,0,57,18,98,0,48,0,18,109,0,16,10,49,0,57,18,98, -0,48,0,18,109,0,16,10,50,0,57,18,98,0,48,0,0,0,0,1,0,14,2,22,1,1,0,9,97,0,0,1,1,0,14,110,0,0,0,1,8, -58,109,97,116,51,0,18,97,0,18,110,0,16,8,48,0,57,49,0,18,97,0,18,110,0,16,10,49,0,57,49,0,18,97,0, -18,110,0,16,10,50,0,57,49,0,0,0,0,1,0,14,2,22,1,1,0,14,109,0,0,1,1,0,9,98,0,0,0,1,8,58,109,97,116, -51,0,18,109,0,16,8,48,0,57,18,98,0,49,0,18,109,0,16,10,49,0,57,18,98,0,49,0,18,109,0,16,10,50,0,57, -18,98,0,49,0,0,0,0,1,0,15,2,26,1,1,0,9,97,0,0,1,1,0,15,110,0,0,0,1,8,58,109,97,116,52,0,18,97,0,18, -110,0,16,8,48,0,57,46,0,18,97,0,18,110,0,16,10,49,0,57,46,0,18,97,0,18,110,0,16,10,50,0,57,46,0,18, -97,0,18,110,0,16,10,51,0,57,46,0,0,0,0,1,0,15,2,26,1,1,0,15,109,0,0,1,1,0,9,98,0,0,0,1,8,58,109,97, -116,52,0,18,109,0,16,8,48,0,57,18,98,0,46,0,18,109,0,16,10,49,0,57,18,98,0,46,0,18,109,0,16,10,50, -0,57,18,98,0,46,0,18,109,0,16,10,51,0,57,18,98,0,46,0,0,0,0,1,0,15,2,27,1,1,0,9,97,0,0,1,1,0,15, -110,0,0,0,1,8,58,109,97,116,52,0,18,97,0,18,110,0,16,8,48,0,57,47,0,18,97,0,18,110,0,16,10,49,0,57, -47,0,18,97,0,18,110,0,16,10,50,0,57,47,0,18,97,0,18,110,0,16,10,51,0,57,47,0,0,0,0,1,0,15,2,27,1,1, -0,15,109,0,0,1,1,0,9,98,0,0,0,1,8,58,109,97,116,52,0,18,109,0,16,8,48,0,57,18,98,0,47,0,18,109,0, -16,10,49,0,57,18,98,0,47,0,18,109,0,16,10,50,0,57,18,98,0,47,0,18,109,0,16,10,51,0,57,18,98,0,47,0, -0,0,0,1,0,15,2,21,1,1,0,9,97,0,0,1,1,0,15,110,0,0,0,1,8,58,109,97,116,52,0,18,97,0,18,110,0,16,8, -48,0,57,48,0,18,97,0,18,110,0,16,10,49,0,57,48,0,18,97,0,18,110,0,16,10,50,0,57,48,0,18,97,0,18, -110,0,16,10,51,0,57,48,0,0,0,0,1,0,15,2,21,1,1,0,15,109,0,0,1,1,0,9,98,0,0,0,1,8,58,109,97,116,52, -0,18,109,0,16,8,48,0,57,18,98,0,48,0,18,109,0,16,10,49,0,57,18,98,0,48,0,18,109,0,16,10,50,0,57,18, -98,0,48,0,18,109,0,16,10,51,0,57,18,98,0,48,0,0,0,0,1,0,15,2,22,1,1,0,9,97,0,0,1,1,0,15,110,0,0,0, -1,8,58,109,97,116,52,0,18,97,0,18,110,0,16,8,48,0,57,49,0,18,97,0,18,110,0,16,10,49,0,57,49,0,18, -97,0,18,110,0,16,10,50,0,57,49,0,18,97,0,18,110,0,16,10,51,0,57,49,0,0,0,0,1,0,15,2,22,1,1,0,15, -109,0,0,1,1,0,9,98,0,0,0,1,8,58,109,97,116,52,0,18,109,0,16,8,48,0,57,18,98,0,49,0,18,109,0,16,10, -49,0,57,18,98,0,49,0,18,109,0,16,10,50,0,57,18,98,0,49,0,18,109,0,16,10,51,0,57,18,98,0,49,0,0,0,0, -1,0,6,2,26,1,1,0,5,97,0,0,1,1,0,6,117,0,0,0,1,8,58,105,118,101,99,50,0,18,97,0,0,0,18,117,0,46,0,0, -1,0,6,2,26,1,1,0,6,118,0,0,1,1,0,5,98,0,0,0,1,8,18,118,0,58,105,118,101,99,50,0,18,98,0,0,0,46,0,0, -1,0,6,2,27,1,1,0,5,97,0,0,1,1,0,6,117,0,0,0,1,8,58,105,118,101,99,50,0,18,97,0,0,0,18,117,0,47,0,0, -1,0,6,2,27,1,1,0,6,118,0,0,1,1,0,5,98,0,0,0,1,8,18,118,0,58,105,118,101,99,50,0,18,98,0,0,0,47,0,0, -1,0,6,2,21,1,1,0,5,97,0,0,1,1,0,6,117,0,0,0,1,8,58,105,118,101,99,50,0,18,97,0,0,0,18,117,0,48,0,0, -1,0,6,2,21,1,1,0,6,118,0,0,1,1,0,5,98,0,0,0,1,8,18,118,0,58,105,118,101,99,50,0,18,98,0,0,0,48,0,0, -1,0,6,2,22,1,1,0,5,97,0,0,1,1,0,6,117,0,0,0,1,8,58,105,118,101,99,50,0,18,97,0,0,0,18,117,0,49,0,0, -1,0,6,2,22,1,1,0,6,118,0,0,1,1,0,5,98,0,0,0,1,8,18,118,0,58,105,118,101,99,50,0,18,98,0,0,0,49,0,0, -1,0,7,2,26,1,1,0,5,97,0,0,1,1,0,7,117,0,0,0,1,8,58,105,118,101,99,51,0,18,97,0,0,0,18,117,0,46,0,0, -1,0,7,2,26,1,1,0,7,118,0,0,1,1,0,5,98,0,0,0,1,8,18,118,0,58,105,118,101,99,51,0,18,98,0,0,0,46,0,0, -1,0,7,2,27,1,1,0,5,97,0,0,1,1,0,7,117,0,0,0,1,8,58,105,118,101,99,51,0,18,97,0,0,0,18,117,0,47,0,0, -1,0,7,2,27,1,1,0,7,118,0,0,1,1,0,5,98,0,0,0,1,8,18,118,0,58,105,118,101,99,51,0,18,98,0,0,0,47,0,0, -1,0,7,2,21,1,1,0,5,97,0,0,1,1,0,7,117,0,0,0,1,8,58,105,118,101,99,51,0,18,97,0,0,0,18,117,0,48,0,0, -1,0,7,2,21,1,1,0,7,118,0,0,1,1,0,5,98,0,0,0,1,8,18,118,0,58,105,118,101,99,51,0,18,98,0,0,0,48,0,0, -1,0,7,2,22,1,1,0,5,97,0,0,1,1,0,7,117,0,0,0,1,8,58,105,118,101,99,51,0,18,97,0,0,0,18,117,0,49,0,0, -1,0,7,2,22,1,1,0,7,118,0,0,1,1,0,5,98,0,0,0,1,8,18,118,0,58,105,118,101,99,51,0,18,98,0,0,0,49,0,0, -1,0,8,2,26,1,1,0,5,97,0,0,1,1,0,8,117,0,0,0,1,8,58,105,118,101,99,52,0,18,97,0,0,0,18,117,0,46,0,0, -1,0,8,2,26,1,1,0,8,118,0,0,1,1,0,5,98,0,0,0,1,8,18,118,0,58,105,118,101,99,52,0,18,98,0,0,0,46,0,0, -1,0,8,2,27,1,1,0,5,97,0,0,1,1,0,8,117,0,0,0,1,8,58,105,118,101,99,52,0,18,97,0,0,0,18,117,0,47,0,0, -1,0,8,2,27,1,1,0,8,118,0,0,1,1,0,5,98,0,0,0,1,8,18,118,0,58,105,118,101,99,52,0,18,98,0,0,0,47,0,0, -1,0,8,2,21,1,1,0,5,97,0,0,1,1,0,8,117,0,0,0,1,8,58,105,118,101,99,52,0,18,97,0,0,0,18,117,0,48,0,0, -1,0,8,2,21,1,1,0,8,118,0,0,1,1,0,5,98,0,0,0,1,8,18,118,0,58,105,118,101,99,52,0,18,98,0,0,0,48,0,0, -1,0,8,2,22,1,1,0,5,97,0,0,1,1,0,8,117,0,0,0,1,8,58,105,118,101,99,52,0,18,97,0,0,0,18,117,0,49,0,0, -1,0,8,2,22,1,1,0,8,118,0,0,1,1,0,5,98,0,0,0,1,8,18,118,0,58,105,118,101,99,52,0,18,98,0,0,0,49,0,0, -1,0,10,2,27,1,1,0,10,118,0,0,0,1,8,58,118,101,99,50,0,18,118,0,59,120,0,54,0,18,118,0,59,121,0,54, -0,0,0,0,1,0,11,2,27,1,1,0,11,118,0,0,0,1,8,58,118,101,99,51,0,18,118,0,59,120,0,54,0,18,118,0,59, -121,0,54,0,18,118,0,59,122,0,54,0,0,0,0,1,0,12,2,27,1,1,0,12,118,0,0,0,1,8,58,118,101,99,52,0,18, -118,0,59,120,0,54,0,18,118,0,59,121,0,54,0,18,118,0,59,122,0,54,0,18,118,0,59,119,0,54,0,0,0,0,1,0, -6,2,27,1,1,0,6,118,0,0,0,1,8,58,105,118,101,99,50,0,18,118,0,59,120,0,54,0,18,118,0,59,121,0,54,0, -0,0,0,1,0,7,2,27,1,1,0,7,118,0,0,0,1,8,58,105,118,101,99,51,0,18,118,0,59,120,0,54,0,18,118,0,59, -121,0,54,0,18,118,0,59,122,0,54,0,0,0,0,1,0,8,2,27,1,1,0,8,118,0,0,0,1,8,58,105,118,101,99,52,0,18, -118,0,59,120,0,54,0,18,118,0,59,121,0,54,0,18,118,0,59,122,0,54,0,18,118,0,59,119,0,54,0,0,0,0,1,0, -13,2,27,1,1,0,13,109,0,0,0,1,8,58,109,97,116,50,0,18,109,0,16,8,48,0,57,54,0,18,109,0,16,10,49,0, -57,54,0,0,0,0,1,0,14,2,27,1,1,0,14,109,0,0,0,1,8,58,109,97,116,51,0,18,109,0,16,8,48,0,57,54,0,18, -109,0,16,10,49,0,57,54,0,18,109,0,16,10,50,0,57,54,0,0,0,0,1,0,15,2,27,1,1,0,15,109,0,0,0,1,8,58, -109,97,116,52,0,18,109,0,16,8,48,0,57,54,0,18,109,0,16,10,49,0,57,54,0,18,109,0,16,10,50,0,57,54,0, -18,109,0,16,10,51,0,57,54,0,0,0,0,1,0,0,2,25,1,0,2,9,97,0,0,0,1,9,18,97,0,17,49,0,48,0,0,22,0,0,1, -0,0,2,25,1,0,2,5,97,0,0,0,1,9,18,97,0,16,10,49,0,22,0,0,1,0,0,2,25,1,0,2,10,118,0,0,0,1,9,18,118,0, -59,120,0,52,0,9,18,118,0,59,121,0,52,0,0,1,0,0,2,25,1,0,2,11,118,0,0,0,1,9,18,118,0,59,120,0,52,0, -9,18,118,0,59,121,0,52,0,9,18,118,0,59,122,0,52,0,0,1,0,0,2,25,1,0,2,12,118,0,0,0,1,9,18,118,0,59, -120,0,52,0,9,18,118,0,59,121,0,52,0,9,18,118,0,59,122,0,52,0,9,18,118,0,59,119,0,52,0,0,1,0,0,2,25, -1,0,2,6,118,0,0,0,1,9,18,118,0,59,120,0,52,0,9,18,118,0,59,121,0,52,0,0,1,0,0,2,25,1,0,2,7,118,0,0, -0,1,9,18,118,0,59,120,0,52,0,9,18,118,0,59,121,0,52,0,9,18,118,0,59,122,0,52,0,0,1,0,0,2,25,1,0,2, -8,118,0,0,0,1,9,18,118,0,59,120,0,52,0,9,18,118,0,59,121,0,52,0,9,18,118,0,59,122,0,52,0,9,18,118, -0,59,119,0,52,0,0,1,0,0,2,25,1,0,2,13,109,0,0,0,1,9,18,109,0,16,8,48,0,57,52,0,9,18,109,0,16,10,49, -0,57,52,0,0,1,0,0,2,25,1,0,2,14,109,0,0,0,1,9,18,109,0,16,8,48,0,57,52,0,9,18,109,0,16,10,49,0,57, -52,0,9,18,109,0,16,10,50,0,57,52,0,0,1,0,0,2,25,1,0,2,15,109,0,0,0,1,9,18,109,0,16,8,48,0,57,52,0, -9,18,109,0,16,10,49,0,57,52,0,9,18,109,0,16,10,50,0,57,52,0,9,18,109,0,16,10,51,0,57,52,0,0,1,0,0, -2,24,1,0,2,9,97,0,0,0,1,9,18,97,0,17,49,0,48,0,0,21,0,0,1,0,0,2,24,1,0,2,5,97,0,0,0,1,9,18,97,0,16, -10,49,0,21,0,0,1,0,0,2,24,1,0,2,10,118,0,0,0,1,9,18,118,0,59,120,0,51,0,9,18,118,0,59,121,0,51,0,0, -1,0,0,2,24,1,0,2,11,118,0,0,0,1,9,18,118,0,59,120,0,51,0,9,18,118,0,59,121,0,51,0,9,18,118,0,59, -122,0,51,0,0,1,0,0,2,24,1,0,2,12,118,0,0,0,1,9,18,118,0,59,120,0,51,0,9,18,118,0,59,121,0,51,0,9, -18,118,0,59,122,0,51,0,9,18,118,0,59,119,0,51,0,0,1,0,0,2,24,1,0,2,6,118,0,0,0,1,9,18,118,0,59,120, -0,51,0,9,18,118,0,59,121,0,51,0,0,1,0,0,2,24,1,0,2,7,118,0,0,0,1,9,18,118,0,59,120,0,51,0,9,18,118, -0,59,121,0,51,0,9,18,118,0,59,122,0,51,0,0,1,0,0,2,24,1,0,2,8,118,0,0,0,1,9,18,118,0,59,120,0,51,0, -9,18,118,0,59,121,0,51,0,9,18,118,0,59,122,0,51,0,9,18,118,0,59,119,0,51,0,0,1,0,0,2,24,1,0,2,13, -109,0,0,0,1,9,18,109,0,16,8,48,0,57,51,0,9,18,109,0,16,10,49,0,57,51,0,0,1,0,0,2,24,1,0,2,14,109,0, -0,0,1,9,18,109,0,16,8,48,0,57,51,0,9,18,109,0,16,10,49,0,57,51,0,9,18,109,0,16,10,50,0,57,51,0,0,1, -0,0,2,24,1,0,2,15,109,0,0,0,1,9,18,109,0,16,8,48,0,57,51,0,9,18,109,0,16,10,49,0,57,51,0,9,18,109, -0,16,10,50,0,57,51,0,9,18,109,0,16,10,51,0,57,51,0,0,1,0,9,2,25,1,0,2,9,97,0,0,1,1,0,5,0,0,0,1,3,2, -0,9,1,98,0,2,18,97,0,0,0,9,18,97,0,52,0,8,18,98,0,0,0,1,0,5,2,25,1,0,2,5,97,0,0,1,1,0,5,0,0,0,1,3, -2,0,5,1,98,0,2,18,97,0,0,0,9,18,97,0,52,0,8,18,98,0,0,0,1,0,10,2,25,1,0,2,10,118,0,0,1,1,0,5,0,0,0, -1,8,58,118,101,99,50,0,18,118,0,59,120,0,61,0,18,118,0,59,121,0,61,0,0,0,0,1,0,11,2,25,1,0,2,11, -118,0,0,1,1,0,5,0,0,0,1,8,58,118,101,99,51,0,18,118,0,59,120,0,61,0,18,118,0,59,121,0,61,0,18,118, -0,59,122,0,61,0,0,0,0,1,0,12,2,25,1,0,2,12,118,0,0,1,1,0,5,0,0,0,1,8,58,118,101,99,52,0,18,118,0, -59,120,0,61,0,18,118,0,59,121,0,61,0,18,118,0,59,122,0,61,0,18,118,0,59,119,0,61,0,0,0,0,1,0,6,2, -25,1,0,2,6,118,0,0,1,1,0,5,0,0,0,1,8,58,105,118,101,99,50,0,18,118,0,59,120,0,61,0,18,118,0,59,121, -0,61,0,0,0,0,1,0,7,2,25,1,0,2,7,118,0,0,1,1,0,5,0,0,0,1,8,58,105,118,101,99,51,0,18,118,0,59,120,0, -61,0,18,118,0,59,121,0,61,0,18,118,0,59,122,0,61,0,0,0,0,1,0,8,2,25,1,0,2,8,118,0,0,1,1,0,5,0,0,0, -1,8,58,105,118,101,99,52,0,18,118,0,59,120,0,61,0,18,118,0,59,121,0,61,0,18,118,0,59,122,0,61,0,18, -118,0,59,119,0,61,0,0,0,0,1,0,13,2,25,1,0,2,13,109,0,0,1,1,0,5,0,0,0,1,8,58,109,97,116,50,0,18,109, -0,16,8,48,0,57,61,0,18,109,0,16,10,49,0,57,61,0,0,0,0,1,0,14,2,25,1,0,2,14,109,0,0,1,1,0,5,0,0,0,1, -8,58,109,97,116,51,0,18,109,0,16,8,48,0,57,61,0,18,109,0,16,10,49,0,57,61,0,18,109,0,16,10,50,0,57, -61,0,0,0,0,1,0,15,2,25,1,0,2,15,109,0,0,1,1,0,5,0,0,0,1,8,58,109,97,116,52,0,18,109,0,16,8,48,0,57, -61,0,18,109,0,16,10,49,0,57,61,0,18,109,0,16,10,50,0,57,61,0,18,109,0,16,10,51,0,57,61,0,0,0,0,1,0, -9,2,24,1,0,2,9,97,0,0,1,1,0,5,0,0,0,1,3,2,0,9,1,98,0,2,18,97,0,0,0,9,18,97,0,51,0,8,18,98,0,0,0,1, -0,5,2,24,1,0,2,5,97,0,0,1,1,0,5,0,0,0,1,3,2,0,5,1,98,0,2,18,97,0,0,0,9,18,97,0,51,0,8,18,98,0,0,0, -1,0,10,2,24,1,0,2,10,118,0,0,1,1,0,5,0,0,0,1,8,58,118,101,99,50,0,18,118,0,59,120,0,60,0,18,118,0, -59,121,0,60,0,0,0,0,1,0,11,2,24,1,0,2,11,118,0,0,1,1,0,5,0,0,0,1,8,58,118,101,99,51,0,18,118,0,59, -120,0,60,0,18,118,0,59,121,0,60,0,18,118,0,59,122,0,60,0,0,0,0,1,0,12,2,24,1,0,2,12,118,0,0,1,1,0, -5,0,0,0,1,8,58,118,101,99,52,0,18,118,0,59,120,0,60,0,18,118,0,59,121,0,60,0,18,118,0,59,122,0,60, -0,18,118,0,59,119,0,60,0,0,0,0,1,0,6,2,24,1,0,2,6,118,0,0,1,1,0,5,0,0,0,1,8,58,105,118,101,99,50,0, -18,118,0,59,120,0,60,0,18,118,0,59,121,0,60,0,0,0,0,1,0,7,2,24,1,0,2,7,118,0,0,1,1,0,5,0,0,0,1,8, -58,105,118,101,99,51,0,18,118,0,59,120,0,60,0,18,118,0,59,121,0,60,0,18,118,0,59,122,0,60,0,0,0,0, -1,0,8,2,24,1,0,2,8,118,0,0,1,1,0,5,0,0,0,1,8,58,105,118,101,99,52,0,18,118,0,59,120,0,60,0,18,118, -0,59,121,0,60,0,18,118,0,59,122,0,60,0,18,118,0,59,119,0,60,0,0,0,0,1,0,13,2,24,1,0,2,13,109,0,0,1, -1,0,5,0,0,0,1,8,58,109,97,116,50,0,18,109,0,16,8,48,0,57,60,0,18,109,0,16,10,49,0,57,60,0,0,0,0,1, -0,14,2,24,1,0,2,14,109,0,0,1,1,0,5,0,0,0,1,8,58,109,97,116,51,0,18,109,0,16,8,48,0,57,60,0,18,109, -0,16,10,49,0,57,60,0,18,109,0,16,10,50,0,57,60,0,0,0,0,1,0,15,2,24,1,0,2,15,109,0,0,1,1,0,5,0,0,0, -1,8,58,109,97,116,52,0,18,109,0,16,8,48,0,57,60,0,18,109,0,16,10,49,0,57,60,0,18,109,0,16,10,50,0, -57,60,0,18,109,0,16,10,51,0,57,60,0,0,0,0,1,0,1,2,15,1,1,0,9,97,0,0,1,1,0,9,98,0,0,0,1,3,2,0,1,1, -99,0,0,0,4,102,108,111,97,116,95,108,101,115,115,0,18,99,0,0,18,97,0,0,18,98,0,0,0,8,18,99,0,0,0,1, -0,1,2,15,1,1,0,5,97,0,0,1,1,0,5,98,0,0,0,1,8,58,102,108,111,97,116,0,18,97,0,0,0,58,102,108,111,97, -116,0,18,98,0,0,0,40,0,0,1,0,1,2,16,1,1,0,9,97,0,0,1,1,0,9,98,0,0,0,1,3,2,0,1,1,99,0,0,0,4,102,108, -111,97,116,95,108,101,115,115,0,18,99,0,0,18,98,0,0,18,97,0,0,0,8,18,99,0,0,0,1,0,1,2,16,1,1,0,5, -97,0,0,1,1,0,5,98,0,0,0,1,8,58,102,108,111,97,116,0,18,97,0,0,0,58,102,108,111,97,116,0,18,98,0,0, -0,41,0,0,1,0,1,2,18,1,1,0,9,97,0,0,1,1,0,9,98,0,0,0,1,3,2,0,1,1,103,0,0,1,1,101,0,0,0,4,102,108, -111,97,116,95,108,101,115,115,0,18,103,0,0,18,98,0,0,18,97,0,0,0,4,102,108,111,97,116,95,101,113, -117,97,108,0,18,101,0,0,18,97,0,0,18,98,0,0,0,8,18,103,0,18,101,0,32,0,0,1,0,1,2,18,1,1,0,5,97,0,0, -1,1,0,5,98,0,0,0,1,8,58,102,108,111,97,116,0,18,97,0,0,0,58,102,108,111,97,116,0,18,98,0,0,0,43,0, -0,1,0,1,2,17,1,1,0,9,97,0,0,1,1,0,9,98,0,0,0,1,3,2,0,1,1,103,0,0,1,1,101,0,0,0,4,102,108,111,97, -116,95,108,101,115,115,0,18,103,0,0,18,97,0,0,18,98,0,0,0,4,102,108,111,97,116,95,101,113,117,97, -108,0,18,101,0,0,18,97,0,0,18,98,0,0,0,8,18,103,0,18,101,0,32,0,0,1,0,1,2,17,1,1,0,5,97,0,0,1,1,0, -5,98,0,0,0,1,8,58,102,108,111,97,116,0,18,97,0,0,0,58,102,108,111,97,116,0,18,98,0,0,0,42,0,0,1,0, -1,2,11,1,1,0,1,97,0,0,1,1,0,1,98,0,0,0,1,8,18,97,0,18,98,0,39,0,0,1,0,1,2,29,1,1,0,1,97,0,0,0,1,8, -18,97,0,15,2,48,0,38,0,0,1,0,0,0,112,114,105,110,116,77,69,83,65,0,1,1,0,9,102,0,0,0,1,4,102,108, -111,97,116,95,112,114,105,110,116,0,18,102,0,0,0,0,1,0,0,0,112,114,105,110,116,77,69,83,65,0,1,1,0, -5,105,0,0,0,1,4,105,110,116,95,112,114,105,110,116,0,18,105,0,0,0,0,1,0,0,0,112,114,105,110,116,77, -69,83,65,0,1,1,0,1,98,0,0,0,1,4,98,111,111,108,95,112,114,105,110,116,0,18,98,0,0,0,0,1,0,0,0,112, -114,105,110,116,77,69,83,65,0,1,1,0,10,118,0,0,0,1,9,58,112,114,105,110,116,77,69,83,65,0,18,118,0, -59,120,0,0,0,0,9,58,112,114,105,110,116,77,69,83,65,0,18,118,0,59,121,0,0,0,0,0,1,0,0,0,112,114, -105,110,116,77,69,83,65,0,1,1,0,11,118,0,0,0,1,9,58,112,114,105,110,116,77,69,83,65,0,18,118,0,59, -120,0,0,0,0,9,58,112,114,105,110,116,77,69,83,65,0,18,118,0,59,121,0,0,0,0,9,58,112,114,105,110, -116,77,69,83,65,0,18,118,0,59,122,0,0,0,0,0,1,0,0,0,112,114,105,110,116,77,69,83,65,0,1,1,0,12,118, -0,0,0,1,9,58,112,114,105,110,116,77,69,83,65,0,18,118,0,59,120,0,0,0,0,9,58,112,114,105,110,116,77, -69,83,65,0,18,118,0,59,121,0,0,0,0,9,58,112,114,105,110,116,77,69,83,65,0,18,118,0,59,122,0,0,0,0, -9,58,112,114,105,110,116,77,69,83,65,0,18,118,0,59,119,0,0,0,0,0,1,0,0,0,112,114,105,110,116,77,69, -83,65,0,1,1,0,6,118,0,0,0,1,9,58,112,114,105,110,116,77,69,83,65,0,18,118,0,59,120,0,0,0,0,9,58, -112,114,105,110,116,77,69,83,65,0,18,118,0,59,121,0,0,0,0,0,1,0,0,0,112,114,105,110,116,77,69,83, -65,0,1,1,0,7,118,0,0,0,1,9,58,112,114,105,110,116,77,69,83,65,0,18,118,0,59,120,0,0,0,0,9,58,112, -114,105,110,116,77,69,83,65,0,18,118,0,59,121,0,0,0,0,9,58,112,114,105,110,116,77,69,83,65,0,18, -118,0,59,122,0,0,0,0,0,1,0,0,0,112,114,105,110,116,77,69,83,65,0,1,1,0,8,118,0,0,0,1,9,58,112,114, -105,110,116,77,69,83,65,0,18,118,0,59,120,0,0,0,0,9,58,112,114,105,110,116,77,69,83,65,0,18,118,0, -59,121,0,0,0,0,9,58,112,114,105,110,116,77,69,83,65,0,18,118,0,59,122,0,0,0,0,9,58,112,114,105,110, -116,77,69,83,65,0,18,118,0,59,119,0,0,0,0,0,1,0,0,0,112,114,105,110,116,77,69,83,65,0,1,1,0,2,118, -0,0,0,1,9,58,112,114,105,110,116,77,69,83,65,0,18,118,0,59,120,0,0,0,0,9,58,112,114,105,110,116,77, -69,83,65,0,18,118,0,59,121,0,0,0,0,0,1,0,0,0,112,114,105,110,116,77,69,83,65,0,1,1,0,3,118,0,0,0,1, -9,58,112,114,105,110,116,77,69,83,65,0,18,118,0,59,120,0,0,0,0,9,58,112,114,105,110,116,77,69,83, -65,0,18,118,0,59,121,0,0,0,0,9,58,112,114,105,110,116,77,69,83,65,0,18,118,0,59,122,0,0,0,0,0,1,0, -0,0,112,114,105,110,116,77,69,83,65,0,1,1,0,4,118,0,0,0,1,9,58,112,114,105,110,116,77,69,83,65,0, -18,118,0,59,120,0,0,0,0,9,58,112,114,105,110,116,77,69,83,65,0,18,118,0,59,121,0,0,0,0,9,58,112, -114,105,110,116,77,69,83,65,0,18,118,0,59,122,0,0,0,0,9,58,112,114,105,110,116,77,69,83,65,0,18, -118,0,59,119,0,0,0,0,0,1,0,0,0,112,114,105,110,116,77,69,83,65,0,1,1,0,13,109,0,0,0,1,9,58,112,114, -105,110,116,77,69,83,65,0,18,109,0,16,8,48,0,57,0,0,0,9,58,112,114,105,110,116,77,69,83,65,0,18, -109,0,16,10,49,0,57,0,0,0,0,1,0,0,0,112,114,105,110,116,77,69,83,65,0,1,1,0,14,109,0,0,0,1,9,58, +9,18,109,0,16,10,50,0,57,18,97,0,23,0,9,18,109,0,16,10,51,0,57,18,97,0,23,0,0,1,0,0,2,4,1,0,2,15, +109,0,0,1,1,0,9,97,0,0,0,1,9,18,109,0,16,8,48,0,57,18,97,0,24,0,9,18,109,0,16,10,49,0,57,18,97,0, +24,0,9,18,109,0,16,10,50,0,57,18,97,0,24,0,9,18,109,0,16,10,51,0,57,18,97,0,24,0,0,1,0,0,2,3,1,0,2, +10,118,0,0,1,1,0,13,109,0,0,0,1,9,18,118,0,18,118,0,18,109,0,48,20,0,0,1,0,0,2,3,1,0,2,11,118,0,0, +1,1,0,14,109,0,0,0,1,9,18,118,0,18,118,0,18,109,0,48,20,0,0,1,0,0,2,3,1,0,2,12,118,0,0,1,1,0,15, +109,0,0,0,1,9,18,118,0,18,118,0,18,109,0,48,20,0,0,1,0,5,2,25,1,0,2,5,97,0,0,0,1,9,18,97,0,18,97,0, +16,10,49,0,47,20,0,9,18,95,95,114,101,116,86,97,108,0,18,97,0,20,0,0,1,0,6,2,25,1,0,2,6,118,0,0,0, +1,9,18,118,0,18,118,0,58,105,118,101,99,50,0,16,10,49,0,0,0,47,20,0,9,18,95,95,114,101,116,86,97, +108,0,18,118,0,20,0,0,1,0,7,2,25,1,0,2,7,118,0,0,0,1,9,18,118,0,18,118,0,58,105,118,101,99,51,0,16, +10,49,0,0,0,47,20,0,9,18,95,95,114,101,116,86,97,108,0,18,118,0,20,0,0,1,0,8,2,25,1,0,2,8,118,0,0, +0,1,9,18,118,0,18,118,0,58,105,118,101,99,52,0,16,10,49,0,0,0,47,20,0,9,18,95,95,114,101,116,86,97, +108,0,18,118,0,20,0,0,1,0,9,2,25,1,0,2,9,97,0,0,0,1,9,18,97,0,18,97,0,17,49,0,48,0,0,47,20,0,9,18, +95,95,114,101,116,86,97,108,0,18,97,0,20,0,0,1,0,10,2,25,1,0,2,10,118,0,0,0,1,9,18,118,0,18,118,0, +58,118,101,99,50,0,17,49,0,48,0,0,0,0,47,20,0,9,18,95,95,114,101,116,86,97,108,0,18,118,0,20,0,0,1, +0,11,2,25,1,0,2,11,118,0,0,0,1,9,18,118,0,18,118,0,58,118,101,99,51,0,17,49,0,48,0,0,0,0,47,20,0,9, +18,95,95,114,101,116,86,97,108,0,18,118,0,20,0,0,1,0,12,2,25,1,0,2,12,118,0,0,0,1,9,18,118,0,18, +118,0,58,118,101,99,52,0,17,49,0,48,0,0,0,0,47,20,0,9,18,95,95,114,101,116,86,97,108,0,18,118,0,20, +0,0,1,0,13,2,25,1,0,2,13,109,0,0,0,1,9,18,109,0,16,8,48,0,57,18,109,0,16,8,48,0,57,58,118,101,99, +50,0,17,49,0,48,0,0,0,0,47,20,0,9,18,109,0,16,10,49,0,57,18,109,0,16,10,49,0,57,58,118,101,99,50,0, +17,49,0,48,0,0,0,0,47,20,0,9,18,95,95,114,101,116,86,97,108,0,18,109,0,20,0,0,1,0,14,2,25,1,0,2,14, +109,0,0,0,1,9,18,109,0,16,8,48,0,57,18,109,0,16,8,48,0,57,58,118,101,99,51,0,17,49,0,48,0,0,0,0,47, +20,0,9,18,109,0,16,10,49,0,57,18,109,0,16,10,49,0,57,58,118,101,99,51,0,17,49,0,48,0,0,0,0,47,20,0, +9,18,109,0,16,10,50,0,57,18,109,0,16,10,50,0,57,58,118,101,99,51,0,17,49,0,48,0,0,0,0,47,20,0,9,18, +95,95,114,101,116,86,97,108,0,18,109,0,20,0,0,1,0,15,2,25,1,0,2,15,109,0,0,0,1,9,18,109,0,16,8,48, +0,57,18,109,0,16,8,48,0,57,58,118,101,99,52,0,17,49,0,48,0,0,0,0,47,20,0,9,18,109,0,16,10,49,0,57, +18,109,0,16,10,49,0,57,58,118,101,99,52,0,17,49,0,48,0,0,0,0,47,20,0,9,18,109,0,16,10,50,0,57,18, +109,0,16,10,50,0,57,58,118,101,99,52,0,17,49,0,48,0,0,0,0,47,20,0,9,18,109,0,16,10,51,0,57,18,109, +0,16,10,51,0,57,58,118,101,99,52,0,17,49,0,48,0,0,0,0,47,20,0,9,18,95,95,114,101,116,86,97,108,0, +18,109,0,20,0,0,1,0,5,2,24,1,0,2,5,97,0,0,0,1,9,18,97,0,18,97,0,16,10,49,0,46,20,0,9,18,95,95,114, +101,116,86,97,108,0,18,97,0,20,0,0,1,0,6,2,24,1,0,2,6,118,0,0,0,1,9,18,118,0,18,118,0,58,105,118, +101,99,50,0,16,10,49,0,0,0,46,20,0,9,18,95,95,114,101,116,86,97,108,0,18,118,0,20,0,0,1,0,7,2,24,1, +0,2,7,118,0,0,0,1,9,18,118,0,18,118,0,58,105,118,101,99,51,0,16,10,49,0,0,0,46,20,0,9,18,95,95,114, +101,116,86,97,108,0,18,118,0,20,0,0,1,0,8,2,24,1,0,2,8,118,0,0,0,1,9,18,118,0,18,118,0,58,105,118, +101,99,52,0,16,10,49,0,0,0,46,20,0,9,18,95,95,114,101,116,86,97,108,0,18,118,0,20,0,0,1,0,9,2,24,1, +0,2,9,97,0,0,0,1,9,18,97,0,18,97,0,17,49,0,48,0,0,46,20,0,9,18,95,95,114,101,116,86,97,108,0,18,97, +0,20,0,0,1,0,10,2,24,1,0,2,10,118,0,0,0,1,9,18,118,0,18,118,0,58,118,101,99,50,0,17,49,0,48,0,0,0, +0,46,20,0,9,18,95,95,114,101,116,86,97,108,0,18,118,0,20,0,0,1,0,11,2,24,1,0,2,11,118,0,0,0,1,9,18, +118,0,18,118,0,58,118,101,99,51,0,17,49,0,48,0,0,0,0,46,20,0,9,18,95,95,114,101,116,86,97,108,0,18, +118,0,20,0,0,1,0,12,2,24,1,0,2,12,118,0,0,0,1,9,18,118,0,18,118,0,58,118,101,99,52,0,17,49,0,48,0, +0,0,0,46,20,0,9,18,95,95,114,101,116,86,97,108,0,18,118,0,20,0,0,1,0,13,2,24,1,0,2,13,109,0,0,0,1, +9,18,109,0,16,8,48,0,57,18,109,0,16,8,48,0,57,58,118,101,99,50,0,17,49,0,48,0,0,0,0,46,20,0,9,18, +109,0,16,10,49,0,57,18,109,0,16,10,49,0,57,58,118,101,99,50,0,17,49,0,48,0,0,0,0,46,20,0,9,18,95, +95,114,101,116,86,97,108,0,18,109,0,20,0,0,1,0,14,2,24,1,0,2,14,109,0,0,0,1,9,18,109,0,16,8,48,0, +57,18,109,0,16,8,48,0,57,58,118,101,99,51,0,17,49,0,48,0,0,0,0,46,20,0,9,18,109,0,16,10,49,0,57,18, +109,0,16,10,49,0,57,58,118,101,99,51,0,17,49,0,48,0,0,0,0,46,20,0,9,18,109,0,16,10,50,0,57,18,109, +0,16,10,50,0,57,58,118,101,99,51,0,17,49,0,48,0,0,0,0,46,20,0,9,18,95,95,114,101,116,86,97,108,0, +18,109,0,20,0,0,1,0,15,2,24,1,0,2,15,109,0,0,0,1,9,18,109,0,16,8,48,0,57,18,109,0,16,8,48,0,57,58, +118,101,99,52,0,17,49,0,48,0,0,0,0,46,20,0,9,18,109,0,16,10,49,0,57,18,109,0,16,10,49,0,57,58,118, +101,99,52,0,17,49,0,48,0,0,0,0,46,20,0,9,18,109,0,16,10,50,0,57,18,109,0,16,10,50,0,57,58,118,101, +99,52,0,17,49,0,48,0,0,0,0,46,20,0,9,18,109,0,16,10,51,0,57,18,109,0,16,10,51,0,57,58,118,101,99, +52,0,17,49,0,48,0,0,0,0,46,20,0,9,18,95,95,114,101,116,86,97,108,0,18,109,0,20,0,0,1,0,5,0,95,95, +112,111,115,116,68,101,99,114,0,1,0,2,5,97,0,0,0,1,9,18,95,95,114,101,116,86,97,108,0,18,97,0,20,0, +9,18,97,0,18,97,0,16,10,49,0,47,20,0,0,1,0,6,0,95,95,112,111,115,116,68,101,99,114,0,1,0,2,6,118,0, +0,0,1,9,18,95,95,114,101,116,86,97,108,0,18,118,0,20,0,9,18,118,0,18,118,0,58,105,118,101,99,50,0, +16,10,49,0,0,0,47,20,0,0,1,0,7,0,95,95,112,111,115,116,68,101,99,114,0,1,0,2,7,118,0,0,0,1,9,18,95, +95,114,101,116,86,97,108,0,18,118,0,20,0,9,18,118,0,18,118,0,58,105,118,101,99,51,0,16,10,49,0,0,0, +47,20,0,0,1,0,8,0,95,95,112,111,115,116,68,101,99,114,0,1,0,2,8,118,0,0,0,1,9,18,95,95,114,101,116, +86,97,108,0,18,118,0,20,0,9,18,118,0,18,118,0,58,105,118,101,99,52,0,16,10,49,0,0,0,47,20,0,0,1,0, +9,0,95,95,112,111,115,116,68,101,99,114,0,1,0,2,9,97,0,0,0,1,9,18,95,95,114,101,116,86,97,108,0,18, +97,0,20,0,9,18,97,0,18,97,0,17,49,0,48,0,0,47,20,0,0,1,0,10,0,95,95,112,111,115,116,68,101,99,114, +0,1,0,2,10,118,0,0,0,1,9,18,95,95,114,101,116,86,97,108,0,18,118,0,20,0,9,18,118,0,18,118,0,58,118, +101,99,50,0,17,49,0,48,0,0,0,0,47,20,0,0,1,0,11,0,95,95,112,111,115,116,68,101,99,114,0,1,0,2,11, +118,0,0,0,1,9,18,95,95,114,101,116,86,97,108,0,18,118,0,20,0,9,18,118,0,18,118,0,58,118,101,99,51, +0,17,49,0,48,0,0,0,0,47,20,0,0,1,0,12,0,95,95,112,111,115,116,68,101,99,114,0,1,0,2,12,118,0,0,0,1, +9,18,95,95,114,101,116,86,97,108,0,18,118,0,20,0,9,18,118,0,18,118,0,58,118,101,99,52,0,17,49,0,48, +0,0,0,0,47,20,0,0,1,0,13,0,95,95,112,111,115,116,68,101,99,114,0,1,0,2,13,109,0,0,0,1,9,18,95,95, +114,101,116,86,97,108,0,18,109,0,20,0,9,18,109,0,16,8,48,0,57,18,109,0,16,8,48,0,57,58,118,101,99, +50,0,17,49,0,48,0,0,0,0,47,20,0,9,18,109,0,16,10,49,0,57,18,109,0,16,10,49,0,57,58,118,101,99,50,0, +17,49,0,48,0,0,0,0,47,20,0,0,1,0,14,0,95,95,112,111,115,116,68,101,99,114,0,1,0,2,14,109,0,0,0,1,9, +18,95,95,114,101,116,86,97,108,0,18,109,0,20,0,9,18,109,0,16,8,48,0,57,18,109,0,16,8,48,0,57,58, +118,101,99,51,0,17,49,0,48,0,0,0,0,47,20,0,9,18,109,0,16,10,49,0,57,18,109,0,16,10,49,0,57,58,118, +101,99,51,0,17,49,0,48,0,0,0,0,47,20,0,9,18,109,0,16,10,50,0,57,18,109,0,16,10,50,0,57,58,118,101, +99,51,0,17,49,0,48,0,0,0,0,47,20,0,0,1,0,15,0,95,95,112,111,115,116,68,101,99,114,0,1,0,2,15,109,0, +0,0,1,9,18,95,95,114,101,116,86,97,108,0,18,109,0,20,0,9,18,109,0,16,8,48,0,57,18,109,0,16,8,48,0, +57,58,118,101,99,52,0,17,49,0,48,0,0,0,0,47,20,0,9,18,109,0,16,10,49,0,57,18,109,0,16,10,49,0,57, +58,118,101,99,52,0,17,49,0,48,0,0,0,0,47,20,0,9,18,109,0,16,10,50,0,57,18,109,0,16,10,50,0,57,58, +118,101,99,52,0,17,49,0,48,0,0,0,0,47,20,0,9,18,109,0,16,10,51,0,57,18,109,0,16,10,51,0,57,58,118, +101,99,52,0,17,49,0,48,0,0,0,0,47,20,0,0,1,0,9,0,95,95,112,111,115,116,73,110,99,114,0,1,0,2,9,97, +0,0,0,1,9,18,95,95,114,101,116,86,97,108,0,18,97,0,20,0,9,18,97,0,18,97,0,16,10,49,0,46,20,0,0,1,0, +10,0,95,95,112,111,115,116,73,110,99,114,0,1,0,2,10,118,0,0,0,1,9,18,95,95,114,101,116,86,97,108,0, +18,118,0,20,0,9,18,118,0,18,118,0,58,118,101,99,50,0,17,49,0,48,0,0,0,0,46,20,0,0,1,0,11,0,95,95, +112,111,115,116,73,110,99,114,0,1,0,2,11,118,0,0,0,1,9,18,95,95,114,101,116,86,97,108,0,18,118,0, +20,0,9,18,118,0,18,118,0,58,118,101,99,51,0,17,49,0,48,0,0,0,0,46,20,0,0,1,0,12,0,95,95,112,111, +115,116,73,110,99,114,0,1,0,2,12,118,0,0,0,1,9,18,95,95,114,101,116,86,97,108,0,18,118,0,20,0,9,18, +118,0,18,118,0,58,118,101,99,52,0,17,49,0,48,0,0,0,0,46,20,0,0,1,0,5,0,95,95,112,111,115,116,73, +110,99,114,0,1,0,2,5,97,0,0,0,1,9,18,95,95,114,101,116,86,97,108,0,18,97,0,20,0,9,18,97,0,18,97,0, +16,10,49,0,46,20,0,0,1,0,6,0,95,95,112,111,115,116,73,110,99,114,0,1,0,2,6,118,0,0,0,1,9,18,95,95, +114,101,116,86,97,108,0,18,118,0,20,0,9,18,118,0,18,118,0,58,105,118,101,99,50,0,16,10,49,0,0,0,46, +20,0,0,1,0,7,0,95,95,112,111,115,116,73,110,99,114,0,1,0,2,7,118,0,0,0,1,9,18,95,95,114,101,116,86, +97,108,0,18,118,0,20,0,9,18,118,0,18,118,0,58,105,118,101,99,51,0,16,10,49,0,0,0,46,20,0,0,1,0,8,0, +95,95,112,111,115,116,73,110,99,114,0,1,0,2,8,118,0,0,0,1,9,18,95,95,114,101,116,86,97,108,0,18, +118,0,20,0,9,18,118,0,18,118,0,58,105,118,101,99,51,0,16,10,49,0,0,0,46,20,0,0,1,0,13,0,95,95,112, +111,115,116,73,110,99,114,0,1,0,2,13,109,0,0,0,1,3,2,0,13,1,110,0,2,18,109,0,0,0,9,18,109,0,16,8, +48,0,57,18,109,0,16,8,48,0,57,58,118,101,99,50,0,17,49,0,48,0,0,0,0,46,20,0,9,18,109,0,16,10,49,0, +57,18,109,0,16,10,49,0,57,58,118,101,99,50,0,17,49,0,48,0,0,0,0,46,20,0,8,18,110,0,0,0,1,0,14,0,95, +95,112,111,115,116,73,110,99,114,0,1,0,2,14,109,0,0,0,1,3,2,0,14,1,110,0,2,18,109,0,0,0,9,18,109,0, +16,8,48,0,57,18,109,0,16,8,48,0,57,58,118,101,99,51,0,17,49,0,48,0,0,0,0,46,20,0,9,18,109,0,16,10, +49,0,57,18,109,0,16,10,49,0,57,58,118,101,99,51,0,17,49,0,48,0,0,0,0,46,20,0,9,18,109,0,16,10,50,0, +57,18,109,0,16,10,50,0,57,58,118,101,99,51,0,17,49,0,48,0,0,0,0,46,20,0,8,18,110,0,0,0,1,0,15,0,95, +95,112,111,115,116,73,110,99,114,0,1,0,2,15,109,0,0,0,1,3,2,0,15,1,110,0,2,18,109,0,0,0,9,18,109,0, +16,8,48,0,57,18,109,0,16,8,48,0,57,58,118,101,99,52,0,17,49,0,48,0,0,0,0,46,20,0,9,18,109,0,16,10, +49,0,57,18,109,0,16,10,49,0,57,58,118,101,99,52,0,17,49,0,48,0,0,0,0,46,20,0,9,18,109,0,16,10,50,0, +57,18,109,0,16,10,50,0,57,58,118,101,99,52,0,17,49,0,48,0,0,0,0,46,20,0,9,18,109,0,16,10,51,0,57, +18,109,0,16,10,51,0,57,58,118,101,99,52,0,17,49,0,48,0,0,0,0,46,20,0,8,18,110,0,0,0,1,0,1,2,15,1,1, +0,9,97,0,0,1,1,0,9,98,0,0,0,1,4,118,101,99,52,95,115,103,116,0,18,95,95,114,101,116,86,97,108,0,59, +120,0,0,18,98,0,0,18,97,0,0,0,0,1,0,1,2,15,1,1,0,5,97,0,0,1,1,0,5,98,0,0,0,1,8,58,102,108,111,97, +116,0,18,97,0,0,0,58,102,108,111,97,116,0,18,98,0,0,0,40,0,0,1,0,1,2,16,1,1,0,9,97,0,0,1,1,0,9,98, +0,0,0,1,3,2,0,1,1,99,0,0,0,4,102,108,111,97,116,95,108,101,115,115,0,18,99,0,0,18,98,0,0,18,97,0,0, +0,8,18,99,0,0,0,1,0,1,2,16,1,1,0,5,97,0,0,1,1,0,5,98,0,0,0,1,8,58,102,108,111,97,116,0,18,97,0,0,0, +58,102,108,111,97,116,0,18,98,0,0,0,41,0,0,1,0,1,2,18,1,1,0,9,97,0,0,1,1,0,9,98,0,0,0,1,3,2,0,1,1, +103,0,0,1,1,101,0,0,0,4,102,108,111,97,116,95,108,101,115,115,0,18,103,0,0,18,98,0,0,18,97,0,0,0,4, +102,108,111,97,116,95,101,113,117,97,108,0,18,101,0,0,18,97,0,0,18,98,0,0,0,8,18,103,0,18,101,0,32, +0,0,1,0,1,2,18,1,1,0,5,97,0,0,1,1,0,5,98,0,0,0,1,8,58,102,108,111,97,116,0,18,97,0,0,0,58,102,108, +111,97,116,0,18,98,0,0,0,43,0,0,1,0,1,2,17,1,1,0,9,97,0,0,1,1,0,9,98,0,0,0,1,3,2,0,1,1,103,0,0,1,1, +101,0,0,0,4,102,108,111,97,116,95,108,101,115,115,0,18,103,0,0,18,97,0,0,18,98,0,0,0,4,102,108,111, +97,116,95,101,113,117,97,108,0,18,101,0,0,18,97,0,0,18,98,0,0,0,8,18,103,0,18,101,0,32,0,0,1,0,1,2, +17,1,1,0,5,97,0,0,1,1,0,5,98,0,0,0,1,8,58,102,108,111,97,116,0,18,97,0,0,0,58,102,108,111,97,116,0, +18,98,0,0,0,42,0,0,1,0,1,0,95,95,108,111,103,105,99,97,108,78,111,116,0,1,1,0,1,97,0,0,0,1,10,18, +97,0,0,8,15,2,48,0,0,9,14,0,8,15,2,49,0,0,0,1,0,1,0,95,95,108,111,103,105,99,97,108,88,111,114,0,1, +1,0,1,97,0,0,1,1,0,1,98,0,0,0,1,10,18,97,0,0,8,58,95,95,108,111,103,105,99,97,108,78,111,116,0,18, +98,0,0,0,0,9,14,0,8,18,98,0,0,0,1,0,0,0,112,114,105,110,116,77,69,83,65,0,1,1,0,9,102,0,0,0,1,4, +102,108,111,97,116,95,112,114,105,110,116,0,18,102,0,0,0,0,1,0,0,0,112,114,105,110,116,77,69,83,65, +0,1,1,0,5,105,0,0,0,1,4,105,110,116,95,112,114,105,110,116,0,18,105,0,0,0,0,1,0,0,0,112,114,105, +110,116,77,69,83,65,0,1,1,0,1,98,0,0,0,1,4,98,111,111,108,95,112,114,105,110,116,0,18,98,0,0,0,0,1, +0,0,0,112,114,105,110,116,77,69,83,65,0,1,1,0,10,118,0,0,0,1,9,58,112,114,105,110,116,77,69,83,65, +0,18,118,0,59,120,0,0,0,0,9,58,112,114,105,110,116,77,69,83,65,0,18,118,0,59,121,0,0,0,0,0,1,0,0,0, +112,114,105,110,116,77,69,83,65,0,1,1,0,11,118,0,0,0,1,9,58,112,114,105,110,116,77,69,83,65,0,18, +118,0,59,120,0,0,0,0,9,58,112,114,105,110,116,77,69,83,65,0,18,118,0,59,121,0,0,0,0,9,58,112,114, +105,110,116,77,69,83,65,0,18,118,0,59,122,0,0,0,0,0,1,0,0,0,112,114,105,110,116,77,69,83,65,0,1,1, +0,12,118,0,0,0,1,9,58,112,114,105,110,116,77,69,83,65,0,18,118,0,59,120,0,0,0,0,9,58,112,114,105, +110,116,77,69,83,65,0,18,118,0,59,121,0,0,0,0,9,58,112,114,105,110,116,77,69,83,65,0,18,118,0,59, +122,0,0,0,0,9,58,112,114,105,110,116,77,69,83,65,0,18,118,0,59,119,0,0,0,0,0,1,0,0,0,112,114,105, +110,116,77,69,83,65,0,1,1,0,6,118,0,0,0,1,9,58,112,114,105,110,116,77,69,83,65,0,18,118,0,59,120,0, +0,0,0,9,58,112,114,105,110,116,77,69,83,65,0,18,118,0,59,121,0,0,0,0,0,1,0,0,0,112,114,105,110,116, +77,69,83,65,0,1,1,0,7,118,0,0,0,1,9,58,112,114,105,110,116,77,69,83,65,0,18,118,0,59,120,0,0,0,0,9, +58,112,114,105,110,116,77,69,83,65,0,18,118,0,59,121,0,0,0,0,9,58,112,114,105,110,116,77,69,83,65, +0,18,118,0,59,122,0,0,0,0,0,1,0,0,0,112,114,105,110,116,77,69,83,65,0,1,1,0,8,118,0,0,0,1,9,58,112, +114,105,110,116,77,69,83,65,0,18,118,0,59,120,0,0,0,0,9,58,112,114,105,110,116,77,69,83,65,0,18, +118,0,59,121,0,0,0,0,9,58,112,114,105,110,116,77,69,83,65,0,18,118,0,59,122,0,0,0,0,9,58,112,114, +105,110,116,77,69,83,65,0,18,118,0,59,119,0,0,0,0,0,1,0,0,0,112,114,105,110,116,77,69,83,65,0,1,1, +0,2,118,0,0,0,1,9,58,112,114,105,110,116,77,69,83,65,0,18,118,0,59,120,0,0,0,0,9,58,112,114,105, +110,116,77,69,83,65,0,18,118,0,59,121,0,0,0,0,0,1,0,0,0,112,114,105,110,116,77,69,83,65,0,1,1,0,3, +118,0,0,0,1,9,58,112,114,105,110,116,77,69,83,65,0,18,118,0,59,120,0,0,0,0,9,58,112,114,105,110, +116,77,69,83,65,0,18,118,0,59,121,0,0,0,0,9,58,112,114,105,110,116,77,69,83,65,0,18,118,0,59,122,0, +0,0,0,0,1,0,0,0,112,114,105,110,116,77,69,83,65,0,1,1,0,4,118,0,0,0,1,9,58,112,114,105,110,116,77, +69,83,65,0,18,118,0,59,120,0,0,0,0,9,58,112,114,105,110,116,77,69,83,65,0,18,118,0,59,121,0,0,0,0, +9,58,112,114,105,110,116,77,69,83,65,0,18,118,0,59,122,0,0,0,0,9,58,112,114,105,110,116,77,69,83, +65,0,18,118,0,59,119,0,0,0,0,0,1,0,0,0,112,114,105,110,116,77,69,83,65,0,1,1,0,13,109,0,0,0,1,9,58, 112,114,105,110,116,77,69,83,65,0,18,109,0,16,8,48,0,57,0,0,0,9,58,112,114,105,110,116,77,69,83,65, -0,18,109,0,16,10,49,0,57,0,0,0,9,58,112,114,105,110,116,77,69,83,65,0,18,109,0,16,10,50,0,57,0,0,0, -0,1,0,0,0,112,114,105,110,116,77,69,83,65,0,1,1,0,15,109,0,0,0,1,9,58,112,114,105,110,116,77,69,83, -65,0,18,109,0,16,8,48,0,57,0,0,0,9,58,112,114,105,110,116,77,69,83,65,0,18,109,0,16,10,49,0,57,0,0, -0,9,58,112,114,105,110,116,77,69,83,65,0,18,109,0,16,10,50,0,57,0,0,0,9,58,112,114,105,110,116,77, -69,83,65,0,18,109,0,16,10,51,0,57,0,0,0,0,1,0,0,0,112,114,105,110,116,77,69,83,65,0,1,1,0,16,101,0, -0,0,1,4,105,110,116,95,112,114,105,110,116,0,18,101,0,0,0,0,1,0,0,0,112,114,105,110,116,77,69,83, -65,0,1,1,0,17,101,0,0,0,1,4,105,110,116,95,112,114,105,110,116,0,18,101,0,0,0,0,1,0,0,0,112,114, -105,110,116,77,69,83,65,0,1,1,0,18,101,0,0,0,1,4,105,110,116,95,112,114,105,110,116,0,18,101,0,0,0, -0,1,0,0,0,112,114,105,110,116,77,69,83,65,0,1,1,0,19,101,0,0,0,1,4,105,110,116,95,112,114,105,110, -116,0,18,101,0,0,0,0,1,0,0,0,112,114,105,110,116,77,69,83,65,0,1,1,0,20,101,0,0,0,1,4,105,110,116, -95,112,114,105,110,116,0,18,101,0,0,0,0,1,0,0,0,112,114,105,110,116,77,69,83,65,0,1,1,0,21,101,0,0, -0,1,4,105,110,116,95,112,114,105,110,116,0,18,101,0,0,0,0,0 +0,18,109,0,16,10,49,0,57,0,0,0,0,1,0,0,0,112,114,105,110,116,77,69,83,65,0,1,1,0,14,109,0,0,0,1,9, +58,112,114,105,110,116,77,69,83,65,0,18,109,0,16,8,48,0,57,0,0,0,9,58,112,114,105,110,116,77,69,83, +65,0,18,109,0,16,10,49,0,57,0,0,0,9,58,112,114,105,110,116,77,69,83,65,0,18,109,0,16,10,50,0,57,0, +0,0,0,1,0,0,0,112,114,105,110,116,77,69,83,65,0,1,1,0,15,109,0,0,0,1,9,58,112,114,105,110,116,77, +69,83,65,0,18,109,0,16,8,48,0,57,0,0,0,9,58,112,114,105,110,116,77,69,83,65,0,18,109,0,16,10,49,0, +57,0,0,0,9,58,112,114,105,110,116,77,69,83,65,0,18,109,0,16,10,50,0,57,0,0,0,9,58,112,114,105,110, +116,77,69,83,65,0,18,109,0,16,10,51,0,57,0,0,0,0,1,0,0,0,112,114,105,110,116,77,69,83,65,0,1,1,0, +16,101,0,0,0,1,4,105,110,116,95,112,114,105,110,116,0,18,101,0,0,0,0,1,0,0,0,112,114,105,110,116, +77,69,83,65,0,1,1,0,17,101,0,0,0,1,4,105,110,116,95,112,114,105,110,116,0,18,101,0,0,0,0,1,0,0,0, +112,114,105,110,116,77,69,83,65,0,1,1,0,18,101,0,0,0,1,4,105,110,116,95,112,114,105,110,116,0,18, +101,0,0,0,0,1,0,0,0,112,114,105,110,116,77,69,83,65,0,1,1,0,19,101,0,0,0,1,4,105,110,116,95,112, +114,105,110,116,0,18,101,0,0,0,0,1,0,0,0,112,114,105,110,116,77,69,83,65,0,1,1,0,20,101,0,0,0,1,4, +105,110,116,95,112,114,105,110,116,0,18,101,0,0,0,0,1,0,0,0,112,114,105,110,116,77,69,83,65,0,1,1, +0,21,101,0,0,0,1,4,105,110,116,95,112,114,105,110,116,0,18,101,0,0,0,0,0 diff --git a/src/mesa/shader/slang/library/slang_fragment_builtin.gc b/src/mesa/shader/slang/library/slang_fragment_builtin.gc index 373b42de1d..9a7e17bdaf 100755..100644 --- a/src/mesa/shader/slang/library/slang_fragment_builtin.gc +++ b/src/mesa/shader/slang/library/slang_fragment_builtin.gc @@ -23,11 +23,6 @@ */ // -// TODO: -// - implement dFdx, dFdy, -// - -// // From Shader Spec, ver. 1.10, rev. 59 // @@ -42,131 +37,240 @@ varying vec4 gl_SecondaryColor; varying vec4 gl_TexCoord[gl_MaxTextureCoords]; varying float gl_FogFragCoord; -// -// 8.7 Texture Lookup Functions -// -vec4 texture1D (sampler1D sampler, float coord, float bias) { - vec4 texel; - __asm vec4_tex1d texel, sampler, coord, bias; - return texel; + +//// 8.7 Texture Lookup Functions (with bias) + +vec4 texture1D(const sampler1D sampler, const float coord, const float bias) +{ + vec4 coord4; + coord4.x = coord; + coord4.w = bias; + __asm vec4_texb1d __retVal, sampler, coord4; } -vec4 texture1DProj (sampler1D sampler, vec2 coord, float bias) { - return texture1D (sampler, coord.s / coord.t, bias); +vec4 texture1DProj(const sampler1D sampler, const vec2 coord, const float bias) +{ + // do projection here (there's no vec4_texbp1d instruction) + vec4 pcoord; + pcoord.x = coord.x / coord.y; + pcoord.w = bias; + __asm vec4_texb1d __retVal, sampler, pcoord; } -vec4 texture1DProj (sampler1D sampler, vec4 coord, float bias) { - return texture1D (sampler, coord.s / coord.q, bias); +vec4 texture1DProj(const sampler1D sampler, const vec4 coord, const float bias) +{ + // do projection here (there's no vec4_texbp1d instruction) + vec4 pcoord; + pcoord.x = coord.x / coord.z; + pcoord.w = bias; + __asm vec4_texb1d __retVal, sampler, pcoord; } -vec4 texture2D (sampler2D sampler, vec2 coord, float bias) { - vec4 texel; - __asm vec4_tex2d texel, sampler, coord, bias; - return texel; + + + +vec4 texture2D(const sampler2D sampler, const vec2 coord, const float bias) +{ + vec4 coord4; + coord4.xy = coord.xy; + coord4.w = bias; + __asm vec4_texb2d __retVal, sampler, coord4; } -vec4 texture2DProj (sampler2D sampler, vec3 coord, float bias) { - return texture2D (sampler, vec2 (coord.s / coord.p, coord.t / coord.p), bias); +vec4 texture2DProj(const sampler2D sampler, const vec3 coord, const float bias) +{ + // do projection here (there's no vec4_texbp2d instruction) + vec4 pcoord; + pcoord.xy = coord.xy / coord.z; + pcoord.w = bias; + __asm vec4_texb2d __retVal, sampler, pcoord; } -vec4 texture2DProj (sampler2D sampler, vec4 coord, float bias) { - return texture2D (sampler, vec2 (coord.s / coord.q, coord.t / coord.q), bias); +vec4 texture2DProj(const sampler2D sampler, const vec4 coord, const float bias) +{ + // do projection here (there's no vec4_texbp2d instruction) + vec4 pcoord; + pcoord.xy = coord.xy / coord.w; + pcoord.w = bias; + __asm vec4_texb2d __retVal, sampler, pcoord; } -vec4 texture3D (sampler3D sampler, vec3 coord, float bias) { - vec4 texel; - __asm vec4_tex3d texel, sampler, coord, bias; - return texel; + + + +vec4 texture3D(const sampler3D sampler, const vec3 coord, const float bias) +{ + vec4 coord4; + coord4.xyz = coord.xyz; + coord4.w = bias; + __asm vec4_texb3d __retVal, sampler, coord4; } -vec4 texture3DProj (sampler3D sampler, vec4 coord, float bias) { - return texture3D (sampler, vec3 (coord.s / coord.q, coord.t / coord.q, coord.p / coord.q), bias); +vec4 texture3DProj(const sampler3D sampler, const vec4 coord, const float bias) +{ + // do projection here (there's no vec4_texbp3d instruction) + vec4 pcoord; + pcoord.xyz = coord.xyz / coord.w; + pcoord.w = bias; + __asm vec4_texb3d __retVal, sampler, pcoord; } -vec4 textureCube (samplerCube sampler, vec3 coord, float bias) { - vec4 texel; - __asm vec4_texcube texel, sampler, coord, bias; - return texel; + + + +vec4 textureCube(const samplerCube sampler, const vec3 coord, const float bias) +{ + vec4 coord4; + coord4.xyz = coord; + coord4.w = bias; + __asm vec4_texcube __retVal, sampler, coord4; } -vec4 shadow1D (sampler1DShadow sampler, vec3 coord, float bias) { - vec4 texel; - __asm vec4_shad1d texel, sampler, coord, bias; - return texel; + + + +// For shadow textures, we use the regular tex instructions since they should +// do the depth comparison step. + +vec4 shadow1D(const sampler1DShadow sampler, const vec3 coord, const float bias) +{ + vec4 coord4; + coord4.xyz = coord; + coord4.w = bias; + __asm vec4_texb1d __retVal, sampler, coord4; +} + +vec4 shadow1DProj(const sampler1DShadow sampler, const vec4 coord, const float bias) +{ + vec4 pcoord; + pcoord.x = coord.x / coord.w; + pcoord.z = coord.z; + pcoord.w = bias; + __asm vec4_texb1d __retVal, sampler, pcoord; +} + + + + +vec4 shadow2D(const sampler2DShadow sampler, const vec3 coord, const float bias) +{ + vec4 coord4; + coord4.xyz = coord; + coord4.w = bias; + __asm vec4_texb2d __retVal, sampler, coord4; +} + +vec4 shadow2DProj(const sampler2DShadow sampler, const vec4 coord, const float bias) +{ + vec4 pcoord; + pcoord.xy = coord.xy / coord.w; + pcoord.z = coord.z; + pcoord.w = bias; + __asm vec4_texb2d __retVal, sampler, pcoord; +} + + + +//// GL_ARB_texture_rectangle: +vec4 texture2DRect(const sampler2DRect sampler, const vec2 coord) +{ + __asm vec4_tex_rect __retVal, sampler, coord; } -vec4 shadow1DProj (sampler1DShadow sampler, vec4 coord, float bias) { - return shadow1D (sampler, vec3 (coord.s / coord.q, 0.0, coord.p / coord.q), bias); +vec4 texture2DRectProj(const sampler2DRect sampler, const vec3 coord) +{ + // do projection here + vec4 pcoord; + pcoord.xy = coord.xy / coord.z; + __asm vec4_texp_rect __retVal, sampler, pcoord; } -vec4 shadow2D (sampler2DShadow sampler, vec3 coord, float bias) { - vec4 texel; - __asm vec4_shad2d texel, sampler, coord, bias; - return texel; +vec4 texture2DRectProj(const sampler2DRect sampler, const vec4 coord) +{ + // do projection here + vec4 pcoord; + pcoord.xy = coord.xy / coord.w; + __asm vec4_texp_rect __retVal, sampler, pcoord; } -vec4 shadow2DProj (sampler2DShadow sampler, vec4 coord, float bias) { - return shadow2D (sampler, vec3 (coord.s / coord.q, coord.t / coord.q, coord.p / coord.q), bias); +vec4 shadow2DRect(const sampler2DRectShadow sampler, const vec3 coord) +{ +// XXX to do } +vec4 shadow2DRectProj(const sampler2DRectShadow sampler, const vec4 coord) +{ +// XXX to do +} + + + // // 8.8 Fragment Processing Functions // -float dFdx (float p) { - // XXX: - return 0.001; +float dFdx(const float p) +{ + __asm vec4_ddx __retVal.x, p.xxxx; } -vec2 dFdx (vec2 p) { - // XXX: - return vec2 (0.001); +vec2 dFdx(const vec2 p) +{ + __asm vec4_ddx __retVal.xy, p.xyyy; } -vec3 dFdx (vec3 p) { - // XXX: - return vec3 (0.001); +vec3 dFdx(const vec3 p) +{ + __asm vec4_ddx __retVal.xyz, p.xyzz; } -vec4 dFdx (vec4 p) { - // XXX: - return vec4 (0.001); +vec4 dFdx(const vec4 p) +{ + __asm vec4_ddx __retVal, p; } -float dFdy (float p) { - // XXX: - return 0.001; +float dFdy(const float p) +{ + __asm vec4_ddy __retVal.x, p.xxxx; } -vec2 dFdy (vec2 p) { - // XXX: - return vec2 (0.001); +vec2 dFdy(const vec2 p) +{ + __asm vec4_ddy __retVal.xy, p.xyyy; } -vec3 dFdy (vec3 p) { - // XXX: - return vec3 (0.001); +vec3 dFdy(const vec3 p) +{ + __asm vec4_ddy __retVal.xyz, p.xyzz; } -vec4 dFdy (vec4 p) { - // XXX: - return vec4 (0.001); +vec4 dFdy(const vec4 p) +{ + __asm vec4_ddy __retVal, p; } -float fwidth (float p) { - return abs (dFdx (p)) + abs (dFdy (p)); +float fwidth (const float p) +{ + // XXX hand-write with __asm + return abs(dFdx(p)) + abs(dFdy(p)); } -vec2 fwidth (vec2 p) { - return abs (dFdx (p)) + abs (dFdy (p)); +vec2 fwidth(const vec2 p) +{ + // XXX hand-write with __asm + return abs(dFdx(p)) + abs(dFdy(p)); } -vec3 fwidth (vec3 p) { - return abs (dFdx (p)) + abs (dFdy (p)); +vec3 fwidth(const vec3 p) +{ + // XXX hand-write with __asm + return abs(dFdx(p)) + abs(dFdy(p)); } -vec4 fwidth (vec4 p) { - return abs (dFdx (p)) + abs (dFdy (p)); +vec4 fwidth(const vec4 p) +{ + // XXX hand-write with __asm + return abs(dFdx(p)) + abs(dFdy(p)); } diff --git a/src/mesa/shader/slang/library/slang_fragment_builtin_gc.h b/src/mesa/shader/slang/library/slang_fragment_builtin_gc.h index b7f1d3816c..88317107b2 100644 --- a/src/mesa/shader/slang/library/slang_fragment_builtin_gc.h +++ b/src/mesa/shader/slang/library/slang_fragment_builtin_gc.h @@ -9,71 +9,107 @@ 108,95,67,111,108,111,114,0,0,0,2,2,3,12,1,103,108,95,83,101,99,111,110,100,97,114,121,67,111,108, 111,114,0,0,0,2,2,3,12,1,103,108,95,84,101,120,67,111,111,114,100,0,3,18,103,108,95,77,97,120,84, 101,120,116,117,114,101,67,111,111,114,100,115,0,0,0,2,2,3,9,1,103,108,95,70,111,103,70,114,97,103, -67,111,111,114,100,0,0,0,1,0,12,0,116,101,120,116,117,114,101,49,68,0,1,0,0,16,115,97,109,112,108, -101,114,0,0,1,0,0,9,99,111,111,114,100,0,0,1,0,0,9,98,105,97,115,0,0,0,1,3,2,0,12,1,116,101,120, -101,108,0,0,0,4,118,101,99,52,95,116,101,120,49,100,0,18,116,101,120,101,108,0,0,18,115,97,109,112, -108,101,114,0,0,18,99,111,111,114,100,0,0,18,98,105,97,115,0,0,0,8,18,116,101,120,101,108,0,0,0,1, -0,12,0,116,101,120,116,117,114,101,49,68,80,114,111,106,0,1,0,0,16,115,97,109,112,108,101,114,0,0, -1,0,0,10,99,111,111,114,100,0,0,1,0,0,9,98,105,97,115,0,0,0,1,8,58,116,101,120,116,117,114,101,49, -68,0,18,115,97,109,112,108,101,114,0,0,18,99,111,111,114,100,0,59,115,0,18,99,111,111,114,100,0,59, -116,0,49,0,18,98,105,97,115,0,0,0,0,0,1,0,12,0,116,101,120,116,117,114,101,49,68,80,114,111,106,0, -1,0,0,16,115,97,109,112,108,101,114,0,0,1,0,0,12,99,111,111,114,100,0,0,1,0,0,9,98,105,97,115,0,0, -0,1,8,58,116,101,120,116,117,114,101,49,68,0,18,115,97,109,112,108,101,114,0,0,18,99,111,111,114, -100,0,59,115,0,18,99,111,111,114,100,0,59,113,0,49,0,18,98,105,97,115,0,0,0,0,0,1,0,12,0,116,101, -120,116,117,114,101,50,68,0,1,0,0,17,115,97,109,112,108,101,114,0,0,1,0,0,10,99,111,111,114,100,0, -0,1,0,0,9,98,105,97,115,0,0,0,1,3,2,0,12,1,116,101,120,101,108,0,0,0,4,118,101,99,52,95,116,101, -120,50,100,0,18,116,101,120,101,108,0,0,18,115,97,109,112,108,101,114,0,0,18,99,111,111,114,100,0, -0,18,98,105,97,115,0,0,0,8,18,116,101,120,101,108,0,0,0,1,0,12,0,116,101,120,116,117,114,101,50,68, -80,114,111,106,0,1,0,0,17,115,97,109,112,108,101,114,0,0,1,0,0,11,99,111,111,114,100,0,0,1,0,0,9, -98,105,97,115,0,0,0,1,8,58,116,101,120,116,117,114,101,50,68,0,18,115,97,109,112,108,101,114,0,0, -58,118,101,99,50,0,18,99,111,111,114,100,0,59,115,0,18,99,111,111,114,100,0,59,112,0,49,0,18,99, -111,111,114,100,0,59,116,0,18,99,111,111,114,100,0,59,112,0,49,0,0,0,18,98,105,97,115,0,0,0,0,0,1, -0,12,0,116,101,120,116,117,114,101,50,68,80,114,111,106,0,1,0,0,17,115,97,109,112,108,101,114,0,0, -1,0,0,12,99,111,111,114,100,0,0,1,0,0,9,98,105,97,115,0,0,0,1,8,58,116,101,120,116,117,114,101,50, -68,0,18,115,97,109,112,108,101,114,0,0,58,118,101,99,50,0,18,99,111,111,114,100,0,59,115,0,18,99, -111,111,114,100,0,59,113,0,49,0,18,99,111,111,114,100,0,59,116,0,18,99,111,111,114,100,0,59,113,0, -49,0,0,0,18,98,105,97,115,0,0,0,0,0,1,0,12,0,116,101,120,116,117,114,101,51,68,0,1,0,0,18,115,97, -109,112,108,101,114,0,0,1,0,0,11,99,111,111,114,100,0,0,1,0,0,9,98,105,97,115,0,0,0,1,3,2,0,12,1, -116,101,120,101,108,0,0,0,4,118,101,99,52,95,116,101,120,51,100,0,18,116,101,120,101,108,0,0,18, -115,97,109,112,108,101,114,0,0,18,99,111,111,114,100,0,0,18,98,105,97,115,0,0,0,8,18,116,101,120, -101,108,0,0,0,1,0,12,0,116,101,120,116,117,114,101,51,68,80,114,111,106,0,1,0,0,18,115,97,109,112, -108,101,114,0,0,1,0,0,12,99,111,111,114,100,0,0,1,0,0,9,98,105,97,115,0,0,0,1,8,58,116,101,120,116, -117,114,101,51,68,0,18,115,97,109,112,108,101,114,0,0,58,118,101,99,51,0,18,99,111,111,114,100,0, -59,115,0,18,99,111,111,114,100,0,59,113,0,49,0,18,99,111,111,114,100,0,59,116,0,18,99,111,111,114, -100,0,59,113,0,49,0,18,99,111,111,114,100,0,59,112,0,18,99,111,111,114,100,0,59,113,0,49,0,0,0,18, -98,105,97,115,0,0,0,0,0,1,0,12,0,116,101,120,116,117,114,101,67,117,98,101,0,1,0,0,19,115,97,109, -112,108,101,114,0,0,1,0,0,11,99,111,111,114,100,0,0,1,0,0,9,98,105,97,115,0,0,0,1,3,2,0,12,1,116, -101,120,101,108,0,0,0,4,118,101,99,52,95,116,101,120,99,117,98,101,0,18,116,101,120,101,108,0,0,18, -115,97,109,112,108,101,114,0,0,18,99,111,111,114,100,0,0,18,98,105,97,115,0,0,0,8,18,116,101,120, -101,108,0,0,0,1,0,12,0,115,104,97,100,111,119,49,68,0,1,0,0,20,115,97,109,112,108,101,114,0,0,1,0, -0,11,99,111,111,114,100,0,0,1,0,0,9,98,105,97,115,0,0,0,1,3,2,0,12,1,116,101,120,101,108,0,0,0,4, -118,101,99,52,95,115,104,97,100,49,100,0,18,116,101,120,101,108,0,0,18,115,97,109,112,108,101,114, -0,0,18,99,111,111,114,100,0,0,18,98,105,97,115,0,0,0,8,18,116,101,120,101,108,0,0,0,1,0,12,0,115, -104,97,100,111,119,49,68,80,114,111,106,0,1,0,0,20,115,97,109,112,108,101,114,0,0,1,0,0,12,99,111, -111,114,100,0,0,1,0,0,9,98,105,97,115,0,0,0,1,8,58,115,104,97,100,111,119,49,68,0,18,115,97,109, -112,108,101,114,0,0,58,118,101,99,51,0,18,99,111,111,114,100,0,59,115,0,18,99,111,111,114,100,0,59, -113,0,49,0,17,48,0,48,0,0,0,18,99,111,111,114,100,0,59,112,0,18,99,111,111,114,100,0,59,113,0,49,0, -0,0,18,98,105,97,115,0,0,0,0,0,1,0,12,0,115,104,97,100,111,119,50,68,0,1,0,0,21,115,97,109,112,108, -101,114,0,0,1,0,0,11,99,111,111,114,100,0,0,1,0,0,9,98,105,97,115,0,0,0,1,3,2,0,12,1,116,101,120, -101,108,0,0,0,4,118,101,99,52,95,115,104,97,100,50,100,0,18,116,101,120,101,108,0,0,18,115,97,109, -112,108,101,114,0,0,18,99,111,111,114,100,0,0,18,98,105,97,115,0,0,0,8,18,116,101,120,101,108,0,0, -0,1,0,12,0,115,104,97,100,111,119,50,68,80,114,111,106,0,1,0,0,21,115,97,109,112,108,101,114,0,0,1, -0,0,12,99,111,111,114,100,0,0,1,0,0,9,98,105,97,115,0,0,0,1,8,58,115,104,97,100,111,119,50,68,0,18, -115,97,109,112,108,101,114,0,0,58,118,101,99,51,0,18,99,111,111,114,100,0,59,115,0,18,99,111,111, -114,100,0,59,113,0,49,0,18,99,111,111,114,100,0,59,116,0,18,99,111,111,114,100,0,59,113,0,49,0,18, -99,111,111,114,100,0,59,112,0,18,99,111,111,114,100,0,59,113,0,49,0,0,0,18,98,105,97,115,0,0,0,0,0, -1,0,9,0,100,70,100,120,0,1,0,0,9,112,0,0,0,1,8,17,48,0,48,48,49,0,0,0,0,1,0,10,0,100,70,100,120,0, -1,0,0,10,112,0,0,0,1,8,58,118,101,99,50,0,17,48,0,48,48,49,0,0,0,0,0,0,1,0,11,0,100,70,100,120,0,1, -0,0,11,112,0,0,0,1,8,58,118,101,99,51,0,17,48,0,48,48,49,0,0,0,0,0,0,1,0,12,0,100,70,100,120,0,1,0, -0,12,112,0,0,0,1,8,58,118,101,99,52,0,17,48,0,48,48,49,0,0,0,0,0,0,1,0,9,0,100,70,100,121,0,1,0,0, -9,112,0,0,0,1,8,17,48,0,48,48,49,0,0,0,0,1,0,10,0,100,70,100,121,0,1,0,0,10,112,0,0,0,1,8,58,118, -101,99,50,0,17,48,0,48,48,49,0,0,0,0,0,0,1,0,11,0,100,70,100,121,0,1,0,0,11,112,0,0,0,1,8,58,118, -101,99,51,0,17,48,0,48,48,49,0,0,0,0,0,0,1,0,12,0,100,70,100,121,0,1,0,0,12,112,0,0,0,1,8,58,118, -101,99,52,0,17,48,0,48,48,49,0,0,0,0,0,0,1,0,9,0,102,119,105,100,116,104,0,1,0,0,9,112,0,0,0,1,8, -58,97,98,115,0,58,100,70,100,120,0,18,112,0,0,0,0,0,58,97,98,115,0,58,100,70,100,121,0,18,112,0,0, -0,0,0,46,0,0,1,0,10,0,102,119,105,100,116,104,0,1,0,0,10,112,0,0,0,1,8,58,97,98,115,0,58,100,70, +67,111,111,114,100,0,0,0,1,0,12,0,116,101,120,116,117,114,101,49,68,0,1,1,0,16,115,97,109,112,108, +101,114,0,0,1,1,0,9,99,111,111,114,100,0,0,1,1,0,9,98,105,97,115,0,0,0,1,3,2,0,12,1,99,111,111,114, +100,52,0,0,0,9,18,99,111,111,114,100,52,0,59,120,0,18,99,111,111,114,100,0,20,0,9,18,99,111,111, +114,100,52,0,59,119,0,18,98,105,97,115,0,20,0,4,118,101,99,52,95,116,101,120,98,49,100,0,18,95,95, +114,101,116,86,97,108,0,0,18,115,97,109,112,108,101,114,0,0,18,99,111,111,114,100,52,0,0,0,0,1,0, +12,0,116,101,120,116,117,114,101,49,68,80,114,111,106,0,1,1,0,16,115,97,109,112,108,101,114,0,0,1, +1,0,10,99,111,111,114,100,0,0,1,1,0,9,98,105,97,115,0,0,0,1,3,2,0,12,1,112,99,111,111,114,100,0,0, +0,9,18,112,99,111,111,114,100,0,59,120,0,18,99,111,111,114,100,0,59,120,0,18,99,111,111,114,100,0, +59,121,0,49,20,0,9,18,112,99,111,111,114,100,0,59,119,0,18,98,105,97,115,0,20,0,4,118,101,99,52,95, +116,101,120,98,49,100,0,18,95,95,114,101,116,86,97,108,0,0,18,115,97,109,112,108,101,114,0,0,18, +112,99,111,111,114,100,0,0,0,0,1,0,12,0,116,101,120,116,117,114,101,49,68,80,114,111,106,0,1,1,0, +16,115,97,109,112,108,101,114,0,0,1,1,0,12,99,111,111,114,100,0,0,1,1,0,9,98,105,97,115,0,0,0,1,3, +2,0,12,1,112,99,111,111,114,100,0,0,0,9,18,112,99,111,111,114,100,0,59,120,0,18,99,111,111,114,100, +0,59,120,0,18,99,111,111,114,100,0,59,122,0,49,20,0,9,18,112,99,111,111,114,100,0,59,119,0,18,98, +105,97,115,0,20,0,4,118,101,99,52,95,116,101,120,98,49,100,0,18,95,95,114,101,116,86,97,108,0,0,18, +115,97,109,112,108,101,114,0,0,18,112,99,111,111,114,100,0,0,0,0,1,0,12,0,116,101,120,116,117,114, +101,50,68,0,1,1,0,17,115,97,109,112,108,101,114,0,0,1,1,0,10,99,111,111,114,100,0,0,1,1,0,9,98,105, +97,115,0,0,0,1,3,2,0,12,1,99,111,111,114,100,52,0,0,0,9,18,99,111,111,114,100,52,0,59,120,121,0,18, +99,111,111,114,100,0,59,120,121,0,20,0,9,18,99,111,111,114,100,52,0,59,119,0,18,98,105,97,115,0,20, +0,4,118,101,99,52,95,116,101,120,98,50,100,0,18,95,95,114,101,116,86,97,108,0,0,18,115,97,109,112, +108,101,114,0,0,18,99,111,111,114,100,52,0,0,0,0,1,0,12,0,116,101,120,116,117,114,101,50,68,80,114, +111,106,0,1,1,0,17,115,97,109,112,108,101,114,0,0,1,1,0,11,99,111,111,114,100,0,0,1,1,0,9,98,105, +97,115,0,0,0,1,3,2,0,12,1,112,99,111,111,114,100,0,0,0,9,18,112,99,111,111,114,100,0,59,120,121,0, +18,99,111,111,114,100,0,59,120,121,0,18,99,111,111,114,100,0,59,122,0,49,20,0,9,18,112,99,111,111, +114,100,0,59,119,0,18,98,105,97,115,0,20,0,4,118,101,99,52,95,116,101,120,98,50,100,0,18,95,95,114, +101,116,86,97,108,0,0,18,115,97,109,112,108,101,114,0,0,18,112,99,111,111,114,100,0,0,0,0,1,0,12,0, +116,101,120,116,117,114,101,50,68,80,114,111,106,0,1,1,0,17,115,97,109,112,108,101,114,0,0,1,1,0, +12,99,111,111,114,100,0,0,1,1,0,9,98,105,97,115,0,0,0,1,3,2,0,12,1,112,99,111,111,114,100,0,0,0,9, +18,112,99,111,111,114,100,0,59,120,121,0,18,99,111,111,114,100,0,59,120,121,0,18,99,111,111,114, +100,0,59,119,0,49,20,0,9,18,112,99,111,111,114,100,0,59,119,0,18,98,105,97,115,0,20,0,4,118,101,99, +52,95,116,101,120,98,50,100,0,18,95,95,114,101,116,86,97,108,0,0,18,115,97,109,112,108,101,114,0,0, +18,112,99,111,111,114,100,0,0,0,0,1,0,12,0,116,101,120,116,117,114,101,51,68,0,1,1,0,18,115,97,109, +112,108,101,114,0,0,1,1,0,11,99,111,111,114,100,0,0,1,1,0,9,98,105,97,115,0,0,0,1,3,2,0,12,1,99, +111,111,114,100,52,0,0,0,9,18,99,111,111,114,100,52,0,59,120,121,122,0,18,99,111,111,114,100,0,59, +120,121,122,0,20,0,9,18,99,111,111,114,100,52,0,59,119,0,18,98,105,97,115,0,20,0,4,118,101,99,52, +95,116,101,120,98,51,100,0,18,95,95,114,101,116,86,97,108,0,0,18,115,97,109,112,108,101,114,0,0,18, +99,111,111,114,100,52,0,0,0,0,1,0,12,0,116,101,120,116,117,114,101,51,68,80,114,111,106,0,1,1,0,18, +115,97,109,112,108,101,114,0,0,1,1,0,12,99,111,111,114,100,0,0,1,1,0,9,98,105,97,115,0,0,0,1,3,2,0, +12,1,112,99,111,111,114,100,0,0,0,9,18,112,99,111,111,114,100,0,59,120,121,122,0,18,99,111,111,114, +100,0,59,120,121,122,0,18,99,111,111,114,100,0,59,119,0,49,20,0,9,18,112,99,111,111,114,100,0,59, +119,0,18,98,105,97,115,0,20,0,4,118,101,99,52,95,116,101,120,98,51,100,0,18,95,95,114,101,116,86, +97,108,0,0,18,115,97,109,112,108,101,114,0,0,18,112,99,111,111,114,100,0,0,0,0,1,0,12,0,116,101, +120,116,117,114,101,67,117,98,101,0,1,1,0,19,115,97,109,112,108,101,114,0,0,1,1,0,11,99,111,111, +114,100,0,0,1,1,0,9,98,105,97,115,0,0,0,1,3,2,0,12,1,99,111,111,114,100,52,0,0,0,9,18,99,111,111, +114,100,52,0,59,120,121,122,0,18,99,111,111,114,100,0,20,0,9,18,99,111,111,114,100,52,0,59,119,0, +18,98,105,97,115,0,20,0,4,118,101,99,52,95,116,101,120,99,117,98,101,0,18,95,95,114,101,116,86,97, +108,0,0,18,115,97,109,112,108,101,114,0,0,18,99,111,111,114,100,52,0,0,0,0,1,0,12,0,115,104,97,100, +111,119,49,68,0,1,1,0,20,115,97,109,112,108,101,114,0,0,1,1,0,11,99,111,111,114,100,0,0,1,1,0,9,98, +105,97,115,0,0,0,1,3,2,0,12,1,99,111,111,114,100,52,0,0,0,9,18,99,111,111,114,100,52,0,59,120,121, +122,0,18,99,111,111,114,100,0,20,0,9,18,99,111,111,114,100,52,0,59,119,0,18,98,105,97,115,0,20,0,4, +118,101,99,52,95,116,101,120,98,49,100,0,18,95,95,114,101,116,86,97,108,0,0,18,115,97,109,112,108, +101,114,0,0,18,99,111,111,114,100,52,0,0,0,0,1,0,12,0,115,104,97,100,111,119,49,68,80,114,111,106, +0,1,1,0,20,115,97,109,112,108,101,114,0,0,1,1,0,12,99,111,111,114,100,0,0,1,1,0,9,98,105,97,115,0, +0,0,1,3,2,0,12,1,112,99,111,111,114,100,0,0,0,9,18,112,99,111,111,114,100,0,59,120,0,18,99,111,111, +114,100,0,59,120,0,18,99,111,111,114,100,0,59,119,0,49,20,0,9,18,112,99,111,111,114,100,0,59,122,0, +18,99,111,111,114,100,0,59,122,0,20,0,9,18,112,99,111,111,114,100,0,59,119,0,18,98,105,97,115,0,20, +0,4,118,101,99,52,95,116,101,120,98,49,100,0,18,95,95,114,101,116,86,97,108,0,0,18,115,97,109,112, +108,101,114,0,0,18,112,99,111,111,114,100,0,0,0,0,1,0,12,0,115,104,97,100,111,119,50,68,0,1,1,0,21, +115,97,109,112,108,101,114,0,0,1,1,0,11,99,111,111,114,100,0,0,1,1,0,9,98,105,97,115,0,0,0,1,3,2,0, +12,1,99,111,111,114,100,52,0,0,0,9,18,99,111,111,114,100,52,0,59,120,121,122,0,18,99,111,111,114, +100,0,20,0,9,18,99,111,111,114,100,52,0,59,119,0,18,98,105,97,115,0,20,0,4,118,101,99,52,95,116, +101,120,98,50,100,0,18,95,95,114,101,116,86,97,108,0,0,18,115,97,109,112,108,101,114,0,0,18,99,111, +111,114,100,52,0,0,0,0,1,0,12,0,115,104,97,100,111,119,50,68,80,114,111,106,0,1,1,0,21,115,97,109, +112,108,101,114,0,0,1,1,0,12,99,111,111,114,100,0,0,1,1,0,9,98,105,97,115,0,0,0,1,3,2,0,12,1,112, +99,111,111,114,100,0,0,0,9,18,112,99,111,111,114,100,0,59,120,121,0,18,99,111,111,114,100,0,59,120, +121,0,18,99,111,111,114,100,0,59,119,0,49,20,0,9,18,112,99,111,111,114,100,0,59,122,0,18,99,111, +111,114,100,0,59,122,0,20,0,9,18,112,99,111,111,114,100,0,59,119,0,18,98,105,97,115,0,20,0,4,118, +101,99,52,95,116,101,120,98,50,100,0,18,95,95,114,101,116,86,97,108,0,0,18,115,97,109,112,108,101, +114,0,0,18,112,99,111,111,114,100,0,0,0,0,1,0,12,0,116,101,120,116,117,114,101,50,68,82,101,99,116, +0,1,1,0,22,115,97,109,112,108,101,114,0,0,1,1,0,10,99,111,111,114,100,0,0,0,1,4,118,101,99,52,95, +116,101,120,95,114,101,99,116,0,18,95,95,114,101,116,86,97,108,0,0,18,115,97,109,112,108,101,114,0, +0,18,99,111,111,114,100,0,0,0,0,1,0,12,0,116,101,120,116,117,114,101,50,68,82,101,99,116,80,114, +111,106,0,1,1,0,22,115,97,109,112,108,101,114,0,0,1,1,0,11,99,111,111,114,100,0,0,0,1,3,2,0,12,1, +112,99,111,111,114,100,0,0,0,9,18,112,99,111,111,114,100,0,59,120,121,0,18,99,111,111,114,100,0,59, +120,121,0,18,99,111,111,114,100,0,59,122,0,49,20,0,4,118,101,99,52,95,116,101,120,112,95,114,101, +99,116,0,18,95,95,114,101,116,86,97,108,0,0,18,115,97,109,112,108,101,114,0,0,18,112,99,111,111, +114,100,0,0,0,0,1,0,12,0,116,101,120,116,117,114,101,50,68,82,101,99,116,80,114,111,106,0,1,1,0,22, +115,97,109,112,108,101,114,0,0,1,1,0,12,99,111,111,114,100,0,0,0,1,3,2,0,12,1,112,99,111,111,114, +100,0,0,0,9,18,112,99,111,111,114,100,0,59,120,121,0,18,99,111,111,114,100,0,59,120,121,0,18,99, +111,111,114,100,0,59,119,0,49,20,0,4,118,101,99,52,95,116,101,120,112,95,114,101,99,116,0,18,95,95, +114,101,116,86,97,108,0,0,18,115,97,109,112,108,101,114,0,0,18,112,99,111,111,114,100,0,0,0,0,1,0, +12,0,115,104,97,100,111,119,50,68,82,101,99,116,0,1,1,0,23,115,97,109,112,108,101,114,0,0,1,1,0,11, +99,111,111,114,100,0,0,0,1,0,1,0,12,0,115,104,97,100,111,119,50,68,82,101,99,116,80,114,111,106,0, +1,1,0,23,115,97,109,112,108,101,114,0,0,1,1,0,12,99,111,111,114,100,0,0,0,1,0,1,0,9,0,100,70,100, +120,0,1,1,0,9,112,0,0,0,1,4,118,101,99,52,95,100,100,120,0,18,95,95,114,101,116,86,97,108,0,59,120, +0,0,18,112,0,59,120,120,120,120,0,0,0,0,1,0,10,0,100,70,100,120,0,1,1,0,10,112,0,0,0,1,4,118,101, +99,52,95,100,100,120,0,18,95,95,114,101,116,86,97,108,0,59,120,121,0,0,18,112,0,59,120,121,121,121, +0,0,0,0,1,0,11,0,100,70,100,120,0,1,1,0,11,112,0,0,0,1,4,118,101,99,52,95,100,100,120,0,18,95,95, +114,101,116,86,97,108,0,59,120,121,122,0,0,18,112,0,59,120,121,122,122,0,0,0,0,1,0,12,0,100,70,100, +120,0,1,1,0,12,112,0,0,0,1,4,118,101,99,52,95,100,100,120,0,18,95,95,114,101,116,86,97,108,0,0,18, +112,0,0,0,0,1,0,9,0,100,70,100,121,0,1,1,0,9,112,0,0,0,1,4,118,101,99,52,95,100,100,121,0,18,95,95, +114,101,116,86,97,108,0,59,120,0,0,18,112,0,59,120,120,120,120,0,0,0,0,1,0,10,0,100,70,100,121,0,1, +1,0,10,112,0,0,0,1,4,118,101,99,52,95,100,100,121,0,18,95,95,114,101,116,86,97,108,0,59,120,121,0, +0,18,112,0,59,120,121,121,121,0,0,0,0,1,0,11,0,100,70,100,121,0,1,1,0,11,112,0,0,0,1,4,118,101,99, +52,95,100,100,121,0,18,95,95,114,101,116,86,97,108,0,59,120,121,122,0,0,18,112,0,59,120,121,122, +122,0,0,0,0,1,0,12,0,100,70,100,121,0,1,1,0,12,112,0,0,0,1,4,118,101,99,52,95,100,100,121,0,18,95, +95,114,101,116,86,97,108,0,0,18,112,0,0,0,0,1,0,9,0,102,119,105,100,116,104,0,1,1,0,9,112,0,0,0,1, +8,58,97,98,115,0,58,100,70,100,120,0,18,112,0,0,0,0,0,58,97,98,115,0,58,100,70,100,121,0,18,112,0, +0,0,0,0,46,0,0,1,0,10,0,102,119,105,100,116,104,0,1,1,0,10,112,0,0,0,1,8,58,97,98,115,0,58,100,70, 100,120,0,18,112,0,0,0,0,0,58,97,98,115,0,58,100,70,100,121,0,18,112,0,0,0,0,0,46,0,0,1,0,11,0,102, -119,105,100,116,104,0,1,0,0,11,112,0,0,0,1,8,58,97,98,115,0,58,100,70,100,120,0,18,112,0,0,0,0,0, -58,97,98,115,0,58,100,70,100,121,0,18,112,0,0,0,0,0,46,0,0,1,0,12,0,102,119,105,100,116,104,0,1,0, +119,105,100,116,104,0,1,1,0,11,112,0,0,0,1,8,58,97,98,115,0,58,100,70,100,120,0,18,112,0,0,0,0,0, +58,97,98,115,0,58,100,70,100,121,0,18,112,0,0,0,0,0,46,0,0,1,0,12,0,102,119,105,100,116,104,0,1,1, 0,12,112,0,0,0,1,8,58,97,98,115,0,58,100,70,100,120,0,18,112,0,0,0,0,0,58,97,98,115,0,58,100,70, 100,121,0,18,112,0,0,0,0,0,46,0,0,0 diff --git a/src/mesa/shader/slang/library/slang_shader.syn b/src/mesa/shader/slang/library/slang_shader.syn index 149bb15c44..9389869da2 100644 --- a/src/mesa/shader/slang/library/slang_shader.syn +++ b/src/mesa/shader/slang/library/slang_shader.syn @@ -139,8 +139,10 @@ .emtcode TYPE_SPECIFIER_SAMPLERCUBE 19 .emtcode TYPE_SPECIFIER_SAMPLER1DSHADOW 20 .emtcode TYPE_SPECIFIER_SAMPLER2DSHADOW 21 -.emtcode TYPE_SPECIFIER_STRUCT 22 -.emtcode TYPE_SPECIFIER_TYPENAME 23 +.emtcode TYPE_SPECIFIER_SAMPLER2DRECT 22 +.emtcode TYPE_SPECIFIER_SAMPLER2DRECTSHADOW 23 +.emtcode TYPE_SPECIFIER_STRUCT 24 +.emtcode TYPE_SPECIFIER_TYPENAME 25 /* structure field */ .emtcode FIELD_NONE 0 @@ -884,6 +886,8 @@ type_qualifier | "samplerCube" | "sampler1DShadow" | "sampler2DShadow" + | "sampler2DRect" + | "sampler2DRectShadow" | <struct_specifier> | <type_name> */ @@ -910,6 +914,8 @@ type_specifier_space "samplerCube" .emit TYPE_SPECIFIER_SAMPLERCUBE .or "sampler1DShadow" .emit TYPE_SPECIFIER_SAMPLER1DSHADOW .or "sampler2DShadow" .emit TYPE_SPECIFIER_SAMPLER2DSHADOW .or + "sampler2DRect" .emit TYPE_SPECIFIER_SAMPLER2DRECT .or + "sampler2DRectShadow" .emit TYPE_SPECIFIER_SAMPLER2DRECTSHADOW .or type_name .emit TYPE_SPECIFIER_TYPENAME; type_specifier_nospace struct_specifier .emit TYPE_SPECIFIER_STRUCT; @@ -1096,7 +1102,7 @@ condition_3 expression .and .true .emit OP_END; /* - <iteration_statement> ::= "while" "(" <condition> ")" <statement_no_new_scope> + <iteration_statement> ::= "while" "(" <condition> ")" <statement> | "do" <statement> "while" "(" <expression> ")" ";" | "for" "(" <for_init_statement> <for_rest_statement> ")" <statement_no_new_scope> @@ -1105,7 +1111,7 @@ iteration_statement iteration_statement_1 .or iteration_statement_2 .or iteration_statement_3; iteration_statement_1 "while" .emit OP_WHILE .and lparen .error LPAREN_EXPECTED .and condition .and - rparen .error RPAREN_EXPECTED .and statement_no_new_scope; + rparen .error RPAREN_EXPECTED .and statement; iteration_statement_2 "do" .emit OP_DO .and statement_space .and "while" .and lparen .error LPAREN_EXPECTED .and expression .and rparen .error RPAREN_EXPECTED .emit OP_END .and semicolon; @@ -1192,7 +1198,12 @@ note: this is an extension to the standard language specification - normally sla __asm statements */ asm_argument - variable_identifier .or floatconstant; + var_with_field .or + variable_identifier .or + floatconstant; + +var_with_field + variable_identifier .and dot .and field_selection .emit OP_FIELD; /* <translation_unit> ::= <external_declaration> diff --git a/src/mesa/shader/slang/library/slang_shader_syn.h b/src/mesa/shader/slang/library/slang_shader_syn.h index ad89472ba3..4863feda5b 100644 --- a/src/mesa/shader/slang/library/slang_shader_syn.h +++ b/src/mesa/shader/slang/library/slang_shader_syn.h @@ -63,8 +63,10 @@ ".emtcode TYPE_SPECIFIER_SAMPLERCUBE 19\n" ".emtcode TYPE_SPECIFIER_SAMPLER1DSHADOW 20\n" ".emtcode TYPE_SPECIFIER_SAMPLER2DSHADOW 21\n" -".emtcode TYPE_SPECIFIER_STRUCT 22\n" -".emtcode TYPE_SPECIFIER_TYPENAME 23\n" +".emtcode TYPE_SPECIFIER_SAMPLER2DRECT 22\n" +".emtcode TYPE_SPECIFIER_SAMPLER2DRECTSHADOW 23\n" +".emtcode TYPE_SPECIFIER_STRUCT 24\n" +".emtcode TYPE_SPECIFIER_TYPENAME 25\n" ".emtcode FIELD_NONE 0\n" ".emtcode FIELD_NEXT 1\n" ".emtcode FIELD_ARRAY 2\n" @@ -435,6 +437,8 @@ " \"samplerCube\" .emit TYPE_SPECIFIER_SAMPLERCUBE .or\n" " \"sampler1DShadow\" .emit TYPE_SPECIFIER_SAMPLER1DSHADOW .or\n" " \"sampler2DShadow\" .emit TYPE_SPECIFIER_SAMPLER2DSHADOW .or\n" +" \"sampler2DRect\" .emit TYPE_SPECIFIER_SAMPLER2DRECT .or\n" +" \"sampler2DRectShadow\" .emit TYPE_SPECIFIER_SAMPLER2DRECTSHADOW .or\n" " type_name .emit TYPE_SPECIFIER_TYPENAME;\n" "type_specifier_nospace\n" " struct_specifier .emit TYPE_SPECIFIER_STRUCT;\n" @@ -533,7 +537,7 @@ " iteration_statement_1 .or iteration_statement_2 .or iteration_statement_3;\n" "iteration_statement_1\n" " \"while\" .emit OP_WHILE .and lparen .error LPAREN_EXPECTED .and condition .and\n" -" rparen .error RPAREN_EXPECTED .and statement_no_new_scope;\n" +" rparen .error RPAREN_EXPECTED .and statement;\n" "iteration_statement_2\n" " \"do\" .emit OP_DO .and statement_space .and \"while\" .and lparen .error LPAREN_EXPECTED .and\n" " expression .and rparen .error RPAREN_EXPECTED .emit OP_END .and semicolon;\n" @@ -571,7 +575,11 @@ "asm_arguments_1\n" " comma .and asm_argument .and .true .emit OP_END;\n" "asm_argument\n" -" variable_identifier .or floatconstant;\n" +" var_with_field .or\n" +" variable_identifier .or\n" +" floatconstant;\n" +"var_with_field\n" +" variable_identifier .and dot .and field_selection .emit OP_FIELD;\n" "translation_unit\n" " optional_space .emit REVISION .and external_declaration .error INVALID_EXTERNAL_DECLARATION .and\n" " .loop external_declaration .and optional_space .and\n" diff --git a/src/mesa/shader/slang/library/slang_vertex_builtin.gc b/src/mesa/shader/slang/library/slang_vertex_builtin.gc index 8afb723ee2..20c924a30d 100755..100644 --- a/src/mesa/shader/slang/library/slang_vertex_builtin.gc +++ b/src/mesa/shader/slang/library/slang_vertex_builtin.gc @@ -55,74 +55,133 @@ varying float gl_FogFragCoord; // Geometric Functions // -vec4 ftransform () { - return gl_ModelViewProjectionMatrix * gl_Vertex; +vec4 ftransform() +{ + __retVal = gl_Vertex * gl_ModelViewProjectionMatrixTranspose; } + + // // 8.7 Texture Lookup Functions +// These are pretty much identical to the ones in slang_fragment_builtin.gc +// When used in a vertex program, the texture sample instructions should not +// be using a LOD term so it's effectively zero. Adding 'lod' to that does +// what we want. // -vec4 texture1DLod (sampler1D sampler, float coord, float lod) { - vec4 texel; - __asm vec4_tex1d texel, sampler, coord, lod; - return texel; +vec4 texture1DLod(const sampler1D sampler, const float coord, const float lod) +{ + vec4 coord4; + coord4.x = coord; + coord4.w = lod; + __asm vec4_texb1d __retVal, sampler, coord4; } -vec4 texture1DProjLod (sampler1D sampler, vec2 coord, float lod) { - return texture1DLod (sampler, coord.s / coord.t, lod); +vec4 texture1DProjLod(const sampler1D sampler, const vec2 coord, const float lod) +{ + vec4 pcoord; + pcoord.x = coord.x / coord.y; + pcoord.w = lod; + __asm vec4_texb1d __retVal, sampler, pcoord; } -vec4 texture1DProjLod (sampler1D sampler, vec4 coord, float lod) { - return texture1DLod (sampler, coord.s / coord.q, lod); +vec4 texture1DProjLod(const sampler1D sampler, const vec4 coord, const float lod) +{ + vec4 pcoord; + pcoord.x = coord.x / coord.z; + pcoord.w = lod; + __asm vec4_texb1d __retVal, sampler, pcoord; } -vec4 texture2DLod (sampler2D sampler, vec2 coord, float lod) { - vec4 texel; - __asm vec4_tex2d texel, sampler, coord, lod; - return texel; + + +vec4 texture2DLod(const sampler2D sampler, const vec2 coord, const float lod) +{ + vec4 coord4; + coord4.xy = coord.xy; + coord4.w = lod; + __asm vec4_texb2d __retVal, sampler, coord4; } -vec4 texture2DProjLod (sampler2D sampler, vec3 coord, float lod) { - return texture2DLod (sampler, vec2 (coord.s / coord.p, coord.t / coord.p), lod); +vec4 texture2DProjLod(const sampler2D sampler, const vec3 coord, const float lod) +{ + vec4 pcoord; + pcoord.xy = coord.xy / coord.z; + pcoord.w = lod; + __asm vec4_texb2d __retVal, sampler, pcoord; } -vec4 texture2DProjLod (sampler2D sampler, vec4 coord, float lod) { - return texture2DLod (sampler, vec2 (coord.s / coord.q, coord.t / coord.q), lod); +vec4 texture2DProjLod(const sampler2D sampler, const vec4 coord, const float lod) +{ + vec4 pcoord; + pcoord.xy = coord.xy / coord.z; + pcoord.w = lod; + __asm vec4_texb2d __retVal, sampler, pcoord; } -vec4 texture3DLod (sampler3D sampler, vec3 coord, float lod) { - vec4 texel; - __asm vec4_tex3d texel, sampler, coord, lod; - return texel; + +vec4 texture3DLod(const sampler3D sampler, const vec3 coord, const float lod) +{ + vec4 coord4; + coord4.xyz = coord.xyz; + coord4.w = lod; + __asm vec4_texb3d __retVal, sampler, coord4; } -vec4 texture3DProjLod (sampler3D sampler, vec4 coord, float lod) { - return texture3DLod (sampler, vec3 (coord.s / coord.q, coord.t / coord.q, coord.p / coord.q), lod); + +vec4 texture3DProjLod(const sampler3D sampler, const vec4 coord, const float lod) +{ + // do projection here (there's no vec4_texbp3d instruction) + vec4 pcoord; + pcoord.xyz = coord.xyz / coord.w; + pcoord.w = lod; + __asm vec4_texb3d __retVal, sampler, pcoord; } -vec4 textureCubeLod (samplerCube sampler, vec3 coord, float lod) { - vec4 texel; - __asm vec4_texcube texel, sampler, coord, lod; - return texel; + +vec4 textureCubeLod(const samplerCube sampler, const vec3 coord, const float lod) +{ + vec4 coord4; + coord4.xyz = coord; + coord4.w = lod; + __asm vec4_texcube __retVal, sampler, coord4; } -vec4 shadow1DLod (sampler1DShadow sampler, vec3 coord, float lod) { - vec4 texel; - __asm vec4_shad1d texel, sampler, coord, lod; - return texel; + +vec4 shadow1DLod(const sampler1DShadow sampler, const vec3 coord, const float lod) +{ + vec4 coord4; + coord4.xyz = coord; + coord4.w = lod; + __asm vec4_texb1d __retVal, sampler, coord4; } -vec4 shadow1DProjLod (sampler1DShadow sampler, vec4 coord, float lod) { - return shadow1DLod (sampler, vec3 (coord.s / coord.q, 0.0, coord.p / coord.q), lod); +vec4 shadow1DProjLod(const sampler1DShadow sampler, const vec4 coord, + const float lod) +{ + vec4 pcoord; + pcoord.x = coord.x / coord.w; + pcoord.z = coord.z; + pcoord.w = lod; + __asm vec4_texb1d __retVal, sampler, pcoord; } -vec4 shadow2DLod (sampler2DShadow sampler, vec3 coord, float lod) { - vec4 texel; - __asm vec4_shad2d texel, sampler, coord, lod; - return texel; + +vec4 shadow2DLod(const sampler2DShadow sampler, const vec3 coord, const float lod) +{ + vec4 coord4; + coord4.xyz = coord; + coord4.w = lod; + __asm vec4_texb2d __retVal, sampler, coord4; } -vec4 shadow2DProjLod (sampler2DShadow sampler, vec4 coord, float lod) { - return shadow2DLod (sampler, vec3 (coord.s / coord.q, coord.t / coord.q, coord.p / coord.q), lod); +vec4 shadow2DProjLod(const sampler2DShadow sampler, const vec4 coord, + const float lod) +{ + vec4 pcoord; + pcoord.xy = coord.xy / coord.w; + pcoord.z = coord.z; + pcoord.w = lod; + __asm vec4_texb2d __retVal, sampler, pcoord; } diff --git a/src/mesa/shader/slang/library/slang_vertex_builtin_gc.h b/src/mesa/shader/slang/library/slang_vertex_builtin_gc.h index b47c2717c5..d47d62f909 100644 --- a/src/mesa/shader/slang/library/slang_vertex_builtin_gc.h +++ b/src/mesa/shader/slang/library/slang_vertex_builtin_gc.h @@ -19,60 +19,75 @@ 107,83,101,99,111,110,100,97,114,121,67,111,108,111,114,0,0,0,2,2,3,12,1,103,108,95,84,101,120,67, 111,111,114,100,0,3,18,103,108,95,77,97,120,84,101,120,116,117,114,101,67,111,111,114,100,115,0,0, 0,2,2,3,9,1,103,108,95,70,111,103,70,114,97,103,67,111,111,114,100,0,0,0,1,0,12,0,102,116,114,97, -110,115,102,111,114,109,0,0,1,8,18,103,108,95,77,111,100,101,108,86,105,101,119,80,114,111,106,101, -99,116,105,111,110,77,97,116,114,105,120,0,18,103,108,95,86,101,114,116,101,120,0,48,0,0,1,0,12,0, -116,101,120,116,117,114,101,49,68,76,111,100,0,1,0,0,16,115,97,109,112,108,101,114,0,0,1,0,0,9,99, -111,111,114,100,0,0,1,0,0,9,108,111,100,0,0,0,1,3,2,0,12,1,116,101,120,101,108,0,0,0,4,118,101,99, -52,95,116,101,120,49,100,0,18,116,101,120,101,108,0,0,18,115,97,109,112,108,101,114,0,0,18,99,111, -111,114,100,0,0,18,108,111,100,0,0,0,8,18,116,101,120,101,108,0,0,0,1,0,12,0,116,101,120,116,117, -114,101,49,68,80,114,111,106,76,111,100,0,1,0,0,16,115,97,109,112,108,101,114,0,0,1,0,0,10,99,111, -111,114,100,0,0,1,0,0,9,108,111,100,0,0,0,1,8,58,116,101,120,116,117,114,101,49,68,76,111,100,0,18, -115,97,109,112,108,101,114,0,0,18,99,111,111,114,100,0,59,115,0,18,99,111,111,114,100,0,59,116,0, -49,0,18,108,111,100,0,0,0,0,0,1,0,12,0,116,101,120,116,117,114,101,49,68,80,114,111,106,76,111,100, -0,1,0,0,16,115,97,109,112,108,101,114,0,0,1,0,0,12,99,111,111,114,100,0,0,1,0,0,9,108,111,100,0,0, -0,1,8,58,116,101,120,116,117,114,101,49,68,76,111,100,0,18,115,97,109,112,108,101,114,0,0,18,99, -111,111,114,100,0,59,115,0,18,99,111,111,114,100,0,59,113,0,49,0,18,108,111,100,0,0,0,0,0,1,0,12,0, -116,101,120,116,117,114,101,50,68,76,111,100,0,1,0,0,17,115,97,109,112,108,101,114,0,0,1,0,0,10,99, -111,111,114,100,0,0,1,0,0,9,108,111,100,0,0,0,1,3,2,0,12,1,116,101,120,101,108,0,0,0,4,118,101,99, -52,95,116,101,120,50,100,0,18,116,101,120,101,108,0,0,18,115,97,109,112,108,101,114,0,0,18,99,111, -111,114,100,0,0,18,108,111,100,0,0,0,8,18,116,101,120,101,108,0,0,0,1,0,12,0,116,101,120,116,117, -114,101,50,68,80,114,111,106,76,111,100,0,1,0,0,17,115,97,109,112,108,101,114,0,0,1,0,0,11,99,111, -111,114,100,0,0,1,0,0,9,108,111,100,0,0,0,1,8,58,116,101,120,116,117,114,101,50,68,76,111,100,0,18, -115,97,109,112,108,101,114,0,0,58,118,101,99,50,0,18,99,111,111,114,100,0,59,115,0,18,99,111,111, -114,100,0,59,112,0,49,0,18,99,111,111,114,100,0,59,116,0,18,99,111,111,114,100,0,59,112,0,49,0,0,0, -18,108,111,100,0,0,0,0,0,1,0,12,0,116,101,120,116,117,114,101,50,68,80,114,111,106,76,111,100,0,1, -0,0,17,115,97,109,112,108,101,114,0,0,1,0,0,12,99,111,111,114,100,0,0,1,0,0,9,108,111,100,0,0,0,1, -8,58,116,101,120,116,117,114,101,50,68,76,111,100,0,18,115,97,109,112,108,101,114,0,0,58,118,101, -99,50,0,18,99,111,111,114,100,0,59,115,0,18,99,111,111,114,100,0,59,113,0,49,0,18,99,111,111,114, -100,0,59,116,0,18,99,111,111,114,100,0,59,113,0,49,0,0,0,18,108,111,100,0,0,0,0,0,1,0,12,0,116,101, -120,116,117,114,101,51,68,76,111,100,0,1,0,0,18,115,97,109,112,108,101,114,0,0,1,0,0,11,99,111,111, -114,100,0,0,1,0,0,9,108,111,100,0,0,0,1,3,2,0,12,1,116,101,120,101,108,0,0,0,4,118,101,99,52,95, -116,101,120,51,100,0,18,116,101,120,101,108,0,0,18,115,97,109,112,108,101,114,0,0,18,99,111,111, -114,100,0,0,18,108,111,100,0,0,0,8,18,116,101,120,101,108,0,0,0,1,0,12,0,116,101,120,116,117,114, -101,51,68,80,114,111,106,76,111,100,0,1,0,0,18,115,97,109,112,108,101,114,0,0,1,0,0,12,99,111,111, -114,100,0,0,1,0,0,9,108,111,100,0,0,0,1,8,58,116,101,120,116,117,114,101,51,68,76,111,100,0,18,115, -97,109,112,108,101,114,0,0,58,118,101,99,51,0,18,99,111,111,114,100,0,59,115,0,18,99,111,111,114, -100,0,59,113,0,49,0,18,99,111,111,114,100,0,59,116,0,18,99,111,111,114,100,0,59,113,0,49,0,18,99, -111,111,114,100,0,59,112,0,18,99,111,111,114,100,0,59,113,0,49,0,0,0,18,108,111,100,0,0,0,0,0,1,0, -12,0,116,101,120,116,117,114,101,67,117,98,101,76,111,100,0,1,0,0,19,115,97,109,112,108,101,114,0, -0,1,0,0,11,99,111,111,114,100,0,0,1,0,0,9,108,111,100,0,0,0,1,3,2,0,12,1,116,101,120,101,108,0,0,0, -4,118,101,99,52,95,116,101,120,99,117,98,101,0,18,116,101,120,101,108,0,0,18,115,97,109,112,108, -101,114,0,0,18,99,111,111,114,100,0,0,18,108,111,100,0,0,0,8,18,116,101,120,101,108,0,0,0,1,0,12,0, -115,104,97,100,111,119,49,68,76,111,100,0,1,0,0,20,115,97,109,112,108,101,114,0,0,1,0,0,11,99,111, -111,114,100,0,0,1,0,0,9,108,111,100,0,0,0,1,3,2,0,12,1,116,101,120,101,108,0,0,0,4,118,101,99,52, -95,115,104,97,100,49,100,0,18,116,101,120,101,108,0,0,18,115,97,109,112,108,101,114,0,0,18,99,111, -111,114,100,0,0,18,108,111,100,0,0,0,8,18,116,101,120,101,108,0,0,0,1,0,12,0,115,104,97,100,111, -119,49,68,80,114,111,106,76,111,100,0,1,0,0,20,115,97,109,112,108,101,114,0,0,1,0,0,12,99,111,111, -114,100,0,0,1,0,0,9,108,111,100,0,0,0,1,8,58,115,104,97,100,111,119,49,68,76,111,100,0,18,115,97, -109,112,108,101,114,0,0,58,118,101,99,51,0,18,99,111,111,114,100,0,59,115,0,18,99,111,111,114,100, -0,59,113,0,49,0,17,48,0,48,0,0,0,18,99,111,111,114,100,0,59,112,0,18,99,111,111,114,100,0,59,113,0, -49,0,0,0,18,108,111,100,0,0,0,0,0,1,0,12,0,115,104,97,100,111,119,50,68,76,111,100,0,1,0,0,21,115, -97,109,112,108,101,114,0,0,1,0,0,11,99,111,111,114,100,0,0,1,0,0,9,108,111,100,0,0,0,1,3,2,0,12,1, -116,101,120,101,108,0,0,0,4,118,101,99,52,95,115,104,97,100,50,100,0,18,116,101,120,101,108,0,0,18, -115,97,109,112,108,101,114,0,0,18,99,111,111,114,100,0,0,18,108,111,100,0,0,0,8,18,116,101,120,101, -108,0,0,0,1,0,12,0,115,104,97,100,111,119,50,68,80,114,111,106,76,111,100,0,1,0,0,21,115,97,109, -112,108,101,114,0,0,1,0,0,12,99,111,111,114,100,0,0,1,0,0,9,108,111,100,0,0,0,1,8,58,115,104,97, -100,111,119,50,68,76,111,100,0,18,115,97,109,112,108,101,114,0,0,58,118,101,99,51,0,18,99,111,111, -114,100,0,59,115,0,18,99,111,111,114,100,0,59,113,0,49,0,18,99,111,111,114,100,0,59,116,0,18,99, -111,111,114,100,0,59,113,0,49,0,18,99,111,111,114,100,0,59,112,0,18,99,111,111,114,100,0,59,113,0, -49,0,0,0,18,108,111,100,0,0,0,0,0,0 +110,115,102,111,114,109,0,0,1,9,18,95,95,114,101,116,86,97,108,0,18,103,108,95,86,101,114,116,101, +120,0,18,103,108,95,77,111,100,101,108,86,105,101,119,80,114,111,106,101,99,116,105,111,110,77,97, +116,114,105,120,84,114,97,110,115,112,111,115,101,0,48,20,0,0,1,0,12,0,116,101,120,116,117,114,101, +49,68,76,111,100,0,1,1,0,16,115,97,109,112,108,101,114,0,0,1,1,0,9,99,111,111,114,100,0,0,1,1,0,9, +108,111,100,0,0,0,1,3,2,0,12,1,99,111,111,114,100,52,0,0,0,9,18,99,111,111,114,100,52,0,59,120,0, +18,99,111,111,114,100,0,20,0,9,18,99,111,111,114,100,52,0,59,119,0,18,108,111,100,0,20,0,4,118,101, +99,52,95,116,101,120,98,49,100,0,18,95,95,114,101,116,86,97,108,0,0,18,115,97,109,112,108,101,114, +0,0,18,99,111,111,114,100,52,0,0,0,0,1,0,12,0,116,101,120,116,117,114,101,49,68,80,114,111,106,76, +111,100,0,1,1,0,16,115,97,109,112,108,101,114,0,0,1,1,0,10,99,111,111,114,100,0,0,1,1,0,9,108,111, +100,0,0,0,1,3,2,0,12,1,112,99,111,111,114,100,0,0,0,9,18,112,99,111,111,114,100,0,59,120,0,18,99, +111,111,114,100,0,59,120,0,18,99,111,111,114,100,0,59,121,0,49,20,0,9,18,112,99,111,111,114,100,0, +59,119,0,18,108,111,100,0,20,0,4,118,101,99,52,95,116,101,120,98,49,100,0,18,95,95,114,101,116,86, +97,108,0,0,18,115,97,109,112,108,101,114,0,0,18,112,99,111,111,114,100,0,0,0,0,1,0,12,0,116,101, +120,116,117,114,101,49,68,80,114,111,106,76,111,100,0,1,1,0,16,115,97,109,112,108,101,114,0,0,1,1, +0,12,99,111,111,114,100,0,0,1,1,0,9,108,111,100,0,0,0,1,3,2,0,12,1,112,99,111,111,114,100,0,0,0,9, +18,112,99,111,111,114,100,0,59,120,0,18,99,111,111,114,100,0,59,120,0,18,99,111,111,114,100,0,59, +122,0,49,20,0,9,18,112,99,111,111,114,100,0,59,119,0,18,108,111,100,0,20,0,4,118,101,99,52,95,116, +101,120,98,49,100,0,18,95,95,114,101,116,86,97,108,0,0,18,115,97,109,112,108,101,114,0,0,18,112,99, +111,111,114,100,0,0,0,0,1,0,12,0,116,101,120,116,117,114,101,50,68,76,111,100,0,1,1,0,17,115,97, +109,112,108,101,114,0,0,1,1,0,10,99,111,111,114,100,0,0,1,1,0,9,108,111,100,0,0,0,1,3,2,0,12,1,99, +111,111,114,100,52,0,0,0,9,18,99,111,111,114,100,52,0,59,120,121,0,18,99,111,111,114,100,0,59,120, +121,0,20,0,9,18,99,111,111,114,100,52,0,59,119,0,18,108,111,100,0,20,0,4,118,101,99,52,95,116,101, +120,98,50,100,0,18,95,95,114,101,116,86,97,108,0,0,18,115,97,109,112,108,101,114,0,0,18,99,111,111, +114,100,52,0,0,0,0,1,0,12,0,116,101,120,116,117,114,101,50,68,80,114,111,106,76,111,100,0,1,1,0,17, +115,97,109,112,108,101,114,0,0,1,1,0,11,99,111,111,114,100,0,0,1,1,0,9,108,111,100,0,0,0,1,3,2,0, +12,1,112,99,111,111,114,100,0,0,0,9,18,112,99,111,111,114,100,0,59,120,121,0,18,99,111,111,114,100, +0,59,120,121,0,18,99,111,111,114,100,0,59,122,0,49,20,0,9,18,112,99,111,111,114,100,0,59,119,0,18, +108,111,100,0,20,0,4,118,101,99,52,95,116,101,120,98,50,100,0,18,95,95,114,101,116,86,97,108,0,0, +18,115,97,109,112,108,101,114,0,0,18,112,99,111,111,114,100,0,0,0,0,1,0,12,0,116,101,120,116,117, +114,101,50,68,80,114,111,106,76,111,100,0,1,1,0,17,115,97,109,112,108,101,114,0,0,1,1,0,12,99,111, +111,114,100,0,0,1,1,0,9,108,111,100,0,0,0,1,3,2,0,12,1,112,99,111,111,114,100,0,0,0,9,18,112,99, +111,111,114,100,0,59,120,121,0,18,99,111,111,114,100,0,59,120,121,0,18,99,111,111,114,100,0,59,122, +0,49,20,0,9,18,112,99,111,111,114,100,0,59,119,0,18,108,111,100,0,20,0,4,118,101,99,52,95,116,101, +120,98,50,100,0,18,95,95,114,101,116,86,97,108,0,0,18,115,97,109,112,108,101,114,0,0,18,112,99,111, +111,114,100,0,0,0,0,1,0,12,0,116,101,120,116,117,114,101,51,68,76,111,100,0,1,1,0,18,115,97,109, +112,108,101,114,0,0,1,1,0,11,99,111,111,114,100,0,0,1,1,0,9,108,111,100,0,0,0,1,3,2,0,12,1,99,111, +111,114,100,52,0,0,0,9,18,99,111,111,114,100,52,0,59,120,121,122,0,18,99,111,111,114,100,0,59,120, +121,122,0,20,0,9,18,99,111,111,114,100,52,0,59,119,0,18,108,111,100,0,20,0,4,118,101,99,52,95,116, +101,120,98,51,100,0,18,95,95,114,101,116,86,97,108,0,0,18,115,97,109,112,108,101,114,0,0,18,99,111, +111,114,100,52,0,0,0,0,1,0,12,0,116,101,120,116,117,114,101,51,68,80,114,111,106,76,111,100,0,1,1, +0,18,115,97,109,112,108,101,114,0,0,1,1,0,12,99,111,111,114,100,0,0,1,1,0,9,108,111,100,0,0,0,1,3, +2,0,12,1,112,99,111,111,114,100,0,0,0,9,18,112,99,111,111,114,100,0,59,120,121,122,0,18,99,111,111, +114,100,0,59,120,121,122,0,18,99,111,111,114,100,0,59,119,0,49,20,0,9,18,112,99,111,111,114,100,0, +59,119,0,18,108,111,100,0,20,0,4,118,101,99,52,95,116,101,120,98,51,100,0,18,95,95,114,101,116,86, +97,108,0,0,18,115,97,109,112,108,101,114,0,0,18,112,99,111,111,114,100,0,0,0,0,1,0,12,0,116,101, +120,116,117,114,101,67,117,98,101,76,111,100,0,1,1,0,19,115,97,109,112,108,101,114,0,0,1,1,0,11,99, +111,111,114,100,0,0,1,1,0,9,108,111,100,0,0,0,1,3,2,0,12,1,99,111,111,114,100,52,0,0,0,9,18,99,111, +111,114,100,52,0,59,120,121,122,0,18,99,111,111,114,100,0,20,0,9,18,99,111,111,114,100,52,0,59,119, +0,18,108,111,100,0,20,0,4,118,101,99,52,95,116,101,120,99,117,98,101,0,18,95,95,114,101,116,86,97, +108,0,0,18,115,97,109,112,108,101,114,0,0,18,99,111,111,114,100,52,0,0,0,0,1,0,12,0,115,104,97,100, +111,119,49,68,76,111,100,0,1,1,0,20,115,97,109,112,108,101,114,0,0,1,1,0,11,99,111,111,114,100,0,0, +1,1,0,9,108,111,100,0,0,0,1,3,2,0,12,1,99,111,111,114,100,52,0,0,0,9,18,99,111,111,114,100,52,0,59, +120,121,122,0,18,99,111,111,114,100,0,20,0,9,18,99,111,111,114,100,52,0,59,119,0,18,108,111,100,0, +20,0,4,118,101,99,52,95,116,101,120,98,49,100,0,18,95,95,114,101,116,86,97,108,0,0,18,115,97,109, +112,108,101,114,0,0,18,99,111,111,114,100,52,0,0,0,0,1,0,12,0,115,104,97,100,111,119,49,68,80,114, +111,106,76,111,100,0,1,1,0,20,115,97,109,112,108,101,114,0,0,1,1,0,12,99,111,111,114,100,0,0,1,1,0, +9,108,111,100,0,0,0,1,3,2,0,12,1,112,99,111,111,114,100,0,0,0,9,18,112,99,111,111,114,100,0,59,120, +0,18,99,111,111,114,100,0,59,120,0,18,99,111,111,114,100,0,59,119,0,49,20,0,9,18,112,99,111,111, +114,100,0,59,122,0,18,99,111,111,114,100,0,59,122,0,20,0,9,18,112,99,111,111,114,100,0,59,119,0,18, +108,111,100,0,20,0,4,118,101,99,52,95,116,101,120,98,49,100,0,18,95,95,114,101,116,86,97,108,0,0, +18,115,97,109,112,108,101,114,0,0,18,112,99,111,111,114,100,0,0,0,0,1,0,12,0,115,104,97,100,111, +119,50,68,76,111,100,0,1,1,0,21,115,97,109,112,108,101,114,0,0,1,1,0,11,99,111,111,114,100,0,0,1,1, +0,9,108,111,100,0,0,0,1,3,2,0,12,1,99,111,111,114,100,52,0,0,0,9,18,99,111,111,114,100,52,0,59,120, +121,122,0,18,99,111,111,114,100,0,20,0,9,18,99,111,111,114,100,52,0,59,119,0,18,108,111,100,0,20,0, +4,118,101,99,52,95,116,101,120,98,50,100,0,18,95,95,114,101,116,86,97,108,0,0,18,115,97,109,112, +108,101,114,0,0,18,99,111,111,114,100,52,0,0,0,0,1,0,12,0,115,104,97,100,111,119,50,68,80,114,111, +106,76,111,100,0,1,1,0,21,115,97,109,112,108,101,114,0,0,1,1,0,12,99,111,111,114,100,0,0,1,1,0,9, +108,111,100,0,0,0,1,3,2,0,12,1,112,99,111,111,114,100,0,0,0,9,18,112,99,111,111,114,100,0,59,120, +121,0,18,99,111,111,114,100,0,59,120,121,0,18,99,111,111,114,100,0,59,119,0,49,20,0,9,18,112,99, +111,111,114,100,0,59,122,0,18,99,111,111,114,100,0,59,122,0,20,0,9,18,112,99,111,111,114,100,0,59, +119,0,18,108,111,100,0,20,0,4,118,101,99,52,95,116,101,120,98,50,100,0,18,95,95,114,101,116,86,97, +108,0,0,18,115,97,109,112,108,101,114,0,0,18,112,99,111,111,114,100,0,0,0,0,0 diff --git a/src/mesa/shader/slang/slang_analyse.c b/src/mesa/shader/slang/slang_analyse.c deleted file mode 100644 index fe48a670ee..0000000000 --- a/src/mesa/shader/slang/slang_analyse.c +++ /dev/null @@ -1,100 +0,0 @@ -/* - * Mesa 3-D graphics library - * Version: 6.5 - * - * Copyright (C) 2006 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. - */ - -/** - * \file slang_analyse.c - * slang assembly code analysis - * \author Michal Krol - */ - -#include "imports.h" -#include "slang_analyse.h" -#include "slang_utility.h" - -GLboolean _slang_analyse_texture_usage (slang_program *prog) -{ - GLuint i, count = 0; - - _slang_texture_usages_dtr (&prog->texture_usage); - _slang_texture_usages_ctr (&prog->texture_usage); - - /* - * We could do a full code analysis to find out which uniforms are actually used. - * For now, we are very conservative and extract them from uniform binding table, which - * in turn also do not come from code analysis. - */ - - for (i = 0; i < prog->uniforms.count; i++) - { - slang_uniform_binding *b = &prog->uniforms.table[i]; - - if (b->address[SLANG_SHADER_FRAGMENT] != ~0 && !slang_export_data_quant_struct (b->quant)) - { - switch (slang_export_data_quant_type (b->quant)) - { - case GL_SAMPLER_1D_ARB: - case GL_SAMPLER_2D_ARB: - case GL_SAMPLER_3D_ARB: - case GL_SAMPLER_CUBE_ARB: - case GL_SAMPLER_1D_SHADOW_ARB: - case GL_SAMPLER_2D_SHADOW_ARB: - count++; - break; - } - } - } - - if (count == 0) - return GL_TRUE; - prog->texture_usage.table = (slang_texture_usage *) slang_alloc_malloc ( - count * sizeof (slang_texture_usage)); - if (prog->texture_usage.table == NULL) - return GL_FALSE; - prog->texture_usage.count = count; - - for (count = i = 0; i < prog->uniforms.count; i++) - { - slang_uniform_binding *b = &prog->uniforms.table[i]; - - if (b->address[SLANG_SHADER_FRAGMENT] != ~0 && !slang_export_data_quant_struct (b->quant)) - { - switch (slang_export_data_quant_type (b->quant)) - { - case GL_SAMPLER_1D_ARB: - case GL_SAMPLER_2D_ARB: - case GL_SAMPLER_3D_ARB: - case GL_SAMPLER_CUBE_ARB: - case GL_SAMPLER_1D_SHADOW_ARB: - case GL_SAMPLER_2D_SHADOW_ARB: - prog->texture_usage.table[count].quant = b->quant; - prog->texture_usage.table[count].frag_address = b->address[SLANG_SHADER_FRAGMENT]; - count++; - break; - } - } - } - - return GL_TRUE; -} - diff --git a/src/mesa/shader/slang/slang_analyse.h b/src/mesa/shader/slang/slang_analyse.h deleted file mode 100644 index d7e39ae7ce..0000000000 --- a/src/mesa/shader/slang/slang_analyse.h +++ /dev/null @@ -1,50 +0,0 @@ -/* - * Mesa 3-D graphics library - * Version: 6.5 - * - * Copyright (C) 2006 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. - */ - -#if !defined SLANG_ANALYSE_H -#define SLANG_ANALYSE_H - -#include "slang_link.h" - -#if defined __cplusplus -extern "C" { -#endif - -/* - * Texture usage analysis is a bit more difficult than for fragment programs. While fragment - * programs statically link to texture targets and texture units, shaders statically link - * only to texture targets. The texture unit linkage is determined just before the execution - * of a given primitive by reading active uniform samplers. - * - * This procedure retrieves a list of uniforms that reach texture sample instructions. - */ - -GLboolean _slang_analyse_texture_usage (slang_program *); - -#ifdef __cplusplus -} -#endif - -#endif - diff --git a/src/mesa/shader/slang/slang_assemble.c b/src/mesa/shader/slang/slang_assemble.c deleted file mode 100644 index 0cba5d5d00..0000000000 --- a/src/mesa/shader/slang/slang_assemble.c +++ /dev/null @@ -1,1542 +0,0 @@ -/* - * Mesa 3-D graphics library - * Version: 6.5 - * - * Copyright (C) 2005-2006 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. - */ - -/** - * \file slang_assemble.c - * slang intermediate code assembler - * \author Michal Krol - */ - -#include "imports.h" -#include "slang_assemble.h" -#include "slang_compile.h" -#include "slang_storage.h" - -/* slang_assembly */ - -static GLboolean -slang_assembly_construct(slang_assembly * assem) -{ - assem->type = slang_asm_none; - return GL_TRUE; -} - -static GLvoid -slang_assembly_destruct(slang_assembly * assem) -{ -} - -/* - * slang_assembly_file - */ - -GLvoid -_slang_assembly_file_ctr(slang_assembly_file * self) -{ - self->code = NULL; - self->count = 0; - self->capacity = 0; -} - -GLvoid -slang_assembly_file_destruct(slang_assembly_file * file) -{ - GLuint i; - - for (i = 0; i < file->count; i++) - slang_assembly_destruct(&file->code[i]); - slang_alloc_free(file->code); -} - -static GLboolean -push_new(slang_assembly_file * file) -{ - if (file->count == file->capacity) { - GLuint n; - - if (file->capacity == 0) - n = 256; - else - n = file->capacity * 2; - file->code = (slang_assembly *) - slang_alloc_realloc(file->code, - file->capacity * sizeof(slang_assembly), - n * sizeof(slang_assembly)); - if (file->code == NULL) - return GL_FALSE; - file->capacity = n; - } - if (!slang_assembly_construct(&file->code[file->count])) - return GL_FALSE; - file->count++; - return GL_TRUE; -} - -static GLboolean -push_gen(slang_assembly_file * file, slang_assembly_type type, - GLfloat literal, GLuint label, GLuint size) -{ - slang_assembly *assem; - - if (!push_new(file)) - return GL_FALSE; - assem = &file->code[file->count - 1]; - assem->type = type; - assem->literal = literal; - assem->param[0] = label; - assem->param[1] = size; - return GL_TRUE; -} - -GLboolean -slang_assembly_file_push(slang_assembly_file * file, slang_assembly_type type) -{ - return push_gen(file, type, (GLfloat) 0, 0, 0); -} - -GLboolean -slang_assembly_file_push_label(slang_assembly_file * file, - slang_assembly_type type, GLuint label) -{ - return push_gen(file, type, (GLfloat) 0, label, 0); -} - -GLboolean -slang_assembly_file_push_label2(slang_assembly_file * file, - slang_assembly_type type, GLuint label1, - GLuint label2) -{ - return push_gen(file, type, (GLfloat) 0, label1, label2); -} - -GLboolean -slang_assembly_file_push_literal(slang_assembly_file * file, - slang_assembly_type type, GLfloat literal) -{ - return push_gen(file, type, literal, 0, 0); -} - -#define PUSH slang_assembly_file_push -#define PLAB slang_assembly_file_push_label -#define PLAB2 slang_assembly_file_push_label2 -#define PLIT slang_assembly_file_push_literal - -/* slang_assembly_file_restore_point */ - -GLboolean -slang_assembly_file_restore_point_save(slang_assembly_file * file, - slang_assembly_file_restore_point * - point) -{ - point->count = file->count; - return GL_TRUE; -} - -GLboolean -slang_assembly_file_restore_point_load(slang_assembly_file * file, - slang_assembly_file_restore_point * - point) -{ - GLuint i; - - for (i = point->count; i < file->count; i++) - slang_assembly_destruct(&file->code[i]); - file->count = point->count; - return GL_TRUE; -} - -/* utility functions */ - -static GLboolean -sizeof_variable(slang_assemble_ctx * A, slang_type_specifier * spec, - slang_type_qualifier qual, GLuint array_len, GLuint * size) -{ - slang_storage_aggregate agg; - - /* calculate the size of the variable's aggregate */ - if (!slang_storage_aggregate_construct(&agg)) - return GL_FALSE; - if (!_slang_aggregate_variable - (&agg, spec, array_len, A->space.funcs, A->space.structs, - A->space.vars, A->mach, A->file, A->atoms)) { - slang_storage_aggregate_destruct(&agg); - return GL_FALSE; - } - *size += _slang_sizeof_aggregate(&agg); - slang_storage_aggregate_destruct(&agg); - - /* for reference variables consider the additional address overhead */ - if (qual == slang_qual_out || qual == slang_qual_inout) - *size += 4; - - return GL_TRUE; -} - -static GLboolean -sizeof_variable2(slang_assemble_ctx * A, slang_variable * var, GLuint * size) -{ - var->address = *size; - if (var->type.qualifier == slang_qual_out - || var->type.qualifier == slang_qual_inout) - var->address += 4; - return sizeof_variable(A, &var->type.specifier, var->type.qualifier, - var->array_len, size); -} - -static GLboolean -sizeof_variables(slang_assemble_ctx * A, slang_variable_scope * vars, - GLuint start, GLuint stop, GLuint * size) -{ - GLuint i; - - for (i = start; i < stop; i++) - if (!sizeof_variable2(A, &vars->variables[i], size)) - return GL_FALSE; - return GL_TRUE; -} - -static GLboolean -collect_locals(slang_assemble_ctx * A, slang_operation * op, GLuint * size) -{ - GLuint i; - - if (!sizeof_variables(A, op->locals, 0, op->locals->num_variables, size)) - return GL_FALSE; - for (i = 0; i < op->num_children; i++) - if (!collect_locals(A, &op->children[i], size)) - return GL_FALSE; - return GL_TRUE; -} - -/* _slang_locate_function() */ - -slang_function * -_slang_locate_function(const slang_function_scope * funcs, slang_atom a_name, - const slang_operation * params, GLuint num_params, - const slang_assembly_name_space * space, - slang_atom_pool * atoms) -{ - GLuint i; - - for (i = 0; i < funcs->num_functions; i++) { - GLuint j; - slang_function *f = &funcs->functions[i]; - - if (a_name != f->header.a_name) - continue; - if (f->param_count != num_params) - continue; - for (j = 0; j < num_params; j++) { - slang_assembly_typeinfo ti; - - if (!slang_assembly_typeinfo_construct(&ti)) - return NULL; - if (!_slang_typeof_operation_(¶ms[j], space, &ti, atoms)) { - slang_assembly_typeinfo_destruct(&ti); - return NULL; - } - if (!slang_type_specifier_equal - (&ti.spec, &f->parameters->variables[j].type.specifier)) { - slang_assembly_typeinfo_destruct(&ti); - break; - } - slang_assembly_typeinfo_destruct(&ti); - - /* "out" and "inout" formal parameter requires the actual parameter to be l-value */ - if (!ti.can_be_referenced && - (f->parameters->variables[j].type.qualifier == slang_qual_out || - f->parameters->variables[j].type.qualifier == slang_qual_inout)) - break; - } - if (j == num_params) - return f; - } - if (funcs->outer_scope != NULL) - return _slang_locate_function(funcs->outer_scope, a_name, params, - num_params, space, atoms); - return NULL; -} - -/* _slang_assemble_function() */ - -GLboolean -_slang_assemble_function(slang_assemble_ctx * A, slang_function * fun) -{ - GLuint param_size, local_size; - GLuint skip, cleanup; - - fun->address = A->file->count; - - if (fun->body == NULL) { - /* jump to the actual function body - we do not know it, so add - * the instruction to fixup table - */ - if (!slang_fixup_save(&fun->fixups, fun->address)) - return GL_FALSE; - if (!PUSH(A->file, slang_asm_jump)) - return GL_FALSE; - return GL_TRUE; - } - else { - /* resolve all fixup table entries and delete it */ - GLuint i; - for (i = 0; i < fun->fixups.count; i++) - A->file->code[fun->fixups.table[i]].param[0] = fun->address; - slang_fixup_table_free(&fun->fixups); - } - - /* At this point traverse function formal parameters and code to calculate - * total memory size to be allocated on the stack. - * During this process the variables will be assigned local addresses to - * reference them in the code. - * No storage optimizations are performed so exclusive scopes are not - * detected and shared. - */ - - /* calculate return value size */ - param_size = 0; - if (fun->header.type.specifier.type != slang_spec_void) - if (!sizeof_variable - (A, &fun->header.type.specifier, slang_qual_none, 0, ¶m_size)) - return GL_FALSE; - A->local.ret_size = param_size; - - /* calculate formal parameter list size */ - if (!sizeof_variables - (A, fun->parameters, 0, fun->param_count, ¶m_size)) - return GL_FALSE; - - /* calculate local variables size - take into account the four-byte - * return address and temporaries for various tasks (4 for addr and - * 16 for swizzle temporaries). these include variables from the - * formal parameter scope and from the code - */ - A->local.addr_tmp = param_size + 4; - A->local.swizzle_tmp = param_size + 4 + 4; - local_size = param_size + 4 + 4 + 16; - if (!sizeof_variables - (A, fun->parameters, fun->param_count, fun->parameters->num_variables, - &local_size)) - return GL_FALSE; - if (!collect_locals(A, fun->body, &local_size)) - return GL_FALSE; - - /* allocate local variable storage */ - if (!PLAB(A->file, slang_asm_local_alloc, local_size - param_size - 4)) - return GL_FALSE; - - /* mark a new frame for function variable storage */ - if (!PLAB(A->file, slang_asm_enter, local_size)) - return GL_FALSE; - - /* jump directly to the actual code */ - skip = A->file->count; - if (!push_new(A->file)) - return GL_FALSE; - A->file->code[skip].type = slang_asm_jump; - - /* all "return" statements will be directed here */ - A->flow.function_end = A->file->count; - cleanup = A->file->count; - if (!push_new(A->file)) - return GL_FALSE; - A->file->code[cleanup].type = slang_asm_jump; - - /* execute the function body */ - A->file->code[skip].param[0] = A->file->count; - if (!_slang_assemble_operation - (A, fun->body, /*slang_ref_freelance */ slang_ref_forbid)) - return GL_FALSE; - - /* this is the end of the function - restore the old function frame */ - A->file->code[cleanup].param[0] = A->file->count; - if (!PUSH(A->file, slang_asm_leave)) - return GL_FALSE; - - /* free local variable storage */ - if (!PLAB(A->file, slang_asm_local_free, local_size - param_size - 4)) - return GL_FALSE; - - /* return from the function */ - if (!PUSH(A->file, slang_asm_return)) - return GL_FALSE; - - return GL_TRUE; -} - -GLboolean -_slang_cleanup_stack(slang_assemble_ctx * A, slang_operation * op) -{ - slang_assembly_typeinfo ti; - GLuint size = 0; - - /* get type info of the operation and calculate its size */ - if (!slang_assembly_typeinfo_construct(&ti)) - return GL_FALSE; - if (!_slang_typeof_operation(A, op, &ti)) { - slang_assembly_typeinfo_destruct(&ti); - return GL_FALSE; - } - if (ti.spec.type != slang_spec_void) { - if (A->ref == slang_ref_force) { - size = 4; - } - else if (!sizeof_variable(A, &ti.spec, slang_qual_none, 0, &size)) { - slang_assembly_typeinfo_destruct(&ti); - return GL_FALSE; - } - } - slang_assembly_typeinfo_destruct(&ti); - - /* if nonzero, free it from the stack */ - if (size != 0) { - if (!PLAB(A->file, slang_asm_local_free, size)) - return GL_FALSE; - } - - return GL_TRUE; -} - -/* _slang_assemble_operation() */ - -static GLboolean -dereference_basic(slang_assemble_ctx * A, slang_storage_type type, - GLuint * size, slang_swizzle * swz, GLboolean is_swizzled) -{ - GLuint src_offset; - slang_assembly_type ty; - - *size -= _slang_sizeof_type(type); - - /* If swizzling is taking place, we are forced to use scalar - * operations, even if we have vec4 instructions enabled (this - * should be actually done with special vec4 shuffle instructions). - * Adjust the size and calculate the offset within source variable - * to read. - */ - if (is_swizzled) - src_offset = swz->swizzle[*size / 4] * 4; - else - src_offset = *size; - - /* dereference data slot of a basic type */ - if (!PLAB2(A->file, slang_asm_local_addr, A->local.addr_tmp, 4)) - return GL_FALSE; - if (!PUSH(A->file, slang_asm_addr_deref)) - return GL_FALSE; - if (src_offset != 0) { - if (!PLAB(A->file, slang_asm_addr_push, src_offset)) - return GL_FALSE; - if (!PUSH(A->file, slang_asm_addr_add)) - return GL_FALSE; - } - - switch (type) { - case slang_stor_bool: - ty = slang_asm_bool_deref; - break; - case slang_stor_int: - ty = slang_asm_int_deref; - break; - case slang_stor_float: - ty = slang_asm_float_deref; - break; -#if defined(USE_X86_ASM) || defined(SLANG_X86) - case slang_stor_vec4: - ty = slang_asm_vec4_deref; - break; -#endif - default: - _mesa_problem(NULL, "Unexpected arr->type in dereference_basic"); - ty = slang_asm_none; - } - - return PUSH(A->file, ty); -} - -static GLboolean -dereference_aggregate(slang_assemble_ctx * A, - const slang_storage_aggregate * agg, GLuint * size, - slang_swizzle * swz, GLboolean is_swizzled) -{ - GLuint i; - - for (i = agg->count; i > 0; i--) { - const slang_storage_array *arr = &agg->arrays[i - 1]; - GLuint j; - - for (j = arr->length; j > 0; j--) { - if (arr->type == slang_stor_aggregate) { - if (!dereference_aggregate - (A, arr->aggregate, size, swz, is_swizzled)) - return GL_FALSE; - } - else { - if (is_swizzled && arr->type == slang_stor_vec4) { - if (!dereference_basic - (A, slang_stor_float, size, swz, is_swizzled)) - return GL_FALSE; - if (!dereference_basic - (A, slang_stor_float, size, swz, is_swizzled)) - return GL_FALSE; - if (!dereference_basic - (A, slang_stor_float, size, swz, is_swizzled)) - return GL_FALSE; - if (!dereference_basic - (A, slang_stor_float, size, swz, is_swizzled)) - return GL_FALSE; - } - else { - if (!dereference_basic(A, arr->type, size, swz, is_swizzled)) - return GL_FALSE; - } - } - } - } - - return GL_TRUE; -} - -GLboolean -_slang_dereference(slang_assemble_ctx * A, slang_operation * op) -{ - slang_assembly_typeinfo ti; - GLboolean result = GL_FALSE; - slang_storage_aggregate agg; - GLuint size; - - /* get type information of the given operation */ - if (!slang_assembly_typeinfo_construct(&ti)) - return GL_FALSE; - if (!_slang_typeof_operation(A, op, &ti)) - goto end1; - - /* construct aggregate from the type info */ - if (!slang_storage_aggregate_construct(&agg)) - goto end1; - if (!_slang_aggregate_variable - (&agg, &ti.spec, ti.array_len, A->space.funcs, A->space.structs, - A->space.vars, A->mach, A->file, A->atoms)) - goto end; - - /* dereference the resulting aggregate */ - size = _slang_sizeof_aggregate(&agg); - result = dereference_aggregate(A, &agg, &size, &ti.swz, ti.is_swizzled); - - end: - slang_storage_aggregate_destruct(&agg); - end1: - slang_assembly_typeinfo_destruct(&ti); - return result; -} - -GLboolean -_slang_assemble_function_call(slang_assemble_ctx * A, slang_function * fun, - slang_operation * params, GLuint param_count, - GLboolean assignment) -{ - GLuint i; - slang_swizzle p_swz[64]; - slang_ref_type p_ref[64]; - - /* TODO: fix this, allocate dynamically */ - if (param_count > 64) - return GL_FALSE; - - /* make room for the return value, if any */ - if (fun->header.type.specifier.type != slang_spec_void) { - GLuint ret_size = 0; - - if (!sizeof_variable - (A, &fun->header.type.specifier, slang_qual_none, 0, &ret_size)) - return GL_FALSE; - if (!PLAB(A->file, slang_asm_local_alloc, ret_size)) - return GL_FALSE; - } - - /* push the actual parameters on the stack */ - for (i = 0; i < param_count; i++) { - if (fun->parameters->variables[i].type.qualifier == slang_qual_inout || - fun->parameters->variables[i].type.qualifier == slang_qual_out) { - if (!PLAB2(A->file, slang_asm_local_addr, A->local.addr_tmp, 4)) - return GL_FALSE; - /* TODO: optimize the "out" parameter case */ - if (!_slang_assemble_operation(A, ¶ms[i], slang_ref_force)) - return GL_FALSE; - p_swz[i] = A->swz; - p_ref[i] = A->ref; - if (!PUSH(A->file, slang_asm_addr_copy)) - return GL_FALSE; - if (!PUSH(A->file, slang_asm_addr_deref)) - return GL_FALSE; - if (i == 0 && assignment) { - /* duplicate the resulting address */ - if (!PLAB2(A->file, slang_asm_local_addr, A->local.addr_tmp, 4)) - return GL_FALSE; - if (!PUSH(A->file, slang_asm_addr_deref)) - return GL_FALSE; - } - if (!_slang_dereference(A, ¶ms[i])) - return GL_FALSE; - } - else { - if (!_slang_assemble_operation(A, ¶ms[i], slang_ref_forbid)) - return GL_FALSE; - p_swz[i] = A->swz; - p_ref[i] = A->ref; - } - } - - /* call the function */ - if (!PLAB(A->file, slang_asm_call, fun->address)) - return GL_FALSE; - - /* pop the parameters from the stack */ - for (i = param_count; i > 0; i--) { - GLuint j = i - 1; - - A->swz = p_swz[j]; - A->ref = p_ref[j]; - if (fun->parameters->variables[j].type.qualifier == slang_qual_inout || - fun->parameters->variables[j].type.qualifier == slang_qual_out) { - /* for output parameter copy the contents of the formal parameter - * back to the original actual parameter - */ - if (!_slang_assemble_assignment(A, ¶ms[j])) - return GL_FALSE; - /* pop the actual parameter's address */ - if (!PLAB(A->file, slang_asm_local_free, 4)) - return GL_FALSE; - } - else { - /* pop the value of the parameter */ - if (!_slang_cleanup_stack(A, ¶ms[j])) - return GL_FALSE; - } - } - - return GL_TRUE; -} - -GLboolean -_slang_assemble_function_call_name(slang_assemble_ctx * A, const char *name, - slang_operation * params, - GLuint param_count, GLboolean assignment) -{ - slang_atom atom; - slang_function *fun; - - atom = slang_atom_pool_atom(A->atoms, name); - if (atom == SLANG_ATOM_NULL) - return GL_FALSE; - fun = - _slang_locate_function(A->space.funcs, atom, params, param_count, - &A->space, A->atoms); - if (fun == NULL) - return GL_FALSE; - return _slang_assemble_function_call(A, fun, params, param_count, - assignment); -} - -static GLboolean -assemble_function_call_name_dummyint(slang_assemble_ctx * A, const char *name, - slang_operation * params) -{ - slang_operation p[2]; - GLboolean result; - - p[0] = params[0]; - if (!slang_operation_construct(&p[1])) - return GL_FALSE; - p[1].type = slang_oper_literal_int; - result = _slang_assemble_function_call_name(A, name, p, 2, GL_FALSE); - slang_operation_destruct(&p[1]); - return result; -} - -static const struct -{ - const char *name; - slang_assembly_type code1, code2; -} inst[] = { - /* core */ - {"float_add", slang_asm_float_add, slang_asm_float_copy}, - {"float_multiply", slang_asm_float_multiply, slang_asm_float_copy}, - {"float_divide", slang_asm_float_divide, slang_asm_float_copy}, - {"float_negate", slang_asm_float_negate, slang_asm_float_copy}, - {"float_less", slang_asm_float_less, slang_asm_bool_copy}, - {"float_equal", slang_asm_float_equal_exp, slang_asm_bool_copy}, - {"float_to_int", slang_asm_float_to_int, slang_asm_int_copy}, - {"float_sine", slang_asm_float_sine, slang_asm_float_copy}, - {"float_arcsine", slang_asm_float_arcsine, slang_asm_float_copy}, - {"float_arctan", slang_asm_float_arctan, slang_asm_float_copy}, - {"float_power", slang_asm_float_power, slang_asm_float_copy}, - {"float_log2", slang_asm_float_log2, slang_asm_float_copy}, - {"float_floor", slang_asm_float_floor, slang_asm_float_copy}, - {"float_ceil", slang_asm_float_ceil, slang_asm_float_copy}, - {"float_noise1", slang_asm_float_noise1, slang_asm_float_copy}, - {"float_noise2", slang_asm_float_noise2, slang_asm_float_copy}, - {"float_noise3", slang_asm_float_noise3, slang_asm_float_copy}, - {"float_noise4", slang_asm_float_noise4, slang_asm_float_copy}, - {"int_to_float", slang_asm_int_to_float, slang_asm_float_copy}, - {"vec4_tex1d", slang_asm_vec4_tex1d, slang_asm_none}, - {"vec4_tex2d", slang_asm_vec4_tex2d, slang_asm_none}, - {"vec4_tex3d", slang_asm_vec4_tex3d, slang_asm_none}, - {"vec4_texcube", slang_asm_vec4_texcube, slang_asm_none}, - {"vec4_shad1d", slang_asm_vec4_shad1d, slang_asm_none}, - {"vec4_shad2d", slang_asm_vec4_shad2d, slang_asm_none}, - /* GL_MESA_shader_debug */ - {"float_print", slang_asm_float_deref, slang_asm_float_print}, - {"int_print", slang_asm_int_deref, slang_asm_int_print}, - {"bool_print", slang_asm_bool_deref, slang_asm_bool_print}, - /* vec4 */ - {"float_to_vec4", slang_asm_float_to_vec4, slang_asm_none}, - {"vec4_add", slang_asm_vec4_add, slang_asm_none}, - {"vec4_subtract", slang_asm_vec4_subtract, slang_asm_none}, - {"vec4_multiply", slang_asm_vec4_multiply, slang_asm_none}, - {"vec4_divide", slang_asm_vec4_divide, slang_asm_none}, - {"vec4_negate", slang_asm_vec4_negate, slang_asm_none}, - {"vec4_dot", slang_asm_vec4_dot, slang_asm_none}, - {NULL, slang_asm_none, slang_asm_none} -}; - -static GLboolean -call_asm_instruction(slang_assemble_ctx * A, slang_atom a_name) -{ - const char *id; - GLuint i; - - id = slang_atom_pool_id(A->atoms, a_name); - - for (i = 0; inst[i].name != NULL; i++) - if (slang_string_compare(id, inst[i].name) == 0) - break; - if (inst[i].name == NULL) - return GL_FALSE; - - if (!PLAB2(A->file, inst[i].code1, 4, 0)) - return GL_FALSE; - if (inst[i].code2 != slang_asm_none) - if (!PLAB2(A->file, inst[i].code2, 4, 0)) - return GL_FALSE; - - /* clean-up the stack from the remaining dst address */ - if (!PLAB(A->file, slang_asm_local_free, 4)) - return GL_FALSE; - - return GL_TRUE; -} - -static GLboolean -equality_aggregate(slang_assemble_ctx * A, - const slang_storage_aggregate * agg, GLuint * index, - GLuint size, GLuint z_label) -{ - GLuint i; - - for (i = 0; i < agg->count; i++) { - const slang_storage_array *arr = &agg->arrays[i]; - GLuint j; - - for (j = 0; j < arr->length; j++) { - if (arr->type == slang_stor_aggregate) { - if (!equality_aggregate(A, arr->aggregate, index, size, z_label)) - return GL_FALSE; - } - else { -#if defined(USE_X86_ASM) || defined(SLANG_X86) - if (arr->type == slang_stor_vec4) { - if (!PLAB2 - (A->file, slang_asm_vec4_equal_int, size + *index, *index)) - return GL_FALSE; - } - else -#endif - if (!PLAB2 - (A->file, slang_asm_float_equal_int, size + *index, - *index)) - return GL_FALSE; - - *index += _slang_sizeof_type(arr->type); - if (!PLAB(A->file, slang_asm_jump_if_zero, z_label)) - return GL_FALSE; - } - } - } - - return GL_TRUE; -} - -static GLboolean -equality(slang_assemble_ctx * A, slang_operation * op, GLboolean equal) -{ - slang_assembly_typeinfo ti; - GLboolean result = GL_FALSE; - slang_storage_aggregate agg; - GLuint index, size; - GLuint skip_jump, true_label, true_jump, false_label, false_jump; - - /* get type of operation */ - if (!slang_assembly_typeinfo_construct(&ti)) - return GL_FALSE; - if (!_slang_typeof_operation(A, op, &ti)) - goto end1; - - /* convert it to an aggregate */ - if (!slang_storage_aggregate_construct(&agg)) - goto end1; - if (!_slang_aggregate_variable - (&agg, &ti.spec, 0, A->space.funcs, A->space.structs, A->space.vars, - A->mach, A->file, A->atoms)) - goto end; - - /* compute the size of the agregate - there are two such aggregates on the stack */ - size = _slang_sizeof_aggregate(&agg); - - /* jump to the actual data-comparison code */ - skip_jump = A->file->count; - if (!PUSH(A->file, slang_asm_jump)) - goto end; - - /* pop off the stack the compared data and push 1 */ - true_label = A->file->count; - if (!PLAB(A->file, slang_asm_local_free, size * 2)) - goto end; - if (!PLIT(A->file, slang_asm_bool_push, (GLfloat) 1)) - goto end; - true_jump = A->file->count; - if (!PUSH(A->file, slang_asm_jump)) - goto end; - - false_label = A->file->count; - if (!PLAB(A->file, slang_asm_local_free, size * 2)) - goto end; - if (!PLIT(A->file, slang_asm_bool_push, (GLfloat) 0)) - goto end; - false_jump = A->file->count; - if (!PUSH(A->file, slang_asm_jump)) - goto end; - - A->file->code[skip_jump].param[0] = A->file->count; - - /* compare the data on stack, it will eventually jump either to true or false label */ - index = 0; - if (!equality_aggregate - (A, &agg, &index, size, equal ? false_label : true_label)) - goto end; - if (!PLAB(A->file, slang_asm_jump, equal ? true_label : false_label)) - goto end; - - A->file->code[true_jump].param[0] = A->file->count; - A->file->code[false_jump].param[0] = A->file->count; - - result = GL_TRUE; - end: - slang_storage_aggregate_destruct(&agg); - end1: - slang_assembly_typeinfo_destruct(&ti); - return result; -} - -static GLboolean -handle_subscript(slang_assemble_ctx * A, slang_assembly_typeinfo * tie, - slang_assembly_typeinfo * tia, slang_operation * op, - slang_ref_type ref) -{ - GLuint asize = 0, esize = 0; - - /* get type info of the master expression (matrix, vector or an array */ - if (!_slang_typeof_operation(A, &op->children[0], tia)) - return GL_FALSE; - if (!sizeof_variable - (A, &tia->spec, slang_qual_none, tia->array_len, &asize)) - return GL_FALSE; - - /* get type info of the result (matrix column, vector row or array element) */ - if (!_slang_typeof_operation(A, op, tie)) - return GL_FALSE; - if (!sizeof_variable(A, &tie->spec, slang_qual_none, 0, &esize)) - return GL_FALSE; - - /* assemble the master expression */ - if (!_slang_assemble_operation(A, &op->children[0], ref)) - return GL_FALSE; - - /* when indexing an l-value swizzle, push the swizzle_tmp */ - if (ref == slang_ref_force && tia->is_swizzled) - if (!PLAB2(A->file, slang_asm_local_addr, A->local.swizzle_tmp, 16)) - return GL_FALSE; - - /* assemble the subscript expression */ - if (!_slang_assemble_operation(A, &op->children[1], slang_ref_forbid)) - return GL_FALSE; - - if (ref == slang_ref_force && tia->is_swizzled) { - GLuint i; - - /* copy the swizzle indexes to the swizzle_tmp */ - for (i = 0; i < tia->swz.num_components; i++) { - if (!PLAB2(A->file, slang_asm_local_addr, A->local.swizzle_tmp, 16)) - return GL_FALSE; - if (!PLAB(A->file, slang_asm_addr_push, i * 4)) - return GL_FALSE; - if (!PUSH(A->file, slang_asm_addr_add)) - return GL_FALSE; - if (!PLAB(A->file, slang_asm_addr_push, tia->swz.swizzle[i])) - return GL_FALSE; - if (!PUSH(A->file, slang_asm_addr_copy)) - return GL_FALSE; - if (!PLAB(A->file, slang_asm_local_free, 4)) - return GL_FALSE; - } - - /* offset the pushed swizzle_tmp address and dereference it */ - if (!PUSH(A->file, slang_asm_int_to_addr)) - return GL_FALSE; - if (!PLAB(A->file, slang_asm_addr_push, 4)) - return GL_FALSE; - if (!PUSH(A->file, slang_asm_addr_multiply)) - return GL_FALSE; - if (!PUSH(A->file, slang_asm_addr_add)) - return GL_FALSE; - if (!PUSH(A->file, slang_asm_addr_deref)) - return GL_FALSE; - } - else { - /* convert the integer subscript to a relative address */ - if (!PUSH(A->file, slang_asm_int_to_addr)) - return GL_FALSE; - } - - if (!PLAB(A->file, slang_asm_addr_push, esize)) - return GL_FALSE; - if (!PUSH(A->file, slang_asm_addr_multiply)) - return GL_FALSE; - - if (ref == slang_ref_force) { - /* offset the base address with the relative address */ - if (!PUSH(A->file, slang_asm_addr_add)) - return GL_FALSE; - } - else { - GLuint i; - - /* move the selected element to the beginning of the master expression */ - for (i = 0; i < esize; i += 4) - if (!PLAB2 - (A->file, slang_asm_float_move, asize - esize + i + 4, i + 4)) - return GL_FALSE; - if (!PLAB(A->file, slang_asm_local_free, 4)) - return GL_FALSE; - - /* free the rest of the master expression */ - if (!PLAB(A->file, slang_asm_local_free, asize - esize)) - return GL_FALSE; - } - - return GL_TRUE; -} - -static GLboolean -handle_field(slang_assemble_ctx * A, slang_assembly_typeinfo * tia, - slang_assembly_typeinfo * tib, slang_operation * op, - slang_ref_type ref) -{ - /* get type info of the result (field or swizzle) */ - if (!_slang_typeof_operation(A, op, tia)) - return GL_FALSE; - - /* get type info of the master expression being accessed (struct or vector) */ - if (!_slang_typeof_operation(A, &op->children[0], tib)) - return GL_FALSE; - - /* if swizzling a vector in-place, the swizzle temporary is needed */ - if (ref == slang_ref_forbid && tia->is_swizzled) - if (!PLAB2(A->file, slang_asm_local_addr, A->local.swizzle_tmp, 16)) - return GL_FALSE; - - /* assemble the master expression */ - if (!_slang_assemble_operation(A, &op->children[0], ref)) - return GL_FALSE; - - /* assemble the field expression */ - if (tia->is_swizzled) { - if (ref == slang_ref_force) { -#if 0 - if (tia->swz.num_components == 1) { - /* simple case - adjust the vector's address to point to - * the selected component - */ - if (!PLAB(file, slang_asm_addr_push, tia->swz.swizzle[0] * 4)) - return 0; - if (!PUSH(file, slang_asm_addr_add)) - return 0; - } - else -#endif - { - /* two or more vector components are being referenced - - * the so-called write mask must be passed to the upper - * operations and applied when assigning value to this swizzle - */ - A->swz = tia->swz; - } - } - else { - /* swizzle the vector in-place using the swizzle temporary */ - if (!_slang_assemble_constructor_from_swizzle - (A, &tia->swz, &tia->spec, &tib->spec)) - return GL_FALSE; - } - } - else { - GLuint i, struct_size = 0, field_offset = 0, field_size = 0; - - /* - * Calculate struct size, field offset and field size. - */ - for (i = 0; i < tib->spec._struct->fields->num_variables; i++) { - slang_variable *field; - slang_storage_aggregate agg; - GLuint size; - - field = &tib->spec._struct->fields->variables[i]; - if (!slang_storage_aggregate_construct(&agg)) - return GL_FALSE; - if (!_slang_aggregate_variable - (&agg, &field->type.specifier, field->array_len, A->space.funcs, - A->space.structs, A->space.vars, A->mach, A->file, A->atoms)) { - slang_storage_aggregate_destruct(&agg); - return GL_FALSE; - } - size = _slang_sizeof_aggregate(&agg); - slang_storage_aggregate_destruct(&agg); - - if (op->a_id == field->a_name) { - field_size = size; - field_offset = struct_size; - } - struct_size += size; - } - - if (ref == slang_ref_force) { - GLboolean shift; - - /* - * OPTIMIZATION: If selecting first field, no address shifting - * is needed. - */ - shift = (field_offset != 0); - - if (shift) { - if (!PLAB(A->file, slang_asm_addr_push, field_offset)) - return GL_FALSE; - if (!PUSH(A->file, slang_asm_addr_add)) - return GL_FALSE; - } - } - else { - GLboolean relocate, shrink; - GLuint free_b = 0; - - /* - * OPTIMIZATION: If selecting last field, no relocation is needed. - */ - relocate = (field_offset != (struct_size - field_size)); - - /* - * OPTIMIZATION: If field and struct sizes are equal, no partial - * free is needed. - */ - shrink = (field_size != struct_size); - - if (relocate) { - GLuint i; - - /* - * Move the selected element to the end of the master expression. - * Do it in reverse order to avoid overwriting itself. - */ - if (!PLAB(A->file, slang_asm_addr_push, field_offset)) - return GL_FALSE; - for (i = field_size; i > 0; i -= 4) - if (!PLAB2 - (A->file, slang_asm_float_move, - struct_size - field_size + i, i)) - return GL_FALSE; - free_b += 4; - } - - if (shrink) { - /* free the rest of the master expression */ - free_b += struct_size - field_size; - } - - if (free_b) { - if (!PLAB(A->file, slang_asm_local_free, free_b)) - return GL_FALSE; - } - } - } - - return GL_TRUE; -} - -GLboolean -_slang_assemble_operation(slang_assemble_ctx * A, slang_operation * op, - slang_ref_type ref) -{ - /* set default results */ - A->ref = /*(ref == slang_ref_freelance) ? slang_ref_force : */ ref; - A->swz.num_components = 0; - - switch (op->type) { - case slang_oper_block_no_new_scope: - case slang_oper_block_new_scope: - { - GLuint i; - - for (i = 0; i < op->num_children; i++) { - if (!_slang_assemble_operation - (A, &op->children[i], - slang_ref_forbid /*slang_ref_freelance */ )) - return GL_FALSE; - if (!_slang_cleanup_stack(A, &op->children[i])) - return GL_FALSE; - } - } - break; - case slang_oper_variable_decl: - { - GLuint i; - slang_operation assign; - GLboolean result; - - /* Construct assignment expression placeholder. */ - if (!slang_operation_construct(&assign)) - return GL_FALSE; - assign.type = slang_oper_assign; - assign.children = - (slang_operation *) slang_alloc_malloc(2 * - sizeof(slang_operation)); - if (assign.children == NULL) { - slang_operation_destruct(&assign); - return GL_FALSE; - } - for (assign.num_children = 0; assign.num_children < 2; - assign.num_children++) - if (!slang_operation_construct - (&assign.children[assign.num_children])) { - slang_operation_destruct(&assign); - return GL_FALSE; - } - - result = GL_TRUE; - for (i = 0; i < op->num_children; i++) { - slang_variable *var; - - var = - _slang_locate_variable(op->children[i].locals, - op->children[i].a_id, GL_TRUE); - if (var == NULL) { - result = GL_FALSE; - break; - } - if (var->initializer == NULL) - continue; - - if (!slang_operation_copy(&assign.children[0], &op->children[i]) - || !slang_operation_copy(&assign.children[1], - var->initializer) - || !_slang_assemble_assign(A, &assign, "=", slang_ref_forbid) - || !_slang_cleanup_stack(A, &assign)) { - result = GL_FALSE; - break; - } - } - slang_operation_destruct(&assign); - if (!result) - return GL_FALSE; - } - break; - case slang_oper_asm: - { - GLuint i; - if (!_slang_assemble_operation(A, &op->children[0], slang_ref_force)) - return GL_FALSE; - for (i = 1; i < op->num_children; i++) - if (!_slang_assemble_operation - (A, &op->children[i], slang_ref_forbid)) - return GL_FALSE; - if (!call_asm_instruction(A, op->a_id)) - return GL_FALSE; - } - break; - case slang_oper_break: - if (!PLAB(A->file, slang_asm_jump, A->flow.loop_end)) - return GL_FALSE; - break; - case slang_oper_continue: - if (!PLAB(A->file, slang_asm_jump, A->flow.loop_start)) - return GL_FALSE; - break; - case slang_oper_discard: - if (!PUSH(A->file, slang_asm_discard)) - return GL_FALSE; - if (!PUSH(A->file, slang_asm_exit)) - return GL_FALSE; - break; - case slang_oper_return: - if (A->local.ret_size != 0) { - /* push the result's address */ - if (!PLAB2(A->file, slang_asm_local_addr, 0, A->local.ret_size)) - return GL_FALSE; - if (!_slang_assemble_operation - (A, &op->children[0], slang_ref_forbid)) - return GL_FALSE; - - A->swz.num_components = 0; - /* assign the operation to the function result (it was reserved on the stack) */ - if (!_slang_assemble_assignment(A, op->children)) - return GL_FALSE; - - if (!PLAB(A->file, slang_asm_local_free, 4)) - return GL_FALSE; - } - if (!PLAB(A->file, slang_asm_jump, A->flow.function_end)) - return GL_FALSE; - break; - case slang_oper_expression: - if (ref == slang_ref_force) - return GL_FALSE; - if (!_slang_assemble_operation(A, &op->children[0], ref)) - return GL_FALSE; - break; - case slang_oper_if: - if (!_slang_assemble_if(A, op)) - return GL_FALSE; - break; - case slang_oper_while: - if (!_slang_assemble_while(A, op)) - return GL_FALSE; - break; - case slang_oper_do: - if (!_slang_assemble_do(A, op)) - return GL_FALSE; - break; - case slang_oper_for: - if (!_slang_assemble_for(A, op)) - return GL_FALSE; - break; - case slang_oper_void: - break; - case slang_oper_literal_bool: - if (ref == slang_ref_force) - return GL_FALSE; - if (!PLIT(A->file, slang_asm_bool_push, op->literal)) - return GL_FALSE; - A->ref = slang_ref_forbid; - break; - case slang_oper_literal_int: - if (ref == slang_ref_force) - return GL_FALSE; - if (!PLIT(A->file, slang_asm_int_push, op->literal)) - return GL_FALSE; - A->ref = slang_ref_forbid; - break; - case slang_oper_literal_float: - if (ref == slang_ref_force) - return GL_FALSE; - if (!PLIT(A->file, slang_asm_float_push, op->literal)) - return GL_FALSE; - A->ref = slang_ref_forbid; - break; - case slang_oper_identifier: - { - slang_variable *var; - GLuint size; - - /* find the variable and calculate its size */ - var = _slang_locate_variable(op->locals, op->a_id, GL_TRUE); - if (var == NULL) - return GL_FALSE; - size = 0; - if (!sizeof_variable - (A, &var->type.specifier, slang_qual_none, var->array_len, - &size)) - return GL_FALSE; - - /* prepare stack for dereferencing */ - if (ref == slang_ref_forbid) - if (!PLAB2(A->file, slang_asm_local_addr, A->local.addr_tmp, 4)) - return GL_FALSE; - - /* push the variable's address */ - if (var->global) { - if (!PLAB(A->file, slang_asm_global_addr, var->address)) - return GL_FALSE; - } - else { - if (!PLAB2(A->file, slang_asm_local_addr, var->address, size)) - return GL_FALSE; - } - - /* perform the dereference */ - if (ref == slang_ref_forbid) { - if (!PUSH(A->file, slang_asm_addr_copy)) - return GL_FALSE; - if (!PLAB(A->file, slang_asm_local_free, 4)) - return GL_FALSE; - if (!_slang_dereference(A, op)) - return GL_FALSE; - } - } - break; - case slang_oper_sequence: - if (ref == slang_ref_force) - return GL_FALSE; - if (!_slang_assemble_operation(A, &op->children[0], - slang_ref_forbid /*slang_ref_freelance */ )) - return GL_FALSE; - if (!_slang_cleanup_stack(A, &op->children[0])) - return GL_FALSE; - if (!_slang_assemble_operation(A, &op->children[1], slang_ref_forbid)) - return GL_FALSE; - A->ref = slang_ref_forbid; - break; - case slang_oper_assign: - if (!_slang_assemble_assign(A, op, "=", ref)) - return GL_FALSE; - break; - case slang_oper_addassign: - if (!_slang_assemble_assign(A, op, "+=", ref)) - return GL_FALSE; - A->ref = ref; - break; - case slang_oper_subassign: - if (!_slang_assemble_assign(A, op, "-=", ref)) - return GL_FALSE; - A->ref = ref; - break; - case slang_oper_mulassign: - if (!_slang_assemble_assign(A, op, "*=", ref)) - return GL_FALSE; - A->ref = ref; - 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_divassign: - if (!_slang_assemble_assign(A, op, "/=", ref)) - return GL_FALSE; - A->ref = ref; - break; - case slang_oper_select: - if (!_slang_assemble_select(A, op)) - return GL_FALSE; - A->ref = slang_ref_forbid; - break; - case slang_oper_logicalor: - if (!_slang_assemble_logicalor(A, op)) - return GL_FALSE; - A->ref = slang_ref_forbid; - break; - case slang_oper_logicaland: - if (!_slang_assemble_logicaland(A, op)) - return GL_FALSE; - A->ref = slang_ref_forbid; - break; - case slang_oper_logicalxor: - if (!_slang_assemble_function_call_name(A, "^^", op->children, 2, GL_FALSE)) - return GL_FALSE; - A->ref = slang_ref_forbid; - break; - /*case slang_oper_bitor: */ - /*case slang_oper_bitxor: */ - /*case slang_oper_bitand: */ - case slang_oper_less: - if (!_slang_assemble_function_call_name(A, "<", op->children, 2, GL_FALSE)) - return GL_FALSE; - A->ref = slang_ref_forbid; - break; - case slang_oper_greater: - if (!_slang_assemble_function_call_name(A, ">", op->children, 2, GL_FALSE)) - return GL_FALSE; - A->ref = slang_ref_forbid; - break; - case slang_oper_lessequal: - if (!_slang_assemble_function_call_name(A, "<=", op->children, 2, GL_FALSE)) - return GL_FALSE; - A->ref = slang_ref_forbid; - break; - case slang_oper_greaterequal: - if (!_slang_assemble_function_call_name(A, ">=", op->children, 2, GL_FALSE)) - return GL_FALSE; - A->ref = slang_ref_forbid; - break; - /*case slang_oper_lshift: */ - /*case slang_oper_rshift: */ - case slang_oper_add: - if (!_slang_assemble_function_call_name(A, "+", op->children, 2, GL_FALSE)) - return GL_FALSE; - A->ref = slang_ref_forbid; - break; - case slang_oper_subtract: - if (!_slang_assemble_function_call_name(A, "-", op->children, 2, GL_FALSE)) - return GL_FALSE; - A->ref = slang_ref_forbid; - break; - case slang_oper_multiply: - if (!_slang_assemble_function_call_name(A, "*", op->children, 2, GL_FALSE)) - return GL_FALSE; - A->ref = slang_ref_forbid; - break; - /*case slang_oper_modulus: */ - case slang_oper_divide: - if (!_slang_assemble_function_call_name(A, "/", op->children, 2, GL_FALSE)) - return GL_FALSE; - A->ref = slang_ref_forbid; - break; - case slang_oper_equal: - if (!_slang_assemble_operation(A, &op->children[0], slang_ref_forbid)) - return GL_FALSE; - if (!_slang_assemble_operation(A, &op->children[1], slang_ref_forbid)) - return GL_FALSE; - if (!equality(A, op->children, GL_TRUE)) - return GL_FALSE; - A->ref = slang_ref_forbid; - break; - case slang_oper_notequal: - if (!_slang_assemble_operation(A, &op->children[0], slang_ref_forbid)) - return GL_FALSE; - if (!_slang_assemble_operation(A, &op->children[1], slang_ref_forbid)) - return GL_FALSE; - if (!equality(A, op->children, GL_FALSE)) - return GL_FALSE; - A->ref = slang_ref_forbid; - break; - case slang_oper_preincrement: - if (!_slang_assemble_assign(A, op, "++", ref)) - return GL_FALSE; - A->ref = ref; - break; - case slang_oper_predecrement: - if (!_slang_assemble_assign(A, op, "--", ref)) - return GL_FALSE; - A->ref = ref; - break; - case slang_oper_plus: - if (!_slang_dereference(A, op)) - return GL_FALSE; - A->ref = slang_ref_forbid; - break; - case slang_oper_minus: - if (!_slang_assemble_function_call_name - (A, "-", op->children, 1, GL_FALSE)) - return GL_FALSE; - A->ref = slang_ref_forbid; - break; - /*case slang_oper_complement: */ - case slang_oper_not: - if (!_slang_assemble_function_call_name - (A, "!", op->children, 1, GL_FALSE)) - return GL_FALSE; - A->ref = slang_ref_forbid; - break; - case slang_oper_subscript: - { - slang_assembly_typeinfo ti_arr, ti_elem; - - if (!slang_assembly_typeinfo_construct(&ti_arr)) - return GL_FALSE; - if (!slang_assembly_typeinfo_construct(&ti_elem)) { - slang_assembly_typeinfo_destruct(&ti_arr); - return GL_FALSE; - } - if (!handle_subscript(A, &ti_elem, &ti_arr, op, ref)) { - slang_assembly_typeinfo_destruct(&ti_arr); - slang_assembly_typeinfo_destruct(&ti_elem); - return GL_FALSE; - } - slang_assembly_typeinfo_destruct(&ti_arr); - slang_assembly_typeinfo_destruct(&ti_elem); - } - break; - case slang_oper_call: - { - slang_function *fun; - - fun = - _slang_locate_function(A->space.funcs, op->a_id, op->children, - op->num_children, &A->space, A->atoms); - if (fun == NULL) { - if (!_slang_assemble_constructor(A, op)) - return GL_FALSE; - } - else { - if (!_slang_assemble_function_call - (A, fun, op->children, op->num_children, GL_FALSE)) - return GL_FALSE; - } - A->ref = slang_ref_forbid; - } - break; - case slang_oper_field: - { - slang_assembly_typeinfo ti_after, ti_before; - - if (!slang_assembly_typeinfo_construct(&ti_after)) - return GL_FALSE; - if (!slang_assembly_typeinfo_construct(&ti_before)) { - slang_assembly_typeinfo_destruct(&ti_after); - return GL_FALSE; - } - if (!handle_field(A, &ti_after, &ti_before, op, ref)) { - slang_assembly_typeinfo_destruct(&ti_after); - slang_assembly_typeinfo_destruct(&ti_before); - return GL_FALSE; - } - slang_assembly_typeinfo_destruct(&ti_after); - slang_assembly_typeinfo_destruct(&ti_before); - } - break; - case slang_oper_postincrement: - if (!assemble_function_call_name_dummyint(A, "++", op->children)) - return GL_FALSE; - A->ref = slang_ref_forbid; - break; - case slang_oper_postdecrement: - if (!assemble_function_call_name_dummyint(A, "--", op->children)) - return GL_FALSE; - A->ref = slang_ref_forbid; - break; - default: - return GL_FALSE; - } - - return GL_TRUE; -} diff --git a/src/mesa/shader/slang/slang_assemble.h b/src/mesa/shader/slang/slang_assemble.h deleted file mode 100644 index d004e66500..0000000000 --- a/src/mesa/shader/slang/slang_assemble.h +++ /dev/null @@ -1,278 +0,0 @@ -/* - * Mesa 3-D graphics library - * Version: 6.5.2 - * - * Copyright (C) 2005-2006 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 SLANG_ASSEMBLE_H -#define SLANG_ASSEMBLE_H - -#include "slang_utility.h" - -#if defined __cplusplus -extern "C" { -#endif - - -struct slang_operation_; - -typedef enum slang_assembly_type_ -{ - /* core */ - slang_asm_none, - slang_asm_float_copy, - slang_asm_float_move, - slang_asm_float_push, - slang_asm_float_deref, - slang_asm_float_add, /* a = pop(); b = pop(); push(a + b); */ - slang_asm_float_multiply, - slang_asm_float_divide, - slang_asm_float_negate, /* push(-pop()) */ - slang_asm_float_less, /* a = pop(); b = pop(); push(a < b); */ - slang_asm_float_equal_exp, - slang_asm_float_equal_int, - slang_asm_float_to_int, /* push(floatToInt(pop())) */ - slang_asm_float_sine, /* push(sin(pop()) */ - slang_asm_float_arcsine, - slang_asm_float_arctan, - slang_asm_float_power, /* push(pow(pop(), pop())) */ - slang_asm_float_log2, - slang_asm_float_floor, - slang_asm_float_ceil, - slang_asm_float_noise1, /* push(noise1(pop()) */ - slang_asm_float_noise2, /* push(noise2(pop(), pop())) */ - slang_asm_float_noise3, - slang_asm_float_noise4, - - slang_asm_int_copy, - slang_asm_int_move, - slang_asm_int_push, - slang_asm_int_deref, - slang_asm_int_to_float, - slang_asm_int_to_addr, - - slang_asm_bool_copy, - slang_asm_bool_move, - slang_asm_bool_push, - slang_asm_bool_deref, - - slang_asm_addr_copy, - slang_asm_addr_push, - slang_asm_addr_deref, - slang_asm_addr_add, - slang_asm_addr_multiply, - - slang_asm_vec4_tex1d, - slang_asm_vec4_tex2d, - slang_asm_vec4_tex3d, - slang_asm_vec4_texcube, - slang_asm_vec4_shad1d, - slang_asm_vec4_shad2d, - - slang_asm_jump, - slang_asm_jump_if_zero, - - slang_asm_enter, - slang_asm_leave, - - slang_asm_local_alloc, - slang_asm_local_free, - slang_asm_local_addr, - slang_asm_global_addr, - - slang_asm_call, /* push(ip); jump(inst->param[0]); */ - slang_asm_return, - - slang_asm_discard, - slang_asm_exit, - /* GL_MESA_shader_debug */ - slang_asm_float_print, - slang_asm_int_print, - slang_asm_bool_print, - /* vec4 */ - slang_asm_float_to_vec4, - slang_asm_vec4_add, - slang_asm_vec4_subtract, - slang_asm_vec4_multiply, - slang_asm_vec4_divide, - slang_asm_vec4_negate, - slang_asm_vec4_dot, - slang_asm_vec4_copy, - slang_asm_vec4_deref, - slang_asm_vec4_equal_int, - /* not a real assembly instruction */ - slang_asm__last -} slang_assembly_type; - - -/** - * An assembly-level shader instruction. - */ -typedef struct slang_assembly_ -{ - slang_assembly_type type; /**< The instruction opcode */ - GLfloat literal; /**< float literal */ - GLuint param[2]; /**< Two integer/address parameters */ -} slang_assembly; - - -/** - * A list of slang_assembly instructions - */ -typedef struct slang_assembly_file_ -{ - slang_assembly *code; - GLuint count; - GLuint capacity; -} slang_assembly_file; - - -extern GLvoid -_slang_assembly_file_ctr(slang_assembly_file *); - -extern GLvoid -slang_assembly_file_destruct(slang_assembly_file *); - -extern GLboolean -slang_assembly_file_push(slang_assembly_file *, slang_assembly_type); - -extern GLboolean -slang_assembly_file_push_label(slang_assembly_file *, - slang_assembly_type, GLuint); - -extern GLboolean -slang_assembly_file_push_label2(slang_assembly_file *, slang_assembly_type, - GLuint, GLuint); - -extern GLboolean -slang_assembly_file_push_literal(slang_assembly_file *, - slang_assembly_type, GLfloat); - - -typedef struct slang_assembly_file_restore_point_ -{ - GLuint count; -} slang_assembly_file_restore_point; - - -extern GLboolean -slang_assembly_file_restore_point_save(slang_assembly_file *, - slang_assembly_file_restore_point *); - -extern GLboolean -slang_assembly_file_restore_point_load(slang_assembly_file *, - slang_assembly_file_restore_point *); - - -typedef struct slang_assembly_flow_control_ -{ - GLuint loop_start; /**< for "continue" statement */ - GLuint loop_end; /**< for "break" statement */ - GLuint function_end; /**< for "return" statement */ -} slang_assembly_flow_control; - -typedef struct slang_assembly_local_info_ -{ - GLuint ret_size; - GLuint addr_tmp; - GLuint swizzle_tmp; -} slang_assembly_local_info; - -typedef enum -{ - slang_ref_force, - slang_ref_forbid /**< slang_ref_freelance */ -} slang_ref_type; - -/** - * Holds complete information about vector swizzle - the <swizzle> - * array contains vector component source indices, where 0 is "x", 1 - * is "y", 2 is "z" and 3 is "w". - * Example: "xwz" --> { 3, { 0, 3, 2, not used } }. - */ -typedef struct slang_swizzle_ -{ - GLuint num_components; - GLuint swizzle[4]; -} slang_swizzle; - -typedef struct slang_assembly_name_space_ -{ - struct slang_function_scope_ *funcs; - struct slang_struct_scope_ *structs; - struct slang_variable_scope_ *vars; -} slang_assembly_name_space; - -typedef struct slang_assemble_ctx_ -{ - slang_assembly_file *file; - struct slang_machine_ *mach; - slang_atom_pool *atoms; - slang_assembly_name_space space; - slang_assembly_flow_control flow; - slang_assembly_local_info local; - slang_ref_type ref; - slang_swizzle swz; -} slang_assemble_ctx; - -extern struct slang_function_ * -_slang_locate_function(const struct slang_function_scope_ *funcs, - slang_atom name, const struct slang_operation_ *params, - GLuint num_params, - const slang_assembly_name_space *space, - slang_atom_pool *); - -extern GLboolean -_slang_assemble_function(slang_assemble_ctx *, struct slang_function_ *); - -extern GLboolean -_slang_assemble_function2(slang_assemble_ctx * , struct slang_function_ *); - -extern GLboolean -_slang_cleanup_stack(slang_assemble_ctx *, struct slang_operation_ *); - -extern GLboolean -_slang_dereference(slang_assemble_ctx *, struct slang_operation_ *); - -extern GLboolean -_slang_assemble_function_call(slang_assemble_ctx *, struct slang_function_ *, - struct slang_operation_ *, GLuint, GLboolean); - -extern GLboolean -_slang_assemble_function_call_name(slang_assemble_ctx *, const char *, - struct slang_operation_ *, GLuint, - GLboolean); - -extern GLboolean -_slang_assemble_operation(slang_assemble_ctx *, struct slang_operation_ *, - slang_ref_type); - - -#ifdef __cplusplus -} -#endif - -#include "slang_assemble_assignment.h" -#include "slang_assemble_typeinfo.h" -#include "slang_assemble_constructor.h" -#include "slang_assemble_conditional.h" - -#endif diff --git a/src/mesa/shader/slang/slang_assemble_assignment.c b/src/mesa/shader/slang/slang_assemble_assignment.c deleted file mode 100644 index a1038671c4..0000000000 --- a/src/mesa/shader/slang/slang_assemble_assignment.c +++ /dev/null @@ -1,223 +0,0 @@ -/* - * Mesa 3-D graphics library - * Version: 6.5.2 - * - * Copyright (C) 2005-2006 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. - */ - -/** - * \file slang_assemble_assignment.c - * slang assignment expressions assembler - * \author Michal Krol - */ - -#include "imports.h" -#include "slang_assemble.h" -#include "slang_storage.h" - -/* - * _slang_assemble_assignment() - * - * Copies values on the stack (<component 0> to <component N-1>) to a memory - * location pointed by <addr of variable>. - * - * in: - * +------------------+ - * | addr of variable | - * +------------------+ - * | component N-1 | - * | ... | - * | component 0 | - * +------------------+ - * - * out: - * +------------------+ - * | addr of variable | - * +------------------+ - */ - - - -static GLboolean -assign_basic(slang_assemble_ctx * A, slang_storage_type type, GLuint * index, - GLuint size) -{ - GLuint dst_offset, dst_addr_loc; - slang_assembly_type ty; - - /* Calculate the offset within destination variable to write. */ - if (A->swz.num_components != 0) - dst_offset = A->swz.swizzle[*index / 4] * 4; - else - dst_offset = *index; - - switch (type) { - case slang_stor_bool: - ty = slang_asm_bool_copy; - break; - case slang_stor_int: - ty = slang_asm_int_copy; - break; - case slang_stor_float: - ty = slang_asm_float_copy; - break; -#if defined(USE_X86_ASM) || defined(SLANG_X86) - case slang_stor_vec4: - ty = slang_asm_vec4_copy; - break; -#endif - default: - _mesa_problem(NULL, "Unexpected arr->type in assign_basic"); - ty = slang_asm_none; - } - - /* Calculate the distance from top of the stack to the destination - * address. As the copy operation progresses, components of the - * source are being successively popped off the stack by the amount - * of *index increase step. - */ - dst_addr_loc = size - *index; - - if (!slang_assembly_file_push_label2 - (A->file, ty, dst_addr_loc, dst_offset)) - return GL_FALSE; - *index += _slang_sizeof_type(type); - - return GL_TRUE; -} - - -static GLboolean -assign_aggregate(slang_assemble_ctx * A, const slang_storage_aggregate * agg, - GLuint * index, GLuint size) -{ - GLuint i; - - for (i = 0; i < agg->count; i++) { - const slang_storage_array *arr = &agg->arrays[i]; - GLuint j; - - for (j = 0; j < arr->length; j++) { - if (arr->type == slang_stor_aggregate) { - if (!assign_aggregate(A, arr->aggregate, index, size)) - return GL_FALSE; - } - else { - /* When the destination is swizzled, we are forced to do - * float_copy, even if vec4 extension is enabled with - * vec4_copy operation. - */ - if (A->swz.num_components != 0 && arr->type == slang_stor_vec4) { - if (!assign_basic(A, slang_stor_float, index, size)) - return GL_FALSE; - if (!assign_basic(A, slang_stor_float, index, size)) - return GL_FALSE; - if (!assign_basic(A, slang_stor_float, index, size)) - return GL_FALSE; - if (!assign_basic(A, slang_stor_float, index, size)) - return GL_FALSE; - } - else { - if (!assign_basic(A, arr->type, index, size)) - return GL_FALSE; - } - } - } - } - - return GL_TRUE; -} - - -GLboolean -_slang_assemble_assignment(slang_assemble_ctx * A, const slang_operation * op) -{ - slang_assembly_typeinfo ti; - GLboolean result = GL_FALSE; - slang_storage_aggregate agg; - GLuint index, size; - - if (!slang_assembly_typeinfo_construct(&ti)) - return GL_FALSE; - if (!_slang_typeof_operation(A, op, &ti)) - goto end1; - - if (!slang_storage_aggregate_construct(&agg)) - goto end1; - if (!_slang_aggregate_variable(&agg, &ti.spec, 0, A->space.funcs, - A->space.structs, A->space.vars, - A->mach, A->file, A->atoms)) - goto end; - - index = 0; - size = _slang_sizeof_aggregate(&agg); - result = assign_aggregate(A, &agg, &index, size); - - end1: - slang_storage_aggregate_destruct(&agg); - end: - slang_assembly_typeinfo_destruct(&ti); - return result; -} - - -/** - * Performs unary (pre ++ and --) or binary (=, +=, -=, *=, /=) - * assignment on the operation's children. - */ -GLboolean -_slang_assemble_assign(slang_assemble_ctx * A, slang_operation * op, - const char *oper, slang_ref_type ref) -{ - slang_swizzle swz; - - if (ref == slang_ref_forbid) { - if (!slang_assembly_file_push_label2 - (A->file, slang_asm_local_addr, A->local.addr_tmp, 4)) - return GL_FALSE; - } - - if (slang_string_compare("=", oper) == 0) { - if (!_slang_assemble_operation(A, &op->children[0], slang_ref_force)) - return GL_FALSE; - swz = A->swz; - if (!_slang_assemble_operation(A, &op->children[1], slang_ref_forbid)) - return GL_FALSE; - A->swz = swz; - if (!_slang_assemble_assignment(A, op->children)) - return GL_FALSE; - } - else { - if (!_slang_assemble_function_call_name - (A, oper, op->children, op->num_children, GL_TRUE)) - return GL_FALSE; - } - - if (ref == slang_ref_forbid) { - if (!slang_assembly_file_push(A->file, slang_asm_addr_copy)) - return GL_FALSE; - if (!slang_assembly_file_push_label(A->file, slang_asm_local_free, 4)) - return GL_FALSE; - if (!_slang_dereference(A, op->children)) - return GL_FALSE; - } - - return GL_TRUE; -} diff --git a/src/mesa/shader/slang/slang_assemble_conditional.c b/src/mesa/shader/slang/slang_assemble_conditional.c deleted file mode 100644 index f3400e8753..0000000000 --- a/src/mesa/shader/slang/slang_assemble_conditional.c +++ /dev/null @@ -1,448 +0,0 @@ -/* - * Mesa 3-D graphics library - * Version: 6.5 - * - * Copyright (C) 2005-2006 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. - */ - -/** - * \file slang_assemble_conditional.c - * slang condtional expressions assembler - * \author Michal Krol - */ - -#include "imports.h" -#include "slang_assemble.h" -#include "slang_compile.h" - -/* - * _slang_assemble_logicaland() - * - * and: - * <left-expression> - * jumpz zero - * <right-expression> - * jump end - * zero: - * push 0 - * end: - */ - -GLboolean _slang_assemble_logicaland (slang_assemble_ctx *A, slang_operation *op) -{ - GLuint zero_jump, end_jump; - - /* evaluate left expression */ - if (!_slang_assemble_operation (A, &op->children[0], slang_ref_forbid)) - return GL_FALSE; - - /* jump to pushing 0 if not true */ - zero_jump = A->file->count; - if (!slang_assembly_file_push (A->file, slang_asm_jump_if_zero)) - return GL_FALSE; - - /* evaluate right expression */ - if (!_slang_assemble_operation (A, &op->children[1], slang_ref_forbid)) - return GL_FALSE; - - /* jump to the end of the expression */ - end_jump = A->file->count; - if (!slang_assembly_file_push (A->file, slang_asm_jump)) - return GL_FALSE; - - /* push 0 on stack */ - A->file->code[zero_jump].param[0] = A->file->count; - if (!slang_assembly_file_push_literal (A->file, slang_asm_bool_push, (GLfloat) 0)) - return GL_FALSE; - - /* the end of the expression */ - A->file->code[end_jump].param[0] = A->file->count; - - return GL_TRUE; -} - -/* - * _slang_assemble_logicalor() - * - * or: - * <left-expression> - * jumpz right - * push 1 - * jump end - * right: - * <right-expression> - * end: - */ - -GLboolean _slang_assemble_logicalor (slang_assemble_ctx *A, slang_operation *op) -{ - GLuint right_jump, end_jump; - - /* evaluate left expression */ - if (!_slang_assemble_operation (A, &op->children[0], slang_ref_forbid)) - return GL_FALSE; - - /* jump to evaluation of right expression if not true */ - right_jump = A->file->count; - if (!slang_assembly_file_push (A->file, slang_asm_jump_if_zero)) - return GL_FALSE; - - /* push 1 on stack */ - if (!slang_assembly_file_push_literal (A->file, slang_asm_bool_push, (GLfloat) 1)) - return GL_FALSE; - - /* jump to the end of the expression */ - end_jump = A->file->count; - if (!slang_assembly_file_push (A->file, slang_asm_jump)) - return GL_FALSE; - - /* evaluate right expression */ - A->file->code[right_jump].param[0] = A->file->count; - if (!_slang_assemble_operation (A, &op->children[1], slang_ref_forbid)) - return GL_FALSE; - - /* the end of the expression */ - A->file->code[end_jump].param[0] = A->file->count; - - return GL_TRUE; -} - -/* - * _slang_assemble_select() - * - * select: - * <condition-expression> - * jumpz false - * <true-expression> - * jump end - * false: - * <false-expression> - * end: - */ - -GLboolean _slang_assemble_select (slang_assemble_ctx *A, slang_operation *op) -{ - GLuint cond_jump, end_jump; - - /* execute condition expression */ - if (!_slang_assemble_operation (A, &op->children[0], slang_ref_forbid)) - return GL_FALSE; - - /* jump to false expression if not true */ - cond_jump = A->file->count; - if (!slang_assembly_file_push (A->file, slang_asm_jump_if_zero)) - return GL_FALSE; - - /* execute true expression */ - if (!_slang_assemble_operation (A, &op->children[1], slang_ref_forbid)) - return GL_FALSE; - - /* jump to the end of the expression */ - end_jump = A->file->count; - if (!slang_assembly_file_push (A->file, slang_asm_jump)) - return GL_FALSE; - - /* resolve false point */ - A->file->code[cond_jump].param[0] = A->file->count; - - /* execute false expression */ - if (!_slang_assemble_operation (A, &op->children[2], slang_ref_forbid)) - return GL_FALSE; - - /* resolve the end of the expression */ - A->file->code[end_jump].param[0] = A->file->count; - - return GL_TRUE; -} - -/* - * _slang_assemble_for() - * - * for: - * <init-statement> - * jump start - * break: - * jump end - * continue: - * <loop-increment> - * start: - * <condition-statement> - * jumpz end - * <loop-body> - * jump continue - * end: - */ - -GLboolean _slang_assemble_for (slang_assemble_ctx *A, slang_operation *op) -{ - GLuint start_jump, end_jump, cond_jump; - GLuint break_label, cont_label; - slang_assembly_flow_control save_flow = A->flow; - - /* execute initialization statement */ - if (!_slang_assemble_operation (A, &op->children[0], slang_ref_forbid/*slang_ref_freelance*/)) - return GL_FALSE; - if (!_slang_cleanup_stack (A, &op->children[0])) - return GL_FALSE; - - /* skip the "go to the end of the loop" and loop-increment statements */ - start_jump = A->file->count; - if (!slang_assembly_file_push (A->file, slang_asm_jump)) - return GL_FALSE; - - /* go to the end of the loop - break statements are directed here */ - break_label = A->file->count; - end_jump = A->file->count; - if (!slang_assembly_file_push (A->file, slang_asm_jump)) - return GL_FALSE; - - /* resolve the beginning of the loop - continue statements are directed here */ - cont_label = A->file->count; - - /* execute loop-increment statement */ - if (!_slang_assemble_operation (A, &op->children[2], slang_ref_forbid/*slang_ref_freelance*/)) - return GL_FALSE; - if (!_slang_cleanup_stack (A, &op->children[2])) - return GL_FALSE; - - /* resolve the condition point */ - A->file->code[start_jump].param[0] = A->file->count; - - /* execute condition statement */ - if (!_slang_assemble_operation (A, &op->children[1], slang_ref_forbid)) - return GL_FALSE; - - /* jump to the end of the loop if not true */ - cond_jump = A->file->count; - if (!slang_assembly_file_push (A->file, slang_asm_jump_if_zero)) - return GL_FALSE; - - /* execute loop body */ - A->flow.loop_start = cont_label; - A->flow.loop_end = break_label; - if (!_slang_assemble_operation (A, &op->children[3], slang_ref_forbid/*slang_ref_freelance*/)) - return GL_FALSE; - if (!_slang_cleanup_stack (A, &op->children[3])) - return GL_FALSE; - A->flow = save_flow; - - /* go to the beginning of the loop */ - if (!slang_assembly_file_push_label (A->file, slang_asm_jump, cont_label)) - return GL_FALSE; - - /* resolve the end of the loop */ - A->file->code[end_jump].param[0] = A->file->count; - A->file->code[cond_jump].param[0] = A->file->count; - - return GL_TRUE; -} - -/* - * _slang_assemble_do() - * - * do: - * jump start - * break: - * jump end - * continue: - * jump condition - * start: - * <loop-body> - * condition: - * <condition-statement> - * jumpz end - * jump start - * end: - */ - -GLboolean _slang_assemble_do (slang_assemble_ctx *A, slang_operation *op) -{ - GLuint skip_jump, end_jump, cont_jump, cond_jump; - GLuint break_label, cont_label; - slang_assembly_flow_control save_flow = A->flow; - - /* skip the "go to the end of the loop" and "go to condition" statements */ - skip_jump = A->file->count; - if (!slang_assembly_file_push (A->file, slang_asm_jump)) - return GL_FALSE; - - /* go to the end of the loop - break statements are directed here */ - break_label = A->file->count; - end_jump = A->file->count; - if (!slang_assembly_file_push (A->file, slang_asm_jump)) - return GL_FALSE; - - /* go to condition - continue statements are directed here */ - cont_label = A->file->count; - cont_jump = A->file->count; - if (!slang_assembly_file_push (A->file, slang_asm_jump)) - return GL_FALSE; - - /* resolve the beginning of the loop */ - A->file->code[skip_jump].param[0] = A->file->count; - - /* execute loop body */ - A->flow.loop_start = cont_label; - A->flow.loop_end = break_label; - if (!_slang_assemble_operation (A, &op->children[0], slang_ref_forbid/*slang_ref_freelance*/)) - return GL_FALSE; - if (!_slang_cleanup_stack (A, &op->children[0])) - return GL_FALSE; - A->flow = save_flow; - - /* resolve condition point */ - A->file->code[cont_jump].param[0] = A->file->count; - - /* execute condition statement */ - if (!_slang_assemble_operation (A, &op->children[1], slang_ref_forbid)) - return GL_FALSE; - - /* jump to the end of the loop if not true */ - cond_jump = A->file->count; - if (!slang_assembly_file_push (A->file, slang_asm_jump_if_zero)) - return GL_FALSE; - - /* jump to the beginning of the loop */ - if (!slang_assembly_file_push_label (A->file, slang_asm_jump, A->file->code[skip_jump].param[0])) - return GL_FALSE; - - /* resolve the end of the loop */ - A->file->code[end_jump].param[0] = A->file->count; - A->file->code[cond_jump].param[0] = A->file->count; - - return GL_TRUE; -} - -/* - * _slang_assemble_while() - * - * while: - * jump continue - * break: - * jump end - * continue: - * <condition-statement> - * jumpz end - * <loop-body> - * jump continue - * end: - */ - -GLboolean _slang_assemble_while (slang_assemble_ctx *A, slang_operation *op) -{ - GLuint skip_jump, end_jump, cond_jump; - GLuint break_label; - slang_assembly_flow_control save_flow = A->flow; - - /* skip the "go to the end of the loop" statement */ - skip_jump = A->file->count; - if (!slang_assembly_file_push (A->file, slang_asm_jump)) - return GL_FALSE; - - /* go to the end of the loop - break statements are directed here */ - break_label = A->file->count; - end_jump = A->file->count; - if (!slang_assembly_file_push (A->file, slang_asm_jump)) - return GL_FALSE; - - /* resolve the beginning of the loop - continue statements are directed here */ - A->file->code[skip_jump].param[0] = A->file->count; - - /* execute condition statement */ - if (!_slang_assemble_operation (A, &op->children[0], slang_ref_forbid)) - return GL_FALSE; - - /* jump to the end of the loop if not true */ - cond_jump = A->file->count; - if (!slang_assembly_file_push (A->file, slang_asm_jump_if_zero)) - return GL_FALSE; - - /* execute loop body */ - A->flow.loop_start = A->file->code[skip_jump].param[0]; - A->flow.loop_end = break_label; - if (!_slang_assemble_operation (A, &op->children[1], slang_ref_forbid/*slang_ref_freelance*/)) - return GL_FALSE; - if (!_slang_cleanup_stack (A, &op->children[1])) - return GL_FALSE; - A->flow = save_flow; - - /* jump to the beginning of the loop */ - if (!slang_assembly_file_push_label (A->file, slang_asm_jump, A->file->code[skip_jump].param[0])) - return GL_FALSE; - - /* resolve the end of the loop */ - A->file->code[end_jump].param[0] = A->file->count; - A->file->code[cond_jump].param[0] = A->file->count; - - return GL_TRUE; -} - -/* - * _slang_assemble_if() - * - * if: - * <condition-statement> - * jumpz else - * <true-statement> - * jump end - * else: - * <false-statement> - * end: - */ - -GLboolean _slang_assemble_if (slang_assemble_ctx *A, slang_operation *op) -{ - GLuint cond_jump, else_jump; - - /* execute condition statement */ - if (!_slang_assemble_operation (A, &op->children[0], slang_ref_forbid)) - return GL_FALSE; - - /* jump to false-statement if not true */ - cond_jump = A->file->count; - if (!slang_assembly_file_push (A->file, slang_asm_jump_if_zero)) - return GL_FALSE; - - /* execute true-statement */ - if (!_slang_assemble_operation (A, &op->children[1], slang_ref_forbid/*slang_ref_freelance*/)) - return GL_FALSE; - if (!_slang_cleanup_stack (A, &op->children[1])) - return GL_FALSE; - - /* skip if-false statement */ - else_jump = A->file->count; - if (!slang_assembly_file_push (A->file, slang_asm_jump)) - return GL_FALSE; - - /* resolve start of false-statement */ - A->file->code[cond_jump].param[0] = A->file->count; - - /* execute false-statement */ - if (!_slang_assemble_operation (A, &op->children[2], slang_ref_forbid/*slang_ref_freelance*/)) - return GL_FALSE; - if (!_slang_cleanup_stack (A, &op->children[2])) - return GL_FALSE; - - /* resolve end of if-false statement */ - A->file->code[else_jump].param[0] = A->file->count; - - return GL_TRUE; -} - diff --git a/src/mesa/shader/slang/slang_assemble_conditional.h b/src/mesa/shader/slang/slang_assemble_conditional.h deleted file mode 100644 index ce9e4de6c9..0000000000 --- a/src/mesa/shader/slang/slang_assemble_conditional.h +++ /dev/null @@ -1,51 +0,0 @@ -/* - * Mesa 3-D graphics library - * Version: 6.5 - * - * Copyright (C) 2005-2006 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. - */ - -#if !defined SLANG_ASSEMBLE_CONDITIONAL_H -#define SLANG_ASSEMBLE_CONDITIONAL_H - -#if defined __cplusplus -extern "C" { -#endif - -GLboolean _slang_assemble_logicaland (slang_assemble_ctx *, struct slang_operation_ *); - -GLboolean _slang_assemble_logicalor (slang_assemble_ctx *, struct slang_operation_ *); - -GLboolean _slang_assemble_select (slang_assemble_ctx *, struct slang_operation_ *); - -GLboolean _slang_assemble_for (slang_assemble_ctx *, struct slang_operation_ *); - -GLboolean _slang_assemble_do (slang_assemble_ctx *, struct slang_operation_ *); - -GLboolean _slang_assemble_while (slang_assemble_ctx *, struct slang_operation_ *); - -GLboolean _slang_assemble_if (slang_assemble_ctx *, struct slang_operation_ *); - -#ifdef __cplusplus -} -#endif - -#endif - diff --git a/src/mesa/shader/slang/slang_assemble_constructor.c b/src/mesa/shader/slang/slang_assemble_constructor.c deleted file mode 100644 index 6cd320d446..0000000000 --- a/src/mesa/shader/slang/slang_assemble_constructor.c +++ /dev/null @@ -1,401 +0,0 @@ -/* - * Mesa 3-D graphics library - * Version: 6.5.2 - * - * Copyright (C) 2005-2006 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. - */ - -/** - * \file slang_assemble_constructor.c - * slang constructor and vector swizzle assembler - * \author Michal Krol - */ - -#include "imports.h" -#include "slang_assemble.h" -#include "slang_storage.h" - - - -/** - * Checks if a field selector is a general swizzle (an r-value swizzle - * with replicated components or an l-value swizzle mask) for a - * vector. Returns GL_TRUE if this is the case, <swz> is filled with - * swizzle information. Returns GL_FALSE otherwise. - */ -GLboolean -_slang_is_swizzle(const char *field, GLuint rows, slang_swizzle * swz) -{ - GLuint i; - GLboolean xyzw = GL_FALSE, rgba = GL_FALSE, stpq = GL_FALSE; - - /* the swizzle can be at most 4-component long */ - swz->num_components = slang_string_length(field); - if (swz->num_components > 4) - return GL_FALSE; - - for (i = 0; i < swz->num_components; i++) { - /* mark which swizzle group is used */ - switch (field[i]) { - case 'x': - case 'y': - case 'z': - case 'w': - xyzw = GL_TRUE; - break; - case 'r': - case 'g': - case 'b': - case 'a': - rgba = GL_TRUE; - break; - case 's': - case 't': - case 'p': - case 'q': - stpq = GL_TRUE; - break; - default: - return GL_FALSE; - } - - /* collect swizzle component */ - switch (field[i]) { - case 'x': - case 'r': - case 's': - swz->swizzle[i] = 0; - break; - case 'y': - case 'g': - case 't': - swz->swizzle[i] = 1; - break; - case 'z': - case 'b': - case 'p': - swz->swizzle[i] = 2; - break; - case 'w': - case 'a': - case 'q': - swz->swizzle[i] = 3; - break; - } - - /* check if the component is valid for given vector's row count */ - if (rows <= swz->swizzle[i]) - return GL_FALSE; - } - - /* only one swizzle group can be used */ - if ((xyzw && rgba) || (xyzw && stpq) || (rgba && stpq)) - return GL_FALSE; - - return GL_TRUE; -} - - - -/** - * Checks if a general swizzle is an l-value swizzle - these swizzles - * do not have duplicated fields. Returns GL_TRUE if this is a - * swizzle mask. Returns GL_FALSE otherwise - */ -GLboolean -_slang_is_swizzle_mask(const slang_swizzle * swz, GLuint rows) -{ - GLuint i, c = 0; - - /* the swizzle may not be longer than the vector dim */ - if (swz->num_components > rows) - return GL_FALSE; - - /* the swizzle components cannot be duplicated */ - for (i = 0; i < swz->num_components; i++) { - if ((c & (1 << swz->swizzle[i])) != 0) - return GL_FALSE; - c |= 1 << swz->swizzle[i]; - } - - return GL_TRUE; -} - - - -/** - * Combines (multiplies) two swizzles to form single swizzle. - * Example: "vec.wzyx.yx" --> "vec.zw". - */ -GLvoid -_slang_multiply_swizzles(slang_swizzle * dst, const slang_swizzle * left, - const slang_swizzle * right) -{ - GLuint i; - - dst->num_components = right->num_components; - for (i = 0; i < right->num_components; i++) - dst->swizzle[i] = left->swizzle[right->swizzle[i]]; -} - - - -static GLboolean -sizeof_argument(slang_assemble_ctx * A, GLuint * size, slang_operation * op) -{ - slang_assembly_typeinfo ti; - GLboolean result = GL_FALSE; - slang_storage_aggregate agg; - - if (!slang_assembly_typeinfo_construct(&ti)) - return GL_FALSE; - if (!_slang_typeof_operation(A, op, &ti)) - goto end1; - - if (!slang_storage_aggregate_construct(&agg)) - goto end1; - if (!_slang_aggregate_variable(&agg, &ti.spec, 0, A->space.funcs, - A->space.structs, A->space.vars, - A->mach, A->file, A->atoms)) - goto end; - - *size = _slang_sizeof_aggregate(&agg); - result = GL_TRUE; - - end: - slang_storage_aggregate_destruct(&agg); - end1: - slang_assembly_typeinfo_destruct(&ti); - return result; -} - - -static GLboolean -constructor_aggregate(slang_assemble_ctx * A, - const slang_storage_aggregate * flat, - slang_operation * op, GLuint garbage_size) -{ - slang_assembly_typeinfo ti; - GLboolean result = GL_FALSE; - slang_storage_aggregate agg, flat_agg; - - if (!slang_assembly_typeinfo_construct(&ti)) - return GL_FALSE; - if (!_slang_typeof_operation(A, op, &ti)) - goto end1; - - if (!slang_storage_aggregate_construct(&agg)) - goto end1; - if (!_slang_aggregate_variable(&agg, &ti.spec, 0, A->space.funcs, - A->space.structs, A->space.vars, - A->mach, A->file, A->atoms)) - goto end2; - - if (!slang_storage_aggregate_construct(&flat_agg)) - goto end2; - if (!_slang_flatten_aggregate(&flat_agg, &agg)) - goto end; - - if (!_slang_assemble_operation(A, op, slang_ref_forbid)) - goto end; - - /* TODO: convert (generic) elements */ - - /* free the garbage */ - if (garbage_size != 0) { - GLuint i; - - /* move the non-garbage part to the end of the argument */ - if (!slang_assembly_file_push_label(A->file, slang_asm_addr_push, 0)) - goto end; - for (i = flat_agg.count * 4 - garbage_size; i > 0; i -= 4) { - if (!slang_assembly_file_push_label2(A->file, slang_asm_float_move, - garbage_size + i, i)) { - goto end; - } - } - if (!slang_assembly_file_push_label - (A->file, slang_asm_local_free, garbage_size + 4)) - goto end; - } - - result = GL_TRUE; - end: - slang_storage_aggregate_destruct(&flat_agg); - end2: - slang_storage_aggregate_destruct(&agg); - end1: - slang_assembly_typeinfo_destruct(&ti); - return result; -} - - -GLboolean -_slang_assemble_constructor(slang_assemble_ctx * A, const slang_operation * op) -{ - slang_assembly_typeinfo ti; - GLboolean result = GL_FALSE; - slang_storage_aggregate agg, flat; - GLuint size, i; - GLuint arg_sums[2]; - - /* get typeinfo of the constructor (the result of constructor expression) */ - if (!slang_assembly_typeinfo_construct(&ti)) - return GL_FALSE; - if (!_slang_typeof_operation(A, op, &ti)) - goto end1; - - /* create an aggregate of the constructor */ - if (!slang_storage_aggregate_construct(&agg)) - goto end1; - if (!_slang_aggregate_variable(&agg, &ti.spec, 0, A->space.funcs, - A->space.structs, A->space.vars, - A->mach, A->file, A->atoms)) - goto end2; - - /* calculate size of the constructor */ - size = _slang_sizeof_aggregate(&agg); - - /* flatten the constructor */ - if (!slang_storage_aggregate_construct(&flat)) - goto end2; - if (!_slang_flatten_aggregate(&flat, &agg)) - goto end; - - /* collect the last two constructor's argument size sums */ - arg_sums[0] = 0; /* will hold all but the last argument's size sum */ - arg_sums[1] = 0; /* will hold all argument's size sum */ - for (i = 0; i < op->num_children; i++) { - GLuint arg_size = 0; - - if (!sizeof_argument(A, &arg_size, &op->children[i])) - goto end; - if (i > 0) - arg_sums[0] = arg_sums[1]; - arg_sums[1] += arg_size; - } - - /* check if there are too many arguments */ - if (arg_sums[0] >= size) { - /* TODO: info log: too many arguments in constructor list */ - goto end; - } - - /* check if there are too few arguments */ - if (arg_sums[1] < size) { - /* TODO: info log: too few arguments in constructor list */ - goto end; - } - - /* traverse the children that form the constructor expression */ - for (i = op->num_children; i > 0; i--) { - GLuint garbage_size; - - /* the last argument may be too big - calculate the unnecessary - * data size - */ - if (i == op->num_children) - garbage_size = arg_sums[1] - size; - else - garbage_size = 0; - - if (!constructor_aggregate - (A, &flat, &op->children[i - 1], garbage_size)) - goto end; - } - - result = GL_TRUE; - end: - slang_storage_aggregate_destruct(&flat); - end2: - slang_storage_aggregate_destruct(&agg); - end1: - slang_assembly_typeinfo_destruct(&ti); - return result; -} - - - -GLboolean -_slang_assemble_constructor_from_swizzle(slang_assemble_ctx * A, - const slang_swizzle * swz, - const slang_type_specifier * spec, - const slang_type_specifier * master_spec) -{ - const GLuint master_rows = _slang_type_dim(master_spec->type); - GLuint i; - - for (i = 0; i < master_rows; i++) { - switch (_slang_type_base(master_spec->type)) { - case slang_spec_bool: - if (!slang_assembly_file_push_label2(A->file, slang_asm_bool_copy, - (master_rows - i) * 4, i * 4)) - return GL_FALSE; - break; - case slang_spec_int: - if (!slang_assembly_file_push_label2(A->file, slang_asm_int_copy, - (master_rows - i) * 4, i * 4)) - return GL_FALSE; - break; - case slang_spec_float: - if (!slang_assembly_file_push_label2(A->file, slang_asm_float_copy, - (master_rows - i) * 4, i * 4)) - return GL_FALSE; - break; - default: - break; - } - } - - if (!slang_assembly_file_push_label(A->file, slang_asm_local_free, 4)) - return GL_FALSE; - - for (i = swz->num_components; i > 0; i--) { - const GLuint n = i - 1; - - if (!slang_assembly_file_push_label2(A->file, slang_asm_local_addr, - A->local.swizzle_tmp, 16)) - return GL_FALSE; - if (!slang_assembly_file_push_label(A->file, slang_asm_addr_push, - swz->swizzle[n] * 4)) - return GL_FALSE; - if (!slang_assembly_file_push(A->file, slang_asm_addr_add)) - return GL_FALSE; - - switch (_slang_type_base(master_spec->type)) { - case slang_spec_bool: - if (!slang_assembly_file_push(A->file, slang_asm_bool_deref)) - return GL_FALSE; - break; - case slang_spec_int: - if (!slang_assembly_file_push(A->file, slang_asm_int_deref)) - return GL_FALSE; - break; - case slang_spec_float: - if (!slang_assembly_file_push(A->file, slang_asm_float_deref)) - return GL_FALSE; - break; - default: - break; - } - } - - return GL_TRUE; -} diff --git a/src/mesa/shader/slang/slang_assemble_constructor.h b/src/mesa/shader/slang/slang_assemble_constructor.h deleted file mode 100644 index c0deb91344..0000000000 --- a/src/mesa/shader/slang/slang_assemble_constructor.h +++ /dev/null @@ -1,57 +0,0 @@ -/* - * Mesa 3-D graphics library - * Version: 6.5.2 - * - * Copyright (C) 2005-2006 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 SLANG_ASSEMBLE_CONSTRUCTOR_H -#define SLANG_ASSEMBLE_CONSTRUCTOR_H - -#if defined __cplusplus -extern "C" { -#endif - - -extern GLboolean -_slang_is_swizzle(const char *field, GLuint rows, slang_swizzle *swz); - -extern GLboolean -_slang_is_swizzle_mask(const slang_swizzle *swz, GLuint rows); - -extern GLvoid -_slang_multiply_swizzles(slang_swizzle *, const slang_swizzle *, - const slang_swizzle *); - -extern GLboolean -_slang_assemble_constructor(slang_assemble_ctx *, - const struct slang_operation_ *); - -extern GLboolean -_slang_assemble_constructor_from_swizzle(slang_assemble_ctx *, - const slang_swizzle *, - const slang_type_specifier *, - const slang_type_specifier *); - -#ifdef __cplusplus -} -#endif - -#endif /* SLANG_ASSEMBLE_CONSTRUCTOR_H */ diff --git a/src/mesa/shader/slang/slang_assemble_typeinfo.c b/src/mesa/shader/slang/slang_assemble_typeinfo.c deleted file mode 100644 index 265e417dad..0000000000 --- a/src/mesa/shader/slang/slang_assemble_typeinfo.c +++ /dev/null @@ -1,625 +0,0 @@ -/* - * Mesa 3-D graphics library - * Version: 6.5 - * - * Copyright (C) 2005-2006 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. - */ - -/** - * \file slang_assemble_typeinfo.c - * slang type info - * \author Michal Krol - */ - -#include "imports.h" -#include "slang_assemble.h" -#include "slang_compile.h" - -/* - * slang_type_specifier - */ - -GLvoid -slang_type_specifier_ctr(slang_type_specifier * self) -{ - self->type = slang_spec_void; - self->_struct = NULL; - self->_array = NULL; -} - -GLvoid -slang_type_specifier_dtr(slang_type_specifier * self) -{ - if (self->_struct != NULL) { - slang_struct_destruct(self->_struct); - slang_alloc_free(self->_struct); - } - if (self->_array != NULL) { - slang_type_specifier_dtr(self->_array); - slang_alloc_free(self->_array); - } -} - -GLboolean -slang_type_specifier_copy(slang_type_specifier * x, - const slang_type_specifier * y) -{ - slang_type_specifier z; - - slang_type_specifier_ctr(&z); - z.type = y->type; - 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); - return GL_FALSE; - } - if (!slang_struct_construct(z._struct)) { - slang_alloc_free(z._struct); - slang_type_specifier_dtr(&z); - return GL_FALSE; - } - if (!slang_struct_copy(z._struct, y->_struct)) { - slang_type_specifier_dtr(&z); - return GL_FALSE; - } - } - else if (z.type == slang_spec_array) { - z._array = - (slang_type_specifier *) - slang_alloc_malloc(sizeof(slang_type_specifier)); - if (z._array == NULL) { - slang_type_specifier_dtr(&z); - return GL_FALSE; - } - slang_type_specifier_ctr(z._array); - if (!slang_type_specifier_copy(z._array, y->_array)) { - slang_type_specifier_dtr(&z); - return GL_FALSE; - } - } - slang_type_specifier_dtr(x); - *x = z; - return GL_TRUE; -} - -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 slang_struct_equal(x->_struct, y->_struct); - if (x->type == slang_spec_array) - return slang_type_specifier_equal(x->_array, y->_array); - return 1; -} - -/* slang_assembly_typeinfo */ - -GLboolean -slang_assembly_typeinfo_construct(slang_assembly_typeinfo * ti) -{ - slang_type_specifier_ctr(&ti->spec); - ti->array_len = 0; - return GL_TRUE; -} - -GLvoid -slang_assembly_typeinfo_destruct(slang_assembly_typeinfo * ti) -{ - slang_type_specifier_dtr(&ti->spec); -} - -/* _slang_typeof_operation() */ - -/** - * Determine the return type of a function. - * \param name name of the function - * \param params array of function parameters - * \param num_params number of parameters - * \param space namespace to use - * \param spec returns the function's type - * \param atoms atom pool - * \return GL_TRUE for success, GL_FALSE if failure - */ -static GLboolean -typeof_existing_function(const char *name, const slang_operation * params, - GLuint num_params, - const slang_assembly_name_space * space, - slang_type_specifier * spec, - slang_atom_pool * atoms) -{ - slang_atom atom; - GLboolean exists; - - atom = slang_atom_pool_atom(atoms, name); - if (!_slang_typeof_function(atom, params, num_params, space, spec, - &exists, atoms)) - return GL_FALSE; - return exists; -} - -GLboolean -_slang_typeof_operation(const slang_assemble_ctx * A, - const slang_operation * op, - slang_assembly_typeinfo * ti) -{ - return _slang_typeof_operation_(op, &A->space, ti, A->atoms); -} - - -/** - * Determine the return type of an operation. - * \param op the operation node - * \param space the namespace to use - * \param ti the returned type - * \param atoms atom pool - * \return GL_TRUE for success, GL_FALSE if failure - */ -GLboolean -_slang_typeof_operation_(const slang_operation * op, - const slang_assembly_name_space * space, - slang_assembly_typeinfo * ti, - slang_atom_pool * atoms) -{ - ti->can_be_referenced = GL_FALSE; - 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; - 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: - if (!_slang_typeof_operation_(op->children, space, ti, atoms)) - return 0; - break; - case slang_oper_literal_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: - ti->spec.type = slang_spec_int; - break; - case slang_oper_literal_float: - ti->spec.type = slang_spec_float; - break; - case slang_oper_identifier: - { - slang_variable *var; - - var = _slang_locate_variable(op->locals, op->a_id, GL_TRUE); - if (var == NULL) - return GL_FALSE; - if (!slang_type_specifier_copy(&ti->spec, &var->type.specifier)) - return GL_FALSE; - ti->can_be_referenced = GL_TRUE; - ti->array_len = var->array_len; - } - break; - case slang_oper_sequence: - /* TODO: check [0] and [1] if they match */ - if (!_slang_typeof_operation_(&op->children[1], space, ti, atoms)) - return GL_FALSE; - 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: - /* TODO: check [1] and [2] if they match */ - if (!_slang_typeof_operation_(&op->children[1], space, ti, atoms)) - return GL_FALSE; - 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: - if (!typeof_existing_function("+", op->children, 2, space, - &ti->spec, atoms)) - return GL_FALSE; - break; - case slang_oper_subtract: - if (!typeof_existing_function("-", op->children, 2, space, - &ti->spec, atoms)) - return GL_FALSE; - break; - case slang_oper_multiply: - if (!typeof_existing_function("*", op->children, 2, space, - &ti->spec, atoms)) - return GL_FALSE; - break; - case slang_oper_divide: - if (!typeof_existing_function("/", op->children, 2, space, - &ti->spec, atoms)) - return GL_FALSE; - break; - /*case slang_oper_modulus: */ - case slang_oper_plus: - if (!_slang_typeof_operation_(op->children, space, ti, atoms)) - return GL_FALSE; - ti->can_be_referenced = GL_FALSE; - ti->is_swizzled = GL_FALSE; - break; - case slang_oper_minus: - if (!typeof_existing_function - ("-", op->children, 1, space, &ti->spec, atoms)) - return GL_FALSE; - break; - /*case slang_oper_complement: */ - case slang_oper_subscript: - { - slang_assembly_typeinfo _ti; - - if (!slang_assembly_typeinfo_construct(&_ti)) - return GL_FALSE; - if (!_slang_typeof_operation_(op->children, space, &_ti, atoms)) { - slang_assembly_typeinfo_destruct(&_ti); - return GL_FALSE; - } - ti->can_be_referenced = _ti.can_be_referenced; - if (_ti.spec.type == slang_spec_array) { - if (!slang_type_specifier_copy(&ti->spec, _ti.spec._array)) { - slang_assembly_typeinfo_destruct(&_ti); - return GL_FALSE; - } - } - else { - if (!_slang_type_is_vector(_ti.spec.type) - && !_slang_type_is_matrix(_ti.spec.type)) { - slang_assembly_typeinfo_destruct(&_ti); - return GL_FALSE; - } - ti->spec.type = _slang_type_base(_ti.spec.type); - } - slang_assembly_typeinfo_destruct(&_ti); - } - break; - case slang_oper_call: - { - GLboolean exists; - - if (!_slang_typeof_function(op->a_id, op->children, op->num_children, - space, &ti->spec, &exists, atoms)) - return GL_FALSE; - if (!exists) { - 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._struct = - (slang_struct *) slang_alloc_malloc(sizeof(slang_struct)); - if (ti->spec._struct == NULL) - return GL_FALSE; - if (!slang_struct_construct(ti->spec._struct)) { - slang_alloc_free(ti->spec._struct); - ti->spec._struct = NULL; - return GL_FALSE; - } - if (!slang_struct_copy(ti->spec._struct, s)) - return GL_FALSE; - } - else { - const char *name; - slang_type_specifier_type type; - - name = slang_atom_pool_id(atoms, op->a_id); - type = slang_type_specifier_type_from_string(name); - if (type == slang_spec_void) - return GL_FALSE; - ti->spec.type = type; - } - } - } - break; - case slang_oper_field: - { - slang_assembly_typeinfo _ti; - - if (!slang_assembly_typeinfo_construct(&_ti)) - return GL_FALSE; - if (!_slang_typeof_operation_(op->children, space, &_ti, atoms)) { - slang_assembly_typeinfo_destruct(&_ti); - return GL_FALSE; - } - if (_ti.spec.type == slang_spec_struct) { - slang_variable *field; - - field = - _slang_locate_variable(_ti.spec._struct->fields, op->a_id, - GL_FALSE); - if (field == NULL) { - slang_assembly_typeinfo_destruct(&_ti); - return GL_FALSE; - } - if (!slang_type_specifier_copy(&ti->spec, &field->type.specifier)) { - slang_assembly_typeinfo_destruct(&_ti); - return GL_FALSE; - } - ti->can_be_referenced = _ti.can_be_referenced; - } - else { - GLuint rows; - const char *swizzle; - slang_type_specifier_type base; - - /* determine the swizzle of the field expression */ - if (!_slang_type_is_vector(_ti.spec.type)) { - slang_assembly_typeinfo_destruct(&_ti); - return GL_FALSE; - } - rows = _slang_type_dim(_ti.spec.type); - swizzle = slang_atom_pool_id(atoms, op->a_id); - if (!_slang_is_swizzle(swizzle, rows, &ti->swz)) { - slang_assembly_typeinfo_destruct(&_ti); - return GL_FALSE; - } - ti->is_swizzled = GL_TRUE; - ti->can_be_referenced = _ti.can_be_referenced - && _slang_is_swizzle_mask(&ti->swz, rows); - if (_ti.is_swizzled) { - slang_swizzle swz; - - /* swizzle the swizzle */ - _slang_multiply_swizzles(&swz, &_ti.swz, &ti->swz); - ti->swz = swz; - } - base = _slang_type_base(_ti.spec.type); - switch (ti->swz.num_components) { - case 1: - ti->spec.type = base; - break; - case 2: - switch (base) { - case slang_spec_float: - ti->spec.type = slang_spec_vec2; - break; - case slang_spec_int: - ti->spec.type = slang_spec_ivec2; - break; - case slang_spec_bool: - ti->spec.type = slang_spec_bvec2; - break; - default: - break; - } - break; - case 3: - switch (base) { - case slang_spec_float: - ti->spec.type = slang_spec_vec3; - break; - case slang_spec_int: - ti->spec.type = slang_spec_ivec3; - break; - case slang_spec_bool: - ti->spec.type = slang_spec_bvec3; - break; - default: - break; - } - break; - case 4: - switch (base) { - case slang_spec_float: - ti->spec.type = slang_spec_vec4; - break; - case slang_spec_int: - ti->spec.type = slang_spec_ivec4; - break; - case slang_spec_bool: - ti->spec.type = slang_spec_bvec4; - break; - default: - break; - } - break; - default: - break; - } - } - slang_assembly_typeinfo_destruct(&_ti); - } - break; - case slang_oper_postincrement: - case slang_oper_postdecrement: - if (!_slang_typeof_operation_(op->children, space, ti, atoms)) - return GL_FALSE; - ti->can_be_referenced = GL_FALSE; - ti->is_swizzled = GL_FALSE; - break; - default: - return GL_FALSE; - } - - return GL_TRUE; -} - - - -/** - * Determine the return type of a function. - * \param a_name the function name - * \param param function parameters (overloading) - * \param num_params number of parameters to function - * \param space namespace to search - * \param exists returns GL_TRUE or GL_FALSE to indicate existance of function - * \return GL_TRUE for success, GL_FALSE if failure (bad function name) - */ -GLboolean -_slang_typeof_function(slang_atom a_name, const slang_operation * params, - GLuint num_params, - const slang_assembly_name_space * space, - slang_type_specifier * spec, GLboolean * exists, - slang_atom_pool * atoms) -{ - slang_function *fun = _slang_locate_function(space->funcs, a_name, params, - num_params, space, atoms); - *exists = fun != NULL; - if (!fun) - return GL_TRUE; /* yes, not false */ - return slang_type_specifier_copy(spec, &fun->header.type.specifier); -} - - - -/** - * Determine if a type is a matrix. - * \return GL_TRUE if is a matrix, GL_FALSE otherwise. - */ -GLboolean -_slang_type_is_matrix(slang_type_specifier_type ty) -{ - switch (ty) { - case slang_spec_mat2: - case slang_spec_mat3: - case slang_spec_mat4: - return GL_TRUE; - default: - return GL_FALSE; - } -} - - -/** - * Determine if a type is a vector. - * \return GL_TRUE if is a vector, GL_FALSE otherwise. - */ -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: - return GL_TRUE; - default: - return GL_FALSE; - } -} - - -/** - * Given a vector type, return the type of the vector's elements - */ -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; - default: - return slang_spec_void; - } -} - - -/** - * Return the dimensionality of a vector or matrix type. - */ -GLuint -_slang_type_dim(slang_type_specifier_type ty) -{ - switch (ty) { - 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: - return 2; - 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: - return 4; - default: - return 0; - } -} diff --git a/src/mesa/shader/slang/slang_builtin.c b/src/mesa/shader/slang/slang_builtin.c new file mode 100644 index 0000000000..6ee0fd33b6 --- /dev/null +++ b/src/mesa/shader/slang/slang_builtin.c @@ -0,0 +1,440 @@ +/* + * Mesa 3-D graphics library + * Version: 6.5.3 + * + * Copyright (C) 2005-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. + */ + +/** + * \file slang_builtin.c + * Resolve built-in uniform vars. + * \author Brian Paul + */ + +#include "imports.h" +#include "slang_builtin.h" +#include "slang_ir.h" +#include "mtypes.h" +#include "program.h" +#include "prog_instruction.h" +#include "prog_parameter.h" +#include "prog_statevars.h" + + +/** + * Lookup GL state given a variable name, 0, 1 or 2 indexes and a field. + * Allocate room for the state in the given param list and return position + * in the list. + * Yes, this is kind of ugly, but it works. + */ +static GLint +lookup_statevar(const char *var, GLint index1, GLint index2, const char *field, + GLuint *swizzleOut, + struct gl_program_parameter_list *paramList) +{ + /* + * NOTE: The ARB_vertex_program extension specified that matrices get + * loaded in registers in row-major order. With GLSL, we want column- + * major order. So, we need to transpose all matrices here... + */ + static const struct { + const char *name; + gl_state_index matrix; + gl_state_index modifier; + } matrices[] = { + { "gl_ModelViewMatrix", STATE_MODELVIEW_MATRIX, STATE_MATRIX_TRANSPOSE }, + { "gl_ModelViewMatrixInverse", STATE_MODELVIEW_MATRIX, STATE_MATRIX_INVTRANS }, + { "gl_ModelViewMatrixTranspose", STATE_MODELVIEW_MATRIX, 0 }, + { "gl_ModelViewMatrixInverseTranspose", STATE_MODELVIEW_MATRIX, STATE_MATRIX_INVERSE }, + + { "gl_ProjectionMatrix", STATE_PROJECTION_MATRIX, STATE_MATRIX_TRANSPOSE }, + { "gl_ProjectionMatrixInverse", STATE_PROJECTION_MATRIX, STATE_MATRIX_INVTRANS }, + { "gl_ProjectionMatrixTranspose", STATE_PROJECTION_MATRIX, 0 }, + { "gl_ProjectionMatrixInverseTranspose", STATE_PROJECTION_MATRIX, STATE_MATRIX_INVERSE }, + + { "gl_ModelViewProjectionMatrix", STATE_MVP_MATRIX, STATE_MATRIX_TRANSPOSE }, + { "gl_ModelViewProjectionMatrixInverse", STATE_MVP_MATRIX, STATE_MATRIX_INVTRANS }, + { "gl_ModelViewProjectionMatrixTranspose", STATE_MVP_MATRIX, 0 }, + { "gl_ModelViewProjectionMatrixInverseTranspose", STATE_MVP_MATRIX, STATE_MATRIX_INVERSE }, + + { "gl_TextureMatrix", STATE_TEXTURE_MATRIX, STATE_MATRIX_TRANSPOSE }, + { "gl_TextureMatrixInverse", STATE_TEXTURE_MATRIX, STATE_MATRIX_INVTRANS }, + { "gl_TextureMatrixTranspose", STATE_TEXTURE_MATRIX, 0 }, + { "gl_TextureMatrixInverseTranspose", STATE_TEXTURE_MATRIX, STATE_MATRIX_INVERSE }, + + /* XXX verify these!!! */ + { "gl_NormalMatrix", STATE_MODELVIEW_MATRIX, STATE_MATRIX_TRANSPOSE }, + { "__NormalMatrixTranspose", STATE_MODELVIEW_MATRIX, 0 }, + + { NULL, 0, 0 } + }; + gl_state_index tokens[STATE_LENGTH]; + GLuint i; + GLboolean isMatrix = GL_FALSE; + + for (i = 0; i < STATE_LENGTH; i++) { + tokens[i] = 0; + } + *swizzleOut = SWIZZLE_NOOP; + + /* first, look if var is a pre-defined matrix */ + for (i = 0; matrices[i].name; i++) { + if (strcmp(var, matrices[i].name) == 0) { + tokens[0] = matrices[i].matrix; + /* tokens[1], [2] and [3] filled below */ + tokens[4] = matrices[i].modifier; + isMatrix = GL_TRUE; + break; + } + } + + if (isMatrix) { + if (tokens[0] == STATE_TEXTURE_MATRIX) { + if (index1 >= 0) { + tokens[1] = index1; + index1 = 0; /* prevent extra addition at end of function */ + } + } + } + else if (strcmp(var, "gl_DepthRange") == 0) { + tokens[0] = STATE_DEPTH_RANGE; + if (strcmp(field, "near") == 0) { + *swizzleOut = SWIZZLE_XXXX; + } + else if (strcmp(field, "far") == 0) { + *swizzleOut = SWIZZLE_YYYY; + } + else if (strcmp(field, "diff") == 0) { + *swizzleOut = SWIZZLE_ZZZZ; + } + else { + return -1; + } + } + else if (strcmp(var, "gl_ClipPlane") == 0) { + tokens[0] = STATE_CLIPPLANE; + tokens[1] = index1; + } + else if (strcmp(var, "gl_Point") == 0) { + if (strcmp(field, "size") == 0) { + tokens[0] = STATE_POINT_SIZE; + *swizzleOut = SWIZZLE_XXXX; + } + else if (strcmp(field, "sizeMin") == 0) { + tokens[0] = STATE_POINT_SIZE; + *swizzleOut = SWIZZLE_YYYY; + } + else if (strcmp(field, "sizeMax") == 0) { + tokens[0] = STATE_POINT_SIZE; + *swizzleOut = SWIZZLE_ZZZZ; + } + else if (strcmp(field, "fadeThresholdSize") == 0) { + tokens[0] = STATE_POINT_SIZE; + *swizzleOut = SWIZZLE_WWWW; + } + else if (strcmp(field, "distanceConstantAttenuation") == 0) { + tokens[0] = STATE_POINT_ATTENUATION; + *swizzleOut = SWIZZLE_XXXX; + } + else if (strcmp(field, "distanceLinearAttenuation") == 0) { + tokens[0] = STATE_POINT_ATTENUATION; + *swizzleOut = SWIZZLE_YYYY; + } + else if (strcmp(field, "distanceQuadraticAttenuation") == 0) { + tokens[0] = STATE_POINT_ATTENUATION; + *swizzleOut = SWIZZLE_ZZZZ; + } + else { + return -1; + } + } + else if (strcmp(var, "gl_FrontMaterial") == 0 || + strcmp(var, "gl_BackMaterial") == 0) { + tokens[0] = STATE_MATERIAL; + if (strcmp(var, "gl_FrontMaterial") == 0) + tokens[1] = 0; + else + tokens[1] = 1; + if (strcmp(field, "emission") == 0) { + tokens[2] = STATE_EMISSION; + } + else if (strcmp(field, "ambient") == 0) { + tokens[2] = STATE_AMBIENT; + } + else if (strcmp(field, "diffuse") == 0) { + tokens[2] = STATE_DIFFUSE; + } + else if (strcmp(field, "specular") == 0) { + tokens[2] = STATE_SPECULAR; + } + else if (strcmp(field, "shininess") == 0) { + tokens[2] = STATE_SHININESS; + *swizzleOut = SWIZZLE_XXXX; + } + else { + return -1; + } + } + else if (strcmp(var, "gl_LightSource") == 0) { + tokens[0] = STATE_LIGHT; + tokens[1] = index1; + if (strcmp(field, "ambient") == 0) { + tokens[2] = STATE_AMBIENT; + } + else if (strcmp(field, "diffuse") == 0) { + tokens[2] = STATE_DIFFUSE; + } + else if (strcmp(field, "specular") == 0) { + tokens[2] = STATE_SPECULAR; + } + else if (strcmp(field, "position") == 0) { + tokens[2] = STATE_POSITION; + } + else if (strcmp(field, "halfVector") == 0) { + tokens[2] = STATE_HALF_VECTOR; + } + else if (strcmp(field, "spotDirection") == 0) { + tokens[2] = STATE_SPOT_DIRECTION; + } + else if (strcmp(field, "spotCosCutoff") == 0) { + tokens[2] = STATE_SPOT_DIRECTION; + *swizzleOut = SWIZZLE_WWWW; + } + else if (strcmp(field, "spotCutoff") == 0) { + tokens[2] = STATE_SPOT_CUTOFF; + *swizzleOut = SWIZZLE_XXXX; + } + else if (strcmp(field, "spotExponent") == 0) { + tokens[2] = STATE_ATTENUATION; + *swizzleOut = SWIZZLE_WWWW; + } + else if (strcmp(field, "constantAttenuation") == 0) { + tokens[2] = STATE_ATTENUATION; + *swizzleOut = SWIZZLE_XXXX; + } + else if (strcmp(field, "linearAttenuation") == 0) { + tokens[2] = STATE_ATTENUATION; + *swizzleOut = SWIZZLE_YYYY; + } + else if (strcmp(field, "quadraticAttenuation") == 0) { + tokens[2] = STATE_ATTENUATION; + *swizzleOut = SWIZZLE_ZZZZ; + } + else { + return -1; + } + } + else if (strcmp(var, "gl_LightModel") == 0) { + if (strcmp(field, "ambient") == 0) { + tokens[0] = STATE_LIGHTMODEL_AMBIENT; + } + else { + return -1; + } + } + else if (strcmp(var, "gl_FrontLightModelProduct") == 0) { + if (strcmp(field, "ambient") == 0) { + tokens[0] = STATE_LIGHTMODEL_SCENECOLOR; + tokens[1] = 0; + } + else { + return -1; + } + } + else if (strcmp(var, "gl_BackLightModelProduct") == 0) { + if (strcmp(field, "ambient") == 0) { + tokens[0] = STATE_LIGHTMODEL_SCENECOLOR; + tokens[1] = 1; + } + else { + return -1; + } + } + else if (strcmp(var, "gl_FrontLightProduct") == 0 || + strcmp(var, "gl_BackLightProduct") == 0) { + tokens[0] = STATE_LIGHTPROD; + tokens[1] = index1; /* light number */ + if (strcmp(var, "gl_FrontLightProduct") == 0) { + tokens[2] = 0; /* front */ + } + else { + tokens[2] = 1; /* back */ + } + if (strcmp(field, "ambient") == 0) { + tokens[3] = STATE_AMBIENT; + } + else if (strcmp(field, "diffuse") == 0) { + tokens[3] = STATE_DIFFUSE; + } + else if (strcmp(field, "specular") == 0) { + tokens[3] = STATE_SPECULAR; + } + else { + return -1; + } + } + else if (strcmp(var, "gl_TextureEnvColor") == 0) { + tokens[0] = STATE_TEXENV_COLOR; + tokens[1] = index1; + } + else if (strcmp(var, "gl_EyePlaneS") == 0) { + tokens[0] = STATE_TEXGEN; + tokens[1] = index1; /* tex unit */ + tokens[2] = STATE_TEXGEN_EYE_S; + } + else if (strcmp(var, "gl_EyePlaneT") == 0) { + tokens[0] = STATE_TEXGEN; + tokens[1] = index1; /* tex unit */ + tokens[2] = STATE_TEXGEN_EYE_T; + } + else if (strcmp(var, "gl_EyePlaneR") == 0) { + tokens[0] = STATE_TEXGEN; + tokens[1] = index1; /* tex unit */ + tokens[2] = STATE_TEXGEN_EYE_R; + } + else if (strcmp(var, "gl_EyePlaneQ") == 0) { + tokens[0] = STATE_TEXGEN; + tokens[1] = index1; /* tex unit */ + tokens[2] = STATE_TEXGEN_EYE_Q; + } + else if (strcmp(var, "gl_ObjectPlaneS") == 0) { + tokens[0] = STATE_TEXGEN; + tokens[1] = index1; /* tex unit */ + tokens[2] = STATE_TEXGEN_OBJECT_S; + } + else if (strcmp(var, "gl_ObjectPlaneT") == 0) { + tokens[0] = STATE_TEXGEN; + tokens[1] = index1; /* tex unit */ + tokens[2] = STATE_TEXGEN_OBJECT_T; + } + else if (strcmp(var, "gl_ObjectPlaneR") == 0) { + tokens[0] = STATE_TEXGEN; + tokens[1] = index1; /* tex unit */ + tokens[2] = STATE_TEXGEN_OBJECT_R; + } + else if (strcmp(var, "gl_ObjectPlaneQ") == 0) { + tokens[0] = STATE_TEXGEN; + tokens[1] = index1; /* tex unit */ + tokens[2] = STATE_TEXGEN_OBJECT_Q; + } + else if (strcmp(var, "gl_Fog") == 0) { + if (strcmp(field, "color") == 0) { + tokens[0] = STATE_FOG_COLOR; + } + else if (strcmp(field, "density") == 0) { + tokens[0] = STATE_FOG_PARAMS; + *swizzleOut = SWIZZLE_XXXX; + } + else if (strcmp(field, "start") == 0) { + tokens[0] = STATE_FOG_PARAMS; + *swizzleOut = SWIZZLE_YYYY; + } + else if (strcmp(field, "end") == 0) { + tokens[0] = STATE_FOG_PARAMS; + *swizzleOut = SWIZZLE_ZZZZ; + } + else if (strcmp(field, "scale") == 0) { + tokens[0] = STATE_FOG_PARAMS; + *swizzleOut = SWIZZLE_WWWW; + } + else { + return -1; + } + } + else { + return -1; + } + + if (isMatrix) { + /* load all four columns of matrix */ + GLint pos[4]; + GLuint j; + for (j = 0; j < 4; j++) { + tokens[2] = tokens[3] = j; /* jth row of matrix */ + pos[j] = _mesa_add_state_reference(paramList, tokens); + assert(pos[j] >= 0); + ASSERT(pos[j] >= 0); + } + return pos[0] + index1; + } + else { + /* allocate a single register */ + GLint pos = _mesa_add_state_reference(paramList, tokens); + ASSERT(pos >= 0); + return pos; + } +} + + +/** + * Allocate storage for a pre-defined uniform (a GL state variable). + * As a memory-saving optimization, we try to only allocate storage for + * state vars that are actually used. + * For example, the "gl_LightSource" uniform is huge. If we only use + * a handful of gl_LightSource fields, we don't want to allocate storage + * for all of gl_LightSource. + * + * Currently, all pre-defined uniforms are in one of these forms: + * var + * var[i] + * var.field + * var[i].field + * var[i][j] + */ +GLint +_slang_alloc_statevar(slang_ir_node *n, + struct gl_program_parameter_list *paramList) +{ + slang_ir_node *n0 = n; + const char *field = NULL, *var; + GLint index1 = -1, index2 = -1, pos; + GLuint swizzle; + + if (n->Opcode == IR_FIELD) { + field = n->Field; + n = n->Children[0]; + } + + if (n->Opcode == IR_ELEMENT) { + /* XXX can only handle constant indexes for now */ + assert(n->Children[1]->Opcode == IR_FLOAT); + index1 = (GLint) n->Children[1]->Value[0]; + n = n->Children[0]; + } + + if (n->Opcode == IR_ELEMENT) { + /* XXX can only handle constant indexes for now */ + assert(n->Children[1]->Opcode == IR_FLOAT); + index2 = (GLint) n->Children[1]->Value[0]; + n = n->Children[0]; + } + + assert(n->Opcode == IR_VAR); + var = (char *) n->Var->a_name; + + pos = lookup_statevar(var, index1, index2, field, &swizzle, paramList); + assert(pos >= 0); + if (pos >= 0) { + n0->Store->Index = pos; + n0->Store->Swizzle = swizzle; + } + return pos; +} + diff --git a/src/mesa/shader/slang/slang_mesa.h b/src/mesa/shader/slang/slang_builtin.h index ca7af22d2a..ae20c844d5 100644 --- a/src/mesa/shader/slang/slang_mesa.h +++ b/src/mesa/shader/slang/slang_builtin.h @@ -1,8 +1,8 @@ /* * Mesa 3-D graphics library - * Version: 6.3 + * Version: 6.5.3 * - * Copyright (C) 2005 Brian Paul All Rights Reserved. + * Copyright (C) 2005-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"), @@ -22,15 +22,18 @@ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -#if defined __cplusplus -extern "C" { -#endif -int _mesa_isalnum (char); -int _glslang_3dlabs_InitProcess (); -int _glslang_3dlabs_ShInitialize (); +#ifndef SLANG_BUILTIN_H +#define SLANG_BUILTIN_H -#if defined __cplusplus -} -#endif +#include "prog_parameter.h" +#include "slang_utility.h" +#include "slang_ir.h" + +extern GLint +_slang_alloc_statevar(slang_ir_node *n, + struct gl_program_parameter_list *paramList); + + +#endif /* SLANG_BUILTIN_H */ diff --git a/src/mesa/shader/slang/slang_codegen.c b/src/mesa/shader/slang/slang_codegen.c new file mode 100644 index 0000000000..fa57ef8666 --- /dev/null +++ b/src/mesa/shader/slang/slang_codegen.c @@ -0,0 +1,2833 @@ +/* + * Mesa 3-D graphics library + * Version: 6.5.3 + * + * Copyright (C) 2005-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. + */ + +/** + * \file slang_codegen.c + * Generate IR tree from AST. + * \author Brian Paul + */ + + +/*** + *** NOTES: + *** The new_() functions return a new instance of a simple IR node. + *** The gen_() functions generate larger IR trees from the simple nodes. + ***/ + + + +#include "imports.h" +#include "macros.h" +#include "mtypes.h" +#include "program.h" +#include "prog_instruction.h" +#include "prog_parameter.h" +#include "prog_statevars.h" +#include "slang_typeinfo.h" +#include "slang_codegen.h" +#include "slang_compile.h" +#include "slang_label.h" +#include "slang_simplify.h" +#include "slang_emit.h" +#include "slang_vartable.h" +#include "slang_ir.h" +#include "slang_print.h" + + +static slang_ir_node * +_slang_gen_operation(slang_assemble_ctx * A, slang_operation *oper); + + +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_SAMPLER2DRECT: + case SLANG_SPEC_SAMPLER2DRECTSHADOW: + return GL_TRUE; + default: + return GL_FALSE; + } +} + + +/** + * Return the offset (in floats or ints) of the named field within + * the given struct. Return -1 if field not found. + * If field is NULL, return the size of the struct instead. + */ +static GLint +_slang_field_offset(const slang_type_specifier *spec, slang_atom field) +{ + GLint offset = 0; + GLuint i; + for (i = 0; i < spec->_struct->fields->num_variables; i++) { + const slang_variable *v = spec->_struct->fields->variables[i]; + const GLuint sz = _slang_sizeof_type_specifier(&v->type.specifier); + if (sz > 1) { + /* types larger than 1 float are register (4-float) aligned */ + offset = (offset + 3) & ~3; + } + if (field && v->a_name == field) { + return offset; + } + offset += sz; + } + if (field) + return -1; /* field not found */ + else + return offset; /* struct size */ +} + + +GLuint +_slang_sizeof_type_specifier(const slang_type_specifier *spec) +{ + switch (spec->type) { + case SLANG_SPEC_VOID: + return 0; + case SLANG_SPEC_BOOL: + return 1; + case SLANG_SPEC_BVEC2: + return 2; + case SLANG_SPEC_BVEC3: + return 3; + case SLANG_SPEC_BVEC4: + return 4; + case SLANG_SPEC_INT: + return 1; + case SLANG_SPEC_IVEC2: + return 2; + case SLANG_SPEC_IVEC3: + return 3; + case SLANG_SPEC_IVEC4: + return 4; + case SLANG_SPEC_FLOAT: + return 1; + case SLANG_SPEC_VEC2: + return 2; + case SLANG_SPEC_VEC3: + return 3; + case SLANG_SPEC_VEC4: + return 4; + case SLANG_SPEC_MAT2: + return 2 * 2; + case SLANG_SPEC_MAT3: + return 3 * 3; + 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_SAMPLER2DRECT: + case SLANG_SPEC_SAMPLER2DRECTSHADOW: + return 1; /* a sampler is basically just an integer index */ + case SLANG_SPEC_STRUCT: + return _slang_field_offset(spec, 0); /* special use */ + case SLANG_SPEC_ARRAY: + return _slang_sizeof_type_specifier(spec->_array); + default: + _mesa_problem(NULL, "Unexpected type in _slang_sizeof_type_specifier()"); + return 0; + } + return 0; +} + + +/** + * Establish the binding between a slang_ir_node and a slang_variable. + * Then, allocate/attach a slang_ir_storage object to the IR node if needed. + * The IR node must be a IR_VAR or IR_VAR_DECL node. + * \param n the IR node + * \param var the variable to associate with the IR node + */ +static void +_slang_attach_storage(slang_ir_node *n, slang_variable *var) +{ + assert(n); + assert(var); + assert(n->Opcode == IR_VAR || n->Opcode == IR_VAR_DECL); + assert(!n->Var || n->Var == var); + + n->Var = var; + + if (!n->Store) { + /* need to setup storage */ + if (n->Var && n->Var->aux) { + /* node storage info = var storage info */ + n->Store = (slang_ir_storage *) n->Var->aux; + } + else { + /* alloc new storage info */ + n->Store = _slang_new_ir_storage(PROGRAM_UNDEFINED, -1, -5); + if (n->Var) + n->Var->aux = n->Store; + assert(n->Var->aux); + } + } +} + + +/** + * Return the TEXTURE_*_INDEX value that corresponds to a sampler type, + * or -1 if the type is not a sampler. + */ +static GLint +sampler_to_texture_index(const slang_type_specifier_type type) +{ + switch (type) { + case SLANG_SPEC_SAMPLER1D: + return TEXTURE_1D_INDEX; + case SLANG_SPEC_SAMPLER2D: + return TEXTURE_2D_INDEX; + case SLANG_SPEC_SAMPLER3D: + return TEXTURE_3D_INDEX; + case SLANG_SPEC_SAMPLERCUBE: + return TEXTURE_CUBE_INDEX; + case SLANG_SPEC_SAMPLER1DSHADOW: + return TEXTURE_1D_INDEX; /* XXX fix */ + case SLANG_SPEC_SAMPLER2DSHADOW: + return TEXTURE_2D_INDEX; /* XXX fix */ + case SLANG_SPEC_SAMPLER2DRECT: + return TEXTURE_RECT_INDEX; + case SLANG_SPEC_SAMPLER2DRECTSHADOW: + return TEXTURE_RECT_INDEX; /* XXX fix */ + default: + return -1; + } +} + + +/** + * Return the VERT_ATTRIB_* or FRAG_ATTRIB_* value that corresponds to + * a vertex or fragment program input variable. Return -1 if the input + * name is invalid. + * XXX return size too + */ +static GLint +_slang_input_index(const char *name, GLenum target, GLuint *swizzleOut) +{ + struct input_info { + const char *Name; + GLuint Attrib; + GLuint Swizzle; + }; + static const struct input_info vertInputs[] = { + { "gl_Vertex", VERT_ATTRIB_POS, SWIZZLE_NOOP }, + { "gl_Normal", VERT_ATTRIB_NORMAL, SWIZZLE_NOOP }, + { "gl_Color", VERT_ATTRIB_COLOR0, SWIZZLE_NOOP }, + { "gl_SecondaryColor", VERT_ATTRIB_COLOR1, SWIZZLE_NOOP }, + { "gl_FogCoord", VERT_ATTRIB_FOG, SWIZZLE_XXXX }, + { "gl_MultiTexCoord0", VERT_ATTRIB_TEX0, SWIZZLE_NOOP }, + { "gl_MultiTexCoord1", VERT_ATTRIB_TEX1, SWIZZLE_NOOP }, + { "gl_MultiTexCoord2", VERT_ATTRIB_TEX2, SWIZZLE_NOOP }, + { "gl_MultiTexCoord3", VERT_ATTRIB_TEX3, SWIZZLE_NOOP }, + { "gl_MultiTexCoord4", VERT_ATTRIB_TEX4, SWIZZLE_NOOP }, + { "gl_MultiTexCoord5", VERT_ATTRIB_TEX5, SWIZZLE_NOOP }, + { "gl_MultiTexCoord6", VERT_ATTRIB_TEX6, SWIZZLE_NOOP }, + { "gl_MultiTexCoord7", VERT_ATTRIB_TEX7, SWIZZLE_NOOP }, + { NULL, 0, SWIZZLE_NOOP } + }; + static const struct input_info fragInputs[] = { + { "gl_FragCoord", FRAG_ATTRIB_WPOS, SWIZZLE_NOOP }, + { "gl_Color", FRAG_ATTRIB_COL0, SWIZZLE_NOOP }, + { "gl_SecondaryColor", FRAG_ATTRIB_COL1, SWIZZLE_NOOP }, + { "gl_FogFragCoord", FRAG_ATTRIB_FOGC, SWIZZLE_XXXX }, + { "gl_TexCoord", FRAG_ATTRIB_TEX0, SWIZZLE_NOOP }, + { "gl_FrontFacing", FRAG_ATTRIB_FOGC, SWIZZLE_YYYY }, /*XXX*/ + { NULL, 0, SWIZZLE_NOOP } + }; + GLuint i; + const struct input_info *inputs + = (target == GL_VERTEX_PROGRAM_ARB) ? vertInputs : fragInputs; + + ASSERT(MAX_TEXTURE_UNITS == 8); /* if this fails, fix vertInputs above */ + + for (i = 0; inputs[i].Name; i++) { + if (strcmp(inputs[i].Name, name) == 0) { + /* found */ + *swizzleOut = inputs[i].Swizzle; + return inputs[i].Attrib; + } + } + return -1; +} + + +/** + * Return the VERT_RESULT_* or FRAG_RESULT_* value that corresponds to + * a vertex or fragment program output variable. Return -1 for an invalid + * output name. + */ +static GLint +_slang_output_index(const char *name, GLenum target) +{ + struct output_info { + const char *Name; + GLuint Attrib; + }; + static const struct output_info vertOutputs[] = { + { "gl_Position", VERT_RESULT_HPOS }, + { "gl_FrontColor", VERT_RESULT_COL0 }, + { "gl_BackColor", VERT_RESULT_BFC0 }, + { "gl_FrontSecondaryColor", VERT_RESULT_COL1 }, + { "gl_BackSecondaryColor", VERT_RESULT_BFC1 }, + { "gl_TexCoord", VERT_RESULT_TEX0 }, + { "gl_FogFragCoord", VERT_RESULT_FOGC }, + { "gl_PointSize", VERT_RESULT_PSIZ }, + { NULL, 0 } + }; + static const struct output_info fragOutputs[] = { + { "gl_FragColor", FRAG_RESULT_COLR }, + { "gl_FragDepth", FRAG_RESULT_DEPR }, + { "gl_FragData", FRAG_RESULT_DATA0 }, + { NULL, 0 } + }; + GLuint i; + const struct output_info *outputs + = (target == GL_VERTEX_PROGRAM_ARB) ? vertOutputs : fragOutputs; + + for (i = 0; outputs[i].Name; i++) { + if (strcmp(outputs[i].Name, name) == 0) { + /* found */ + return outputs[i].Attrib; + } + } + return -1; +} + + + +/**********************************************************************/ + + +/** + * Map "_asm foo" to IR_FOO, etc. + */ +typedef struct +{ + const char *Name; + slang_ir_opcode Opcode; + GLuint HaveRetValue, NumParams; +} slang_asm_info; + + +static slang_asm_info AsmInfo[] = { + /* vec4 binary op */ + { "vec4_add", IR_ADD, 1, 2 }, + { "vec4_subtract", IR_SUB, 1, 2 }, + { "vec4_multiply", IR_MUL, 1, 2 }, + { "vec4_dot", IR_DOT4, 1, 2 }, + { "vec3_dot", IR_DOT3, 1, 2 }, + { "vec3_cross", IR_CROSS, 1, 2 }, + { "vec4_lrp", IR_LRP, 1, 3 }, + { "vec4_min", IR_MIN, 1, 2 }, + { "vec4_max", IR_MAX, 1, 2 }, + { "vec4_clamp", IR_CLAMP, 1, 3 }, + { "vec4_seq", IR_SEQUAL, 1, 2 }, + { "vec4_sne", IR_SNEQUAL, 1, 2 }, + { "vec4_sge", IR_SGE, 1, 2 }, + { "vec4_sgt", IR_SGT, 1, 2 }, + { "vec4_sle", IR_SLE, 1, 2 }, + { "vec4_slt", IR_SLT, 1, 2 }, + /* vec4 unary */ + { "vec4_floor", IR_FLOOR, 1, 1 }, + { "vec4_frac", IR_FRAC, 1, 1 }, + { "vec4_abs", IR_ABS, 1, 1 }, + { "vec4_negate", IR_NEG, 1, 1 }, + { "vec4_ddx", IR_DDX, 1, 1 }, + { "vec4_ddy", IR_DDY, 1, 1 }, + /* float binary op */ + { "float_power", IR_POW, 1, 2 }, + /* texture / sampler */ + { "vec4_tex1d", IR_TEX, 1, 2 }, + { "vec4_texb1d", IR_TEXB, 1, 2 }, /* 1d w/ bias */ + { "vec4_texp1d", IR_TEXP, 1, 2 }, /* 1d w/ projection */ + { "vec4_tex2d", IR_TEX, 1, 2 }, + { "vec4_texb2d", IR_TEXB, 1, 2 }, /* 2d w/ bias */ + { "vec4_texp2d", IR_TEXP, 1, 2 }, /* 2d w/ projection */ + { "vec4_tex3d", IR_TEX, 1, 2 }, + { "vec4_texb3d", IR_TEXB, 1, 2 }, /* 3d w/ bias */ + { "vec4_texp3d", IR_TEXP, 1, 2 }, /* 3d w/ projection */ + { "vec4_texcube", IR_TEX, 1, 2 }, /* cubemap */ + { "vec4_tex_rect", IR_TEX, 1, 2 }, /* rectangle */ + { "vec4_texp_rect", IR_TEX, 1, 2 },/* rectangle w/ projection */ + + /* unary op */ + { "int_to_float", IR_I_TO_F, 1, 1 }, + { "float_to_int", IR_F_TO_I, 1, 1 }, + { "float_exp", IR_EXP, 1, 1 }, + { "float_exp2", IR_EXP2, 1, 1 }, + { "float_log2", IR_LOG2, 1, 1 }, + { "float_rsq", IR_RSQ, 1, 1 }, + { "float_rcp", IR_RCP, 1, 1 }, + { "float_sine", IR_SIN, 1, 1 }, + { "float_cosine", IR_COS, 1, 1 }, + { "float_noise1", IR_NOISE1, 1, 1}, + { "float_noise2", IR_NOISE2, 1, 1}, + { "float_noise3", IR_NOISE3, 1, 1}, + { "float_noise4", IR_NOISE4, 1, 1}, + + { NULL, IR_NOP, 0, 0 } +}; + + +static slang_ir_node * +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] = c0; + n->Children[1] = c1; + n->Children[2] = c2; + n->Writemask = WRITEMASK_XYZW; + n->InstLocation = -1; + } + return n; +} + +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) +{ + if (!left) + return right; + if (!right) + return left; + return new_node2(IR_SEQ, left, right); +} + +static slang_ir_node * +new_label(slang_label *label) +{ + slang_ir_node *n = new_node0(IR_LABEL); + assert(label); + if (n) + n->Label = label; + return n; +} + +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_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); + return n; +} + +/** + * Unconditional jump. + */ +static slang_ir_node * +new_jump(slang_label *dest) +{ + slang_ir_node *n = new_node0(IR_JUMP); + assert(dest); + if (n) + n->Label = dest; + return n; +} + + +static slang_ir_node * +new_loop(slang_ir_node *body) +{ + return new_node1(IR_LOOP, body); +} + + +static slang_ir_node * +new_break(slang_ir_node *loopNode) +{ + slang_ir_node *n = new_node0(IR_BREAK); + assert(loopNode); + assert(loopNode->Opcode == IR_LOOP); + if (n) { + /* insert this node at head of linked list */ + n->List = loopNode->List; + loopNode->List = n; + } + return n; +} + + +/** + * Make new IR_BREAK_IF_TRUE or IR_BREAK_IF_FALSE node. + */ +static slang_ir_node * +new_break_if(slang_ir_node *loopNode, slang_ir_node *cond, GLboolean breakTrue) +{ + 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) { + /* insert this node at head of linked list */ + n->List = loopNode->List; + loopNode->List = n; + } + return n; +} + + +/** + * Make new IR_CONT_IF_TRUE or IR_CONT_IF_FALSE node. + */ +static slang_ir_node * +new_cont_if(slang_ir_node *loopNode, slang_ir_node *cond, GLboolean contTrue) +{ + 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) { + /* insert this node at head of linked list */ + n->List = loopNode->List; + loopNode->List = n; + } + return n; +} + + +static slang_ir_node * +new_cond(slang_ir_node *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); +} + + +/** + * New IR_VAR node - a reference to a previously declared variable. + */ +static slang_ir_node * +new_var(slang_assemble_ctx *A, slang_operation *oper, slang_atom name) +{ + slang_ir_node *n; + slang_variable *var = _slang_locate_variable(oper->locals, name, GL_TRUE); + if (!var) + return NULL; + + assert(!oper->var || oper->var == var); + + n = new_node0(IR_VAR); + if (n) { + _slang_attach_storage(n, var); + } + return n; +} + + +/** + * Check if the given function is really just a wrapper for a + * basic assembly instruction. + */ +static GLboolean +slang_is_asm_function(const slang_function *fun) +{ + if (fun->body->type == SLANG_OPER_BLOCK_NO_NEW_SCOPE && + fun->body->num_children == 1 && + fun->body->children[0].type == SLANG_OPER_ASM) { + return GL_TRUE; + } + return GL_FALSE; +} + + +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)) + return GL_TRUE; + else + return GL_FALSE; +} + + +/** + * Produce inline code for a call to an assembly instruction. + * XXX Note: children are passed as asm args in-order, not by name! + */ +static slang_operation * +slang_inline_asm_function(slang_assemble_ctx *A, + slang_function *fun, slang_operation *oper) +{ + const GLuint numArgs = oper->num_children; + const slang_operation *args = oper->children; + GLuint i; + slang_operation *inlined = slang_operation_new(1); + + /*assert(oper->type == SLANG_OPER_CALL); or vec4_add, etc */ + /* + printf("Inline asm %s\n", (char*) fun->header.a_name); + */ + inlined->type = fun->body->children[0].type; + inlined->a_id = fun->body->children[0].a_id; + inlined->num_children = numArgs; + inlined->children = slang_operation_new(numArgs); + inlined->locals->outer_scope = oper->locals->outer_scope; + + for (i = 0; i < numArgs; i++) { + slang_operation_copy(inlined->children + i, args + i); + } + + return inlined; +} + + +static void +slang_resolve_variable(slang_operation *oper) +{ + if (oper->type == SLANG_OPER_IDENTIFIER && !oper->var) { + oper->var = _slang_locate_variable(oper->locals, oper->a_id, GL_TRUE); + } +} + + +/** + * Replace particular variables (SLANG_OPER_IDENTIFIER) with new expressions. + */ +static void +slang_substitute(slang_assemble_ctx *A, slang_operation *oper, + GLuint substCount, slang_variable **substOld, + slang_operation **substNew, GLboolean isLHS) +{ + switch (oper->type) { + case SLANG_OPER_VARIABLE_DECL: + { + slang_variable *v = _slang_locate_variable(oper->locals, + oper->a_id, GL_TRUE); + assert(v); + if (v->initializer && oper->num_children == 0) { + /* set child of oper to copy of initializer */ + oper->num_children = 1; + oper->children = slang_operation_new(1); + slang_operation_copy(&oper->children[0], v->initializer); + } + if (oper->num_children == 1) { + /* the initializer */ + slang_substitute(A, &oper->children[0], substCount, + substOld, substNew, GL_FALSE); + } + } + break; + case SLANG_OPER_IDENTIFIER: + assert(oper->num_children == 0); + if (1/**!isLHS XXX FIX */) { + slang_atom id = oper->a_id; + slang_variable *v; + GLuint i; + v = _slang_locate_variable(oper->locals, id, GL_TRUE); + if (!v) { + printf("var %s not found!\n", (char *) oper->a_id); + _slang_print_var_scope(oper->locals, 6); + + abort(); + break; + } + + /* look for a substitution */ + for (i = 0; i < substCount; i++) { + if (v == substOld[i]) { + /* OK, replace this SLANG_OPER_IDENTIFIER with a new expr */ +#if 0 /* DEBUG only */ + 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", + (char*)v->a_name, (char*) substNew[i]->var->a_name, + (void*) oper); + } + else { + printf("Substitute %s with %f in id node %p\n", + (char*)v->a_name, substNew[i]->literal[0], + (void*) oper); + } +#endif + slang_operation_copy(oper, substNew[i]); + break; + } + } + } + break; + + case SLANG_OPER_RETURN: + /* do return replacement here too */ + assert(oper->num_children == 0 || oper->num_children == 1); + if (!_slang_is_noop(oper)) { + /* replace: + * return expr; + * with: + * __retVal = expr; + * return; + * then do substitutions on the assignment. + */ + slang_operation *blockOper, *assignOper, *returnOper; + blockOper = slang_operation_new(1); + blockOper->type = SLANG_OPER_BLOCK_NO_NEW_SCOPE; + blockOper->num_children = 2; + blockOper->locals->outer_scope = oper->locals->outer_scope; + blockOper->children = slang_operation_new(2); + assignOper = blockOper->children + 0; + returnOper = blockOper->children + 1; + + assignOper->type = SLANG_OPER_ASSIGN; + assignOper->num_children = 2; + assignOper->locals->outer_scope = blockOper->locals; + assignOper->children = slang_operation_new(2); + 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 = assignOper->locals; + + slang_operation_copy(&assignOper->children[1], + &oper->children[0]); + + returnOper->type = SLANG_OPER_RETURN; + assert(returnOper->num_children == 0); + + /* do substitutions on the "__retVal = expr" sub-tree */ + slang_substitute(A, assignOper, + substCount, substOld, substNew, GL_FALSE); + + /* install new code */ + slang_operation_copy(oper, blockOper); + slang_operation_destruct(blockOper); + } + break; + + case SLANG_OPER_ASSIGN: + case SLANG_OPER_SUBSCRIPT: + /* special case: + * child[0] can't have substitutions but child[1] can. + */ + slang_substitute(A, &oper->children[0], + substCount, substOld, substNew, GL_TRUE); + slang_substitute(A, &oper->children[1], + substCount, substOld, substNew, GL_FALSE); + break; + case SLANG_OPER_FIELD: + /* XXX NEW - test */ + slang_substitute(A, &oper->children[0], + substCount, substOld, substNew, GL_TRUE); + break; + default: + { + GLuint i; + for (i = 0; i < oper->num_children; i++) + slang_substitute(A, &oper->children[i], + substCount, substOld, substNew, GL_FALSE); + } + } +} + + + +/** + * Inline the given function call operation. + * Return a new slang_operation that corresponds to the inlined code. + */ +static slang_operation * +slang_inline_function_call(slang_assemble_ctx * A, slang_function *fun, + slang_operation *oper, slang_operation *returnOper) +{ + typedef enum { + SUBST = 1, + COPY_IN, + COPY_OUT + } ParamMode; + ParamMode *paramMode; + const GLboolean haveRetValue = _slang_function_has_return_value(fun); + const GLuint numArgs = oper->num_children; + const GLuint totalArgs = numArgs + haveRetValue; + slang_operation *args = oper->children; + slang_operation *inlined, *top; + slang_variable **substOld; + slang_operation **substNew; + GLuint substCount, numCopyIn, i; + + /*assert(oper->type == SLANG_OPER_CALL); (or (matrix) multiply, etc) */ + assert(fun->param_count == totalArgs); + + /* allocate temporary arrays */ + paramMode = (ParamMode *) + _mesa_calloc(totalArgs * sizeof(ParamMode)); + substOld = (slang_variable **) + _mesa_calloc(totalArgs * sizeof(slang_variable *)); + substNew = (slang_operation **) + _mesa_calloc(totalArgs * sizeof(slang_operation *)); + +#if 0 + printf("Inline call to %s (total vars=%d nparams=%d)\n", + (char *) fun->header.a_name, + fun->parameters->num_variables, numArgs); +#endif + + if (haveRetValue && !returnOper) { + /* Create 3-child comma sequence for inlined code: + * child[0]: declare __resultTmp + * child[1]: inlined function body + * child[2]: __resultTmp + */ + slang_operation *commaSeq; + slang_operation *declOper = NULL; + slang_variable *resultVar; + + commaSeq = slang_operation_new(1); + commaSeq->type = SLANG_OPER_SEQUENCE; + assert(commaSeq->locals); + commaSeq->locals->outer_scope = oper->locals->outer_scope; + commaSeq->num_children = 3; + commaSeq->children = slang_operation_new(3); + /* allocate the return var */ + resultVar = slang_variable_scope_grow(commaSeq->locals); + /* + printf("Alloc __resultTmp in scope %p for retval of calling %s\n", + (void*)commaSeq->locals, (char *) fun->header.a_name); + */ + + resultVar->a_name = slang_atom_pool_atom(A->atoms, "__resultTmp"); + resultVar->type = fun->header.type; /* XXX copy? */ + resultVar->isTemp = GL_TRUE; + + /* child[0] = __resultTmp declaration */ + declOper = &commaSeq->children[0]; + declOper->type = SLANG_OPER_VARIABLE_DECL; + declOper->a_id = resultVar->a_name; + declOper->locals->outer_scope = commaSeq->locals; + + /* child[1] = function body */ + inlined = &commaSeq->children[1]; + inlined->locals->outer_scope = commaSeq->locals; + + /* child[2] = __resultTmp reference */ + returnOper = &commaSeq->children[2]; + returnOper->type = SLANG_OPER_IDENTIFIER; + returnOper->a_id = resultVar->a_name; + returnOper->locals->outer_scope = commaSeq->locals; + + top = commaSeq; + } + else { + top = inlined = slang_operation_new(1); + /* XXXX this may be inappropriate!!!! */ + inlined->locals->outer_scope = oper->locals->outer_scope; + } + + + assert(inlined->locals); + + /* Examine the parameters, look for inout/out params, look for possible + * substitutions, etc: + * param type behaviour + * in copy actual to local + * const in substitute param with actual + * out copy out + */ + substCount = 0; + for (i = 0; i < totalArgs; i++) { + slang_variable *p = fun->parameters->variables[i]; + /* + printf("Param %d: %s %s \n", i, + slang_type_qual_string(p->type.qualifier), + (char *) p->a_name); + */ + if (p->type.qualifier == SLANG_QUAL_INOUT || + p->type.qualifier == SLANG_QUAL_OUT) { + /* an output param */ + slang_operation *arg; + if (i < numArgs) + arg = &args[i]; + else + arg = returnOper; + paramMode[i] = SUBST; + + if (arg->type == SLANG_OPER_IDENTIFIER) + slang_resolve_variable(arg); + + /* replace parameter 'p' with argument 'arg' */ + substOld[substCount] = p; + substNew[substCount] = arg; /* will get copied */ + substCount++; + } + 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) { + /* replace all occurances of this parameter variable with the + * actual argument variable or a literal. + */ + paramMode[i] = SUBST; + slang_resolve_variable(&args[i]); + substOld[substCount] = p; + substNew[substCount] = &args[i]; /* will get copied */ + substCount++; + } + else { + paramMode[i] = COPY_IN; + } + } + else { + paramMode[i] = COPY_IN; + } + assert(paramMode[i]); + } + + /* actual code inlining: */ + 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; + +#if 0 + printf("======================= orig body code ======================\n"); + printf("=== params scope = %p\n", (void*) fun->parameters); + slang_print_tree(fun->body, 8); + printf("======================= copied code =========================\n"); + slang_print_tree(inlined, 8); +#endif + + /* do parameter substitution in inlined code: */ + slang_substitute(A, inlined, substCount, substOld, substNew, GL_FALSE); + +#if 0 + printf("======================= subst code ==========================\n"); + slang_print_tree(inlined, 8); + printf("=============================================================\n"); +#endif + + /* New prolog statements: (inserted before the inlined code) + * Copy the 'in' arguments. + */ + numCopyIn = 0; + for (i = 0; i < numArgs; i++) { + if (paramMode[i] == COPY_IN) { + slang_variable *p = fun->parameters->variables[i]; + /* declare parameter 'p' */ + slang_operation *decl = slang_operation_insert(&inlined->num_children, + &inlined->children, + numCopyIn); + /* + printf("COPY_IN %s from expr\n", (char*)p->a_name); + */ + decl->type = SLANG_OPER_VARIABLE_DECL; + assert(decl->locals); + decl->locals->outer_scope = inlined->locals; + decl->a_id = p->a_name; + decl->num_children = 1; + decl->children = slang_operation_new(1); + + /* child[0] is the var's initializer */ + slang_operation_copy(&decl->children[0], args + i); + + numCopyIn++; + } + } + + /* New epilog statements: + * 1. Create end of function label to jump to from return statements. + * 2. Copy the 'out' parameter vars + */ + { + slang_operation *lab = slang_operation_insert(&inlined->num_children, + &inlined->children, + inlined->num_children); + lab->type = SLANG_OPER_LABEL; + lab->label = A->curFuncEndLabel; + } + + for (i = 0; i < totalArgs; i++) { + if (paramMode[i] == COPY_OUT) { + const slang_variable *p = fun->parameters->variables[i]; + /* actualCallVar = outParam */ + /*if (i > 0 || !haveRetValue)*/ + slang_operation *ass = slang_operation_insert(&inlined->num_children, + &inlined->children, + inlined->num_children); + ass->type = SLANG_OPER_ASSIGN; + ass->num_children = 2; + ass->locals->outer_scope = inlined->locals; + ass->children = slang_operation_new(2); + ass->children[0] = args[i]; /*XXX copy */ + ass->children[1].type = SLANG_OPER_IDENTIFIER; + ass->children[1].a_id = p->a_name; + ass->children[1].locals->outer_scope = ass->locals; + } + } + + _mesa_free(paramMode); + _mesa_free(substOld); + _mesa_free(substNew); + +#if 0 + printf("Done Inline call to %s (total vars=%d nparams=%d)\n", + (char *) fun->header.a_name, + fun->parameters->num_variables, numArgs); + slang_print_tree(top, 0); +#endif + return top; +} + + +static slang_ir_node * +_slang_gen_function_call(slang_assemble_ctx *A, slang_function *fun, + slang_operation *oper, slang_operation *dest) +{ + slang_ir_node *n; + slang_operation *inlined; + slang_label *prevFuncEndLabel; + char name[200]; + + prevFuncEndLabel = A->curFuncEndLabel; + sprintf(name, "__endOfFunc_%s_", (char *) fun->header.a_name); + A->curFuncEndLabel = _slang_label_new(name); + assert(A->curFuncEndLabel); + + if (slang_is_asm_function(fun) && !dest) { + /* assemble assembly function - tree style */ + inlined = slang_inline_asm_function(A, fun, oper); + } + else { + /* non-assembly function */ + inlined = slang_inline_function_call(A, fun, oper, dest); + } + + /* Replace the function call with the inlined block */ + slang_operation_destruct(oper); + *oper = *inlined; + /* XXX slang_operation_destruct(inlined) ??? */ + +#if 0 + assert(inlined->locals); + printf("*** Inlined code for call to %s:\n", + (char*) fun->header.a_name); + slang_print_tree(oper, 10); + printf("\n"); +#endif + + n = _slang_gen_operation(A, oper); + + /*_slang_label_delete(A->curFuncEndLabel);*/ + A->curFuncEndLabel = prevFuncEndLabel; + assert(A->curFuncEndLabel); + + return n; +} + + +static slang_asm_info * +slang_find_asm_info(const char *name) +{ + GLuint i; + for (i = 0; AsmInfo[i].Name; i++) { + if (_mesa_strcmp(AsmInfo[i].Name, name) == 0) { + return AsmInfo + i; + } + } + return NULL; +} + + +static GLuint +make_writemask(const char *field) +{ + GLuint mask = 0x0; + while (*field) { + switch (*field) { + case 'x': + mask |= WRITEMASK_X; + break; + case 'y': + mask |= WRITEMASK_Y; + break; + case 'z': + mask |= WRITEMASK_Z; + break; + case 'w': + mask |= WRITEMASK_W; + break; + default: + abort(); + } + field++; + } + if (mask == 0x0) + return WRITEMASK_XYZW; + else + return mask; +} + + +/** + * Generate IR tree for an asm instruction/operation such as: + * __asm vec4_dot __retVal.x, v1, v2; + */ +static slang_ir_node * +_slang_gen_asm(slang_assemble_ctx *A, slang_operation *oper, + slang_operation *dest) +{ + const slang_asm_info *info; + slang_ir_node *kids[3], *n; + GLuint j, firstOperand; + + assert(oper->type == SLANG_OPER_ASM); + + info = slang_find_asm_info((char *) oper->a_id); + if (!info) { + _mesa_problem(NULL, "undefined __asm function %s\n", + (char *) oper->a_id); + assert(info); + } + assert(info->NumParams <= 3); + + if (info->NumParams == oper->num_children) { + /* Storage for result is not specified. + * Children[0], [1] are the operands. + */ + firstOperand = 0; + } + else { + /* Storage for result (child[0]) is specified. + * Children[1], [2] are the operands. + */ + firstOperand = 1; + } + + /* assemble child(ren) */ + kids[0] = kids[1] = kids[2] = NULL; + for (j = 0; j < info->NumParams; j++) { + kids[j] = _slang_gen_operation(A, &oper->children[firstOperand + j]); + if (!kids[j]) + return NULL; + } + + n = new_node3(info->Opcode, kids[0], kids[1], kids[2]); + + if (firstOperand) { + /* Setup n->Store to be a particular location. Otherwise, storage + * for the result (a temporary) will be allocated later. + */ + GLuint writemask = WRITEMASK_XYZW; + slang_operation *dest_oper; + slang_ir_node *n0; + + dest_oper = &oper->children[0]; + while (dest_oper->type == SLANG_OPER_FIELD) { + /* writemask */ + writemask &= make_writemask((char*) dest_oper->a_id); + dest_oper = &dest_oper->children[0]; + } + + n0 = _slang_gen_operation(A, dest_oper); + assert(n0->Var); + assert(n0->Store); + assert(!n->Store); + n->Store = n0->Store; + n->Writemask = writemask; + + free(n0); + } + + return n; +} + + +static void +print_funcs(struct slang_function_scope_ *scope, const char *name) +{ + GLuint i; + for (i = 0; i < scope->num_functions; i++) { + slang_function *f = &scope->functions[i]; + if (!name || strcmp(name, (char*) f->header.a_name) == 0) + printf(" %s (%d args)\n", name, f->param_count); + + } + if (scope->outer_scope) + print_funcs(scope->outer_scope, 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) +{ + GLuint i; + for (i = 0; i < scope->num_functions; i++) { + slang_function *f = &scope->functions[i]; + if (strcmp(name, (char*) f->header.a_name) == 0) + return f; + } + if (scope->outer_scope) + return _slang_first_function(scope->outer_scope, name); + return NULL; +} + + + +/** + * Assemble a function call, given a particular function name. + * \param name the function's name (operators like '*' are possible). + */ +static slang_ir_node * +_slang_gen_function_call_name(slang_assemble_ctx *A, const char *name, + slang_operation *oper, slang_operation *dest) +{ + slang_operation *params = oper->children; + const GLuint param_count = oper->num_children; + slang_atom atom; + slang_function *fun; + + atom = slang_atom_pool_atom(A->atoms, name); + if (atom == SLANG_ATOM_NULL) + return NULL; + + /* + * Use 'name' to find the function to call + */ + fun = _slang_locate_function(A->space.funcs, atom, params, param_count, + &A->space, A->atoms, A->log); + if (!fun) { + /* A function with exactly the right parameters/types was not found. + * Try adapting the parameters. + */ + fun = _slang_first_function(A->space.funcs, name); + if (!_slang_adapt_call(oper, fun, &A->space, A->atoms, A->log)) { + slang_info_log_error(A->log, "Function '%s' not found (check argument types)", name); + return NULL; + } + assert(fun); + } + + return _slang_gen_function_call(A, fun, oper, dest); +} + + +static GLboolean +_slang_is_constant_cond(const slang_operation *oper, GLboolean *value) +{ + 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 loop code using high-level IR_LOOP instruction + */ +static slang_ir_node * +_slang_gen_while(slang_assemble_ctx * A, const slang_operation *oper) +{ + /* + * LOOP: + * BREAK if !expr (child[0]) + * body code (child[1]) + */ + slang_ir_node *prevLoop, *loop, *cond, *breakIf, *body; + GLboolean isConst, constTrue; + + /* Check if loop condition is a constant */ + isConst = _slang_is_constant_cond(&oper->children[0], &constTrue); + + if (isConst && !constTrue) { + /* loop is never executed! */ + return new_node0(IR_NOP); + } + + loop = new_loop(NULL); + + /* 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]); + loop->Children[0] = new_seq(breakIf, body); + + /* Do infinite loop detection */ + /* loop->List is head of linked list of break/continue nodes */ + if (!loop->List && isConst && constTrue) { + /* infinite loop detected */ + A->CurLoop = prevLoop; /* clean-up */ + slang_info_log_error(A->log, "Infinite loop detected!"); + return NULL; + } + + /* pop loop, restore prev */ + A->CurLoop = prevLoop; + + return 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) +{ + /* + * LOOP: + * body code (child[0]) + * tail code: + * BREAK if !expr (child[1]) + */ + slang_ir_node *prevLoop, *loop, *cond; + GLboolean isConst, constTrue; + + loop = new_loop(NULL); + + /* save old, push new loop */ + prevLoop = A->CurLoop; + A->CurLoop = loop; + + /* loop body: */ + loop->Children[0] = _slang_gen_operation(A, &oper->children[0]); + + /* Check if loop condition is a constant */ + isConst = _slang_is_constant_cond(&oper->children[1], &constTrue); + if (isConst && constTrue) { + /* do { } while(1) ==> no conditional break */ + loop->Children[1] = NULL; /* no tail code */ + } + else { + cond = new_cond(_slang_gen_operation(A, &oper->children[1])); + loop->Children[1] = new_break_if(A->CurLoop, cond, GL_FALSE); + } + + /* XXX we should do infinite loop detection, as above */ + + /* pop loop, restore prev */ + A->CurLoop = prevLoop; + + return 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]) + * LOOP: + * BREAK if !expr (child[1]) + * body code (child[3]) + * tail code: + * incr code (child[2]) // XXX continue here + */ + slang_ir_node *prevLoop, *loop, *cond, *breakIf, *body, *init, *incr; + + init = _slang_gen_operation(A, &oper->children[0]); + loop = new_loop(NULL); + + /* 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]); + incr = _slang_gen_operation(A, &oper->children[2]); + + loop->Children[0] = new_seq(breakIf, body); + loop->Children[1] = incr; /* tail code */ + + /* pop loop, restore prev */ + A->CurLoop = prevLoop; + + return new_seq(init, loop); +} + + +static slang_ir_node * +_slang_gen_continue(slang_assemble_ctx * A, const slang_operation *oper) +{ + slang_ir_node *n, *loopNode; + assert(oper->type == SLANG_OPER_CONTINUE); + loopNode = A->CurLoop; + assert(loopNode); + assert(loopNode->Opcode == IR_LOOP); + n = new_node0(IR_CONT); + if (n) { + n->Parent = loopNode; + /* insert this node at head of linked list */ + n->List = loopNode->List; + loopNode->List = n; + } + return n; +} + + +/** + * 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 + * IR_IF instruction. + */ +static slang_ir_node * +_slang_gen_if(slang_assemble_ctx * A, const slang_operation *oper) +{ + /* + * eval expr (child[0]) + * IF expr THEN + * if-body code + * ELSE + * else-body code + * ENDIF + */ + const GLboolean haveElseClause = !_slang_is_noop(&oper->children[2]); + slang_ir_node *ifNode, *cond, *ifBody, *elseBody; + + cond = _slang_gen_operation(A, &oper->children[0]); + cond = new_cond(cond); + + 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; + } +} + + + +/** + * Generate IR node for storage of a temporary of given size. + */ +static slang_ir_node * +_slang_gen_temporary(GLint size) +{ + slang_ir_storage *store; + slang_ir_node *n; + + store = _slang_new_ir_storage(PROGRAM_TEMPORARY, -1, size); + if (store) { + n = new_node0(IR_VAR_DECL); + if (n) { + n->Store = store; + } + else { + free(store); + } + } + return n; +} + + +/** + * Generate IR node for allocating/declaring a variable. + */ +static slang_ir_node * +_slang_gen_var_decl(slang_assemble_ctx *A, slang_variable *var) +{ + slang_ir_node *n; + assert(!is_sampler_type(&var->type)); + n = new_node0(IR_VAR_DECL); + if (n) { + _slang_attach_storage(n, var); + + assert(var->aux); + assert(n->Store == var->aux); + assert(n->Store); + assert(n->Store->Index < 0); + + n->Store->File = PROGRAM_TEMPORARY; + n->Store->Size = _slang_sizeof_type_specifier(&n->Var->type.specifier); + assert(n->Store->Size > 0); + } + return n; +} + + +/** + * Generate code for a selection expression: b ? x : y + * XXX In some cases we could implement a selection expression + * with an LRP instruction (use the boolean as the interpolant). + * Otherwise, we use an IF/ELSE/ENDIF construct. + */ +static slang_ir_node * +_slang_gen_select(slang_assemble_ctx *A, slang_operation *oper) +{ + slang_ir_node *cond, *ifNode, *trueExpr, *falseExpr, *trueNode, *falseNode; + slang_ir_node *tmpDecl, *tmpVar, *tree; + slang_typeinfo type; + int size; + + assert(oper->type == SLANG_OPER_SELECT); + assert(oper->num_children == 3); + + /* size of x or y's type */ + slang_typeinfo_construct(&type); + _slang_typeof_operation(A, &oper->children[1], &type); + size = _slang_sizeof_type_specifier(&type.spec); + assert(size > 0); + + /* temporary var */ + tmpDecl = _slang_gen_temporary(size); + + /* the condition (child 0) */ + cond = _slang_gen_operation(A, &oper->children[0]); + cond = new_cond(cond); + + /* if-true body (child 1) */ + tmpVar = new_node0(IR_VAR); + tmpVar->Store = tmpDecl->Store; + trueExpr = _slang_gen_operation(A, &oper->children[1]); + trueNode = new_node2(IR_MOVE, tmpVar, trueExpr); + + /* if-false body (child 2) */ + tmpVar = new_node0(IR_VAR); + tmpVar->Store = tmpDecl->Store; + falseExpr = _slang_gen_operation(A, &oper->children[2]); + falseNode = new_node2(IR_MOVE, tmpVar, falseExpr); + + ifNode = new_if(cond, trueNode, falseNode); + + /* tmp var value */ + tmpVar = new_node0(IR_VAR); + tmpVar->Store = tmpDecl->Store; + + tree = new_seq(ifNode, tmpVar); + tree = new_seq(tmpDecl, tree); + + /*_slang_print_ir_tree(tree, 10);*/ + return tree; +} + + +/** + * Generate code for &&. + */ +static slang_ir_node * +_slang_gen_logical_and(slang_assemble_ctx *A, slang_operation *oper) +{ + /* rewrite "a && b" as "a ? b : false" */ + slang_operation *select; + slang_ir_node *n; + + select = slang_operation_new(1); + 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; + ASSIGN_4V(select->children[2].literal, 0, 0, 0, 0); /* false */ + select->children[2].literal_size = 1; + + n = _slang_gen_select(A, select); + + /* xxx wrong */ + free(select->children); + free(select); + + return n; +} + + +/** + * Generate code for ||. + */ +static slang_ir_node * +_slang_gen_logical_or(slang_assemble_ctx *A, slang_operation *oper) +{ + /* rewrite "a || b" as "a ? true : b" */ + slang_operation *select; + slang_ir_node *n; + + select = slang_operation_new(1); + 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; + ASSIGN_4V(select->children[1].literal, 1, 1, 1, 1); /* true */ + select->children[1].literal_size = 1; + slang_operation_copy(&select->children[2], &oper->children[1]); + + n = _slang_gen_select(A, select); + + /* xxx wrong */ + free(select->children); + free(select); + + return n; +} + + +/** + * Generate IR tree for a return statement. + */ +static slang_ir_node * +_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)) { + /* Convert from: + * return; + * To: + * goto __endOfFunction; + */ + slang_ir_node *n; + slang_operation gotoOp; + slang_operation_construct(&gotoOp); + gotoOp.type = SLANG_OPER_GOTO; + gotoOp.label = A->curFuncEndLabel; + assert(gotoOp.label); + + /* assemble the new code */ + n = _slang_gen_operation(A, &gotoOp); + /* destroy temp code */ + slang_operation_destruct(&gotoOp); + return n; + } + else { + /* + * Convert from: + * return expr; + * To: + * __retVal = expr; + * goto __endOfFunction; + */ + slang_operation *block, *assign, *jump; + slang_atom a_retVal; + slang_ir_node *n; + + a_retVal = slang_atom_pool_atom(A->atoms, "__retVal"); + assert(a_retVal); + +#if 1 /* DEBUG */ + { + slang_variable *v + = _slang_locate_variable(oper->locals, a_retVal, GL_TRUE); + assert(v); + } +#endif + + block = slang_operation_new(1); + block->type = SLANG_OPER_BLOCK_NO_NEW_SCOPE; + assert(block->locals); + block->locals->outer_scope = oper->locals->outer_scope; + block->num_children = 2; + block->children = slang_operation_new(2); + + /* child[0]: __retVal = expr; */ + assign = &block->children[0]; + 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].a_id = a_retVal; + assign->children[0].locals->outer_scope = assign->locals; + /* rhs (expr) */ + /* XXX we might be able to avoid this copy someday */ + slang_operation_copy(&assign->children[1], &oper->children[0]); + + /* child[1]: goto __endOfFunction */ + jump = &block->children[1]; + jump->type = SLANG_OPER_GOTO; + assert(A->curFuncEndLabel); + /* XXX don't call function? */ + jump->label = A->curFuncEndLabel; + assert(jump->label); + +#if 0 /* debug */ + printf("NEW RETURN:\n"); + slang_print_tree(block, 0); +#endif + + /* assemble the new code */ + n = _slang_gen_operation(A, block); + slang_operation_delete(block); + return n; + } +} + + +/** + * Generate IR tree for a variable declaration. + */ +static slang_ir_node * +_slang_gen_declaration(slang_assemble_ctx *A, slang_operation *oper) +{ + slang_ir_node *n; + slang_ir_node *varDecl; + slang_variable *v; + const char *varName = (char *) oper->a_id; + + assert(oper->num_children == 0 || oper->num_children == 1); + + v = _slang_locate_variable(oper->locals, oper->a_id, GL_TRUE); + assert(v); + + varDecl = _slang_gen_var_decl(A, v); + + if (oper->num_children > 0) { + /* child is initializer */ + slang_ir_node *var, *init, *rhs; + assert(oper->num_children == 1); + var = new_var(A, oper, oper->a_id); + if (!var) { + slang_info_log_error(A->log, "undefined variable '%s'", varName); + return NULL; + } + /* XXX make copy of this initializer? */ + rhs = _slang_gen_operation(A, &oper->children[0]); + assert(rhs); + init = new_node2(IR_MOVE, var, rhs); + /*assert(rhs->Opcode != IR_SEQ);*/ + n = new_seq(varDecl, init); + } + else if (v->initializer) { + slang_ir_node *var, *init, *rhs; + var = new_var(A, oper, oper->a_id); + if (!var) { + slang_info_log_error(A->log, "undefined variable '%s'", varName); + return NULL; + } +#if 0 + /* XXX make copy of this initializer? */ + { + slang_operation dup; + slang_operation_construct(&dup); + slang_operation_copy(&dup, v->initializer); + _slang_simplify(&dup, &A->space, A->atoms); + rhs = _slang_gen_operation(A, &dup); + } +#else + _slang_simplify(v->initializer, &A->space, A->atoms); + rhs = _slang_gen_operation(A, v->initializer); +#endif + assert(rhs); + init = new_node2(IR_MOVE, var, rhs); + /* + assert(rhs->Opcode != IR_SEQ); + */ + n = new_seq(varDecl, init); + } + else { + n = varDecl; + } + return n; +} + + +/** + * Generate IR tree for a variable (such as in an expression). + */ +static slang_ir_node * +_slang_gen_variable(slang_assemble_ctx * A, slang_operation *oper) +{ + /* If there's a variable associated with this oper (from inlining) + * use it. Otherwise, use the oper's var id. + */ + slang_atom aVar = oper->var ? oper->var->a_name : oper->a_id; + slang_ir_node *n = new_var(A, oper, aVar); + if (!n) { + slang_info_log_error(A->log, "undefined variable '%s'", (char *) aVar); + return NULL; + } + return n; +} + + +/** + * Some write-masked assignments are simple, but others are hard. + * Simple example: + * vec3 v; + * v.xy = vec2(a, b); + * Hard example: + * vec3 v; + * v.zy = vec2(a, b); + * this gets transformed/swizzled into: + * v.zy = vec2(a, b).*yx* (* = don't care) + * This function helps to determine simple vs. non-simple. + */ +static GLboolean +_slang_simple_writemask(GLuint writemask, GLuint swizzle) +{ + switch (writemask) { + case WRITEMASK_X: + return GET_SWZ(swizzle, 0) == SWIZZLE_X; + case WRITEMASK_Y: + return GET_SWZ(swizzle, 1) == SWIZZLE_Y; + case WRITEMASK_Z: + return GET_SWZ(swizzle, 2) == SWIZZLE_Z; + case WRITEMASK_W: + return GET_SWZ(swizzle, 3) == SWIZZLE_W; + case WRITEMASK_XY: + return (GET_SWZ(swizzle, 0) == SWIZZLE_X) + && (GET_SWZ(swizzle, 1) == SWIZZLE_Y); + case WRITEMASK_XYZ: + return (GET_SWZ(swizzle, 0) == SWIZZLE_X) + && (GET_SWZ(swizzle, 1) == SWIZZLE_Y) + && (GET_SWZ(swizzle, 2) == SWIZZLE_Z); + case WRITEMASK_XYZW: + return swizzle == SWIZZLE_NOOP; + default: + return GL_FALSE; + } +} + + +/** + * Convert the given swizzle into a writemask. In some cases this + * is trivial, in other cases, we'll need to also swizzle the right + * hand side to put components in the right places. + * \param swizzle the incoming swizzle + * \param writemaskOut returns the writemask + * \param swizzleOut swizzle to apply to the right-hand-side + * \return GL_FALSE for simple writemasks, GL_TRUE for non-simple + */ +static GLboolean +swizzle_to_writemask(GLuint swizzle, + GLuint *writemaskOut, GLuint *swizzleOut) +{ + GLuint mask = 0x0, newSwizzle[4]; + GLint i, size; + + /* make new dst writemask, compute size */ + for (i = 0; i < 4; i++) { + const GLuint swz = GET_SWZ(swizzle, i); + if (swz == SWIZZLE_NIL) { + /* end */ + break; + } + assert(swz >= 0 && swz <= 3); + mask |= (1 << swz); + } + assert(mask <= 0xf); + size = i; /* number of components in mask/swizzle */ + + *writemaskOut = mask; + + /* make new src swizzle, by inversion */ + for (i = 0; i < 4; i++) { + newSwizzle[i] = i; /*identity*/ + } + for (i = 0; i < size; i++) { + const GLuint swz = GET_SWZ(swizzle, i); + newSwizzle[swz] = i; + } + *swizzleOut = MAKE_SWIZZLE4(newSwizzle[0], + newSwizzle[1], + newSwizzle[2], + newSwizzle[3]); + + if (_slang_simple_writemask(mask, *swizzleOut)) { + if (size >= 1) + assert(GET_SWZ(*swizzleOut, 0) == SWIZZLE_X); + if (size >= 2) + assert(GET_SWZ(*swizzleOut, 1) == SWIZZLE_Y); + if (size >= 3) + assert(GET_SWZ(*swizzleOut, 2) == SWIZZLE_Z); + if (size >= 4) + assert(GET_SWZ(*swizzleOut, 3) == SWIZZLE_W); + return GL_TRUE; + } + else + return GL_FALSE; +} + + +static slang_ir_node * +_slang_gen_swizzle(slang_ir_node *child, GLuint swizzle) +{ + slang_ir_node *n = new_node1(IR_SWIZZLE, child); + assert(child); + if (n) { + n->Store = _slang_new_ir_storage(PROGRAM_UNDEFINED, -1, -1); + n->Store->Swizzle = swizzle; + } + return n; +} + + +/** + * Generate IR tree for an assignment (=). + */ +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) { + /* Special case of: x = f(a, b) + * Replace with f(a, b, x) (where x == hidden __retVal out param) + * + * XXX this could be even more effective if we could accomodate + * cases such as "v.x = f();" - would help with typical vertex + * transformation. + */ + slang_ir_node *n; + n = _slang_gen_function_call_name(A, + (const char *) oper->children[1].a_id, + &oper->children[1], &oper->children[0]); + return n; + } + else { + slang_ir_node *n, *lhs, *rhs; + lhs = _slang_gen_operation(A, &oper->children[0]); + + if (lhs) { + if (lhs->Store->File != PROGRAM_OUTPUT && + lhs->Store->File != PROGRAM_TEMPORARY && + lhs->Store->File != PROGRAM_VARYING && + lhs->Store->File != PROGRAM_UNDEFINED) { + slang_info_log_error(A->log, "Assignment to read-only variable"); + return NULL; + } + } + + rhs = _slang_gen_operation(A, &oper->children[1]); + if (lhs && rhs) { + /* convert lhs swizzle into writemask */ + GLuint writemask, newSwizzle; + if (!swizzle_to_writemask(lhs->Store->Swizzle, + &writemask, &newSwizzle)) { + /* Non-simple writemask, need to swizzle right hand side in + * order to put components into the right place. + */ + rhs = _slang_gen_swizzle(rhs, newSwizzle); + } + n = new_node2(IR_MOVE, lhs, rhs); + n->Writemask = writemask; + return n; + } + else { + return NULL; + } + } +} + + +/** + * Generate IR tree for referencing a field in a struct (or basic vector type) + */ +static slang_ir_node * +_slang_gen_field(slang_assemble_ctx * A, slang_operation *oper) +{ + slang_typeinfo ti; + + /* type of struct */ + slang_typeinfo_construct(&ti); + _slang_typeof_operation(A, &oper->children[0], &ti); + + if (_slang_type_is_vector(ti.spec.type)) { + /* the field should be a swizzle */ + const GLuint rows = _slang_type_dim(ti.spec.type); + slang_swizzle swz; + slang_ir_node *n; + GLuint swizzle; + if (!_slang_is_swizzle((char *) oper->a_id, rows, &swz)) { + slang_info_log_error(A->log, "Bad swizzle"); + } + swizzle = MAKE_SWIZZLE4(swz.swizzle[0], + swz.swizzle[1], + swz.swizzle[2], + swz.swizzle[3]); + + n = _slang_gen_operation(A, &oper->children[0]); + /* create new parent node with swizzle */ + if (n) + n = _slang_gen_swizzle(n, swizzle); + return n; + } + else if (ti.spec.type == SLANG_SPEC_FLOAT) { + const GLuint rows = 1; + slang_swizzle swz; + slang_ir_node *n; + GLuint swizzle; + if (!_slang_is_swizzle((char *) oper->a_id, rows, &swz)) { + slang_info_log_error(A->log, "Bad swizzle"); + } + swizzle = MAKE_SWIZZLE4(swz.swizzle[0], + swz.swizzle[1], + swz.swizzle[2], + swz.swizzle[3]); + n = _slang_gen_operation(A, &oper->children[0]); + /* create new parent node with swizzle */ + n = _slang_gen_swizzle(n, swizzle); + return n; + } + else { + /* the field is a structure member (base.field) */ + /* oper->children[0] is the base */ + /* oper->a_id is the field name */ + slang_ir_node *base, *n; + slang_typeinfo field_ti; + GLint fieldSize, fieldOffset; + /* type of field */ + slang_typeinfo_construct(&field_ti); + _slang_typeof_operation(A, oper, &field_ti); + + fieldSize = _slang_sizeof_type_specifier(&field_ti.spec); + fieldOffset = _slang_field_offset(&ti.spec, oper->a_id); + + if (fieldOffset < 0) { + slang_info_log_error(A->log, + "\"%s\" is not a member of struct \"%s\"", + (char *) oper->a_id, + (char *) ti.spec._struct->a_name); + return NULL; + } + assert(fieldSize >= 0); + + base = _slang_gen_operation(A, &oper->children[0]); + if (!base) { + /* error msg should have already been logged */ + return NULL; + } + + n = new_node1(IR_FIELD, base); + if (n) { + n->Field = (char *) oper->a_id; + n->FieldOffset = fieldOffset; + assert(n->FieldOffset >= 0); + n->Store = _slang_new_ir_storage(base->Store->File, + base->Store->Index, + fieldSize); + } + return n; + +#if 0 + _mesa_problem(NULL, "glsl structs/fields not supported yet"); + return NULL; +#endif + } +} + + +/** + * Gen code for array indexing. + */ +static slang_ir_node * +_slang_gen_subscript(slang_assemble_ctx * A, slang_operation *oper) +{ + slang_typeinfo array_ti; + + /* get array's type info */ + slang_typeinfo_construct(&array_ti); + _slang_typeof_operation(A, &oper->children[0], &array_ti); + + if (_slang_type_is_vector(array_ti.spec.type)) { + /* indexing a simple vector type: "vec4 v; v[0]=p;" */ + /* translate the index into a swizzle/writemask: "v.x=p" */ + const GLuint max = _slang_type_dim(array_ti.spec.type); + GLint index; + slang_ir_node *n; + + index = (GLint) oper->children[1].literal[0]; + if (oper->children[1].type != SLANG_OPER_LITERAL_INT || + index >= max) { + slang_info_log_error(A->log, "Invalid array index for vector type"); + return NULL; + } + + n = _slang_gen_operation(A, &oper->children[0]); + if (n) { + /* use swizzle to access the element */ + GLuint swizzle = MAKE_SWIZZLE4(SWIZZLE_X + index, + SWIZZLE_NIL, + SWIZZLE_NIL, + SWIZZLE_NIL); + n = _slang_gen_swizzle(n, swizzle); + /*n->Store = _slang_clone_ir_storage_swz(n->Store, */ + n->Writemask = WRITEMASK_X << index; + } + return n; + } + else { + /* conventional array */ + slang_typeinfo elem_ti; + slang_ir_node *elem, *array, *index; + GLint elemSize, arrayLen; + + /* size of array element */ + slang_typeinfo_construct(&elem_ti); + _slang_typeof_operation(A, oper, &elem_ti); + elemSize = _slang_sizeof_type_specifier(&elem_ti.spec); + + if (_slang_type_is_matrix(array_ti.spec.type)) + arrayLen = _slang_type_dim(array_ti.spec.type); + else + arrayLen = array_ti.array_len; + + slang_typeinfo_destruct(&array_ti); + slang_typeinfo_destruct(&elem_ti); + + if (elemSize <= 0) { + /* unknown var or type */ + slang_info_log_error(A->log, "Undefined variable or type"); + return NULL; + } + + array = _slang_gen_operation(A, &oper->children[0]); + index = _slang_gen_operation(A, &oper->children[1]); + if (array && index) { + /* bounds check */ + if (index->Opcode == IR_FLOAT && + ((int) index->Value[0] < 0 || + (int) index->Value[0] >= arrayLen)) { + slang_info_log_error(A->log, + "Array index out of bounds (index=%d size=%d)", + (int) index->Value[0], arrayLen); + _slang_free_ir_tree(array); + _slang_free_ir_tree(index); + return NULL; + } + + elem = new_node2(IR_ELEMENT, array, index); + elem->Store = _slang_new_ir_storage(array->Store->File, + array->Store->Index, + elemSize); + /* XXX try to do some array bounds checking here */ + return elem; + } + else { + _slang_free_ir_tree(array); + _slang_free_ir_tree(index); + return NULL; + } + } +} + + +/** + * Look for expressions such as: gl_ModelviewMatrix * gl_Vertex + * and replace with this: gl_Vertex * gl_ModelviewMatrixTranpose + * Since matrices are stored in column-major order, the second form of + * multiplication is much more efficient (just 4 dot products). + */ +static void +_slang_check_matmul_optimization(slang_assemble_ctx *A, slang_operation *oper) +{ + static const struct { + const char *orig; + const char *tranpose; + } matrices[] = { + {"gl_ModelViewMatrix", "gl_ModelViewMatrixTranspose"}, + {"gl_ProjectionMatrix", "gl_ProjectionMatrixTranspose"}, + {"gl_ModelViewProjectionMatrix", "gl_ModelViewProjectionMatrixTranspose"}, + {"gl_TextureMatrix", "gl_TextureMatrixTranspose"}, + {"gl_NormalMatrix", "__NormalMatrixTranspose"}, + { NULL, NULL } + }; + + assert(oper->type == SLANG_OPER_MULTIPLY); + if (oper->children[0].type == SLANG_OPER_IDENTIFIER) { + GLuint i; + for (i = 0; matrices[i].orig; i++) { + if (oper->children[0].a_id + == slang_atom_pool_atom(A->atoms, matrices[i].orig)) { + /* + _mesa_printf("Replace %s with %s\n", + matrices[i].orig, matrices[i].tranpose); + */ + assert(oper->children[0].type == SLANG_OPER_IDENTIFIER); + oper->children[0].a_id + = slang_atom_pool_atom(A->atoms, matrices[i].tranpose); + /* finally, swap the operands */ + _slang_operation_swap(&oper->children[0], &oper->children[1]); + return; + } + } + } +} + + +/** + * Generate IR tree for a slang_operation (AST node) + */ +static slang_ir_node * +_slang_gen_operation(slang_assemble_ctx * A, slang_operation *oper) +{ + switch (oper->type) { + 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 */ + n = _slang_gen_operation(A, oper); + oper->type = SLANG_OPER_BLOCK_NEW_SCOPE; /* restore */ + + _slang_pop_var_table(A->vartable); + + if (n) + n = new_node1(IR_SCOPE, n); + return n; + } + break; + + case SLANG_OPER_BLOCK_NO_NEW_SCOPE: + /* list of operations */ + if (oper->num_children > 0) + { + slang_ir_node *n, *tree = NULL; + GLuint i; + + for (i = 0; i < oper->num_children; i++) { + n = _slang_gen_operation(A, &oper->children[i]); + if (!n) { + _slang_free_ir_tree(tree); + return NULL; /* error must have occured */ + } + tree = tree ? new_seq(tree, n) : n; + } + +#if 00 + if (oper->locals->num_variables > 0) { + int i; + /* + printf("\n****** Deallocate vars in scope!\n"); + */ + for (i = 0; i < oper->locals->num_variables; i++) { + slang_variable *v = oper->locals->variables + i; + if (v->aux) { + slang_ir_storage *store = (slang_ir_storage *) v->aux; + /* + printf(" Deallocate var %s\n", (char*) v->a_name); + */ + assert(store->File == PROGRAM_TEMPORARY); + assert(store->Index >= 0); + _slang_free_temp(A->vartable, store->Index, store->Size); + } + } + } +#endif + return tree; + } + else { + return new_node0(IR_NOP); + } + + case SLANG_OPER_EXPRESSION: + return _slang_gen_operation(A, &oper->children[0]); + + case SLANG_OPER_FOR: + return _slang_gen_for(A, oper); + case SLANG_OPER_DO: + return _slang_gen_do(A, oper); + case SLANG_OPER_WHILE: + return _slang_gen_while(A, oper); + case SLANG_OPER_BREAK: + if (!A->CurLoop) { + slang_info_log_error(A->log, "'break' not in loop"); + } + return new_break(A->CurLoop); + case SLANG_OPER_CONTINUE: + if (!A->CurLoop) { + slang_info_log_error(A->log, "'continue' not in loop"); + } + return _slang_gen_continue(A, oper); + case SLANG_OPER_DISCARD: + return new_node0(IR_KILL); + + case SLANG_OPER_EQUAL: + return new_node2(IR_EQUAL, + _slang_gen_operation(A, &oper->children[0]), + _slang_gen_operation(A, &oper->children[1])); + case SLANG_OPER_NOTEQUAL: + return new_node2(IR_NOTEQUAL, + _slang_gen_operation(A, &oper->children[0]), + _slang_gen_operation(A, &oper->children[1])); + 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: + return new_node2(IR_SLT, + _slang_gen_operation(A, &oper->children[0]), + _slang_gen_operation(A, &oper->children[1])); + 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: + return new_node2(IR_SLE, + _slang_gen_operation(A, &oper->children[0]), + _slang_gen_operation(A, &oper->children[1])); + 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: + { + slang_ir_node *n; + assert(oper->num_children == 2); + n = _slang_gen_function_call_name(A, "-", oper, NULL); + return n; + } + case SLANG_OPER_MULTIPLY: + { + slang_ir_node *n; + assert(oper->num_children == 2); + _slang_check_matmul_optimization(A, oper); + n = _slang_gen_function_call_name(A, "*", oper, NULL); + return n; + } + 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: + { + slang_ir_node *n; + assert(oper->num_children == 1); + n = _slang_gen_function_call_name(A, "-", oper, NULL); + return n; + } + case SLANG_OPER_PLUS: + /* +expr --> do nothing */ + return _slang_gen_operation(A, &oper->children[0]); + case SLANG_OPER_VARIABLE_DECL: + return _slang_gen_declaration(A, oper); + case SLANG_OPER_ASSIGN: + return _slang_gen_assignment(A, oper); + 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: + { + slang_ir_node *n; + assert(oper->num_children == 2); + n = _slang_gen_function_call_name(A, "-=", oper, &oper->children[0]); + return n; + } + break; + 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: + { + 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: + { + slang_ir_node *n; + assert(oper->num_children == 2); + n = _slang_gen_logical_and(A, oper); + return n; + } + 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: + { + 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: + { + slang_ir_node *n; + assert(oper->num_children == 1); + n = _slang_gen_function_call_name(A, "__logicalNot", oper, NULL); + return n; + } + + case SLANG_OPER_SELECT: /* b ? x : y */ + { + slang_ir_node *n; + assert(oper->num_children == 3); + n = _slang_gen_select(A, oper); + return n; + } + + case SLANG_OPER_ASM: + return _slang_gen_asm(A, oper, NULL); + case SLANG_OPER_CALL: + return _slang_gen_function_call_name(A, (const char *) oper->a_id, + oper, NULL); + case SLANG_OPER_RETURN: + return _slang_gen_return(A, oper); + case SLANG_OPER_GOTO: + return new_jump(oper->label); + case SLANG_OPER_LABEL: + return new_label(oper->label); + case SLANG_OPER_IDENTIFIER: + return _slang_gen_variable(A, oper); + case SLANG_OPER_IF: + return _slang_gen_if(A, oper); + case SLANG_OPER_FIELD: + return _slang_gen_field(A, oper); + case SLANG_OPER_SUBSCRIPT: + return _slang_gen_subscript(A, oper); + case SLANG_OPER_LITERAL_FLOAT: + /* fall-through */ + case SLANG_OPER_LITERAL_INT: + /* fall-through */ + case SLANG_OPER_LITERAL_BOOL: + return new_float_literal(oper->literal); + + 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-- */ + { + 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 */ + { + 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 */ + { + slang_ir_node *n; + assert(oper->num_children == 1); + n = _slang_gen_function_call_name(A, "--", oper, NULL); + return n; + } + + case SLANG_OPER_SEQUENCE: + { + slang_ir_node *tree = NULL; + GLuint i; + for (i = 0; i < oper->num_children; i++) { + slang_ir_node *n = _slang_gen_operation(A, &oper->children[i]); + tree = tree ? new_seq(tree, n) : n; + } + return tree; + } + + case SLANG_OPER_NONE: + case SLANG_OPER_VOID: + /* returning NULL here would generate an error */ + return new_node0(IR_NOP); + + default: + printf("Unhandled node type %d\n", oper->type); + abort(); + return new_node0(IR_NOP); + } + + return NULL; +} + + + +/** + * Called by compiler when a global variable has been parsed/compiled. + * Here we examine the variable's type to determine what kind of register + * storage will be used. + * + * A uniform such as "gl_Position" will become the register specification + * (PROGRAM_OUTPUT, VERT_RESULT_HPOS). Or, uniform "gl_FogFragCoord" + * will be (PROGRAM_INPUT, FRAG_ATTRIB_FOGC). + * + * Samplers are interesting. For "uniform sampler2D tex;" we'll specify + * (PROGRAM_SAMPLER, index) where index is resolved at link-time to an + * actual texture unit (as specified by the user calling glUniform1i()). + */ +GLboolean +_slang_codegen_global_variable(slang_assemble_ctx *A, slang_variable *var, + slang_unit_type type) +{ + struct gl_program *prog = A->program; + const char *varName = (char *) var->a_name; + GLboolean success = GL_TRUE; + GLint texIndex; + slang_ir_storage *store = NULL; + int dbg = 0; + + texIndex = sampler_to_texture_index(var->type.specifier.type); + + if (texIndex != -1) { + /* Texture sampler: + * store->File = PROGRAM_SAMPLER + * store->Index = sampler uniform location + * store->Size = texture type index (1D, 2D, 3D, cube, etc) + */ + GLint samplerUniform = _mesa_add_sampler(prog->Parameters, varName); + store = _slang_new_ir_storage(PROGRAM_SAMPLER, samplerUniform, texIndex); + if (dbg) printf("SAMPLER "); + } + else if (var->type.qualifier == SLANG_QUAL_UNIFORM) { + /* Uniform variable */ + const GLint size = _slang_sizeof_type_specifier(&var->type.specifier) + * MAX2(var->array_len, 1); + if (prog) { + /* user-defined uniform */ + GLint uniformLoc = _mesa_add_uniform(prog->Parameters, varName, size); + store = _slang_new_ir_storage(PROGRAM_UNIFORM, uniformLoc, size); + } + else { + /* pre-defined uniform, like gl_ModelviewMatrix */ + /* We know it's a uniform, but don't allocate storage unless + * it's really used. + */ + store = _slang_new_ir_storage(PROGRAM_STATE_VAR, -1, size); + } + if (dbg) printf("UNIFORM (sz %d) ", size); + } + else if (var->type.qualifier == SLANG_QUAL_VARYING) { + const GLint size = 4; /* XXX fix */ + if (prog) { + /* user-defined varying */ + GLint varyingLoc = _mesa_add_varying(prog->Varying, varName, size); + store = _slang_new_ir_storage(PROGRAM_VARYING, varyingLoc, size); + } + else { + /* pre-defined varying, like gl_Color or gl_TexCoord */ + if (type == SLANG_UNIT_FRAGMENT_BUILTIN) { + GLuint swizzle; + GLint index = _slang_input_index(varName, GL_FRAGMENT_PROGRAM_ARB, + &swizzle); + assert(index >= 0); + store = _slang_new_ir_storage(PROGRAM_INPUT, index, size); + store->Swizzle = swizzle; + assert(index < FRAG_ATTRIB_MAX); + } + else { + GLint index = _slang_output_index(varName, GL_VERTEX_PROGRAM_ARB); + assert(index >= 0); + assert(type == SLANG_UNIT_VERTEX_BUILTIN); + store = _slang_new_ir_storage(PROGRAM_OUTPUT, index, size); + assert(index < VERT_RESULT_MAX); + } + if (dbg) printf("V/F "); + } + if (dbg) printf("VARYING "); + } + else if (var->type.qualifier == SLANG_QUAL_ATTRIBUTE) { + if (prog) { + /* user-defined vertex attribute */ + const GLint size = _slang_sizeof_type_specifier(&var->type.specifier); + const GLint attr = -1; /* unknown */ + GLint index = _mesa_add_attribute(prog->Attributes, varName, + size, attr); + assert(index >= 0); + store = _slang_new_ir_storage(PROGRAM_INPUT, + VERT_ATTRIB_GENERIC0 + index, size); + } + else { + /* pre-defined vertex attrib */ + GLuint swizzle; + GLint index = _slang_input_index(varName, GL_VERTEX_PROGRAM_ARB, + &swizzle); + GLint size = 4; /* XXX? */ + assert(index >= 0); + store = _slang_new_ir_storage(PROGRAM_INPUT, index, size); + store->Swizzle = swizzle; + } + if (dbg) printf("ATTRIB "); + } + else if (var->type.qualifier == SLANG_QUAL_FIXEDINPUT) { + GLuint swizzle; + GLint index = _slang_input_index(varName, GL_FRAGMENT_PROGRAM_ARB, + &swizzle); + GLint size = 4; /* XXX? */ + store = _slang_new_ir_storage(PROGRAM_INPUT, index, size); + store->Swizzle = swizzle; + if (dbg) printf("INPUT "); + } + 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); + 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) { + /* 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); + if (dbg) printf("CONST "); + } + else { + /* ordinary variable (may be const) */ + slang_ir_node *n; + + /* IR node to declare the variable */ + n = _slang_gen_var_decl(A, var); + + /* IR code for the var's initializer, if present */ + if (var->initializer) { + slang_ir_node *lhs, *rhs, *init; + + /* Generate IR_MOVE instruction to initialize the variable */ + lhs = new_node0(IR_VAR); + lhs->Var = var; + lhs->Store = n->Store; + + /* constant folding, etc */ + _slang_simplify(var->initializer, &A->space, A->atoms); + + rhs = _slang_gen_operation(A, var->initializer); + assert(rhs); + init = new_node2(IR_MOVE, lhs, rhs); + n = new_seq(n, init); + } + + success = _slang_emit_code(n, A->vartable, A->program, GL_FALSE, A->log); + + _slang_free_ir_tree(n); + } + + if (dbg) printf("GLOBAL VAR %s idx %d\n", (char*) var->a_name, + store ? store->Index : -2); + + if (store) + var->aux = store; /* save var's storage info */ + + return success; +} + + +/** + * Produce an IR tree from a function AST (fun->body). + * Then call the code emitter to convert the IR tree into gl_program + * instructions. + */ +GLboolean +_slang_codegen_function(slang_assemble_ctx * A, slang_function * fun) +{ + slang_ir_node *n; + GLboolean success = GL_TRUE; + + if (_mesa_strcmp((char *) fun->header.a_name, "main") != 0) { + /* we only really generate code for main, all other functions get + * inlined. + */ + return GL_TRUE; /* not an error */ + } + +#if 0 + printf("\n*********** codegen_function %s\n", (char *) fun->header.a_name); + slang_print_function(fun, 1); +#endif + + /* should have been allocated earlier: */ + assert(A->program->Parameters ); + assert(A->program->Varying); + assert(A->vartable); + + /* fold constant expressions, etc. */ + _slang_simplify(fun->body, &A->space, A->atoms); + +#if 0 + printf("\n*********** simplified %s\n", (char *) fun->header.a_name); + slang_print_function(fun, 1); +#endif + + /* Create an end-of-function label */ + A->curFuncEndLabel = _slang_label_new("__endOfFunc__main"); + + /* push new vartable scope */ + _slang_push_var_table(A->vartable); + + /* Generate IR tree for the function body code */ + n = _slang_gen_operation(A, fun->body); + if (n) + n = new_node1(IR_SCOPE, n); + + /* pop vartable, restore previous */ + _slang_pop_var_table(A->vartable); + + if (!n) { + /* XXX record error */ + return GL_FALSE; + } + + /* append an end-of-function-label to IR tree */ + n = new_seq(n, new_label(A->curFuncEndLabel)); + + /*_slang_label_delete(A->curFuncEndLabel);*/ + A->curFuncEndLabel = NULL; + +#if 0 + printf("************* New AST for %s *****\n", (char*)fun->header.a_name); + slang_print_function(fun, 1); +#endif +#if 0 + printf("************* IR for %s *******\n", (char*)fun->header.a_name); + _slang_print_ir_tree(n, 0); +#endif +#if 0 + printf("************* End codegen function ************\n\n"); +#endif + + /* Emit program instructions */ + success = _slang_emit_code(n, A->vartable, A->program, GL_TRUE, A->log); + _slang_free_ir_tree(n); + + /* free codegen context */ + /* + _mesa_free(A->codegen); + */ + + return success; +} + diff --git a/src/mesa/shader/slang/slang_assemble_assignment.h b/src/mesa/shader/slang/slang_codegen.h index 3c1ecdedab..821d396162 100644 --- a/src/mesa/shader/slang/slang_assemble_assignment.h +++ b/src/mesa/shader/slang/slang_codegen.h @@ -1,8 +1,8 @@ /* * Mesa 3-D graphics library - * Version: 6.5.2 + * Version: 6.5.3 * - * Copyright (C) 2005-2006 Brian Paul All Rights Reserved. + * Copyright (C) 2005-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"), @@ -22,24 +22,24 @@ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -#ifndef SLANG_ASSEMBLE_ASSIGNMENT_H -#define SLANG_ASSEMBLE_ASSIGNMENT_H -#if defined __cplusplus -extern "C" { -#endif +#ifndef SLANG_CODEGEN_H +#define SLANG_CODEGEN_H -extern GLboolean -_slang_assemble_assignment(slang_assemble_ctx *, const struct slang_operation_ *); +#include "imports.h" +#include "slang_compile.h" + + +extern GLuint +_slang_sizeof_type_specifier(const slang_type_specifier *spec); extern GLboolean -_slang_assemble_assign(slang_assemble_ctx *, struct slang_operation_ *, - const char *, slang_ref_type); +_slang_codegen_function(slang_assemble_ctx *A , struct slang_function_ *fun); +extern GLboolean +_slang_codegen_global_variable(slang_assemble_ctx *A, slang_variable *var, + slang_unit_type type); -#ifdef __cplusplus -} -#endif -#endif /* SLANG_ASSEMBLE_ASSIGNMENT_H */ +#endif /* SLANG_CODEGEN_H */ diff --git a/src/mesa/shader/slang/slang_compile.c b/src/mesa/shader/slang/slang_compile.c index c49ab4a68d..85dd158698 100644 --- a/src/mesa/shader/slang/slang_compile.c +++ b/src/mesa/shader/slang/slang_compile.c @@ -29,10 +29,20 @@ */ #include "imports.h" +#include "context.h" +#include "program.h" +#include "prog_parameter.h" #include "grammar_mesa.h" +#include "slang_codegen.h" #include "slang_compile.h" #include "slang_preprocess.h" #include "slang_storage.h" +#include "slang_emit.h" +#include "slang_log.h" +#include "slang_vartable.h" +#include "slang_simplify.h" + +#include "slang_print.h" /* * This is a straightforward implementation of the slang front-end @@ -90,14 +100,8 @@ _slang_code_object_ctr(slang_code_object * self) for (i = 0; i < SLANG_BUILTIN_TOTAL; i++) _slang_code_unit_ctr(&self->builtin[i], self); _slang_code_unit_ctr(&self->unit, self); - _slang_assembly_file_ctr(&self->assembly); - slang_machine_ctr(&self->machine); self->varpool.next_addr = 0; slang_atom_pool_construct(&self->atompool); - slang_export_data_table_ctr(&self->expdata); - self->expdata.atoms = &self->atompool; - slang_export_code_table_ctr(&self->expcode); - self->expcode.atoms = &self->atompool; } GLvoid @@ -108,113 +112,9 @@ _slang_code_object_dtr(slang_code_object * self) for (i = 0; i < SLANG_BUILTIN_TOTAL; i++) _slang_code_unit_dtr(&self->builtin[i]); _slang_code_unit_dtr(&self->unit); - slang_assembly_file_destruct(&self->assembly); - slang_machine_dtr(&self->machine); slang_atom_pool_destruct(&self->atompool); - slang_export_data_table_dtr(&self->expdata); - slang_export_code_table_ctr(&self->expcode); -} - -/* slang_info_log */ - -static char *out_of_memory = "Error: Out of memory.\n"; - -void -slang_info_log_construct(slang_info_log * log) -{ - log->text = NULL; - log->dont_free_text = 0; } -void -slang_info_log_destruct(slang_info_log * log) -{ - if (!log->dont_free_text) - slang_alloc_free(log->text); -} - -static int -slang_info_log_message(slang_info_log * log, const char *prefix, - const char *msg) -{ - GLuint size; - - if (log->dont_free_text) - return 0; - size = slang_string_length(msg) + 2; - if (prefix != NULL) - size += slang_string_length(prefix) + 2; - if (log->text != NULL) { - GLuint old_len = slang_string_length(log->text); - log->text = (char *) - slang_alloc_realloc(log->text, old_len + 1, old_len + size); - } - else { - log->text = (char *) (slang_alloc_malloc(size)); - if (log->text != NULL) - log->text[0] = '\0'; - } - if (log->text == NULL) - return 0; - if (prefix != NULL) { - slang_string_concat(log->text, prefix); - slang_string_concat(log->text, ": "); - } - slang_string_concat(log->text, msg); - slang_string_concat(log->text, "\n"); - return 1; -} - -int -slang_info_log_print(slang_info_log * log, const char *msg, ...) -{ - va_list va; - char buf[1024]; - - va_start(va, msg); - _mesa_vsprintf(buf, msg, va); - va_end(va); - return slang_info_log_message(log, NULL, buf); -} - -int -slang_info_log_error(slang_info_log * log, const char *msg, ...) -{ - va_list va; - char buf[1024]; - - va_start(va, msg); - _mesa_vsprintf(buf, msg, va); - va_end(va); - if (slang_info_log_message(log, "Error", buf)) - return 1; - slang_info_log_memory(log); - return 0; -} - -int -slang_info_log_warning(slang_info_log * log, const char *msg, ...) -{ - va_list va; - char buf[1024]; - - va_start(va, msg); - _mesa_vsprintf(buf, msg, va); - va_end(va); - if (slang_info_log_message(log, "Warning", buf)) - return 1; - slang_info_log_memory(log); - return 0; -} - -void -slang_info_log_memory(slang_info_log * log) -{ - if (!slang_info_log_message(log, "Error", "Out of memory.")) { - log->dont_free_text = 1; - log->text = out_of_memory; - } -} /* slang_parse_ctx */ @@ -225,6 +125,7 @@ typedef struct slang_parse_ctx_ int parsing_builtin; GLboolean global_scope; /**< Is object being declared a global? */ slang_atom_pool *atoms; + slang_unit_type type; /**< Vertex vs. Fragment */ } slang_parse_ctx; /* slang_output_ctx */ @@ -234,9 +135,9 @@ typedef struct slang_output_ctx_ slang_variable_scope *vars; slang_function_scope *funs; slang_struct_scope *structs; - slang_assembly_file *assembly; slang_var_pool *global_pool; - slang_machine *machine; + struct gl_program *program; + slang_var_table *vartable; } slang_output_ctx; /* _slang_compile() */ @@ -337,7 +238,7 @@ static GLboolean parse_array_len(slang_parse_ctx * C, slang_output_ctx * O, GLuint * len) { slang_operation array_size; - slang_assembly_name_space space; + slang_name_space space; GLboolean result; if (!slang_operation_construct(&array_size)) @@ -350,8 +251,13 @@ parse_array_len(slang_parse_ctx * C, slang_output_ctx * O, GLuint * len) space.funcs = O->funs; space.structs = O->structs; space.vars = O->vars; - result = _slang_evaluate_int(O->assembly, O->machine, &space, - &array_size, len, C->atoms); + + /* evaluate compile-time expression which is array size */ + _slang_simplify(&array_size, &space, C->atoms); + result = (array_size.type == SLANG_OPER_LITERAL_INT); + + *len = (GLint) array_size.literal[0]; + slang_operation_destruct(&array_size); return result; } @@ -365,8 +271,7 @@ calculate_var_size(slang_parse_ctx * C, slang_output_ctx * O, if (!slang_storage_aggregate_construct(&agg)) return GL_FALSE; if (!_slang_aggregate_variable(&agg, &var->type.specifier, var->array_len, - O->funs, O->structs, O->vars, O->machine, - O->assembly, C->atoms)) { + O->funs, O->structs, O->vars, C->atoms)) { slang_storage_aggregate_destruct(&agg); return GL_FALSE; } @@ -381,7 +286,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) { @@ -533,25 +438,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; @@ -582,8 +487,10 @@ parse_type_qualifier(slang_parse_ctx * C, slang_type_qualifier * qual) #define TYPE_SPECIFIER_SAMPLERCUBE 19 #define TYPE_SPECIFIER_SAMPLER1DSHADOW 20 #define TYPE_SPECIFIER_SAMPLER2DSHADOW 21 -#define TYPE_SPECIFIER_STRUCT 22 -#define TYPE_SPECIFIER_TYPENAME 23 +#define TYPE_SPECIFIER_SAMPLER2DRECT 22 +#define TYPE_SPECIFIER_SAMPLER2DRECTSHADOW 23 +#define TYPE_SPECIFIER_STRUCT 24 +#define TYPE_SPECIFIER_TYPENAME 25 static int parse_type_specifier(slang_parse_ctx * C, slang_output_ctx * O, @@ -591,78 +498,84 @@ 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_SAMPLER2DRECT: + spec->type = SLANG_SPEC_SAMPLER2DRECT; 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_SAMPLER2DRECTSHADOW: + spec->type = SLANG_SPEC_SAMPLER2DRECTSHADOW; 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; @@ -673,7 +586,7 @@ parse_type_specifier(slang_parse_ctx * C, slang_output_ctx * O, stru = slang_struct_scope_find(O->structs, a_name, 1); if (stru == NULL) { - slang_info_log_error(C->L, "%s: undeclared type name.", + slang_info_log_error(C->L, "undeclared type name '%s'", slang_atom_pool_id(C->atoms, a_name)); return 0; } @@ -705,7 +618,9 @@ parse_fully_specified_type(slang_parse_ctx * C, slang_output_ctx * O, { if (!parse_type_qualifier(C, &type->qualifier)) return 0; - return parse_type_specifier(C, O, &type->specifier); + if (!parse_type_specifier(C, O, &type->specifier)) + return 0; + return 1; } /* operation */ @@ -776,38 +691,23 @@ parse_fully_specified_type(slang_parse_ctx * C, slang_output_ctx * O, /** * When parsing a compound production, this function is used to parse the * children. - * For example, a a while-loop compound will have two children, the + * For example, a while-loop compound will have two children, the * while condition expression and the loop body. So, this function will * be called twice to parse those two sub-expressions. * \param C the parsing context * \param O the output context * \param oper the operation we're parsing - * \param statment which child of the operation is being parsed + * \param statement indicates whether parsing a statement, or expression * \return 1 if success, 0 if error */ static int parse_child_operation(slang_parse_ctx * C, slang_output_ctx * O, - slang_operation * oper, unsigned int statement) + slang_operation * oper, GLboolean statement) { slang_operation *ch; /* grow child array */ - oper->children = (slang_operation *) - slang_alloc_realloc(oper->children, - oper->num_children * sizeof(slang_operation), - (oper->num_children + 1) * sizeof(slang_operation)); - if (oper->children == NULL) { - slang_info_log_memory(C->L); - return 0; - } - - ch = &oper->children[oper->num_children]; - if (!slang_operation_construct(ch)) { - slang_info_log_memory(C->L); - return 0; - } - oper->num_children++; - /* XXX I guess the 0th "statement" is not really a statement? */ + ch = slang_operation_grow(&oper->num_children, &oper->children); if (statement) return parse_statement(C, O, ch); return parse_expression(C, O, ch); @@ -823,7 +723,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; @@ -834,7 +734,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)) @@ -846,7 +746,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_variable_decl; + oper->type = SLANG_OPER_BLOCK_NO_NEW_SCOPE; { const unsigned int first_var = O->vars->num_variables; @@ -858,26 +758,18 @@ parse_statement(slang_parse_ctx * C, slang_output_ctx * O, if (first_var < O->vars->num_variables) { const unsigned int num_vars = O->vars->num_variables - first_var; unsigned int i; - - oper->children = (slang_operation *) - slang_alloc_malloc(num_vars * sizeof(slang_operation)); + assert(oper->num_children == 0); + oper->num_children = num_vars; + oper->children = slang_operation_new(num_vars); if (oper->children == NULL) { slang_info_log_memory(C->L); return 0; } - for (oper->num_children = 0; oper->num_children < num_vars; - oper->num_children++) { - if (!slang_operation_construct - (&oper->children[oper->num_children])) { - slang_info_log_memory(C->L); - return 0; - } - } for (i = first_var; i < O->vars->num_variables; i++) { slang_operation *o = &oper->children[i - first_var]; - o->type = slang_oper_identifier; + o->type = SLANG_OPER_VARIABLE_DECL; o->locals->outer_scope = O->vars; - o->a_id = O->vars->variables[i].a_name; + o->a_id = O->vars->variables[i]->a_name; } } } @@ -886,7 +778,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; @@ -897,26 +789,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)) @@ -928,7 +820,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; @@ -937,7 +829,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)) @@ -947,7 +839,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; @@ -972,16 +864,18 @@ handle_nary_expression(slang_parse_ctx * C, slang_operation * op, { unsigned int i; - op->children = - (slang_operation *) slang_alloc_malloc(n * sizeof(slang_operation)); + op->children = slang_operation_new(n); if (op->children == NULL) { slang_info_log_memory(C->L); return 0; } op->num_children = n; - for (i = 0; i < n; i++) + for (i = 0; i < n; i++) { + slang_operation_destruct(&op->children[i]); op->children[i] = (*ops)[*total_ops - (n + 1 - i)]; + } + (*ops)[*total_ops - (n + 1)] = (*ops)[*total_ops - 1]; *total_ops -= n; @@ -1000,7 +894,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; } @@ -1036,58 +930,70 @@ 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 = (GLfloat) number; + op->literal[0] = + op->literal[1] = + op->literal[2] = + op->literal[3] = (GLfloat) number; + 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 = (GLfloat) number; + op->literal[0] = + op->literal[1] = + op->literal[2] = + op->literal[3] = (GLfloat) number; + op->literal_size = 1; break; case OP_PUSH_FLOAT: - op->type = slang_oper_literal_float; - if (!parse_float(C, &op->literal)) + op->type = SLANG_OPER_LITERAL_FLOAT; + if (!parse_float(C, &op->literal[0])) return 0; + op->literal[1] = + op->literal[2] = + op->literal[3] = op->literal[0]; + 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; @@ -1098,22 +1004,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; @@ -1121,91 +1027,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; @@ -1226,7 +1132,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; @@ -1234,12 +1140,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; @@ -1249,7 +1155,8 @@ parse_expression(slang_parse_ctx * C, slang_output_ctx * O, } C->I++; - *oper = *ops; + slang_operation_destruct(oper); + *oper = *ops; /* struct copy */ slang_alloc_free(ops); return 1; @@ -1275,23 +1182,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; @@ -1441,14 +1348,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, @@ -1460,7 +1367,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; @@ -1480,6 +1387,18 @@ parse_function_prototype(slang_parse_ctx * C, slang_output_ctx * O, return 0; } + /* if the function returns a value, append a hidden __retVal 'out' + * parameter that corresponds to the return value. + */ + if (_slang_function_has_return_value(func)) { + slang_variable *p = slang_variable_scope_grow(func->parameters); + slang_atom a_retVal = slang_atom_pool_atom(C->atoms, "__retVal"); + assert(a_retVal); + p->a_name = a_retVal; + p->type = func->header.type; + p->type.qualifier = SLANG_QUAL_OUT; + } + /* function formal parameters and local variables share the same * scope, so save the information about param count in a seperate * place also link the scope to the global variable scope so when a @@ -1488,6 +1407,7 @@ parse_function_prototype(slang_parse_ctx * C, slang_output_ctx * O, */ func->param_count = func->parameters->num_variables; func->parameters->outer_scope = O->vars; + return 1; } @@ -1529,44 +1449,24 @@ parse_function_definition(slang_parse_ctx * C, slang_output_ctx * O, static GLboolean initialize_global(slang_assemble_ctx * A, slang_variable * var) { - slang_assembly_file_restore_point point; - slang_machine mach; - slang_assembly_local_info save_local = A->local; slang_operation op_id, op_assign; GLboolean result; - /* save the current assembly */ - if (!slang_assembly_file_restore_point_save(A->file, &point)) - return GL_FALSE; - - /* setup the machine */ - mach = *A->mach; - mach.ip = A->file->count; - - /* allocate local storage for expression */ - A->local.ret_size = 0; - A->local.addr_tmp = 0; - A->local.swizzle_tmp = 4; - if (!slang_assembly_file_push_label(A->file, slang_asm_local_alloc, 20)) - return GL_FALSE; - if (!slang_assembly_file_push_label(A->file, slang_asm_enter, 20)) - return GL_FALSE; - /* 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 */ op_id.locals->variables = - (slang_variable *) slang_alloc_malloc(sizeof(slang_variable)); + (slang_variable **) slang_alloc_malloc(sizeof(slang_variable *)); if (op_id.locals->variables == NULL) { slang_operation_destruct(&op_id); return GL_FALSE; } op_id.locals->num_variables = 1; - op_id.locals->variables[0] = *var; + op_id.locals->variables[0] = var; /* construct the assignment expression */ if (!slang_operation_construct(&op_assign)) { @@ -1574,7 +1474,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) { @@ -1587,8 +1487,7 @@ initialize_global(slang_assemble_ctx * A, slang_variable * var) op_assign.children[0] = op_id; op_assign.children[1] = *var->initializer; - /* insert the actual expression */ - result = _slang_assemble_operation(A, &op_assign, slang_ref_forbid); + result = 1; /* carefully destroy the operations */ op_assign.num_children = 0; @@ -1600,21 +1499,6 @@ initialize_global(slang_assemble_ctx * A, slang_variable * var) if (!result) return GL_FALSE; - if (!slang_assembly_file_push(A->file, slang_asm_exit)) - return GL_FALSE; - - /* execute the expression */ - if (!_slang_execute2(A->file, &mach)) - return GL_FALSE; - - /* restore the old assembly */ - if (!slang_assembly_file_restore_point_load(A->file, &point)) - return GL_FALSE; - A->local = save_local; - - /* now we copy the contents of the initialized variable back to the original machine */ - _mesa_memcpy((GLubyte *) A->mach->mem + var->address, - (GLubyte *) mach.mem + var->address, var->size); return GL_TRUE; } @@ -1652,7 +1536,6 @@ parse_init_declarator(slang_parse_ctx * C, slang_output_ctx * O, } /* copy the declarator qualifier type, parse the identifier */ - var->global = C->global_scope; var->type.qualifier = type->qualifier; var->a_name = parse_identifier(C); if (var->a_name == SLANG_ATOM_NULL) @@ -1683,7 +1566,6 @@ parse_init_declarator(slang_parse_ctx * C, slang_output_ctx * O, if (!parse_expression(C, O, var->initializer)) return 0; break; -#if 0 case VARIABLE_ARRAY_UNKNOWN: /* unsized array - mark it as array and copy the specifier to the array element @@ -1691,7 +1573,6 @@ parse_init_declarator(slang_parse_ctx * C, slang_output_ctx * O, if (!convert_to_array(C, var, &type->specifier)) return GL_FALSE; break; -#endif case VARIABLE_ARRAY_EXPLICIT: if (!convert_to_array(C, var, &type->specifier)) return GL_FALSE; @@ -1702,9 +1583,21 @@ parse_init_declarator(slang_parse_ctx * C, slang_output_ctx * O, return 0; } + /* emit code for global var decl */ + if (C->global_scope) { + slang_assemble_ctx A; + A.atoms = C->atoms; + A.space.funcs = O->funs; + A.space.structs = O->structs; + A.space.vars = O->vars; + A.program = O->program; + A.vartable = O->vartable; + _slang_codegen_global_variable(&A, var, C->type); + } + /* 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; @@ -1716,8 +1609,6 @@ parse_init_declarator(slang_parse_ctx * C, slang_output_ctx * O, if (var->initializer != NULL) { slang_assemble_ctx A; - A.file = O->assembly; - A.mach = O->machine; A.atoms = C->atoms; A.space.funcs = O->funs; A.space.structs = O->structs; @@ -1725,10 +1616,6 @@ parse_init_declarator(slang_parse_ctx * C, slang_output_ctx * O, if (!initialize_global(&A, var)) return 0; } - else { - _mesa_memset((GLubyte *) (O->machine->mem) + var->address, 0, - var->size); - } } return 1; } @@ -1770,9 +1657,9 @@ parse_init_declarator_list(slang_parse_ctx * C, slang_output_ctx * O) * \param O output context * \param definition if non-zero expect a definition, else a declaration * \param parsed_func_ret returns the parsed function - * \return 1 if success, 0 if failure + * \return GL_TRUE if success, GL_FALSE if failure */ -static int +static GLboolean parse_function(slang_parse_ctx * C, slang_output_ctx * O, int definition, slang_function ** parsed_func_ret) { @@ -1780,17 +1667,17 @@ parse_function(slang_parse_ctx * C, slang_output_ctx * O, int definition, /* parse function definition/declaration */ if (!slang_function_construct(&parsed_func)) - return 0; + return GL_FALSE; if (definition) { if (!parse_function_definition(C, O, &parsed_func)) { slang_function_destruct(&parsed_func); - return 0; + return GL_FALSE; } } else { if (!parse_function_prototype(C, O, &parsed_func)) { slang_function_destruct(&parsed_func); - return 0; + return GL_FALSE; } } @@ -1800,7 +1687,7 @@ parse_function(slang_parse_ctx * C, slang_output_ctx * O, int definition, */ found_func = slang_function_scope_find(O->funs, &parsed_func, 0); if (found_func == NULL) { - /* add the parsed function to the function list */ + /* New function, add it to the function list */ O->funs->functions = (slang_function *) slang_alloc_realloc(O->funs->functions, O->funs->num_functions * @@ -1810,7 +1697,7 @@ parse_function(slang_parse_ctx * C, slang_output_ctx * O, int definition, if (O->funs->functions == NULL) { slang_info_log_memory(C->L); slang_function_destruct(&parsed_func); - return 0; + return GL_FALSE; } O->funs->functions[O->funs->num_functions] = parsed_func; O->funs->num_functions++; @@ -1819,6 +1706,7 @@ parse_function(slang_parse_ctx * C, slang_output_ctx * O, int definition, *parsed_func_ret = &O->funs->functions[O->funs->num_functions - 1]; } else { + /* previously defined or declared */ /* TODO: check function return type qualifiers and specifiers */ if (definition) { if (found_func->body != NULL) { @@ -1827,7 +1715,7 @@ parse_function(slang_parse_ctx * C, slang_output_ctx * O, int definition, parsed_func.header. a_name)); slang_function_destruct(&parsed_func); - return 0; + return GL_FALSE; } /* destroy the existing function declaration and replace it @@ -1851,16 +1739,17 @@ parse_function(slang_parse_ctx * C, slang_output_ctx * O, int definition, { slang_assemble_ctx A; - A.file = O->assembly; - A.mach = O->machine; A.atoms = C->atoms; A.space.funcs = O->funs; A.space.structs = O->structs; A.space.vars = O->vars; - if (!_slang_assemble_function(&A, *parsed_func_ret)) - return 0; + A.program = O->program; + A.vartable = O->vartable; + A.log = C->L; + + _slang_codegen_function(&A, *parsed_func_ret); } - return 1; + return GL_TRUE; } /* declaration */ @@ -1895,17 +1784,32 @@ parse_declaration(slang_parse_ctx * C, slang_output_ctx * O) #define EXTERNAL_DECLARATION 2 static GLboolean -parse_code_unit(slang_parse_ctx * C, slang_code_unit * unit) +parse_code_unit(slang_parse_ctx * C, slang_code_unit * unit, + struct gl_program *program) { + GET_CURRENT_CONTEXT(ctx); slang_output_ctx o; + GLboolean success; + GLuint maxRegs; + + 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); + maxRegs = ctx->Const.VertexProgram.MaxTemps; + } /* setup output context */ o.funs = &unit->funs; o.structs = &unit->structs; o.vars = &unit->vars; - o.assembly = &unit->object->assembly; o.global_pool = &unit->object->varpool; - o.machine = &unit->object->machine; + o.program = program; + o.vartable = _slang_new_var_table(maxRegs); + _slang_push_var_table(o.vartable); /* parse individual functions and declarations */ while (*C->I != EXTERNAL_NULL) { @@ -1913,27 +1817,33 @@ parse_code_unit(slang_parse_ctx * C, slang_code_unit * unit) case EXTERNAL_FUNCTION_DEFINITION: { slang_function *func; - - if (!parse_function(C, &o, 1, &func)) - return 0; + success = parse_function(C, &o, 1, &func); } break; case EXTERNAL_DECLARATION: - if (!parse_declaration(C, &o)) - return 0; + success = parse_declaration(C, &o); break; default: - return 0; + success = GL_FALSE; + } + + if (!success) { + /* xxx free codegen */ + _slang_pop_var_table(o.vartable); + return GL_FALSE; } } C->I++; - return 1; + + _slang_pop_var_table(o.vartable); + return GL_TRUE; } static GLboolean compile_binary(const byte * prod, slang_code_unit * unit, slang_unit_type type, slang_info_log * infolog, - slang_code_unit * builtin, slang_code_unit * downlink) + slang_code_unit * builtin, slang_code_unit * downlink, + struct gl_program *program) { slang_parse_ctx C; @@ -1945,6 +1855,7 @@ compile_binary(const byte * prod, slang_code_unit * unit, C.parsing_builtin = (builtin == NULL); C.global_scope = GL_TRUE; C.atoms = &unit->object->atompool; + C.type = type; if (!check_revision(&C)) return GL_FALSE; @@ -1956,13 +1867,14 @@ compile_binary(const byte * prod, slang_code_unit * unit, } /* parse translation unit */ - return parse_code_unit(&C, unit); + return parse_code_unit(&C, unit, program); } static GLboolean compile_with_grammar(grammar id, const char *source, slang_code_unit * unit, slang_unit_type type, slang_info_log * infolog, - slang_code_unit * builtin) + slang_code_unit * builtin, + struct gl_program *program) { byte *prod; GLuint size, start, version; @@ -1987,23 +1899,34 @@ compile_with_grammar(grammar id, const char *source, slang_code_unit * unit, } /* Finally check the syntax and generate its binary representation. */ - if (!grammar_fast_check - (id, (const byte *) (slang_string_cstr(&preprocessed)), &prod, &size, - 65536)) { + if (!grammar_fast_check(id, + (const byte *) (slang_string_cstr(&preprocessed)), + &prod, &size, 65536)) { char buf[1024]; GLint pos; slang_string_free(&preprocessed); grammar_get_last_error((byte *) (buf), sizeof(buf), &pos); slang_info_log_error(infolog, buf); + /* syntax error (possibly in library code) */ +#if 0 + { + int line, col; + char *s; + s = (char *) _mesa_find_line_column((const GLubyte *) source, + (const GLubyte *) source + pos, + &line, &col); + printf("Error on line %d, col %d: %s\n", line, col, s); + } +#endif return GL_FALSE; } slang_string_free(&preprocessed); /* Syntax is okay - translate it to internal representation. */ - if (!compile_binary - (prod, unit, type, infolog, builtin, - &builtin[SLANG_BUILTIN_TOTAL - 1])) { + if (!compile_binary(prod, unit, type, infolog, builtin, + &builtin[SLANG_BUILTIN_TOTAL - 1], + program)) { grammar_alloc_free(prod); return GL_FALSE; } @@ -2031,15 +1954,10 @@ static const byte slang_vertex_builtin_gc[] = { #include "library/slang_vertex_builtin_gc.h" }; -#if defined(USE_X86_ASM) || defined(SLANG_X86) -static const byte slang_builtin_vec4_gc[] = { -#include "library/slang_builtin_vec4_gc.h" -}; -#endif - static GLboolean compile_object(grammar * id, const char *source, slang_code_object * object, - slang_unit_type type, slang_info_log * infolog) + slang_unit_type type, slang_info_log * infolog, + struct gl_program *program) { slang_code_unit *builtins = NULL; @@ -2055,8 +1973,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); @@ -2065,84 +1983,133 @@ 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, NULL, NULL)) + if (!compile_binary(slang_core_gc, + &object->builtin[SLANG_BUILTIN_CORE], + 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, - &object->builtin[SLANG_BUILTIN_CORE])) + if (!compile_binary(slang_common_builtin_gc, + &object->builtin[SLANG_BUILTIN_COMMON], + 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 (!compile_binary - (slang_fragment_builtin_gc, - &object->builtin[SLANG_BUILTIN_TARGET], - slang_unit_fragment_builtin, infolog, NULL, - &object->builtin[SLANG_BUILTIN_COMMON])) + if (type == SLANG_UNIT_FRAGMENT_SHADER) { + if (!compile_binary(slang_fragment_builtin_gc, + &object->builtin[SLANG_BUILTIN_TARGET], + SLANG_UNIT_FRAGMENT_BUILTIN, infolog, NULL, + &object->builtin[SLANG_BUILTIN_COMMON], NULL)) return GL_FALSE; } - 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, - &object->builtin[SLANG_BUILTIN_COMMON])) + 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, + &object->builtin[SLANG_BUILTIN_COMMON], NULL)) return GL_FALSE; } -#if defined(USE_X86_ASM) || defined(SLANG_X86) - /* compile x86 4-component vector overrides, link to target */ - if (!compile_binary - (slang_builtin_vec4_gc, &object->builtin[SLANG_BUILTIN_VEC4], - slang_unit_fragment_builtin, infolog, NULL, - &object->builtin[SLANG_BUILTIN_TARGET])) - return GL_FALSE; -#endif - /* disable language extensions */ +#if NEW_SLANG /* allow-built-ins */ + grammar_set_reg8(*id, (const byte *) "parsing_builtin", 1); +#else grammar_set_reg8(*id, (const byte *) "parsing_builtin", 0); +#endif builtins = object->builtin; } /* compile the actual shader - pass-in built-in library for external shader */ return compile_with_grammar(*id, source, &object->unit, type, infolog, - builtins); + builtins, program); } -GLboolean -_slang_compile(const char *source, slang_code_object * object, - slang_unit_type type, slang_info_log * infolog) + +static GLboolean +compile_shader(GLcontext *ctx, slang_code_object * object, + slang_unit_type type, slang_info_log * infolog, + struct gl_shader *shader) { + struct gl_program *program = shader->Programs[0]; GLboolean success; grammar id = 0; + assert(program); + _slang_code_object_dtr(object); _slang_code_object_ctr(object); - success = compile_object(&id, source, object, type, infolog); + success = compile_object(&id, shader->Source, object, type, infolog, program); if (id != 0) grammar_destroy(id); if (!success) return GL_FALSE; - if (!_slang_build_export_data_table(&object->expdata, &object->unit.vars)) - return GL_FALSE; - if (!_slang_build_export_code_table - (&object->expcode, &object->unit.funs, &object->unit)) - return GL_FALSE; + return GL_TRUE; +} -#if defined(USE_X86_ASM) || defined(SLANG_X86) - /* XXX: lookup the @main label */ - if (!_slang_x86_codegen - (&object->machine, &object->assembly, - object->expcode.entries[0].address)) - return GL_FALSE; -#endif - return GL_TRUE; + +GLboolean +_slang_compile(GLcontext *ctx, struct gl_shader *shader) +{ + GLboolean success; + slang_info_log info_log; + slang_code_object obj; + slang_unit_type type; + + if (shader->Type == GL_VERTEX_SHADER) { + type = SLANG_UNIT_VERTEX_SHADER; + } + else { + assert(shader->Type == GL_FRAGMENT_SHADER); + type = SLANG_UNIT_FRAGMENT_SHADER; + } + + /* XXX temporary hack */ + if (!shader->Programs) { + GLenum progTarget; + if (shader->Type == GL_VERTEX_SHADER) + progTarget = GL_VERTEX_PROGRAM_ARB; + else + progTarget = GL_FRAGMENT_PROGRAM_ARB; + shader->Programs + = (struct gl_program **) malloc(sizeof(struct gl_program*)); + shader->Programs[0] = _mesa_new_program(ctx, progTarget, 1); + shader->NumPrograms = 1; + + shader->Programs[0]->Parameters = _mesa_new_parameter_list(); + shader->Programs[0]->Varying = _mesa_new_parameter_list(); + shader->Programs[0]->Attributes = _mesa_new_parameter_list(); + } + + slang_info_log_construct(&info_log); + _slang_code_object_ctr(&obj); + + success = compile_shader(ctx, &obj, type, &info_log, shader); + + /* free shader's prev info log */ + if (shader->InfoLog) { + _mesa_free(shader->InfoLog); + shader->InfoLog = NULL; + } + + if (info_log.text) { + /* copy info-log string to shader object */ + shader->InfoLog = _mesa_strdup(info_log.text); + } + + if (info_log.error_flag) { + success = GL_FALSE; + } + + slang_info_log_destruct(&info_log); + _slang_code_object_dtr(&obj); + + return success; } + diff --git a/src/mesa/shader/slang/slang_compile.h b/src/mesa/shader/slang/slang_compile.h index 02987f4e1b..086e2d8dc4 100644 --- a/src/mesa/shader/slang/slang_compile.h +++ b/src/mesa/shader/slang/slang_compile.h @@ -25,8 +25,9 @@ #if !defined SLANG_COMPILE_H #define SLANG_COMPILE_H -#include "slang_export.h" -#include "slang_execute.h" +#include "imports.h" +#include "mtypes.h" +#include "slang_typeinfo.h" #include "slang_compile_variable.h" #include "slang_compile_struct.h" #include "slang_compile_operation.h" @@ -38,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; @@ -58,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_ *); @@ -68,23 +72,14 @@ _slang_code_unit_dtr (slang_code_unit *); #define SLANG_BUILTIN_COMMON 1 #define SLANG_BUILTIN_TARGET 2 -#if defined(USE_X86_ASM) || defined(SLANG_X86) -#define SLANG_BUILTIN_VEC4 3 -#define SLANG_BUILTIN_TOTAL 4 -#else #define SLANG_BUILTIN_TOTAL 3 -#endif typedef struct slang_code_object_ { slang_code_unit builtin[SLANG_BUILTIN_TOTAL]; slang_code_unit unit; - slang_assembly_file assembly; - slang_machine machine; slang_var_pool varpool; slang_atom_pool atompool; - slang_export_data_table expdata; - slang_export_code_table expcode; } slang_code_object; extern GLvoid @@ -93,21 +88,8 @@ _slang_code_object_ctr (slang_code_object *); extern GLvoid _slang_code_object_dtr (slang_code_object *); -typedef struct slang_info_log_ -{ - char *text; - int dont_free_text; -} slang_info_log; - -void slang_info_log_construct (slang_info_log *); -void slang_info_log_destruct (slang_info_log *); -int slang_info_log_print (slang_info_log *, const char *, ...); -int slang_info_log_error (slang_info_log *, const char *, ...); -int slang_info_log_warning (slang_info_log *, const char *, ...); -void slang_info_log_memory (slang_info_log *); - extern GLboolean -_slang_compile (const char *, slang_code_object *, slang_unit_type, slang_info_log *); +_slang_compile (GLcontext *ctx, struct gl_shader *shader); #ifdef __cplusplus } diff --git a/src/mesa/shader/slang/slang_compile_function.c b/src/mesa/shader/slang/slang_compile_function.c index e6e0d89ddb..2f74050b86 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; @@ -127,6 +127,16 @@ slang_function_scope_destruct(slang_function_scope * scope) /** + * Does this function have a non-void return value? + */ +GLboolean +_slang_function_has_return_value(const slang_function *fun) +{ + return fun->header.type.specifier.type != SLANG_SPEC_VOID; +} + + +/** * Search a list of functions for a particular function by name. * \param funcs the list of functions to search * \param a_name the name to search for @@ -166,69 +176,40 @@ slang_function_scope_find(slang_function_scope * funcs, slang_function * fun, for (i = 0; i < funcs->num_functions; i++) { slang_function *f = &funcs->functions[i]; + const GLuint haveRetValue = 0; +#if 0 + = (f->header.type.specifier.type != SLANG_SPEC_VOID); +#endif unsigned int j; + /* + printf("Compare name %s to %s (ret %u, %d, %d)\n", + (char *) fun->header.a_name, (char *) f->header.a_name, + haveRetValue, + fun->param_count, f->param_count); + */ + if (fun->header.a_name != f->header.a_name) continue; if (fun->param_count != f->param_count) continue; - for (j = 0; j < fun->param_count; j++) { + for (j = haveRetValue; j < fun->param_count; j++) { if (!slang_type_specifier_equal - (&fun->parameters->variables[j].type.specifier, - &f->parameters->variables[j].type.specifier)) + (&fun->parameters->variables[j]->type.specifier, + &f->parameters->variables[j]->type.specifier)) break; } - if (j == fun->param_count) + if (j == fun->param_count) { + /* + printf("Found match\n"); + */ return f; + } } + /* + printf("Not found\n"); + */ if (all_scopes && funcs->outer_scope != NULL) return slang_function_scope_find(funcs->outer_scope, fun, 1); return NULL; } - -/* - * _slang_build_export_code_table() - */ - -GLboolean -_slang_build_export_code_table(slang_export_code_table * tbl, - slang_function_scope * funs, - slang_code_unit * unit) -{ - slang_atom mainAtom; - GLuint i; - - mainAtom = slang_atom_pool_atom(tbl->atoms, "main"); - if (mainAtom == SLANG_ATOM_NULL) - return GL_FALSE; - - for (i = 0; i < funs->num_functions; i++) { - if (funs->functions[i].header.a_name == mainAtom) { - slang_function *fun = &funs->functions[i]; - slang_export_code_entry *e; - slang_assemble_ctx A; - - e = slang_export_code_table_add(tbl); - if (e == NULL) - return GL_FALSE; - e->address = unit->object->assembly.count; - e->name = slang_atom_pool_atom(tbl->atoms, "@main"); - if (e->name == SLANG_ATOM_NULL) - return GL_FALSE; - - A.file = &unit->object->assembly; - A.mach = &unit->object->machine; - A.atoms = &unit->object->atompool; - A.space.funcs = &unit->funs; - A.space.structs = &unit->structs; - A.space.vars = &unit->vars; - slang_assembly_file_push_label(&unit->object->assembly, - slang_asm_local_alloc, 20); - slang_assembly_file_push_label(&unit->object->assembly, - slang_asm_enter, 20); - _slang_assemble_function_call(&A, fun, NULL, 0, GL_FALSE); - slang_assembly_file_push(&unit->object->assembly, slang_asm_exit); - } - } - return GL_TRUE; -} diff --git a/src/mesa/shader/slang/slang_compile_function.h b/src/mesa/shader/slang/slang_compile_function.h index c05c6f4d85..a59b094e08 100644 --- a/src/mesa/shader/slang/slang_compile_function.h +++ b/src/mesa/shader/slang/slang_compile_function.h @@ -25,9 +25,6 @@ #ifndef SLANG_COMPILE_FUNCTION_H #define SLANG_COMPILE_FUNCTION_H -#if defined __cplusplus -extern "C" { -#endif struct slang_code_unit_; @@ -36,9 +33,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; @@ -92,20 +89,13 @@ _slang_function_scope_ctr(slang_function_scope *); extern void slang_function_scope_destruct(slang_function_scope *); +extern GLboolean +_slang_function_has_return_value(const slang_function *fun); + extern int slang_function_scope_find_by_name(slang_function_scope *, slang_atom, int); extern slang_function * slang_function_scope_find(slang_function_scope *, slang_function *, int); -extern GLboolean -_slang_build_export_code_table(slang_export_code_table *, - slang_function_scope *, - struct slang_code_unit_ *); - - -#ifdef __cplusplus -} -#endif - #endif /* SLANG_COMPILE_FUNCTION_H */ diff --git a/src/mesa/shader/slang/slang_compile_operation.c b/src/mesa/shader/slang/slang_compile_operation.c index 73f57bfb12..410d215a8d 100644 --- a/src/mesa/shader/slang/slang_compile_operation.c +++ b/src/mesa/shader/slang/slang_compile_operation.c @@ -38,17 +38,18 @@ 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 = (float) 0; + oper->literal[0] = 0.0; + oper->literal_size = 1; oper->a_id = SLANG_ATOM_NULL; - oper->locals = - (slang_variable_scope *) - slang_alloc_malloc(sizeof(slang_variable_scope)); + oper->locals = _slang_variable_scope_new(NULL); if (oper->locals == NULL) return GL_FALSE; _slang_variable_scope_ctr(oper->locals); + oper->fun = NULL; + oper->var = NULL; return GL_TRUE; } @@ -62,6 +63,9 @@ slang_operation_destruct(slang_operation * oper) slang_alloc_free(oper->children); slang_variable_scope_destruct(oper->locals); slang_alloc_free(oper->locals); + oper->children = NULL; + oper->num_children = 0; + oper->locals = NULL; } /** @@ -96,12 +100,24 @@ slang_operation_copy(slang_operation * x, const slang_operation * y) return GL_FALSE; } } - z.literal = y->literal; + z.literal[0] = y->literal[0]; + z.literal[1] = y->literal[1]; + z.literal[2] = y->literal[2]; + z.literal[3] = y->literal[3]; + z.literal_size = y->literal_size; + assert(y->literal_size >= 1); + assert(y->literal_size <= 4); z.a_id = y->a_id; - if (!slang_variable_scope_copy(z.locals, y->locals)) { - slang_operation_destruct(&z); - return GL_FALSE; + if (y->locals) { + if (!slang_variable_scope_copy(z.locals, y->locals)) { + slang_operation_destruct(&z); + return GL_FALSE; + } } +#if 0 + z.var = y->var; + z.fun = y->fun; +#endif slang_operation_destruct(x); *x = z; return GL_TRUE; @@ -111,5 +127,98 @@ slang_operation_copy(slang_operation * x, const slang_operation * y) slang_operation * slang_operation_new(GLuint count) { - return (slang_operation *) _mesa_calloc(count * sizeof(slang_operation)); + slang_operation *ops + = (slang_operation *) _mesa_malloc(count * sizeof(slang_operation)); + assert(count > 0); + if (ops) { + GLuint i; + for (i = 0; i < count; i++) + slang_operation_construct(ops + i); + } + return ops; } + + +/** + * Delete operation and all children + */ +void +slang_operation_delete(slang_operation *oper) +{ + slang_operation_destruct(oper); + _mesa_free(oper); +} + + +slang_operation * +slang_operation_grow(GLuint *numChildren, slang_operation **children) +{ + slang_operation *ops; + + ops = (slang_operation *) + slang_alloc_realloc(*children, + *numChildren * sizeof(slang_operation), + (*numChildren + 1) * sizeof(slang_operation)); + if (ops) { + slang_operation *newOp = ops + *numChildren; + if (!slang_operation_construct(newOp)) { + _mesa_free(ops); + *children = NULL; + return NULL; + } + *children = ops; + (*numChildren)++; + return newOp; + } + return NULL; +} + +/** + * Insert a new slang_operation into an array. + * \param numChildren pointer to current number of children (in/out) + * \param children address of array (in/out) + * \param pos position to insert + * \return pointer to the new operation + */ +slang_operation * +slang_operation_insert(GLuint *numChildren, slang_operation **children, + GLuint pos) +{ + slang_operation *ops; + + assert(pos <= *numChildren); + + ops = (slang_operation *) + _mesa_malloc((*numChildren + 1) * sizeof(slang_operation)); + if (ops) { + slang_operation *newOp; + newOp = ops + pos; + if (pos > 0) + _mesa_memcpy(ops, *children, pos * sizeof(slang_operation)); + if (pos < *numChildren) + _mesa_memcpy(newOp + 1, (*children) + pos, + (*numChildren - pos) * sizeof(slang_operation)); + + if (!slang_operation_construct(newOp)) { + _mesa_free(ops); + *numChildren = 0; + *children = NULL; + return NULL; + } + *children = ops; + (*numChildren)++; + return newOp; + } + return NULL; +} + + +void +_slang_operation_swap(slang_operation *oper0, slang_operation *oper1) +{ + slang_operation tmp = *oper0; + *oper0 = *oper1; + *oper1 = tmp; +} + + diff --git a/src/mesa/shader/slang/slang_compile_operation.h b/src/mesa/shader/slang/slang_compile_operation.h index a9376ec945..3bed3218a6 100644 --- a/src/mesa/shader/slang/slang_compile_operation.h +++ b/src/mesa/shader/slang/slang_compile_operation.h @@ -25,10 +25,6 @@ #ifndef SLANG_COMPILE_OPERATION_H #define SLANG_COMPILE_OPERATION_H -#if defined __cplusplus -extern "C" { -#endif - /** * Types of slang operations. @@ -37,68 +33,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_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; @@ -114,9 +112,13 @@ typedef struct slang_operation_ slang_operation_type type; struct slang_operation_ *children; GLuint num_children; - GLfloat literal; /**< Used for float, int and bool values */ - slang_atom a_id; /**< type: asm, identifier, call, field */ - slang_variable_scope *locals; /**< local vars for scope */ + GLfloat literal[4]; /**< Used for float, int and bool values */ + 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_variable_ *var; /**< If type == slang_oper_identier */ + struct slang_label_ *label; /**< If type == SLANG_OPER_LABEL or GOTO */ } slang_operation; @@ -132,9 +134,18 @@ slang_operation_copy(slang_operation *, const slang_operation *); extern slang_operation * slang_operation_new(GLuint count); +extern void +slang_operation_delete(slang_operation *oper); + +extern slang_operation * +slang_operation_grow(GLuint *numChildren, slang_operation **children); + +extern slang_operation * +slang_operation_insert(GLuint *numChildren, slang_operation **children, + GLuint pos); + +extern void +_slang_operation_swap(slang_operation *oper0, slang_operation *oper1); -#ifdef __cplusplus -} -#endif #endif /* SLANG_COMPILE_OPERATION_H */ diff --git a/src/mesa/shader/slang/slang_compile_struct.c b/src/mesa/shader/slang/slang_compile_struct.c index 15585a62af..89c79d431b 100644 --- a/src/mesa/shader/slang/slang_compile_struct.c +++ b/src/mesa/shader/slang/slang_compile_struct.c @@ -1,8 +1,8 @@ /* * Mesa 3-D graphics library - * Version: 6.5 + * Version: 6.5.3 * - * Copyright (C) 2005-2006 Brian Paul All Rights Reserved. + * Copyright (C) 2005-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"), @@ -31,139 +31,143 @@ #include "imports.h" #include "slang_compile.h" -/* - * slang_struct_scope - */ GLvoid -_slang_struct_scope_ctr (slang_struct_scope *self) +_slang_struct_scope_ctr(slang_struct_scope * self) { self->structs = NULL; self->num_structs = 0; self->outer_scope = NULL; } -void slang_struct_scope_destruct (slang_struct_scope *scope) +void +slang_struct_scope_destruct(slang_struct_scope * scope) { - unsigned int i; + GLuint i; - for (i = 0; i < scope->num_structs; i++) - slang_struct_destruct (scope->structs + i); - slang_alloc_free (scope->structs); - /* do not free scope->outer_scope */ + for (i = 0; i < scope->num_structs; i++) + slang_struct_destruct(scope->structs + i); + slang_alloc_free(scope->structs); + /* do not free scope->outer_scope */ } -int slang_struct_scope_copy (slang_struct_scope *x, const slang_struct_scope *y) +int +slang_struct_scope_copy(slang_struct_scope * x, const slang_struct_scope * y) { - slang_struct_scope z; - unsigned int i; - - _slang_struct_scope_ctr (&z); - z.structs = (slang_struct *) slang_alloc_malloc (y->num_structs * sizeof (slang_struct)); - if (z.structs == NULL) - { - slang_struct_scope_destruct (&z); - return 0; - } - for (z.num_structs = 0; z.num_structs < y->num_structs; z.num_structs++) - if (!slang_struct_construct (&z.structs[z.num_structs])) - { - slang_struct_scope_destruct (&z); - return 0; - } - for (i = 0; i < z.num_structs; i++) - if (!slang_struct_copy (&z.structs[i], &y->structs[i])) - { - slang_struct_scope_destruct (&z); - return 0; - } - z.outer_scope = y->outer_scope; - slang_struct_scope_destruct (x); - *x = z; - return 1; + slang_struct_scope z; + GLuint i; + + _slang_struct_scope_ctr(&z); + z.structs = + (slang_struct *) slang_alloc_malloc(y->num_structs * + sizeof(slang_struct)); + if (z.structs == NULL) { + slang_struct_scope_destruct(&z); + return 0; + } + for (z.num_structs = 0; z.num_structs < y->num_structs; z.num_structs++) + if (!slang_struct_construct(&z.structs[z.num_structs])) { + slang_struct_scope_destruct(&z); + return 0; + } + for (i = 0; i < z.num_structs; i++) + if (!slang_struct_copy(&z.structs[i], &y->structs[i])) { + slang_struct_scope_destruct(&z); + return 0; + } + z.outer_scope = y->outer_scope; + slang_struct_scope_destruct(x); + *x = z; + return 1; } -slang_struct *slang_struct_scope_find (slang_struct_scope *stru, slang_atom a_name, int all_scopes) +slang_struct * +slang_struct_scope_find(slang_struct_scope * stru, slang_atom a_name, + int all_scopes) { - unsigned int i; - - for (i = 0; i < stru->num_structs; i++) - if (a_name == stru->structs[i].a_name) - return &stru->structs[i]; - if (all_scopes && stru->outer_scope != NULL) - return slang_struct_scope_find (stru->outer_scope, a_name, 1); - return NULL; + GLuint i; + + for (i = 0; i < stru->num_structs; i++) + if (a_name == stru->structs[i].a_name) + return &stru->structs[i]; + if (all_scopes && stru->outer_scope != NULL) + return slang_struct_scope_find(stru->outer_scope, a_name, 1); + return NULL; } /* slang_struct */ -int slang_struct_construct (slang_struct *stru) +int +slang_struct_construct(slang_struct * stru) { - stru->a_name = SLANG_ATOM_NULL; - stru->fields = (slang_variable_scope *) slang_alloc_malloc (sizeof (slang_variable_scope)); - if (stru->fields == NULL) - return 0; - _slang_variable_scope_ctr (stru->fields); - stru->structs = (slang_struct_scope *) slang_alloc_malloc (sizeof (slang_struct_scope)); - if (stru->structs == NULL) - { - slang_variable_scope_destruct (stru->fields); - slang_alloc_free (stru->fields); - return 0; - } - _slang_struct_scope_ctr (stru->structs); - return 1; + stru->a_name = SLANG_ATOM_NULL; + stru->fields = (slang_variable_scope *) + slang_alloc_malloc(sizeof(slang_variable_scope)); + if (stru->fields == NULL) + return 0; + _slang_variable_scope_ctr(stru->fields); + + stru->structs = + (slang_struct_scope *) slang_alloc_malloc(sizeof(slang_struct_scope)); + if (stru->structs == NULL) { + slang_variable_scope_destruct(stru->fields); + slang_alloc_free(stru->fields); + return 0; + } + _slang_struct_scope_ctr(stru->structs); + return 1; } -void slang_struct_destruct (slang_struct *stru) +void +slang_struct_destruct(slang_struct * stru) { - slang_variable_scope_destruct (stru->fields); - slang_alloc_free (stru->fields); - slang_struct_scope_destruct (stru->structs); - slang_alloc_free (stru->structs); + slang_variable_scope_destruct(stru->fields); + slang_alloc_free(stru->fields); + slang_struct_scope_destruct(stru->structs); + slang_alloc_free(stru->structs); } -int slang_struct_copy (slang_struct *x, const slang_struct *y) +int +slang_struct_copy(slang_struct * x, const slang_struct * y) { - slang_struct z; - - if (!slang_struct_construct (&z)) - return 0; - z.a_name = y->a_name; - if (!slang_variable_scope_copy (z.fields, y->fields)) - { - slang_struct_destruct (&z); - return 0; - } - if (!slang_struct_scope_copy (z.structs, y->structs)) - { - slang_struct_destruct (&z); - return 0; - } - slang_struct_destruct (x); - *x = z; - return 1; + slang_struct z; + + if (!slang_struct_construct(&z)) + return 0; + z.a_name = y->a_name; + if (!slang_variable_scope_copy(z.fields, y->fields)) { + slang_struct_destruct(&z); + return 0; + } + if (!slang_struct_scope_copy(z.structs, y->structs)) { + slang_struct_destruct(&z); + return 0; + } + slang_struct_destruct(x); + *x = z; + return 1; } -int slang_struct_equal (const slang_struct *x, const slang_struct *y) +int +slang_struct_equal(const slang_struct * x, const slang_struct * y) { - unsigned int i; - - if (x->fields->num_variables != y->fields->num_variables) - return 0; - for (i = 0; i < x->fields->num_variables; i++) - { - slang_variable *varx = &x->fields->variables[i]; - slang_variable *vary = &y->fields->variables[i]; - - if (varx->a_name != vary->a_name) - 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->array_len != vary->array_len) - return GL_FALSE; - } - return 1; + GLuint i; + + if (x->fields->num_variables != y->fields->num_variables) + return 0; + + for (i = 0; i < x->fields->num_variables; i++) { + const slang_variable *varx = x->fields->variables[i]; + const slang_variable *vary = y->fields->variables[i]; + + if (varx->a_name != vary->a_name) + 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->array_len != vary->array_len) + return GL_FALSE; + } + return 1; } - diff --git a/src/mesa/shader/slang/slang_compile_variable.c b/src/mesa/shader/slang/slang_compile_variable.c index a8a2d6aa6a..9a0b985507 100644 --- a/src/mesa/shader/slang/slang_compile_variable.c +++ b/src/mesa/shader/slang/slang_compile_variable.c @@ -1,8 +1,8 @@ /* * Mesa 3-D graphics library - * Version: 6.5 + * Version: 6.5.3 * - * Copyright (C) 2005-2006 Brian Paul All Rights Reserved. + * Copyright (C) 2005-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"), @@ -40,29 +40,31 @@ 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}, + {"sampler2DRect", SLANG_SPEC_SAMPLER2DRECT}, + {"sampler2DRectShadow", SLANG_SPEC_SAMPLER2DRECTSHADOW}, + {NULL, SLANG_SPEC_VOID} }; slang_type_specifier_type @@ -94,7 +96,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; } @@ -123,10 +125,43 @@ slang_fully_specified_type_copy(slang_fully_specified_type * x, return 1; } + +static slang_variable * +slang_variable_new(void) +{ + slang_variable *v = (slang_variable *) malloc(sizeof(slang_variable)); + if (v) { + if (!slang_variable_construct(v)) { + free(v); + v = NULL; + } + } + return v; +} + + +static void +slang_variable_delete(slang_variable * var) +{ + slang_variable_destruct(var); + free(var); +} + + /* * slang_variable_scope */ +slang_variable_scope * +_slang_variable_scope_new(slang_variable_scope *parent) +{ + slang_variable_scope *s; + s = (slang_variable_scope *) _mesa_calloc(sizeof(slang_variable_scope)); + s->outer_scope = parent; + return s; +} + + GLvoid _slang_variable_scope_ctr(slang_variable_scope * self) { @@ -142,8 +177,10 @@ slang_variable_scope_destruct(slang_variable_scope * scope) if (!scope) return; - for (i = 0; i < scope->num_variables; i++) - slang_variable_destruct(scope->variables + i); + for (i = 0; i < scope->num_variables; i++) { + if (scope->variables[i]) + slang_variable_delete(scope->variables[i]); + } slang_alloc_free(scope->variables); /* do not free scope->outer_scope */ } @@ -156,21 +193,22 @@ slang_variable_scope_copy(slang_variable_scope * x, unsigned int i; _slang_variable_scope_ctr(&z); - z.variables = (slang_variable *) - slang_alloc_malloc(y->num_variables * sizeof(slang_variable)); + z.variables = (slang_variable **) + _mesa_calloc(y->num_variables * sizeof(slang_variable *)); if (z.variables == NULL) { slang_variable_scope_destruct(&z); return 0; } for (z.num_variables = 0; z.num_variables < y->num_variables; z.num_variables++) { - if (!slang_variable_construct(&z.variables[z.num_variables])) { + z.variables[z.num_variables] = slang_variable_new(); + if (!z.variables[z.num_variables]) { slang_variable_scope_destruct(&z); return 0; } } for (i = 0; i < z.num_variables; i++) { - if (!slang_variable_copy(&z.variables[i], &y->variables[i])) { + if (!slang_variable_copy(z.variables[i], y->variables[i])) { slang_variable_scope_destruct(&z); return 0; } @@ -190,19 +228,20 @@ slang_variable * slang_variable_scope_grow(slang_variable_scope *scope) { const int n = scope->num_variables; - scope->variables = (slang_variable *) + scope->variables = (slang_variable **) slang_alloc_realloc(scope->variables, - n * sizeof(slang_variable), - (n + 1) * sizeof(slang_variable)); + n * sizeof(slang_variable *), + (n + 1) * sizeof(slang_variable *)); if (!scope->variables) return NULL; scope->num_variables++; - if (!slang_variable_construct(scope->variables + n)) + scope->variables[n] = slang_variable_new(); + if (!scope->variables[n]) return NULL; - return scope->variables + n; + return scope->variables[n]; } @@ -218,12 +257,13 @@ slang_variable_construct(slang_variable * var) var->array_len = 0; var->initializer = NULL; var->address = ~0; - var->address2 = 0; var->size = 0; - var->global = GL_FALSE; + var->isTemp = GL_FALSE; + var->aux = NULL; return 1; } + void slang_variable_destruct(slang_variable * var) { @@ -232,8 +272,14 @@ slang_variable_destruct(slang_variable * var) slang_operation_destruct(var->initializer); slang_alloc_free(var->initializer); } +#if 0 + if (var->aux) { + _mesa_free(var->aux); + } +#endif } + int slang_variable_copy(slang_variable * x, const slang_variable * y) { @@ -248,8 +294,8 @@ slang_variable_copy(slang_variable * x, const slang_variable * y) z.a_name = y->a_name; z.array_len = y->array_len; if (y->initializer != NULL) { - z.initializer = - (slang_operation *) slang_alloc_malloc(sizeof(slang_operation)); + z.initializer + = (slang_operation *) slang_alloc_malloc(sizeof(slang_operation)); if (z.initializer == NULL) { slang_variable_destruct(&z); return 0; @@ -266,12 +312,12 @@ slang_variable_copy(slang_variable * x, const slang_variable * y) } z.address = y->address; z.size = y->size; - z.global = y->global; slang_variable_destruct(x); *x = z; return 1; } + slang_variable * _slang_locate_variable(const slang_variable_scope * scope, const slang_atom a_name, GLboolean all) @@ -279,130 +325,65 @@ _slang_locate_variable(const slang_variable_scope * scope, GLuint i; for (i = 0; i < scope->num_variables; i++) - if (a_name == scope->variables[i].a_name) - return &scope->variables[i]; + if (a_name == scope->variables[i]->a_name) + return scope->variables[i]; if (all && scope->outer_scope != NULL) return _slang_locate_variable(scope->outer_scope, a_name, 1); return NULL; } -/* - * _slang_build_export_data_table() - */ - +#if 0 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; } } +#endif -static GLboolean -build_quant(slang_export_data_quant * q, const slang_variable * var) -{ - const slang_type_specifier *spec = &var->type.specifier; - - q->name = var->a_name; - q->size = var->size; - if (spec->type == slang_spec_array) { - q->array_len = var->array_len; - q->size /= var->array_len; - spec = spec->_array; - } - if (spec->type == slang_spec_struct) { - GLuint i; - - q->u.field_count = spec->_struct->fields->num_variables; - q->structure = (slang_export_data_quant *) - slang_alloc_malloc(q->u.field_count - * sizeof(slang_export_data_quant)); - if (q->structure == NULL) - return GL_FALSE; - - for (i = 0; i < q->u.field_count; i++) - slang_export_data_quant_ctr(&q->structure[i]); - for (i = 0; i < q->u.field_count; i++) { - if (!build_quant(&q->structure[i], - &spec->_struct->fields->variables[i])) - return GL_FALSE; - } - } - else - q->u.basic_type = gl_type_from_specifier(spec); - return GL_TRUE; -} - -GLboolean -_slang_build_export_data_table(slang_export_data_table * tbl, - slang_variable_scope * vars) -{ - GLuint i; - - for (i = 0; i < vars->num_variables; i++) { - const slang_variable *var = &vars->variables[i]; - slang_export_data_entry *e; - - e = slang_export_data_table_add(tbl); - if (e == NULL) - return GL_FALSE; - if (!build_quant(&e->quant, var)) - return GL_FALSE; - if (var->type.qualifier == slang_qual_uniform) - e->access = slang_exp_uniform; - else if (var->type.qualifier == slang_qual_attribute) - e->access = slang_exp_attribute; - else - e->access = slang_exp_varying; - e->address = var->address; - } - - if (vars->outer_scope != NULL) - return _slang_build_export_data_table(tbl, vars->outer_scope); - return GL_TRUE; -} diff --git a/src/mesa/shader/slang/slang_compile_variable.h b/src/mesa/shader/slang/slang_compile_variable.h index b0910e855e..d3691f0f51 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,12 +75,11 @@ 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 address2; /**< Storage location */ GLuint size; /**< Variable's size in bytes */ - GLboolean global; /**< A global var? */ + GLboolean isTemp; /**< a named temporary (__resultTmp) */ void *aux; /**< Used during code gen */ } slang_variable; @@ -90,11 +89,15 @@ typedef struct slang_variable_ */ typedef struct slang_variable_scope_ { - slang_variable *variables; /**< Array [num_variables] */ + slang_variable **variables; /**< Array [num_variables] of ptrs to vars */ GLuint num_variables; struct slang_variable_scope_ *outer_scope; } slang_variable_scope; + +extern slang_variable_scope * +_slang_variable_scope_new(slang_variable_scope *parent); + extern GLvoid _slang_variable_scope_ctr(slang_variable_scope *); @@ -105,7 +108,7 @@ extern int slang_variable_scope_copy(slang_variable_scope *, const slang_variable_scope *); -slang_variable * +extern slang_variable * slang_variable_scope_grow(slang_variable_scope *); extern int @@ -121,11 +124,6 @@ extern slang_variable * _slang_locate_variable(const slang_variable_scope *, const slang_atom a_name, GLboolean all); -extern GLboolean -_slang_build_export_data_table(slang_export_data_table *, - slang_variable_scope *); - - #ifdef __cplusplus } diff --git a/src/mesa/shader/slang/slang_emit.c b/src/mesa/shader/slang/slang_emit.c new file mode 100644 index 0000000000..ace68d1f05 --- /dev/null +++ b/src/mesa/shader/slang/slang_emit.c @@ -0,0 +1,1591 @@ +/* + * Mesa 3-D graphics library + * Version: 6.5.3 + * + * Copyright (C) 2005-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. + */ + +/** + * \file slang_emit.c + * Emit program instructions (PI code) from IR trees. + * \author Brian Paul + */ + +/*** + *** NOTES + *** + *** To emit GPU instructions, we basically just do an in-order traversal + *** of the IR tree. + ***/ + + +#include "imports.h" +#include "context.h" +#include "macros.h" +#include "program.h" +#include "prog_instruction.h" +#include "prog_parameter.h" +#include "prog_print.h" +#include "slang_builtin.h" +#include "slang_emit.h" + + +#define PEEPHOLE_OPTIMIZATIONS 1 +#define ANNOTATE 0 + + +/* XXX temporarily here */ + + +typedef struct +{ + slang_info_log *log; + slang_var_table *vt; + struct gl_program *prog; + /* code-gen options */ + GLboolean EmitHighLevelInstructions; + GLboolean EmitCondCodes; + GLboolean EmitComments; +} slang_emit_info; + + + +/** + * Swizzle a swizzle. That is, return swz2(swz1) + */ +static GLuint +swizzle_swizzle(GLuint swz1, GLuint swz2) +{ + GLuint i, swz, s[4]; + for (i = 0; i < 4; i++) { + GLuint c = GET_SWZ(swz2, i); + s[i] = GET_SWZ(swz1, c); + } + swz = MAKE_SWIZZLE4(s[0], s[1], s[2], s[3]); + return swz; +} + + +slang_ir_storage * +_slang_new_ir_storage(enum register_file file, GLint index, GLint size) +{ + slang_ir_storage *st; + st = (slang_ir_storage *) _mesa_calloc(sizeof(slang_ir_storage)); + if (st) { + st->File = file; + st->Index = index; + st->Size = size; + st->Swizzle = SWIZZLE_NOOP; + } + return st; +} + + +/** + * Allocate temporary storage for an intermediate result (such as for + * a multiply or add, etc. + */ +static GLboolean +alloc_temp_storage(slang_emit_info *emitInfo, slang_ir_node *n, GLint size) +{ + assert(!n->Var); + assert(!n->Store); + assert(size > 0); + n->Store = _slang_new_ir_storage(PROGRAM_TEMPORARY, -1, size); + if (!_slang_alloc_temp(emitInfo->vt, n->Store)) { + slang_info_log_error(emitInfo->log, + "Ran out of registers, too many temporaries"); + return GL_FALSE; + } + return GL_TRUE; +} + + +/** + * Free temporary storage, if n->Store is, in fact, temp storage. + * Otherwise, no-op. + */ +static void +free_temp_storage(slang_var_table *vt, slang_ir_node *n) +{ + if (n->Store->File == PROGRAM_TEMPORARY && n->Store->Index >= 0) { + if (_slang_is_temp(vt, n->Store)) { + _slang_free_temp(vt, n->Store); + n->Store->Index = -1; + n->Store->Size = -1; + } + } +} + + +/** + * Convert IR storage to an instruction dst register. + */ +static void +storage_to_dst_reg(struct prog_dst_register *dst, const slang_ir_storage *st, + GLuint writemask) +{ + static const GLuint defaultWritemask[4] = { + WRITEMASK_X, + WRITEMASK_X | WRITEMASK_Y, + WRITEMASK_X | WRITEMASK_Y | WRITEMASK_Z, + WRITEMASK_X | WRITEMASK_Y | WRITEMASK_Z | WRITEMASK_W + }; + assert(st->Index >= 0); + dst->File = st->File; + dst->Index = st->Index; + assert(st->File != PROGRAM_UNDEFINED); + assert(st->Size >= 1); + assert(st->Size <= 4); + if (st->Size == 1) { + GLuint comp = GET_SWZ(st->Swizzle, 0); + assert(comp < 4); + assert(writemask & WRITEMASK_X); + /* + assert((writemask == WRITEMASK_X) || + (writemask == WRITEMASK_Y) || + (writemask == WRITEMASK_Z) || + (writemask == WRITEMASK_W)); + */ + dst->WriteMask = WRITEMASK_X << comp; + } + else { + dst->WriteMask = defaultWritemask[st->Size - 1] & writemask; + } +} + + +/** + * Convert IR storage to an instruction src register. + */ +static void +storage_to_src_reg(struct prog_src_register *src, const slang_ir_storage *st) +{ + static const GLuint defaultSwizzle[4] = { + MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_X, SWIZZLE_X, SWIZZLE_X), + MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_Y, SWIZZLE_Z, SWIZZLE_W), + MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_Y, SWIZZLE_Z, SWIZZLE_W), + MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_Y, SWIZZLE_Z, SWIZZLE_W) + }; + assert(st->File >= 0); + assert(st->File < PROGRAM_UNDEFINED); + assert(st->Size >= 1); + assert(st->Size <= 4); + src->File = st->File; + src->Index = st->Index; + if (st->Swizzle != SWIZZLE_NOOP) + src->Swizzle = st->Swizzle; + else + src->Swizzle = defaultSwizzle[st->Size - 1]; /*XXX really need this?*/ + + assert(GET_SWZ(src->Swizzle, 0) != SWIZZLE_NIL); + assert(GET_SWZ(src->Swizzle, 1) != SWIZZLE_NIL); + assert(GET_SWZ(src->Swizzle, 2) != SWIZZLE_NIL); + assert(GET_SWZ(src->Swizzle, 3) != SWIZZLE_NIL); +} + + + +/** + * Add new instruction at end of given program. + * \param prog the program to append instruction onto + * \param opcode opcode for the new instruction + * \return pointer to the new instruction + */ +static struct prog_instruction * +new_instruction(slang_emit_info *emitInfo, gl_inst_opcode opcode) +{ + struct gl_program *prog = emitInfo->prog; + struct prog_instruction *inst; + prog->Instructions = _mesa_realloc_instructions(prog->Instructions, + prog->NumInstructions, + prog->NumInstructions + 1); + inst = prog->Instructions + prog->NumInstructions; + prog->NumInstructions++; + _mesa_init_instructions(inst, 1); + inst->Opcode = opcode; + inst->BranchTarget = -1; /* invalid */ + /* + printf("New inst %d: %p %s\n", prog->NumInstructions-1,(void*)inst, + _mesa_opcode_string(inst->Opcode)); + */ + return inst; +} + + +#if 0 +/** + * Return pointer to last instruction in program. + */ +static struct prog_instruction * +prev_instruction(struct gl_program *prog) +{ + if (prog->NumInstructions == 0) + return NULL; + else + return prog->Instructions + prog->NumInstructions - 1; +} +#endif + + +static struct prog_instruction * +emit(slang_emit_info *emitInfo, slang_ir_node *n); + + +/** + * Return an annotation string for given node's storage. + */ +static char * +storage_annotation(const slang_ir_node *n, const struct gl_program *prog) +{ +#if ANNOTATE + const slang_ir_storage *st = n->Store; + static char s[100] = ""; + + if (!st) + return _mesa_strdup(""); + + switch (st->File) { + case PROGRAM_CONSTANT: + if (st->Index >= 0) { + const GLfloat *val = prog->Parameters->ParameterValues[st->Index]; + if (st->Swizzle == SWIZZLE_NOOP) + sprintf(s, "{%g, %g, %g, %g}", val[0], val[1], val[2], val[3]); + else { + sprintf(s, "%g", val[GET_SWZ(st->Swizzle, 0)]); + } + } + break; + case PROGRAM_TEMPORARY: + if (n->Var) + sprintf(s, "%s", (char *) n->Var->a_name); + else + sprintf(s, "t[%d]", st->Index); + break; + case PROGRAM_STATE_VAR: + case PROGRAM_UNIFORM: + sprintf(s, "%s", prog->Parameters->Parameters[st->Index].Name); + break; + case PROGRAM_VARYING: + sprintf(s, "%s", prog->Varying->Parameters[st->Index].Name); + break; + case PROGRAM_INPUT: + sprintf(s, "input[%d]", st->Index); + break; + case PROGRAM_OUTPUT: + sprintf(s, "output[%d]", st->Index); + break; + default: + s[0] = 0; + } + return _mesa_strdup(s); +#else + return NULL; +#endif +} + + +/** + * Return an annotation string for an instruction. + */ +static char * +instruction_annotation(gl_inst_opcode opcode, char *dstAnnot, + char *srcAnnot0, char *srcAnnot1, char *srcAnnot2) +{ +#if ANNOTATE + const char *operator; + char *s; + int len = 50; + + if (dstAnnot) + len += strlen(dstAnnot); + else + dstAnnot = _mesa_strdup(""); + + if (srcAnnot0) + len += strlen(srcAnnot0); + else + srcAnnot0 = _mesa_strdup(""); + + if (srcAnnot1) + len += strlen(srcAnnot1); + else + srcAnnot1 = _mesa_strdup(""); + + if (srcAnnot2) + len += strlen(srcAnnot2); + else + srcAnnot2 = _mesa_strdup(""); + + switch (opcode) { + case OPCODE_ADD: + operator = "+"; + break; + case OPCODE_SUB: + operator = "-"; + break; + case OPCODE_MUL: + operator = "*"; + break; + case OPCODE_DP3: + operator = "DP3"; + break; + case OPCODE_DP4: + operator = "DP4"; + break; + case OPCODE_XPD: + operator = "XPD"; + break; + case OPCODE_RSQ: + operator = "RSQ"; + break; + case OPCODE_SGT: + operator = ">"; + break; + default: + operator = ","; + } + + s = (char *) malloc(len); + sprintf(s, "%s = %s %s %s %s", dstAnnot, + srcAnnot0, operator, srcAnnot1, srcAnnot2); + assert(_mesa_strlen(s) < len); + + free(dstAnnot); + free(srcAnnot0); + free(srcAnnot1); + free(srcAnnot2); + + return s; +#else + return NULL; +#endif +} + + +/** + * Emit an instruction that's just a comment. + */ +static struct prog_instruction * +emit_comment(slang_emit_info *emitInfo, const char *s) +{ + struct prog_instruction *inst = new_instruction(emitInfo, OPCODE_NOP); + if (inst) { + inst->Comment = _mesa_strdup(s); + } + return inst; +} + + +/** + * Generate code for a simple arithmetic instruction. + * Either 1, 2 or 3 operands. + */ +static struct prog_instruction * +emit_arith(slang_emit_info *emitInfo, slang_ir_node *n) +{ + struct prog_instruction *inst; + const slang_ir_info *info = _slang_ir_info(n->Opcode); + char *srcAnnot[3], *dstAnnot; + GLuint i; + + assert(info); + assert(info->InstOpcode != OPCODE_NOP); + + srcAnnot[0] = srcAnnot[1] = srcAnnot[2] = dstAnnot = NULL; + +#if PEEPHOLE_OPTIMIZATIONS + /* Look for MAD opportunity */ + if (info->NumParams == 2 && + n->Opcode == IR_ADD && n->Children[0]->Opcode == IR_MUL) { + /* found pattern IR_ADD(IR_MUL(A, B), C) */ + emit(emitInfo, n->Children[0]->Children[0]); /* A */ + emit(emitInfo, n->Children[0]->Children[1]); /* B */ + emit(emitInfo, n->Children[1]); /* C */ + /* generate MAD instruction */ + inst = new_instruction(emitInfo, OPCODE_MAD); + /* operands: A, B, C: */ + storage_to_src_reg(&inst->SrcReg[0], n->Children[0]->Children[0]->Store); + storage_to_src_reg(&inst->SrcReg[1], n->Children[0]->Children[1]->Store); + storage_to_src_reg(&inst->SrcReg[2], n->Children[1]->Store); + free_temp_storage(emitInfo->vt, n->Children[0]->Children[0]); + free_temp_storage(emitInfo->vt, n->Children[0]->Children[1]); + free_temp_storage(emitInfo->vt, n->Children[1]); + } + else if (info->NumParams == 2 && + n->Opcode == IR_ADD && n->Children[1]->Opcode == IR_MUL) { + /* found pattern IR_ADD(A, IR_MUL(B, C)) */ + emit(emitInfo, n->Children[0]); /* A */ + emit(emitInfo, n->Children[1]->Children[0]); /* B */ + emit(emitInfo, n->Children[1]->Children[1]); /* C */ + /* generate MAD instruction */ + inst = new_instruction(emitInfo, OPCODE_MAD); + /* operands: B, C, A */ + storage_to_src_reg(&inst->SrcReg[0], n->Children[1]->Children[0]->Store); + storage_to_src_reg(&inst->SrcReg[1], n->Children[1]->Children[1]->Store); + storage_to_src_reg(&inst->SrcReg[2], n->Children[0]->Store); + free_temp_storage(emitInfo->vt, n->Children[1]->Children[0]); + free_temp_storage(emitInfo->vt, n->Children[1]->Children[1]); + free_temp_storage(emitInfo->vt, n->Children[0]); + } + else +#endif + { + /* normal case */ + + /* gen code for children */ + for (i = 0; i < info->NumParams; i++) + emit(emitInfo, n->Children[i]); + + /* gen this instruction and src registers */ + inst = new_instruction(emitInfo, info->InstOpcode); + for (i = 0; i < info->NumParams; i++) + storage_to_src_reg(&inst->SrcReg[i], n->Children[i]->Store); + + /* annotation */ + for (i = 0; i < info->NumParams; i++) + srcAnnot[i] = storage_annotation(n->Children[i], emitInfo->prog); + + /* free temps */ + for (i = 0; i < info->NumParams; i++) + free_temp_storage(emitInfo->vt, n->Children[i]); + } + + /* result storage */ + if (!n->Store) { + if (!alloc_temp_storage(emitInfo, n, info->ResultSize)) + return NULL; + } + storage_to_dst_reg(&inst->DstReg, n->Store, n->Writemask); + + dstAnnot = storage_annotation(n, emitInfo->prog); + + inst->Comment = instruction_annotation(inst->Opcode, dstAnnot, srcAnnot[0], + srcAnnot[1], srcAnnot[2]); + + /*_mesa_print_instruction(inst);*/ + return inst; +} + + +/** + * Emit code for == and != operators. These could normally be handled + * by emit_arith() except we need to be able to handle structure comparisons. + */ +static struct prog_instruction * +emit_compare(slang_emit_info *emitInfo, slang_ir_node *n) +{ + struct prog_instruction *inst; + GLint size; + + assert(n->Opcode == IR_EQUAL || n->Opcode == IR_NOTEQUAL); + + /* gen code for children */ + emit(emitInfo, n->Children[0]); + emit(emitInfo, n->Children[1]); + +#if 0 + assert(n->Children[0]->Store->Size == n->Children[1]->Store->Size); + size = n->Children[0]->Store->Size; +#else + /* XXX kind of a hack for now... */ + size = MIN2(n->Children[0]->Store->Size, n->Children[1]->Store->Size); +#endif + if (size == 1) { + gl_inst_opcode opcode; + + if (!n->Store) { + if (!alloc_temp_storage(emitInfo, n, 1)) /* 1 bool */ + return NULL; + } + + opcode = n->Opcode == IR_EQUAL ? OPCODE_SEQ : OPCODE_SNE; + inst = new_instruction(emitInfo, opcode); + storage_to_src_reg(&inst->SrcReg[0], n->Children[0]->Store); + ASSERT(inst->SrcReg[0].Swizzle != SWIZZLE_XYZW); + storage_to_src_reg(&inst->SrcReg[1], n->Children[1]->Store); + ASSERT(inst->SrcReg[1].Swizzle != SWIZZLE_XYZW); + storage_to_dst_reg(&inst->DstReg, n->Store, n->Writemask); + } + else if (size <= 4) { + static const GLfloat zero[4] = { 0, 0, 0, 0 }; + GLuint zeroSwizzle, swizzle; + GLint zeroReg = _mesa_add_unnamed_constant(emitInfo->prog->Parameters, + zero, 4, &zeroSwizzle); + gl_inst_opcode dotOp; + + assert(zeroReg >= 0); + + if (!n->Store) { + if (!alloc_temp_storage(emitInfo, n, 4)) /* 4 bools */ + return NULL; + } + + if (size == 4) { + dotOp = OPCODE_DP4; + swizzle = SWIZZLE_XYZW; + } + else if (size == 3) { + dotOp = OPCODE_DP3; + swizzle = SWIZZLE_XYZW; + } + else { + assert(size == 2); + dotOp = OPCODE_DP3; + swizzle = MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_Y, SWIZZLE_Y, SWIZZLE_Y); + } + + /* Compute equality, inequality */ + inst = new_instruction(emitInfo, OPCODE_SNE); + storage_to_src_reg(&inst->SrcReg[0], n->Children[0]->Store); + storage_to_src_reg(&inst->SrcReg[1], n->Children[1]->Store); + storage_to_dst_reg(&inst->DstReg, n->Store, n->Writemask); + inst->Comment = _mesa_strdup("Compare values"); + /* compute D = DP4(D, D) (reduction) */ + inst = new_instruction(emitInfo, dotOp); + inst->SrcReg[0].File = PROGRAM_TEMPORARY; + inst->SrcReg[0].Index = n->Store->Index; + inst->SrcReg[0].Swizzle = swizzle; + inst->SrcReg[1].File = PROGRAM_TEMPORARY; + inst->SrcReg[1].Index = n->Store->Index; + inst->SrcReg[1].Swizzle = swizzle; + inst->DstReg.File = PROGRAM_TEMPORARY; + inst->DstReg.Index = n->Store->Index; + inst->Comment = _mesa_strdup("Reduce vec to bool"); + if (n->Opcode == IR_EQUAL) { + /* compute D.x = !D.x via D.x = (D.x == 0) */ + inst = new_instruction(emitInfo, OPCODE_SEQ); + inst->SrcReg[0].File = PROGRAM_TEMPORARY; + inst->SrcReg[0].Index = n->Store->Index; + inst->SrcReg[1].File = PROGRAM_CONSTANT; + inst->SrcReg[1].Index = zeroReg; + inst->SrcReg[1].Swizzle = zeroSwizzle; + inst->DstReg.File = PROGRAM_TEMPORARY; + inst->DstReg.Index = n->Store->Index; + inst->DstReg.WriteMask = WRITEMASK_X; + inst->Comment = _mesa_strdup("Invert true/false"); + } + } + else { + /* size > 4, struct compare */ +#if 0 + GLint i, num = (n->Children[0]->Store->Size + 3) / 4; + /*printf("BEGIN COMPARE size %d\n", num);*/ + for (i = 0; i < num; i++) { + inst = new_instruction(emitInfo, opcode); + inst->SrcReg[0].File = n->Children[0]->Store->File; + inst->SrcReg[0].Index = n->Children[0]->Store->Index + i; + inst->SrcReg[1].File = n->Children[1]->Store->File; + inst->SrcReg[1].Index = n->Children[1]->Store->Index + i; + inst->DstReg.File = n->Store->File; + inst->DstReg.Index = n->Store->Index; + + inst->CondUpdate = 1; /* update cond code */ + if (i > 0) { + inst->DstReg.CondMask = COND_NE; /* update if !=0 */ + } + /*_mesa_print_instruction(inst);*/ + } + storage_to_dst_reg(&inst->DstReg, n->Store, n->Writemask); +#endif + _mesa_problem(NULL, "struct comparison not implemented yet"); + inst = NULL; + } + + /* free temps */ + free_temp_storage(emitInfo->vt, n->Children[0]); + free_temp_storage(emitInfo->vt, n->Children[1]); + + return inst; +} + + + +/** + * Generate code for an IR_CLAMP instruction. + */ +static struct prog_instruction * +emit_clamp(slang_emit_info *emitInfo, slang_ir_node *n) +{ + struct prog_instruction *inst; + + assert(n->Opcode == IR_CLAMP); + /* ch[0] = value + * ch[1] = min limit + * ch[2] = max limit + */ + + inst = emit(emitInfo, n->Children[0]); + + /* If lower limit == 0.0 and upper limit == 1.0, + * set prev instruction's SaturateMode field to SATURATE_ZERO_ONE. + * Else, + * emit OPCODE_MIN, OPCODE_MAX sequence. + */ +#if 0 + /* XXX this isn't quite finished yet */ + if (n->Children[1]->Opcode == IR_FLOAT && + n->Children[1]->Value[0] == 0.0 && + n->Children[1]->Value[1] == 0.0 && + n->Children[1]->Value[2] == 0.0 && + n->Children[1]->Value[3] == 0.0 && + n->Children[2]->Opcode == IR_FLOAT && + n->Children[2]->Value[0] == 1.0 && + n->Children[2]->Value[1] == 1.0 && + n->Children[2]->Value[2] == 1.0 && + n->Children[2]->Value[3] == 1.0) { + if (!inst) { + inst = prev_instruction(prog); + } + if (inst && inst->Opcode != OPCODE_NOP) { + /* and prev instruction's DstReg matches n->Children[0]->Store */ + inst->SaturateMode = SATURATE_ZERO_ONE; + n->Store = n->Children[0]->Store; + return inst; + } + } +#endif + + if (!n->Store) + if (!alloc_temp_storage(emitInfo, n, n->Children[0]->Store->Size)) + return NULL; + + emit(emitInfo, n->Children[1]); + emit(emitInfo, n->Children[2]); + + /* tmp = max(ch[0], ch[1]) */ + inst = new_instruction(emitInfo, OPCODE_MAX); + storage_to_dst_reg(&inst->DstReg, n->Store, n->Writemask); + storage_to_src_reg(&inst->SrcReg[0], n->Children[0]->Store); + storage_to_src_reg(&inst->SrcReg[1], n->Children[1]->Store); + + /* tmp = min(tmp, ch[2]) */ + inst = new_instruction(emitInfo, OPCODE_MIN); + storage_to_dst_reg(&inst->DstReg, n->Store, n->Writemask); + storage_to_src_reg(&inst->SrcReg[0], n->Store); + storage_to_src_reg(&inst->SrcReg[1], n->Children[2]->Store); + + return inst; +} + + +static struct prog_instruction * +emit_negation(slang_emit_info *emitInfo, slang_ir_node *n) +{ + /* Implement as MOV dst, -src; */ + /* XXX we could look at the previous instruction and in some circumstances + * modify it to accomplish the negation. + */ + struct prog_instruction *inst; + + emit(emitInfo, n->Children[0]); + + if (!n->Store) + if (!alloc_temp_storage(emitInfo, n, n->Children[0]->Store->Size)) + return NULL; + + inst = new_instruction(emitInfo, OPCODE_MOV); + storage_to_dst_reg(&inst->DstReg, n->Store, n->Writemask); + storage_to_src_reg(&inst->SrcReg[0], n->Children[0]->Store); + inst->SrcReg[0].NegateBase = NEGATE_XYZW; + return inst; +} + + +static struct prog_instruction * +emit_label(slang_emit_info *emitInfo, const slang_ir_node *n) +{ + assert(n->Label); +#if 0 + /* XXX this fails in loop tail code - investigate someday */ + assert(_slang_label_get_location(n->Label) < 0); + _slang_label_set_location(n->Label, emitInfo->prog->NumInstructions, + emitInfo->prog); +#else + if (_slang_label_get_location(n->Label) < 0) + _slang_label_set_location(n->Label, emitInfo->prog->NumInstructions, + emitInfo->prog); +#endif + return NULL; +} + + +static struct prog_instruction * +emit_jump(slang_emit_info *emitInfo, slang_ir_node *n) +{ + struct prog_instruction *inst; + assert(n); + assert(n->Label); + inst = new_instruction(emitInfo, OPCODE_BRA); + inst->DstReg.CondMask = COND_TR; /* always branch */ + inst->BranchTarget = _slang_label_get_location(n->Label); + if (inst->BranchTarget < 0) { + _slang_label_add_reference(n->Label, emitInfo->prog->NumInstructions - 1); + } + return inst; +} + + +static struct prog_instruction * +emit_kill(slang_emit_info *emitInfo) +{ + struct prog_instruction *inst; + /* NV-KILL - discard fragment depending on condition code. + * Note that ARB-KILL depends on sign of vector operand. + */ + inst = new_instruction(emitInfo, OPCODE_KIL_NV); + inst->DstReg.CondMask = COND_TR; /* always branch */ + return inst; +} + + +static struct prog_instruction * +emit_tex(slang_emit_info *emitInfo, slang_ir_node *n) +{ + struct prog_instruction *inst; + + (void) emit(emitInfo, n->Children[1]); + + if (n->Opcode == IR_TEX) { + inst = new_instruction(emitInfo, OPCODE_TEX); + } + else if (n->Opcode == IR_TEXB) { + inst = new_instruction(emitInfo, OPCODE_TXB); + } + else { + assert(n->Opcode == IR_TEXP); + inst = new_instruction(emitInfo, OPCODE_TXP); + } + + if (!n->Store) + if (!alloc_temp_storage(emitInfo, n, 4)) + return NULL; + + storage_to_dst_reg(&inst->DstReg, n->Store, n->Writemask); + + /* Child[1] is the coord */ + assert(n->Children[1]->Store->File != PROGRAM_UNDEFINED); + assert(n->Children[1]->Store->Index >= 0); + storage_to_src_reg(&inst->SrcReg[0], n->Children[1]->Store); + + /* Child[0] is the sampler (a uniform which'll indicate the texture unit) */ + assert(n->Children[0]->Store); + assert(n->Children[0]->Store->Size >= TEXTURE_1D_INDEX); + + inst->Sampler = n->Children[0]->Store->Index; /* i.e. uniform's index */ + inst->TexSrcTarget = n->Children[0]->Store->Size; + inst->TexSrcUnit = 27; /* Dummy value; the TexSrcUnit will be computed at + * link time, using the sampler uniform's value. + */ + return inst; +} + + +static struct prog_instruction * +emit_move(slang_emit_info *emitInfo, slang_ir_node *n) +{ + struct prog_instruction *inst; + + /* lhs */ + emit(emitInfo, n->Children[0]); + + /* rhs */ + assert(n->Children[1]); + inst = emit(emitInfo, n->Children[1]); + + assert(n->Children[1]->Store->Index >= 0); + +#if 0 + assert(!n->Store); +#endif + n->Store = n->Children[0]->Store; + +#if PEEPHOLE_OPTIMIZATIONS + if (inst && _slang_is_temp(emitInfo->vt, n->Children[1]->Store)) { + /* Peephole optimization: + * Just modify the RHS to put its result into the dest of this + * MOVE operation. Then, this MOVE is a no-op. + */ + _slang_free_temp(emitInfo->vt, n->Children[1]->Store); + *n->Children[1]->Store = *n->Children[0]->Store; + /* fixup the prev (RHS) instruction */ + assert(n->Children[0]->Store->Index >= 0); + storage_to_dst_reg(&inst->DstReg, n->Children[0]->Store, n->Writemask); + return inst; + } + else +#endif + { + if (n->Children[0]->Store->Size > 4) { + /* move matrix/struct etc (block of registers) */ + slang_ir_storage dstStore = *n->Children[0]->Store; + slang_ir_storage srcStore = *n->Children[1]->Store; + GLint size = srcStore.Size; + ASSERT(n->Children[0]->Writemask == WRITEMASK_XYZW); + ASSERT(n->Children[1]->Store->Swizzle == SWIZZLE_NOOP); + dstStore.Size = 4; + srcStore.Size = 4; + while (size >= 4) { + inst = new_instruction(emitInfo, OPCODE_MOV); + inst->Comment = _mesa_strdup("IR_MOVE block"); + storage_to_dst_reg(&inst->DstReg, &dstStore, n->Writemask); + storage_to_src_reg(&inst->SrcReg[0], &srcStore); + srcStore.Index++; + dstStore.Index++; + size -= 4; + } + } + else { + /* single register move */ + char *srcAnnot, *dstAnnot; + inst = new_instruction(emitInfo, OPCODE_MOV); + assert(n->Children[0]->Store->Index >= 0); + storage_to_dst_reg(&inst->DstReg, n->Children[0]->Store, n->Writemask); + storage_to_src_reg(&inst->SrcReg[0], n->Children[1]->Store); + dstAnnot = storage_annotation(n->Children[0], emitInfo->prog); + srcAnnot = storage_annotation(n->Children[1], emitInfo->prog); + inst->Comment = instruction_annotation(inst->Opcode, dstAnnot, + srcAnnot, NULL, NULL); + } + free_temp_storage(emitInfo->vt, n->Children[1]); + return inst; + } +} + + +static struct prog_instruction * +emit_cond(slang_emit_info *emitInfo, slang_ir_node *n) +{ + struct prog_instruction *inst; + + if (!n->Children[0]) + return NULL; + + inst = emit(emitInfo, n->Children[0]); + + if (emitInfo->EmitCondCodes) { + /* Conditional expression (in if/while/for stmts). + * Need to update condition code register. + * Next instruction is typically an IR_IF. + */ + if (inst) { + /* set inst's CondUpdate flag */ + inst->CondUpdate = GL_TRUE; + n->Store = n->Children[0]->Store; + return inst; /* XXX or null? */ + } + else { + /* This'll happen for things like "if (i) ..." where no code + * is normally generated for the expression "i". + * Generate a move instruction just to set condition codes. + * Note: must use full 4-component vector since all four + * condition codes must be set identically. + */ + if (!alloc_temp_storage(emitInfo, n, 4)) + return NULL; + inst = new_instruction(emitInfo, OPCODE_MOV); + inst->CondUpdate = GL_TRUE; + storage_to_dst_reg(&inst->DstReg, n->Store, n->Writemask); + storage_to_src_reg(&inst->SrcReg[0], n->Children[0]->Store); + _slang_free_temp(emitInfo->vt, n->Store); + inst->Comment = _mesa_strdup("COND expr"); + return inst; /* XXX or null? */ + } + } + else { + /* No-op */ + n->Store = n->Children[0]->Store; + return NULL; + } +} + + +/** + * Logical-NOT + */ +static struct prog_instruction * +emit_not(slang_emit_info *emitInfo, slang_ir_node *n) +{ + GLfloat zero = 0.0; + slang_ir_storage st; + struct prog_instruction *inst; + + /* need zero constant */ + st.File = PROGRAM_CONSTANT; + st.Size = 1; + st.Index = _mesa_add_unnamed_constant(emitInfo->prog->Parameters, &zero, + 1, &st.Swizzle); + + /* child expr */ + (void) emit(emitInfo, n->Children[0]); + /* XXXX if child instr is SGT convert to SLE, if SEQ, SNE, etc */ + + if (!n->Store) + if (!alloc_temp_storage(emitInfo, n, n->Children[0]->Store->Size)) + return NULL; + + inst = new_instruction(emitInfo, OPCODE_SEQ); + storage_to_dst_reg(&inst->DstReg, n->Store, n->Writemask); + storage_to_src_reg(&inst->SrcReg[0], n->Children[0]->Store); + storage_to_src_reg(&inst->SrcReg[1], &st); + + free_temp_storage(emitInfo->vt, n->Children[0]); + + inst->Comment = _mesa_strdup("NOT"); + return inst; +} + + +static struct prog_instruction * +emit_if(slang_emit_info *emitInfo, slang_ir_node *n) +{ + struct gl_program *prog = emitInfo->prog; + struct prog_instruction *ifInst; + GLuint ifInstLoc, elseInstLoc = 0; + + emit(emitInfo, n->Children[0]); /* the condition */ + +#if 0 + assert(n->Children[0]->Store->Size == 1); /* a bool! */ +#endif + + ifInstLoc = prog->NumInstructions; + if (emitInfo->EmitHighLevelInstructions) { + ifInst = new_instruction(emitInfo, OPCODE_IF); + if (emitInfo->EmitCondCodes) { + ifInst->DstReg.CondMask = COND_NE; /* if cond is non-zero */ + } + else { + /* test reg.x */ + storage_to_src_reg(&ifInst->SrcReg[0], n->Children[0]->Store); + } + } + else { + /* conditional jump to else, or endif */ + ifInst = new_instruction(emitInfo, OPCODE_BRA); + ifInst->DstReg.CondMask = COND_EQ; /* BRA if cond is zero */ + ifInst->Comment = _mesa_strdup("if zero"); + } + if (emitInfo->EmitCondCodes) { + /* which condition code to use: */ + ifInst->DstReg.CondSwizzle = n->Children[0]->Store->Swizzle; + } + + /* if body */ + emit(emitInfo, n->Children[1]); + + if (n->Children[2]) { + /* have else body */ + elseInstLoc = prog->NumInstructions; + if (emitInfo->EmitHighLevelInstructions) { + (void) new_instruction(emitInfo, OPCODE_ELSE); + } + else { + /* jump to endif instruction */ + struct prog_instruction *inst; + inst = new_instruction(emitInfo, OPCODE_BRA); + inst->Comment = _mesa_strdup("else"); + inst->DstReg.CondMask = COND_TR; /* always branch */ + } + ifInst = prog->Instructions + ifInstLoc; + ifInst->BranchTarget = prog->NumInstructions; + + emit(emitInfo, n->Children[2]); + } + else { + /* no else body */ + ifInst = prog->Instructions + ifInstLoc; + ifInst->BranchTarget = prog->NumInstructions + 1; + } + + if (emitInfo->EmitHighLevelInstructions) { + (void) new_instruction(emitInfo, 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_emit_info *emitInfo, slang_ir_node *n) +{ + struct gl_program *prog = emitInfo->prog; + struct prog_instruction *beginInst, *endInst; + GLuint beginInstLoc, tailInstLoc, endInstLoc; + slang_ir_node *ir; + + /* emit OPCODE_BGNLOOP */ + beginInstLoc = prog->NumInstructions; + if (emitInfo->EmitHighLevelInstructions) { + (void) new_instruction(emitInfo, OPCODE_BGNLOOP); + } + + /* body */ + emit(emitInfo, n->Children[0]); + + /* tail */ + tailInstLoc = prog->NumInstructions; + if (n->Children[1]) { + if (emitInfo->EmitComments) + emit_comment(emitInfo, "Loop tail code:"); + emit(emitInfo, n->Children[1]); + } + + endInstLoc = prog->NumInstructions; + if (emitInfo->EmitHighLevelInstructions) { + /* emit OPCODE_ENDLOOP */ + endInst = new_instruction(emitInfo, OPCODE_ENDLOOP); + } + else { + /* emit unconditional BRA-nch */ + endInst = new_instruction(emitInfo, OPCODE_BRA); + endInst->DstReg.CondMask = COND_TR; /* always true */ + } + /* ENDLOOP's BranchTarget points to the BGNLOOP inst */ + endInst->BranchTarget = beginInstLoc; + + if (emitInfo->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->List; ir; ir = ir->List) { + 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_BRK0 || + inst->Opcode == OPCODE_BRK1 || + 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_CONT0 || + inst->Opcode == OPCODE_CONT1 || + inst->Opcode == OPCODE_BRA); + /* go to instruction at tail of loop */ + inst->BranchTarget = endInstLoc; + } + } + return NULL; +} + + +/** + * Unconditional "continue" or "break" statement. + * Either OPCODE_CONT, OPCODE_BRK or OPCODE_BRA will be emitted. + */ +static struct prog_instruction * +emit_cont_break(slang_emit_info *emitInfo, slang_ir_node *n) +{ + gl_inst_opcode opcode; + struct prog_instruction *inst; + + if (n->Opcode == IR_CONT) { + /* we need to execute the loop's tail code before doing CONT */ + assert(n->Parent); + assert(n->Parent->Opcode == IR_LOOP); + if (n->Parent->Children[1]) { + /* emit tail code */ + if (emitInfo->EmitComments) { + emit_comment(emitInfo, "continue - tail code:"); + } + emit(emitInfo, n->Parent->Children[1]); + } + } + + /* opcode selection */ + if (emitInfo->EmitHighLevelInstructions) { + opcode = (n->Opcode == IR_CONT) ? OPCODE_CONT : OPCODE_BRK; + } + else { + opcode = OPCODE_BRA; + } + n->InstLocation = emitInfo->prog->NumInstructions; + inst = new_instruction(emitInfo, 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_emit_info *emitInfo, slang_ir_node *n, + GLboolean breakTrue) +{ + gl_inst_opcode opcode; + struct prog_instruction *inst; + + assert(n->Opcode == IR_CONT_IF_TRUE || + n->Opcode == IR_CONT_IF_FALSE || + n->Opcode == IR_BREAK_IF_TRUE || + n->Opcode == IR_BREAK_IF_FALSE); + + /* evaluate condition expr, setting cond codes */ + inst = emit(emitInfo, n->Children[0]); + if (emitInfo->EmitCondCodes) { + assert(inst); + inst->CondUpdate = GL_TRUE; + } + + n->InstLocation = emitInfo->prog->NumInstructions; + + /* opcode selection */ + if (emitInfo->EmitHighLevelInstructions) { + if (emitInfo->EmitCondCodes) { + if (n->Opcode == IR_CONT_IF_TRUE || + n->Opcode == IR_CONT_IF_FALSE) + opcode = OPCODE_CONT; + else + opcode = OPCODE_BRK; + } + else { + if (n->Opcode == IR_CONT_IF_TRUE) + opcode = OPCODE_CONT1; + else if (n->Opcode == IR_CONT_IF_FALSE) + opcode = OPCODE_CONT0; + else if (n->Opcode == IR_BREAK_IF_TRUE) + opcode = OPCODE_BRK1; + else if (n->Opcode == IR_BREAK_IF_FALSE) + opcode = OPCODE_BRK0; + } + } + else { + opcode = OPCODE_BRA; + } + + inst = new_instruction(emitInfo, opcode); + if (emitInfo->EmitCondCodes) { + inst->DstReg.CondMask = breakTrue ? COND_NE : COND_EQ; + } + else { + /* BRK0, BRK1, CONT0, CONT1 uses SrcReg[0] as the condition */ + storage_to_src_reg(&inst->SrcReg[0], n->Children[0]->Store); + } + return inst; +} + + + +/** + * Remove any SWIZZLE_NIL terms from given swizzle mask (smear prev term). + * Ex: fix_swizzle("zyNN") -> "zyyy" + */ +static GLuint +fix_swizzle(GLuint swizzle) +{ + GLuint swz[4], i; + for (i = 0; i < 4; i++) { + swz[i] = GET_SWZ(swizzle, i); + if (swz[i] == SWIZZLE_NIL) { + swz[i] = swz[i - 1]; + } + } + return MAKE_SWIZZLE4(swz[0], swz[1], swz[2], swz[3]); +} + + +#if 0 +static GLuint +swizzle_size(GLuint swizzle) +{ + GLuint size = 0, i; + for (i = 0; i < 4; i++) { + GLuint swz = GET_SWZ(swizzle, i); + size += (swz >= 0 && swz <= 3); + } + return size; +} +#endif + + +static struct prog_instruction * +emit_swizzle(slang_emit_info *emitInfo, slang_ir_node *n) +{ + GLuint swizzle; + + /* swizzled storage access */ + (void) emit(emitInfo, n->Children[0]); + + /* "pull-up" the child's storage info, applying our swizzle info */ + n->Store->File = n->Children[0]->Store->File; + n->Store->Index = n->Children[0]->Store->Index; + n->Store->Size = n->Children[0]->Store->Size; + /*n->Var = n->Children[0]->Var; XXX for debug */ + assert(n->Store->Index >= 0); + + swizzle = fix_swizzle(n->Store->Swizzle); +#ifdef DEBUG + { + GLuint s = n->Children[0]->Store->Swizzle; + assert(GET_SWZ(s, 0) != SWIZZLE_NIL); + assert(GET_SWZ(s, 1) != SWIZZLE_NIL); + assert(GET_SWZ(s, 2) != SWIZZLE_NIL); + assert(GET_SWZ(s, 3) != SWIZZLE_NIL); + } +#endif + +#if 0 + n->Store->Size = swizzle_size(n->Store->Swizzle); + printf("Emit Swizzle reg %d chSize %d size %d\n", + n->Store->Index, n->Children[0]->Store->Size, + n->Store->Size); +#endif + /* apply this swizzle to child's swizzle to get composed swizzle */ + n->Store->Swizzle = swizzle_swizzle(n->Children[0]->Store->Swizzle, + swizzle); + return NULL; +} + + +/** + * Dereference array element. Just resolve storage for the array + * element represented by this node. + */ +static struct prog_instruction * +emit_array_element(slang_emit_info *emitInfo, slang_ir_node *n) +{ + assert(n->Store); + assert(n->Store->File != PROGRAM_UNDEFINED); + assert(n->Store->Size > 0); + + if (n->Store->File == PROGRAM_STATE_VAR) { + n->Store->Index = _slang_alloc_statevar(n, emitInfo->prog->Parameters); + return NULL; + } + + if (n->Children[1]->Opcode == IR_FLOAT) { + /* Constant index */ + const GLint arrayAddr = n->Children[0]->Store->Index; + const GLint index = (GLint) n->Children[1]->Value[0]; + n->Store->Index = arrayAddr + index; + } + else { + /* Variable index - PROBLEM */ + const GLint arrayAddr = n->Children[0]->Store->Index; + const GLint index = 0; + _mesa_problem(NULL, "variable array indexes not supported yet!"); + n->Store->Index = arrayAddr + index; + } + return NULL; /* no instruction */ +} + + +/** + * Resolve storage for accessing a structure field. + */ +static struct prog_instruction * +emit_struct_field(slang_emit_info *emitInfo, slang_ir_node *n) +{ + if (n->Store->File == PROGRAM_STATE_VAR) { + n->Store->Index = _slang_alloc_statevar(n, emitInfo->prog->Parameters); + } + else { + GLint offset = n->FieldOffset / 4; + assert(n->Children[0]->Store->Index >= 0); + n->Store->Index = n->Children[0]->Store->Index + offset; + if (n->Store->Size == 1) { + GLint swz = n->FieldOffset % 4; + n->Store->Swizzle = MAKE_SWIZZLE4(swz, swz, swz, swz); + } + else { + n->Store->Swizzle = SWIZZLE_XYZW; + } + } + return NULL; /* no instruction */ +} + + +static struct prog_instruction * +emit(slang_emit_info *emitInfo, slang_ir_node *n) +{ + struct prog_instruction *inst; + if (!n) + return NULL; + + switch (n->Opcode) { + case IR_SEQ: + /* sequence of two sub-trees */ + assert(n->Children[0]); + assert(n->Children[1]); + emit(emitInfo, n->Children[0]); + inst = emit(emitInfo, n->Children[1]); +#if 0 + assert(!n->Store); +#endif + n->Store = n->Children[1]->Store; + return inst; + + case IR_SCOPE: + /* new variable scope */ + _slang_push_var_table(emitInfo->vt); + inst = emit(emitInfo, n->Children[0]); + _slang_pop_var_table(emitInfo->vt); + return inst; + + case IR_VAR_DECL: + /* Variable declaration - allocate a register for it */ + assert(n->Store); + assert(n->Store->File != PROGRAM_UNDEFINED); + assert(n->Store->Size > 0); + /*assert(n->Store->Index < 0);*/ + if (!n->Var || n->Var->isTemp) { + /* a nameless/temporary variable, will be freed after first use */ + /*NEW*/ + if (n->Store->Index < 0 && !_slang_alloc_temp(emitInfo->vt, n->Store)) { + slang_info_log_error(emitInfo->log, + "Ran out of registers, too many temporaries"); + return NULL; + } + } + else { + /* a regular variable */ + _slang_add_variable(emitInfo->vt, n->Var); + if (!_slang_alloc_var(emitInfo->vt, n->Store)) { + slang_info_log_error(emitInfo->log, + "Ran out of registers, too many variables"); + return NULL; + } + /* + printf("IR_VAR_DECL %s %d store %p\n", + (char*) n->Var->a_name, n->Store->Index, (void*) n->Store); + */ + assert(n->Var->aux == n->Store); + } + if (emitInfo->EmitComments) { + /* emit NOP with comment describing the variable's storage location */ + char s[1000]; + sprintf(s, "TEMP[%d]%s = variable %s (size %d)", + n->Store->Index, + _mesa_swizzle_string(n->Store->Swizzle, 0, GL_FALSE), + (n->Var ? (char *) n->Var->a_name : "anonymous"), + n->Store->Size); + inst = emit_comment(emitInfo, s); + return inst; + } + return NULL; + + case IR_VAR: + /* Reference to a variable + * Storage should have already been resolved/allocated. + */ + assert(n->Store); + assert(n->Store->File != PROGRAM_UNDEFINED); + + if (n->Store->File == PROGRAM_STATE_VAR && + n->Store->Index < 0) { + n->Store->Index = _slang_alloc_statevar(n, emitInfo->prog->Parameters); + } + + if (n->Store->Index < 0) { + printf("#### VAR %s not allocated!\n", (char*)n->Var->a_name); + } + assert(n->Store->Index >= 0); + assert(n->Store->Size > 0); + break; + + case IR_ELEMENT: + return emit_array_element(emitInfo, n); + case IR_FIELD: + return emit_struct_field(emitInfo, n); + case IR_SWIZZLE: + return emit_swizzle(emitInfo, n); + + case IR_I_TO_F: + /* just move */ + emit(emitInfo, n->Children[0]); + inst = new_instruction(emitInfo, OPCODE_MOV); + if (!n->Store) { + if (!alloc_temp_storage(emitInfo, n, 1)) + return NULL; + } + storage_to_dst_reg(&inst->DstReg, n->Store, n->Writemask); + storage_to_src_reg(&inst->SrcReg[0], n->Children[0]->Store); + if (emitInfo->EmitComments) + inst->Comment = _mesa_strdup("int to float"); + return NULL; + + /* Simple arithmetic */ + /* unary */ + case IR_RSQ: + case IR_RCP: + case IR_FLOOR: + case IR_FRAC: + case IR_F_TO_I: + case IR_ABS: + case IR_SIN: + case IR_COS: + case IR_DDX: + case IR_DDY: + case IR_NOISE1: + case IR_NOISE2: + case IR_NOISE3: + case IR_NOISE4: + /* binary */ + case IR_ADD: + case IR_SUB: + case IR_MUL: + case IR_DOT4: + case IR_DOT3: + case IR_CROSS: + case IR_MIN: + case IR_MAX: + case IR_SEQUAL: + case IR_SNEQUAL: + case IR_SGE: + case IR_SGT: + case IR_SLE: + case IR_SLT: + case IR_POW: + case IR_EXP: + case IR_EXP2: + /* trinary operators */ + case IR_LRP: + return emit_arith(emitInfo, n); + + case IR_EQUAL: + case IR_NOTEQUAL: + return emit_compare(emitInfo, n); + + case IR_CLAMP: + return emit_clamp(emitInfo, n); + case IR_TEX: + case IR_TEXB: + case IR_TEXP: + return emit_tex(emitInfo, n); + case IR_NEG: + return emit_negation(emitInfo, n); + case IR_FLOAT: + /* find storage location for this float constant */ + n->Store->Index = _mesa_add_unnamed_constant(emitInfo->prog->Parameters, n->Value, + n->Store->Size, + &n->Store->Swizzle); + if (n->Store->Index < 0) { + slang_info_log_error(emitInfo->log, "Ran out of space for constants"); + return NULL; + } + return NULL; + + case IR_MOVE: + return emit_move(emitInfo, n); + + case IR_COND: + return emit_cond(emitInfo, n); + + case IR_NOT: + return emit_not(emitInfo, n); + + case IR_LABEL: + return emit_label(emitInfo, n); + case IR_JUMP: + assert(n); + assert(n->Label); + return emit_jump(emitInfo, n); + case IR_KILL: + return emit_kill(emitInfo); + + case IR_IF: + return emit_if(emitInfo, n); + + case IR_LOOP: + return emit_loop(emitInfo, n); + case IR_BREAK_IF_FALSE: + case IR_CONT_IF_FALSE: + return emit_cont_break_if(emitInfo, n, GL_FALSE); + case IR_BREAK_IF_TRUE: + case IR_CONT_IF_TRUE: + return emit_cont_break_if(emitInfo, n, GL_TRUE); + case IR_BREAK: + /* fall-through */ + case IR_CONT: + return emit_cont_break(emitInfo, n); + + case IR_BEGIN_SUB: + return new_instruction(emitInfo, OPCODE_BGNSUB); + case IR_END_SUB: + return new_instruction(emitInfo, OPCODE_ENDSUB); + case IR_RETURN: + return new_instruction(emitInfo, OPCODE_RET); + + case IR_NOP: + return NULL; + + default: + _mesa_problem(NULL, "Unexpected IR opcode in emit()\n"); + abort(); + } + return NULL; +} + + +GLboolean +_slang_emit_code(slang_ir_node *n, slang_var_table *vt, + struct gl_program *prog, GLboolean withEnd, + slang_info_log *log) +{ + GET_CURRENT_CONTEXT(ctx); + GLboolean success; + slang_emit_info emitInfo; + + emitInfo.log = log; + emitInfo.vt = vt; + emitInfo.prog = prog; + + emitInfo.EmitHighLevelInstructions = ctx->Shader.EmitHighLevelInstructions; + emitInfo.EmitCondCodes = 0; /* XXX temporary! */ + emitInfo.EmitComments = 1 + ctx->Shader.EmitComments; + + (void) emit(&emitInfo, n); + + /* finish up by adding the END opcode to program */ + if (withEnd) { + struct prog_instruction *inst; + inst = new_instruction(&emitInfo, OPCODE_END); + } + success = GL_TRUE; + +#if 0 + printf("*********** End emit code (%u inst):\n", prog->NumInstructions); + _mesa_print_program(prog); + _mesa_print_program_parameters(ctx,prog); +#endif + + return success; +} diff --git a/src/mesa/shader/slang/slang_emit.h b/src/mesa/shader/slang/slang_emit.h new file mode 100644 index 0000000000..13ba6d7d6c --- /dev/null +++ b/src/mesa/shader/slang/slang_emit.h @@ -0,0 +1,49 @@ +/* + * Mesa 3-D graphics library + * Version: 6.5.3 + * + * Copyright (C) 2005-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 SLANG_EMIT_H +#define SLANG_EMIT_H + + +#include "imports.h" +#include "slang_compile.h" +#include "slang_ir.h" +#include "mtypes.h" + + +extern void +slang_print_ir(const slang_ir_node *n, int indent); + + +extern slang_ir_storage * +_slang_new_ir_storage(enum register_file file, GLint index, GLint size); + + +extern GLboolean +_slang_emit_code(slang_ir_node *n, slang_var_table *vartable, + struct gl_program *prog, GLboolean withEnd, + slang_info_log *log); + + +#endif /* SLANG_EMIT_H */ diff --git a/src/mesa/shader/slang/slang_execute.c b/src/mesa/shader/slang/slang_execute.c deleted file mode 100644 index 3ffa4b88bf..0000000000 --- a/src/mesa/shader/slang/slang_execute.c +++ /dev/null @@ -1,783 +0,0 @@ -/* - * Mesa 3-D graphics library - * Version: 6.5 - * - * Copyright (C) 2005-2006 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. - */ - -/** - * \file slang_execute.c - * intermediate code interpreter - * \author Michal Krol - */ - -#include "imports.h" -#include "slang_compile.h" -#include "slang_execute.h" -#include "slang_library_noise.h" -#include "slang_library_texsample.h" - -#define DEBUG_SLANG 0 - -GLvoid -slang_machine_ctr(slang_machine * self) -{ - slang_machine_init(self); - self->infolog = NULL; -#if defined(USE_X86_ASM) || defined(SLANG_X86) - self->x86.compiled_func = NULL; -#endif -} - -GLvoid -slang_machine_dtr(slang_machine * self) -{ - if (self->infolog != NULL) { - slang_info_log_destruct(self->infolog); - slang_alloc_free(self->infolog); - } -#if defined(USE_X86_ASM) || defined(SLANG_X86) - if (self->x86.compiled_func != NULL) - _mesa_exec_free(self->x86.compiled_func); -#endif -} - - -/** - * Initialize the shader virtual machine. - * NOTE: stack grows downward in memory. - */ -void -slang_machine_init(slang_machine * mach) -{ - mach->ip = 0; - mach->sp = SLANG_MACHINE_STACK_SIZE; - mach->bp = 0; - mach->kill = GL_FALSE; - mach->exit = GL_FALSE; -} - -#if DEBUG_SLANG - -static void -dump_instruction(FILE * f, slang_assembly * a, unsigned int i) -{ - fprintf(f, "%.5u:\t", i); - - switch (a->type) { - /* core */ - case slang_asm_none: - fprintf(f, "none"); - break; - case slang_asm_float_copy: - fprintf(f, "float_copy\t%d, %d", a->param[0], a->param[1]); - break; - case slang_asm_float_move: - fprintf(f, "float_move\t%d, %d", a->param[0], a->param[1]); - break; - case slang_asm_float_push: - fprintf(f, "float_push\t%f", a->literal); - break; - case slang_asm_float_deref: - fprintf(f, "float_deref"); - break; - case slang_asm_float_add: - fprintf(f, "float_add"); - break; - case slang_asm_float_multiply: - fprintf(f, "float_multiply"); - break; - case slang_asm_float_divide: - fprintf(f, "float_divide"); - break; - case slang_asm_float_negate: - fprintf(f, "float_negate"); - break; - case slang_asm_float_less: - fprintf(f, "float_less"); - break; - case slang_asm_float_equal_exp: - fprintf(f, "float_equal"); - break; - case slang_asm_float_equal_int: - fprintf(f, "float_equal\t%d, %d", a->param[0], a->param[1]); - break; - case slang_asm_float_to_int: - fprintf(f, "float_to_int"); - break; - case slang_asm_float_sine: - fprintf(f, "float_sine"); - break; - case slang_asm_float_arcsine: - fprintf(f, "float_arcsine"); - break; - case slang_asm_float_arctan: - fprintf(f, "float_arctan"); - break; - case slang_asm_float_power: - fprintf(f, "float_power"); - break; - case slang_asm_float_log2: - fprintf(f, "float_log2"); - break; - case slang_asm_float_floor: - fprintf(f, "float_floor"); - break; - case slang_asm_float_ceil: - fprintf(f, "float_ceil"); - break; - case slang_asm_float_noise1: - fprintf(f, "float_noise1"); - break; - case slang_asm_float_noise2: - fprintf(f, "float_noise2"); - break; - case slang_asm_float_noise3: - fprintf(f, "float_noise3"); - break; - case slang_asm_float_noise4: - fprintf(f, "float_noise4"); - break; - case slang_asm_int_copy: - fprintf(f, "int_copy\t%d, %d", a->param[0], a->param[1]); - break; - case slang_asm_int_move: - fprintf(f, "int_move\t%d, %d", a->param[0], a->param[1]); - break; - case slang_asm_int_push: - fprintf(f, "int_push\t%d", (GLint) a->literal); - break; - case slang_asm_int_deref: - fprintf(f, "int_deref"); - break; - case slang_asm_int_to_float: - fprintf(f, "int_to_float"); - break; - case slang_asm_int_to_addr: - fprintf(f, "int_to_addr"); - break; - case slang_asm_bool_copy: - fprintf(f, "bool_copy\t%d, %d", a->param[0], a->param[1]); - break; - case slang_asm_bool_move: - fprintf(f, "bool_move\t%d, %d", a->param[0], a->param[1]); - break; - case slang_asm_bool_push: - fprintf(f, "bool_push\t%d", a->literal != 0.0f); - break; - case slang_asm_bool_deref: - fprintf(f, "bool_deref"); - break; - case slang_asm_addr_copy: - fprintf(f, "addr_copy"); - break; - case slang_asm_addr_push: - fprintf(f, "addr_push\t%u", a->param[0]); - break; - case slang_asm_addr_deref: - fprintf(f, "addr_deref"); - break; - case slang_asm_addr_add: - fprintf(f, "addr_add"); - break; - case slang_asm_addr_multiply: - fprintf(f, "addr_multiply"); - break; - case slang_asm_vec4_tex1d: - fprintf(f, "vec4_tex1d"); - break; - case slang_asm_vec4_tex2d: - fprintf(f, "vec4_tex2d"); - break; - case slang_asm_vec4_tex3d: - fprintf(f, "vec4_tex3d"); - break; - case slang_asm_vec4_texcube: - fprintf(f, "vec4_texcube"); - break; - case slang_asm_vec4_shad1d: - fprintf(f, "vec4_shad1d"); - break; - case slang_asm_vec4_shad2d: - fprintf(f, "vec4_shad2d"); - break; - case slang_asm_jump: - fprintf(f, "jump\t%u", a->param[0]); - break; - case slang_asm_jump_if_zero: - fprintf(f, "jump_if_zero\t%u", a->param[0]); - break; - case slang_asm_enter: - fprintf(f, "enter\t%u", a->param[0]); - break; - case slang_asm_leave: - fprintf(f, "leave"); - break; - case slang_asm_local_alloc: - fprintf(f, "local_alloc\t%u", a->param[0]); - break; - case slang_asm_local_free: - fprintf(f, "local_free\t%u", a->param[0]); - break; - case slang_asm_local_addr: - fprintf(f, "local_addr\t%u, %u", a->param[0], a->param[1]); - break; - case slang_asm_global_addr: - fprintf(f, "global_addr\t%u", a->param[0]); - break; - case slang_asm_call: - fprintf(f, "call\t%u", a->param[0]); - break; - case slang_asm_return: - fprintf(f, "return"); - break; - case slang_asm_discard: - fprintf(f, "discard"); - break; - case slang_asm_exit: - fprintf(f, "exit"); - break; - /* GL_MESA_shader_debug */ - case slang_asm_float_print: - fprintf(f, "float_print"); - break; - case slang_asm_int_print: - fprintf(f, "int_print"); - break; - case slang_asm_bool_print: - fprintf(f, "bool_print"); - break; - /* vec4 */ - case slang_asm_float_to_vec4: - fprintf(f, "float_to_vec4"); - break; - case slang_asm_vec4_add: - fprintf(f, "vec4_add"); - break; - case slang_asm_vec4_subtract: - fprintf(f, "vec4_subtract"); - break; - case slang_asm_vec4_multiply: - fprintf(f, "vec4_multiply"); - break; - case slang_asm_vec4_divide: - fprintf(f, "vec4_divide"); - break; - case slang_asm_vec4_negate: - fprintf(f, "vec4_negate"); - break; - case slang_asm_vec4_dot: - fprintf(f, "vec4_dot"); - break; - case slang_asm_vec4_copy: - fprintf(f, "vec4_copy"); - break; - case slang_asm_vec4_deref: - fprintf(f, "vec4_deref"); - break; - case slang_asm_vec4_equal_int: - fprintf(f, "vec4_equal"); - break; - default: - break; - } - - fprintf(f, "\n"); -} - -static void -dump(const slang_assembly_file * file) -{ - unsigned int i; - static unsigned int counter = 0; - FILE *f; - char filename[256]; - - counter++; - _mesa_sprintf(filename, "~mesa-slang-assembly-dump-(%u).txt", counter); - f = fopen(filename, "w"); - if (f == NULL) - return; - - for (i = 0; i < file->count; i++) - dump_instruction(f, file->code + i, i); - - fclose(f); -} - -#endif - -static GLvoid -ensure_infolog_created(slang_info_log ** infolog) -{ - if (*infolog == NULL) { - *infolog = (slang_info_log *) slang_alloc_malloc(sizeof(slang_info_log)); - if (*infolog == NULL) - return; - slang_info_log_construct(*infolog); - } -} - -GLboolean -_slang_execute2(const slang_assembly_file * file, slang_machine * mach) -{ - slang_machine_slot *stack; - -#if DEBUG_SLANG - static unsigned int counter = 0; - char filename[256]; - FILE *f; -#endif - - /* assume 32-bit floats and uints; should work fine also on 64-bit platforms */ - static_assert(sizeof(GLfloat) == 4); - static_assert(sizeof(GLuint) == 4); - -#if DEBUG_SLANG - dump(file); - counter++; - _mesa_sprintf(filename, "~mesa-slang-assembly-exec-(%u).txt", counter); - f = fopen(filename, "w"); -#endif - -#if defined(USE_X86_ASM) || defined(SLANG_X86) - if (mach->x86.compiled_func != NULL) { - mach->x86.compiled_func(mach); - return GL_TRUE; - } -#endif - - stack = mach->mem + SLANG_MACHINE_GLOBAL_SIZE; - - while (!mach->exit) { - const slang_assembly *a = &file->code[mach->ip]; - -#if DEBUG_SLANG - if (f != NULL && a->type != slang_asm_none) { - unsigned int i; - - dump_instruction(f, file->code + mach->ip, mach->ip); - fprintf(f, "\t\tsp=%u bp=%u\n", mach->sp, mach->bp); - for (i = mach->sp; i < SLANG_MACHINE_STACK_SIZE; i++) - fprintf(f, "\t%.5u\t%6f\t%u\n", i, stack[i]._float, - stack[i]._addr); - fflush(f); - } -#endif - - mach->ip++; - - switch (a->type) { - /* core */ - case slang_asm_none: - break; - case slang_asm_float_copy: - case slang_asm_int_copy: - case slang_asm_bool_copy: - /* store top value on stack to memory */ - { - GLuint address - = (stack[mach->sp + a->param[0] / 4]._addr + a->param[1]) / 4; - GLfloat value = stack[mach->sp]._float; - mach->mem[address]._float = value; - } - mach->sp++; - break; - case slang_asm_float_move: - case slang_asm_int_move: - case slang_asm_bool_move: - stack[mach->sp + a->param[0] / 4]._float = - stack[mach->sp + - (stack[mach->sp]._addr + a->param[1]) / 4]._float; - break; - case slang_asm_float_push: - case slang_asm_int_push: - case slang_asm_bool_push: - /* push float/int/bool literal onto stop of stack */ - mach->sp--; - stack[mach->sp]._float = a->literal; - break; - case slang_asm_float_deref: - case slang_asm_int_deref: - case slang_asm_bool_deref: - /* load value from memory, replace stop of stack with it */ - stack[mach->sp]._float = mach->mem[stack[mach->sp]._addr / 4]._float; - break; - case slang_asm_float_add: - /* pop two top floats, push sum */ - stack[mach->sp + 1]._float += stack[mach->sp]._float; - mach->sp++; - break; - case slang_asm_float_multiply: - stack[mach->sp + 1]._float *= stack[mach->sp]._float; - mach->sp++; - break; - case slang_asm_float_divide: - stack[mach->sp + 1]._float /= stack[mach->sp]._float; - mach->sp++; - break; - case slang_asm_float_negate: - stack[mach->sp]._float = -stack[mach->sp]._float; - break; - case slang_asm_float_less: - stack[mach->sp + 1]._float = - (stack[mach->sp + 1]._float < stack[mach->sp]._float) - ? (GLfloat) 1 : (GLfloat) 0; - mach->sp++; - break; - case slang_asm_float_equal_exp: - stack[mach->sp + 1]._float = - (stack[mach->sp + 1]._float == stack[mach->sp]._float) - ? (GLfloat) 1 : (GLfloat) 0; - mach->sp++; - break; - case slang_asm_float_equal_int: - /* pop top two values, compare, push 0 or 1 */ - mach->sp--; - stack[mach->sp]._float = - (stack[mach->sp + 1 + a->param[0] / 4]._float == - stack[mach->sp + 1 + a->param[1] / 4]._float) - ? (GLfloat) 1 : (GLfloat) 0; - break; - case slang_asm_float_to_int: - stack[mach->sp]._float = (GLfloat) (GLint) stack[mach->sp]._float; - break; - case slang_asm_float_sine: - stack[mach->sp]._float = (GLfloat) _mesa_sin(stack[mach->sp]._float); - break; - case slang_asm_float_arcsine: - stack[mach->sp]._float = _mesa_asinf(stack[mach->sp]._float); - break; - case slang_asm_float_arctan: - stack[mach->sp]._float = _mesa_atanf(stack[mach->sp]._float); - break; - case slang_asm_float_power: - stack[mach->sp + 1]._float = (GLfloat) - _mesa_pow(stack[mach->sp + 1]._float, stack[mach->sp]._float); - mach->sp++; - break; - case slang_asm_float_log2: - stack[mach->sp]._float = LOG2(stack[mach->sp]._float); - break; - case slang_asm_float_floor: - stack[mach->sp]._float = FLOORF(stack[mach->sp]._float); - break; - case slang_asm_float_ceil: - stack[mach->sp]._float = CEILF(stack[mach->sp]._float); - break; - case slang_asm_float_noise1: - stack[mach->sp]._float = - _slang_library_noise1(stack[mach->sp]._float); - break; - case slang_asm_float_noise2: - stack[mach->sp + 1]._float = - _slang_library_noise2(stack[mach->sp]._float, - stack[mach->sp + 1]._float); - mach->sp++; - break; - case slang_asm_float_noise3: - stack[mach->sp + 2]._float = - _slang_library_noise3(stack[mach->sp]._float, - stack[mach->sp + 1]._float, - stack[mach->sp + 2]._float); - mach->sp += 2; - break; - case slang_asm_float_noise4: - stack[mach->sp + 3]._float = - _slang_library_noise4(stack[mach->sp]._float, - stack[mach->sp + 1]._float, - stack[mach->sp + 2]._float, - stack[mach->sp + 3]._float); - mach->sp += 3; - break; - case slang_asm_int_to_float: - break; - case slang_asm_int_to_addr: - stack[mach->sp]._addr = (GLuint) (GLint) stack[mach->sp]._float; - break; - case slang_asm_addr_copy: - mach->mem[stack[mach->sp + 1]._addr / 4]._addr = - stack[mach->sp]._addr; - mach->sp++; - break; - case slang_asm_addr_push: - case slang_asm_global_addr: - mach->sp--; - stack[mach->sp]._addr = a->param[0]; - break; - case slang_asm_addr_deref: - stack[mach->sp]._addr = mach->mem[stack[mach->sp]._addr / 4]._addr; - break; - case slang_asm_addr_add: - stack[mach->sp + 1]._addr += stack[mach->sp]._addr; - mach->sp++; - break; - case slang_asm_addr_multiply: - stack[mach->sp + 1]._addr *= stack[mach->sp]._addr; - mach->sp++; - break; - case slang_asm_vec4_tex1d: - _slang_library_tex1d(stack[mach->sp]._float, - stack[mach->sp + 1]._float, - stack[mach->sp + 2]._float, - &mach->mem[stack[mach->sp + 3]._addr / - 4]._float); - mach->sp += 3; - break; - case slang_asm_vec4_tex2d: - _slang_library_tex2d(stack[mach->sp]._float, - stack[mach->sp + 1]._float, - stack[mach->sp + 2]._float, - stack[mach->sp + 3]._float, - &mach->mem[stack[mach->sp + 4]._addr / - 4]._float); - mach->sp += 4; - break; - case slang_asm_vec4_tex3d: - _slang_library_tex3d(stack[mach->sp]._float, - stack[mach->sp + 1]._float, - stack[mach->sp + 2]._float, - stack[mach->sp + 3]._float, - stack[mach->sp + 4]._float, - &mach->mem[stack[mach->sp + 5]._addr / - 4]._float); - mach->sp += 5; - break; - case slang_asm_vec4_texcube: - _slang_library_texcube(stack[mach->sp]._float, - stack[mach->sp + 1]._float, - stack[mach->sp + 2]._float, - stack[mach->sp + 3]._float, - stack[mach->sp + 4]._float, - &mach->mem[stack[mach->sp + 5]._addr / - 4]._float); - mach->sp += 5; - break; - case slang_asm_vec4_shad1d: - _slang_library_shad1d(stack[mach->sp]._float, - stack[mach->sp + 1]._float, - stack[mach->sp + 2]._float, - stack[mach->sp + 3]._float, - stack[mach->sp + 4]._float, - &mach->mem[stack[mach->sp + 5]._addr / - 4]._float); - mach->sp += 5; - break; - case slang_asm_vec4_shad2d: - _slang_library_shad2d(stack[mach->sp]._float, - stack[mach->sp + 1]._float, - stack[mach->sp + 2]._float, - stack[mach->sp + 3]._float, - stack[mach->sp + 4]._float, - &mach->mem[stack[mach->sp + 5]._addr / - 4]._float); - mach->sp += 5; - break; - case slang_asm_jump: - mach->ip = a->param[0]; - break; - case slang_asm_jump_if_zero: - if (stack[mach->sp]._float == 0.0f) - mach->ip = a->param[0]; - mach->sp++; - break; - case slang_asm_enter: - mach->sp--; - stack[mach->sp]._addr = mach->bp; - mach->bp = mach->sp + a->param[0] / 4; - break; - case slang_asm_leave: - mach->bp = stack[mach->sp]._addr; - mach->sp++; - break; - case slang_asm_local_alloc: - mach->sp -= a->param[0] / 4; - break; - case slang_asm_local_free: - mach->sp += a->param[0] / 4; - break; - case slang_asm_local_addr: - mach->sp--; - stack[mach->sp]._addr = - SLANG_MACHINE_GLOBAL_SIZE * 4 + mach->bp * 4 - (a->param[0] + - a->param[1]) + 4; - break; - case slang_asm_call: - mach->sp--; - stack[mach->sp]._addr = mach->ip; - mach->ip = a->param[0]; - break; - case slang_asm_return: - mach->ip = stack[mach->sp]._addr; - mach->sp++; - break; - case slang_asm_discard: - mach->kill = GL_TRUE; - break; - case slang_asm_exit: - mach->exit = GL_TRUE; - break; - /* GL_MESA_shader_debug */ - case slang_asm_float_print: - _mesa_printf("slang print: %f\n", stack[mach->sp]._float); - ensure_infolog_created(&mach->infolog); - slang_info_log_print(mach->infolog, "%f", stack[mach->sp]._float); - break; - case slang_asm_int_print: - _mesa_printf("slang print: %d\n", (GLint) stack[mach->sp]._float); - ensure_infolog_created(&mach->infolog); - slang_info_log_print(mach->infolog, "%d", - (GLint) (stack[mach->sp]._float)); - break; - case slang_asm_bool_print: - _mesa_printf("slang print: %s\n", - (GLint) stack[mach->sp]._float ? "true" : "false"); - ensure_infolog_created(&mach->infolog); - slang_info_log_print(mach->infolog, "%s", - (GLint) (stack[mach->sp]. - _float) ? "true" : "false"); - break; - /* vec4 */ - case slang_asm_float_to_vec4: - /* [vec4] | float > [vec4] */ - { - GLuint da = stack[mach->sp + 1]._addr; - mach->mem[da / 4]._float = stack[mach->sp]._float; - mach->sp++; - } - break; - case slang_asm_vec4_add: - /* [vec4] | vec4 > [vec4] */ - { - GLuint da = stack[mach->sp + 4]._addr; - mach->mem[da / 4]._float += stack[mach->sp]._float; - mach->mem[(da + 4) / 4]._float += stack[mach->sp + 1]._float; - mach->mem[(da + 8) / 4]._float += stack[mach->sp + 2]._float; - mach->mem[(da + 12) / 4]._float += stack[mach->sp + 3]._float; - mach->sp += 4; - } - break; - case slang_asm_vec4_subtract: - /* [vec4] | vec4 > [vec4] */ - { - GLuint da = stack[mach->sp + 4]._addr; - mach->mem[da / 4]._float -= stack[mach->sp]._float; - mach->mem[(da + 4) / 4]._float -= stack[mach->sp + 1]._float; - mach->mem[(da + 8) / 4]._float -= stack[mach->sp + 2]._float; - mach->mem[(da + 12) / 4]._float -= stack[mach->sp + 3]._float; - mach->sp += 4; - } - break; - case slang_asm_vec4_multiply: - /* [vec4] | vec4 > [vec4] */ - { - GLuint da = stack[mach->sp + 4]._addr; - mach->mem[da / 4]._float *= stack[mach->sp]._float; - mach->mem[(da + 4) / 4]._float *= stack[mach->sp + 1]._float; - mach->mem[(da + 8) / 4]._float *= stack[mach->sp + 2]._float; - mach->mem[(da + 12) / 4]._float *= stack[mach->sp + 3]._float; - mach->sp += 4; - } - break; - case slang_asm_vec4_divide: - /* [vec4] | vec4 > [vec4] */ - { - GLuint da = stack[mach->sp + 4]._addr; - mach->mem[da / 4]._float /= stack[mach->sp]._float; - mach->mem[(da + 4) / 4]._float /= stack[mach->sp + 1]._float; - mach->mem[(da + 8) / 4]._float /= stack[mach->sp + 2]._float; - mach->mem[(da + 12) / 4]._float /= stack[mach->sp + 3]._float; - mach->sp += 4; - } - break; - case slang_asm_vec4_negate: - /* [vec4] > [vec4] */ - { - GLuint da = stack[mach->sp]._addr; - mach->mem[da / 4]._float = -mach->mem[da / 4]._float; - mach->mem[(da + 4) / 4]._float = -mach->mem[(da + 4) / 4]._float; - mach->mem[(da + 8) / 4]._float = -mach->mem[(da + 8) / 4]._float; - mach->mem[(da + 12) / 4]._float = - -mach->mem[(da + 12) / 4]._float; - } - break; - case slang_asm_vec4_dot: - /* [vec4] | vec4 > [float] */ - { - GLuint da = stack[mach->sp + 4]._addr; - mach->mem[da / 4]._float = - mach->mem[da / 4]._float * stack[mach->sp]._float + - mach->mem[(da + 4) / 4]._float * stack[mach->sp + 1]._float + - mach->mem[(da + 8) / 4]._float * stack[mach->sp + 2]._float + - mach->mem[(da + 12) / 4]._float * stack[mach->sp + 3]._float; - mach->sp += 4; - } - break; - case slang_asm_vec4_copy: - /* [vec4] | vec4 > [vec4] */ - { - GLuint da = stack[mach->sp + a->param[0] / 4]._addr + a->param[1]; - mach->mem[da / 4]._float = stack[mach->sp]._float; - mach->mem[(da + 4) / 4]._float = stack[mach->sp + 1]._float; - mach->mem[(da + 8) / 4]._float = stack[mach->sp + 2]._float; - mach->mem[(da + 12) / 4]._float = stack[mach->sp + 3]._float; - mach->sp += 4; - } - break; - case slang_asm_vec4_deref: - /* [vec4] > vec4 */ - { - GLuint sa = stack[mach->sp]._addr; - mach->sp -= 3; - stack[mach->sp]._float = mach->mem[sa / 4]._float; - stack[mach->sp + 1]._float = mach->mem[(sa + 4) / 4]._float; - stack[mach->sp + 2]._float = mach->mem[(sa + 8) / 4]._float; - stack[mach->sp + 3]._float = mach->mem[(sa + 12) / 4]._float; - } - break; - case slang_asm_vec4_equal_int: - { - GLuint sp0 = mach->sp + a->param[0] / 4; - GLuint sp1 = mach->sp + a->param[1] / 4; - mach->sp--; - if (stack[sp0]._float == stack[sp1]._float && - stack[sp0 + 1]._float == stack[sp1 + 1]._float && - stack[sp0 + 2]._float == stack[sp1 + 2]._float && - stack[sp0 + 3]._float == stack[sp1 + 3]._float) { - stack[mach->sp]._float = 1.0f; - } - else { - stack[mach->sp]._float = 0.0f; - } - } - break; - default: - _mesa_problem(NULL, "bad slang opcode 0x%x", a->type); - return GL_FALSE; - } - } - -#if DEBUG_SLANG - if (f != NULL) - fclose(f); -#endif - - return GL_TRUE; -} diff --git a/src/mesa/shader/slang/slang_execute.h b/src/mesa/shader/slang/slang_execute.h deleted file mode 100644 index 138f139308..0000000000 --- a/src/mesa/shader/slang/slang_execute.h +++ /dev/null @@ -1,105 +0,0 @@ -/* - * Mesa 3-D graphics library - * Version: 6.5.2 - * - * Copyright (C) 2005-2006 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 SLANG_EXECUTE_H -#define SLANG_EXECUTE_H - -#include "slang_assemble.h" - -#if defined __cplusplus -extern "C" { -#endif - - -/** - * A memory location - */ -typedef union slang_machine_slot_ -{ - GLfloat _float; - GLuint _addr; -} slang_machine_slot; - -#define SLANG_MACHINE_GLOBAL_SIZE 3072 -#define SLANG_MACHINE_STACK_SIZE 1024 -#define SLANG_MACHINE_MEMORY_SIZE (SLANG_MACHINE_GLOBAL_SIZE + SLANG_MACHINE_STACK_SIZE) - - -#if defined(USE_X86_ASM) || defined(SLANG_X86) -/** - * Extra machine state for x86 execution. - */ -typedef struct -{ - GLvoid(*compiled_func) (struct slang_machine_ *); - GLuint esp_restore; - GLshort fpucntl_rnd_neg; - GLshort fpucntl_restore; -} slang_machine_x86; -#endif - - -/** - * Runtime shader machine state. - */ -typedef struct slang_machine_ -{ - GLuint ip; /**< instruction pointer, for flow control */ - GLuint sp; /**< stack pointer, for stack access */ - GLuint bp; /**< base pointer, for local variable access */ - GLboolean kill; /**< discard the fragment? */ - GLboolean exit; /**< terminate the shader */ - /** Machine memory */ - slang_machine_slot mem[SLANG_MACHINE_MEMORY_SIZE]; - struct slang_info_log_ *infolog; /**< printMESA() support */ -#if defined(USE_X86_ASM) || defined(SLANG_X86) - slang_machine_x86 x86; -#endif -} slang_machine; - - -extern GLvoid -slang_machine_ctr(slang_machine *); - -extern GLvoid -slang_machine_dtr(slang_machine *); - -extern void -slang_machine_init(slang_machine *); - -extern GLboolean -_slang_execute2(const slang_assembly_file *, slang_machine *); - - -#if defined(USE_X86_ASM) || defined(SLANG_X86) -extern GLboolean -_slang_x86_codegen(slang_machine *, slang_assembly_file *, GLuint); -#endif - - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/src/mesa/shader/slang/slang_execute_x86.c b/src/mesa/shader/slang/slang_execute_x86.c deleted file mode 100644 index 958086ff07..0000000000 --- a/src/mesa/shader/slang/slang_execute_x86.c +++ /dev/null @@ -1,754 +0,0 @@ -/* - * Mesa 3-D graphics library - * Version: 6.5 - * - * Copyright (C) 2006 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. - */ - -/** - * \file slang_execute_x86.c - * x86 back end compiler - * \author Michal Krol, Keith Whitwell - */ - -#include "imports.h" -#include "slang_compile.h" -#include "slang_execute.h" -#include "slang_library_noise.h" -#include "slang_library_texsample.h" - -#if defined(USE_X86_ASM) || defined(SLANG_X86) - -#include "x86/rtasm/x86sse.h" - -typedef struct -{ - GLuint index; - GLubyte *csr; -} fixup; - -typedef struct -{ - struct x86_function f; - struct x86_reg r_eax; - struct x86_reg r_ecx; - struct x86_reg r_edx; - struct x86_reg r_ebx; - struct x86_reg r_esp; - struct x86_reg r_ebp; - struct x86_reg r_st0; - struct x86_reg r_st1; - struct x86_reg r_st2; - struct x86_reg r_st3; - struct x86_reg r_st4; - fixup *fixups; - GLuint fixup_count; - GLubyte **labels; - slang_machine *mach; - GLubyte *l_discard; - GLubyte *l_exit; - GLshort fpucntl; -} codegen_ctx; - -static GLvoid -add_fixup(codegen_ctx * G, GLuint index, GLubyte * csr) -{ - G->fixups = - (fixup *) slang_alloc_realloc(G->fixups, G->fixup_count * sizeof(fixup), - (G->fixup_count + 1) * sizeof(fixup)); - G->fixups[G->fixup_count].index = index; - G->fixups[G->fixup_count].csr = csr; - G->fixup_count++; -} - -#ifdef NO_FAST_MATH -#define RESTORE_FPU (DEFAULT_X86_FPU) -#define RND_NEG_FPU (DEFAULT_X86_FPU | 0x400) -#else -#define RESTORE_FPU (FAST_X86_FPU) -#define RND_NEG_FPU (FAST_X86_FPU | 0x400) -#endif - -#if 0 - -/* - * XXX - * These should produce a valid code that computes powers. - * Unfortunately, it does not. - */ -static void -set_fpu_round_neg_inf(codegen_ctx * G) -{ - if (G->fpucntl != RND_NEG_FPU) { - G->fpucntl = RND_NEG_FPU; - x87_fnclex(&G->f); - x86_mov_reg_imm(&G->f, G->r_eax, - (GLint) & G->mach->x86.fpucntl_rnd_neg); - x87_fldcw(&G->f, x86_deref(G->r_eax)); - } -} - -static void -emit_x87_ex2(codegen_ctx * G) -{ - set_fpu_round_neg_inf(G); - - x87_fld(&G->f, G->r_st0); /* a a */ - x87_fprndint(&G->f); /* int(a) a */ - x87_fld(&G->f, G->r_st0); /* int(a) int(a) a */ - x87_fstp(&G->f, G->r_st3); /* int(a) a int(a) */ - x87_fsubp(&G->f, G->r_st1); /* frac(a) int(a) */ - x87_f2xm1(&G->f); /* (2^frac(a))-1 int(a) */ - x87_fld1(&G->f); /* 1 (2^frac(a))-1 int(a) */ - x87_faddp(&G->f, G->r_st1); /* 2^frac(a) int(a) */ - x87_fscale(&G->f); /* 2^a */ -} - -static void -emit_pow(codegen_ctx * G) -{ - x87_fld(&G->f, x86_deref(G->r_esp)); - x87_fld(&G->f, x86_make_disp(G->r_esp, 4)); - x87_fyl2x(&G->f); - emit_x87_ex2(G); -} - -#endif - -static GLfloat -do_ceilf(GLfloat x) -{ - return CEILF(x); -} - -static GLfloat -do_floorf(GLfloat x) -{ - return FLOORF(x); -} - -static GLfloat -do_ftoi(GLfloat x) -{ - return (GLfloat) ((GLint) (x)); -} - -static GLfloat -do_powf(GLfloat y, GLfloat x) -{ - return (GLfloat) _mesa_pow((GLdouble) x, (GLdouble) y); -} - -static GLvoid -ensure_infolog_created(slang_info_log ** infolog) -{ - if (*infolog == NULL) { - *infolog = slang_alloc_malloc(sizeof(slang_info_log)); - if (*infolog == NULL) - return; - slang_info_log_construct(*infolog); - } -} - -static GLvoid -do_print_float(slang_info_log ** infolog, GLfloat x) -{ - _mesa_printf("slang print: %f\n", x); - ensure_infolog_created(infolog); - slang_info_log_print(*infolog, "%f", x); -} - -static GLvoid -do_print_int(slang_info_log ** infolog, GLfloat x) -{ - _mesa_printf("slang print: %d\n", (GLint) (x)); - ensure_infolog_created(infolog); - slang_info_log_print(*infolog, "%d", (GLint) (x)); -} - -static GLvoid -do_print_bool(slang_info_log ** infolog, GLfloat x) -{ - _mesa_printf("slang print: %s\n", (GLint) (x) ? "true" : "false"); - ensure_infolog_created(infolog); - slang_info_log_print(*infolog, "%s", (GLint) (x) ? "true" : "false"); -} - -#define FLOAT_ONE 0x3f800000 -#define FLOAT_ZERO 0 - -static GLvoid -codegen_assem(codegen_ctx * G, slang_assembly * a, slang_info_log ** infolog) -{ - GLint disp, i; - - switch (a->type) { - case slang_asm_none: - break; - case slang_asm_float_copy: - case slang_asm_int_copy: - case slang_asm_bool_copy: - x86_mov(&G->f, G->r_eax, x86_make_disp(G->r_esp, a->param[0])); - x86_pop(&G->f, G->r_ecx); - x86_mov(&G->f, x86_make_disp(G->r_eax, a->param[1]), G->r_ecx); - break; - case slang_asm_float_move: - case slang_asm_int_move: - case slang_asm_bool_move: - x86_lea(&G->f, G->r_eax, x86_make_disp(G->r_esp, a->param[1])); - x86_add(&G->f, G->r_eax, x86_deref(G->r_esp)); - x86_mov(&G->f, G->r_eax, x86_deref(G->r_eax)); - x86_mov(&G->f, x86_make_disp(G->r_esp, a->param[0]), G->r_eax); - break; - case slang_asm_float_push: - case slang_asm_int_push: - case slang_asm_bool_push: - /* TODO: use push imm32 */ - x86_mov_reg_imm(&G->f, G->r_eax, *((GLint *) & a->literal)); - x86_push(&G->f, G->r_eax); - break; - case slang_asm_float_deref: - case slang_asm_int_deref: - case slang_asm_bool_deref: - case slang_asm_addr_deref: - x86_mov(&G->f, G->r_eax, x86_deref(G->r_esp)); - x86_mov(&G->f, G->r_eax, x86_deref(G->r_eax)); - x86_mov(&G->f, x86_deref(G->r_esp), G->r_eax); - break; - case slang_asm_float_add: - x87_fld(&G->f, x86_make_disp(G->r_esp, 4)); - x87_fld(&G->f, x86_deref(G->r_esp)); - x87_faddp(&G->f, G->r_st1); - x86_lea(&G->f, G->r_esp, x86_make_disp(G->r_esp, 4)); - x87_fstp(&G->f, x86_deref(G->r_esp)); - break; - case slang_asm_float_multiply: - x87_fld(&G->f, x86_make_disp(G->r_esp, 4)); - x87_fld(&G->f, x86_deref(G->r_esp)); - x87_fmulp(&G->f, G->r_st1); - x86_lea(&G->f, G->r_esp, x86_make_disp(G->r_esp, 4)); - x87_fstp(&G->f, x86_deref(G->r_esp)); - break; - case slang_asm_float_divide: - x87_fld(&G->f, x86_make_disp(G->r_esp, 4)); - x87_fld(&G->f, x86_deref(G->r_esp)); - x87_fdivp(&G->f, G->r_st1); - x86_lea(&G->f, G->r_esp, x86_make_disp(G->r_esp, 4)); - x87_fstp(&G->f, x86_deref(G->r_esp)); - break; - case slang_asm_float_negate: - x87_fld(&G->f, x86_deref(G->r_esp)); - x87_fchs(&G->f); - x87_fstp(&G->f, x86_deref(G->r_esp)); - break; - case slang_asm_float_less: - x87_fld(&G->f, x86_make_disp(G->r_esp, 4)); - x87_fcomp(&G->f, x86_deref(G->r_esp)); - x87_fnstsw(&G->f, G->r_eax); - /* TODO: use test r8,imm8 */ - x86_mov_reg_imm(&G->f, G->r_ecx, 0x100); - x86_test(&G->f, G->r_eax, G->r_ecx); - { - GLubyte *lab0, *lab1; - /* TODO: use jcc rel8 */ - lab0 = x86_jcc_forward(&G->f, cc_E); - x86_mov_reg_imm(&G->f, G->r_ecx, FLOAT_ONE); - /* TODO: use jmp rel8 */ - lab1 = x86_jmp_forward(&G->f); - x86_fixup_fwd_jump(&G->f, lab0); - x86_mov_reg_imm(&G->f, G->r_ecx, FLOAT_ZERO); - x86_fixup_fwd_jump(&G->f, lab1); - x86_lea(&G->f, G->r_esp, x86_make_disp(G->r_esp, 4)); - x86_mov(&G->f, x86_deref(G->r_esp), G->r_ecx); - } - break; - case slang_asm_float_equal_exp: - x87_fld(&G->f, x86_make_disp(G->r_esp, 4)); - x87_fcomp(&G->f, x86_deref(G->r_esp)); - x87_fnstsw(&G->f, G->r_eax); - /* TODO: use test r8,imm8 */ - x86_mov_reg_imm(&G->f, G->r_ecx, 0x4000); - x86_test(&G->f, G->r_eax, G->r_ecx); - { - GLubyte *lab0, *lab1; - /* TODO: use jcc rel8 */ - lab0 = x86_jcc_forward(&G->f, cc_E); - x86_mov_reg_imm(&G->f, G->r_ecx, FLOAT_ONE); - /* TODO: use jmp rel8 */ - lab1 = x86_jmp_forward(&G->f); - x86_fixup_fwd_jump(&G->f, lab0); - x86_mov_reg_imm(&G->f, G->r_ecx, FLOAT_ZERO); - x86_fixup_fwd_jump(&G->f, lab1); - x86_lea(&G->f, G->r_esp, x86_make_disp(G->r_esp, 4)); - x86_mov(&G->f, x86_deref(G->r_esp), G->r_ecx); - } - break; - case slang_asm_float_equal_int: - x86_lea(&G->f, G->r_esp, x86_make_disp(G->r_esp, -4)); - x87_fld(&G->f, x86_make_disp(G->r_esp, a->param[0] + 4)); - x87_fcomp(&G->f, x86_make_disp(G->r_esp, a->param[1] + 4)); - x87_fnstsw(&G->f, G->r_eax); - /* TODO: use test r8,imm8 */ - x86_mov_reg_imm(&G->f, G->r_ecx, 0x4000); - x86_test(&G->f, G->r_eax, G->r_ecx); - { - GLubyte *lab0, *lab1; - /* TODO: use jcc rel8 */ - lab0 = x86_jcc_forward(&G->f, cc_E); - x86_mov_reg_imm(&G->f, G->r_ecx, FLOAT_ONE); - /* TODO: use jmp rel8 */ - lab1 = x86_jmp_forward(&G->f); - x86_fixup_fwd_jump(&G->f, lab0); - x86_mov_reg_imm(&G->f, G->r_ecx, FLOAT_ZERO); - x86_fixup_fwd_jump(&G->f, lab1); - x86_mov(&G->f, x86_deref(G->r_esp), G->r_ecx); - } - break; - case slang_asm_float_to_int: - /* TODO: use fistp without rounding */ - x86_call(&G->f, (GLubyte *) (do_ftoi)); - x87_fstp(&G->f, x86_deref(G->r_esp)); - break; - case slang_asm_float_sine: - /* TODO: use fsin */ - x86_call(&G->f, (GLubyte *) _mesa_sinf); - x87_fstp(&G->f, x86_deref(G->r_esp)); - break; - case slang_asm_float_arcsine: - /* TODO: use fpatan (?) */ - x86_call(&G->f, (GLubyte *) _mesa_asinf); - x87_fstp(&G->f, x86_deref(G->r_esp)); - break; - case slang_asm_float_arctan: - /* TODO: use fpatan */ - x86_call(&G->f, (GLubyte *) _mesa_atanf); - x87_fstp(&G->f, x86_deref(G->r_esp)); - break; - case slang_asm_float_power: - /* TODO: use emit_pow() */ - x86_call(&G->f, (GLubyte *) do_powf); - x86_lea(&G->f, G->r_esp, x86_make_disp(G->r_esp, 4)); - x87_fstp(&G->f, x86_deref(G->r_esp)); - break; - case slang_asm_float_log2: - x87_fld1(&G->f); - x87_fld(&G->f, x86_deref(G->r_esp)); - x87_fyl2x(&G->f); - x87_fstp(&G->f, x86_deref(G->r_esp)); - break; - case slang_asm_float_floor: - x86_call(&G->f, (GLubyte *) do_floorf); - x87_fstp(&G->f, x86_deref(G->r_esp)); - break; - case slang_asm_float_ceil: - x86_call(&G->f, (GLubyte *) do_ceilf); - x87_fstp(&G->f, x86_deref(G->r_esp)); - break; - case slang_asm_float_noise1: - x86_call(&G->f, (GLubyte *) _slang_library_noise1); - x87_fstp(&G->f, x86_deref(G->r_esp)); - break; - case slang_asm_float_noise2: - x86_call(&G->f, (GLubyte *) _slang_library_noise2); - x86_lea(&G->f, G->r_esp, x86_make_disp(G->r_esp, 4)); - x87_fstp(&G->f, x86_deref(G->r_esp)); - break; - case slang_asm_float_noise3: - x86_call(&G->f, (GLubyte *) _slang_library_noise4); - x86_lea(&G->f, G->r_esp, x86_make_disp(G->r_esp, 8)); - x87_fstp(&G->f, x86_deref(G->r_esp)); - break; - case slang_asm_float_noise4: - x86_call(&G->f, (GLubyte *) _slang_library_noise4); - x86_lea(&G->f, G->r_esp, x86_make_disp(G->r_esp, 12)); - x87_fstp(&G->f, x86_deref(G->r_esp)); - break; - case slang_asm_int_to_float: - break; - case slang_asm_int_to_addr: - x87_fld(&G->f, x86_deref(G->r_esp)); - x87_fistp(&G->f, x86_deref(G->r_esp)); - break; - case slang_asm_addr_copy: - x86_pop(&G->f, G->r_eax); - x86_mov(&G->f, G->r_ecx, x86_deref(G->r_esp)); - x86_mov(&G->f, x86_deref(G->r_ecx), G->r_eax); - break; - case slang_asm_addr_push: - /* TODO: use push imm32 */ - x86_mov_reg_imm(&G->f, G->r_eax, (GLint) a->param[0]); - x86_push(&G->f, G->r_eax); - break; - case slang_asm_addr_add: - x86_pop(&G->f, G->r_eax); - x86_add(&G->f, x86_deref(G->r_esp), G->r_eax); - break; - case slang_asm_addr_multiply: - x86_pop(&G->f, G->r_ecx); - x86_mov(&G->f, G->r_eax, x86_deref(G->r_esp)); - x86_mul(&G->f, G->r_ecx); - x86_mov(&G->f, x86_deref(G->r_esp), G->r_eax); - break; - case slang_asm_vec4_tex1d: - x86_call(&G->f, (GLubyte *) _slang_library_tex1d); - x86_lea(&G->f, G->r_esp, x86_make_disp(G->r_esp, 12)); - break; - case slang_asm_vec4_tex2d: - x86_call(&G->f, (GLubyte *) _slang_library_tex2d); - x86_lea(&G->f, G->r_esp, x86_make_disp(G->r_esp, 16)); - break; - case slang_asm_vec4_tex3d: - x86_call(&G->f, (GLubyte *) _slang_library_tex3d); - x86_lea(&G->f, G->r_esp, x86_make_disp(G->r_esp, 20)); - break; - case slang_asm_vec4_texcube: - x86_call(&G->f, (GLubyte *) _slang_library_texcube); - x86_lea(&G->f, G->r_esp, x86_make_disp(G->r_esp, 20)); - break; - case slang_asm_vec4_shad1d: - x86_call(&G->f, (GLubyte *) _slang_library_shad1d); - x86_lea(&G->f, G->r_esp, x86_make_disp(G->r_esp, 20)); - break; - case slang_asm_vec4_shad2d: - x86_call(&G->f, (GLubyte *) _slang_library_shad2d); - x86_lea(&G->f, G->r_esp, x86_make_disp(G->r_esp, 20)); - break; - case slang_asm_jump: - add_fixup(G, a->param[0], x86_jmp_forward(&G->f)); - break; - case slang_asm_jump_if_zero: - x86_lea(&G->f, G->r_esp, x86_make_disp(G->r_esp, 4)); - x86_xor(&G->f, G->r_eax, G->r_eax); - x86_cmp(&G->f, G->r_eax, x86_make_disp(G->r_esp, -4)); - { - GLubyte *lab0; - /* TODO: use jcc rel8 */ - lab0 = x86_jcc_forward(&G->f, cc_NE); - add_fixup(G, a->param[0], x86_jmp_forward(&G->f)); - x86_fixup_fwd_jump(&G->f, lab0); - } - break; - case slang_asm_enter: - /* FIXME: x86_make_disp(esp, 0) + x86_lea() generates bogus code */ - assert(a->param[0] != 0); - x86_push(&G->f, G->r_ebp); - x86_lea(&G->f, G->r_ebp, x86_make_disp(G->r_esp, (GLint) a->param[0])); - break; - case slang_asm_leave: - x86_pop(&G->f, G->r_ebp); - break; - case slang_asm_local_alloc: - /* FIXME: x86_make_disp(esp, 0) + x86_lea() generates bogus code */ - assert(a->param[0] != 0); - x86_lea(&G->f, G->r_esp, x86_make_disp(G->r_esp, -(GLint) a->param[0])); - break; - case slang_asm_local_free: - /* FIXME: x86_make_disp(esp, 0) + x86_lea() generates bogus code */ - assert(a->param[0] != 0); - x86_lea(&G->f, G->r_esp, x86_make_disp(G->r_esp, (GLint) a->param[0])); - break; - case slang_asm_local_addr: - disp = -(GLint) (a->param[0] + a->param[1]) + 4; - if (disp != 0) { - x86_lea(&G->f, G->r_eax, x86_make_disp(G->r_ebp, disp)); - x86_push(&G->f, G->r_eax); - } - else - x86_push(&G->f, G->r_ebp); - break; - case slang_asm_global_addr: - /* TODO: use push imm32 */ - x86_mov_reg_imm(&G->f, G->r_eax, (GLint) & G->mach->mem + a->param[0]); - x86_push(&G->f, G->r_eax); - break; - case slang_asm_call: - add_fixup(G, a->param[0], x86_call_forward(&G->f)); - break; - case slang_asm_return: - x86_ret(&G->f); - break; - case slang_asm_discard: - x86_jmp(&G->f, G->l_discard); - break; - case slang_asm_exit: - x86_jmp(&G->f, G->l_exit); - break; - /* GL_MESA_shader_debug */ - case slang_asm_float_print: - /* TODO: use push imm32 */ - x86_mov_reg_imm(&G->f, G->r_eax, (GLint) (infolog)); - x86_push(&G->f, G->r_eax); - x86_call(&G->f, (GLubyte *) (do_print_float)); - x86_lea(&G->f, G->r_esp, x86_make_disp(G->r_esp, 4)); - break; - case slang_asm_int_print: - /* TODO: use push imm32 */ - x86_mov_reg_imm(&G->f, G->r_eax, (GLint) (infolog)); - x86_push(&G->f, G->r_eax); - x86_call(&G->f, (GLubyte *) do_print_int); - x86_lea(&G->f, G->r_esp, x86_make_disp(G->r_esp, 4)); - break; - case slang_asm_bool_print: - /* TODO: use push imm32 */ - x86_mov_reg_imm(&G->f, G->r_eax, (GLint) (infolog)); - x86_push(&G->f, G->r_eax); - x86_call(&G->f, (GLubyte *) do_print_bool); - x86_lea(&G->f, G->r_esp, x86_make_disp(G->r_esp, 4)); - break; - /* vec4 */ - case slang_asm_float_to_vec4: - /* [vec4] | float > [vec4] */ - x87_fld(&G->f, x86_deref(G->r_esp)); - x86_lea(&G->f, G->r_esp, x86_make_disp(G->r_esp, 4)); - x86_mov(&G->f, G->r_eax, x86_deref(G->r_esp)); - x87_fst(&G->f, x86_make_disp(G->r_eax, 12)); - x87_fst(&G->f, x86_make_disp(G->r_eax, 8)); - x87_fst(&G->f, x86_make_disp(G->r_eax, 4)); - x87_fstp(&G->f, x86_deref(G->r_eax)); - break; - case slang_asm_vec4_add: - /* [vec4] | vec4 > [vec4] */ - x86_mov(&G->f, G->r_eax, x86_make_disp(G->r_esp, 16)); - for (i = 0; i < 4; i++) - x87_fld(&G->f, x86_make_disp(G->r_eax, i * 4)); - for (i = 0; i < 4; i++) - x87_fld(&G->f, x86_make_disp(G->r_esp, i * 4)); - x86_lea(&G->f, G->r_esp, x86_make_disp(G->r_esp, 16)); - for (i = 0; i < 4; i++) - x87_faddp(&G->f, G->r_st4); - for (i = 0; i < 4; i++) - x87_fstp(&G->f, x86_make_disp(G->r_eax, 12 - i * 4)); - break; - case slang_asm_vec4_subtract: - /* [vec4] | vec4 > [vec4] */ - x86_mov(&G->f, G->r_eax, x86_make_disp(G->r_esp, 16)); - for (i = 0; i < 4; i++) - x87_fld(&G->f, x86_make_disp(G->r_eax, i * 4)); - for (i = 0; i < 4; i++) - x87_fld(&G->f, x86_make_disp(G->r_esp, i * 4)); - x86_lea(&G->f, G->r_esp, x86_make_disp(G->r_esp, 16)); - for (i = 0; i < 4; i++) - x87_fsubp(&G->f, G->r_st4); - for (i = 0; i < 4; i++) - x87_fstp(&G->f, x86_make_disp(G->r_eax, 12 - i * 4)); - break; - case slang_asm_vec4_multiply: - /* [vec4] | vec4 > [vec4] */ - x86_mov(&G->f, G->r_eax, x86_make_disp(G->r_esp, 16)); - for (i = 0; i < 4; i++) - x87_fld(&G->f, x86_make_disp(G->r_eax, i * 4)); - for (i = 0; i < 4; i++) - x87_fld(&G->f, x86_make_disp(G->r_esp, i * 4)); - x86_lea(&G->f, G->r_esp, x86_make_disp(G->r_esp, 16)); - for (i = 0; i < 4; i++) - x87_fmulp(&G->f, G->r_st4); - for (i = 0; i < 4; i++) - x87_fstp(&G->f, x86_make_disp(G->r_eax, 12 - i * 4)); - break; - case slang_asm_vec4_divide: - /* [vec4] | vec4 > [vec4] */ - x86_mov(&G->f, G->r_eax, x86_make_disp(G->r_esp, 16)); - for (i = 0; i < 4; i++) - x87_fld(&G->f, x86_make_disp(G->r_eax, i * 4)); - for (i = 0; i < 4; i++) - x87_fld(&G->f, x86_make_disp(G->r_esp, i * 4)); - x86_lea(&G->f, G->r_esp, x86_make_disp(G->r_esp, 16)); - for (i = 0; i < 4; i++) - x87_fdivp(&G->f, G->r_st4); - for (i = 0; i < 4; i++) - x87_fstp(&G->f, x86_make_disp(G->r_eax, 12 - i * 4)); - break; - case slang_asm_vec4_negate: - /* [vec4] > [vec4] */ - x86_mov(&G->f, G->r_eax, x86_deref(G->r_esp)); - for (i = 0; i < 4; i++) - x87_fld(&G->f, x86_make_disp(G->r_eax, i * 4)); - for (i = 0; i < 4; i++) { - x87_fchs(&G->f); - x87_fstp(&G->f, x86_make_disp(G->r_eax, 12 - i * 4)); - } - break; - case slang_asm_vec4_dot: - /* [vec4] | vec4 > [float] */ - for (i = 0; i < 4; i++) - x87_fld(&G->f, x86_make_disp(G->r_esp, i * 4)); - x86_lea(&G->f, G->r_esp, x86_make_disp(G->r_esp, 16)); - x86_mov(&G->f, G->r_eax, x86_deref(G->r_esp)); - for (i = 0; i < 4; i++) - x87_fld(&G->f, x86_make_disp(G->r_eax, i * 4)); - for (i = 0; i < 4; i++) - x87_fmulp(&G->f, G->r_st4); - for (i = 0; i < 3; i++) - x87_faddp(&G->f, G->r_st1); - x87_fstp(&G->f, x86_deref(G->r_eax)); - break; - case slang_asm_vec4_copy: - /* [vec4] | vec4 > [vec4] */ - x86_mov(&G->f, G->r_eax, x86_make_disp(G->r_esp, a->param[0])); - x86_pop(&G->f, G->r_ecx); - x86_pop(&G->f, G->r_edx); - x86_mov(&G->f, x86_make_disp(G->r_eax, a->param[1]), G->r_ecx); - x86_pop(&G->f, G->r_ebx); - x86_mov(&G->f, x86_make_disp(G->r_eax, a->param[1] + 4), G->r_edx); - x86_pop(&G->f, G->r_ecx); - x86_mov(&G->f, x86_make_disp(G->r_eax, a->param[1] + 8), G->r_ebx); - x86_mov(&G->f, x86_make_disp(G->r_eax, a->param[1] + 12), G->r_ecx); - break; - case slang_asm_vec4_deref: - /* [vec4] > vec4 */ - x86_mov(&G->f, G->r_eax, x86_deref(G->r_esp)); - x86_mov(&G->f, G->r_ecx, x86_make_disp(G->r_eax, 12)); - x86_mov(&G->f, G->r_edx, x86_make_disp(G->r_eax, 8)); - x86_mov(&G->f, x86_deref(G->r_esp), G->r_ecx); - x86_mov(&G->f, G->r_ebx, x86_make_disp(G->r_eax, 4)); - x86_push(&G->f, G->r_edx); - x86_mov(&G->f, G->r_ecx, x86_deref(G->r_eax)); - x86_push(&G->f, G->r_ebx); - x86_push(&G->f, G->r_ecx); - break; - case slang_asm_vec4_equal_int: - x86_lea(&G->f, G->r_esp, x86_make_disp(G->r_esp, -4)); - x86_mov_reg_imm(&G->f, G->r_edx, 0x4000); - for (i = 0; i < 4; i++) { - x87_fld(&G->f, x86_make_disp(G->r_esp, a->param[0] + 4 + i * 4)); - x87_fcomp(&G->f, x86_make_disp(G->r_esp, a->param[1] + 4 + i * 4)); - x87_fnstsw(&G->f, G->r_eax); - x86_and(&G->f, G->r_edx, G->r_eax); - } - /* TODO: use test r8,imm8 */ - x86_mov_reg_imm(&G->f, G->r_ecx, 0x4000); - x86_test(&G->f, G->r_edx, G->r_ecx); - { - GLubyte *lab0, *lab1; - - /* TODO: use jcc rel8 */ - lab0 = x86_jcc_forward(&G->f, cc_E); - x86_mov_reg_imm(&G->f, G->r_ecx, FLOAT_ONE); - /* TODO: use jmp rel8 */ - lab1 = x86_jmp_forward(&G->f); - x86_fixup_fwd_jump(&G->f, lab0); - x86_mov_reg_imm(&G->f, G->r_ecx, FLOAT_ZERO); - x86_fixup_fwd_jump(&G->f, lab1); - x86_mov(&G->f, x86_deref(G->r_esp), G->r_ecx); - } - break; - default: - _mesa_problem(NULL, "Unexpected switch case in codegen_assem"); - } -} - -GLboolean -_slang_x86_codegen(slang_machine * mach, slang_assembly_file * file, - GLuint start) -{ - codegen_ctx G; - GLubyte *j_body, *j_exit; - GLuint i; - - /* Free the old code - if any. - */ - if (mach->x86.compiled_func != NULL) { - _mesa_exec_free(mach->x86.compiled_func); - mach->x86.compiled_func = NULL; - } - - /* - * We need as much as 1M because *all* assembly, including built-in library, is - * being translated to x86. - * The built-in library occupies 450K, so we can be safe for now. - * It is going to change in the future, when we get assembly analysis running. - */ - x86_init_func_size(&G.f, 1048576); - G.r_eax = x86_make_reg(file_REG32, reg_AX); - G.r_ecx = x86_make_reg(file_REG32, reg_CX); - G.r_edx = x86_make_reg(file_REG32, reg_DX); - G.r_ebx = x86_make_reg(file_REG32, reg_BX); - G.r_esp = x86_make_reg(file_REG32, reg_SP); - G.r_ebp = x86_make_reg(file_REG32, reg_BP); - G.r_st0 = x86_make_reg(file_x87, 0); - G.r_st1 = x86_make_reg(file_x87, 1); - G.r_st2 = x86_make_reg(file_x87, 2); - G.r_st3 = x86_make_reg(file_x87, 3); - G.r_st4 = x86_make_reg(file_x87, 4); - G.fixups = NULL; - G.fixup_count = 0; - G.labels = - (GLubyte **) slang_alloc_malloc(file->count * sizeof(GLubyte *)); - G.mach = mach; - G.fpucntl = RESTORE_FPU; - - mach->x86.fpucntl_rnd_neg = RND_NEG_FPU; - mach->x86.fpucntl_restore = RESTORE_FPU; - - /* prepare stack and jump to start */ - x86_push(&G.f, G.r_ebp); - x86_mov_reg_imm(&G.f, G.r_eax, (GLint) & mach->x86.esp_restore); - x86_push(&G.f, G.r_esp); - x86_pop(&G.f, G.r_ecx); - x86_mov(&G.f, x86_deref(G.r_eax), G.r_ecx); - j_body = x86_jmp_forward(&G.f); - - /* "discard" instructions jump to this label */ - G.l_discard = x86_get_label(&G.f); - x86_mov_reg_imm(&G.f, G.r_eax, (GLint) & G.mach->kill); - x86_mov_reg_imm(&G.f, G.r_ecx, 1); - x86_mov(&G.f, x86_deref(G.r_eax), G.r_ecx); - G.l_exit = x86_get_label(&G.f); - j_exit = x86_jmp_forward(&G.f); - - for (i = 0; i < file->count; i++) { - G.labels[i] = x86_get_label(&G.f); - if (i == start) - x86_fixup_fwd_jump(&G.f, j_body); - codegen_assem(&G, &file->code[i], &mach->infolog); - } - - /* - * Restore stack and return. - * This must be handled this way, because "discard" can be invoked from any - * place in the code. - */ - x86_fixup_fwd_jump(&G.f, j_exit); - x86_mov_reg_imm(&G.f, G.r_eax, (GLint) & mach->x86.esp_restore); - x86_mov(&G.f, G.r_esp, x86_deref(G.r_eax)); - x86_pop(&G.f, G.r_ebp); - if (G.fpucntl != RESTORE_FPU) { - x87_fnclex(&G.f); - x86_mov_reg_imm(&G.f, G.r_eax, (GLint) & G.mach->x86.fpucntl_restore); - x87_fldcw(&G.f, x86_deref(G.r_eax)); - } - x86_ret(&G.f); - - /* fixup forward labels */ - for (i = 0; i < G.fixup_count; i++) { - G.f.csr = G.labels[G.fixups[i].index]; - x86_fixup_fwd_jump(&G.f, G.fixups[i].csr); - } - - slang_alloc_free(G.fixups); - slang_alloc_free(G.labels); - - /* install new code */ - mach->x86.compiled_func = (GLvoid(*)(slang_machine *)) x86_get_func(&G.f); - - return GL_TRUE; -} - -#endif diff --git a/src/mesa/shader/slang/slang_export.c b/src/mesa/shader/slang/slang_export.c deleted file mode 100644 index 9620ef0790..0000000000 --- a/src/mesa/shader/slang/slang_export.c +++ /dev/null @@ -1,386 +0,0 @@ -/* - * Mesa 3-D graphics library - * Version: 6.5 - * - * Copyright (C) 2006 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. - */ - -/** - * \file slang_export.c - * interface between assembly code and the application - * \author Michal Krol - */ - -#include "imports.h" -#include "slang_export.h" - -/* - * slang_export_data_quant - */ - -GLvoid slang_export_data_quant_ctr (slang_export_data_quant *self) -{ - self->name = SLANG_ATOM_NULL; - self->size = 0; - self->array_len = 0; - self->structure = NULL; - self->u.basic_type = GL_FLOAT; -} - -GLvoid slang_export_data_quant_dtr (slang_export_data_quant *self) -{ - if (self->structure != NULL) - { - GLuint i; - - for (i = 0; i < self->u.field_count; i++) - slang_export_data_quant_dtr (&self->structure[i]); - slang_alloc_free (self->structure); - } -} - -slang_export_data_quant *slang_export_data_quant_add_field (slang_export_data_quant *self) -{ - const GLuint n = self->u.field_count; - - self->structure = (slang_export_data_quant *) slang_alloc_realloc (self->structure, - n * sizeof (slang_export_data_quant), (n + 1) * sizeof (slang_export_data_quant)); - if (self->structure == NULL) - return NULL; - slang_export_data_quant_ctr (&self->structure[n]); - self->u.field_count++; - return &self->structure[n]; -} - -GLboolean slang_export_data_quant_array (slang_export_data_quant *self) -{ - return self->array_len != 0; -} - -GLboolean slang_export_data_quant_struct (slang_export_data_quant *self) -{ - return self->structure != NULL; -} - -GLboolean slang_export_data_quant_simple (slang_export_data_quant *self) -{ - return self->array_len == 0 && self->structure == NULL; -} - -GLenum slang_export_data_quant_type (slang_export_data_quant *self) -{ - assert (self->structure == NULL); - return self->u.basic_type; -} - -GLuint slang_export_data_quant_fields (slang_export_data_quant *self) -{ - assert (self->structure != NULL); - return self->u.field_count; -} - -GLuint slang_export_data_quant_elements (slang_export_data_quant *self) -{ - if (self->array_len == 0) - return 1; - return self->array_len; -} - -GLuint slang_export_data_quant_components (slang_export_data_quant *self) -{ - return self->size / 4; -} - -GLuint slang_export_data_quant_size (slang_export_data_quant *self) -{ - return self->size; -} - -/* - * slang_export_data_entry - */ - -GLvoid slang_export_data_entry_ctr (slang_export_data_entry *self) -{ - slang_export_data_quant_ctr (&self->quant); - self->access = slang_exp_uniform; - self->address = ~0; -} - -GLvoid slang_export_data_entry_dtr (slang_export_data_entry *self) -{ - slang_export_data_quant_dtr (&self->quant); -} - -/* - * slang_export_data_table - */ - -GLvoid slang_export_data_table_ctr (slang_export_data_table *self) -{ - self->entries = NULL; - self->count = 0; - self->atoms = NULL; -} - -GLvoid slang_export_data_table_dtr (slang_export_data_table *self) -{ - if (self->entries != NULL) - { - GLuint i; - - for (i = 0; i < self->count; i++) - slang_export_data_entry_dtr (&self->entries[i]); - slang_alloc_free (self->entries); - } -} - -slang_export_data_entry *slang_export_data_table_add (slang_export_data_table *self) -{ - const GLuint n = self->count; - - self->entries = (slang_export_data_entry *) slang_alloc_realloc (self->entries, - n * sizeof (slang_export_data_entry), (n + 1) * sizeof (slang_export_data_entry)); - if (self->entries == NULL) - return NULL; - slang_export_data_entry_ctr (&self->entries[n]); - self->count++; - return &self->entries[n]; -} - -/* - * slang_export_code_entry - */ - -static GLvoid slang_export_code_entry_ctr (slang_export_code_entry *self) -{ - self->name = SLANG_ATOM_NULL; - self->address = ~0; -} - -static GLvoid slang_export_code_entry_dtr (slang_export_code_entry *self) -{ -} - -/* - * slang_export_code_table - */ - -GLvoid slang_export_code_table_ctr (slang_export_code_table *self) -{ - self->entries = NULL; - self->count = 0; - self->atoms = NULL; -} - -GLvoid slang_export_code_table_dtr (slang_export_code_table *self) -{ - if (self->entries != NULL) - { - GLuint i; - - for (i = 0; i < self->count; i++) - slang_export_code_entry_dtr (&self->entries[i]); - slang_alloc_free (self->entries); - } -} - -slang_export_code_entry *slang_export_code_table_add (slang_export_code_table *self) -{ - const GLuint n = self->count; - - self->entries = (slang_export_code_entry *) slang_alloc_realloc (self->entries, - n * sizeof (slang_export_code_entry), (n + 1) * sizeof (slang_export_code_entry)); - if (self->entries == NULL) - return NULL; - slang_export_code_entry_ctr (&self->entries[n]); - self->count++; - return &self->entries[n]; -} - -/* - * _slang_find_exported_data() - */ - -#define EXTRACT_ERROR 0 -#define EXTRACT_BASIC 1 -#define EXTRACT_ARRAY 2 -#define EXTRACT_STRUCT 3 -#define EXTRACT_STRUCT_ARRAY 4 - -#define EXTRACT_MAXLEN 255 - -static GLuint extract_name (const char *name, char *parsed, GLuint *element, const char **end) -{ - GLuint i; - - if ((name[0] >= 'a' && name[0] <= 'z') || (name[0] >= 'A' && name[0] <= 'Z') || name[0] == '_') - { - parsed[0] = name[0]; - - for (i = 1; i < EXTRACT_MAXLEN; i++) - { - if ((name[i] >= 'a' && name[i] <= 'z') || (name[i] >= 'A' && name[i] <= 'Z') || - (name[i] >= '0' && name[i] <= '9') || name[0] == '_') - { - parsed[i] = name[i]; - } - else - { - if (name[i] == '\0') - { - parsed[i] = '\0'; - return EXTRACT_BASIC; - } - if (name[i] == '.') - { - parsed[i] = '\0'; - *end = &name[i + 1]; - return EXTRACT_STRUCT; - } - if (name[i] == '[') - { - parsed[i] = '\0'; - i++; - if (name[i] >= '0' && name[i] <= '9') - { - *element = name[i] - '0'; - for (i++; ; i++) - { - if (name[i] >= '0' && name[i] <= '9') - *element = *element * 10 + (name[i] - '0'); - else - { - if (name[i] == ']') - { - i++; - if (name[i] == '.') - { - *end = &name[i + 1]; - return EXTRACT_STRUCT_ARRAY; - } - *end = &name[i]; - return EXTRACT_ARRAY; - } - break; - } - } - } - } - break; - } - } - } - return EXTRACT_ERROR; -} - -static GLboolean validate_extracted (slang_export_data_quant *q, GLuint element, GLuint extr) -{ - switch (extr) - { - case EXTRACT_BASIC: - return GL_TRUE; - case EXTRACT_ARRAY: - return element < slang_export_data_quant_elements (q); - case EXTRACT_STRUCT: - return slang_export_data_quant_struct (q); - case EXTRACT_STRUCT_ARRAY: - return slang_export_data_quant_struct (q) && element < slang_export_data_quant_elements (q); - } - return GL_FALSE; -} - -static GLuint calculate_offset (slang_export_data_quant *q, GLuint element) -{ - if (slang_export_data_quant_array (q)) - return element * slang_export_data_quant_size (q); - return 0; -} - -static GLboolean find_exported_data (slang_export_data_quant *q, const char *name, - slang_export_data_quant **quant, GLuint *offset, slang_atom_pool *atoms) -{ - char parsed[EXTRACT_MAXLEN]; - GLuint result, element, i; - const char *end; - slang_atom atom; - const GLuint fields = slang_export_data_quant_fields (q); - - result = extract_name (name, parsed, &element, &end); - if (result == EXTRACT_ERROR) - return GL_FALSE; - - atom = slang_atom_pool_atom (atoms, parsed); - if (atom == SLANG_ATOM_NULL) - return GL_FALSE; - - for (i = 0; i < fields; i++) - if (q->structure[i].name == atom) - { - if (!validate_extracted (&q->structure[i], element, result)) - return GL_FALSE; - *offset += calculate_offset (&q->structure[i], element); - if (result == EXTRACT_BASIC || result == EXTRACT_ARRAY) - { - if (*end != '\0') - return GL_FALSE; - *quant = &q->structure[i]; - return GL_TRUE; - } - return find_exported_data (&q->structure[i], end, quant, offset, atoms); - } - return GL_FALSE; -} - -GLboolean _slang_find_exported_data (slang_export_data_table *table, const char *name, - slang_export_data_entry **entry, slang_export_data_quant **quant, GLuint *offset) -{ - char parsed[EXTRACT_MAXLEN]; - GLuint result, element, i; - const char *end; - slang_atom atom; - - result = extract_name (name, parsed, &element, &end); - if (result == EXTRACT_ERROR) - return GL_FALSE; - - atom = slang_atom_pool_atom (table->atoms, parsed); - if (atom == SLANG_ATOM_NULL) - return GL_FALSE; - - for (i = 0; i < table->count; i++) - if (table->entries[i].quant.name == atom) - { - if (!validate_extracted (&table->entries[i].quant, element, result)) - return GL_FALSE; - *entry = &table->entries[i]; - *offset = calculate_offset (&table->entries[i].quant, element); - if (result == EXTRACT_BASIC || result == EXTRACT_ARRAY) - { - if (*end != '\0') - return GL_FALSE; - *quant = &table->entries[i].quant; - return GL_TRUE; - } - return find_exported_data (&table->entries[i].quant, end, quant, offset, table->atoms); - } - return GL_FALSE; -} - diff --git a/src/mesa/shader/slang/slang_export.h b/src/mesa/shader/slang/slang_export.h deleted file mode 100644 index 40ceac19e1..0000000000 --- a/src/mesa/shader/slang/slang_export.h +++ /dev/null @@ -1,183 +0,0 @@ -/* - * Mesa 3-D graphics library - * Version: 6.5 - * - * Copyright (C) 2006 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. - */ - -#if !defined SLANG_EXPORT_H -#define SLANG_EXPORT_H - -#include "slang_utility.h" - -#if defined __cplusplus -extern "C" { -#endif - -/* - * Basic data quantity to transfer between application and assembly. - * The <size> is the actual size of the data quantity including padding, if any. It is - * used to calculate offsets from the beginning of the data. - * If the <array_len> is not 0, the data quantity is an array of <array_len> size. - * If the <structure> is not NULL, the data quantity is a struct. The <basic_type> is - * invalid and the <field_count> holds the size of the <structure> array. - * The <basic_type> values match those of <type> parameter for glGetActiveUniformARB. - */ - -typedef struct slang_export_data_quant_ -{ - slang_atom name; - GLuint size; - GLuint array_len; - struct slang_export_data_quant_ *structure; - union - { - GLenum basic_type; - GLuint field_count; - } u; -} slang_export_data_quant; - -GLvoid slang_export_data_quant_ctr (slang_export_data_quant *); -GLvoid slang_export_data_quant_dtr (slang_export_data_quant *); -slang_export_data_quant *slang_export_data_quant_add_field (slang_export_data_quant *); - -/* - * Returns GL_FALSE if the quant is not an array. - */ -GLboolean slang_export_data_quant_array (slang_export_data_quant *); - -/* - * Returns GL_FALSE if the quant is not a structure. - */ -GLboolean slang_export_data_quant_struct (slang_export_data_quant *); - -/* - * Returns GL_TRUE if the quant is neither an array nor a structure. - */ -GLboolean slang_export_data_quant_simple (slang_export_data_quant *); - -/* - * Returns basic type of the quant. It must not be a structure. - */ -GLenum slang_export_data_quant_type (slang_export_data_quant *); - -/* - * Returns number of fields in the quant that is a structure. - */ -GLuint slang_export_data_quant_fields (slang_export_data_quant *); - -/* - * Return number of elements in the quant. - * For arrays, return the size of the array. - * Otherwise, return 1. - */ -GLuint slang_export_data_quant_elements (slang_export_data_quant *); - -/* - * Returns total number of components withing the quant element. - */ -GLuint slang_export_data_quant_components (slang_export_data_quant *); - -/* - * Returns size of the quant element. - */ -GLuint slang_export_data_quant_size (slang_export_data_quant *); - -/* - * Data access pattern. Specifies how data is accessed at what frequency. - */ - -typedef enum -{ - slang_exp_uniform, - slang_exp_varying, - slang_exp_attribute -} slang_export_data_access; - -/* - * Data export entry. Holds the data type information, access pattern and base address. - */ - -typedef struct -{ - slang_export_data_quant quant; - slang_export_data_access access; - GLuint address; -} slang_export_data_entry; - -GLvoid slang_export_data_entry_ctr (slang_export_data_entry *); -GLvoid slang_export_data_entry_dtr (slang_export_data_entry *); - -/* - * Data export table. - */ - -typedef struct -{ - slang_export_data_entry *entries; - GLuint count; - slang_atom_pool *atoms; -} slang_export_data_table; - -GLvoid slang_export_data_table_ctr (slang_export_data_table *); -GLvoid slang_export_data_table_dtr (slang_export_data_table *); -slang_export_data_entry *slang_export_data_table_add (slang_export_data_table *); - -/* - * Code export entry. Contains label name and its entry point (label, address). - */ - -typedef struct -{ - slang_atom name; - GLuint address; -} slang_export_code_entry; - -/* - * Code export table. - */ - -typedef struct -{ - slang_export_code_entry *entries; - GLuint count; - slang_atom_pool *atoms; -} slang_export_code_table; - -GLvoid slang_export_code_table_ctr (slang_export_code_table *); -GLvoid slang_export_code_table_dtr (slang_export_code_table *); -slang_export_code_entry *slang_export_code_table_add (slang_export_code_table *); - -/* - * _slang_find_exported_data() - * - * Parses the name string and returns corresponding data entry, data quantity and offset. - * Returns GL_TRUE if the data is found, returns GL_FALSE otherwise. - */ - -GLboolean _slang_find_exported_data (slang_export_data_table *, const char *, - slang_export_data_entry **, slang_export_data_quant **, GLuint *); - -#ifdef __cplusplus -} -#endif - -#endif - diff --git a/src/mesa/shader/slang/slang_ir.c b/src/mesa/shader/slang/slang_ir.c new file mode 100644 index 0000000000..14a7b694bd --- /dev/null +++ b/src/mesa/shader/slang/slang_ir.c @@ -0,0 +1,389 @@ +/* + * Mesa 3-D graphics library + * Version: 6.5.3 + * + * Copyright (C) 2005-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 "imports.h" +#include "context.h" +#include "slang_ir.h" +#include "prog_print.h" + + +static const slang_ir_info IrInfo[] = { + /* binary ops */ + { IR_ADD, "IR_ADD", OPCODE_ADD, 4, 2 }, + { IR_SUB, "IR_SUB", OPCODE_SUB, 4, 2 }, + { IR_MUL, "IR_MUL", OPCODE_MUL, 4, 2 }, + { IR_DIV, "IR_DIV", OPCODE_NOP, 0, 2 }, /* XXX broke */ + { IR_DOT4, "IR_DOT_4", OPCODE_DP4, 1, 2 }, + { IR_DOT3, "IR_DOT_3", OPCODE_DP3, 1, 2 }, + { IR_CROSS, "IR_CROSS", OPCODE_XPD, 3, 2 }, + { IR_LRP, "IR_LRP", OPCODE_LRP, 4, 3 }, + { IR_MIN, "IR_MIN", OPCODE_MIN, 4, 2 }, + { IR_MAX, "IR_MAX", OPCODE_MAX, 4, 2 }, + { IR_CLAMP, "IR_CLAMP", OPCODE_NOP, 4, 3 }, /* special case: emit_clamp() */ + { IR_SEQUAL, "IR_SEQUAL", OPCODE_SEQ, 4, 2 }, + { IR_SNEQUAL, "IR_SNEQUAL", OPCODE_SNE, 4, 2 }, + { IR_SGE, "IR_SGE", OPCODE_SGE, 4, 2 }, + { IR_SGT, "IR_SGT", OPCODE_SGT, 4, 2 }, + { IR_SLE, "IR_SLE", OPCODE_SLE, 4, 2 }, + { IR_SLT, "IR_SLT", OPCODE_SLT, 4, 2 }, + { IR_POW, "IR_POW", OPCODE_POW, 1, 2 }, + /* unary ops */ + { IR_I_TO_F, "IR_I_TO_F", OPCODE_NOP, 1, 1 }, + { IR_F_TO_I, "IR_F_TO_I", OPCODE_INT, 4, 1 }, /* 4 floats to 4 ints */ + { IR_EXP, "IR_EXP", OPCODE_EXP, 1, 1 }, + { IR_EXP2, "IR_EXP2", OPCODE_EX2, 1, 1 }, + { IR_LOG2, "IR_LOG2", OPCODE_LG2, 1, 1 }, + { IR_RSQ, "IR_RSQ", OPCODE_RSQ, 1, 1 }, + { IR_RCP, "IR_RCP", OPCODE_RCP, 1, 1 }, + { IR_FLOOR, "IR_FLOOR", OPCODE_FLR, 4, 1 }, + { IR_FRAC, "IR_FRAC", OPCODE_FRC, 4, 1 }, + { IR_ABS, "IR_ABS", OPCODE_ABS, 4, 1 }, + { IR_NEG, "IR_NEG", OPCODE_NOP, 4, 1 }, /* special case: emit_negation() */ + { IR_DDX, "IR_DDX", OPCODE_DDX, 4, 1 }, + { IR_DDX, "IR_DDY", OPCODE_DDX, 4, 1 }, + { IR_SIN, "IR_SIN", OPCODE_SIN, 1, 1 }, + { IR_COS, "IR_COS", OPCODE_COS, 1, 1 }, + { IR_NOISE1, "IR_NOISE1", OPCODE_NOISE1, 1, 1 }, + { IR_NOISE2, "IR_NOISE2", OPCODE_NOISE2, 1, 1 }, + { IR_NOISE3, "IR_NOISE3", OPCODE_NOISE3, 1, 1 }, + { IR_NOISE4, "IR_NOISE4", OPCODE_NOISE4, 1, 1 }, + + /* other */ + { IR_SEQ, "IR_SEQ", OPCODE_NOP, 0, 0 }, + { IR_SCOPE, "IR_SCOPE", OPCODE_NOP, 0, 0 }, + { IR_LABEL, "IR_LABEL", OPCODE_NOP, 0, 0 }, + { IR_JUMP, "IR_JUMP", OPCODE_NOP, 0, 0 }, + { IR_IF, "IR_IF", 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 }, + { IR_MOVE, "IR_MOVE", OPCODE_NOP, 0, 1 }, + { IR_NOT, "IR_NOT", OPCODE_NOP, 1, 1 }, + { IR_VAR, "IR_VAR", OPCODE_NOP, 0, 0 }, + { IR_VAR_DECL, "IR_VAR_DECL", OPCODE_NOP, 0, 0 }, + { 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 }, /* 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 }, + { IR_NOP, NULL, OPCODE_NOP, 0, 0 } +}; + + +const slang_ir_info * +_slang_ir_info(slang_ir_opcode opcode) +{ + GLuint i; + for (i = 0; IrInfo[i].IrName; i++) { + if (IrInfo[i].IrOpcode == opcode) { + return IrInfo + i; + } + } + return NULL; +} + + +static const char * +_slang_ir_name(slang_ir_opcode opcode) +{ + return _slang_ir_info(opcode)->IrName; +} + + +/** + * Since many IR nodes might point to the same IR storage info, we need + * to be careful when deleting things. + * Before deleting an IR tree, traverse it and do refcounting on the + * IR storage nodes. Use the refcount info during delete to free things + * properly. + */ +static void +_slang_refcount_storage(slang_ir_node *n) +{ + GLuint i; + if (!n) + return; + if (n->Store) + n->Store->RefCount++; + for (i = 0; i < 3; i++) + _slang_refcount_storage(n->Children[i]); +} + + +static void +_slang_free_ir(slang_ir_node *n) +{ + GLuint i; + if (!n) + return; + + if (n->Store) { + n->Store->RefCount--; + if (n->Store->RefCount == 0) { +#if 0 + free(n->Store); +#endif + n->Store = NULL; + } + } + + for (i = 0; i < 3; i++) + _slang_free_ir(n->Children[i]); + /* Do not free n->List since it's a child elsewhere */ + free(n); +} + + +/** + * Recursively free an IR tree. + */ +void +_slang_free_ir_tree(slang_ir_node *n) +{ + _slang_refcount_storage(n); + _slang_free_ir(n); +} + + + +static const char * +swizzle_string(GLuint swizzle) +{ + static char s[6]; + GLuint i; + s[0] = '.'; + for (i = 1; i < 5; i++) { + s[i] = "xyzw"[GET_SWZ(swizzle, i-1)]; + } + s[i] = 0; + return s; +} + + +static const char * +writemask_string(GLuint writemask) +{ + static char s[6]; + GLuint i, j = 0; + s[j++] = '.'; + for (i = 0; i < 4; i++) { + if (writemask & (1 << i)) + s[j++] = "xyzw"[i]; + } + s[j] = 0; + return s; +} + + +static const char * +storage_string(const slang_ir_storage *st) +{ + static const char *files[] = { + "TEMP", + "LOCAL_PARAM", + "ENV_PARAM", + "STATE", + "INPUT", + "OUTPUT", + "NAMED_PARAM", + "CONSTANT", + "UNIFORM", + "WRITE_ONLY", + "ADDRESS", + "SAMPLER", + "UNDEFINED" + }; + static char s[100]; +#if 0 + if (st->Size == 1) + sprintf(s, "%s[%d]", files[st->File], st->Index); + else + sprintf(s, "%s[%d..%d]", files[st->File], st->Index, + st->Index + st->Size - 1); +#endif + assert(st->File < (GLint) (sizeof(files) / sizeof(files[0]))); + sprintf(s, "%s[%d]", files[st->File], st->Index); + return s; +} + + +static void +spaces(int n) +{ + while (n-- > 0) { + printf(" "); + } +} + + +void +_slang_print_ir_tree(const slang_ir_node *n, int indent) +{ +#define IND 0 + + if (!n) + return; +#if !IND + if (n->Opcode != IR_SEQ) +#else + printf("%3d:", indent); +#endif + spaces(indent); + + switch (n->Opcode) { + case IR_SEQ: +#if IND + printf("SEQ at %p\n", (void*) n); +#endif + assert(n->Children[0]); + assert(n->Children[1]); + _slang_print_ir_tree(n->Children[0], indent + IND); + _slang_print_ir_tree(n->Children[1], indent + IND); + break; + case IR_SCOPE: + printf("NEW SCOPE\n"); + assert(!n->Children[1]); + _slang_print_ir_tree(n->Children[0], indent + 3); + break; + case IR_MOVE: + printf("MOVE (writemask = %s)\n", writemask_string(n->Writemask)); + _slang_print_ir_tree(n->Children[0], indent+3); + _slang_print_ir_tree(n->Children[1], indent+3); + break; + case IR_LABEL: + printf("LABEL: %s\n", n->Label->Name); + break; + case IR_COND: + printf("COND\n"); + _slang_print_ir_tree(n->Children[0], indent + 3); + break; + case IR_JUMP: + printf("JUMP %s\n", n->Label->Name); + break; + + case IR_IF: + printf("IF \n"); + _slang_print_ir_tree(n->Children[0], indent+3); + spaces(indent); + printf("THEN\n"); + _slang_print_ir_tree(n->Children[1], indent+3); + if (n->Children[2]) { + spaces(indent); + printf("ELSE\n"); + _slang_print_ir_tree(n->Children[2], indent+3); + } + spaces(indent); + printf("ENDIF\n"); + break; + + case IR_BEGIN_SUB: + printf("BEGIN_SUB\n"); + break; + case IR_END_SUB: + printf("END_SUB\n"); + break; + case IR_RETURN: + printf("RETURN\n"); + break; + case IR_CALL: + printf("CALL\n"); + break; + + case IR_LOOP: + printf("LOOP\n"); + _slang_print_ir_tree(n->Children[0], indent+3); + if (n->Children[1]) { + spaces(indent); + printf("TAIL:\n"); + _slang_print_ir_tree(n->Children[1], indent+3); + } + spaces(indent); + printf("ENDLOOP\n"); + break; + case IR_CONT: + printf("CONT\n"); + break; + case IR_BREAK: + printf("BREAK\n"); + break; + case IR_BREAK_IF_FALSE: + printf("BREAK_IF_FALSE\n"); + _slang_print_ir_tree(n->Children[0], indent+3); + break; + case IR_BREAK_IF_TRUE: + printf("BREAK_IF_TRUE\n"); + _slang_print_ir_tree(n->Children[0], indent+3); + break; + case IR_CONT_IF_FALSE: + printf("CONT_IF_FALSE\n"); + _slang_print_ir_tree(n->Children[0], indent+3); + break; + case IR_CONT_IF_TRUE: + printf("CONT_IF_TRUE\n"); + _slang_print_ir_tree(n->Children[0], indent+3); + break; + + case IR_VAR: + printf("VAR %s%s at %s store %p\n", + (n->Var ? (char *) n->Var->a_name : "TEMP"), + swizzle_string(n->Store->Swizzle), + storage_string(n->Store), (void*) n->Store); + break; + case IR_VAR_DECL: + printf("VAR_DECL %s (%p) at %s store %p\n", + (n->Var ? (char *) n->Var->a_name : "TEMP"), + (void*) n->Var, storage_string(n->Store), + (void*) n->Store); + break; + case IR_FIELD: + printf("FIELD %s of\n", n->Field); + _slang_print_ir_tree(n->Children[0], indent+3); + break; + case IR_FLOAT: + 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\n"); + _slang_print_ir_tree(n->Children[0], indent+3); + break; + case IR_F_TO_I: + printf("FLOAT_TO_INT\n"); + _slang_print_ir_tree(n->Children[0], indent+3); + break; + case IR_SWIZZLE: + printf("SWIZZLE %s of (store %p) \n", + swizzle_string(n->Store->Swizzle), (void*) n->Store); + _slang_print_ir_tree(n->Children[0], indent + 3); + break; + default: + printf("%s (%p, %p) (store %p)\n", _slang_ir_name(n->Opcode), + (void*) n->Children[0], (void*) n->Children[1], (void*) n->Store); + _slang_print_ir_tree(n->Children[0], indent+3); + _slang_print_ir_tree(n->Children[1], indent+3); + } +} diff --git a/src/mesa/shader/slang/slang_ir.h b/src/mesa/shader/slang/slang_ir.h new file mode 100644 index 0000000000..2e90409caf --- /dev/null +++ b/src/mesa/shader/slang/slang_ir.h @@ -0,0 +1,205 @@ +/* + * Mesa 3-D graphics library + * Version: 6.5.3 + * + * Copyright (C) 2005-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. + */ + +/** + * \file slang_ir.h + * Mesa GLSL Intermediate Representation tree types and constants. + * \author Brian Paul + */ + + +#ifndef SLANG_IR_H +#define SLANG_IR_H + + +#include "imports.h" +#include "slang_compile.h" +#include "slang_label.h" +#include "mtypes.h" + + +/** + * Intermediate Representation opcodes + */ +typedef enum +{ + IR_NOP = 0, + IR_SEQ, /* sequence (eval left, then right) */ + IR_SCOPE, /* new variable scope (one child) */ + + IR_LABEL, /* target of a jump or cjump */ + IR_JUMP, /* unconditional jump */ + IR_COND, /* conditional expression/predicate */ + + IR_IF, /* high-level IF/then/else */ + /* Children[0] = conditional expression */ + /* Children[1] = if-true part */ + /* Children[2] = if-else part, or NULL */ + + IR_BEGIN_SUB, /* begin subroutine */ + IR_END_SUB, /* end subroutine */ + IR_RETURN, /* return from subroutine */ + IR_CALL, /* call subroutine */ + + IR_LOOP, /* high-level loop-begin / loop-end */ + /* Children[0] = loop body */ + /* Children[1] = loop tail code, or NULL */ + + IR_CONT, /* continue loop */ + /* n->Parent = ptr to parent IR_LOOP Node */ + IR_BREAK, /* break loop */ + + IR_BREAK_IF_TRUE, + IR_BREAK_IF_FALSE, + IR_CONT_IF_TRUE, + IR_CONT_IF_FALSE, + /* Children[0] = the condition expression */ + + IR_MOVE, + + /* vector ops: */ + IR_ADD, + IR_SUB, + IR_MUL, + IR_DIV, + IR_DOT4, + IR_DOT3, + IR_CROSS, /* vec3 cross product */ + IR_LRP, + IR_CLAMP, + IR_MIN, + IR_MAX, + IR_SEQUAL, /* Set if args are equal (vector) */ + IR_SNEQUAL, /* Set if args are not equal (vector) */ + IR_SGE, /* Set if greater or equal (vector) */ + IR_SGT, /* Set if greater than (vector) */ + IR_SLE, /* Set if less or equal (vector) */ + IR_SLT, /* Set if less than (vector) */ + IR_POW, /* x^y */ + IR_EXP, /* e^x */ + IR_EXP2, /* 2^x */ + IR_LOG2, /* log base 2 */ + IR_RSQ, /* 1/sqrt() */ + IR_RCP, /* reciprocol */ + IR_FLOOR, + IR_FRAC, + IR_ABS, /* absolute value */ + IR_NEG, /* negate */ + IR_DDX, /* derivative w.r.t. X */ + IR_DDY, /* derivative w.r.t. Y */ + IR_SIN, /* sine */ + IR_COS, /* cosine */ + IR_NOISE1, /* noise(x) */ + IR_NOISE2, /* noise(x, y) */ + IR_NOISE3, /* noise(x, y, z) */ + IR_NOISE4, /* noise(x, y, z, w) */ + + IR_EQUAL, /* boolean equality */ + IR_NOTEQUAL,/* boolean inequality */ + IR_NOT, /* boolean not */ + + IR_VAR, /* variable reference */ + IR_VAR_DECL,/* var declaration */ + + IR_ELEMENT, /* array element */ + IR_FIELD, /* struct field */ + IR_SWIZZLE, /* swizzled storage access */ + + IR_TEX, /* texture lookup */ + IR_TEXB, /* texture lookup with LOD bias */ + IR_TEXP, /* texture lookup with projection */ + + IR_FLOAT, + IR_I_TO_F, /* int[4] to float[4] conversion */ + IR_F_TO_I, /* float[4] to int[4] conversion */ + + IR_KILL /* fragment kill/discard */ +} slang_ir_opcode; + + +/** + * Describes where data storage is allocated. + */ +struct _slang_ir_storage +{ + enum register_file File; /**< PROGRAM_TEMPORARY, PROGRAM_INPUT, etc */ + GLint Index; /**< -1 means unallocated */ + GLint Size; /**< number of floats */ + GLuint Swizzle; + GLint RefCount; /**< Used during IR tree delete */ +}; + +typedef struct _slang_ir_storage slang_ir_storage; + + +/** + * Intermediate Representation (IR) tree node + * Basically a binary tree, but IR_LRP and IR_CLAMP have three children. + */ +typedef struct slang_ir_node_ +{ + slang_ir_opcode Opcode; + struct slang_ir_node_ *Children[3]; + slang_ir_storage *Store; /**< location of result of this operation */ + GLint InstLocation; /**< Location of instruction emitted for this node */ + + /** special fields depending on Opcode: */ + const char *Field; /**< If Opcode == IR_FIELD */ + int FieldOffset; /**< If Opcode == IR_FIELD */ + GLuint Writemask; /**< If Opcode == IR_MOVE */ + GLfloat Value[4]; /**< If Opcode == IR_FLOAT */ + slang_variable *Var; /**< If Opcode == IR_VAR or IR_VAR_DECL */ + struct slang_ir_node_ *List; /**< For various linked lists */ + struct slang_ir_node_ *Parent; /**< Pointer to logical parent (ie. loop) */ + slang_label *Label; /**< Used for branches */ +} slang_ir_node; + + + +/** + * Assembly and IR info + */ +typedef struct +{ + slang_ir_opcode IrOpcode; + const char *IrName; + gl_inst_opcode InstOpcode; + GLuint ResultSize, NumParams; +} slang_ir_info; + + + +extern const slang_ir_info * +_slang_ir_info(slang_ir_opcode opcode); + + +extern void +_slang_free_ir_tree(slang_ir_node *n); + + +extern void +_slang_print_ir_tree(const slang_ir_node *n, int indent); + + +#endif /* SLANG_IR_H */ diff --git a/src/mesa/shader/slang/slang_label.c b/src/mesa/shader/slang/slang_label.c new file mode 100644 index 0000000000..4d35d2e72a --- /dev/null +++ b/src/mesa/shader/slang/slang_label.c @@ -0,0 +1,77 @@ + + +/** + * Functions for managing instruction labels. + * Basically, this is used to manage the problem of forward branches where + * we have a branch instruciton but don't know the target address yet. + */ + + +#include "slang_label.h" + + +slang_label * +_slang_label_new(const char *name) +{ + slang_label *l = (slang_label *) _mesa_calloc(sizeof(slang_label)); + if (l) { + l->Name = _mesa_strdup(name); + l->Location = -1; + } + return l; +} + +void +_slang_label_delete(slang_label *l) +{ + if (l->Name) + _mesa_free(l->Name); + if (l->References) + _mesa_free(l->References); + _mesa_free(l); +} + + +void +_slang_label_add_reference(slang_label *l, GLuint inst) +{ + const GLuint oldSize = l->NumReferences * sizeof(GLuint); + assert(l->Location < 0); + l->References = _mesa_realloc(l->References, + oldSize, oldSize + sizeof(GLuint)); + if (l->References) { + l->References[l->NumReferences] = inst; + l->NumReferences++; + } +} + + +GLint +_slang_label_get_location(const slang_label *l) +{ + return l->Location; +} + + +void +_slang_label_set_location(slang_label *l, GLint location, + struct gl_program *prog) +{ + GLuint i; + + assert(l->Location < 0); + assert(location >= 0); + + l->Location = location; + + /* for the instructions that were waiting to learn the label's location: */ + for (i = 0; i < l->NumReferences; i++) { + const GLuint j = l->References[i]; + prog->Instructions[j].BranchTarget = location; + } + + if (l->References) { + _mesa_free(l->References); + l->References = NULL; + } +} diff --git a/src/mesa/shader/slang/slang_label.h b/src/mesa/shader/slang/slang_label.h new file mode 100644 index 0000000000..661624f173 --- /dev/null +++ b/src/mesa/shader/slang/slang_label.h @@ -0,0 +1,42 @@ +#ifndef SLANG_LABEL_H +#define SLANG_LABEL_H 1 + +#include "imports.h" +#include "mtypes.h" +#include "prog_instruction.h" + + +struct slang_label_ +{ + char *Name; + GLint Location; + /** + * List of instruction references (numbered starting at zero) which need + * their BranchTarget field filled in with the location eventually + * assigned to the label. + */ + GLuint NumReferences; + GLuint *References; /** Array [NumReferences] */ +}; + +typedef struct slang_label_ slang_label; + + +extern slang_label * +_slang_label_new(const char *name); + +extern void +_slang_label_delete(slang_label *l); + +extern void +_slang_label_add_reference(slang_label *l, GLuint inst); + +extern GLint +_slang_label_get_location(const slang_label *l); + +extern void +_slang_label_set_location(slang_label *l, GLint location, + struct gl_program *prog); + + +#endif /* SLANG_LABEL_H */ diff --git a/src/mesa/shader/slang/slang_library_noise.c b/src/mesa/shader/slang/slang_library_noise.c index b30bb30ce2..46075c492c 100644 --- a/src/mesa/shader/slang/slang_library_noise.c +++ b/src/mesa/shader/slang/slang_library_noise.c @@ -24,7 +24,7 @@ /* * SimplexNoise1234 - * Copyright © 2003-2005, Stefan Gustavson + * Copyright (c) 2003-2005, Stefan Gustavson * * Contact: stegu@itn.liu.se */ @@ -395,7 +395,7 @@ GLfloat _slang_library_noise4 (GLfloat x, GLfloat y, GLfloat z, GLfloat w) /* To find out which of the 24 possible simplices we're in, we need to */ /* determine the magnitude ordering of x0, y0, z0 and w0. */ /* The method below is a good way of finding the ordering of x,y,z,w and */ - /* then find the correct traversal order for the simplex we’re in. */ + /* then find the correct traversal order for the simplex we're in. */ /* First, six pair-wise comparisons are performed between each possible pair */ /* of the four coordinates, and the results are used to add up binary bits */ /* for an integer index. */ diff --git a/src/mesa/shader/slang/slang_library_texsample.c b/src/mesa/shader/slang/slang_library_texsample.c deleted file mode 100644 index 7d56880400..0000000000 --- a/src/mesa/shader/slang/slang_library_texsample.c +++ /dev/null @@ -1,172 +0,0 @@ -/* - * Mesa 3-D graphics library - * Version: 6.5 - * - * Copyright (C) 2006 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. - */ - -/** - * \file slang_library_texsample.c - * built-in library functions for texture and shadow sampling - * \author Michal Krol - */ - -#include "imports.h" -#include "context.h" -#include "colormac.h" -#include "swrast/s_context.h" -#include "slang_library_texsample.h" - -GLvoid _slang_library_tex1d (GLfloat bias, GLfloat s, GLfloat sampler, GLfloat *color) -{ - GET_CURRENT_CONTEXT(ctx); - SWcontext *swrast = SWRAST_CONTEXT(ctx); - GLuint unit = (GLuint) sampler; - GLfloat texcoord[4]; - GLfloat lambda = bias; - GLchan rgba[4]; - - texcoord[0] = s; - texcoord[1] = 0.0f; - texcoord[2] = 0.0f; - texcoord[3] = 1.0f; - - swrast->TextureSample[unit] (ctx, ctx->Texture.Unit[unit]._Current, 1, - (const GLfloat (*)[4]) texcoord, &lambda, &rgba); - color[0] = CHAN_TO_FLOAT(rgba[0]); - color[1] = CHAN_TO_FLOAT(rgba[1]); - color[2] = CHAN_TO_FLOAT(rgba[2]); - color[3] = CHAN_TO_FLOAT(rgba[3]); -} - -GLvoid _slang_library_tex2d (GLfloat bias, GLfloat s, GLfloat t, GLfloat sampler, GLfloat *color) -{ - GET_CURRENT_CONTEXT(ctx); - SWcontext *swrast = SWRAST_CONTEXT(ctx); - GLuint unit = (GLuint) sampler; - GLfloat texcoord[4]; - GLfloat lambda = bias; - GLchan rgba[4]; - - texcoord[0] = s; - texcoord[1] = t; - texcoord[2] = 0.0f; - texcoord[3] = 1.0f; - - swrast->TextureSample[unit] (ctx, ctx->Texture.Unit[unit]._Current, 1, - (const GLfloat (*)[4]) texcoord, &lambda, &rgba); - color[0] = CHAN_TO_FLOAT(rgba[0]); - color[1] = CHAN_TO_FLOAT(rgba[1]); - color[2] = CHAN_TO_FLOAT(rgba[2]); - color[3] = CHAN_TO_FLOAT(rgba[3]); -} - -GLvoid _slang_library_tex3d (GLfloat bias, GLfloat s, GLfloat t, GLfloat r, GLfloat sampler, - GLfloat *color) -{ - GET_CURRENT_CONTEXT(ctx); - SWcontext *swrast = SWRAST_CONTEXT(ctx); - GLuint unit = (GLuint) sampler; - GLfloat texcoord[4]; - GLfloat lambda = bias; - GLchan rgba[4]; - - texcoord[0] = s; - texcoord[1] = t; - texcoord[2] = r; - texcoord[3] = 1.0f; - - swrast->TextureSample[unit] (ctx, ctx->Texture.Unit[unit]._Current, 1, - (const GLfloat (*)[4]) texcoord, &lambda, &rgba); - color[0] = CHAN_TO_FLOAT(rgba[0]); - color[1] = CHAN_TO_FLOAT(rgba[1]); - color[2] = CHAN_TO_FLOAT(rgba[2]); - color[3] = CHAN_TO_FLOAT(rgba[3]); -} - -GLvoid _slang_library_texcube (GLfloat bias, GLfloat s, GLfloat t, GLfloat r, GLfloat sampler, - GLfloat *color) -{ - GET_CURRENT_CONTEXT(ctx); - SWcontext *swrast = SWRAST_CONTEXT(ctx); - GLuint unit = (GLuint) sampler; - GLfloat texcoord[4]; - GLfloat lambda = bias; - GLchan rgba[4]; - - texcoord[0] = s; - texcoord[1] = t; - texcoord[2] = r; - texcoord[3] = 1.0f; - - swrast->TextureSample[unit] (ctx, ctx->Texture.Unit[unit]._Current, 1, - (const GLfloat (*)[4]) texcoord, &lambda, &rgba); - color[0] = CHAN_TO_FLOAT(rgba[0]); - color[1] = CHAN_TO_FLOAT(rgba[1]); - color[2] = CHAN_TO_FLOAT(rgba[2]); - color[3] = CHAN_TO_FLOAT(rgba[3]); -} - -GLvoid _slang_library_shad1d (GLfloat bias, GLfloat s, GLfloat t, GLfloat r, GLfloat sampler, - GLfloat *color) -{ - GET_CURRENT_CONTEXT(ctx); - SWcontext *swrast = SWRAST_CONTEXT(ctx); - GLuint unit = (GLuint) sampler; - GLfloat texcoord[4]; - GLfloat lambda = bias; - GLchan rgba[4]; - - texcoord[0] = s; - texcoord[1] = t; - texcoord[2] = r; - texcoord[3] = 1.0f; - - swrast->TextureSample[unit] (ctx, ctx->Texture.Unit[unit]._Current, 1, - (const GLfloat (*)[4]) texcoord, &lambda, &rgba); - color[0] = CHAN_TO_FLOAT(rgba[0]); - color[1] = CHAN_TO_FLOAT(rgba[1]); - color[2] = CHAN_TO_FLOAT(rgba[2]); - color[3] = CHAN_TO_FLOAT(rgba[3]); -} - -GLvoid _slang_library_shad2d (GLfloat bias, GLfloat s, GLfloat t, GLfloat r, GLfloat sampler, - GLfloat *color) -{ - GET_CURRENT_CONTEXT(ctx); - SWcontext *swrast = SWRAST_CONTEXT(ctx); - GLuint unit = (GLuint) sampler; - GLfloat texcoord[4]; - GLfloat lambda = bias; - GLchan rgba[4]; - - texcoord[0] = s; - texcoord[1] = t; - texcoord[2] = r; - texcoord[3] = 1.0f; - - swrast->TextureSample[unit] (ctx, ctx->Texture.Unit[unit]._Current, 1, - (const GLfloat (*)[4]) texcoord, &lambda, &rgba); - color[0] = CHAN_TO_FLOAT(rgba[0]); - color[1] = CHAN_TO_FLOAT(rgba[1]); - color[2] = CHAN_TO_FLOAT(rgba[2]); - color[3] = CHAN_TO_FLOAT(rgba[3]); -} - diff --git a/src/mesa/shader/slang/slang_library_texsample.h b/src/mesa/shader/slang/slang_library_texsample.h deleted file mode 100644 index f74738ffa1..0000000000 --- a/src/mesa/shader/slang/slang_library_texsample.h +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Mesa 3-D graphics library - * Version: 6.5 - * - * Copyright (C) 2006 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. - */ - -#if !defined SLANG_LIBRARY_TEXSAMPLE_H -#define SLANG_LIBRARY_TEXSAMPLE_H - -#if defined __cplusplus -extern "C" { -#endif - -GLvoid _slang_library_tex1d (GLfloat, GLfloat, GLfloat, GLfloat *); -GLvoid _slang_library_tex2d (GLfloat, GLfloat, GLfloat, GLfloat, GLfloat *); -GLvoid _slang_library_tex3d (GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat *); -GLvoid _slang_library_texcube (GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat *); -GLvoid _slang_library_shad1d (GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat *); -GLvoid _slang_library_shad2d (GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat *); - -#ifdef __cplusplus -} -#endif - -#endif - diff --git a/src/mesa/shader/slang/slang_link.c b/src/mesa/shader/slang/slang_link.c index 6114b7c252..bcd54d6fe9 100644 --- a/src/mesa/shader/slang/slang_link.c +++ b/src/mesa/shader/slang/slang_link.c @@ -1,8 +1,8 @@ /* * Mesa 3-D graphics library - * Version: 6.6 + * 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"), @@ -24,850 +24,572 @@ /** * \file slang_link.c - * slang linker - * \author Michal Krol + * GLSL linker + * \author Brian Paul */ #include "imports.h" +#include "context.h" +#include "hash.h" +#include "macros.h" +#include "program.h" +#include "prog_instruction.h" +#include "prog_parameter.h" +#include "prog_print.h" +#include "prog_statevars.h" +#include "shader_api.h" #include "slang_link.h" -#include "slang_analyse.h" -#define TABLE_GROW(PTR,TYPE,N) \ - (PTR = (TYPE *) (slang_alloc_realloc (PTR, N * sizeof (TYPE), (N + 1) * sizeof (TYPE)))) -/* - * Check if a given name starts with "gl_". Globals with this prefix are - * treated differently, as they are built-in variables. - */ -static GLboolean -entry_has_gl_prefix (slang_atom name, slang_atom_pool *atoms) -{ - const GLchar *str; - - str = slang_atom_pool_id (atoms, name); - return str[0] == 'g' && str[1] == 'l' && str[2] == '_'; -} - -/* - * slang_active_variables - */ - -static GLvoid -slang_active_variables_ctr (slang_active_variables *self) -{ - self->table = NULL; - self->count = 0; -} - -static GLvoid -slang_active_variables_dtr (slang_active_variables *self) -{ - GLuint i; - - for (i = 0; i < self->count; i++) - slang_alloc_free (self->table[i].name); - slang_alloc_free (self->table); -} -/* - * Active variable queried by the application cannot be a structure. Queriable globals - * (uniforms and attributes) are decomposited into "simple" variables if they are - * "complex". - */ static GLboolean -add_simple_variable (slang_active_variables *self, slang_export_data_quant *q, const GLchar *name) +link_varying_vars(struct gl_shader_program *shProg, struct gl_program *prog) { - GLuint n; - slang_active_variable *var; - - n = self->count; - if (!TABLE_GROW(self->table, slang_active_variable, n)) - return GL_FALSE; + GLuint *map, i, firstVarying, newFile; + GLbitfield varsWritten, varsRead; - /* Initialize the new element. Increment table size only when it is fully initilized. */ - var = &self->table[n]; - var->quant = q; - var->name = slang_string_duplicate (name); - if (var->name == NULL) + map = (GLuint *) malloc(prog->Varying->NumParameters * sizeof(GLuint)); + if (!map) return GL_FALSE; - self->count++; - - return GL_TRUE; -} -static GLboolean -add_complex_variable (slang_active_variables *self, slang_export_data_quant *q, GLchar *name, - slang_atom_pool *atoms) -{ - slang_string_concat (name, slang_atom_pool_id (atoms, q->name)); - - /* If array, add only first element. */ - if (slang_export_data_quant_array (q)) - slang_string_concat (name, "[0]"); - - if (slang_export_data_quant_struct (q)) { - GLuint field_pos, fields, i; + for (i = 0; i < prog->Varying->NumParameters; i++) { + /* see if this varying is in the linked varying list */ + const struct gl_program_parameter *var + = prog->Varying->Parameters + i; - slang_string_concat (name, "."); - field_pos = slang_string_length (name); - - /* Break it down into individual fields. */ - fields = slang_export_data_quant_fields (q); - for (i = 0; i < fields; i++) { - if (!add_complex_variable (self, &q->structure[i], name, atoms)) + GLint j = _mesa_lookup_parameter_index(shProg->Varying, -1, var->Name); + if (j >= 0) { + /* already in list, check size */ + if (var->Size != shProg->Varying->Parameters[j].Size) { + /* error */ return GL_FALSE; - name[field_pos] = '\0'; + } + } + else { + /* not already in linked list */ + j = _mesa_add_varying(shProg->Varying, var->Name, var->Size); } + ASSERT(j >= 0); - return GL_TRUE; + map[i] = j; } - return add_simple_variable (self, q, name); -} - -/* - * Search a list of global variables with a given access (either attribute or uniform) - * and add it to the list of active variables. - */ -static GLboolean -gather_active_variables (slang_active_variables *self, slang_export_data_table *tbl, - slang_export_data_access access) -{ - GLuint i; - - for (i = 0; i < tbl->count; i++) { - if (tbl->entries[i].access == access) { - GLchar name[1024] = ""; - if (!add_complex_variable (self, &tbl->entries[i].quant, name, tbl->atoms)) - return GL_FALSE; - } + /* Varying variables are treated like other vertex program outputs + * (and like other fragment program inputs). The position of the + * first varying differs for vertex/fragment programs... + * Also, replace File=PROGRAM_VARYING with File=PROGRAM_INPUT/OUTPUT. + */ + if (prog->Target == GL_VERTEX_PROGRAM_ARB) { + firstVarying = VERT_RESULT_VAR0; + newFile = PROGRAM_OUTPUT; + } + else { + assert(prog->Target == GL_FRAGMENT_PROGRAM_ARB); + firstVarying = FRAG_ATTRIB_VAR0; + newFile = PROGRAM_INPUT; } - return GL_TRUE; -} - -/* - * slang_attrib_overrides - */ - -static GLvoid -slang_attrib_overrides_ctr (slang_attrib_overrides *self) -{ - self->table = NULL; - self->count = 0; -} - -static GLvoid -slang_attrib_overrides_dtr (slang_attrib_overrides *self) -{ - GLuint i; + /* keep track of which varying vars we read and write */ + varsWritten = varsRead = 0x0; - for (i = 0; i < self->count; i++) - slang_alloc_free (self->table[i].name); - slang_alloc_free (self->table); -} + /* OK, now scan the program/shader instructions looking for varying vars, + * replacing the old index with the new index. + */ + for (i = 0; i < prog->NumInstructions; i++) { + struct prog_instruction *inst = prog->Instructions + i; + GLuint j; -static slang_attrib_override * -lookup_attrib_override (slang_attrib_overrides *self, const GLchar *name) -{ - GLuint n, i; + if (inst->DstReg.File == PROGRAM_VARYING) { + inst->DstReg.File = newFile; + inst->DstReg.Index = map[ inst->DstReg.Index ] + firstVarying; + varsWritten |= (1 << inst->DstReg.Index); + } - n = self->count; - for (i = 0; i < n; i++) { - if (slang_string_compare (name, self->table[i].name) == 0) - return &self->table[i]; + for (j = 0; j < 3; j++) { + if (inst->SrcReg[j].File == PROGRAM_VARYING) { + inst->SrcReg[j].File = newFile; + inst->SrcReg[j].Index = map[ inst->SrcReg[j].Index ] + firstVarying; + varsRead |= (1 << inst->SrcReg[j].Index); + } + } + /* XXX update program OutputsWritten, InputsRead */ } - return NULL; -} -GLboolean -_slang_attrib_overrides_add (slang_attrib_overrides *self, GLuint index, const GLchar *name) -{ - slang_attrib_override *ovr; - GLuint n; - - /* Attribs can be overriden multiple times. Look-up the table and replace - * its index if it is found. */ - ovr = lookup_attrib_override (self, name); - if (ovr != NULL) { - ovr->index = index; - return GL_TRUE; + if (prog->Target == GL_VERTEX_PROGRAM_ARB) { + prog->OutputsWritten |= varsWritten; + } + else { + assert(prog->Target == GL_FRAGMENT_PROGRAM_ARB); + prog->InputsRead |= varsRead; } - n = self->count; - if (!TABLE_GROW(self->table, slang_attrib_override, n)) - return GL_FALSE; - /* Initialize the new element. Increment table size only when it is fully initilized. */ - ovr = &self->table[n]; - ovr->index = index; - ovr->name = slang_string_duplicate (name); - if (ovr->name == NULL) - return GL_FALSE; - self->count++; + free(map); return GL_TRUE; } -/* - * slang_uniform_bindings - */ -static GLvoid -slang_uniform_bindings_ctr (slang_uniform_bindings *self) +static GLboolean +is_uniform(GLuint file) { - self->table = NULL; - self->count = 0; + return (file == PROGRAM_ENV_PARAM || + file == PROGRAM_STATE_VAR || + file == PROGRAM_NAMED_PARAM || + file == PROGRAM_CONSTANT || + file == PROGRAM_SAMPLER || + file == PROGRAM_UNIFORM); } -static GLvoid -slang_uniform_bindings_dtr (slang_uniform_bindings *self) -{ - GLuint i; - - for (i = 0; i < self->count; i++) - slang_alloc_free (self->table[i].name); - slang_alloc_free (self->table); -} static GLboolean -add_simple_uniform_binding (slang_uniform_bindings *self, slang_export_data_quant *q, - const GLchar *name, GLuint index, GLuint addr) +link_uniform_vars(struct gl_shader_program *shProg, struct gl_program *prog) { - GLuint n, i; - slang_uniform_binding *bind; - - /* Uniform binding table is shared between vertex and fragment shaders. If the same uniform - * is declared both in a vertex and fragment shader, only one uniform entry is maintained. - * When add a uniform binding there can be an entry already allocated for it by the other - * shader. */ - n = self->count; - for (i = 0; i < n; i++) { - if (slang_string_compare (self->table[i].name, name) == 0) { - self->table[i].address[index] = addr; - return GL_TRUE; - } - } + GLuint *map, i; - if (!TABLE_GROW(self->table, slang_uniform_binding, n)) - return GL_FALSE; +#if 0 + printf("================ pre link uniforms ===============\n"); + _mesa_print_parameter_list(shProg->Uniforms); +#endif - /* Initialize the new element. Increment table size only when it is fully initilized. */ - bind = &self->table[n]; - bind->quant = q; - bind->name = slang_string_duplicate (name); - if (bind->name == NULL) + map = (GLuint *) malloc(prog->Parameters->NumParameters * sizeof(GLuint)); + if (!map) return GL_FALSE; - for (i = 0; i < SLANG_SHADER_MAX; i++) - bind->address[i] = ~0; - bind->address[index] = addr; - self->count++; - - return GL_TRUE; -} - -static GLboolean -add_complex_uniform_binding (slang_uniform_bindings *self, slang_export_data_quant *q, - GLchar *name, slang_atom_pool *atoms, GLuint index, GLuint addr) -{ - GLuint count, i; - - slang_string_concat (name, slang_atom_pool_id (atoms, q->name)); - count = slang_export_data_quant_elements (q); - - /* If array, add binding for every array element. */ - for (i = 0; i < count; i++) { - GLuint bracket_pos; - - bracket_pos = slang_string_length (name); - if (slang_export_data_quant_array (q)) - _mesa_sprintf (&name[slang_string_length (name)], "[%d]", i); - if (slang_export_data_quant_struct (q)) { - GLuint field_pos, fields, i; + for (i = 0; i < prog->Parameters->NumParameters; /* incr below*/) { + /* see if this uniform is in the linked uniform list */ + const struct gl_program_parameter *p = prog->Parameters->Parameters + i; + const GLfloat *pVals = prog->Parameters->ParameterValues[i]; + GLint j; + GLint size; - slang_string_concat (name, "."); - field_pos = slang_string_length (name); + /* sanity check */ + assert(is_uniform(p->Type)); - /* Break it down into individual fields. */ - fields = slang_export_data_quant_fields (q); - for (i = 0; i < fields; i++) { - if (!add_complex_uniform_binding (self, &q->structure[i], name, atoms, index, addr)) - return GL_FALSE; - - name[field_pos] = '\0'; - addr += slang_export_data_quant_size (&q->structure[i]); - } + if (p->Name) { + j = _mesa_lookup_parameter_index(shProg->Uniforms, -1, p->Name); } else { - if (!add_simple_uniform_binding (self, q, name, index, addr)) - return GL_FALSE; - - addr += slang_export_data_quant_size (q); + /*GLuint swizzle;*/ + ASSERT(p->Type == PROGRAM_CONSTANT); + if (_mesa_lookup_parameter_constant(shProg->Uniforms, pVals, + p->Size, &j, NULL)) { + assert(j >= 0); + } + else { + j = -1; + } } - name[bracket_pos] = '\0'; - } - - return GL_TRUE; -} - -static GLboolean -gather_uniform_bindings (slang_uniform_bindings *self, slang_export_data_table *tbl, GLuint index) -{ - GLuint n, i; - - n = tbl->count; - for (i = 0; i < n; i++) { - if (tbl->entries[i].access == slang_exp_uniform) { - GLchar name[1024] = ""; - - if (!add_complex_uniform_binding (self, &tbl->entries[i].quant, name, tbl->atoms, index, - tbl->entries[i].address)) - return GL_FALSE; + if (j >= 0) { + /* already in list, check size XXX check this */ +#if 0 + assert(p->Size == shProg->Uniforms->Parameters[j].Size); +#endif } - } - - return GL_TRUE; -} - -/* - * slang_attrib_bindings - */ - -static GLvoid -slang_attrib_bindings_ctr (slang_attrib_bindings *self) -{ - GLuint i; - - self->binding_count = 0; - for (i = 0; i < MAX_VERTEX_ATTRIBS; i++) - self->slots[i].addr = ~0; -} - -static GLvoid -slang_attrib_bindings_dtr (slang_attrib_bindings *self) -{ - GLuint i; - - for (i = 0; i < self->binding_count; i++) - slang_alloc_free (self->bindings[i].name); -} - -/* - * NOTE: If conventional vertex attribute gl_Vertex is used, application cannot use - * vertex attrib index 0 for binding override. Currently this is not checked. - * Anyways, attrib index 0 is not used when not explicitly asked. - */ + else { + /* not already in linked list */ + switch (p->Type) { + case PROGRAM_ENV_PARAM: + j = _mesa_add_named_parameter(shProg->Uniforms, p->Name, pVals); + break; + case PROGRAM_CONSTANT: + j = _mesa_add_named_constant(shProg->Uniforms, p->Name, pVals, p->Size); + break; + case PROGRAM_STATE_VAR: + j = _mesa_add_state_reference(shProg->Uniforms, p->StateIndexes); + break; + case PROGRAM_UNIFORM: + j = _mesa_add_uniform(shProg->Uniforms, p->Name, p->Size); + break; + case PROGRAM_SAMPLER: + j = _mesa_add_sampler(shProg->Uniforms, p->Name); + break; + default: + abort(); + } -static GLuint -can_allocate_attrib_slots (slang_attrib_bindings *self, GLuint index, GLuint count) -{ - GLuint i; + } + ASSERT(j >= 0); + + size = p->Size; + while (size > 0) { + map[i] = j; + i++; + j++; + size -= 4; + } - for (i = 0; i < count; i++) { - if (self->slots[index + i].addr != ~0) - break; } - return i; -} -static GLuint -allocate_attrib_slots (slang_attrib_bindings *self, GLuint count) -{ - GLuint i; - - /* Start with attrib index 1. Index 0 will be used when explicitly - * asked by application binding. */ - for (i = 1; i <= MAX_VERTEX_ATTRIBS - count; i++) { - GLuint size; - - size = can_allocate_attrib_slots (self, i, count); - if (size == count) - return i; +#if 0 + printf("================ post link uniforms ===============\n"); + _mesa_print_parameter_list(shProg->Uniforms); +#endif - /* Speed-up the search a bit. */ - i += size; +#if 0 + { + GLuint i; + for (i = 0; i < prog->Parameters->NumParameters; i++) { + printf("map[%d] = %d\n", i, map[i]); + } + _mesa_print_parameter_list(shProg->Uniforms); } +#endif - return MAX_VERTEX_ATTRIBS; -} + /* OK, now scan the program/shader instructions looking for uniform vars, + * replacing the old index with the new index. + */ + for (i = 0; i < prog->NumInstructions; i++) { + struct prog_instruction *inst = prog->Instructions + i; + GLuint j; -static GLboolean -add_attrib_binding (slang_attrib_bindings *self, slang_export_data_quant *q, const GLchar *name, - GLuint addr, GLuint index_override) -{ - GLuint slot_span, slot_fill, slot_index, i; - slang_attrib_binding *bind; - - assert (slang_export_data_quant_simple (q)); - - switch (slang_export_data_quant_type (q)) { - case GL_FLOAT: - slot_span = 1; - slot_fill = 1; - break; - case GL_FLOAT_VEC2: - slot_span = 1; - slot_fill = 2; - break; - case GL_FLOAT_VEC3: - slot_span = 1; - slot_fill = 3; - break; - case GL_FLOAT_VEC4: - slot_span = 1; - slot_fill = 4; - break; - case GL_FLOAT_MAT2: - slot_span = 2; - slot_fill = 2; - break; - case GL_FLOAT_MAT3: - slot_span = 3; - slot_fill = 3; - break; - case GL_FLOAT_MAT4: - slot_span = 4; - slot_fill = 4; - break; - default: - assert (0); - } + if (is_uniform(inst->DstReg.File)) { + inst->DstReg.Index = map[ inst->DstReg.Index ]; + } - if (index_override == MAX_VERTEX_ATTRIBS) - slot_index = allocate_attrib_slots (self, slot_span); - else if (can_allocate_attrib_slots (self, index_override, slot_span) == slot_span) - slot_index = index_override; - else - slot_index = MAX_VERTEX_ATTRIBS; + for (j = 0; j < 3; j++) { + if (is_uniform(inst->SrcReg[j].File)) { + inst->SrcReg[j].Index = map[ inst->SrcReg[j].Index ]; + } + } - if (slot_index == MAX_VERTEX_ATTRIBS) { - /* TODO: info log: error: MAX_VERTEX_ATTRIBS exceeded */ - return GL_FALSE; + if (inst->Opcode == OPCODE_TEX || + inst->Opcode == OPCODE_TXB || + inst->Opcode == OPCODE_TXP) { + /* + printf("====== remap sampler from %d to %d\n", + inst->Sampler, map[ inst->Sampler ]); + */ + inst->Sampler = map[ inst->Sampler ]; + } } - /* Initialize the new element. Increment table size only when it is fully initilized. */ - bind = &self->bindings[self->binding_count]; - bind->quant = q; - bind->name = slang_string_duplicate (name); - if (bind->name == NULL) - return GL_FALSE; - bind->first_slot_index = slot_index; - self->binding_count++; - - for (i = 0; i < slot_span; i++) { - slang_attrib_slot *slot; - - slot = &self->slots[bind->first_slot_index + i]; - slot->addr = addr + i * slot_fill * 4; - slot->fill = slot_fill; - } + free(map); return GL_TRUE; } -static GLboolean -gather_attrib_bindings (slang_attrib_bindings *self, slang_export_data_table *tbl, - slang_attrib_overrides *ovr) -{ - GLuint i; - /* First pass. Gather attribs that have overriden index slots. */ - for (i = 0; i < tbl->count; i++) { - if (tbl->entries[i].access == slang_exp_attribute && - !entry_has_gl_prefix (tbl->entries[i].quant.name, tbl->atoms)) { - slang_export_data_quant *quant; - const GLchar *id; - slang_attrib_override *ao; - - quant = &tbl->entries[i].quant; - id = slang_atom_pool_id (tbl->atoms, quant->name); - ao = lookup_attrib_override (ovr, id); - if (ao != NULL) { - if (!add_attrib_binding (self, quant, id, tbl->entries[i].address, ao->index)) - return GL_FALSE; - } - } +/** + * Resolve binding of generic vertex attributes. + * For example, if the vertex shader declared "attribute vec4 foobar" we'll + * allocate a generic vertex attribute for "foobar" and plug that value into + * the vertex program instructions. + */ +static GLboolean +_slang_resolve_attributes(struct gl_shader_program *shProg, + struct gl_program *prog) +{ + GLuint i, j; + GLbitfield usedAttributes; + GLint size = 4; /* XXX fix */ + + assert(prog->Target == GL_VERTEX_PROGRAM_ARB); + + /* Build a bitmask indicating which attribute indexes have been + * explicitly bound by the user with glBindAttributeLocation(). + */ + usedAttributes = 0x0; + for (i = 0; i < shProg->Attributes->NumParameters; i++) { + GLint attr = shProg->Attributes->Parameters[i].StateIndexes[0]; + usedAttributes |= attr; } - /* Second pass. Gather attribs that have not overriden index slots. */ - for (i = 0; i < tbl->count; i++) { - if (tbl->entries[i].access == slang_exp_attribute && - !entry_has_gl_prefix (tbl->entries[i].quant.name, tbl->atoms)) { - slang_export_data_quant *quant; - const GLchar *id; - slang_attrib_override *ao; - - quant = &tbl->entries[i].quant; - id = slang_atom_pool_id (tbl->atoms, quant->name); - ao = lookup_attrib_override (ovr, id); - if (ao == NULL) { - if (!add_attrib_binding (self, quant, id, tbl->entries[i].address, ao->index)) - return GL_FALSE; + if (!shProg->Attributes) + shProg->Attributes = _mesa_new_parameter_list(); + + /* + * Scan program for generic attribute references + */ + for (i = 0; i < prog->NumInstructions; i++) { + struct prog_instruction *inst = prog->Instructions + i; + for (j = 0; j < 3; j++) { + if (inst->SrcReg[j].File == PROGRAM_INPUT && + inst->SrcReg[j].Index >= VERT_ATTRIB_GENERIC0) { + /* this is a generic attrib */ + const GLint k = inst->SrcReg[j].Index - VERT_ATTRIB_GENERIC0; + const char *name = prog->Attributes->Parameters[k].Name; + /* See if this attrib name is in the program's attribute list + * (i.e. was bound by the user). + */ + GLint index = _mesa_lookup_parameter_index(shProg->Attributes, + -1, name); + GLint attr; + if (index >= 0) { + /* found, user must have specified a binding */ + attr = shProg->Attributes->Parameters[index].StateIndexes[0]; + } + else { + /* Not found, choose our own attribute number. + * Start at 1 since generic attribute 0 always aliases + * glVertex/position. + */ + for (attr = 1; attr < MAX_VERTEX_ATTRIBS; attr++) { + if (((1 << attr) & usedAttributes) == 0) + break; + } + if (attr == MAX_VERTEX_ATTRIBS) { + /* too many! XXX record error log */ + return GL_FALSE; + } + _mesa_add_attribute(shProg->Attributes, name, size, attr); + } + + inst->SrcReg[j].Index = VERT_ATTRIB_GENERIC0 + attr; } } } - return GL_TRUE; } -/* - * slang_varying_bindings - */ -static GLvoid -slang_varying_bindings_ctr (slang_varying_bindings *self) +/** + * Scan program instructions to update the program's InputsRead and + * OutputsWritten fields. + */ +static void +_slang_update_inputs_outputs(struct gl_program *prog) { - self->binding_count = 0; - self->slot_count = 0; -} + GLuint i, j; -static GLvoid -slang_varying_bindings_dtr (slang_varying_bindings *self) -{ - GLuint i; + prog->InputsRead = 0x0; + prog->OutputsWritten = 0x0; - for (i = 0; i < self->binding_count; i++) - slang_alloc_free (self->bindings[i].name); + for (i = 0; i < prog->NumInstructions; i++) { + const struct prog_instruction *inst = prog->Instructions + i; + const GLuint numSrc = _mesa_num_inst_src_regs(inst->Opcode); + for (j = 0; j < numSrc; j++) { + if (inst->SrcReg[j].File == PROGRAM_INPUT) { + prog->InputsRead |= 1 << inst->SrcReg[j].Index; + } + } + if (inst->DstReg.File == PROGRAM_OUTPUT) { + prog->OutputsWritten |= 1 << inst->DstReg.Index; + } + } } -static GLvoid -update_varying_slots (slang_varying_slot *slots, GLuint count, GLboolean is_vert, GLuint addr, - GLuint do_offset) + +/** + * Scan a vertex program looking for instances of + * (PROGRAM_INPUT, VERT_ATTRIB_GENERIC0 + oldAttrib) and replace with + * (PROGRAM_INPUT, VERT_ATTRIB_GENERIC0 + newAttrib). + * This is used when the user calls glBindAttribLocation on an already linked + * shader program. + */ +void +_slang_remap_attribute(struct gl_program *prog, GLuint oldAttrib, GLuint newAttrib) { - GLuint i; + GLuint i, j; - for (i = 0; i < count; i++) { - if (is_vert) - slots[i].vert_addr = addr + i * 4 * do_offset; - else - slots[i].frag_addr = addr + i * 4 * do_offset; - } -} + assert(prog->Target == GL_VERTEX_PROGRAM_ARB); -static GLboolean -add_varying_binding (slang_varying_bindings *self, slang_export_data_quant *q, const GLchar *name, - GLboolean is_vert, GLuint addr) -{ - GLuint n, slot_span, i; - slang_varying_binding *bind; - - n = self->binding_count; - slot_span = slang_export_data_quant_components (q) * slang_export_data_quant_elements (q); - for (i = 0; i < n; i++) { - if (slang_string_compare (self->bindings[i].name, name) == 0) { - /* TODO: data quantities must match, or else link fails */ - update_varying_slots (&self->slots[self->bindings[i].first_slot_index], slot_span, - is_vert, addr, 1); - return GL_TRUE; + for (i = 0; i < prog->NumInstructions; i++) { + struct prog_instruction *inst = prog->Instructions + i; + for (j = 0; j < 3; j++) { + if (inst->SrcReg[j].File == PROGRAM_INPUT) { + if (inst->SrcReg[j].Index == VERT_ATTRIB_GENERIC0 + oldAttrib) { + inst->SrcReg[j].Index = VERT_ATTRIB_GENERIC0 + newAttrib; + } + } } } - if (self->slot_count + slot_span > MAX_VARYING_FLOATS) { - /* TODO: info log: error: MAX_VARYING_FLOATS exceeded */ - return GL_FALSE; - } - - /* Initialize the new element. Increment table size only when it is fully initilized. */ - bind = &self->bindings[n]; - bind->quant = q; - bind->name = slang_string_duplicate (name); - if (bind->name == NULL) - return GL_FALSE; - bind->first_slot_index = self->slot_count; - self->binding_count++; + _slang_update_inputs_outputs(prog); +} - update_varying_slots (&self->slots[bind->first_slot_index], slot_span, is_vert, addr, 1); - update_varying_slots (&self->slots[bind->first_slot_index], slot_span, !is_vert, ~0, 0); - self->slot_count += slot_span; - return GL_TRUE; -} -static GLboolean -gather_varying_bindings (slang_varying_bindings *self, slang_export_data_table *tbl, - GLboolean is_vert) +/** + * Scan program for texture instructions, lookup sampler/uniform's value + * to determine which texture unit to use. + * Also, update the program's TexturesUsed[] array. + */ +void +_slang_resolve_samplers(struct gl_shader_program *shProg, + struct gl_program *prog) { GLuint i; - for (i = 0; i < tbl->count; i++) { - if (tbl->entries[i].access == slang_exp_varying && - !entry_has_gl_prefix (tbl->entries[i].quant.name, tbl->atoms)) { - if (!add_varying_binding (self, &tbl->entries[i].quant, - slang_atom_pool_id (tbl->atoms, tbl->entries[i].quant.name), - is_vert, tbl->entries[i].address)) - return GL_FALSE; + for (i = 0; i < MAX_TEXTURE_IMAGE_UNITS; i++) + prog->TexturesUsed[i] = 0; + + for (i = 0; i < prog->NumInstructions; i++) { + struct prog_instruction *inst = prog->Instructions + i; + if (inst->Opcode == OPCODE_TEX || + inst->Opcode == OPCODE_TXB || + inst->Opcode == OPCODE_TXP) { + GLint sampleUnit = (GLint) shProg->Uniforms->ParameterValues[inst->Sampler][0]; + assert(sampleUnit < MAX_TEXTURE_IMAGE_UNITS); + inst->TexSrcUnit = sampleUnit; + + prog->TexturesUsed[inst->TexSrcUnit] |= (1 << inst->TexSrcTarget); } } - - return GL_TRUE; } -/* - * slang_texture_bindings - */ -GLvoid -_slang_texture_usages_ctr (slang_texture_usages *self) -{ - self->table = NULL; - self->count = 0; -} -GLvoid -_slang_texture_usages_dtr (slang_texture_usages *self) +/** cast wrapper */ +static struct gl_vertex_program * +vertex_program(struct gl_program *prog) { - slang_alloc_free (self->table); + assert(prog->Target == GL_VERTEX_PROGRAM_ARB); + return (struct gl_vertex_program *) prog; } -/* - * slang_program - */ - -GLvoid -_slang_program_ctr (slang_program *self) -{ - GLuint i; - - slang_active_variables_ctr (&self->active_uniforms); - slang_active_variables_ctr (&self->active_attribs); - slang_attrib_overrides_ctr (&self->attrib_overrides); - slang_uniform_bindings_ctr (&self->uniforms); - slang_attrib_bindings_ctr (&self->attribs); - slang_varying_bindings_ctr (&self->varyings); - _slang_texture_usages_ctr (&self->texture_usage); - for (i = 0; i < SLANG_SHADER_MAX; i++) { - GLuint j; - for (j = 0; j < SLANG_COMMON_FIXED_MAX; j++) - self->common_fixed_entries[i][j] = ~0; - for (j = 0; j < SLANG_COMMON_CODE_MAX; j++) - self->code[i][j] = ~0; - self->machines[i] = NULL; - self->assemblies[i] = NULL; - } - for (i = 0; i < SLANG_VERTEX_FIXED_MAX; i++) - self->vertex_fixed_entries[i] = ~0; - for (i = 0; i < SLANG_FRAGMENT_FIXED_MAX; i++) - self->fragment_fixed_entries[i] = ~0; -} - -GLvoid -_slang_program_dtr (slang_program *self) +/** cast wrapper */ +static struct gl_fragment_program * +fragment_program(struct gl_program *prog) { - slang_active_variables_dtr (&self->active_uniforms); - slang_active_variables_dtr (&self->active_attribs); - slang_attrib_overrides_dtr (&self->attrib_overrides); - slang_uniform_bindings_dtr (&self->uniforms); - slang_attrib_bindings_dtr (&self->attribs); - slang_varying_bindings_dtr (&self->varyings); - _slang_texture_usages_dtr (&self->texture_usage); + assert(prog->Target == GL_FRAGMENT_PROGRAM_ARB); + return (struct gl_fragment_program *) prog; } -GLvoid -_slang_program_rst (slang_program *self) -{ - GLuint i; - - slang_active_variables_dtr (&self->active_uniforms); - slang_active_variables_dtr (&self->active_attribs); - slang_uniform_bindings_dtr (&self->uniforms); - slang_attrib_bindings_dtr (&self->attribs); - slang_varying_bindings_dtr (&self->varyings); - _slang_texture_usages_dtr (&self->texture_usage); - - slang_active_variables_ctr (&self->active_uniforms); - slang_active_variables_ctr (&self->active_attribs); - slang_uniform_bindings_ctr (&self->uniforms); - slang_attrib_bindings_ctr (&self->attribs); - slang_varying_bindings_ctr (&self->varyings); - _slang_texture_usages_ctr (&self->texture_usage); - for (i = 0; i < SLANG_SHADER_MAX; i++) { - GLuint j; - - for (j = 0; j < SLANG_COMMON_FIXED_MAX; j++) - self->common_fixed_entries[i][j] = ~0; - for (j = 0; j < SLANG_COMMON_CODE_MAX; j++) - self->code[i][j] = ~0; - } - for (i = 0; i < SLANG_VERTEX_FIXED_MAX; i++) - self->vertex_fixed_entries[i] = ~0; - for (i = 0; i < SLANG_FRAGMENT_FIXED_MAX; i++) - self->fragment_fixed_entries[i] = ~0; -} -/* - * _slang_link() +/** + * Shader linker. Currently: + * + * 1. The last attached vertex shader and fragment shader are linked. + * 2. Varying vars in the two shaders are combined so their locations + * agree between the vertex and fragment stages. They're treated as + * vertex program output attribs and as fragment program input attribs. + * 3. Uniform vars (including state references, constants, etc) from the + * vertex and fragment shaders are merged into one group. Recall that + * GLSL uniforms are shared by all linked shaders. + * 4. The vertex and fragment programs are cloned and modified to update + * src/dst register references so they use the new, linked uniform/ + * varying storage locations. */ - -static GLuint -gd (slang_export_data_table *tbl, const GLchar *name) +void +_slang_link(GLcontext *ctx, + GLhandleARB programObj, + struct gl_shader_program *shProg) { - slang_atom atom; + const struct gl_vertex_program *vertProg; + const struct gl_fragment_program *fragProg; GLuint i; - atom = slang_atom_pool_atom (tbl->atoms, name); - if (atom == SLANG_ATOM_NULL) - return ~0; - - for (i = 0; i < tbl->count; i++) { - if (atom == tbl->entries[i].quant.name) - return tbl->entries[i].address; + _mesa_free_shader_program_data(ctx, shProg); + + shProg->Uniforms = _mesa_new_parameter_list(); + shProg->Varying = _mesa_new_parameter_list(); + + /** + * Find attached vertex shader, fragment shader + */ + vertProg = NULL; + fragProg = NULL; + for (i = 0; i < shProg->NumShaders; i++) { + if (shProg->Shaders[i]->Type == GL_VERTEX_SHADER) + vertProg = vertex_program(shProg->Shaders[i]->Programs[0]); + 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_link()"); } - return ~0; -} - -static GLvoid -resolve_common_fixed (GLuint e[], slang_export_data_table *tbl) -{ - e[SLANG_COMMON_FIXED_MODELVIEWMATRIX] = gd (tbl, "gl_ModelViewMatrix"); - e[SLANG_COMMON_FIXED_PROJECTIONMATRIX] = gd (tbl, "gl_ProjectionMatrix"); - e[SLANG_COMMON_FIXED_MODELVIEWPROJECTIONMATRIX] = gd (tbl, "gl_ModelViewProjectionMatrix"); - e[SLANG_COMMON_FIXED_TEXTUREMATRIX] = gd (tbl, "gl_TextureMatrix"); - e[SLANG_COMMON_FIXED_NORMALMATRIX] = gd (tbl, "gl_NormalMatrix"); - e[SLANG_COMMON_FIXED_MODELVIEWMATRIXINVERSE] = gd (tbl, "gl_ModelViewMatrixInverse"); - e[SLANG_COMMON_FIXED_PROJECTIONMATRIXINVERSE] = gd (tbl, "gl_ProjectionMatrixInverse"); - e[SLANG_COMMON_FIXED_MODELVIEWPROJECTIONMATRIXINVERSE] = gd (tbl, "gl_ModelViewProjectionMatrixInverse"); - e[SLANG_COMMON_FIXED_TEXTUREMATRIXINVERSE] = gd (tbl, "gl_TextureMatrixInverse"); - e[SLANG_COMMON_FIXED_MODELVIEWMATRIXTRANSPOSE] = gd (tbl, "gl_ModelViewMatrixTranspose"); - e[SLANG_COMMON_FIXED_PROJECTIONMATRIXTRANSPOSE] = gd (tbl, "gl_ProjectionMatrixTranspose"); - e[SLANG_COMMON_FIXED_MODELVIEWPROJECTIONMATRIXTRANSPOSE] = gd (tbl, "gl_ModelViewProjectionMatrixTranspose"); - e[SLANG_COMMON_FIXED_TEXTUREMATRIXTRANSPOSE] = gd (tbl, "gl_TextureMatrixTranspose"); - e[SLANG_COMMON_FIXED_MODELVIEWMATRIXINVERSETRANSPOSE] = gd (tbl, "gl_ModelViewMatrixInverseTranspose"); - e[SLANG_COMMON_FIXED_PROJECTIONMATRIXINVERSETRANSPOSE] = gd (tbl, "gl_ProjectionMatrixInverseTranspose"); - e[SLANG_COMMON_FIXED_MODELVIEWPROJECTIONMATRIXINVERSETRANSPOSE] = gd (tbl, "gl_ModelViewProjectionMatrixInverseTranspose"); - e[SLANG_COMMON_FIXED_TEXTUREMATRIXINVERSETRANSPOSE] = gd (tbl, "gl_TextureMatrixInverseTranspose"); - e[SLANG_COMMON_FIXED_NORMALSCALE] = gd (tbl, "gl_NormalScale"); - e[SLANG_COMMON_FIXED_DEPTHRANGE] = gd (tbl, "gl_DepthRange"); - e[SLANG_COMMON_FIXED_CLIPPLANE] = gd (tbl, "gl_ClipPlane"); - e[SLANG_COMMON_FIXED_POINT] = gd (tbl, "gl_Point"); - e[SLANG_COMMON_FIXED_FRONTMATERIAL] = gd (tbl, "gl_FrontMaterial"); - e[SLANG_COMMON_FIXED_BACKMATERIAL] = gd (tbl, "gl_BackMaterial"); - e[SLANG_COMMON_FIXED_LIGHTSOURCE] = gd (tbl, "gl_LightSource"); - e[SLANG_COMMON_FIXED_LIGHTMODEL] = gd (tbl, "gl_LightModel"); - e[SLANG_COMMON_FIXED_FRONTLIGHTMODELPRODUCT] = gd (tbl, "gl_FrontLightModelProduct"); - e[SLANG_COMMON_FIXED_BACKLIGHTMODELPRODUCT] = gd (tbl, "gl_BackLightModelProduct"); - e[SLANG_COMMON_FIXED_FRONTLIGHTPRODUCT] = gd (tbl, "gl_FrontLightProduct"); - e[SLANG_COMMON_FIXED_BACKLIGHTPRODUCT] = gd (tbl, "gl_BackLightProduct"); - e[SLANG_COMMON_FIXED_TEXTUREENVCOLOR] = gd (tbl, "gl_TextureEnvColor"); - e[SLANG_COMMON_FIXED_EYEPLANES] = gd (tbl, "gl_EyePlaneS"); - e[SLANG_COMMON_FIXED_EYEPLANET] = gd (tbl, "gl_EyePlaneT"); - e[SLANG_COMMON_FIXED_EYEPLANER] = gd (tbl, "gl_EyePlaneR"); - e[SLANG_COMMON_FIXED_EYEPLANEQ] = gd (tbl, "gl_EyePlaneQ"); - e[SLANG_COMMON_FIXED_OBJECTPLANES] = gd (tbl, "gl_ObjectPlaneS"); - e[SLANG_COMMON_FIXED_OBJECTPLANET] = gd (tbl, "gl_ObjectPlaneT"); - e[SLANG_COMMON_FIXED_OBJECTPLANER] = gd (tbl, "gl_ObjectPlaneR"); - e[SLANG_COMMON_FIXED_OBJECTPLANEQ] = gd (tbl, "gl_ObjectPlaneQ"); - e[SLANG_COMMON_FIXED_FOG] = gd (tbl, "gl_Fog"); -} -static GLvoid -resolve_vertex_fixed (GLuint e[], slang_export_data_table *tbl) -{ - e[SLANG_VERTEX_FIXED_POSITION] = gd (tbl, "gl_Position"); - e[SLANG_VERTEX_FIXED_POINTSIZE] = gd (tbl, "gl_PointSize"); - e[SLANG_VERTEX_FIXED_CLIPVERTEX] = gd (tbl, "gl_ClipVertex"); - e[SLANG_VERTEX_FIXED_COLOR] = gd (tbl, "gl_Color"); - e[SLANG_VERTEX_FIXED_SECONDARYCOLOR] = gd (tbl, "gl_SecondaryColor"); - e[SLANG_VERTEX_FIXED_NORMAL] = gd (tbl, "gl_Normal"); - e[SLANG_VERTEX_FIXED_VERTEX] = gd (tbl, "gl_Vertex"); - e[SLANG_VERTEX_FIXED_MULTITEXCOORD0] = gd (tbl, "gl_MultiTexCoord0"); - e[SLANG_VERTEX_FIXED_MULTITEXCOORD1] = gd (tbl, "gl_MultiTexCoord1"); - e[SLANG_VERTEX_FIXED_MULTITEXCOORD2] = gd (tbl, "gl_MultiTexCoord2"); - e[SLANG_VERTEX_FIXED_MULTITEXCOORD3] = gd (tbl, "gl_MultiTexCoord3"); - e[SLANG_VERTEX_FIXED_MULTITEXCOORD4] = gd (tbl, "gl_MultiTexCoord4"); - e[SLANG_VERTEX_FIXED_MULTITEXCOORD5] = gd (tbl, "gl_MultiTexCoord5"); - e[SLANG_VERTEX_FIXED_MULTITEXCOORD6] = gd (tbl, "gl_MultiTexCoord6"); - e[SLANG_VERTEX_FIXED_MULTITEXCOORD7] = gd (tbl, "gl_MultiTexCoord7"); - e[SLANG_VERTEX_FIXED_FOGCOORD] = gd (tbl, "gl_FogCoord"); - e[SLANG_VERTEX_FIXED_FRONTCOLOR] = gd (tbl, "gl_FrontColor"); - e[SLANG_VERTEX_FIXED_BACKCOLOR] = gd (tbl, "gl_BackColor"); - e[SLANG_VERTEX_FIXED_FRONTSECONDARYCOLOR] = gd (tbl, "gl_FrontSecondaryColor"); - e[SLANG_VERTEX_FIXED_BACKSECONDARYCOLOR] = gd (tbl, "gl_BackSecondaryColor"); - e[SLANG_VERTEX_FIXED_TEXCOORD] = gd (tbl, "gl_TexCoord"); - e[SLANG_VERTEX_FIXED_FOGFRAGCOORD] = gd (tbl, "gl_FogFragCoord"); -} + /* + * Make copies of the vertex/fragment programs now since we'll be + * changing src/dst registers after merging the uniforms and varying vars. + */ + if (vertProg) { + shProg->VertexProgram + = vertex_program(_mesa_clone_program(ctx, &vertProg->Base)); + } + else { + shProg->VertexProgram = NULL; + } -static GLvoid -resolve_fragment_fixed (GLuint e[], slang_export_data_table *tbl) -{ - e[SLANG_FRAGMENT_FIXED_FRAGCOORD] = gd (tbl, "gl_FragCoord"); - e[SLANG_FRAGMENT_FIXED_FRONTFACING] = gd (tbl, "gl_FrontFacing"); - e[SLANG_FRAGMENT_FIXED_FRAGCOLOR] = gd (tbl, "gl_FragColor"); - e[SLANG_FRAGMENT_FIXED_FRAGDATA] = gd (tbl, "gl_FragData"); - e[SLANG_FRAGMENT_FIXED_FRAGDEPTH] = gd (tbl, "gl_FragDepth"); - e[SLANG_FRAGMENT_FIXED_COLOR] = gd (tbl, "gl_Color"); - e[SLANG_FRAGMENT_FIXED_SECONDARYCOLOR] = gd (tbl, "gl_SecondaryColor"); - e[SLANG_FRAGMENT_FIXED_TEXCOORD] = gd (tbl, "gl_TexCoord"); - e[SLANG_FRAGMENT_FIXED_FOGFRAGCOORD] = gd (tbl, "gl_FogFragCoord"); -} + if (fragProg) { + shProg->FragmentProgram + = fragment_program(_mesa_clone_program(ctx, &fragProg->Base)); + } + else { + shProg->FragmentProgram = NULL; + } -static GLuint -gc (slang_export_code_table *tbl, const GLchar *name) -{ - slang_atom atom; - GLuint i; + if (shProg->VertexProgram) + link_varying_vars(shProg, &shProg->VertexProgram->Base); + if (shProg->FragmentProgram) + link_varying_vars(shProg, &shProg->FragmentProgram->Base); - atom = slang_atom_pool_atom (tbl->atoms, name); - if (atom == SLANG_ATOM_NULL) - return ~0; + if (shProg->VertexProgram) + link_uniform_vars(shProg, &shProg->VertexProgram->Base); + if (shProg->FragmentProgram) + link_uniform_vars(shProg, &shProg->FragmentProgram->Base); - for (i = 0; i < tbl->count; i++) { - if (atom == tbl->entries[i].name) - return tbl->entries[i].address; + /* The vertex and fragment programs share a common set of uniforms now */ + if (shProg->VertexProgram) { + _mesa_free_parameter_list(shProg->VertexProgram->Base.Parameters); + shProg->VertexProgram->Base.Parameters = shProg->Uniforms; + } + if (shProg->FragmentProgram) { + _mesa_free_parameter_list(shProg->FragmentProgram->Base.Parameters); + shProg->FragmentProgram->Base.Parameters = shProg->Uniforms; } - return ~0; -} - -static GLvoid -resolve_common_code (GLuint code[], slang_export_code_table *tbl) -{ - code[SLANG_COMMON_CODE_MAIN] = gc (tbl, "@main"); -} - -GLboolean -_slang_link (slang_program *prog, slang_code_object **objects, GLuint count) -{ - GLuint i; - for (i = 0; i < count; i++) { - GLuint index; + if (shProg->VertexProgram) { + _slang_resolve_samplers(shProg, &shProg->VertexProgram->Base); + } + if (shProg->FragmentProgram) { + _slang_resolve_samplers(shProg, &shProg->FragmentProgram->Base); + } - if (objects[i]->unit.type == slang_unit_fragment_shader) { - index = SLANG_SHADER_FRAGMENT; - resolve_fragment_fixed (prog->fragment_fixed_entries, &objects[i]->expdata); + if (shProg->VertexProgram) { + if (!_slang_resolve_attributes(shProg, &shProg->VertexProgram->Base)) { + /*goto cleanup;*/ + _mesa_problem(ctx, "_slang_resolve_attributes() failed"); + abort(); /* XXX fix */ } - else { - index = SLANG_SHADER_VERTEX; - resolve_vertex_fixed (prog->vertex_fixed_entries, &objects[i]->expdata); - if (!gather_attrib_bindings (&prog->attribs, &objects[i]->expdata, - &prog->attrib_overrides)) - return GL_FALSE; - } - - if (!gather_active_variables (&prog->active_uniforms, &objects[i]->expdata, slang_exp_uniform)) - return GL_FALSE; - if (!gather_active_variables (&prog->active_attribs, &objects[i]->expdata, slang_exp_attribute)) - return GL_FALSE; - if (!gather_uniform_bindings (&prog->uniforms, &objects[i]->expdata, index)) - return GL_FALSE; - if (!gather_varying_bindings (&prog->varyings, &objects[i]->expdata, - index == SLANG_SHADER_VERTEX)) - return GL_FALSE; - resolve_common_fixed (prog->common_fixed_entries[index], &objects[i]->expdata); - resolve_common_code (prog->code[index], &objects[i]->expcode); - prog->machines[index] = &objects[i]->machine; - prog->assemblies[index] = &objects[i]->assembly; } - /* TODO: all varyings read by fragment shader must be written by vertex shader */ + if (shProg->VertexProgram) { + _slang_update_inputs_outputs(&shProg->VertexProgram->Base); + if (!(shProg->VertexProgram->Base.OutputsWritten & (1 << VERT_RESULT_HPOS))) { + /* the vertex program did not compute a vertex position */ + if (shProg->InfoLog) { + _mesa_free(shProg->InfoLog); + } + shProg->InfoLog + = _mesa_strdup("gl_Position was not written by vertex shader\n"); + shProg->LinkStatus = GL_FALSE; + return; + } + } + if (shProg->FragmentProgram) + _slang_update_inputs_outputs(&shProg->FragmentProgram->Base); + + if (fragProg && shProg->FragmentProgram) { +#if 1 + printf("************** original fragment program\n"); + _mesa_print_program(&fragProg->Base); + _mesa_print_program_parameters(ctx, &fragProg->Base); +#endif +#if 1 + printf("************** linked fragment prog\n"); + _mesa_print_program(&shProg->FragmentProgram->Base); + _mesa_print_program_parameters(ctx, &shProg->FragmentProgram->Base); +#endif + } - if (!_slang_analyse_texture_usage (prog)) - return GL_FALSE; + if (vertProg && shProg->VertexProgram) { +#if 1 + printf("************** original vertex program\n"); + _mesa_print_program(&vertProg->Base); + _mesa_print_program_parameters(ctx, &vertProg->Base); +#endif +#if 1 + printf("************** linked vertex prog\n"); + _mesa_print_program(&shProg->VertexProgram->Base); + _mesa_print_program_parameters(ctx, &shProg->VertexProgram->Base); +#endif + } - return GL_TRUE; + shProg->LinkStatus = (shProg->VertexProgram || shProg->FragmentProgram); } diff --git a/src/mesa/shader/slang/slang_link.h b/src/mesa/shader/slang/slang_link.h index 433964223a..606b9e46b1 100644 --- a/src/mesa/shader/slang/slang_link.h +++ b/src/mesa/shader/slang/slang_link.h @@ -1,8 +1,8 @@ /* * Mesa 3-D graphics library - * Version: 6.5.2 + * 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"), @@ -22,332 +22,24 @@ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -#if !defined SLANG_LINK_H -#define SLANG_LINK_H +#ifndef SLANG_LINK_H +#define SLANG_LINK_H 1 #include "slang_compile.h" -#if defined __cplusplus -extern "C" { -#endif - -enum -{ - SLANG_SHADER_VERTEX, - SLANG_SHADER_FRAGMENT, - SLANG_SHADER_MAX -}; - - -/** - * Active variables. - * - * Active uniforms/attribs can be queried by the application to get a - * list of uniforms/attribs actually used by shaders (uniforms) or - * vertex shader only (attribs). - */ -/*@{*/ -typedef struct -{ - slang_export_data_quant *quant; - GLchar *name; -} slang_active_variable; - -typedef struct -{ - slang_active_variable *table; - GLuint count; -} slang_active_variables; -/*@}*/ - - -/** - * Attrib binding override. - * - * The application can override GL attrib binding by specifying its - * preferred index assignment for a given attrib name. Those overrides - * are taken into account while linking the program. - */ -/*@{*/ -typedef struct -{ - GLuint index; - GLchar *name; -} slang_attrib_override; - -typedef struct -{ - slang_attrib_override *table; - GLuint count; -} slang_attrib_overrides; -/*@}*/ - - -extern GLboolean -_slang_attrib_overrides_add (slang_attrib_overrides *, GLuint, const GLchar *); - - -/** - * Uniform bindings. - * - * Each slang_uniform_binding holds an array of addresses to actual - * memory locations in those shader types that use that - * uniform. Uniform bindings are held in an array and accessed by - * array index which is seen to the application as a uniform location. - * - * When the application writes to a particular uniform, it specifies - * its location. This location is treated as an array index to - * slang_uniform_bindings::table and tested against - * slang_uniform_bindings::count limit. The result is a pointer to - * slang_uniform_binding. The type of data being written to uniform - * is tested against slang_uniform_binding::quant. If the types are - * compatible, the array slang_uniform_binding::address is iterated - * for each shader type and if the address is valid (i.e. the uniform - * is used by this shader type), the new uniform value is written at - * that address. - */ -/*@{*/ -typedef struct -{ - slang_export_data_quant *quant; - GLchar *name; - GLuint address[SLANG_SHADER_MAX]; -} slang_uniform_binding; - -typedef struct -{ - slang_uniform_binding *table; - GLuint count; -} slang_uniform_bindings; -/*@}*/ - - -/** - * Attrib bindings. - * - * There is a fixed number of vertex attrib vectors (attrib - * slots). The slang_attrib_slot::addr maps vertex attrib index to the - * actual memory location of the attrib in vertex shader. One vertex - * attrib can span over many attrib slots (this is the case for - * matrices). The slang_attrib_binding::first_slot_index holds the - * first slot index that the attrib is bound to. - */ -/*@{*/ -typedef struct -{ - slang_export_data_quant *quant; - GLchar *name; - GLuint first_slot_index; -} slang_attrib_binding; - -typedef struct -{ - GLuint addr; /**< memory location */ - GLuint fill; /**< 1..4, number of components used */ -} slang_attrib_slot; -typedef struct -{ - slang_attrib_binding bindings[MAX_VERTEX_ATTRIBS]; - GLuint binding_count; - slang_attrib_slot slots[MAX_VERTEX_ATTRIBS]; -} slang_attrib_bindings; -/*@}*/ +extern void +_slang_link(GLcontext *ctx, GLhandleARB h, + struct gl_shader_program *shProg); +extern void +_slang_resolve_samplers(struct gl_shader_program *shProg, + struct gl_program *prog); +extern void +_slang_remap_attribute(struct gl_program *prog, GLuint oldAttrib, + GLuint newAttrib); -/** - * Varying bindings. - * - * There is a fixed number of varying floats (varying slots). The - * slang_varying_slot::vert_addr maps varying float index to the - * actual memory location of the output variable in vertex shader. - * The slang_varying_slot::frag_addr maps varying float index to the - * actual memory location of the input variable in fragment shader. - */ -/*@{*/ -typedef struct -{ - GLuint vert_addr; - GLuint frag_addr; -} slang_varying_slot; - -typedef struct -{ - slang_export_data_quant *quant; - GLchar *name; - GLuint first_slot_index; -} slang_varying_binding; - -typedef struct -{ - slang_varying_binding bindings[MAX_VARYING_FLOATS]; - GLuint binding_count; - slang_varying_slot slots[MAX_VARYING_FLOATS]; - GLuint slot_count; -} slang_varying_bindings; -/*@}*/ - - -/** - * Texture usage. - * - * A slang_texture_usage struct holds indirect information about - * texture image unit usage. The slang_texture_usages::table is - * derived from active uniform table by extracting only uniforms that - * are samplers. - * - * To collect current texture usage one must iterate the - * slang_texture_usages::table and read uniform at address - * slang_texture_usage::frag_address to get texture unit index. This - * index, coupled with texture access type (target) taken from - * slang_texture_usage::quant forms texture usage for that texture - * unit. - */ -/*@{*/ -typedef struct -{ - slang_export_data_quant *quant; - GLuint frag_address; -} slang_texture_usage; - -typedef struct -{ - slang_texture_usage *table; - GLuint count; -} slang_texture_usages; -/*@}*/ - - -extern GLvoid -_slang_texture_usages_ctr (slang_texture_usages *); - -extern GLvoid -_slang_texture_usages_dtr (slang_texture_usages *); - -enum -{ - SLANG_COMMON_FIXED_MODELVIEWMATRIX, - SLANG_COMMON_FIXED_PROJECTIONMATRIX, - SLANG_COMMON_FIXED_MODELVIEWPROJECTIONMATRIX, - SLANG_COMMON_FIXED_TEXTUREMATRIX, - SLANG_COMMON_FIXED_NORMALMATRIX, - SLANG_COMMON_FIXED_MODELVIEWMATRIXINVERSE, - SLANG_COMMON_FIXED_PROJECTIONMATRIXINVERSE, - SLANG_COMMON_FIXED_MODELVIEWPROJECTIONMATRIXINVERSE, - SLANG_COMMON_FIXED_TEXTUREMATRIXINVERSE, - SLANG_COMMON_FIXED_MODELVIEWMATRIXTRANSPOSE, - SLANG_COMMON_FIXED_PROJECTIONMATRIXTRANSPOSE, - SLANG_COMMON_FIXED_MODELVIEWPROJECTIONMATRIXTRANSPOSE, - SLANG_COMMON_FIXED_TEXTUREMATRIXTRANSPOSE, - SLANG_COMMON_FIXED_MODELVIEWMATRIXINVERSETRANSPOSE, - SLANG_COMMON_FIXED_PROJECTIONMATRIXINVERSETRANSPOSE, - SLANG_COMMON_FIXED_MODELVIEWPROJECTIONMATRIXINVERSETRANSPOSE, - SLANG_COMMON_FIXED_TEXTUREMATRIXINVERSETRANSPOSE, - SLANG_COMMON_FIXED_NORMALSCALE, - SLANG_COMMON_FIXED_DEPTHRANGE, - SLANG_COMMON_FIXED_CLIPPLANE, - SLANG_COMMON_FIXED_POINT, - SLANG_COMMON_FIXED_FRONTMATERIAL, - SLANG_COMMON_FIXED_BACKMATERIAL, - SLANG_COMMON_FIXED_LIGHTSOURCE, - SLANG_COMMON_FIXED_LIGHTMODEL, - SLANG_COMMON_FIXED_FRONTLIGHTMODELPRODUCT, - SLANG_COMMON_FIXED_BACKLIGHTMODELPRODUCT, - SLANG_COMMON_FIXED_FRONTLIGHTPRODUCT, - SLANG_COMMON_FIXED_BACKLIGHTPRODUCT, - SLANG_COMMON_FIXED_TEXTUREENVCOLOR, - SLANG_COMMON_FIXED_EYEPLANES, - SLANG_COMMON_FIXED_EYEPLANET, - SLANG_COMMON_FIXED_EYEPLANER, - SLANG_COMMON_FIXED_EYEPLANEQ, - SLANG_COMMON_FIXED_OBJECTPLANES, - SLANG_COMMON_FIXED_OBJECTPLANET, - SLANG_COMMON_FIXED_OBJECTPLANER, - SLANG_COMMON_FIXED_OBJECTPLANEQ, - SLANG_COMMON_FIXED_FOG, - SLANG_COMMON_FIXED_MAX -}; - -enum -{ - SLANG_VERTEX_FIXED_POSITION, - SLANG_VERTEX_FIXED_POINTSIZE, - SLANG_VERTEX_FIXED_CLIPVERTEX, - SLANG_VERTEX_FIXED_COLOR, - SLANG_VERTEX_FIXED_SECONDARYCOLOR, - SLANG_VERTEX_FIXED_NORMAL, - SLANG_VERTEX_FIXED_VERTEX, - SLANG_VERTEX_FIXED_MULTITEXCOORD0, - SLANG_VERTEX_FIXED_MULTITEXCOORD1, - SLANG_VERTEX_FIXED_MULTITEXCOORD2, - SLANG_VERTEX_FIXED_MULTITEXCOORD3, - SLANG_VERTEX_FIXED_MULTITEXCOORD4, - SLANG_VERTEX_FIXED_MULTITEXCOORD5, - SLANG_VERTEX_FIXED_MULTITEXCOORD6, - SLANG_VERTEX_FIXED_MULTITEXCOORD7, - SLANG_VERTEX_FIXED_FOGCOORD, - SLANG_VERTEX_FIXED_FRONTCOLOR, - SLANG_VERTEX_FIXED_BACKCOLOR, - SLANG_VERTEX_FIXED_FRONTSECONDARYCOLOR, - SLANG_VERTEX_FIXED_BACKSECONDARYCOLOR, - SLANG_VERTEX_FIXED_TEXCOORD, - SLANG_VERTEX_FIXED_FOGFRAGCOORD, - SLANG_VERTEX_FIXED_MAX -}; - -enum -{ - SLANG_FRAGMENT_FIXED_FRAGCOORD, - SLANG_FRAGMENT_FIXED_FRONTFACING, - SLANG_FRAGMENT_FIXED_FRAGCOLOR, - SLANG_FRAGMENT_FIXED_FRAGDATA, - SLANG_FRAGMENT_FIXED_FRAGDEPTH, - SLANG_FRAGMENT_FIXED_COLOR, - SLANG_FRAGMENT_FIXED_SECONDARYCOLOR, - SLANG_FRAGMENT_FIXED_TEXCOORD, - SLANG_FRAGMENT_FIXED_FOGFRAGCOORD, - SLANG_FRAGMENT_FIXED_MAX -}; - -enum -{ - SLANG_COMMON_CODE_MAIN, - SLANG_COMMON_CODE_MAX -}; - -typedef struct -{ - slang_active_variables active_uniforms; - slang_active_variables active_attribs; - slang_attrib_overrides attrib_overrides; - slang_uniform_bindings uniforms; - slang_attrib_bindings attribs; - slang_varying_bindings varyings; - slang_texture_usages texture_usage; - GLuint common_fixed_entries[SLANG_SHADER_MAX][SLANG_COMMON_FIXED_MAX]; - GLuint vertex_fixed_entries[SLANG_VERTEX_FIXED_MAX]; - GLuint fragment_fixed_entries[SLANG_FRAGMENT_FIXED_MAX]; - GLuint code[SLANG_SHADER_MAX][SLANG_COMMON_CODE_MAX]; - slang_machine *machines[SLANG_SHADER_MAX]; - slang_assembly_file *assemblies[SLANG_SHADER_MAX]; -} slang_program; - -extern GLvoid -_slang_program_ctr (slang_program *); - -extern GLvoid -_slang_program_dtr (slang_program *); - -extern GLvoid -_slang_program_rst (slang_program *); - -extern GLboolean -_slang_link (slang_program *, slang_code_object **, GLuint); - -#ifdef __cplusplus -} -#endif #endif diff --git a/src/mesa/shader/slang/slang_log.c b/src/mesa/shader/slang/slang_log.c new file mode 100644 index 0000000000..e838744491 --- /dev/null +++ b/src/mesa/shader/slang/slang_log.c @@ -0,0 +1,131 @@ +/* + * Mesa 3-D graphics library + * Version: 6.5.3 + * + * Copyright (C) 2005-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 "imports.h" +#include "slang_log.h" +#include "slang_utility.h" + + + +static char *out_of_memory = "Error: Out of memory.\n"; + +void +slang_info_log_construct(slang_info_log * log) +{ + log->text = NULL; + log->dont_free_text = GL_FALSE; + log->error_flag = GL_FALSE; +} + +void +slang_info_log_destruct(slang_info_log * log) +{ + if (!log->dont_free_text) + slang_alloc_free(log->text); +} + +static int +slang_info_log_message(slang_info_log * log, const char *prefix, + const char *msg) +{ + GLuint size; + + if (log->dont_free_text) + return 0; + size = slang_string_length(msg) + 2; + if (prefix != NULL) + size += slang_string_length(prefix) + 2; + if (log->text != NULL) { + GLuint old_len = slang_string_length(log->text); + log->text = (char *) + slang_alloc_realloc(log->text, old_len + 1, old_len + size); + } + else { + log->text = (char *) (slang_alloc_malloc(size)); + if (log->text != NULL) + log->text[0] = '\0'; + } + if (log->text == NULL) + return 0; + if (prefix != NULL) { + slang_string_concat(log->text, prefix); + slang_string_concat(log->text, ": "); + } + slang_string_concat(log->text, msg); + slang_string_concat(log->text, "\n"); + return 1; +} + +int +slang_info_log_print(slang_info_log * log, const char *msg, ...) +{ + va_list va; + char buf[1024]; + + va_start(va, msg); + _mesa_vsprintf(buf, msg, va); + va_end(va); + return slang_info_log_message(log, NULL, buf); +} + +int +slang_info_log_error(slang_info_log * log, const char *msg, ...) +{ + va_list va; + char buf[1024]; + + va_start(va, msg); + _mesa_vsprintf(buf, msg, va); + va_end(va); + log->error_flag = GL_TRUE; + if (slang_info_log_message(log, "Error", buf)) + return 1; + slang_info_log_memory(log); + return 0; +} + +int +slang_info_log_warning(slang_info_log * log, const char *msg, ...) +{ + va_list va; + char buf[1024]; + + va_start(va, msg); + _mesa_vsprintf(buf, msg, va); + va_end(va); + if (slang_info_log_message(log, "Warning", buf)) + return 1; + slang_info_log_memory(log); + return 0; +} + +void +slang_info_log_memory(slang_info_log * log) +{ + if (!slang_info_log_message(log, "Error", "Out of memory.")) { + log->dont_free_text = GL_TRUE; + log->error_flag = GL_TRUE; + log->text = out_of_memory; + } +} diff --git a/src/mesa/shader/shaderobjects_3dlabs.h b/src/mesa/shader/slang/slang_log.h index 2092dd923e..dcaba0285a 100755..100644 --- a/src/mesa/shader/shaderobjects_3dlabs.h +++ b/src/mesa/shader/slang/slang_log.h @@ -1,8 +1,8 @@ /* * Mesa 3-D graphics library - * Version: 6.5 + * Version: 6.5.3 * - * Copyright (C) 2005-2006 Brian Paul All Rights Reserved. + * Copyright (C) 2005-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"), @@ -22,30 +22,36 @@ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -#ifndef SHADEROBJECTS_3DLABS_H -#define SHADEROBJECTS_3DLABS_H -#if FEATURE_ARB_shader_objects +#ifndef SLANG_LOG_H +#define SLANG_LOG_H -extern int _slang_fetch_discard (struct gl2_program_intf **pro, GLboolean *val); -extern GLvoid _slang_exec_fragment_shader (struct gl2_program_intf **pro); +typedef struct slang_info_log_ +{ + char *text; + GLboolean dont_free_text; + GLboolean error_flag; +} slang_info_log; -extern GLvoid _slang_exec_vertex_shader (struct gl2_program_intf **pro); -extern GLhandleARB -_mesa_3dlabs_create_shader_object (GLenum); +extern void +slang_info_log_construct(slang_info_log *); + +extern void +slang_info_log_destruct(slang_info_log *); -extern GLhandleARB -_mesa_3dlabs_create_program_object (GLvoid); +extern int +slang_info_log_print(slang_info_log *, const char *, ...); -extern GLhandleARB -_mesa_3dlabs_create_debug_object (GLvoid); +extern int +slang_info_log_error(slang_info_log *, const char *, ...); -#endif /* FEATURE_ARB_shader_objects */ +extern int +slang_info_log_warning(slang_info_log *, const char *, ...); extern void -_mesa_init_shaderobjects_3dlabs (GLcontext *ctx); +slang_info_log_memory(slang_info_log *); -#endif +#endif /* SLANG_LOG_H */ diff --git a/src/mesa/shader/slang/slang_mesa.cpp b/src/mesa/shader/slang/slang_mesa.cpp deleted file mode 100644 index 3f437ee7df..0000000000 --- a/src/mesa/shader/slang/slang_mesa.cpp +++ /dev/null @@ -1,144 +0,0 @@ -/* - * Mesa 3-D graphics library - * Version: 6.3 - * - * Copyright (C) 2005 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 "slang_mesa.h" -#include "Initialisation.h" -#include "Include/Common.h" -#include "Include/ShHandle.h" -#include "Public/ShaderLang.h" - - -class TGenericCompiler: public TCompiler -{ -public: - TGenericCompiler (EShLanguage l, int dOptions): TCompiler(l, infoSink), debugOptions(dOptions) - { - } -public: - virtual bool compile (TIntermNode *root) - { - haveValidObjectCode = true; - return haveValidObjectCode; - } - TInfoSink infoSink; - int debugOptions; -}; - -TCompiler *ConstructCompiler (EShLanguage language, int debugOptions) -{ - return new TGenericCompiler (language, debugOptions); -} - -void DeleteCompiler (TCompiler *compiler) -{ - delete compiler; -} - -class TGenericLinker: public TLinker -{ -public: - TGenericLinker (EShExecutable e, int dOptions): TLinker(e, infoSink), debugOptions(dOptions) - { - } -public: - bool link (TCompilerList &, TUniformMap *) - { - return true; - } - void getAttributeBindings (ShBindingTable const **t) const - { - } - TInfoSink infoSink; - int debugOptions; -}; - -TShHandleBase *ConstructLinker (EShExecutable executable, int debugOptions) -{ - return new TGenericLinker (executable, debugOptions); -} - -void DeleteLinker (TShHandleBase *linker) -{ - delete linker; -} - -class TUniformLinkedMap: public TUniformMap -{ -public: - TUniformLinkedMap() - { - } -public: - virtual int getLocation (const char *name) - { - return 0; - } -}; - -TUniformMap *ConstructUniformMap () -{ - return new TUniformLinkedMap; -} - -void DeleteUniformMap (TUniformMap *map) -{ - delete map; -} - - -namespace std -{ - -void _Xran () -{ - /* XXX fix this under Linux */ - /*_THROW(out_of_range, "invalid string position");*/ -} - -void _Xlen () -{ - /* XXX fix this under Linux */ - /*_THROW(length_error, "string too long");*/ -} - -} - - -/* these functions link with extern "C" */ - -int _mesa_isalnum (char c) -{ - return (c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z') || (c >= '0' && c <= '9'); -} - -int _glslang_3dlabs_InitProcess () -{ - return InitProcess () ? 1 : 0; -} - -int _glslang_3dlabs_ShInitialize () -{ - return ShInitialize () ? 1 : 0; -} - diff --git a/src/mesa/shader/slang/slang_preprocess.h b/src/mesa/shader/slang/slang_preprocess.h index f83e6e6e3f..d8eb12e4ff 100644 --- a/src/mesa/shader/slang/slang_preprocess.h +++ b/src/mesa/shader/slang/slang_preprocess.h @@ -1,8 +1,8 @@ /* * Mesa 3-D graphics library - * Version: 6.6 + * Version: 6.5.3 * - * Copyright (C) 2005-2006 Brian Paul All Rights Reserved. + * Copyright (C) 2005-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"), @@ -22,24 +22,19 @@ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -#if !defined SLANG_PREPROCESS_H +#ifndef SLANG_PREPROCESS_H #define SLANG_PREPROCESS_H #include "slang_compile.h" +#include "slang_log.h" -#if defined __cplusplus -extern "C" { -#endif -GLboolean +extern GLboolean _slang_preprocess_version (const char *, GLuint *, GLuint *, slang_info_log *); -GLboolean -_slang_preprocess_directives (slang_string *output, const char *input, slang_info_log *); +extern GLboolean +_slang_preprocess_directives (slang_string *output, const char *input, + slang_info_log *); -#ifdef __cplusplus -} -#endif - -#endif +#endif /* SLANG_PREPROCESS_H */ diff --git a/src/mesa/shader/slang/slang_print.c b/src/mesa/shader/slang/slang_print.c new file mode 100644 index 0000000000..4be9041c78 --- /dev/null +++ b/src/mesa/shader/slang/slang_print.c @@ -0,0 +1,802 @@ + +/** + * Dump/print a slang_operation tree + */ + + +#include "imports.h" +#include "slang_compile.h" +#include "slang_print.h" + + +static void +spaces(int n) +{ + while (n--) + printf(" "); +} + + +static void +print_type(const slang_fully_specified_type *t) +{ + switch (t->qualifier) { + case SLANG_QUAL_NONE: + /*printf("");*/ + break; + case SLANG_QUAL_CONST: + printf("const "); + break; + case SLANG_QUAL_ATTRIBUTE: + printf("attrib "); + break; + case SLANG_QUAL_VARYING: + printf("varying "); + break; + case SLANG_QUAL_UNIFORM: + printf("uniform "); + break; + case SLANG_QUAL_OUT: + printf("output "); + break; + case SLANG_QUAL_INOUT: + printf("inout "); + break; + case SLANG_QUAL_FIXEDOUTPUT: + printf("fixedoutput"); + break; + case SLANG_QUAL_FIXEDINPUT: + printf("fixedinput"); + break; + default: + printf("unknown qualifer!"); + } + + switch (t->specifier.type) { + case SLANG_SPEC_VOID: + printf("void"); + break; + case SLANG_SPEC_BOOL: + printf("bool"); + break; + case SLANG_SPEC_BVEC2: + printf("bvec2"); + break; + case SLANG_SPEC_BVEC3: + printf("bvec3"); + break; + case SLANG_SPEC_BVEC4: + printf("bvec4"); + break; + case SLANG_SPEC_INT: + printf("int"); + break; + case SLANG_SPEC_IVEC2: + printf("ivec2"); + break; + case SLANG_SPEC_IVEC3: + printf("ivec3"); + break; + case SLANG_SPEC_IVEC4: + printf("ivec4"); + break; + case SLANG_SPEC_FLOAT: + printf("float"); + break; + case SLANG_SPEC_VEC2: + printf("vec2"); + break; + case SLANG_SPEC_VEC3: + printf("vec3"); + break; + case SLANG_SPEC_VEC4: + printf("vec4"); + break; + case SLANG_SPEC_MAT2: + printf("mat2"); + break; + case SLANG_SPEC_MAT3: + printf("mat3"); + break; + case SLANG_SPEC_MAT4: + printf("mat4"); + break; + case SLANG_SPEC_SAMPLER1D: + printf("sampler1D"); + break; + case SLANG_SPEC_SAMPLER2D: + printf("sampler2D"); + break; + case SLANG_SPEC_SAMPLER3D: + printf("sampler3D"); + break; + case SLANG_SPEC_SAMPLERCUBE: + printf("samplerCube"); + break; + case SLANG_SPEC_SAMPLER1DSHADOW: + printf("sampler1DShadow"); + break; + case SLANG_SPEC_SAMPLER2DSHADOW: + printf("sampler2DShadow"); + break; + case SLANG_SPEC_STRUCT: + printf("struct"); + break; + case SLANG_SPEC_ARRAY: + printf("array"); + break; + default: + printf("unknown type"); + } + /*printf("\n");*/ +} + + +static void +print_variable(const slang_variable *v, int indent) +{ + spaces(indent); + printf("VAR "); + print_type(&v->type); + printf(" %s", (char *) v->a_name); + if (v->initializer) { + printf(" :=\n"); + slang_print_tree(v->initializer, indent + 3); + } + else { + printf(";\n"); + } +} + + +static void +print_binary(const slang_operation *op, const char *oper, int indent) +{ + assert(op->num_children == 2); + slang_print_tree(&op->children[0], indent + 3); + spaces(indent); + printf("%s\n", oper); + slang_print_tree(&op->children[1], indent + 3); +} + + +static void +print_generic2(const slang_operation *op, const char *oper, + const char *s, int indent) +{ + int i; + if (oper) { + spaces(indent); + printf("[%p locals %p] %s %s\n", (void*) op, (void*) op->locals, oper, s); + } + for (i = 0; i < op->num_children; i++) { + spaces(indent); + printf("//child %d:\n", i); + slang_print_tree(&op->children[i], indent); + } +} + +static void +print_generic(const slang_operation *op, const char *oper, int indent) +{ + print_generic2(op, oper, "", indent); +} + + +static const slang_variable_scope * +find_scope(const slang_variable_scope *s, slang_atom name) +{ + GLuint i; + for (i = 0; i < s->num_variables; i++) { + if (s->variables[i]->a_name == name) + return s; + } + if (s->outer_scope) + return find_scope(s->outer_scope, name); + else + return NULL; +} + +static const slang_variable * +find_var(const slang_variable_scope *s, slang_atom name) +{ + GLuint i; + for (i = 0; i < s->num_variables; i++) { + if (s->variables[i]->a_name == name) + return s->variables[i]; + } + if (s->outer_scope) + return find_var(s->outer_scope, name); + else + return NULL; +} + + +void +slang_print_tree(const slang_operation *op, int indent) +{ + int i; + + switch (op->type) { + + case SLANG_OPER_NONE: + spaces(indent); + printf("SLANG_OPER_NONE\n"); + break; + + 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); + spaces(indent); + printf("}\n"); + break; + + case SLANG_OPER_BLOCK_NEW_SCOPE: + spaces(indent); + printf("{{ // new scope locals %p\n", (void*)op->locals); + print_generic(op, NULL, indent+3); + spaces(indent); + printf("}}\n"); + break; + + case SLANG_OPER_VARIABLE_DECL: + assert(op->num_children == 0 || op->num_children == 1); + { + slang_variable *v; + v = _slang_locate_variable(op->locals, op->a_id, GL_TRUE); + if (v) { + spaces(indent); + printf("DECL (locals=%p outer=%p) ", (void*)op->locals, (void*) op->locals->outer_scope); + print_type(&v->type); + printf(" %s (%p)", (char *) op->a_id, + (void *) find_var(op->locals, op->a_id)); + + printf(" (in scope %p) ", + (void *) find_scope(op->locals, op->a_id)); + if (op->num_children == 1) { + printf(" :=\n"); + slang_print_tree(&op->children[0], indent + 3); + } + else if (v->initializer) { + printf(" := INITIALIZER\n"); + slang_print_tree(v->initializer, indent + 3); + } + else { + printf(";\n"); + } + /* + spaces(indent); + printf("TYPE: "); + print_type(&v->type); + spaces(indent); + printf("ADDR: %d size: %d\n", v->address, v->size); + */ + } + else { + abort(); + spaces(indent); + printf("DECL %s (anonymous variable!!!!)\n", (char *) op->a_id); + /*abort();*/ + } + } + break; + + 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: + spaces(indent); + printf("BREAK\n"); + break; + + case SLANG_OPER_CONTINUE: + spaces(indent); + printf("CONTINUE\n"); + break; + + case SLANG_OPER_DISCARD: + spaces(indent); + printf("DISCARD\n"); + break; + + 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: + spaces(indent); + printf("GOTO %s\n", (char *) op->a_id); + break; + + case SLANG_OPER_LABEL: + spaces(indent); + printf("LABEL %s\n", (char *) op->a_id); + break; + + case SLANG_OPER_EXPRESSION: + spaces(indent); + printf("EXPR: locals %p\n", (void*) op->locals); + /*print_generic(op, "SLANG_OPER_EXPRESSION", indent);*/ + slang_print_tree(&op->children[0], indent + 3); + break; + + case SLANG_OPER_IF: + spaces(indent); + printf("IF\n"); + slang_print_tree(&op->children[0], indent + 3); + spaces(indent); + printf("THEN\n"); + slang_print_tree(&op->children[1], indent + 3); + spaces(indent); + printf("ELSE\n"); + slang_print_tree(&op->children[2], indent + 3); + spaces(indent); + printf("ENDIF\n"); + break; + + case SLANG_OPER_WHILE: + assert(op->num_children == 2); + spaces(indent); + printf("WHILE cond:\n"); + slang_print_tree(&op->children[0], indent + 3); + spaces(indent); + printf("WHILE body:\n"); + slang_print_tree(&op->children[1], indent + 3); + break; + + case SLANG_OPER_DO: + spaces(indent); + printf("DO body:\n"); + slang_print_tree(&op->children[0], indent + 3); + spaces(indent); + printf("DO cond:\n"); + slang_print_tree(&op->children[1], indent + 3); + break; + + case SLANG_OPER_FOR: + spaces(indent); + printf("FOR init:\n"); + slang_print_tree(&op->children[0], indent + 3); + spaces(indent); + printf("FOR while:\n"); + slang_print_tree(&op->children[1], indent + 3); + spaces(indent); + printf("FOR step:\n"); + slang_print_tree(&op->children[2], indent + 3); + spaces(indent); + printf("FOR body:\n"); + slang_print_tree(&op->children[3], indent + 3); + spaces(indent); + printf("ENDFOR\n"); + /* + print_generic(op, "FOR", indent + 3); + */ + break; + + case SLANG_OPER_VOID: + spaces(indent); + printf("(oper-void)\n"); + break; + + case SLANG_OPER_LITERAL_BOOL: + spaces(indent); + printf("LITERAL ("); + for (i = 0; i < op->literal_size; i++) + printf("%s ", op->literal[0] ? "TRUE" : "FALSE"); + printf(")\n"); + + break; + + case SLANG_OPER_LITERAL_INT: + spaces(indent); + printf("LITERAL ("); + for (i = 0; i < op->literal_size; i++) + printf("%d ", (int) op->literal[i]); + printf(")\n"); + break; + + case SLANG_OPER_LITERAL_FLOAT: + spaces(indent); + printf("LITERAL ("); + for (i = 0; i < op->literal_size; i++) + printf("%f ", op->literal[i]); + printf(")\n"); + break; + + 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, + (void *) find_scope(op->locals, op->a_id)); + else + printf("VAR' %s (in scope %p)\n", (char *) op->a_id, + (void *) find_scope(op->locals, op->a_id)); + break; + + case SLANG_OPER_SEQUENCE: + print_generic(op, "COMMA-SEQ", indent+3); + break; + + case SLANG_OPER_ASSIGN: + spaces(indent); + printf("ASSIGNMENT locals %p\n", (void*)op->locals); + print_binary(op, ":=", indent); + break; + + case SLANG_OPER_ADDASSIGN: + spaces(indent); + printf("ASSIGN\n"); + print_binary(op, "+=", indent); + break; + + case SLANG_OPER_SUBASSIGN: + spaces(indent); + printf("ASSIGN\n"); + print_binary(op, "-=", indent); + break; + + case SLANG_OPER_MULASSIGN: + spaces(indent); + printf("ASSIGN\n"); + print_binary(op, "*=", indent); + break; + + 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: + spaces(indent); + 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); + printf("?\n"); + slang_print_tree(&op->children[1], indent+3); + spaces(indent); + printf(":\n"); + slang_print_tree(&op->children[2], indent+3); + break; + + case SLANG_OPER_LOGICALOR: + print_binary(op, "||", indent); + break; + + case SLANG_OPER_LOGICALXOR: + print_binary(op, "^^", indent); + break; + + case SLANG_OPER_LOGICALAND: + print_binary(op, "&&", indent); + break; + + /*SLANG_OPER_BITOR*/ + /*SLANG_OPER_BITXOR*/ + /*SLANG_OPER_BITAND*/ + case SLANG_OPER_EQUAL: + print_binary(op, "==", indent); + break; + + case SLANG_OPER_NOTEQUAL: + print_binary(op, "!=", indent); + break; + + case SLANG_OPER_LESS: + print_binary(op, "<", indent); + break; + + case SLANG_OPER_GREATER: + print_binary(op, ">", indent); + break; + + case SLANG_OPER_LESSEQUAL: + print_binary(op, "<=", indent); + break; + + case SLANG_OPER_GREATEREQUAL: + print_binary(op, ">=", indent); + break; + + /*SLANG_OPER_LSHIFT*/ + /*SLANG_OPER_RSHIFT*/ + case SLANG_OPER_ADD: + print_binary(op, "+", indent); + break; + + case SLANG_OPER_SUBTRACT: + print_binary(op, "-", indent); + break; + + case SLANG_OPER_MULTIPLY: + print_binary(op, "*", indent); + break; + + case SLANG_OPER_DIVIDE: + print_binary(op, "/", indent); + break; + + /*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: + spaces(indent); + printf("PRE--\n"); + slang_print_tree(&op->children[0], indent+3); + break; + + case SLANG_OPER_PLUS: + spaces(indent); + printf("SLANG_OPER_PLUS\n"); + break; + + case SLANG_OPER_MINUS: + spaces(indent); + printf("SLANG_OPER_MINUS\n"); + break; + + /*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: + spaces(indent); + printf("SLANG_OPER_SUBSCRIPT\n"); + print_generic(op, NULL, indent+3); + break; + + case SLANG_OPER_CALL: +#if 0 + slang_function *fun + = _slang_locate_function(A->space.funcs, oper->a_id, + oper->children, + oper->num_children, &A->space, A->atoms); +#endif + spaces(indent); + printf("CALL %s(\n", (char *) op->a_id); + for (i = 0; i < op->num_children; i++) { + slang_print_tree(&op->children[i], indent+3); + if (i + 1 < op->num_children) { + spaces(indent + 3); + printf(",\n"); + } + } + spaces(indent); + printf(")\n"); + break; + + 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: + spaces(indent); + printf("POST++\n"); + slang_print_tree(&op->children[0], indent+3); + break; + + case SLANG_OPER_POSTDECREMENT: + spaces(indent); + printf("POST--\n"); + slang_print_tree(&op->children[0], indent+3); + break; + + default: + printf("unknown op->type %d\n", (int) op->type); + } + +} + + + +void +slang_print_function(const slang_function *f, GLboolean body) +{ + int i; + +#if 0 + if (_mesa_strcmp((char *) f->header.a_name, "main") != 0) + return; +#endif + + printf("FUNCTION %s (\n", + (char *) f->header.a_name); + + for (i = 0; i < f->param_count; i++) { + print_variable(f->parameters->variables[i], 3); + } + + printf(")\n"); + if (body && f->body) + slang_print_tree(f->body, 0); +} + + + + + +const char * +slang_type_qual_string(slang_type_qualifier q) +{ + switch (q) { + case SLANG_QUAL_NONE: + return "none"; + case SLANG_QUAL_CONST: + return "const"; + case SLANG_QUAL_ATTRIBUTE: + return "attribute"; + case SLANG_QUAL_VARYING: + return "varying"; + case SLANG_QUAL_UNIFORM: + return "uniform"; + case SLANG_QUAL_OUT: + return "out"; + case SLANG_QUAL_INOUT: + return "inout"; + case SLANG_QUAL_FIXEDOUTPUT: + return "fixedoutput"; + case SLANG_QUAL_FIXEDINPUT: + return "fixedinputk"; + default: + return "qual?"; + } +} + + +static const char * +slang_type_string(slang_type_specifier_type t) +{ + switch (t) { + case SLANG_SPEC_VOID: + return "void"; + case SLANG_SPEC_BOOL: + return "bool"; + case SLANG_SPEC_BVEC2: + return "bvec2"; + case SLANG_SPEC_BVEC3: + return "bvec3"; + case SLANG_SPEC_BVEC4: + return "bvec4"; + case SLANG_SPEC_INT: + return "int"; + case SLANG_SPEC_IVEC2: + return "ivec2"; + case SLANG_SPEC_IVEC3: + return "ivec3"; + case SLANG_SPEC_IVEC4: + return "ivec4"; + case SLANG_SPEC_FLOAT: + return "float"; + case SLANG_SPEC_VEC2: + return "vec2"; + case SLANG_SPEC_VEC3: + return "vec3"; + case SLANG_SPEC_VEC4: + return "vec4"; + case SLANG_SPEC_MAT2: + return "mat2"; + case SLANG_SPEC_MAT3: + return "mat3"; + case SLANG_SPEC_MAT4: + return "mat4"; + case SLANG_SPEC_SAMPLER1D: + return "sampler1D"; + case SLANG_SPEC_SAMPLER2D: + return "sampler2D"; + case SLANG_SPEC_SAMPLER3D: + return "sampler3D"; + case SLANG_SPEC_SAMPLERCUBE: + return "samplerCube"; + case SLANG_SPEC_SAMPLER1DSHADOW: + return "sampler1DShadow"; + case SLANG_SPEC_SAMPLER2DSHADOW: + return "sampler2DShadow"; + case SLANG_SPEC_SAMPLER2DRECT: + return "sampler2DRect"; + case SLANG_SPEC_SAMPLER2DRECTSHADOW: + return "sampler2DRectShadow"; + case SLANG_SPEC_STRUCT: + return "struct"; + case SLANG_SPEC_ARRAY: + return "array"; + default: + return "type?"; + } +} + + +static const char * +slang_fq_type_string(const slang_fully_specified_type *t) +{ + static char str[1000]; + sprintf(str, "%s %s", slang_type_qual_string(t->qualifier), + slang_type_string(t->specifier.type)); + return str; +} + + +void +slang_print_type(const slang_fully_specified_type *t) +{ + printf("%s %s", slang_type_qual_string(t->qualifier), + slang_type_string(t->specifier.type)); +} + + +#if 0 +static char * +slang_var_string(const slang_variable *v) +{ + static char str[1000]; + sprintf(str, "%s : %s", + (char *) v->a_name, + slang_fq_type_string(&v->type)); + return str; +} +#endif + + +void +slang_print_variable(const slang_variable *v) +{ + printf("Name: %s\n", (char *) v->a_name); + printf("Type: %s\n", slang_fq_type_string(&v->type)); +} + + +void +_slang_print_var_scope(const slang_variable_scope *vars, int indent) +{ + GLuint i; + + spaces(indent); + printf("Var scope %p %d vars:\n", (void *) vars, vars->num_variables); + for (i = 0; i < vars->num_variables; i++) { + spaces(indent + 3); + printf("%s (at %p)\n", (char *) vars->variables[i]->a_name, (void*) (vars->variables + i)); + } + spaces(indent + 3); + printf("outer_scope = %p\n", (void*) vars->outer_scope); + + if (vars->outer_scope) { + /*spaces(indent + 3);*/ + _slang_print_var_scope(vars->outer_scope, indent + 3); + } +} + + + +int +slang_checksum_tree(const slang_operation *op) +{ + int s = op->num_children; + int i; + + for (i = 0; i < op->num_children; i++) { + s += slang_checksum_tree(&op->children[i]); + } + return s; +} diff --git a/src/mesa/shader/slang/slang_print.h b/src/mesa/shader/slang/slang_print.h new file mode 100644 index 0000000000..46605c8061 --- /dev/null +++ b/src/mesa/shader/slang/slang_print.h @@ -0,0 +1,29 @@ + + +#ifndef SLANG_PRINT +#define SLANG_PRINT + +extern void +slang_print_function(const slang_function *f, GLboolean body); + +extern void +slang_print_tree(const slang_operation *op, int indent); + +extern const char * +slang_type_qual_string(slang_type_qualifier q); + +extern void +slang_print_type(const slang_fully_specified_type *t); + +extern void +slang_print_variable(const slang_variable *v); + +extern void +_slang_print_var_scope(const slang_variable_scope *s, int indent); + + +extern int +slang_checksum_tree(const slang_operation *op); + +#endif /* SLANG_PRINT */ + diff --git a/src/mesa/shader/slang/slang_simplify.c b/src/mesa/shader/slang/slang_simplify.c new file mode 100644 index 0000000000..21d004db88 --- /dev/null +++ b/src/mesa/shader/slang/slang_simplify.c @@ -0,0 +1,449 @@ +/* + * Mesa 3-D graphics library + * Version: 6.5.2 + * + * Copyright (C) 2005-2006 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. + */ + +/** + * \file slang_assemble_typeinfo.c + * slang type info + * \author Michal Krol + */ + +#include "imports.h" +#include "macros.h" +#include "get.h" +#include "slang_compile.h" +#include "slang_codegen.h" +#include "slang_simplify.h" +#include "slang_print.h" + + + + +/** + * Lookup the value of named constant, such as gl_MaxLights. + * \return value of constant, or -1 if unknown + */ +GLint +_slang_lookup_constant(const char *name) +{ + struct constant_info { + const char *Name; + const GLenum Token; + }; + static const struct constant_info info[] = { + { "gl_MaxClipPlanes", GL_MAX_CLIP_PLANES }, + { "gl_MaxCombinedTextureImageUnits", GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS }, + { "gl_MaxDrawBuffers", GL_MAX_DRAW_BUFFERS }, + { "gl_MaxFragmentUniformComponents", GL_MAX_FRAGMENT_UNIFORM_COMPONENTS }, + { "gl_MaxLights", GL_MAX_LIGHTS }, + { "gl_MaxTextureUnits", GL_MAX_TEXTURE_UNITS }, + { "gl_MaxTextureCoords", GL_MAX_TEXTURE_COORDS }, + { "gl_MaxVertexAttribs", GL_MAX_VERTEX_ATTRIBS }, + { "gl_MaxVertexUniformComponents", GL_MAX_VERTEX_UNIFORM_COMPONENTS }, + { "gl_MaxVaryingFloats", GL_MAX_VARYING_FLOATS }, + { "gl_MaxVertexTextureImageUnits", GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS }, + { "gl_MaxTextureImageUnits", GL_MAX_TEXTURE_IMAGE_UNITS }, + { NULL, 0 } + }; + GLuint i; + + for (i = 0; info[i].Name; i++) { + if (strcmp(info[i].Name, name) == 0) { + /* found */ + GLint value = -1.0; + _mesa_GetIntegerv(info[i].Token, &value); + ASSERT(value >= 0); /* sanity check that glGetFloatv worked */ + return value; + } + } + return -1; +} + + + +/** + * Recursively traverse an AST tree, applying simplifications wherever + * possible. + * At the least, we do constant folding. We need to do that much so that + * compile-time expressions can be evaluated for things like array + * declarations. I.e.: float foo[3 + 5]; + */ +void +_slang_simplify(slang_operation *oper, + const slang_name_space * space, + slang_atom_pool * atoms) +{ + GLboolean isFloat[4]; + GLboolean isBool[4]; + GLuint i, n; + + 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) { + oper->literal[0] = + oper->literal[1] = + oper->literal[2] = + oper->literal[3] = value; + oper->type = SLANG_OPER_LITERAL_INT; + return; + } + } + + /* first, simplify children */ + for (i = 0; i < oper->num_children; i++) { + _slang_simplify(&oper->children[i], space, atoms); + } + + /* 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); + } + + if (oper->num_children == 2 && isFloat[0] && isFloat[1]) { + /* probably simple arithmetic */ + switch (oper->type) { + 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; + return; + 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; + return; + 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; + return; + 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; + return; + default: + ; /* nothing */ + } + } + + if (oper->num_children == 1 && isFloat[0]) { + switch (oper->type) { + 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; + return; + 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; + return; + default: + ; /* nothing */ + } + } + + if (oper->num_children == 2 && isBool[0] && isBool[1]) { + /* simple boolean expression */ + switch (oper->type) { + 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; + oper->literal[i] = (GLfloat) (a && b); + } + oper->literal_size = oper->children[0].literal_size; + slang_operation_destruct(oper); + oper->type = SLANG_OPER_LITERAL_BOOL; + return; + 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; + oper->literal[i] = (GLfloat) (a || b); + } + oper->literal_size = oper->children[0].literal_size; + slang_operation_destruct(oper); + oper->type = SLANG_OPER_LITERAL_BOOL; + return; + 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; + oper->literal[i] = (GLfloat) (a ^ b); + } + oper->literal_size = oper->children[0].literal_size; + slang_operation_destruct(oper); + oper->type = SLANG_OPER_LITERAL_BOOL; + return; + default: + ; /* nothing */ + } + } + + 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 (strcmp((char *) oper->a_id, "vec4") == 0) { + oper->literal[0] = oper->children[0].literal[0]; + oper->literal[1] = oper->children[1].literal[0]; + oper->literal[2] = oper->children[2].literal[0]; + oper->literal[3] = oper->children[3].literal[0]; + oper->literal_size = 4; + slang_operation_destruct(oper); + oper->type = SLANG_OPER_LITERAL_FLOAT; + return; + } + } + } + + if (oper->num_children == 3 && isFloat[0] && isFloat[1] && isFloat[2]) { + /* vec3(flt, flt, flt) constructor */ + 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]; + oper->literal[2] = oper->children[2].literal[0]; + oper->literal[3] = oper->literal[2]; + oper->literal_size = 3; + slang_operation_destruct(oper); + oper->type = SLANG_OPER_LITERAL_FLOAT; + return; + } + } + } + + if (oper->num_children == 2 && isFloat[0] && isFloat[1]) { + /* vec2(flt, flt) constructor */ + if (oper->type == SLANG_OPER_CALL) { + if (strcmp((char *) oper->a_id, "vec2") == 0) { + oper->literal[0] = oper->children[0].literal[0]; + oper->literal[1] = oper->children[1].literal[0]; + oper->literal[2] = oper->literal[1]; + 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; + assert(oper->num_children == 0); + return; + } + } + } + + if (oper->num_children == 1 && isFloat[0]) { + /* vec2/3/4(flt, flt) constructor */ + if (oper->type == SLANG_OPER_CALL) { + const char *func = (const char *) oper->a_id; + if (strncmp(func, "vec", 3) == 0 && func[3] >= '2' && func[3] <= '4') { + oper->literal[0] = + oper->literal[1] = + oper->literal[2] = + oper->literal[3] = oper->children[0].literal[0]; + oper->literal_size = func[3] - '0'; + assert(oper->literal_size >= 2); + assert(oper->literal_size <= 4); + slang_operation_destruct(oper); /* XXX oper->locals goes NULL! */ + oper->type = SLANG_OPER_LITERAL_FLOAT; + assert(oper->num_children == 0); + return; + } + } + } +} + + + +/** + * Adapt the arguments for a function call to match the parameters of + * the given function. + * This is for: + * 1. converting/casting argument types to match parameters + * 2. breaking up vector/matrix types into individual components to + * satisfy constructors. + */ +GLboolean +_slang_adapt_call(slang_operation *callOper, const slang_function *fun, + const slang_name_space * space, + slang_atom_pool * atoms, slang_info_log *log) +{ + const GLboolean haveRetValue = _slang_function_has_return_value(fun); + const int numParams = fun->param_count - haveRetValue; + int i; + int dbg = 0; + + if (dbg) printf("Adapt %d args to %d parameters\n", + callOper->num_children, numParams); + + /* Only try adapting for constructors */ + if (fun->kind != SLANG_FUNC_CONSTRUCTOR) + return GL_FALSE; + + if (callOper->num_children != numParams) { + /* number of arguments doesn't match number of parameters */ + + 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. + */ + for (i = 0; i < numParams; i++) { + slang_typeinfo argType; + GLint argSz, j; + + /* Get type of arg[i] */ + if (!slang_typeinfo_construct(&argType)) + return GL_FALSE; + if (!_slang_typeof_operation_(&callOper->children[i], space, + &argType, atoms, log)) { + slang_typeinfo_destruct(&argType); + return GL_FALSE; + } + + /* + paramSz = _slang_sizeof_type_specifier(¶mVar->type.specifier); + assert(paramSz == 1); + */ + argSz = _slang_sizeof_type_specifier(&argType.spec); + if (argSz > 1) { + slang_operation origArg; + /* break up arg[i] into components */ + if (dbg) + printf("Break up arg %d from 1 to %d elements\n", i, argSz); + + slang_operation_construct(&origArg); + slang_operation_copy(&origArg, + &callOper->children[i]); + + /* insert argSz-1 new children/args */ + for (j = 0; j < argSz - 1; j++) { + (void) slang_operation_insert(&callOper->num_children, + &callOper->children, i); + } + + /* 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].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; + callOper->children[i + j].children[1].literal[0] = j; + } + + } + } /* for i */ + } + else { + /* non-constructor function: number of args must match number + * of function params. + */ + return GL_FALSE; /* caller will record an error msg */ + } + } + + if (callOper->num_children < numParams) { + /* still not enough args for all params */ + return GL_FALSE; + } + else if (callOper->num_children > numParams) { + /* now too many arguments */ + /* XXX this isn't always an error, see spec */ + return GL_FALSE; + } + + /* + * Second phase, argument casting. + * Example: + * void foo(int i, bool b) {} + * x = foo(3.15, 9); + * Gets translated into: + * x = foo(int(3.15), bool(9)) + */ + for (i = 0; i < numParams; i++) { + slang_typeinfo argType; + slang_variable *paramVar = fun->parameters->variables[i]; + + /* Get type of arg[i] */ + if (!slang_typeinfo_construct(&argType)) + return GL_FALSE; + if (!_slang_typeof_operation_(&callOper->children[i], space, + &argType, atoms, log)) { + slang_typeinfo_destruct(&argType); + return GL_FALSE; + } + + /* see if arg type matches parameter type */ + if (!slang_type_specifier_equal(&argType.spec, + ¶mVar->type.specifier)) { + /* need to adapt arg type to match param type */ + const char *constructorName = + slang_type_specifier_type_to_string(paramVar->type.specifier.type); + slang_operation *child = slang_operation_new(1); + + slang_operation_copy(child, &callOper->children[i]); + child->locals->outer_scope = callOper->children[i].locals; + + 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; + } + + slang_typeinfo_destruct(&argType); + } + + if (dbg) { + printf("===== New call to %s with adapted arguments ===============\n", + (char*) fun->header.a_name); + slang_print_tree(callOper, 5); + } + + return GL_TRUE; +} diff --git a/src/mesa/shader/slang/slang_simplify.h b/src/mesa/shader/slang/slang_simplify.h new file mode 100644 index 0000000000..b3840ee9df --- /dev/null +++ b/src/mesa/shader/slang/slang_simplify.h @@ -0,0 +1,22 @@ + +#ifndef SLANG_SIMPLIFY_H +#define SLANG_SIMPLIFY_H + + +extern GLint +_slang_lookup_constant(const char *name); + + +extern void +_slang_simplify(slang_operation *oper, + const slang_name_space * space, + slang_atom_pool * atoms); + + +extern GLboolean +_slang_adapt_call(slang_operation *callOper, const slang_function *fun, + const slang_name_space * space, + slang_atom_pool * atoms, slang_info_log *log); + + +#endif /* SLANG_SIMPLIFY_H */ diff --git a/src/mesa/shader/slang/slang_storage.c b/src/mesa/shader/slang/slang_storage.c index 6220b7c5bf..6d6a6d9ac4 100644 --- a/src/mesa/shader/slang/slang_storage.c +++ b/src/mesa/shader/slang/slang_storage.c @@ -33,254 +33,214 @@ /* slang_storage_array */ -GLboolean slang_storage_array_construct (slang_storage_array *arr) +GLboolean +slang_storage_array_construct(slang_storage_array * arr) { - arr->type = slang_stor_aggregate; - arr->aggregate = NULL; - arr->length = 0; - return GL_TRUE; + arr->type = SLANG_STORE_AGGREGATE; + arr->aggregate = NULL; + arr->length = 0; + return GL_TRUE; } -GLvoid slang_storage_array_destruct (slang_storage_array *arr) +GLvoid +slang_storage_array_destruct(slang_storage_array * arr) { - if (arr->aggregate != NULL) - { - slang_storage_aggregate_destruct (arr->aggregate); - slang_alloc_free (arr->aggregate); - } + if (arr->aggregate != NULL) { + slang_storage_aggregate_destruct(arr->aggregate); + slang_alloc_free(arr->aggregate); + } } /* slang_storage_aggregate */ -GLboolean slang_storage_aggregate_construct (slang_storage_aggregate *agg) +GLboolean +slang_storage_aggregate_construct(slang_storage_aggregate * agg) { - agg->arrays = NULL; - agg->count = 0; - return GL_TRUE; + agg->arrays = NULL; + agg->count = 0; + return GL_TRUE; } -GLvoid slang_storage_aggregate_destruct (slang_storage_aggregate *agg) +GLvoid +slang_storage_aggregate_destruct(slang_storage_aggregate * agg) { - GLuint i; + GLuint i; - for (i = 0; i < agg->count; i++) - slang_storage_array_destruct (agg->arrays + i); - slang_alloc_free (agg->arrays); + for (i = 0; i < agg->count; i++) + slang_storage_array_destruct(agg->arrays + i); + slang_alloc_free(agg->arrays); } -static slang_storage_array *slang_storage_aggregate_push_new (slang_storage_aggregate *agg) +static slang_storage_array * +slang_storage_aggregate_push_new(slang_storage_aggregate * agg) { - slang_storage_array *arr = NULL; - - agg->arrays = (slang_storage_array *) slang_alloc_realloc (agg->arrays, agg->count * sizeof ( - slang_storage_array), (agg->count + 1) * sizeof (slang_storage_array)); - if (agg->arrays != NULL) - { - arr = agg->arrays + agg->count; - if (!slang_storage_array_construct (arr)) - return NULL; - agg->count++; - } - return arr; + slang_storage_array *arr = NULL; + + agg->arrays = (slang_storage_array *) + slang_alloc_realloc(agg->arrays, + agg->count * sizeof(slang_storage_array), + (agg->count + 1) * sizeof(slang_storage_array)); + if (agg->arrays != NULL) { + arr = agg->arrays + agg->count; + if (!slang_storage_array_construct(arr)) + return NULL; + agg->count++; + } + return arr; } /* _slang_aggregate_variable() */ -static GLboolean aggregate_vector (slang_storage_aggregate *agg, slang_storage_type basic_type, - GLuint row_count) +static GLboolean +aggregate_vector(slang_storage_aggregate * agg, slang_storage_type basic_type, + GLuint row_count) { - slang_storage_array *arr = slang_storage_aggregate_push_new (agg); - if (arr == NULL) - return GL_FALSE; - arr->type = basic_type; - arr->length = row_count; - return GL_TRUE; + slang_storage_array *arr = slang_storage_aggregate_push_new(agg); + if (arr == NULL) + return GL_FALSE; + arr->type = basic_type; + arr->length = row_count; + return GL_TRUE; } -static GLboolean aggregate_matrix (slang_storage_aggregate *agg, slang_storage_type basic_type, - GLuint dimension) +static GLboolean +aggregate_matrix(slang_storage_aggregate * agg, slang_storage_type basic_type, + GLuint dimension) { - slang_storage_array *arr = slang_storage_aggregate_push_new (agg); - if (arr == NULL) - return GL_FALSE; - arr->type = slang_stor_aggregate; - arr->length = dimension; - arr->aggregate = (slang_storage_aggregate *) slang_alloc_malloc (sizeof (slang_storage_aggregate)); - if (arr->aggregate == NULL) - return GL_FALSE; - if (!slang_storage_aggregate_construct (arr->aggregate)) - { - slang_alloc_free (arr->aggregate); - arr->aggregate = NULL; - return GL_FALSE; - } - if (!aggregate_vector (arr->aggregate, basic_type, dimension)) - return GL_FALSE; - return GL_TRUE; + slang_storage_array *arr = slang_storage_aggregate_push_new(agg); + if (arr == NULL) + return GL_FALSE; + arr->type = SLANG_STORE_AGGREGATE; + arr->length = dimension; + arr->aggregate = + (slang_storage_aggregate *) + slang_alloc_malloc(sizeof(slang_storage_aggregate)); + if (arr->aggregate == NULL) + return GL_FALSE; + if (!slang_storage_aggregate_construct(arr->aggregate)) { + slang_alloc_free(arr->aggregate); + arr->aggregate = NULL; + return GL_FALSE; + } + if (!aggregate_vector(arr->aggregate, basic_type, dimension)) + return GL_FALSE; + return GL_TRUE; } -static GLboolean aggregate_variables (slang_storage_aggregate *agg, slang_variable_scope *vars, - slang_function_scope *funcs, slang_struct_scope *structs, slang_variable_scope *globals, - slang_machine *mach, slang_assembly_file *file, slang_atom_pool *atoms) + +static GLboolean +aggregate_variables(slang_storage_aggregate * agg, + slang_variable_scope * vars, slang_function_scope * funcs, + slang_struct_scope * structs, + slang_variable_scope * globals, + slang_atom_pool * atoms) { - GLuint i; + GLuint i; - for (i = 0; i < vars->num_variables; i++) - if (!_slang_aggregate_variable (agg, &vars->variables[i].type.specifier, - vars->variables[i].array_len, funcs, structs, globals, mach, file, atoms)) - return GL_FALSE; - return GL_TRUE; + for (i = 0; i < vars->num_variables; i++) + if (!_slang_aggregate_variable(agg, &vars->variables[i]->type.specifier, + vars->variables[i]->array_len, funcs, + structs, globals, atoms)) + return GL_FALSE; + return GL_TRUE; } -GLboolean _slang_evaluate_int (slang_assembly_file *file, slang_machine *pmach, - slang_assembly_name_space *space, slang_operation *array_size, GLuint *pint, - slang_atom_pool *atoms) -{ - slang_assembly_file_restore_point point; - slang_machine mach; - slang_assemble_ctx A; - - A.file = file; - A.mach = pmach; - A.atoms = atoms; - A.space = *space; - A.local.ret_size = 0; - A.local.addr_tmp = 0; - A.local.swizzle_tmp = 4; - - /* save the current assembly */ - if (!slang_assembly_file_restore_point_save (file, &point)) - return GL_FALSE; - - /* setup the machine */ - mach = *pmach; - mach.ip = file->count; - - /* allocate local storage for expression */ - if (!slang_assembly_file_push_label (file, slang_asm_local_alloc, 20)) - return GL_FALSE; - if (!slang_assembly_file_push_label (file, slang_asm_enter, 20)) - return GL_FALSE; - - /* insert the actual expression */ - if (!_slang_assemble_operation (&A, array_size, slang_ref_forbid)) - return GL_FALSE; - if (!slang_assembly_file_push (file, slang_asm_exit)) - return GL_FALSE; - - /* execute the expression */ - if (!_slang_execute2 (file, &mach)) - return GL_FALSE; - - /* the evaluated expression is on top of the stack */ - *pint = (GLuint) mach.mem[mach.sp + SLANG_MACHINE_GLOBAL_SIZE]._float; - - /* restore the old assembly */ - if (!slang_assembly_file_restore_point_load (file, &point)) - return GL_FALSE; - - return GL_TRUE; -} -GLboolean _slang_aggregate_variable (slang_storage_aggregate *agg, slang_type_specifier *spec, - GLuint array_len, slang_function_scope *funcs, slang_struct_scope *structs, - slang_variable_scope *vars, slang_machine *mach, slang_assembly_file *file, - slang_atom_pool *atoms) +GLboolean +_slang_aggregate_variable(slang_storage_aggregate * agg, + slang_type_specifier * spec, GLuint array_len, + slang_function_scope * funcs, + slang_struct_scope * structs, + slang_variable_scope * vars, + 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: -#if defined(USE_X86_ASM) || defined(SLANG_X86) - return aggregate_vector (agg, slang_stor_vec4, 1); -#else - return aggregate_vector (agg, slang_stor_float, 4); -#endif - 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: -#if defined(USE_X86_ASM) || defined(SLANG_X86) - return aggregate_vector (agg, slang_stor_vec4, 4); -#else - return aggregate_matrix (agg, slang_stor_float, 4); -#endif - 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: - return aggregate_variables (agg, spec->_struct->fields, funcs, structs, vars, mach, - file, atoms); - 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->aggregate = (slang_storage_aggregate *) slang_alloc_malloc (sizeof (slang_storage_aggregate)); - if (arr->aggregate == NULL) - return GL_FALSE; - if (!slang_storage_aggregate_construct (arr->aggregate)) - { - slang_alloc_free (arr->aggregate); - arr->aggregate = NULL; - return GL_FALSE; - } - if (!_slang_aggregate_variable (arr->aggregate, spec->_array, 0, funcs, structs, - vars, mach, file, atoms)) - return GL_FALSE; - arr->length = array_len; - /* TODO: check if 0 < arr->length <= 65535 */ - } - return GL_TRUE; - default: - return GL_FALSE; - } + switch (spec->type) { + 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: + case SLANG_SPEC_SAMPLER2DRECT: + case SLANG_SPEC_SAMPLER2DRECTSHADOW: + 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: + { + slang_storage_array *arr; + + arr = slang_storage_aggregate_push_new(agg); + if (arr == NULL) + return GL_FALSE; + arr->type = SLANG_STORE_AGGREGATE; + arr->aggregate = + (slang_storage_aggregate *) + slang_alloc_malloc(sizeof(slang_storage_aggregate)); + if (arr->aggregate == NULL) + return GL_FALSE; + if (!slang_storage_aggregate_construct(arr->aggregate)) { + slang_alloc_free(arr->aggregate); + arr->aggregate = NULL; + return GL_FALSE; + } + if (!_slang_aggregate_variable(arr->aggregate, spec->_array, 0, + funcs, structs, vars, atoms)) + return GL_FALSE; + arr->length = array_len; + /* TODO: check if 0 < arr->length <= 65535 */ + } + return GL_TRUE; + default: + return GL_FALSE; + } } -/* _slang_sizeof_type() */ GLuint -_slang_sizeof_type (slang_storage_type type) +_slang_sizeof_type(slang_storage_type type) { - if (type == slang_stor_aggregate) + if (type == SLANG_STORE_AGGREGATE) return 0; - if (type == slang_stor_vec4) - return 4 * sizeof (GLfloat); - return sizeof (GLfloat); + if (type == SLANG_STORE_VEC4) + return 4 * sizeof(GLfloat); + return sizeof(GLfloat); } -/* _slang_sizeof_aggregate() */ -GLuint _slang_sizeof_aggregate (const slang_storage_aggregate *agg) +GLuint +_slang_sizeof_aggregate(const slang_storage_aggregate * agg) { GLuint i, size = 0; @@ -288,19 +248,20 @@ GLuint _slang_sizeof_aggregate (const slang_storage_aggregate *agg) slang_storage_array *arr = &agg->arrays[i]; GLuint element_size; - if (arr->type == slang_stor_aggregate) - element_size = _slang_sizeof_aggregate (arr->aggregate); + if (arr->type == SLANG_STORE_AGGREGATE) + element_size = _slang_sizeof_aggregate(arr->aggregate); else - element_size = _slang_sizeof_type (arr->type); + element_size = _slang_sizeof_type(arr->type); size += element_size * arr->length; } return size; } -/* _slang_flatten_aggregate () */ +#if 0 GLboolean -_slang_flatten_aggregate (slang_storage_aggregate *flat, const slang_storage_aggregate *agg) +_slang_flatten_aggregate(slang_storage_aggregate * flat, + const slang_storage_aggregate * agg) { GLuint i; @@ -308,17 +269,17 @@ _slang_flatten_aggregate (slang_storage_aggregate *flat, const slang_storage_agg GLuint j; for (j = 0; j < agg->arrays[i].length; j++) { - if (agg->arrays[i].type == slang_stor_aggregate) { - if (!_slang_flatten_aggregate (flat, agg->arrays[i].aggregate)) + if (agg->arrays[i].type == SLANG_STORE_AGGREGATE) { + if (!_slang_flatten_aggregate(flat, agg->arrays[i].aggregate)) return GL_FALSE; } else { 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; @@ -328,7 +289,7 @@ _slang_flatten_aggregate (slang_storage_aggregate *flat, const slang_storage_agg for (k = 0; k < count; k++) { slang_storage_array *arr; - arr = slang_storage_aggregate_push_new (flat); + arr = slang_storage_aggregate_push_new(flat); if (arr == NULL) return GL_FALSE; arr->type = type; @@ -339,4 +300,4 @@ _slang_flatten_aggregate (slang_storage_aggregate *flat, const slang_storage_agg } return GL_TRUE; } - +#endif diff --git a/src/mesa/shader/slang/slang_storage.h b/src/mesa/shader/slang/slang_storage.h index 209f8674d9..d3047ee516 100644 --- a/src/mesa/shader/slang/slang_storage.h +++ b/src/mesa/shader/slang/slang_storage.h @@ -22,76 +22,83 @@ * 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" -#include "slang_assemble.h" -#include "slang_execute.h" +#include "slang_typeinfo.h" -#if defined __cplusplus -extern "C" { -#endif /* - * Program variable data storage is kept completely transparent to the front-end compiler. It is - * up to the back-end how the data is actually allocated. The slang_storage_type enum - * provides the basic information about how the memory is interpreted. This abstract piece - * of memory is called a data slot. A data slot of a particular type has a fixed size. + * Program variable data storage is kept completely transparent to the + * front-end compiler. It is up to the back-end how the data is + * actually allocated. The slang_storage_type enum provides the basic + * information about how the memory is interpreted. This abstract + * piece of memory is called a data slot. A data slot of a particular + * type has a fixed size. * - * For now, only the three basic types are supported, that is bool, int and float. Other built-in - * types like vector or matrix can easily be decomposed into a series of basic types. + * For now, only the three basic types are supported, that is bool, + * int and float. Other built-in types like vector or matrix can + * easily be decomposed into a series of basic types. * - * If the vec4 module is enabled, 4-component vectors of floats are used when possible. 4x4 matrices - * are constructed of 4 vec4 slots. + * If the vec4 module is enabled, 4-component vectors of floats are + * used when possible. 4x4 matrices are constructed of 4 vec4 slots. */ 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; -/* - * The slang_storage_array structure groups data slots of the same type into an array. This - * array has a fixed length. Arrays are required to have a size equal to the sum of sizes of its - * elements. They are also required to support indirect addressing. That is, if B references - * first data slot in the array, S is the size of the data slot and I is the integral index that - * is not known at compile time, B+I*S references I-th data slot. + +/** + * The slang_storage_array structure groups data slots of the same + * type into an array. This array has a fixed length. Arrays are + * required to have a size equal to the sum of sizes of its + * elements. They are also required to support indirect + * addressing. That is, if B references first data slot in the array, + * S is the size of the data slot and I is the integral index that is + * not known at compile time, B+I*S references I-th data slot. * - * This structure is also used to break down built-in data types that are not supported directly. - * Vectors, like vec3, are constructed from arrays of their basic types. Matrices are formed of - * an array of column vectors, which are in turn processed as other vectors. + * This structure is also used to break down built-in data types that + * are not supported directly. Vectors, like vec3, are constructed + * from arrays of their basic types. Matrices are formed of an array + * of column vectors, which are in turn processed as other vectors. */ typedef struct slang_storage_array_ { - slang_storage_type type; - struct slang_storage_aggregate_ *aggregate; /* slang_stor_aggregate */ - GLuint length; + slang_storage_type type; + struct slang_storage_aggregate_ *aggregate; + GLuint length; } slang_storage_array; GLboolean slang_storage_array_construct (slang_storage_array *); GLvoid slang_storage_array_destruct (slang_storage_array *); -/* - * The slang_storage_aggregate structure relaxes the indirect addressing requirement for - * slang_storage_array structure. Aggregates are always accessed statically - its member - * addresses are well-known at compile time. For example, user-defined types are implemented as - * aggregates. Aggregates can collect data of a different type. + +/** + * The slang_storage_aggregate structure relaxes the indirect + * addressing requirement for slang_storage_array + * structure. Aggregates are always accessed statically - its member + * addresses are well-known at compile time. For example, user-defined + * types are implemented as aggregates. Aggregates can collect data of + * a different type. */ typedef struct slang_storage_aggregate_ { - slang_storage_array *arrays; - GLuint count; + slang_storage_array *arrays; + GLuint count; } slang_storage_aggregate; GLboolean slang_storage_aggregate_construct (slang_storage_aggregate *); GLvoid slang_storage_aggregate_destruct (slang_storage_aggregate *); + extern GLboolean _slang_aggregate_variable(slang_storage_aggregate *agg, slang_type_specifier *spec, @@ -99,43 +106,35 @@ _slang_aggregate_variable(slang_storage_aggregate *agg, slang_function_scope *funcs, slang_struct_scope *structs, slang_variable_scope *vars, - slang_machine *mach, - slang_assembly_file *file, slang_atom_pool *atoms); -extern GLboolean -_slang_evaluate_int(slang_assembly_file *file, - slang_machine *pmach, - slang_assembly_name_space *space, - slang_operation *array_size, - GLuint *pint, - slang_atom_pool *atoms); - /* * 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 _slang_sizeof_type (slang_storage_type); -/* + +/** * Returns total size (in machine units) of the given aggregate. * Returns 0 on error. */ -GLuint _slang_sizeof_aggregate (const slang_storage_aggregate *); +extern GLuint +_slang_sizeof_aggregate (const slang_storage_aggregate *); -/* - * Converts structured aggregate to a flat one, with arrays of generic type being - * one-element long. - * Returns GL_TRUE on success. - * Returns GL_FALSE otherwise. - */ -GLboolean _slang_flatten_aggregate (slang_storage_aggregate *, const slang_storage_aggregate *); -#ifdef __cplusplus -} -#endif +#if 0 +/** + * Converts structured aggregate to a flat one, with arrays of generic + * type being one-element long. Returns GL_TRUE on success. Returns + * GL_FALSE otherwise. + */ +extern GLboolean +_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 new file mode 100644 index 0000000000..fef5575631 --- /dev/null +++ b/src/mesa/shader/slang/slang_typeinfo.c @@ -0,0 +1,912 @@ +/* + * Mesa 3-D graphics library + * Version: 6.5 + * + * Copyright (C) 2005-2006 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. + */ + +/** + * \file slang_assemble_typeinfo.c + * slang type info + * \author Michal Krol + */ + +#include "imports.h" +#include "slang_typeinfo.h" +#include "slang_compile.h" +#include "slang_log.h" +#include "prog_instruction.h" + + +/** + * Checks if a field selector is a general swizzle (an r-value swizzle + * with replicated components or an l-value swizzle mask) for a + * vector. Returns GL_TRUE if this is the case, <swz> is filled with + * swizzle information. Returns GL_FALSE otherwise. + */ +GLboolean +_slang_is_swizzle(const char *field, GLuint rows, slang_swizzle * swz) +{ + GLuint i; + GLboolean xyzw = GL_FALSE, rgba = GL_FALSE, stpq = GL_FALSE; + + /* init to undefined. + * We rely on undefined/nil values to distinguish between + * regular swizzles and writemasks. + * For example, the swizzle ".xNNN" is the writemask ".x". + * That's different than the swizzle ".xxxx". + */ + for (i = 0; i < 4; i++) + swz->swizzle[i] = SWIZZLE_NIL; + + /* the swizzle can be at most 4-component long */ + swz->num_components = slang_string_length(field); + if (swz->num_components > 4) + return GL_FALSE; + + for (i = 0; i < swz->num_components; i++) { + /* mark which swizzle group is used */ + switch (field[i]) { + case 'x': + case 'y': + case 'z': + case 'w': + xyzw = GL_TRUE; + break; + case 'r': + case 'g': + case 'b': + case 'a': + rgba = GL_TRUE; + break; + case 's': + case 't': + case 'p': + case 'q': + stpq = GL_TRUE; + break; + default: + return GL_FALSE; + } + + /* collect swizzle component */ + switch (field[i]) { + case 'x': + case 'r': + case 's': + swz->swizzle[i] = 0; + break; + case 'y': + case 'g': + case 't': + swz->swizzle[i] = 1; + break; + case 'z': + case 'b': + case 'p': + swz->swizzle[i] = 2; + break; + case 'w': + case 'a': + case 'q': + swz->swizzle[i] = 3; + break; + } + + /* check if the component is valid for given vector's row count */ + if (rows <= swz->swizzle[i]) + return GL_FALSE; + } + + /* only one swizzle group can be used */ + if ((xyzw && rgba) || (xyzw && stpq) || (rgba && stpq)) + return GL_FALSE; + + return GL_TRUE; +} + + + +/** + * Checks if a general swizzle is an l-value swizzle - these swizzles + * do not have duplicated fields. Returns GL_TRUE if this is a + * swizzle mask. Returns GL_FALSE otherwise + */ +GLboolean +_slang_is_swizzle_mask(const slang_swizzle * swz, GLuint rows) +{ + GLuint i, c = 0; + + /* the swizzle may not be longer than the vector dim */ + if (swz->num_components > rows) + return GL_FALSE; + + /* the swizzle components cannot be duplicated */ + for (i = 0; i < swz->num_components; i++) { + if ((c & (1 << swz->swizzle[i])) != 0) + return GL_FALSE; + c |= 1 << swz->swizzle[i]; + } + + return GL_TRUE; +} + + +/** + * Combines (multiplies) two swizzles to form single swizzle. + * Example: "vec.wzyx.yx" --> "vec.zw". + */ +GLvoid +_slang_multiply_swizzles(slang_swizzle * dst, const slang_swizzle * left, + const slang_swizzle * right) +{ + GLuint i; + + dst->num_components = right->num_components; + for (i = 0; i < right->num_components; i++) + dst->swizzle[i] = left->swizzle[right->swizzle[i]]; +} + + +GLvoid +slang_type_specifier_ctr(slang_type_specifier * self) +{ + self->type = SLANG_SPEC_VOID; + self->_struct = NULL; + self->_array = NULL; +} + +GLvoid +slang_type_specifier_dtr(slang_type_specifier * self) +{ + if (self->_struct != NULL) { + slang_struct_destruct(self->_struct); + slang_alloc_free(self->_struct); + } + if (self->_array != NULL) { + slang_type_specifier_dtr(self->_array); + slang_alloc_free(self->_array); + } +} + +GLboolean +slang_type_specifier_copy(slang_type_specifier * x, + const slang_type_specifier * y) +{ + slang_type_specifier z; + + slang_type_specifier_ctr(&z); + z.type = y->type; + 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); + return GL_FALSE; + } + if (!slang_struct_construct(z._struct)) { + slang_alloc_free(z._struct); + slang_type_specifier_dtr(&z); + return GL_FALSE; + } + if (!slang_struct_copy(z._struct, y->_struct)) { + slang_type_specifier_dtr(&z); + return GL_FALSE; + } + } + else if (z.type == SLANG_SPEC_ARRAY) { + z._array = + (slang_type_specifier *) + slang_alloc_malloc(sizeof(slang_type_specifier)); + if (z._array == NULL) { + slang_type_specifier_dtr(&z); + return GL_FALSE; + } + slang_type_specifier_ctr(z._array); + if (!slang_type_specifier_copy(z._array, y->_array)) { + slang_type_specifier_dtr(&z); + return GL_FALSE; + } + } + slang_type_specifier_dtr(x); + *x = z; + 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 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_equal(x->_array, y->_array); + 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; +} + + +GLboolean +slang_typeinfo_construct(slang_typeinfo * ti) +{ + slang_type_specifier_ctr(&ti->spec); + ti->array_len = 0; + return GL_TRUE; +} + +GLvoid +slang_typeinfo_destruct(slang_typeinfo * ti) +{ + slang_type_specifier_dtr(&ti->spec); +} + + + +/** + * Determine the return type of a function. + * \param a_name the function name + * \param param function parameters (overloading) + * \param num_params number of parameters to function + * \param space namespace to search + * \param spec returns the type + * \param funFound returns pointer to the function, or NULL if not found. + * \return GL_TRUE for success, GL_FALSE if failure (bad function name) + */ +static GLboolean +_slang_typeof_function(slang_atom a_name, + slang_operation * params, GLuint num_params, + const slang_name_space * space, + slang_type_specifier * spec, + slang_function **funFound, + slang_atom_pool *atoms, slang_info_log *log) +{ + *funFound = _slang_locate_function(space->funcs, a_name, params, + num_params, space, atoms, log); + if (!*funFound) + return GL_TRUE; /* yes, not false */ + return slang_type_specifier_copy(spec, &(*funFound)->header.type.specifier); +} + + +/** + * Determine the type of a math function. + * \param name name of the operator, one of +,-,*,/ or unary - + * \param params array of function parameters + * \param num_params number of parameters + * \param space namespace to use + * \param spec returns the function's type + * \param atoms atom pool + * \return GL_TRUE for success, GL_FALSE if failure + */ +static GLboolean +typeof_math_call(const char *name, slang_operation *call, + const slang_name_space * space, + slang_type_specifier * spec, + slang_atom_pool * atoms, + slang_info_log *log) +{ + if (call->fun) { + /* we've previously resolved this function call */ + slang_type_specifier_copy(spec, &call->fun->header.type.specifier); + return GL_TRUE; + } + else { + slang_atom atom; + slang_function *fun; + + /* number of params: */ + assert(call->num_children == 1 || call->num_children == 2); + + atom = slang_atom_pool_atom(atoms, name); + if (!_slang_typeof_function(atom, call->children, call->num_children, + space, spec, &fun, atoms, log)) + return GL_FALSE; + + if (fun) { + /* Save pointer to save time in future */ + call->fun = fun; + return GL_TRUE; + } + return GL_FALSE; + } +} + +GLboolean +_slang_typeof_operation(const slang_assemble_ctx * A, + slang_operation * op, + slang_typeinfo * ti) +{ + return _slang_typeof_operation_(op, &A->space, ti, A->atoms, A->log); +} + + +/** + * Determine the return type of an operation. + * \param op the operation node + * \param space the namespace to use + * \param ti the returned type + * \param atoms atom pool + * \return GL_TRUE for success, GL_FALSE if failure + */ +GLboolean +_slang_typeof_operation_(slang_operation * op, + const slang_name_space * space, + slang_typeinfo * ti, + slang_atom_pool * atoms, + slang_info_log *log) +{ + ti->can_be_referenced = GL_FALSE; + 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; + 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: + if (!_slang_typeof_operation_(op->children, space, ti, atoms, log)) + return GL_FALSE; + break; + case SLANG_OPER_LITERAL_BOOL: + if (op->literal_size == 1) + ti->spec.type = SLANG_SPEC_BOOL; + else if (op->literal_size == 2) + ti->spec.type = SLANG_SPEC_BVEC2; + else if (op->literal_size == 3) + ti->spec.type = SLANG_SPEC_BVEC3; + else if (op->literal_size == 4) + 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; + } + 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; + break; + case SLANG_OPER_LITERAL_INT: + if (op->literal_size == 1) + ti->spec.type = SLANG_SPEC_INT; + else if (op->literal_size == 2) + ti->spec.type = SLANG_SPEC_IVEC2; + else if (op->literal_size == 3) + ti->spec.type = SLANG_SPEC_IVEC3; + else if (op->literal_size == 4) + 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; + } + break; + case SLANG_OPER_LITERAL_FLOAT: + if (op->literal_size == 1) + ti->spec.type = SLANG_SPEC_FLOAT; + else if (op->literal_size == 2) + ti->spec.type = SLANG_SPEC_VEC2; + else if (op->literal_size == 3) + ti->spec.type = SLANG_SPEC_VEC3; + else if (op->literal_size == 4) + 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; + } + break; + case SLANG_OPER_IDENTIFIER: + { + slang_variable *var; + var = _slang_locate_variable(op->locals, op->a_id, GL_TRUE); + if (!var) { + slang_info_log_error(log, "undefined variable '%s'", + (char *) op->a_id); + return GL_FALSE; + } + if (!slang_type_specifier_copy(&ti->spec, &var->type.specifier)) { + slang_info_log_memory(log); + return GL_FALSE; + } + ti->can_be_referenced = GL_TRUE; + ti->array_len = var->array_len; + } + break; + case SLANG_OPER_SEQUENCE: + /* TODO: check [0] and [1] if they match */ + if (!_slang_typeof_operation_(&op->children[1], space, ti, atoms, log)) { + return GL_FALSE; + } + 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: + /* TODO: check [1] and [2] if they match */ + if (!_slang_typeof_operation_(&op->children[1], space, ti, atoms, log)) { + return GL_FALSE; + } + 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: + assert(op->num_children == 2); + if (!typeof_math_call("+", op, space, &ti->spec, atoms, log)) + return GL_FALSE; + break; + case SLANG_OPER_SUBTRACT: + assert(op->num_children == 2); + if (!typeof_math_call("-", op, space, &ti->spec, atoms, log)) + return GL_FALSE; + break; + case SLANG_OPER_MULTIPLY: + assert(op->num_children == 2); + if (!typeof_math_call("*", op, space, &ti->spec, atoms, log)) + return GL_FALSE; + break; + case SLANG_OPER_DIVIDE: + assert(op->num_children == 2); + if (!typeof_math_call("/", op, space, &ti->spec, atoms, log)) + return GL_FALSE; + break; + /*case SLANG_OPER_MODULUS: */ + case SLANG_OPER_PLUS: + if (!_slang_typeof_operation_(op->children, space, ti, atoms, log)) + return GL_FALSE; + ti->can_be_referenced = GL_FALSE; + ti->is_swizzled = GL_FALSE; + break; + case SLANG_OPER_MINUS: + assert(op->num_children == 1); + if (!typeof_math_call("-", op, space, &ti->spec, atoms, log)) + return GL_FALSE; + break; + /*case SLANG_OPER_COMPLEMENT: */ + case SLANG_OPER_SUBSCRIPT: + { + slang_typeinfo _ti; + + if (!slang_typeinfo_construct(&_ti)) + return GL_FALSE; + if (!_slang_typeof_operation_(op->children, space, &_ti, atoms, log)) { + slang_typeinfo_destruct(&_ti); + return GL_FALSE; + } + ti->can_be_referenced = _ti.can_be_referenced; + if (_ti.spec.type == SLANG_SPEC_ARRAY) { + if (!slang_type_specifier_copy(&ti->spec, _ti.spec._array)) { + slang_typeinfo_destruct(&_ti); + return GL_FALSE; + } + } + else { + if (!_slang_type_is_vector(_ti.spec.type) + && !_slang_type_is_matrix(_ti.spec.type)) { + slang_typeinfo_destruct(&_ti); + slang_info_log_error(log, "cannot index a non-array type"); + return GL_FALSE; + } + ti->spec.type = _slang_type_base(_ti.spec.type); + } + slang_typeinfo_destruct(&_ti); + } + break; + case SLANG_OPER_CALL: + if (op->fun) { + /* we've resolved this call before */ + slang_type_specifier_copy(&ti->spec, &op->fun->header.type.specifier); + } + else { + slang_function *fun; + if (!_slang_typeof_function(op->a_id, op->children, op->num_children, + space, &ti->spec, &fun, atoms, log)) + return GL_FALSE; + if (fun) { + /* save result for future use */ + op->fun = fun; + } + else { + slang_struct *s = + slang_struct_scope_find(space->structs, op->a_id, GL_TRUE); + if (s) { + /* struct initializer */ + ti->spec.type = SLANG_SPEC_STRUCT; + ti->spec._struct = + (slang_struct *) slang_alloc_malloc(sizeof(slang_struct)); + if (ti->spec._struct == NULL) + return GL_FALSE; + if (!slang_struct_construct(ti->spec._struct)) { + slang_alloc_free(ti->spec._struct); + ti->spec._struct = NULL; + return GL_FALSE; + } + if (!slang_struct_copy(ti->spec._struct, s)) + return GL_FALSE; + } + else { + /* float, int, vec4, mat3, etc. constructor? */ + const char *name; + slang_type_specifier_type type; + + name = slang_atom_pool_id(atoms, op->a_id); + type = slang_type_specifier_type_from_string(name); + if (type == SLANG_SPEC_VOID) { + slang_info_log_error(log, "undefined function '%s'", name); + return GL_FALSE; + } + ti->spec.type = type; + } + } + } + break; + case SLANG_OPER_FIELD: + { + slang_typeinfo _ti; + + if (!slang_typeinfo_construct(&_ti)) + return GL_FALSE; + if (!_slang_typeof_operation_(op->children, space, &_ti, atoms, log)) { + slang_typeinfo_destruct(&_ti); + return GL_FALSE; + } + if (_ti.spec.type == SLANG_SPEC_STRUCT) { + slang_variable *field; + + field = _slang_locate_variable(_ti.spec._struct->fields, op->a_id, + GL_FALSE); + if (field == NULL) { + slang_typeinfo_destruct(&_ti); + return GL_FALSE; + } + if (!slang_type_specifier_copy(&ti->spec, &field->type.specifier)) { + slang_typeinfo_destruct(&_ti); + return GL_FALSE; + } + ti->can_be_referenced = _ti.can_be_referenced; + } + else { + GLuint rows; + const char *swizzle; + slang_type_specifier_type base; + + /* determine the swizzle of the field expression */ + if (!_slang_type_is_vector(_ti.spec.type)) { + slang_typeinfo_destruct(&_ti); + slang_info_log_error(log, "Can't swizzle scalar expression"); + return GL_FALSE; + } + rows = _slang_type_dim(_ti.spec.type); + swizzle = slang_atom_pool_id(atoms, op->a_id); + if (!_slang_is_swizzle(swizzle, rows, &ti->swz)) { + slang_typeinfo_destruct(&_ti); + slang_info_log_error(log, "bad swizzle '%s'", swizzle); + return GL_FALSE; + } + ti->is_swizzled = GL_TRUE; + ti->can_be_referenced = _ti.can_be_referenced + && _slang_is_swizzle_mask(&ti->swz, rows); + if (_ti.is_swizzled) { + slang_swizzle swz; + + /* swizzle the swizzle */ + _slang_multiply_swizzles(&swz, &_ti.swz, &ti->swz); + ti->swz = swz; + } + base = _slang_type_base(_ti.spec.type); + switch (ti->swz.num_components) { + case 1: + ti->spec.type = base; + break; + case 2: + switch (base) { + case SLANG_SPEC_FLOAT: + ti->spec.type = SLANG_SPEC_VEC2; + break; + case SLANG_SPEC_INT: + ti->spec.type = SLANG_SPEC_IVEC2; + break; + case SLANG_SPEC_BOOL: + ti->spec.type = SLANG_SPEC_BVEC2; + break; + default: + break; + } + break; + case 3: + switch (base) { + case SLANG_SPEC_FLOAT: + ti->spec.type = SLANG_SPEC_VEC3; + break; + case SLANG_SPEC_INT: + ti->spec.type = SLANG_SPEC_IVEC3; + break; + case SLANG_SPEC_BOOL: + ti->spec.type = SLANG_SPEC_BVEC3; + break; + default: + break; + } + break; + case 4: + switch (base) { + case SLANG_SPEC_FLOAT: + ti->spec.type = SLANG_SPEC_VEC4; + break; + case SLANG_SPEC_INT: + ti->spec.type = SLANG_SPEC_IVEC4; + break; + case SLANG_SPEC_BOOL: + ti->spec.type = SLANG_SPEC_BVEC4; + break; + default: + break; + } + break; + default: + break; + } + } + slang_typeinfo_destruct(&_ti); + } + break; + case SLANG_OPER_POSTINCREMENT: + case SLANG_OPER_POSTDECREMENT: + if (!_slang_typeof_operation_(op->children, space, ti, atoms, log)) + return GL_FALSE; + ti->can_be_referenced = GL_FALSE; + ti->is_swizzled = GL_FALSE; + break; + default: + return GL_FALSE; + } + + return GL_TRUE; +} + + +/** + * Lookup a function according to name and parameter count/types. + */ +slang_function * +_slang_locate_function(const slang_function_scope * funcs, slang_atom a_name, + slang_operation * args, GLuint num_args, + const slang_name_space * space, slang_atom_pool * atoms, + slang_info_log *log) +{ + GLuint i; + + for (i = 0; i < funcs->num_functions; i++) { + slang_function *f = &funcs->functions[i]; + const GLuint haveRetValue = _slang_function_has_return_value(f); + GLuint j; + + if (a_name != f->header.a_name) + continue; + if (f->param_count - haveRetValue != num_args) + continue; + + /* compare parameter / argument types */ + for (j = 0; j < num_args; j++) { + slang_typeinfo ti; + + if (!slang_typeinfo_construct(&ti)) + return NULL; + if (!_slang_typeof_operation_(&args[j], space, &ti, atoms, log)) { + slang_typeinfo_destruct(&ti); + return NULL; + } + 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. + */ + if (!ti.can_be_referenced && + (f->parameters->variables[j]->type.qualifier == SLANG_QUAL_OUT || + f->parameters->variables[j]->type.qualifier == SLANG_QUAL_INOUT)) + break; + } + if (j == num_args) + return f; + } + if (funcs->outer_scope != NULL) + return _slang_locate_function(funcs->outer_scope, a_name, args, + num_args, space, atoms, log); + return NULL; +} + + +/** + * Determine if a type is a matrix. + * \return GL_TRUE if is a matrix, GL_FALSE otherwise. + */ +GLboolean +_slang_type_is_matrix(slang_type_specifier_type ty) +{ + switch (ty) { + case SLANG_SPEC_MAT2: + case SLANG_SPEC_MAT3: + case SLANG_SPEC_MAT4: + return GL_TRUE; + default: + return GL_FALSE; + } +} + + +/** + * Determine if a type is a vector. + * \return GL_TRUE if is a vector, GL_FALSE otherwise. + */ +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: + return GL_TRUE; + default: + return GL_FALSE; + } +} + + +/** + * Given a vector type, return the type of the vector's elements + */ +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; + default: + return SLANG_SPEC_VOID; + } +} + + +/** + * Return the dimensionality of a vector or matrix type. + */ +GLuint +_slang_type_dim(slang_type_specifier_type ty) +{ + switch (ty) { + 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: + return 2; + 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: + return 4; + default: + return 0; + } +} diff --git a/src/mesa/shader/slang/slang_assemble_typeinfo.h b/src/mesa/shader/slang/slang_typeinfo.h index 777dc21f3a..be2e229b76 100644 --- a/src/mesa/shader/slang/slang_assemble_typeinfo.h +++ b/src/mesa/shader/slang/slang_typeinfo.h @@ -22,12 +22,68 @@ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -#if !defined SLANG_ASSEMBLE_TYPEINFO_H -#define SLANG_ASSEMBLE_TYPEINFO_H +#ifndef SLANG_TYPEINFO_H +#define SLANG_TYPEINFO_H 1 + +#include "imports.h" +#include "mtypes.h" +#include "slang_log.h" +#include "slang_utility.h" +#include "slang_vartable.h" -#if defined __cplusplus -extern "C" { -#endif + +struct slang_operation_; + + +/** + * Holds complete information about vector swizzle - the <swizzle> + * array contains vector component source indices, where 0 is "x", 1 + * is "y", 2 is "z" and 3 is "w". + * Example: "xwz" --> { 3, { 0, 3, 2, not used } }. + */ +typedef struct slang_swizzle_ +{ + GLuint num_components; + GLuint swizzle[4]; +} slang_swizzle; + +typedef struct slang_name_space_ +{ + struct slang_function_scope_ *funcs; + struct slang_struct_scope_ *structs; + struct slang_variable_scope_ *vars; +} slang_name_space; + + +typedef struct slang_assemble_ctx_ +{ + slang_atom_pool *atoms; + slang_name_space space; + struct gl_program *program; + slang_var_table *vartable; + slang_info_log *log; + struct slang_label_ *curFuncEndLabel; + struct slang_ir_node_ *CurLoop; +} slang_assemble_ctx; + + +extern struct slang_function_ * +_slang_locate_function(const struct slang_function_scope_ *funcs, + slang_atom name, struct slang_operation_ *params, + GLuint num_params, + const slang_name_space *space, + slang_atom_pool *atoms, slang_info_log *log); + + +extern GLboolean +_slang_is_swizzle(const char *field, GLuint rows, slang_swizzle *swz); + +extern GLboolean +_slang_is_swizzle_mask(const slang_swizzle *swz, GLuint rows); + +extern GLvoid +_slang_multiply_swizzles(slang_swizzle *, const slang_swizzle *, + const slang_swizzle *); /** @@ -35,30 +91,32 @@ extern "C" { */ 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_SAMPLER2DRECT, + SLANG_SPEC_SAMPLER1DSHADOW, + SLANG_SPEC_SAMPLER2DSHADOW, + SLANG_SPEC_SAMPLER2DRECTSHADOW, + SLANG_SPEC_STRUCT, + SLANG_SPEC_ARRAY } slang_type_specifier_type; @@ -87,20 +145,20 @@ slang_type_specifier_equal(const slang_type_specifier *, const slang_type_specifier *); -typedef struct slang_assembly_typeinfo_ +typedef struct slang_typeinfo_ { GLboolean can_be_referenced; GLboolean is_swizzled; slang_swizzle swz; slang_type_specifier spec; GLuint array_len; -} slang_assembly_typeinfo; +} slang_typeinfo; extern GLboolean -slang_assembly_typeinfo_construct(slang_assembly_typeinfo *); +slang_typeinfo_construct(slang_typeinfo *); extern GLvoid -slang_assembly_typeinfo_destruct(slang_assembly_typeinfo *); +slang_typeinfo_destruct(slang_typeinfo *); /** @@ -110,25 +168,14 @@ slang_assembly_typeinfo_destruct(slang_assembly_typeinfo *); */ extern GLboolean _slang_typeof_operation(const slang_assemble_ctx *, - const struct slang_operation_ *, - slang_assembly_typeinfo *); + struct slang_operation_ *, + slang_typeinfo *); extern GLboolean -_slang_typeof_operation_(const struct slang_operation_ *, - const slang_assembly_name_space *, - slang_assembly_typeinfo *, slang_atom_pool *); - -/** - * Retrieves type of a function prototype, if one exists. - * Returns GL_TRUE on success, even if the function was not found. - * Returns GL_FALSE otherwise. - */ -extern GLboolean -_slang_typeof_function(slang_atom a_name, - const struct slang_operation_ *params, - GLuint num_params, const slang_assembly_name_space *, - slang_type_specifier *spec, GLboolean *exists, - slang_atom_pool *); +_slang_typeof_operation_(struct slang_operation_ *, + const slang_name_space *, + slang_typeinfo *, slang_atom_pool *, + slang_info_log *log); extern GLboolean _slang_type_is_matrix(slang_type_specifier_type); @@ -143,10 +190,4 @@ extern GLuint _slang_type_dim(slang_type_specifier_type); - -#ifdef __cplusplus -} #endif - -#endif - diff --git a/src/mesa/shader/slang/slang_utility.c b/src/mesa/shader/slang/slang_utility.c index 256d52455d..0fbfcc5840 100644 --- a/src/mesa/shader/slang/slang_utility.c +++ b/src/mesa/shader/slang/slang_utility.c @@ -31,11 +31,13 @@ #include "imports.h" #include "slang_utility.h" -char *slang_string_concat (char *dst, const char *src) +char * +slang_string_concat (char *dst, const char *src) { - return _mesa_strcpy (dst + _mesa_strlen (dst), src); + return _mesa_strcpy (dst + _mesa_strlen (dst), src); } + /* slang_string */ GLvoid @@ -156,8 +158,8 @@ slang_atom_pool_destruct (slang_atom_pool * pool) slang_alloc_free(entry->id); slang_alloc_free(entry); entry = next; - } - } + } + } } /* @@ -211,12 +213,11 @@ slang_atom_pool_atom(slang_atom_pool * pool, const char * id) return (slang_atom) (**entry).id; } -/* +/** * Return the name of a given atom. */ const char * slang_atom_pool_id(slang_atom_pool * pool, slang_atom atom) { - return (const char *) (atom); + return (const char *) (atom); } - diff --git a/src/mesa/shader/slang/slang_utility.h b/src/mesa/shader/slang/slang_utility.h index 565de4e4b0..360241916f 100644 --- a/src/mesa/shader/slang/slang_utility.h +++ b/src/mesa/shader/slang/slang_utility.h @@ -25,9 +25,6 @@ #if !defined SLANG_UTILITY_H #define SLANG_UTILITY_H -#if defined __cplusplus -extern "C" { -#endif /* Compile-time assertions. If the expression is zero, try to declare an * array of size [-1] to cause compilation error. @@ -102,9 +99,6 @@ GLvoid slang_atom_pool_destruct (slang_atom_pool *); slang_atom slang_atom_pool_atom (slang_atom_pool *, const char *); const char *slang_atom_pool_id (slang_atom_pool *, slang_atom); -#ifdef __cplusplus -} -#endif #endif diff --git a/src/mesa/shader/slang/slang_vartable.c b/src/mesa/shader/slang/slang_vartable.c new file mode 100644 index 0000000000..e3efa17908 --- /dev/null +++ b/src/mesa/shader/slang/slang_vartable.c @@ -0,0 +1,328 @@ + +#include "imports.h" +#include "slang_compile.h" +#include "slang_compile_variable.h" +#include "slang_vartable.h" +#include "slang_ir.h" +#include "prog_instruction.h" + + +static int dbg = 0; + + +typedef enum { + FREE, + VAR, + TEMP +} TempState; + + +/** + * Variable/register info for one variable scope. + */ +struct table +{ + int Level; + int NumVars; + slang_variable **Vars; /* array [NumVars] */ + + TempState Temps[MAX_PROGRAM_TEMPS * 4]; /* per-component state */ + int ValSize[MAX_PROGRAM_TEMPS]; /* For debug only */ + + struct table *Parent; /** Parent scope table */ +}; + + +/** + * A variable table is a stack of tables, one per scope. + */ +struct slang_var_table_ +{ + GLint CurLevel; + GLuint MaxRegisters; + struct table *Top; /**< Table at top of stack */ +}; + + + +slang_var_table * +_slang_new_var_table(GLuint maxRegisters) +{ + slang_var_table *vt + = (slang_var_table *) _mesa_calloc(sizeof(slang_var_table)); + if (vt) { + vt->MaxRegisters = maxRegisters; + } + return vt; +} + + +void +_slang_delete_var_table(slang_var_table *vt) +{ + if (vt->Top) { + _mesa_problem(NULL, "non-empty var table in _slang_delete_var_table()"); + return; + } + _mesa_free(vt); +} + + + +/** + * Create new table, put at head, return ptr to it. + * XXX we should take a maxTemps parameter to indicate how many temporaries + * are available for the current shader/program target. + */ +void +_slang_push_var_table(slang_var_table *vt) +{ + struct table *t = (struct table *) _mesa_calloc(sizeof(struct table)); + if (t) { + t->Level = vt->CurLevel++; + t->Parent = vt->Top; + if (t->Parent) { + /* copy the info indicating which temp regs are in use */ + memcpy(t->Temps, t->Parent->Temps, sizeof(t->Temps)); + memcpy(t->ValSize, t->Parent->ValSize, sizeof(t->ValSize)); + } + vt->Top = t; + if (dbg) printf("Pushing level %d\n", t->Level); + } +} + + +/** + * Destroy given table, return ptr to Parent + */ +void +_slang_pop_var_table(slang_var_table *vt) +{ + struct table *t = vt->Top; + int i; + + if (dbg) printf("Popping level %d\n", t->Level); + + /* free the storage allocated for each variable */ + for (i = 0; i < t->NumVars; i++) { + slang_ir_storage *store = (slang_ir_storage *) t->Vars[i]->aux; + GLint j; + GLuint comp; + if (dbg) printf(" Free var %s, size %d at %d\n", + (char*) t->Vars[i]->a_name, store->Size, + store->Index); + + if (store->Size == 1) + comp = GET_SWZ(store->Swizzle, 0); + else + comp = 0; + + assert(store->Index >= 0); + for (j = 0; j < store->Size; j++) { + assert(t->Temps[store->Index * 4 + j + comp] == VAR); + t->Temps[store->Index * 4 + j + comp] = FREE; + } + store->Index = -1; + } + if (t->Parent) { + /* just verify that any remaining allocations in this scope + * were for temps + */ + for (i = 0; i < vt->MaxRegisters * 4; i++) { + if (t->Temps[i] != FREE && t->Parent->Temps[i] == FREE) { + if (dbg) printf(" Free reg %d\n", i/4); + assert(t->Temps[i] == TEMP); + } + } + } + + if (t->Vars) + free(t->Vars); + + vt->Top = t->Parent; + free(t); + vt->CurLevel--; +} + + +/** + * Add a new variable to the given symbol table. + */ +void +_slang_add_variable(slang_var_table *vt, slang_variable *v) +{ + struct table *t; + assert(vt); + t = vt->Top; + assert(t); + if (dbg) printf("Adding var %s\n", (char *) v->a_name); + t->Vars = realloc(t->Vars, (t->NumVars + 1) * sizeof(slang_variable *)); + t->Vars[t->NumVars] = v; + t->NumVars++; +} + + +/** + * Look for variable by name in given table. + * If not found, Parent table will be searched. + */ +slang_variable * +_slang_find_variable(const slang_var_table *vt, slang_atom name) +{ + struct table *t = vt->Top; + while (1) { + int i; + for (i = 0; i < t->NumVars; i++) { + if (t->Vars[i]->a_name == name) + return t->Vars[i]; + } + if (t->Parent) + t = t->Parent; + else + return NULL; + } +} + + +/** + * Allocation helper. + * \param size var size in floats + * \return position for var, measured in floats + */ +static GLint +alloc_reg(slang_var_table *vt, GLint size, GLboolean isTemp) +{ + struct table *t = vt->Top; + /* if size == 1, allocate anywhere, else, pos must be multiple of 4 */ + const GLuint step = (size == 1) ? 1 : 4; + GLuint i, j; + assert(size > 0); /* number of floats */ + + for (i = 0; i <= vt->MaxRegisters * 4 - size; i += step) { + GLuint found = 0; + for (j = 0; j < size; j++) { + if (i + j < vt->MaxRegisters * 4 && t->Temps[i + j] == FREE) { + found++; + } + else { + break; + } + } + if (found == size) { + /* found block of size free regs */ + if (size > 1) + assert(i % 4 == 0); + for (j = 0; j < size; j++) + t->Temps[i + j] = isTemp ? TEMP : VAR; + t->ValSize[i] = size; + return i; + } + } + return -1; +} + + +/** + * Allocate temp register(s) for storing a variable. + * \param size size needed, in floats + * \param swizzle returns swizzle mask for accessing var in register + * \return register allocated, or -1 + */ +GLboolean +_slang_alloc_var(slang_var_table *vt, slang_ir_storage *store) +{ + struct table *t = vt->Top; + const int i = alloc_reg(vt, store->Size, GL_FALSE); + if (i < 0) + return GL_FALSE; + + store->Index = i / 4; + if (store->Size == 1) { + const GLuint comp = i % 4; + store->Swizzle = MAKE_SWIZZLE4(comp, comp, comp, comp); + if (dbg) printf("Alloc var sz %d at %d.%c (level %d)\n", + store->Size, store->Index, "xyzw"[comp], t->Level); + } + else { + store->Swizzle = SWIZZLE_NOOP; + if (dbg) printf("Alloc var sz %d at %d.xyzw (level %d)\n", + store->Size, store->Index, t->Level); + } + return GL_TRUE; +} + + + +/** + * Allocate temp register(s) for storing an unnamed intermediate value. + */ +GLboolean +_slang_alloc_temp(slang_var_table *vt, slang_ir_storage *store) +{ + struct table *t = vt->Top; + const int i = alloc_reg(vt, store->Size, GL_TRUE); + if (i < 0) + return GL_FALSE; + + store->Index = i / 4; + if (store->Size == 1) { + const GLuint comp = i % 4; + store->Swizzle = MAKE_SWIZZLE4(comp, comp, comp, comp); + if (dbg) printf("Alloc temp sz %d at %d.%c (level %d)\n", + store->Size, store->Index, "xyzw"[comp], t->Level); + } + else { + store->Swizzle = SWIZZLE_NOOP; + if (dbg) printf("Alloc temp sz %d at %d.xyzw (level %d)\n", + store->Size, store->Index, t->Level); + } + return GL_TRUE; +} + + +void +_slang_free_temp(slang_var_table *vt, slang_ir_storage *store) +{ + struct table *t = vt->Top; + GLuint i; + GLuint r = store->Index; + assert(store->Size > 0); + assert(r >= 0); + assert(r + store->Size <= vt->MaxRegisters * 4); + if (dbg) printf("Free temp sz %d at %d (level %d)\n", store->Size, r, t->Level); + if (store->Size == 1) { + const GLuint comp = GET_SWZ(store->Swizzle, 0); + assert(store->Swizzle == MAKE_SWIZZLE4(comp, comp, comp, comp)); + assert(comp < 4); + assert(t->ValSize[r * 4 + comp] == 1); + assert(t->Temps[r * 4 + comp] == TEMP); + t->Temps[r * 4 + comp] = FREE; + } + else { + /*assert(store->Swizzle == SWIZZLE_NOOP);*/ + assert(t->ValSize[r*4] == store->Size); + for (i = 0; i < store->Size; i++) { + assert(t->Temps[r * 4 + i] == TEMP); + t->Temps[r * 4 + i] = FREE; + } + } +} + + +GLboolean +_slang_is_temp(const slang_var_table *vt, const slang_ir_storage *store) +{ + struct table *t = vt->Top; + assert(store->Index >= 0); + assert(store->Index < vt->MaxRegisters); + GLuint comp; + if (store->Swizzle == SWIZZLE_NOOP) + comp = 0; + else + comp = GET_SWZ(store->Swizzle, 0); + + if (t->Temps[store->Index * 4 + comp] == TEMP) + return GL_TRUE; + else + return GL_FALSE; +} diff --git a/src/mesa/shader/slang/slang_vartable.h b/src/mesa/shader/slang/slang_vartable.h new file mode 100644 index 0000000000..8a3b992c96 --- /dev/null +++ b/src/mesa/shader/slang/slang_vartable.h @@ -0,0 +1,42 @@ + +#ifndef SLANG_VARTABLE_H +#define SLANG_VARTABLE_H + +struct _slang_ir_storage; + +typedef struct slang_var_table_ slang_var_table; + +struct slang_variable_; + +extern slang_var_table * +_slang_new_var_table(GLuint maxRegisters); + +extern void +_slang_delete_var_table(slang_var_table *vt); + +extern void +_slang_push_var_table(slang_var_table *parent); + +extern void +_slang_pop_var_table(slang_var_table *t); + +extern void +_slang_add_variable(slang_var_table *t, struct slang_variable_ *v); + +extern struct slang_variable_ * +_slang_find_variable(const slang_var_table *t, slang_atom name); + +extern GLboolean +_slang_alloc_var(slang_var_table *t, struct _slang_ir_storage *store); + +extern GLboolean +_slang_alloc_temp(slang_var_table *t, struct _slang_ir_storage *store); + +extern void +_slang_free_temp(slang_var_table *t, struct _slang_ir_storage *store); + +extern GLboolean +_slang_is_temp(const slang_var_table *t, const struct _slang_ir_storage *store); + + +#endif /* SLANG_VARTABLE_H */ diff --git a/src/mesa/shader/slang/traverse_wrap.h b/src/mesa/shader/slang/traverse_wrap.h deleted file mode 100644 index b2f244ee01..0000000000 --- a/src/mesa/shader/slang/traverse_wrap.h +++ /dev/null @@ -1,112 +0,0 @@ -/* - * Mesa 3-D graphics library - * Version: 6.3 - * - * Copyright (C) 2005 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. - */ - -/** - * \file traverse_wrap.h - * Handy TIntermTraverser class wrapper - * \author Michal Krol - */ - -#ifndef __TRAVERSE_WRAP_H__ -#define __TRAVERSE_WRAP_H__ - -#include "Include/intermediate.h" - -/* - The original TIntermTraverser class that is used to walk the intermediate tree, - is not very elegant in its design. One must define static functions with - appropriate prototypes, construct TIntermTraverser object, and set its member - function pointers to one's static functions. If traversal-specific data - is needed, a new class must be derived, and one must up-cast the object - passed as a parameter to the static function. - - The class below eliminates this burden by providing virtual methods that are - to be overridden in the derived class. -*/ - -class traverse_wrap: private TIntermTraverser -{ -private: - static void _visitSymbol (TIntermSymbol *S, TIntermTraverser *T) { - static_cast<traverse_wrap *> (T)->Symbol (*S); - } - static void _visitConstantUnion (TIntermConstantUnion *U, TIntermTraverser *T) { - static_cast<traverse_wrap *> (T)->ConstantUnion (*U); - } - static bool _visitBinary (bool preVisit, TIntermBinary *B, TIntermTraverser *T) { - return static_cast<traverse_wrap *> (T)->Binary (preVisit, *B); - } - static bool _visitUnary (bool preVisit, TIntermUnary *U, TIntermTraverser *T) { - return static_cast<traverse_wrap *> (T)->Unary (preVisit, *U); - } - static bool _visitSelection (bool preVisit, TIntermSelection *S, TIntermTraverser *T) { - return static_cast<traverse_wrap *> (T)->Selection (preVisit, *S); - } - static bool _visitAggregate (bool preVisit, TIntermAggregate *A, TIntermTraverser *T) { - return static_cast<traverse_wrap *> (T)->Aggregate (preVisit, *A); - } - static bool _visitLoop (bool preVisit, TIntermLoop *L, TIntermTraverser *T) { - return static_cast<traverse_wrap *> (T)->Loop (preVisit, *L); - } - static bool _visitBranch (bool preVisit, TIntermBranch *B, TIntermTraverser *T) { - return static_cast<traverse_wrap *> (T)->Branch (preVisit, *B); - } -public: - traverse_wrap () { - visitSymbol = _visitSymbol; - visitConstantUnion = _visitConstantUnion; - visitBinary = _visitBinary; - visitUnary = _visitUnary; - visitSelection = _visitSelection; - visitAggregate = _visitAggregate; - visitLoop = _visitLoop; - visitBranch = _visitBranch; - } -protected: - virtual void Symbol (const TIntermSymbol &) { - } - virtual void ConstantUnion (const TIntermConstantUnion &) { - } - virtual bool Binary (bool, const TIntermBinary &) { - return true; - } - virtual bool Unary (bool, const TIntermUnary &) { - return true; - } - virtual bool Selection (bool, const TIntermSelection &) { - return true; - } - virtual bool Aggregate (bool, const TIntermAggregate &) { - return true; - } - virtual bool Loop (bool, const TIntermLoop &) { - return true; - } - virtual bool Branch (bool, const TIntermBranch &) { - return true; - } -}; - -#endif - diff --git a/src/mesa/sources b/src/mesa/sources index 6d6d22861c..73fd58125a 100644 --- a/src/mesa/sources +++ b/src/mesa/sources @@ -48,6 +48,7 @@ MAIN_SOURCES = \ main/rastpos.c \ main/rbadaptors.c \ main/renderbuffer.c \ + main/shaders.c \ main/state.c \ main/stencil.c \ main/texcompress.c \ @@ -83,7 +84,6 @@ SWRAST_SOURCES = \ swrast/s_aatriangle.c \ swrast/s_accum.c \ swrast/s_alpha.c \ - swrast/s_arbshader.c \ swrast/s_atifragshader.c \ swrast/s_bitmap.c \ swrast/s_blend.c \ @@ -95,11 +95,11 @@ SWRAST_SOURCES = \ swrast/s_drawpix.c \ swrast/s_feedback.c \ swrast/s_fog.c \ + swrast/s_fragprog.c \ swrast/s_imaging.c \ swrast/s_lines.c \ swrast/s_logic.c \ swrast/s_masking.c \ - swrast/s_nvfragprog.c \ swrast/s_points.c \ swrast/s_readpix.c \ swrast/s_span.c \ @@ -120,7 +120,6 @@ TNL_SOURCES = \ tnl/t_draw.c \ tnl/t_vb_arbprogram.c \ tnl/t_vb_arbprogram_sse.c \ - tnl/t_vb_arbshader.c\ tnl/t_vb_program.c \ tnl/t_vb_render.c \ tnl/t_vb_texgen.c \ @@ -160,60 +159,37 @@ SHADER_SOURCES = \ shader/grammar/grammar_mesa.c \ shader/nvfragparse.c \ shader/nvprogram.c \ - shader/nvvertexec.c \ shader/nvvertparse.c \ shader/program.c \ + shader/prog_debug.c \ + shader/prog_execute.c \ + shader/prog_instruction.c \ + shader/prog_parameter.c \ + shader/prog_print.c \ + shader/prog_statevars.c \ shader/programopt.c \ - shader/shaderobjects.c \ - shader/shaderobjects_3dlabs.c - -SLANG_C_SOURCES = \ - shader/slang/MachineIndependent/preprocessor/atom.c \ - shader/slang/MachineIndependent/preprocessor/cpp.c \ - shader/slang/MachineIndependent/preprocessor/cppstruct.c \ - shader/slang/MachineIndependent/preprocessor/memory.c \ - shader/slang/MachineIndependent/preprocessor/scanner.c \ - shader/slang/MachineIndependent/preprocessor/symbols.c \ - shader/slang/MachineIndependent/preprocessor/tokens.c - -SLANG_CPP_SOURCES = \ - shader/slang/slang_mesa.cpp \ - shader/slang/MachineIndependent/Gen_glslang.cpp \ - shader/slang/MachineIndependent/Gen_glslang_tab.cpp \ - shader/slang/MachineIndependent/InfoSink.cpp \ - shader/slang/MachineIndependent/Initialize.cpp \ - shader/slang/MachineIndependent/Intermediate.cpp \ - shader/slang/MachineIndependent/intermOut.cpp \ - shader/slang/MachineIndependent/IntermTraverse.cpp \ - shader/slang/MachineIndependent/parseConst.cpp \ - shader/slang/MachineIndependent/ParseHelper.cpp \ - shader/slang/MachineIndependent/PoolAlloc.cpp \ - shader/slang/MachineIndependent/QualifierAlive.cpp \ - shader/slang/MachineIndependent/RemoveTree.cpp \ - shader/slang/MachineIndependent/ShaderLang.cpp \ - shader/slang/MachineIndependent/SymbolTable.cpp \ - shader/slang/OGLCompilersDLL/Initialisation.cpp \ - shader/slang/OSDependent/Linux/ossource.cpp + shader/shader_api.c \ SLANG_SOURCES = \ - shader/slang/slang_analyse.c \ - shader/slang/slang_assemble.c \ - shader/slang/slang_assemble_assignment.c \ - shader/slang/slang_assemble_conditional.c \ - shader/slang/slang_assemble_constructor.c \ - shader/slang/slang_assemble_typeinfo.c \ + shader/slang/slang_builtin.c \ + shader/slang/slang_codegen.c \ shader/slang/slang_compile.c \ shader/slang/slang_compile_function.c \ shader/slang/slang_compile_operation.c \ shader/slang/slang_compile_struct.c \ shader/slang/slang_compile_variable.c \ - shader/slang/slang_execute.c \ - shader/slang/slang_export.c \ + shader/slang/slang_emit.c \ + shader/slang/slang_ir.c \ + shader/slang/slang_label.c \ shader/slang/slang_library_noise.c \ - shader/slang/slang_library_texsample.c \ shader/slang/slang_link.c \ + shader/slang/slang_log.c \ shader/slang/slang_preprocess.c \ + shader/slang/slang_print.c \ + shader/slang/slang_simplify.c \ shader/slang/slang_storage.c \ + shader/slang/slang_typeinfo.c \ + shader/slang/slang_vartable.c \ shader/slang/slang_utility.c ASM_C_SOURCES = \ @@ -224,8 +200,7 @@ ASM_C_SOURCES = \ x86/rtasm/x86sse.c \ sparc/sparc.c \ ppc/common_ppc.c \ - x86-64/x86-64.c \ - shader/slang/slang_execute_x86.c + x86-64/x86-64.c X86_SOURCES = \ x86/common_x86_asm.S \ @@ -325,7 +300,6 @@ SOLO_SOURCES = \ $(SWRAST_SETUP_SOURCES) \ $(ASM_C_SOURCES) \ $(SLANG_SOURCES) -# $(SLANG_C_SOURCES) CORE_SOURCES = \ $(GLAPI_SOURCES) \ @@ -364,7 +338,5 @@ INCLUDE_DIRS = \ -I$(TOP)/src/mesa/shader \ -I$(TOP)/src/mesa/shader/grammar \ -I$(TOP)/src/mesa/shader/slang \ - -I$(TOP)/src/mesa/shader/slang/OSDependent/Linux \ - -I$(TOP)/src/mesa/shader/slang/OGLCompilersDLL \ -I$(TOP)/src/mesa/swrast \ -I$(TOP)/src/mesa/swrast_setup diff --git a/src/mesa/swrast/s_aaline.c b/src/mesa/swrast/s_aaline.c index b3a209923f..c81095163b 100644 --- a/src/mesa/swrast/s_aaline.c +++ b/src/mesa/swrast/s_aaline.c @@ -1,8 +1,8 @@ /* * Mesa 3-D graphics library - * Version: 6.1 + * Version: 6.5.3 * - * Copyright (C) 1999-2004 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"), @@ -67,14 +67,14 @@ struct LineInfo GLfloat iPlane[4]; /* DO_SPEC */ GLfloat srPlane[4], sgPlane[4], sbPlane[4]; - /* DO_TEX or DO_MULTITEX */ - GLfloat sPlane[MAX_TEXTURE_COORD_UNITS][4]; - GLfloat tPlane[MAX_TEXTURE_COORD_UNITS][4]; - GLfloat uPlane[MAX_TEXTURE_COORD_UNITS][4]; - GLfloat vPlane[MAX_TEXTURE_COORD_UNITS][4]; - GLfloat lambda[MAX_TEXTURE_COORD_UNITS]; - GLfloat texWidth[MAX_TEXTURE_COORD_UNITS]; - GLfloat texHeight[MAX_TEXTURE_COORD_UNITS]; + /* DO_TEXVAR */ + GLfloat sPlane[FRAG_ATTRIB_MAX][4]; + GLfloat tPlane[FRAG_ATTRIB_MAX][4]; + GLfloat uPlane[FRAG_ATTRIB_MAX][4]; + GLfloat vPlane[FRAG_ATTRIB_MAX][4]; + GLfloat lambda[FRAG_ATTRIB_MAX]; + GLfloat texWidth[FRAG_ATTRIB_MAX]; + GLfloat texHeight[FRAG_ATTRIB_MAX]; SWspan span; }; @@ -499,15 +499,7 @@ segment(GLcontext *ctx, #define DO_Z #define DO_FOG #define DO_RGBA -#define DO_TEX -#include "s_aalinetemp.h" - - -#define NAME(x) aa_multitex_rgba_##x -#define DO_Z -#define DO_FOG -#define DO_RGBA -#define DO_MULTITEX +#define DO_TEXVAR #include "s_aalinetemp.h" @@ -515,7 +507,7 @@ segment(GLcontext *ctx, #define DO_Z #define DO_FOG #define DO_RGBA -#define DO_MULTITEX +#define DO_TEXVAR #define DO_SPEC #include "s_aalinetemp.h" @@ -530,18 +522,15 @@ _swrast_choose_aa_line_function(GLcontext *ctx) if (ctx->Visual.rgbMode) { /* RGBA */ - if (ctx->Texture._EnabledCoordUnits != 0) { - if (ctx->Texture._EnabledCoordUnits > 1) { - /* Multitextured! */ - if (ctx->Light.Model.ColorControl==GL_SEPARATE_SPECULAR_COLOR || - ctx->Fog.ColorSumEnabled) - swrast->Line = aa_multitex_spec_line; - else - swrast->Line = aa_multitex_rgba_line; - } - else { + if (ctx->Texture._EnabledCoordUnits != 0 + || ctx->FragmentProgram._Current) { + + if (ctx->Light.Model.ColorControl==GL_SEPARATE_SPECULAR_COLOR || + ctx->Fog.ColorSumEnabled) + swrast->Line = aa_multitex_spec_line; + else swrast->Line = aa_tex_rgba_line; - } + } else { swrast->Line = aa_rgba_line; diff --git a/src/mesa/swrast/s_aalinetemp.h b/src/mesa/swrast/s_aalinetemp.h index 34c95fc34e..4d33b7dff7 100644 --- a/src/mesa/swrast/s_aalinetemp.h +++ b/src/mesa/swrast/s_aalinetemp.h @@ -1,8 +1,8 @@ /* * Mesa 3-D graphics library - * Version: 6.5 + * Version: 6.5.3 * - * Copyright (C) 1999-2005 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"), @@ -36,6 +36,7 @@ static void NAME(plot)(GLcontext *ctx, struct LineInfo *line, int ix, int iy) { + const SWcontext *swrast = SWRAST_CONTEXT(ctx); const GLfloat fx = (GLfloat) ix; const GLfloat fy = (GLfloat) iy; #ifdef DO_INDEX @@ -45,6 +46,8 @@ NAME(plot)(GLcontext *ctx, struct LineInfo *line, int ix, int iy) #endif const GLuint i = line->span.end; + (void) swrast; + if (coverage == 0.0) return; @@ -61,7 +64,7 @@ NAME(plot)(GLcontext *ctx, struct LineInfo *line, int ix, int iy) line->span.array->z[i] = (GLuint) solve_plane(fx, fy, line->zPlane); #endif #ifdef DO_FOG - line->span.array->fog[i] = solve_plane(fx, fy, line->fPlane); + line->span.array->attribs[FRAG_ATTRIB_FOGC][i][0] = solve_plane(fx, fy, line->fPlane); #endif #ifdef DO_RGBA line->span.array->rgba[i][RCOMP] = solve_plane_chan(fx, fy, line->rPlane); @@ -77,41 +80,29 @@ NAME(plot)(GLcontext *ctx, struct LineInfo *line, int ix, int iy) line->span.array->spec[i][GCOMP] = solve_plane_chan(fx, fy, line->sgPlane); line->span.array->spec[i][BCOMP] = solve_plane_chan(fx, fy, line->sbPlane); #endif -#ifdef DO_TEX - { - GLfloat invQ; - if (ctx->FragmentProgram._Active) { - invQ = 1.0F; - } - else { - invQ = solve_plane_recip(fx, fy, line->vPlane[0]); - } - line->span.array->texcoords[0][i][0] = solve_plane(fx, fy, line->sPlane[0]) * invQ; - line->span.array->texcoords[0][i][1] = solve_plane(fx, fy, line->tPlane[0]) * invQ; - line->span.array->texcoords[0][i][2] = solve_plane(fx, fy, line->uPlane[0]) * invQ; - line->span.array->lambda[0][i] = compute_lambda(line->sPlane[0], - line->tPlane[0], invQ, - line->texWidth[0], - line->texHeight[0]); - } -#elif defined(DO_MULTITEX) +#if defined(DO_TEXVAR) { - GLuint unit; - for (unit = 0; unit < ctx->Const.MaxTextureUnits; unit++) { - if (ctx->Texture.Unit[unit]._ReallyEnabled) { + GLuint attr; + for (attr = swrast->_MinFragmentAttrib; attr < swrast->_MaxFragmentAttrib; attr++) { + if (swrast->_FragmentAttribs & (1 << attr)) { + GLfloat (*attribArray)[4] = line->span.array->attribs[attr]; GLfloat invQ; - if (ctx->FragmentProgram._Active) { + if (ctx->FragmentProgram._Current) { invQ = 1.0F; } else { - invQ = solve_plane_recip(fx, fy, line->vPlane[unit]); + invQ = solve_plane_recip(fx, fy, line->vPlane[attr]); + } + attribArray[i][0] = solve_plane(fx, fy, line->sPlane[attr]) * invQ; + attribArray[i][1] = solve_plane(fx, fy, line->tPlane[attr]) * invQ; + attribArray[i][2] = solve_plane(fx, fy, line->uPlane[attr]) * invQ; + if (attr < FRAG_ATTRIB_VAR0) { + const GLuint unit = attr - FRAG_ATTRIB_TEX0; + line->span.array->lambda[unit][i] + = compute_lambda(line->sPlane[attr], + line->tPlane[attr], invQ, + line->texWidth[attr], line->texHeight[attr]); } - line->span.array->texcoords[unit][i][0] = solve_plane(fx, fy, line->sPlane[unit]) * invQ; - line->span.array->texcoords[unit][i][1] = solve_plane(fx, fy, line->tPlane[unit]) * invQ; - line->span.array->texcoords[unit][i][2] = solve_plane(fx, fy, line->uPlane[unit]) * invQ; - line->span.array->lambda[unit][i] = compute_lambda(line->sPlane[unit], - line->tPlane[unit], invQ, - line->texWidth[unit], line->texHeight[unit]); } } } @@ -214,52 +205,33 @@ NAME(line)(GLcontext *ctx, const SWvertex *v0, const SWvertex *v1) constant_plane(v1->index, line.iPlane); } #endif -#ifdef DO_TEX +#if defined(DO_TEXVAR) { - const struct gl_texture_object *obj = ctx->Texture.Unit[0]._Current; - const struct gl_texture_image *texImage = obj->Image[0][obj->BaseLevel]; + GLuint attr; const GLfloat invW0 = v0->win[3]; const GLfloat invW1 = v1->win[3]; - const GLfloat s0 = v0->texcoord[0][0] * invW0; - const GLfloat s1 = v1->texcoord[0][0] * invW1; - const GLfloat t0 = v0->texcoord[0][1] * invW0; - const GLfloat t1 = v1->texcoord[0][1] * invW1; - const GLfloat r0 = v0->texcoord[0][2] * invW0; - const GLfloat r1 = v1->texcoord[0][2] * invW1; - const GLfloat q0 = v0->texcoord[0][3] * invW0; - const GLfloat q1 = v1->texcoord[0][3] * invW1; - line.span.arrayMask |= (SPAN_TEXTURE | SPAN_LAMBDA); - compute_plane(line.x0, line.y0, line.x1, line.y1, s0, s1, line.sPlane[0]); - compute_plane(line.x0, line.y0, line.x1, line.y1, t0, t1, line.tPlane[0]); - compute_plane(line.x0, line.y0, line.x1, line.y1, r0, r1, line.uPlane[0]); - compute_plane(line.x0, line.y0, line.x1, line.y1, q0, q1, line.vPlane[0]); - line.texWidth[0] = (GLfloat) texImage->Width; - line.texHeight[0] = (GLfloat) texImage->Height; - } -#elif defined(DO_MULTITEX) - { - GLuint u; - line.span.arrayMask |= (SPAN_TEXTURE | SPAN_LAMBDA); - for (u = 0; u < ctx->Const.MaxTextureUnits; u++) { - if (ctx->Texture.Unit[u]._ReallyEnabled) { - const struct gl_texture_object *obj = ctx->Texture.Unit[u]._Current; - const struct gl_texture_image *texImage = obj->Image[0][obj->BaseLevel]; - const GLfloat invW0 = v0->win[3]; - const GLfloat invW1 = v1->win[3]; - const GLfloat s0 = v0->texcoord[u][0] * invW0; - const GLfloat s1 = v1->texcoord[u][0] * invW1; - const GLfloat t0 = v0->texcoord[u][1] * invW0; - const GLfloat t1 = v1->texcoord[u][1] * invW1; - const GLfloat r0 = v0->texcoord[u][2] * invW0; - const GLfloat r1 = v1->texcoord[u][2] * invW1; - const GLfloat q0 = v0->texcoord[u][3] * invW0; - const GLfloat q1 = v1->texcoord[u][3] * invW1; - compute_plane(line.x0, line.y0, line.x1, line.y1, s0, s1, line.sPlane[u]); - compute_plane(line.x0, line.y0, line.x1, line.y1, t0, t1, line.tPlane[u]); - compute_plane(line.x0, line.y0, line.x1, line.y1, r0, r1, line.uPlane[u]); - compute_plane(line.x0, line.y0, line.x1, line.y1, q0, q1, line.vPlane[u]); - line.texWidth[u] = (GLfloat) texImage->Width; - line.texHeight[u] = (GLfloat) texImage->Height; + line.span.arrayMask |= (SPAN_TEXTURE | SPAN_LAMBDA | SPAN_VARYING); + for (attr = swrast->_MinFragmentAttrib; attr < swrast->_MaxFragmentAttrib; attr++) { + if (swrast->_FragmentAttribs & (1 << attr)) { + const GLfloat s0 = v0->attrib[attr][0] * invW0; + const GLfloat s1 = v1->attrib[attr][0] * invW1; + const GLfloat t0 = v0->attrib[attr][1] * invW0; + const GLfloat t1 = v1->attrib[attr][1] * invW1; + const GLfloat r0 = v0->attrib[attr][2] * invW0; + const GLfloat r1 = v1->attrib[attr][2] * invW1; + const GLfloat q0 = v0->attrib[attr][3] * invW0; + const GLfloat q1 = v1->attrib[attr][3] * invW1; + compute_plane(line.x0, line.y0, line.x1, line.y1, s0, s1, line.sPlane[attr]); + compute_plane(line.x0, line.y0, line.x1, line.y1, t0, t1, line.tPlane[attr]); + compute_plane(line.x0, line.y0, line.x1, line.y1, r0, r1, line.uPlane[attr]); + compute_plane(line.x0, line.y0, line.x1, line.y1, q0, q1, line.vPlane[attr]); + if (attr < FRAG_ATTRIB_VAR0) { + const GLuint u = attr - FRAG_ATTRIB_TEX0; + const struct gl_texture_object *obj = ctx->Texture.Unit[u]._Current; + const struct gl_texture_image *texImage = obj->Image[0][obj->BaseLevel]; + line.texWidth[attr] = (GLfloat) texImage->Width; + line.texHeight[attr] = (GLfloat) texImage->Height; + } } } } @@ -324,6 +296,5 @@ NAME(line)(GLcontext *ctx, const SWvertex *v0, const SWvertex *v1) #undef DO_RGBA #undef DO_INDEX #undef DO_SPEC -#undef DO_TEX -#undef DO_MULTITEX +#undef DO_TEXVAR #undef NAME diff --git a/src/mesa/swrast/s_aatriangle.c b/src/mesa/swrast/s_aatriangle.c index 63a13cf3fb..5e3059af93 100644 --- a/src/mesa/swrast/s_aatriangle.c +++ b/src/mesa/swrast/s_aatriangle.c @@ -1,8 +1,8 @@ /* * Mesa 3-D graphics library - * Version: 6.3 + * Version: 6.5.3 * - * Copyright (C) 1999-2004 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"), @@ -408,7 +408,7 @@ tex_aa_tri(GLcontext *ctx, #define DO_Z #define DO_FOG #define DO_RGBA -#define DO_TEX +#define DO_TEXVAR #include "s_aatritemp.h" } @@ -422,39 +422,12 @@ spec_tex_aa_tri(GLcontext *ctx, #define DO_Z #define DO_FOG #define DO_RGBA -#define DO_TEX +#define DO_TEXVAR #define DO_SPEC #include "s_aatritemp.h" } -static void -multitex_aa_tri(GLcontext *ctx, - const SWvertex *v0, - const SWvertex *v1, - const SWvertex *v2) -{ -#define DO_Z -#define DO_FOG -#define DO_RGBA -#define DO_MULTITEX -#include "s_aatritemp.h" -} - -static void -spec_multitex_aa_tri(GLcontext *ctx, - const SWvertex *v0, - const SWvertex *v1, - const SWvertex *v2) -{ -#define DO_Z -#define DO_FOG -#define DO_RGBA -#define DO_MULTITEX -#define DO_SPEC -#include "s_aatritemp.h" -} - /* * Examine GL state and set swrast->Triangle to an @@ -465,22 +438,13 @@ _swrast_set_aa_triangle_function(GLcontext *ctx) { ASSERT(ctx->Polygon.SmoothFlag); - if (ctx->Texture._EnabledCoordUnits != 0) { + if (ctx->Texture._EnabledCoordUnits != 0 + || ctx->FragmentProgram._Current) { if (NEED_SECONDARY_COLOR(ctx)) { - if (ctx->Texture._EnabledCoordUnits > 1) { - SWRAST_CONTEXT(ctx)->Triangle = spec_multitex_aa_tri; - } - else { - SWRAST_CONTEXT(ctx)->Triangle = spec_tex_aa_tri; - } + SWRAST_CONTEXT(ctx)->Triangle = spec_tex_aa_tri; } else { - if (ctx->Texture._EnabledCoordUnits > 1) { - SWRAST_CONTEXT(ctx)->Triangle = multitex_aa_tri; - } - else { - SWRAST_CONTEXT(ctx)->Triangle = tex_aa_tri; - } + SWRAST_CONTEXT(ctx)->Triangle = tex_aa_tri; } } else if (ctx->Visual.rgbMode) { diff --git a/src/mesa/swrast/s_aatritemp.h b/src/mesa/swrast/s_aatritemp.h index b5470a0298..bbf9cc611d 100644 --- a/src/mesa/swrast/s_aatritemp.h +++ b/src/mesa/swrast/s_aatritemp.h @@ -1,8 +1,8 @@ /* * Mesa 3-D graphics library - * Version: 6.5 + * Version: 6.5.3 * - * Copyright (C) 1999-2005 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"), @@ -36,12 +36,12 @@ * DO_RGBA - if defined, compute RGBA values * DO_INDEX - if defined, compute color index values * DO_SPEC - if defined, compute specular RGB values - * DO_TEX - if defined, compute unit 0 STRQ texcoords - * DO_MULTITEX - if defined, compute all unit's STRQ texcoords + * DO_TEXVAR - if defined, compute texcoords, varying */ /*void triangle( GLcontext *ctx, GLuint v0, GLuint v1, GLuint v2, GLuint pv )*/ { + const SWcontext *swrast = SWRAST_CONTEXT(ctx); const GLfloat *p0 = v0->win; const GLfloat *p1 = v1->win; const GLfloat *p2 = v2->win; @@ -70,20 +70,18 @@ #ifdef DO_SPEC GLfloat srPlane[4], sgPlane[4], sbPlane[4]; #endif -#ifdef DO_TEX - GLfloat sPlane[4], tPlane[4], uPlane[4], vPlane[4]; - GLfloat texWidth, texHeight; -#elif defined(DO_MULTITEX) - GLfloat sPlane[MAX_TEXTURE_COORD_UNITS][4]; /* texture S */ - GLfloat tPlane[MAX_TEXTURE_COORD_UNITS][4]; /* texture T */ - GLfloat uPlane[MAX_TEXTURE_COORD_UNITS][4]; /* texture R */ - GLfloat vPlane[MAX_TEXTURE_COORD_UNITS][4]; /* texture Q */ - GLfloat texWidth[MAX_TEXTURE_COORD_UNITS]; - GLfloat texHeight[MAX_TEXTURE_COORD_UNITS]; +#if defined(DO_TEXVAR) + GLfloat sPlane[FRAG_ATTRIB_MAX][4]; /* texture S */ + GLfloat tPlane[FRAG_ATTRIB_MAX][4]; /* texture T */ + GLfloat uPlane[FRAG_ATTRIB_MAX][4]; /* texture R */ + GLfloat vPlane[FRAG_ATTRIB_MAX][4]; /* texture Q */ + GLfloat texWidth[FRAG_ATTRIB_MAX]; + GLfloat texHeight[FRAG_ATTRIB_MAX]; #endif GLfloat bf = SWRAST_CONTEXT(ctx)->_BackfaceSign; - + (void) swrast; + INIT_SPAN(span, GL_POLYGON, 0, 0, SPAN_COVERAGE); /* determine bottom to top order of vertices */ @@ -179,65 +177,44 @@ } span.arrayMask |= SPAN_SPEC; #endif -#ifdef DO_TEX +#if defined(DO_TEXVAR) { - const struct gl_texture_object *obj = ctx->Texture.Unit[0]._Current; - const struct gl_texture_image *texImage = obj->Image[0][obj->BaseLevel]; + GLuint attr; const GLfloat invW0 = v0->win[3]; const GLfloat invW1 = v1->win[3]; const GLfloat invW2 = v2->win[3]; - const GLfloat s0 = v0->texcoord[0][0] * invW0; - const GLfloat s1 = v1->texcoord[0][0] * invW1; - const GLfloat s2 = v2->texcoord[0][0] * invW2; - const GLfloat t0 = v0->texcoord[0][1] * invW0; - const GLfloat t1 = v1->texcoord[0][1] * invW1; - const GLfloat t2 = v2->texcoord[0][1] * invW2; - const GLfloat r0 = v0->texcoord[0][2] * invW0; - const GLfloat r1 = v1->texcoord[0][2] * invW1; - const GLfloat r2 = v2->texcoord[0][2] * invW2; - const GLfloat q0 = v0->texcoord[0][3] * invW0; - const GLfloat q1 = v1->texcoord[0][3] * invW1; - const GLfloat q2 = v2->texcoord[0][3] * invW2; - compute_plane(p0, p1, p2, s0, s1, s2, sPlane); - compute_plane(p0, p1, p2, t0, t1, t2, tPlane); - compute_plane(p0, p1, p2, r0, r1, r2, uPlane); - compute_plane(p0, p1, p2, q0, q1, q2, vPlane); - texWidth = (GLfloat) texImage->Width; - texHeight = (GLfloat) texImage->Height; - } - span.arrayMask |= (SPAN_TEXTURE | SPAN_LAMBDA); -#elif defined(DO_MULTITEX) - { - GLuint u; - for (u = 0; u < ctx->Const.MaxTextureUnits; u++) { - if (ctx->Texture.Unit[u]._ReallyEnabled) { - const struct gl_texture_object *obj = ctx->Texture.Unit[u]._Current; - const struct gl_texture_image *texImage = obj->Image[0][obj->BaseLevel]; - const GLfloat invW0 = v0->win[3]; - const GLfloat invW1 = v1->win[3]; - const GLfloat invW2 = v2->win[3]; - const GLfloat s0 = v0->texcoord[u][0] * invW0; - const GLfloat s1 = v1->texcoord[u][0] * invW1; - const GLfloat s2 = v2->texcoord[u][0] * invW2; - const GLfloat t0 = v0->texcoord[u][1] * invW0; - const GLfloat t1 = v1->texcoord[u][1] * invW1; - const GLfloat t2 = v2->texcoord[u][1] * invW2; - const GLfloat r0 = v0->texcoord[u][2] * invW0; - const GLfloat r1 = v1->texcoord[u][2] * invW1; - const GLfloat r2 = v2->texcoord[u][2] * invW2; - const GLfloat q0 = v0->texcoord[u][3] * invW0; - const GLfloat q1 = v1->texcoord[u][3] * invW1; - const GLfloat q2 = v2->texcoord[u][3] * invW2; - compute_plane(p0, p1, p2, s0, s1, s2, sPlane[u]); - compute_plane(p0, p1, p2, t0, t1, t2, tPlane[u]); - compute_plane(p0, p1, p2, r0, r1, r2, uPlane[u]); - compute_plane(p0, p1, p2, q0, q1, q2, vPlane[u]); - texWidth[u] = (GLfloat) texImage->Width; - texHeight[u] = (GLfloat) texImage->Height; + for (attr = swrast->_MinFragmentAttrib; attr < swrast->_MaxFragmentAttrib; attr++) { + if (swrast->_FragmentAttribs & (1 << attr)) { + const GLfloat s0 = v0->attrib[attr][0] * invW0; + const GLfloat s1 = v1->attrib[attr][0] * invW1; + const GLfloat s2 = v2->attrib[attr][0] * invW2; + const GLfloat t0 = v0->attrib[attr][1] * invW0; + const GLfloat t1 = v1->attrib[attr][1] * invW1; + const GLfloat t2 = v2->attrib[attr][1] * invW2; + const GLfloat r0 = v0->attrib[attr][2] * invW0; + const GLfloat r1 = v1->attrib[attr][2] * invW1; + const GLfloat r2 = v2->attrib[attr][2] * invW2; + const GLfloat q0 = v0->attrib[attr][3] * invW0; + const GLfloat q1 = v1->attrib[attr][3] * invW1; + const GLfloat q2 = v2->attrib[attr][3] * invW2; + compute_plane(p0, p1, p2, s0, s1, s2, sPlane[attr]); + compute_plane(p0, p1, p2, t0, t1, t2, tPlane[attr]); + compute_plane(p0, p1, p2, r0, r1, r2, uPlane[attr]); + compute_plane(p0, p1, p2, q0, q1, q2, vPlane[attr]); + if (attr < FRAG_ATTRIB_VAR0) { + const GLuint u = attr - FRAG_ATTRIB_TEX0; + const struct gl_texture_object *obj = ctx->Texture.Unit[u]._Current; + const struct gl_texture_image *texImage = obj->Image[0][obj->BaseLevel]; + texWidth[attr] = (GLfloat) texImage->Width; + texHeight[attr] = (GLfloat) texImage->Height; + } + else { + texWidth[attr] = texHeight[attr] = 1.0; + } } } } - span.arrayMask |= (SPAN_TEXTURE | SPAN_LAMBDA); + span.arrayMask |= (SPAN_TEXTURE | SPAN_LAMBDA | SPAN_VARYING); #endif /* Begin bottom-to-top scan over the triangle. @@ -289,7 +266,7 @@ array->z[count] = (GLuint) solve_plane(cx, cy, zPlane); #endif #ifdef DO_FOG - array->fog[count] = solve_plane(cx, cy, fogPlane); + array->attribs[FRAG_ATTRIB_FOGC][count][0] = solve_plane(cx, cy, fogPlane); #endif #ifdef DO_RGBA array->rgba[count][RCOMP] = solve_plane_chan(cx, cy, rPlane); @@ -305,28 +282,21 @@ array->spec[count][GCOMP] = solve_plane_chan(cx, cy, sgPlane); array->spec[count][BCOMP] = solve_plane_chan(cx, cy, sbPlane); #endif -#ifdef DO_TEX +#if defined(DO_TEXVAR) { - const GLfloat invQ = solve_plane_recip(cx, cy, vPlane); - array->texcoords[0][count][0] = solve_plane(cx, cy, sPlane) * invQ; - array->texcoords[0][count][1] = solve_plane(cx, cy, tPlane) * invQ; - array->texcoords[0][count][2] = solve_plane(cx, cy, uPlane) * invQ; - array->lambda[0][count] = compute_lambda(sPlane, tPlane, vPlane, - cx, cy, invQ, - texWidth, texHeight); - } -#elif defined(DO_MULTITEX) - { - GLuint unit; - for (unit = 0; unit < ctx->Const.MaxTextureUnits; unit++) { - if (ctx->Texture.Unit[unit]._ReallyEnabled) { - GLfloat invQ = solve_plane_recip(cx, cy, vPlane[unit]); - array->texcoords[unit][count][0] = solve_plane(cx, cy, sPlane[unit]) * invQ; - array->texcoords[unit][count][1] = solve_plane(cx, cy, tPlane[unit]) * invQ; - array->texcoords[unit][count][2] = solve_plane(cx, cy, uPlane[unit]) * invQ; - array->lambda[unit][count] = compute_lambda(sPlane[unit], - tPlane[unit], vPlane[unit], cx, cy, invQ, - texWidth[unit], texHeight[unit]); + GLuint attr; + for (attr = swrast->_MinFragmentAttrib; attr < swrast->_MaxFragmentAttrib; attr++) { + if (swrast->_FragmentAttribs & (1 << attr)) { + GLfloat invQ = solve_plane_recip(cx, cy, vPlane[attr]); + array->attribs[attr][count][0] = solve_plane(cx, cy, sPlane[attr]) * invQ; + array->attribs[attr][count][1] = solve_plane(cx, cy, tPlane[attr]) * invQ; + array->attribs[attr][count][2] = solve_plane(cx, cy, uPlane[attr]) * invQ; + if (attr < FRAG_ATTRIB_VAR0) { + const GLuint unit = attr - FRAG_ATTRIB_TEX0; + array->lambda[unit][count] = compute_lambda(sPlane[attr], tPlane[attr], + vPlane[attr], cx, cy, invQ, + texWidth[attr], texHeight[attr]); + } } } } @@ -393,7 +363,7 @@ array->z[ix] = (GLuint) solve_plane(cx, cy, zPlane); #endif #ifdef DO_FOG - array->fog[ix] = solve_plane(cx, cy, fogPlane); + array->attribs[FRAG_ATTRIB_FOGC][ix][0] = solve_plane(cx, cy, fogPlane); #endif #ifdef DO_RGBA array->rgba[ix][RCOMP] = solve_plane_chan(cx, cy, rPlane); @@ -409,30 +379,24 @@ array->spec[ix][GCOMP] = solve_plane_chan(cx, cy, sgPlane); array->spec[ix][BCOMP] = solve_plane_chan(cx, cy, sbPlane); #endif -#ifdef DO_TEX - { - const GLfloat invQ = solve_plane_recip(cx, cy, vPlane); - array->texcoords[0][ix][0] = solve_plane(cx, cy, sPlane) * invQ; - array->texcoords[0][ix][1] = solve_plane(cx, cy, tPlane) * invQ; - array->texcoords[0][ix][2] = solve_plane(cx, cy, uPlane) * invQ; - array->lambda[0][ix] = compute_lambda(sPlane, tPlane, vPlane, - cx, cy, invQ, texWidth, texHeight); - } -#elif defined(DO_MULTITEX) +#if defined(DO_TEXVAR) { - GLuint unit; - for (unit = 0; unit < ctx->Const.MaxTextureUnits; unit++) { - if (ctx->Texture.Unit[unit]._ReallyEnabled) { - GLfloat invQ = solve_plane_recip(cx, cy, vPlane[unit]); - array->texcoords[unit][ix][0] = solve_plane(cx, cy, sPlane[unit]) * invQ; - array->texcoords[unit][ix][1] = solve_plane(cx, cy, tPlane[unit]) * invQ; - array->texcoords[unit][ix][2] = solve_plane(cx, cy, uPlane[unit]) * invQ; - array->lambda[unit][ix] = compute_lambda(sPlane[unit], - tPlane[unit], - vPlane[unit], - cx, cy, invQ, - texWidth[unit], - texHeight[unit]); + GLuint attr; + for (attr = swrast->_MinFragmentAttrib; attr < swrast->_MaxFragmentAttrib; attr++) { + if (swrast->_FragmentAttribs & (1 << attr)) { + GLfloat invQ = solve_plane_recip(cx, cy, vPlane[attr]); + array->attribs[attr][ix][0] = solve_plane(cx, cy, sPlane[attr]) * invQ; + array->attribs[attr][ix][1] = solve_plane(cx, cy, tPlane[attr]) * invQ; + array->attribs[attr][ix][2] = solve_plane(cx, cy, uPlane[attr]) * invQ; + if (attr < FRAG_ATTRIB_VAR0) { + const GLuint unit = attr - FRAG_ATTRIB_TEX0; + array->lambda[unit][ix] = compute_lambda(sPlane[attr], + tPlane[attr], + vPlane[attr], + cx, cy, invQ, + texWidth[attr], + texHeight[attr]); + } } } } @@ -468,30 +432,28 @@ array->z[j] = array->z[j + left]; #endif #ifdef DO_FOG - array->fog[j] = array->fog[j + left]; + array->attribs[FRAG_ATTRIB_FOGC][j][0] + = array->attribs[FRAG_ATTRIB_FOGC][j + left][0]; #endif -#ifdef DO_TEX - COPY_4V(array->texcoords[0][j], array->texcoords[0][j + left]); -#endif -#if defined(DO_MULTITEX) || defined(DO_TEX) +#if defined(DO_TEXVAR) array->lambda[0][j] = array->lambda[0][j + left]; #endif array->coverage[j] = array->coverage[j + left]; } } -#ifdef DO_MULTITEX - /* shift texcoords */ +#ifdef DO_TEXVAR + /* shift texcoords, varying */ { SWspanarrays *array = span.array; - GLuint unit; - for (unit = 0; unit < ctx->Const.MaxTextureUnits; unit++) { - if (ctx->Texture.Unit[unit]._ReallyEnabled) { + GLuint attr; + for (attr = swrast->_MinFragmentAttrib; attr < swrast->_MaxFragmentAttrib; attr++) { + if (swrast->_FragmentAttribs & (1 << attr)) { GLint j; for (j = 0; j < (GLint) n; j++) { - array->texcoords[unit][j][0] = array->texcoords[unit][j + left][0]; - array->texcoords[unit][j][1] = array->texcoords[unit][j + left][1]; - array->texcoords[unit][j][2] = array->texcoords[unit][j + left][2]; - array->lambda[unit][j] = array->lambda[unit][j + left]; + array->attribs[attr][j][0] = array->attribs[attr][j + left][0]; + array->attribs[attr][j][1] = array->attribs[attr][j + left][1]; + array->attribs[attr][j][2] = array->attribs[attr][j + left][2]; + /*array->lambda[unit][j] = array->lambda[unit][j + left];*/ } } } @@ -532,12 +494,8 @@ #undef DO_SPEC #endif -#ifdef DO_TEX -#undef DO_TEX -#endif - -#ifdef DO_MULTITEX -#undef DO_MULTITEX +#ifdef DO_TEXVAR +#undef DO_TEXVAR #endif #ifdef DO_OCCLUSION_TEST diff --git a/src/mesa/swrast/s_alpha.c b/src/mesa/swrast/s_alpha.c index 87a016512c..af8a6baddc 100644 --- a/src/mesa/swrast/s_alpha.c +++ b/src/mesa/swrast/s_alpha.c @@ -123,7 +123,7 @@ _swrast_alpha_test(const GLcontext *ctx, SWspan *span) ALPHA_TEST(rgba[i][ACOMP], ;); } else { - GLfloat (*rgba)[4] = span->array->color.sz4.rgba; + GLfloat (*rgba)[4] = span->array->attribs[FRAG_ATTRIB_COL0]; const GLfloat ref = ctx->Color.AlphaRef; ALPHA_TEST(rgba[i][ACOMP], ;); } diff --git a/src/mesa/swrast/s_arbshader.c b/src/mesa/swrast/s_arbshader.c deleted file mode 100644 index 356e43c819..0000000000 --- a/src/mesa/swrast/s_arbshader.c +++ /dev/null @@ -1,126 +0,0 @@ -/* - * Mesa 3-D graphics library - * Version: 6.5.3 - * - * Copyright (C) 2006 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. - * - * Authors: - * Michal Krol - */ - -#include "glheader.h" -#include "context.h" -#include "colormac.h" -#include "s_arbshader.h" -#include "s_context.h" -#include "shaderobjects.h" -#include "shaderobjects_3dlabs.h" -#include "slang_utility.h" -#include "slang_link.h" - -#if FEATURE_ARB_fragment_shader - -void -_swrast_exec_arbshader(GLcontext *ctx, SWspan *span) -{ - struct gl2_program_intf **pro; - GLuint i; - - ASSERT(span->array->ChanType == GL_FLOAT); - - if (!ctx->ShaderObjects._FragmentShaderPresent) - return; - - pro = ctx->ShaderObjects.CurrentProgram; - if (!ctx->ShaderObjects._VertexShaderPresent) - (**pro).UpdateFixedUniforms(pro); - - for (i = span->start; i < span->end; i++) { - /* only run shader on active fragments */ - if (span->array->mask[i]) { - GLfloat vec[4]; - GLuint j; - GLboolean discard; - - /* - * Load input attributes - */ - vec[0] = (GLfloat) span->x + i; - vec[1] = (GLfloat) span->y; - vec[2] = (GLfloat) span->array->z[i] / ctx->DrawBuffer->_DepthMaxF; - vec[3] = span->w + span->dwdx * i; - (**pro).UpdateFixedVarying(pro, SLANG_FRAGMENT_FIXED_FRAGCOORD, vec, - 0, 4 * sizeof(GLfloat), GL_TRUE); - - (**pro).UpdateFixedVarying(pro, SLANG_FRAGMENT_FIXED_COLOR, - span->array->color.sz4.rgba[i], - 0, 4 * sizeof(GLfloat), GL_TRUE); - - (**pro).UpdateFixedVarying(pro, SLANG_FRAGMENT_FIXED_SECONDARYCOLOR, - span->array->color.sz4.spec[i], - 0, 4 * sizeof(GLfloat), GL_TRUE); - - for (j = 0; j < ctx->Const.MaxTextureCoordUnits; j++) { - (**pro).UpdateFixedVarying(pro, SLANG_FRAGMENT_FIXED_TEXCOORD, - span->array->texcoords[j][i], - j, 4 * sizeof(GLfloat), GL_TRUE); - } - - for (j = 0; j < MAX_VARYING_VECTORS; j++) { - GLuint k; - for (k = 0; k < VARYINGS_PER_VECTOR; k++) { - (**pro).UpdateVarying(pro, j * VARYINGS_PER_VECTOR + k, - &span->array->varying[i][j][k], - GL_FALSE); - } - } - - _slang_exec_fragment_shader(pro); - - /* - * Store results - */ - _slang_fetch_discard(pro, &discard); - if (discard) { - span->array->mask[i] = GL_FALSE; - span->writeAll = GL_FALSE; - } - else { - GLboolean zWritten = GL_FALSE; /* temp hack (bug 9345) */ - (**pro).UpdateFixedVarying(pro, SLANG_FRAGMENT_FIXED_FRAGCOLOR, - vec, 0, 4 * sizeof(GLfloat), GL_FALSE); - COPY_4V(span->array->color.sz4.rgba[i], vec); - if (zWritten) { - (**pro).UpdateFixedVarying(pro, SLANG_FRAGMENT_FIXED_FRAGDEPTH, - vec, 0, sizeof (GLfloat), GL_FALSE); - if (vec[0] <= 0.0f) - span->array->z[i] = 0; - else if (vec[0] >= 1.0f) - span->array->z[i] = ctx->DrawBuffer->_DepthMax; - else - span->array->z[i] = IROUND(vec[0] * ctx->DrawBuffer->_DepthMaxF); - } - } - } - } -} - -#endif /* FEATURE_ARB_fragment_shader */ - diff --git a/src/mesa/swrast/s_atifragshader.c b/src/mesa/swrast/s_atifragshader.c index 467b8652d8..947054faa3 100644 --- a/src/mesa/swrast/s_atifragshader.c +++ b/src/mesa/swrast/s_atifragshader.c @@ -268,7 +268,7 @@ handle_pass_op(struct atifs_machine *machine, struct atifs_setupinst *texinst, if (pass_tex >= GL_TEXTURE0_ARB && pass_tex <= GL_TEXTURE7_ARB) { pass_tex -= GL_TEXTURE0_ARB; COPY_4V(machine->Registers[idx], - span->array->texcoords[pass_tex][column]); + span->array->attribs[FRAG_ATTRIB_TEX0 + pass_tex][column]); } else if (pass_tex >= GL_REG_0_ATI && pass_tex <= GL_REG_5_ATI) { pass_tex -= GL_REG_0_ATI; @@ -290,7 +290,8 @@ handle_sample_op(GLcontext * ctx, struct atifs_machine *machine, if (coord_source >= GL_TEXTURE0_ARB && coord_source <= GL_TEXTURE7_ARB) { coord_source -= GL_TEXTURE0_ARB; - COPY_4V(tex_coords, span->array->texcoords[coord_source][column]); + COPY_4V(tex_coords, + span->array->attribs[FRAG_ATTRIB_TEX0 + coord_source][column]); } else if (coord_source >= GL_REG_0_ATI && coord_source <= GL_REG_5_ATI) { coord_source -= GL_REG_0_ATI; @@ -573,8 +574,8 @@ init_machine(GLcontext * ctx, struct atifs_machine *machine, machine->Registers[i][j] = 0.0; } - COPY_4V(inputs[ATI_FS_INPUT_PRIMARY], span->array->color.sz4.rgba[col]); - COPY_4V(inputs[ATI_FS_INPUT_SECONDARY], span->array->color.sz4.spec[col]); + COPY_4V(inputs[ATI_FS_INPUT_PRIMARY], span->array->attribs[FRAG_ATTRIB_COL0][col]); + COPY_4V(inputs[ATI_FS_INPUT_SECONDARY], span->array->attribs[FRAG_ATTRIB_COL1][col]); } @@ -605,7 +606,7 @@ _swrast_exec_fragment_shader(GLcontext * ctx, SWspan *span) const GLfloat *colOut = machine.Registers[0]; /*fprintf(stderr,"outputs %f %f %f %f\n", colOut[0], colOut[1], colOut[2], colOut[3]); */ - COPY_4V(span->array->color.sz4.rgba[i], colOut); + COPY_4V(span->array->attribs[FRAG_ATTRIB_COL0][i], colOut); } } } diff --git a/src/mesa/swrast/s_context.c b/src/mesa/swrast/s_context.c index f5f04b05f5..00702b4301 100644 --- a/src/mesa/swrast/s_context.c +++ b/src/mesa/swrast/s_context.c @@ -2,7 +2,7 @@ * Mesa 3-D graphics library * 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"), @@ -31,7 +31,7 @@ #include "context.h" #include "colormac.h" #include "mtypes.h" -#include "program.h" +#include "prog_statevars.h" #include "teximage.h" #include "swrast.h" #include "s_blend.h" @@ -98,11 +98,7 @@ _swrast_update_rasterflags( GLcontext *ctx ) rasterMask |= MULTI_DRAW_BIT; /* all color index bits disabled */ } - if (ctx->FragmentProgram._Enabled) { - rasterMask |= FRAGPROG_BIT; - } - - if (ctx->ShaderObjects._FragmentShaderPresent) { + if (ctx->FragmentProgram._Current) { rasterMask |= FRAGPROG_BIT; } @@ -129,27 +125,28 @@ _swrast_update_rasterflags( GLcontext *ctx ) static void _swrast_update_polygon( GLcontext *ctx ) { - GLfloat backface_sign = 1; + GLfloat backface_sign; if (ctx->Polygon.CullFlag) { - backface_sign = 1; - switch(ctx->Polygon.CullFaceMode) { + backface_sign = 1.0; + switch (ctx->Polygon.CullFaceMode) { case GL_BACK: - if(ctx->Polygon.FrontFace==GL_CCW) - backface_sign = -1; + if (ctx->Polygon.FrontFace == GL_CCW) + backface_sign = -1.0; break; case GL_FRONT: - if(ctx->Polygon.FrontFace!=GL_CCW) - backface_sign = -1; + if (ctx->Polygon.FrontFace != GL_CCW) + backface_sign = -1.0; break; - default: case GL_FRONT_AND_BACK: - backface_sign = 0; + /* fallthrough */ + default: + backface_sign = 0.0; break; } } else { - backface_sign = 0; + backface_sign = 0.0; } SWRAST_CONTEXT(ctx)->_BackfaceSign = backface_sign; @@ -165,7 +162,7 @@ _swrast_update_fog_hint( GLcontext *ctx ) { SWcontext *swrast = SWRAST_CONTEXT(ctx); swrast->_PreferPixelFog = (!swrast->AllowVertexFog || - ctx->FragmentProgram._Enabled || /* not _Active! */ + ctx->FragmentProgram._Current || (ctx->Hint.Fog == GL_NICEST && swrast->AllowPixelFog)); } @@ -198,20 +195,14 @@ static void _swrast_update_fog_state( GLcontext *ctx ) { SWcontext *swrast = SWRAST_CONTEXT(ctx); + const struct gl_fragment_program *fp = ctx->FragmentProgram._Current; /* determine if fog is needed, and if so, which fog mode */ swrast->_FogEnabled = GL_FALSE; - if (ctx->ShaderObjects._FragmentShaderPresent) { - swrast->_FogEnabled = GL_FALSE; - } - else if (ctx->FragmentProgram._Enabled) { - if (ctx->FragmentProgram._Current->Base.Target==GL_FRAGMENT_PROGRAM_ARB) { - const struct gl_fragment_program *fp - = ctx->FragmentProgram._Current; - if (fp->FogOption != GL_NONE) { - swrast->_FogEnabled = GL_TRUE; - swrast->_FogMode = fp->FogOption; - } + if (fp && fp->Base.Target == GL_FRAGMENT_PROGRAM_ARB) { + if (fp->FogOption != GL_NONE) { + swrast->_FogEnabled = GL_TRUE; + swrast->_FogMode = fp->FogOption; } } else if (ctx->Fog.Enabled) { @@ -228,8 +219,8 @@ _swrast_update_fog_state( GLcontext *ctx ) static void _swrast_update_fragment_program(GLcontext *ctx, GLbitfield newState) { - if (ctx->FragmentProgram._Enabled) { - const struct gl_fragment_program *fp = ctx->FragmentProgram._Current; + const struct gl_fragment_program *fp = ctx->FragmentProgram._Current; + if (fp) { #if 0 /* XXX Need a way to trigger the initial loading of parameters * even when there's no recent state changes. @@ -304,7 +295,7 @@ _swrast_validate_triangle( GLcontext *ctx, if (ctx->Texture._EnabledUnits == 0 && NEED_SECONDARY_COLOR(ctx) - && !ctx->FragmentProgram._Enabled) { + && !ctx->FragmentProgram._Current) { /* separate specular color, but no texture */ swrast->SpecTriangle = swrast->Triangle; swrast->Triangle = _swrast_add_spec_terms_triangle; @@ -328,7 +319,7 @@ _swrast_validate_line( GLcontext *ctx, const SWvertex *v0, const SWvertex *v1 ) if (ctx->Texture._EnabledUnits == 0 && NEED_SECONDARY_COLOR(ctx) - && !ctx->FragmentProgram._Enabled) { + && !ctx->FragmentProgram._Current) { swrast->SpecLine = swrast->Line; swrast->Line = _swrast_add_spec_terms_line; } @@ -351,7 +342,7 @@ _swrast_validate_point( GLcontext *ctx, const SWvertex *v0 ) if (ctx->Texture._EnabledUnits == 0 && NEED_SECONDARY_COLOR(ctx) - && !ctx->FragmentProgram._Enabled) { + && !ctx->FragmentProgram._Current) { swrast->SpecPoint = swrast->Point; swrast->Point = _swrast_add_spec_terms_point; } @@ -505,11 +496,96 @@ _swrast_update_texture_samplers(GLcontext *ctx) for (u = 0; u < ctx->Const.MaxTextureImageUnits; u++) { const struct gl_texture_object *tObj = ctx->Texture.Unit[u]._Current; + /* Note: If tObj is NULL, the sample function will be a simple + * function that just returns opaque black (0,0,0,1). + */ swrast->TextureSample[u] = _swrast_choose_texture_sample_func(ctx, tObj); } } +/** + * Update the swrast->_FragmentAttribs field. + */ +static void +_swrast_update_fragment_attribs(GLcontext *ctx) +{ + SWcontext *swrast = SWRAST_CONTEXT(ctx); + + if (ctx->FragmentProgram._Current) { + swrast->_FragmentAttribs + = ctx->FragmentProgram._Current->Base.InputsRead; + } + else { + GLuint u; + swrast->_FragmentAttribs = 0x0; + + if (ctx->Depth.Test) + swrast->_FragmentAttribs |= FRAG_BIT_WPOS; + if (NEED_SECONDARY_COLOR(ctx)) + swrast->_FragmentAttribs |= FRAG_BIT_COL1; + if (swrast->_FogEnabled) + swrast->_FragmentAttribs |= FRAG_BIT_FOGC; + + for (u = 0; u < ctx->Const.MaxTextureUnits; u++) { + if (ctx->Texture.Unit[u]._ReallyEnabled) { + swrast->_FragmentAttribs |= FRAG_BIT_TEX(u); + } + } + } + + /* Find lowest, highest bit set in _FragmentAttribs */ + { + GLuint bits = swrast->_FragmentAttribs; + GLuint i = 0;; + while (bits) { + i++; + bits = bits >> 1; + } + swrast->_MaxFragmentAttrib = i; + swrast->_MinFragmentAttrib = FRAG_ATTRIB_TEX0; /* XXX temporary */ + } +} + + +/** + * Update the swrast->_ColorOutputsMask which indicates which color + * renderbuffers (aka rendertargets) are being written to by the current + * fragment program. + * We also take glDrawBuffers() into account to skip outputs that are + * set to GL_NONE. + */ +static void +_swrast_update_color_outputs(GLcontext *ctx) +{ + SWcontext *swrast = SWRAST_CONTEXT(ctx); + const struct gl_framebuffer *fb = ctx->DrawBuffer; + + swrast->_ColorOutputsMask = 0; + swrast->_NumColorOutputs = 0; + + if (ctx->FragmentProgram._Current) { + const GLbitfield outputsWritten + = ctx->FragmentProgram._Current->Base.OutputsWritten; + GLuint output; + for (output = 0; output < ctx->Const.MaxDrawBuffers; output++) { + if ((outputsWritten & (1 << (FRAG_RESULT_DATA0 + output))) + && (fb->_NumColorDrawBuffers[output] > 0)) { + swrast->_ColorOutputsMask |= (1 << output); + swrast->_NumColorOutputs = output + 1; + } + } + } + if (swrast->_ColorOutputsMask == 0x0) { + /* no fragment program, or frag prog didn't write to gl_FragData[] */ + if (fb->_NumColorDrawBuffers[0] > 0) { + swrast->_ColorOutputsMask = 0x1; + swrast->_NumColorOutputs = 1; + } + } +} + + void _swrast_validate_derived( GLcontext *ctx ) { @@ -550,6 +626,15 @@ _swrast_validate_derived( GLcontext *ctx ) if (swrast->NewState & _SWRAST_NEW_RASTERMASK) _swrast_update_rasterflags( ctx ); + if (swrast->NewState & (_NEW_DEPTH | + _NEW_FOG | + _NEW_PROGRAM | + _NEW_TEXTURE)) + _swrast_update_fragment_attribs(ctx); + + if (swrast->NewState & (_NEW_PROGRAM | _NEW_BUFFERS)) + _swrast_update_color_outputs(ctx); + swrast->NewState = 0; swrast->StateChanges = 0; swrast->InvalidateState = _swrast_invalidate_state; @@ -707,7 +792,6 @@ _swrast_CreateContext( GLcontext *ctx ) /* init point span buffer */ swrast->PointSpan.primitive = GL_POINT; - swrast->PointSpan.start = 0; swrast->PointSpan.end = 0; swrast->PointSpan.facing = 0; swrast->PointSpan.array = swrast->SpanArrays; @@ -810,8 +894,10 @@ _swrast_print_vertex( GLcontext *ctx, const SWvertex *v ) for (i = 0 ; i < ctx->Const.MaxTextureCoordUnits ; i++) if (ctx->Texture.Unit[i]._ReallyEnabled) _mesa_debug(ctx, "texcoord[%d] %f %f %f %f\n", i, - v->texcoord[i][0], v->texcoord[i][1], - v->texcoord[i][2], v->texcoord[i][3]); + v->attrib[FRAG_ATTRIB_TEX0 + i][0], + v->attrib[FRAG_ATTRIB_TEX0 + i][1], + v->attrib[FRAG_ATTRIB_TEX0 + i][2], + v->attrib[FRAG_ATTRIB_TEX0 + i][3]); #if CHAN_TYPE == GL_FLOAT _mesa_debug(ctx, "color %f %f %f %f\n", diff --git a/src/mesa/swrast/s_context.h b/src/mesa/swrast/s_context.h index 37d7081d4d..3a9a48922e 100644 --- a/src/mesa/swrast/s_context.h +++ b/src/mesa/swrast/s_context.h @@ -45,204 +45,7 @@ #include "mtypes.h" #include "swrast.h" - - -/** - * \defgroup SpanFlags SPAN_XXX-flags - * Bitmasks to indicate which sw_span_arrays need to be computed - * (sw_span::interpMask) or have already been filled in (sw_span::arrayMask) - */ -/*@{*/ -#define SPAN_RGBA 0x001 -#define SPAN_SPEC 0x002 -#define SPAN_INDEX 0x004 -#define SPAN_Z 0x008 -#define SPAN_W 0x010 -#define SPAN_FOG 0x020 -#define SPAN_TEXTURE 0x040 -#define SPAN_INT_TEXTURE 0x080 -#define SPAN_LAMBDA 0x100 -#define SPAN_COVERAGE 0x200 -#define SPAN_FLAT 0x400 /**< flat shading? */ -#define SPAN_XY 0x800 -#define SPAN_MASK 0x1000 -#define SPAN_VARYING 0x2000 -/*@}*/ - -#if 0 -/* alternate arrangement for code below */ -struct arrays2 { - union { - GLubyte sz1[MAX_WIDTH][4]; /* primary color */ - GLushort sz2[MAX_WIDTH][4]; - GLfloat sz4[MAX_WIDTH][4]; - } rgba; - union { - GLubyte sz1[MAX_WIDTH][4]; /* specular color and temp storage */ - GLushort sz2[MAX_WIDTH][4]; - GLfloat sz4[MAX_WIDTH][4]; - } spec; -}; -#endif - - -/** - * \sw_span_arrays - * \brief Arrays of fragment values. - * - * These will either be computed from the x/xStep values above or - * filled in by glDraw/CopyPixels, etc. - * These arrays are separated out of sw_span to conserve memory. - */ -typedef struct sw_span_arrays { - GLenum ChanType; /**< Color channel type, GL_UNSIGNED_BYTE, GL_FLOAT */ - union { - struct { - GLubyte rgba[MAX_WIDTH][4]; /**< primary color */ - GLubyte spec[MAX_WIDTH][4]; /**< specular color and temp storage */ - } sz1; - struct { - GLushort rgba[MAX_WIDTH][4]; - GLushort spec[MAX_WIDTH][4]; - } sz2; - struct { - GLfloat rgba[MAX_WIDTH][4]; - GLfloat spec[MAX_WIDTH][4]; - } sz4; - } color; - /** XXX these are temporary fields, pointing into above color arrays */ - GLchan (*rgba)[4]; - GLchan (*spec)[4]; - - GLuint index[MAX_WIDTH]; - GLint x[MAX_WIDTH]; /**< X/Y used for point/line rendering only */ - GLint y[MAX_WIDTH]; /**< X/Y used for point/line rendering only */ - GLuint z[MAX_WIDTH]; - GLfloat fog[MAX_WIDTH]; - GLfloat texcoords[MAX_TEXTURE_COORD_UNITS][MAX_WIDTH][4]; - GLfloat lambda[MAX_TEXTURE_COORD_UNITS][MAX_WIDTH]; - GLfloat coverage[MAX_WIDTH]; - GLfloat varying[MAX_WIDTH][MAX_VARYING_VECTORS][VARYINGS_PER_VECTOR]; - - /** This mask indicates which fragments are alive or culled */ - GLubyte mask[MAX_WIDTH]; -} SWspanarrays; - - -/** - * \SWspan - * \brief Contains data for either a horizontal line or a set of - * pixels that are passed through a pipeline of functions before being - * drawn. - * - * The sw_span structure describes the colors, Z, fogcoord, texcoords, - * etc for either a horizontal run or an array of independent pixels. - * We can either specify a base/step to indicate interpolated values, or - * fill in arrays of values. The interpMask and arrayMask bitfields - * indicate which are active. - * - * With this structure it's easy to hand-off span rasterization to - * subroutines instead of doing it all inline in the triangle functions - * like we used to do. - * It also cleans up the local variable namespace a great deal. - * - * It would be interesting to experiment with multiprocessor rasterization - * with this structure. The triangle rasterizer could simply emit a - * stream of these structures which would be consumed by one or more - * span-processing threads which could run in parallel. - */ -typedef struct sw_span { - GLint x, y; - - /** Only need to process pixels between start <= i < end */ - /** At this time, start is always zero. */ - GLuint start, end; - - /** This flag indicates that mask[] array is effectively filled with ones */ - GLboolean writeAll; - - /** either GL_POLYGON, GL_LINE, GL_POLYGON, GL_BITMAP */ - GLenum primitive; - - /** 0 = front-facing span, 1 = back-facing span (for two-sided stencil) */ - GLuint facing; - - /** - * This bitmask (of \link SpanFlags SPAN_* flags\endlink) indicates - * which of the x/xStep variables are relevant. - */ - GLbitfield interpMask; - - /* For horizontal spans, step is the partial derivative wrt X. - * For lines, step is the delta from one fragment to the next. - */ -#if CHAN_TYPE == GL_FLOAT - GLfloat red, redStep; - GLfloat green, greenStep; - GLfloat blue, blueStep; - GLfloat alpha, alphaStep; - GLfloat specRed, specRedStep; - GLfloat specGreen, specGreenStep; - GLfloat specBlue, specBlueStep; -#else /* CHAN_TYPE == GL_UNSIGNED_BYTE or GL_UNSIGNED_SHORT */ - GLfixed red, redStep; - GLfixed green, greenStep; - GLfixed blue, blueStep; - GLfixed alpha, alphaStep; - GLfixed specRed, specRedStep; - GLfixed specGreen, specGreenStep; - GLfixed specBlue, specBlueStep; -#endif - GLfixed index, indexStep; - GLfixed z, zStep; /* XXX z should probably be GLuint */ - GLfloat fog, fogStep; - GLfloat tex[MAX_TEXTURE_COORD_UNITS][4]; /* s, t, r, q */ - GLfloat texStepX[MAX_TEXTURE_COORD_UNITS][4]; - GLfloat texStepY[MAX_TEXTURE_COORD_UNITS][4]; - GLfixed intTex[2], intTexStep[2]; /* s, t only */ - GLfloat var[MAX_VARYING_VECTORS][VARYINGS_PER_VECTOR]; - GLfloat varStepX[MAX_VARYING_VECTORS][VARYINGS_PER_VECTOR]; - GLfloat varStepY[MAX_VARYING_VECTORS][VARYINGS_PER_VECTOR]; - - /* partial derivatives wrt X and Y. */ - GLfloat dzdx, dzdy; - GLfloat w, dwdx, dwdy; - GLfloat drdx, drdy; - GLfloat dgdx, dgdy; - GLfloat dbdx, dbdy; - GLfloat dadx, dady; - GLfloat dsrdx, dsrdy; - GLfloat dsgdx, dsgdy; - GLfloat dsbdx, dsbdy; - GLfloat dfogdx, dfogdy; - - /** - * This bitmask (of \link SpanFlags SPAN_* flags\endlink) indicates - * which of the fragment arrays in the span_arrays struct are relevant. - */ - GLbitfield arrayMask; - - /** - * We store the arrays of fragment values in a separate struct so - * that we can allocate sw_span structs on the stack without using - * a lot of memory. The span_arrays struct is about 400KB while the - * sw_span struct is only about 512 bytes. - */ - SWspanarrays *array; -} SWspan; - - - -#define INIT_SPAN(S, PRIMITIVE, END, INTERP_MASK, ARRAY_MASK) \ -do { \ - (S).primitive = (PRIMITIVE); \ - (S).interpMask = (INTERP_MASK); \ - (S).arrayMask = (ARRAY_MASK); \ - (S).start = 0; \ - (S).end = (END); \ - (S).facing = 0; \ - (S).array = SWRAST_CONTEXT(ctx)->SpanArrays; \ -} while (0) +#include "s_span.h" typedef void (*texture_sample_func)(GLcontext *ctx, @@ -269,7 +72,8 @@ typedef void (*validate_texture_image_func)(GLcontext *ctx, GLuint face, GLuint level); -/** \defgroup Bitmasks +/** + * \defgroup Bitmasks * Bitmasks to indicate which rasterization options are enabled * (RasterMask) */ @@ -329,6 +133,17 @@ typedef struct GLboolean _FogEnabled; GLenum _FogMode; /* either GL_FOG_MODE or fragment program's fog mode */ + /** Multiple render targets */ + GLbitfield _ColorOutputsMask; + GLuint _NumColorOutputs; + + /** Fragment attributes to compute during rasterization. + * Mask of FRAG_BIT_* flags. + */ + GLbitfield _FragmentAttribs; + GLuint _MinFragmentAttrib; /**< Lowest bit set in _FragmentAttribs */ + GLuint _MaxFragmentAttrib; /**< Highest bit set in _FragmentAttribs + 1 */ + /* Accum buffer temporaries. */ GLboolean _IntegerAccumMode; /**< Storing unscaled integers? */ diff --git a/src/mesa/swrast/s_copypix.c b/src/mesa/swrast/s_copypix.c index b318777072..2051e1f3b7 100644 --- a/src/mesa/swrast/s_copypix.c +++ b/src/mesa/swrast/s_copypix.c @@ -268,7 +268,7 @@ copy_rgba_pixels(GLcontext *ctx, GLint srcx, GLint srcy, ASSERT(width < MAX_WIDTH); for (row = 0; row < height; row++, sy += stepy, dy += stepy) { - GLvoid *rgba = span.array->color.sz4.rgba; + GLvoid *rgba = span.array->attribs[FRAG_ATTRIB_COL0]; /* Get row/span of source pixels */ if (overlapping) { diff --git a/src/mesa/swrast/s_drawpix.c b/src/mesa/swrast/s_drawpix.c index 99ad71143e..50147f329f 100644 --- a/src/mesa/swrast/s_drawpix.c +++ b/src/mesa/swrast/s_drawpix.c @@ -644,7 +644,7 @@ draw_rgba_pixels( GLcontext *ctx, GLint x, GLint y, = _mesa_image_row_stride(unpack, width, format, type); GLint skipPixels = 0; /* use span array for temp color storage */ - GLfloat *rgba = (GLfloat *) span.array->color.sz4.rgba; + GLfloat *rgba = (GLfloat *) span.array->attribs[FRAG_ATTRIB_COL0]; /* if the span is wider than MAX_WIDTH we have to do it in chunks */ while (skipPixels < width) { diff --git a/src/mesa/swrast/s_feedback.c b/src/mesa/swrast/s_feedback.c index 26cb05cd56..5d3fbdfeb6 100644 --- a/src/mesa/swrast/s_feedback.c +++ b/src/mesa/swrast/s_feedback.c @@ -46,10 +46,10 @@ static void feedback_vertex( GLcontext *ctx, const SWvertex *v, const SWvertex *pv ) { - const GLuint texUnit = 0; /* See section 5.3 of 1.2.1 spec */ GLfloat win[4]; GLfloat color[4]; GLfloat tc[4]; + const GLfloat *vtc = v->attrib[FRAG_ATTRIB_TEX0]; win[0] = v->win[0]; win[1] = v->win[1]; @@ -61,16 +61,15 @@ static void feedback_vertex( GLcontext *ctx, color[2] = CHAN_TO_FLOAT(pv->color[2]); color[3] = CHAN_TO_FLOAT(pv->color[3]); - if (v->texcoord[texUnit][3] != 1.0 && - v->texcoord[texUnit][3] != 0.0) { - GLfloat invq = 1.0F / v->texcoord[texUnit][3]; - tc[0] = v->texcoord[texUnit][0] * invq; - tc[1] = v->texcoord[texUnit][1] * invq; - tc[2] = v->texcoord[texUnit][2] * invq; - tc[3] = v->texcoord[texUnit][3]; + if (vtc[3] != 1.0 && vtc[3] != 0.0) { + GLfloat invq = 1.0F / vtc[3]; + tc[0] = vtc[0] * invq; + tc[1] = vtc[1] * invq; + tc[2] = vtc[2] * invq; + tc[3] = vtc[3]; } else { - COPY_4V(tc, v->texcoord[texUnit]); + COPY_4V(tc, vtc); } _mesa_feedback_vertex( ctx, win, color, (GLfloat) v->index, tc ); diff --git a/src/mesa/swrast/s_fog.c b/src/mesa/swrast/s_fog.c index f4c3fe4f2d..433fc4a4d0 100644 --- a/src/mesa/swrast/s_fog.c +++ b/src/mesa/swrast/s_fog.c @@ -72,10 +72,10 @@ _swrast_z_to_fogfactor(GLcontext *ctx, GLfloat z) */ #define FOG_LOOP(TYPE, COMPUTE_F) \ do { \ - const GLfloat fogStep = span->fogStep; \ - GLfloat fogCoord = span->fog; \ - const GLfloat wStep = haveW ? span->dwdx : 0.0F; \ - GLfloat w = haveW ? span->w : 1.0F; \ + const GLfloat fogStep = span->attrStepX[FRAG_ATTRIB_FOGC][0]; \ + GLfloat fogCoord = span->attrStart[FRAG_ATTRIB_FOGC][0]; \ + const GLfloat wStep = haveW ? span->attrStepX[FRAG_ATTRIB_WPOS][3] : 0.0F;\ + GLfloat w = haveW ? span->attrStart[FRAG_ATTRIB_WPOS][3] : 1.0F; \ GLuint i; \ for (i = 0; i < span->end; i++) { \ GLfloat f, oneMinusF; \ @@ -154,7 +154,7 @@ _swrast_fog_rgba_span( const GLcontext *ctx, SWspan *span ) FOG_LOOP(GLushort, COMPUTE_F); } else { - GLfloat (*rgba)[4] = span->array->color.sz4.rgba; + GLfloat (*rgba)[4] = span->array->attribs[FRAG_ATTRIB_COL0]; ASSERT(span->array->ChanType == GL_FLOAT); FOG_LOOP(GLfloat, COMPUTE_F); } @@ -172,7 +172,7 @@ _swrast_fog_rgba_span( const GLcontext *ctx, SWspan *span ) FOG_LOOP(GLushort, COMPUTE_F); } else { - GLfloat (*rgba)[4] = span->array->color.sz4.rgba; + GLfloat (*rgba)[4] = span->array->attribs[FRAG_ATTRIB_COL0]; ASSERT(span->array->ChanType == GL_FLOAT); FOG_LOOP(GLfloat, COMPUTE_F); } @@ -194,7 +194,7 @@ _swrast_fog_rgba_span( const GLcontext *ctx, SWspan *span ) FOG_LOOP(GLushort, COMPUTE_F); } else { - GLfloat (*rgba)[4] = span->array->color.sz4.rgba; + GLfloat (*rgba)[4] = span->array->attribs[FRAG_ATTRIB_COL0]; ASSERT(span->array->ChanType == GL_FLOAT); FOG_LOOP(GLfloat, COMPUTE_F); } @@ -214,7 +214,7 @@ _swrast_fog_rgba_span( const GLcontext *ctx, SWspan *span ) if (span->array->ChanType == GL_UNSIGNED_BYTE) { GLubyte (*rgba)[4] = span->array->color.sz1.rgba; for (i = 0; i < span->end; i++) { - const GLfloat f = span->array->fog[i]; + const GLfloat f = span->array->attribs[FRAG_ATTRIB_FOGC][i][0]; const GLfloat oneMinusF = 1.0F - f; rgba[i][RCOMP] = (GLubyte) (f * rgba[i][RCOMP] + oneMinusF * rFog); rgba[i][GCOMP] = (GLubyte) (f * rgba[i][GCOMP] + oneMinusF * gFog); @@ -224,7 +224,7 @@ _swrast_fog_rgba_span( const GLcontext *ctx, SWspan *span ) else if (span->array->ChanType == GL_UNSIGNED_SHORT) { GLushort (*rgba)[4] = span->array->color.sz2.rgba; for (i = 0; i < span->end; i++) { - const GLfloat f = span->array->fog[i]; + const GLfloat f = span->array->attribs[FRAG_ATTRIB_FOGC][i][0]; const GLfloat oneMinusF = 1.0F - f; rgba[i][RCOMP] = (GLushort) (f * rgba[i][RCOMP] + oneMinusF * rFog); rgba[i][GCOMP] = (GLushort) (f * rgba[i][GCOMP] + oneMinusF * gFog); @@ -232,10 +232,10 @@ _swrast_fog_rgba_span( const GLcontext *ctx, SWspan *span ) } } else { - GLfloat (*rgba)[4] = span->array->color.sz4.rgba; + GLfloat (*rgba)[4] = span->array->attribs[FRAG_ATTRIB_COL0]; ASSERT(span->array->ChanType == GL_FLOAT); for (i = 0; i < span->end; i++) { - const GLfloat f = span->array->fog[i]; + const GLfloat f = span->array->attribs[FRAG_ATTRIB_FOGC][i][0]; const GLfloat oneMinusF = 1.0F - f; rgba[i][RCOMP] = f * rgba[i][RCOMP] + oneMinusF * rFog; rgba[i][GCOMP] = f * rgba[i][GCOMP] + oneMinusF * gFog; @@ -258,7 +258,7 @@ _swrast_fog_rgba_span( const GLcontext *ctx, SWspan *span ) FOG_LOOP(GLushort, COMPUTE_F); } else { - GLfloat (*rgba)[4] = span->array->color.sz4.rgba; + GLfloat (*rgba)[4] = span->array->attribs[FRAG_ATTRIB_COL0]; ASSERT(span->array->ChanType == GL_FLOAT); FOG_LOOP(GLfloat, COMPUTE_F); } @@ -293,10 +293,10 @@ _swrast_fog_ci_span( const GLcontext *ctx, SWspan *span ) const GLfloat fogEnd = ctx->Fog.End; const GLfloat fogScale = (ctx->Fog.Start == ctx->Fog.End) ? 1.0F : 1.0F / (ctx->Fog.End - ctx->Fog.Start); - const GLfloat fogStep = span->fogStep; - GLfloat fogCoord = span->fog; - const GLfloat wStep = haveW ? span->dwdx : 0.0F; - GLfloat w = haveW ? span->w : 1.0F; + const GLfloat fogStep = span->attrStepX[FRAG_ATTRIB_FOGC][0]; + GLfloat fogCoord = span->attrStart[FRAG_ATTRIB_FOGC][0]; + const GLfloat wStep = haveW ? span->attrStepX[FRAG_ATTRIB_WPOS][3] : 0.0F; + GLfloat w = haveW ? span->attrStart[FRAG_ATTRIB_WPOS][3] : 1.0F; GLuint i; for (i = 0; i < span->end; i++) { GLfloat f = (fogEnd - fogCoord / w) * fogScale; @@ -310,10 +310,10 @@ _swrast_fog_ci_span( const GLcontext *ctx, SWspan *span ) case GL_EXP: { const GLfloat density = -ctx->Fog.Density; - const GLfloat fogStep = span->fogStep; - GLfloat fogCoord = span->fog; - const GLfloat wStep = haveW ? span->dwdx : 0.0F; - GLfloat w = haveW ? span->w : 1.0F; + const GLfloat fogStep = span->attrStepX[FRAG_ATTRIB_FOGC][0]; + GLfloat fogCoord = span->attrStart[FRAG_ATTRIB_FOGC][0]; + const GLfloat wStep = haveW ? span->attrStepX[FRAG_ATTRIB_WPOS][3] : 0.0F; + GLfloat w = haveW ? span->attrStart[FRAG_ATTRIB_WPOS][3] : 1.0F; GLuint i; for (i = 0; i < span->end; i++) { GLfloat f = EXPF(density * fogCoord / w); @@ -327,10 +327,10 @@ _swrast_fog_ci_span( const GLcontext *ctx, SWspan *span ) case GL_EXP2: { const GLfloat negDensitySquared = -ctx->Fog.Density * ctx->Fog.Density; - const GLfloat fogStep = span->fogStep; - GLfloat fogCoord = span->fog; - const GLfloat wStep = haveW ? span->dwdx : 0.0F; - GLfloat w = haveW ? span->w : 1.0F; + const GLfloat fogStep = span->attrStepX[FRAG_ATTRIB_FOGC][0]; + GLfloat fogCoord = span->attrStart[FRAG_ATTRIB_FOGC][0]; + const GLfloat wStep = haveW ? span->attrStepX[FRAG_ATTRIB_WPOS][3] : 0.0F; + GLfloat w = haveW ? span->attrStart[FRAG_ATTRIB_WPOS][3] : 1.0F; GLuint i; for (i = 0; i < span->end; i++) { const GLfloat coord = fogCoord / w; @@ -360,7 +360,7 @@ _swrast_fog_ci_span( const GLcontext *ctx, SWspan *span ) */ GLuint i; for (i = 0; i < span->end; i++) { - const GLfloat f = span->array->fog[i]; + const GLfloat f = span->array->attribs[FRAG_ATTRIB_FOGC][i][0]; index[i] = (GLuint) ((GLfloat) index[i] + (1.0F - f) * fogIndex); } } @@ -368,10 +368,10 @@ _swrast_fog_ci_span( const GLcontext *ctx, SWspan *span ) /* The span's fog start/step values are blend factors. * They were previously computed per-vertex. */ - const GLfloat fogStep = span->fogStep; - GLfloat fog = span->fog; - const GLfloat wStep = haveW ? span->dwdx : 0.0F; - GLfloat w = haveW ? span->w : 1.0F; + const GLfloat fogStep = span->attrStepX[FRAG_ATTRIB_FOGC][0]; + GLfloat fog = span->attrStart[FRAG_ATTRIB_FOGC][0]; + const GLfloat wStep = haveW ? span->attrStepX[FRAG_ATTRIB_WPOS][3] : 0.0F; + GLfloat w = haveW ? span->attrStart[FRAG_ATTRIB_WPOS][3] : 1.0F; GLuint i; ASSERT(span->interpMask & SPAN_FOG); for (i = 0; i < span->end; i++) { diff --git a/src/mesa/swrast/s_fragprog.c b/src/mesa/swrast/s_fragprog.c new file mode 100644 index 0000000000..7f7c0d6db5 --- /dev/null +++ b/src/mesa/swrast/s_fragprog.c @@ -0,0 +1,224 @@ +/* + * Mesa 3-D graphics library + * Version: 6.5.2 + * + * Copyright (C) 1999-2006 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 "colormac.h" +#include "context.h" +#include "prog_execute.h" +#include "prog_instruction.h" + +#include "s_fragprog.h" +#include "s_span.h" + + +/** + * Fetch a texel. + */ +static void +fetch_texel( GLcontext *ctx, const GLfloat texcoord[4], GLfloat lambda, + GLuint unit, GLfloat color[4] ) +{ + GLchan rgba[4]; + SWcontext *swrast = SWRAST_CONTEXT(ctx); + + /* XXX use a float-valued TextureSample routine here!!! */ + swrast->TextureSample[unit](ctx, ctx->Texture.Unit[unit]._Current, + 1, (const GLfloat (*)[4]) texcoord, + &lambda, &rgba); + color[0] = CHAN_TO_FLOAT(rgba[0]); + color[1] = CHAN_TO_FLOAT(rgba[1]); + color[2] = CHAN_TO_FLOAT(rgba[2]); + color[3] = CHAN_TO_FLOAT(rgba[3]); +} + + +/** + * Fetch a texel with the given partial derivatives to compute a level + * of detail in the mipmap. + */ +static void +fetch_texel_deriv( GLcontext *ctx, const GLfloat texcoord[4], + const GLfloat texdx[4], const GLfloat texdy[4], + GLuint unit, GLfloat color[4] ) +{ + SWcontext *swrast = SWRAST_CONTEXT(ctx); + const struct gl_texture_object *texObj = ctx->Texture.Unit[unit]._Current; + const struct gl_texture_image *texImg = texObj->Image[0][texObj->BaseLevel]; + const GLfloat texW = (GLfloat) texImg->WidthScale; + const GLfloat texH = (GLfloat) texImg->HeightScale; + GLchan rgba[4]; + + GLfloat lambda = _swrast_compute_lambda(texdx[0], texdy[0], /* ds/dx, ds/dy */ + texdx[1], texdy[1], /* dt/dx, dt/dy */ + texdx[3], texdy[2], /* dq/dx, dq/dy */ + texW, texH, + texcoord[0], texcoord[1], texcoord[3], + 1.0F / texcoord[3]); + + swrast->TextureSample[unit](ctx, ctx->Texture.Unit[unit]._Current, + 1, (const GLfloat (*)[4]) texcoord, + &lambda, &rgba); + color[0] = CHAN_TO_FLOAT(rgba[0]); + color[1] = CHAN_TO_FLOAT(rgba[1]); + color[2] = CHAN_TO_FLOAT(rgba[2]); + color[3] = CHAN_TO_FLOAT(rgba[3]); +} + + +/** + * Initialize the virtual fragment program machine state prior to running + * fragment program on a fragment. This involves initializing the input + * registers, condition codes, etc. + * \param machine the virtual machine state to init + * \param program the fragment program we're about to run + * \param span the span of pixels we'll operate on + * \param col which element (column) of the span we'll operate on + */ +static void +init_machine(GLcontext *ctx, struct gl_program_machine *machine, + const struct gl_fragment_program *program, + const SWspan *span, GLuint col) +{ + GLuint inputsRead = program->Base.InputsRead; + + if (ctx->FragmentProgram.CallbackEnabled) + inputsRead = ~0; + + if (program->Base.Target == GL_FRAGMENT_PROGRAM_NV) { + /* Clear temporary registers (undefined for ARB_f_p) */ + _mesa_bzero(machine->Temporaries, + MAX_PROGRAM_TEMPS * 4 * sizeof(GLfloat)); + } + + /* Setup pointer to input attributes */ + machine->Attribs = span->array->attribs; + + /* Store front/back facing value in register FOGC.Y */ + machine->Attribs[FRAG_ATTRIB_FOGC][col][1] = (GLfloat) ctx->_Facing; + + machine->CurElement = col; + + /* init condition codes */ + machine->CondCodes[0] = COND_EQ; + machine->CondCodes[1] = COND_EQ; + machine->CondCodes[2] = COND_EQ; + machine->CondCodes[3] = COND_EQ; + + /* init call stack */ + machine->StackDepth = 0; + + machine->FetchTexelLod = fetch_texel; + machine->FetchTexelDeriv = fetch_texel_deriv; +} + + +/** + * Run fragment program on the pixels in span from 'start' to 'end' - 1. + */ +static void +run_program(GLcontext *ctx, SWspan *span, GLuint start, GLuint end) +{ + SWcontext *swrast = SWRAST_CONTEXT(ctx); + const struct gl_fragment_program *program = ctx->FragmentProgram._Current; + const GLbitfield outputsWritten = program->Base.OutputsWritten; + struct gl_program_machine machine; + GLuint i; + + for (i = start; i < end; i++) { + if (span->array->mask[i]) { + init_machine(ctx, &machine, program, span, i); + + if (_mesa_execute_program(ctx, &program->Base, &machine)) { + + /* Store result color */ + if (outputsWritten & (1 << FRAG_RESULT_COLR)) { + COPY_4V(span->array->attribs[FRAG_ATTRIB_COL0][i], + machine.Outputs[FRAG_RESULT_COLR]); + } + else { + /* Multiple drawbuffers / render targets + * Note that colors beyond 0 and 1 will overwrite other + * attributes, such as FOGC, TEX0, TEX1, etc. That's OK. + */ + GLuint output; + for (output = 0; output < swrast->_NumColorOutputs; output++) { + if (outputsWritten & (1 << (FRAG_RESULT_DATA0 + output))) { + COPY_4V(span->array->attribs[FRAG_ATTRIB_COL0+output][i], + machine.Outputs[FRAG_RESULT_DATA0 + output]); + } + } + } + + /* Store result depth/z */ + if (outputsWritten & (1 << FRAG_RESULT_DEPR)) { + const GLfloat depth = machine.Outputs[FRAG_RESULT_DEPR][2]; + if (depth <= 0.0) + span->array->z[i] = 0; + else if (depth >= 1.0) + span->array->z[i] = ctx->DrawBuffer->_DepthMax; + else + span->array->z[i] = IROUND(depth * ctx->DrawBuffer->_DepthMaxF); + } + } + else { + /* killed fragment */ + span->array->mask[i] = GL_FALSE; + span->writeAll = GL_FALSE; + } + } + } +} + + +/** + * Execute the current fragment program for all the fragments + * in the given span. + */ +void +_swrast_exec_fragment_program( GLcontext *ctx, SWspan *span ) +{ + const struct gl_fragment_program *program = ctx->FragmentProgram._Current; + + /* incoming colors should be floats */ + if (program->Base.InputsRead & FRAG_BIT_COL0) { + ASSERT(span->array->ChanType == GL_FLOAT); + } + + ctx->_CurrentProgram = GL_FRAGMENT_PROGRAM_ARB; /* or NV, doesn't matter */ + + run_program(ctx, span, 0, span->end); + + if (program->Base.OutputsWritten & (1 << FRAG_RESULT_COLR)) { + span->interpMask &= ~SPAN_RGBA; + span->arrayMask |= SPAN_RGBA; + } + + if (program->Base.OutputsWritten & (1 << FRAG_RESULT_DEPR)) { + span->interpMask &= ~SPAN_Z; + span->arrayMask |= SPAN_Z; + } + + ctx->_CurrentProgram = 0; +} + diff --git a/src/mesa/swrast/s_nvfragprog.h b/src/mesa/swrast/s_fragprog.h index 188bacc3d8..e1b7e67918 100644 --- a/src/mesa/swrast/s_nvfragprog.h +++ b/src/mesa/swrast/s_fragprog.h @@ -1,8 +1,8 @@ /* * Mesa 3-D graphics library - * Version: 6.1 + * Version: 6.5.3 * - * Copyright (C) 1999-2003 Brian Paul All Rights Reserved. + * Copyright (C) 1999-2006 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,15 +23,16 @@ */ -#ifndef S_NVFRAGPROG_H -#define S_NVFRAGPROG_H +#ifndef S_FRAGPROG_H +#define S_FRAGPROG_H #include "s_context.h" extern void -_swrast_exec_fragment_program( GLcontext *ctx, SWspan *span ); +_swrast_exec_fragment_program(GLcontext *ctx, SWspan *span); -#endif +#endif /* S_FRAGPROG_H */ + diff --git a/src/mesa/swrast/s_lines.c b/src/mesa/swrast/s_lines.c index ff507249b0..7b2a52b4ff 100644 --- a/src/mesa/swrast/s_lines.c +++ b/src/mesa/swrast/s_lines.c @@ -198,6 +198,7 @@ draw_wide_line( GLcontext *ctx, SWspan *span, GLboolean xMajor ) #define INTERP_Z #define INTERP_FOG #define INTERP_MULTITEX +#define INTERP_VARYING #define RENDER_SPAN(span) \ if (ctx->Line.StippleFlag) { \ span.arrayMask |= SPAN_MASK; \ @@ -298,10 +299,12 @@ _swrast_choose_line( GLcontext *ctx ) _swrast_choose_aa_line_function(ctx); ASSERT(swrast->Line); } - else if (ctx->Texture._EnabledCoordUnits) { + else if (ctx->Texture._EnabledCoordUnits + || ctx->FragmentProgram._Current) { /* textured lines */ if (ctx->Texture._EnabledCoordUnits > 0x1 - || NEED_SECONDARY_COLOR(ctx)) { + || NEED_SECONDARY_COLOR(ctx) + || ctx->FragmentProgram._Current) { /* multi-texture and/or separate specular color */ USE(multitextured_line); } diff --git a/src/mesa/swrast/s_linetemp.h b/src/mesa/swrast/s_linetemp.h index 8b3918511d..7b66291eb5 100644 --- a/src/mesa/swrast/s_linetemp.h +++ b/src/mesa/swrast/s_linetemp.h @@ -37,6 +37,7 @@ * INTERP_INDEX - if defined, interpolate color index values * INTERP_TEX - if defined, interpolate unit 0 texcoords * INTERP_MULTITEX - if defined, interpolate multi-texcoords + * INTERP_VARYING - if defined, interpolate GLSL varyings * * When one can directly address pixels in the color buffer the following * macros can be defined and used to directly compute pixel addresses during @@ -70,6 +71,7 @@ static void NAME( GLcontext *ctx, const SWvertex *vert0, const SWvertex *vert1 ) { + const SWcontext *swrast = SWRAST_CONTEXT(ctx); SWspan span; GLuint interpFlags = 0; GLint x0 = (GLint) vert0->win[0]; @@ -99,6 +101,8 @@ NAME( GLcontext *ctx, const SWvertex *vert0, const SWvertex *vert1 ) SETUP_CODE #endif + (void) swrast; + /* Cull primitives with malformed coordinates. */ { @@ -276,8 +280,8 @@ NAME( GLcontext *ctx, const SWvertex *vert0, const SWvertex *vert1 ) #endif #ifdef INTERP_FOG interpFlags |= SPAN_FOG; - span.fog = vert0->fog; - span.fogStep = (vert1->fog - vert0->fog) / numPixels; + span.attrStart[FRAG_ATTRIB_FOGC][0] = vert0->fog; + span.attrStepX[FRAG_ATTRIB_FOGC][0] = (vert1->fog - vert0->fog) / numPixels; #endif #ifdef INTERP_TEX interpFlags |= SPAN_TEXTURE; @@ -286,50 +290,50 @@ NAME( GLcontext *ctx, const SWvertex *vert0, const SWvertex *vert1 ) const GLfloat invw1 = vert1->win[3]; const GLfloat invLen = 1.0F / numPixels; GLfloat ds, dt, dr, dq; - span.tex[0][0] = invw0 * vert0->texcoord[0][0]; - span.tex[0][1] = invw0 * vert0->texcoord[0][1]; - span.tex[0][2] = invw0 * vert0->texcoord[0][2]; - span.tex[0][3] = invw0 * vert0->texcoord[0][3]; - ds = (invw1 * vert1->texcoord[0][0]) - span.tex[0][0]; - dt = (invw1 * vert1->texcoord[0][1]) - span.tex[0][1]; - dr = (invw1 * vert1->texcoord[0][2]) - span.tex[0][2]; - dq = (invw1 * vert1->texcoord[0][3]) - span.tex[0][3]; - span.texStepX[0][0] = ds * invLen; - span.texStepX[0][1] = dt * invLen; - span.texStepX[0][2] = dr * invLen; - span.texStepX[0][3] = dq * invLen; - span.texStepY[0][0] = 0.0F; - span.texStepY[0][1] = 0.0F; - span.texStepY[0][2] = 0.0F; - span.texStepY[0][3] = 0.0F; + span.attrStart[FRAG_ATTRIB_TEX0][0] = invw0 * vert0->attrib[FRAG_ATTRIB_TEX0][0]; + span.attrStart[FRAG_ATTRIB_TEX0][1] = invw0 * vert0->attrib[FRAG_ATTRIB_TEX0][1]; + span.attrStart[FRAG_ATTRIB_TEX0][2] = invw0 * vert0->attrib[FRAG_ATTRIB_TEX0][2]; + span.attrStart[FRAG_ATTRIB_TEX0][3] = invw0 * vert0->attrib[FRAG_ATTRIB_TEX0][3]; + ds = (invw1 * vert1->attrib[FRAG_ATTRIB_TEX0][0]) - span.attrStart[FRAG_ATTRIB_TEX0][0]; + dt = (invw1 * vert1->attrib[FRAG_ATTRIB_TEX0][1]) - span.attrStart[FRAG_ATTRIB_TEX0][1]; + dr = (invw1 * vert1->attrib[FRAG_ATTRIB_TEX0][2]) - span.attrStart[FRAG_ATTRIB_TEX0][2]; + dq = (invw1 * vert1->attrib[FRAG_ATTRIB_TEX0][3]) - span.attrStart[FRAG_ATTRIB_TEX0][3]; + span.attrStepX[FRAG_ATTRIB_TEX0][0] = ds * invLen; + span.attrStepX[FRAG_ATTRIB_TEX0][1] = dt * invLen; + span.attrStepX[FRAG_ATTRIB_TEX0][2] = dr * invLen; + span.attrStepX[FRAG_ATTRIB_TEX0][3] = dq * invLen; + span.attrStepY[FRAG_ATTRIB_TEX0][0] = 0.0F; + span.attrStepY[FRAG_ATTRIB_TEX0][1] = 0.0F; + span.attrStepY[FRAG_ATTRIB_TEX0][2] = 0.0F; + span.attrStepY[FRAG_ATTRIB_TEX0][3] = 0.0F; } #endif -#ifdef INTERP_MULTITEX - interpFlags |= SPAN_TEXTURE; +#if defined(INTERP_MULTITEX) || defined(INTERP_VARYING) + interpFlags |= (SPAN_TEXTURE | SPAN_VARYING); { const GLfloat invLen = 1.0F / numPixels; - GLuint u; - for (u = 0; u < ctx->Const.MaxTextureUnits; u++) { - if (ctx->Texture.Unit[u]._ReallyEnabled) { - const GLfloat invw0 = vert0->win[3]; - const GLfloat invw1 = vert1->win[3]; + const GLfloat invw0 = vert0->win[3]; + const GLfloat invw1 = vert1->win[3]; + GLuint attr; + for (attr = swrast->_MinFragmentAttrib; attr < swrast->_MaxFragmentAttrib; attr++) { + if (swrast->_FragmentAttribs & (1 << attr)) { GLfloat ds, dt, dr, dq; - span.tex[u][0] = invw0 * vert0->texcoord[u][0]; - span.tex[u][1] = invw0 * vert0->texcoord[u][1]; - span.tex[u][2] = invw0 * vert0->texcoord[u][2]; - span.tex[u][3] = invw0 * vert0->texcoord[u][3]; - ds = (invw1 * vert1->texcoord[u][0]) - span.tex[u][0]; - dt = (invw1 * vert1->texcoord[u][1]) - span.tex[u][1]; - dr = (invw1 * vert1->texcoord[u][2]) - span.tex[u][2]; - dq = (invw1 * vert1->texcoord[u][3]) - span.tex[u][3]; - span.texStepX[u][0] = ds * invLen; - span.texStepX[u][1] = dt * invLen; - span.texStepX[u][2] = dr * invLen; - span.texStepX[u][3] = dq * invLen; - span.texStepY[u][0] = 0.0F; - span.texStepY[u][1] = 0.0F; - span.texStepY[u][2] = 0.0F; - span.texStepY[u][3] = 0.0F; + span.attrStart[attr][0] = invw0 * vert0->attrib[attr][0]; + span.attrStart[attr][1] = invw0 * vert0->attrib[attr][1]; + span.attrStart[attr][2] = invw0 * vert0->attrib[attr][2]; + span.attrStart[attr][3] = invw0 * vert0->attrib[attr][3]; + ds = (invw1 * vert1->attrib[attr][0]) - span.attrStart[attr][0]; + dt = (invw1 * vert1->attrib[attr][1]) - span.attrStart[attr][1]; + dr = (invw1 * vert1->attrib[attr][2]) - span.attrStart[attr][2]; + dq = (invw1 * vert1->attrib[attr][3]) - span.attrStart[attr][3]; + span.attrStepX[attr][0] = ds * invLen; + span.attrStepX[attr][1] = dt * invLen; + span.attrStepX[attr][2] = dr * invLen; + span.attrStepX[attr][3] = dq * invLen; + span.attrStepY[attr][0] = 0.0F; + span.attrStepY[attr][1] = 0.0F; + span.attrStepY[attr][2] = 0.0F; + span.attrStepY[attr][3] = 0.0F; } } } @@ -338,9 +342,9 @@ NAME( GLcontext *ctx, const SWvertex *vert0, const SWvertex *vert1 ) INIT_SPAN(span, GL_LINE, numPixels, interpFlags, SPAN_XY); /* Need these for fragment prog texcoord interpolation */ - span.w = 1.0F; - span.dwdx = 0.0F; - span.dwdy = 0.0F; + span.attrStart[FRAG_ATTRIB_WPOS][3] = 1.0F; + span.attrStepX[FRAG_ATTRIB_WPOS][3] = 0.0F; + span.attrStepY[FRAG_ATTRIB_WPOS][3] = 0.0F; /* * Draw diff --git a/src/mesa/swrast/s_logic.c b/src/mesa/swrast/s_logic.c index 719b17962d..e680732bee 100644 --- a/src/mesa/swrast/s_logic.c +++ b/src/mesa/swrast/s_logic.c @@ -240,7 +240,7 @@ _swrast_logicop_rgba_span(GLcontext *ctx, struct gl_renderbuffer *rb, } else { logicop_uint4(ctx, 4 * span->end, - (GLuint *) span->array->color.sz4.rgba, + (GLuint *) span->array->attribs[FRAG_ATTRIB_COL0], (const GLuint *) rbPixels, span->array->mask); } } diff --git a/src/mesa/swrast/s_masking.c b/src/mesa/swrast/s_masking.c index 65c984dd3e..8800f7d8e3 100644 --- a/src/mesa/swrast/s_masking.c +++ b/src/mesa/swrast/s_masking.c @@ -91,7 +91,7 @@ _swrast_mask_rgba_span(GLcontext *ctx, struct gl_renderbuffer *rb, const GLuint bMask = ctx->Color.ColorMask[BCOMP] ? ~0x0 : 0x0; const GLuint aMask = ctx->Color.ColorMask[ACOMP] ? ~0x0 : 0x0; const GLuint (*dst)[4] = (const GLuint (*)[4]) rbPixels; - GLuint (*src)[4] = (GLuint (*)[4]) span->array->color.sz4.rgba; + GLuint (*src)[4] = (GLuint (*)[4]) span->array->attribs[FRAG_ATTRIB_COL0]; GLuint i; for (i = 0; i < n; i++) { src[i][RCOMP] = (src[i][RCOMP] & rMask) | (dst[i][RCOMP] & ~rMask); diff --git a/src/mesa/swrast/s_nvfragprog.c b/src/mesa/swrast/s_nvfragprog.c deleted file mode 100644 index 028ddc0090..0000000000 --- a/src/mesa/swrast/s_nvfragprog.c +++ /dev/null @@ -1,1665 +0,0 @@ -/* - * Mesa 3-D graphics library - * Version: 6.5.2 - * - * Copyright (C) 1999-2006 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. - */ - -/* - * Regarding GL_NV_fragment_program: - * - * Portions of this software may use or implement intellectual - * property owned and licensed by NVIDIA Corporation. NVIDIA disclaims - * any and all warranties with respect to such intellectual property, - * including any use thereof or modifications thereto. - */ - -#include "glheader.h" -#include "colormac.h" -#include "context.h" -#include "program_instruction.h" -#include "program.h" - -#include "s_nvfragprog.h" -#include "s_span.h" - - -/* See comments below for info about this */ -#define LAMBDA_ZERO 1 - -/* debug predicate */ -#define DEBUG_FRAG 0 - - -/** - * Virtual machine state used during execution of a fragment programs. - */ -struct fp_machine -{ - GLfloat Temporaries[MAX_NV_FRAGMENT_PROGRAM_TEMPS][4]; - GLfloat Inputs[MAX_NV_FRAGMENT_PROGRAM_INPUTS][4]; - GLfloat Outputs[MAX_NV_FRAGMENT_PROGRAM_OUTPUTS][4]; - GLuint CondCodes[4]; /**< COND_* value for x/y/z/w */ - - GLuint CallStack[MAX_PROGRAM_CALL_DEPTH]; /**< For CAL/RET instructions */ - GLuint StackDepth; /**< Index/ptr to top of CallStack[] */ -}; - - -#if FEATURE_MESA_program_debug -static struct fp_machine *CurrentMachine = NULL; - -/** - * For GL_MESA_program_debug. - * Return current value (4*GLfloat) of a fragment program register. - * Called via ctx->Driver.GetFragmentProgramRegister(). - */ -void -_swrast_get_program_register(GLcontext *ctx, enum register_file file, - GLuint index, GLfloat val[4]) -{ - if (CurrentMachine) { - switch (file) { - case PROGRAM_INPUT: - COPY_4V(val, CurrentMachine->Inputs[index]); - break; - case PROGRAM_OUTPUT: - COPY_4V(val, CurrentMachine->Outputs[index]); - break; - case PROGRAM_TEMPORARY: - COPY_4V(val, CurrentMachine->Temporaries[index]); - break; - default: - _mesa_problem(NULL, - "bad register file in _swrast_get_program_register"); - } - } -} -#endif /* FEATURE_MESA_program_debug */ - - -/** - * Fetch a texel. - */ -static void -fetch_texel( GLcontext *ctx, const GLfloat texcoord[4], GLfloat lambda, - GLuint unit, GLfloat color[4] ) -{ - GLchan rgba[4]; - SWcontext *swrast = SWRAST_CONTEXT(ctx); - - /* XXX use a float-valued TextureSample routine here!!! */ - swrast->TextureSample[unit](ctx, ctx->Texture.Unit[unit]._Current, - 1, (const GLfloat (*)[4]) texcoord, - &lambda, &rgba); - color[0] = CHAN_TO_FLOAT(rgba[0]); - color[1] = CHAN_TO_FLOAT(rgba[1]); - color[2] = CHAN_TO_FLOAT(rgba[2]); - color[3] = CHAN_TO_FLOAT(rgba[3]); -} - - -/** - * Fetch a texel with the given partial derivatives to compute a level - * of detail in the mipmap. - */ -static void -fetch_texel_deriv( GLcontext *ctx, const GLfloat texcoord[4], - const GLfloat texdx[4], const GLfloat texdy[4], - GLuint unit, GLfloat color[4] ) -{ - SWcontext *swrast = SWRAST_CONTEXT(ctx); - const struct gl_texture_object *texObj = ctx->Texture.Unit[unit]._Current; - const struct gl_texture_image *texImg = texObj->Image[0][texObj->BaseLevel]; - const GLfloat texW = (GLfloat) texImg->WidthScale; - const GLfloat texH = (GLfloat) texImg->HeightScale; - GLchan rgba[4]; - - GLfloat lambda = _swrast_compute_lambda(texdx[0], texdy[0], /* ds/dx, ds/dy */ - texdx[1], texdy[1], /* dt/dx, dt/dy */ - texdx[3], texdy[2], /* dq/dx, dq/dy */ - texW, texH, - texcoord[0], texcoord[1], texcoord[3], - 1.0F / texcoord[3]); - - swrast->TextureSample[unit](ctx, ctx->Texture.Unit[unit]._Current, - 1, (const GLfloat (*)[4]) texcoord, - &lambda, &rgba); - color[0] = CHAN_TO_FLOAT(rgba[0]); - color[1] = CHAN_TO_FLOAT(rgba[1]); - color[2] = CHAN_TO_FLOAT(rgba[2]); - color[3] = CHAN_TO_FLOAT(rgba[3]); -} - - -/** - * Return a pointer to the 4-element float vector specified by the given - * source register. - */ -static INLINE const GLfloat * -get_register_pointer( GLcontext *ctx, - const struct prog_src_register *source, - const struct fp_machine *machine, - const struct gl_fragment_program *program ) -{ - switch (source->File) { - case PROGRAM_TEMPORARY: - ASSERT(source->Index < MAX_NV_FRAGMENT_PROGRAM_TEMPS); - return machine->Temporaries[source->Index]; - case PROGRAM_INPUT: - ASSERT(source->Index < MAX_NV_FRAGMENT_PROGRAM_INPUTS); - return machine->Inputs[source->Index]; - case PROGRAM_OUTPUT: - /* This is only for PRINT */ - ASSERT(source->Index < MAX_NV_FRAGMENT_PROGRAM_OUTPUTS); - return machine->Outputs[source->Index]; - case PROGRAM_LOCAL_PARAM: - ASSERT(source->Index < MAX_PROGRAM_LOCAL_PARAMS); - return program->Base.LocalParams[source->Index]; - case PROGRAM_ENV_PARAM: - ASSERT(source->Index < MAX_NV_FRAGMENT_PROGRAM_PARAMS); - return ctx->FragmentProgram.Parameters[source->Index]; - case PROGRAM_STATE_VAR: - /* Fallthrough */ - case PROGRAM_CONSTANT: - /* Fallthrough */ - case PROGRAM_NAMED_PARAM: - ASSERT(source->Index < (GLint) program->Base.Parameters->NumParameters); - return program->Base.Parameters->ParameterValues[source->Index]; - default: - _mesa_problem(ctx, "Invalid input register file %d in fp " - "get_register_pointer", source->File); - return NULL; - } -} - - -/** - * Fetch a 4-element float vector from the given source register. - * Apply swizzling and negating as needed. - */ -static void -fetch_vector4( GLcontext *ctx, - const struct prog_src_register *source, - const struct fp_machine *machine, - const struct gl_fragment_program *program, - GLfloat result[4] ) -{ - const GLfloat *src = get_register_pointer(ctx, source, machine, program); - ASSERT(src); - - if (source->Swizzle == MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_Y, - SWIZZLE_Z, SWIZZLE_W)) { - /* no swizzling */ - COPY_4V(result, src); - } - else { - result[0] = src[GET_SWZ(source->Swizzle, 0)]; - result[1] = src[GET_SWZ(source->Swizzle, 1)]; - result[2] = src[GET_SWZ(source->Swizzle, 2)]; - result[3] = src[GET_SWZ(source->Swizzle, 3)]; - } - - if (source->NegateBase) { - result[0] = -result[0]; - result[1] = -result[1]; - result[2] = -result[2]; - result[3] = -result[3]; - } - if (source->Abs) { - result[0] = FABSF(result[0]); - result[1] = FABSF(result[1]); - result[2] = FABSF(result[2]); - result[3] = FABSF(result[3]); - } - if (source->NegateAbs) { - result[0] = -result[0]; - result[1] = -result[1]; - result[2] = -result[2]; - result[3] = -result[3]; - } -} - - -/** - * Fetch the derivative with respect to X for the given register. - * \return GL_TRUE if it was easily computed or GL_FALSE if we - * need to execute another instance of the program (ugh)! - */ -static GLboolean -fetch_vector4_deriv( GLcontext *ctx, - const struct prog_src_register *source, - const SWspan *span, - char xOrY, GLint column, GLfloat result[4] ) -{ - GLfloat src[4]; - - ASSERT(xOrY == 'X' || xOrY == 'Y'); - - switch (source->Index) { - case FRAG_ATTRIB_WPOS: - if (xOrY == 'X') { - src[0] = 1.0; - src[1] = 0.0; - src[2] = span->dzdx / ctx->DrawBuffer->_DepthMaxF; - src[3] = span->dwdx; - } - else { - src[0] = 0.0; - src[1] = 1.0; - src[2] = span->dzdy / ctx->DrawBuffer->_DepthMaxF; - src[3] = span->dwdy; - } - break; - case FRAG_ATTRIB_COL0: - if (xOrY == 'X') { - src[0] = span->drdx * (1.0F / CHAN_MAXF); - src[1] = span->dgdx * (1.0F / CHAN_MAXF); - src[2] = span->dbdx * (1.0F / CHAN_MAXF); - src[3] = span->dadx * (1.0F / CHAN_MAXF); - } - else { - src[0] = span->drdy * (1.0F / CHAN_MAXF); - src[1] = span->dgdy * (1.0F / CHAN_MAXF); - src[2] = span->dbdy * (1.0F / CHAN_MAXF); - src[3] = span->dady * (1.0F / CHAN_MAXF); - } - break; - case FRAG_ATTRIB_COL1: - if (xOrY == 'X') { - src[0] = span->dsrdx * (1.0F / CHAN_MAXF); - src[1] = span->dsgdx * (1.0F / CHAN_MAXF); - src[2] = span->dsbdx * (1.0F / CHAN_MAXF); - src[3] = 0.0; /* XXX need this */ - } - else { - src[0] = span->dsrdy * (1.0F / CHAN_MAXF); - src[1] = span->dsgdy * (1.0F / CHAN_MAXF); - src[2] = span->dsbdy * (1.0F / CHAN_MAXF); - src[3] = 0.0; /* XXX need this */ - } - break; - case FRAG_ATTRIB_FOGC: - if (xOrY == 'X') { - src[0] = span->dfogdx; - src[1] = 0.0; - src[2] = 0.0; - src[3] = 0.0; - } - else { - src[0] = span->dfogdy; - src[1] = 0.0; - src[2] = 0.0; - src[3] = 0.0; - } - break; - case FRAG_ATTRIB_TEX0: - case FRAG_ATTRIB_TEX1: - case FRAG_ATTRIB_TEX2: - case FRAG_ATTRIB_TEX3: - case FRAG_ATTRIB_TEX4: - case FRAG_ATTRIB_TEX5: - case FRAG_ATTRIB_TEX6: - case FRAG_ATTRIB_TEX7: - if (xOrY == 'X') { - const GLuint u = source->Index - FRAG_ATTRIB_TEX0; - /* this is a little tricky - I think I've got it right */ - const GLfloat invQ = 1.0f / (span->tex[u][3] - + span->texStepX[u][3] * column); - src[0] = span->texStepX[u][0] * invQ; - src[1] = span->texStepX[u][1] * invQ; - src[2] = span->texStepX[u][2] * invQ; - src[3] = span->texStepX[u][3] * invQ; - } - else { - const GLuint u = source->Index - FRAG_ATTRIB_TEX0; - /* Tricky, as above, but in Y direction */ - const GLfloat invQ = 1.0f / (span->tex[u][3] + span->texStepY[u][3]); - src[0] = span->texStepY[u][0] * invQ; - src[1] = span->texStepY[u][1] * invQ; - src[2] = span->texStepY[u][2] * invQ; - src[3] = span->texStepY[u][3] * invQ; - } - break; - default: - return GL_FALSE; - } - - result[0] = src[GET_SWZ(source->Swizzle, 0)]; - result[1] = src[GET_SWZ(source->Swizzle, 1)]; - result[2] = src[GET_SWZ(source->Swizzle, 2)]; - result[3] = src[GET_SWZ(source->Swizzle, 3)]; - - if (source->NegateBase) { - result[0] = -result[0]; - result[1] = -result[1]; - result[2] = -result[2]; - result[3] = -result[3]; - } - if (source->Abs) { - result[0] = FABSF(result[0]); - result[1] = FABSF(result[1]); - result[2] = FABSF(result[2]); - result[3] = FABSF(result[3]); - } - if (source->NegateAbs) { - result[0] = -result[0]; - result[1] = -result[1]; - result[2] = -result[2]; - result[3] = -result[3]; - } - return GL_TRUE; -} - - -/** - * As above, but only return result[0] element. - */ -static void -fetch_vector1( GLcontext *ctx, - const struct prog_src_register *source, - const struct fp_machine *machine, - const struct gl_fragment_program *program, - GLfloat result[4] ) -{ - const GLfloat *src = get_register_pointer(ctx, source, machine, program); - ASSERT(src); - - result[0] = src[GET_SWZ(source->Swizzle, 0)]; - - if (source->NegateBase) { - result[0] = -result[0]; - } - if (source->Abs) { - result[0] = FABSF(result[0]); - } - if (source->NegateAbs) { - result[0] = -result[0]; - } -} - - -/** - * Test value against zero and return GT, LT, EQ or UN if NaN. - */ -static INLINE GLuint -generate_cc( float value ) -{ - if (value != value) - return COND_UN; /* NaN */ - if (value > 0.0F) - return COND_GT; - if (value < 0.0F) - return COND_LT; - return COND_EQ; -} - - -/** - * Test if the ccMaskRule is satisfied by the given condition code. - * Used to mask destination writes according to the current condition code. - */ -static INLINE GLboolean -test_cc(GLuint condCode, GLuint ccMaskRule) -{ - switch (ccMaskRule) { - case COND_EQ: return (condCode == COND_EQ); - case COND_NE: return (condCode != COND_EQ); - case COND_LT: return (condCode == COND_LT); - case COND_GE: return (condCode == COND_GT || condCode == COND_EQ); - case COND_LE: return (condCode == COND_LT || condCode == COND_EQ); - case COND_GT: return (condCode == COND_GT); - case COND_TR: return GL_TRUE; - case COND_FL: return GL_FALSE; - default: return GL_TRUE; - } -} - - -/** - * Store 4 floats into a register. Observe the instructions saturate and - * set-condition-code flags. - */ -static void -store_vector4( const struct prog_instruction *inst, - struct fp_machine *machine, - const GLfloat value[4] ) -{ - const struct prog_dst_register *dest = &(inst->DstReg); - const GLboolean clamp = inst->SaturateMode == SATURATE_ZERO_ONE; - GLfloat *dstReg; - GLfloat dummyReg[4]; - GLfloat clampedValue[4]; - GLuint writeMask = dest->WriteMask; - - switch (dest->File) { - case PROGRAM_OUTPUT: - dstReg = machine->Outputs[dest->Index]; - break; - case PROGRAM_TEMPORARY: - dstReg = machine->Temporaries[dest->Index]; - break; - case PROGRAM_WRITE_ONLY: - dstReg = dummyReg; - return; - default: - _mesa_problem(NULL, "bad register file in store_vector4(fp)"); - return; - } - -#if 0 - if (value[0] > 1.0e10 || - IS_INF_OR_NAN(value[0]) || - IS_INF_OR_NAN(value[1]) || - IS_INF_OR_NAN(value[2]) || - IS_INF_OR_NAN(value[3]) ) - printf("store %g %g %g %g\n", value[0], value[1], value[2], value[3]); -#endif - - if (clamp) { - clampedValue[0] = CLAMP(value[0], 0.0F, 1.0F); - clampedValue[1] = CLAMP(value[1], 0.0F, 1.0F); - clampedValue[2] = CLAMP(value[2], 0.0F, 1.0F); - clampedValue[3] = CLAMP(value[3], 0.0F, 1.0F); - value = clampedValue; - } - - if (dest->CondMask != COND_TR) { - /* condition codes may turn off some writes */ - if (writeMask & WRITEMASK_X) { - if (!test_cc(machine->CondCodes[GET_SWZ(dest->CondSwizzle, 0)], - dest->CondMask)) - writeMask &= ~WRITEMASK_X; - } - if (writeMask & WRITEMASK_Y) { - if (!test_cc(machine->CondCodes[GET_SWZ(dest->CondSwizzle, 1)], - dest->CondMask)) - writeMask &= ~WRITEMASK_Y; - } - if (writeMask & WRITEMASK_Z) { - if (!test_cc(machine->CondCodes[GET_SWZ(dest->CondSwizzle, 2)], - dest->CondMask)) - writeMask &= ~WRITEMASK_Z; - } - if (writeMask & WRITEMASK_W) { - if (!test_cc(machine->CondCodes[GET_SWZ(dest->CondSwizzle, 3)], - dest->CondMask)) - writeMask &= ~WRITEMASK_W; - } - } - - if (writeMask & WRITEMASK_X) - dstReg[0] = value[0]; - if (writeMask & WRITEMASK_Y) - dstReg[1] = value[1]; - if (writeMask & WRITEMASK_Z) - dstReg[2] = value[2]; - if (writeMask & WRITEMASK_W) - dstReg[3] = value[3]; - - if (inst->CondUpdate) { - if (writeMask & WRITEMASK_X) - machine->CondCodes[0] = generate_cc(value[0]); - if (writeMask & WRITEMASK_Y) - machine->CondCodes[1] = generate_cc(value[1]); - if (writeMask & WRITEMASK_Z) - machine->CondCodes[2] = generate_cc(value[2]); - if (writeMask & WRITEMASK_W) - machine->CondCodes[3] = generate_cc(value[3]); - } -} - - -/** - * Initialize a new machine state instance from an existing one, adding - * the partial derivatives onto the input registers. - * Used to implement DDX and DDY instructions in non-trivial cases. - */ -static void -init_machine_deriv( GLcontext *ctx, - const struct fp_machine *machine, - const struct gl_fragment_program *program, - const SWspan *span, char xOrY, - struct fp_machine *dMachine ) -{ - GLuint u; - - ASSERT(xOrY == 'X' || xOrY == 'Y'); - - /* copy existing machine */ - _mesa_memcpy(dMachine, machine, sizeof(struct fp_machine)); - - if (program->Base.Target == GL_FRAGMENT_PROGRAM_NV) { - /* Clear temporary registers (undefined for ARB_f_p) */ - _mesa_bzero( (void*) machine->Temporaries, - MAX_NV_FRAGMENT_PROGRAM_TEMPS * 4 * sizeof(GLfloat)); - } - - /* Add derivatives */ - if (program->Base.InputsRead & (1 << FRAG_ATTRIB_WPOS)) { - GLfloat *wpos = (GLfloat*) machine->Inputs[FRAG_ATTRIB_WPOS]; - if (xOrY == 'X') { - wpos[0] += 1.0F; - wpos[1] += 0.0F; - wpos[2] += span->dzdx; - wpos[3] += span->dwdx; - } - else { - wpos[0] += 0.0F; - wpos[1] += 1.0F; - wpos[2] += span->dzdy; - wpos[3] += span->dwdy; - } - } - if (program->Base.InputsRead & (1 << FRAG_ATTRIB_COL0)) { - GLfloat *col0 = (GLfloat*) machine->Inputs[FRAG_ATTRIB_COL0]; - if (xOrY == 'X') { - col0[0] += span->drdx * (1.0F / CHAN_MAXF); - col0[1] += span->dgdx * (1.0F / CHAN_MAXF); - col0[2] += span->dbdx * (1.0F / CHAN_MAXF); - col0[3] += span->dadx * (1.0F / CHAN_MAXF); - } - else { - col0[0] += span->drdy * (1.0F / CHAN_MAXF); - col0[1] += span->dgdy * (1.0F / CHAN_MAXF); - col0[2] += span->dbdy * (1.0F / CHAN_MAXF); - col0[3] += span->dady * (1.0F / CHAN_MAXF); - } - } - if (program->Base.InputsRead & (1 << FRAG_ATTRIB_COL1)) { - GLfloat *col1 = (GLfloat*) machine->Inputs[FRAG_ATTRIB_COL1]; - if (xOrY == 'X') { - col1[0] += span->dsrdx * (1.0F / CHAN_MAXF); - col1[1] += span->dsgdx * (1.0F / CHAN_MAXF); - col1[2] += span->dsbdx * (1.0F / CHAN_MAXF); - col1[3] += 0.0; /*XXX fix */ - } - else { - col1[0] += span->dsrdy * (1.0F / CHAN_MAXF); - col1[1] += span->dsgdy * (1.0F / CHAN_MAXF); - col1[2] += span->dsbdy * (1.0F / CHAN_MAXF); - col1[3] += 0.0; /*XXX fix */ - } - } - if (program->Base.InputsRead & (1 << FRAG_ATTRIB_FOGC)) { - GLfloat *fogc = (GLfloat*) machine->Inputs[FRAG_ATTRIB_FOGC]; - if (xOrY == 'X') { - fogc[0] += span->dfogdx; - } - else { - fogc[0] += span->dfogdy; - } - } - for (u = 0; u < ctx->Const.MaxTextureCoordUnits; u++) { - if (program->Base.InputsRead & (1 << (FRAG_ATTRIB_TEX0 + u))) { - GLfloat *tex = (GLfloat*) machine->Inputs[FRAG_ATTRIB_TEX0 + u]; - /* XXX perspective-correct interpolation */ - if (xOrY == 'X') { - tex[0] += span->texStepX[u][0]; - tex[1] += span->texStepX[u][1]; - tex[2] += span->texStepX[u][2]; - tex[3] += span->texStepX[u][3]; - } - else { - tex[0] += span->texStepY[u][0]; - tex[1] += span->texStepY[u][1]; - tex[2] += span->texStepY[u][2]; - tex[3] += span->texStepY[u][3]; - } - } - } - - /* init condition codes */ - dMachine->CondCodes[0] = COND_EQ; - dMachine->CondCodes[1] = COND_EQ; - dMachine->CondCodes[2] = COND_EQ; - dMachine->CondCodes[3] = COND_EQ; -} - - -/** - * Execute the given vertex program. - * NOTE: we do everything in single-precision floating point; we don't - * currently observe the single/half/fixed-precision qualifiers. - * \param ctx - rendering context - * \param program - the fragment program to execute - * \param machine - machine state (register file) - * \param maxInst - max number of instructions to execute - * \return GL_TRUE if program completed or GL_FALSE if program executed KIL. - */ -static GLboolean -execute_program( GLcontext *ctx, - const struct gl_fragment_program *program, GLuint maxInst, - struct fp_machine *machine, const SWspan *span, - GLuint column ) -{ - GLuint pc; - - if (DEBUG_FRAG) { - printf("execute fragment program --------------------\n"); - } - - for (pc = 0; pc < maxInst; pc++) { - const struct prog_instruction *inst = program->Base.Instructions + pc; - - if (ctx->FragmentProgram.CallbackEnabled && - ctx->FragmentProgram.Callback) { - ctx->FragmentProgram.CurrentPosition = inst->StringPos; - ctx->FragmentProgram.Callback(program->Base.Target, - ctx->FragmentProgram.CallbackData); - } - - if (DEBUG_FRAG) { - _mesa_print_instruction(inst); - } - - switch (inst->Opcode) { - case OPCODE_ABS: - { - GLfloat a[4], result[4]; - fetch_vector4( ctx, &inst->SrcReg[0], machine, program, a ); - result[0] = FABSF(a[0]); - result[1] = FABSF(a[1]); - result[2] = FABSF(a[2]); - result[3] = FABSF(a[3]); - store_vector4( inst, machine, result ); - } - break; - case OPCODE_ADD: - { - GLfloat a[4], b[4], result[4]; - fetch_vector4( ctx, &inst->SrcReg[0], machine, program, a ); - fetch_vector4( ctx, &inst->SrcReg[1], machine, program, b ); - result[0] = a[0] + b[0]; - result[1] = a[1] + b[1]; - result[2] = a[2] + b[2]; - result[3] = a[3] + b[3]; - store_vector4( inst, machine, result ); - if (DEBUG_FRAG) { - printf("ADD (%g %g %g %g) = (%g %g %g %g) + (%g %g %g %g)\n", - result[0], result[1], result[2], result[3], - a[0], a[1], a[2], a[3], - b[0], b[1], b[2], b[3]); - } - } - break; - case OPCODE_BRA: /* conditional branch */ - { - /* 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)) { - /* take branch */ - pc = inst->BranchTarget; - } - } - 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; - } - } - break; - case OPCODE_CMP: - { - GLfloat a[4], b[4], c[4], result[4]; - fetch_vector4( ctx, &inst->SrcReg[0], machine, program, a ); - fetch_vector4( ctx, &inst->SrcReg[1], machine, program, b ); - fetch_vector4( ctx, &inst->SrcReg[2], machine, program, c ); - result[0] = a[0] < 0.0F ? b[0] : c[0]; - result[1] = a[1] < 0.0F ? b[1] : c[1]; - result[2] = a[2] < 0.0F ? b[2] : c[2]; - result[3] = a[3] < 0.0F ? b[3] : c[3]; - store_vector4( inst, machine, result ); - } - break; - case OPCODE_COS: - { - GLfloat a[4], result[4]; - fetch_vector1( ctx, &inst->SrcReg[0], machine, program, a ); - result[0] = result[1] = result[2] = result[3] - = (GLfloat) _mesa_cos(a[0]); - store_vector4( inst, machine, result ); - } - break; - case OPCODE_DDX: /* Partial derivative with respect to X */ - { - GLfloat a[4], aNext[4], result[4]; - struct fp_machine dMachine; - if (!fetch_vector4_deriv(ctx, &inst->SrcReg[0], span, 'X', - column, result)) { - /* This is tricky. Make a copy of the current machine state, - * increment the input registers by the dx or dy partial - * derivatives, then re-execute the program up to the - * preceeding instruction, then fetch the source register. - * Finally, find the difference in the register values for - * the original and derivative runs. - */ - fetch_vector4( ctx, &inst->SrcReg[0], machine, program, a); - init_machine_deriv(ctx, machine, program, span, - 'X', &dMachine); - execute_program(ctx, program, pc, &dMachine, span, column); - fetch_vector4( ctx, &inst->SrcReg[0], &dMachine, program, aNext ); - result[0] = aNext[0] - a[0]; - result[1] = aNext[1] - a[1]; - result[2] = aNext[2] - a[2]; - result[3] = aNext[3] - a[3]; - } - store_vector4( inst, machine, result ); - } - break; - case OPCODE_DDY: /* Partial derivative with respect to Y */ - { - GLfloat a[4], aNext[4], result[4]; - struct fp_machine dMachine; - if (!fetch_vector4_deriv(ctx, &inst->SrcReg[0], span, 'Y', - column, result)) { - init_machine_deriv(ctx, machine, program, span, - 'Y', &dMachine); - fetch_vector4( ctx, &inst->SrcReg[0], machine, program, a); - execute_program(ctx, program, pc, &dMachine, span, column); - fetch_vector4( ctx, &inst->SrcReg[0], &dMachine, program, aNext ); - result[0] = aNext[0] - a[0]; - result[1] = aNext[1] - a[1]; - result[2] = aNext[2] - a[2]; - result[3] = aNext[3] - a[3]; - } - store_vector4( inst, machine, result ); - } - break; - case OPCODE_DP3: - { - GLfloat a[4], b[4], result[4]; - fetch_vector4( ctx, &inst->SrcReg[0], machine, program, a ); - fetch_vector4( ctx, &inst->SrcReg[1], machine, program, b ); - result[0] = result[1] = result[2] = result[3] = DOT3(a, b); - store_vector4( inst, machine, result ); - if (DEBUG_FRAG) { - printf("DP3 %g = (%g %g %g) . (%g %g %g)\n", - result[0], a[0], a[1], a[2], b[0], b[1], b[2]); - } - } - break; - case OPCODE_DP4: - { - GLfloat a[4], b[4], result[4]; - fetch_vector4( ctx, &inst->SrcReg[0], machine, program, a ); - fetch_vector4( ctx, &inst->SrcReg[1], machine, program, b ); - result[0] = result[1] = result[2] = result[3] = DOT4(a,b); - store_vector4( inst, machine, result ); - if (DEBUG_FRAG) { - printf("DP4 %g = (%g, %g %g %g) . (%g, %g %g %g)\n", - result[0], a[0], a[1], a[2], a[3], - b[0], b[1], b[2], b[3]); - } - } - break; - case OPCODE_DPH: - { - GLfloat a[4], b[4], result[4]; - fetch_vector4( ctx, &inst->SrcReg[0], machine, program, a ); - fetch_vector4( ctx, &inst->SrcReg[1], machine, program, b ); - result[0] = result[1] = result[2] = result[3] = - a[0] * b[0] + a[1] * b[1] + a[2] * b[2] + b[3]; - store_vector4( inst, machine, result ); - } - break; - case OPCODE_DST: /* Distance vector */ - { - GLfloat a[4], b[4], result[4]; - fetch_vector4( ctx, &inst->SrcReg[0], machine, program, a ); - fetch_vector4( ctx, &inst->SrcReg[1], machine, program, b ); - result[0] = 1.0F; - result[1] = a[1] * b[1]; - result[2] = a[2]; - result[3] = b[3]; - store_vector4( inst, machine, result ); - } - break; - case OPCODE_EX2: /* Exponential base 2 */ - { - GLfloat a[4], result[4]; - fetch_vector1( ctx, &inst->SrcReg[0], machine, program, a ); - result[0] = result[1] = result[2] = result[3] = - (GLfloat) _mesa_pow(2.0, a[0]); - store_vector4( inst, machine, result ); - } - break; - case OPCODE_FLR: - { - GLfloat a[4], result[4]; - fetch_vector4( ctx, &inst->SrcReg[0], machine, program, a ); - result[0] = FLOORF(a[0]); - result[1] = FLOORF(a[1]); - result[2] = FLOORF(a[2]); - result[3] = FLOORF(a[3]); - store_vector4( inst, machine, result ); - } - break; - case OPCODE_FRC: - { - GLfloat a[4], result[4]; - fetch_vector4( ctx, &inst->SrcReg[0], machine, program, a ); - result[0] = a[0] - FLOORF(a[0]); - result[1] = a[1] - FLOORF(a[1]); - result[2] = a[2] - FLOORF(a[2]); - result[3] = a[3] - FLOORF(a[3]); - 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; - } - } - break; - case OPCODE_KIL: /* ARB_f_p only */ - { - GLfloat a[4]; - fetch_vector4( ctx, &inst->SrcReg[0], machine, program, a ); - if (a[0] < 0.0F || a[1] < 0.0F || a[2] < 0.0F || a[3] < 0.0F) { - return GL_FALSE; - } - } - break; - case OPCODE_LG2: /* log base 2 */ - { - GLfloat a[4], result[4]; - fetch_vector1( ctx, &inst->SrcReg[0], machine, program, a ); - result[0] = result[1] = result[2] = result[3] = LOG2(a[0]); - store_vector4( inst, machine, result ); - } - break; - case OPCODE_LIT: - { - const GLfloat epsilon = 1.0F / 256.0F; /* from NV VP spec */ - GLfloat a[4], result[4]; - fetch_vector4( ctx, &inst->SrcReg[0], machine, program, a ); - a[0] = MAX2(a[0], 0.0F); - a[1] = MAX2(a[1], 0.0F); - /* XXX ARB version clamps a[3], NV version doesn't */ - a[3] = CLAMP(a[3], -(128.0F - epsilon), (128.0F - epsilon)); - result[0] = 1.0F; - result[1] = a[0]; - /* XXX we could probably just use pow() here */ - if (a[0] > 0.0F) { - if (a[1] == 0.0 && a[3] == 0.0) - result[2] = 1.0; - else - result[2] = EXPF(a[3] * LOGF(a[1])); - } - else { - result[2] = 0.0; - } - result[3] = 1.0F; - store_vector4( inst, machine, result ); - if (DEBUG_FRAG) { - printf("LIT (%g %g %g %g) : (%g %g %g %g)\n", - result[0], result[1], result[2], result[3], - a[0], a[1], a[2], a[3]); - } - } - break; - case OPCODE_LRP: - { - GLfloat a[4], b[4], c[4], result[4]; - fetch_vector4( ctx, &inst->SrcReg[0], machine, program, a ); - fetch_vector4( ctx, &inst->SrcReg[1], machine, program, b ); - fetch_vector4( ctx, &inst->SrcReg[2], machine, program, c ); - result[0] = a[0] * b[0] + (1.0F - a[0]) * c[0]; - result[1] = a[1] * b[1] + (1.0F - a[1]) * c[1]; - result[2] = a[2] * b[2] + (1.0F - a[2]) * c[2]; - result[3] = a[3] * b[3] + (1.0F - a[3]) * c[3]; - store_vector4( inst, machine, result ); - if (DEBUG_FRAG) { - printf("LRP (%g %g %g %g) = (%g %g %g %g), " - "(%g %g %g %g), (%g %g %g %g)\n", - result[0], result[1], result[2], result[3], - a[0], a[1], a[2], a[3], - b[0], b[1], b[2], b[3], - c[0], c[1], c[2], c[3]); - } - } - break; - case OPCODE_MAD: - { - GLfloat a[4], b[4], c[4], result[4]; - fetch_vector4( ctx, &inst->SrcReg[0], machine, program, a ); - fetch_vector4( ctx, &inst->SrcReg[1], machine, program, b ); - fetch_vector4( ctx, &inst->SrcReg[2], machine, program, c ); - result[0] = a[0] * b[0] + c[0]; - result[1] = a[1] * b[1] + c[1]; - result[2] = a[2] * b[2] + c[2]; - result[3] = a[3] * b[3] + c[3]; - store_vector4( inst, machine, result ); - if (DEBUG_FRAG) { - printf("MAD (%g %g %g %g) = (%g %g %g %g) * " - "(%g %g %g %g) + (%g %g %g %g)\n", - result[0], result[1], result[2], result[3], - a[0], a[1], a[2], a[3], - b[0], b[1], b[2], b[3], - c[0], c[1], c[2], c[3]); - } - } - break; - case OPCODE_MAX: - { - GLfloat a[4], b[4], result[4]; - fetch_vector4( ctx, &inst->SrcReg[0], machine, program, a ); - fetch_vector4( ctx, &inst->SrcReg[1], machine, program, b ); - result[0] = MAX2(a[0], b[0]); - result[1] = MAX2(a[1], b[1]); - result[2] = MAX2(a[2], b[2]); - result[3] = MAX2(a[3], b[3]); - store_vector4( inst, machine, result ); - if (DEBUG_FRAG) { - printf("MAX (%g %g %g %g) = (%g %g %g %g), (%g %g %g %g)\n", - result[0], result[1], result[2], result[3], - a[0], a[1], a[2], a[3], - b[0], b[1], b[2], b[3]); - } - } - break; - case OPCODE_MIN: - { - GLfloat a[4], b[4], result[4]; - fetch_vector4( ctx, &inst->SrcReg[0], machine, program, a ); - fetch_vector4( ctx, &inst->SrcReg[1], machine, program, b ); - result[0] = MIN2(a[0], b[0]); - result[1] = MIN2(a[1], b[1]); - result[2] = MIN2(a[2], b[2]); - result[3] = MIN2(a[3], b[3]); - store_vector4( inst, machine, result ); - } - break; - case OPCODE_MOV: - { - GLfloat result[4]; - fetch_vector4( ctx, &inst->SrcReg[0], machine, program, result ); - store_vector4( inst, machine, result ); - if (DEBUG_FRAG) { - printf("MOV (%g %g %g %g)\n", - result[0], result[1], result[2], result[3]); - } - } - break; - case OPCODE_MUL: - { - GLfloat a[4], b[4], result[4]; - fetch_vector4( ctx, &inst->SrcReg[0], machine, program, a ); - fetch_vector4( ctx, &inst->SrcReg[1], machine, program, b ); - result[0] = a[0] * b[0]; - result[1] = a[1] * b[1]; - result[2] = a[2] * b[2]; - result[3] = a[3] * b[3]; - store_vector4( inst, machine, result ); - if (DEBUG_FRAG) { - printf("MUL (%g %g %g %g) = (%g %g %g %g) * (%g %g %g %g)\n", - result[0], result[1], result[2], result[3], - a[0], a[1], a[2], a[3], - b[0], b[1], b[2], b[3]); - } - } - break; - case OPCODE_PK2H: /* pack two 16-bit floats in one 32-bit float */ - { - GLfloat a[4], result[4]; - GLhalfNV hx, hy; - GLuint *rawResult = (GLuint *) result; - GLuint twoHalves; - fetch_vector4( ctx, &inst->SrcReg[0], machine, program, a ); - hx = _mesa_float_to_half(a[0]); - hy = _mesa_float_to_half(a[1]); - twoHalves = hx | (hy << 16); - rawResult[0] = rawResult[1] = rawResult[2] = rawResult[3] - = twoHalves; - store_vector4( inst, machine, result ); - } - break; - case OPCODE_PK2US: /* pack two GLushorts into one 32-bit float */ - { - GLfloat a[4], result[4]; - GLuint usx, usy, *rawResult = (GLuint *) result; - fetch_vector4( ctx, &inst->SrcReg[0], machine, program, a ); - a[0] = CLAMP(a[0], 0.0F, 1.0F); - a[1] = CLAMP(a[1], 0.0F, 1.0F); - usx = IROUND(a[0] * 65535.0F); - usy = IROUND(a[1] * 65535.0F); - rawResult[0] = rawResult[1] = rawResult[2] = rawResult[3] - = usx | (usy << 16); - store_vector4( inst, machine, result ); - } - break; - case OPCODE_PK4B: /* pack four GLbytes into one 32-bit float */ - { - GLfloat a[4], result[4]; - GLuint ubx, uby, ubz, ubw, *rawResult = (GLuint *) result; - fetch_vector4( ctx, &inst->SrcReg[0], machine, program, a ); - a[0] = CLAMP(a[0], -128.0F / 127.0F, 1.0F); - a[1] = CLAMP(a[1], -128.0F / 127.0F, 1.0F); - a[2] = CLAMP(a[2], -128.0F / 127.0F, 1.0F); - a[3] = CLAMP(a[3], -128.0F / 127.0F, 1.0F); - ubx = IROUND(127.0F * a[0] + 128.0F); - uby = IROUND(127.0F * a[1] + 128.0F); - ubz = IROUND(127.0F * a[2] + 128.0F); - ubw = IROUND(127.0F * a[3] + 128.0F); - rawResult[0] = rawResult[1] = rawResult[2] = rawResult[3] - = ubx | (uby << 8) | (ubz << 16) | (ubw << 24); - store_vector4( inst, machine, result ); - } - break; - case OPCODE_PK4UB: /* pack four GLubytes into one 32-bit float */ - { - GLfloat a[4], result[4]; - GLuint ubx, uby, ubz, ubw, *rawResult = (GLuint *) result; - fetch_vector4( ctx, &inst->SrcReg[0], machine, program, a ); - a[0] = CLAMP(a[0], 0.0F, 1.0F); - a[1] = CLAMP(a[1], 0.0F, 1.0F); - a[2] = CLAMP(a[2], 0.0F, 1.0F); - a[3] = CLAMP(a[3], 0.0F, 1.0F); - ubx = IROUND(255.0F * a[0]); - uby = IROUND(255.0F * a[1]); - ubz = IROUND(255.0F * a[2]); - ubw = IROUND(255.0F * a[3]); - rawResult[0] = rawResult[1] = rawResult[2] = rawResult[3] - = ubx | (uby << 8) | (ubz << 16) | (ubw << 24); - store_vector4( inst, machine, result ); - } - break; - case OPCODE_POW: - { - GLfloat a[4], b[4], result[4]; - fetch_vector1( ctx, &inst->SrcReg[0], machine, program, a ); - fetch_vector1( ctx, &inst->SrcReg[1], machine, program, b ); - result[0] = result[1] = result[2] = result[3] - = (GLfloat)_mesa_pow(a[0], b[0]); - store_vector4( inst, machine, result ); - } - break; - case OPCODE_RCP: - { - GLfloat a[4], result[4]; - fetch_vector1( ctx, &inst->SrcReg[0], machine, program, a ); - if (DEBUG_FRAG) { - if (a[0] == 0) - printf("RCP(0)\n"); - else if (IS_INF_OR_NAN(a[0])) - printf("RCP(inf)\n"); - } - result[0] = result[1] = result[2] = result[3] = 1.0F / a[0]; - 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]; - } - } - break; - case OPCODE_RFL: /* reflection vector */ - { - GLfloat axis[4], dir[4], result[4], tmpX, tmpW; - fetch_vector4( ctx, &inst->SrcReg[0], machine, program, axis ); - fetch_vector4( ctx, &inst->SrcReg[1], machine, program, dir ); - tmpW = DOT3(axis, axis); - tmpX = (2.0F * DOT3(axis, dir)) / tmpW; - result[0] = tmpX * axis[0] - dir[0]; - result[1] = tmpX * axis[1] - dir[1]; - result[2] = tmpX * axis[2] - dir[2]; - /* result[3] is never written! XXX enforce in parser! */ - store_vector4( inst, machine, result ); - } - break; - case OPCODE_RSQ: /* 1 / sqrt() */ - { - GLfloat a[4], result[4]; - fetch_vector1( ctx, &inst->SrcReg[0], machine, program, a ); - a[0] = FABSF(a[0]); - result[0] = result[1] = result[2] = result[3] = INV_SQRTF(a[0]); - store_vector4( inst, machine, result ); - if (DEBUG_FRAG) { - printf("RSQ %g = 1/sqrt(|%g|)\n", result[0], a[0]); - } - } - break; - case OPCODE_SCS: /* sine and cos */ - { - GLfloat a[4], result[4]; - fetch_vector1( ctx, &inst->SrcReg[0], machine, program, a ); - result[0] = (GLfloat)_mesa_cos(a[0]); - result[1] = (GLfloat)_mesa_sin(a[0]); - result[2] = 0.0; /* undefined! */ - result[3] = 0.0; /* undefined! */ - store_vector4( inst, machine, result ); - } - break; - case OPCODE_SEQ: /* set on equal */ - { - GLfloat a[4], b[4], result[4]; - fetch_vector4( ctx, &inst->SrcReg[0], machine, program, a ); - fetch_vector4( ctx, &inst->SrcReg[1], machine, program, b ); - result[0] = (a[0] == b[0]) ? 1.0F : 0.0F; - result[1] = (a[1] == b[1]) ? 1.0F : 0.0F; - result[2] = (a[2] == b[2]) ? 1.0F : 0.0F; - result[3] = (a[3] == b[3]) ? 1.0F : 0.0F; - store_vector4( inst, machine, result ); - } - break; - case OPCODE_SFL: /* set false, operands ignored */ - { - static const GLfloat result[4] = { 0.0F, 0.0F, 0.0F, 0.0F }; - store_vector4( inst, machine, result ); - } - break; - case OPCODE_SGE: /* set on greater or equal */ - { - GLfloat a[4], b[4], result[4]; - fetch_vector4( ctx, &inst->SrcReg[0], machine, program, a ); - fetch_vector4( ctx, &inst->SrcReg[1], machine, program, b ); - result[0] = (a[0] >= b[0]) ? 1.0F : 0.0F; - result[1] = (a[1] >= b[1]) ? 1.0F : 0.0F; - result[2] = (a[2] >= b[2]) ? 1.0F : 0.0F; - result[3] = (a[3] >= b[3]) ? 1.0F : 0.0F; - store_vector4( inst, machine, result ); - } - break; - case OPCODE_SGT: /* set on greater */ - { - GLfloat a[4], b[4], result[4]; - fetch_vector4( ctx, &inst->SrcReg[0], machine, program, a ); - fetch_vector4( ctx, &inst->SrcReg[1], machine, program, b ); - result[0] = (a[0] > b[0]) ? 1.0F : 0.0F; - result[1] = (a[1] > b[1]) ? 1.0F : 0.0F; - result[2] = (a[2] > b[2]) ? 1.0F : 0.0F; - result[3] = (a[3] > b[3]) ? 1.0F : 0.0F; - store_vector4( inst, machine, result ); - } - break; - case OPCODE_SIN: - { - GLfloat a[4], result[4]; - fetch_vector1( ctx, &inst->SrcReg[0], machine, program, a ); - result[0] = result[1] = result[2] = result[3] - = (GLfloat) _mesa_sin(a[0]); - store_vector4( inst, machine, result ); - } - break; - case OPCODE_SLE: /* set on less or equal */ - { - GLfloat a[4], b[4], result[4]; - fetch_vector4( ctx, &inst->SrcReg[0], machine, program, a ); - fetch_vector4( ctx, &inst->SrcReg[1], machine, program, b ); - result[0] = (a[0] <= b[0]) ? 1.0F : 0.0F; - result[1] = (a[1] <= b[1]) ? 1.0F : 0.0F; - result[2] = (a[2] <= b[2]) ? 1.0F : 0.0F; - result[3] = (a[3] <= b[3]) ? 1.0F : 0.0F; - store_vector4( inst, machine, result ); - } - break; - case OPCODE_SLT: /* set on less */ - { - GLfloat a[4], b[4], result[4]; - fetch_vector4( ctx, &inst->SrcReg[0], machine, program, a ); - fetch_vector4( ctx, &inst->SrcReg[1], machine, program, b ); - result[0] = (a[0] < b[0]) ? 1.0F : 0.0F; - result[1] = (a[1] < b[1]) ? 1.0F : 0.0F; - result[2] = (a[2] < b[2]) ? 1.0F : 0.0F; - result[3] = (a[3] < b[3]) ? 1.0F : 0.0F; - store_vector4( inst, machine, result ); - } - break; - case OPCODE_SNE: /* set on not equal */ - { - GLfloat a[4], b[4], result[4]; - fetch_vector4( ctx, &inst->SrcReg[0], machine, program, a ); - fetch_vector4( ctx, &inst->SrcReg[1], machine, program, b ); - result[0] = (a[0] != b[0]) ? 1.0F : 0.0F; - result[1] = (a[1] != b[1]) ? 1.0F : 0.0F; - result[2] = (a[2] != b[2]) ? 1.0F : 0.0F; - result[3] = (a[3] != b[3]) ? 1.0F : 0.0F; - store_vector4( inst, machine, result ); - } - break; - case OPCODE_STR: /* set true, operands ignored */ - { - static const GLfloat result[4] = { 1.0F, 1.0F, 1.0F, 1.0F }; - store_vector4( inst, machine, result ); - } - break; - case OPCODE_SUB: - { - GLfloat a[4], b[4], result[4]; - fetch_vector4( ctx, &inst->SrcReg[0], machine, program, a ); - fetch_vector4( ctx, &inst->SrcReg[1], machine, program, b ); - result[0] = a[0] - b[0]; - result[1] = a[1] - b[1]; - result[2] = a[2] - b[2]; - result[3] = a[3] - b[3]; - store_vector4( inst, machine, result ); - if (DEBUG_FRAG) { - printf("SUB (%g %g %g %g) = (%g %g %g %g) - (%g %g %g %g)\n", - result[0], result[1], result[2], result[3], - a[0], a[1], a[2], a[3], b[0], b[1], b[2], b[3]); - } - } - break; - case OPCODE_SWZ: /* extended swizzle */ - { - const struct prog_src_register *source = &inst->SrcReg[0]; - const GLfloat *src = get_register_pointer(ctx, source, - machine, program); - GLfloat result[4]; - GLuint i; - for (i = 0; i < 4; i++) { - const GLuint swz = GET_SWZ(source->Swizzle, i); - if (swz == SWIZZLE_ZERO) - result[i] = 0.0; - else if (swz == SWIZZLE_ONE) - result[i] = 1.0; - else { - ASSERT(swz >= 0); - ASSERT(swz <= 3); - result[i] = src[swz]; - } - if (source->NegateBase & (1 << i)) - result[i] = -result[i]; - } - store_vector4( inst, machine, result ); - } - break; - case OPCODE_TEX: /* Both ARB and NV frag prog */ - /* Texel lookup */ - { - /* Note: only use the precomputed lambda value when we're - * sampling texture unit [K] with texcoord[K]. - * Otherwise, the lambda value may have no relation to the - * instruction's texcoord or texture image. Using the wrong - * lambda is usually bad news. - * The rest of the time, just use zero (until we get a more - * sophisticated way of computing lambda). - */ - GLfloat coord[4], color[4], lambda; - if (inst->SrcReg[0].File == PROGRAM_INPUT && - inst->SrcReg[0].Index == FRAG_ATTRIB_TEX0+inst->TexSrcUnit) - lambda = span->array->lambda[inst->TexSrcUnit][column]; - else - lambda = 0.0; - fetch_vector4(ctx, &inst->SrcReg[0], machine, program, coord); - fetch_texel( ctx, coord, lambda, inst->TexSrcUnit, color ); - if (DEBUG_FRAG) { - printf("TEX (%g, %g, %g, %g) = texture[%d][%g, %g, %g, %g], " - "lod %f\n", - color[0], color[1], color[2], color[3], - inst->TexSrcUnit, - coord[0], coord[1], coord[2], coord[3], lambda); - } - store_vector4( inst, machine, color ); - } - break; - case OPCODE_TXB: /* GL_ARB_fragment_program only */ - /* Texel lookup with LOD bias */ - { - GLfloat coord[4], color[4], lambda, bias; - if (inst->SrcReg[0].File == PROGRAM_INPUT && - inst->SrcReg[0].Index == FRAG_ATTRIB_TEX0+inst->TexSrcUnit) - lambda = span->array->lambda[inst->TexSrcUnit][column]; - else - lambda = 0.0; - fetch_vector4(ctx, &inst->SrcReg[0], machine, program, coord); - /* coord[3] is the bias to add to lambda */ - bias = ctx->Texture.Unit[inst->TexSrcUnit].LodBias - + ctx->Texture.Unit[inst->TexSrcUnit]._Current->LodBias - + coord[3]; - fetch_texel(ctx, coord, lambda + bias, inst->TexSrcUnit, color); - store_vector4( inst, machine, color ); - } - break; - case OPCODE_TXD: /* GL_NV_fragment_program only */ - /* Texture lookup w/ partial derivatives for LOD */ - { - GLfloat texcoord[4], dtdx[4], dtdy[4], color[4]; - fetch_vector4( ctx, &inst->SrcReg[0], machine, program, texcoord ); - fetch_vector4( ctx, &inst->SrcReg[1], machine, program, dtdx ); - fetch_vector4( ctx, &inst->SrcReg[2], machine, program, dtdy ); - fetch_texel_deriv( ctx, texcoord, dtdx, dtdy, inst->TexSrcUnit, - color ); - store_vector4( inst, machine, color ); - } - break; - case OPCODE_TXP: /* GL_ARB_fragment_program only */ - /* Texture lookup w/ projective divide */ - { - GLfloat texcoord[4], color[4], lambda; - if (inst->SrcReg[0].File == PROGRAM_INPUT && - inst->SrcReg[0].Index == FRAG_ATTRIB_TEX0+inst->TexSrcUnit) - lambda = span->array->lambda[inst->TexSrcUnit][column]; - else - lambda = 0.0; - fetch_vector4(ctx, &inst->SrcReg[0], machine, program,texcoord); - /* Not so sure about this test - if texcoord[3] is - * zero, we'd probably be fine except for an ASSERT in - * IROUND_POS() which gets triggered by the inf values created. - */ - if (texcoord[3] != 0.0) { - texcoord[0] /= texcoord[3]; - texcoord[1] /= texcoord[3]; - texcoord[2] /= texcoord[3]; - } - fetch_texel( ctx, texcoord, lambda, inst->TexSrcUnit, color ); - store_vector4( inst, machine, color ); - } - break; - case OPCODE_TXP_NV: /* GL_NV_fragment_program only */ - /* Texture lookup w/ projective divide */ - { - GLfloat texcoord[4], color[4], lambda; - if (inst->SrcReg[0].File == PROGRAM_INPUT && - inst->SrcReg[0].Index == FRAG_ATTRIB_TEX0+inst->TexSrcUnit) - lambda = span->array->lambda[inst->TexSrcUnit][column]; - else - lambda = 0.0; - fetch_vector4(ctx, &inst->SrcReg[0], machine, program,texcoord); - if (inst->TexSrcTarget != TEXTURE_CUBE_INDEX && - texcoord[3] != 0.0) { - texcoord[0] /= texcoord[3]; - texcoord[1] /= texcoord[3]; - texcoord[2] /= texcoord[3]; - } - fetch_texel( ctx, texcoord, lambda, inst->TexSrcUnit, color ); - store_vector4( inst, machine, color ); - } - break; - case OPCODE_UP2H: /* unpack two 16-bit floats */ - { - GLfloat a[4], result[4]; - const GLuint *rawBits = (const GLuint *) a; - GLhalfNV hx, hy; - fetch_vector1( ctx, &inst->SrcReg[0], machine, program, a ); - hx = rawBits[0] & 0xffff; - hy = rawBits[0] >> 16; - result[0] = result[2] = _mesa_half_to_float(hx); - result[1] = result[3] = _mesa_half_to_float(hy); - store_vector4( inst, machine, result ); - } - break; - case OPCODE_UP2US: /* unpack two GLushorts */ - { - GLfloat a[4], result[4]; - const GLuint *rawBits = (const GLuint *) a; - GLushort usx, usy; - fetch_vector1( ctx, &inst->SrcReg[0], machine, program, a ); - usx = rawBits[0] & 0xffff; - usy = rawBits[0] >> 16; - result[0] = result[2] = usx * (1.0f / 65535.0f); - result[1] = result[3] = usy * (1.0f / 65535.0f); - store_vector4( inst, machine, result ); - } - break; - case OPCODE_UP4B: /* unpack four GLbytes */ - { - GLfloat a[4], result[4]; - const GLuint *rawBits = (const GLuint *) a; - fetch_vector1( ctx, &inst->SrcReg[0], machine, program, a ); - result[0] = (((rawBits[0] >> 0) & 0xff) - 128) / 127.0F; - result[1] = (((rawBits[0] >> 8) & 0xff) - 128) / 127.0F; - result[2] = (((rawBits[0] >> 16) & 0xff) - 128) / 127.0F; - result[3] = (((rawBits[0] >> 24) & 0xff) - 128) / 127.0F; - store_vector4( inst, machine, result ); - } - break; - case OPCODE_UP4UB: /* unpack four GLubytes */ - { - GLfloat a[4], result[4]; - const GLuint *rawBits = (const GLuint *) a; - fetch_vector1( ctx, &inst->SrcReg[0], machine, program, a ); - result[0] = ((rawBits[0] >> 0) & 0xff) / 255.0F; - result[1] = ((rawBits[0] >> 8) & 0xff) / 255.0F; - result[2] = ((rawBits[0] >> 16) & 0xff) / 255.0F; - result[3] = ((rawBits[0] >> 24) & 0xff) / 255.0F; - store_vector4( inst, machine, result ); - } - break; - case OPCODE_XPD: /* cross product */ - { - GLfloat a[4], b[4], result[4]; - fetch_vector4( ctx, &inst->SrcReg[0], machine, program, a ); - fetch_vector4( ctx, &inst->SrcReg[1], machine, program, b ); - result[0] = a[1] * b[2] - a[2] * b[1]; - result[1] = a[2] * b[0] - a[0] * b[2]; - result[2] = a[0] * b[1] - a[1] * b[0]; - result[3] = 1.0; - store_vector4( inst, machine, result ); - } - break; - case OPCODE_X2D: /* 2-D matrix transform */ - { - GLfloat a[4], b[4], c[4], result[4]; - fetch_vector4( ctx, &inst->SrcReg[0], machine, program, a ); - fetch_vector4( ctx, &inst->SrcReg[1], machine, program, b ); - fetch_vector4( ctx, &inst->SrcReg[2], machine, program, c ); - result[0] = a[0] + b[0] * c[0] + b[1] * c[1]; - result[1] = a[1] + b[0] * c[2] + b[1] * c[3]; - result[2] = a[2] + b[0] * c[0] + b[1] * c[1]; - result[3] = a[3] + b[0] * c[2] + b[1] * c[3]; - store_vector4( inst, machine, result ); - } - break; - case OPCODE_PRINT: - { - if (inst->SrcReg[0].File != -1) { - GLfloat a[4]; - fetch_vector4( ctx, &inst->SrcReg[0], machine, program, a); - _mesa_printf("%s%g, %g, %g, %g\n", (const char *) inst->Data, - a[0], a[1], a[2], a[3]); - } - else { - _mesa_printf("%s\n", (const char *) inst->Data); - } - } - break; - case OPCODE_END: - return GL_TRUE; - default: - _mesa_problem(ctx, "Bad opcode %d in _mesa_exec_fragment_program", - inst->Opcode); - return GL_TRUE; /* return value doesn't matter */ - } - } - return GL_TRUE; -} - - -/** - * Initialize the virtual fragment program machine state prior to running - * fragment program on a fragment. This involves initializing the input - * registers, condition codes, etc. - * \param machine the virtual machine state to init - * \param program the fragment program we're about to run - * \param span the span of pixels we'll operate on - * \param col which element (column) of the span we'll operate on - */ -static void -init_machine( GLcontext *ctx, struct fp_machine *machine, - const struct gl_fragment_program *program, - const SWspan *span, GLuint col ) -{ - GLuint inputsRead = program->Base.InputsRead; - GLuint u; - - if (ctx->FragmentProgram.CallbackEnabled) - inputsRead = ~0; - - if (program->Base.Target == GL_FRAGMENT_PROGRAM_NV) { - /* Clear temporary registers (undefined for ARB_f_p) */ - _mesa_bzero(machine->Temporaries, - MAX_NV_FRAGMENT_PROGRAM_TEMPS * 4 * sizeof(GLfloat)); - } - - /* Load input registers */ - if (inputsRead & (1 << FRAG_ATTRIB_WPOS)) { - GLfloat *wpos = machine->Inputs[FRAG_ATTRIB_WPOS]; - ASSERT(span->arrayMask & SPAN_Z); - if (span->arrayMask & SPAN_XY) { - wpos[0] = (GLfloat) span->array->x[col]; - wpos[1] = (GLfloat) span->array->y[col]; - } - else { - wpos[0] = (GLfloat) span->x + col; - wpos[1] = (GLfloat) span->y; - } - wpos[2] = (GLfloat) span->array->z[col] / ctx->DrawBuffer->_DepthMaxF; - wpos[3] = span->w + col * span->dwdx; - } - if (inputsRead & (1 << FRAG_ATTRIB_COL0)) { - ASSERT(span->arrayMask & SPAN_RGBA); - COPY_4V(machine->Inputs[FRAG_ATTRIB_COL0], - span->array->color.sz4.rgba[col]); - } - if (inputsRead & (1 << FRAG_ATTRIB_COL1)) { - ASSERT(span->arrayMask & SPAN_SPEC); - COPY_4V(machine->Inputs[FRAG_ATTRIB_COL1], - span->array->color.sz4.spec[col]); - } - if (inputsRead & (1 << FRAG_ATTRIB_FOGC)) { - GLfloat *fogc = machine->Inputs[FRAG_ATTRIB_FOGC]; - ASSERT(span->arrayMask & SPAN_FOG); - fogc[0] = span->array->fog[col]; - fogc[1] = 0.0F; - fogc[2] = 0.0F; - fogc[3] = 0.0F; - } - for (u = 0; u < ctx->Const.MaxTextureCoordUnits; u++) { - if (inputsRead & (1 << (FRAG_ATTRIB_TEX0 + u))) { - GLfloat *tex = machine->Inputs[FRAG_ATTRIB_TEX0 + u]; - /*ASSERT(ctx->Texture._EnabledCoordUnits & (1 << u));*/ - COPY_4V(tex, span->array->texcoords[u][col]); - /*ASSERT(tex[0] != 0 || tex[1] != 0 || tex[2] != 0);*/ - } - } - - /* init condition codes */ - machine->CondCodes[0] = COND_EQ; - machine->CondCodes[1] = COND_EQ; - machine->CondCodes[2] = COND_EQ; - machine->CondCodes[3] = COND_EQ; - - /* init call stack */ - machine->StackDepth = 0; -} - - -/** - * Run fragment program on the pixels in span from 'start' to 'end' - 1. - */ -static void -run_program(GLcontext *ctx, SWspan *span, GLuint start, GLuint end) -{ - const struct gl_fragment_program *program = ctx->FragmentProgram._Current; - struct fp_machine machine; - GLuint i; - - CurrentMachine = &machine; - - for (i = start; i < end; i++) { - if (span->array->mask[i]) { - init_machine(ctx, &machine, program, span, i); - - if (execute_program(ctx, program, ~0, &machine, span, i)) { - /* Store result color */ - COPY_4V(span->array->color.sz4.rgba[i], - machine.Outputs[FRAG_RESULT_COLR]); - - /* Store result depth/z */ - if (program->Base.OutputsWritten & (1 << FRAG_RESULT_DEPR)) { - const GLfloat depth = machine.Outputs[FRAG_RESULT_DEPR][2]; - if (depth <= 0.0) - span->array->z[i] = 0; - else if (depth >= 1.0) - span->array->z[i] = ctx->DrawBuffer->_DepthMax; - else - span->array->z[i] = IROUND(depth * ctx->DrawBuffer->_DepthMaxF); - } - } - else { - /* killed fragment */ - span->array->mask[i] = GL_FALSE; - span->writeAll = GL_FALSE; - } - } - } - - CurrentMachine = NULL; -} - - -/** - * Execute the current fragment program for all the fragments - * in the given span. - */ -void -_swrast_exec_fragment_program( GLcontext *ctx, SWspan *span ) -{ - const struct gl_fragment_program *program = ctx->FragmentProgram._Current; - - /* incoming colors should be floats */ - ASSERT(span->array->ChanType == GL_FLOAT); - - ctx->_CurrentProgram = GL_FRAGMENT_PROGRAM_ARB; /* or NV, doesn't matter */ - - run_program(ctx, span, 0, span->end); - - if (program->Base.OutputsWritten & (1 << FRAG_RESULT_DEPR)) { - span->interpMask &= ~SPAN_Z; - span->arrayMask |= SPAN_Z; - } - - ctx->_CurrentProgram = 0; -} - diff --git a/src/mesa/swrast/s_pointtemp.h b/src/mesa/swrast/s_pointtemp.h index 083f1ebe83..cc6f999b91 100644 --- a/src/mesa/swrast/s_pointtemp.h +++ b/src/mesa/swrast/s_pointtemp.h @@ -88,8 +88,8 @@ NAME ( GLcontext *ctx, const SWvertex *vert ) const GLuint colorIndex = (GLuint) vert->index; /* XXX round? */ #endif #if FLAGS & TEXTURE - GLfloat texcoord[MAX_TEXTURE_COORD_UNITS][4]; - GLuint u; + GLfloat attrib[FRAG_ATTRIB_MAX][4]; /* texture & varying */ + GLuint attr; #endif SWcontext *swrast = SWRAST_CONTEXT(ctx); SWspan *span = &(swrast->PointSpan); @@ -107,8 +107,9 @@ NAME ( GLcontext *ctx, const SWvertex *vert ) */ span->interpMask = SPAN_FOG; span->arrayMask = SPAN_XY | SPAN_Z; - span->fog = vert->fog; - span->fogStep = 0.0; + span->attrStart[FRAG_ATTRIB_FOGC][0] = vert->fog; + span->attrStepX[FRAG_ATTRIB_FOGC][0] = 0.0; + span->attrStepY[FRAG_ATTRIB_FOGC][0] = 0.0; #if FLAGS & RGBA span->arrayMask |= SPAN_RGBA; #endif @@ -120,31 +121,31 @@ NAME ( GLcontext *ctx, const SWvertex *vert ) #endif #if FLAGS & TEXTURE span->arrayMask |= (SPAN_TEXTURE | SPAN_LAMBDA); - if (ctx->FragmentProgram._Active) { + if (ctx->FragmentProgram._Current) { /* Don't divide texture s,t,r by q (use TXP to do that) */ - for (u = 0; u < ctx->Const.MaxTextureUnits; u++) { - if (ctx->Texture._EnabledCoordUnits & (1 << u)) { - COPY_4V(texcoord[u], vert->texcoord[u]); + for (attr = swrast->_MinFragmentAttrib; attr < swrast->_MaxFragmentAttrib; attr++) { + if (swrast->_FragmentAttribs & (1 << attr)) { + COPY_4V(attrib[attr], vert->attrib[attr]); } } } else { /* Divide texture s,t,r by q here */ - for (u = 0; u < ctx->Const.MaxTextureUnits; u++) { - if (ctx->Texture._EnabledCoordUnits & (1 << u)) { - const GLfloat q = vert->texcoord[u][3]; + for (attr = swrast->_MinFragmentAttrib; attr < swrast->_MaxFragmentAttrib; attr++) { + if (swrast->_FragmentAttribs & (1 << attr)) { + const GLfloat q = vert->attrib[attr][3]; const GLfloat invQ = (q == 0.0F || q == 1.0F) ? 1.0F : (1.0F / q); - texcoord[u][0] = vert->texcoord[u][0] * invQ; - texcoord[u][1] = vert->texcoord[u][1] * invQ; - texcoord[u][2] = vert->texcoord[u][2] * invQ; - texcoord[u][3] = q; + attrib[attr][0] = vert->attrib[attr][0] * invQ; + attrib[attr][1] = vert->attrib[attr][1] * invQ; + attrib[attr][2] = vert->attrib[attr][2] * invQ; + attrib[attr][3] = q; } } } /* need these for fragment programs */ - span->w = 1.0F; - span->dwdx = 0.0F; - span->dwdy = 0.0F; + span->attrStart[FRAG_ATTRIB_WPOS][3] = 1.0F; + span->attrStepX[FRAG_ATTRIB_WPOS][3] = 0.0F; + span->attrStepY[FRAG_ATTRIB_WPOS][3] = 0.0F; #endif #if FLAGS & SMOOTH span->arrayMask |= SPAN_COVERAGE; @@ -259,7 +260,7 @@ NAME ( GLcontext *ctx, const SWvertex *vert ) count = span->end = 0; } for (x = xmin; x <= xmax; x++) { -#if FLAGS & (SPRITE | TEXTURE) +#if FLAGS & SPRITE GLuint u; #endif @@ -278,10 +279,13 @@ NAME ( GLcontext *ctx, const SWvertex *vert ) span->array->index[count] = colorIndex; #endif #if FLAGS & TEXTURE - for (u = 0; u < ctx->Const.MaxTextureUnits; u++) { - if (ctx->Texture._EnabledCoordUnits & (1 << u)) { - COPY_4V(span->array->texcoords[u][count], texcoord[u]); - span->array->lambda[u][count] = 0.0; + for (attr = swrast->_MinFragmentAttrib; attr < swrast->_MaxFragmentAttrib; attr++) { + if (swrast->_FragmentAttribs & (1 << attr)) { + COPY_4V(span->array->attribs[attr][count], attrib[attr]); + if (attr < FRAG_ATTRIB_VAR0) { + const GLuint u = attr - FRAG_ATTRIB_TEX0; + span->array->lambda[u][count] = 0.0; + } } } #endif @@ -328,6 +332,7 @@ NAME ( GLcontext *ctx, const SWvertex *vert ) #if FLAGS & SPRITE for (u = 0; u < ctx->Const.MaxTextureUnits; u++) { + GLuint attr = FRAG_ATTRIB_TEX0 + u; if (ctx->Texture.Unit[u]._ReallyEnabled) { if (ctx->Point.CoordReplace[u]) { GLfloat s = 0.5F + (x + 0.5F - vert->win[0]) / size; @@ -339,17 +344,18 @@ NAME ( GLcontext *ctx, const SWvertex *vert ) if (ctx->Point.SpriteRMode == GL_ZERO) r = 0.0F; else if (ctx->Point.SpriteRMode == GL_S) - r = vert->texcoord[u][0]; + r = vert->attrib[attr][0]; else /* GL_R */ - r = vert->texcoord[u][2]; - span->array->texcoords[u][count][0] = s; - span->array->texcoords[u][count][1] = t; - span->array->texcoords[u][count][2] = r; - span->array->texcoords[u][count][3] = 1.0F; + r = vert->attrib[attr][2]; + span->array->attribs[attr][count][0] = s; + span->array->attribs[attr][count][1] = t; + span->array->attribs[attr][count][2] = r; + span->array->attribs[attr][count][3] = 1.0F; span->array->lambda[u][count] = 0.0; /* XXX fix? */ } else { - COPY_4V(span->array->texcoords[u][count], vert->texcoord[u]); + COPY_4V(span->array->attribs[attr][count], + vert->attrib[attr]); } } } @@ -400,9 +406,9 @@ NAME ( GLcontext *ctx, const SWvertex *vert ) span->array->index[count] = colorIndex; #endif #if FLAGS & TEXTURE - for (u = 0; u < ctx->Const.MaxTextureUnits; u++) { - if (ctx->Texture.Unit[u]._ReallyEnabled) { - COPY_4V(span->array->texcoords[u][count], texcoord[u]); + for (attr = swrast->_MinFragmentAttrib; attr < swrast->_MaxFragmentAttrib; attr++) { + if (swrast->_FragmentAttribs & (1 << attr)) { + COPY_4V(span->array->attribs[attr][count], attribs[attr]); } } #endif diff --git a/src/mesa/swrast/s_readpix.c b/src/mesa/swrast/s_readpix.c index 7dc48aec68..fe9a70f4ea 100644 --- a/src/mesa/swrast/s_readpix.c +++ b/src/mesa/swrast/s_readpix.c @@ -404,7 +404,7 @@ read_rgba_pixels( GLcontext *ctx, /* no convolution */ const GLint dstStride = _mesa_image_row_stride(packing, width, format, type); - GLfloat (*rgba)[4] = swrast->SpanArrays->color.sz4.rgba; + GLfloat (*rgba)[4] = swrast->SpanArrays->attribs[FRAG_ATTRIB_COL0]; GLint row; GLubyte *dst = (GLubyte *) _mesa_image_address2d(packing, pixels, width, height, diff --git a/src/mesa/swrast/s_span.c b/src/mesa/swrast/s_span.c index cca1864ea4..fa7761269d 100644 --- a/src/mesa/swrast/s_span.c +++ b/src/mesa/swrast/s_span.c @@ -39,14 +39,13 @@ #include "s_atifragshader.h" #include "s_alpha.h" -#include "s_arbshader.h" #include "s_blend.h" #include "s_context.h" #include "s_depth.h" #include "s_fog.h" #include "s_logic.h" #include "s_masking.h" -#include "s_nvfragprog.h" +#include "s_fragprog.h" #include "s_span.h" #include "s_stencil.h" #include "s_texcombine.h" @@ -76,8 +75,10 @@ _swrast_span_default_z( GLcontext *ctx, SWspan *span ) void _swrast_span_default_fog( GLcontext *ctx, SWspan *span ) { - span->fog = _swrast_z_to_fogfactor(ctx, ctx->Current.RasterDistance); - span->fogStep = span->dfogdx = span->dfogdy = 0.0F; + span->attrStart[FRAG_ATTRIB_FOGC][0] + = _swrast_z_to_fogfactor(ctx, ctx->Current.RasterDistance); + span->attrStepX[FRAG_ATTRIB_FOGC][0] = 0.0; + span->attrStepY[FRAG_ATTRIB_FOGC][0] = 0.0; span->interpMask |= SPAN_FOG; } @@ -129,22 +130,23 @@ _swrast_span_default_texcoords( GLcontext *ctx, SWspan *span ) { GLuint i; for (i = 0; i < ctx->Const.MaxTextureCoordUnits; i++) { + const GLuint attr = FRAG_ATTRIB_TEX0 + i; const GLfloat *tc = ctx->Current.RasterTexCoords[i]; - if (ctx->FragmentProgram._Enabled || ctx->ATIFragmentShader._Enabled) { - COPY_4V(span->tex[i], tc); + if (ctx->FragmentProgram._Current || ctx->ATIFragmentShader._Enabled) { + COPY_4V(span->attrStart[attr], tc); } else if (tc[3] > 0.0F) { /* use (s/q, t/q, r/q, 1) */ - span->tex[i][0] = tc[0] / tc[3]; - span->tex[i][1] = tc[1] / tc[3]; - span->tex[i][2] = tc[2] / tc[3]; - span->tex[i][3] = 1.0; + span->attrStart[attr][0] = tc[0] / tc[3]; + span->attrStart[attr][1] = tc[1] / tc[3]; + span->attrStart[attr][2] = tc[2] / tc[3]; + span->attrStart[attr][3] = 1.0; } else { - ASSIGN_4V(span->tex[i], 0.0F, 0.0F, 0.0F, 1.0F); + ASSIGN_4V(span->attrStart[attr], 0.0F, 0.0F, 0.0F, 1.0F); } - ASSIGN_4V(span->texStepX[i], 0.0F, 0.0F, 0.0F, 0.0F); - ASSIGN_4V(span->texStepY[i], 0.0F, 0.0F, 0.0F, 0.0F); + ASSIGN_4V(span->attrStepX[attr], 0.0F, 0.0F, 0.0F, 0.0F); + ASSIGN_4V(span->attrStepY[attr], 0.0F, 0.0F, 0.0F, 0.0F); } span->interpMask |= SPAN_TEXTURE; } @@ -240,7 +242,7 @@ interpolate_colors(SWspan *span) #endif case GL_FLOAT: { - GLfloat (*rgba)[4] = span->array->color.sz4.rgba; + GLfloat (*rgba)[4] = span->array->attribs[FRAG_ATTRIB_COL0]; GLfloat r, g, b, a, dr, dg, db, da; r = span->red; g = span->green; @@ -352,7 +354,7 @@ interpolate_specular(SWspan *span) #endif case GL_FLOAT: { - GLfloat (*spec)[4] = span->array->color.sz4.spec; + GLfloat (*spec)[4] = span->array->attribs[FRAG_ATTRIB_COL1]; #if CHAN_BITS <= 16 GLfloat r = CHAN_TO_FLOAT(FixedToChan(span->specRed)); GLfloat g = CHAN_TO_FLOAT(FixedToChan(span->specGreen)); @@ -431,15 +433,15 @@ interpolate_indexes(GLcontext *ctx, SWspan *span) static INLINE void interpolate_fog(const GLcontext *ctx, SWspan *span) { - GLfloat *fog = span->array->fog; - const GLfloat fogStep = span->fogStep; - GLfloat fogCoord = span->fog; + GLfloat (*fog)[4] = span->array->attribs[FRAG_ATTRIB_FOGC]; + const GLfloat fogStep = span->attrStepX[FRAG_ATTRIB_FOGC][0]; + GLfloat fogCoord = span->attrStart[FRAG_ATTRIB_FOGC][0]; const GLuint haveW = (span->interpMask & SPAN_W); - const GLfloat wStep = haveW ? span->dwdx : 0.0F; - GLfloat w = haveW ? span->w : 1.0F; + const GLfloat wStep = haveW ? span->attrStepX[FRAG_ATTRIB_WPOS][3] : 0.0F; + GLfloat w = haveW ? span->attrStart[FRAG_ATTRIB_WPOS][3] : 1.0F; GLuint i; for (i = 0; i < span->end; i++) { - fog[i] = fogCoord / w; + fog[i][0] = fogCoord / w; fogCoord += fogStep; w += wStep; } @@ -539,309 +541,188 @@ _swrast_compute_lambda(GLfloat dsdx, GLfloat dsdy, GLfloat dtdx, GLfloat dtdy, static void interpolate_texcoords(GLcontext *ctx, SWspan *span) { + const GLuint maxUnit + = (ctx->Texture._EnabledCoordUnits > 1) ? ctx->Const.MaxTextureUnits : 1; + GLuint u; + ASSERT(span->interpMask & SPAN_TEXTURE); ASSERT(!(span->arrayMask & SPAN_TEXTURE)); - if (ctx->Texture._EnabledCoordUnits > 1) { - /* multitexture */ - GLuint u; - span->arrayMask |= SPAN_TEXTURE; - /* XXX CoordUnits vs. ImageUnits */ - for (u = 0; u < ctx->Const.MaxTextureUnits; u++) { - if (ctx->Texture._EnabledCoordUnits & (1 << u)) { - const struct gl_texture_object *obj =ctx->Texture.Unit[u]._Current; - GLfloat texW, texH; - GLboolean needLambda; - if (obj) { - const struct gl_texture_image *img = obj->Image[0][obj->BaseLevel]; - needLambda = (obj->MinFilter != obj->MagFilter) - || ctx->FragmentProgram._Enabled; - texW = img->WidthScale; - texH = img->HeightScale; - } - else { - /* using a fragment program */ - texW = 1.0; - texH = 1.0; - needLambda = GL_FALSE; - } - if (needLambda) { - GLfloat (*texcoord)[4] = span->array->texcoords[u]; - GLfloat *lambda = span->array->lambda[u]; - const GLfloat dsdx = span->texStepX[u][0]; - const GLfloat dsdy = span->texStepY[u][0]; - const GLfloat dtdx = span->texStepX[u][1]; - const GLfloat dtdy = span->texStepY[u][1]; - const GLfloat drdx = span->texStepX[u][2]; - const GLfloat dqdx = span->texStepX[u][3]; - const GLfloat dqdy = span->texStepY[u][3]; - GLfloat s = span->tex[u][0]; - GLfloat t = span->tex[u][1]; - GLfloat r = span->tex[u][2]; - GLfloat q = span->tex[u][3]; - GLuint i; - if (ctx->FragmentProgram._Enabled || ctx->ATIFragmentShader._Enabled || - ctx->ShaderObjects._FragmentShaderPresent) { - /* do perspective correction but don't divide s, t, r by q */ - const GLfloat dwdx = span->dwdx; - GLfloat w = span->w; - for (i = 0; i < span->end; i++) { - const GLfloat invW = 1.0F / w; - texcoord[i][0] = s * invW; - texcoord[i][1] = t * invW; - texcoord[i][2] = r * invW; - texcoord[i][3] = q * invW; - lambda[i] = _swrast_compute_lambda(dsdx, dsdy, dtdx, dtdy, - dqdx, dqdy, texW, texH, - s, t, q, invW); - s += dsdx; - t += dtdx; - r += drdx; - q += dqdx; - w += dwdx; - } + span->arrayMask |= SPAN_TEXTURE; + + /* XXX CoordUnits vs. ImageUnits */ + for (u = 0; u < maxUnit; u++) { + if (ctx->Texture._EnabledCoordUnits & (1 << u)) { + const GLuint attr = FRAG_ATTRIB_TEX0 + u; + const struct gl_texture_object *obj = ctx->Texture.Unit[u]._Current; + GLfloat texW, texH; + GLboolean needLambda; + GLfloat (*texcoord)[4] = span->array->attribs[attr]; + GLfloat *lambda = span->array->lambda[u]; + const GLfloat dsdx = span->attrStepX[attr][0]; + const GLfloat dsdy = span->attrStepY[attr][0]; + const GLfloat dtdx = span->attrStepX[attr][1]; + const GLfloat dtdy = span->attrStepY[attr][1]; + const GLfloat drdx = span->attrStepX[attr][2]; + const GLfloat dqdx = span->attrStepX[attr][3]; + const GLfloat dqdy = span->attrStepY[attr][3]; + GLfloat s = span->attrStart[attr][0]; + GLfloat t = span->attrStart[attr][1]; + GLfloat r = span->attrStart[attr][2]; + GLfloat q = span->attrStart[attr][3]; + + if (obj) { + const struct gl_texture_image *img = obj->Image[0][obj->BaseLevel]; + needLambda = (obj->MinFilter != obj->MagFilter) + || ctx->FragmentProgram._Current; + texW = img->WidthScale; + texH = img->HeightScale; + } + else { + /* using a fragment program */ + texW = 1.0; + texH = 1.0; + needLambda = GL_FALSE; + } + if (needLambda) { + GLuint i; + if (ctx->FragmentProgram._Current + || ctx->ATIFragmentShader._Enabled) { + /* do perspective correction but don't divide s, t, r by q */ + const GLfloat dwdx = span->attrStepX[FRAG_ATTRIB_WPOS][3]; + GLfloat w = span->attrStart[FRAG_ATTRIB_WPOS][3]; + for (i = 0; i < span->end; i++) { + const GLfloat invW = 1.0F / w; + texcoord[i][0] = s * invW; + texcoord[i][1] = t * invW; + texcoord[i][2] = r * invW; + texcoord[i][3] = q * invW; + lambda[i] = _swrast_compute_lambda(dsdx, dsdy, dtdx, dtdy, + dqdx, dqdy, texW, texH, + s, t, q, invW); + s += dsdx; + t += dtdx; + r += drdx; + q += dqdx; + w += dwdx; } - else { - for (i = 0; i < span->end; i++) { - const GLfloat invQ = (q == 0.0F) ? 1.0F : (1.0F / q); - texcoord[i][0] = s * invQ; - texcoord[i][1] = t * invQ; - texcoord[i][2] = r * invQ; - texcoord[i][3] = q; - lambda[i] = _swrast_compute_lambda(dsdx, dsdy, dtdx, dtdy, - dqdx, dqdy, texW, texH, - s, t, q, invQ); - s += dsdx; - t += dtdx; - r += drdx; - q += dqdx; - } - } - span->arrayMask |= SPAN_LAMBDA; } else { - GLfloat (*texcoord)[4] = span->array->texcoords[u]; - GLfloat *lambda = span->array->lambda[u]; - const GLfloat dsdx = span->texStepX[u][0]; - const GLfloat dtdx = span->texStepX[u][1]; - const GLfloat drdx = span->texStepX[u][2]; - const GLfloat dqdx = span->texStepX[u][3]; - GLfloat s = span->tex[u][0]; - GLfloat t = span->tex[u][1]; - GLfloat r = span->tex[u][2]; - GLfloat q = span->tex[u][3]; - GLuint i; - if (ctx->FragmentProgram._Enabled || ctx->ATIFragmentShader._Enabled || - ctx->ShaderObjects._FragmentShaderPresent) { - /* do perspective correction but don't divide s, t, r by q */ - const GLfloat dwdx = span->dwdx; - GLfloat w = span->w; - for (i = 0; i < span->end; i++) { - const GLfloat invW = 1.0F / w; - texcoord[i][0] = s * invW; - texcoord[i][1] = t * invW; - texcoord[i][2] = r * invW; - texcoord[i][3] = q * invW; - lambda[i] = 0.0; - s += dsdx; - t += dtdx; - r += drdx; - q += dqdx; - w += dwdx; - } - } - else if (dqdx == 0.0F) { - /* Ortho projection or polygon's parallel to window X axis */ + for (i = 0; i < span->end; i++) { const GLfloat invQ = (q == 0.0F) ? 1.0F : (1.0F / q); - for (i = 0; i < span->end; i++) { - texcoord[i][0] = s * invQ; - texcoord[i][1] = t * invQ; - texcoord[i][2] = r * invQ; - texcoord[i][3] = q; - lambda[i] = 0.0; - s += dsdx; - t += dtdx; - r += drdx; - } - } - else { - for (i = 0; i < span->end; i++) { - const GLfloat invQ = (q == 0.0F) ? 1.0F : (1.0F / q); - texcoord[i][0] = s * invQ; - texcoord[i][1] = t * invQ; - texcoord[i][2] = r * invQ; - texcoord[i][3] = q; - lambda[i] = 0.0; - s += dsdx; - t += dtdx; - r += drdx; - q += dqdx; - } + texcoord[i][0] = s * invQ; + texcoord[i][1] = t * invQ; + texcoord[i][2] = r * invQ; + texcoord[i][3] = q; + lambda[i] = _swrast_compute_lambda(dsdx, dsdy, dtdx, dtdy, + dqdx, dqdy, texW, texH, + s, t, q, invQ); + s += dsdx; + t += dtdx; + r += drdx; + q += dqdx; } - } /* lambda */ - } /* if */ - } /* for */ - } - else { - /* single texture */ - const struct gl_texture_object *obj = ctx->Texture.Unit[0]._Current; - GLfloat texW, texH; - GLboolean needLambda; - if (obj) { - const struct gl_texture_image *img = obj->Image[0][obj->BaseLevel]; - needLambda = (obj->MinFilter != obj->MagFilter) - || ctx->FragmentProgram._Enabled; - texW = (GLfloat) img->WidthScale; - texH = (GLfloat) img->HeightScale; - } - else { - needLambda = GL_FALSE; - texW = texH = 1.0; - } - span->arrayMask |= SPAN_TEXTURE; - if (needLambda) { - /* just texture unit 0, with lambda */ - GLfloat (*texcoord)[4] = span->array->texcoords[0]; - GLfloat *lambda = span->array->lambda[0]; - const GLfloat dsdx = span->texStepX[0][0]; - const GLfloat dsdy = span->texStepY[0][0]; - const GLfloat dtdx = span->texStepX[0][1]; - const GLfloat dtdy = span->texStepY[0][1]; - const GLfloat drdx = span->texStepX[0][2]; - const GLfloat dqdx = span->texStepX[0][3]; - const GLfloat dqdy = span->texStepY[0][3]; - GLfloat s = span->tex[0][0]; - GLfloat t = span->tex[0][1]; - GLfloat r = span->tex[0][2]; - GLfloat q = span->tex[0][3]; - GLuint i; - if (ctx->FragmentProgram._Enabled || ctx->ATIFragmentShader._Enabled || - ctx->ShaderObjects._FragmentShaderPresent) { - /* do perspective correction but don't divide s, t, r by q */ - const GLfloat dwdx = span->dwdx; - GLfloat w = span->w; - for (i = 0; i < span->end; i++) { - const GLfloat invW = 1.0F / w; - texcoord[i][0] = s * invW; - texcoord[i][1] = t * invW; - texcoord[i][2] = r * invW; - texcoord[i][3] = q * invW; - lambda[i] = _swrast_compute_lambda(dsdx, dsdy, dtdx, dtdy, - dqdx, dqdy, texW, texH, - s, t, q, invW); - s += dsdx; - t += dtdx; - r += drdx; - q += dqdx; - w += dwdx; } + span->arrayMask |= SPAN_LAMBDA; } else { - /* tex.c */ - for (i = 0; i < span->end; i++) { - const GLfloat invQ = (q == 0.0F) ? 1.0F : (1.0F / q); - lambda[i] = _swrast_compute_lambda(dsdx, dsdy, dtdx, dtdy, - dqdx, dqdy, texW, texH, - s, t, q, invQ); - texcoord[i][0] = s * invQ; - texcoord[i][1] = t * invQ; - texcoord[i][2] = r * invQ; - texcoord[i][3] = q; - s += dsdx; - t += dtdx; - r += drdx; - q += dqdx; - } - } - span->arrayMask |= SPAN_LAMBDA; - } - else { - /* just texture 0, without lambda */ - GLfloat (*texcoord)[4] = span->array->texcoords[0]; - const GLfloat dsdx = span->texStepX[0][0]; - const GLfloat dtdx = span->texStepX[0][1]; - const GLfloat drdx = span->texStepX[0][2]; - const GLfloat dqdx = span->texStepX[0][3]; - GLfloat s = span->tex[0][0]; - GLfloat t = span->tex[0][1]; - GLfloat r = span->tex[0][2]; - GLfloat q = span->tex[0][3]; - GLuint i; - if (ctx->FragmentProgram._Enabled || ctx->ATIFragmentShader._Enabled || - ctx->ShaderObjects._FragmentShaderPresent) { - /* do perspective correction but don't divide s, t, r by q */ - const GLfloat dwdx = span->dwdx; - GLfloat w = span->w; - for (i = 0; i < span->end; i++) { - const GLfloat invW = 1.0F / w; - texcoord[i][0] = s * invW; - texcoord[i][1] = t * invW; - texcoord[i][2] = r * invW; - texcoord[i][3] = q * invW; - s += dsdx; - t += dtdx; - r += drdx; - q += dqdx; - w += dwdx; - } - } - else if (dqdx == 0.0F) { - /* Ortho projection or polygon's parallel to window X axis */ - const GLfloat invQ = (q == 0.0F) ? 1.0F : (1.0F / q); - for (i = 0; i < span->end; i++) { - texcoord[i][0] = s * invQ; - texcoord[i][1] = t * invQ; - texcoord[i][2] = r * invQ; - texcoord[i][3] = q; - s += dsdx; - t += dtdx; - r += drdx; + GLuint i; + if (ctx->FragmentProgram._Current || + ctx->ATIFragmentShader._Enabled) { + /* do perspective correction but don't divide s, t, r by q */ + const GLfloat dwdx = span->attrStepX[FRAG_ATTRIB_WPOS][3]; + GLfloat w = span->attrStart[FRAG_ATTRIB_WPOS][3]; + for (i = 0; i < span->end; i++) { + const GLfloat invW = 1.0F / w; + texcoord[i][0] = s * invW; + texcoord[i][1] = t * invW; + texcoord[i][2] = r * invW; + texcoord[i][3] = q * invW; + lambda[i] = 0.0; + s += dsdx; + t += dtdx; + r += drdx; + q += dqdx; + w += dwdx; + } } - } - else { - for (i = 0; i < span->end; i++) { + else if (dqdx == 0.0F) { + /* Ortho projection or polygon's parallel to window X axis */ const GLfloat invQ = (q == 0.0F) ? 1.0F : (1.0F / q); - texcoord[i][0] = s * invQ; - texcoord[i][1] = t * invQ; - texcoord[i][2] = r * invQ; - texcoord[i][3] = q; - s += dsdx; - t += dtdx; - r += drdx; - q += dqdx; + for (i = 0; i < span->end; i++) { + texcoord[i][0] = s * invQ; + texcoord[i][1] = t * invQ; + texcoord[i][2] = r * invQ; + texcoord[i][3] = q; + lambda[i] = 0.0; + s += dsdx; + t += dtdx; + r += drdx; + } } - } - } - } + else { + for (i = 0; i < span->end; i++) { + const GLfloat invQ = (q == 0.0F) ? 1.0F : (1.0F / q); + texcoord[i][0] = s * invQ; + texcoord[i][1] = t * invQ; + texcoord[i][2] = r * invQ; + texcoord[i][3] = q; + lambda[i] = 0.0; + s += dsdx; + t += dtdx; + r += drdx; + q += dqdx; + } + } + } /* lambda */ + } /* if */ + } /* for */ } + /** - * Fill in the span.varying array from the interpolation values. + * Fill in the arrays->attribs[FRAG_ATTRIB_VARx] arrays from the + * interpolation values. + * XXX since interpolants/arrays are getting uniformed, we might merge + * this with interpolate_texcoords(), interpolate_Fog(), etc. someday. */ static INLINE void interpolate_varying(GLcontext *ctx, SWspan *span) { - GLuint i, j; + GLuint var; + const GLbitfield inputsUsed = ctx->FragmentProgram._Current->Base.InputsRead; ASSERT(span->interpMask & SPAN_VARYING); ASSERT(!(span->arrayMask & SPAN_VARYING)); span->arrayMask |= SPAN_VARYING; - for (i = 0; i < MAX_VARYING_VECTORS; i++) { - for (j = 0; j < VARYINGS_PER_VECTOR; j++) { - const GLfloat dvdx = span->varStepX[i][j]; - GLfloat v = span->var[i][j]; - const GLfloat dwdx = span->dwdx; - GLfloat w = span->w; + for (var = 0; var < MAX_VARYING; var++) { + if (inputsUsed & FRAG_BIT_VAR(var)) { + const GLuint attr = FRAG_ATTRIB_VAR0 + var; + const GLfloat dwdx = span->attrStepX[FRAG_ATTRIB_WPOS][3]; + GLfloat w = span->attrStart[FRAG_ATTRIB_WPOS][3]; + const GLfloat dv0dx = span->attrStepX[attr][0]; + const GLfloat dv1dx = span->attrStepX[attr][1]; + const GLfloat dv2dx = span->attrStepX[attr][2]; + const GLfloat dv3dx = span->attrStepX[attr][3]; + GLfloat v0 = span->attrStart[attr][0]; + GLfloat v1 = span->attrStart[attr][1]; + GLfloat v2 = span->attrStart[attr][2]; + GLfloat v3 = span->attrStart[attr][3]; GLuint k; - for (k = 0; k < span->end; k++) { GLfloat invW = 1.0f / w; - span->array->varying[k][i][j] = v * invW; - v += dvdx; + span->array->attribs[attr][k][0] = v0 * invW; + span->array->attribs[attr][k][1] = v1 * invW; + span->array->attribs[attr][k][2] = v2 * invW; + span->array->attribs[attr][k][3] = v3 * invW; + v0 += dv0dx; + v1 += dv1dx; + v2 += dv2dx; + v3 += dv3dx; w += dwdx; } } @@ -850,28 +731,68 @@ interpolate_varying(GLcontext *ctx, SWspan *span) /** + * Fill in the arrays->attribs[FRAG_ATTRIB_WPOS] array. + */ +static INLINE void +interpolate_wpos(GLcontext *ctx, SWspan *span) +{ + GLfloat (*wpos)[4] = span->array->attribs[FRAG_ATTRIB_WPOS]; + GLuint i; + if (span->arrayMask & SPAN_XY) { + for (i = 0; i < span->end; i++) { + wpos[i][0] = (GLfloat) span->array->x[i]; + wpos[i][1] = (GLfloat) span->array->y[i]; + } + } + else { + for (i = 0; i < span->end; i++) { + wpos[i][0] = (GLfloat) span->x + i; + wpos[i][1] = (GLfloat) span->y; + } + } + for (i = 0; i < span->end; i++) { + wpos[i][2] = (GLfloat) span->array->z[i] / ctx->DrawBuffer->_DepthMaxF; + wpos[i][3] = span->attrStart[FRAG_ATTRIB_WPOS][3] + + i * span->attrStepX[FRAG_ATTRIB_WPOS][3]; + } +} + + +/** * Apply the current polygon stipple pattern to a span of pixels. */ static INLINE void -stipple_polygon_span( GLcontext *ctx, SWspan *span ) +stipple_polygon_span(GLcontext *ctx, SWspan *span) { - const GLuint highbit = 0x80000000; - const GLuint stipple = ctx->PolygonStipple[span->y % 32]; GLubyte *mask = span->array->mask; - GLuint i, m; ASSERT(ctx->Polygon.StippleFlag); - ASSERT((span->arrayMask & SPAN_XY) == 0); - m = highbit >> (GLuint) (span->x % 32); - - for (i = 0; i < span->end; i++) { - if ((m & stipple) == 0) { - mask[i] = 0; + if (span->arrayMask & SPAN_XY) { + /* arrays of x/y pixel coords */ + GLuint i; + for (i = 0; i < span->end; i++) { + const GLint col = span->array->x[i] % 32; + const GLint row = span->array->y[i] % 32; + const GLuint stipple = ctx->PolygonStipple[row]; + if (((1 << col) & stipple) == 0) { + mask[i] = 0; + } } - m = m >> 1; - if (m == 0) { - m = highbit; + } + else { + /* horizontal span of pixels */ + const GLuint highBit = 1 << 31; + const GLuint stipple = ctx->PolygonStipple[span->y % 32]; + GLuint i, m = highBit >> (GLuint) (span->x % 32); + for (i = 0; i < span->end; i++) { + if ((m & stipple) == 0) { + mask[i] = 0; + } + m = m >> 1; + if (m == 0) { + m = highBit; + } } } span->writeAll = GL_FALSE; @@ -1224,8 +1145,8 @@ add_specular(GLcontext *ctx, SWspan *span) break; case GL_FLOAT: { - GLfloat (*rgba)[4] = span->array->color.sz4.rgba; - GLfloat (*spec)[4] = span->array->color.sz4.spec; + GLfloat (*rgba)[4] = span->array->attribs[FRAG_ATTRIB_COL0]; + GLfloat (*spec)[4] = span->array->attribs[FRAG_ATTRIB_COL1]; GLuint i; for (i = 0; i < span->end; i++) { rgba[i][RCOMP] += spec[i][RCOMP]; @@ -1266,7 +1187,7 @@ apply_aa_coverage(SWspan *span) } } else { - GLfloat (*rgba)[4] = span->array->color.sz4.rgba; + GLfloat (*rgba)[4] = span->array->attribs[FRAG_ATTRIB_COL0]; for (i = 0; i < span->end; i++) { rgba[i][ACOMP] = rgba[i][ACOMP] * coverage[i]; } @@ -1280,7 +1201,7 @@ apply_aa_coverage(SWspan *span) static INLINE void clamp_colors(SWspan *span) { - GLfloat (*rgba)[4] = span->array->color.sz4.rgba; + GLfloat (*rgba)[4] = span->array->attribs[FRAG_ATTRIB_COL0]; GLuint i; ASSERT(span->array->ChanType == GL_FLOAT); for (i = 0; i < span->end; i++) { @@ -1294,28 +1215,35 @@ clamp_colors(SWspan *span) /** * Convert the span's color arrays to the given type. + * The only way 'output' can be greater than one is when we have a fragment + * program that writes to gl_FragData[1] or higher. + * \param output which fragment program color output is being processed */ static INLINE void -convert_color_type(GLcontext *ctx, SWspan *span, GLenum newType) +convert_color_type(SWspan *span, GLenum newType, GLuint output) { GLvoid *src, *dst; - if (span->array->ChanType == GL_UNSIGNED_BYTE) { - src = span->array->color.sz1.rgba; + + if (output > 0 || span->array->ChanType == GL_FLOAT) { + src = span->array->attribs[FRAG_ATTRIB_COL0 + output]; + span->array->ChanType = GL_FLOAT; } else if (span->array->ChanType == GL_UNSIGNED_BYTE) { - src = span->array->color.sz2.rgba; + src = span->array->color.sz1.rgba; } else { - src = span->array->color.sz4.rgba; + ASSERT(span->array->ChanType == GL_UNSIGNED_SHORT); + src = span->array->color.sz2.rgba; } + if (newType == GL_UNSIGNED_BYTE) { dst = span->array->color.sz1.rgba; } - else if (newType == GL_UNSIGNED_BYTE) { + else if (newType == GL_UNSIGNED_SHORT) { dst = span->array->color.sz2.rgba; } else { - dst = span->array->color.sz4.rgba; + dst = span->array->attribs[FRAG_ATTRIB_COL0]; } _mesa_convert_colors(span->array->ChanType, src, @@ -1333,46 +1261,58 @@ convert_color_type(GLcontext *ctx, SWspan *span, GLenum newType) static INLINE void shade_texture_span(GLcontext *ctx, SWspan *span) { - /* Now we need the rgba array, fill it in if needed */ - if (span->interpMask & SPAN_RGBA) + GLbitfield inputsRead; + + /* Determine which fragment attributes are actually needed */ + if (ctx->FragmentProgram._Current) { + inputsRead = ctx->FragmentProgram._Current->Base.InputsRead; + } + else { + /* XXX we could be a bit smarter about this */ + inputsRead = ~0; + } + + if ((inputsRead & FRAG_BIT_COL0) && (span->interpMask & SPAN_RGBA)) interpolate_colors(span); if (ctx->Texture._EnabledCoordUnits && (span->interpMask & SPAN_TEXTURE)) interpolate_texcoords(ctx, span); - if (ctx->ShaderObjects._FragmentShaderPresent || - ctx->FragmentProgram._Enabled || + if (ctx->FragmentProgram._Current || ctx->ATIFragmentShader._Enabled) { - /* use float colors if running a fragment program or shader */ const GLenum oldType = span->array->ChanType; const GLenum newType = GL_FLOAT; - if (oldType != newType) { + + if ((inputsRead & FRAG_BIT_COL0) && (oldType != newType)) { GLvoid *src = (oldType == GL_UNSIGNED_BYTE) ? (GLvoid *) span->array->color.sz1.rgba : (GLvoid *) span->array->color.sz2.rgba; + assert(span->arrayMask & SPAN_RGBA); _mesa_convert_colors(oldType, src, - newType, span->array->color.sz4.rgba, + newType, span->array->attribs[FRAG_ATTRIB_COL0], span->end, span->array->mask); - span->array->ChanType = newType; } + span->array->ChanType = newType; /* fragment programs/shaders may need specular, fog and Z coords */ - if (span->interpMask & SPAN_SPEC) + if ((inputsRead & FRAG_BIT_COL1) && (span->interpMask & SPAN_SPEC)) interpolate_specular(span); - if (span->interpMask & SPAN_FOG) + if ((inputsRead & FRAG_BIT_FOGC) && (span->interpMask & SPAN_FOG)) interpolate_fog(ctx, span); if (span->interpMask & SPAN_Z) _swrast_span_interpolate_z (ctx, span); - /* Run fragment program/shader now */ - if (ctx->ShaderObjects._FragmentShaderPresent) { + if ((inputsRead >= FRAG_BIT_VAR0) && (span->interpMask & SPAN_VARYING)) interpolate_varying(ctx, span); - _swrast_exec_arbshader(ctx, span); - } - else if (ctx->FragmentProgram._Enabled) { + + if (inputsRead & FRAG_BIT_WPOS) + interpolate_wpos(ctx, span); + + /* Run fragment program/shader now */ + if (ctx->FragmentProgram._Current) { _swrast_exec_fragment_program(ctx, span); } else { @@ -1403,11 +1343,11 @@ _swrast_write_rgba_span( GLcontext *ctx, SWspan *span) const GLbitfield origInterpMask = span->interpMask; const GLbitfield origArrayMask = span->arrayMask; const GLenum chanType = span->array->ChanType; - const GLboolean shader - = ctx->FragmentProgram._Enabled - || ctx->ShaderObjects._FragmentShaderPresent - || ctx->ATIFragmentShader._Enabled; + const GLboolean shader = (ctx->FragmentProgram._Current + || ctx->ATIFragmentShader._Enabled); const GLboolean shaderOrTexture = shader || ctx->Texture._EnabledUnits; + struct gl_framebuffer *fb = ctx->DrawBuffer; + GLuint output; GLboolean deferredTexture; /* @@ -1429,20 +1369,16 @@ _swrast_write_rgba_span( GLcontext *ctx, SWspan *span) deferredTexture = GL_FALSE; } else if (shaderOrTexture) { - if (ctx->FragmentProgram._Enabled) { - if (ctx->FragmentProgram.Current->Base.OutputsWritten + if (ctx->FragmentProgram._Current) { + if (ctx->FragmentProgram._Current->Base.OutputsWritten & (1 << FRAG_RESULT_DEPR)) { - /* Z comes from fragment program */ + /* Z comes from fragment program/shader */ deferredTexture = GL_FALSE; } else { deferredTexture = GL_TRUE; } } - else if (ctx->ShaderObjects._FragmentShaderPresent) { - /* XXX how do we test if Z is written by shader? */ - deferredTexture = GL_FALSE; /* never defer to be safe */ - } else { /* ATI frag shader or conventional texturing */ deferredTexture = GL_TRUE; @@ -1476,10 +1412,10 @@ _swrast_write_rgba_span( GLcontext *ctx, SWspan *span) GLuint i; for (i = 0; i < span->end; i++) { if (span->array->mask[i]) { - assert(span->array->x[i] >= ctx->DrawBuffer->_Xmin); - assert(span->array->x[i] < ctx->DrawBuffer->_Xmax); - assert(span->array->y[i] >= ctx->DrawBuffer->_Ymin); - assert(span->array->y[i] < ctx->DrawBuffer->_Ymax); + assert(span->array->x[i] >= fb->_Xmin); + assert(span->array->x[i] < fb->_Xmax); + assert(span->array->y[i] >= fb->_Ymin); + assert(span->array->y[i] < fb->_Ymax); } } } @@ -1511,13 +1447,13 @@ _swrast_write_rgba_span( GLcontext *ctx, SWspan *span) if (span->interpMask & SPAN_Z) _swrast_span_interpolate_z(ctx, span); - if (ctx->Stencil.Enabled && ctx->DrawBuffer->Visual.stencilBits > 0) { + if (ctx->Stencil.Enabled && fb->Visual.stencilBits > 0) { /* Combined Z/stencil tests */ if (!_swrast_stencil_and_ztest_span(ctx, span)) { goto end; } } - else if (ctx->DrawBuffer->Visual.depthBits > 0) { + else if (fb->Visual.depthBits > 0) { /* Just regular depth testing */ ASSERT(ctx->Depth.Test); ASSERT(span->arrayMask & SPAN_Z); @@ -1597,64 +1533,67 @@ _swrast_write_rgba_span( GLcontext *ctx, SWspan *span) /* * Write to renderbuffers */ - { - struct gl_framebuffer *fb = ctx->DrawBuffer; - const GLuint output = 0; /* only frag progs can write to other outputs */ - const GLuint numDrawBuffers = fb->_NumColorDrawBuffers[output]; - GLchan rgbaSave[MAX_WIDTH][4]; - GLuint buf; - - if (numDrawBuffers > 0) { - if (fb->_ColorDrawBuffers[output][0]->DataType - != span->array->ChanType) { - convert_color_type(ctx, span, - fb->_ColorDrawBuffers[output][0]->DataType); - } - } - - if (numDrawBuffers > 1) { - /* save colors for second, third renderbuffer writes */ - _mesa_memcpy(rgbaSave, span->array->rgba, - 4 * span->end * sizeof(GLchan)); - } - - for (buf = 0; buf < numDrawBuffers; buf++) { - struct gl_renderbuffer *rb = fb->_ColorDrawBuffers[output][buf]; - ASSERT(rb->_BaseFormat == GL_RGBA || rb->_BaseFormat == GL_RGB); - - if (ctx->Color._LogicOpEnabled) { - _swrast_logicop_rgba_span(ctx, rb, span); - } - else if (ctx->Color.BlendEnabled) { - _swrast_blend_span(ctx, rb, span); - } - - if (colorMask != 0xffffffff) { - _swrast_mask_rgba_span(ctx, rb, span); - } - - if (span->arrayMask & SPAN_XY) { - /* array of pixel coords */ - ASSERT(rb->PutValues); - rb->PutValues(ctx, rb, span->end, - span->array->x, span->array->y, - span->array->rgba, span->array->mask); - } - else { - /* horizontal run of pixels */ - ASSERT(rb->PutRow); - rb->PutRow(ctx, rb, span->end, span->x, span->y, span->array->rgba, - span->writeAll ? NULL: span->array->mask); - } - - if (buf + 1 < numDrawBuffers) { - /* restore original span values */ - _mesa_memcpy(span->array->rgba, rgbaSave, - 4 * span->end * sizeof(GLchan)); - } - } /* for buf */ - - } + /* Loop over color outputs (GL_ARB_draw_buffers) written by frag prog */ + for (output = 0; output < swrast->_NumColorOutputs; output++) { + if (swrast->_ColorOutputsMask & (1 << output)) { + const GLuint numDrawBuffers = fb->_NumColorDrawBuffers[output]; + GLchan rgbaSave[MAX_WIDTH][4]; + GLuint buf; + + ASSERT(numDrawBuffers > 0); + + if (fb->_ColorDrawBuffers[output][0]->DataType + != span->array->ChanType || output > 0) { + convert_color_type(span, + fb->_ColorDrawBuffers[output][0]->DataType, + output); + } + + if (numDrawBuffers > 1) { + /* save colors for second, third renderbuffer writes */ + _mesa_memcpy(rgbaSave, span->array->rgba, + 4 * span->end * sizeof(GLchan)); + } + + /* Loop over renderbuffers (i.e. GL_FRONT_AND_BACK) */ + for (buf = 0; buf < numDrawBuffers; buf++) { + struct gl_renderbuffer *rb = fb->_ColorDrawBuffers[output][buf]; + ASSERT(rb->_BaseFormat == GL_RGBA || rb->_BaseFormat == GL_RGB); + + if (ctx->Color._LogicOpEnabled) { + _swrast_logicop_rgba_span(ctx, rb, span); + } + else if (ctx->Color.BlendEnabled) { + _swrast_blend_span(ctx, rb, span); + } + + if (colorMask != 0xffffffff) { + _swrast_mask_rgba_span(ctx, rb, span); + } + + if (span->arrayMask & SPAN_XY) { + /* array of pixel coords */ + ASSERT(rb->PutValues); + rb->PutValues(ctx, rb, span->end, + span->array->x, span->array->y, + span->array->rgba, span->array->mask); + } + else { + /* horizontal run of pixels */ + ASSERT(rb->PutRow); + rb->PutRow(ctx, rb, span->end, span->x, span->y, + span->array->rgba, + span->writeAll ? NULL: span->array->mask); + } + + if (buf + 1 < numDrawBuffers) { + /* restore original span values */ + _mesa_memcpy(span->array->rgba, rgbaSave, + 4 * span->end * sizeof(GLchan)); + } + } /* for buf */ + } /* if output is written to */ + } /* for output */ end: /* restore these values before returning */ @@ -1665,9 +1604,9 @@ end: /** - * Read RGBA pixels from frame buffer. Clipping will be done to prevent + * Read RGBA pixels from a renderbuffer. Clipping will be done to prevent * reading ouside the buffer's boundaries. - * \param type datatype for returned colors + * \param dstType datatype for returned colors * \param rgba the returned colors */ void @@ -1732,7 +1671,7 @@ _swrast_read_rgba_span( GLcontext *ctx, struct gl_renderbuffer *rb, /** - * Read CI pixels from frame buffer. Clipping will be done to prevent + * Read CI pixels from a renderbuffer. Clipping will be done to prevent * reading ouside the buffer's boundaries. */ void @@ -1815,8 +1754,7 @@ _swrast_get_values(GLcontext *ctx, struct gl_renderbuffer *rb, for (i = 0; i < count; i++) { if (x[i] >= 0 && y[i] >= 0 && - x[i] < (GLint) rb->Width && - y[i] < (GLint) rb->Height) { + x[i] < (GLint) rb->Width && y[i] < (GLint) rb->Height) { /* inside */ if (inCount == 0) inStart = i; @@ -1850,13 +1788,13 @@ _swrast_put_row(GLcontext *ctx, struct gl_renderbuffer *rb, { GLint skip = 0; - if (y < 0 || (GLint) y >= rb->Height) + if (y < 0 || y >= (GLint) rb->Height) return; /* above or below */ if (x + (GLint) count <= 0 || x >= (GLint) rb->Width) return; /* entirely left or right */ - if (x + count > rb->Width) { + if ((GLint) (x + count) > (GLint) rb->Width) { /* right clip */ GLint clip = x + count - rb->Width; count -= clip; @@ -1885,10 +1823,10 @@ _swrast_get_row(GLcontext *ctx, struct gl_renderbuffer *rb, { GLint skip = 0; - if (y < 0 || y >= rb->Height) + if (y < 0 || y >= (GLint) rb->Height) return; /* above or below */ - if (x + (GLint) count <= 0 || x >= rb->Width) + if (x + (GLint) count <= 0 || x >= (GLint) rb->Width) return; /* entirely left or right */ if (x + count > rb->Width) { @@ -1933,7 +1871,7 @@ _swrast_get_dest_rgba(GLcontext *ctx, struct gl_renderbuffer *rb, rbPixels = span->array->color.sz2.spec; } else { - rbPixels = span->array->color.sz4.spec; + rbPixels = span->array->attribs[FRAG_ATTRIB_COL1]; } /* Get destination values from renderbuffer */ diff --git a/src/mesa/swrast/s_span.h b/src/mesa/swrast/s_span.h index c441106aba..8a9b9eb21c 100644 --- a/src/mesa/swrast/s_span.h +++ b/src/mesa/swrast/s_span.h @@ -31,6 +31,185 @@ #include "swrast.h" +/** + * \defgroup SpanFlags + * Bitflags used for interpMask and arrayMask fields below to indicate + * which interpolant values and fragment arrays are in use, respectively. + * + * XXX We should replace these flags with the FRAG_BIT_ values someday... + */ +/*@{*/ +#define SPAN_RGBA 0x001 +#define SPAN_SPEC 0x002 +#define SPAN_INDEX 0x004 +#define SPAN_Z 0x008 +#define SPAN_W 0x010 +#define SPAN_FOG 0x020 +#define SPAN_TEXTURE 0x040 +#define SPAN_INT_TEXTURE 0x080 +#define SPAN_LAMBDA 0x100 +#define SPAN_COVERAGE 0x200 +#define SPAN_FLAT 0x400 /**< flat shading? */ +#define SPAN_XY 0x800 +#define SPAN_MASK 0x1000 +#define SPAN_VARYING 0x2000 +/*@}*/ + + +#if 0 +/* alternate arrangement for code below */ +struct arrays2 { + union { + GLubyte sz1[MAX_WIDTH][4]; /* primary color */ + GLushort sz2[MAX_WIDTH][4]; + } rgba; + union { + GLubyte sz1[MAX_WIDTH][4]; /* specular color and temp storage */ + GLushort sz2[MAX_WIDTH][4]; + } spec; +}; +#endif + + + +/** + * \sw_span_arrays + * \brief Arrays of fragment values. + * + * These will either be computed from the span x/xStep values or + * filled in by glDraw/CopyPixels, etc. + * These arrays are separated out of sw_span to conserve memory. + */ +typedef struct sw_span_arrays +{ + /** Per-fragment attributes (indexed by FRAG_ATTRIB_* tokens) */ + /* XXX someday look at transposing first two indexes for better memory + * access pattern. + */ + GLfloat attribs[FRAG_ATTRIB_MAX][MAX_WIDTH][4]; + + /** This mask indicates which fragments are alive or culled */ + GLubyte mask[MAX_WIDTH]; + + GLenum ChanType; /**< Color channel type, GL_UNSIGNED_BYTE, GL_FLOAT */ + union { + struct { + GLubyte rgba[MAX_WIDTH][4]; /**< primary color */ + GLubyte spec[MAX_WIDTH][4]; /**< specular color and temp storage */ + } sz1; + struct { + GLushort rgba[MAX_WIDTH][4]; + GLushort spec[MAX_WIDTH][4]; + } sz2; + } color; + /** XXX these are temporary fields, pointing into above color arrays */ + GLchan (*rgba)[4]; + GLchan (*spec)[4]; + + GLint x[MAX_WIDTH]; /**< fragment X coords */ + GLint y[MAX_WIDTH]; /**< fragment Y coords */ + GLuint z[MAX_WIDTH]; /**< fragment Z coords */ + GLuint index[MAX_WIDTH]; /**< Color indexes */ + GLfloat lambda[MAX_TEXTURE_COORD_UNITS][MAX_WIDTH]; /**< Texture LOD */ + GLfloat coverage[MAX_WIDTH]; /**< Fragment coverage for AA/smoothing */ +} SWspanarrays; + + +/** + * The SWspan structure describes the colors, Z, fogcoord, texcoords, + * etc for either a horizontal run or an array of independent pixels. + * We can either specify a base/step to indicate interpolated values, or + * fill in explicit arrays of values. The interpMask and arrayMask bitfields + * indicate which attributes are active interpolants or arrays, respectively. + * + * It would be interesting to experiment with multiprocessor rasterization + * with this structure. The triangle rasterizer could simply emit a + * stream of these structures which would be consumed by one or more + * span-processing threads which could run in parallel. + */ +typedef struct sw_span +{ + /** Coord of first fragment in horizontal span/run */ + GLint x, y; + + /** Number of fragments in the span */ + GLuint end; + + /** This flag indicates that mask[] array is effectively filled with ones */ + GLboolean writeAll; + + /** either GL_POLYGON, GL_LINE, GL_POLYGON, GL_BITMAP */ + GLenum primitive; + + /** 0 = front-facing span, 1 = back-facing span (for two-sided stencil) */ + GLuint facing; + + /** + * This bitmask (of \link SpanFlags SPAN_* flags\endlink) indicates + * which of the attrStart/StepX/StepY variables are relevant. + */ + GLbitfield interpMask; + + /** Fragment attribute interpolants */ + GLfloat attrStart[FRAG_ATTRIB_MAX][4]; /**< initial value */ + GLfloat attrStepX[FRAG_ATTRIB_MAX][4]; /**< dvalue/dx */ + GLfloat attrStepY[FRAG_ATTRIB_MAX][4]; /**< dvalue/dy */ + + /* XXX the rest of these will go away eventually... */ + + /* For horizontal spans, step is the partial derivative wrt X. + * For lines, step is the delta from one fragment to the next. + */ +#if CHAN_TYPE == GL_FLOAT + GLfloat red, redStep; + GLfloat green, greenStep; + GLfloat blue, blueStep; + GLfloat alpha, alphaStep; + GLfloat specRed, specRedStep; + GLfloat specGreen, specGreenStep; + GLfloat specBlue, specBlueStep; +#else /* CHAN_TYPE == GL_UNSIGNED_BYTE or GL_UNSIGNED_SHORT */ + GLfixed red, redStep; + GLfixed green, greenStep; + GLfixed blue, blueStep; + GLfixed alpha, alphaStep; + GLfixed specRed, specRedStep; + GLfixed specGreen, specGreenStep; + GLfixed specBlue, specBlueStep; +#endif + GLfixed index, indexStep; + GLfixed z, zStep; /* XXX z should probably be GLuint */ + GLfixed intTex[2], intTexStep[2]; /* s, t only */ + + /** + * This bitmask (of \link SpanFlags SPAN_* flags\endlink) indicates + * which of the fragment arrays in the span_arrays struct are relevant. + */ + GLbitfield arrayMask; + + /** + * We store the arrays of fragment values in a separate struct so + * that we can allocate sw_span structs on the stack without using + * a lot of memory. The span_arrays struct is about 1.4MB while the + * sw_span struct is only about 512 bytes. + */ + SWspanarrays *array; +} SWspan; + + + +#define INIT_SPAN(S, PRIMITIVE, END, INTERP_MASK, ARRAY_MASK) \ +do { \ + (S).primitive = (PRIMITIVE); \ + (S).interpMask = (INTERP_MASK); \ + (S).arrayMask = (ARRAY_MASK); \ + (S).end = (END); \ + (S).facing = 0; \ + (S).array = SWRAST_CONTEXT(ctx)->SpanArrays; \ +} while (0) + + + extern void _swrast_span_default_z( GLcontext *ctx, SWspan *span ); diff --git a/src/mesa/swrast/s_texcombine.c b/src/mesa/swrast/s_texcombine.c index 2a3455f35e..ebb4c0d936 100644 --- a/src/mesa/swrast/s_texcombine.c +++ b/src/mesa/swrast/s_texcombine.c @@ -1094,6 +1094,9 @@ _swrast_texture_span( GLcontext *ctx, SWspan *span ) */ for (unit = 0; unit < ctx->Const.MaxTextureUnits; unit++) { if (ctx->Texture.Unit[unit]._ReallyEnabled) { + const GLfloat (*texcoords)[4] + = (const GLfloat (*)[4]) + span->array->attribs[FRAG_ATTRIB_TEX0 + unit]; const struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit]; const struct gl_texture_object *curObj = texUnit->_Current; GLfloat *lambda = span->array->lambda[unit]; @@ -1127,8 +1130,7 @@ _swrast_texture_span( GLcontext *ctx, SWspan *span ) /* Sample the texture (span->end = number of fragments) */ swrast->TextureSample[unit]( ctx, texUnit->_Current, span->end, - (const GLfloat (*)[4]) span->array->texcoords[unit], - lambda, texels ); + texcoords, lambda, texels ); /* GL_SGI_texture_color_table */ if (texUnit->ColorTableEnabled) { diff --git a/src/mesa/swrast/s_triangle.c b/src/mesa/swrast/s_triangle.c index b17c435460..3b7960bf80 100644 --- a/src/mesa/swrast/s_triangle.c +++ b/src/mesa/swrast/s_triangle.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"), @@ -676,13 +676,13 @@ fast_persp_span(GLcontext *ctx, SWspan *span, const GLuint savedTexEnable = ctx->Texture._EnabledUnits; ctx->Texture._EnabledUnits = 0; - tex_coord[0] = span->tex[0][0] * (info->smask + 1); - tex_step[0] = span->texStepX[0][0] * (info->smask + 1); - tex_coord[1] = span->tex[0][1] * (info->tmask + 1); - tex_step[1] = span->texStepX[0][1] * (info->tmask + 1); - /* span->tex[0][2] only if 3D-texturing, here only 2D */ - tex_coord[2] = span->tex[0][3]; - tex_step[2] = span->texStepX[0][3]; + tex_coord[0] = span->attrStart[FRAG_ATTRIB_TEX0][0] * (info->smask + 1); + tex_step[0] = span->attrStepX[FRAG_ATTRIB_TEX0][0] * (info->smask + 1); + tex_coord[1] = span->attrStart[FRAG_ATTRIB_TEX0][1] * (info->tmask + 1); + tex_step[1] = span->attrStepX[FRAG_ATTRIB_TEX0][1] * (info->tmask + 1); + /* span->attrStart[FRAG_ATTRIB_TEX0][2] only if 3D-texturing, here only 2D */ + tex_coord[2] = span->attrStart[FRAG_ATTRIB_TEX0][3]; + tex_step[2] = span->attrStepX[FRAG_ATTRIB_TEX0][3]; switch (info->filter) { case GL_NEAREST: @@ -866,7 +866,6 @@ fast_persp_span(GLcontext *ctx, SWspan *span, /* * Render a smooth-shaded, textured, RGBA triangle. - * Interpolate S,T,R with perspective correction, w/out mipmapping. */ #define NAME general_textured_triangle #define INTERP_Z 1 @@ -881,24 +880,6 @@ fast_persp_span(GLcontext *ctx, SWspan *span, -/* - * This is the big one! - * Interpolate Z, RGB, Alpha, specular, fog, N sets of texture coordinates, and varying floats. - * Yup, it's slow. - */ -#define NAME multitextured_triangle -#define INTERP_Z 1 -#define INTERP_W 1 -#define INTERP_FOG 1 -#define INTERP_RGB 1 -#define INTERP_ALPHA 1 -#define INTERP_SPEC 1 -#define INTERP_MULTITEX 1 -#define INTERP_VARYING 1 -#define RENDER_SPAN( span ) _swrast_write_rgba_span(ctx, &span); -#include "s_tritemp.h" - - /* * Special tri function for occlusion testing @@ -1073,8 +1054,9 @@ _swrast_choose_triangle( GLcontext *ctx ) } } - if (ctx->Texture._EnabledCoordUnits || ctx->FragmentProgram._Enabled || - ctx->ATIFragmentShader._Enabled || ctx->ShaderObjects._FragmentShaderPresent) { + if (ctx->Texture._EnabledCoordUnits || + ctx->FragmentProgram._Current || + ctx->ATIFragmentShader._Enabled) { /* Ugh, we do a _lot_ of tests to pick the best textured tri func */ const struct gl_texture_object *texObj2D; const struct gl_texture_image *texImg; @@ -1089,9 +1071,8 @@ _swrast_choose_triangle( GLcontext *ctx ) /* First see if we can use an optimized 2-D texture function */ if (ctx->Texture._EnabledCoordUnits == 0x1 - && !ctx->FragmentProgram._Enabled + && !ctx->FragmentProgram._Current && !ctx->ATIFragmentShader._Enabled - && !ctx->ShaderObjects._FragmentShaderPresent && ctx->Texture.Unit[0]._ReallyEnabled == TEXTURE_2D_BIT && texObj2D->WrapS == GL_REPEAT && texObj2D->WrapT == GL_REPEAT @@ -1137,12 +1118,7 @@ _swrast_choose_triangle( GLcontext *ctx ) } else { /* general case textured triangles */ - if (ctx->Texture._EnabledCoordUnits > 1) { - USE(multitextured_triangle); - } - else { - USE(general_textured_triangle); - } + USE(general_textured_triangle); } } else { diff --git a/src/mesa/swrast/s_tritemp.h b/src/mesa/swrast/s_tritemp.h index 9e0a8a3d32..435491a0c8 100644 --- a/src/mesa/swrast/s_tritemp.h +++ b/src/mesa/swrast/s_tritemp.h @@ -1,8 +1,8 @@ /* * Mesa 3-D graphics library - * Version: 6.5 + * 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"), @@ -38,10 +38,8 @@ * INTERP_INDEX - if defined, interpolate color index values * INTERP_INT_TEX - if defined, interpolate integer ST texcoords * (fast, simple 2-D texture mapping) - * INTERP_TEX - if defined, interpolate set 0 float STRQ texcoords + * INTERP_TEX - if defined, interpolate texcoords and varying vars * NOTE: OpenGL STRQ = Mesa STUV (R was taken for red) - * INTERP_MULTITEX - if defined, interpolate N units of STRQ texcoords - * INTERP_VARYING - if defined, interpolate M floats of GLSL varyings * * When one can directly address pixels in the color buffer the following * macros can be defined and used to compute pixel addresses during @@ -119,43 +117,19 @@ #endif -/* - * Either loop over all texture units, or just use unit zero. - */ -#ifdef INTERP_MULTITEX -#define TEX_UNIT_LOOP(CODE) \ - { \ - GLuint u; \ - for (u = 0; u < ctx->Const.MaxTextureUnits; u++) { \ - if (ctx->Texture._EnabledCoordUnits & (1 << u)) { \ - CODE \ - } \ - } \ +#define TEXVAR_LOOP(CODE) \ + { \ + GLuint attr; \ + for (attr = swrast->_MinFragmentAttrib; \ + attr < swrast->_MaxFragmentAttrib; attr++) { \ + if (swrast->_FragmentAttribs & (1 << attr)) { \ + CODE \ + } \ + } \ } -#define INTERP_TEX -#elif defined(INTERP_TEX) -#define TEX_UNIT_LOOP(CODE) \ - { \ - const GLuint u = 0; \ - CODE \ - } -#endif -#ifdef INTERP_VARYING -#define VARYING_LOOP(CODE)\ - {\ - GLuint iv, ic;\ - for (iv = 0; iv < MAX_VARYING_VECTORS; iv++) {\ - for (ic = 0; ic < VARYINGS_PER_VECTOR; ic++) {\ - CODE\ - }\ - }\ - } -#endif - - /* * Some code we unfortunately need to prevent negative interpolated colors. @@ -201,6 +175,7 @@ static void NAME(GLcontext *ctx, const SWvertex *v0, GLint lines; /* number of lines to be sampled on this edge */ } EdgeT; + const SWcontext *swrast = SWRAST_CONTEXT(ctx); #ifdef INTERP_Z const GLint depthBits = ctx->DrawBuffer->Visual.depthBits; const GLint fixedToDepthShift = depthBits <= 16 ? FIXED_SHIFT : 0; @@ -218,6 +193,8 @@ static void NAME(GLcontext *ctx, const SWvertex *v0, SWspan span; + (void) swrast; + INIT_SPAN(span, GL_POLYGON, 0, 0, 0); #ifdef INTERP_Z @@ -465,19 +442,19 @@ static void NAME(GLcontext *ctx, const SWvertex *v0, { GLfloat eMaj_dz = vMax->win[2] - vMin->win[2]; GLfloat eBot_dz = vMid->win[2] - vMin->win[2]; - span.dzdx = oneOverArea * (eMaj_dz * eBot.dy - eMaj.dy * eBot_dz); - if (span.dzdx > maxDepth || span.dzdx < -maxDepth) { + span.attrStepX[FRAG_ATTRIB_WPOS][2] = oneOverArea * (eMaj_dz * eBot.dy - eMaj.dy * eBot_dz); + if (span.attrStepX[FRAG_ATTRIB_WPOS][2] > maxDepth || span.attrStepX[FRAG_ATTRIB_WPOS][2] < -maxDepth) { /* probably a sliver triangle */ - span.dzdx = 0.0; - span.dzdy = 0.0; + span.attrStepX[FRAG_ATTRIB_WPOS][2] = 0.0; + span.attrStepY[FRAG_ATTRIB_WPOS][2] = 0.0; } else { - span.dzdy = oneOverArea * (eMaj.dx * eBot_dz - eMaj_dz * eBot.dx); + span.attrStepY[FRAG_ATTRIB_WPOS][2] = oneOverArea * (eMaj.dx * eBot_dz - eMaj_dz * eBot.dx); } if (depthBits <= 16) - span.zStep = SignedFloatToFixed(span.dzdx); + span.zStep = SignedFloatToFixed(span.attrStepX[FRAG_ATTRIB_WPOS][2]); else - span.zStep = (GLint) span.dzdx; + span.zStep = (GLint) span.attrStepX[FRAG_ATTRIB_WPOS][2]; } #endif #ifdef INTERP_W @@ -485,8 +462,8 @@ static void NAME(GLcontext *ctx, const SWvertex *v0, { const GLfloat eMaj_dw = vMax->win[3] - vMin->win[3]; const GLfloat eBot_dw = vMid->win[3] - vMin->win[3]; - span.dwdx = oneOverArea * (eMaj_dw * eBot.dy - eMaj.dy * eBot_dw); - span.dwdy = oneOverArea * (eMaj.dx * eBot_dw - eMaj_dw * eBot.dx); + span.attrStepX[FRAG_ATTRIB_WPOS][3] = oneOverArea * (eMaj_dw * eBot.dy - eMaj.dy * eBot_dw); + span.attrStepY[FRAG_ATTRIB_WPOS][3] = oneOverArea * (eMaj.dx * eBot_dw - eMaj_dw * eBot.dx); } #endif #ifdef INTERP_FOG @@ -500,9 +477,8 @@ static void NAME(GLcontext *ctx, const SWvertex *v0, const GLfloat eMaj_dfog = vMax->fog - vMin->fog; const GLfloat eBot_dfog = vMid->fog - vMin->fog; # endif - span.dfogdx = oneOverArea * (eMaj_dfog * eBot.dy - eMaj.dy * eBot_dfog); - span.dfogdy = oneOverArea * (eMaj.dx * eBot_dfog - eMaj_dfog * eBot.dx); - span.fogStep = span.dfogdx; + span.attrStepX[FRAG_ATTRIB_FOGC][0] = oneOverArea * (eMaj_dfog * eBot.dy - eMaj.dy * eBot_dfog); + span.attrStepY[FRAG_ATTRIB_FOGC][0] = oneOverArea * (eMaj.dx * eBot_dfog - eMaj_dfog * eBot.dx); } #endif #ifdef INTERP_RGB @@ -518,37 +494,37 @@ static void NAME(GLcontext *ctx, const SWvertex *v0, GLfloat eMaj_da = (GLfloat) ((ColorTemp) vMax->color[ACOMP] - (ColorTemp) vMin->color[ACOMP]); GLfloat eBot_da = (GLfloat) ((ColorTemp) vMid->color[ACOMP] - (ColorTemp) vMin->color[ACOMP]); # endif - span.drdx = oneOverArea * (eMaj_dr * eBot.dy - eMaj.dy * eBot_dr); - span.drdy = oneOverArea * (eMaj.dx * eBot_dr - eMaj_dr * eBot.dx); - span.dgdx = oneOverArea * (eMaj_dg * eBot.dy - eMaj.dy * eBot_dg); - span.dgdy = oneOverArea * (eMaj.dx * eBot_dg - eMaj_dg * eBot.dx); - span.dbdx = oneOverArea * (eMaj_db * eBot.dy - eMaj.dy * eBot_db); - span.dbdy = oneOverArea * (eMaj.dx * eBot_db - eMaj_db * eBot.dx); + span.attrStepX[FRAG_ATTRIB_COL0][0] = oneOverArea * (eMaj_dr * eBot.dy - eMaj.dy * eBot_dr); + span.attrStepY[FRAG_ATTRIB_COL0][0] = oneOverArea * (eMaj.dx * eBot_dr - eMaj_dr * eBot.dx); + span.attrStepX[FRAG_ATTRIB_COL0][1] = oneOverArea * (eMaj_dg * eBot.dy - eMaj.dy * eBot_dg); + span.attrStepY[FRAG_ATTRIB_COL0][1] = oneOverArea * (eMaj.dx * eBot_dg - eMaj_dg * eBot.dx); + span.attrStepX[FRAG_ATTRIB_COL0][2] = oneOverArea * (eMaj_db * eBot.dy - eMaj.dy * eBot_db); + span.attrStepY[FRAG_ATTRIB_COL0][2] = oneOverArea * (eMaj.dx * eBot_db - eMaj_db * eBot.dx); # if CHAN_TYPE == GL_FLOAT - span.redStep = span.drdx; - span.greenStep = span.dgdx; - span.blueStep = span.dbdx; + span.redStep = span.attrStepX[FRAG_ATTRIB_COL0][0]; + span.greenStep = span.attrStepX[FRAG_ATTRIB_COL0][1]; + span.blueStep = span.attrStepX[FRAG_ATTRIB_COL0][2]; # else - span.redStep = SignedFloatToFixed(span.drdx); - span.greenStep = SignedFloatToFixed(span.dgdx); - span.blueStep = SignedFloatToFixed(span.dbdx); + span.redStep = SignedFloatToFixed(span.attrStepX[FRAG_ATTRIB_COL0][0]); + span.greenStep = SignedFloatToFixed(span.attrStepX[FRAG_ATTRIB_COL0][1]); + span.blueStep = SignedFloatToFixed(span.attrStepX[FRAG_ATTRIB_COL0][2]); # endif /* GL_FLOAT */ # ifdef INTERP_ALPHA - span.dadx = oneOverArea * (eMaj_da * eBot.dy - eMaj.dy * eBot_da); - span.dady = oneOverArea * (eMaj.dx * eBot_da - eMaj_da * eBot.dx); + span.attrStepX[FRAG_ATTRIB_COL0][3] = oneOverArea * (eMaj_da * eBot.dy - eMaj.dy * eBot_da); + span.attrStepX[FRAG_ATTRIB_COL0][3] = oneOverArea * (eMaj.dx * eBot_da - eMaj_da * eBot.dx); # if CHAN_TYPE == GL_FLOAT - span.alphaStep = span.dadx; + span.alphaStep = span.attrStepX[FRAG_ATTRIB_COL0][3]; # else - span.alphaStep = SignedFloatToFixed(span.dadx); + span.alphaStep = SignedFloatToFixed(span.attrStepX[FRAG_ATTRIB_COL0][3]); # endif /* GL_FLOAT */ # endif /* INTERP_ALPHA */ } else { ASSERT(ctx->Light.ShadeModel == GL_FLAT); span.interpMask |= SPAN_FLAT; - span.drdx = span.drdy = 0.0F; - span.dgdx = span.dgdy = 0.0F; - span.dbdx = span.dbdy = 0.0F; + span.attrStepX[FRAG_ATTRIB_COL0][0] = span.attrStepY[FRAG_ATTRIB_COL0][0] = 0.0F; + span.attrStepX[FRAG_ATTRIB_COL0][1] = span.attrStepY[FRAG_ATTRIB_COL0][1] = 0.0F; + span.attrStepX[FRAG_ATTRIB_COL0][2] = span.attrStepY[FRAG_ATTRIB_COL0][2] = 0.0F; # if CHAN_TYPE == GL_FLOAT span.redStep = 0.0F; span.greenStep = 0.0F; @@ -559,7 +535,7 @@ static void NAME(GLcontext *ctx, const SWvertex *v0, span.blueStep = 0; # endif /* GL_FLOAT */ # ifdef INTERP_ALPHA - span.dadx = span.dady = 0.0F; + span.attrStepX[FRAG_ATTRIB_COL0][3] = span.attrStepX[FRAG_ATTRIB_COL0][3] = 0.0F; # if CHAN_TYPE == GL_FLOAT span.alphaStep = 0.0F; # else @@ -577,26 +553,26 @@ static void NAME(GLcontext *ctx, const SWvertex *v0, GLfloat eBot_dsg = (GLfloat) ((ColorTemp) vMid->specular[GCOMP] - (ColorTemp) vMin->specular[GCOMP]); GLfloat eMaj_dsb = (GLfloat) ((ColorTemp) vMax->specular[BCOMP] - (ColorTemp) vMin->specular[BCOMP]); GLfloat eBot_dsb = (GLfloat) ((ColorTemp) vMid->specular[BCOMP] - (ColorTemp) vMin->specular[BCOMP]); - span.dsrdx = oneOverArea * (eMaj_dsr * eBot.dy - eMaj.dy * eBot_dsr); - span.dsrdy = oneOverArea * (eMaj.dx * eBot_dsr - eMaj_dsr * eBot.dx); - span.dsgdx = oneOverArea * (eMaj_dsg * eBot.dy - eMaj.dy * eBot_dsg); - span.dsgdy = oneOverArea * (eMaj.dx * eBot_dsg - eMaj_dsg * eBot.dx); - span.dsbdx = oneOverArea * (eMaj_dsb * eBot.dy - eMaj.dy * eBot_dsb); - span.dsbdy = oneOverArea * (eMaj.dx * eBot_dsb - eMaj_dsb * eBot.dx); + span.attrStepX[FRAG_ATTRIB_COL1][0] = oneOverArea * (eMaj_dsr * eBot.dy - eMaj.dy * eBot_dsr); + span.attrStepY[FRAG_ATTRIB_COL1][0] = oneOverArea * (eMaj.dx * eBot_dsr - eMaj_dsr * eBot.dx); + span.attrStepX[FRAG_ATTRIB_COL1][1] = oneOverArea * (eMaj_dsg * eBot.dy - eMaj.dy * eBot_dsg); + span.attrStepY[FRAG_ATTRIB_COL1][1] = oneOverArea * (eMaj.dx * eBot_dsg - eMaj_dsg * eBot.dx); + span.attrStepX[FRAG_ATTRIB_COL1][2] = oneOverArea * (eMaj_dsb * eBot.dy - eMaj.dy * eBot_dsb); + span.attrStepY[FRAG_ATTRIB_COL1][2] = oneOverArea * (eMaj.dx * eBot_dsb - eMaj_dsb * eBot.dx); # if CHAN_TYPE == GL_FLOAT - span.specRedStep = span.dsrdx; + span.specRedStep = span.attrStep[FRAG_ATTRIB_COL1][0]; span.specGreenStep = span.dsgdx; span.specBlueStep = span.dsbdx; # else - span.specRedStep = SignedFloatToFixed(span.dsrdx); - span.specGreenStep = SignedFloatToFixed(span.dsgdx); - span.specBlueStep = SignedFloatToFixed(span.dsbdx); + span.specRedStep = SignedFloatToFixed(span.attrStepX[FRAG_ATTRIB_COL1][0]); + span.specGreenStep = SignedFloatToFixed(span.attrStepX[FRAG_ATTRIB_COL1][1]); + span.specBlueStep = SignedFloatToFixed(span.attrStepX[FRAG_ATTRIB_COL1][2]); # endif } else { - span.dsrdx = span.dsrdy = 0.0F; - span.dsgdx = span.dsgdy = 0.0F; - span.dsbdx = span.dsbdy = 0.0F; + span.attrStepX[FRAG_ATTRIB_COL1][0] = span.attrStepY[FRAG_ATTRIB_COL1][0] = 0.0F; + span.attrStepX[FRAG_ATTRIB_COL1][1] = span.attrStepY[FRAG_ATTRIB_COL1][1] = 0.0F; + span.attrStepX[FRAG_ATTRIB_COL1][2] = span.attrStepY[FRAG_ATTRIB_COL1][2] = 0.0F; # if CHAN_TYPE == GL_FLOAT span.specRedStep = 0.0F; span.specGreenStep = 0.0F; @@ -626,53 +602,40 @@ static void NAME(GLcontext *ctx, const SWvertex *v0, #ifdef INTERP_INT_TEX span.interpMask |= SPAN_INT_TEXTURE; { - GLfloat eMaj_ds = (vMax->texcoord[0][0] - vMin->texcoord[0][0]) * S_SCALE; - GLfloat eBot_ds = (vMid->texcoord[0][0] - vMin->texcoord[0][0]) * S_SCALE; - GLfloat eMaj_dt = (vMax->texcoord[0][1] - vMin->texcoord[0][1]) * T_SCALE; - GLfloat eBot_dt = (vMid->texcoord[0][1] - vMin->texcoord[0][1]) * T_SCALE; - span.texStepX[0][0] = oneOverArea * (eMaj_ds * eBot.dy - eMaj.dy * eBot_ds); - span.texStepY[0][0] = oneOverArea * (eMaj.dx * eBot_ds - eMaj_ds * eBot.dx); - span.texStepX[0][1] = oneOverArea * (eMaj_dt * eBot.dy - eMaj.dy * eBot_dt); - span.texStepY[0][1] = oneOverArea * (eMaj.dx * eBot_dt - eMaj_dt * eBot.dx); - span.intTexStep[0] = SignedFloatToFixed(span.texStepX[0][0]); - span.intTexStep[1] = SignedFloatToFixed(span.texStepX[0][1]); + GLfloat eMaj_ds = (vMax->attrib[FRAG_ATTRIB_TEX0][0] - vMin->attrib[FRAG_ATTRIB_TEX0][0]) * S_SCALE; + GLfloat eBot_ds = (vMid->attrib[FRAG_ATTRIB_TEX0][0] - vMin->attrib[FRAG_ATTRIB_TEX0][0]) * S_SCALE; + GLfloat eMaj_dt = (vMax->attrib[FRAG_ATTRIB_TEX0][1] - vMin->attrib[FRAG_ATTRIB_TEX0][1]) * T_SCALE; + GLfloat eBot_dt = (vMid->attrib[FRAG_ATTRIB_TEX0][1] - vMin->attrib[FRAG_ATTRIB_TEX0][1]) * T_SCALE; + span.attrStepX[FRAG_ATTRIB_TEX0][0] = oneOverArea * (eMaj_ds * eBot.dy - eMaj.dy * eBot_ds); + span.attrStepY[FRAG_ATTRIB_TEX0][0] = oneOverArea * (eMaj.dx * eBot_ds - eMaj_ds * eBot.dx); + span.attrStepX[FRAG_ATTRIB_TEX0][1] = oneOverArea * (eMaj_dt * eBot.dy - eMaj.dy * eBot_dt); + span.attrStepY[FRAG_ATTRIB_TEX0][1] = oneOverArea * (eMaj.dx * eBot_dt - eMaj_dt * eBot.dx); + span.intTexStep[0] = SignedFloatToFixed(span.attrStepX[FRAG_ATTRIB_TEX0][0]); + span.intTexStep[1] = SignedFloatToFixed(span.attrStepX[FRAG_ATTRIB_TEX0][1]); } #endif #ifdef INTERP_TEX - span.interpMask |= SPAN_TEXTURE; + span.interpMask |= (SPAN_TEXTURE | SPAN_VARYING); { /* win[3] is 1/W */ const GLfloat wMax = vMax->win[3], wMin = vMin->win[3], wMid = vMid->win[3]; - TEX_UNIT_LOOP( - GLfloat eMaj_ds = vMax->texcoord[u][0] * wMax - vMin->texcoord[u][0] * wMin; - GLfloat eBot_ds = vMid->texcoord[u][0] * wMid - vMin->texcoord[u][0] * wMin; - GLfloat eMaj_dt = vMax->texcoord[u][1] * wMax - vMin->texcoord[u][1] * wMin; - GLfloat eBot_dt = vMid->texcoord[u][1] * wMid - vMin->texcoord[u][1] * wMin; - GLfloat eMaj_du = vMax->texcoord[u][2] * wMax - vMin->texcoord[u][2] * wMin; - GLfloat eBot_du = vMid->texcoord[u][2] * wMid - vMin->texcoord[u][2] * wMin; - GLfloat eMaj_dv = vMax->texcoord[u][3] * wMax - vMin->texcoord[u][3] * wMin; - GLfloat eBot_dv = vMid->texcoord[u][3] * wMid - vMin->texcoord[u][3] * wMin; - span.texStepX[u][0] = oneOverArea * (eMaj_ds * eBot.dy - eMaj.dy * eBot_ds); - span.texStepY[u][0] = oneOverArea * (eMaj.dx * eBot_ds - eMaj_ds * eBot.dx); - span.texStepX[u][1] = oneOverArea * (eMaj_dt * eBot.dy - eMaj.dy * eBot_dt); - span.texStepY[u][1] = oneOverArea * (eMaj.dx * eBot_dt - eMaj_dt * eBot.dx); - span.texStepX[u][2] = oneOverArea * (eMaj_du * eBot.dy - eMaj.dy * eBot_du); - span.texStepY[u][2] = oneOverArea * (eMaj.dx * eBot_du - eMaj_du * eBot.dx); - span.texStepX[u][3] = oneOverArea * (eMaj_dv * eBot.dy - eMaj.dy * eBot_dv); - span.texStepY[u][3] = oneOverArea * (eMaj.dx * eBot_dv - eMaj_dv * eBot.dx); - ) - } -#endif -#ifdef INTERP_VARYING - span.interpMask |= SPAN_VARYING; - { - /* win[3] is 1/W */ - const GLfloat wMax = vMax->win[3], wMin = vMin->win[3], wMid = vMid->win[3]; - VARYING_LOOP( - GLfloat eMaj_dvar = vMax->attribute[iv][ic] * wMax - vMin->attribute[iv][ic] * wMin; - GLfloat eBot_dvar = vMid->attribute[iv][ic] * wMid - vMin->attribute[iv][ic] * wMin; - span.varStepX[iv][ic] = oneOverArea * (eMaj_dvar * eBot.dy - eMaj.dy * eBot_dvar); - span.varStepY[iv][ic] = oneOverArea * (eMaj.dx * eBot_dvar - eMaj_dvar * eBot.dx); + TEXVAR_LOOP( + GLfloat eMaj_ds = vMax->attrib[attr][0] * wMax - vMin->attrib[attr][0] * wMin; + GLfloat eBot_ds = vMid->attrib[attr][0] * wMid - vMin->attrib[attr][0] * wMin; + GLfloat eMaj_dt = vMax->attrib[attr][1] * wMax - vMin->attrib[attr][1] * wMin; + GLfloat eBot_dt = vMid->attrib[attr][1] * wMid - vMin->attrib[attr][1] * wMin; + GLfloat eMaj_du = vMax->attrib[attr][2] * wMax - vMin->attrib[attr][2] * wMin; + GLfloat eBot_du = vMid->attrib[attr][2] * wMid - vMin->attrib[attr][2] * wMin; + GLfloat eMaj_dv = vMax->attrib[attr][3] * wMax - vMin->attrib[attr][3] * wMin; + GLfloat eBot_dv = vMid->attrib[attr][3] * wMid - vMin->attrib[attr][3] * wMin; + span.attrStepX[attr][0] = oneOverArea * (eMaj_ds * eBot.dy - eMaj.dy * eBot_ds); + span.attrStepY[attr][0] = oneOverArea * (eMaj.dx * eBot_ds - eMaj_ds * eBot.dx); + span.attrStepX[attr][1] = oneOverArea * (eMaj_dt * eBot.dy - eMaj.dy * eBot_dt); + span.attrStepY[attr][1] = oneOverArea * (eMaj.dx * eBot_dt - eMaj_dt * eBot.dx); + span.attrStepX[attr][2] = oneOverArea * (eMaj_du * eBot.dy - eMaj.dy * eBot_du); + span.attrStepY[attr][2] = oneOverArea * (eMaj.dx * eBot_du - eMaj_du * eBot.dx); + span.attrStepX[attr][3] = oneOverArea * (eMaj_dv * eBot.dy - eMaj.dy * eBot_dv); + span.attrStepY[attr][3] = oneOverArea * (eMaj.dx * eBot_dv - eMaj_dv * eBot.dx); ) } #endif @@ -770,19 +733,14 @@ static void NAME(GLcontext *ctx, const SWvertex *v0, GLfixed tLeft=0, dtOuter=0, dtInner; #endif #ifdef INTERP_TEX - GLfloat sLeft[MAX_TEXTURE_COORD_UNITS]; - GLfloat tLeft[MAX_TEXTURE_COORD_UNITS]; - GLfloat uLeft[MAX_TEXTURE_COORD_UNITS]; - GLfloat vLeft[MAX_TEXTURE_COORD_UNITS]; - GLfloat dsOuter[MAX_TEXTURE_COORD_UNITS], dsInner[MAX_TEXTURE_COORD_UNITS]; - GLfloat dtOuter[MAX_TEXTURE_COORD_UNITS], dtInner[MAX_TEXTURE_COORD_UNITS]; - GLfloat duOuter[MAX_TEXTURE_COORD_UNITS], duInner[MAX_TEXTURE_COORD_UNITS]; - GLfloat dvOuter[MAX_TEXTURE_COORD_UNITS], dvInner[MAX_TEXTURE_COORD_UNITS]; -#endif -#ifdef INTERP_VARYING - GLfloat varLeft[MAX_VARYING_VECTORS][VARYINGS_PER_VECTOR]; - GLfloat dvarOuter[MAX_VARYING_VECTORS][VARYINGS_PER_VECTOR]; - GLfloat dvarInner[MAX_VARYING_VECTORS][VARYINGS_PER_VECTOR]; + GLfloat sLeft[FRAG_ATTRIB_MAX]; + GLfloat tLeft[FRAG_ATTRIB_MAX]; + GLfloat uLeft[FRAG_ATTRIB_MAX]; + GLfloat vLeft[FRAG_ATTRIB_MAX]; + GLfloat dsOuter[FRAG_ATTRIB_MAX], dsInner[FRAG_ATTRIB_MAX]; + GLfloat dtOuter[FRAG_ATTRIB_MAX], dtInner[FRAG_ATTRIB_MAX]; + GLfloat duOuter[FRAG_ATTRIB_MAX], duInner[FRAG_ATTRIB_MAX]; + GLfloat dvOuter[FRAG_ATTRIB_MAX], dvInner[FRAG_ATTRIB_MAX]; #endif for (subTriangle=0; subTriangle<=1; subTriangle++) { @@ -894,19 +852,20 @@ static void NAME(GLcontext *ctx, const SWvertex *v0, GLfloat z0 = vLower->win[2]; if (depthBits <= 16) { /* interpolate fixed-pt values */ - GLfloat tmp = (z0 * FIXED_SCALE + span.dzdx * adjx - + span.dzdy * adjy) + FIXED_HALF; + GLfloat tmp = (z0 * FIXED_SCALE + + span.attrStepX[FRAG_ATTRIB_WPOS][2] * adjx + + span.attrStepY[FRAG_ATTRIB_WPOS][2] * adjy) + FIXED_HALF; if (tmp < MAX_GLUINT / 2) zLeft = (GLfixed) tmp; else zLeft = MAX_GLUINT / 2; - fdzOuter = SignedFloatToFixed(span.dzdy + dxOuter * span.dzdx); + fdzOuter = SignedFloatToFixed(span.attrStepY[FRAG_ATTRIB_WPOS][2] + dxOuter * span.attrStepX[FRAG_ATTRIB_WPOS][2]); } else { /* interpolate depth values w/out scaling */ - zLeft = (GLuint) (z0 + span.dzdx * FixedToFloat(adjx) - + span.dzdy * FixedToFloat(adjy)); - fdzOuter = (GLint) (span.dzdy + dxOuter * span.dzdx); + zLeft = (GLuint) (z0 + span.attrStepX[FRAG_ATTRIB_WPOS][2] * FixedToFloat(adjx) + + span.attrStepY[FRAG_ATTRIB_WPOS][2] * FixedToFloat(adjy)); + fdzOuter = (GLint) (span.attrStepY[FRAG_ATTRIB_WPOS][2] + dxOuter * span.attrStepX[FRAG_ATTRIB_WPOS][2]); } # ifdef DEPTH_TYPE zRow = (DEPTH_TYPE *) @@ -916,41 +875,41 @@ static void NAME(GLcontext *ctx, const SWvertex *v0, } #endif #ifdef INTERP_W - wLeft = vLower->win[3] + (span.dwdx * adjx + span.dwdy * adjy) * (1.0F/FIXED_SCALE); - dwOuter = span.dwdy + dxOuter * span.dwdx; + wLeft = vLower->win[3] + (span.attrStepX[FRAG_ATTRIB_WPOS][3] * adjx + span.attrStepY[FRAG_ATTRIB_WPOS][3] * adjy) * (1.0F/FIXED_SCALE); + dwOuter = span.attrStepY[FRAG_ATTRIB_WPOS][3] + dxOuter * span.attrStepX[FRAG_ATTRIB_WPOS][3]; #endif #ifdef INTERP_FOG # ifdef INTERP_W - fogLeft = vLower->fog * vLower->win[3] + (span.dfogdx * adjx + span.dfogdy * adjy) * (1.0F/FIXED_SCALE); + fogLeft = vLower->fog * vLower->win[3] + (span.attrStepX[FRAG_ATTRIB_FOGC][0] * adjx + span.attrStepY[FRAG_ATTRIB_FOGC][0] * adjy) * (1.0F/FIXED_SCALE); # else - fogLeft = vLower->fog + (span.dfogdx * adjx + span.dfogdy * adjy) * (1.0F/FIXED_SCALE); + fogLeft = vLower->fog + (span.attrStepX[FRAG_ATTRIB_FOGC][0] * adjx + span.attrStepY[FRAG_ATTRIB_FOGC][0] * adjy) * (1.0F/FIXED_SCALE); # endif - dfogOuter = span.dfogdy + dxOuter * span.dfogdx; + dfogOuter = span.attrStepY[FRAG_ATTRIB_FOGC][0] + dxOuter * span.attrStepX[FRAG_ATTRIB_FOGC][0]; #endif #ifdef INTERP_RGB if (ctx->Light.ShadeModel == GL_SMOOTH) { # if CHAN_TYPE == GL_FLOAT - rLeft = vLower->color[RCOMP] + (span.drdx * adjx + span.drdy * adjy) * (1.0F / FIXED_SCALE); - gLeft = vLower->color[GCOMP] + (span.dgdx * adjx + span.dgdy * adjy) * (1.0F / FIXED_SCALE); - bLeft = vLower->color[BCOMP] + (span.dbdx * adjx + span.dbdy * adjy) * (1.0F / FIXED_SCALE); - fdrOuter = span.drdy + dxOuter * span.drdx; - fdgOuter = span.dgdy + dxOuter * span.dgdx; - fdbOuter = span.dbdy + dxOuter * span.dbdx; + rLeft = vLower->color[RCOMP] + (span.attrStepX[FRAG_ATTRIB_COL0][0] * adjx + span.attrStepY[FRAG_ATTRIB_COL0][0] * adjy) * (1.0F / FIXED_SCALE); + gLeft = vLower->color[GCOMP] + (span.attrStepX[FRAG_ATTRIB_COL0][1] * adjx + span.attrStepY[FRAG_ATTRIB_COL0][1] * adjy) * (1.0F / FIXED_SCALE); + bLeft = vLower->color[BCOMP] + (span.attrStepX[FRAG_ATTRIB_COL0][2] * adjx + span.attrStepY[FRAG_ATTRIB_COL0][2] * adjy) * (1.0F / FIXED_SCALE); + fdrOuter = span.attrStepY[FRAG_ATTRIB_COL0][0] + dxOuter * span.attrStepX[FRAG_ATTRIB_COL0][0]; + fdgOuter = span.attrStepY[FRAG_ATTRIB_COL0][1] + dxOuter * span.attrStepX[FRAG_ATTRIB_COL0][1]; + fdbOuter = span.attrStepY[FRAG_ATTRIB_COL0][2] + dxOuter * span.attrStepX[FRAG_ATTRIB_COL0][2]; # else - rLeft = (GLint)(ChanToFixed(vLower->color[RCOMP]) + span.drdx * adjx + span.drdy * adjy) + FIXED_HALF; - gLeft = (GLint)(ChanToFixed(vLower->color[GCOMP]) + span.dgdx * adjx + span.dgdy * adjy) + FIXED_HALF; - bLeft = (GLint)(ChanToFixed(vLower->color[BCOMP]) + span.dbdx * adjx + span.dbdy * adjy) + FIXED_HALF; - fdrOuter = SignedFloatToFixed(span.drdy + dxOuter * span.drdx); - fdgOuter = SignedFloatToFixed(span.dgdy + dxOuter * span.dgdx); - fdbOuter = SignedFloatToFixed(span.dbdy + dxOuter * span.dbdx); + rLeft = (GLint)(ChanToFixed(vLower->color[RCOMP]) + span.attrStepX[FRAG_ATTRIB_COL0][0] * adjx + span.attrStepY[FRAG_ATTRIB_COL0][0] * adjy) + FIXED_HALF; + gLeft = (GLint)(ChanToFixed(vLower->color[GCOMP]) + span.attrStepX[FRAG_ATTRIB_COL0][1] * adjx + span.attrStepY[FRAG_ATTRIB_COL0][1] * adjy) + FIXED_HALF; + bLeft = (GLint)(ChanToFixed(vLower->color[BCOMP]) + span.attrStepX[FRAG_ATTRIB_COL0][2] * adjx + span.attrStepY[FRAG_ATTRIB_COL0][2] * adjy) + FIXED_HALF; + fdrOuter = SignedFloatToFixed(span.attrStepY[FRAG_ATTRIB_COL0][0] + dxOuter * span.attrStepX[FRAG_ATTRIB_COL0][0]); + fdgOuter = SignedFloatToFixed(span.attrStepY[FRAG_ATTRIB_COL0][1] + dxOuter * span.attrStepX[FRAG_ATTRIB_COL0][1]); + fdbOuter = SignedFloatToFixed(span.attrStepY[FRAG_ATTRIB_COL0][2] + dxOuter * span.attrStepX[FRAG_ATTRIB_COL0][2]); # endif # ifdef INTERP_ALPHA # if CHAN_TYPE == GL_FLOAT - aLeft = vLower->color[ACOMP] + (span.dadx * adjx + span.dady * adjy) * (1.0F / FIXED_SCALE); - fdaOuter = span.dady + dxOuter * span.dadx; + aLeft = vLower->color[ACOMP] + (span.attrStepX[FRAG_ATTRIB_COL0][3] * adjx + span.attrStepX[FRAG_ATTRIB_COL0][3] * adjy) * (1.0F / FIXED_SCALE); + fdaOuter = span.attrStepX[FRAG_ATTRIB_COL0][3] + dxOuter * span.attrStepX[FRAG_ATTRIB_COL0][3]; # else - aLeft = (GLint)(ChanToFixed(vLower->color[ACOMP]) + span.dadx * adjx + span.dady * adjy) + FIXED_HALF; - fdaOuter = SignedFloatToFixed(span.dady + dxOuter * span.dadx); + aLeft = (GLint)(ChanToFixed(vLower->color[ACOMP]) + span.attrStepX[FRAG_ATTRIB_COL0][3] * adjx + span.attrStepX[FRAG_ATTRIB_COL0][3] * adjy) + FIXED_HALF; + fdaOuter = SignedFloatToFixed(span.attrStepX[FRAG_ATTRIB_COL0][3] + dxOuter * span.attrStepX[FRAG_ATTRIB_COL0][3]); # endif # endif } @@ -983,19 +942,19 @@ static void NAME(GLcontext *ctx, const SWvertex *v0, #ifdef INTERP_SPEC if (ctx->Light.ShadeModel == GL_SMOOTH) { # if CHAN_TYPE == GL_FLOAT - srLeft = vLower->specular[RCOMP] + (span.dsrdx * adjx + span.dsrdy * adjy) * (1.0F / FIXED_SCALE); - sgLeft = vLower->specular[GCOMP] + (span.dsgdx * adjx + span.dsgdy * adjy) * (1.0F / FIXED_SCALE); - sbLeft = vLower->specular[BCOMP] + (span.dsbdx * adjx + span.dsbdy * adjy) * (1.0F / FIXED_SCALE); - dsrOuter = span.dsrdy + dxOuter * span.dsrdx; - dsgOuter = span.dsgdy + dxOuter * span.dsgdx; - dsbOuter = span.dsbdy + dxOuter * span.dsbdx; + srLeft = vLower->specular[RCOMP] + (span.attrStepX[FRAG_ATTRIB_COL1][0] * adjx + span.attrStepY[FRAG_ATTRIB_COL1][0] * adjy) * (1.0F / FIXED_SCALE); + sgLeft = vLower->specular[GCOMP] + (span.attrStepX[FRAG_ATTRIB_COL1][1] * adjx + span.attrStepY[FRAG_ATTRIB_COL1][1] * adjy) * (1.0F / FIXED_SCALE); + sbLeft = vLower->specular[BCOMP] + (span.attrStepX[FRAG_ATTRIB_COL1][2] * adjx + span.attrStepY[FRAG_ATTRIB_COL1][2] * adjy) * (1.0F / FIXED_SCALE); + dsrOuter = span.attrStepY[FRAG_ATTRIB_COL1][0] + dxOuter * span.attrStepX[FRAG_ATTRIB_COL1][0]; + dsgOuter = span.attrStepY[FRAG_ATTRIB_COL1][1] + dxOuter * span.attrStepX[FRAG_ATTRIB_COL1][1]; + dsbOuter = span.attrStepY[FRAG_ATTRIB_COL1][2] + dxOuter * span.attrStepX[FRAG_ATTRIB_COL1][2]; # else - srLeft = (GLfixed) (ChanToFixed(vLower->specular[RCOMP]) + span.dsrdx * adjx + span.dsrdy * adjy) + FIXED_HALF; - sgLeft = (GLfixed) (ChanToFixed(vLower->specular[GCOMP]) + span.dsgdx * adjx + span.dsgdy * adjy) + FIXED_HALF; - sbLeft = (GLfixed) (ChanToFixed(vLower->specular[BCOMP]) + span.dsbdx * adjx + span.dsbdy * adjy) + FIXED_HALF; - dsrOuter = SignedFloatToFixed(span.dsrdy + dxOuter * span.dsrdx); - dsgOuter = SignedFloatToFixed(span.dsgdy + dxOuter * span.dsgdx); - dsbOuter = SignedFloatToFixed(span.dsbdy + dxOuter * span.dsbdx); + srLeft = (GLfixed) (ChanToFixed(vLower->specular[RCOMP]) + span.attrStepX[FRAG_ATTRIB_COL1][0] * adjx + span.attrStepY[FRAG_ATTRIB_COL1][0] * adjy) + FIXED_HALF; + sgLeft = (GLfixed) (ChanToFixed(vLower->specular[GCOMP]) + span.attrStepX[FRAG_ATTRIB_COL1][1] * adjx + span.attrStepY[FRAG_ATTRIB_COL1][1] * adjy) + FIXED_HALF; + sbLeft = (GLfixed) (ChanToFixed(vLower->specular[BCOMP]) + span.attrStepX[FRAG_ATTRIB_COL1][2] * adjx + span.attrStepY[FRAG_ATTRIB_COL1][2] * adjy) + FIXED_HALF; + dsrOuter = SignedFloatToFixed(span.attrStepY[FRAG_ATTRIB_COL1][0] + dxOuter * span.attrStepX[FRAG_ATTRIB_COL1][0]); + dsgOuter = SignedFloatToFixed(span.attrStepY[FRAG_ATTRIB_COL1][1] + dxOuter * span.attrStepX[FRAG_ATTRIB_COL1][1]); + dsbOuter = SignedFloatToFixed(span.attrStepY[FRAG_ATTRIB_COL1][2] + dxOuter * span.attrStepX[FRAG_ATTRIB_COL1][2]); # endif } else { @@ -1029,41 +988,32 @@ static void NAME(GLcontext *ctx, const SWvertex *v0, #ifdef INTERP_INT_TEX { GLfloat s0, t0; - s0 = vLower->texcoord[0][0] * S_SCALE; - sLeft = (GLfixed)(s0 * FIXED_SCALE + span.texStepX[0][0] * adjx - + span.texStepY[0][0] * adjy) + FIXED_HALF; - dsOuter = SignedFloatToFixed(span.texStepY[0][0] + dxOuter * span.texStepX[0][0]); - - t0 = vLower->texcoord[0][1] * T_SCALE; - tLeft = (GLfixed)(t0 * FIXED_SCALE + span.texStepX[0][1] * adjx - + span.texStepY[0][1] * adjy) + FIXED_HALF; - dtOuter = SignedFloatToFixed(span.texStepY[0][1] + dxOuter * span.texStepX[0][1]); + s0 = vLower->attrib[FRAG_ATTRIB_TEX0][0] * S_SCALE; + sLeft = (GLfixed)(s0 * FIXED_SCALE + span.attrStepX[FRAG_ATTRIB_TEX0][0] * adjx + + span.attrStepY[FRAG_ATTRIB_TEX0][0] * adjy) + FIXED_HALF; + dsOuter = SignedFloatToFixed(span.attrStepY[FRAG_ATTRIB_TEX0][0] + dxOuter * span.attrStepX[FRAG_ATTRIB_TEX0][0]); + + t0 = vLower->attrib[FRAG_ATTRIB_TEX0][1] * T_SCALE; + tLeft = (GLfixed)(t0 * FIXED_SCALE + span.attrStepX[FRAG_ATTRIB_TEX0][1] * adjx + + span.attrStepY[FRAG_ATTRIB_TEX0][1] * adjy) + FIXED_HALF; + dtOuter = SignedFloatToFixed(span.attrStepY[FRAG_ATTRIB_TEX0][1] + dxOuter * span.attrStepX[FRAG_ATTRIB_TEX0][1]); } #endif #ifdef INTERP_TEX - TEX_UNIT_LOOP( + TEXVAR_LOOP( const GLfloat invW = vLower->win[3]; - const GLfloat s0 = vLower->texcoord[u][0] * invW; - const GLfloat t0 = vLower->texcoord[u][1] * invW; - const GLfloat u0 = vLower->texcoord[u][2] * invW; - const GLfloat v0 = vLower->texcoord[u][3] * invW; - sLeft[u] = s0 + (span.texStepX[u][0] * adjx + span.texStepY[u][0] * adjy) * (1.0F/FIXED_SCALE); - tLeft[u] = t0 + (span.texStepX[u][1] * adjx + span.texStepY[u][1] * adjy) * (1.0F/FIXED_SCALE); - uLeft[u] = u0 + (span.texStepX[u][2] * adjx + span.texStepY[u][2] * adjy) * (1.0F/FIXED_SCALE); - vLeft[u] = v0 + (span.texStepX[u][3] * adjx + span.texStepY[u][3] * adjy) * (1.0F/FIXED_SCALE); - dsOuter[u] = span.texStepY[u][0] + dxOuter * span.texStepX[u][0]; - dtOuter[u] = span.texStepY[u][1] + dxOuter * span.texStepX[u][1]; - duOuter[u] = span.texStepY[u][2] + dxOuter * span.texStepX[u][2]; - dvOuter[u] = span.texStepY[u][3] + dxOuter * span.texStepX[u][3]; - ) -#endif -#ifdef INTERP_VARYING - VARYING_LOOP( - const GLfloat invW = vLower->win[3]; - const GLfloat var0 = vLower->attribute[iv][ic] * invW; - varLeft[iv][ic] = var0 + (span.varStepX[iv][ic] * adjx + - span.varStepY[iv][ic] * adjy) * (1.0f / FIXED_SCALE); - dvarOuter[iv][ic] = span.varStepY[iv][ic] + dxOuter * span.varStepX[iv][ic]; + const GLfloat s0 = vLower->attrib[attr][0] * invW; + const GLfloat t0 = vLower->attrib[attr][1] * invW; + const GLfloat u0 = vLower->attrib[attr][2] * invW; + const GLfloat v0 = vLower->attrib[attr][3] * invW; + sLeft[attr] = s0 + (span.attrStepX[attr][0] * adjx + span.attrStepY[attr][0] * adjy) * (1.0F/FIXED_SCALE); + tLeft[attr] = t0 + (span.attrStepX[attr][1] * adjx + span.attrStepY[attr][1] * adjy) * (1.0F/FIXED_SCALE); + uLeft[attr] = u0 + (span.attrStepX[attr][2] * adjx + span.attrStepY[attr][2] * adjy) * (1.0F/FIXED_SCALE); + vLeft[attr] = v0 + (span.attrStepX[attr][3] * adjx + span.attrStepY[attr][3] * adjy) * (1.0F/FIXED_SCALE); + dsOuter[attr] = span.attrStepY[attr][0] + dxOuter * span.attrStepX[attr][0]; + dtOuter[attr] = span.attrStepY[attr][1] + dxOuter * span.attrStepX[attr][1]; + duOuter[attr] = span.attrStepY[attr][2] + dxOuter * span.attrStepX[attr][2]; + dvOuter[attr] = span.attrStepY[attr][3] + dxOuter * span.attrStepX[attr][3]; ) #endif } /*if setupLeft*/ @@ -1095,10 +1045,10 @@ static void NAME(GLcontext *ctx, const SWvertex *v0, fdzInner = fdzOuter + span.zStep; #endif #ifdef INTERP_W - dwInner = dwOuter + span.dwdx; + dwInner = dwOuter + span.attrStepX[FRAG_ATTRIB_WPOS][3]; #endif #ifdef INTERP_FOG - dfogInner = dfogOuter + span.dfogdx; + dfogInner = dfogOuter + span.attrStepX[FRAG_ATTRIB_FOGC][0]; #endif #ifdef INTERP_RGB fdrInner = fdrOuter + span.redStep; @@ -1121,16 +1071,11 @@ static void NAME(GLcontext *ctx, const SWvertex *v0, dtInner = dtOuter + span.intTexStep[1]; #endif #ifdef INTERP_TEX - TEX_UNIT_LOOP( - dsInner[u] = dsOuter[u] + span.texStepX[u][0]; - dtInner[u] = dtOuter[u] + span.texStepX[u][1]; - duInner[u] = duOuter[u] + span.texStepX[u][2]; - dvInner[u] = dvOuter[u] + span.texStepX[u][3]; - ) -#endif -#ifdef INTERP_VARYING - VARYING_LOOP( - dvarInner[iv][ic] = dvarOuter[iv][ic] + span.varStepX[iv][ic]; + TEXVAR_LOOP( + dsInner[attr] = dsOuter[attr] + span.attrStepX[attr][0]; + dtInner[attr] = dtOuter[attr] + span.attrStepX[attr][1]; + duInner[attr] = duOuter[attr] + span.attrStepX[attr][2]; + dvInner[attr] = dvOuter[attr] + span.attrStepX[attr][3]; ) #endif @@ -1148,10 +1093,10 @@ static void NAME(GLcontext *ctx, const SWvertex *v0, span.z = zLeft; #endif #ifdef INTERP_W - span.w = wLeft; + span.attrStart[FRAG_ATTRIB_WPOS][3] = wLeft; #endif #ifdef INTERP_FOG - span.fog = fogLeft; + span.attrStart[FRAG_ATTRIB_FOGC][0] = fogLeft; #endif #ifdef INTERP_RGB span.red = rLeft; @@ -1175,16 +1120,11 @@ static void NAME(GLcontext *ctx, const SWvertex *v0, #endif #ifdef INTERP_TEX - TEX_UNIT_LOOP( - span.tex[u][0] = sLeft[u]; - span.tex[u][1] = tLeft[u]; - span.tex[u][2] = uLeft[u]; - span.tex[u][3] = vLeft[u]; - ) -#endif -#ifdef INTERP_VARYING - VARYING_LOOP( - span.var[iv][ic] = varLeft[iv][ic]; + TEXVAR_LOOP( + span.attrStart[attr][0] = sLeft[attr]; + span.attrStart[attr][1] = tLeft[attr]; + span.attrStart[attr][2] = uLeft[attr]; + span.attrStart[attr][3] = vLeft[attr]; ) #endif @@ -1268,16 +1208,11 @@ static void NAME(GLcontext *ctx, const SWvertex *v0, tLeft += dtOuter; #endif #ifdef INTERP_TEX - TEX_UNIT_LOOP( - sLeft[u] += dsOuter[u]; - tLeft[u] += dtOuter[u]; - uLeft[u] += duOuter[u]; - vLeft[u] += dvOuter[u]; - ) -#endif -#ifdef INTERP_VARYING - VARYING_LOOP( - varLeft[iv][ic] += dvarOuter[iv][ic]; + TEXVAR_LOOP( + sLeft[attr] += dsOuter[attr]; + tLeft[attr] += dtOuter[attr]; + uLeft[attr] += duOuter[attr]; + vLeft[attr] += dvOuter[attr]; ) #endif } @@ -1318,16 +1253,11 @@ static void NAME(GLcontext *ctx, const SWvertex *v0, tLeft += dtInner; #endif #ifdef INTERP_TEX - TEX_UNIT_LOOP( - sLeft[u] += dsInner[u]; - tLeft[u] += dtInner[u]; - uLeft[u] += duInner[u]; - vLeft[u] += dvInner[u]; - ) -#endif -#ifdef INTERP_VARYING - VARYING_LOOP( - varLeft[iv][ic] += dvarInner[iv][ic]; + TEXVAR_LOOP( + sLeft[attr] += dsInner[attr]; + tLeft[attr] += dtInner[attr]; + uLeft[attr] += duInner[attr]; + vLeft[attr] += dvInner[attr]; ) #endif } @@ -1360,8 +1290,6 @@ static void NAME(GLcontext *ctx, const SWvertex *v0, #undef INTERP_INDEX #undef INTERP_INT_TEX #undef INTERP_TEX -#undef INTERP_MULTITEX -#undef INTERP_VARYING #undef TEX_UNIT_LOOP #undef VARYING_LOOP diff --git a/src/mesa/swrast/s_zoom.c b/src/mesa/swrast/s_zoom.c index 036a6084dc..9bec0bb1a1 100644 --- a/src/mesa/swrast/s_zoom.c +++ b/src/mesa/swrast/s_zoom.c @@ -159,8 +159,9 @@ zoom_span( GLcontext *ctx, GLint imgX, GLint imgY, const SWspan *span, /* copy fog interp info */ - zoomed.fog = span->fog; - zoomed.fogStep = span->fogStep; + zoomed.attrStart[FRAG_ATTRIB_FOGC][0] = span->attrStart[FRAG_ATTRIB_FOGC][0]; + zoomed.attrStepX[FRAG_ATTRIB_FOGC][0] = span->attrStepX[FRAG_ATTRIB_FOGC][0]; + zoomed.attrStepY[FRAG_ATTRIB_FOGC][0] = span->attrStepY[FRAG_ATTRIB_FOGC][0]; /* XXX copy texcoord info? */ if (format == GL_RGBA || format == GL_RGB) { @@ -229,8 +230,8 @@ zoom_span( GLcontext *ctx, GLint imgX, GLint imgY, const SWspan *span, for (i = 0; i < zoomedWidth; i++) { GLint j = unzoom_x(ctx->Pixel.ZoomX, imgX, x0 + i) - span->x; ASSERT(j >= 0); - ASSERT(j < (GLint) span->end); - COPY_4V(zoomed.array->color.sz4.rgba[i], rgba[j]); + ASSERT(j < span->end); + COPY_4V(zoomed.array->attribs[FRAG_ATTRIB_COL0][i], rgba[j]); } } } @@ -267,11 +268,11 @@ zoom_span( GLcontext *ctx, GLint imgX, GLint imgY, const SWspan *span, for (i = 0; i < zoomedWidth; i++) { GLint j = unzoom_x(ctx->Pixel.ZoomX, imgX, x0 + i) - span->x; ASSERT(j >= 0); - ASSERT(j < (GLint) span->end); - zoomed.array->color.sz4.rgba[i][0] = rgb[j][0]; - zoomed.array->color.sz4.rgba[i][1] = rgb[j][1]; - zoomed.array->color.sz4.rgba[i][2] = rgb[j][2]; - zoomed.array->color.sz4.rgba[i][3] = 1.0F; + ASSERT(j < span->end); + zoomed.array->attribs[FRAG_ATTRIB_COL0][i][0] = rgb[j][0]; + zoomed.array->attribs[FRAG_ATTRIB_COL0][i][1] = rgb[j][1]; + zoomed.array->attribs[FRAG_ATTRIB_COL0][i][2] = rgb[j][2]; + zoomed.array->attribs[FRAG_ATTRIB_COL0][i][3] = 1.0F; } } } diff --git a/src/mesa/swrast/swrast.h b/src/mesa/swrast/swrast.h index 09686c8380..9e1fe24bb4 100644 --- a/src/mesa/swrast/swrast.h +++ b/src/mesa/swrast/swrast.h @@ -67,13 +67,12 @@ typedef struct { * that clip{XYZ} were multiplied by to get ndc{XYZ}. */ GLfloat win[4]; - GLfloat texcoord[MAX_TEXTURE_COORD_UNITS][4]; GLchan color[4]; GLchan specular[4]; GLfloat fog; GLfloat index; GLfloat pointSize; - GLfloat attribute[MAX_VERTEX_ATTRIBS][4]; + GLfloat attrib[FRAG_ATTRIB_MAX][4]; /**< texcoords & varying, more to come */ } SWvertex; diff --git a/src/mesa/swrast_setup/ss_context.c b/src/mesa/swrast_setup/ss_context.c index cd76375d0c..e1b60d0e85 100644 --- a/src/mesa/swrast_setup/ss_context.c +++ b/src/mesa/swrast_setup/ss_context.c @@ -42,6 +42,9 @@ #define _SWSETUP_NEW_RENDERINDEX (_NEW_POLYGON|_NEW_LIGHT|_NEW_PROGRAM) +#define VARYING_EMIT_STYLE EMIT_4F + + GLboolean _swsetup_CreateContext( GLcontext *ctx ) { @@ -142,17 +145,20 @@ _swsetup_RenderStart( GLcontext *ctx ) if (RENDERINPUTS_TEST_RANGE( index_bitset, _TNL_FIRST_TEX, _TNL_LAST_TEX )) { for (i = 0; i < MAX_TEXTURE_COORD_UNITS; i++) { if (RENDERINPUTS_TEST( index_bitset, _TNL_ATTRIB_TEX(i) )) { - EMIT_ATTR( _TNL_ATTRIB_TEX(i), EMIT_4F, texcoord[i] ); + EMIT_ATTR( _TNL_ATTRIB_TEX(i), EMIT_4F, attrib[FRAG_ATTRIB_TEX0 + i] ); } } } - if (RENDERINPUTS_TEST_RANGE( index_bitset, _TNL_FIRST_GENERIC, _TNL_LAST_GENERIC )) { - for (i = 0; i < MAX_VERTEX_ATTRIBS; i++) { - if (RENDERINPUTS_TEST( index_bitset, _TNL_ATTRIB_GENERIC(i) )) { - EMIT_ATTR( _TNL_ATTRIB_GENERIC(i), VARYING_EMIT_STYLE, attribute[i] ); - } - } + /* shader varying vars */ + if (RENDERINPUTS_TEST_RANGE( index_bitset, + _TNL_FIRST_GENERIC, _TNL_LAST_GENERIC )) { + for (i = 0; i < ctx->Const.MaxVarying; i++) { + if (RENDERINPUTS_TEST( index_bitset, _TNL_ATTRIB_GENERIC(i) )) { + EMIT_ATTR( _TNL_ATTRIB_GENERIC(i), VARYING_EMIT_STYLE, + attrib[FRAG_ATTRIB_VAR0 + i] ); + } + } } if (RENDERINPUTS_TEST( index_bitset, _TNL_ATTRIB_POINTSIZE )) @@ -236,8 +242,13 @@ _swsetup_Translate( GLcontext *ctx, const void *vertex, SWvertex *dest ) for (i = 0 ; i < ctx->Const.MaxTextureCoordUnits ; i++) - _tnl_get_attr( ctx, vertex, _TNL_ATTRIB_TEX0+i, dest->texcoord[i] ); - + _tnl_get_attr( ctx, vertex, _TNL_ATTRIB_TEX0+i, + dest->attrib[FRAG_ATTRIB_TEX0 + i] ); + + for (i = 0 ; i < ctx->Const.MaxVarying ; i++) + _tnl_get_attr( ctx, vertex, _TNL_ATTRIB_GENERIC0+i, + dest->attrib[FRAG_ATTRIB_VAR0 + i] ); + _tnl_get_attr( ctx, vertex, _TNL_ATTRIB_COLOR0, tmp ); UNCLAMPED_FLOAT_TO_RGBA_CHAN( dest->color, tmp ); diff --git a/src/mesa/swrast_setup/ss_triangle.c b/src/mesa/swrast_setup/ss_triangle.c index 09244d9c4b..628e9288e8 100644 --- a/src/mesa/swrast_setup/ss_triangle.c +++ b/src/mesa/swrast_setup/ss_triangle.c @@ -290,8 +290,10 @@ void _swsetup_choose_trifuncs( GLcontext *ctx ) ctx->Polygon.OffsetFill) ind |= SS_OFFSET_BIT; + /* Note: gl_FrontFacing lives in fragment input FOGC.Y at this time */ if ((ctx->Light.Enabled && ctx->Light.Model.TwoSide) || - (ctx->VertexProgram._Enabled && ctx->VertexProgram.TwoSideEnabled)) + (ctx->VertexProgram._Enabled && ctx->VertexProgram.TwoSideEnabled) || + (ctx->FragmentProgram._Current && ctx->FragmentProgram._Current->Base.InputsRead & (1 << FRAG_ATTRIB_FOGC))) ind |= SS_TWOSIDE_BIT; /* We piggyback the two-sided stencil front/back determination on the diff --git a/src/mesa/swrast_setup/ss_tritmp.h b/src/mesa/swrast_setup/ss_tritmp.h index 61c9b2817e..5b14b283f1 100644 --- a/src/mesa/swrast_setup/ss_tritmp.h +++ b/src/mesa/swrast_setup/ss_tritmp.h @@ -55,8 +55,7 @@ static void TAG(triangle)(GLcontext *ctx, GLuint e0, GLuint e1, GLuint e2 ) if (IND & (SS_TWOSIDE_BIT | SS_UNFILLED_BIT)) { facing = (cc < 0.0) ^ ctx->Polygon._FrontBit; - if (ctx->Stencil.TestTwoSide) - ctx->_Facing = facing; /* for 2-sided stencil test */ + ctx->_Facing = facing; if (IND & SS_UNFILLED_BIT) mode = facing ? ctx->Polygon.BackMode : ctx->Polygon.FrontMode; diff --git a/src/mesa/tnl/t_context.c b/src/mesa/tnl/t_context.c index d9458b74ec..fa42a3df98 100644 --- a/src/mesa/tnl/t_context.c +++ b/src/mesa/tnl/t_context.c @@ -60,7 +60,7 @@ _tnl_CreateContext( GLcontext *ctx ) /* Initialize tnl state. */ - if (ctx->_MaintainTnlProgram) { + if (ctx->VertexProgram._MaintainTnlProgram) { _tnl_ProgramCacheInit( ctx ); _tnl_install_pipeline( ctx, _tnl_vp_pipeline ); } else { @@ -90,7 +90,7 @@ _tnl_DestroyContext( GLcontext *ctx ) _tnl_destroy_pipeline( ctx ); - if (ctx->_MaintainTnlProgram) + if (ctx->VertexProgram._MaintainTnlProgram) _tnl_ProgramCacheDestroy( ctx ); FREE(tnl); @@ -102,6 +102,8 @@ void _tnl_InvalidateState( GLcontext *ctx, GLuint new_state ) { TNLcontext *tnl = TNL_CONTEXT(ctx); + const struct gl_vertex_program *vp = ctx->VertexProgram._Current; + const struct gl_fragment_program *fp = ctx->FragmentProgram._Current; if (new_state & (_NEW_HINT)) { ASSERT(tnl->AllowVertexFog || tnl->AllowPixelFog); @@ -118,7 +120,9 @@ _tnl_InvalidateState( GLcontext *ctx, GLuint new_state ) RENDERINPUTS_ZERO( tnl->render_inputs_bitset ); RENDERINPUTS_SET( tnl->render_inputs_bitset, _TNL_ATTRIB_POS ); - RENDERINPUTS_SET( tnl->render_inputs_bitset, _TNL_ATTRIB_COLOR0 ); + if (!fp || fp->Base.InputsRead & FRAG_BIT_COL0) { + RENDERINPUTS_SET( tnl->render_inputs_bitset, _TNL_ATTRIB_COLOR0 ); + } for (i = 0; i < ctx->Const.MaxTextureCoordUnits; i++) { if (ctx->Texture._EnabledCoordUnits & (1 << i)) { RENDERINPUTS_SET( tnl->render_inputs_bitset, _TNL_ATTRIB_TEX(i) ); @@ -134,7 +138,7 @@ _tnl_InvalidateState( GLcontext *ctx, GLuint new_state ) } if (ctx->Fog.Enabled || - (ctx->FragmentProgram._Active && + (ctx->FragmentProgram._Current && (ctx->FragmentProgram._Current->FogOption != GL_NONE || ctx->FragmentProgram._Current->Base.InputsRead & FRAG_BIT_FOGC))) RENDERINPUTS_SET( tnl->render_inputs_bitset, _TNL_ATTRIB_FOG ); @@ -150,8 +154,16 @@ _tnl_InvalidateState( GLcontext *ctx, GLuint new_state ) (ctx->VertexProgram._Enabled && ctx->VertexProgram.PointSizeEnabled)) RENDERINPUTS_SET( tnl->render_inputs_bitset, _TNL_ATTRIB_POINTSIZE ); - if (ctx->ShaderObjects._VertexShaderPresent || ctx->ShaderObjects._FragmentShaderPresent) - RENDERINPUTS_SET_RANGE( tnl->render_inputs_bitset, _TNL_FIRST_GENERIC, _TNL_LAST_GENERIC ); + /* check for varying vars which are written by the vertex program */ + if (vp) { + GLuint i; + for (i = 0; i < MAX_VARYING; i++) { + if (vp->Base.OutputsWritten & (1 << (VERT_RESULT_VAR0 + i))) { + RENDERINPUTS_SET(tnl->render_inputs_bitset, + _TNL_ATTRIB_GENERIC(i)); + } + } + } } diff --git a/src/mesa/tnl/t_context.h b/src/mesa/tnl/t_context.h index a872f26177..31b89aca41 100644 --- a/src/mesa/tnl/t_context.h +++ b/src/mesa/tnl/t_context.h @@ -217,7 +217,6 @@ struct vertex_buffer GLvector4f *ColorPtr[2]; /* _TNL_BIT_COLOR0 */ GLvector4f *SecondaryColorPtr[2]; /* _TNL_BIT_COLOR1 */ GLvector4f *FogCoordPtr; /* _TNL_BIT_FOG */ - GLvector4f *VaryingPtr[MAX_VARYING_VECTORS]; const struct _mesa_prim *Primitive; GLuint PrimitiveCount; diff --git a/src/mesa/tnl/t_pipeline.c b/src/mesa/tnl/t_pipeline.c index 2efe701a80..a50a3f0f2f 100644 --- a/src/mesa/tnl/t_pipeline.c +++ b/src/mesa/tnl/t_pipeline.c @@ -132,7 +132,7 @@ void _tnl_run_pipeline( GLcontext *ctx ) * (ie const or non-const). */ if (check_input_changes( ctx ) || tnl->pipeline.new_state) { - if (ctx->_MaintainTnlProgram) + if (ctx->VertexProgram._MaintainTnlProgram) _tnl_UpdateFixedFunctionProgram( ctx ); for (i = 0; i < tnl->pipeline.nr_stages ; i++) { @@ -208,9 +208,6 @@ const struct tnl_pipeline_stage *_tnl_default_pipeline[] = { &_tnl_arb_vertex_program_stage, &_tnl_vertex_program_stage, #endif -#if FEATURE_ARB_vertex_shader - &_tnl_arb_vertex_shader_stage, -#endif &_tnl_render_stage, NULL }; diff --git a/src/mesa/tnl/t_save_api.c b/src/mesa/tnl/t_save_api.c new file mode 100644 index 0000000000..b08f05374e --- /dev/null +++ b/src/mesa/tnl/t_save_api.c @@ -0,0 +1,1834 @@ +/************************************************************************** + +Copyright 2002 Tungsten Graphics Inc., Cedar Park, Texas. + +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 +on the rights to use, copy, modify, merge, publish, distribute, sub +license, 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 (including the next +paragraph) 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 NON-INFRINGEMENT. IN NO EVENT SHALL +TUNGSTEN GRAPHICS AND/OR THEIR SUPPLIERS 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. + +**************************************************************************/ + +/* + * Authors: + * Keith Whitwell <keith@tungstengraphics.com> + */ + + + +/** + * The display list compiler attempts to store lists of vertices with the + * same vertex layout. Additionally it attempts to minimize the need + * for execute-time fixup of these vertex lists, allowing them to be + * cached on hardware. + * + * There are still some circumstances where this can be thwarted, for + * example by building a list that consists of one very long primitive + * (eg Begin(Triangles), 1000 vertices, End), and calling that list + * from inside a different begin/end object (Begin(Lines), CallList, + * End). + * + * In that case the code will have to replay the list as individual + * commands through the Exec dispatch table, or fix up the copied + * vertices at execute-time. + * + * The other case where fixup is required is when a vertex attribute + * is introduced in the middle of a primitive. Eg: + * Begin(Lines) + * TexCoord1f() Vertex2f() + * TexCoord1f() Color3f() Vertex2f() + * End() + * + * If the current value of Color isn't known at compile-time, this + * primitive will require fixup. + * + * + * The list compiler currently doesn't attempt to compile lists + * containing EvalCoord or EvalPoint commands. On encountering one of + * these, compilation falls back to opcodes. + * + * This could be improved to fallback only when a mix of EvalCoord and + * Vertex commands are issued within a single primitive. + */ + + +#include "glheader.h" +#include "context.h" +#include "dlist.h" +#include "enums.h" +#include "macros.h" +#include "api_validate.h" +#include "api_arrayelt.h" +#include "vtxfmt.h" +#include "t_save_api.h" +#include "dispatch.h" + +/* + * NOTE: Old 'parity' issue is gone, but copying can still be + * wrong-footed on replay. + */ +static GLuint _save_copy_vertices( GLcontext *ctx, + const struct tnl_vertex_list *node ) +{ + TNLcontext *tnl = TNL_CONTEXT( ctx ); + const struct tnl_prim *prim = &node->prim[node->prim_count-1]; + GLuint nr = prim->count; + GLuint sz = tnl->save.vertex_size; + const GLfloat *src = node->buffer + prim->start * sz; + GLfloat *dst = tnl->save.copied.buffer; + GLuint ovf, i; + + if (prim->mode & PRIM_END) + return 0; + + switch( prim->mode & PRIM_MODE_MASK ) + { + case GL_POINTS: + return 0; + case GL_LINES: + ovf = nr&1; + for (i = 0 ; i < ovf ; i++) + _mesa_memcpy( dst+i*sz, src+(nr-ovf+i)*sz, sz*sizeof(GLfloat) ); + return i; + case GL_TRIANGLES: + ovf = nr%3; + for (i = 0 ; i < ovf ; i++) + _mesa_memcpy( dst+i*sz, src+(nr-ovf+i)*sz, sz*sizeof(GLfloat) ); + return i; + case GL_QUADS: + ovf = nr&3; + for (i = 0 ; i < ovf ; i++) + _mesa_memcpy( dst+i*sz, src+(nr-ovf+i)*sz, sz*sizeof(GLfloat) ); + return i; + case GL_LINE_STRIP: + if (nr == 0) + return 0; + else { + _mesa_memcpy( dst, src+(nr-1)*sz, sz*sizeof(GLfloat) ); + return 1; + } + case GL_LINE_LOOP: + case GL_TRIANGLE_FAN: + case GL_POLYGON: + if (nr == 0) + return 0; + else if (nr == 1) { + _mesa_memcpy( dst, src+0, sz*sizeof(GLfloat) ); + return 1; + } else { + _mesa_memcpy( dst, src+0, sz*sizeof(GLfloat) ); + _mesa_memcpy( dst+sz, src+(nr-1)*sz, sz*sizeof(GLfloat) ); + return 2; + } + case GL_TRIANGLE_STRIP: + case GL_QUAD_STRIP: + switch (nr) { + case 0: ovf = 0; break; + case 1: ovf = 1; break; + default: ovf = 2 + (nr&1); break; + } + for (i = 0 ; i < ovf ; i++) + _mesa_memcpy( dst+i*sz, src+(nr-ovf+i)*sz, sz*sizeof(GLfloat) ); + return i; + default: + assert(0); + return 0; + } +} + + +static void +build_normal_lengths( struct tnl_vertex_list *node ) +{ + GLuint i; + GLfloat *len; + GLfloat *n = node->buffer; + GLuint stride = node->vertex_size; + GLuint count = node->count; + + len = node->normal_lengths = (GLfloat *) MALLOC( count * sizeof(GLfloat) ); + if (!len) + return; + + /* Find the normal of the first vertex: + */ + for (i = 0 ; i < _TNL_ATTRIB_NORMAL ; i++) + n += node->attrsz[i]; + + for (i = 0 ; i < count ; i++, n += stride) { + len[i] = LEN_3FV( n ); + if (len[i] > 0.0F) len[i] = 1.0F / len[i]; + } +} + +static struct tnl_vertex_store *alloc_vertex_store( GLcontext *ctx ) +{ + struct tnl_vertex_store *store = MALLOC_STRUCT(tnl_vertex_store); + (void) ctx; + store->used = 0; + store->refcount = 1; + return store; +} + +static struct tnl_primitive_store *alloc_prim_store( GLcontext *ctx ) +{ + struct tnl_primitive_store *store = MALLOC_STRUCT(tnl_primitive_store); + (void) ctx; + store->used = 0; + store->refcount = 1; + return store; +} + +static void _save_reset_counters( GLcontext *ctx ) +{ + TNLcontext *tnl = TNL_CONTEXT(ctx); + + tnl->save.prim = tnl->save.prim_store->buffer + tnl->save.prim_store->used; + tnl->save.buffer = (tnl->save.vertex_store->buffer + + tnl->save.vertex_store->used); + + if (tnl->save.vertex_size) + tnl->save.initial_counter = ((SAVE_BUFFER_SIZE - + tnl->save.vertex_store->used) / + tnl->save.vertex_size); + else + tnl->save.initial_counter = 0; + + if (tnl->save.initial_counter > ctx->Const.MaxArrayLockSize ) + tnl->save.initial_counter = ctx->Const.MaxArrayLockSize; + + tnl->save.counter = tnl->save.initial_counter; + tnl->save.prim_count = 0; + tnl->save.prim_max = SAVE_PRIM_SIZE - tnl->save.prim_store->used; + tnl->save.copied.nr = 0; + tnl->save.dangling_attr_ref = 0; +} + + +/* Insert the active immediate struct onto the display list currently + * being built. + */ +static void _save_compile_vertex_list( GLcontext *ctx ) +{ + TNLcontext *tnl = TNL_CONTEXT(ctx); + struct tnl_vertex_list *node; + + /* Allocate space for this structure in the display list currently + * being compiled. + */ + node = (struct tnl_vertex_list *) + _mesa_alloc_instruction(ctx, tnl->save.opcode_vertex_list, sizeof(*node)); + + if (!node) + return; + + /* Duplicate our template, increment refcounts to the storage structs: + */ + _mesa_memcpy(node->attrsz, tnl->save.attrsz, sizeof(node->attrsz)); + node->vertex_size = tnl->save.vertex_size; + node->buffer = tnl->save.buffer; + node->count = tnl->save.initial_counter - tnl->save.counter; + node->wrap_count = tnl->save.copied.nr; + node->have_materials = tnl->save.have_materials; + node->dangling_attr_ref = tnl->save.dangling_attr_ref; + node->normal_lengths = NULL; + node->prim = tnl->save.prim; + node->prim_count = tnl->save.prim_count; + node->vertex_store = tnl->save.vertex_store; + node->prim_store = tnl->save.prim_store; + + node->vertex_store->refcount++; + node->prim_store->refcount++; + + assert(node->attrsz[_TNL_ATTRIB_POS] != 0 || + node->count == 0); + + if (tnl->save.dangling_attr_ref) + ctx->ListState.CurrentList->flags |= MESA_DLIST_DANGLING_REFS; + + /* Maybe calculate normal lengths: + */ + if (tnl->CalcDListNormalLengths && + node->attrsz[_TNL_ATTRIB_NORMAL] == 3 && + !(ctx->ListState.CurrentList->flags & MESA_DLIST_DANGLING_REFS)) + build_normal_lengths( node ); + + + tnl->save.vertex_store->used += tnl->save.vertex_size * node->count; + tnl->save.prim_store->used += node->prim_count; + + /* Decide whether the storage structs are full, or can be used for + * the next vertex lists as well. + */ + if (tnl->save.vertex_store->used > + SAVE_BUFFER_SIZE - 16 * (tnl->save.vertex_size + 4)) { + + tnl->save.vertex_store->refcount--; + assert(tnl->save.vertex_store->refcount != 0); + tnl->save.vertex_store = alloc_vertex_store( ctx ); + tnl->save.vbptr = tnl->save.vertex_store->buffer; + } + + if (tnl->save.prim_store->used > SAVE_PRIM_SIZE - 6) { + tnl->save.prim_store->refcount--; + assert(tnl->save.prim_store->refcount != 0); + tnl->save.prim_store = alloc_prim_store( ctx ); + } + + /* Reset our structures for the next run of vertices: + */ + _save_reset_counters( ctx ); + + /* Copy duplicated vertices + */ + tnl->save.copied.nr = _save_copy_vertices( ctx, node ); + + + /* Deal with GL_COMPILE_AND_EXECUTE: + */ + if (ctx->ExecuteFlag) { + _tnl_playback_vertex_list( ctx, (void *) node ); + } +} + + +/* TODO -- If no new vertices have been stored, don't bother saving + * it. + */ +static void _save_wrap_buffers( GLcontext *ctx ) +{ + TNLcontext *tnl = TNL_CONTEXT(ctx); + GLint i = tnl->save.prim_count - 1; + GLenum mode; + + assert(i < (GLint) tnl->save.prim_max); + assert(i >= 0); + + /* Close off in-progress primitive. + */ + tnl->save.prim[i].count = ((tnl->save.initial_counter - tnl->save.counter) - + tnl->save.prim[i].start); + mode = tnl->save.prim[i].mode & ~(PRIM_BEGIN|PRIM_END); + + /* store the copied vertices, and allocate a new list. + */ + _save_compile_vertex_list( ctx ); + + /* Restart interrupted primitive + */ + tnl->save.prim[0].mode = mode; + tnl->save.prim[0].start = 0; + tnl->save.prim[0].count = 0; + tnl->save.prim_count = 1; +} + + + +/* Called only when buffers are wrapped as the result of filling the + * vertex_store struct. + */ +static void _save_wrap_filled_vertex( GLcontext *ctx ) +{ + TNLcontext *tnl = TNL_CONTEXT(ctx); + GLfloat *data = tnl->save.copied.buffer; + GLuint i; + + /* Emit a glEnd to close off the last vertex list. + */ + _save_wrap_buffers( ctx ); + + /* Copy stored stored vertices to start of new list. + */ + assert(tnl->save.counter > tnl->save.copied.nr); + + for (i = 0 ; i < tnl->save.copied.nr ; i++) { + _mesa_memcpy( tnl->save.vbptr, data, tnl->save.vertex_size * sizeof(GLfloat)); + data += tnl->save.vertex_size; + tnl->save.vbptr += tnl->save.vertex_size; + tnl->save.counter--; + } +} + + +static void _save_copy_to_current( GLcontext *ctx ) +{ + TNLcontext *tnl = TNL_CONTEXT(ctx); + GLuint i; + + /* XXX Use _TNL_FIRST_* and _TNL_LAST_* values instead? */ + for (i = _TNL_ATTRIB_POS+1 ; i <= _TNL_ATTRIB_EDGEFLAG ; i++) { + if (tnl->save.attrsz[i]) { + tnl->save.currentsz[i][0] = tnl->save.attrsz[i]; + COPY_CLEAN_4V(tnl->save.current[i], + tnl->save.attrsz[i], + tnl->save.attrptr[i]); + } + } + + /* Edgeflag requires special treatment: + * + * TODO: change edgeflag to GLfloat in Mesa. + */ + if (tnl->save.attrsz[_TNL_ATTRIB_EDGEFLAG]) { + ctx->ListState.ActiveEdgeFlag = 1; + tnl->save.CurrentFloatEdgeFlag = + tnl->save.attrptr[_TNL_ATTRIB_EDGEFLAG][0]; + ctx->ListState.CurrentEdgeFlag = + (tnl->save.CurrentFloatEdgeFlag == 1.0); + } +} + + +static void _save_copy_from_current( GLcontext *ctx ) +{ + TNLcontext *tnl = TNL_CONTEXT(ctx); + GLint i; + + for (i = _TNL_ATTRIB_POS+1 ; i <= _TNL_ATTRIB_EDGEFLAG ; i++) + switch (tnl->save.attrsz[i]) { + case 4: tnl->save.attrptr[i][3] = tnl->save.current[i][3]; + case 3: tnl->save.attrptr[i][2] = tnl->save.current[i][2]; + case 2: tnl->save.attrptr[i][1] = tnl->save.current[i][1]; + case 1: tnl->save.attrptr[i][0] = tnl->save.current[i][0]; + case 0: break; + } + + /* Edgeflag requires special treatment: + */ + if (tnl->save.attrsz[_TNL_ATTRIB_EDGEFLAG]) { + tnl->save.CurrentFloatEdgeFlag = (GLfloat)ctx->ListState.CurrentEdgeFlag; + tnl->save.attrptr[_TNL_ATTRIB_EDGEFLAG][0] = tnl->save.CurrentFloatEdgeFlag; + } +} + + + + +/* Flush existing data, set new attrib size, replay copied vertices. + */ +static void _save_upgrade_vertex( GLcontext *ctx, + GLuint attr, + GLuint newsz ) +{ + TNLcontext *tnl = TNL_CONTEXT(ctx); + GLuint oldsz; + GLuint i; + GLfloat *tmp; + + /* Store the current run of vertices, and emit a GL_END. Emit a + * BEGIN in the new buffer. + */ + if (tnl->save.initial_counter != tnl->save.counter) + _save_wrap_buffers( ctx ); + else + assert( tnl->save.copied.nr == 0 ); + + /* Do a COPY_TO_CURRENT to ensure back-copying works for the case + * when the attribute already exists in the vertex and is having + * its size increased. + */ + _save_copy_to_current( ctx ); + + /* Fix up sizes: + */ + oldsz = tnl->save.attrsz[attr]; + tnl->save.attrsz[attr] = newsz; + + tnl->save.vertex_size += newsz - oldsz; + tnl->save.counter = ((SAVE_BUFFER_SIZE - tnl->save.vertex_store->used) / + tnl->save.vertex_size); + if (tnl->save.counter > ctx->Const.MaxArrayLockSize ) + tnl->save.counter = ctx->Const.MaxArrayLockSize; + tnl->save.initial_counter = tnl->save.counter; + + /* Recalculate all the attrptr[] values: + */ + for (i = 0, tmp = tnl->save.vertex ; i < _TNL_ATTRIB_MAX ; i++) { + if (tnl->save.attrsz[i]) { + tnl->save.attrptr[i] = tmp; + tmp += tnl->save.attrsz[i]; + } + else + tnl->save.attrptr[i] = NULL; /* will not be dereferenced. */ + } + + /* Copy from current to repopulate the vertex with correct values. + */ + _save_copy_from_current( ctx ); + + /* Replay stored vertices to translate them to new format here. + * + * If there are copied vertices and the new (upgraded) attribute + * has not been defined before, this list is somewhat degenerate, + * and will need fixup at runtime. + */ + if (tnl->save.copied.nr) + { + GLfloat *data = tnl->save.copied.buffer; + GLfloat *dest = tnl->save.buffer; + GLuint j; + + /* Need to note this and fix up at runtime (or loopback): + */ + if (tnl->save.currentsz[attr][0] == 0) { + assert(oldsz == 0); + tnl->save.dangling_attr_ref = GL_TRUE; + +/* _mesa_debug(NULL, "_save_upgrade_vertex: dangling reference attr %d\n", */ +/* attr); */ + +#if 0 + /* The current strategy is to punt these degenerate cases + * through _tnl_loopback_vertex_list(), a lower-performance + * option. To minimize the impact of this, artificially + * reduce the size of this vertex_list. + */ + if (t->save.counter > 10) { + t->save.initial_counter = 10; + t->save.counter = 10; + } +#endif + } + + for (i = 0 ; i < tnl->save.copied.nr ; i++) { + for (j = 0 ; j < _TNL_ATTRIB_MAX ; j++) { + if (tnl->save.attrsz[j]) { + if (j == attr) { + if (oldsz) { + COPY_CLEAN_4V( dest, oldsz, data ); + data += oldsz; + dest += newsz; + } + else { + COPY_SZ_4V( dest, newsz, tnl->save.current[attr] ); + dest += newsz; + } + } + else { + GLint sz = tnl->save.attrsz[j]; + COPY_SZ_4V( dest, sz, data ); + data += sz; + dest += sz; + } + } + } + } + + tnl->save.vbptr = dest; + tnl->save.counter -= tnl->save.copied.nr; + } +} + + + + +/* Helper function for 'CHOOSE' macro. Do what's necessary when an + * entrypoint is called for the first time. + */ +static void do_choose( GLuint attr, GLuint sz, + void (*attr_func)( const GLfloat *), + void (*choose1)( const GLfloat *), + void (*choose2)( const GLfloat *), + void (*choose3)( const GLfloat *), + void (*choose4)( const GLfloat *), + const GLfloat *v ) +{ + GET_CURRENT_CONTEXT( ctx ); + TNLcontext *tnl = TNL_CONTEXT(ctx); + static GLfloat id[4] = { 0, 0, 0, 1 }; + int i; + + if (tnl->save.attrsz[attr] < sz) { + /* New size is larger. Need to flush existing vertices and get + * an enlarged vertex format. + */ + _save_upgrade_vertex( ctx, attr, sz ); + } + else { + /* New size is equal or smaller - just need to fill in some + * zeros. + */ + for (i = sz ; i <= tnl->save.attrsz[attr] ; i++) + tnl->save.attrptr[attr][i-1] = id[i-1]; + } + + /* Reset any active pointers for this attribute + */ + tnl->save.tabfv[attr][0] = choose1; + tnl->save.tabfv[attr][1] = choose2; + tnl->save.tabfv[attr][2] = choose3; + tnl->save.tabfv[attr][3] = choose4; + + /* Update the secondary dispatch table with the new function + */ + tnl->save.tabfv[attr][sz-1] = attr_func; + + (*attr_func)(v); +} + + + +/* Only one size for each attribute may be active at once. Eg. if + * Color3f is installed/active, then Color4f may not be, even if the + * vertex actually contains 4 color coordinates. This is because the + * 3f version won't otherwise set color[3] to 1.0 -- this is the job + * of the chooser function when switching between Color4f and Color3f. + */ +#define ATTRFV( ATTR, N ) \ +static void save_choose_##ATTR##_##N( const GLfloat *v ); \ + \ +static void save_attrib_##ATTR##_##N( const GLfloat *v ) \ +{ \ + GET_CURRENT_CONTEXT( ctx ); \ + TNLcontext *tnl = TNL_CONTEXT(ctx); \ + \ + if ((ATTR) == 0) { \ + GLuint i; \ + \ + if (N>0) tnl->save.vbptr[0] = v[0]; \ + if (N>1) tnl->save.vbptr[1] = v[1]; \ + if (N>2) tnl->save.vbptr[2] = v[2]; \ + if (N>3) tnl->save.vbptr[3] = v[3]; \ + \ + for (i = N; i < tnl->save.vertex_size; i++) \ + tnl->save.vbptr[i] = tnl->save.vertex[i]; \ + \ + tnl->save.vbptr += tnl->save.vertex_size; \ + \ + if (--tnl->save.counter == 0) \ + _save_wrap_filled_vertex( ctx ); \ + } \ + else { \ + GLfloat *dest = tnl->save.attrptr[ATTR]; \ + if (N>0) dest[0] = v[0]; \ + if (N>1) dest[1] = v[1]; \ + if (N>2) dest[2] = v[2]; \ + if (N>3) dest[3] = v[3]; \ + } \ +} + +#define CHOOSE( ATTR, N ) \ +static void save_choose_##ATTR##_##N( const GLfloat *v ) \ +{ \ + do_choose(ATTR, N, \ + save_attrib_##ATTR##_##N, \ + save_choose_##ATTR##_1, \ + save_choose_##ATTR##_2, \ + save_choose_##ATTR##_3, \ + save_choose_##ATTR##_4, \ + v ); \ +} + +#define INIT(ATTR) \ +static void save_init_##ATTR( TNLcontext *tnl ) \ +{ \ + tnl->save.tabfv[ATTR][0] = save_choose_##ATTR##_1; \ + tnl->save.tabfv[ATTR][1] = save_choose_##ATTR##_2; \ + tnl->save.tabfv[ATTR][2] = save_choose_##ATTR##_3; \ + tnl->save.tabfv[ATTR][3] = save_choose_##ATTR##_4; \ +} + +#define ATTRS( ATTRIB ) \ + ATTRFV( ATTRIB, 1 ) \ + ATTRFV( ATTRIB, 2 ) \ + ATTRFV( ATTRIB, 3 ) \ + ATTRFV( ATTRIB, 4 ) \ + CHOOSE( ATTRIB, 1 ) \ + CHOOSE( ATTRIB, 2 ) \ + CHOOSE( ATTRIB, 3 ) \ + CHOOSE( ATTRIB, 4 ) \ + INIT( ATTRIB ) \ + + +/* Generate a lot of functions. These are the actual worker + * functions, which are equivalent to those generated via codegen + * elsewhere. + */ +ATTRS( 0 ) +ATTRS( 1 ) +ATTRS( 2 ) +ATTRS( 3 ) +ATTRS( 4 ) +ATTRS( 5 ) +ATTRS( 6 ) +ATTRS( 7 ) +ATTRS( 8 ) +ATTRS( 9 ) +ATTRS( 10 ) +ATTRS( 11 ) +ATTRS( 12 ) +ATTRS( 13 ) +ATTRS( 14 ) +ATTRS( 15 ) + +ATTRS( 16 ) +ATTRS( 17 ) +ATTRS( 18 ) +ATTRS( 19 ) +ATTRS( 20 ) +ATTRS( 21 ) +ATTRS( 22 ) +ATTRS( 23 ) +ATTRS( 24 ) +ATTRS( 25 ) +ATTRS( 26 ) +ATTRS( 27 ) +ATTRS( 28 ) +ATTRS( 29 ) +ATTRS( 30 ) +ATTRS( 31 ) + + +static void _save_reset_vertex( GLcontext *ctx ) +{ + TNLcontext *tnl = TNL_CONTEXT(ctx); + GLuint i; + + /* conventional attributes */ + save_init_0( tnl ); + save_init_1( tnl ); + save_init_2( tnl ); + save_init_3( tnl ); + save_init_4( tnl ); + save_init_5( tnl ); + save_init_6( tnl ); + save_init_7( tnl ); + save_init_8( tnl ); + save_init_9( tnl ); + save_init_10( tnl ); + save_init_11( tnl ); + save_init_12( tnl ); + save_init_13( tnl ); + save_init_14( tnl ); + save_init_15( tnl ); + + /* generic attributes */ + save_init_16( tnl ); + save_init_17( tnl ); + save_init_18( tnl ); + save_init_19( tnl ); + save_init_20( tnl ); + save_init_21( tnl ); + save_init_22( tnl ); + save_init_23( tnl ); + save_init_24( tnl ); + save_init_25( tnl ); + save_init_26( tnl ); + save_init_27( tnl ); + save_init_28( tnl ); + save_init_29( tnl ); + save_init_30( tnl ); + save_init_31( tnl ); + + for (i = 0 ; i < _TNL_ATTRIB_MAX ; i++) + tnl->save.attrsz[i] = 0; + + tnl->save.vertex_size = 0; + tnl->save.have_materials = 0; + + _save_reset_counters( ctx ); +} + + + +/* Cope with aliasing of classic Vertex, Normal, etc. and the fan-out + * of glMultTexCoord and glProgramParamterNV by routing all these + * through a second level dispatch table. + */ +#define DISPATCH_ATTRFV( ATTR, COUNT, P ) \ +do { \ + GET_CURRENT_CONTEXT( ctx ); \ + TNLcontext *tnl = TNL_CONTEXT(ctx); \ + tnl->save.tabfv[ATTR][COUNT-1]( P ); \ +} while (0) + +#define DISPATCH_ATTR1FV( ATTR, V ) DISPATCH_ATTRFV( ATTR, 1, V ) +#define DISPATCH_ATTR2FV( ATTR, V ) DISPATCH_ATTRFV( ATTR, 2, V ) +#define DISPATCH_ATTR3FV( ATTR, V ) DISPATCH_ATTRFV( ATTR, 3, V ) +#define DISPATCH_ATTR4FV( ATTR, V ) DISPATCH_ATTRFV( ATTR, 4, V ) + +#define DISPATCH_ATTR1F( ATTR, S ) DISPATCH_ATTRFV( ATTR, 1, &(S) ) + +#if defined(USE_X86_ASM) && 0 /* will break register calling convention */ +/* Naughty cheat: + */ +#define DISPATCH_ATTR2F( ATTR, S,T ) DISPATCH_ATTRFV( ATTR, 2, &(S) ) +#define DISPATCH_ATTR3F( ATTR, S,T,R ) DISPATCH_ATTRFV( ATTR, 3, &(S) ) +#define DISPATCH_ATTR4F( ATTR, S,T,R,Q ) DISPATCH_ATTRFV( ATTR, 4, &(S) ) +#else +/* Safe: + */ +#define DISPATCH_ATTR2F( ATTR, S,T ) \ +do { \ + GLfloat v[2]; \ + v[0] = S; v[1] = T; \ + DISPATCH_ATTR2FV( ATTR, v ); \ +} while (0) +#define DISPATCH_ATTR3F( ATTR, S,T,R ) \ +do { \ + GLfloat v[3]; \ + v[0] = S; v[1] = T; v[2] = R; \ + DISPATCH_ATTR3FV( ATTR, v ); \ +} while (0) +#define DISPATCH_ATTR4F( ATTR, S,T,R,Q ) \ +do { \ + GLfloat v[4]; \ + v[0] = S; v[1] = T; v[2] = R; v[3] = Q; \ + DISPATCH_ATTR4FV( ATTR, v ); \ +} while (0) +#endif + + +static void enum_error( void ) +{ + GET_CURRENT_CONTEXT( ctx ); + _mesa_compile_error( ctx, GL_INVALID_ENUM, "glVertexAttrib" ); +} + +static void GLAPIENTRY _save_Vertex2f( GLfloat x, GLfloat y ) +{ + DISPATCH_ATTR2F( _TNL_ATTRIB_POS, x, y ); +} + +static void GLAPIENTRY _save_Vertex2fv( const GLfloat *v ) +{ + DISPATCH_ATTR2FV( _TNL_ATTRIB_POS, v ); +} + +static void GLAPIENTRY _save_Vertex3f( GLfloat x, GLfloat y, GLfloat z ) +{ + DISPATCH_ATTR3F( _TNL_ATTRIB_POS, x, y, z ); +} + +static void GLAPIENTRY _save_Vertex3fv( const GLfloat *v ) +{ + DISPATCH_ATTR3FV( _TNL_ATTRIB_POS, v ); +} + +static void GLAPIENTRY _save_Vertex4f( GLfloat x, GLfloat y, GLfloat z, GLfloat w ) +{ + DISPATCH_ATTR4F( _TNL_ATTRIB_POS, x, y, z, w ); +} + +static void GLAPIENTRY _save_Vertex4fv( const GLfloat *v ) +{ + DISPATCH_ATTR4FV( _TNL_ATTRIB_POS, v ); +} + +static void GLAPIENTRY _save_TexCoord1f( GLfloat x ) +{ + DISPATCH_ATTR1F( _TNL_ATTRIB_TEX0, x ); +} + +static void GLAPIENTRY _save_TexCoord1fv( const GLfloat *v ) +{ + DISPATCH_ATTR1FV( _TNL_ATTRIB_TEX0, v ); +} + +static void GLAPIENTRY _save_TexCoord2f( GLfloat x, GLfloat y ) +{ + DISPATCH_ATTR2F( _TNL_ATTRIB_TEX0, x, y ); +} + +static void GLAPIENTRY _save_TexCoord2fv( const GLfloat *v ) +{ + DISPATCH_ATTR2FV( _TNL_ATTRIB_TEX0, v ); +} + +static void GLAPIENTRY _save_TexCoord3f( GLfloat x, GLfloat y, GLfloat z ) +{ + DISPATCH_ATTR3F( _TNL_ATTRIB_TEX0, x, y, z ); +} + +static void GLAPIENTRY _save_TexCoord3fv( const GLfloat *v ) +{ + DISPATCH_ATTR3FV( _TNL_ATTRIB_TEX0, v ); +} + +static void GLAPIENTRY _save_TexCoord4f( GLfloat x, GLfloat y, GLfloat z, GLfloat w ) +{ + DISPATCH_ATTR4F( _TNL_ATTRIB_TEX0, x, y, z, w ); +} + +static void GLAPIENTRY _save_TexCoord4fv( const GLfloat *v ) +{ + DISPATCH_ATTR4FV( _TNL_ATTRIB_TEX0, v ); +} + +static void GLAPIENTRY _save_Normal3f( GLfloat x, GLfloat y, GLfloat z ) +{ + DISPATCH_ATTR3F( _TNL_ATTRIB_NORMAL, x, y, z ); +} + +static void GLAPIENTRY _save_Normal3fv( const GLfloat *v ) +{ + DISPATCH_ATTR3FV( _TNL_ATTRIB_NORMAL, v ); +} + +static void GLAPIENTRY _save_FogCoordfEXT( GLfloat x ) +{ + DISPATCH_ATTR1F( _TNL_ATTRIB_FOG, x ); +} + +static void GLAPIENTRY _save_FogCoordfvEXT( const GLfloat *v ) +{ + DISPATCH_ATTR1FV( _TNL_ATTRIB_FOG, v ); +} + +static void GLAPIENTRY _save_Color3f( GLfloat x, GLfloat y, GLfloat z ) +{ + DISPATCH_ATTR3F( _TNL_ATTRIB_COLOR0, x, y, z ); +} + +static void GLAPIENTRY _save_Color3fv( const GLfloat *v ) +{ + DISPATCH_ATTR3FV( _TNL_ATTRIB_COLOR0, v ); +} + +static void GLAPIENTRY _save_Color4f( GLfloat x, GLfloat y, GLfloat z, GLfloat w ) +{ + DISPATCH_ATTR4F( _TNL_ATTRIB_COLOR0, x, y, z, w ); +} + +static void GLAPIENTRY _save_Color4fv( const GLfloat *v ) +{ + DISPATCH_ATTR4FV( _TNL_ATTRIB_COLOR0, v ); +} + +static void GLAPIENTRY _save_SecondaryColor3fEXT( GLfloat x, GLfloat y, GLfloat z ) +{ + DISPATCH_ATTR3F( _TNL_ATTRIB_COLOR1, x, y, z ); +} + +static void GLAPIENTRY _save_SecondaryColor3fvEXT( const GLfloat *v ) +{ + DISPATCH_ATTR3FV( _TNL_ATTRIB_COLOR1, v ); +} + +static void GLAPIENTRY _save_MultiTexCoord1f( GLenum target, GLfloat x ) +{ + GLuint attr = (target & 0x7) + _TNL_ATTRIB_TEX0; + DISPATCH_ATTR1F( attr, x ); +} + +static void GLAPIENTRY _save_MultiTexCoord1fv( GLenum target, const GLfloat *v ) +{ + GLuint attr = (target & 0x7) + _TNL_ATTRIB_TEX0; + DISPATCH_ATTR1FV( attr, v ); +} + +static void GLAPIENTRY _save_MultiTexCoord2f( GLenum target, GLfloat x, GLfloat y ) +{ + GLuint attr = (target & 0x7) + _TNL_ATTRIB_TEX0; + DISPATCH_ATTR2F( attr, x, y ); +} + +static void GLAPIENTRY _save_MultiTexCoord2fv( GLenum target, const GLfloat *v ) +{ + GLuint attr = (target & 0x7) + _TNL_ATTRIB_TEX0; + DISPATCH_ATTR2FV( attr, v ); +} + +static void GLAPIENTRY _save_MultiTexCoord3f( GLenum target, GLfloat x, GLfloat y, + GLfloat z) +{ + GLuint attr = (target & 0x7) + _TNL_ATTRIB_TEX0; + DISPATCH_ATTR3F( attr, x, y, z ); +} + +static void GLAPIENTRY _save_MultiTexCoord3fv( GLenum target, const GLfloat *v ) +{ + GLuint attr = (target & 0x7) + _TNL_ATTRIB_TEX0; + DISPATCH_ATTR3FV( attr, v ); +} + +static void GLAPIENTRY _save_MultiTexCoord4f( GLenum target, GLfloat x, GLfloat y, + GLfloat z, GLfloat w ) +{ + GLuint attr = (target & 0x7) + _TNL_ATTRIB_TEX0; + DISPATCH_ATTR4F( attr, x, y, z, w ); +} + +static void GLAPIENTRY _save_MultiTexCoord4fv( GLenum target, const GLfloat *v ) +{ + GLuint attr = (target & 0x7) + _TNL_ATTRIB_TEX0; + DISPATCH_ATTR4FV( attr, v ); +} + + + +static void GLAPIENTRY +_save_VertexAttrib1fNV(GLuint index, GLfloat x) +{ + if (index < MAX_VERTEX_PROGRAM_ATTRIBS) { + if (index > 0) + index += VERT_ATTRIB_GENERIC0; + DISPATCH_ATTR1F( index, x ); + } + else + enum_error(); +} + +static void GLAPIENTRY +_save_VertexAttrib1fvNV(GLuint index, const GLfloat *v) +{ + if (index < MAX_VERTEX_PROGRAM_ATTRIBS) { + if (index > 0) + index += VERT_ATTRIB_GENERIC0; + DISPATCH_ATTR1FV( index, v ); + } + else + enum_error(); +} + +static void GLAPIENTRY +_save_VertexAttrib2fNV(GLuint index, GLfloat x, GLfloat y) +{ + if (index < MAX_VERTEX_PROGRAM_ATTRIBS) { + if (index > 0) + index += VERT_ATTRIB_GENERIC0; + DISPATCH_ATTR2F( index, x, y ); + } + else + enum_error(); +} + +static void GLAPIENTRY +_save_VertexAttrib2fvNV(GLuint index, const GLfloat *v) +{ + if (index < MAX_VERTEX_PROGRAM_ATTRIBS) { + if (index > 0) + index += VERT_ATTRIB_GENERIC0; + DISPATCH_ATTR2FV( index, v ); + } + else + enum_error(); +} + +static void GLAPIENTRY +_save_VertexAttrib3fNV(GLuint index, GLfloat x, GLfloat y, GLfloat z) +{ + if (index < MAX_VERTEX_PROGRAM_ATTRIBS) { + if (index > 0) + index += VERT_ATTRIB_GENERIC0; + DISPATCH_ATTR3F( index, x, y, z ); + } + else + enum_error(); +} + +static void GLAPIENTRY +_save_VertexAttrib3fvNV(GLuint index, const GLfloat *v) +{ + if (index < MAX_VERTEX_PROGRAM_ATTRIBS) { + if (index > 0) + index += VERT_ATTRIB_GENERIC0; + DISPATCH_ATTR3FV( index, v ); + } + else + enum_error(); +} + +static void GLAPIENTRY +_save_VertexAttrib4fNV(GLuint index, GLfloat x, GLfloat y, + GLfloat z, GLfloat w) +{ + if (index < MAX_VERTEX_PROGRAM_ATTRIBS) { + if (index > 0) + index += VERT_ATTRIB_GENERIC0; + DISPATCH_ATTR4F( index, x, y, z, w ); + } + else + enum_error(); +} + +static void GLAPIENTRY +_save_VertexAttrib4fvNV(GLuint index, const GLfloat *v) +{ + if (index < MAX_VERTEX_PROGRAM_ATTRIBS) { + if (index > 0) + index += VERT_ATTRIB_GENERIC0; + DISPATCH_ATTR4FV( index, v ); + } + else + enum_error(); +} + +static void GLAPIENTRY +_save_VertexAttrib1fARB(GLuint index, GLfloat x) +{ + if (index < MAX_VERTEX_ATTRIBS) { + if (index > 0) + index += VERT_ATTRIB_GENERIC0; + DISPATCH_ATTR1F( index, x ); + } + else + enum_error(); +} + +static void GLAPIENTRY +_save_VertexAttrib1fvARB(GLuint index, const GLfloat *v) +{ + if (index < MAX_VERTEX_ATTRIBS) { + if (index > 0) + index += VERT_ATTRIB_GENERIC0; + DISPATCH_ATTR1FV( index, v ); + } + else + enum_error(); +} + +static void GLAPIENTRY +_save_VertexAttrib2fARB(GLuint index, GLfloat x, GLfloat y) +{ + if (index < MAX_VERTEX_ATTRIBS) { + if (index > 0) + index += VERT_ATTRIB_GENERIC0; + DISPATCH_ATTR2F( index, x, y ); + } + else + enum_error(); +} + +static void GLAPIENTRY +_save_VertexAttrib2fvARB(GLuint index, const GLfloat *v) +{ + if (index < MAX_VERTEX_ATTRIBS) { + if (index > 0) + index += VERT_ATTRIB_GENERIC0; + DISPATCH_ATTR2FV( index, v ); + } + else + enum_error(); +} + +static void GLAPIENTRY +_save_VertexAttrib3fARB(GLuint index, GLfloat x, GLfloat y, GLfloat z) +{ + if (index < MAX_VERTEX_ATTRIBS) { + if (index > 0) + index += VERT_ATTRIB_GENERIC0; + DISPATCH_ATTR3F( index, x, y, z ); + } + else + enum_error(); +} + +static void GLAPIENTRY +_save_VertexAttrib3fvARB(GLuint index, const GLfloat *v) +{ + if (index < MAX_VERTEX_ATTRIBS) { + if (index > 0) + index += VERT_ATTRIB_GENERIC0; + DISPATCH_ATTR3FV( index, v ); + } + else + enum_error(); +} + +static void GLAPIENTRY +_save_VertexAttrib4fARB(GLuint index, GLfloat x, GLfloat y, + GLfloat z, GLfloat w) +{ + if (index < MAX_VERTEX_ATTRIBS) { + if (index > 0) + index += VERT_ATTRIB_GENERIC0; + DISPATCH_ATTR4F( index, x, y, z, w ); + } + else + enum_error(); +} + +static void GLAPIENTRY +_save_VertexAttrib4fvARB(GLuint index, const GLfloat *v) +{ + if (index < MAX_VERTEX_ATTRIBS) { + if (index > 0) + index += VERT_ATTRIB_GENERIC0; + DISPATCH_ATTR4FV( index, v ); + } + else + enum_error(); +} + + +/* Materials: + * + * These are treated as per-vertex attributes, at indices above where + * the NV_vertex_program leaves off. There are a lot of good things + * about treating materials this way. + * + * However: I don't want to double the number of generated functions + * just to cope with this, so I unroll the 'C' varients of CHOOSE and + * ATTRF into this function, and dispense with codegen and + * second-level dispatch. + * + * There is no aliasing of material attributes with other entrypoints. + */ +#define MAT_ATTR( A, N, params ) \ +do { \ + if (tnl->save.attrsz[A] < N) { \ + _save_upgrade_vertex( ctx, A, N ); \ + tnl->save.have_materials = GL_TRUE; \ + } \ + \ + { \ + GLfloat *dest = tnl->save.attrptr[A]; \ + if (N>0) dest[0] = params[0]; \ + if (N>1) dest[1] = params[1]; \ + if (N>2) dest[2] = params[2]; \ + if (N>3) dest[3] = params[3]; \ + } \ +} while (0) + + +#define MAT( ATTR, N, face, params ) \ +do { \ + if (face != GL_BACK) \ + MAT_ATTR( ATTR, N, params ); /* front */ \ + if (face != GL_FRONT) \ + MAT_ATTR( ATTR + 1, N, params ); /* back */ \ +} while (0) + + +/* NOTE: Have to remove/deal-with colormaterial crossovers, probably + * later on - in the meantime just store everything. + */ +static void GLAPIENTRY _save_Materialfv( GLenum face, GLenum pname, + const GLfloat *params ) +{ + GET_CURRENT_CONTEXT( ctx ); + TNLcontext *tnl = TNL_CONTEXT(ctx); + + switch (pname) { + case GL_EMISSION: + MAT( _TNL_ATTRIB_MAT_FRONT_EMISSION, 4, face, params ); + break; + case GL_AMBIENT: + MAT( _TNL_ATTRIB_MAT_FRONT_AMBIENT, 4, face, params ); + break; + case GL_DIFFUSE: + MAT( _TNL_ATTRIB_MAT_FRONT_DIFFUSE, 4, face, params ); + break; + case GL_SPECULAR: + MAT( _TNL_ATTRIB_MAT_FRONT_SPECULAR, 4, face, params ); + break; + case GL_SHININESS: + MAT( _TNL_ATTRIB_MAT_FRONT_SHININESS, 1, face, params ); + break; + case GL_COLOR_INDEXES: + MAT( _TNL_ATTRIB_MAT_FRONT_INDEXES, 3, face, params ); + break; + case GL_AMBIENT_AND_DIFFUSE: + MAT( _TNL_ATTRIB_MAT_FRONT_AMBIENT, 4, face, params ); + MAT( _TNL_ATTRIB_MAT_FRONT_DIFFUSE, 4, face, params ); + break; + default: + _mesa_compile_error( ctx, GL_INVALID_ENUM, "glMaterialfv" ); + return; + } +} + + +#define IDX_ATTR( A, IDX ) \ +do { \ + GET_CURRENT_CONTEXT( ctx ); \ + TNLcontext *tnl = TNL_CONTEXT(ctx); \ + \ + if (tnl->save.attrsz[A] < 1) { \ + _save_upgrade_vertex( ctx, A, 1 ); \ + } \ + \ + { \ + GLfloat *dest = tnl->save.attrptr[A]; \ + dest[0] = IDX; \ + } \ +} while (0) + + +static void GLAPIENTRY _save_EdgeFlag( GLboolean b ) +{ + IDX_ATTR( _TNL_ATTRIB_EDGEFLAG, (GLfloat)b ); +} + + +static void GLAPIENTRY _save_Indexf( GLfloat f ) +{ + IDX_ATTR( _TNL_ATTRIB_COLOR_INDEX, f ); +} + +static void GLAPIENTRY _save_Indexfv( const GLfloat *f ) +{ + IDX_ATTR( _TNL_ATTRIB_COLOR_INDEX, f[0] ); +} + + + + +/* Cope with EvalCoord/CallList called within a begin/end object: + * -- Flush current buffer + * -- Fallback to opcodes for the rest of the begin/end object. + */ +#define FALLBACK(ctx) \ +do { \ + TNLcontext *tnl = TNL_CONTEXT(ctx); \ + \ + if (tnl->save.initial_counter != tnl->save.counter || \ + tnl->save.prim_count) \ + _save_compile_vertex_list( ctx ); \ + \ + _save_copy_to_current( ctx ); \ + _save_reset_vertex( ctx ); \ + _mesa_install_save_vtxfmt( ctx, &ctx->ListState.ListVtxfmt ); \ + ctx->Driver.SaveNeedFlush = 0; \ +} while (0) + +static void GLAPIENTRY _save_EvalCoord1f( GLfloat u ) +{ + GET_CURRENT_CONTEXT(ctx); + FALLBACK(ctx); + CALL_EvalCoord1f(ctx->Save, ( u )); +} + +static void GLAPIENTRY _save_EvalCoord1fv( const GLfloat *v ) +{ + GET_CURRENT_CONTEXT(ctx); + FALLBACK(ctx); + CALL_EvalCoord1fv(ctx->Save, ( v )); +} + +static void GLAPIENTRY _save_EvalCoord2f( GLfloat u, GLfloat v ) +{ + GET_CURRENT_CONTEXT(ctx); + FALLBACK(ctx); + CALL_EvalCoord2f(ctx->Save, ( u, v )); +} + +static void GLAPIENTRY _save_EvalCoord2fv( const GLfloat *v ) +{ + GET_CURRENT_CONTEXT(ctx); + FALLBACK(ctx); + CALL_EvalCoord2fv(ctx->Save, ( v )); +} + +static void GLAPIENTRY _save_EvalPoint1( GLint i ) +{ + GET_CURRENT_CONTEXT(ctx); + FALLBACK(ctx); + CALL_EvalPoint1(ctx->Save, ( i )); +} + +static void GLAPIENTRY _save_EvalPoint2( GLint i, GLint j ) +{ + GET_CURRENT_CONTEXT(ctx); + FALLBACK(ctx); + CALL_EvalPoint2(ctx->Save, ( i, j )); +} + +static void GLAPIENTRY _save_CallList( GLuint l ) +{ + GET_CURRENT_CONTEXT(ctx); + FALLBACK(ctx); + CALL_CallList(ctx->Save, ( l )); +} + +static void GLAPIENTRY _save_CallLists( GLsizei n, GLenum type, const GLvoid *v ) +{ + GET_CURRENT_CONTEXT(ctx); + FALLBACK(ctx); + CALL_CallLists(ctx->Save, ( n, type, v )); +} + + + + +/** + * Called via ctx->Driver.NotifySaveBegin(ctx, mode) when we get a + * glBegin() call while compiling a display list. + * See save_Begin() in dlist.c + * + * This plugs in our special TNL-related display list functions. + * All subsequent glBegin/glVertex/glEnd()s found while compiling a + * display list will get routed to the functions in this file. + * + * Updating of ctx->Driver.CurrentSavePrimitive is already taken care of. + */ +static GLboolean _save_NotifyBegin( GLcontext *ctx, GLenum mode ) +{ + TNLcontext *tnl = TNL_CONTEXT(ctx); + + if (1) { + GLuint i = tnl->save.prim_count++; + + assert(i < tnl->save.prim_max); + tnl->save.prim[i].mode = mode | PRIM_BEGIN; + tnl->save.prim[i].start = tnl->save.initial_counter - tnl->save.counter; + tnl->save.prim[i].count = 0; + + _mesa_install_save_vtxfmt( ctx, &tnl->save_vtxfmt ); + ctx->Driver.SaveNeedFlush = 1; + return GL_TRUE; + } + else + return GL_FALSE; +} + + + +static void GLAPIENTRY _save_End( void ) +{ + GET_CURRENT_CONTEXT( ctx ); + TNLcontext *tnl = TNL_CONTEXT(ctx); + GLint i = tnl->save.prim_count - 1; + + ctx->Driver.CurrentSavePrimitive = PRIM_OUTSIDE_BEGIN_END; + if (ctx->ExecuteFlag) + ctx->Driver.CurrentExecPrimitive = PRIM_OUTSIDE_BEGIN_END; + + tnl->save.prim[i].mode |= PRIM_END; + tnl->save.prim[i].count = ((tnl->save.initial_counter - tnl->save.counter) - + tnl->save.prim[i].start); + + if (i == (GLint) tnl->save.prim_max - 1) { + _save_compile_vertex_list( ctx ); + assert(tnl->save.copied.nr == 0); + } + + /* Swap out this vertex format while outside begin/end. Any color, + * etc. received between here and the next begin will be compiled + * as opcodes. + */ + _mesa_install_save_vtxfmt( ctx, &ctx->ListState.ListVtxfmt ); +} + + +/* These are all errors as this vtxfmt is only installed inside + * begin/end pairs. + */ +static void GLAPIENTRY _save_DrawElements(GLenum mode, GLsizei count, GLenum type, + const GLvoid *indices) +{ + GET_CURRENT_CONTEXT(ctx); + (void) mode; (void) count; (void) type; (void) indices; + _mesa_compile_error( ctx, GL_INVALID_OPERATION, "glDrawElements" ); +} + + +static void GLAPIENTRY _save_DrawRangeElements(GLenum mode, + GLuint start, GLuint end, + GLsizei count, GLenum type, + const GLvoid *indices) +{ + GET_CURRENT_CONTEXT(ctx); + (void) mode; (void) start; (void) end; (void) count; (void) type; (void) indices; + _mesa_compile_error( ctx, GL_INVALID_OPERATION, "glDrawRangeElements" ); +} + +static void GLAPIENTRY _save_DrawArrays(GLenum mode, GLint start, GLsizei count) +{ + GET_CURRENT_CONTEXT(ctx); + (void) mode; (void) start; (void) count; + _mesa_compile_error( ctx, GL_INVALID_OPERATION, "glDrawArrays" ); +} + +static void GLAPIENTRY _save_Rectf( GLfloat x1, GLfloat y1, GLfloat x2, GLfloat y2 ) +{ + GET_CURRENT_CONTEXT(ctx); + (void) x1; (void) y1; (void) x2; (void) y2; + _mesa_compile_error( ctx, GL_INVALID_OPERATION, "glRectf" ); +} + +static void GLAPIENTRY _save_EvalMesh1( GLenum mode, GLint i1, GLint i2 ) +{ + GET_CURRENT_CONTEXT(ctx); + (void) mode; (void) i1; (void) i2; + _mesa_compile_error( ctx, GL_INVALID_OPERATION, "glEvalMesh1" ); +} + +static void GLAPIENTRY _save_EvalMesh2( GLenum mode, GLint i1, GLint i2, + GLint j1, GLint j2 ) +{ + GET_CURRENT_CONTEXT(ctx); + (void) mode; (void) i1; (void) i2; (void) j1; (void) j2; + _mesa_compile_error( ctx, GL_INVALID_OPERATION, "glEvalMesh2" ); +} + +/** + * This is only called if someone tries to compile nested glBegin()s + * in their display list. + */ +static void GLAPIENTRY _save_Begin( GLenum mode ) +{ + GET_CURRENT_CONTEXT( ctx ); + (void) mode; + _mesa_compile_error(ctx, GL_INVALID_OPERATION, + "glBegin(called inside glBegin/End)"); +} + + +/* Unlike the functions above, these are to be hooked into the vtxfmt + * maintained in ctx->ListState, active when the list is known or + * suspected to be outside any begin/end primitive. + */ +static void GLAPIENTRY _save_OBE_Rectf( GLfloat x1, GLfloat y1, GLfloat x2, GLfloat y2 ) +{ + GET_CURRENT_CONTEXT(ctx); + _save_NotifyBegin( ctx, GL_QUADS | PRIM_WEAK ); + CALL_Vertex2f(GET_DISPATCH(), ( x1, y1 )); + CALL_Vertex2f(GET_DISPATCH(), ( x2, y1 )); + CALL_Vertex2f(GET_DISPATCH(), ( x2, y2 )); + CALL_Vertex2f(GET_DISPATCH(), ( x1, y2 )); + CALL_End(GET_DISPATCH(), ()); +} + + +static void GLAPIENTRY _save_OBE_DrawArrays(GLenum mode, GLint start, GLsizei count) +{ + GET_CURRENT_CONTEXT(ctx); + GLint i; + + if (!_mesa_validate_DrawArrays( ctx, mode, start, count )) + return; + + _ae_map_vbos( ctx ); + + _save_NotifyBegin( ctx, mode | PRIM_WEAK ); + for (i = 0; i < count; i++) + CALL_ArrayElement(GET_DISPATCH(), (start + i)); + CALL_End(GET_DISPATCH(), ()); + + _ae_unmap_vbos( ctx ); +} + + +static void GLAPIENTRY _save_OBE_DrawElements(GLenum mode, GLsizei count, GLenum type, + const GLvoid *indices) +{ + GET_CURRENT_CONTEXT(ctx); + GLint i; + + if (!_mesa_validate_DrawElements( ctx, mode, count, type, indices )) + return; + + _ae_map_vbos( ctx ); + + _save_NotifyBegin( ctx, mode | PRIM_WEAK ); + + switch (type) { + case GL_UNSIGNED_BYTE: + for (i = 0 ; i < count ; i++) + CALL_ArrayElement(GET_DISPATCH(), ( ((GLubyte *)indices)[i] )); + break; + case GL_UNSIGNED_SHORT: + for (i = 0 ; i < count ; i++) + CALL_ArrayElement(GET_DISPATCH(), ( ((GLushort *)indices)[i] )); + break; + case GL_UNSIGNED_INT: + for (i = 0 ; i < count ; i++) + CALL_ArrayElement(GET_DISPATCH(), ( ((GLuint *)indices)[i] )); + break; + default: + _mesa_error( ctx, GL_INVALID_ENUM, "glDrawElements(type)" ); + break; + } + + CALL_End(GET_DISPATCH(), ()); + + _ae_unmap_vbos( ctx ); +} + +static void GLAPIENTRY _save_OBE_DrawRangeElements(GLenum mode, + GLuint start, GLuint end, + GLsizei count, GLenum type, + const GLvoid *indices) +{ + GET_CURRENT_CONTEXT(ctx); + if (_mesa_validate_DrawRangeElements( ctx, mode, + start, end, + count, type, indices )) + _save_OBE_DrawElements( mode, count, type, indices ); +} + + + + + +static void _save_vtxfmt_init( GLcontext *ctx ) +{ + TNLcontext *tnl = TNL_CONTEXT(ctx); + GLvertexformat *vfmt = &tnl->save_vtxfmt; + + vfmt->ArrayElement = _ae_loopback_array_elt; /* generic helper */ + vfmt->Begin = _save_Begin; + vfmt->Color3f = _save_Color3f; + vfmt->Color3fv = _save_Color3fv; + vfmt->Color4f = _save_Color4f; + vfmt->Color4fv = _save_Color4fv; + vfmt->EdgeFlag = _save_EdgeFlag; + vfmt->End = _save_End; + vfmt->FogCoordfEXT = _save_FogCoordfEXT; + vfmt->FogCoordfvEXT = _save_FogCoordfvEXT; + vfmt->Indexf = _save_Indexf; + vfmt->Indexfv = _save_Indexfv; + vfmt->Materialfv = _save_Materialfv; + vfmt->MultiTexCoord1fARB = _save_MultiTexCoord1f; + vfmt->MultiTexCoord1fvARB = _save_MultiTexCoord1fv; + vfmt->MultiTexCoord2fARB = _save_MultiTexCoord2f; + vfmt->MultiTexCoord2fvARB = _save_MultiTexCoord2fv; + vfmt->MultiTexCoord3fARB = _save_MultiTexCoord3f; + vfmt->MultiTexCoord3fvARB = _save_MultiTexCoord3fv; + vfmt->MultiTexCoord4fARB = _save_MultiTexCoord4f; + vfmt->MultiTexCoord4fvARB = _save_MultiTexCoord4fv; + vfmt->Normal3f = _save_Normal3f; + vfmt->Normal3fv = _save_Normal3fv; + vfmt->SecondaryColor3fEXT = _save_SecondaryColor3fEXT; + vfmt->SecondaryColor3fvEXT = _save_SecondaryColor3fvEXT; + vfmt->TexCoord1f = _save_TexCoord1f; + vfmt->TexCoord1fv = _save_TexCoord1fv; + vfmt->TexCoord2f = _save_TexCoord2f; + vfmt->TexCoord2fv = _save_TexCoord2fv; + vfmt->TexCoord3f = _save_TexCoord3f; + vfmt->TexCoord3fv = _save_TexCoord3fv; + vfmt->TexCoord4f = _save_TexCoord4f; + vfmt->TexCoord4fv = _save_TexCoord4fv; + vfmt->Vertex2f = _save_Vertex2f; + vfmt->Vertex2fv = _save_Vertex2fv; + vfmt->Vertex3f = _save_Vertex3f; + vfmt->Vertex3fv = _save_Vertex3fv; + vfmt->Vertex4f = _save_Vertex4f; + vfmt->Vertex4fv = _save_Vertex4fv; + vfmt->VertexAttrib1fNV = _save_VertexAttrib1fNV; + vfmt->VertexAttrib1fvNV = _save_VertexAttrib1fvNV; + vfmt->VertexAttrib2fNV = _save_VertexAttrib2fNV; + vfmt->VertexAttrib2fvNV = _save_VertexAttrib2fvNV; + vfmt->VertexAttrib3fNV = _save_VertexAttrib3fNV; + vfmt->VertexAttrib3fvNV = _save_VertexAttrib3fvNV; + vfmt->VertexAttrib4fNV = _save_VertexAttrib4fNV; + vfmt->VertexAttrib4fvNV = _save_VertexAttrib4fvNV; + vfmt->VertexAttrib1fARB = _save_VertexAttrib1fARB; + vfmt->VertexAttrib1fvARB = _save_VertexAttrib1fvARB; + vfmt->VertexAttrib2fARB = _save_VertexAttrib2fARB; + vfmt->VertexAttrib2fvARB = _save_VertexAttrib2fvARB; + vfmt->VertexAttrib3fARB = _save_VertexAttrib3fARB; + vfmt->VertexAttrib3fvARB = _save_VertexAttrib3fvARB; + vfmt->VertexAttrib4fARB = _save_VertexAttrib4fARB; + vfmt->VertexAttrib4fvARB = _save_VertexAttrib4fvARB; + + /* This will all require us to fallback to saving the list as opcodes: + */ + vfmt->CallList = _save_CallList; /* inside begin/end */ + vfmt->CallLists = _save_CallLists; /* inside begin/end */ + vfmt->EvalCoord1f = _save_EvalCoord1f; + vfmt->EvalCoord1fv = _save_EvalCoord1fv; + vfmt->EvalCoord2f = _save_EvalCoord2f; + vfmt->EvalCoord2fv = _save_EvalCoord2fv; + vfmt->EvalPoint1 = _save_EvalPoint1; + vfmt->EvalPoint2 = _save_EvalPoint2; + + /* These are all errors as we at least know we are in some sort of + * begin/end pair: + */ + vfmt->EvalMesh1 = _save_EvalMesh1; + vfmt->EvalMesh2 = _save_EvalMesh2; + vfmt->Begin = _save_Begin; + vfmt->Rectf = _save_Rectf; + vfmt->DrawArrays = _save_DrawArrays; + vfmt->DrawElements = _save_DrawElements; + vfmt->DrawRangeElements = _save_DrawRangeElements; + +} + + +void _tnl_SaveFlushVertices( GLcontext *ctx ) +{ + TNLcontext *tnl = TNL_CONTEXT(ctx); + + /* Noop when we are actually active: + */ + if (ctx->Driver.CurrentSavePrimitive == PRIM_INSIDE_UNKNOWN_PRIM || + ctx->Driver.CurrentSavePrimitive <= GL_POLYGON) + return; + + if (tnl->save.initial_counter != tnl->save.counter || + tnl->save.prim_count) + _save_compile_vertex_list( ctx ); + + _save_copy_to_current( ctx ); + _save_reset_vertex( ctx ); + ctx->Driver.SaveNeedFlush = 0; +} + +void _tnl_NewList( GLcontext *ctx, GLuint list, GLenum mode ) +{ + TNLcontext *tnl = TNL_CONTEXT(ctx); + + (void) list; (void) mode; + + if (!tnl->save.prim_store) + tnl->save.prim_store = alloc_prim_store( ctx ); + + if (!tnl->save.vertex_store) { + tnl->save.vertex_store = alloc_vertex_store( ctx ); + tnl->save.vbptr = tnl->save.vertex_store->buffer; + } + + _save_reset_vertex( ctx ); + ctx->Driver.SaveNeedFlush = 0; +} + +void _tnl_EndList( GLcontext *ctx ) +{ + (void) ctx; + assert(TNL_CONTEXT(ctx)->save.vertex_size == 0); +} + +void _tnl_BeginCallList( GLcontext *ctx, struct mesa_display_list *dlist ) +{ + TNLcontext *tnl = TNL_CONTEXT(ctx); + tnl->save.replay_flags |= dlist->flags; + tnl->save.replay_flags |= tnl->LoopbackDListCassettes; +} + +void _tnl_EndCallList( GLcontext *ctx ) +{ + TNLcontext *tnl = TNL_CONTEXT(ctx); + + if (ctx->ListState.CallDepth == 1) + tnl->save.replay_flags = 0; +} + + +static void _tnl_destroy_vertex_list( GLcontext *ctx, void *data ) +{ + struct tnl_vertex_list *node = (struct tnl_vertex_list *)data; + (void) ctx; + + if ( --node->vertex_store->refcount == 0 ) + FREE( node->vertex_store ); + + if ( --node->prim_store->refcount == 0 ) + FREE( node->prim_store ); + + if ( node->normal_lengths ) + FREE( node->normal_lengths ); +} + + +static void _tnl_print_vertex_list( GLcontext *ctx, void *data ) +{ + struct tnl_vertex_list *node = (struct tnl_vertex_list *)data; + GLuint i; + (void) ctx; + + _mesa_debug(NULL, "TNL-VERTEX-LIST, %u vertices %d primitives, %d vertsize\n", + node->count, + node->prim_count, + node->vertex_size); + + for (i = 0 ; i < node->prim_count ; i++) { + struct tnl_prim *prim = &node->prim[i]; + _mesa_debug(NULL, " prim %d: %s %d..%d %s %s\n", + i, + _mesa_lookup_enum_by_nr(prim->mode & PRIM_MODE_MASK), + prim->start, + prim->start + prim->count, + (prim->mode & PRIM_BEGIN) ? "BEGIN" : "(wrap)", + (prim->mode & PRIM_END) ? "END" : "(wrap)"); + } +} + + +static void _save_current_init( GLcontext *ctx ) +{ + TNLcontext *tnl = TNL_CONTEXT(ctx); + GLint i; + + for (i = 0; i < _TNL_ATTRIB_MAT_FRONT_AMBIENT; i++) { + ASSERT(i < VERT_ATTRIB_MAX); + tnl->save.currentsz[i] = &ctx->ListState.ActiveAttribSize[i]; + tnl->save.current[i] = ctx->ListState.CurrentAttrib[i]; + } + + for (i = _TNL_FIRST_MAT; i <= _TNL_LAST_MAT; i++) { + const GLuint j = i - _TNL_FIRST_MAT; + ASSERT(j < MAT_ATTRIB_MAX); + tnl->save.currentsz[i] = &ctx->ListState.ActiveMaterialSize[j]; + tnl->save.current[i] = ctx->ListState.CurrentMaterial[j]; + } + + tnl->save.currentsz[_TNL_ATTRIB_EDGEFLAG] = &ctx->ListState.ActiveEdgeFlag; + tnl->save.current[_TNL_ATTRIB_EDGEFLAG] = &tnl->save.CurrentFloatEdgeFlag; +} + +/** + * Initialize the display list compiler + */ +void _tnl_save_init( GLcontext *ctx ) +{ + TNLcontext *tnl = TNL_CONTEXT(ctx); + struct tnl_vertex_arrays *tmp = &tnl->save_inputs; + GLuint i; + + + for (i = 0; i < _TNL_ATTRIB_MAX; i++) + _mesa_vector4f_init( &tmp->Attribs[i], 0, NULL); + + tnl->save.opcode_vertex_list = + _mesa_alloc_opcode( ctx, + sizeof(struct tnl_vertex_list), + _tnl_playback_vertex_list, + _tnl_destroy_vertex_list, + _tnl_print_vertex_list ); + + ctx->Driver.NotifySaveBegin = _save_NotifyBegin; + + _save_vtxfmt_init( ctx ); + _save_current_init( ctx ); + + /* Hook our array functions into the outside-begin-end vtxfmt in + * ctx->ListState. + */ + ctx->ListState.ListVtxfmt.Rectf = _save_OBE_Rectf; + ctx->ListState.ListVtxfmt.DrawArrays = _save_OBE_DrawArrays; + ctx->ListState.ListVtxfmt.DrawElements = _save_OBE_DrawElements; + ctx->ListState.ListVtxfmt.DrawRangeElements = _save_OBE_DrawRangeElements; + _mesa_install_save_vtxfmt( ctx, &ctx->ListState.ListVtxfmt ); +} + + +/** + * Deallocate the immediate-mode buffer for the given context, if + * its reference count goes to zero. + */ +void _tnl_save_destroy( GLcontext *ctx ) +{ + TNLcontext *tnl = TNL_CONTEXT(ctx); + + /* Decrement the refcounts. References may still be held by + * display lists yet to be destroyed, so it may not yet be time to + * free these items. + */ + if (tnl->save.prim_store && + --tnl->save.prim_store->refcount == 0 ) + FREE( tnl->save.prim_store ); + + if (tnl->save.vertex_store && + --tnl->save.vertex_store->refcount == 0 ) + FREE( tnl->save.vertex_store ); +} diff --git a/src/mesa/tnl/t_vb_arbprogram.c b/src/mesa/tnl/t_vb_arbprogram.c index 4c8f967fdf..425a866994 100644 --- a/src/mesa/tnl/t_vb_arbprogram.c +++ b/src/mesa/tnl/t_vb_arbprogram.c @@ -1,8 +1,8 @@ /* * Mesa 3-D graphics library - * Version: 6.5.1 + * 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"), @@ -37,12 +37,15 @@ #include "arbprogparse.h" #include "light.h" #include "program.h" +#include "prog_instruction.h" +#include "prog_parameter.h" +#include "prog_statevars.h" +#include "programopt.h" #include "math/m_matrix.h" #include "t_context.h" #include "t_pipeline.h" #include "t_vb_arbprogram.h" #include "tnl.h" -#include "program_instruction.h" #define DISASSEM 0 @@ -292,7 +295,7 @@ static void do_EX2( struct arb_vp_machine *m, union instruction op ) GLfloat *result = m->File[0][op.alu.dst]; const GLfloat *arg0 = m->File[op.alu.file0][op.alu.idx0]; - result[0] = (GLfloat)ApproxExp2(arg0[0]); + result[0] = ApproxExp2(arg0[0]); PUFF(result); } @@ -335,6 +338,17 @@ static void do_FRC( struct arb_vp_machine *m, union instruction op ) result[3] = arg0[3] - FLOORF(arg0[3]); } +static void do_INT( struct arb_vp_machine *m, union instruction op ) +{ + GLfloat *result = m->File[0][op.alu.dst]; + const GLfloat *arg0 = m->File[op.alu.file0][op.alu.idx0]; + + result[0] = (GLfloat) (GLint) arg0[0]; + result[1] = (GLfloat) (GLint) arg0[1]; + result[2] = (GLfloat) (GLint) arg0[2]; + result[3] = (GLfloat) (GLint) arg0[3]; +} + /* High precision log base 2: */ static void do_LG2( struct arb_vp_machine *m, union instruction op ) @@ -566,7 +580,7 @@ static void print_reg( GLuint file, GLuint reg ) _mesa_printf("TMP%d", reg - REG_TMP0); else if (reg >= REG_IN0 && reg <= REG_IN31) _mesa_printf("IN%d", reg - REG_IN0); - else if (reg >= REG_OUT0 && reg <= REG_OUT14) + else if (reg >= REG_OUT0 && reg <= REG_OUT23) _mesa_printf("OUT%d", reg - REG_OUT0); else if (reg == REG_ADDR) _mesa_printf("ADDR"); @@ -662,6 +676,7 @@ _tnl_disassem_vba_insn( union instruction op ) case OPCODE_EXP: case OPCODE_FLR: case OPCODE_FRC: + case OPCODE_INT: case OPCODE_LG2: case OPCODE_LIT: case OPCODE_LOG: @@ -711,18 +726,28 @@ _tnl_disassem_vba_insn( union instruction op ) } } +typedef void (*gpu_function)(struct arb_vp_machine *m, union instruction op); -static void (* const opcode_func[MAX_OPCODE+3])(struct arb_vp_machine *, union instruction) = +static gpu_function opcode_func[MAX_OPCODE+3] = { + do_NOP, do_ABS, do_ADD, do_NOP,/*ARA*/ do_NOP,/*ARL*/ do_NOP,/*ARL_NV*/ do_NOP,/*ARR*/ + do_NOP,/*BGNLOOP*/ + do_NOP,/*BGNSUB*/ do_NOP,/*BRA*/ + do_NOP,/*BRK*/ + do_NOP,/*BRK0*/ + do_NOP,/*BRK1*/ do_NOP,/*CAL*/ do_NOP,/*CMP*/ + do_NOP,/*CONT*/ + do_NOP,/*CONT0*/ + do_NOP,/*CONT1*/ do_NOP,/*COS*/ do_NOP,/*DDX*/ do_NOP,/*DDY*/ @@ -730,11 +755,17 @@ static void (* const opcode_func[MAX_OPCODE+3])(struct arb_vp_machine *, union i do_DP4, do_DPH, do_DST, - do_NOP, + do_NOP,/*ELSE*/ + do_NOP,/*END*/ + do_NOP,/*ENDIF*/ + do_NOP,/*ENDLOOP*/ + do_NOP,/*ENDSUB*/ do_EX2, do_EXP, do_FLR, do_FRC, + do_NOP,/*IF*/ + do_INT, do_NOP,/*KIL*/ do_NOP,/*KIL_NV*/ do_LG2, @@ -746,6 +777,10 @@ static void (* const opcode_func[MAX_OPCODE+3])(struct arb_vp_machine *, union i do_MIN, do_MOV, do_MUL, + do_NOP,/*NOISE1*/ + do_NOP,/*NOISE2*/ + do_NOP,/*NOISE3*/ + do_NOP,/*NOISE4*/ do_NOP,/*PK2H*/ do_NOP,/*PK2US*/ do_NOP,/*PK4B*/ @@ -828,6 +863,7 @@ static struct reg cvp_load_reg( struct compilation *cp, switch (file) { case PROGRAM_TEMPORARY: + assert(REG_TMP0 + index <= REG_TMP11); return cvp_make_reg(FILE_REG, REG_TMP0 + index); case PROGRAM_INPUT: @@ -853,6 +889,8 @@ static struct reg cvp_load_reg( struct compilation *cp, return reg; case PROGRAM_STATE_VAR: + case PROGRAM_CONSTANT: + case PROGRAM_UNIFORM: reg = cvp_make_reg(FILE_STATE_PARAM, index); if (rel) return cvp_emit_rel(cp, reg, tmpreg); @@ -864,7 +902,7 @@ static struct reg cvp_load_reg( struct compilation *cp, case PROGRAM_WRITE_ONLY: case PROGRAM_ADDRESS: default: - _mesa_problem(NULL, "Invalid register file %d in cvp_load_reg()"); + _mesa_problem(NULL, "Invalid register file %d in cvp_load_reg()", file); assert(0); return tmpreg; /* can't happen */ } @@ -925,7 +963,10 @@ static GLuint cvp_choose_result( struct compilation *cp, idx = REG_OUT0 + dst->Index; break; default: +#if 0 + /* IF/ELSE/ENDIF instructions will hit this */ assert(0); +#endif return REG_RES; /* can't happen */ } @@ -1020,6 +1061,13 @@ static void cvp_emit_inst( struct compilation *cp, } break; + case OPCODE_NOP: + break; + + case OPCODE_BRA: + /* XXX implement */ + break; + default: result = cvp_choose_result( cp, &inst->DstReg, &fixup ); nr_args = _mesa_num_inst_src_regs(inst->Opcode); @@ -1058,6 +1106,16 @@ static void compile_vertex_program( struct gl_vertex_program *program, struct tnl_compiled_program *p = CALLOC_STRUCT(tnl_compiled_program); GLint i; +#if 1 + if (!program->IsNVProgram && program->IsPositionInvariant) { + printf("Adding MVP code\n"); + if (!program->Base.Parameters) + program->Base.Parameters = _mesa_new_parameter_list(); + _mesa_insert_mvp_code(NULL, program); + program->IsPositionInvariant = 0; + } +#endif + if (program->TnlData) free_tnl_data( program ); @@ -1097,7 +1155,6 @@ static void compile_vertex_program( struct gl_vertex_program *program, - /* ---------------------------------------------------------------------- * Execution */ @@ -1182,6 +1239,7 @@ do_ndc_cliptest(GLcontext *ctx, struct arb_vp_machine *m) /* Test userclip planes. This contributes to VB->ClipMask. */ + /** XXX NEW_SLANG _Enabled ??? */ if (ctx->Transform.ClipPlanesEnabled && (!ctx->VertexProgram._Enabled || ctx->VertexProgram.Current->IsPositionInvariant)) { userclip( ctx, @@ -1209,6 +1267,7 @@ static INLINE void call_func( struct tnl_compiled_program *p, p->compiled_func(m); } + /** * Execute the given vertex program. * @@ -1221,22 +1280,20 @@ static INLINE void call_func( struct tnl_compiled_program *p, static GLboolean run_arb_vertex_program(GLcontext *ctx, struct tnl_pipeline_stage *stage) { - const struct gl_vertex_program *program; + const struct gl_vertex_program *program = ctx->VertexProgram._Current; struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb; struct arb_vp_machine *m = ARB_VP_MACHINE(stage); struct tnl_compiled_program *p; GLuint i, j; GLbitfield outputs; - if (ctx->ShaderObjects._VertexShaderPresent) - return GL_TRUE; - - program = ctx->VertexProgram._Enabled ? ctx->VertexProgram.Current : NULL; - if (!program && ctx->_MaintainTnlProgram) { - program = ctx->_TnlProgram; - } - if (!program || program->IsNVProgram) +#define FORCE_PROG_EXECUTE_C 1 +#if FORCE_PROG_EXECUTE_C + return GL_TRUE; +#else + if (!program) return GL_TRUE; +#endif if (program->Base.Parameters) { _mesa_load_state_parameters(ctx, program->Base.Parameters); @@ -1279,7 +1336,13 @@ run_arb_vertex_program(GLcontext *ctx, struct tnl_pipeline_stage *stage) case 2: m->File[0][idx][1] = m->input[j].data[1]; case 1: m->File[0][idx][0] = m->input[j].data[0]; } - +#if 0 + printf(" attr %d/%d: %g %g %g %g\n", j, idx-REG_IN0, + m->input[j].data[0], + m->input[j].data[1], + m->input[j].data[2], + m->input[j].data[3]); +#endif STRIDE_F(m->input[j].data, m->input[j].stride); } @@ -1288,9 +1351,9 @@ run_arb_vertex_program(GLcontext *ctx, struct tnl_pipeline_stage *stage) call_func( p, m ); } else { - GLint j; - for (j = 0; j < p->nr_instructions; j++) { - union instruction inst = p->instructions[j]; + GLint pc; + for (pc = 0; pc < p->nr_instructions; pc++) { + union instruction inst = p->instructions[pc]; opcode_func[inst.alu.opcode]( m, inst ); } } @@ -1384,6 +1447,14 @@ run_arb_vertex_program(GLcontext *ctx, struct tnl_pipeline_stage *stage) } } + for (i = 0; i < ctx->Const.MaxVarying; i++) { + if (outputs & (1 << (VERT_RESULT_VAR0 + i))) { + /* Note: varying results get put into the generic attributes */ + VB->AttribPtr[VERT_ATTRIB_GENERIC0+i] + = &m->attribs[VERT_RESULT_VAR0 + i]; + } + } + #if 0 for (i = 0; i < VB->Count; i++) { printf("Out %d: %f %f %f %f %f %f %f %f\n", i, @@ -1408,17 +1479,13 @@ static void validate_vertex_program( GLcontext *ctx, struct tnl_pipeline_stage *stage ) { struct arb_vp_machine *m = ARB_VP_MACHINE(stage); - struct gl_vertex_program *program; - - if (ctx->ShaderObjects._VertexShaderPresent) - return; - - program = (ctx->VertexProgram._Enabled ? ctx->VertexProgram.Current : 0); - if (!program && ctx->_MaintainTnlProgram) { - program = ctx->_TnlProgram; - } + struct gl_vertex_program *program = ctx->VertexProgram._Current; +#if FORCE_OLD + if (0 &&program) { +#else if (program) { +#endif if (!program->TnlData) compile_vertex_program( program, m->try_codegen ); @@ -1435,11 +1502,6 @@ validate_vertex_program( GLcontext *ctx, struct tnl_pipeline_stage *stage ) } - - - - - /** * Called the first time stage->run is called. In effect, don't * allocate data until the first time the stage is run. @@ -1453,6 +1515,10 @@ static GLboolean init_vertex_program( GLcontext *ctx, const GLuint size = VB->Size; GLuint i; + /* spot checks to be sure the opcode table is correct */ + assert(opcode_func[OPCODE_SGE] == do_SGE); + assert(opcode_func[OPCODE_XPD] == do_XPD); + stage->privatePtr = _mesa_calloc(sizeof(*m)); m = ARB_VP_MACHINE(stage); if (!m) @@ -1486,7 +1552,7 @@ static GLboolean init_vertex_program( GLcontext *ctx, _mesa_vector4f_alloc( &m->ndcCoords, 0, size, 32 ); m->clipmask = (GLubyte *) ALIGN_MALLOC(sizeof(GLubyte)*size, 32 ); - if (ctx->_MaintainTnlProgram) + if (ctx->VertexProgram._MaintainTnlProgram) _mesa_allow_light_in_model( ctx, GL_FALSE ); m->fpucntl_rnd_neg = RND_NEG_FPU; /* const value */ @@ -1496,8 +1562,6 @@ static GLboolean init_vertex_program( GLcontext *ctx, } - - /** * Destructor for this pipeline stage. */ @@ -1522,6 +1586,7 @@ static void dtr( struct tnl_pipeline_stage *stage ) } } + /** * Public description of this pipeline stage. */ @@ -1543,7 +1608,7 @@ const struct tnl_pipeline_stage _tnl_arb_vertex_program_stage = void _tnl_program_string(GLcontext *ctx, GLenum target, struct gl_program *program) { - if (target == GL_VERTEX_PROGRAM_ARB) { + if (program->Target == GL_VERTEX_PROGRAM_ARB) { /* free any existing tnl data hanging off the program */ struct gl_vertex_program *vprog = (struct gl_vertex_program *) program; if (vprog->TnlData) { diff --git a/src/mesa/tnl/t_vb_arbprogram.h b/src/mesa/tnl/t_vb_arbprogram.h index 6de8dca328..1bec2a411e 100644 --- a/src/mesa/tnl/t_vb_arbprogram.h +++ b/src/mesa/tnl/t_vb_arbprogram.h @@ -56,6 +56,22 @@ #define REG_TMP0 5 #define REG_TMP11 16 #define REG_OUT0 17 +#define REG_OUT23 40 +#define REG_IN0 41 +#define REG_IN31 72 +#define REG_ID 73 /* 0,0,0,1 */ +#define REG_ONES 74 /* 1,1,1,1 */ +#define REG_SWZ 75 /* 1,-1,0,0 */ +#define REG_NEG 76 /* -1,-1,-1,-1 */ +#define REG_LIT 77 /* 1,0,0,1 */ +#define REG_LIT2 78 /* 1,0,0,1 */ +#define REG_SCRATCH 79 /* internal temporary. XXX we can't actually use this because 70 doesn't fit in the 5-bit 'dst' instruction field! */ +#define REG_UNDEF 127 /* special case - never used */ +#define REG_MAX 128 +#define REG_INVALID ~0 + + +#if 0 #define REG_OUT14 31 #define REG_IN0 32 #define REG_IN31 63 @@ -69,6 +85,7 @@ #define REG_UNDEF 127 /* special case - never used */ #define REG_MAX 128 #define REG_INVALID ~0 +#endif /* ARB_vp instructions are broken down into one or more of the * following micro-instructions, each representable in a 64 bit packed @@ -76,16 +93,16 @@ */ struct reg { GLuint file:2; - GLuint idx:7; + GLuint idx:8; }; union instruction { struct { GLuint opcode:7; - GLuint dst:5; + GLuint dst:6; GLuint file0:2; - GLuint idx0:7; + GLuint idx0:8; GLuint file1:2; GLuint idx1:7; GLuint pad:2; @@ -94,18 +111,18 @@ union instruction { struct { GLuint opcode:7; - GLuint dst:5; + GLuint dst:6; GLuint file0:2; - GLuint idx0:7; + GLuint idx0:8; GLuint neg:4; GLuint swz:12; /* xyzw01 */ } rsw; struct { GLuint opcode:7; - GLuint dst:5; + GLuint dst:6; GLuint file:2; - GLuint idx:7; + GLuint idx:8; GLuint mask:4; GLuint pad:7; GLuint pad2; diff --git a/src/mesa/tnl/t_vb_arbprogram_sse.c b/src/mesa/tnl/t_vb_arbprogram_sse.c index b9126d6d88..d0f66fd619 100644 --- a/src/mesa/tnl/t_vb_arbprogram_sse.c +++ b/src/mesa/tnl/t_vb_arbprogram_sse.c @@ -43,7 +43,7 @@ #include "mtypes.h" #include "arbprogparse.h" #include "program.h" -#include "program_instruction.h" +#include "prog_instruction.h" #include "math/m_matrix.h" #include "math/m_translate.h" #include "t_context.h" diff --git a/src/mesa/tnl/t_vb_arbshader.c b/src/mesa/tnl/t_vb_arbshader.c deleted file mode 100644 index 13aa3ea910..0000000000 --- a/src/mesa/tnl/t_vb_arbshader.c +++ /dev/null @@ -1,301 +0,0 @@ -/* - * Mesa 3-D graphics library - * Version: 6.5 - * - * Copyright (C) 2006 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. - * - * Authors: - * Michal Krol - */ - -#include "glheader.h" -#include "imports.h" -#include "macros.h" -#include "shaderobjects.h" -#include "shaderobjects_3dlabs.h" -#include "t_pipeline.h" -#include "slang_utility.h" -#include "slang_link.h" - -#if FEATURE_ARB_vertex_shader - -typedef struct -{ - GLvector4f outputs[VERT_RESULT_MAX]; - GLvector4f varyings[MAX_VARYING_VECTORS]; - GLvector4f ndc_coords; - GLubyte *clipmask; - GLubyte ormask; - GLubyte andmask; -} arbvs_stage_data; - -#define ARBVS_STAGE_DATA(stage) ((arbvs_stage_data *) stage->privatePtr) - -static GLboolean construct_arb_vertex_shader (GLcontext *ctx, struct tnl_pipeline_stage *stage) -{ - TNLcontext *tnl = TNL_CONTEXT(ctx); - struct vertex_buffer *vb = &tnl->vb; - arbvs_stage_data *store; - GLuint size = vb->Size; - GLuint i; - - stage->privatePtr = _mesa_malloc (sizeof (arbvs_stage_data)); - store = ARBVS_STAGE_DATA(stage); - if (store == NULL) - return GL_FALSE; - - for (i = 0; i < VERT_RESULT_MAX; i++) - { - _mesa_vector4f_alloc (&store->outputs[i], 0, size, 32); - store->outputs[i].size = 4; - } - for (i = 0; i < MAX_VARYING_VECTORS; i++) - { - _mesa_vector4f_alloc (&store->varyings[i], 0, size, 32); - store->varyings[i].size = 4; - } - _mesa_vector4f_alloc (&store->ndc_coords, 0, size, 32); - store->clipmask = (GLubyte *) ALIGN_MALLOC (size, 32); - - return GL_TRUE; -} - -static void destruct_arb_vertex_shader (struct tnl_pipeline_stage *stage) -{ - arbvs_stage_data *store = ARBVS_STAGE_DATA(stage); - - if (store != NULL) - { - GLuint i; - - for (i = 0; i < VERT_RESULT_MAX; i++) - _mesa_vector4f_free (&store->outputs[i]); - for (i = 0; i < MAX_VARYING_VECTORS; i++) - _mesa_vector4f_free (&store->varyings[i]); - _mesa_vector4f_free (&store->ndc_coords); - ALIGN_FREE (store->clipmask); - - _mesa_free (store); - stage->privatePtr = NULL; - } -} - -static void validate_arb_vertex_shader (GLcontext *ctx, struct tnl_pipeline_stage *stage) -{ -} - -static GLvoid fetch_input_float (struct gl2_program_intf **pro, GLuint index, GLuint attr, GLuint i, - struct vertex_buffer *vb) -{ - const GLubyte *ptr = (const GLubyte *) vb->AttribPtr[attr]->data; - const GLuint stride = vb->AttribPtr[attr]->stride; - GLfloat *data = (GLfloat *) (ptr + stride * i); - - (**pro).UpdateFixedAttrib (pro, index, data, 0, sizeof (GLfloat), GL_TRUE); -} - -static GLvoid fetch_input_vec3 (struct gl2_program_intf **pro, GLuint index, GLuint attr, GLuint i, - struct vertex_buffer *vb) -{ - const GLubyte *ptr = (const GLubyte *) vb->AttribPtr[attr]->data; - const GLuint stride = vb->AttribPtr[attr]->stride; - GLfloat *data = (GLfloat *) (ptr + stride * i); - - (**pro).UpdateFixedAttrib (pro, index, data, 0, 3 * sizeof (GLfloat), GL_TRUE); -} - -static void fetch_input_vec4 (struct gl2_program_intf **pro, GLuint index, GLuint attr, GLuint i, - struct vertex_buffer *vb) -{ - const GLubyte *ptr = (const GLubyte *) vb->AttribPtr[attr]->data; - const GLuint size = vb->AttribPtr[attr]->size; - const GLuint stride = vb->AttribPtr[attr]->stride; - const GLfloat *data = (const GLfloat *) (ptr + stride * i); - GLfloat vec[4]; - - switch (size) - { - case 2: - vec[0] = data[0]; - vec[1] = data[1]; - vec[2] = 0.0f; - vec[3] = 1.0f; - break; - case 3: - vec[0] = data[0]; - vec[1] = data[1]; - vec[2] = data[2]; - vec[3] = 1.0f; - break; - case 4: - vec[0] = data[0]; - vec[1] = data[1]; - vec[2] = data[2]; - vec[3] = data[3]; - break; - } - (**pro).UpdateFixedAttrib (pro, index, vec, 0, 4 * sizeof (GLfloat), GL_TRUE); -} - -static GLvoid -fetch_gen_attrib (struct gl2_program_intf **pro, GLuint index, GLuint i, struct vertex_buffer *vb) -{ - const GLuint attr = _TNL_ATTRIB_GENERIC0 + index; - const GLubyte *ptr = (const GLubyte *) (vb->AttribPtr[attr]->data); - const GLuint stride = vb->AttribPtr[attr]->stride; - const GLfloat *data = (const GLfloat *) (ptr + stride * i); - - (**pro).WriteAttrib (pro, index, data); -} - -static GLvoid fetch_output_float (struct gl2_program_intf **pro, GLuint index, GLuint attr, GLuint i, - arbvs_stage_data *store) -{ - (**pro).UpdateFixedAttrib (pro, index, &store->outputs[attr].data[i], 0, sizeof (GLfloat), - GL_FALSE); -} - -static void fetch_output_vec4 (struct gl2_program_intf **pro, GLuint index, GLuint attr, GLuint i, - GLuint offset, arbvs_stage_data *store) -{ - (**pro).UpdateFixedAttrib (pro, index, &store->outputs[attr].data[i], offset, - 4 * sizeof (GLfloat), GL_FALSE); -} - -static GLboolean run_arb_vertex_shader (GLcontext *ctx, struct tnl_pipeline_stage *stage) -{ - TNLcontext *tnl = TNL_CONTEXT(ctx); - struct vertex_buffer *vb = &tnl->vb; - arbvs_stage_data *store = ARBVS_STAGE_DATA(stage); - struct gl2_program_intf **pro; - GLsizei i, j; - - if (!ctx->ShaderObjects._VertexShaderPresent) - return GL_TRUE; - - pro = ctx->ShaderObjects.CurrentProgram; - (**pro).UpdateFixedUniforms (pro); - - for (i = 0; i < vb->Count; i++) - { - fetch_input_vec4 (pro, SLANG_VERTEX_FIXED_VERTEX, _TNL_ATTRIB_POS, i, vb); - fetch_input_vec3 (pro, SLANG_VERTEX_FIXED_NORMAL, _TNL_ATTRIB_NORMAL, i, vb); - fetch_input_vec4 (pro, SLANG_VERTEX_FIXED_COLOR, _TNL_ATTRIB_COLOR0, i, vb); - fetch_input_vec4 (pro, SLANG_VERTEX_FIXED_SECONDARYCOLOR, _TNL_ATTRIB_COLOR1, i, vb); - fetch_input_float (pro, SLANG_VERTEX_FIXED_FOGCOORD, _TNL_ATTRIB_FOG, i, vb); - fetch_input_vec4 (pro, SLANG_VERTEX_FIXED_MULTITEXCOORD0, _TNL_ATTRIB_TEX0, i, vb); - fetch_input_vec4 (pro, SLANG_VERTEX_FIXED_MULTITEXCOORD1, _TNL_ATTRIB_TEX1, i, vb); - fetch_input_vec4 (pro, SLANG_VERTEX_FIXED_MULTITEXCOORD2, _TNL_ATTRIB_TEX2, i, vb); - fetch_input_vec4 (pro, SLANG_VERTEX_FIXED_MULTITEXCOORD3, _TNL_ATTRIB_TEX3, i, vb); - fetch_input_vec4 (pro, SLANG_VERTEX_FIXED_MULTITEXCOORD4, _TNL_ATTRIB_TEX4, i, vb); - fetch_input_vec4 (pro, SLANG_VERTEX_FIXED_MULTITEXCOORD5, _TNL_ATTRIB_TEX5, i, vb); - fetch_input_vec4 (pro, SLANG_VERTEX_FIXED_MULTITEXCOORD6, _TNL_ATTRIB_TEX6, i, vb); - fetch_input_vec4 (pro, SLANG_VERTEX_FIXED_MULTITEXCOORD7, _TNL_ATTRIB_TEX7, i, vb); - for (j = 0; j < MAX_VERTEX_ATTRIBS; j++) - fetch_gen_attrib (pro, j, i, vb); - - _slang_exec_vertex_shader (pro); - - fetch_output_vec4 (pro, SLANG_VERTEX_FIXED_POSITION, VERT_RESULT_HPOS, i, 0, store); - fetch_output_vec4 (pro, SLANG_VERTEX_FIXED_FRONTCOLOR, VERT_RESULT_COL0, i, 0, store); - fetch_output_vec4 (pro, SLANG_VERTEX_FIXED_FRONTSECONDARYCOLOR, VERT_RESULT_COL1, i, 0, store); - fetch_output_float (pro, SLANG_VERTEX_FIXED_FOGFRAGCOORD, VERT_RESULT_FOGC, i, store); - for (j = 0; j < 8; j++) - fetch_output_vec4 (pro, SLANG_VERTEX_FIXED_TEXCOORD, VERT_RESULT_TEX0 + j, i, j, store); - fetch_output_float (pro, SLANG_VERTEX_FIXED_POINTSIZE, VERT_RESULT_PSIZ, i, store); - fetch_output_vec4 (pro, SLANG_VERTEX_FIXED_BACKCOLOR, VERT_RESULT_BFC0, i, 0, store); - fetch_output_vec4 (pro, SLANG_VERTEX_FIXED_BACKSECONDARYCOLOR, VERT_RESULT_BFC1, i, 0, store); - /* XXX: fetch output SLANG_VERTEX_FIXED_CLIPVERTEX */ - - for (j = 0; j < MAX_VARYING_VECTORS; j++) - { - GLuint k; - - for (k = 0; k < VARYINGS_PER_VECTOR; k++) - { - (**pro).UpdateVarying (pro, j * VARYINGS_PER_VECTOR + k, - &store->varyings[j].data[i][k], GL_TRUE); - } - } - } - - vb->ClipPtr = &store->outputs[VERT_RESULT_HPOS]; - vb->ClipPtr->count = vb->Count; - - vb->ColorPtr[0] = &store->outputs[VERT_RESULT_COL0]; - vb->AttribPtr[VERT_ATTRIB_COLOR0] = vb->ColorPtr[0]; - vb->ColorPtr[1] = &store->outputs[VERT_RESULT_BFC0]; - - vb->SecondaryColorPtr[0] = - vb->AttribPtr[VERT_ATTRIB_COLOR1] = &store->outputs[VERT_RESULT_COL1]; - - vb->SecondaryColorPtr[1] = &store->outputs[VERT_RESULT_BFC1]; - - for (i = 0; i < ctx->Const.MaxTextureCoordUnits; i++) { - vb->TexCoordPtr[i] = - vb->AttribPtr[VERT_ATTRIB_TEX0 + i] = &store->outputs[VERT_RESULT_TEX0 + i]; - } - - vb->FogCoordPtr = - vb->AttribPtr[VERT_ATTRIB_FOG] = &store->outputs[VERT_RESULT_FOGC]; - - vb->AttribPtr[_TNL_ATTRIB_POINTSIZE] = &store->outputs[VERT_RESULT_PSIZ]; - - for (i = 0; i < MAX_VARYING_VECTORS; i++) { - vb->VaryingPtr[i] = &store->varyings[i]; - vb->AttribPtr[_TNL_ATTRIB_GENERIC0 + i] = vb->VaryingPtr[i]; - } - - store->ormask = 0; - store->andmask = CLIP_FRUSTUM_BITS; - - if (tnl->NeedNdcCoords) - { - vb->NdcPtr = _mesa_clip_tab[vb->ClipPtr->size] (vb->ClipPtr, &store->ndc_coords, - store->clipmask, &store->ormask, &store->andmask); - } - else - { - vb->NdcPtr = NULL; - _mesa_clip_np_tab[vb->ClipPtr->size] (vb->ClipPtr, NULL, store->clipmask, &store->ormask, - &store->andmask); - } - - if (store->andmask) - return GL_FALSE; - - vb->ClipAndMask = store->andmask; - vb->ClipOrMask = store->ormask; - vb->ClipMask = store->clipmask; - - return GL_TRUE; -} - -const struct tnl_pipeline_stage _tnl_arb_vertex_shader_stage = { - "ARB_vertex_shader", - NULL, - construct_arb_vertex_shader, - destruct_arb_vertex_shader, - validate_arb_vertex_shader, - run_arb_vertex_shader -}; - -#endif /* FEATURE_ARB_vertex_shader */ - diff --git a/src/mesa/tnl/t_vb_cull.c b/src/mesa/tnl/t_vb_cull.c index 8848dac10c..21a32e5b1d 100644 --- a/src/mesa/tnl/t_vb_cull.c +++ b/src/mesa/tnl/t_vb_cull.c @@ -57,10 +57,7 @@ static GLboolean run_cull_stage( GLcontext *ctx, GLuint count = VB->Count; GLuint i; - if (ctx->ShaderObjects._VertexShaderPresent) - return GL_TRUE; - - if (ctx->VertexProgram._Enabled || + if (ctx->VertexProgram._Current || !ctx->Transform.CullVertexFlag) return GL_TRUE; diff --git a/src/mesa/tnl/t_vb_fog.c b/src/mesa/tnl/t_vb_fog.c index 51f28c4059..5440ff7894 100644 --- a/src/mesa/tnl/t_vb_fog.c +++ b/src/mesa/tnl/t_vb_fog.c @@ -148,10 +148,7 @@ run_fog_stage(GLcontext *ctx, struct tnl_pipeline_stage *stage) struct fog_stage_data *store = FOG_STAGE_DATA(stage); GLvector4f *input; - if (ctx->ShaderObjects._VertexShaderPresent) - return GL_TRUE; - - if (!ctx->Fog.Enabled || ctx->VertexProgram._Enabled) + if (!ctx->Fog.Enabled || ctx->VertexProgram._Current) return GL_TRUE; diff --git a/src/mesa/tnl/t_vb_light.c b/src/mesa/tnl/t_vb_light.c index 47c5b400aa..12f2cc7735 100644 --- a/src/mesa/tnl/t_vb_light.c +++ b/src/mesa/tnl/t_vb_light.c @@ -203,10 +203,7 @@ static GLboolean run_lighting( GLcontext *ctx, GLvector4f *input = ctx->_NeedEyeCoords ? VB->EyePtr : VB->ObjPtr; GLuint idx; - if (ctx->ShaderObjects._VertexShaderPresent) - return GL_TRUE; - - if (!ctx->Light.Enabled || ctx->VertexProgram._Enabled) + if (!ctx->Light.Enabled || ctx->VertexProgram._Current) return GL_TRUE; /* Make sure we can talk about position x,y and z: @@ -264,10 +261,7 @@ static void validate_lighting( GLcontext *ctx, { light_func *tab; - if (ctx->ShaderObjects._VertexShaderPresent) - return; - - if (!ctx->Light.Enabled || ctx->VertexProgram._Enabled) + if (!ctx->Light.Enabled || ctx->VertexProgram._Current) return; if (ctx->Visual.rgbMode) { diff --git a/src/mesa/tnl/t_vb_normals.c b/src/mesa/tnl/t_vb_normals.c index 0f91784e80..01fad0cee2 100644 --- a/src/mesa/tnl/t_vb_normals.c +++ b/src/mesa/tnl/t_vb_normals.c @@ -95,12 +95,7 @@ validate_normal_stage(GLcontext *ctx, struct tnl_pipeline_stage *stage) { struct normal_stage_data *store = NORMAL_STAGE_DATA(stage); - if (ctx->ShaderObjects._VertexShaderPresent) { - store->NormalTransform = NULL; - return; - } - - if (ctx->VertexProgram._Enabled || + if (ctx->VertexProgram._Current || (!ctx->Light.Enabled && !(ctx->Texture._GenFlags & TEXGEN_NEED_NORMALS))) { store->NormalTransform = NULL; diff --git a/src/mesa/tnl/t_vb_points.c b/src/mesa/tnl/t_vb_points.c index 2f502d61d1..9327f8c273 100644 --- a/src/mesa/tnl/t_vb_points.c +++ b/src/mesa/tnl/t_vb_points.c @@ -47,10 +47,7 @@ struct point_stage_data { static GLboolean run_point_stage(GLcontext *ctx, struct tnl_pipeline_stage *stage) { - if (ctx->ShaderObjects._VertexShaderPresent) - return GL_TRUE; - - if (ctx->Point._Attenuated && !ctx->VertexProgram._Enabled) { + if (ctx->Point._Attenuated && !ctx->VertexProgram._Current) { struct point_stage_data *store = POINT_STAGE_DATA(stage); struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb; const GLfloat (*eye)[4] = (const GLfloat (*)[4]) VB->EyePtr->data; diff --git a/src/mesa/tnl/t_vb_program.c b/src/mesa/tnl/t_vb_program.c index f11ac616f1..17eefe7032 100644 --- a/src/mesa/tnl/t_vb_program.c +++ b/src/mesa/tnl/t_vb_program.c @@ -1,8 +1,8 @@ /* * Mesa 3-D graphics library - * Version: 6.5 + * 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"), @@ -31,20 +31,14 @@ #include "glheader.h" -#include "api_noop.h" -#include "colormac.h" #include "context.h" -#include "dlist.h" -#include "hash.h" -#include "light.h" #include "macros.h" #include "imports.h" -#include "simple_list.h" -#include "mtypes.h" -#include "program_instruction.h" -#include "nvvertexec.h" -#include "nvprogram.h" +#include "prog_instruction.h" +#include "prog_statevars.h" +#include "prog_execute.h" +#include "tnl.h" #include "t_context.h" #include "t_pipeline.h" @@ -55,7 +49,7 @@ */ struct vp_stage_data { /** The results of running the vertex program go into these arrays. */ - GLvector4f attribs[15]; + GLvector4f results[VERT_RESULT_MAX]; GLvector4f ndcCoords; /**< normalized device coords */ GLubyte *clipmask; /**< clip flags */ @@ -67,6 +61,131 @@ struct vp_stage_data { /** + * Initialize virtual machine state prior to executing vertex program. + */ +static void +init_machine(GLcontext *ctx, struct gl_program_machine *machine) +{ + /* Input registers get initialized from the current vertex attribs */ + MEMCPY(machine->VertAttribs, ctx->Current.Attrib, + MAX_VERTEX_PROGRAM_ATTRIBS * 4 * sizeof(GLfloat)); + + if (ctx->VertexProgram.Current->IsNVProgram) { + GLuint i; + /* Output/result regs are initialized to [0,0,0,1] */ + for (i = 0; i < MAX_NV_VERTEX_PROGRAM_OUTPUTS; i++) { + ASSIGN_4V(machine->Outputs[i], 0.0F, 0.0F, 0.0F, 1.0F); + } + /* Temp regs are initialized to [0,0,0,0] */ + for (i = 0; i < MAX_NV_VERTEX_PROGRAM_TEMPS; i++) { + ASSIGN_4V(machine->Temporaries[i], 0.0F, 0.0F, 0.0F, 0.0F); + } + for (i = 0; i < MAX_VERTEX_PROGRAM_ADDRESS_REGS; i++) { + ASSIGN_4V(machine->AddressReg[i], 0, 0, 0, 0); + } + } + + /* init condition codes */ + machine->CondCodes[0] = COND_EQ; + machine->CondCodes[1] = COND_EQ; + machine->CondCodes[2] = COND_EQ; + machine->CondCodes[3] = COND_EQ; +} + + +/** + * Copy the 16 elements of a matrix into four consecutive program + * registers starting at 'pos'. + */ +static void +load_matrix(GLfloat registers[][4], GLuint pos, const GLfloat mat[16]) +{ + GLuint i; + for (i = 0; i < 4; i++) { + registers[pos + i][0] = mat[0 + i]; + registers[pos + i][1] = mat[4 + i]; + registers[pos + i][2] = mat[8 + i]; + registers[pos + i][3] = mat[12 + i]; + } +} + + +/** + * As above, but transpose the matrix. + */ +static void +load_transpose_matrix(GLfloat registers[][4], GLuint pos, + const GLfloat mat[16]) +{ + MEMCPY(registers[pos], mat, 16 * sizeof(GLfloat)); +} + + +/** + * Load current vertex program's parameter registers with tracked + * matrices (if NV program). This only needs to be done per + * glBegin/glEnd, not per-vertex. + */ +void +_mesa_load_tracked_matrices(GLcontext *ctx) +{ + GLuint i; + + for (i = 0; i < MAX_NV_VERTEX_PROGRAM_PARAMS / 4; i++) { + /* point 'mat' at source matrix */ + GLmatrix *mat; + if (ctx->VertexProgram.TrackMatrix[i] == GL_MODELVIEW) { + mat = ctx->ModelviewMatrixStack.Top; + } + else if (ctx->VertexProgram.TrackMatrix[i] == GL_PROJECTION) { + mat = ctx->ProjectionMatrixStack.Top; + } + else if (ctx->VertexProgram.TrackMatrix[i] == GL_TEXTURE) { + mat = ctx->TextureMatrixStack[ctx->Texture.CurrentUnit].Top; + } + else if (ctx->VertexProgram.TrackMatrix[i] == GL_COLOR) { + mat = ctx->ColorMatrixStack.Top; + } + else if (ctx->VertexProgram.TrackMatrix[i]==GL_MODELVIEW_PROJECTION_NV) { + /* XXX verify the combined matrix is up to date */ + mat = &ctx->_ModelProjectMatrix; + } + else if (ctx->VertexProgram.TrackMatrix[i] >= GL_MATRIX0_NV && + ctx->VertexProgram.TrackMatrix[i] <= GL_MATRIX7_NV) { + GLuint n = ctx->VertexProgram.TrackMatrix[i] - GL_MATRIX0_NV; + ASSERT(n < MAX_PROGRAM_MATRICES); + mat = ctx->ProgramMatrixStack[n].Top; + } + else { + /* no matrix is tracked, but we leave the register values as-is */ + assert(ctx->VertexProgram.TrackMatrix[i] == GL_NONE); + continue; + } + + /* load the matrix values into sequential registers */ + if (ctx->VertexProgram.TrackMatrixTransform[i] == GL_IDENTITY_NV) { + load_matrix(ctx->VertexProgram.Parameters, i*4, mat->m); + } + else if (ctx->VertexProgram.TrackMatrixTransform[i] == GL_INVERSE_NV) { + _math_matrix_analyse(mat); /* update the inverse */ + ASSERT(!_math_matrix_is_dirty(mat)); + load_matrix(ctx->VertexProgram.Parameters, i*4, mat->inv); + } + else if (ctx->VertexProgram.TrackMatrixTransform[i] == GL_TRANSPOSE_NV) { + load_transpose_matrix(ctx->VertexProgram.Parameters, i*4, mat->m); + } + else { + assert(ctx->VertexProgram.TrackMatrixTransform[i] + == GL_INVERSE_TRANSPOSE_NV); + _math_matrix_analyse(mat); /* update the inverse */ + ASSERT(!_math_matrix_is_dirty(mat)); + load_transpose_matrix(ctx->VertexProgram.Parameters, i*4, mat->inv); + } + } +} + + +/** * This function executes vertex programs */ static GLboolean @@ -75,24 +194,38 @@ run_vp( GLcontext *ctx, struct tnl_pipeline_stage *stage ) TNLcontext *tnl = TNL_CONTEXT(ctx); struct vp_stage_data *store = VP_STAGE_DATA(stage); struct vertex_buffer *VB = &tnl->vb; - struct gl_vertex_program *program = ctx->VertexProgram.Current; - struct vp_machine machine; - GLuint i; - - if (ctx->ShaderObjects._VertexShaderPresent) + struct gl_vertex_program *program = ctx->VertexProgram._Current; + struct gl_program_machine machine; + GLuint outputs[VERT_RESULT_MAX], numOutputs; + GLuint i, j; + +#define FORCE_PROG_EXECUTE_C 1 +#if FORCE_PROG_EXECUTE_C + if (!program) return GL_TRUE; - - if (!ctx->VertexProgram._Enabled || - !program->IsNVProgram) +#else + if (!program || !program->IsNVProgram) return GL_TRUE; +#endif - /* load program parameter registers (they're read-only) */ - _mesa_init_vp_per_primitive_registers(ctx); + if (ctx->VertexProgram.Current->IsNVProgram) { + _mesa_load_tracked_matrices(ctx); + } + else { + _mesa_load_state_parameters(ctx, program->Base.Parameters); + } + + numOutputs = 0; + for (i = 0; i < VERT_RESULT_MAX; i++) { + if (program->Base.OutputsWritten & (1 << i)) { + outputs[numOutputs++] = i; + } + } for (i = 0; i < VB->Count; i++) { GLuint attr; - _mesa_init_vp_per_vertex_registers(ctx, &machine); + init_machine(ctx, &machine); #if 0 printf("Input %d: %f, %f, %f, %f\n", i, @@ -119,13 +252,12 @@ run_vp( GLcontext *ctx, struct tnl_pipeline_stage *stage ) const GLuint size = VB->AttribPtr[attr]->size; const GLuint stride = VB->AttribPtr[attr]->stride; const GLfloat *data = (GLfloat *) (ptr + stride * i); - COPY_CLEAN_4V(machine.Inputs[attr], size, data); + COPY_CLEAN_4V(machine.VertAttribs[attr], size, data); } } /* execute the program */ - ASSERT(program); - _mesa_exec_vertex_program(ctx, &machine, program); + _mesa_execute_program(ctx, &program->Base, &machine); /* Fixup fog an point size results if needed */ if (ctx->Fog.Enabled && @@ -139,33 +271,48 @@ run_vp( GLcontext *ctx, struct tnl_pipeline_stage *stage ) } /* copy the output registers into the VB->attribs arrays */ - /* XXX (optimize) could use a conditional and smaller loop limit here */ - for (attr = 0; attr < 15; attr++) { - COPY_4V(store->attribs[attr].data[i], machine.Outputs[attr]); + for (j = 0; j < numOutputs; j++) { + const GLuint attr = outputs[j]; + COPY_4V(store->results[attr].data[i], machine.Outputs[attr]); } +#if 0 + printf("HPOS: %f %f %f %f\n", + machine.Outputs[0][0], + machine.Outputs[0][1], + machine.Outputs[0][2], + machine.Outputs[0][3]); +#endif } /* Setup the VB pointers so that the next pipeline stages get * their data from the right place (the program output arrays). */ - VB->ClipPtr = &store->attribs[VERT_RESULT_HPOS]; + VB->ClipPtr = &store->results[VERT_RESULT_HPOS]; VB->ClipPtr->size = 4; VB->ClipPtr->count = VB->Count; - VB->ColorPtr[0] = &store->attribs[VERT_RESULT_COL0]; - VB->ColorPtr[1] = &store->attribs[VERT_RESULT_BFC0]; - VB->SecondaryColorPtr[0] = &store->attribs[VERT_RESULT_COL1]; - VB->SecondaryColorPtr[1] = &store->attribs[VERT_RESULT_BFC1]; - VB->FogCoordPtr = &store->attribs[VERT_RESULT_FOGC]; + VB->ColorPtr[0] = &store->results[VERT_RESULT_COL0]; + VB->ColorPtr[1] = &store->results[VERT_RESULT_BFC0]; + VB->SecondaryColorPtr[0] = &store->results[VERT_RESULT_COL1]; + VB->SecondaryColorPtr[1] = &store->results[VERT_RESULT_BFC1]; + VB->FogCoordPtr = &store->results[VERT_RESULT_FOGC]; - VB->AttribPtr[VERT_ATTRIB_COLOR0] = &store->attribs[VERT_RESULT_COL0]; - VB->AttribPtr[VERT_ATTRIB_COLOR1] = &store->attribs[VERT_RESULT_COL1]; - VB->AttribPtr[VERT_ATTRIB_FOG] = &store->attribs[VERT_RESULT_FOGC]; - VB->AttribPtr[_TNL_ATTRIB_POINTSIZE] = &store->attribs[VERT_RESULT_PSIZ]; + VB->AttribPtr[VERT_ATTRIB_COLOR0] = &store->results[VERT_RESULT_COL0]; + VB->AttribPtr[VERT_ATTRIB_COLOR1] = &store->results[VERT_RESULT_COL1]; + VB->AttribPtr[VERT_ATTRIB_FOG] = &store->results[VERT_RESULT_FOGC]; + VB->AttribPtr[_TNL_ATTRIB_POINTSIZE] = &store->results[VERT_RESULT_PSIZ]; for (i = 0; i < ctx->Const.MaxTextureCoordUnits; i++) { VB->TexCoordPtr[i] = VB->AttribPtr[_TNL_ATTRIB_TEX0 + i] - = &store->attribs[VERT_RESULT_TEX0 + i]; + = &store->results[VERT_RESULT_TEX0 + i]; + } + + for (i = 0; i < ctx->Const.MaxVarying; i++) { + if (program->Base.OutputsWritten & (1 << (VERT_RESULT_VAR0 + i))) { + /* Note: varying results get put into the generic attributes */ + VB->AttribPtr[VERT_ATTRIB_GENERIC0+i] + = &store->results[VERT_RESULT_VAR0 + i]; + } } /* Cliptest and perspective divide. Clip functions must clear @@ -206,8 +353,6 @@ run_vp( GLcontext *ctx, struct tnl_pipeline_stage *stage ) } - - /** * Called the first time stage->run is called. In effect, don't * allocate data until the first time the stage is run. @@ -227,10 +372,9 @@ static GLboolean init_vp( GLcontext *ctx, return GL_FALSE; /* Allocate arrays of vertex output values */ - /* XXX change '15' to a named constant */ - for (i = 0; i < 15; i++) { - _mesa_vector4f_alloc( &store->attribs[i], 0, size, 32 ); - store->attribs[i].size = 4; + for (i = 0; i < VERT_RESULT_MAX; i++) { + _mesa_vector4f_alloc( &store->results[i], 0, size, 32 ); + store->results[i].size = 4; } /* a few other misc allocations */ @@ -241,9 +385,6 @@ static GLboolean init_vp( GLcontext *ctx, } - - - /** * Destructor for this pipeline stage. */ @@ -256,7 +397,7 @@ static void dtr( struct tnl_pipeline_stage *stage ) /* free the vertex program result arrays */ for (i = 0; i < VERT_RESULT_MAX; i++) - _mesa_vector4f_free( &store->attribs[i] ); + _mesa_vector4f_free( &store->results[i] ); /* free misc arrays */ _mesa_vector4f_free( &store->ndcCoords ); @@ -267,6 +408,7 @@ static void dtr( struct tnl_pipeline_stage *stage ) } } + /** * Public description of this pipeline stage. */ diff --git a/src/mesa/tnl/t_vb_texgen.c b/src/mesa/tnl/t_vb_texgen.c index 5f7b2dccd8..e98ab743c5 100644 --- a/src/mesa/tnl/t_vb_texgen.c +++ b/src/mesa/tnl/t_vb_texgen.c @@ -488,10 +488,7 @@ static GLboolean run_texgen_stage( GLcontext *ctx, struct texgen_stage_data *store = TEXGEN_STAGE_DATA(stage); GLuint i; - if (ctx->ShaderObjects._VertexShaderPresent) - return GL_TRUE; - - if (!ctx->Texture._TexGenEnabled || ctx->VertexProgram._Enabled) + if (!ctx->Texture._TexGenEnabled || ctx->VertexProgram._Current) return GL_TRUE; for (i = 0 ; i < ctx->Const.MaxTextureCoordUnits ; i++) { @@ -516,10 +513,7 @@ static void validate_texgen_stage( GLcontext *ctx, struct texgen_stage_data *store = TEXGEN_STAGE_DATA(stage); GLuint i; - if (ctx->ShaderObjects._VertexShaderPresent) - return; - - if (!ctx->Texture._TexGenEnabled || ctx->VertexProgram._Enabled) + if (!ctx->Texture._TexGenEnabled || ctx->VertexProgram._Current) return; for (i = 0 ; i < ctx->Const.MaxTextureCoordUnits ; i++) { diff --git a/src/mesa/tnl/t_vb_texmat.c b/src/mesa/tnl/t_vb_texmat.c index fa9222c0f1..674d36f8cb 100644 --- a/src/mesa/tnl/t_vb_texmat.c +++ b/src/mesa/tnl/t_vb_texmat.c @@ -61,10 +61,7 @@ static GLboolean run_texmat_stage( GLcontext *ctx, struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb; GLuint i; - if (ctx->ShaderObjects._VertexShaderPresent) - return GL_TRUE; - - if (!ctx->Texture._TexMatEnabled || ctx->VertexProgram._Enabled) + if (!ctx->Texture._TexMatEnabled || ctx->VertexProgram._Current) return GL_TRUE; /* ENABLE_TEXMAT implies that the texture matrix is not the diff --git a/src/mesa/tnl/t_vb_vertex.c b/src/mesa/tnl/t_vb_vertex.c index 100fca2a22..276305b5e6 100644 --- a/src/mesa/tnl/t_vb_vertex.c +++ b/src/mesa/tnl/t_vb_vertex.c @@ -126,10 +126,7 @@ static GLboolean run_vertex_stage( GLcontext *ctx, TNLcontext *tnl = TNL_CONTEXT(ctx); struct vertex_buffer *VB = &tnl->vb; - if (ctx->ShaderObjects._VertexShaderPresent) - return GL_TRUE; - - if (ctx->VertexProgram._Enabled) + if (ctx->VertexProgram._Current) return GL_TRUE; if (ctx->_NeedEyeCoords) { diff --git a/src/mesa/tnl/t_vp_build.c b/src/mesa/tnl/t_vp_build.c index b1c148a136..63c99ee6ca 100644 --- a/src/mesa/tnl/t_vp_build.c +++ b/src/mesa/tnl/t_vp_build.c @@ -33,11 +33,14 @@ #include "glheader.h" #include "macros.h" #include "enums.h" +#include "program.h" +#include "prog_instruction.h" +#include "prog_parameter.h" +#include "prog_print.h" +#include "prog_statevars.h" #include "t_context.h" /* NOTE: very light dependency on this */ #include "t_vp_build.h" -#include "shader/program.h" -#include "shader/program_instruction.h" struct state_key { unsigned light_global_enabled:1; @@ -382,11 +385,14 @@ static struct ureg register_const4f( struct tnl_program *p, { GLfloat values[4]; GLint idx; + GLuint swizzle; values[0] = s0; values[1] = s1; values[2] = s2; values[3] = s3; - idx = _mesa_add_unnamed_constant( p->program->Base.Parameters, values, 4 ); + idx = _mesa_add_unnamed_constant( p->program->Base.Parameters, values, 4, + &swizzle ); + ASSERT(swizzle == SWIZZLE_NOOP); return make_ureg(PROGRAM_STATE_VAR, idx); } @@ -408,40 +414,37 @@ static struct ureg get_identity_param( struct tnl_program *p ) return p->identity; } -static struct ureg register_param6( struct tnl_program *p, +static struct ureg register_param5(struct tnl_program *p, GLint s0, GLint s1, GLint s2, GLint s3, - GLint s4, - GLint s5) + GLint s4) { - GLint tokens[6]; + gl_state_index tokens[STATE_LENGTH]; GLint idx; tokens[0] = s0; tokens[1] = s1; tokens[2] = s2; tokens[3] = s3; tokens[4] = s4; - tokens[5] = s5; idx = _mesa_add_state_reference( p->program->Base.Parameters, tokens ); return make_ureg(PROGRAM_STATE_VAR, idx); } -#define register_param1(p,s0) register_param6(p,s0,0,0,0,0,0) -#define register_param2(p,s0,s1) register_param6(p,s0,s1,0,0,0,0) -#define register_param3(p,s0,s1,s2) register_param6(p,s0,s1,s2,0,0,0) -#define register_param4(p,s0,s1,s2,s3) register_param6(p,s0,s1,s2,s3,0,0) +#define register_param1(p,s0) register_param5(p,s0,0,0,0,0) +#define register_param2(p,s0,s1) register_param5(p,s0,s1,0,0,0) +#define register_param3(p,s0,s1,s2) register_param5(p,s0,s1,s2,0,0) +#define register_param4(p,s0,s1,s2,s3) register_param5(p,s0,s1,s2,s3,0) -static void register_matrix_param6( struct tnl_program *p, - GLint s0, - GLint s1, - GLint s2, - GLint s3, - GLint s4, - GLint s5, +static void register_matrix_param5( struct tnl_program *p, + GLint s0, /* modelview, projection, etc */ + GLint s1, /* texture matrix number */ + GLint s2, /* first row */ + GLint s3, /* last row */ + GLint s4, /* inverse, transpose, etc */ struct ureg *matrix ) { GLint i; @@ -449,8 +452,8 @@ static void register_matrix_param6( struct tnl_program *p, /* This is a bit sad as the support is there to pull the whole * matrix out in one go: */ - for (i = 0; i <= s4 - s3; i++) - matrix[i] = register_param6( p, s0, s1, s2, i, i, s5 ); + for (i = 0; i <= s3 - s2; i++) + matrix[i] = register_param5( p, s0, s1, i, i, s4 ); } @@ -630,13 +633,13 @@ static struct ureg get_eye_position( struct tnl_program *p ) p->eye_position = reserve_temp(p); if (PREFER_DP4) { - register_matrix_param6( p, STATE_MATRIX, STATE_MODELVIEW, 0, 0, 3, - STATE_MATRIX, modelview ); + register_matrix_param5( p, STATE_MODELVIEW_MATRIX, 0, 0, 3, + 0, modelview ); emit_matrix_transform_vec4(p, p->eye_position, modelview, pos); } else { - register_matrix_param6( p, STATE_MATRIX, STATE_MODELVIEW, 0, 0, 3, + register_matrix_param5( p, STATE_MODELVIEW_MATRIX, 0, 0, 3, STATE_MATRIX_TRANSPOSE, modelview ); emit_transpose_matrix_transform_vec4(p, p->eye_position, modelview, pos); @@ -665,7 +668,7 @@ static struct ureg get_eye_normal( struct tnl_program *p ) struct ureg normal = register_input(p, VERT_ATTRIB_NORMAL ); struct ureg mvinv[3]; - register_matrix_param6( p, STATE_MATRIX, STATE_MODELVIEW, 0, 0, 2, + register_matrix_param5( p, STATE_MODELVIEW_MATRIX, 0, 0, 2, STATE_MATRIX_INVTRANS, mvinv ); p->eye_normal = reserve_temp(p); @@ -700,12 +703,12 @@ static void build_hpos( struct tnl_program *p ) struct ureg mvp[4]; if (PREFER_DP4) { - register_matrix_param6( p, STATE_MATRIX, STATE_MVP, 0, 0, 3, - STATE_MATRIX, mvp ); + register_matrix_param5( p, STATE_MVP_MATRIX, 0, 0, 3, + 0, mvp ); emit_matrix_transform_vec4( p, hpos, mvp, pos ); } else { - register_matrix_param6( p, STATE_MATRIX, STATE_MVP, 0, 0, 3, + register_matrix_param5( p, STATE_MVP_MATRIX, 0, 0, 3, STATE_MATRIX_TRANSPOSE, mvp ); emit_transpose_matrix_transform_vec4( p, hpos, mvp, pos ); } @@ -850,7 +853,7 @@ static struct ureg calculate_light_attenuation( struct tnl_program *p, /* Need to add some addtional parameters to allow lighting in object - * space - STATE_SPOT_DIRECTION and STATE_HALF implicitly assume eye + * space - STATE_SPOT_DIRECTION and STATE_HALF_VECTOR implicitly assume eye * space lighting. */ static void build_lighting( struct tnl_program *p ) @@ -945,7 +948,7 @@ static void build_lighting( struct tnl_program *p ) emit_op2(p, OPCODE_SUB, half, 0, VPpli, eye_hat); emit_normalize_vec3(p, half, half); } else { - half = register_param3(p, STATE_LIGHT, i, STATE_HALF); + half = register_param3(p, STATE_LIGHT, i, STATE_HALF_VECTOR); } } else { @@ -1211,7 +1214,7 @@ static void build_texture_transform( struct tnl_program *p ) for (i = 0; i < MAX_TEXTURE_UNITS; i++) { - if (!(p->state->fragprog_inputs_read & (FRAG_BIT_TEX0<<i))) + if (!(p->state->fragprog_inputs_read & FRAG_BIT_TEX(i))) continue; if (p->state->unit[i].texgen_enabled || @@ -1301,13 +1304,13 @@ static void build_texture_transform( struct tnl_program *p ) out_texgen : register_input(p, VERT_ATTRIB_TEX0+i)); if (PREFER_DP4) { - register_matrix_param6( p, STATE_MATRIX, STATE_TEXTURE, i, - 0, 3, STATE_MATRIX, texmat ); + register_matrix_param5( p, STATE_TEXTURE_MATRIX, i, 0, 3, + 0, texmat ); emit_matrix_transform_vec4( p, out, texmat, in ); } else { - register_matrix_param6( p, STATE_MATRIX, STATE_TEXTURE, i, - 0, 3, STATE_MATRIX_TRANSPOSE, texmat ); + register_matrix_param5( p, STATE_TEXTURE_MATRIX, i, 0, 3, + STATE_MATRIX_TRANSPOSE, texmat ); emit_transpose_matrix_transform_vec4( p, out, texmat, in ); } } @@ -1503,7 +1506,7 @@ void _tnl_UpdateFixedFunctionProgram( GLcontext *ctx ) GLuint hash; const struct gl_vertex_program *prev = ctx->VertexProgram._Current; - if (ctx->VertexProgram._Enabled == GL_FALSE) { + if (!ctx->VertexProgram._Current) { /* Grab all the relevent state and put it in a single structure: */ key = make_state_key(ctx); @@ -1511,45 +1514,42 @@ void _tnl_UpdateFixedFunctionProgram( GLcontext *ctx ) /* Look for an already-prepared program for this state: */ - ctx->_TnlProgram = (struct gl_vertex_program *) + ctx->VertexProgram._TnlProgram = (struct gl_vertex_program *) search_cache( tnl->vp_cache, hash, key, sizeof(*key) ); /* OK, we'll have to build a new one: */ - if (!ctx->_TnlProgram) { + if (!ctx->VertexProgram._TnlProgram) { if (0) _mesa_printf("Build new TNL program\n"); - ctx->_TnlProgram = (struct gl_vertex_program *) + ctx->VertexProgram._TnlProgram = (struct gl_vertex_program *) ctx->Driver.NewProgram(ctx, GL_VERTEX_PROGRAM_ARB, 0); - create_new_program( key, ctx->_TnlProgram, + create_new_program( key, ctx->VertexProgram._TnlProgram, ctx->Const.VertexProgram.MaxTemps ); if (ctx->Driver.ProgramStringNotify) ctx->Driver.ProgramStringNotify( ctx, GL_VERTEX_PROGRAM_ARB, - &ctx->_TnlProgram->Base ); + &ctx->VertexProgram._TnlProgram->Base ); - cache_item(tnl->vp_cache, hash, key, ctx->_TnlProgram ); + cache_item(tnl->vp_cache, hash, key, ctx->VertexProgram._TnlProgram ); } else { FREE(key); if (0) _mesa_printf("Found existing TNL program for key %x\n", hash); } - ctx->VertexProgram._Current = ctx->_TnlProgram; - } - else { - ctx->VertexProgram._Current = ctx->VertexProgram.Current; + ctx->VertexProgram._Current = ctx->VertexProgram._TnlProgram; } /* Tell the driver about the change. Could define a new target for * this? */ - if (ctx->VertexProgram._Current != prev && - ctx->Driver.BindProgram) + if (ctx->VertexProgram._Current != prev && ctx->Driver.BindProgram) { ctx->Driver.BindProgram(ctx, GL_VERTEX_PROGRAM_ARB, (struct gl_program *) ctx->VertexProgram._Current); + } } void _tnl_ProgramCacheInit( GLcontext *ctx ) diff --git a/src/mesa/tnl/tnl.h b/src/mesa/tnl/tnl.h index 17cb30adc7..20bed5546d 100644 --- a/src/mesa/tnl/tnl.h +++ b/src/mesa/tnl/tnl.h @@ -82,4 +82,7 @@ _tnl_draw_prims( GLcontext *ctx, GLuint min_index, GLuint max_index); +extern void +_mesa_load_tracked_matrices(GLcontext *ctx); + #endif diff --git a/src/mesa/tnl_dd/t_dd_vb.c b/src/mesa/tnl_dd/t_dd_vb.c index edd78f7acf..629f328a4d 100644 --- a/src/mesa/tnl_dd/t_dd_vb.c +++ b/src/mesa/tnl_dd/t_dd_vb.c @@ -141,45 +141,45 @@ void TAG(translate_vertex)(GLcontext *ctx, ((HAVE_TEX2_VERTICES && format == PROJ_TEX3_VERTEX_FORMAT) || (format == PROJ_TEX1_VERTEX_FORMAT))) { - dst->texcoord[0][0] = src->pv.u0; - dst->texcoord[0][1] = src->pv.v0; - dst->texcoord[0][3] = src->pv.q0; + dst->attrib[FRAG_ATTRIB_TEX0][0] = src->pv.u0; + dst->attrib[FRAG_ATTRIB_TEX0][1] = src->pv.v0; + dst->attrib[FRAG_ATTRIB_TEX0][3] = src->pv.q0; - dst->texcoord[1][0] = src->pv.u1; - dst->texcoord[1][1] = src->pv.v1; - dst->texcoord[1][3] = src->pv.q1; + dst->attrib[FRAG_ATTRIB_TEX1][0] = src->pv.u1; + dst->attrib[FRAG_ATTRIB_TEX1][1] = src->pv.v1; + dst->attrib[FRAG_ATTRIB_TEX1][3] = src->pv.q1; if (HAVE_TEX2_VERTICES) { - dst->texcoord[2][0] = src->pv.u2; - dst->texcoord[2][1] = src->pv.v2; - dst->texcoord[2][3] = src->pv.q2; + dst->attrib[FRAG_ATTRIB_TEX2][0] = src->pv.u2; + dst->attrib[FRAG_ATTRIB_TEX2][1] = src->pv.v2; + dst->attrib[FRAG_ATTRIB_TEX2][3] = src->pv.q2; } if (HAVE_TEX3_VERTICES) { - dst->texcoord[3][0] = src->pv.u3; - dst->texcoord[3][1] = src->pv.v3; - dst->texcoord[3][3] = src->pv.q3; + dst->attrib[FRAG_ATTRIB_TEX3][0] = src->pv.u3; + dst->attrib[FRAG_ATTRIB_TEX3][1] = src->pv.v3; + dst->attrib[FRAG_ATTRIB_TEX3][3] = src->pv.q3; } } else { - dst->texcoord[0][0] = src->v.u0; - dst->texcoord[0][1] = src->v.v0; - dst->texcoord[0][3] = 1.0; + dst->attrib[FRAG_ATTRIB_TEX0][0] = src->v.u0; + dst->attrib[FRAG_ATTRIB_TEX0][1] = src->v.v0; + dst->attrib[FRAG_ATTRIB_TEX0][3] = 1.0; - dst->texcoord[1][0] = src->v.u1; - dst->texcoord[1][1] = src->v.v1; - dst->texcoord[1][3] = 1.0; + dst->attrib[FRAG_ATTRIB_TEX1][0] = src->v.u1; + dst->attrib[FRAG_ATTRIB_TEX1][1] = src->v.v1; + dst->attrib[FRAG_ATTRIB_TEX1][3] = 1.0; if (HAVE_TEX2_VERTICES) { - dst->texcoord[2][0] = src->v.u2; - dst->texcoord[2][1] = src->v.v2; - dst->texcoord[2][3] = 1.0; + dst->attrib[FRAG_ATTRIB_TEX2][0] = src->v.u2; + dst->attrib[FRAG_ATTRIB_TEX2][1] = src->v.v2; + dst->attrib[FRAG_ATTRIB_TEX2][3] = 1.0; } if (HAVE_TEX3_VERTICES) { - dst->texcoord[3][0] = src->v.u3; - dst->texcoord[3][1] = src->v.v3; - dst->texcoord[3][3] = 1.0; + dst->attrib[FRAG_ATTRIB_TEX3][0] = src->v.u3; + dst->attrib[FRAG_ATTRIB_TEX3][1] = src->v.v3; + dst->attrib[FRAG_ATTRIB_TEX3][3] = 1.0; } } } diff --git a/src/mesa/vbo/vbo_context.h b/src/mesa/vbo/vbo_context.h index 0dc1019b39..013f81bdd5 100644 --- a/src/mesa/vbo/vbo_context.h +++ b/src/mesa/vbo/vbo_context.h @@ -96,9 +96,9 @@ enum { static INLINE GLuint get_program_mode( GLcontext *ctx ) { - if (!ctx->VertexProgram._Enabled) + if (!ctx->VertexProgram._Current) return VP_NONE; - else if (ctx->VertexProgram.Current->IsNVProgram) + else if (ctx->VertexProgram._Current->IsNVProgram) return VP_NV; else return VP_ARB; diff --git a/src/mesa/vbo/vbo_exec_api.c b/src/mesa/vbo/vbo_exec_api.c index 71fee8ca16..c30fd18e2d 100644 --- a/src/mesa/vbo/vbo_exec_api.c +++ b/src/mesa/vbo/vbo_exec_api.c @@ -486,6 +486,7 @@ static void GLAPIENTRY vbo_exec_Begin( GLenum mode ) if (ctx->NewState) { _mesa_update_state( ctx ); + /* XXX also need to check if shader enabled, but invalid */ if ((ctx->VertexProgram.Enabled && !ctx->VertexProgram._Enabled) || (ctx->FragmentProgram.Enabled && !ctx->FragmentProgram._Enabled)) { _mesa_error(ctx, GL_INVALID_OPERATION, diff --git a/src/mesa/vbo/vbo_save_draw.c b/src/mesa/vbo/vbo_save_draw.c index bc59a0d821..75cbf020d7 100644 --- a/src/mesa/vbo/vbo_save_draw.c +++ b/src/mesa/vbo/vbo_save_draw.c @@ -203,6 +203,7 @@ void vbo_save_playback_vertex_list( GLcontext *ctx, void *data ) if (ctx->NewState) _mesa_update_state( ctx ); + /* XXX also need to check if shader enabled, but invalid */ if ((ctx->VertexProgram.Enabled && !ctx->VertexProgram._Enabled) || (ctx->FragmentProgram.Enabled && !ctx->FragmentProgram._Enabled)) { _mesa_error(ctx, GL_INVALID_OPERATION, |