diff options
author | marha <marha@users.sourceforge.net> | 2010-11-29 22:05:53 +0000 |
---|---|---|
committer | marha <marha@users.sourceforge.net> | 2010-11-29 22:05:53 +0000 |
commit | fed109d6a33c0871291d1bb2f3f6b7a3d1a3e9d7 (patch) | |
tree | fa1ba494685a71e28a096990a8707680c7cb378b /mesalib/src/mesa/shader | |
parent | ae340911c1ba1f98b418bd8f1a487fa4d79491b0 (diff) | |
parent | 6fda93be42ace9eeab0e82ceebb6798961c9105c (diff) | |
download | vcxsrv-fed109d6a33c0871291d1bb2f3f6b7a3d1a3e9d7.tar.gz vcxsrv-fed109d6a33c0871291d1bb2f3f6b7a3d1a3e9d7.tar.bz2 vcxsrv-fed109d6a33c0871291d1bb2f3f6b7a3d1a3e9d7.zip |
svn merge ^/branches/released .
Diffstat (limited to 'mesalib/src/mesa/shader')
98 files changed, 0 insertions, 61073 deletions
diff --git a/mesalib/src/mesa/shader/Makefile b/mesalib/src/mesa/shader/Makefile deleted file mode 100644 index 400a543bd..000000000 --- a/mesalib/src/mesa/shader/Makefile +++ /dev/null @@ -1,7 +0,0 @@ -all: program_parse.tab.c lex.yy.c - -program_parse.tab.c program_parse.tab.h: program_parse.y - bison -v -d $< - -lex.yy.c: program_lexer.l - flex --never-interactive $< diff --git a/mesalib/src/mesa/shader/arbprogparse.c b/mesalib/src/mesa/shader/arbprogparse.c deleted file mode 100644 index 6373529e4..000000000 --- a/mesalib/src/mesa/shader/arbprogparse.c +++ /dev/null @@ -1,217 +0,0 @@ -/* - * Mesa 3-D graphics library - * Version: 7.1 - * - * Copyright (C) 1999-2008 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. - */ - -#define DEBUG_PARSING 0 - -/** - * \file arbprogparse.c - * ARB_*_program parser core - * \author Karl Rasche - */ - -/** -Notes on program parameters, etc. - -The instructions we emit will use six kinds of source registers: - - PROGRAM_INPUT - input registers - PROGRAM_TEMPORARY - temp registers - PROGRAM_ADDRESS - address/indirect register - PROGRAM_SAMPLER - texture sampler - PROGRAM_CONSTANT - indexes into program->Parameters, a known constant/literal - PROGRAM_STATE_VAR - indexes into program->Parameters, and may actually be: - + a state variable, like "state.fog.color", or - + a pointer to a "program.local[k]" parameter, or - + a pointer to a "program.env[k]" parameter - -Basically, all the program.local[] and program.env[] values will get mapped -into the unified gl_program->Parameters array. This solves the problem of -having three separate program parameter arrays. -*/ - - -#include "main/glheader.h" -#include "main/imports.h" -#include "main/context.h" -#include "main/mtypes.h" -#include "arbprogparse.h" -#include "programopt.h" -#include "prog_parameter.h" -#include "prog_statevars.h" -#include "prog_instruction.h" -#include "program_parser.h" - - -void -_mesa_parse_arb_fragment_program(GLcontext* ctx, GLenum target, - const GLvoid *str, GLsizei len, - struct gl_fragment_program *program) -{ - struct gl_program prog; - struct asm_parser_state state; - GLuint i; - - ASSERT(target == GL_FRAGMENT_PROGRAM_ARB); - - memset(&prog, 0, sizeof(prog)); - memset(&state, 0, sizeof(state)); - state.prog = &prog; - - if (!_mesa_parse_arb_program(ctx, target, (const GLubyte*) str, len, - &state)) { - /* Error in the program. Just return. */ - return; - } - - if (program->Base.String != NULL) - free(program->Base.String); - - /* Copy the relevant contents of the arb_program struct into the - * fragment_program struct. - */ - program->Base.String = prog.String; - program->Base.NumInstructions = prog.NumInstructions; - program->Base.NumTemporaries = prog.NumTemporaries; - program->Base.NumParameters = prog.NumParameters; - program->Base.NumAttributes = prog.NumAttributes; - program->Base.NumAddressRegs = prog.NumAddressRegs; - program->Base.NumNativeInstructions = prog.NumNativeInstructions; - program->Base.NumNativeTemporaries = prog.NumNativeTemporaries; - program->Base.NumNativeParameters = prog.NumNativeParameters; - program->Base.NumNativeAttributes = prog.NumNativeAttributes; - program->Base.NumNativeAddressRegs = prog.NumNativeAddressRegs; - program->Base.NumAluInstructions = prog.NumAluInstructions; - program->Base.NumTexInstructions = prog.NumTexInstructions; - program->Base.NumTexIndirections = prog.NumTexIndirections; - program->Base.NumNativeAluInstructions = prog.NumAluInstructions; - program->Base.NumNativeTexInstructions = prog.NumTexInstructions; - program->Base.NumNativeTexIndirections = prog.NumTexIndirections; - program->Base.InputsRead = prog.InputsRead; - program->Base.OutputsWritten = prog.OutputsWritten; - for (i = 0; i < MAX_TEXTURE_IMAGE_UNITS; i++) { - program->Base.TexturesUsed[i] = prog.TexturesUsed[i]; - if (prog.TexturesUsed[i]) - program->Base.SamplersUsed |= (1 << i); - } - program->Base.ShadowSamplers = prog.ShadowSamplers; - switch (state.option.Fog) { - case OPTION_FOG_EXP: program->FogOption = GL_EXP; break; - case OPTION_FOG_EXP2: program->FogOption = GL_EXP2; break; - case OPTION_FOG_LINEAR: program->FogOption = GL_LINEAR; break; - default: program->FogOption = GL_NONE; break; - } - program->OriginUpperLeft = state.option.OriginUpperLeft; - program->PixelCenterInteger = state.option.PixelCenterInteger; - - program->UsesKill = state.fragment.UsesKill; - - if (program->FogOption) - program->Base.InputsRead |= FRAG_BIT_FOGC; - - if (program->Base.Instructions) - free(program->Base.Instructions); - program->Base.Instructions = prog.Instructions; - - if (program->Base.Parameters) - _mesa_free_parameter_list(program->Base.Parameters); - program->Base.Parameters = prog.Parameters; - - /* Append fog instructions now if the program has "OPTION ARB_fog_exp" - * or similar. We used to leave this up to drivers, but it appears - * there's no hardware that wants to do fog in a discrete stage separate - * from the fragment shader. - */ - if (program->FogOption != GL_NONE) { - _mesa_append_fog_code(ctx, program); - program->FogOption = GL_NONE; - } - -#if DEBUG_FP - printf("____________Fragment program %u ________\n", program->Base.Id); - _mesa_print_program(&program->Base); -#endif -} - - - -/** - * Parse the vertex program string. If success, update the given - * vertex_program object with the new program. Else, leave the vertex_program - * object unchanged. - */ -void -_mesa_parse_arb_vertex_program(GLcontext *ctx, GLenum target, - const GLvoid *str, GLsizei len, - struct gl_vertex_program *program) -{ - struct gl_program prog; - struct asm_parser_state state; - - ASSERT(target == GL_VERTEX_PROGRAM_ARB); - - memset(&prog, 0, sizeof(prog)); - memset(&state, 0, sizeof(state)); - state.prog = &prog; - - if (!_mesa_parse_arb_program(ctx, target, (const GLubyte*) str, len, - &state)) { - _mesa_error(ctx, GL_INVALID_OPERATION, "glProgramString(bad program)"); - return; - } - - if (program->Base.String != NULL) - free(program->Base.String); - - /* Copy the relevant contents of the arb_program struct into the - * vertex_program struct. - */ - program->Base.String = prog.String; - program->Base.NumInstructions = prog.NumInstructions; - program->Base.NumTemporaries = prog.NumTemporaries; - program->Base.NumParameters = prog.NumParameters; - program->Base.NumAttributes = prog.NumAttributes; - program->Base.NumAddressRegs = prog.NumAddressRegs; - program->Base.NumNativeInstructions = prog.NumNativeInstructions; - program->Base.NumNativeTemporaries = prog.NumNativeTemporaries; - program->Base.NumNativeParameters = prog.NumNativeParameters; - program->Base.NumNativeAttributes = prog.NumNativeAttributes; - program->Base.NumNativeAddressRegs = prog.NumNativeAddressRegs; - program->Base.InputsRead = prog.InputsRead; - program->Base.OutputsWritten = prog.OutputsWritten; - program->IsPositionInvariant = (state.option.PositionInvariant) - ? GL_TRUE : GL_FALSE; - - if (program->Base.Instructions) - free(program->Base.Instructions); - program->Base.Instructions = prog.Instructions; - - if (program->Base.Parameters) - _mesa_free_parameter_list(program->Base.Parameters); - program->Base.Parameters = prog.Parameters; - -#if DEBUG_VP - printf("____________Vertex program %u __________\n", program->Base.Id); - _mesa_print_program(&program->Base); -#endif -} diff --git a/mesalib/src/mesa/shader/arbprogparse.h b/mesalib/src/mesa/shader/arbprogparse.h deleted file mode 100644 index 980d39fb9..000000000 --- a/mesalib/src/mesa/shader/arbprogparse.h +++ /dev/null @@ -1,41 +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. - */ - - -#ifndef ARBPROGPARSE_H -#define ARBPROGPARSE_H - -#include "main/mtypes.h" - -extern void -_mesa_parse_arb_vertex_program(GLcontext *ctx, GLenum target, - const GLvoid *str, GLsizei len, - struct gl_vertex_program *program); - -extern void -_mesa_parse_arb_fragment_program(GLcontext *ctx, GLenum target, - const GLvoid *str, GLsizei len, - struct gl_fragment_program *program); - -#endif diff --git a/mesalib/src/mesa/shader/arbprogram.c b/mesalib/src/mesa/shader/arbprogram.c deleted file mode 100644 index 75b4274bf..000000000 --- a/mesalib/src/mesa/shader/arbprogram.c +++ /dev/null @@ -1,1097 +0,0 @@ -/* - * Mesa 3-D graphics library - * Version: 7.0 - * - * 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 arbprogram.c - * ARB_vertex/fragment_program state management functions. - * \author Brian Paul - */ - - -#include "main/glheader.h" -#include "main/context.h" -#include "main/hash.h" -#include "main/imports.h" -#include "main/macros.h" -#include "main/mtypes.h" -#include "arbprogram.h" -#include "arbprogparse.h" -#include "nvfragparse.h" -#include "nvvertparse.h" -#include "program.h" - - - -/** - * Mixing ARB and NV vertex/fragment programs can be tricky. - * Note: GL_VERTEX_PROGRAM_ARB == GL_VERTEX_PROGRAM_NV - * but, GL_FRAGMENT_PROGRAM_ARB != GL_FRAGMENT_PROGRAM_NV - * The two different fragment program targets are supposed to be compatible - * to some extent (see GL_ARB_fragment_program spec). - * This function does the compatibility check. - */ -static GLboolean -compatible_program_targets(GLenum t1, GLenum t2) -{ - if (t1 == t2) - return GL_TRUE; - if (t1 == GL_FRAGMENT_PROGRAM_ARB && t2 == GL_FRAGMENT_PROGRAM_NV) - return GL_TRUE; - if (t1 == GL_FRAGMENT_PROGRAM_NV && t2 == GL_FRAGMENT_PROGRAM_ARB) - return GL_TRUE; - return GL_FALSE; -} - - -/** - * Bind a program (make it current) - * \note Called from the GL API dispatcher by both glBindProgramNV - * and glBindProgramARB. - */ -void GLAPIENTRY -_mesa_BindProgram(GLenum target, GLuint id) -{ - struct gl_program *curProg, *newProg; - GET_CURRENT_CONTEXT(ctx); - ASSERT_OUTSIDE_BEGIN_END(ctx); - - /* Error-check target and get curProg */ - if ((target == GL_VERTEX_PROGRAM_ARB) && /* == GL_VERTEX_PROGRAM_NV */ - (ctx->Extensions.NV_vertex_program || - ctx->Extensions.ARB_vertex_program)) { - curProg = &ctx->VertexProgram.Current->Base; - } - else if ((target == GL_FRAGMENT_PROGRAM_NV - && ctx->Extensions.NV_fragment_program) || - (target == GL_FRAGMENT_PROGRAM_ARB - && ctx->Extensions.ARB_fragment_program)) { - curProg = &ctx->FragmentProgram.Current->Base; - } - else { - _mesa_error(ctx, GL_INVALID_ENUM, "glBindProgramNV/ARB(target)"); - return; - } - - /* - * Get pointer to new program to bind. - * NOTE: binding to a non-existant program is not an error. - * That's supposed to be caught in glBegin. - */ - if (id == 0) { - /* Bind a default program */ - newProg = NULL; - if (target == GL_VERTEX_PROGRAM_ARB) /* == GL_VERTEX_PROGRAM_NV */ - newProg = &ctx->Shared->DefaultVertexProgram->Base; - else - newProg = &ctx->Shared->DefaultFragmentProgram->Base; - } - else { - /* Bind a user program */ - newProg = _mesa_lookup_program(ctx, id); - if (!newProg || newProg == &_mesa_DummyProgram) { - /* allocate a new program now */ - newProg = ctx->Driver.NewProgram(ctx, target, id); - if (!newProg) { - _mesa_error(ctx, GL_OUT_OF_MEMORY, "glBindProgramNV/ARB"); - return; - } - _mesa_HashInsert(ctx->Shared->Programs, id, newProg); - } - else if (!compatible_program_targets(newProg->Target, target)) { - _mesa_error(ctx, GL_INVALID_OPERATION, - "glBindProgramNV/ARB(target mismatch)"); - return; - } - } - - /** All error checking is complete now **/ - - if (curProg->Id == id) { - /* binding same program - no change */ - return; - } - - /* signal new program (and its new constants) */ - FLUSH_VERTICES(ctx, _NEW_PROGRAM | _NEW_PROGRAM_CONSTANTS); - - /* bind newProg */ - if (target == GL_VERTEX_PROGRAM_ARB) { /* == GL_VERTEX_PROGRAM_NV */ - _mesa_reference_vertprog(ctx, &ctx->VertexProgram.Current, - (struct gl_vertex_program *) newProg); - } - else if (target == GL_FRAGMENT_PROGRAM_NV || - target == GL_FRAGMENT_PROGRAM_ARB) { - _mesa_reference_fragprog(ctx, &ctx->FragmentProgram.Current, - (struct gl_fragment_program *) newProg); - } - - /* Never null pointers */ - ASSERT(ctx->VertexProgram.Current); - ASSERT(ctx->FragmentProgram.Current); - - if (ctx->Driver.BindProgram) - ctx->Driver.BindProgram(ctx, target, newProg); -} - - -/** - * Delete a list of programs. - * \note Not compiled into display lists. - * \note Called by both glDeleteProgramsNV and glDeleteProgramsARB. - */ -void GLAPIENTRY -_mesa_DeletePrograms(GLsizei n, const GLuint *ids) -{ - GLint i; - GET_CURRENT_CONTEXT(ctx); - ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); - - if (n < 0) { - _mesa_error( ctx, GL_INVALID_VALUE, "glDeleteProgramsNV" ); - return; - } - - for (i = 0; i < n; i++) { - if (ids[i] != 0) { - struct gl_program *prog = _mesa_lookup_program(ctx, ids[i]); - if (prog == &_mesa_DummyProgram) { - _mesa_HashRemove(ctx->Shared->Programs, ids[i]); - } - else if (prog) { - /* Unbind program if necessary */ - switch (prog->Target) { - case GL_VERTEX_PROGRAM_ARB: /* == GL_VERTEX_PROGRAM_NV */ - case GL_VERTEX_STATE_PROGRAM_NV: - if (ctx->VertexProgram.Current && - ctx->VertexProgram.Current->Base.Id == ids[i]) { - /* unbind this currently bound program */ - _mesa_BindProgram(prog->Target, 0); - } - break; - case GL_FRAGMENT_PROGRAM_NV: - case GL_FRAGMENT_PROGRAM_ARB: - if (ctx->FragmentProgram.Current && - ctx->FragmentProgram.Current->Base.Id == ids[i]) { - /* unbind this currently bound program */ - _mesa_BindProgram(prog->Target, 0); - } - break; - default: - _mesa_problem(ctx, "bad target in glDeleteProgramsNV"); - return; - } - /* The ID is immediately available for re-use now */ - _mesa_HashRemove(ctx->Shared->Programs, ids[i]); - _mesa_reference_program(ctx, &prog, NULL); - } - } - } -} - - -/** - * Generate a list of new program identifiers. - * \note Not compiled into display lists. - * \note Called by both glGenProgramsNV and glGenProgramsARB. - */ -void GLAPIENTRY -_mesa_GenPrograms(GLsizei n, GLuint *ids) -{ - GLuint first; - GLuint i; - GET_CURRENT_CONTEXT(ctx); - ASSERT_OUTSIDE_BEGIN_END(ctx); - - if (n < 0) { - _mesa_error(ctx, GL_INVALID_VALUE, "glGenPrograms"); - return; - } - - if (!ids) - return; - - first = _mesa_HashFindFreeKeyBlock(ctx->Shared->Programs, n); - - /* Insert pointer to dummy program as placeholder */ - for (i = 0; i < (GLuint) n; i++) { - _mesa_HashInsert(ctx->Shared->Programs, first + i, &_mesa_DummyProgram); - } - - /* Return the program names */ - for (i = 0; i < (GLuint) n; i++) { - ids[i] = first + i; - } -} - - -void GLAPIENTRY -_mesa_EnableVertexAttribArrayARB(GLuint index) -{ - GET_CURRENT_CONTEXT(ctx); - ASSERT_OUTSIDE_BEGIN_END(ctx); - - if (index >= ctx->Const.VertexProgram.MaxAttribs) { - _mesa_error(ctx, GL_INVALID_VALUE, - "glEnableVertexAttribArrayARB(index)"); - return; - } - - ASSERT(index < Elements(ctx->Array.ArrayObj->VertexAttrib)); - - FLUSH_VERTICES(ctx, _NEW_ARRAY); - ctx->Array.ArrayObj->VertexAttrib[index].Enabled = GL_TRUE; - ctx->Array.ArrayObj->_Enabled |= _NEW_ARRAY_ATTRIB(index); - ctx->Array.NewState |= _NEW_ARRAY_ATTRIB(index); -} - - -void GLAPIENTRY -_mesa_DisableVertexAttribArrayARB(GLuint index) -{ - GET_CURRENT_CONTEXT(ctx); - ASSERT_OUTSIDE_BEGIN_END(ctx); - - if (index >= ctx->Const.VertexProgram.MaxAttribs) { - _mesa_error(ctx, GL_INVALID_VALUE, - "glEnableVertexAttribArrayARB(index)"); - return; - } - - ASSERT(index < Elements(ctx->Array.ArrayObj->VertexAttrib)); - - FLUSH_VERTICES(ctx, _NEW_ARRAY); - ctx->Array.ArrayObj->VertexAttrib[index].Enabled = GL_FALSE; - ctx->Array.ArrayObj->_Enabled &= ~_NEW_ARRAY_ATTRIB(index); - ctx->Array.NewState |= _NEW_ARRAY_ATTRIB(index); -} - - -void GLAPIENTRY -_mesa_GetVertexAttribdvARB(GLuint index, GLenum pname, GLdouble *params) -{ - GLfloat fparams[4]; - GET_CURRENT_CONTEXT(ctx); - ASSERT_OUTSIDE_BEGIN_END(ctx); - - _mesa_GetVertexAttribfvARB(index, pname, fparams); - if (ctx->ErrorValue == GL_NO_ERROR) { - if (pname == GL_CURRENT_VERTEX_ATTRIB_ARB) { - COPY_4V(params, fparams); - } - else { - params[0] = fparams[0]; - } - } -} - - -/** - * Return info for a generic vertex attribute array (no alias with - * legacy vertex attributes (pos, normal, color, etc)). - */ -void GLAPIENTRY -_mesa_GetVertexAttribfvARB(GLuint index, GLenum pname, GLfloat *params) -{ - const struct gl_client_array *array; - GET_CURRENT_CONTEXT(ctx); - ASSERT_OUTSIDE_BEGIN_END(ctx); - - if (index >= MAX_VERTEX_GENERIC_ATTRIBS) { - _mesa_error(ctx, GL_INVALID_VALUE, "glGetVertexAttribfvARB(index)"); - return; - } - - ASSERT(index < Elements(ctx->Array.ArrayObj->VertexAttrib)); - - array = &ctx->Array.ArrayObj->VertexAttrib[index]; - - switch (pname) { - case GL_VERTEX_ATTRIB_ARRAY_ENABLED_ARB: - params[0] = (GLfloat) array->Enabled; - break; - case GL_VERTEX_ATTRIB_ARRAY_SIZE_ARB: - params[0] = (GLfloat) array->Size; - break; - case GL_VERTEX_ATTRIB_ARRAY_STRIDE_ARB: - params[0] = (GLfloat) array->Stride; - break; - case GL_VERTEX_ATTRIB_ARRAY_TYPE_ARB: - params[0] = (GLfloat) array->Type; - break; - case GL_VERTEX_ATTRIB_ARRAY_NORMALIZED_ARB: - params[0] = array->Normalized; - break; - case GL_CURRENT_VERTEX_ATTRIB_ARB: - if (index == 0) { - _mesa_error(ctx, GL_INVALID_OPERATION, - "glGetVertexAttribfvARB(index==0)"); - return; - } - FLUSH_CURRENT(ctx, 0); - COPY_4V(params, ctx->Current.Attrib[VERT_ATTRIB_GENERIC0 + index]); - break; - case GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING_ARB: - params[0] = (GLfloat) array->BufferObj->Name; - break; - default: - _mesa_error(ctx, GL_INVALID_ENUM, "glGetVertexAttribfvARB(pname)"); - return; - } -} - - -void GLAPIENTRY -_mesa_GetVertexAttribivARB(GLuint index, GLenum pname, GLint *params) -{ - GLfloat fparams[4]; - GET_CURRENT_CONTEXT(ctx); - ASSERT_OUTSIDE_BEGIN_END(ctx); - - _mesa_GetVertexAttribfvARB(index, pname, fparams); - if (ctx->ErrorValue == GL_NO_ERROR) { - if (pname == GL_CURRENT_VERTEX_ATTRIB_ARB) { - COPY_4V_CAST(params, fparams, GLint); /* float to int */ - } - else { - params[0] = (GLint) fparams[0]; - } - } -} - - -void GLAPIENTRY -_mesa_GetVertexAttribPointervARB(GLuint index, GLenum pname, GLvoid **pointer) -{ - GET_CURRENT_CONTEXT(ctx); - ASSERT_OUTSIDE_BEGIN_END(ctx); - - if (index >= ctx->Const.VertexProgram.MaxAttribs) { - _mesa_error(ctx, GL_INVALID_VALUE, "glGetVertexAttribPointerARB(index)"); - return; - } - - if (pname != GL_VERTEX_ATTRIB_ARRAY_POINTER_ARB) { - _mesa_error(ctx, GL_INVALID_ENUM, "glGetVertexAttribPointerARB(pname)"); - return; - } - - ASSERT(index < Elements(ctx->Array.ArrayObj->VertexAttrib)); - - *pointer = (GLvoid *) ctx->Array.ArrayObj->VertexAttrib[index].Ptr; -} - - -/** - * Determine if id names a vertex or fragment program. - * \note Not compiled into display lists. - * \note Called from both glIsProgramNV and glIsProgramARB. - * \param id is the program identifier - * \return GL_TRUE if id is a program, else GL_FALSE. - */ -GLboolean GLAPIENTRY -_mesa_IsProgramARB(GLuint id) -{ - struct gl_program *prog = NULL; - GET_CURRENT_CONTEXT(ctx); - ASSERT_OUTSIDE_BEGIN_END_WITH_RETVAL(ctx, GL_FALSE); - - if (id == 0) - return GL_FALSE; - - prog = _mesa_lookup_program(ctx, id); - if (prog && (prog != &_mesa_DummyProgram)) - return GL_TRUE; - else - return GL_FALSE; -} - - -void GLAPIENTRY -_mesa_ProgramStringARB(GLenum target, GLenum format, GLsizei len, - const GLvoid *string) -{ - struct gl_program *base; - GET_CURRENT_CONTEXT(ctx); - ASSERT_OUTSIDE_BEGIN_END(ctx); - - FLUSH_VERTICES(ctx, _NEW_PROGRAM); - - if (!ctx->Extensions.ARB_vertex_program - && !ctx->Extensions.ARB_fragment_program) { - _mesa_error(ctx, GL_INVALID_OPERATION, "glProgramStringARB()"); - return; - } - - if (format != GL_PROGRAM_FORMAT_ASCII_ARB) { - _mesa_error(ctx, GL_INVALID_ENUM, "glProgramStringARB(format)"); - return; - } - - /* The first couple cases are complicated. The same enum value is used for - * ARB and NV vertex programs. If the target is a vertex program, parse it - * using the ARB grammar if the string starts with "!!ARB" or if - * NV_vertex_program is not supported. - */ - if (target == GL_VERTEX_PROGRAM_ARB - && ctx->Extensions.ARB_vertex_program - && ((strncmp(string, "!!ARB", 5) == 0) - || !ctx->Extensions.NV_vertex_program)) { - struct gl_vertex_program *prog = ctx->VertexProgram.Current; - _mesa_parse_arb_vertex_program(ctx, target, string, len, prog); - - base = & prog->Base; - } - else if ((target == GL_VERTEX_PROGRAM_ARB - || target == GL_VERTEX_STATE_PROGRAM_NV) - && ctx->Extensions.NV_vertex_program) { - struct gl_vertex_program *prog = ctx->VertexProgram.Current; - _mesa_parse_nv_vertex_program(ctx, target, string, len, prog); - - base = & prog->Base; - } - else if (target == GL_FRAGMENT_PROGRAM_ARB - && ctx->Extensions.ARB_fragment_program) { - struct gl_fragment_program *prog = ctx->FragmentProgram.Current; - _mesa_parse_arb_fragment_program(ctx, target, string, len, prog); - - base = & prog->Base; - } - else if (target == GL_FRAGMENT_PROGRAM_NV - && ctx->Extensions.NV_fragment_program) { - struct gl_fragment_program *prog = ctx->FragmentProgram.Current; - _mesa_parse_nv_fragment_program(ctx, target, string, len, prog); - - base = & prog->Base; - } - else { - _mesa_error(ctx, GL_INVALID_ENUM, "glProgramStringARB(target)"); - return; - } - - if (ctx->Program.ErrorPos == -1) { - /* finally, give the program to the driver for translation/checking */ - if (!ctx->Driver.ProgramStringNotify(ctx, target, base)) { - _mesa_error(ctx, GL_INVALID_OPERATION, - "glProgramStringARB(rejected by driver"); - } - } -} - - -/** - * Set a program env parameter register. - * \note Called from the GL API dispatcher. - * Note, this function is also used by the GL_NV_vertex_program extension - * (alias to ProgramParameterdNV) - */ -void GLAPIENTRY -_mesa_ProgramEnvParameter4dARB(GLenum target, GLuint index, - GLdouble x, GLdouble y, GLdouble z, GLdouble w) -{ - _mesa_ProgramEnvParameter4fARB(target, index, (GLfloat) x, (GLfloat) y, - (GLfloat) z, (GLfloat) w); -} - - -/** - * Set a program env parameter register. - * \note Called from the GL API dispatcher. - * Note, this function is also used by the GL_NV_vertex_program extension - * (alias to ProgramParameterdvNV) - */ -void GLAPIENTRY -_mesa_ProgramEnvParameter4dvARB(GLenum target, GLuint index, - const GLdouble *params) -{ - _mesa_ProgramEnvParameter4fARB(target, index, (GLfloat) params[0], - (GLfloat) params[1], (GLfloat) params[2], - (GLfloat) params[3]); -} - - -/** - * Set a program env parameter register. - * \note Called from the GL API dispatcher. - * Note, this function is also used by the GL_NV_vertex_program extension - * (alias to ProgramParameterfNV) - */ -void GLAPIENTRY -_mesa_ProgramEnvParameter4fARB(GLenum target, GLuint index, - GLfloat x, GLfloat y, GLfloat z, GLfloat w) -{ - GET_CURRENT_CONTEXT(ctx); - ASSERT_OUTSIDE_BEGIN_END(ctx); - - FLUSH_VERTICES(ctx, _NEW_PROGRAM_CONSTANTS); - - if (target == GL_FRAGMENT_PROGRAM_ARB - && ctx->Extensions.ARB_fragment_program) { - if (index >= ctx->Const.FragmentProgram.MaxEnvParams) { - _mesa_error(ctx, GL_INVALID_VALUE, "glProgramEnvParameter(index)"); - return; - } - ASSIGN_4V(ctx->FragmentProgram.Parameters[index], x, y, z, w); - } - else if (target == GL_VERTEX_PROGRAM_ARB /* == GL_VERTEX_PROGRAM_NV */ - && (ctx->Extensions.ARB_vertex_program || ctx->Extensions.NV_vertex_program)) { - if (index >= ctx->Const.VertexProgram.MaxEnvParams) { - _mesa_error(ctx, GL_INVALID_VALUE, "glProgramEnvParameter(index)"); - return; - } - ASSIGN_4V(ctx->VertexProgram.Parameters[index], x, y, z, w); - } - else { - _mesa_error(ctx, GL_INVALID_ENUM, "glProgramEnvParameter(target)"); - return; - } -} - - - -/** - * Set a program env parameter register. - * \note Called from the GL API dispatcher. - * Note, this function is also used by the GL_NV_vertex_program extension - * (alias to ProgramParameterfvNV) - */ -void GLAPIENTRY -_mesa_ProgramEnvParameter4fvARB(GLenum target, GLuint index, - const GLfloat *params) -{ - GET_CURRENT_CONTEXT(ctx); - ASSERT_OUTSIDE_BEGIN_END(ctx); - - FLUSH_VERTICES(ctx, _NEW_PROGRAM_CONSTANTS); - - if (target == GL_FRAGMENT_PROGRAM_ARB - && ctx->Extensions.ARB_fragment_program) { - if (index >= ctx->Const.FragmentProgram.MaxEnvParams) { - _mesa_error(ctx, GL_INVALID_VALUE, "glProgramEnvParameter4fv(index)"); - return; - } - memcpy(ctx->FragmentProgram.Parameters[index], params, - 4 * sizeof(GLfloat)); - } - else if (target == GL_VERTEX_PROGRAM_ARB /* == GL_VERTEX_PROGRAM_NV */ - && (ctx->Extensions.ARB_vertex_program || ctx->Extensions.NV_vertex_program)) { - if (index >= ctx->Const.VertexProgram.MaxEnvParams) { - _mesa_error(ctx, GL_INVALID_VALUE, "glProgramEnvParameter4fv(index)"); - return; - } - memcpy(ctx->VertexProgram.Parameters[index], params, - 4 * sizeof(GLfloat)); - } - else { - _mesa_error(ctx, GL_INVALID_ENUM, "glProgramEnvParameter4fv(target)"); - return; - } -} - - -void GLAPIENTRY -_mesa_ProgramEnvParameters4fvEXT(GLenum target, GLuint index, GLsizei count, - const GLfloat *params) -{ - GET_CURRENT_CONTEXT(ctx); - GLfloat * dest; - ASSERT_OUTSIDE_BEGIN_END(ctx); - - FLUSH_VERTICES(ctx, _NEW_PROGRAM_CONSTANTS); - - if (count <= 0) { - _mesa_error(ctx, GL_INVALID_VALUE, "glProgramEnvParameters4fv(count)"); - } - - if (target == GL_FRAGMENT_PROGRAM_ARB - && ctx->Extensions.ARB_fragment_program) { - if ((index + count) > ctx->Const.FragmentProgram.MaxEnvParams) { - _mesa_error(ctx, GL_INVALID_VALUE, "glProgramEnvParameters4fv(index + count)"); - return; - } - dest = ctx->FragmentProgram.Parameters[index]; - } - else if (target == GL_VERTEX_PROGRAM_ARB - && ctx->Extensions.ARB_vertex_program) { - if ((index + count) > ctx->Const.VertexProgram.MaxEnvParams) { - _mesa_error(ctx, GL_INVALID_VALUE, "glProgramEnvParameters4fv(index + count)"); - return; - } - dest = ctx->VertexProgram.Parameters[index]; - } - else { - _mesa_error(ctx, GL_INVALID_ENUM, "glProgramEnvParameters4fv(target)"); - return; - } - - memcpy(dest, params, count * 4 * sizeof(GLfloat)); -} - - -void GLAPIENTRY -_mesa_GetProgramEnvParameterdvARB(GLenum target, GLuint index, - GLdouble *params) -{ - GET_CURRENT_CONTEXT(ctx); - GLfloat fparams[4]; - - _mesa_GetProgramEnvParameterfvARB(target, index, fparams); - if (ctx->ErrorValue == GL_NO_ERROR) { - params[0] = fparams[0]; - params[1] = fparams[1]; - params[2] = fparams[2]; - params[3] = fparams[3]; - } -} - - -void GLAPIENTRY -_mesa_GetProgramEnvParameterfvARB(GLenum target, GLuint index, - GLfloat *params) -{ - GET_CURRENT_CONTEXT(ctx); - - ASSERT_OUTSIDE_BEGIN_END(ctx); - - if (target == GL_FRAGMENT_PROGRAM_ARB - && ctx->Extensions.ARB_fragment_program) { - if (index >= ctx->Const.FragmentProgram.MaxEnvParams) { - _mesa_error(ctx, GL_INVALID_VALUE, "glGetProgramEnvParameter(index)"); - return; - } - COPY_4V(params, ctx->FragmentProgram.Parameters[index]); - } - else if (target == GL_VERTEX_PROGRAM_ARB - && ctx->Extensions.ARB_vertex_program) { - if (index >= ctx->Const.VertexProgram.MaxEnvParams) { - _mesa_error(ctx, GL_INVALID_VALUE, "glGetProgramEnvParameter(index)"); - return; - } - COPY_4V(params, ctx->VertexProgram.Parameters[index]); - } - else { - _mesa_error(ctx, GL_INVALID_ENUM, "glGetProgramEnvParameter(target)"); - return; - } -} - - -/** - * Note, this function is also used by the GL_NV_fragment_program extension. - */ -void GLAPIENTRY -_mesa_ProgramLocalParameter4fARB(GLenum target, GLuint index, - GLfloat x, GLfloat y, GLfloat z, GLfloat w) -{ - GET_CURRENT_CONTEXT(ctx); - struct gl_program *prog; - ASSERT_OUTSIDE_BEGIN_END(ctx); - - FLUSH_VERTICES(ctx, _NEW_PROGRAM_CONSTANTS); - - if ((target == GL_FRAGMENT_PROGRAM_NV - && ctx->Extensions.NV_fragment_program) || - (target == GL_FRAGMENT_PROGRAM_ARB - && ctx->Extensions.ARB_fragment_program)) { - if (index >= ctx->Const.FragmentProgram.MaxLocalParams) { - _mesa_error(ctx, GL_INVALID_VALUE, "glProgramLocalParameterARB"); - return; - } - prog = &(ctx->FragmentProgram.Current->Base); - } - else if (target == GL_VERTEX_PROGRAM_ARB - && ctx->Extensions.ARB_vertex_program) { - if (index >= ctx->Const.VertexProgram.MaxLocalParams) { - _mesa_error(ctx, GL_INVALID_VALUE, "glProgramLocalParameterARB"); - return; - } - prog = &(ctx->VertexProgram.Current->Base); - } - else { - _mesa_error(ctx, GL_INVALID_ENUM, "glProgramLocalParameterARB"); - return; - } - - ASSERT(index < MAX_PROGRAM_LOCAL_PARAMS); - prog->LocalParams[index][0] = x; - prog->LocalParams[index][1] = y; - prog->LocalParams[index][2] = z; - prog->LocalParams[index][3] = w; -} - - -/** - * Note, this function is also used by the GL_NV_fragment_program extension. - */ -void GLAPIENTRY -_mesa_ProgramLocalParameter4fvARB(GLenum target, GLuint index, - const GLfloat *params) -{ - _mesa_ProgramLocalParameter4fARB(target, index, params[0], params[1], - params[2], params[3]); -} - - -void GLAPIENTRY -_mesa_ProgramLocalParameters4fvEXT(GLenum target, GLuint index, GLsizei count, - const GLfloat *params) -{ - GET_CURRENT_CONTEXT(ctx); - GLfloat *dest; - ASSERT_OUTSIDE_BEGIN_END(ctx); - - FLUSH_VERTICES(ctx, _NEW_PROGRAM_CONSTANTS); - - if (count <= 0) { - _mesa_error(ctx, GL_INVALID_VALUE, "glProgramLocalParameters4fv(count)"); - } - - if (target == GL_FRAGMENT_PROGRAM_ARB - && ctx->Extensions.ARB_fragment_program) { - if ((index + count) > ctx->Const.FragmentProgram.MaxLocalParams) { - _mesa_error(ctx, GL_INVALID_VALUE, "glProgramLocalParameters4fvEXT(index + count)"); - return; - } - dest = ctx->FragmentProgram.Current->Base.LocalParams[index]; - } - else if (target == GL_VERTEX_PROGRAM_ARB - && ctx->Extensions.ARB_vertex_program) { - if ((index + count) > ctx->Const.VertexProgram.MaxLocalParams) { - _mesa_error(ctx, GL_INVALID_VALUE, "glProgramLocalParameters4fvEXT(index + count)"); - return; - } - dest = ctx->VertexProgram.Current->Base.LocalParams[index]; - } - else { - _mesa_error(ctx, GL_INVALID_ENUM, "glProgramLocalParameters4fvEXT(target)"); - return; - } - - memcpy(dest, params, count * 4 * sizeof(GLfloat)); -} - - -/** - * Note, this function is also used by the GL_NV_fragment_program extension. - */ -void GLAPIENTRY -_mesa_ProgramLocalParameter4dARB(GLenum target, GLuint index, - GLdouble x, GLdouble y, - GLdouble z, GLdouble w) -{ - _mesa_ProgramLocalParameter4fARB(target, index, (GLfloat) x, (GLfloat) y, - (GLfloat) z, (GLfloat) w); -} - - -/** - * Note, this function is also used by the GL_NV_fragment_program extension. - */ -void GLAPIENTRY -_mesa_ProgramLocalParameter4dvARB(GLenum target, GLuint index, - const GLdouble *params) -{ - _mesa_ProgramLocalParameter4fARB(target, index, - (GLfloat) params[0], (GLfloat) params[1], - (GLfloat) params[2], (GLfloat) params[3]); -} - - -/** - * Note, this function is also used by the GL_NV_fragment_program extension. - */ -void GLAPIENTRY -_mesa_GetProgramLocalParameterfvARB(GLenum target, GLuint index, - GLfloat *params) -{ - const struct gl_program *prog; - GLuint maxParams; - GET_CURRENT_CONTEXT(ctx); - ASSERT_OUTSIDE_BEGIN_END(ctx); - - if (target == GL_VERTEX_PROGRAM_ARB - && ctx->Extensions.ARB_vertex_program) { - prog = &(ctx->VertexProgram.Current->Base); - maxParams = ctx->Const.VertexProgram.MaxLocalParams; - } - else if (target == GL_FRAGMENT_PROGRAM_ARB - && ctx->Extensions.ARB_fragment_program) { - prog = &(ctx->FragmentProgram.Current->Base); - maxParams = ctx->Const.FragmentProgram.MaxLocalParams; - } - else if (target == GL_FRAGMENT_PROGRAM_NV - && ctx->Extensions.NV_fragment_program) { - prog = &(ctx->FragmentProgram.Current->Base); - maxParams = MAX_NV_FRAGMENT_PROGRAM_PARAMS; - } - else { - _mesa_error(ctx, GL_INVALID_ENUM, - "glGetProgramLocalParameterARB(target)"); - return; - } - - if (index >= maxParams) { - _mesa_error(ctx, GL_INVALID_VALUE, - "glGetProgramLocalParameterARB(index)"); - return; - } - - ASSERT(prog); - ASSERT(index < MAX_PROGRAM_LOCAL_PARAMS); - COPY_4V(params, prog->LocalParams[index]); -} - - -/** - * Note, this function is also used by the GL_NV_fragment_program extension. - */ -void GLAPIENTRY -_mesa_GetProgramLocalParameterdvARB(GLenum target, GLuint index, - GLdouble *params) -{ - GET_CURRENT_CONTEXT(ctx); - GLfloat floatParams[4]; - ASSIGN_4V(floatParams, 0.0F, 0.0F, 0.0F, 0.0F); - _mesa_GetProgramLocalParameterfvARB(target, index, floatParams); - if (ctx->ErrorValue == GL_NO_ERROR) { - COPY_4V(params, floatParams); - } -} - - -void GLAPIENTRY -_mesa_GetProgramivARB(GLenum target, GLenum pname, GLint *params) -{ - const struct gl_program_constants *limits; - struct gl_program *prog; - GET_CURRENT_CONTEXT(ctx); - - ASSERT_OUTSIDE_BEGIN_END(ctx); - - if (target == GL_VERTEX_PROGRAM_ARB - && ctx->Extensions.ARB_vertex_program) { - prog = &(ctx->VertexProgram.Current->Base); - limits = &ctx->Const.VertexProgram; - } - else if (target == GL_FRAGMENT_PROGRAM_ARB - && ctx->Extensions.ARB_fragment_program) { - prog = &(ctx->FragmentProgram.Current->Base); - limits = &ctx->Const.FragmentProgram; - } - else { - _mesa_error(ctx, GL_INVALID_ENUM, "glGetProgramivARB(target)"); - return; - } - - ASSERT(prog); - ASSERT(limits); - - /* Queries supported for both vertex and fragment programs */ - switch (pname) { - case GL_PROGRAM_LENGTH_ARB: - *params - = prog->String ? (GLint) strlen((char *) prog->String) : 0; - return; - case GL_PROGRAM_FORMAT_ARB: - *params = prog->Format; - return; - case GL_PROGRAM_BINDING_ARB: - *params = prog->Id; - return; - case GL_PROGRAM_INSTRUCTIONS_ARB: - *params = prog->NumInstructions; - return; - case GL_MAX_PROGRAM_INSTRUCTIONS_ARB: - *params = limits->MaxInstructions; - return; - case GL_PROGRAM_NATIVE_INSTRUCTIONS_ARB: - *params = prog->NumNativeInstructions; - return; - case GL_MAX_PROGRAM_NATIVE_INSTRUCTIONS_ARB: - *params = limits->MaxNativeInstructions; - return; - case GL_PROGRAM_TEMPORARIES_ARB: - *params = prog->NumTemporaries; - return; - case GL_MAX_PROGRAM_TEMPORARIES_ARB: - *params = limits->MaxTemps; - return; - case GL_PROGRAM_NATIVE_TEMPORARIES_ARB: - *params = prog->NumNativeTemporaries; - return; - case GL_MAX_PROGRAM_NATIVE_TEMPORARIES_ARB: - *params = limits->MaxNativeTemps; - return; - case GL_PROGRAM_PARAMETERS_ARB: - *params = prog->NumParameters; - return; - case GL_MAX_PROGRAM_PARAMETERS_ARB: - *params = limits->MaxParameters; - return; - case GL_PROGRAM_NATIVE_PARAMETERS_ARB: - *params = prog->NumNativeParameters; - return; - case GL_MAX_PROGRAM_NATIVE_PARAMETERS_ARB: - *params = limits->MaxNativeParameters; - return; - case GL_PROGRAM_ATTRIBS_ARB: - *params = prog->NumAttributes; - return; - case GL_MAX_PROGRAM_ATTRIBS_ARB: - *params = limits->MaxAttribs; - return; - case GL_PROGRAM_NATIVE_ATTRIBS_ARB: - *params = prog->NumNativeAttributes; - return; - case GL_MAX_PROGRAM_NATIVE_ATTRIBS_ARB: - *params = limits->MaxNativeAttribs; - return; - case GL_PROGRAM_ADDRESS_REGISTERS_ARB: - *params = prog->NumAddressRegs; - return; - case GL_MAX_PROGRAM_ADDRESS_REGISTERS_ARB: - *params = limits->MaxAddressRegs; - return; - case GL_PROGRAM_NATIVE_ADDRESS_REGISTERS_ARB: - *params = prog->NumNativeAddressRegs; - return; - case GL_MAX_PROGRAM_NATIVE_ADDRESS_REGISTERS_ARB: - *params = limits->MaxNativeAddressRegs; - return; - case GL_MAX_PROGRAM_LOCAL_PARAMETERS_ARB: - *params = limits->MaxLocalParams; - return; - case GL_MAX_PROGRAM_ENV_PARAMETERS_ARB: - *params = limits->MaxEnvParams; - return; - case GL_PROGRAM_UNDER_NATIVE_LIMITS_ARB: - /* - * XXX we may not really need a driver callback here. - * If the number of native instructions, registers, etc. used - * are all below the maximums, we could return true. - * The spec says that even if this query returns true, there's - * no guarantee that the program will run in hardware. - */ - if (prog->Id == 0) { - /* default/null program */ - *params = GL_FALSE; - } - else if (ctx->Driver.IsProgramNative) { - /* ask the driver */ - *params = ctx->Driver.IsProgramNative( ctx, target, prog ); - } - else { - /* probably running in software */ - *params = GL_TRUE; - } - return; - default: - /* continue with fragment-program only queries below */ - break; - } - - /* - * The following apply to fragment programs only (at this time) - */ - if (target == GL_FRAGMENT_PROGRAM_ARB) { - const struct gl_fragment_program *fp = ctx->FragmentProgram.Current; - switch (pname) { - case GL_PROGRAM_ALU_INSTRUCTIONS_ARB: - *params = fp->Base.NumNativeAluInstructions; - return; - case GL_PROGRAM_NATIVE_ALU_INSTRUCTIONS_ARB: - *params = fp->Base.NumAluInstructions; - return; - case GL_PROGRAM_TEX_INSTRUCTIONS_ARB: - *params = fp->Base.NumTexInstructions; - return; - case GL_PROGRAM_NATIVE_TEX_INSTRUCTIONS_ARB: - *params = fp->Base.NumNativeTexInstructions; - return; - case GL_PROGRAM_TEX_INDIRECTIONS_ARB: - *params = fp->Base.NumTexIndirections; - return; - case GL_PROGRAM_NATIVE_TEX_INDIRECTIONS_ARB: - *params = fp->Base.NumNativeTexIndirections; - return; - case GL_MAX_PROGRAM_ALU_INSTRUCTIONS_ARB: - *params = limits->MaxAluInstructions; - return; - case GL_MAX_PROGRAM_NATIVE_ALU_INSTRUCTIONS_ARB: - *params = limits->MaxNativeAluInstructions; - return; - case GL_MAX_PROGRAM_TEX_INSTRUCTIONS_ARB: - *params = limits->MaxTexInstructions; - return; - case GL_MAX_PROGRAM_NATIVE_TEX_INSTRUCTIONS_ARB: - *params = limits->MaxNativeTexInstructions; - return; - case GL_MAX_PROGRAM_TEX_INDIRECTIONS_ARB: - *params = limits->MaxTexIndirections; - return; - case GL_MAX_PROGRAM_NATIVE_TEX_INDIRECTIONS_ARB: - *params = limits->MaxNativeTexIndirections; - return; - default: - _mesa_error(ctx, GL_INVALID_ENUM, "glGetProgramivARB(pname)"); - return; - } - } else { - _mesa_error(ctx, GL_INVALID_ENUM, "glGetProgramivARB(pname)"); - return; - } -} - - -void GLAPIENTRY -_mesa_GetProgramStringARB(GLenum target, GLenum pname, GLvoid *string) -{ - const struct gl_program *prog; - char *dst = (char *) string; - GET_CURRENT_CONTEXT(ctx); - - ASSERT_OUTSIDE_BEGIN_END(ctx); - - if (target == GL_VERTEX_PROGRAM_ARB) { - prog = &(ctx->VertexProgram.Current->Base); - } - else if (target == GL_FRAGMENT_PROGRAM_ARB) { - prog = &(ctx->FragmentProgram.Current->Base); - } - else { - _mesa_error(ctx, GL_INVALID_ENUM, "glGetProgramStringARB(target)"); - return; - } - - ASSERT(prog); - - if (pname != GL_PROGRAM_STRING_ARB) { - _mesa_error(ctx, GL_INVALID_ENUM, "glGetProgramStringARB(pname)"); - return; - } - - if (prog->String) - memcpy(dst, prog->String, strlen((char *) prog->String)); - else - *dst = '\0'; -} diff --git a/mesalib/src/mesa/shader/arbprogram.h b/mesalib/src/mesa/shader/arbprogram.h deleted file mode 100644 index 6fe76267b..000000000 --- a/mesalib/src/mesa/shader/arbprogram.h +++ /dev/null @@ -1,152 +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. - */ - - -#ifndef ARBPROGRAM_H -#define ARBPROGRAM_H - - -extern void GLAPIENTRY -_mesa_BindProgram(GLenum target, GLuint id); - -extern void GLAPIENTRY -_mesa_DeletePrograms(GLsizei n, const GLuint *ids); - -extern void GLAPIENTRY -_mesa_GenPrograms(GLsizei n, GLuint *ids); - - -extern void GLAPIENTRY -_mesa_EnableVertexAttribArrayARB(GLuint index); - - -extern void GLAPIENTRY -_mesa_DisableVertexAttribArrayARB(GLuint index); - - -extern void GLAPIENTRY -_mesa_GetVertexAttribdvARB(GLuint index, GLenum pname, GLdouble *params); - - -extern void GLAPIENTRY -_mesa_GetVertexAttribfvARB(GLuint index, GLenum pname, GLfloat *params); - - -extern void GLAPIENTRY -_mesa_GetVertexAttribivARB(GLuint index, GLenum pname, GLint *params); - - -extern void GLAPIENTRY -_mesa_GetVertexAttribPointervARB(GLuint index, GLenum pname, GLvoid **pointer); - - -extern GLboolean GLAPIENTRY -_mesa_IsProgramARB(GLuint id); - - -extern void GLAPIENTRY -_mesa_ProgramStringARB(GLenum target, GLenum format, GLsizei len, - const GLvoid *string); - - -extern void GLAPIENTRY -_mesa_ProgramEnvParameter4dARB(GLenum target, GLuint index, - GLdouble x, GLdouble y, GLdouble z, GLdouble w); - - -extern void GLAPIENTRY -_mesa_ProgramEnvParameter4dvARB(GLenum target, GLuint index, - const GLdouble *params); - - -extern void GLAPIENTRY -_mesa_ProgramEnvParameter4fARB(GLenum target, GLuint index, - GLfloat x, GLfloat y, GLfloat z, GLfloat w); - - -extern void GLAPIENTRY -_mesa_ProgramEnvParameter4fvARB(GLenum target, GLuint index, - const GLfloat *params); - - -extern void GLAPIENTRY -_mesa_ProgramEnvParameters4fvEXT(GLenum target, GLuint index, GLsizei count, - const GLfloat *params); - - -extern void GLAPIENTRY -_mesa_ProgramLocalParameter4dARB(GLenum target, GLuint index, - GLdouble x, GLdouble y, - GLdouble z, GLdouble w); - - -extern void GLAPIENTRY -_mesa_ProgramLocalParameter4dvARB(GLenum target, GLuint index, - const GLdouble *params); - - -extern void GLAPIENTRY -_mesa_ProgramLocalParameter4fARB(GLenum target, GLuint index, - GLfloat x, GLfloat y, GLfloat z, GLfloat w); - - -extern void GLAPIENTRY -_mesa_ProgramLocalParameter4fvARB(GLenum target, GLuint index, - const GLfloat *params); - - -extern void GLAPIENTRY -_mesa_ProgramLocalParameters4fvEXT(GLenum target, GLuint index, GLsizei count, - const GLfloat *params); - - -extern void GLAPIENTRY -_mesa_GetProgramEnvParameterdvARB(GLenum target, GLuint index, - GLdouble *params); - - -extern void GLAPIENTRY -_mesa_GetProgramEnvParameterfvARB(GLenum target, GLuint index, - GLfloat *params); - - -extern void GLAPIENTRY -_mesa_GetProgramLocalParameterdvARB(GLenum target, GLuint index, - GLdouble *params); - - -extern void GLAPIENTRY -_mesa_GetProgramLocalParameterfvARB(GLenum target, GLuint index, - GLfloat *params); - - -extern void GLAPIENTRY -_mesa_GetProgramivARB(GLenum target, GLenum pname, GLint *params); - - -extern void GLAPIENTRY -_mesa_GetProgramStringARB(GLenum target, GLenum pname, GLvoid *string); - - -#endif diff --git a/mesalib/src/mesa/shader/atifragshader.c b/mesalib/src/mesa/shader/atifragshader.c deleted file mode 100644 index 870f77e30..000000000 --- a/mesalib/src/mesa/shader/atifragshader.c +++ /dev/null @@ -1,769 +0,0 @@ -/** - * \file atifragshader.c - * \author David Airlie - * Copyright (C) 2004 David Airlie 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 - * DAVID AIRLIE 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 "main/glheader.h" -#include "main/context.h" -#include "main/hash.h" -#include "main/imports.h" -#include "main/macros.h" -#include "main/enums.h" -#include "main/mtypes.h" -#include "atifragshader.h" - -#define MESA_DEBUG_ATI_FS 0 - -static struct ati_fragment_shader DummyShader; - - -/** - * Allocate and initialize a new ATI fragment shader object. - */ -struct ati_fragment_shader * -_mesa_new_ati_fragment_shader(GLcontext *ctx, GLuint id) -{ - struct ati_fragment_shader *s = CALLOC_STRUCT(ati_fragment_shader); - (void) ctx; - if (s) { - s->Id = id; - s->RefCount = 1; - } - return s; -} - - -/** - * Delete the given ati fragment shader - */ -void -_mesa_delete_ati_fragment_shader(GLcontext *ctx, struct ati_fragment_shader *s) -{ - GLuint i; - for (i = 0; i < MAX_NUM_PASSES_ATI; i++) { - if (s->Instructions[i]) - free(s->Instructions[i]); - if (s->SetupInst[i]) - free(s->SetupInst[i]); - } - free(s); -} - - - -static void -new_arith_inst(struct ati_fragment_shader *prog) -{ -/* set "default" instruction as not all may get defined. - there is no specified way to express a nop with ati fragment shaders we use - GL_NONE as the op enum and just set some params to 0 - so nothing to do here */ - prog->numArithInstr[prog->cur_pass >> 1]++; -} - -static void -new_tex_inst(struct ati_fragment_shader *prog) -{ -} - -static void match_pair_inst(struct ati_fragment_shader *curProg, GLuint optype) -{ - if (optype == curProg->last_optype) { - curProg->last_optype = 1; - } -} - -#if MESA_DEBUG_ATI_FS -static char * -create_dst_mod_str(GLuint mod) -{ - static char ret_str[1024]; - - memset(ret_str, 0, 1024); - if (mod & GL_2X_BIT_ATI) - strncat(ret_str, "|2X", 1024); - - if (mod & GL_4X_BIT_ATI) - strncat(ret_str, "|4X", 1024); - - if (mod & GL_8X_BIT_ATI) - strncat(ret_str, "|8X", 1024); - if (mod & GL_HALF_BIT_ATI) - strncat(ret_str, "|HA", 1024); - if (mod & GL_QUARTER_BIT_ATI) - strncat(ret_str, "|QU", 1024); - if (mod & GL_EIGHTH_BIT_ATI) - strncat(ret_str, "|EI", 1024); - - if (mod & GL_SATURATE_BIT_ATI) - strncat(ret_str, "|SAT", 1024); - - if (strlen(ret_str) == 0) - strncat(ret_str, "NONE", 1024); - return ret_str; -} - -static char *atifs_ops[] = {"ColorFragmentOp1ATI", "ColorFragmentOp2ATI", "ColorFragmentOp3ATI", - "AlphaFragmentOp1ATI", "AlphaFragmentOp2ATI", "AlphaFragmentOp3ATI" }; - -static void debug_op(GLint optype, GLuint arg_count, GLenum op, GLuint dst, - GLuint dstMask, GLuint dstMod, GLuint arg1, - GLuint arg1Rep, GLuint arg1Mod, GLuint arg2, - GLuint arg2Rep, GLuint arg2Mod, GLuint arg3, - GLuint arg3Rep, GLuint arg3Mod) -{ - char *op_name; - - op_name = atifs_ops[(arg_count-1)+(optype?3:0)]; - - fprintf(stderr, "%s(%s, %s", op_name, _mesa_lookup_enum_by_nr(op), - _mesa_lookup_enum_by_nr(dst)); - if (!optype) - fprintf(stderr, ", %d", dstMask); - - fprintf(stderr, ", %s", create_dst_mod_str(dstMod)); - - fprintf(stderr, ", %s, %s, %d", _mesa_lookup_enum_by_nr(arg1), - _mesa_lookup_enum_by_nr(arg1Rep), arg1Mod); - if (arg_count>1) - fprintf(stderr, ", %s, %s, %d", _mesa_lookup_enum_by_nr(arg2), - _mesa_lookup_enum_by_nr(arg2Rep), arg2Mod); - if (arg_count>2) - fprintf(stderr, ", %s, %s, %d", _mesa_lookup_enum_by_nr(arg3), - _mesa_lookup_enum_by_nr(arg3Rep), arg3Mod); - - fprintf(stderr,")\n"); - -} -#endif - -static int check_arith_arg(struct ati_fragment_shader *curProg, - GLuint optype, GLuint arg, GLuint argRep) -{ - GET_CURRENT_CONTEXT(ctx); - - if (((arg < GL_CON_0_ATI) || (arg > GL_CON_7_ATI)) && - ((arg < GL_REG_0_ATI) || (arg > GL_REG_5_ATI)) && - (arg != GL_ZERO) && (arg != GL_ONE) && - (arg != GL_PRIMARY_COLOR_ARB) && (arg != GL_SECONDARY_INTERPOLATOR_ATI)) { - _mesa_error(ctx, GL_INVALID_ENUM, "C/AFragmentOpATI(arg)"); - return 0; - } - if ((arg == GL_SECONDARY_INTERPOLATOR_ATI) && (((optype == 0) && (argRep == GL_ALPHA)) || - ((optype == 1) && ((arg == GL_ALPHA) || (argRep == GL_NONE))))) { - _mesa_error(ctx, GL_INVALID_OPERATION, "C/AFragmentOpATI(sec_interp)"); - return 0; - } - if ((arg == GL_SECONDARY_INTERPOLATOR_ATI) && (((optype == 0) && (argRep == GL_ALPHA)) || - ((optype == 1) && ((arg == GL_ALPHA) || (argRep == GL_NONE))))) { - _mesa_error(ctx, GL_INVALID_OPERATION, "C/AFragmentOpATI(sec_interp)"); - return 0; - } - if ((curProg->cur_pass == 1) && - ((arg == GL_PRIMARY_COLOR_ARB) || (arg == GL_SECONDARY_INTERPOLATOR_ATI))) { - curProg->interpinp1 = GL_TRUE; - } - return 1; -} - -GLuint GLAPIENTRY -_mesa_GenFragmentShadersATI(GLuint range) -{ - GLuint first; - GLuint i; - GET_CURRENT_CONTEXT(ctx); - - if (range == 0) { - _mesa_error(ctx, GL_INVALID_VALUE, "glGenFragmentShadersATI(range)"); - return 0; - } - - if (ctx->ATIFragmentShader.Compiling) { - _mesa_error(ctx, GL_INVALID_OPERATION, "glGenFragmentShadersATI(insideShader)"); - return 0; - } - - first = _mesa_HashFindFreeKeyBlock(ctx->Shared->ATIShaders, range); - for (i = 0; i < range; i++) { - _mesa_HashInsert(ctx->Shared->ATIShaders, first + i, &DummyShader); - } - - return first; -} - -void GLAPIENTRY -_mesa_BindFragmentShaderATI(GLuint id) -{ - GET_CURRENT_CONTEXT(ctx); - struct ati_fragment_shader *curProg = ctx->ATIFragmentShader.Current; - struct ati_fragment_shader *newProg; - - if (ctx->ATIFragmentShader.Compiling) { - _mesa_error(ctx, GL_INVALID_OPERATION, "glBindFragmentShaderATI(insideShader)"); - return; - } - - FLUSH_VERTICES(ctx, _NEW_PROGRAM); - - if (curProg->Id == id) { - return; - } - - /* unbind current */ - if (curProg->Id != 0) { - curProg->RefCount--; - if (curProg->RefCount <= 0) { - _mesa_HashRemove(ctx->Shared->ATIShaders, id); - } - } - - /* find new shader */ - if (id == 0) { - newProg = ctx->Shared->DefaultFragmentShader; - } - else { - newProg = (struct ati_fragment_shader *) - _mesa_HashLookup(ctx->Shared->ATIShaders, id); - if (!newProg || newProg == &DummyShader) { - /* allocate a new program now */ - newProg = _mesa_new_ati_fragment_shader(ctx, id); - if (!newProg) { - _mesa_error(ctx, GL_OUT_OF_MEMORY, "glBindFragmentShaderATI"); - return; - } - _mesa_HashInsert(ctx->Shared->ATIShaders, id, newProg); - } - - } - - /* do actual bind */ - ctx->ATIFragmentShader.Current = newProg; - - ASSERT(ctx->ATIFragmentShader.Current); - if (newProg) - newProg->RefCount++; - - /*if (ctx->Driver.BindProgram) - ctx->Driver.BindProgram(ctx, target, prog); */ -} - -void GLAPIENTRY -_mesa_DeleteFragmentShaderATI(GLuint id) -{ - GET_CURRENT_CONTEXT(ctx); - - if (ctx->ATIFragmentShader.Compiling) { - _mesa_error(ctx, GL_INVALID_OPERATION, "glDeleteFragmentShaderATI(insideShader)"); - return; - } - - if (id != 0) { - struct ati_fragment_shader *prog = (struct ati_fragment_shader *) - _mesa_HashLookup(ctx->Shared->ATIShaders, id); - if (prog == &DummyShader) { - _mesa_HashRemove(ctx->Shared->ATIShaders, id); - } - else if (prog) { - if (ctx->ATIFragmentShader.Current && - ctx->ATIFragmentShader.Current->Id == id) { - FLUSH_VERTICES(ctx, _NEW_PROGRAM); - _mesa_BindFragmentShaderATI(0); - } - } - - /* The ID is immediately available for re-use now */ - _mesa_HashRemove(ctx->Shared->ATIShaders, id); - if (prog) { - prog->RefCount--; - if (prog->RefCount <= 0) { - free(prog); - } - } - } -} - - -void GLAPIENTRY -_mesa_BeginFragmentShaderATI(void) -{ - GLint i; - GET_CURRENT_CONTEXT(ctx); - - if (ctx->ATIFragmentShader.Compiling) { - _mesa_error(ctx, GL_INVALID_OPERATION, "glBeginFragmentShaderATI(insideShader)"); - return; - } - - FLUSH_VERTICES(ctx, _NEW_PROGRAM); - - /* if the shader was already defined free instructions and get new ones - (or, could use the same mem but would need to reinitialize) */ - /* no idea if it's allowed to redefine a shader */ - for (i = 0; i < MAX_NUM_PASSES_ATI; i++) { - if (ctx->ATIFragmentShader.Current->Instructions[i]) - free(ctx->ATIFragmentShader.Current->Instructions[i]); - if (ctx->ATIFragmentShader.Current->SetupInst[i]) - free(ctx->ATIFragmentShader.Current->SetupInst[i]); - } - - /* malloc the instructions here - not sure if the best place but its - a start */ - for (i = 0; i < MAX_NUM_PASSES_ATI; i++) { - ctx->ATIFragmentShader.Current->Instructions[i] = - (struct atifs_instruction *) - calloc(1, sizeof(struct atifs_instruction) * - (MAX_NUM_INSTRUCTIONS_PER_PASS_ATI)); - ctx->ATIFragmentShader.Current->SetupInst[i] = - (struct atifs_setupinst *) - calloc(1, sizeof(struct atifs_setupinst) * - (MAX_NUM_FRAGMENT_REGISTERS_ATI)); - } - -/* can't rely on calloc for initialization as it's possible to redefine a shader (?) */ - ctx->ATIFragmentShader.Current->LocalConstDef = 0; - ctx->ATIFragmentShader.Current->numArithInstr[0] = 0; - ctx->ATIFragmentShader.Current->numArithInstr[1] = 0; - ctx->ATIFragmentShader.Current->regsAssigned[0] = 0; - ctx->ATIFragmentShader.Current->regsAssigned[1] = 0; - ctx->ATIFragmentShader.Current->NumPasses = 0; - ctx->ATIFragmentShader.Current->cur_pass = 0; - ctx->ATIFragmentShader.Current->last_optype = 0; - ctx->ATIFragmentShader.Current->interpinp1 = GL_FALSE; - ctx->ATIFragmentShader.Current->isValid = GL_FALSE; - ctx->ATIFragmentShader.Current->swizzlerq = 0; - ctx->ATIFragmentShader.Compiling = 1; -} - -void GLAPIENTRY -_mesa_EndFragmentShaderATI(void) -{ - GET_CURRENT_CONTEXT(ctx); - struct ati_fragment_shader *curProg = ctx->ATIFragmentShader.Current; -#if MESA_DEBUG_ATI_FS - GLint i, j; -#endif - - if (!ctx->ATIFragmentShader.Compiling) { - _mesa_error(ctx, GL_INVALID_OPERATION, "glEndFragmentShaderATI(outsideShader)"); - return; - } - if (curProg->interpinp1 && (ctx->ATIFragmentShader.Current->cur_pass > 1)) { - _mesa_error(ctx, GL_INVALID_OPERATION, "glEndFragmentShaderATI(interpinfirstpass)"); - /* according to spec, DON'T return here */ - } - - match_pair_inst(curProg, 0); - ctx->ATIFragmentShader.Compiling = 0; - ctx->ATIFragmentShader.Current->isValid = GL_TRUE; - if ((ctx->ATIFragmentShader.Current->cur_pass == 0) || - (ctx->ATIFragmentShader.Current->cur_pass == 2)) { - _mesa_error(ctx, GL_INVALID_OPERATION, "glEndFragmentShaderATI(noarithinst)"); - } - if (ctx->ATIFragmentShader.Current->cur_pass > 1) - ctx->ATIFragmentShader.Current->NumPasses = 2; - else - ctx->ATIFragmentShader.Current->NumPasses = 1; - - ctx->ATIFragmentShader.Current->cur_pass = 0; - -#if MESA_DEBUG_ATI_FS - for (j = 0; j < MAX_NUM_PASSES_ATI; j++) { - for (i = 0; i < MAX_NUM_FRAGMENT_REGISTERS_ATI; i++) { - GLuint op = curProg->SetupInst[j][i].Opcode; - const char *op_enum = op > 5 ? _mesa_lookup_enum_by_nr(op) : "0"; - GLuint src = curProg->SetupInst[j][i].src; - GLuint swizzle = curProg->SetupInst[j][i].swizzle; - fprintf(stderr, "%2d %04X %s %d %04X\n", i, op, op_enum, src, - swizzle); - } - for (i = 0; i < curProg->numArithInstr[j]; i++) { - GLuint op0 = curProg->Instructions[j][i].Opcode[0]; - GLuint op1 = curProg->Instructions[j][i].Opcode[1]; - const char *op0_enum = op0 > 5 ? _mesa_lookup_enum_by_nr(op0) : "0"; - const char *op1_enum = op1 > 5 ? _mesa_lookup_enum_by_nr(op1) : "0"; - GLuint count0 = curProg->Instructions[j][i].ArgCount[0]; - GLuint count1 = curProg->Instructions[j][i].ArgCount[1]; - fprintf(stderr, "%2d %04X %s %d %04X %s %d\n", i, op0, op0_enum, count0, - op1, op1_enum, count1); - } - } -#endif - - if (!ctx->Driver.ProgramStringNotify(ctx, GL_FRAGMENT_SHADER_ATI, NULL)) { - ctx->ATIFragmentShader.Current->isValid = GL_FALSE; - /* XXX is this the right error? */ - _mesa_error(ctx, GL_INVALID_OPERATION, - "glEndFragmentShaderATI(driver rejected shader)"); - } -} - -void GLAPIENTRY -_mesa_PassTexCoordATI(GLuint dst, GLuint coord, GLenum swizzle) -{ - GET_CURRENT_CONTEXT(ctx); - struct ati_fragment_shader *curProg = ctx->ATIFragmentShader.Current; - struct atifs_setupinst *curI; - - if (!ctx->ATIFragmentShader.Compiling) { - _mesa_error(ctx, GL_INVALID_OPERATION, "glPassTexCoordATI(outsideShader)"); - return; - } - - if (curProg->cur_pass == 1) { - match_pair_inst(curProg, 0); - curProg->cur_pass = 2; - } - if ((curProg->cur_pass > 2) || - ((1 << (dst - GL_REG_0_ATI)) & curProg->regsAssigned[curProg->cur_pass >> 1])) { - _mesa_error(ctx, GL_INVALID_OPERATION, "glPassTexCoord(pass)"); - return; - } - if ((dst < GL_REG_0_ATI) || (dst > GL_REG_5_ATI) || - ((dst - GL_REG_0_ATI) >= ctx->Const.MaxTextureUnits)) { - _mesa_error(ctx, GL_INVALID_ENUM, "glPassTexCoordATI(dst)"); - return; - } - if (((coord < GL_REG_0_ATI) || (coord > GL_REG_5_ATI)) && - ((coord < GL_TEXTURE0_ARB) || (coord > GL_TEXTURE7_ARB) || - ((coord - GL_TEXTURE0_ARB) >= ctx->Const.MaxTextureUnits))) { - _mesa_error(ctx, GL_INVALID_ENUM, "glPassTexCoordATI(coord)"); - return; - } - if ((curProg->cur_pass == 0) && (coord >= GL_REG_0_ATI)) { - _mesa_error(ctx, GL_INVALID_OPERATION, "glPassTexCoordATI(coord)"); - return; - } - if (!(swizzle >= GL_SWIZZLE_STR_ATI) && (swizzle <= GL_SWIZZLE_STQ_DQ_ATI)) { - _mesa_error(ctx, GL_INVALID_ENUM, "glPassTexCoordATI(swizzle)"); - return; - } - if ((swizzle & 1) && (coord >= GL_REG_0_ATI)) { - _mesa_error(ctx, GL_INVALID_OPERATION, "glPassTexCoordATI(swizzle)"); - return; - } - if (coord <= GL_TEXTURE7_ARB) { - GLuint tmp = coord - GL_TEXTURE0_ARB; - if ((((curProg->swizzlerq >> (tmp * 2)) & 3) != 0) && - (((swizzle & 1) + 1) != ((curProg->swizzlerq >> (tmp * 2)) & 3))) { - _mesa_error(ctx, GL_INVALID_OPERATION, "glPassTexCoordATI(swizzle)"); - return; - } else { - curProg->swizzlerq |= (((swizzle & 1) + 1) << (tmp * 2)); - } - } - - curProg->regsAssigned[curProg->cur_pass >> 1] |= 1 << (dst - GL_REG_0_ATI); - new_tex_inst(curProg); - - /* add the instructions */ - curI = &curProg->SetupInst[curProg->cur_pass >> 1][dst - GL_REG_0_ATI]; - - curI->Opcode = ATI_FRAGMENT_SHADER_PASS_OP; - curI->src = coord; - curI->swizzle = swizzle; - -#if MESA_DEBUG_ATI_FS - _mesa_debug(ctx, "%s(%s, %s, %s)\n", __FUNCTION__, - _mesa_lookup_enum_by_nr(dst), _mesa_lookup_enum_by_nr(coord), - _mesa_lookup_enum_by_nr(swizzle)); -#endif -} - -void GLAPIENTRY -_mesa_SampleMapATI(GLuint dst, GLuint interp, GLenum swizzle) -{ - GET_CURRENT_CONTEXT(ctx); - struct ati_fragment_shader *curProg = ctx->ATIFragmentShader.Current; - struct atifs_setupinst *curI; - - if (!ctx->ATIFragmentShader.Compiling) { - _mesa_error(ctx, GL_INVALID_OPERATION, "glSampleMapATI(outsideShader)"); - return; - } - - if (curProg->cur_pass == 1) { - match_pair_inst(curProg, 0); - curProg->cur_pass = 2; - } - if ((curProg->cur_pass > 2) || - ((1 << (dst - GL_REG_0_ATI)) & curProg->regsAssigned[curProg->cur_pass >> 1])) { - _mesa_error(ctx, GL_INVALID_OPERATION, "glSampleMapATI(pass)"); - return; - } - if ((dst < GL_REG_0_ATI) || (dst > GL_REG_5_ATI) || - ((dst - GL_REG_0_ATI) >= ctx->Const.MaxTextureUnits)) { - _mesa_error(ctx, GL_INVALID_ENUM, "glSampleMapATI(dst)"); - return; - } - if (((interp < GL_REG_0_ATI) || (interp > GL_REG_5_ATI)) && - ((interp < GL_TEXTURE0_ARB) || (interp > GL_TEXTURE7_ARB) || - ((interp - GL_TEXTURE0_ARB) >= ctx->Const.MaxTextureUnits))) { - /* is this texture5 or texture7? spec is a bit unclear there */ - _mesa_error(ctx, GL_INVALID_ENUM, "glSampleMapATI(interp)"); - return; - } - if ((curProg->cur_pass == 0) && (interp >= GL_REG_0_ATI)) { - _mesa_error(ctx, GL_INVALID_OPERATION, "glSampleMapATI(interp)"); - return; - } - if (!(swizzle >= GL_SWIZZLE_STR_ATI) && (swizzle <= GL_SWIZZLE_STQ_DQ_ATI)) { - _mesa_error(ctx, GL_INVALID_ENUM, "glSampleMapATI(swizzle)"); - return; - } - if ((swizzle & 1) && (interp >= GL_REG_0_ATI)) { - _mesa_error(ctx, GL_INVALID_OPERATION, "glSampleMapATI(swizzle)"); - return; - } - if (interp <= GL_TEXTURE7_ARB) { - GLuint tmp = interp - GL_TEXTURE0_ARB; - if ((((curProg->swizzlerq >> (tmp * 2)) & 3) != 0) && - (((swizzle & 1) + 1) != ((curProg->swizzlerq >> (tmp * 2)) & 3))) { - _mesa_error(ctx, GL_INVALID_OPERATION, "glSampleMapATI(swizzle)"); - return; - } else { - curProg->swizzlerq |= (((swizzle & 1) + 1) << (tmp * 2)); - } - } - - curProg->regsAssigned[curProg->cur_pass >> 1] |= 1 << (dst - GL_REG_0_ATI); - new_tex_inst(curProg); - - /* add the instructions */ - curI = &curProg->SetupInst[curProg->cur_pass >> 1][dst - GL_REG_0_ATI]; - - curI->Opcode = ATI_FRAGMENT_SHADER_SAMPLE_OP; - curI->src = interp; - curI->swizzle = swizzle; - -#if MESA_DEBUG_ATI_FS - _mesa_debug(ctx, "%s(%s, %s, %s)\n", __FUNCTION__, - _mesa_lookup_enum_by_nr(dst), _mesa_lookup_enum_by_nr(interp), - _mesa_lookup_enum_by_nr(swizzle)); -#endif -} - -static void -_mesa_FragmentOpXATI(GLint optype, GLuint arg_count, GLenum op, GLuint dst, - GLuint dstMask, GLuint dstMod, GLuint arg1, - GLuint arg1Rep, GLuint arg1Mod, GLuint arg2, - GLuint arg2Rep, GLuint arg2Mod, GLuint arg3, - GLuint arg3Rep, GLuint arg3Mod) -{ - GET_CURRENT_CONTEXT(ctx); - struct ati_fragment_shader *curProg = ctx->ATIFragmentShader.Current; - GLint ci; - struct atifs_instruction *curI; - GLuint modtemp = dstMod & ~GL_SATURATE_BIT_ATI; - - if (!ctx->ATIFragmentShader.Compiling) { - _mesa_error(ctx, GL_INVALID_OPERATION, "C/AFragmentOpATI(outsideShader)"); - return; - } - - if (curProg->cur_pass==0) - curProg->cur_pass=1; - - else if (curProg->cur_pass==2) - curProg->cur_pass=3; - - /* decide whether this is a new instruction or not ... all color instructions are new, - and alpha instructions might also be new if there was no preceding color inst */ - if ((optype == 0) || (curProg->last_optype == optype)) { - if (curProg->numArithInstr[curProg->cur_pass >> 1] > 7) { - _mesa_error(ctx, GL_INVALID_OPERATION, "C/AFragmentOpATI(instrCount)"); - return; - } - /* easier to do that here slight side effect invalid instr will still be inserted as nops */ - match_pair_inst(curProg, optype); - new_arith_inst(curProg); - } - curProg->last_optype = optype; - ci = curProg->numArithInstr[curProg->cur_pass >> 1] - 1; - - /* add the instructions */ - curI = &curProg->Instructions[curProg->cur_pass >> 1][ci]; - - /* error checking */ - if ((dst < GL_REG_0_ATI) || (dst > GL_REG_5_ATI)) { - _mesa_error(ctx, GL_INVALID_ENUM, "C/AFragmentOpATI(dst)"); - return; - } - if ((modtemp != GL_NONE) && (modtemp != GL_2X_BIT_ATI) && - (modtemp != GL_4X_BIT_ATI) && (modtemp != GL_8X_BIT_ATI) && - (modtemp != GL_HALF_BIT_ATI) && !(modtemp != GL_QUARTER_BIT_ATI) && - (modtemp != GL_EIGHTH_BIT_ATI)) { - _mesa_error(ctx, GL_INVALID_ENUM, "C/AFragmentOpATI(dstMod)%x", modtemp); - return; - } - /* op checking? Actually looks like that's missing in the spec but we'll do it anyway */ - if (((op < GL_ADD_ATI) || (op > GL_DOT2_ADD_ATI)) && !(op == GL_MOV_ATI)) { - _mesa_error(ctx, GL_INVALID_ENUM, "C/AFragmentOpATI(op)"); - return; - } - if (optype == 1) { - if (((op == GL_DOT2_ADD_ATI) && (curI->Opcode[0] != GL_DOT2_ADD_ATI)) || - ((op == GL_DOT3_ATI) && (curI->Opcode[0] != GL_DOT3_ATI)) || - ((op == GL_DOT4_ATI) && (curI->Opcode[0] != GL_DOT4_ATI)) || - ((op != GL_DOT4_ATI) && (curI->Opcode[0] == GL_DOT4_ATI))) { - _mesa_error(ctx, GL_INVALID_OPERATION, "AFragmentOpATI(op)"); - return; - } - } - if ((op == GL_DOT4_ATI) && - (((arg1 == GL_SECONDARY_INTERPOLATOR_ATI) && ((arg1Rep == GL_ALPHA) || (arg1Rep == GL_NONE))) || - (((arg2 == GL_SECONDARY_INTERPOLATOR_ATI) && ((arg2Rep == GL_ALPHA) || (arg2Rep == GL_NONE)))))) { - _mesa_error(ctx, GL_INVALID_OPERATION, "C/AFragmentOpATI(sec_interp)"); - } - - if (!check_arith_arg(curProg, optype, arg1, arg1Rep)) { - return; - } - if (arg2) { - if (!check_arith_arg(curProg, optype, arg2, arg2Rep)) { - return; - } - } - if (arg3) { - if (!check_arith_arg(curProg, optype, arg3, arg3Rep)) { - return; - } - if ((arg1 >= GL_CON_0_ATI) && (arg1 <= GL_CON_7_ATI) && - (arg2 >= GL_CON_0_ATI) && (arg2 <= GL_CON_7_ATI) && - (arg3 >= GL_CON_0_ATI) && (arg3 <= GL_CON_7_ATI) && - (arg1 != arg2) && (arg1 != arg3) && (arg2 != arg3)) { - _mesa_error(ctx, GL_INVALID_OPERATION, "C/AFragmentOpATI(3Consts)"); - return; - } - } - - /* all ok - not all fully validated though (e.g. argNMod - spec doesn't say anything) */ - - curI->Opcode[optype] = op; - curI->SrcReg[optype][0].Index = arg1; - curI->SrcReg[optype][0].argRep = arg1Rep; - curI->SrcReg[optype][0].argMod = arg1Mod; - curI->ArgCount[optype] = arg_count; - - if (arg2) { - curI->SrcReg[optype][1].Index = arg2; - curI->SrcReg[optype][1].argRep = arg2Rep; - curI->SrcReg[optype][1].argMod = arg2Mod; - } - - if (arg3) { - curI->SrcReg[optype][2].Index = arg3; - curI->SrcReg[optype][2].argRep = arg3Rep; - curI->SrcReg[optype][2].argMod = arg3Mod; - } - - curI->DstReg[optype].Index = dst; - curI->DstReg[optype].dstMod = dstMod; - curI->DstReg[optype].dstMask = dstMask; - -#if MESA_DEBUG_ATI_FS - debug_op(optype, arg_count, op, dst, dstMask, dstMod, arg1, arg1Rep, arg1Mod, arg2, arg2Rep, arg2Mod, arg3, arg3Rep, arg3Mod); -#endif - -} - -void GLAPIENTRY -_mesa_ColorFragmentOp1ATI(GLenum op, GLuint dst, GLuint dstMask, - GLuint dstMod, GLuint arg1, GLuint arg1Rep, - GLuint arg1Mod) -{ - _mesa_FragmentOpXATI(ATI_FRAGMENT_SHADER_COLOR_OP, 1, op, dst, dstMask, - dstMod, arg1, arg1Rep, arg1Mod, 0, 0, 0, 0, 0, 0); -} - -void GLAPIENTRY -_mesa_ColorFragmentOp2ATI(GLenum op, GLuint dst, GLuint dstMask, - GLuint dstMod, GLuint arg1, GLuint arg1Rep, - GLuint arg1Mod, GLuint arg2, GLuint arg2Rep, - GLuint arg2Mod) -{ - _mesa_FragmentOpXATI(ATI_FRAGMENT_SHADER_COLOR_OP, 2, op, dst, dstMask, - dstMod, arg1, arg1Rep, arg1Mod, arg2, arg2Rep, - arg2Mod, 0, 0, 0); -} - -void GLAPIENTRY -_mesa_ColorFragmentOp3ATI(GLenum op, GLuint dst, GLuint dstMask, - GLuint dstMod, GLuint arg1, GLuint arg1Rep, - GLuint arg1Mod, GLuint arg2, GLuint arg2Rep, - GLuint arg2Mod, GLuint arg3, GLuint arg3Rep, - GLuint arg3Mod) -{ - _mesa_FragmentOpXATI(ATI_FRAGMENT_SHADER_COLOR_OP, 3, op, dst, dstMask, - dstMod, arg1, arg1Rep, arg1Mod, arg2, arg2Rep, - arg2Mod, arg3, arg3Rep, arg3Mod); -} - -void GLAPIENTRY -_mesa_AlphaFragmentOp1ATI(GLenum op, GLuint dst, GLuint dstMod, GLuint arg1, - GLuint arg1Rep, GLuint arg1Mod) -{ - _mesa_FragmentOpXATI(ATI_FRAGMENT_SHADER_ALPHA_OP, 1, op, dst, 0, dstMod, - arg1, arg1Rep, arg1Mod, 0, 0, 0, 0, 0, 0); -} - -void GLAPIENTRY -_mesa_AlphaFragmentOp2ATI(GLenum op, GLuint dst, GLuint dstMod, GLuint arg1, - GLuint arg1Rep, GLuint arg1Mod, GLuint arg2, - GLuint arg2Rep, GLuint arg2Mod) -{ - _mesa_FragmentOpXATI(ATI_FRAGMENT_SHADER_ALPHA_OP, 2, op, dst, 0, dstMod, - arg1, arg1Rep, arg1Mod, arg2, arg2Rep, arg2Mod, 0, 0, - 0); -} - -void GLAPIENTRY -_mesa_AlphaFragmentOp3ATI(GLenum op, GLuint dst, GLuint dstMod, GLuint arg1, - GLuint arg1Rep, GLuint arg1Mod, GLuint arg2, - GLuint arg2Rep, GLuint arg2Mod, GLuint arg3, - GLuint arg3Rep, GLuint arg3Mod) -{ - _mesa_FragmentOpXATI(ATI_FRAGMENT_SHADER_ALPHA_OP, 3, op, dst, 0, dstMod, - arg1, arg1Rep, arg1Mod, arg2, arg2Rep, arg2Mod, arg3, - arg3Rep, arg3Mod); -} - -void GLAPIENTRY -_mesa_SetFragmentShaderConstantATI(GLuint dst, const GLfloat * value) -{ - GLuint dstindex; - GET_CURRENT_CONTEXT(ctx); - - if ((dst < GL_CON_0_ATI) || (dst > GL_CON_7_ATI)) { - /* spec says nothing about what should happen here but we can't just segfault...*/ - _mesa_error(ctx, GL_INVALID_ENUM, "glSetFragmentShaderConstantATI(dst)"); - return; - } - - dstindex = dst - GL_CON_0_ATI; - if (ctx->ATIFragmentShader.Compiling) { - struct ati_fragment_shader *curProg = ctx->ATIFragmentShader.Current; - COPY_4V(curProg->Constants[dstindex], value); - curProg->LocalConstDef |= 1 << dstindex; - } - else { - FLUSH_VERTICES(ctx, _NEW_PROGRAM); - COPY_4V(ctx->ATIFragmentShader.GlobalConstants[dstindex], value); - } -} diff --git a/mesalib/src/mesa/shader/atifragshader.h b/mesalib/src/mesa/shader/atifragshader.h deleted file mode 100644 index e1dc20e60..000000000 --- a/mesalib/src/mesa/shader/atifragshader.h +++ /dev/null @@ -1,123 +0,0 @@ -/* - * Mesa 3-D graphics library ATI Fragment Shader - * - * Copyright (C) 2004 David Airlie All Rights Reserved. - * - */ - -#ifndef ATIFRAGSHADER_H -#define ATIFRAGSHADER_H - -#include "main/mtypes.h" - -#define MAX_NUM_INSTRUCTIONS_PER_PASS_ATI 8 -#define MAX_NUM_PASSES_ATI 2 -#define MAX_NUM_FRAGMENT_REGISTERS_ATI 6 - -struct ati_fs_opcode_st -{ - GLenum opcode; - GLint num_src_args; -}; - -extern struct ati_fs_opcode_st ati_fs_opcodes[]; - -struct atifragshader_src_register -{ - GLuint Index; - GLuint argRep; - GLuint argMod; -}; - -struct atifragshader_dst_register -{ - GLuint Index; - GLuint dstMod; - GLuint dstMask; -}; - -#define ATI_FRAGMENT_SHADER_COLOR_OP 0 -#define ATI_FRAGMENT_SHADER_ALPHA_OP 1 -#define ATI_FRAGMENT_SHADER_PASS_OP 2 -#define ATI_FRAGMENT_SHADER_SAMPLE_OP 3 - -/* two opcodes - one for color/one for alpha */ -/* up to three source registers for most ops */ -struct atifs_instruction -{ - GLenum Opcode[2]; - GLuint ArgCount[2]; - struct atifragshader_src_register SrcReg[2][3]; - struct atifragshader_dst_register DstReg[2]; -}; - -/* different from arithmetic shader instruction */ -struct atifs_setupinst -{ - GLenum Opcode; - GLuint src; - GLenum swizzle; -}; - - -extern struct ati_fragment_shader * -_mesa_new_ati_fragment_shader(GLcontext *ctx, GLuint id); - -extern void -_mesa_delete_ati_fragment_shader(GLcontext *ctx, - struct ati_fragment_shader *s); - - -extern GLuint GLAPIENTRY _mesa_GenFragmentShadersATI(GLuint range); - -extern void GLAPIENTRY _mesa_BindFragmentShaderATI(GLuint id); - -extern void GLAPIENTRY _mesa_DeleteFragmentShaderATI(GLuint id); - -extern void GLAPIENTRY _mesa_BeginFragmentShaderATI(void); - -extern void GLAPIENTRY _mesa_EndFragmentShaderATI(void); - -extern void GLAPIENTRY -_mesa_PassTexCoordATI(GLuint dst, GLuint coord, GLenum swizzle); - -extern void GLAPIENTRY -_mesa_SampleMapATI(GLuint dst, GLuint interp, GLenum swizzle); - -extern void GLAPIENTRY -_mesa_ColorFragmentOp1ATI(GLenum op, GLuint dst, GLuint dstMask, - GLuint dstMod, GLuint arg1, GLuint arg1Rep, - GLuint arg1Mod); - -extern void GLAPIENTRY -_mesa_ColorFragmentOp2ATI(GLenum op, GLuint dst, GLuint dstMask, - GLuint dstMod, GLuint arg1, GLuint arg1Rep, - GLuint arg1Mod, GLuint arg2, GLuint arg2Rep, - GLuint arg2Mod); - -extern void GLAPIENTRY -_mesa_ColorFragmentOp3ATI(GLenum op, GLuint dst, GLuint dstMask, - GLuint dstMod, GLuint arg1, GLuint arg1Rep, - GLuint arg1Mod, GLuint arg2, GLuint arg2Rep, - GLuint arg2Mod, GLuint arg3, GLuint arg3Rep, - GLuint arg3Mod); - -extern void GLAPIENTRY -_mesa_AlphaFragmentOp1ATI(GLenum op, GLuint dst, GLuint dstMod, GLuint arg1, - GLuint arg1Rep, GLuint arg1Mod); - -extern void GLAPIENTRY -_mesa_AlphaFragmentOp2ATI(GLenum op, GLuint dst, GLuint dstMod, GLuint arg1, - GLuint arg1Rep, GLuint arg1Mod, GLuint arg2, - GLuint arg2Rep, GLuint arg2Mod); - -extern void GLAPIENTRY -_mesa_AlphaFragmentOp3ATI(GLenum op, GLuint dst, GLuint dstMod, GLuint arg1, - GLuint arg1Rep, GLuint arg1Mod, GLuint arg2, - GLuint arg2Rep, GLuint arg2Mod, GLuint arg3, - GLuint arg3Rep, GLuint arg3Mod); - -extern void GLAPIENTRY -_mesa_SetFragmentShaderConstantATI(GLuint dst, const GLfloat * value); - -#endif diff --git a/mesalib/src/mesa/shader/descrip.mms b/mesalib/src/mesa/shader/descrip.mms deleted file mode 100644 index 59730020d..000000000 --- a/mesalib/src/mesa/shader/descrip.mms +++ /dev/null @@ -1,93 +0,0 @@ -# Makefile for core library for VMS -# contributed by Jouk Jansen joukj@hrem.nano.tudelft.nl -# Last revision : 29 September 2008 -.first - define gl [---.include.gl] - define math [-.math] - define swrast [-.swrast] - define array_cache [-.array_cache] - define glapi [-.glapi] - define main [-.main] - define shader [-.shader] - -.include [---]mms-config. - -##### MACROS ##### - -VPATH = RCS - -INCDIR = [---.include],[-.main],[-.glapi],[.slang] -LIBDIR = [---.lib] -CFLAGS = /include=($(INCDIR),[])/define=(PTHREADS=1,"__extension__=")/name=(as_is,short)/float=ieee/ieee=denorm - -SOURCES = \ - atifragshader.c \ - arbprogparse.c \ - arbprogram.c \ - nvfragparse.c \ - nvprogram.c \ - nvvertparse.c \ - program.c \ - programopt.c \ - prog_debug.c \ - prog_execute.c \ - prog_instruction.c \ - prog_parameter.c \ - prog_print.c \ - prog_cache.c \ - prog_statevars.c \ - shader_api.c prog_uniform.c - -OBJECTS = \ - atifragshader.obj,\ - arbprogparse.obj,\ - arbprogram.obj,\ - nvfragparse.obj,\ - nvprogram.obj,\ - nvvertparse.obj,\ - program.obj,\ - programopt.obj,\ - prog_debug.obj,\ - prog_execute.obj,\ - prog_instruction.obj,\ - prog_parameter.obj,\ - prog_print.obj,\ - prog_statevars.obj,\ - shader_api.obj,prog_uniform.obj,prog_cache.obj - -##### RULES ##### - -VERSION=Mesa V3.4 - -##### TARGETS ##### -all : - $(MMS)$(MMSQUALIFIERS) $(LIBDIR)$(GL_LIB) - set def [.slang] - $(MMS)$(MMSQUALIFIERS) - set def [-] - -# Make the library -$(LIBDIR)$(GL_LIB) : $(OBJECTS) - @ library $(LIBDIR)$(GL_LIB) $(OBJECTS) - -clean : - purge - delete *.obj;* - -atifragshader.obj : atifragshader.c -arbprogparse.obj : arbprogparse.c -arbprogram.obj : arbprogram.c -nvfragparse.obj : nvfragparse.c -nvprogram.obj : nvprogram.c -nvvertparse.obj : nvvertparse.c -program.obj : program.c -programopt. obj : programopt.c -prog_debug.obj : prog_debug.c -prog_execute.obj : prog_execute.c -prog_instruction.obj : prog_instruction.c -prog_parameter.obj : prog_parameter.c -prog_print.obj : prog_print.c -prog_statevars.obj : prog_statevars.c -shader_api.obj : shader_api.c -prog_uniform.obj : prog_uniform.c -prog_cache.obj : prog_cache.c diff --git a/mesalib/src/mesa/shader/hash_table.c b/mesalib/src/mesa/shader/hash_table.c deleted file mode 100644 index fa6ba2bfd..000000000 --- a/mesalib/src/mesa/shader/hash_table.c +++ /dev/null @@ -1,159 +0,0 @@ -/* - * Copyright © 2008 Intel Corporation - * - * 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 (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 NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS 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 hash_table.c - * \brief Implementation of a generic, opaque hash table data type. - * - * \author Ian Romanick <ian.d.romanick@intel.com> - */ - -#include "main/imports.h" -#include "main/simple_list.h" -#include "hash_table.h" - -struct node { - struct node *next; - struct node *prev; -}; - -struct hash_table { - hash_func_t hash; - hash_compare_func_t compare; - - unsigned num_buckets; - struct node buckets[1]; -}; - - -struct hash_node { - struct node link; - const void *key; - void *data; -}; - - -struct hash_table * -hash_table_ctor(unsigned num_buckets, hash_func_t hash, - hash_compare_func_t compare) -{ - struct hash_table *ht; - unsigned i; - - - if (num_buckets < 16) { - num_buckets = 16; - } - - ht = malloc(sizeof(*ht) + ((num_buckets - 1) - * sizeof(ht->buckets[0]))); - if (ht != NULL) { - ht->hash = hash; - ht->compare = compare; - ht->num_buckets = num_buckets; - - for (i = 0; i < num_buckets; i++) { - make_empty_list(& ht->buckets[i]); - } - } - - return ht; -} - - -void -hash_table_dtor(struct hash_table *ht) -{ - hash_table_clear(ht); - free(ht); -} - - -void -hash_table_clear(struct hash_table *ht) -{ - struct node *node; - struct node *temp; - unsigned i; - - - for (i = 0; i < ht->num_buckets; i++) { - foreach_s(node, temp, & ht->buckets[i]) { - remove_from_list(node); - free(node); - } - - assert(is_empty_list(& ht->buckets[i])); - } -} - - -void * -hash_table_find(struct hash_table *ht, const void *key) -{ - const unsigned hash_value = (*ht->hash)(key); - const unsigned bucket = hash_value % ht->num_buckets; - struct node *node; - - foreach(node, & ht->buckets[bucket]) { - struct hash_node *hn = (struct hash_node *) node; - - if ((*ht->compare)(hn->key, key) == 0) { - return hn->data; - } - } - - return NULL; -} - - -void -hash_table_insert(struct hash_table *ht, void *data, const void *key) -{ - const unsigned hash_value = (*ht->hash)(key); - const unsigned bucket = hash_value % ht->num_buckets; - struct hash_node *node; - - node = calloc(1, sizeof(*node)); - - node->data = data; - node->key = key; - - insert_at_head(& ht->buckets[bucket], & node->link); -} - - -unsigned -hash_table_string_hash(const void *key) -{ - const char *str = (const char *) key; - unsigned hash = 5381; - - - while (*str != '\0') { - hash = (hash * 33) + *str; - str++; - } - - return hash; -} diff --git a/mesalib/src/mesa/shader/hash_table.h b/mesalib/src/mesa/shader/hash_table.h deleted file mode 100644 index 7b302f5db..000000000 --- a/mesalib/src/mesa/shader/hash_table.h +++ /dev/null @@ -1,117 +0,0 @@ -/* - * Copyright © 2008 Intel Corporation - * - * 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 (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 NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS 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 hash_table.h - * \brief Implementation of a generic, opaque hash table data type. - * - * \author Ian Romanick <ian.d.romanick@intel.com> - */ - -#ifndef HASH_TABLE_H -#define HASH_TABLE_H - -#include <string.h> - -struct hash_table; - -typedef unsigned (*hash_func_t)(const void *key); -typedef int (*hash_compare_func_t)(const void *key1, const void *key2); - -/** - * Hash table constructor - * - * Creates a hash table with the specified number of buckets. The supplied - * \c hash and \c compare routines are used when adding elements to the table - * and when searching for elements in the table. - * - * \param num_buckets Number of buckets (bins) in the hash table. - * \param hash Function used to compute hash value of input keys. - * \param compare Function used to compare keys. - */ -extern struct hash_table *hash_table_ctor(unsigned num_buckets, - hash_func_t hash, hash_compare_func_t compare); - - -/** - * Release all memory associated with a hash table - * - * \warning - * This function cannot release memory occupied either by keys or data. - */ -extern void hash_table_dtor(struct hash_table *ht); - - -/** - * Flush all entries from a hash table - * - * \param ht Table to be cleared of its entries. - */ -extern void hash_table_clear(struct hash_table *ht); - - -/** - * Search a hash table for a specific element - * - * \param ht Table to be searched - * \param key Key of the desired element - * - * \return - * The \c data value supplied to \c hash_table_insert when the element with - * the matching key was added. If no matching key exists in the table, - * \c NULL is returned. - */ -extern void *hash_table_find(struct hash_table *ht, const void *key); - - -/** - * Add an element to a hash table - */ -extern void hash_table_insert(struct hash_table *ht, void *data, - const void *key); - - -/** - * Compute hash value of a string - * - * Computes the hash value of a string using the DJB2 algorithm developed by - * Professor Daniel J. Bernstein. It was published on comp.lang.c once upon - * a time. I was unable to find the original posting in the archives. - * - * \param key Pointer to a NUL terminated string to be hashed. - * - * \sa hash_table_string_compare - */ -extern unsigned hash_table_string_hash(const void *key); - - -/** - * Compare two strings used as keys - * - * This is just a macro wrapper around \c strcmp. - * - * \sa hash_table_string_hash - */ -#define hash_table_string_compare ((hash_compare_func_t) strcmp) - -#endif /* HASH_TABLE_H */ diff --git a/mesalib/src/mesa/shader/lex.yy.c b/mesalib/src/mesa/shader/lex.yy.c deleted file mode 100644 index 4c5c644a6..000000000 --- a/mesalib/src/mesa/shader/lex.yy.c +++ /dev/null @@ -1,3655 +0,0 @@ - -#line 3 "lex.yy.c" - -#define YY_INT_ALIGNED short int - -/* A lexical scanner generated by flex */ - -#define FLEX_SCANNER -#define YY_FLEX_MAJOR_VERSION 2 -#define YY_FLEX_MINOR_VERSION 5 -#define YY_FLEX_SUBMINOR_VERSION 35 -#if YY_FLEX_SUBMINOR_VERSION > 0 -#define FLEX_BETA -#endif - -/* First, we deal with platform-specific or compiler-specific issues. */ - -/* begin standard C headers. */ -#include <stdio.h> -#include <string.h> -#include <errno.h> -#include <stdlib.h> - -/* end standard C headers. */ - -/* flex integer type definitions */ - -#ifndef FLEXINT_H -#define FLEXINT_H - -/* C99 systems have <inttypes.h>. Non-C99 systems may or may not. */ - -#if defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L - -/* C99 says to define __STDC_LIMIT_MACROS before including stdint.h, - * if you want the limit (max/min) macros for int types. - */ -#ifndef __STDC_LIMIT_MACROS -#define __STDC_LIMIT_MACROS 1 -#endif - -#include <inttypes.h> -typedef int8_t flex_int8_t; -typedef uint8_t flex_uint8_t; -typedef int16_t flex_int16_t; -typedef uint16_t flex_uint16_t; -typedef int32_t flex_int32_t; -typedef uint32_t flex_uint32_t; -#else -typedef signed char flex_int8_t; -typedef short int flex_int16_t; -typedef int flex_int32_t; -typedef unsigned char flex_uint8_t; -typedef unsigned short int flex_uint16_t; -typedef unsigned int flex_uint32_t; -#endif /* ! C99 */ - -/* Limits of integral types. */ -#ifndef INT8_MIN -#define INT8_MIN (-128) -#endif -#ifndef INT16_MIN -#define INT16_MIN (-32767-1) -#endif -#ifndef INT32_MIN -#define INT32_MIN (-2147483647-1) -#endif -#ifndef INT8_MAX -#define INT8_MAX (127) -#endif -#ifndef INT16_MAX -#define INT16_MAX (32767) -#endif -#ifndef INT32_MAX -#define INT32_MAX (2147483647) -#endif -#ifndef UINT8_MAX -#define UINT8_MAX (255U) -#endif -#ifndef UINT16_MAX -#define UINT16_MAX (65535U) -#endif -#ifndef UINT32_MAX -#define UINT32_MAX (4294967295U) -#endif - -#endif /* ! FLEXINT_H */ - -#ifdef __cplusplus - -/* The "const" storage-class-modifier is valid. */ -#define YY_USE_CONST - -#else /* ! __cplusplus */ - -/* C99 requires __STDC__ to be defined as 1. */ -#if defined (__STDC__) - -#define YY_USE_CONST - -#endif /* defined (__STDC__) */ -#endif /* ! __cplusplus */ - -#ifdef YY_USE_CONST -#define yyconst const -#else -#define yyconst -#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) - -/* An opaque pointer. */ -#ifndef YY_TYPEDEF_YY_SCANNER_T -#define YY_TYPEDEF_YY_SCANNER_T -typedef void* yyscan_t; -#endif - -/* For convenience, these vars (plus the bison vars far below) - are macros in the reentrant scanner. */ -#define yyin yyg->yyin_r -#define yyout yyg->yyout_r -#define yyextra yyg->yyextra_r -#define yyleng yyg->yyleng_r -#define yytext yyg->yytext_r -#define yylineno (YY_CURRENT_BUFFER_LVALUE->yy_bs_lineno) -#define yycolumn (YY_CURRENT_BUFFER_LVALUE->yy_bs_column) -#define yy_flex_debug yyg->yy_flex_debug_r - -/* 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 yyg->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 ((yyg->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 ,yyscanner ) - -#define YY_END_OF_BUFFER_CHAR 0 - -/* Size of default input buffer. */ -#ifndef YY_BUF_SIZE -#define YY_BUF_SIZE 16384 -#endif - -/* The state buf must be large enough to hold one state per character in the main buffer. - */ -#define YY_STATE_BUF_SIZE ((YY_BUF_SIZE + 2) * sizeof(yy_state_type)) - -#ifndef YY_TYPEDEF_YY_BUFFER_STATE -#define YY_TYPEDEF_YY_BUFFER_STATE -typedef struct yy_buffer_state *YY_BUFFER_STATE; -#endif - -#define EOB_ACT_CONTINUE_SCAN 0 -#define EOB_ACT_END_OF_FILE 1 -#define EOB_ACT_LAST_MATCH 2 - - #define YY_LESS_LINENO(n) - -/* Return all but the first "n" matched characters back to the input stream. */ -#define yyless(n) \ - do \ - { \ - /* Undo effects of setting up yytext. */ \ - int yyless_macro_arg = (n); \ - YY_LESS_LINENO(yyless_macro_arg);\ - *yy_cp = yyg->yy_hold_char; \ - YY_RESTORE_YY_MORE_OFFSET \ - yyg->yy_c_buf_p = yy_cp = yy_bp + yyless_macro_arg - YY_MORE_ADJ; \ - YY_DO_BEFORE_ACTION; /* set up yytext again */ \ - } \ - while ( 0 ) - -#define unput(c) yyunput( c, yyg->yytext_ptr , yyscanner ) - -#ifndef YY_TYPEDEF_YY_SIZE_T -#define YY_TYPEDEF_YY_SIZE_T -typedef size_t yy_size_t; -#endif - -#ifndef YY_STRUCT_YY_BUFFER_STATE -#define YY_STRUCT_YY_BUFFER_STATE -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; - - int yy_bs_lineno; /**< The line count. */ - int yy_bs_column; /**< The column count. */ - - /* 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 - - }; -#endif /* !YY_STRUCT_YY_BUFFER_STATE */ - -/* 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". - * - * Returns the top of the stack, or NULL. - */ -#define YY_CURRENT_BUFFER ( yyg->yy_buffer_stack \ - ? yyg->yy_buffer_stack[yyg->yy_buffer_stack_top] \ - : NULL) - -/* Same as previous macro, but useful when we know that the buffer stack is not - * NULL or when we need an lvalue. For internal use only. - */ -#define YY_CURRENT_BUFFER_LVALUE yyg->yy_buffer_stack[yyg->yy_buffer_stack_top] - -void yyrestart (FILE *input_file ,yyscan_t yyscanner ); -void yy_switch_to_buffer (YY_BUFFER_STATE new_buffer ,yyscan_t yyscanner ); -YY_BUFFER_STATE yy_create_buffer (FILE *file,int size ,yyscan_t yyscanner ); -void yy_delete_buffer (YY_BUFFER_STATE b ,yyscan_t yyscanner ); -void yy_flush_buffer (YY_BUFFER_STATE b ,yyscan_t yyscanner ); -void yypush_buffer_state (YY_BUFFER_STATE new_buffer ,yyscan_t yyscanner ); -void yypop_buffer_state (yyscan_t yyscanner ); - -static void yyensure_buffer_stack (yyscan_t yyscanner ); -static void yy_load_buffer_state (yyscan_t yyscanner ); -static void yy_init_buffer (YY_BUFFER_STATE b,FILE *file ,yyscan_t yyscanner ); - -#define YY_FLUSH_BUFFER yy_flush_buffer(YY_CURRENT_BUFFER ,yyscanner) - -YY_BUFFER_STATE yy_scan_buffer (char *base,yy_size_t size ,yyscan_t yyscanner ); -YY_BUFFER_STATE yy_scan_string (yyconst char *yy_str ,yyscan_t yyscanner ); -YY_BUFFER_STATE yy_scan_bytes (yyconst char *bytes,int len ,yyscan_t yyscanner ); - -void *yyalloc (yy_size_t ,yyscan_t yyscanner ); -void *yyrealloc (void *,yy_size_t ,yyscan_t yyscanner ); -void yyfree (void * ,yyscan_t yyscanner ); - -#define yy_new_buffer yy_create_buffer - -#define yy_set_interactive(is_interactive) \ - { \ - if ( ! YY_CURRENT_BUFFER ){ \ - yyensure_buffer_stack (yyscanner); \ - YY_CURRENT_BUFFER_LVALUE = \ - yy_create_buffer(yyin,YY_BUF_SIZE ,yyscanner); \ - } \ - YY_CURRENT_BUFFER_LVALUE->yy_is_interactive = is_interactive; \ - } - -#define yy_set_bol(at_bol) \ - { \ - if ( ! YY_CURRENT_BUFFER ){\ - yyensure_buffer_stack (yyscanner); \ - YY_CURRENT_BUFFER_LVALUE = \ - yy_create_buffer(yyin,YY_BUF_SIZE ,yyscanner); \ - } \ - YY_CURRENT_BUFFER_LVALUE->yy_at_bol = at_bol; \ - } - -#define YY_AT_BOL() (YY_CURRENT_BUFFER_LVALUE->yy_at_bol) - -/* Begin user sect3 */ - -#define yywrap(n) 1 -#define YY_SKIP_YYWRAP - -typedef unsigned char YY_CHAR; - -typedef int yy_state_type; - -#define yytext_ptr yytext_r - -static yy_state_type yy_get_previous_state (yyscan_t yyscanner ); -static yy_state_type yy_try_NUL_trans (yy_state_type current_state ,yyscan_t yyscanner); -static int yy_get_next_buffer (yyscan_t yyscanner ); -static void yy_fatal_error (yyconst char msg[] ,yyscan_t yyscanner ); - -/* Done after the current pattern has been matched and before the - * corresponding action - sets up yytext. - */ -#define YY_DO_BEFORE_ACTION \ - yyg->yytext_ptr = yy_bp; \ - yyleng = (size_t) (yy_cp - yy_bp); \ - yyg->yy_hold_char = *yy_cp; \ - *yy_cp = '\0'; \ - yyg->yy_c_buf_p = yy_cp; - -#define YY_NUM_RULES 170 -#define YY_END_OF_BUFFER 171 -/* This struct is not used in this scanner, - but its presence is necessary. */ -struct yy_trans_info - { - flex_int32_t yy_verify; - flex_int32_t yy_nxt; - }; -static yyconst flex_int16_t yy_accept[850] = - { 0, - 0, 0, 171, 169, 167, 166, 169, 169, 139, 165, - 141, 141, 141, 141, 139, 139, 139, 139, 139, 139, - 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, - 139, 139, 139, 139, 139, 167, 0, 0, 168, 139, - 0, 140, 142, 162, 162, 0, 0, 0, 0, 162, - 0, 0, 0, 0, 0, 0, 0, 119, 163, 120, - 121, 153, 153, 153, 153, 0, 141, 0, 127, 128, - 129, 139, 139, 139, 139, 139, 139, 139, 139, 139, - 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, - 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, - - 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, - 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, - 139, 139, 139, 139, 139, 139, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 161, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 160, 160, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 159, 159, 159, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 150, 150, 150, 151, 151, 152, 143, - 142, 143, 0, 144, 11, 12, 139, 13, 139, 139, - 14, 15, 139, 16, 17, 18, 19, 20, 21, 6, - - 22, 23, 24, 25, 26, 28, 27, 29, 30, 31, - 32, 33, 34, 35, 139, 139, 139, 139, 139, 40, - 41, 139, 42, 43, 44, 45, 46, 47, 48, 139, - 49, 50, 51, 52, 53, 54, 55, 139, 56, 57, - 58, 59, 139, 139, 64, 65, 139, 139, 139, 139, - 139, 139, 0, 0, 0, 0, 142, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 80, 81, 83, - 0, 158, 0, 0, 0, 0, 0, 0, 97, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 157, - 156, 156, 109, 0, 0, 0, 0, 0, 0, 0, - - 0, 0, 0, 147, 147, 148, 149, 0, 145, 11, - 11, 139, 12, 12, 12, 139, 139, 139, 139, 139, - 15, 15, 139, 130, 16, 16, 139, 17, 17, 139, - 18, 18, 139, 19, 19, 139, 20, 20, 139, 21, - 21, 139, 22, 22, 139, 24, 24, 139, 25, 25, - 139, 28, 28, 139, 27, 27, 139, 30, 30, 139, - 31, 31, 139, 32, 32, 139, 33, 33, 139, 34, - 34, 139, 35, 35, 139, 139, 139, 139, 36, 139, - 38, 139, 40, 40, 139, 41, 41, 139, 131, 42, - 42, 139, 43, 43, 139, 139, 45, 45, 139, 46, - - 46, 139, 47, 47, 139, 48, 48, 139, 139, 49, - 49, 139, 50, 50, 139, 51, 51, 139, 52, 52, - 139, 53, 53, 139, 54, 54, 139, 139, 10, 56, - 139, 57, 139, 58, 139, 59, 139, 60, 139, 62, - 139, 64, 64, 139, 139, 139, 139, 139, 139, 139, - 139, 0, 164, 0, 0, 0, 73, 74, 0, 0, - 0, 0, 0, 0, 0, 85, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 155, 0, 0, 0, 113, 0, - 115, 0, 0, 0, 0, 0, 0, 154, 146, 139, - - 139, 139, 4, 139, 139, 139, 139, 139, 139, 139, - 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, - 139, 139, 139, 139, 139, 139, 9, 37, 39, 139, - 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, - 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, - 60, 139, 61, 62, 139, 63, 139, 139, 139, 139, - 139, 69, 139, 139, 0, 0, 0, 0, 0, 75, - 76, 0, 0, 0, 0, 84, 0, 0, 88, 91, - 0, 0, 0, 0, 0, 0, 0, 102, 103, 0, - 0, 0, 0, 108, 0, 0, 0, 0, 0, 0, - - 0, 0, 0, 0, 139, 139, 139, 139, 139, 139, - 5, 139, 139, 139, 139, 139, 139, 139, 139, 139, - 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, - 7, 8, 139, 139, 139, 139, 139, 139, 139, 139, - 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, - 139, 139, 139, 139, 61, 139, 139, 63, 139, 139, - 139, 139, 139, 70, 139, 66, 0, 0, 0, 0, - 124, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 94, 0, 98, 99, 0, 101, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 117, 118, 0, 0, - - 125, 11, 3, 12, 135, 136, 139, 14, 15, 16, - 17, 18, 19, 20, 21, 22, 24, 25, 28, 27, - 30, 31, 32, 33, 34, 35, 40, 41, 42, 43, - 44, 45, 46, 47, 48, 139, 139, 139, 49, 50, - 51, 52, 53, 54, 55, 56, 57, 58, 59, 139, - 139, 139, 139, 64, 65, 139, 68, 126, 0, 0, - 71, 0, 77, 0, 0, 0, 86, 0, 0, 0, - 0, 0, 0, 100, 0, 0, 106, 93, 0, 0, - 0, 0, 0, 0, 122, 0, 139, 132, 133, 139, - 60, 139, 62, 139, 67, 0, 0, 0, 0, 79, - - 82, 87, 0, 0, 92, 0, 0, 0, 105, 0, - 0, 0, 0, 114, 116, 0, 139, 139, 61, 63, - 2, 1, 0, 78, 0, 90, 0, 96, 104, 0, - 0, 111, 112, 123, 139, 134, 0, 89, 0, 107, - 110, 139, 72, 95, 139, 139, 137, 138, 0 - } ; - -static yyconst flex_int32_t yy_ec[256] = - { 0, - 1, 1, 1, 1, 1, 1, 1, 1, 2, 3, - 1, 1, 4, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 2, 5, 1, 6, 7, 1, 1, 1, 1, - 1, 1, 8, 1, 8, 9, 1, 10, 11, 12, - 13, 14, 15, 15, 15, 15, 15, 1, 1, 1, - 1, 1, 1, 1, 16, 17, 18, 19, 20, 21, - 22, 23, 24, 7, 25, 26, 27, 28, 29, 30, - 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, - 1, 1, 1, 1, 41, 1, 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, 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, 1, 1, 1, 1 - } ; - -static yyconst flex_int32_t yy_meta[68] = - { 0, - 1, 1, 1, 1, 1, 1, 2, 1, 3, 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 - } ; - -static yyconst flex_int16_t yy_base[853] = - { 0, - 0, 0, 1299, 1300, 66, 1300, 1293, 1294, 0, 69, - 85, 128, 140, 152, 151, 58, 56, 63, 76, 1272, - 158, 160, 39, 163, 173, 189, 52, 1265, 76, 1235, - 1234, 1246, 1230, 1244, 1243, 105, 1272, 1284, 1300, 0, - 225, 1300, 218, 160, 157, 20, 123, 66, 119, 192, - 1244, 1230, 54, 162, 1228, 1240, 194, 1300, 200, 195, - 98, 227, 196, 231, 235, 293, 305, 316, 1300, 1300, - 1300, 1249, 1262, 1256, 223, 1245, 1248, 1244, 1259, 107, - 298, 1241, 1255, 246, 1241, 1254, 1245, 1258, 1235, 1246, - 1237, 182, 1238, 1229, 1238, 1229, 1228, 1229, 144, 1223, - - 1229, 1240, 1231, 1225, 1222, 1223, 1227, 289, 1236, 1223, - 302, 1230, 1217, 1231, 1207, 65, 315, 276, 1227, 1226, - 1202, 1187, 1182, 1199, 1175, 1180, 1206, 279, 1195, 293, - 1190, 342, 299, 1192, 1173, 317, 1183, 1179, 1174, 207, - 1180, 1166, 1182, 1179, 1170, 320, 324, 1172, 1161, 1175, - 1178, 1160, 1175, 1162, 1159, 1166, 284, 1174, 227, 288, - 327, 342, 345, 1151, 1168, 1169, 1162, 1144, 318, 1145, - 1167, 1158, 330, 341, 345, 349, 353, 357, 361, 1300, - 419, 430, 436, 442, 440, 441, 1191, 0, 1190, 1173, - 1163, 443, 1183, 444, 451, 468, 470, 472, 471, 0, - - 496, 0, 497, 498, 0, 499, 500, 0, 524, 525, - 526, 536, 537, 553, 1178, 1171, 1184, 354, 356, 561, - 563, 1165, 564, 565, 1157, 580, 590, 591, 592, 1178, - 593, 617, 618, 619, 629, 630, 1155, 1165, 330, 362, - 419, 483, 445, 364, 646, 1153, 1145, 1144, 1129, 1129, - 1128, 1127, 1170, 1142, 1130, 662, 669, 643, 1134, 487, - 1131, 1125, 1125, 1119, 1132, 1132, 1117, 1300, 1300, 1132, - 1120, 646, 1127, 135, 1124, 1130, 561, 1125, 1300, 1116, - 1123, 1122, 1125, 1111, 1110, 1114, 1109, 448, 1114, 650, - 653, 665, 1300, 1106, 1104, 1104, 1112, 1113, 1095, 670, - - 1100, 1106, 486, 579, 655, 661, 668, 726, 732, 1112, - 682, 1119, 1110, 688, 730, 1117, 1116, 1109, 1123, 1113, - 1104, 712, 1111, 0, 1102, 731, 1109, 1100, 733, 1107, - 1098, 734, 1105, 1096, 736, 1103, 1094, 737, 1101, 1092, - 738, 1099, 1090, 739, 1097, 1088, 740, 1095, 1086, 741, - 1093, 1084, 742, 1091, 1082, 743, 1089, 1080, 744, 1087, - 1078, 745, 1085, 1076, 746, 1083, 1074, 747, 1081, 1072, - 748, 1079, 1070, 749, 1077, 1080, 1073, 1080, 0, 1073, - 0, 1088, 1063, 750, 1070, 1061, 751, 1068, 0, 1059, - 752, 1066, 1057, 755, 1064, 1063, 1054, 758, 1061, 1052, - - 776, 1059, 1050, 777, 1057, 1048, 779, 1055, 1058, 1045, - 780, 1052, 1043, 782, 1050, 1041, 783, 1048, 1039, 784, - 1046, 1037, 785, 1044, 1035, 786, 1042, 1041, 0, 1032, - 1039, 1030, 1037, 1028, 1035, 1026, 1033, 787, 1032, 788, - 1047, 1022, 789, 1029, 1028, 1006, 1000, 1005, 1011, 994, - 1009, 424, 1300, 1008, 998, 1002, 1300, 1300, 992, 1001, - 987, 1004, 987, 990, 984, 1300, 985, 984, 981, 988, - 981, 989, 985, 995, 992, 974, 980, 987, 971, 970, - 988, 970, 982, 981, 1300, 980, 970, 974, 1300, 961, - 1300, 966, 966, 974, 957, 958, 968, 1300, 1300, 1000, - - 982, 998, 0, 798, 996, 996, 995, 994, 993, 992, - 991, 990, 989, 988, 987, 986, 985, 984, 983, 982, - 981, 980, 979, 978, 965, 958, 0, 0, 0, 975, - 974, 973, 972, 971, 970, 969, 968, 967, 945, 965, - 964, 963, 962, 961, 960, 959, 958, 957, 956, 955, - 929, 936, 793, 927, 934, 794, 950, 949, 918, 921, - 901, 0, 902, 895, 902, 901, 902, 894, 912, 1300, - 1300, 894, 892, 902, 895, 1300, 890, 907, 516, 1300, - 898, 882, 883, 892, 883, 882, 882, 1300, 881, 890, - 880, 896, 893, 1300, 892, 890, 879, 880, 876, 868, - - 875, 870, 871, 866, 892, 892, 890, 904, 903, 898, - 0, 886, 885, 884, 883, 882, 881, 880, 879, 878, - 877, 876, 875, 874, 873, 872, 871, 870, 869, 868, - 0, 0, 867, 866, 865, 864, 863, 862, 861, 860, - 859, 804, 858, 857, 856, 855, 854, 853, 852, 851, - 850, 849, 848, 865, 839, 846, 862, 836, 843, 841, - 840, 818, 818, 0, 825, 0, 859, 858, 807, 825, - 1300, 820, 815, 808, 804, 816, 806, 804, 800, 816, - 807, 806, 1300, 1300, 809, 1300, 804, 797, 786, 797, - 789, 793, 806, 801, 804, 786, 1300, 1300, 798, 787, - - 1300, 0, 0, 0, 0, 0, 826, 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, 814, 813, 802, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 785, - 798, 779, 792, 0, 0, 656, 0, 0, 706, 702, - 1300, 649, 1300, 648, 648, 654, 1300, 637, 645, 610, - 612, 608, 608, 1300, 572, 583, 1300, 1300, 577, 573, - 560, 557, 542, 555, 1300, 539, 573, 0, 0, 572, - 0, 555, 0, 546, 0, 562, 551, 495, 479, 1300, - - 1300, 1300, 481, 481, 1300, 480, 443, 31, 1300, 141, - 166, 171, 186, 1300, 1300, 211, 236, 276, 0, 0, - 1300, 1300, 290, 1300, 325, 1300, 346, 1300, 1300, 343, - 341, 1300, 1300, 1300, 365, 0, 380, 1300, 371, 1300, - 1300, 486, 1300, 1300, 451, 458, 0, 0, 1300, 836, - 503, 839 - } ; - -static yyconst flex_int16_t yy_def[853] = - { 0, - 849, 1, 849, 849, 849, 849, 849, 850, 851, 849, - 849, 849, 849, 849, 851, 851, 851, 851, 851, 851, - 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, - 851, 851, 851, 851, 851, 849, 849, 850, 849, 851, - 849, 849, 849, 849, 849, 849, 849, 849, 849, 849, - 849, 849, 849, 849, 849, 849, 849, 849, 849, 849, - 849, 849, 849, 849, 849, 852, 849, 849, 849, 849, - 849, 851, 851, 851, 851, 851, 851, 851, 851, 851, - 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, - 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, - - 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, - 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, - 851, 851, 851, 851, 851, 851, 849, 849, 849, 849, - 849, 849, 849, 849, 849, 849, 849, 849, 849, 849, - 849, 849, 849, 849, 849, 849, 849, 849, 849, 849, - 849, 849, 849, 849, 849, 849, 849, 849, 849, 849, - 849, 849, 849, 849, 849, 849, 849, 849, 849, 849, - 849, 849, 849, 849, 849, 849, 849, 849, 849, 849, - 849, 849, 849, 849, 851, 851, 851, 851, 851, 851, - 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, - - 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, - 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, - 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, - 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, - 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, - 851, 851, 849, 849, 849, 849, 849, 849, 849, 849, - 849, 849, 849, 849, 849, 849, 849, 849, 849, 849, - 849, 849, 849, 849, 849, 849, 849, 849, 849, 849, - 849, 849, 849, 849, 849, 849, 849, 849, 849, 849, - 849, 849, 849, 849, 849, 849, 849, 849, 849, 849, - - 849, 849, 849, 849, 849, 849, 849, 849, 849, 851, - 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, - 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, - 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, - 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, - 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, - 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, - 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, - 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, - 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, - - 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, - 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, - 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, - 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, - 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, - 851, 849, 849, 849, 849, 849, 849, 849, 849, 849, - 849, 849, 849, 849, 849, 849, 849, 849, 849, 849, - 849, 849, 849, 849, 849, 849, 849, 849, 849, 849, - 849, 849, 849, 849, 849, 849, 849, 849, 849, 849, - 849, 849, 849, 849, 849, 849, 849, 849, 849, 851, - - 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, - 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, - 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, - 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, - 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, - 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, - 851, 851, 851, 851, 849, 849, 849, 849, 849, 849, - 849, 849, 849, 849, 849, 849, 849, 849, 849, 849, - 849, 849, 849, 849, 849, 849, 849, 849, 849, 849, - 849, 849, 849, 849, 849, 849, 849, 849, 849, 849, - - 849, 849, 849, 849, 851, 851, 851, 851, 851, 851, - 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, - 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, - 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, - 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, - 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, - 851, 851, 851, 851, 851, 851, 849, 849, 849, 849, - 849, 849, 849, 849, 849, 849, 849, 849, 849, 849, - 849, 849, 849, 849, 849, 849, 849, 849, 849, 849, - 849, 849, 849, 849, 849, 849, 849, 849, 849, 849, - - 849, 851, 851, 851, 851, 851, 851, 851, 851, 851, - 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, - 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, - 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, - 851, 851, 851, 851, 851, 851, 851, 851, 851, 851, - 851, 851, 851, 851, 851, 851, 851, 851, 849, 849, - 849, 849, 849, 849, 849, 849, 849, 849, 849, 849, - 849, 849, 849, 849, 849, 849, 849, 849, 849, 849, - 849, 849, 849, 849, 849, 849, 851, 851, 851, 851, - 851, 851, 851, 851, 851, 849, 849, 849, 849, 849, - - 849, 849, 849, 849, 849, 849, 849, 849, 849, 849, - 849, 849, 849, 849, 849, 849, 851, 851, 851, 851, - 849, 849, 849, 849, 849, 849, 849, 849, 849, 849, - 849, 849, 849, 849, 851, 851, 849, 849, 849, 849, - 849, 851, 849, 849, 851, 851, 851, 851, 0, 849, - 849, 849 - } ; - -static yyconst flex_int16_t yy_nxt[1368] = - { 0, - 4, 5, 6, 5, 7, 8, 9, 4, 10, 11, - 12, 13, 14, 11, 11, 15, 9, 16, 17, 18, - 19, 9, 9, 9, 20, 21, 22, 9, 23, 24, - 9, 25, 26, 27, 28, 9, 9, 29, 9, 9, - 9, 9, 9, 9, 9, 9, 30, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 31, 9, 32, 33, - 34, 9, 35, 9, 9, 9, 9, 36, 96, 36, - 41, 116, 137, 97, 80, 138, 829, 42, 43, 43, - 43, 43, 43, 43, 77, 81, 78, 119, 82, 117, - 83, 238, 79, 66, 67, 67, 67, 67, 67, 67, - - 84, 85, 239, 150, 68, 120, 36, 86, 36, 151, - 44, 45, 46, 47, 48, 49, 50, 51, 52, 141, - 142, 53, 54, 55, 56, 57, 58, 59, 60, 61, - 68, 143, 62, 63, 64, 65, 66, 67, 67, 67, - 67, 67, 67, 170, 194, 195, 69, 68, 66, 67, - 67, 67, 67, 67, 67, 218, 171, 219, 70, 68, - 66, 67, 67, 67, 67, 67, 67, 72, 139, 73, - 71, 68, 140, 68, 144, 92, 74, 145, 98, 88, - 467, 89, 75, 93, 76, 68, 90, 99, 94, 91, - 101, 100, 102, 103, 95, 468, 830, 68, 136, 133, - - 210, 133, 133, 152, 133, 104, 105, 133, 106, 107, - 108, 109, 110, 134, 111, 133, 112, 153, 133, 211, - 135, 831, 113, 114, 154, 115, 41, 43, 43, 43, - 43, 43, 43, 146, 147, 157, 832, 132, 165, 133, - 166, 161, 162, 167, 168, 833, 158, 163, 188, 159, - 133, 169, 160, 265, 189, 164, 834, 201, 133, 174, - 173, 175, 176, 132, 835, 266, 128, 129, 46, 47, - 48, 49, 172, 51, 52, 202, 285, 53, 54, 55, - 56, 57, 58, 130, 60, 61, 286, 243, 131, 244, - 173, 173, 173, 173, 177, 173, 173, 178, 179, 173, - - 173, 173, 181, 181, 181, 181, 181, 181, 228, 836, - 196, 197, 182, 66, 67, 67, 67, 67, 67, 67, - 198, 232, 229, 183, 68, 184, 184, 184, 184, 184, - 184, 240, 134, 241, 255, 233, 282, 287, 182, 135, - 258, 258, 283, 288, 242, 837, 258, 430, 164, 256, - 68, 257, 257, 257, 257, 257, 257, 258, 258, 258, - 261, 258, 258, 298, 258, 272, 258, 258, 258, 258, - 431, 258, 381, 299, 258, 258, 379, 838, 258, 432, - 440, 289, 258, 290, 258, 258, 291, 292, 380, 258, - 382, 839, 258, 303, 303, 303, 303, 840, 441, 841, - - 258, 842, 433, 258, 303, 303, 303, 303, 304, 303, - 303, 305, 306, 303, 303, 303, 303, 303, 303, 303, - 307, 303, 303, 303, 303, 303, 303, 303, 43, 43, - 43, 43, 43, 43, 843, 844, 434, 308, 132, 309, - 309, 309, 309, 309, 309, 184, 184, 184, 184, 184, - 184, 184, 184, 184, 184, 184, 184, 310, 313, 435, - 321, 325, 311, 314, 132, 322, 326, 438, 328, 847, - 565, 311, 315, 329, 322, 326, 848, 311, 314, 439, - 312, 316, 329, 323, 327, 331, 566, 334, 340, 337, - 332, 330, 335, 341, 338, 482, 845, 846, 483, 332, - - 436, 335, 341, 338, 40, 332, 828, 335, 333, 338, - 336, 342, 339, 343, 346, 349, 352, 355, 344, 347, - 350, 353, 356, 437, 827, 826, 825, 344, 347, 350, - 353, 356, 455, 824, 347, 350, 345, 348, 351, 354, - 357, 358, 361, 364, 823, 456, 359, 362, 365, 498, - 498, 498, 498, 367, 370, 359, 362, 365, 368, 371, - 822, 359, 362, 365, 360, 363, 366, 368, 371, 678, - 373, 821, 679, 368, 371, 374, 369, 372, 383, 820, - 386, 390, 393, 384, 374, 387, 391, 394, 819, 818, - 374, 817, 384, 375, 387, 391, 394, 397, 816, 815, - - 814, 385, 398, 388, 392, 395, 471, 400, 403, 406, - 410, 398, 401, 404, 407, 411, 813, 398, 812, 472, - 399, 401, 404, 407, 411, 811, 810, 401, 404, 407, - 402, 405, 408, 412, 413, 416, 419, 809, 808, 414, - 417, 420, 498, 498, 498, 498, 422, 425, 414, 417, - 420, 423, 426, 807, 414, 417, 420, 415, 418, 421, - 423, 426, 806, 442, 805, 804, 423, 426, 443, 424, - 427, 257, 257, 257, 257, 257, 257, 443, 257, 257, - 257, 257, 257, 257, 453, 453, 444, 453, 453, 803, - 453, 453, 453, 453, 453, 453, 802, 453, 801, 310, - - 453, 453, 800, 799, 453, 313, 485, 453, 453, 798, - 797, 453, 453, 492, 796, 493, 795, 494, 499, 498, - 498, 498, 312, 453, 498, 498, 498, 498, 316, 321, - 495, 498, 498, 498, 498, 309, 309, 309, 309, 309, - 309, 309, 309, 309, 309, 309, 309, 313, 325, 501, - 328, 331, 323, 334, 337, 340, 343, 346, 349, 352, - 355, 358, 361, 364, 367, 370, 373, 383, 386, 390, - 316, 327, 393, 330, 333, 397, 336, 339, 342, 345, - 348, 351, 354, 357, 360, 363, 366, 369, 372, 375, - 385, 388, 392, 400, 403, 395, 406, 410, 399, 413, - - 416, 419, 422, 425, 551, 554, 442, 794, 608, 609, - 655, 658, 793, 792, 736, 737, 402, 405, 791, 408, - 412, 790, 415, 418, 421, 424, 427, 552, 555, 444, - 610, 789, 788, 656, 659, 738, 38, 38, 38, 180, - 180, 787, 786, 785, 784, 783, 782, 781, 780, 779, - 778, 777, 776, 775, 774, 773, 772, 771, 770, 769, - 768, 767, 766, 765, 764, 763, 762, 761, 760, 759, - 758, 757, 756, 755, 754, 753, 659, 752, 751, 656, - 750, 749, 748, 747, 746, 745, 744, 743, 742, 741, - 740, 739, 735, 734, 733, 732, 731, 730, 729, 728, - - 727, 726, 725, 724, 723, 722, 721, 720, 719, 718, - 717, 716, 715, 714, 713, 712, 711, 710, 709, 708, - 707, 706, 705, 704, 703, 702, 701, 700, 699, 698, - 697, 696, 695, 694, 693, 692, 691, 690, 689, 688, - 687, 686, 685, 684, 683, 682, 681, 680, 677, 676, - 675, 674, 673, 672, 671, 670, 669, 668, 667, 666, - 665, 664, 663, 662, 661, 660, 657, 555, 654, 552, - 653, 652, 651, 650, 649, 648, 647, 646, 645, 644, - 643, 642, 641, 640, 639, 638, 637, 636, 635, 634, - 633, 632, 631, 630, 629, 628, 627, 626, 625, 624, - - 623, 622, 621, 620, 619, 618, 617, 616, 615, 614, - 613, 612, 611, 607, 606, 605, 604, 603, 602, 601, - 600, 599, 598, 597, 596, 595, 594, 593, 592, 591, - 590, 589, 588, 587, 586, 585, 584, 583, 582, 581, - 580, 579, 578, 577, 576, 575, 574, 573, 572, 571, - 570, 569, 568, 567, 564, 563, 562, 561, 560, 559, - 558, 557, 444, 556, 553, 550, 437, 549, 435, 548, - 433, 547, 431, 546, 545, 427, 544, 424, 543, 421, - 542, 418, 541, 415, 540, 412, 539, 538, 408, 537, - 405, 536, 402, 535, 399, 534, 533, 395, 532, 392, - - 531, 388, 530, 385, 529, 528, 527, 526, 525, 524, - 375, 523, 372, 522, 369, 521, 366, 520, 363, 519, - 360, 518, 357, 517, 354, 516, 351, 515, 348, 514, - 345, 513, 342, 512, 339, 511, 336, 510, 333, 509, - 330, 508, 327, 507, 323, 506, 505, 504, 503, 502, - 316, 500, 312, 497, 496, 491, 490, 489, 488, 487, - 486, 484, 481, 480, 479, 478, 477, 476, 475, 474, - 473, 470, 469, 466, 465, 464, 463, 462, 461, 460, - 459, 458, 457, 454, 289, 261, 452, 451, 450, 449, - 448, 447, 446, 445, 429, 428, 409, 396, 389, 378, - - 377, 376, 324, 320, 319, 318, 317, 302, 301, 300, - 297, 296, 295, 294, 293, 284, 281, 280, 279, 278, - 277, 276, 275, 274, 273, 271, 270, 269, 268, 267, - 264, 263, 262, 260, 259, 172, 254, 253, 252, 251, - 250, 249, 248, 247, 246, 245, 237, 236, 235, 234, - 231, 230, 227, 226, 225, 224, 223, 222, 221, 220, - 217, 216, 215, 214, 213, 212, 209, 208, 207, 206, - 205, 204, 203, 200, 199, 193, 192, 191, 190, 187, - 186, 185, 156, 155, 149, 148, 39, 127, 126, 125, - 124, 123, 122, 121, 118, 87, 39, 37, 849, 3, - - 849, 849, 849, 849, 849, 849, 849, 849, 849, 849, - 849, 849, 849, 849, 849, 849, 849, 849, 849, 849, - 849, 849, 849, 849, 849, 849, 849, 849, 849, 849, - 849, 849, 849, 849, 849, 849, 849, 849, 849, 849, - 849, 849, 849, 849, 849, 849, 849, 849, 849, 849, - 849, 849, 849, 849, 849, 849, 849, 849, 849, 849, - 849, 849, 849, 849, 849, 849, 849 - } ; - -static yyconst flex_int16_t yy_chk[1368] = - { 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, 5, 23, 5, - 10, 27, 46, 23, 17, 46, 808, 10, 10, 10, - 10, 10, 10, 10, 16, 17, 16, 29, 17, 27, - 18, 116, 16, 11, 11, 11, 11, 11, 11, 11, - - 18, 19, 116, 53, 11, 29, 36, 19, 36, 53, - 10, 10, 10, 10, 10, 10, 10, 10, 10, 48, - 48, 10, 10, 10, 10, 10, 10, 10, 10, 10, - 11, 48, 10, 10, 10, 10, 12, 12, 12, 12, - 12, 12, 12, 61, 80, 80, 12, 12, 13, 13, - 13, 13, 13, 13, 13, 99, 61, 99, 13, 13, - 14, 14, 14, 14, 14, 14, 14, 15, 47, 15, - 14, 14, 47, 12, 49, 22, 15, 49, 24, 21, - 274, 21, 15, 22, 15, 13, 21, 24, 22, 21, - 25, 24, 25, 25, 22, 274, 810, 14, 45, 45, - - 92, 44, 44, 54, 45, 25, 26, 44, 26, 26, - 26, 26, 26, 44, 26, 45, 26, 54, 44, 92, - 44, 811, 26, 26, 54, 26, 41, 43, 43, 43, - 43, 43, 43, 50, 50, 57, 812, 43, 60, 50, - 60, 59, 59, 60, 60, 813, 57, 59, 75, 57, - 50, 60, 57, 140, 75, 59, 816, 84, 59, 63, - 63, 63, 63, 43, 817, 140, 41, 41, 41, 41, - 41, 41, 62, 41, 41, 84, 159, 41, 41, 41, - 41, 41, 41, 41, 41, 41, 159, 118, 41, 118, - 62, 62, 62, 62, 64, 64, 64, 64, 65, 65, - - 65, 65, 66, 66, 66, 66, 66, 66, 108, 818, - 81, 81, 66, 67, 67, 67, 67, 67, 67, 67, - 81, 111, 108, 68, 67, 68, 68, 68, 68, 68, - 68, 117, 128, 117, 130, 111, 157, 160, 66, 128, - 133, 133, 157, 160, 117, 823, 133, 239, 130, 132, - 67, 132, 132, 132, 132, 132, 132, 133, 136, 136, - 136, 146, 146, 169, 136, 147, 147, 146, 161, 161, - 239, 147, 219, 169, 161, 136, 218, 825, 146, 240, - 244, 161, 147, 162, 162, 161, 163, 163, 218, 162, - 219, 827, 163, 173, 173, 173, 173, 830, 244, 831, - - 162, 835, 240, 163, 174, 174, 174, 174, 175, 175, - 175, 175, 176, 176, 176, 176, 177, 177, 177, 177, - 178, 178, 178, 178, 179, 179, 179, 179, 181, 181, - 181, 181, 181, 181, 837, 839, 241, 182, 181, 182, - 182, 182, 182, 182, 182, 183, 183, 183, 183, 183, - 183, 184, 184, 184, 184, 184, 184, 185, 186, 241, - 192, 194, 185, 186, 181, 192, 194, 243, 195, 845, - 452, 185, 186, 195, 192, 194, 846, 185, 186, 243, - 185, 186, 195, 192, 194, 196, 452, 197, 199, 198, - 196, 195, 197, 199, 198, 288, 842, 842, 288, 196, - - 242, 197, 199, 198, 851, 196, 807, 197, 196, 198, - 197, 199, 198, 201, 203, 204, 206, 207, 201, 203, - 204, 206, 207, 242, 806, 804, 803, 201, 203, 204, - 206, 207, 260, 799, 203, 204, 201, 203, 204, 206, - 207, 209, 210, 211, 798, 260, 209, 210, 211, 303, - 303, 303, 303, 212, 213, 209, 210, 211, 212, 213, - 797, 209, 210, 211, 209, 210, 211, 212, 213, 579, - 214, 796, 579, 212, 213, 214, 212, 213, 220, 794, - 221, 223, 224, 220, 214, 221, 223, 224, 792, 790, - 214, 787, 220, 214, 221, 223, 224, 226, 786, 784, - - 783, 220, 226, 221, 223, 224, 277, 227, 228, 229, - 231, 226, 227, 228, 229, 231, 782, 226, 781, 277, - 226, 227, 228, 229, 231, 780, 779, 227, 228, 229, - 227, 228, 229, 231, 232, 233, 234, 776, 775, 232, - 233, 234, 304, 304, 304, 304, 235, 236, 232, 233, - 234, 235, 236, 773, 232, 233, 234, 232, 233, 234, - 235, 236, 772, 245, 771, 770, 235, 236, 245, 235, - 236, 256, 256, 256, 256, 256, 256, 245, 257, 257, - 257, 257, 257, 257, 258, 258, 245, 272, 272, 769, - 258, 290, 290, 272, 291, 291, 768, 290, 766, 311, - - 291, 258, 765, 764, 272, 314, 292, 292, 290, 762, - 760, 291, 292, 300, 759, 300, 756, 300, 305, 305, - 305, 305, 311, 292, 306, 306, 306, 306, 314, 322, - 300, 307, 307, 307, 307, 308, 308, 308, 308, 308, - 308, 309, 309, 309, 309, 309, 309, 315, 326, 315, - 329, 332, 322, 335, 338, 341, 344, 347, 350, 353, - 356, 359, 362, 365, 368, 371, 374, 384, 387, 391, - 315, 326, 394, 329, 332, 398, 335, 338, 341, 344, - 347, 350, 353, 356, 359, 362, 365, 368, 371, 374, - 384, 387, 391, 401, 404, 394, 407, 411, 398, 414, - - 417, 420, 423, 426, 438, 440, 443, 753, 504, 504, - 553, 556, 752, 751, 642, 642, 401, 404, 750, 407, - 411, 738, 414, 417, 420, 423, 426, 438, 440, 443, - 504, 737, 736, 553, 556, 642, 850, 850, 850, 852, - 852, 707, 700, 699, 696, 695, 694, 693, 692, 691, - 690, 689, 688, 687, 685, 682, 681, 680, 679, 678, - 677, 676, 675, 674, 673, 672, 670, 669, 668, 667, - 665, 663, 662, 661, 660, 659, 658, 657, 656, 655, - 654, 653, 652, 651, 650, 649, 648, 647, 646, 645, - 644, 643, 641, 640, 639, 638, 637, 636, 635, 634, - - 633, 630, 629, 628, 627, 626, 625, 624, 623, 622, - 621, 620, 619, 618, 617, 616, 615, 614, 613, 612, - 610, 609, 608, 607, 606, 605, 604, 603, 602, 601, - 600, 599, 598, 597, 596, 595, 593, 592, 591, 590, - 589, 587, 586, 585, 584, 583, 582, 581, 578, 577, - 575, 574, 573, 572, 569, 568, 567, 566, 565, 564, - 563, 561, 560, 559, 558, 557, 555, 554, 552, 551, - 550, 549, 548, 547, 546, 545, 544, 543, 542, 541, - 540, 539, 538, 537, 536, 535, 534, 533, 532, 531, - 530, 526, 525, 524, 523, 522, 521, 520, 519, 518, - - 517, 516, 515, 514, 513, 512, 511, 510, 509, 508, - 507, 506, 505, 502, 501, 500, 497, 496, 495, 494, - 493, 492, 490, 488, 487, 486, 484, 483, 482, 481, - 480, 479, 478, 477, 476, 475, 474, 473, 472, 471, - 470, 469, 468, 467, 465, 464, 463, 462, 461, 460, - 459, 456, 455, 454, 451, 450, 449, 448, 447, 446, - 445, 444, 442, 441, 439, 437, 436, 435, 434, 433, - 432, 431, 430, 428, 427, 425, 424, 422, 421, 419, - 418, 416, 415, 413, 412, 410, 409, 408, 406, 405, - 403, 402, 400, 399, 397, 396, 395, 393, 392, 390, - - 388, 386, 385, 383, 382, 380, 378, 377, 376, 375, - 373, 372, 370, 369, 367, 366, 364, 363, 361, 360, - 358, 357, 355, 354, 352, 351, 349, 348, 346, 345, - 343, 342, 340, 339, 337, 336, 334, 333, 331, 330, - 328, 327, 325, 323, 321, 320, 319, 318, 317, 316, - 313, 312, 310, 302, 301, 299, 298, 297, 296, 295, - 294, 289, 287, 286, 285, 284, 283, 282, 281, 280, - 278, 276, 275, 273, 271, 270, 267, 266, 265, 264, - 263, 262, 261, 259, 255, 254, 253, 252, 251, 250, - 249, 248, 247, 246, 238, 237, 230, 225, 222, 217, - - 216, 215, 193, 191, 190, 189, 187, 172, 171, 170, - 168, 167, 166, 165, 164, 158, 156, 155, 154, 153, - 152, 151, 150, 149, 148, 145, 144, 143, 142, 141, - 139, 138, 137, 135, 134, 131, 129, 127, 126, 125, - 124, 123, 122, 121, 120, 119, 115, 114, 113, 112, - 110, 109, 107, 106, 105, 104, 103, 102, 101, 100, - 98, 97, 96, 95, 94, 93, 91, 90, 89, 88, - 87, 86, 85, 83, 82, 79, 78, 77, 76, 74, - 73, 72, 56, 55, 52, 51, 38, 37, 35, 34, - 33, 32, 31, 30, 28, 20, 8, 7, 3, 849, - - 849, 849, 849, 849, 849, 849, 849, 849, 849, 849, - 849, 849, 849, 849, 849, 849, 849, 849, 849, 849, - 849, 849, 849, 849, 849, 849, 849, 849, 849, 849, - 849, 849, 849, 849, 849, 849, 849, 849, 849, 849, - 849, 849, 849, 849, 849, 849, 849, 849, 849, 849, - 849, 849, 849, 849, 849, 849, 849, 849, 849, 849, - 849, 849, 849, 849, 849, 849, 849 - } ; - -/* 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 -#line 1 "program_lexer.l" -#line 2 "program_lexer.l" -/* - * Copyright © 2009 Intel Corporation - * - * 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 (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 NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS 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 "main/glheader.h" -#include "main/imports.h" -#include "shader/prog_instruction.h" -#include "shader/prog_statevars.h" - -#include "shader/symbol_table.h" -#include "shader/program_parser.h" -#include "shader/program_parse.tab.h" - -#define require_ARB_vp (yyextra->mode == ARB_vertex) -#define require_ARB_fp (yyextra->mode == ARB_fragment) -#define require_NV_fp (yyextra->option.NV_fragment) -#define require_shadow (yyextra->option.Shadow) -#define require_rect (yyextra->option.TexRect) -#define require_texarray (yyextra->option.TexArray) - -#ifndef HAVE_UNISTD_H -#define YY_NO_UNISTD_H -#endif - -#define return_token_or_IDENTIFIER(condition, token) \ - do { \ - if (condition) { \ - return token; \ - } else { \ - return handle_ident(yyextra, yytext, yylval); \ - } \ - } while (0) - -#define return_token_or_DOT(condition, token) \ - do { \ - if (condition) { \ - return token; \ - } else { \ - yyless(1); \ - return DOT; \ - } \ - } while (0) - - -#define return_opcode(condition, token, opcode, len) \ - do { \ - if (condition && \ - _mesa_parse_instruction_suffix(yyextra, \ - yytext + len, \ - & yylval->temp_inst)) { \ - yylval->temp_inst.Opcode = OPCODE_ ## opcode; \ - return token; \ - } else { \ - return handle_ident(yyextra, yytext, yylval); \ - } \ - } while (0) - -#define SWIZZLE_INVAL MAKE_SWIZZLE4(SWIZZLE_NIL, SWIZZLE_NIL, \ - SWIZZLE_NIL, SWIZZLE_NIL) - -static unsigned -mask_from_char(char c) -{ - switch (c) { - case 'x': - case 'r': - return WRITEMASK_X; - case 'y': - case 'g': - return WRITEMASK_Y; - case 'z': - case 'b': - return WRITEMASK_Z; - case 'w': - case 'a': - return WRITEMASK_W; - } - - return 0; -} - -static unsigned -swiz_from_char(char c) -{ - switch (c) { - case 'x': - case 'r': - return SWIZZLE_X; - case 'y': - case 'g': - return SWIZZLE_Y; - case 'z': - case 'b': - return SWIZZLE_Z; - case 'w': - case 'a': - return SWIZZLE_W; - } - - return 0; -} - -static int -handle_ident(struct asm_parser_state *state, const char *text, YYSTYPE *lval) -{ - lval->string = strdup(text); - - return (_mesa_symbol_table_find_symbol(state->st, 0, text) == NULL) - ? IDENTIFIER : USED_IDENTIFIER; -} - -#define YY_USER_ACTION \ - do { \ - yylloc->first_column = yylloc->last_column; \ - yylloc->last_column += yyleng; \ - if ((yylloc->first_line == 1) \ - && (yylloc->first_column == 1)) { \ - yylloc->position = 1; \ - } else { \ - yylloc->position += yylloc->last_column - yylloc->first_column; \ - } \ - } while(0); - -#define YY_EXTRA_TYPE struct asm_parser_state * -#line 1156 "lex.yy.c" - -#define INITIAL 0 - -#ifndef YY_NO_UNISTD_H -/* Special case for "unistd.h", since it is non-ANSI. We include it way - * down here because we want the user's section 1 to have been scanned first. - * The user has a chance to override it with an option. - */ -#include <unistd.h> -#endif - -#ifndef YY_EXTRA_TYPE -#define YY_EXTRA_TYPE void * -#endif - -/* Holds the entire state of the reentrant scanner. */ -struct yyguts_t - { - - /* User-defined. Not touched by flex. */ - YY_EXTRA_TYPE yyextra_r; - - /* The rest are the same as the globals declared in the non-reentrant scanner. */ - FILE *yyin_r, *yyout_r; - size_t yy_buffer_stack_top; /**< index of top of stack. */ - size_t yy_buffer_stack_max; /**< capacity of stack. */ - YY_BUFFER_STATE * yy_buffer_stack; /**< Stack as an array. */ - char yy_hold_char; - int yy_n_chars; - int yyleng_r; - char *yy_c_buf_p; - int yy_init; - int yy_start; - int yy_did_buffer_switch_on_eof; - int yy_start_stack_ptr; - int yy_start_stack_depth; - int *yy_start_stack; - yy_state_type yy_last_accepting_state; - char* yy_last_accepting_cpos; - - int yylineno_r; - int yy_flex_debug_r; - - char *yytext_r; - int yy_more_flag; - int yy_more_len; - - YYSTYPE * yylval_r; - - YYLTYPE * yylloc_r; - - }; /* end struct yyguts_t */ - -static int yy_init_globals (yyscan_t yyscanner ); - - /* This must go here because YYSTYPE and YYLTYPE are included - * from bison output in section 1.*/ - # define yylval yyg->yylval_r - - # define yylloc yyg->yylloc_r - -int yylex_init (yyscan_t* scanner); - -int yylex_init_extra (YY_EXTRA_TYPE user_defined,yyscan_t* scanner); - -/* Accessor methods to globals. - These are made visible to non-reentrant scanners for convenience. */ - -int yylex_destroy (yyscan_t yyscanner ); - -int yyget_debug (yyscan_t yyscanner ); - -void yyset_debug (int debug_flag ,yyscan_t yyscanner ); - -YY_EXTRA_TYPE yyget_extra (yyscan_t yyscanner ); - -void yyset_extra (YY_EXTRA_TYPE user_defined ,yyscan_t yyscanner ); - -FILE *yyget_in (yyscan_t yyscanner ); - -void yyset_in (FILE * in_str ,yyscan_t yyscanner ); - -FILE *yyget_out (yyscan_t yyscanner ); - -void yyset_out (FILE * out_str ,yyscan_t yyscanner ); - -int yyget_leng (yyscan_t yyscanner ); - -char *yyget_text (yyscan_t yyscanner ); - -int yyget_lineno (yyscan_t yyscanner ); - -void yyset_lineno (int line_number ,yyscan_t yyscanner ); - -YYSTYPE * yyget_lval (yyscan_t yyscanner ); - -void yyset_lval (YYSTYPE * yylval_param ,yyscan_t yyscanner ); - - YYLTYPE *yyget_lloc (yyscan_t yyscanner ); - - void yyset_lloc (YYLTYPE * yylloc_param ,yyscan_t yyscanner ); - -/* Macros after this point can all be overridden by user definitions in - * section 1. - */ - -#ifndef YY_SKIP_YYWRAP -#ifdef __cplusplus -extern "C" int yywrap (yyscan_t yyscanner ); -#else -extern int yywrap (yyscan_t yyscanner ); -#endif -#endif - - static void yyunput (int c,char *buf_ptr ,yyscan_t yyscanner); - -#ifndef yytext_ptr -static void yy_flex_strncpy (char *,yyconst char *,int ,yyscan_t yyscanner); -#endif - -#ifdef YY_NEED_STRLEN -static int yy_flex_strlen (yyconst char * ,yyscan_t yyscanner); -#endif - -#ifndef YY_NO_INPUT - -#ifdef __cplusplus -static int yyinput (yyscan_t yyscanner ); -#else -static int input (yyscan_t yyscanner ); -#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 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_LVALUE->yy_is_interactive ) \ - { \ - int c = '*'; \ - unsigned 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 \ - { \ - errno=0; \ - while ( (result = fread(buf, 1, max_size, yyin))==0 && ferror(yyin)) \ - { \ - if( errno != EINTR) \ - { \ - YY_FATAL_ERROR( "input in flex scanner failed" ); \ - break; \ - } \ - errno=0; \ - clearerr(yyin); \ - } \ - }\ -\ - -#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 , yyscanner) -#endif - -/* end tables serialization structures and prototypes */ - -/* Default declaration of generated scanner - a define so the user can - * easily add parameters. - */ -#ifndef YY_DECL -#define YY_DECL_IS_OURS 1 - -extern int yylex \ - (YYSTYPE * yylval_param,YYLTYPE * yylloc_param ,yyscan_t yyscanner); - -#define YY_DECL int yylex \ - (YYSTYPE * yylval_param, YYLTYPE * yylloc_param , yyscan_t yyscanner) -#endif /* !YY_DECL */ - -/* 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 - -/** The main scanner function which does all the work. - */ -YY_DECL -{ - register yy_state_type yy_current_state; - register char *yy_cp, *yy_bp; - register int yy_act; - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; - -#line 157 "program_lexer.l" - - -#line 1400 "lex.yy.c" - - yylval = yylval_param; - - yylloc = yylloc_param; - - if ( !yyg->yy_init ) - { - yyg->yy_init = 1; - -#ifdef YY_USER_INIT - YY_USER_INIT; -#endif - - if ( ! yyg->yy_start ) - yyg->yy_start = 1; /* first start state */ - - if ( ! yyin ) - yyin = stdin; - - if ( ! yyout ) - yyout = stdout; - - if ( ! YY_CURRENT_BUFFER ) { - yyensure_buffer_stack (yyscanner); - YY_CURRENT_BUFFER_LVALUE = - yy_create_buffer(yyin,YY_BUF_SIZE ,yyscanner); - } - - yy_load_buffer_state(yyscanner ); - } - - while ( 1 ) /* loops until end-of-file is reached */ - { - yy_cp = yyg->yy_c_buf_p; - - /* Support of yytext. */ - *yy_cp = yyg->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 = yyg->yy_start; -yy_match: - do - { - register YY_CHAR yy_c = yy_ec[YY_SC_TO_UI(*yy_cp)]; - if ( yy_accept[yy_current_state] ) - { - yyg->yy_last_accepting_state = yy_current_state; - yyg->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 >= 850 ) - 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] != 1300 ); - -yy_find_action: - yy_act = yy_accept[yy_current_state]; - if ( yy_act == 0 ) - { /* have to back up */ - yy_cp = yyg->yy_last_accepting_cpos; - yy_current_state = yyg->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 = yyg->yy_hold_char; - yy_cp = yyg->yy_last_accepting_cpos; - yy_current_state = yyg->yy_last_accepting_state; - goto yy_find_action; - -case 1: -YY_RULE_SETUP -#line 159 "program_lexer.l" -{ return ARBvp_10; } - YY_BREAK -case 2: -YY_RULE_SETUP -#line 160 "program_lexer.l" -{ return ARBfp_10; } - YY_BREAK -case 3: -YY_RULE_SETUP -#line 161 "program_lexer.l" -{ - yylval->integer = at_address; - return_token_or_IDENTIFIER(require_ARB_vp, ADDRESS); -} - YY_BREAK -case 4: -YY_RULE_SETUP -#line 165 "program_lexer.l" -{ return ALIAS; } - YY_BREAK -case 5: -YY_RULE_SETUP -#line 166 "program_lexer.l" -{ return ATTRIB; } - YY_BREAK -case 6: -YY_RULE_SETUP -#line 167 "program_lexer.l" -{ return END; } - YY_BREAK -case 7: -YY_RULE_SETUP -#line 168 "program_lexer.l" -{ return OPTION; } - YY_BREAK -case 8: -YY_RULE_SETUP -#line 169 "program_lexer.l" -{ return OUTPUT; } - YY_BREAK -case 9: -YY_RULE_SETUP -#line 170 "program_lexer.l" -{ return PARAM; } - YY_BREAK -case 10: -YY_RULE_SETUP -#line 171 "program_lexer.l" -{ yylval->integer = at_temp; return TEMP; } - YY_BREAK -case 11: -YY_RULE_SETUP -#line 173 "program_lexer.l" -{ return_opcode( 1, VECTOR_OP, ABS, 3); } - YY_BREAK -case 12: -YY_RULE_SETUP -#line 174 "program_lexer.l" -{ return_opcode( 1, BIN_OP, ADD, 3); } - YY_BREAK -case 13: -YY_RULE_SETUP -#line 175 "program_lexer.l" -{ return_opcode(require_ARB_vp, ARL, ARL, 3); } - YY_BREAK -case 14: -YY_RULE_SETUP -#line 177 "program_lexer.l" -{ return_opcode(require_ARB_fp, TRI_OP, CMP, 3); } - YY_BREAK -case 15: -YY_RULE_SETUP -#line 178 "program_lexer.l" -{ return_opcode(require_ARB_fp, SCALAR_OP, COS, 3); } - YY_BREAK -case 16: -YY_RULE_SETUP -#line 180 "program_lexer.l" -{ return_opcode(require_NV_fp, VECTOR_OP, DDX, 3); } - YY_BREAK -case 17: -YY_RULE_SETUP -#line 181 "program_lexer.l" -{ return_opcode(require_NV_fp, VECTOR_OP, DDY, 3); } - YY_BREAK -case 18: -YY_RULE_SETUP -#line 182 "program_lexer.l" -{ return_opcode( 1, BIN_OP, DP3, 3); } - YY_BREAK -case 19: -YY_RULE_SETUP -#line 183 "program_lexer.l" -{ return_opcode( 1, BIN_OP, DP4, 3); } - YY_BREAK -case 20: -YY_RULE_SETUP -#line 184 "program_lexer.l" -{ return_opcode( 1, BIN_OP, DPH, 3); } - YY_BREAK -case 21: -YY_RULE_SETUP -#line 185 "program_lexer.l" -{ return_opcode( 1, BIN_OP, DST, 3); } - YY_BREAK -case 22: -YY_RULE_SETUP -#line 187 "program_lexer.l" -{ return_opcode( 1, SCALAR_OP, EX2, 3); } - YY_BREAK -case 23: -YY_RULE_SETUP -#line 188 "program_lexer.l" -{ return_opcode(require_ARB_vp, SCALAR_OP, EXP, 3); } - YY_BREAK -case 24: -YY_RULE_SETUP -#line 190 "program_lexer.l" -{ return_opcode( 1, VECTOR_OP, FLR, 3); } - YY_BREAK -case 25: -YY_RULE_SETUP -#line 191 "program_lexer.l" -{ return_opcode( 1, VECTOR_OP, FRC, 3); } - YY_BREAK -case 26: -YY_RULE_SETUP -#line 193 "program_lexer.l" -{ return_opcode(require_ARB_fp, KIL, KIL, 3); } - YY_BREAK -case 27: -YY_RULE_SETUP -#line 195 "program_lexer.l" -{ return_opcode( 1, VECTOR_OP, LIT, 3); } - YY_BREAK -case 28: -YY_RULE_SETUP -#line 196 "program_lexer.l" -{ return_opcode( 1, SCALAR_OP, LG2, 3); } - YY_BREAK -case 29: -YY_RULE_SETUP -#line 197 "program_lexer.l" -{ return_opcode(require_ARB_vp, SCALAR_OP, LOG, 3); } - YY_BREAK -case 30: -YY_RULE_SETUP -#line 198 "program_lexer.l" -{ return_opcode(require_ARB_fp, TRI_OP, LRP, 3); } - YY_BREAK -case 31: -YY_RULE_SETUP -#line 200 "program_lexer.l" -{ return_opcode( 1, TRI_OP, MAD, 3); } - YY_BREAK -case 32: -YY_RULE_SETUP -#line 201 "program_lexer.l" -{ return_opcode( 1, BIN_OP, MAX, 3); } - YY_BREAK -case 33: -YY_RULE_SETUP -#line 202 "program_lexer.l" -{ return_opcode( 1, BIN_OP, MIN, 3); } - YY_BREAK -case 34: -YY_RULE_SETUP -#line 203 "program_lexer.l" -{ return_opcode( 1, VECTOR_OP, MOV, 3); } - YY_BREAK -case 35: -YY_RULE_SETUP -#line 204 "program_lexer.l" -{ return_opcode( 1, BIN_OP, MUL, 3); } - YY_BREAK -case 36: -YY_RULE_SETUP -#line 206 "program_lexer.l" -{ return_opcode(require_NV_fp, VECTOR_OP, PK2H, 4); } - YY_BREAK -case 37: -YY_RULE_SETUP -#line 207 "program_lexer.l" -{ return_opcode(require_NV_fp, VECTOR_OP, PK2US, 5); } - YY_BREAK -case 38: -YY_RULE_SETUP -#line 208 "program_lexer.l" -{ return_opcode(require_NV_fp, VECTOR_OP, PK4B, 4); } - YY_BREAK -case 39: -YY_RULE_SETUP -#line 209 "program_lexer.l" -{ return_opcode(require_NV_fp, VECTOR_OP, PK4UB, 5); } - YY_BREAK -case 40: -YY_RULE_SETUP -#line 210 "program_lexer.l" -{ return_opcode( 1, BINSC_OP, POW, 3); } - YY_BREAK -case 41: -YY_RULE_SETUP -#line 212 "program_lexer.l" -{ return_opcode( 1, SCALAR_OP, RCP, 3); } - YY_BREAK -case 42: -YY_RULE_SETUP -#line 213 "program_lexer.l" -{ return_opcode(require_NV_fp, BIN_OP, RFL, 3); } - YY_BREAK -case 43: -YY_RULE_SETUP -#line 214 "program_lexer.l" -{ return_opcode( 1, SCALAR_OP, RSQ, 3); } - YY_BREAK -case 44: -YY_RULE_SETUP -#line 216 "program_lexer.l" -{ return_opcode(require_ARB_fp, SCALAR_OP, SCS, 3); } - YY_BREAK -case 45: -YY_RULE_SETUP -#line 217 "program_lexer.l" -{ return_opcode(require_NV_fp, BIN_OP, SEQ, 3); } - YY_BREAK -case 46: -YY_RULE_SETUP -#line 218 "program_lexer.l" -{ return_opcode(require_NV_fp, BIN_OP, SFL, 3); } - YY_BREAK -case 47: -YY_RULE_SETUP -#line 219 "program_lexer.l" -{ return_opcode( 1, BIN_OP, SGE, 3); } - YY_BREAK -case 48: -YY_RULE_SETUP -#line 220 "program_lexer.l" -{ return_opcode(require_NV_fp, BIN_OP, SGT, 3); } - YY_BREAK -case 49: -YY_RULE_SETUP -#line 221 "program_lexer.l" -{ return_opcode(require_ARB_fp, SCALAR_OP, SIN, 3); } - YY_BREAK -case 50: -YY_RULE_SETUP -#line 222 "program_lexer.l" -{ return_opcode(require_NV_fp, BIN_OP, SLE, 3); } - YY_BREAK -case 51: -YY_RULE_SETUP -#line 223 "program_lexer.l" -{ return_opcode( 1, BIN_OP, SLT, 3); } - YY_BREAK -case 52: -YY_RULE_SETUP -#line 224 "program_lexer.l" -{ return_opcode(require_NV_fp, BIN_OP, SNE, 3); } - YY_BREAK -case 53: -YY_RULE_SETUP -#line 225 "program_lexer.l" -{ return_opcode(require_NV_fp, BIN_OP, STR, 3); } - YY_BREAK -case 54: -YY_RULE_SETUP -#line 226 "program_lexer.l" -{ return_opcode( 1, BIN_OP, SUB, 3); } - YY_BREAK -case 55: -YY_RULE_SETUP -#line 227 "program_lexer.l" -{ return_opcode( 1, SWZ, SWZ, 3); } - YY_BREAK -case 56: -YY_RULE_SETUP -#line 229 "program_lexer.l" -{ return_opcode(require_ARB_fp, SAMPLE_OP, TEX, 3); } - YY_BREAK -case 57: -YY_RULE_SETUP -#line 230 "program_lexer.l" -{ return_opcode(require_ARB_fp, SAMPLE_OP, TXB, 3); } - YY_BREAK -case 58: -YY_RULE_SETUP -#line 231 "program_lexer.l" -{ return_opcode(require_NV_fp, TXD_OP, TXD, 3); } - YY_BREAK -case 59: -YY_RULE_SETUP -#line 232 "program_lexer.l" -{ return_opcode(require_ARB_fp, SAMPLE_OP, TXP, 3); } - YY_BREAK -case 60: -YY_RULE_SETUP -#line 234 "program_lexer.l" -{ return_opcode(require_NV_fp, SCALAR_OP, UP2H, 4); } - YY_BREAK -case 61: -YY_RULE_SETUP -#line 235 "program_lexer.l" -{ return_opcode(require_NV_fp, SCALAR_OP, UP2US, 5); } - YY_BREAK -case 62: -YY_RULE_SETUP -#line 236 "program_lexer.l" -{ return_opcode(require_NV_fp, SCALAR_OP, UP4B, 4); } - YY_BREAK -case 63: -YY_RULE_SETUP -#line 237 "program_lexer.l" -{ return_opcode(require_NV_fp, SCALAR_OP, UP4UB, 5); } - YY_BREAK -case 64: -YY_RULE_SETUP -#line 239 "program_lexer.l" -{ return_opcode(require_NV_fp, TRI_OP, X2D, 3); } - YY_BREAK -case 65: -YY_RULE_SETUP -#line 240 "program_lexer.l" -{ return_opcode( 1, BIN_OP, XPD, 3); } - YY_BREAK -case 66: -YY_RULE_SETUP -#line 242 "program_lexer.l" -{ return_token_or_IDENTIFIER(require_ARB_vp, VERTEX); } - YY_BREAK -case 67: -YY_RULE_SETUP -#line 243 "program_lexer.l" -{ return_token_or_IDENTIFIER(require_ARB_fp, FRAGMENT); } - YY_BREAK -case 68: -YY_RULE_SETUP -#line 244 "program_lexer.l" -{ return PROGRAM; } - YY_BREAK -case 69: -YY_RULE_SETUP -#line 245 "program_lexer.l" -{ return STATE; } - YY_BREAK -case 70: -YY_RULE_SETUP -#line 246 "program_lexer.l" -{ return RESULT; } - YY_BREAK -case 71: -YY_RULE_SETUP -#line 248 "program_lexer.l" -{ return AMBIENT; } - YY_BREAK -case 72: -YY_RULE_SETUP -#line 249 "program_lexer.l" -{ return ATTENUATION; } - YY_BREAK -case 73: -YY_RULE_SETUP -#line 250 "program_lexer.l" -{ return BACK; } - YY_BREAK -case 74: -YY_RULE_SETUP -#line 251 "program_lexer.l" -{ return_token_or_DOT(require_ARB_vp, CLIP); } - YY_BREAK -case 75: -YY_RULE_SETUP -#line 252 "program_lexer.l" -{ return COLOR; } - YY_BREAK -case 76: -YY_RULE_SETUP -#line 253 "program_lexer.l" -{ return_token_or_DOT(require_ARB_fp, DEPTH); } - YY_BREAK -case 77: -YY_RULE_SETUP -#line 254 "program_lexer.l" -{ return DIFFUSE; } - YY_BREAK -case 78: -YY_RULE_SETUP -#line 255 "program_lexer.l" -{ return DIRECTION; } - YY_BREAK -case 79: -YY_RULE_SETUP -#line 256 "program_lexer.l" -{ return EMISSION; } - YY_BREAK -case 80: -YY_RULE_SETUP -#line 257 "program_lexer.l" -{ return ENV; } - YY_BREAK -case 81: -YY_RULE_SETUP -#line 258 "program_lexer.l" -{ return EYE; } - YY_BREAK -case 82: -YY_RULE_SETUP -#line 259 "program_lexer.l" -{ return FOGCOORD; } - YY_BREAK -case 83: -YY_RULE_SETUP -#line 260 "program_lexer.l" -{ return FOG; } - YY_BREAK -case 84: -YY_RULE_SETUP -#line 261 "program_lexer.l" -{ return FRONT; } - YY_BREAK -case 85: -YY_RULE_SETUP -#line 262 "program_lexer.l" -{ return HALF; } - YY_BREAK -case 86: -YY_RULE_SETUP -#line 263 "program_lexer.l" -{ return INVERSE; } - YY_BREAK -case 87: -YY_RULE_SETUP -#line 264 "program_lexer.l" -{ return INVTRANS; } - YY_BREAK -case 88: -YY_RULE_SETUP -#line 265 "program_lexer.l" -{ return LIGHT; } - YY_BREAK -case 89: -YY_RULE_SETUP -#line 266 "program_lexer.l" -{ return LIGHTMODEL; } - YY_BREAK -case 90: -YY_RULE_SETUP -#line 267 "program_lexer.l" -{ return LIGHTPROD; } - YY_BREAK -case 91: -YY_RULE_SETUP -#line 268 "program_lexer.l" -{ return LOCAL; } - YY_BREAK -case 92: -YY_RULE_SETUP -#line 269 "program_lexer.l" -{ return MATERIAL; } - YY_BREAK -case 93: -YY_RULE_SETUP -#line 270 "program_lexer.l" -{ return MAT_PROGRAM; } - YY_BREAK -case 94: -YY_RULE_SETUP -#line 271 "program_lexer.l" -{ return MATRIX; } - YY_BREAK -case 95: -YY_RULE_SETUP -#line 272 "program_lexer.l" -{ return_token_or_DOT(require_ARB_vp, MATRIXINDEX); } - YY_BREAK -case 96: -YY_RULE_SETUP -#line 273 "program_lexer.l" -{ return MODELVIEW; } - YY_BREAK -case 97: -YY_RULE_SETUP -#line 274 "program_lexer.l" -{ return MVP; } - YY_BREAK -case 98: -YY_RULE_SETUP -#line 275 "program_lexer.l" -{ return_token_or_DOT(require_ARB_vp, NORMAL); } - YY_BREAK -case 99: -YY_RULE_SETUP -#line 276 "program_lexer.l" -{ return OBJECT; } - YY_BREAK -case 100: -YY_RULE_SETUP -#line 277 "program_lexer.l" -{ return PALETTE; } - YY_BREAK -case 101: -YY_RULE_SETUP -#line 278 "program_lexer.l" -{ return PARAMS; } - YY_BREAK -case 102: -YY_RULE_SETUP -#line 279 "program_lexer.l" -{ return PLANE; } - YY_BREAK -case 103: -YY_RULE_SETUP -#line 280 "program_lexer.l" -{ return_token_or_DOT(require_ARB_vp, POINT_TOK); } - YY_BREAK -case 104: -YY_RULE_SETUP -#line 281 "program_lexer.l" -{ return_token_or_DOT(require_ARB_vp, POINTSIZE); } - YY_BREAK -case 105: -YY_RULE_SETUP -#line 282 "program_lexer.l" -{ return POSITION; } - YY_BREAK -case 106: -YY_RULE_SETUP -#line 283 "program_lexer.l" -{ return PRIMARY; } - YY_BREAK -case 107: -YY_RULE_SETUP -#line 284 "program_lexer.l" -{ return PROJECTION; } - YY_BREAK -case 108: -YY_RULE_SETUP -#line 285 "program_lexer.l" -{ return_token_or_DOT(require_ARB_fp, RANGE); } - YY_BREAK -case 109: -YY_RULE_SETUP -#line 286 "program_lexer.l" -{ return ROW; } - YY_BREAK -case 110: -YY_RULE_SETUP -#line 287 "program_lexer.l" -{ return SCENECOLOR; } - YY_BREAK -case 111: -YY_RULE_SETUP -#line 288 "program_lexer.l" -{ return SECONDARY; } - YY_BREAK -case 112: -YY_RULE_SETUP -#line 289 "program_lexer.l" -{ return SHININESS; } - YY_BREAK -case 113: -YY_RULE_SETUP -#line 290 "program_lexer.l" -{ return_token_or_DOT(require_ARB_vp, SIZE_TOK); } - YY_BREAK -case 114: -YY_RULE_SETUP -#line 291 "program_lexer.l" -{ return SPECULAR; } - YY_BREAK -case 115: -YY_RULE_SETUP -#line 292 "program_lexer.l" -{ return SPOT; } - YY_BREAK -case 116: -YY_RULE_SETUP -#line 293 "program_lexer.l" -{ return TEXCOORD; } - YY_BREAK -case 117: -YY_RULE_SETUP -#line 294 "program_lexer.l" -{ return_token_or_DOT(require_ARB_fp, TEXENV); } - YY_BREAK -case 118: -YY_RULE_SETUP -#line 295 "program_lexer.l" -{ return_token_or_DOT(require_ARB_vp, TEXGEN); } - YY_BREAK -case 119: -YY_RULE_SETUP -#line 296 "program_lexer.l" -{ return_token_or_DOT(require_ARB_vp, TEXGEN_Q); } - YY_BREAK -case 120: -YY_RULE_SETUP -#line 297 "program_lexer.l" -{ return_token_or_DOT(require_ARB_vp, TEXGEN_S); } - YY_BREAK -case 121: -YY_RULE_SETUP -#line 298 "program_lexer.l" -{ return_token_or_DOT(require_ARB_vp, TEXGEN_T); } - YY_BREAK -case 122: -YY_RULE_SETUP -#line 299 "program_lexer.l" -{ return TEXTURE; } - YY_BREAK -case 123: -YY_RULE_SETUP -#line 300 "program_lexer.l" -{ return TRANSPOSE; } - YY_BREAK -case 124: -YY_RULE_SETUP -#line 301 "program_lexer.l" -{ return_token_or_DOT(require_ARB_vp, VTXATTRIB); } - YY_BREAK -case 125: -YY_RULE_SETUP -#line 302 "program_lexer.l" -{ return_token_or_DOT(require_ARB_vp, WEIGHT); } - YY_BREAK -case 126: -YY_RULE_SETUP -#line 304 "program_lexer.l" -{ return_token_or_IDENTIFIER(require_ARB_fp, TEXTURE_UNIT); } - YY_BREAK -case 127: -YY_RULE_SETUP -#line 305 "program_lexer.l" -{ return_token_or_IDENTIFIER(require_ARB_fp, TEX_1D); } - YY_BREAK -case 128: -YY_RULE_SETUP -#line 306 "program_lexer.l" -{ return_token_or_IDENTIFIER(require_ARB_fp, TEX_2D); } - YY_BREAK -case 129: -YY_RULE_SETUP -#line 307 "program_lexer.l" -{ return_token_or_IDENTIFIER(require_ARB_fp, TEX_3D); } - YY_BREAK -case 130: -YY_RULE_SETUP -#line 308 "program_lexer.l" -{ return_token_or_IDENTIFIER(require_ARB_fp, TEX_CUBE); } - YY_BREAK -case 131: -YY_RULE_SETUP -#line 309 "program_lexer.l" -{ return_token_or_IDENTIFIER(require_ARB_fp && require_rect, TEX_RECT); } - YY_BREAK -case 132: -YY_RULE_SETUP -#line 310 "program_lexer.l" -{ return_token_or_IDENTIFIER(require_ARB_fp && require_shadow, TEX_SHADOW1D); } - YY_BREAK -case 133: -YY_RULE_SETUP -#line 311 "program_lexer.l" -{ return_token_or_IDENTIFIER(require_ARB_fp && require_shadow, TEX_SHADOW2D); } - YY_BREAK -case 134: -YY_RULE_SETUP -#line 312 "program_lexer.l" -{ return_token_or_IDENTIFIER(require_ARB_fp && require_shadow && require_rect, TEX_SHADOWRECT); } - YY_BREAK -case 135: -YY_RULE_SETUP -#line 313 "program_lexer.l" -{ return_token_or_IDENTIFIER(require_ARB_fp && require_texarray, TEX_ARRAY1D); } - YY_BREAK -case 136: -YY_RULE_SETUP -#line 314 "program_lexer.l" -{ return_token_or_IDENTIFIER(require_ARB_fp && require_texarray, TEX_ARRAY2D); } - YY_BREAK -case 137: -YY_RULE_SETUP -#line 315 "program_lexer.l" -{ return_token_or_IDENTIFIER(require_ARB_fp && require_shadow && require_texarray, TEX_ARRAYSHADOW1D); } - YY_BREAK -case 138: -YY_RULE_SETUP -#line 316 "program_lexer.l" -{ return_token_or_IDENTIFIER(require_ARB_fp && require_shadow && require_texarray, TEX_ARRAYSHADOW2D); } - YY_BREAK -case 139: -YY_RULE_SETUP -#line 318 "program_lexer.l" -{ return handle_ident(yyextra, yytext, yylval); } - YY_BREAK -case 140: -YY_RULE_SETUP -#line 320 "program_lexer.l" -{ return DOT_DOT; } - YY_BREAK -case 141: -YY_RULE_SETUP -#line 322 "program_lexer.l" -{ - yylval->integer = strtol(yytext, NULL, 10); - return INTEGER; -} - YY_BREAK -case 142: -YY_RULE_SETUP -#line 326 "program_lexer.l" -{ - yylval->real = _mesa_strtof(yytext, NULL); - return REAL; -} - YY_BREAK -case 143: -/* rule 143 can match eol */ -*yy_cp = yyg->yy_hold_char; /* undo effects of setting up yytext */ -yyg->yy_c_buf_p = yy_cp -= 1; -YY_DO_BEFORE_ACTION; /* set up yytext again */ -YY_RULE_SETUP -#line 330 "program_lexer.l" -{ - yylval->real = _mesa_strtof(yytext, NULL); - return REAL; -} - YY_BREAK -case 144: -YY_RULE_SETUP -#line 334 "program_lexer.l" -{ - yylval->real = _mesa_strtof(yytext, NULL); - return REAL; -} - YY_BREAK -case 145: -YY_RULE_SETUP -#line 338 "program_lexer.l" -{ - yylval->real = _mesa_strtof(yytext, NULL); - return REAL; -} - YY_BREAK -case 146: -YY_RULE_SETUP -#line 343 "program_lexer.l" -{ - yylval->swiz_mask.swizzle = SWIZZLE_NOOP; - yylval->swiz_mask.mask = WRITEMASK_XYZW; - return MASK4; -} - YY_BREAK -case 147: -YY_RULE_SETUP -#line 349 "program_lexer.l" -{ - yylval->swiz_mask.swizzle = SWIZZLE_INVAL; - yylval->swiz_mask.mask = WRITEMASK_XY - | mask_from_char(yytext[3]); - return MASK3; -} - YY_BREAK -case 148: -YY_RULE_SETUP -#line 355 "program_lexer.l" -{ - yylval->swiz_mask.swizzle = SWIZZLE_INVAL; - yylval->swiz_mask.mask = WRITEMASK_XZW; - return MASK3; -} - YY_BREAK -case 149: -YY_RULE_SETUP -#line 360 "program_lexer.l" -{ - yylval->swiz_mask.swizzle = SWIZZLE_INVAL; - yylval->swiz_mask.mask = WRITEMASK_YZW; - return MASK3; -} - YY_BREAK -case 150: -YY_RULE_SETUP -#line 366 "program_lexer.l" -{ - yylval->swiz_mask.swizzle = SWIZZLE_INVAL; - yylval->swiz_mask.mask = WRITEMASK_X - | mask_from_char(yytext[2]); - return MASK2; -} - YY_BREAK -case 151: -YY_RULE_SETUP -#line 372 "program_lexer.l" -{ - yylval->swiz_mask.swizzle = SWIZZLE_INVAL; - yylval->swiz_mask.mask = WRITEMASK_Y - | mask_from_char(yytext[2]); - return MASK2; -} - YY_BREAK -case 152: -YY_RULE_SETUP -#line 378 "program_lexer.l" -{ - yylval->swiz_mask.swizzle = SWIZZLE_INVAL; - yylval->swiz_mask.mask = WRITEMASK_ZW; - return MASK2; -} - YY_BREAK -case 153: -YY_RULE_SETUP -#line 384 "program_lexer.l" -{ - const unsigned s = swiz_from_char(yytext[1]); - yylval->swiz_mask.swizzle = MAKE_SWIZZLE4(s, s, s, s); - yylval->swiz_mask.mask = mask_from_char(yytext[1]); - return MASK1; -} - YY_BREAK -case 154: -YY_RULE_SETUP -#line 391 "program_lexer.l" -{ - yylval->swiz_mask.swizzle = MAKE_SWIZZLE4(swiz_from_char(yytext[1]), - swiz_from_char(yytext[2]), - swiz_from_char(yytext[3]), - swiz_from_char(yytext[4])); - yylval->swiz_mask.mask = 0; - return SWIZZLE; -} - YY_BREAK -case 155: -YY_RULE_SETUP -#line 400 "program_lexer.l" -{ - yylval->swiz_mask.swizzle = SWIZZLE_NOOP; - yylval->swiz_mask.mask = WRITEMASK_XYZW; - return_token_or_DOT(require_ARB_fp, MASK4); -} - YY_BREAK -case 156: -YY_RULE_SETUP -#line 406 "program_lexer.l" -{ - yylval->swiz_mask.swizzle = SWIZZLE_INVAL; - yylval->swiz_mask.mask = WRITEMASK_XY - | mask_from_char(yytext[3]); - return_token_or_DOT(require_ARB_fp, MASK3); -} - YY_BREAK -case 157: -YY_RULE_SETUP -#line 412 "program_lexer.l" -{ - yylval->swiz_mask.swizzle = SWIZZLE_INVAL; - yylval->swiz_mask.mask = WRITEMASK_XZW; - return_token_or_DOT(require_ARB_fp, MASK3); -} - YY_BREAK -case 158: -YY_RULE_SETUP -#line 417 "program_lexer.l" -{ - yylval->swiz_mask.swizzle = SWIZZLE_INVAL; - yylval->swiz_mask.mask = WRITEMASK_YZW; - return_token_or_DOT(require_ARB_fp, MASK3); -} - YY_BREAK -case 159: -YY_RULE_SETUP -#line 423 "program_lexer.l" -{ - yylval->swiz_mask.swizzle = SWIZZLE_INVAL; - yylval->swiz_mask.mask = WRITEMASK_X - | mask_from_char(yytext[2]); - return_token_or_DOT(require_ARB_fp, MASK2); -} - YY_BREAK -case 160: -YY_RULE_SETUP -#line 429 "program_lexer.l" -{ - yylval->swiz_mask.swizzle = SWIZZLE_INVAL; - yylval->swiz_mask.mask = WRITEMASK_Y - | mask_from_char(yytext[2]); - return_token_or_DOT(require_ARB_fp, MASK2); -} - YY_BREAK -case 161: -YY_RULE_SETUP -#line 435 "program_lexer.l" -{ - yylval->swiz_mask.swizzle = SWIZZLE_INVAL; - yylval->swiz_mask.mask = WRITEMASK_ZW; - return_token_or_DOT(require_ARB_fp, MASK2); -} - YY_BREAK -case 162: -YY_RULE_SETUP -#line 441 "program_lexer.l" -{ - const unsigned s = swiz_from_char(yytext[1]); - yylval->swiz_mask.swizzle = MAKE_SWIZZLE4(s, s, s, s); - yylval->swiz_mask.mask = mask_from_char(yytext[1]); - return_token_or_DOT(require_ARB_fp, MASK1); -} - YY_BREAK -case 163: -YY_RULE_SETUP -#line 449 "program_lexer.l" -{ - if (require_ARB_vp) { - return TEXGEN_R; - } else { - yylval->swiz_mask.swizzle = MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_X, - SWIZZLE_X, SWIZZLE_X); - yylval->swiz_mask.mask = WRITEMASK_X; - return MASK1; - } -} - YY_BREAK -case 164: -YY_RULE_SETUP -#line 460 "program_lexer.l" -{ - yylval->swiz_mask.swizzle = MAKE_SWIZZLE4(swiz_from_char(yytext[1]), - swiz_from_char(yytext[2]), - swiz_from_char(yytext[3]), - swiz_from_char(yytext[4])); - yylval->swiz_mask.mask = 0; - return_token_or_DOT(require_ARB_fp, SWIZZLE); -} - YY_BREAK -case 165: -YY_RULE_SETUP -#line 469 "program_lexer.l" -{ return DOT; } - YY_BREAK -case 166: -/* rule 166 can match eol */ -YY_RULE_SETUP -#line 471 "program_lexer.l" -{ - yylloc->first_line++; - yylloc->first_column = 1; - yylloc->last_line++; - yylloc->last_column = 1; - yylloc->position++; -} - YY_BREAK -case 167: -YY_RULE_SETUP -#line 478 "program_lexer.l" -/* eat whitespace */ ; - YY_BREAK -case 168: -*yy_cp = yyg->yy_hold_char; /* undo effects of setting up yytext */ -yyg->yy_c_buf_p = yy_cp -= 1; -YY_DO_BEFORE_ACTION; /* set up yytext again */ -YY_RULE_SETUP -#line 479 "program_lexer.l" -/* eat comments */ ; - YY_BREAK -case 169: -YY_RULE_SETUP -#line 480 "program_lexer.l" -{ return yytext[0]; } - YY_BREAK -case 170: -YY_RULE_SETUP -#line 481 "program_lexer.l" -ECHO; - YY_BREAK -#line 2464 "lex.yy.c" -case YY_STATE_EOF(INITIAL): - yyterminate(); - - case YY_END_OF_BUFFER: - { - /* Amount of text matched not including the EOB char. */ - int yy_amount_of_matched_text = (int) (yy_cp - yyg->yytext_ptr) - 1; - - /* Undo the effects of YY_DO_BEFORE_ACTION. */ - *yy_cp = yyg->yy_hold_char; - YY_RESTORE_YY_MORE_OFFSET - - if ( YY_CURRENT_BUFFER_LVALUE->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. - */ - yyg->yy_n_chars = YY_CURRENT_BUFFER_LVALUE->yy_n_chars; - YY_CURRENT_BUFFER_LVALUE->yy_input_file = yyin; - YY_CURRENT_BUFFER_LVALUE->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 ( yyg->yy_c_buf_p <= &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[yyg->yy_n_chars] ) - { /* This was really a NUL. */ - yy_state_type yy_next_state; - - yyg->yy_c_buf_p = yyg->yytext_ptr + yy_amount_of_matched_text; - - yy_current_state = yy_get_previous_state( yyscanner ); - - /* 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 , yyscanner); - - yy_bp = yyg->yytext_ptr + YY_MORE_ADJ; - - if ( yy_next_state ) - { - /* Consume the NUL. */ - yy_cp = ++yyg->yy_c_buf_p; - yy_current_state = yy_next_state; - goto yy_match; - } - - else - { - yy_cp = yyg->yy_c_buf_p; - goto yy_find_action; - } - } - - else switch ( yy_get_next_buffer( yyscanner ) ) - { - case EOB_ACT_END_OF_FILE: - { - yyg->yy_did_buffer_switch_on_eof = 0; - - if ( yywrap(yyscanner ) ) - { - /* 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. - */ - yyg->yy_c_buf_p = yyg->yytext_ptr + YY_MORE_ADJ; - - yy_act = YY_STATE_EOF(YY_START); - goto do_action; - } - - else - { - if ( ! yyg->yy_did_buffer_switch_on_eof ) - YY_NEW_FILE; - } - break; - } - - case EOB_ACT_CONTINUE_SCAN: - yyg->yy_c_buf_p = - yyg->yytext_ptr + yy_amount_of_matched_text; - - yy_current_state = yy_get_previous_state( yyscanner ); - - yy_cp = yyg->yy_c_buf_p; - yy_bp = yyg->yytext_ptr + YY_MORE_ADJ; - goto yy_match; - - case EOB_ACT_LAST_MATCH: - yyg->yy_c_buf_p = - &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[yyg->yy_n_chars]; - - yy_current_state = yy_get_previous_state( yyscanner ); - - yy_cp = yyg->yy_c_buf_p; - yy_bp = yyg->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 (yyscan_t yyscanner) -{ - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; - register char *dest = YY_CURRENT_BUFFER_LVALUE->yy_ch_buf; - register char *source = yyg->yytext_ptr; - register int number_to_move, i; - int ret_val; - - if ( yyg->yy_c_buf_p > &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[yyg->yy_n_chars + 1] ) - YY_FATAL_ERROR( - "fatal flex scanner internal error--end of buffer missed" ); - - if ( YY_CURRENT_BUFFER_LVALUE->yy_fill_buffer == 0 ) - { /* Don't try to fill the buffer, so this is an EOF. */ - if ( yyg->yy_c_buf_p - yyg->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) (yyg->yy_c_buf_p - yyg->yytext_ptr) - 1; - - for ( i = 0; i < number_to_move; ++i ) - *(dest++) = *(source++); - - if ( YY_CURRENT_BUFFER_LVALUE->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_LVALUE->yy_n_chars = yyg->yy_n_chars = 0; - - else - { - int num_to_read = - YY_CURRENT_BUFFER_LVALUE->yy_buf_size - number_to_move - 1; - - while ( num_to_read <= 0 ) - { /* Not enough room in the buffer - grow it. */ - - /* just a shorter name for the current buffer */ - YY_BUFFER_STATE b = YY_CURRENT_BUFFER; - - int yy_c_buf_p_offset = - (int) (yyg->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. */ - yyrealloc((void *) b->yy_ch_buf,b->yy_buf_size + 2 ,yyscanner ); - } - 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" ); - - yyg->yy_c_buf_p = &b->yy_ch_buf[yy_c_buf_p_offset]; - - num_to_read = YY_CURRENT_BUFFER_LVALUE->yy_buf_size - - number_to_move - 1; - - } - - if ( num_to_read > YY_READ_BUF_SIZE ) - num_to_read = YY_READ_BUF_SIZE; - - /* Read in more data. */ - YY_INPUT( (&YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move]), - yyg->yy_n_chars, (size_t) num_to_read ); - - YY_CURRENT_BUFFER_LVALUE->yy_n_chars = yyg->yy_n_chars; - } - - if ( yyg->yy_n_chars == 0 ) - { - if ( number_to_move == YY_MORE_ADJ ) - { - ret_val = EOB_ACT_END_OF_FILE; - yyrestart(yyin ,yyscanner); - } - - else - { - ret_val = EOB_ACT_LAST_MATCH; - YY_CURRENT_BUFFER_LVALUE->yy_buffer_status = - YY_BUFFER_EOF_PENDING; - } - } - - else - ret_val = EOB_ACT_CONTINUE_SCAN; - - if ((yy_size_t) (yyg->yy_n_chars + number_to_move) > YY_CURRENT_BUFFER_LVALUE->yy_buf_size) { - /* Extend the array by 50%, plus the number we really need. */ - yy_size_t new_size = yyg->yy_n_chars + number_to_move + (yyg->yy_n_chars >> 1); - YY_CURRENT_BUFFER_LVALUE->yy_ch_buf = (char *) yyrealloc((void *) YY_CURRENT_BUFFER_LVALUE->yy_ch_buf,new_size ,yyscanner ); - if ( ! YY_CURRENT_BUFFER_LVALUE->yy_ch_buf ) - YY_FATAL_ERROR( "out of dynamic memory in yy_get_next_buffer()" ); - } - - yyg->yy_n_chars += number_to_move; - YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[yyg->yy_n_chars] = YY_END_OF_BUFFER_CHAR; - YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[yyg->yy_n_chars + 1] = YY_END_OF_BUFFER_CHAR; - - yyg->yytext_ptr = &YY_CURRENT_BUFFER_LVALUE->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 (yyscan_t yyscanner) -{ - register yy_state_type yy_current_state; - register char *yy_cp; - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; - - yy_current_state = yyg->yy_start; - - for ( yy_cp = yyg->yytext_ptr + YY_MORE_ADJ; yy_cp < yyg->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] ) - { - yyg->yy_last_accepting_state = yy_current_state; - yyg->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 >= 850 ) - 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 ); - */ - static yy_state_type yy_try_NUL_trans (yy_state_type yy_current_state , yyscan_t yyscanner) -{ - register int yy_is_jam; - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; /* This var may be unused depending upon options. */ - register char *yy_cp = yyg->yy_c_buf_p; - - register YY_CHAR yy_c = 1; - if ( yy_accept[yy_current_state] ) - { - yyg->yy_last_accepting_state = yy_current_state; - yyg->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 >= 850 ) - 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 == 849); - - return yy_is_jam ? 0 : yy_current_state; -} - - static void yyunput (int c, register char * yy_bp , yyscan_t yyscanner) -{ - register char *yy_cp; - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; - - yy_cp = yyg->yy_c_buf_p; - - /* undo effects of setting up yytext */ - *yy_cp = yyg->yy_hold_char; - - if ( yy_cp < YY_CURRENT_BUFFER_LVALUE->yy_ch_buf + 2 ) - { /* need to shift things up to make room */ - /* +2 for EOB chars. */ - register int number_to_move = yyg->yy_n_chars + 2; - register char *dest = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[ - YY_CURRENT_BUFFER_LVALUE->yy_buf_size + 2]; - register char *source = - &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move]; - - while ( source > YY_CURRENT_BUFFER_LVALUE->yy_ch_buf ) - *--dest = *--source; - - yy_cp += (int) (dest - source); - yy_bp += (int) (dest - source); - YY_CURRENT_BUFFER_LVALUE->yy_n_chars = - yyg->yy_n_chars = YY_CURRENT_BUFFER_LVALUE->yy_buf_size; - - if ( yy_cp < YY_CURRENT_BUFFER_LVALUE->yy_ch_buf + 2 ) - YY_FATAL_ERROR( "flex scanner push-back overflow" ); - } - - *--yy_cp = (char) c; - - yyg->yytext_ptr = yy_bp; - yyg->yy_hold_char = *yy_cp; - yyg->yy_c_buf_p = yy_cp; -} - -#ifndef YY_NO_INPUT -#ifdef __cplusplus - static int yyinput (yyscan_t yyscanner) -#else - static int input (yyscan_t yyscanner) -#endif - -{ - int c; - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; - - *yyg->yy_c_buf_p = yyg->yy_hold_char; - - if ( *yyg->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 ( yyg->yy_c_buf_p < &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[yyg->yy_n_chars] ) - /* This was really a NUL. */ - *yyg->yy_c_buf_p = '\0'; - - else - { /* need more input */ - int offset = yyg->yy_c_buf_p - yyg->yytext_ptr; - ++yyg->yy_c_buf_p; - - switch ( yy_get_next_buffer( yyscanner ) ) - { - 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 ,yyscanner); - - /*FALLTHROUGH*/ - - case EOB_ACT_END_OF_FILE: - { - if ( yywrap(yyscanner ) ) - return EOF; - - if ( ! yyg->yy_did_buffer_switch_on_eof ) - YY_NEW_FILE; -#ifdef __cplusplus - return yyinput(yyscanner); -#else - return input(yyscanner); -#endif - } - - case EOB_ACT_CONTINUE_SCAN: - yyg->yy_c_buf_p = yyg->yytext_ptr + offset; - break; - } - } - } - - c = *(unsigned char *) yyg->yy_c_buf_p; /* cast for 8-bit char's */ - *yyg->yy_c_buf_p = '\0'; /* preserve yytext */ - yyg->yy_hold_char = *++yyg->yy_c_buf_p; - - return c; -} -#endif /* ifndef YY_NO_INPUT */ - -/** Immediately switch to a different input stream. - * @param input_file A readable stream. - * @param yyscanner The scanner object. - * @note This function does not reset the start condition to @c INITIAL . - */ - void yyrestart (FILE * input_file , yyscan_t yyscanner) -{ - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; - - if ( ! YY_CURRENT_BUFFER ){ - yyensure_buffer_stack (yyscanner); - YY_CURRENT_BUFFER_LVALUE = - yy_create_buffer(yyin,YY_BUF_SIZE ,yyscanner); - } - - yy_init_buffer(YY_CURRENT_BUFFER,input_file ,yyscanner); - yy_load_buffer_state(yyscanner ); -} - -/** Switch to a different input buffer. - * @param new_buffer The new input buffer. - * @param yyscanner The scanner object. - */ - void yy_switch_to_buffer (YY_BUFFER_STATE new_buffer , yyscan_t yyscanner) -{ - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; - - /* TODO. We should be able to replace this entire function body - * with - * yypop_buffer_state(); - * yypush_buffer_state(new_buffer); - */ - yyensure_buffer_stack (yyscanner); - if ( YY_CURRENT_BUFFER == new_buffer ) - return; - - if ( YY_CURRENT_BUFFER ) - { - /* Flush out information for old buffer. */ - *yyg->yy_c_buf_p = yyg->yy_hold_char; - YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = yyg->yy_c_buf_p; - YY_CURRENT_BUFFER_LVALUE->yy_n_chars = yyg->yy_n_chars; - } - - YY_CURRENT_BUFFER_LVALUE = new_buffer; - yy_load_buffer_state(yyscanner ); - - /* 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. - */ - yyg->yy_did_buffer_switch_on_eof = 1; -} - -static void yy_load_buffer_state (yyscan_t yyscanner) -{ - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; - yyg->yy_n_chars = YY_CURRENT_BUFFER_LVALUE->yy_n_chars; - yyg->yytext_ptr = yyg->yy_c_buf_p = YY_CURRENT_BUFFER_LVALUE->yy_buf_pos; - yyin = YY_CURRENT_BUFFER_LVALUE->yy_input_file; - yyg->yy_hold_char = *yyg->yy_c_buf_p; -} - -/** Allocate and initialize an input buffer state. - * @param file A readable stream. - * @param size The character buffer size in bytes. When in doubt, use @c YY_BUF_SIZE. - * @param yyscanner The scanner object. - * @return the allocated buffer state. - */ - YY_BUFFER_STATE yy_create_buffer (FILE * file, int size , yyscan_t yyscanner) -{ - YY_BUFFER_STATE b; - - b = (YY_BUFFER_STATE) yyalloc(sizeof( struct yy_buffer_state ) ,yyscanner ); - 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 *) yyalloc(b->yy_buf_size + 2 ,yyscanner ); - 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 ,yyscanner); - - return b; -} - -/** Destroy the buffer. - * @param b a buffer created with yy_create_buffer() - * @param yyscanner The scanner object. - */ - void yy_delete_buffer (YY_BUFFER_STATE b , yyscan_t yyscanner) -{ - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; - - if ( ! b ) - return; - - if ( b == YY_CURRENT_BUFFER ) /* Not sure if we should pop here. */ - YY_CURRENT_BUFFER_LVALUE = (YY_BUFFER_STATE) 0; - - if ( b->yy_is_our_buffer ) - yyfree((void *) b->yy_ch_buf ,yyscanner ); - - yyfree((void *) b ,yyscanner ); -} - -/* Initializes or reinitializes a buffer. - * This function is sometimes called more than once on the same buffer, - * such as during a yyrestart() or at EOF. - */ - static void yy_init_buffer (YY_BUFFER_STATE b, FILE * file , yyscan_t yyscanner) - -{ - int oerrno = errno; - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; - - yy_flush_buffer(b ,yyscanner); - - b->yy_input_file = file; - b->yy_fill_buffer = 1; - - /* If b is the current buffer, then yy_init_buffer was _probably_ - * called from yyrestart() or through yy_get_next_buffer. - * In that case, we don't want to reset the lineno or column. - */ - if (b != YY_CURRENT_BUFFER){ - b->yy_bs_lineno = 1; - b->yy_bs_column = 0; - } - - b->yy_is_interactive = 0; - - errno = oerrno; -} - -/** Discard all buffered characters. On the next scan, YY_INPUT will be called. - * @param b the buffer state to be flushed, usually @c YY_CURRENT_BUFFER. - * @param yyscanner The scanner object. - */ - void yy_flush_buffer (YY_BUFFER_STATE b , yyscan_t yyscanner) -{ - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; - 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(yyscanner ); -} - -/** Pushes the new state onto the stack. The new state becomes - * the current state. This function will allocate the stack - * if necessary. - * @param new_buffer The new state. - * @param yyscanner The scanner object. - */ -void yypush_buffer_state (YY_BUFFER_STATE new_buffer , yyscan_t yyscanner) -{ - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; - if (new_buffer == NULL) - return; - - yyensure_buffer_stack(yyscanner); - - /* This block is copied from yy_switch_to_buffer. */ - if ( YY_CURRENT_BUFFER ) - { - /* Flush out information for old buffer. */ - *yyg->yy_c_buf_p = yyg->yy_hold_char; - YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = yyg->yy_c_buf_p; - YY_CURRENT_BUFFER_LVALUE->yy_n_chars = yyg->yy_n_chars; - } - - /* Only push if top exists. Otherwise, replace top. */ - if (YY_CURRENT_BUFFER) - yyg->yy_buffer_stack_top++; - YY_CURRENT_BUFFER_LVALUE = new_buffer; - - /* copied from yy_switch_to_buffer. */ - yy_load_buffer_state(yyscanner ); - yyg->yy_did_buffer_switch_on_eof = 1; -} - -/** Removes and deletes the top of the stack, if present. - * The next element becomes the new top. - * @param yyscanner The scanner object. - */ -void yypop_buffer_state (yyscan_t yyscanner) -{ - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; - if (!YY_CURRENT_BUFFER) - return; - - yy_delete_buffer(YY_CURRENT_BUFFER ,yyscanner); - YY_CURRENT_BUFFER_LVALUE = NULL; - if (yyg->yy_buffer_stack_top > 0) - --yyg->yy_buffer_stack_top; - - if (YY_CURRENT_BUFFER) { - yy_load_buffer_state(yyscanner ); - yyg->yy_did_buffer_switch_on_eof = 1; - } -} - -/* Allocates the stack if it does not exist. - * Guarantees space for at least one push. - */ -static void yyensure_buffer_stack (yyscan_t yyscanner) -{ - int num_to_alloc; - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; - - if (!yyg->yy_buffer_stack) { - - /* First allocation is just for 2 elements, since we don't know if this - * scanner will even need a stack. We use 2 instead of 1 to avoid an - * immediate realloc on the next call. - */ - num_to_alloc = 1; - yyg->yy_buffer_stack = (struct yy_buffer_state**)yyalloc - (num_to_alloc * sizeof(struct yy_buffer_state*) - , yyscanner); - if ( ! yyg->yy_buffer_stack ) - YY_FATAL_ERROR( "out of dynamic memory in yyensure_buffer_stack()" ); - - memset(yyg->yy_buffer_stack, 0, num_to_alloc * sizeof(struct yy_buffer_state*)); - - yyg->yy_buffer_stack_max = num_to_alloc; - yyg->yy_buffer_stack_top = 0; - return; - } - - if (yyg->yy_buffer_stack_top >= (yyg->yy_buffer_stack_max) - 1){ - - /* Increase the buffer to prepare for a possible push. */ - int grow_size = 8 /* arbitrary grow size */; - - num_to_alloc = yyg->yy_buffer_stack_max + grow_size; - yyg->yy_buffer_stack = (struct yy_buffer_state**)yyrealloc - (yyg->yy_buffer_stack, - num_to_alloc * sizeof(struct yy_buffer_state*) - , yyscanner); - if ( ! yyg->yy_buffer_stack ) - YY_FATAL_ERROR( "out of dynamic memory in yyensure_buffer_stack()" ); - - /* zero only the new slots.*/ - memset(yyg->yy_buffer_stack + yyg->yy_buffer_stack_max, 0, grow_size * sizeof(struct yy_buffer_state*)); - yyg->yy_buffer_stack_max = num_to_alloc; - } -} - -/** Setup the input buffer state to scan directly from a user-specified character buffer. - * @param base the character buffer - * @param size the size in bytes of the character buffer - * @param yyscanner The scanner object. - * @return the newly allocated buffer state object. - */ -YY_BUFFER_STATE yy_scan_buffer (char * base, yy_size_t size , yyscan_t yyscanner) -{ - 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) yyalloc(sizeof( struct yy_buffer_state ) ,yyscanner ); - 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 ,yyscanner ); - - return b; -} - -/** Setup the input buffer state to scan a string. The next call to yylex() will - * scan from a @e copy of @a str. - * @param yystr a NUL-terminated string to scan - * @param yyscanner The scanner object. - * @return the newly allocated buffer state object. - * @note If you want to scan bytes that may contain NUL values, then use - * yy_scan_bytes() instead. - */ -YY_BUFFER_STATE yy_scan_string (yyconst char * yystr , yyscan_t yyscanner) -{ - - return yy_scan_bytes(yystr,strlen(yystr) ,yyscanner); -} - -/** Setup the input buffer state to scan the given bytes. The next call to yylex() will - * scan from a @e copy of @a bytes. - * @param bytes the byte buffer to scan - * @param len the number of bytes in the buffer pointed to by @a bytes. - * @param yyscanner The scanner object. - * @return the newly allocated buffer state object. - */ -YY_BUFFER_STATE yy_scan_bytes (yyconst char * yybytes, int _yybytes_len , yyscan_t yyscanner) -{ - YY_BUFFER_STATE b; - char *buf; - yy_size_t n; - int i; - - /* Get memory for full buffer, including space for trailing EOB's. */ - n = _yybytes_len + 2; - buf = (char *) yyalloc(n ,yyscanner ); - if ( ! buf ) - YY_FATAL_ERROR( "out of dynamic memory in yy_scan_bytes()" ); - - for ( i = 0; i < _yybytes_len; ++i ) - buf[i] = yybytes[i]; - - buf[_yybytes_len] = buf[_yybytes_len+1] = YY_END_OF_BUFFER_CHAR; - - b = yy_scan_buffer(buf,n ,yyscanner); - 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; -} - -#ifndef YY_EXIT_FAILURE -#define YY_EXIT_FAILURE 2 -#endif - -static void yy_fatal_error (yyconst char* msg , yyscan_t yyscanner) -{ - (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. */ \ - int yyless_macro_arg = (n); \ - YY_LESS_LINENO(yyless_macro_arg);\ - yytext[yyleng] = yyg->yy_hold_char; \ - yyg->yy_c_buf_p = yytext + yyless_macro_arg; \ - yyg->yy_hold_char = *yyg->yy_c_buf_p; \ - *yyg->yy_c_buf_p = '\0'; \ - yyleng = yyless_macro_arg; \ - } \ - while ( 0 ) - -/* Accessor methods (get/set functions) to struct members. */ - -/** Get the user-defined data for this scanner. - * @param yyscanner The scanner object. - */ -YY_EXTRA_TYPE yyget_extra (yyscan_t yyscanner) -{ - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; - return yyextra; -} - -/** Get the current line number. - * @param yyscanner The scanner object. - */ -int yyget_lineno (yyscan_t yyscanner) -{ - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; - - if (! YY_CURRENT_BUFFER) - return 0; - - return yylineno; -} - -/** Get the current column number. - * @param yyscanner The scanner object. - */ -int yyget_column (yyscan_t yyscanner) -{ - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; - - if (! YY_CURRENT_BUFFER) - return 0; - - return yycolumn; -} - -/** Get the input stream. - * @param yyscanner The scanner object. - */ -FILE *yyget_in (yyscan_t yyscanner) -{ - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; - return yyin; -} - -/** Get the output stream. - * @param yyscanner The scanner object. - */ -FILE *yyget_out (yyscan_t yyscanner) -{ - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; - return yyout; -} - -/** Get the length of the current token. - * @param yyscanner The scanner object. - */ -int yyget_leng (yyscan_t yyscanner) -{ - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; - return yyleng; -} - -/** Get the current token. - * @param yyscanner The scanner object. - */ - -char *yyget_text (yyscan_t yyscanner) -{ - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; - return yytext; -} - -/** Set the user-defined data. This data is never touched by the scanner. - * @param user_defined The data to be associated with this scanner. - * @param yyscanner The scanner object. - */ -void yyset_extra (YY_EXTRA_TYPE user_defined , yyscan_t yyscanner) -{ - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; - yyextra = user_defined ; -} - -/** Set the current line number. - * @param line_number - * @param yyscanner The scanner object. - */ -void yyset_lineno (int line_number , yyscan_t yyscanner) -{ - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; - - /* lineno is only valid if an input buffer exists. */ - if (! YY_CURRENT_BUFFER ) - yy_fatal_error( "yyset_lineno called with no buffer" , yyscanner); - - yylineno = line_number; -} - -/** Set the current column. - * @param line_number - * @param yyscanner The scanner object. - */ -void yyset_column (int column_no , yyscan_t yyscanner) -{ - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; - - /* column is only valid if an input buffer exists. */ - if (! YY_CURRENT_BUFFER ) - yy_fatal_error( "yyset_column called with no buffer" , yyscanner); - - yycolumn = column_no; -} - -/** Set the input stream. This does not discard the current - * input buffer. - * @param in_str A readable stream. - * @param yyscanner The scanner object. - * @see yy_switch_to_buffer - */ -void yyset_in (FILE * in_str , yyscan_t yyscanner) -{ - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; - yyin = in_str ; -} - -void yyset_out (FILE * out_str , yyscan_t yyscanner) -{ - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; - yyout = out_str ; -} - -int yyget_debug (yyscan_t yyscanner) -{ - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; - return yy_flex_debug; -} - -void yyset_debug (int bdebug , yyscan_t yyscanner) -{ - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; - yy_flex_debug = bdebug ; -} - -/* Accessor methods for yylval and yylloc */ - -YYSTYPE * yyget_lval (yyscan_t yyscanner) -{ - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; - return yylval; -} - -void yyset_lval (YYSTYPE * yylval_param , yyscan_t yyscanner) -{ - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; - yylval = yylval_param; -} - -YYLTYPE *yyget_lloc (yyscan_t yyscanner) -{ - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; - return yylloc; -} - -void yyset_lloc (YYLTYPE * yylloc_param , yyscan_t yyscanner) -{ - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; - yylloc = yylloc_param; -} - -/* User-visible API */ - -/* yylex_init is special because it creates the scanner itself, so it is - * the ONLY reentrant function that doesn't take the scanner as the last argument. - * That's why we explicitly handle the declaration, instead of using our macros. - */ - -int yylex_init(yyscan_t* ptr_yy_globals) - -{ - if (ptr_yy_globals == NULL){ - errno = EINVAL; - return 1; - } - - *ptr_yy_globals = (yyscan_t) yyalloc ( sizeof( struct yyguts_t ), NULL ); - - if (*ptr_yy_globals == NULL){ - errno = ENOMEM; - return 1; - } - - /* By setting to 0xAA, we expose bugs in yy_init_globals. Leave at 0x00 for releases. */ - memset(*ptr_yy_globals,0x00,sizeof(struct yyguts_t)); - - return yy_init_globals ( *ptr_yy_globals ); -} - -/* yylex_init_extra has the same functionality as yylex_init, but follows the - * convention of taking the scanner as the last argument. Note however, that - * this is a *pointer* to a scanner, as it will be allocated by this call (and - * is the reason, too, why this function also must handle its own declaration). - * The user defined value in the first argument will be available to yyalloc in - * the yyextra field. - */ - -int yylex_init_extra(YY_EXTRA_TYPE yy_user_defined,yyscan_t* ptr_yy_globals ) - -{ - struct yyguts_t dummy_yyguts; - - yyset_extra (yy_user_defined, &dummy_yyguts); - - if (ptr_yy_globals == NULL){ - errno = EINVAL; - return 1; - } - - *ptr_yy_globals = (yyscan_t) yyalloc ( sizeof( struct yyguts_t ), &dummy_yyguts ); - - if (*ptr_yy_globals == NULL){ - errno = ENOMEM; - return 1; - } - - /* By setting to 0xAA, we expose bugs in - yy_init_globals. Leave at 0x00 for releases. */ - memset(*ptr_yy_globals,0x00,sizeof(struct yyguts_t)); - - yyset_extra (yy_user_defined, *ptr_yy_globals); - - return yy_init_globals ( *ptr_yy_globals ); -} - -static int yy_init_globals (yyscan_t yyscanner) -{ - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; - /* Initialization is the same as for the non-reentrant scanner. - * This function is called from yylex_destroy(), so don't allocate here. - */ - - yyg->yy_buffer_stack = 0; - yyg->yy_buffer_stack_top = 0; - yyg->yy_buffer_stack_max = 0; - yyg->yy_c_buf_p = (char *) 0; - yyg->yy_init = 0; - yyg->yy_start = 0; - - yyg->yy_start_stack_ptr = 0; - yyg->yy_start_stack_depth = 0; - yyg->yy_start_stack = NULL; - -/* Defined in main.c */ -#ifdef YY_STDINIT - yyin = stdin; - yyout = stdout; -#else - yyin = (FILE *) 0; - yyout = (FILE *) 0; -#endif - - /* For future reference: Set errno on error, since we are called by - * yylex_init() - */ - return 0; -} - -/* yylex_destroy is for both reentrant and non-reentrant scanners. */ -int yylex_destroy (yyscan_t yyscanner) -{ - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; - - /* Pop the buffer stack, destroying each element. */ - while(YY_CURRENT_BUFFER){ - yy_delete_buffer(YY_CURRENT_BUFFER ,yyscanner ); - YY_CURRENT_BUFFER_LVALUE = NULL; - yypop_buffer_state(yyscanner); - } - - /* Destroy the stack itself. */ - yyfree(yyg->yy_buffer_stack ,yyscanner); - yyg->yy_buffer_stack = NULL; - - /* Destroy the start condition stack. */ - yyfree(yyg->yy_start_stack ,yyscanner ); - yyg->yy_start_stack = NULL; - - /* Reset the globals. This is important in a non-reentrant scanner so the next time - * yylex() is called, initialization will occur. */ - yy_init_globals( yyscanner); - - /* Destroy the main struct (reentrant only). */ - yyfree ( yyscanner , yyscanner ); - yyscanner = NULL; - return 0; -} - -/* - * Internal utility routines. - */ - -#ifndef yytext_ptr -static void yy_flex_strncpy (char* s1, yyconst char * s2, int n , yyscan_t yyscanner) -{ - register int i; - for ( i = 0; i < n; ++i ) - s1[i] = s2[i]; -} -#endif - -#ifdef YY_NEED_STRLEN -static int yy_flex_strlen (yyconst char * s , yyscan_t yyscanner) -{ - register int n; - for ( n = 0; s[n]; ++n ) - ; - - return n; -} -#endif - -void *yyalloc (yy_size_t size , yyscan_t yyscanner) -{ - return (void *) malloc( size ); -} - -void *yyrealloc (void * ptr, yy_size_t size , yyscan_t yyscanner) -{ - /* 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 ); -} - -void yyfree (void * ptr , yyscan_t yyscanner) -{ - free( (char *) ptr ); /* see yyrealloc() for (char *) cast */ -} - -#define YYTABLES_NAME "yytables" - -#line 481 "program_lexer.l" - - - -void -_mesa_program_lexer_ctor(void **scanner, struct asm_parser_state *state, - const char *string, size_t len) -{ - yylex_init_extra(state,scanner); - yy_scan_bytes(string,len,*scanner); -} - -void -_mesa_program_lexer_dtor(void *scanner) -{ - yylex_destroy(scanner); -} - diff --git a/mesalib/src/mesa/shader/nvfragparse.c b/mesalib/src/mesa/shader/nvfragparse.c deleted file mode 100644 index 0de3c5804..000000000 --- a/mesalib/src/mesa/shader/nvfragparse.c +++ /dev/null @@ -1,1588 +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 nvfragparse.c - * NVIDIA fragment program parser. - * \author Brian Paul - */ - -/* - * 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 "main/glheader.h" -#include "main/context.h" -#include "main/imports.h" -#include "main/macros.h" -#include "program.h" -#include "prog_parameter.h" -#include "prog_print.h" -#include "prog_instruction.h" -#include "nvfragparse.h" - - -#define INPUT_1V 1 -#define INPUT_2V 2 -#define INPUT_3V 3 -#define INPUT_1S 4 -#define INPUT_2S 5 -#define INPUT_CC 6 -#define INPUT_1V_T 7 /* one source vector, plus textureId */ -#define INPUT_3V_T 8 /* one source vector, plus textureId */ -#define INPUT_NONE 9 -#define INPUT_1V_S 10 /* a string and a vector register */ -#define OUTPUT_V 20 -#define OUTPUT_S 21 -#define OUTPUT_NONE 22 - -/* IRIX defines some of these */ -#undef _R -#undef _H -#undef _X -#undef _C -#undef _S - -/* Optional suffixes */ -#define _R FLOAT32 /* float */ -#define _H FLOAT16 /* half-float */ -#define _X FIXED12 /* fixed */ -#define _C 0x08 /* set cond codes */ -#define _S 0x10 /* saturate, clamp result to [0,1] */ - -struct instruction_pattern { - const char *name; - enum prog_opcode opcode; - GLuint inputs; - GLuint outputs; - GLuint suffixes; -}; - -static const struct instruction_pattern Instructions[] = { - { "ADD", OPCODE_ADD, INPUT_2V, OUTPUT_V, _R | _H | _X | _C | _S }, - { "COS", OPCODE_COS, INPUT_1S, OUTPUT_S, _R | _H | _C | _S }, - { "DDX", OPCODE_DDX, INPUT_1V, OUTPUT_V, _R | _H | _C | _S }, - { "DDY", OPCODE_DDY, INPUT_1V, OUTPUT_V, _R | _H | _C | _S }, - { "DP3", OPCODE_DP3, INPUT_2V, OUTPUT_S, _R | _H | _X | _C | _S }, - { "DP4", OPCODE_DP4, INPUT_2V, OUTPUT_S, _R | _H | _X | _C | _S }, - { "DST", OPCODE_DP4, INPUT_2V, OUTPUT_V, _R | _H | _C | _S }, - { "EX2", OPCODE_DP4, INPUT_1S, OUTPUT_S, _R | _H | _C | _S }, - { "FLR", OPCODE_FLR, INPUT_1V, OUTPUT_V, _R | _H | _X | _C | _S }, - { "FRC", OPCODE_FRC, INPUT_1V, OUTPUT_V, _R | _H | _X | _C | _S }, - { "KIL", OPCODE_KIL_NV, INPUT_CC, OUTPUT_NONE, 0 }, - { "LG2", OPCODE_LG2, INPUT_1S, OUTPUT_S, _R | _H | _C | _S }, - { "LIT", OPCODE_LIT, INPUT_1V, OUTPUT_V, _R | _H | _C | _S }, - { "LRP", OPCODE_LRP, INPUT_3V, OUTPUT_V, _R | _H | _X | _C | _S }, - { "MAD", OPCODE_MAD, INPUT_3V, OUTPUT_V, _R | _H | _X | _C | _S }, - { "MAX", OPCODE_MAX, INPUT_2V, OUTPUT_V, _R | _H | _X | _C | _S }, - { "MIN", OPCODE_MIN, INPUT_2V, OUTPUT_V, _R | _H | _X | _C | _S }, - { "MOV", OPCODE_MOV, INPUT_1V, OUTPUT_V, _R | _H | _X | _C | _S }, - { "MUL", OPCODE_MUL, INPUT_2V, OUTPUT_V, _R | _H | _X | _C | _S }, - { "PK2H", OPCODE_PK2H, INPUT_1V, OUTPUT_S, 0 }, - { "PK2US", OPCODE_PK2US, INPUT_1V, OUTPUT_S, 0 }, - { "PK4B", OPCODE_PK4B, INPUT_1V, OUTPUT_S, 0 }, - { "PK4UB", OPCODE_PK4UB, INPUT_1V, OUTPUT_S, 0 }, - { "POW", OPCODE_POW, INPUT_2S, OUTPUT_S, _R | _H | _C | _S }, - { "RCP", OPCODE_RCP, INPUT_1S, OUTPUT_S, _R | _H | _C | _S }, - { "RFL", OPCODE_RFL, INPUT_2V, OUTPUT_V, _R | _H | _C | _S }, - { "RSQ", OPCODE_RSQ, INPUT_1S, OUTPUT_S, _R | _H | _C | _S }, - { "SEQ", OPCODE_SEQ, INPUT_2V, OUTPUT_V, _R | _H | _X | _C | _S }, - { "SFL", OPCODE_SFL, INPUT_2V, OUTPUT_V, _R | _H | _X | _C | _S }, - { "SGE", OPCODE_SGE, INPUT_2V, OUTPUT_V, _R | _H | _X | _C | _S }, - { "SGT", OPCODE_SGT, INPUT_2V, OUTPUT_V, _R | _H | _X | _C | _S }, - { "SIN", OPCODE_SIN, INPUT_1S, OUTPUT_S, _R | _H | _C | _S }, - { "SLE", OPCODE_SLE, INPUT_2V, OUTPUT_V, _R | _H | _X | _C | _S }, - { "SLT", OPCODE_SLT, INPUT_2V, OUTPUT_V, _R | _H | _X | _C | _S }, - { "SNE", OPCODE_SNE, INPUT_2V, OUTPUT_V, _R | _H | _X | _C | _S }, - { "STR", OPCODE_STR, INPUT_2V, OUTPUT_V, _R | _H | _X | _C | _S }, - { "SUB", OPCODE_SUB, INPUT_2V, OUTPUT_V, _R | _H | _X | _C | _S }, - { "TEX", OPCODE_TEX, INPUT_1V_T, OUTPUT_V, _C | _S }, - { "TXD", OPCODE_TXD, INPUT_3V_T, OUTPUT_V, _C | _S }, - { "TXP", OPCODE_TXP_NV, INPUT_1V_T, OUTPUT_V, _C | _S }, - { "UP2H", OPCODE_UP2H, INPUT_1S, OUTPUT_V, _C | _S }, - { "UP2US", OPCODE_UP2US, INPUT_1S, OUTPUT_V, _C | _S }, - { "UP4B", OPCODE_UP4B, INPUT_1S, OUTPUT_V, _C | _S }, - { "UP4UB", OPCODE_UP4UB, INPUT_1S, OUTPUT_V, _C | _S }, - { "X2D", OPCODE_X2D, INPUT_3V, OUTPUT_V, _R | _H | _C | _S }, - { "PRINT", OPCODE_PRINT, INPUT_1V_S, OUTPUT_NONE, 0 }, - { NULL, (enum prog_opcode) -1, 0, 0, 0 } -}; - - -/* - * Information needed or computed during parsing. - * Remember, we can't modify the target program object until we've - * _successfully_ parsed the program text. - */ -struct parse_state { - GLcontext *ctx; - const GLubyte *start; /* start of program string */ - const GLubyte *pos; /* current position */ - const GLubyte *curLine; - struct gl_fragment_program *program; /* current program */ - - struct gl_program_parameter_list *parameters; - - GLuint numInst; /* number of instructions parsed */ - GLuint inputsRead; /* bitmask of input registers used */ - GLuint outputsWritten; /* bitmask of 1 << FRAG_OUTPUT_* bits */ - GLuint texturesUsed[MAX_TEXTURE_IMAGE_UNITS]; -}; - - - -/* - * Called whenever we find an error during parsing. - */ -static void -record_error(struct parse_state *parseState, const char *msg, int lineNo) -{ -#ifdef DEBUG - GLint line, column; - const GLubyte *lineStr; - lineStr = _mesa_find_line_column(parseState->start, - parseState->pos, &line, &column); - _mesa_debug(parseState->ctx, - "nvfragparse.c(%d): line %d, column %d:%s (%s)\n", - lineNo, line, column, (char *) lineStr, msg); - free((void *) lineStr); -#else - (void) lineNo; -#endif - - /* Check that no error was already recorded. Only record the first one. */ - if (parseState->ctx->Program.ErrorString[0] == 0) { - _mesa_set_program_error(parseState->ctx, - parseState->pos - parseState->start, - msg); - } -} - - -#define RETURN_ERROR \ -do { \ - record_error(parseState, "Unexpected end of input.", __LINE__); \ - return GL_FALSE; \ -} while(0) - -#define RETURN_ERROR1(msg) \ -do { \ - record_error(parseState, msg, __LINE__); \ - return GL_FALSE; \ -} while(0) - -#define RETURN_ERROR2(msg1, msg2) \ -do { \ - char err[1000]; \ - sprintf(err, "%s %s", msg1, msg2); \ - record_error(parseState, err, __LINE__); \ - return GL_FALSE; \ -} while(0) - - - - -/* - * Search a list of instruction structures for a match. - */ -static struct instruction_pattern -MatchInstruction(const GLubyte *token) -{ - const struct instruction_pattern *inst; - struct instruction_pattern result; - - result.name = NULL; - result.opcode = MAX_OPCODE; /* i.e. invalid instruction */ - result.inputs = 0; - result.outputs = 0; - result.suffixes = 0; - - for (inst = Instructions; inst->name; inst++) { - if (strncmp((const char *) token, inst->name, 3) == 0) { - /* matched! */ - int i = 3; - result = *inst; - result.suffixes = 0; - /* look at suffix */ - if (token[i] == 'R') { - result.suffixes |= _R; - i++; - } - else if (token[i] == 'H') { - result.suffixes |= _H; - i++; - } - else if (token[i] == 'X') { - result.suffixes |= _X; - i++; - } - if (token[i] == 'C') { - result.suffixes |= _C; - i++; - } - if (token[i] == '_' && token[i+1] == 'S' && - token[i+2] == 'A' && token[i+3] == 'T') { - result.suffixes |= _S; - } - return result; - } - } - - return result; -} - - - - -/**********************************************************************/ - - -static GLboolean IsLetter(GLubyte b) -{ - return (b >= 'a' && b <= 'z') || - (b >= 'A' && b <= 'Z') || - (b == '_') || - (b == '$'); -} - - -static GLboolean IsDigit(GLubyte b) -{ - return b >= '0' && b <= '9'; -} - - -static GLboolean IsWhitespace(GLubyte b) -{ - return b == ' ' || b == '\t' || b == '\n' || b == '\r'; -} - - -/** - * Starting at 'str' find the next token. A token can be an integer, - * an identifier or punctuation symbol. - * \return <= 0 we found an error, else, return number of characters parsed. - */ -static GLint -GetToken(struct parse_state *parseState, GLubyte *token) -{ - const GLubyte *str = parseState->pos; - GLint i = 0, j = 0; - - token[0] = 0; - - /* skip whitespace and comments */ - while (str[i] && (IsWhitespace(str[i]) || str[i] == '#')) { - if (str[i] == '#') { - /* skip comment */ - while (str[i] && (str[i] != '\n' && str[i] != '\r')) { - i++; - } - if (str[i] == '\n' || str[i] == '\r') - parseState->curLine = str + i + 1; - } - else { - /* skip whitespace */ - if (str[i] == '\n' || str[i] == '\r') - parseState->curLine = str + i + 1; - i++; - } - } - - if (str[i] == 0) - return -i; - - /* try matching an integer */ - while (str[i] && IsDigit(str[i])) { - token[j++] = str[i++]; - } - if (j > 0 || !str[i]) { - token[j] = 0; - return i; - } - - /* try matching an identifier */ - if (IsLetter(str[i])) { - while (str[i] && (IsLetter(str[i]) || IsDigit(str[i]))) { - token[j++] = str[i++]; - } - token[j] = 0; - return i; - } - - /* punctuation character */ - if (str[i]) { - token[0] = str[i++]; - token[1] = 0; - return i; - } - - /* end of input */ - token[0] = 0; - return i; -} - - -/** - * Get next token from input stream and increment stream pointer past token. - */ -static GLboolean -Parse_Token(struct parse_state *parseState, GLubyte *token) -{ - GLint i; - i = GetToken(parseState, token); - if (i <= 0) { - parseState->pos += (-i); - return GL_FALSE; - } - parseState->pos += i; - return GL_TRUE; -} - - -/** - * Get next token from input stream but don't increment stream pointer. - */ -static GLboolean -Peek_Token(struct parse_state *parseState, GLubyte *token) -{ - GLint i, len; - i = GetToken(parseState, token); - if (i <= 0) { - parseState->pos += (-i); - return GL_FALSE; - } - len = (GLint) strlen((const char *) token); - parseState->pos += (i - len); - return GL_TRUE; -} - - -/**********************************************************************/ - -static const char *InputRegisters[MAX_NV_FRAGMENT_PROGRAM_INPUTS + 1] = { - "WPOS", "COL0", "COL1", "FOGC", - "TEX0", "TEX1", "TEX2", "TEX3", "TEX4", "TEX5", "TEX6", "TEX7", NULL -}; - - - -/**********************************************************************/ - -/** - * Try to match 'pattern' as the next token after any whitespace/comments. - */ -static GLboolean -Parse_String(struct parse_state *parseState, const char *pattern) -{ - const GLubyte *m; - GLint i; - - /* skip whitespace and comments */ - while (IsWhitespace(*parseState->pos) || *parseState->pos == '#') { - if (*parseState->pos == '#') { - while (*parseState->pos && (*parseState->pos != '\n' && *parseState->pos != '\r')) { - parseState->pos += 1; - } - if (*parseState->pos == '\n' || *parseState->pos == '\r') - parseState->curLine = parseState->pos + 1; - } - else { - /* skip whitespace */ - if (*parseState->pos == '\n' || *parseState->pos == '\r') - parseState->curLine = parseState->pos + 1; - parseState->pos += 1; - } - } - - /* Try to match the pattern */ - m = parseState->pos; - for (i = 0; pattern[i]; i++) { - if (*m != (GLubyte) pattern[i]) - return GL_FALSE; - m += 1; - } - parseState->pos = m; - - return GL_TRUE; /* success */ -} - - -static GLboolean -Parse_Identifier(struct parse_state *parseState, GLubyte *ident) -{ - if (!Parse_Token(parseState, ident)) - RETURN_ERROR; - if (IsLetter(ident[0])) - return GL_TRUE; - else - RETURN_ERROR1("Expected an identfier"); -} - - -/** - * Parse a floating point constant, or a defined symbol name. - * [+/-]N[.N[eN]] - * Output: number[0 .. 3] will get the value. - */ -static GLboolean -Parse_ScalarConstant(struct parse_state *parseState, GLfloat *number) -{ - char *end = NULL; - - *number = (GLfloat) _mesa_strtof((const char *) parseState->pos, &end); - - if (end && end > (char *) parseState->pos) { - /* got a number */ - parseState->pos = (GLubyte *) end; - number[1] = *number; - number[2] = *number; - number[3] = *number; - return GL_TRUE; - } - else { - /* should be an identifier */ - GLubyte ident[100]; - const GLfloat *constant; - if (!Parse_Identifier(parseState, ident)) - RETURN_ERROR1("Expected an identifier"); - constant = _mesa_lookup_parameter_value(parseState->parameters, - -1, (const char *) ident); - /* XXX Check that it's a constant and not a parameter */ - if (!constant) { - RETURN_ERROR1("Undefined symbol"); - } - else { - COPY_4V(number, constant); - return GL_TRUE; - } - } -} - - - -/** - * Parse a vector constant, one of: - * { float } - * { float, float } - * { float, float, float } - * { float, float, float, float } - */ -static GLboolean -Parse_VectorConstant(struct parse_state *parseState, GLfloat *vec) -{ - /* "{" was already consumed */ - - ASSIGN_4V(vec, 0.0, 0.0, 0.0, 1.0); - - if (!Parse_ScalarConstant(parseState, vec+0)) /* X */ - return GL_FALSE; - - if (Parse_String(parseState, "}")) { - return GL_TRUE; - } - - if (!Parse_String(parseState, ",")) - RETURN_ERROR1("Expected comma in vector constant"); - - if (!Parse_ScalarConstant(parseState, vec+1)) /* Y */ - return GL_FALSE; - - if (Parse_String(parseState, "}")) { - return GL_TRUE; - } - - if (!Parse_String(parseState, ",")) - RETURN_ERROR1("Expected comma in vector constant"); - - if (!Parse_ScalarConstant(parseState, vec+2)) /* Z */ - return GL_FALSE; - - if (Parse_String(parseState, "}")) { - return GL_TRUE; - } - - if (!Parse_String(parseState, ",")) - RETURN_ERROR1("Expected comma in vector constant"); - - if (!Parse_ScalarConstant(parseState, vec+3)) /* W */ - return GL_FALSE; - - if (!Parse_String(parseState, "}")) - RETURN_ERROR1("Expected closing brace in vector constant"); - - return GL_TRUE; -} - - -/** - * Parse <number>, <varname> or {a, b, c, d}. - * Return number of values in the vector or scalar, or zero if parse error. - */ -static GLuint -Parse_VectorOrScalarConstant(struct parse_state *parseState, GLfloat *vec) -{ - if (Parse_String(parseState, "{")) { - return Parse_VectorConstant(parseState, vec); - } - else { - GLboolean b = Parse_ScalarConstant(parseState, vec); - if (b) { - vec[1] = vec[2] = vec[3] = vec[0]; - } - return b; - } -} - - -/** - * Parse a texture image source: - * [TEX0 | TEX1 | .. | TEX15] , [1D | 2D | 3D | CUBE | RECT] - */ -static GLboolean -Parse_TextureImageId(struct parse_state *parseState, - GLubyte *texUnit, GLubyte *texTargetBit) -{ - GLubyte imageSrc[100]; - GLint unit; - - if (!Parse_Token(parseState, imageSrc)) - RETURN_ERROR; - - if (imageSrc[0] != 'T' || - imageSrc[1] != 'E' || - imageSrc[2] != 'X') { - RETURN_ERROR1("Expected TEX# source"); - } - unit = atoi((const char *) imageSrc + 3); - if ((unit < 0 || unit > MAX_TEXTURE_IMAGE_UNITS) || - (unit == 0 && (imageSrc[3] != '0' || imageSrc[4] != 0))) { - RETURN_ERROR1("Invalied TEX# source index"); - } - *texUnit = unit; - - if (!Parse_String(parseState, ",")) - RETURN_ERROR1("Expected ,"); - - if (Parse_String(parseState, "1D")) { - *texTargetBit = TEXTURE_1D_BIT; - } - else if (Parse_String(parseState, "2D")) { - *texTargetBit = TEXTURE_2D_BIT; - } - else if (Parse_String(parseState, "3D")) { - *texTargetBit = TEXTURE_3D_BIT; - } - else if (Parse_String(parseState, "CUBE")) { - *texTargetBit = TEXTURE_CUBE_BIT; - } - else if (Parse_String(parseState, "RECT")) { - *texTargetBit = TEXTURE_RECT_BIT; - } - else { - RETURN_ERROR1("Invalid texture target token"); - } - - /* update record of referenced texture units */ - parseState->texturesUsed[*texUnit] |= *texTargetBit; - if (_mesa_bitcount(parseState->texturesUsed[*texUnit]) > 1) { - RETURN_ERROR1("Only one texture target can be used per texture unit."); - } - - return GL_TRUE; -} - - -/** - * Parse a scalar suffix like .x, .y, .z or .w or parse a swizzle suffix - * like .wxyz, .xxyy, etc and return the swizzle indexes. - */ -static GLboolean -Parse_SwizzleSuffix(const GLubyte *token, GLuint swizzle[4]) -{ - if (token[1] == 0) { - /* single letter swizzle (scalar) */ - if (token[0] == 'x') - ASSIGN_4V(swizzle, 0, 0, 0, 0); - else if (token[0] == 'y') - ASSIGN_4V(swizzle, 1, 1, 1, 1); - else if (token[0] == 'z') - ASSIGN_4V(swizzle, 2, 2, 2, 2); - else if (token[0] == 'w') - ASSIGN_4V(swizzle, 3, 3, 3, 3); - else - return GL_FALSE; - } - else { - /* 4-component swizzle (vector) */ - GLint k; - for (k = 0; k < 4 && token[k]; k++) { - if (token[k] == 'x') - swizzle[k] = 0; - else if (token[k] == 'y') - swizzle[k] = 1; - else if (token[k] == 'z') - swizzle[k] = 2; - else if (token[k] == 'w') - swizzle[k] = 3; - else - return GL_FALSE; - } - if (k != 4) - return GL_FALSE; - } - return GL_TRUE; -} - - -static GLboolean -Parse_CondCodeMask(struct parse_state *parseState, - struct prog_dst_register *dstReg) -{ - if (Parse_String(parseState, "EQ")) - dstReg->CondMask = COND_EQ; - else if (Parse_String(parseState, "GE")) - dstReg->CondMask = COND_GE; - else if (Parse_String(parseState, "GT")) - dstReg->CondMask = COND_GT; - else if (Parse_String(parseState, "LE")) - dstReg->CondMask = COND_LE; - else if (Parse_String(parseState, "LT")) - dstReg->CondMask = COND_LT; - else if (Parse_String(parseState, "NE")) - dstReg->CondMask = COND_NE; - else if (Parse_String(parseState, "TR")) - dstReg->CondMask = COND_TR; - else if (Parse_String(parseState, "FL")) - dstReg->CondMask = COND_FL; - else - RETURN_ERROR1("Invalid condition code mask"); - - /* look for optional .xyzw swizzle */ - if (Parse_String(parseState, ".")) { - GLubyte token[100]; - GLuint swz[4]; - - if (!Parse_Token(parseState, token)) /* get xyzw suffix */ - RETURN_ERROR; - - if (!Parse_SwizzleSuffix(token, swz)) - RETURN_ERROR1("Invalid swizzle suffix"); - - dstReg->CondSwizzle = MAKE_SWIZZLE4(swz[0], swz[1], swz[2], swz[3]); - } - - return GL_TRUE; -} - - -/** - * Parse a temporary register: Rnn or Hnn - */ -static GLboolean -Parse_TempReg(struct parse_state *parseState, GLint *tempRegNum) -{ - GLubyte token[100]; - - /* Should be 'R##' or 'H##' */ - if (!Parse_Token(parseState, token)) - RETURN_ERROR; - if (token[0] != 'R' && token[0] != 'H') - RETURN_ERROR1("Expected R## or H##"); - - if (IsDigit(token[1])) { - GLint reg = atoi((const char *) (token + 1)); - if (token[0] == 'H') - reg += 32; - if (reg >= MAX_NV_FRAGMENT_PROGRAM_TEMPS) - RETURN_ERROR1("Invalid temporary register name"); - *tempRegNum = reg; - } - else { - RETURN_ERROR1("Invalid temporary register name"); - } - - return GL_TRUE; -} - - -/** - * Parse a write-only dummy register: RC or HC. - */ -static GLboolean -Parse_DummyReg(struct parse_state *parseState, GLint *regNum) -{ - if (Parse_String(parseState, "RC")) { - *regNum = 0; - } - else if (Parse_String(parseState, "HC")) { - *regNum = 1; - } - else { - RETURN_ERROR1("Invalid write-only register name"); - } - - return GL_TRUE; -} - - -/** - * Parse a program local parameter register "p[##]" - */ -static GLboolean -Parse_ProgramParamReg(struct parse_state *parseState, GLint *regNum) -{ - GLubyte token[100]; - - if (!Parse_String(parseState, "p[")) - RETURN_ERROR1("Expected p["); - - if (!Parse_Token(parseState, token)) - RETURN_ERROR; - - if (IsDigit(token[0])) { - /* a numbered program parameter register */ - GLint reg = atoi((const char *) token); - if (reg >= MAX_NV_FRAGMENT_PROGRAM_PARAMS) - RETURN_ERROR1("Invalid constant program number"); - *regNum = reg; - } - else { - RETURN_ERROR; - } - - if (!Parse_String(parseState, "]")) - RETURN_ERROR1("Expected ]"); - - return GL_TRUE; -} - - -/** - * Parse f[name] - fragment input register - */ -static GLboolean -Parse_FragReg(struct parse_state *parseState, GLint *tempRegNum) -{ - GLubyte token[100]; - GLint j; - - /* Match 'f[' */ - if (!Parse_String(parseState, "f[")) - RETURN_ERROR1("Expected f["); - - /* get <name> and look for match */ - if (!Parse_Token(parseState, token)) { - RETURN_ERROR; - } - for (j = 0; InputRegisters[j]; j++) { - if (strcmp((const char *) token, InputRegisters[j]) == 0) { - *tempRegNum = j; - parseState->inputsRead |= (1 << j); - break; - } - } - if (!InputRegisters[j]) { - /* unknown input register label */ - RETURN_ERROR2("Invalid register name", token); - } - - /* Match '[' */ - if (!Parse_String(parseState, "]")) - RETURN_ERROR1("Expected ]"); - - return GL_TRUE; -} - - -static GLboolean -Parse_OutputReg(struct parse_state *parseState, GLint *outputRegNum) -{ - GLubyte token[100]; - - /* Match "o[" */ - if (!Parse_String(parseState, "o[")) - RETURN_ERROR1("Expected o["); - - /* Get output reg name */ - if (!Parse_Token(parseState, token)) - RETURN_ERROR; - - /* try to match an output register name */ - if (strcmp((char *) token, "COLR") == 0 || - strcmp((char *) token, "COLH") == 0) { - /* note that we don't distinguish between COLR and COLH */ - *outputRegNum = FRAG_RESULT_COLOR; - parseState->outputsWritten |= (1 << FRAG_RESULT_COLOR); - } - else if (strcmp((char *) token, "DEPR") == 0) { - *outputRegNum = FRAG_RESULT_DEPTH; - parseState->outputsWritten |= (1 << FRAG_RESULT_DEPTH); - } - else { - RETURN_ERROR1("Invalid output register name"); - } - - /* Match ']' */ - if (!Parse_String(parseState, "]")) - RETURN_ERROR1("Expected ]"); - - return GL_TRUE; -} - - -static GLboolean -Parse_MaskedDstReg(struct parse_state *parseState, - struct prog_dst_register *dstReg) -{ - GLubyte token[100]; - GLint idx; - - /* Dst reg can be R<n>, H<n>, o[n], RC or HC */ - if (!Peek_Token(parseState, token)) - RETURN_ERROR; - - if (strcmp((const char *) token, "RC") == 0 || - strcmp((const char *) token, "HC") == 0) { - /* a write-only register */ - dstReg->File = PROGRAM_WRITE_ONLY; - if (!Parse_DummyReg(parseState, &idx)) - RETURN_ERROR; - dstReg->Index = idx; - } - else if (token[0] == 'R' || token[0] == 'H') { - /* a temporary register */ - dstReg->File = PROGRAM_TEMPORARY; - if (!Parse_TempReg(parseState, &idx)) - RETURN_ERROR; - dstReg->Index = idx; - } - else if (token[0] == 'o') { - /* an output register */ - dstReg->File = PROGRAM_OUTPUT; - if (!Parse_OutputReg(parseState, &idx)) - RETURN_ERROR; - dstReg->Index = idx; - } - else { - RETURN_ERROR1("Invalid destination register name"); - } - - /* Parse optional write mask */ - if (Parse_String(parseState, ".")) { - /* got a mask */ - GLint k = 0; - - if (!Parse_Token(parseState, token)) /* get xyzw writemask */ - RETURN_ERROR; - - dstReg->WriteMask = 0; - - if (token[k] == 'x') { - dstReg->WriteMask |= WRITEMASK_X; - k++; - } - if (token[k] == 'y') { - dstReg->WriteMask |= WRITEMASK_Y; - k++; - } - if (token[k] == 'z') { - dstReg->WriteMask |= WRITEMASK_Z; - k++; - } - if (token[k] == 'w') { - dstReg->WriteMask |= WRITEMASK_W; - k++; - } - if (k == 0) { - RETURN_ERROR1("Invalid writemask character"); - } - - } - else { - dstReg->WriteMask = WRITEMASK_XYZW; - } - - /* optional condition code mask */ - if (Parse_String(parseState, "(")) { - /* ("EQ" | "GE" | "GT" | "LE" | "LT" | "NE" | "TR" | "FL".x|y|z|w) */ - /* ("EQ" | "GE" | "GT" | "LE" | "LT" | "NE" | "TR" | "FL".[xyzw]) */ - if (!Parse_CondCodeMask(parseState, dstReg)) - RETURN_ERROR; - - if (!Parse_String(parseState, ")")) /* consume ")" */ - RETURN_ERROR1("Expected )"); - - return GL_TRUE; - } - else { - /* no cond code mask */ - dstReg->CondMask = COND_TR; - dstReg->CondSwizzle = SWIZZLE_NOOP; - return GL_TRUE; - } -} - - -/** - * Parse a vector source (register, constant, etc): - * <vectorSrc> ::= <absVectorSrc> - * | <baseVectorSrc> - * <absVectorSrc> ::= <negate> "|" <baseVectorSrc> "|" - */ -static GLboolean -Parse_VectorSrc(struct parse_state *parseState, - struct prog_src_register *srcReg) -{ - GLfloat sign = 1.0F; - GLubyte token[100]; - GLint idx; - GLuint negateBase, negateAbs; - - /* - * First, take care of +/- and absolute value stuff. - */ - if (Parse_String(parseState, "-")) - sign = -1.0F; - else if (Parse_String(parseState, "+")) - sign = +1.0F; - - if (Parse_String(parseState, "|")) { - srcReg->Abs = GL_TRUE; - negateAbs = (sign < 0.0F) ? NEGATE_XYZW : NEGATE_NONE; - - if (Parse_String(parseState, "-")) - negateBase = NEGATE_XYZW; - else if (Parse_String(parseState, "+")) - negateBase = NEGATE_NONE; - else - negateBase = NEGATE_NONE; - } - else { - srcReg->Abs = GL_FALSE; - negateAbs = NEGATE_NONE; - negateBase = (sign < 0.0F) ? NEGATE_XYZW : NEGATE_NONE; - } - - srcReg->Negate = srcReg->Abs ? negateAbs : negateBase; - - /* This should be the real src vector/register name */ - if (!Peek_Token(parseState, token)) - RETURN_ERROR; - - /* Src reg can be Rn, Hn, f[n], p[n], a named parameter, a scalar - * literal or vector literal. - */ - if (token[0] == 'R' || token[0] == 'H') { - srcReg->File = PROGRAM_TEMPORARY; - if (!Parse_TempReg(parseState, &idx)) - RETURN_ERROR; - srcReg->Index = idx; - } - else if (token[0] == 'f') { - /* XXX this might be an identifier! */ - srcReg->File = PROGRAM_INPUT; - if (!Parse_FragReg(parseState, &idx)) - RETURN_ERROR; - srcReg->Index = idx; - } - else if (token[0] == 'p') { - /* XXX this might be an identifier! */ - srcReg->File = PROGRAM_LOCAL_PARAM; - if (!Parse_ProgramParamReg(parseState, &idx)) - RETURN_ERROR; - srcReg->Index = idx; - } - else if (IsLetter(token[0])){ - GLubyte ident[100]; - GLint paramIndex; - if (!Parse_Identifier(parseState, ident)) - RETURN_ERROR; - paramIndex = _mesa_lookup_parameter_index(parseState->parameters, - -1, (const char *) ident); - if (paramIndex < 0) { - RETURN_ERROR2("Undefined constant or parameter: ", ident); - } - srcReg->File = PROGRAM_NAMED_PARAM; - srcReg->Index = paramIndex; - } - else if (IsDigit(token[0]) || token[0] == '-' || token[0] == '+' || token[0] == '.'){ - /* literal scalar constant */ - GLfloat values[4]; - GLuint paramIndex; - if (!Parse_ScalarConstant(parseState, values)) - RETURN_ERROR; - paramIndex = _mesa_add_unnamed_constant(parseState->parameters, - values, 4, NULL); - srcReg->File = PROGRAM_NAMED_PARAM; - srcReg->Index = paramIndex; - } - else if (token[0] == '{'){ - /* literal vector constant */ - GLfloat values[4]; - GLuint paramIndex; - (void) Parse_String(parseState, "{"); - if (!Parse_VectorConstant(parseState, values)) - RETURN_ERROR; - paramIndex = _mesa_add_unnamed_constant(parseState->parameters, - values, 4, NULL); - srcReg->File = PROGRAM_NAMED_PARAM; - srcReg->Index = paramIndex; - } - else { - RETURN_ERROR2("Invalid source register name", token); - } - - /* init swizzle fields */ - srcReg->Swizzle = SWIZZLE_NOOP; - - /* Look for optional swizzle suffix */ - if (Parse_String(parseState, ".")) { - GLuint swz[4]; - - if (!Parse_Token(parseState, token)) - RETURN_ERROR; - - if (!Parse_SwizzleSuffix(token, swz)) - RETURN_ERROR1("Invalid swizzle suffix"); - - srcReg->Swizzle = MAKE_SWIZZLE4(swz[0], swz[1], swz[2], swz[3]); - } - - /* Finish absolute value */ - if (srcReg->Abs && !Parse_String(parseState, "|")) { - RETURN_ERROR1("Expected |"); - } - - return GL_TRUE; -} - - -static GLboolean -Parse_ScalarSrcReg(struct parse_state *parseState, - struct prog_src_register *srcReg) -{ - GLubyte token[100]; - GLfloat sign = 1.0F; - GLboolean needSuffix = GL_TRUE; - GLint idx; - GLuint negateBase, negateAbs; - - /* - * First, take care of +/- and absolute value stuff. - */ - if (Parse_String(parseState, "-")) - sign = -1.0F; - else if (Parse_String(parseState, "+")) - sign = +1.0F; - - if (Parse_String(parseState, "|")) { - srcReg->Abs = GL_TRUE; - negateAbs = (sign < 0.0F) ? NEGATE_XYZW : NEGATE_NONE; - - if (Parse_String(parseState, "-")) - negateBase = NEGATE_XYZW; - else if (Parse_String(parseState, "+")) - negateBase = NEGATE_NONE; - else - negateBase = NEGATE_NONE; - } - else { - srcReg->Abs = GL_FALSE; - negateAbs = NEGATE_NONE; - negateBase = (sign < 0.0F) ? NEGATE_XYZW : NEGATE_NONE; - } - - srcReg->Negate = srcReg->Abs ? negateAbs : negateBase; - - if (!Peek_Token(parseState, token)) - RETURN_ERROR; - - /* Src reg can be R<n>, H<n> or a named fragment attrib */ - if (token[0] == 'R' || token[0] == 'H') { - srcReg->File = PROGRAM_TEMPORARY; - if (!Parse_TempReg(parseState, &idx)) - RETURN_ERROR; - srcReg->Index = idx; - } - else if (token[0] == 'f') { - srcReg->File = PROGRAM_INPUT; - if (!Parse_FragReg(parseState, &idx)) - RETURN_ERROR; - srcReg->Index = idx; - } - else if (token[0] == '{') { - /* vector literal */ - GLfloat values[4]; - GLuint paramIndex; - (void) Parse_String(parseState, "{"); - if (!Parse_VectorConstant(parseState, values)) - RETURN_ERROR; - paramIndex = _mesa_add_unnamed_constant(parseState->parameters, - values, 4, NULL); - srcReg->File = PROGRAM_NAMED_PARAM; - srcReg->Index = paramIndex; - } - else if (IsLetter(token[0])){ - /* named param/constant */ - GLubyte ident[100]; - GLint paramIndex; - if (!Parse_Identifier(parseState, ident)) - RETURN_ERROR; - paramIndex = _mesa_lookup_parameter_index(parseState->parameters, - -1, (const char *) ident); - if (paramIndex < 0) { - RETURN_ERROR2("Undefined constant or parameter: ", ident); - } - srcReg->File = PROGRAM_NAMED_PARAM; - srcReg->Index = paramIndex; - } - else if (IsDigit(token[0])) { - /* scalar literal */ - GLfloat values[4]; - GLuint paramIndex; - if (!Parse_ScalarConstant(parseState, values)) - RETURN_ERROR; - paramIndex = _mesa_add_unnamed_constant(parseState->parameters, - values, 4, NULL); - srcReg->Index = paramIndex; - srcReg->File = PROGRAM_NAMED_PARAM; - needSuffix = GL_FALSE; - } - else { - RETURN_ERROR2("Invalid scalar source argument", token); - } - - srcReg->Swizzle = 0; - if (needSuffix) { - /* parse .[xyzw] suffix */ - if (!Parse_String(parseState, ".")) - RETURN_ERROR1("Expected ."); - - if (!Parse_Token(parseState, token)) - RETURN_ERROR; - - if (token[0] == 'x' && token[1] == 0) { - srcReg->Swizzle = 0; - } - else if (token[0] == 'y' && token[1] == 0) { - srcReg->Swizzle = 1; - } - else if (token[0] == 'z' && token[1] == 0) { - srcReg->Swizzle = 2; - } - else if (token[0] == 'w' && token[1] == 0) { - srcReg->Swizzle = 3; - } - else { - RETURN_ERROR1("Invalid scalar source suffix"); - } - } - - /* Finish absolute value */ - if (srcReg->Abs && !Parse_String(parseState, "|")) { - RETURN_ERROR1("Expected |"); - } - - return GL_TRUE; -} - - -static GLboolean -Parse_PrintInstruction(struct parse_state *parseState, - struct prog_instruction *inst) -{ - const GLubyte *str; - GLubyte *msg; - GLuint len; - GLint idx; - - /* The first argument is a literal string 'just like this' */ - if (!Parse_String(parseState, "'")) - RETURN_ERROR1("Expected '"); - - str = parseState->pos; - for (len = 0; str[len] != '\''; len++) /* find closing quote */ - ; - parseState->pos += len + 1; - msg = (GLubyte*) malloc(len + 1); - - memcpy(msg, str, len); - msg[len] = 0; - inst->Data = msg; - - if (Parse_String(parseState, ",")) { - /* got an optional register to print */ - GLubyte token[100]; - GetToken(parseState, token); - if (token[0] == 'o') { - /* dst reg */ - if (!Parse_OutputReg(parseState, &idx)) - RETURN_ERROR; - inst->SrcReg[0].Index = idx; - inst->SrcReg[0].File = PROGRAM_OUTPUT; - } - else { - /* src reg */ - if (!Parse_VectorSrc(parseState, &inst->SrcReg[0])) - RETURN_ERROR; - } - } - else { - inst->SrcReg[0].File = PROGRAM_UNDEFINED; - } - - inst->SrcReg[0].Swizzle = SWIZZLE_NOOP; - inst->SrcReg[0].Abs = GL_FALSE; - inst->SrcReg[0].Negate = NEGATE_NONE; - - return GL_TRUE; -} - - -static GLboolean -Parse_InstructionSequence(struct parse_state *parseState, - struct prog_instruction program[]) -{ - while (1) { - struct prog_instruction *inst = program + parseState->numInst; - struct instruction_pattern instMatch; - GLubyte token[100]; - - /* Initialize the instruction */ - _mesa_init_instructions(inst, 1); - - /* special instructions */ - if (Parse_String(parseState, "DEFINE")) { - GLubyte id[100]; - GLfloat value[7]; /* yes, 7 to be safe */ - if (!Parse_Identifier(parseState, id)) - RETURN_ERROR; - /* XXX make sure id is not a reserved identifer, like R9 */ - if (!Parse_String(parseState, "=")) - RETURN_ERROR1("Expected ="); - if (!Parse_VectorOrScalarConstant(parseState, value)) - RETURN_ERROR; - if (!Parse_String(parseState, ";")) - RETURN_ERROR1("Expected ;"); - if (_mesa_lookup_parameter_index(parseState->parameters, - -1, (const char *) id) >= 0) { - RETURN_ERROR2(id, "already defined"); - } - _mesa_add_named_parameter(parseState->parameters, - (const char *) id, value); - } - else if (Parse_String(parseState, "DECLARE")) { - GLubyte id[100]; - GLfloat value[7] = {0, 0, 0, 0, 0, 0, 0}; /* yes, to be safe */ - if (!Parse_Identifier(parseState, id)) - RETURN_ERROR; - /* XXX make sure id is not a reserved identifer, like R9 */ - if (Parse_String(parseState, "=")) { - if (!Parse_VectorOrScalarConstant(parseState, value)) - RETURN_ERROR; - } - if (!Parse_String(parseState, ";")) - RETURN_ERROR1("Expected ;"); - if (_mesa_lookup_parameter_index(parseState->parameters, - -1, (const char *) id) >= 0) { - RETURN_ERROR2(id, "already declared"); - } - _mesa_add_named_parameter(parseState->parameters, - (const char *) id, value); - } - else if (Parse_String(parseState, "END")) { - inst->Opcode = OPCODE_END; - parseState->numInst++; - if (Parse_Token(parseState, token)) { - RETURN_ERROR1("Code after END opcode."); - } - break; - } - else { - /* general/arithmetic instruction */ - - /* get token */ - if (!Parse_Token(parseState, token)) { - RETURN_ERROR1("Missing END instruction."); - } - - /* try to find matching instuction */ - instMatch = MatchInstruction(token); - if (instMatch.opcode >= MAX_OPCODE) { - /* bad instruction name */ - RETURN_ERROR2("Unexpected token: ", token); - } - - inst->Opcode = instMatch.opcode; - inst->Precision = instMatch.suffixes & (_R | _H | _X); - inst->SaturateMode = (instMatch.suffixes & (_S)) - ? SATURATE_ZERO_ONE : SATURATE_OFF; - inst->CondUpdate = (instMatch.suffixes & (_C)) ? GL_TRUE : GL_FALSE; - - /* - * parse the input and output operands - */ - if (instMatch.outputs == OUTPUT_S || instMatch.outputs == OUTPUT_V) { - if (!Parse_MaskedDstReg(parseState, &inst->DstReg)) - RETURN_ERROR; - if (!Parse_String(parseState, ",")) - RETURN_ERROR1("Expected ,"); - } - else if (instMatch.outputs == OUTPUT_NONE) { - if (instMatch.opcode == OPCODE_KIL_NV) { - /* This is a little weird, the cond code info is in - * the dest register. - */ - if (!Parse_CondCodeMask(parseState, &inst->DstReg)) - RETURN_ERROR; - } - else { - ASSERT(instMatch.opcode == OPCODE_PRINT); - } - } - - if (instMatch.inputs == INPUT_1V) { - if (!Parse_VectorSrc(parseState, &inst->SrcReg[0])) - RETURN_ERROR; - } - else if (instMatch.inputs == INPUT_2V) { - if (!Parse_VectorSrc(parseState, &inst->SrcReg[0])) - RETURN_ERROR; - if (!Parse_String(parseState, ",")) - RETURN_ERROR1("Expected ,"); - if (!Parse_VectorSrc(parseState, &inst->SrcReg[1])) - RETURN_ERROR; - } - else if (instMatch.inputs == INPUT_3V) { - if (!Parse_VectorSrc(parseState, &inst->SrcReg[0])) - RETURN_ERROR; - if (!Parse_String(parseState, ",")) - RETURN_ERROR1("Expected ,"); - if (!Parse_VectorSrc(parseState, &inst->SrcReg[1])) - RETURN_ERROR; - if (!Parse_String(parseState, ",")) - RETURN_ERROR1("Expected ,"); - if (!Parse_VectorSrc(parseState, &inst->SrcReg[2])) - RETURN_ERROR; - } - else if (instMatch.inputs == INPUT_1S) { - if (!Parse_ScalarSrcReg(parseState, &inst->SrcReg[0])) - RETURN_ERROR; - } - else if (instMatch.inputs == INPUT_2S) { - if (!Parse_ScalarSrcReg(parseState, &inst->SrcReg[0])) - RETURN_ERROR; - if (!Parse_String(parseState, ",")) - RETURN_ERROR1("Expected ,"); - if (!Parse_ScalarSrcReg(parseState, &inst->SrcReg[1])) - RETURN_ERROR; - } - else if (instMatch.inputs == INPUT_CC) { - /* XXX to-do */ - } - else if (instMatch.inputs == INPUT_1V_T) { - GLubyte unit, idx; - if (!Parse_VectorSrc(parseState, &inst->SrcReg[0])) - RETURN_ERROR; - if (!Parse_String(parseState, ",")) - RETURN_ERROR1("Expected ,"); - if (!Parse_TextureImageId(parseState, &unit, &idx)) - RETURN_ERROR; - inst->TexSrcUnit = unit; - inst->TexSrcTarget = idx; - } - else if (instMatch.inputs == INPUT_3V_T) { - GLubyte unit, idx; - if (!Parse_VectorSrc(parseState, &inst->SrcReg[0])) - RETURN_ERROR; - if (!Parse_String(parseState, ",")) - RETURN_ERROR1("Expected ,"); - if (!Parse_VectorSrc(parseState, &inst->SrcReg[1])) - RETURN_ERROR; - if (!Parse_String(parseState, ",")) - RETURN_ERROR1("Expected ,"); - if (!Parse_VectorSrc(parseState, &inst->SrcReg[2])) - RETURN_ERROR; - if (!Parse_String(parseState, ",")) - RETURN_ERROR1("Expected ,"); - if (!Parse_TextureImageId(parseState, &unit, &idx)) - RETURN_ERROR; - inst->TexSrcUnit = unit; - inst->TexSrcTarget = idx; - } - else if (instMatch.inputs == INPUT_1V_S) { - if (!Parse_PrintInstruction(parseState, inst)) - RETURN_ERROR; - } - - /* end of statement semicolon */ - if (!Parse_String(parseState, ";")) - RETURN_ERROR1("Expected ;"); - - parseState->numInst++; - - if (parseState->numInst >= MAX_NV_FRAGMENT_PROGRAM_INSTRUCTIONS) - RETURN_ERROR1("Program too long"); - } - } - return GL_TRUE; -} - - - -/** - * Parse/compile the 'str' returning the compiled 'program'. - * ctx->Program.ErrorPos will be -1 if successful. Otherwise, ErrorPos - * indicates the position of the error in 'str'. - */ -void -_mesa_parse_nv_fragment_program(GLcontext *ctx, GLenum dstTarget, - const GLubyte *str, GLsizei len, - struct gl_fragment_program *program) -{ - struct parse_state parseState; - struct prog_instruction instBuffer[MAX_NV_FRAGMENT_PROGRAM_INSTRUCTIONS]; - struct prog_instruction *newInst; - GLenum target; - GLubyte *programString; - - /* Make a null-terminated copy of the program string */ - programString = (GLubyte *) MALLOC(len + 1); - if (!programString) { - _mesa_error(ctx, GL_OUT_OF_MEMORY, "glLoadProgramNV"); - return; - } - memcpy(programString, str, len); - programString[len] = 0; - - /* Get ready to parse */ - memset(&parseState, 0, sizeof(struct parse_state)); - parseState.ctx = ctx; - parseState.start = programString; - parseState.program = program; - parseState.numInst = 0; - parseState.curLine = programString; - parseState.parameters = _mesa_new_parameter_list(); - - /* Reset error state */ - _mesa_set_program_error(ctx, -1, NULL); - - /* check the program header */ - if (strncmp((const char *) programString, "!!FP1.0", 7) == 0) { - target = GL_FRAGMENT_PROGRAM_NV; - parseState.pos = programString + 7; - } - else if (strncmp((const char *) programString, "!!FCP1.0", 8) == 0) { - /* fragment / register combiner program - not supported */ - _mesa_set_program_error(ctx, 0, "Invalid fragment program header"); - _mesa_error(ctx, GL_INVALID_OPERATION, "glLoadProgramNV(bad header)"); - return; - } - else { - /* invalid header */ - _mesa_set_program_error(ctx, 0, "Invalid fragment program header"); - _mesa_error(ctx, GL_INVALID_OPERATION, "glLoadProgramNV(bad header)"); - return; - } - - /* make sure target and header match */ - if (target != dstTarget) { - _mesa_error(ctx, GL_INVALID_OPERATION, - "glLoadProgramNV(target mismatch 0x%x != 0x%x)", - target, dstTarget); - return; - } - - if (Parse_InstructionSequence(&parseState, instBuffer)) { - GLuint u; - /* successful parse! */ - - if (parseState.outputsWritten == 0) { - /* must write at least one output! */ - _mesa_error(ctx, GL_INVALID_OPERATION, - "Invalid fragment program - no outputs written."); - return; - } - - /* copy the compiled instructions */ - assert(parseState.numInst <= MAX_NV_FRAGMENT_PROGRAM_INSTRUCTIONS); - newInst = _mesa_alloc_instructions(parseState.numInst); - if (!newInst) { - _mesa_error(ctx, GL_OUT_OF_MEMORY, "glLoadProgramNV"); - return; /* out of memory */ - } - _mesa_copy_instructions(newInst, instBuffer, parseState.numInst); - - /* install the program */ - program->Base.Target = target; - if (program->Base.String) { - FREE(program->Base.String); - } - program->Base.String = programString; - program->Base.Format = GL_PROGRAM_FORMAT_ASCII_ARB; - if (program->Base.Instructions) { - free(program->Base.Instructions); - } - program->Base.Instructions = newInst; - program->Base.NumInstructions = parseState.numInst; - program->Base.InputsRead = parseState.inputsRead; - program->Base.OutputsWritten = parseState.outputsWritten; - for (u = 0; u < ctx->Const.MaxTextureImageUnits; u++) - program->Base.TexturesUsed[u] = parseState.texturesUsed[u]; - - /* save program parameters */ - program->Base.Parameters = parseState.parameters; - - /* allocate registers for declared program parameters */ -#if 00 - _mesa_assign_program_registers(&(program->SymbolTable)); -#endif - -#ifdef DEBUG_foo - printf("--- glLoadProgramNV(%d) result ---\n", program->Base.Id); - _mesa_fprint_program_opt(stdout, &program->Base, PROG_PRINT_NV, 0); - printf("----------------------------------\n"); -#endif - } - else { - /* Error! */ - _mesa_error(ctx, GL_INVALID_OPERATION, "glLoadProgramNV"); - /* NOTE: _mesa_set_program_error would have been called already */ - } -} - - -const char * -_mesa_nv_fragment_input_register_name(GLuint i) -{ - ASSERT(i < MAX_NV_FRAGMENT_PROGRAM_INPUTS); - return InputRegisters[i]; -} - diff --git a/mesalib/src/mesa/shader/nvfragparse.h b/mesalib/src/mesa/shader/nvfragparse.h deleted file mode 100644 index 544ab80c5..000000000 --- a/mesalib/src/mesa/shader/nvfragparse.h +++ /dev/null @@ -1,43 +0,0 @@ - -/* - * Mesa 3-D graphics library - * Version: 5.1 - * - * Copyright (C) 1999-2002 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: - * Brian Paul - */ - - -#ifndef NVFRAGPARSE_H -#define NVFRAGPARSE_H - - -extern void -_mesa_parse_nv_fragment_program(GLcontext *ctx, GLenum target, - const GLubyte *str, GLsizei len, - struct gl_fragment_program *program); - - -extern const char * -_mesa_nv_fragment_input_register_name(GLuint i); - -#endif diff --git a/mesalib/src/mesa/shader/nvprogram.c b/mesalib/src/mesa/shader/nvprogram.c deleted file mode 100644 index 19020be42..000000000 --- a/mesalib/src/mesa/shader/nvprogram.c +++ /dev/null @@ -1,917 +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 nvprogram.c - * NVIDIA vertex/fragment program state management functions. - * \author Brian Paul - */ - -/* - * Regarding GL_NV_fragment/vertex_program, GL_NV_vertex_program1_1, etc: - * - * 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 "main/glheader.h" -#include "main/context.h" -#include "main/hash.h" -#include "main/imports.h" -#include "main/macros.h" -#include "program.h" -#include "prog_parameter.h" -#include "prog_instruction.h" -#include "nvfragparse.h" -#include "nvvertparse.h" -#include "arbprogparse.h" -#include "nvprogram.h" - - - -/** - * Execute a vertex state program. - * \note Called from the GL API dispatcher. - */ -void GLAPIENTRY -_mesa_ExecuteProgramNV(GLenum target, GLuint id, const GLfloat *params) -{ - struct gl_vertex_program *vprog; - GET_CURRENT_CONTEXT(ctx); - ASSERT_OUTSIDE_BEGIN_END(ctx); - - if (target != GL_VERTEX_STATE_PROGRAM_NV) { - _mesa_error(ctx, GL_INVALID_ENUM, "glExecuteProgramNV"); - return; - } - - FLUSH_VERTICES(ctx, _NEW_PROGRAM); - - vprog = (struct gl_vertex_program *) _mesa_lookup_program(ctx, id); - - if (!vprog || vprog->Base.Target != GL_VERTEX_STATE_PROGRAM_NV) { - _mesa_error(ctx, GL_INVALID_OPERATION, "glExecuteProgramNV"); - return; - } - - _mesa_problem(ctx, "glExecuteProgramNV() not supported"); -} - - -/** - * Determine if a set of programs is resident in hardware. - * \note Not compiled into display lists. - * \note Called from the GL API dispatcher. - */ -GLboolean GLAPIENTRY -_mesa_AreProgramsResidentNV(GLsizei n, const GLuint *ids, - GLboolean *residences) -{ - GLint i, j; - GLboolean allResident = GL_TRUE; - GET_CURRENT_CONTEXT(ctx); - ASSERT_OUTSIDE_BEGIN_END_WITH_RETVAL(ctx, GL_FALSE); - - if (n < 0) { - _mesa_error(ctx, GL_INVALID_VALUE, "glAreProgramsResidentNV(n)"); - return GL_FALSE; - } - - for (i = 0; i < n; i++) { - const struct gl_program *prog; - if (ids[i] == 0) { - _mesa_error(ctx, GL_INVALID_VALUE, "glAreProgramsResidentNV"); - return GL_FALSE; - } - prog = _mesa_lookup_program(ctx, ids[i]); - if (!prog) { - _mesa_error(ctx, GL_INVALID_VALUE, "glAreProgramsResidentNV"); - return GL_FALSE; - } - if (prog->Resident) { - if (!allResident) - residences[i] = GL_TRUE; - } - else { - if (allResident) { - allResident = GL_FALSE; - for (j = 0; j < i; j++) - residences[j] = GL_TRUE; - } - residences[i] = GL_FALSE; - } - } - - return allResident; -} - - -/** - * Request that a set of programs be resident in hardware. - * \note Called from the GL API dispatcher. - */ -void GLAPIENTRY -_mesa_RequestResidentProgramsNV(GLsizei n, const GLuint *ids) -{ - GLint i; - GET_CURRENT_CONTEXT(ctx); - ASSERT_OUTSIDE_BEGIN_END(ctx); - - if (n < 0) { - _mesa_error(ctx, GL_INVALID_VALUE, "glRequestResidentProgramsNV(n)"); - return; - } - - /* just error checking for now */ - for (i = 0; i < n; i++) { - struct gl_program *prog; - - if (ids[i] == 0) { - _mesa_error(ctx, GL_INVALID_VALUE, "glRequestResidentProgramsNV(id)"); - return; - } - - prog = _mesa_lookup_program(ctx, ids[i]); - if (!prog) { - _mesa_error(ctx, GL_INVALID_VALUE, "glRequestResidentProgramsNV(id)"); - return; - } - - /* XXX this is really a hardware thing we should hook out */ - prog->Resident = GL_TRUE; - } -} - - -/** - * Get a program parameter register. - * \note Not compiled into display lists. - * \note Called from the GL API dispatcher. - */ -void GLAPIENTRY -_mesa_GetProgramParameterfvNV(GLenum target, GLuint index, - GLenum pname, GLfloat *params) -{ - GET_CURRENT_CONTEXT(ctx); - ASSERT_OUTSIDE_BEGIN_END(ctx); - - if (target == GL_VERTEX_PROGRAM_NV) { - if (pname == GL_PROGRAM_PARAMETER_NV) { - if (index < MAX_NV_VERTEX_PROGRAM_PARAMS) { - COPY_4V(params, ctx->VertexProgram.Parameters[index]); - } - else { - _mesa_error(ctx, GL_INVALID_VALUE, - "glGetProgramParameterfvNV(index)"); - return; - } - } - else { - _mesa_error(ctx, GL_INVALID_ENUM, "glGetProgramParameterfvNV(pname)"); - return; - } - } - else { - _mesa_error(ctx, GL_INVALID_ENUM, "glGetProgramParameterfvNV(target)"); - return; - } -} - - -/** - * Get a program parameter register. - * \note Not compiled into display lists. - * \note Called from the GL API dispatcher. - */ -void GLAPIENTRY -_mesa_GetProgramParameterdvNV(GLenum target, GLuint index, - GLenum pname, GLdouble *params) -{ - GET_CURRENT_CONTEXT(ctx); - ASSERT_OUTSIDE_BEGIN_END(ctx); - - if (target == GL_VERTEX_PROGRAM_NV) { - if (pname == GL_PROGRAM_PARAMETER_NV) { - if (index < MAX_NV_VERTEX_PROGRAM_PARAMS) { - COPY_4V(params, ctx->VertexProgram.Parameters[index]); - } - else { - _mesa_error(ctx, GL_INVALID_VALUE, - "glGetProgramParameterdvNV(index)"); - return; - } - } - else { - _mesa_error(ctx, GL_INVALID_ENUM, "glGetProgramParameterdvNV(pname)"); - return; - } - } - else { - _mesa_error(ctx, GL_INVALID_ENUM, "glGetProgramParameterdvNV(target)"); - return; - } -} - - -/** - * Get a program attribute. - * \note Not compiled into display lists. - * \note Called from the GL API dispatcher. - */ -void GLAPIENTRY -_mesa_GetProgramivNV(GLuint id, GLenum pname, GLint *params) -{ - struct gl_program *prog; - GET_CURRENT_CONTEXT(ctx); - - ASSERT_OUTSIDE_BEGIN_END(ctx); - - prog = _mesa_lookup_program(ctx, id); - if (!prog) { - _mesa_error(ctx, GL_INVALID_OPERATION, "glGetProgramivNV"); - return; - } - - switch (pname) { - case GL_PROGRAM_TARGET_NV: - *params = prog->Target; - return; - case GL_PROGRAM_LENGTH_NV: - *params = prog->String ?(GLint) strlen((char *) prog->String) : 0; - return; - case GL_PROGRAM_RESIDENT_NV: - *params = prog->Resident; - return; - default: - _mesa_error(ctx, GL_INVALID_ENUM, "glGetProgramivNV(pname)"); - return; - } -} - - -/** - * Get the program source code. - * \note Not compiled into display lists. - * \note Called from the GL API dispatcher. - */ -void GLAPIENTRY -_mesa_GetProgramStringNV(GLuint id, GLenum pname, GLubyte *program) -{ - struct gl_program *prog; - GET_CURRENT_CONTEXT(ctx); - - ASSERT_OUTSIDE_BEGIN_END(ctx); - - if (pname != GL_PROGRAM_STRING_NV) { - _mesa_error(ctx, GL_INVALID_ENUM, "glGetProgramStringNV(pname)"); - return; - } - - prog = _mesa_lookup_program(ctx, id); - if (!prog) { - _mesa_error(ctx, GL_INVALID_OPERATION, "glGetProgramStringNV"); - return; - } - - if (prog->String) { - memcpy(program, prog->String, strlen((char *) prog->String)); - } - else { - program[0] = 0; - } -} - - -/** - * Get matrix tracking information. - * \note Not compiled into display lists. - * \note Called from the GL API dispatcher. - */ -void GLAPIENTRY -_mesa_GetTrackMatrixivNV(GLenum target, GLuint address, - GLenum pname, GLint *params) -{ - GET_CURRENT_CONTEXT(ctx); - ASSERT_OUTSIDE_BEGIN_END(ctx); - - if (target == GL_VERTEX_PROGRAM_NV - && ctx->Extensions.NV_vertex_program) { - GLuint i; - - if ((address & 0x3) || address >= MAX_NV_VERTEX_PROGRAM_PARAMS) { - _mesa_error(ctx, GL_INVALID_VALUE, "glGetTrackMatrixivNV(address)"); - return; - } - - i = address / 4; - - switch (pname) { - case GL_TRACK_MATRIX_NV: - params[0] = (GLint) ctx->VertexProgram.TrackMatrix[i]; - return; - case GL_TRACK_MATRIX_TRANSFORM_NV: - params[0] = (GLint) ctx->VertexProgram.TrackMatrixTransform[i]; - return; - default: - _mesa_error(ctx, GL_INVALID_ENUM, "glGetTrackMatrixivNV"); - return; - } - } - else { - _mesa_error(ctx, GL_INVALID_ENUM, "glGetTrackMatrixivNV"); - return; - } -} - - -/** - * Get a vertex (or vertex array) attribute. - * \note Not compiled into display lists. - * \note Called from the GL API dispatcher. - */ -void GLAPIENTRY -_mesa_GetVertexAttribdvNV(GLuint index, GLenum pname, GLdouble *params) -{ - const struct gl_client_array *array; - GET_CURRENT_CONTEXT(ctx); - ASSERT_OUTSIDE_BEGIN_END(ctx); - - if (index >= MAX_NV_VERTEX_PROGRAM_INPUTS) { - _mesa_error(ctx, GL_INVALID_VALUE, "glGetVertexAttribdvNV(index)"); - return; - } - - array = &ctx->Array.ArrayObj->VertexAttrib[index]; - - switch (pname) { - case GL_ATTRIB_ARRAY_SIZE_NV: - params[0] = array->Size; - break; - case GL_ATTRIB_ARRAY_STRIDE_NV: - params[0] = array->Stride; - break; - case GL_ATTRIB_ARRAY_TYPE_NV: - params[0] = array->Type; - break; - case GL_CURRENT_ATTRIB_NV: - if (index == 0) { - _mesa_error(ctx, GL_INVALID_OPERATION, - "glGetVertexAttribdvNV(index == 0)"); - return; - } - FLUSH_CURRENT(ctx, 0); - COPY_4V(params, ctx->Current.Attrib[index]); - break; - default: - _mesa_error(ctx, GL_INVALID_ENUM, "glGetVertexAttribdvNV"); - return; - } -} - -/** - * Get a vertex (or vertex array) attribute. - * \note Not compiled into display lists. - * \note Called from the GL API dispatcher. - */ -void GLAPIENTRY -_mesa_GetVertexAttribfvNV(GLuint index, GLenum pname, GLfloat *params) -{ - const struct gl_client_array *array; - GET_CURRENT_CONTEXT(ctx); - ASSERT_OUTSIDE_BEGIN_END(ctx); - - if (index >= MAX_NV_VERTEX_PROGRAM_INPUTS) { - _mesa_error(ctx, GL_INVALID_VALUE, "glGetVertexAttribdvNV(index)"); - return; - } - - array = &ctx->Array.ArrayObj->VertexAttrib[index]; - - switch (pname) { - case GL_ATTRIB_ARRAY_SIZE_NV: - params[0] = (GLfloat) array->Size; - break; - case GL_ATTRIB_ARRAY_STRIDE_NV: - params[0] = (GLfloat) array->Stride; - break; - case GL_ATTRIB_ARRAY_TYPE_NV: - params[0] = (GLfloat) array->Type; - break; - case GL_CURRENT_ATTRIB_NV: - if (index == 0) { - _mesa_error(ctx, GL_INVALID_OPERATION, - "glGetVertexAttribfvNV(index == 0)"); - return; - } - FLUSH_CURRENT(ctx, 0); - COPY_4V(params, ctx->Current.Attrib[index]); - break; - default: - _mesa_error(ctx, GL_INVALID_ENUM, "glGetVertexAttribdvNV"); - return; - } -} - -/** - * Get a vertex (or vertex array) attribute. - * \note Not compiled into display lists. - * \note Called from the GL API dispatcher. - */ -void GLAPIENTRY -_mesa_GetVertexAttribivNV(GLuint index, GLenum pname, GLint *params) -{ - const struct gl_client_array *array; - GET_CURRENT_CONTEXT(ctx); - ASSERT_OUTSIDE_BEGIN_END(ctx); - - if (index >= MAX_NV_VERTEX_PROGRAM_INPUTS) { - _mesa_error(ctx, GL_INVALID_VALUE, "glGetVertexAttribdvNV(index)"); - return; - } - - array = &ctx->Array.ArrayObj->VertexAttrib[index]; - - switch (pname) { - case GL_ATTRIB_ARRAY_SIZE_NV: - params[0] = array->Size; - break; - case GL_ATTRIB_ARRAY_STRIDE_NV: - params[0] = array->Stride; - break; - case GL_ATTRIB_ARRAY_TYPE_NV: - params[0] = array->Type; - break; - case GL_CURRENT_ATTRIB_NV: - if (index == 0) { - _mesa_error(ctx, GL_INVALID_OPERATION, - "glGetVertexAttribivNV(index == 0)"); - return; - } - FLUSH_CURRENT(ctx, 0); - params[0] = (GLint) ctx->Current.Attrib[index][0]; - params[1] = (GLint) ctx->Current.Attrib[index][1]; - params[2] = (GLint) ctx->Current.Attrib[index][2]; - params[3] = (GLint) ctx->Current.Attrib[index][3]; - break; - case GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING_ARB: - params[0] = array->BufferObj->Name; - break; - default: - _mesa_error(ctx, GL_INVALID_ENUM, "glGetVertexAttribdvNV"); - return; - } -} - - -/** - * Get a vertex array attribute pointer. - * \note Not compiled into display lists. - * \note Called from the GL API dispatcher. - */ -void GLAPIENTRY -_mesa_GetVertexAttribPointervNV(GLuint index, GLenum pname, GLvoid **pointer) -{ - GET_CURRENT_CONTEXT(ctx); - ASSERT_OUTSIDE_BEGIN_END(ctx); - - if (index >= MAX_NV_VERTEX_PROGRAM_INPUTS) { - _mesa_error(ctx, GL_INVALID_VALUE, "glGetVertexAttribPointerNV(index)"); - return; - } - - if (pname != GL_ATTRIB_ARRAY_POINTER_NV) { - _mesa_error(ctx, GL_INVALID_ENUM, "glGetVertexAttribPointerNV(pname)"); - return; - } - - *pointer = (GLvoid *) ctx->Array.ArrayObj->VertexAttrib[index].Ptr; -} - -void -_mesa_emit_nv_temp_initialization(GLcontext *ctx, - struct gl_program *program) -{ - struct prog_instruction *inst; - GLuint i; - - if (!ctx->Shader.EmitNVTempInitialization) - return; - - /* We'll swizzle up a zero temporary so we can use it for the - * ARL. - */ - if (program->NumTemporaries == 0) - program->NumTemporaries = 1; - - _mesa_insert_instructions(program, 0, program->NumTemporaries + 1); - - for (i = 0; i < program->NumTemporaries; i++) { - struct prog_instruction *inst = &program->Instructions[i]; - - inst->Opcode = OPCODE_SWZ; - inst->DstReg.File = PROGRAM_TEMPORARY; - inst->DstReg.Index = i; - inst->DstReg.WriteMask = WRITEMASK_XYZW; - inst->SrcReg[0].File = PROGRAM_TEMPORARY; - inst->SrcReg[0].Index = 0; - inst->SrcReg[0].Swizzle = MAKE_SWIZZLE4(SWIZZLE_ZERO, - SWIZZLE_ZERO, - SWIZZLE_ZERO, - SWIZZLE_ZERO); - } - - inst = &program->Instructions[i]; - inst->Opcode = OPCODE_ARL; - inst->DstReg.File = PROGRAM_ADDRESS; - inst->DstReg.Index = 0; - inst->DstReg.WriteMask = WRITEMASK_XYZW; - inst->SrcReg[0].File = PROGRAM_TEMPORARY; - inst->SrcReg[0].Index = 0; - inst->SrcReg[0].Swizzle = SWIZZLE_XXXX; - - if (program->NumAddressRegs == 0) - program->NumAddressRegs = 1; -} - -void -_mesa_setup_nv_temporary_count(GLcontext *ctx, struct gl_program *program) -{ - GLuint i; - - program->NumTemporaries = 0; - for (i = 0; i < program->NumInstructions; i++) { - struct prog_instruction *inst = &program->Instructions[i]; - - if (inst->DstReg.File == PROGRAM_TEMPORARY) { - program->NumTemporaries = MAX2(program->NumTemporaries, - inst->DstReg.Index + 1); - } - if (inst->SrcReg[0].File == PROGRAM_TEMPORARY) { - program->NumTemporaries = MAX2((GLint)program->NumTemporaries, - inst->SrcReg[0].Index + 1); - } - if (inst->SrcReg[1].File == PROGRAM_TEMPORARY) { - program->NumTemporaries = MAX2((GLint)program->NumTemporaries, - inst->SrcReg[1].Index + 1); - } - if (inst->SrcReg[2].File == PROGRAM_TEMPORARY) { - program->NumTemporaries = MAX2((GLint)program->NumTemporaries, - inst->SrcReg[2].Index + 1); - } - } -} - -/** - * Load/parse/compile a program. - * \note Called from the GL API dispatcher. - */ -void GLAPIENTRY -_mesa_LoadProgramNV(GLenum target, GLuint id, GLsizei len, - const GLubyte *program) -{ - struct gl_program *prog; - GET_CURRENT_CONTEXT(ctx); - ASSERT_OUTSIDE_BEGIN_END(ctx); - - if (!ctx->Extensions.NV_vertex_program - && !ctx->Extensions.NV_fragment_program) { - _mesa_error(ctx, GL_INVALID_OPERATION, "glLoadProgramNV()"); - return; - } - - if (id == 0) { - _mesa_error(ctx, GL_INVALID_VALUE, "glLoadProgramNV(id)"); - return; - } - - if (len < 0) { - _mesa_error(ctx, GL_INVALID_VALUE, "glLoadProgramNV(len)"); - return; - } - - FLUSH_VERTICES(ctx, _NEW_PROGRAM); - - prog = _mesa_lookup_program(ctx, id); - - if (prog && prog->Target != 0 && prog->Target != target) { - _mesa_error(ctx, GL_INVALID_OPERATION, "glLoadProgramNV(target)"); - return; - } - - if ((target == GL_VERTEX_PROGRAM_NV || - target == GL_VERTEX_STATE_PROGRAM_NV) - && ctx->Extensions.NV_vertex_program) { - struct gl_vertex_program *vprog = (struct gl_vertex_program *) prog; - if (!vprog || prog == &_mesa_DummyProgram) { - vprog = (struct gl_vertex_program *) - ctx->Driver.NewProgram(ctx, target, id); - if (!vprog) { - _mesa_error(ctx, GL_OUT_OF_MEMORY, "glLoadProgramNV"); - return; - } - _mesa_HashInsert(ctx->Shared->Programs, id, vprog); - } - - if (ctx->Extensions.ARB_vertex_program - && (strncmp((char *) program, "!!ARB", 5) == 0)) { - _mesa_parse_arb_vertex_program(ctx, target, program, len, vprog); - } else { - _mesa_parse_nv_vertex_program(ctx, target, program, len, vprog); - } - } - else if (target == GL_FRAGMENT_PROGRAM_NV - && ctx->Extensions.NV_fragment_program) { - struct gl_fragment_program *fprog = (struct gl_fragment_program *) prog; - if (!fprog || prog == &_mesa_DummyProgram) { - fprog = (struct gl_fragment_program *) - ctx->Driver.NewProgram(ctx, target, id); - if (!fprog) { - _mesa_error(ctx, GL_OUT_OF_MEMORY, "glLoadProgramNV"); - return; - } - _mesa_HashInsert(ctx->Shared->Programs, id, fprog); - } - _mesa_parse_nv_fragment_program(ctx, target, program, len, fprog); - } - else if (target == GL_FRAGMENT_PROGRAM_ARB - && ctx->Extensions.ARB_fragment_program) { - struct gl_fragment_program *fprog = (struct gl_fragment_program *) prog; - if (!fprog || prog == &_mesa_DummyProgram) { - fprog = (struct gl_fragment_program *) - ctx->Driver.NewProgram(ctx, target, id); - if (!fprog) { - _mesa_error(ctx, GL_OUT_OF_MEMORY, "glLoadProgramNV"); - return; - } - _mesa_HashInsert(ctx->Shared->Programs, id, fprog); - } - _mesa_parse_arb_fragment_program(ctx, target, program, len, fprog); - } - else { - _mesa_error(ctx, GL_INVALID_ENUM, "glLoadProgramNV(target)"); - } -} - - - -/** - * Set a sequence of program parameter registers. - * \note Called from the GL API dispatcher. - */ -void GLAPIENTRY -_mesa_ProgramParameters4dvNV(GLenum target, GLuint index, - GLuint num, const GLdouble *params) -{ - GET_CURRENT_CONTEXT(ctx); - ASSERT_OUTSIDE_BEGIN_END(ctx); - - if (target == GL_VERTEX_PROGRAM_NV && ctx->Extensions.NV_vertex_program) { - GLuint i; - if (index + num > MAX_NV_VERTEX_PROGRAM_PARAMS) { - _mesa_error(ctx, GL_INVALID_VALUE, "glProgramParameters4dvNV"); - return; - } - for (i = 0; i < num; i++) { - ctx->VertexProgram.Parameters[index + i][0] = (GLfloat) params[0]; - ctx->VertexProgram.Parameters[index + i][1] = (GLfloat) params[1]; - ctx->VertexProgram.Parameters[index + i][2] = (GLfloat) params[2]; - ctx->VertexProgram.Parameters[index + i][3] = (GLfloat) params[3]; - params += 4; - }; - } - else { - _mesa_error(ctx, GL_INVALID_ENUM, "glProgramParameters4dvNV"); - return; - } -} - - -/** - * Set a sequence of program parameter registers. - * \note Called from the GL API dispatcher. - */ -void GLAPIENTRY -_mesa_ProgramParameters4fvNV(GLenum target, GLuint index, - GLuint num, const GLfloat *params) -{ - GET_CURRENT_CONTEXT(ctx); - ASSERT_OUTSIDE_BEGIN_END(ctx); - - if (target == GL_VERTEX_PROGRAM_NV && ctx->Extensions.NV_vertex_program) { - GLuint i; - if (index + num > MAX_NV_VERTEX_PROGRAM_PARAMS) { - _mesa_error(ctx, GL_INVALID_VALUE, "glProgramParameters4fvNV"); - return; - } - for (i = 0; i < num; i++) { - COPY_4V(ctx->VertexProgram.Parameters[index + i], params); - params += 4; - } - } - else { - _mesa_error(ctx, GL_INVALID_ENUM, "glProgramParameters4fvNV"); - return; - } -} - - - -/** - * Setup tracking of matrices into program parameter registers. - * \note Called from the GL API dispatcher. - */ -void GLAPIENTRY -_mesa_TrackMatrixNV(GLenum target, GLuint address, - GLenum matrix, GLenum transform) -{ - GET_CURRENT_CONTEXT(ctx); - ASSERT_OUTSIDE_BEGIN_END(ctx); - - FLUSH_VERTICES(ctx, _NEW_PROGRAM); - - if (target == GL_VERTEX_PROGRAM_NV && ctx->Extensions.NV_vertex_program) { - if (address & 0x3) { - /* addr must be multiple of four */ - _mesa_error(ctx, GL_INVALID_VALUE, "glTrackMatrixNV(address)"); - return; - } - - switch (matrix) { - case GL_NONE: - case GL_MODELVIEW: - case GL_PROJECTION: - case GL_TEXTURE: - case GL_COLOR: - case GL_MODELVIEW_PROJECTION_NV: - case GL_MATRIX0_NV: - case GL_MATRIX1_NV: - case GL_MATRIX2_NV: - case GL_MATRIX3_NV: - case GL_MATRIX4_NV: - case GL_MATRIX5_NV: - case GL_MATRIX6_NV: - case GL_MATRIX7_NV: - /* OK, fallthrough */ - break; - default: - _mesa_error(ctx, GL_INVALID_ENUM, "glTrackMatrixNV(matrix)"); - return; - } - - switch (transform) { - case GL_IDENTITY_NV: - case GL_INVERSE_NV: - case GL_TRANSPOSE_NV: - case GL_INVERSE_TRANSPOSE_NV: - /* OK, fallthrough */ - break; - default: - _mesa_error(ctx, GL_INVALID_ENUM, "glTrackMatrixNV(transform)"); - return; - } - - ctx->VertexProgram.TrackMatrix[address / 4] = matrix; - ctx->VertexProgram.TrackMatrixTransform[address / 4] = transform; - } - else { - _mesa_error(ctx, GL_INVALID_ENUM, "glTrackMatrixNV(target)"); - return; - } -} - - -void GLAPIENTRY -_mesa_ProgramNamedParameter4fNV(GLuint id, GLsizei len, const GLubyte *name, - GLfloat x, GLfloat y, GLfloat z, GLfloat w) -{ - struct gl_program *prog; - struct gl_fragment_program *fragProg; - GLfloat *v; - - GET_CURRENT_CONTEXT(ctx); - ASSERT_OUTSIDE_BEGIN_END(ctx); - - FLUSH_VERTICES(ctx, _NEW_PROGRAM_CONSTANTS); - - prog = _mesa_lookup_program(ctx, id); - if (!prog || prog->Target != GL_FRAGMENT_PROGRAM_NV) { - _mesa_error(ctx, GL_INVALID_OPERATION, "glProgramNamedParameterNV"); - return; - } - - if (len <= 0) { - _mesa_error(ctx, GL_INVALID_VALUE, "glProgramNamedParameterNV(len)"); - return; - } - - fragProg = (struct gl_fragment_program *) prog; - v = _mesa_lookup_parameter_value(fragProg->Base.Parameters, len, - (char *) name); - if (v) { - v[0] = x; - v[1] = y; - v[2] = z; - v[3] = w; - return; - } - - _mesa_error(ctx, GL_INVALID_VALUE, "glProgramNamedParameterNV(name)"); -} - - -void GLAPIENTRY -_mesa_ProgramNamedParameter4fvNV(GLuint id, GLsizei len, const GLubyte *name, - const float v[]) -{ - _mesa_ProgramNamedParameter4fNV(id, len, name, v[0], v[1], v[2], v[3]); -} - - -void GLAPIENTRY -_mesa_ProgramNamedParameter4dNV(GLuint id, GLsizei len, const GLubyte *name, - GLdouble x, GLdouble y, GLdouble z, GLdouble w) -{ - _mesa_ProgramNamedParameter4fNV(id, len, name, (GLfloat)x, (GLfloat)y, - (GLfloat)z, (GLfloat)w); -} - - -void GLAPIENTRY -_mesa_ProgramNamedParameter4dvNV(GLuint id, GLsizei len, const GLubyte *name, - const double v[]) -{ - _mesa_ProgramNamedParameter4fNV(id, len, name, - (GLfloat)v[0], (GLfloat)v[1], - (GLfloat)v[2], (GLfloat)v[3]); -} - - -void GLAPIENTRY -_mesa_GetProgramNamedParameterfvNV(GLuint id, GLsizei len, const GLubyte *name, - GLfloat *params) -{ - struct gl_program *prog; - struct gl_fragment_program *fragProg; - const GLfloat *v; - - GET_CURRENT_CONTEXT(ctx); - - ASSERT_OUTSIDE_BEGIN_END(ctx); - - prog = _mesa_lookup_program(ctx, id); - if (!prog || prog->Target != GL_FRAGMENT_PROGRAM_NV) { - _mesa_error(ctx, GL_INVALID_OPERATION, "glGetProgramNamedParameterNV"); - return; - } - - if (len <= 0) { - _mesa_error(ctx, GL_INVALID_VALUE, "glGetProgramNamedParameterNV"); - return; - } - - fragProg = (struct gl_fragment_program *) prog; - v = _mesa_lookup_parameter_value(fragProg->Base.Parameters, - len, (char *) name); - if (v) { - params[0] = v[0]; - params[1] = v[1]; - params[2] = v[2]; - params[3] = v[3]; - return; - } - - _mesa_error(ctx, GL_INVALID_VALUE, "glGetProgramNamedParameterNV"); -} - - -void GLAPIENTRY -_mesa_GetProgramNamedParameterdvNV(GLuint id, GLsizei len, const GLubyte *name, - GLdouble *params) -{ - GLfloat floatParams[4]; - _mesa_GetProgramNamedParameterfvNV(id, len, name, floatParams); - COPY_4V(params, floatParams); -} diff --git a/mesalib/src/mesa/shader/nvprogram.h b/mesalib/src/mesa/shader/nvprogram.h deleted file mode 100644 index 8ee59661b..000000000 --- a/mesalib/src/mesa/shader/nvprogram.h +++ /dev/null @@ -1,113 +0,0 @@ -/* - * Mesa 3-D graphics library - * Version: 5.1 - * - * Copyright (C) 1999-2003 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: - * Brian Paul - */ - - -#ifndef NVPROGRAM_H -#define NVPROGRAM_H - - -extern void GLAPIENTRY -_mesa_ExecuteProgramNV(GLenum target, GLuint id, const GLfloat *params); - -extern GLboolean GLAPIENTRY -_mesa_AreProgramsResidentNV(GLsizei n, const GLuint *ids, GLboolean *residences); - -extern void GLAPIENTRY -_mesa_RequestResidentProgramsNV(GLsizei n, const GLuint *ids); - -extern void GLAPIENTRY -_mesa_GetProgramParameterfvNV(GLenum target, GLuint index, GLenum pname, GLfloat *params); - -extern void GLAPIENTRY -_mesa_GetProgramParameterdvNV(GLenum target, GLuint index, GLenum pname, GLdouble *params); - -extern void GLAPIENTRY -_mesa_GetProgramivNV(GLuint id, GLenum pname, GLint *params); - -extern void GLAPIENTRY -_mesa_GetProgramStringNV(GLuint id, GLenum pname, GLubyte *program); - -extern void GLAPIENTRY -_mesa_GetTrackMatrixivNV(GLenum target, GLuint address, GLenum pname, GLint *params); - -extern void GLAPIENTRY -_mesa_GetVertexAttribdvNV(GLuint index, GLenum pname, GLdouble *params); - -extern void GLAPIENTRY -_mesa_GetVertexAttribfvNV(GLuint index, GLenum pname, GLfloat *params); - -extern void GLAPIENTRY -_mesa_GetVertexAttribivNV(GLuint index, GLenum pname, GLint *params); - -extern void GLAPIENTRY -_mesa_GetVertexAttribPointervNV(GLuint index, GLenum pname, GLvoid **pointer); - -extern void GLAPIENTRY -_mesa_LoadProgramNV(GLenum target, GLuint id, GLsizei len, const GLubyte *program); - -extern void GLAPIENTRY -_mesa_ProgramParameters4dvNV(GLenum target, GLuint index, GLuint num, const GLdouble *params); - -extern void GLAPIENTRY -_mesa_ProgramParameters4fvNV(GLenum target, GLuint index, GLuint num, const GLfloat *params); - -extern void GLAPIENTRY -_mesa_TrackMatrixNV(GLenum target, GLuint address, GLenum matrix, GLenum transform); - - -extern void GLAPIENTRY -_mesa_ProgramNamedParameter4fNV(GLuint id, GLsizei len, const GLubyte *name, - GLfloat x, GLfloat y, GLfloat z, GLfloat w); - -extern void GLAPIENTRY -_mesa_ProgramNamedParameter4fvNV(GLuint id, GLsizei len, const GLubyte *name, - const float v[]); - -extern void GLAPIENTRY -_mesa_ProgramNamedParameter4dNV(GLuint id, GLsizei len, const GLubyte *name, - GLdouble x, GLdouble y, GLdouble z, GLdouble w); - -extern void GLAPIENTRY -_mesa_ProgramNamedParameter4dvNV(GLuint id, GLsizei len, const GLubyte *name, - const double v[]); - -extern void GLAPIENTRY -_mesa_GetProgramNamedParameterfvNV(GLuint id, GLsizei len, const GLubyte *name, - GLfloat *params); - -extern void GLAPIENTRY -_mesa_GetProgramNamedParameterdvNV(GLuint id, GLsizei len, const GLubyte *name, - GLdouble *params); - -extern void -_mesa_setup_nv_temporary_count(GLcontext *ctx, struct gl_program *program); - -extern void -_mesa_emit_nv_temp_initialization(GLcontext *ctx, - struct gl_program *program); - -#endif diff --git a/mesalib/src/mesa/shader/nvvertparse.c b/mesalib/src/mesa/shader/nvvertparse.c deleted file mode 100644 index 631b315af..000000000 --- a/mesalib/src/mesa/shader/nvvertparse.c +++ /dev/null @@ -1,1454 +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 nvvertparse.c - * NVIDIA vertex program parser. - * \author Brian Paul - */ - -/* - * Regarding GL_NV_vertex_program, GL_NV_vertex_program1_1: - * - * 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 "main/glheader.h" -#include "main/context.h" -#include "main/imports.h" -#include "nvprogram.h" -#include "nvvertparse.h" -#include "prog_instruction.h" -#include "prog_parameter.h" -#include "prog_print.h" -#include "program.h" - - -/** - * Current parsing state. This structure is passed among the parsing - * functions and keeps track of the current parser position and various - * program attributes. - */ -struct parse_state { - GLcontext *ctx; - const GLubyte *start; - const GLubyte *pos; - const GLubyte *curLine; - GLboolean isStateProgram; - GLboolean isPositionInvariant; - GLboolean isVersion1_1; - GLbitfield inputsRead; - GLbitfield outputsWritten; - GLboolean anyProgRegsWritten; - GLuint numInst; /* number of instructions parsed */ -}; - - -/* - * Called whenever we find an error during parsing. - */ -static void -record_error(struct parse_state *parseState, const char *msg, int lineNo) -{ -#ifdef DEBUG - GLint line, column; - const GLubyte *lineStr; - lineStr = _mesa_find_line_column(parseState->start, - parseState->pos, &line, &column); - _mesa_debug(parseState->ctx, - "nvfragparse.c(%d): line %d, column %d:%s (%s)\n", - lineNo, line, column, (char *) lineStr, msg); - free((void *) lineStr); -#else - (void) lineNo; -#endif - - /* Check that no error was already recorded. Only record the first one. */ - if (parseState->ctx->Program.ErrorString[0] == 0) { - _mesa_set_program_error(parseState->ctx, - parseState->pos - parseState->start, - msg); - } -} - - -#define RETURN_ERROR \ -do { \ - record_error(parseState, "Unexpected end of input.", __LINE__); \ - return GL_FALSE; \ -} while(0) - -#define RETURN_ERROR1(msg) \ -do { \ - record_error(parseState, msg, __LINE__); \ - return GL_FALSE; \ -} while(0) - -#define RETURN_ERROR2(msg1, msg2) \ -do { \ - char err[1000]; \ - sprintf(err, "%s %s", msg1, msg2); \ - record_error(parseState, err, __LINE__); \ - return GL_FALSE; \ -} while(0) - - - - - -static GLboolean IsLetter(GLubyte b) -{ - return (b >= 'a' && b <= 'z') || (b >= 'A' && b <= 'Z'); -} - - -static GLboolean IsDigit(GLubyte b) -{ - return b >= '0' && b <= '9'; -} - - -static GLboolean IsWhitespace(GLubyte b) -{ - return b == ' ' || b == '\t' || b == '\n' || b == '\r'; -} - - -/** - * Starting at 'str' find the next token. A token can be an integer, - * an identifier or punctuation symbol. - * \return <= 0 we found an error, else, return number of characters parsed. - */ -static GLint -GetToken(struct parse_state *parseState, GLubyte *token) -{ - const GLubyte *str = parseState->pos; - GLint i = 0, j = 0; - - token[0] = 0; - - /* skip whitespace and comments */ - while (str[i] && (IsWhitespace(str[i]) || str[i] == '#')) { - if (str[i] == '#') { - /* skip comment */ - while (str[i] && (str[i] != '\n' && str[i] != '\r')) { - i++; - } - if (str[i] == '\n' || str[i] == '\r') - parseState->curLine = str + i + 1; - } - else { - /* skip whitespace */ - if (str[i] == '\n' || str[i] == '\r') - parseState->curLine = str + i + 1; - i++; - } - } - - if (str[i] == 0) - return -i; - - /* try matching an integer */ - while (str[i] && IsDigit(str[i])) { - token[j++] = str[i++]; - } - if (j > 0 || !str[i]) { - token[j] = 0; - return i; - } - - /* try matching an identifier */ - if (IsLetter(str[i])) { - while (str[i] && (IsLetter(str[i]) || IsDigit(str[i]))) { - token[j++] = str[i++]; - } - token[j] = 0; - return i; - } - - /* punctuation character */ - if (str[i]) { - token[0] = str[i++]; - token[1] = 0; - return i; - } - - /* end of input */ - token[0] = 0; - return i; -} - - -/** - * Get next token from input stream and increment stream pointer past token. - */ -static GLboolean -Parse_Token(struct parse_state *parseState, GLubyte *token) -{ - GLint i; - i = GetToken(parseState, token); - if (i <= 0) { - parseState->pos += (-i); - return GL_FALSE; - } - parseState->pos += i; - return GL_TRUE; -} - - -/** - * Get next token from input stream but don't increment stream pointer. - */ -static GLboolean -Peek_Token(struct parse_state *parseState, GLubyte *token) -{ - GLint i, len; - i = GetToken(parseState, token); - if (i <= 0) { - parseState->pos += (-i); - return GL_FALSE; - } - len = (GLint) strlen((const char *) token); - parseState->pos += (i - len); - return GL_TRUE; -} - - -/** - * Try to match 'pattern' as the next token after any whitespace/comments. - * Advance the current parsing position only if we match the pattern. - * \return GL_TRUE if pattern is matched, GL_FALSE otherwise. - */ -static GLboolean -Parse_String(struct parse_state *parseState, const char *pattern) -{ - const GLubyte *m; - GLint i; - - /* skip whitespace and comments */ - while (IsWhitespace(*parseState->pos) || *parseState->pos == '#') { - if (*parseState->pos == '#') { - while (*parseState->pos && (*parseState->pos != '\n' && *parseState->pos != '\r')) { - parseState->pos += 1; - } - if (*parseState->pos == '\n' || *parseState->pos == '\r') - parseState->curLine = parseState->pos + 1; - } - else { - /* skip whitespace */ - if (*parseState->pos == '\n' || *parseState->pos == '\r') - parseState->curLine = parseState->pos + 1; - parseState->pos += 1; - } - } - - /* Try to match the pattern */ - m = parseState->pos; - for (i = 0; pattern[i]; i++) { - if (*m != (GLubyte) pattern[i]) - return GL_FALSE; - m += 1; - } - parseState->pos = m; - - return GL_TRUE; /* success */ -} - - -/**********************************************************************/ - -static const char *InputRegisters[MAX_NV_VERTEX_PROGRAM_INPUTS + 1] = { - "OPOS", "WGHT", "NRML", "COL0", "COL1", "FOGC", "6", "7", - "TEX0", "TEX1", "TEX2", "TEX3", "TEX4", "TEX5", "TEX6", "TEX7", NULL -}; - -static const char *OutputRegisters[MAX_NV_VERTEX_PROGRAM_OUTPUTS + 1] = { - "HPOS", "COL0", "COL1", "FOGC", - "TEX0", "TEX1", "TEX2", "TEX3", "TEX4", "TEX5", "TEX6", "TEX7", - "PSIZ", "BFC0", "BFC1", NULL -}; - - - -/** - * Parse a temporary register: Rnn - */ -static GLboolean -Parse_TempReg(struct parse_state *parseState, GLint *tempRegNum) -{ - GLubyte token[100]; - - /* Should be 'R##' */ - if (!Parse_Token(parseState, token)) - RETURN_ERROR; - if (token[0] != 'R') - RETURN_ERROR1("Expected R##"); - - if (IsDigit(token[1])) { - GLint reg = atoi((char *) (token + 1)); - if (reg >= MAX_NV_VERTEX_PROGRAM_TEMPS) - RETURN_ERROR1("Bad temporary register name"); - *tempRegNum = reg; - } - else { - RETURN_ERROR1("Bad temporary register name"); - } - - return GL_TRUE; -} - - -/** - * Parse address register "A0.x" - */ -static GLboolean -Parse_AddrReg(struct parse_state *parseState) -{ - /* match 'A0' */ - if (!Parse_String(parseState, "A0")) - RETURN_ERROR; - - /* match '.' */ - if (!Parse_String(parseState, ".")) - RETURN_ERROR; - - /* match 'x' */ - if (!Parse_String(parseState, "x")) - RETURN_ERROR; - - return GL_TRUE; -} - - -/** - * Parse absolute program parameter register "c[##]" - */ -static GLboolean -Parse_AbsParamReg(struct parse_state *parseState, GLint *regNum) -{ - GLubyte token[100]; - - if (!Parse_String(parseState, "c")) - RETURN_ERROR; - - if (!Parse_String(parseState, "[")) - RETURN_ERROR; - - if (!Parse_Token(parseState, token)) - RETURN_ERROR; - - if (IsDigit(token[0])) { - /* a numbered program parameter register */ - GLint reg = atoi((char *) token); - if (reg >= MAX_NV_VERTEX_PROGRAM_PARAMS) - RETURN_ERROR1("Bad program parameter number"); - *regNum = reg; - } - else { - RETURN_ERROR; - } - - if (!Parse_String(parseState, "]")) - RETURN_ERROR; - - return GL_TRUE; -} - - -static GLboolean -Parse_ParamReg(struct parse_state *parseState, struct prog_src_register *srcReg) -{ - GLubyte token[100]; - - if (!Parse_String(parseState, "c")) - RETURN_ERROR; - - if (!Parse_String(parseState, "[")) - RETURN_ERROR; - - if (!Peek_Token(parseState, token)) - RETURN_ERROR; - - if (IsDigit(token[0])) { - /* a numbered program parameter register */ - GLint reg; - (void) Parse_Token(parseState, token); - reg = atoi((char *) token); - if (reg >= MAX_NV_VERTEX_PROGRAM_PARAMS) - RETURN_ERROR1("Bad program parameter number"); - srcReg->File = PROGRAM_ENV_PARAM; - srcReg->Index = reg; - } - else if (strcmp((const char *) token, "A0") == 0) { - /* address register "A0.x" */ - if (!Parse_AddrReg(parseState)) - RETURN_ERROR; - - srcReg->RelAddr = GL_TRUE; - srcReg->File = PROGRAM_ENV_PARAM; - /* Look for +/-N offset */ - if (!Peek_Token(parseState, token)) - RETURN_ERROR; - - if (token[0] == '-' || token[0] == '+') { - const GLubyte sign = token[0]; - (void) Parse_Token(parseState, token); /* consume +/- */ - - /* an integer should be next */ - if (!Parse_Token(parseState, token)) - RETURN_ERROR; - - if (IsDigit(token[0])) { - const GLint k = atoi((char *) token); - if (sign == '-') { - if (k > 64) - RETURN_ERROR1("Bad address offset"); - srcReg->Index = -k; - } - else { - if (k > 63) - RETURN_ERROR1("Bad address offset"); - srcReg->Index = k; - } - } - else { - RETURN_ERROR; - } - } - else { - /* probably got a ']', catch it below */ - } - } - else { - RETURN_ERROR; - } - - /* Match closing ']' */ - if (!Parse_String(parseState, "]")) - RETURN_ERROR; - - return GL_TRUE; -} - - -/** - * Parse v[#] or v[<name>] - */ -static GLboolean -Parse_AttribReg(struct parse_state *parseState, GLint *tempRegNum) -{ - GLubyte token[100]; - GLint j; - - /* Match 'v' */ - if (!Parse_String(parseState, "v")) - RETURN_ERROR; - - /* Match '[' */ - if (!Parse_String(parseState, "[")) - RETURN_ERROR; - - /* match number or named register */ - if (!Parse_Token(parseState, token)) - RETURN_ERROR; - - if (parseState->isStateProgram && token[0] != '0') - RETURN_ERROR1("Only v[0] accessible in vertex state programs"); - - if (IsDigit(token[0])) { - GLint reg = atoi((char *) token); - if (reg >= MAX_NV_VERTEX_PROGRAM_INPUTS) - RETURN_ERROR1("Bad vertex attribute register name"); - *tempRegNum = reg; - } - else { - for (j = 0; InputRegisters[j]; j++) { - if (strcmp((const char *) token, InputRegisters[j]) == 0) { - *tempRegNum = j; - break; - } - } - if (!InputRegisters[j]) { - /* unknown input register label */ - RETURN_ERROR2("Bad register name", token); - } - } - - /* Match '[' */ - if (!Parse_String(parseState, "]")) - RETURN_ERROR; - - return GL_TRUE; -} - - -static GLboolean -Parse_OutputReg(struct parse_state *parseState, GLint *outputRegNum) -{ - GLubyte token[100]; - GLint start, j; - - /* Match 'o' */ - if (!Parse_String(parseState, "o")) - RETURN_ERROR; - - /* Match '[' */ - if (!Parse_String(parseState, "[")) - RETURN_ERROR; - - /* Get output reg name */ - if (!Parse_Token(parseState, token)) - RETURN_ERROR; - - if (parseState->isPositionInvariant) - start = 1; /* skip HPOS register name */ - else - start = 0; - - /* try to match an output register name */ - for (j = start; OutputRegisters[j]; j++) { - if (strcmp((const char *) token, OutputRegisters[j]) == 0) { - *outputRegNum = j; - break; - } - } - if (!OutputRegisters[j]) - RETURN_ERROR1("Unrecognized output register name"); - - /* Match ']' */ - if (!Parse_String(parseState, "]")) - RETURN_ERROR1("Expected ]"); - - return GL_TRUE; -} - - -static GLboolean -Parse_MaskedDstReg(struct parse_state *parseState, struct prog_dst_register *dstReg) -{ - GLubyte token[100]; - GLint idx; - - /* Dst reg can be R<n> or o[n] */ - if (!Peek_Token(parseState, token)) - RETURN_ERROR; - - if (token[0] == 'R') { - /* a temporary register */ - dstReg->File = PROGRAM_TEMPORARY; - if (!Parse_TempReg(parseState, &idx)) - RETURN_ERROR; - dstReg->Index = idx; - } - else if (!parseState->isStateProgram && token[0] == 'o') { - /* an output register */ - dstReg->File = PROGRAM_OUTPUT; - if (!Parse_OutputReg(parseState, &idx)) - RETURN_ERROR; - dstReg->Index = idx; - } - else if (parseState->isStateProgram && token[0] == 'c' && - parseState->isStateProgram) { - /* absolute program parameter register */ - /* Only valid for vertex state programs */ - dstReg->File = PROGRAM_ENV_PARAM; - if (!Parse_AbsParamReg(parseState, &idx)) - RETURN_ERROR; - dstReg->Index = idx; - } - else { - RETURN_ERROR1("Bad destination register name"); - } - - /* Parse optional write mask */ - if (!Peek_Token(parseState, token)) - RETURN_ERROR; - - if (token[0] == '.') { - /* got a mask */ - GLint k = 0; - - if (!Parse_String(parseState, ".")) - RETURN_ERROR; - - if (!Parse_Token(parseState, token)) - RETURN_ERROR; - - dstReg->WriteMask = 0; - - if (token[k] == 'x') { - dstReg->WriteMask |= WRITEMASK_X; - k++; - } - if (token[k] == 'y') { - dstReg->WriteMask |= WRITEMASK_Y; - k++; - } - if (token[k] == 'z') { - dstReg->WriteMask |= WRITEMASK_Z; - k++; - } - if (token[k] == 'w') { - dstReg->WriteMask |= WRITEMASK_W; - k++; - } - if (k == 0) { - RETURN_ERROR1("Bad writemask character"); - } - return GL_TRUE; - } - else { - dstReg->WriteMask = WRITEMASK_XYZW; - return GL_TRUE; - } -} - - -static GLboolean -Parse_SwizzleSrcReg(struct parse_state *parseState, struct prog_src_register *srcReg) -{ - GLubyte token[100]; - GLint idx; - - srcReg->RelAddr = GL_FALSE; - - /* check for '-' */ - if (!Peek_Token(parseState, token)) - RETURN_ERROR; - if (token[0] == '-') { - (void) Parse_String(parseState, "-"); - srcReg->Negate = NEGATE_XYZW; - if (!Peek_Token(parseState, token)) - RETURN_ERROR; - } - else { - srcReg->Negate = NEGATE_NONE; - } - - /* Src reg can be R<n>, c[n], c[n +/- offset], or a named vertex attrib */ - if (token[0] == 'R') { - srcReg->File = PROGRAM_TEMPORARY; - if (!Parse_TempReg(parseState, &idx)) - RETURN_ERROR; - srcReg->Index = idx; - } - else if (token[0] == 'c') { - if (!Parse_ParamReg(parseState, srcReg)) - RETURN_ERROR; - } - else if (token[0] == 'v') { - srcReg->File = PROGRAM_INPUT; - if (!Parse_AttribReg(parseState, &idx)) - RETURN_ERROR; - srcReg->Index = idx; - } - else { - RETURN_ERROR2("Bad source register name", token); - } - - /* init swizzle fields */ - srcReg->Swizzle = SWIZZLE_NOOP; - - /* Look for optional swizzle suffix */ - if (!Peek_Token(parseState, token)) - RETURN_ERROR; - if (token[0] == '.') { - (void) Parse_String(parseState, "."); /* consume . */ - - if (!Parse_Token(parseState, token)) - RETURN_ERROR; - - if (token[1] == 0) { - /* single letter swizzle */ - if (token[0] == 'x') - srcReg->Swizzle = SWIZZLE_XXXX; - else if (token[0] == 'y') - srcReg->Swizzle = SWIZZLE_YYYY; - else if (token[0] == 'z') - srcReg->Swizzle = SWIZZLE_ZZZZ; - else if (token[0] == 'w') - srcReg->Swizzle = SWIZZLE_WWWW; - else - RETURN_ERROR1("Expected x, y, z, or w"); - } - else { - /* 2, 3 or 4-component swizzle */ - GLint k; - - srcReg->Swizzle = 0; - - for (k = 0; token[k] && k < 5; k++) { - if (token[k] == 'x') - srcReg->Swizzle |= 0 << (k*3); - else if (token[k] == 'y') - srcReg->Swizzle |= 1 << (k*3); - else if (token[k] == 'z') - srcReg->Swizzle |= 2 << (k*3); - else if (token[k] == 'w') - srcReg->Swizzle |= 3 << (k*3); - else - RETURN_ERROR; - } - if (k >= 5) - RETURN_ERROR; - } - } - - return GL_TRUE; -} - - -static GLboolean -Parse_ScalarSrcReg(struct parse_state *parseState, struct prog_src_register *srcReg) -{ - GLubyte token[100]; - GLint idx; - - srcReg->RelAddr = GL_FALSE; - - /* check for '-' */ - if (!Peek_Token(parseState, token)) - RETURN_ERROR; - if (token[0] == '-') { - srcReg->Negate = NEGATE_XYZW; - (void) Parse_String(parseState, "-"); /* consume '-' */ - if (!Peek_Token(parseState, token)) - RETURN_ERROR; - } - else { - srcReg->Negate = NEGATE_NONE; - } - - /* Src reg can be R<n>, c[n], c[n +/- offset], or a named vertex attrib */ - if (token[0] == 'R') { - srcReg->File = PROGRAM_TEMPORARY; - if (!Parse_TempReg(parseState, &idx)) - RETURN_ERROR; - srcReg->Index = idx; - } - else if (token[0] == 'c') { - if (!Parse_ParamReg(parseState, srcReg)) - RETURN_ERROR; - } - else if (token[0] == 'v') { - srcReg->File = PROGRAM_INPUT; - if (!Parse_AttribReg(parseState, &idx)) - RETURN_ERROR; - srcReg->Index = idx; - } - else { - RETURN_ERROR2("Bad source register name", token); - } - - /* Look for .[xyzw] suffix */ - if (!Parse_String(parseState, ".")) - RETURN_ERROR; - - if (!Parse_Token(parseState, token)) - RETURN_ERROR; - - if (token[0] == 'x' && token[1] == 0) { - srcReg->Swizzle = 0; - } - else if (token[0] == 'y' && token[1] == 0) { - srcReg->Swizzle = 1; - } - else if (token[0] == 'z' && token[1] == 0) { - srcReg->Swizzle = 2; - } - else if (token[0] == 'w' && token[1] == 0) { - srcReg->Swizzle = 3; - } - else { - RETURN_ERROR1("Bad scalar source suffix"); - } - - return GL_TRUE; -} - - -static GLint -Parse_UnaryOpInstruction(struct parse_state *parseState, - struct prog_instruction *inst, - enum prog_opcode opcode) -{ - if (opcode == OPCODE_ABS && !parseState->isVersion1_1) - RETURN_ERROR1("ABS illegal for vertex program 1.0"); - - inst->Opcode = opcode; - - /* dest reg */ - if (!Parse_MaskedDstReg(parseState, &inst->DstReg)) - RETURN_ERROR; - - /* comma */ - if (!Parse_String(parseState, ",")) - RETURN_ERROR; - - /* src arg */ - if (!Parse_SwizzleSrcReg(parseState, &inst->SrcReg[0])) - RETURN_ERROR; - - /* semicolon */ - if (!Parse_String(parseState, ";")) - RETURN_ERROR; - - return GL_TRUE; -} - - -static GLboolean -Parse_BiOpInstruction(struct parse_state *parseState, - struct prog_instruction *inst, - enum prog_opcode opcode) -{ - if (opcode == OPCODE_DPH && !parseState->isVersion1_1) - RETURN_ERROR1("DPH illegal for vertex program 1.0"); - if (opcode == OPCODE_SUB && !parseState->isVersion1_1) - RETURN_ERROR1("SUB illegal for vertex program 1.0"); - - inst->Opcode = opcode; - - /* dest reg */ - if (!Parse_MaskedDstReg(parseState, &inst->DstReg)) - RETURN_ERROR; - - /* comma */ - if (!Parse_String(parseState, ",")) - RETURN_ERROR; - - /* first src arg */ - if (!Parse_SwizzleSrcReg(parseState, &inst->SrcReg[0])) - RETURN_ERROR; - - /* comma */ - if (!Parse_String(parseState, ",")) - RETURN_ERROR; - - /* second src arg */ - if (!Parse_SwizzleSrcReg(parseState, &inst->SrcReg[1])) - RETURN_ERROR; - - /* semicolon */ - if (!Parse_String(parseState, ";")) - RETURN_ERROR; - - /* make sure we don't reference more than one program parameter register */ - if (inst->SrcReg[0].File == PROGRAM_ENV_PARAM && - inst->SrcReg[1].File == PROGRAM_ENV_PARAM && - inst->SrcReg[0].Index != inst->SrcReg[1].Index) - RETURN_ERROR1("Can't reference two program parameter registers"); - - /* make sure we don't reference more than one vertex attribute register */ - if (inst->SrcReg[0].File == PROGRAM_INPUT && - inst->SrcReg[1].File == PROGRAM_INPUT && - inst->SrcReg[0].Index != inst->SrcReg[1].Index) - RETURN_ERROR1("Can't reference two vertex attribute registers"); - - return GL_TRUE; -} - - -static GLboolean -Parse_TriOpInstruction(struct parse_state *parseState, - struct prog_instruction *inst, - enum prog_opcode opcode) -{ - inst->Opcode = opcode; - - /* dest reg */ - if (!Parse_MaskedDstReg(parseState, &inst->DstReg)) - RETURN_ERROR; - - /* comma */ - if (!Parse_String(parseState, ",")) - RETURN_ERROR; - - /* first src arg */ - if (!Parse_SwizzleSrcReg(parseState, &inst->SrcReg[0])) - RETURN_ERROR; - - /* comma */ - if (!Parse_String(parseState, ",")) - RETURN_ERROR; - - /* second src arg */ - if (!Parse_SwizzleSrcReg(parseState, &inst->SrcReg[1])) - RETURN_ERROR; - - /* comma */ - if (!Parse_String(parseState, ",")) - RETURN_ERROR; - - /* third src arg */ - if (!Parse_SwizzleSrcReg(parseState, &inst->SrcReg[2])) - RETURN_ERROR; - - /* semicolon */ - if (!Parse_String(parseState, ";")) - RETURN_ERROR; - - /* make sure we don't reference more than one program parameter register */ - if ((inst->SrcReg[0].File == PROGRAM_ENV_PARAM && - inst->SrcReg[1].File == PROGRAM_ENV_PARAM && - inst->SrcReg[0].Index != inst->SrcReg[1].Index) || - (inst->SrcReg[0].File == PROGRAM_ENV_PARAM && - inst->SrcReg[2].File == PROGRAM_ENV_PARAM && - inst->SrcReg[0].Index != inst->SrcReg[2].Index) || - (inst->SrcReg[1].File == PROGRAM_ENV_PARAM && - inst->SrcReg[2].File == PROGRAM_ENV_PARAM && - inst->SrcReg[1].Index != inst->SrcReg[2].Index)) - RETURN_ERROR1("Can only reference one program register"); - - /* make sure we don't reference more than one vertex attribute register */ - if ((inst->SrcReg[0].File == PROGRAM_INPUT && - inst->SrcReg[1].File == PROGRAM_INPUT && - inst->SrcReg[0].Index != inst->SrcReg[1].Index) || - (inst->SrcReg[0].File == PROGRAM_INPUT && - inst->SrcReg[2].File == PROGRAM_INPUT && - inst->SrcReg[0].Index != inst->SrcReg[2].Index) || - (inst->SrcReg[1].File == PROGRAM_INPUT && - inst->SrcReg[2].File == PROGRAM_INPUT && - inst->SrcReg[1].Index != inst->SrcReg[2].Index)) - RETURN_ERROR1("Can only reference one input register"); - - return GL_TRUE; -} - - -static GLboolean -Parse_ScalarInstruction(struct parse_state *parseState, - struct prog_instruction *inst, - enum prog_opcode opcode) -{ - if (opcode == OPCODE_RCC && !parseState->isVersion1_1) - RETURN_ERROR1("RCC illegal for vertex program 1.0"); - - inst->Opcode = opcode; - - /* dest reg */ - if (!Parse_MaskedDstReg(parseState, &inst->DstReg)) - RETURN_ERROR; - - /* comma */ - if (!Parse_String(parseState, ",")) - RETURN_ERROR; - - /* first src arg */ - if (!Parse_ScalarSrcReg(parseState, &inst->SrcReg[0])) - RETURN_ERROR; - - /* semicolon */ - if (!Parse_String(parseState, ";")) - RETURN_ERROR; - - return GL_TRUE; -} - - -static GLboolean -Parse_AddressInstruction(struct parse_state *parseState, struct prog_instruction *inst) -{ - inst->Opcode = OPCODE_ARL; - - /* Make ARB_vp backends happy */ - inst->DstReg.File = PROGRAM_ADDRESS; - inst->DstReg.WriteMask = WRITEMASK_X; - inst->DstReg.Index = 0; - - /* dest A0 reg */ - if (!Parse_AddrReg(parseState)) - RETURN_ERROR; - - /* comma */ - if (!Parse_String(parseState, ",")) - RETURN_ERROR; - - /* parse src reg */ - if (!Parse_ScalarSrcReg(parseState, &inst->SrcReg[0])) - RETURN_ERROR; - - /* semicolon */ - if (!Parse_String(parseState, ";")) - RETURN_ERROR; - - return GL_TRUE; -} - - -static GLboolean -Parse_EndInstruction(struct parse_state *parseState, struct prog_instruction *inst) -{ - GLubyte token[100]; - - inst->Opcode = OPCODE_END; - - /* this should fail! */ - if (Parse_Token(parseState, token)) - RETURN_ERROR2("Unexpected token after END:", token); - else - return GL_TRUE; -} - - -/** - * The PRINT instruction is Mesa-specific and is meant as a debugging aid for - * the vertex program developer. - * The NV_vertex_program extension grammar is modified as follows: - * - * <instruction> ::= <ARL-instruction> - * | ... - * | <PRINT-instruction> - * - * <PRINT-instruction> ::= "PRINT" <string literal> - * | "PRINT" <string literal> "," <srcReg> - * | "PRINT" <string literal> "," <dstReg> - */ -static GLboolean -Parse_PrintInstruction(struct parse_state *parseState, struct prog_instruction *inst) -{ - const GLubyte *str; - GLubyte *msg; - GLuint len; - GLubyte token[100]; - struct prog_src_register *srcReg = &inst->SrcReg[0]; - GLint idx; - - inst->Opcode = OPCODE_PRINT; - - /* The first argument is a literal string 'just like this' */ - if (!Parse_String(parseState, "'")) - RETURN_ERROR; - - str = parseState->pos; - for (len = 0; str[len] != '\''; len++) /* find closing quote */ - ; - parseState->pos += len + 1; - msg = (GLubyte*) malloc(len + 1); - - memcpy(msg, str, len); - msg[len] = 0; - inst->Data = msg; - - /* comma */ - if (Parse_String(parseState, ",")) { - - /* The second argument is a register name */ - if (!Peek_Token(parseState, token)) - RETURN_ERROR; - - srcReg->RelAddr = GL_FALSE; - srcReg->Negate = NEGATE_NONE; - srcReg->Swizzle = SWIZZLE_NOOP; - - /* Register can be R<n>, c[n], c[n +/- offset], a named vertex attrib, - * or an o[n] output register. - */ - if (token[0] == 'R') { - srcReg->File = PROGRAM_TEMPORARY; - if (!Parse_TempReg(parseState, &idx)) - RETURN_ERROR; - srcReg->Index = idx; - } - else if (token[0] == 'c') { - srcReg->File = PROGRAM_ENV_PARAM; - if (!Parse_ParamReg(parseState, srcReg)) - RETURN_ERROR; - } - else if (token[0] == 'v') { - srcReg->File = PROGRAM_INPUT; - if (!Parse_AttribReg(parseState, &idx)) - RETURN_ERROR; - srcReg->Index = idx; - } - else if (token[0] == 'o') { - srcReg->File = PROGRAM_OUTPUT; - if (!Parse_OutputReg(parseState, &idx)) - RETURN_ERROR; - srcReg->Index = idx; - } - else { - RETURN_ERROR2("Bad source register name", token); - } - } - else { - srcReg->File = 0; - } - - /* semicolon */ - if (!Parse_String(parseState, ";")) - RETURN_ERROR; - - return GL_TRUE; -} - - -static GLboolean -Parse_OptionSequence(struct parse_state *parseState, - struct prog_instruction program[]) -{ - (void) program; - while (1) { - if (!Parse_String(parseState, "OPTION")) - return GL_TRUE; /* ok, not an OPTION statement */ - if (Parse_String(parseState, "NV_position_invariant")) { - parseState->isPositionInvariant = GL_TRUE; - } - else { - RETURN_ERROR1("unexpected OPTION statement"); - } - if (!Parse_String(parseState, ";")) - return GL_FALSE; - } -} - - -static GLboolean -Parse_InstructionSequence(struct parse_state *parseState, - struct prog_instruction program[]) -{ - while (1) { - struct prog_instruction *inst = program + parseState->numInst; - - /* Initialize the instruction */ - _mesa_init_instructions(inst, 1); - - if (Parse_String(parseState, "MOV")) { - if (!Parse_UnaryOpInstruction(parseState, inst, OPCODE_MOV)) - RETURN_ERROR; - } - else if (Parse_String(parseState, "LIT")) { - if (!Parse_UnaryOpInstruction(parseState, inst, OPCODE_LIT)) - RETURN_ERROR; - } - else if (Parse_String(parseState, "ABS")) { - if (!Parse_UnaryOpInstruction(parseState, inst, OPCODE_ABS)) - RETURN_ERROR; - } - else if (Parse_String(parseState, "MUL")) { - if (!Parse_BiOpInstruction(parseState, inst, OPCODE_MUL)) - RETURN_ERROR; - } - else if (Parse_String(parseState, "ADD")) { - if (!Parse_BiOpInstruction(parseState, inst, OPCODE_ADD)) - RETURN_ERROR; - } - else if (Parse_String(parseState, "DP3")) { - if (!Parse_BiOpInstruction(parseState, inst, OPCODE_DP3)) - RETURN_ERROR; - } - else if (Parse_String(parseState, "DP4")) { - if (!Parse_BiOpInstruction(parseState, inst, OPCODE_DP4)) - RETURN_ERROR; - } - else if (Parse_String(parseState, "DST")) { - if (!Parse_BiOpInstruction(parseState, inst, OPCODE_DST)) - RETURN_ERROR; - } - else if (Parse_String(parseState, "MIN")) { - if (!Parse_BiOpInstruction(parseState, inst, OPCODE_MIN)) - RETURN_ERROR; - } - else if (Parse_String(parseState, "MAX")) { - if (!Parse_BiOpInstruction(parseState, inst, OPCODE_MAX)) - RETURN_ERROR; - } - else if (Parse_String(parseState, "SLT")) { - if (!Parse_BiOpInstruction(parseState, inst, OPCODE_SLT)) - RETURN_ERROR; - } - else if (Parse_String(parseState, "SGE")) { - if (!Parse_BiOpInstruction(parseState, inst, OPCODE_SGE)) - RETURN_ERROR; - } - else if (Parse_String(parseState, "DPH")) { - if (!Parse_BiOpInstruction(parseState, inst, OPCODE_DPH)) - RETURN_ERROR; - } - else if (Parse_String(parseState, "SUB")) { - if (!Parse_BiOpInstruction(parseState, inst, OPCODE_SUB)) - RETURN_ERROR; - } - else if (Parse_String(parseState, "MAD")) { - if (!Parse_TriOpInstruction(parseState, inst, OPCODE_MAD)) - RETURN_ERROR; - } - else if (Parse_String(parseState, "RCP")) { - if (!Parse_ScalarInstruction(parseState, inst, OPCODE_RCP)) - RETURN_ERROR; - } - else if (Parse_String(parseState, "RSQ")) { - if (!Parse_ScalarInstruction(parseState, inst, OPCODE_RSQ)) - RETURN_ERROR; - } - else if (Parse_String(parseState, "EXP")) { - if (!Parse_ScalarInstruction(parseState, inst, OPCODE_EXP)) - RETURN_ERROR; - } - else if (Parse_String(parseState, "LOG")) { - if (!Parse_ScalarInstruction(parseState, inst, OPCODE_LOG)) - RETURN_ERROR; - } - else if (Parse_String(parseState, "RCC")) { - if (!Parse_ScalarInstruction(parseState, inst, OPCODE_RCC)) - RETURN_ERROR; - } - else if (Parse_String(parseState, "ARL")) { - if (!Parse_AddressInstruction(parseState, inst)) - RETURN_ERROR; - } - else if (Parse_String(parseState, "PRINT")) { - if (!Parse_PrintInstruction(parseState, inst)) - RETURN_ERROR; - } - else if (Parse_String(parseState, "END")) { - if (!Parse_EndInstruction(parseState, inst)) - RETURN_ERROR; - else { - parseState->numInst++; - return GL_TRUE; /* all done */ - } - } - else { - /* bad instruction name */ - RETURN_ERROR1("Unexpected token"); - } - - /* examine input/output registers */ - if (inst->DstReg.File == PROGRAM_OUTPUT) - parseState->outputsWritten |= (1 << inst->DstReg.Index); - else if (inst->DstReg.File == PROGRAM_ENV_PARAM) - parseState->anyProgRegsWritten = GL_TRUE; - - if (inst->SrcReg[0].File == PROGRAM_INPUT) - parseState->inputsRead |= (1 << inst->SrcReg[0].Index); - if (inst->SrcReg[1].File == PROGRAM_INPUT) - parseState->inputsRead |= (1 << inst->SrcReg[1].Index); - if (inst->SrcReg[2].File == PROGRAM_INPUT) - parseState->inputsRead |= (1 << inst->SrcReg[2].Index); - - parseState->numInst++; - - if (parseState->numInst >= MAX_NV_VERTEX_PROGRAM_INSTRUCTIONS) - RETURN_ERROR1("Program too long"); - } - - RETURN_ERROR; -} - - -static GLboolean -Parse_Program(struct parse_state *parseState, - struct prog_instruction instBuffer[]) -{ - if (parseState->isVersion1_1) { - if (!Parse_OptionSequence(parseState, instBuffer)) { - return GL_FALSE; - } - } - return Parse_InstructionSequence(parseState, instBuffer); -} - - -/** - * Parse/compile the 'str' returning the compiled 'program'. - * ctx->Program.ErrorPos will be -1 if successful. Otherwise, ErrorPos - * indicates the position of the error in 'str'. - */ -void -_mesa_parse_nv_vertex_program(GLcontext *ctx, GLenum dstTarget, - const GLubyte *str, GLsizei len, - struct gl_vertex_program *program) -{ - struct parse_state parseState; - struct prog_instruction instBuffer[MAX_NV_VERTEX_PROGRAM_INSTRUCTIONS]; - struct prog_instruction *newInst; - GLenum target; - GLubyte *programString; - - /* Make a null-terminated copy of the program string */ - programString = (GLubyte *) MALLOC(len + 1); - if (!programString) { - _mesa_error(ctx, GL_OUT_OF_MEMORY, "glLoadProgramNV"); - return; - } - memcpy(programString, str, len); - programString[len] = 0; - - /* Get ready to parse */ - parseState.ctx = ctx; - parseState.start = programString; - parseState.isPositionInvariant = GL_FALSE; - parseState.isVersion1_1 = GL_FALSE; - parseState.numInst = 0; - parseState.inputsRead = 0; - parseState.outputsWritten = 0; - parseState.anyProgRegsWritten = GL_FALSE; - - /* Reset error state */ - _mesa_set_program_error(ctx, -1, NULL); - - /* check the program header */ - if (strncmp((const char *) programString, "!!VP1.0", 7) == 0) { - target = GL_VERTEX_PROGRAM_NV; - parseState.pos = programString + 7; - parseState.isStateProgram = GL_FALSE; - } - else if (strncmp((const char *) programString, "!!VP1.1", 7) == 0) { - target = GL_VERTEX_PROGRAM_NV; - parseState.pos = programString + 7; - parseState.isStateProgram = GL_FALSE; - parseState.isVersion1_1 = GL_TRUE; - } - else if (strncmp((const char *) programString, "!!VSP1.0", 8) == 0) { - target = GL_VERTEX_STATE_PROGRAM_NV; - parseState.pos = programString + 8; - parseState.isStateProgram = GL_TRUE; - } - else { - /* invalid header */ - ctx->Program.ErrorPos = 0; - _mesa_error(ctx, GL_INVALID_OPERATION, "glLoadProgramNV(bad header)"); - return; - } - - /* make sure target and header match */ - if (target != dstTarget) { - _mesa_error(ctx, GL_INVALID_OPERATION, - "glLoadProgramNV(target mismatch)"); - return; - } - - - if (Parse_Program(&parseState, instBuffer)) { - gl_state_index state_tokens[STATE_LENGTH] = {0, 0, 0, 0, 0}; - int i; - - /* successful parse! */ - - if (parseState.isStateProgram) { - if (!parseState.anyProgRegsWritten) { - _mesa_error(ctx, GL_INVALID_OPERATION, - "glLoadProgramNV(c[#] not written)"); - return; - } - } - else { - if (!parseState.isPositionInvariant && - !(parseState.outputsWritten & (1 << VERT_RESULT_HPOS))) { - /* bit 1 = HPOS register */ - _mesa_error(ctx, GL_INVALID_OPERATION, - "glLoadProgramNV(HPOS not written)"); - return; - } - } - - /* copy the compiled instructions */ - assert(parseState.numInst <= MAX_NV_VERTEX_PROGRAM_INSTRUCTIONS); - newInst = _mesa_alloc_instructions(parseState.numInst); - if (!newInst) { - _mesa_error(ctx, GL_OUT_OF_MEMORY, "glLoadProgramNV"); - free(programString); - return; /* out of memory */ - } - _mesa_copy_instructions(newInst, instBuffer, parseState.numInst); - - /* install the program */ - program->Base.Target = target; - if (program->Base.String) { - free(program->Base.String); - } - program->Base.String = programString; - program->Base.Format = GL_PROGRAM_FORMAT_ASCII_ARB; - if (program->Base.Instructions) { - free(program->Base.Instructions); - } - program->Base.Instructions = newInst; - program->Base.InputsRead = parseState.inputsRead; - if (parseState.isPositionInvariant) - program->Base.InputsRead |= VERT_BIT_POS; - program->Base.NumInstructions = parseState.numInst; - program->Base.OutputsWritten = parseState.outputsWritten; - program->IsPositionInvariant = parseState.isPositionInvariant; - program->IsNVProgram = GL_TRUE; - -#ifdef DEBUG_foo - printf("--- glLoadProgramNV result ---\n"); - _mesa_fprint_program_opt(stdout, &program->Base, PROG_PRINT_NV, 0); - printf("------------------------------\n"); -#endif - - if (program->Base.Parameters) - _mesa_free_parameter_list(program->Base.Parameters); - - program->Base.Parameters = _mesa_new_parameter_list (); - program->Base.NumParameters = 0; - - state_tokens[0] = STATE_VERTEX_PROGRAM; - state_tokens[1] = STATE_ENV; - /* Add refs to all of the potential params, in order. If we want to not - * upload everything, _mesa_layout_parameters is the answer. - */ - for (i = 0; i < MAX_NV_VERTEX_PROGRAM_PARAMS; i++) { - GLint index; - state_tokens[2] = i; - index = _mesa_add_state_reference(program->Base.Parameters, - state_tokens); - assert(index == i); - } - program->Base.NumParameters = program->Base.Parameters->NumParameters; - - _mesa_setup_nv_temporary_count(ctx, &program->Base); - _mesa_emit_nv_temp_initialization(ctx, &program->Base); - } - else { - /* Error! */ - _mesa_error(ctx, GL_INVALID_OPERATION, "glLoadProgramNV"); - /* NOTE: _mesa_set_program_error would have been called already */ - /* GL_NV_vertex_program isn't supposed to set the error string - * so we reset it here. - */ - _mesa_set_program_error(ctx, ctx->Program.ErrorPos, NULL); - } -} - - -const char * -_mesa_nv_vertex_input_register_name(GLuint i) -{ - ASSERT(i < MAX_NV_VERTEX_PROGRAM_INPUTS); - return InputRegisters[i]; -} - - -const char * -_mesa_nv_vertex_output_register_name(GLuint i) -{ - ASSERT(i < MAX_NV_VERTEX_PROGRAM_OUTPUTS); - return OutputRegisters[i]; -} - diff --git a/mesalib/src/mesa/shader/nvvertparse.h b/mesalib/src/mesa/shader/nvvertparse.h deleted file mode 100644 index 9919e2238..000000000 --- a/mesalib/src/mesa/shader/nvvertparse.h +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Mesa 3-D graphics library - * Version: 5.1 - * - * Copyright (C) 1999-2003 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: - * Brian Paul - */ - - -#ifndef NVVERTPARSE_H -#define NVVERTPARSE_H - - -extern void -_mesa_parse_nv_vertex_program(GLcontext *ctx, GLenum target, - const GLubyte *str, GLsizei len, - struct gl_vertex_program *program); - - -extern const char * -_mesa_nv_vertex_input_register_name(GLuint i); - -extern const char * -_mesa_nv_vertex_output_register_name(GLuint i); - -#endif diff --git a/mesalib/src/mesa/shader/prog_cache.c b/mesalib/src/mesa/shader/prog_cache.c deleted file mode 100644 index e5b602fc0..000000000 --- a/mesalib/src/mesa/shader/prog_cache.c +++ /dev/null @@ -1,206 +0,0 @@ -/************************************************************************** - * - * Copyright 2003 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 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 ITS 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. - * - **************************************************************************/ - - -#include "main/glheader.h" -#include "main/mtypes.h" -#include "main/imports.h" -#include "shader/prog_cache.h" -#include "shader/program.h" - - -struct cache_item -{ - GLuint hash; - void *key; - struct gl_program *program; - struct cache_item *next; -}; - -struct gl_program_cache -{ - struct cache_item **items; - struct cache_item *last; - GLuint size, n_items; -}; - - - -/** - * Compute hash index from state key. - */ -static GLuint -hash_key(const void *key, GLuint key_size) -{ - const GLuint *ikey = (const GLuint *) key; - GLuint hash = 0, i; - - assert(key_size >= 4); - - /* Make a slightly better attempt at a hash function: - */ - for (i = 0; i < key_size / sizeof(*ikey); i++) - { - hash += ikey[i]; - hash += (hash << 10); - hash ^= (hash >> 6); - } - - return hash; -} - - -/** - * Rebuild/expand the hash table to accomodate more entries - */ -static void -rehash(struct gl_program_cache *cache) -{ - struct cache_item **items; - struct cache_item *c, *next; - GLuint size, i; - - cache->last = NULL; - - size = cache->size * 3; - items = (struct cache_item**) malloc(size * sizeof(*items)); - memset(items, 0, size * sizeof(*items)); - - for (i = 0; i < cache->size; i++) - for (c = cache->items[i]; c; c = next) { - next = c->next; - c->next = items[c->hash % size]; - items[c->hash % size] = c; - } - - free(cache->items); - cache->items = items; - cache->size = size; -} - - -static void -clear_cache(GLcontext *ctx, struct gl_program_cache *cache) -{ - struct cache_item *c, *next; - GLuint i; - - cache->last = NULL; - - for (i = 0; i < cache->size; i++) { - for (c = cache->items[i]; c; c = next) { - next = c->next; - free(c->key); - _mesa_reference_program(ctx, &c->program, NULL); - free(c); - } - cache->items[i] = NULL; - } - - - cache->n_items = 0; -} - - - -struct gl_program_cache * -_mesa_new_program_cache(void) -{ - struct gl_program_cache *cache = CALLOC_STRUCT(gl_program_cache); - if (cache) { - cache->size = 17; - cache->items = (struct cache_item **) - calloc(1, cache->size * sizeof(struct cache_item)); - if (!cache->items) { - free(cache); - return NULL; - } - } - return cache; -} - - -void -_mesa_delete_program_cache(GLcontext *ctx, struct gl_program_cache *cache) -{ - clear_cache(ctx, cache); - free(cache->items); - free(cache); -} - - -struct gl_program * -_mesa_search_program_cache(struct gl_program_cache *cache, - const void *key, GLuint keysize) -{ - if (cache->last && - memcmp(cache->last->key, key, keysize) == 0) { - return cache->last->program; - } - else { - const GLuint hash = hash_key(key, keysize); - struct cache_item *c; - - for (c = cache->items[hash % cache->size]; c; c = c->next) { - if (c->hash == hash && memcmp(c->key, key, keysize) == 0) { - cache->last = c; - return c->program; - } - } - - return NULL; - } -} - - -void -_mesa_program_cache_insert(GLcontext *ctx, - struct gl_program_cache *cache, - const void *key, GLuint keysize, - struct gl_program *program) -{ - const GLuint hash = hash_key(key, keysize); - struct cache_item *c = CALLOC_STRUCT(cache_item); - - c->hash = hash; - - c->key = malloc(keysize); - memcpy(c->key, key, keysize); - - c->program = program; /* no refcount change */ - - if (cache->n_items > cache->size * 1.5) { - if (cache->size < 1000) - rehash(cache); - else - clear_cache(ctx, cache); - } - - cache->n_items++; - c->next = cache->items[hash % cache->size]; - cache->items[hash % cache->size] = c; -} diff --git a/mesalib/src/mesa/shader/prog_cache.h b/mesalib/src/mesa/shader/prog_cache.h deleted file mode 100644 index 4e1ccac03..000000000 --- a/mesalib/src/mesa/shader/prog_cache.h +++ /dev/null @@ -1,55 +0,0 @@ -/************************************************************************** - * - * Copyright 2003 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 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 ITS 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. - * - **************************************************************************/ - - -#ifndef PROG_CACHE_H -#define PROG_CACHE_H - - -/** Opaque type */ -struct gl_program_cache; - - -extern struct gl_program_cache * -_mesa_new_program_cache(void); - -extern void -_mesa_delete_program_cache(GLcontext *ctx, struct gl_program_cache *pc); - - -extern struct gl_program * -_mesa_search_program_cache(struct gl_program_cache *cache, - const void *key, GLuint keysize); - -extern void -_mesa_program_cache_insert(GLcontext *ctx, - struct gl_program_cache *cache, - const void *key, GLuint keysize, - struct gl_program *program); - - -#endif /* PROG_CACHE_H */ diff --git a/mesalib/src/mesa/shader/prog_execute.c b/mesalib/src/mesa/shader/prog_execute.c deleted file mode 100644 index 37750cc33..000000000 --- a/mesalib/src/mesa/shader/prog_execute.c +++ /dev/null @@ -1,1798 +0,0 @@ -/* - * Mesa 3-D graphics library - * Version: 7.3 - * - * Copyright (C) 1999-2008 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 "main/glheader.h" -#include "main/colormac.h" -#include "main/context.h" -#include "prog_execute.h" -#include "prog_instruction.h" -#include "prog_parameter.h" -#include "prog_print.h" -#include "prog_noise.h" - - -/* debug predicate */ -#define DEBUG_PROG 0 - - -/** - * Set x to positive or negative infinity. - */ -#if defined(USE_IEEE) || defined(_WIN32) -#define SET_POS_INFINITY(x) \ - do { \ - fi_type fi; \ - fi.i = 0x7F800000; \ - x = fi.f; \ - } while (0) -#define SET_NEG_INFINITY(x) \ - do { \ - fi_type fi; \ - fi.i = 0xFF800000; \ - x = fi.f; \ - } while (0) -#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_src_register_pointer(const struct prog_src_register *source, - const struct gl_program_machine *machine) -{ - const struct gl_program *prog = machine->CurProgram; - GLint reg = source->Index; - - if (source->RelAddr) { - /* add address register value to src index/offset */ - reg += machine->AddressReg[0][0]; - if (reg < 0) { - return ZeroVec; - } - } - - switch (source->File) { - case PROGRAM_TEMPORARY: - if (reg >= MAX_PROGRAM_TEMPS) - return ZeroVec; - return machine->Temporaries[reg]; - - case PROGRAM_INPUT: - if (prog->Target == GL_VERTEX_PROGRAM_ARB) { - if (reg >= VERT_ATTRIB_MAX) - return ZeroVec; - return machine->VertAttribs[reg]; - } - else { - if (reg >= FRAG_ATTRIB_MAX) - return ZeroVec; - return machine->Attribs[reg][machine->CurElement]; - } - - case PROGRAM_OUTPUT: - if (reg >= MAX_PROGRAM_OUTPUTS) - return ZeroVec; - return machine->Outputs[reg]; - - case PROGRAM_LOCAL_PARAM: - if (reg >= MAX_PROGRAM_LOCAL_PARAMS) - return ZeroVec; - return machine->CurProgram->LocalParams[reg]; - - case PROGRAM_ENV_PARAM: - if (reg >= MAX_PROGRAM_ENV_PARAMS) - return ZeroVec; - return machine->EnvParams[reg]; - - case PROGRAM_STATE_VAR: - /* Fallthrough */ - case PROGRAM_CONSTANT: - /* Fallthrough */ - case PROGRAM_UNIFORM: - /* Fallthrough */ - case PROGRAM_NAMED_PARAM: - if (reg >= (GLint) prog->Parameters->NumParameters) - return ZeroVec; - return prog->Parameters->ParameterValues[reg]; - - default: - _mesa_problem(NULL, - "Invalid src register file %d in get_src_register_pointer()", - source->File); - return NULL; - } -} - - -/** - * Return a pointer to the 4-element float vector specified by the given - * destination register. - */ -static INLINE GLfloat * -get_dst_register_pointer(const struct prog_dst_register *dest, - struct gl_program_machine *machine) -{ - static GLfloat dummyReg[4]; - GLint reg = dest->Index; - - if (dest->RelAddr) { - /* add address register value to src index/offset */ - reg += machine->AddressReg[0][0]; - if (reg < 0) { - return dummyReg; - } - } - - switch (dest->File) { - case PROGRAM_TEMPORARY: - if (reg >= MAX_PROGRAM_TEMPS) - return dummyReg; - return machine->Temporaries[reg]; - - case PROGRAM_OUTPUT: - if (reg >= MAX_PROGRAM_OUTPUTS) - return dummyReg; - return machine->Outputs[reg]; - - case PROGRAM_WRITE_ONLY: - return dummyReg; - - default: - _mesa_problem(NULL, - "Invalid dest register file %d in get_dst_register_pointer()", - dest->File); - return NULL; - } -} - - - -/** - * 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_src_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->Abs) { - result[0] = FABSF(result[0]); - result[1] = FABSF(result[1]); - result[2] = FABSF(result[2]); - result[3] = FABSF(result[3]); - } - if (source->Negate) { - ASSERT(source->Negate == NEGATE_XYZW); - result[0] = -result[0]; - result[1] = -result[1]; - result[2] = -result[2]; - result[3] = -result[3]; - } - -#ifdef NAN_CHECK - assert(!IS_INF_OR_NAN(result[0])); - assert(!IS_INF_OR_NAN(result[0])); - assert(!IS_INF_OR_NAN(result[0])); - assert(!IS_INF_OR_NAN(result[0])); -#endif -} - - -/** - * Fetch a 4-element uint vector from the given source register. - * Apply swizzling but not negation/abs. - */ -static void -fetch_vector4ui(const struct prog_src_register *source, - const struct gl_program_machine *machine, GLuint result[4]) -{ - const GLuint *src = (GLuint *) get_src_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)]; - } - - /* Note: no Negate or Abs here */ -} - - - -/** - * Fetch the derivative with respect to X or Y for the given register. - * XXX this currently only works for fragment program input attribs. - */ -static void -fetch_vector4_deriv(GLcontext * ctx, - const struct prog_src_register *source, - const struct gl_program_machine *machine, - char xOrY, GLfloat result[4]) -{ - if (source->File == PROGRAM_INPUT && - source->Index < (GLint) machine->NumDeriv) { - const GLint col = machine->CurElement; - const GLfloat w = machine->Attribs[FRAG_ATTRIB_WPOS][col][3]; - const GLfloat invQ = 1.0f / w; - GLfloat deriv[4]; - - if (xOrY == 'X') { - deriv[0] = machine->DerivX[source->Index][0] * invQ; - deriv[1] = machine->DerivX[source->Index][1] * invQ; - deriv[2] = machine->DerivX[source->Index][2] * invQ; - deriv[3] = machine->DerivX[source->Index][3] * invQ; - } - else { - deriv[0] = machine->DerivY[source->Index][0] * invQ; - deriv[1] = machine->DerivY[source->Index][1] * invQ; - deriv[2] = machine->DerivY[source->Index][2] * invQ; - deriv[3] = machine->DerivY[source->Index][3] * invQ; - } - - result[0] = deriv[GET_SWZ(source->Swizzle, 0)]; - result[1] = deriv[GET_SWZ(source->Swizzle, 1)]; - result[2] = deriv[GET_SWZ(source->Swizzle, 2)]; - result[3] = deriv[GET_SWZ(source->Swizzle, 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->Negate) { - ASSERT(source->Negate == NEGATE_XYZW); - result[0] = -result[0]; - result[1] = -result[1]; - result[2] = -result[2]; - result[3] = -result[3]; - } - } - else { - ASSIGN_4V(result, 0.0, 0.0, 0.0, 0.0); - } -} - - -/** - * 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_src_register_pointer(source, machine); - ASSERT(src); - - result[0] = src[GET_SWZ(source->Swizzle, 0)]; - - if (source->Abs) { - result[0] = FABSF(result[0]); - } - if (source->Negate) { - result[0] = -result[0]; - } -} - - -static GLuint -fetch_vector1ui(const struct prog_src_register *source, - const struct gl_program_machine *machine) -{ - const GLuint *src = (GLuint *) get_src_register_pointer(source, machine); - return src[GET_SWZ(source->Swizzle, 0)]; -} - - -/** - * Fetch texel from texture. Use partial derivatives when possible. - */ -static INLINE void -fetch_texel(GLcontext *ctx, - const struct gl_program_machine *machine, - const struct prog_instruction *inst, - const GLfloat texcoord[4], GLfloat lodBias, - GLfloat color[4]) -{ - const GLuint unit = machine->Samplers[inst->TexSrcUnit]; - - /* Note: we only have the right derivatives for fragment input attribs. - */ - if (machine->NumDeriv > 0 && - inst->SrcReg[0].File == PROGRAM_INPUT && - inst->SrcReg[0].Index == FRAG_ATTRIB_TEX0 + inst->TexSrcUnit) { - /* simple texture fetch for which we should have derivatives */ - GLuint attr = inst->SrcReg[0].Index; - machine->FetchTexelDeriv(ctx, texcoord, - machine->DerivX[attr], - machine->DerivY[attr], - lodBias, unit, color); - } - else { - machine->FetchTexelLod(ctx, texcoord, lodBias, unit, color); - } -} - - -/** - * 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 *dstReg = &(inst->DstReg); - const GLboolean clamp = inst->SaturateMode == SATURATE_ZERO_ONE; - GLuint writeMask = dstReg->WriteMask; - GLfloat clampedValue[4]; - GLfloat *dst = get_dst_register_pointer(dstReg, machine); - -#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 (dstReg->CondMask != COND_TR) { - /* condition codes may turn off some writes */ - if (writeMask & WRITEMASK_X) { - if (!test_cc(machine->CondCodes[GET_SWZ(dstReg->CondSwizzle, 0)], - dstReg->CondMask)) - writeMask &= ~WRITEMASK_X; - } - if (writeMask & WRITEMASK_Y) { - if (!test_cc(machine->CondCodes[GET_SWZ(dstReg->CondSwizzle, 1)], - dstReg->CondMask)) - writeMask &= ~WRITEMASK_Y; - } - if (writeMask & WRITEMASK_Z) { - if (!test_cc(machine->CondCodes[GET_SWZ(dstReg->CondSwizzle, 2)], - dstReg->CondMask)) - writeMask &= ~WRITEMASK_Z; - } - if (writeMask & WRITEMASK_W) { - if (!test_cc(machine->CondCodes[GET_SWZ(dstReg->CondSwizzle, 3)], - dstReg->CondMask)) - writeMask &= ~WRITEMASK_W; - } - } - -#ifdef NAN_CHECK - assert(!IS_INF_OR_NAN(value[0])); - assert(!IS_INF_OR_NAN(value[0])); - assert(!IS_INF_OR_NAN(value[0])); - assert(!IS_INF_OR_NAN(value[0])); -#endif - - if (writeMask & WRITEMASK_X) - dst[0] = value[0]; - if (writeMask & WRITEMASK_Y) - dst[1] = value[1]; - if (writeMask & WRITEMASK_Z) - dst[2] = value[2]; - if (writeMask & WRITEMASK_W) - dst[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 DEBUG_PROG - printf("CondCodes=(%s,%s,%s,%s) for:\n", - _mesa_condcode_string(machine->CondCodes[0]), - _mesa_condcode_string(machine->CondCodes[1]), - _mesa_condcode_string(machine->CondCodes[2]), - _mesa_condcode_string(machine->CondCodes[3])); -#endif - } -} - - -/** - * Store 4 uints into a register. Observe the set-condition-code flags. - */ -static void -store_vector4ui(const struct prog_instruction *inst, - struct gl_program_machine *machine, const GLuint value[4]) -{ - const struct prog_dst_register *dstReg = &(inst->DstReg); - GLuint writeMask = dstReg->WriteMask; - GLuint *dst = (GLuint *) get_dst_register_pointer(dstReg, machine); - - if (dstReg->CondMask != COND_TR) { - /* condition codes may turn off some writes */ - if (writeMask & WRITEMASK_X) { - if (!test_cc(machine->CondCodes[GET_SWZ(dstReg->CondSwizzle, 0)], - dstReg->CondMask)) - writeMask &= ~WRITEMASK_X; - } - if (writeMask & WRITEMASK_Y) { - if (!test_cc(machine->CondCodes[GET_SWZ(dstReg->CondSwizzle, 1)], - dstReg->CondMask)) - writeMask &= ~WRITEMASK_Y; - } - if (writeMask & WRITEMASK_Z) { - if (!test_cc(machine->CondCodes[GET_SWZ(dstReg->CondSwizzle, 2)], - dstReg->CondMask)) - writeMask &= ~WRITEMASK_Z; - } - if (writeMask & WRITEMASK_W) { - if (!test_cc(machine->CondCodes[GET_SWZ(dstReg->CondSwizzle, 3)], - dstReg->CondMask)) - writeMask &= ~WRITEMASK_W; - } - } - - if (writeMask & WRITEMASK_X) - dst[0] = value[0]; - if (writeMask & WRITEMASK_Y) - dst[1] = value[1]; - if (writeMask & WRITEMASK_Z) - dst[2] = value[2]; - if (writeMask & WRITEMASK_W) - dst[3] = value[3]; - - if (inst->CondUpdate) { - if (writeMask & WRITEMASK_X) - machine->CondCodes[0] = generate_cc((float)value[0]); - if (writeMask & WRITEMASK_Y) - machine->CondCodes[1] = generate_cc((float)value[1]); - if (writeMask & WRITEMASK_Z) - machine->CondCodes[2] = generate_cc((float)value[2]); - if (writeMask & WRITEMASK_W) - machine->CondCodes[3] = generate_cc((float)value[3]); -#if DEBUG_PROG - printf("CondCodes=(%s,%s,%s,%s) for:\n", - _mesa_condcode_string(machine->CondCodes[0]), - _mesa_condcode_string(machine->CondCodes[1]), - _mesa_condcode_string(machine->CondCodes[2]), - _mesa_condcode_string(machine->CondCodes[3])); -#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; - GLuint pc, numExec = 0; - - machine->CurProgram = program; - - if (DEBUG_PROG) { - printf("execute program %u --------------------\n", program->Id); - } - - 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 (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_AND: /* bitwise AND */ - { - GLuint a[4], b[4], result[4]; - fetch_vector4ui(&inst->SrcReg[0], machine, a); - fetch_vector4ui(&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_vector4ui(inst, machine, result); - } - break; - case OPCODE_ARL: - { - GLfloat t[4]; - fetch_vector4(&inst->SrcReg[0], machine, t); - machine->AddressReg[0][0] = IFLOOR(t[0]); - if (DEBUG_PROG) { - printf("ARL %d\n", machine->AddressReg[0][0]); - } - } - break; - case OPCODE_BGNLOOP: - /* no-op */ - ASSERT(program->Instructions[inst->BranchTarget].Opcode - == OPCODE_ENDLOOP); - break; - case OPCODE_ENDLOOP: - /* subtract 1 here since pc is incremented by for(pc) loop */ - ASSERT(program->Instructions[inst->BranchTarget].Opcode - == OPCODE_BGNLOOP); - 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) */ - if (eval_condition(machine, inst)) { - /* take branch */ - /* Subtract 1 here since we'll do pc++ below */ - pc = inst->BranchTarget - 1; - } - break; - case OPCODE_BRK: /* break out of loop (conditional) */ - ASSERT(program->Instructions[inst->BranchTarget].Opcode - == OPCODE_ENDLOOP); - if (eval_condition(machine, inst)) { - /* break out of loop */ - /* pc++ at end of for-loop will put us after the ENDLOOP inst */ - pc = inst->BranchTarget; - } - break; - case OPCODE_CONT: /* continue loop (conditional) */ - ASSERT(program->Instructions[inst->BranchTarget].Opcode - == OPCODE_ENDLOOP); - if (eval_condition(machine, inst)) { - /* continue at ENDLOOP */ - /* 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; /* next inst */ - /* Subtract 1 here since we'll do pc++ at end of for-loop */ - pc = inst->BranchTarget - 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 */ - { - GLfloat result[4]; - fetch_vector4_deriv(ctx, &inst->SrcReg[0], machine, - 'X', result); - store_vector4(inst, machine, result); - } - break; - case OPCODE_DDY: /* Partial derivative with respect to Y */ - { - GLfloat result[4]; - fetch_vector4_deriv(ctx, &inst->SrcReg[0], machine, - 'Y', result); - store_vector4(inst, machine, result); - } - break; - case OPCODE_DP2: - { - 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] = DOT2(a, b); - store_vector4(inst, machine, result); - if (DEBUG_PROG) { - printf("DP2 %g = (%g %g) . (%g %g)\n", - result[0], a[0], a[1], b[0], b[1]); - } - } - break; - case OPCODE_DP2A: - { - GLfloat a[4], b[4], c, result[4]; - fetch_vector4(&inst->SrcReg[0], machine, a); - fetch_vector4(&inst->SrcReg[1], machine, b); - fetch_vector1(&inst->SrcReg[1], machine, &c); - result[0] = result[1] = result[2] = result[3] = DOT2(a, b) + c; - store_vector4(inst, machine, result); - if (DEBUG_PROG) { - printf("DP2A %g = (%g %g) . (%g %g) + %g\n", - result[0], a[0], a[1], b[0], b[1], c); - } - } - 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] = DOT3(a, b) + 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] = (GLfloat) _mesa_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], val; - fetch_vector1(&inst->SrcReg[0], machine, a); - val = (GLfloat) _mesa_pow(2.0, a[0]); - /* - if (IS_INF_OR_NAN(val)) - val = 1.0e10; - */ - result[0] = result[1] = result[2] = result[3] = val; - 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; - ASSERT(program->Instructions[inst->BranchTarget].Opcode - == OPCODE_ELSE || - program->Instructions[inst->BranchTarget].Opcode - == OPCODE_ENDIF); - /* 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); - } - if (DEBUG_PROG) { - printf("IF: %d\n", cond); - } - /* 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; - } - } - break; - case OPCODE_ELSE: - /* goto ENDIF */ - ASSERT(program->Instructions[inst->BranchTarget].Opcode - == OPCODE_ENDIF); - assert(inst->BranchTarget >= 0); - pc = inst->BranchTarget; - break; - case OPCODE_ENDIF: - /* nothing */ - 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 (DEBUG_PROG) { - printf("KIL if (%g %g %g %g) <= 0.0\n", - a[0], a[1], a[2], a[3]); - } - - 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], val; - fetch_vector1(&inst->SrcReg[0], machine, a); - /* The fast LOG2 macro doesn't meet the precision requirements. - */ - if (a[0] == 0.0F) { - val = -FLT_MAX; - } - else { - val = (float)(log(a[0]) * 1.442695F); - } - result[0] = result[1] = result[2] = result[3] = val; - 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.0F; - else - result[2] = (GLfloat) _mesa_pow(a[1], a[3]); - } - else { - result[2] = 0.0F; - } - 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) */ - - /* The fast LOG2 macro doesn't meet the precision - * requirements. - */ - q[2] = (float)(log(t[0]) * 1.442695F); - } - } - 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] = _mesa_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] = _mesa_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] = _mesa_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] = _mesa_noise4(a[0], a[1], a[2], a[3]); - store_vector4(inst, machine, result); - } - break; - case OPCODE_NOP: - break; - case OPCODE_NOT: /* bitwise NOT */ - { - GLuint a[4], result[4]; - fetch_vector4ui(&inst->SrcReg[0], machine, a); - result[0] = ~a[0]; - result[1] = ~a[1]; - result[2] = ~a[2]; - result[3] = ~a[3]; - store_vector4ui(inst, machine, result); - } - break; - case OPCODE_NRM3: /* 3-component normalization */ - { - GLfloat a[4], result[4]; - GLfloat tmp; - fetch_vector4(&inst->SrcReg[0], machine, a); - tmp = a[0] * a[0] + a[1] * a[1] + a[2] * a[2]; - if (tmp != 0.0F) - tmp = INV_SQRTF(tmp); - result[0] = tmp * a[0]; - result[1] = tmp * a[1]; - result[2] = tmp * a[2]; - result[3] = 0.0; /* undefined, but prevent valgrind warnings */ - store_vector4(inst, machine, result); - } - break; - case OPCODE_NRM4: /* 4-component normalization */ - { - GLfloat a[4], result[4]; - GLfloat tmp; - fetch_vector4(&inst->SrcReg[0], machine, a); - tmp = a[0] * a[0] + a[1] * a[1] + a[2] * a[2] + a[3] * a[3]; - if (tmp != 0.0F) - tmp = INV_SQRTF(tmp); - result[0] = tmp * a[0]; - result[1] = tmp * a[1]; - result[2] = tmp * a[2]; - result[3] = tmp * a[3]; - store_vector4(inst, machine, result); - } - break; - case OPCODE_OR: /* bitwise OR */ - { - GLuint a[4], b[4], result[4]; - fetch_vector4ui(&inst->SrcReg[0], machine, a); - fetch_vector4ui(&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_vector4ui(inst, machine, result); - } - break; - case OPCODE_PK2H: /* pack two 16-bit floats in one 32-bit float */ - { - GLfloat a[4]; - GLuint result[4]; - GLhalfNV hx, hy; - fetch_vector4(&inst->SrcReg[0], machine, a); - hx = _mesa_float_to_half(a[0]); - hy = _mesa_float_to_half(a[1]); - result[0] = - result[1] = - result[2] = - result[3] = hx | (hy << 16); - store_vector4ui(inst, machine, result); - } - break; - case OPCODE_PK2US: /* pack two GLushorts into one 32-bit float */ - { - GLfloat a[4]; - GLuint result[4], usx, usy; - 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); - result[0] = - result[1] = - result[2] = - result[3] = usx | (usy << 16); - store_vector4ui(inst, machine, result); - } - break; - case OPCODE_PK4B: /* pack four GLbytes into one 32-bit float */ - { - GLfloat a[4]; - GLuint result[4], ubx, uby, ubz, ubw; - 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); - result[0] = - result[1] = - result[2] = - result[3] = ubx | (uby << 8) | (ubz << 16) | (ubw << 24); - store_vector4ui(inst, machine, result); - } - break; - case OPCODE_PK4UB: /* pack four GLubytes into one 32-bit float */ - { - GLfloat a[4]; - GLuint result[4], ubx, uby, ubz, ubw; - 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]); - result[0] = - result[1] = - result[2] = - result[3] = ubx | (uby << 8) | (ubz << 16) | (ubw << 24); - store_vector4ui(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 */ - } - /* subtract one because of pc++ in the for loop */ - pc = machine->CallStack[--machine->StackDepth] - 1; - } - 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_SSG: /* set sign (-1, 0 or +1) */ - { - GLfloat a[4], result[4]; - fetch_vector4(&inst->SrcReg[0], machine, a); - result[0] = (GLfloat) ((a[0] > 0.0F) - (a[0] < 0.0F)); - result[1] = (GLfloat) ((a[1] > 0.0F) - (a[1] < 0.0F)); - result[2] = (GLfloat) ((a[2] > 0.0F) - (a[2] < 0.0F)); - result[3] = (GLfloat) ((a[3] > 0.0F) - (a[3] < 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(&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_src_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->Negate & (1 << i)) - result[i] = -result[i]; - } - store_vector4(inst, machine, result); - } - break; - case OPCODE_TEX: /* Both ARB and NV frag prog */ - /* Simple texel lookup */ - { - GLfloat texcoord[4], color[4]; - fetch_vector4(&inst->SrcReg[0], machine, texcoord); - - fetch_texel(ctx, machine, inst, texcoord, 0.0, color); - - if (DEBUG_PROG) { - printf("TEX (%g, %g, %g, %g) = texture[%d][%g, %g, %g, %g]\n", - color[0], color[1], color[2], color[3], - inst->TexSrcUnit, - texcoord[0], texcoord[1], texcoord[2], texcoord[3]); - } - store_vector4(inst, machine, color); - } - break; - case OPCODE_TXB: /* GL_ARB_fragment_program only */ - /* Texel lookup with LOD bias */ - { - GLfloat texcoord[4], color[4], lodBias; - - fetch_vector4(&inst->SrcReg[0], machine, texcoord); - - /* texcoord[3] is the bias to add to lambda */ - lodBias = texcoord[3]; - - fetch_texel(ctx, machine, inst, texcoord, lodBias, 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, - 0.0, /* lodBias */ - 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]; - - 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]; - } - - fetch_texel(ctx, machine, inst, texcoord, 0.0, color); - - store_vector4(inst, machine, color); - } - break; - case OPCODE_TXP_NV: /* GL_NV_fragment_program only */ - /* Texture lookup w/ projective divide, as above, but do not - * do the divide by w if sampling from a cube map. - */ - { - GLfloat texcoord[4], color[4]; - - 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]; - } - - fetch_texel(ctx, machine, inst, texcoord, 0.0, color); - - store_vector4(inst, machine, color); - } - break; - case OPCODE_TRUNC: /* truncate toward zero */ - { - 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_UP2H: /* unpack two 16-bit floats */ - { - const GLuint raw = fetch_vector1ui(&inst->SrcReg[0], machine); - GLfloat result[4]; - GLushort hx, hy; - hx = raw & 0xffff; - hy = raw >> 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 */ - { - const GLuint raw = fetch_vector1ui(&inst->SrcReg[0], machine); - GLfloat result[4]; - GLushort usx, usy; - usx = raw & 0xffff; - usy = raw >> 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 */ - { - const GLuint raw = fetch_vector1ui(&inst->SrcReg[0], machine); - GLfloat result[4]; - result[0] = (((raw >> 0) & 0xff) - 128) / 127.0F; - result[1] = (((raw >> 8) & 0xff) - 128) / 127.0F; - result[2] = (((raw >> 16) & 0xff) - 128) / 127.0F; - result[3] = (((raw >> 24) & 0xff) - 128) / 127.0F; - store_vector4(inst, machine, result); - } - break; - case OPCODE_UP4UB: /* unpack four GLubytes */ - { - const GLuint raw = fetch_vector1ui(&inst->SrcReg[0], machine); - GLfloat result[4]; - result[0] = ((raw >> 0) & 0xff) / 255.0F; - result[1] = ((raw >> 8) & 0xff) / 255.0F; - result[2] = ((raw >> 16) & 0xff) / 255.0F; - result[3] = ((raw >> 24) & 0xff) / 255.0F; - store_vector4(inst, machine, result); - } - break; - case OPCODE_XOR: /* bitwise XOR */ - { - GLuint a[4], b[4], result[4]; - fetch_vector4ui(&inst->SrcReg[0], machine, a); - fetch_vector4ui(&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_vector4ui(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); - printf("%s%g, %g, %g, %g\n", (const char *) inst->Data, - a[0], a[1], a[2], a[3]); - } - else { - printf("%s\n", (const char *) inst->Data); - } - } - break; - case OPCODE_END: - return GL_TRUE; - default: - _mesa_problem(ctx, "Bad opcode %d in _mesa_execute_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 */ - - return GL_TRUE; -} diff --git a/mesalib/src/mesa/shader/prog_execute.h b/mesalib/src/mesa/shader/prog_execute.h deleted file mode 100644 index adefc5439..000000000 --- a/mesalib/src/mesa/shader/prog_execute.h +++ /dev/null @@ -1,85 +0,0 @@ -/* - * Mesa 3-D graphics library - * Version: 7.0.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 - -#include "main/config.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], - GLfloat lodBias, - GLuint unit, GLfloat color[4]); - - -/** - * 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]; - GLfloat (*DerivX)[4]; - GLfloat (*DerivY)[4]; - GLuint NumDeriv; /**< Max index into DerivX/Y arrays */ - 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]; - - const GLubyte *Samplers; /** Array mapping sampler var to tex unit */ - - 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, gl_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/mesalib/src/mesa/shader/prog_instruction.c b/mesalib/src/mesa/shader/prog_instruction.c deleted file mode 100644 index 81099cb99..000000000 --- a/mesalib/src/mesa/shader/prog_instruction.c +++ /dev/null @@ -1,352 +0,0 @@ -/* - * Mesa 3-D graphics library - * Version: 7.3 - * - * Copyright (C) 1999-2008 Brian Paul All Rights Reserved. - * Copyright (C) 1999-2009 VMware, 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. - */ - - -#include "main/glheader.h" -#include "main/imports.h" -#include "main/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; - - memset(inst, 0, 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 *) - calloc(1, 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) -{ - GLuint i; - memcpy(dest, src, n * sizeof(struct prog_instruction)); - for (i = 0; i < n; i++) { - if (src[i].Comment) - dest[i].Comment = _mesa_strdup(src[i].Comment); - } - return dest; -} - - -/** - * Free an array of instructions - */ -void -_mesa_free_instructions(struct prog_instruction *inst, GLuint count) -{ - GLuint i; - for (i = 0; i < count; i++) { - if (inst[i].Data) - free(inst[i].Data); - if (inst[i].Comment) - free((char *) inst[i].Comment); - } - free(inst); -} - - -/** - * Basic info about each instruction - */ -struct instruction_info -{ - gl_inst_opcode Opcode; - const char *Name; - GLuint NumSrcRegs; - GLuint NumDstRegs; -}; - -/** - * Instruction info - * \note Opcode should equal array index! - */ -static const struct instruction_info InstInfo[MAX_OPCODE] = { - { OPCODE_NOP, "NOP", 0, 0 }, - { OPCODE_ABS, "ABS", 1, 1 }, - { OPCODE_ADD, "ADD", 2, 1 }, - { OPCODE_AND, "AND", 2, 1 }, - { OPCODE_ARA, "ARA", 1, 1 }, - { OPCODE_ARL, "ARL", 1, 1 }, - { OPCODE_ARL_NV, "ARL_NV", 1, 1 }, - { OPCODE_ARR, "ARL", 1, 1 }, - { OPCODE_BGNLOOP,"BGNLOOP", 0, 0 }, - { OPCODE_BGNSUB, "BGNSUB", 0, 0 }, - { OPCODE_BRA, "BRA", 0, 0 }, - { OPCODE_BRK, "BRK", 0, 0 }, - { OPCODE_CAL, "CAL", 0, 0 }, - { OPCODE_CMP, "CMP", 3, 1 }, - { OPCODE_CONT, "CONT", 0, 0 }, - { OPCODE_COS, "COS", 1, 1 }, - { OPCODE_DDX, "DDX", 1, 1 }, - { OPCODE_DDY, "DDY", 1, 1 }, - { OPCODE_DP2, "DP2", 2, 1 }, - { OPCODE_DP2A, "DP2A", 3, 1 }, - { OPCODE_DP3, "DP3", 2, 1 }, - { OPCODE_DP4, "DP4", 2, 1 }, - { OPCODE_DPH, "DPH", 2, 1 }, - { OPCODE_DST, "DST", 2, 1 }, - { OPCODE_ELSE, "ELSE", 0, 0 }, - { OPCODE_END, "END", 0, 0 }, - { OPCODE_ENDIF, "ENDIF", 0, 0 }, - { OPCODE_ENDLOOP,"ENDLOOP", 0, 0 }, - { OPCODE_ENDSUB, "ENDSUB", 0, 0 }, - { OPCODE_EX2, "EX2", 1, 1 }, - { OPCODE_EXP, "EXP", 1, 1 }, - { OPCODE_FLR, "FLR", 1, 1 }, - { OPCODE_FRC, "FRC", 1, 1 }, - { OPCODE_IF, "IF", 1, 0 }, - { OPCODE_KIL, "KIL", 1, 0 }, - { OPCODE_KIL_NV, "KIL_NV", 0, 0 }, - { OPCODE_LG2, "LG2", 1, 1 }, - { OPCODE_LIT, "LIT", 1, 1 }, - { OPCODE_LOG, "LOG", 1, 1 }, - { OPCODE_LRP, "LRP", 3, 1 }, - { OPCODE_MAD, "MAD", 3, 1 }, - { OPCODE_MAX, "MAX", 2, 1 }, - { OPCODE_MIN, "MIN", 2, 1 }, - { OPCODE_MOV, "MOV", 1, 1 }, - { OPCODE_MUL, "MUL", 2, 1 }, - { OPCODE_NOISE1, "NOISE1", 1, 1 }, - { OPCODE_NOISE2, "NOISE2", 1, 1 }, - { OPCODE_NOISE3, "NOISE3", 1, 1 }, - { OPCODE_NOISE4, "NOISE4", 1, 1 }, - { OPCODE_NOT, "NOT", 1, 1 }, - { OPCODE_NRM3, "NRM3", 1, 1 }, - { OPCODE_NRM4, "NRM4", 1, 1 }, - { OPCODE_OR, "OR", 2, 1 }, - { OPCODE_PK2H, "PK2H", 1, 1 }, - { OPCODE_PK2US, "PK2US", 1, 1 }, - { OPCODE_PK4B, "PK4B", 1, 1 }, - { OPCODE_PK4UB, "PK4UB", 1, 1 }, - { OPCODE_POW, "POW", 2, 1 }, - { OPCODE_POPA, "POPA", 0, 0 }, - { OPCODE_PRINT, "PRINT", 1, 0 }, - { OPCODE_PUSHA, "PUSHA", 0, 0 }, - { OPCODE_RCC, "RCC", 1, 1 }, - { OPCODE_RCP, "RCP", 1, 1 }, - { OPCODE_RET, "RET", 0, 0 }, - { OPCODE_RFL, "RFL", 1, 1 }, - { OPCODE_RSQ, "RSQ", 1, 1 }, - { OPCODE_SCS, "SCS", 1, 1 }, - { OPCODE_SEQ, "SEQ", 2, 1 }, - { OPCODE_SFL, "SFL", 0, 1 }, - { OPCODE_SGE, "SGE", 2, 1 }, - { OPCODE_SGT, "SGT", 2, 1 }, - { OPCODE_SIN, "SIN", 1, 1 }, - { OPCODE_SLE, "SLE", 2, 1 }, - { OPCODE_SLT, "SLT", 2, 1 }, - { OPCODE_SNE, "SNE", 2, 1 }, - { OPCODE_SSG, "SSG", 1, 1 }, - { OPCODE_STR, "STR", 0, 1 }, - { OPCODE_SUB, "SUB", 2, 1 }, - { OPCODE_SWZ, "SWZ", 1, 1 }, - { OPCODE_TEX, "TEX", 1, 1 }, - { OPCODE_TXB, "TXB", 1, 1 }, - { OPCODE_TXD, "TXD", 3, 1 }, - { OPCODE_TXL, "TXL", 1, 1 }, - { OPCODE_TXP, "TXP", 1, 1 }, - { OPCODE_TXP_NV, "TXP_NV", 1, 1 }, - { OPCODE_TRUNC, "TRUNC", 1, 1 }, - { OPCODE_UP2H, "UP2H", 1, 1 }, - { OPCODE_UP2US, "UP2US", 1, 1 }, - { OPCODE_UP4B, "UP4B", 1, 1 }, - { OPCODE_UP4UB, "UP4UB", 1, 1 }, - { OPCODE_X2D, "X2D", 3, 1 }, - { OPCODE_XOR, "XOR", 2, 1 }, - { OPCODE_XPD, "XPD", 2, 1 } -}; - - -/** - * Return the number of src registers for the given instruction/opcode. - */ -GLuint -_mesa_num_inst_src_regs(gl_inst_opcode opcode) -{ - ASSERT(opcode < MAX_OPCODE); - ASSERT(opcode == InstInfo[opcode].Opcode); - ASSERT(OPCODE_XPD == InstInfo[OPCODE_XPD].Opcode); - return InstInfo[opcode].NumSrcRegs; -} - - -/** - * Return the number of dst registers for the given instruction/opcode. - */ -GLuint -_mesa_num_inst_dst_regs(gl_inst_opcode opcode) -{ - ASSERT(opcode < MAX_OPCODE); - ASSERT(opcode == InstInfo[opcode].Opcode); - ASSERT(OPCODE_XPD == InstInfo[OPCODE_XPD].Opcode); - return InstInfo[opcode].NumDstRegs; -} - - -GLboolean -_mesa_is_tex_instruction(gl_inst_opcode opcode) -{ - return (opcode == OPCODE_TEX || - opcode == OPCODE_TXB || - opcode == OPCODE_TXD || - opcode == OPCODE_TXL || - opcode == OPCODE_TXP); -} - - -/** - * Check if there's a potential src/dst register data dependency when - * using SOA execution. - * Example: - * MOV T, T.yxwz; - * This would expand into: - * MOV t0, t1; - * MOV t1, t0; - * MOV t2, t3; - * MOV t3, t2; - * The second instruction will have the wrong value for t0 if executed as-is. - */ -GLboolean -_mesa_check_soa_dependencies(const struct prog_instruction *inst) -{ - GLuint i, chan; - - if (inst->DstReg.WriteMask == WRITEMASK_X || - inst->DstReg.WriteMask == WRITEMASK_Y || - inst->DstReg.WriteMask == WRITEMASK_Z || - inst->DstReg.WriteMask == WRITEMASK_W || - inst->DstReg.WriteMask == 0x0) { - /* no chance of data dependency */ - return GL_FALSE; - } - - /* loop over src regs */ - for (i = 0; i < 3; i++) { - if (inst->SrcReg[i].File == inst->DstReg.File && - inst->SrcReg[i].Index == inst->DstReg.Index) { - /* loop over dest channels */ - GLuint channelsWritten = 0x0; - for (chan = 0; chan < 4; chan++) { - if (inst->DstReg.WriteMask & (1 << chan)) { - /* check if we're reading a channel that's been written */ - GLuint swizzle = GET_SWZ(inst->SrcReg[i].Swizzle, chan); - if (swizzle <= SWIZZLE_W && - (channelsWritten & (1 << swizzle))) { - return GL_TRUE; - } - - channelsWritten |= (1 << chan); - } - } - } - } - return GL_FALSE; -} - - -/** - * Return string name for given program opcode. - */ -const char * -_mesa_opcode_string(gl_inst_opcode opcode) -{ - if (opcode < MAX_OPCODE) - return InstInfo[opcode].Name; - else { - static char s[20]; - _mesa_snprintf(s, sizeof(s), "OP%u", opcode); - return s; - } -} - diff --git a/mesalib/src/mesa/shader/prog_instruction.h b/mesalib/src/mesa/shader/prog_instruction.h deleted file mode 100644 index 28c797a4b..000000000 --- a/mesalib/src/mesa/shader/prog_instruction.h +++ /dev/null @@ -1,437 +0,0 @@ -/* - * Mesa 3-D graphics library - * Version: 7.3 - * - * Copyright (C) 1999-2008 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 - - -#include "main/mfeatures.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 than or equal to zero */ -#define COND_LE 6 /**< less than 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 -/*@}*/ - - -/** - * Per-component negation masks - */ -/*@{*/ -#define NEGATE_X 0x1 -#define NEGATE_Y 0x2 -#define NEGATE_Z 0x4 -#define NEGATE_W 0x8 -#define NEGATE_XYZ 0x7 -#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_AND, /* */ - 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_CAL, /* 2 2 */ - OPCODE_CMP, /* X */ - OPCODE_CONT, /* opt */ - OPCODE_COS, /* X 2 X X */ - OPCODE_DDX, /* X X */ - OPCODE_DDY, /* X X */ - OPCODE_DP2, /* 2 */ - OPCODE_DP2A, /* 2 */ - 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_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_NOT, /* */ - OPCODE_NRM3, /* */ - OPCODE_NRM4, /* */ - OPCODE_OR, /* */ - 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_TRUNC, /* X */ - OPCODE_UP2H, /* X */ - OPCODE_UP2US, /* X */ - OPCODE_UP4B, /* X */ - OPCODE_UP4UB, /* X */ - OPCODE_X2D, /* X */ - OPCODE_XOR, /* */ - OPCODE_XPD, /* X X X */ - MAX_OPCODE -} gl_inst_opcode; - - -/** - * Number of bits for the src/dst register Index field. - * This limits the size of temp/uniform register files. - */ -#define INST_INDEX_BITS 10 - - -/** - * Instruction source register. - */ -struct prog_src_register -{ - GLuint File:4; /**< One of the PROGRAM_* register file values. */ - GLint Index:(INST_INDEX_BITS+1); /**< Extra bit here for sign bit. - * May be negative for relative addressing. - */ - GLuint Swizzle:12; - GLuint RelAddr:1; - - /** Take the component-wise absolute value */ - GLuint Abs:1; - - /** - * Post-Abs negation. - * This will either be NEGATE_NONE or NEGATE_XYZW, except for the SWZ - * instruction which allows per-component negation. - */ - GLuint Negate:4; -}; - - -/** - * Instruction destination register. - */ -struct prog_dst_register -{ - GLuint File:4; /**< One of the PROGRAM_* register file values */ - GLuint Index:INST_INDEX_BITS; /**< Unsigned, never negative */ - GLuint WriteMask:4; - GLuint RelAddr:1; - - /** - * \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; - /*@}*/ -}; - - -/** - * Vertex/fragment program instruction. - */ -struct prog_instruction -{ - gl_inst_opcode Opcode; - 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: FLOAT32, FLOAT16, FIXED12. - * - * \since - * NV_fragment_program, NV_fragment_program_option. - */ - GLuint Precision:3; - - /** - * \name Extra fields for TEX, TXB, TXD, TXL, TXP instructions. - */ - /*@{*/ - /** Source texture unit. */ - GLuint TexSrcUnit:5; - - /** Source texture target, one of TEXTURE_{1D,2D,3D,CUBE,RECT}_INDEX */ - GLuint TexSrcTarget:3; - - /** True if tex instruction should do shadow comparison */ - GLuint TexShadow:1; - /*@}*/ - - /** - * 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 debugging purposes */ - const char *Comment; - - /** Arbitrary data. Used for OPCODE_PRINT and some drivers */ - void *Data; - - /** for driver use (try to remove someday) */ - GLint Aux; -}; - - -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 void -_mesa_free_instructions(struct prog_instruction *inst, GLuint count); - -extern GLuint -_mesa_num_inst_src_regs(gl_inst_opcode opcode); - -extern GLuint -_mesa_num_inst_dst_regs(gl_inst_opcode opcode); - -extern GLboolean -_mesa_is_tex_instruction(gl_inst_opcode opcode); - -extern GLboolean -_mesa_check_soa_dependencies(const struct prog_instruction *inst); - -extern const char * -_mesa_opcode_string(gl_inst_opcode opcode); - - -#endif /* PROG_INSTRUCTION_H */ diff --git a/mesalib/src/mesa/shader/prog_noise.c b/mesalib/src/mesa/shader/prog_noise.c deleted file mode 100644 index 1713ddb5f..000000000 --- a/mesalib/src/mesa/shader/prog_noise.c +++ /dev/null @@ -1,638 +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. - */ - -/* - * SimplexNoise1234 - * Copyright (c) 2003-2005, Stefan Gustavson - * - * Contact: stegu@itn.liu.se - */ - -/** - * \file - * \brief C implementation of Perlin Simplex Noise over 1, 2, 3 and 4 dims. - * \author Stefan Gustavson (stegu@itn.liu.se) - * - * - * This implementation is "Simplex Noise" as presented by - * Ken Perlin at a relatively obscure and not often cited course - * session "Real-Time Shading" at Siggraph 2001 (before real - * time shading actually took on), under the title "hardware noise". - * The 3D function is numerically equivalent to his Java reference - * code available in the PDF course notes, although I re-implemented - * it from scratch to get more readable code. The 1D, 2D and 4D cases - * were implemented from scratch by me from Ken Perlin's text. - * - * This file has no dependencies on any other file, not even its own - * header file. The header file is made for use by external code only. - */ - - -#include "main/imports.h" -#include "prog_noise.h" - -#define FASTFLOOR(x) ( ((x)>0) ? ((int)x) : (((int)x)-1) ) - -/* - * --------------------------------------------------------------------- - * Static data - */ - -/** - * Permutation table. This is just a random jumble of all numbers 0-255, - * repeated twice to avoid wrapping the index at 255 for each lookup. - * This needs to be exactly the same for all instances on all platforms, - * so it's easiest to just keep it as static explicit data. - * This also removes the need for any initialisation of this class. - * - * Note that making this an int[] instead of a char[] might make the - * code run faster on platforms with a high penalty for unaligned single - * byte addressing. Intel x86 is generally single-byte-friendly, but - * some other CPUs are faster with 4-aligned reads. - * However, a char[] is smaller, which avoids cache trashing, and that - * is probably the most important aspect on most architectures. - * This array is accessed a *lot* by the noise functions. - * A vector-valued noise over 3D accesses it 96 times, and a - * float-valued 4D noise 64 times. We want this to fit in the cache! - */ -unsigned char perm[512] = { 151, 160, 137, 91, 90, 15, - 131, 13, 201, 95, 96, 53, 194, 233, 7, 225, 140, 36, 103, 30, 69, 142, 8, - 99, 37, 240, 21, 10, 23, - 190, 6, 148, 247, 120, 234, 75, 0, 26, 197, 62, 94, 252, 219, 203, 117, 35, - 11, 32, 57, 177, 33, - 88, 237, 149, 56, 87, 174, 20, 125, 136, 171, 168, 68, 175, 74, 165, 71, - 134, 139, 48, 27, 166, - 77, 146, 158, 231, 83, 111, 229, 122, 60, 211, 133, 230, 220, 105, 92, 41, - 55, 46, 245, 40, 244, - 102, 143, 54, 65, 25, 63, 161, 1, 216, 80, 73, 209, 76, 132, 187, 208, 89, - 18, 169, 200, 196, - 135, 130, 116, 188, 159, 86, 164, 100, 109, 198, 173, 186, 3, 64, 52, 217, - 226, 250, 124, 123, - 5, 202, 38, 147, 118, 126, 255, 82, 85, 212, 207, 206, 59, 227, 47, 16, 58, - 17, 182, 189, 28, 42, - 223, 183, 170, 213, 119, 248, 152, 2, 44, 154, 163, 70, 221, 153, 101, 155, - 167, 43, 172, 9, - 129, 22, 39, 253, 19, 98, 108, 110, 79, 113, 224, 232, 178, 185, 112, 104, - 218, 246, 97, 228, - 251, 34, 242, 193, 238, 210, 144, 12, 191, 179, 162, 241, 81, 51, 145, 235, - 249, 14, 239, 107, - 49, 192, 214, 31, 181, 199, 106, 157, 184, 84, 204, 176, 115, 121, 50, 45, - 127, 4, 150, 254, - 138, 236, 205, 93, 222, 114, 67, 29, 24, 72, 243, 141, 128, 195, 78, 66, - 215, 61, 156, 180, - 151, 160, 137, 91, 90, 15, - 131, 13, 201, 95, 96, 53, 194, 233, 7, 225, 140, 36, 103, 30, 69, 142, 8, - 99, 37, 240, 21, 10, 23, - 190, 6, 148, 247, 120, 234, 75, 0, 26, 197, 62, 94, 252, 219, 203, 117, 35, - 11, 32, 57, 177, 33, - 88, 237, 149, 56, 87, 174, 20, 125, 136, 171, 168, 68, 175, 74, 165, 71, - 134, 139, 48, 27, 166, - 77, 146, 158, 231, 83, 111, 229, 122, 60, 211, 133, 230, 220, 105, 92, 41, - 55, 46, 245, 40, 244, - 102, 143, 54, 65, 25, 63, 161, 1, 216, 80, 73, 209, 76, 132, 187, 208, 89, - 18, 169, 200, 196, - 135, 130, 116, 188, 159, 86, 164, 100, 109, 198, 173, 186, 3, 64, 52, 217, - 226, 250, 124, 123, - 5, 202, 38, 147, 118, 126, 255, 82, 85, 212, 207, 206, 59, 227, 47, 16, 58, - 17, 182, 189, 28, 42, - 223, 183, 170, 213, 119, 248, 152, 2, 44, 154, 163, 70, 221, 153, 101, 155, - 167, 43, 172, 9, - 129, 22, 39, 253, 19, 98, 108, 110, 79, 113, 224, 232, 178, 185, 112, 104, - 218, 246, 97, 228, - 251, 34, 242, 193, 238, 210, 144, 12, 191, 179, 162, 241, 81, 51, 145, 235, - 249, 14, 239, 107, - 49, 192, 214, 31, 181, 199, 106, 157, 184, 84, 204, 176, 115, 121, 50, 45, - 127, 4, 150, 254, - 138, 236, 205, 93, 222, 114, 67, 29, 24, 72, 243, 141, 128, 195, 78, 66, - 215, 61, 156, 180 -}; - -/* - * --------------------------------------------------------------------- - */ - -/* - * Helper functions to compute gradients-dot-residualvectors (1D to 4D) - * Note that these generate gradients of more than unit length. To make - * a close match with the value range of classic Perlin noise, the final - * noise values need to be rescaled to fit nicely within [-1,1]. - * (The simplex noise functions as such also have different scaling.) - * Note also that these noise functions are the most practical and useful - * signed version of Perlin noise. To return values according to the - * RenderMan specification from the SL noise() and pnoise() functions, - * the noise values need to be scaled and offset to [0,1], like this: - * float SLnoise = (SimplexNoise1234::noise(x,y,z) + 1.0) * 0.5; - */ - -static float -grad1(int hash, float x) -{ - int h = hash & 15; - float grad = 1.0f + (h & 7); /* Gradient value 1.0, 2.0, ..., 8.0 */ - if (h & 8) - grad = -grad; /* Set a random sign for the gradient */ - return (grad * x); /* Multiply the gradient with the distance */ -} - -static float -grad2(int hash, float x, float y) -{ - int h = hash & 7; /* Convert low 3 bits of hash code */ - float u = h < 4 ? x : y; /* into 8 simple gradient directions, */ - float v = h < 4 ? y : x; /* and compute the dot product with (x,y). */ - return ((h & 1) ? -u : u) + ((h & 2) ? -2.0f * v : 2.0f * v); -} - -static float -grad3(int hash, float x, float y, float z) -{ - int h = hash & 15; /* Convert low 4 bits of hash code into 12 simple */ - float u = h < 8 ? x : y; /* gradient directions, and compute dot product. */ - float v = h < 4 ? y : h == 12 || h == 14 ? x : z; /* Fix repeats at h = 12 to 15 */ - return ((h & 1) ? -u : u) + ((h & 2) ? -v : v); -} - -static float -grad4(int hash, float x, float y, float z, float t) -{ - int h = hash & 31; /* Convert low 5 bits of hash code into 32 simple */ - float u = h < 24 ? x : y; /* gradient directions, and compute dot product. */ - float v = h < 16 ? y : z; - float w = h < 8 ? z : t; - return ((h & 1) ? -u : u) + ((h & 2) ? -v : v) + ((h & 4) ? -w : w); -} - -/** - * A lookup table to traverse the simplex around a given point in 4D. - * Details can be found where this table is used, in the 4D noise method. - * TODO: This should not be required, backport it from Bill's GLSL code! - */ -static unsigned char simplex[64][4] = { - {0, 1, 2, 3}, {0, 1, 3, 2}, {0, 0, 0, 0}, {0, 2, 3, 1}, - {0, 0, 0, 0}, {0, 0, 0, 0}, {0, 0, 0, 0}, {1, 2, 3, 0}, - {0, 2, 1, 3}, {0, 0, 0, 0}, {0, 3, 1, 2}, {0, 3, 2, 1}, - {0, 0, 0, 0}, {0, 0, 0, 0}, {0, 0, 0, 0}, {1, 3, 2, 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, 0}, {0, 0, 0, 0}, - {1, 2, 0, 3}, {0, 0, 0, 0}, {1, 3, 0, 2}, {0, 0, 0, 0}, - {0, 0, 0, 0}, {0, 0, 0, 0}, {2, 3, 0, 1}, {2, 3, 1, 0}, - {1, 0, 2, 3}, {1, 0, 3, 2}, {0, 0, 0, 0}, {0, 0, 0, 0}, - {0, 0, 0, 0}, {2, 0, 3, 1}, {0, 0, 0, 0}, {2, 1, 3, 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, 0}, {0, 0, 0, 0}, - {2, 0, 1, 3}, {0, 0, 0, 0}, {0, 0, 0, 0}, {0, 0, 0, 0}, - {3, 0, 1, 2}, {3, 0, 2, 1}, {0, 0, 0, 0}, {3, 1, 2, 0}, - {2, 1, 0, 3}, {0, 0, 0, 0}, {0, 0, 0, 0}, {0, 0, 0, 0}, - {3, 1, 0, 2}, {0, 0, 0, 0}, {3, 2, 0, 1}, {3, 2, 1, 0} -}; - - -/** 1D simplex noise */ -GLfloat -_mesa_noise1(GLfloat x) -{ - int i0 = FASTFLOOR(x); - int i1 = i0 + 1; - float x0 = x - i0; - float x1 = x0 - 1.0f; - float t1 = 1.0f - x1 * x1; - float n0, n1; - - float t0 = 1.0f - x0 * x0; -/* if(t0 < 0.0f) t0 = 0.0f; // this never happens for the 1D case */ - t0 *= t0; - n0 = t0 * t0 * grad1(perm[i0 & 0xff], x0); - -/* if(t1 < 0.0f) t1 = 0.0f; // this never happens for the 1D case */ - t1 *= t1; - n1 = t1 * t1 * grad1(perm[i1 & 0xff], x1); - /* The maximum value of this noise is 8*(3/4)^4 = 2.53125 */ - /* A factor of 0.395 would scale to fit exactly within [-1,1], but */ - /* we want to match PRMan's 1D noise, so we scale it down some more. */ - return 0.25f * (n0 + n1); -} - - -/** 2D simplex noise */ -GLfloat -_mesa_noise2(GLfloat x, GLfloat y) -{ -#define F2 0.366025403f /* F2 = 0.5*(sqrt(3.0)-1.0) */ -#define G2 0.211324865f /* G2 = (3.0-Math.sqrt(3.0))/6.0 */ - - float n0, n1, n2; /* Noise contributions from the three corners */ - - /* Skew the input space to determine which simplex cell we're in */ - float s = (x + y) * F2; /* Hairy factor for 2D */ - float xs = x + s; - float ys = y + s; - int i = FASTFLOOR(xs); - int j = FASTFLOOR(ys); - - float t = (float) (i + j) * G2; - float X0 = i - t; /* Unskew the cell origin back to (x,y) space */ - float Y0 = j - t; - float x0 = x - X0; /* The x,y distances from the cell origin */ - float y0 = y - Y0; - - float x1, y1, x2, y2; - int ii, jj; - float t0, t1, t2; - - /* For the 2D case, the simplex shape is an equilateral triangle. */ - /* Determine which simplex we are in. */ - int i1, j1; /* Offsets for second (middle) corner of simplex in (i,j) coords */ - if (x0 > y0) { - i1 = 1; - j1 = 0; - } /* lower triangle, XY order: (0,0)->(1,0)->(1,1) */ - else { - i1 = 0; - j1 = 1; - } /* upper triangle, YX order: (0,0)->(0,1)->(1,1) */ - - /* A step of (1,0) in (i,j) means a step of (1-c,-c) in (x,y), and */ - /* a step of (0,1) in (i,j) means a step of (-c,1-c) in (x,y), where */ - /* c = (3-sqrt(3))/6 */ - - x1 = x0 - i1 + G2; /* Offsets for middle corner in (x,y) unskewed coords */ - y1 = y0 - j1 + G2; - x2 = x0 - 1.0f + 2.0f * G2; /* Offsets for last corner in (x,y) unskewed coords */ - y2 = y0 - 1.0f + 2.0f * G2; - - /* Wrap the integer indices at 256, to avoid indexing perm[] out of bounds */ - ii = i % 256; - jj = j % 256; - - /* Calculate the contribution from the three corners */ - t0 = 0.5f - x0 * x0 - y0 * y0; - if (t0 < 0.0f) - n0 = 0.0f; - else { - t0 *= t0; - n0 = t0 * t0 * grad2(perm[ii + perm[jj]], x0, y0); - } - - t1 = 0.5f - x1 * x1 - y1 * y1; - if (t1 < 0.0f) - n1 = 0.0f; - else { - t1 *= t1; - n1 = t1 * t1 * grad2(perm[ii + i1 + perm[jj + j1]], x1, y1); - } - - t2 = 0.5f - x2 * x2 - y2 * y2; - if (t2 < 0.0f) - n2 = 0.0f; - else { - t2 *= t2; - n2 = t2 * t2 * grad2(perm[ii + 1 + perm[jj + 1]], x2, y2); - } - - /* Add contributions from each corner to get the final noise value. */ - /* The result is scaled to return values in the interval [-1,1]. */ - return 40.0f * (n0 + n1 + n2); /* TODO: The scale factor is preliminary! */ -} - - -/** 3D simplex noise */ -GLfloat -_mesa_noise3(GLfloat x, GLfloat y, GLfloat z) -{ -/* Simple skewing factors for the 3D case */ -#define F3 0.333333333f -#define G3 0.166666667f - - float n0, n1, n2, n3; /* Noise contributions from the four corners */ - - /* Skew the input space to determine which simplex cell we're in */ - float s = (x + y + z) * F3; /* Very nice and simple skew factor for 3D */ - float xs = x + s; - float ys = y + s; - float zs = z + s; - int i = FASTFLOOR(xs); - int j = FASTFLOOR(ys); - int k = FASTFLOOR(zs); - - float t = (float) (i + j + k) * G3; - float X0 = i - t; /* Unskew the cell origin back to (x,y,z) space */ - float Y0 = j - t; - float Z0 = k - t; - float x0 = x - X0; /* The x,y,z distances from the cell origin */ - float y0 = y - Y0; - float z0 = z - Z0; - - float x1, y1, z1, x2, y2, z2, x3, y3, z3; - int ii, jj, kk; - float t0, t1, t2, t3; - - /* For the 3D case, the simplex shape is a slightly irregular tetrahedron. */ - /* Determine which simplex we are in. */ - int i1, j1, k1; /* Offsets for second corner of simplex in (i,j,k) coords */ - int i2, j2, k2; /* Offsets for third corner of simplex in (i,j,k) coords */ - -/* This code would benefit from a backport from the GLSL version! */ - if (x0 >= y0) { - if (y0 >= z0) { - i1 = 1; - j1 = 0; - k1 = 0; - i2 = 1; - j2 = 1; - k2 = 0; - } /* X Y Z order */ - else if (x0 >= z0) { - i1 = 1; - j1 = 0; - k1 = 0; - i2 = 1; - j2 = 0; - k2 = 1; - } /* X Z Y order */ - else { - i1 = 0; - j1 = 0; - k1 = 1; - i2 = 1; - j2 = 0; - k2 = 1; - } /* Z X Y order */ - } - else { /* x0<y0 */ - if (y0 < z0) { - i1 = 0; - j1 = 0; - k1 = 1; - i2 = 0; - j2 = 1; - k2 = 1; - } /* Z Y X order */ - else if (x0 < z0) { - i1 = 0; - j1 = 1; - k1 = 0; - i2 = 0; - j2 = 1; - k2 = 1; - } /* Y Z X order */ - else { - i1 = 0; - j1 = 1; - k1 = 0; - i2 = 1; - j2 = 1; - k2 = 0; - } /* Y X Z order */ - } - - /* A step of (1,0,0) in (i,j,k) means a step of (1-c,-c,-c) in - * (x,y,z), a step of (0,1,0) in (i,j,k) means a step of - * (-c,1-c,-c) in (x,y,z), and a step of (0,0,1) in (i,j,k) means a - * step of (-c,-c,1-c) in (x,y,z), where c = 1/6. - */ - - x1 = x0 - i1 + G3; /* Offsets for second corner in (x,y,z) coords */ - y1 = y0 - j1 + G3; - z1 = z0 - k1 + G3; - x2 = x0 - i2 + 2.0f * G3; /* Offsets for third corner in (x,y,z) coords */ - y2 = y0 - j2 + 2.0f * G3; - z2 = z0 - k2 + 2.0f * G3; - x3 = x0 - 1.0f + 3.0f * G3;/* Offsets for last corner in (x,y,z) coords */ - y3 = y0 - 1.0f + 3.0f * G3; - z3 = z0 - 1.0f + 3.0f * G3; - - /* Wrap the integer indices at 256 to avoid indexing perm[] out of bounds */ - ii = i % 256; - jj = j % 256; - kk = k % 256; - - /* Calculate the contribution from the four corners */ - t0 = 0.6f - x0 * x0 - y0 * y0 - z0 * z0; - if (t0 < 0.0f) - n0 = 0.0f; - else { - t0 *= t0; - n0 = t0 * t0 * grad3(perm[ii + perm[jj + perm[kk]]], x0, y0, z0); - } - - t1 = 0.6f - x1 * x1 - y1 * y1 - z1 * z1; - if (t1 < 0.0f) - n1 = 0.0f; - else { - t1 *= t1; - n1 = - t1 * t1 * grad3(perm[ii + i1 + perm[jj + j1 + perm[kk + k1]]], x1, - y1, z1); - } - - t2 = 0.6f - x2 * x2 - y2 * y2 - z2 * z2; - if (t2 < 0.0f) - n2 = 0.0f; - else { - t2 *= t2; - n2 = - t2 * t2 * grad3(perm[ii + i2 + perm[jj + j2 + perm[kk + k2]]], x2, - y2, z2); - } - - t3 = 0.6f - x3 * x3 - y3 * y3 - z3 * z3; - if (t3 < 0.0f) - n3 = 0.0f; - else { - t3 *= t3; - n3 = - t3 * t3 * grad3(perm[ii + 1 + perm[jj + 1 + perm[kk + 1]]], x3, y3, - z3); - } - - /* Add contributions from each corner to get the final noise value. - * The result is scaled to stay just inside [-1,1] - */ - return 32.0f * (n0 + n1 + n2 + n3); /* TODO: The scale factor is preliminary! */ -} - - -/** 4D simplex noise */ -GLfloat -_mesa_noise4(GLfloat x, GLfloat y, GLfloat z, GLfloat w) -{ - /* The skewing and unskewing factors are hairy again for the 4D case */ -#define F4 0.309016994f /* F4 = (Math.sqrt(5.0)-1.0)/4.0 */ -#define G4 0.138196601f /* G4 = (5.0-Math.sqrt(5.0))/20.0 */ - - float n0, n1, n2, n3, n4; /* Noise contributions from the five corners */ - - /* Skew the (x,y,z,w) space to determine which cell of 24 simplices we're in */ - float s = (x + y + z + w) * F4; /* Factor for 4D skewing */ - float xs = x + s; - float ys = y + s; - float zs = z + s; - float ws = w + s; - int i = FASTFLOOR(xs); - int j = FASTFLOOR(ys); - int k = FASTFLOOR(zs); - int l = FASTFLOOR(ws); - - float t = (i + j + k + l) * G4; /* Factor for 4D unskewing */ - float X0 = i - t; /* Unskew the cell origin back to (x,y,z,w) space */ - float Y0 = j - t; - float Z0 = k - t; - float W0 = l - t; - - float x0 = x - X0; /* The x,y,z,w distances from the cell origin */ - float y0 = y - Y0; - float z0 = z - Z0; - float w0 = w - W0; - - /* For the 4D case, the simplex is a 4D shape I won't even try to describe. - * 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. - * 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. - */ - int c1 = (x0 > y0) ? 32 : 0; - int c2 = (x0 > z0) ? 16 : 0; - int c3 = (y0 > z0) ? 8 : 0; - int c4 = (x0 > w0) ? 4 : 0; - int c5 = (y0 > w0) ? 2 : 0; - int c6 = (z0 > w0) ? 1 : 0; - int c = c1 + c2 + c3 + c4 + c5 + c6; - - int i1, j1, k1, l1; /* The integer offsets for the second simplex corner */ - int i2, j2, k2, l2; /* The integer offsets for the third simplex corner */ - int i3, j3, k3, l3; /* The integer offsets for the fourth simplex corner */ - - float x1, y1, z1, w1, x2, y2, z2, w2, x3, y3, z3, w3, x4, y4, z4, w4; - int ii, jj, kk, ll; - float t0, t1, t2, t3, t4; - - /* - * simplex[c] is a 4-vector with the numbers 0, 1, 2 and 3 in some - * order. Many values of c will never occur, since e.g. x>y>z>w - * makes x<z, y<w and x<w impossible. Only the 24 indices which - * have non-zero entries make any sense. We use a thresholding to - * set the coordinates in turn from the largest magnitude. The - * number 3 in the "simplex" array is at the position of the - * largest coordinate. - */ - i1 = simplex[c][0] >= 3 ? 1 : 0; - j1 = simplex[c][1] >= 3 ? 1 : 0; - k1 = simplex[c][2] >= 3 ? 1 : 0; - l1 = simplex[c][3] >= 3 ? 1 : 0; - /* The number 2 in the "simplex" array is at the second largest coordinate. */ - i2 = simplex[c][0] >= 2 ? 1 : 0; - j2 = simplex[c][1] >= 2 ? 1 : 0; - k2 = simplex[c][2] >= 2 ? 1 : 0; - l2 = simplex[c][3] >= 2 ? 1 : 0; - /* The number 1 in the "simplex" array is at the second smallest coordinate. */ - i3 = simplex[c][0] >= 1 ? 1 : 0; - j3 = simplex[c][1] >= 1 ? 1 : 0; - k3 = simplex[c][2] >= 1 ? 1 : 0; - l3 = simplex[c][3] >= 1 ? 1 : 0; - /* The fifth corner has all coordinate offsets = 1, so no need to look that up. */ - - x1 = x0 - i1 + G4; /* Offsets for second corner in (x,y,z,w) coords */ - y1 = y0 - j1 + G4; - z1 = z0 - k1 + G4; - w1 = w0 - l1 + G4; - x2 = x0 - i2 + 2.0f * G4; /* Offsets for third corner in (x,y,z,w) coords */ - y2 = y0 - j2 + 2.0f * G4; - z2 = z0 - k2 + 2.0f * G4; - w2 = w0 - l2 + 2.0f * G4; - x3 = x0 - i3 + 3.0f * G4; /* Offsets for fourth corner in (x,y,z,w) coords */ - y3 = y0 - j3 + 3.0f * G4; - z3 = z0 - k3 + 3.0f * G4; - w3 = w0 - l3 + 3.0f * G4; - x4 = x0 - 1.0f + 4.0f * G4; /* Offsets for last corner in (x,y,z,w) coords */ - y4 = y0 - 1.0f + 4.0f * G4; - z4 = z0 - 1.0f + 4.0f * G4; - w4 = w0 - 1.0f + 4.0f * G4; - - /* Wrap the integer indices at 256, to avoid indexing perm[] out of bounds */ - ii = i % 256; - jj = j % 256; - kk = k % 256; - ll = l % 256; - - /* Calculate the contribution from the five corners */ - t0 = 0.6f - x0 * x0 - y0 * y0 - z0 * z0 - w0 * w0; - if (t0 < 0.0f) - n0 = 0.0f; - else { - t0 *= t0; - n0 = - t0 * t0 * grad4(perm[ii + perm[jj + perm[kk + perm[ll]]]], x0, y0, - z0, w0); - } - - t1 = 0.6f - x1 * x1 - y1 * y1 - z1 * z1 - w1 * w1; - if (t1 < 0.0f) - n1 = 0.0f; - else { - t1 *= t1; - n1 = - t1 * t1 * - grad4(perm[ii + i1 + perm[jj + j1 + perm[kk + k1 + perm[ll + l1]]]], - x1, y1, z1, w1); - } - - t2 = 0.6f - x2 * x2 - y2 * y2 - z2 * z2 - w2 * w2; - if (t2 < 0.0f) - n2 = 0.0f; - else { - t2 *= t2; - n2 = - t2 * t2 * - grad4(perm[ii + i2 + perm[jj + j2 + perm[kk + k2 + perm[ll + l2]]]], - x2, y2, z2, w2); - } - - t3 = 0.6f - x3 * x3 - y3 * y3 - z3 * z3 - w3 * w3; - if (t3 < 0.0f) - n3 = 0.0f; - else { - t3 *= t3; - n3 = - t3 * t3 * - grad4(perm[ii + i3 + perm[jj + j3 + perm[kk + k3 + perm[ll + l3]]]], - x3, y3, z3, w3); - } - - t4 = 0.6f - x4 * x4 - y4 * y4 - z4 * z4 - w4 * w4; - if (t4 < 0.0f) - n4 = 0.0f; - else { - t4 *= t4; - n4 = - t4 * t4 * - grad4(perm[ii + 1 + perm[jj + 1 + perm[kk + 1 + perm[ll + 1]]]], x4, - y4, z4, w4); - } - - /* Sum up and scale the result to cover the range [-1,1] */ - return 27.0f * (n0 + n1 + n2 + n3 + n4); /* TODO: The scale factor is preliminary! */ -} diff --git a/mesalib/src/mesa/shader/prog_noise.h b/mesalib/src/mesa/shader/prog_noise.h deleted file mode 100644 index c4779479f..000000000 --- a/mesalib/src/mesa/shader/prog_noise.h +++ /dev/null @@ -1,34 +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. - */ - -#ifndef PROG_NOISE -#define PROG_NOISE - -extern GLfloat _mesa_noise1(GLfloat); -extern GLfloat _mesa_noise2(GLfloat, GLfloat); -extern GLfloat _mesa_noise3(GLfloat, GLfloat, GLfloat); -extern GLfloat _mesa_noise4(GLfloat, GLfloat, GLfloat, GLfloat); - -#endif - diff --git a/mesalib/src/mesa/shader/prog_optimize.c b/mesalib/src/mesa/shader/prog_optimize.c deleted file mode 100644 index 2941a17da..000000000 --- a/mesalib/src/mesa/shader/prog_optimize.c +++ /dev/null @@ -1,1035 +0,0 @@ -/* - * Mesa 3-D graphics library - * Version: 7.5 - * - * Copyright (C) 2009 VMware, 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 - * VMWARE 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 "main/glheader.h" -#include "main/context.h" -#include "main/macros.h" -#include "program.h" -#include "prog_instruction.h" -#include "prog_optimize.h" -#include "prog_print.h" - - -#define MAX_LOOP_NESTING 50 - - -static GLboolean dbg = GL_FALSE; - -/* Returns the mask of channels read from the given srcreg in this instruction. - */ -static GLuint -get_src_arg_mask(const struct prog_instruction *inst, int arg) -{ - int writemask = inst->DstReg.WriteMask; - - if (inst->CondUpdate) - writemask = WRITEMASK_XYZW; - - switch (inst->Opcode) { - case OPCODE_MOV: - case OPCODE_ABS: - case OPCODE_ADD: - case OPCODE_MUL: - case OPCODE_SUB: - return writemask; - case OPCODE_RCP: - case OPCODE_SIN: - case OPCODE_COS: - case OPCODE_RSQ: - case OPCODE_POW: - case OPCODE_EX2: - return WRITEMASK_X; - case OPCODE_DP2: - return WRITEMASK_XY; - case OPCODE_DP3: - case OPCODE_XPD: - return WRITEMASK_XYZ; - default: - return WRITEMASK_XYZW; - } -} - -/** - * In 'prog' remove instruction[i] if removeFlags[i] == TRUE. - * \return number of instructions removed - */ -static GLuint -remove_instructions(struct gl_program *prog, const GLboolean *removeFlags) -{ - GLint i, removeEnd = 0, removeCount = 0; - GLuint totalRemoved = 0; - - /* go backward */ - for (i = prog->NumInstructions - 1; i >= 0; i--) { - if (removeFlags[i]) { - totalRemoved++; - if (removeCount == 0) { - /* begin a run of instructions to remove */ - removeEnd = i; - removeCount = 1; - } - else { - /* extend the run of instructions to remove */ - removeCount++; - } - } - else { - /* don't remove this instruction, but check if the preceeding - * instructions are to be removed. - */ - if (removeCount > 0) { - GLint removeStart = removeEnd - removeCount + 1; - _mesa_delete_instructions(prog, removeStart, removeCount); - removeStart = removeCount = 0; /* reset removal info */ - } - } - } - /* Finish removing if the first instruction was to be removed. */ - if (removeCount > 0) { - GLint removeStart = removeEnd - removeCount + 1; - _mesa_delete_instructions(prog, removeStart, removeCount); - } - return totalRemoved; -} - - -/** - * Remap register indexes according to map. - * \param prog the program to search/replace - * \param file the type of register file to search/replace - * \param map maps old register indexes to new indexes - */ -static void -replace_regs(struct gl_program *prog, gl_register_file file, const GLint map[]) -{ - GLuint i; - - for (i = 0; i < prog->NumInstructions; i++) { - struct prog_instruction *inst = prog->Instructions + i; - const GLuint numSrc = _mesa_num_inst_src_regs(inst->Opcode); - GLuint j; - for (j = 0; j < numSrc; j++) { - if (inst->SrcReg[j].File == file) { - GLuint index = inst->SrcReg[j].Index; - ASSERT(map[index] >= 0); - inst->SrcReg[j].Index = map[index]; - } - } - if (inst->DstReg.File == file) { - const GLuint index = inst->DstReg.Index; - ASSERT(map[index] >= 0); - inst->DstReg.Index = map[index]; - } - } -} - - -/** - * Consolidate temporary registers to use low numbers. For example, if the - * shader only uses temps 4, 5, 8, replace them with 0, 1, 2. - */ -static void -_mesa_consolidate_registers(struct gl_program *prog) -{ - GLboolean tempUsed[MAX_PROGRAM_TEMPS]; - GLint tempMap[MAX_PROGRAM_TEMPS]; - GLuint tempMax = 0, i; - - if (dbg) { - printf("Optimize: Begin register consolidation\n"); - } - - memset(tempUsed, 0, sizeof(tempUsed)); - - for (i = 0; i < MAX_PROGRAM_TEMPS; i++) { - tempMap[i] = -1; - } - - /* set tempUsed[i] if temporary [i] is referenced */ - 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); - GLuint j; - for (j = 0; j < numSrc; j++) { - if (inst->SrcReg[j].File == PROGRAM_TEMPORARY) { - const GLuint index = inst->SrcReg[j].Index; - ASSERT(index < MAX_PROGRAM_TEMPS); - tempUsed[index] = GL_TRUE; - tempMax = MAX2(tempMax, index); - break; - } - } - if (inst->DstReg.File == PROGRAM_TEMPORARY) { - const GLuint index = inst->DstReg.Index; - ASSERT(index < MAX_PROGRAM_TEMPS); - tempUsed[index] = GL_TRUE; - tempMax = MAX2(tempMax, index); - } - } - - /* allocate a new index for each temp that's used */ - { - GLuint freeTemp = 0; - for (i = 0; i <= tempMax; i++) { - if (tempUsed[i]) { - tempMap[i] = freeTemp++; - /*printf("replace %u with %u\n", i, tempMap[i]);*/ - } - } - if (freeTemp == tempMax + 1) { - /* no consolidation possible */ - return; - } - if (dbg) { - printf("Replace regs 0..%u with 0..%u\n", tempMax, freeTemp-1); - } - } - - replace_regs(prog, PROGRAM_TEMPORARY, tempMap); - - if (dbg) { - printf("Optimize: End register consolidation\n"); - } -} - - -/** - * Remove dead instructions from the given program. - * This is very primitive for now. Basically look for temp registers - * that are written to but never read. Remove any instructions that - * write to such registers. Be careful with condition code setters. - */ -static void -_mesa_remove_dead_code(struct gl_program *prog) -{ - GLboolean tempRead[MAX_PROGRAM_TEMPS][4]; - GLboolean *removeInst; /* per-instruction removal flag */ - GLuint i, rem = 0, comp; - - memset(tempRead, 0, sizeof(tempRead)); - - if (dbg) { - printf("Optimize: Begin dead code removal\n"); - /*_mesa_print_program(prog);*/ - } - - removeInst = (GLboolean *) - calloc(1, prog->NumInstructions * sizeof(GLboolean)); - - /* Determine which temps are read and written */ - 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); - GLuint j; - - /* check src regs */ - for (j = 0; j < numSrc; j++) { - if (inst->SrcReg[j].File == PROGRAM_TEMPORARY) { - const GLuint index = inst->SrcReg[j].Index; - GLuint read_mask; - ASSERT(index < MAX_PROGRAM_TEMPS); - read_mask = get_src_arg_mask(inst, j); - - if (inst->SrcReg[j].RelAddr) { - if (dbg) - printf("abort remove dead code (indirect temp)\n"); - goto done; - } - - for (comp = 0; comp < 4; comp++) { - GLuint swz = (inst->SrcReg[j].Swizzle >> (3 * comp)) & 0x7; - - if ((read_mask & (1 << comp)) == 0) - continue; - - switch (swz) { - case SWIZZLE_X: - tempRead[index][0] = GL_TRUE; - break; - case SWIZZLE_Y: - tempRead[index][1] = GL_TRUE; - break; - case SWIZZLE_Z: - tempRead[index][2] = GL_TRUE; - break; - case SWIZZLE_W: - tempRead[index][3] = GL_TRUE; - break; - } - } - } - } - - /* check dst reg */ - if (inst->DstReg.File == PROGRAM_TEMPORARY) { - const GLuint index = inst->DstReg.Index; - ASSERT(index < MAX_PROGRAM_TEMPS); - - if (inst->DstReg.RelAddr) { - if (dbg) - printf("abort remove dead code (indirect temp)\n"); - goto done; - } - - if (inst->CondUpdate) { - /* If we're writing to this register and setting condition - * codes we cannot remove the instruction. Prevent removal - * by setting the 'read' flag. - */ - tempRead[index][0] = GL_TRUE; - tempRead[index][1] = GL_TRUE; - tempRead[index][2] = GL_TRUE; - tempRead[index][3] = GL_TRUE; - } - } - } - - /* find instructions that write to dead registers, flag for removal */ - for (i = 0; i < prog->NumInstructions; i++) { - struct prog_instruction *inst = prog->Instructions + i; - const GLuint numDst = _mesa_num_inst_dst_regs(inst->Opcode); - - if (numDst != 0 && inst->DstReg.File == PROGRAM_TEMPORARY) { - GLint chan, index = inst->DstReg.Index; - - for (chan = 0; chan < 4; chan++) { - if (!tempRead[index][chan] && - inst->DstReg.WriteMask & (1 << chan)) { - if (dbg) { - printf("Remove writemask on %u.%c\n", i, - chan == 3 ? 'w' : 'x' + chan); - } - inst->DstReg.WriteMask &= ~(1 << chan); - rem++; - } - } - - if (inst->DstReg.WriteMask == 0) { - /* If we cleared all writes, the instruction can be removed. */ - if (dbg) - printf("Remove instruction %u: \n", i); - removeInst[i] = GL_TRUE; - } - } - } - - /* now remove the instructions which aren't needed */ - rem = remove_instructions(prog, removeInst); - - if (dbg) { - printf("Optimize: End dead code removal.\n"); - printf(" %u channel writes removed\n", rem); - printf(" %u instructions removed\n", rem); - /*_mesa_print_program(prog);*/ - } - -done: - free(removeInst); -} - - -enum temp_use -{ - READ, - WRITE, - FLOW, - END -}; - -/** - * Scan forward in program from 'start' for the next occurance of TEMP[index]. - * Return READ, WRITE, FLOW or END to indicate the next usage or an indicator - * that we can't look further. - */ -static enum temp_use -find_next_temp_use(const struct gl_program *prog, GLuint start, GLuint index) -{ - GLuint i; - - for (i = start; i < prog->NumInstructions; i++) { - const struct prog_instruction *inst = prog->Instructions + i; - switch (inst->Opcode) { - case OPCODE_BGNLOOP: - case OPCODE_ENDLOOP: - case OPCODE_BGNSUB: - case OPCODE_ENDSUB: - return FLOW; - default: - { - const GLuint numSrc = _mesa_num_inst_src_regs(inst->Opcode); - GLuint j; - for (j = 0; j < numSrc; j++) { - if (inst->SrcReg[j].File == PROGRAM_TEMPORARY && - inst->SrcReg[j].Index == index) - return READ; - } - if (inst->DstReg.File == PROGRAM_TEMPORARY && - inst->DstReg.Index == index) - return WRITE; - } - } - } - - return END; -} - -static GLboolean _mesa_is_flow_control_opcode(enum prog_opcode opcode) -{ - switch (opcode) { - case OPCODE_BGNLOOP: - case OPCODE_BGNSUB: - case OPCODE_BRA: - case OPCODE_CAL: - case OPCODE_CONT: - case OPCODE_IF: - case OPCODE_ELSE: - case OPCODE_END: - case OPCODE_ENDIF: - case OPCODE_ENDLOOP: - case OPCODE_ENDSUB: - case OPCODE_RET: - return GL_TRUE; - default: - return GL_FALSE; - } -} - -/** - * Try to remove use of extraneous MOV instructions, to free them up for dead - * code removal. - */ -static void -_mesa_remove_extra_move_use(struct gl_program *prog) -{ - GLuint i, j; - - if (dbg) { - printf("Optimize: Begin remove extra move use\n"); - _mesa_print_program(prog); - } - - /* - * Look for sequences such as this: - * MOV tmpX, arg0; - * ... - * FOO tmpY, tmpX, arg1; - * and convert into: - * MOV tmpX, arg0; - * ... - * FOO tmpY, arg0, arg1; - */ - - for (i = 0; i + 1 < prog->NumInstructions; i++) { - const struct prog_instruction *mov = prog->Instructions + i; - - if (mov->Opcode != OPCODE_MOV || - mov->DstReg.File != PROGRAM_TEMPORARY || - mov->DstReg.RelAddr || - mov->DstReg.CondMask != COND_TR || - mov->SaturateMode != SATURATE_OFF || - mov->SrcReg[0].RelAddr) - continue; - - /* Walk through remaining instructions until the or src reg gets - * rewritten or we get into some flow-control, eliminating the use of - * this MOV. - */ - for (j = i + 1; j < prog->NumInstructions; j++) { - struct prog_instruction *inst2 = prog->Instructions + j; - GLuint arg; - - if (_mesa_is_flow_control_opcode(inst2->Opcode)) - break; - - /* First rewrite this instruction's args if appropriate. */ - for (arg = 0; arg < _mesa_num_inst_src_regs(inst2->Opcode); arg++) { - int comp; - int read_mask = get_src_arg_mask(inst2, arg); - - if (inst2->SrcReg[arg].File != mov->DstReg.File || - inst2->SrcReg[arg].Index != mov->DstReg.Index || - inst2->SrcReg[arg].RelAddr || - inst2->SrcReg[arg].Abs) - continue; - - /* Check that all the sources for this arg of inst2 come from inst1 - * or constants. - */ - for (comp = 0; comp < 4; comp++) { - int src_swz = GET_SWZ(inst2->SrcReg[arg].Swizzle, comp); - - /* If the MOV didn't write that channel, can't use it. */ - if ((read_mask & (1 << comp)) && - src_swz <= SWIZZLE_W && - (mov->DstReg.WriteMask & (1 << src_swz)) == 0) - break; - } - if (comp != 4) - continue; - - /* Adjust the swizzles of inst2 to point at MOV's source */ - for (comp = 0; comp < 4; comp++) { - int inst2_swz = GET_SWZ(inst2->SrcReg[arg].Swizzle, comp); - - if (inst2_swz <= SWIZZLE_W) { - GLuint s = GET_SWZ(mov->SrcReg[0].Swizzle, inst2_swz); - inst2->SrcReg[arg].Swizzle &= ~(7 << (3 * comp)); - inst2->SrcReg[arg].Swizzle |= s << (3 * comp); - inst2->SrcReg[arg].Negate ^= (((mov->SrcReg[0].Negate >> - inst2_swz) & 0x1) << comp); - } - } - inst2->SrcReg[arg].File = mov->SrcReg[0].File; - inst2->SrcReg[arg].Index = mov->SrcReg[0].Index; - } - - /* If this instruction overwrote part of the move, our time is up. */ - if ((inst2->DstReg.File == mov->DstReg.File && - (inst2->DstReg.RelAddr || - inst2->DstReg.Index == mov->DstReg.Index)) || - (inst2->DstReg.File == mov->SrcReg[0].File && - (inst2->DstReg.RelAddr || - inst2->DstReg.Index == mov->SrcReg[0].Index))) - break; - } - } - - if (dbg) { - printf("Optimize: End remove extra move use.\n"); - /*_mesa_print_program(prog);*/ - } -} - -/** - * Try to remove extraneous MOV instructions from the given program. - */ -static void -_mesa_remove_extra_moves(struct gl_program *prog) -{ - GLboolean *removeInst; /* per-instruction removal flag */ - GLuint i, rem, loopNesting = 0, subroutineNesting = 0; - - if (dbg) { - printf("Optimize: Begin remove extra moves\n"); - _mesa_print_program(prog); - } - - removeInst = (GLboolean *) - calloc(1, prog->NumInstructions * sizeof(GLboolean)); - - /* - * Look for sequences such as this: - * FOO tmpX, arg0, arg1; - * MOV tmpY, tmpX; - * and convert into: - * FOO tmpY, arg0, arg1; - */ - - for (i = 0; i < prog->NumInstructions; i++) { - const struct prog_instruction *inst = prog->Instructions + i; - - switch (inst->Opcode) { - case OPCODE_BGNLOOP: - loopNesting++; - break; - case OPCODE_ENDLOOP: - loopNesting--; - break; - case OPCODE_BGNSUB: - subroutineNesting++; - break; - case OPCODE_ENDSUB: - subroutineNesting--; - break; - case OPCODE_MOV: - if (i > 0 && - loopNesting == 0 && - subroutineNesting == 0 && - inst->SrcReg[0].File == PROGRAM_TEMPORARY && - inst->SrcReg[0].Swizzle == SWIZZLE_XYZW) { - /* see if this MOV can be removed */ - const GLuint tempIndex = inst->SrcReg[0].Index; - struct prog_instruction *prevInst; - GLuint prevI; - - /* get pointer to previous instruction */ - prevI = i - 1; - while (prevI > 0 && removeInst[prevI]) - prevI--; - prevInst = prog->Instructions + prevI; - - if (prevInst->DstReg.File == PROGRAM_TEMPORARY && - prevInst->DstReg.Index == tempIndex && - prevInst->DstReg.WriteMask == WRITEMASK_XYZW) { - - enum temp_use next_use = - find_next_temp_use(prog, i + 1, tempIndex); - - if (next_use == WRITE || next_use == END) { - /* OK, we can safely remove this MOV instruction. - * Transform: - * prevI: FOO tempIndex, x, y; - * i: MOV z, tempIndex; - * Into: - * prevI: FOO z, x, y; - */ - - /* patch up prev inst */ - prevInst->DstReg.File = inst->DstReg.File; - prevInst->DstReg.Index = inst->DstReg.Index; - - /* flag this instruction for removal */ - removeInst[i] = GL_TRUE; - - if (dbg) { - printf("Remove MOV at %u\n", i); - printf("new prev inst %u: ", prevI); - _mesa_print_instruction(prevInst); - } - } - } - } - break; - default: - ; /* nothing */ - } - } - - /* now remove the instructions which aren't needed */ - rem = remove_instructions(prog, removeInst); - - free(removeInst); - - if (dbg) { - printf("Optimize: End remove extra moves. %u instructions removed\n", rem); - /*_mesa_print_program(prog);*/ - } -} - - -/** A live register interval */ -struct interval -{ - GLuint Reg; /** The temporary register index */ - GLuint Start, End; /** Start/end instruction numbers */ -}; - - -/** A list of register intervals */ -struct interval_list -{ - GLuint Num; - struct interval Intervals[MAX_PROGRAM_TEMPS]; -}; - - -static void -append_interval(struct interval_list *list, const struct interval *inv) -{ - list->Intervals[list->Num++] = *inv; -} - - -/** Insert interval inv into list, sorted by interval end */ -static void -insert_interval_by_end(struct interval_list *list, const struct interval *inv) -{ - /* XXX we could do a binary search insertion here since list is sorted */ - GLint i = list->Num - 1; - while (i >= 0 && list->Intervals[i].End > inv->End) { - list->Intervals[i + 1] = list->Intervals[i]; - i--; - } - list->Intervals[i + 1] = *inv; - list->Num++; - -#ifdef DEBUG - { - GLuint i; - for (i = 0; i + 1 < list->Num; i++) { - ASSERT(list->Intervals[i].End <= list->Intervals[i + 1].End); - } - } -#endif -} - - -/** Remove the given interval from the interval list */ -static void -remove_interval(struct interval_list *list, const struct interval *inv) -{ - /* XXX we could binary search since list is sorted */ - GLuint k; - for (k = 0; k < list->Num; k++) { - if (list->Intervals[k].Reg == inv->Reg) { - /* found, remove it */ - ASSERT(list->Intervals[k].Start == inv->Start); - ASSERT(list->Intervals[k].End == inv->End); - while (k < list->Num - 1) { - list->Intervals[k] = list->Intervals[k + 1]; - k++; - } - list->Num--; - return; - } - } -} - - -/** called by qsort() */ -static int -compare_start(const void *a, const void *b) -{ - const struct interval *ia = (const struct interval *) a; - const struct interval *ib = (const struct interval *) b; - if (ia->Start < ib->Start) - return -1; - else if (ia->Start > ib->Start) - return +1; - else - return 0; -} - -/** sort the interval list according to interval starts */ -static void -sort_interval_list_by_start(struct interval_list *list) -{ - qsort(list->Intervals, list->Num, sizeof(struct interval), compare_start); -#ifdef DEBUG - { - GLuint i; - for (i = 0; i + 1 < list->Num; i++) { - ASSERT(list->Intervals[i].Start <= list->Intervals[i + 1].Start); - } - } -#endif -} - - -/** - * Update the intermediate interval info for register 'index' and - * instruction 'ic'. - */ -static void -update_interval(GLint intBegin[], GLint intEnd[], GLuint index, GLuint ic) -{ - ASSERT(index < MAX_PROGRAM_TEMPS); - if (intBegin[index] == -1) { - ASSERT(intEnd[index] == -1); - intBegin[index] = intEnd[index] = ic; - } - else { - intEnd[index] = ic; - } -} - - -/** - * Find first/last instruction that references each temporary register. - */ -GLboolean -_mesa_find_temp_intervals(const struct prog_instruction *instructions, - GLuint numInstructions, - GLint intBegin[MAX_PROGRAM_TEMPS], - GLint intEnd[MAX_PROGRAM_TEMPS]) -{ - struct loop_info - { - GLuint Start, End; /**< Start, end instructions of loop */ - }; - struct loop_info loopStack[MAX_LOOP_NESTING]; - GLuint loopStackDepth = 0; - GLuint i; - - for (i = 0; i < MAX_PROGRAM_TEMPS; i++){ - intBegin[i] = intEnd[i] = -1; - } - - /* Scan instructions looking for temporary registers */ - for (i = 0; i < numInstructions; i++) { - const struct prog_instruction *inst = instructions + i; - if (inst->Opcode == OPCODE_BGNLOOP) { - loopStack[loopStackDepth].Start = i; - loopStack[loopStackDepth].End = inst->BranchTarget; - loopStackDepth++; - } - else if (inst->Opcode == OPCODE_ENDLOOP) { - loopStackDepth--; - } - else if (inst->Opcode == OPCODE_CAL) { - return GL_FALSE; - } - else { - const GLuint numSrc = 3;/*_mesa_num_inst_src_regs(inst->Opcode);*/ - GLuint j; - for (j = 0; j < numSrc; j++) { - if (inst->SrcReg[j].File == PROGRAM_TEMPORARY) { - const GLuint index = inst->SrcReg[j].Index; - if (inst->SrcReg[j].RelAddr) - return GL_FALSE; - update_interval(intBegin, intEnd, index, i); - if (loopStackDepth > 0) { - /* extend temp register's interval to end of loop */ - GLuint loopEnd = loopStack[loopStackDepth - 1].End; - update_interval(intBegin, intEnd, index, loopEnd); - } - } - } - if (inst->DstReg.File == PROGRAM_TEMPORARY) { - const GLuint index = inst->DstReg.Index; - if (inst->DstReg.RelAddr) - return GL_FALSE; - update_interval(intBegin, intEnd, index, i); - if (loopStackDepth > 0) { - /* extend temp register's interval to end of loop */ - GLuint loopEnd = loopStack[loopStackDepth - 1].End; - update_interval(intBegin, intEnd, index, loopEnd); - } - } - } - } - - return GL_TRUE; -} - - -/** - * Find the live intervals for each temporary register in the program. - * For register R, the interval [A,B] indicates that R is referenced - * from instruction A through instruction B. - * Special consideration is needed for loops and subroutines. - * \return GL_TRUE if success, GL_FALSE if we cannot proceed for some reason - */ -static GLboolean -find_live_intervals(struct gl_program *prog, - struct interval_list *liveIntervals) -{ - GLint intBegin[MAX_PROGRAM_TEMPS], intEnd[MAX_PROGRAM_TEMPS]; - GLuint i; - - /* - * Note: we'll return GL_FALSE below if we find relative indexing - * into the TEMP register file. We can't handle that yet. - * We also give up on subroutines for now. - */ - - if (dbg) { - printf("Optimize: Begin find intervals\n"); - } - - /* build intermediate arrays */ - if (!_mesa_find_temp_intervals(prog->Instructions, prog->NumInstructions, - intBegin, intEnd)) - return GL_FALSE; - - /* Build live intervals list from intermediate arrays */ - liveIntervals->Num = 0; - for (i = 0; i < MAX_PROGRAM_TEMPS; i++) { - if (intBegin[i] >= 0) { - struct interval inv; - inv.Reg = i; - inv.Start = intBegin[i]; - inv.End = intEnd[i]; - append_interval(liveIntervals, &inv); - } - } - - /* Sort the list according to interval starts */ - sort_interval_list_by_start(liveIntervals); - - if (dbg) { - /* print interval info */ - for (i = 0; i < liveIntervals->Num; i++) { - const struct interval *inv = liveIntervals->Intervals + i; - printf("Reg[%d] live [%d, %d]:", - inv->Reg, inv->Start, inv->End); - if (1) { - GLuint j; - for (j = 0; j < inv->Start; j++) - printf(" "); - for (j = inv->Start; j <= inv->End; j++) - printf("x"); - } - printf("\n"); - } - } - - return GL_TRUE; -} - - -/** Scan the array of used register flags to find free entry */ -static GLint -alloc_register(GLboolean usedRegs[MAX_PROGRAM_TEMPS]) -{ - GLuint k; - for (k = 0; k < MAX_PROGRAM_TEMPS; k++) { - if (!usedRegs[k]) { - usedRegs[k] = GL_TRUE; - return k; - } - } - return -1; -} - - -/** - * This function implements "Linear Scan Register Allocation" to reduce - * the number of temporary registers used by the program. - * - * We compute the "live interval" for all temporary registers then - * examine the overlap of the intervals to allocate new registers. - * Basically, if two intervals do not overlap, they can use the same register. - */ -static void -_mesa_reallocate_registers(struct gl_program *prog) -{ - struct interval_list liveIntervals; - GLint registerMap[MAX_PROGRAM_TEMPS]; - GLboolean usedRegs[MAX_PROGRAM_TEMPS]; - GLuint i; - GLint maxTemp = -1; - - if (dbg) { - printf("Optimize: Begin live-interval register reallocation\n"); - _mesa_print_program(prog); - } - - for (i = 0; i < MAX_PROGRAM_TEMPS; i++){ - registerMap[i] = -1; - usedRegs[i] = GL_FALSE; - } - - if (!find_live_intervals(prog, &liveIntervals)) { - if (dbg) - printf("Aborting register reallocation\n"); - return; - } - - { - struct interval_list activeIntervals; - activeIntervals.Num = 0; - - /* loop over live intervals, allocating a new register for each */ - for (i = 0; i < liveIntervals.Num; i++) { - const struct interval *live = liveIntervals.Intervals + i; - - if (dbg) - printf("Consider register %u\n", live->Reg); - - /* Expire old intervals. Intervals which have ended with respect - * to the live interval can have their remapped registers freed. - */ - { - GLint j; - for (j = 0; j < (GLint) activeIntervals.Num; j++) { - const struct interval *inv = activeIntervals.Intervals + j; - if (inv->End >= live->Start) { - /* Stop now. Since the activeInterval list is sorted - * we know we don't have to go further. - */ - break; - } - else { - /* Interval 'inv' has expired */ - const GLint regNew = registerMap[inv->Reg]; - ASSERT(regNew >= 0); - - if (dbg) - printf(" expire interval for reg %u\n", inv->Reg); - - /* remove interval j from active list */ - remove_interval(&activeIntervals, inv); - j--; /* counter-act j++ in for-loop above */ - - /* return register regNew to the free pool */ - if (dbg) - printf(" free reg %d\n", regNew); - ASSERT(usedRegs[regNew] == GL_TRUE); - usedRegs[regNew] = GL_FALSE; - } - } - } - - /* find a free register for this live interval */ - { - const GLint k = alloc_register(usedRegs); - if (k < 0) { - /* out of registers, give up */ - return; - } - registerMap[live->Reg] = k; - maxTemp = MAX2(maxTemp, k); - if (dbg) - printf(" remap register %u -> %d\n", live->Reg, k); - } - - /* Insert this live interval into the active list which is sorted - * by increasing end points. - */ - insert_interval_by_end(&activeIntervals, live); - } - } - - if (maxTemp + 1 < (GLint) liveIntervals.Num) { - /* OK, we've reduced the number of registers needed. - * Scan the program and replace all the old temporary register - * indexes with the new indexes. - */ - replace_regs(prog, PROGRAM_TEMPORARY, registerMap); - - prog->NumTemporaries = maxTemp + 1; - } - - if (dbg) { - printf("Optimize: End live-interval register reallocation\n"); - printf("Num temp regs before: %u after: %u\n", - liveIntervals.Num, maxTemp + 1); - _mesa_print_program(prog); - } -} - - -/** - * Apply optimizations to the given program to eliminate unnecessary - * instructions, temp regs, etc. - */ -void -_mesa_optimize_program(GLcontext *ctx, struct gl_program *program) -{ - _mesa_remove_extra_move_use(program); - - if (1) - _mesa_remove_dead_code(program); - - if (0) /* not tested much yet */ - _mesa_remove_extra_moves(program); - - if (0) - _mesa_consolidate_registers(program); - else - _mesa_reallocate_registers(program); -} diff --git a/mesalib/src/mesa/shader/prog_optimize.h b/mesalib/src/mesa/shader/prog_optimize.h deleted file mode 100644 index 43894a272..000000000 --- a/mesalib/src/mesa/shader/prog_optimize.h +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Mesa 3-D graphics library - * Version: 7.5 - * - * Copyright (C) 2009 VMware, 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 - * VMWARE 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_OPT_H -#define PROG_OPT_H - - -#include "main/config.h" - - -struct gl_program; -struct prog_instruction; - - -extern GLboolean -_mesa_find_temp_intervals(const struct prog_instruction *instructions, - GLuint numInstructions, - GLint intBegin[MAX_PROGRAM_TEMPS], - GLint intEnd[MAX_PROGRAM_TEMPS]); - -extern void -_mesa_optimize_program(GLcontext *ctx, struct gl_program *program); - -#endif diff --git a/mesalib/src/mesa/shader/prog_parameter.c b/mesalib/src/mesa/shader/prog_parameter.c deleted file mode 100644 index 25bb4f3d4..000000000 --- a/mesalib/src/mesa/shader/prog_parameter.c +++ /dev/null @@ -1,750 +0,0 @@ -/* - * Mesa 3-D graphics library - * Version: 7.3 - * - * Copyright (C) 1999-2008 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 "main/glheader.h" -#include "main/imports.h" -#include "main/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 CALLOC_STRUCT(gl_program_parameter_list); -} - - -struct gl_program_parameter_list * -_mesa_new_parameter_list_sized(unsigned size) -{ - struct gl_program_parameter_list *p = _mesa_new_parameter_list(); - - if ((p != NULL) && (size != 0)) { - p->Size = size; - - /* alloc arrays */ - p->Parameters = (struct gl_program_parameter *) - calloc(1, size * sizeof(struct gl_program_parameter)); - - p->ParameterValues = (GLfloat (*)[4]) - _mesa_align_malloc(size * 4 *sizeof(GLfloat), 16); - - - if ((p->Parameters == NULL) || (p->ParameterValues == NULL)) { - free(p->Parameters); - _mesa_align_free(p->ParameterValues); - free(p); - p = NULL; - } - } - - return p; -} - - -/** - * 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) - free((void *) paramList->Parameters[i].Name); - } - free(paramList->Parameters); - if (paramList->ParameterValues) - _mesa_align_free(paramList->ParameterValues); - 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 datatype GL_FLOAT, GL_FLOAT_VECx, GL_INT, GL_INT_VECx or GL_NONE. - * \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, - gl_register_file type, const char *name, - GLuint size, GLenum datatype, const GLfloat *values, - const gl_state_index state[STATE_LENGTH], - GLbitfield flags) -{ - 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; - - 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; - p->DataType = datatype; - p->Flags = flags; - if (values) { - COPY_4V(paramList->ParameterValues[oldNum + i], values); - values += 4; - p->Initialized = GL_TRUE; - } - 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, GL_NONE, values, NULL, 0x0); - -} - - -/** - * 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) -{ - /* first check if this is a duplicate constant */ - GLint pos; - for (pos = 0; pos < (GLint)paramList->NumParameters; pos++) { - const GLfloat *pvals = paramList->ParameterValues[pos]; - if (pvals[0] == values[0] && - pvals[1] == values[1] && - pvals[2] == values[2] && - pvals[3] == values[3] && - strcmp(paramList->Parameters[pos].Name, name) == 0) { - /* Same name and value is already in the param list - reuse it */ - return pos; - } - } - /* not found, add new parameter */ - return _mesa_add_parameter(paramList, PROGRAM_CONSTANT, name, - size, GL_NONE, values, NULL, 0x0); -} - - -/** - * 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 }; - * If swizzleOut is non-null we'll search the parameter list for an - * existing instance of the constant which matches with a swizzle. - * - * \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 (swizzleOut && - _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, GL_NONE, values, NULL, 0x0); - if (pos >= 0 && swizzleOut) { - if (size == 1) - *swizzleOut = SWIZZLE_XXXX; - else - *swizzleOut = SWIZZLE_NOOP; - } - return pos; -} - - -/** - * Add a uniform to the parameter list. - * Note that if the uniform is an array, size may be greater than - * what's implied by the datatype. - * \param name uniform's name - * \param size number of floats to allocate - * \param datatype GL_FLOAT_VEC3, GL_FLOAT_MAT4, etc. - */ -GLint -_mesa_add_uniform(struct gl_program_parameter_list *paramList, - const char *name, GLuint size, GLenum datatype, - const GLfloat *values) -{ - GLint i = _mesa_lookup_parameter_index(paramList, -1, name); - ASSERT(datatype != GL_NONE); - if (i >= 0 && paramList->Parameters[i].Type == PROGRAM_UNIFORM) { - ASSERT(paramList->Parameters[i].Size == size); - ASSERT(paramList->Parameters[i].DataType == datatype); - /* already in list */ - return i; - } - else { - i = _mesa_add_parameter(paramList, PROGRAM_UNIFORM, name, - size, datatype, values, NULL, 0x0); - return i; - } -} - - -/** - * Mark the named uniform as 'used'. - */ -void -_mesa_use_uniform(struct gl_program_parameter_list *paramList, - const char *name) -{ - GLuint i; - for (i = 0; i < paramList->NumParameters; i++) { - struct gl_program_parameter *p = paramList->Parameters + i; - if ((p->Type == PROGRAM_UNIFORM || p->Type == PROGRAM_SAMPLER) && - strcmp(p->Name, name) == 0) { - p->Used = GL_TRUE; - /* Note that large uniforms may occupy several slots so we're - * not done searching yet. - */ - } - } -} - - -/** - * Add a sampler to the parameter list. - * \param name uniform's name - * \param datatype GL_SAMPLER_2D, GL_SAMPLER_2D_RECT_ARB, etc. - * \param index the sampler number (as seen in TEX instructions) - * \return sampler index (starting at zero) or -1 if error - */ -GLint -_mesa_add_sampler(struct gl_program_parameter_list *paramList, - const char *name, GLenum datatype) -{ - GLint i = _mesa_lookup_parameter_index(paramList, -1, name); - if (i >= 0 && paramList->Parameters[i].Type == PROGRAM_SAMPLER) { - ASSERT(paramList->Parameters[i].Size == 1); - ASSERT(paramList->Parameters[i].DataType == datatype); - /* already in list */ - return (GLint) paramList->ParameterValues[i][0]; - } - else { - GLuint i; - const GLint size = 1; /* a sampler is basically a texture unit number */ - GLfloat value[4]; - GLint numSamplers = 0; - for (i = 0; i < paramList->NumParameters; i++) { - if (paramList->Parameters[i].Type == PROGRAM_SAMPLER) - numSamplers++; - } - value[0] = (GLfloat) numSamplers; - value[1] = value[2] = value[3] = 0.0F; - (void) _mesa_add_parameter(paramList, PROGRAM_SAMPLER, name, - size, datatype, value, NULL, 0x0); - return numSamplers; - } -} - - -/** - * Add parameter representing a varying variable. - */ -GLint -_mesa_add_varying(struct gl_program_parameter_list *paramList, - const char *name, GLuint size, GLbitfield flags) -{ - 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, GL_NONE, NULL, NULL, flags); - 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, GLenum datatype, 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, datatype, NULL, state, 0x0); - } - 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 stateTokens an array of 5 (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 */ - 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, GL_NONE, - NULL, (gl_state_index *) stateTokens, 0x0); - paramList->StateFlags |= _mesa_program_state_flags(stateTokens); - - /* free name string here since we duplicated it in add_parameter() */ - free(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) -{ - GLint 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 && - 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 && - strncmp(paramList->Parameters[i].Name, name, nameLen) == 0 - && 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 vSize 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; - } - } - } - } - /* smear last value to remaining positions */ - for (; j < 4; j++) - swz[j] = swz[j-1]; - - 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; - struct gl_program_parameter *pCopy; - GLuint size = MIN2(p->Size, 4); - GLint j = _mesa_add_parameter(clone, p->Type, p->Name, size, p->DataType, - list->ParameterValues[i], NULL, 0x0); - ASSERT(j >= 0); - pCopy = clone->Parameters + j; - pCopy->Used = p->Used; - pCopy->Flags = p->Flags; - /* copy state indexes */ - if (p->Type == PROGRAM_STATE_VAR) { - GLint k; - for (k = 0; k < STATE_LENGTH; k++) { - pCopy->StateIndexes[k] = p->StateIndexes[k]; - } - } - else { - clone->Parameters[j].Size = p->Size; - } - - } - - clone->StateFlags = list->StateFlags; - - return clone; -} - - -/** - * Return a new parameter list which is listA + listB. - */ -struct gl_program_parameter_list * -_mesa_combine_parameter_lists(const struct gl_program_parameter_list *listA, - const struct gl_program_parameter_list *listB) -{ - struct gl_program_parameter_list *list; - - if (listA) { - list = _mesa_clone_parameter_list(listA); - if (list && listB) { - GLuint i; - for (i = 0; i < listB->NumParameters; i++) { - struct gl_program_parameter *param = listB->Parameters + i; - _mesa_add_parameter(list, param->Type, param->Name, param->Size, - param->DataType, - listB->ParameterValues[i], - param->StateIndexes, - param->Flags); - } - } - } - else if (listB) { - list = _mesa_clone_parameter_list(listB); - } - else { - list = NULL; - } - return list; -} - - - -/** - * Find longest name of all uniform parameters in list. - */ -GLuint -_mesa_longest_parameter_name(const struct gl_program_parameter_list *list, - gl_register_file type) -{ - GLuint i, maxLen = 0; - if (!list) - return 0; - for (i = 0; i < list->NumParameters; i++) { - if (list->Parameters[i].Type == type) { - GLuint len = strlen(list->Parameters[i].Name); - if (len > maxLen) - maxLen = len; - } - } - return maxLen; -} - - -/** - * Count the number of parameters in the last that match the given type. - */ -GLuint -_mesa_num_parameters_of_type(const struct gl_program_parameter_list *list, - gl_register_file type) -{ - GLuint i, count = 0; - if (list) { - for (i = 0; i < list->NumParameters; i++) { - if (list->Parameters[i].Type == type) - count++; - } - } - return count; -} diff --git a/mesalib/src/mesa/shader/prog_parameter.h b/mesalib/src/mesa/shader/prog_parameter.h deleted file mode 100644 index 1111c8597..000000000 --- a/mesalib/src/mesa/shader/prog_parameter.h +++ /dev/null @@ -1,181 +0,0 @@ -/* - * Mesa 3-D graphics library - * Version: 7.3 - * - * Copyright (C) 1999-2008 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 "main/mtypes.h" -#include "prog_statevars.h" - - -/** - * Program parameter flags - */ -/*@{*/ -#define PROG_PARAM_BIT_CENTROID 0x1 /**< for varying vars (GLSL 1.20) */ -#define PROG_PARAM_BIT_INVARIANT 0x2 /**< for varying vars (GLSL 1.20) */ -#define PROG_PARAM_BIT_FLAT 0x4 /**< for varying vars (GLSL 1.30) */ -#define PROG_PARAM_BIT_LINEAR 0x8 /**< for varying vars (GLSL 1.30) */ -#define PROG_PARAM_BIT_CYL_WRAP 0x10 /**< XXX gallium debug */ -/*@}*/ - - - -/** - * Program parameter. - * Used by shaders/programs for uniforms, constants, varying vars, etc. - */ -struct gl_program_parameter -{ - const char *Name; /**< Null-terminated string */ - gl_register_file Type; /**< PROGRAM_NAMED_PARAM, CONSTANT or STATE_VAR */ - GLenum DataType; /**< GL_FLOAT, GL_FLOAT_VEC2, etc */ - /** - * Number of components (1..4), or more. - * If the number of components is greater than 4, - * this parameter is part of a larger uniform like a GLSL matrix or array. - * The next program parameter's Size will be Size-4 of this parameter. - */ - GLuint Size; - GLboolean Used; /**< Helper flag for GLSL uniform tracking */ - GLboolean Initialized; /**< Has the ParameterValue[] been set? */ - GLbitfield Flags; /**< Bitmask of PROG_PARAM_*_BIT */ - /** - * 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 struct gl_program_parameter_list * -_mesa_new_parameter_list_sized(unsigned size); - -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 struct gl_program_parameter_list * -_mesa_combine_parameter_lists(const struct gl_program_parameter_list *a, - const struct gl_program_parameter_list *b); - -static INLINE GLuint -_mesa_num_parameters(const struct gl_program_parameter_list *list) -{ - return list ? list->NumParameters : 0; -} - -extern GLint -_mesa_add_parameter(struct gl_program_parameter_list *paramList, - gl_register_file type, const char *name, - GLuint size, GLenum datatype, const GLfloat *values, - const gl_state_index state[STATE_LENGTH], - GLbitfield flags); - -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, GLenum datatype, - const GLfloat *values); - -extern void -_mesa_use_uniform(struct gl_program_parameter_list *paramList, - const char *name); - -extern GLint -_mesa_add_sampler(struct gl_program_parameter_list *paramList, - const char *name, GLenum datatype); - -extern GLint -_mesa_add_varying(struct gl_program_parameter_list *paramList, - const char *name, GLuint size, GLbitfield flags); - -extern GLint -_mesa_add_attribute(struct gl_program_parameter_list *paramList, - const char *name, GLint size, GLenum datatype, 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_longest_parameter_name(const struct gl_program_parameter_list *list, - gl_register_file type); - -extern GLuint -_mesa_num_parameters_of_type(const struct gl_program_parameter_list *list, - gl_register_file type); - - -#endif /* PROG_PARAMETER_H */ diff --git a/mesalib/src/mesa/shader/prog_parameter_layout.c b/mesalib/src/mesa/shader/prog_parameter_layout.c deleted file mode 100644 index a88857383..000000000 --- a/mesalib/src/mesa/shader/prog_parameter_layout.c +++ /dev/null @@ -1,213 +0,0 @@ -/* - * Copyright © 2009 Intel Corporation - * - * 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 (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 NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS 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_layout.c - * \brief Helper functions to layout storage for program parameters - * - * \author Ian Romanick <ian.d.romanick@intel.com> - */ - -#include "main/mtypes.h" -#include "prog_parameter.h" -#include "prog_parameter_layout.h" -#include "prog_instruction.h" -#include "program_parser.h" - -unsigned -_mesa_combine_swizzles(unsigned base, unsigned applied) -{ - unsigned swiz = 0; - unsigned i; - - for (i = 0; i < 4; i++) { - const unsigned s = GET_SWZ(applied, i); - - swiz |= ((s <= SWIZZLE_W) ? GET_SWZ(base, s) : s) << (i * 3); - } - - return swiz; -} - - -/** - * Copy indirect access array from one parameter list to another - * - * \param src Parameter array copied from - * \param dst Parameter array copied to - * \param first Index of first element in \c src to copy - * \param count Number of elements to copy - * - * \return - * The location in \c dst of the first element copied from \c src on - * success. -1 on failure. - * - * \warning - * This function assumes that there is already enough space available in - * \c dst to hold all of the elements that will be copied over. - */ -static int -copy_indirect_accessed_array(struct gl_program_parameter_list *src, - struct gl_program_parameter_list *dst, - unsigned first, unsigned count) -{ - const int base = dst->NumParameters; - unsigned i, j; - - for (i = first; i < (first + count); i++) { - struct gl_program_parameter *curr = & src->Parameters[i]; - - if (curr->Type == PROGRAM_CONSTANT) { - j = dst->NumParameters; - } else { - for (j = 0; j < dst->NumParameters; j++) { - if (memcmp(dst->Parameters[j].StateIndexes, curr->StateIndexes, - sizeof(curr->StateIndexes)) == 0) { - return -1; - } - } - } - - assert(j == dst->NumParameters); - - /* copy src parameter [i] to dest parameter [j] */ - memcpy(& dst->Parameters[j], curr, - sizeof(dst->Parameters[j])); - memcpy(dst->ParameterValues[j], src->ParameterValues[i], - sizeof(GLfloat) * 4); - - /* Pointer to the string name was copied. Null-out src param name - * to prevent double free later. - */ - curr->Name = NULL; - - dst->NumParameters++; - } - - return base; -} - - -/** - * XXX description??? - * \return GL_TRUE for success, GL_FALSE for failure - */ -GLboolean -_mesa_layout_parameters(struct asm_parser_state *state) -{ - struct gl_program_parameter_list *layout; - struct asm_instruction *inst; - unsigned i; - - layout = - _mesa_new_parameter_list_sized(state->prog->Parameters->NumParameters); - - /* PASS 1: Move any parameters that are accessed indirectly from the - * original parameter list to the new parameter list. - */ - for (inst = state->inst_head; inst != NULL; inst = inst->next) { - for (i = 0; i < 3; i++) { - if (inst->SrcReg[i].Base.RelAddr) { - /* Only attempt to add the to the new parameter list once. - */ - if (!inst->SrcReg[i].Symbol->pass1_done) { - const int new_begin = - copy_indirect_accessed_array(state->prog->Parameters, layout, - inst->SrcReg[i].Symbol->param_binding_begin, - inst->SrcReg[i].Symbol->param_binding_length); - - if (new_begin < 0) { - return GL_FALSE; - } - - inst->SrcReg[i].Symbol->param_binding_begin = new_begin; - inst->SrcReg[i].Symbol->pass1_done = 1; - } - - /* Previously the Index was just the offset from the parameter - * array. Now that the base of the parameter array is known, the - * index can be updated to its actual value. - */ - inst->Base.SrcReg[i] = inst->SrcReg[i].Base; - inst->Base.SrcReg[i].Index += - inst->SrcReg[i].Symbol->param_binding_begin; - } - } - } - - /* PASS 2: Move any parameters that are not accessed indirectly from the - * original parameter list to the new parameter list. - */ - for (inst = state->inst_head; inst != NULL; inst = inst->next) { - for (i = 0; i < 3; i++) { - const struct gl_program_parameter *p; - const int idx = inst->SrcReg[i].Base.Index; - unsigned swizzle = SWIZZLE_NOOP; - - /* All relative addressed operands were processed on the first - * pass. Just skip them here. - */ - if (inst->SrcReg[i].Base.RelAddr) { - continue; - } - - if ((inst->SrcReg[i].Base.File <= PROGRAM_VARYING ) - || (inst->SrcReg[i].Base.File >= PROGRAM_WRITE_ONLY)) { - continue; - } - - inst->Base.SrcReg[i] = inst->SrcReg[i].Base; - p = & state->prog->Parameters->Parameters[idx]; - - switch (p->Type) { - case PROGRAM_CONSTANT: { - const float *const v = - state->prog->Parameters->ParameterValues[idx]; - - inst->Base.SrcReg[i].Index = - _mesa_add_unnamed_constant(layout, v, p->Size, & swizzle); - - inst->Base.SrcReg[i].Swizzle = - _mesa_combine_swizzles(swizzle, inst->Base.SrcReg[i].Swizzle); - break; - } - - case PROGRAM_STATE_VAR: - inst->Base.SrcReg[i].Index = - _mesa_add_state_reference(layout, p->StateIndexes); - break; - - default: - break; - } - - inst->SrcReg[i].Base.File = p->Type; - inst->Base.SrcReg[i].File = p->Type; - } - } - - _mesa_free_parameter_list(state->prog->Parameters); - state->prog->Parameters = layout; - - return GL_TRUE; -} diff --git a/mesalib/src/mesa/shader/prog_parameter_layout.h b/mesalib/src/mesa/shader/prog_parameter_layout.h deleted file mode 100644 index 99a7b6c72..000000000 --- a/mesalib/src/mesa/shader/prog_parameter_layout.h +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Copyright © 2009 Intel Corporation - * - * 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 (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 NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS 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_layout.h - * \brief Helper functions to layout storage for program parameters - * - * \author Ian Romanick <ian.d.romanick@intel.com> - */ - -#pragma once - -#ifndef PROG_PARAMETER_LAYOUT_H -#define PROG_PARAMETER_LAYOUT_H - -extern unsigned _mesa_combine_swizzles(unsigned base, unsigned applied); - -struct asm_parser_state; - -extern GLboolean _mesa_layout_parameters(struct asm_parser_state *state); - -#endif /* PROG_PARAMETER_LAYOUT_H */ diff --git a/mesalib/src/mesa/shader/prog_print.c b/mesalib/src/mesa/shader/prog_print.c deleted file mode 100644 index f66c240ce..000000000 --- a/mesalib/src/mesa/shader/prog_print.c +++ /dev/null @@ -1,1065 +0,0 @@ -/* - * Mesa 3-D graphics library - * Version: 7.3 - * - * Copyright (C) 1999-2008 Brian Paul All Rights Reserved. - * Copyright (C) 2009 VMware, 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. - */ - -/** - * \file prog_print.c - * Print vertex/fragment programs - for debugging. - * \author Brian Paul - */ - -#include "main/glheader.h" -#include "main/context.h" -#include "main/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(gl_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"; - case PROGRAM_UNDEFINED: - return "UNDEFINED"; - default: - { - static char s[20]; - _mesa_snprintf(s, sizeof(s), "FILE%u", f); - return s; - } - } -} - - -/** - * Return ARB_v/f_prog-style input attrib string. - */ -static const char * -arb_input_attrib_string(GLint index, GLenum progType) -{ - /* - * These strings should match the VERT_ATTRIB_x and FRAG_ATTRIB_x tokens. - */ - 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]", - "vertex.attrib[0]", - "vertex.attrib[1]", - "vertex.attrib[2]", - "vertex.attrib[3]", - "vertex.attrib[4]", - "vertex.attrib[5]", - "vertex.attrib[6]", - "vertex.attrib[7]", - "vertex.attrib[8]", - "vertex.attrib[9]", - "vertex.attrib[10]", - "vertex.attrib[11]", - "vertex.attrib[12]", - "vertex.attrib[13]", - "vertex.attrib[14]", - "vertex.attrib[15]" - }; - 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]" - }; - - /* sanity checks */ - assert(strcmp(vertAttribs[VERT_ATTRIB_TEX0], "vertex.texcoord[0]") == 0); - assert(strcmp(vertAttribs[VERT_ATTRIB_GENERIC15], "vertex.attrib[15]") == 0); - - 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]; - } -} - - -/** - * Print a vertex program's InputsRead field in human-readable format. - * For debugging. - */ -void -_mesa_print_vp_inputs(GLbitfield inputs) -{ - printf("VP Inputs 0x%x: \n", inputs); - while (inputs) { - GLint attr = _mesa_ffs(inputs) - 1; - const char *name = arb_input_attrib_string(attr, - GL_VERTEX_PROGRAM_ARB); - printf(" %d: %s\n", attr, name); - inputs &= ~(1 << attr); - } -} - - -/** - * Print a fragment program's InputsRead field in human-readable format. - * For debugging. - */ -void -_mesa_print_fp_inputs(GLbitfield inputs) -{ - printf("FP Inputs 0x%x: \n", inputs); - while (inputs) { - GLint attr = _mesa_ffs(inputs) - 1; - const char *name = arb_input_attrib_string(attr, - GL_FRAGMENT_PROGRAM_ARB); - printf(" %d: %s\n", attr, name); - inputs &= ~(1 << attr); - } -} - - - -/** - * Return ARB_v/f_prog-style output attrib string. - */ -static const char * -arb_output_attrib_string(GLint index, GLenum progType) -{ - /* - * These strings should match the VERT_RESULT_x and FRAG_RESULT_x tokens. - */ - 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.color(half)", - "result.depth", - "result.color[0]", - "result.color[1]", - "result.color[2]", - "result.color[3]" - }; - - 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 f 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(gl_register_file f, GLint index, gl_prog_print_mode mode, - GLboolean relAddr, const struct gl_program *prog) -{ - static char str[100]; - const char *addr = relAddr ? "ADDR+" : ""; - - str[0] = 0; - - switch (mode) { - case PROG_PRINT_DEBUG: - sprintf(str, "%s[%s%d]", file_string(f, mode), addr, 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[%s%d]", addr, index); - break; - case PROGRAM_LOCAL_PARAM: - sprintf(str, "program.local[%s%d]", addr, index); - break; - case PROGRAM_VARYING: /* extension */ - sprintf(str, "varying[%s%d]", addr, index); - break; - case PROGRAM_CONSTANT: /* extension */ - sprintf(str, "constant[%s%d]", addr, index); - break; - case PROGRAM_UNIFORM: /* extension */ - sprintf(str, "uniform[%s%d]", addr, index); - break; - case PROGRAM_STATE_VAR: - { - struct gl_program_parameter *param - = prog->Parameters->Parameters + index; - char *state = _mesa_program_state_string(param->StateIndexes); - sprintf(str, "%s", state); - free(state); - } - 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[%s%d]", addr, index); - break; - case PROGRAM_UNIFORM: /* extension */ - sprintf(str, "uniform[%s%d]", addr, index); - break; - case PROGRAM_CONSTANT: /* extension */ - sprintf(str, "constant[%s%d]", addr, index); - break; - case PROGRAM_STATE_VAR: /* extension */ - sprintf(str, "state[%s%d]", addr, 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 negateMask, GLboolean extended) -{ - static const char swz[] = "xyzw01!?"; /* See SWIZZLE_x definitions */ - static char s[20]; - GLuint i = 0; - - if (!extended && swizzle == SWIZZLE_NOOP && negateMask == 0) - return ""; /* no swizzle/negation */ - - if (!extended) - s[i++] = '.'; - - if (negateMask & NEGATE_X) - s[i++] = '-'; - s[i++] = swz[GET_SWZ(swizzle, 0)]; - - if (extended) { - s[i++] = ','; - } - - if (negateMask & NEGATE_Y) - s[i++] = '-'; - s[i++] = swz[GET_SWZ(swizzle, 1)]; - - if (extended) { - s[i++] = ','; - } - - if (negateMask & NEGATE_Z) - s[i++] = '-'; - s[i++] = swz[GET_SWZ(swizzle, 2)]; - - if (extended) { - s[i++] = ','; - } - - if (negateMask & NEGATE_W) - s[i++] = '-'; - s[i++] = swz[GET_SWZ(swizzle, 3)]; - - s[i] = 0; - return s; -} - - -void -_mesa_print_swizzle(GLuint swizzle) -{ - if (swizzle == SWIZZLE_XYZW) { - printf(".xyzw\n"); - } - else { - const char *s = _mesa_swizzle_string(swizzle, 0, 0); - printf("%s\n", s); - } -} - - -const char * -_mesa_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; -} - - -const char * -_mesa_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 -fprint_dst_reg(FILE * f, - const struct prog_dst_register *dstReg, - gl_prog_print_mode mode, - const struct gl_program *prog) -{ - fprintf(f, "%s%s", - reg_string((gl_register_file) dstReg->File, - dstReg->Index, mode, dstReg->RelAddr, prog), - _mesa_writemask_string(dstReg->WriteMask)); - - if (dstReg->CondMask != COND_TR) { - fprintf(f, " (%s.%s)", - _mesa_condcode_string(dstReg->CondMask), - _mesa_swizzle_string(dstReg->CondSwizzle, - GL_FALSE, GL_FALSE)); - } - -#if 0 - fprintf(f, "%s[%d]%s", - file_string((gl_register_file) dstReg->File, mode), - dstReg->Index, - _mesa_writemask_string(dstReg->WriteMask)); -#endif -} - - -static void -fprint_src_reg(FILE *f, - const struct prog_src_register *srcReg, - gl_prog_print_mode mode, - const struct gl_program *prog) -{ - const char *abs = srcReg->Abs ? "|" : ""; - - fprintf(f, "%s%s%s%s", - abs, - reg_string((gl_register_file) srcReg->File, - srcReg->Index, mode, srcReg->RelAddr, prog), - _mesa_swizzle_string(srcReg->Swizzle, - srcReg->Negate, GL_FALSE), - abs); -#if 0 - fprintf(f, "%s[%d]%s", - file_string((gl_register_file) srcReg->File, mode), - srcReg->Index, - _mesa_swizzle_string(srcReg->Swizzle, - srcReg->Negate, GL_FALSE)); -#endif -} - - -static void -fprint_comment(FILE *f, const struct prog_instruction *inst) -{ - if (inst->Comment) - fprintf(f, "; # %s\n", inst->Comment); - else - fprintf(f, ";\n"); -} - - -static void -fprint_alu_instruction(FILE *f, - const struct prog_instruction *inst, - const char *opcode_string, GLuint numRegs, - gl_prog_print_mode mode, - const struct gl_program *prog) -{ - GLuint j; - - fprintf(f, "%s", opcode_string); - if (inst->CondUpdate) - fprintf(f, ".C"); - - /* frag prog only */ - if (inst->SaturateMode == SATURATE_ZERO_ONE) - fprintf(f, "_SAT"); - - fprintf(f, " "); - if (inst->DstReg.File != PROGRAM_UNDEFINED) { - fprint_dst_reg(f, &inst->DstReg, mode, prog); - } - else { - fprintf(f, " ???"); - } - - if (numRegs > 0) - fprintf(f, ", "); - - for (j = 0; j < numRegs; j++) { - fprint_src_reg(f, inst->SrcReg + j, mode, prog); - if (j + 1 < numRegs) - fprintf(f, ", "); - } - - fprint_comment(f, inst); -} - - -void -_mesa_print_alu_instruction(const struct prog_instruction *inst, - const char *opcode_string, GLuint numRegs) -{ - fprint_alu_instruction(stderr, inst, opcode_string, - numRegs, PROG_PRINT_DEBUG, NULL); -} - - -/** - * Print a single vertex/fragment program instruction. - */ -GLint -_mesa_fprint_instruction_opt(FILE *f, - 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++) { - fprintf(f, " "); - } - - switch (inst->Opcode) { - case OPCODE_PRINT: - fprintf(f, "PRINT '%s'", (char *) inst->Data); - if (inst->SrcReg[0].File != PROGRAM_UNDEFINED) { - fprintf(f, ", "); - fprintf(f, "%s[%d]%s", - file_string((gl_register_file) inst->SrcReg[0].File, - mode), - inst->SrcReg[0].Index, - _mesa_swizzle_string(inst->SrcReg[0].Swizzle, - inst->SrcReg[0].Negate, GL_FALSE)); - } - if (inst->Comment) - fprintf(f, " # %s", inst->Comment); - fprint_comment(f, inst); - break; - case OPCODE_SWZ: - fprintf(f, "SWZ"); - if (inst->SaturateMode == SATURATE_ZERO_ONE) - fprintf(f, "_SAT"); - fprintf(f, " "); - fprint_dst_reg(f, &inst->DstReg, mode, prog); - fprintf(f, ", %s[%d], %s", - file_string((gl_register_file) inst->SrcReg[0].File, - mode), - inst->SrcReg[0].Index, - _mesa_swizzle_string(inst->SrcReg[0].Swizzle, - inst->SrcReg[0].Negate, GL_TRUE)); - fprint_comment(f, inst); - break; - case OPCODE_TEX: - case OPCODE_TXP: - case OPCODE_TXL: - case OPCODE_TXB: - fprintf(f, "%s", _mesa_opcode_string(inst->Opcode)); - if (inst->SaturateMode == SATURATE_ZERO_ONE) - fprintf(f, "_SAT"); - fprintf(f, " "); - fprint_dst_reg(f, &inst->DstReg, mode, prog); - fprintf(f, ", "); - fprint_src_reg(f, &inst->SrcReg[0], mode, prog); - fprintf(f, ", texture[%d], ", inst->TexSrcUnit); - switch (inst->TexSrcTarget) { - case TEXTURE_1D_INDEX: fprintf(f, "1D"); break; - case TEXTURE_2D_INDEX: fprintf(f, "2D"); break; - case TEXTURE_3D_INDEX: fprintf(f, "3D"); break; - case TEXTURE_CUBE_INDEX: fprintf(f, "CUBE"); break; - case TEXTURE_RECT_INDEX: fprintf(f, "RECT"); break; - case TEXTURE_1D_ARRAY_INDEX: fprintf(f, "1D_ARRAY"); break; - case TEXTURE_2D_ARRAY_INDEX: fprintf(f, "2D_ARRAY"); break; - default: - ; - } - if (inst->TexShadow) - fprintf(f, " SHADOW"); - fprint_comment(f, inst); - break; - - case OPCODE_KIL: - fprintf(f, "%s", _mesa_opcode_string(inst->Opcode)); - fprintf(f, " "); - fprint_src_reg(f, &inst->SrcReg[0], mode, prog); - fprint_comment(f, inst); - break; - case OPCODE_KIL_NV: - fprintf(f, "%s", _mesa_opcode_string(inst->Opcode)); - fprintf(f, " "); - fprintf(f, "%s.%s", - _mesa_condcode_string(inst->DstReg.CondMask), - _mesa_swizzle_string(inst->DstReg.CondSwizzle, - GL_FALSE, GL_FALSE)); - fprint_comment(f, inst); - break; - - case OPCODE_ARL: - fprintf(f, "ARL "); - fprint_dst_reg(f, &inst->DstReg, mode, prog); - fprintf(f, ", "); - fprint_src_reg(f, &inst->SrcReg[0], mode, prog); - fprint_comment(f, inst); - break; - case OPCODE_BRA: - fprintf(f, "BRA %d (%s%s)", - inst->BranchTarget, - _mesa_condcode_string(inst->DstReg.CondMask), - _mesa_swizzle_string(inst->DstReg.CondSwizzle, 0, GL_FALSE)); - fprint_comment(f, inst); - break; - case OPCODE_IF: - if (inst->SrcReg[0].File != PROGRAM_UNDEFINED) { - /* Use ordinary register */ - fprintf(f, "IF "); - fprint_src_reg(f, &inst->SrcReg[0], mode, prog); - fprintf(f, "; "); - } - else { - /* Use cond codes */ - fprintf(f, "IF (%s%s);", - _mesa_condcode_string(inst->DstReg.CondMask), - _mesa_swizzle_string(inst->DstReg.CondSwizzle, - 0, GL_FALSE)); - } - fprintf(f, " # (if false, goto %d)", inst->BranchTarget); - fprint_comment(f, inst); - return indent + 3; - case OPCODE_ELSE: - fprintf(f, "ELSE; # (goto %d)\n", inst->BranchTarget); - return indent + 3; - case OPCODE_ENDIF: - fprintf(f, "ENDIF;\n"); - break; - case OPCODE_BGNLOOP: - fprintf(f, "BGNLOOP; # (end at %d)\n", inst->BranchTarget); - return indent + 3; - case OPCODE_ENDLOOP: - fprintf(f, "ENDLOOP; # (goto %d)\n", inst->BranchTarget); - break; - case OPCODE_BRK: - case OPCODE_CONT: - fprintf(f, "%s (%s%s); # (goto %d)", - _mesa_opcode_string(inst->Opcode), - _mesa_condcode_string(inst->DstReg.CondMask), - _mesa_swizzle_string(inst->DstReg.CondSwizzle, 0, GL_FALSE), - inst->BranchTarget); - fprint_comment(f, inst); - break; - - case OPCODE_BGNSUB: - if (mode == PROG_PRINT_NV) { - fprintf(f, "%s:\n", inst->Comment); /* comment is label */ - return indent; - } - else { - fprintf(f, "BGNSUB"); - fprint_comment(f, inst); - return indent + 3; - } - case OPCODE_ENDSUB: - if (mode == PROG_PRINT_DEBUG) { - fprintf(f, "ENDSUB"); - fprint_comment(f, inst); - } - break; - case OPCODE_CAL: - if (mode == PROG_PRINT_NV) { - fprintf(f, "CAL %s; # (goto %d)\n", inst->Comment, inst->BranchTarget); - } - else { - fprintf(f, "CAL %u", inst->BranchTarget); - fprint_comment(f, inst); - } - break; - case OPCODE_RET: - fprintf(f, "RET (%s%s)", - _mesa_condcode_string(inst->DstReg.CondMask), - _mesa_swizzle_string(inst->DstReg.CondSwizzle, 0, GL_FALSE)); - fprint_comment(f, inst); - break; - - case OPCODE_END: - fprintf(f, "END\n"); - break; - case OPCODE_NOP: - if (mode == PROG_PRINT_DEBUG) { - fprintf(f, "NOP"); - fprint_comment(f, inst); - } - else if (inst->Comment) { - /* ARB/NV extensions don't have NOP instruction */ - fprintf(f, "# %s\n", inst->Comment); - } - break; - /* XXX may need other special-case instructions */ - default: - if (inst->Opcode < MAX_OPCODE) { - /* typical alu instruction */ - fprint_alu_instruction(f, inst, - _mesa_opcode_string(inst->Opcode), - _mesa_num_inst_src_regs(inst->Opcode), - mode, prog); - } - else { - fprint_alu_instruction(f, inst, - _mesa_opcode_string(inst->Opcode), - 3/*_mesa_num_inst_src_regs(inst->Opcode)*/, - mode, prog); - } - break; - } - return indent; -} - - -GLint -_mesa_print_instruction_opt(const struct prog_instruction *inst, - GLint indent, - gl_prog_print_mode mode, - const struct gl_program *prog) -{ - return _mesa_fprint_instruction_opt(stderr, inst, indent, mode, prog); -} - - -void -_mesa_print_instruction(const struct prog_instruction *inst) -{ - /* note: 4th param should be ignored for PROG_PRINT_DEBUG */ - _mesa_fprint_instruction_opt(stderr, inst, 0, PROG_PRINT_DEBUG, NULL); -} - - - -/** - * Print program, with options. - */ -void -_mesa_fprint_program_opt(FILE *f, - 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) - fprintf(f, "!!ARBvp1.0\n"); - else if (mode == PROG_PRINT_NV) - fprintf(f, "!!VP1.0\n"); - else - fprintf(f, "# Vertex Program/Shader %u\n", prog->Id); - break; - case GL_FRAGMENT_PROGRAM_ARB: - case GL_FRAGMENT_PROGRAM_NV: - if (mode == PROG_PRINT_ARB) - fprintf(f, "!!ARBfp1.0\n"); - else if (mode == PROG_PRINT_NV) - fprintf(f, "!!FP1.0\n"); - else - fprintf(f, "# Fragment Program/Shader %u\n", prog->Id); - break; - } - - for (i = 0; i < prog->NumInstructions; i++) { - if (lineNumbers) - fprintf(f, "%3d: ", i); - indent = _mesa_fprint_instruction_opt(f, prog->Instructions + i, - indent, mode, prog); - } -} - - -/** - * Print program to stderr, default options. - */ -void -_mesa_print_program(const struct gl_program *prog) -{ - _mesa_fprint_program_opt(stderr, prog, PROG_PRINT_DEBUG, GL_TRUE); -} - - -/** - * Return binary representation of 64-bit value (as a string). - * Insert a comma to separate each group of 8 bits. - * Note we return a pointer to local static storage so this is not - * re-entrant, etc. - * XXX move to imports.[ch] if useful elsewhere. - */ -static const char * -binary(GLbitfield64 val) -{ - static char buf[80]; - GLint i, len = 0; - for (i = 63; i >= 0; --i) { - if (val & (1ULL << i)) - buf[len++] = '1'; - else if (len > 0 || i == 0) - buf[len++] = '0'; - if (len > 0 && ((i-1) % 8) == 7) - buf[len++] = ','; - } - buf[len] = '\0'; - return buf; -} - - -/** - * Print all of a program's parameters/fields to given file. - */ -static void -_mesa_fprint_program_parameters(FILE *f, - GLcontext *ctx, - const struct gl_program *prog) -{ - GLuint i; - - fprintf(f, "InputsRead: 0x%x (0b%s)\n", - prog->InputsRead, binary(prog->InputsRead)); - fprintf(f, "OutputsWritten: 0x%llx (0b%s)\n", - prog->OutputsWritten, binary(prog->OutputsWritten)); - fprintf(f, "NumInstructions=%d\n", prog->NumInstructions); - fprintf(f, "NumTemporaries=%d\n", prog->NumTemporaries); - fprintf(f, "NumParameters=%d\n", prog->NumParameters); - fprintf(f, "NumAttributes=%d\n", prog->NumAttributes); - fprintf(f, "NumAddressRegs=%d\n", prog->NumAddressRegs); - fprintf(f, "SamplersUsed: 0x%x (0b%s)\n", - prog->SamplersUsed, binary(prog->SamplersUsed)); - fprintf(f, "Samplers=[ "); - for (i = 0; i < MAX_SAMPLERS; i++) { - fprintf(f, "%d ", prog->SamplerUnits[i]); - } - fprintf(f, "]\n"); - - _mesa_load_state_parameters(ctx, prog->Parameters); - -#if 0 - fprintf(f, "Local Params:\n"); - for (i = 0; i < MAX_PROGRAM_LOCAL_PARAMS; i++){ - const GLfloat *p = prog->LocalParams[i]; - fprintf(f, "%2d: %f, %f, %f, %f\n", i, p[0], p[1], p[2], p[3]); - } -#endif - _mesa_print_parameter_list(prog->Parameters); -} - - -/** - * Print all of a program's parameters/fields to stderr. - */ -void -_mesa_print_program_parameters(GLcontext *ctx, const struct gl_program *prog) -{ - _mesa_fprint_program_parameters(stderr, ctx, prog); -} - - -/** - * Print a program parameter list to given file. - */ -static void -_mesa_fprint_parameter_list(FILE *f, - const struct gl_program_parameter_list *list) -{ - const gl_prog_print_mode mode = PROG_PRINT_DEBUG; - GLuint i; - - if (!list) - return; - - if (0) - fprintf(f, "param list %p\n", (void *) list); - fprintf(f, "dirty state flags: 0x%x\n", list->StateFlags); - for (i = 0; i < list->NumParameters; i++){ - struct gl_program_parameter *param = list->Parameters + i; - const GLfloat *v = list->ParameterValues[i]; - fprintf(f, "param[%d] sz=%d %s %s = {%.3g, %.3g, %.3g, %.3g}", - i, param->Size, - file_string(list->Parameters[i].Type, mode), - param->Name, v[0], v[1], v[2], v[3]); - if (param->Flags & PROG_PARAM_BIT_CENTROID) - fprintf(f, " Centroid"); - if (param->Flags & PROG_PARAM_BIT_INVARIANT) - fprintf(f, " Invariant"); - if (param->Flags & PROG_PARAM_BIT_FLAT) - fprintf(f, " Flat"); - if (param->Flags & PROG_PARAM_BIT_LINEAR) - fprintf(f, " Linear"); - fprintf(f, "\n"); - } -} - - -/** - * Print a program parameter list to stderr. - */ -void -_mesa_print_parameter_list(const struct gl_program_parameter_list *list) -{ - _mesa_fprint_parameter_list(stderr, list); -} - - -/** - * Write shader and associated info to a file. - */ -void -_mesa_write_shader_to_file(const struct gl_shader *shader) -{ - const char *type; - char filename[100]; - FILE *f; - - if (shader->Type == GL_FRAGMENT_SHADER) - type = "frag"; - else - type = "vert"; - - _mesa_snprintf(filename, sizeof(filename), "shader_%u.%s", shader->Name, type); - f = fopen(filename, "w"); - if (!f) { - fprintf(stderr, "Unable to open %s for writing\n", filename); - return; - } - - fprintf(f, "/* Shader %u source, checksum %u */\n", shader->Name, shader->SourceChecksum); - fputs(shader->Source, f); - fprintf(f, "\n"); - - fprintf(f, "/* Compile status: %s */\n", - shader->CompileStatus ? "ok" : "fail"); - if (!shader->CompileStatus) { - fprintf(f, "/* Log Info: */\n"); - fputs(shader->InfoLog, f); - } - else { - fprintf(f, "/* GPU code */\n"); - fprintf(f, "/*\n"); - _mesa_fprint_program_opt(f, shader->Program, PROG_PRINT_DEBUG, GL_TRUE); - fprintf(f, "*/\n"); - fprintf(f, "/* Parameters / constants */\n"); - fprintf(f, "/*\n"); - _mesa_fprint_parameter_list(f, shader->Program->Parameters); - fprintf(f, "*/\n"); - } - - fclose(f); -} - - -/** - * Append the shader's uniform info/values to the shader log file. - * The log file will typically have been created by the - * _mesa_write_shader_to_file function. - */ -void -_mesa_append_uniforms_to_file(const struct gl_shader *shader, - const struct gl_program *prog) -{ - const char *type; - char filename[100]; - FILE *f; - - if (shader->Type == GL_FRAGMENT_SHADER) - type = "frag"; - else - type = "vert"; - - _mesa_snprintf(filename, sizeof(filename), "shader_%u.%s", shader->Name, type); - f = fopen(filename, "a"); /* append */ - if (!f) { - fprintf(stderr, "Unable to open %s for appending\n", filename); - return; - } - - fprintf(f, "/* First-draw parameters / constants */\n"); - fprintf(f, "/*\n"); - _mesa_fprint_parameter_list(f, prog->Parameters); - fprintf(f, "*/\n"); - - fclose(f); -} diff --git a/mesalib/src/mesa/shader/prog_print.h b/mesalib/src/mesa/shader/prog_print.h deleted file mode 100644 index 9ab745601..000000000 --- a/mesalib/src/mesa/shader/prog_print.h +++ /dev/null @@ -1,100 +0,0 @@ -/* - * 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_PRINT_H -#define PROG_PRINT_H - - -/** - * The output style to use when printing programs. - */ -typedef enum { - PROG_PRINT_ARB, - PROG_PRINT_NV, - PROG_PRINT_DEBUG -} gl_prog_print_mode; - - -extern void -_mesa_print_vp_inputs(GLbitfield inputs); - -extern void -_mesa_print_fp_inputs(GLbitfield inputs); - -extern const char * -_mesa_condcode_string(GLuint condcode); - -extern const char * -_mesa_swizzle_string(GLuint swizzle, GLuint negateBase, GLboolean extended); - -const char * -_mesa_writemask_string(GLuint writeMask); - -extern void -_mesa_print_swizzle(GLuint swizzle); - -extern void -_mesa_print_alu_instruction(const struct prog_instruction *inst, - const char *opcode_string, GLuint numRegs); - -extern void -_mesa_print_instruction(const struct prog_instruction *inst); - -extern GLint -_mesa_fprint_instruction_opt(FILE *f, - const struct prog_instruction *inst, - GLint indent, - gl_prog_print_mode mode, - const struct gl_program *prog); - -extern GLint -_mesa_print_instruction_opt(const struct prog_instruction *inst, GLint indent, - gl_prog_print_mode mode, - const struct gl_program *prog); - -extern void -_mesa_print_program(const struct gl_program *prog); - -extern void -_mesa_fprint_program_opt(FILE *f, - const struct gl_program *prog, gl_prog_print_mode mode, - GLboolean lineNumbers); - -extern void -_mesa_print_program_parameters(GLcontext *ctx, const struct gl_program *prog); - -extern void -_mesa_print_parameter_list(const struct gl_program_parameter_list *list); - - -extern void -_mesa_write_shader_to_file(const struct gl_shader *shader); - -extern void -_mesa_append_uniforms_to_file(const struct gl_shader *shader, - const struct gl_program *prog); - - -#endif /* PROG_PRINT_H */ diff --git a/mesalib/src/mesa/shader/prog_statevars.c b/mesalib/src/mesa/shader/prog_statevars.c deleted file mode 100644 index ead3ece95..000000000 --- a/mesalib/src/mesa/shader/prog_statevars.c +++ /dev/null @@ -1,1187 +0,0 @@ -/* - * Mesa 3-D graphics library - * Version: 7.1 - * - * 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 "main/glheader.h" -#include "main/context.h" -#include "main/imports.h" -#include "main/macros.h" -#include "main/mtypes.h" -#include "prog_statevars.h" -#include "prog_parameter.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].SpotDirection); - value[3] = ctx->Light.Light[ln]._CosCutoff; - return; - case STATE_SPOT_CUTOFF: - value[0] = ctx->Light.Light[ln].SpotCutoff; - return; - case STATE_HALF_VECTOR: - { - static const GLfloat eye_z[] = {0, 0, 1}; - GLfloat p[3]; - /* Compute infinite half angle vector: - * halfVector = normalize(normalize(lightPos) + (0, 0, 1)) - * light.EyePosition.w should be 0 for infinite lights. - */ - COPY_3V(p, ctx->Light.Light[ln].EyePosition); - NORMALIZE_3FV(p); - ADD_3V(value, p, eye_z); - NORMALIZE_3FV(value); - value[3] = 1.0; - } - 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_AMBIENT+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_SPECULAR+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].GenS.EyePlane); - return; - case STATE_TEXGEN_EYE_T: - COPY_4V(value, ctx->Texture.Unit[unit].GenT.EyePlane); - return; - case STATE_TEXGEN_EYE_R: - COPY_4V(value, ctx->Texture.Unit[unit].GenR.EyePlane); - return; - case STATE_TEXGEN_EYE_Q: - COPY_4V(value, ctx->Texture.Unit[unit].GenQ.EyePlane); - return; - case STATE_TEXGEN_OBJECT_S: - COPY_4V(value, ctx->Texture.Unit[unit].GenS.ObjectPlane); - return; - case STATE_TEXGEN_OBJECT_T: - COPY_4V(value, ctx->Texture.Unit[unit].GenT.ObjectPlane); - return; - case STATE_TEXGEN_OBJECT_R: - COPY_4V(value, ctx->Texture.Unit[unit].GenR.ObjectPlane); - return; - case STATE_TEXGEN_OBJECT_Q: - COPY_4V(value, ctx->Texture.Unit[unit].GenQ.ObjectPlane); - 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] = (ctx->Fog.End == ctx->Fog.Start) - ? 1.0f : (GLfloat)(1.0 / (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: - case STATE_COLOR_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) { - ASSERT(index < Elements(ctx->TextureMatrixStack)); - matrix = ctx->TextureMatrixStack[index].Top; - } - else if (mat == STATE_PROGRAM_MATRIX) { - ASSERT(index < Elements(ctx->ProgramMatrixStack)); - matrix = ctx->ProgramMatrixStack[index].Top; - } - else if (mat == STATE_COLOR_MATRIX) { - matrix = ctx->ColorMatrixStack.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] = 1.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]); - return; - case STATE_LOCAL: - COPY_4V(value, ctx->FragmentProgram.Current->Base.LocalParams[idx]); - return; - 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]); - return; - case STATE_LOCAL: - COPY_4V(value, ctx->VertexProgram.Current->Base.LocalParams[idx]); - return; - 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_CURRENT_ATTRIB: - { - const GLuint idx = (GLuint) state[2]; - COPY_4V(value, ctx->Current.Attrib[idx]); - } - return; - - case STATE_NORMAL_SCALE: - ASSIGN_4V(value, - ctx->_ModelViewInvScale, - ctx->_ModelViewInvScale, - ctx->_ModelViewInvScale, - 1); - return; - - case STATE_TEXRECT_SCALE: - /* Value = { 1/texWidth, 1/texHeight, 0, 1 }. - * Used to convert unnormalized texcoords to normalized texcoords. - */ - { - 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, - (GLfloat) (1.0 / texImage->Width), - (GLfloat) (1.0 / texImage->Height), - 0.0f, 1.0f); - } - } - 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] = (ctx->Fog.End == ctx->Fog.Start) - ? 1.0f : (GLfloat)(-1.0F / (ctx->Fog.End - ctx->Fog.Start)); - value[1] = ctx->Fog.End * -value[0]; - value[2] = (GLfloat)(ctx->Fog.Density * ONE_DIV_LN2); - value[3] = (GLfloat)(ctx->Fog.Density * ONE_DIV_SQRT_LN2); - return; - - case STATE_POINT_SIZE_CLAMPED: - { - /* this includes implementation dependent limits, to avoid - * another potentially necessary clamp. - * Note: for sprites, point smooth (point AA) is ignored - * and we'll clamp to MinPointSizeAA and MaxPointSize, because we - * expect drivers will want to say their minimum for AA size is 0.0 - * but for non-AA it's 1.0 (because normal points with size below 1.0 - * need to get rounded up to 1.0, hence never disappear). GL does - * not specify max clamp size for sprites, other than it needs to be - * at least as large as max AA size, hence use non-AA size there. - */ - GLfloat minImplSize; - GLfloat maxImplSize; - if (ctx->Point.PointSprite) { - minImplSize = ctx->Const.MinPointSizeAA; - maxImplSize = ctx->Const.MaxPointSize; - } - else if (ctx->Point.SmoothFlag || ctx->Multisample._Enabled) { - minImplSize = ctx->Const.MinPointSizeAA; - maxImplSize = ctx->Const.MaxPointSizeAA; - } - else { - minImplSize = ctx->Const.MinPointSize; - maxImplSize = ctx->Const.MaxPointSize; - } - value[0] = ctx->Point.Size; - value[1] = ctx->Point.MinSize >= minImplSize ? ctx->Point.MinSize : minImplSize; - value[2] = ctx->Point.MaxSize <= maxImplSize ? ctx->Point.MaxSize : maxImplSize; - value[3] = ctx->Point.Threshold; - } - return; - case STATE_POINT_SIZE_IMPL_CLAMP: - { - /* for implementation clamp only in vs */ - GLfloat minImplSize; - GLfloat maxImplSize; - if (ctx->Point.PointSprite) { - minImplSize = ctx->Const.MinPointSizeAA; - maxImplSize = ctx->Const.MaxPointSize; - } - else if (ctx->Point.SmoothFlag || ctx->Multisample._Enabled) { - minImplSize = ctx->Const.MinPointSizeAA; - maxImplSize = ctx->Const.MaxPointSizeAA; - } - else { - minImplSize = ctx->Const.MinPointSize; - maxImplSize = ctx->Const.MaxPointSize; - } - value[0] = ctx->Point.Size; - value[1] = minImplSize; - value[2] = maxImplSize; - value[3] = ctx->Point.Threshold; - } - return; - case STATE_LIGHT_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]._NormSpotDirection); - value[3] = ctx->Light.Light[ln]._CosCutoff; - } - return; - - case STATE_LIGHT_POSITION: - { - const GLuint ln = (GLuint) state[2]; - COPY_4V(value, ctx->Light.Light[ln]._Position); - } - return; - - case STATE_LIGHT_POSITION_NORMALIZED: - { - const GLuint ln = (GLuint) state[2]; - COPY_4V(value, ctx->Light.Light[ln]._Position); - NORMALIZE_3FV( value ); - } - return; - - case STATE_LIGHT_HALF_VECTOR: - { - const GLuint ln = (GLuint) state[2]; - GLfloat p[3]; - /* Compute infinite half angle vector: - * halfVector = normalize(normalize(lightPos) + (0, 0, 1)) - * light.EyePosition.w should be 0 for infinite lights. - */ - COPY_3V(p, ctx->Light.Light[ln]._Position); - NORMALIZE_3FV(p); - ADD_3V(value, p, ctx->_EyeZDir); - NORMALIZE_3FV(value); - value[3] = 1.0; - } - return; - - case STATE_PT_SCALE: - value[0] = ctx->Pixel.RedScale; - value[1] = ctx->Pixel.GreenScale; - value[2] = ctx->Pixel.BlueScale; - value[3] = ctx->Pixel.AlphaScale; - return; - - case STATE_PT_BIAS: - value[0] = ctx->Pixel.RedBias; - value[1] = ctx->Pixel.GreenBias; - value[2] = ctx->Pixel.BlueBias; - value[3] = ctx->Pixel.AlphaBias; - return; - - case STATE_PCM_SCALE: - COPY_4V(value, ctx->Pixel.PostColorMatrixScale); - return; - - case STATE_PCM_BIAS: - COPY_4V(value, ctx->Pixel.PostColorMatrixBias); - return; - - case STATE_SHADOW_AMBIENT: - { - const int unit = (int) state[2]; - const struct gl_texture_object *texObj - = ctx->Texture.Unit[unit]._Current; - if (texObj) { - value[0] = - value[1] = - value[2] = - value[3] = texObj->CompareFailValue; - } - } - return; - - case STATE_FB_SIZE: - value[0] = (GLfloat) (ctx->DrawBuffer->Width - 1); - value[1] = (GLfloat) (ctx->DrawBuffer->Height - 1); - value[2] = 0.0F; - value[3] = 0.0F; - return; - - case STATE_ROT_MATRIX_0: - { - const int unit = (int) state[2]; - GLfloat *rotMat22 = ctx->Texture.Unit[unit].RotMatrix; - value[0] = rotMat22[0]; - value[1] = rotMat22[2]; - value[2] = 0.0; - value[3] = 0.0; - } - return; - - case STATE_ROT_MATRIX_1: - { - const int unit = (int) state[2]; - GLfloat *rotMat22 = ctx->Texture.Unit[unit].RotMatrix; - value[0] = rotMat22[1]; - value[1] = rotMat22[3]; - value[2] = 0.0; - value[3] = 0.0; - } - return; - - /* XXX: make sure new tokens added here are also handled in the - * _mesa_program_state_flags() switch, below. - */ - default: - /* Unknown state indexes are silently ignored here. - * Drivers may do something special. - */ - 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_COLOR_MATRIX: - return _NEW_COLOR_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_CURRENT_ATTRIB: - return _NEW_CURRENT_ATTRIB; - - case STATE_NORMAL_SCALE: - return _NEW_MODELVIEW; - - case STATE_TEXRECT_SCALE: - case STATE_SHADOW_AMBIENT: - case STATE_ROT_MATRIX_0: - case STATE_ROT_MATRIX_1: - return _NEW_TEXTURE; - case STATE_FOG_PARAMS_OPTIMIZED: - return _NEW_FOG; - case STATE_POINT_SIZE_CLAMPED: - case STATE_POINT_SIZE_IMPL_CLAMP: - return _NEW_POINT | _NEW_MULTISAMPLE; - case STATE_LIGHT_SPOT_DIR_NORMALIZED: - case STATE_LIGHT_POSITION: - case STATE_LIGHT_POSITION_NORMALIZED: - case STATE_LIGHT_HALF_VECTOR: - return _NEW_LIGHT; - - case STATE_PT_SCALE: - case STATE_PT_BIAS: - case STATE_PCM_SCALE: - case STATE_PCM_BIAS: - return _NEW_PIXEL; - - case STATE_FB_SIZE: - return _NEW_BUFFERS; - - 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; -} - - -/** - * Convert token 'k' to a string, append it onto 'dst' string. - */ -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_COLOR_MATRIX: - append(dst, "matrix.color"); - 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; - /* BEGIN internal state vars */ - case STATE_INTERNAL: - append(dst, ".internal."); - break; - case STATE_CURRENT_ATTRIB: - append(dst, "current"); - break; - case STATE_NORMAL_SCALE: - append(dst, "normalScale"); - break; - case STATE_TEXRECT_SCALE: - append(dst, "texrectScale"); - break; - case STATE_FOG_PARAMS_OPTIMIZED: - append(dst, "fogParamsOptimized"); - break; - case STATE_POINT_SIZE_CLAMPED: - append(dst, "pointSizeClamped"); - break; - case STATE_POINT_SIZE_IMPL_CLAMP: - append(dst, "pointSizeImplClamp"); - break; - case STATE_LIGHT_SPOT_DIR_NORMALIZED: - append(dst, "lightSpotDirNormalized"); - break; - case STATE_LIGHT_POSITION: - append(dst, "lightPosition"); - break; - case STATE_LIGHT_POSITION_NORMALIZED: - append(dst, "light.position.normalized"); - break; - case STATE_LIGHT_HALF_VECTOR: - append(dst, "lightHalfVector"); - break; - case STATE_PT_SCALE: - append(dst, "PTscale"); - break; - case STATE_PT_BIAS: - append(dst, "PTbias"); - break; - case STATE_PCM_SCALE: - append(dst, "PCMscale"); - break; - case STATE_PCM_BIAS: - append(dst, "PCMbias"); - break; - case STATE_SHADOW_AMBIENT: - append(dst, "CompareFailValue"); - break; - case STATE_FB_SIZE: - append(dst, "FbSize"); - break; - case STATE_ROT_MATRIX_0: - append(dst, "rotMatrixRow0"); - break; - case STATE_ROT_MATRIX_1: - append(dst, "rotMatrixRow1"); - break; - default: - /* probably STATE_INTERNAL_DRIVER+i (driver private state) */ - append(dst, "driverState"); - } -} - -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]; - sprintf(s, "[%d]", index); - append(dst, s); -} - -/** - * Make a string from the given state vector. - * For example, return "state.matrix.texture[2].inverse". - * Use free() to deallocate the string. - */ -char * -_mesa_program_state_string(const gl_state_index state[STATE_LENGTH]) -{ - char str[1000] = ""; - char tmp[30]; - - append(str, "state."); - append_token(str, state[0]); - - switch (state[0]) { - case STATE_MATERIAL: - append_face(str, state[1]); - append_token(str, state[2]); - break; - case STATE_LIGHT: - append_index(str, state[1]); /* light number [i]. */ - append_token(str, 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, state[3]); - break; - case STATE_TEXGEN: - append_index(str, state[1]); /* tex unit [i] */ - append_token(str, 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: - case STATE_COLOR_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 = 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]; - if (index || - mat == STATE_TEXTURE_MATRIX || - mat == STATE_PROGRAM_MATRIX) - append_index(str, index); - if (modifier) - append_token(str, modifier); - if (firstRow == lastRow) - sprintf(tmp, ".row[%d]", firstRow); - else - 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, state[1]); - append_index(str, state[2]); - break; - case STATE_INTERNAL: - append_token(str, state[1]); - if (state[1] == STATE_CURRENT_ATTRIB) - append_index(str, state[2]); - 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; - - /*assert(ctx->Driver.NeedFlush == 0);*/ - - 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]); - } - } -} - - -/** - * 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) { - GLuint unit = MIN2(ctx->Texture.CurrentUnit, - Elements(ctx->TextureMatrixStack) - 1); - mat = ctx->TextureMatrixStack[unit].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 < Elements(ctx->ProgramMatrixStack)); - 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); - } - } -} diff --git a/mesalib/src/mesa/shader/prog_statevars.h b/mesalib/src/mesa/shader/prog_statevars.h deleted file mode 100644 index 1753471ff..000000000 --- a/mesalib/src/mesa/shader/prog_statevars.h +++ /dev/null @@ -1,147 +0,0 @@ -/* - * Mesa 3-D graphics library - * Version: 7.1 - * - * 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_STATEVARS_H -#define PROG_STATEVARS_H - -#include "main/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_COLOR_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, /**< xyzw = position */ - STATE_ATTENUATION, /**< xyz = attenuation, w = spot exponent */ - STATE_SPOT_DIRECTION, /**< xyz = direction, w = cos(cutoff) */ - STATE_SPOT_CUTOFF, /**< x = cutoff, yzw = undefined */ - - 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_CURRENT_ATTRIB, /* ctx->Current vertex attrib value */ - STATE_NORMAL_SCALE, - STATE_TEXRECT_SCALE, - STATE_FOG_PARAMS_OPTIMIZED, /* for faster fog calc */ - STATE_POINT_SIZE_CLAMPED, /* includes implementation dependent size clamp */ - STATE_POINT_SIZE_IMPL_CLAMP, /* for implementation clamp only in vs */ - STATE_LIGHT_SPOT_DIR_NORMALIZED, /* pre-normalized spot dir */ - STATE_LIGHT_POSITION, /* object vs eye space */ - STATE_LIGHT_POSITION_NORMALIZED, /* object vs eye space */ - STATE_LIGHT_HALF_VECTOR, /* object vs eye space */ - STATE_PT_SCALE, /**< Pixel transfer RGBA scale */ - STATE_PT_BIAS, /**< Pixel transfer RGBA bias */ - STATE_PCM_SCALE, /**< Post color matrix RGBA scale */ - STATE_PCM_BIAS, /**< Post color matrix RGBA bias */ - STATE_SHADOW_AMBIENT, /**< ARB_shadow_ambient fail value; token[2] is texture unit index */ - STATE_FB_SIZE, /**< (width-1, height-1, 0, 0) */ - STATE_ROT_MATRIX_0, /**< ATI_envmap_bumpmap, rot matrix row 0 */ - STATE_ROT_MATRIX_1, /**< ATI_envmap_bumpmap, rot matrix row 1 */ - 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 char * -_mesa_program_state_string(const gl_state_index state[STATE_LENGTH]); - - -extern void -_mesa_load_tracked_matrices(GLcontext *ctx); - - -#endif /* PROG_STATEVARS_H */ diff --git a/mesalib/src/mesa/shader/prog_uniform.c b/mesalib/src/mesa/shader/prog_uniform.c deleted file mode 100644 index c408a8492..000000000 --- a/mesalib/src/mesa/shader/prog_uniform.c +++ /dev/null @@ -1,165 +0,0 @@ -/* - * Mesa 3-D graphics library - * Version: 7.1 - * - * Copyright (C) 1999-2008 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_uniform.c - * Shader uniform functions. - * \author Brian Paul - */ - -#include "main/imports.h" -#include "main/mtypes.h" -#include "prog_uniform.h" - - -struct gl_uniform_list * -_mesa_new_uniform_list(void) -{ - return CALLOC_STRUCT(gl_uniform_list); -} - - -void -_mesa_free_uniform_list(struct gl_uniform_list *list) -{ - GLuint i; - for (i = 0; i < list->NumUniforms; i++) { - free((void *) list->Uniforms[i].Name); - } - free(list->Uniforms); - free(list); -} - - -struct gl_uniform * -_mesa_append_uniform(struct gl_uniform_list *list, - const char *name, GLenum target, GLuint progPos) -{ - const GLuint oldNum = list->NumUniforms; - struct gl_uniform *uniform; - GLint index; - - assert(target == GL_VERTEX_PROGRAM_ARB || - target == GL_FRAGMENT_PROGRAM_ARB); - - index = _mesa_lookup_uniform(list, name); - if (index < 0) { - /* not found - append to list */ - - if (oldNum + 1 > list->Size) { - /* Need to grow the list array (alloc some extra) */ - list->Size += 4; - - /* realloc arrays */ - list->Uniforms = (struct gl_uniform *) - _mesa_realloc(list->Uniforms, - oldNum * sizeof(struct gl_uniform), - list->Size * sizeof(struct gl_uniform)); - } - - if (!list->Uniforms) { - /* out of memory */ - list->NumUniforms = 0; - list->Size = 0; - return GL_FALSE; - } - - uniform = list->Uniforms + oldNum; - - uniform->Name = _mesa_strdup(name); - uniform->VertPos = -1; - uniform->FragPos = -1; - uniform->Initialized = GL_FALSE; - - list->NumUniforms++; - } - else { - /* found */ - uniform = list->Uniforms + index; - } - - /* update position for the vertex or fragment program */ - if (target == GL_VERTEX_PROGRAM_ARB) { - if (uniform->VertPos != -1) { - /* this uniform is already in the list - that shouldn't happen */ - return GL_FALSE; - } - uniform->VertPos = progPos; - } - else { - if (uniform->FragPos != -1) { - /* this uniform is already in the list - that shouldn't happen */ - return GL_FALSE; - } - uniform->FragPos = progPos; - } - - return uniform; -} - - -/** - * Return the location/index of the named uniform in the uniform list, - * or -1 if not found. - */ -GLint -_mesa_lookup_uniform(const struct gl_uniform_list *list, const char *name) -{ - GLuint i; - for (i = 0; list && i < list->NumUniforms; i++) { - if (!strcmp(list->Uniforms[i].Name, name)) { - return i; - } - } - return -1; -} - - -GLint -_mesa_longest_uniform_name(const struct gl_uniform_list *list) -{ - GLint max = 0; - GLuint i; - for (i = 0; list && i < list->NumUniforms; i++) { - GLint len = (GLint) strlen(list->Uniforms[i].Name); - if (len > max) - max = len; - } - return max; -} - - -void -_mesa_print_uniforms(const struct gl_uniform_list *list) -{ - GLuint i; - printf("Uniform list %p:\n", (void *) list); - for (i = 0; i < list->NumUniforms; i++) { - printf("%d: %s %d %d\n", - i, - list->Uniforms[i].Name, - list->Uniforms[i].VertPos, - list->Uniforms[i].FragPos); - } -} diff --git a/mesalib/src/mesa/shader/prog_uniform.h b/mesalib/src/mesa/shader/prog_uniform.h deleted file mode 100644 index 22a2bfd97..000000000 --- a/mesalib/src/mesa/shader/prog_uniform.h +++ /dev/null @@ -1,92 +0,0 @@ -/* - * Mesa 3-D graphics library - * Version: 7.1 - * - * Copyright (C) 1999-2008 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_uniform.c - * Shader uniform functions. - * \author Brian Paul - */ - -#ifndef PROG_UNIFORM_H -#define PROG_UNIFORM_H - -#include "main/mtypes.h" -#include "prog_statevars.h" - - -/** - * Shader program uniform variable. - * The glGetUniformLocation() and glUniform() commands will use this - * information. - * Note that a uniform such as "binormal" might be used in both the - * vertex shader and the fragment shader. When glUniform() is called to - * set the uniform's value, it must be updated in both the vertex and - * fragment shaders. The uniform may be in different locations in the - * two shaders so we keep track of that here. - */ -struct gl_uniform -{ - const char *Name; /**< Null-terminated string */ - GLint VertPos; - GLint FragPos; - GLboolean Initialized; /**< For debug. Has this uniform been set? */ -#if 0 - GLenum DataType; /**< GL_FLOAT, GL_FLOAT_VEC2, etc */ - GLuint Size; /**< Number of components (1..4) */ -#endif -}; - - -/** - * List of gl_uniforms - */ -struct gl_uniform_list -{ - GLuint Size; /**< allocated size of Uniforms array */ - GLuint NumUniforms; /**< number of uniforms in the array */ - struct gl_uniform *Uniforms; /**< Array [Size] */ -}; - - -extern struct gl_uniform_list * -_mesa_new_uniform_list(void); - -extern void -_mesa_free_uniform_list(struct gl_uniform_list *list); - -extern struct gl_uniform * -_mesa_append_uniform(struct gl_uniform_list *list, - const char *name, GLenum target, GLuint progPos); - -extern GLint -_mesa_lookup_uniform(const struct gl_uniform_list *list, const char *name); - -extern GLint -_mesa_longest_uniform_name(const struct gl_uniform_list *list); - -extern void -_mesa_print_uniforms(const struct gl_uniform_list *list); - - -#endif /* PROG_UNIFORM_H */ diff --git a/mesalib/src/mesa/shader/program.c b/mesalib/src/mesa/shader/program.c deleted file mode 100644 index f77a77375..000000000 --- a/mesalib/src/mesa/shader/program.c +++ /dev/null @@ -1,912 +0,0 @@ -/* - * 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 program.c - * Vertex and fragment program support functions. - * \author Brian Paul - */ - - -#include "main/glheader.h" -#include "main/context.h" -#include "main/hash.h" -#include "program.h" -#include "prog_cache.h" -#include "prog_parameter.h" -#include "prog_instruction.h" - - -/** - * A pointer to this dummy program is put into the hash table when - * glGenPrograms is called. - */ -struct gl_program _mesa_DummyProgram; - - -/** - * Init context's vertex/fragment program state - */ -void -_mesa_init_program(GLcontext *ctx) -{ - GLuint i; - - /* - * If this assertion fails, we need to increase the field - * size for register indexes. - */ - ASSERT(ctx->Const.VertexProgram.MaxUniformComponents / 4 - <= (1 << INST_INDEX_BITS)); - ASSERT(ctx->Const.FragmentProgram.MaxUniformComponents / 4 - <= (1 << INST_INDEX_BITS)); - - /* If this fails, increase prog_instruction::TexSrcUnit size */ - ASSERT(MAX_TEXTURE_UNITS < (1 << 5)); - - /* If this fails, increase prog_instruction::TexSrcTarget size */ - ASSERT(NUM_TEXTURE_TARGETS < (1 << 3)); - - ctx->Program.ErrorPos = -1; - ctx->Program.ErrorString = _mesa_strdup(""); - -#if FEATURE_NV_vertex_program || FEATURE_ARB_vertex_program - ctx->VertexProgram.Enabled = GL_FALSE; -#if FEATURE_es2_glsl - ctx->VertexProgram.PointSizeEnabled = GL_TRUE; -#else - ctx->VertexProgram.PointSizeEnabled = GL_FALSE; -#endif - ctx->VertexProgram.TwoSideEnabled = GL_FALSE; - _mesa_reference_vertprog(ctx, &ctx->VertexProgram.Current, - ctx->Shared->DefaultVertexProgram); - assert(ctx->VertexProgram.Current); - for (i = 0; i < MAX_NV_VERTEX_PROGRAM_PARAMS / 4; i++) { - ctx->VertexProgram.TrackMatrix[i] = GL_NONE; - ctx->VertexProgram.TrackMatrixTransform[i] = GL_IDENTITY_NV; - } - ctx->VertexProgram.Cache = _mesa_new_program_cache(); -#endif - -#if FEATURE_NV_fragment_program || FEATURE_ARB_fragment_program - ctx->FragmentProgram.Enabled = GL_FALSE; - _mesa_reference_fragprog(ctx, &ctx->FragmentProgram.Current, - ctx->Shared->DefaultFragmentProgram); - assert(ctx->FragmentProgram.Current); - ctx->FragmentProgram.Cache = _mesa_new_program_cache(); -#endif - - - /* XXX probably move this stuff */ -#if FEATURE_ATI_fragment_shader - ctx->ATIFragmentShader.Enabled = GL_FALSE; - ctx->ATIFragmentShader.Current = ctx->Shared->DefaultFragmentShader; - assert(ctx->ATIFragmentShader.Current); - ctx->ATIFragmentShader.Current->RefCount++; -#endif -} - - -/** - * Free a context's vertex/fragment program state - */ -void -_mesa_free_program_data(GLcontext *ctx) -{ -#if FEATURE_NV_vertex_program || FEATURE_ARB_vertex_program - _mesa_reference_vertprog(ctx, &ctx->VertexProgram.Current, NULL); - _mesa_delete_program_cache(ctx, ctx->VertexProgram.Cache); -#endif -#if FEATURE_NV_fragment_program || FEATURE_ARB_fragment_program - _mesa_reference_fragprog(ctx, &ctx->FragmentProgram.Current, NULL); - _mesa_delete_program_cache(ctx, ctx->FragmentProgram.Cache); -#endif - /* XXX probably move this stuff */ -#if FEATURE_ATI_fragment_shader - if (ctx->ATIFragmentShader.Current) { - ctx->ATIFragmentShader.Current->RefCount--; - if (ctx->ATIFragmentShader.Current->RefCount <= 0) { - free(ctx->ATIFragmentShader.Current); - } - } -#endif - free((void *) ctx->Program.ErrorString); -} - - -/** - * Update the default program objects in the given context to reference those - * specified in the shared state and release those referencing the old - * shared state. - */ -void -_mesa_update_default_objects_program(GLcontext *ctx) -{ -#if FEATURE_NV_vertex_program || FEATURE_ARB_vertex_program - _mesa_reference_vertprog(ctx, &ctx->VertexProgram.Current, - (struct gl_vertex_program *) - ctx->Shared->DefaultVertexProgram); - assert(ctx->VertexProgram.Current); -#endif - -#if FEATURE_NV_fragment_program || FEATURE_ARB_fragment_program - _mesa_reference_fragprog(ctx, &ctx->FragmentProgram.Current, - (struct gl_fragment_program *) - ctx->Shared->DefaultFragmentProgram); - assert(ctx->FragmentProgram.Current); -#endif - - /* XXX probably move this stuff */ -#if FEATURE_ATI_fragment_shader - if (ctx->ATIFragmentShader.Current) { - ctx->ATIFragmentShader.Current->RefCount--; - if (ctx->ATIFragmentShader.Current->RefCount <= 0) { - free(ctx->ATIFragmentShader.Current); - } - } - ctx->ATIFragmentShader.Current = (struct ati_fragment_shader *) ctx->Shared->DefaultFragmentShader; - assert(ctx->ATIFragmentShader.Current); - ctx->ATIFragmentShader.Current->RefCount++; -#endif -} - - -/** - * Set the vertex/fragment program error state (position and error string). - * This is generally called from within the parsers. - */ -void -_mesa_set_program_error(GLcontext *ctx, GLint pos, const char *string) -{ - ctx->Program.ErrorPos = pos; - free((void *) ctx->Program.ErrorString); - if (!string) - string = ""; - ctx->Program.ErrorString = _mesa_strdup(string); -} - - -/** - * Find the line number and column for 'pos' within 'string'. - * Return a copy of the line which contains 'pos'. Free the line with - * free(). - * \param string the program string - * \param pos the position within the string - * \param line returns the line number corresponding to 'pos'. - * \param col returns the column number corresponding to 'pos'. - * \return copy of the line containing 'pos'. - */ -const GLubyte * -_mesa_find_line_column(const GLubyte *string, const GLubyte *pos, - GLint *line, GLint *col) -{ - const GLubyte *lineStart = string; - const GLubyte *p = string; - GLubyte *s; - int len; - - *line = 1; - - while (p != pos) { - if (*p == (GLubyte) '\n') { - (*line)++; - lineStart = p + 1; - } - p++; - } - - *col = (pos - lineStart) + 1; - - /* return copy of this line */ - while (*p != 0 && *p != '\n') - p++; - len = p - lineStart; - s = (GLubyte *) malloc(len + 1); - memcpy(s, lineStart, len); - s[len] = 0; - - return s; -} - - -/** - * Initialize a new vertex/fragment program object. - */ -static struct gl_program * -_mesa_init_program_struct( GLcontext *ctx, struct gl_program *prog, - GLenum target, GLuint id) -{ - (void) ctx; - if (prog) { - GLuint i; - memset(prog, 0, sizeof(*prog)); - prog->Id = id; - prog->Target = target; - prog->Resident = GL_TRUE; - prog->RefCount = 1; - prog->Format = GL_PROGRAM_FORMAT_ASCII_ARB; - - /* default mapping from samplers to texture units */ - for (i = 0; i < MAX_SAMPLERS; i++) - prog->SamplerUnits[i] = i; - } - - return prog; -} - - -/** - * Initialize a new fragment program object. - */ -struct gl_program * -_mesa_init_fragment_program( GLcontext *ctx, struct gl_fragment_program *prog, - GLenum target, GLuint id) -{ - if (prog) - return _mesa_init_program_struct( ctx, &prog->Base, target, id ); - else - return NULL; -} - - -/** - * Initialize a new vertex program object. - */ -struct gl_program * -_mesa_init_vertex_program( GLcontext *ctx, struct gl_vertex_program *prog, - GLenum target, GLuint id) -{ - if (prog) - return _mesa_init_program_struct( ctx, &prog->Base, target, id ); - else - return NULL; -} - - -/** - * Allocate and initialize a new fragment/vertex program object but - * don't put it into the program hash table. Called via - * ctx->Driver.NewProgram. May be overridden (ie. replaced) by a - * device driver function to implement OO deriviation with additional - * types not understood by this function. - * - * \param ctx context - * \param id program id/number - * \param target program target/type - * \return pointer to new program object - */ -struct gl_program * -_mesa_new_program(GLcontext *ctx, GLenum target, GLuint id) -{ - struct gl_program *prog; - switch (target) { - case GL_VERTEX_PROGRAM_ARB: /* == GL_VERTEX_PROGRAM_NV */ - case GL_VERTEX_STATE_PROGRAM_NV: - prog = _mesa_init_vertex_program(ctx, CALLOC_STRUCT(gl_vertex_program), - target, id ); - break; - case GL_FRAGMENT_PROGRAM_NV: - case GL_FRAGMENT_PROGRAM_ARB: - prog =_mesa_init_fragment_program(ctx, - CALLOC_STRUCT(gl_fragment_program), - target, id ); - break; - default: - _mesa_problem(ctx, "bad target in _mesa_new_program"); - prog = NULL; - } - return prog; -} - - -/** - * Delete a program and remove it from the hash table, ignoring the - * reference count. - * Called via ctx->Driver.DeleteProgram. May be wrapped (OO deriviation) - * by a device driver function. - */ -void -_mesa_delete_program(GLcontext *ctx, struct gl_program *prog) -{ - (void) ctx; - ASSERT(prog); - ASSERT(prog->RefCount==0); - - if (prog == &_mesa_DummyProgram) - return; - - if (prog->String) - free(prog->String); - - _mesa_free_instructions(prog->Instructions, prog->NumInstructions); - - 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); - } - - free(prog); -} - - -/** - * Return the gl_program object for a given ID. - * Basically just a wrapper for _mesa_HashLookup() to avoid a lot of - * casts elsewhere. - */ -struct gl_program * -_mesa_lookup_program(GLcontext *ctx, GLuint id) -{ - if (id) - return (struct gl_program *) _mesa_HashLookup(ctx->Shared->Programs, id); - else - return NULL; -} - - -/** - * Reference counting for vertex/fragment programs - */ -void -_mesa_reference_program(GLcontext *ctx, - struct gl_program **ptr, - struct gl_program *prog) -{ - assert(ptr); - if (*ptr && prog) { - /* sanity check */ - if ((*ptr)->Target == GL_VERTEX_PROGRAM_ARB) - ASSERT(prog->Target == GL_VERTEX_PROGRAM_ARB); - else if ((*ptr)->Target == GL_FRAGMENT_PROGRAM_ARB) - ASSERT(prog->Target == GL_FRAGMENT_PROGRAM_ARB || - prog->Target == GL_FRAGMENT_PROGRAM_NV); - } - if (*ptr == prog) { - return; /* no change */ - } - if (*ptr) { - GLboolean deleteFlag; - - /*_glthread_LOCK_MUTEX((*ptr)->Mutex);*/ -#if 0 - printf("Program %p ID=%u Target=%s Refcount-- to %d\n", - *ptr, (*ptr)->Id, - ((*ptr)->Target == GL_VERTEX_PROGRAM_ARB ? "VP" : "FP"), - (*ptr)->RefCount - 1); -#endif - ASSERT((*ptr)->RefCount > 0); - (*ptr)->RefCount--; - - deleteFlag = ((*ptr)->RefCount == 0); - /*_glthread_UNLOCK_MUTEX((*ptr)->Mutex);*/ - - if (deleteFlag) { - ASSERT(ctx); - ctx->Driver.DeleteProgram(ctx, *ptr); - } - - *ptr = NULL; - } - - assert(!*ptr); - if (prog) { - /*_glthread_LOCK_MUTEX(prog->Mutex);*/ - prog->RefCount++; -#if 0 - printf("Program %p ID=%u Target=%s Refcount++ to %d\n", - prog, prog->Id, - (prog->Target == GL_VERTEX_PROGRAM_ARB ? "VP" : "FP"), - prog->RefCount); -#endif - /*_glthread_UNLOCK_MUTEX(prog->Mutex);*/ - } - - *ptr = prog; -} - - -/** - * Return a copy of a program. - * XXX Problem here if the program object is actually OO-derivation - * made by a device driver. - */ -struct gl_program * -_mesa_clone_program(GLcontext *ctx, const struct gl_program *prog) -{ - struct gl_program *clone; - - clone = ctx->Driver.NewProgram(ctx, prog->Target, prog->Id); - if (!clone) - return NULL; - - assert(clone->Target == prog->Target); - assert(clone->RefCount == 1); - - clone->String = (GLubyte *) _mesa_strdup((char *) prog->String); - clone->Format = prog->Format; - clone->Instructions = _mesa_alloc_instructions(prog->NumInstructions); - if (!clone->Instructions) { - _mesa_reference_program(ctx, &clone, NULL); - return NULL; - } - _mesa_copy_instructions(clone->Instructions, prog->Instructions, - prog->NumInstructions); - clone->InputsRead = prog->InputsRead; - clone->OutputsWritten = prog->OutputsWritten; - clone->SamplersUsed = prog->SamplersUsed; - clone->ShadowSamplers = prog->ShadowSamplers; - 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: - { - 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; - vpc->IsNVProgram = vp->IsNVProgram; - } - break; - case GL_FRAGMENT_PROGRAM_ARB: - { - 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; - fpc->OriginUpperLeft = fp->OriginUpperLeft; - fpc->PixelCenterInteger = fp->PixelCenterInteger; - } - break; - default: - _mesa_problem(NULL, "Unexpected target in _mesa_clone_program"); - } - - return clone; -} - - -/** - * Insert 'count' NOP instructions at 'start' in the given program. - * Adjust branch targets accordingly. - */ -GLboolean -_mesa_insert_instructions(struct gl_program *prog, GLuint start, GLuint count) -{ - const GLuint origLen = prog->NumInstructions; - const GLuint newLen = origLen + count; - struct prog_instruction *newInst; - GLuint i; - - /* adjust branches */ - for (i = 0; i < prog->NumInstructions; i++) { - struct prog_instruction *inst = prog->Instructions + i; - if (inst->BranchTarget > 0) { - if ((GLuint)inst->BranchTarget >= start) { - inst->BranchTarget += count; - } - } - } - - /* Alloc storage for new instructions */ - newInst = _mesa_alloc_instructions(newLen); - if (!newInst) { - return GL_FALSE; - } - - /* Copy 'start' instructions into new instruction buffer */ - _mesa_copy_instructions(newInst, prog->Instructions, start); - - /* init the new instructions */ - _mesa_init_instructions(newInst + start, count); - - /* Copy the remaining/tail instructions to new inst buffer */ - _mesa_copy_instructions(newInst + start + count, - prog->Instructions + start, - origLen - start); - - /* free old instructions */ - _mesa_free_instructions(prog->Instructions, origLen); - - /* install new instructions */ - prog->Instructions = newInst; - prog->NumInstructions = newLen; - - return GL_TRUE; -} - -/** - * Delete 'count' instructions at 'start' in the given program. - * Adjust branch targets accordingly. - */ -GLboolean -_mesa_delete_instructions(struct gl_program *prog, GLuint start, GLuint count) -{ - const GLuint origLen = prog->NumInstructions; - const GLuint newLen = origLen - count; - struct prog_instruction *newInst; - GLuint i; - - /* adjust branches */ - for (i = 0; i < prog->NumInstructions; i++) { - struct prog_instruction *inst = prog->Instructions + i; - if (inst->BranchTarget > 0) { - if (inst->BranchTarget > (GLint) start) { - inst->BranchTarget -= count; - } - } - } - - /* Alloc storage for new instructions */ - newInst = _mesa_alloc_instructions(newLen); - if (!newInst) { - return GL_FALSE; - } - - /* Copy 'start' instructions into new instruction buffer */ - _mesa_copy_instructions(newInst, prog->Instructions, start); - - /* Copy the remaining/tail instructions to new inst buffer */ - _mesa_copy_instructions(newInst + start, - prog->Instructions + start + count, - newLen - start); - - /* free old instructions */ - _mesa_free_instructions(prog->Instructions, origLen); - - /* install new instructions */ - prog->Instructions = newInst; - prog->NumInstructions = newLen; - - return GL_TRUE; -} - - -/** - * Search instructions for registers that match (oldFile, oldIndex), - * replacing them with (newFile, newIndex). - */ -static void -replace_registers(struct prog_instruction *inst, GLuint numInst, - GLuint oldFile, GLuint oldIndex, - GLuint newFile, GLuint newIndex) -{ - GLuint i, j; - for (i = 0; i < numInst; i++) { - /* src regs */ - for (j = 0; j < _mesa_num_inst_src_regs(inst[i].Opcode); j++) { - if (inst[i].SrcReg[j].File == oldFile && - inst[i].SrcReg[j].Index == oldIndex) { - inst[i].SrcReg[j].File = newFile; - inst[i].SrcReg[j].Index = newIndex; - } - } - /* dst reg */ - if (inst[i].DstReg.File == oldFile && inst[i].DstReg.Index == oldIndex) { - inst[i].DstReg.File = newFile; - inst[i].DstReg.Index = newIndex; - } - } -} - - -/** - * Search instructions for references to program parameters. When found, - * increment the parameter index by 'offset'. - * Used when combining programs. - */ -static void -adjust_param_indexes(struct prog_instruction *inst, GLuint numInst, - GLuint offset) -{ - GLuint i, j; - for (i = 0; i < numInst; i++) { - for (j = 0; j < _mesa_num_inst_src_regs(inst[i].Opcode); j++) { - GLuint f = inst[i].SrcReg[j].File; - if (f == PROGRAM_CONSTANT || - f == PROGRAM_UNIFORM || - f == PROGRAM_STATE_VAR) { - inst[i].SrcReg[j].Index += offset; - } - } - } -} - - -/** - * Combine two programs into one. Fix instructions so the outputs of - * the first program go to the inputs of the second program. - */ -struct gl_program * -_mesa_combine_programs(GLcontext *ctx, - const struct gl_program *progA, - const struct gl_program *progB) -{ - struct prog_instruction *newInst; - struct gl_program *newProg; - const GLuint lenA = progA->NumInstructions - 1; /* omit END instr */ - const GLuint lenB = progB->NumInstructions; - const GLuint numParamsA = _mesa_num_parameters(progA->Parameters); - const GLuint newLength = lenA + lenB; - GLboolean usedTemps[MAX_PROGRAM_TEMPS]; - GLuint firstTemp = 0; - GLbitfield inputsB; - GLuint i; - - ASSERT(progA->Target == progB->Target); - - newInst = _mesa_alloc_instructions(newLength); - if (!newInst) - return GL_FALSE; - - _mesa_copy_instructions(newInst, progA->Instructions, lenA); - _mesa_copy_instructions(newInst + lenA, progB->Instructions, lenB); - - /* adjust branch / instruction addresses for B's instructions */ - for (i = 0; i < lenB; i++) { - newInst[lenA + i].BranchTarget += lenA; - } - - newProg = ctx->Driver.NewProgram(ctx, progA->Target, 0); - newProg->Instructions = newInst; - newProg->NumInstructions = newLength; - - /* find used temp regs (we may need new temps below) */ - _mesa_find_used_registers(newProg, PROGRAM_TEMPORARY, - usedTemps, MAX_PROGRAM_TEMPS); - - if (newProg->Target == GL_FRAGMENT_PROGRAM_ARB) { - struct gl_fragment_program *fprogA, *fprogB, *newFprog; - GLbitfield progB_inputsRead = progB->InputsRead; - GLint progB_colorFile, progB_colorIndex; - - fprogA = (struct gl_fragment_program *) progA; - fprogB = (struct gl_fragment_program *) progB; - newFprog = (struct gl_fragment_program *) newProg; - - newFprog->UsesKill = fprogA->UsesKill || fprogB->UsesKill; - - /* We'll do a search and replace for instances - * of progB_colorFile/progB_colorIndex below... - */ - progB_colorFile = PROGRAM_INPUT; - progB_colorIndex = FRAG_ATTRIB_COL0; - - /* - * The fragment program may get color from a state var rather than - * a fragment input (vertex output) if it's constant. - * See the texenvprogram.c code. - * So, search the program's parameter list now to see if the program - * gets color from a state var instead of a conventional fragment - * input register. - */ - for (i = 0; i < progB->Parameters->NumParameters; i++) { - struct gl_program_parameter *p = &progB->Parameters->Parameters[i]; - if (p->Type == PROGRAM_STATE_VAR && - p->StateIndexes[0] == STATE_INTERNAL && - p->StateIndexes[1] == STATE_CURRENT_ATTRIB && - p->StateIndexes[2] == VERT_ATTRIB_COLOR0) { - progB_inputsRead |= FRAG_BIT_COL0; - progB_colorFile = PROGRAM_STATE_VAR; - progB_colorIndex = i; - break; - } - } - - /* Connect color outputs of fprogA to color inputs of fprogB, via a - * new temporary register. - */ - if ((progA->OutputsWritten & (1 << FRAG_RESULT_COLOR)) && - (progB_inputsRead & FRAG_BIT_COL0)) { - GLint tempReg = _mesa_find_free_register(usedTemps, MAX_PROGRAM_TEMPS, - firstTemp); - if (tempReg < 0) { - _mesa_problem(ctx, "No free temp regs found in " - "_mesa_combine_programs(), using 31"); - tempReg = 31; - } - firstTemp = tempReg + 1; - - /* replace writes to result.color[0] with tempReg */ - replace_registers(newInst, lenA, - PROGRAM_OUTPUT, FRAG_RESULT_COLOR, - PROGRAM_TEMPORARY, tempReg); - /* replace reads from the input color with tempReg */ - replace_registers(newInst + lenA, lenB, - progB_colorFile, progB_colorIndex, /* search for */ - PROGRAM_TEMPORARY, tempReg /* replace with */ ); - } - - /* compute combined program's InputsRead */ - inputsB = progB_inputsRead; - if (progA->OutputsWritten & (1 << FRAG_RESULT_COLOR)) { - inputsB &= ~(1 << FRAG_ATTRIB_COL0); - } - newProg->InputsRead = progA->InputsRead | inputsB; - newProg->OutputsWritten = progB->OutputsWritten; - newProg->SamplersUsed = progA->SamplersUsed | progB->SamplersUsed; - } - else { - /* vertex program */ - assert(0); /* XXX todo */ - } - - /* - * Merge parameters (uniforms, constants, etc) - */ - newProg->Parameters = _mesa_combine_parameter_lists(progA->Parameters, - progB->Parameters); - - adjust_param_indexes(newInst + lenA, lenB, numParamsA); - - - return newProg; -} - - -/** - * Populate the 'used' array with flags indicating which registers (TEMPs, - * INPUTs, OUTPUTs, etc, are used by the given program. - * \param file type of register to scan for - * \param used returns true/false flags for in use / free - * \param usedSize size of the 'used' array - */ -void -_mesa_find_used_registers(const struct gl_program *prog, - gl_register_file file, - GLboolean used[], GLuint usedSize) -{ - GLuint i, j; - - memset(used, 0, usedSize); - - for (i = 0; i < prog->NumInstructions; i++) { - const struct prog_instruction *inst = prog->Instructions + i; - const GLuint n = _mesa_num_inst_src_regs(inst->Opcode); - - if (inst->DstReg.File == file) { - used[inst->DstReg.Index] = GL_TRUE; - } - - for (j = 0; j < n; j++) { - if (inst->SrcReg[j].File == file) { - used[inst->SrcReg[j].Index] = GL_TRUE; - } - } - } -} - - -/** - * Scan the given 'used' register flag array for the first entry - * that's >= firstReg. - * \param used vector of flags indicating registers in use (as returned - * by _mesa_find_used_registers()) - * \param usedSize size of the 'used' array - * \param firstReg first register to start searching at - * \return index of unused register, or -1 if none. - */ -GLint -_mesa_find_free_register(const GLboolean used[], - GLuint usedSize, GLuint firstReg) -{ - GLuint i; - - assert(firstReg < usedSize); - - for (i = firstReg; i < usedSize; i++) - if (!used[i]) - return i; - - return -1; -} - - -/** - * "Post-process" a GPU program. This is intended to be used for debugging. - * Example actions include no-op'ing instructions or changing instruction - * behaviour. - */ -void -_mesa_postprocess_program(GLcontext *ctx, struct gl_program *prog) -{ - static const GLfloat white[4] = { 0.5, 0.5, 0.5, 0.5 }; - GLuint i; - GLuint whiteSwizzle; - GLint whiteIndex = _mesa_add_unnamed_constant(prog->Parameters, - white, 4, &whiteSwizzle); - - (void) whiteIndex; - - for (i = 0; i < prog->NumInstructions; i++) { - struct prog_instruction *inst = prog->Instructions + i; - const GLuint n = _mesa_num_inst_src_regs(inst->Opcode); - - (void) n; - - if (_mesa_is_tex_instruction(inst->Opcode)) { -#if 0 - /* replace TEX/TXP/TXB with MOV */ - inst->Opcode = OPCODE_MOV; - inst->DstReg.WriteMask = WRITEMASK_XYZW; - inst->SrcReg[0].Swizzle = SWIZZLE_XYZW; - inst->SrcReg[0].Negate = NEGATE_NONE; -#endif - -#if 0 - /* disable shadow texture mode */ - inst->TexShadow = 0; -#endif - } - - if (inst->Opcode == OPCODE_TXP) { -#if 0 - inst->Opcode = OPCODE_MOV; - inst->DstReg.WriteMask = WRITEMASK_XYZW; - inst->SrcReg[0].File = PROGRAM_CONSTANT; - inst->SrcReg[0].Index = whiteIndex; - inst->SrcReg[0].Swizzle = SWIZZLE_XYZW; - inst->SrcReg[0].Negate = NEGATE_NONE; -#endif -#if 0 - inst->TexShadow = 0; -#endif -#if 0 - inst->Opcode = OPCODE_TEX; - inst->TexShadow = 0; -#endif - } - - } -} diff --git a/mesalib/src/mesa/shader/program.h b/mesalib/src/mesa/shader/program.h deleted file mode 100644 index af9f4170d..000000000 --- a/mesalib/src/mesa/shader/program.h +++ /dev/null @@ -1,151 +0,0 @@ -/* - * 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 program.c - * Vertex and fragment program support functions. - * \author Brian Paul - */ - - -/** - * \mainpage Mesa vertex and fragment program module - * - * This module or directory contains most of the code for vertex and - * fragment programs and shaders, including state management, parsers, - * and (some) software routines for executing programs - */ - -#ifndef PROGRAM_H -#define PROGRAM_H - -#include "main/mtypes.h" - - -extern struct gl_program _mesa_DummyProgram; - - -extern void -_mesa_init_program(GLcontext *ctx); - -extern void -_mesa_free_program_data(GLcontext *ctx); - -extern void -_mesa_update_default_objects_program(GLcontext *ctx); - -extern void -_mesa_set_program_error(GLcontext *ctx, GLint pos, const char *string); - -extern const GLubyte * -_mesa_find_line_column(const GLubyte *string, const GLubyte *pos, - GLint *line, GLint *col); - - -extern struct gl_program * -_mesa_init_vertex_program(GLcontext *ctx, - struct gl_vertex_program *prog, - GLenum target, GLuint id); - -extern struct gl_program * -_mesa_init_fragment_program(GLcontext *ctx, - struct gl_fragment_program *prog, - GLenum target, GLuint id); - -extern struct gl_program * -_mesa_new_program(GLcontext *ctx, GLenum target, GLuint id); - -extern void -_mesa_delete_program(GLcontext *ctx, struct gl_program *prog); - -extern struct gl_program * -_mesa_lookup_program(GLcontext *ctx, GLuint id); - -extern void -_mesa_reference_program(GLcontext *ctx, - struct gl_program **ptr, - struct gl_program *prog); - -static INLINE void -_mesa_reference_vertprog(GLcontext *ctx, - struct gl_vertex_program **ptr, - struct gl_vertex_program *prog) -{ - _mesa_reference_program(ctx, (struct gl_program **) ptr, - (struct gl_program *) prog); -} - -static INLINE void -_mesa_reference_fragprog(GLcontext *ctx, - struct gl_fragment_program **ptr, - struct gl_fragment_program *prog) -{ - _mesa_reference_program(ctx, (struct gl_program **) ptr, - (struct gl_program *) prog); -} - -extern struct gl_program * -_mesa_clone_program(GLcontext *ctx, const struct gl_program *prog); - -static INLINE struct gl_vertex_program * -_mesa_clone_vertex_program(GLcontext *ctx, - const struct gl_vertex_program *prog) -{ - return (struct gl_vertex_program *) _mesa_clone_program(ctx, &prog->Base); -} - - -static INLINE struct gl_fragment_program * -_mesa_clone_fragment_program(GLcontext *ctx, - const struct gl_fragment_program *prog) -{ - return (struct gl_fragment_program *) _mesa_clone_program(ctx, &prog->Base); -} - - -extern GLboolean -_mesa_insert_instructions(struct gl_program *prog, GLuint start, GLuint count); - -extern GLboolean -_mesa_delete_instructions(struct gl_program *prog, GLuint start, GLuint count); - -extern struct gl_program * -_mesa_combine_programs(GLcontext *ctx, - const struct gl_program *progA, - const struct gl_program *progB); - -extern void -_mesa_find_used_registers(const struct gl_program *prog, - gl_register_file file, - GLboolean used[], GLuint usedSize); - -extern GLint -_mesa_find_free_register(const GLboolean used[], - GLuint maxRegs, GLuint firstReg); - -extern void -_mesa_postprocess_program(GLcontext *ctx, struct gl_program *prog); - - -#endif /* PROGRAM_H */ diff --git a/mesalib/src/mesa/shader/program_lexer.l b/mesalib/src/mesa/shader/program_lexer.l deleted file mode 100644 index fe18272cd..000000000 --- a/mesalib/src/mesa/shader/program_lexer.l +++ /dev/null @@ -1,495 +0,0 @@ -%{ -/* - * Copyright © 2009 Intel Corporation - * - * 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 (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 NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS 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 "main/glheader.h" -#include "main/imports.h" -#include "shader/prog_instruction.h" -#include "shader/prog_statevars.h" - -#include "shader/symbol_table.h" -#include "shader/program_parser.h" -#include "shader/program_parse.tab.h" - -#define require_ARB_vp (yyextra->mode == ARB_vertex) -#define require_ARB_fp (yyextra->mode == ARB_fragment) -#define require_NV_fp (yyextra->option.NV_fragment) -#define require_shadow (yyextra->option.Shadow) -#define require_rect (yyextra->option.TexRect) -#define require_texarray (yyextra->option.TexArray) - -#ifndef HAVE_UNISTD_H -#define YY_NO_UNISTD_H -#endif - -#define return_token_or_IDENTIFIER(condition, token) \ - do { \ - if (condition) { \ - return token; \ - } else { \ - return handle_ident(yyextra, yytext, yylval); \ - } \ - } while (0) - -#define return_token_or_DOT(condition, token) \ - do { \ - if (condition) { \ - return token; \ - } else { \ - yyless(1); \ - return DOT; \ - } \ - } while (0) - - -#define return_opcode(condition, token, opcode, len) \ - do { \ - if (condition && \ - _mesa_parse_instruction_suffix(yyextra, \ - yytext + len, \ - & yylval->temp_inst)) { \ - yylval->temp_inst.Opcode = OPCODE_ ## opcode; \ - return token; \ - } else { \ - return handle_ident(yyextra, yytext, yylval); \ - } \ - } while (0) - -#define SWIZZLE_INVAL MAKE_SWIZZLE4(SWIZZLE_NIL, SWIZZLE_NIL, \ - SWIZZLE_NIL, SWIZZLE_NIL) - -static unsigned -mask_from_char(char c) -{ - switch (c) { - case 'x': - case 'r': - return WRITEMASK_X; - case 'y': - case 'g': - return WRITEMASK_Y; - case 'z': - case 'b': - return WRITEMASK_Z; - case 'w': - case 'a': - return WRITEMASK_W; - } - - return 0; -} - -static unsigned -swiz_from_char(char c) -{ - switch (c) { - case 'x': - case 'r': - return SWIZZLE_X; - case 'y': - case 'g': - return SWIZZLE_Y; - case 'z': - case 'b': - return SWIZZLE_Z; - case 'w': - case 'a': - return SWIZZLE_W; - } - - return 0; -} - -static int -handle_ident(struct asm_parser_state *state, const char *text, YYSTYPE *lval) -{ - lval->string = strdup(text); - - return (_mesa_symbol_table_find_symbol(state->st, 0, text) == NULL) - ? IDENTIFIER : USED_IDENTIFIER; -} - -#define YY_USER_ACTION \ - do { \ - yylloc->first_column = yylloc->last_column; \ - yylloc->last_column += yyleng; \ - if ((yylloc->first_line == 1) \ - && (yylloc->first_column == 1)) { \ - yylloc->position = 1; \ - } else { \ - yylloc->position += yylloc->last_column - yylloc->first_column; \ - } \ - } while(0); - -#define YY_EXTRA_TYPE struct asm_parser_state * -%} - -num [0-9]+ -exp [Ee][-+]?[0-9]+ -frac "."[0-9]+ -dot "."[ \t]* - -sz [HRX]? -szf [HR]? -cc C? -sat (_SAT)? - -%option bison-bridge bison-locations reentrant noyywrap -%% - -"!!ARBvp1.0" { return ARBvp_10; } -"!!ARBfp1.0" { return ARBfp_10; } -ADDRESS { - yylval->integer = at_address; - return_token_or_IDENTIFIER(require_ARB_vp, ADDRESS); -} -ALIAS { return ALIAS; } -ATTRIB { return ATTRIB; } -END { return END; } -OPTION { return OPTION; } -OUTPUT { return OUTPUT; } -PARAM { return PARAM; } -TEMP { yylval->integer = at_temp; return TEMP; } - -ABS{sz}{cc}{sat} { return_opcode( 1, VECTOR_OP, ABS, 3); } -ADD{sz}{cc}{sat} { return_opcode( 1, BIN_OP, ADD, 3); } -ARL { return_opcode(require_ARB_vp, ARL, ARL, 3); } - -CMP{sat} { return_opcode(require_ARB_fp, TRI_OP, CMP, 3); } -COS{szf}{cc}{sat} { return_opcode(require_ARB_fp, SCALAR_OP, COS, 3); } - -DDX{szf}{cc}{sat} { return_opcode(require_NV_fp, VECTOR_OP, DDX, 3); } -DDY{szf}{cc}{sat} { return_opcode(require_NV_fp, VECTOR_OP, DDY, 3); } -DP3{sz}{cc}{sat} { return_opcode( 1, BIN_OP, DP3, 3); } -DP4{sz}{cc}{sat} { return_opcode( 1, BIN_OP, DP4, 3); } -DPH{sz}{cc}{sat} { return_opcode( 1, BIN_OP, DPH, 3); } -DST{szf}{cc}{sat} { return_opcode( 1, BIN_OP, DST, 3); } - -EX2{szf}{cc}{sat} { return_opcode( 1, SCALAR_OP, EX2, 3); } -EXP { return_opcode(require_ARB_vp, SCALAR_OP, EXP, 3); } - -FLR{sz}{cc}{sat} { return_opcode( 1, VECTOR_OP, FLR, 3); } -FRC{sz}{cc}{sat} { return_opcode( 1, VECTOR_OP, FRC, 3); } - -KIL { return_opcode(require_ARB_fp, KIL, KIL, 3); } - -LIT{szf}{cc}{sat} { return_opcode( 1, VECTOR_OP, LIT, 3); } -LG2{szf}{cc}{sat} { return_opcode( 1, SCALAR_OP, LG2, 3); } -LOG { return_opcode(require_ARB_vp, SCALAR_OP, LOG, 3); } -LRP{sz}{cc}{sat} { return_opcode(require_ARB_fp, TRI_OP, LRP, 3); } - -MAD{sz}{cc}{sat} { return_opcode( 1, TRI_OP, MAD, 3); } -MAX{sz}{cc}{sat} { return_opcode( 1, BIN_OP, MAX, 3); } -MIN{sz}{cc}{sat} { return_opcode( 1, BIN_OP, MIN, 3); } -MOV{sz}{cc}{sat} { return_opcode( 1, VECTOR_OP, MOV, 3); } -MUL{sz}{cc}{sat} { return_opcode( 1, BIN_OP, MUL, 3); } - -PK2H { return_opcode(require_NV_fp, VECTOR_OP, PK2H, 4); } -PK2US { return_opcode(require_NV_fp, VECTOR_OP, PK2US, 5); } -PK4B { return_opcode(require_NV_fp, VECTOR_OP, PK4B, 4); } -PK4UB { return_opcode(require_NV_fp, VECTOR_OP, PK4UB, 5); } -POW{szf}{cc}{sat} { return_opcode( 1, BINSC_OP, POW, 3); } - -RCP{szf}{cc}{sat} { return_opcode( 1, SCALAR_OP, RCP, 3); } -RFL{szf}{cc}{sat} { return_opcode(require_NV_fp, BIN_OP, RFL, 3); } -RSQ{szf}{cc}{sat} { return_opcode( 1, SCALAR_OP, RSQ, 3); } - -SCS{sat} { return_opcode(require_ARB_fp, SCALAR_OP, SCS, 3); } -SEQ{sz}{cc}{sat} { return_opcode(require_NV_fp, BIN_OP, SEQ, 3); } -SFL{sz}{cc}{sat} { return_opcode(require_NV_fp, BIN_OP, SFL, 3); } -SGE{sz}{cc}{sat} { return_opcode( 1, BIN_OP, SGE, 3); } -SGT{sz}{cc}{sat} { return_opcode(require_NV_fp, BIN_OP, SGT, 3); } -SIN{szf}{cc}{sat} { return_opcode(require_ARB_fp, SCALAR_OP, SIN, 3); } -SLE{sz}{cc}{sat} { return_opcode(require_NV_fp, BIN_OP, SLE, 3); } -SLT{sz}{cc}{sat} { return_opcode( 1, BIN_OP, SLT, 3); } -SNE{sz}{cc}{sat} { return_opcode(require_NV_fp, BIN_OP, SNE, 3); } -STR{sz}{cc}{sat} { return_opcode(require_NV_fp, BIN_OP, STR, 3); } -SUB{sz}{cc}{sat} { return_opcode( 1, BIN_OP, SUB, 3); } -SWZ{sat} { return_opcode( 1, SWZ, SWZ, 3); } - -TEX{cc}{sat} { return_opcode(require_ARB_fp, SAMPLE_OP, TEX, 3); } -TXB{cc}{sat} { return_opcode(require_ARB_fp, SAMPLE_OP, TXB, 3); } -TXD{cc}{sat} { return_opcode(require_NV_fp, TXD_OP, TXD, 3); } -TXP{cc}{sat} { return_opcode(require_ARB_fp, SAMPLE_OP, TXP, 3); } - -UP2H{cc}{sat} { return_opcode(require_NV_fp, SCALAR_OP, UP2H, 4); } -UP2US{cc}{sat} { return_opcode(require_NV_fp, SCALAR_OP, UP2US, 5); } -UP4B{cc}{sat} { return_opcode(require_NV_fp, SCALAR_OP, UP4B, 4); } -UP4UB{cc}{sat} { return_opcode(require_NV_fp, SCALAR_OP, UP4UB, 5); } - -X2D{szf}{cc}{sat} { return_opcode(require_NV_fp, TRI_OP, X2D, 3); } -XPD{sat} { return_opcode( 1, BIN_OP, XPD, 3); } - -vertex { return_token_or_IDENTIFIER(require_ARB_vp, VERTEX); } -fragment { return_token_or_IDENTIFIER(require_ARB_fp, FRAGMENT); } -program { return PROGRAM; } -state { return STATE; } -result { return RESULT; } - -{dot}ambient { return AMBIENT; } -{dot}attenuation { return ATTENUATION; } -{dot}back { return BACK; } -{dot}clip { return_token_or_DOT(require_ARB_vp, CLIP); } -{dot}color { return COLOR; } -{dot}depth { return_token_or_DOT(require_ARB_fp, DEPTH); } -{dot}diffuse { return DIFFUSE; } -{dot}direction { return DIRECTION; } -{dot}emission { return EMISSION; } -{dot}env { return ENV; } -{dot}eye { return EYE; } -{dot}fogcoord { return FOGCOORD; } -{dot}fog { return FOG; } -{dot}front { return FRONT; } -{dot}half { return HALF; } -{dot}inverse { return INVERSE; } -{dot}invtrans { return INVTRANS; } -{dot}light { return LIGHT; } -{dot}lightmodel { return LIGHTMODEL; } -{dot}lightprod { return LIGHTPROD; } -{dot}local { return LOCAL; } -{dot}material { return MATERIAL; } -{dot}program { return MAT_PROGRAM; } -{dot}matrix { return MATRIX; } -{dot}matrixindex { return_token_or_DOT(require_ARB_vp, MATRIXINDEX); } -{dot}modelview { return MODELVIEW; } -{dot}mvp { return MVP; } -{dot}normal { return_token_or_DOT(require_ARB_vp, NORMAL); } -{dot}object { return OBJECT; } -{dot}palette { return PALETTE; } -{dot}params { return PARAMS; } -{dot}plane { return PLANE; } -{dot}point { return_token_or_DOT(require_ARB_vp, POINT_TOK); } -{dot}pointsize { return_token_or_DOT(require_ARB_vp, POINTSIZE); } -{dot}position { return POSITION; } -{dot}primary { return PRIMARY; } -{dot}projection { return PROJECTION; } -{dot}range { return_token_or_DOT(require_ARB_fp, RANGE); } -{dot}row { return ROW; } -{dot}scenecolor { return SCENECOLOR; } -{dot}secondary { return SECONDARY; } -{dot}shininess { return SHININESS; } -{dot}size { return_token_or_DOT(require_ARB_vp, SIZE_TOK); } -{dot}specular { return SPECULAR; } -{dot}spot { return SPOT; } -{dot}texcoord { return TEXCOORD; } -{dot}texenv { return_token_or_DOT(require_ARB_fp, TEXENV); } -{dot}texgen { return_token_or_DOT(require_ARB_vp, TEXGEN); } -{dot}q { return_token_or_DOT(require_ARB_vp, TEXGEN_Q); } -{dot}s { return_token_or_DOT(require_ARB_vp, TEXGEN_S); } -{dot}t { return_token_or_DOT(require_ARB_vp, TEXGEN_T); } -{dot}texture { return TEXTURE; } -{dot}transpose { return TRANSPOSE; } -{dot}attrib { return_token_or_DOT(require_ARB_vp, VTXATTRIB); } -{dot}weight { return_token_or_DOT(require_ARB_vp, WEIGHT); } - -texture { return_token_or_IDENTIFIER(require_ARB_fp, TEXTURE_UNIT); } -1D { return_token_or_IDENTIFIER(require_ARB_fp, TEX_1D); } -2D { return_token_or_IDENTIFIER(require_ARB_fp, TEX_2D); } -3D { return_token_or_IDENTIFIER(require_ARB_fp, TEX_3D); } -CUBE { return_token_or_IDENTIFIER(require_ARB_fp, TEX_CUBE); } -RECT { return_token_or_IDENTIFIER(require_ARB_fp && require_rect, TEX_RECT); } -SHADOW1D { return_token_or_IDENTIFIER(require_ARB_fp && require_shadow, TEX_SHADOW1D); } -SHADOW2D { return_token_or_IDENTIFIER(require_ARB_fp && require_shadow, TEX_SHADOW2D); } -SHADOWRECT { return_token_or_IDENTIFIER(require_ARB_fp && require_shadow && require_rect, TEX_SHADOWRECT); } -ARRAY1D { return_token_or_IDENTIFIER(require_ARB_fp && require_texarray, TEX_ARRAY1D); } -ARRAY2D { return_token_or_IDENTIFIER(require_ARB_fp && require_texarray, TEX_ARRAY2D); } -ARRAYSHADOW1D { return_token_or_IDENTIFIER(require_ARB_fp && require_shadow && require_texarray, TEX_ARRAYSHADOW1D); } -ARRAYSHADOW2D { return_token_or_IDENTIFIER(require_ARB_fp && require_shadow && require_texarray, TEX_ARRAYSHADOW2D); } - -[_a-zA-Z$][_a-zA-Z0-9$]* { return handle_ident(yyextra, yytext, yylval); } - -".." { return DOT_DOT; } - -{num} { - yylval->integer = strtol(yytext, NULL, 10); - return INTEGER; -} -{num}?{frac}{exp}? { - yylval->real = _mesa_strtof(yytext, NULL); - return REAL; -} -{num}"."/[^.] { - yylval->real = _mesa_strtof(yytext, NULL); - return REAL; -} -{num}{exp} { - yylval->real = _mesa_strtof(yytext, NULL); - return REAL; -} -{num}"."{exp} { - yylval->real = _mesa_strtof(yytext, NULL); - return REAL; -} - -".xyzw" { - yylval->swiz_mask.swizzle = SWIZZLE_NOOP; - yylval->swiz_mask.mask = WRITEMASK_XYZW; - return MASK4; -} - -".xy"[zw] { - yylval->swiz_mask.swizzle = SWIZZLE_INVAL; - yylval->swiz_mask.mask = WRITEMASK_XY - | mask_from_char(yytext[3]); - return MASK3; -} -".xzw" { - yylval->swiz_mask.swizzle = SWIZZLE_INVAL; - yylval->swiz_mask.mask = WRITEMASK_XZW; - return MASK3; -} -".yzw" { - yylval->swiz_mask.swizzle = SWIZZLE_INVAL; - yylval->swiz_mask.mask = WRITEMASK_YZW; - return MASK3; -} - -".x"[yzw] { - yylval->swiz_mask.swizzle = SWIZZLE_INVAL; - yylval->swiz_mask.mask = WRITEMASK_X - | mask_from_char(yytext[2]); - return MASK2; -} -".y"[zw] { - yylval->swiz_mask.swizzle = SWIZZLE_INVAL; - yylval->swiz_mask.mask = WRITEMASK_Y - | mask_from_char(yytext[2]); - return MASK2; -} -".zw" { - yylval->swiz_mask.swizzle = SWIZZLE_INVAL; - yylval->swiz_mask.mask = WRITEMASK_ZW; - return MASK2; -} - -"."[xyzw] { - const unsigned s = swiz_from_char(yytext[1]); - yylval->swiz_mask.swizzle = MAKE_SWIZZLE4(s, s, s, s); - yylval->swiz_mask.mask = mask_from_char(yytext[1]); - return MASK1; -} - -"."[xyzw]{4} { - yylval->swiz_mask.swizzle = MAKE_SWIZZLE4(swiz_from_char(yytext[1]), - swiz_from_char(yytext[2]), - swiz_from_char(yytext[3]), - swiz_from_char(yytext[4])); - yylval->swiz_mask.mask = 0; - return SWIZZLE; -} - -".rgba" { - yylval->swiz_mask.swizzle = SWIZZLE_NOOP; - yylval->swiz_mask.mask = WRITEMASK_XYZW; - return_token_or_DOT(require_ARB_fp, MASK4); -} - -".rg"[ba] { - yylval->swiz_mask.swizzle = SWIZZLE_INVAL; - yylval->swiz_mask.mask = WRITEMASK_XY - | mask_from_char(yytext[3]); - return_token_or_DOT(require_ARB_fp, MASK3); -} -".rba" { - yylval->swiz_mask.swizzle = SWIZZLE_INVAL; - yylval->swiz_mask.mask = WRITEMASK_XZW; - return_token_or_DOT(require_ARB_fp, MASK3); -} -".gba" { - yylval->swiz_mask.swizzle = SWIZZLE_INVAL; - yylval->swiz_mask.mask = WRITEMASK_YZW; - return_token_or_DOT(require_ARB_fp, MASK3); -} - -".r"[gba] { - yylval->swiz_mask.swizzle = SWIZZLE_INVAL; - yylval->swiz_mask.mask = WRITEMASK_X - | mask_from_char(yytext[2]); - return_token_or_DOT(require_ARB_fp, MASK2); -} -".g"[ba] { - yylval->swiz_mask.swizzle = SWIZZLE_INVAL; - yylval->swiz_mask.mask = WRITEMASK_Y - | mask_from_char(yytext[2]); - return_token_or_DOT(require_ARB_fp, MASK2); -} -".ba" { - yylval->swiz_mask.swizzle = SWIZZLE_INVAL; - yylval->swiz_mask.mask = WRITEMASK_ZW; - return_token_or_DOT(require_ARB_fp, MASK2); -} - -"."[gba] { - const unsigned s = swiz_from_char(yytext[1]); - yylval->swiz_mask.swizzle = MAKE_SWIZZLE4(s, s, s, s); - yylval->swiz_mask.mask = mask_from_char(yytext[1]); - return_token_or_DOT(require_ARB_fp, MASK1); -} - - -".r" { - if (require_ARB_vp) { - return TEXGEN_R; - } else { - yylval->swiz_mask.swizzle = MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_X, - SWIZZLE_X, SWIZZLE_X); - yylval->swiz_mask.mask = WRITEMASK_X; - return MASK1; - } -} - -"."[rgba]{4} { - yylval->swiz_mask.swizzle = MAKE_SWIZZLE4(swiz_from_char(yytext[1]), - swiz_from_char(yytext[2]), - swiz_from_char(yytext[3]), - swiz_from_char(yytext[4])); - yylval->swiz_mask.mask = 0; - return_token_or_DOT(require_ARB_fp, SWIZZLE); -} - -"." { return DOT; } - -\n { - yylloc->first_line++; - yylloc->first_column = 1; - yylloc->last_line++; - yylloc->last_column = 1; - yylloc->position++; -} -[ \t\r]+ /* eat whitespace */ ; -#.*$ /* eat comments */ ; -. { return yytext[0]; } -%% - -void -_mesa_program_lexer_ctor(void **scanner, struct asm_parser_state *state, - const char *string, size_t len) -{ - yylex_init_extra(state, scanner); - yy_scan_bytes(string, len, *scanner); -} - -void -_mesa_program_lexer_dtor(void *scanner) -{ - yylex_destroy(scanner); -} diff --git a/mesalib/src/mesa/shader/program_parse.tab.c b/mesalib/src/mesa/shader/program_parse.tab.c deleted file mode 100644 index 64a987e16..000000000 --- a/mesalib/src/mesa/shader/program_parse.tab.c +++ /dev/null @@ -1,5728 +0,0 @@ - -/* A Bison parser, made by GNU Bison 2.4.1. */ - -/* Skeleton implementation for Bison's Yacc-like parsers in C - - Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005, 2006 - 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 3 of the License, 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, see <http://www.gnu.org/licenses/>. */ - -/* As a special exception, you may create a larger work that contains - part or all of the Bison parser skeleton and distribute that work - under terms of your choice, so long as that work isn't itself a - parser generator using the skeleton or a modified version thereof - as a parser skeleton. Alternatively, if you modify or redistribute - the parser skeleton itself, you may (at your option) remove this - special exception, which will cause the skeleton and the resulting - Bison output files to be licensed under the GNU General Public - License without this special exception. - - This special exception was added by the Free Software Foundation in - version 2.2 of Bison. */ - -/* C LALR(1) parser skeleton 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 - -/* Bison version. */ -#define YYBISON_VERSION "2.4.1" - -/* Skeleton name. */ -#define YYSKELETON_NAME "yacc.c" - -/* Pure parsers. */ -#define YYPURE 1 - -/* Push parsers. */ -#define YYPUSH 0 - -/* Pull parsers. */ -#define YYPULL 1 - -/* Using locations. */ -#define YYLSP_NEEDED 1 - - - -/* Copy the first part of user declarations. */ - -/* Line 189 of yacc.c */ -#line 1 "program_parse.y" - -/* - * Copyright © 2009 Intel Corporation - * - * 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 (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 NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS 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 <stdio.h> -#include <stdlib.h> -#include <string.h> - -#include "main/mtypes.h" -#include "main/imports.h" -#include "shader/program.h" -#include "shader/prog_parameter.h" -#include "shader/prog_parameter_layout.h" -#include "shader/prog_statevars.h" -#include "shader/prog_instruction.h" - -#include "shader/symbol_table.h" -#include "shader/program_parser.h" - -extern void *yy_scan_string(char *); -extern void yy_delete_buffer(void *); - -static struct asm_symbol *declare_variable(struct asm_parser_state *state, - char *name, enum asm_type t, struct YYLTYPE *locp); - -static int add_state_reference(struct gl_program_parameter_list *param_list, - const gl_state_index tokens[STATE_LENGTH]); - -static int initialize_symbol_from_state(struct gl_program *prog, - struct asm_symbol *param_var, const gl_state_index tokens[STATE_LENGTH]); - -static int initialize_symbol_from_param(struct gl_program *prog, - struct asm_symbol *param_var, const gl_state_index tokens[STATE_LENGTH]); - -static int initialize_symbol_from_const(struct gl_program *prog, - struct asm_symbol *param_var, const struct asm_vector *vec, - GLboolean allowSwizzle); - -static int yyparse(struct asm_parser_state *state); - -static char *make_error_string(const char *fmt, ...); - -static void yyerror(struct YYLTYPE *locp, struct asm_parser_state *state, - const char *s); - -static int validate_inputs(struct YYLTYPE *locp, - struct asm_parser_state *state); - -static void init_dst_reg(struct prog_dst_register *r); - -static void set_dst_reg(struct prog_dst_register *r, - gl_register_file file, GLint index); - -static void init_src_reg(struct asm_src_register *r); - -static void set_src_reg(struct asm_src_register *r, - gl_register_file file, GLint index); - -static void set_src_reg_swz(struct asm_src_register *r, - gl_register_file file, GLint index, GLuint swizzle); - -static void asm_instruction_set_operands(struct asm_instruction *inst, - const struct prog_dst_register *dst, const struct asm_src_register *src0, - const struct asm_src_register *src1, const struct asm_src_register *src2); - -static struct asm_instruction *asm_instruction_ctor(gl_inst_opcode op, - const struct prog_dst_register *dst, const struct asm_src_register *src0, - const struct asm_src_register *src1, const struct asm_src_register *src2); - -static struct asm_instruction *asm_instruction_copy_ctor( - const struct prog_instruction *base, const struct prog_dst_register *dst, - const struct asm_src_register *src0, const struct asm_src_register *src1, - const struct asm_src_register *src2); - -#ifndef FALSE -#define FALSE 0 -#define TRUE (!FALSE) -#endif - -#define YYLLOC_DEFAULT(Current, Rhs, N) \ - do { \ - if (YYID(N)) { \ - (Current).first_line = YYRHSLOC(Rhs, 1).first_line; \ - (Current).first_column = YYRHSLOC(Rhs, 1).first_column; \ - (Current).position = YYRHSLOC(Rhs, 1).position; \ - (Current).last_line = YYRHSLOC(Rhs, N).last_line; \ - (Current).last_column = YYRHSLOC(Rhs, N).last_column; \ - } else { \ - (Current).first_line = YYRHSLOC(Rhs, 0).last_line; \ - (Current).last_line = (Current).first_line; \ - (Current).first_column = YYRHSLOC(Rhs, 0).last_column; \ - (Current).last_column = (Current).first_column; \ - (Current).position = YYRHSLOC(Rhs, 0).position \ - + (Current).first_column; \ - } \ - } while(YYID(0)) - -#define YYLEX_PARAM state->scanner - - -/* Line 189 of yacc.c */ -#line 193 "program_parse.tab.c" - -/* Enabling traces. */ -#ifndef YYDEBUG -# define YYDEBUG 0 -#endif - -/* Enabling verbose error messages. */ -#ifdef YYERROR_VERBOSE -# undef YYERROR_VERBOSE -# define YYERROR_VERBOSE 1 -#else -# define YYERROR_VERBOSE 1 -#endif - -/* Enabling the token table. */ -#ifndef YYTOKEN_TABLE -# define YYTOKEN_TABLE 0 -#endif - - -/* Tokens. */ -#ifndef YYTOKENTYPE -# define YYTOKENTYPE - /* Put the tokens into the symbol table, so that GDB and other debuggers - know about them. */ - enum yytokentype { - ARBvp_10 = 258, - ARBfp_10 = 259, - ADDRESS = 260, - ALIAS = 261, - ATTRIB = 262, - OPTION = 263, - OUTPUT = 264, - PARAM = 265, - TEMP = 266, - END = 267, - BIN_OP = 268, - BINSC_OP = 269, - SAMPLE_OP = 270, - SCALAR_OP = 271, - TRI_OP = 272, - VECTOR_OP = 273, - ARL = 274, - KIL = 275, - SWZ = 276, - TXD_OP = 277, - INTEGER = 278, - REAL = 279, - AMBIENT = 280, - ATTENUATION = 281, - BACK = 282, - CLIP = 283, - COLOR = 284, - DEPTH = 285, - DIFFUSE = 286, - DIRECTION = 287, - EMISSION = 288, - ENV = 289, - EYE = 290, - FOG = 291, - FOGCOORD = 292, - FRAGMENT = 293, - FRONT = 294, - HALF = 295, - INVERSE = 296, - INVTRANS = 297, - LIGHT = 298, - LIGHTMODEL = 299, - LIGHTPROD = 300, - LOCAL = 301, - MATERIAL = 302, - MAT_PROGRAM = 303, - MATRIX = 304, - MATRIXINDEX = 305, - MODELVIEW = 306, - MVP = 307, - NORMAL = 308, - OBJECT = 309, - PALETTE = 310, - PARAMS = 311, - PLANE = 312, - POINT_TOK = 313, - POINTSIZE = 314, - POSITION = 315, - PRIMARY = 316, - PROGRAM = 317, - PROJECTION = 318, - RANGE = 319, - RESULT = 320, - ROW = 321, - SCENECOLOR = 322, - SECONDARY = 323, - SHININESS = 324, - SIZE_TOK = 325, - SPECULAR = 326, - SPOT = 327, - STATE = 328, - TEXCOORD = 329, - TEXENV = 330, - TEXGEN = 331, - TEXGEN_Q = 332, - TEXGEN_R = 333, - TEXGEN_S = 334, - TEXGEN_T = 335, - TEXTURE = 336, - TRANSPOSE = 337, - TEXTURE_UNIT = 338, - TEX_1D = 339, - TEX_2D = 340, - TEX_3D = 341, - TEX_CUBE = 342, - TEX_RECT = 343, - TEX_SHADOW1D = 344, - TEX_SHADOW2D = 345, - TEX_SHADOWRECT = 346, - TEX_ARRAY1D = 347, - TEX_ARRAY2D = 348, - TEX_ARRAYSHADOW1D = 349, - TEX_ARRAYSHADOW2D = 350, - VERTEX = 351, - VTXATTRIB = 352, - WEIGHT = 353, - IDENTIFIER = 354, - USED_IDENTIFIER = 355, - MASK4 = 356, - MASK3 = 357, - MASK2 = 358, - MASK1 = 359, - SWIZZLE = 360, - DOT_DOT = 361, - DOT = 362 - }; -#endif - - - -#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED -typedef union YYSTYPE -{ - -/* Line 214 of yacc.c */ -#line 126 "program_parse.y" - - struct asm_instruction *inst; - struct asm_symbol *sym; - struct asm_symbol temp_sym; - struct asm_swizzle_mask swiz_mask; - struct asm_src_register src_reg; - struct prog_dst_register dst_reg; - struct prog_instruction temp_inst; - char *string; - unsigned result; - unsigned attrib; - int integer; - float real; - gl_state_index state[STATE_LENGTH]; - int negate; - struct asm_vector vector; - gl_inst_opcode opcode; - - struct { - unsigned swz; - unsigned rgba_valid:1; - unsigned xyzw_valid:1; - unsigned negate:1; - } ext_swizzle; - - - -/* Line 214 of yacc.c */ -#line 364 "program_parse.tab.c" -} YYSTYPE; -# define YYSTYPE_IS_TRIVIAL 1 -# define yystype YYSTYPE /* obsolescent; will be withdrawn */ -# define YYSTYPE_IS_DECLARED 1 -#endif - -#if ! defined YYLTYPE && ! defined YYLTYPE_IS_DECLARED -typedef struct YYLTYPE -{ - int first_line; - int first_column; - int last_line; - int last_column; -} YYLTYPE; -# define yyltype YYLTYPE /* obsolescent; will be withdrawn */ -# define YYLTYPE_IS_DECLARED 1 -# define YYLTYPE_IS_TRIVIAL 1 -#endif - - -/* Copy the second part of user declarations. */ - -/* Line 264 of yacc.c */ -#line 271 "program_parse.y" - -extern int yylex(YYSTYPE *yylval_param, YYLTYPE *yylloc_param, - void *yyscanner); - - -/* Line 264 of yacc.c */ -#line 395 "program_parse.tab.c" - -#ifdef short -# undef short -#endif - -#ifdef YYTYPE_UINT8 -typedef YYTYPE_UINT8 yytype_uint8; -#else -typedef unsigned char yytype_uint8; -#endif - -#ifdef YYTYPE_INT8 -typedef YYTYPE_INT8 yytype_int8; -#elif (defined __STDC__ || defined __C99__FUNC__ \ - || defined __cplusplus || defined _MSC_VER) -typedef signed char yytype_int8; -#else -typedef short int yytype_int8; -#endif - -#ifdef YYTYPE_UINT16 -typedef YYTYPE_UINT16 yytype_uint16; -#else -typedef unsigned short int yytype_uint16; -#endif - -#ifdef YYTYPE_INT16 -typedef YYTYPE_INT16 yytype_int16; -#else -typedef short int yytype_int16; -#endif - -#ifndef YYSIZE_T -# ifdef __SIZE_TYPE__ -# define YYSIZE_T __SIZE_TYPE__ -# elif defined size_t -# define YYSIZE_T size_t -# elif ! defined YYSIZE_T && (defined __STDC__ || defined __C99__FUNC__ \ - || defined __cplusplus || defined _MSC_VER) -# include <stddef.h> /* INFRINGES ON USER NAME SPACE */ -# define YYSIZE_T size_t -# else -# define YYSIZE_T unsigned int -# endif -#endif - -#define YYSIZE_MAXIMUM ((YYSIZE_T) -1) - -#ifndef YY_ -# if YYENABLE_NLS -# if ENABLE_NLS -# include <libintl.h> /* INFRINGES ON USER NAME SPACE */ -# define YY_(msgid) dgettext ("bison-runtime", msgid) -# endif -# endif -# ifndef YY_ -# define YY_(msgid) msgid -# endif -#endif - -/* Suppress unused-variable warnings by "using" E. */ -#if ! defined lint || defined __GNUC__ -# define YYUSE(e) ((void) (e)) -#else -# define YYUSE(e) /* empty */ -#endif - -/* Identity function, used to suppress warnings about constant conditions. */ -#ifndef lint -# define YYID(n) (n) -#else -#if (defined __STDC__ || defined __C99__FUNC__ \ - || defined __cplusplus || defined _MSC_VER) -static int -YYID (int yyi) -#else -static int -YYID (yyi) - int yyi; -#endif -{ - return yyi; -} -#endif - -#if ! defined yyoverflow || YYERROR_VERBOSE - -/* The parser invokes alloca or malloc; define the necessary symbols. */ - -# ifdef YYSTACK_USE_ALLOCA -# if YYSTACK_USE_ALLOCA -# ifdef __GNUC__ -# define YYSTACK_ALLOC __builtin_alloca -# elif defined __BUILTIN_VA_ARG_INCR -# include <alloca.h> /* INFRINGES ON USER NAME SPACE */ -# elif defined _AIX -# define YYSTACK_ALLOC __alloca -# elif defined _MSC_VER -# include <malloc.h> /* INFRINGES ON USER NAME SPACE */ -# define alloca _alloca -# else -# define YYSTACK_ALLOC alloca -# if ! defined _ALLOCA_H && ! defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \ - || defined __cplusplus || defined _MSC_VER) -# include <stdlib.h> /* INFRINGES ON USER NAME SPACE */ -# ifndef _STDLIB_H -# define _STDLIB_H 1 -# endif -# endif -# endif -# endif -# endif - -# ifdef YYSTACK_ALLOC - /* Pacify GCC's `empty if-body' warning. */ -# define YYSTACK_FREE(Ptr) do { /* empty */; } while (YYID (0)) -# ifndef YYSTACK_ALLOC_MAXIMUM - /* The OS might guarantee only one guard page at the bottom of the stack, - and a page size can be as small as 4096 bytes. So we cannot safely - invoke alloca (N) if N exceeds 4096. Use a slightly smaller number - to allow for a few compiler-allocated temporary stack slots. */ -# define YYSTACK_ALLOC_MAXIMUM 4032 /* reasonable circa 2006 */ -# endif -# else -# define YYSTACK_ALLOC YYMALLOC -# define YYSTACK_FREE YYFREE -# ifndef YYSTACK_ALLOC_MAXIMUM -# define YYSTACK_ALLOC_MAXIMUM YYSIZE_MAXIMUM -# endif -# if (defined __cplusplus && ! defined _STDLIB_H \ - && ! ((defined YYMALLOC || defined malloc) \ - && (defined YYFREE || defined free))) -# include <stdlib.h> /* INFRINGES ON USER NAME SPACE */ -# ifndef _STDLIB_H -# define _STDLIB_H 1 -# endif -# endif -# ifndef YYMALLOC -# define YYMALLOC malloc -# if ! defined malloc && ! defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \ - || defined __cplusplus ) -void *malloc (YYSIZE_T); /* INFRINGES ON USER NAME SPACE */ -# endif -# endif -# ifndef YYFREE -# define YYFREE free -# if ! defined free && ! defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \ - || defined __cplusplus ) -void free (void *); /* INFRINGES ON USER NAME SPACE */ -# endif -# endif -# endif -#endif /* ! defined yyoverflow || YYERROR_VERBOSE */ - - -#if (! defined yyoverflow \ - && (! defined __cplusplus \ - || (defined YYLTYPE_IS_TRIVIAL && YYLTYPE_IS_TRIVIAL \ - && defined YYSTYPE_IS_TRIVIAL && YYSTYPE_IS_TRIVIAL))) - -/* A type that is properly aligned for any stack member. */ -union yyalloc -{ - yytype_int16 yyss_alloc; - YYSTYPE yyvs_alloc; - YYLTYPE yyls_alloc; -}; - -/* 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 (yytype_int16) + sizeof (YYSTYPE) + sizeof (YYLTYPE)) \ - + 2 * YYSTACK_GAP_MAXIMUM) - -/* Copy COUNT objects from FROM to TO. The source and destination do - not overlap. */ -# ifndef YYCOPY -# if defined __GNUC__ && 1 < __GNUC__ -# define YYCOPY(To, From, Count) \ - __builtin_memcpy (To, From, (Count) * sizeof (*(From))) -# else -# define YYCOPY(To, From, Count) \ - do \ - { \ - YYSIZE_T yyi; \ - for (yyi = 0; yyi < (Count); yyi++) \ - (To)[yyi] = (From)[yyi]; \ - } \ - while (YYID (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_alloc, Stack) \ - do \ - { \ - YYSIZE_T yynewbytes; \ - YYCOPY (&yyptr->Stack_alloc, Stack, yysize); \ - Stack = &yyptr->Stack_alloc; \ - yynewbytes = yystacksize * sizeof (*Stack) + YYSTACK_GAP_MAXIMUM; \ - yyptr += yynewbytes / sizeof (*yyptr); \ - } \ - while (YYID (0)) - -#endif - -/* YYFINAL -- State number of the termination state. */ -#define YYFINAL 5 -/* YYLAST -- Last index in YYTABLE. */ -#define YYLAST 396 - -/* YYNTOKENS -- Number of terminals. */ -#define YYNTOKENS 120 -/* YYNNTS -- Number of nonterminals. */ -#define YYNNTS 143 -/* YYNRULES -- Number of rules. */ -#define YYNRULES 282 -/* YYNRULES -- Number of states. */ -#define YYNSTATES 475 - -/* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX. */ -#define YYUNDEFTOK 2 -#define YYMAXUTOK 362 - -#define YYTRANSLATE(YYX) \ - ((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK) - -/* YYTRANSLATE[YYLEX] -- Bison symbol number corresponding to YYLEX. */ -static const yytype_uint8 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, - 115, 116, 2, 113, 109, 114, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 108, - 2, 117, 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, 111, 2, 112, 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, 118, 110, 119, 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, 93, 94, - 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, - 105, 106, 107 -}; - -#if YYDEBUG -/* YYPRHS[YYN] -- Index of the first RHS symbol of rule number YYN in - YYRHS. */ -static const yytype_uint16 yyprhs[] = -{ - 0, 0, 3, 8, 10, 12, 15, 16, 20, 23, - 24, 27, 30, 32, 34, 36, 38, 40, 42, 44, - 46, 48, 50, 52, 54, 59, 64, 69, 76, 83, - 92, 101, 104, 107, 120, 123, 125, 127, 129, 131, - 133, 135, 137, 139, 141, 143, 145, 147, 154, 157, - 162, 165, 167, 171, 177, 181, 184, 192, 195, 197, - 199, 201, 203, 208, 210, 212, 214, 216, 218, 220, - 222, 226, 227, 230, 233, 235, 237, 239, 241, 243, - 245, 247, 249, 251, 252, 254, 256, 258, 260, 261, - 265, 269, 270, 273, 276, 278, 280, 282, 284, 286, - 288, 290, 292, 297, 300, 303, 305, 308, 310, 313, - 315, 318, 323, 328, 330, 331, 335, 337, 339, 342, - 344, 347, 349, 351, 355, 362, 363, 365, 368, 373, - 375, 379, 381, 383, 385, 387, 389, 391, 393, 395, - 397, 399, 402, 405, 408, 411, 414, 417, 420, 423, - 426, 429, 432, 435, 439, 441, 443, 445, 451, 453, - 455, 457, 460, 462, 464, 467, 469, 472, 479, 481, - 485, 487, 489, 491, 493, 495, 500, 502, 504, 506, - 508, 510, 512, 515, 517, 519, 525, 527, 530, 532, - 534, 540, 543, 544, 551, 555, 556, 558, 560, 562, - 564, 566, 569, 571, 573, 576, 581, 586, 587, 591, - 593, 595, 597, 600, 602, 604, 606, 608, 614, 616, - 620, 626, 632, 634, 638, 644, 646, 648, 650, 652, - 654, 656, 658, 660, 662, 666, 672, 680, 690, 693, - 696, 698, 700, 701, 702, 707, 709, 710, 711, 715, - 719, 721, 727, 730, 733, 736, 739, 743, 746, 750, - 751, 753, 755, 756, 758, 760, 761, 763, 765, 766, - 768, 770, 771, 775, 776, 780, 781, 785, 787, 789, - 791, 796, 798 -}; - -/* YYRHS -- A `-1'-separated list of the rules' RHS. */ -static const yytype_int16 yyrhs[] = -{ - 121, 0, -1, 122, 123, 125, 12, -1, 3, -1, - 4, -1, 123, 124, -1, -1, 8, 262, 108, -1, - 125, 126, -1, -1, 127, 108, -1, 170, 108, -1, - 128, -1, 129, -1, 130, -1, 131, -1, 132, -1, - 133, -1, 134, -1, 135, -1, 141, -1, 136, -1, - 137, -1, 138, -1, 19, 146, 109, 142, -1, 18, - 145, 109, 144, -1, 16, 145, 109, 142, -1, 14, - 145, 109, 142, 109, 142, -1, 13, 145, 109, 144, - 109, 144, -1, 17, 145, 109, 144, 109, 144, 109, - 144, -1, 15, 145, 109, 144, 109, 139, 109, 140, - -1, 20, 144, -1, 20, 166, -1, 22, 145, 109, - 144, 109, 144, 109, 144, 109, 139, 109, 140, -1, - 83, 256, -1, 84, -1, 85, -1, 86, -1, 87, - -1, 88, -1, 89, -1, 90, -1, 91, -1, 92, - -1, 93, -1, 94, -1, 95, -1, 21, 145, 109, - 150, 109, 147, -1, 241, 143, -1, 241, 110, 143, - 110, -1, 150, 162, -1, 238, -1, 241, 150, 163, - -1, 241, 110, 150, 163, 110, -1, 151, 164, 165, - -1, 159, 161, -1, 148, 109, 148, 109, 148, 109, - 148, -1, 241, 149, -1, 23, -1, 262, -1, 100, - -1, 172, -1, 152, 111, 153, 112, -1, 186, -1, - 249, -1, 100, -1, 100, -1, 154, -1, 155, -1, - 23, -1, 159, 160, 156, -1, -1, 113, 157, -1, - 114, 158, -1, 23, -1, 23, -1, 100, -1, 104, - -1, 104, -1, 104, -1, 104, -1, 101, -1, 105, - -1, -1, 101, -1, 102, -1, 103, -1, 104, -1, - -1, 115, 166, 116, -1, 115, 167, 116, -1, -1, - 168, 163, -1, 169, 163, -1, 99, -1, 100, -1, - 171, -1, 178, -1, 242, -1, 245, -1, 248, -1, - 261, -1, 7, 99, 117, 172, -1, 96, 173, -1, - 38, 177, -1, 60, -1, 98, 175, -1, 53, -1, - 29, 254, -1, 37, -1, 74, 255, -1, 50, 111, - 176, 112, -1, 97, 111, 174, 112, -1, 23, -1, - -1, 111, 176, 112, -1, 23, -1, 60, -1, 29, - 254, -1, 37, -1, 74, 255, -1, 179, -1, 180, - -1, 10, 99, 182, -1, 10, 99, 111, 181, 112, - 183, -1, -1, 23, -1, 117, 185, -1, 117, 118, - 184, 119, -1, 187, -1, 184, 109, 187, -1, 189, - -1, 225, -1, 235, -1, 189, -1, 225, -1, 236, - -1, 188, -1, 226, -1, 235, -1, 189, -1, 73, - 213, -1, 73, 190, -1, 73, 192, -1, 73, 195, - -1, 73, 197, -1, 73, 203, -1, 73, 199, -1, - 73, 206, -1, 73, 208, -1, 73, 210, -1, 73, - 212, -1, 73, 224, -1, 47, 253, 191, -1, 201, - -1, 33, -1, 69, -1, 43, 111, 202, 112, 193, - -1, 201, -1, 60, -1, 26, -1, 72, 194, -1, - 40, -1, 32, -1, 44, 196, -1, 25, -1, 253, - 67, -1, 45, 111, 202, 112, 253, 198, -1, 201, - -1, 75, 257, 200, -1, 29, -1, 25, -1, 31, - -1, 71, -1, 23, -1, 76, 255, 204, 205, -1, - 35, -1, 54, -1, 79, -1, 80, -1, 78, -1, - 77, -1, 36, 207, -1, 29, -1, 56, -1, 28, - 111, 209, 112, 57, -1, 23, -1, 58, 211, -1, - 70, -1, 26, -1, 215, 66, 111, 218, 112, -1, - 215, 214, -1, -1, 66, 111, 218, 106, 218, 112, - -1, 49, 219, 216, -1, -1, 217, -1, 41, -1, - 82, -1, 42, -1, 23, -1, 51, 220, -1, 63, - -1, 52, -1, 81, 255, -1, 55, 111, 222, 112, - -1, 48, 111, 223, 112, -1, -1, 111, 221, 112, - -1, 23, -1, 23, -1, 23, -1, 30, 64, -1, - 229, -1, 232, -1, 227, -1, 230, -1, 62, 34, - 111, 228, 112, -1, 233, -1, 233, 106, 233, -1, - 62, 34, 111, 233, 112, -1, 62, 46, 111, 231, - 112, -1, 234, -1, 234, 106, 234, -1, 62, 46, - 111, 234, 112, -1, 23, -1, 23, -1, 237, -1, - 239, -1, 238, -1, 239, -1, 240, -1, 24, -1, - 23, -1, 118, 240, 119, -1, 118, 240, 109, 240, - 119, -1, 118, 240, 109, 240, 109, 240, 119, -1, - 118, 240, 109, 240, 109, 240, 109, 240, 119, -1, - 241, 24, -1, 241, 23, -1, 113, -1, 114, -1, - -1, -1, 244, 11, 243, 247, -1, 262, -1, -1, - -1, 5, 246, 247, -1, 247, 109, 99, -1, 99, - -1, 244, 9, 99, 117, 249, -1, 65, 60, -1, - 65, 37, -1, 65, 250, -1, 65, 59, -1, 65, - 74, 255, -1, 65, 30, -1, 29, 251, 252, -1, - -1, 39, -1, 27, -1, -1, 61, -1, 68, -1, - -1, 39, -1, 27, -1, -1, 61, -1, 68, -1, - -1, 111, 258, 112, -1, -1, 111, 259, 112, -1, - -1, 111, 260, 112, -1, 23, -1, 23, -1, 23, - -1, 6, 99, 117, 100, -1, 99, -1, 100, -1 -}; - -/* YYRLINE[YYN] -- source line where rule number YYN was defined. */ -static const yytype_uint16 yyrline[] = -{ - 0, 278, 278, 281, 289, 301, 302, 305, 329, 330, - 333, 348, 351, 356, 363, 364, 365, 366, 367, 368, - 369, 372, 373, 374, 377, 383, 389, 395, 402, 408, - 415, 459, 464, 474, 518, 524, 525, 526, 527, 528, - 529, 530, 531, 532, 533, 534, 535, 538, 550, 558, - 575, 582, 601, 612, 632, 657, 664, 697, 704, 719, - 774, 817, 826, 847, 857, 861, 890, 909, 909, 911, - 918, 930, 931, 932, 935, 949, 963, 983, 994, 1006, - 1008, 1009, 1010, 1011, 1014, 1014, 1014, 1014, 1015, 1018, - 1022, 1027, 1034, 1041, 1048, 1071, 1094, 1095, 1096, 1097, - 1098, 1099, 1102, 1121, 1125, 1131, 1135, 1139, 1143, 1152, - 1161, 1165, 1170, 1176, 1187, 1187, 1188, 1190, 1194, 1198, - 1202, 1208, 1208, 1210, 1228, 1254, 1257, 1268, 1274, 1280, - 1281, 1288, 1294, 1300, 1308, 1314, 1320, 1328, 1334, 1340, - 1348, 1349, 1352, 1353, 1354, 1355, 1356, 1357, 1358, 1359, - 1360, 1361, 1362, 1365, 1374, 1378, 1382, 1388, 1397, 1401, - 1405, 1414, 1418, 1424, 1430, 1437, 1442, 1450, 1460, 1462, - 1470, 1476, 1480, 1484, 1490, 1501, 1510, 1514, 1519, 1523, - 1527, 1531, 1537, 1544, 1548, 1554, 1562, 1573, 1580, 1584, - 1590, 1600, 1611, 1615, 1633, 1642, 1645, 1651, 1655, 1659, - 1665, 1676, 1681, 1686, 1691, 1696, 1701, 1709, 1712, 1717, - 1730, 1738, 1749, 1757, 1757, 1759, 1759, 1761, 1771, 1776, - 1783, 1793, 1802, 1807, 1814, 1824, 1834, 1846, 1846, 1847, - 1847, 1849, 1859, 1867, 1877, 1885, 1893, 1902, 1913, 1917, - 1923, 1924, 1925, 1928, 1928, 1931, 1966, 1970, 1970, 1973, - 1980, 1989, 2003, 2012, 2021, 2025, 2034, 2043, 2054, 2061, - 2066, 2075, 2087, 2090, 2099, 2110, 2111, 2112, 2115, 2116, - 2117, 2120, 2121, 2124, 2125, 2128, 2129, 2132, 2143, 2154, - 2165, 2191, 2192 -}; -#endif - -#if YYDEBUG || YYERROR_VERBOSE || YYTOKEN_TABLE -/* YYTNAME[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", "ARBvp_10", "ARBfp_10", "ADDRESS", - "ALIAS", "ATTRIB", "OPTION", "OUTPUT", "PARAM", "TEMP", "END", "BIN_OP", - "BINSC_OP", "SAMPLE_OP", "SCALAR_OP", "TRI_OP", "VECTOR_OP", "ARL", - "KIL", "SWZ", "TXD_OP", "INTEGER", "REAL", "AMBIENT", "ATTENUATION", - "BACK", "CLIP", "COLOR", "DEPTH", "DIFFUSE", "DIRECTION", "EMISSION", - "ENV", "EYE", "FOG", "FOGCOORD", "FRAGMENT", "FRONT", "HALF", "INVERSE", - "INVTRANS", "LIGHT", "LIGHTMODEL", "LIGHTPROD", "LOCAL", "MATERIAL", - "MAT_PROGRAM", "MATRIX", "MATRIXINDEX", "MODELVIEW", "MVP", "NORMAL", - "OBJECT", "PALETTE", "PARAMS", "PLANE", "POINT_TOK", "POINTSIZE", - "POSITION", "PRIMARY", "PROGRAM", "PROJECTION", "RANGE", "RESULT", "ROW", - "SCENECOLOR", "SECONDARY", "SHININESS", "SIZE_TOK", "SPECULAR", "SPOT", - "STATE", "TEXCOORD", "TEXENV", "TEXGEN", "TEXGEN_Q", "TEXGEN_R", - "TEXGEN_S", "TEXGEN_T", "TEXTURE", "TRANSPOSE", "TEXTURE_UNIT", "TEX_1D", - "TEX_2D", "TEX_3D", "TEX_CUBE", "TEX_RECT", "TEX_SHADOW1D", - "TEX_SHADOW2D", "TEX_SHADOWRECT", "TEX_ARRAY1D", "TEX_ARRAY2D", - "TEX_ARRAYSHADOW1D", "TEX_ARRAYSHADOW2D", "VERTEX", "VTXATTRIB", - "WEIGHT", "IDENTIFIER", "USED_IDENTIFIER", "MASK4", "MASK3", "MASK2", - "MASK1", "SWIZZLE", "DOT_DOT", "DOT", "';'", "','", "'|'", "'['", "']'", - "'+'", "'-'", "'('", "')'", "'='", "'{'", "'}'", "$accept", "program", - "language", "optionSequence", "option", "statementSequence", "statement", - "instruction", "ALU_instruction", "TexInstruction", "ARL_instruction", - "VECTORop_instruction", "SCALARop_instruction", "BINSCop_instruction", - "BINop_instruction", "TRIop_instruction", "SAMPLE_instruction", - "KIL_instruction", "TXD_instruction", "texImageUnit", "texTarget", - "SWZ_instruction", "scalarSrcReg", "scalarUse", "swizzleSrcReg", - "maskedDstReg", "maskedAddrReg", "extendedSwizzle", "extSwizComp", - "extSwizSel", "srcReg", "dstReg", "progParamArray", "progParamArrayMem", - "progParamArrayAbs", "progParamArrayRel", "addrRegRelOffset", - "addrRegPosOffset", "addrRegNegOffset", "addrReg", "addrComponent", - "addrWriteMask", "scalarSuffix", "swizzleSuffix", "optionalMask", - "optionalCcMask", "ccTest", "ccTest2", "ccMaskRule", "ccMaskRule2", - "namingStatement", "ATTRIB_statement", "attribBinding", "vtxAttribItem", - "vtxAttribNum", "vtxOptWeightNum", "vtxWeightNum", "fragAttribItem", - "PARAM_statement", "PARAM_singleStmt", "PARAM_multipleStmt", - "optArraySize", "paramSingleInit", "paramMultipleInit", - "paramMultInitList", "paramSingleItemDecl", "paramSingleItemUse", - "paramMultipleItem", "stateMultipleItem", "stateSingleItem", - "stateMaterialItem", "stateMatProperty", "stateLightItem", - "stateLightProperty", "stateSpotProperty", "stateLightModelItem", - "stateLModProperty", "stateLightProdItem", "stateLProdProperty", - "stateTexEnvItem", "stateTexEnvProperty", "ambDiffSpecProperty", - "stateLightNumber", "stateTexGenItem", "stateTexGenType", - "stateTexGenCoord", "stateFogItem", "stateFogProperty", - "stateClipPlaneItem", "stateClipPlaneNum", "statePointItem", - "statePointProperty", "stateMatrixRow", "stateMatrixRows", - "optMatrixRows", "stateMatrixItem", "stateOptMatModifier", - "stateMatModifier", "stateMatrixRowNum", "stateMatrixName", - "stateOptModMatNum", "stateModMatNum", "statePaletteMatNum", - "stateProgramMatNum", "stateDepthItem", "programSingleItem", - "programMultipleItem", "progEnvParams", "progEnvParamNums", - "progEnvParam", "progLocalParams", "progLocalParamNums", - "progLocalParam", "progEnvParamNum", "progLocalParamNum", - "paramConstDecl", "paramConstUse", "paramConstScalarDecl", - "paramConstScalarUse", "paramConstVector", "signedFloatConstant", - "optionalSign", "TEMP_statement", "@1", "optVarSize", - "ADDRESS_statement", "@2", "varNameList", "OUTPUT_statement", - "resultBinding", "resultColBinding", "optResultFaceType", - "optResultColorType", "optFaceType", "optColorType", - "optTexCoordUnitNum", "optTexImageUnitNum", "optLegacyTexUnitNum", - "texCoordUnitNum", "texImageUnitNum", "legacyTexUnitNum", - "ALIAS_statement", "string", 0 -}; -#endif - -# ifdef YYPRINT -/* YYTOKNUM[YYLEX-NUM] -- Internal token number corresponding to - token YYLEX-NUM. */ -static const yytype_uint16 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, 348, 349, 350, 351, 352, 353, 354, - 355, 356, 357, 358, 359, 360, 361, 362, 59, 44, - 124, 91, 93, 43, 45, 40, 41, 61, 123, 125 -}; -# endif - -/* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */ -static const yytype_uint16 yyr1[] = -{ - 0, 120, 121, 122, 122, 123, 123, 124, 125, 125, - 126, 126, 127, 127, 128, 128, 128, 128, 128, 128, - 128, 129, 129, 129, 130, 131, 132, 133, 134, 135, - 136, 137, 137, 138, 139, 140, 140, 140, 140, 140, - 140, 140, 140, 140, 140, 140, 140, 141, 142, 142, - 143, 143, 144, 144, 145, 146, 147, 148, 149, 149, - 150, 150, 150, 150, 151, 151, 152, 153, 153, 154, - 155, 156, 156, 156, 157, 158, 159, 160, 161, 162, - 163, 163, 163, 163, 164, 164, 164, 164, 164, 165, - 165, 165, 166, 167, 168, 169, 170, 170, 170, 170, - 170, 170, 171, 172, 172, 173, 173, 173, 173, 173, - 173, 173, 173, 174, 175, 175, 176, 177, 177, 177, - 177, 178, 178, 179, 180, 181, 181, 182, 183, 184, - 184, 185, 185, 185, 186, 186, 186, 187, 187, 187, - 188, 188, 189, 189, 189, 189, 189, 189, 189, 189, - 189, 189, 189, 190, 191, 191, 191, 192, 193, 193, - 193, 193, 193, 194, 195, 196, 196, 197, 198, 199, - 200, 201, 201, 201, 202, 203, 204, 204, 205, 205, - 205, 205, 206, 207, 207, 208, 209, 210, 211, 211, - 212, 213, 214, 214, 215, 216, 216, 217, 217, 217, - 218, 219, 219, 219, 219, 219, 219, 220, 220, 221, - 222, 223, 224, 225, 225, 226, 226, 227, 228, 228, - 229, 230, 231, 231, 232, 233, 234, 235, 235, 236, - 236, 237, 238, 238, 239, 239, 239, 239, 240, 240, - 241, 241, 241, 243, 242, 244, 244, 246, 245, 247, - 247, 248, 249, 249, 249, 249, 249, 249, 250, 251, - 251, 251, 252, 252, 252, 253, 253, 253, 254, 254, - 254, 255, 255, 256, 256, 257, 257, 258, 259, 260, - 261, 262, 262 -}; - -/* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN. */ -static const yytype_uint8 yyr2[] = -{ - 0, 2, 4, 1, 1, 2, 0, 3, 2, 0, - 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 4, 4, 4, 6, 6, 8, - 8, 2, 2, 12, 2, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 6, 2, 4, - 2, 1, 3, 5, 3, 2, 7, 2, 1, 1, - 1, 1, 4, 1, 1, 1, 1, 1, 1, 1, - 3, 0, 2, 2, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 0, 1, 1, 1, 1, 0, 3, - 3, 0, 2, 2, 1, 1, 1, 1, 1, 1, - 1, 1, 4, 2, 2, 1, 2, 1, 2, 1, - 2, 4, 4, 1, 0, 3, 1, 1, 2, 1, - 2, 1, 1, 3, 6, 0, 1, 2, 4, 1, - 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 3, 1, 1, 1, 5, 1, 1, - 1, 2, 1, 1, 2, 1, 2, 6, 1, 3, - 1, 1, 1, 1, 1, 4, 1, 1, 1, 1, - 1, 1, 2, 1, 1, 5, 1, 2, 1, 1, - 5, 2, 0, 6, 3, 0, 1, 1, 1, 1, - 1, 2, 1, 1, 2, 4, 4, 0, 3, 1, - 1, 1, 2, 1, 1, 1, 1, 5, 1, 3, - 5, 5, 1, 3, 5, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 3, 5, 7, 9, 2, 2, - 1, 1, 0, 0, 4, 1, 0, 0, 3, 3, - 1, 5, 2, 2, 2, 2, 3, 2, 3, 0, - 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, - 1, 0, 3, 0, 3, 0, 3, 1, 1, 1, - 4, 1, 1 -}; - -/* 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 yytype_uint16 yydefact[] = -{ - 0, 3, 4, 0, 6, 1, 9, 0, 5, 246, - 281, 282, 0, 247, 0, 0, 0, 2, 0, 0, - 0, 0, 0, 0, 0, 242, 0, 0, 8, 0, - 12, 13, 14, 15, 16, 17, 18, 19, 21, 22, - 23, 20, 0, 96, 97, 121, 122, 98, 0, 99, - 100, 101, 245, 7, 0, 0, 0, 0, 0, 65, - 0, 88, 64, 0, 0, 0, 0, 0, 76, 0, - 0, 94, 240, 241, 31, 32, 83, 0, 0, 0, - 10, 11, 0, 243, 250, 248, 0, 0, 125, 242, - 123, 259, 257, 253, 255, 252, 271, 254, 242, 84, - 85, 86, 87, 91, 242, 242, 242, 242, 242, 242, - 78, 55, 81, 80, 82, 92, 233, 232, 0, 0, - 0, 0, 60, 0, 242, 83, 0, 61, 63, 134, - 135, 213, 214, 136, 229, 230, 0, 242, 0, 0, - 0, 280, 102, 126, 0, 127, 131, 132, 133, 227, - 228, 231, 0, 261, 260, 262, 0, 256, 0, 0, - 54, 0, 0, 0, 26, 0, 25, 24, 268, 119, - 117, 271, 104, 0, 0, 0, 0, 0, 0, 265, - 0, 265, 0, 0, 275, 271, 142, 143, 144, 145, - 147, 146, 148, 149, 150, 151, 0, 152, 268, 109, - 0, 107, 105, 271, 0, 114, 103, 83, 0, 52, - 0, 0, 0, 0, 244, 249, 0, 239, 238, 263, - 264, 258, 277, 0, 242, 95, 0, 0, 83, 242, - 0, 48, 0, 51, 0, 242, 269, 270, 118, 120, - 0, 0, 0, 212, 183, 184, 182, 0, 165, 267, - 266, 164, 0, 0, 0, 0, 207, 203, 0, 202, - 271, 195, 189, 188, 187, 0, 0, 0, 0, 108, - 0, 110, 0, 0, 106, 0, 242, 234, 69, 0, - 67, 68, 0, 242, 242, 251, 0, 124, 272, 28, - 89, 90, 93, 27, 0, 79, 50, 273, 0, 0, - 225, 0, 226, 0, 186, 0, 174, 0, 166, 0, - 171, 172, 155, 156, 173, 153, 154, 0, 0, 201, - 0, 204, 197, 199, 198, 194, 196, 279, 0, 170, - 169, 176, 177, 0, 0, 116, 0, 113, 0, 0, - 53, 0, 62, 77, 71, 47, 0, 0, 0, 242, - 49, 0, 34, 0, 242, 220, 224, 0, 0, 265, - 211, 0, 209, 0, 210, 0, 276, 181, 180, 178, - 179, 175, 200, 0, 111, 112, 115, 242, 235, 0, - 0, 70, 242, 58, 57, 59, 242, 0, 0, 0, - 129, 137, 140, 138, 215, 216, 139, 278, 0, 35, - 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, - 46, 30, 29, 185, 160, 162, 159, 0, 157, 158, - 0, 206, 208, 205, 190, 0, 74, 72, 75, 73, - 0, 0, 0, 0, 141, 192, 242, 128, 274, 163, - 161, 167, 168, 242, 236, 242, 0, 0, 0, 0, - 191, 130, 0, 0, 0, 0, 218, 0, 222, 0, - 237, 242, 0, 217, 0, 221, 0, 0, 56, 33, - 219, 223, 0, 0, 193 -}; - -/* YYDEFGOTO[NTERM-NUM]. */ -static const yytype_int16 yydefgoto[] = -{ - -1, 3, 4, 6, 8, 9, 28, 29, 30, 31, - 32, 33, 34, 35, 36, 37, 38, 39, 40, 298, - 411, 41, 161, 231, 74, 60, 69, 345, 346, 384, - 232, 61, 126, 279, 280, 281, 381, 427, 429, 70, - 344, 111, 296, 115, 103, 160, 75, 227, 76, 228, - 42, 43, 127, 206, 338, 274, 336, 172, 44, 45, - 46, 144, 90, 287, 389, 145, 128, 390, 391, 129, - 186, 315, 187, 418, 440, 188, 251, 189, 441, 190, - 330, 316, 307, 191, 333, 371, 192, 246, 193, 305, - 194, 264, 195, 434, 450, 196, 325, 326, 373, 261, - 319, 363, 365, 361, 197, 130, 393, 394, 455, 131, - 395, 457, 132, 301, 303, 396, 133, 149, 134, 135, - 151, 77, 47, 139, 48, 49, 54, 85, 50, 62, - 97, 155, 221, 252, 238, 157, 352, 266, 223, 398, - 328, 51, 12 -}; - -/* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing - STATE-NUM. */ -#define YYPACT_NINF -401 -static const yytype_int16 yypact[] = -{ - 193, -401, -401, 27, -401, -401, 62, 143, -401, 24, - -401, -401, -30, -401, -18, 12, 83, -401, 15, 15, - 15, 15, 15, 15, 67, 61, 15, 15, -401, 127, - -401, -401, -401, -401, -401, -401, -401, -401, -401, -401, - -401, -401, 144, -401, -401, -401, -401, -401, 204, -401, - -401, -401, -401, -401, 155, 136, 138, 34, 140, -401, - 147, 108, -401, 150, 156, 157, 158, 160, -401, 162, - 159, -401, -401, -401, -401, -401, 102, -13, 163, 164, - -401, -401, 165, -401, -401, 166, 170, 10, 235, 0, - -401, 141, -401, -401, -401, -401, 167, -401, 131, -401, - -401, -401, -401, 168, 131, 131, 131, 131, 131, 131, - -401, -401, -401, -401, -401, -401, -401, -401, 104, 97, - 114, 38, 169, 30, 131, 102, 171, -401, -401, -401, - -401, -401, -401, -401, -401, -401, 30, 131, 172, 155, - 175, -401, -401, -401, 173, -401, -401, -401, -401, -401, - -401, -401, 223, -401, -401, 123, 253, -401, 177, 149, - -401, 178, -10, 181, -401, 182, -401, -401, 134, -401, - -401, 167, -401, 183, 184, 185, 213, 99, 186, 154, - 187, 146, 153, 7, 188, 167, -401, -401, -401, -401, - -401, -401, -401, -401, -401, -401, 215, -401, 134, -401, - 190, -401, -401, 167, 191, 192, -401, 102, -48, -401, - 1, 195, 196, 214, 166, -401, 189, -401, -401, -401, - -401, -401, -401, 180, 131, -401, 194, 197, 102, 131, - 30, -401, 203, 205, 201, 131, -401, -401, -401, -401, - 285, 288, 289, -401, -401, -401, -401, 291, -401, -401, - -401, -401, 248, 291, 33, 206, 207, -401, 208, -401, - 167, 14, -401, -401, -401, 293, 292, 92, 209, -401, - 299, -401, 301, 299, -401, 216, 131, -401, -401, 217, - -401, -401, 221, 131, 131, -401, 212, -401, -401, -401, - -401, -401, -401, -401, 218, -401, -401, 220, 224, 225, - -401, 226, -401, 227, -401, 228, -401, 230, -401, 231, - -401, -401, -401, -401, -401, -401, -401, 304, 309, -401, - 312, -401, -401, -401, -401, -401, -401, -401, 232, -401, - -401, -401, -401, 161, 313, -401, 233, -401, 234, 238, - -401, 13, -401, -401, 137, -401, 242, -15, 243, 3, - -401, 314, -401, 133, 131, -401, -401, 296, 94, 146, - -401, 245, -401, 246, -401, 247, -401, -401, -401, -401, - -401, -401, -401, 249, -401, -401, -401, 131, -401, 332, - 337, -401, 131, -401, -401, -401, 131, 142, 114, 28, - -401, -401, -401, -401, -401, -401, -401, -401, 250, -401, - -401, -401, -401, -401, -401, -401, -401, -401, -401, -401, - -401, -401, -401, -401, -401, -401, -401, 331, -401, -401, - 68, -401, -401, -401, -401, 43, -401, -401, -401, -401, - 255, 256, 257, 258, -401, 300, 3, -401, -401, -401, - -401, -401, -401, 131, -401, 131, 201, 285, 288, 259, - -401, -401, 252, 264, 265, 263, 261, 266, 270, 313, - -401, 131, 133, -401, 285, -401, 288, 80, -401, -401, - -401, -401, 313, 267, -401 -}; - -/* YYPGOTO[NTERM-NUM]. */ -static const yytype_int16 yypgoto[] = -{ - -401, -401, -401, -401, -401, -401, -401, -401, -401, -401, - -401, -401, -401, -401, -401, -401, -401, -401, -401, -69, - -82, -401, -100, 151, -86, 210, -401, -401, -366, -401, - -54, -401, -401, -401, -401, -401, -401, -401, -401, 174, - -401, -401, -401, -118, -401, -401, 229, -401, -401, -401, - -401, -401, 295, -401, -401, -401, 110, -401, -401, -401, - -401, -401, -401, -401, -401, -401, -401, -51, -401, -88, - -401, -401, -401, -401, -401, -401, -401, -401, -401, -401, - -401, -311, 139, -401, -401, -401, -401, -401, -401, -401, - -401, -401, -401, -401, -401, -2, -401, -401, -400, -401, - -401, -401, -401, -401, -401, 298, -401, -401, -401, -401, - -401, -401, -401, -390, -295, 302, -401, -401, -136, -87, - -120, -89, -401, -401, -401, -401, -401, 251, -401, 176, - -401, -401, -401, -176, 198, -153, -401, -401, -401, -401, - -401, -401, -6 -}; - -/* 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 -230 -static const yytype_int16 yytable[] = -{ - 152, 146, 150, 52, 208, 254, 164, 209, 383, 167, - 116, 117, 158, 116, 117, 162, 430, 162, 239, 163, - 162, 165, 166, 125, 278, 118, 233, 5, 118, 13, - 14, 15, 267, 262, 16, 152, 17, 18, 19, 20, - 21, 22, 23, 24, 25, 26, 27, 419, 118, 119, - 271, 212, 119, 116, 117, 322, 323, 456, 310, 467, - 120, 276, 119, 120, 311, 387, 312, 198, 118, 207, - 7, 277, 473, 120, 470, 199, 388, 263, 53, 453, - 58, 55, 211, 121, 10, 11, 121, 122, 200, 275, - 122, 201, 119, 310, 233, 468, 324, 123, 202, 311, - 230, 68, 313, 120, 314, 124, 121, 321, 124, 442, - 292, 56, 203, 72, 73, 59, 72, 73, 124, 310, - 414, 124, 377, 10, 11, 311, 121, 331, 244, 293, - 122, 173, 378, 168, 415, 204, 205, 436, 289, 314, - 162, 169, 175, 174, 176, 88, 332, 437, 124, 299, - 177, 89, 443, 458, 416, 245, 341, 178, 179, 180, - 71, 181, 444, 182, 170, 314, 417, 68, 153, 91, - 92, 471, 183, 249, 72, 73, 432, 93, 171, 248, - 154, 249, 57, 420, 219, 250, 472, 152, 433, 184, - 185, 220, 424, 250, 347, 236, 1, 2, 348, 94, - 95, 255, 237, 112, 256, 257, 113, 114, 258, 99, - 100, 101, 102, 82, 96, 83, 259, 399, 400, 401, - 402, 403, 404, 405, 406, 407, 408, 409, 410, 63, - 64, 65, 66, 67, 260, 80, 78, 79, 367, 368, - 369, 370, 10, 11, 72, 73, 217, 218, 71, 225, - 379, 380, 81, 86, 84, 87, 98, 425, 143, 104, - 152, 392, 150, 110, 138, 105, 106, 107, 412, 108, - 141, 109, 136, 137, 215, 140, 222, 243, 156, 58, - -66, 268, 210, 159, 297, 216, 224, 229, 152, 213, - 234, 235, 288, 347, 240, 241, 242, 247, 253, 265, - 431, 270, 272, 273, 283, 284, 286, 295, 300, -229, - 290, 302, 304, 291, 306, 308, 327, 317, 318, 320, - 334, 329, 335, 452, 337, 343, 340, 360, 350, 342, - 349, 351, 362, 353, 354, 364, 372, 397, 355, 356, - 357, 385, 358, 359, 366, 374, 375, 152, 392, 150, - 376, 382, 386, 413, 152, 426, 347, 421, 422, 423, - 428, 424, 438, 439, 445, 446, 449, 464, 447, 448, - 459, 460, 347, 461, 462, 463, 466, 454, 465, 474, - 469, 294, 142, 339, 282, 451, 435, 147, 226, 285, - 214, 148, 309, 0, 0, 0, 269 -}; - -static const yytype_int16 yycheck[] = -{ - 89, 89, 89, 9, 124, 181, 106, 125, 23, 109, - 23, 24, 98, 23, 24, 104, 382, 106, 171, 105, - 109, 107, 108, 77, 23, 38, 162, 0, 38, 5, - 6, 7, 185, 26, 10, 124, 12, 13, 14, 15, - 16, 17, 18, 19, 20, 21, 22, 358, 38, 62, - 203, 137, 62, 23, 24, 41, 42, 447, 25, 459, - 73, 109, 62, 73, 31, 62, 33, 29, 38, 123, - 8, 119, 472, 73, 464, 37, 73, 70, 108, 445, - 65, 99, 136, 96, 99, 100, 96, 100, 50, 207, - 100, 53, 62, 25, 230, 461, 82, 110, 60, 31, - 110, 100, 69, 73, 71, 118, 96, 260, 118, 420, - 228, 99, 74, 113, 114, 100, 113, 114, 118, 25, - 26, 118, 109, 99, 100, 31, 96, 35, 29, 229, - 100, 34, 119, 29, 40, 97, 98, 109, 224, 71, - 229, 37, 28, 46, 30, 111, 54, 119, 118, 235, - 36, 117, 109, 448, 60, 56, 276, 43, 44, 45, - 99, 47, 119, 49, 60, 71, 72, 100, 27, 29, - 30, 466, 58, 27, 113, 114, 34, 37, 74, 25, - 39, 27, 99, 359, 61, 39, 106, 276, 46, 75, - 76, 68, 112, 39, 283, 61, 3, 4, 284, 59, - 60, 48, 68, 101, 51, 52, 104, 105, 55, 101, - 102, 103, 104, 9, 74, 11, 63, 84, 85, 86, - 87, 88, 89, 90, 91, 92, 93, 94, 95, 19, - 20, 21, 22, 23, 81, 108, 26, 27, 77, 78, - 79, 80, 99, 100, 113, 114, 23, 24, 99, 100, - 113, 114, 108, 117, 99, 117, 109, 377, 23, 109, - 349, 349, 349, 104, 99, 109, 109, 109, 354, 109, - 100, 109, 109, 109, 99, 109, 23, 64, 111, 65, - 111, 66, 111, 115, 83, 112, 109, 109, 377, 117, - 109, 109, 112, 382, 111, 111, 111, 111, 111, 111, - 386, 111, 111, 111, 109, 109, 117, 104, 23, 104, - 116, 23, 23, 116, 23, 67, 23, 111, 111, 111, - 111, 29, 23, 443, 23, 104, 110, 23, 110, 112, - 118, 111, 23, 109, 109, 23, 23, 23, 112, 112, - 112, 347, 112, 112, 112, 112, 112, 436, 436, 436, - 112, 109, 109, 57, 443, 23, 445, 112, 112, 112, - 23, 112, 112, 32, 109, 109, 66, 106, 111, 111, - 111, 119, 461, 109, 109, 112, 106, 446, 112, 112, - 462, 230, 87, 273, 210, 436, 388, 89, 159, 213, - 139, 89, 253, -1, -1, -1, 198 -}; - -/* YYSTOS[STATE-NUM] -- The (internal number of the) accessing - symbol of state STATE-NUM. */ -static const yytype_uint16 yystos[] = -{ - 0, 3, 4, 121, 122, 0, 123, 8, 124, 125, - 99, 100, 262, 5, 6, 7, 10, 12, 13, 14, - 15, 16, 17, 18, 19, 20, 21, 22, 126, 127, - 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, - 138, 141, 170, 171, 178, 179, 180, 242, 244, 245, - 248, 261, 262, 108, 246, 99, 99, 99, 65, 100, - 145, 151, 249, 145, 145, 145, 145, 145, 100, 146, - 159, 99, 113, 114, 144, 166, 168, 241, 145, 145, - 108, 108, 9, 11, 99, 247, 117, 117, 111, 117, - 182, 29, 30, 37, 59, 60, 74, 250, 109, 101, - 102, 103, 104, 164, 109, 109, 109, 109, 109, 109, - 104, 161, 101, 104, 105, 163, 23, 24, 38, 62, - 73, 96, 100, 110, 118, 150, 152, 172, 186, 189, - 225, 229, 232, 236, 238, 239, 109, 109, 99, 243, - 109, 100, 172, 23, 181, 185, 189, 225, 235, 237, - 239, 240, 241, 27, 39, 251, 111, 255, 144, 115, - 165, 142, 241, 144, 142, 144, 144, 142, 29, 37, - 60, 74, 177, 34, 46, 28, 30, 36, 43, 44, - 45, 47, 49, 58, 75, 76, 190, 192, 195, 197, - 199, 203, 206, 208, 210, 212, 215, 224, 29, 37, - 50, 53, 60, 74, 97, 98, 173, 150, 240, 163, - 111, 150, 144, 117, 247, 99, 112, 23, 24, 61, - 68, 252, 23, 258, 109, 100, 166, 167, 169, 109, - 110, 143, 150, 238, 109, 109, 61, 68, 254, 255, - 111, 111, 111, 64, 29, 56, 207, 111, 25, 27, - 39, 196, 253, 111, 253, 48, 51, 52, 55, 63, - 81, 219, 26, 70, 211, 111, 257, 255, 66, 254, - 111, 255, 111, 111, 175, 163, 109, 119, 23, 153, - 154, 155, 159, 109, 109, 249, 117, 183, 112, 144, - 116, 116, 163, 142, 143, 104, 162, 83, 139, 144, - 23, 233, 23, 234, 23, 209, 23, 202, 67, 202, - 25, 31, 33, 69, 71, 191, 201, 111, 111, 220, - 111, 255, 41, 42, 82, 216, 217, 23, 260, 29, - 200, 35, 54, 204, 111, 23, 176, 23, 174, 176, - 110, 240, 112, 104, 160, 147, 148, 241, 144, 118, - 110, 111, 256, 109, 109, 112, 112, 112, 112, 112, - 23, 223, 23, 221, 23, 222, 112, 77, 78, 79, - 80, 205, 23, 218, 112, 112, 112, 109, 119, 113, - 114, 156, 109, 23, 149, 262, 109, 62, 73, 184, - 187, 188, 189, 226, 227, 230, 235, 23, 259, 84, - 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, - 95, 140, 144, 57, 26, 40, 60, 72, 193, 201, - 253, 112, 112, 112, 112, 240, 23, 157, 23, 158, - 148, 144, 34, 46, 213, 215, 109, 119, 112, 32, - 194, 198, 201, 109, 119, 109, 109, 111, 111, 66, - 214, 187, 240, 148, 139, 228, 233, 231, 234, 111, - 119, 109, 109, 112, 106, 112, 106, 218, 148, 140, - 233, 234, 106, 218, 112 -}; - -#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 yyerrorlab - - -/* 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 (1); \ - goto yybackup; \ - } \ - else \ - { \ - yyerror (&yylloc, state, YY_("syntax error: cannot back up")); \ - YYERROR; \ - } \ -while (YYID (0)) - - -#define YYTERROR 1 -#define YYERRCODE 256 - - -/* YYLLOC_DEFAULT -- Set CURRENT to span from RHS[1] to RHS[N]. - If N is 0, then set CURRENT to the empty location which ends - the previous symbol: RHS[0] (always defined). */ - -#define YYRHSLOC(Rhs, K) ((Rhs)[K]) -#ifndef YYLLOC_DEFAULT -# define YYLLOC_DEFAULT(Current, Rhs, N) \ - do \ - if (YYID (N)) \ - { \ - (Current).first_line = YYRHSLOC (Rhs, 1).first_line; \ - (Current).first_column = YYRHSLOC (Rhs, 1).first_column; \ - (Current).last_line = YYRHSLOC (Rhs, N).last_line; \ - (Current).last_column = YYRHSLOC (Rhs, N).last_column; \ - } \ - else \ - { \ - (Current).first_line = (Current).last_line = \ - YYRHSLOC (Rhs, 0).last_line; \ - (Current).first_column = (Current).last_column = \ - YYRHSLOC (Rhs, 0).last_column; \ - } \ - while (YYID (0)) -#endif - - -/* YY_LOCATION_PRINT -- Print the location on the stream. - This macro was not mandated originally: define only if we know - we won't break user code: when these are the locations we know. */ - -#ifndef YY_LOCATION_PRINT -# if YYLTYPE_IS_TRIVIAL -# define YY_LOCATION_PRINT(File, Loc) \ - fprintf (File, "%d.%d-%d.%d", \ - (Loc).first_line, (Loc).first_column, \ - (Loc).last_line, (Loc).last_column) -# else -# define YY_LOCATION_PRINT(File, Loc) ((void) 0) -# endif -#endif - - -/* YYLEX -- calling `yylex' with the right arguments. */ - -#ifdef YYLEX_PARAM -# define YYLEX yylex (&yylval, &yylloc, YYLEX_PARAM) -#else -# define YYLEX yylex (&yylval, &yylloc, scanner) -#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 (YYID (0)) - -# define YY_SYMBOL_PRINT(Title, Type, Value, Location) \ -do { \ - if (yydebug) \ - { \ - YYFPRINTF (stderr, "%s ", Title); \ - yy_symbol_print (stderr, \ - Type, Value, Location, state); \ - YYFPRINTF (stderr, "\n"); \ - } \ -} while (YYID (0)) - - -/*--------------------------------. -| Print this symbol on YYOUTPUT. | -`--------------------------------*/ - -/*ARGSUSED*/ -#if (defined __STDC__ || defined __C99__FUNC__ \ - || defined __cplusplus || defined _MSC_VER) -static void -yy_symbol_value_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep, YYLTYPE const * const yylocationp, struct asm_parser_state *state) -#else -static void -yy_symbol_value_print (yyoutput, yytype, yyvaluep, yylocationp, state) - FILE *yyoutput; - int yytype; - YYSTYPE const * const yyvaluep; - YYLTYPE const * const yylocationp; - struct asm_parser_state *state; -#endif -{ - if (!yyvaluep) - return; - YYUSE (yylocationp); - YYUSE (state); -# ifdef YYPRINT - if (yytype < YYNTOKENS) - YYPRINT (yyoutput, yytoknum[yytype], *yyvaluep); -# else - YYUSE (yyoutput); -# endif - switch (yytype) - { - default: - break; - } -} - - -/*--------------------------------. -| Print this symbol on YYOUTPUT. | -`--------------------------------*/ - -#if (defined __STDC__ || defined __C99__FUNC__ \ - || defined __cplusplus || defined _MSC_VER) -static void -yy_symbol_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep, YYLTYPE const * const yylocationp, struct asm_parser_state *state) -#else -static void -yy_symbol_print (yyoutput, yytype, yyvaluep, yylocationp, state) - FILE *yyoutput; - int yytype; - YYSTYPE const * const yyvaluep; - YYLTYPE const * const yylocationp; - struct asm_parser_state *state; -#endif -{ - if (yytype < YYNTOKENS) - YYFPRINTF (yyoutput, "token %s (", yytname[yytype]); - else - YYFPRINTF (yyoutput, "nterm %s (", yytname[yytype]); - - YY_LOCATION_PRINT (yyoutput, *yylocationp); - YYFPRINTF (yyoutput, ": "); - yy_symbol_value_print (yyoutput, yytype, yyvaluep, yylocationp, state); - YYFPRINTF (yyoutput, ")"); -} - -/*------------------------------------------------------------------. -| yy_stack_print -- Print the state stack from its BOTTOM up to its | -| TOP (included). | -`------------------------------------------------------------------*/ - -#if (defined __STDC__ || defined __C99__FUNC__ \ - || defined __cplusplus || defined _MSC_VER) -static void -yy_stack_print (yytype_int16 *yybottom, yytype_int16 *yytop) -#else -static void -yy_stack_print (yybottom, yytop) - yytype_int16 *yybottom; - yytype_int16 *yytop; -#endif -{ - YYFPRINTF (stderr, "Stack now"); - for (; yybottom <= yytop; yybottom++) - { - int yybot = *yybottom; - YYFPRINTF (stderr, " %d", yybot); - } - YYFPRINTF (stderr, "\n"); -} - -# define YY_STACK_PRINT(Bottom, Top) \ -do { \ - if (yydebug) \ - yy_stack_print ((Bottom), (Top)); \ -} while (YYID (0)) - - -/*------------------------------------------------. -| Report that the YYRULE is going to be reduced. | -`------------------------------------------------*/ - -#if (defined __STDC__ || defined __C99__FUNC__ \ - || defined __cplusplus || defined _MSC_VER) -static void -yy_reduce_print (YYSTYPE *yyvsp, YYLTYPE *yylsp, int yyrule, struct asm_parser_state *state) -#else -static void -yy_reduce_print (yyvsp, yylsp, yyrule, state) - YYSTYPE *yyvsp; - YYLTYPE *yylsp; - int yyrule; - struct asm_parser_state *state; -#endif -{ - int yynrhs = yyr2[yyrule]; - int yyi; - unsigned long int yylno = yyrline[yyrule]; - YYFPRINTF (stderr, "Reducing stack by rule %d (line %lu):\n", - yyrule - 1, yylno); - /* The symbols being reduced. */ - for (yyi = 0; yyi < yynrhs; yyi++) - { - YYFPRINTF (stderr, " $%d = ", yyi + 1); - yy_symbol_print (stderr, yyrhs[yyprhs[yyrule] + yyi], - &(yyvsp[(yyi + 1) - (yynrhs)]) - , &(yylsp[(yyi + 1) - (yynrhs)]) , state); - YYFPRINTF (stderr, "\n"); - } -} - -# define YY_REDUCE_PRINT(Rule) \ -do { \ - if (yydebug) \ - yy_reduce_print (yyvsp, yylsp, Rule, state); \ -} while (YYID (0)) - -/* Nonzero means print parse trace. It is left uninitialized so that - multiple parsers can coexist. */ -int yydebug; -#else /* !YYDEBUG */ -# define YYDPRINTF(Args) -# define YY_SYMBOL_PRINT(Title, Type, 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 - YYSTACK_ALLOC_MAXIMUM < YYSTACK_BYTES (YYMAXDEPTH) - evaluated with infinite-precision integer arithmetic. */ - -#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. */ -#if (defined __STDC__ || defined __C99__FUNC__ \ - || defined __cplusplus || defined _MSC_VER) -static YYSIZE_T -yystrlen (const char *yystr) -#else -static YYSIZE_T -yystrlen (yystr) - const char *yystr; -#endif -{ - YYSIZE_T yylen; - for (yylen = 0; yystr[yylen]; yylen++) - continue; - return yylen; -} -# 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. */ -#if (defined __STDC__ || defined __C99__FUNC__ \ - || defined __cplusplus || defined _MSC_VER) -static char * -yystpcpy (char *yydest, const char *yysrc) -#else -static char * -yystpcpy (yydest, yysrc) - char *yydest; - const char *yysrc; -#endif -{ - char *yyd = yydest; - const char *yys = yysrc; - - while ((*yyd++ = *yys++) != '\0') - continue; - - return yyd - 1; -} -# endif -# endif - -# ifndef yytnamerr -/* Copy to YYRES the contents of YYSTR after stripping away unnecessary - quotes and backslashes, so that it's suitable for yyerror. The - heuristic is that double-quoting is unnecessary unless the string - contains an apostrophe, a comma, or backslash (other than - backslash-backslash). YYSTR is taken from yytname. If YYRES is - null, do not copy; instead, return the length of what the result - would have been. */ -static YYSIZE_T -yytnamerr (char *yyres, const char *yystr) -{ - if (*yystr == '"') - { - YYSIZE_T yyn = 0; - char const *yyp = yystr; - - for (;;) - switch (*++yyp) - { - case '\'': - case ',': - goto do_not_strip_quotes; - - case '\\': - if (*++yyp != '\\') - goto do_not_strip_quotes; - /* Fall through. */ - default: - if (yyres) - yyres[yyn] = *yyp; - yyn++; - break; - - case '"': - if (yyres) - yyres[yyn] = '\0'; - return yyn; - } - do_not_strip_quotes: ; - } - - if (! yyres) - return yystrlen (yystr); - - return yystpcpy (yyres, yystr) - yyres; -} -# endif - -/* Copy into YYRESULT an error message about the unexpected token - YYCHAR while in state YYSTATE. Return the number of bytes copied, - including the terminating null byte. If YYRESULT is null, do not - copy anything; just return the number of bytes that would be - copied. As a special case, return 0 if an ordinary "syntax error" - message will do. Return YYSIZE_MAXIMUM if overflow occurs during - size calculation. */ -static YYSIZE_T -yysyntax_error (char *yyresult, int yystate, int yychar) -{ - int yyn = yypact[yystate]; - - if (! (YYPACT_NINF < yyn && yyn <= YYLAST)) - return 0; - else - { - int yytype = YYTRANSLATE (yychar); - YYSIZE_T yysize0 = yytnamerr (0, yytname[yytype]); - YYSIZE_T yysize = yysize0; - YYSIZE_T yysize1; - int yysize_overflow = 0; - enum { YYERROR_VERBOSE_ARGS_MAXIMUM = 5 }; - char const *yyarg[YYERROR_VERBOSE_ARGS_MAXIMUM]; - int yyx; - -# if 0 - /* This is so xgettext sees the translatable formats that are - constructed on the fly. */ - YY_("syntax error, unexpected %s"); - YY_("syntax error, unexpected %s, expecting %s"); - YY_("syntax error, unexpected %s, expecting %s or %s"); - YY_("syntax error, unexpected %s, expecting %s or %s or %s"); - YY_("syntax error, unexpected %s, expecting %s or %s or %s or %s"); -# endif - char *yyfmt; - char const *yyf; - static char const yyunexpected[] = "syntax error, unexpected %s"; - static char const yyexpecting[] = ", expecting %s"; - static char const yyor[] = " or %s"; - char yyformat[sizeof yyunexpected - + sizeof yyexpecting - 1 - + ((YYERROR_VERBOSE_ARGS_MAXIMUM - 2) - * (sizeof yyor - 1))]; - char const *yyprefix = yyexpecting; - - /* Start YYX at -YYN if negative to avoid negative indexes in - YYCHECK. */ - int yyxbegin = yyn < 0 ? -yyn : 0; - - /* Stay within bounds of both yycheck and yytname. */ - int yychecklim = YYLAST - yyn + 1; - int yyxend = yychecklim < YYNTOKENS ? yychecklim : YYNTOKENS; - int yycount = 1; - - yyarg[0] = yytname[yytype]; - yyfmt = yystpcpy (yyformat, yyunexpected); - - for (yyx = yyxbegin; yyx < yyxend; ++yyx) - if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR) - { - if (yycount == YYERROR_VERBOSE_ARGS_MAXIMUM) - { - yycount = 1; - yysize = yysize0; - yyformat[sizeof yyunexpected - 1] = '\0'; - break; - } - yyarg[yycount++] = yytname[yyx]; - yysize1 = yysize + yytnamerr (0, yytname[yyx]); - yysize_overflow |= (yysize1 < yysize); - yysize = yysize1; - yyfmt = yystpcpy (yyfmt, yyprefix); - yyprefix = yyor; - } - - yyf = YY_(yyformat); - yysize1 = yysize + yystrlen (yyf); - yysize_overflow |= (yysize1 < yysize); - yysize = yysize1; - - if (yysize_overflow) - return YYSIZE_MAXIMUM; - - if (yyresult) - { - /* Avoid sprintf, as that infringes on the user's name space. - Don't have undefined behavior even if the translation - produced a string with the wrong number of "%s"s. */ - char *yyp = yyresult; - int yyi = 0; - while ((*yyp = *yyf) != '\0') - { - if (*yyp == '%' && yyf[1] == 's' && yyi < yycount) - { - yyp += yytnamerr (yyp, yyarg[yyi++]); - yyf += 2; - } - else - { - yyp++; - yyf++; - } - } - } - return yysize; - } -} -#endif /* YYERROR_VERBOSE */ - - -/*-----------------------------------------------. -| Release the memory associated to this symbol. | -`-----------------------------------------------*/ - -/*ARGSUSED*/ -#if (defined __STDC__ || defined __C99__FUNC__ \ - || defined __cplusplus || defined _MSC_VER) -static void -yydestruct (const char *yymsg, int yytype, YYSTYPE *yyvaluep, YYLTYPE *yylocationp, struct asm_parser_state *state) -#else -static void -yydestruct (yymsg, yytype, yyvaluep, yylocationp, state) - const char *yymsg; - int yytype; - YYSTYPE *yyvaluep; - YYLTYPE *yylocationp; - struct asm_parser_state *state; -#endif -{ - YYUSE (yyvaluep); - YYUSE (yylocationp); - YYUSE (state); - - if (!yymsg) - yymsg = "Deleting"; - YY_SYMBOL_PRINT (yymsg, yytype, yyvaluep, yylocationp); - - 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 (struct asm_parser_state *state); -#else -int yyparse (); -#endif -#endif /* ! YYPARSE_PARAM */ - - - - - -/*-------------------------. -| yyparse or yypush_parse. | -`-------------------------*/ - -#ifdef YYPARSE_PARAM -#if (defined __STDC__ || defined __C99__FUNC__ \ - || defined __cplusplus || defined _MSC_VER) -int -yyparse (void *YYPARSE_PARAM) -#else -int -yyparse (YYPARSE_PARAM) - void *YYPARSE_PARAM; -#endif -#else /* ! YYPARSE_PARAM */ -#if (defined __STDC__ || defined __C99__FUNC__ \ - || defined __cplusplus || defined _MSC_VER) -int -yyparse (struct asm_parser_state *state) -#else -int -yyparse (state) - struct asm_parser_state *state; -#endif -#endif -{ -/* The lookahead symbol. */ -int yychar; - -/* The semantic value of the lookahead symbol. */ -YYSTYPE yylval; - -/* Location data for the lookahead symbol. */ -YYLTYPE yylloc; - - /* Number of syntax errors so far. */ - int yynerrs; - - int yystate; - /* Number of tokens to shift before error messages enabled. */ - int yyerrstatus; - - /* The 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. */ - yytype_int16 yyssa[YYINITDEPTH]; - yytype_int16 *yyss; - yytype_int16 *yyssp; - - /* The semantic value stack. */ - YYSTYPE yyvsa[YYINITDEPTH]; - YYSTYPE *yyvs; - YYSTYPE *yyvsp; - - /* The location stack. */ - YYLTYPE yylsa[YYINITDEPTH]; - YYLTYPE *yyls; - YYLTYPE *yylsp; - - /* The locations where the error started and ended. */ - YYLTYPE yyerror_range[2]; - - YYSIZE_T yystacksize; - - int yyn; - int yyresult; - /* Lookahead token as an internal (translated) token number. */ - int yytoken; - /* The variables used to return semantic value and location from the - action routines. */ - YYSTYPE yyval; - YYLTYPE yyloc; - -#if YYERROR_VERBOSE - /* Buffer for error messages, and its allocated size. */ - char yymsgbuf[128]; - char *yymsg = yymsgbuf; - YYSIZE_T yymsg_alloc = sizeof yymsgbuf; -#endif - -#define YYPOPSTACK(N) (yyvsp -= (N), yyssp -= (N), yylsp -= (N)) - - /* The number of symbols on the RHS of the reduced rule. - Keep to zero when no symbol should be popped. */ - int yylen = 0; - - yytoken = 0; - yyss = yyssa; - yyvs = yyvsa; - yyls = yylsa; - yystacksize = YYINITDEPTH; - - 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; - yylsp = yyls; - -#if YYLTYPE_IS_TRIVIAL - /* Initialize the default location before parsing starts. */ - yylloc.first_line = yylloc.last_line = 1; - yylloc.first_column = yylloc.last_column = 1; -#endif - - 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; - yytype_int16 *yyss1 = yyss; - YYLTYPE *yyls1 = yyls; - - /* 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 (YY_("memory exhausted"), - &yyss1, yysize * sizeof (*yyssp), - &yyvs1, yysize * sizeof (*yyvsp), - &yyls1, yysize * sizeof (*yylsp), - &yystacksize); - - yyls = yyls1; - yyss = yyss1; - yyvs = yyvs1; - } -#else /* no yyoverflow */ -# ifndef YYSTACK_RELOCATE - goto yyexhaustedlab; -# else - /* Extend the stack our own way. */ - if (YYMAXDEPTH <= yystacksize) - goto yyexhaustedlab; - yystacksize *= 2; - if (YYMAXDEPTH < yystacksize) - yystacksize = YYMAXDEPTH; - - { - yytype_int16 *yyss1 = yyss; - union yyalloc *yyptr = - (union yyalloc *) YYSTACK_ALLOC (YYSTACK_BYTES (yystacksize)); - if (! yyptr) - goto yyexhaustedlab; - YYSTACK_RELOCATE (yyss_alloc, yyss); - YYSTACK_RELOCATE (yyvs_alloc, yyvs); - YYSTACK_RELOCATE (yyls_alloc, yyls); -# undef YYSTACK_RELOCATE - if (yyss1 != yyssa) - YYSTACK_FREE (yyss1); - } -# endif -#endif /* no yyoverflow */ - - yyssp = yyss + yysize - 1; - yyvsp = yyvs + yysize - 1; - yylsp = yyls + 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)); - - if (yystate == YYFINAL) - YYACCEPT; - - 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. */ - - /* 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); - YY_SYMBOL_PRINT ("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; - } - - /* Count tokens shifted since error; after three, turn off error - status. */ - if (yyerrstatus) - yyerrstatus--; - - /* Shift the lookahead token. */ - YY_SYMBOL_PRINT ("Shifting", yytoken, &yylval, &yylloc); - - /* Discard the shifted token. */ - yychar = YYEMPTY; - - yystate = yyn; - *++yyvsp = yylval; - *++yylsp = yylloc; - 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]; - - /* Default location. */ - YYLLOC_DEFAULT (yyloc, (yylsp - yylen), yylen); - YY_REDUCE_PRINT (yyn); - switch (yyn) - { - case 3: - -/* Line 1455 of yacc.c */ -#line 282 "program_parse.y" - { - if (state->prog->Target != GL_VERTEX_PROGRAM_ARB) { - yyerror(& (yylsp[(1) - (1)]), state, "invalid fragment program header"); - - } - state->mode = ARB_vertex; - ;} - break; - - case 4: - -/* Line 1455 of yacc.c */ -#line 290 "program_parse.y" - { - if (state->prog->Target != GL_FRAGMENT_PROGRAM_ARB) { - yyerror(& (yylsp[(1) - (1)]), state, "invalid vertex program header"); - } - state->mode = ARB_fragment; - - state->option.TexRect = - (state->ctx->Extensions.NV_texture_rectangle != GL_FALSE); - ;} - break; - - case 7: - -/* Line 1455 of yacc.c */ -#line 306 "program_parse.y" - { - int valid = 0; - - if (state->mode == ARB_vertex) { - valid = _mesa_ARBvp_parse_option(state, (yyvsp[(2) - (3)].string)); - } else if (state->mode == ARB_fragment) { - valid = _mesa_ARBfp_parse_option(state, (yyvsp[(2) - (3)].string)); - } - - - free((yyvsp[(2) - (3)].string)); - - if (!valid) { - const char *const err_str = (state->mode == ARB_vertex) - ? "invalid ARB vertex program option" - : "invalid ARB fragment program option"; - - yyerror(& (yylsp[(2) - (3)]), state, err_str); - YYERROR; - } - ;} - break; - - case 10: - -/* Line 1455 of yacc.c */ -#line 334 "program_parse.y" - { - if ((yyvsp[(1) - (2)].inst) != NULL) { - if (state->inst_tail == NULL) { - state->inst_head = (yyvsp[(1) - (2)].inst); - } else { - state->inst_tail->next = (yyvsp[(1) - (2)].inst); - } - - state->inst_tail = (yyvsp[(1) - (2)].inst); - (yyvsp[(1) - (2)].inst)->next = NULL; - - state->prog->NumInstructions++; - } - ;} - break; - - case 12: - -/* Line 1455 of yacc.c */ -#line 352 "program_parse.y" - { - (yyval.inst) = (yyvsp[(1) - (1)].inst); - state->prog->NumAluInstructions++; - ;} - break; - - case 13: - -/* Line 1455 of yacc.c */ -#line 357 "program_parse.y" - { - (yyval.inst) = (yyvsp[(1) - (1)].inst); - state->prog->NumTexInstructions++; - ;} - break; - - case 24: - -/* Line 1455 of yacc.c */ -#line 378 "program_parse.y" - { - (yyval.inst) = asm_instruction_ctor(OPCODE_ARL, & (yyvsp[(2) - (4)].dst_reg), & (yyvsp[(4) - (4)].src_reg), NULL, NULL); - ;} - break; - - case 25: - -/* Line 1455 of yacc.c */ -#line 384 "program_parse.y" - { - (yyval.inst) = asm_instruction_copy_ctor(& (yyvsp[(1) - (4)].temp_inst), & (yyvsp[(2) - (4)].dst_reg), & (yyvsp[(4) - (4)].src_reg), NULL, NULL); - ;} - break; - - case 26: - -/* Line 1455 of yacc.c */ -#line 390 "program_parse.y" - { - (yyval.inst) = asm_instruction_copy_ctor(& (yyvsp[(1) - (4)].temp_inst), & (yyvsp[(2) - (4)].dst_reg), & (yyvsp[(4) - (4)].src_reg), NULL, NULL); - ;} - break; - - case 27: - -/* Line 1455 of yacc.c */ -#line 396 "program_parse.y" - { - (yyval.inst) = asm_instruction_copy_ctor(& (yyvsp[(1) - (6)].temp_inst), & (yyvsp[(2) - (6)].dst_reg), & (yyvsp[(4) - (6)].src_reg), & (yyvsp[(6) - (6)].src_reg), NULL); - ;} - break; - - case 28: - -/* Line 1455 of yacc.c */ -#line 403 "program_parse.y" - { - (yyval.inst) = asm_instruction_copy_ctor(& (yyvsp[(1) - (6)].temp_inst), & (yyvsp[(2) - (6)].dst_reg), & (yyvsp[(4) - (6)].src_reg), & (yyvsp[(6) - (6)].src_reg), NULL); - ;} - break; - - case 29: - -/* Line 1455 of yacc.c */ -#line 410 "program_parse.y" - { - (yyval.inst) = asm_instruction_copy_ctor(& (yyvsp[(1) - (8)].temp_inst), & (yyvsp[(2) - (8)].dst_reg), & (yyvsp[(4) - (8)].src_reg), & (yyvsp[(6) - (8)].src_reg), & (yyvsp[(8) - (8)].src_reg)); - ;} - break; - - case 30: - -/* Line 1455 of yacc.c */ -#line 416 "program_parse.y" - { - (yyval.inst) = asm_instruction_copy_ctor(& (yyvsp[(1) - (8)].temp_inst), & (yyvsp[(2) - (8)].dst_reg), & (yyvsp[(4) - (8)].src_reg), NULL, NULL); - if ((yyval.inst) != NULL) { - const GLbitfield tex_mask = (1U << (yyvsp[(6) - (8)].integer)); - GLbitfield shadow_tex = 0; - GLbitfield target_mask = 0; - - - (yyval.inst)->Base.TexSrcUnit = (yyvsp[(6) - (8)].integer); - - if ((yyvsp[(8) - (8)].integer) < 0) { - shadow_tex = tex_mask; - - (yyval.inst)->Base.TexSrcTarget = -(yyvsp[(8) - (8)].integer); - (yyval.inst)->Base.TexShadow = 1; - } else { - (yyval.inst)->Base.TexSrcTarget = (yyvsp[(8) - (8)].integer); - } - - target_mask = (1U << (yyval.inst)->Base.TexSrcTarget); - - /* If this texture unit was previously accessed and that access - * had a different texture target, generate an error. - * - * If this texture unit was previously accessed and that access - * had a different shadow mode, generate an error. - */ - if ((state->prog->TexturesUsed[(yyvsp[(6) - (8)].integer)] != 0) - && ((state->prog->TexturesUsed[(yyvsp[(6) - (8)].integer)] != target_mask) - || ((state->prog->ShadowSamplers & tex_mask) - != shadow_tex))) { - yyerror(& (yylsp[(8) - (8)]), state, - "multiple targets used on one texture image unit"); - YYERROR; - } - - - state->prog->TexturesUsed[(yyvsp[(6) - (8)].integer)] |= target_mask; - state->prog->ShadowSamplers |= shadow_tex; - } - ;} - break; - - case 31: - -/* Line 1455 of yacc.c */ -#line 460 "program_parse.y" - { - (yyval.inst) = asm_instruction_ctor(OPCODE_KIL, NULL, & (yyvsp[(2) - (2)].src_reg), NULL, NULL); - state->fragment.UsesKill = 1; - ;} - break; - - case 32: - -/* Line 1455 of yacc.c */ -#line 465 "program_parse.y" - { - (yyval.inst) = asm_instruction_ctor(OPCODE_KIL_NV, NULL, NULL, NULL, NULL); - (yyval.inst)->Base.DstReg.CondMask = (yyvsp[(2) - (2)].dst_reg).CondMask; - (yyval.inst)->Base.DstReg.CondSwizzle = (yyvsp[(2) - (2)].dst_reg).CondSwizzle; - (yyval.inst)->Base.DstReg.CondSrc = (yyvsp[(2) - (2)].dst_reg).CondSrc; - state->fragment.UsesKill = 1; - ;} - break; - - case 33: - -/* Line 1455 of yacc.c */ -#line 475 "program_parse.y" - { - (yyval.inst) = asm_instruction_copy_ctor(& (yyvsp[(1) - (12)].temp_inst), & (yyvsp[(2) - (12)].dst_reg), & (yyvsp[(4) - (12)].src_reg), & (yyvsp[(6) - (12)].src_reg), & (yyvsp[(8) - (12)].src_reg)); - if ((yyval.inst) != NULL) { - const GLbitfield tex_mask = (1U << (yyvsp[(10) - (12)].integer)); - GLbitfield shadow_tex = 0; - GLbitfield target_mask = 0; - - - (yyval.inst)->Base.TexSrcUnit = (yyvsp[(10) - (12)].integer); - - if ((yyvsp[(12) - (12)].integer) < 0) { - shadow_tex = tex_mask; - - (yyval.inst)->Base.TexSrcTarget = -(yyvsp[(12) - (12)].integer); - (yyval.inst)->Base.TexShadow = 1; - } else { - (yyval.inst)->Base.TexSrcTarget = (yyvsp[(12) - (12)].integer); - } - - target_mask = (1U << (yyval.inst)->Base.TexSrcTarget); - - /* If this texture unit was previously accessed and that access - * had a different texture target, generate an error. - * - * If this texture unit was previously accessed and that access - * had a different shadow mode, generate an error. - */ - if ((state->prog->TexturesUsed[(yyvsp[(10) - (12)].integer)] != 0) - && ((state->prog->TexturesUsed[(yyvsp[(10) - (12)].integer)] != target_mask) - || ((state->prog->ShadowSamplers & tex_mask) - != shadow_tex))) { - yyerror(& (yylsp[(12) - (12)]), state, - "multiple targets used on one texture image unit"); - YYERROR; - } - - - state->prog->TexturesUsed[(yyvsp[(10) - (12)].integer)] |= target_mask; - state->prog->ShadowSamplers |= shadow_tex; - } - ;} - break; - - case 34: - -/* Line 1455 of yacc.c */ -#line 519 "program_parse.y" - { - (yyval.integer) = (yyvsp[(2) - (2)].integer); - ;} - break; - - case 35: - -/* Line 1455 of yacc.c */ -#line 524 "program_parse.y" - { (yyval.integer) = TEXTURE_1D_INDEX; ;} - break; - - case 36: - -/* Line 1455 of yacc.c */ -#line 525 "program_parse.y" - { (yyval.integer) = TEXTURE_2D_INDEX; ;} - break; - - case 37: - -/* Line 1455 of yacc.c */ -#line 526 "program_parse.y" - { (yyval.integer) = TEXTURE_3D_INDEX; ;} - break; - - case 38: - -/* Line 1455 of yacc.c */ -#line 527 "program_parse.y" - { (yyval.integer) = TEXTURE_CUBE_INDEX; ;} - break; - - case 39: - -/* Line 1455 of yacc.c */ -#line 528 "program_parse.y" - { (yyval.integer) = TEXTURE_RECT_INDEX; ;} - break; - - case 40: - -/* Line 1455 of yacc.c */ -#line 529 "program_parse.y" - { (yyval.integer) = -TEXTURE_1D_INDEX; ;} - break; - - case 41: - -/* Line 1455 of yacc.c */ -#line 530 "program_parse.y" - { (yyval.integer) = -TEXTURE_2D_INDEX; ;} - break; - - case 42: - -/* Line 1455 of yacc.c */ -#line 531 "program_parse.y" - { (yyval.integer) = -TEXTURE_RECT_INDEX; ;} - break; - - case 43: - -/* Line 1455 of yacc.c */ -#line 532 "program_parse.y" - { (yyval.integer) = TEXTURE_1D_ARRAY_INDEX; ;} - break; - - case 44: - -/* Line 1455 of yacc.c */ -#line 533 "program_parse.y" - { (yyval.integer) = TEXTURE_2D_ARRAY_INDEX; ;} - break; - - case 45: - -/* Line 1455 of yacc.c */ -#line 534 "program_parse.y" - { (yyval.integer) = -TEXTURE_1D_ARRAY_INDEX; ;} - break; - - case 46: - -/* Line 1455 of yacc.c */ -#line 535 "program_parse.y" - { (yyval.integer) = -TEXTURE_2D_ARRAY_INDEX; ;} - break; - - case 47: - -/* Line 1455 of yacc.c */ -#line 539 "program_parse.y" - { - /* FIXME: Is this correct? Should the extenedSwizzle be applied - * FIXME: to the existing swizzle? - */ - (yyvsp[(4) - (6)].src_reg).Base.Swizzle = (yyvsp[(6) - (6)].swiz_mask).swizzle; - (yyvsp[(4) - (6)].src_reg).Base.Negate = (yyvsp[(6) - (6)].swiz_mask).mask; - - (yyval.inst) = asm_instruction_copy_ctor(& (yyvsp[(1) - (6)].temp_inst), & (yyvsp[(2) - (6)].dst_reg), & (yyvsp[(4) - (6)].src_reg), NULL, NULL); - ;} - break; - - case 48: - -/* Line 1455 of yacc.c */ -#line 551 "program_parse.y" - { - (yyval.src_reg) = (yyvsp[(2) - (2)].src_reg); - - if ((yyvsp[(1) - (2)].negate)) { - (yyval.src_reg).Base.Negate = ~(yyval.src_reg).Base.Negate; - } - ;} - break; - - case 49: - -/* Line 1455 of yacc.c */ -#line 559 "program_parse.y" - { - (yyval.src_reg) = (yyvsp[(3) - (4)].src_reg); - - if (!state->option.NV_fragment) { - yyerror(& (yylsp[(2) - (4)]), state, "unexpected character '|'"); - YYERROR; - } - - if ((yyvsp[(1) - (4)].negate)) { - (yyval.src_reg).Base.Negate = ~(yyval.src_reg).Base.Negate; - } - - (yyval.src_reg).Base.Abs = 1; - ;} - break; - - case 50: - -/* Line 1455 of yacc.c */ -#line 576 "program_parse.y" - { - (yyval.src_reg) = (yyvsp[(1) - (2)].src_reg); - - (yyval.src_reg).Base.Swizzle = _mesa_combine_swizzles((yyval.src_reg).Base.Swizzle, - (yyvsp[(2) - (2)].swiz_mask).swizzle); - ;} - break; - - case 51: - -/* Line 1455 of yacc.c */ -#line 583 "program_parse.y" - { - struct asm_symbol temp_sym; - - if (!state->option.NV_fragment) { - yyerror(& (yylsp[(1) - (1)]), state, "expected scalar suffix"); - YYERROR; - } - - memset(& temp_sym, 0, sizeof(temp_sym)); - temp_sym.param_binding_begin = ~0; - initialize_symbol_from_const(state->prog, & temp_sym, & (yyvsp[(1) - (1)].vector), GL_TRUE); - - set_src_reg_swz(& (yyval.src_reg), PROGRAM_CONSTANT, - temp_sym.param_binding_begin, - temp_sym.param_binding_swizzle); - ;} - break; - - case 52: - -/* Line 1455 of yacc.c */ -#line 602 "program_parse.y" - { - (yyval.src_reg) = (yyvsp[(2) - (3)].src_reg); - - if ((yyvsp[(1) - (3)].negate)) { - (yyval.src_reg).Base.Negate = ~(yyval.src_reg).Base.Negate; - } - - (yyval.src_reg).Base.Swizzle = _mesa_combine_swizzles((yyval.src_reg).Base.Swizzle, - (yyvsp[(3) - (3)].swiz_mask).swizzle); - ;} - break; - - case 53: - -/* Line 1455 of yacc.c */ -#line 613 "program_parse.y" - { - (yyval.src_reg) = (yyvsp[(3) - (5)].src_reg); - - if (!state->option.NV_fragment) { - yyerror(& (yylsp[(2) - (5)]), state, "unexpected character '|'"); - YYERROR; - } - - if ((yyvsp[(1) - (5)].negate)) { - (yyval.src_reg).Base.Negate = ~(yyval.src_reg).Base.Negate; - } - - (yyval.src_reg).Base.Abs = 1; - (yyval.src_reg).Base.Swizzle = _mesa_combine_swizzles((yyval.src_reg).Base.Swizzle, - (yyvsp[(4) - (5)].swiz_mask).swizzle); - ;} - break; - - case 54: - -/* Line 1455 of yacc.c */ -#line 633 "program_parse.y" - { - (yyval.dst_reg) = (yyvsp[(1) - (3)].dst_reg); - (yyval.dst_reg).WriteMask = (yyvsp[(2) - (3)].swiz_mask).mask; - (yyval.dst_reg).CondMask = (yyvsp[(3) - (3)].dst_reg).CondMask; - (yyval.dst_reg).CondSwizzle = (yyvsp[(3) - (3)].dst_reg).CondSwizzle; - (yyval.dst_reg).CondSrc = (yyvsp[(3) - (3)].dst_reg).CondSrc; - - if ((yyval.dst_reg).File == PROGRAM_OUTPUT) { - /* Technically speaking, this should check that it is in - * vertex program mode. However, PositionInvariant can never be - * set in fragment program mode, so it is somewhat irrelevant. - */ - if (state->option.PositionInvariant - && ((yyval.dst_reg).Index == VERT_RESULT_HPOS)) { - yyerror(& (yylsp[(1) - (3)]), state, "position-invariant programs cannot " - "write position"); - YYERROR; - } - - state->prog->OutputsWritten |= BITFIELD64_BIT((yyval.dst_reg).Index); - } - ;} - break; - - case 55: - -/* Line 1455 of yacc.c */ -#line 658 "program_parse.y" - { - set_dst_reg(& (yyval.dst_reg), PROGRAM_ADDRESS, 0); - (yyval.dst_reg).WriteMask = (yyvsp[(2) - (2)].swiz_mask).mask; - ;} - break; - - case 56: - -/* Line 1455 of yacc.c */ -#line 665 "program_parse.y" - { - const unsigned xyzw_valid = - ((yyvsp[(1) - (7)].ext_swizzle).xyzw_valid << 0) - | ((yyvsp[(3) - (7)].ext_swizzle).xyzw_valid << 1) - | ((yyvsp[(5) - (7)].ext_swizzle).xyzw_valid << 2) - | ((yyvsp[(7) - (7)].ext_swizzle).xyzw_valid << 3); - const unsigned rgba_valid = - ((yyvsp[(1) - (7)].ext_swizzle).rgba_valid << 0) - | ((yyvsp[(3) - (7)].ext_swizzle).rgba_valid << 1) - | ((yyvsp[(5) - (7)].ext_swizzle).rgba_valid << 2) - | ((yyvsp[(7) - (7)].ext_swizzle).rgba_valid << 3); - - /* All of the swizzle components have to be valid in either RGBA - * or XYZW. Note that 0 and 1 are valid in both, so both masks - * can have some bits set. - * - * We somewhat deviate from the spec here. It would be really hard - * to figure out which component is the error, and there probably - * isn't a lot of benefit. - */ - if ((rgba_valid != 0x0f) && (xyzw_valid != 0x0f)) { - yyerror(& (yylsp[(1) - (7)]), state, "cannot combine RGBA and XYZW swizzle " - "components"); - YYERROR; - } - - (yyval.swiz_mask).swizzle = MAKE_SWIZZLE4((yyvsp[(1) - (7)].ext_swizzle).swz, (yyvsp[(3) - (7)].ext_swizzle).swz, (yyvsp[(5) - (7)].ext_swizzle).swz, (yyvsp[(7) - (7)].ext_swizzle).swz); - (yyval.swiz_mask).mask = ((yyvsp[(1) - (7)].ext_swizzle).negate) | ((yyvsp[(3) - (7)].ext_swizzle).negate << 1) | ((yyvsp[(5) - (7)].ext_swizzle).negate << 2) - | ((yyvsp[(7) - (7)].ext_swizzle).negate << 3); - ;} - break; - - case 57: - -/* Line 1455 of yacc.c */ -#line 698 "program_parse.y" - { - (yyval.ext_swizzle) = (yyvsp[(2) - (2)].ext_swizzle); - (yyval.ext_swizzle).negate = ((yyvsp[(1) - (2)].negate)) ? 1 : 0; - ;} - break; - - case 58: - -/* Line 1455 of yacc.c */ -#line 705 "program_parse.y" - { - if (((yyvsp[(1) - (1)].integer) != 0) && ((yyvsp[(1) - (1)].integer) != 1)) { - yyerror(& (yylsp[(1) - (1)]), state, "invalid extended swizzle selector"); - YYERROR; - } - - (yyval.ext_swizzle).swz = ((yyvsp[(1) - (1)].integer) == 0) ? SWIZZLE_ZERO : SWIZZLE_ONE; - - /* 0 and 1 are valid for both RGBA swizzle names and XYZW - * swizzle names. - */ - (yyval.ext_swizzle).xyzw_valid = 1; - (yyval.ext_swizzle).rgba_valid = 1; - ;} - break; - - case 59: - -/* Line 1455 of yacc.c */ -#line 720 "program_parse.y" - { - char s; - - if (strlen((yyvsp[(1) - (1)].string)) > 1) { - yyerror(& (yylsp[(1) - (1)]), state, "invalid extended swizzle selector"); - YYERROR; - } - - s = (yyvsp[(1) - (1)].string)[0]; - free((yyvsp[(1) - (1)].string)); - - switch (s) { - case 'x': - (yyval.ext_swizzle).swz = SWIZZLE_X; - (yyval.ext_swizzle).xyzw_valid = 1; - break; - case 'y': - (yyval.ext_swizzle).swz = SWIZZLE_Y; - (yyval.ext_swizzle).xyzw_valid = 1; - break; - case 'z': - (yyval.ext_swizzle).swz = SWIZZLE_Z; - (yyval.ext_swizzle).xyzw_valid = 1; - break; - case 'w': - (yyval.ext_swizzle).swz = SWIZZLE_W; - (yyval.ext_swizzle).xyzw_valid = 1; - break; - - case 'r': - (yyval.ext_swizzle).swz = SWIZZLE_X; - (yyval.ext_swizzle).rgba_valid = 1; - break; - case 'g': - (yyval.ext_swizzle).swz = SWIZZLE_Y; - (yyval.ext_swizzle).rgba_valid = 1; - break; - case 'b': - (yyval.ext_swizzle).swz = SWIZZLE_Z; - (yyval.ext_swizzle).rgba_valid = 1; - break; - case 'a': - (yyval.ext_swizzle).swz = SWIZZLE_W; - (yyval.ext_swizzle).rgba_valid = 1; - break; - - default: - yyerror(& (yylsp[(1) - (1)]), state, "invalid extended swizzle selector"); - YYERROR; - break; - } - ;} - break; - - case 60: - -/* Line 1455 of yacc.c */ -#line 775 "program_parse.y" - { - struct asm_symbol *const s = (struct asm_symbol *) - _mesa_symbol_table_find_symbol(state->st, 0, (yyvsp[(1) - (1)].string)); - - free((yyvsp[(1) - (1)].string)); - - if (s == NULL) { - yyerror(& (yylsp[(1) - (1)]), state, "invalid operand variable"); - YYERROR; - } else if ((s->type != at_param) && (s->type != at_temp) - && (s->type != at_attrib)) { - yyerror(& (yylsp[(1) - (1)]), state, "invalid operand variable"); - YYERROR; - } else if ((s->type == at_param) && s->param_is_array) { - yyerror(& (yylsp[(1) - (1)]), state, "non-array access to array PARAM"); - YYERROR; - } - - init_src_reg(& (yyval.src_reg)); - switch (s->type) { - case at_temp: - set_src_reg(& (yyval.src_reg), PROGRAM_TEMPORARY, s->temp_binding); - break; - case at_param: - set_src_reg_swz(& (yyval.src_reg), s->param_binding_type, - s->param_binding_begin, - s->param_binding_swizzle); - break; - case at_attrib: - set_src_reg(& (yyval.src_reg), PROGRAM_INPUT, s->attrib_binding); - state->prog->InputsRead |= (1U << (yyval.src_reg).Base.Index); - - if (!validate_inputs(& (yylsp[(1) - (1)]), state)) { - YYERROR; - } - break; - - default: - YYERROR; - break; - } - ;} - break; - - case 61: - -/* Line 1455 of yacc.c */ -#line 818 "program_parse.y" - { - set_src_reg(& (yyval.src_reg), PROGRAM_INPUT, (yyvsp[(1) - (1)].attrib)); - state->prog->InputsRead |= (1U << (yyval.src_reg).Base.Index); - - if (!validate_inputs(& (yylsp[(1) - (1)]), state)) { - YYERROR; - } - ;} - break; - - case 62: - -/* Line 1455 of yacc.c */ -#line 827 "program_parse.y" - { - if (! (yyvsp[(3) - (4)].src_reg).Base.RelAddr - && ((unsigned) (yyvsp[(3) - (4)].src_reg).Base.Index >= (yyvsp[(1) - (4)].sym)->param_binding_length)) { - yyerror(& (yylsp[(3) - (4)]), state, "out of bounds array access"); - YYERROR; - } - - init_src_reg(& (yyval.src_reg)); - (yyval.src_reg).Base.File = (yyvsp[(1) - (4)].sym)->param_binding_type; - - if ((yyvsp[(3) - (4)].src_reg).Base.RelAddr) { - (yyvsp[(1) - (4)].sym)->param_accessed_indirectly = 1; - - (yyval.src_reg).Base.RelAddr = 1; - (yyval.src_reg).Base.Index = (yyvsp[(3) - (4)].src_reg).Base.Index; - (yyval.src_reg).Symbol = (yyvsp[(1) - (4)].sym); - } else { - (yyval.src_reg).Base.Index = (yyvsp[(1) - (4)].sym)->param_binding_begin + (yyvsp[(3) - (4)].src_reg).Base.Index; - } - ;} - break; - - case 63: - -/* Line 1455 of yacc.c */ -#line 848 "program_parse.y" - { - gl_register_file file = ((yyvsp[(1) - (1)].temp_sym).name != NULL) - ? (yyvsp[(1) - (1)].temp_sym).param_binding_type - : PROGRAM_CONSTANT; - set_src_reg_swz(& (yyval.src_reg), file, (yyvsp[(1) - (1)].temp_sym).param_binding_begin, - (yyvsp[(1) - (1)].temp_sym).param_binding_swizzle); - ;} - break; - - case 64: - -/* Line 1455 of yacc.c */ -#line 858 "program_parse.y" - { - set_dst_reg(& (yyval.dst_reg), PROGRAM_OUTPUT, (yyvsp[(1) - (1)].result)); - ;} - break; - - case 65: - -/* Line 1455 of yacc.c */ -#line 862 "program_parse.y" - { - struct asm_symbol *const s = (struct asm_symbol *) - _mesa_symbol_table_find_symbol(state->st, 0, (yyvsp[(1) - (1)].string)); - - free((yyvsp[(1) - (1)].string)); - - if (s == NULL) { - yyerror(& (yylsp[(1) - (1)]), state, "invalid operand variable"); - YYERROR; - } else if ((s->type != at_output) && (s->type != at_temp)) { - yyerror(& (yylsp[(1) - (1)]), state, "invalid operand variable"); - YYERROR; - } - - switch (s->type) { - case at_temp: - set_dst_reg(& (yyval.dst_reg), PROGRAM_TEMPORARY, s->temp_binding); - break; - case at_output: - set_dst_reg(& (yyval.dst_reg), PROGRAM_OUTPUT, s->output_binding); - break; - default: - set_dst_reg(& (yyval.dst_reg), s->param_binding_type, s->param_binding_begin); - break; - } - ;} - break; - - case 66: - -/* Line 1455 of yacc.c */ -#line 891 "program_parse.y" - { - struct asm_symbol *const s = (struct asm_symbol *) - _mesa_symbol_table_find_symbol(state->st, 0, (yyvsp[(1) - (1)].string)); - - free((yyvsp[(1) - (1)].string)); - - if (s == NULL) { - yyerror(& (yylsp[(1) - (1)]), state, "invalid operand variable"); - YYERROR; - } else if ((s->type != at_param) || !s->param_is_array) { - yyerror(& (yylsp[(1) - (1)]), state, "array access to non-PARAM variable"); - YYERROR; - } else { - (yyval.sym) = s; - } - ;} - break; - - case 69: - -/* Line 1455 of yacc.c */ -#line 912 "program_parse.y" - { - init_src_reg(& (yyval.src_reg)); - (yyval.src_reg).Base.Index = (yyvsp[(1) - (1)].integer); - ;} - break; - - case 70: - -/* Line 1455 of yacc.c */ -#line 919 "program_parse.y" - { - /* FINISHME: Add support for multiple address registers. - */ - /* FINISHME: Add support for 4-component address registers. - */ - init_src_reg(& (yyval.src_reg)); - (yyval.src_reg).Base.RelAddr = 1; - (yyval.src_reg).Base.Index = (yyvsp[(3) - (3)].integer); - ;} - break; - - case 71: - -/* Line 1455 of yacc.c */ -#line 930 "program_parse.y" - { (yyval.integer) = 0; ;} - break; - - case 72: - -/* Line 1455 of yacc.c */ -#line 931 "program_parse.y" - { (yyval.integer) = (yyvsp[(2) - (2)].integer); ;} - break; - - case 73: - -/* Line 1455 of yacc.c */ -#line 932 "program_parse.y" - { (yyval.integer) = -(yyvsp[(2) - (2)].integer); ;} - break; - - case 74: - -/* Line 1455 of yacc.c */ -#line 936 "program_parse.y" - { - if (((yyvsp[(1) - (1)].integer) < 0) || ((yyvsp[(1) - (1)].integer) > 63)) { - char s[100]; - _mesa_snprintf(s, sizeof(s), - "relative address offset too large (%d)", (yyvsp[(1) - (1)].integer)); - yyerror(& (yylsp[(1) - (1)]), state, s); - YYERROR; - } else { - (yyval.integer) = (yyvsp[(1) - (1)].integer); - } - ;} - break; - - case 75: - -/* Line 1455 of yacc.c */ -#line 950 "program_parse.y" - { - if (((yyvsp[(1) - (1)].integer) < 0) || ((yyvsp[(1) - (1)].integer) > 64)) { - char s[100]; - _mesa_snprintf(s, sizeof(s), - "relative address offset too large (%d)", (yyvsp[(1) - (1)].integer)); - yyerror(& (yylsp[(1) - (1)]), state, s); - YYERROR; - } else { - (yyval.integer) = (yyvsp[(1) - (1)].integer); - } - ;} - break; - - case 76: - -/* Line 1455 of yacc.c */ -#line 964 "program_parse.y" - { - struct asm_symbol *const s = (struct asm_symbol *) - _mesa_symbol_table_find_symbol(state->st, 0, (yyvsp[(1) - (1)].string)); - - free((yyvsp[(1) - (1)].string)); - - if (s == NULL) { - yyerror(& (yylsp[(1) - (1)]), state, "invalid array member"); - YYERROR; - } else if (s->type != at_address) { - yyerror(& (yylsp[(1) - (1)]), state, - "invalid variable for indexed array access"); - YYERROR; - } else { - (yyval.sym) = s; - } - ;} - break; - - case 77: - -/* Line 1455 of yacc.c */ -#line 984 "program_parse.y" - { - if ((yyvsp[(1) - (1)].swiz_mask).mask != WRITEMASK_X) { - yyerror(& (yylsp[(1) - (1)]), state, "invalid address component selector"); - YYERROR; - } else { - (yyval.swiz_mask) = (yyvsp[(1) - (1)].swiz_mask); - } - ;} - break; - - case 78: - -/* Line 1455 of yacc.c */ -#line 995 "program_parse.y" - { - if ((yyvsp[(1) - (1)].swiz_mask).mask != WRITEMASK_X) { - yyerror(& (yylsp[(1) - (1)]), state, - "address register write mask must be \".x\""); - YYERROR; - } else { - (yyval.swiz_mask) = (yyvsp[(1) - (1)].swiz_mask); - } - ;} - break; - - case 83: - -/* Line 1455 of yacc.c */ -#line 1011 "program_parse.y" - { (yyval.swiz_mask).swizzle = SWIZZLE_NOOP; (yyval.swiz_mask).mask = WRITEMASK_XYZW; ;} - break; - - case 88: - -/* Line 1455 of yacc.c */ -#line 1015 "program_parse.y" - { (yyval.swiz_mask).swizzle = SWIZZLE_NOOP; (yyval.swiz_mask).mask = WRITEMASK_XYZW; ;} - break; - - case 89: - -/* Line 1455 of yacc.c */ -#line 1019 "program_parse.y" - { - (yyval.dst_reg) = (yyvsp[(2) - (3)].dst_reg); - ;} - break; - - case 90: - -/* Line 1455 of yacc.c */ -#line 1023 "program_parse.y" - { - (yyval.dst_reg) = (yyvsp[(2) - (3)].dst_reg); - ;} - break; - - case 91: - -/* Line 1455 of yacc.c */ -#line 1027 "program_parse.y" - { - (yyval.dst_reg).CondMask = COND_TR; - (yyval.dst_reg).CondSwizzle = SWIZZLE_NOOP; - (yyval.dst_reg).CondSrc = 0; - ;} - break; - - case 92: - -/* Line 1455 of yacc.c */ -#line 1035 "program_parse.y" - { - (yyval.dst_reg) = (yyvsp[(1) - (2)].dst_reg); - (yyval.dst_reg).CondSwizzle = (yyvsp[(2) - (2)].swiz_mask).swizzle; - ;} - break; - - case 93: - -/* Line 1455 of yacc.c */ -#line 1042 "program_parse.y" - { - (yyval.dst_reg) = (yyvsp[(1) - (2)].dst_reg); - (yyval.dst_reg).CondSwizzle = (yyvsp[(2) - (2)].swiz_mask).swizzle; - ;} - break; - - case 94: - -/* Line 1455 of yacc.c */ -#line 1049 "program_parse.y" - { - const int cond = _mesa_parse_cc((yyvsp[(1) - (1)].string)); - if ((cond == 0) || ((yyvsp[(1) - (1)].string)[2] != '\0')) { - char *const err_str = - make_error_string("invalid condition code \"%s\"", (yyvsp[(1) - (1)].string)); - - yyerror(& (yylsp[(1) - (1)]), state, (err_str != NULL) - ? err_str : "invalid condition code"); - - if (err_str != NULL) { - free(err_str); - } - - YYERROR; - } - - (yyval.dst_reg).CondMask = cond; - (yyval.dst_reg).CondSwizzle = SWIZZLE_NOOP; - (yyval.dst_reg).CondSrc = 0; - ;} - break; - - case 95: - -/* Line 1455 of yacc.c */ -#line 1072 "program_parse.y" - { - const int cond = _mesa_parse_cc((yyvsp[(1) - (1)].string)); - if ((cond == 0) || ((yyvsp[(1) - (1)].string)[2] != '\0')) { - char *const err_str = - make_error_string("invalid condition code \"%s\"", (yyvsp[(1) - (1)].string)); - - yyerror(& (yylsp[(1) - (1)]), state, (err_str != NULL) - ? err_str : "invalid condition code"); - - if (err_str != NULL) { - free(err_str); - } - - YYERROR; - } - - (yyval.dst_reg).CondMask = cond; - (yyval.dst_reg).CondSwizzle = SWIZZLE_NOOP; - (yyval.dst_reg).CondSrc = 0; - ;} - break; - - case 102: - -/* Line 1455 of yacc.c */ -#line 1103 "program_parse.y" - { - struct asm_symbol *const s = - declare_variable(state, (yyvsp[(2) - (4)].string), at_attrib, & (yylsp[(2) - (4)])); - - if (s == NULL) { - free((yyvsp[(2) - (4)].string)); - YYERROR; - } else { - s->attrib_binding = (yyvsp[(4) - (4)].attrib); - state->InputsBound |= (1U << s->attrib_binding); - - if (!validate_inputs(& (yylsp[(4) - (4)]), state)) { - YYERROR; - } - } - ;} - break; - - case 103: - -/* Line 1455 of yacc.c */ -#line 1122 "program_parse.y" - { - (yyval.attrib) = (yyvsp[(2) - (2)].attrib); - ;} - break; - - case 104: - -/* Line 1455 of yacc.c */ -#line 1126 "program_parse.y" - { - (yyval.attrib) = (yyvsp[(2) - (2)].attrib); - ;} - break; - - case 105: - -/* Line 1455 of yacc.c */ -#line 1132 "program_parse.y" - { - (yyval.attrib) = VERT_ATTRIB_POS; - ;} - break; - - case 106: - -/* Line 1455 of yacc.c */ -#line 1136 "program_parse.y" - { - (yyval.attrib) = VERT_ATTRIB_WEIGHT; - ;} - break; - - case 107: - -/* Line 1455 of yacc.c */ -#line 1140 "program_parse.y" - { - (yyval.attrib) = VERT_ATTRIB_NORMAL; - ;} - break; - - case 108: - -/* Line 1455 of yacc.c */ -#line 1144 "program_parse.y" - { - if (!state->ctx->Extensions.EXT_secondary_color) { - yyerror(& (yylsp[(2) - (2)]), state, "GL_EXT_secondary_color not supported"); - YYERROR; - } - - (yyval.attrib) = VERT_ATTRIB_COLOR0 + (yyvsp[(2) - (2)].integer); - ;} - break; - - case 109: - -/* Line 1455 of yacc.c */ -#line 1153 "program_parse.y" - { - if (!state->ctx->Extensions.EXT_fog_coord) { - yyerror(& (yylsp[(1) - (1)]), state, "GL_EXT_fog_coord not supported"); - YYERROR; - } - - (yyval.attrib) = VERT_ATTRIB_FOG; - ;} - break; - - case 110: - -/* Line 1455 of yacc.c */ -#line 1162 "program_parse.y" - { - (yyval.attrib) = VERT_ATTRIB_TEX0 + (yyvsp[(2) - (2)].integer); - ;} - break; - - case 111: - -/* Line 1455 of yacc.c */ -#line 1166 "program_parse.y" - { - yyerror(& (yylsp[(1) - (4)]), state, "GL_ARB_matrix_palette not supported"); - YYERROR; - ;} - break; - - case 112: - -/* Line 1455 of yacc.c */ -#line 1171 "program_parse.y" - { - (yyval.attrib) = VERT_ATTRIB_GENERIC0 + (yyvsp[(3) - (4)].integer); - ;} - break; - - case 113: - -/* Line 1455 of yacc.c */ -#line 1177 "program_parse.y" - { - if ((unsigned) (yyvsp[(1) - (1)].integer) >= state->limits->MaxAttribs) { - yyerror(& (yylsp[(1) - (1)]), state, "invalid vertex attribute reference"); - YYERROR; - } - - (yyval.integer) = (yyvsp[(1) - (1)].integer); - ;} - break; - - case 117: - -/* Line 1455 of yacc.c */ -#line 1191 "program_parse.y" - { - (yyval.attrib) = FRAG_ATTRIB_WPOS; - ;} - break; - - case 118: - -/* Line 1455 of yacc.c */ -#line 1195 "program_parse.y" - { - (yyval.attrib) = FRAG_ATTRIB_COL0 + (yyvsp[(2) - (2)].integer); - ;} - break; - - case 119: - -/* Line 1455 of yacc.c */ -#line 1199 "program_parse.y" - { - (yyval.attrib) = FRAG_ATTRIB_FOGC; - ;} - break; - - case 120: - -/* Line 1455 of yacc.c */ -#line 1203 "program_parse.y" - { - (yyval.attrib) = FRAG_ATTRIB_TEX0 + (yyvsp[(2) - (2)].integer); - ;} - break; - - case 123: - -/* Line 1455 of yacc.c */ -#line 1211 "program_parse.y" - { - struct asm_symbol *const s = - declare_variable(state, (yyvsp[(2) - (3)].string), at_param, & (yylsp[(2) - (3)])); - - if (s == NULL) { - free((yyvsp[(2) - (3)].string)); - YYERROR; - } else { - s->param_binding_type = (yyvsp[(3) - (3)].temp_sym).param_binding_type; - s->param_binding_begin = (yyvsp[(3) - (3)].temp_sym).param_binding_begin; - s->param_binding_length = (yyvsp[(3) - (3)].temp_sym).param_binding_length; - s->param_binding_swizzle = SWIZZLE_XYZW; - s->param_is_array = 0; - } - ;} - break; - - case 124: - -/* Line 1455 of yacc.c */ -#line 1229 "program_parse.y" - { - if (((yyvsp[(4) - (6)].integer) != 0) && ((unsigned) (yyvsp[(4) - (6)].integer) != (yyvsp[(6) - (6)].temp_sym).param_binding_length)) { - free((yyvsp[(2) - (6)].string)); - yyerror(& (yylsp[(4) - (6)]), state, - "parameter array size and number of bindings must match"); - YYERROR; - } else { - struct asm_symbol *const s = - declare_variable(state, (yyvsp[(2) - (6)].string), (yyvsp[(6) - (6)].temp_sym).type, & (yylsp[(2) - (6)])); - - if (s == NULL) { - free((yyvsp[(2) - (6)].string)); - YYERROR; - } else { - s->param_binding_type = (yyvsp[(6) - (6)].temp_sym).param_binding_type; - s->param_binding_begin = (yyvsp[(6) - (6)].temp_sym).param_binding_begin; - s->param_binding_length = (yyvsp[(6) - (6)].temp_sym).param_binding_length; - s->param_binding_swizzle = SWIZZLE_XYZW; - s->param_is_array = 1; - } - } - ;} - break; - - case 125: - -/* Line 1455 of yacc.c */ -#line 1254 "program_parse.y" - { - (yyval.integer) = 0; - ;} - break; - - case 126: - -/* Line 1455 of yacc.c */ -#line 1258 "program_parse.y" - { - if (((yyvsp[(1) - (1)].integer) < 1) || ((unsigned) (yyvsp[(1) - (1)].integer) > state->limits->MaxParameters)) { - yyerror(& (yylsp[(1) - (1)]), state, "invalid parameter array size"); - YYERROR; - } else { - (yyval.integer) = (yyvsp[(1) - (1)].integer); - } - ;} - break; - - case 127: - -/* Line 1455 of yacc.c */ -#line 1269 "program_parse.y" - { - (yyval.temp_sym) = (yyvsp[(2) - (2)].temp_sym); - ;} - break; - - case 128: - -/* Line 1455 of yacc.c */ -#line 1275 "program_parse.y" - { - (yyval.temp_sym) = (yyvsp[(3) - (4)].temp_sym); - ;} - break; - - case 130: - -/* Line 1455 of yacc.c */ -#line 1282 "program_parse.y" - { - (yyvsp[(1) - (3)].temp_sym).param_binding_length += (yyvsp[(3) - (3)].temp_sym).param_binding_length; - (yyval.temp_sym) = (yyvsp[(1) - (3)].temp_sym); - ;} - break; - - case 131: - -/* Line 1455 of yacc.c */ -#line 1289 "program_parse.y" - { - memset(& (yyval.temp_sym), 0, sizeof((yyval.temp_sym))); - (yyval.temp_sym).param_binding_begin = ~0; - initialize_symbol_from_state(state->prog, & (yyval.temp_sym), (yyvsp[(1) - (1)].state)); - ;} - break; - - case 132: - -/* Line 1455 of yacc.c */ -#line 1295 "program_parse.y" - { - memset(& (yyval.temp_sym), 0, sizeof((yyval.temp_sym))); - (yyval.temp_sym).param_binding_begin = ~0; - initialize_symbol_from_param(state->prog, & (yyval.temp_sym), (yyvsp[(1) - (1)].state)); - ;} - break; - - case 133: - -/* Line 1455 of yacc.c */ -#line 1301 "program_parse.y" - { - memset(& (yyval.temp_sym), 0, sizeof((yyval.temp_sym))); - (yyval.temp_sym).param_binding_begin = ~0; - initialize_symbol_from_const(state->prog, & (yyval.temp_sym), & (yyvsp[(1) - (1)].vector), GL_TRUE); - ;} - break; - - case 134: - -/* Line 1455 of yacc.c */ -#line 1309 "program_parse.y" - { - memset(& (yyval.temp_sym), 0, sizeof((yyval.temp_sym))); - (yyval.temp_sym).param_binding_begin = ~0; - initialize_symbol_from_state(state->prog, & (yyval.temp_sym), (yyvsp[(1) - (1)].state)); - ;} - break; - - case 135: - -/* Line 1455 of yacc.c */ -#line 1315 "program_parse.y" - { - memset(& (yyval.temp_sym), 0, sizeof((yyval.temp_sym))); - (yyval.temp_sym).param_binding_begin = ~0; - initialize_symbol_from_param(state->prog, & (yyval.temp_sym), (yyvsp[(1) - (1)].state)); - ;} - break; - - case 136: - -/* Line 1455 of yacc.c */ -#line 1321 "program_parse.y" - { - memset(& (yyval.temp_sym), 0, sizeof((yyval.temp_sym))); - (yyval.temp_sym).param_binding_begin = ~0; - initialize_symbol_from_const(state->prog, & (yyval.temp_sym), & (yyvsp[(1) - (1)].vector), GL_TRUE); - ;} - break; - - case 137: - -/* Line 1455 of yacc.c */ -#line 1329 "program_parse.y" - { - memset(& (yyval.temp_sym), 0, sizeof((yyval.temp_sym))); - (yyval.temp_sym).param_binding_begin = ~0; - initialize_symbol_from_state(state->prog, & (yyval.temp_sym), (yyvsp[(1) - (1)].state)); - ;} - break; - - case 138: - -/* Line 1455 of yacc.c */ -#line 1335 "program_parse.y" - { - memset(& (yyval.temp_sym), 0, sizeof((yyval.temp_sym))); - (yyval.temp_sym).param_binding_begin = ~0; - initialize_symbol_from_param(state->prog, & (yyval.temp_sym), (yyvsp[(1) - (1)].state)); - ;} - break; - - case 139: - -/* Line 1455 of yacc.c */ -#line 1341 "program_parse.y" - { - memset(& (yyval.temp_sym), 0, sizeof((yyval.temp_sym))); - (yyval.temp_sym).param_binding_begin = ~0; - initialize_symbol_from_const(state->prog, & (yyval.temp_sym), & (yyvsp[(1) - (1)].vector), GL_FALSE); - ;} - break; - - case 140: - -/* Line 1455 of yacc.c */ -#line 1348 "program_parse.y" - { memcpy((yyval.state), (yyvsp[(1) - (1)].state), sizeof((yyval.state))); ;} - break; - - case 141: - -/* Line 1455 of yacc.c */ -#line 1349 "program_parse.y" - { memcpy((yyval.state), (yyvsp[(2) - (2)].state), sizeof((yyval.state))); ;} - break; - - case 142: - -/* Line 1455 of yacc.c */ -#line 1352 "program_parse.y" - { memcpy((yyval.state), (yyvsp[(2) - (2)].state), sizeof((yyval.state))); ;} - break; - - case 143: - -/* Line 1455 of yacc.c */ -#line 1353 "program_parse.y" - { memcpy((yyval.state), (yyvsp[(2) - (2)].state), sizeof((yyval.state))); ;} - break; - - case 144: - -/* Line 1455 of yacc.c */ -#line 1354 "program_parse.y" - { memcpy((yyval.state), (yyvsp[(2) - (2)].state), sizeof((yyval.state))); ;} - break; - - case 145: - -/* Line 1455 of yacc.c */ -#line 1355 "program_parse.y" - { memcpy((yyval.state), (yyvsp[(2) - (2)].state), sizeof((yyval.state))); ;} - break; - - case 146: - -/* Line 1455 of yacc.c */ -#line 1356 "program_parse.y" - { memcpy((yyval.state), (yyvsp[(2) - (2)].state), sizeof((yyval.state))); ;} - break; - - case 147: - -/* Line 1455 of yacc.c */ -#line 1357 "program_parse.y" - { memcpy((yyval.state), (yyvsp[(2) - (2)].state), sizeof((yyval.state))); ;} - break; - - case 148: - -/* Line 1455 of yacc.c */ -#line 1358 "program_parse.y" - { memcpy((yyval.state), (yyvsp[(2) - (2)].state), sizeof((yyval.state))); ;} - break; - - case 149: - -/* Line 1455 of yacc.c */ -#line 1359 "program_parse.y" - { memcpy((yyval.state), (yyvsp[(2) - (2)].state), sizeof((yyval.state))); ;} - break; - - case 150: - -/* Line 1455 of yacc.c */ -#line 1360 "program_parse.y" - { memcpy((yyval.state), (yyvsp[(2) - (2)].state), sizeof((yyval.state))); ;} - break; - - case 151: - -/* Line 1455 of yacc.c */ -#line 1361 "program_parse.y" - { memcpy((yyval.state), (yyvsp[(2) - (2)].state), sizeof((yyval.state))); ;} - break; - - case 152: - -/* Line 1455 of yacc.c */ -#line 1362 "program_parse.y" - { memcpy((yyval.state), (yyvsp[(2) - (2)].state), sizeof((yyval.state))); ;} - break; - - case 153: - -/* Line 1455 of yacc.c */ -#line 1366 "program_parse.y" - { - memset((yyval.state), 0, sizeof((yyval.state))); - (yyval.state)[0] = STATE_MATERIAL; - (yyval.state)[1] = (yyvsp[(2) - (3)].integer); - (yyval.state)[2] = (yyvsp[(3) - (3)].integer); - ;} - break; - - case 154: - -/* Line 1455 of yacc.c */ -#line 1375 "program_parse.y" - { - (yyval.integer) = (yyvsp[(1) - (1)].integer); - ;} - break; - - case 155: - -/* Line 1455 of yacc.c */ -#line 1379 "program_parse.y" - { - (yyval.integer) = STATE_EMISSION; - ;} - break; - - case 156: - -/* Line 1455 of yacc.c */ -#line 1383 "program_parse.y" - { - (yyval.integer) = STATE_SHININESS; - ;} - break; - - case 157: - -/* Line 1455 of yacc.c */ -#line 1389 "program_parse.y" - { - memset((yyval.state), 0, sizeof((yyval.state))); - (yyval.state)[0] = STATE_LIGHT; - (yyval.state)[1] = (yyvsp[(3) - (5)].integer); - (yyval.state)[2] = (yyvsp[(5) - (5)].integer); - ;} - break; - - case 158: - -/* Line 1455 of yacc.c */ -#line 1398 "program_parse.y" - { - (yyval.integer) = (yyvsp[(1) - (1)].integer); - ;} - break; - - case 159: - -/* Line 1455 of yacc.c */ -#line 1402 "program_parse.y" - { - (yyval.integer) = STATE_POSITION; - ;} - break; - - case 160: - -/* Line 1455 of yacc.c */ -#line 1406 "program_parse.y" - { - if (!state->ctx->Extensions.EXT_point_parameters) { - yyerror(& (yylsp[(1) - (1)]), state, "GL_ARB_point_parameters not supported"); - YYERROR; - } - - (yyval.integer) = STATE_ATTENUATION; - ;} - break; - - case 161: - -/* Line 1455 of yacc.c */ -#line 1415 "program_parse.y" - { - (yyval.integer) = (yyvsp[(2) - (2)].integer); - ;} - break; - - case 162: - -/* Line 1455 of yacc.c */ -#line 1419 "program_parse.y" - { - (yyval.integer) = STATE_HALF_VECTOR; - ;} - break; - - case 163: - -/* Line 1455 of yacc.c */ -#line 1425 "program_parse.y" - { - (yyval.integer) = STATE_SPOT_DIRECTION; - ;} - break; - - case 164: - -/* Line 1455 of yacc.c */ -#line 1431 "program_parse.y" - { - (yyval.state)[0] = (yyvsp[(2) - (2)].state)[0]; - (yyval.state)[1] = (yyvsp[(2) - (2)].state)[1]; - ;} - break; - - case 165: - -/* Line 1455 of yacc.c */ -#line 1438 "program_parse.y" - { - memset((yyval.state), 0, sizeof((yyval.state))); - (yyval.state)[0] = STATE_LIGHTMODEL_AMBIENT; - ;} - break; - - case 166: - -/* Line 1455 of yacc.c */ -#line 1443 "program_parse.y" - { - memset((yyval.state), 0, sizeof((yyval.state))); - (yyval.state)[0] = STATE_LIGHTMODEL_SCENECOLOR; - (yyval.state)[1] = (yyvsp[(1) - (2)].integer); - ;} - break; - - case 167: - -/* Line 1455 of yacc.c */ -#line 1451 "program_parse.y" - { - memset((yyval.state), 0, sizeof((yyval.state))); - (yyval.state)[0] = STATE_LIGHTPROD; - (yyval.state)[1] = (yyvsp[(3) - (6)].integer); - (yyval.state)[2] = (yyvsp[(5) - (6)].integer); - (yyval.state)[3] = (yyvsp[(6) - (6)].integer); - ;} - break; - - case 169: - -/* Line 1455 of yacc.c */ -#line 1463 "program_parse.y" - { - memset((yyval.state), 0, sizeof((yyval.state))); - (yyval.state)[0] = (yyvsp[(3) - (3)].integer); - (yyval.state)[1] = (yyvsp[(2) - (3)].integer); - ;} - break; - - case 170: - -/* Line 1455 of yacc.c */ -#line 1471 "program_parse.y" - { - (yyval.integer) = STATE_TEXENV_COLOR; - ;} - break; - - case 171: - -/* Line 1455 of yacc.c */ -#line 1477 "program_parse.y" - { - (yyval.integer) = STATE_AMBIENT; - ;} - break; - - case 172: - -/* Line 1455 of yacc.c */ -#line 1481 "program_parse.y" - { - (yyval.integer) = STATE_DIFFUSE; - ;} - break; - - case 173: - -/* Line 1455 of yacc.c */ -#line 1485 "program_parse.y" - { - (yyval.integer) = STATE_SPECULAR; - ;} - break; - - case 174: - -/* Line 1455 of yacc.c */ -#line 1491 "program_parse.y" - { - if ((unsigned) (yyvsp[(1) - (1)].integer) >= state->MaxLights) { - yyerror(& (yylsp[(1) - (1)]), state, "invalid light selector"); - YYERROR; - } - - (yyval.integer) = (yyvsp[(1) - (1)].integer); - ;} - break; - - case 175: - -/* Line 1455 of yacc.c */ -#line 1502 "program_parse.y" - { - memset((yyval.state), 0, sizeof((yyval.state))); - (yyval.state)[0] = STATE_TEXGEN; - (yyval.state)[1] = (yyvsp[(2) - (4)].integer); - (yyval.state)[2] = (yyvsp[(3) - (4)].integer) + (yyvsp[(4) - (4)].integer); - ;} - break; - - case 176: - -/* Line 1455 of yacc.c */ -#line 1511 "program_parse.y" - { - (yyval.integer) = STATE_TEXGEN_EYE_S; - ;} - break; - - case 177: - -/* Line 1455 of yacc.c */ -#line 1515 "program_parse.y" - { - (yyval.integer) = STATE_TEXGEN_OBJECT_S; - ;} - break; - - case 178: - -/* Line 1455 of yacc.c */ -#line 1520 "program_parse.y" - { - (yyval.integer) = STATE_TEXGEN_EYE_S - STATE_TEXGEN_EYE_S; - ;} - break; - - case 179: - -/* Line 1455 of yacc.c */ -#line 1524 "program_parse.y" - { - (yyval.integer) = STATE_TEXGEN_EYE_T - STATE_TEXGEN_EYE_S; - ;} - break; - - case 180: - -/* Line 1455 of yacc.c */ -#line 1528 "program_parse.y" - { - (yyval.integer) = STATE_TEXGEN_EYE_R - STATE_TEXGEN_EYE_S; - ;} - break; - - case 181: - -/* Line 1455 of yacc.c */ -#line 1532 "program_parse.y" - { - (yyval.integer) = STATE_TEXGEN_EYE_Q - STATE_TEXGEN_EYE_S; - ;} - break; - - case 182: - -/* Line 1455 of yacc.c */ -#line 1538 "program_parse.y" - { - memset((yyval.state), 0, sizeof((yyval.state))); - (yyval.state)[0] = (yyvsp[(2) - (2)].integer); - ;} - break; - - case 183: - -/* Line 1455 of yacc.c */ -#line 1545 "program_parse.y" - { - (yyval.integer) = STATE_FOG_COLOR; - ;} - break; - - case 184: - -/* Line 1455 of yacc.c */ -#line 1549 "program_parse.y" - { - (yyval.integer) = STATE_FOG_PARAMS; - ;} - break; - - case 185: - -/* Line 1455 of yacc.c */ -#line 1555 "program_parse.y" - { - memset((yyval.state), 0, sizeof((yyval.state))); - (yyval.state)[0] = STATE_CLIPPLANE; - (yyval.state)[1] = (yyvsp[(3) - (5)].integer); - ;} - break; - - case 186: - -/* Line 1455 of yacc.c */ -#line 1563 "program_parse.y" - { - if ((unsigned) (yyvsp[(1) - (1)].integer) >= state->MaxClipPlanes) { - yyerror(& (yylsp[(1) - (1)]), state, "invalid clip plane selector"); - YYERROR; - } - - (yyval.integer) = (yyvsp[(1) - (1)].integer); - ;} - break; - - case 187: - -/* Line 1455 of yacc.c */ -#line 1574 "program_parse.y" - { - memset((yyval.state), 0, sizeof((yyval.state))); - (yyval.state)[0] = (yyvsp[(2) - (2)].integer); - ;} - break; - - case 188: - -/* Line 1455 of yacc.c */ -#line 1581 "program_parse.y" - { - (yyval.integer) = STATE_POINT_SIZE; - ;} - break; - - case 189: - -/* Line 1455 of yacc.c */ -#line 1585 "program_parse.y" - { - (yyval.integer) = STATE_POINT_ATTENUATION; - ;} - break; - - case 190: - -/* Line 1455 of yacc.c */ -#line 1591 "program_parse.y" - { - (yyval.state)[0] = (yyvsp[(1) - (5)].state)[0]; - (yyval.state)[1] = (yyvsp[(1) - (5)].state)[1]; - (yyval.state)[2] = (yyvsp[(4) - (5)].integer); - (yyval.state)[3] = (yyvsp[(4) - (5)].integer); - (yyval.state)[4] = (yyvsp[(1) - (5)].state)[2]; - ;} - break; - - case 191: - -/* Line 1455 of yacc.c */ -#line 1601 "program_parse.y" - { - (yyval.state)[0] = (yyvsp[(1) - (2)].state)[0]; - (yyval.state)[1] = (yyvsp[(1) - (2)].state)[1]; - (yyval.state)[2] = (yyvsp[(2) - (2)].state)[2]; - (yyval.state)[3] = (yyvsp[(2) - (2)].state)[3]; - (yyval.state)[4] = (yyvsp[(1) - (2)].state)[2]; - ;} - break; - - case 192: - -/* Line 1455 of yacc.c */ -#line 1611 "program_parse.y" - { - (yyval.state)[2] = 0; - (yyval.state)[3] = 3; - ;} - break; - - case 193: - -/* Line 1455 of yacc.c */ -#line 1616 "program_parse.y" - { - /* It seems logical that the matrix row range specifier would have - * to specify a range or more than one row (i.e., $5 > $3). - * However, the ARB_vertex_program spec says "a program will fail - * to load if <a> is greater than <b>." This means that $3 == $5 - * is valid. - */ - if ((yyvsp[(3) - (6)].integer) > (yyvsp[(5) - (6)].integer)) { - yyerror(& (yylsp[(3) - (6)]), state, "invalid matrix row range"); - YYERROR; - } - - (yyval.state)[2] = (yyvsp[(3) - (6)].integer); - (yyval.state)[3] = (yyvsp[(5) - (6)].integer); - ;} - break; - - case 194: - -/* Line 1455 of yacc.c */ -#line 1634 "program_parse.y" - { - (yyval.state)[0] = (yyvsp[(2) - (3)].state)[0]; - (yyval.state)[1] = (yyvsp[(2) - (3)].state)[1]; - (yyval.state)[2] = (yyvsp[(3) - (3)].integer); - ;} - break; - - case 195: - -/* Line 1455 of yacc.c */ -#line 1642 "program_parse.y" - { - (yyval.integer) = 0; - ;} - break; - - case 196: - -/* Line 1455 of yacc.c */ -#line 1646 "program_parse.y" - { - (yyval.integer) = (yyvsp[(1) - (1)].integer); - ;} - break; - - case 197: - -/* Line 1455 of yacc.c */ -#line 1652 "program_parse.y" - { - (yyval.integer) = STATE_MATRIX_INVERSE; - ;} - break; - - case 198: - -/* Line 1455 of yacc.c */ -#line 1656 "program_parse.y" - { - (yyval.integer) = STATE_MATRIX_TRANSPOSE; - ;} - break; - - case 199: - -/* Line 1455 of yacc.c */ -#line 1660 "program_parse.y" - { - (yyval.integer) = STATE_MATRIX_INVTRANS; - ;} - break; - - case 200: - -/* Line 1455 of yacc.c */ -#line 1666 "program_parse.y" - { - if ((yyvsp[(1) - (1)].integer) > 3) { - yyerror(& (yylsp[(1) - (1)]), state, "invalid matrix row reference"); - YYERROR; - } - - (yyval.integer) = (yyvsp[(1) - (1)].integer); - ;} - break; - - case 201: - -/* Line 1455 of yacc.c */ -#line 1677 "program_parse.y" - { - (yyval.state)[0] = STATE_MODELVIEW_MATRIX; - (yyval.state)[1] = (yyvsp[(2) - (2)].integer); - ;} - break; - - case 202: - -/* Line 1455 of yacc.c */ -#line 1682 "program_parse.y" - { - (yyval.state)[0] = STATE_PROJECTION_MATRIX; - (yyval.state)[1] = 0; - ;} - break; - - case 203: - -/* Line 1455 of yacc.c */ -#line 1687 "program_parse.y" - { - (yyval.state)[0] = STATE_MVP_MATRIX; - (yyval.state)[1] = 0; - ;} - break; - - case 204: - -/* Line 1455 of yacc.c */ -#line 1692 "program_parse.y" - { - (yyval.state)[0] = STATE_TEXTURE_MATRIX; - (yyval.state)[1] = (yyvsp[(2) - (2)].integer); - ;} - break; - - case 205: - -/* Line 1455 of yacc.c */ -#line 1697 "program_parse.y" - { - yyerror(& (yylsp[(1) - (4)]), state, "GL_ARB_matrix_palette not supported"); - YYERROR; - ;} - break; - - case 206: - -/* Line 1455 of yacc.c */ -#line 1702 "program_parse.y" - { - (yyval.state)[0] = STATE_PROGRAM_MATRIX; - (yyval.state)[1] = (yyvsp[(3) - (4)].integer); - ;} - break; - - case 207: - -/* Line 1455 of yacc.c */ -#line 1709 "program_parse.y" - { - (yyval.integer) = 0; - ;} - break; - - case 208: - -/* Line 1455 of yacc.c */ -#line 1713 "program_parse.y" - { - (yyval.integer) = (yyvsp[(2) - (3)].integer); - ;} - break; - - case 209: - -/* Line 1455 of yacc.c */ -#line 1718 "program_parse.y" - { - /* Since GL_ARB_vertex_blend isn't supported, only modelview matrix - * zero is valid. - */ - if ((yyvsp[(1) - (1)].integer) != 0) { - yyerror(& (yylsp[(1) - (1)]), state, "invalid modelview matrix index"); - YYERROR; - } - - (yyval.integer) = (yyvsp[(1) - (1)].integer); - ;} - break; - - case 210: - -/* Line 1455 of yacc.c */ -#line 1731 "program_parse.y" - { - /* Since GL_ARB_matrix_palette isn't supported, just let any value - * through here. The error will be generated later. - */ - (yyval.integer) = (yyvsp[(1) - (1)].integer); - ;} - break; - - case 211: - -/* Line 1455 of yacc.c */ -#line 1739 "program_parse.y" - { - if ((unsigned) (yyvsp[(1) - (1)].integer) >= state->MaxProgramMatrices) { - yyerror(& (yylsp[(1) - (1)]), state, "invalid program matrix selector"); - YYERROR; - } - - (yyval.integer) = (yyvsp[(1) - (1)].integer); - ;} - break; - - case 212: - -/* Line 1455 of yacc.c */ -#line 1750 "program_parse.y" - { - memset((yyval.state), 0, sizeof((yyval.state))); - (yyval.state)[0] = STATE_DEPTH_RANGE; - ;} - break; - - case 217: - -/* Line 1455 of yacc.c */ -#line 1762 "program_parse.y" - { - memset((yyval.state), 0, sizeof((yyval.state))); - (yyval.state)[0] = state->state_param_enum; - (yyval.state)[1] = STATE_ENV; - (yyval.state)[2] = (yyvsp[(4) - (5)].state)[0]; - (yyval.state)[3] = (yyvsp[(4) - (5)].state)[1]; - ;} - break; - - case 218: - -/* Line 1455 of yacc.c */ -#line 1772 "program_parse.y" - { - (yyval.state)[0] = (yyvsp[(1) - (1)].integer); - (yyval.state)[1] = (yyvsp[(1) - (1)].integer); - ;} - break; - - case 219: - -/* Line 1455 of yacc.c */ -#line 1777 "program_parse.y" - { - (yyval.state)[0] = (yyvsp[(1) - (3)].integer); - (yyval.state)[1] = (yyvsp[(3) - (3)].integer); - ;} - break; - - case 220: - -/* Line 1455 of yacc.c */ -#line 1784 "program_parse.y" - { - memset((yyval.state), 0, sizeof((yyval.state))); - (yyval.state)[0] = state->state_param_enum; - (yyval.state)[1] = STATE_ENV; - (yyval.state)[2] = (yyvsp[(4) - (5)].integer); - (yyval.state)[3] = (yyvsp[(4) - (5)].integer); - ;} - break; - - case 221: - -/* Line 1455 of yacc.c */ -#line 1794 "program_parse.y" - { - memset((yyval.state), 0, sizeof((yyval.state))); - (yyval.state)[0] = state->state_param_enum; - (yyval.state)[1] = STATE_LOCAL; - (yyval.state)[2] = (yyvsp[(4) - (5)].state)[0]; - (yyval.state)[3] = (yyvsp[(4) - (5)].state)[1]; - ;} - break; - - case 222: - -/* Line 1455 of yacc.c */ -#line 1803 "program_parse.y" - { - (yyval.state)[0] = (yyvsp[(1) - (1)].integer); - (yyval.state)[1] = (yyvsp[(1) - (1)].integer); - ;} - break; - - case 223: - -/* Line 1455 of yacc.c */ -#line 1808 "program_parse.y" - { - (yyval.state)[0] = (yyvsp[(1) - (3)].integer); - (yyval.state)[1] = (yyvsp[(3) - (3)].integer); - ;} - break; - - case 224: - -/* Line 1455 of yacc.c */ -#line 1815 "program_parse.y" - { - memset((yyval.state), 0, sizeof((yyval.state))); - (yyval.state)[0] = state->state_param_enum; - (yyval.state)[1] = STATE_LOCAL; - (yyval.state)[2] = (yyvsp[(4) - (5)].integer); - (yyval.state)[3] = (yyvsp[(4) - (5)].integer); - ;} - break; - - case 225: - -/* Line 1455 of yacc.c */ -#line 1825 "program_parse.y" - { - if ((unsigned) (yyvsp[(1) - (1)].integer) >= state->limits->MaxEnvParams) { - yyerror(& (yylsp[(1) - (1)]), state, "invalid environment parameter reference"); - YYERROR; - } - (yyval.integer) = (yyvsp[(1) - (1)].integer); - ;} - break; - - case 226: - -/* Line 1455 of yacc.c */ -#line 1835 "program_parse.y" - { - if ((unsigned) (yyvsp[(1) - (1)].integer) >= state->limits->MaxLocalParams) { - yyerror(& (yylsp[(1) - (1)]), state, "invalid local parameter reference"); - YYERROR; - } - (yyval.integer) = (yyvsp[(1) - (1)].integer); - ;} - break; - - case 231: - -/* Line 1455 of yacc.c */ -#line 1850 "program_parse.y" - { - (yyval.vector).count = 4; - (yyval.vector).data[0] = (yyvsp[(1) - (1)].real); - (yyval.vector).data[1] = (yyvsp[(1) - (1)].real); - (yyval.vector).data[2] = (yyvsp[(1) - (1)].real); - (yyval.vector).data[3] = (yyvsp[(1) - (1)].real); - ;} - break; - - case 232: - -/* Line 1455 of yacc.c */ -#line 1860 "program_parse.y" - { - (yyval.vector).count = 1; - (yyval.vector).data[0] = (yyvsp[(1) - (1)].real); - (yyval.vector).data[1] = (yyvsp[(1) - (1)].real); - (yyval.vector).data[2] = (yyvsp[(1) - (1)].real); - (yyval.vector).data[3] = (yyvsp[(1) - (1)].real); - ;} - break; - - case 233: - -/* Line 1455 of yacc.c */ -#line 1868 "program_parse.y" - { - (yyval.vector).count = 1; - (yyval.vector).data[0] = (float) (yyvsp[(1) - (1)].integer); - (yyval.vector).data[1] = (float) (yyvsp[(1) - (1)].integer); - (yyval.vector).data[2] = (float) (yyvsp[(1) - (1)].integer); - (yyval.vector).data[3] = (float) (yyvsp[(1) - (1)].integer); - ;} - break; - - case 234: - -/* Line 1455 of yacc.c */ -#line 1878 "program_parse.y" - { - (yyval.vector).count = 4; - (yyval.vector).data[0] = (yyvsp[(2) - (3)].real); - (yyval.vector).data[1] = 0.0f; - (yyval.vector).data[2] = 0.0f; - (yyval.vector).data[3] = 1.0f; - ;} - break; - - case 235: - -/* Line 1455 of yacc.c */ -#line 1886 "program_parse.y" - { - (yyval.vector).count = 4; - (yyval.vector).data[0] = (yyvsp[(2) - (5)].real); - (yyval.vector).data[1] = (yyvsp[(4) - (5)].real); - (yyval.vector).data[2] = 0.0f; - (yyval.vector).data[3] = 1.0f; - ;} - break; - - case 236: - -/* Line 1455 of yacc.c */ -#line 1895 "program_parse.y" - { - (yyval.vector).count = 4; - (yyval.vector).data[0] = (yyvsp[(2) - (7)].real); - (yyval.vector).data[1] = (yyvsp[(4) - (7)].real); - (yyval.vector).data[2] = (yyvsp[(6) - (7)].real); - (yyval.vector).data[3] = 1.0f; - ;} - break; - - case 237: - -/* Line 1455 of yacc.c */ -#line 1904 "program_parse.y" - { - (yyval.vector).count = 4; - (yyval.vector).data[0] = (yyvsp[(2) - (9)].real); - (yyval.vector).data[1] = (yyvsp[(4) - (9)].real); - (yyval.vector).data[2] = (yyvsp[(6) - (9)].real); - (yyval.vector).data[3] = (yyvsp[(8) - (9)].real); - ;} - break; - - case 238: - -/* Line 1455 of yacc.c */ -#line 1914 "program_parse.y" - { - (yyval.real) = ((yyvsp[(1) - (2)].negate)) ? -(yyvsp[(2) - (2)].real) : (yyvsp[(2) - (2)].real); - ;} - break; - - case 239: - -/* Line 1455 of yacc.c */ -#line 1918 "program_parse.y" - { - (yyval.real) = (float)(((yyvsp[(1) - (2)].negate)) ? -(yyvsp[(2) - (2)].integer) : (yyvsp[(2) - (2)].integer)); - ;} - break; - - case 240: - -/* Line 1455 of yacc.c */ -#line 1923 "program_parse.y" - { (yyval.negate) = FALSE; ;} - break; - - case 241: - -/* Line 1455 of yacc.c */ -#line 1924 "program_parse.y" - { (yyval.negate) = TRUE; ;} - break; - - case 242: - -/* Line 1455 of yacc.c */ -#line 1925 "program_parse.y" - { (yyval.negate) = FALSE; ;} - break; - - case 243: - -/* Line 1455 of yacc.c */ -#line 1928 "program_parse.y" - { (yyval.integer) = (yyvsp[(2) - (2)].integer); ;} - break; - - case 245: - -/* Line 1455 of yacc.c */ -#line 1932 "program_parse.y" - { - /* NV_fragment_program_option defines the size qualifiers in a - * fairly broken way. "SHORT" or "LONG" can optionally be used - * before TEMP or OUTPUT. However, neither is a reserved word! - * This means that we have to parse it as an identifier, then check - * to make sure it's one of the valid values. *sigh* - * - * In addition, the grammar in the extension spec does *not* allow - * the size specifier to be optional, but all known implementations - * do. - */ - if (!state->option.NV_fragment) { - yyerror(& (yylsp[(1) - (1)]), state, "unexpected IDENTIFIER"); - YYERROR; - } - - if (strcmp("SHORT", (yyvsp[(1) - (1)].string)) == 0) { - } else if (strcmp("LONG", (yyvsp[(1) - (1)].string)) == 0) { - } else { - char *const err_str = - make_error_string("invalid storage size specifier \"%s\"", - (yyvsp[(1) - (1)].string)); - - yyerror(& (yylsp[(1) - (1)]), state, (err_str != NULL) - ? err_str : "invalid storage size specifier"); - - if (err_str != NULL) { - free(err_str); - } - - YYERROR; - } - ;} - break; - - case 246: - -/* Line 1455 of yacc.c */ -#line 1966 "program_parse.y" - { - ;} - break; - - case 247: - -/* Line 1455 of yacc.c */ -#line 1970 "program_parse.y" - { (yyval.integer) = (yyvsp[(1) - (1)].integer); ;} - break; - - case 249: - -/* Line 1455 of yacc.c */ -#line 1974 "program_parse.y" - { - if (!declare_variable(state, (yyvsp[(3) - (3)].string), (yyvsp[(0) - (3)].integer), & (yylsp[(3) - (3)]))) { - free((yyvsp[(3) - (3)].string)); - YYERROR; - } - ;} - break; - - case 250: - -/* Line 1455 of yacc.c */ -#line 1981 "program_parse.y" - { - if (!declare_variable(state, (yyvsp[(1) - (1)].string), (yyvsp[(0) - (1)].integer), & (yylsp[(1) - (1)]))) { - free((yyvsp[(1) - (1)].string)); - YYERROR; - } - ;} - break; - - case 251: - -/* Line 1455 of yacc.c */ -#line 1990 "program_parse.y" - { - struct asm_symbol *const s = - declare_variable(state, (yyvsp[(3) - (5)].string), at_output, & (yylsp[(3) - (5)])); - - if (s == NULL) { - free((yyvsp[(3) - (5)].string)); - YYERROR; - } else { - s->output_binding = (yyvsp[(5) - (5)].result); - } - ;} - break; - - case 252: - -/* Line 1455 of yacc.c */ -#line 2004 "program_parse.y" - { - if (state->mode == ARB_vertex) { - (yyval.result) = VERT_RESULT_HPOS; - } else { - yyerror(& (yylsp[(2) - (2)]), state, "invalid program result name"); - YYERROR; - } - ;} - break; - - case 253: - -/* Line 1455 of yacc.c */ -#line 2013 "program_parse.y" - { - if (state->mode == ARB_vertex) { - (yyval.result) = VERT_RESULT_FOGC; - } else { - yyerror(& (yylsp[(2) - (2)]), state, "invalid program result name"); - YYERROR; - } - ;} - break; - - case 254: - -/* Line 1455 of yacc.c */ -#line 2022 "program_parse.y" - { - (yyval.result) = (yyvsp[(2) - (2)].result); - ;} - break; - - case 255: - -/* Line 1455 of yacc.c */ -#line 2026 "program_parse.y" - { - if (state->mode == ARB_vertex) { - (yyval.result) = VERT_RESULT_PSIZ; - } else { - yyerror(& (yylsp[(2) - (2)]), state, "invalid program result name"); - YYERROR; - } - ;} - break; - - case 256: - -/* Line 1455 of yacc.c */ -#line 2035 "program_parse.y" - { - if (state->mode == ARB_vertex) { - (yyval.result) = VERT_RESULT_TEX0 + (yyvsp[(3) - (3)].integer); - } else { - yyerror(& (yylsp[(2) - (3)]), state, "invalid program result name"); - YYERROR; - } - ;} - break; - - case 257: - -/* Line 1455 of yacc.c */ -#line 2044 "program_parse.y" - { - if (state->mode == ARB_fragment) { - (yyval.result) = FRAG_RESULT_DEPTH; - } else { - yyerror(& (yylsp[(2) - (2)]), state, "invalid program result name"); - YYERROR; - } - ;} - break; - - case 258: - -/* Line 1455 of yacc.c */ -#line 2055 "program_parse.y" - { - (yyval.result) = (yyvsp[(2) - (3)].integer) + (yyvsp[(3) - (3)].integer); - ;} - break; - - case 259: - -/* Line 1455 of yacc.c */ -#line 2061 "program_parse.y" - { - (yyval.integer) = (state->mode == ARB_vertex) - ? VERT_RESULT_COL0 - : FRAG_RESULT_COLOR; - ;} - break; - - case 260: - -/* Line 1455 of yacc.c */ -#line 2067 "program_parse.y" - { - if (state->mode == ARB_vertex) { - (yyval.integer) = VERT_RESULT_COL0; - } else { - yyerror(& (yylsp[(1) - (1)]), state, "invalid program result name"); - YYERROR; - } - ;} - break; - - case 261: - -/* Line 1455 of yacc.c */ -#line 2076 "program_parse.y" - { - if (state->mode == ARB_vertex) { - (yyval.integer) = VERT_RESULT_BFC0; - } else { - yyerror(& (yylsp[(1) - (1)]), state, "invalid program result name"); - YYERROR; - } - ;} - break; - - case 262: - -/* Line 1455 of yacc.c */ -#line 2087 "program_parse.y" - { - (yyval.integer) = 0; - ;} - break; - - case 263: - -/* Line 1455 of yacc.c */ -#line 2091 "program_parse.y" - { - if (state->mode == ARB_vertex) { - (yyval.integer) = 0; - } else { - yyerror(& (yylsp[(1) - (1)]), state, "invalid program result name"); - YYERROR; - } - ;} - break; - - case 264: - -/* Line 1455 of yacc.c */ -#line 2100 "program_parse.y" - { - if (state->mode == ARB_vertex) { - (yyval.integer) = 1; - } else { - yyerror(& (yylsp[(1) - (1)]), state, "invalid program result name"); - YYERROR; - } - ;} - break; - - case 265: - -/* Line 1455 of yacc.c */ -#line 2110 "program_parse.y" - { (yyval.integer) = 0; ;} - break; - - case 266: - -/* Line 1455 of yacc.c */ -#line 2111 "program_parse.y" - { (yyval.integer) = 0; ;} - break; - - case 267: - -/* Line 1455 of yacc.c */ -#line 2112 "program_parse.y" - { (yyval.integer) = 1; ;} - break; - - case 268: - -/* Line 1455 of yacc.c */ -#line 2115 "program_parse.y" - { (yyval.integer) = 0; ;} - break; - - case 269: - -/* Line 1455 of yacc.c */ -#line 2116 "program_parse.y" - { (yyval.integer) = 0; ;} - break; - - case 270: - -/* Line 1455 of yacc.c */ -#line 2117 "program_parse.y" - { (yyval.integer) = 1; ;} - break; - - case 271: - -/* Line 1455 of yacc.c */ -#line 2120 "program_parse.y" - { (yyval.integer) = 0; ;} - break; - - case 272: - -/* Line 1455 of yacc.c */ -#line 2121 "program_parse.y" - { (yyval.integer) = (yyvsp[(2) - (3)].integer); ;} - break; - - case 273: - -/* Line 1455 of yacc.c */ -#line 2124 "program_parse.y" - { (yyval.integer) = 0; ;} - break; - - case 274: - -/* Line 1455 of yacc.c */ -#line 2125 "program_parse.y" - { (yyval.integer) = (yyvsp[(2) - (3)].integer); ;} - break; - - case 275: - -/* Line 1455 of yacc.c */ -#line 2128 "program_parse.y" - { (yyval.integer) = 0; ;} - break; - - case 276: - -/* Line 1455 of yacc.c */ -#line 2129 "program_parse.y" - { (yyval.integer) = (yyvsp[(2) - (3)].integer); ;} - break; - - case 277: - -/* Line 1455 of yacc.c */ -#line 2133 "program_parse.y" - { - if ((unsigned) (yyvsp[(1) - (1)].integer) >= state->MaxTextureCoordUnits) { - yyerror(& (yylsp[(1) - (1)]), state, "invalid texture coordinate unit selector"); - YYERROR; - } - - (yyval.integer) = (yyvsp[(1) - (1)].integer); - ;} - break; - - case 278: - -/* Line 1455 of yacc.c */ -#line 2144 "program_parse.y" - { - if ((unsigned) (yyvsp[(1) - (1)].integer) >= state->MaxTextureImageUnits) { - yyerror(& (yylsp[(1) - (1)]), state, "invalid texture image unit selector"); - YYERROR; - } - - (yyval.integer) = (yyvsp[(1) - (1)].integer); - ;} - break; - - case 279: - -/* Line 1455 of yacc.c */ -#line 2155 "program_parse.y" - { - if ((unsigned) (yyvsp[(1) - (1)].integer) >= state->MaxTextureUnits) { - yyerror(& (yylsp[(1) - (1)]), state, "invalid texture unit selector"); - YYERROR; - } - - (yyval.integer) = (yyvsp[(1) - (1)].integer); - ;} - break; - - case 280: - -/* Line 1455 of yacc.c */ -#line 2166 "program_parse.y" - { - struct asm_symbol *exist = (struct asm_symbol *) - _mesa_symbol_table_find_symbol(state->st, 0, (yyvsp[(2) - (4)].string)); - struct asm_symbol *target = (struct asm_symbol *) - _mesa_symbol_table_find_symbol(state->st, 0, (yyvsp[(4) - (4)].string)); - - free((yyvsp[(4) - (4)].string)); - - if (exist != NULL) { - char m[1000]; - _mesa_snprintf(m, sizeof(m), "redeclared identifier: %s", (yyvsp[(2) - (4)].string)); - free((yyvsp[(2) - (4)].string)); - yyerror(& (yylsp[(2) - (4)]), state, m); - YYERROR; - } else if (target == NULL) { - free((yyvsp[(2) - (4)].string)); - yyerror(& (yylsp[(4) - (4)]), state, - "undefined variable binding in ALIAS statement"); - YYERROR; - } else { - _mesa_symbol_table_add_symbol(state->st, 0, (yyvsp[(2) - (4)].string), target); - } - ;} - break; - - - -/* Line 1455 of yacc.c */ -#line 4937 "program_parse.tab.c" - default: break; - } - YY_SYMBOL_PRINT ("-> $$ =", yyr1[yyn], &yyval, &yyloc); - - YYPOPSTACK (yylen); - yylen = 0; - YY_STACK_PRINT (yyss, yyssp); - - *++yyvsp = yyval; - *++yylsp = yyloc; - - /* 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 - yyerror (&yylloc, state, YY_("syntax error")); -#else - { - YYSIZE_T yysize = yysyntax_error (0, yystate, yychar); - if (yymsg_alloc < yysize && yymsg_alloc < YYSTACK_ALLOC_MAXIMUM) - { - YYSIZE_T yyalloc = 2 * yysize; - if (! (yysize <= yyalloc && yyalloc <= YYSTACK_ALLOC_MAXIMUM)) - yyalloc = YYSTACK_ALLOC_MAXIMUM; - if (yymsg != yymsgbuf) - YYSTACK_FREE (yymsg); - yymsg = (char *) YYSTACK_ALLOC (yyalloc); - if (yymsg) - yymsg_alloc = yyalloc; - else - { - yymsg = yymsgbuf; - yymsg_alloc = sizeof yymsgbuf; - } - } - - if (0 < yysize && yysize <= yymsg_alloc) - { - (void) yysyntax_error (yymsg, yystate, yychar); - yyerror (&yylloc, state, yymsg); - } - else - { - yyerror (&yylloc, state, YY_("syntax error")); - if (yysize != 0) - goto yyexhaustedlab; - } - } -#endif - } - - yyerror_range[0] = yylloc; - - if (yyerrstatus == 3) - { - /* If just tried and failed to reuse lookahead token after an - error, discard it. */ - - if (yychar <= YYEOF) - { - /* Return failure if at end of input. */ - if (yychar == YYEOF) - YYABORT; - } - else - { - yydestruct ("Error: discarding", - yytoken, &yylval, &yylloc, state); - yychar = YYEMPTY; - } - } - - /* Else will try to reuse lookahead token after shifting the error - token. */ - goto yyerrlab1; - - -/*---------------------------------------------------. -| yyerrorlab -- error raised explicitly by YYERROR. | -`---------------------------------------------------*/ -yyerrorlab: - - /* Pacify compilers like GCC when the user code never invokes - YYERROR and the label yyerrorlab therefore never appears in user - code. */ - if (/*CONSTCOND*/ 0) - goto yyerrorlab; - - yyerror_range[0] = yylsp[1-yylen]; - /* Do not reclaim the symbols of the rule which action triggered - this YYERROR. */ - YYPOPSTACK (yylen); - yylen = 0; - YY_STACK_PRINT (yyss, yyssp); - yystate = *yyssp; - goto yyerrlab1; - - -/*-------------------------------------------------------------. -| yyerrlab1 -- common code for both syntax error and YYERROR. | -`-------------------------------------------------------------*/ -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; - - yyerror_range[0] = *yylsp; - yydestruct ("Error: popping", - yystos[yystate], yyvsp, yylsp, state); - YYPOPSTACK (1); - yystate = *yyssp; - YY_STACK_PRINT (yyss, yyssp); - } - - *++yyvsp = yylval; - - yyerror_range[1] = yylloc; - /* Using YYLLOC is tempting, but would change the location of - the lookahead. YYLOC is available though. */ - YYLLOC_DEFAULT (yyloc, (yyerror_range - 1), 2); - *++yylsp = yyloc; - - /* Shift the error token. */ - YY_SYMBOL_PRINT ("Shifting", yystos[yyn], yyvsp, yylsp); - - yystate = yyn; - goto yynewstate; - - -/*-------------------------------------. -| yyacceptlab -- YYACCEPT comes here. | -`-------------------------------------*/ -yyacceptlab: - yyresult = 0; - goto yyreturn; - -/*-----------------------------------. -| yyabortlab -- YYABORT comes here. | -`-----------------------------------*/ -yyabortlab: - yyresult = 1; - goto yyreturn; - -#if !defined(yyoverflow) || YYERROR_VERBOSE -/*-------------------------------------------------. -| yyexhaustedlab -- memory exhaustion comes here. | -`-------------------------------------------------*/ -yyexhaustedlab: - yyerror (&yylloc, state, YY_("memory exhausted")); - yyresult = 2; - /* Fall through. */ -#endif - -yyreturn: - if (yychar != YYEMPTY) - yydestruct ("Cleanup: discarding lookahead", - yytoken, &yylval, &yylloc, state); - /* Do not reclaim the symbols of the rule which action triggered - this YYABORT or YYACCEPT. */ - YYPOPSTACK (yylen); - YY_STACK_PRINT (yyss, yyssp); - while (yyssp != yyss) - { - yydestruct ("Cleanup: popping", - yystos[*yyssp], yyvsp, yylsp, state); - YYPOPSTACK (1); - } -#ifndef yyoverflow - if (yyss != yyssa) - YYSTACK_FREE (yyss); -#endif -#if YYERROR_VERBOSE - if (yymsg != yymsgbuf) - YYSTACK_FREE (yymsg); -#endif - /* Make sure YYID is used. */ - return YYID (yyresult); -} - - - -/* Line 1675 of yacc.c */ -#line 2195 "program_parse.y" - - -void -asm_instruction_set_operands(struct asm_instruction *inst, - const struct prog_dst_register *dst, - const struct asm_src_register *src0, - const struct asm_src_register *src1, - const struct asm_src_register *src2) -{ - /* In the core ARB extensions only the KIL instruction doesn't have a - * destination register. - */ - if (dst == NULL) { - init_dst_reg(& inst->Base.DstReg); - } else { - inst->Base.DstReg = *dst; - } - - /* The only instruction that doesn't have any source registers is the - * condition-code based KIL instruction added by NV_fragment_program_option. - */ - if (src0 != NULL) { - inst->Base.SrcReg[0] = src0->Base; - inst->SrcReg[0] = *src0; - } else { - init_src_reg(& inst->SrcReg[0]); - } - - if (src1 != NULL) { - inst->Base.SrcReg[1] = src1->Base; - inst->SrcReg[1] = *src1; - } else { - init_src_reg(& inst->SrcReg[1]); - } - - if (src2 != NULL) { - inst->Base.SrcReg[2] = src2->Base; - inst->SrcReg[2] = *src2; - } else { - init_src_reg(& inst->SrcReg[2]); - } -} - - -struct asm_instruction * -asm_instruction_ctor(gl_inst_opcode op, - const struct prog_dst_register *dst, - const struct asm_src_register *src0, - const struct asm_src_register *src1, - const struct asm_src_register *src2) -{ - struct asm_instruction *inst = CALLOC_STRUCT(asm_instruction); - - if (inst) { - _mesa_init_instructions(& inst->Base, 1); - inst->Base.Opcode = op; - - asm_instruction_set_operands(inst, dst, src0, src1, src2); - } - - return inst; -} - - -struct asm_instruction * -asm_instruction_copy_ctor(const struct prog_instruction *base, - const struct prog_dst_register *dst, - const struct asm_src_register *src0, - const struct asm_src_register *src1, - const struct asm_src_register *src2) -{ - struct asm_instruction *inst = CALLOC_STRUCT(asm_instruction); - - if (inst) { - _mesa_init_instructions(& inst->Base, 1); - inst->Base.Opcode = base->Opcode; - inst->Base.CondUpdate = base->CondUpdate; - inst->Base.CondDst = base->CondDst; - inst->Base.SaturateMode = base->SaturateMode; - inst->Base.Precision = base->Precision; - - asm_instruction_set_operands(inst, dst, src0, src1, src2); - } - - return inst; -} - - -void -init_dst_reg(struct prog_dst_register *r) -{ - memset(r, 0, sizeof(*r)); - r->File = PROGRAM_UNDEFINED; - r->WriteMask = WRITEMASK_XYZW; - r->CondMask = COND_TR; - r->CondSwizzle = SWIZZLE_NOOP; -} - - -/** Like init_dst_reg() but set the File and Index fields. */ -void -set_dst_reg(struct prog_dst_register *r, gl_register_file file, GLint index) -{ - const GLint maxIndex = 1 << INST_INDEX_BITS; - const GLint minIndex = 0; - ASSERT(index >= minIndex); - (void) minIndex; - ASSERT(index <= maxIndex); - (void) maxIndex; - ASSERT(file == PROGRAM_TEMPORARY || - file == PROGRAM_ADDRESS || - file == PROGRAM_OUTPUT); - memset(r, 0, sizeof(*r)); - r->File = file; - r->Index = index; - r->WriteMask = WRITEMASK_XYZW; - r->CondMask = COND_TR; - r->CondSwizzle = SWIZZLE_NOOP; -} - - -void -init_src_reg(struct asm_src_register *r) -{ - memset(r, 0, sizeof(*r)); - r->Base.File = PROGRAM_UNDEFINED; - r->Base.Swizzle = SWIZZLE_NOOP; - r->Symbol = NULL; -} - - -/** Like init_src_reg() but set the File and Index fields. - * \return GL_TRUE if a valid src register, GL_FALSE otherwise - */ -void -set_src_reg(struct asm_src_register *r, gl_register_file file, GLint index) -{ - set_src_reg_swz(r, file, index, SWIZZLE_XYZW); -} - - -void -set_src_reg_swz(struct asm_src_register *r, gl_register_file file, GLint index, - GLuint swizzle) -{ - const GLint maxIndex = (1 << INST_INDEX_BITS) - 1; - const GLint minIndex = -(1 << INST_INDEX_BITS); - ASSERT(file < PROGRAM_FILE_MAX); - ASSERT(index >= minIndex); - (void) minIndex; - ASSERT(index <= maxIndex); - (void) maxIndex; - memset(r, 0, sizeof(*r)); - r->Base.File = file; - r->Base.Index = index; - r->Base.Swizzle = swizzle; - r->Symbol = NULL; -} - - -/** - * Validate the set of inputs used by a program - * - * Validates that legal sets of inputs are used by the program. In this case - * "used" included both reading the input or binding the input to a name using - * the \c ATTRIB command. - * - * \return - * \c TRUE if the combination of inputs used is valid, \c FALSE otherwise. - */ -int -validate_inputs(struct YYLTYPE *locp, struct asm_parser_state *state) -{ - const int inputs = state->prog->InputsRead | state->InputsBound; - - if (((inputs & 0x0ffff) & (inputs >> 16)) != 0) { - yyerror(locp, state, "illegal use of generic attribute and name attribute"); - return 0; - } - - return 1; -} - - -struct asm_symbol * -declare_variable(struct asm_parser_state *state, char *name, enum asm_type t, - struct YYLTYPE *locp) -{ - struct asm_symbol *s = NULL; - struct asm_symbol *exist = (struct asm_symbol *) - _mesa_symbol_table_find_symbol(state->st, 0, name); - - - if (exist != NULL) { - yyerror(locp, state, "redeclared identifier"); - } else { - s = calloc(1, sizeof(struct asm_symbol)); - s->name = name; - s->type = t; - - switch (t) { - case at_temp: - if (state->prog->NumTemporaries >= state->limits->MaxTemps) { - yyerror(locp, state, "too many temporaries declared"); - free(s); - return NULL; - } - - s->temp_binding = state->prog->NumTemporaries; - state->prog->NumTemporaries++; - break; - - case at_address: - if (state->prog->NumAddressRegs >= state->limits->MaxAddressRegs) { - yyerror(locp, state, "too many address registers declared"); - free(s); - return NULL; - } - - /* FINISHME: Add support for multiple address registers. - */ - state->prog->NumAddressRegs++; - break; - - default: - break; - } - - _mesa_symbol_table_add_symbol(state->st, 0, s->name, s); - s->next = state->sym; - state->sym = s; - } - - return s; -} - - -int add_state_reference(struct gl_program_parameter_list *param_list, - const gl_state_index tokens[STATE_LENGTH]) -{ - const GLuint size = 4; /* XXX fix */ - char *name; - GLint index; - - name = _mesa_program_state_string(tokens); - index = _mesa_add_parameter(param_list, PROGRAM_STATE_VAR, name, - size, GL_NONE, NULL, tokens, 0x0); - param_list->StateFlags |= _mesa_program_state_flags(tokens); - - /* free name string here since we duplicated it in add_parameter() */ - free(name); - - return index; -} - - -int -initialize_symbol_from_state(struct gl_program *prog, - struct asm_symbol *param_var, - const gl_state_index tokens[STATE_LENGTH]) -{ - int idx = -1; - gl_state_index state_tokens[STATE_LENGTH]; - - - memcpy(state_tokens, tokens, sizeof(state_tokens)); - - param_var->type = at_param; - param_var->param_binding_type = PROGRAM_STATE_VAR; - - /* If we are adding a STATE_MATRIX that has multiple rows, we need to - * unroll it and call add_state_reference() for each row - */ - 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])) { - int row; - const int first_row = state_tokens[2]; - const int last_row = state_tokens[3]; - - for (row = first_row; row <= last_row; row++) { - state_tokens[2] = state_tokens[3] = row; - - idx = add_state_reference(prog->Parameters, state_tokens); - if (param_var->param_binding_begin == ~0U) { - param_var->param_binding_begin = idx; - param_var->param_binding_swizzle = SWIZZLE_XYZW; - } - - param_var->param_binding_length++; - } - } - else { - idx = add_state_reference(prog->Parameters, state_tokens); - if (param_var->param_binding_begin == ~0U) { - param_var->param_binding_begin = idx; - param_var->param_binding_swizzle = SWIZZLE_XYZW; - } - param_var->param_binding_length++; - } - - return idx; -} - - -int -initialize_symbol_from_param(struct gl_program *prog, - struct asm_symbol *param_var, - const gl_state_index tokens[STATE_LENGTH]) -{ - int idx = -1; - gl_state_index state_tokens[STATE_LENGTH]; - - - memcpy(state_tokens, tokens, sizeof(state_tokens)); - - assert((state_tokens[0] == STATE_VERTEX_PROGRAM) - || (state_tokens[0] == STATE_FRAGMENT_PROGRAM)); - assert((state_tokens[1] == STATE_ENV) - || (state_tokens[1] == STATE_LOCAL)); - - /* - * The param type is STATE_VAR. The program parameter entry will - * effectively be a pointer into the LOCAL or ENV parameter array. - */ - param_var->type = at_param; - param_var->param_binding_type = PROGRAM_STATE_VAR; - - /* If we are adding a STATE_ENV or STATE_LOCAL that has multiple elements, - * we need to unroll it and call add_state_reference() for each row - */ - if (state_tokens[2] != state_tokens[3]) { - int row; - const int first_row = state_tokens[2]; - const int last_row = state_tokens[3]; - - for (row = first_row; row <= last_row; row++) { - state_tokens[2] = state_tokens[3] = row; - - idx = add_state_reference(prog->Parameters, state_tokens); - if (param_var->param_binding_begin == ~0U) { - param_var->param_binding_begin = idx; - param_var->param_binding_swizzle = SWIZZLE_XYZW; - } - param_var->param_binding_length++; - } - } - else { - idx = add_state_reference(prog->Parameters, state_tokens); - if (param_var->param_binding_begin == ~0U) { - param_var->param_binding_begin = idx; - param_var->param_binding_swizzle = SWIZZLE_XYZW; - } - param_var->param_binding_length++; - } - - return idx; -} - - -/** - * Put a float/vector constant/literal into the parameter list. - * \param param_var returns info about the parameter/constant's location, - * binding, type, etc. - * \param vec the vector/constant to add - * \param allowSwizzle if true, try to consolidate constants which only differ - * by a swizzle. We don't want to do this when building - * arrays of constants that may be indexed indirectly. - * \return index of the constant in the parameter list. - */ -int -initialize_symbol_from_const(struct gl_program *prog, - struct asm_symbol *param_var, - const struct asm_vector *vec, - GLboolean allowSwizzle) -{ - unsigned swizzle; - const int idx = _mesa_add_unnamed_constant(prog->Parameters, - vec->data, vec->count, - allowSwizzle ? &swizzle : NULL); - - param_var->type = at_param; - param_var->param_binding_type = PROGRAM_CONSTANT; - - if (param_var->param_binding_begin == ~0U) { - param_var->param_binding_begin = idx; - param_var->param_binding_swizzle = allowSwizzle ? swizzle : SWIZZLE_XYZW; - } - param_var->param_binding_length++; - - return idx; -} - - -char * -make_error_string(const char *fmt, ...) -{ - int length; - char *str; - va_list args; - - va_start(args, fmt); - - /* Call vsnprintf once to determine how large the final string is. Call it - * again to do the actual formatting. from the v_mesa_snprintf manual page: - * - * Upon successful return, these functions return the number of - * characters printed (not including the trailing '\0' used to end - * output to strings). - */ - length = 1 + vsnprintf(NULL, 0, fmt, args); - - str = malloc(length); - if (str) { - vsnprintf(str, length, fmt, args); - } - - va_end(args); - - return str; -} - - -void -yyerror(YYLTYPE *locp, struct asm_parser_state *state, const char *s) -{ - char *err_str; - - - err_str = make_error_string("glProgramStringARB(%s)\n", s); - if (err_str) { - _mesa_error(state->ctx, GL_INVALID_OPERATION, err_str); - free(err_str); - } - - err_str = make_error_string("line %u, char %u: error: %s\n", - locp->first_line, locp->first_column, s); - _mesa_set_program_error(state->ctx, locp->position, err_str); - - if (err_str) { - free(err_str); - } -} - - -GLboolean -_mesa_parse_arb_program(GLcontext *ctx, GLenum target, const GLubyte *str, - GLsizei len, struct asm_parser_state *state) -{ - struct asm_instruction *inst; - unsigned i; - GLubyte *strz; - GLboolean result = GL_FALSE; - void *temp; - struct asm_symbol *sym; - - state->ctx = ctx; - state->prog->Target = target; - state->prog->Parameters = _mesa_new_parameter_list(); - - /* Make a copy of the program string and force it to be NUL-terminated. - */ - strz = (GLubyte *) malloc(len + 1); - if (strz == NULL) { - _mesa_error(ctx, GL_OUT_OF_MEMORY, "glProgramStringARB"); - return GL_FALSE; - } - memcpy (strz, str, len); - strz[len] = '\0'; - - state->prog->String = strz; - - state->st = _mesa_symbol_table_ctor(); - - state->limits = (target == GL_VERTEX_PROGRAM_ARB) - ? & ctx->Const.VertexProgram - : & ctx->Const.FragmentProgram; - - state->MaxTextureImageUnits = ctx->Const.MaxTextureImageUnits; - state->MaxTextureCoordUnits = ctx->Const.MaxTextureCoordUnits; - state->MaxTextureUnits = ctx->Const.MaxTextureUnits; - state->MaxClipPlanes = ctx->Const.MaxClipPlanes; - state->MaxLights = ctx->Const.MaxLights; - state->MaxProgramMatrices = ctx->Const.MaxProgramMatrices; - - state->state_param_enum = (target == GL_VERTEX_PROGRAM_ARB) - ? STATE_VERTEX_PROGRAM : STATE_FRAGMENT_PROGRAM; - - _mesa_set_program_error(ctx, -1, NULL); - - _mesa_program_lexer_ctor(& state->scanner, state, (const char *) str, len); - yyparse(state); - _mesa_program_lexer_dtor(state->scanner); - - - if (ctx->Program.ErrorPos != -1) { - goto error; - } - - if (! _mesa_layout_parameters(state)) { - struct YYLTYPE loc; - - loc.first_line = 0; - loc.first_column = 0; - loc.position = len; - - yyerror(& loc, state, "invalid PARAM usage"); - goto error; - } - - - - /* Add one instruction to store the "END" instruction. - */ - state->prog->Instructions = - _mesa_alloc_instructions(state->prog->NumInstructions + 1); - inst = state->inst_head; - for (i = 0; i < state->prog->NumInstructions; i++) { - struct asm_instruction *const temp = inst->next; - - state->prog->Instructions[i] = inst->Base; - inst = temp; - } - - /* Finally, tag on an OPCODE_END instruction */ - { - const GLuint numInst = state->prog->NumInstructions; - _mesa_init_instructions(state->prog->Instructions + numInst, 1); - state->prog->Instructions[numInst].Opcode = OPCODE_END; - } - state->prog->NumInstructions++; - - state->prog->NumParameters = state->prog->Parameters->NumParameters; - state->prog->NumAttributes = _mesa_bitcount(state->prog->InputsRead); - - /* - * Initialize native counts to logical counts. The device driver may - * change them if program is translated into a hardware program. - */ - state->prog->NumNativeInstructions = state->prog->NumInstructions; - state->prog->NumNativeTemporaries = state->prog->NumTemporaries; - state->prog->NumNativeParameters = state->prog->NumParameters; - state->prog->NumNativeAttributes = state->prog->NumAttributes; - state->prog->NumNativeAddressRegs = state->prog->NumAddressRegs; - - result = GL_TRUE; - -error: - for (inst = state->inst_head; inst != NULL; inst = temp) { - temp = inst->next; - free(inst); - } - - state->inst_head = NULL; - state->inst_tail = NULL; - - for (sym = state->sym; sym != NULL; sym = temp) { - temp = sym->next; - - free((void *) sym->name); - free(sym); - } - state->sym = NULL; - - _mesa_symbol_table_dtor(state->st); - state->st = NULL; - - return result; -} - diff --git a/mesalib/src/mesa/shader/program_parse.tab.h b/mesalib/src/mesa/shader/program_parse.tab.h deleted file mode 100644 index 045241d9e..000000000 --- a/mesalib/src/mesa/shader/program_parse.tab.h +++ /dev/null @@ -1,209 +0,0 @@ - -/* A Bison parser, made by GNU Bison 2.4.1. */ - -/* Skeleton interface for Bison's Yacc-like parsers in C - - Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005, 2006 - 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 3 of the License, 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, see <http://www.gnu.org/licenses/>. */ - -/* As a special exception, you may create a larger work that contains - part or all of the Bison parser skeleton and distribute that work - under terms of your choice, so long as that work isn't itself a - parser generator using the skeleton or a modified version thereof - as a parser skeleton. Alternatively, if you modify or redistribute - the parser skeleton itself, you may (at your option) remove this - special exception, which will cause the skeleton and the resulting - Bison output files to be licensed under the GNU General Public - License without this special exception. - - This special exception was added by the Free Software Foundation in - version 2.2 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 { - ARBvp_10 = 258, - ARBfp_10 = 259, - ADDRESS = 260, - ALIAS = 261, - ATTRIB = 262, - OPTION = 263, - OUTPUT = 264, - PARAM = 265, - TEMP = 266, - END = 267, - BIN_OP = 268, - BINSC_OP = 269, - SAMPLE_OP = 270, - SCALAR_OP = 271, - TRI_OP = 272, - VECTOR_OP = 273, - ARL = 274, - KIL = 275, - SWZ = 276, - TXD_OP = 277, - INTEGER = 278, - REAL = 279, - AMBIENT = 280, - ATTENUATION = 281, - BACK = 282, - CLIP = 283, - COLOR = 284, - DEPTH = 285, - DIFFUSE = 286, - DIRECTION = 287, - EMISSION = 288, - ENV = 289, - EYE = 290, - FOG = 291, - FOGCOORD = 292, - FRAGMENT = 293, - FRONT = 294, - HALF = 295, - INVERSE = 296, - INVTRANS = 297, - LIGHT = 298, - LIGHTMODEL = 299, - LIGHTPROD = 300, - LOCAL = 301, - MATERIAL = 302, - MAT_PROGRAM = 303, - MATRIX = 304, - MATRIXINDEX = 305, - MODELVIEW = 306, - MVP = 307, - NORMAL = 308, - OBJECT = 309, - PALETTE = 310, - PARAMS = 311, - PLANE = 312, - POINT_TOK = 313, - POINTSIZE = 314, - POSITION = 315, - PRIMARY = 316, - PROGRAM = 317, - PROJECTION = 318, - RANGE = 319, - RESULT = 320, - ROW = 321, - SCENECOLOR = 322, - SECONDARY = 323, - SHININESS = 324, - SIZE_TOK = 325, - SPECULAR = 326, - SPOT = 327, - STATE = 328, - TEXCOORD = 329, - TEXENV = 330, - TEXGEN = 331, - TEXGEN_Q = 332, - TEXGEN_R = 333, - TEXGEN_S = 334, - TEXGEN_T = 335, - TEXTURE = 336, - TRANSPOSE = 337, - TEXTURE_UNIT = 338, - TEX_1D = 339, - TEX_2D = 340, - TEX_3D = 341, - TEX_CUBE = 342, - TEX_RECT = 343, - TEX_SHADOW1D = 344, - TEX_SHADOW2D = 345, - TEX_SHADOWRECT = 346, - TEX_ARRAY1D = 347, - TEX_ARRAY2D = 348, - TEX_ARRAYSHADOW1D = 349, - TEX_ARRAYSHADOW2D = 350, - VERTEX = 351, - VTXATTRIB = 352, - WEIGHT = 353, - IDENTIFIER = 354, - USED_IDENTIFIER = 355, - MASK4 = 356, - MASK3 = 357, - MASK2 = 358, - MASK1 = 359, - SWIZZLE = 360, - DOT_DOT = 361, - DOT = 362 - }; -#endif - - - -#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED -typedef union YYSTYPE -{ - -/* Line 1676 of yacc.c */ -#line 126 "program_parse.y" - - struct asm_instruction *inst; - struct asm_symbol *sym; - struct asm_symbol temp_sym; - struct asm_swizzle_mask swiz_mask; - struct asm_src_register src_reg; - struct prog_dst_register dst_reg; - struct prog_instruction temp_inst; - char *string; - unsigned result; - unsigned attrib; - int integer; - float real; - gl_state_index state[STATE_LENGTH]; - int negate; - struct asm_vector vector; - gl_inst_opcode opcode; - - struct { - unsigned swz; - unsigned rgba_valid:1; - unsigned xyzw_valid:1; - unsigned negate:1; - } ext_swizzle; - - - -/* Line 1676 of yacc.c */ -#line 187 "program_parse.tab.h" -} YYSTYPE; -# define YYSTYPE_IS_TRIVIAL 1 -# define yystype YYSTYPE /* obsolescent; will be withdrawn */ -# define YYSTYPE_IS_DECLARED 1 -#endif - - - -#if ! defined YYLTYPE && ! defined YYLTYPE_IS_DECLARED -typedef struct YYLTYPE -{ - int first_line; - int first_column; - int last_line; - int last_column; -} YYLTYPE; -# define yyltype YYLTYPE /* obsolescent; will be withdrawn */ -# define YYLTYPE_IS_DECLARED 1 -# define YYLTYPE_IS_TRIVIAL 1 -#endif - - - diff --git a/mesalib/src/mesa/shader/program_parse.y b/mesalib/src/mesa/shader/program_parse.y deleted file mode 100644 index d5fb0fac3..000000000 --- a/mesalib/src/mesa/shader/program_parse.y +++ /dev/null @@ -1,2766 +0,0 @@ -%{ -/* - * Copyright © 2009 Intel Corporation - * - * 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 (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 NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS 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 <stdio.h> -#include <stdlib.h> -#include <string.h> - -#include "main/mtypes.h" -#include "main/imports.h" -#include "shader/program.h" -#include "shader/prog_parameter.h" -#include "shader/prog_parameter_layout.h" -#include "shader/prog_statevars.h" -#include "shader/prog_instruction.h" - -#include "shader/symbol_table.h" -#include "shader/program_parser.h" - -extern void *yy_scan_string(char *); -extern void yy_delete_buffer(void *); - -static struct asm_symbol *declare_variable(struct asm_parser_state *state, - char *name, enum asm_type t, struct YYLTYPE *locp); - -static int add_state_reference(struct gl_program_parameter_list *param_list, - const gl_state_index tokens[STATE_LENGTH]); - -static int initialize_symbol_from_state(struct gl_program *prog, - struct asm_symbol *param_var, const gl_state_index tokens[STATE_LENGTH]); - -static int initialize_symbol_from_param(struct gl_program *prog, - struct asm_symbol *param_var, const gl_state_index tokens[STATE_LENGTH]); - -static int initialize_symbol_from_const(struct gl_program *prog, - struct asm_symbol *param_var, const struct asm_vector *vec, - GLboolean allowSwizzle); - -static int yyparse(struct asm_parser_state *state); - -static char *make_error_string(const char *fmt, ...); - -static void yyerror(struct YYLTYPE *locp, struct asm_parser_state *state, - const char *s); - -static int validate_inputs(struct YYLTYPE *locp, - struct asm_parser_state *state); - -static void init_dst_reg(struct prog_dst_register *r); - -static void set_dst_reg(struct prog_dst_register *r, - gl_register_file file, GLint index); - -static void init_src_reg(struct asm_src_register *r); - -static void set_src_reg(struct asm_src_register *r, - gl_register_file file, GLint index); - -static void set_src_reg_swz(struct asm_src_register *r, - gl_register_file file, GLint index, GLuint swizzle); - -static void asm_instruction_set_operands(struct asm_instruction *inst, - const struct prog_dst_register *dst, const struct asm_src_register *src0, - const struct asm_src_register *src1, const struct asm_src_register *src2); - -static struct asm_instruction *asm_instruction_ctor(gl_inst_opcode op, - const struct prog_dst_register *dst, const struct asm_src_register *src0, - const struct asm_src_register *src1, const struct asm_src_register *src2); - -static struct asm_instruction *asm_instruction_copy_ctor( - const struct prog_instruction *base, const struct prog_dst_register *dst, - const struct asm_src_register *src0, const struct asm_src_register *src1, - const struct asm_src_register *src2); - -#ifndef FALSE -#define FALSE 0 -#define TRUE (!FALSE) -#endif - -#define YYLLOC_DEFAULT(Current, Rhs, N) \ - do { \ - if (YYID(N)) { \ - (Current).first_line = YYRHSLOC(Rhs, 1).first_line; \ - (Current).first_column = YYRHSLOC(Rhs, 1).first_column; \ - (Current).position = YYRHSLOC(Rhs, 1).position; \ - (Current).last_line = YYRHSLOC(Rhs, N).last_line; \ - (Current).last_column = YYRHSLOC(Rhs, N).last_column; \ - } else { \ - (Current).first_line = YYRHSLOC(Rhs, 0).last_line; \ - (Current).last_line = (Current).first_line; \ - (Current).first_column = YYRHSLOC(Rhs, 0).last_column; \ - (Current).last_column = (Current).first_column; \ - (Current).position = YYRHSLOC(Rhs, 0).position \ - + (Current).first_column; \ - } \ - } while(YYID(0)) - -#define YYLEX_PARAM state->scanner -%} - -%pure-parser -%locations -%parse-param { struct asm_parser_state *state } -%error-verbose -%lex-param { void *scanner } - -%union { - struct asm_instruction *inst; - struct asm_symbol *sym; - struct asm_symbol temp_sym; - struct asm_swizzle_mask swiz_mask; - struct asm_src_register src_reg; - struct prog_dst_register dst_reg; - struct prog_instruction temp_inst; - char *string; - unsigned result; - unsigned attrib; - int integer; - float real; - gl_state_index state[STATE_LENGTH]; - int negate; - struct asm_vector vector; - gl_inst_opcode opcode; - - struct { - unsigned swz; - unsigned rgba_valid:1; - unsigned xyzw_valid:1; - unsigned negate:1; - } ext_swizzle; -} - -%token ARBvp_10 ARBfp_10 - -/* Tokens for assembler pseudo-ops */ -%token <integer> ADDRESS -%token ALIAS ATTRIB -%token OPTION OUTPUT -%token PARAM -%token <integer> TEMP -%token END - - /* Tokens for instructions */ -%token <temp_inst> BIN_OP BINSC_OP SAMPLE_OP SCALAR_OP TRI_OP VECTOR_OP -%token <temp_inst> ARL KIL SWZ TXD_OP - -%token <integer> INTEGER -%token <real> REAL - -%token AMBIENT ATTENUATION -%token BACK -%token CLIP COLOR -%token DEPTH DIFFUSE DIRECTION -%token EMISSION ENV EYE -%token FOG FOGCOORD FRAGMENT FRONT -%token HALF -%token INVERSE INVTRANS -%token LIGHT LIGHTMODEL LIGHTPROD LOCAL -%token MATERIAL MAT_PROGRAM MATRIX MATRIXINDEX MODELVIEW MVP -%token NORMAL -%token OBJECT -%token PALETTE PARAMS PLANE POINT_TOK POINTSIZE POSITION PRIMARY PROGRAM PROJECTION -%token RANGE RESULT ROW -%token SCENECOLOR SECONDARY SHININESS SIZE_TOK SPECULAR SPOT STATE -%token TEXCOORD TEXENV TEXGEN TEXGEN_Q TEXGEN_R TEXGEN_S TEXGEN_T TEXTURE TRANSPOSE -%token TEXTURE_UNIT TEX_1D TEX_2D TEX_3D TEX_CUBE TEX_RECT -%token TEX_SHADOW1D TEX_SHADOW2D TEX_SHADOWRECT -%token TEX_ARRAY1D TEX_ARRAY2D TEX_ARRAYSHADOW1D TEX_ARRAYSHADOW2D -%token VERTEX VTXATTRIB -%token WEIGHT - -%token <string> IDENTIFIER USED_IDENTIFIER -%type <string> string -%token <swiz_mask> MASK4 MASK3 MASK2 MASK1 SWIZZLE -%token DOT_DOT -%token DOT - -%type <inst> instruction ALU_instruction TexInstruction -%type <inst> ARL_instruction VECTORop_instruction -%type <inst> SCALARop_instruction BINSCop_instruction BINop_instruction -%type <inst> TRIop_instruction TXD_instruction SWZ_instruction SAMPLE_instruction -%type <inst> KIL_instruction - -%type <dst_reg> dstReg maskedDstReg maskedAddrReg -%type <src_reg> srcReg scalarUse scalarSrcReg swizzleSrcReg -%type <swiz_mask> scalarSuffix swizzleSuffix extendedSwizzle -%type <ext_swizzle> extSwizComp extSwizSel -%type <swiz_mask> optionalMask - -%type <sym> progParamArray -%type <integer> addrRegRelOffset addrRegPosOffset addrRegNegOffset -%type <src_reg> progParamArrayMem progParamArrayAbs progParamArrayRel -%type <sym> addrReg -%type <swiz_mask> addrComponent addrWriteMask - -%type <dst_reg> ccMaskRule ccTest ccMaskRule2 ccTest2 optionalCcMask - -%type <result> resultBinding resultColBinding -%type <integer> optFaceType optColorType -%type <integer> optResultFaceType optResultColorType - -%type <integer> optTexImageUnitNum texImageUnitNum -%type <integer> optTexCoordUnitNum texCoordUnitNum -%type <integer> optLegacyTexUnitNum legacyTexUnitNum -%type <integer> texImageUnit texTarget -%type <integer> vtxAttribNum - -%type <attrib> attribBinding vtxAttribItem fragAttribItem - -%type <temp_sym> paramSingleInit paramSingleItemDecl -%type <integer> optArraySize - -%type <state> stateSingleItem stateMultipleItem -%type <state> stateMaterialItem -%type <state> stateLightItem stateLightModelItem stateLightProdItem -%type <state> stateTexGenItem stateFogItem stateClipPlaneItem statePointItem -%type <state> stateMatrixItem stateMatrixRow stateMatrixRows -%type <state> stateTexEnvItem stateDepthItem - -%type <state> stateLModProperty -%type <state> stateMatrixName optMatrixRows - -%type <integer> stateMatProperty -%type <integer> stateLightProperty stateSpotProperty -%type <integer> stateLightNumber stateLProdProperty -%type <integer> stateTexGenType stateTexGenCoord -%type <integer> stateTexEnvProperty -%type <integer> stateFogProperty -%type <integer> stateClipPlaneNum -%type <integer> statePointProperty - -%type <integer> stateOptMatModifier stateMatModifier stateMatrixRowNum -%type <integer> stateOptModMatNum stateModMatNum statePaletteMatNum -%type <integer> stateProgramMatNum - -%type <integer> ambDiffSpecProperty - -%type <state> programSingleItem progEnvParam progLocalParam -%type <state> programMultipleItem progEnvParams progLocalParams - -%type <temp_sym> paramMultipleInit paramMultInitList paramMultipleItem -%type <temp_sym> paramSingleItemUse - -%type <integer> progEnvParamNum progLocalParamNum -%type <state> progEnvParamNums progLocalParamNums - -%type <vector> paramConstDecl paramConstUse -%type <vector> paramConstScalarDecl paramConstScalarUse paramConstVector -%type <real> signedFloatConstant -%type <negate> optionalSign - -%{ -extern int yylex(YYSTYPE *yylval_param, YYLTYPE *yylloc_param, - void *yyscanner); -%} - -%% - -program: language optionSequence statementSequence END - ; - -language: ARBvp_10 - { - if (state->prog->Target != GL_VERTEX_PROGRAM_ARB) { - yyerror(& @1, state, "invalid fragment program header"); - - } - state->mode = ARB_vertex; - } - | ARBfp_10 - { - if (state->prog->Target != GL_FRAGMENT_PROGRAM_ARB) { - yyerror(& @1, state, "invalid vertex program header"); - } - state->mode = ARB_fragment; - - state->option.TexRect = - (state->ctx->Extensions.NV_texture_rectangle != GL_FALSE); - } - ; - -optionSequence: optionSequence option - | - ; - -option: OPTION string ';' - { - int valid = 0; - - if (state->mode == ARB_vertex) { - valid = _mesa_ARBvp_parse_option(state, $2); - } else if (state->mode == ARB_fragment) { - valid = _mesa_ARBfp_parse_option(state, $2); - } - - - free($2); - - if (!valid) { - const char *const err_str = (state->mode == ARB_vertex) - ? "invalid ARB vertex program option" - : "invalid ARB fragment program option"; - - yyerror(& @2, state, err_str); - YYERROR; - } - } - ; - -statementSequence: statementSequence statement - | - ; - -statement: instruction ';' - { - if ($1 != NULL) { - if (state->inst_tail == NULL) { - state->inst_head = $1; - } else { - state->inst_tail->next = $1; - } - - state->inst_tail = $1; - $1->next = NULL; - - state->prog->NumInstructions++; - } - } - | namingStatement ';' - ; - -instruction: ALU_instruction - { - $$ = $1; - state->prog->NumAluInstructions++; - } - | TexInstruction - { - $$ = $1; - state->prog->NumTexInstructions++; - } - ; - -ALU_instruction: ARL_instruction - | VECTORop_instruction - | SCALARop_instruction - | BINSCop_instruction - | BINop_instruction - | TRIop_instruction - | SWZ_instruction - ; - -TexInstruction: SAMPLE_instruction - | KIL_instruction - | TXD_instruction - ; - -ARL_instruction: ARL maskedAddrReg ',' scalarSrcReg - { - $$ = asm_instruction_ctor(OPCODE_ARL, & $2, & $4, NULL, NULL); - } - ; - -VECTORop_instruction: VECTOR_OP maskedDstReg ',' swizzleSrcReg - { - $$ = asm_instruction_copy_ctor(& $1, & $2, & $4, NULL, NULL); - } - ; - -SCALARop_instruction: SCALAR_OP maskedDstReg ',' scalarSrcReg - { - $$ = asm_instruction_copy_ctor(& $1, & $2, & $4, NULL, NULL); - } - ; - -BINSCop_instruction: BINSC_OP maskedDstReg ',' scalarSrcReg ',' scalarSrcReg - { - $$ = asm_instruction_copy_ctor(& $1, & $2, & $4, & $6, NULL); - } - ; - - -BINop_instruction: BIN_OP maskedDstReg ',' swizzleSrcReg ',' swizzleSrcReg - { - $$ = asm_instruction_copy_ctor(& $1, & $2, & $4, & $6, NULL); - } - ; - -TRIop_instruction: TRI_OP maskedDstReg ',' - swizzleSrcReg ',' swizzleSrcReg ',' swizzleSrcReg - { - $$ = asm_instruction_copy_ctor(& $1, & $2, & $4, & $6, & $8); - } - ; - -SAMPLE_instruction: SAMPLE_OP maskedDstReg ',' swizzleSrcReg ',' texImageUnit ',' texTarget - { - $$ = asm_instruction_copy_ctor(& $1, & $2, & $4, NULL, NULL); - if ($$ != NULL) { - const GLbitfield tex_mask = (1U << $6); - GLbitfield shadow_tex = 0; - GLbitfield target_mask = 0; - - - $$->Base.TexSrcUnit = $6; - - if ($8 < 0) { - shadow_tex = tex_mask; - - $$->Base.TexSrcTarget = -$8; - $$->Base.TexShadow = 1; - } else { - $$->Base.TexSrcTarget = $8; - } - - target_mask = (1U << $$->Base.TexSrcTarget); - - /* If this texture unit was previously accessed and that access - * had a different texture target, generate an error. - * - * If this texture unit was previously accessed and that access - * had a different shadow mode, generate an error. - */ - if ((state->prog->TexturesUsed[$6] != 0) - && ((state->prog->TexturesUsed[$6] != target_mask) - || ((state->prog->ShadowSamplers & tex_mask) - != shadow_tex))) { - yyerror(& @8, state, - "multiple targets used on one texture image unit"); - YYERROR; - } - - - state->prog->TexturesUsed[$6] |= target_mask; - state->prog->ShadowSamplers |= shadow_tex; - } - } - ; - -KIL_instruction: KIL swizzleSrcReg - { - $$ = asm_instruction_ctor(OPCODE_KIL, NULL, & $2, NULL, NULL); - state->fragment.UsesKill = 1; - } - | KIL ccTest - { - $$ = asm_instruction_ctor(OPCODE_KIL_NV, NULL, NULL, NULL, NULL); - $$->Base.DstReg.CondMask = $2.CondMask; - $$->Base.DstReg.CondSwizzle = $2.CondSwizzle; - $$->Base.DstReg.CondSrc = $2.CondSrc; - state->fragment.UsesKill = 1; - } - ; - -TXD_instruction: TXD_OP maskedDstReg ',' swizzleSrcReg ',' swizzleSrcReg ',' swizzleSrcReg ',' texImageUnit ',' texTarget - { - $$ = asm_instruction_copy_ctor(& $1, & $2, & $4, & $6, & $8); - if ($$ != NULL) { - const GLbitfield tex_mask = (1U << $10); - GLbitfield shadow_tex = 0; - GLbitfield target_mask = 0; - - - $$->Base.TexSrcUnit = $10; - - if ($12 < 0) { - shadow_tex = tex_mask; - - $$->Base.TexSrcTarget = -$12; - $$->Base.TexShadow = 1; - } else { - $$->Base.TexSrcTarget = $12; - } - - target_mask = (1U << $$->Base.TexSrcTarget); - - /* If this texture unit was previously accessed and that access - * had a different texture target, generate an error. - * - * If this texture unit was previously accessed and that access - * had a different shadow mode, generate an error. - */ - if ((state->prog->TexturesUsed[$10] != 0) - && ((state->prog->TexturesUsed[$10] != target_mask) - || ((state->prog->ShadowSamplers & tex_mask) - != shadow_tex))) { - yyerror(& @12, state, - "multiple targets used on one texture image unit"); - YYERROR; - } - - - state->prog->TexturesUsed[$10] |= target_mask; - state->prog->ShadowSamplers |= shadow_tex; - } - } - ; - -texImageUnit: TEXTURE_UNIT optTexImageUnitNum - { - $$ = $2; - } - ; - -texTarget: TEX_1D { $$ = TEXTURE_1D_INDEX; } - | TEX_2D { $$ = TEXTURE_2D_INDEX; } - | TEX_3D { $$ = TEXTURE_3D_INDEX; } - | TEX_CUBE { $$ = TEXTURE_CUBE_INDEX; } - | TEX_RECT { $$ = TEXTURE_RECT_INDEX; } - | TEX_SHADOW1D { $$ = -TEXTURE_1D_INDEX; } - | TEX_SHADOW2D { $$ = -TEXTURE_2D_INDEX; } - | TEX_SHADOWRECT { $$ = -TEXTURE_RECT_INDEX; } - | TEX_ARRAY1D { $$ = TEXTURE_1D_ARRAY_INDEX; } - | TEX_ARRAY2D { $$ = TEXTURE_2D_ARRAY_INDEX; } - | TEX_ARRAYSHADOW1D { $$ = -TEXTURE_1D_ARRAY_INDEX; } - | TEX_ARRAYSHADOW2D { $$ = -TEXTURE_2D_ARRAY_INDEX; } - ; - -SWZ_instruction: SWZ maskedDstReg ',' srcReg ',' extendedSwizzle - { - /* FIXME: Is this correct? Should the extenedSwizzle be applied - * FIXME: to the existing swizzle? - */ - $4.Base.Swizzle = $6.swizzle; - $4.Base.Negate = $6.mask; - - $$ = asm_instruction_copy_ctor(& $1, & $2, & $4, NULL, NULL); - } - ; - -scalarSrcReg: optionalSign scalarUse - { - $$ = $2; - - if ($1) { - $$.Base.Negate = ~$$.Base.Negate; - } - } - | optionalSign '|' scalarUse '|' - { - $$ = $3; - - if (!state->option.NV_fragment) { - yyerror(& @2, state, "unexpected character '|'"); - YYERROR; - } - - if ($1) { - $$.Base.Negate = ~$$.Base.Negate; - } - - $$.Base.Abs = 1; - } - ; - -scalarUse: srcReg scalarSuffix - { - $$ = $1; - - $$.Base.Swizzle = _mesa_combine_swizzles($$.Base.Swizzle, - $2.swizzle); - } - | paramConstScalarUse - { - struct asm_symbol temp_sym; - - if (!state->option.NV_fragment) { - yyerror(& @1, state, "expected scalar suffix"); - YYERROR; - } - - memset(& temp_sym, 0, sizeof(temp_sym)); - temp_sym.param_binding_begin = ~0; - initialize_symbol_from_const(state->prog, & temp_sym, & $1, GL_TRUE); - - set_src_reg_swz(& $$, PROGRAM_CONSTANT, - temp_sym.param_binding_begin, - temp_sym.param_binding_swizzle); - } - ; - -swizzleSrcReg: optionalSign srcReg swizzleSuffix - { - $$ = $2; - - if ($1) { - $$.Base.Negate = ~$$.Base.Negate; - } - - $$.Base.Swizzle = _mesa_combine_swizzles($$.Base.Swizzle, - $3.swizzle); - } - | optionalSign '|' srcReg swizzleSuffix '|' - { - $$ = $3; - - if (!state->option.NV_fragment) { - yyerror(& @2, state, "unexpected character '|'"); - YYERROR; - } - - if ($1) { - $$.Base.Negate = ~$$.Base.Negate; - } - - $$.Base.Abs = 1; - $$.Base.Swizzle = _mesa_combine_swizzles($$.Base.Swizzle, - $4.swizzle); - } - - ; - -maskedDstReg: dstReg optionalMask optionalCcMask - { - $$ = $1; - $$.WriteMask = $2.mask; - $$.CondMask = $3.CondMask; - $$.CondSwizzle = $3.CondSwizzle; - $$.CondSrc = $3.CondSrc; - - if ($$.File == PROGRAM_OUTPUT) { - /* Technically speaking, this should check that it is in - * vertex program mode. However, PositionInvariant can never be - * set in fragment program mode, so it is somewhat irrelevant. - */ - if (state->option.PositionInvariant - && ($$.Index == VERT_RESULT_HPOS)) { - yyerror(& @1, state, "position-invariant programs cannot " - "write position"); - YYERROR; - } - - state->prog->OutputsWritten |= BITFIELD64_BIT($$.Index); - } - } - ; - -maskedAddrReg: addrReg addrWriteMask - { - set_dst_reg(& $$, PROGRAM_ADDRESS, 0); - $$.WriteMask = $2.mask; - } - ; - -extendedSwizzle: extSwizComp ',' extSwizComp ',' extSwizComp ',' extSwizComp - { - const unsigned xyzw_valid = - ($1.xyzw_valid << 0) - | ($3.xyzw_valid << 1) - | ($5.xyzw_valid << 2) - | ($7.xyzw_valid << 3); - const unsigned rgba_valid = - ($1.rgba_valid << 0) - | ($3.rgba_valid << 1) - | ($5.rgba_valid << 2) - | ($7.rgba_valid << 3); - - /* All of the swizzle components have to be valid in either RGBA - * or XYZW. Note that 0 and 1 are valid in both, so both masks - * can have some bits set. - * - * We somewhat deviate from the spec here. It would be really hard - * to figure out which component is the error, and there probably - * isn't a lot of benefit. - */ - if ((rgba_valid != 0x0f) && (xyzw_valid != 0x0f)) { - yyerror(& @1, state, "cannot combine RGBA and XYZW swizzle " - "components"); - YYERROR; - } - - $$.swizzle = MAKE_SWIZZLE4($1.swz, $3.swz, $5.swz, $7.swz); - $$.mask = ($1.negate) | ($3.negate << 1) | ($5.negate << 2) - | ($7.negate << 3); - } - ; - -extSwizComp: optionalSign extSwizSel - { - $$ = $2; - $$.negate = ($1) ? 1 : 0; - } - ; - -extSwizSel: INTEGER - { - if (($1 != 0) && ($1 != 1)) { - yyerror(& @1, state, "invalid extended swizzle selector"); - YYERROR; - } - - $$.swz = ($1 == 0) ? SWIZZLE_ZERO : SWIZZLE_ONE; - - /* 0 and 1 are valid for both RGBA swizzle names and XYZW - * swizzle names. - */ - $$.xyzw_valid = 1; - $$.rgba_valid = 1; - } - | string - { - char s; - - if (strlen($1) > 1) { - yyerror(& @1, state, "invalid extended swizzle selector"); - YYERROR; - } - - s = $1[0]; - free($1); - - switch (s) { - case 'x': - $$.swz = SWIZZLE_X; - $$.xyzw_valid = 1; - break; - case 'y': - $$.swz = SWIZZLE_Y; - $$.xyzw_valid = 1; - break; - case 'z': - $$.swz = SWIZZLE_Z; - $$.xyzw_valid = 1; - break; - case 'w': - $$.swz = SWIZZLE_W; - $$.xyzw_valid = 1; - break; - - case 'r': - $$.swz = SWIZZLE_X; - $$.rgba_valid = 1; - break; - case 'g': - $$.swz = SWIZZLE_Y; - $$.rgba_valid = 1; - break; - case 'b': - $$.swz = SWIZZLE_Z; - $$.rgba_valid = 1; - break; - case 'a': - $$.swz = SWIZZLE_W; - $$.rgba_valid = 1; - break; - - default: - yyerror(& @1, state, "invalid extended swizzle selector"); - YYERROR; - break; - } - } - ; - -srcReg: USED_IDENTIFIER /* temporaryReg | progParamSingle */ - { - struct asm_symbol *const s = (struct asm_symbol *) - _mesa_symbol_table_find_symbol(state->st, 0, $1); - - free($1); - - if (s == NULL) { - yyerror(& @1, state, "invalid operand variable"); - YYERROR; - } else if ((s->type != at_param) && (s->type != at_temp) - && (s->type != at_attrib)) { - yyerror(& @1, state, "invalid operand variable"); - YYERROR; - } else if ((s->type == at_param) && s->param_is_array) { - yyerror(& @1, state, "non-array access to array PARAM"); - YYERROR; - } - - init_src_reg(& $$); - switch (s->type) { - case at_temp: - set_src_reg(& $$, PROGRAM_TEMPORARY, s->temp_binding); - break; - case at_param: - set_src_reg_swz(& $$, s->param_binding_type, - s->param_binding_begin, - s->param_binding_swizzle); - break; - case at_attrib: - set_src_reg(& $$, PROGRAM_INPUT, s->attrib_binding); - state->prog->InputsRead |= (1U << $$.Base.Index); - - if (!validate_inputs(& @1, state)) { - YYERROR; - } - break; - - default: - YYERROR; - break; - } - } - | attribBinding - { - set_src_reg(& $$, PROGRAM_INPUT, $1); - state->prog->InputsRead |= (1U << $$.Base.Index); - - if (!validate_inputs(& @1, state)) { - YYERROR; - } - } - | progParamArray '[' progParamArrayMem ']' - { - if (! $3.Base.RelAddr - && ((unsigned) $3.Base.Index >= $1->param_binding_length)) { - yyerror(& @3, state, "out of bounds array access"); - YYERROR; - } - - init_src_reg(& $$); - $$.Base.File = $1->param_binding_type; - - if ($3.Base.RelAddr) { - $1->param_accessed_indirectly = 1; - - $$.Base.RelAddr = 1; - $$.Base.Index = $3.Base.Index; - $$.Symbol = $1; - } else { - $$.Base.Index = $1->param_binding_begin + $3.Base.Index; - } - } - | paramSingleItemUse - { - gl_register_file file = ($1.name != NULL) - ? $1.param_binding_type - : PROGRAM_CONSTANT; - set_src_reg_swz(& $$, file, $1.param_binding_begin, - $1.param_binding_swizzle); - } - ; - -dstReg: resultBinding - { - set_dst_reg(& $$, PROGRAM_OUTPUT, $1); - } - | USED_IDENTIFIER /* temporaryReg | vertexResultReg */ - { - struct asm_symbol *const s = (struct asm_symbol *) - _mesa_symbol_table_find_symbol(state->st, 0, $1); - - free($1); - - if (s == NULL) { - yyerror(& @1, state, "invalid operand variable"); - YYERROR; - } else if ((s->type != at_output) && (s->type != at_temp)) { - yyerror(& @1, state, "invalid operand variable"); - YYERROR; - } - - switch (s->type) { - case at_temp: - set_dst_reg(& $$, PROGRAM_TEMPORARY, s->temp_binding); - break; - case at_output: - set_dst_reg(& $$, PROGRAM_OUTPUT, s->output_binding); - break; - default: - set_dst_reg(& $$, s->param_binding_type, s->param_binding_begin); - break; - } - } - ; - -progParamArray: USED_IDENTIFIER - { - struct asm_symbol *const s = (struct asm_symbol *) - _mesa_symbol_table_find_symbol(state->st, 0, $1); - - free($1); - - if (s == NULL) { - yyerror(& @1, state, "invalid operand variable"); - YYERROR; - } else if ((s->type != at_param) || !s->param_is_array) { - yyerror(& @1, state, "array access to non-PARAM variable"); - YYERROR; - } else { - $$ = s; - } - } - ; - -progParamArrayMem: progParamArrayAbs | progParamArrayRel; - -progParamArrayAbs: INTEGER - { - init_src_reg(& $$); - $$.Base.Index = $1; - } - ; - -progParamArrayRel: addrReg addrComponent addrRegRelOffset - { - /* FINISHME: Add support for multiple address registers. - */ - /* FINISHME: Add support for 4-component address registers. - */ - init_src_reg(& $$); - $$.Base.RelAddr = 1; - $$.Base.Index = $3; - } - ; - -addrRegRelOffset: { $$ = 0; } - | '+' addrRegPosOffset { $$ = $2; } - | '-' addrRegNegOffset { $$ = -$2; } - ; - -addrRegPosOffset: INTEGER - { - if (($1 < 0) || ($1 > 63)) { - char s[100]; - _mesa_snprintf(s, sizeof(s), - "relative address offset too large (%d)", $1); - yyerror(& @1, state, s); - YYERROR; - } else { - $$ = $1; - } - } - ; - -addrRegNegOffset: INTEGER - { - if (($1 < 0) || ($1 > 64)) { - char s[100]; - _mesa_snprintf(s, sizeof(s), - "relative address offset too large (%d)", $1); - yyerror(& @1, state, s); - YYERROR; - } else { - $$ = $1; - } - } - ; - -addrReg: USED_IDENTIFIER - { - struct asm_symbol *const s = (struct asm_symbol *) - _mesa_symbol_table_find_symbol(state->st, 0, $1); - - free($1); - - if (s == NULL) { - yyerror(& @1, state, "invalid array member"); - YYERROR; - } else if (s->type != at_address) { - yyerror(& @1, state, - "invalid variable for indexed array access"); - YYERROR; - } else { - $$ = s; - } - } - ; - -addrComponent: MASK1 - { - if ($1.mask != WRITEMASK_X) { - yyerror(& @1, state, "invalid address component selector"); - YYERROR; - } else { - $$ = $1; - } - } - ; - -addrWriteMask: MASK1 - { - if ($1.mask != WRITEMASK_X) { - yyerror(& @1, state, - "address register write mask must be \".x\""); - YYERROR; - } else { - $$ = $1; - } - } - ; - -scalarSuffix: MASK1; - -swizzleSuffix: MASK1 - | MASK4 - | SWIZZLE - | { $$.swizzle = SWIZZLE_NOOP; $$.mask = WRITEMASK_XYZW; } - ; - -optionalMask: MASK4 | MASK3 | MASK2 | MASK1 - | { $$.swizzle = SWIZZLE_NOOP; $$.mask = WRITEMASK_XYZW; } - ; - -optionalCcMask: '(' ccTest ')' - { - $$ = $2; - } - | '(' ccTest2 ')' - { - $$ = $2; - } - | - { - $$.CondMask = COND_TR; - $$.CondSwizzle = SWIZZLE_NOOP; - $$.CondSrc = 0; - } - ; - -ccTest: ccMaskRule swizzleSuffix - { - $$ = $1; - $$.CondSwizzle = $2.swizzle; - } - ; - -ccTest2: ccMaskRule2 swizzleSuffix - { - $$ = $1; - $$.CondSwizzle = $2.swizzle; - } - ; - -ccMaskRule: IDENTIFIER - { - const int cond = _mesa_parse_cc($1); - if ((cond == 0) || ($1[2] != '\0')) { - char *const err_str = - make_error_string("invalid condition code \"%s\"", $1); - - yyerror(& @1, state, (err_str != NULL) - ? err_str : "invalid condition code"); - - if (err_str != NULL) { - free(err_str); - } - - YYERROR; - } - - $$.CondMask = cond; - $$.CondSwizzle = SWIZZLE_NOOP; - $$.CondSrc = 0; - } - ; - -ccMaskRule2: USED_IDENTIFIER - { - const int cond = _mesa_parse_cc($1); - if ((cond == 0) || ($1[2] != '\0')) { - char *const err_str = - make_error_string("invalid condition code \"%s\"", $1); - - yyerror(& @1, state, (err_str != NULL) - ? err_str : "invalid condition code"); - - if (err_str != NULL) { - free(err_str); - } - - YYERROR; - } - - $$.CondMask = cond; - $$.CondSwizzle = SWIZZLE_NOOP; - $$.CondSrc = 0; - } - ; - -namingStatement: ATTRIB_statement - | PARAM_statement - | TEMP_statement - | ADDRESS_statement - | OUTPUT_statement - | ALIAS_statement - ; - -ATTRIB_statement: ATTRIB IDENTIFIER '=' attribBinding - { - struct asm_symbol *const s = - declare_variable(state, $2, at_attrib, & @2); - - if (s == NULL) { - free($2); - YYERROR; - } else { - s->attrib_binding = $4; - state->InputsBound |= (1U << s->attrib_binding); - - if (!validate_inputs(& @4, state)) { - YYERROR; - } - } - } - ; - -attribBinding: VERTEX vtxAttribItem - { - $$ = $2; - } - | FRAGMENT fragAttribItem - { - $$ = $2; - } - ; - -vtxAttribItem: POSITION - { - $$ = VERT_ATTRIB_POS; - } - | WEIGHT vtxOptWeightNum - { - $$ = VERT_ATTRIB_WEIGHT; - } - | NORMAL - { - $$ = VERT_ATTRIB_NORMAL; - } - | COLOR optColorType - { - if (!state->ctx->Extensions.EXT_secondary_color) { - yyerror(& @2, state, "GL_EXT_secondary_color not supported"); - YYERROR; - } - - $$ = VERT_ATTRIB_COLOR0 + $2; - } - | FOGCOORD - { - if (!state->ctx->Extensions.EXT_fog_coord) { - yyerror(& @1, state, "GL_EXT_fog_coord not supported"); - YYERROR; - } - - $$ = VERT_ATTRIB_FOG; - } - | TEXCOORD optTexCoordUnitNum - { - $$ = VERT_ATTRIB_TEX0 + $2; - } - | MATRIXINDEX '[' vtxWeightNum ']' - { - yyerror(& @1, state, "GL_ARB_matrix_palette not supported"); - YYERROR; - } - | VTXATTRIB '[' vtxAttribNum ']' - { - $$ = VERT_ATTRIB_GENERIC0 + $3; - } - ; - -vtxAttribNum: INTEGER - { - if ((unsigned) $1 >= state->limits->MaxAttribs) { - yyerror(& @1, state, "invalid vertex attribute reference"); - YYERROR; - } - - $$ = $1; - } - ; - -vtxOptWeightNum: | '[' vtxWeightNum ']'; -vtxWeightNum: INTEGER; - -fragAttribItem: POSITION - { - $$ = FRAG_ATTRIB_WPOS; - } - | COLOR optColorType - { - $$ = FRAG_ATTRIB_COL0 + $2; - } - | FOGCOORD - { - $$ = FRAG_ATTRIB_FOGC; - } - | TEXCOORD optTexCoordUnitNum - { - $$ = FRAG_ATTRIB_TEX0 + $2; - } - ; - -PARAM_statement: PARAM_singleStmt | PARAM_multipleStmt; - -PARAM_singleStmt: PARAM IDENTIFIER paramSingleInit - { - struct asm_symbol *const s = - declare_variable(state, $2, at_param, & @2); - - if (s == NULL) { - free($2); - YYERROR; - } else { - s->param_binding_type = $3.param_binding_type; - s->param_binding_begin = $3.param_binding_begin; - s->param_binding_length = $3.param_binding_length; - s->param_binding_swizzle = SWIZZLE_XYZW; - s->param_is_array = 0; - } - } - ; - -PARAM_multipleStmt: PARAM IDENTIFIER '[' optArraySize ']' paramMultipleInit - { - if (($4 != 0) && ((unsigned) $4 != $6.param_binding_length)) { - free($2); - yyerror(& @4, state, - "parameter array size and number of bindings must match"); - YYERROR; - } else { - struct asm_symbol *const s = - declare_variable(state, $2, $6.type, & @2); - - if (s == NULL) { - free($2); - YYERROR; - } else { - s->param_binding_type = $6.param_binding_type; - s->param_binding_begin = $6.param_binding_begin; - s->param_binding_length = $6.param_binding_length; - s->param_binding_swizzle = SWIZZLE_XYZW; - s->param_is_array = 1; - } - } - } - ; - -optArraySize: - { - $$ = 0; - } - | INTEGER - { - if (($1 < 1) || ((unsigned) $1 > state->limits->MaxParameters)) { - yyerror(& @1, state, "invalid parameter array size"); - YYERROR; - } else { - $$ = $1; - } - } - ; - -paramSingleInit: '=' paramSingleItemDecl - { - $$ = $2; - } - ; - -paramMultipleInit: '=' '{' paramMultInitList '}' - { - $$ = $3; - } - ; - -paramMultInitList: paramMultipleItem - | paramMultInitList ',' paramMultipleItem - { - $1.param_binding_length += $3.param_binding_length; - $$ = $1; - } - ; - -paramSingleItemDecl: stateSingleItem - { - memset(& $$, 0, sizeof($$)); - $$.param_binding_begin = ~0; - initialize_symbol_from_state(state->prog, & $$, $1); - } - | programSingleItem - { - memset(& $$, 0, sizeof($$)); - $$.param_binding_begin = ~0; - initialize_symbol_from_param(state->prog, & $$, $1); - } - | paramConstDecl - { - memset(& $$, 0, sizeof($$)); - $$.param_binding_begin = ~0; - initialize_symbol_from_const(state->prog, & $$, & $1, GL_TRUE); - } - ; - -paramSingleItemUse: stateSingleItem - { - memset(& $$, 0, sizeof($$)); - $$.param_binding_begin = ~0; - initialize_symbol_from_state(state->prog, & $$, $1); - } - | programSingleItem - { - memset(& $$, 0, sizeof($$)); - $$.param_binding_begin = ~0; - initialize_symbol_from_param(state->prog, & $$, $1); - } - | paramConstUse - { - memset(& $$, 0, sizeof($$)); - $$.param_binding_begin = ~0; - initialize_symbol_from_const(state->prog, & $$, & $1, GL_TRUE); - } - ; - -paramMultipleItem: stateMultipleItem - { - memset(& $$, 0, sizeof($$)); - $$.param_binding_begin = ~0; - initialize_symbol_from_state(state->prog, & $$, $1); - } - | programMultipleItem - { - memset(& $$, 0, sizeof($$)); - $$.param_binding_begin = ~0; - initialize_symbol_from_param(state->prog, & $$, $1); - } - | paramConstDecl - { - memset(& $$, 0, sizeof($$)); - $$.param_binding_begin = ~0; - initialize_symbol_from_const(state->prog, & $$, & $1, GL_FALSE); - } - ; - -stateMultipleItem: stateSingleItem { memcpy($$, $1, sizeof($$)); } - | STATE stateMatrixRows { memcpy($$, $2, sizeof($$)); } - ; - -stateSingleItem: STATE stateMaterialItem { memcpy($$, $2, sizeof($$)); } - | STATE stateLightItem { memcpy($$, $2, sizeof($$)); } - | STATE stateLightModelItem { memcpy($$, $2, sizeof($$)); } - | STATE stateLightProdItem { memcpy($$, $2, sizeof($$)); } - | STATE stateTexGenItem { memcpy($$, $2, sizeof($$)); } - | STATE stateTexEnvItem { memcpy($$, $2, sizeof($$)); } - | STATE stateFogItem { memcpy($$, $2, sizeof($$)); } - | STATE stateClipPlaneItem { memcpy($$, $2, sizeof($$)); } - | STATE statePointItem { memcpy($$, $2, sizeof($$)); } - | STATE stateMatrixRow { memcpy($$, $2, sizeof($$)); } - | STATE stateDepthItem { memcpy($$, $2, sizeof($$)); } - ; - -stateMaterialItem: MATERIAL optFaceType stateMatProperty - { - memset($$, 0, sizeof($$)); - $$[0] = STATE_MATERIAL; - $$[1] = $2; - $$[2] = $3; - } - ; - -stateMatProperty: ambDiffSpecProperty - { - $$ = $1; - } - | EMISSION - { - $$ = STATE_EMISSION; - } - | SHININESS - { - $$ = STATE_SHININESS; - } - ; - -stateLightItem: LIGHT '[' stateLightNumber ']' stateLightProperty - { - memset($$, 0, sizeof($$)); - $$[0] = STATE_LIGHT; - $$[1] = $3; - $$[2] = $5; - } - ; - -stateLightProperty: ambDiffSpecProperty - { - $$ = $1; - } - | POSITION - { - $$ = STATE_POSITION; - } - | ATTENUATION - { - if (!state->ctx->Extensions.EXT_point_parameters) { - yyerror(& @1, state, "GL_ARB_point_parameters not supported"); - YYERROR; - } - - $$ = STATE_ATTENUATION; - } - | SPOT stateSpotProperty - { - $$ = $2; - } - | HALF - { - $$ = STATE_HALF_VECTOR; - } - ; - -stateSpotProperty: DIRECTION - { - $$ = STATE_SPOT_DIRECTION; - } - ; - -stateLightModelItem: LIGHTMODEL stateLModProperty - { - $$[0] = $2[0]; - $$[1] = $2[1]; - } - ; - -stateLModProperty: AMBIENT - { - memset($$, 0, sizeof($$)); - $$[0] = STATE_LIGHTMODEL_AMBIENT; - } - | optFaceType SCENECOLOR - { - memset($$, 0, sizeof($$)); - $$[0] = STATE_LIGHTMODEL_SCENECOLOR; - $$[1] = $1; - } - ; - -stateLightProdItem: LIGHTPROD '[' stateLightNumber ']' optFaceType stateLProdProperty - { - memset($$, 0, sizeof($$)); - $$[0] = STATE_LIGHTPROD; - $$[1] = $3; - $$[2] = $5; - $$[3] = $6; - } - ; - -stateLProdProperty: ambDiffSpecProperty; - -stateTexEnvItem: TEXENV optLegacyTexUnitNum stateTexEnvProperty - { - memset($$, 0, sizeof($$)); - $$[0] = $3; - $$[1] = $2; - } - ; - -stateTexEnvProperty: COLOR - { - $$ = STATE_TEXENV_COLOR; - } - ; - -ambDiffSpecProperty: AMBIENT - { - $$ = STATE_AMBIENT; - } - | DIFFUSE - { - $$ = STATE_DIFFUSE; - } - | SPECULAR - { - $$ = STATE_SPECULAR; - } - ; - -stateLightNumber: INTEGER - { - if ((unsigned) $1 >= state->MaxLights) { - yyerror(& @1, state, "invalid light selector"); - YYERROR; - } - - $$ = $1; - } - ; - -stateTexGenItem: TEXGEN optTexCoordUnitNum stateTexGenType stateTexGenCoord - { - memset($$, 0, sizeof($$)); - $$[0] = STATE_TEXGEN; - $$[1] = $2; - $$[2] = $3 + $4; - } - ; - -stateTexGenType: EYE - { - $$ = STATE_TEXGEN_EYE_S; - } - | OBJECT - { - $$ = STATE_TEXGEN_OBJECT_S; - } - ; -stateTexGenCoord: TEXGEN_S - { - $$ = STATE_TEXGEN_EYE_S - STATE_TEXGEN_EYE_S; - } - | TEXGEN_T - { - $$ = STATE_TEXGEN_EYE_T - STATE_TEXGEN_EYE_S; - } - | TEXGEN_R - { - $$ = STATE_TEXGEN_EYE_R - STATE_TEXGEN_EYE_S; - } - | TEXGEN_Q - { - $$ = STATE_TEXGEN_EYE_Q - STATE_TEXGEN_EYE_S; - } - ; - -stateFogItem: FOG stateFogProperty - { - memset($$, 0, sizeof($$)); - $$[0] = $2; - } - ; - -stateFogProperty: COLOR - { - $$ = STATE_FOG_COLOR; - } - | PARAMS - { - $$ = STATE_FOG_PARAMS; - } - ; - -stateClipPlaneItem: CLIP '[' stateClipPlaneNum ']' PLANE - { - memset($$, 0, sizeof($$)); - $$[0] = STATE_CLIPPLANE; - $$[1] = $3; - } - ; - -stateClipPlaneNum: INTEGER - { - if ((unsigned) $1 >= state->MaxClipPlanes) { - yyerror(& @1, state, "invalid clip plane selector"); - YYERROR; - } - - $$ = $1; - } - ; - -statePointItem: POINT_TOK statePointProperty - { - memset($$, 0, sizeof($$)); - $$[0] = $2; - } - ; - -statePointProperty: SIZE_TOK - { - $$ = STATE_POINT_SIZE; - } - | ATTENUATION - { - $$ = STATE_POINT_ATTENUATION; - } - ; - -stateMatrixRow: stateMatrixItem ROW '[' stateMatrixRowNum ']' - { - $$[0] = $1[0]; - $$[1] = $1[1]; - $$[2] = $4; - $$[3] = $4; - $$[4] = $1[2]; - } - ; - -stateMatrixRows: stateMatrixItem optMatrixRows - { - $$[0] = $1[0]; - $$[1] = $1[1]; - $$[2] = $2[2]; - $$[3] = $2[3]; - $$[4] = $1[2]; - } - ; - -optMatrixRows: - { - $$[2] = 0; - $$[3] = 3; - } - | ROW '[' stateMatrixRowNum DOT_DOT stateMatrixRowNum ']' - { - /* It seems logical that the matrix row range specifier would have - * to specify a range or more than one row (i.e., $5 > $3). - * However, the ARB_vertex_program spec says "a program will fail - * to load if <a> is greater than <b>." This means that $3 == $5 - * is valid. - */ - if ($3 > $5) { - yyerror(& @3, state, "invalid matrix row range"); - YYERROR; - } - - $$[2] = $3; - $$[3] = $5; - } - ; - -stateMatrixItem: MATRIX stateMatrixName stateOptMatModifier - { - $$[0] = $2[0]; - $$[1] = $2[1]; - $$[2] = $3; - } - ; - -stateOptMatModifier: - { - $$ = 0; - } - | stateMatModifier - { - $$ = $1; - } - ; - -stateMatModifier: INVERSE - { - $$ = STATE_MATRIX_INVERSE; - } - | TRANSPOSE - { - $$ = STATE_MATRIX_TRANSPOSE; - } - | INVTRANS - { - $$ = STATE_MATRIX_INVTRANS; - } - ; - -stateMatrixRowNum: INTEGER - { - if ($1 > 3) { - yyerror(& @1, state, "invalid matrix row reference"); - YYERROR; - } - - $$ = $1; - } - ; - -stateMatrixName: MODELVIEW stateOptModMatNum - { - $$[0] = STATE_MODELVIEW_MATRIX; - $$[1] = $2; - } - | PROJECTION - { - $$[0] = STATE_PROJECTION_MATRIX; - $$[1] = 0; - } - | MVP - { - $$[0] = STATE_MVP_MATRIX; - $$[1] = 0; - } - | TEXTURE optTexCoordUnitNum - { - $$[0] = STATE_TEXTURE_MATRIX; - $$[1] = $2; - } - | PALETTE '[' statePaletteMatNum ']' - { - yyerror(& @1, state, "GL_ARB_matrix_palette not supported"); - YYERROR; - } - | MAT_PROGRAM '[' stateProgramMatNum ']' - { - $$[0] = STATE_PROGRAM_MATRIX; - $$[1] = $3; - } - ; - -stateOptModMatNum: - { - $$ = 0; - } - | '[' stateModMatNum ']' - { - $$ = $2; - } - ; -stateModMatNum: INTEGER - { - /* Since GL_ARB_vertex_blend isn't supported, only modelview matrix - * zero is valid. - */ - if ($1 != 0) { - yyerror(& @1, state, "invalid modelview matrix index"); - YYERROR; - } - - $$ = $1; - } - ; -statePaletteMatNum: INTEGER - { - /* Since GL_ARB_matrix_palette isn't supported, just let any value - * through here. The error will be generated later. - */ - $$ = $1; - } - ; -stateProgramMatNum: INTEGER - { - if ((unsigned) $1 >= state->MaxProgramMatrices) { - yyerror(& @1, state, "invalid program matrix selector"); - YYERROR; - } - - $$ = $1; - } - ; - -stateDepthItem: DEPTH RANGE - { - memset($$, 0, sizeof($$)); - $$[0] = STATE_DEPTH_RANGE; - } - ; - - -programSingleItem: progEnvParam | progLocalParam; - -programMultipleItem: progEnvParams | progLocalParams; - -progEnvParams: PROGRAM ENV '[' progEnvParamNums ']' - { - memset($$, 0, sizeof($$)); - $$[0] = state->state_param_enum; - $$[1] = STATE_ENV; - $$[2] = $4[0]; - $$[3] = $4[1]; - } - ; - -progEnvParamNums: progEnvParamNum - { - $$[0] = $1; - $$[1] = $1; - } - | progEnvParamNum DOT_DOT progEnvParamNum - { - $$[0] = $1; - $$[1] = $3; - } - ; - -progEnvParam: PROGRAM ENV '[' progEnvParamNum ']' - { - memset($$, 0, sizeof($$)); - $$[0] = state->state_param_enum; - $$[1] = STATE_ENV; - $$[2] = $4; - $$[3] = $4; - } - ; - -progLocalParams: PROGRAM LOCAL '[' progLocalParamNums ']' - { - memset($$, 0, sizeof($$)); - $$[0] = state->state_param_enum; - $$[1] = STATE_LOCAL; - $$[2] = $4[0]; - $$[3] = $4[1]; - } - -progLocalParamNums: progLocalParamNum - { - $$[0] = $1; - $$[1] = $1; - } - | progLocalParamNum DOT_DOT progLocalParamNum - { - $$[0] = $1; - $$[1] = $3; - } - ; - -progLocalParam: PROGRAM LOCAL '[' progLocalParamNum ']' - { - memset($$, 0, sizeof($$)); - $$[0] = state->state_param_enum; - $$[1] = STATE_LOCAL; - $$[2] = $4; - $$[3] = $4; - } - ; - -progEnvParamNum: INTEGER - { - if ((unsigned) $1 >= state->limits->MaxEnvParams) { - yyerror(& @1, state, "invalid environment parameter reference"); - YYERROR; - } - $$ = $1; - } - ; - -progLocalParamNum: INTEGER - { - if ((unsigned) $1 >= state->limits->MaxLocalParams) { - yyerror(& @1, state, "invalid local parameter reference"); - YYERROR; - } - $$ = $1; - } - ; - - - -paramConstDecl: paramConstScalarDecl | paramConstVector; -paramConstUse: paramConstScalarUse | paramConstVector; - -paramConstScalarDecl: signedFloatConstant - { - $$.count = 4; - $$.data[0] = $1; - $$.data[1] = $1; - $$.data[2] = $1; - $$.data[3] = $1; - } - ; - -paramConstScalarUse: REAL - { - $$.count = 1; - $$.data[0] = $1; - $$.data[1] = $1; - $$.data[2] = $1; - $$.data[3] = $1; - } - | INTEGER - { - $$.count = 1; - $$.data[0] = (float) $1; - $$.data[1] = (float) $1; - $$.data[2] = (float) $1; - $$.data[3] = (float) $1; - } - ; - -paramConstVector: '{' signedFloatConstant '}' - { - $$.count = 4; - $$.data[0] = $2; - $$.data[1] = 0.0f; - $$.data[2] = 0.0f; - $$.data[3] = 1.0f; - } - | '{' signedFloatConstant ',' signedFloatConstant '}' - { - $$.count = 4; - $$.data[0] = $2; - $$.data[1] = $4; - $$.data[2] = 0.0f; - $$.data[3] = 1.0f; - } - | '{' signedFloatConstant ',' signedFloatConstant ',' - signedFloatConstant '}' - { - $$.count = 4; - $$.data[0] = $2; - $$.data[1] = $4; - $$.data[2] = $6; - $$.data[3] = 1.0f; - } - | '{' signedFloatConstant ',' signedFloatConstant ',' - signedFloatConstant ',' signedFloatConstant '}' - { - $$.count = 4; - $$.data[0] = $2; - $$.data[1] = $4; - $$.data[2] = $6; - $$.data[3] = $8; - } - ; - -signedFloatConstant: optionalSign REAL - { - $$ = ($1) ? -$2 : $2; - } - | optionalSign INTEGER - { - $$ = (float)(($1) ? -$2 : $2); - } - ; - -optionalSign: '+' { $$ = FALSE; } - | '-' { $$ = TRUE; } - | { $$ = FALSE; } - ; - -TEMP_statement: optVarSize TEMP { $<integer>$ = $2; } varNameList - ; - -optVarSize: string - { - /* NV_fragment_program_option defines the size qualifiers in a - * fairly broken way. "SHORT" or "LONG" can optionally be used - * before TEMP or OUTPUT. However, neither is a reserved word! - * This means that we have to parse it as an identifier, then check - * to make sure it's one of the valid values. *sigh* - * - * In addition, the grammar in the extension spec does *not* allow - * the size specifier to be optional, but all known implementations - * do. - */ - if (!state->option.NV_fragment) { - yyerror(& @1, state, "unexpected IDENTIFIER"); - YYERROR; - } - - if (strcmp("SHORT", $1) == 0) { - } else if (strcmp("LONG", $1) == 0) { - } else { - char *const err_str = - make_error_string("invalid storage size specifier \"%s\"", - $1); - - yyerror(& @1, state, (err_str != NULL) - ? err_str : "invalid storage size specifier"); - - if (err_str != NULL) { - free(err_str); - } - - YYERROR; - } - } - | - { - } - ; - -ADDRESS_statement: ADDRESS { $<integer>$ = $1; } varNameList - ; - -varNameList: varNameList ',' IDENTIFIER - { - if (!declare_variable(state, $3, $<integer>0, & @3)) { - free($3); - YYERROR; - } - } - | IDENTIFIER - { - if (!declare_variable(state, $1, $<integer>0, & @1)) { - free($1); - YYERROR; - } - } - ; - -OUTPUT_statement: optVarSize OUTPUT IDENTIFIER '=' resultBinding - { - struct asm_symbol *const s = - declare_variable(state, $3, at_output, & @3); - - if (s == NULL) { - free($3); - YYERROR; - } else { - s->output_binding = $5; - } - } - ; - -resultBinding: RESULT POSITION - { - if (state->mode == ARB_vertex) { - $$ = VERT_RESULT_HPOS; - } else { - yyerror(& @2, state, "invalid program result name"); - YYERROR; - } - } - | RESULT FOGCOORD - { - if (state->mode == ARB_vertex) { - $$ = VERT_RESULT_FOGC; - } else { - yyerror(& @2, state, "invalid program result name"); - YYERROR; - } - } - | RESULT resultColBinding - { - $$ = $2; - } - | RESULT POINTSIZE - { - if (state->mode == ARB_vertex) { - $$ = VERT_RESULT_PSIZ; - } else { - yyerror(& @2, state, "invalid program result name"); - YYERROR; - } - } - | RESULT TEXCOORD optTexCoordUnitNum - { - if (state->mode == ARB_vertex) { - $$ = VERT_RESULT_TEX0 + $3; - } else { - yyerror(& @2, state, "invalid program result name"); - YYERROR; - } - } - | RESULT DEPTH - { - if (state->mode == ARB_fragment) { - $$ = FRAG_RESULT_DEPTH; - } else { - yyerror(& @2, state, "invalid program result name"); - YYERROR; - } - } - ; - -resultColBinding: COLOR optResultFaceType optResultColorType - { - $$ = $2 + $3; - } - ; - -optResultFaceType: - { - $$ = (state->mode == ARB_vertex) - ? VERT_RESULT_COL0 - : FRAG_RESULT_COLOR; - } - | FRONT - { - if (state->mode == ARB_vertex) { - $$ = VERT_RESULT_COL0; - } else { - yyerror(& @1, state, "invalid program result name"); - YYERROR; - } - } - | BACK - { - if (state->mode == ARB_vertex) { - $$ = VERT_RESULT_BFC0; - } else { - yyerror(& @1, state, "invalid program result name"); - YYERROR; - } - } - ; - -optResultColorType: - { - $$ = 0; - } - | PRIMARY - { - if (state->mode == ARB_vertex) { - $$ = 0; - } else { - yyerror(& @1, state, "invalid program result name"); - YYERROR; - } - } - | SECONDARY - { - if (state->mode == ARB_vertex) { - $$ = 1; - } else { - yyerror(& @1, state, "invalid program result name"); - YYERROR; - } - } - ; - -optFaceType: { $$ = 0; } - | FRONT { $$ = 0; } - | BACK { $$ = 1; } - ; - -optColorType: { $$ = 0; } - | PRIMARY { $$ = 0; } - | SECONDARY { $$ = 1; } - ; - -optTexCoordUnitNum: { $$ = 0; } - | '[' texCoordUnitNum ']' { $$ = $2; } - ; - -optTexImageUnitNum: { $$ = 0; } - | '[' texImageUnitNum ']' { $$ = $2; } - ; - -optLegacyTexUnitNum: { $$ = 0; } - | '[' legacyTexUnitNum ']' { $$ = $2; } - ; - -texCoordUnitNum: INTEGER - { - if ((unsigned) $1 >= state->MaxTextureCoordUnits) { - yyerror(& @1, state, "invalid texture coordinate unit selector"); - YYERROR; - } - - $$ = $1; - } - ; - -texImageUnitNum: INTEGER - { - if ((unsigned) $1 >= state->MaxTextureImageUnits) { - yyerror(& @1, state, "invalid texture image unit selector"); - YYERROR; - } - - $$ = $1; - } - ; - -legacyTexUnitNum: INTEGER - { - if ((unsigned) $1 >= state->MaxTextureUnits) { - yyerror(& @1, state, "invalid texture unit selector"); - YYERROR; - } - - $$ = $1; - } - ; - -ALIAS_statement: ALIAS IDENTIFIER '=' USED_IDENTIFIER - { - struct asm_symbol *exist = (struct asm_symbol *) - _mesa_symbol_table_find_symbol(state->st, 0, $2); - struct asm_symbol *target = (struct asm_symbol *) - _mesa_symbol_table_find_symbol(state->st, 0, $4); - - free($4); - - if (exist != NULL) { - char m[1000]; - _mesa_snprintf(m, sizeof(m), "redeclared identifier: %s", $2); - free($2); - yyerror(& @2, state, m); - YYERROR; - } else if (target == NULL) { - free($2); - yyerror(& @4, state, - "undefined variable binding in ALIAS statement"); - YYERROR; - } else { - _mesa_symbol_table_add_symbol(state->st, 0, $2, target); - } - } - ; - -string: IDENTIFIER - | USED_IDENTIFIER - ; - -%% - -void -asm_instruction_set_operands(struct asm_instruction *inst, - const struct prog_dst_register *dst, - const struct asm_src_register *src0, - const struct asm_src_register *src1, - const struct asm_src_register *src2) -{ - /* In the core ARB extensions only the KIL instruction doesn't have a - * destination register. - */ - if (dst == NULL) { - init_dst_reg(& inst->Base.DstReg); - } else { - inst->Base.DstReg = *dst; - } - - /* The only instruction that doesn't have any source registers is the - * condition-code based KIL instruction added by NV_fragment_program_option. - */ - if (src0 != NULL) { - inst->Base.SrcReg[0] = src0->Base; - inst->SrcReg[0] = *src0; - } else { - init_src_reg(& inst->SrcReg[0]); - } - - if (src1 != NULL) { - inst->Base.SrcReg[1] = src1->Base; - inst->SrcReg[1] = *src1; - } else { - init_src_reg(& inst->SrcReg[1]); - } - - if (src2 != NULL) { - inst->Base.SrcReg[2] = src2->Base; - inst->SrcReg[2] = *src2; - } else { - init_src_reg(& inst->SrcReg[2]); - } -} - - -struct asm_instruction * -asm_instruction_ctor(gl_inst_opcode op, - const struct prog_dst_register *dst, - const struct asm_src_register *src0, - const struct asm_src_register *src1, - const struct asm_src_register *src2) -{ - struct asm_instruction *inst = CALLOC_STRUCT(asm_instruction); - - if (inst) { - _mesa_init_instructions(& inst->Base, 1); - inst->Base.Opcode = op; - - asm_instruction_set_operands(inst, dst, src0, src1, src2); - } - - return inst; -} - - -struct asm_instruction * -asm_instruction_copy_ctor(const struct prog_instruction *base, - const struct prog_dst_register *dst, - const struct asm_src_register *src0, - const struct asm_src_register *src1, - const struct asm_src_register *src2) -{ - struct asm_instruction *inst = CALLOC_STRUCT(asm_instruction); - - if (inst) { - _mesa_init_instructions(& inst->Base, 1); - inst->Base.Opcode = base->Opcode; - inst->Base.CondUpdate = base->CondUpdate; - inst->Base.CondDst = base->CondDst; - inst->Base.SaturateMode = base->SaturateMode; - inst->Base.Precision = base->Precision; - - asm_instruction_set_operands(inst, dst, src0, src1, src2); - } - - return inst; -} - - -void -init_dst_reg(struct prog_dst_register *r) -{ - memset(r, 0, sizeof(*r)); - r->File = PROGRAM_UNDEFINED; - r->WriteMask = WRITEMASK_XYZW; - r->CondMask = COND_TR; - r->CondSwizzle = SWIZZLE_NOOP; -} - - -/** Like init_dst_reg() but set the File and Index fields. */ -void -set_dst_reg(struct prog_dst_register *r, gl_register_file file, GLint index) -{ - const GLint maxIndex = 1 << INST_INDEX_BITS; - const GLint minIndex = 0; - ASSERT(index >= minIndex); - (void) minIndex; - ASSERT(index <= maxIndex); - (void) maxIndex; - ASSERT(file == PROGRAM_TEMPORARY || - file == PROGRAM_ADDRESS || - file == PROGRAM_OUTPUT); - memset(r, 0, sizeof(*r)); - r->File = file; - r->Index = index; - r->WriteMask = WRITEMASK_XYZW; - r->CondMask = COND_TR; - r->CondSwizzle = SWIZZLE_NOOP; -} - - -void -init_src_reg(struct asm_src_register *r) -{ - memset(r, 0, sizeof(*r)); - r->Base.File = PROGRAM_UNDEFINED; - r->Base.Swizzle = SWIZZLE_NOOP; - r->Symbol = NULL; -} - - -/** Like init_src_reg() but set the File and Index fields. - * \return GL_TRUE if a valid src register, GL_FALSE otherwise - */ -void -set_src_reg(struct asm_src_register *r, gl_register_file file, GLint index) -{ - set_src_reg_swz(r, file, index, SWIZZLE_XYZW); -} - - -void -set_src_reg_swz(struct asm_src_register *r, gl_register_file file, GLint index, - GLuint swizzle) -{ - const GLint maxIndex = (1 << INST_INDEX_BITS) - 1; - const GLint minIndex = -(1 << INST_INDEX_BITS); - ASSERT(file < PROGRAM_FILE_MAX); - ASSERT(index >= minIndex); - (void) minIndex; - ASSERT(index <= maxIndex); - (void) maxIndex; - memset(r, 0, sizeof(*r)); - r->Base.File = file; - r->Base.Index = index; - r->Base.Swizzle = swizzle; - r->Symbol = NULL; -} - - -/** - * Validate the set of inputs used by a program - * - * Validates that legal sets of inputs are used by the program. In this case - * "used" included both reading the input or binding the input to a name using - * the \c ATTRIB command. - * - * \return - * \c TRUE if the combination of inputs used is valid, \c FALSE otherwise. - */ -int -validate_inputs(struct YYLTYPE *locp, struct asm_parser_state *state) -{ - const int inputs = state->prog->InputsRead | state->InputsBound; - - if (((inputs & 0x0ffff) & (inputs >> 16)) != 0) { - yyerror(locp, state, "illegal use of generic attribute and name attribute"); - return 0; - } - - return 1; -} - - -struct asm_symbol * -declare_variable(struct asm_parser_state *state, char *name, enum asm_type t, - struct YYLTYPE *locp) -{ - struct asm_symbol *s = NULL; - struct asm_symbol *exist = (struct asm_symbol *) - _mesa_symbol_table_find_symbol(state->st, 0, name); - - - if (exist != NULL) { - yyerror(locp, state, "redeclared identifier"); - } else { - s = calloc(1, sizeof(struct asm_symbol)); - s->name = name; - s->type = t; - - switch (t) { - case at_temp: - if (state->prog->NumTemporaries >= state->limits->MaxTemps) { - yyerror(locp, state, "too many temporaries declared"); - free(s); - return NULL; - } - - s->temp_binding = state->prog->NumTemporaries; - state->prog->NumTemporaries++; - break; - - case at_address: - if (state->prog->NumAddressRegs >= state->limits->MaxAddressRegs) { - yyerror(locp, state, "too many address registers declared"); - free(s); - return NULL; - } - - /* FINISHME: Add support for multiple address registers. - */ - state->prog->NumAddressRegs++; - break; - - default: - break; - } - - _mesa_symbol_table_add_symbol(state->st, 0, s->name, s); - s->next = state->sym; - state->sym = s; - } - - return s; -} - - -int add_state_reference(struct gl_program_parameter_list *param_list, - const gl_state_index tokens[STATE_LENGTH]) -{ - const GLuint size = 4; /* XXX fix */ - char *name; - GLint index; - - name = _mesa_program_state_string(tokens); - index = _mesa_add_parameter(param_list, PROGRAM_STATE_VAR, name, - size, GL_NONE, NULL, tokens, 0x0); - param_list->StateFlags |= _mesa_program_state_flags(tokens); - - /* free name string here since we duplicated it in add_parameter() */ - free(name); - - return index; -} - - -int -initialize_symbol_from_state(struct gl_program *prog, - struct asm_symbol *param_var, - const gl_state_index tokens[STATE_LENGTH]) -{ - int idx = -1; - gl_state_index state_tokens[STATE_LENGTH]; - - - memcpy(state_tokens, tokens, sizeof(state_tokens)); - - param_var->type = at_param; - param_var->param_binding_type = PROGRAM_STATE_VAR; - - /* If we are adding a STATE_MATRIX that has multiple rows, we need to - * unroll it and call add_state_reference() for each row - */ - 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])) { - int row; - const int first_row = state_tokens[2]; - const int last_row = state_tokens[3]; - - for (row = first_row; row <= last_row; row++) { - state_tokens[2] = state_tokens[3] = row; - - idx = add_state_reference(prog->Parameters, state_tokens); - if (param_var->param_binding_begin == ~0U) { - param_var->param_binding_begin = idx; - param_var->param_binding_swizzle = SWIZZLE_XYZW; - } - - param_var->param_binding_length++; - } - } - else { - idx = add_state_reference(prog->Parameters, state_tokens); - if (param_var->param_binding_begin == ~0U) { - param_var->param_binding_begin = idx; - param_var->param_binding_swizzle = SWIZZLE_XYZW; - } - param_var->param_binding_length++; - } - - return idx; -} - - -int -initialize_symbol_from_param(struct gl_program *prog, - struct asm_symbol *param_var, - const gl_state_index tokens[STATE_LENGTH]) -{ - int idx = -1; - gl_state_index state_tokens[STATE_LENGTH]; - - - memcpy(state_tokens, tokens, sizeof(state_tokens)); - - assert((state_tokens[0] == STATE_VERTEX_PROGRAM) - || (state_tokens[0] == STATE_FRAGMENT_PROGRAM)); - assert((state_tokens[1] == STATE_ENV) - || (state_tokens[1] == STATE_LOCAL)); - - /* - * The param type is STATE_VAR. The program parameter entry will - * effectively be a pointer into the LOCAL or ENV parameter array. - */ - param_var->type = at_param; - param_var->param_binding_type = PROGRAM_STATE_VAR; - - /* If we are adding a STATE_ENV or STATE_LOCAL that has multiple elements, - * we need to unroll it and call add_state_reference() for each row - */ - if (state_tokens[2] != state_tokens[3]) { - int row; - const int first_row = state_tokens[2]; - const int last_row = state_tokens[3]; - - for (row = first_row; row <= last_row; row++) { - state_tokens[2] = state_tokens[3] = row; - - idx = add_state_reference(prog->Parameters, state_tokens); - if (param_var->param_binding_begin == ~0U) { - param_var->param_binding_begin = idx; - param_var->param_binding_swizzle = SWIZZLE_XYZW; - } - param_var->param_binding_length++; - } - } - else { - idx = add_state_reference(prog->Parameters, state_tokens); - if (param_var->param_binding_begin == ~0U) { - param_var->param_binding_begin = idx; - param_var->param_binding_swizzle = SWIZZLE_XYZW; - } - param_var->param_binding_length++; - } - - return idx; -} - - -/** - * Put a float/vector constant/literal into the parameter list. - * \param param_var returns info about the parameter/constant's location, - * binding, type, etc. - * \param vec the vector/constant to add - * \param allowSwizzle if true, try to consolidate constants which only differ - * by a swizzle. We don't want to do this when building - * arrays of constants that may be indexed indirectly. - * \return index of the constant in the parameter list. - */ -int -initialize_symbol_from_const(struct gl_program *prog, - struct asm_symbol *param_var, - const struct asm_vector *vec, - GLboolean allowSwizzle) -{ - unsigned swizzle; - const int idx = _mesa_add_unnamed_constant(prog->Parameters, - vec->data, vec->count, - allowSwizzle ? &swizzle : NULL); - - param_var->type = at_param; - param_var->param_binding_type = PROGRAM_CONSTANT; - - if (param_var->param_binding_begin == ~0U) { - param_var->param_binding_begin = idx; - param_var->param_binding_swizzle = allowSwizzle ? swizzle : SWIZZLE_XYZW; - } - param_var->param_binding_length++; - - return idx; -} - - -char * -make_error_string(const char *fmt, ...) -{ - int length; - char *str; - va_list args; - - va_start(args, fmt); - - /* Call vsnprintf once to determine how large the final string is. Call it - * again to do the actual formatting. from the v_mesa_snprintf manual page: - * - * Upon successful return, these functions return the number of - * characters printed (not including the trailing '\0' used to end - * output to strings). - */ - length = 1 + vsnprintf(NULL, 0, fmt, args); - - str = malloc(length); - if (str) { - vsnprintf(str, length, fmt, args); - } - - va_end(args); - - return str; -} - - -void -yyerror(YYLTYPE *locp, struct asm_parser_state *state, const char *s) -{ - char *err_str; - - - err_str = make_error_string("glProgramStringARB(%s)\n", s); - if (err_str) { - _mesa_error(state->ctx, GL_INVALID_OPERATION, err_str); - free(err_str); - } - - err_str = make_error_string("line %u, char %u: error: %s\n", - locp->first_line, locp->first_column, s); - _mesa_set_program_error(state->ctx, locp->position, err_str); - - if (err_str) { - free(err_str); - } -} - - -GLboolean -_mesa_parse_arb_program(GLcontext *ctx, GLenum target, const GLubyte *str, - GLsizei len, struct asm_parser_state *state) -{ - struct asm_instruction *inst; - unsigned i; - GLubyte *strz; - GLboolean result = GL_FALSE; - void *temp; - struct asm_symbol *sym; - - state->ctx = ctx; - state->prog->Target = target; - state->prog->Parameters = _mesa_new_parameter_list(); - - /* Make a copy of the program string and force it to be NUL-terminated. - */ - strz = (GLubyte *) malloc(len + 1); - if (strz == NULL) { - _mesa_error(ctx, GL_OUT_OF_MEMORY, "glProgramStringARB"); - return GL_FALSE; - } - memcpy (strz, str, len); - strz[len] = '\0'; - - state->prog->String = strz; - - state->st = _mesa_symbol_table_ctor(); - - state->limits = (target == GL_VERTEX_PROGRAM_ARB) - ? & ctx->Const.VertexProgram - : & ctx->Const.FragmentProgram; - - state->MaxTextureImageUnits = ctx->Const.MaxTextureImageUnits; - state->MaxTextureCoordUnits = ctx->Const.MaxTextureCoordUnits; - state->MaxTextureUnits = ctx->Const.MaxTextureUnits; - state->MaxClipPlanes = ctx->Const.MaxClipPlanes; - state->MaxLights = ctx->Const.MaxLights; - state->MaxProgramMatrices = ctx->Const.MaxProgramMatrices; - - state->state_param_enum = (target == GL_VERTEX_PROGRAM_ARB) - ? STATE_VERTEX_PROGRAM : STATE_FRAGMENT_PROGRAM; - - _mesa_set_program_error(ctx, -1, NULL); - - _mesa_program_lexer_ctor(& state->scanner, state, (const char *) str, len); - yyparse(state); - _mesa_program_lexer_dtor(state->scanner); - - - if (ctx->Program.ErrorPos != -1) { - goto error; - } - - if (! _mesa_layout_parameters(state)) { - struct YYLTYPE loc; - - loc.first_line = 0; - loc.first_column = 0; - loc.position = len; - - yyerror(& loc, state, "invalid PARAM usage"); - goto error; - } - - - - /* Add one instruction to store the "END" instruction. - */ - state->prog->Instructions = - _mesa_alloc_instructions(state->prog->NumInstructions + 1); - inst = state->inst_head; - for (i = 0; i < state->prog->NumInstructions; i++) { - struct asm_instruction *const temp = inst->next; - - state->prog->Instructions[i] = inst->Base; - inst = temp; - } - - /* Finally, tag on an OPCODE_END instruction */ - { - const GLuint numInst = state->prog->NumInstructions; - _mesa_init_instructions(state->prog->Instructions + numInst, 1); - state->prog->Instructions[numInst].Opcode = OPCODE_END; - } - state->prog->NumInstructions++; - - state->prog->NumParameters = state->prog->Parameters->NumParameters; - state->prog->NumAttributes = _mesa_bitcount(state->prog->InputsRead); - - /* - * Initialize native counts to logical counts. The device driver may - * change them if program is translated into a hardware program. - */ - state->prog->NumNativeInstructions = state->prog->NumInstructions; - state->prog->NumNativeTemporaries = state->prog->NumTemporaries; - state->prog->NumNativeParameters = state->prog->NumParameters; - state->prog->NumNativeAttributes = state->prog->NumAttributes; - state->prog->NumNativeAddressRegs = state->prog->NumAddressRegs; - - result = GL_TRUE; - -error: - for (inst = state->inst_head; inst != NULL; inst = temp) { - temp = inst->next; - free(inst); - } - - state->inst_head = NULL; - state->inst_tail = NULL; - - for (sym = state->sym; sym != NULL; sym = temp) { - temp = sym->next; - - free((void *) sym->name); - free(sym); - } - state->sym = NULL; - - _mesa_symbol_table_dtor(state->st); - state->st = NULL; - - return result; -} diff --git a/mesalib/src/mesa/shader/program_parse_extra.c b/mesalib/src/mesa/shader/program_parse_extra.c deleted file mode 100644 index ae98b782b..000000000 --- a/mesalib/src/mesa/shader/program_parse_extra.c +++ /dev/null @@ -1,255 +0,0 @@ -/* - * Copyright © 2009 Intel Corporation - * - * 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 (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 NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS 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 <string.h> -#include "main/mtypes.h" -#include "prog_instruction.h" -#include "program_parser.h" - - -/** - * Extra assembly-level parser routines - * - * \author Ian Romanick <ian.d.romanick@intel.com> - */ - -int -_mesa_parse_instruction_suffix(const struct asm_parser_state *state, - const char *suffix, - struct prog_instruction *inst) -{ - inst->CondUpdate = 0; - inst->CondDst = 0; - inst->SaturateMode = SATURATE_OFF; - inst->Precision = FLOAT32; - - - /* The first possible suffix element is the precision specifier from - * NV_fragment_program_option. - */ - if (state->option.NV_fragment) { - switch (suffix[0]) { - case 'H': - inst->Precision = FLOAT16; - suffix++; - break; - case 'R': - inst->Precision = FLOAT32; - suffix++; - break; - case 'X': - inst->Precision = FIXED12; - suffix++; - break; - default: - break; - } - } - - /* The next possible suffix element is the condition code modifier selection - * from NV_fragment_program_option. - */ - if (state->option.NV_fragment) { - if (suffix[0] == 'C') { - inst->CondUpdate = 1; - suffix++; - } - } - - - /* The final possible suffix element is the saturation selector from - * ARB_fragment_program. - */ - if (state->mode == ARB_fragment) { - if (strcmp(suffix, "_SAT") == 0) { - inst->SaturateMode = SATURATE_ZERO_ONE; - suffix += 4; - } - } - - - /* It is an error for all of the suffix string not to be consumed. - */ - return suffix[0] == '\0'; -} - - -int -_mesa_parse_cc(const char *s) -{ - int cond = 0; - - switch (s[0]) { - case 'E': - if (s[1] == 'Q') { - cond = COND_EQ; - } - break; - - case 'F': - if (s[1] == 'L') { - cond = COND_FL; - } - break; - - case 'G': - if (s[1] == 'E') { - cond = COND_GE; - } else if (s[1] == 'T') { - cond = COND_GT; - } - break; - - case 'L': - if (s[1] == 'E') { - cond = COND_LE; - } else if (s[1] == 'T') { - cond = COND_LT; - } - break; - - case 'N': - if (s[1] == 'E') { - cond = COND_NE; - } - break; - - case 'T': - if (s[1] == 'R') { - cond = COND_TR; - } - break; - - default: - break; - } - - return ((cond == 0) || (s[2] != '\0')) ? 0 : cond; -} - - -int -_mesa_ARBvp_parse_option(struct asm_parser_state *state, const char *option) -{ - if (strcmp(option, "ARB_position_invariant") == 0) { - state->option.PositionInvariant = 1; - return 1; - } - - return 0; -} - - -int -_mesa_ARBfp_parse_option(struct asm_parser_state *state, const char *option) -{ - /* All of the options currently supported start with "ARB_". The code is - * currently structured with nested if-statements because eventually options - * that start with "NV_" will be supported. This structure will result in - * less churn when those options are added. - */ - if (strncmp(option, "ARB_", 4) == 0) { - /* Advance the pointer past the "ARB_" prefix. - */ - option += 4; - - - if (strncmp(option, "fog_", 4) == 0) { - option += 4; - - if (state->option.Fog == OPTION_NONE) { - if (strcmp(option, "exp") == 0) { - state->option.Fog = OPTION_FOG_EXP; - return 1; - } else if (strcmp(option, "exp2") == 0) { - state->option.Fog = OPTION_FOG_EXP2; - return 1; - } else if (strcmp(option, "linear") == 0) { - state->option.Fog = OPTION_FOG_LINEAR; - return 1; - } - } - - return 0; - } else if (strncmp(option, "precision_hint_", 15) == 0) { - option += 15; - - if (state->option.PrecisionHint == OPTION_NONE) { - if (strcmp(option, "nicest") == 0) { - state->option.PrecisionHint = OPTION_NICEST; - return 1; - } else if (strcmp(option, "fastest") == 0) { - state->option.PrecisionHint = OPTION_FASTEST; - return 1; - } - } - - return 0; - } else if (strcmp(option, "draw_buffers") == 0) { - /* Don't need to check extension availability because all Mesa-based - * drivers support GL_ARB_draw_buffers. - */ - state->option.DrawBuffers = 1; - return 1; - } else if (strcmp(option, "fragment_program_shadow") == 0) { - if (state->ctx->Extensions.ARB_fragment_program_shadow) { - state->option.Shadow = 1; - return 1; - } - } else if (strncmp(option, "fragment_coord_", 15) == 0) { - option += 15; - if (state->ctx->Extensions.ARB_fragment_coord_conventions) { - if (strcmp(option, "origin_upper_left") == 0) { - state->option.OriginUpperLeft = 1; - return 1; - } - else if (strcmp(option, "pixel_center_integer") == 0) { - state->option.PixelCenterInteger = 1; - return 1; - } - } - } - } else if (strncmp(option, "NV_fragment_program", 19) == 0) { - option += 19; - - /* Other NV_fragment_program strings may be supported later. - */ - if (option[0] == '\0') { - if (state->ctx->Extensions.NV_fragment_program_option) { - state->option.NV_fragment = 1; - return 1; - } - } - } else if (strncmp(option, "MESA_", 5) == 0) { - option += 5; - - if (strcmp(option, "texture_array") == 0) { - if (state->ctx->Extensions.MESA_texture_array) { - state->option.TexArray = 1; - return 1; - } - } - } - - return 0; -} diff --git a/mesalib/src/mesa/shader/program_parser.h b/mesalib/src/mesa/shader/program_parser.h deleted file mode 100644 index be952d4b9..000000000 --- a/mesalib/src/mesa/shader/program_parser.h +++ /dev/null @@ -1,302 +0,0 @@ -/* - * Copyright © 2009 Intel Corporation - * - * 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 (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 NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS 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. - */ -#pragma once - -#include "main/config.h" - -#ifndef MTYPES_H -struct __GLcontextRec; -typedef struct __GLcontextRec GLcontext; -#endif - -enum asm_type { - at_none, - at_address, - at_attrib, - at_param, - at_temp, - at_output -}; - -struct asm_symbol { - struct asm_symbol *next; /**< List linkage for freeing. */ - const char *name; - enum asm_type type; - unsigned attrib_binding; - unsigned output_binding; /**< Output / result register number. */ - - /** - * One of PROGRAM_STATE_VAR, PROGRAM_LOCAL_PARAM, or PROGRAM_ENV_PARAM. - */ - unsigned param_binding_type; - - /** - * Offset into the program_parameter_list where the tokens representing our - * bound state (or constants) start. - */ - unsigned param_binding_begin; - - /** - * Constants put into the parameter list may be swizzled. This - * field contain's the symbol's swizzle. (SWIZZLE_X/Y/Z/W) - */ - unsigned param_binding_swizzle; - - /* This is how many entries in the program_parameter_list we take up - * with our state tokens or constants. Note that this is _not_ the same as - * the number of param registers we eventually use. - */ - unsigned param_binding_length; - - /** - * Index of the temp register assigned to this variable. - */ - unsigned temp_binding; - - /** - * Flag whether or not a PARAM is an array - */ - unsigned param_is_array:1; - - - /** - * Flag whether or not a PARAM array is accessed indirectly - */ - unsigned param_accessed_indirectly:1; - - - /** - * \brief Is first pass of parameter layout done with this variable? - * - * The parameter layout routine operates in two passes. This flag tracks - * whether or not the first pass has handled this variable. - * - * \sa _mesa_layout_parameters - */ - unsigned pass1_done:1; -}; - - -struct asm_vector { - unsigned count; - float data[4]; -}; - - -struct asm_swizzle_mask { - unsigned swizzle:12; - unsigned mask:4; -}; - - -struct asm_src_register { - struct prog_src_register Base; - - /** - * Symbol associated with indirect access to parameter arrays. - * - * If \c Base::RelAddr is 1, this will point to the symbol for the parameter - * that is being dereferenced. Further, \c Base::Index will be the offset - * from the address register being used. - */ - struct asm_symbol *Symbol; -}; - - -struct asm_instruction { - struct prog_instruction Base; - struct asm_instruction *next; - struct asm_src_register SrcReg[3]; -}; - - -struct asm_parser_state { - GLcontext *ctx; - struct gl_program *prog; - - /** - * Per-program target limits - */ - struct gl_program_constants *limits; - - struct _mesa_symbol_table *st; - - /** - * Linked list of symbols - * - * This list is \b only used when cleaning up compiler state and freeing - * memory. - */ - struct asm_symbol *sym; - - /** - * State for the lexer. - */ - void *scanner; - - /** - * Linked list of instructions generated during parsing. - */ - /*@{*/ - struct asm_instruction *inst_head; - struct asm_instruction *inst_tail; - /*@}*/ - - - /** - * Selected limits copied from gl_constants - * - * These are limits from the GL context, but various bits in the program - * must be validated against these values. - */ - /*@{*/ - unsigned MaxTextureCoordUnits; - unsigned MaxTextureImageUnits; - unsigned MaxTextureUnits; - unsigned MaxClipPlanes; - unsigned MaxLights; - unsigned MaxProgramMatrices; - /*@}*/ - - /** - * Value to use in state vector accessors for environment and local - * parameters - */ - unsigned state_param_enum; - - - /** - * Input attributes bound to specific names - * - * This is only needed so that errors can be properly produced when - * multiple ATTRIB statements bind illegal combinations of vertex - * attributes. - */ - unsigned InputsBound; - - enum { - invalid_mode = 0, - ARB_vertex, - ARB_fragment - } mode; - - struct { - unsigned PositionInvariant:1; - unsigned Fog:2; - unsigned PrecisionHint:2; - unsigned DrawBuffers:1; - unsigned Shadow:1; - unsigned TexRect:1; - unsigned TexArray:1; - unsigned NV_fragment:1; - unsigned OriginUpperLeft:1; - unsigned PixelCenterInteger:1; - } option; - - struct { - unsigned UsesKill:1; - } fragment; -}; - -#define OPTION_NONE 0 -#define OPTION_FOG_EXP 1 -#define OPTION_FOG_EXP2 2 -#define OPTION_FOG_LINEAR 3 -#define OPTION_NICEST 1 -#define OPTION_FASTEST 2 - -typedef struct YYLTYPE { - int first_line; - int first_column; - int last_line; - int last_column; - int position; -} YYLTYPE; - -#define YYLTYPE_IS_DECLARED 1 -#define YYLTYPE_IS_TRIVIAL 1 - - -extern GLboolean _mesa_parse_arb_program(GLcontext *ctx, GLenum target, - const GLubyte *str, GLsizei len, struct asm_parser_state *state); - - - -/* From program_lexer.l. */ -extern void _mesa_program_lexer_dtor(void *scanner); - -extern void _mesa_program_lexer_ctor(void **scanner, - struct asm_parser_state *state, const char *string, size_t len); - - -/** - *\name From program_parse_extra.c - */ -/*@{*/ - -/** - * Parses and processes an option string to an ARB vertex program - * - * \return - * Non-zero on success, zero on failure. - */ -extern int _mesa_ARBvp_parse_option(struct asm_parser_state *state, - const char *option); - -/** - * Parses and processes an option string to an ARB fragment program - * - * \return - * Non-zero on success, zero on failure. - */ -extern int _mesa_ARBfp_parse_option(struct asm_parser_state *state, - const char *option); - -/** - * Parses and processes instruction suffixes - * - * Instruction suffixes, such as \c _SAT, are processed. The relevant bits - * are set in \c inst. If suffixes are encountered that are either not known - * or not supported by the modes and options set in \c state, zero will be - * returned. - * - * \return - * Non-zero on success, zero on failure. - */ -extern int _mesa_parse_instruction_suffix(const struct asm_parser_state *state, - const char *suffix, struct prog_instruction *inst); - -/** - * Parses a condition code name - * - * The condition code names (e.g., \c LT, \c GT, \c NE) were added to assembly - * shaders with the \c GL_NV_fragment_program_option extension. This function - * converts a string representation into one of the \c COND_ macros. - * - * \return - * One of the \c COND_ macros defined in prog_instruction.h on success or zero - * on failure. - */ -extern int _mesa_parse_cc(const char *s); - -/*@}*/ diff --git a/mesalib/src/mesa/shader/programopt.c b/mesalib/src/mesa/shader/programopt.c deleted file mode 100644 index fb2ebe633..000000000 --- a/mesalib/src/mesa/shader/programopt.c +++ /dev/null @@ -1,669 +0,0 @@ -/* - * 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 programopt.c - * Vertex/Fragment program optimizations and transformations for program - * options, etc. - * - * \author Brian Paul - */ - - -#include "main/glheader.h" -#include "main/context.h" -#include "prog_parameter.h" -#include "prog_statevars.h" -#include "program.h" -#include "programopt.h" -#include "prog_instruction.h" - - -/** - * This function inserts instructions for coordinate modelview * projection - * into a vertex program. - * May be used to implement the position_invariant option. - */ -static void -_mesa_insert_mvp_dp4_code(GLcontext *ctx, struct gl_vertex_program *vprog) -{ - struct prog_instruction *newInst; - const GLuint origLen = vprog->Base.NumInstructions; - const GLuint newLen = origLen + 4; - GLuint i; - - /* - * Setup state references for the modelview/projection matrix. - * XXX we should check if these state vars are already declared. - */ - 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]; - - for (i = 0; i < 4; i++) { - mvpRef[i] = _mesa_add_state_reference(vprog->Base.Parameters, - mvpState[i]); - } - - /* Alloc storage for new instructions */ - newInst = _mesa_alloc_instructions(newLen); - if (!newInst) { - _mesa_error(ctx, GL_OUT_OF_MEMORY, - "glProgramString(inserting position_invariant code)"); - return; - } - - /* - * Generated instructions: - * newInst[0] = DP4 result.position.x, mvp.row[0], vertex.position; - * newInst[1] = DP4 result.position.y, mvp.row[1], vertex.position; - * newInst[2] = DP4 result.position.z, mvp.row[2], vertex.position; - * newInst[3] = DP4 result.position.w, mvp.row[3], vertex.position; - */ - _mesa_init_instructions(newInst, 4); - for (i = 0; i < 4; i++) { - newInst[i].Opcode = OPCODE_DP4; - newInst[i].DstReg.File = PROGRAM_OUTPUT; - newInst[i].DstReg.Index = VERT_RESULT_HPOS; - newInst[i].DstReg.WriteMask = (WRITEMASK_X << i); - newInst[i].SrcReg[0].File = PROGRAM_STATE_VAR; - newInst[i].SrcReg[0].Index = mvpRef[i]; - newInst[i].SrcReg[0].Swizzle = SWIZZLE_NOOP; - newInst[i].SrcReg[1].File = PROGRAM_INPUT; - newInst[i].SrcReg[1].Index = VERT_ATTRIB_POS; - newInst[i].SrcReg[1].Swizzle = SWIZZLE_NOOP; - } - - /* Append original instructions after new instructions */ - _mesa_copy_instructions (newInst + 4, vprog->Base.Instructions, origLen); - - /* free old instructions */ - _mesa_free_instructions(vprog->Base.Instructions, origLen); - - /* install new instructions */ - vprog->Base.Instructions = newInst; - vprog->Base.NumInstructions = newLen; - vprog->Base.InputsRead |= VERT_BIT_POS; - vprog->Base.OutputsWritten |= BITFIELD64_BIT(VERT_RESULT_HPOS); -} - - -static void -_mesa_insert_mvp_mad_code(GLcontext *ctx, struct gl_vertex_program *vprog) -{ - struct prog_instruction *newInst; - const GLuint origLen = vprog->Base.NumInstructions; - const GLuint newLen = origLen + 4; - GLuint hposTemp; - GLuint i; - - /* - * Setup state references for the modelview/projection matrix. - * XXX we should check if these state vars are already declared. - */ - static const gl_state_index mvpState[4][STATE_LENGTH] = { - { STATE_MVP_MATRIX, 0, 0, 0, STATE_MATRIX_TRANSPOSE }, - { STATE_MVP_MATRIX, 0, 1, 1, STATE_MATRIX_TRANSPOSE }, - { STATE_MVP_MATRIX, 0, 2, 2, STATE_MATRIX_TRANSPOSE }, - { STATE_MVP_MATRIX, 0, 3, 3, STATE_MATRIX_TRANSPOSE }, - }; - GLint mvpRef[4]; - - for (i = 0; i < 4; i++) { - mvpRef[i] = _mesa_add_state_reference(vprog->Base.Parameters, - mvpState[i]); - } - - /* Alloc storage for new instructions */ - newInst = _mesa_alloc_instructions(newLen); - if (!newInst) { - _mesa_error(ctx, GL_OUT_OF_MEMORY, - "glProgramString(inserting position_invariant code)"); - return; - } - - /* TEMP hposTemp; */ - hposTemp = vprog->Base.NumTemporaries++; - - /* - * Generated instructions: - * emit_op2(p, OPCODE_MUL, tmp, 0, swizzle1(src,X), mat[0]); - * emit_op3(p, OPCODE_MAD, tmp, 0, swizzle1(src,Y), mat[1], tmp); - * emit_op3(p, OPCODE_MAD, tmp, 0, swizzle1(src,Z), mat[2], tmp); - * emit_op3(p, OPCODE_MAD, dest, 0, swizzle1(src,W), mat[3], tmp); - */ - _mesa_init_instructions(newInst, 4); - - newInst[0].Opcode = OPCODE_MUL; - newInst[0].DstReg.File = PROGRAM_TEMPORARY; - newInst[0].DstReg.Index = hposTemp; - newInst[0].DstReg.WriteMask = WRITEMASK_XYZW; - newInst[0].SrcReg[0].File = PROGRAM_INPUT; - newInst[0].SrcReg[0].Index = VERT_ATTRIB_POS; - newInst[0].SrcReg[0].Swizzle = SWIZZLE_XXXX; - newInst[0].SrcReg[1].File = PROGRAM_STATE_VAR; - newInst[0].SrcReg[1].Index = mvpRef[0]; - newInst[0].SrcReg[1].Swizzle = SWIZZLE_NOOP; - - for (i = 1; i <= 2; i++) { - newInst[i].Opcode = OPCODE_MAD; - newInst[i].DstReg.File = PROGRAM_TEMPORARY; - newInst[i].DstReg.Index = hposTemp; - newInst[i].DstReg.WriteMask = WRITEMASK_XYZW; - newInst[i].SrcReg[0].File = PROGRAM_INPUT; - newInst[i].SrcReg[0].Index = VERT_ATTRIB_POS; - newInst[i].SrcReg[0].Swizzle = MAKE_SWIZZLE4(i,i,i,i); - newInst[i].SrcReg[1].File = PROGRAM_STATE_VAR; - newInst[i].SrcReg[1].Index = mvpRef[i]; - newInst[i].SrcReg[1].Swizzle = SWIZZLE_NOOP; - newInst[i].SrcReg[2].File = PROGRAM_TEMPORARY; - newInst[i].SrcReg[2].Index = hposTemp; - newInst[1].SrcReg[2].Swizzle = SWIZZLE_NOOP; - } - - newInst[3].Opcode = OPCODE_MAD; - newInst[3].DstReg.File = PROGRAM_OUTPUT; - newInst[3].DstReg.Index = VERT_RESULT_HPOS; - newInst[3].DstReg.WriteMask = WRITEMASK_XYZW; - newInst[3].SrcReg[0].File = PROGRAM_INPUT; - newInst[3].SrcReg[0].Index = VERT_ATTRIB_POS; - newInst[3].SrcReg[0].Swizzle = SWIZZLE_WWWW; - newInst[3].SrcReg[1].File = PROGRAM_STATE_VAR; - newInst[3].SrcReg[1].Index = mvpRef[3]; - newInst[3].SrcReg[1].Swizzle = SWIZZLE_NOOP; - newInst[3].SrcReg[2].File = PROGRAM_TEMPORARY; - newInst[3].SrcReg[2].Index = hposTemp; - newInst[3].SrcReg[2].Swizzle = SWIZZLE_NOOP; - - - /* Append original instructions after new instructions */ - _mesa_copy_instructions (newInst + 4, vprog->Base.Instructions, origLen); - - /* free old instructions */ - _mesa_free_instructions(vprog->Base.Instructions, origLen); - - /* install new instructions */ - vprog->Base.Instructions = newInst; - vprog->Base.NumInstructions = newLen; - vprog->Base.InputsRead |= VERT_BIT_POS; - vprog->Base.OutputsWritten |= BITFIELD64_BIT(VERT_RESULT_HPOS); -} - - -void -_mesa_insert_mvp_code(GLcontext *ctx, struct gl_vertex_program *vprog) -{ - if (ctx->mvp_with_dp4) - _mesa_insert_mvp_dp4_code( ctx, vprog ); - else - _mesa_insert_mvp_mad_code( ctx, vprog ); -} - - - - - - -/** - * Append extra instructions onto the given fragment program to implement - * the fog mode specified by fprog->FogOption. - * The fragment.fogcoord input is used to compute the fog blend factor. - * - * XXX with a little work, this function could be adapted to add fog code - * to vertex programs too. - */ -void -_mesa_append_fog_code(GLcontext *ctx, struct gl_fragment_program *fprog) -{ - 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; - GLuint i; - GLint fogPRefOpt, fogColorRef; /* state references */ - GLuint colorTemp, fogFactorTemp; /* temporary registerss */ - - if (fprog->FogOption == GL_NONE) { - _mesa_problem(ctx, "_mesa_append_fog_code() called for fragment program" - " with FogOption == GL_NONE"); - return; - } - - /* Alloc storage for new instructions */ - newInst = _mesa_alloc_instructions(newLen); - if (!newInst) { - _mesa_error(ctx, GL_OUT_OF_MEMORY, - "glProgramString(inserting fog_option code)"); - return; - } - - /* Copy orig instructions into new instruction buffer */ - _mesa_copy_instructions(newInst, fprog->Base.Instructions, origLen); - - /* PARAM fogParamsRefOpt = internal optimized fog params; */ - fogPRefOpt - = _mesa_add_state_reference(fprog->Base.Parameters, fogPStateOpt); - /* PARAM fogColorRef = state.fog.color; */ - fogColorRef - = _mesa_add_state_reference(fprog->Base.Parameters, fogColorState); - - /* TEMP colorTemp; */ - colorTemp = fprog->Base.NumTemporaries++; - /* TEMP fogFactorTemp; */ - fogFactorTemp = fprog->Base.NumTemporaries++; - - /* Scan program to find where result.color is written */ - inst = newInst; - for (i = 0; i < fprog->Base.NumInstructions; i++) { - if (inst->Opcode == OPCODE_END) - break; - if (inst->DstReg.File == PROGRAM_OUTPUT && - inst->DstReg.Index == FRAG_RESULT_COLOR) { - /* change the instruction to write to colorTemp w/ clamping */ - inst->DstReg.File = PROGRAM_TEMPORARY; - inst->DstReg.Index = colorTemp; - inst->SaturateMode = SATURATE_ZERO_ONE; - /* don't break (may be several writes to result.color) */ - } - inst++; - } - assert(inst->Opcode == OPCODE_END); /* we'll overwrite this inst */ - - _mesa_init_instructions(inst, 5); - - /* emit instructions to compute fog blending factor */ - if (fprog->FogOption == GL_LINEAR) { - /* MAD fogFactorTemp.x, fragment.fogcoord.x, fogPRefOpt.x, fogPRefOpt.y; */ - inst->Opcode = OPCODE_MAD; - inst->DstReg.File = PROGRAM_TEMPORARY; - inst->DstReg.Index = fogFactorTemp; - inst->DstReg.WriteMask = WRITEMASK_X; - inst->SrcReg[0].File = PROGRAM_INPUT; - inst->SrcReg[0].Index = FRAG_ATTRIB_FOGC; - inst->SrcReg[0].Swizzle = SWIZZLE_XXXX; - inst->SrcReg[1].File = PROGRAM_STATE_VAR; - inst->SrcReg[1].Index = fogPRefOpt; - inst->SrcReg[1].Swizzle = SWIZZLE_XXXX; - inst->SrcReg[2].File = PROGRAM_STATE_VAR; - inst->SrcReg[2].Index = fogPRefOpt; - inst->SrcReg[2].Swizzle = SWIZZLE_YYYY; - inst->SaturateMode = SATURATE_ZERO_ONE; - inst++; - } - else { - ASSERT(fprog->FogOption == GL_EXP || fprog->FogOption == GL_EXP2); - /* fogPRefOpt.z = d/ln(2), fogPRefOpt.w = d/sqrt(ln(2) */ - /* EXP: MUL fogFactorTemp.x, fogPRefOpt.z, fragment.fogcoord.x; */ - /* EXP2: MUL fogFactorTemp.x, fogPRefOpt.w, fragment.fogcoord.x; */ - inst->Opcode = OPCODE_MUL; - inst->DstReg.File = PROGRAM_TEMPORARY; - inst->DstReg.Index = fogFactorTemp; - inst->DstReg.WriteMask = WRITEMASK_X; - inst->SrcReg[0].File = PROGRAM_STATE_VAR; - inst->SrcReg[0].Index = fogPRefOpt; - inst->SrcReg[0].Swizzle - = (fprog->FogOption == GL_EXP) ? SWIZZLE_ZZZZ : SWIZZLE_WWWW; - inst->SrcReg[1].File = PROGRAM_INPUT; - inst->SrcReg[1].Index = FRAG_ATTRIB_FOGC; - inst->SrcReg[1].Swizzle = SWIZZLE_XXXX; - inst++; - if (fprog->FogOption == GL_EXP2) { - /* MUL fogFactorTemp.x, fogFactorTemp.x, fogFactorTemp.x; */ - inst->Opcode = OPCODE_MUL; - inst->DstReg.File = PROGRAM_TEMPORARY; - inst->DstReg.Index = fogFactorTemp; - inst->DstReg.WriteMask = WRITEMASK_X; - inst->SrcReg[0].File = PROGRAM_TEMPORARY; - inst->SrcReg[0].Index = fogFactorTemp; - inst->SrcReg[0].Swizzle = SWIZZLE_XXXX; - inst->SrcReg[1].File = PROGRAM_TEMPORARY; - inst->SrcReg[1].Index = fogFactorTemp; - inst->SrcReg[1].Swizzle = SWIZZLE_XXXX; - inst++; - } - /* EX2_SAT fogFactorTemp.x, -fogFactorTemp.x; */ - inst->Opcode = OPCODE_EX2; - inst->DstReg.File = PROGRAM_TEMPORARY; - inst->DstReg.Index = fogFactorTemp; - inst->DstReg.WriteMask = WRITEMASK_X; - inst->SrcReg[0].File = PROGRAM_TEMPORARY; - inst->SrcReg[0].Index = fogFactorTemp; - inst->SrcReg[0].Negate = NEGATE_XYZW; - inst->SrcReg[0].Swizzle = SWIZZLE_XXXX; - inst->SaturateMode = SATURATE_ZERO_ONE; - inst++; - } - /* LRP result.color.xyz, fogFactorTemp.xxxx, colorTemp, fogColorRef; */ - inst->Opcode = OPCODE_LRP; - inst->DstReg.File = PROGRAM_OUTPUT; - inst->DstReg.Index = FRAG_RESULT_COLOR; - inst->DstReg.WriteMask = WRITEMASK_XYZ; - inst->SrcReg[0].File = PROGRAM_TEMPORARY; - inst->SrcReg[0].Index = fogFactorTemp; - inst->SrcReg[0].Swizzle = SWIZZLE_XXXX; - inst->SrcReg[1].File = PROGRAM_TEMPORARY; - inst->SrcReg[1].Index = colorTemp; - inst->SrcReg[1].Swizzle = SWIZZLE_NOOP; - inst->SrcReg[2].File = PROGRAM_STATE_VAR; - inst->SrcReg[2].Index = fogColorRef; - inst->SrcReg[2].Swizzle = SWIZZLE_NOOP; - inst++; - /* MOV result.color.w, colorTemp.x; # copy alpha */ - inst->Opcode = OPCODE_MOV; - inst->DstReg.File = PROGRAM_OUTPUT; - inst->DstReg.Index = FRAG_RESULT_COLOR; - inst->DstReg.WriteMask = WRITEMASK_W; - inst->SrcReg[0].File = PROGRAM_TEMPORARY; - inst->SrcReg[0].Index = colorTemp; - inst->SrcReg[0].Swizzle = SWIZZLE_NOOP; - inst++; - /* END; */ - inst->Opcode = OPCODE_END; - inst++; - - /* free old instructions */ - _mesa_free_instructions(fprog->Base.Instructions, origLen); - - /* install new instructions */ - fprog->Base.Instructions = newInst; - fprog->Base.NumInstructions = inst - newInst; - 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); - } -} - - -/** - * Scan/rewrite program to remove reads of custom (output) registers. - * The passed type has to be either PROGRAM_OUTPUT or PROGRAM_VARYING - * (for vertex shaders). - * In GLSL shaders, varying vars can be read and written. - * On some hardware, trying to read an output register causes trouble. - * So, rewrite the program to use a temporary register in this case. - */ -void -_mesa_remove_output_reads(struct gl_program *prog, gl_register_file type) -{ - GLuint i; - GLint outputMap[VERT_RESULT_MAX]; - GLuint numVaryingReads = 0; - GLboolean usedTemps[MAX_PROGRAM_TEMPS]; - GLuint firstTemp = 0; - - _mesa_find_used_registers(prog, PROGRAM_TEMPORARY, - usedTemps, MAX_PROGRAM_TEMPS); - - assert(type == PROGRAM_VARYING || type == PROGRAM_OUTPUT); - assert(prog->Target == GL_VERTEX_PROGRAM_ARB || type != PROGRAM_VARYING); - - for (i = 0; i < VERT_RESULT_MAX; i++) - outputMap[i] = -1; - - /* look for instructions which read from varying vars */ - for (i = 0; i < prog->NumInstructions; i++) { - struct prog_instruction *inst = prog->Instructions + i; - const GLuint numSrc = _mesa_num_inst_src_regs(inst->Opcode); - GLuint j; - for (j = 0; j < numSrc; j++) { - if (inst->SrcReg[j].File == type) { - /* replace the read with a temp reg */ - const GLuint var = inst->SrcReg[j].Index; - if (outputMap[var] == -1) { - numVaryingReads++; - outputMap[var] = _mesa_find_free_register(usedTemps, - MAX_PROGRAM_TEMPS, - firstTemp); - firstTemp = outputMap[var] + 1; - } - inst->SrcReg[j].File = PROGRAM_TEMPORARY; - inst->SrcReg[j].Index = outputMap[var]; - } - } - } - - if (numVaryingReads == 0) - return; /* nothing to be done */ - - /* look for instructions which write to the varying vars identified above */ - for (i = 0; i < prog->NumInstructions; i++) { - struct prog_instruction *inst = prog->Instructions + i; - if (inst->DstReg.File == type && - outputMap[inst->DstReg.Index] >= 0) { - /* change inst to write to the temp reg, instead of the varying */ - inst->DstReg.File = PROGRAM_TEMPORARY; - inst->DstReg.Index = outputMap[inst->DstReg.Index]; - } - } - - /* insert new instructions to copy the temp vars to the varying vars */ - { - struct prog_instruction *inst; - GLint endPos, var; - - /* Look for END instruction and insert the new varying writes */ - endPos = -1; - for (i = 0; i < prog->NumInstructions; i++) { - struct prog_instruction *inst = prog->Instructions + i; - if (inst->Opcode == OPCODE_END) { - endPos = i; - _mesa_insert_instructions(prog, i, numVaryingReads); - break; - } - } - - assert(endPos >= 0); - - /* insert new MOV instructions here */ - inst = prog->Instructions + endPos; - for (var = 0; var < VERT_RESULT_MAX; var++) { - if (outputMap[var] >= 0) { - /* MOV VAR[var], TEMP[tmp]; */ - inst->Opcode = OPCODE_MOV; - inst->DstReg.File = type; - inst->DstReg.Index = var; - inst->SrcReg[0].File = PROGRAM_TEMPORARY; - inst->SrcReg[0].Index = outputMap[var]; - inst++; - } - } - } -} - - -/** - * Make the given fragment program into a "no-op" shader. - * Actually, just copy the incoming fragment color (or texcoord) - * to the output color. - * This is for debug/test purposes. - */ -void -_mesa_nop_fragment_program(GLcontext *ctx, struct gl_fragment_program *prog) -{ - struct prog_instruction *inst; - GLuint inputAttr; - - inst = _mesa_alloc_instructions(2); - if (!inst) { - _mesa_error(ctx, GL_OUT_OF_MEMORY, "_mesa_nop_fragment_program"); - return; - } - - _mesa_init_instructions(inst, 2); - - inst[0].Opcode = OPCODE_MOV; - inst[0].DstReg.File = PROGRAM_OUTPUT; - inst[0].DstReg.Index = FRAG_RESULT_COLOR; - inst[0].SrcReg[0].File = PROGRAM_INPUT; - if (prog->Base.InputsRead & FRAG_BIT_COL0) - inputAttr = FRAG_ATTRIB_COL0; - else - inputAttr = FRAG_ATTRIB_TEX0; - inst[0].SrcReg[0].Index = inputAttr; - - inst[1].Opcode = OPCODE_END; - - _mesa_free_instructions(prog->Base.Instructions, - prog->Base.NumInstructions); - - prog->Base.Instructions = inst; - prog->Base.NumInstructions = 2; - prog->Base.InputsRead = 1 << inputAttr; - prog->Base.OutputsWritten = BITFIELD64_BIT(FRAG_RESULT_COLOR); -} - - -/** - * \sa _mesa_nop_fragment_program - * Replace the given vertex program with a "no-op" program that just - * transforms vertex position and emits color. - */ -void -_mesa_nop_vertex_program(GLcontext *ctx, struct gl_vertex_program *prog) -{ - struct prog_instruction *inst; - GLuint inputAttr; - - /* - * Start with a simple vertex program that emits color. - */ - inst = _mesa_alloc_instructions(2); - if (!inst) { - _mesa_error(ctx, GL_OUT_OF_MEMORY, "_mesa_nop_vertex_program"); - return; - } - - _mesa_init_instructions(inst, 2); - - inst[0].Opcode = OPCODE_MOV; - inst[0].DstReg.File = PROGRAM_OUTPUT; - inst[0].DstReg.Index = VERT_RESULT_COL0; - inst[0].SrcReg[0].File = PROGRAM_INPUT; - if (prog->Base.InputsRead & VERT_BIT_COLOR0) - inputAttr = VERT_ATTRIB_COLOR0; - else - inputAttr = VERT_ATTRIB_TEX0; - inst[0].SrcReg[0].Index = inputAttr; - - inst[1].Opcode = OPCODE_END; - - _mesa_free_instructions(prog->Base.Instructions, - prog->Base.NumInstructions); - - prog->Base.Instructions = inst; - prog->Base.NumInstructions = 2; - prog->Base.InputsRead = 1 << inputAttr; - prog->Base.OutputsWritten = BITFIELD64_BIT(VERT_RESULT_COL0); - - /* - * Now insert code to do standard modelview/projection transformation. - */ - _mesa_insert_mvp_code(ctx, prog); -} diff --git a/mesalib/src/mesa/shader/programopt.h b/mesalib/src/mesa/shader/programopt.h deleted file mode 100644 index 21fac0784..000000000 --- a/mesalib/src/mesa/shader/programopt.h +++ /dev/null @@ -1,52 +0,0 @@ -/* - * 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 PROGRAMOPT_H -#define PROGRAMOPT_H 1 - - -extern void -_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); - -extern void -_mesa_remove_output_reads(struct gl_program *prog, gl_register_file type); - -extern void -_mesa_nop_fragment_program(GLcontext *ctx, struct gl_fragment_program *prog); - -extern void -_mesa_nop_vertex_program(GLcontext *ctx, struct gl_vertex_program *prog); - - -#endif /* PROGRAMOPT_H */ diff --git a/mesalib/src/mesa/shader/shader_api.c b/mesalib/src/mesa/shader/shader_api.c deleted file mode 100644 index 5e87bb405..000000000 --- a/mesalib/src/mesa/shader/shader_api.c +++ /dev/null @@ -1,2233 +0,0 @@ -/* - * Mesa 3-D graphics library - * Version: 7.6 - * - * Copyright (C) 2004-2008 Brian Paul All Rights Reserved. - * Copyright (C) 2009 VMware, 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. - */ - -/** - * \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 "main/glheader.h" -#include "main/context.h" -#include "main/hash.h" -#include "shader/program.h" -#include "shader/prog_parameter.h" -#include "shader/prog_statevars.h" -#include "shader/prog_uniform.h" -#include "shader/shader_api.h" -#include "shader/slang/slang_compile.h" -#include "shader/slang/slang_link.h" -#include "main/dispatch.h" - - -/** - * Allocate a new gl_shader_program object, initialize it. - */ -static 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_MESA; - shProg->Name = name; - shProg->RefCount = 1; - shProg->Attributes = _mesa_new_parameter_list(); - } - return shProg; -} - - -/** - * Clear (free) the shader program state that gets produced by linking. - */ -void -_mesa_clear_shader_program_data(GLcontext *ctx, - struct gl_shader_program *shProg) -{ - _mesa_reference_vertprog(ctx, &shProg->VertexProgram, NULL); - _mesa_reference_fragprog(ctx, &shProg->FragmentProgram, NULL); - - if (shProg->Uniforms) { - _mesa_free_uniform_list(shProg->Uniforms); - shProg->Uniforms = NULL; - } - - if (shProg->Varying) { - _mesa_free_parameter_list(shProg->Varying); - shProg->Varying = NULL; - } -} - - -/** - * Free all 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) -{ - GLuint i; - - assert(shProg->Type == GL_SHADER_PROGRAM_MESA); - - _mesa_clear_shader_program_data(ctx, shProg); - - if (shProg->Attributes) { - _mesa_free_parameter_list(shProg->Attributes); - shProg->Attributes = NULL; - } - - /* detach shaders */ - for (i = 0; i < shProg->NumShaders; i++) { - _mesa_reference_shader(ctx, &shProg->Shaders[i], NULL); - } - shProg->NumShaders = 0; - - if (shProg->Shaders) { - free(shProg->Shaders); - shProg->Shaders = NULL; - } - - if (shProg->InfoLog) { - free(shProg->InfoLog); - shProg->InfoLog = 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); - - free(shProg); -} - - -/** - * Set ptr to point to shProg. - * If ptr is pointing to another object, decrement its refcount (and delete - * if refcount hits zero). - * Then set ptr to point to shProg, incrementing its refcount. - */ -/* XXX this could be static */ -void -_mesa_reference_shader_program(GLcontext *ctx, - struct gl_shader_program **ptr, - struct gl_shader_program *shProg) -{ - assert(ptr); - if (*ptr == shProg) { - /* no-op */ - return; - } - if (*ptr) { - /* Unreference the old shader program */ - GLboolean deleteFlag = GL_FALSE; - struct gl_shader_program *old = *ptr; - - ASSERT(old->RefCount > 0); - old->RefCount--; -#if 0 - printf("ShaderProgram %p ID=%u RefCount-- to %d\n", - (void *) old, old->Name, old->RefCount); -#endif - deleteFlag = (old->RefCount == 0); - - if (deleteFlag) { - _mesa_HashRemove(ctx->Shared->ShaderObjects, old->Name); - _mesa_free_shader_program(ctx, old); - } - - *ptr = NULL; - } - assert(!*ptr); - - if (shProg) { - shProg->RefCount++; -#if 0 - printf("ShaderProgram %p ID=%u RefCount++ to %d\n", - (void *) shProg, shProg->Name, shProg->RefCount); -#endif - *ptr = 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_MESA) { - return NULL; - } - return shProg; - } - return NULL; -} - - -/** - * As above, but record an error if program is not found. - */ -static struct gl_shader_program * -_mesa_lookup_shader_program_err(GLcontext *ctx, GLuint name, - const char *caller) -{ - if (!name) { - _mesa_error(ctx, GL_INVALID_VALUE, caller); - return NULL; - } - else { - struct gl_shader_program *shProg = (struct gl_shader_program *) - _mesa_HashLookup(ctx->Shared->ShaderObjects, name); - if (!shProg) { - _mesa_error(ctx, GL_INVALID_VALUE, caller); - return NULL; - } - if (shProg->Type != GL_SHADER_PROGRAM_MESA) { - _mesa_error(ctx, GL_INVALID_OPERATION, caller); - return NULL; - } - return shProg; - } -} - - - - -/** - * 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) -{ - if (sh->Source) - free((void *) sh->Source); - if (sh->InfoLog) - free(sh->InfoLog); - _mesa_reference_program(ctx, &sh->Program, NULL); - free(sh); -} - - -/** - * Set ptr to point to sh. - * If ptr is pointing to another shader, decrement its refcount (and delete - * if refcount hits zero). - * Then set ptr to point to sh, incrementing its refcount. - */ -/* XXX this could be static */ -void -_mesa_reference_shader(GLcontext *ctx, struct gl_shader **ptr, - struct gl_shader *sh) -{ - assert(ptr); - if (*ptr == sh) { - /* no-op */ - return; - } - if (*ptr) { - /* Unreference the old shader */ - GLboolean deleteFlag = GL_FALSE; - struct gl_shader *old = *ptr; - - ASSERT(old->RefCount > 0); - old->RefCount--; - /*printf("SHADER DECR %p (%d) to %d\n", - (void*) old, old->Name, old->RefCount);*/ - deleteFlag = (old->RefCount == 0); - - if (deleteFlag) { - _mesa_HashRemove(ctx->Shared->ShaderObjects, old->Name); - _mesa_free_shader(ctx, old); - } - - *ptr = NULL; - } - assert(!*ptr); - - if (sh) { - /* reference new */ - sh->RefCount++; - /*printf("SHADER INCR %p (%d) to %d\n", - (void*) sh, sh->Name, sh->RefCount);*/ - *ptr = 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_MESA) { - return NULL; - } - return sh; - } - return NULL; -} - - -/** - * As above, but record an error if shader is not found. - */ -static struct gl_shader * -_mesa_lookup_shader_err(GLcontext *ctx, GLuint name, const char *caller) -{ - if (!name) { - _mesa_error(ctx, GL_INVALID_VALUE, caller); - return NULL; - } - else { - struct gl_shader *sh = (struct gl_shader *) - _mesa_HashLookup(ctx->Shared->ShaderObjects, name); - if (!sh) { - _mesa_error(ctx, GL_INVALID_VALUE, caller); - return NULL; - } - if (sh->Type == GL_SHADER_PROGRAM_MESA) { - _mesa_error(ctx, GL_INVALID_OPERATION, caller); - return NULL; - } - return sh; - } -} - - -/** - * Return mask of GLSL_x flags by examining the MESA_GLSL env var. - */ -static GLbitfield -get_shader_flags(void) -{ - GLbitfield flags = 0x0; - const char *env = _mesa_getenv("MESA_GLSL"); - - if (env) { - if (strstr(env, "dump")) - flags |= GLSL_DUMP; - if (strstr(env, "log")) - flags |= GLSL_LOG; - if (strstr(env, "nopvert")) - flags |= GLSL_NOP_VERT; - if (strstr(env, "nopfrag")) - flags |= GLSL_NOP_FRAG; - if (strstr(env, "nopt")) - flags |= GLSL_NO_OPT; - else if (strstr(env, "opt")) - flags |= GLSL_OPT; - if (strstr(env, "uniform")) - flags |= GLSL_UNIFORMS; - if (strstr(env, "useprog")) - flags |= GLSL_USE_PROG; - } - - return flags; -} - - -/** - * 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.EmitContReturn = GL_TRUE; - ctx->Shader.EmitCondCodes = GL_FALSE; - ctx->Shader.EmitComments = GL_FALSE; - ctx->Shader.Flags = get_shader_flags(); - - /* Default pragma settings */ - ctx->Shader.DefaultPragmas.IgnoreOptimize = GL_FALSE; - ctx->Shader.DefaultPragmas.IgnoreDebug = GL_FALSE; - ctx->Shader.DefaultPragmas.Optimize = GL_TRUE; - ctx->Shader.DefaultPragmas.Debug = GL_FALSE; -} - - -/** - * Free the per-context shader-related state. - */ -void -_mesa_free_shader_state(GLcontext *ctx) -{ - _mesa_reference_shader_program(ctx, &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; -} - - -static 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; -} - - -static 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.AttachShader() - */ -static void -_mesa_attach_shader(GLcontext *ctx, GLuint program, GLuint shader) -{ - struct gl_shader_program *shProg; - struct gl_shader *sh; - GLuint i, n; - - shProg = _mesa_lookup_shader_program_err(ctx, program, "glAttachShader"); - if (!shProg) - return; - - sh = _mesa_lookup_shader_err(ctx, shader, "glAttachShader"); - if (!sh) { - return; - } - - n = shProg->NumShaders; - for (i = 0; i < n; i++) { - if (shProg->Shaders[i] == sh) { - /* The shader is already attched to this program. The - * GL_ARB_shader_objects spec says: - * - * "The error INVALID_OPERATION is generated by AttachObjectARB - * if <obj> is already attached to <containerObj>." - */ - _mesa_error(ctx, GL_INVALID_OPERATION, "glAttachShader"); - 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] = NULL; /* since realloc() didn't zero the new space */ - _mesa_reference_shader(ctx, &shProg->Shaders[n], sh); - shProg->NumShaders++; -} - - -static GLint -_mesa_get_attrib_location(GLcontext *ctx, GLuint program, - const GLchar *name) -{ - struct gl_shader_program *shProg - = _mesa_lookup_shader_program_err(ctx, program, "glGetAttribLocation"); - - if (!shProg) { - return -1; - } - - if (!shProg->LinkStatus) { - _mesa_error(ctx, GL_INVALID_OPERATION, - "glGetAttribLocation(program not linked)"); - return -1; - } - - if (!name) - return -1; - - if (shProg->VertexProgram) { - const struct gl_program_parameter_list *attribs = - shProg->VertexProgram->Base.Attributes; - if (attribs) { - GLint i = _mesa_lookup_parameter_index(attribs, -1, name); - if (i >= 0) { - return attribs->Parameters[i].StateIndexes[0]; - } - } - } - return -1; -} - - -static void -_mesa_bind_attrib_location(GLcontext *ctx, GLuint program, GLuint index, - const GLchar *name) -{ - struct gl_shader_program *shProg; - const GLint size = -1; /* unknown size */ - GLint i, oldIndex; - GLenum datatype = GL_FLOAT_VEC4; - - shProg = _mesa_lookup_shader_program_err(ctx, program, - "glBindAttribLocation"); - if (!shProg) { - return; - } - - if (!name) - return; - - if (strncmp(name, "gl_", 3) == 0) { - _mesa_error(ctx, GL_INVALID_OPERATION, - "glBindAttribLocation(illegal name)"); - return; - } - - if (index >= ctx->Const.VertexProgram.MaxAttribs) { - _mesa_error(ctx, GL_INVALID_VALUE, "glBindAttribLocation(index)"); - return; - } - - if (shProg->LinkStatus) { - /* get current index/location for the attribute */ - oldIndex = _mesa_get_attrib_location(ctx, program, name); - } - else { - oldIndex = -1; - } - - /* this will replace the current value if it's already in the list */ - i = _mesa_add_attribute(shProg->Attributes, name, size, datatype, index); - if (i < 0) { - _mesa_error(ctx, GL_OUT_OF_MEMORY, "glBindAttribLocation"); - return; - } - - /* - * Note that this attribute binding won't go into effect until - * glLinkProgram is called again. - */ -} - - -static 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; -} - - -static 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); - - assert(shProg->RefCount == 1); - - return name; -} - - -/** - * Named w/ "2" to indicate OpenGL 2.x vs GL_ARB_fragment_programs's - * DeleteProgramARB. - */ -static void -_mesa_delete_program2(GLcontext *ctx, GLuint name) -{ - /* - * NOTE: deleting shaders/programs works a bit differently than - * texture objects (and buffer objects, etc). Shader/program - * handles/IDs exist in the hash table until the object is really - * deleted (refcount==0). With texture objects, the handle/ID is - * removed from the hash table in glDeleteTextures() while the tex - * object itself might linger until its refcount goes to zero. - */ - struct gl_shader_program *shProg; - - shProg = _mesa_lookup_shader_program_err(ctx, name, "glDeleteProgram"); - if (!shProg) - return; - - shProg->DeletePending = GL_TRUE; - - /* effectively, decr shProg's refcount */ - _mesa_reference_shader_program(ctx, &shProg, NULL); -} - - -static void -_mesa_delete_shader(GLcontext *ctx, GLuint shader) -{ - struct gl_shader *sh; - - sh = _mesa_lookup_shader_err(ctx, shader, "glDeleteShader"); - if (!sh) - return; - - sh->DeletePending = GL_TRUE; - - /* effectively, decr sh's refcount */ - _mesa_reference_shader(ctx, &sh, NULL); -} - - -static void -_mesa_detach_shader(GLcontext *ctx, GLuint program, GLuint shader) -{ - struct gl_shader_program *shProg; - GLuint n; - GLuint i, j; - - shProg = _mesa_lookup_shader_program_err(ctx, program, "glDetachShader"); - if (!shProg) - return; - - n = shProg->NumShaders; - - for (i = 0; i < n; i++) { - if (shProg->Shaders[i]->Name == shader) { - /* found it */ - struct gl_shader **newList; - - /* release */ - _mesa_reference_shader(ctx, &shProg->Shaders[i], NULL); - - /* alloc new, smaller array */ - newList = (struct gl_shader **) - 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]; - free(shProg->Shaders); - - shProg->Shaders = newList; - shProg->NumShaders = n - 1; - -#ifdef DEBUG - /* sanity check */ - { - for (j = 0; j < shProg->NumShaders; j++) { - assert(shProg->Shaders[j]->Type == GL_VERTEX_SHADER || - shProg->Shaders[j]->Type == GL_FRAGMENT_SHADER); - assert(shProg->Shaders[j]->RefCount > 0); - } - } -#endif - - return; - } - } - - /* not found */ - { - GLenum err; - if (_mesa_is_shader(ctx, shader)) - err = GL_INVALID_OPERATION; - else if (_mesa_is_program(ctx, shader)) - err = GL_INVALID_OPERATION; - else - err = GL_INVALID_VALUE; - _mesa_error(ctx, err, "glDetachProgram(shader)"); - return; - } -} - - -static GLint -sizeof_glsl_type(GLenum type) -{ - switch (type) { - case GL_FLOAT: - case GL_INT: - case GL_BOOL: - case GL_SAMPLER_1D: - case GL_SAMPLER_2D: - case GL_SAMPLER_3D: - case GL_SAMPLER_CUBE: - case GL_SAMPLER_1D_SHADOW: - case GL_SAMPLER_2D_SHADOW: - case GL_SAMPLER_2D_RECT_ARB: - case GL_SAMPLER_2D_RECT_SHADOW_ARB: - case GL_SAMPLER_1D_ARRAY_EXT: - case GL_SAMPLER_2D_ARRAY_EXT: - case GL_SAMPLER_1D_ARRAY_SHADOW_EXT: - case GL_SAMPLER_2D_ARRAY_SHADOW_EXT: - case GL_SAMPLER_CUBE_SHADOW_EXT: - return 1; - case GL_FLOAT_VEC2: - case GL_INT_VEC2: - case GL_BOOL_VEC2: - return 2; - case GL_FLOAT_VEC3: - case GL_INT_VEC3: - case GL_BOOL_VEC3: - return 3; - case GL_FLOAT_VEC4: - case GL_INT_VEC4: - case GL_BOOL_VEC4: - return 4; - case GL_FLOAT_MAT2: - case GL_FLOAT_MAT2x3: - case GL_FLOAT_MAT2x4: - return 8; /* two float[4] vectors */ - case GL_FLOAT_MAT3: - case GL_FLOAT_MAT3x2: - case GL_FLOAT_MAT3x4: - return 12; /* three float[4] vectors */ - case GL_FLOAT_MAT4: - case GL_FLOAT_MAT4x2: - case GL_FLOAT_MAT4x3: - return 16; /* four float[4] vectors */ - default: - _mesa_problem(NULL, "Invalid type in sizeof_glsl_type()"); - return 1; - } -} - - -static GLboolean -is_boolean_type(GLenum type) -{ - switch (type) { - case GL_BOOL: - case GL_BOOL_VEC2: - case GL_BOOL_VEC3: - case GL_BOOL_VEC4: - return GL_TRUE; - default: - return GL_FALSE; - } -} - - -static GLboolean -is_integer_type(GLenum type) -{ - switch (type) { - case GL_INT: - case GL_INT_VEC2: - case GL_INT_VEC3: - case GL_INT_VEC4: - return GL_TRUE; - default: - return GL_FALSE; - } -} - - -static GLboolean -is_sampler_type(GLenum type) -{ - switch (type) { - case GL_SAMPLER_1D: - case GL_SAMPLER_2D: - case GL_SAMPLER_3D: - case GL_SAMPLER_CUBE: - case GL_SAMPLER_1D_SHADOW: - case GL_SAMPLER_2D_SHADOW: - case GL_SAMPLER_2D_RECT_ARB: - case GL_SAMPLER_2D_RECT_SHADOW_ARB: - case GL_SAMPLER_1D_ARRAY_EXT: - case GL_SAMPLER_2D_ARRAY_EXT: - case GL_SAMPLER_1D_ARRAY_SHADOW_EXT: - case GL_SAMPLER_2D_ARRAY_SHADOW_EXT: - return GL_TRUE; - default: - return GL_FALSE; - } -} - - -static void -_mesa_get_active_attrib(GLcontext *ctx, GLuint program, GLuint index, - GLsizei maxLength, GLsizei *length, GLint *size, - GLenum *type, GLchar *nameOut) -{ - const struct gl_program_parameter_list *attribs = NULL; - struct gl_shader_program *shProg; - - shProg = _mesa_lookup_shader_program_err(ctx, program, "glGetActiveAttrib"); - if (!shProg) - return; - - if (shProg->VertexProgram) - attribs = shProg->VertexProgram->Base.Attributes; - - if (!attribs || index >= attribs->NumParameters) { - _mesa_error(ctx, GL_INVALID_VALUE, "glGetActiveAttrib(index)"); - return; - } - - copy_string(nameOut, maxLength, length, attribs->Parameters[index].Name); - - if (size) - *size = attribs->Parameters[index].Size - / sizeof_glsl_type(attribs->Parameters[index].DataType); - - if (type) - *type = attribs->Parameters[index].DataType; -} - - -static struct gl_program_parameter * -get_uniform_parameter(const struct gl_shader_program *shProg, GLuint index) -{ - const struct gl_program *prog = NULL; - GLint progPos; - - progPos = shProg->Uniforms->Uniforms[index].VertPos; - if (progPos >= 0) { - prog = &shProg->VertexProgram->Base; - } - else { - progPos = shProg->Uniforms->Uniforms[index].FragPos; - if (progPos >= 0) { - prog = &shProg->FragmentProgram->Base; - } - } - - if (!prog || progPos < 0) - return NULL; /* should never happen */ - - return &prog->Parameters->Parameters[progPos]; -} - - -/** - * Called via ctx->Driver.GetActiveUniform(). - */ -static void -_mesa_get_active_uniform(GLcontext *ctx, GLuint program, GLuint index, - GLsizei maxLength, GLsizei *length, GLint *size, - GLenum *type, GLchar *nameOut) -{ - const struct gl_shader_program *shProg; - const struct gl_program *prog = NULL; - const struct gl_program_parameter *param; - GLint progPos; - - shProg = _mesa_lookup_shader_program_err(ctx, program, "glGetActiveUniform"); - if (!shProg) - return; - - if (!shProg->Uniforms || index >= shProg->Uniforms->NumUniforms) { - _mesa_error(ctx, GL_INVALID_VALUE, "glGetActiveUniform(index)"); - return; - } - - progPos = shProg->Uniforms->Uniforms[index].VertPos; - if (progPos >= 0) { - prog = &shProg->VertexProgram->Base; - } - else { - progPos = shProg->Uniforms->Uniforms[index].FragPos; - if (progPos >= 0) { - prog = &shProg->FragmentProgram->Base; - } - } - - if (!prog || progPos < 0) - return; /* should never happen */ - - ASSERT(progPos < prog->Parameters->NumParameters); - param = &prog->Parameters->Parameters[progPos]; - - if (nameOut) { - copy_string(nameOut, maxLength, length, param->Name); - } - - if (size) { - GLint typeSize = sizeof_glsl_type(param->DataType); - if ((GLint) param->Size > typeSize) { - /* This is an array. - * Array elements are placed on vector[4] boundaries so they're - * a multiple of four floats. We round typeSize up to next multiple - * of four to get the right size below. - */ - typeSize = (typeSize + 3) & ~3; - } - /* Note that the returned size is in units of the <type>, not bytes */ - *size = param->Size / typeSize; - } - - if (type) { - *type = param->DataType; - } -} - - -/** - * Called via ctx->Driver.GetAttachedShaders(). - */ -static void -_mesa_get_attached_shaders(GLcontext *ctx, GLuint program, GLsizei maxCount, - GLsizei *count, GLuint *obj) -{ - struct gl_shader_program *shProg = - _mesa_lookup_shader_program_err(ctx, program, "glGetAttachedShaders"); - if (shProg) { - GLuint i; - for (i = 0; i < (GLuint) maxCount && i < shProg->NumShaders; i++) { - obj[i] = shProg->Shaders[i]->Name; - } - if (count) - *count = i; - } -} - - -static GLuint -_mesa_get_handle(GLcontext *ctx, GLenum pname) -{ - GLint handle = 0; - - if (pname == GL_PROGRAM_OBJECT_ARB) { - CALL_GetIntegerv(ctx->Exec, (GL_CURRENT_PROGRAM, &handle)); - } else { - _mesa_error(ctx, GL_INVALID_ENUM, "glGetHandleARB"); - } - - return handle; -} - - -static void -_mesa_get_programiv(GLcontext *ctx, GLuint program, - GLenum pname, GLint *params) -{ - const struct gl_program_parameter_list *attribs; - struct gl_shader_program *shProg - = _mesa_lookup_shader_program(ctx, program); - - if (!shProg) { - _mesa_error(ctx, GL_INVALID_VALUE, "glGetProgramiv(program)"); - return; - } - - if (shProg->VertexProgram) - attribs = shProg->VertexProgram->Base.Attributes; - else - attribs = NULL; - - 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) + 1 : 0; - break; - case GL_ATTACHED_SHADERS: - *params = shProg->NumShaders; - break; - case GL_ACTIVE_ATTRIBUTES: - *params = attribs ? attribs->NumParameters : 0; - break; - case GL_ACTIVE_ATTRIBUTE_MAX_LENGTH: - *params = _mesa_longest_parameter_name(attribs, PROGRAM_INPUT) + 1; - break; - case GL_ACTIVE_UNIFORMS: - *params = shProg->Uniforms ? shProg->Uniforms->NumUniforms : 0; - break; - case GL_ACTIVE_UNIFORM_MAX_LENGTH: - *params = _mesa_longest_uniform_name(shProg->Uniforms); - if (*params > 0) - (*params)++; /* add one for terminating zero */ - break; - case GL_PROGRAM_BINARY_LENGTH_OES: - *params = 0; - break; - default: - _mesa_error(ctx, GL_INVALID_ENUM, "glGetProgramiv(pname)"); - return; - } -} - - -static void -_mesa_get_shaderiv(GLcontext *ctx, GLuint name, GLenum pname, GLint *params) -{ - struct gl_shader *shader = _mesa_lookup_shader_err(ctx, name, "glGetShaderiv"); - - if (!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) + 1 : 0; - break; - case GL_SHADER_SOURCE_LENGTH: - *params = shader->Source ? strlen((char *) shader->Source) + 1 : 0; - break; - default: - _mesa_error(ctx, GL_INVALID_ENUM, "glGetShaderiv(pname)"); - return; - } -} - - -static 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); -} - - -static 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(). - */ -static void -_mesa_get_shader_source(GLcontext *ctx, GLuint shader, GLsizei maxLength, - GLsizei *length, GLchar *sourceOut) -{ - struct gl_shader *sh; - sh = _mesa_lookup_shader_err(ctx, shader, "glGetShaderSource"); - if (!sh) { - return; - } - copy_string(sourceOut, maxLength, length, sh->Source); -} - - -static void -get_matrix_dims(GLenum type, GLint *rows, GLint *cols) -{ - switch (type) { - case GL_FLOAT_MAT2: - *rows = *cols = 2; - break; - case GL_FLOAT_MAT2x3: - *rows = 3; - *cols = 2; - break; - case GL_FLOAT_MAT2x4: - *rows = 4; - *cols = 2; - break; - case GL_FLOAT_MAT3: - *rows = 3; - *cols = 3; - break; - case GL_FLOAT_MAT3x2: - *rows = 2; - *cols = 3; - break; - case GL_FLOAT_MAT3x4: - *rows = 4; - *cols = 3; - break; - case GL_FLOAT_MAT4: - *rows = 4; - *cols = 4; - break; - case GL_FLOAT_MAT4x2: - *rows = 2; - *cols = 4; - break; - case GL_FLOAT_MAT4x3: - *rows = 3; - *cols = 4; - break; - default: - *rows = *cols = 0; - } -} - - -/** - * Determine the number of rows and columns occupied by a uniform - * according to its datatype. For non-matrix types (such as GL_FLOAT_VEC4), - * the number of rows = 1 and cols = number of elements in the vector. - */ -static void -get_uniform_rows_cols(const struct gl_program_parameter *p, - GLint *rows, GLint *cols) -{ - get_matrix_dims(p->DataType, rows, cols); - if (*rows == 0 && *cols == 0) { - /* not a matrix type, probably a float or vector */ - if (p->Size <= 4) { - *rows = 1; - *cols = p->Size; - } - else { - *rows = p->Size / 4 + 1; - if (p->Size % 4 == 0) - *cols = 4; - else - *cols = p->Size % 4; - } - } -} - - -/** - * Helper for get_uniform[fi]v() functions. - * Given a shader program name and uniform location, return a pointer - * to the shader program and return the program parameter position. - */ -static void -lookup_uniform_parameter(GLcontext *ctx, GLuint program, GLint location, - struct gl_program **progOut, GLint *paramPosOut) -{ - struct gl_shader_program *shProg - = _mesa_lookup_shader_program_err(ctx, program, "glGetUniform[if]v"); - struct gl_program *prog = NULL; - GLint progPos = -1; - - /* if shProg is NULL, we'll have already recorded an error */ - - if (shProg) { - if (!shProg->Uniforms || - location < 0 || - location >= (GLint) shProg->Uniforms->NumUniforms) { - _mesa_error(ctx, GL_INVALID_OPERATION, "glGetUniformfv(location)"); - } - else { - /* OK, find the gl_program and program parameter location */ - progPos = shProg->Uniforms->Uniforms[location].VertPos; - if (progPos >= 0) { - prog = &shProg->VertexProgram->Base; - } - else { - progPos = shProg->Uniforms->Uniforms[location].FragPos; - if (progPos >= 0) { - prog = &shProg->FragmentProgram->Base; - } - } - } - } - - *progOut = prog; - *paramPosOut = progPos; -} - - -/** - * GLGL uniform arrays and structs require special handling. - * - * The GL_ARB_shader_objects spec says that if you use - * glGetUniformLocation to get the location of an array, you CANNOT - * access other elements of the array by adding an offset to the - * returned location. For example, you must call - * glGetUniformLocation("foo[16]") if you want to set the 16th element - * of the array with glUniform(). - * - * HOWEVER, some other OpenGL drivers allow accessing array elements - * by adding an offset to the returned array location. And some apps - * seem to depend on that behaviour. - * - * Mesa's gl_uniform_list doesn't directly support this since each - * entry in the list describes one uniform variable, not one uniform - * element. We could insert dummy entries in the list for each array - * element after [0] but that causes complications elsewhere. - * - * We solve this problem by encoding two values in the location that's - * returned by glGetUniformLocation(): - * a) index into gl_uniform_list::Uniforms[] for the uniform - * b) an array/field offset (0 for simple types) - * - * These two values are encoded in the high and low halves of a GLint. - * By putting the uniform number in the high part and the offset in the - * low part, we can support the unofficial ability to index into arrays - * by adding offsets to the location value. - */ -static void -merge_location_offset(GLint *location, GLint offset) -{ - *location = (*location << 16) | offset; -} - - -/** - * Seperate the uniform location and parameter offset. See above. - */ -static void -split_location_offset(GLint *location, GLint *offset) -{ - *offset = *location & 0xffff; - *location = *location >> 16; -} - - - -/** - * Called via ctx->Driver.GetUniformfv(). - */ -static void -_mesa_get_uniformfv(GLcontext *ctx, GLuint program, GLint location, - GLfloat *params) -{ - struct gl_program *prog; - GLint paramPos; - GLint offset; - - split_location_offset(&location, &offset); - - lookup_uniform_parameter(ctx, program, location, &prog, ¶mPos); - - if (prog) { - const struct gl_program_parameter *p = - &prog->Parameters->Parameters[paramPos]; - GLint rows, cols, i, j, k; - - get_uniform_rows_cols(p, &rows, &cols); - - k = 0; - for (i = 0; i < rows; i++) { - for (j = 0; j < cols; j++ ) { - params[k++] = prog->Parameters->ParameterValues[paramPos+i][j]; - } - } - } -} - - -/** - * Called via ctx->Driver.GetUniformiv(). - * \sa _mesa_get_uniformfv, only difference is a cast. - */ -static void -_mesa_get_uniformiv(GLcontext *ctx, GLuint program, GLint location, - GLint *params) -{ - struct gl_program *prog; - GLint paramPos; - GLint offset; - - split_location_offset(&location, &offset); - - lookup_uniform_parameter(ctx, program, location, &prog, ¶mPos); - - if (prog) { - const struct gl_program_parameter *p = - &prog->Parameters->Parameters[paramPos]; - GLint rows, cols, i, j, k; - - get_uniform_rows_cols(p, &rows, &cols); - - k = 0; - for (i = 0; i < rows; i++) { - for (j = 0; j < cols; j++ ) { - params[k++] = (GLint) prog->Parameters->ParameterValues[paramPos+i][j]; - } - } - } -} - - -/** - * Called via ctx->Driver.GetUniformLocation(). - * - * The return value will encode two values, the uniform location and an - * offset (used for arrays, structs). - */ -static GLint -_mesa_get_uniform_location(GLcontext *ctx, GLuint program, const GLchar *name) -{ - GLint offset = 0, location = -1; - - struct gl_shader_program *shProg = - _mesa_lookup_shader_program_err(ctx, program, "glGetUniformLocation"); - - if (!shProg) - return -1; - - if (shProg->LinkStatus == GL_FALSE) { - _mesa_error(ctx, GL_INVALID_OPERATION, "glGetUniformfv(program)"); - return -1; - } - - /* XXX we should return -1 if the uniform was declared, but not - * actually used. - */ - - /* XXX we need to be able to parse uniform names for structs and arrays - * such as: - * mymatrix[1] - * mystruct.field1 - */ - - { - /* handle 1-dimension arrays here... */ - char *c = strchr(name, '['); - if (c) { - /* truncate name at [ */ - const GLint len = c - name; - GLchar *newName = malloc(len + 1); - if (!newName) - return -1; /* out of mem */ - memcpy(newName, name, len); - newName[len] = 0; - - location = _mesa_lookup_uniform(shProg->Uniforms, newName); - if (location >= 0) { - const GLint element = atoi(c + 1); - if (element > 0) { - /* get type of the uniform array element */ - struct gl_program_parameter *p; - p = get_uniform_parameter(shProg, location); - if (p) { - GLint rows, cols; - get_matrix_dims(p->DataType, &rows, &cols); - if (rows < 1) - rows = 1; - offset = element * rows; - } - } - } - - free(newName); - } - } - - if (location < 0) { - location = _mesa_lookup_uniform(shProg->Uniforms, name); - } - - if (location >= 0) { - merge_location_offset(&location, offset); - } - - return location; -} - - - -/** - * Called via ctx->Driver.ShaderSource() - */ -static void -_mesa_shader_source(GLcontext *ctx, GLuint shader, const GLchar *source) -{ - struct gl_shader *sh; - - sh = _mesa_lookup_shader_err(ctx, shader, "glShaderSource"); - if (!sh) - return; - - /* free old shader source string and install new one */ - if (sh->Source) { - free((void *) sh->Source); - } - sh->Source = source; - sh->CompileStatus = GL_FALSE; -#ifdef DEBUG - sh->SourceChecksum = _mesa_str_checksum(sh->Source); -#endif -} - - -/** - * Called via ctx->Driver.CompileShader() - */ -static void -_mesa_compile_shader(GLcontext *ctx, GLuint shaderObj) -{ - struct gl_shader *sh; - - sh = _mesa_lookup_shader_err(ctx, shaderObj, "glCompileShader"); - if (!sh) - return; - - /* set default pragma state for shader */ - sh->Pragmas = ctx->Shader.DefaultPragmas; - - /* this call will set the sh->CompileStatus field to indicate if - * compilation was successful. - */ - (void) _slang_compile(ctx, sh); -} - - -/** - * Called via ctx->Driver.LinkProgram() - */ -static void -_mesa_link_program(GLcontext *ctx, GLuint program) -{ - struct gl_shader_program *shProg; - - shProg = _mesa_lookup_shader_program_err(ctx, program, "glLinkProgram"); - if (!shProg) - return; - - FLUSH_VERTICES(ctx, _NEW_PROGRAM); - - _slang_link(ctx, program, shProg); - - /* debug code */ - if (0) { - GLuint i; - - printf("Link %u shaders in program %u: %s\n", - shProg->NumShaders, shProg->Name, - shProg->LinkStatus ? "Success" : "Failed"); - - for (i = 0; i < shProg->NumShaders; i++) { - printf(" shader %u, type 0x%x\n", - shProg->Shaders[i]->Name, - shProg->Shaders[i]->Type); - } - } -} - - -/** - * Print basic shader info (for debug). - */ -static void -print_shader_info(const struct gl_shader_program *shProg) -{ - GLuint i; - - printf("Mesa: glUseProgram(%u)\n", shProg->Name); - for (i = 0; i < shProg->NumShaders; i++) { - const char *s; - switch (shProg->Shaders[i]->Type) { - case GL_VERTEX_SHADER: - s = "vertex"; - break; - case GL_FRAGMENT_SHADER: - s = "fragment"; - break; - case GL_GEOMETRY_SHADER: - s = "geometry"; - break; - default: - s = ""; - } - printf(" %s shader %u, checksum %u\n", s, - shProg->Shaders[i]->Name, - shProg->Shaders[i]->SourceChecksum); - } - if (shProg->VertexProgram) - printf(" vert prog %u\n", shProg->VertexProgram->Base.Id); - if (shProg->FragmentProgram) - printf(" frag prog %u\n", shProg->FragmentProgram->Base.Id); -} - - -/** - * Called via ctx->Driver.UseProgram() - */ -void -_mesa_use_program(GLcontext *ctx, GLuint program) -{ - struct gl_shader_program *shProg; - - if (ctx->Shader.CurrentProgram && - ctx->Shader.CurrentProgram->Name == program) { - /* no-op */ - return; - } - - if (program) { - shProg = _mesa_lookup_shader_program_err(ctx, program, "glUseProgram"); - if (!shProg) { - return; - } - if (!shProg->LinkStatus) { - _mesa_error(ctx, GL_INVALID_OPERATION, - "glUseProgram(program %u not linked)", program); - return; - } - - /* debug code */ - if (ctx->Shader.Flags & GLSL_USE_PROG) { - print_shader_info(shProg); - } - } - else { - shProg = NULL; - } - - if (ctx->Shader.CurrentProgram != shProg) { - FLUSH_VERTICES(ctx, _NEW_PROGRAM | _NEW_PROGRAM_CONSTANTS); - _mesa_reference_shader_program(ctx, &ctx->Shader.CurrentProgram, shProg); - } -} - - - -/** - * Update the vertex/fragment program's TexturesUsed array. - * - * This needs to be called after glUniform(set sampler var) is called. - * A call to glUniform(samplerVar, value) causes a sampler to point to a - * particular texture unit. We know the sampler's texture target - * (1D/2D/3D/etc) from compile time but the sampler's texture unit is - * set by glUniform() calls. - * - * So, scan the program->SamplerUnits[] and program->SamplerTargets[] - * information to update the prog->TexturesUsed[] values. - * Each value of TexturesUsed[unit] is one of zero, TEXTURE_1D_INDEX, - * TEXTURE_2D_INDEX, TEXTURE_3D_INDEX, etc. - * We'll use that info for state validation before rendering. - */ -void -_mesa_update_shader_textures_used(struct gl_program *prog) -{ - GLuint s; - - memset(prog->TexturesUsed, 0, sizeof(prog->TexturesUsed)); - - for (s = 0; s < MAX_SAMPLERS; s++) { - if (prog->SamplersUsed & (1 << s)) { - GLuint unit = prog->SamplerUnits[s]; - GLuint tgt = prog->SamplerTargets[s]; - assert(unit < MAX_TEXTURE_IMAGE_UNITS); - assert(tgt < NUM_TEXTURE_TARGETS); - prog->TexturesUsed[unit] |= (1 << tgt); - } - } -} - - -/** - * Check if the type given by userType is allowed to set a uniform of the - * target type. Generally, equivalence is required, but setting Boolean - * uniforms can be done with glUniformiv or glUniformfv. - */ -static GLboolean -compatible_types(GLenum userType, GLenum targetType) -{ - if (userType == targetType) - return GL_TRUE; - - if (targetType == GL_BOOL && (userType == GL_FLOAT || userType == GL_INT)) - return GL_TRUE; - - if (targetType == GL_BOOL_VEC2 && (userType == GL_FLOAT_VEC2 || - userType == GL_INT_VEC2)) - return GL_TRUE; - - if (targetType == GL_BOOL_VEC3 && (userType == GL_FLOAT_VEC3 || - userType == GL_INT_VEC3)) - return GL_TRUE; - - if (targetType == GL_BOOL_VEC4 && (userType == GL_FLOAT_VEC4 || - userType == GL_INT_VEC4)) - return GL_TRUE; - - if (is_sampler_type(targetType) && userType == GL_INT) - return GL_TRUE; - - return GL_FALSE; -} - - -/** - * Set the value of a program's uniform variable. - * \param program the program whose uniform to update - * \param index the index of the program parameter for the uniform - * \param offset additional parameter slot offset (for arrays) - * \param type the incoming datatype of 'values' - * \param count the number of uniforms to set - * \param elems number of elements per uniform (1, 2, 3 or 4) - * \param values the new values, of datatype 'type' - */ -static void -set_program_uniform(GLcontext *ctx, struct gl_program *program, - GLint index, GLint offset, - GLenum type, GLsizei count, GLint elems, - const void *values) -{ - const struct gl_program_parameter *param = - &program->Parameters->Parameters[index]; - - assert(offset >= 0); - assert(elems >= 1); - assert(elems <= 4); - - if (!compatible_types(type, param->DataType)) { - _mesa_error(ctx, GL_INVALID_OPERATION, "glUniform(type mismatch)"); - return; - } - - if (index + offset > (GLint) program->Parameters->Size) { - /* out of bounds! */ - return; - } - - if (param->Type == PROGRAM_SAMPLER) { - /* This controls which texture unit which is used by a sampler */ - GLboolean changed = GL_FALSE; - GLint i; - - /* this should have been caught by the compatible_types() check */ - ASSERT(type == GL_INT); - - /* loop over number of samplers to change */ - for (i = 0; i < count; i++) { - GLuint sampler = - (GLuint) program->Parameters->ParameterValues[index + offset + i][0]; - GLuint texUnit = ((GLuint *) values)[i]; - - /* check that the sampler (tex unit index) is legal */ - if (texUnit >= ctx->Const.MaxTextureImageUnits) { - _mesa_error(ctx, GL_INVALID_VALUE, - "glUniform1(invalid sampler/tex unit index)"); - return; - } - - /* This maps a sampler to a texture unit: */ - if (sampler < MAX_SAMPLERS) { -#if 0 - printf("Set program %p sampler %d '%s' to unit %u\n", - program, sampler, param->Name, texUnit); -#endif - if (program->SamplerUnits[sampler] != texUnit) { - program->SamplerUnits[sampler] = texUnit; - changed = GL_TRUE; - } - } - } - - if (changed) { - /* When a sampler's value changes it usually requires rewriting - * a GPU program's TEX instructions since there may not be a - * sampler->texture lookup table. We signal this with the - * ProgramStringNotify() callback. - */ - FLUSH_VERTICES(ctx, _NEW_TEXTURE | _NEW_PROGRAM); - _mesa_update_shader_textures_used(program); - /* Do we need to care about the return value here? - * This should not be the first time the driver was notified of - * this program. - */ - (void) ctx->Driver.ProgramStringNotify(ctx, program->Target, program); - } - } - else { - /* ordinary uniform variable */ - const GLboolean isUniformBool = is_boolean_type(param->DataType); - const GLboolean areIntValues = is_integer_type(type); - const GLint slots = (param->Size + 3) / 4; - const GLint typeSize = sizeof_glsl_type(param->DataType); - GLsizei k, i; - - if ((GLint) param->Size > typeSize) { - /* an array */ - /* we'll ignore extra data below */ - } - else { - /* non-array: count must be at most one; count == 0 is handled by the loop below */ - if (count > 1) { - _mesa_error(ctx, GL_INVALID_OPERATION, - "glUniform(uniform is not an array)"); - return; - } - } - - /* loop over number of array elements */ - for (k = 0; k < count; k++) { - GLfloat *uniformVal; - - if (offset + k >= slots) { - /* Extra array data is ignored */ - break; - } - - /* uniformVal (the destination) is always float[4] */ - uniformVal = program->Parameters->ParameterValues[index + offset + k]; - - if (areIntValues) { - /* convert user's ints to floats */ - 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 the uniform is bool-valued, convert to 1.0 or 0.0 */ - if (isUniformBool) { - for (i = 0; i < elems; i++) { - uniformVal[i] = uniformVal[i] ? 1.0f : 0.0f; - } - } - } - } -} - - -/** - * Called via ctx->Driver.Uniform(). - */ -static void -_mesa_uniform(GLcontext *ctx, GLint location, GLsizei count, - const GLvoid *values, GLenum type) -{ - struct gl_shader_program *shProg = ctx->Shader.CurrentProgram; - struct gl_uniform *uniform; - GLint elems, offset; - GLenum basicType; - - if (!shProg || !shProg->LinkStatus) { - _mesa_error(ctx, GL_INVALID_OPERATION, "glUniform(program not linked)"); - return; - } - - if (location == -1) - return; /* The standard specifies this as a no-op */ - - if (location < -1) { - _mesa_error(ctx, GL_INVALID_OPERATION, "glUniform(location)"); - return; - } - - split_location_offset(&location, &offset); - - if (location < 0 || location >= (GLint) shProg->Uniforms->NumUniforms) { - _mesa_error(ctx, GL_INVALID_VALUE, "glUniform(location)"); - return; - } - - if (count < 0) { - _mesa_error(ctx, GL_INVALID_VALUE, "glUniform(count < 0)"); - return; - } - - switch (type) { - case GL_FLOAT: - basicType = GL_FLOAT; - elems = 1; - break; - case GL_INT: - basicType = GL_INT; - elems = 1; - break; - case GL_FLOAT_VEC2: - basicType = GL_FLOAT; - elems = 2; - break; - case GL_INT_VEC2: - basicType = GL_INT; - elems = 2; - break; - case GL_FLOAT_VEC3: - basicType = GL_FLOAT; - elems = 3; - break; - case GL_INT_VEC3: - basicType = GL_INT; - elems = 3; - break; - case GL_FLOAT_VEC4: - basicType = GL_FLOAT; - elems = 4; - break; - case GL_INT_VEC4: - basicType = GL_INT; - elems = 4; - break; - default: - _mesa_problem(ctx, "Invalid type in _mesa_uniform"); - return; - } - - FLUSH_VERTICES(ctx, _NEW_PROGRAM_CONSTANTS); - - uniform = &shProg->Uniforms->Uniforms[location]; - - if (ctx->Shader.Flags & GLSL_UNIFORMS) { - GLint i; - printf("Mesa: set program %u uniform %s (loc %d) to: ", - shProg->Name, uniform->Name, location); - if (basicType == GL_INT) { - const GLint *v = (const GLint *) values; - for (i = 0; i < count * elems; i++) { - printf("%d ", v[i]); - } - } - else { - const GLfloat *v = (const GLfloat *) values; - for (i = 0; i < count * elems; i++) { - printf("%g ", v[i]); - } - } - printf("\n"); - } - - /* A uniform var may be used by both a vertex shader and a fragment - * shader. We may need to update one or both shader's uniform here: - */ - if (shProg->VertexProgram) { - /* convert uniform location to program parameter index */ - GLint index = uniform->VertPos; - if (index >= 0) { - set_program_uniform(ctx, &shProg->VertexProgram->Base, - index, offset, type, count, elems, values); - } - } - - if (shProg->FragmentProgram) { - /* convert uniform location to program parameter index */ - GLint index = uniform->FragPos; - if (index >= 0) { - set_program_uniform(ctx, &shProg->FragmentProgram->Base, - index, offset, type, count, elems, values); - } - } - - uniform->Initialized = GL_TRUE; -} - - -/** - * Set a matrix-valued program parameter. - */ -static void -set_program_uniform_matrix(GLcontext *ctx, struct gl_program *program, - GLuint index, GLuint offset, - GLuint count, GLuint rows, GLuint cols, - GLboolean transpose, const GLfloat *values) -{ - GLuint mat, row, col; - GLuint src = 0; - const struct gl_program_parameter * param = &program->Parameters->Parameters[index]; - const GLuint slots = (param->Size + 3) / 4; - const GLint typeSize = sizeof_glsl_type(param->DataType); - GLint nr, nc; - - /* check that the number of rows, columns is correct */ - get_matrix_dims(param->DataType, &nr, &nc); - if (rows != nr || cols != nc) { - _mesa_error(ctx, GL_INVALID_OPERATION, - "glUniformMatrix(matrix size mismatch)"); - return; - } - - if ((GLint) param->Size <= typeSize) { - /* non-array: count must be at most one; count == 0 is handled by the loop below */ - if (count > 1) { - _mesa_error(ctx, GL_INVALID_OPERATION, - "glUniformMatrix(uniform is not an array)"); - return; - } - } - - /* - * Note: the _columns_ of a matrix are stored in program registers, not - * the rows. So, the loops below look a little funny. - * XXX could optimize this a bit... - */ - - /* loop over matrices */ - for (mat = 0; mat < count; mat++) { - - /* each matrix: */ - for (col = 0; col < cols; col++) { - GLfloat *v; - if (offset >= slots) { - /* Ignore writes beyond the end of (the used part of) an array */ - return; - } - v = program->Parameters->ParameterValues[index + offset]; - for (row = 0; row < rows; row++) { - if (transpose) { - v[row] = values[src + row * cols + col]; - } - else { - v[row] = values[src + col * rows + row]; - } - } - - offset++; - } - - src += rows * cols; /* next matrix */ - } -} - - -/** - * Called by ctx->Driver.UniformMatrix(). - * Note: cols=2, rows=4 ==> array[2] of vec4 - */ -static void -_mesa_uniform_matrix(GLcontext *ctx, GLint cols, GLint rows, - GLint location, GLsizei count, - GLboolean transpose, const GLfloat *values) -{ - struct gl_shader_program *shProg = ctx->Shader.CurrentProgram; - struct gl_uniform *uniform; - GLint offset; - - if (!shProg || !shProg->LinkStatus) { - _mesa_error(ctx, GL_INVALID_OPERATION, - "glUniformMatrix(program not linked)"); - return; - } - - if (location == -1) - return; /* The standard specifies this as a no-op */ - - if (location < -1) { - _mesa_error(ctx, GL_INVALID_OPERATION, "glUniformMatrix(location)"); - return; - } - - split_location_offset(&location, &offset); - - if (location < 0 || location >= (GLint) shProg->Uniforms->NumUniforms) { - _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_CONSTANTS); - - uniform = &shProg->Uniforms->Uniforms[location]; - - if (shProg->VertexProgram) { - /* convert uniform location to program parameter index */ - GLint index = uniform->VertPos; - if (index >= 0) { - set_program_uniform_matrix(ctx, &shProg->VertexProgram->Base, - index, offset, - count, rows, cols, transpose, values); - } - } - - if (shProg->FragmentProgram) { - /* convert uniform location to program parameter index */ - GLint index = uniform->FragPos; - if (index >= 0) { - set_program_uniform_matrix(ctx, &shProg->FragmentProgram->Base, - index, offset, - count, rows, cols, transpose, values); - } - } - - uniform->Initialized = GL_TRUE; -} - - -/** - * Validate a program's samplers. - * Specifically, check that there aren't two samplers of different types - * pointing to the same texture unit. - * \return GL_TRUE if valid, GL_FALSE if invalid - */ -static GLboolean -validate_samplers(GLcontext *ctx, const struct gl_program *prog, char *errMsg) -{ - static const char *targetName[] = { - "TEXTURE_2D_ARRAY", - "TEXTURE_1D_ARRAY", - "TEXTURE_CUBE", - "TEXTURE_3D", - "TEXTURE_RECT", - "TEXTURE_2D", - "TEXTURE_1D", - }; - GLint targetUsed[MAX_TEXTURE_IMAGE_UNITS]; - GLbitfield samplersUsed = prog->SamplersUsed; - GLuint i; - - assert(Elements(targetName) == NUM_TEXTURE_TARGETS); - - if (samplersUsed == 0x0) - return GL_TRUE; - - for (i = 0; i < Elements(targetUsed); i++) - targetUsed[i] = -1; - - /* walk over bits which are set in 'samplers' */ - while (samplersUsed) { - GLuint unit; - gl_texture_index target; - GLint sampler = _mesa_ffs(samplersUsed) - 1; - assert(sampler >= 0); - assert(sampler < MAX_TEXTURE_IMAGE_UNITS); - unit = prog->SamplerUnits[sampler]; - target = prog->SamplerTargets[sampler]; - if (targetUsed[unit] != -1 && targetUsed[unit] != target) { - _mesa_snprintf(errMsg, 100, - "Texture unit %d is accessed both as %s and %s", - unit, targetName[targetUsed[unit]], targetName[target]); - return GL_FALSE; - } - targetUsed[unit] = target; - samplersUsed ^= (1 << sampler); - } - - return GL_TRUE; -} - - -/** - * Do validation of the given shader program. - * \param errMsg returns error message if validation fails. - * \return GL_TRUE if valid, GL_FALSE if invalid (and set errMsg) - */ -GLboolean -_mesa_validate_shader_program(GLcontext *ctx, - const struct gl_shader_program *shProg, - char *errMsg) -{ - const struct gl_vertex_program *vp = shProg->VertexProgram; - const struct gl_fragment_program *fp = shProg->FragmentProgram; - - if (!shProg->LinkStatus) { - return GL_FALSE; - } - - /* From the GL spec, a program is invalid if any of these are true: - - 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. - */ - - - /* - * Check: any two active samplers in the current program object are of - * different types, but refer to the same texture image unit, - */ - if (vp && !validate_samplers(ctx, &vp->Base, errMsg)) { - return GL_FALSE; - } - if (fp && !validate_samplers(ctx, &fp->Base, errMsg)) { - return GL_FALSE; - } - - return GL_TRUE; -} - - -/** - * Called via glValidateProgram() - */ -static void -_mesa_validate_program(GLcontext *ctx, GLuint program) -{ - struct gl_shader_program *shProg; - char errMsg[100]; - - shProg = _mesa_lookup_shader_program_err(ctx, program, "glValidateProgram"); - if (!shProg) { - return; - } - - shProg->Validated = _mesa_validate_shader_program(ctx, shProg, errMsg); - if (!shProg->Validated) { - /* update info log */ - if (shProg->InfoLog) { - free(shProg->InfoLog); - } - shProg->InfoLog = _mesa_strdup(errMsg); - } -} - - -/** - * Plug in Mesa's GLSL functions into the device driver function table. - */ -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->GetUniformiv = _mesa_get_uniformiv; - 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/mesalib/src/mesa/shader/shader_api.h b/mesalib/src/mesa/shader/shader_api.h deleted file mode 100644 index d08d47373..000000000 --- a/mesalib/src/mesa/shader/shader_api.h +++ /dev/null @@ -1,100 +0,0 @@ -/* - * Mesa 3-D graphics library - * Version: 7.6 - * - * Copyright (C) 2004-2006 Brian Paul All Rights Reserved. - * Copyright (C) 2009 VMware, 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. - */ - - -#ifndef SHADER_API_H -#define SHADER_API_H - - -#include "main/glheader.h" -#include "main/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_clear_shader_program_data(GLcontext *ctx, - struct gl_shader_program *shProg); - -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 void -_mesa_reference_shader_program(GLcontext *ctx, - struct gl_shader_program **ptr, - 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 void -_mesa_reference_shader(GLcontext *ctx, struct gl_shader **ptr, - struct gl_shader *sh); - -extern struct gl_shader * -_mesa_lookup_shader(GLcontext *ctx, GLuint name); - - -extern void -_mesa_update_shader_textures_used(struct gl_program *prog); - - -extern void -_mesa_use_program(GLcontext *ctx, GLuint program); - - -extern GLboolean -_mesa_validate_shader_program(GLcontext *ctx, - const struct gl_shader_program *shProg, - char *errMsg); - -extern void -_mesa_init_glsl_driver_functions(struct dd_function_table *driver); - - -#endif /* SHADER_API_H */ diff --git a/mesalib/src/mesa/shader/slang/descrip.mms b/mesalib/src/mesa/shader/slang/descrip.mms deleted file mode 100644 index 674b786ac..000000000 --- a/mesalib/src/mesa/shader/slang/descrip.mms +++ /dev/null @@ -1,67 +0,0 @@ -# Makefile for core library for VMS -# contributed by Jouk Jansen joukj@hrem.nano.tudelft.nl -# Last revision : 3 October 2007 - -.first - define gl [----.include.gl] - define math [--.math] - define swrast [--.swrast] - define array_cache [--.array_cache] - define main [--.main] - define glapi [--.glapi] - define shader [--.shader] - -.include [----]mms-config. - -##### MACROS ##### - -VPATH = RCS - -INCDIR = [----.include],[--.main],[--.glapi],[-.slang],[-] -LIBDIR = [----.lib] -CFLAGS = /include=($(INCDIR),[])/define=(PTHREADS=1)/name=(as_is,short)/float=ieee/ieee=denorm - -SOURCES = \ - slang_compile.c - -OBJECTS = slang_builtin.obj,slang_codegen.obj,slang_compile.obj,\ - slang_compile_function.obj,slang_compile_operation.obj,\ - slang_compile_struct.obj,slang_compile_variable.obj,slang_emit.obj,\ - slang_ir.obj,slang_label.obj,slang_library_noise.obj,slang_link.obj,\ - slang_log.obj,slang_mem.obj,slang_preprocess.obj,slang_print.obj,\ - slang_simplify.obj,slang_storage.obj,slang_typeinfo.obj,\ - slang_utility.obj,slang_vartable.obj - -##### RULES ##### - -VERSION=Mesa V3.4 - -##### TARGETS ##### -# Make the library -$(LIBDIR)$(GL_LIB) : $(OBJECTS) - @ library $(LIBDIR)$(GL_LIB) $(OBJECTS) - -clean : - purge - delete *.obj;* - -slang_builtin.obj : slang_builtin.c -slang_codegen.obj : slang_codegen.c -slang_compile.obj : slang_compile.c -slang_compile_function.obj : slang_compile_function.c -slang_compile_operation.obj : slang_compile_operation.c -slang_compile_struct.obj : slang_compile_struct.c -slang_compile_variable.obj : slang_compile_variable.c -slang_emit.obj : slang_emit.c -slang_ir.obj : slang_ir.c -slang_label.obj : slang_label.c -slang_library_noise.obj : slang_library_noise.c -slang_link.obj : slang_link.c -slang_log.obj : slang_log.c -slang_mem.obj : slang_mem.c -slang_print.obj : slang_print.c -slang_simplify.obj : slang_simplify.c -slang_storage.obj : slang_storage.c -slang_typeinfo.obj : slang_typeinfo.c -slang_utility.obj : slang_utility.c -slang_vartable.obj : slang_vartable.c diff --git a/mesalib/src/mesa/shader/slang/library/Makefile b/mesalib/src/mesa/shader/slang/library/Makefile deleted file mode 100644 index c6964512b..000000000 --- a/mesalib/src/mesa/shader/slang/library/Makefile +++ /dev/null @@ -1,51 +0,0 @@ -# src/mesa/shader/slang/library/Makefile - -TOP = ../../../../.. - -include $(TOP)/configs/current - -GLSL_CL = $(TOP)/src/glsl/apps/compile - -# -# targets -# - -.PHONY: default clean - -default: builtin - -clean: - -rm -f *_gc.h - -builtin: builtin_110 builtin_120 - -# -# builtin library sources -# - -builtin_110: slang_common_builtin_gc.h slang_core_gc.h slang_fragment_builtin_gc.h slang_vertex_builtin_gc.h - -builtin_120: slang_120_core_gc.h slang_builtin_120_common_gc.h slang_builtin_120_fragment_gc.h - - -slang_120_core_gc.h: slang_120_core.gc - $(GLSL_CL) fragment slang_120_core.gc slang_120_core_gc.h - -slang_builtin_120_common_gc.h: slang_builtin_120_common.gc - $(GLSL_CL) fragment slang_builtin_120_common.gc slang_builtin_120_common_gc.h - -slang_builtin_120_fragment_gc.h: slang_builtin_120_fragment.gc - $(GLSL_CL) fragment slang_builtin_120_fragment.gc slang_builtin_120_fragment_gc.h - -slang_common_builtin_gc.h: slang_common_builtin.gc - $(GLSL_CL) fragment slang_common_builtin.gc slang_common_builtin_gc.h - -slang_core_gc.h: slang_core.gc - $(GLSL_CL) fragment slang_core.gc slang_core_gc.h - -slang_fragment_builtin_gc.h: slang_fragment_builtin.gc - $(GLSL_CL) fragment slang_fragment_builtin.gc slang_fragment_builtin_gc.h - -slang_vertex_builtin_gc.h: slang_vertex_builtin.gc - $(GLSL_CL) vertex slang_vertex_builtin.gc slang_vertex_builtin_gc.h - diff --git a/mesalib/src/mesa/shader/slang/library/slang_120_core.gc b/mesalib/src/mesa/shader/slang/library/slang_120_core.gc deleted file mode 100644 index 04c5ec2ec..000000000 --- a/mesalib/src/mesa/shader/slang/library/slang_120_core.gc +++ /dev/null @@ -1,1978 +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. - */ - -// -// Constructors and operators introduced in GLSL 1.20 - mostly on new -// (non-square) types of matrices. -// -// One important change in the language is that when a matrix is used -// as an argument to a matrix constructor, it must be the only argument -// for the constructor. The compiler takes care of it by itself and -// here we only care to re-introduce constructors for old (square) -// types of matrices. -// - -// -// From Shader Spec, ver. 1.20, rev. 6 -// - -//// mat2x3: 2 columns of vec3 - -mat2x3 __constructor(const float f00, const float f10, const float f20, - const float f01, const float f11, const float f21) -{ - __retVal[0].x = f00; - __retVal[0].y = f10; - __retVal[0].z = f20; - __retVal[1].x = f01; - __retVal[1].y = f11; - __retVal[1].z = f21; -} - -mat2x3 __constructor(const float f) -{ - __retVal = mat2x3( f, 0.0, 0.0, - 0.0, f, 0.0); -} - -mat2x3 __constructor(const int i) -{ - const float f = float(i); - __retVal = mat2x3(f); -} - -mat2x3 __constructor(const bool b) -{ - const float f = float(b); - __retVal = mat2x3(f); -} - -mat2x3 __constructor(const vec3 c0, const vec3 c1) -{ - __retVal[0] = c0; - __retVal[1] = c1; -} - - - -//// mat2x4: 2 columns of vec4 - -mat2x4 __constructor(const float f00, const float f10, const float f20, const float f30, - const float f01, const float f11, const float f21, const float f31) -{ - __retVal[0].x = f00; - __retVal[0].y = f10; - __retVal[0].z = f20; - __retVal[0].w = f30; - __retVal[1].x = f01; - __retVal[1].y = f11; - __retVal[1].z = f21; - __retVal[1].w = f31; -} - -mat2x4 __constructor(const float f) -{ - __retVal = mat2x4( f, 0.0, 0.0, 0.0, - 0.0, f, 0.0, 0.0); -} - -mat2x4 __constructor(const int i) -{ - const float f = float(i); - __retVal = mat2x4(f); -} - -mat2x4 __constructor(const bool b) -{ - const float f = float(b); - __retVal = mat2x4(f); -} - -mat2x4 __constructor(const vec4 c0, const vec4 c1) -{ - __retVal[0] = c0; - __retVal[1] = c1; -} - - - -//// mat3x2: 3 columns of vec2 - -mat3x2 __constructor(const float f00, const float f10, - const float f01, const float f11, - const float f02, const float f12) -{ - __retVal[0].x = f00; - __retVal[0].y = f10; - __retVal[1].x = f01; - __retVal[1].y = f11; - __retVal[2].x = f02; - __retVal[2].y = f12; -} - -mat3x2 __constructor(const float f) -{ - __retVal = mat3x2( f, 0.0, - 0.0, f, - 0.0, 0.0); -} - -mat3x2 __constructor(const int i) -{ - const float f = float(i); - __retVal = mat3x2(f); -} - -mat3x2 __constructor(const bool b) -{ - const float f = float(b); - __retVal = mat3x2(f); -} - -mat3x2 __constructor(const vec2 c0, const vec2 c1, const vec2 c2) -{ - __retVal[0] = c0; - __retVal[1] = c1; - __retVal[2] = c2; -} - - - -//// mat3x4: 3 columns of vec4 - -mat3x4 __constructor(const float f00, const float f10, const float f20, const float f30, - const float f01, const float f11, const float f21, const float f31, - const float f02, const float f12, const float f22, const float f32) -{ - __retVal[0].x = f00; - __retVal[0].y = f10; - __retVal[0].z = f20; - __retVal[0].w = f30; - __retVal[1].x = f01; - __retVal[1].y = f11; - __retVal[1].z = f21; - __retVal[1].w = f31; - __retVal[2].x = f02; - __retVal[2].y = f12; - __retVal[2].z = f22; - __retVal[2].w = f32; -} - -mat3x4 __constructor(const float f) -{ - __retVal = mat3x4( f, 0.0, 0.0, 0.0, - 0.0, f, 0.0, 0.0, - 0.0, 0.0, f, 0.0); -} - -mat3x4 __constructor(const int i) -{ - const float f = float(i); - __retVal = mat3x4(f); -} - -mat3x4 __constructor(const bool b) -{ - const float f = float(b); - __retVal = mat3x4(f); -} - -mat3x4 __constructor(const vec4 c0, const vec4 c1, const vec4 c2) -{ - __retVal[0] = c0; - __retVal[1] = c1; - __retVal[2] = c2; -} - - - -//// mat4x2: 4 columns of vec2 - -mat4x2 __constructor(const float f00, const float f10, - const float f01, const float f11, - const float f02, const float f12, - const float f03, const float f13) -{ - __retVal[0].x = f00; - __retVal[0].y = f10; - __retVal[1].x = f01; - __retVal[1].y = f11; - __retVal[2].x = f02; - __retVal[2].y = f12; - __retVal[3].x = f03; - __retVal[3].y = f13; -} - -mat4x2 __constructor(const float f) -{ - __retVal = mat4x2( f, 0.0, - 0.0, 4, - 0.0, 0.0, - 0.0, 0.0); -} - -mat4x2 __constructor(const int i) -{ - const float f = float(i); - __retVal = mat4x2(f); -} - -mat4x2 __constructor(const bool b) -{ - const float f = float(b); - __retVal = mat4x2(f); -} - -mat4x2 __constructor(const vec2 c0, const vec2 c1, const vec2 c2, const vec2 c3) -{ - __retVal[0] = c0; - __retVal[1] = c1; - __retVal[2] = c2; - __retVal[3] = c3; -} - - - -//// mat4x3: 4 columns of vec3 - -mat4x3 __constructor(const float f00, const float f10, const float f20, - const float f01, const float f11, const float f21, - const float f02, const float f12, const float f22, - const float f03, const float f13, const float f23) -{ - __retVal[0].x = f00; - __retVal[0].y = f10; - __retVal[0].z = f20; - __retVal[1].x = f01; - __retVal[1].y = f11; - __retVal[1].z = f21; - __retVal[2].x = f02; - __retVal[2].y = f12; - __retVal[2].z = f22; - __retVal[3].x = f03; - __retVal[3].y = f13; - __retVal[3].z = f23; -} - -mat4x3 __constructor(const float f) -{ - __retVal = mat4x3( f, 0.0, 0.0, - 0.0, f, 0.0, - 0.0, 0.0, f, - 0.0, 0.0, 0.0); -} - -mat4x3 __constructor(const int i) -{ - const float f = float(i); - __retVal = mat4x3(f); -} - -mat4x3 __constructor(const bool b) -{ - const float f = float(b); - __retVal = mat4x3(f); -} - -mat4x3 __constructor(const vec3 c0, const vec3 c1, const vec3 c2, const vec3 c3) -{ - __retVal[0] = c0; - __retVal[1] = c1; - __retVal[2] = c2; - __retVal[3] = c3; -} - - - -//// misc assorted matrix constructors - -mat2 __constructor(const mat2 m) -{ - __retVal = m; -} - -mat2 __constructor(const mat3x2 m) -{ - __retVal = mat2(m[0], m[1]); -} - -mat2 __constructor(const mat4x2 m) -{ - __retVal = mat2(m[0], m[1]); -} - -mat2 __constructor(const mat2x3 m) -{ - __retVal = mat2(m[0].xy, m[1].xy); -} - -mat2 __constructor(const mat2x4 m) -{ - __retVal = mat2(m[0].xy, m[1].xy); -} - -mat2 __constructor(const mat3 m) -{ - __retVal = mat2(m[0].xy, m[1].xy); -} - -mat2 __constructor(const mat3x4 m) -{ - __retVal = mat2(m[0].xy, m[1].xy); -} - -mat2 __constructor(const mat4x3 m) -{ - __retVal = mat2(m[0].xy, m[1].xy); -} - -mat2 __constructor(const mat4 m) -{ - __retVal = mat2(m[0].xy, m[1].xy); -} - - - -mat2x3 __constructor(const mat2x3 m) -{ - __retVal = m; -} - -mat2x3 __constructor(const mat3 m) -{ - __retVal = mat2x3(m[0], m[1]); -} - -mat2x3 __constructor(const mat4x3 m) -{ - __retVal = mat2x3(m[0], m[1]); -} - -mat2x3 __constructor(const mat2x4 m) -{ - __retVal = mat2x3(m[0].xyz, m[1].xyz); -} - -mat2x3 __constructor(const mat3x4 m) -{ - __retVal = mat2x3(m[0].xyz, m[1].xyz); -} - -mat2x3 __constructor(const mat4 m) -{ - __retVal = mat2x3(m[0].xyz, m[1].xyz); -} - -mat2x3 __constructor(const mat2 m) -{ - __retVal = mat2x3(m[0].x, m[0].y, 0.0, - m[1].x, m[1].y, 0.0); -} - -mat2x3 __constructor(const mat3x2 m) -{ - __retVal = mat2x3(m[0].x, m[0].y, 0.0, - m[1].x, m[1].y, 0.0); -} - -mat2x3 __constructor(const mat4x2 m) -{ - __retVal = mat2x3(m[0].x, m[0].y, 0.0, - m[1].x, m[1].y, 0.0); -} - - - -mat2x4 __constructor(const mat2x4 m) -{ - __retVal = m; -} - -mat2x4 __constructor(const mat3x4 m) -{ - __retVal = mat2x4(m[0], m[1]); -} - -mat2x4 __constructor(const mat4 m) -{ - __retVal = mat2x4(m[0], m[1]); -} - -mat2x4 __constructor(const mat2x3 m) -{ - __retVal = mat2x4(m[0].x, m[0].y, m[0].z, 0.0, - m[1].x, m[1].y, m[1].z, 0.0); -} - -mat2x4 __constructor(const mat3 m) -{ - __retVal = mat2x4(m[0].x, m[0].y, m[0].z, 0.0, - m[1].x, m[1].y, m[1].z, 0.0); -} - -mat2x4 __constructor(const mat4x3 m) -{ - __retVal = mat2x4(m[0].x, m[0].y, m[0].z, 0.0, - m[1].x, m[1].y, m[1].z, 0.0); -} - -mat2x4 __constructor(const mat2 m) -{ - __retVal = mat2x4(m[0].x, m[1].y, 0.0, 0.0, - m[1].x, m[1].y, 0.0, 0.0); -} - -mat2x4 __constructor(const mat3x2 m) -{ - __retVal = mat2x4(m[0].x, m[0].y, 0.0, 0.0, - m[1].x, m[1].y, 0.0, 0.0); -} - -mat2x4 __constructor(const mat4x2 m) -{ - __retVal = mat2x4(m[0].x, m[0].y, 0.0, 0.0, - m[1].x, m[1].y, 0.0, 0.0); -} - - - -mat3x2 __constructor(const mat3x2 m) -{ - __retVal = m; -} - -mat3x2 __constructor(const mat4x2 m) -{ - __retVal = mat3x2(m[0], m[1], m[2]); -} - -mat3x2 __constructor(const mat3 m) -{ - __retVal = mat3x2(m[0], m[1], m[2]); -} - -mat3x2 __constructor(const mat3x4 m) -{ - __retVal = mat3x2(m[0].x, m[0].y, - m[1].x, m[1].y, - m[2].x, m[2].y); -} - -mat3x2 __constructor(const mat4x3 m) -{ - __retVal = mat3x2(m[0].x, m[0].y, - m[1].x, m[1].y, - m[2].x, m[2].y); -} - -mat3x2 __constructor(const mat4 m) -{ - __retVal = mat3x2(m[0].x, m[0].y, - m[1].x, m[1].y, - 0.0, 0.0); -} - -mat3x2 __constructor(const mat2 m) -{ - __retVal = mat3x2(m[0], m[1], vec2(0.0)); -} - -mat3x2 __constructor(const mat2x3 m) -{ - __retVal = mat3x2(m[0].x, m[0].y, - m[1].x, m[1].y, - 0.0, 0.0); -} - -mat3x2 __constructor(const mat2x4 m) -{ - __retVal = mat3x2(m[0].x, m[0].y, - m[1].x, m[1].y, - 0.0, 0.0); -} - - - - -mat3 __constructor(const mat3 m) -{ - __retVal = m; -} - -mat3 __constructor(const mat4x3 m) -{ - __retVal = mat3 ( - m[0], - m[1], - m[2] - ); -} - -mat3 __constructor(const mat3x4 m) -{ - __retVal = mat3 ( - m[0].xyz, - m[1].xyz, - m[2].xyz - ); -} - -mat3 __constructor(const mat4 m) -{ - __retVal = mat3 ( - m[0].xyz, - m[1].xyz, - m[2].xyz - ); -} - -mat3 __constructor(const mat2x3 m) -{ - __retVal = mat3 ( - m[0], - m[1], - 0., 0., 1. - ); -} - -mat3 __constructor(const mat2x4 m) -{ - __retVal = mat3 ( - m[0].xyz, - m[1].xyz, - 0., 0., 1. - ); -} - -mat3 __constructor(const mat3x2 m) -{ - __retVal = mat3 ( - m[0], 0., - m[1], 0., - m[2], 1. - ); -} - -mat3 __constructor(const mat4x2 m) -{ - __retVal = mat3 ( - m[0], 0., - m[1], 0., - m[2], 1. - ); -} - -mat3 __constructor(const mat2 m) -{ - __retVal = mat3 ( - m[0], 0., - m[1], 0., - 0., 0., 1. - ); -} - - -mat3x4 __constructor(const mat3x4 m) -{ - __retVal = m; -} - -mat3x4 __constructor(const mat4 m) -{ - __retVal = mat3x4 ( - m[0], - m[1], - m[2] - ); -} - -mat3x4 __constructor(const mat3 m) -{ - __retVal = mat3x4 ( - m[0], 0., - m[1], 0., - m[2], 0. - ); -} - -mat3x4 __constructor(const mat4x3 m) -{ - __retVal = mat3x4 ( - m[0], 0., - m[1], 0., - m[2], 0. - ); -} - -mat3x4 __constructor(const mat2x4 m) -{ - __retVal = mat3x4 ( - m[0], - m[1], - 0., 0., 1., 0. - ); -} - -mat3x4 __constructor(const mat2x3 m) -{ - __retVal = mat3x4 ( - m[0], 0., - m[1], 0., - 0., 0., 1., 0. - ); -} - -mat3x4 __constructor(const mat3x2 m) -{ - __retVal = mat3x4 ( - m[0], 0., 0., - m[1], 0., 0., - m[2], 1., 0. - ); -} - -mat3x4 __constructor(const mat4x2 m) -{ - __retVal = mat3x4 ( - m[0], 0., 0., - m[1], 0., 0., - m[2], 1., 0. - ); -} - -mat3x4 __constructor(const mat2 m) -{ - __retVal = mat3x4 ( - m[0], 0., 0., - m[1], 0., 0., - 0., 0., 1., 0. - ); -} - - -mat4x2 __constructor(const mat4x2 m) -{ - __retVal = m; -} - -mat4x2 __constructor(const mat4x3 m) -{ - __retVal = mat4x2 ( - m[0].xy, - m[1].xy, - m[2].xy, - m[3].xy - ); -} - -mat4x2 __constructor(const mat4 m) -{ - __retVal = mat4x2 ( - m[0].xy, - m[1].xy, - m[2].xy, - m[3].xy - ); -} - -mat4x2 __constructor(const mat3x2 m) -{ - __retVal = mat4x2 ( - m[0], - m[1], - 0., 0. - ); -} - -mat4x2 __constructor(const mat3 m) -{ - __retVal = mat4x2 ( - m[0].xy, - m[1].xy, - m[2].xy, - 0., 0. - ); -} - -mat4x2 __constructor(const mat3x4 m) -{ - __retVal = mat4x2 ( - m[0].xy, - m[1].xy, - m[2].xy, - 0., 0. - ); -} - -mat4x2 __constructor(const mat2 m) -{ - __retVal = mat4x2 ( - m[0], - m[1], - 0., 0., - 0., 0. - ); -} - -mat4x2 __constructor(const mat2x3 m) -{ - __retVal = mat4x2 ( - m[0].xy, - m[1].xy, - 0., 0., - 0., 0. - ); -} - -mat4x2 __constructor(const mat2x4 m) -{ - __retVal = mat4x2 ( - m[0].xy, - m[1].xy, - 0., 0., - 0., 0. - ); -} - - -mat4x3 __constructor(const mat4x3 m) -{ - __retVal = m; -} - -mat4x3 __constructor(const mat4 m) -{ - __retVal = mat4x3 ( - m[0].xyz, - m[1].xyz, - m[2].xyz, - m[3].xyz - ); -} - -mat4x3 __constructor(const mat3 m) -{ - __retVal = mat4x3 ( - m[0], - m[1], - m[2], - 0., 0., 0. - ); -} - -mat4x3 __constructor(const mat3x4 m) -{ - __retVal = mat4x3 ( - m[0].xyz, - m[1].xyz, - m[2].xyz, - 0., 0., 0. - ); -} - -mat4x3 __constructor(const mat4x2 m) -{ - __retVal = mat4x3 ( - m[0], 0., - m[1], 0., - m[2], 1., - m[3], 0. - ); -} - -mat4x3 __constructor(const mat2x3 m) -{ - __retVal = mat4x3 ( - m[0], - m[1], - 0., 0., 1., - 0., 0., 0. - ); -} - -mat4x3 __constructor(const mat3x2 m) -{ - __retVal = mat4x3 ( - m[0], 0., - m[1], 0., - m[2], 1., - 0., 0., 0. - ); -} - -mat4x3 __constructor(const mat2x4 m) -{ - __retVal = mat4x3 ( - m[0].xyz, - m[1].xyz, - 0., 0., 1., - 0., 0., 0. - ); -} - -mat4x3 __constructor(const mat2 m) -{ - __retVal = mat4x3 ( - m[0], 0., - m[1], 0., - 0., 0., 1., - 0., 0., 0. - ); -} - - -mat4 __constructor(const mat4 m) -{ - __retVal = m; -} - -mat4 __constructor(const mat3x4 m) -{ - __retVal = mat4 ( - m[0], - m[1], - m[2], - 0., 0., 0., 1. - ); -} - -mat4 __constructor(const mat4x3 m) -{ - __retVal = mat4 ( - m[0], 0., - m[1], 0., - m[2], 0., - m[3], 1. - ); -} - -mat4 __constructor(const mat2x4 m) -{ - __retVal = mat4 ( - m[0], - m[1], - 0., 0., 1., 0., - 0., 0., 0., 1. - ); -} - -mat4 __constructor(const mat4x2 m) -{ - __retVal = mat4 ( - m[0], 0., 0., - m[1], 0., 0., - m[2], 1., 0., - m[3], 0., 1. - ); -} - -mat4 __constructor(const mat3 m) -{ - __retVal = mat4 ( - m[0], 0., - m[1], 0., - m[2], 0., - 0., 0., 0., 1. - ); -} - -mat4 __constructor(const mat2x3 m) -{ - __retVal = mat4 ( - m[0], 0., - m[1], 0., - 0., 0., 1., 0., - 0., 0., 0., 1. - ); -} - -mat4 __constructor(const mat3x2 m) -{ - __retVal = mat4 ( - m[0], 0., 0., - m[1], 0., 0., - m[2], 1., 0., - 0., 0., 0., 1. - ); -} - -mat4 __constructor(const mat2 m) -{ - __retVal = mat4 ( - m[0], 0., 0., - m[1], 0., 0., - 0., 0., 1., 0., - 0., 0., 0., 1. - ); -} - - -void __operator += (inout mat2x3 m, const mat2x3 n) { - m[0] += n[0]; - m[1] += n[1]; -} - -void __operator += (inout mat2x4 m, const mat2x4 n) { - m[0] += n[0]; - m[1] += n[1]; -} - -void __operator += (inout mat3x2 m, const mat3x2 n) { - m[0] += n[0]; - m[1] += n[1]; - m[2] += n[2]; -} - -void __operator += (inout mat3x4 m, const mat3x4 n) { - m[0] += n[0]; - m[1] += n[1]; - m[2] += n[2]; -} - -void __operator += (inout mat4x2 m, const mat4x2 n) { - m[0] += n[0]; - m[1] += n[1]; - m[2] += n[2]; - m[3] += n[3]; -} - -void __operator += (inout mat4x3 m, const mat4x3 n) { - m[0] += n[0]; - m[1] += n[1]; - m[2] += n[2]; - m[3] += n[3]; -} - - -void __operator -= (inout mat2x3 m, const mat2x3 n) { - m[0] -= n[0]; - m[1] -= n[1]; -} - -void __operator -= (inout mat2x4 m, const mat2x4 n) { - m[0] -= n[0]; - m[1] -= n[1]; -} - -void __operator -= (inout mat3x2 m, const mat3x2 n) { - m[0] -= n[0]; - m[1] -= n[1]; - m[2] -= n[2]; -} - -void __operator -= (inout mat3x4 m, const mat3x4 n) { - m[0] -= n[0]; - m[1] -= n[1]; - m[2] -= n[2]; -} - -void __operator -= (inout mat4x2 m, const mat4x2 n) { - m[0] -= n[0]; - m[1] -= n[1]; - m[2] -= n[2]; - m[3] -= n[3]; -} - -void __operator -= (inout mat4x3 m, const mat4x3 n) { - m[0] -= n[0]; - m[1] -= n[1]; - m[2] -= n[2]; - m[3] -= n[3]; -} - - -void __operator /= (inout mat2x3 m, const mat2x3 n) { - m[0] /= n[0]; - m[1] /= n[1]; -} - -void __operator /= (inout mat2x4 m, const mat2x4 n) { - m[0] /= n[0]; - m[1] /= n[1]; -} - -void __operator /= (inout mat3x2 m, const mat3x2 n) { - m[0] /= n[0]; - m[1] /= n[1]; - m[2] /= n[2]; -} - -void __operator /= (inout mat3x4 m, const mat3x4 n) { - m[0] /= n[0]; - m[1] /= n[1]; - m[2] /= n[2]; -} - -void __operator /= (inout mat4x2 m, const mat4x2 n) { - m[0] /= n[0]; - m[1] /= n[1]; - m[2] /= n[2]; - m[3] /= n[3]; -} - -void __operator /= (inout mat4x3 m, const mat4x3 n) { - m[0] /= n[0]; - m[1] /= n[1]; - m[2] /= n[2]; - m[3] /= n[3]; -} - - -vec3 __operator * (const mat2x3 m, const vec2 v) -{ - __retVal.x = v.x * m[0].x + v.y * m[1].x; - __retVal.y = v.x * m[0].y + v.y * m[1].y; - __retVal.z = v.x * m[0].z + v.y * m[1].z; -} - -vec4 __operator * (const mat2x4 m, const vec2 v) -{ - __retVal.x = v.x * m[0].x + v.y * m[1].x; - __retVal.y = v.x * m[0].y + v.y * m[1].y; - __retVal.z = v.x * m[0].z + v.y * m[1].z; - __retVal.w = v.x * m[0].w + v.y * m[1].w; -} - -vec2 __operator * (const mat3x2 m, const vec3 v) -{ - __retVal.x = v.x * m[0].x + v.y * m[1].x + v.z * m[2].x; - __retVal.y = v.x * m[0].y + v.y * m[1].y + v.z * m[2].y; -} - -vec4 __operator * (const mat3x4 m, const vec3 v) -{ - __retVal.x = v.x * m[0].x + v.y * m[1].x + v.z * m[2].x; - __retVal.y = v.x * m[0].y + v.y * m[1].y + v.z * m[2].y; - __retVal.z = v.x * m[0].z + v.y * m[1].z + v.z * m[2].z; - __retVal.w = v.x * m[0].w + v.y * m[1].w + v.z * m[2].w; -} - -vec2 __operator * (const mat4x2 m, const vec4 v) -{ - __retVal.x = v.x * m[0].x + v.y * m[1].x + v.z * m[2].x + v.w * m[3].x; - __retVal.y = v.x * m[0].y + v.y * m[1].y + v.z * m[2].y + v.w * m[3].y; -} - -vec3 __operator * (const mat4x3 m, const vec4 v) -{ - __retVal.x = v.x * m[0].x + v.y * m[1].x + v.z * m[2].x + v.w * m[3].x; - __retVal.y = v.x * m[0].y + v.y * m[1].y + v.z * m[2].y + v.w * m[3].y; - __retVal.z = v.x * m[0].z + v.y * m[1].z + v.z * m[2].z + v.w * m[3].z; -} - - -mat3x2 __operator * (const mat2 m, const mat3x2 n) -{ - //return mat3x2 (m * n[0], m * n[1], m * n[2]); - __retVal[0] = m * n[0]; - __retVal[1] = m * n[1]; - __retVal[2] = m * n[2]; -} - -mat4x2 __operator * (const mat2 m, const mat4x2 n) -{ - //return mat4x2 (m * n[0], m * n[1], m * n[2], m * n[3]); - __retVal[0] = m * n[0]; - __retVal[1] = m * n[1]; - __retVal[2] = m * n[2]; - __retVal[3] = m * n[3]; -} - - -mat2x3 __operator * (const mat2x3 m, const mat2 n) -{ - //return mat2x3 (m * n[0], m * n[1]); - __retVal[0] = m * n[0]; - __retVal[1] = m * n[1]; -} - -mat3 __operator * (const mat2x3 m, const mat3x2 n) -{ - //return mat3 (m * n[0], m * n[1], m * n[2]); - __retVal[0] = m * n[0]; - __retVal[1] = m * n[1]; - __retVal[2] = m * n[2]; -} - -mat4x3 __operator * (const mat2x3 m, const mat4x2 n) -{ - //return mat4x3 (m * n[0], m * n[1], m * n[2], m * n[3]); - __retVal[0] = m * n[0]; - __retVal[1] = m * n[1]; - __retVal[2] = m * n[2]; - __retVal[3] = m * n[3]; -} - - -mat2x4 __operator * (const mat2x4 m, const mat2 n) -{ - //return mat2x4 (m * n[0], m * n[1]); - __retVal[0] = m * n[0]; - __retVal[1] = m * n[1]; -} - -mat3x4 __operator * (const mat2x4 m, const mat3x2 n) -{ - //return mat3x4 (m * n[0], m * n[1], m * n[2]); - __retVal[0] = m * n[0]; - __retVal[1] = m * n[1]; - __retVal[2] = m * n[2]; -} - -mat4 __operator * (const mat2x4 m, const mat4x2 n) -{ - //return mat4 (m * n[0], m * n[1], m * n[2], m * n[3]); - __retVal[0] = m * n[0]; - __retVal[1] = m * n[1]; - __retVal[2] = m * n[2]; - __retVal[3] = m * n[3]; -} - - -mat2 __operator * (const mat3x2 m, const mat2x3 n) -{ - //return mat2 (m * n[0], m * n[1]); - __retVal[0] = m * n[0]; - __retVal[1] = m * n[1]; -} - -mat3x2 __operator * (const mat3x2 m, const mat3 n) -{ - //return mat3x2 (m * n[0], m * n[1], m * n[2]); - __retVal[0] = m * n[0]; - __retVal[1] = m * n[1]; - __retVal[2] = m * n[2]; -} - -mat4x2 __operator * (const mat3x2 m, const mat4x3 n) -{ - //return mat4x2 (m * n[0], m * n[1], m * n[2], m * n[3]); - __retVal[0] = m * n[0]; - __retVal[1] = m * n[1]; - __retVal[2] = m * n[2]; - __retVal[3] = m * n[3]; -} - - -mat2x3 __operator * (const mat3 m, const mat2x3 n) -{ - //return mat2x3 (m * n[0], m * n[1]); - __retVal[0] = m * n[0]; - __retVal[1] = m * n[1]; -} - -mat4x3 __operator * (const mat3 m, const mat4x3 n) -{ - //return mat4x3 (m * n[0], m * n[1], m * n[2], m * n[3]); - __retVal[0] = m * n[0]; - __retVal[1] = m * n[1]; - __retVal[2] = m * n[2]; - __retVal[3] = m * n[3]; -} - - -mat2x4 __operator * (const mat3x4 m, const mat2x3 n) -{ - //return mat2x4 (m * n[0], m * n[1]); - __retVal[0] = m * n[0]; - __retVal[1] = m * n[1]; -} - -mat3x4 __operator * (const mat3x4 m, const mat3 n) -{ - //return mat3x4 (m * n[0], m * n[1], m * n[2]); - __retVal[0] = m * n[0]; - __retVal[1] = m * n[1]; - __retVal[2] = m * n[2]; -} - -mat4 __operator * (const mat3x4 m, const mat4x3 n) -{ - //return mat4 (m * n[0], m * n[1], m * n[2], m * n[3]); - __retVal[0] = m * n[0]; - __retVal[1] = m * n[1]; - __retVal[2] = m * n[2]; - __retVal[3] = m * n[3]; -} - - -mat2 __operator * (const mat4x2 m, const mat2x4 n) -{ - //return = mat2 (m * n[0], m * n[1]); - __retVal[0] = m * n[0]; - __retVal[1] = m * n[1]; -} - -mat3x2 __operator * (const mat4x2 m, const mat3x4 n) -{ - //return mat3x2 (m * n[0], m * n[1], m * n[2]); - __retVal[0] = m * n[0]; - __retVal[1] = m * n[1]; - __retVal[2] = m * n[2]; -} - -mat4x2 __operator * (const mat4x2 m, const mat4 n) -{ - //return mat4x2 (m * n[0], m * n[1], m * n[2], m * n[3]); - __retVal[0] = m * n[0]; - __retVal[1] = m * n[1]; - __retVal[2] = m * n[2]; - __retVal[3] = m * n[3]; -} - - -mat2x3 __operator * (const mat4x3 m, const mat2x4 n) -{ - //return mat2x3 (m * n[0], m * n[1]); - __retVal[0] = m * n[0]; - __retVal[1] = m * n[1]; -} - -mat3 __operator * (const mat4x3 m, const mat3x4 n) -{ - //return mat3 (m * n[0], m * n[1], m * n[2]); - __retVal[0] = m * n[0]; - __retVal[1] = m * n[1]; - __retVal[2] = m * n[2]; -} - -mat4x3 __operator * (const mat4x3 m, const mat4 n) -{ - //return mat4x3 (m * n[0], m * n[1], m * n[2], m * n[3]); - __retVal[0] = m * n[0]; - __retVal[1] = m * n[1]; - __retVal[2] = m * n[2]; - __retVal[3] = m * n[3]; -} - - -mat2x4 __operator * (const mat4 m, const mat2x4 n) -{ - //return mat2x4 (m * n[0], m * n[1]); - __retVal[0] = m * n[0]; - __retVal[1] = m * n[1]; -} - -mat3x4 __operator * (const mat4 m, const mat3x4 n) -{ - //return mat3x4 (m * n[0], m * n[1], m * n[2]); - __retVal[0] = m * n[0]; - __retVal[1] = m * n[1]; - __retVal[2] = m * n[2]; -} - - -void __operator *= (inout mat2x3 m, const mat2 n) { - m = m * n; -} - -void __operator *= (inout mat2x4 m, const mat2 n) { - m = m * n; -} - -void __operator *= (inout mat3x2 m, const mat3 n) { - m = m * n; -} - -void __operator *= (inout mat3x4 m, const mat3 n) { - m = m * n; -} - -void __operator *= (inout mat4x2 m, const mat4 n) { - m = m * n; -} - -void __operator *= (inout mat4x3 m, const mat4 n) { - m = m * n; -} - - -vec3 __operator * (const vec2 v, const mat3x2 m) -{ - __retVal.x = dot(v, m[0]); - __retVal.y = dot(v, m[1]); - __retVal.z = dot(v, m[2]); -} - -vec4 __operator * (const vec2 v, const mat4x2 m) -{ - __retVal.x = dot(v, m[0]); - __retVal.y = dot(v, m[1]); - __retVal.z = dot(v, m[2]); - __retVal.w = dot(v, m[3]); -} - -vec2 __operator * (const vec3 v, const mat2x3 m) -{ - __retVal.x = dot(v, m[0]); - __retVal.y = dot(v, m[1]); -} - -vec4 __operator * (const vec3 v, const mat4x3 m) -{ - __retVal.x = dot(v, m[0]); - __retVal.y = dot(v, m[1]); - __retVal.z = dot(v, m[2]); - __retVal.w = dot(v, m[3]); -} - -vec2 __operator * (const vec4 v, const mat2x4 m) -{ - __retVal.x = dot(v, m[0]); - __retVal.y = dot(v, m[1]); -} - -vec3 __operator * (const vec4 v, const mat3x4 m) -{ - __retVal.x = dot(v, m[0]); - __retVal.y = dot(v, m[1]); - __retVal.z = dot(v, m[2]); -} - - -void __operator += (inout mat2x3 m, const float a) { - m[0] += a; - m[1] += a; -} - -void __operator += (inout mat2x4 m, const float a) { - m[0] += a; - m[1] += a; -} - -void __operator += (inout mat3x2 m, const float a) { - m[0] += a; - m[1] += a; - m[2] += a; -} - -void __operator += (inout mat3x4 m, const float a) { - m[0] += a; - m[1] += a; - m[2] += a; -} - -void __operator += (inout mat4x2 m, const float a) { - m[0] += a; - m[1] += a; - m[2] += a; - m[3] += a; -} - -void __operator += (inout mat4x3 m, const float a) { - m[0] += a; - m[1] += a; - m[2] += a; - m[3] += a; -} - - -void __operator -= (inout mat2x3 m, const float a) { - m[0] -= a; - m[1] -= a; -} - -void __operator -= (inout mat2x4 m, const float a) { - m[0] -= a; - m[1] -= a; -} - -void __operator -= (inout mat3x2 m, const float a) { - m[0] -= a; - m[1] -= a; - m[2] -= a; -} - -void __operator -= (inout mat3x4 m, const float a) { - m[0] -= a; - m[1] -= a; - m[2] -= a; -} - -void __operator -= (inout mat4x2 m, const float a) { - m[0] -= a; - m[1] -= a; - m[2] -= a; - m[3] -= a; -} - -void __operator -= (inout mat4x3 m, const float a) { - m[0] -= a; - m[1] -= a; - m[2] -= a; - m[3] -= a; -} - - -void __operator *= (inout mat2x3 m, const float a) { - m[0] *= a; - m[1] *= a; -} - -void __operator *= (inout mat2x4 m, const float a) { - m[0] *= a; - m[1] *= a; -} - -void __operator *= (inout mat3x2 m, const float a) { - m[0] *= a; - m[1] *= a; - m[2] *= a; -} - -void __operator *= (inout mat3x4 m, const float a) { - m[0] *= a; - m[1] *= a; - m[2] *= a; -} - -void __operator *= (inout mat4x2 m, const float a) { - m[0] *= a; - m[1] *= a; - m[2] *= a; - m[3] *= a; -} - -void __operator *= (inout mat4x3 m, const float a) { - m[0] *= a; - m[1] *= a; - m[2] *= a; - m[3] *= a; -} - - -void __operator /= (inout mat2x3 m, const float a) { - m[0] /= a; - m[1] /= a; -} - -void __operator /= (inout mat2x4 m, const float a) { - m[0] /= a; - m[1] /= a; -} - -void __operator /= (inout mat3x2 m, const float a) { - m[0] /= a; - m[1] /= a; - m[2] /= a; -} - -void __operator /= (inout mat3x4 m, const float a) { - m[0] /= a; - m[1] /= a; - m[2] /= a; -} - -void __operator /= (inout mat4x2 m, const float a) { - m[0] /= a; - m[1] /= a; - m[2] /= a; - m[3] /= a; -} - -void __operator /= (inout mat4x3 m, const float a) { - m[0] /= a; - m[1] /= a; - m[2] /= a; - m[3] /= a; -} - - -mat2x3 __operator + (const mat2x3 m, const mat2x3 n) { - return mat2x3 (m[0] + n[0], m[1] + n[1]); -} - -mat2x4 __operator + (const mat2x4 m, const mat2x4 n) { - return mat2x4 (m[0] + n[0], m[1] + n[1]); -} - -mat3x2 __operator + (const mat3x2 m, const mat3x2 n) { - return mat3x2 (m[0] + n[0], m[1] + n[1], m[2] + n[2]); -} - -mat3x4 __operator + (const mat3x4 m, const mat3x4 n) { - return mat3x4 (m[0] + n[0], m[1] + n[1], m[2] + n[2]); -} - -mat4x2 __operator + (const mat4x2 m, const mat4x2 n) { - return mat4x2 (m[0] + n[0], m[1] + n[1], m[2] + n[2], m[3] + n[3]); -} - -mat4x3 __operator + (const mat4x3 m, const mat4x3 n) { - return mat4x3 (m[0] + n[0], m[1] + n[1], m[2] + n[2], m[3] + n[3]); -} - - -mat2x3 __operator - (const mat2x3 m, const mat2x3 n) { - return mat2x3 (m[0] - n[0], m[1] - n[1]); -} - -mat2x4 __operator - (const mat2x4 m, const mat2x4 n) { - return mat2x4 (m[0] - n[0], m[1] - n[1]); -} - -mat3x2 __operator - (const mat3x2 m, const mat3x2 n) { - return mat3x2 (m[0] - n[0], m[1] - n[1], m[2] - n[2]); -} - -mat3x4 __operator - (const mat3x4 m, const mat3x4 n) { - return mat3x4 (m[0] - n[0], m[1] - n[1], m[2] - n[2]); -} - -mat4x2 __operator - (const mat4x2 m, const mat4x2 n) { - return mat4x2 (m[0] - n[0], m[1] - n[1], m[2] - n[2], m[3] - n[3]); -} - -mat4x3 __operator - (const mat4x3 m, const mat4x3 n) { - return mat4x3 (m[0] - n[0], m[1] - n[1], m[2] - n[2], m[3] - n[3]); -} - - -mat2x3 __operator / (const mat2x3 m, const mat2x3 n) { - return mat2x3 (m[0] / n[0], m[1] / n[1]); -} - -mat2x4 __operator / (const mat2x4 m, const mat2x4 n) { - return mat2x4 (m[0] / n[0], m[1] / n[1]); -} - -mat3x2 __operator / (const mat3x2 m, const mat3x2 n) { - return mat3x2 (m[0] / n[0], m[1] / n[1], m[2] / n[2]); -} - -mat3x4 __operator / (const mat3x4 m, const mat3x4 n) { - return mat3x4 (m[0] / n[0], m[1] / n[1], m[2] / n[2]); -} - -mat4x2 __operator / (const mat4x2 m, const mat4x2 n) { - return mat4x2 (m[0] / n[0], m[1] / n[1], m[2] / n[2], m[3] / n[3]); -} - -mat4x3 __operator / (const mat4x3 m, const mat4x3 n) { - return mat4x3 (m[0] / n[0], m[1] / n[1], m[2] / n[2], m[3] / n[3]); -} - - -mat2x3 __operator + (const float a, const mat2x3 n) { - return mat2x3 (a + n[0], a + n[1]); -} - -mat2x3 __operator + (const mat2x3 m, const float b) { - return mat2x3 (m[0] + b, m[1] + b); -} - -mat2x4 __operator + (const float a, const mat2x4 n) { - return mat2x4 (a + n[0], a + n[1]); -} - -mat2x4 __operator + (const mat2x4 m, const float b) { - return mat2x4 (m[0] + b, m[1] + b); -} - -mat3x2 __operator + (const float a, const mat3x2 n) { - return mat3x2 (a + n[0], a + n[1], a + n[2]); -} - -mat3x2 __operator + (const mat3x2 m, const float b) { - return mat3x2 (m[0] + b, m[1] + b, m[2] + b); -} - -mat3x4 __operator + (const float a, const mat3x4 n) { - return mat3x4 (a + n[0], a + n[1], a + n[2]); -} - -mat3x4 __operator + (const mat3x4 m, const float b) { - return mat3x4 (m[0] + b, m[1] + b, m[2] + b); -} - -mat4x2 __operator + (const mat4x2 m, const float b) { - return mat4x2 (m[0] + b, m[1] + b, m[2] + b, m[3] + b); -} - -mat4x2 __operator + (const float a, const mat4x2 n) { - return mat4x2 (a + n[0], a + n[1], a + n[2], a + n[3]); -} - -mat4x3 __operator + (const mat4x3 m, const float b) { - return mat4x3 (m[0] + b, m[1] + b, m[2] + b, m[3] + b); -} - -mat4x3 __operator + (const float a, const mat4x3 n) { - return mat4x3 (a + n[0], a + n[1], a + n[2], a + n[3]); -} - - -mat2x3 __operator - (const float a, const mat2x3 n) { - return mat2x3 (a - n[0], a - n[1]); -} - -mat2x3 __operator - (const mat2x3 m, const float b) { - return mat2x3 (m[0] - b, m[1] - b); -} - -mat2x4 __operator - (const float a, const mat2x4 n) { - return mat2x4 (a - n[0], a - n[1]); -} - -mat2x4 __operator - (const mat2x4 m, const float b) { - return mat2x4 (m[0] - b, m[1] - b); -} - -mat3x2 __operator - (const float a, const mat3x2 n) { - return mat3x2 (a - n[0], a - n[1], a - n[2]); -} - -mat3x2 __operator - (const mat3x2 m, const float b) { - return mat3x2 (m[0] - b, m[1] - b, m[2] - b); -} - -mat3x4 __operator - (const float a, const mat3x4 n) { - return mat3x4 (a - n[0], a - n[1], a - n[2]); -} - -mat3x4 __operator - (const mat3x4 m, const float b) { - return mat3x4 (m[0] - b, m[1] - b, m[2] - b); -} - -mat4x2 __operator - (const mat4x2 m, const float b) { - return mat4x2 (m[0] - b, m[1] - b, m[2] - b, m[3] - b); -} - -mat4x2 __operator - (const float a, const mat4x2 n) { - return mat4x2 (a - n[0], a - n[1], a - n[2], a - n[3]); -} - -mat4x3 __operator - (const mat4x3 m, const float b) { - return mat4x3 (m[0] - b, m[1] - b, m[2] - b, m[3] - b); -} - -mat4x3 __operator - (const float a, const mat4x3 n) { - return mat4x3 (a - n[0], a - n[1], a - n[2], a - n[3]); -} - - -mat2x3 __operator * (const float a, const mat2x3 n) -{ - //return mat2x3 (a * n[0], a * n[1]); - __retVal[0] = a * n[0]; - __retVal[1] = a * n[1]; -} - -mat2x3 __operator * (const mat2x3 m, const float b) -{ - //return mat2x3 (m[0] * b, m[1] * b); - __retVal[0] = m[0] * b; - __retVal[1] = m[1] * b; -} - -mat2x4 __operator * (const float a, const mat2x4 n) -{ - //return mat2x4 (a * n[0], a * n[1]); - __retVal[0] = a * n[0]; - __retVal[1] = a * n[1]; -} - -mat2x4 __operator * (const mat2x4 m, const float b) -{ - //return mat2x4 (m[0] * b, m[1] * b); - __retVal[0] = m[0] * b; - __retVal[1] = m[1] * b; -} - -mat3x2 __operator * (const float a, const mat3x2 n) -{ - //return mat3x2 (a * n[0], a * n[1], a * n[2]); - __retVal[0] = a * n[0]; - __retVal[1] = a * n[1]; - __retVal[2] = a * n[2]; -} - -mat3x2 __operator * (const mat3x2 m, const float b) -{ - //return mat3x2 (m[0] * b, m[1] * b, m[2] * b); - __retVal[0] = m[0] * b; - __retVal[1] = m[1] * b; - __retVal[2] = m[2] * b; -} - -mat3x4 __operator * (const float a, const mat3x4 n) -{ - //return mat3x4 (a * n[0], a * n[1], a * n[2]); - __retVal[0] = a * n[0]; - __retVal[1] = a * n[1]; - __retVal[2] = a * n[2]; -} - -mat3x4 __operator * (const mat3x4 m, const float b) -{ - //return mat3x4 (m[0] * b, m[1] * b, m[2] * b); - __retVal[0] = m[0] * b; - __retVal[1] = m[1] * b; - __retVal[2] = m[2] * b; -} - -mat4x2 __operator * (const mat4x2 m, const float b) -{ - //return mat4x2 (m[0] * b, m[1] * b, m[2] * b, m[3] * b); - __retVal[0] = m[0] * b; - __retVal[1] = m[1] * b; - __retVal[2] = m[2] * b; - __retVal[3] = m[3] * b; -} - -mat4x2 __operator * (const float a, const mat4x2 n) -{ - //return mat4x2 (a * n[0], a * n[1], a * n[2], a * n[3]); - __retVal[0] = a * n[0]; - __retVal[1] = a * n[1]; - __retVal[2] = a * n[2]; - __retVal[3] = a * n[3]; -} - -mat4x3 __operator * (const mat4x3 m, const float b) -{ - //return mat4x3 (m[0] * b, m[1] * b, m[2] * b, m[3] * b); - __retVal[0] = m[0] * b; - __retVal[1] = m[1] * b; - __retVal[2] = m[2] * b; - __retVal[3] = m[3] * b; -} - -mat4x3 __operator * (const float a, const mat4x3 n) -{ - //return mat4x3 (a * n[0], a * n[1], a * n[2], a * n[3]); - __retVal[0] = a * n[0]; - __retVal[1] = a * n[1]; - __retVal[2] = a * n[2]; - __retVal[3] = a * n[3]; -} - - -mat2x3 __operator / (const float a, const mat2x3 n) -{ - //return mat2x3 (a / n[0], a / n[1]); - const float inv = 1.0 / a; - __retVal[0] = inv * n[0]; - __retVal[1] = inv * n[1]; -} - -mat2x3 __operator / (const mat2x3 m, const float b) -{ - //return mat2x3 (m[0] / b, m[1] / b); - const float inv = 1.0 / b; - __retVal[0] = m[0] * inv; - __retVal[1] = m[1] * inv; -} - -mat2x4 __operator / (const float a, const mat2x4 n) -{ - //return mat2x4 (a / n[0], a / n[1]); - const float inv = 1.0 / a; - __retVal[0] = inv * n[0]; - __retVal[1] = inv * n[1]; -} - -mat2x4 __operator / (const mat2x4 m, const float b) -{ - //return mat2x4 (m[0] / b, m[1] / b); - const float inv = 1.0 / b; - __retVal[0] = m[0] * inv; - __retVal[1] = m[1] * inv; -} - -mat3x2 __operator / (const float a, const mat3x2 n) -{ - //return mat3x2 (a / n[0], a / n[1], a / n[2]); - const float inv = 1.0 / a; - __retVal[0] = inv * n[0]; - __retVal[1] = inv * n[1]; - __retVal[2] = inv * n[2]; -} - -mat3x2 __operator / (const mat3x2 m, const float b) -{ - //return mat3x2 (m[0] / b, m[1] / b, m[2] / b); - const float inv = 1.0 / b; - __retVal[0] = m[0] * inv; - __retVal[1] = m[1] * inv; - __retVal[2] = m[2] * inv; -} - -mat3x4 __operator / (const float a, const mat3x4 n) -{ - //return mat3x4 (a / n[0], a / n[1], a / n[2]); - const float inv = 1.0 / a; - __retVal[0] = inv * n[0]; - __retVal[1] = inv * n[1]; - __retVal[2] = inv * n[2]; -} - -mat3x4 __operator / (const mat3x4 m, const float b) -{ - //return mat3x4 (m[0] / b, m[1] / b, m[2] / b); - const float inv = 1.0 / b; - __retVal[0] = m[0] * inv; - __retVal[1] = m[1] * inv; - __retVal[2] = m[2] * inv; -} - -mat4x2 __operator / (const mat4x2 m, const float b) -{ - //return mat4x2 (m[0] / b, m[1] / b, m[2] / b, m[3] / b); - const float inv = 1.0 / b; - __retVal[0] = m[0] * inv; - __retVal[1] = m[1] * inv; - __retVal[2] = m[2] * inv; - __retVal[3] = m[3] * inv; -} - -mat4x2 __operator / (const float a, const mat4x2 n) -{ - //return mat4x2 (a / n[0], a / n[1], a / n[2], a / n[3]); - const float inv = 1.0 / a; - __retVal[0] = inv * n[0]; - __retVal[1] = inv * n[1]; - __retVal[2] = inv * n[2]; - __retVal[3] = inv * n[3]; -} - -mat4x3 __operator / (const mat4x3 m, const float b) -{ - //return mat4x3 (m[0] / b, m[1] / b, m[2] / b, m[3] / b); - const float inv = 1.0 / b; - __retVal[0] = m[0] * inv; - __retVal[1] = m[1] * inv; - __retVal[2] = m[2] * inv; - __retVal[3] = m[3] * inv; -} - -mat4x3 __operator / (const float a, const mat4x3 n) -{ - //return mat4x3 (a / n[0], a / n[1], a / n[2], a / n[3]); - const float inv = 1.0 / a; - __retVal[0] = inv * n[0]; - __retVal[1] = inv * n[1]; - __retVal[2] = inv * n[2]; - __retVal[3] = inv * n[3]; -} - - -mat2x3 __operator - (const mat2x3 m) { - return mat2x3 (-m[0], -m[1]); -} - -mat2x4 __operator - (const mat2x4 m) { - return mat2x4 (-m[0], -m[1]); -} - -mat3x2 __operator - (const mat3x2 m) { - return mat3x2 (-m[0], -m[1], -m[2]); -} - -mat3x4 __operator - (const mat3x4 m) { - return mat3x4 (-m[0], -m[1], -m[2]); -} - -mat4x2 __operator - (const mat4x2 m) { - return mat4x2 (-m[0], -m[1], -m[2], -m[3]); -} - -mat4x3 __operator - (const mat4x3 m) { - return mat4x3 (-m[0], -m[1], -m[2], -m[3]); -} - - -void __operator -- (inout mat2x3 m) { - --m[0]; - --m[1]; -} - -void __operator -- (inout mat2x4 m) { - --m[0]; - --m[1]; -} - -void __operator -- (inout mat3x2 m) { - --m[0]; - --m[1]; - --m[2]; -} - -void __operator -- (inout mat3x4 m) { - --m[0]; - --m[1]; - --m[2]; -} - -void __operator -- (inout mat4x2 m) { - --m[0]; - --m[1]; - --m[2]; - --m[3]; -} - -void __operator -- (inout mat4x3 m) { - --m[0]; - --m[1]; - --m[2]; - --m[3]; -} - - -void __operator ++ (inout mat2x3 m) { - ++m[0]; - ++m[1]; -} - -void __operator ++ (inout mat2x4 m) { - ++m[0]; - ++m[1]; -} - -void __operator ++ (inout mat3x2 m) { - ++m[0]; - ++m[1]; - ++m[2]; -} - -void __operator ++ (inout mat3x4 m) { - ++m[0]; - ++m[1]; - ++m[2]; -} - -void __operator ++ (inout mat4x2 m) { - ++m[0]; - ++m[1]; - ++m[2]; - ++m[3]; -} - -void __operator ++ (inout mat4x3 m) { - ++m[0]; - ++m[1]; - ++m[2]; - ++m[3]; -} - diff --git a/mesalib/src/mesa/shader/slang/library/slang_builtin_120_common.gc b/mesalib/src/mesa/shader/slang/library/slang_builtin_120_common.gc deleted file mode 100644 index c6264c3b4..000000000 --- a/mesalib/src/mesa/shader/slang/library/slang_builtin_120_common.gc +++ /dev/null @@ -1,200 +0,0 @@ -/* - * Mesa 3-D graphics library - * Version: 6.6 - * - * 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. - */ - -// -// From Shader Spec, ver. 1.20, rev. 6 -// - -// -// 8.5 Matrix Functions -// - -mat2x3 matrixCompMult (mat2x3 m, mat2x3 n) { - return mat2x3 (m[0] * n[0], m[1] * n[1]); -} - -mat2x4 matrixCompMult (mat2x4 m, mat2x4 n) { - return mat2x4 (m[0] * n[0], m[1] * n[1]); -} - -mat3x2 matrixCompMult (mat3x2 m, mat3x2 n) { - return mat3x2 (m[0] * n[0], m[1] * n[1], m[2] * n[2]); -} - -mat3x4 matrixCompMult (mat3x4 m, mat3x4 n) { - return mat3x4 (m[0] * n[0], m[1] * n[1], m[2] * n[2]); -} - -mat4x2 matrixCompMult (mat4x2 m, mat4x2 n) { - return mat4x2 (m[0] * n[0], m[1] * n[1], m[2] * n[2], m[3] * n[3]); -} - -mat4x3 matrixCompMult (mat4x3 m, mat4x3 n) { - return mat4x3 (m[0] * n[0], m[1] * n[1], m[2] * n[2], m[3] * n[3]); -} - -mat2 outerProduct (vec2 c, vec2 r) { - return mat2 ( - c.x * r.x, c.y * r.x, - c.x * r.y, c.y * r.y - ); -} - -mat3 outerProduct (vec3 c, vec3 r) { - return mat3 ( - c.x * r.x, c.y * r.x, c.z * r.x, - c.x * r.y, c.y * r.y, c.z * r.y, - c.x * r.z, c.y * r.z, c.z * r.z - ); -} - -mat4 outerProduct (vec4 c, vec4 r) { - return mat4 ( - c.x * r.x, c.y * r.x, c.z * r.x, c.w * r.x, - c.x * r.y, c.y * r.y, c.z * r.y, c.w * r.y, - c.x * r.z, c.y * r.z, c.z * r.z, c.w * r.z, - c.x * r.w, c.y * r.w, c.z * r.w, c.w * r.w - ); -} - -mat2x3 outerProduct (vec3 c, vec2 r) { - return mat2x3 ( - c.x * r.x, c.y * r.x, c.z * r.x, - c.x * r.y, c.y * r.y, c.z * r.y - ); -} - -mat3x2 outerProduct (vec2 c, vec3 r) { - return mat3x2 ( - c.x * r.x, c.y * r.x, - c.x * r.y, c.y * r.y, - c.x * r.z, c.y * r.z - ); -} - -mat2x4 outerProduct (vec4 c, vec2 r) { - return mat2x4 ( - c.x * r.x, c.y * r.x, c.z * r.x, c.w * r.x, - c.x * r.y, c.y * r.y, c.z * r.y, c.w * r.y - ); -} - -mat4x2 outerProduct (vec2 c, vec4 r) { - return mat4x2 ( - c.x * r.x, c.y * r.x, - c.x * r.y, c.y * r.y, - c.x * r.z, c.y * r.z, - c.x * r.w, c.y * r.w - ); -} - -mat3x4 outerProduct (vec4 c, vec3 r) { - return mat3x4 ( - c.x * r.x, c.y * r.x, c.z * r.x, c.w * r.x, - c.x * r.y, c.y * r.y, c.z * r.y, c.w * r.y, - c.x * r.z, c.y * r.z, c.z * r.z, c.w * r.z - ); -} - -mat4x3 outerProduct (vec3 c, vec4 r) { - return mat4x3 ( - c.x * r.x, c.y * r.x, c.z * r.x, - c.x * r.y, c.y * r.y, c.z * r.y, - c.x * r.z, c.y * r.z, c.z * r.z, - c.x * r.w, c.y * r.w, c.z * r.w - ); -} - -mat2 transpose (mat2 m) { - return mat2 ( - m[0].x, m[1].x, - m[0].y, m[1].y - ); -} - -mat3 transpose (mat3 m) { - return mat3 ( - m[0].x, m[1].x, m[2].x, - m[0].y, m[1].y, m[2].y, - m[0].z, m[1].z, m[2].z - ); -} - -mat4 transpose (mat4 m) { - return mat4 ( - m[0].x, m[1].x, m[2].x, m[3].x, - m[0].y, m[1].y, m[2].y, m[3].y, - m[0].z, m[1].z, m[2].z, m[3].z, - m[0].w, m[1].w, m[2].w, m[3].w - ); -} - -mat2x3 transpose (mat3x2 m) { - return mat2x3 ( - m[0].x, m[1].x, m[2].x, - m[0].y, m[1].y, m[2].y - ); -} - -mat3x2 transpose (mat2x3 m) { - return mat3x2 ( - m[0].x, m[1].x, - m[0].y, m[1].y, - m[0].z, m[1].z - ); -} - -mat2x4 transpose (mat4x2 m) { - return mat2x4 ( - m[0].x, m[1].x, m[2].x, m[3].x, - m[0].y, m[1].y, m[2].y, m[3].y - ); -} - -mat4x2 transpose (mat2x4 m) { - return mat4x2 ( - m[0].x, m[1].x, - m[0].y, m[1].y, - m[0].z, m[1].z, - m[0].w, m[1].w - ); -} - -mat3x4 transpose (mat4x3 m) { - return mat3x4 ( - m[0].x, m[1].x, m[2].x, m[3].x, - m[0].y, m[1].y, m[2].y, m[3].y, - m[0].z, m[1].z, m[2].z, m[3].z - ); -} - -mat4x3 transpose (mat3x4 m) { - return mat4x3 ( - m[0].x, m[1].x, m[2].x, - m[0].y, m[1].y, m[2].y, - m[0].z, m[1].z, m[2].z, - m[0].w, m[1].w, m[2].w - ); -} - diff --git a/mesalib/src/mesa/shader/slang/library/slang_builtin_120_fragment.gc b/mesalib/src/mesa/shader/slang/library/slang_builtin_120_fragment.gc deleted file mode 100644 index 7d516046a..000000000 --- a/mesalib/src/mesa/shader/slang/library/slang_builtin_120_fragment.gc +++ /dev/null @@ -1,30 +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. - */ - -// -// From Shader Spec, ver. 1.20, rev. 6 -// - -varying vec2 gl_PointCoord; - diff --git a/mesalib/src/mesa/shader/slang/library/slang_common_builtin.gc b/mesalib/src/mesa/shader/slang/library/slang_common_builtin.gc deleted file mode 100644 index a25ca55bc..000000000 --- a/mesalib/src/mesa/shader/slang/library/slang_common_builtin.gc +++ /dev/null @@ -1,1893 +0,0 @@ -/* - * Mesa 3-D graphics library - * Version: 7.3 - * - * Copyright (C) 2006 Brian Paul All Rights Reserved. - * Copyright (C) 2008 VMware, 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. - */ - -// -// From Shader Spec, ver. 1.10, rev. 59 -// - -// Note: the values assigned to these constants here aren't actually used. -// They're set by the compiler according to the GL context limits. -// See slang_simplify.c -const int gl_MaxLights = 8; -const int gl_MaxClipPlanes = 6; -const int gl_MaxTextureUnits = 8; -const int gl_MaxTextureCoords = 8; -const int gl_MaxVertexAttribs = 16; -const int gl_MaxVertexUniformComponents = 512; -const int gl_MaxVaryingFloats = 32; -const int gl_MaxVertexTextureImageUnits = 0; -const int gl_MaxCombinedTextureImageUnits = 2; -const int gl_MaxTextureImageUnits = 2; -const int gl_MaxFragmentUniformComponents = 64; -const int gl_MaxDrawBuffers = 1; - -uniform mat4 gl_ModelViewMatrix; -uniform mat4 gl_ProjectionMatrix; -uniform mat4 gl_ModelViewProjectionMatrix; -uniform mat4 gl_TextureMatrix[gl_MaxTextureCoords]; - -uniform mat3 gl_NormalMatrix; - -uniform mat4 gl_ModelViewMatrixInverse; -uniform mat4 gl_ProjectionMatrixInverse; -uniform mat4 gl_ModelViewProjectionMatrixInverse; -uniform mat4 gl_TextureMatrixInverse[gl_MaxTextureCoords]; - -uniform mat4 gl_ModelViewMatrixTranspose; -uniform mat4 gl_ProjectionMatrixTranspose; -uniform mat4 gl_ModelViewProjectionMatrixTranspose; -uniform mat4 gl_TextureMatrixTranspose[gl_MaxTextureCoords]; - -uniform mat4 gl_ModelViewMatrixInverseTranspose; -uniform mat4 gl_ProjectionMatrixInverseTranspose; -uniform mat4 gl_ModelViewProjectionMatrixInverseTranspose; -uniform mat4 gl_TextureMatrixInverseTranspose[gl_MaxTextureCoords]; - -uniform float gl_NormalScale; - -struct gl_DepthRangeParameters { - float near; - float far; - float diff; -}; - -uniform gl_DepthRangeParameters gl_DepthRange; - -uniform vec4 gl_ClipPlane[gl_MaxClipPlanes]; - -struct gl_PointParameters { - float size; - float sizeMin; - float sizeMax; - float fadeThresholdSize; - float distanceConstantAttenuation; - float distanceLinearAttenuation; - float distanceQuadraticAttenuation; -}; - -uniform gl_PointParameters gl_Point; - -struct gl_MaterialParameters { - vec4 emission; - vec4 ambient; - vec4 diffuse; - vec4 specular; - float shininess; -}; - -uniform gl_MaterialParameters gl_FrontMaterial; -uniform gl_MaterialParameters gl_BackMaterial; - -/* NOTE: the order of these fields is significant! - * See the definition of the lighting state vars such as STATE_SPOT_DIRECTION. - */ -struct gl_LightSourceParameters { - vec4 ambient; - vec4 diffuse; - vec4 specular; - vec4 position; - vec4 halfVector; - vec3 spotDirection; - float spotCosCutoff; - - float constantAttenuation; - float linearAttenuation; - float quadraticAttenuation; - float spotExponent; - - float spotCutoff; -}; - -uniform gl_LightSourceParameters gl_LightSource[gl_MaxLights]; - -struct gl_LightModelParameters { - vec4 ambient; -}; - -uniform gl_LightModelParameters gl_LightModel; - -struct gl_LightModelProducts { - vec4 sceneColor; -}; - -uniform gl_LightModelProducts gl_FrontLightModelProduct; -uniform gl_LightModelProducts gl_BackLightModelProduct; - -struct gl_LightProducts { - vec4 ambient; - vec4 diffuse; - vec4 specular; -}; - -uniform gl_LightProducts gl_FrontLightProduct[gl_MaxLights]; -uniform gl_LightProducts gl_BackLightProduct[gl_MaxLights]; - -uniform vec4 gl_TextureEnvColor[gl_MaxTextureImageUnits]; -uniform vec4 gl_EyePlaneS[gl_MaxTextureCoords]; -uniform vec4 gl_EyePlaneT[gl_MaxTextureCoords]; -uniform vec4 gl_EyePlaneR[gl_MaxTextureCoords]; -uniform vec4 gl_EyePlaneQ[gl_MaxTextureCoords]; -uniform vec4 gl_ObjectPlaneS[gl_MaxTextureCoords]; -uniform vec4 gl_ObjectPlaneT[gl_MaxTextureCoords]; -uniform vec4 gl_ObjectPlaneR[gl_MaxTextureCoords]; -uniform vec4 gl_ObjectPlaneQ[gl_MaxTextureCoords]; - -struct gl_FogParameters { - vec4 color; - float density; - float start; - float end; - float scale; -}; - -uniform gl_FogParameters gl_Fog; - - - - - -// -// 8.1 Angle and Trigonometry Functions -// - -//// radians - -float radians(const float deg) -{ - const float c = 3.1415926 / 180.0; - __asm vec4_multiply __retVal, deg, c; -} - -vec2 radians(const vec2 deg) -{ - const float c = 3.1415926 / 180.0; - __asm vec4_multiply __retVal.xy, deg.xy, c.xx; -} - -vec3 radians(const vec3 deg) -{ - const float c = 3.1415926 / 180.0; - __asm vec4_multiply __retVal.xyz, deg.xyz, c.xxx; -} - -vec4 radians(const vec4 deg) -{ - const float c = 3.1415926 / 180.0; - __asm vec4_multiply __retVal, deg, c.xxxx; -} - - -//// degrees - -float degrees(const float rad) -{ - const float c = 180.0 / 3.1415926; - __asm vec4_multiply __retVal, rad, c; -} - -vec2 degrees(const vec2 rad) -{ - const float c = 180.0 / 3.1415926; - __asm vec4_multiply __retVal.xy, rad.xy, c.xx; -} - -vec3 degrees(const vec3 rad) -{ - const float c = 180.0 / 3.1415926; - __asm vec4_multiply __retVal.xyz, rad.xyz, c.xxx; -} - -vec4 degrees(const vec4 rad) -{ - const float c = 180.0 / 3.1415926; - __asm vec4_multiply __retVal, rad, c.xxxx; -} - - -//// sin - -float sin(const float radians) -{ - __asm float_sine __retVal, radians; -} - -vec2 sin(const vec2 radians) -{ - __asm float_sine __retVal.x, radians.x; - __asm float_sine __retVal.y, radians.y; -} - -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(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; -} - - -//// cos - -float cos(const float radians) -{ - __asm float_cosine __retVal, radians; -} - -vec2 cos(const vec2 radians) -{ - __asm float_cosine __retVal.x, radians.x; - __asm float_cosine __retVal.y, radians.y; -} - -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(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; -} - - - -//// tan - -float tan(const float angle) -{ - const float s = sin(angle); - const float c = cos(angle); - return s / c; -} - -vec2 tan(const vec2 angle) -{ - const vec2 s = sin(angle); - const vec2 c = cos(angle); - return s / c; -} - -vec3 tan(const vec3 angle) -{ - const vec3 s = sin(angle); - const vec3 c = cos(angle); - return s / c; -} - -vec4 tan(const vec4 angle) -{ - const vec4 s = sin(angle); - const vec4 c = cos(angle); - return s / c; -} - - - -float asin(const float x) -{ - const float a0 = 1.5707288; // PI/2? - const float a1 = -0.2121144; - const float a2 = 0.0742610; - //const float a3 = -0.0187293; - const float halfPi = 3.1415926 * 0.5; - const float y = abs(x); - // three terms seem to be enough: - __retVal = (halfPi - sqrt(1.0 - y) * (a0 + y * (a1 + a2 * y))) * sign(x); - // otherwise, try four: - //__retVal = (halfPi - sqrt(1.0 - y) * (a0 + y * (a1 + y * (a2 + y * a3)))) * sign(x); -} - -vec2 asin(const vec2 v) -{ - __retVal.x = asin(v.x); - __retVal.y = asin(v.y); -} - -vec3 asin(const vec3 v) -{ - __retVal.x = asin(v.x); - __retVal.y = asin(v.y); - __retVal.z = asin(v.z); -} - -vec4 asin(const vec4 v) -{ - __retVal.x = asin(v.x); - __retVal.y = asin(v.y); - __retVal.z = asin(v.z); - __retVal.w = asin(v.w); -} - -float acos(const float x) -{ - const float halfPi = 3.1415926 * 0.5; - __retVal = halfPi - asin(x); -} - -vec2 acos(const vec2 v) -{ - __retVal.x = acos(v.x); - __retVal.y = acos(v.y); -} - -vec3 acos(const vec3 v) -{ - __retVal.x = acos(v.x); - __retVal.y = acos(v.y); - __retVal.z = acos(v.z); -} - -vec4 acos(const vec4 v) -{ - __retVal.x = acos(v.x); - __retVal.y = acos(v.y); - __retVal.z = acos(v.z); - __retVal.w = acos(v.w); -} - -float atan(const float x) -{ - __retVal = asin(x * inversesqrt(x * x + 1.0)); -} - -vec2 atan(const vec2 y_over_x) -{ - __retVal.x = atan(y_over_x.x); - __retVal.y = atan(y_over_x.y); -} - -vec3 atan(const vec3 y_over_x) -{ - __retVal.x = atan(y_over_x.x); - __retVal.y = atan(y_over_x.y); - __retVal.z = atan(y_over_x.z); -} - -vec4 atan(const vec4 y_over_x) -{ - __retVal.x = atan(y_over_x.x); - __retVal.y = atan(y_over_x.y); - __retVal.z = atan(y_over_x.z); - __retVal.w = atan(y_over_x.w); -} - -float atan(const float y, const float x) -{ - float r; - if (abs(x) > 1.0e-4) { - r = atan(y / x); - if (x < 0.0) { - r = r + sign(y) * 3.141593; - } - } - else { - r = sign(y) * 1.5707965; // pi/2 - } - return r; -} - -vec2 atan(const vec2 u, const vec2 v) -{ - __retVal.x = atan(u.x, v.x); - __retVal.y = atan(u.y, v.y); -} - -vec3 atan(const vec3 u, const vec3 v) -{ - __retVal.x = atan(u.x, v.x); - __retVal.y = atan(u.y, v.y); - __retVal.z = atan(u.z, v.z); -} - -vec4 atan(const vec4 u, const vec4 v) -{ - __retVal.x = atan(u.x, v.x); - __retVal.y = atan(u.y, v.y); - __retVal.z = atan(u.z, v.z); - __retVal.w = atan(u.w, v.w); -} - - -// -// 8.2 Exponential Functions -// - -//// pow - -float pow(const float a, const float b) -{ - __asm float_power __retVal, a, b; -} - -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(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(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; -} - - -//// exp - -float exp(const float a) -{ - // NOTE: log2(e) = 1.44269502 - float t = a * 1.44269502; - __asm float_exp2 __retVal, t; -} - -vec2 exp(const vec2 a) -{ - vec2 t = a * 1.44269502; - __asm float_exp2 __retVal.x, t.x; - __asm float_exp2 __retVal.y, t.y; -} - -vec3 exp(const vec3 a) -{ - vec3 t = a * 1.44269502; - __asm float_exp2 __retVal.x, t.x; - __asm float_exp2 __retVal.y, t.y; - __asm float_exp2 __retVal.z, t.z; -} - -vec4 exp(const vec4 a) -{ - vec4 t = a * 1.44269502; - __asm float_exp2 __retVal.x, t.x; - __asm float_exp2 __retVal.y, t.y; - __asm float_exp2 __retVal.z, t.z; - __asm float_exp2 __retVal.w, t.w; -} - - - -//// log2 - -float log2(const float x) -{ - __asm float_log2 __retVal, x; -} - -vec2 log2(const vec2 v) -{ - __asm float_log2 __retVal.x, v.x; - __asm float_log2 __retVal.y, v.y; -} - -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(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; -} - - -//// 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(const vec2 v) -{ - const float c = 0.693147181; - return log2(v) * c; -} - -vec3 log(const vec3 v) -{ - const float c = 0.693147181; - return log2(v) * c; -} - -vec4 log(const vec4 v) -{ - const float c = 0.693147181; - return log2(v) * c; -} - - -//// exp2 - -float exp2(const float a) -{ - __asm float_exp2 __retVal, a; -} - -vec2 exp2(const vec2 a) -{ - __asm float_exp2 __retVal.x, a.x; - __asm float_exp2 __retVal.y, a.y; -} - -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(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; -} - - -//// sqrt - -float sqrt(const float x) -{ - const float nx = -x; - float r; - __asm float_rsq r, x; - __asm float_rcp r, r; - __asm vec4_cmp __retVal, nx, r, 0.0; -} - -vec2 sqrt(const vec2 x) -{ - const vec2 nx = -x, zero = vec2(0.0); - vec2 r; - __asm float_rsq r.x, x.x; - __asm float_rsq r.y, x.y; - __asm float_rcp r.x, r.x; - __asm float_rcp r.y, r.y; - __asm vec4_cmp __retVal, nx, r, zero; -} - -vec3 sqrt(const vec3 x) -{ - const vec3 nx = -x, zero = vec3(0.0); - vec3 r; - __asm float_rsq r.x, x.x; - __asm float_rsq r.y, x.y; - __asm float_rsq r.z, x.z; - __asm float_rcp r.x, r.x; - __asm float_rcp r.y, r.y; - __asm float_rcp r.z, r.z; - __asm vec4_cmp __retVal, nx, r, zero; -} - -vec4 sqrt(const vec4 x) -{ - const vec4 nx = -x, zero = vec4(0.0); - vec4 r; - __asm float_rsq r.x, x.x; - __asm float_rsq r.y, x.y; - __asm float_rsq r.z, x.z; - __asm float_rsq r.w, x.w; - __asm float_rcp r.x, r.x; - __asm float_rcp r.y, r.y; - __asm float_rcp r.z, r.z; - __asm float_rcp r.w, r.w; - __asm vec4_cmp __retVal, nx, r, zero; -} - - -//// 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; -} - -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; -} - -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 = 1.0; -} - -vec2 normalize(const vec2 v) -{ - const float s = inversesqrt(dot(v, v)); - __asm vec4_multiply __retVal.xy, v, s; -} - -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 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; -} - -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; -} - - - -// -// 8.3 Common Functions -// - - -//// abs - -float abs(const float a) -{ - __asm vec4_abs __retVal, a; -} - -vec2 abs(const vec2 a) -{ - __asm vec4_abs __retVal.xy, a; -} - -vec3 abs(const vec3 a) -{ - __asm vec4_abs __retVal.xyz, a; -} - -vec4 abs(const vec4 a) -{ - __asm vec4_abs __retVal, a; -} - - -//// sign - -float sign(const float x) -{ - float p, n; - __asm vec4_sgt p, x, 0.0; // p = (x > 0) - __asm vec4_sgt n, 0.0, x; // n = (x < 0) - __asm vec4_subtract __retVal, p, n; // sign = p - n -} - -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(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(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; -} - - -//// floor - -float floor(const float a) -{ - __asm vec4_floor __retVal, a; -} - -vec2 floor(const vec2 a) -{ - __asm vec4_floor __retVal.xy, a; -} - -vec3 floor(const vec3 a) -{ - __asm vec4_floor __retVal.xyz, a; -} - -vec4 floor(const vec4 a) -{ - __asm vec4_floor __retVal, a; -} - - -//// ceil - -float ceil(const float a) -{ - // XXX this could be improved - float b = -a; - __asm vec4_floor b, b; - __retVal = -b; -} - -vec2 ceil(const vec2 a) -{ - vec2 b = -a; - __asm vec4_floor b, b; - __retVal.xy = -b; -} - -vec3 ceil(const vec3 a) -{ - vec3 b = -a; - __asm vec4_floor b, b; - __retVal.xyz = -b; -} - -vec4 ceil(const vec4 a) -{ - vec4 b = -a; - __asm vec4_floor b, b; - __retVal = -b; -} - - -//// fract - -float fract(const float a) -{ - __asm vec4_frac __retVal, a; -} - -vec2 fract(const vec2 a) -{ - __asm vec4_frac __retVal.xy, a; -} - -vec3 fract(const vec3 a) -{ - __asm vec4_frac __retVal.xyz, a; -} - -vec4 fract(const vec4 a) -{ - __asm vec4_frac __retVal, a; -} - - -//// mod (very untested!) - -float mod(const float a, const float b) -{ - float oneOverB; - __asm float_rcp oneOverB, b; - __retVal = a - b * floor(a * oneOverB); -} - -vec2 mod(const vec2 a, const float b) -{ - float oneOverB; - __asm float_rcp oneOverB, b; - __retVal.xy = a - b * floor(a * oneOverB); -} - -vec3 mod(const vec3 a, const float b) -{ - float oneOverB; - __asm float_rcp oneOverB, b; - __retVal.xyz = a - b * floor(a * oneOverB); -} - -vec4 mod(const vec4 a, const float b) -{ - float oneOverB; - __asm float_rcp oneOverB, b; - __retVal = a - b * floor(a * oneOverB); -} - -vec2 mod(const vec2 a, const vec2 b) -{ - vec2 oneOverB; - __asm float_rcp oneOverB.x, b.x; - __asm float_rcp oneOverB.y, b.y; - __retVal = a - b * floor(a * oneOverB); -} - -vec3 mod(const vec3 a, const vec3 b) -{ - vec3 oneOverB; - __asm float_rcp oneOverB.x, b.x; - __asm float_rcp oneOverB.y, b.y; - __asm float_rcp oneOverB.z, b.z; - __retVal = a - b * floor(a * oneOverB); -} - -vec4 mod(const vec4 a, const vec4 b) -{ - vec4 oneOverB; - __asm float_rcp oneOverB.x, b.x; - __asm float_rcp oneOverB.y, b.y; - __asm float_rcp oneOverB.z, b.z; - __asm float_rcp oneOverB.w, b.w; - __retVal = a - b * floor(a * oneOverB); -} - - -//// min - -float min(const float a, const float b) -{ - __asm vec4_min __retVal, a, b; -} - -vec2 min(const vec2 a, const vec2 b) -{ - __asm vec4_min __retVal.xy, a.xy, b.xy; -} - -vec3 min(const vec3 a, const vec3 b) -{ - __asm vec4_min __retVal.xyz, a.xyz, b.xyz; -} - -vec4 min(const vec4 a, const vec4 b) -{ - __asm vec4_min __retVal, a, b; -} - -vec2 min(const vec2 a, const float b) -{ - __asm vec4_min __retVal, a.xy, b; -} - -vec3 min(const vec3 a, const float b) -{ - __asm vec4_min __retVal, a.xyz, b; -} - -vec4 min(const vec4 a, const float b) -{ - __asm vec4_min __retVal, a, b; -} - - -//// max - -float max(const float a, const float b) -{ - __asm vec4_max __retVal, a, b; -} - -vec2 max(const vec2 a, const vec2 b) -{ - __asm vec4_max __retVal.xy, a.xy, b.xy; -} - -vec3 max(const vec3 a, const vec3 b) -{ - __asm vec4_max __retVal.xyz, a.xyz, b.xyz; -} - -vec4 max(const vec4 a, const vec4 b) -{ - __asm vec4_max __retVal, a, b; -} - -vec2 max(const vec2 a, const float b) -{ - __asm vec4_max __retVal, a.xy, b; -} - -vec3 max(const vec3 a, const float b) -{ - __asm vec4_max __retVal, a.xyz, b; -} - -vec4 max(const vec4 a, const float b) -{ - __asm vec4_max __retVal, a, b; -} - - -//// clamp - -float clamp(const float val, const float minVal, const float maxVal) -{ - __asm vec4_clamp __retVal, val, minVal, maxVal; -} - -vec2 clamp(const vec2 val, const float minVal, const float maxVal) -{ - __asm vec4_clamp __retVal, val, minVal, maxVal; -} - -vec3 clamp(const vec3 val, const float minVal, const float maxVal) -{ - __asm vec4_clamp __retVal, val, minVal, maxVal; -} - -vec4 clamp(const vec4 val, const float minVal, const float maxVal) -{ - __asm vec4_clamp __retVal, val, minVal, maxVal; -} - -vec2 clamp(const vec2 val, const vec2 minVal, const vec2 maxVal) -{ - __asm vec4_clamp __retVal, val, minVal, maxVal; -} - -vec3 clamp(const vec3 val, const vec3 minVal, const vec3 maxVal) -{ - __asm vec4_clamp __retVal, val, minVal, maxVal; -} - -vec4 clamp(const vec4 val, const vec4 minVal, const vec4 maxVal) -{ - __asm vec4_clamp __retVal, val, minVal, maxVal; -} - - -//// mix - -float mix(const float x, const float y, const float a) -{ - __asm vec4_lrp __retVal, a, y, x; -} - -vec2 mix(const vec2 x, const vec2 y, const float a) -{ - __asm vec4_lrp __retVal, a, y, x; -} - -vec3 mix(const vec3 x, const vec3 y, const float a) -{ - __asm vec4_lrp __retVal, a, y, x; -} - -vec4 mix(const vec4 x, const vec4 y, const float a) -{ - __asm vec4_lrp __retVal, a, y, x; -} - -vec2 mix(const vec2 x, const vec2 y, const vec2 a) -{ - __asm vec4_lrp __retVal, a, y, x; -} - -vec3 mix(const vec3 x, const vec3 y, const vec3 a) -{ - __asm vec4_lrp __retVal, a, y, x; -} - -vec4 mix(const vec4 x, const vec4 y, const vec4 a) -{ - __asm vec4_lrp __retVal, a, y, x; -} - - -//// step - -float step(const float edge, const float x) -{ - __asm vec4_sge __retVal, x, edge; -} - -vec2 step(const vec2 edge, const vec2 x) -{ - __asm vec4_sge __retVal.xy, x, edge; -} - -vec3 step(const vec3 edge, const vec3 x) -{ - __asm vec4_sge __retVal.xyz, x, edge; -} - -vec4 step(const vec4 edge, const vec4 x) -{ - __asm vec4_sge __retVal, x, edge; -} - -vec2 step(const float edge, const vec2 v) -{ - __asm vec4_sge __retVal.xy, v, edge; -} - -vec3 step(const float edge, const vec3 v) -{ - __asm vec4_sge __retVal.xyz, v, edge; -} - -vec4 step(const float edge, const vec4 v) -{ - __asm vec4_sge __retVal, v, edge; -} - - -//// smoothstep - -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(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(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(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(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(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(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 -// - - -//// length - -float length(const float x) -{ - return abs(x); -} - -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(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, r; // retVal = 1 / r -} - -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, r; // retVal = 1 / r -} - - -//// distance - -float distance(const float x, const float y) -{ - const float d = x - y; - __retVal = length(d); -} - -float distance(const vec2 v, const vec2 u) -{ - const vec2 d2 = v - u; - __retVal = length(d2); -} - -float distance(const vec3 v, const vec3 u) -{ - const vec3 d3 = v - u; - __retVal = length(d3); -} - -float distance(const vec4 v, const vec4 u) -{ - const vec4 d4 = v - u; - __retVal = length(d4); -} - - -//// cross - -vec3 cross(const vec3 v, const vec3 u) -{ - __asm vec3_cross __retVal.xyz, v, u; -} - - -//// faceforward - -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, 0.0, d; // s = (0.0 > d) ? 1 : 0 - return mix(-N, N, s); -} - -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, 0.0, d; // s = (0.0 > d) ? 1 : 0 - return mix(-N, N, s); -} - -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, 0.0, d; // s = (0.0 > d) ? 1 : 0 - return mix(-N, N, s); -} - -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, 0.0, d; // s = (0.0 > d) ? 1 : 0 - return mix(-N, N, s); -} - - -//// reflect - -float reflect(const float I, const float 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(const vec3 I, const vec3 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; -} - -//// refract - -float refract(const float I, const float N, const float eta) -{ - float n_dot_i = dot(N, I); - float k = 1.0 - eta * eta * (1.0 - n_dot_i * n_dot_i); - float retval; - if (k < 0.0) - retval = 0.0; - else - retval = eta * I - (eta * n_dot_i + sqrt(k)) * N; - return retval; -} - -vec2 refract(const vec2 I, const vec2 N, const float eta) -{ - float n_dot_i = dot(N, I); - float k = 1.0 - eta * eta * (1.0 - n_dot_i * n_dot_i); - vec2 retval; - if (k < 0.0) - retval = vec2(0.0); - else - retval = eta * I - (eta * n_dot_i + sqrt(k)) * N; - return retval; -} - -vec3 refract(const vec3 I, const vec3 N, const float eta) -{ - float n_dot_i = dot(N, I); - float k = 1.0 - eta * eta * (1.0 - n_dot_i * n_dot_i); - vec3 retval; - if (k < 0.0) - retval = vec3(0.0); - else - retval = eta * I - (eta * n_dot_i + sqrt(k)) * N; - return retval; -} - -vec4 refract(const vec4 I, const vec4 N, const float eta) -{ - float n_dot_i = dot(N, I); - float k = 1.0 - eta * eta * (1.0 - n_dot_i * n_dot_i); - vec4 retval; - if (k < 0.0) - retval = vec4(0.0); - else - retval = eta * I - (eta * n_dot_i + sqrt(k)) * N; - return retval; -} - - - - -// -// 8.5 Matrix Functions -// - -mat2 matrixCompMult (mat2 m, mat2 n) { - return mat2 (m[0] * n[0], m[1] * n[1]); -} - -mat3 matrixCompMult (mat3 m, mat3 n) { - return mat3 (m[0] * n[0], m[1] * n[1], m[2] * n[2]); -} - -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 -// - -//// lessThan - -bvec2 lessThan(const vec2 u, const vec2 v) -{ - __asm vec4_slt __retVal.xy, u, v; -} - -bvec3 lessThan(const vec3 u, const vec3 v) -{ - __asm vec4_slt __retVal.xyz, u, v; -} - -bvec4 lessThan(const vec4 u, const vec4 v) -{ - __asm vec4_slt __retVal, u, v; -} - -bvec2 lessThan(const ivec2 u, const ivec2 v) -{ - __asm vec4_slt __retVal.xy, u, v; -} - -bvec3 lessThan(const ivec3 u, const ivec3 v) -{ - __asm vec4_slt __retVal.xyz, u, v; -} - -bvec4 lessThan(const ivec4 u, const ivec4 v) -{ - __asm vec4_slt __retVal, u, v; -} - - -//// lessThanEqual - -bvec2 lessThanEqual(const vec2 u, const vec2 v) -{ - __asm vec4_sle __retVal.xy, u, v; -} - -bvec3 lessThanEqual(const vec3 u, const vec3 v) -{ - __asm vec4_sle __retVal.xyz, u, v; -} - -bvec4 lessThanEqual(const vec4 u, const vec4 v) -{ - __asm vec4_sle __retVal, u, v; -} - -bvec2 lessThanEqual(const ivec2 u, const ivec2 v) -{ - __asm vec4_sle __retVal.xy, u, v; -} - -bvec3 lessThanEqual(const ivec3 u, const ivec3 v) -{ - __asm vec4_sle __retVal.xyz, u, v; -} - -bvec4 lessThanEqual(const ivec4 u, const ivec4 v) -{ - __asm vec4_sle __retVal, u, v; -} - - -//// greaterThan - -bvec2 greaterThan(const vec2 u, const vec2 v) -{ - __asm vec4_sgt __retVal.xy, u, v; -} - -bvec3 greaterThan(const vec3 u, const vec3 v) -{ - __asm vec4_sgt __retVal.xyz, u, v; -} - -bvec4 greaterThan(const vec4 u, const vec4 v) -{ - __asm vec4_sgt __retVal, u, v; -} - -bvec2 greaterThan(const ivec2 u, const ivec2 v) -{ - __asm vec4_sgt __retVal.xy, u.xy, v.xy; -} - -bvec3 greaterThan(const ivec3 u, const ivec3 v) -{ - __asm vec4_sgt __retVal.xyz, u, v; -} - -bvec4 greaterThan(const ivec4 u, const ivec4 v) -{ - __asm vec4_sgt __retVal, u, v; -} - - -//// greaterThanEqual - -bvec2 greaterThanEqual(const vec2 u, const vec2 v) -{ - __asm vec4_sge __retVal.xy, u, v; -} - -bvec3 greaterThanEqual(const vec3 u, const vec3 v) -{ - __asm vec4_sge __retVal.xyz, u, v; -} - -bvec4 greaterThanEqual(const vec4 u, const vec4 v) -{ - __asm vec4_sge __retVal, u, v; -} - -bvec2 greaterThanEqual(const ivec2 u, const ivec2 v) -{ - __asm vec4_sge __retVal.xy, u, v; -} - -bvec3 greaterThanEqual(const ivec3 u, const ivec3 v) -{ - __asm vec4_sge __retVal.xyz, u, v; -} - -bvec4 greaterThanEqual(const ivec4 u, const ivec4 v) -{ - __asm vec4_sge __retVal, u, v; -} - - -//// equal - -bvec2 equal(const vec2 u, const vec2 v) -{ - __asm vec4_seq __retVal.xy, u, v; -} - -bvec3 equal(const vec3 u, const vec3 v) -{ - __asm vec4_seq __retVal.xyz, u, v; -} - -bvec4 equal(const vec4 u, const vec4 v) -{ - __asm vec4_seq __retVal, u, v; -} - -bvec2 equal(const ivec2 u, const ivec2 v) -{ - __asm vec4_seq __retVal.xy, u, v; -} - -bvec3 equal(const ivec3 u, const ivec3 v) -{ - __asm vec4_seq __retVal.xyz, u, v; -} - -bvec4 equal(const ivec4 u, const ivec4 v) -{ - __asm vec4_seq __retVal, u, v; -} - -bvec2 equal(const bvec2 u, const bvec2 v) -{ - __asm vec4_seq __retVal.xy, u, v; -} - -bvec3 equal(const bvec3 u, const bvec3 v) -{ - __asm vec4_seq __retVal.xyz, u, v; -} - -bvec4 equal(const bvec4 u, const bvec4 v) -{ - __asm vec4_seq __retVal, u, v; -} - - - - -//// notEqual - -bvec2 notEqual(const vec2 u, const vec2 v) -{ - __asm vec4_sne __retVal.xy, u, v; -} - -bvec3 notEqual(const vec3 u, const vec3 v) -{ - __asm vec4_sne __retVal.xyz, u, v; -} - -bvec4 notEqual(const vec4 u, const vec4 v) -{ - __asm vec4_sne __retVal, u, v; -} - -bvec2 notEqual(const ivec2 u, const ivec2 v) -{ - __asm vec4_sne __retVal.xy, u, v; -} - -bvec3 notEqual(const ivec3 u, const ivec3 v) -{ - __asm vec4_sne __retVal.xyz, u, v; -} - -bvec4 notEqual(const ivec4 u, const ivec4 v) -{ - __asm vec4_sne __retVal, u, v; -} - -bvec2 notEqual(const bvec2 u, const bvec2 v) -{ - __asm vec4_sne __retVal.xy, u, v; -} - -bvec3 notEqual(const bvec3 u, const bvec3 v) -{ - __asm vec4_sne __retVal.xyz, u, v; -} - -bvec4 notEqual(const bvec4 u, const bvec4 v) -{ - __asm vec4_sne __retVal, u, v; -} - - - -//// 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(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(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; -} - - -//// all - -bool all (const bvec2 v) -{ - float prod; - __asm vec4_multiply prod, v.x, v.y; - __asm vec4_sne __retVal, prod, 0.0; -} - -bool all (const bvec3 v) -{ - float prod; - __asm vec4_multiply prod, v.x, v.y; - __asm vec4_multiply prod, prod, v.z; - __asm vec4_sne __retVal, prod, 0.0; -} - -bool all (const bvec4 v) -{ - float prod; - __asm vec4_multiply prod, v.x, v.y; - __asm vec4_multiply prod, prod, v.z; - __asm vec4_multiply prod, prod, v.w; - __asm vec4_sne __retVal, prod, 0.0; -} - - - -//// not - -bvec2 not (const bvec2 v) -{ - __asm vec4_seq __retVal.xy, v, 0.0; -} - -bvec3 not (const bvec3 v) -{ - __asm vec4_seq __retVal.xyz, v, 0.0; -} - -bvec4 not (const bvec4 v) -{ - __asm vec4_seq __retVal, v, 0.0; -} - - - -//// Texture Lookup Functions (for both fragment and vertex shaders) - -vec4 texture1D(const sampler1D sampler, const float coord) -{ - __asm vec4_tex_1d __retVal, sampler, coord; -} - -vec4 texture1DProj(const sampler1D sampler, const vec2 coord) -{ - // need to swizzle .y into .w - __asm vec4_tex_1d_proj __retVal, sampler, coord.xyyy; -} - -vec4 texture1DProj(const sampler1D sampler, const vec4 coord) -{ - __asm vec4_tex_1d_proj __retVal, sampler, coord; -} - - -vec4 texture2D(const sampler2D sampler, const vec2 coord) -{ - __asm vec4_tex_2d __retVal, sampler, coord; -} - -vec4 texture2DProj(const sampler2D sampler, const vec3 coord) -{ - // need to swizzle 'z' into 'w'. - __asm vec4_tex_2d_proj __retVal, sampler, coord.xyzz; -} - -vec4 texture2DProj(const sampler2D sampler, const vec4 coord) -{ - __asm vec4_tex_2d_proj __retVal, sampler, coord; -} - - -vec4 texture3D(const sampler3D sampler, const vec3 coord) -{ - __asm vec4_tex_3d __retVal, sampler, coord; -} - -vec4 texture3DProj(const sampler3D sampler, const vec4 coord) -{ - __asm vec4_tex_3d_proj __retVal, sampler, coord; -} - - -vec4 textureCube(const samplerCube sampler, const vec3 coord) -{ - __asm vec4_tex_cube __retVal, sampler, coord; -} - - - -vec4 shadow1D(const sampler1DShadow sampler, const vec3 coord) -{ - __asm vec4_tex_1d_shadow __retVal, sampler, coord; -} - -vec4 shadow1DProj(const sampler1DShadow sampler, const vec4 coord) -{ - // .s and .p will be divided by .q - __asm vec4_tex_1d_proj_shadow __retVal, sampler, coord; -} - -vec4 shadow2D(const sampler2DShadow sampler, const vec3 coord) -{ - __asm vec4_tex_2d_shadow __retVal, sampler, coord; -} - -vec4 shadow2DProj(const sampler2DShadow sampler, const vec4 coord) -{ - // .s, .t and .p will be divided by .q - __asm vec4_tex_2d_proj_shadow __retVal, sampler, coord; -} - - -//// GL_ARB_texture_rectangle: -vec4 texture2DRect(const sampler2DRect sampler, const vec2 coord) -{ - __asm vec4_tex_rect __retVal, sampler, coord; -} - -vec4 texture2DRectProj(const sampler2DRect sampler, const vec3 coord) -{ - // need to swizzle .y into .w - __asm vec4_tex_rect_proj __retVal, sampler, coord.xyzz; -} - -vec4 texture2DRectProj(const sampler2DRect sampler, const vec4 coord) -{ - __asm vec4_tex_rect_proj __retVal, sampler, ccoord; -} - -vec4 shadow2DRect(const sampler2DRectShadow sampler, const vec3 coord) -{ - __asm vec4_tex_rect_shadow __retVal, sampler, coord; -} - -vec4 shadow2DRectProj(const sampler2DRectShadow sampler, const vec4 coord) -{ - __asm vec4_tex_rect_proj_shadow __retVal, sampler, coord; -} - - - -//// GL_EXT_texture_array -vec4 texture1DArray(const sampler1DArray sampler, const vec2 coord) -{ - __asm vec4_tex_1d_array __retVal, sampler, coord; -} - -vec4 texture2DArray(const sampler2DArray sampler, const vec3 coord) -{ - __asm vec4_tex_2d_array __retVal, sampler, coord; -} - - -// -// 8.9 Noise Functions -// -// AUTHOR: Stefan Gustavson (stegu@itn.liu.se), Nov 26, 2005 -// - -float noise1(const float x) -{ - __asm float_noise1 __retVal, x; -} - - -float noise1(const vec2 x) -{ - __asm float_noise2 __retVal, x; -} - -float noise1(const vec3 x) -{ - __asm float_noise3 __retVal, x; -} - -float noise1(const vec4 x) -{ - __asm float_noise4 __retVal, x; -} - -vec2 noise2(const float x) -{ - __retVal.x = noise1(x); - __retVal.y = noise1(x + 19.34); -} - -vec2 noise2(const vec2 x) -{ - __retVal.x = noise1(x); - __retVal.y = noise1(x + vec2(19.34, 7.66)); -} - -vec2 noise2(const vec3 x) -{ - __retVal.x = noise1(x); - __retVal.y = noise1(x + vec3(19.34, 7.66, 3.23)); -} - -vec2 noise2(const vec4 x) -{ - __retVal.x = noise1(x); - __retVal.y = noise1(x + vec4(19.34, 7.66, 3.23, 2.77)); -} - -vec3 noise3(const float x) -{ - __retVal.x = noise1(x); - __retVal.y = noise1(x + 19.34); - __retVal.z = noise1(x + 5.47); -} - -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(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)); -} - -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(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(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(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/mesalib/src/mesa/shader/slang/library/slang_core.gc b/mesalib/src/mesa/shader/slang/library/slang_core.gc deleted file mode 100644 index 0a0d15903..000000000 --- a/mesalib/src/mesa/shader/slang/library/slang_core.gc +++ /dev/null @@ -1,2619 +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 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. -// -// 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 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. -// -// 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. -// -// 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 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, -// -// 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: -// - "." (field selection) - translated to subscript access, -// - "&&" (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. -// - - - -//// Basic, scalar constructors/casts - -int __constructor(const float f) -{ - __asm vec4_to_ivec4 __retVal, f; -} - -int __constructor(const bool b) -{ - __retVal = b; -} - -int __constructor(const int i) -{ - __retVal = i; -} - -bool __constructor(const int i) -{ - __asm vec4_sne __retVal, i, 0.0; -} - -bool __constructor(const float f) -{ - __asm vec4_sne __retVal, f, 0.0; -} - -bool __constructor(const bool b) -{ - __retVal = b; -} - -float __constructor(const int i) -{ - __asm ivec4_to_vec4 __retVal, i; -} - -float __constructor(const bool b) -{ - __asm ivec4_to_vec4 __retVal, b; -} - -float __constructor(const float f) -{ - __retVal = f; -} - - -//// vec2 constructors - -vec2 __constructor(const float x, const float y) -{ - __retVal.x = x; - __retVal.y = y; -} - -vec2 __constructor(const float f) -{ - __asm vec4_move __retVal.xy, f; -} - -vec2 __constructor(const int i) -{ - __asm ivec4_to_vec4 __retVal.xy, i; -} - -vec2 __constructor(const bool b) -{ - __asm ivec4_to_vec4 __retVal.xy, b; -} - -vec2 __constructor(const bvec2 b) -{ -// __retVal = b; - __asm ivec4_to_vec4 __retVal.xy, b; -} - -vec2 __constructor(const vec3 v) -{ - __asm vec4_move __retVal.xy, v.xy; -} - -vec2 __constructor(const vec4 v) -{ - __asm vec4_move __retVal.xy, v.xy; -} - - -//// vec3 constructors - -vec3 __constructor(const float x, const float y, const float z) -{ - __retVal.x = x; - __retVal.y = y; - __retVal.z = z; -} - -vec3 __constructor(const float f) -{ - // Note: this could be "__retVal.xyz = f" but that's an illegal assignment - __asm vec4_move __retVal.xyz, f; -} - -vec3 __constructor(const int i) -{ - __asm ivec4_to_vec4 __retVal.xyz, i; -} - -vec3 __constructor(const bool b) -{ - __asm ivec4_to_vec4 __retVal.xyz, b; -} - -vec3 __constructor(const bvec3 b) -{ - __asm ivec4_to_vec4 __retVal.xyz, b; -} - -vec3 __constructor(const vec4 v) -{ - __asm vec4_move __retVal.xyz, v; -} - - -//// 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; -} - -vec4 __constructor(const float f) -{ - // Note: this could be "__retVal = f" but that's an illegal assignment - __asm vec4_move __retVal, f; -} - -vec4 __constructor(const int i) -{ - __asm ivec4_to_vec4 __retVal, i; -} - -vec4 __constructor(const bool b) -{ - __asm ivec4_to_vec4 __retVal, b; -} - -vec4 __constructor(const bvec4 b) -{ - __asm ivec4_to_vec4 __retVal, b; -} - -vec4 __constructor(const ivec4 i) -{ - __asm ivec4_to_vec4 __retVal, i; -} - -vec4 __constructor(const vec3 v3, const float f) -{ - // XXX this constructor shouldn't be needed anymore - __retVal.xyz = v3; - __retVal.w = f; -} - -vec4 __constructor(const vec2 v2, const float f1, const float f2) -{ - // XXX this constructor shouldn't be needed anymore - __retVal.xy = v2; - __retVal.z = f1; - __retVal.w = f2; -} - - -//// ivec2 constructors - -ivec2 __constructor(const int i, const int j) -{ - __retVal.x = i; - __retVal.y = j; -} - -ivec2 __constructor(const int i) -{ - __asm vec4_move __retVal.xy, i; -} - -ivec2 __constructor(const float f) -{ - __asm vec4_to_ivec4 __retVal.xy, f; -} - -ivec2 __constructor(const bool b) -{ - __asm vec4_to_ivec4 __retVal.xy, b; -} - - -//// ivec3 constructors - -ivec3 __constructor(const int i, const int j, const int k) -{ - __retVal.x = i; - __retVal.y = j; - __retVal.z = k; -} - -ivec3 __constructor(const int i) -{ - __asm vec4_move __retVal.xyz, i; -} - -ivec3 __constructor(const float f) -{ - __asm vec4_to_ivec4 __retVal.xyz, f; -} - -ivec3 __constructor(const bool b) -{ - __asm vec4_move __retVal.xyz, b; -} - - -//// 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; -} - -ivec4 __constructor(const int i) -{ - __asm vec4_move __retVal, i; -} - -ivec4 __constructor(const float f) -{ - __asm vec4_to_ivec4 __retVal, f; -} - -ivec4 __constructor(const bool b) -{ - __asm vec4_to_ivec4 __retVal, b; -} - - -//// bvec2 constructors - -bvec2 __constructor(const bool b1, const bool b2) -{ - __retVal.x = b1; - __retVal.y = b2; -} - -bvec2 __constructor(const int i1, const int i2) -{ - __asm vec4_sne __retVal.x, i1, 0.0; - __asm vec4_sne __retVal.y, i2, 0.0; -} - - -bvec2 __constructor(const bool b) -{ - __asm vec4_move __retVal.xy, b; -} - -bvec2 __constructor(const float f) -{ - __asm vec4_sne __retVal.xy, f, 0.0; -} - -bvec2 __constructor(const int i) -{ - __asm vec4_sne __retVal.xy, i, 0.0; -} - -bvec2 __constructor(const vec2 v) -{ - __asm vec4_sne __retVal.xy, v, 0.0; -} - -bvec2 __constructor(const ivec2 v) -{ - __asm vec4_sne __retVal.xy, v, 0.0; -} - - - -//// bvec3 constructors - -bvec3 __constructor(const bool b1, const bool b2, const bool b3) -{ - __retVal.x = b1; - __retVal.y = b2; - __retVal.z = b3; -} - -bvec3 __constructor(const float f1, const float f2, const float f3) -{ - __asm vec4_sne __retVal.x, f1, 0.0; - __asm vec4_sne __retVal.y, f2, 0.0; - __asm vec4_sne __retVal.z, f3, 0.0; -} - -bvec3 __constructor(const bool b) -{ - __asm vec4_move __retVal.xyz, b; -} - -bvec3 __constructor(const float f) -{ - __asm vec4_sne __retVal.xyz, f, 0.0; -} - -bvec3 __constructor(const int i) -{ - __asm vec4_sne __retVal.xyz, i, 0.0; -} - -bvec3 __constructor(const vec3 v) -{ - __asm vec4_sne __retVal.xyz, v, 0.0; -} - -bvec3 __constructor(const ivec3 v) -{ - __asm vec4_sne __retVal.xyz, v, 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; -} - -bvec4 __constructor(const float f1, const float f2, const float f3, const float f4) -{ - const float zero = 0.0; - __asm vec4_sne __retVal.x, f1, zero; - __asm vec4_sne __retVal.y, f2, zero; - __asm vec4_sne __retVal.z, f3, zero; - __asm vec4_sne __retVal.w, f4, zero; -} - -bvec4 __constructor(const bool b) -{ - __asm vec4_move __retVal.xyzw, b; -} - -bvec4 __constructor(const float f) -{ - __asm vec4_sne __retVal.xyzw, f, 0.0; -} - -bvec4 __constructor(const int i) -{ - __asm vec4_sne __retVal.xyzw, i, 0.0; -} - -bvec4 __constructor(const vec4 v) -{ - __asm vec4_sne __retVal.xyzw, v, 0.0; -} - -bvec4 __constructor(const ivec4 v) -{ - __asm vec4_sne __retVal.xyzw, v, 0.0; -} - - - -//// 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; -} - -mat2 __constructor(const float f) -{ - __retVal[0].x = f; - __retVal[0].y = 0.0; - __retVal[1].x = 0.0; - __retVal[1].y = f; -} - -mat2 __constructor(const int i) -{ - return mat2(float(i)); -} - -mat2 __constructor(const bool b) -{ - return mat2(float(b)); -} - -mat2 __constructor(const vec2 c0, const vec2 c1) -{ - __retVal[0] = c0; - __retVal[1] = c1; -} - - -//// 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; -} - -mat3 __constructor(const float f) -{ - vec2 v = vec2(f, 0.0); - __retVal[0] = v.xyy; - __retVal[1] = v.yxy; - __retVal[2] = v.yyx; -} - -mat3 __constructor(const int i) -{ - return mat3(float(i)); -} - -mat3 __constructor(const bool b) -{ - return mat3(float(b)); -} - -mat3 __constructor(const vec3 c0, const vec3 c1, const vec3 c2) -{ - __retVal[0] = c0; - __retVal[1] = c1; - __retVal[2] = c2; -} - - -//// 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; -} - - -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; -} - -mat4 __constructor(const int i) -{ - return mat4(float(i)); -} - -mat4 __constructor(const bool b) -{ - return mat4(float(b)); -} - -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; -} - - - -//// Basic int operators - -int __operator + (const int a, const int b) -{ - __asm vec4_add __retVal, a, b; -} - -int __operator - (const int a, const int b) -{ - __asm vec4_subtract __retVal, a, b; -} - -int __operator * (const int a, const int b) -{ - __asm vec4_multiply __retVal, a, b; -} - -int __operator / (const int a, const int b) -{ - float bInv, x; - __asm float_rcp bInv, b; - __asm vec4_multiply x, a, bInv; - __asm vec4_to_ivec4 __retVal, x; -} - - -//// Basic ivec2 operators - -ivec2 __operator + (const ivec2 a, const ivec2 b) -{ - __asm vec4_add __retVal, a, b; -} - -ivec2 __operator - (const ivec2 a, const ivec2 b) -{ - __asm vec4_subtract __retVal, a, b; -} - -ivec2 __operator * (const ivec2 a, const ivec2 b) -{ - __asm vec4_multiply __retVal, a, b; -} - -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 vec4_to_ivec4 __retVal, x; -} - - -//// Basic ivec3 operators - -ivec3 __operator + (const ivec3 a, const ivec3 b) -{ - __asm vec4_add __retVal, a, b; -} - -ivec3 __operator - (const ivec3 a, const ivec3 b) -{ - __asm vec4_subtract __retVal, a, b; -} - -ivec3 __operator * (const ivec3 a, const ivec3 b) -{ - __asm vec4_multiply __retVal, a, b; -} - -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 vec4_to_ivec4 __retVal, x; -} - - -//// Basic ivec4 operators - -ivec4 __operator + (const ivec4 a, const ivec4 b) -{ - __asm vec4_add __retVal, a, b; -} - -ivec4 __operator - (const ivec4 a, const ivec4 b) -{ - __asm vec4_subtract __retVal, a, b; -} - -ivec4 __operator * (const ivec4 a, const ivec4 b) -{ - __asm vec4_multiply __retVal, a, b; -} - -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 vec4_to_ivec4 __retVal, x; -} - - -//// Basic float operators - -float __operator + (const float a, const float b) -{ - __asm vec4_add __retVal, a, b; -} - -float __operator - (const float a, const float b) -{ - __asm vec4_subtract __retVal, a, b; -} - -float __operator * (const float a, const float b) -{ - __asm vec4_multiply __retVal, a, b; -} - -float __operator / (const float a, const float b) -{ - float bInv; - __asm float_rcp bInv.x, b; - __asm vec4_multiply __retVal, a, bInv; -} - - -//// Basic vec2 operators - -vec2 __operator + (const vec2 v, const vec2 u) -{ - __asm vec4_add __retVal.xy, v, u; -} - -vec2 __operator - (const vec2 v, const vec2 u) -{ - __asm vec4_subtract __retVal.xy, v, u; -} - -vec2 __operator * (const vec2 v, const vec2 u) -{ - __asm vec4_multiply __retVal.xy, v, u; -} - -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; -} - - -//// Basic vec3 operators - -vec3 __operator + (const vec3 v, const vec3 u) -{ - __asm vec4_add __retVal.xyz, v, u; -} - -vec3 __operator - (const vec3 v, const vec3 u) -{ - __asm vec4_subtract __retVal.xyz, v, u; -} - -vec3 __operator * (const vec3 v, const vec3 u) -{ - __asm vec4_multiply __retVal.xyz, v, u; -} - -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; -} - - -//// Basic vec4 operators - -vec4 __operator + (const vec4 v, const vec4 u) -{ - __asm vec4_add __retVal, v, u; -} - -vec4 __operator - (const vec4 v, const vec4 u) -{ - __asm vec4_subtract __retVal, v, u; -} - -vec4 __operator * (const vec4 v, const vec4 u) -{ - __asm vec4_multiply __retVal, v, u; -} - -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; -} - - - - -//// Basic vec2/float operators - -vec2 __operator + (const float a, const vec2 u) -{ - __asm vec4_add __retVal.xy, a, u.xy; -} - -vec2 __operator + (const vec2 v, const float b) -{ - __asm vec4_add __retVal.xy, v.xy, b; -} - -vec2 __operator - (const float a, const vec2 u) -{ - __asm vec4_subtract __retVal.xy, a, u.xy; -} - -vec2 __operator - (const vec2 v, const float b) -{ - __asm vec4_subtract __retVal.xy, v.xy, b; -} - -vec2 __operator * (const float a, const vec2 u) -{ - __asm vec4_multiply __retVal.xy, a, u.xy; -} - -vec2 __operator * (const vec2 v, const float b) -{ - __asm vec4_multiply __retVal.xy, v.xy, b; -} - -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, invU.xy; -} - -vec2 __operator / (const vec2 v, const float b) -{ - float invB; - __asm float_rcp invB, b; - __asm vec4_multiply __retVal.xy, v.xy, invB; -} - - -//// Basic vec3/float operators - -vec3 __operator + (const float a, const vec3 u) -{ - __asm vec4_add __retVal.xyz, a, u.xyz; -} - -vec3 __operator + (const vec3 v, const float b) -{ - __asm vec4_add __retVal.xyz, v.xyz, b; -} - -vec3 __operator - (const float a, const vec3 u) -{ - __asm vec4_subtract __retVal.xyz, a, u.xyz; -} - -vec3 __operator - (const vec3 v, const float b) -{ - __asm vec4_subtract __retVal.xyz, v.xyz, b; -} - -vec3 __operator * (const float a, const vec3 u) -{ - __asm vec4_multiply __retVal.xyz, a, u.xyz; -} - -vec3 __operator * (const vec3 v, const float b) -{ - __asm vec4_multiply __retVal.xyz, v.xyz, b; -} - -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, invU.xyz; -} - -vec3 __operator / (const vec3 v, const float b) -{ - float invB; - __asm float_rcp invB, b; - __asm vec4_multiply __retVal.xyz, v.xyz, invB; -} - - -//// Basic vec4/float operators - -vec4 __operator + (const float a, const vec4 u) -{ - __asm vec4_add __retVal, a, u; -} - -vec4 __operator + (const vec4 v, const float b) -{ - __asm vec4_add __retVal, v, b; -} - -vec4 __operator - (const float a, const vec4 u) -{ - __asm vec4_subtract __retVal, a, u; -} - -vec4 __operator - (const vec4 v, const float b) -{ - __asm vec4_subtract __retVal, v, b; -} - -vec4 __operator * (const float a, const vec4 u) -{ - __asm vec4_multiply __retVal, a, u; -} - -vec4 __operator * (const vec4 v, const float b) -{ - __asm vec4_multiply __retVal, v, b; -} - -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, invU; -} - -vec4 __operator / (const vec4 v, const float b) -{ - float invB; - __asm float_rcp invB, b; - __asm vec4_multiply __retVal, v, invB; -} - - - -//// Basic ivec2/int operators - -ivec2 __operator + (const int a, const ivec2 u) -{ - __retVal = ivec2(a) + u; -} - -ivec2 __operator + (const ivec2 v, const int b) -{ - __retVal = v + ivec2(b); -} - -ivec2 __operator - (const int a, const ivec2 u) -{ - __retVal = ivec2(a) - u; -} - -ivec2 __operator - (const ivec2 v, const int b) -{ - __retVal = v - ivec2(b); -} - -ivec2 __operator * (const int a, const ivec2 u) -{ - __retVal = ivec2(a) * u; -} - -ivec2 __operator * (const ivec2 v, const int b) -{ - __retVal = v * ivec2(b); -} - -ivec2 __operator / (const int a, const ivec2 u) -{ - __retVal = ivec2(a) / u; -} - -ivec2 __operator / (const ivec2 v, const int b) -{ - __retVal = v / ivec2(b); -} - - -//// Basic ivec3/int operators - -ivec3 __operator + (const int a, const ivec3 u) -{ - __retVal = ivec3(a) + u; -} - -ivec3 __operator + (const ivec3 v, const int b) -{ - __retVal = v + ivec3(b); -} - -ivec3 __operator - (const int a, const ivec3 u) -{ - __retVal = ivec3(a) - u; -} - -ivec3 __operator - (const ivec3 v, const int b) -{ - __retVal = v - ivec3(b); -} - -ivec3 __operator * (const int a, const ivec3 u) -{ - __retVal = ivec3(a) * u; -} - -ivec3 __operator * (const ivec3 v, const int b) -{ - __retVal = v * ivec3(b); -} - -ivec3 __operator / (const int a, const ivec3 u) -{ - __retVal = ivec3(a) / u; -} - -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; -} - -float __operator - (const float a) -{ - __asm vec4_negate __retVal.x, a; -} - -vec2 __operator - (const vec2 v) -{ - __asm vec4_negate __retVal.xy, v.xy; -} - -vec3 __operator - (const vec3 v) -{ - __asm vec4_negate __retVal.xyz, v.xyz; -} - -vec4 __operator - (const vec4 v) -{ - __asm vec4_negate __retVal, v; -} - -mat2 __operator - (const mat2 m) -{ - __retVal[0] = -m[0]; - __retVal[1] = -m[1]; -} - -mat3 __operator - (const mat3 m) -{ - __retVal[0] = -m[0]; - __retVal[1] = -m[1]; - __retVal[2] = -m[2]; -} - -mat4 __operator - (const mat4 m) -{ - __retVal[0] = -m[0]; - __retVal[1] = -m[1]; - __retVal[2] = -m[2]; - __retVal[3] = -m[3]; -} - - - -//// dot product - -float dot(const float a, const float b) -{ - __retVal = a * b; -} - -float dot(const vec2 a, const vec2 b) -{ - __retVal = a.x * b.x + a.y * b.y; -} - -float dot(const vec3 a, const vec3 b) -{ - __asm vec3_dot __retVal, a, b; -} - -float dot(const vec4 a, const vec4 b) -{ - __asm vec4_dot __retVal, a, b; -} - - - -//// int assignment operators - -int __operator += (inout int a, const int b) -{ - a = a + b; - return a; -} - -int __operator -= (inout int a, const int b) -{ - a = a - b; - return a; -} - -int __operator *= (inout int a, const int b) -{ - a = a * b; - return a; -} - -int __operator /= (inout int a, const int b) -{ - a = a / b; - return a; -} - - -//// ivec2 assignment operators - -ivec2 __operator += (inout ivec2 v, const ivec2 u) -{ - v = v + u; - return v; -} - -ivec2 __operator -= (inout ivec2 v, const ivec2 u) -{ - v = v - u; - return v; -} - -ivec2 __operator *= (inout ivec2 v, const ivec2 u) -{ - v = v * u; - return v; -} - -ivec2 __operator /= (inout ivec2 v, const ivec2 u) -{ - v = v / u; - return v; -} - - -//// ivec3 assignment operators - -ivec3 __operator += (inout ivec3 v, const ivec3 u) -{ - v = v + u; - return v; -} - -ivec3 __operator -= (inout ivec3 v, const ivec3 u) -{ - v = v - u; - return v; -} - -ivec3 __operator *= (inout ivec3 v, const ivec3 u) -{ - v = v * u; - return v; -} - -ivec3 __operator /= (inout ivec3 v, const ivec3 u) -{ - v = v / u; - return v; -} - - -//// ivec4 assignment operators - -ivec4 __operator += (inout ivec4 v, const ivec4 u) -{ - v = v + u; - return v; -} - -ivec4 __operator -= (inout ivec4 v, const ivec4 u) -{ - v = v - u; - return v; -} - -ivec4 __operator *= (inout ivec4 v, const ivec4 u) -{ - v = v * u; - return v; -} - -ivec4 __operator /= (inout ivec4 v, const ivec4 u) -{ - v = v / u; - return v; -} - - -//// float assignment operators - -float __operator += (inout float a, const float b) -{ - a = a + b; - return a; -} - -float __operator -= (inout float a, const float b) -{ - a = a - b; - return a; -} - -float __operator *= (inout float a, const float b) -{ - a = a * b; - return a; -} - -float __operator /= (inout float a, const float b) -{ - a = a / b; - return a; -} - - -//// vec2 assignment operators - -vec2 __operator += (inout vec2 v, const vec2 u) -{ - v = v + u; - return v; -} - -vec2 __operator -= (inout vec2 v, const vec2 u) -{ - v = v - u; - return v; -} - -vec2 __operator *= (inout vec2 v, const vec2 u) -{ - v = v * u; - return v; -} - -vec2 __operator /= (inout vec2 v, const vec2 u) -{ - v = v / u; - return v; -} - - -//// vec3 assignment operators - -vec3 __operator += (inout vec3 v, const vec3 u) -{ - v = v + u; - return v; -} - -vec3 __operator -= (inout vec3 v, const vec3 u) -{ - v = v - u; - return v; -} - -vec3 __operator *= (inout vec3 v, const vec3 u) -{ - v = v * u; - return v; -} - -vec3 __operator /= (inout vec3 v, const vec3 u) -{ - v = v / u; - return v; -} - - -//// vec4 assignment operators - -vec4 __operator += (inout vec4 v, const vec4 u) -{ - v = v + u; - return v; -} - -vec4 __operator -= (inout vec4 v, const vec4 u) -{ - v = v - u; - return v; -} - -vec4 __operator *= (inout vec4 v, const vec4 u) -{ - v = v * u; - return v; -} - -vec4 __operator /= (inout vec4 v, const vec4 u) -{ - v = v / u; - return v; -} - - - -//// ivec2/int assignment operators - -ivec2 __operator += (inout ivec2 v, const int a) -{ - v = v + ivec2(a); - return v; -} - -ivec2 __operator -= (inout ivec2 v, const int a) -{ - v = v - ivec2(a); - return v; -} - -ivec2 __operator *= (inout ivec2 v, const int a) -{ - v = v * ivec2(a); - return v; -} - -ivec2 __operator /= (inout ivec2 v, const int a) -{ - v = v / ivec2(a); - return v; -} - - -//// ivec3/int assignment operators - -ivec3 __operator += (inout ivec3 v, const int a) -{ - v = v + ivec3(a); - return v; -} - -ivec3 __operator -= (inout ivec3 v, const int a) -{ - v = v - ivec3(a); - return v; -} - -ivec3 __operator *= (inout ivec3 v, const int a) -{ - v = v * ivec3(a); - return v; -} - -ivec4 __operator /= (inout ivec3 v, const int a) -{ - v = v / ivec3(a); - return v; -} - - -//// ivec4/int assignment operators - -ivec4 __operator += (inout ivec4 v, const int a) -{ - v = v + ivec4(a); - return v; -} - -ivec4 __operator -= (inout ivec4 v, const int a) -{ - v = v - ivec4(a); - return v; -} - -ivec4 __operator *= (inout ivec4 v, const int a) -{ - v = v * ivec4(a); - return v; -} - -ivec4 __operator /= (inout ivec4 v, const int a) -{ - v = v / ivec4(a); - return v; -} - - - -//// vec2/float assignment operators - -vec2 __operator += (inout vec2 v, const float a) -{ - v = v + vec2(a); - return v; -} - -vec2 __operator -= (inout vec2 v, const float a) -{ - v = v - vec2(a); - return v; -} - -vec2 __operator *= (inout vec2 v, const float a) -{ - v = v * vec2(a); - return v; -} - -vec2 __operator /= (inout vec2 v, const float a) -{ - v = v / vec2(a); - return v; -} - - -//// vec3/float assignment operators - -vec3 __operator += (inout vec3 v, const float a) -{ - v = v + vec3(a); - return v; -} - -vec3 __operator -= (inout vec3 v, const float a) -{ - v = v - vec3(a); - return v; -} - -vec3 __operator *= (inout vec3 v, const float a) -{ - v = v * vec3(a); - return v; -} - -vec3 __operator /= (inout vec3 v, const float a) -{ - v = v / vec3(a); - return v; -} - - -//// vec4/float assignment operators - -vec4 __operator += (inout vec4 v, const float a) -{ - v = v + vec4(a); - return v; -} - -vec4 __operator -= (inout vec4 v, const float a) -{ - v = v - vec4(a); - return v; -} - -vec4 __operator *= (inout vec4 v, const float a) -{ - v = v * vec4(a); - return v; -} - -vec4 __operator /= (inout vec4 v, const float a) -{ - v = v / vec4(a); - return v; -} - - - - - -//// Basic mat2 operations - -mat2 __operator + (const mat2 m, const mat2 n) -{ - __retVal[0] = m[0] + n[0]; - __retVal[1] = m[1] + n[1]; -} - -mat2 __operator - (const mat2 m, const mat2 n) -{ - __retVal[0] = m[0] - n[0]; - __retVal[1] = m[1] - n[1]; -} - -mat2 __operator * (const mat2 m, const mat2 n) -{ - __retVal[0] = m[0] * n[0].xx + m[1] * n[0].yy; - __retVal[1] = m[0] * n[1].xx + m[1] * n[1].yy; -} - -mat2 __operator / (const mat2 m, const mat2 n) -{ - __retVal[0] = m[0] / n[0]; - __retVal[1] = m[1] / n[1]; -} - - -//// 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 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) -{ - __retVal[0] = m[0] * n[0].xxx + m[1] * n[0].yyy + m[2] * n[0].zzz; - __retVal[1] = m[0] * n[1].xxx + m[1] * n[1].yyy + m[2] * n[1].zzz; - __retVal[2] = m[0] * n[2].xxx + m[1] * n[2].yyy + m[2] * n[2].zzz; -} - -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) -{ - __retVal[0] = m[0] * n[0].xxxx + m[1] * n[0].yyyy + m[2] * n[0].zzzz + m[3] * n[0].wwww; - __retVal[1] = m[0] * n[1].xxxx + m[1] * n[1].yyyy + m[2] * n[1].zzzz + m[3] * n[1].wwww; - __retVal[2] = m[0] * n[2].xxxx + m[1] * n[2].yyyy + m[2] * n[2].zzzz + m[3] * n[2].wwww; - __retVal[3] = m[0] * n[3].xxxx + m[1] * n[3].yyyy + m[2] * n[3].zzzz + m[3] * n[3].wwww; -} - -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; -} - -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; -} - -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; -} - -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; -} - - -//// 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]; -} - -mat3 __operator + (const mat3 m, const float b) -{ - __retVal[0] = m[0] + b; - __retVal[1] = m[1] + b; - __retVal[2] = m[2] + b; -} - -mat3 __operator - (const float a, const mat3 n) -{ - __retVal[0] = a - n[0]; - __retVal[1] = a - n[1]; - __retVal[2] = a - n[2]; -} - -mat3 __operator - (const mat3 m, const float b) -{ - __retVal[0] = m[0] - b; - __retVal[1] = m[1] - b; - __retVal[2] = m[2] - b; -} - -mat3 __operator * (const float a, const mat3 n) -{ - __retVal[0] = a * n[0]; - __retVal[1] = a * n[1]; - __retVal[2] = a * n[2]; -} - -mat3 __operator * (const mat3 m, const float b) -{ - __retVal[0] = m[0] * b; - __retVal[1] = m[1] * b; - __retVal[2] = m[2] * b; -} - -mat3 __operator / (const float a, const mat3 n) -{ - __retVal[0] = a / n[0]; - __retVal[1] = a / n[1]; - __retVal[2] = a / n[2]; -} - -mat3 __operator / (const mat3 m, const float b) -{ - __retVal[0] = m[0] / b; - __retVal[1] = m[1] / b; - __retVal[2] = m[2] / b; -} - - -//// 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]; -} - -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; -} - -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) -{ - __retVal = m[0] * v.xx - + m[1] * v.yy; -} - -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) -{ - __retVal = m[0] * v.xxx - + m[1] * v.yyy - + m[2] * v.zzz; -} - -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) -{ - __retVal = m[0] * v.xxxx - + m[1] * v.yyyy - + m[2] * v.zzzz - + m[3] * v.wwww; -} - -vec4 __operator * (const vec4 v, const mat4 m) -{ - __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 - -mat2 __operator += (inout mat2 m, const mat2 n) -{ - m[0] = m[0] + n[0]; - m[1] = m[1] + n[1]; - return m; -} - -mat2 __operator -= (inout mat2 m, const mat2 n) -{ - m[0] = m[0] - n[0]; - m[1] = m[1] - n[1]; - return m; -} - -mat2 __operator *= (inout mat2 m, const mat2 n) -{ - m = m * n; - return m; -} - -mat2 __operator /= (inout mat2 m, const mat2 n) -{ - m[0] = m[0] / n[0]; - m[1] = m[1] / n[1]; - return m; -} - - -//// mat3 assignment operators - -mat3 __operator += (inout mat3 m, const mat3 n) -{ - m[0] = m[0] + n[0]; - m[1] = m[1] + n[1]; - m[2] = m[2] + n[2]; - return m; -} - -mat3 __operator -= (inout mat3 m, const mat3 n) -{ - m[0] = m[0] - n[0]; - m[1] = m[1] - n[1]; - m[2] = m[2] - n[2]; - return m; -} - -mat3 __operator *= (inout mat3 m, const mat3 n) -{ - m = m * n; - return m; -} - -mat3 __operator /= (inout mat3 m, const mat3 n) -{ - m[0] = m[0] / n[0]; - m[1] = m[1] / n[1]; - m[2] = m[2] / n[2]; - return m; -} - - -// mat4 assignment operators - -mat4 __operator += (inout mat4 m, const mat4 n) -{ - m[0] = m[0] + n[0]; - m[1] = m[1] + n[1]; - m[2] = m[2] + n[2]; - m[3] = m[3] + n[3]; - return m; -} - -mat4 __operator -= (inout mat4 m, const mat4 n) -{ - m[0] = m[0] - n[0]; - m[1] = m[1] - n[1]; - m[2] = m[2] - n[2]; - m[3] = m[3] - n[3]; - return m; -} - -mat4 __operator *= (inout mat4 m, const mat4 n) -{ - m = m * n; - return m; -} - -mat4 __operator /= (inout mat4 m, const mat4 n) -{ - m[0] = m[0] / n[0]; - m[1] = m[1] / n[1]; - m[2] = m[2] / n[2]; - m[3] = m[3] / n[3]; - return m; -} - - -//// mat2/float assignment operators - -mat2 __operator += (inout mat2 m, const float a) -{ - vec2 v = vec2(a); - m[0] = m[0] + v; - m[1] = m[1] + v; - return m; -} - -mat2 __operator -= (inout mat2 m, const float a) -{ - vec2 v = vec2(a); - m[0] = m[0] - v; - m[1] = m[1] - v; - return m; -} - -mat2 __operator *= (inout mat2 m, const float a) -{ - vec2 v = vec2(a); - m[0] = m[0] * v; - m[1] = m[1] * v; - return m; -} - -mat2 __operator /= (inout mat2 m, const float a) -{ - vec2 v = vec2(1.0 / a); - m[0] = m[0] * v; - m[1] = m[1] * v; - return m; -} - - -//// mat3/float assignment operators - -mat3 __operator += (inout mat3 m, const float a) -{ - vec3 v = vec3(a); - m[0] = m[0] + v; - m[1] = m[1] + v; - m[2] = m[2] + v; - return m; -} - -mat3 __operator -= (inout mat3 m, const float a) -{ - vec3 v = vec3(a); - m[0] = m[0] - v; - m[1] = m[1] - v; - m[2] = m[2] - v; - return m; -} - -mat3 __operator *= (inout mat3 m, const float a) -{ - vec3 v = vec3(a); - m[0] = m[0] * v; - m[1] = m[1] * v; - m[2] = m[2] * v; - return m; -} - -mat3 __operator /= (inout mat3 m, const float a) -{ - vec3 v = vec3(1.0 / a); - m[0] = m[0] * v; - m[1] = m[1] * v; - m[2] = m[2] * v; - return m; -} - - -//// mat4/float assignment operators - -mat4 __operator += (inout mat4 m, const float a) -{ - vec4 v = vec4(a); - m[0] = m[0] + v; - m[1] = m[1] + v; - m[2] = m[2] + v; - m[3] = m[3] + v; - return m; -} - -mat4 __operator -= (inout mat4 m, const float a) -{ - vec4 v = vec4(a); - m[0] = m[0] - v; - m[1] = m[1] - v; - m[2] = m[2] - v; - m[3] = m[3] - v; - return m; -} - -mat4 __operator *= (inout mat4 m, const float a) -{ - vec4 v = vec4(a); - m[0] = m[0] * v; - m[1] = m[1] * v; - m[2] = m[2] * v; - m[3] = m[3] * v; - return m; -} - -mat4 __operator /= (inout mat4 m, const float a) -{ - vec4 v = vec4(1.0 / a); - m[0] = m[0] * v; - m[1] = m[1] * v; - m[2] = m[2] * v; - m[3] = m[3] * v; - return m; -} - - - -//// vec/mat assignment operators - -vec2 __operator *= (inout vec2 v, const mat2 m) -{ - v = v * m; - return v; -} - -vec3 __operator *= (inout vec3 v, const mat3 m) -{ - v = v * m; - return v; -} - -vec4 __operator *= (inout vec4 v, const mat4 m) -{ - v = v * m; - return v; -} - - - -//// pre-decrement operators - -int __operator --(inout int a) -{ - a = a - 1; - __retVal = a; -} - -ivec2 __operator --(inout ivec2 v) -{ - v = v - ivec2(1); - __retVal = v; -} - -ivec3 __operator --(inout ivec3 v) -{ - v = v - ivec3(1); - __retVal = v; -} - -ivec4 __operator --(inout ivec4 v) -{ - v = v - ivec4(1); - __retVal = v; -} - - -float __operator --(inout float a) -{ - a = a - 1.0; - __retVal = a; -} - -vec2 __operator --(inout vec2 v) -{ - v = v - vec2(1.0); - __retVal = v; -} - -vec3 __operator --(inout vec3 v) -{ - v = v - vec3(1.0); - __retVal = v; -} - -vec4 __operator --(inout vec4 v) -{ - v = v - vec4(1.0); - __retVal = v; -} - - -mat2 __operator --(inout mat2 m) -{ - m[0] = m[0] - vec2(1.0); - m[1] = m[1] - vec2(1.0); - __retVal = m; -} - -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; -} - -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; -} - - -//// pre-increment operators - -int __operator ++(inout int a) -{ - a = a + 1; - __retVal = a; -} - -ivec2 __operator ++(inout ivec2 v) -{ - v = v + ivec2(1); - __retVal = v; -} - -ivec3 __operator ++(inout ivec3 v) -{ - v = v + ivec3(1); - __retVal = v; -} - -ivec4 __operator ++(inout ivec4 v) -{ - v = v + ivec4(1); - __retVal = v; -} - - -float __operator ++(inout float a) -{ - a = a + 1.0; - __retVal = a; -} - -vec2 __operator ++(inout vec2 v) -{ - v = v + vec2(1.0); - __retVal = v; -} - -vec3 __operator ++(inout vec3 v) -{ - v = v + vec3(1.0); - __retVal = v; -} - -vec4 __operator ++(inout vec4 v) -{ - v = v + vec4(1.0); - __retVal = v; -} - - -mat2 __operator ++(inout mat2 m) -{ - m[0] = m[0] + vec2(1.0); - m[1] = m[1] + vec2(1.0); - __retVal = m; -} - -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; -} - -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; -} - - - -//// post-decrement - -int __postDecr(inout int a) -{ - __retVal = a; - a = a - 1; -} - -ivec2 __postDecr(inout ivec2 v) -{ - __retVal = v; - v = v - ivec2(1); -} - -ivec3 __postDecr(inout ivec3 v) -{ - __retVal = v; - v = v - ivec3(1); -} - -ivec4 __postDecr(inout ivec4 v) -{ - __retVal = v; - v = v - ivec4(1); -} - - -float __postDecr(inout float a) -{ - __retVal = a; - a = a - 1.0; -} - -vec2 __postDecr(inout vec2 v) -{ - __retVal = v; - v = v - vec2(1.0); -} - -vec3 __postDecr(inout vec3 v) -{ - __retVal = v; - v = v - vec3(1.0); -} - -vec4 __postDecr(inout vec4 v) -{ - __retVal = v; - v = v - vec4(1.0); -} - - -mat2 __postDecr(inout mat2 m) -{ - __retVal = m; - m[0] = m[0] - vec2(1.0); - m[1] = m[1] - vec2(1.0); -} - -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 __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); -} - - -//// post-increment - -float __postIncr(inout float a) -{ - __retVal = a; - a = a + 1; -} - -vec2 __postIncr(inout vec2 v) -{ - __retVal = v; - v = v + vec2(1.0); -} - -vec3 __postIncr(inout vec3 v) -{ - __retVal = v; - v = v + vec3(1.0); -} - -vec4 __postIncr(inout vec4 v) -{ - __retVal = v; - v = v + vec4(1.0); -} - - -int __postIncr(inout int a) -{ - __retVal = a; - a = a + 1; -} - -ivec2 __postIncr(inout ivec2 v) -{ - __retVal = v; - v = v + ivec2(1); -} - -ivec3 __postIncr(inout ivec3 v) -{ - __retVal = v; - v = v + ivec3(1); -} - -ivec4 __postIncr(inout ivec4 v) -{ - __retVal = v; - v = v + ivec3(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 __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 __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; -} - - - -//// 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); -} - -bool __operator > (const float a, const float b) { - bool c; - __asm float_less c, b, a; - return c; -} - -bool __operator > (const int a, const int b) { - return float (a) > float (b); -} - -bool __operator >= (const float a, const float b) { - bool g, e; - __asm float_less g, b, a; - __asm float_equal e, a, b; - return g || e; -} - -bool __operator >= (const int a, const int b) { - return float (a) >= float (b); -} - -bool __operator <= (const float a, const float b) { - bool g, e; - __asm float_less g, a, b; - __asm float_equal e, a, b; - return g || e; -} - -bool __operator <= (const int a, const int b) { - return float (a) <= float (b); -} - - - -// -// MESA-specific extension functions. -// - -void printMESA (const float f) { - __asm float_print f; -} - -void printMESA (const int i) { - __asm int_print i; -} - -void printMESA (const bool b) { - __asm bool_print b; -} - -void printMESA (const vec2 v) { - printMESA (v.x); - printMESA (v.y); -} - -void printMESA (const vec3 v) { - printMESA (v.x); - printMESA (v.y); - printMESA (v.z); -} - -void printMESA (const vec4 v) { - printMESA (v.x); - printMESA (v.y); - printMESA (v.z); - printMESA (v.w); -} - -void printMESA (const ivec2 v) { - printMESA (v.x); - printMESA (v.y); -} - -void printMESA (const ivec3 v) { - printMESA (v.x); - printMESA (v.y); - printMESA (v.z); -} - -void printMESA (const ivec4 v) { - printMESA (v.x); - printMESA (v.y); - printMESA (v.z); - printMESA (v.w); -} - -void printMESA (const bvec2 v) { - printMESA (v.x); - printMESA (v.y); -} - -void printMESA (const bvec3 v) { - printMESA (v.x); - printMESA (v.y); - printMESA (v.z); -} - -void printMESA (const bvec4 v) { - printMESA (v.x); - printMESA (v.y); - printMESA (v.z); - printMESA (v.w); -} - -void printMESA (const mat2 m) { - printMESA (m[0]); - printMESA (m[1]); -} - -void printMESA (const mat3 m) { - printMESA (m[0]); - printMESA (m[1]); - printMESA (m[2]); -} - -void printMESA (const mat4 m) { - printMESA (m[0]); - printMESA (m[1]); - printMESA (m[2]); - printMESA (m[3]); -} - -void printMESA (const sampler1D e) { - __asm int_print e; -} - -void printMESA (const sampler2D e) { - __asm int_print e; -} - -void printMESA (const sampler3D e) { - __asm int_print e; -} - -void printMESA (const samplerCube e) { - __asm int_print e; -} - -void printMESA (const sampler1DShadow e) { - __asm int_print e; -} - -void printMESA (const sampler2DShadow e) { - __asm int_print e; -} - diff --git a/mesalib/src/mesa/shader/slang/library/slang_fragment_builtin.gc b/mesalib/src/mesa/shader/slang/library/slang_fragment_builtin.gc deleted file mode 100644 index 54a80ea0e..000000000 --- a/mesalib/src/mesa/shader/slang/library/slang_fragment_builtin.gc +++ /dev/null @@ -1,299 +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. - */ - -// -// From Shader Spec, ver. 1.10, rev. 59 -// - -__fixed_input vec4 gl_FragCoord; -__fixed_input bool gl_FrontFacing; -__fixed_output vec4 gl_FragColor; -__fixed_output vec4 gl_FragData[gl_MaxDrawBuffers]; -__fixed_output float gl_FragDepth; - -varying vec4 gl_Color; -varying vec4 gl_SecondaryColor; -varying vec4 gl_TexCoord[gl_MaxTextureCoords]; -varying float gl_FogFragCoord; - - - -//// 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_tex_1d_bias __retVal, sampler, coord4; -} - -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_tex_1d_bias __retVal, sampler, pcoord; -} - -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_tex_1d_bias __retVal, sampler, pcoord; -} - - - - -vec4 texture2D(const sampler2D sampler, const vec2 coord, const float bias) -{ - vec4 coord4; - coord4.xy = coord.xy; - coord4.w = bias; - __asm vec4_tex_2d_bias __retVal, sampler, coord4; -} - -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_tex_2d_bias __retVal, sampler, pcoord; -} - -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_tex_2d_bias __retVal, sampler, pcoord; -} - - - - -vec4 texture3D(const sampler3D sampler, const vec3 coord, const float bias) -{ - vec4 coord4; - coord4.xyz = coord.xyz; - coord4.w = bias; - __asm vec4_tex_3d_bias __retVal, sampler, coord4; -} - -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_tex_3d_bias __retVal, sampler, pcoord; -} - - - - -vec4 textureCube(const samplerCube sampler, const vec3 coord, const float bias) -{ - vec4 coord4; - coord4.xyz = coord; - coord4.w = bias; - __asm vec4_tex_cube __retVal, sampler, coord4; -} - - - -vec4 shadow1D(const sampler1DShadow sampler, const vec3 coord, const float bias) -{ - vec4 coord4; - coord4.xyz = coord; - coord4.w = bias; - __asm vec4_tex_1d_bias_shadow __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_tex_1d_bias_shadow __retVal, sampler, pcoord; -} - -vec4 shadow2D(const sampler2DShadow sampler, const vec3 coord, const float bias) -{ - vec4 coord4; - coord4.xyz = coord; - coord4.w = bias; - __asm vec4_tex_2d_bias_shadow __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_tex_2d_bias_shadow __retVal, sampler, pcoord; -} - - - -//// GL_EXT_texture_array - -vec4 texture1DArray(const sampler1DArray sampler, const vec2 coord) -{ - vec4 coord4; - coord4.xy = coord; - __asm vec4_tex_1d_array __retVal, sampler, coord4; -} - -vec4 texture1DArray(const sampler1DArray sampler, const vec2 coord, const float bias) -{ - vec4 coord4; - coord4.xy = coord; - coord4.w = bias; - __asm vec4_tex_1d_array_bias __retVal, sampler, coord4; -} - -vec4 texure2DArray(const sampler2DArray sampler, const vec3 coord) -{ - vec4 coord4; - coord4.xyz = coord; - __asm vec4_tex_2d_array __retVal, sampler, coord4; -} - -vec4 texture2DArray(const sampler2DArray sampler, const vec3 coord, const float bias) -{ - vec4 coord4; - coord4.xyz = coord; - coord4.w = bias; - __asm vec4_tex_2d_array_bias __retVal, sampler, coord4; -} - -vec4 shadow1DArray(const sampler1DArrayShadow sampler, const vec2 coord) -{ - vec4 coord4; - coord4.xy = coord; - __asm vec4_tex_1d_array_shadow __retVal, sampler, coord4; -} - -vec4 shadow1DArray(const sampler1DArrayShadow sampler, const vec2 coord, const float bias) -{ - vec4 coord4; - coord4.xy = coord; - coord4.w = bias; - __asm vec4_tex_1d_array_bias_shadow __retVal, sampler, coord4; -} - -vec4 shadow2DArray(const sampler2DArrayShadow sampler, const vec3 coord) -{ - vec4 coord4; - coord4.xyz = coord; - __asm vec4_tex_2d_array_shadow __retVal, sampler, coord4; -} - -vec4 shadow2DArray(const sampler2DArrayShadow sampler, const vec3 coord, const float bias) -{ - vec4 coord4; - coord4.xyz = coord; - coord4.w = bias; - __asm vec4_tex_2d_array_bias_shadow __retVal, sampler, coord4; -} - - - -// -// 8.8 Fragment Processing Functions -// - -float dFdx(const float p) -{ - __asm vec4_ddx __retVal.x, p.xxxx; -} - -vec2 dFdx(const vec2 p) -{ - __asm vec4_ddx __retVal.xy, p.xyyy; -} - -vec3 dFdx(const vec3 p) -{ - __asm vec4_ddx __retVal.xyz, p.xyzz; -} - -vec4 dFdx(const vec4 p) -{ - __asm vec4_ddx __retVal, p; -} - -float dFdy(const float p) -{ - __asm vec4_ddy __retVal.x, p.xxxx; -} - -vec2 dFdy(const vec2 p) -{ - __asm vec4_ddy __retVal.xy, p.xyyy; -} - -vec3 dFdy(const vec3 p) -{ - __asm vec4_ddy __retVal.xyz, p.xyzz; -} - -vec4 dFdy(const vec4 p) -{ - __asm vec4_ddy __retVal, p; -} - -float fwidth (const float p) -{ - // XXX hand-write with __asm - 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(const vec3 p) -{ - // XXX hand-write with __asm - 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/mesalib/src/mesa/shader/slang/library/slang_vertex_builtin.gc b/mesalib/src/mesa/shader/slang/library/slang_vertex_builtin.gc deleted file mode 100644 index 0c67c2ef2..000000000 --- a/mesalib/src/mesa/shader/slang/library/slang_vertex_builtin.gc +++ /dev/null @@ -1,210 +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. - */ - -// -// From Shader Spec, ver. 1.10, rev. 59 -// - -__fixed_output vec4 gl_Position; -__fixed_output float gl_PointSize; -__fixed_output vec4 gl_ClipVertex; - -attribute vec4 gl_Color; -attribute vec4 gl_SecondaryColor; -attribute vec3 gl_Normal; -attribute vec4 gl_Vertex; -attribute vec4 gl_MultiTexCoord0; -attribute vec4 gl_MultiTexCoord1; -attribute vec4 gl_MultiTexCoord2; -attribute vec4 gl_MultiTexCoord3; -attribute vec4 gl_MultiTexCoord4; -attribute vec4 gl_MultiTexCoord5; -attribute vec4 gl_MultiTexCoord6; -attribute vec4 gl_MultiTexCoord7; -attribute float gl_FogCoord; - -varying vec4 gl_FrontColor; -varying vec4 gl_BackColor; -varying vec4 gl_FrontSecondaryColor; -varying vec4 gl_BackSecondaryColor; -varying vec4 gl_TexCoord[gl_MaxTextureCoords]; -varying float gl_FogFragCoord; - -// -// Geometric Functions -// - -vec4 ftransform() -{ - __retVal = gl_ModelViewProjectionMatrix[0] * gl_Vertex.xxxx - + gl_ModelViewProjectionMatrix[1] * gl_Vertex.yyyy - + gl_ModelViewProjectionMatrix[2] * gl_Vertex.zzzz - + gl_ModelViewProjectionMatrix[3] * gl_Vertex.wwww; -} - - - -// -// 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(const sampler1D sampler, const float coord, const float lod) -{ - vec4 coord4; - coord4.x = coord; - coord4.w = lod; - __asm vec4_tex_1d_bias __retVal, sampler, coord4; -} - -vec4 texture1DProjLod(const sampler1D sampler, const vec2 coord, const float lod) -{ - vec4 pcoord; - pcoord.x = coord.x / coord.y; - pcoord.w = lod; - __asm vec4_tex_1d_bias __retVal, sampler, pcoord; -} - -vec4 texture1DProjLod(const sampler1D sampler, const vec4 coord, const float lod) -{ - vec4 pcoord; - pcoord.x = coord.x / coord.z; - pcoord.w = lod; - __asm vec4_tex_1d_bias __retVal, sampler, pcoord; -} - - - -vec4 texture2DLod(const sampler2D sampler, const vec2 coord, const float lod) -{ - vec4 coord4; - coord4.xy = coord.xy; - coord4.w = lod; - __asm vec4_tex_2d_bias __retVal, sampler, coord4; -} - -vec4 texture2DProjLod(const sampler2D sampler, const vec3 coord, const float lod) -{ - vec4 pcoord; - pcoord.xy = coord.xy / coord.z; - pcoord.w = lod; - __asm vec4_tex_2d_bias __retVal, sampler, pcoord; -} - -vec4 texture2DProjLod(const sampler2D sampler, const vec4 coord, const float lod) -{ - vec4 pcoord; - pcoord.xy = coord.xy / coord.z; - pcoord.w = lod; - __asm vec4_tex_2d_bias __retVal, sampler, pcoord; -} - - -vec4 texture3DLod(const sampler3D sampler, const vec3 coord, const float lod) -{ - vec4 coord4; - coord4.xyz = coord.xyz; - coord4.w = lod; - __asm vec4_tex_3d_bias __retVal, sampler, coord4; -} - -vec4 texture3DProjLod(const sampler3D sampler, const vec4 coord, const float lod) -{ - // do projection here (there's no vec4_tex_3d_bias_proj instruction) - vec4 pcoord; - pcoord.xyz = coord.xyz / coord.w; - pcoord.w = lod; - __asm vec4_tex_3d_bias __retVal, sampler, pcoord; -} - - -vec4 textureCubeLod(const samplerCube sampler, const vec3 coord, const float lod) -{ - vec4 coord4; - coord4.xyz = coord; - coord4.w = lod; - __asm vec4_tex_cube __retVal, sampler, coord4; -} - - -vec4 shadow1DLod(const sampler1DShadow sampler, const vec3 coord, const float lod) -{ - vec4 coord4; - coord4.xyz = coord; - coord4.w = lod; - __asm vec4_tex_1d_bias_shadow __retVal, sampler, coord4; -} - -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_tex_1d_bias_shadow __retVal, sampler, pcoord; -} - - -vec4 shadow2DLod(const sampler2DShadow sampler, const vec3 coord, const float lod) -{ - vec4 coord4; - coord4.xyz = coord; - coord4.w = lod; - __asm vec4_tex_2d_bias_shadow __retVal, sampler, coord4; -} - -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_tex_2d_bias_shadow __retVal, sampler, pcoord; -} - - -//// GL_EXT_texture_array - -vec4 texture1DArrayLod(const sampler1DArray sampler, const vec2 coord, const float lod) -{ - vec4 coord4; - coord4.xy = coord; - coord4.w = lod; - __asm vec4_tex_1d_array_bias __retVal, sampler, coord4; -} - - -vec4 texture2DArrayLod(const sampler2DArray sampler, const vec3 coord, const float lod) -{ - vec4 coord4; - coord4.xyz = coord; - coord4.w = lod; - __asm vec4_tex_2d_array_bias __retVal, sampler, coord4; -} - diff --git a/mesalib/src/mesa/shader/slang/slang_builtin.c b/mesalib/src/mesa/shader/slang/slang_builtin.c deleted file mode 100644 index 791e75152..000000000 --- a/mesalib/src/mesa/shader/slang/slang_builtin.c +++ /dev/null @@ -1,897 +0,0 @@ -/* - * Mesa 3-D graphics library - * Version: 7.3 - * - * Copyright (C) 2005-2007 Brian Paul All Rights Reserved. - * Copyright (C) 2008 VMware, 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. - */ - -/** - * \file slang_builtin.c - * Resolve built-in uniform vars. - * \author Brian Paul - */ - -#include "main/imports.h" -#include "main/mtypes.h" -#include "shader/program.h" -#include "shader/prog_instruction.h" -#include "shader/prog_parameter.h" -#include "shader/prog_statevars.h" -#include "shader/slang/slang_ir.h" -#include "shader/slang/slang_builtin.h" - - -/** special state token (see below) */ -#define STATE_ARRAY ((gl_state_index) 0xfffff) - - -/** - * 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 }, - - { "gl_NormalMatrix", STATE_MODELVIEW_MATRIX, STATE_MATRIX_INVERSE }, - - { 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) { - /* texture_matrix[index1][index2] */ - tokens[1] = index1 >= 0 ? index1 : 0; /* which texture matrix */ - index1 = index2; /* move matrix row value to index1 */ - } - if (index1 < 0) { - /* index1 is unused: prevent extra addition at end of function */ - index1 = 0; - } - } - else if (strcmp(var, "gl_DepthRange") == 0) { - tokens[0] = STATE_DEPTH_RANGE; - assert(field); - 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) { - if (index1 < 0) - return -1; - tokens[0] = STATE_CLIPPLANE; - tokens[1] = index1; - } - else if (strcmp(var, "gl_Point") == 0) { - assert(field); - 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; - assert(field); - 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) { - if (!field || index1 < 0) - return -1; - - 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, "sceneColor") == 0) { - tokens[0] = STATE_LIGHTMODEL_SCENECOLOR; - tokens[1] = 0; - } - else { - return -1; - } - } - else if (strcmp(var, "gl_BackLightModelProduct") == 0) { - if (strcmp(field, "sceneColor") == 0) { - tokens[0] = STATE_LIGHTMODEL_SCENECOLOR; - tokens[1] = 1; - } - else { - return -1; - } - } - else if (strcmp(var, "gl_FrontLightProduct") == 0 || - strcmp(var, "gl_BackLightProduct") == 0) { - if (index1 < 0 || !field) - return -1; - - 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) { - if (index1 < 0) - return -1; - tokens[0] = STATE_TEXENV_COLOR; - tokens[1] = index1; - } - else if (strcmp(var, "gl_EyePlaneS") == 0) { - if (index1 < 0) - return -1; - tokens[0] = STATE_TEXGEN; - tokens[1] = index1; /* tex unit */ - tokens[2] = STATE_TEXGEN_EYE_S; - } - else if (strcmp(var, "gl_EyePlaneT") == 0) { - if (index1 < 0) - return -1; - tokens[0] = STATE_TEXGEN; - tokens[1] = index1; /* tex unit */ - tokens[2] = STATE_TEXGEN_EYE_T; - } - else if (strcmp(var, "gl_EyePlaneR") == 0) { - if (index1 < 0) - return -1; - tokens[0] = STATE_TEXGEN; - tokens[1] = index1; /* tex unit */ - tokens[2] = STATE_TEXGEN_EYE_R; - } - else if (strcmp(var, "gl_EyePlaneQ") == 0) { - if (index1 < 0) - return -1; - tokens[0] = STATE_TEXGEN; - tokens[1] = index1; /* tex unit */ - tokens[2] = STATE_TEXGEN_EYE_Q; - } - else if (strcmp(var, "gl_ObjectPlaneS") == 0) { - if (index1 < 0) - return -1; - tokens[0] = STATE_TEXGEN; - tokens[1] = index1; /* tex unit */ - tokens[2] = STATE_TEXGEN_OBJECT_S; - } - else if (strcmp(var, "gl_ObjectPlaneT") == 0) { - if (index1 < 0) - return -1; - tokens[0] = STATE_TEXGEN; - tokens[1] = index1; /* tex unit */ - tokens[2] = STATE_TEXGEN_OBJECT_T; - } - else if (strcmp(var, "gl_ObjectPlaneR") == 0) { - if (index1 < 0) - return -1; - tokens[0] = STATE_TEXGEN; - tokens[1] = index1; /* tex unit */ - tokens[2] = STATE_TEXGEN_OBJECT_R; - } - else if (strcmp(var, "gl_ObjectPlaneQ") == 0) { - if (index1 < 0) - return -1; - 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; - } -} - - - -/** - * Given a variable name and datatype, emit uniform/constant buffer - * entries which will store that state variable. - * For example, if name="gl_LightSource" we'll emit 64 state variable - * vectors/references and return position where that data starts. This will - * allow run-time array indexing into the light source array. - * - * Note that this is a recursive function. - * - * \return -1 if error, else index of start of data in the program parameter list - */ -static GLint -emit_statevars(const char *name, int array_len, - const slang_type_specifier *type, - gl_state_index tokens[STATE_LENGTH], - struct gl_program_parameter_list *paramList) -{ - if (type->type == SLANG_SPEC_ARRAY) { - GLint i, pos = -1; - assert(array_len > 0); - if (strcmp(name, "gl_ClipPlane") == 0) { - tokens[0] = STATE_CLIPPLANE; - } - else if (strcmp(name, "gl_LightSource") == 0) { - tokens[0] = STATE_LIGHT; - } - else if (strcmp(name, "gl_FrontLightProduct") == 0) { - tokens[0] = STATE_LIGHTPROD; - tokens[2] = 0; /* front */ - } - else if (strcmp(name, "gl_BackLightProduct") == 0) { - tokens[0] = STATE_LIGHTPROD; - tokens[2] = 1; /* back */ - } - else if (strcmp(name, "gl_TextureEnvColor") == 0) { - tokens[0] = STATE_TEXENV_COLOR; - } - else if (strcmp(name, "gl_EyePlaneS") == 0) { - tokens[0] = STATE_TEXGEN; - tokens[2] = STATE_TEXGEN_EYE_S; - } - else if (strcmp(name, "gl_EyePlaneT") == 0) { - tokens[0] = STATE_TEXGEN; - tokens[2] = STATE_TEXGEN_EYE_T; - } - else if (strcmp(name, "gl_EyePlaneR") == 0) { - tokens[0] = STATE_TEXGEN; - tokens[2] = STATE_TEXGEN_EYE_R; - } - else if (strcmp(name, "gl_EyePlaneQ") == 0) { - tokens[0] = STATE_TEXGEN; - tokens[2] = STATE_TEXGEN_EYE_Q; - } - else if (strcmp(name, "gl_ObjectPlaneS") == 0) { - tokens[0] = STATE_TEXGEN; - tokens[2] = STATE_TEXGEN_OBJECT_S; - } - else if (strcmp(name, "gl_ObjectPlaneT") == 0) { - tokens[0] = STATE_TEXGEN; - tokens[2] = STATE_TEXGEN_OBJECT_T; - } - else if (strcmp(name, "gl_ObjectPlaneR") == 0) { - tokens[0] = STATE_TEXGEN; - tokens[2] = STATE_TEXGEN_OBJECT_R; - } - else if (strcmp(name, "gl_ObjectPlaneQ") == 0) { - tokens[0] = STATE_TEXGEN; - tokens[2] = STATE_TEXGEN_OBJECT_Q; - } - else { - return -1; /* invalid array name */ - } - for (i = 0; i < array_len; i++) { - GLint p; - tokens[1] = i; - p = emit_statevars(NULL, 0, type->_array, tokens, paramList); - if (i == 0) - pos = p; - } - return pos; - } - else if (type->type == SLANG_SPEC_STRUCT) { - const slang_variable_scope *fields = type->_struct->fields; - GLuint i, pos = 0; - for (i = 0; i < fields->num_variables; i++) { - const slang_variable *var = fields->variables[i]; - GLint p = emit_statevars(var->a_name, 0, &var->type.specifier, - tokens, paramList); - if (i == 0) - pos = p; - } - return pos; - } - else { - GLint pos; - assert(type->type == SLANG_SPEC_VEC4 || - type->type == SLANG_SPEC_VEC3 || - type->type == SLANG_SPEC_VEC2 || - type->type == SLANG_SPEC_FLOAT || - type->type == SLANG_SPEC_IVEC4 || - type->type == SLANG_SPEC_IVEC3 || - type->type == SLANG_SPEC_IVEC2 || - type->type == SLANG_SPEC_INT); - if (name) { - GLint t; - - if (tokens[0] == STATE_LIGHT) - t = 2; - else if (tokens[0] == STATE_LIGHTPROD) - t = 3; - else - return -1; /* invalid array name */ - - if (strcmp(name, "ambient") == 0) { - tokens[t] = STATE_AMBIENT; - } - else if (strcmp(name, "diffuse") == 0) { - tokens[t] = STATE_DIFFUSE; - } - else if (strcmp(name, "specular") == 0) { - tokens[t] = STATE_SPECULAR; - } - else if (strcmp(name, "position") == 0) { - tokens[t] = STATE_POSITION; - } - else if (strcmp(name, "halfVector") == 0) { - tokens[t] = STATE_HALF_VECTOR; - } - else if (strcmp(name, "spotDirection") == 0) { - tokens[t] = STATE_SPOT_DIRECTION; /* xyz components */ - } - else if (strcmp(name, "spotCosCutoff") == 0) { - tokens[t] = STATE_SPOT_DIRECTION; /* w component */ - } - - else if (strcmp(name, "constantAttenuation") == 0) { - tokens[t] = STATE_ATTENUATION; /* x component */ - } - else if (strcmp(name, "linearAttenuation") == 0) { - tokens[t] = STATE_ATTENUATION; /* y component */ - } - else if (strcmp(name, "quadraticAttenuation") == 0) { - tokens[t] = STATE_ATTENUATION; /* z component */ - } - else if (strcmp(name, "spotExponent") == 0) { - tokens[t] = STATE_ATTENUATION; /* w = spot exponent */ - } - - else if (strcmp(name, "spotCutoff") == 0) { - tokens[t] = STATE_SPOT_CUTOFF; /* x component */ - } - - else { - return -1; /* invalid field name */ - } - } - - pos = _mesa_add_state_reference(paramList, tokens); - return pos; - } - - return 1; -} - - -/** - * Unroll the named built-in uniform variable into a sequence of state - * vars in the given parameter list. - */ -static GLint -alloc_state_var_array(const slang_variable *var, - struct gl_program_parameter_list *paramList) -{ - gl_state_index tokens[STATE_LENGTH]; - GLuint i; - GLint pos; - - /* Initialize the state tokens array. This is very important. - * When we call _mesa_add_state_reference() it'll searches the parameter - * list to see if the given statevar token sequence is already present. - * This is normally a good thing since it prevents redundant values in the - * constant buffer. - * - * But when we're building arrays of state this can be bad. For example, - * consider this fragment of GLSL code: - * foo = gl_LightSource[3].diffuse; - * ... - * bar = gl_LightSource[i].diffuse; - * - * When we unroll the gl_LightSource array (for "bar") we want to re-emit - * gl_LightSource[3].diffuse and not re-use the first instance (from "foo") - * since that would upset the array layout. We handle this situation by - * setting the last token in the state var token array to the special - * value STATE_ARRAY. - * This token will only be set for array state. We can hijack the last - * element in the array for this since it's never used for light, clipplane - * or texture env array state. - */ - for (i = 0; i < STATE_LENGTH; i++) - tokens[i] = 0; - tokens[STATE_LENGTH - 1] = STATE_ARRAY; - - pos = emit_statevars(var->a_name, var->array_len, &var->type.specifier, - tokens, paramList); - - 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. - * - * Arrays such as gl_LightSource are handled specially. For an expression - * like "gl_LightSource[2].diffuse", we can allocate a single uniform/constant - * slot and return the index. In this case, we return direct=TRUE. - * - * Buf for something like "gl_LightSource[i].diffuse" we don't know the value - * of 'i' at compile time so we need to "unroll" the gl_LightSource array - * into a consecutive sequence of uniform/constant slots so it can be indexed - * at runtime. In this case, we return direct=FALSE. - * - * Currently, all pre-defined uniforms are in one of these forms: - * var - * var[i] - * var.field - * var[i].field - * var[i][j] - * - * \return -1 upon error, else position in paramList of the state variable/data - */ -GLint -_slang_alloc_statevar(slang_ir_node *n, - struct gl_program_parameter_list *paramList, - GLboolean *direct) -{ - slang_ir_node *n0 = n; - const char *field = NULL; - GLint index1 = -1, index2 = -1; - GLuint swizzle; - - *direct = GL_TRUE; - - if (n->Opcode == IR_FIELD) { - field = n->Field; - n = n->Children[0]; - } - - if (n->Opcode == IR_ELEMENT) { - if (n->Children[1]->Opcode == IR_FLOAT) { - index1 = (GLint) n->Children[1]->Value[0]; - } - else { - *direct = GL_FALSE; - } - n = n->Children[0]; - } - - if (n->Opcode == IR_ELEMENT) { - /* XXX can only handle constant indexes for now */ - if (n->Children[1]->Opcode == IR_FLOAT) { - /* two-dimensional array index: mat[i][j] */ - index2 = index1; - index1 = (GLint) n->Children[1]->Value[0]; - } - else { - *direct = GL_FALSE; - } - n = n->Children[0]; - } - - assert(n->Opcode == IR_VAR); - - if (*direct) { - const char *var = (const char *) n->Var->a_name; - GLint pos = - lookup_statevar(var, index1, index2, field, &swizzle, paramList); - if (pos >= 0) { - /* newly resolved storage for the statevar/constant/uniform */ - n0->Store->File = PROGRAM_STATE_VAR; - n0->Store->Index = pos; - n0->Store->Swizzle = swizzle; - n0->Store->Parent = NULL; - return pos; - } - } - - *direct = GL_FALSE; - return alloc_state_var_array(n->Var, paramList); -} - - - - -#define SWIZZLE_ZWWW MAKE_SWIZZLE4(SWIZZLE_Z, SWIZZLE_W, SWIZZLE_W, SWIZZLE_W) - - -/** Predefined shader inputs */ -struct input_info -{ - const char *Name; - GLuint Attrib; - GLenum Type; - GLuint Swizzle; -}; - -/** Predefined vertex shader inputs/attributes */ -static const struct input_info vertInputs[] = { - { "gl_Vertex", VERT_ATTRIB_POS, GL_FLOAT_VEC4, SWIZZLE_NOOP }, - { "gl_Normal", VERT_ATTRIB_NORMAL, GL_FLOAT_VEC3, SWIZZLE_NOOP }, - { "gl_Color", VERT_ATTRIB_COLOR0, GL_FLOAT_VEC4, SWIZZLE_NOOP }, - { "gl_SecondaryColor", VERT_ATTRIB_COLOR1, GL_FLOAT_VEC4, SWIZZLE_NOOP }, - { "gl_FogCoord", VERT_ATTRIB_FOG, GL_FLOAT, SWIZZLE_XXXX }, - { "gl_MultiTexCoord0", VERT_ATTRIB_TEX0, GL_FLOAT_VEC4, SWIZZLE_NOOP }, - { "gl_MultiTexCoord1", VERT_ATTRIB_TEX1, GL_FLOAT_VEC4, SWIZZLE_NOOP }, - { "gl_MultiTexCoord2", VERT_ATTRIB_TEX2, GL_FLOAT_VEC4, SWIZZLE_NOOP }, - { "gl_MultiTexCoord3", VERT_ATTRIB_TEX3, GL_FLOAT_VEC4, SWIZZLE_NOOP }, - { "gl_MultiTexCoord4", VERT_ATTRIB_TEX4, GL_FLOAT_VEC4, SWIZZLE_NOOP }, - { "gl_MultiTexCoord5", VERT_ATTRIB_TEX5, GL_FLOAT_VEC4, SWIZZLE_NOOP }, - { "gl_MultiTexCoord6", VERT_ATTRIB_TEX6, GL_FLOAT_VEC4, SWIZZLE_NOOP }, - { "gl_MultiTexCoord7", VERT_ATTRIB_TEX7, GL_FLOAT_VEC4, SWIZZLE_NOOP }, - { NULL, 0, GL_NONE, SWIZZLE_NOOP } -}; - -/** Predefined fragment shader inputs */ -static const struct input_info fragInputs[] = { - { "gl_FragCoord", FRAG_ATTRIB_WPOS, GL_FLOAT_VEC4, SWIZZLE_NOOP }, - { "gl_Color", FRAG_ATTRIB_COL0, GL_FLOAT_VEC4, SWIZZLE_NOOP }, - { "gl_SecondaryColor", FRAG_ATTRIB_COL1, GL_FLOAT_VEC4, SWIZZLE_NOOP }, - { "gl_TexCoord", FRAG_ATTRIB_TEX0, GL_FLOAT_VEC4, SWIZZLE_NOOP }, - /* note: we're packing several quantities into the fogcoord vector */ - { "gl_FogFragCoord", FRAG_ATTRIB_FOGC, GL_FLOAT, SWIZZLE_XXXX }, - { "gl_FrontFacing", FRAG_ATTRIB_FACE, GL_FLOAT, SWIZZLE_XXXX }, - { "gl_PointCoord", FRAG_ATTRIB_PNTC, GL_FLOAT_VEC2, SWIZZLE_XYZW }, - { NULL, 0, GL_NONE, SWIZZLE_NOOP } -}; - - -/** - * 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 - */ -GLint -_slang_input_index(const char *name, GLenum target, GLuint *swizzleOut) -{ - const struct input_info *inputs; - GLuint i; - - switch (target) { - case GL_VERTEX_PROGRAM_ARB: - inputs = vertInputs; - break; - case GL_FRAGMENT_PROGRAM_ARB: - inputs = fragInputs; - break; - /* XXX geom program */ - default: - _mesa_problem(NULL, "bad target in _slang_input_index"); - return -1; - } - - ASSERT(MAX_TEXTURE_COORD_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 name of the given vertex attribute (VERT_ATTRIB_x). - */ -const char * -_slang_vert_attrib_name(GLuint attrib) -{ - GLuint i; - assert(attrib < VERT_ATTRIB_GENERIC0); - for (i = 0; vertInputs[i].Name; i++) { - if (vertInputs[i].Attrib == attrib) - return vertInputs[i].Name; - } - return NULL; -} - - -/** - * Return type (GL_FLOAT, GL_FLOAT_VEC2, etc) of the given vertex - * attribute (VERT_ATTRIB_x). - */ -GLenum -_slang_vert_attrib_type(GLuint attrib) -{ - GLuint i; - assert(attrib < VERT_ATTRIB_GENERIC0); - for (i = 0; vertInputs[i].Name; i++) { - if (vertInputs[i].Attrib == attrib) - return vertInputs[i].Type; - } - return GL_NONE; -} - - - - - -/** Predefined shader output info */ -struct output_info -{ - const char *Name; - GLuint Attrib; -}; - -/** Predefined vertex shader outputs */ -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 } -}; - -/** Predefined fragment shader outputs */ -static const struct output_info fragOutputs[] = { - { "gl_FragColor", FRAG_RESULT_COLOR }, - { "gl_FragDepth", FRAG_RESULT_DEPTH }, - { "gl_FragData", FRAG_RESULT_DATA0 }, - { NULL, 0 } -}; - - -/** - * 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. - */ -GLint -_slang_output_index(const char *name, GLenum target) -{ - const struct output_info *outputs; - GLuint i; - - switch (target) { - case GL_VERTEX_PROGRAM_ARB: - outputs = vertOutputs; - break; - case GL_FRAGMENT_PROGRAM_ARB: - outputs = fragOutputs; - break; - /* XXX geom program */ - default: - _mesa_problem(NULL, "bad target in _slang_output_index"); - return -1; - } - - for (i = 0; outputs[i].Name; i++) { - if (strcmp(outputs[i].Name, name) == 0) { - /* found */ - return outputs[i].Attrib; - } - } - return -1; -} diff --git a/mesalib/src/mesa/shader/slang/slang_builtin.h b/mesalib/src/mesa/shader/slang/slang_builtin.h deleted file mode 100644 index f814d11ac..000000000 --- a/mesalib/src/mesa/shader/slang/slang_builtin.h +++ /dev/null @@ -1,54 +0,0 @@ -/* - * 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_BUILTIN_H -#define SLANG_BUILTIN_H - -#include "shader/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, - GLboolean *direct); - - -extern GLint -_slang_input_index(const char *name, GLenum target, GLuint *swizzleOut); - -extern GLint -_slang_output_index(const char *name, GLenum target); - - -extern const char * -_slang_vert_attrib_name(GLuint attrib); - -extern GLenum -_slang_vert_attrib_type(GLuint attrib); - - -#endif /* SLANG_BUILTIN_H */ diff --git a/mesalib/src/mesa/shader/slang/slang_codegen.c b/mesalib/src/mesa/shader/slang/slang_codegen.c deleted file mode 100644 index 7d5e5eb29..000000000 --- a/mesalib/src/mesa/shader/slang/slang_codegen.c +++ /dev/null @@ -1,5354 +0,0 @@ -/* - * Mesa 3-D graphics library - * - * Copyright (C) 2005-2007 Brian Paul All Rights Reserved. - * Copyright (C) 2008 VMware, 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. - */ - -/** - * \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 "main/imports.h" -#include "main/macros.h" -#include "main/mtypes.h" -#include "shader/program.h" -#include "shader/prog_instruction.h" -#include "shader/prog_parameter.h" -#include "shader/prog_print.h" -#include "shader/prog_statevars.h" -#include "slang_typeinfo.h" -#include "slang_builtin.h" -#include "slang_codegen.h" -#include "slang_compile.h" -#include "slang_label.h" -#include "slang_mem.h" -#include "slang_simplify.h" -#include "slang_emit.h" -#include "slang_vartable.h" -#include "slang_ir.h" -#include "slang_print.h" - - -/** Max iterations to unroll */ -const GLuint MAX_FOR_LOOP_UNROLL_ITERATIONS = 32; - -/** Max for-loop body size (in slang operations) to unroll */ -const GLuint MAX_FOR_LOOP_UNROLL_BODY_SIZE = 50; - -/** Max for-loop body complexity to unroll. - * We'll compute complexity as the product of the number of iterations - * and the size of the body. So long-ish loops with very simple bodies - * can be unrolled, as well as short loops with larger bodies. - */ -const GLuint MAX_FOR_LOOP_UNROLL_COMPLEXITY = 256; - - - -static slang_ir_node * -_slang_gen_operation(slang_assemble_ctx * A, slang_operation *oper); - -static void -slang_substitute(slang_assemble_ctx *A, slang_operation *oper, - GLuint substCount, slang_variable **substOld, - slang_operation **substNew, GLboolean isLHS); - - -/** - * Retrieves type information about an operation. - * Returns GL_TRUE on success. - * Returns GL_FALSE otherwise. - */ -static GLboolean -typeof_operation(const struct slang_assemble_ctx_ *A, - slang_operation *op, - slang_typeinfo *ti) -{ - return _slang_typeof_operation(op, &A->space, ti, A->atoms, A->log); -} - - -static GLboolean -is_sampler_type(const slang_fully_specified_type *t) -{ - switch (t->specifier.type) { - case SLANG_SPEC_SAMPLER_1D: - case SLANG_SPEC_SAMPLER_2D: - case SLANG_SPEC_SAMPLER_3D: - case SLANG_SPEC_SAMPLER_CUBE: - case SLANG_SPEC_SAMPLER_1D_SHADOW: - case SLANG_SPEC_SAMPLER_2D_SHADOW: - case SLANG_SPEC_SAMPLER_RECT: - case SLANG_SPEC_SAMPLER_RECT_SHADOW: - case SLANG_SPEC_SAMPLER_1D_ARRAY: - case SLANG_SPEC_SAMPLER_2D_ARRAY: - case SLANG_SPEC_SAMPLER_1D_ARRAY_SHADOW: - case SLANG_SPEC_SAMPLER_2D_ARRAY_SHADOW: - 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 */ -} - - -/** - * Return the size (in floats) of the given type specifier. - * If the size is greater than 4, the size should be a multiple of 4 - * so that the correct number of 4-float registers are allocated. - * For example, a mat3x2 is size 12 because we want to store the - * 3 columns in 3 float[4] registers. - */ -GLuint -_slang_sizeof_type_specifier(const slang_type_specifier *spec) -{ - GLuint sz; - switch (spec->type) { - case SLANG_SPEC_VOID: - sz = 0; - break; - case SLANG_SPEC_BOOL: - sz = 1; - break; - case SLANG_SPEC_BVEC2: - sz = 2; - break; - case SLANG_SPEC_BVEC3: - sz = 3; - break; - case SLANG_SPEC_BVEC4: - sz = 4; - break; - case SLANG_SPEC_INT: - sz = 1; - break; - case SLANG_SPEC_IVEC2: - sz = 2; - break; - case SLANG_SPEC_IVEC3: - sz = 3; - break; - case SLANG_SPEC_IVEC4: - sz = 4; - break; - case SLANG_SPEC_FLOAT: - sz = 1; - break; - case SLANG_SPEC_VEC2: - sz = 2; - break; - case SLANG_SPEC_VEC3: - sz = 3; - break; - case SLANG_SPEC_VEC4: - sz = 4; - break; - case SLANG_SPEC_MAT2: - sz = 2 * 4; /* 2 columns (regs) */ - break; - case SLANG_SPEC_MAT3: - sz = 3 * 4; - break; - case SLANG_SPEC_MAT4: - sz = 4 * 4; - break; - case SLANG_SPEC_MAT23: - sz = 2 * 4; /* 2 columns (regs) */ - break; - case SLANG_SPEC_MAT32: - sz = 3 * 4; /* 3 columns (regs) */ - break; - case SLANG_SPEC_MAT24: - sz = 2 * 4; - break; - case SLANG_SPEC_MAT42: - sz = 4 * 4; /* 4 columns (regs) */ - break; - case SLANG_SPEC_MAT34: - sz = 3 * 4; - break; - case SLANG_SPEC_MAT43: - sz = 4 * 4; /* 4 columns (regs) */ - break; - case SLANG_SPEC_SAMPLER_1D: - case SLANG_SPEC_SAMPLER_2D: - case SLANG_SPEC_SAMPLER_3D: - case SLANG_SPEC_SAMPLER_CUBE: - case SLANG_SPEC_SAMPLER_1D_SHADOW: - case SLANG_SPEC_SAMPLER_2D_SHADOW: - case SLANG_SPEC_SAMPLER_RECT: - case SLANG_SPEC_SAMPLER_RECT_SHADOW: - case SLANG_SPEC_SAMPLER_1D_ARRAY: - case SLANG_SPEC_SAMPLER_2D_ARRAY: - case SLANG_SPEC_SAMPLER_1D_ARRAY_SHADOW: - case SLANG_SPEC_SAMPLER_2D_ARRAY_SHADOW: - sz = 1; /* a sampler is basically just an integer index */ - break; - case SLANG_SPEC_STRUCT: - sz = _slang_field_offset(spec, 0); /* special use */ - if (sz == 1) { - /* 1-float structs are actually troublesome to deal with since they - * might get placed at R.x, R.y, R.z or R.z. Return size=2 to - * ensure the object is placed at R.x - */ - sz = 2; - } - else if (sz > 4) { - sz = (sz + 3) & ~0x3; /* round up to multiple of four */ - } - break; - case SLANG_SPEC_ARRAY: - sz = _slang_sizeof_type_specifier(spec->_array); - break; - default: - _mesa_problem(NULL, "Unexpected type in _slang_sizeof_type_specifier()"); - sz = 0; - } - - if (sz > 4) { - /* if size is > 4, it should be a multiple of four */ - assert((sz & 0x3) == 0); - } - return sz; -} - - -/** - * Query variable/array length (number of elements). - * This is slightly non-trivial because there are two ways to express - * arrays: "float x[3]" vs. "float[3] x". - * \return the length of the array for the given variable, or 0 if not an array - */ -static GLint -_slang_array_length(const slang_variable *var) -{ - if (var->type.array_len > 0) { - /* Ex: float[4] x; */ - return var->type.array_len; - } - if (var->array_len > 0) { - /* Ex: float x[4]; */ - return var->array_len; - } - return 0; -} - - -/** - * Compute total size of array give size of element, number of elements. - * \return size in floats - */ -static GLint -_slang_array_size(GLint elemSize, GLint arrayLen) -{ - GLint total; - assert(elemSize > 0); - if (arrayLen > 1) { - /* round up base type to multiple of 4 */ - total = ((elemSize + 3) & ~0x3) * MAX2(arrayLen, 1); - } - else { - total = elemSize; - } - return total; -} - - -/** - * 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_SAMPLER_1D: - return TEXTURE_1D_INDEX; - case SLANG_SPEC_SAMPLER_2D: - return TEXTURE_2D_INDEX; - case SLANG_SPEC_SAMPLER_3D: - return TEXTURE_3D_INDEX; - case SLANG_SPEC_SAMPLER_CUBE: - return TEXTURE_CUBE_INDEX; - case SLANG_SPEC_SAMPLER_1D_SHADOW: - return TEXTURE_1D_INDEX; /* XXX fix */ - case SLANG_SPEC_SAMPLER_2D_SHADOW: - return TEXTURE_2D_INDEX; /* XXX fix */ - case SLANG_SPEC_SAMPLER_RECT: - return TEXTURE_RECT_INDEX; - case SLANG_SPEC_SAMPLER_RECT_SHADOW: - return TEXTURE_RECT_INDEX; /* XXX fix */ - case SLANG_SPEC_SAMPLER_1D_ARRAY: - return TEXTURE_1D_ARRAY_INDEX; - case SLANG_SPEC_SAMPLER_2D_ARRAY: - return TEXTURE_2D_ARRAY_INDEX; - case SLANG_SPEC_SAMPLER_1D_ARRAY_SHADOW: - return TEXTURE_1D_ARRAY_INDEX; - case SLANG_SPEC_SAMPLER_2D_ARRAY_SHADOW: - return TEXTURE_2D_ARRAY_INDEX; - default: - return -1; - } -} - - -/** helper to build a SLANG_OPER_IDENTIFIER node */ -static void -slang_operation_identifier(slang_operation *oper, - slang_assemble_ctx *A, - const char *name) -{ - oper->type = SLANG_OPER_IDENTIFIER; - oper->a_id = slang_atom_pool_atom(A->atoms, name); -} - - -/** - * Called when we begin code/IR generation for a new while/do/for loop. - */ -static void -push_loop(slang_assemble_ctx *A, slang_operation *loopOper, slang_ir_node *loopIR) -{ - A->LoopOperStack[A->LoopDepth] = loopOper; - A->LoopIRStack[A->LoopDepth] = loopIR; - A->LoopDepth++; -} - - -/** - * Called when we end code/IR generation for a new while/do/for loop. - */ -static void -pop_loop(slang_assemble_ctx *A) -{ - assert(A->LoopDepth > 0); - A->LoopDepth--; -} - - -/** - * Return pointer to slang_operation for the loop we're currently inside, - * or NULL if not in a loop. - */ -static const slang_operation * -current_loop_oper(const slang_assemble_ctx *A) -{ - if (A->LoopDepth > 0) - return A->LoopOperStack[A->LoopDepth - 1]; - else - return NULL; -} - - -/** - * Return pointer to slang_ir_node for the loop we're currently inside, - * or NULL if not in a loop. - */ -static slang_ir_node * -current_loop_ir(const slang_assemble_ctx *A) -{ - if (A->LoopDepth > 0) - return A->LoopIRStack[A->LoopDepth - 1]; - else - return NULL; -} - - -/**********************************************************************/ - - -/** - * 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 }, - { "vec2_dot", IR_DOT2, 1, 2 }, - { "vec3_nrm", IR_NRM3, 1, 1 }, - { "vec4_nrm", IR_NRM4, 1, 1 }, - { "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_cmp", IR_CMP, 1, 3 }, - { "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_move", IR_MOVE, 1, 1 }, - { "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_tex_1d", IR_TEX, 1, 2 }, - { "vec4_tex_1d_bias", IR_TEXB, 1, 2 }, /* 1d w/ bias */ - { "vec4_tex_1d_proj", IR_TEXP, 1, 2 }, /* 1d w/ projection */ - { "vec4_tex_2d", IR_TEX, 1, 2 }, - { "vec4_tex_2d_bias", IR_TEXB, 1, 2 }, /* 2d w/ bias */ - { "vec4_tex_2d_proj", IR_TEXP, 1, 2 }, /* 2d w/ projection */ - { "vec4_tex_3d", IR_TEX, 1, 2 }, - { "vec4_tex_3d_bias", IR_TEXB, 1, 2 }, /* 3d w/ bias */ - { "vec4_tex_3d_proj", IR_TEXP, 1, 2 }, /* 3d w/ projection */ - { "vec4_tex_cube", IR_TEX, 1, 2 }, /* cubemap */ - { "vec4_tex_rect", IR_TEX, 1, 2 }, /* rectangle */ - { "vec4_tex_rect_bias", IR_TEX, 1, 2 }, /* rectangle w/ projection */ - { "vec4_tex_1d_array", IR_TEX, 1, 2 }, - { "vec4_tex_1d_array_bias", IR_TEXB, 1, 2 }, - { "vec4_tex_1d_array_shadow", IR_TEX, 1, 2 }, - { "vec4_tex_1d_array_bias_shadow", IR_TEXB, 1, 2 }, - { "vec4_tex_2d_array", IR_TEX, 1, 2 }, - { "vec4_tex_2d_array_bias", IR_TEXB, 1, 2 }, - { "vec4_tex_2d_array_shadow", IR_TEX, 1, 2 }, - { "vec4_tex_2d_array_bias_shadow", IR_TEXB, 1, 2 }, - - /* texture / sampler but with shadow comparison */ - { "vec4_tex_1d_shadow", IR_TEX_SH, 1, 2 }, - { "vec4_tex_1d_bias_shadow", IR_TEXB_SH, 1, 2 }, - { "vec4_tex_1d_proj_shadow", IR_TEXP_SH, 1, 2 }, - { "vec4_tex_2d_shadow", IR_TEX_SH, 1, 2 }, - { "vec4_tex_2d_bias_shadow", IR_TEXB_SH, 1, 2 }, - { "vec4_tex_2d_proj_shadow", IR_TEXP_SH, 1, 2 }, - { "vec4_tex_rect_shadow", IR_TEX_SH, 1, 2 }, - { "vec4_tex_rect_proj_shadow", IR_TEXP_SH, 1, 2 }, - - /* unary op */ - { "ivec4_to_vec4", IR_I_TO_F, 1, 1 }, /* int[4] to float[4] */ - { "vec4_to_ivec4", IR_F_TO_I, 1, 1 }, /* float[4] to int[4] */ - { "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 *) _slang_alloc(sizeof(slang_ir_node)); - if (n) { - n->Opcode = op; - n->Children[0] = c0; - n->Children[1] = c1; - n->Children[2] = c2; - 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); -} - - -/** - * Create sequence of two nodes. - */ -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], GLuint size) -{ - slang_ir_node *n = new_node0(IR_FLOAT); - assert(size <= 4); - 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; -} - - -static slang_ir_node * -new_not(slang_ir_node *n) -{ - return new_node1(IR_NOT, n); -} - - -/** - * Non-inlined function call. - */ -static slang_ir_node * -new_function_call(slang_ir_node *code, slang_label *name) -{ - slang_ir_node *n = new_node1(IR_CALL, code); - assert(name); - if (n) - n->Label = name; - return n; -} - - -/** - * Unconditional jump. - */ -static slang_ir_node * -new_return(slang_label *dest) -{ - slang_ir_node *n = new_node0(IR_RETURN); - 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 of cont/break instructions */ - n->List = loopNode->List; - loopNode->List = n; - } - return n; -} - - -/** - * Make new IR_BREAK_IF_TRUE. - */ -static slang_ir_node * -new_break_if_true(slang_assemble_ctx *A, slang_ir_node *cond) -{ - slang_ir_node *loopNode = current_loop_ir(A); - slang_ir_node *n; - assert(loopNode); - assert(loopNode->Opcode == IR_LOOP); - n = new_node1(IR_BREAK_IF_TRUE, cond); - if (n) { - /* insert this node at head of linked list of cont/break instructions */ - n->List = loopNode->List; - loopNode->List = n; - } - return n; -} - - -/** - * Make new IR_CONT_IF_TRUE node. - */ -static slang_ir_node * -new_cont_if_true(slang_assemble_ctx *A, slang_ir_node *cond) -{ - slang_ir_node *loopNode = current_loop_ir(A); - slang_ir_node *n; - assert(loopNode); - assert(loopNode->Opcode == IR_LOOP); - n = new_node1(IR_CONT_IF_TRUE, cond); - if (n) { - n->Parent = loopNode; /* pointer to containing loop */ - /* insert this node at head of linked list of cont/break instructions */ - 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_variable *var) -{ - slang_ir_node *n = new_node0(IR_VAR); - if (n) { - ASSERT(var); - ASSERT(var->store); - ASSERT(!n->Store); - ASSERT(!n->Var); - - /* Set IR node's Var and Store pointers */ - n->Var = var; - n->Store = var->store; - } - 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; -} - - -/** - * Recursively search tree for a node of the given type. - */ -#if 0 -static slang_operation * -_slang_find_node_type(slang_operation *oper, slang_operation_type type) -{ - GLuint i; - if (oper->type == type) - return oper; - for (i = 0; i < oper->num_children; i++) { - slang_operation *p = _slang_find_node_type(&oper->children[i], type); - if (p) - return p; - } - return NULL; -} -#endif - - -/** - * Count the number of operations of the given time rooted at 'oper'. - */ -static GLuint -_slang_count_node_type(const slang_operation *oper, slang_operation_type type) -{ - GLuint i, count = 0; - if (oper->type == type) { - return 1; - } - for (i = 0; i < oper->num_children; i++) { - count += _slang_count_node_type(&oper->children[i], type); - } - return count; -} - - -/** - * Check if the 'return' statement found under 'oper' is a "tail return" - * that can be no-op'd. For example: - * - * void func(void) - * { - * .. do something .. - * return; // this is a no-op - * } - * - * This is used when determining if a function can be inlined. If the - * 'return' is not the last statement, we can't inline the function since - * we still need the semantic behaviour of the 'return' but we don't want - * to accidentally return from the _calling_ function. We'd need to use an - * unconditional branch, but we don't have such a GPU instruction (not - * always, at least). - */ -static GLboolean -_slang_is_tail_return(const slang_operation *oper) -{ - GLuint k = oper->num_children; - - while (k > 0) { - const slang_operation *last = &oper->children[k - 1]; - if (last->type == SLANG_OPER_RETURN) - return GL_TRUE; - else if (last->type == SLANG_OPER_IDENTIFIER || - last->type == SLANG_OPER_LABEL) - k--; /* try prev child */ - else if (last->type == SLANG_OPER_BLOCK_NO_NEW_SCOPE || - last->type == SLANG_OPER_BLOCK_NEW_SCOPE) - /* try sub-children */ - return _slang_is_tail_return(last); - else - break; - } - - return GL_FALSE; -} - - -/** - * Generate a variable declaration opeartion. - * I.e.: generate AST code for "bool flag = false;" - */ -static void -slang_generate_declaration(slang_assemble_ctx *A, - slang_variable_scope *scope, - slang_operation *decl, - slang_type_specifier_type type, - const char *name, - GLint initValue) -{ - slang_variable *var; - - assert(type == SLANG_SPEC_BOOL || - type == SLANG_SPEC_INT); - - decl->type = SLANG_OPER_VARIABLE_DECL; - - var = slang_variable_scope_grow(scope); - - slang_fully_specified_type_construct(&var->type); - - var->type.specifier.type = type; - var->a_name = slang_atom_pool_atom(A->atoms, name); - decl->a_id = var->a_name; - var->initializer = slang_operation_new(1); - slang_operation_literal_bool(var->initializer, initValue); -} - - -static void -slang_resolve_variable(slang_operation *oper) -{ - if (oper->type == SLANG_OPER_IDENTIFIER && !oper->var) { - oper->var = _slang_variable_locate(oper->locals, oper->a_id, GL_TRUE); - } -} - - -/** - * Rewrite AST code for "return expression;". - * - * We return values from functions by assinging the returned value to - * the hidden __retVal variable which is an extra 'out' parameter we add - * to the function signature. - * This code basically converts "return expr;" into "__retVal = expr; return;" - * - * \return the new AST code. - */ -static slang_operation * -gen_return_with_expression(slang_assemble_ctx *A, slang_operation *oper) -{ - slang_operation *blockOper, *assignOper; - - assert(oper->type == SLANG_OPER_RETURN); - - if (A->CurFunction->header.type.specifier.type == SLANG_SPEC_VOID) { - slang_info_log_error(A->log, "illegal return expression"); - return NULL; - } - - blockOper = slang_operation_new(1); - blockOper->type = SLANG_OPER_BLOCK_NO_NEW_SCOPE; - blockOper->locals->outer_scope = oper->locals->outer_scope; - slang_operation_add_children(blockOper, 2); - - if (A->UseReturnFlag) { - /* Emit: - * { - * if (__notRetFlag) - * __retVal = expr; - * __notRetFlag = 0; - * } - */ - { - slang_operation *ifOper = slang_oper_child(blockOper, 0); - ifOper->type = SLANG_OPER_IF; - slang_operation_add_children(ifOper, 3); - { - slang_operation *cond = slang_oper_child(ifOper, 0); - cond->type = SLANG_OPER_IDENTIFIER; - cond->a_id = slang_atom_pool_atom(A->atoms, "__notRetFlag"); - } - { - slang_operation *elseOper = slang_oper_child(ifOper, 2); - elseOper->type = SLANG_OPER_VOID; - } - assignOper = slang_oper_child(ifOper, 1); - } - { - slang_operation *setOper = slang_oper_child(blockOper, 1); - setOper->type = SLANG_OPER_ASSIGN; - slang_operation_add_children(setOper, 2); - { - slang_operation *lhs = slang_oper_child(setOper, 0); - lhs->type = SLANG_OPER_IDENTIFIER; - lhs->a_id = slang_atom_pool_atom(A->atoms, "__notRetFlag"); - } - { - slang_operation *rhs = slang_oper_child(setOper, 1); - slang_operation_literal_bool(rhs, GL_FALSE); - } - } - } - else { - /* Emit: - * { - * __retVal = expr; - * return_inlined; - * } - */ - assignOper = slang_oper_child(blockOper, 0); - { - slang_operation *returnOper = slang_oper_child(blockOper, 1); - returnOper->type = SLANG_OPER_RETURN_INLINED; - assert(returnOper->num_children == 0); - } - } - - /* __retVal = expression; */ - assignOper->type = SLANG_OPER_ASSIGN; - slang_operation_add_children(assignOper, 2); - { - slang_operation *lhs = slang_oper_child(assignOper, 0); - lhs->type = SLANG_OPER_IDENTIFIER; - lhs->a_id = slang_atom_pool_atom(A->atoms, "__retVal"); - } - { - slang_operation *rhs = slang_oper_child(assignOper, 1); - slang_operation_copy(rhs, &oper->children[0]); - } - - /*blockOper->locals->outer_scope = oper->locals->outer_scope;*/ - - /*slang_print_tree(blockOper, 0);*/ - - return blockOper; -} - - -/** - * Rewrite AST code for "return;" (no expression). - */ -static slang_operation * -gen_return_without_expression(slang_assemble_ctx *A, slang_operation *oper) -{ - slang_operation *newRet; - - assert(oper->type == SLANG_OPER_RETURN); - - if (A->CurFunction->header.type.specifier.type != SLANG_SPEC_VOID) { - slang_info_log_error(A->log, "return statement requires an expression"); - return NULL; - } - - if (A->UseReturnFlag) { - /* Emit: - * __notRetFlag = 0; - */ - { - newRet = slang_operation_new(1); - newRet->locals->outer_scope = oper->locals->outer_scope; - newRet->type = SLANG_OPER_ASSIGN; - slang_operation_add_children(newRet, 2); - { - slang_operation *lhs = slang_oper_child(newRet, 0); - lhs->type = SLANG_OPER_IDENTIFIER; - lhs->a_id = slang_atom_pool_atom(A->atoms, "__notRetFlag"); - } - { - slang_operation *rhs = slang_oper_child(newRet, 1); - slang_operation_literal_bool(rhs, GL_FALSE); - } - } - } - else { - /* Emit: - * return_inlined; - */ - newRet = slang_operation_new(1); - newRet->locals->outer_scope = oper->locals->outer_scope; - newRet->type = SLANG_OPER_RETURN_INLINED; - } - - /*slang_print_tree(newRet, 0);*/ - - return newRet; -} - - - - -/** - * 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_variable_locate(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_variable_locate(oper->locals, id, GL_TRUE); - if (!v) { - if (strcmp((char *) oper->a_id, "__notRetFlag")) - _mesa_problem(NULL, "var %s not found!\n", (char *) oper->a_id); - return; - } - - /* 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: - { - slang_operation *newReturn; - /* generate new 'return' code' */ - if (slang_oper_child(oper, 0)->type == SLANG_OPER_VOID) - newReturn = gen_return_without_expression(A, oper); - else - newReturn = gen_return_with_expression(A, oper); - - if (!newReturn) - return; - - /* do substitutions on the new 'return' code */ - slang_substitute(A, newReturn, - substCount, substOld, substNew, GL_FALSE); - - /* install new 'return' code */ - slang_operation_copy(oper, newReturn); - slang_operation_destruct(newReturn); - } - 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); - } - } -} - - -/** - * Produce inline code for a call to an assembly instruction. - * This is typically used to compile a call to a built-in function like this: - * - * vec4 mix(const vec4 x, const vec4 y, const vec4 a) - * { - * __asm vec4_lrp __retVal, a, y, x; - * } - * - * - * A call to - * r = mix(p1, p2, p3); - * - * Becomes: - * - * mov - * / \ - * r vec4_lrp - * / | \ - * p3 p2 p1 - * - * We basically translate a SLANG_OPER_CALL into a SLANG_OPER_ASM. - */ -static slang_operation * -slang_inline_asm_function(slang_assemble_ctx *A, - slang_function *fun, slang_operation *oper) -{ - const GLuint numArgs = oper->num_children; - GLuint i; - slang_operation *inlined; - const GLboolean haveRetValue = _slang_function_has_return_value(fun); - slang_variable **substOld; - slang_operation **substNew; - - ASSERT(slang_is_asm_function(fun)); - ASSERT(fun->param_count == numArgs + haveRetValue); - - /* - printf("Inline %s as %s\n", - (char*) fun->header.a_name, - (char*) fun->body->children[0].a_id); - */ - - /* - * We'll substitute formal params with actual args in the asm call. - */ - substOld = (slang_variable **) - _slang_alloc(numArgs * sizeof(slang_variable *)); - substNew = (slang_operation **) - _slang_alloc(numArgs * sizeof(slang_operation *)); - for (i = 0; i < numArgs; i++) { - substOld[i] = fun->parameters->variables[i]; - substNew[i] = oper->children + i; - } - - /* make a copy of the code to inline */ - inlined = slang_operation_new(1); - slang_operation_copy(inlined, &fun->body->children[0]); - if (haveRetValue) { - /* get rid of the __retVal child */ - inlined->num_children--; - for (i = 0; i < inlined->num_children; i++) { - inlined->children[i] = inlined->children[i + 1]; - } - } - - /* now do formal->actual substitutions */ - slang_substitute(A, inlined, numArgs, substOld, substNew, GL_FALSE); - - _slang_free(substOld); - _slang_free(substNew); - -#if 0 - printf("+++++++++++++ inlined asm function %s +++++++++++++\n", - (char *) fun->header.a_name); - slang_print_tree(inlined, 3); - printf("+++++++++++++++++++++++++++++++++++++++++++++++++++\n"); -#endif - - return inlined; -} - - -/** - * 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; - slang_function *prevFunction; - slang_variable_scope *newScope = NULL; - - /* save / push */ - prevFunction = A->CurFunction; - A->CurFunction = fun; - - /*assert(oper->type == SLANG_OPER_CALL); (or (matrix) multiply, etc) */ - assert(fun->param_count == totalArgs); - - /* allocate temporary arrays */ - paramMode = (ParamMode *) - _slang_alloc(totalArgs * sizeof(ParamMode)); - substOld = (slang_variable **) - _slang_alloc(totalArgs * sizeof(slang_variable *)); - substNew = (slang_operation **) - _slang_alloc(totalArgs * sizeof(slang_operation *)); - -#if 0 - printf("\nInline 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 || - args[i].type == SLANG_OPER_SUBSCRIPT) { - /* 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); - 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); - - 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); - - /* add parameter 'p' to the local variable scope here */ - { - slang_variable *pCopy = slang_variable_scope_grow(inlined->locals); - pCopy->type = p->type; - pCopy->a_name = p->a_name; - pCopy->array_len = p->array_len; - } - - newScope = inlined->locals; - numCopyIn++; - } - } - - /* Now add copies of the function's local vars to the new variable scope */ - for (i = totalArgs; i < fun->parameters->num_variables; i++) { - slang_variable *p = fun->parameters->variables[i]; - slang_variable *pCopy = slang_variable_scope_grow(inlined->locals); - pCopy->type = p->type; - pCopy->a_name = p->a_name; - pCopy->array_len = p->array_len; - } - - - /* 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; - } - } - - _slang_free(paramMode); - _slang_free(substOld); - _slang_free(substNew); - - /* Update scoping to use the new local vars instead of the - * original function's vars. This is especially important - * for nested inlining. - */ - if (newScope) - slang_replace_scope(inlined, fun->parameters, newScope); - -#if 0 - printf("Done Inline call to %s (total vars=%d nparams=%d)\n\n", - (char *) fun->header.a_name, - fun->parameters->num_variables, numArgs); - slang_print_tree(top, 0); -#endif - - /* pop */ - A->CurFunction = prevFunction; - - return top; -} - - -/** - * Insert declaration for "bool __notRetFlag" in given block operation. - * This is used when we can't emit "early" return statements in subroutines. - */ -static void -declare_return_flag(slang_assemble_ctx *A, slang_operation *oper) -{ - slang_operation *decl; - - assert(oper->type == SLANG_OPER_BLOCK_NEW_SCOPE || - oper->type == SLANG_OPER_SEQUENCE); - - decl = slang_operation_insert_child(oper, 1); - - slang_generate_declaration(A, oper->locals, decl, - SLANG_SPEC_BOOL, "__notRetFlag", GL_TRUE); - - /*slang_print_tree(oper, 0);*/ -} - - -/** - * Recursively replace instances of the old node type with the new type. - */ -static void -replace_node_type(slang_operation *oper, slang_operation_type oldType, - slang_operation_type newType) -{ - GLuint i; - - if (oper->type == oldType) - oper->type = newType; - - for (i = 0; i < slang_oper_num_children(oper); i++) { - replace_node_type(slang_oper_child(oper, i), oldType, newType); - } -} - - - -/** - * Test if the given function body has an "early return". That is, there's - * a 'return' statement that's not the very last instruction in the body. - */ -static GLboolean -has_early_return(const slang_operation *funcBody) -{ - GLuint retCount = _slang_count_node_type(funcBody, SLANG_OPER_RETURN); - if (retCount == 0) - return GL_FALSE; - else if (retCount == 1 && _slang_is_tail_return(funcBody)) - return GL_FALSE; - else - return GL_TRUE; -} - - -/** - * Emit IR code for a function call. This does one of two things: - * 1. Inline the function's code - * 2. Create an IR for the function's body and create a real call to it. - */ -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 *instance; - 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); - - /* - * 'instance' is basically a copy of the function's body with various - * transformations. - */ - - if (slang_is_asm_function(fun) && !dest) { - /* assemble assembly function - tree style */ - instance = slang_inline_asm_function(A, fun, oper); - } - else { - /* non-assembly function */ - /* We always generate an "inline-able" block of code here. - * We may either: - * 1. insert the inline code - * 2. Generate a call to the "inline" code as a subroutine - */ - const GLboolean earlyReturn = has_early_return(fun->body); - - if (earlyReturn && !A->EmitContReturn) { - A->UseReturnFlag = GL_TRUE; - } - - instance = slang_inline_function_call(A, fun, oper, dest); - if (!instance) - return NULL; - - if (earlyReturn) { - /* The function we're calling has one or more 'return' statements - * that prevent us from inlining the function's code. - * - * In this case, change the function's body type from - * SLANG_OPER_BLOCK_NEW_SCOPE to SLANG_OPER_NON_INLINED_CALL. - * During code emit this will result in a true subroutine call. - * - * Also, convert SLANG_OPER_RETURN_INLINED nodes to SLANG_OPER_RETURN. - */ - slang_operation *callOper; - - assert(instance->type == SLANG_OPER_BLOCK_NEW_SCOPE || - instance->type == SLANG_OPER_SEQUENCE); - - if (_slang_function_has_return_value(fun) && !dest) { - assert(instance->children[0].type == SLANG_OPER_VARIABLE_DECL); - assert(instance->children[2].type == SLANG_OPER_IDENTIFIER); - callOper = &instance->children[1]; - } - else { - callOper = instance; - } - - if (A->UseReturnFlag) { - /* Early returns not supported. Create a _returnFlag variable - * that's set upon 'return' and tested elsewhere to no-op any - * remaining instructions in the subroutine. - */ - assert(callOper->type == SLANG_OPER_BLOCK_NEW_SCOPE || - callOper->type == SLANG_OPER_SEQUENCE); - declare_return_flag(A, callOper); - } - else { - /* We can emit real 'return' statements. If we generated any - * 'inline return' statements during function instantiation, - * change them back to regular 'return' statements. - */ - replace_node_type(instance, SLANG_OPER_RETURN_INLINED, - SLANG_OPER_RETURN); - } - - callOper->type = SLANG_OPER_NON_INLINED_CALL; - callOper->fun = fun; - callOper->label = _slang_label_new_unique((char*) fun->header.a_name); - } - else { - /* If there are any 'return' statements remaining, they're at the - * very end of the function and can effectively become no-ops. - */ - replace_node_type(instance, SLANG_OPER_RETURN_INLINED, - SLANG_OPER_VOID); - } - } - - if (!instance) - return NULL; - - /* Replace the function call with the instance block (or new CALL stmt) */ - slang_operation_destruct(oper); - *oper = *instance; - _slang_free(instance); - -#if 0 - assert(instance->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; - - if (A->pragmas->Debug) { - char s[1000]; - _mesa_snprintf(s, sizeof(s), "Call/inline %s()", (char *) fun->header.a_name); - n->Comment = _slang_strdup(s); - } - - A->UseReturnFlag = GL_FALSE; - - return n; -} - - -static slang_asm_info * -slang_find_asm_info(const char *name) -{ - GLuint i; - for (i = 0; AsmInfo[i].Name; i++) { - if (strcmp(AsmInfo[i].Name, name) == 0) { - return AsmInfo + i; - } - } - return NULL; -} - - -/** - * 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. - * See comment above for more info. - * XXX this function could be simplified and should probably be renamed. - * \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(slang_assemble_ctx *A, 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 <= 3); - - if (swizzle != SWIZZLE_XXXX && - swizzle != SWIZZLE_YYYY && - swizzle != SWIZZLE_ZZZZ && - swizzle != SWIZZLE_WWWW && - (mask & (1 << swz))) { - /* a channel can't be specified twice (ex: ".xyyz") */ - slang_info_log_error(A->log, "Invalid writemask '%s'", - _mesa_swizzle_string(swizzle, 0, 0)); - return GL_FALSE; - } - - 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; -} - - -#if 0 /* not used, but don't remove just yet */ -/** - * Recursively traverse 'oper' to produce a swizzle mask in the event - * of any vector subscripts and swizzle suffixes. - * Ex: for "vec4 v", "v[2].x" resolves to v.z - */ -static GLuint -resolve_swizzle(const slang_operation *oper) -{ - if (oper->type == SLANG_OPER_FIELD) { - /* writemask from .xyzw suffix */ - slang_swizzle swz; - if (_slang_is_swizzle((char*) oper->a_id, 4, &swz)) { - GLuint swizzle = MAKE_SWIZZLE4(swz.swizzle[0], - swz.swizzle[1], - swz.swizzle[2], - swz.swizzle[3]); - GLuint child_swizzle = resolve_swizzle(&oper->children[0]); - GLuint s = _slang_swizzle_swizzle(child_swizzle, swizzle); - return s; - } - else - return SWIZZLE_XYZW; - } - else if (oper->type == SLANG_OPER_SUBSCRIPT && - oper->children[1].type == SLANG_OPER_LITERAL_INT) { - /* writemask from [index] */ - GLuint child_swizzle = resolve_swizzle(&oper->children[0]); - GLuint i = (GLuint) oper->children[1].literal[0]; - GLuint swizzle; - GLuint s; - switch (i) { - case 0: - swizzle = SWIZZLE_XXXX; - break; - case 1: - swizzle = SWIZZLE_YYYY; - break; - case 2: - swizzle = SWIZZLE_ZZZZ; - break; - case 3: - swizzle = SWIZZLE_WWWW; - break; - default: - swizzle = SWIZZLE_XYZW; - } - s = _slang_swizzle_swizzle(child_swizzle, swizzle); - return s; - } - else { - return SWIZZLE_XYZW; - } -} -#endif - - -#if 0 -/** - * Recursively descend through swizzle nodes to find the node's storage info. - */ -static slang_ir_storage * -get_store(const slang_ir_node *n) -{ - if (n->Opcode == IR_SWIZZLE) { - return get_store(n->Children[0]); - } - return n->Store; -} -#endif - - -/** - * 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); - return NULL; - } - assert(info->NumParams <= 3); - - if (info->NumParams == oper->num_children) { - /* Storage for result is not specified. - * Children[0], [1], [2] are the operands. - */ - firstOperand = 0; - } - else { - /* Storage for result (child[0]) is specified. - * Children[1], [2], [3] 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. - */ - slang_operation *dest_oper; - slang_ir_node *n0; - - dest_oper = &oper->children[0]; - - n0 = _slang_gen_operation(A, dest_oper); - if (!n0) - return NULL; - - assert(!n->Store); - n->Store = n0->Store; - - assert(n->Store->File != PROGRAM_UNDEFINED || n->Store->Parent); - - _slang_free(n0); - } - - return n; -} - - -#if 0 -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); -} -#endif - - -/** - * Find a function of the given name, taking 'numArgs' arguments. - * 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_find_function_by_argc(slang_function_scope *scope, - const char *name, int numArgs) -{ - while (scope) { - 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) { - int haveRetValue = _slang_function_has_return_value(f); - if (numArgs == f->param_count - haveRetValue) - return f; - } - } - scope = scope->outer_scope; - } - - return NULL; -} - - -static slang_function * -_slang_find_function_by_max_argc(slang_function_scope *scope, - const char *name) -{ - slang_function *maxFunc = NULL; - GLuint maxArgs = 0; - - while (scope) { - 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) { - if (f->param_count > maxArgs) { - maxArgs = f->param_count; - maxFunc = f; - } - } - } - scope = scope->outer_scope; - } - - return maxFunc; -} - - -/** - * Generate a new slang_function which is a constructor for a user-defined - * struct type. - */ -static slang_function * -_slang_make_struct_constructor(slang_assemble_ctx *A, slang_struct *str) -{ - const GLint numFields = str->fields->num_variables; - slang_function *fun = slang_function_new(SLANG_FUNC_CONSTRUCTOR); - - /* function header (name, return type) */ - fun->header.a_name = str->a_name; - fun->header.type.qualifier = SLANG_QUAL_NONE; - fun->header.type.specifier.type = SLANG_SPEC_STRUCT; - fun->header.type.specifier._struct = str; - - /* function parameters (= struct's fields) */ - { - GLint i; - for (i = 0; i < numFields; i++) { - /* - printf("Field %d: %s\n", i, (char*) str->fields->variables[i]->a_name); - */ - slang_variable *p = slang_variable_scope_grow(fun->parameters); - *p = *str->fields->variables[i]; /* copy the variable and type */ - p->type.qualifier = SLANG_QUAL_CONST; - } - fun->param_count = fun->parameters->num_variables; - } - - /* Add __retVal to params */ - { - slang_variable *p = slang_variable_scope_grow(fun->parameters); - slang_atom a_retVal = slang_atom_pool_atom(A->atoms, "__retVal"); - assert(a_retVal); - p->a_name = a_retVal; - p->type = fun->header.type; - p->type.qualifier = SLANG_QUAL_OUT; - fun->param_count++; - } - - /* function body is: - * block: - * declare T; - * T.f1 = p1; - * T.f2 = p2; - * ... - * T.fn = pn; - * return T; - */ - { - slang_variable_scope *scope; - slang_variable *var; - GLint i; - - fun->body = slang_operation_new(1); - fun->body->type = SLANG_OPER_BLOCK_NEW_SCOPE; - fun->body->num_children = numFields + 2; - fun->body->children = slang_operation_new(numFields + 2); - - scope = fun->body->locals; - scope->outer_scope = fun->parameters; - - /* create local var 't' */ - var = slang_variable_scope_grow(scope); - var->a_name = slang_atom_pool_atom(A->atoms, "t"); - var->type = fun->header.type; - - /* declare t */ - { - slang_operation *decl; - - decl = &fun->body->children[0]; - decl->type = SLANG_OPER_VARIABLE_DECL; - decl->locals = _slang_variable_scope_new(scope); - decl->a_id = var->a_name; - } - - /* assign params to fields of t */ - for (i = 0; i < numFields; i++) { - slang_operation *assign = &fun->body->children[1 + i]; - - assign->type = SLANG_OPER_ASSIGN; - assign->locals = _slang_variable_scope_new(scope); - assign->num_children = 2; - assign->children = slang_operation_new(2); - - { - slang_operation *lhs = &assign->children[0]; - - lhs->type = SLANG_OPER_FIELD; - lhs->locals = _slang_variable_scope_new(scope); - lhs->num_children = 1; - lhs->children = slang_operation_new(1); - lhs->a_id = str->fields->variables[i]->a_name; - - lhs->children[0].type = SLANG_OPER_IDENTIFIER; - lhs->children[0].a_id = var->a_name; - lhs->children[0].locals = _slang_variable_scope_new(scope); - -#if 0 - lhs->children[1].num_children = 1; - lhs->children[1].children = slang_operation_new(1); - lhs->children[1].children[0].type = SLANG_OPER_IDENTIFIER; - lhs->children[1].children[0].a_id = str->fields->variables[i]->a_name; - lhs->children[1].children->locals = _slang_variable_scope_new(scope); -#endif - } - - { - slang_operation *rhs = &assign->children[1]; - - rhs->type = SLANG_OPER_IDENTIFIER; - rhs->locals = _slang_variable_scope_new(scope); - rhs->a_id = str->fields->variables[i]->a_name; - } - } - - /* return t; */ - { - slang_operation *ret = &fun->body->children[numFields + 1]; - - ret->type = SLANG_OPER_RETURN; - ret->locals = _slang_variable_scope_new(scope); - ret->num_children = 1; - ret->children = slang_operation_new(1); - ret->children[0].type = SLANG_OPER_IDENTIFIER; - ret->children[0].a_id = var->a_name; - ret->children[0].locals = _slang_variable_scope_new(scope); - } - } - /* - slang_print_function(fun, 1); - */ - return fun; -} - - -/** - * Find/create a function (constructor) for the given structure name. - */ -static slang_function * -_slang_locate_struct_constructor(slang_assemble_ctx *A, const char *name) -{ - unsigned int i; - for (i = 0; i < A->space.structs->num_structs; i++) { - slang_struct *str = &A->space.structs->structs[i]; - if (strcmp(name, (const char *) str->a_name) == 0) { - /* found a structure type that matches the function name */ - if (!str->constructor) { - /* create the constructor function now */ - str->constructor = _slang_make_struct_constructor(A, str); - } - return str->constructor; - } - } - return NULL; -} - - -/** - * Generate a new slang_function to satisfy a call to an array constructor. - * Ex: float[3](1., 2., 3.) - */ -static slang_function * -_slang_make_array_constructor(slang_assemble_ctx *A, slang_operation *oper) -{ - slang_type_specifier_type baseType; - slang_function *fun; - int num_elements; - - fun = slang_function_new(SLANG_FUNC_CONSTRUCTOR); - if (!fun) - return NULL; - - baseType = slang_type_specifier_type_from_string((char *) oper->a_id); - - num_elements = oper->num_children; - - /* function header, return type */ - { - fun->header.a_name = oper->a_id; - fun->header.type.qualifier = SLANG_QUAL_NONE; - fun->header.type.specifier.type = SLANG_SPEC_ARRAY; - fun->header.type.specifier._array = - slang_type_specifier_new(baseType, NULL, NULL); - fun->header.type.array_len = num_elements; - } - - /* function parameters (= number of elements) */ - { - GLint i; - for (i = 0; i < num_elements; i++) { - /* - printf("Field %d: %s\n", i, (char*) str->fields->variables[i]->a_name); - */ - slang_variable *p = slang_variable_scope_grow(fun->parameters); - char name[10]; - _mesa_snprintf(name, sizeof(name), "p%d", i); - p->a_name = slang_atom_pool_atom(A->atoms, name); - p->type.qualifier = SLANG_QUAL_CONST; - p->type.specifier.type = baseType; - } - fun->param_count = fun->parameters->num_variables; - } - - /* Add __retVal to params */ - { - slang_variable *p = slang_variable_scope_grow(fun->parameters); - slang_atom a_retVal = slang_atom_pool_atom(A->atoms, "__retVal"); - assert(a_retVal); - p->a_name = a_retVal; - p->type = fun->header.type; - p->type.qualifier = SLANG_QUAL_OUT; - p->type.specifier.type = baseType; - fun->param_count++; - } - - /* function body is: - * block: - * declare T; - * T[0] = p0; - * T[1] = p1; - * ... - * T[n] = pn; - * return T; - */ - { - slang_variable_scope *scope; - slang_variable *var; - GLint i; - - fun->body = slang_operation_new(1); - fun->body->type = SLANG_OPER_BLOCK_NEW_SCOPE; - fun->body->num_children = num_elements + 2; - fun->body->children = slang_operation_new(num_elements + 2); - - scope = fun->body->locals; - scope->outer_scope = fun->parameters; - - /* create local var 't' */ - var = slang_variable_scope_grow(scope); - var->a_name = slang_atom_pool_atom(A->atoms, "ttt"); - var->type = fun->header.type;/*XXX copy*/ - - /* declare t */ - { - slang_operation *decl; - - decl = &fun->body->children[0]; - decl->type = SLANG_OPER_VARIABLE_DECL; - decl->locals = _slang_variable_scope_new(scope); - decl->a_id = var->a_name; - } - - /* assign params to elements of t */ - for (i = 0; i < num_elements; i++) { - slang_operation *assign = &fun->body->children[1 + i]; - - assign->type = SLANG_OPER_ASSIGN; - assign->locals = _slang_variable_scope_new(scope); - assign->num_children = 2; - assign->children = slang_operation_new(2); - - { - slang_operation *lhs = &assign->children[0]; - - lhs->type = SLANG_OPER_SUBSCRIPT; - lhs->locals = _slang_variable_scope_new(scope); - lhs->num_children = 2; - lhs->children = slang_operation_new(2); - - lhs->children[0].type = SLANG_OPER_IDENTIFIER; - lhs->children[0].a_id = var->a_name; - lhs->children[0].locals = _slang_variable_scope_new(scope); - - lhs->children[1].type = SLANG_OPER_LITERAL_INT; - lhs->children[1].literal[0] = (GLfloat) i; - } - - { - slang_operation *rhs = &assign->children[1]; - - rhs->type = SLANG_OPER_IDENTIFIER; - rhs->locals = _slang_variable_scope_new(scope); - rhs->a_id = fun->parameters->variables[i]->a_name; - } - } - - /* return t; */ - { - slang_operation *ret = &fun->body->children[num_elements + 1]; - - ret->type = SLANG_OPER_RETURN; - ret->locals = _slang_variable_scope_new(scope); - ret->num_children = 1; - ret->children = slang_operation_new(1); - ret->children[0].type = SLANG_OPER_IDENTIFIER; - ret->children[0].a_id = var->a_name; - ret->children[0].locals = _slang_variable_scope_new(scope); - } - } - - /* - slang_print_function(fun, 1); - */ - - return fun; -} - - -static GLboolean -_slang_is_vec_mat_type(const char *name) -{ - static const char *vecmat_types[] = { - "float", "int", "bool", - "vec2", "vec3", "vec4", - "ivec2", "ivec3", "ivec4", - "bvec2", "bvec3", "bvec4", - "mat2", "mat3", "mat4", - "mat2x3", "mat2x4", "mat3x2", "mat3x4", "mat4x2", "mat4x3", - NULL - }; - int i; - for (i = 0; vecmat_types[i]; i++) - if (strcmp(name, vecmat_types[i]) == 0) - return GL_TRUE; - return GL_FALSE; -} - - -/** - * 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; - slang_ir_node *n; - - atom = slang_atom_pool_atom(A->atoms, name); - if (atom == SLANG_ATOM_NULL) - return NULL; - - if (oper->array_constructor) { - /* this needs special handling */ - fun = _slang_make_array_constructor(A, oper); - } - else { - /* Try to find function by name and exact argument type matching */ - GLboolean error = GL_FALSE; - fun = _slang_function_locate(A->space.funcs, atom, params, param_count, - &A->space, A->atoms, A->log, &error); - if (error) { - slang_info_log_error(A->log, - "Function '%s' not found (check argument types)", - name); - return NULL; - } - } - - if (!fun) { - /* Next, try locating a constructor function for a user-defined type */ - fun = _slang_locate_struct_constructor(A, name); - } - - /* - * At this point, some heuristics are used to try to find a function - * that matches the calling signature by means of casting or "unrolling" - * of constructors. - */ - - if (!fun && _slang_is_vec_mat_type(name)) { - /* Next, if this call looks like a vec() or mat() constructor call, - * try "unwinding" the args to satisfy a constructor. - */ - fun = _slang_find_function_by_max_argc(A->space.funcs, name); - if (fun) { - 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; - } - } - } - - if (!fun && _slang_is_vec_mat_type(name)) { - /* Next, try casting args to the types of the formal parameters */ - int numArgs = oper->num_children; - fun = _slang_find_function_by_argc(A->space.funcs, name, numArgs); - if (!fun || !_slang_cast_func_params(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); - } - - if (!fun) { - slang_info_log_error(A->log, - "Function '%s' not found (check argument types)", - name); - return NULL; - } - - if (!fun->body) { - /* The function body may be in another compilation unit. - * We'll try concatenating the shaders and recompile at link time. - */ - A->UnresolvedRefs = GL_TRUE; - return new_node1(IR_NOP, NULL); - } - - /* type checking to be sure function's return type matches 'dest' type */ - if (dest) { - slang_typeinfo t0; - - slang_typeinfo_construct(&t0); - typeof_operation(A, dest, &t0); - - if (!slang_type_specifier_equal(&t0.spec, &fun->header.type.specifier)) { - slang_info_log_error(A->log, - "Incompatible type returned by call to '%s'", - name); - return NULL; - } - } - - n = _slang_gen_function_call(A, fun, oper, dest); - - if (n && !n->Store && !dest - && fun->header.type.specifier.type != SLANG_SPEC_VOID) { - /* setup n->Store for the result of the function call */ - GLint size = _slang_sizeof_type_specifier(&fun->header.type.specifier); - n->Store = _slang_new_ir_storage(PROGRAM_TEMPORARY, -1, size); - /*printf("Alloc storage for function result, size %d \n", size);*/ - } - - if (oper->array_constructor) { - /* free the temporary array constructor function now */ - slang_function_destruct(fun); - } - - return n; -} - - -static slang_ir_node * -_slang_gen_method_call(slang_assemble_ctx *A, slang_operation *oper) -{ - slang_atom *a_length = slang_atom_pool_atom(A->atoms, "length"); - slang_ir_node *n; - slang_variable *var; - - /* NOTE: In GLSL 1.20, there's only one kind of method - * call: array.length(). Anything else is an error. - */ - if (oper->a_id != a_length) { - slang_info_log_error(A->log, - "Undefined method call '%s'", (char *) oper->a_id); - return NULL; - } - - /* length() takes no arguments */ - if (oper->num_children > 0) { - slang_info_log_error(A->log, "Invalid arguments to length() method"); - return NULL; - } - - /* lookup the object/variable */ - var = _slang_variable_locate(oper->locals, oper->a_obj, GL_TRUE); - if (!var || var->type.specifier.type != SLANG_SPEC_ARRAY) { - slang_info_log_error(A->log, - "Undefined object '%s'", (char *) oper->a_obj); - return NULL; - } - - /* Create a float/literal IR node encoding the array length */ - n = new_node0(IR_FLOAT); - if (n) { - n->Value[0] = (float) _slang_array_length(var); - n->Store = _slang_new_ir_storage(PROGRAM_CONSTANT, -1, 1); - } - return n; -} - - -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; -} - - -/** - * Test if an operation is a scalar or boolean. - */ -static GLboolean -_slang_is_scalar_or_boolean(slang_assemble_ctx *A, slang_operation *oper) -{ - slang_typeinfo type; - GLint size; - - slang_typeinfo_construct(&type); - typeof_operation(A, oper, &type); - size = _slang_sizeof_type_specifier(&type.spec); - slang_typeinfo_destruct(&type); - return size == 1; -} - - -/** - * Test if an operation is boolean. - */ -static GLboolean -_slang_is_boolean(slang_assemble_ctx *A, slang_operation *oper) -{ - slang_typeinfo type; - GLboolean isBool; - - slang_typeinfo_construct(&type); - typeof_operation(A, oper, &type); - isBool = (type.spec.type == SLANG_SPEC_BOOL); - slang_typeinfo_destruct(&type); - return isBool; -} - - -/** - * Check if a loop contains a 'continue' statement. - * Stop looking if we find a nested loop. - */ -static GLboolean -_slang_loop_contains_continue(const slang_operation *oper) -{ - switch (oper->type) { - case SLANG_OPER_CONTINUE: - return GL_TRUE; - case SLANG_OPER_FOR: - case SLANG_OPER_DO: - case SLANG_OPER_WHILE: - /* stop upon finding a nested loop */ - return GL_FALSE; - default: - /* recurse */ - { - GLuint i; - for (i = 0; i < oper->num_children; i++) { - const slang_operation *child = slang_oper_child_const(oper, i); - if (_slang_loop_contains_continue(child)) - return GL_TRUE; - } - } - return GL_FALSE; - } -} - - -/** - * Check if a loop contains a 'continue' or 'break' statement. - * Stop looking if we find a nested loop. - */ -static GLboolean -_slang_loop_contains_continue_or_break(const slang_operation *oper) -{ - switch (oper->type) { - case SLANG_OPER_CONTINUE: - case SLANG_OPER_BREAK: - return GL_TRUE; - case SLANG_OPER_FOR: - case SLANG_OPER_DO: - case SLANG_OPER_WHILE: - /* stop upon finding a nested loop */ - return GL_FALSE; - default: - /* recurse */ - { - GLuint i; - for (i = 0; i < oper->num_children; i++) { - const slang_operation *child = slang_oper_child_const(oper, i); - if (_slang_loop_contains_continue_or_break(child)) - return GL_TRUE; - } - } - return GL_FALSE; - } -} - - -/** - * Replace 'break' and 'continue' statements inside a do and while loops. - * This is a recursive helper function used by - * _slang_gen_do/while_without_continue(). - */ -static void -replace_break_and_cont(slang_assemble_ctx *A, slang_operation *oper) -{ - switch (oper->type) { - case SLANG_OPER_BREAK: - /* replace 'break' with "_notBreakFlag = false; break" */ - { - slang_operation *block = oper; - block->type = SLANG_OPER_BLOCK_NEW_SCOPE; - slang_operation_add_children(block, 2); - { - slang_operation *assign = slang_oper_child(block, 0); - assign->type = SLANG_OPER_ASSIGN; - slang_operation_add_children(assign, 2); - { - slang_operation *lhs = slang_oper_child(assign, 0); - slang_operation_identifier(lhs, A, "_notBreakFlag"); - } - { - slang_operation *rhs = slang_oper_child(assign, 1); - slang_operation_literal_bool(rhs, GL_FALSE); - } - } - { - slang_operation *brk = slang_oper_child(block, 1); - brk->type = SLANG_OPER_BREAK; - assert(!brk->children); - } - } - break; - case SLANG_OPER_CONTINUE: - /* convert continue into a break */ - oper->type = SLANG_OPER_BREAK; - break; - case SLANG_OPER_FOR: - case SLANG_OPER_DO: - case SLANG_OPER_WHILE: - /* stop upon finding a nested loop */ - break; - default: - /* recurse */ - { - GLuint i; - for (i = 0; i < oper->num_children; i++) { - replace_break_and_cont(A, slang_oper_child(oper, i)); - } - } - } -} - - -/** - * Transform a while-loop so that continue statements are converted to breaks. - * Then do normal IR code generation. - * - * Before: - * - * while (LOOPCOND) { - * A; - * if (IFCOND) - * continue; - * B; - * break; - * C; - * } - * - * After: - * - * { - * bool _notBreakFlag = 1; - * while (_notBreakFlag && LOOPCOND) { - * do { - * A; - * if (IFCOND) { - * break; // was continue - * } - * B; - * _notBreakFlag = 0; // was - * break; // break - * C; - * } while (0) - * } - * } - */ -static slang_ir_node * -_slang_gen_while_without_continue(slang_assemble_ctx *A, slang_operation *oper) -{ - slang_operation *top; - slang_operation *innerBody; - - assert(oper->type == SLANG_OPER_WHILE); - - top = slang_operation_new(1); - top->type = SLANG_OPER_BLOCK_NEW_SCOPE; - top->locals->outer_scope = oper->locals->outer_scope; - slang_operation_add_children(top, 2); - - /* declare: bool _notBreakFlag = true */ - { - slang_operation *condDecl = slang_oper_child(top, 0); - slang_generate_declaration(A, top->locals, condDecl, - SLANG_SPEC_BOOL, "_notBreakFlag", GL_TRUE); - } - - /* build outer while-loop: while (_notBreakFlag && LOOPCOND) { ... } */ - { - slang_operation *outerWhile = slang_oper_child(top, 1); - outerWhile->type = SLANG_OPER_WHILE; - slang_operation_add_children(outerWhile, 2); - - /* _notBreakFlag && LOOPCOND */ - { - slang_operation *cond = slang_oper_child(outerWhile, 0); - cond->type = SLANG_OPER_LOGICALAND; - slang_operation_add_children(cond, 2); - { - slang_operation *notBreak = slang_oper_child(cond, 0); - slang_operation_identifier(notBreak, A, "_notBreakFlag"); - } - { - slang_operation *origCond = slang_oper_child(cond, 1); - slang_operation_copy(origCond, slang_oper_child(oper, 0)); - } - } - - /* inner loop */ - { - slang_operation *innerDo = slang_oper_child(outerWhile, 1); - innerDo->type = SLANG_OPER_DO; - slang_operation_add_children(innerDo, 2); - - /* copy original do-loop body into inner do-loop's body */ - innerBody = slang_oper_child(innerDo, 0); - slang_operation_copy(innerBody, slang_oper_child(oper, 1)); - innerBody->locals->outer_scope = innerDo->locals; - - /* inner do-loop's condition is constant/false */ - { - slang_operation *constFalse = slang_oper_child(innerDo, 1); - slang_operation_literal_bool(constFalse, GL_FALSE); - } - } - } - - /* Finally, in innerBody, - * replace "break" with "_notBreakFlag = 0; break" - * replace "continue" with "break" - */ - replace_break_and_cont(A, innerBody); - - /*slang_print_tree(top, 0);*/ - - return _slang_gen_operation(A, top); - - return NULL; -} - - -/** - * Generate loop code using high-level IR_LOOP instruction - */ -static slang_ir_node * -_slang_gen_while(slang_assemble_ctx * A, slang_operation *oper) -{ - /* - * LOOP: - * BREAK if !expr (child[0]) - * body code (child[1]) - */ - slang_ir_node *loop, *breakIf, *body; - GLboolean isConst, constTrue = GL_FALSE; - - if (!A->EmitContReturn) { - /* We don't want to emit CONT instructions. If this while-loop has - * a continue, translate it away. - */ - if (_slang_loop_contains_continue(slang_oper_child(oper, 1))) { - return _slang_gen_while_without_continue(A, oper); - } - } - - /* type-check expression */ - if (!_slang_is_boolean(A, &oper->children[0])) { - slang_info_log_error(A->log, "scalar/boolean expression expected for 'while'"); - return NULL; - } - - /* 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); - } - - /* Begin new loop */ - loop = new_loop(NULL); - - /* save loop state */ - push_loop(A, oper, loop); - - if (isConst && constTrue) { - /* while(nonzero constant), no conditional break */ - breakIf = NULL; - } - else { - slang_ir_node *cond - = new_cond(new_not(_slang_gen_operation(A, &oper->children[0]))); - breakIf = new_break_if_true(A, cond); - } - 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 */ - pop_loop(A); - slang_info_log_error(A->log, "Infinite loop detected!"); - return NULL; - } - - /* restore loop state */ - pop_loop(A); - - return loop; -} - - -/** - * Transform a do-while-loop so that continue statements are converted to breaks. - * Then do normal IR code generation. - * - * Before: - * - * do { - * A; - * if (IFCOND) - * continue; - * B; - * break; - * C; - * } while (LOOPCOND); - * - * After: - * - * { - * bool _notBreakFlag = 1; - * do { - * do { - * A; - * if (IFCOND) { - * break; // was continue - * } - * B; - * _notBreakFlag = 0; // was - * break; // break - * C; - * } while (0) - * } while (_notBreakFlag && LOOPCOND); - * } - */ -static slang_ir_node * -_slang_gen_do_without_continue(slang_assemble_ctx *A, slang_operation *oper) -{ - slang_operation *top; - slang_operation *innerBody; - - assert(oper->type == SLANG_OPER_DO); - - top = slang_operation_new(1); - top->type = SLANG_OPER_BLOCK_NEW_SCOPE; - top->locals->outer_scope = oper->locals->outer_scope; - slang_operation_add_children(top, 2); - - /* declare: bool _notBreakFlag = true */ - { - slang_operation *condDecl = slang_oper_child(top, 0); - slang_generate_declaration(A, top->locals, condDecl, - SLANG_SPEC_BOOL, "_notBreakFlag", GL_TRUE); - } - - /* build outer do-loop: do { ... } while (_notBreakFlag && LOOPCOND) */ - { - slang_operation *outerDo = slang_oper_child(top, 1); - outerDo->type = SLANG_OPER_DO; - slang_operation_add_children(outerDo, 2); - - /* inner do-loop */ - { - slang_operation *innerDo = slang_oper_child(outerDo, 0); - innerDo->type = SLANG_OPER_DO; - slang_operation_add_children(innerDo, 2); - - /* copy original do-loop body into inner do-loop's body */ - innerBody = slang_oper_child(innerDo, 0); - slang_operation_copy(innerBody, slang_oper_child(oper, 0)); - innerBody->locals->outer_scope = innerDo->locals; - - /* inner do-loop's condition is constant/false */ - { - slang_operation *constFalse = slang_oper_child(innerDo, 1); - slang_operation_literal_bool(constFalse, GL_FALSE); - } - } - - /* _notBreakFlag && LOOPCOND */ - { - slang_operation *cond = slang_oper_child(outerDo, 1); - cond->type = SLANG_OPER_LOGICALAND; - slang_operation_add_children(cond, 2); - { - slang_operation *notBreak = slang_oper_child(cond, 0); - slang_operation_identifier(notBreak, A, "_notBreakFlag"); - } - { - slang_operation *origCond = slang_oper_child(cond, 1); - slang_operation_copy(origCond, slang_oper_child(oper, 1)); - } - } - } - - /* Finally, in innerBody, - * replace "break" with "_notBreakFlag = 0; break" - * replace "continue" with "break" - */ - replace_break_and_cont(A, innerBody); - - /*slang_print_tree(top, 0);*/ - - return _slang_gen_operation(A, top); -} - - -/** - * 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, slang_operation *oper) -{ - /* - * LOOP: - * body code (child[0]) - * tail code: - * BREAK if !expr (child[1]) - */ - slang_ir_node *loop; - GLboolean isConst, constTrue; - - if (!A->EmitContReturn) { - /* We don't want to emit CONT instructions. If this do-loop has - * a continue, translate it away. - */ - if (_slang_loop_contains_continue(slang_oper_child(oper, 0))) { - return _slang_gen_do_without_continue(A, oper); - } - } - - /* type-check expression */ - if (!_slang_is_boolean(A, &oper->children[1])) { - slang_info_log_error(A->log, "scalar/boolean expression expected for 'do/while'"); - return NULL; - } - - loop = new_loop(NULL); - - /* save loop state */ - push_loop(A, oper, 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 { - slang_ir_node *cond - = new_cond(new_not(_slang_gen_operation(A, &oper->children[1]))); - loop->Children[1] = new_break_if_true(A, cond); - } - - /* XXX we should do infinite loop detection, as above */ - - /* restore loop state */ - pop_loop(A); - - return loop; -} - - -/** - * Recursively count the number of operations rooted at 'oper'. - * This gives some kind of indication of the size/complexity of an operation. - */ -static GLuint -sizeof_operation(const slang_operation *oper) -{ - if (oper) { - GLuint count = 1; /* me */ - GLuint i; - for (i = 0; i < oper->num_children; i++) { - count += sizeof_operation(&oper->children[i]); - } - return count; - } - else { - return 0; - } -} - - -/** - * Determine if a for-loop can be unrolled. - * At this time, only a rather narrow class of for loops can be unrolled. - * See code for details. - * When a loop can't be unrolled because it's too large we'll emit a - * message to the log. - */ -static GLboolean -_slang_can_unroll_for_loop(slang_assemble_ctx * A, const slang_operation *oper) -{ - GLuint bodySize; - GLint start, end; - const char *varName; - slang_atom varId; - - if (oper->type != SLANG_OPER_FOR) - return GL_FALSE; - - assert(oper->num_children == 4); - - if (_slang_loop_contains_continue_or_break(slang_oper_child_const(oper, 3))) - return GL_FALSE; - - /* children[0] must be either "int i=constant" or "i=constant" */ - if (oper->children[0].type == SLANG_OPER_BLOCK_NO_NEW_SCOPE) { - slang_variable *var; - - if (oper->children[0].children[0].type != SLANG_OPER_VARIABLE_DECL) - return GL_FALSE; - - varId = oper->children[0].children[0].a_id; - - var = _slang_variable_locate(oper->children[0].children[0].locals, - varId, GL_TRUE); - if (!var) - return GL_FALSE; - if (!var->initializer) - return GL_FALSE; - if (var->initializer->type != SLANG_OPER_LITERAL_INT) - return GL_FALSE; - start = (GLint) var->initializer->literal[0]; - } - else if (oper->children[0].type == SLANG_OPER_EXPRESSION) { - if (oper->children[0].children[0].type != SLANG_OPER_ASSIGN) - return GL_FALSE; - if (oper->children[0].children[0].children[0].type != SLANG_OPER_IDENTIFIER) - return GL_FALSE; - if (oper->children[0].children[0].children[1].type != SLANG_OPER_LITERAL_INT) - return GL_FALSE; - - varId = oper->children[0].children[0].children[0].a_id; - - start = (GLint) oper->children[0].children[0].children[1].literal[0]; - } - else { - return GL_FALSE; - } - - /* children[1] must be "i<constant" */ - if (oper->children[1].type != SLANG_OPER_EXPRESSION) - return GL_FALSE; - if (oper->children[1].children[0].type != SLANG_OPER_LESS) - return GL_FALSE; - if (oper->children[1].children[0].children[0].type != SLANG_OPER_IDENTIFIER) - return GL_FALSE; - if (oper->children[1].children[0].children[1].type != SLANG_OPER_LITERAL_INT) - return GL_FALSE; - - end = (GLint) oper->children[1].children[0].children[1].literal[0]; - - /* children[2] must be "i++" or "++i" */ - if (oper->children[2].type != SLANG_OPER_POSTINCREMENT && - oper->children[2].type != SLANG_OPER_PREINCREMENT) - return GL_FALSE; - if (oper->children[2].children[0].type != SLANG_OPER_IDENTIFIER) - return GL_FALSE; - - /* make sure the same variable name is used in all places */ - if ((oper->children[1].children[0].children[0].a_id != varId) || - (oper->children[2].children[0].a_id != varId)) - return GL_FALSE; - - varName = (const char *) varId; - - /* children[3], the loop body, can't be too large */ - bodySize = sizeof_operation(&oper->children[3]); - if (bodySize > MAX_FOR_LOOP_UNROLL_BODY_SIZE) { - slang_info_log_print(A->log, - "Note: 'for (%s ... )' body is too large/complex" - " to unroll", - varName); - return GL_FALSE; - } - - if (start >= end) - return GL_FALSE; /* degenerate case */ - - if ((GLuint)(end - start) > MAX_FOR_LOOP_UNROLL_ITERATIONS) { - slang_info_log_print(A->log, - "Note: 'for (%s=%d; %s<%d; ++%s)' is too" - " many iterations to unroll", - varName, start, varName, end, varName); - return GL_FALSE; - } - - if ((end - start) * bodySize > MAX_FOR_LOOP_UNROLL_COMPLEXITY) { - slang_info_log_print(A->log, - "Note: 'for (%s=%d; %s<%d; ++%s)' will generate" - " too much code to unroll", - varName, start, varName, end, varName); - return GL_FALSE; - } - - return GL_TRUE; /* we can unroll the loop */ -} - - -/** - * Unroll a for-loop. - * First we determine the number of iterations to unroll. - * Then for each iteration: - * make a copy of the loop body - * replace instances of the loop variable with the current iteration value - * generate IR code for the body - * \return pointer to generated IR code or NULL if error, out of memory, etc. - */ -static slang_ir_node * -_slang_unroll_for_loop(slang_assemble_ctx * A, const slang_operation *oper) -{ - GLint start, end, iter; - slang_ir_node *n, *root = NULL; - slang_atom varId; - - if (oper->children[0].type == SLANG_OPER_BLOCK_NO_NEW_SCOPE) { - /* for (int i=0; ... */ - slang_variable *var; - - varId = oper->children[0].children[0].a_id; - var = _slang_variable_locate(oper->children[0].children[0].locals, - varId, GL_TRUE); - assert(var); - start = (GLint) var->initializer->literal[0]; - } - else { - /* for (i=0; ... */ - varId = oper->children[0].children[0].children[0].a_id; - start = (GLint) oper->children[0].children[0].children[1].literal[0]; - } - - end = (GLint) oper->children[1].children[0].children[1].literal[0]; - - for (iter = start; iter < end; iter++) { - slang_operation *body; - - /* make a copy of the loop body */ - body = slang_operation_new(1); - if (!body) - return NULL; - - if (!slang_operation_copy(body, &oper->children[3])) - return NULL; - - /* in body, replace instances of 'varId' with literal 'iter' */ - { - slang_variable *oldVar; - slang_operation *newOper; - - oldVar = _slang_variable_locate(oper->locals, varId, GL_TRUE); - if (!oldVar) { - /* undeclared loop variable */ - slang_operation_delete(body); - return NULL; - } - - newOper = slang_operation_new(1); - newOper->type = SLANG_OPER_LITERAL_INT; - newOper->literal_size = 1; - newOper->literal[0] = (GLfloat) iter; - - /* replace instances of the loop variable with newOper */ - slang_substitute(A, body, 1, &oldVar, &newOper, GL_FALSE); - } - - /* do IR codegen for body */ - n = _slang_gen_operation(A, body); - if (!n) - return NULL; - - root = new_seq(root, n); - - slang_operation_delete(body); - } - - return root; -} - - -/** - * Replace 'continue' statement with 'break' inside a for-loop. - * This is a recursive helper function used by _slang_gen_for_without_continue(). - */ -static void -replace_continue_with_break(slang_assemble_ctx *A, slang_operation *oper) -{ - switch (oper->type) { - case SLANG_OPER_CONTINUE: - oper->type = SLANG_OPER_BREAK; - break; - case SLANG_OPER_FOR: - case SLANG_OPER_DO: - case SLANG_OPER_WHILE: - /* stop upon finding a nested loop */ - break; - default: - /* recurse */ - { - GLuint i; - for (i = 0; i < oper->num_children; i++) { - replace_continue_with_break(A, slang_oper_child(oper, i)); - } - } - } -} - - -/** - * Transform a for-loop so that continue statements are converted to breaks. - * Then do normal IR code generation. - * - * Before: - * - * for (INIT; LOOPCOND; INCR) { - * A; - * if (IFCOND) { - * continue; - * } - * B; - * } - * - * After: - * - * { - * bool _condFlag = 1; - * for (INIT; _condFlag; ) { - * for ( ; _condFlag = LOOPCOND; INCR) { - * A; - * if (IFCOND) { - * break; - * } - * B; - * } - * if (_condFlag) - * INCR; - * } - * } - */ -static slang_ir_node * -_slang_gen_for_without_continue(slang_assemble_ctx *A, slang_operation *oper) -{ - slang_operation *top; - slang_operation *outerFor, *innerFor, *init, *cond, *incr; - slang_operation *lhs, *rhs; - - assert(oper->type == SLANG_OPER_FOR); - - top = slang_operation_new(1); - top->type = SLANG_OPER_BLOCK_NEW_SCOPE; - top->locals->outer_scope = oper->locals->outer_scope; - slang_operation_add_children(top, 2); - - /* declare: bool _condFlag = true */ - { - slang_operation *condDecl = slang_oper_child(top, 0); - slang_generate_declaration(A, top->locals, condDecl, - SLANG_SPEC_BOOL, "_condFlag", GL_TRUE); - } - - /* build outer loop: for (INIT; _condFlag; ) { */ - outerFor = slang_oper_child(top, 1); - outerFor->type = SLANG_OPER_FOR; - slang_operation_add_children(outerFor, 4); - - init = slang_oper_child(outerFor, 0); - slang_operation_copy(init, slang_oper_child(oper, 0)); - - cond = slang_oper_child(outerFor, 1); - cond->type = SLANG_OPER_IDENTIFIER; - cond->a_id = slang_atom_pool_atom(A->atoms, "_condFlag"); - - incr = slang_oper_child(outerFor, 2); - incr->type = SLANG_OPER_VOID; - - /* body of the outer loop */ - { - slang_operation *block = slang_oper_child(outerFor, 3); - - slang_operation_add_children(block, 2); - block->type = SLANG_OPER_BLOCK_NO_NEW_SCOPE; - - /* build inner loop: for ( ; _condFlag = LOOPCOND; INCR) { */ - { - innerFor = slang_oper_child(block, 0); - - /* make copy of orig loop */ - slang_operation_copy(innerFor, oper); - assert(innerFor->type == SLANG_OPER_FOR); - innerFor->locals->outer_scope = block->locals; - - init = slang_oper_child(innerFor, 0); - init->type = SLANG_OPER_VOID; /* leak? */ - - cond = slang_oper_child(innerFor, 1); - slang_operation_destruct(cond); - cond->type = SLANG_OPER_ASSIGN; - cond->locals = _slang_variable_scope_new(innerFor->locals); - slang_operation_add_children(cond, 2); - - lhs = slang_oper_child(cond, 0); - lhs->type = SLANG_OPER_IDENTIFIER; - lhs->a_id = slang_atom_pool_atom(A->atoms, "_condFlag"); - - rhs = slang_oper_child(cond, 1); - slang_operation_copy(rhs, slang_oper_child(oper, 1)); - } - - /* if (_condFlag) INCR; */ - { - slang_operation *ifop = slang_oper_child(block, 1); - ifop->type = SLANG_OPER_IF; - slang_operation_add_children(ifop, 2); - - /* re-use cond node build above */ - slang_operation_copy(slang_oper_child(ifop, 0), cond); - - /* incr node from original for-loop operation */ - slang_operation_copy(slang_oper_child(ifop, 1), - slang_oper_child(oper, 2)); - } - - /* finally, replace "continue" with "break" in the inner for-loop */ - replace_continue_with_break(A, slang_oper_child(innerFor, 3)); - } - - return _slang_gen_operation(A, top); -} - - - -/** - * Generate IR for a for-loop. Unrolling will be done when possible. - */ -static slang_ir_node * -_slang_gen_for(slang_assemble_ctx * A, slang_operation *oper) -{ - GLboolean unroll; - - if (!A->EmitContReturn) { - /* We don't want to emit CONT instructions. If this for-loop has - * a continue, translate it away. - */ - if (_slang_loop_contains_continue(slang_oper_child(oper, 3))) { - return _slang_gen_for_without_continue(A, oper); - } - } - - unroll = _slang_can_unroll_for_loop(A, oper); - if (unroll) { - slang_ir_node *code = _slang_unroll_for_loop(A, oper); - if (code) - return code; - } - - assert(oper->type == SLANG_OPER_FOR); - - /* conventional for-loop code generation */ - { - /* - * 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 *loop, *cond, *breakIf, *body, *init, *incr; - init = _slang_gen_operation(A, &oper->children[0]); - loop = new_loop(NULL); - - /* save loop state */ - push_loop(A, oper, loop); - - cond = new_cond(new_not(_slang_gen_operation(A, &oper->children[1]))); - breakIf = new_break_if_true(A, cond); - 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 */ - - /* restore loop state */ - pop_loop(A); - - return new_seq(init, loop); - } -} - - -static slang_ir_node * -_slang_gen_continue(slang_assemble_ctx * A, const slang_operation *oper) -{ - slang_ir_node *n, *cont, *incr = NULL, *loopNode; - - assert(oper->type == SLANG_OPER_CONTINUE); - loopNode = current_loop_ir(A); - assert(loopNode); - assert(loopNode->Opcode == IR_LOOP); - - cont = new_node0(IR_CONT); - if (cont) { - cont->Parent = loopNode; - /* insert this node at head of linked list of cont/break instructions */ - cont->List = loopNode->List; - loopNode->List = cont; - } - - n = new_seq(incr, cont); - return n; -} - - -/** - * Determine if the given operation is of a specific type. - */ -static GLboolean -is_operation_type(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; - GLboolean isConst, constTrue; - - /* type-check expression */ - if (!_slang_is_boolean(A, &oper->children[0])) { - slang_info_log_error(A->log, "boolean expression expected for 'if'"); - return NULL; - } - - if (!_slang_is_scalar_or_boolean(A, &oper->children[0])) { - slang_info_log_error(A->log, "scalar/boolean expression expected for 'if'"); - return NULL; - } - - isConst = _slang_is_constant_cond(&oper->children[0], &constTrue); - if (isConst) { - if (constTrue) { - /* if (true) ... */ - return _slang_gen_operation(A, &oper->children[1]); - } - else { - /* if (false) ... */ - return _slang_gen_operation(A, &oper->children[2]); - } - } - - cond = _slang_gen_operation(A, &oper->children[0]); - cond = new_cond(cond); - - if (is_operation_type(&oper->children[1], SLANG_OPER_BREAK) - && !haveElseClause) { - /* Special case: generate a conditional break */ - ifBody = new_break_if_true(A, cond); - return ifBody; - } - else if (is_operation_type(&oper->children[1], SLANG_OPER_CONTINUE) - && !haveElseClause - && current_loop_oper(A) - && current_loop_oper(A)->type != SLANG_OPER_FOR) { - /* Special case: generate a conditional continue */ - ifBody = new_cont_if_true(A, cond); - 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; - } -} - - - -static slang_ir_node * -_slang_gen_not(slang_assemble_ctx * A, const slang_operation *oper) -{ - slang_ir_node *n; - - assert(oper->type == SLANG_OPER_NOT); - - /* type-check expression */ - if (!_slang_is_scalar_or_boolean(A, &oper->children[0])) { - slang_info_log_error(A->log, - "scalar/boolean expression expected for '!'"); - return NULL; - } - - n = _slang_gen_operation(A, &oper->children[0]); - if (n) - return new_not(n); - else - return NULL; -} - - -static slang_ir_node * -_slang_gen_xor(slang_assemble_ctx * A, const slang_operation *oper) -{ - slang_ir_node *n1, *n2; - - assert(oper->type == SLANG_OPER_LOGICALXOR); - - if (!_slang_is_scalar_or_boolean(A, &oper->children[0]) || - !_slang_is_scalar_or_boolean(A, &oper->children[0])) { - slang_info_log_error(A->log, - "scalar/boolean expressions expected for '^^'"); - return NULL; - } - - n1 = _slang_gen_operation(A, &oper->children[0]); - if (!n1) - return NULL; - n2 = _slang_gen_operation(A, &oper->children[1]); - if (!n2) - return NULL; - return new_node2(IR_NOTEQUAL, n1, n2); -} - - -/** - * 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 = NULL; - - store = _slang_new_ir_storage(PROGRAM_TEMPORARY, -2, size); - if (store) { - n = new_node0(IR_VAR_DECL); - if (n) { - n->Store = store; - } - else { - _slang_free(store); - } - } - return n; -} - - -/** - * Generate program constants for an array. - * Ex: const vec2[3] v = vec2[3](vec2(1,1), vec2(2,2), vec2(3,3)); - * This will allocate and initialize three vector constants, storing - * the array in constant memory, not temporaries like a non-const array. - * This can also be used for uniform array initializers. - * \return GL_TRUE for success, GL_FALSE if failure (semantic error, etc). - */ -static GLboolean -make_constant_array(slang_assemble_ctx *A, - slang_variable *var, - slang_operation *initializer) -{ - struct gl_program *prog = A->program; - const GLenum datatype = _slang_gltype_from_specifier(&var->type.specifier); - const char *varName = (char *) var->a_name; - const GLuint numElements = initializer->num_children; - GLint size; - GLuint i, j; - GLfloat *values; - - if (!var->store) { - var->store = _slang_new_ir_storage(PROGRAM_UNDEFINED, -6, -6); - } - size = var->store->Size; - - assert(var->type.qualifier == SLANG_QUAL_CONST || - var->type.qualifier == SLANG_QUAL_UNIFORM); - assert(initializer->type == SLANG_OPER_CALL); - assert(initializer->array_constructor); - - values = (GLfloat *) malloc(numElements * 4 * sizeof(GLfloat)); - - /* convert constructor params into ordinary floats */ - for (i = 0; i < numElements; i++) { - const slang_operation *op = &initializer->children[i]; - if (op->type != SLANG_OPER_LITERAL_FLOAT) { - /* unsupported type for this optimization */ - free(values); - return GL_FALSE; - } - for (j = 0; j < op->literal_size; j++) { - values[i * 4 + j] = op->literal[j]; - } - for ( ; j < 4; j++) { - values[i * 4 + j] = 0.0f; - } - } - - /* slightly different paths for constants vs. uniforms */ - if (var->type.qualifier == SLANG_QUAL_UNIFORM) { - var->store->File = PROGRAM_UNIFORM; - var->store->Index = _mesa_add_uniform(prog->Parameters, varName, - size, datatype, values); - } - else { - var->store->File = PROGRAM_CONSTANT; - var->store->Index = _mesa_add_named_constant(prog->Parameters, varName, - values, size); - } - assert(var->store->Size == size); - - free(values); - - return GL_TRUE; -} - - - -/** - * Generate IR node for allocating/declaring a variable (either a local or - * a global). - * Generally, this involves allocating an slang_ir_storage instance for the - * variable, choosing a register file (temporary, constant, etc). - * For ordinary variables we do not yet allocate storage though. We do that - * when we find the first actual use of the variable to avoid allocating temp - * regs that will never get used. - * At this time, uniforms are always allocated space in this function. - * - * \param initializer Optional initializer expression for the variable. - */ -static slang_ir_node * -_slang_gen_var_decl(slang_assemble_ctx *A, slang_variable *var, - slang_operation *initializer) -{ - const char *varName = (const char *) var->a_name; - const GLenum datatype = _slang_gltype_from_specifier(&var->type.specifier); - slang_ir_node *varDecl, *n; - slang_ir_storage *store; - GLint arrayLen, size, totalSize; /* if array then totalSize > size */ - gl_register_file file; - - /*assert(!var->declared);*/ - var->declared = GL_TRUE; - - /* determine GPU register file for simple cases */ - if (is_sampler_type(&var->type)) { - file = PROGRAM_SAMPLER; - } - else if (var->type.qualifier == SLANG_QUAL_UNIFORM) { - file = PROGRAM_UNIFORM; - } - else { - file = PROGRAM_TEMPORARY; - } - - size = _slang_sizeof_type_specifier(&var->type.specifier); - if (size <= 0) { - slang_info_log_error(A->log, "invalid declaration for '%s'", varName); - return NULL; - } - - arrayLen = _slang_array_length(var); - totalSize = _slang_array_size(size, arrayLen); - - /* Allocate IR node for the declaration */ - varDecl = new_node0(IR_VAR_DECL); - if (!varDecl) - return NULL; - - /* Allocate slang_ir_storage for this variable if needed. - * Note that we may not actually allocate a constant or temporary register - * until later. - */ - if (!var->store) { - GLint index = -7; /* TBD / unknown */ - var->store = _slang_new_ir_storage(file, index, totalSize); - if (!var->store) - return NULL; /* out of memory */ - } - - /* set the IR node's Var and Store pointers */ - varDecl->Var = var; - varDecl->Store = var->store; - - - store = var->store; - - /* if there's an initializer, generate IR for the expression */ - if (initializer) { - slang_ir_node *varRef, *init; - - if (var->type.qualifier == SLANG_QUAL_CONST) { - /* if the variable is const, the initializer must be a const - * expression as well. - */ -#if 0 - if (!_slang_is_constant_expr(initializer)) { - slang_info_log_error(A->log, - "initializer for %s not constant", varName); - return NULL; - } -#endif - } - - if (var->type.qualifier == SLANG_QUAL_UNIFORM && - !A->allow_uniform_initializers) { - slang_info_log_error(A->log, - "initializer for uniform %s not allowed", - varName); - return NULL; - } - - /* IR for the variable we're initializing */ - varRef = new_var(A, var); - if (!varRef) { - slang_info_log_error(A->log, "out of memory"); - return NULL; - } - - /* constant-folding, etc here */ - _slang_simplify(initializer, &A->space, A->atoms); - - /* look for simple constant-valued variables and uniforms */ - if (var->type.qualifier == SLANG_QUAL_CONST || - var->type.qualifier == SLANG_QUAL_UNIFORM) { - - if (initializer->type == SLANG_OPER_CALL && - initializer->array_constructor) { - /* array initializer */ - if (make_constant_array(A, var, initializer)) - return varRef; - } - else if (initializer->type == SLANG_OPER_LITERAL_FLOAT || - initializer->type == SLANG_OPER_LITERAL_INT) { - /* simple float/vector initializer */ - if (store->File == PROGRAM_UNIFORM) { - store->Index = _mesa_add_uniform(A->program->Parameters, - varName, - totalSize, datatype, - initializer->literal); - store->Swizzle = _slang_var_swizzle(size, 0); - return varRef; - } -#if 0 - else { - store->File = PROGRAM_CONSTANT; - store->Index = _mesa_add_named_constant(A->program->Parameters, - varName, - initializer->literal, - totalSize); - store->Swizzle = _slang_var_swizzle(size, 0); - return varRef; - } -#endif - } - } - - /* IR for initializer */ - init = _slang_gen_operation(A, initializer); - if (!init) - return NULL; - - /* XXX remove this when type checking is added above */ - if (init->Store && init->Store->Size != totalSize) { - slang_info_log_error(A->log, "invalid assignment (wrong types)"); - return NULL; - } - - /* assign RHS to LHS */ - n = new_node2(IR_COPY, varRef, init); - n = new_seq(varDecl, n); - } - else { - /* no initializer */ - n = varDecl; - } - - if (store->File == PROGRAM_UNIFORM && store->Index < 0) { - /* always need to allocate storage for uniforms at this point */ - store->Index = _mesa_add_uniform(A->program->Parameters, varName, - totalSize, datatype, NULL); - store->Swizzle = _slang_var_swizzle(size, 0); - } - -#if 0 - printf("%s var %p %s store=%p index=%d size=%d\n", - __FUNCTION__, (void *) var, (char *) varName, - (void *) store, store->Index, store->Size); -#endif - - 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 type0, type1, type2; - int size, isBool, isEqual; - - assert(oper->type == SLANG_OPER_SELECT); - assert(oper->num_children == 3); - - /* type of children[0] must be boolean */ - slang_typeinfo_construct(&type0); - typeof_operation(A, &oper->children[0], &type0); - isBool = (type0.spec.type == SLANG_SPEC_BOOL); - slang_typeinfo_destruct(&type0); - if (!isBool) { - slang_info_log_error(A->log, "selector type is not boolean"); - return NULL; - } - - slang_typeinfo_construct(&type1); - slang_typeinfo_construct(&type2); - typeof_operation(A, &oper->children[1], &type1); - typeof_operation(A, &oper->children[2], &type2); - isEqual = slang_type_specifier_equal(&type1.spec, &type2.spec); - slang_typeinfo_destruct(&type1); - slang_typeinfo_destruct(&type2); - if (!isEqual) { - slang_info_log_error(A->log, "incompatible types for ?: operator"); - return NULL; - } - - /* size of x or y's type */ - size = _slang_sizeof_type_specifier(&type1.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_COPY, 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_COPY, 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; - slang_operation_add_children(select, 3); - - slang_operation_copy(slang_oper_child(select, 0), &oper->children[0]); - slang_operation_copy(slang_oper_child(select, 1), &oper->children[1]); - slang_operation_literal_bool(slang_oper_child(select, 2), GL_FALSE); - - n = _slang_gen_select(A, 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; - slang_operation_add_children(select, 3); - - slang_operation_copy(slang_oper_child(select, 0), &oper->children[0]); - slang_operation_literal_bool(slang_oper_child(select, 1), GL_TRUE); - slang_operation_copy(slang_oper_child(select, 2), &oper->children[1]); - - n = _slang_gen_select(A, select); - return n; -} - - -/** - * Generate IR tree for a return statement. - */ -static slang_ir_node * -_slang_gen_return(slang_assemble_ctx * A, slang_operation *oper) -{ - assert(oper->type == SLANG_OPER_RETURN); - return new_return(A->curFuncEndLabel); -} - - -#if 0 -/** - * Determine if the given operation/expression is const-valued. - */ -static GLboolean -_slang_is_constant_expr(const slang_operation *oper) -{ - slang_variable *var; - GLuint i; - - switch (oper->type) { - case SLANG_OPER_IDENTIFIER: - var = _slang_variable_locate(oper->locals, oper->a_id, GL_TRUE); - if (var && var->type.qualifier == SLANG_QUAL_CONST) - return GL_TRUE; - return GL_FALSE; - default: - for (i = 0; i < oper->num_children; i++) { - if (!_slang_is_constant_expr(&oper->children[i])) - return GL_FALSE; - } - return GL_TRUE; - } -} -#endif - - -/** - * Check if an assignment of type t1 to t0 is legal. - * XXX more cases needed. - */ -static GLboolean -_slang_assignment_compatible(slang_assemble_ctx *A, - slang_operation *op0, - slang_operation *op1) -{ - slang_typeinfo t0, t1; - GLuint sz0, sz1; - - if (op0->type == SLANG_OPER_POSTINCREMENT || - op0->type == SLANG_OPER_POSTDECREMENT) { - return GL_FALSE; - } - - slang_typeinfo_construct(&t0); - typeof_operation(A, op0, &t0); - - slang_typeinfo_construct(&t1); - typeof_operation(A, op1, &t1); - - sz0 = _slang_sizeof_type_specifier(&t0.spec); - sz1 = _slang_sizeof_type_specifier(&t1.spec); - -#if 1 - if (sz0 != sz1) { - /*printf("assignment size mismatch %u vs %u\n", sz0, sz1);*/ - return GL_FALSE; - } -#endif - - if (t0.spec.type == SLANG_SPEC_STRUCT && - t1.spec.type == SLANG_SPEC_STRUCT && - t0.spec._struct->a_name != t1.spec._struct->a_name) - return GL_FALSE; - - if (t0.spec.type == SLANG_SPEC_FLOAT && - t1.spec.type == SLANG_SPEC_BOOL) - return GL_FALSE; - -#if 0 /* not used just yet - causes problems elsewhere */ - if (t0.spec.type == SLANG_SPEC_INT && - t1.spec.type == SLANG_SPEC_FLOAT) - return GL_FALSE; -#endif - - if (t0.spec.type == SLANG_SPEC_BOOL && - t1.spec.type == SLANG_SPEC_FLOAT) - return GL_FALSE; - - if (t0.spec.type == SLANG_SPEC_BOOL && - t1.spec.type == SLANG_SPEC_INT) - return GL_FALSE; - - return GL_TRUE; -} - - -/** - * Generate IR tree for a local variable declaration. - * Basically do some error checking and call _slang_gen_var_decl(). - */ -static slang_ir_node * -_slang_gen_declaration(slang_assemble_ctx *A, slang_operation *oper) -{ - const char *varName = (char *) oper->a_id; - slang_variable *var; - slang_ir_node *varDecl; - slang_operation *initializer; - - assert(oper->type == SLANG_OPER_VARIABLE_DECL); - assert(oper->num_children <= 1); - - - /* lookup the variable by name */ - var = _slang_variable_locate(oper->locals, oper->a_id, GL_TRUE); - if (!var) - return NULL; /* "shouldn't happen" */ - - if (var->type.qualifier == SLANG_QUAL_ATTRIBUTE || - var->type.qualifier == SLANG_QUAL_VARYING || - var->type.qualifier == SLANG_QUAL_UNIFORM) { - /* can't declare attribute/uniform vars inside functions */ - slang_info_log_error(A->log, - "local variable '%s' cannot be an attribute/uniform/varying", - varName); - return NULL; - } - -#if 0 - if (v->declared) { - slang_info_log_error(A->log, "variable '%s' redeclared", varName); - return NULL; - } -#endif - - /* check if the var has an initializer */ - if (oper->num_children > 0) { - assert(oper->num_children == 1); - initializer = &oper->children[0]; - } - else if (var->initializer) { - initializer = var->initializer; - } - else { - initializer = NULL; - } - - if (initializer) { - /* check/compare var type and initializer type */ - if (!_slang_assignment_compatible(A, oper, initializer)) { - slang_info_log_error(A->log, "incompatible types in assignment"); - return NULL; - } - } - else { - if (var->type.qualifier == SLANG_QUAL_CONST) { - slang_info_log_error(A->log, - "const-qualified variable '%s' requires initializer", - varName); - return NULL; - } - } - - /* Generate IR node */ - varDecl = _slang_gen_var_decl(A, var, initializer); - if (!varDecl) - return NULL; - - return varDecl; -} - - -/** - * Generate IR tree for a reference to a variable (such as in an expression). - * This is different from a variable declaration. - */ -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 name = oper->var ? oper->var->a_name : oper->a_id; - slang_variable *var = _slang_variable_locate(oper->locals, name, GL_TRUE); - slang_ir_node *n; - if (!var || !var->declared) { - slang_info_log_error(A->log, "undefined variable '%s'", (char *) name); - return NULL; - } - n = new_var(A, var); - return n; -} - - - -/** - * Return the number of components actually named by the swizzle. - * Recall that swizzles may have undefined/don't-care values. - */ -static GLuint -swizzle_size(GLuint swizzle) -{ - GLuint size = 0, i; - for (i = 0; i < 4; i++) { - GLuint swz = GET_SWZ(swizzle, i); - size += (swz <= 3); - } - return size; -} - - -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) { - assert(!n->Store); - n->Store = _slang_new_ir_storage_relative(0, - swizzle_size(swizzle), - child->Store); - assert(n->Store); - n->Store->Swizzle = swizzle; - } - return n; -} - - -static GLboolean -is_store_writable(const slang_assemble_ctx *A, const slang_ir_storage *store) -{ - while (store->Parent) - store = store->Parent; - - if (!(store->File == PROGRAM_OUTPUT || - store->File == PROGRAM_TEMPORARY || - (store->File == PROGRAM_VARYING && - A->program->Target == GL_VERTEX_PROGRAM_ARB))) { - return GL_FALSE; - } - else { - return GL_TRUE; - } -} - - -/** - * Walk up an IR storage path to compute the final swizzle. - * This is used when we find an expression such as "foo.xz.yx". - */ -static GLuint -root_swizzle(const slang_ir_storage *st) -{ - GLuint swizzle = st->Swizzle; - while (st->Parent) { - st = st->Parent; - swizzle = _slang_swizzle_swizzle(st->Swizzle, swizzle); - } - return swizzle; -} - - -/** - * Generate IR tree for an assignment (=). - */ -static slang_ir_node * -_slang_gen_assignment(slang_assemble_ctx * A, slang_operation *oper) -{ - slang_operation *pred = NULL; - slang_ir_node *n = NULL; - - if (oper->children[0].type == SLANG_OPER_IDENTIFIER) { - /* Check that var is writeable */ - const char *varName = (char *) oper->children[0].a_id; - slang_variable *var - = _slang_variable_locate(oper->children[0].locals, - oper->children[0].a_id, GL_TRUE); - if (!var) { - slang_info_log_error(A->log, "undefined variable '%s'", varName); - return NULL; - } - - if (var->type.qualifier == SLANG_QUAL_CONST || - var->type.qualifier == SLANG_QUAL_ATTRIBUTE || - var->type.qualifier == SLANG_QUAL_UNIFORM || - (var->type.qualifier == SLANG_QUAL_VARYING && - A->program->Target == GL_FRAGMENT_PROGRAM_ARB)) { - slang_info_log_error(A->log, - "illegal assignment to read-only variable '%s'", - varName); - return NULL; - } - - /* check if we need to predicate this assignment based on __notRetFlag */ - if ((var->is_global || - var->type.qualifier == SLANG_QUAL_OUT || - var->type.qualifier == SLANG_QUAL_INOUT) && A->UseReturnFlag) { - /* create predicate, used below */ - pred = slang_operation_new(1); - pred->type = SLANG_OPER_IDENTIFIER; - pred->a_id = slang_atom_pool_atom(A->atoms, "__notRetFlag"); - pred->locals->outer_scope = oper->locals->outer_scope; - } - } - - 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. - */ - n = _slang_gen_function_call_name(A, - (const char *) oper->children[1].a_id, - &oper->children[1], &oper->children[0]); - } - else { - slang_ir_node *lhs, *rhs; - - /* lhs and rhs type checking */ - if (!_slang_assignment_compatible(A, - &oper->children[0], - &oper->children[1])) { - slang_info_log_error(A->log, "incompatible types in assignment"); - return NULL; - } - - lhs = _slang_gen_operation(A, &oper->children[0]); - if (!lhs) { - return NULL; - } - - if (!lhs->Store) { - slang_info_log_error(A->log, - "invalid left hand side for assignment"); - return NULL; - } - - /* check that lhs is writable */ - if (!is_store_writable(A, lhs->Store)) { - slang_info_log_error(A->log, - "illegal assignment to read-only l-value"); - return NULL; - } - - rhs = _slang_gen_operation(A, &oper->children[1]); - if (lhs && rhs) { - /* convert lhs swizzle into writemask */ - const GLuint swizzle = root_swizzle(lhs->Store); - GLuint writemask, newSwizzle = 0x0; - if (!swizzle_to_writemask(A, 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_COPY, lhs, rhs); - } - else { - return NULL; - } - } - - if (n && pred) { - /* predicate the assignment code on __notRetFlag */ - slang_ir_node *top, *cond; - - cond = _slang_gen_operation(A, pred); - top = new_if(cond, n, NULL); - return top; - } - return n; -} - - -/** - * Generate IR tree for referencing a field in a struct (or basic vector type) - */ -static slang_ir_node * -_slang_gen_struct_field(slang_assemble_ctx * A, slang_operation *oper) -{ - slang_typeinfo ti; - - /* type of struct */ - slang_typeinfo_construct(&ti); - 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"); - return NULL; - } - 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 - || ti.spec.type == SLANG_SPEC_INT - || ti.spec.type == SLANG_SPEC_BOOL) { - 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 = -1; - - /* type of field */ - slang_typeinfo_construct(&field_ti); - typeof_operation(A, oper, &field_ti); - - fieldSize = _slang_sizeof_type_specifier(&field_ti.spec); - if (fieldSize > 0) - fieldOffset = _slang_field_offset(&ti.spec, oper->a_id); - - if (fieldSize == 0 || fieldOffset < 0) { - const char *structName; - if (ti.spec._struct) - structName = (char *) ti.spec._struct->a_name; - else - structName = "unknown"; - slang_info_log_error(A->log, - "\"%s\" is not a member of struct \"%s\"", - (char *) oper->a_id, structName); - 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) - return NULL; - - n->Field = (char *) oper->a_id; - - /* Store the field's offset in storage->Index */ - n->Store = _slang_new_ir_storage(base->Store->File, - fieldOffset, - fieldSize); - - return n; - } -} - - -/** - * Gen code for array indexing. - */ -static slang_ir_node * -_slang_gen_array_element(slang_assemble_ctx * A, slang_operation *oper) -{ - slang_typeinfo array_ti; - - /* get array's type info */ - slang_typeinfo_construct(&array_ti); - 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 >= (GLint) max) { -#if 0 - slang_info_log_error(A->log, "Invalid array index for vector type"); - printf("type = %d\n", oper->children[1].type); - printf("index = %d, max = %d\n", index, max); - printf("array = %s\n", (char*)oper->children[0].a_id); - printf("index = %s\n", (char*)oper->children[1].a_id); - return NULL; -#else - index = 0; -#endif - } - - 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); - } - 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); - 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 */ - GLint constIndex = -1; - if (index->Opcode == IR_FLOAT) { - constIndex = (int) index->Value[0]; - if (constIndex < 0 || constIndex >= arrayLen) { - slang_info_log_error(A->log, - "Array index out of bounds (index=%d size=%d)", - constIndex, arrayLen); - _slang_free_ir_tree(array); - _slang_free_ir_tree(index); - return NULL; - } - } - - if (!array->Store) { - slang_info_log_error(A->log, "Invalid array"); - return NULL; - } - - elem = new_node2(IR_ELEMENT, array, index); - - /* The storage info here will be updated during code emit */ - elem->Store = _slang_new_ir_storage(array->Store->File, - array->Store->Index, - elemSize); - elem->Store->Swizzle = _slang_var_swizzle(elemSize, 0); - return elem; - } - else { - _slang_free_ir_tree(array); - _slang_free_ir_tree(index); - return NULL; - } - } -} - - -static slang_ir_node * -_slang_gen_compare(slang_assemble_ctx *A, slang_operation *oper, - slang_ir_opcode opcode) -{ - slang_typeinfo t0, t1; - slang_ir_node *n; - - slang_typeinfo_construct(&t0); - typeof_operation(A, &oper->children[0], &t0); - - slang_typeinfo_construct(&t1); - typeof_operation(A, &oper->children[0], &t1); - - if (t0.spec.type == SLANG_SPEC_ARRAY || - t1.spec.type == SLANG_SPEC_ARRAY) { - slang_info_log_error(A->log, "Illegal array comparison"); - return NULL; - } - - if (oper->type != SLANG_OPER_EQUAL && - oper->type != SLANG_OPER_NOTEQUAL) { - /* <, <=, >, >= can only be used with scalars */ - if ((t0.spec.type != SLANG_SPEC_INT && - t0.spec.type != SLANG_SPEC_FLOAT) || - (t1.spec.type != SLANG_SPEC_INT && - t1.spec.type != SLANG_SPEC_FLOAT)) { - slang_info_log_error(A->log, "Incompatible type(s) for inequality operator"); - return NULL; - } - } - - n = new_node2(opcode, - _slang_gen_operation(A, &oper->children[0]), - _slang_gen_operation(A, &oper->children[1])); - - /* result is a bool (size 1) */ - n->Store = _slang_new_ir_storage(PROGRAM_TEMPORARY, -1, 1); - - return n; -} - - -#if 0 -static void -print_vars(slang_variable_scope *s) -{ - int i; - printf("vars: "); - for (i = 0; i < s->num_variables; i++) { - printf("%s %d, \n", - (char*) s->variables[i]->a_name, - s->variables[i]->declared); - } - - printf("\n"); -} -#endif - - -#if 0 -static void -_slang_undeclare_vars(slang_variable_scope *locals) -{ - if (locals->num_variables > 0) { - int i; - for (i = 0; i < locals->num_variables; i++) { - slang_variable *v = locals->variables[i]; - printf("undeclare %s at %p\n", (char*) v->a_name, v); - v->declared = GL_FALSE; - } - } -} -#endif - - -/** - * 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); - - /*_slang_undeclare_vars(oper->locals);*/ - /*print_vars(oper->locals);*/ - - 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 = new_seq(tree, n); - } - - 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 (!current_loop_oper(A)) { - slang_info_log_error(A->log, "'break' not in loop"); - return NULL; - } - return new_break(current_loop_ir(A)); - case SLANG_OPER_CONTINUE: - if (!current_loop_oper(A)) { - slang_info_log_error(A->log, "'continue' not in loop"); - return NULL; - } - return _slang_gen_continue(A, oper); - case SLANG_OPER_DISCARD: - return new_node0(IR_KILL); - - case SLANG_OPER_EQUAL: - return _slang_gen_compare(A, oper, IR_EQUAL); - case SLANG_OPER_NOTEQUAL: - return _slang_gen_compare(A, oper, IR_NOTEQUAL); - case SLANG_OPER_GREATER: - return _slang_gen_compare(A, oper, IR_SGT); - case SLANG_OPER_LESS: - return _slang_gen_compare(A, oper, IR_SLT); - case SLANG_OPER_GREATEREQUAL: - return _slang_gen_compare(A, oper, IR_SGE); - case SLANG_OPER_LESSEQUAL: - return _slang_gen_compare(A, oper, IR_SLE); - 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); - 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, NULL); - return n; - } - case SLANG_OPER_SUBASSIGN: - { - slang_ir_node *n; - assert(oper->num_children == 2); - n = _slang_gen_function_call_name(A, "-=", oper, NULL); - return n; - } - break; - case SLANG_OPER_MULASSIGN: - { - slang_ir_node *n; - assert(oper->num_children == 2); - n = _slang_gen_function_call_name(A, "*=", oper, NULL); - return n; - } - case SLANG_OPER_DIVASSIGN: - { - slang_ir_node *n; - assert(oper->num_children == 2); - n = _slang_gen_function_call_name(A, "/=", oper, NULL); - 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: - return _slang_gen_xor(A, oper); - case SLANG_OPER_NOT: - return _slang_gen_not(A, oper); - 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_METHOD: - return _slang_gen_method_call(A, oper); - case SLANG_OPER_RETURN: - return _slang_gen_return(A, oper); - case SLANG_OPER_RETURN_INLINED: - return _slang_gen_return(A, oper); - 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_struct_field(A, oper); - case SLANG_OPER_SUBSCRIPT: - return _slang_gen_array_element(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, oper->literal_size); - - 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_NON_INLINED_CALL: - 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 = new_seq(tree, n); - if (n) - tree->Store = n->Store; - } - if (oper->type == SLANG_OPER_NON_INLINED_CALL) { - tree = new_function_call(tree, oper->label); - } - return tree; - } - - case SLANG_OPER_NONE: - case SLANG_OPER_VOID: - /* returning NULL here would generate an error */ - return new_node0(IR_NOP); - - default: - _mesa_problem(NULL, "bad node type %d in _slang_gen_operation", - oper->type); - return new_node0(IR_NOP); - } - - return NULL; -} - - -/** - * Check if the given type specifier is a rectangular texture sampler. - */ -static GLboolean -is_rect_sampler_spec(const slang_type_specifier *spec) -{ - while (spec->_array) { - spec = spec->_array; - } - return spec->type == SLANG_SPEC_SAMPLER_RECT || - spec->type == SLANG_SPEC_SAMPLER_RECT_SHADOW; -} - - - -/** - * 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; - slang_ir_storage *store = NULL; - int dbg = 0; - const GLenum datatype = _slang_gltype_from_specifier(&var->type.specifier); - const GLint size = _slang_sizeof_type_specifier(&var->type.specifier); - const GLint arrayLen = _slang_array_length(var); - const GLint totalSize = _slang_array_size(size, arrayLen); - GLint texIndex = sampler_to_texture_index(var->type.specifier.type); - - var->is_global = GL_TRUE; - - /* check for sampler2D arrays */ - if (texIndex == -1 && var->type.specifier._array) - texIndex = sampler_to_texture_index(var->type.specifier._array->type); - - if (texIndex != -1) { - /* This is a texture sampler variable... - * store->File = PROGRAM_SAMPLER - * store->Index = sampler number (0..7, typically) - * store->Size = texture type index (1D, 2D, 3D, cube, etc) - */ - if (var->initializer) { - slang_info_log_error(A->log, "illegal assignment to '%s'", varName); - return GL_FALSE; - } -#if FEATURE_es2_glsl /* XXX should use FEATURE_texture_rect */ - /* disallow rect samplers */ - if (is_rect_sampler_spec(&var->type.specifier)) { - slang_info_log_error(A->log, "invalid sampler type for '%s'", varName); - return GL_FALSE; - } -#else - (void) is_rect_sampler_spec; /* silence warning */ -#endif - { - GLint sampNum = _mesa_add_sampler(prog->Parameters, varName, datatype); - store = _slang_new_ir_storage_sampler(sampNum, texIndex, totalSize); - - /* If we have a sampler array, then we need to allocate the - * additional samplers to ensure we don't allocate them elsewhere. - * We can't directly use _mesa_add_sampler() as that checks the - * varName and gets a match, so we call _mesa_add_parameter() - * directly and use the last sampler number from the call above. - */ - if (arrayLen > 0) { - GLint a = arrayLen - 1; - GLint i; - for (i = 0; i < a; i++) { - GLfloat value = (GLfloat)(i + sampNum + 1); - (void) _mesa_add_parameter(prog->Parameters, PROGRAM_SAMPLER, - varName, 1, datatype, &value, NULL, 0x0); - } - } - } - if (dbg) printf("SAMPLER "); - } - else if (var->type.qualifier == SLANG_QUAL_UNIFORM) { - /* Uniform variable */ - const GLuint swizzle = _slang_var_swizzle(totalSize, 0); - - if (prog) { - /* user-defined uniform */ - if (datatype == GL_NONE) { - if ((var->type.specifier.type == SLANG_SPEC_ARRAY && - var->type.specifier._array->type == SLANG_SPEC_STRUCT) || - (var->type.specifier.type == SLANG_SPEC_STRUCT)) { - /* temporary work-around */ - GLenum datatype = GL_FLOAT; - GLint uniformLoc = _mesa_add_uniform(prog->Parameters, varName, - totalSize, datatype, NULL); - store = _slang_new_ir_storage_swz(PROGRAM_UNIFORM, uniformLoc, - totalSize, swizzle); - - if (arrayLen > 0) { - GLint a = arrayLen - 1; - GLint i; - for (i = 0; i < a; i++) { - GLfloat value = (GLfloat)(i + uniformLoc + 1); - (void) _mesa_add_parameter(prog->Parameters, PROGRAM_UNIFORM, - varName, 1, datatype, &value, NULL, 0x0); - } - } - - /* XXX what we need to do is unroll the struct into its - * basic types, creating a uniform variable for each. - * For example: - * struct foo { - * vec3 a; - * vec4 b; - * }; - * uniform foo f; - * - * Should produce uniforms: - * "f.a" (GL_FLOAT_VEC3) - * "f.b" (GL_FLOAT_VEC4) - */ - - if (var->initializer) { - slang_info_log_error(A->log, - "unsupported initializer for uniform '%s'", varName); - return GL_FALSE; - } - } - else { - slang_info_log_error(A->log, - "invalid datatype for uniform variable %s", - varName); - return GL_FALSE; - } - } - else { - /* non-struct uniform */ - if (!_slang_gen_var_decl(A, var, var->initializer)) - return GL_FALSE; - store = var->store; - } - } - 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_swz(PROGRAM_STATE_VAR, -1, - totalSize, swizzle); - } - if (dbg) printf("UNIFORM (sz %d) ", totalSize); - } - else if (var->type.qualifier == SLANG_QUAL_VARYING) { - /* varyings must be float, vec or mat */ - if (!_slang_type_is_float_vec_mat(var->type.specifier.type) && - var->type.specifier.type != SLANG_SPEC_ARRAY) { - slang_info_log_error(A->log, - "varying '%s' must be float/vector/matrix", - varName); - return GL_FALSE; - } - - if (var->initializer) { - slang_info_log_error(A->log, "illegal initializer for varying '%s'", - varName); - return GL_FALSE; - } - - if (prog) { - /* user-defined varying */ - GLbitfield flags; - GLint varyingLoc; - GLuint swizzle; - - flags = 0x0; - if (var->type.centroid == SLANG_CENTROID) - flags |= PROG_PARAM_BIT_CENTROID; - if (var->type.variant == SLANG_INVARIANT) - flags |= PROG_PARAM_BIT_INVARIANT; - - varyingLoc = _mesa_add_varying(prog->Varying, varName, - totalSize, flags); - swizzle = _slang_var_swizzle(size, 0); - store = _slang_new_ir_storage_swz(PROGRAM_VARYING, varyingLoc, - totalSize, swizzle); - } - else { - /* pre-defined varying, like gl_Color or gl_TexCoord */ - if (type == SLANG_UNIT_FRAGMENT_BUILTIN) { - /* fragment program input */ - GLuint swizzle; - GLint index = _slang_input_index(varName, GL_FRAGMENT_PROGRAM_ARB, - &swizzle); - assert(index >= 0); - assert(index < FRAG_ATTRIB_MAX); - store = _slang_new_ir_storage_swz(PROGRAM_INPUT, index, - size, swizzle); - } - else { - /* vertex program output */ - GLint index = _slang_output_index(varName, GL_VERTEX_PROGRAM_ARB); - GLuint swizzle = _slang_var_swizzle(size, 0); - assert(index >= 0); - assert(index < VERT_RESULT_MAX); - assert(type == SLANG_UNIT_VERTEX_BUILTIN); - store = _slang_new_ir_storage_swz(PROGRAM_OUTPUT, index, - size, swizzle); - } - if (dbg) printf("V/F "); - } - if (dbg) printf("VARYING "); - } - else if (var->type.qualifier == SLANG_QUAL_ATTRIBUTE) { - GLuint swizzle; - GLint index; - /* attributes must be float, vec or mat */ - if (!_slang_type_is_float_vec_mat(var->type.specifier.type)) { - slang_info_log_error(A->log, - "attribute '%s' must be float/vector/matrix", - varName); - return GL_FALSE; - } - - if (prog) { - /* user-defined vertex attribute */ - const GLint attr = -1; /* unknown */ - swizzle = _slang_var_swizzle(size, 0); - index = _mesa_add_attribute(prog->Attributes, varName, - size, datatype, attr); - assert(index >= 0); - index = VERT_ATTRIB_GENERIC0 + index; - } - else { - /* pre-defined vertex attrib */ - index = _slang_input_index(varName, GL_VERTEX_PROGRAM_ARB, &swizzle); - assert(index >= 0); - } - store = _slang_new_ir_storage_swz(PROGRAM_INPUT, index, size, swizzle); - if (dbg) printf("ATTRIB "); - } - else if (var->type.qualifier == SLANG_QUAL_FIXEDINPUT) { - GLuint swizzle = SWIZZLE_XYZW; /* silence compiler warning */ - GLint index = _slang_input_index(varName, GL_FRAGMENT_PROGRAM_ARB, - &swizzle); - store = _slang_new_ir_storage_swz(PROGRAM_INPUT, index, size, 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); - store = _slang_new_ir_storage(PROGRAM_OUTPUT, index, size); - } - else { - GLint index = _slang_output_index(varName, GL_FRAGMENT_PROGRAM_ARB); - GLint specialSize = 4; /* treat all fragment outputs as float[4] */ - assert(type == SLANG_UNIT_FRAGMENT_BUILTIN); - store = _slang_new_ir_storage(PROGRAM_OUTPUT, index, specialSize); - } - if (dbg) printf("OUTPUT "); - } - else if (var->type.qualifier == SLANG_QUAL_CONST && !prog) { - /* pre-defined global constant, like gl_MaxLights */ - 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, var->initializer); - - /* emit GPU instructions */ - success = _slang_emit_code(n, A->vartable, A->program, A->pragmas, 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->store = store; /* save var's storage info */ - - var->declared = GL_TRUE; - - 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 (strcmp((char *) fun->header.a_name, "main") != 0) { - /* we only really generate code for main, all other functions get - * inlined or codegen'd upon an actual call. - */ -#if 0 - /* do some basic error checking though */ - if (fun->header.type.specifier.type != SLANG_SPEC_VOID) { - /* check that non-void functions actually return something */ - slang_operation *op - = _slang_find_node_type(fun->body, SLANG_OPER_RETURN); - if (!op) { - slang_info_log_error(A->log, - "function \"%s\" has no return statement", - (char *) fun->header.a_name); - printf( - "function \"%s\" has no return statement\n", - (char *) fun->header.a_name); - return GL_FALSE; - } - } -#endif - 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); - - A->LoopDepth = 0; - A->UseReturnFlag = GL_FALSE; - A->CurFunction = fun; - - /* 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 - - if (A->UnresolvedRefs) { - /* Can't codegen at this time. - * At link time we'll concatenate all the vertex shaders and/or all - * the fragment shaders and try recompiling. - */ - return GL_TRUE; - } - - /* Emit program instructions */ - success = _slang_emit_code(n, A->vartable, A->program, A->pragmas, GL_TRUE, A->log); - _slang_free_ir_tree(n); - - /* free codegen context */ - /* - free(A->codegen); - */ - - return success; -} - diff --git a/mesalib/src/mesa/shader/slang/slang_codegen.h b/mesalib/src/mesa/shader/slang/slang_codegen.h deleted file mode 100644 index 461633fe3..000000000 --- a/mesalib/src/mesa/shader/slang/slang_codegen.h +++ /dev/null @@ -1,73 +0,0 @@ -/* - * 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_CODEGEN_H -#define SLANG_CODEGEN_H - - -#include "main/imports.h" -#include "slang_compile.h" - - -#define MAX_LOOP_DEPTH 30 - - -typedef struct slang_assemble_ctx_ -{ - slang_atom_pool *atoms; - slang_name_space space; - struct gl_program *program; - struct gl_sl_pragmas *pragmas; - slang_var_table *vartable; - slang_info_log *log; - GLboolean allow_uniform_initializers; - - /* current loop stack */ - const slang_operation *LoopOperStack[MAX_LOOP_DEPTH]; - struct slang_ir_node_ *LoopIRStack[MAX_LOOP_DEPTH]; - GLuint LoopDepth; - - /* current function */ - struct slang_function_ *CurFunction; - struct slang_label_ *curFuncEndLabel; - GLboolean UseReturnFlag; - - GLboolean UnresolvedRefs; - GLboolean EmitContReturn; -} slang_assemble_ctx; - - -extern GLuint -_slang_sizeof_type_specifier(const slang_type_specifier *spec); - -extern GLboolean -_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); - - -#endif /* SLANG_CODEGEN_H */ diff --git a/mesalib/src/mesa/shader/slang/slang_compile.c b/mesalib/src/mesa/shader/slang/slang_compile.c deleted file mode 100644 index ad8667615..000000000 --- a/mesalib/src/mesa/shader/slang/slang_compile.c +++ /dev/null @@ -1,3032 +0,0 @@ -/* - * Mesa 3-D graphics library - * - * Copyright (C) 2005-2006 Brian Paul All Rights Reserved. - * Copyright (C) 2008 VMware, 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. - */ - -/** - * \file slang_compile.c - * slang front-end compiler - * \author Michal Krol - */ - -#include "main/imports.h" -#include "main/context.h" -#include "shader/program.h" -#include "shader/programopt.h" -#include "shader/prog_optimize.h" -#include "shader/prog_print.h" -#include "shader/prog_parameter.h" -#include "../../glsl/pp/sl_pp_public.h" -#include "../../glsl/cl/sl_cl_parse.h" -#include "slang_codegen.h" -#include "slang_compile.h" -#include "slang_storage.h" -#include "slang_log.h" -#include "slang_mem.h" -#include "slang_vartable.h" -#include "slang_simplify.h" - -/* - * This is a straightforward implementation of the slang front-end - * compiler. Lots of error-checking functionality is missing but - * every well-formed shader source should compile successfully and - * execute as expected. However, some semantically ill-formed shaders - * may be accepted resulting in undefined behaviour. - */ - - -/** re-defined below, should be the same though */ -#define TYPE_SPECIFIER_COUNT 36 - - -/** - * Check if the given identifier is legal. - */ -static GLboolean -legal_identifier(slang_atom name) -{ - /* "gl_" is a reserved prefix */ - if (strncmp((char *) name, "gl_", 3) == 0) { - return GL_FALSE; - } - return GL_TRUE; -} - - -/* - * slang_code_unit - */ - -GLvoid -_slang_code_unit_ctr(slang_code_unit * self, - struct slang_code_object_ * object) -{ - _slang_variable_scope_ctr(&self->vars); - _slang_function_scope_ctr(&self->funs); - _slang_struct_scope_ctr(&self->structs); - self->object = object; -} - -GLvoid -_slang_code_unit_dtr(slang_code_unit * self) -{ - slang_variable_scope_destruct(&self->vars); - slang_function_scope_destruct(&self->funs); - slang_struct_scope_destruct(&self->structs); -} - -/* - * slang_code_object - */ - -GLvoid -_slang_code_object_ctr(slang_code_object * self) -{ - GLuint i; - - for (i = 0; i < SLANG_BUILTIN_TOTAL; i++) - _slang_code_unit_ctr(&self->builtin[i], self); - _slang_code_unit_ctr(&self->unit, self); - slang_atom_pool_construct(&self->atompool); -} - -GLvoid -_slang_code_object_dtr(slang_code_object * self) -{ - GLuint i; - - for (i = 0; i < SLANG_BUILTIN_TOTAL; i++) - _slang_code_unit_dtr(&self->builtin[i]); - _slang_code_unit_dtr(&self->unit); - slang_atom_pool_destruct(&self->atompool); -} - - -/* slang_parse_ctx */ - -typedef struct slang_parse_ctx_ -{ - const unsigned char *I; - slang_info_log *L; - int parsing_builtin; - GLboolean global_scope; /**< Is object being declared a global? */ - slang_atom_pool *atoms; - slang_unit_type type; /**< Vertex vs. Fragment */ - GLuint version; /**< user-specified (or default) #version */ -} slang_parse_ctx; - -/* slang_output_ctx */ - -typedef struct slang_output_ctx_ -{ - slang_variable_scope *vars; - slang_function_scope *funs; - slang_struct_scope *structs; - struct gl_program *program; - struct gl_sl_pragmas *pragmas; - slang_var_table *vartable; - GLuint default_precision[TYPE_SPECIFIER_COUNT]; - GLboolean allow_precision; - GLboolean allow_invariant; - GLboolean allow_centroid; - GLboolean allow_array_types; /* float[] syntax */ -} slang_output_ctx; - -/* _slang_compile() */ - - -/* Debugging aid, print file/line where parsing error is detected */ -#define RETURN0 \ - do { \ - if (0) \ - printf("slang error at %s:%d\n", __FILE__, __LINE__); \ - return 0; \ - } while (0) - - -static void -parse_identifier_str(slang_parse_ctx * C, char **id) -{ - *id = (char *) C->I; - C->I += strlen(*id) + 1; -} - -static slang_atom -parse_identifier(slang_parse_ctx * C) -{ - const char *id; - - id = (const char *) C->I; - C->I += strlen(id) + 1; - return slang_atom_pool_atom(C->atoms, id); -} - -static int -is_hex_digit(char c) -{ - return (c >= '0' && c <= '9') || (c >= 'a' && c <= 'f') || (c >= 'A' && c <= 'F'); -} - -static int -parse_general_number(slang_parse_ctx *ctx, float *number) -{ - char *flt = NULL; - - if (*ctx->I == '0') { - int value = 0; - const unsigned char *pi; - - if (ctx->I[1] == 'x' || ctx->I[1] == 'X') { - ctx->I += 2; - if (!is_hex_digit(*ctx->I)) { - return 0; - } - do { - int digit; - - if (*ctx->I >= '0' && *ctx->I <= '9') { - digit = (int)(*ctx->I - '0'); - } else if (*ctx->I >= 'a' && *ctx->I <= 'f') { - digit = (int)(*ctx->I - 'a') + 10; - } else { - digit = (int)(*ctx->I - 'A') + 10; - } - value = value * 0x10 + digit; - ctx->I++; - } while (is_hex_digit(*ctx->I)); - if (*ctx->I != '\0') { - return 0; - } - ctx->I++; - *number = (float)value; - return 1; - } - - pi = ctx->I; - pi++; - while (*pi >= '0' && *pi <= '7') { - int digit; - - digit = (int)(*pi - '0'); - value = value * 010 + digit; - pi++; - } - if (*pi == '\0') { - pi++; - ctx->I = pi; - *number = (float)value; - return 1; - } - } - - parse_identifier_str(ctx, &flt); - flt = _mesa_strdup(flt); - if (!flt) { - return 0; - } - if (flt[strlen(flt) - 1] == 'f' || flt[strlen(flt) - 1] == 'F') { - flt[strlen(flt) - 1] = '\0'; - } - *number = _mesa_strtof(flt, (char **)NULL); - free(flt); - - return 1; -} - -static int -parse_number(slang_parse_ctx * C, int *number) -{ - const int radix = (int) (*C->I++); - - if (radix == 1) { - float f = 0.0f; - - parse_general_number(C, &f); - *number = (int)f; - } else { - *number = 0; - while (*C->I != '\0') { - int digit; - if (*C->I >= '0' && *C->I <= '9') - digit = (int) (*C->I - '0'); - else if (*C->I >= 'A' && *C->I <= 'Z') - digit = (int) (*C->I - 'A') + 10; - else - digit = (int) (*C->I - 'a') + 10; - *number = *number * radix + digit; - C->I++; - } - C->I++; - } - if (*number > 65535) - slang_info_log_warning(C->L, "%d: literal integer overflow.", *number); - return 1; -} - -static int -parse_float(slang_parse_ctx * C, float *number) -{ - if (*C->I == 1) { - C->I++; - parse_general_number(C, number); - } else { - char *integral = NULL; - char *fractional = NULL; - char *exponent = NULL; - char *whole = NULL; - - parse_identifier_str(C, &integral); - parse_identifier_str(C, &fractional); - parse_identifier_str(C, &exponent); - - whole = (char *) _slang_alloc((strlen(integral) + - strlen(fractional) + - strlen(exponent) + 3) * sizeof(char)); - if (whole == NULL) { - slang_info_log_memory(C->L); - RETURN0; - } - - slang_string_copy(whole, integral); - slang_string_concat(whole, "."); - slang_string_concat(whole, fractional); - slang_string_concat(whole, "E"); - slang_string_concat(whole, exponent); - - *number = _mesa_strtof(whole, (char **) NULL); - - _slang_free(whole); - } - - return 1; -} - -/* revision number - increment after each change affecting emitted output */ -#define REVISION 5 - -static int -check_revision(slang_parse_ctx * C) -{ - if (*C->I != REVISION) { - slang_info_log_error(C->L, "Internal compiler error."); - RETURN0; - } - C->I++; - return 1; -} - -static int parse_statement(slang_parse_ctx *, slang_output_ctx *, - slang_operation *); -static int parse_expression(slang_parse_ctx *, slang_output_ctx *, - slang_operation *); -static int parse_type_specifier(slang_parse_ctx *, slang_output_ctx *, - slang_type_specifier *); -static int -parse_type_array_size(slang_parse_ctx *C, - slang_output_ctx *O, - GLint *array_len); - -static GLboolean -parse_array_len(slang_parse_ctx * C, slang_output_ctx * O, GLuint * len) -{ - slang_operation array_size; - slang_name_space space; - GLboolean result; - - if (!slang_operation_construct(&array_size)) - return GL_FALSE; - if (!parse_expression(C, O, &array_size)) { - slang_operation_destruct(&array_size); - return GL_FALSE; - } - - space.funcs = O->funs; - space.structs = O->structs; - space.vars = O->vars; - - /* evaluate compile-time expression which is array size */ - _slang_simplify(&array_size, &space, C->atoms); - - if (array_size.type == SLANG_OPER_LITERAL_INT) { - result = GL_TRUE; - *len = (GLint) array_size.literal[0]; - } else if (array_size.type == SLANG_OPER_IDENTIFIER) { - slang_variable *var = _slang_variable_locate(array_size.locals, array_size.a_id, GL_TRUE); - if (!var) { - slang_info_log_error(C->L, "undefined variable '%s'", - (char *) array_size.a_id); - result = GL_FALSE; - } else if (var->type.qualifier == SLANG_QUAL_CONST && - var->type.specifier.type == SLANG_SPEC_INT) { - if (var->initializer && - var->initializer->type == SLANG_OPER_LITERAL_INT) { - *len = (GLint) var->initializer->literal[0]; - result = GL_TRUE; - } else { - slang_info_log_error(C->L, "unable to parse array size declaration"); - result = GL_FALSE; - } - } else { - slang_info_log_error(C->L, "unable to parse array size declaration"); - result = GL_FALSE; - } - } else { - result = GL_FALSE; - } - - slang_operation_destruct(&array_size); - return result; -} - -static GLboolean -calculate_var_size(slang_parse_ctx * C, slang_output_ctx * O, - slang_variable * var) -{ - slang_storage_aggregate agg; - - 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, C->atoms)) { - slang_storage_aggregate_destruct(&agg); - return GL_FALSE; - } - var->size = _slang_sizeof_aggregate(&agg); - slang_storage_aggregate_destruct(&agg); - return GL_TRUE; -} - -static void -promote_type_to_array(slang_parse_ctx *C, - slang_fully_specified_type *type, - GLint array_len) -{ - slang_type_specifier *baseType = - slang_type_specifier_new(type->specifier.type, NULL, NULL); - - type->specifier.type = SLANG_SPEC_ARRAY; - type->specifier._array = baseType; - type->array_len = array_len; -} - - -static GLboolean -convert_to_array(slang_parse_ctx * C, slang_variable * var, - const slang_type_specifier * sp) -{ - /* 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._array = (slang_type_specifier *) - _slang_alloc(sizeof(slang_type_specifier)); - if (var->type.specifier._array == NULL) { - slang_info_log_memory(C->L); - return GL_FALSE; - } - slang_type_specifier_ctr(var->type.specifier._array); - return slang_type_specifier_copy(var->type.specifier._array, sp); -} - -/* structure field */ -#define FIELD_NONE 0 -#define FIELD_NEXT 1 -#define FIELD_ARRAY 2 - -static GLboolean -parse_struct_field_var(slang_parse_ctx * C, slang_output_ctx * O, - slang_variable * var, slang_atom a_name, - const slang_type_specifier * sp, - GLuint array_len) -{ - var->a_name = a_name; - if (var->a_name == SLANG_ATOM_NULL) - return GL_FALSE; - - switch (*C->I++) { - case FIELD_NONE: - if (array_len != -1) { - if (!convert_to_array(C, var, sp)) - return GL_FALSE; - var->array_len = array_len; - } - else { - if (!slang_type_specifier_copy(&var->type.specifier, sp)) - return GL_FALSE; - } - break; - case FIELD_ARRAY: - if (array_len != -1) - return GL_FALSE; - if (!convert_to_array(C, var, sp)) - return GL_FALSE; - if (!parse_array_len(C, O, &var->array_len)) - return GL_FALSE; - break; - default: - return GL_FALSE; - } - - return calculate_var_size(C, O, var); -} - -static int -parse_struct_field(slang_parse_ctx * C, slang_output_ctx * O, - slang_struct * st, slang_type_specifier * sp) -{ - slang_output_ctx o = *O; - GLint array_len; - - o.structs = st->structs; - if (!parse_type_specifier(C, &o, sp)) - RETURN0; - if (!parse_type_array_size(C, &o, &array_len)) - RETURN0; - - do { - slang_atom a_name; - slang_variable *var = slang_variable_scope_grow(st->fields); - if (!var) { - slang_info_log_memory(C->L); - RETURN0; - } - a_name = parse_identifier(C); - if (_slang_variable_locate(st->fields, a_name, GL_FALSE)) { - slang_info_log_error(C->L, "duplicate field '%s'", (char *) a_name); - RETURN0; - } - - if (!parse_struct_field_var(C, &o, var, a_name, sp, array_len)) - RETURN0; - } - while (*C->I++ != FIELD_NONE); - - return 1; -} - -static int -parse_struct(slang_parse_ctx * C, slang_output_ctx * O, slang_struct ** st) -{ - slang_atom a_name; - const char *name; - - /* parse struct name (if any) and make sure it is unique in current scope */ - a_name = parse_identifier(C); - if (a_name == SLANG_ATOM_NULL) - RETURN0; - - name = slang_atom_pool_id(C->atoms, a_name); - if (name[0] != '\0' - && slang_struct_scope_find(O->structs, a_name, 0) != NULL) { - slang_info_log_error(C->L, "%s: duplicate type name.", name); - RETURN0; - } - - /* set-up a new struct */ - *st = (slang_struct *) _slang_alloc(sizeof(slang_struct)); - if (*st == NULL) { - slang_info_log_memory(C->L); - RETURN0; - } - if (!slang_struct_construct(*st)) { - _slang_free(*st); - *st = NULL; - slang_info_log_memory(C->L); - RETURN0; - } - (**st).a_name = a_name; - (**st).structs->outer_scope = O->structs; - - /* parse individual struct fields */ - do { - slang_type_specifier sp; - - slang_type_specifier_ctr(&sp); - if (!parse_struct_field(C, O, *st, &sp)) { - slang_type_specifier_dtr(&sp); - RETURN0; - } - slang_type_specifier_dtr(&sp); - } - while (*C->I++ != FIELD_NONE); - - /* if named struct, copy it to current scope */ - if (name[0] != '\0') { - slang_struct *s; - - O->structs->structs = - (slang_struct *) _slang_realloc(O->structs->structs, - O->structs->num_structs - * sizeof(slang_struct), - (O->structs->num_structs + 1) - * sizeof(slang_struct)); - if (O->structs->structs == NULL) { - slang_info_log_memory(C->L); - RETURN0; - } - s = &O->structs->structs[O->structs->num_structs]; - if (!slang_struct_construct(s)) - RETURN0; - O->structs->num_structs++; - if (!slang_struct_copy(s, *st)) - RETURN0; - } - - return 1; -} - - -/* invariant qualifer */ -#define TYPE_VARIANT 90 -#define TYPE_INVARIANT 91 - -static int -parse_type_variant(slang_parse_ctx * C, slang_type_variant *variant) -{ - GLuint invariant = *C->I++; - switch (invariant) { - case TYPE_VARIANT: - *variant = SLANG_VARIANT; - return 1; - case TYPE_INVARIANT: - *variant = SLANG_INVARIANT; - return 1; - default: - RETURN0; - } -} - - -/* centroid qualifer */ -#define TYPE_CENTER 95 -#define TYPE_CENTROID 96 - -static int -parse_type_centroid(slang_parse_ctx * C, slang_type_centroid *centroid) -{ - GLuint c = *C->I++; - switch (c) { - case TYPE_CENTER: - *centroid = SLANG_CENTER; - return 1; - case TYPE_CENTROID: - *centroid = SLANG_CENTROID; - return 1; - default: - RETURN0; - } -} - - -/* Layout qualifiers */ -#define LAYOUT_QUALIFIER_NONE 0 -#define LAYOUT_QUALIFIER_UPPER_LEFT 1 -#define LAYOUT_QUALIFIER_PIXEL_CENTER_INTEGER 2 - -static int -parse_layout_qualifiers(slang_parse_ctx * C, slang_layout_qualifier *layout) -{ - *layout = 0x0; - - /* the layout qualifiers come as a list of LAYOUT_QUALIFER_x tokens, - * terminated by LAYOUT_QUALIFIER_NONE. - */ - while (1) { - GLuint c = *C->I++; - switch (c) { - case LAYOUT_QUALIFIER_NONE: - /* end of list of qualifiers */ - return 1; - case LAYOUT_QUALIFIER_UPPER_LEFT: - *layout |= SLANG_LAYOUT_UPPER_LEFT_BIT; - break; - case LAYOUT_QUALIFIER_PIXEL_CENTER_INTEGER: - *layout |= SLANG_LAYOUT_PIXEL_CENTER_INTEGER_BIT; - break; - default: - assert(0 && "Bad layout qualifier"); - } - } -} - - -/* type qualifier */ -#define TYPE_QUALIFIER_NONE 0 -#define TYPE_QUALIFIER_CONST 1 -#define TYPE_QUALIFIER_ATTRIBUTE 2 -#define TYPE_QUALIFIER_VARYING 3 -#define TYPE_QUALIFIER_UNIFORM 4 -#define TYPE_QUALIFIER_FIXEDOUTPUT 5 -#define TYPE_QUALIFIER_FIXEDINPUT 6 - -static int -parse_type_qualifier(slang_parse_ctx * C, slang_type_qualifier * qual) -{ - GLuint qualifier = *C->I++; - switch (qualifier) { - case TYPE_QUALIFIER_NONE: - *qual = SLANG_QUAL_NONE; - break; - case TYPE_QUALIFIER_CONST: - *qual = SLANG_QUAL_CONST; - break; - case TYPE_QUALIFIER_ATTRIBUTE: - *qual = SLANG_QUAL_ATTRIBUTE; - break; - case TYPE_QUALIFIER_VARYING: - *qual = SLANG_QUAL_VARYING; - break; - case TYPE_QUALIFIER_UNIFORM: - *qual = SLANG_QUAL_UNIFORM; - break; - case TYPE_QUALIFIER_FIXEDOUTPUT: - *qual = SLANG_QUAL_FIXEDOUTPUT; - break; - case TYPE_QUALIFIER_FIXEDINPUT: - *qual = SLANG_QUAL_FIXEDINPUT; - break; - default: - RETURN0; - } - return 1; -} - -/* type specifier */ -#define TYPE_SPECIFIER_VOID 0 -#define TYPE_SPECIFIER_BOOL 1 -#define TYPE_SPECIFIER_BVEC2 2 -#define TYPE_SPECIFIER_BVEC3 3 -#define TYPE_SPECIFIER_BVEC4 4 -#define TYPE_SPECIFIER_INT 5 -#define TYPE_SPECIFIER_IVEC2 6 -#define TYPE_SPECIFIER_IVEC3 7 -#define TYPE_SPECIFIER_IVEC4 8 -#define TYPE_SPECIFIER_FLOAT 9 -#define TYPE_SPECIFIER_VEC2 10 -#define TYPE_SPECIFIER_VEC3 11 -#define TYPE_SPECIFIER_VEC4 12 -#define TYPE_SPECIFIER_MAT2 13 -#define TYPE_SPECIFIER_MAT3 14 -#define TYPE_SPECIFIER_MAT4 15 -#define TYPE_SPECIFIER_SAMPLER1D 16 -#define TYPE_SPECIFIER_SAMPLER2D 17 -#define TYPE_SPECIFIER_SAMPLER3D 18 -#define TYPE_SPECIFIER_SAMPLERCUBE 19 -#define TYPE_SPECIFIER_SAMPLER1DSHADOW 20 -#define TYPE_SPECIFIER_SAMPLER2DSHADOW 21 -#define TYPE_SPECIFIER_SAMPLER2DRECT 22 -#define TYPE_SPECIFIER_SAMPLER2DRECTSHADOW 23 -#define TYPE_SPECIFIER_STRUCT 24 -#define TYPE_SPECIFIER_TYPENAME 25 -#define TYPE_SPECIFIER_MAT23 26 -#define TYPE_SPECIFIER_MAT32 27 -#define TYPE_SPECIFIER_MAT24 28 -#define TYPE_SPECIFIER_MAT42 29 -#define TYPE_SPECIFIER_MAT34 30 -#define TYPE_SPECIFIER_MAT43 31 -#define TYPE_SPECIFIER_SAMPLER_1D_ARRAY 32 -#define TYPE_SPECIFIER_SAMPLER_2D_ARRAY 33 -#define TYPE_SPECIFIER_SAMPLER_1D_ARRAY_SHADOW 34 -#define TYPE_SPECIFIER_SAMPLER_2D_ARRAY_SHADOW 35 -#define TYPE_SPECIFIER_COUNT 36 - -static int -parse_type_specifier(slang_parse_ctx * C, slang_output_ctx * O, - slang_type_specifier * spec) -{ - int type = *C->I++; - switch (type) { - case TYPE_SPECIFIER_VOID: - spec->type = SLANG_SPEC_VOID; - break; - case TYPE_SPECIFIER_BOOL: - spec->type = SLANG_SPEC_BOOL; - break; - case TYPE_SPECIFIER_BVEC2: - spec->type = SLANG_SPEC_BVEC2; - break; - case TYPE_SPECIFIER_BVEC3: - spec->type = SLANG_SPEC_BVEC3; - break; - case TYPE_SPECIFIER_BVEC4: - spec->type = SLANG_SPEC_BVEC4; - break; - case TYPE_SPECIFIER_INT: - spec->type = SLANG_SPEC_INT; - break; - case TYPE_SPECIFIER_IVEC2: - spec->type = SLANG_SPEC_IVEC2; - break; - case TYPE_SPECIFIER_IVEC3: - spec->type = SLANG_SPEC_IVEC3; - break; - case TYPE_SPECIFIER_IVEC4: - spec->type = SLANG_SPEC_IVEC4; - break; - case TYPE_SPECIFIER_FLOAT: - spec->type = SLANG_SPEC_FLOAT; - break; - case TYPE_SPECIFIER_VEC2: - spec->type = SLANG_SPEC_VEC2; - break; - case TYPE_SPECIFIER_VEC3: - spec->type = SLANG_SPEC_VEC3; - break; - case TYPE_SPECIFIER_VEC4: - spec->type = SLANG_SPEC_VEC4; - break; - case TYPE_SPECIFIER_MAT2: - spec->type = SLANG_SPEC_MAT2; - break; - case TYPE_SPECIFIER_MAT3: - spec->type = SLANG_SPEC_MAT3; - break; - case TYPE_SPECIFIER_MAT4: - spec->type = SLANG_SPEC_MAT4; - break; - case TYPE_SPECIFIER_MAT23: - spec->type = SLANG_SPEC_MAT23; - break; - case TYPE_SPECIFIER_MAT32: - spec->type = SLANG_SPEC_MAT32; - break; - case TYPE_SPECIFIER_MAT24: - spec->type = SLANG_SPEC_MAT24; - break; - case TYPE_SPECIFIER_MAT42: - spec->type = SLANG_SPEC_MAT42; - break; - case TYPE_SPECIFIER_MAT34: - spec->type = SLANG_SPEC_MAT34; - break; - case TYPE_SPECIFIER_MAT43: - spec->type = SLANG_SPEC_MAT43; - break; - case TYPE_SPECIFIER_SAMPLER1D: - spec->type = SLANG_SPEC_SAMPLER_1D; - break; - case TYPE_SPECIFIER_SAMPLER2D: - spec->type = SLANG_SPEC_SAMPLER_2D; - break; - case TYPE_SPECIFIER_SAMPLER3D: - spec->type = SLANG_SPEC_SAMPLER_3D; - break; - case TYPE_SPECIFIER_SAMPLERCUBE: - spec->type = SLANG_SPEC_SAMPLER_CUBE; - break; - case TYPE_SPECIFIER_SAMPLER2DRECT: - spec->type = SLANG_SPEC_SAMPLER_RECT; - break; - case TYPE_SPECIFIER_SAMPLER1DSHADOW: - spec->type = SLANG_SPEC_SAMPLER_1D_SHADOW; - break; - case TYPE_SPECIFIER_SAMPLER2DSHADOW: - spec->type = SLANG_SPEC_SAMPLER_2D_SHADOW; - break; - case TYPE_SPECIFIER_SAMPLER2DRECTSHADOW: - spec->type = SLANG_SPEC_SAMPLER_RECT_SHADOW; - break; - case TYPE_SPECIFIER_SAMPLER_1D_ARRAY: - spec->type = SLANG_SPEC_SAMPLER_1D_ARRAY; - break; - case TYPE_SPECIFIER_SAMPLER_2D_ARRAY: - spec->type = SLANG_SPEC_SAMPLER_2D_ARRAY; - break; - case TYPE_SPECIFIER_SAMPLER_1D_ARRAY_SHADOW: - spec->type = SLANG_SPEC_SAMPLER_1D_ARRAY_SHADOW; - break; - case TYPE_SPECIFIER_SAMPLER_2D_ARRAY_SHADOW: - spec->type = SLANG_SPEC_SAMPLER_2D_ARRAY_SHADOW; - break; - case TYPE_SPECIFIER_STRUCT: - spec->type = SLANG_SPEC_STRUCT; - if (!parse_struct(C, O, &spec->_struct)) - RETURN0; - break; - case TYPE_SPECIFIER_TYPENAME: - spec->type = SLANG_SPEC_STRUCT; - { - slang_atom a_name; - slang_struct *stru; - - a_name = parse_identifier(C); - if (a_name == NULL) - RETURN0; - - stru = slang_struct_scope_find(O->structs, a_name, 1); - if (stru == NULL) { - slang_info_log_error(C->L, "undeclared type name '%s'", - slang_atom_pool_id(C->atoms, a_name)); - RETURN0; - } - - spec->_struct = (slang_struct *) _slang_alloc(sizeof(slang_struct)); - if (spec->_struct == NULL) { - slang_info_log_memory(C->L); - RETURN0; - } - if (!slang_struct_construct(spec->_struct)) { - _slang_free(spec->_struct); - spec->_struct = NULL; - RETURN0; - } - if (!slang_struct_copy(spec->_struct, stru)) - RETURN0; - } - break; - default: - RETURN0; - } - return 1; -} - -#define TYPE_SPECIFIER_NONARRAY 0 -#define TYPE_SPECIFIER_ARRAY 1 - -static int -parse_type_array_size(slang_parse_ctx *C, - slang_output_ctx *O, - GLint *array_len) -{ - GLuint size; - - switch (*C->I++) { - case TYPE_SPECIFIER_NONARRAY: - *array_len = -1; /* -1 = not an array */ - break; - case TYPE_SPECIFIER_ARRAY: - if (!parse_array_len(C, O, &size)) - RETURN0; - *array_len = (GLint) size; - break; - default: - assert(0); - RETURN0; - } - return 1; -} - -#define PRECISION_DEFAULT 0 -#define PRECISION_LOW 1 -#define PRECISION_MEDIUM 2 -#define PRECISION_HIGH 3 - -static int -parse_type_precision(slang_parse_ctx *C, - slang_type_precision *precision) -{ - GLint prec = *C->I++; - switch (prec) { - case PRECISION_DEFAULT: - *precision = SLANG_PREC_DEFAULT; - return 1; - case PRECISION_LOW: - *precision = SLANG_PREC_LOW; - return 1; - case PRECISION_MEDIUM: - *precision = SLANG_PREC_MEDIUM; - return 1; - case PRECISION_HIGH: - *precision = SLANG_PREC_HIGH; - return 1; - default: - RETURN0; - } -} - -static int -parse_fully_specified_type(slang_parse_ctx * C, slang_output_ctx * O, - slang_fully_specified_type * type) -{ - if (!parse_layout_qualifiers(C, &type->layout)) - RETURN0; - - if (!parse_type_variant(C, &type->variant)) - RETURN0; - - if (!parse_type_centroid(C, &type->centroid)) - RETURN0; - - if (!parse_type_qualifier(C, &type->qualifier)) - RETURN0; - - if (!parse_type_precision(C, &type->precision)) - RETURN0; - - if (!parse_type_specifier(C, O, &type->specifier)) - RETURN0; - - if (!parse_type_array_size(C, O, &type->array_len)) - RETURN0; - - if (!O->allow_invariant && type->variant == SLANG_INVARIANT) { - slang_info_log_error(C->L, - "'invariant' keyword not allowed (perhaps set #version 120)"); - RETURN0; - } - - if (!O->allow_centroid && type->centroid == SLANG_CENTROID) { - slang_info_log_error(C->L, - "'centroid' keyword not allowed (perhaps set #version 120)"); - RETURN0; - } - else if (type->centroid == SLANG_CENTROID && - type->qualifier != SLANG_QUAL_VARYING) { - slang_info_log_error(C->L, - "'centroid' keyword only allowed for varying vars"); - RETURN0; - } - - - /* need this? - if (type->qualifier != SLANG_QUAL_VARYING && - type->variant == SLANG_INVARIANT) { - slang_info_log_error(C->L, - "invariant qualifer only allowed for varying vars"); - RETURN0; - } - */ - - if (O->allow_precision) { - if (type->precision == SLANG_PREC_DEFAULT) { - assert(type->specifier.type < TYPE_SPECIFIER_COUNT); - /* use the default precision for this datatype */ - type->precision = O->default_precision[type->specifier.type]; - } - } - else { - /* only default is allowed */ - if (type->precision != SLANG_PREC_DEFAULT) { - slang_info_log_error(C->L, "precision qualifiers not allowed"); - RETURN0; - } - } - - if (!O->allow_array_types && type->array_len >= 0) { - slang_info_log_error(C->L, "first-class array types not allowed"); - RETURN0; - } - - if (type->array_len >= 0) { - /* convert type to array type (ex: convert "int" to "array of int" */ - promote_type_to_array(C, type, type->array_len); - } - - return 1; -} - -/* operation */ -#define OP_END 0 -#define OP_BLOCK_BEGIN_NO_NEW_SCOPE 1 -#define OP_BLOCK_BEGIN_NEW_SCOPE 2 -#define OP_DECLARE 3 -#define OP_ASM 4 -#define OP_BREAK 5 -#define OP_CONTINUE 6 -#define OP_DISCARD 7 -#define OP_RETURN 8 -#define OP_EXPRESSION 9 -#define OP_IF 10 -#define OP_WHILE 11 -#define OP_DO 12 -#define OP_FOR 13 -#define OP_PUSH_VOID 14 -#define OP_PUSH_BOOL 15 -#define OP_PUSH_INT 16 -#define OP_PUSH_FLOAT 17 -#define OP_PUSH_IDENTIFIER 18 -#define OP_SEQUENCE 19 -#define OP_ASSIGN 20 -#define OP_ADDASSIGN 21 -#define OP_SUBASSIGN 22 -#define OP_MULASSIGN 23 -#define OP_DIVASSIGN 24 -/*#define OP_MODASSIGN 25*/ -/*#define OP_LSHASSIGN 26*/ -/*#define OP_RSHASSIGN 27*/ -/*#define OP_ORASSIGN 28*/ -/*#define OP_XORASSIGN 29*/ -/*#define OP_ANDASSIGN 30*/ -#define OP_SELECT 31 -#define OP_LOGICALOR 32 -#define OP_LOGICALXOR 33 -#define OP_LOGICALAND 34 -/*#define OP_BITOR 35*/ -/*#define OP_BITXOR 36*/ -/*#define OP_BITAND 37*/ -#define OP_EQUAL 38 -#define OP_NOTEQUAL 39 -#define OP_LESS 40 -#define OP_GREATER 41 -#define OP_LESSEQUAL 42 -#define OP_GREATEREQUAL 43 -/*#define OP_LSHIFT 44*/ -/*#define OP_RSHIFT 45*/ -#define OP_ADD 46 -#define OP_SUBTRACT 47 -#define OP_MULTIPLY 48 -#define OP_DIVIDE 49 -/*#define OP_MODULUS 50*/ -#define OP_PREINCREMENT 51 -#define OP_PREDECREMENT 52 -#define OP_PLUS 53 -#define OP_MINUS 54 -/*#define OP_COMPLEMENT 55*/ -#define OP_NOT 56 -#define OP_SUBSCRIPT 57 -#define OP_CALL 58 -#define OP_FIELD 59 -#define OP_POSTINCREMENT 60 -#define OP_POSTDECREMENT 61 -#define OP_PRECISION 62 -#define OP_METHOD 63 - - -/** - * When parsing a compound production, this function is used to parse the - * children. - * 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 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, GLboolean statement) -{ - slang_operation *ch; - - /* grow child array */ - ch = slang_operation_grow(&oper->num_children, &oper->children); - if (statement) - return parse_statement(C, O, ch); - return parse_expression(C, O, ch); -} - -static int parse_declaration(slang_parse_ctx * C, slang_output_ctx * O); - -static int -parse_statement(slang_parse_ctx * C, slang_output_ctx * O, - slang_operation * oper) -{ - int op; - - oper->locals->outer_scope = O->vars; - - op = *C->I++; - switch (op) { - case OP_BLOCK_BEGIN_NO_NEW_SCOPE: - /* parse child statements, do not create new variable scope */ - oper->type = SLANG_OPER_BLOCK_NO_NEW_SCOPE; - while (*C->I != OP_END) - if (!parse_child_operation(C, O, oper, GL_TRUE)) - RETURN0; - C->I++; - break; - case OP_BLOCK_BEGIN_NEW_SCOPE: - /* parse child statements, create new variable scope */ - { - slang_output_ctx o = *O; - - oper->type = SLANG_OPER_BLOCK_NEW_SCOPE; - o.vars = oper->locals; - while (*C->I != OP_END) - if (!parse_child_operation(C, &o, oper, GL_TRUE)) - RETURN0; - C->I++; - } - break; - case OP_DECLARE: - /* local variable declaration, individual declarators are stored as - * children identifiers - */ - oper->type = SLANG_OPER_BLOCK_NO_NEW_SCOPE; - { - const unsigned int first_var = O->vars->num_variables; - - /* parse the declaration, note that there can be zero or more - * than one declarators - */ - if (!parse_declaration(C, O)) - RETURN0; - if (first_var < O->vars->num_variables) { - const unsigned int num_vars = O->vars->num_variables - first_var; - unsigned int i; - 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); - RETURN0; - } - for (i = first_var; i < O->vars->num_variables; i++) { - slang_operation *o = &oper->children[i - first_var]; - slang_variable *var = O->vars->variables[i]; - o->type = SLANG_OPER_VARIABLE_DECL; - o->locals->outer_scope = O->vars; - o->a_id = var->a_name; - - /* new/someday... - calculate_var_size(C, O, var); - */ - - if (!legal_identifier(o->a_id)) { - slang_info_log_error(C->L, "illegal variable name '%s'", - (char *) o->a_id); - RETURN0; - } - } - } - } - break; - case OP_ASM: - /* the __asm statement, parse the mnemonic and all its arguments - * as expressions - */ - oper->type = SLANG_OPER_ASM; - oper->a_id = parse_identifier(C); - if (oper->a_id == SLANG_ATOM_NULL) - RETURN0; - while (*C->I != OP_END) { - if (!parse_child_operation(C, O, oper, GL_FALSE)) - RETURN0; - } - C->I++; - break; - case OP_BREAK: - oper->type = SLANG_OPER_BREAK; - break; - case OP_CONTINUE: - oper->type = SLANG_OPER_CONTINUE; - break; - case OP_DISCARD: - oper->type = SLANG_OPER_DISCARD; - break; - case OP_RETURN: - oper->type = SLANG_OPER_RETURN; - if (!parse_child_operation(C, O, oper, GL_FALSE)) - RETURN0; - break; - case OP_EXPRESSION: - oper->type = SLANG_OPER_EXPRESSION; - if (!parse_child_operation(C, O, oper, GL_FALSE)) - RETURN0; - break; - case OP_IF: - oper->type = SLANG_OPER_IF; - if (!parse_child_operation(C, O, oper, GL_FALSE)) - RETURN0; - if (!parse_child_operation(C, O, oper, GL_TRUE)) - RETURN0; - if (!parse_child_operation(C, O, oper, GL_TRUE)) - RETURN0; - break; - case OP_WHILE: - { - slang_output_ctx o = *O; - - oper->type = SLANG_OPER_WHILE; - o.vars = oper->locals; - if (!parse_child_operation(C, &o, oper, GL_TRUE)) - RETURN0; - if (!parse_child_operation(C, &o, oper, GL_TRUE)) - RETURN0; - } - break; - case OP_DO: - oper->type = SLANG_OPER_DO; - if (!parse_child_operation(C, O, oper, GL_TRUE)) - RETURN0; - if (!parse_child_operation(C, O, oper, GL_FALSE)) - RETURN0; - break; - case OP_FOR: - { - slang_output_ctx o = *O; - - oper->type = SLANG_OPER_FOR; - o.vars = oper->locals; - if (!parse_child_operation(C, &o, oper, GL_TRUE)) - RETURN0; - if (!parse_child_operation(C, &o, oper, GL_TRUE)) - RETURN0; - if (!parse_child_operation(C, &o, oper, GL_FALSE)) - RETURN0; - if (!parse_child_operation(C, &o, oper, GL_TRUE)) - RETURN0; - } - break; - case OP_PRECISION: - { - /* set default precision for a type in this scope */ - /* ignored at this time */ - int prec_qual = *C->I++; - int datatype = *C->I++; - (void) prec_qual; - (void) datatype; - } - break; - default: - /*printf("Unexpected operation %d\n", op);*/ - RETURN0; - } - return 1; -} - -static int -handle_nary_expression(slang_parse_ctx * C, slang_operation * op, - slang_operation ** ops, unsigned int *total_ops, - unsigned int n) -{ - unsigned int i; - - op->children = slang_operation_new(n); - if (op->children == NULL) { - slang_info_log_memory(C->L); - RETURN0; - } - op->num_children = n; - - 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; - - *ops = (slang_operation *) - _slang_realloc(*ops, - (*total_ops + n) * sizeof(slang_operation), - *total_ops * sizeof(slang_operation)); - if (*ops == NULL) { - slang_info_log_memory(C->L); - RETURN0; - } - return 1; -} - -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) - return 1; - return slang_struct_scope_find(structs, a_name, 1) != NULL; -} - -#define FUNCTION_CALL_NONARRAY 0 -#define FUNCTION_CALL_ARRAY 1 - -static int -parse_expression(slang_parse_ctx * C, slang_output_ctx * O, - slang_operation * oper) -{ - slang_operation *ops = NULL; - unsigned int num_ops = 0; - int number; - - while (*C->I != OP_END) { - slang_operation *op; - const unsigned int op_code = *C->I++; - - /* allocate default operation, becomes a no-op if not used */ - ops = (slang_operation *) - _slang_realloc(ops, - num_ops * sizeof(slang_operation), - (num_ops + 1) * sizeof(slang_operation)); - if (ops == NULL) { - slang_info_log_memory(C->L); - RETURN0; - } - op = &ops[num_ops]; - if (!slang_operation_construct(op)) { - slang_info_log_memory(C->L); - RETURN0; - } - num_ops++; - op->locals->outer_scope = O->vars; - - switch (op_code) { - case OP_PUSH_VOID: - op->type = SLANG_OPER_VOID; - break; - case OP_PUSH_BOOL: - op->type = SLANG_OPER_LITERAL_BOOL; - if (!parse_number(C, &number)) - RETURN0; - 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; - if (!parse_number(C, &number)) - RETURN0; - 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[0])) - RETURN0; - 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->a_id = parse_identifier(C); - if (op->a_id == SLANG_ATOM_NULL) - RETURN0; - break; - case OP_SEQUENCE: - op->type = SLANG_OPER_SEQUENCE; - if (!handle_nary_expression(C, op, &ops, &num_ops, 2)) - RETURN0; - break; - case OP_ASSIGN: - op->type = SLANG_OPER_ASSIGN; - if (!handle_nary_expression(C, op, &ops, &num_ops, 2)) - RETURN0; - break; - case OP_ADDASSIGN: - op->type = SLANG_OPER_ADDASSIGN; - if (!handle_nary_expression(C, op, &ops, &num_ops, 2)) - RETURN0; - break; - case OP_SUBASSIGN: - op->type = SLANG_OPER_SUBASSIGN; - if (!handle_nary_expression(C, op, &ops, &num_ops, 2)) - RETURN0; - break; - case OP_MULASSIGN: - op->type = SLANG_OPER_MULASSIGN; - if (!handle_nary_expression(C, op, &ops, &num_ops, 2)) - RETURN0; - break; - case OP_DIVASSIGN: - op->type = SLANG_OPER_DIVASSIGN; - if (!handle_nary_expression(C, op, &ops, &num_ops, 2)) - RETURN0; - break; - /*case OP_MODASSIGN: */ - /*case OP_LSHASSIGN: */ - /*case OP_RSHASSIGN: */ - /*case OP_ORASSIGN: */ - /*case OP_XORASSIGN: */ - /*case OP_ANDASSIGN: */ - case OP_SELECT: - op->type = SLANG_OPER_SELECT; - if (!handle_nary_expression(C, op, &ops, &num_ops, 3)) - RETURN0; - break; - case OP_LOGICALOR: - op->type = SLANG_OPER_LOGICALOR; - if (!handle_nary_expression(C, op, &ops, &num_ops, 2)) - RETURN0; - break; - case OP_LOGICALXOR: - op->type = SLANG_OPER_LOGICALXOR; - if (!handle_nary_expression(C, op, &ops, &num_ops, 2)) - RETURN0; - break; - case OP_LOGICALAND: - op->type = SLANG_OPER_LOGICALAND; - if (!handle_nary_expression(C, op, &ops, &num_ops, 2)) - RETURN0; - break; - /*case OP_BITOR: */ - /*case OP_BITXOR: */ - /*case OP_BITAND: */ - case OP_EQUAL: - op->type = SLANG_OPER_EQUAL; - if (!handle_nary_expression(C, op, &ops, &num_ops, 2)) - RETURN0; - break; - case OP_NOTEQUAL: - op->type = SLANG_OPER_NOTEQUAL; - if (!handle_nary_expression(C, op, &ops, &num_ops, 2)) - RETURN0; - break; - case OP_LESS: - op->type = SLANG_OPER_LESS; - if (!handle_nary_expression(C, op, &ops, &num_ops, 2)) - RETURN0; - break; - case OP_GREATER: - op->type = SLANG_OPER_GREATER; - if (!handle_nary_expression(C, op, &ops, &num_ops, 2)) - RETURN0; - break; - case OP_LESSEQUAL: - op->type = SLANG_OPER_LESSEQUAL; - if (!handle_nary_expression(C, op, &ops, &num_ops, 2)) - RETURN0; - break; - case OP_GREATEREQUAL: - op->type = SLANG_OPER_GREATEREQUAL; - if (!handle_nary_expression(C, op, &ops, &num_ops, 2)) - RETURN0; - break; - /*case OP_LSHIFT: */ - /*case OP_RSHIFT: */ - case OP_ADD: - op->type = SLANG_OPER_ADD; - if (!handle_nary_expression(C, op, &ops, &num_ops, 2)) - RETURN0; - break; - case OP_SUBTRACT: - op->type = SLANG_OPER_SUBTRACT; - if (!handle_nary_expression(C, op, &ops, &num_ops, 2)) - RETURN0; - break; - case OP_MULTIPLY: - op->type = SLANG_OPER_MULTIPLY; - if (!handle_nary_expression(C, op, &ops, &num_ops, 2)) - RETURN0; - break; - case OP_DIVIDE: - op->type = SLANG_OPER_DIVIDE; - if (!handle_nary_expression(C, op, &ops, &num_ops, 2)) - RETURN0; - break; - /*case OP_MODULUS: */ - case OP_PREINCREMENT: - op->type = SLANG_OPER_PREINCREMENT; - if (!handle_nary_expression(C, op, &ops, &num_ops, 1)) - RETURN0; - break; - case OP_PREDECREMENT: - op->type = SLANG_OPER_PREDECREMENT; - if (!handle_nary_expression(C, op, &ops, &num_ops, 1)) - RETURN0; - break; - case OP_PLUS: - op->type = SLANG_OPER_PLUS; - if (!handle_nary_expression(C, op, &ops, &num_ops, 1)) - RETURN0; - break; - case OP_MINUS: - op->type = SLANG_OPER_MINUS; - if (!handle_nary_expression(C, op, &ops, &num_ops, 1)) - RETURN0; - break; - case OP_NOT: - op->type = SLANG_OPER_NOT; - if (!handle_nary_expression(C, op, &ops, &num_ops, 1)) - RETURN0; - break; - /*case OP_COMPLEMENT: */ - case OP_SUBSCRIPT: - op->type = SLANG_OPER_SUBSCRIPT; - if (!handle_nary_expression(C, op, &ops, &num_ops, 2)) - RETURN0; - break; - case OP_METHOD: - op->type = SLANG_OPER_METHOD; - op->a_obj = parse_identifier(C); - if (op->a_obj == SLANG_ATOM_NULL) - RETURN0; - - op->a_id = parse_identifier(C); - if (op->a_id == SLANG_ATOM_NULL) - RETURN0; - - assert(*C->I == OP_END); - C->I++; - - while (*C->I != OP_END) - if (!parse_child_operation(C, O, op, GL_FALSE)) - RETURN0; - C->I++; -#if 0 - /* don't lookup the method (not yet anyway) */ - if (!C->parsing_builtin - && !slang_function_scope_find_by_name(O->funs, op->a_id, 1)) { - const char *id; - - id = slang_atom_pool_id(C->atoms, op->a_id); - if (!is_constructor_name(id, op->a_id, O->structs)) { - slang_info_log_error(C->L, "%s: undeclared function name.", id); - RETURN0; - } - } -#endif - break; - case OP_CALL: - { - GLboolean array_constructor = GL_FALSE; - GLint array_constructor_size = 0; - - op->type = SLANG_OPER_CALL; - op->a_id = parse_identifier(C); - if (op->a_id == SLANG_ATOM_NULL) - RETURN0; - switch (*C->I++) { - case FUNCTION_CALL_NONARRAY: - /* Nothing to do. */ - break; - case FUNCTION_CALL_ARRAY: - /* Calling an array constructor. For example: - * float[3](1.1, 2.2, 3.3); - */ - if (!O->allow_array_types) { - slang_info_log_error(C->L, - "array constructors not allowed " - "in this GLSL version"); - RETURN0; - } - else { - /* parse the array constructor size */ - slang_operation array_size; - array_constructor = GL_TRUE; - slang_operation_construct(&array_size); - if (!parse_expression(C, O, &array_size)) { - slang_operation_destruct(&array_size); - return GL_FALSE; - } - if (array_size.type != SLANG_OPER_LITERAL_INT) { - slang_info_log_error(C->L, - "constructor array size is not an integer"); - slang_operation_destruct(&array_size); - RETURN0; - } - array_constructor_size = (int) array_size.literal[0]; - op->array_constructor = GL_TRUE; - slang_operation_destruct(&array_size); - } - break; - default: - assert(0); - RETURN0; - } - while (*C->I != OP_END) - if (!parse_child_operation(C, O, op, GL_FALSE)) - RETURN0; - C->I++; - - if (array_constructor && - array_constructor_size != op->num_children) { - slang_info_log_error(C->L, "number of parameters to array" - " constructor does not match array size"); - RETURN0; - } - - if (!C->parsing_builtin - && !slang_function_scope_find_by_name(O->funs, op->a_id, 1)) { - const char *id; - - id = slang_atom_pool_id(C->atoms, op->a_id); - if (!is_constructor_name(id, op->a_id, O->structs)) { - slang_info_log_error(C->L, "%s: undeclared function name.", id); - RETURN0; - } - } - } - break; - case OP_FIELD: - op->type = SLANG_OPER_FIELD; - op->a_id = parse_identifier(C); - if (op->a_id == SLANG_ATOM_NULL) - RETURN0; - if (!handle_nary_expression(C, op, &ops, &num_ops, 1)) - RETURN0; - break; - case OP_POSTINCREMENT: - op->type = SLANG_OPER_POSTINCREMENT; - if (!handle_nary_expression(C, op, &ops, &num_ops, 1)) - RETURN0; - break; - case OP_POSTDECREMENT: - op->type = SLANG_OPER_POSTDECREMENT; - if (!handle_nary_expression(C, op, &ops, &num_ops, 1)) - RETURN0; - break; - default: - RETURN0; - } - } - C->I++; - - slang_operation_destruct(oper); - *oper = *ops; /* struct copy */ - _slang_free(ops); - - return 1; -} - -/* parameter qualifier */ -#define PARAM_QUALIFIER_IN 0 -#define PARAM_QUALIFIER_OUT 1 -#define PARAM_QUALIFIER_INOUT 2 - -/* function parameter array presence */ -#define PARAMETER_ARRAY_NOT_PRESENT 0 -#define PARAMETER_ARRAY_PRESENT 1 - -static int -parse_parameter_declaration(slang_parse_ctx * C, slang_output_ctx * O, - slang_variable * param) -{ - int param_qual, precision_qual; - - /* parse and validate the parameter's type qualifiers (there can be - * two at most) because not all combinations are valid - */ - if (!parse_type_qualifier(C, ¶m->type.qualifier)) - RETURN0; - - param_qual = *C->I++; - switch (param_qual) { - case PARAM_QUALIFIER_IN: - if (param->type.qualifier != SLANG_QUAL_CONST - && param->type.qualifier != SLANG_QUAL_NONE) { - slang_info_log_error(C->L, "Invalid type qualifier."); - RETURN0; - } - break; - case PARAM_QUALIFIER_OUT: - if (param->type.qualifier == SLANG_QUAL_NONE) - param->type.qualifier = SLANG_QUAL_OUT; - else { - slang_info_log_error(C->L, "Invalid type qualifier."); - RETURN0; - } - break; - case PARAM_QUALIFIER_INOUT: - if (param->type.qualifier == SLANG_QUAL_NONE) - param->type.qualifier = SLANG_QUAL_INOUT; - else { - slang_info_log_error(C->L, "Invalid type qualifier."); - RETURN0; - } - break; - default: - RETURN0; - } - - /* parse precision qualifier (lowp, mediump, highp */ - precision_qual = *C->I++; - /* ignored at this time */ - (void) precision_qual; - - /* parse parameter's type specifier and name */ - if (!parse_type_specifier(C, O, ¶m->type.specifier)) - RETURN0; - if (!parse_type_array_size(C, O, ¶m->type.array_len)) - RETURN0; - param->a_name = parse_identifier(C); - if (param->a_name == SLANG_ATOM_NULL) - RETURN0; - - /* first-class array - */ - if (param->type.array_len >= 0) { - slang_type_specifier p; - - slang_type_specifier_ctr(&p); - if (!slang_type_specifier_copy(&p, ¶m->type.specifier)) { - slang_type_specifier_dtr(&p); - RETURN0; - } - if (!convert_to_array(C, param, &p)) { - slang_type_specifier_dtr(&p); - RETURN0; - } - slang_type_specifier_dtr(&p); - param->array_len = param->type.array_len; - } - - /* if the parameter is an array, parse its size (the size must be - * explicitly defined - */ - if (*C->I++ == PARAMETER_ARRAY_PRESENT) { - slang_type_specifier p; - - if (param->type.array_len >= 0) { - slang_info_log_error(C->L, "multi-dimensional arrays not allowed"); - RETURN0; - } - slang_type_specifier_ctr(&p); - if (!slang_type_specifier_copy(&p, ¶m->type.specifier)) { - slang_type_specifier_dtr(&p); - RETURN0; - } - if (!convert_to_array(C, param, &p)) { - slang_type_specifier_dtr(&p); - RETURN0; - } - slang_type_specifier_dtr(&p); - if (!parse_array_len(C, O, ¶m->array_len)) - RETURN0; - } - -#if 0 - /* calculate the parameter size */ - if (!calculate_var_size(C, O, param)) - RETURN0; -#endif - /* TODO: allocate the local address here? */ - return 1; -} - -/* function type */ -#define FUNCTION_ORDINARY 0 -#define FUNCTION_CONSTRUCTOR 1 -#define FUNCTION_OPERATOR 2 - -/* function parameter */ -#define PARAMETER_NONE 0 -#define PARAMETER_NEXT 1 - -/* operator type */ -#define OPERATOR_ADDASSIGN 1 -#define OPERATOR_SUBASSIGN 2 -#define OPERATOR_MULASSIGN 3 -#define OPERATOR_DIVASSIGN 4 -/*#define OPERATOR_MODASSIGN 5*/ -/*#define OPERATOR_LSHASSIGN 6*/ -/*#define OPERATOR_RSHASSIGN 7*/ -/*#define OPERATOR_ANDASSIGN 8*/ -/*#define OPERATOR_XORASSIGN 9*/ -/*#define OPERATOR_ORASSIGN 10*/ -#define OPERATOR_LOGICALXOR 11 -/*#define OPERATOR_BITOR 12*/ -/*#define OPERATOR_BITXOR 13*/ -/*#define OPERATOR_BITAND 14*/ -#define OPERATOR_LESS 15 -#define OPERATOR_GREATER 16 -#define OPERATOR_LESSEQUAL 17 -#define OPERATOR_GREATEREQUAL 18 -/*#define OPERATOR_LSHIFT 19*/ -/*#define OPERATOR_RSHIFT 20*/ -#define OPERATOR_MULTIPLY 21 -#define OPERATOR_DIVIDE 22 -/*#define OPERATOR_MODULUS 23*/ -#define OPERATOR_INCREMENT 24 -#define OPERATOR_DECREMENT 25 -#define OPERATOR_PLUS 26 -#define OPERATOR_MINUS 27 -/*#define OPERATOR_COMPLEMENT 28*/ -#define OPERATOR_NOT 29 - -static const struct -{ - unsigned int o_code; - const char *o_name; -} operator_names[] = { - {OPERATOR_INCREMENT, "++"}, - {OPERATOR_ADDASSIGN, "+="}, - {OPERATOR_PLUS, "+"}, - {OPERATOR_DECREMENT, "--"}, - {OPERATOR_SUBASSIGN, "-="}, - {OPERATOR_MINUS, "-"}, - {OPERATOR_NOT, "!"}, - {OPERATOR_MULASSIGN, "*="}, - {OPERATOR_MULTIPLY, "*"}, - {OPERATOR_DIVASSIGN, "/="}, - {OPERATOR_DIVIDE, "/"}, - {OPERATOR_LESSEQUAL, "<="}, - /*{ OPERATOR_LSHASSIGN, "<<=" }, */ - /*{ OPERATOR_LSHIFT, "<<" }, */ - {OPERATOR_LESS, "<"}, - {OPERATOR_GREATEREQUAL, ">="}, - /*{ OPERATOR_RSHASSIGN, ">>=" }, */ - /*{ OPERATOR_RSHIFT, ">>" }, */ - {OPERATOR_GREATER, ">"}, - /*{ OPERATOR_MODASSIGN, "%=" }, */ - /*{ OPERATOR_MODULUS, "%" }, */ - /*{ OPERATOR_ANDASSIGN, "&=" }, */ - /*{ OPERATOR_BITAND, "&" }, */ - /*{ OPERATOR_ORASSIGN, "|=" }, */ - /*{ OPERATOR_BITOR, "|" }, */ - /*{ OPERATOR_COMPLEMENT, "~" }, */ - /*{ OPERATOR_XORASSIGN, "^=" }, */ - {OPERATOR_LOGICALXOR, "^^"}, - /*{ OPERATOR_BITXOR, "^" } */ -}; - -static slang_atom -parse_operator_name(slang_parse_ctx * C) -{ - unsigned int i; - - for (i = 0; i < sizeof(operator_names) / sizeof(*operator_names); i++) { - if (operator_names[i].o_code == (unsigned int) (*C->I)) { - slang_atom atom = - slang_atom_pool_atom(C->atoms, operator_names[i].o_name); - if (atom == SLANG_ATOM_NULL) { - slang_info_log_memory(C->L); - RETURN0; - } - C->I++; - return atom; - } - } - RETURN0; -} - - -static int -parse_function_prototype(slang_parse_ctx * C, slang_output_ctx * O, - slang_function * func) -{ - GLuint functype; - /* parse function type and name */ - if (!parse_fully_specified_type(C, O, &func->header.type)) - RETURN0; - - functype = *C->I++; - switch (functype) { - case FUNCTION_ORDINARY: - func->kind = SLANG_FUNC_ORDINARY; - func->header.a_name = parse_identifier(C); - if (func->header.a_name == SLANG_ATOM_NULL) - RETURN0; - break; - case FUNCTION_CONSTRUCTOR: - func->kind = SLANG_FUNC_CONSTRUCTOR; - if (func->header.type.specifier.type == SLANG_SPEC_STRUCT) - RETURN0; - func->header.a_name = - slang_atom_pool_atom(C->atoms, - slang_type_specifier_type_to_string - (func->header.type.specifier.type)); - if (func->header.a_name == SLANG_ATOM_NULL) { - slang_info_log_memory(C->L); - RETURN0; - } - break; - case FUNCTION_OPERATOR: - func->kind = SLANG_FUNC_OPERATOR; - func->header.a_name = parse_operator_name(C); - if (func->header.a_name == SLANG_ATOM_NULL) - RETURN0; - break; - default: - RETURN0; - } - - if (!legal_identifier(func->header.a_name)) { - slang_info_log_error(C->L, "illegal function name '%s'", - (char *) func->header.a_name); - RETURN0; - } - - /* parse function parameters */ - while (*C->I++ == PARAMETER_NEXT) { - slang_variable *p = slang_variable_scope_grow(func->parameters); - if (!p) { - slang_info_log_memory(C->L); - RETURN0; - } - if (!parse_parameter_declaration(C, O, p)) - RETURN0; - } - - /* 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 - * given identifier is not found here, the search process continues - * in the global space - */ - func->param_count = func->parameters->num_variables; - func->parameters->outer_scope = O->vars; - - return 1; -} - -static int -parse_function_definition(slang_parse_ctx * C, slang_output_ctx * O, - slang_function * func) -{ - slang_output_ctx o = *O; - - if (!parse_function_prototype(C, O, func)) - RETURN0; - - /* create function's body operation */ - func->body = (slang_operation *) _slang_alloc(sizeof(slang_operation)); - if (func->body == NULL) { - slang_info_log_memory(C->L); - RETURN0; - } - if (!slang_operation_construct(func->body)) { - _slang_free(func->body); - func->body = NULL; - slang_info_log_memory(C->L); - RETURN0; - } - - /* to parse the body the parse context is modified in order to - * capture parsed variables into function's local variable scope - */ - C->global_scope = GL_FALSE; - o.vars = func->parameters; - if (!parse_statement(C, &o, func->body)) - RETURN0; - - C->global_scope = GL_TRUE; - return 1; -} - -static GLboolean -initialize_global(slang_assemble_ctx * A, slang_variable * var) -{ - slang_operation op_id, op_assign; - GLboolean result; - - /* construct the left side of assignment */ - if (!slang_operation_construct(&op_id)) - return GL_FALSE; - 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(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; - - /* construct the assignment expression */ - if (!slang_operation_construct(&op_assign)) { - op_id.locals->num_variables = 0; - slang_operation_destruct(&op_id); - return GL_FALSE; - } - op_assign.type = SLANG_OPER_ASSIGN; - op_assign.children = - (slang_operation *) _slang_alloc(2 * sizeof(slang_operation)); - if (op_assign.children == NULL) { - slang_operation_destruct(&op_assign); - op_id.locals->num_variables = 0; - slang_operation_destruct(&op_id); - return GL_FALSE; - } - op_assign.num_children = 2; - op_assign.children[0] = op_id; - op_assign.children[1] = *var->initializer; - - result = 1; - - /* carefully destroy the operations */ - op_assign.num_children = 0; - _slang_free(op_assign.children); - op_assign.children = NULL; - slang_operation_destruct(&op_assign); - op_id.locals->num_variables = 0; - slang_operation_destruct(&op_id); - - if (!result) - return GL_FALSE; - - return GL_TRUE; -} - -/* init declarator list */ -#define DECLARATOR_NONE 0 -#define DECLARATOR_NEXT 1 - -/* variable declaration */ -#define VARIABLE_NONE 0 -#define VARIABLE_IDENTIFIER 1 -#define VARIABLE_INITIALIZER 2 -#define VARIABLE_ARRAY_EXPLICIT 3 -#define VARIABLE_ARRAY_UNKNOWN 4 - - -/** - * Check if it's OK to re-declare a variable with the given new type. - * This happens when applying layout qualifiers to gl_FragCoord or - * (re)setting an array size. - * If redeclaration is OK, return a pointer to the incoming variable - * updated with new type info. Else return NULL; - */ -static slang_variable * -redeclare_variable(slang_variable *var, - const slang_fully_specified_type *type) -{ - if (slang_fully_specified_types_compatible(&var->type, type)) { - /* replace orig var layout with new layout */ - var->type.layout = type->layout; - - /* XXX there may be other type updates in the future here */ - - return var; - } - else - return NULL; -} - - -/** - * Parse the initializer for a variable declaration. - */ -static int -parse_init_declarator(slang_parse_ctx * C, slang_output_ctx * O, - const slang_fully_specified_type * type) -{ - GET_CURRENT_CONTEXT(ctx); /* a hack */ - slang_variable *var = NULL, *prevDecl; - slang_atom a_name; - - /* empty init declatator (without name, e.g. "float ;") */ - if (*C->I++ == VARIABLE_NONE) - return 1; - - a_name = parse_identifier(C); - - /* check if name is already in this scope */ - prevDecl = _slang_variable_locate(O->vars, a_name, C->global_scope); - if (prevDecl) { - /* A var with this name has already been declared. - * Check if redeclaring the var with a different type/layout is legal. - */ - if (C->global_scope) { - var = redeclare_variable(prevDecl, type); - } - if (!var) { - slang_info_log_error(C->L, - "declaration of '%s' conflicts with previous declaration", - (char *) a_name); - RETURN0; - } - } - - if (!var) { - /* make room for a new variable and initialize it */ - var = slang_variable_scope_grow(O->vars); - if (!var) { - slang_info_log_memory(C->L); - RETURN0; - } - - /* copy the declarator type qualifier/etc info, parse the identifier */ - var->type.qualifier = type->qualifier; - var->type.centroid = type->centroid; - var->type.precision = type->precision; - var->type.specifier = type->specifier;/*new*/ - var->type.variant = type->variant; - var->type.layout = type->layout; - var->type.array_len = type->array_len; - var->a_name = a_name; - if (var->a_name == SLANG_ATOM_NULL) - RETURN0; - } - - switch (*C->I++) { - case VARIABLE_NONE: - /* simple variable declarator - just copy the specifier */ - if (!slang_type_specifier_copy(&var->type.specifier, &type->specifier)) - RETURN0; - break; - case VARIABLE_INITIALIZER: - /* initialized variable - copy the specifier and parse the expression */ - if (0 && type->array_len >= 0) { - /* The type was something like "float[4]" */ - convert_to_array(C, var, &type->specifier); - var->array_len = type->array_len; - } - else { - if (!slang_type_specifier_copy(&var->type.specifier, &type->specifier)) - RETURN0; - } - var->initializer = - (slang_operation *) _slang_alloc(sizeof(slang_operation)); - if (var->initializer == NULL) { - slang_info_log_memory(C->L); - RETURN0; - } - if (!slang_operation_construct(var->initializer)) { - _slang_free(var->initializer); - var->initializer = NULL; - slang_info_log_memory(C->L); - RETURN0; - } - if (!parse_expression(C, O, var->initializer)) - RETURN0; - break; - case VARIABLE_ARRAY_UNKNOWN: - /* unsized array - mark it as array and copy the specifier to - * the array element - */ - if (type->array_len >= 0) { - slang_info_log_error(C->L, "multi-dimensional arrays not allowed"); - RETURN0; - } - if (!convert_to_array(C, var, &type->specifier)) - return GL_FALSE; - break; - case VARIABLE_ARRAY_EXPLICIT: - if (type->array_len >= 0) { - /* the user is trying to do something like: float[2] x[3]; */ - slang_info_log_error(C->L, "multi-dimensional arrays not allowed"); - RETURN0; - } - if (!convert_to_array(C, var, &type->specifier)) - return GL_FALSE; - if (!parse_array_len(C, O, &var->array_len)) - return GL_FALSE; - break; - default: - RETURN0; - } - - /* allocate global address space for a variable with a known size */ - if (C->global_scope - && !(var->type.specifier.type == SLANG_SPEC_ARRAY - && var->array_len == 0)) { - if (!calculate_var_size(C, O, var)) - return GL_FALSE; - } - - /* emit code for global var decl */ - if (C->global_scope) { - slang_assemble_ctx A; - memset(&A, 0, sizeof(slang_assemble_ctx)); - A.allow_uniform_initializers = C->version > 110; - A.atoms = C->atoms; - A.space.funcs = O->funs; - A.space.structs = O->structs; - A.space.vars = O->vars; - A.program = O->program; - A.pragmas = O->pragmas; - A.vartable = O->vartable; - A.log = C->L; - A.curFuncEndLabel = NULL; - A.EmitContReturn = ctx->Shader.EmitContReturn; - if (!_slang_codegen_global_variable(&A, var, C->type)) - RETURN0; - } - - /* initialize global variable */ - if (C->global_scope) { - if (var->initializer != NULL) { - slang_assemble_ctx A; - memset(&A, 0, sizeof(slang_assemble_ctx)); - A.allow_uniform_initializers = C->version > 110; - A.atoms = C->atoms; - A.space.funcs = O->funs; - A.space.structs = O->structs; - A.space.vars = O->vars; - if (!initialize_global(&A, var)) - RETURN0; - } - } - - if (var->type.qualifier == SLANG_QUAL_FIXEDINPUT && - var->a_name == slang_atom_pool_atom(C->atoms, "gl_FragCoord")) { - /* set the program's PixelCenterInteger, OriginUpperLeft fields */ - struct gl_fragment_program *fragProg = - (struct gl_fragment_program *) O->program; - - if (var->type.layout & SLANG_LAYOUT_UPPER_LEFT_BIT) { - fragProg->OriginUpperLeft = GL_TRUE; - } - if (var->type.layout & SLANG_LAYOUT_PIXEL_CENTER_INTEGER_BIT) { - fragProg->PixelCenterInteger = GL_TRUE; - } - } - - return 1; -} - -/** - * Parse a list of variable declarations. Each variable may have an - * initializer. - */ -static int -parse_init_declarator_list(slang_parse_ctx * C, slang_output_ctx * O) -{ - slang_fully_specified_type type; - - /* parse the fully specified type, common to all declarators */ - if (!slang_fully_specified_type_construct(&type)) - RETURN0; - if (!parse_fully_specified_type(C, O, &type)) { - slang_fully_specified_type_destruct(&type); - RETURN0; - } - - /* parse declarators, pass-in the parsed type */ - do { - if (!parse_init_declarator(C, O, &type)) { - slang_fully_specified_type_destruct(&type); - RETURN0; - } - } - while (*C->I++ == DECLARATOR_NEXT); - - slang_fully_specified_type_destruct(&type); - return 1; -} - - -/** - * Parse a function definition or declaration. - * \param C parsing context - * \param O output context - * \param definition if non-zero expect a definition, else a declaration - * \param parsed_func_ret returns the parsed function - * \return GL_TRUE if success, GL_FALSE if failure - */ -static GLboolean -parse_function(slang_parse_ctx * C, slang_output_ctx * O, int definition, - slang_function ** parsed_func_ret) -{ - slang_function parsed_func, *found_func; - - /* parse function definition/declaration */ - if (!slang_function_construct(&parsed_func)) - return GL_FALSE; - if (definition) { - if (!parse_function_definition(C, O, &parsed_func)) { - slang_function_destruct(&parsed_func); - return GL_FALSE; - } - } - else { - if (!parse_function_prototype(C, O, &parsed_func)) { - slang_function_destruct(&parsed_func); - return GL_FALSE; - } - } - - /* find a function with a prototype matching the parsed one - only - * the current scope is being searched to allow built-in function - * overriding - */ - found_func = slang_function_scope_find(O->funs, &parsed_func, 0); - if (found_func == NULL) { - /* New function, add it to the function list */ - O->funs->functions = - (slang_function *) _slang_realloc(O->funs->functions, - O->funs->num_functions - * sizeof(slang_function), - (O->funs->num_functions + 1) - * sizeof(slang_function)); - if (O->funs->functions == NULL) { - /* Make sure that there are no functions marked, as the - * allocation is currently NULL, in order to avoid - * a potental segfault as we clean up later. - */ - O->funs->num_functions = 0; - - slang_info_log_memory(C->L); - slang_function_destruct(&parsed_func); - return GL_FALSE; - } - O->funs->functions[O->funs->num_functions] = parsed_func; - O->funs->num_functions++; - - /* return the newly parsed function */ - *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) { - slang_info_log_error(C->L, "%s: function already has a body.", - slang_atom_pool_id(C->atoms, - parsed_func.header. - a_name)); - slang_function_destruct(&parsed_func); - return GL_FALSE; - } - - /* destroy the existing function declaration and replace it - * with the new one - */ - slang_function_destruct(found_func); - *found_func = parsed_func; - } - else { - /* another declaration of the same function prototype - ignore it */ - slang_function_destruct(&parsed_func); - } - - /* return the found function */ - *parsed_func_ret = found_func; - } - - return GL_TRUE; -} - -/* declaration */ -#define DECLARATION_FUNCTION_PROTOTYPE 1 -#define DECLARATION_INIT_DECLARATOR_LIST 2 - -static int -parse_declaration(slang_parse_ctx * C, slang_output_ctx * O) -{ - switch (*C->I++) { - case DECLARATION_INIT_DECLARATOR_LIST: - if (!parse_init_declarator_list(C, O)) - RETURN0; - break; - case DECLARATION_FUNCTION_PROTOTYPE: - { - slang_function *dummy_func; - - if (!parse_function(C, O, 0, &dummy_func)) - RETURN0; - } - break; - default: - RETURN0; - } - return 1; -} - -static int -parse_default_precision(slang_parse_ctx * C, slang_output_ctx * O) -{ - int precision, type; - - if (!O->allow_precision) { - slang_info_log_error(C->L, "syntax error at \"precision\""); - RETURN0; - } - - precision = *C->I++; - switch (precision) { - case PRECISION_LOW: - case PRECISION_MEDIUM: - case PRECISION_HIGH: - /* OK */ - break; - default: - _mesa_problem(NULL, "unexpected precision %d at %s:%d\n", - precision, __FILE__, __LINE__); - RETURN0; - } - - type = *C->I++; - switch (type) { - case TYPE_SPECIFIER_FLOAT: - case TYPE_SPECIFIER_INT: - case TYPE_SPECIFIER_SAMPLER1D: - case TYPE_SPECIFIER_SAMPLER2D: - case TYPE_SPECIFIER_SAMPLER3D: - case TYPE_SPECIFIER_SAMPLERCUBE: - case TYPE_SPECIFIER_SAMPLER1DSHADOW: - case TYPE_SPECIFIER_SAMPLER2DSHADOW: - case TYPE_SPECIFIER_SAMPLER2DRECT: - case TYPE_SPECIFIER_SAMPLER2DRECTSHADOW: - case TYPE_SPECIFIER_SAMPLER_1D_ARRAY: - case TYPE_SPECIFIER_SAMPLER_2D_ARRAY: - case TYPE_SPECIFIER_SAMPLER_1D_ARRAY_SHADOW: - case TYPE_SPECIFIER_SAMPLER_2D_ARRAY_SHADOW: - /* OK */ - break; - default: - _mesa_problem(NULL, "unexpected type %d at %s:%d\n", - type, __FILE__, __LINE__); - RETURN0; - } - - assert(type < TYPE_SPECIFIER_COUNT); - O->default_precision[type] = precision; - - return 1; -} - - -/** - * Initialize the default precision for all types. - * XXX this info isn't used yet. - */ -static void -init_default_precision(slang_output_ctx *O, slang_unit_type type) -{ - GLuint i; - for (i = 0; i < TYPE_SPECIFIER_COUNT; i++) { -#if FEATURE_es2_glsl - O->default_precision[i] = PRECISION_LOW; -#else - O->default_precision[i] = PRECISION_HIGH; -#endif - } - - if (type == SLANG_UNIT_VERTEX_SHADER) { - O->default_precision[TYPE_SPECIFIER_FLOAT] = PRECISION_HIGH; - O->default_precision[TYPE_SPECIFIER_INT] = PRECISION_HIGH; - } - else { - O->default_precision[TYPE_SPECIFIER_INT] = PRECISION_MEDIUM; - } -} - - -static int -parse_invariant(slang_parse_ctx * C, slang_output_ctx * O) -{ - if (O->allow_invariant) { - slang_atom *a = parse_identifier(C); - /* XXX not doing anything with this var yet */ - /*printf("ID: %s\n", (char*) a);*/ - return a ? 1 : 0; - } - else { - slang_info_log_error(C->L, "syntax error at \"invariant\""); - RETURN0; - } -} - - -/* external declaration or default precision specifier */ -#define EXTERNAL_NULL 0 -#define EXTERNAL_FUNCTION_DEFINITION 1 -#define EXTERNAL_DECLARATION 2 -#define DEFAULT_PRECISION 3 -#define INVARIANT_STMT 4 - - -static GLboolean -parse_code_unit(slang_parse_ctx * C, slang_code_unit * unit, - struct gl_shader *shader) -{ - GET_CURRENT_CONTEXT(ctx); - slang_output_ctx o; - GLboolean success; - GLuint maxRegs; - slang_function *mainFunc = NULL; - - 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.program = shader ? shader->Program : NULL; - o.pragmas = shader ? &shader->Pragmas : NULL; - o.vartable = _slang_new_var_table(maxRegs); - _slang_push_var_table(o.vartable); - - /* allow 'invariant' keyword? */ -#if FEATURE_es2_glsl - o.allow_invariant = GL_TRUE; -#else - o.allow_invariant = (C->version >= 120) ? GL_TRUE : GL_FALSE; -#endif - - /* allow 'centroid' keyword? */ - o.allow_centroid = (C->version >= 120) ? GL_TRUE : GL_FALSE; - - /* allow 'lowp/mediump/highp' keywords? */ -#if FEATURE_es2_glsl - o.allow_precision = GL_TRUE; -#else - o.allow_precision = (C->version >= 120) ? GL_TRUE : GL_FALSE; -#endif - init_default_precision(&o, unit->type); - - /* allow 'float[]' keyword? */ - o.allow_array_types = (C->version >= 120) ? GL_TRUE : GL_FALSE; - - /* parse individual functions and declarations */ - while (*C->I != EXTERNAL_NULL) { - switch (*C->I++) { - case EXTERNAL_FUNCTION_DEFINITION: - { - slang_function *func; - success = parse_function(C, &o, 1, &func); - if (success && strcmp((char *) func->header.a_name, "main") == 0) { - /* found main() */ - mainFunc = func; - } - } - break; - case EXTERNAL_DECLARATION: - success = parse_declaration(C, &o); - break; - case DEFAULT_PRECISION: - success = parse_default_precision(C, &o); - break; - case INVARIANT_STMT: - success = parse_invariant(C, &o); - break; - default: - success = GL_FALSE; - } - - if (!success) { - /* xxx free codegen */ - _slang_pop_var_table(o.vartable); - return GL_FALSE; - } - } - C->I++; - - if (mainFunc) { - /* assemble (generate code) for main() */ - slang_assemble_ctx A; - memset(&A, 0, sizeof(slang_assemble_ctx)); - A.atoms = C->atoms; - A.space.funcs = o.funs; - A.space.structs = o.structs; - A.space.vars = o.vars; - A.program = o.program; - A.pragmas = &shader->Pragmas; - A.vartable = o.vartable; - A.EmitContReturn = ctx->Shader.EmitContReturn; - A.log = C->L; - A.allow_uniform_initializers = C->version > 110; - - /* main() takes no parameters */ - if (mainFunc->param_count > 0) { - slang_info_log_error(A.log, "main() takes no arguments"); - return GL_FALSE; - } - - _slang_codegen_function(&A, mainFunc); - - shader->Main = GL_TRUE; /* this shader defines main() */ - - shader->UnresolvedRefs = A.UnresolvedRefs; - } - - _slang_pop_var_table(o.vartable); - _slang_delete_var_table(o.vartable); - - return GL_TRUE; -} - -static GLboolean -compile_binary(const unsigned char * prod, slang_code_unit * unit, - GLuint version, - slang_unit_type type, slang_info_log * infolog, - slang_code_unit * builtin, slang_code_unit * downlink, - struct gl_shader *shader) -{ - slang_parse_ctx C; - - unit->type = type; - - /* setup parse context */ - C.I = prod; - C.L = infolog; - C.parsing_builtin = (builtin == NULL); - C.global_scope = GL_TRUE; - C.atoms = &unit->object->atompool; - C.type = type; - C.version = version; - - if (!check_revision(&C)) - return GL_FALSE; - - if (downlink != NULL) { - unit->vars.outer_scope = &downlink->vars; - unit->funs.outer_scope = &downlink->funs; - unit->structs.outer_scope = &downlink->structs; - } - - /* parse translation unit */ - return parse_code_unit(&C, unit, shader); -} - -static GLboolean -compile_with_grammar(const char *source, - slang_code_unit *unit, - slang_unit_type type, - slang_info_log *infolog, - slang_code_unit *builtin, - struct gl_shader *shader, - struct gl_sl_pragmas *pragmas, - unsigned int shader_type, - unsigned int parsing_builtin) -{ - struct sl_pp_purify_options options; - struct sl_pp_context *context; - unsigned char *prod; - GLuint size; - unsigned int version; - unsigned int maxVersion; - int result; - char errmsg[200] = ""; - - assert(shader_type == 1 || shader_type == 2); - - memset(&options, 0, sizeof(options)); - - context = sl_pp_context_create(source, &options); - if (!context) { - slang_info_log_error(infolog, "out of memory"); - return GL_FALSE; - } - - if (sl_pp_version(context, &version)) { - slang_info_log_error(infolog, "%s", sl_pp_context_error_message(context)); - sl_pp_context_destroy(context); - return GL_FALSE; - } - - if (sl_pp_context_add_extension(context, "GL_ARB_draw_buffers") || - sl_pp_context_add_extension(context, "GL_ARB_texture_rectangle")) { - slang_info_log_error(infolog, "%s", sl_pp_context_error_message(context)); - sl_pp_context_destroy(context); - return GL_FALSE; - } - - if (type == SLANG_UNIT_FRAGMENT_SHADER) { - sl_pp_context_add_extension(context, "GL_ARB_fragment_coord_conventions"); - } - - -#if FEATURE_es2_glsl - if (sl_pp_context_add_predefined(context, "GL_ES", "1") || - sl_pp_context_add_predefined(context, "GL_FRAGMENT_PRECISION_HIGH", "1")) { - slang_info_log_error(infolog, "%s", sl_pp_context_error_message(context)); - sl_pp_context_destroy(context); - return GL_FALSE; - } -#endif - -#if FEATURE_ARB_shading_language_120 - maxVersion = 120; -#elif FEATURE_es2_glsl - maxVersion = 100; -#else - maxVersion = 110; -#endif - - if (version > maxVersion || - (version != 100 && version != 110 && version != 120)) { - slang_info_log_error(infolog, - "language version %.2f is not supported.", - version * 0.01); - sl_pp_context_destroy(context); - return GL_FALSE; - } - - /* Finally check the syntax and generate its binary representation. */ - result = sl_cl_compile(context, - shader_type, - parsing_builtin, - &prod, - &size, - errmsg, - sizeof(errmsg)); - - sl_pp_context_destroy(context); - - if (result) { - /*GLint pos;*/ - - slang_info_log_error(infolog, errmsg); - /* 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; - } - - /* Syntax is okay - translate it to internal representation. */ - if (!compile_binary(prod, unit, version, type, infolog, builtin, - &builtin[SLANG_BUILTIN_TOTAL - 1], - shader)) { - free(prod); - return GL_FALSE; - } - free(prod); - return GL_TRUE; -} - -static const unsigned char slang_core_gc[] = { -#include "library/slang_core_gc.h" -}; - -static const unsigned char slang_120_core_gc[] = { -#include "library/slang_120_core_gc.h" -}; - -static const unsigned char slang_120_fragment_gc[] = { -#include "library/slang_builtin_120_fragment_gc.h" -}; - -static const unsigned char slang_common_builtin_gc[] = { -#include "library/slang_common_builtin_gc.h" -}; - -static const unsigned char slang_fragment_builtin_gc[] = { -#include "library/slang_fragment_builtin_gc.h" -}; - -static const unsigned char slang_vertex_builtin_gc[] = { -#include "library/slang_vertex_builtin_gc.h" -}; - -static GLboolean -compile_object(const char *source, - slang_code_object *object, - slang_unit_type type, - slang_info_log *infolog, - struct gl_shader *shader, - struct gl_sl_pragmas *pragmas) -{ - slang_code_unit *builtins = NULL; - GLuint base_version = 110; - unsigned int shader_type; - unsigned int parsing_builtin; - - /* set shader type - the syntax is slightly different for different shaders */ - if (type == SLANG_UNIT_FRAGMENT_SHADER || type == SLANG_UNIT_FRAGMENT_BUILTIN) { - shader_type = 1; - } else { - shader_type = 2; - } - - /* enable language extensions */ - parsing_builtin = 1; - - /* if parsing user-specified shader, load built-in library */ - 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], - base_version, - SLANG_UNIT_FRAGMENT_BUILTIN, infolog, - NULL, NULL, NULL)) - return GL_FALSE; - -#if FEATURE_ARB_shading_language_120 - if (!compile_binary(slang_120_core_gc, - &object->builtin[SLANG_BUILTIN_120_CORE], - 120, - SLANG_UNIT_FRAGMENT_BUILTIN, infolog, - NULL, &object->builtin[SLANG_BUILTIN_CORE], NULL)) - return GL_FALSE; -#endif - - /* compile common functions and variables, link to core */ - if (!compile_binary(slang_common_builtin_gc, - &object->builtin[SLANG_BUILTIN_COMMON], -#if FEATURE_ARB_shading_language_120 - 120, -#else - base_version, -#endif - SLANG_UNIT_FRAGMENT_BUILTIN, infolog, NULL, -#if FEATURE_ARB_shading_language_120 - &object->builtin[SLANG_BUILTIN_120_CORE], -#else - &object->builtin[SLANG_BUILTIN_CORE], -#endif - 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], - base_version, - SLANG_UNIT_FRAGMENT_BUILTIN, infolog, NULL, - &object->builtin[SLANG_BUILTIN_COMMON], NULL)) - return GL_FALSE; -#if FEATURE_ARB_shading_language_120 - if (!compile_binary(slang_120_fragment_gc, - &object->builtin[SLANG_BUILTIN_TARGET], - 120, - SLANG_UNIT_FRAGMENT_BUILTIN, infolog, NULL, - &object->builtin[SLANG_BUILTIN_COMMON], NULL)) - return GL_FALSE; -#endif - } - else if (type == SLANG_UNIT_VERTEX_SHADER) { - if (!compile_binary(slang_vertex_builtin_gc, - &object->builtin[SLANG_BUILTIN_TARGET], - base_version, - SLANG_UNIT_VERTEX_BUILTIN, infolog, NULL, - &object->builtin[SLANG_BUILTIN_COMMON], NULL)) - return GL_FALSE; - } - - /* disable language extensions */ - parsing_builtin = 0; - - builtins = object->builtin; - } - - /* compile the actual shader - pass-in built-in library for external shader */ - return compile_with_grammar(source, - &object->unit, - type, - infolog, - builtins, - shader, - pragmas, - shader_type, - parsing_builtin); -} - - -GLboolean -_slang_compile(GLcontext *ctx, struct gl_shader *shader) -{ - GLboolean success; - slang_info_log info_log; - slang_code_object obj; - slang_unit_type type; - GLenum progTarget; - - if (shader->Type == GL_VERTEX_SHADER) { - type = SLANG_UNIT_VERTEX_SHADER; - } - else { - assert(shader->Type == GL_FRAGMENT_SHADER); - type = SLANG_UNIT_FRAGMENT_SHADER; - } - - if (!shader->Source) - return GL_FALSE; - - ctx->Shader.MemPool = _slang_new_mempool(1024*1024); - - shader->Main = GL_FALSE; - - /* free the shader's old instructions, etc */ - _mesa_reference_program(ctx, &shader->Program, NULL); - - /* allocate new GPU program, parameter lists, etc. */ - if (shader->Type == GL_VERTEX_SHADER) - progTarget = GL_VERTEX_PROGRAM_ARB; - else - progTarget = GL_FRAGMENT_PROGRAM_ARB; - shader->Program = ctx->Driver.NewProgram(ctx, progTarget, 1); - shader->Program->Parameters = _mesa_new_parameter_list(); - shader->Program->Varying = _mesa_new_parameter_list(); - shader->Program->Attributes = _mesa_new_parameter_list(); - - slang_info_log_construct(&info_log); - _slang_code_object_ctr(&obj); - - success = compile_object(shader->Source, - &obj, - type, - &info_log, - shader, - &shader->Pragmas); - - /* free shader's prev info log */ - if (shader->InfoLog) { - 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); - - _slang_delete_mempool((slang_mempool *) ctx->Shader.MemPool); - ctx->Shader.MemPool = NULL; - - /* remove any reads of output registers */ -#if 0 - printf("Pre-remove output reads:\n"); - _mesa_print_program(shader->Program); -#endif - _mesa_remove_output_reads(shader->Program, PROGRAM_OUTPUT); - if (shader->Type == GL_VERTEX_SHADER) { - /* and remove writes to varying vars in vertex programs */ - _mesa_remove_output_reads(shader->Program, PROGRAM_VARYING); - } -#if 0 - printf("Post-remove output reads:\n"); - _mesa_print_program(shader->Program); -#endif - - shader->CompileStatus = success; - - if (success) { - if (shader->Pragmas.Optimize && - (ctx->Shader.Flags & GLSL_NO_OPT) == 0) { - _mesa_optimize_program(ctx, shader->Program); - } - if ((ctx->Shader.Flags & GLSL_NOP_VERT) && - shader->Program->Target == GL_VERTEX_PROGRAM_ARB) { - _mesa_nop_vertex_program(ctx, - (struct gl_vertex_program *) shader->Program); - } - if ((ctx->Shader.Flags & GLSL_NOP_FRAG) && - shader->Program->Target == GL_FRAGMENT_PROGRAM_ARB) { - _mesa_nop_fragment_program(ctx, - (struct gl_fragment_program *) shader->Program); - } - } - - if (ctx->Shader.Flags & GLSL_LOG) { - _mesa_write_shader_to_file(shader); - } - - return success; -} - diff --git a/mesalib/src/mesa/shader/slang/slang_compile.h b/mesalib/src/mesa/shader/slang/slang_compile.h deleted file mode 100644 index 7fb549d33..000000000 --- a/mesalib/src/mesa/shader/slang/slang_compile.h +++ /dev/null @@ -1,100 +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_COMPILE_H -#define SLANG_COMPILE_H - -#include "main/imports.h" -#include "main/mtypes.h" -#include "slang_typeinfo.h" -#include "slang_compile_variable.h" -#include "slang_compile_struct.h" -#include "slang_compile_operation.h" -#include "slang_compile_function.h" - -#if defined __cplusplus -extern "C" { -#endif - -typedef struct slang_name_space_ -{ - struct slang_function_scope_ *funcs; - struct slang_struct_scope_ *structs; - struct slang_variable_scope_ *vars; -} slang_name_space; - -typedef enum slang_unit_type_ -{ - SLANG_UNIT_FRAGMENT_SHADER, - SLANG_UNIT_VERTEX_SHADER, - SLANG_UNIT_FRAGMENT_BUILTIN, - SLANG_UNIT_VERTEX_BUILTIN -} slang_unit_type; - - -typedef struct slang_code_unit_ -{ - slang_variable_scope vars; - slang_function_scope funs; - slang_struct_scope structs; - slang_unit_type type; - struct slang_code_object_ *object; -} slang_code_unit; - - -extern GLvoid -_slang_code_unit_ctr (slang_code_unit *, struct slang_code_object_ *); - -extern GLvoid -_slang_code_unit_dtr (slang_code_unit *); - -#define SLANG_BUILTIN_CORE 0 -#define SLANG_BUILTIN_120_CORE 1 -#define SLANG_BUILTIN_COMMON 2 -#define SLANG_BUILTIN_TARGET 3 - -#define SLANG_BUILTIN_TOTAL 4 - -typedef struct slang_code_object_ -{ - slang_code_unit builtin[SLANG_BUILTIN_TOTAL]; - slang_code_unit unit; - slang_atom_pool atompool; -} slang_code_object; - -extern GLvoid -_slang_code_object_ctr (slang_code_object *); - -extern GLvoid -_slang_code_object_dtr (slang_code_object *); - -extern GLboolean -_slang_compile (GLcontext *ctx, struct gl_shader *shader); - -#ifdef __cplusplus -} -#endif - -#endif - diff --git a/mesalib/src/mesa/shader/slang/slang_compile_function.c b/mesalib/src/mesa/shader/slang/slang_compile_function.c deleted file mode 100644 index 4dd885176..000000000 --- a/mesalib/src/mesa/shader/slang/slang_compile_function.c +++ /dev/null @@ -1,262 +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_compile_function.c - * slang front-end compiler - * \author Michal Krol - */ - -#include "main/imports.h" -#include "slang_compile.h" -#include "slang_mem.h" - - -int -slang_function_construct(slang_function * func) -{ - func->kind = SLANG_FUNC_ORDINARY; - if (!slang_variable_construct(&func->header)) - return 0; - - func->parameters = (slang_variable_scope *) - _slang_alloc(sizeof(slang_variable_scope)); - if (func->parameters == NULL) { - slang_variable_destruct(&func->header); - return 0; - } - - _slang_variable_scope_ctr(func->parameters); - func->param_count = 0; - func->body = NULL; - return 1; -} - -void -slang_function_destruct(slang_function * func) -{ - slang_variable_destruct(&func->header); - slang_variable_scope_destruct(func->parameters); - _slang_free(func->parameters); - if (func->body != NULL) { - slang_operation_destruct(func->body); - _slang_free(func->body); - } -} - - -slang_function * -slang_function_new(slang_function_kind kind) -{ - slang_function *fun = (slang_function *) - _slang_alloc(sizeof(slang_function)); - if (fun) { - slang_function_construct(fun); - fun->kind = kind; - } - return fun; -} - - -/* - * slang_function_scope - */ - -GLvoid -_slang_function_scope_ctr(slang_function_scope * self) -{ - self->functions = NULL; - self->num_functions = 0; - self->outer_scope = NULL; -} - -void -slang_function_scope_destruct(slang_function_scope * scope) -{ - unsigned int i; - - for (i = 0; i < scope->num_functions; i++) - slang_function_destruct(scope->functions + i); - _slang_free(scope->functions); -} - - -/** - * 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 - * \param all_scopes if non-zero, search containing scopes too. - * \return pointer to found function, or NULL. - */ -int -slang_function_scope_find_by_name(slang_function_scope * funcs, - slang_atom a_name, int all_scopes) -{ - unsigned int i; - - for (i = 0; i < funcs->num_functions; i++) - if (a_name == funcs->functions[i].header.a_name) - return 1; - if (all_scopes && funcs->outer_scope != NULL) - return slang_function_scope_find_by_name(funcs->outer_scope, a_name, 1); - return 0; -} - - -/** - * Search a list of functions for a particular function (for implementing - * function calls. Matching is done by first comparing the function's name, - * then the function's parameter list. - * - * \param funcs the list of functions to search - * \param fun the function to search for - * \param all_scopes if non-zero, search containing scopes too. - * \return pointer to found function, or NULL. - */ -slang_function * -slang_function_scope_find(slang_function_scope * funcs, slang_function * fun, - int all_scopes) -{ - unsigned int i; - - 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 = haveRetValue; j < fun->param_count; j++) { - if (!slang_type_specifier_equal - (&fun->parameters->variables[j]->type.specifier, - &f->parameters->variables[j]->type.specifier)) - break; - } - 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; -} - - -/** - * Lookup a function according to name and parameter count/types. - */ -slang_function * -_slang_function_locate(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, GLboolean *error) -{ - slang_typeinfo arg_ti[100]; - GLuint i; - - *error = GL_FALSE; - - /* determine type of each argument */ - assert(num_args < 100); - for (i = 0; i < num_args; i++) { - if (!slang_typeinfo_construct(&arg_ti[i])) - return NULL; - if (!_slang_typeof_operation(&args[i], space, &arg_ti[i], atoms, log)) { - return NULL; - } - } - - /* loop over function scopes */ - while (funcs) { - - /* look for function with matching name and argument/param types */ - 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++) { - if (!slang_type_specifier_compatible(&arg_ti[j].spec, - &f->parameters->variables[j]->type.specifier)) { - /* param/arg types don't match */ - break; - } - - /* "out" and "inout" formal parameter requires the actual - * argument to be an l-value. - */ - if (!arg_ti[j].can_be_referenced && - (f->parameters->variables[j]->type.qualifier == SLANG_QUAL_OUT || - f->parameters->variables[j]->type.qualifier == SLANG_QUAL_INOUT)) { - /* param is not an lvalue! */ - *error = GL_TRUE; - return NULL; - } - } - - if (j == num_args) { - /* name and args match! */ - return f; - } - } - - funcs = funcs->outer_scope; - } - - return NULL; -} diff --git a/mesalib/src/mesa/shader/slang/slang_compile_function.h b/mesalib/src/mesa/shader/slang/slang_compile_function.h deleted file mode 100644 index a5445ec25..000000000 --- a/mesalib/src/mesa/shader/slang/slang_compile_function.h +++ /dev/null @@ -1,92 +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_COMPILE_FUNCTION_H -#define SLANG_COMPILE_FUNCTION_H - - -/** - * Types of functions. - */ -typedef enum slang_function_kind_ -{ - SLANG_FUNC_ORDINARY, - SLANG_FUNC_CONSTRUCTOR, - SLANG_FUNC_OPERATOR -} slang_function_kind; - - -/** - * Description of a compiled shader function. - */ -typedef struct slang_function_ -{ - slang_function_kind kind; - slang_variable header; /**< The function's name and return type */ - slang_variable_scope *parameters; /**< formal parameters AND local vars */ - unsigned int param_count; /**< number of formal params (no locals) */ - slang_operation *body; /**< The instruction tree */ -} slang_function; - -extern int slang_function_construct(slang_function *); -extern void slang_function_destruct(slang_function *); -extern slang_function *slang_function_new(slang_function_kind kind); - -extern GLboolean -_slang_function_has_return_value(const slang_function *fun); - - -/** - * Basically, a list of compiled functions. - */ -typedef struct slang_function_scope_ -{ - slang_function *functions; - GLuint num_functions; - struct slang_function_scope_ *outer_scope; -} slang_function_scope; - - -extern GLvoid -_slang_function_scope_ctr(slang_function_scope *); - -extern void -slang_function_scope_destruct(slang_function_scope *); - -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 struct slang_function_ * -_slang_function_locate(const struct slang_function_scope_ *funcs, - slang_atom name, struct slang_operation_ *params, - GLuint num_params, - const struct slang_name_space_ *space, - slang_atom_pool *atoms, slang_info_log *log, - GLboolean *error); - - -#endif /* SLANG_COMPILE_FUNCTION_H */ diff --git a/mesalib/src/mesa/shader/slang/slang_compile_operation.c b/mesalib/src/mesa/shader/slang/slang_compile_operation.c deleted file mode 100644 index 5441d60df..000000000 --- a/mesalib/src/mesa/shader/slang/slang_compile_operation.c +++ /dev/null @@ -1,334 +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_compile_operation.c - * slang front-end compiler - * \author Michal Krol - */ - -#include "main/imports.h" -#include "slang_compile.h" -#include "slang_mem.h" - - -/** - * Init a slang_operation object - */ -GLboolean -slang_operation_construct(slang_operation * oper) -{ - oper->type = SLANG_OPER_NONE; - oper->children = NULL; - oper->num_children = 0; - oper->literal[0] = 0.0; - oper->literal_size = 1; - oper->array_constructor = GL_FALSE; - oper->a_id = SLANG_ATOM_NULL; - oper->a_obj = SLANG_ATOM_NULL; - 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; - oper->label = NULL; - return GL_TRUE; -} - -void -slang_operation_destruct(slang_operation * oper) -{ - GLuint i; - - for (i = 0; i < oper->num_children; i++) - slang_operation_destruct(oper->children + i); - _slang_free(oper->children); - slang_variable_scope_destruct(oper->locals); - _slang_free(oper->locals); - oper->children = NULL; - oper->num_children = 0; - oper->locals = NULL; -} - - -/** - * Recursively traverse 'oper', replacing occurances of 'oldScope' with - * 'newScope' in the oper->locals->outer_scope field. - */ -void -slang_replace_scope(slang_operation *oper, - slang_variable_scope *oldScope, - slang_variable_scope *newScope) -{ - GLuint i; - - if (oper->locals != newScope && - oper->locals->outer_scope == oldScope) { - /* found. replace old w/ new */ - oper->locals->outer_scope = newScope; - } - - if (oper->type == SLANG_OPER_VARIABLE_DECL) { - /* search/replace in the initializer */ - slang_variable *var; - var = _slang_variable_locate(oper->locals, oper->a_id, GL_TRUE); - if (var && var->initializer) { - slang_replace_scope(var->initializer, oldScope, newScope); - } - } - - /* search/replace in children */ - for (i = 0; i < oper->num_children; i++) { - slang_replace_scope(&oper->children[i], oldScope, newScope); - } -} - - -/** - * Recursively copy a slang_operation node. - * \param x copy target - * \param y copy source - * \return GL_TRUE for success, GL_FALSE if failure - */ -GLboolean -slang_operation_copy(slang_operation * x, const slang_operation * y) -{ - slang_operation z; - GLuint i; - - if (!slang_operation_construct(&z)) - return GL_FALSE; - z.type = y->type; - if (y->num_children > 0) { - z.children = (slang_operation *) - _slang_alloc(y->num_children * sizeof(slang_operation)); - if (z.children == NULL) { - slang_operation_destruct(&z); - return GL_FALSE; - } - } - for (z.num_children = 0; z.num_children < y->num_children; - z.num_children++) { - if (!slang_operation_construct(&z.children[z.num_children])) { - slang_operation_destruct(&z); - return GL_FALSE; - } - } - for (i = 0; i < z.num_children; i++) { - if (!slang_operation_copy(&z.children[i], &y->children[i])) { - slang_operation_destruct(&z); - return GL_FALSE; - } - } - 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 (y->locals) { - if (!slang_variable_scope_copy(z.locals, y->locals)) { - slang_operation_destruct(&z); - return GL_FALSE; - } - } - - /* update scoping for children */ - for (i = 0; i < y->num_children; i++) { - if (y->children[i].locals && - y->children[i].locals->outer_scope == y->locals) { - z.children[i].locals->outer_scope = z.locals; - } - } - -#if 0 - z.var = y->var; - z.fun = y->fun; -#endif - slang_operation_destruct(x); - *x = z; - - /* If this operation declares a new scope, we need to make sure - * all children point to it, not the original operation's scope! - */ - if (x->type == SLANG_OPER_BLOCK_NEW_SCOPE || - x->type == SLANG_OPER_WHILE || - x->type == SLANG_OPER_FOR) { - slang_replace_scope(x, y->locals, x->locals); - } - - return GL_TRUE; -} - - -slang_operation * -slang_operation_new(GLuint count) -{ - slang_operation *ops - = (slang_operation *) _slang_alloc(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); - _slang_free(oper); -} - - -void -slang_operation_free_children(slang_operation *oper) -{ - GLuint i; - for (i = 0; i < slang_oper_num_children(oper); i++) { - slang_operation *child = slang_oper_child(oper, i); - slang_operation_destruct(child); - } - _slang_free(oper->children); - oper->children = NULL; - oper->num_children = 0; -} - - -slang_operation * -slang_operation_grow(GLuint *numChildren, slang_operation **children) -{ - slang_operation *ops; - - ops = (slang_operation *) - _slang_realloc(*children, - *numChildren * sizeof(slang_operation), - (*numChildren + 1) * sizeof(slang_operation)); - if (ops) { - slang_operation *newOp = ops + *numChildren; - if (!slang_operation_construct(newOp)) { - _slang_free(ops); - *children = NULL; - return NULL; - } - *children = ops; - (*numChildren)++; - return newOp; - } - return NULL; -} - -/** - * Insert a new slang_operation into an array. - * \param numElements pointer to current array size (in/out) - * \param array address of the array (in/out) - * \param pos position to insert new element - * \return pointer to the new operation/element - */ -slang_operation * -slang_operation_insert(GLuint *numElements, slang_operation **array, - GLuint pos) -{ - slang_operation *ops; - - assert(pos <= *numElements); - - ops = (slang_operation *) - _slang_alloc((*numElements + 1) * sizeof(slang_operation)); - if (ops) { - slang_operation *newOp; - newOp = ops + pos; - if (pos > 0) - memcpy(ops, *array, pos * sizeof(slang_operation)); - if (pos < *numElements) - memcpy(newOp + 1, (*array) + pos, - (*numElements - pos) * sizeof(slang_operation)); - - if (!slang_operation_construct(newOp)) { - _slang_free(ops); - *numElements = 0; - *array = NULL; - return NULL; - } - if (*array) - _slang_free(*array); - *array = ops; - (*numElements)++; - return newOp; - } - return NULL; -} - - -/** - * Add/insert new child into given node at given position. - * \return pointer to the new child node - */ -slang_operation * -slang_operation_insert_child(slang_operation *oper, GLuint pos) -{ - slang_operation *newOp; - - newOp = slang_operation_insert(&oper->num_children, - &oper->children, - pos); - if (newOp) { - newOp->locals->outer_scope = oper->locals; - } - - return newOp; -} - - -void -_slang_operation_swap(slang_operation *oper0, slang_operation *oper1) -{ - slang_operation tmp = *oper0; - *oper0 = *oper1; - *oper1 = tmp; -} - - -void -slang_operation_add_children(slang_operation *oper, GLuint num_children) -{ - GLuint i; - assert(oper->num_children == 0); - assert(oper->children == NULL); - oper->num_children = num_children; - oper->children = slang_operation_new(num_children); - for (i = 0; i < num_children; i++) { - oper->children[i].locals = _slang_variable_scope_new(oper->locals); - } -} - diff --git a/mesalib/src/mesa/shader/slang/slang_compile_operation.h b/mesalib/src/mesa/shader/slang/slang_compile_operation.h deleted file mode 100644 index 1f15c1989..000000000 --- a/mesalib/src/mesa/shader/slang/slang_compile_operation.h +++ /dev/null @@ -1,225 +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_COMPILE_OPERATION_H -#define SLANG_COMPILE_OPERATION_H - - -/** - * Types of slang operations. - * These are the types of the AST (abstract syntax tree) nodes. - * [foo] indicates a sub-tree or reference to another type of node - */ -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_RETURN_INLINED, /* "return" [expr] from inlined function */ - 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_NON_INLINED_CALL, /* a real function call */ - SLANG_OPER_METHOD, /* method call, such as v.length() */ - SLANG_OPER_FIELD, /* i.e.: ".next" or ".xzy" or ".xxx" etc */ - SLANG_OPER_POSTINCREMENT, /* [var] "++" */ - SLANG_OPER_POSTDECREMENT /* [var] "--" */ -} slang_operation_type; - - -/** - * A slang_operation is basically a compiled instruction (such as assignment, - * a while-loop, a conditional, a multiply, a function call, etc). - * The AST (abstract syntax tree) is built from these nodes. - * NOTE: This structure could have been implemented as a union of simpler - * structs which would correspond to the operation types above. - */ -typedef struct slang_operation_ -{ - slang_operation_type type; - struct slang_operation_ *children; - GLuint num_children; - 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_atom a_obj; /**< object in a method call */ - 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 */ - /** If type==SLANG_OPER_CALL and we're calling an array constructor, - * for which there's no real function, we need to have a flag to - * indicate such. num_children indicates number of elements. - */ - GLboolean array_constructor; -} slang_operation; - - -extern GLboolean -slang_operation_construct(slang_operation *); - -extern void -slang_operation_destruct(slang_operation *); - -extern void -slang_replace_scope(slang_operation *oper, - slang_variable_scope *oldScope, - slang_variable_scope *newScope); - -extern GLboolean -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 void -slang_operation_free_children(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 slang_operation * -slang_operation_insert_child(slang_operation *oper, GLuint pos); - -extern void -_slang_operation_swap(slang_operation *oper0, slang_operation *oper1); - - -extern void -slang_operation_add_children(slang_operation *oper, GLuint num_children); - - -/** Return number of children of given node */ -static INLINE GLuint -slang_oper_num_children(const slang_operation *oper) -{ - return oper->num_children; -} - -/** Return child of given operation node */ -static INLINE slang_operation * -slang_oper_child(slang_operation *oper, GLuint child) -{ - assert(child < oper->num_children); - return &oper->children[child]; -} - - -/** Return child of given operation node, const version */ -static INLINE const slang_operation * -slang_oper_child_const(const slang_operation *oper, GLuint child) -{ - assert(child < oper->num_children); - return &oper->children[child]; -} - - -/** Init oper to a boolean literal. */ -static INLINE void -slang_operation_literal_bool(slang_operation *oper, GLboolean value) -{ - oper->type = SLANG_OPER_LITERAL_BOOL; - oper->literal[0] = - oper->literal[1] = - oper->literal[2] = - oper->literal[3] = (float) value; - oper->literal_size = 1; -} - - -/** Init oper to an int literal. */ -static INLINE void -slang_operation_literal_int(slang_operation *oper, GLint value) -{ - oper->type = SLANG_OPER_LITERAL_INT; - oper->literal[0] = - oper->literal[1] = - oper->literal[2] = - oper->literal[3] = (float) value; - oper->literal_size = 1; -} - - -#endif /* SLANG_COMPILE_OPERATION_H */ diff --git a/mesalib/src/mesa/shader/slang/slang_compile_struct.c b/mesalib/src/mesa/shader/slang/slang_compile_struct.c deleted file mode 100644 index e6c38730d..000000000 --- a/mesalib/src/mesa/shader/slang/slang_compile_struct.c +++ /dev/null @@ -1,174 +0,0 @@ -/* - * 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_compile_struct.c - * slang front-end compiler - * \author Michal Krol - */ - -#include "main/imports.h" -#include "slang_mem.h" -#include "slang_compile.h" - - -GLvoid -_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) -{ - GLuint i; - - for (i = 0; i < scope->num_structs; i++) - slang_struct_destruct(scope->structs + i); - _slang_free(scope->structs); - /* do not free scope->outer_scope */ -} - -int -slang_struct_scope_copy(slang_struct_scope * x, const slang_struct_scope * y) -{ - slang_struct_scope z; - GLuint i; - - _slang_struct_scope_ctr(&z); - z.structs = (slang_struct *) - _slang_alloc(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) -{ - 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) -{ - stru->a_name = SLANG_ATOM_NULL; - stru->fields = (slang_variable_scope *) - _slang_alloc(sizeof(slang_variable_scope)); - if (stru->fields == NULL) - return 0; - _slang_variable_scope_ctr(stru->fields); - - stru->structs = - (slang_struct_scope *) _slang_alloc(sizeof(slang_struct_scope)); - if (stru->structs == NULL) { - slang_variable_scope_destruct(stru->fields); - _slang_free(stru->fields); - return 0; - } - _slang_struct_scope_ctr(stru->structs); - stru->constructor = NULL; - return 1; -} - -void -slang_struct_destruct(slang_struct * stru) -{ - slang_variable_scope_destruct(stru->fields); - _slang_free(stru->fields); - slang_struct_scope_destruct(stru->structs); - _slang_free(stru->structs); -} - -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; -} - -int -slang_struct_equal(const slang_struct * x, const slang_struct * y) -{ - 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/mesalib/src/mesa/shader/slang/slang_compile_struct.h b/mesalib/src/mesa/shader/slang/slang_compile_struct.h deleted file mode 100644 index 90c5512f4..000000000 --- a/mesalib/src/mesa/shader/slang/slang_compile_struct.h +++ /dev/null @@ -1,66 +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_COMPILE_STRUCT_H -#define SLANG_COMPILE_STRUCT_H - -#if defined __cplusplus -extern "C" { -#endif - -struct slang_function_; - -typedef struct slang_struct_scope_ -{ - struct slang_struct_ *structs; - GLuint num_structs; - struct slang_struct_scope_ *outer_scope; -} slang_struct_scope; - -extern GLvoid -_slang_struct_scope_ctr (slang_struct_scope *); - -void slang_struct_scope_destruct (slang_struct_scope *); -int slang_struct_scope_copy (slang_struct_scope *, const slang_struct_scope *); -struct slang_struct_ *slang_struct_scope_find (slang_struct_scope *, slang_atom, int); - -typedef struct slang_struct_ -{ - slang_atom a_name; - struct slang_variable_scope_ *fields; - slang_struct_scope *structs; - struct slang_function_ *constructor; -} slang_struct; - -int slang_struct_construct (slang_struct *); -void slang_struct_destruct (slang_struct *); -int slang_struct_copy (slang_struct *, const slang_struct *); -int slang_struct_equal (const slang_struct *, const slang_struct *); - -#ifdef __cplusplus -} -#endif - -#endif - diff --git a/mesalib/src/mesa/shader/slang/slang_compile_variable.c b/mesalib/src/mesa/shader/slang/slang_compile_variable.c deleted file mode 100644 index 23c08a903..000000000 --- a/mesalib/src/mesa/shader/slang/slang_compile_variable.c +++ /dev/null @@ -1,247 +0,0 @@ -/* - * 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_compile_variable.c - * slang front-end compiler - * \author Michal Krol - */ - -#include "main/imports.h" -#include "slang_compile.h" -#include "slang_mem.h" - - -static slang_variable * -slang_variable_new(void) -{ - slang_variable *v = (slang_variable *) _slang_alloc(sizeof(slang_variable)); - if (v) { - if (!slang_variable_construct(v)) { - _slang_free(v); - v = NULL; - } - } - return v; -} - - -static void -slang_variable_delete(slang_variable * var) -{ - slang_variable_destruct(var); - _slang_free(var); -} - - -/* - * slang_variable_scope - */ - -slang_variable_scope * -_slang_variable_scope_new(slang_variable_scope *parent) -{ - slang_variable_scope *s; - s = (slang_variable_scope *) _slang_alloc(sizeof(slang_variable_scope)); - if (s) - s->outer_scope = parent; - return s; -} - - -GLvoid -_slang_variable_scope_ctr(slang_variable_scope * self) -{ - self->variables = NULL; - self->num_variables = 0; - self->outer_scope = NULL; -} - -void -slang_variable_scope_destruct(slang_variable_scope * scope) -{ - unsigned int i; - - if (!scope) - return; - for (i = 0; i < scope->num_variables; i++) { - if (scope->variables[i]) - slang_variable_delete(scope->variables[i]); - } - _slang_free(scope->variables); - /* do not free scope->outer_scope */ -} - -int -slang_variable_scope_copy(slang_variable_scope * x, - const slang_variable_scope * y) -{ - slang_variable_scope z; - unsigned int i; - - _slang_variable_scope_ctr(&z); - z.variables = (slang_variable **) - _slang_alloc(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++) { - 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])) { - slang_variable_scope_destruct(&z); - return 0; - } - } - z.outer_scope = y->outer_scope; - slang_variable_scope_destruct(x); - *x = z; - return 1; -} - - -/** - * Grow the variable list by one. - * \return pointer to space for the new variable (will be initialized) - */ -slang_variable * -slang_variable_scope_grow(slang_variable_scope *scope) -{ - const int n = scope->num_variables; - scope->variables = (slang_variable **) - _slang_realloc(scope->variables, - n * sizeof(slang_variable *), - (n + 1) * sizeof(slang_variable *)); - if (!scope->variables) - return NULL; - - scope->num_variables++; - - scope->variables[n] = slang_variable_new(); - if (!scope->variables[n]) - return NULL; - - return scope->variables[n]; -} - - - -/* slang_variable */ - -int -slang_variable_construct(slang_variable * var) -{ - if (!slang_fully_specified_type_construct(&var->type)) - return 0; - var->a_name = SLANG_ATOM_NULL; - var->array_len = 0; - var->initializer = NULL; - var->size = 0; - var->isTemp = GL_FALSE; - var->store = NULL; - var->declared = 0; - return 1; -} - - -void -slang_variable_destruct(slang_variable * var) -{ - slang_fully_specified_type_destruct(&var->type); - if (var->initializer != NULL) { - slang_operation_destruct(var->initializer); - _slang_free(var->initializer); - } -#if 0 - if (var->aux) { - free(var->aux); - } -#endif -} - - -int -slang_variable_copy(slang_variable * x, const slang_variable * y) -{ - slang_variable z; - - if (!slang_variable_construct(&z)) - return 0; - if (!slang_fully_specified_type_copy(&z.type, &y->type)) { - slang_variable_destruct(&z); - return 0; - } - z.a_name = y->a_name; - z.array_len = y->array_len; - if (y->initializer != NULL) { - z.initializer - = (slang_operation *) _slang_alloc(sizeof(slang_operation)); - if (z.initializer == NULL) { - slang_variable_destruct(&z); - return 0; - } - if (!slang_operation_construct(z.initializer)) { - _slang_free(z.initializer); - slang_variable_destruct(&z); - return 0; - } - if (!slang_operation_copy(z.initializer, y->initializer)) { - slang_variable_destruct(&z); - return 0; - } - } - z.size = y->size; - slang_variable_destruct(x); - *x = z; - return 1; -} - - -/** - * Search for named variable in given scope. - * \param all if true, search parent scopes too. - */ -slang_variable * -_slang_variable_locate(const slang_variable_scope * scope, - const slang_atom a_name, GLboolean all) -{ - while (scope) { - GLuint i; - for (i = 0; i < scope->num_variables; i++) - if (a_name == scope->variables[i]->a_name) - return scope->variables[i]; - if (all) - scope = scope->outer_scope; - else - scope = NULL; - } - return NULL; -} diff --git a/mesalib/src/mesa/shader/slang/slang_compile_variable.h b/mesalib/src/mesa/shader/slang/slang_compile_variable.h deleted file mode 100644 index 5c9d248b3..000000000 --- a/mesalib/src/mesa/shader/slang/slang_compile_variable.h +++ /dev/null @@ -1,90 +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_COMPILE_VARIABLE_H -#define SLANG_COMPILE_VARIABLE_H - - -struct slang_ir_storage_; - - -/** - * A shading language program variable. - */ -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 */ - struct slang_operation_ *initializer; /**< Optional initializer code */ - GLuint size; /**< Variable's size in bytes */ - GLboolean is_global; - GLboolean isTemp; /**< a named temporary (__resultTmp) */ - GLboolean declared; /**< has the var been declared? */ - struct slang_ir_storage_ *store; /**< Storage for this var */ -} slang_variable; - - -/** - * Basically a list of variables, with a pointer to the parent scope. - */ -typedef struct slang_variable_scope_ -{ - 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 *); - -extern void -slang_variable_scope_destruct(slang_variable_scope *); - -extern int -slang_variable_scope_copy(slang_variable_scope *, - const slang_variable_scope *); - -extern slang_variable * -slang_variable_scope_grow(slang_variable_scope *); - -extern int -slang_variable_construct(slang_variable *); - -extern void -slang_variable_destruct(slang_variable *); - -extern int -slang_variable_copy(slang_variable *, const slang_variable *); - -extern slang_variable * -_slang_variable_locate(const slang_variable_scope *, const slang_atom a_name, - GLboolean all); - - -#endif /* SLANG_COMPILE_VARIABLE_H */ diff --git a/mesalib/src/mesa/shader/slang/slang_emit.c b/mesalib/src/mesa/shader/slang/slang_emit.c deleted file mode 100644 index 7c0ea0c11..000000000 --- a/mesalib/src/mesa/shader/slang/slang_emit.c +++ /dev/null @@ -1,2667 +0,0 @@ -/* - * Mesa 3-D graphics library - * - * Copyright (C) 2005-2008 Brian Paul All Rights Reserved. - * Copyright (C) 2008 VMware, 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. - */ - -/** - * \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 "main/imports.h" -#include "main/context.h" -#include "shader/program.h" -#include "shader/prog_instruction.h" -#include "shader/prog_parameter.h" -#include "shader/prog_print.h" -#include "slang_builtin.h" -#include "slang_emit.h" -#include "slang_mem.h" - - -#define PEEPHOLE_OPTIMIZATIONS 1 -#define ANNOTATE 0 - - -typedef struct -{ - slang_info_log *log; - slang_var_table *vt; - struct gl_program *prog; - struct gl_program **Subroutines; - GLuint NumSubroutines; - - GLuint MaxInstructions; /**< size of prog->Instructions[] buffer */ - - GLboolean UnresolvedFunctions; - - /* code-gen options */ - GLboolean EmitHighLevelInstructions; - GLboolean EmitCondCodes; - GLboolean EmitComments; - GLboolean EmitBeginEndSub; /* XXX TEMPORARY */ -} slang_emit_info; - - - -static struct gl_program * -new_subroutine(slang_emit_info *emitInfo, GLuint *id) -{ - GET_CURRENT_CONTEXT(ctx); - const GLuint n = emitInfo->NumSubroutines; - - emitInfo->Subroutines = (struct gl_program **) - _mesa_realloc(emitInfo->Subroutines, - n * sizeof(struct gl_program *), - (n + 1) * sizeof(struct gl_program *)); - emitInfo->Subroutines[n] = ctx->Driver.NewProgram(ctx, emitInfo->prog->Target, 0); - emitInfo->Subroutines[n]->Parameters = emitInfo->prog->Parameters; - emitInfo->NumSubroutines++; - *id = n; - return emitInfo->Subroutines[n]; -} - - -/** - * Convert a writemask to a swizzle. Used for testing cond codes because - * we only want to test the cond code component(s) that was set by the - * previous instruction. - */ -static GLuint -writemask_to_swizzle(GLuint writemask) -{ - if (writemask == WRITEMASK_X) - return SWIZZLE_XXXX; - if (writemask == WRITEMASK_Y) - return SWIZZLE_YYYY; - if (writemask == WRITEMASK_Z) - return SWIZZLE_ZZZZ; - if (writemask == WRITEMASK_W) - return SWIZZLE_WWWW; - return SWIZZLE_XYZW; /* shouldn't be hit */ -} - - -/** - * Convert a swizzle mask to a writemask. - * Note that the slang_ir_storage->Swizzle field can represent either a - * swizzle mask or a writemask, depending on how it's used. For example, - * when we parse "direction.yz" alone, we don't know whether .yz is a - * writemask or a swizzle. In this case, we encode ".yz" in store->Swizzle - * as a swizzle mask (.yz?? actually). Later, if direction.yz is used as - * an R-value, we use store->Swizzle as-is. Otherwise, if direction.yz is - * used as an L-value, we convert it to a writemask. - */ -static GLuint -swizzle_to_writemask(GLuint swizzle) -{ - GLuint i, writemask = 0x0; - for (i = 0; i < 4; i++) { - GLuint swz = GET_SWZ(swizzle, i); - if (swz <= SWIZZLE_W) { - writemask |= (1 << swz); - } - } - return writemask; -} - - -/** - * Swizzle a swizzle (function composition). - * That is, return swz2(swz1), or said another way: swz1.szw2 - * Example: swizzle_swizzle(".zwxx", ".xxyw") yields ".zzwx" - */ -GLuint -_slang_swizzle_swizzle(GLuint swz1, GLuint swz2) -{ - GLuint i, swz, s[4]; - for (i = 0; i < 4; i++) { - GLuint c = GET_SWZ(swz2, i); - if (c <= SWIZZLE_W) - s[i] = GET_SWZ(swz1, c); - else - s[i] = c; - } - swz = MAKE_SWIZZLE4(s[0], s[1], s[2], s[3]); - return swz; -} - - -/** - * Return the default swizzle mask for accessing a variable of the - * given size (in floats). If size = 1, comp is used to identify - * which component [0..3] of the register holds the variable. - */ -GLuint -_slang_var_swizzle(GLint size, GLint comp) -{ - switch (size) { - case 1: - return MAKE_SWIZZLE4(comp, SWIZZLE_NIL, SWIZZLE_NIL, SWIZZLE_NIL); - case 2: - return MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_Y, SWIZZLE_NIL, SWIZZLE_NIL); - case 3: - return MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_Y, SWIZZLE_Z, SWIZZLE_NIL); - default: - return SWIZZLE_XYZW; - } -} - - - -/** - * Allocate storage for the given node (if it hasn't already been allocated). - * - * Typically this is temporary storage for an intermediate result (such as - * for a multiply or add, etc). - * - * If n->Store does not exist it will be created and will be of the size - * specified by defaultSize. - */ -static GLboolean -alloc_node_storage(slang_emit_info *emitInfo, slang_ir_node *n, - GLint defaultSize) -{ - assert(!n->Var); - if (!n->Store) { - assert(defaultSize > 0); - n->Store = _slang_new_ir_storage(PROGRAM_TEMPORARY, -1, defaultSize); - if (!n->Store) { - return GL_FALSE; - } - } - - /* now allocate actual register(s). I.e. set n->Store->Index >= 0 */ - if (n->Store->Index < 0) { - if (!_slang_alloc_temp(emitInfo->vt, n->Store)) { - slang_info_log_error(emitInfo->log, - "Ran out of registers, too many temporaries"); - _slang_free(n->Store); - n->Store = NULL; - return GL_FALSE; - } - } - return GL_TRUE; -} - - -/** - * Free temporary storage, if n->Store is, in fact, temp storage. - * Otherwise, no-op. - */ -static void -free_node_storage(slang_var_table *vt, slang_ir_node *n) -{ - if (n->Store->File == PROGRAM_TEMPORARY && - n->Store->Index >= 0 && - n->Opcode != IR_SWIZZLE) { - if (_slang_is_temp(vt, n->Store)) { - _slang_free_temp(vt, n->Store); - n->Store->Index = -1; - n->Store = NULL; /* XXX this may not be needed */ - } - } -} - - -/** - * Helper function to allocate a short-term temporary. - * Free it with _slang_free_temp(). - */ -static GLboolean -alloc_local_temp(slang_emit_info *emitInfo, slang_ir_storage *temp, GLint size) -{ - assert(size >= 1); - assert(size <= 4); - memset(temp, 0, sizeof(*temp)); - temp->Size = size; - temp->File = PROGRAM_TEMPORARY; - temp->Index = -1; - return _slang_alloc_temp(emitInfo->vt, temp); -} - - -/** - * Remove any SWIZZLE_NIL terms from given swizzle mask. - * For a swizzle like .z??? generate .zzzz (replicate single component). - * Else, for .wx?? generate .wxzw (insert default component for the position). - */ -static GLuint -fix_swizzle(GLuint swizzle) -{ - GLuint c0 = GET_SWZ(swizzle, 0), - c1 = GET_SWZ(swizzle, 1), - c2 = GET_SWZ(swizzle, 2), - c3 = GET_SWZ(swizzle, 3); - if (c1 == SWIZZLE_NIL && c2 == SWIZZLE_NIL && c3 == SWIZZLE_NIL) { - /* smear first component across all positions */ - c1 = c2 = c3 = c0; - } - else { - /* insert default swizzle components */ - if (c0 == SWIZZLE_NIL) - c0 = SWIZZLE_X; - if (c1 == SWIZZLE_NIL) - c1 = SWIZZLE_Y; - if (c2 == SWIZZLE_NIL) - c2 = SWIZZLE_Z; - if (c3 == SWIZZLE_NIL) - c3 = SWIZZLE_W; - } - return MAKE_SWIZZLE4(c0, c1, c2, c3); -} - - - -/** - * Convert IR storage to an instruction dst register. - */ -static void -storage_to_dst_reg(struct prog_dst_register *dst, const slang_ir_storage *st) -{ - const GLboolean relAddr = st->RelAddr; - const GLint size = st->Size; - GLint index = st->Index; - GLuint swizzle = st->Swizzle; - - assert(index >= 0); - /* if this is storage relative to some parent storage, walk up the tree */ - while (st->Parent) { - st = st->Parent; - assert(st->Index >= 0); - index += st->Index; - swizzle = _slang_swizzle_swizzle(st->Swizzle, swizzle); - } - - assert(st->File != PROGRAM_UNDEFINED); - dst->File = st->File; - - assert(index >= 0); - dst->Index = index; - - assert(size >= 1); - assert(size <= 4); - - if (swizzle != SWIZZLE_XYZW) { - dst->WriteMask = swizzle_to_writemask(swizzle); - } - else { - switch (size) { - case 1: - dst->WriteMask = WRITEMASK_X << GET_SWZ(st->Swizzle, 0); - break; - case 2: - dst->WriteMask = WRITEMASK_XY; - break; - case 3: - dst->WriteMask = WRITEMASK_XYZ; - break; - case 4: - dst->WriteMask = WRITEMASK_XYZW; - break; - default: - ; /* error would have been caught above */ - } - } - - dst->RelAddr = relAddr; -} - - -/** - * Convert IR storage to an instruction src register. - */ -static void -storage_to_src_reg(struct prog_src_register *src, const slang_ir_storage *st) -{ - const GLboolean relAddr = st->RelAddr; - GLint index = st->Index; - GLuint swizzle = st->Swizzle; - - /* if this is storage relative to some parent storage, walk up the tree */ - assert(index >= 0); - while (st->Parent) { - st = st->Parent; - if (st->Index < 0) { - /* an error should have been reported already */ - return; - } - assert(st->Index >= 0); - index += st->Index; - swizzle = _slang_swizzle_swizzle(fix_swizzle(st->Swizzle), swizzle); - } - - assert(st->File >= 0); -#if 1 /* XXX temporary */ - if (st->File == PROGRAM_UNDEFINED) { - slang_ir_storage *st0 = (slang_ir_storage *) st; - st0->File = PROGRAM_TEMPORARY; - } -#endif - assert(st->File < PROGRAM_UNDEFINED); - src->File = st->File; - - assert(index >= 0); - src->Index = index; - - swizzle = fix_swizzle(swizzle); - assert(GET_SWZ(swizzle, 0) <= SWIZZLE_W); - assert(GET_SWZ(swizzle, 1) <= SWIZZLE_W); - assert(GET_SWZ(swizzle, 2) <= SWIZZLE_W); - assert(GET_SWZ(swizzle, 3) <= SWIZZLE_W); - src->Swizzle = swizzle; - - src->RelAddr = relAddr; -} - - -/* - * Setup storage pointing to a scalar constant/literal. - */ -static void -constant_to_storage(slang_emit_info *emitInfo, - GLfloat val, - slang_ir_storage *store) -{ - GLuint swizzle; - GLint reg; - GLfloat value[4]; - - value[0] = val; - reg = _mesa_add_unnamed_constant(emitInfo->prog->Parameters, - value, 1, &swizzle); - - memset(store, 0, sizeof(*store)); - store->File = PROGRAM_CONSTANT; - store->Index = reg; - store->Swizzle = swizzle; -} - - -/** - * 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; - -#if 0 - /* print prev inst */ - if (prog->NumInstructions > 0) { - _mesa_print_instruction(prog->Instructions + prog->NumInstructions - 1); - } -#endif - assert(prog->NumInstructions <= emitInfo->MaxInstructions); - - if (prog->NumInstructions == emitInfo->MaxInstructions) { - /* grow the instruction buffer */ - emitInfo->MaxInstructions += 20; - prog->Instructions = - _mesa_realloc_instructions(prog->Instructions, - prog->NumInstructions, - emitInfo->MaxInstructions); - if (!prog->Instructions) { - return NULL; - } - } - - 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; -} - - -static struct prog_instruction * -emit_arl_load(slang_emit_info *emitInfo, - gl_register_file file, GLint index, GLuint swizzle) -{ - struct prog_instruction *inst = new_instruction(emitInfo, OPCODE_ARL); - if (inst) { - inst->SrcReg[0].File = file; - inst->SrcReg[0].Index = index; - inst->SrcReg[0].Swizzle = fix_swizzle(swizzle); - inst->DstReg.File = PROGRAM_ADDRESS; - inst->DstReg.Index = 0; - inst->DstReg.WriteMask = WRITEMASK_X; - } - return inst; -} - - -/** - * Emit a new instruction with given opcode, operands. - * At this point the instruction may have multiple indirect register - * loads/stores. We convert those into ARL loads and address-relative - * operands. See comments inside. - * At some point in the future we could directly emit indirectly addressed - * registers in Mesa GPU instructions. - */ -static struct prog_instruction * -emit_instruction(slang_emit_info *emitInfo, - gl_inst_opcode opcode, - const slang_ir_storage *dst, - const slang_ir_storage *src0, - const slang_ir_storage *src1, - const slang_ir_storage *src2) -{ - struct prog_instruction *inst; - GLuint numIndirect = 0; - const slang_ir_storage *src[3]; - slang_ir_storage newSrc[3], newDst; - GLuint i; - GLboolean isTemp[3]; - - isTemp[0] = isTemp[1] = isTemp[2] = GL_FALSE; - - src[0] = src0; - src[1] = src1; - src[2] = src2; - - /* count up how many operands are indirect loads */ - for (i = 0; i < 3; i++) { - if (src[i] && src[i]->IsIndirect) - numIndirect++; - } - if (dst && dst->IsIndirect) - numIndirect++; - - /* Take special steps for indirect register loads. - * If we had multiple address registers this would be simpler. - * For example, this GLSL code: - * x[i] = y[j] + z[k]; - * would translate into something like: - * ARL ADDR.x, i; - * ARL ADDR.y, j; - * ARL ADDR.z, k; - * ADD TEMP[ADDR.x+5], TEMP[ADDR.y+9], TEMP[ADDR.z+4]; - * But since we currently only have one address register we have to do this: - * ARL ADDR.x, i; - * MOV t1, TEMP[ADDR.x+9]; - * ARL ADDR.x, j; - * MOV t2, TEMP[ADDR.x+4]; - * ARL ADDR.x, k; - * ADD TEMP[ADDR.x+5], t1, t2; - * The code here figures this out... - */ - if (numIndirect > 0) { - for (i = 0; i < 3; i++) { - if (src[i] && src[i]->IsIndirect) { - /* load the ARL register with the indirect register */ - emit_arl_load(emitInfo, - src[i]->IndirectFile, - src[i]->IndirectIndex, - src[i]->IndirectSwizzle); - - if (numIndirect > 1) { - /* Need to load src[i] into a temporary register */ - slang_ir_storage srcRelAddr; - alloc_local_temp(emitInfo, &newSrc[i], src[i]->Size); - isTemp[i] = GL_TRUE; - - /* set RelAddr flag on src register */ - srcRelAddr = *src[i]; - srcRelAddr.RelAddr = GL_TRUE; - srcRelAddr.IsIndirect = GL_FALSE; /* not really needed */ - - /* MOV newSrc, srcRelAddr; */ - inst = emit_instruction(emitInfo, - OPCODE_MOV, - &newSrc[i], - &srcRelAddr, - NULL, - NULL); - if (!inst) { - return NULL; - } - - src[i] = &newSrc[i]; - } - else { - /* just rewrite the src[i] storage to be ARL-relative */ - newSrc[i] = *src[i]; - newSrc[i].RelAddr = GL_TRUE; - newSrc[i].IsIndirect = GL_FALSE; /* not really needed */ - src[i] = &newSrc[i]; - } - } - } - } - - /* Take special steps for indirect dest register write */ - if (dst && dst->IsIndirect) { - /* load the ARL register with the indirect register */ - emit_arl_load(emitInfo, - dst->IndirectFile, - dst->IndirectIndex, - dst->IndirectSwizzle); - newDst = *dst; - newDst.RelAddr = GL_TRUE; - newDst.IsIndirect = GL_FALSE; - dst = &newDst; - } - - /* OK, emit the instruction and its dst, src regs */ - inst = new_instruction(emitInfo, opcode); - if (!inst) - return NULL; - - if (dst) - storage_to_dst_reg(&inst->DstReg, dst); - - for (i = 0; i < 3; i++) { - if (src[i]) - storage_to_src_reg(&inst->SrcReg[i], src[i]); - } - - /* Free any temp registers that we allocated above */ - for (i = 0; i < 3; i++) { - if (isTemp[i]) - _slang_free_temp(emitInfo->vt, &newSrc[i]); - } - - return inst; -} - - - -/** - * Put a comment on the given instruction. - */ -static void -inst_comment(struct prog_instruction *inst, const char *comment) -{ - if (inst) - inst->Comment = _mesa_strdup(comment); -} - - - -/** - * Return pointer to last instruction in program. - */ -static struct prog_instruction * -prev_instruction(slang_emit_info *emitInfo) -{ - struct gl_program *prog = emitInfo->prog; - if (prog->NumInstructions == 0) - return NULL; - else - return prog->Instructions + prog->NumInstructions - 1; -} - - -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_DP2: - operator = "DP2"; - 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(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 *comment) -{ - struct prog_instruction *inst = new_instruction(emitInfo, OPCODE_NOP); - if (inst) { - inst_comment(inst, comment); - } - 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) -{ - const slang_ir_info *info = _slang_ir_info(n->Opcode); - struct prog_instruction *inst; - GLuint i; - - assert(info); - assert(info->InstOpcode != OPCODE_NOP); - -#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 */ - if (!alloc_node_storage(emitInfo, n, -1)) { /* dest */ - return NULL; - } - - inst = emit_instruction(emitInfo, - OPCODE_MAD, - n->Store, - n->Children[0]->Children[0]->Store, - n->Children[0]->Children[1]->Store, - n->Children[1]->Store); - - free_node_storage(emitInfo->vt, n->Children[0]->Children[0]); - free_node_storage(emitInfo->vt, n->Children[0]->Children[1]); - free_node_storage(emitInfo->vt, n->Children[1]); - return inst; - } - - 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 */ - if (!alloc_node_storage(emitInfo, n, -1)) { /* dest */ - return NULL; - } - - inst = emit_instruction(emitInfo, - OPCODE_MAD, - n->Store, - n->Children[1]->Children[0]->Store, - n->Children[1]->Children[1]->Store, - n->Children[0]->Store); - - free_node_storage(emitInfo->vt, n->Children[1]->Children[0]); - free_node_storage(emitInfo->vt, n->Children[1]->Children[1]); - free_node_storage(emitInfo->vt, n->Children[0]); - return inst; - } -#endif - - /* gen code for children, may involve temp allocation */ - for (i = 0; i < info->NumParams; i++) { - emit(emitInfo, n->Children[i]); - if (!n->Children[i] || !n->Children[i]->Store) { - /* error recovery */ - return NULL; - } - } - - /* result storage */ - if (!alloc_node_storage(emitInfo, n, -1)) { - return NULL; - } - - inst = emit_instruction(emitInfo, - info->InstOpcode, - n->Store, /* dest */ - (info->NumParams > 0 ? n->Children[0]->Store : NULL), - (info->NumParams > 1 ? n->Children[1]->Store : NULL), - (info->NumParams > 2 ? n->Children[2]->Store : NULL) - ); - - /* free temps */ - for (i = 0; i < info->NumParams; i++) - free_node_storage(emitInfo->vt, n->Children[i]); - - 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 = NULL; - 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 (n->Children[0]->Store->Size != n->Children[1]->Store->Size) { - /* XXX this error should have been caught in slang_codegen.c */ - slang_info_log_error(emitInfo->log, "invalid operands to == or !="); - n->Store = NULL; - return NULL; - } - - /* final result is 1 bool */ - if (!alloc_node_storage(emitInfo, n, 1)) - return NULL; - - size = n->Children[0]->Store->Size; - - if (size == 1) { - gl_inst_opcode opcode = n->Opcode == IR_EQUAL ? OPCODE_SEQ : OPCODE_SNE; - inst = emit_instruction(emitInfo, - opcode, - n->Store, /* dest */ - n->Children[0]->Store, - n->Children[1]->Store, - NULL); - } - else if (size <= 4) { - /* compare two vectors. - * Unfortunately, there's no instruction to compare vectors and - * return a scalar result. Do it with some compare and dot product - * instructions... - */ - GLuint swizzle; - gl_inst_opcode dotOp; - slang_ir_storage tempStore; - - if (!alloc_local_temp(emitInfo, &tempStore, 4)) { - n->Store = NULL; - return NULL; - /* out of temps */ - } - - 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; /* XXX use OPCODE_DP2 eventually */ - swizzle = MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_Y, SWIZZLE_Y, SWIZZLE_Y); - } - - /* Compute inequality (temp = (A != B)) */ - inst = emit_instruction(emitInfo, - OPCODE_SNE, - &tempStore, - n->Children[0]->Store, - n->Children[1]->Store, - NULL); - if (!inst) { - return NULL; - } - inst_comment(inst, "Compare values"); - - /* Compute val = DOT(temp, temp) (reduction) */ - inst = emit_instruction(emitInfo, - dotOp, - n->Store, - &tempStore, - &tempStore, - NULL); - if (!inst) { - return NULL; - } - inst->SrcReg[0].Swizzle = inst->SrcReg[1].Swizzle = swizzle; /*override*/ - inst_comment(inst, "Reduce vec to bool"); - - _slang_free_temp(emitInfo->vt, &tempStore); /* free temp */ - - if (n->Opcode == IR_EQUAL) { - /* compute val = !val.x with SEQ val, val, 0; */ - slang_ir_storage zero; - constant_to_storage(emitInfo, 0.0, &zero); - inst = emit_instruction(emitInfo, - OPCODE_SEQ, - n->Store, /* dest */ - n->Store, - &zero, - NULL); - if (!inst) { - return NULL; - } - inst_comment(inst, "Invert true/false"); - } - } - else { - /* size > 4, struct or array compare. - * XXX this won't work reliably for structs with padding!! - */ - GLint i, num = (n->Children[0]->Store->Size + 3) / 4; - slang_ir_storage accTemp, sneTemp; - - if (!alloc_local_temp(emitInfo, &accTemp, 4)) - return NULL; - - if (!alloc_local_temp(emitInfo, &sneTemp, 4)) - return NULL; - - for (i = 0; i < num; i++) { - slang_ir_storage srcStore0 = *n->Children[0]->Store; - slang_ir_storage srcStore1 = *n->Children[1]->Store; - srcStore0.Index += i; - srcStore1.Index += i; - - if (i == 0) { - /* SNE accTemp, left[i], right[i] */ - inst = emit_instruction(emitInfo, OPCODE_SNE, - &accTemp, /* dest */ - &srcStore0, - &srcStore1, - NULL); - if (!inst) { - return NULL; - } - inst_comment(inst, "Begin struct/array comparison"); - } - else { - /* SNE sneTemp, left[i], right[i] */ - inst = emit_instruction(emitInfo, OPCODE_SNE, - &sneTemp, /* dest */ - &srcStore0, - &srcStore1, - NULL); - if (!inst) { - return NULL; - } - /* ADD accTemp, accTemp, sneTemp; # like logical-OR */ - inst = emit_instruction(emitInfo, OPCODE_ADD, - &accTemp, /* dest */ - &accTemp, - &sneTemp, - NULL); - if (!inst) { - return NULL; - } - } - } - - /* compute accTemp.x || accTemp.y || accTemp.z || accTemp.w with DOT4 */ - inst = emit_instruction(emitInfo, OPCODE_DP4, - n->Store, - &accTemp, - &accTemp, - NULL); - if (!inst) { - return NULL; - } - inst_comment(inst, "End struct/array comparison"); - - if (n->Opcode == IR_EQUAL) { - /* compute tmp.x = !tmp.x via tmp.x = (tmp.x == 0) */ - slang_ir_storage zero; - constant_to_storage(emitInfo, 0.0, &zero); - inst = emit_instruction(emitInfo, OPCODE_SEQ, - n->Store, /* dest */ - n->Store, - &zero, - NULL); - if (!inst) { - return NULL; - } - inst_comment(inst, "Invert true/false"); - } - - _slang_free_temp(emitInfo->vt, &accTemp); - _slang_free_temp(emitInfo->vt, &sneTemp); - } - - /* free temps */ - free_node_storage(emitInfo->vt, n->Children[0]); - free_node_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; - slang_ir_node tmpNode; - - 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; - } - } -#else - (void) inst; -#endif - - if (!alloc_node_storage(emitInfo, n, n->Children[0]->Store->Size)) - return NULL; - - emit(emitInfo, n->Children[1]); - emit(emitInfo, n->Children[2]); - - /* Some GPUs don't allow reading from output registers. So if the - * dest for this clamp() is an output reg, we can't use that reg for - * the intermediate result. Use a temp register instead. - */ - memset(&tmpNode, 0, sizeof(tmpNode)); - if (!alloc_node_storage(emitInfo, &tmpNode, n->Store->Size)) { - return NULL; - } - - /* tmp = max(ch[0], ch[1]) */ - inst = emit_instruction(emitInfo, OPCODE_MAX, - tmpNode.Store, /* dest */ - n->Children[0]->Store, - n->Children[1]->Store, - NULL); - if (!inst) { - return NULL; - } - - /* n->dest = min(tmp, ch[2]) */ - inst = emit_instruction(emitInfo, OPCODE_MIN, - n->Store, /* dest */ - tmpNode.Store, - n->Children[2]->Store, - NULL); - - free_node_storage(emitInfo->vt, &tmpNode); - - 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 (!alloc_node_storage(emitInfo, n, n->Children[0]->Store->Size)) - return NULL; - - inst = emit_instruction(emitInfo, - OPCODE_MOV, - n->Store, /* dest */ - n->Children[0]->Store, - NULL, - NULL); - if (inst) { - inst->SrcReg[0].Negate = 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; -} - - -/** - * Emit code for a function call. - * Note that for each time a function is called, we emit the function's - * body code again because the set of available registers may be different. - */ -static struct prog_instruction * -emit_fcall(slang_emit_info *emitInfo, slang_ir_node *n) -{ - struct gl_program *progSave; - struct prog_instruction *inst; - GLuint subroutineId; - GLuint maxInstSave; - - assert(n->Opcode == IR_CALL); - assert(n->Label); - - /* save/push cur program */ - maxInstSave = emitInfo->MaxInstructions; - progSave = emitInfo->prog; - - emitInfo->prog = new_subroutine(emitInfo, &subroutineId); - emitInfo->MaxInstructions = emitInfo->prog->NumInstructions; - - _slang_label_set_location(n->Label, emitInfo->prog->NumInstructions, - emitInfo->prog); - - if (emitInfo->EmitBeginEndSub) { - /* BGNSUB isn't a real instruction. - * We require a label (i.e. "foobar:") though, if we're going to - * print the program in the NV format. The BNGSUB instruction is - * really just a NOP to attach the label to. - */ - inst = new_instruction(emitInfo, OPCODE_BGNSUB); - if (!inst) { - return NULL; - } - inst_comment(inst, n->Label->Name); - } - - /* body of function: */ - emit(emitInfo, n->Children[0]); - n->Store = n->Children[0]->Store; - - /* add RET instruction now, if needed */ - inst = prev_instruction(emitInfo); - if (inst && inst->Opcode != OPCODE_RET) { - inst = new_instruction(emitInfo, OPCODE_RET); - if (!inst) { - return NULL; - } - } - - if (emitInfo->EmitBeginEndSub) { - inst = new_instruction(emitInfo, OPCODE_ENDSUB); - if (!inst) { - return NULL; - } - inst_comment(inst, n->Label->Name); - } - - /* pop/restore cur program */ - emitInfo->prog = progSave; - emitInfo->MaxInstructions = maxInstSave; - - /* emit the function call */ - inst = new_instruction(emitInfo, OPCODE_CAL); - if (!inst) { - return NULL; - } - /* The branch target is just the subroutine number (changed later) */ - inst->BranchTarget = subroutineId; - inst_comment(inst, n->Label->Name); - assert(inst->BranchTarget >= 0); - - return inst; -} - - -/** - * Emit code for a 'return' statement. - */ -static struct prog_instruction * -emit_return(slang_emit_info *emitInfo, slang_ir_node *n) -{ - struct prog_instruction *inst; - assert(n); - assert(n->Opcode == IR_RETURN); - assert(n->Label); - inst = new_instruction(emitInfo, OPCODE_RET); - if (inst) { - inst->DstReg.CondMask = COND_TR; /* always return */ - } - return inst; -} - - -static struct prog_instruction * -emit_kill(slang_emit_info *emitInfo) -{ - struct gl_fragment_program *fp; - 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); - if (!inst) { - return NULL; - } - inst->DstReg.CondMask = COND_TR; /* always kill */ - - assert(emitInfo->prog->Target == GL_FRAGMENT_PROGRAM_ARB); - fp = (struct gl_fragment_program *) emitInfo->prog; - fp->UsesKill = GL_TRUE; - - return inst; -} - - -static struct prog_instruction * -emit_tex(slang_emit_info *emitInfo, slang_ir_node *n) -{ - struct prog_instruction *inst; - gl_inst_opcode opcode; - GLboolean shadow = GL_FALSE; - - switch (n->Opcode) { - case IR_TEX: - opcode = OPCODE_TEX; - break; - case IR_TEX_SH: - opcode = OPCODE_TEX; - shadow = GL_TRUE; - break; - case IR_TEXB: - opcode = OPCODE_TXB; - break; - case IR_TEXB_SH: - opcode = OPCODE_TXB; - shadow = GL_TRUE; - break; - case IR_TEXP: - opcode = OPCODE_TXP; - break; - case IR_TEXP_SH: - opcode = OPCODE_TXP; - shadow = GL_TRUE; - break; - default: - _mesa_problem(NULL, "Bad IR TEX code"); - return NULL; - } - - if (n->Children[0]->Opcode == IR_ELEMENT) { - /* array is the sampler (a uniform which'll indicate the texture unit) */ - assert(n->Children[0]->Children[0]->Store); - assert(n->Children[0]->Children[0]->Store->File == PROGRAM_SAMPLER); - - emit(emitInfo, n->Children[0]); - - n->Children[0]->Var = n->Children[0]->Children[0]->Var; - } else { - /* this is the sampler (a uniform which'll indicate the texture unit) */ - assert(n->Children[0]->Store); - assert(n->Children[0]->Store->File == PROGRAM_SAMPLER); - } - - /* emit code for the texcoord operand */ - (void) emit(emitInfo, n->Children[1]); - - /* alloc storage for result of texture fetch */ - if (!alloc_node_storage(emitInfo, n, 4)) - return NULL; - - /* emit TEX instruction; Child[1] is the texcoord */ - inst = emit_instruction(emitInfo, - opcode, - n->Store, - n->Children[1]->Store, - NULL, - NULL); - if (!inst) { - return NULL; - } - - inst->TexShadow = shadow; - - /* Store->Index is the uniform/sampler index */ - assert(n->Children[0]->Store->Index >= 0); - inst->TexSrcUnit = n->Children[0]->Store->Index; - inst->TexSrcTarget = n->Children[0]->Store->TexTarget; - - /* mark the sampler as being used */ - _mesa_use_uniform(emitInfo->prog->Parameters, - (char *) n->Children[0]->Var->a_name); - - return inst; -} - - -/** - * Assignment/copy - */ -static struct prog_instruction * -emit_copy(slang_emit_info *emitInfo, slang_ir_node *n) -{ - struct prog_instruction *inst; - - assert(n->Opcode == IR_COPY); - - /* lhs */ - emit(emitInfo, n->Children[0]); - if (!n->Children[0]->Store || n->Children[0]->Store->Index < 0) { - /* an error should have been already recorded */ - return NULL; - } - - /* rhs */ - assert(n->Children[1]); - inst = emit(emitInfo, n->Children[1]); - - if (!n->Children[1]->Store || n->Children[1]->Store->Index < 0) { - if (!emitInfo->log->text && !emitInfo->UnresolvedFunctions) { - /* XXX this error should have been caught in slang_codegen.c */ - slang_info_log_error(emitInfo->log, "invalid assignment"); - } - return NULL; - } - - assert(n->Children[1]->Store->Index >= 0); - - /*assert(n->Children[0]->Store->Size == n->Children[1]->Store->Size);*/ - - n->Store = n->Children[0]->Store; - - if (n->Store->File == PROGRAM_SAMPLER) { - /* no code generated for sampler assignments, - * just copy the sampler index/target at compile time. - */ - n->Store->Index = n->Children[1]->Store->Index; - n->Store->TexTarget = n->Children[1]->Store->TexTarget; - return NULL; - } - -#if PEEPHOLE_OPTIMIZATIONS - if (inst && - (n->Children[1]->Opcode != IR_SWIZZLE) && - _slang_is_temp(emitInfo->vt, n->Children[1]->Store) && - (inst->DstReg.File == n->Children[1]->Store->File) && - (inst->DstReg.Index == n->Children[1]->Store->Index) && - !n->Children[0]->Store->IsIndirect && - n->Children[0]->Store->Size <= 4) { - /* Peephole optimization: - * The Right-Hand-Side has its results in a temporary place. - * Modify the RHS (and the prev instruction) to store its results - * in the destination specified by n->Children[0]. - * Then, this MOVE is a no-op. - * Ex: - * MUL tmp, x, y; - * MOV a, tmp; - * becomes: - * MUL a, x, y; - */ - - /* fixup the previous instruction (which stored the RHS result) */ - assert(n->Children[0]->Store->Index >= 0); - storage_to_dst_reg(&inst->DstReg, n->Children[0]->Store); - 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[1]->Store->Swizzle == SWIZZLE_NOOP); - dstStore.Size = 4; - srcStore.Size = 4; - while (size >= 4) { - inst = emit_instruction(emitInfo, OPCODE_MOV, - &dstStore, - &srcStore, - NULL, - NULL); - if (!inst) { - return NULL; - } - inst_comment(inst, "IR_COPY block"); - srcStore.Index++; - dstStore.Index++; - size -= 4; - } - } - else { - /* single register move */ - char *srcAnnot, *dstAnnot; - assert(n->Children[0]->Store->Index >= 0); - inst = emit_instruction(emitInfo, OPCODE_MOV, - n->Children[0]->Store, /* dest */ - n->Children[1]->Store, - NULL, - NULL); - if (!inst) { - return NULL; - } - 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_node_storage(emitInfo->vt, n->Children[1]); - return inst; - } -} - - -/** - * An IR_COND node wraps a boolean expression which is used by an - * IF or WHILE test. This is where we'll set condition codes, if needed. - */ -static struct prog_instruction * -emit_cond(slang_emit_info *emitInfo, slang_ir_node *n) -{ - struct prog_instruction *inst; - - assert(n->Opcode == IR_COND); - - if (!n->Children[0]) - return NULL; - - /* emit code for the expression */ - inst = emit(emitInfo, n->Children[0]); - - if (!n->Children[0]->Store) { - /* error recovery */ - return NULL; - } - - assert(n->Children[0]->Store); - /*assert(n->Children[0]->Store->Size == 1);*/ - - if (emitInfo->EmitCondCodes) { - if (inst && - n->Children[0]->Store && - inst->DstReg.File == n->Children[0]->Store->File && - inst->DstReg.Index == n->Children[0]->Store->Index) { - /* The previous instruction wrote to the register who's value - * we're testing. Just fix that instruction so that the - * condition codes are computed. - */ - inst->CondUpdate = GL_TRUE; - n->Store = n->Children[0]->Store; - return inst; - } - 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. - */ - if (!alloc_node_storage(emitInfo, n, 1)) - return NULL; - inst = emit_instruction(emitInfo, OPCODE_MOV, - n->Store, /* dest */ - n->Children[0]->Store, - NULL, - NULL); - if (!inst) { - return NULL; - } - inst->CondUpdate = GL_TRUE; - inst_comment(inst, "COND expr"); - _slang_free_temp(emitInfo->vt, n->Store); - return inst; - } - } - else { - /* No-op: the boolean result of the expression is in a regular reg */ - n->Store = n->Children[0]->Store; - return inst; - } -} - - -/** - * Logical-NOT - */ -static struct prog_instruction * -emit_not(slang_emit_info *emitInfo, slang_ir_node *n) -{ - static const struct { - gl_inst_opcode op, opNot; - } operators[] = { - { OPCODE_SLT, OPCODE_SGE }, - { OPCODE_SLE, OPCODE_SGT }, - { OPCODE_SGT, OPCODE_SLE }, - { OPCODE_SGE, OPCODE_SLT }, - { OPCODE_SEQ, OPCODE_SNE }, - { OPCODE_SNE, OPCODE_SEQ }, - { 0, 0 } - }; - struct prog_instruction *inst; - slang_ir_storage zero; - GLuint i; - - /* child expr */ - inst = emit(emitInfo, n->Children[0]); - -#if PEEPHOLE_OPTIMIZATIONS - if (inst) { - /* if the prev instruction was a comparison instruction, invert it */ - for (i = 0; operators[i].op; i++) { - if (inst->Opcode == operators[i].op) { - inst->Opcode = operators[i].opNot; - n->Store = n->Children[0]->Store; - return inst; - } - } - } -#endif - - /* else, invert using SEQ (v = v == 0) */ - if (!alloc_node_storage(emitInfo, n, n->Children[0]->Store->Size)) - return NULL; - - constant_to_storage(emitInfo, 0.0, &zero); - inst = emit_instruction(emitInfo, - OPCODE_SEQ, - n->Store, - n->Children[0]->Store, - &zero, - NULL); - if (!inst) { - return NULL; - } - inst_comment(inst, "NOT"); - - free_node_storage(emitInfo->vt, n->Children[0]); - - return inst; -} - - -static struct prog_instruction * -emit_if(slang_emit_info *emitInfo, slang_ir_node *n) -{ - struct gl_program *prog = emitInfo->prog; - GLuint ifInstLoc, elseInstLoc = 0; - GLuint condWritemask = 0; - - /* emit condition expression code */ - { - struct prog_instruction *inst; - inst = emit(emitInfo, n->Children[0]); - if (emitInfo->EmitCondCodes) { - if (!inst) { - /* error recovery */ - return NULL; - } - condWritemask = inst->DstReg.WriteMask; - } - } - - if (!n->Children[0]->Store) - return NULL; - -#if 0 - assert(n->Children[0]->Store->Size == 1); /* a bool! */ -#endif - - ifInstLoc = prog->NumInstructions; - if (emitInfo->EmitHighLevelInstructions) { - if (emitInfo->EmitCondCodes) { - /* IF condcode THEN ... */ - struct prog_instruction *ifInst = new_instruction(emitInfo, OPCODE_IF); - if (!ifInst) { - return NULL; - } - ifInst->DstReg.CondMask = COND_NE; /* if cond is non-zero */ - /* only test the cond code (1 of 4) that was updated by the - * previous instruction. - */ - ifInst->DstReg.CondSwizzle = writemask_to_swizzle(condWritemask); - } - else { - struct prog_instruction *inst; - - /* IF src[0] THEN ... */ - inst = emit_instruction(emitInfo, OPCODE_IF, - NULL, /* dst */ - n->Children[0]->Store, /* op0 */ - NULL, - NULL); - if (!inst) { - return NULL; - } - } - } - else { - /* conditional jump to else, or endif */ - struct prog_instruction *ifInst = new_instruction(emitInfo, OPCODE_BRA); - if (!ifInst) { - return NULL; - } - ifInst->DstReg.CondMask = COND_EQ; /* BRA if cond is zero */ - inst_comment(ifInst, "if zero"); - ifInst->DstReg.CondSwizzle = writemask_to_swizzle(condWritemask); - } - - /* if body */ - emit(emitInfo, n->Children[1]); - - if (n->Children[2]) { - /* have else body */ - elseInstLoc = prog->NumInstructions; - if (emitInfo->EmitHighLevelInstructions) { - struct prog_instruction *inst = new_instruction(emitInfo, OPCODE_ELSE); - if (!inst) { - return NULL; - } - prog->Instructions[ifInstLoc].BranchTarget = prog->NumInstructions - 1; - } - else { - /* jump to endif instruction */ - struct prog_instruction *inst = new_instruction(emitInfo, OPCODE_BRA); - if (!inst) { - return NULL; - } - inst_comment(inst, "else"); - inst->DstReg.CondMask = COND_TR; /* always branch */ - prog->Instructions[ifInstLoc].BranchTarget = prog->NumInstructions; - } - emit(emitInfo, n->Children[2]); - } - else { - /* no else body */ - prog->Instructions[ifInstLoc].BranchTarget = prog->NumInstructions; - } - - if (emitInfo->EmitHighLevelInstructions) { - struct prog_instruction *inst = new_instruction(emitInfo, OPCODE_ENDIF); - if (!inst) { - return NULL; - } - } - - if (elseInstLoc) { - /* point ELSE instruction BranchTarget at ENDIF */ - if (emitInfo->EmitHighLevelInstructions) { - prog->Instructions[elseInstLoc].BranchTarget = prog->NumInstructions - 1; - } - else { - prog->Instructions[elseInstLoc].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 *endInst; - GLuint beginInstLoc, tailInstLoc, endInstLoc; - slang_ir_node *ir; - - /* emit OPCODE_BGNLOOP */ - beginInstLoc = prog->NumInstructions; - if (emitInfo->EmitHighLevelInstructions) { - struct prog_instruction *inst = new_instruction(emitInfo, OPCODE_BGNLOOP); - if (!inst) { - return NULL; - } - } - - /* 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); - if (!endInst) { - return NULL; - } - } - else { - /* emit unconditional BRA-nch */ - endInst = new_instruction(emitInfo, OPCODE_BRA); - if (!endInst) { - return NULL; - } - 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 */ - prog->Instructions[beginInstLoc].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 corresponding ENDLOOP instruction. - */ - 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_TRUE) { - assert(inst->Opcode == OPCODE_BRK || - inst->Opcode == OPCODE_BRA); - /* go to instruction at end of loop */ - if (emitInfo->EmitHighLevelInstructions) { - inst->BranchTarget = endInstLoc; - } - else { - inst->BranchTarget = endInstLoc + 1; - } - } - else { - assert(ir->Opcode == IR_CONT || - ir->Opcode == IR_CONT_IF_TRUE); - assert(inst->Opcode == OPCODE_CONT || - 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); - if (inst) { - 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_true(slang_emit_info *emitInfo, slang_ir_node *n) -{ - struct prog_instruction *inst; - - assert(n->Opcode == IR_CONT_IF_TRUE || - n->Opcode == IR_BREAK_IF_TRUE); - - /* 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) { - const gl_inst_opcode opcode - = (n->Opcode == IR_CONT_IF_TRUE) ? OPCODE_CONT : OPCODE_BRK; - if (emitInfo->EmitCondCodes) { - /* Get the writemask from the previous instruction which set - * the condcodes. Use that writemask as the CondSwizzle. - */ - const GLuint condWritemask = inst->DstReg.WriteMask; - inst = new_instruction(emitInfo, opcode); - if (inst) { - inst->DstReg.CondMask = COND_NE; - inst->DstReg.CondSwizzle = writemask_to_swizzle(condWritemask); - } - return inst; - } - else { - /* IF reg - * BRK/CONT; - * ENDIF - */ - GLint ifInstLoc; - ifInstLoc = emitInfo->prog->NumInstructions; - inst = emit_instruction(emitInfo, OPCODE_IF, - NULL, /* dest */ - n->Children[0]->Store, - NULL, - NULL); - if (!inst) { - return NULL; - } - n->InstLocation = emitInfo->prog->NumInstructions; - - inst = new_instruction(emitInfo, opcode); - if (!inst) { - return NULL; - } - inst = new_instruction(emitInfo, OPCODE_ENDIF); - if (!inst) { - return NULL; - } - - emitInfo->prog->Instructions[ifInstLoc].BranchTarget - = emitInfo->prog->NumInstructions - 1; - return inst; - } - } - else { - const GLuint condWritemask = inst->DstReg.WriteMask; - assert(emitInfo->EmitCondCodes); - inst = new_instruction(emitInfo, OPCODE_BRA); - if (inst) { - inst->DstReg.CondMask = COND_NE; - inst->DstReg.CondSwizzle = writemask_to_swizzle(condWritemask); - } - return inst; - } -} - - -/** - * Return the size of a swizzle mask given that some swizzle components - * may be NIL/undefined. For example: - * swizzle_size(".zzxx") = 4 - * swizzle_size(".xy??") = 2 - * swizzle_size(".w???") = 1 - */ -static GLuint -swizzle_size(GLuint swizzle) -{ - GLuint i; - for (i = 0; i < 4; i++) { - if (GET_SWZ(swizzle, i) == SWIZZLE_NIL) - return i; - } - return 4; -} - - -static struct prog_instruction * -emit_swizzle(slang_emit_info *emitInfo, slang_ir_node *n) -{ - struct prog_instruction *inst; - - inst = emit(emitInfo, n->Children[0]); - - if (!n->Store->Parent) { - /* this covers a case such as "(b ? p : q).x" */ - n->Store->Parent = n->Children[0]->Store; - assert(n->Store->Parent); - } - - { - const GLuint swizzle = n->Store->Swizzle; - /* new storage is parent storage with updated Swizzle + Size fields */ - _slang_copy_ir_storage(n->Store, n->Store->Parent); - /* Apply this node's swizzle to parent's storage */ - n->Store->Swizzle = _slang_swizzle_swizzle(n->Store->Swizzle, swizzle); - /* Update size */ - n->Store->Size = swizzle_size(n->Store->Swizzle); - } - - assert(!n->Store->Parent); - assert(n->Store->Index >= 0); - - return inst; -} - - -/** - * Dereference array element: element == array[index] - * This basically involves emitting code for computing the array index - * and updating the node/element's storage info. - */ -static struct prog_instruction * -emit_array_element(slang_emit_info *emitInfo, slang_ir_node *n) -{ - slang_ir_storage *arrayStore, *indexStore; - const int elemSize = n->Store->Size; /* number of floats */ - const GLint elemSizeVec = (elemSize + 3) / 4; /* number of vec4 */ - struct prog_instruction *inst; - - assert(n->Opcode == IR_ELEMENT); - assert(elemSize > 0); - - /* special case for built-in state variables, like light state */ - { - slang_ir_storage *root = n->Store; - assert(!root->Parent); - while (root->Parent) - root = root->Parent; - - if (root->File == PROGRAM_STATE_VAR) { - GLboolean direct; - GLint index = - _slang_alloc_statevar(n, emitInfo->prog->Parameters, &direct); - if (index < 0) { - /* error */ - return NULL; - } - if (direct) { - n->Store->Index = index; - return NULL; /* all done */ - } - } - } - - /* do codegen for array itself */ - emit(emitInfo, n->Children[0]); - arrayStore = n->Children[0]->Store; - - /* The initial array element storage is the array's storage, - * then modified below. - */ - _slang_copy_ir_storage(n->Store, arrayStore); - - - if (n->Children[1]->Opcode == IR_FLOAT) { - /* Constant array index */ - const GLint element = (GLint) n->Children[1]->Value[0]; - - /* this element's storage is the array's storage, plus constant offset */ - n->Store->Index += elemSizeVec * element; - } - else { - /* Variable array index */ - - /* do codegen for array index expression */ - emit(emitInfo, n->Children[1]); - indexStore = n->Children[1]->Store; - - if (indexStore->IsIndirect) { - /* need to put the array index into a temporary since we can't - * directly support a[b[i]] constructs. - */ - - - /*indexStore = tempstore();*/ - } - - - if (elemSize > 4) { - /* need to multiply array index by array element size */ - struct prog_instruction *inst; - slang_ir_storage *indexTemp; - slang_ir_storage elemSizeStore; - - /* allocate 1 float indexTemp */ - indexTemp = _slang_new_ir_storage(PROGRAM_TEMPORARY, -1, 1); - _slang_alloc_temp(emitInfo->vt, indexTemp); - - /* allocate a constant containing the element size */ - constant_to_storage(emitInfo, (float) elemSizeVec, &elemSizeStore); - - /* multiply array index by element size */ - inst = emit_instruction(emitInfo, - OPCODE_MUL, - indexTemp, /* dest */ - indexStore, /* the index */ - &elemSizeStore, - NULL); - if (!inst) { - return NULL; - } - - indexStore = indexTemp; - } - - if (arrayStore->IsIndirect) { - /* ex: in a[i][j], a[i] (the arrayStore) is indirect */ - /* Need to add indexStore to arrayStore->Indirect store */ - slang_ir_storage indirectArray; - slang_ir_storage *indexTemp; - - _slang_init_ir_storage(&indirectArray, - arrayStore->IndirectFile, - arrayStore->IndirectIndex, - 1, - arrayStore->IndirectSwizzle); - - /* allocate 1 float indexTemp */ - indexTemp = _slang_new_ir_storage(PROGRAM_TEMPORARY, -1, 1); - _slang_alloc_temp(emitInfo->vt, indexTemp); - - inst = emit_instruction(emitInfo, - OPCODE_ADD, - indexTemp, /* dest */ - indexStore, /* the index */ - &indirectArray, /* indirect array base */ - NULL); - if (!inst) { - return NULL; - } - - indexStore = indexTemp; - } - - /* update the array element storage info */ - n->Store->IsIndirect = GL_TRUE; - n->Store->IndirectFile = indexStore->File; - n->Store->IndirectIndex = indexStore->Index; - n->Store->IndirectSwizzle = indexStore->Swizzle; - } - - n->Store->Size = elemSize; - n->Store->Swizzle = _slang_var_swizzle(elemSize, 0); - - 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) -{ - slang_ir_storage *root = n->Store; - GLint fieldOffset, fieldSize; - - assert(n->Opcode == IR_FIELD); - - assert(!root->Parent); - while (root->Parent) - root = root->Parent; - - /* If this is the field of a state var, allocate constant/uniform - * storage for it now if we haven't already. - * Note that we allocate storage (uniform/constant slots) for state - * variables here rather than at declaration time so we only allocate - * space for the ones that we actually use! - */ - if (root->File == PROGRAM_STATE_VAR) { - GLboolean direct; - GLint index = _slang_alloc_statevar(n, emitInfo->prog->Parameters, &direct); - if (index < 0) { - slang_info_log_error(emitInfo->log, "Error parsing state variable"); - return NULL; - } - if (direct) { - root->Index = index; - return NULL; /* all done */ - } - } - - /* do codegen for struct */ - emit(emitInfo, n->Children[0]); - assert(n->Children[0]->Store->Index >= 0); - - - fieldOffset = n->Store->Index; - fieldSize = n->Store->Size; - - _slang_copy_ir_storage(n->Store, n->Children[0]->Store); - - n->Store->Index = n->Children[0]->Store->Index + fieldOffset / 4; - n->Store->Size = fieldSize; - - switch (fieldSize) { - case 1: - { - GLint swz = fieldOffset % 4; - n->Store->Swizzle = MAKE_SWIZZLE4(swz, swz, swz, swz); - } - break; - case 2: - n->Store->Swizzle = MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_Y, - SWIZZLE_NIL, SWIZZLE_NIL); - break; - case 3: - n->Store->Swizzle = MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_Y, - SWIZZLE_Z, SWIZZLE_NIL); - break; - default: - n->Store->Swizzle = SWIZZLE_XYZW; - } - - assert(n->Store->Index >= 0); - - return NULL; /* no instruction */ -} - - -/** - * Emit code for a variable declaration. - * This usually doesn't result in any code generation, but just - * memory allocation. - */ -static struct prog_instruction * -emit_var_decl(slang_emit_info *emitInfo, slang_ir_node *n) -{ - 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->store == 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); - emit_comment(emitInfo, s); - } - return NULL; -} - - -/** - * Emit code for a reference to a variable. - * Actually, no code is generated but we may do some memory allocation. - * In particular, state vars (uniforms) are allocated on an as-needed basis. - */ -static struct prog_instruction * -emit_var_ref(slang_emit_info *emitInfo, slang_ir_node *n) -{ - assert(n->Store); - assert(n->Store->File != PROGRAM_UNDEFINED); - - if (n->Store->File == PROGRAM_STATE_VAR && n->Store->Index < 0) { - GLboolean direct; - GLint index = _slang_alloc_statevar(n, emitInfo->prog->Parameters, &direct); - if (index < 0) { - /* error */ - char s[100]; - /* XXX isn't this really an out of memory/resources error? */ - _mesa_snprintf(s, sizeof(s), "Undefined variable '%s'", - (char *) n->Var->a_name); - slang_info_log_error(emitInfo->log, s); - return NULL; - } - - n->Store->Index = index; - } - else if (n->Store->File == PROGRAM_UNIFORM || - n->Store->File == PROGRAM_SAMPLER) { - /* mark var as used */ - _mesa_use_uniform(emitInfo->prog->Parameters, (char *) n->Var->a_name); - } - else if (n->Store->File == PROGRAM_INPUT) { - assert(n->Store->Index >= 0); - emitInfo->prog->InputsRead |= (1 << n->Store->Index); - } - - if (n->Store->Index < 0) { - /* probably ran out of registers */ - return NULL; - } - assert(n->Store->Size > 0); - - return NULL; -} - - -static struct prog_instruction * -emit(slang_emit_info *emitInfo, slang_ir_node *n) -{ - struct prog_instruction *inst; - if (!n) - return NULL; - - if (emitInfo->log->error_flag) { - return NULL; - } - - if (n->Comment) { - inst = new_instruction(emitInfo, OPCODE_NOP); - if (inst) { - inst->Comment = _mesa_strdup(n->Comment); - } - inst = 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]); - if (emitInfo->log->error_flag) - return NULL; - 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 */ - inst = emit_var_decl(emitInfo, n); - return inst; - - case IR_VAR: - /* Reference to a variable - * Storage should have already been resolved/allocated. - */ - return emit_var_ref(emitInfo, n); - - 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); - - /* Simple arithmetic */ - /* unary */ - case IR_MOVE: - case IR_RSQ: - case IR_RCP: - case IR_FLOOR: - case IR_FRAC: - case IR_F_TO_I: - case IR_I_TO_F: - case IR_ABS: - case IR_SIN: - case IR_COS: - case IR_DDX: - case IR_DDY: - case IR_EXP: - case IR_EXP2: - case IR_LOG2: - case IR_NOISE1: - case IR_NOISE2: - case IR_NOISE3: - case IR_NOISE4: - case IR_NRM4: - case IR_NRM3: - /* binary */ - case IR_ADD: - case IR_SUB: - case IR_MUL: - case IR_DOT4: - case IR_DOT3: - case IR_DOT2: - 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: - /* trinary operators */ - case IR_LRP: - case IR_CMP: - 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: - case IR_TEX_SH: - case IR_TEXB_SH: - case IR_TEXP_SH: - 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_COPY: - return emit_copy(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_KILL: - return emit_kill(emitInfo); - - case IR_CALL: - /* new variable scope for subroutines/function calls */ - _slang_push_var_table(emitInfo->vt); - inst = emit_fcall(emitInfo, n); - _slang_pop_var_table(emitInfo->vt); - return inst; - - case IR_IF: - return emit_if(emitInfo, n); - - case IR_LOOP: - return emit_loop(emitInfo, n); - case IR_BREAK_IF_TRUE: - case IR_CONT_IF_TRUE: - return emit_cont_break_if_true(emitInfo, n); - 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 emit_return(emitInfo, n); - - case IR_NOP: - return NULL; - - default: - _mesa_problem(NULL, "Unexpected IR opcode in emit()\n"); - } - return NULL; -} - - -/** - * After code generation, any subroutines will be in separate program - * objects. This function appends all the subroutines onto the main - * program and resolves the linking of all the branch/call instructions. - * XXX this logic should really be part of the linking process... - */ -static void -_slang_resolve_subroutines(slang_emit_info *emitInfo) -{ - GET_CURRENT_CONTEXT(ctx); - struct gl_program *mainP = emitInfo->prog; - GLuint *subroutineLoc, i, total; - - subroutineLoc - = (GLuint *) malloc(emitInfo->NumSubroutines * sizeof(GLuint)); - - /* total number of instructions */ - total = mainP->NumInstructions; - for (i = 0; i < emitInfo->NumSubroutines; i++) { - subroutineLoc[i] = total; - total += emitInfo->Subroutines[i]->NumInstructions; - } - - /* adjust BranchTargets within the functions */ - for (i = 0; i < emitInfo->NumSubroutines; i++) { - struct gl_program *sub = emitInfo->Subroutines[i]; - GLuint j; - for (j = 0; j < sub->NumInstructions; j++) { - struct prog_instruction *inst = sub->Instructions + j; - if (inst->Opcode != OPCODE_CAL && inst->BranchTarget >= 0) { - inst->BranchTarget += subroutineLoc[i]; - } - } - } - - /* append subroutines' instructions after main's instructions */ - mainP->Instructions = _mesa_realloc_instructions(mainP->Instructions, - mainP->NumInstructions, - total); - mainP->NumInstructions = total; - for (i = 0; i < emitInfo->NumSubroutines; i++) { - struct gl_program *sub = emitInfo->Subroutines[i]; - _mesa_copy_instructions(mainP->Instructions + subroutineLoc[i], - sub->Instructions, - sub->NumInstructions); - /* delete subroutine code */ - sub->Parameters = NULL; /* prevent double-free */ - _mesa_reference_program(ctx, &emitInfo->Subroutines[i], NULL); - } - - /* free subroutine list */ - if (emitInfo->Subroutines) { - free(emitInfo->Subroutines); - emitInfo->Subroutines = NULL; - } - emitInfo->NumSubroutines = 0; - - /* Examine CAL instructions. - * At this point, the BranchTarget field of the CAL instruction is - * the number/id of the subroutine to call (an index into the - * emitInfo->Subroutines list). - * Translate that into an actual instruction location now. - */ - for (i = 0; i < mainP->NumInstructions; i++) { - struct prog_instruction *inst = mainP->Instructions + i; - if (inst->Opcode == OPCODE_CAL) { - const GLuint f = inst->BranchTarget; - inst->BranchTarget = subroutineLoc[f]; - } - } - - free(subroutineLoc); -} - - - -/** - * Convert the IR tree into GPU instructions. - * \param n root of IR tree - * \param vt variable table - * \param prog program to put GPU instructions into - * \param pragmas controls codegen options - * \param withEnd if true, emit END opcode at end - * \param log log for emitting errors/warnings/info - */ -GLboolean -_slang_emit_code(slang_ir_node *n, slang_var_table *vt, - struct gl_program *prog, - const struct gl_sl_pragmas *pragmas, - GLboolean withEnd, - slang_info_log *log) -{ - GET_CURRENT_CONTEXT(ctx); - GLboolean success; - slang_emit_info emitInfo; - GLuint maxUniforms; - - emitInfo.log = log; - emitInfo.vt = vt; - emitInfo.prog = prog; - emitInfo.Subroutines = NULL; - emitInfo.NumSubroutines = 0; - emitInfo.MaxInstructions = prog->NumInstructions; - - emitInfo.EmitHighLevelInstructions = ctx->Shader.EmitHighLevelInstructions; - emitInfo.EmitCondCodes = ctx->Shader.EmitCondCodes; - emitInfo.EmitComments = ctx->Shader.EmitComments || pragmas->Debug; - emitInfo.EmitBeginEndSub = GL_TRUE; - - if (!emitInfo.EmitCondCodes) { - emitInfo.EmitHighLevelInstructions = GL_TRUE; - } - - /* Check uniform/constant limits */ - if (prog->Target == GL_FRAGMENT_PROGRAM_ARB) { - maxUniforms = ctx->Const.FragmentProgram.MaxUniformComponents / 4; - } - else { - assert(prog->Target == GL_VERTEX_PROGRAM_ARB); - maxUniforms = ctx->Const.VertexProgram.MaxUniformComponents / 4; - } - if (prog->Parameters->NumParameters > maxUniforms) { - slang_info_log_error(log, "Constant/uniform register limit exceeded " - "(max=%u vec4)", maxUniforms); - - return GL_FALSE; - } - - (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); - if (!inst) { - return GL_FALSE; - } - } - - _slang_resolve_subroutines(&emitInfo); - - 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/mesalib/src/mesa/shader/slang/slang_emit.h b/mesalib/src/mesa/shader/slang/slang_emit.h deleted file mode 100644 index ab4c202d6..000000000 --- a/mesalib/src/mesa/shader/slang/slang_emit.h +++ /dev/null @@ -1,51 +0,0 @@ -/* - * Mesa 3-D graphics library - * Version: 7.1 - * - * Copyright (C) 2005-2008 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 "main/imports.h" -#include "slang_compile.h" -#include "slang_ir.h" -#include "main/mtypes.h" - - -extern GLuint -_slang_swizzle_swizzle(GLuint swz1, GLuint swz2); - - -extern GLuint -_slang_var_swizzle(GLint size, GLint comp); - - -extern GLboolean -_slang_emit_code(slang_ir_node *n, slang_var_table *vartable, - struct gl_program *prog, - const struct gl_sl_pragmas *pragmas, - GLboolean withEnd, - slang_info_log *log); - - -#endif /* SLANG_EMIT_H */ diff --git a/mesalib/src/mesa/shader/slang/slang_ir.c b/mesalib/src/mesa/shader/slang/slang_ir.c deleted file mode 100644 index 62603503d..000000000 --- a/mesalib/src/mesa/shader/slang/slang_ir.c +++ /dev/null @@ -1,498 +0,0 @@ -/* - * Mesa 3-D graphics library - * - * Copyright (C) 2005-2008 Brian Paul All Rights Reserved. - * Copyright (C) 2009 VMware, 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. - */ - - -#include "main/imports.h" -#include "main/context.h" -#include "slang_ir.h" -#include "slang_mem.h" -#include "shader/prog_instruction.h" -#include "shader/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_DOT4", OPCODE_DP4, 1, 2 }, - { IR_DOT3, "IR_DOT3", OPCODE_DP3, 1, 2 }, - { IR_DOT2, "IR_DOT2", OPCODE_DP2, 1, 2 }, - { IR_NRM4, "IR_NRM4", OPCODE_NRM4, 1, 1 }, - { IR_NRM3, "IR_NRM3", OPCODE_NRM3, 1, 1 }, - { 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 }, - { IR_EQUAL, "IR_EQUAL", OPCODE_NOP, 1, 2 }, - { IR_NOTEQUAL, "IR_NOTEQUAL", OPCODE_NOP, 1, 2 }, - - /* unary ops */ - { IR_MOVE, "IR_MOVE", OPCODE_MOV, 4, 1 }, - { IR_I_TO_F, "IR_I_TO_F", OPCODE_MOV, 4, 1 }, /* int[4] to float[4] */ - { IR_F_TO_I, "IR_F_TO_I", OPCODE_TRUNC, 4, 1 }, - { 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_DDY, "IR_DDY", OPCODE_DDY, 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_CMP, "IR_CMP", OPCODE_CMP, 4, 3 }, /* compare/select */ - { 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_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_COPY, "IR_COPY", 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_TEX_SH, "IR_TEX_SH", OPCODE_TEX, 4, 1 }, - { IR_TEXB_SH, "IR_TEXB_SH", OPCODE_TXB, 4, 1 }, - { IR_TEXP_SH, "IR_TEXP_SH", 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, "IR_NOP", OPCODE_NOP, 0, 0 }, - { 0, NULL, 0, 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; -} - - -void -_slang_init_ir_storage(slang_ir_storage *st, - gl_register_file file, GLint index, GLint size, - GLuint swizzle) -{ - st->File = file; - st->Index = index; - st->Size = size; - st->Swizzle = swizzle; - st->Parent = NULL; - st->IsIndirect = GL_FALSE; -} - - -/** - * Return a new slang_ir_storage object. - */ -slang_ir_storage * -_slang_new_ir_storage(gl_register_file file, GLint index, GLint size) -{ - slang_ir_storage *st; - st = (slang_ir_storage *) _slang_alloc(sizeof(slang_ir_storage)); - if (st) { - st->File = file; - st->Index = index; - st->Size = size; - st->Swizzle = SWIZZLE_NOOP; - st->Parent = NULL; - st->IsIndirect = GL_FALSE; - } - return st; -} - - -/** - * Return a new slang_ir_storage object. - */ -slang_ir_storage * -_slang_new_ir_storage_swz(gl_register_file file, GLint index, GLint size, - GLuint swizzle) -{ - slang_ir_storage *st; - st = (slang_ir_storage *) _slang_alloc(sizeof(slang_ir_storage)); - if (st) { - st->File = file; - st->Index = index; - st->Size = size; - st->Swizzle = swizzle; - st->Parent = NULL; - st->IsIndirect = GL_FALSE; - } - return st; -} - - -/** - * Return a new slang_ir_storage object. - */ -slang_ir_storage * -_slang_new_ir_storage_relative(GLint index, GLint size, - slang_ir_storage *parent) -{ - slang_ir_storage *st; - st = (slang_ir_storage *) _slang_alloc(sizeof(slang_ir_storage)); - if (st) { - st->File = PROGRAM_UNDEFINED; - st->Index = index; - st->Size = size; - st->Swizzle = SWIZZLE_NOOP; - st->Parent = parent; - st->IsIndirect = GL_FALSE; - } - return st; -} - - -slang_ir_storage * -_slang_new_ir_storage_indirect(gl_register_file file, - GLint index, - GLint size, - gl_register_file indirectFile, - GLint indirectIndex, - GLuint indirectSwizzle) -{ - slang_ir_storage *st; - st = (slang_ir_storage *) _slang_alloc(sizeof(slang_ir_storage)); - if (st) { - st->File = file; - st->Index = index; - st->Size = size; - st->Swizzle = SWIZZLE_NOOP; - st->IsIndirect = GL_TRUE; - st->IndirectFile = indirectFile; - st->IndirectIndex = indirectIndex; - st->IndirectSwizzle = indirectSwizzle; - } - return st; -} - - -/** - * Allocate IR storage for a texture sampler. - * \param sampNum the sampler number/index - * \param texTarget one of TEXTURE_x_INDEX values - * \param size number of samplers (in case of sampler array) - */ -slang_ir_storage * -_slang_new_ir_storage_sampler(GLint sampNum, GLuint texTarget, GLint size) -{ - slang_ir_storage *st; - assert(texTarget < NUM_TEXTURE_TARGETS); - st = _slang_new_ir_storage(PROGRAM_SAMPLER, sampNum, size); - if (st) { - st->TexTarget = texTarget; - } - return st; -} - - - -/* XXX temporary function */ -void -_slang_copy_ir_storage(slang_ir_storage *dst, const slang_ir_storage *src) -{ - *dst = *src; - dst->Parent = NULL; -} - - - -static const char * -_slang_ir_name(slang_ir_opcode opcode) -{ - return _slang_ir_info(opcode)->IrName; -} - - - -#if 0 /* no longer needed with mempool */ -/** - * 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]); -} -#endif - - -static void -_slang_free_ir(slang_ir_node *n) -{ - GLuint i; - if (!n) - return; - -#if 0 - if (n->Store) { - n->Store->RefCount--; - if (n->Store->RefCount == 0) { - _slang_free(n->Store); - n->Store = NULL; - } - } -#endif - - for (i = 0; i < 3; i++) - _slang_free_ir(n->Children[i]); - /* Do not free n->List since it's a child elsewhere */ - _slang_free(n); -} - - -/** - * Recursively free an IR tree. - */ -void -_slang_free_ir_tree(slang_ir_node *n) -{ -#if 0 - _slang_refcount_storage(n); -#endif - _slang_free_ir(n); -} - - -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", - "VARYING", - "WRITE_ONLY", - "ADDRESS", - "SAMPLER", - "UNDEFINED" - }; - static char s[100]; - assert(Elements(files) == PROGRAM_FILE_MAX); -#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_COPY: - printf("COPY\n"); - _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_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 %s\n", n->Label->Name); - 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_TRUE: - printf("BREAK_IF_TRUE\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"), - _mesa_swizzle_string(n->Store->Swizzle, 0, 0), - 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", - _mesa_swizzle_string(n->Store->Swizzle, 0, 0), (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/mesalib/src/mesa/shader/slang/slang_ir.h b/mesalib/src/mesa/shader/slang/slang_ir.h deleted file mode 100644 index 166b4e804..000000000 --- a/mesalib/src/mesa/shader/slang/slang_ir.h +++ /dev/null @@ -1,280 +0,0 @@ -/* - * Mesa 3-D graphics library - * - * Copyright (C) 2005-2008 Brian Paul All Rights Reserved. - * Copyright (C) 2009 VMware, 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. - */ - -/** - * \file slang_ir.h - * Mesa GLSL Intermediate Representation tree types and constants. - * \author Brian Paul - */ - - -#ifndef SLANG_IR_H -#define SLANG_IR_H - - -#include "main/imports.h" -#include "slang_compile.h" -#include "slang_label.h" -#include "main/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_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, /**< Children[0] = the condition expression */ - IR_CONT_IF_TRUE, - - IR_COPY, /**< assignment/copy */ - IR_MOVE, /**< assembly MOV instruction */ - - /* vector ops: */ - IR_ADD, /**< assembly ADD instruction */ - IR_SUB, - IR_MUL, - IR_DIV, - IR_DOT4, - IR_DOT3, - IR_DOT2, - IR_NRM4, - IR_NRM3, - IR_CROSS, /* vec3 cross product */ - IR_LRP, - IR_CLAMP, - IR_MIN, - IR_MAX, - IR_CMP, /* = (op0 < 0) ? op1 : op2 */ - 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_TEX_SH, /* texture lookup, shadow compare */ - IR_TEXB_SH, /* texture lookup with LOD bias, shadow compare */ - IR_TEXP_SH, /* texture lookup with projection, shadow compare */ - - 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/variables are stored in the various register files. - * - * In the simple case, the File, Index and Size fields indicate where - * a variable is stored. For example, a vec3 variable may be stored - * as (File=PROGRAM_TEMPORARY, Index=6, Size=3). Or, File[Index]. - * Or, a program input like color may be stored as - * (File=PROGRAM_INPUT,Index=3,Size=4); - * - * For single-float values, the Swizzle field indicates which component - * of the vector contains the float. - * - * If IsIndirect is set, the storage is accessed through an indirect - * register lookup. The value in question will be located at: - * File[Index + IndirectFile[IndirectIndex]] - * - * This is primary used for indexing arrays. For example, consider this - * GLSL code: - * uniform int i; - * float a[10]; - * float x = a[i]; - * - * here, storage for a[i] would be described by (File=PROGRAM_TEMPORAY, - * Index=aPos, IndirectFile=PROGRAM_UNIFORM, IndirectIndex=iPos), which - * would mean TEMP[aPos + UNIFORM[iPos]] - */ -struct slang_ir_storage_ -{ - gl_register_file File; /**< PROGRAM_TEMPORARY, PROGRAM_INPUT, etc */ - GLint Index; /**< -1 means unallocated */ - GLint Size; /**< number of floats or ints */ - GLuint Swizzle; /**< Swizzle AND writemask info */ - GLint RefCount; /**< Used during IR tree delete */ - - GLboolean RelAddr; /* we'll remove this eventually */ - - GLboolean IsIndirect; - gl_register_file IndirectFile; - GLint IndirectIndex; - GLuint IndirectSwizzle; - GLuint TexTarget; /**< If File==PROGRAM_SAMPLER, one of TEXTURE_x_INDEX */ - - /** If Parent is non-null, Index is relative to parent. - * The other fields are ignored. - */ - struct slang_ir_storage_ *Parent; -}; - -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 */ - 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 */ - const char *Comment; /**< If Opcode == IR_COMMENT */ -} 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_init_ir_storage(slang_ir_storage *st, - gl_register_file file, GLint index, GLint size, - GLuint swizzle); - -extern slang_ir_storage * -_slang_new_ir_storage(gl_register_file file, GLint index, GLint size); - - -extern slang_ir_storage * -_slang_new_ir_storage_swz(gl_register_file file, GLint index, GLint size, - GLuint swizzle); - -extern slang_ir_storage * -_slang_new_ir_storage_relative(GLint index, GLint size, - slang_ir_storage *parent); - - -extern slang_ir_storage * -_slang_new_ir_storage_indirect(gl_register_file file, - GLint index, - GLint size, - gl_register_file indirectFile, - GLint indirectIndex, - GLuint indirectSwizzle); - -extern slang_ir_storage * -_slang_new_ir_storage_sampler(GLint sampNum, GLuint texTarget, GLint size); - - -extern void -_slang_copy_ir_storage(slang_ir_storage *dst, const slang_ir_storage *src); - - -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/mesalib/src/mesa/shader/slang/slang_label.c b/mesalib/src/mesa/shader/slang/slang_label.c deleted file mode 100644 index 225612a93..000000000 --- a/mesalib/src/mesa/shader/slang/slang_label.c +++ /dev/null @@ -1,104 +0,0 @@ - - -/** - * 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" -#include "slang_mem.h" - - - -slang_label * -_slang_label_new(const char *name) -{ - slang_label *l = (slang_label *) _slang_alloc(sizeof(slang_label)); - if (l) { - l->Name = _slang_strdup(name); - l->Location = -1; - } - return l; -} - -/** - * As above, but suffix the name with a unique number. - */ -slang_label * -_slang_label_new_unique(const char *name) -{ - static int id = 1; - slang_label *l = (slang_label *) _slang_alloc(sizeof(slang_label)); - if (l) { - l->Name = (char *) _slang_alloc(strlen(name) + 10); - if (!l->Name) { - free(l); - return NULL; - } - sprintf(l->Name, "%s_%d", name, id); - id++; - l->Location = -1; - } - return l; -} - -void -_slang_label_delete(slang_label *l) -{ - if (l->Name) { - _slang_free(l->Name); - l->Name = NULL; - } - if (l->References) { - _slang_free(l->References); - l->References = NULL; - } - _slang_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 = _slang_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) { - _slang_free(l->References); - l->References = NULL; - } -} diff --git a/mesalib/src/mesa/shader/slang/slang_label.h b/mesalib/src/mesa/shader/slang/slang_label.h deleted file mode 100644 index 87068ae7a..000000000 --- a/mesalib/src/mesa/shader/slang/slang_label.h +++ /dev/null @@ -1,45 +0,0 @@ -#ifndef SLANG_LABEL_H -#define SLANG_LABEL_H 1 - -#include "main/imports.h" -#include "main/mtypes.h" -#include "shader/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 slang_label * -_slang_label_new_unique(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/mesalib/src/mesa/shader/slang/slang_link.c b/mesalib/src/mesa/shader/slang/slang_link.c deleted file mode 100644 index e8dca0142..000000000 --- a/mesalib/src/mesa/shader/slang/slang_link.c +++ /dev/null @@ -1,933 +0,0 @@ -/* - * Mesa 3-D graphics library - * Version: 7.3 - * - * Copyright (C) 2008 Brian Paul All Rights Reserved. - * Copyright (C) 2009 VMware, 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. - */ - -/** - * \file slang_link.c - * GLSL linker - * \author Brian Paul - */ - -#include "main/imports.h" -#include "main/context.h" -#include "main/macros.h" -#include "shader/program.h" -#include "shader/prog_instruction.h" -#include "shader/prog_parameter.h" -#include "shader/prog_print.h" -#include "shader/prog_statevars.h" -#include "shader/prog_uniform.h" -#include "shader/shader_api.h" -#include "slang_builtin.h" -#include "slang_link.h" - - -/** cast wrapper */ -static struct gl_vertex_program * -vertex_program(struct gl_program *prog) -{ - assert(prog->Target == GL_VERTEX_PROGRAM_ARB); - return (struct gl_vertex_program *) prog; -} - - -/** cast wrapper */ -static struct gl_fragment_program * -fragment_program(struct gl_program *prog) -{ - assert(prog->Target == GL_FRAGMENT_PROGRAM_ARB); - return (struct gl_fragment_program *) prog; -} - - -/** - * Record a linking error. - */ -static void -link_error(struct gl_shader_program *shProg, const char *msg) -{ - if (shProg->InfoLog) { - free(shProg->InfoLog); - } - shProg->InfoLog = _mesa_strdup(msg); - shProg->LinkStatus = GL_FALSE; -} - - - -/** - * Check if the given bit is either set or clear in both bitfields. - */ -static GLboolean -bits_agree(GLbitfield flags1, GLbitfield flags2, GLbitfield bit) -{ - return (flags1 & bit) == (flags2 & bit); -} - - -/** - * Linking varying vars involves rearranging varying vars so that the - * vertex program's output varyings matches the order of the fragment - * program's input varyings. - * We'll then rewrite instructions to replace PROGRAM_VARYING with either - * PROGRAM_INPUT or PROGRAM_OUTPUT depending on whether it's a vertex or - * fragment shader. - * This is also where we set program Input/OutputFlags to indicate - * which inputs are centroid-sampled, invariant, etc. - */ -static GLboolean -link_varying_vars(GLcontext *ctx, - struct gl_shader_program *shProg, struct gl_program *prog) -{ - GLuint *map, i, firstVarying, newFile; - GLbitfield *inOutFlags; - - map = (GLuint *) malloc(prog->Varying->NumParameters * sizeof(GLuint)); - if (!map) - 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; - inOutFlags = prog->OutputFlags; - } - else { - assert(prog->Target == GL_FRAGMENT_PROGRAM_ARB); - firstVarying = FRAG_ATTRIB_VAR0; - newFile = PROGRAM_INPUT; - inOutFlags = prog->InputFlags; - } - - 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; - GLint j = _mesa_lookup_parameter_index(shProg->Varying, -1, var->Name); - if (j >= 0) { - /* varying is already in list, do some error checking */ - const struct gl_program_parameter *v = - &shProg->Varying->Parameters[j]; - if (var->Size != v->Size) { - link_error(shProg, "mismatched varying variable types"); - free(map); - return GL_FALSE; - } - if (!bits_agree(var->Flags, v->Flags, PROG_PARAM_BIT_CENTROID)) { - char msg[100]; - _mesa_snprintf(msg, sizeof(msg), - "centroid modifier mismatch for '%s'", var->Name); - link_error(shProg, msg); - free(map); - return GL_FALSE; - } - if (!bits_agree(var->Flags, v->Flags, PROG_PARAM_BIT_INVARIANT)) { - char msg[100]; - _mesa_snprintf(msg, sizeof(msg), - "invariant modifier mismatch for '%s'", var->Name); - link_error(shProg, msg); - free(map); - return GL_FALSE; - } - } - else { - /* not already in linked list */ - j = _mesa_add_varying(shProg->Varying, var->Name, var->Size, - var->Flags); - } - - if (shProg->Varying->NumParameters > ctx->Const.MaxVarying) { - link_error(shProg, "Too many varying variables"); - free(map); - return GL_FALSE; - } - - /* Map varying[i] to varying[j]. - * Note: the loop here takes care of arrays or large (sz>4) vars. - */ - { - GLint sz = var->Size; - while (sz > 0) { - inOutFlags[firstVarying + j] = var->Flags; - /*printf("Link varying from %d to %d\n", i, j);*/ - map[i++] = j++; - sz -= 4; - } - i--; /* go back one */ - } - } - - - /* 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; - - if (inst->DstReg.File == PROGRAM_VARYING) { - inst->DstReg.File = newFile; - inst->DstReg.Index = map[ inst->DstReg.Index ] + firstVarying; - } - - 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; - } - } - } - - free(map); - - /* these will get recomputed before linking is completed */ - prog->InputsRead = 0x0; - prog->OutputsWritten = 0x0; - - return GL_TRUE; -} - - -/** - * Build the shProg->Uniforms list. - * This is basically a list/index of all uniforms found in either/both of - * the vertex and fragment shaders. - * - * About uniforms: - * Each uniform has two indexes, one that points into the vertex - * program's parameter array and another that points into the fragment - * program's parameter array. When the user changes a uniform's value - * we have to change the value in the vertex and/or fragment program's - * parameter array. - * - * This function will be called twice to set up the two uniform->parameter - * mappings. - * - * If a uniform is only present in the vertex program OR fragment program - * then the fragment/vertex parameter index, respectively, will be -1. - */ -static GLboolean -link_uniform_vars(GLcontext *ctx, - struct gl_shader_program *shProg, - struct gl_program *prog, - GLuint *numSamplers) -{ - GLuint samplerMap[200]; /* max number of samplers declared, not used */ - GLuint i; - - for (i = 0; i < prog->Parameters->NumParameters; i++) { - const struct gl_program_parameter *p = prog->Parameters->Parameters + i; - - /* - * XXX FIX NEEDED HERE - * We should also be adding a uniform if p->Type == PROGRAM_STATE_VAR. - * For example, modelview matrix, light pos, etc. - * Also, we need to update the state-var name-generator code to - * generate GLSL-style names, like "gl_LightSource[0].position". - * Furthermore, we'll need to fix the state-var's size/datatype info. - */ - - if ((p->Type == PROGRAM_UNIFORM || p->Type == PROGRAM_SAMPLER) - && p->Used) { - /* add this uniform, indexing into the target's Parameters list */ - struct gl_uniform *uniform = - _mesa_append_uniform(shProg->Uniforms, p->Name, prog->Target, i); - if (uniform) - uniform->Initialized = p->Initialized; - } - - /* The samplerMap[] table we build here is used to remap/re-index - * sampler references by TEX instructions. - */ - if (p->Type == PROGRAM_SAMPLER && p->Used) { - /* Allocate a new sampler index */ - GLuint oldSampNum = (GLuint) prog->Parameters->ParameterValues[i][0]; - GLuint newSampNum = *numSamplers; - if (newSampNum >= ctx->Const.MaxTextureImageUnits) { - char s[100]; - sprintf(s, "Too many texture samplers (%u, max is %u)", - newSampNum, ctx->Const.MaxTextureImageUnits); - link_error(shProg, s); - return GL_FALSE; - } - /* save old->new mapping in the table */ - if (oldSampNum < Elements(samplerMap)) - samplerMap[oldSampNum] = newSampNum; - /* update parameter's sampler index */ - prog->Parameters->ParameterValues[i][0] = (GLfloat) newSampNum; - (*numSamplers)++; - } - } - - /* OK, now scan the program/shader instructions looking for texture - * instructions using sampler vars. Replace old sampler indexes with - * new ones. - */ - prog->SamplersUsed = 0x0; - for (i = 0; i < prog->NumInstructions; i++) { - struct prog_instruction *inst = prog->Instructions + i; - if (_mesa_is_tex_instruction(inst->Opcode)) { - /* here, inst->TexSrcUnit is really the sampler unit */ - const GLint oldSampNum = inst->TexSrcUnit; - -#if 0 - printf("====== remap sampler from %d to %d\n", - inst->TexSrcUnit, samplerMap[ inst->TexSrcUnit ]); -#endif - - if (oldSampNum < Elements(samplerMap)) { - const GLuint newSampNum = samplerMap[oldSampNum]; - inst->TexSrcUnit = newSampNum; - prog->SamplerTargets[newSampNum] = inst->TexSrcTarget; - prog->SamplersUsed |= (1 << newSampNum); - if (inst->TexShadow) { - prog->ShadowSamplers |= (1 << newSampNum); - } - } - } - } - - return GL_TRUE; -} - - -/** - * 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. - * But if the user called glBindAttributeLocation(), those bindings will - * have priority. - */ -static GLboolean -_slang_resolve_attributes(struct gl_shader_program *shProg, - const struct gl_program *origProg, - struct gl_program *linkedProg) -{ - GLint attribMap[MAX_VERTEX_GENERIC_ATTRIBS]; - GLuint i, j; - GLbitfield usedAttributes; /* generics only, not legacy attributes */ - GLbitfield inputsRead = 0x0; - - assert(origProg != linkedProg); - assert(origProg->Target == GL_VERTEX_PROGRAM_ARB); - assert(linkedProg->Target == GL_VERTEX_PROGRAM_ARB); - - if (!shProg->Attributes) - shProg->Attributes = _mesa_new_parameter_list(); - - if (linkedProg->Attributes) { - _mesa_free_parameter_list(linkedProg->Attributes); - } - linkedProg->Attributes = _mesa_new_parameter_list(); - - - /* 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 |= (1 << attr); - } - - /* If gl_Vertex is used, that actually counts against the limit - * on generic vertex attributes. This avoids the ambiguity of - * whether glVertexAttrib4fv(0, v) sets legacy attribute 0 (vert pos) - * or generic attribute[0]. If gl_Vertex is used, we want the former. - */ - if (origProg->InputsRead & VERT_BIT_POS) { - usedAttributes |= 0x1; - } - - /* initialize the generic attribute map entries to -1 */ - for (i = 0; i < MAX_VERTEX_GENERIC_ATTRIBS; i++) { - attribMap[i] = -1; - } - - /* - * Scan program for generic attribute references - */ - for (i = 0; i < linkedProg->NumInstructions; i++) { - struct prog_instruction *inst = linkedProg->Instructions + i; - for (j = 0; j < 3; j++) { - if (inst->SrcReg[j].File == PROGRAM_INPUT) { - inputsRead |= (1 << inst->SrcReg[j].Index); - } - - if (inst->SrcReg[j].File == PROGRAM_INPUT && - inst->SrcReg[j].Index >= VERT_ATTRIB_GENERIC0) { - /* - * OK, we've found a generic vertex attribute reference. - */ - const GLint k = inst->SrcReg[j].Index - VERT_ATTRIB_GENERIC0; - - GLint attr = attribMap[k]; - - if (attr < 0) { - /* Need to figure out attribute mapping now. - */ - const char *name = origProg->Attributes->Parameters[k].Name; - const GLint size = origProg->Attributes->Parameters[k].Size; - const GLenum type =origProg->Attributes->Parameters[k].DataType; - GLint index; - - /* See if there's a user-defined attribute binding for - * this name. - */ - index = _mesa_lookup_parameter_index(shProg->Attributes, - -1, name); - if (index >= 0) { - /* Found a user-defined binding */ - attr = shProg->Attributes->Parameters[index].StateIndexes[0]; - } - else { - /* No user-defined binding, choose our own attribute number. - * Start at 1 since generic attribute 0 always aliases - * glVertex/position. - */ - for (attr = 0; attr < MAX_VERTEX_GENERIC_ATTRIBS; attr++) { - if (((1 << attr) & usedAttributes) == 0) - break; - } - if (attr == MAX_VERTEX_GENERIC_ATTRIBS) { - link_error(shProg, "Too many vertex attributes"); - return GL_FALSE; - } - - /* mark this attribute as used */ - usedAttributes |= (1 << attr); - } - - attribMap[k] = attr; - - /* Save the final name->attrib binding so it can be queried - * with glGetAttributeLocation(). - */ - _mesa_add_attribute(linkedProg->Attributes, name, - size, type, attr); - } - - assert(attr >= 0); - - /* update the instruction's src reg */ - inst->SrcReg[j].Index = VERT_ATTRIB_GENERIC0 + attr; - } - } - } - - /* Handle pre-defined attributes here (gl_Vertex, gl_Normal, etc). - * When the user queries the active attributes we need to include both - * the user-defined attributes and the built-in ones. - */ - for (i = VERT_ATTRIB_POS; i < VERT_ATTRIB_GENERIC0; i++) { - if (inputsRead & (1 << i)) { - _mesa_add_attribute(linkedProg->Attributes, - _slang_vert_attrib_name(i), - 4, /* size in floats */ - _slang_vert_attrib_type(i), - -1 /* attrib/input */); - } - } - - return GL_TRUE; -} - - -/** - * Scan program instructions to update the program's NumTemporaries field. - * Note: this implemenation relies on the code generator allocating - * temps in increasing order (0, 1, 2, ... ). - */ -static void -_slang_count_temporaries(struct gl_program *prog) -{ - GLuint i, j; - GLint maxIndex = -1; - - 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_TEMPORARY) { - if (maxIndex < inst->SrcReg[j].Index) - maxIndex = inst->SrcReg[j].Index; - } - if (inst->DstReg.File == PROGRAM_TEMPORARY) { - if (maxIndex < (GLint) inst->DstReg.Index) - maxIndex = inst->DstReg.Index; - } - } - } - - prog->NumTemporaries = (GLuint) (maxIndex + 1); -} - - -/** - * Scan program instructions to update the program's InputsRead and - * OutputsWritten fields. - */ -static void -_slang_update_inputs_outputs(struct gl_program *prog) -{ - GLuint i, j; - GLuint maxAddrReg = 0; - - prog->InputsRead = 0x0; - prog->OutputsWritten = 0x0; - - 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; - } - else if (inst->SrcReg[j].File == PROGRAM_ADDRESS) { - maxAddrReg = MAX2(maxAddrReg, (GLuint) (inst->SrcReg[j].Index + 1)); - } - } - - if (inst->DstReg.File == PROGRAM_OUTPUT) { - prog->OutputsWritten |= BITFIELD64_BIT(inst->DstReg.Index); - if (inst->DstReg.RelAddr) { - /* If the output attribute is indexed with relative addressing - * we know that it must be a varying or texcoord such as - * gl_TexCoord[i] = v; In this case, mark all the texcoords - * or varying outputs as being written. It's not an error if - * a vertex shader writes varying vars that aren't used by the - * fragment shader. But it is an error for a fragment shader - * to use varyings that are not written by the vertex shader. - */ - if (prog->Target == GL_VERTEX_PROGRAM_ARB) { - if (inst->DstReg.Index == VERT_RESULT_TEX0) { - /* mark all texcoord outputs as written */ - const GLbitfield64 mask = - BITFIELD64_RANGE(VERT_RESULT_TEX0, - (VERT_RESULT_TEX0 - + MAX_TEXTURE_COORD_UNITS - 1)); - prog->OutputsWritten |= mask; - } - else if (inst->DstReg.Index == VERT_RESULT_VAR0) { - /* mark all generic varying outputs as written */ - const GLbitfield64 mask = - BITFIELD64_RANGE(VERT_RESULT_VAR0, - (VERT_RESULT_VAR0 + MAX_VARYING - 1)); - prog->OutputsWritten |= mask; - } - } - } - } - else if (inst->DstReg.File == PROGRAM_ADDRESS) { - maxAddrReg = MAX2(maxAddrReg, inst->DstReg.Index + 1); - } - } - prog->NumAddressRegs = maxAddrReg; -} - - - -/** - * Remove extra #version directives from the concatenated source string. - * Disable the extra ones by converting first two chars to //, a comment. - * This is a bit of hack to work around a preprocessor bug that only - * allows one #version directive per source. - */ -static void -remove_extra_version_directives(GLchar *source) -{ - GLuint verCount = 0; - while (1) { - char *ver = strstr(source, "#version"); - if (ver) { - verCount++; - if (verCount > 1) { - ver[0] = '/'; - ver[1] = '/'; - } - source += 8; - } - else { - break; - } - } -} - - - -/** - * Return a new shader whose source code is the concatenation of - * all the shader sources of the given type. - */ -static struct gl_shader * -concat_shaders(struct gl_shader_program *shProg, GLenum shaderType) -{ - struct gl_shader *newShader; - const struct gl_shader *firstShader = NULL; - GLuint *shaderLengths; - GLchar *source; - GLuint totalLen = 0, len = 0; - GLuint i; - - shaderLengths = (GLuint *)malloc(shProg->NumShaders * sizeof(GLuint)); - if (!shaderLengths) { - return NULL; - } - - /* compute total size of new shader source code */ - for (i = 0; i < shProg->NumShaders; i++) { - const struct gl_shader *shader = shProg->Shaders[i]; - if (shader->Type == shaderType) { - shaderLengths[i] = strlen(shader->Source); - totalLen += shaderLengths[i]; - if (!firstShader) - firstShader = shader; - } - } - - if (totalLen == 0) { - free(shaderLengths); - return NULL; - } - - source = (GLchar *) malloc(totalLen + 1); - if (!source) { - free(shaderLengths); - return NULL; - } - - /* concatenate shaders */ - for (i = 0; i < shProg->NumShaders; i++) { - const struct gl_shader *shader = shProg->Shaders[i]; - if (shader->Type == shaderType) { - memcpy(source + len, shader->Source, shaderLengths[i]); - len += shaderLengths[i]; - } - } - source[len] = '\0'; - /* - printf("---NEW CONCATENATED SHADER---:\n%s\n------------\n", source); - */ - - free(shaderLengths); - - remove_extra_version_directives(source); - - newShader = CALLOC_STRUCT(gl_shader); - if (!newShader) { - free(source); - return NULL; - } - - newShader->Type = shaderType; - newShader->Source = source; - newShader->Pragmas = firstShader->Pragmas; - - return newShader; -} - - -/** - * Search the shader program's list of shaders to find the one that - * defines main(). - * This will involve shader concatenation and recompilation if needed. - */ -static struct gl_shader * -get_main_shader(GLcontext *ctx, - struct gl_shader_program *shProg, GLenum type) -{ - struct gl_shader *shader = NULL; - GLuint i; - - /* - * Look for a shader that defines main() and has no unresolved references. - */ - for (i = 0; i < shProg->NumShaders; i++) { - shader = shProg->Shaders[i]; - if (shader->Type == type && - shader->Main && - !shader->UnresolvedRefs) { - /* All set! */ - return shader; - } - } - - /* - * There must have been unresolved references during the original - * compilation. Try concatenating all the shaders of the given type - * and recompile that. - */ - shader = concat_shaders(shProg, type); - - if (shader) { - _slang_compile(ctx, shader); - - /* Finally, check if recompiling failed */ - if (!shader->CompileStatus || - !shader->Main || - shader->UnresolvedRefs) { - link_error(shProg, "Unresolved symbols"); - _mesa_free_shader(ctx, shader); - return NULL; - } - } - - return shader; -} - - -/** - * 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. The vertex and fragment programs are cloned and modified to update - * src/dst register references so they use the new, linked varying - * storage locations. - */ -void -_slang_link(GLcontext *ctx, - GLhandleARB programObj, - struct gl_shader_program *shProg) -{ - const struct gl_vertex_program *vertProg = NULL; - const struct gl_fragment_program *fragProg = NULL; - GLboolean vertNotify = GL_TRUE, fragNotify = GL_TRUE; - GLuint numSamplers = 0; - GLuint i; - - _mesa_clear_shader_program_data(ctx, shProg); - - /* Initialize LinkStatus to "success". Will be cleared if error. */ - shProg->LinkStatus = GL_TRUE; - - /* check that all programs compiled successfully */ - for (i = 0; i < shProg->NumShaders; i++) { - if (!shProg->Shaders[i]->CompileStatus) { - link_error(shProg, "linking with uncompiled shader\n"); - return; - } - } - - shProg->Uniforms = _mesa_new_uniform_list(); - shProg->Varying = _mesa_new_parameter_list(); - - /* - * Find the vertex and fragment shaders which define main() - */ - { - struct gl_shader *vertShader, *fragShader; - vertShader = get_main_shader(ctx, shProg, GL_VERTEX_SHADER); - fragShader = get_main_shader(ctx, shProg, GL_FRAGMENT_SHADER); - if (vertShader) - vertProg = vertex_program(vertShader->Program); - if (fragShader) - fragProg = fragment_program(fragShader->Program); - if (!shProg->LinkStatus) - return; - } - -#if FEATURE_es2_glsl - /* must have both a vertex and fragment program for ES2 */ - if (!vertProg) { - link_error(shProg, "missing vertex shader\n"); - return; - } - if (!fragProg) { - link_error(shProg, "missing fragment shader\n"); - return; - } -#endif - - /* - * Make copies of the vertex/fragment programs now since we'll be - * changing src/dst registers after merging the uniforms and varying vars. - */ - _mesa_reference_vertprog(ctx, &shProg->VertexProgram, NULL); - if (vertProg) { - struct gl_vertex_program *linked_vprog = - _mesa_clone_vertex_program(ctx, vertProg); - shProg->VertexProgram = linked_vprog; /* refcount OK */ - /* vertex program ID not significant; just set Id for debugging purposes */ - shProg->VertexProgram->Base.Id = shProg->Name; - ASSERT(shProg->VertexProgram->Base.RefCount == 1); - } - - _mesa_reference_fragprog(ctx, &shProg->FragmentProgram, NULL); - if (fragProg) { - struct gl_fragment_program *linked_fprog = - _mesa_clone_fragment_program(ctx, fragProg); - shProg->FragmentProgram = linked_fprog; /* refcount OK */ - /* vertex program ID not significant; just set Id for debugging purposes */ - shProg->FragmentProgram->Base.Id = shProg->Name; - ASSERT(shProg->FragmentProgram->Base.RefCount == 1); - } - - /* link varying vars */ - if (shProg->VertexProgram) { - if (!link_varying_vars(ctx, shProg, &shProg->VertexProgram->Base)) - return; - } - if (shProg->FragmentProgram) { - if (!link_varying_vars(ctx, shProg, &shProg->FragmentProgram->Base)) - return; - } - - /* link uniform vars */ - if (shProg->VertexProgram) { - if (!link_uniform_vars(ctx, shProg, &shProg->VertexProgram->Base, - &numSamplers)) { - return; - } - } - if (shProg->FragmentProgram) { - if (!link_uniform_vars(ctx, shProg, &shProg->FragmentProgram->Base, - &numSamplers)) { - return; - } - } - - /*_mesa_print_uniforms(shProg->Uniforms);*/ - - if (shProg->VertexProgram) { - if (!_slang_resolve_attributes(shProg, &vertProg->Base, - &shProg->VertexProgram->Base)) { - return; - } - } - - if (shProg->VertexProgram) { - _slang_update_inputs_outputs(&shProg->VertexProgram->Base); - _slang_count_temporaries(&shProg->VertexProgram->Base); - if (!(shProg->VertexProgram->Base.OutputsWritten - & BITFIELD64_BIT(VERT_RESULT_HPOS))) { - /* the vertex program did not compute a vertex position */ - link_error(shProg, - "gl_Position was not written by vertex shader\n"); - return; - } - } - if (shProg->FragmentProgram) { - _slang_count_temporaries(&shProg->FragmentProgram->Base); - _slang_update_inputs_outputs(&shProg->FragmentProgram->Base); - } - - /* Check that all the varying vars needed by the fragment shader are - * actually produced by the vertex shader. - */ - if (shProg->FragmentProgram) { - const GLbitfield varyingRead - = shProg->FragmentProgram->Base.InputsRead >> FRAG_ATTRIB_VAR0; - const GLbitfield64 varyingWritten = shProg->VertexProgram ? - shProg->VertexProgram->Base.OutputsWritten >> VERT_RESULT_VAR0 : 0x0; - if ((varyingRead & varyingWritten) != varyingRead) { - link_error(shProg, - "Fragment program using varying vars not written by vertex shader\n"); - return; - } - } - - /* check that gl_FragColor and gl_FragData are not both written to */ - if (shProg->FragmentProgram) { - const GLbitfield64 outputsWritten = - shProg->FragmentProgram->Base.OutputsWritten; - if ((outputsWritten & BITFIELD64_BIT(FRAG_RESULT_COLOR)) && - (outputsWritten >= BITFIELD64_BIT(FRAG_RESULT_DATA0))) { - link_error(shProg, "Fragment program cannot write both gl_FragColor" - " and gl_FragData[].\n"); - return; - } - } - - - if (fragProg && shProg->FragmentProgram) { - /* Compute initial program's TexturesUsed info */ - _mesa_update_shader_textures_used(&shProg->FragmentProgram->Base); - - /* notify driver that a new fragment program has been compiled/linked */ - vertNotify = ctx->Driver.ProgramStringNotify(ctx, GL_FRAGMENT_PROGRAM_ARB, - &shProg->FragmentProgram->Base); - if (ctx->Shader.Flags & GLSL_DUMP) { - printf("Mesa pre-link fragment program:\n"); - _mesa_print_program(&fragProg->Base); - _mesa_print_program_parameters(ctx, &fragProg->Base); - - printf("Mesa post-link fragment program:\n"); - _mesa_print_program(&shProg->FragmentProgram->Base); - _mesa_print_program_parameters(ctx, &shProg->FragmentProgram->Base); - } - } - - if (vertProg && shProg->VertexProgram) { - /* Compute initial program's TexturesUsed info */ - _mesa_update_shader_textures_used(&shProg->VertexProgram->Base); - - /* notify driver that a new vertex program has been compiled/linked */ - fragNotify = ctx->Driver.ProgramStringNotify(ctx, GL_VERTEX_PROGRAM_ARB, - &shProg->VertexProgram->Base); - if (ctx->Shader.Flags & GLSL_DUMP) { - printf("Mesa pre-link vertex program:\n"); - _mesa_print_program(&vertProg->Base); - _mesa_print_program_parameters(ctx, &vertProg->Base); - - printf("Mesa post-link vertex program:\n"); - _mesa_print_program(&shProg->VertexProgram->Base); - _mesa_print_program_parameters(ctx, &shProg->VertexProgram->Base); - } - } - - /* Debug: */ - if (0) { - if (shProg->VertexProgram) - _mesa_postprocess_program(ctx, &shProg->VertexProgram->Base); - if (shProg->FragmentProgram) - _mesa_postprocess_program(ctx, &shProg->FragmentProgram->Base); - } - - if (ctx->Shader.Flags & GLSL_DUMP) { - printf("Varying vars:\n"); - _mesa_print_parameter_list(shProg->Varying); - if (shProg->InfoLog) { - printf("Info Log: %s\n", shProg->InfoLog); - } - } - - if (!vertNotify || !fragNotify) { - /* driver rejected one/both of the vertex/fragment programs */ - if (!shProg->InfoLog) { - link_error(shProg, - "Vertex and/or fragment program rejected by driver\n"); - } - } - else { - shProg->LinkStatus = (shProg->VertexProgram || shProg->FragmentProgram); - } -} - diff --git a/mesalib/src/mesa/shader/slang/slang_link.h b/mesalib/src/mesa/shader/slang/slang_link.h deleted file mode 100644 index 2b44d2078..000000000 --- a/mesalib/src/mesa/shader/slang/slang_link.h +++ /dev/null @@ -1,37 +0,0 @@ -/* - * Mesa 3-D graphics library - * Version: 7.2 - * - * Copyright (C) 2008 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_LINK_H -#define SLANG_LINK_H 1 - -#include "slang_compile.h" - - -extern void -_slang_link(GLcontext *ctx, GLhandleARB h, - struct gl_shader_program *shProg); - - -#endif - diff --git a/mesalib/src/mesa/shader/slang/slang_log.c b/mesalib/src/mesa/shader/slang/slang_log.c deleted file mode 100644 index 9ff21417b..000000000 --- a/mesalib/src/mesa/shader/slang/slang_log.c +++ /dev/null @@ -1,133 +0,0 @@ -/* - * Mesa 3-D graphics library - * Version: 7.3 - * - * Copyright (C) 2005-2007 Brian Paul All Rights Reserved. - * Copyright (C) 2009 VMware, 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. - */ - -#include "main/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) - 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 *) - _mesa_realloc(log->text, old_len + 1, old_len + size); - } - else { - log->text = (char *) (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); - 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); - 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); - 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/mesalib/src/mesa/shader/slang/slang_log.h b/mesalib/src/mesa/shader/slang/slang_log.h deleted file mode 100644 index dcaba0285..000000000 --- a/mesalib/src/mesa/shader/slang/slang_log.h +++ /dev/null @@ -1,57 +0,0 @@ -/* - * 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_LOG_H -#define SLANG_LOG_H - - -typedef struct slang_info_log_ -{ - char *text; - GLboolean dont_free_text; - GLboolean error_flag; -} slang_info_log; - - -extern void -slang_info_log_construct(slang_info_log *); - -extern void -slang_info_log_destruct(slang_info_log *); - -extern int -slang_info_log_print(slang_info_log *, const char *, ...); - -extern int -slang_info_log_error(slang_info_log *, const char *, ...); - -extern int -slang_info_log_warning(slang_info_log *, const char *, ...); - -extern void -slang_info_log_memory(slang_info_log *); - - -#endif /* SLANG_LOG_H */ diff --git a/mesalib/src/mesa/shader/slang/slang_mem.c b/mesalib/src/mesa/shader/slang/slang_mem.c deleted file mode 100644 index 5eaa7c442..000000000 --- a/mesalib/src/mesa/shader/slang/slang_mem.c +++ /dev/null @@ -1,243 +0,0 @@ -/* - * 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_mem.c - * - * Memory manager for GLSL compiler. The general idea is to do all - * allocations out of a large pool then just free the pool when done - * compiling to avoid intricate malloc/free tracking and memory leaks. - * - * \author Brian Paul - */ - -#include "main/context.h" -#include "main/macros.h" -#include "slang_mem.h" - - -#define GRANULARITY 8 -#define ROUND_UP(B) ( ((B) + (GRANULARITY - 1)) & ~(GRANULARITY - 1) ) - - -/** If 1, use conventional malloc/free. Helpful for debugging */ -#define USE_MALLOC_FREE 0 - - -struct slang_mempool_ -{ - GLuint Size, Used, Count, Largest; - char *Data; - struct slang_mempool_ *Next; -}; - - -slang_mempool * -_slang_new_mempool(GLuint initialSize) -{ - slang_mempool *pool = (slang_mempool *) calloc(1, sizeof(slang_mempool)); - if (pool) { - pool->Data = (char *) calloc(1, initialSize); - /*printf("ALLOC MEMPOOL %d at %p\n", initialSize, pool->Data);*/ - if (!pool->Data) { - free(pool); - return NULL; - } - pool->Size = initialSize; - pool->Used = 0; - } - return pool; -} - - -void -_slang_delete_mempool(slang_mempool *pool) -{ - GLuint total = 0; - while (pool) { - slang_mempool *next = pool->Next; - /* - printf("DELETE MEMPOOL %u / %u count=%u largest=%u\n", - pool->Used, pool->Size, pool->Count, pool->Largest); - */ - total += pool->Used; - free(pool->Data); - free(pool); - pool = next; - } - /*printf("TOTAL ALLOCATED: %u\n", total);*/ -} - - -#ifdef DEBUG -static void -check_zero(const char *addr, GLuint n) -{ - GLuint i; - for (i = 0; i < n; i++) { - assert(addr[i]==0); - } -} -#endif - - -#ifdef DEBUG -static GLboolean -is_valid_address(const slang_mempool *pool, void *addr) -{ - while (pool) { - if ((char *) addr >= pool->Data && - (char *) addr < pool->Data + pool->Used) - return GL_TRUE; - - pool = pool->Next; - } - return GL_FALSE; -} -#endif - - -/** - * Alloc 'bytes' from shader mempool. - */ -void * -_slang_alloc(GLuint bytes) -{ -#if USE_MALLOC_FREE - return calloc(1, bytes); -#else - slang_mempool *pool; - GET_CURRENT_CONTEXT(ctx); - pool = (slang_mempool *) ctx->Shader.MemPool; - - if (bytes == 0) - bytes = 1; - - while (pool) { - if (pool->Used + bytes <= pool->Size) { - /* found room */ - void *addr = (void *) (pool->Data + pool->Used); -#ifdef DEBUG - check_zero((char*) addr, bytes); -#endif - pool->Used += ROUND_UP(bytes); - pool->Largest = MAX2(pool->Largest, bytes); - pool->Count++; - /*printf("alloc %u Used %u\n", bytes, pool->Used);*/ - return addr; - } - else if (pool->Next) { - /* try next block */ - pool = pool->Next; - } - else { - /* alloc new pool */ - const GLuint sz = MAX2(bytes, pool->Size); - pool->Next = _slang_new_mempool(sz); - if (!pool->Next) { - /* we're _really_ out of memory */ - return NULL; - } - else { - pool = pool->Next; - pool->Largest = bytes; - pool->Count++; - pool->Used = ROUND_UP(bytes); -#ifdef DEBUG - check_zero((char*) pool->Data, bytes); -#endif - return (void *) pool->Data; - } - } - } - return NULL; -#endif -} - - -void * -_slang_realloc(void *oldBuffer, GLuint oldSize, GLuint newSize) -{ -#if USE_MALLOC_FREE - return _mesa_realloc(oldBuffer, oldSize, newSize); -#else - GET_CURRENT_CONTEXT(ctx); - slang_mempool *pool = (slang_mempool *) ctx->Shader.MemPool; - (void) pool; - - if (newSize < oldSize) { - return oldBuffer; - } - else { - const GLuint copySize = (oldSize < newSize) ? oldSize : newSize; - void *newBuffer = _slang_alloc(newSize); - - if (oldBuffer) - ASSERT(is_valid_address(pool, oldBuffer)); - - if (newBuffer && oldBuffer && copySize > 0) - memcpy(newBuffer, oldBuffer, copySize); - - return newBuffer; - } -#endif -} - - -/** - * Clone string, storing in current mempool. - */ -char * -_slang_strdup(const char *s) -{ - if (s) { - size_t l = strlen(s); - char *s2 = (char *) _slang_alloc(l + 1); - if (s2) - strcpy(s2, s); - return s2; - } - else { - return NULL; - } -} - - -/** - * Don't actually free memory, but mark it (for debugging). - */ -void -_slang_free(void *addr) -{ -#if USE_MALLOC_FREE - free(addr); -#else - if (addr) { - GET_CURRENT_CONTEXT(ctx); - slang_mempool *pool = (slang_mempool *) ctx->Shader.MemPool; - (void) pool; - ASSERT(is_valid_address(pool, addr)); - } -#endif -} diff --git a/mesalib/src/mesa/shader/slang/slang_mem.h b/mesalib/src/mesa/shader/slang/slang_mem.h deleted file mode 100644 index b5bfae247..000000000 --- a/mesalib/src/mesa/shader/slang/slang_mem.h +++ /dev/null @@ -1,55 +0,0 @@ -/* - * 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_MEM_H -#define SLANG_MEM_H - - -#include "main/imports.h" - - -typedef struct slang_mempool_ slang_mempool; - - -extern slang_mempool * -_slang_new_mempool(GLuint initialSize); - -extern void -_slang_delete_mempool(slang_mempool *pool); - -extern void * -_slang_alloc(GLuint bytes); - -extern void * -_slang_realloc(void *oldBuffer, GLuint oldSize, GLuint newSize); - -extern char * -_slang_strdup(const char *s); - -extern void -_slang_free(void *addr); - - -#endif diff --git a/mesalib/src/mesa/shader/slang/slang_print.c b/mesalib/src/mesa/shader/slang/slang_print.c deleted file mode 100644 index 3c75523c4..000000000 --- a/mesalib/src/mesa/shader/slang/slang_print.c +++ /dev/null @@ -1,883 +0,0 @@ - -/** - * Dump/print a slang_operation tree - */ - - -#include "main/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_MAT23: - printf("mat2x3"); - break; - case SLANG_SPEC_MAT32: - printf("mat3x2"); - break; - case SLANG_SPEC_MAT24: - printf("mat2x4"); - break; - case SLANG_SPEC_MAT42: - printf("mat4x2"); - break; - case SLANG_SPEC_MAT34: - printf("mat3x4"); - break; - case SLANG_SPEC_MAT43: - printf("mat4x3"); - break; - case SLANG_SPEC_SAMPLER_1D: - printf("sampler1D"); - break; - case SLANG_SPEC_SAMPLER_2D: - printf("sampler2D"); - break; - case SLANG_SPEC_SAMPLER_3D: - printf("sampler3D"); - break; - case SLANG_SPEC_SAMPLER_CUBE: - printf("samplerCube"); - break; - case SLANG_SPEC_SAMPLER_1D_SHADOW: - printf("sampler1DShadow"); - break; - case SLANG_SPEC_SAMPLER_2D_SHADOW: - 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 (at %p)", (char *) v->a_name, (void *) v); - 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); -#if 0 - printf("binary at %p locals=%p outer=%p\n", - (void *) op, - (void *) op->locals, - (void *) op->locals->outer_scope); -#endif - slang_print_tree(&op->children[0], indent + 3); - spaces(indent); - printf("%s at %p locals=%p outer=%p\n", - oper, (void *) op, (void *) op->locals, - (void *) op->locals->outer_scope); - slang_print_tree(&op->children[1], indent + 3); -} - - -static void -print_generic2(const slang_operation *op, const char *oper, - const char *s, int indent) -{ - GLuint i; - if (oper) { - spaces(indent); - printf("%s %s at %p locals=%p outer=%p\n", - oper, s, (void *) op, (void *) op->locals, - (void *) op->locals->outer_scope); - } - for (i = 0; i < op->num_children; i++) { - spaces(indent); - printf("//child %u of %u:\n", i, op->num_children); - 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) -{ - GLuint 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: - case SLANG_OPER_NON_INLINED_CALL: - spaces(indent); - printf("{{ // new scope locals=%p outer=%p: ", - (void *) op->locals, - (void *) op->locals->outer_scope); - for (i = 0; i < op->locals->num_variables; i++) { - printf("%s ", (char *) op->locals->variables[i]->a_name); - } - printf("\n"); - 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_variable_locate(op->locals, op->a_id, GL_TRUE); - if (v) { - const slang_variable_scope *scope; - 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)); - - scope = find_scope(op->locals, op->a_id); - printf(" (in scope %p) ", (void *) scope); - assert(scope); - 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 { - spaces(indent); - printf("DECL %s (anonymous variable!!!!)\n", (char *) op->a_id); - } - } - break; - - case SLANG_OPER_ASM: - spaces(indent); - printf("ASM: %s at %p locals=%p outer=%p\n", - (char *) op->a_id, - (void *) op, - (void *) op->locals, - (void *) op->locals->outer_scope); - print_generic(op, "ASM", 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_RETURN_INLINED: - spaces(indent); - printf("RETURN_INLINED\n"); - if (op->num_children > 0) - slang_print_tree(&op->children[0], indent + 3); - 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 outer=%p\n", - (void *) op->locals, - (void *) op->locals->outer_scope); - /*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 LOOP: locals = %p\n", (void *) op->locals); - indent += 3; - 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); - indent -= 3; - spaces(indent); - printf("END WHILE LOOP\n"); - break; - - case SLANG_OPER_DO: - spaces(indent); - printf("DO LOOP: locals = %p\n", (void *) op->locals); - indent += 3; - 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); - indent -= 3; - spaces(indent); - printf("END DO LOOP\n"); - break; - - case SLANG_OPER_FOR: - spaces(indent); - printf("FOR LOOP: locals = %p\n", (void *) op->locals); - indent += 3; - spaces(indent); - printf("FOR init:\n"); - slang_print_tree(&op->children[0], indent + 3); - spaces(indent); - printf("FOR condition:\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); - 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: - { - const slang_variable_scope *scope; - spaces(indent); - if (op->var && op->var->a_name) { - scope = find_scope(op->locals, op->var->a_name); - printf("VAR %s (in scope %p)\n", (char *) op->var->a_name, - (void *) scope); - assert(scope); - } - else { - scope = find_scope(op->locals, op->a_id); - printf("VAR' %s (in scope %p) locals=%p outer=%p\n", - (char *) op->a_id, - (void *) scope, - (void *) op->locals, - (void *) op->locals->outer_scope); - /*assert(scope);*/ - } - } - break; - - case SLANG_OPER_SEQUENCE: - print_generic(op, "COMMA-SEQ", indent+3); - break; - - case SLANG_OPER_ASSIGN: - spaces(indent); - printf("ASSIGNMENT locals=%p outer=%p\n", - (void *) op->locals, - (void *) op->locals->outer_scope); - 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 locals=%p outer=%p\n", - (void *) op->locals, - (void *) op->locals->outer_scope); - print_generic(op, NULL, indent+3); - break; - - case SLANG_OPER_CALL: -#if 0 - slang_function *fun - = _slang_function_locate(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_METHOD: - spaces(indent); - printf("METHOD CALL %s.%s\n", (char *) op->a_obj, (char *) op->a_id); - 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) -{ - GLuint i; - -#if 0 - if (strcmp((char *) f->header.a_name, "main") != 0) - return; -#endif - - printf("FUNCTION %s ( scope=%p\n", - (char *) f->header.a_name, (void *) f->parameters); - - for (i = 0; i < f->param_count; i++) { - print_variable(f->parameters->variables[i], 3); - } - - printf(") param scope = %p\n", (void *) f->parameters); - - 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_SAMPLER_1D: - return "sampler1D"; - case SLANG_SPEC_SAMPLER_2D: - return "sampler2D"; - case SLANG_SPEC_SAMPLER_3D: - return "sampler3D"; - case SLANG_SPEC_SAMPLER_CUBE: - return "samplerCube"; - case SLANG_SPEC_SAMPLER_1D_SHADOW: - return "sampler1DShadow"; - case SLANG_SPEC_SAMPLER_2D_SHADOW: - return "sampler2DShadow"; - case SLANG_SPEC_SAMPLER_RECT: - return "sampler2DRect"; - case SLANG_SPEC_SAMPLER_RECT_SHADOW: - 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; - GLuint i; - - for (i = 0; i < op->num_children; i++) { - s += slang_checksum_tree(&op->children[i]); - } - return s; -} diff --git a/mesalib/src/mesa/shader/slang/slang_print.h b/mesalib/src/mesa/shader/slang/slang_print.h deleted file mode 100644 index 46605c806..000000000 --- a/mesalib/src/mesa/shader/slang/slang_print.h +++ /dev/null @@ -1,29 +0,0 @@ - - -#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/mesalib/src/mesa/shader/slang/slang_simplify.c b/mesalib/src/mesa/shader/slang/slang_simplify.c deleted file mode 100644 index 13b9ca3c8..000000000 --- a/mesalib/src/mesa/shader/slang/slang_simplify.c +++ /dev/null @@ -1,527 +0,0 @@ -/* - * Mesa 3-D graphics library - * Version: 7.1 - * - * Copyright (C) 2005-2008 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. - */ - -/** - * Functions for constant folding, built-in constant lookup, and function - * call casting. - */ - - -#include "main/imports.h" -#include "main/macros.h" -#include "main/get.h" -#include "slang_compile.h" -#include "slang_codegen.h" -#include "slang_simplify.h" -#include "slang_print.h" - - -#ifndef GL_MAX_FRAGMENT_UNIFORM_VECTORS -#define GL_MAX_FRAGMENT_UNIFORM_VECTORS 0x8DFD -#endif -#ifndef GL_MAX_VERTEX_UNIFORM_VECTORS -#define GL_MAX_VERTEX_UNIFORM_VECTORS 0x8DFB -#endif -#ifndef GL_MAX_VARYING_VECTORS -#define GL_MAX_VARYING_VECTORS 0x8DFC -#endif - - -/** - * 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 }, -#if FEATURE_es2_glsl - { "gl_MaxVertexUniformVectors", GL_MAX_VERTEX_UNIFORM_VECTORS }, - { "gl_MaxVaryingVectors", GL_MAX_VARYING_VECTORS }, - { "gl_MaxFragmentUniformVectors", GL_MAX_FRAGMENT_UNIFORM_VECTORS }, -#endif - { NULL, 0 } - }; - GLuint i; - - for (i = 0; info[i].Name; i++) { - if (strcmp(info[i].Name, name) == 0) { - /* found */ - GLint values[16]; - values[0] = -1; - _mesa_GetIntegerv(info[i].Token, values); - ASSERT(values[0] >= 0); /* sanity check that glGetFloatv worked */ - return values[0]; - } - } - return -1; -} - - -static slang_operation_type -literal_type(slang_operation_type t1, slang_operation_type t2) -{ - if (t1 == SLANG_OPER_LITERAL_FLOAT || t2 == SLANG_OPER_LITERAL_FLOAT) - return SLANG_OPER_LITERAL_FLOAT; - else - return SLANG_OPER_LITERAL_INT; -} - - -/** - * 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); - /*printf("value[%s] = %d\n", (char*) oper->a_id, value);*/ - if (value >= 0) { - oper->literal[0] = - oper->literal[1] = - oper->literal[2] = - oper->literal[3] = (GLfloat) value; - oper->type = SLANG_OPER_LITERAL_INT; - return; - } - /* look for user-defined constant */ - { - slang_variable *var; - var = _slang_variable_locate(oper->locals, oper->a_id, GL_TRUE); - if (var) { - if (var->type.qualifier == SLANG_QUAL_CONST && - var->initializer && - (var->initializer->type == SLANG_OPER_LITERAL_INT || - var->initializer->type == SLANG_OPER_LITERAL_FLOAT)) { - oper->literal[0] = var->initializer->literal[0]; - oper->literal[1] = var->initializer->literal[1]; - oper->literal[2] = var->initializer->literal[2]; - oper->literal[3] = var->initializer->literal[3]; - oper->literal_size = var->initializer->literal_size; - oper->type = var->initializer->type; - /* - printf("value[%s] = %f\n", - (char*) oper->a_id, oper->literal[0]); - */ - 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; - oper->type = literal_type(oper->children[0].type, - oper->children[1].type); - slang_operation_destruct(oper); /* frees unused children */ - 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; - oper->type = literal_type(oper->children[0].type, - oper->children[1].type); - slang_operation_destruct(oper); - 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; - oper->type = literal_type(oper->children[0].type, - oper->children[1].type); - slang_operation_destruct(oper); - 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; - oper->type = literal_type(oper->children[0].type, - oper->children[1].type); - slang_operation_destruct(oper); - 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; - } - } - } -} - - - -/** - * Insert casts to try to adapt actual parameters to formal parameters for a - * function call when an exact match for the parameter types is not found. - * Example: - * void foo(int i, bool b) {} - * x = foo(3.15, 9); - * Gets translated into: - * x = foo(int(3.15), bool(9)) - */ -GLboolean -_slang_cast_func_params(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 call of %d args to func %s (%d params)\n", - callOper->num_children, (char*) fun->header.a_name, numParams); - - 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); - - if (dbg) - printf("Need to adapt types of arg %d\n", i); - - slang_operation_copy(child, &callOper->children[i]); - child->locals->outer_scope = callOper->children[i].locals; - -#if 0 - if (_slang_sizeof_type_specifier(&argType.spec) > - _slang_sizeof_type_specifier(¶mVar->type.specifier)) { - } -#endif - - 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 cast arguments ===============\n", - (char*) fun->header.a_name); - slang_print_tree(callOper, 5); - } - - return GL_TRUE; -} - - -/** - * 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 for %s\n", - callOper->num_children, numParams, (char *) fun->header.a_name); - - /* 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 */ - - /* 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].locals = _slang_variable_scope_new(callOper->locals); - 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] = (GLfloat) j; - } - } - } - } - - if (callOper->num_children < (GLuint) numParams) { - /* still not enough args for all params */ - return GL_FALSE; - } - else if (callOper->num_children > (GLuint) numParams) { - /* now too many arguments */ - /* just truncate */ - callOper->num_children = (GLuint) numParams; - } - - 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/mesalib/src/mesa/shader/slang/slang_simplify.h b/mesalib/src/mesa/shader/slang/slang_simplify.h deleted file mode 100644 index 8689c23b1..000000000 --- a/mesalib/src/mesa/shader/slang/slang_simplify.h +++ /dev/null @@ -1,50 +0,0 @@ -/* - * Mesa 3-D graphics library - * Version: 7.1 - * - * Copyright (C) 2005-2008 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_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_cast_func_params(slang_operation *callOper, const slang_function *fun, - const slang_name_space * space, - slang_atom_pool * atoms, slang_info_log *log); - -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/mesalib/src/mesa/shader/slang/slang_storage.c b/mesalib/src/mesa/shader/slang/slang_storage.c deleted file mode 100644 index 656e15670..000000000 --- a/mesalib/src/mesa/shader/slang/slang_storage.c +++ /dev/null @@ -1,321 +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_storage.c - * slang variable storage - * \author Michal Krol - */ - -#include "main/imports.h" -#include "slang_storage.h" -#include "slang_mem.h" - -/* slang_storage_array */ - -GLboolean -slang_storage_array_construct(slang_storage_array * arr) -{ - arr->type = SLANG_STORE_AGGREGATE; - arr->aggregate = NULL; - arr->length = 0; - return GL_TRUE; -} - -GLvoid -slang_storage_array_destruct(slang_storage_array * arr) -{ - if (arr->aggregate != NULL) { - slang_storage_aggregate_destruct(arr->aggregate); - _slang_free(arr->aggregate); - } -} - -/* slang_storage_aggregate */ - -GLboolean -slang_storage_aggregate_construct(slang_storage_aggregate * agg) -{ - agg->arrays = NULL; - agg->count = 0; - return GL_TRUE; -} - -GLvoid -slang_storage_aggregate_destruct(slang_storage_aggregate * agg) -{ - GLuint i; - - for (i = 0; i < agg->count; i++) - slang_storage_array_destruct(agg->arrays + i); - _slang_free(agg->arrays); -} - -static slang_storage_array * -slang_storage_aggregate_push_new(slang_storage_aggregate * agg) -{ - slang_storage_array *arr = NULL; - - agg->arrays = (slang_storage_array *) - _slang_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) -{ - 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 columns, GLuint rows) -{ - slang_storage_array *arr = slang_storage_aggregate_push_new(agg); - if (arr == NULL) - return GL_FALSE; - arr->type = SLANG_STORE_AGGREGATE; - arr->length = columns; - arr->aggregate = (slang_storage_aggregate *) - _slang_alloc(sizeof(slang_storage_aggregate)); - if (arr->aggregate == NULL) - return GL_FALSE; - if (!slang_storage_aggregate_construct(arr->aggregate)) { - _slang_free(arr->aggregate); - arr->aggregate = NULL; - return GL_FALSE; - } - if (!aggregate_vector(arr->aggregate, basic_type, rows)) - 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_atom_pool * atoms) -{ - 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, atoms)) - 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_atom_pool * atoms) -{ - 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, 2); - case SLANG_SPEC_MAT3: - return aggregate_matrix(agg, SLANG_STORE_FLOAT, 3, 3); - case SLANG_SPEC_MAT4: - return aggregate_matrix(agg, SLANG_STORE_FLOAT, 4, 4); - - case SLANG_SPEC_MAT23: - return aggregate_matrix(agg, SLANG_STORE_FLOAT, 2, 3); - case SLANG_SPEC_MAT32: - return aggregate_matrix(agg, SLANG_STORE_FLOAT, 3, 2); - case SLANG_SPEC_MAT24: - return aggregate_matrix(agg, SLANG_STORE_FLOAT, 2, 4); - case SLANG_SPEC_MAT42: - return aggregate_matrix(agg, SLANG_STORE_FLOAT, 4, 2); - case SLANG_SPEC_MAT34: - return aggregate_matrix(agg, SLANG_STORE_FLOAT, 3, 4); - case SLANG_SPEC_MAT43: - return aggregate_matrix(agg, SLANG_STORE_FLOAT, 4, 3); - - case SLANG_SPEC_SAMPLER_1D: - case SLANG_SPEC_SAMPLER_2D: - case SLANG_SPEC_SAMPLER_3D: - case SLANG_SPEC_SAMPLER_CUBE: - case SLANG_SPEC_SAMPLER_1D_SHADOW: - case SLANG_SPEC_SAMPLER_2D_SHADOW: - case SLANG_SPEC_SAMPLER_RECT: - case SLANG_SPEC_SAMPLER_RECT_SHADOW: - case SLANG_SPEC_SAMPLER_1D_ARRAY: - case SLANG_SPEC_SAMPLER_2D_ARRAY: - case SLANG_SPEC_SAMPLER_1D_ARRAY_SHADOW: - case SLANG_SPEC_SAMPLER_2D_ARRAY_SHADOW: - - 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(sizeof(slang_storage_aggregate)); - if (arr->aggregate == NULL) - return GL_FALSE; - if (!slang_storage_aggregate_construct(arr->aggregate)) { - _slang_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; - } -} - - -GLuint -_slang_sizeof_type(slang_storage_type type) -{ - if (type == SLANG_STORE_AGGREGATE) - return 0; - if (type == SLANG_STORE_VEC4) - return 4 * sizeof(GLfloat); - return sizeof(GLfloat); -} - - -GLuint -_slang_sizeof_aggregate(const slang_storage_aggregate * agg) -{ - GLuint i, size = 0; - - for (i = 0; i < agg->count; i++) { - slang_storage_array *arr = &agg->arrays[i]; - GLuint element_size; - - if (arr->type == SLANG_STORE_AGGREGATE) - element_size = _slang_sizeof_aggregate(arr->aggregate); - else - element_size = _slang_sizeof_type(arr->type); - size += element_size * arr->length; - } - return size; -} - - -#if 0 -GLboolean -_slang_flatten_aggregate(slang_storage_aggregate * flat, - const slang_storage_aggregate * agg) -{ - GLuint i; - - for (i = 0; i < agg->count; i++) { - GLuint j; - - for (j = 0; j < agg->arrays[i].length; j++) { - 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_STORE_VEC4) { - count = 4; - type = SLANG_STORE_FLOAT; - } - else { - count = 1; - type = agg->arrays[i].type; - } - - for (k = 0; k < count; k++) { - slang_storage_array *arr; - - arr = slang_storage_aggregate_push_new(flat); - if (arr == NULL) - return GL_FALSE; - arr->type = type; - arr->length = 1; - } - } - } - } - return GL_TRUE; -} -#endif diff --git a/mesalib/src/mesa/shader/slang/slang_storage.h b/mesalib/src/mesa/shader/slang/slang_storage.h deleted file mode 100644 index 1876a36dd..000000000 --- a/mesalib/src/mesa/shader/slang/slang_storage.h +++ /dev/null @@ -1,139 +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. - */ - -#ifndef SLANG_STORAGE_H -#define SLANG_STORAGE_H - -#include "slang_compile.h" - - -/* - * 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. - * - * 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_STORE_AGGREGATE, - SLANG_STORE_BOOL, - SLANG_STORE_INT, - SLANG_STORE_FLOAT, - /* 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. - * - * 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; - 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. - */ -typedef struct slang_storage_aggregate_ -{ - 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, - GLuint array_len, - slang_function_scope *funcs, - slang_struct_scope *structs, - slang_variable_scope *vars, - slang_atom_pool *atoms); - -/* - * Returns the size (in machine units) of the given storage type. - * 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. - */ -extern GLuint -_slang_sizeof_aggregate (const slang_storage_aggregate *); - - -#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/mesalib/src/mesa/shader/slang/slang_typeinfo.c b/mesalib/src/mesa/shader/slang/slang_typeinfo.c deleted file mode 100644 index 0f96768b0..000000000 --- a/mesalib/src/mesa/shader/slang/slang_typeinfo.c +++ /dev/null @@ -1,1177 +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_typeinfo.c - * slang type info - * \author Michal Krol - */ - -#include "main/imports.h" -#include "shader/prog_instruction.h" -#include "slang_typeinfo.h" -#include "slang_compile.h" -#include "slang_log.h" -#include "slang_mem.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 - */ -static 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". - */ -static void -_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]]; -} - - -typedef struct -{ - const char *name; - slang_type_specifier_type type; -} 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}, - {"mat2x3", SLANG_SPEC_MAT23}, - {"mat3x2", SLANG_SPEC_MAT32}, - {"mat2x4", SLANG_SPEC_MAT24}, - {"mat4x2", SLANG_SPEC_MAT42}, - {"mat3x4", SLANG_SPEC_MAT34}, - {"mat4x3", SLANG_SPEC_MAT43}, - {"sampler1D", SLANG_SPEC_SAMPLER_1D}, - {"sampler2D", SLANG_SPEC_SAMPLER_2D}, - {"sampler3D", SLANG_SPEC_SAMPLER_3D}, - {"samplerCube", SLANG_SPEC_SAMPLER_CUBE}, - {"sampler1DShadow", SLANG_SPEC_SAMPLER_1D_SHADOW}, - {"sampler2DShadow", SLANG_SPEC_SAMPLER_2D_SHADOW}, - {"sampler2DRect", SLANG_SPEC_SAMPLER_RECT}, - {"sampler2DRectShadow", SLANG_SPEC_SAMPLER_RECT_SHADOW}, - {"sampler1DArray", SLANG_SPEC_SAMPLER_1D_ARRAY}, - {"sampler2DArray", SLANG_SPEC_SAMPLER_2D_ARRAY}, - {"sampler1DArrayShadow", SLANG_SPEC_SAMPLER_1D_ARRAY_SHADOW}, - {"sampler2DArrayShadow", SLANG_SPEC_SAMPLER_2D_ARRAY_SHADOW}, - {NULL, SLANG_SPEC_VOID} -}; - -slang_type_specifier_type -slang_type_specifier_type_from_string(const char *name) -{ - const type_specifier_type_name *p = type_specifier_type_names; - while (p->name != NULL) { - if (slang_string_compare(p->name, name) == 0) - break; - p++; - } - return p->type; -} - -const char * -slang_type_specifier_type_to_string(slang_type_specifier_type type) -{ - const type_specifier_type_name *p = type_specifier_type_names; - while (p->name != NULL) { - if (p->type == type) - break; - p++; - } - return p->name; -} - -/* slang_fully_specified_type */ - -int -slang_fully_specified_type_construct(slang_fully_specified_type * type) -{ - type->qualifier = SLANG_QUAL_NONE; - slang_type_specifier_ctr(&type->specifier); - return 1; -} - -void -slang_fully_specified_type_destruct(slang_fully_specified_type * type) -{ - slang_type_specifier_dtr(&type->specifier); -} - -int -slang_fully_specified_type_copy(slang_fully_specified_type * x, - const slang_fully_specified_type * y) -{ - slang_fully_specified_type z; - - if (!slang_fully_specified_type_construct(&z)) - return 0; - z.qualifier = y->qualifier; - z.precision = y->precision; - z.variant = y->variant; - z.centroid = y->centroid; - z.layout = y->layout; - z.array_len = y->array_len; - if (!slang_type_specifier_copy(&z.specifier, &y->specifier)) { - slang_fully_specified_type_destruct(&z); - return 0; - } - slang_fully_specified_type_destruct(x); - *x = z; - return 1; -} - - -/** - * Test if two fully specified types are compatible. This is a bit - * looser than testing for equality. We don't check the precision, - * variant, centroid, etc. information. - * XXX this may need some tweaking. - */ -GLboolean -slang_fully_specified_types_compatible(const slang_fully_specified_type * x, - const slang_fully_specified_type * y) -{ - if (!slang_type_specifier_equal(&x->specifier, &y->specifier)) - return GL_FALSE; - - if (x->qualifier == SLANG_QUAL_FIXEDINPUT && - y->qualifier == SLANG_QUAL_VARYING) - ; /* ok */ - else if (x->qualifier != y->qualifier) - return GL_FALSE; - - /* Note: don't compare precision, variant, centroid */ - - /* XXX array length? */ - - return GL_TRUE; -} - - -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_free(self->_struct); - } - if (self->_array != NULL) { - slang_type_specifier_dtr(self->_array); - _slang_free(self->_array); - } -} - -slang_type_specifier * -slang_type_specifier_new(slang_type_specifier_type type, - struct slang_struct_ *_struct, - struct slang_type_specifier_ *_array) -{ - slang_type_specifier *spec = - (slang_type_specifier *) _slang_alloc(sizeof(slang_type_specifier)); - if (spec) { - spec->type = type; - spec->_struct = _struct; - spec->_array = _array; - } - return spec; -} - -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(sizeof(slang_struct)); - if (z._struct == NULL) { - slang_type_specifier_dtr(&z); - return GL_FALSE; - } - if (!slang_struct_construct(z._struct)) { - _slang_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(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. - */ -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) -{ - memset(ti, 0, sizeof(*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) -{ - GLboolean error; - - *funFound = _slang_function_locate(space->funcs, a_name, params, - num_params, space, atoms, log, &error); - if (error) - return GL_FALSE; - - 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; - } -} - - -/** - * 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_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: - case SLANG_OPER_VARIABLE_DECL: - { - slang_variable *var; - var = _slang_variable_locate(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; - if (var->type.specifier.type == SLANG_SPEC_ARRAY && - var->type.array_len >= 1) { - /* the datatype is an array, ex: float[3] x; */ - ti->array_len = var->type.array_len; - } - else { - /* the variable is an array, ex: float x[3]; */ - 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->array_constructor) { - /* build array typeinfo */ - ti->spec.type = SLANG_SPEC_ARRAY; - ti->spec._array = (slang_type_specifier *) - _slang_alloc(sizeof(slang_type_specifier)); - slang_type_specifier_ctr(ti->spec._array); - - ti->spec._array->type = - slang_type_specifier_type_from_string((char *) op->a_id); - ti->array_len = op->num_children; - } - else 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(sizeof(slang_struct)); - if (ti->spec._struct == NULL) - return GL_FALSE; - if (!slang_struct_construct(ti->spec._struct)) { - _slang_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_METHOD: - /* at this time, GLSL 1.20 only has one method: array.length() - * which returns an integer. - */ - ti->spec.type = SLANG_SPEC_INT; - 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_variable_locate(_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; - ti->array_len = field->array_len; - } - 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; -} - - -/** - * 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: - case SLANG_SPEC_MAT23: - case SLANG_SPEC_MAT32: - case SLANG_SPEC_MAT24: - case SLANG_SPEC_MAT42: - case SLANG_SPEC_MAT34: - case SLANG_SPEC_MAT43: - 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; - } -} - - -/** - * Determine if a type is a float, float vector or float matrix. - * \return GL_TRUE if so, GL_FALSE otherwise - */ -GLboolean -_slang_type_is_float_vec_mat(slang_type_specifier_type ty) -{ - switch (ty) { - case SLANG_SPEC_FLOAT: - case SLANG_SPEC_VEC2: - case SLANG_SPEC_VEC3: - case SLANG_SPEC_VEC4: - case SLANG_SPEC_MAT2: - case SLANG_SPEC_MAT3: - case SLANG_SPEC_MAT4: - case SLANG_SPEC_MAT23: - case SLANG_SPEC_MAT32: - case SLANG_SPEC_MAT24: - case SLANG_SPEC_MAT42: - case SLANG_SPEC_MAT34: - case SLANG_SPEC_MAT43: - return GL_TRUE; - default: - return GL_FALSE; - } -} - - -/** - * Given a vector type, return the type of the vector's elements. - * For a matrix, return the type of the columns. - */ -slang_type_specifier_type -_slang_type_base(slang_type_specifier_type ty) -{ - switch (ty) { - case SLANG_SPEC_FLOAT: - case SLANG_SPEC_VEC2: - case SLANG_SPEC_VEC3: - case SLANG_SPEC_VEC4: - return SLANG_SPEC_FLOAT; - case SLANG_SPEC_INT: - case SLANG_SPEC_IVEC2: - case SLANG_SPEC_IVEC3: - case SLANG_SPEC_IVEC4: - return SLANG_SPEC_INT; - case SLANG_SPEC_BOOL: - case SLANG_SPEC_BVEC2: - case SLANG_SPEC_BVEC3: - case SLANG_SPEC_BVEC4: - return SLANG_SPEC_BOOL; - case SLANG_SPEC_MAT2: - return SLANG_SPEC_VEC2; - case SLANG_SPEC_MAT3: - return SLANG_SPEC_VEC3; - case SLANG_SPEC_MAT4: - return SLANG_SPEC_VEC4; - case SLANG_SPEC_MAT23: - return SLANG_SPEC_VEC3; - case SLANG_SPEC_MAT32: - return SLANG_SPEC_VEC2; - case SLANG_SPEC_MAT24: - return SLANG_SPEC_VEC4; - case SLANG_SPEC_MAT42: - return SLANG_SPEC_VEC2; - case SLANG_SPEC_MAT34: - return SLANG_SPEC_VEC4; - case SLANG_SPEC_MAT43: - return SLANG_SPEC_VEC3; - default: - return SLANG_SPEC_VOID; - } -} - - -/** - * Return the dimensionality of a vector, or for a matrix, return number - * of columns. - */ -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; - - case SLANG_SPEC_MAT23: - return 2; - case SLANG_SPEC_MAT32: - return 3; - case SLANG_SPEC_MAT24: - return 2; - case SLANG_SPEC_MAT42: - return 4; - case SLANG_SPEC_MAT34: - return 3; - case SLANG_SPEC_MAT43: - return 4; - - default: - return 0; - } -} - - -/** - * Return the GL_* type that corresponds to a SLANG_SPEC_* type. - */ -GLenum -_slang_gltype_from_specifier(const slang_type_specifier *type) -{ - switch (type->type) { - case SLANG_SPEC_BOOL: - return GL_BOOL; - case SLANG_SPEC_BVEC2: - return GL_BOOL_VEC2; - case SLANG_SPEC_BVEC3: - return GL_BOOL_VEC3; - case SLANG_SPEC_BVEC4: - return GL_BOOL_VEC4; - case SLANG_SPEC_INT: - return GL_INT; - case SLANG_SPEC_IVEC2: - return GL_INT_VEC2; - case SLANG_SPEC_IVEC3: - return GL_INT_VEC3; - case SLANG_SPEC_IVEC4: - return GL_INT_VEC4; - case SLANG_SPEC_FLOAT: - return GL_FLOAT; - case SLANG_SPEC_VEC2: - return GL_FLOAT_VEC2; - case SLANG_SPEC_VEC3: - return GL_FLOAT_VEC3; - case SLANG_SPEC_VEC4: - return GL_FLOAT_VEC4; - case SLANG_SPEC_MAT2: - return GL_FLOAT_MAT2; - case SLANG_SPEC_MAT3: - return GL_FLOAT_MAT3; - case SLANG_SPEC_MAT4: - return GL_FLOAT_MAT4; - case SLANG_SPEC_MAT23: - return GL_FLOAT_MAT2x3; - case SLANG_SPEC_MAT32: - return GL_FLOAT_MAT3x2; - case SLANG_SPEC_MAT24: - return GL_FLOAT_MAT2x4; - case SLANG_SPEC_MAT42: - return GL_FLOAT_MAT4x2; - case SLANG_SPEC_MAT34: - return GL_FLOAT_MAT3x4; - case SLANG_SPEC_MAT43: - return GL_FLOAT_MAT4x3; - case SLANG_SPEC_SAMPLER_1D: - return GL_SAMPLER_1D; - case SLANG_SPEC_SAMPLER_2D: - return GL_SAMPLER_2D; - case SLANG_SPEC_SAMPLER_3D: - return GL_SAMPLER_3D; - case SLANG_SPEC_SAMPLER_CUBE: - return GL_SAMPLER_CUBE; - case SLANG_SPEC_SAMPLER_1D_SHADOW: - return GL_SAMPLER_1D_SHADOW; - case SLANG_SPEC_SAMPLER_2D_SHADOW: - return GL_SAMPLER_2D_SHADOW; - case SLANG_SPEC_SAMPLER_RECT: - return GL_SAMPLER_2D_RECT_ARB; - case SLANG_SPEC_SAMPLER_RECT_SHADOW: - return GL_SAMPLER_2D_RECT_SHADOW_ARB; - case SLANG_SPEC_SAMPLER_1D_ARRAY: - return GL_SAMPLER_1D_ARRAY_EXT; - case SLANG_SPEC_SAMPLER_2D_ARRAY: - return GL_SAMPLER_2D_ARRAY_EXT; - case SLANG_SPEC_SAMPLER_1D_ARRAY_SHADOW: - return GL_SAMPLER_1D_ARRAY_SHADOW_EXT; - case SLANG_SPEC_SAMPLER_2D_ARRAY_SHADOW: - return GL_SAMPLER_2D_ARRAY_SHADOW_EXT; - case SLANG_SPEC_ARRAY: - return _slang_gltype_from_specifier(type->_array); - case SLANG_SPEC_STRUCT: - /* fall-through */ - default: - return GL_NONE; - } -} - diff --git a/mesalib/src/mesa/shader/slang/slang_typeinfo.h b/mesalib/src/mesa/shader/slang/slang_typeinfo.h deleted file mode 100644 index 9a6407a31..000000000 --- a/mesalib/src/mesa/shader/slang/slang_typeinfo.h +++ /dev/null @@ -1,259 +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. - */ - -#ifndef SLANG_TYPEINFO_H -#define SLANG_TYPEINFO_H 1 - -#include "main/imports.h" -#include "main/mtypes.h" -#include "slang_log.h" -#include "slang_utility.h" -#include "slang_vartable.h" - - -struct slang_operation_; - -struct slang_name_space_; - - - -/** - * 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; - -extern GLboolean -_slang_is_swizzle(const char *field, GLuint rows, slang_swizzle *swz); - - -typedef enum slang_type_variant_ -{ - SLANG_VARIANT, /* the default */ - SLANG_INVARIANT /* indicates the "invariant" keyword */ -} slang_type_variant; - - -typedef enum slang_type_centroid_ -{ - SLANG_CENTER, /* the default */ - SLANG_CENTROID /* indicates the "centroid" keyword */ -} slang_type_centroid; - - -/** - * These only apply to gl_FragCoord, but other layout qualifiers may - * appear in the future. - */ -typedef enum slang_layout_qualifier_ -{ - SLANG_LAYOUT_NONE = 0x0, - SLANG_LAYOUT_UPPER_LEFT_BIT = 0x1, - SLANG_LAYOUT_PIXEL_CENTER_INTEGER_BIT = 0x2 -} slang_layout_qualifier; - - -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_type_qualifier; - - -typedef enum slang_type_precision_ -{ - SLANG_PREC_DEFAULT, - SLANG_PREC_LOW, - SLANG_PREC_MEDIUM, - SLANG_PREC_HIGH -} slang_type_precision; - - -/** - * The basic shading language types (float, vec4, mat3, etc) - */ -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_MAT23, - SLANG_SPEC_MAT32, - SLANG_SPEC_MAT24, - SLANG_SPEC_MAT42, - SLANG_SPEC_MAT34, - SLANG_SPEC_MAT43, - SLANG_SPEC_SAMPLER_1D, - SLANG_SPEC_SAMPLER_2D, - SLANG_SPEC_SAMPLER_3D, - SLANG_SPEC_SAMPLER_CUBE, - SLANG_SPEC_SAMPLER_RECT, - SLANG_SPEC_SAMPLER_1D_SHADOW, - SLANG_SPEC_SAMPLER_2D_SHADOW, - SLANG_SPEC_SAMPLER_RECT_SHADOW, - SLANG_SPEC_SAMPLER_1D_ARRAY, - SLANG_SPEC_SAMPLER_2D_ARRAY, - SLANG_SPEC_SAMPLER_1D_ARRAY_SHADOW, - SLANG_SPEC_SAMPLER_2D_ARRAY_SHADOW, - SLANG_SPEC_STRUCT, - SLANG_SPEC_ARRAY -} slang_type_specifier_type; - - -extern slang_type_specifier_type -slang_type_specifier_type_from_string(const char *); - -extern const char * -slang_type_specifier_type_to_string(slang_type_specifier_type); - - -/** - * Describes more sophisticated types, like structs and arrays. - */ -typedef struct slang_type_specifier_ -{ - slang_type_specifier_type type; - struct slang_struct_ *_struct; /**< if type == SLANG_SPEC_STRUCT */ - struct slang_type_specifier_ *_array; /**< if type == SLANG_SPEC_ARRAY */ -} slang_type_specifier; - - -extern GLvoid -slang_type_specifier_ctr(slang_type_specifier *); - -extern GLvoid -slang_type_specifier_dtr(slang_type_specifier *); - -extern slang_type_specifier * -slang_type_specifier_new(slang_type_specifier_type type, - struct slang_struct_ *_struct, - struct slang_type_specifier_ *_array); - - -extern GLboolean -slang_type_specifier_copy(slang_type_specifier *, const slang_type_specifier *); - -extern GLboolean -slang_type_specifier_equal(const slang_type_specifier *, - const slang_type_specifier *); - - -extern GLboolean -slang_type_specifier_compatible(const slang_type_specifier *x, - const slang_type_specifier *y); - - -typedef struct slang_fully_specified_type_ -{ - slang_type_qualifier qualifier; - slang_type_specifier specifier; - slang_type_precision precision; - slang_type_variant variant; - slang_type_centroid centroid; - slang_layout_qualifier layout; - GLint array_len; /**< -1 if not an array type */ -} slang_fully_specified_type; - -extern int -slang_fully_specified_type_construct(slang_fully_specified_type *); - -extern void -slang_fully_specified_type_destruct(slang_fully_specified_type *); - -extern int -slang_fully_specified_type_copy(slang_fully_specified_type *, - const slang_fully_specified_type *); - -GLboolean -slang_fully_specified_types_compatible(const slang_fully_specified_type * x, - const slang_fully_specified_type * y); - - -typedef struct slang_typeinfo_ -{ - GLboolean can_be_referenced; - GLboolean is_swizzled; - slang_swizzle swz; - slang_type_specifier spec; - GLuint array_len; -} slang_typeinfo; - -extern GLboolean -slang_typeinfo_construct(slang_typeinfo *); - -extern GLvoid -slang_typeinfo_destruct(slang_typeinfo *); - - -extern GLboolean -_slang_typeof_operation(struct slang_operation_ *, - const struct slang_name_space_ *, - slang_typeinfo *, slang_atom_pool *, - slang_info_log *log); - -extern GLboolean -_slang_type_is_matrix(slang_type_specifier_type); - -extern GLboolean -_slang_type_is_vector(slang_type_specifier_type); - -extern GLboolean -_slang_type_is_float_vec_mat(slang_type_specifier_type); - -extern slang_type_specifier_type -_slang_type_base(slang_type_specifier_type); - -extern GLuint -_slang_type_dim(slang_type_specifier_type); - -extern GLenum -_slang_gltype_from_specifier(const slang_type_specifier *type); - -#endif diff --git a/mesalib/src/mesa/shader/slang/slang_utility.c b/mesalib/src/mesa/shader/slang/slang_utility.c deleted file mode 100644 index e77404f69..000000000 --- a/mesalib/src/mesa/shader/slang/slang_utility.c +++ /dev/null @@ -1,228 +0,0 @@ -/* - * 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_utility.c - * slang utilities - * \author Michal Krol - */ - -#include "main/imports.h" -#include "slang_utility.h" -#include "slang_mem.h" - -char * -slang_string_concat (char *dst, const char *src) -{ - return strcpy (dst + strlen (dst), src); -} - - -/* slang_string */ - -GLvoid -slang_string_init (slang_string *self) -{ - self->data = NULL; - self->capacity = 0; - self->length = 0; - self->fail = GL_FALSE; -} - -GLvoid -slang_string_free (slang_string *self) -{ - if (self->data != NULL) - free(self->data); -} - -GLvoid -slang_string_reset (slang_string *self) -{ - self->length = 0; - self->fail = GL_FALSE; -} - -static GLboolean -grow (slang_string *self, GLuint size) -{ - if (self->fail) - return GL_FALSE; - if (size > self->capacity) { - /* do not overflow 32-bit range */ - assert (size < 0x80000000); - - self->data = (char *) (_mesa_realloc (self->data, self->capacity, size * 2)); - self->capacity = size * 2; - if (self->data == NULL) { - self->capacity = 0; - self->fail = GL_TRUE; - return GL_FALSE; - } - } - return GL_TRUE; -} - -GLvoid -slang_string_push (slang_string *self, const slang_string *str) -{ - if (str->fail) { - self->fail = GL_TRUE; - return; - } - if (grow (self, self->length + str->length)) { - memcpy (&self->data[self->length], str->data, str->length); - self->length += str->length; - } -} - -GLvoid -slang_string_pushc (slang_string *self, const char c) -{ - if (grow (self, self->length + 1)) { - self->data[self->length] = c; - self->length++; - } -} - -GLvoid -slang_string_pushs (slang_string *self, const char *cstr, GLuint len) -{ - if (grow (self, self->length + len)) { - memcpy (&self->data[self->length], cstr, len); - self->length += len; - } -} - -GLvoid -slang_string_pushi (slang_string *self, GLint i) -{ - char buffer[12]; - - sprintf (buffer, "%d", i); - slang_string_pushs (self, buffer, strlen (buffer)); -} - -const char * -slang_string_cstr (slang_string *self) -{ - if (grow (self, self->length + 1)) - self->data[self->length] = '\0'; - return self->data; -} - -/* slang_atom_pool */ - -void -slang_atom_pool_construct(slang_atom_pool * pool) -{ - GLuint i; - - for (i = 0; i < SLANG_ATOM_POOL_SIZE; i++) - pool->entries[i] = NULL; -} - -void -slang_atom_pool_destruct (slang_atom_pool * pool) -{ - GLuint i; - - for (i = 0; i < SLANG_ATOM_POOL_SIZE; i++) { - slang_atom_entry * entry; - - entry = pool->entries[i]; - while (entry != NULL) { - slang_atom_entry *next = entry->next; - _slang_free(entry->id); - _slang_free(entry); - entry = next; - } - } -} - -/* - * Search the atom pool for an atom with a given name. - * If atom is not found, create and add it to the pool. - * Returns ATOM_NULL if the atom was not found and the function failed - * to create a new atom. - */ -slang_atom -slang_atom_pool_atom(slang_atom_pool * pool, const char * id) -{ - GLuint hash; - const char * p = id; - slang_atom_entry ** entry; - - /* Hash a given string to a number in the range [0, ATOM_POOL_SIZE). */ - hash = 0; - while (*p != '\0') { - GLuint g; - - hash = (hash << 4) + (GLuint) (*p++); - g = hash & 0xf0000000; - if (g != 0) - hash ^= g >> 24; - hash &= ~g; - } - hash %= SLANG_ATOM_POOL_SIZE; - - /* Now the hash points to a linked list of atoms with names that - * have the same hash value. Search the linked list for a given - * name. - */ - entry = &pool->entries[hash]; - while (*entry != NULL) { - /* If the same, return the associated atom. */ - if (slang_string_compare((**entry).id, id) == 0) - return (slang_atom) (**entry).id; - /* Grab the next atom in the linked list. */ - entry = &(**entry).next; - } - - /* Okay, we have not found an atom. Create a new entry for it. - * Note that the <entry> points to the last entry's <next> field. - */ - *entry = (slang_atom_entry *) _slang_alloc(sizeof(slang_atom_entry)); - if (*entry == NULL) - return SLANG_ATOM_NULL; - - /* Initialize a new entry. Because we'll need the actual name of - * the atom, we use the pointer to this string as an actual atom's - * value. - */ - (**entry).next = NULL; - (**entry).id = _slang_strdup(id); - if ((**entry).id == NULL) - return SLANG_ATOM_NULL; - 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); -} diff --git a/mesalib/src/mesa/shader/slang/slang_utility.h b/mesalib/src/mesa/shader/slang/slang_utility.h deleted file mode 100644 index 2c0d0bcbb..000000000 --- a/mesalib/src/mesa/shader/slang/slang_utility.h +++ /dev/null @@ -1,100 +0,0 @@ -/* - * 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_UTILITY_H -#define SLANG_UTILITY_H - - -/* Compile-time assertions. If the expression is zero, try to declare an - * array of size [-1] to cause compilation error. - */ -#define static_assert(expr) do { int _array[(expr) ? 1 : -1]; (void) _array[0]; } while (0) - - -#define slang_string_compare(str1, str2) strcmp (str1, str2) -#define slang_string_copy(dst, src) strcpy (dst, src) -#define slang_string_length(str) strlen (str) - -char *slang_string_concat (char *, const char *); - -/* slang_string */ - -typedef struct -{ - char *data; - GLuint length; - GLuint capacity; - GLboolean fail; -} slang_string; - -GLvoid -slang_string_init (slang_string *); - -GLvoid -slang_string_free (slang_string *); - -GLvoid -slang_string_reset (slang_string *); - -GLvoid -slang_string_push (slang_string *, const slang_string *); - -GLvoid -slang_string_pushc (slang_string *, const char); - -GLvoid -slang_string_pushs (slang_string *, const char *, GLuint); - -GLvoid -slang_string_pushi (slang_string *, GLint); - -const char * -slang_string_cstr (slang_string *); - -/* slang_atom */ - -typedef GLvoid *slang_atom; - -#define SLANG_ATOM_NULL ((slang_atom) 0) - -typedef struct slang_atom_entry_ -{ - char *id; - struct slang_atom_entry_ *next; -} slang_atom_entry; - -#define SLANG_ATOM_POOL_SIZE 1023 - -typedef struct slang_atom_pool_ -{ - slang_atom_entry *entries[SLANG_ATOM_POOL_SIZE]; -} slang_atom_pool; - -GLvoid slang_atom_pool_construct (slang_atom_pool *); -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); - - -#endif diff --git a/mesalib/src/mesa/shader/slang/slang_vartable.c b/mesalib/src/mesa/shader/slang/slang_vartable.c deleted file mode 100644 index e07e3a226..000000000 --- a/mesalib/src/mesa/shader/slang/slang_vartable.c +++ /dev/null @@ -1,362 +0,0 @@ - -#include "main/imports.h" -#include "shader/program.h" -#include "shader/prog_print.h" -#include "slang_compile.h" -#include "slang_compile_variable.h" -#include "slang_emit.h" -#include "slang_mem.h" -#include "slang_vartable.h" -#include "slang_ir.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 * 4]; /**< 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 *) _slang_alloc(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; - } - _slang_free(vt); -} - - - -/** - * Create new table on top of vartable stack. - * Used when we enter a {} block. - */ -void -_slang_push_var_table(slang_var_table *vt) -{ - struct table *t = (struct table *) _slang_alloc(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); - } -} - - -/** - * Pop top entry from variable table. - * Used when we leave a {} block. - */ -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 = t->Vars[i]->store; - GLint j; - GLuint comp; - if (dbg) printf(" Free var %s, size %d at %d.%s\n", - (char*) t->Vars[i]->a_name, store->Size, - store->Index, - _mesa_swizzle_string(store->Swizzle, 0, 0)); - - if (store->File == PROGRAM_SAMPLER) { - /* samplers have no storage */ - continue; - } - - if (store->Size == 1) - comp = GET_SWZ(store->Swizzle, 0); - else - comp = 0; - - /* store->Index may be -1 if we run out of registers */ - if (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 < (int) 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) { - _slang_free(t->Vars); - t->Vars = NULL; - } - - vt->Top = t->Parent; - _slang_free(t); - vt->CurLevel--; -} - - -/** - * Add a new variable to the given var/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, store %p\n", (char *) v->a_name, (void *) v->store); - t->Vars = (slang_variable **) - _slang_realloc(t->Vars, - t->NumVars * sizeof(slang_variable *), - (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 < (GLuint) size; j++) { - assert(i + j < 4 * MAX_PROGRAM_TEMPS); - 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 < (GLuint) size; j++) { - assert(i + j < 4 * MAX_PROGRAM_TEMPS); - t->Temps[i + j] = isTemp ? TEMP : VAR; - } - assert(i < MAX_PROGRAM_TEMPS * 4); - t->ValSize[i] = size; - return i; - } - } - - /* if we get here, we ran out of registers */ - 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; - int i; - - if (store->File == PROGRAM_SAMPLER) { - /* don't really allocate storage */ - store->Index = 0; - return GL_TRUE; - } - - i = alloc_reg(vt, store->Size, GL_FALSE); - if (i < 0) - return GL_FALSE; - - store->Index = i / 4; - store->Swizzle = _slang_var_swizzle(store->Size, i % 4); - - if (dbg) - printf("Alloc var storage sz %d at %d.%s (level %d) store %p\n", - store->Size, store->Index, - _mesa_swizzle_string(store->Swizzle, 0, 0), - t->Level, - (void*) store); - - 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; - - assert(store->Index < 0); - - store->Index = i / 4; - store->Swizzle = _slang_var_swizzle(store->Size, i % 4); - - if (dbg) printf("Alloc temp sz %d at %d.%s (level %d) store %p\n", - store->Size, store->Index, - _mesa_swizzle_string(store->Swizzle, 0, 0), t->Level, - (void *) store); - - return GL_TRUE; -} - - -void -_slang_free_temp(slang_var_table *vt, slang_ir_storage *store) -{ - struct table *t = vt->Top; - GLuint i; - GLint r = store->Index; - assert(store->Size > 0); - assert(r >= 0); - assert((GLuint)r + store->Size <= vt->MaxRegisters * 4); - if (dbg) printf("Free temp sz %d at %d.%s (level %d) store %p\n", - store->Size, r, - _mesa_swizzle_string(store->Swizzle, 0, 0), - t->Level, (void *) store); - if (store->Size == 1) { - const GLuint comp = GET_SWZ(store->Swizzle, 0); - /* we can actually fail some of these assertions because of the - * troublesome IR_SWIZZLE handling. - */ -#if 0 - assert(store->Swizzle == MAKE_SWIZZLE4(comp, comp, comp, comp)); - assert(comp < 4); - assert(t->ValSize[r * 4 + comp] == 1); -#endif - 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 < (GLuint) 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; - GLuint comp; - assert(store->Index >= 0); - assert(store->Index < (int) vt->MaxRegisters); - 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/mesalib/src/mesa/shader/slang/slang_vartable.h b/mesalib/src/mesa/shader/slang/slang_vartable.h deleted file mode 100644 index 94bcd63f4..000000000 --- a/mesalib/src/mesa/shader/slang/slang_vartable.h +++ /dev/null @@ -1,42 +0,0 @@ - -#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/mesalib/src/mesa/shader/symbol_table.c b/mesalib/src/mesa/shader/symbol_table.c deleted file mode 100644 index 6a5d68689..000000000 --- a/mesalib/src/mesa/shader/symbol_table.c +++ /dev/null @@ -1,362 +0,0 @@ -/* - * Copyright © 2008 Intel Corporation - * - * 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 (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 NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS 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 "main/imports.h" -#include "symbol_table.h" -#include "hash_table.h" - -struct symbol { - /** - * Link to the next symbol in the table with the same name - * - * The linked list of symbols with the same name is ordered by scope - * from inner-most to outer-most. - */ - struct symbol *next_with_same_name; - - - /** - * Link to the next symbol in the table with the same scope - * - * The linked list of symbols with the same scope is unordered. Symbols - * in this list my have unique names. - */ - struct symbol *next_with_same_scope; - - - /** - * Header information for the list of symbols with the same name. - */ - struct symbol_header *hdr; - - - /** - * Name space of the symbol - * - * Name space are arbitrary user assigned integers. No two symbols can - * exist in the same name space at the same scope level. - */ - int name_space; - - - /** - * Arbitrary user supplied data. - */ - void *data; -}; - - -/** - */ -struct symbol_header { - /** Linkage in list of all headers in a given symbol table. */ - struct symbol_header *next; - - /** Symbol name. */ - const char *name; - - /** Linked list of symbols with the same name. */ - struct symbol *symbols; -}; - - -/** - * Element of the scope stack. - */ -struct scope_level { - /** Link to next (inner) scope level. */ - struct scope_level *next; - - /** Linked list of symbols with the same scope. */ - struct symbol *symbols; -}; - - -/** - * - */ -struct _mesa_symbol_table { - /** Hash table containing all symbols in the symbol table. */ - struct hash_table *ht; - - /** Top of scope stack. */ - struct scope_level *current_scope; - - /** List of all symbol headers in the table. */ - struct symbol_header *hdr; -}; - - -struct _mesa_symbol_table_iterator { - /** - * Name space of symbols returned by this iterator. - */ - int name_space; - - - /** - * Currently iterated symbol - * - * The next call to \c _mesa_symbol_table_iterator_get will return this - * value. It will also update this value to the value that should be - * returned by the next call. - */ - struct symbol *curr; -}; - - -static void -check_symbol_table(struct _mesa_symbol_table *table) -{ -#if 1 - struct scope_level *scope; - - for (scope = table->current_scope; scope != NULL; scope = scope->next) { - struct symbol *sym; - - for (sym = scope->symbols - ; sym != NULL - ; sym = sym->next_with_same_name) { - const struct symbol_header *const hdr = sym->hdr; - struct symbol *sym2; - - for (sym2 = hdr->symbols - ; sym2 != NULL - ; sym2 = sym2->next_with_same_name) { - assert(sym2->hdr == hdr); - } - } - } -#endif -} - -void -_mesa_symbol_table_pop_scope(struct _mesa_symbol_table *table) -{ - struct scope_level *const scope = table->current_scope; - struct symbol *sym = scope->symbols; - - table->current_scope = scope->next; - - free(scope); - - while (sym != NULL) { - struct symbol *const next = sym->next_with_same_scope; - struct symbol_header *const hdr = sym->hdr; - - assert(hdr->symbols == sym); - - hdr->symbols = sym->next_with_same_name; - - free(sym); - - sym = next; - } - - check_symbol_table(table); -} - - -void -_mesa_symbol_table_push_scope(struct _mesa_symbol_table *table) -{ - struct scope_level *const scope = calloc(1, sizeof(*scope)); - - scope->next = table->current_scope; - table->current_scope = scope; -} - - -static struct symbol_header * -find_symbol(struct _mesa_symbol_table *table, const char *name) -{ - return (struct symbol_header *) hash_table_find(table->ht, name); -} - - -struct _mesa_symbol_table_iterator * -_mesa_symbol_table_iterator_ctor(struct _mesa_symbol_table *table, - int name_space, const char *name) -{ - struct _mesa_symbol_table_iterator *iter = calloc(1, sizeof(*iter)); - struct symbol_header *const hdr = find_symbol(table, name); - - iter->name_space = name_space; - - if (hdr != NULL) { - struct symbol *sym; - - for (sym = hdr->symbols; sym != NULL; sym = sym->next_with_same_name) { - assert(sym->hdr == hdr); - - if ((name_space == -1) || (sym->name_space == name_space)) { - iter->curr = sym; - break; - } - } - } - - return iter; -} - - -void -_mesa_symbol_table_iterator_dtor(struct _mesa_symbol_table_iterator *iter) -{ - free(iter); -} - - -void * -_mesa_symbol_table_iterator_get(struct _mesa_symbol_table_iterator *iter) -{ - return (iter->curr == NULL) ? NULL : iter->curr->data; -} - - -int -_mesa_symbol_table_iterator_next(struct _mesa_symbol_table_iterator *iter) -{ - struct symbol_header *hdr; - - if (iter->curr == NULL) { - return 0; - } - - hdr = iter->curr->hdr; - iter->curr = iter->curr->next_with_same_name; - - while (iter->curr != NULL) { - assert(iter->curr->hdr == hdr); - - if ((iter->name_space == -1) - || (iter->curr->name_space == iter->name_space)) { - return 1; - } - - iter->curr = iter->curr->next_with_same_name; - } - - return 0; -} - - -void * -_mesa_symbol_table_find_symbol(struct _mesa_symbol_table *table, - int name_space, const char *name) -{ - struct symbol_header *const hdr = find_symbol(table, name); - - if (hdr != NULL) { - struct symbol *sym; - - - for (sym = hdr->symbols; sym != NULL; sym = sym->next_with_same_name) { - assert(sym->hdr == hdr); - - if ((name_space == -1) || (sym->name_space == name_space)) { - return sym->data; - } - } - } - - return NULL; -} - - -int -_mesa_symbol_table_add_symbol(struct _mesa_symbol_table *table, - int name_space, const char *name, - void *declaration) -{ - struct symbol_header *hdr; - struct symbol *sym; - - check_symbol_table(table); - - hdr = find_symbol(table, name); - - check_symbol_table(table); - - if (hdr == NULL) { - hdr = calloc(1, sizeof(*hdr)); - hdr->name = name; - - hash_table_insert(table->ht, hdr, name); - hdr->next = table->hdr; - table->hdr = hdr; - } - - check_symbol_table(table); - - sym = calloc(1, sizeof(*sym)); - sym->next_with_same_name = hdr->symbols; - sym->next_with_same_scope = table->current_scope->symbols; - sym->hdr = hdr; - sym->name_space = name_space; - sym->data = declaration; - - assert(sym->hdr == hdr); - - hdr->symbols = sym; - table->current_scope->symbols = sym; - - check_symbol_table(table); - return 0; -} - - -struct _mesa_symbol_table * -_mesa_symbol_table_ctor(void) -{ - struct _mesa_symbol_table *table = calloc(1, sizeof(*table)); - - if (table != NULL) { - table->ht = hash_table_ctor(32, hash_table_string_hash, - hash_table_string_compare); - - _mesa_symbol_table_push_scope(table); - } - - return table; -} - - -void -_mesa_symbol_table_dtor(struct _mesa_symbol_table *table) -{ - struct symbol_header *hdr; - struct symbol_header *next; - - while (table->current_scope != NULL) { - _mesa_symbol_table_pop_scope(table); - } - - for (hdr = table->hdr; hdr != NULL; hdr = next) { - next = hdr->next; - free(hdr); - } - - hash_table_dtor(table->ht); - free(table); -} diff --git a/mesalib/src/mesa/shader/symbol_table.h b/mesalib/src/mesa/shader/symbol_table.h deleted file mode 100644 index 0c054ef13..000000000 --- a/mesalib/src/mesa/shader/symbol_table.h +++ /dev/null @@ -1,55 +0,0 @@ -/* - * Copyright © 2008 Intel Corporation - * - * 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 (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 NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS 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 MESA_SYMBOL_TABLE_H -#define MESA_SYMBOL_TABLE_H - -struct _mesa_symbol_table; -struct _mesa_symbol_table_iterator; - -extern void _mesa_symbol_table_push_scope(struct _mesa_symbol_table *table); - -extern void _mesa_symbol_table_pop_scope(struct _mesa_symbol_table *table); - -extern int _mesa_symbol_table_add_symbol(struct _mesa_symbol_table *symtab, - int name_space, const char *name, void *declaration); - -extern void *_mesa_symbol_table_find_symbol( - struct _mesa_symbol_table *symtab, int name_space, const char *name); - -extern struct _mesa_symbol_table *_mesa_symbol_table_ctor(void); - -extern void _mesa_symbol_table_dtor(struct _mesa_symbol_table *); - -extern struct _mesa_symbol_table_iterator *_mesa_symbol_table_iterator_ctor( - struct _mesa_symbol_table *table, int name_space, const char *name); - -extern void _mesa_symbol_table_iterator_dtor( - struct _mesa_symbol_table_iterator *); - -extern void *_mesa_symbol_table_iterator_get( - struct _mesa_symbol_table_iterator *iter); - -extern int _mesa_symbol_table_iterator_next( - struct _mesa_symbol_table_iterator *iter); - -#endif /* MESA_SYMBOL_TABLE_H */ |