diff options
Diffstat (limited to 'nx-X11/extras/Mesa/src/mesa/shader')
63 files changed, 33717 insertions, 0 deletions
diff --git a/nx-X11/extras/Mesa/src/mesa/shader/arbfragparse.c b/nx-X11/extras/Mesa/src/mesa/shader/arbfragparse.c new file mode 100644 index 000000000..237c348ba --- /dev/null +++ b/nx-X11/extras/Mesa/src/mesa/shader/arbfragparse.c @@ -0,0 +1,229 @@ +/* + * Mesa 3-D graphics library + * Version: 6.2 + * + * Copyright (C) 1999-2004 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_FP 0 + +/** + * \file arbfragparse.c + * ARB_fragment_program parser. + * \author Karl Rasche + */ + +#include "glheader.h" +#include "context.h" +#include "imports.h" +#include "macros.h" +#include "mtypes.h" +#include "program.h" +#include "arbprogparse.h" +#include "arbfragparse.h" + +void +_mesa_debug_fp_inst(GLint num, struct fp_instruction *fp) +{ + GLint a; + + static const char *opcode_string[] = { + "ABS", /* ARB_f_p only */ + "ADD", + "CMP", /* ARB_f_p only */ + "COS", + "DDX", /* NV_f_p only */ + "DDY", /* NV_f_p only */ + "DP3", + "DP4", + "DPH", /* ARB_f_p only */ + "DST", + "END", /* private opcode */ + "EX2", + "FLR", + "FRC", + "KIL", /* ARB_f_p only */ + "KIL_NV", /* NV_f_p only */ + "LG2", + "LIT", + "LRP", + "MAD", + "MAX", + "MIN", + "MOV", + "MUL", + "PK2H", /* NV_f_p only */ + "PK2US", /* NV_f_p only */ + "PK4B", /* NV_f_p only */ + "PK4UB", /* NV_f_p only */ + "POW", + "PRINT", /* Mesa only */ + "RCP", + "RFL", /* NV_f_p only */ + "RSQ", + "SCS", /* ARB_f_p only */ + "SEQ", /* NV_f_p only */ + "SFL", /* NV_f_p only */ + "SGE", /* NV_f_p only */ + "SGT", /* NV_f_p only */ + "SIN", + "SLE", /* NV_f_p only */ + "SLT", + "SNE", /* NV_f_p only */ + "STR", /* NV_f_p only */ + "SUB", + "SWZ", /* ARB_f_p only */ + "TEX", + "TXB", /* ARB_f_p only */ + "TXD", /* NV_f_p only */ + "TXP", /* ARB_f_p only */ + "TXP_NV", /* NV_f_p only */ + "UP2H", /* NV_f_p only */ + "UP2US", /* NV_f_p only */ + "UP4B", /* NV_f_p only */ + "UP4UB", /* NV_f_p only */ + "X2D", /* NV_f_p only - 2d mat mul */ + "XPD", /* ARB_f_p only - cross product */ + }; + + static const char *file_string[] = { + "TEMP", + "INPUT", + "OUTPUT", + "LOCAL", + "ENV", + "NAMED", + "STATE", + "WRITE_ONLY", + "ADDR" + }; + + static const char swz[] = "xyzw01??"; + + for (a=0; a<num; a++) { + _mesa_printf("%s", opcode_string[fp[a].Opcode]); + + if (fp[a].Saturate) + _mesa_printf("_SAT"); + + if (fp[a].DstReg.File != 0xf) { + if (fp[a].DstReg.WriteMask != 0xf || + fp[a].SrcReg[0].NegateBase) + _mesa_printf(" %s[%d].%s%s%s%s ", file_string[fp[a].DstReg.File], fp[a].DstReg.Index, + GET_BIT(fp[a].DstReg.WriteMask, 0) ? "x" : "", + GET_BIT(fp[a].DstReg.WriteMask, 1) ? "y" : "", + GET_BIT(fp[a].DstReg.WriteMask, 2) ? "z" : "", + GET_BIT(fp[a].DstReg.WriteMask, 3) ? "w" : ""); + else + _mesa_printf(" %s[%d] ", file_string[fp[a].DstReg.File], fp[a].DstReg.Index); + } + + if (fp[a].SrcReg[0].File != 0xf) { + if (fp[a].SrcReg[0].Swizzle != SWIZZLE_NOOP || + fp[a].SrcReg[0].NegateBase) + _mesa_printf("%s[%d].%s%c%c%c%c ", file_string[fp[a].SrcReg[0].File], fp[a].SrcReg[0].Index, + fp[a].SrcReg[0].NegateBase ? "-" : "", + swz[GET_SWZ(fp[a].SrcReg[0].Swizzle, 0)], + swz[GET_SWZ(fp[a].SrcReg[0].Swizzle, 1)], + swz[GET_SWZ(fp[a].SrcReg[0].Swizzle, 2)], + swz[GET_SWZ(fp[a].SrcReg[0].Swizzle, 3)]); + else + _mesa_printf("%s[%d] ", file_string[fp[a].SrcReg[0].File], fp[a].SrcReg[0].Index); + } + + if (fp[a].SrcReg[1].File != 0xf) { + if (fp[a].SrcReg[1].Swizzle != SWIZZLE_NOOP || + fp[a].SrcReg[1].NegateBase) + _mesa_printf("%s[%d].%s%c%c%c%c ", file_string[fp[a].SrcReg[1].File], fp[a].SrcReg[1].Index, + fp[a].SrcReg[1].NegateBase ? "-" : "", + swz[GET_SWZ(fp[a].SrcReg[1].Swizzle, 0)], + swz[GET_SWZ(fp[a].SrcReg[1].Swizzle, 1)], + swz[GET_SWZ(fp[a].SrcReg[1].Swizzle, 2)], + swz[GET_SWZ(fp[a].SrcReg[1].Swizzle, 3)]); + else + _mesa_printf("%s[%d] ", file_string[fp[a].SrcReg[1].File], fp[a].SrcReg[1].Index); + } + + if (fp[a].SrcReg[2].File != 0xf) { + if (fp[a].SrcReg[2].Swizzle != SWIZZLE_NOOP || + fp[a].SrcReg[2].NegateBase) + _mesa_printf("%s[%d].%s%c%c%c%c ", file_string[fp[a].SrcReg[2].File], fp[a].SrcReg[2].Index, + fp[a].SrcReg[1].NegateBase ? "-" : "", + swz[GET_SWZ(fp[a].SrcReg[2].Swizzle, 0)], + swz[GET_SWZ(fp[a].SrcReg[2].Swizzle, 1)], + swz[GET_SWZ(fp[a].SrcReg[2].Swizzle, 2)], + swz[GET_SWZ(fp[a].SrcReg[2].Swizzle, 3)]); + else + _mesa_printf("%s[%d] ", file_string[fp[a].SrcReg[2].File], fp[a].SrcReg[2].Index); + } + + _mesa_printf("\n"); + } +} + + +void +_mesa_parse_arb_fragment_program(GLcontext * ctx, GLenum target, + const GLubyte * str, GLsizei len, + struct fragment_program *program) +{ + GLuint i; + struct arb_program ap; + (void) target; + + /* set the program target before parsing */ + ap.Base.Target = GL_FRAGMENT_PROGRAM_ARB; + + if (!_mesa_parse_arb_program(ctx, str, len, &ap)) { + /* Error in the program. Just return. */ + return; + } + + /* Copy the relevant contents of the arb_program struct into the + * fragment_program struct. + */ + program->Base.String = ap.Base.String; + program->Base.NumInstructions = ap.Base.NumInstructions; + program->Base.NumTemporaries = ap.Base.NumTemporaries; + program->Base.NumParameters = ap.Base.NumParameters; + program->Base.NumAttributes = ap.Base.NumAttributes; + program->Base.NumAddressRegs = ap.Base.NumAddressRegs; + program->NumAluInstructions = ap.NumAluInstructions; + program->NumTexInstructions = ap.NumTexInstructions; + program->NumTexIndirections = ap.NumTexIndirections; + + program->InputsRead = ap.InputsRead; + program->OutputsWritten = ap.OutputsWritten; + for (i = 0; i < MAX_TEXTURE_IMAGE_UNITS; i++) + program->TexturesUsed[i] = ap.TexturesUsed[i]; + + if (program->Parameters) { + /* free previous program's parameters */ + _mesa_free_parameter_list(program->Parameters); + } + program->Parameters = ap.Parameters; + program->FogOption = ap.FogOption; + +#if DEBUG_FP + _mesa_debug_fp_inst(ap.Base.NumInstructions, ap.FPInstructions); +#endif + + program->Instructions = ap.FPInstructions; +} diff --git a/nx-X11/extras/Mesa/src/mesa/shader/arbfragparse.h b/nx-X11/extras/Mesa/src/mesa/shader/arbfragparse.h new file mode 100644 index 000000000..0d3e69fa8 --- /dev/null +++ b/nx-X11/extras/Mesa/src/mesa/shader/arbfragparse.h @@ -0,0 +1,39 @@ +/* + * 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. + */ + +#ifndef ARBFRAGPARSE_H +#define ARBFRAGPARSE_H + +#include "mtypes.h" + +extern void +_mesa_parse_arb_fragment_program(GLcontext * ctx, GLenum target, + const GLubyte * str, GLsizei len, + struct fragment_program *program); + +extern void +_mesa_debug_fp_inst(GLint num, struct fp_instruction *fp); + + +#endif diff --git a/nx-X11/extras/Mesa/src/mesa/shader/arbprogparse.c b/nx-X11/extras/Mesa/src/mesa/shader/arbprogparse.c new file mode 100644 index 000000000..7da4139d2 --- /dev/null +++ b/nx-X11/extras/Mesa/src/mesa/shader/arbprogparse.c @@ -0,0 +1,4133 @@ +/* + * Mesa 3-D graphics library + * Version: 6.4 + * + * 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. + */ + +#define DEBUG_PARSING 0 + +/** + * \file arbprogparse.c + * ARB_*_program parser core + * \author Karl Rasche + */ + +#include "mtypes.h" +#include "glheader.h" +#include "context.h" +#include "hash.h" +#include "imports.h" +#include "macros.h" +#include "program.h" +#include "nvvertprog.h" +#include "nvfragprog.h" +#include "arbprogparse.h" +#include "grammar_mesa.h" + +#include "dispatch.h" + +#ifndef __extension__ +#if !defined(__GNUC__) || (__GNUC__ < 2) || \ + ((__GNUC__ == 2) && (__GNUC_MINOR__ <= 7)) +# define __extension__ +#endif +#endif + +/* TODO: + * Fragment Program Stuff: + * ----------------------------------------------------- + * + * - things from Michal's email + * + overflow on atoi + * + not-overflowing floats (don't use parse_integer..) + * + can remove range checking in arbparse.c + * + * - check all limits of number of various variables + * + parameters + * + * - test! test! test! + * + * Vertex Program Stuff: + * ----------------------------------------------------- + * - Optimize param array usage and count limits correctly, see spec, + * section 2.14.3.7 + * + Record if an array is reference absolutly or relatively (or both) + * + For absolute arrays, store a bitmap of accesses + * + For single parameters, store an access flag + * + After parsing, make a parameter cleanup and merging pass, where + * relative arrays are layed out first, followed by abs arrays, and + * finally single state. + * + Remap offsets for param src and dst registers + * + Now we can properly count parameter usage + * + * - Multiple state binding errors in param arrays (see spec, just before + * section 2.14.3.3) + * - grep for XXX + * + * Mesa Stuff + * ----------------------------------------------------- + * - User clipping planes vs. PositionInvariant + * - Is it sufficient to just multiply by the mvp to transform in the + * PositionInvariant case? Or do we need something more involved? + * + * - vp_src swizzle is GLubyte, fp_src swizzle is GLuint + * - fetch state listed in program_parameters list + * + WTF should this go??? + * + currently in nvvertexec.c and s_nvfragprog.c + * + * - allow for multiple address registers (and fetch address regs properly) + * + * Cosmetic Stuff + * ----------------------------------------------------- + * - remove any leftover unused grammar.c stuff (dict_ ?) + * - fix grammar.c error handling so its not static + * - #ifdef around stuff pertaining to extentions + * + * Outstanding Questions: + * ----------------------------------------------------- + * - ARB_matrix_palette / ARB_vertex_blend -- not supported + * what gets hacked off because of this: + * + VERTEX_ATTRIB_MATRIXINDEX + * + VERTEX_ATTRIB_WEIGHT + * + MATRIX_MODELVIEW + * + MATRIX_PALETTE + * + * - When can we fetch env/local params from their own register files, and + * when to we have to fetch them into the main state register file? + * (think arrays) + * + * Grammar Changes: + * ----------------------------------------------------- + */ + +/* Changes since moving the file to shader directory + +2004-III-4 ------------------------------------------------------------ +- added #include "grammar_mesa.h" +- removed grammar specific code part (it resides now in grammar.c) +- added GL_ARB_fragment_program_shadow tokens +- modified #include "arbparse_syn.h" +- major changes inside _mesa_parse_arb_program() +- check the program string for '\0' characters +- copy the program string to a one-byte-longer location to have + it null-terminated +- position invariance test (not writing to result.position) moved + to syntax part +*/ + +typedef GLubyte *production; + +/** + * This is the text describing the rules to parse the grammar + */ +__extension__ static char arb_grammar_text[] = +#include "arbprogram_syn.h" +; + +/** + * These should match up with the values defined in arbprogram.syn + */ + +/* + Changes: + - changed and merged V_* and F_* opcode values to OP_*. + - added GL_ARB_fragment_program_shadow specific tokens (michal) +*/ +#define REVISION 0x09 + +/* program type */ +#define FRAGMENT_PROGRAM 0x01 +#define VERTEX_PROGRAM 0x02 + +/* program section */ +#define OPTION 0x01 +#define INSTRUCTION 0x02 +#define DECLARATION 0x03 +#define END 0x04 + +/* GL_ARB_fragment_program option */ +#define ARB_PRECISION_HINT_FASTEST 0x00 +#define ARB_PRECISION_HINT_NICEST 0x01 +#define ARB_FOG_EXP 0x02 +#define ARB_FOG_EXP2 0x03 +#define ARB_FOG_LINEAR 0x04 + +/* GL_ARB_vertex_program option */ +#define ARB_POSITION_INVARIANT 0x05 + +/* GL_ARB_fragment_program_shadow option */ +#define ARB_FRAGMENT_PROGRAM_SHADOW 0x06 + +/* GL_ARB_draw_buffers option */ +#define ARB_DRAW_BUFFERS 0x07 + +/* GL_ARB_fragment_program instruction class */ +#define OP_ALU_INST 0x00 +#define OP_TEX_INST 0x01 + +/* GL_ARB_vertex_program instruction class */ +/* OP_ALU_INST */ + +/* GL_ARB_fragment_program instruction type */ +#define OP_ALU_VECTOR 0x00 +#define OP_ALU_SCALAR 0x01 +#define OP_ALU_BINSC 0x02 +#define OP_ALU_BIN 0x03 +#define OP_ALU_TRI 0x04 +#define OP_ALU_SWZ 0x05 +#define OP_TEX_SAMPLE 0x06 +#define OP_TEX_KIL 0x07 + +/* GL_ARB_vertex_program instruction type */ +#define OP_ALU_ARL 0x08 +/* OP_ALU_VECTOR */ +/* OP_ALU_SCALAR */ +/* OP_ALU_BINSC */ +/* OP_ALU_BIN */ +/* OP_ALU_TRI */ +/* OP_ALU_SWZ */ + +/* GL_ARB_fragment_program instruction code */ +#define OP_ABS 0x00 +#define OP_ABS_SAT 0x1B +#define OP_FLR 0x09 +#define OP_FLR_SAT 0x26 +#define OP_FRC 0x0A +#define OP_FRC_SAT 0x27 +#define OP_LIT 0x0C +#define OP_LIT_SAT 0x2A +#define OP_MOV 0x11 +#define OP_MOV_SAT 0x30 +#define OP_COS 0x1F +#define OP_COS_SAT 0x20 +#define OP_EX2 0x07 +#define OP_EX2_SAT 0x25 +#define OP_LG2 0x0B +#define OP_LG2_SAT 0x29 +#define OP_RCP 0x14 +#define OP_RCP_SAT 0x33 +#define OP_RSQ 0x15 +#define OP_RSQ_SAT 0x34 +#define OP_SIN 0x38 +#define OP_SIN_SAT 0x39 +#define OP_SCS 0x35 +#define OP_SCS_SAT 0x36 +#define OP_POW 0x13 +#define OP_POW_SAT 0x32 +#define OP_ADD 0x01 +#define OP_ADD_SAT 0x1C +#define OP_DP3 0x03 +#define OP_DP3_SAT 0x21 +#define OP_DP4 0x04 +#define OP_DP4_SAT 0x22 +#define OP_DPH 0x05 +#define OP_DPH_SAT 0x23 +#define OP_DST 0x06 +#define OP_DST_SAT 0x24 +#define OP_MAX 0x0F +#define OP_MAX_SAT 0x2E +#define OP_MIN 0x10 +#define OP_MIN_SAT 0x2F +#define OP_MUL 0x12 +#define OP_MUL_SAT 0x31 +#define OP_SGE 0x16 +#define OP_SGE_SAT 0x37 +#define OP_SLT 0x17 +#define OP_SLT_SAT 0x3A +#define OP_SUB 0x18 +#define OP_SUB_SAT 0x3B +#define OP_XPD 0x1A +#define OP_XPD_SAT 0x43 +#define OP_CMP 0x1D +#define OP_CMP_SAT 0x1E +#define OP_LRP 0x2B +#define OP_LRP_SAT 0x2C +#define OP_MAD 0x0E +#define OP_MAD_SAT 0x2D +#define OP_SWZ 0x19 +#define OP_SWZ_SAT 0x3C +#define OP_TEX 0x3D +#define OP_TEX_SAT 0x3E +#define OP_TXB 0x3F +#define OP_TXB_SAT 0x40 +#define OP_TXP 0x41 +#define OP_TXP_SAT 0x42 +#define OP_KIL 0x28 + +/* GL_ARB_vertex_program instruction code */ +#define OP_ARL 0x02 +/* OP_ABS */ +/* OP_FLR */ +/* OP_FRC */ +/* OP_LIT */ +/* OP_MOV */ +/* OP_EX2 */ +#define OP_EXP 0x08 +/* OP_LG2 */ +#define OP_LOG 0x0D +/* OP_RCP */ +/* OP_RSQ */ +/* OP_POW */ +/* OP_ADD */ +/* OP_DP3 */ +/* OP_DP4 */ +/* OP_DPH */ +/* OP_DST */ +/* OP_MAX */ +/* OP_MIN */ +/* OP_MUL */ +/* OP_SGE */ +/* OP_SLT */ +/* OP_SUB */ +/* OP_XPD */ +/* OP_MAD */ +/* OP_SWZ */ + +/* fragment attribute binding */ +#define FRAGMENT_ATTRIB_COLOR 0x01 +#define FRAGMENT_ATTRIB_TEXCOORD 0x02 +#define FRAGMENT_ATTRIB_FOGCOORD 0x03 +#define FRAGMENT_ATTRIB_POSITION 0x04 + +/* vertex attribute binding */ +#define VERTEX_ATTRIB_POSITION 0x01 +#define VERTEX_ATTRIB_WEIGHT 0x02 +#define VERTEX_ATTRIB_NORMAL 0x03 +#define VERTEX_ATTRIB_COLOR 0x04 +#define VERTEX_ATTRIB_FOGCOORD 0x05 +#define VERTEX_ATTRIB_TEXCOORD 0x06 +#define VERTEX_ATTRIB_MATRIXINDEX 0x07 +#define VERTEX_ATTRIB_GENERIC 0x08 + +/* fragment result binding */ +#define FRAGMENT_RESULT_COLOR 0x01 +#define FRAGMENT_RESULT_DEPTH 0x02 + +/* vertex result binding */ +#define VERTEX_RESULT_POSITION 0x01 +#define VERTEX_RESULT_COLOR 0x02 +#define VERTEX_RESULT_FOGCOORD 0x03 +#define VERTEX_RESULT_POINTSIZE 0x04 +#define VERTEX_RESULT_TEXCOORD 0x05 + +/* texture target */ +#define TEXTARGET_1D 0x01 +#define TEXTARGET_2D 0x02 +#define TEXTARGET_3D 0x03 +#define TEXTARGET_RECT 0x04 +#define TEXTARGET_CUBE 0x05 +/* GL_ARB_fragment_program_shadow */ +#define TEXTARGET_SHADOW1D 0x06 +#define TEXTARGET_SHADOW2D 0x07 +#define TEXTARGET_SHADOWRECT 0x08 + +/* face type */ +#define FACE_FRONT 0x00 +#define FACE_BACK 0x01 + +/* color type */ +#define COLOR_PRIMARY 0x00 +#define COLOR_SECONDARY 0x01 + +/* component */ +#define COMPONENT_X 0x00 +#define COMPONENT_Y 0x01 +#define COMPONENT_Z 0x02 +#define COMPONENT_W 0x03 +#define COMPONENT_0 0x04 +#define COMPONENT_1 0x05 + +/* array index type */ +#define ARRAY_INDEX_ABSOLUTE 0x00 +#define ARRAY_INDEX_RELATIVE 0x01 + +/* matrix name */ +#define MATRIX_MODELVIEW 0x01 +#define MATRIX_PROJECTION 0x02 +#define MATRIX_MVP 0x03 +#define MATRIX_TEXTURE 0x04 +#define MATRIX_PALETTE 0x05 +#define MATRIX_PROGRAM 0x06 + +/* matrix modifier */ +#define MATRIX_MODIFIER_IDENTITY 0x00 +#define MATRIX_MODIFIER_INVERSE 0x01 +#define MATRIX_MODIFIER_TRANSPOSE 0x02 +#define MATRIX_MODIFIER_INVTRANS 0x03 + +/* constant type */ +#define CONSTANT_SCALAR 0x01 +#define CONSTANT_VECTOR 0x02 + +/* program param type */ +#define PROGRAM_PARAM_ENV 0x01 +#define PROGRAM_PARAM_LOCAL 0x02 + +/* register type */ +#define REGISTER_ATTRIB 0x01 +#define REGISTER_PARAM 0x02 +#define REGISTER_RESULT 0x03 +#define REGISTER_ESTABLISHED_NAME 0x04 + +/* param binding */ +#define PARAM_NULL 0x00 +#define PARAM_ARRAY_ELEMENT 0x01 +#define PARAM_STATE_ELEMENT 0x02 +#define PARAM_PROGRAM_ELEMENT 0x03 +#define PARAM_PROGRAM_ELEMENTS 0x04 +#define PARAM_CONSTANT 0x05 + +/* param state property */ +#define STATE_MATERIAL_PARSER 0x01 +#define STATE_LIGHT_PARSER 0x02 +#define STATE_LIGHT_MODEL 0x03 +#define STATE_LIGHT_PROD 0x04 +#define STATE_FOG 0x05 +#define STATE_MATRIX_ROWS 0x06 +/* GL_ARB_fragment_program */ +#define STATE_TEX_ENV 0x07 +#define STATE_DEPTH 0x08 +/* GL_ARB_vertex_program */ +#define STATE_TEX_GEN 0x09 +#define STATE_CLIP_PLANE 0x0A +#define STATE_POINT 0x0B + +/* state material property */ +#define MATERIAL_AMBIENT 0x01 +#define MATERIAL_DIFFUSE 0x02 +#define MATERIAL_SPECULAR 0x03 +#define MATERIAL_EMISSION 0x04 +#define MATERIAL_SHININESS 0x05 + +/* state light property */ +#define LIGHT_AMBIENT 0x01 +#define LIGHT_DIFFUSE 0x02 +#define LIGHT_SPECULAR 0x03 +#define LIGHT_POSITION 0x04 +#define LIGHT_ATTENUATION 0x05 +#define LIGHT_HALF 0x06 +#define LIGHT_SPOT_DIRECTION 0x07 + +/* state light model property */ +#define LIGHT_MODEL_AMBIENT 0x01 +#define LIGHT_MODEL_SCENECOLOR 0x02 + +/* state light product property */ +#define LIGHT_PROD_AMBIENT 0x01 +#define LIGHT_PROD_DIFFUSE 0x02 +#define LIGHT_PROD_SPECULAR 0x03 + +/* state texture environment property */ +#define TEX_ENV_COLOR 0x01 + +/* state texture generation coord property */ +#define TEX_GEN_EYE 0x01 +#define TEX_GEN_OBJECT 0x02 + +/* state fog property */ +#define FOG_COLOR 0x01 +#define FOG_PARAMS 0x02 + +/* state depth property */ +#define DEPTH_RANGE 0x01 + +/* state point parameters property */ +#define POINT_SIZE 0x01 +#define POINT_ATTENUATION 0x02 + +/* declaration */ +#define ATTRIB 0x01 +#define PARAM 0x02 +#define TEMP 0x03 +#define OUTPUT 0x04 +#define ALIAS 0x05 +/* GL_ARB_vertex_program */ +#define ADDRESS 0x06 + +/*----------------------------------------------------------------------- + * From here on down is the semantic checking portion + * + */ + +/** + * Variable Table Handling functions + */ +typedef enum +{ + vt_none, + vt_address, + vt_attrib, + vt_param, + vt_temp, + vt_output, + vt_alias +} var_type; + + +/* + * Setting an explicit field for each of the binding properties is a bit wasteful + * of space, but it should be much more clear when reading later on.. + */ +struct var_cache +{ + GLubyte *name; + var_type type; + GLuint address_binding; /* The index of the address register we should + * be using */ + GLuint attrib_binding; /* For type vt_attrib, see nvfragprog.h for values */ + GLuint attrib_binding_idx; /* The index into the attrib register file corresponding + * to the state in attrib_binding */ + GLuint attrib_is_generic; /* If the attrib was specified through a generic + * vertex attrib */ + GLuint temp_binding; /* The index of the temp register we are to use */ + GLuint output_binding; /* For type vt_output, see nvfragprog.h for values */ + GLuint output_binding_idx; /* This is the index into the result register file + * corresponding to the bound result state */ + struct var_cache *alias_binding; /* For type vt_alias, points to the var_cache entry + * that this is aliased to */ + GLuint param_binding_type; /* {PROGRAM_STATE_VAR, PROGRAM_LOCAL_PARAM, + * PROGRAM_ENV_PARAM} */ + GLuint param_binding_begin; /* This is the offset into the program_parameter_list where + * the tokens representing our bound state (or constants) + * start */ + GLuint param_binding_length; /* This is how many entries in the 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 */ + struct var_cache *next; +}; + +static GLvoid +var_cache_create (struct var_cache **va) +{ + *va = (struct var_cache *) _mesa_malloc (sizeof (struct var_cache)); + if (*va) { + (**va).name = NULL; + (**va).type = vt_none; + (**va).attrib_binding = ~0; + (**va).attrib_is_generic = 0; + (**va).temp_binding = ~0; + (**va).output_binding = ~0; + (**va).output_binding_idx = ~0; + (**va).param_binding_type = ~0; + (**va).param_binding_begin = ~0; + (**va).param_binding_length = ~0; + (**va).alias_binding = NULL; + (**va).next = NULL; + } +} + +static GLvoid +var_cache_destroy (struct var_cache **va) +{ + if (*va) { + var_cache_destroy (&(**va).next); + _mesa_free (*va); + *va = NULL; + } +} + +static GLvoid +var_cache_append (struct var_cache **va, struct var_cache *nv) +{ + if (*va) + var_cache_append (&(**va).next, nv); + else + *va = nv; +} + +static struct var_cache * +var_cache_find (struct var_cache *va, GLubyte * name) +{ + /*struct var_cache *first = va;*/ + + while (va) { + if (!strcmp ( (const char*) name, (const char*) va->name)) { + if (va->type == vt_alias) + return va->alias_binding; + return va; + } + + va = va->next; + } + + return NULL; +} + +/** + * constructs an integer from 4 GLubytes in LE format + */ +static GLuint +parse_position (GLubyte ** inst) +{ + GLuint value; + + value = (GLuint) (*(*inst)++); + value += (GLuint) (*(*inst)++) * 0x100; + value += (GLuint) (*(*inst)++) * 0x10000; + value += (GLuint) (*(*inst)++) * 0x1000000; + + return value; +} + +/** + * This will, given a string, lookup the string as a variable name in the + * var cache. If the name is found, the var cache node corresponding to the + * var name is returned. If it is not found, a new entry is allocated + * + * \param I Points into the binary array where the string identifier begins + * \param found 1 if the string was found in the var_cache, 0 if it was allocated + * \return The location on the var_cache corresponding the the string starting at I + */ +static struct var_cache * +parse_string (GLubyte ** inst, struct var_cache **vc_head, + struct arb_program *Program, GLuint * found) +{ + GLubyte *i = *inst; + struct var_cache *va = NULL; + (void) Program; + + *inst += _mesa_strlen ((char *) i) + 1; + + va = var_cache_find (*vc_head, i); + + if (va) { + *found = 1; + return va; + } + + *found = 0; + var_cache_create (&va); + va->name = i; + + var_cache_append (vc_head, va); + + return va; +} + +static char * +parse_string_without_adding (GLubyte ** inst, struct arb_program *Program) +{ + GLubyte *i = *inst; + (void) Program; + + *inst += _mesa_strlen ((char *) i) + 1; + + return (char *) i; +} + +/** + * \return -1 if we parse '-', return 1 otherwise + */ +static GLint +parse_sign (GLubyte ** inst) +{ + /*return *(*inst)++ != '+'; */ + + if (**inst == '-') { + (*inst)++; + return -1; + } + else if (**inst == '+') { + (*inst)++; + return 1; + } + + return 1; +} + +/** + * parses and returns signed integer + */ +static GLint +parse_integer (GLubyte ** inst, struct arb_program *Program) +{ + GLint sign; + GLint value; + + /* check if *inst points to '+' or '-' + * if yes, grab the sign and increment *inst + */ + sign = parse_sign (inst); + + /* now check if *inst points to 0 + * if yes, increment the *inst and return the default value + */ + if (**inst == 0) { + (*inst)++; + return 0; + } + + /* parse the integer as you normally would do it */ + value = _mesa_atoi (parse_string_without_adding (inst, Program)); + + /* now, after terminating 0 there is a position + * to parse it - parse_position() + */ + Program->Position = parse_position (inst); + + return value * sign; +} + +/** + Accumulate this string of digits, and return them as + a large integer represented in floating point (for range). + If scale is not NULL, also accumulates a power-of-ten + integer scale factor that represents the number of digits + in the string. +*/ +static GLdouble +parse_float_string(GLubyte ** inst, struct arb_program *Program, GLdouble *scale) +{ + GLdouble value = 0.0; + GLdouble oscale = 1.0; + + if (**inst == 0) { /* this string of digits is empty-- do nothing */ + (*inst)++; + } + else { /* nonempty string-- parse out the digits */ + while (**inst >= '0' && **inst <= '9') { + GLubyte digit = *((*inst)++); + value = value * 10.0 + (GLint) (digit - '0'); + oscale *= 10.0; + } + assert(**inst == 0); /* integer string should end with 0 */ + (*inst)++; /* skip over terminating 0 */ + Program->Position = parse_position(inst); /* skip position (from integer) */ + } + if (scale) + *scale = oscale; + return value; +} + +/** + Parse an unsigned floating-point number from this stream of tokenized + characters. Example floating-point formats supported: + 12.34 + 12 + 0.34 + .34 + 12.34e-4 + */ +static GLfloat +parse_float (GLubyte ** inst, struct arb_program *Program) +{ + GLint exponent; + GLdouble whole, fraction, fracScale = 1.0; + + whole = parse_float_string(inst, Program, 0); + fraction = parse_float_string(inst, Program, &fracScale); + + /* Parse signed exponent */ + exponent = parse_integer(inst, Program); /* This is the exponent */ + + /* Assemble parts of floating-point number: */ + return (GLfloat) ((whole + fraction / fracScale) * + _mesa_pow(10.0, (GLfloat) exponent)); +} + + +/** + */ +static GLfloat +parse_signed_float (GLubyte ** inst, struct arb_program *Program) +{ + GLint sign = parse_sign (inst); + GLfloat value = parse_float (inst, Program); + return value * sign; +} + +/** + * This picks out a constant value from the parsed array. The constant vector is r + * returned in the *values array, which should be of length 4. + * + * \param values - The 4 component vector with the constant value in it + */ +static GLvoid +parse_constant (GLubyte ** inst, GLfloat *values, struct arb_program *Program, + GLboolean use) +{ + GLuint components, i; + + + switch (*(*inst)++) { + case CONSTANT_SCALAR: + if (use == GL_TRUE) { + values[0] = + values[1] = + values[2] = values[3] = parse_float (inst, Program); + } + else { + values[0] = + values[1] = + values[2] = values[3] = parse_signed_float (inst, Program); + } + + break; + case CONSTANT_VECTOR: + values[0] = values[1] = values[2] = 0; + values[3] = 1; + components = *(*inst)++; + for (i = 0; i < components; i++) { + values[i] = parse_signed_float (inst, Program); + } + break; + } +} + +/** + * \param offset The offset from the address register that we should + * address + * + * \return 0 on sucess, 1 on error + */ +static GLuint +parse_relative_offset (GLcontext *ctx, GLubyte **inst, struct arb_program *Program, + GLint *offset) +{ + *offset = parse_integer(inst, Program); + return 0; +} + +/** + * \param color 0 if color type is primary, 1 if color type is secondary + * \return 0 on sucess, 1 on error + */ +static GLuint +parse_color_type (GLcontext * ctx, GLubyte ** inst, struct arb_program *Program, + GLint * color) +{ + (void) ctx; (void) Program; + *color = *(*inst)++ != COLOR_PRIMARY; + return 0; +} + +/** + * Get an integer corresponding to a generic vertex attribute. + * + * \return 0 on sucess, 1 on error + */ +static GLuint +parse_generic_attrib_num(GLcontext *ctx, GLubyte ** inst, + struct arb_program *Program, GLuint *attrib) +{ + GLint i = parse_integer(inst, Program); + + if ((i < 0) || (i > MAX_VERTEX_PROGRAM_ATTRIBS)) + { + _mesa_set_program_error (ctx, Program->Position, + "Invalid generic vertex attribute index"); + _mesa_error (ctx, GL_INVALID_OPERATION, "Invalid generic vertex attribute index"); + + return 1; + } + + *attrib = (GLuint) i; + + return 0; +} + + +/** + * \param color The index of the color buffer to write into + * \return 0 on sucess, 1 on error + */ +static GLuint +parse_output_color_num (GLcontext * ctx, GLubyte ** inst, + struct arb_program *Program, GLuint * color) +{ + GLint i = parse_integer (inst, Program); + + if ((i < 0) || (i >= (int)ctx->Const.MaxDrawBuffers)) { + _mesa_set_program_error (ctx, Program->Position, + "Invalid draw buffer index"); + _mesa_error (ctx, GL_INVALID_OPERATION, "Invalid draw buffer index"); + return 1; + } + + *color = (GLuint) i; + return 0; +} + + +/** + * \param coord The texture unit index + * \return 0 on sucess, 1 on error + */ +static GLuint +parse_texcoord_num (GLcontext * ctx, GLubyte ** inst, + struct arb_program *Program, GLuint * coord) +{ + GLint i = parse_integer (inst, Program); + + if ((i < 0) || (i >= (int)ctx->Const.MaxTextureUnits)) { + _mesa_set_program_error (ctx, Program->Position, + "Invalid texture unit index"); + _mesa_error (ctx, GL_INVALID_OPERATION, "Invalid texture unit index"); + return 1; + } + + *coord = (GLuint) i; + return 0; +} + +/** + * \param coord The weight index + * \return 0 on sucess, 1 on error + */ +static GLuint +parse_weight_num (GLcontext * ctx, GLubyte ** inst, struct arb_program *Program, + GLint * coord) +{ + *coord = parse_integer (inst, Program); + + if ((*coord < 0) || (*coord >= 1)) { + _mesa_set_program_error (ctx, Program->Position, + "Invalid weight index"); + _mesa_error (ctx, GL_INVALID_OPERATION, "Invalid weight index"); + return 1; + } + + return 0; +} + +/** + * \param coord The clip plane index + * \return 0 on sucess, 1 on error + */ +static GLuint +parse_clipplane_num (GLcontext * ctx, GLubyte ** inst, + struct arb_program *Program, GLint * coord) +{ + *coord = parse_integer (inst, Program); + + if ((*coord < 0) || (*coord >= (GLint) ctx->Const.MaxClipPlanes)) { + _mesa_set_program_error (ctx, Program->Position, + "Invalid clip plane index"); + _mesa_error (ctx, GL_INVALID_OPERATION, "Invalid clip plane index"); + return 1; + } + + return 0; +} + + +/** + * \return 0 on front face, 1 on back face + */ +static GLuint +parse_face_type (GLubyte ** inst) +{ + switch (*(*inst)++) { + case FACE_FRONT: + return 0; + + case FACE_BACK: + return 1; + } + return 0; +} + + +/** + * Given a matrix and a modifier token on the binary array, return tokens + * that _mesa_fetch_state() [program.c] can understand. + * + * \param matrix - the matrix we are talking about + * \param matrix_idx - the index of the matrix we have (for texture & program matricies) + * \param matrix_modifier - the matrix modifier (trans, inv, etc) + * \return 0 on sucess, 1 on failure + */ +static GLuint +parse_matrix (GLcontext * ctx, GLubyte ** inst, struct arb_program *Program, + GLint * matrix, GLint * matrix_idx, GLint * matrix_modifier) +{ + GLubyte mat = *(*inst)++; + + *matrix_idx = 0; + + switch (mat) { + case MATRIX_MODELVIEW: + *matrix = STATE_MODELVIEW; + *matrix_idx = parse_integer (inst, Program); + if (*matrix_idx > 0) { + _mesa_set_program_error (ctx, Program->Position, + "ARB_vertex_blend not supported\n"); + _mesa_error (ctx, GL_INVALID_OPERATION, + "ARB_vertex_blend not supported\n"); + return 1; + } + break; + + case MATRIX_PROJECTION: + *matrix = STATE_PROJECTION; + break; + + case MATRIX_MVP: + *matrix = STATE_MVP; + break; + + case MATRIX_TEXTURE: + *matrix = STATE_TEXTURE; + *matrix_idx = parse_integer (inst, Program); + if (*matrix_idx >= (GLint) ctx->Const.MaxTextureUnits) { + _mesa_set_program_error (ctx, Program->Position, + "Invalid Texture Unit"); + _mesa_error (ctx, GL_INVALID_OPERATION, + "Invalid Texture Unit: %d", *matrix_idx); + return 1; + } + break; + + /* This is not currently supported (ARB_matrix_palette) */ + case MATRIX_PALETTE: + *matrix_idx = parse_integer (inst, Program); + _mesa_set_program_error (ctx, Program->Position, + "ARB_matrix_palette not supported\n"); + _mesa_error (ctx, GL_INVALID_OPERATION, + "ARB_matrix_palette not supported\n"); + return 1; + break; + + case MATRIX_PROGRAM: + *matrix = STATE_PROGRAM; + *matrix_idx = parse_integer (inst, Program); + if (*matrix_idx >= (GLint) ctx->Const.MaxProgramMatrices) { + _mesa_set_program_error (ctx, Program->Position, + "Invalid Program Matrix"); + _mesa_error (ctx, GL_INVALID_OPERATION, + "Invalid Program Matrix: %d", *matrix_idx); + return 1; + } + break; + } + + switch (*(*inst)++) { + case MATRIX_MODIFIER_IDENTITY: + *matrix_modifier = 0; + break; + case MATRIX_MODIFIER_INVERSE: + *matrix_modifier = STATE_MATRIX_INVERSE; + break; + case MATRIX_MODIFIER_TRANSPOSE: + *matrix_modifier = STATE_MATRIX_TRANSPOSE; + break; + case MATRIX_MODIFIER_INVTRANS: + *matrix_modifier = STATE_MATRIX_INVTRANS; + break; + } + + return 0; +} + + +/** + * This parses a state string (rather, the binary version of it) into + * a 6-token sequence as described in _mesa_fetch_state() [program.c] + * + * \param inst - the start in the binary arry to start working from + * \param state_tokens - the storage for the 6-token state description + * \return - 0 on sucess, 1 on error + */ +static GLuint +parse_state_single_item (GLcontext * ctx, GLubyte ** inst, + struct arb_program *Program, GLint * state_tokens) +{ + switch (*(*inst)++) { + case STATE_MATERIAL_PARSER: + state_tokens[0] = STATE_MATERIAL; + state_tokens[1] = parse_face_type (inst); + switch (*(*inst)++) { + case MATERIAL_AMBIENT: + state_tokens[2] = STATE_AMBIENT; + break; + case MATERIAL_DIFFUSE: + state_tokens[2] = STATE_DIFFUSE; + break; + case MATERIAL_SPECULAR: + state_tokens[2] = STATE_SPECULAR; + break; + case MATERIAL_EMISSION: + state_tokens[2] = STATE_EMISSION; + break; + case MATERIAL_SHININESS: + state_tokens[2] = STATE_SHININESS; + break; + } + break; + + case STATE_LIGHT_PARSER: + state_tokens[0] = STATE_LIGHT; + state_tokens[1] = parse_integer (inst, Program); + + /* Check the value of state_tokens[1] against the # of lights */ + if (state_tokens[1] >= (GLint) ctx->Const.MaxLights) { + _mesa_set_program_error (ctx, Program->Position, + "Invalid Light Number"); + _mesa_error (ctx, GL_INVALID_OPERATION, + "Invalid Light Number: %d", state_tokens[1]); + return 1; + } + + switch (*(*inst)++) { + case LIGHT_AMBIENT: + state_tokens[2] = STATE_AMBIENT; + break; + case LIGHT_DIFFUSE: + state_tokens[2] = STATE_DIFFUSE; + break; + case LIGHT_SPECULAR: + state_tokens[2] = STATE_SPECULAR; + break; + case LIGHT_POSITION: + state_tokens[2] = STATE_POSITION; + break; + case LIGHT_ATTENUATION: + state_tokens[2] = STATE_ATTENUATION; + break; + case LIGHT_HALF: + state_tokens[2] = STATE_HALF; + break; + case LIGHT_SPOT_DIRECTION: + state_tokens[2] = STATE_SPOT_DIRECTION; + break; + } + break; + + case STATE_LIGHT_MODEL: + switch (*(*inst)++) { + case LIGHT_MODEL_AMBIENT: + state_tokens[0] = STATE_LIGHTMODEL_AMBIENT; + break; + case LIGHT_MODEL_SCENECOLOR: + state_tokens[0] = STATE_LIGHTMODEL_SCENECOLOR; + state_tokens[1] = parse_face_type (inst); + break; + } + break; + + case STATE_LIGHT_PROD: + state_tokens[0] = STATE_LIGHTPROD; + state_tokens[1] = parse_integer (inst, Program); + + /* Check the value of state_tokens[1] against the # of lights */ + if (state_tokens[1] >= (GLint) ctx->Const.MaxLights) { + _mesa_set_program_error (ctx, Program->Position, + "Invalid Light Number"); + _mesa_error (ctx, GL_INVALID_OPERATION, + "Invalid Light Number: %d", state_tokens[1]); + return 1; + } + + state_tokens[2] = parse_face_type (inst); + switch (*(*inst)++) { + case LIGHT_PROD_AMBIENT: + state_tokens[3] = STATE_AMBIENT; + break; + case LIGHT_PROD_DIFFUSE: + state_tokens[3] = STATE_DIFFUSE; + break; + case LIGHT_PROD_SPECULAR: + state_tokens[3] = STATE_SPECULAR; + break; + } + break; + + + case STATE_FOG: + switch (*(*inst)++) { + case FOG_COLOR: + state_tokens[0] = STATE_FOG_COLOR; + break; + case FOG_PARAMS: + state_tokens[0] = STATE_FOG_PARAMS; + break; + } + break; + + case STATE_TEX_ENV: + state_tokens[1] = parse_integer (inst, Program); + switch (*(*inst)++) { + case TEX_ENV_COLOR: + state_tokens[0] = STATE_TEXENV_COLOR; + break; + } + break; + + case STATE_TEX_GEN: + { + GLuint type, coord; + + state_tokens[0] = STATE_TEXGEN; + /*state_tokens[1] = parse_integer (inst, Program);*/ /* Texture Unit */ + + if (parse_texcoord_num (ctx, inst, Program, &coord)) + return 1; + state_tokens[1] = coord; + + /* EYE or OBJECT */ + type = *(*inst++); + + /* 0 - s, 1 - t, 2 - r, 3 - q */ + coord = *(*inst++); + + if (type == TEX_GEN_EYE) { + switch (coord) { + case COMPONENT_X: + state_tokens[2] = STATE_TEXGEN_EYE_S; + break; + case COMPONENT_Y: + state_tokens[2] = STATE_TEXGEN_EYE_T; + break; + case COMPONENT_Z: + state_tokens[2] = STATE_TEXGEN_EYE_R; + break; + case COMPONENT_W: + state_tokens[2] = STATE_TEXGEN_EYE_Q; + break; + } + } + else { + switch (coord) { + case COMPONENT_X: + state_tokens[2] = STATE_TEXGEN_OBJECT_S; + break; + case COMPONENT_Y: + state_tokens[2] = STATE_TEXGEN_OBJECT_T; + break; + case COMPONENT_Z: + state_tokens[2] = STATE_TEXGEN_OBJECT_R; + break; + case COMPONENT_W: + state_tokens[2] = STATE_TEXGEN_OBJECT_Q; + break; + } + } + } + break; + + case STATE_DEPTH: + switch (*(*inst)++) { + case DEPTH_RANGE: + state_tokens[0] = STATE_DEPTH_RANGE; + break; + } + break; + + case STATE_CLIP_PLANE: + state_tokens[0] = STATE_CLIPPLANE; + state_tokens[1] = parse_integer (inst, Program); + if (parse_clipplane_num (ctx, inst, Program, &state_tokens[1])) + return 1; + break; + + case STATE_POINT: + switch (*(*inst++)) { + case POINT_SIZE: + state_tokens[0] = STATE_POINT_SIZE; + break; + + case POINT_ATTENUATION: + state_tokens[0] = STATE_POINT_ATTENUATION; + break; + } + break; + + /* XXX: I think this is the correct format for a matrix row */ + case STATE_MATRIX_ROWS: + state_tokens[0] = STATE_MATRIX; + if (parse_matrix + (ctx, inst, Program, &state_tokens[1], &state_tokens[2], + &state_tokens[5])) + return 1; + + state_tokens[3] = parse_integer (inst, Program); /* The first row to grab */ + + if ((**inst) != 0) { /* Either the last row, 0 */ + state_tokens[4] = parse_integer (inst, Program); + if (state_tokens[4] < state_tokens[3]) { + _mesa_set_program_error (ctx, Program->Position, + "Second matrix index less than the first"); + _mesa_error (ctx, GL_INVALID_OPERATION, + "Second matrix index (%d) less than the first (%d)", + state_tokens[4], state_tokens[3]); + return 1; + } + } + else { + state_tokens[4] = state_tokens[3]; + (*inst)++; + } + break; + } + + return 0; +} + +/** + * This parses a state string (rather, the binary version of it) into + * a 6-token similar for the state fetching code in program.c + * + * One might ask, why fetch these parameters into just like you fetch + * state when they are already stored in other places? + * + * Because of array offsets -> We can stick env/local parameters in the + * middle of a parameter array and then index someplace into the array + * when we execute. + * + * One optimization might be to only do this for the cases where the + * env/local parameters end up inside of an array, and leave the + * single parameters (or arrays of pure env/local pareameters) in their + * respective register files. + * + * For ENV parameters, the format is: + * state_tokens[0] = STATE_FRAGMENT_PROGRAM / STATE_VERTEX_PROGRAM + * state_tokens[1] = STATE_ENV + * state_tokens[2] = the parameter index + * + * for LOCAL parameters, the format is: + * state_tokens[0] = STATE_FRAGMENT_PROGRAM / STATE_VERTEX_PROGRAM + * state_tokens[1] = STATE_LOCAL + * state_tokens[2] = the parameter index + * + * \param inst - the start in the binary arry to start working from + * \param state_tokens - the storage for the 6-token state description + * \return - 0 on sucess, 1 on failure + */ +static GLuint +parse_program_single_item (GLcontext * ctx, GLubyte ** inst, + struct arb_program *Program, GLint * state_tokens) +{ + if (Program->Base.Target == GL_FRAGMENT_PROGRAM_ARB) + state_tokens[0] = STATE_FRAGMENT_PROGRAM; + else + state_tokens[0] = STATE_VERTEX_PROGRAM; + + + switch (*(*inst)++) { + case PROGRAM_PARAM_ENV: + state_tokens[1] = STATE_ENV; + state_tokens[2] = parse_integer (inst, Program); + + /* Check state_tokens[2] against the number of ENV parameters available */ + if (((Program->Base.Target == GL_FRAGMENT_PROGRAM_ARB) && + (state_tokens[2] >= (GLint) ctx->Const.MaxFragmentProgramEnvParams)) + || + ((Program->Base.Target == GL_VERTEX_PROGRAM_ARB) && + (state_tokens[2] >= (GLint) ctx->Const.MaxVertexProgramEnvParams))) { + _mesa_set_program_error (ctx, Program->Position, + "Invalid Program Env Parameter"); + _mesa_error (ctx, GL_INVALID_OPERATION, + "Invalid Program Env Parameter: %d", + state_tokens[2]); + return 1; + } + + break; + + case PROGRAM_PARAM_LOCAL: + state_tokens[1] = STATE_LOCAL; + state_tokens[2] = parse_integer (inst, Program); + + /* Check state_tokens[2] against the number of LOCAL parameters available */ + if (((Program->Base.Target == GL_FRAGMENT_PROGRAM_ARB) && + (state_tokens[2] >= (GLint) ctx->Const.MaxFragmentProgramLocalParams)) + || + ((Program->Base.Target == GL_VERTEX_PROGRAM_ARB) && + (state_tokens[2] >= (GLint) ctx->Const.MaxVertexProgramLocalParams))) { + _mesa_set_program_error (ctx, Program->Position, + "Invalid Program Local Parameter"); + _mesa_error (ctx, GL_INVALID_OPERATION, + "Invalid Program Local Parameter: %d", + state_tokens[2]); + return 1; + } + break; + } + + return 0; +} + +/** + * For ARB_vertex_program, programs are not allowed to use both an explicit + * vertex attribute and a generic vertex attribute corresponding to the same + * state. See section 2.14.3.1 of the GL_ARB_vertex_program spec. + * + * This will walk our var_cache and make sure that nobody does anything fishy. + * + * \return 0 on sucess, 1 on error + */ +static GLuint +generic_attrib_check(struct var_cache *vc_head) +{ + int a; + struct var_cache *curr; + GLboolean explicitAttrib[MAX_VERTEX_PROGRAM_ATTRIBS], + genericAttrib[MAX_VERTEX_PROGRAM_ATTRIBS]; + + for (a=0; a<MAX_VERTEX_PROGRAM_ATTRIBS; a++) { + explicitAttrib[a] = GL_FALSE; + genericAttrib[a] = GL_FALSE; + } + + curr = vc_head; + while (curr) { + if (curr->type == vt_attrib) { + if (curr->attrib_is_generic) + genericAttrib[ curr->attrib_binding_idx ] = GL_TRUE; + else + explicitAttrib[ curr->attrib_binding_idx ] = GL_TRUE; + } + + curr = curr->next; + } + + for (a=0; a<MAX_VERTEX_PROGRAM_ATTRIBS; a++) { + if ((explicitAttrib[a]) && (genericAttrib[a])) + return 1; + } + + return 0; +} + +/** + * This will handle the binding side of an ATTRIB var declaration + * + * \param binding - the fragment input register state, defined in nvfragprog.h + * \param binding_idx - the index in the attrib register file that binding is associated with + * \return returns 0 on sucess, 1 on error + * + * See nvfragparse.c for attrib register file layout + */ +static GLuint +parse_attrib_binding (GLcontext * ctx, GLubyte ** inst, + struct arb_program *Program, GLuint * binding, + GLuint * binding_idx, GLuint *is_generic) +{ + GLuint texcoord; + GLint coord; + GLint err = 0; + + *is_generic = 0; + if (Program->Base.Target == GL_FRAGMENT_PROGRAM_ARB) { + switch (*(*inst)++) { + case FRAGMENT_ATTRIB_COLOR: + err = parse_color_type (ctx, inst, Program, &coord); + *binding = FRAG_ATTRIB_COL0 + coord; + *binding_idx = 1 + coord; + break; + + case FRAGMENT_ATTRIB_TEXCOORD: + err = parse_texcoord_num (ctx, inst, Program, &texcoord); + *binding = FRAG_ATTRIB_TEX0 + texcoord; + *binding_idx = 4 + texcoord; + break; + + case FRAGMENT_ATTRIB_FOGCOORD: + *binding = FRAG_ATTRIB_FOGC; + *binding_idx = 3; + break; + + case FRAGMENT_ATTRIB_POSITION: + *binding = FRAG_ATTRIB_WPOS; + *binding_idx = 0; + break; + + default: + err = 1; + break; + } + } + else { + switch (*(*inst)++) { + case VERTEX_ATTRIB_POSITION: + *binding = VERT_ATTRIB_POS; + *binding_idx = 0; + break; + + case VERTEX_ATTRIB_WEIGHT: + { + GLint weight; + + err = parse_weight_num (ctx, inst, Program, &weight); + *binding = VERT_ATTRIB_WEIGHT; + *binding_idx = 1; + } + _mesa_set_program_error (ctx, Program->Position, + "ARB_vertex_blend not supported\n"); + _mesa_error (ctx, GL_INVALID_OPERATION, + "ARB_vertex_blend not supported\n"); + return 1; + break; + + case VERTEX_ATTRIB_NORMAL: + *binding = VERT_ATTRIB_NORMAL; + *binding_idx = 2; + break; + + case VERTEX_ATTRIB_COLOR: + { + GLint color; + + err = parse_color_type (ctx, inst, Program, &color); + if (color) { + *binding = VERT_ATTRIB_COLOR1; + *binding_idx = 4; + } + else { + *binding = VERT_ATTRIB_COLOR0; + *binding_idx = 3; + } + } + break; + + case VERTEX_ATTRIB_FOGCOORD: + *binding = VERT_ATTRIB_FOG; + *binding_idx = 5; + break; + + case VERTEX_ATTRIB_TEXCOORD: + { + GLuint unit; + + err = parse_texcoord_num (ctx, inst, Program, &unit); + *binding = VERT_ATTRIB_TEX0 + unit; + *binding_idx = 8 + unit; + } + break; + + /* It looks like we don't support this at all, atm */ + case VERTEX_ATTRIB_MATRIXINDEX: + parse_integer (inst, Program); + _mesa_set_program_error (ctx, Program->Position, + "ARB_palette_matrix not supported"); + _mesa_error (ctx, GL_INVALID_OPERATION, + "ARB_palette_matrix not supported"); + return 1; + break; + + case VERTEX_ATTRIB_GENERIC: + { + GLuint attrib; + + if (!parse_generic_attrib_num(ctx, inst, Program, &attrib)) { + *is_generic = 1; + switch (attrib) { + case 0: + *binding = VERT_ATTRIB_POS; + break; + case 1: + *binding = VERT_ATTRIB_WEIGHT; + break; + case 2: + *binding = VERT_ATTRIB_NORMAL; + break; + case 3: + *binding = VERT_ATTRIB_COLOR0; + break; + case 4: + *binding = VERT_ATTRIB_COLOR1; + break; + case 5: + *binding = VERT_ATTRIB_FOG; + break; + case 6: + break; + case 7: + break; + default: + *binding = VERT_ATTRIB_TEX0 + (attrib-8); + break; + } + *binding_idx = attrib; + } + } + break; + + default: + err = 1; + break; + } + } + + /* Can this even happen? */ + if (err) { + _mesa_set_program_error (ctx, Program->Position, + "Bad attribute binding"); + _mesa_error (ctx, GL_INVALID_OPERATION, "Bad attribute binding"); + } + + Program->InputsRead |= (1 << *binding_idx); + + return err; +} + +/** + * This translates between a binary token for an output variable type + * and the mesa token for the same thing. + * + * + * XXX: What is the 'name' for vertex program state? -> do we need it? + * I don't think we do; + * + * See nvfragprog.h for definitions + * + * \param inst - The parsed tokens + * \param binding - The name of the state we are binding too + * \param binding_idx - The index into the result register file that this is bound too + * + * See nvfragparse.c for the register file layout for fragment programs + * See nvvertparse.c for the register file layout for vertex programs + */ +static GLuint +parse_result_binding (GLcontext * ctx, GLubyte ** inst, GLuint * binding, + GLuint * binding_idx, struct arb_program *Program) +{ + GLuint b, out_color; + + switch (*(*inst)++) { + case FRAGMENT_RESULT_COLOR: + /* for frag programs, this is FRAGMENT_RESULT_COLOR */ + if (Program->Base.Target == GL_FRAGMENT_PROGRAM_ARB) { + /* This gets result of the color buffer we're supposed to + * draw into + */ + parse_output_color_num(ctx, inst, Program, &out_color); + + *binding = FRAG_OUTPUT_COLR; + + /* XXX: We're ignoring the color buffer for now. */ + *binding_idx = 0; + } + /* for vtx programs, this is VERTEX_RESULT_POSITION */ + else { + *binding_idx = 0; + } + break; + + case FRAGMENT_RESULT_DEPTH: + /* for frag programs, this is FRAGMENT_RESULT_DEPTH */ + if (Program->Base.Target == GL_FRAGMENT_PROGRAM_ARB) { + *binding = FRAG_OUTPUT_DEPR; + *binding_idx = 2; + } + /* for vtx programs, this is VERTEX_RESULT_COLOR */ + else { + GLint color_type; + GLuint face_type = parse_face_type(inst); + GLint color_type_ret = parse_color_type(ctx, inst, Program, &color_type); + + /* back face */ + if (face_type) { + if (color_type_ret) return 1; + + /* secondary color */ + if (color_type) { + *binding_idx = 4; + } + /* primary color */ + else { + *binding_idx = 3; + } + } + /* front face */ + else { + /* secondary color */ + if (color_type) { + *binding_idx = 2; + } + /* primary color */ + else { + *binding_idx = 1; + } + } + } + break; + + case VERTEX_RESULT_FOGCOORD: + *binding_idx = 5; + break; + + case VERTEX_RESULT_POINTSIZE: + *binding_idx = 6; + break; + + case VERTEX_RESULT_TEXCOORD: + if (parse_texcoord_num (ctx, inst, Program, &b)) + return 1; + *binding_idx = 7 + b; + break; + } + + Program->OutputsWritten |= (1 << *binding_idx); + + return 0; +} + +/** + * This handles the declaration of ATTRIB variables + * + * XXX: Still needs + * parse_vert_attrib_binding(), or something like that + * + * \return 0 on sucess, 1 on error + */ +static GLint +parse_attrib (GLcontext * ctx, GLubyte ** inst, struct var_cache **vc_head, + struct arb_program *Program) +{ + GLuint found; + char *error_msg; + struct var_cache *attrib_var; + + attrib_var = parse_string (inst, vc_head, Program, &found); + Program->Position = parse_position (inst); + if (found) { + error_msg = (char *) + _mesa_malloc (_mesa_strlen ((char *) attrib_var->name) + 40); + _mesa_sprintf (error_msg, "Duplicate Varible Declaration: %s", + attrib_var->name); + + _mesa_set_program_error (ctx, Program->Position, error_msg); + _mesa_error (ctx, GL_INVALID_OPERATION, error_msg); + + _mesa_free (error_msg); + return 1; + } + + attrib_var->type = vt_attrib; + + /* I think this is ok now - karl */ + /* XXX: */ + /*if (Program->type == GL_FRAGMENT_PROGRAM_ARB) */ + { + if (parse_attrib_binding + (ctx, inst, Program, &attrib_var->attrib_binding, + &attrib_var->attrib_binding_idx, &attrib_var->attrib_is_generic)) + return 1; + if (generic_attrib_check(*vc_head)) { + _mesa_set_program_error (ctx, Program->Position, + "Cannot use both a generic vertex attribute and a specific attribute of the same type"); + _mesa_error (ctx, GL_INVALID_OPERATION, + "Cannot use both a generic vertex attribute and a specific attribute of the same type"); + return 1; + } + + } + + Program->Base.NumAttributes++; + return 0; +} + +/** + * \param use -- TRUE if we're called when declaring implicit parameters, + * FALSE if we're declaraing variables. This has to do with + * if we get a signed or unsigned float for scalar constants + */ +static GLuint +parse_param_elements (GLcontext * ctx, GLubyte ** inst, + struct var_cache *param_var, + struct arb_program *Program, GLboolean use) +{ + GLint idx; + GLuint err; + GLint state_tokens[6]; + GLfloat const_values[4]; + + err = 0; + + switch (*(*inst)++) { + case PARAM_STATE_ELEMENT: + + if (parse_state_single_item (ctx, inst, Program, state_tokens)) + return 1; + + /* If we adding STATE_MATRIX that has multiple rows, we need to + * unroll it and call _mesa_add_state_reference() for each row + */ + if ((state_tokens[0] == STATE_MATRIX) + && (state_tokens[3] != state_tokens[4])) { + GLint row; + GLint first_row = state_tokens[3]; + GLint last_row = state_tokens[4]; + + for (row = first_row; row <= last_row; row++) { + state_tokens[3] = state_tokens[4] = row; + + idx = + _mesa_add_state_reference (Program->Parameters, + state_tokens); + if (param_var->param_binding_begin == ~0U) + param_var->param_binding_begin = idx; + param_var->param_binding_length++; + Program->Base.NumParameters++; + } + } + else { + idx = + _mesa_add_state_reference (Program->Parameters, state_tokens); + if (param_var->param_binding_begin == ~0U) + param_var->param_binding_begin = idx; + param_var->param_binding_length++; + Program->Base.NumParameters++; + } + break; + + case PARAM_PROGRAM_ELEMENT: + + if (parse_program_single_item (ctx, inst, Program, state_tokens)) + return 1; + idx = _mesa_add_state_reference (Program->Parameters, state_tokens); + if (param_var->param_binding_begin == ~0U) + param_var->param_binding_begin = idx; + param_var->param_binding_length++; + Program->Base.NumParameters++; + + /* Check if there is more: 0 -> we're done, else its an integer */ + if (**inst) { + GLuint out_of_range, new_idx; + GLuint start_idx = state_tokens[2] + 1; + GLuint end_idx = parse_integer (inst, Program); + + out_of_range = 0; + if (Program->Base.Target == GL_FRAGMENT_PROGRAM_ARB) { + if (((state_tokens[1] == STATE_ENV) + && (end_idx >= ctx->Const.MaxFragmentProgramEnvParams)) + || ((state_tokens[1] == STATE_LOCAL) + && (end_idx >= + ctx->Const.MaxFragmentProgramLocalParams))) + out_of_range = 1; + } + else { + if (((state_tokens[1] == STATE_ENV) + && (end_idx >= ctx->Const.MaxVertexProgramEnvParams)) + || ((state_tokens[1] == STATE_LOCAL) + && (end_idx >= + ctx->Const.MaxVertexProgramLocalParams))) + out_of_range = 1; + } + if (out_of_range) { + _mesa_set_program_error (ctx, Program->Position, + "Invalid Program Parameter"); + _mesa_error (ctx, GL_INVALID_OPERATION, + "Invalid Program Parameter: %d", end_idx); + return 1; + } + + for (new_idx = start_idx; new_idx <= end_idx; new_idx++) { + state_tokens[2] = new_idx; + idx = + _mesa_add_state_reference (Program->Parameters, + state_tokens); + param_var->param_binding_length++; + Program->Base.NumParameters++; + } + } + else + { + (*inst)++; + } + break; + + case PARAM_CONSTANT: + parse_constant (inst, const_values, Program, use); + idx = + _mesa_add_named_constant (Program->Parameters, + (char *) param_var->name, const_values); + if (param_var->param_binding_begin == ~0U) + param_var->param_binding_begin = idx; + param_var->param_binding_length++; + Program->Base.NumParameters++; + break; + + default: + _mesa_set_program_error (ctx, Program->Position, + "Unexpected token in parse_param_elements()"); + _mesa_error (ctx, GL_INVALID_OPERATION, + "Unexpected token in parse_param_elements()"); + return 1; + } + + /* Make sure we haven't blown past our parameter limits */ + if (((Program->Base.Target == GL_VERTEX_PROGRAM_ARB) && + (Program->Base.NumParameters >= + ctx->Const.MaxVertexProgramLocalParams)) + || ((Program->Base.Target == GL_FRAGMENT_PROGRAM_ARB) + && (Program->Base.NumParameters >= + ctx->Const.MaxFragmentProgramLocalParams))) { + _mesa_set_program_error (ctx, Program->Position, + "Too many parameter variables"); + _mesa_error (ctx, GL_INVALID_OPERATION, "Too many parameter variables"); + return 1; + } + + return err; +} + +/** + * This picks out PARAM program parameter bindings. + * + * XXX: This needs to be stressed & tested + * + * \return 0 on sucess, 1 on error + */ +static GLuint +parse_param (GLcontext * ctx, GLubyte ** inst, struct var_cache **vc_head, + struct arb_program *Program) +{ + GLuint found, err; + GLint specified_length; + char *error_msg; + struct var_cache *param_var; + + err = 0; + param_var = parse_string (inst, vc_head, Program, &found); + Program->Position = parse_position (inst); + + if (found) { + error_msg = (char *) _mesa_malloc (_mesa_strlen ((char *) param_var->name) + 40); + _mesa_sprintf (error_msg, "Duplicate Varible Declaration: %s", + param_var->name); + + _mesa_set_program_error (ctx, Program->Position, error_msg); + _mesa_error (ctx, GL_INVALID_OPERATION, error_msg); + + _mesa_free (error_msg); + return 1; + } + + specified_length = parse_integer (inst, Program); + + if (specified_length < 0) { + _mesa_set_program_error (ctx, Program->Position, + "Negative parameter array length"); + _mesa_error (ctx, GL_INVALID_OPERATION, + "Negative parameter array length: %d", specified_length); + return 1; + } + + param_var->type = vt_param; + param_var->param_binding_length = 0; + + /* Right now, everything is shoved into the main state register file. + * + * In the future, it would be nice to leave things ENV/LOCAL params + * in their respective register files, if possible + */ + param_var->param_binding_type = PROGRAM_STATE_VAR; + + /* Remember to: + * * - add each guy to the parameter list + * * - increment the param_var->param_binding_len + * * - store the param_var->param_binding_begin for the first one + * * - compare the actual len to the specified len at the end + */ + while (**inst != PARAM_NULL) { + if (parse_param_elements (ctx, inst, param_var, Program, GL_FALSE)) + return 1; + } + + /* Test array length here! */ + if (specified_length) { + if (specified_length != (int)param_var->param_binding_length) { + _mesa_set_program_error (ctx, Program->Position, + "Declared parameter array length does not match parameter list"); + _mesa_error (ctx, GL_INVALID_OPERATION, + "Declared parameter array length does not match parameter list"); + } + } + + (*inst)++; + + return 0; +} + +/** + * + */ +static GLuint +parse_param_use (GLcontext * ctx, GLubyte ** inst, struct var_cache **vc_head, + struct arb_program *Program, struct var_cache **new_var) +{ + struct var_cache *param_var; + + /* First, insert a dummy entry into the var_cache */ + var_cache_create (¶m_var); + param_var->name = (GLubyte *) _mesa_strdup (" "); + param_var->type = vt_param; + + param_var->param_binding_length = 0; + /* Don't fill in binding_begin; We use the default value of -1 + * to tell if its already initialized, elsewhere. + * + * param_var->param_binding_begin = 0; + */ + param_var->param_binding_type = PROGRAM_STATE_VAR; + + var_cache_append (vc_head, param_var); + + /* Then fill it with juicy parameter goodness */ + if (parse_param_elements (ctx, inst, param_var, Program, GL_TRUE)) + return 1; + + *new_var = param_var; + + return 0; +} + + +/** + * This handles the declaration of TEMP variables + * + * \return 0 on sucess, 1 on error + */ +static GLuint +parse_temp (GLcontext * ctx, GLubyte ** inst, struct var_cache **vc_head, + struct arb_program *Program) +{ + GLuint found; + struct var_cache *temp_var; + char *error_msg; + + while (**inst != 0) { + temp_var = parse_string (inst, vc_head, Program, &found); + Program->Position = parse_position (inst); + if (found) { + error_msg = (char *) + _mesa_malloc (_mesa_strlen ((char *) temp_var->name) + 40); + _mesa_sprintf (error_msg, "Duplicate Varible Declaration: %s", + temp_var->name); + + _mesa_set_program_error (ctx, Program->Position, error_msg); + _mesa_error (ctx, GL_INVALID_OPERATION, error_msg); + + _mesa_free (error_msg); + return 1; + } + + temp_var->type = vt_temp; + + if (((Program->Base.Target == GL_FRAGMENT_PROGRAM_ARB) && + (Program->Base.NumTemporaries >= + ctx->Const.MaxFragmentProgramTemps)) + || ((Program->Base.Target == GL_VERTEX_PROGRAM_ARB) + && (Program->Base.NumTemporaries >= + ctx->Const.MaxVertexProgramTemps))) { + _mesa_set_program_error (ctx, Program->Position, + "Too many TEMP variables declared"); + _mesa_error (ctx, GL_INVALID_OPERATION, + "Too many TEMP variables declared"); + return 1; + } + + temp_var->temp_binding = Program->Base.NumTemporaries; + Program->Base.NumTemporaries++; + } + (*inst)++; + + return 0; +} + +/** + * This handles variables of the OUTPUT variety + * + * \return 0 on sucess, 1 on error + */ +static GLuint +parse_output (GLcontext * ctx, GLubyte ** inst, struct var_cache **vc_head, + struct arb_program *Program) +{ + GLuint found; + struct var_cache *output_var; + + output_var = parse_string (inst, vc_head, Program, &found); + Program->Position = parse_position (inst); + if (found) { + char *error_msg; + error_msg = (char *) + _mesa_malloc (_mesa_strlen ((char *) output_var->name) + 40); + _mesa_sprintf (error_msg, "Duplicate Varible Declaration: %s", + output_var->name); + + _mesa_set_program_error (ctx, Program->Position, error_msg); + _mesa_error (ctx, GL_INVALID_OPERATION, error_msg); + + _mesa_free (error_msg); + return 1; + } + + output_var->type = vt_output; + return parse_result_binding (ctx, inst, &output_var->output_binding, + &output_var->output_binding_idx, Program); +} + +/** + * This handles variables of the ALIAS kind + * + * \return 0 on sucess, 1 on error + */ +static GLuint +parse_alias (GLcontext * ctx, GLubyte ** inst, struct var_cache **vc_head, + struct arb_program *Program) +{ + GLuint found; + struct var_cache *temp_var; + char *error_msg; + + + temp_var = parse_string (inst, vc_head, Program, &found); + Program->Position = parse_position (inst); + + if (found) { + error_msg = (char *) + _mesa_malloc (_mesa_strlen ((char *) temp_var->name) + 40); + _mesa_sprintf (error_msg, "Duplicate Varible Declaration: %s", + temp_var->name); + + _mesa_set_program_error (ctx, Program->Position, error_msg); + _mesa_error (ctx, GL_INVALID_OPERATION, error_msg); + + _mesa_free (error_msg); + return 1; + } + + temp_var->type = vt_alias; + temp_var->alias_binding = parse_string (inst, vc_head, Program, &found); + Program->Position = parse_position (inst); + + if (!found) + { + error_msg = (char *) + _mesa_malloc (_mesa_strlen ((char *) temp_var->name) + 40); + _mesa_sprintf (error_msg, "Alias value %s is not defined", + temp_var->alias_binding->name); + + _mesa_set_program_error (ctx, Program->Position, error_msg); + _mesa_error (ctx, GL_INVALID_OPERATION, error_msg); + + _mesa_free (error_msg); + return 1; + } + + return 0; +} + +/** + * This handles variables of the ADDRESS kind + * + * \return 0 on sucess, 1 on error + */ +static GLuint +parse_address (GLcontext * ctx, GLubyte ** inst, struct var_cache **vc_head, + struct arb_program *Program) +{ + GLuint found; + struct var_cache *temp_var; + char *error_msg; + + while (**inst != 0) { + temp_var = parse_string (inst, vc_head, Program, &found); + Program->Position = parse_position (inst); + if (found) { + error_msg = (char *) + _mesa_malloc (_mesa_strlen ((char *) temp_var->name) + 40); + _mesa_sprintf (error_msg, "Duplicate Varible Declaration: %s", + temp_var->name); + + _mesa_set_program_error (ctx, Program->Position, error_msg); + _mesa_error (ctx, GL_INVALID_OPERATION, error_msg); + + _mesa_free (error_msg); + return 1; + } + + temp_var->type = vt_address; + + if (Program->Base.NumAddressRegs >= + ctx->Const.MaxVertexProgramAddressRegs) { + _mesa_set_program_error (ctx, Program->Position, + "Too many ADDRESS variables declared"); + _mesa_error (ctx, GL_INVALID_OPERATION, + "Too many ADDRESS variables declared"); + return 1; + } + + temp_var->address_binding = Program->Base.NumAddressRegs; + Program->Base.NumAddressRegs++; + } + (*inst)++; + + return 0; +} + +/** + * Parse a program declaration + * + * \return 0 on sucess, 1 on error + */ +static GLint +parse_declaration (GLcontext * ctx, GLubyte ** inst, struct var_cache **vc_head, + struct arb_program *Program) +{ + GLint err = 0; + + switch (*(*inst)++) { + case ADDRESS: + err = parse_address (ctx, inst, vc_head, Program); + break; + + case ALIAS: + err = parse_alias (ctx, inst, vc_head, Program); + break; + + case ATTRIB: + err = parse_attrib (ctx, inst, vc_head, Program); + break; + + case OUTPUT: + err = parse_output (ctx, inst, vc_head, Program); + break; + + case PARAM: + err = parse_param (ctx, inst, vc_head, Program); + break; + + case TEMP: + err = parse_temp (ctx, inst, vc_head, Program); + break; + } + + return err; +} + +/** + * Handle the parsing out of a masked destination register + * + * If we are a vertex program, make sure we don't write to + * result.position of we have specified that the program is + * position invariant + * + * \param File - The register file we write to + * \param Index - The register index we write to + * \param WriteMask - The mask controlling which components we write (1->write) + * + * \return 0 on sucess, 1 on error + */ +static GLuint +parse_masked_dst_reg (GLcontext * ctx, GLubyte ** inst, + struct var_cache **vc_head, struct arb_program *Program, + GLint * File, GLint * Index, GLint *WriteMask) +{ + GLuint result, tmp; + struct var_cache *dst; + + /* We either have a result register specified, or a + * variable that may or may not be writable + */ + switch (*(*inst)++) { + case REGISTER_RESULT: + if (parse_result_binding + (ctx, inst, &result, (GLuint *) Index, Program)) + return 1; + *File = PROGRAM_OUTPUT; + break; + + case REGISTER_ESTABLISHED_NAME: + dst = parse_string (inst, vc_head, Program, &result); + Program->Position = parse_position (inst); + + /* If the name has never been added to our symbol table, we're hosed */ + if (!result) { + _mesa_set_program_error (ctx, Program->Position, + "0: Undefined variable"); + _mesa_error (ctx, GL_INVALID_OPERATION, "0: Undefined variable: %s", + dst->name); + return 1; + } + + switch (dst->type) { + case vt_output: + *File = PROGRAM_OUTPUT; + *Index = dst->output_binding_idx; + break; + + case vt_temp: + *File = PROGRAM_TEMPORARY; + *Index = dst->temp_binding; + break; + + /* If the var type is not vt_output or vt_temp, no go */ + default: + _mesa_set_program_error (ctx, Program->Position, + "Destination register is read only"); + _mesa_error (ctx, GL_INVALID_OPERATION, + "Destination register is read only: %s", + dst->name); + return 1; + } + break; + + default: + _mesa_set_program_error (ctx, Program->Position, + "Unexpected opcode in parse_masked_dst_reg()"); + _mesa_error (ctx, GL_INVALID_OPERATION, + "Unexpected opcode in parse_masked_dst_reg()"); + return 1; + } + + + /* Position invariance test */ + /* This test is done now in syntax portion - when position invariance OPTION + is specified, "result.position" rule is disabled so there is no way + to write the position + */ + /*if ((Program->HintPositionInvariant) && (*File == PROGRAM_OUTPUT) && + (*Index == 0)) { + _mesa_set_program_error (ctx, Program->Position, + "Vertex program specified position invariance and wrote vertex position"); + _mesa_error (ctx, GL_INVALID_OPERATION, + "Vertex program specified position invariance and wrote vertex position"); + }*/ + + /* And then the mask. + * w,a -> bit 0 + * z,b -> bit 1 + * y,g -> bit 2 + * x,r -> bit 3 + * + * ==> Need to reverse the order of bits for this! + */ + tmp = (GLint) *(*inst)++; + *WriteMask = (((tmp>>3) & 0x1) | + ((tmp>>1) & 0x2) | + ((tmp<<1) & 0x4) | + ((tmp<<3) & 0x8)); + + return 0; +} + + +/** + * Handle the parsing of a address register + * + * \param Index - The register index we write to + * + * \return 0 on sucess, 1 on error + */ +static GLuint +parse_address_reg (GLcontext * ctx, GLubyte ** inst, + struct var_cache **vc_head, + struct arb_program *Program, GLint * Index) +{ + struct var_cache *dst; + GLuint result; + (void) Index; + + dst = parse_string (inst, vc_head, Program, &result); + Program->Position = parse_position (inst); + + /* If the name has never been added to our symbol table, we're hosed */ + if (!result) { + _mesa_set_program_error (ctx, Program->Position, "Undefined variable"); + _mesa_error (ctx, GL_INVALID_OPERATION, "Undefined variable: %s", + dst->name); + return 1; + } + + if (dst->type != vt_address) { + _mesa_set_program_error (ctx, Program->Position, + "Variable is not of type ADDRESS"); + _mesa_error (ctx, GL_INVALID_OPERATION, + "Variable: %s is not of type ADDRESS", dst->name); + return 1; + } + + return 0; +} + +#if 0 /* unused */ +/** + * Handle the parsing out of a masked address register + * + * \param Index - The register index we write to + * \param WriteMask - The mask controlling which components we write (1->write) + * + * \return 0 on sucess, 1 on error + */ +static GLuint +parse_masked_address_reg (GLcontext * ctx, GLubyte ** inst, + struct var_cache **vc_head, + struct arb_program *Program, GLint * Index, + GLboolean * WriteMask) +{ + if (parse_address_reg (ctx, inst, vc_head, Program, Index)) + return 1; + + /* This should be 0x8 */ + (*inst)++; + + /* Writemask of .x is implied */ + WriteMask[0] = 1; + WriteMask[1] = WriteMask[2] = WriteMask[3] = 0; + + return 0; +} +#endif + +/** + * Parse out a swizzle mask. + * + * The values in the input stream are: + * COMPONENT_X -> x/r + * COMPONENT_Y -> y/g + * COMPONENT_Z-> z/b + * COMPONENT_W-> w/a + * + * The values in the output mask are: + * 0 -> x/r + * 1 -> y/g + * 2 -> z/b + * 3 -> w/a + * + * The len parameter allows us to grab 4 components for a vector + * swizzle, or just 1 component for a scalar src register selection + */ +static GLuint +parse_swizzle_mask (GLubyte ** inst, GLubyte * mask, GLint len) +{ + GLint a; + + for (a = 0; a < 4; a++) + mask[a] = a; + + for (a = 0; a < len; a++) { + switch (*(*inst)++) { + case COMPONENT_X: + mask[a] = 0; + break; + + case COMPONENT_Y: + mask[a] = 1; + break; + + case COMPONENT_Z: + mask[a] = 2; + break; + + case COMPONENT_W: + mask[a] = 3; + break; + } + } + + return 0; +} + +/** + */ +static GLuint +parse_extended_swizzle_mask(GLubyte **inst, GLubyte *mask, GLubyte *negate) +{ + GLint a; + GLubyte swz; + + *negate = 0x0; + for (a = 0; a < 4; a++) { + if (parse_sign (inst) == -1) + *negate |= (1 << a); + + swz = *(*inst)++; + + switch (swz) { + case COMPONENT_0: + mask[a] = SWIZZLE_ZERO; + break; + case COMPONENT_1: + mask[a] = SWIZZLE_ONE; + break; + case COMPONENT_X: + mask[a] = SWIZZLE_X; + break; + case COMPONENT_Y: + mask[a] = SWIZZLE_Y; + break; + case COMPONENT_Z: + mask[a] = SWIZZLE_Z; + break; + case COMPONENT_W: + mask[a] = SWIZZLE_W; + break; + + } +#if 0 + if (swz == 0) + mask[a] = SWIZZLE_ZERO; + else if (swz == 1) + mask[a] = SWIZZLE_ONE; + else + mask[a] = swz - 2; +#endif + + } + + return 0; +} + + +static GLuint +parse_src_reg (GLcontext * ctx, GLubyte ** inst, struct var_cache **vc_head, + struct arb_program *Program, GLint * File, GLint * Index, + GLboolean *IsRelOffset ) +{ + struct var_cache *src; + GLuint binding_state, binding_idx, is_generic, found; + GLint offset; + + *IsRelOffset = 0; + + /* And the binding for the src */ + switch (*(*inst)++) { + case REGISTER_ATTRIB: + if (parse_attrib_binding + (ctx, inst, Program, &binding_state, &binding_idx, &is_generic)) + return 1; + *File = PROGRAM_INPUT; + *Index = binding_idx; + + /* We need to insert a dummy variable into the var_cache so we can + * catch generic vertex attrib aliasing errors + */ + var_cache_create(&src); + src->type = vt_attrib; + src->name = (GLubyte *)_mesa_strdup("Dummy Attrib Variable"); + src->attrib_binding = binding_state; + src->attrib_binding_idx = binding_idx; + src->attrib_is_generic = is_generic; + var_cache_append(vc_head, src); + if (generic_attrib_check(*vc_head)) { + _mesa_set_program_error (ctx, Program->Position, + "Cannot use both a generic vertex attribute and a specific attribute of the same type"); + _mesa_error (ctx, GL_INVALID_OPERATION, + "Cannot use both a generic vertex attribute and a specific attribute of the same type"); + return 1; + } + break; + + case REGISTER_PARAM: + switch (**inst) { + case PARAM_ARRAY_ELEMENT: + (*inst)++; + src = parse_string (inst, vc_head, Program, &found); + Program->Position = parse_position (inst); + + if (!found) { + _mesa_set_program_error (ctx, Program->Position, + "2: Undefined variable"); + _mesa_error (ctx, GL_INVALID_OPERATION, + "2: Undefined variable: %s", src->name); + return 1; + } + + *File = src->param_binding_type; + + switch (*(*inst)++) { + case ARRAY_INDEX_ABSOLUTE: + offset = parse_integer (inst, Program); + + if ((offset < 0) + || (offset >= (int)src->param_binding_length)) { + _mesa_set_program_error (ctx, Program->Position, + "Index out of range"); + _mesa_error (ctx, GL_INVALID_OPERATION, + "Index %d out of range for %s", offset, + src->name); + return 1; + } + + *Index = src->param_binding_begin + offset; + break; + + case ARRAY_INDEX_RELATIVE: + { + GLint addr_reg_idx, rel_off; + + /* First, grab the address regiseter */ + if (parse_address_reg (ctx, inst, vc_head, Program, &addr_reg_idx)) + return 1; + + /* And the .x */ + ((*inst)++); + ((*inst)++); + ((*inst)++); + ((*inst)++); + + /* Then the relative offset */ + if (parse_relative_offset(ctx, inst, Program, &rel_off)) return 1; + + /* And store it properly */ + *Index = src->param_binding_begin + rel_off; + *IsRelOffset = 1; + } + break; + } + break; + + default: + + if (parse_param_use (ctx, inst, vc_head, Program, &src)) + return 1; + + *File = src->param_binding_type; + *Index = src->param_binding_begin; + break; + } + break; + + case REGISTER_ESTABLISHED_NAME: + + src = parse_string (inst, vc_head, Program, &found); + Program->Position = parse_position (inst); + + /* If the name has never been added to our symbol table, we're hosed */ + if (!found) { + _mesa_set_program_error (ctx, Program->Position, + "3: Undefined variable"); + _mesa_error (ctx, GL_INVALID_OPERATION, "3: Undefined variable: %s", + src->name); + return 1; + } + + switch (src->type) { + case vt_attrib: + *File = PROGRAM_INPUT; + *Index = src->attrib_binding_idx; + break; + + /* XXX: We have to handle offsets someplace in here! -- or are those above? */ + case vt_param: + *File = src->param_binding_type; + *Index = src->param_binding_begin; + break; + + case vt_temp: + *File = PROGRAM_TEMPORARY; + *Index = src->temp_binding; + break; + + /* If the var type is vt_output no go */ + default: + _mesa_set_program_error (ctx, Program->Position, + "destination register is read only"); + _mesa_error (ctx, GL_INVALID_OPERATION, + "destination register is read only: %s", + src->name); + return 1; + } + break; + + default: + _mesa_set_program_error (ctx, Program->Position, + "Unknown token in parse_src_reg"); + _mesa_error (ctx, GL_INVALID_OPERATION, + "Unknown token in parse_src_reg"); + return 1; + } + + return 0; +} + +/** + */ +static GLuint +parse_fp_vector_src_reg (GLcontext * ctx, GLubyte ** inst, + struct var_cache **vc_head, struct arb_program *Program, + struct fp_src_register *reg ) +{ + + GLint File; + GLint Index; + GLboolean Negate; + GLubyte Swizzle[4]; + GLboolean IsRelOffset; + + /* Grab the sign */ + Negate = (parse_sign (inst) == -1) ? 0xf : 0x0; + + /* And the src reg */ + if (parse_src_reg (ctx, inst, vc_head, Program, &File, &Index, &IsRelOffset)) + return 1; + + /* finally, the swizzle */ + parse_swizzle_mask (inst, Swizzle, 4); + + reg->File = File; + reg->Index = Index; + reg->Abs = 0; /* NV only */ + reg->NegateAbs = 0; /* NV only */ + reg->NegateBase = Negate; + reg->Swizzle = (Swizzle[0] << 0 | + Swizzle[1] << 3 | + Swizzle[2] << 6 | + Swizzle[3] << 9); + + return 0; +} + + +static GLuint +parse_fp_dst_reg(GLcontext * ctx, GLubyte ** inst, + struct var_cache **vc_head, struct arb_program *Program, + struct fp_dst_register *reg ) +{ + GLint file, idx, mask; + + if (parse_masked_dst_reg (ctx, inst, vc_head, Program, &file, &idx, &mask)) + return 1; + + reg->CondMask = 0; /* NV only */ + reg->CondSwizzle = 0; /* NV only */ + reg->File = file; + reg->Index = idx; + reg->WriteMask = mask; + return 0; +} + + + +static GLuint +parse_fp_scalar_src_reg (GLcontext * ctx, GLubyte ** inst, + struct var_cache **vc_head, struct arb_program *Program, + struct fp_src_register *reg ) +{ + + GLint File; + GLint Index; + GLboolean Negate; + GLubyte Swizzle[4]; + GLboolean IsRelOffset; + + /* Grab the sign */ + Negate = (parse_sign (inst) == -1) ? 0x1 : 0x0; + + /* And the src reg */ + if (parse_src_reg (ctx, inst, vc_head, Program, &File, &Index, &IsRelOffset)) + return 1; + + /* finally, the swizzle */ + parse_swizzle_mask (inst, Swizzle, 1); + + reg->File = File; + reg->Index = Index; + reg->Abs = 0; /* NV only */ + reg->NegateAbs = 0; /* NV only */ + reg->NegateBase = Negate; + reg->Swizzle = (Swizzle[0] << 0); + + return 0; +} + + +/** + * This is a big mother that handles getting opcodes into the instruction + * and handling the src & dst registers for fragment program instructions + */ +static GLuint +parse_fp_instruction (GLcontext * ctx, GLubyte ** inst, + struct var_cache **vc_head, struct arb_program *Program, + struct fp_instruction *fp) +{ + GLint a; + GLuint texcoord; + GLubyte instClass, type, code; + GLboolean rel; + + /* No condition codes in ARB_fp */ + fp->UpdateCondRegister = 0; + + /* Record the position in the program string for debugging */ + fp->StringPos = Program->Position; + + fp->Data = NULL; + + fp->DstReg.File = 0xf; /* mark as undef */ + fp->SrcReg[0].File = 0xf; /* mark as undef */ + fp->SrcReg[1].File = 0xf; /* mark as undef */ + fp->SrcReg[2].File = 0xf; /* mark as undef */ + + /* OP_ALU_INST or OP_TEX_INST */ + instClass = *(*inst)++; + + /* OP_ALU_{VECTOR, SCALAR, BINSC, BIN, TRI, SWZ}, + * OP_TEX_{SAMPLE, KIL} + */ + type = *(*inst)++; + + /* The actual opcode name */ + code = *(*inst)++; + + /* Increment the correct count */ + switch (instClass) { + case OP_ALU_INST: + Program->NumAluInstructions++; + break; + case OP_TEX_INST: + Program->NumTexInstructions++; + break; + } + + fp->Saturate = 0; + fp->Precision = FLOAT32; + + fp->DstReg.CondMask = COND_TR; + + switch (type) { + case OP_ALU_VECTOR: + switch (code) { + case OP_ABS_SAT: + fp->Saturate = 1; + case OP_ABS: + fp->Opcode = FP_OPCODE_ABS; + break; + + case OP_FLR_SAT: + fp->Saturate = 1; + case OP_FLR: + fp->Opcode = FP_OPCODE_FLR; + break; + + case OP_FRC_SAT: + fp->Saturate = 1; + case OP_FRC: + fp->Opcode = FP_OPCODE_FRC; + break; + + case OP_LIT_SAT: + fp->Saturate = 1; + case OP_LIT: + fp->Opcode = FP_OPCODE_LIT; + break; + + case OP_MOV_SAT: + fp->Saturate = 1; + case OP_MOV: + fp->Opcode = FP_OPCODE_MOV; + break; + } + + if (parse_fp_dst_reg (ctx, inst, vc_head, Program, &fp->DstReg)) + return 1; + + if (parse_fp_vector_src_reg(ctx, inst, vc_head, Program, &fp->SrcReg[0])) + return 1; + break; + + case OP_ALU_SCALAR: + switch (code) { + case OP_COS_SAT: + fp->Saturate = 1; + case OP_COS: + fp->Opcode = FP_OPCODE_COS; + break; + + case OP_EX2_SAT: + fp->Saturate = 1; + case OP_EX2: + fp->Opcode = FP_OPCODE_EX2; + break; + + case OP_LG2_SAT: + fp->Saturate = 1; + case OP_LG2: + fp->Opcode = FP_OPCODE_LG2; + break; + + case OP_RCP_SAT: + fp->Saturate = 1; + case OP_RCP: + fp->Opcode = FP_OPCODE_RCP; + break; + + case OP_RSQ_SAT: + fp->Saturate = 1; + case OP_RSQ: + fp->Opcode = FP_OPCODE_RSQ; + break; + + case OP_SIN_SAT: + fp->Saturate = 1; + case OP_SIN: + fp->Opcode = FP_OPCODE_SIN; + break; + + case OP_SCS_SAT: + fp->Saturate = 1; + case OP_SCS: + + fp->Opcode = FP_OPCODE_SCS; + break; + } + + if (parse_fp_dst_reg (ctx, inst, vc_head, Program, &fp->DstReg)) + return 1; + + if (parse_fp_scalar_src_reg(ctx, inst, vc_head, Program, &fp->SrcReg[0])) + return 1; + break; + + case OP_ALU_BINSC: + switch (code) { + case OP_POW_SAT: + fp->Saturate = 1; + case OP_POW: + fp->Opcode = FP_OPCODE_POW; + break; + } + + if (parse_fp_dst_reg(ctx, inst, vc_head, Program, &fp->DstReg)) + return 1; + + for (a = 0; a < 2; a++) { + if (parse_fp_scalar_src_reg(ctx, inst, vc_head, Program, &fp->SrcReg[a])) + return 1; + } + break; + + + case OP_ALU_BIN: + switch (code) { + case OP_ADD_SAT: + fp->Saturate = 1; + case OP_ADD: + fp->Opcode = FP_OPCODE_ADD; + break; + + case OP_DP3_SAT: + fp->Saturate = 1; + case OP_DP3: + fp->Opcode = FP_OPCODE_DP3; + break; + + case OP_DP4_SAT: + fp->Saturate = 1; + case OP_DP4: + fp->Opcode = FP_OPCODE_DP4; + break; + + case OP_DPH_SAT: + fp->Saturate = 1; + case OP_DPH: + fp->Opcode = FP_OPCODE_DPH; + break; + + case OP_DST_SAT: + fp->Saturate = 1; + case OP_DST: + fp->Opcode = FP_OPCODE_DST; + break; + + case OP_MAX_SAT: + fp->Saturate = 1; + case OP_MAX: + fp->Opcode = FP_OPCODE_MAX; + break; + + case OP_MIN_SAT: + fp->Saturate = 1; + case OP_MIN: + fp->Opcode = FP_OPCODE_MIN; + break; + + case OP_MUL_SAT: + fp->Saturate = 1; + case OP_MUL: + fp->Opcode = FP_OPCODE_MUL; + break; + + case OP_SGE_SAT: + fp->Saturate = 1; + case OP_SGE: + fp->Opcode = FP_OPCODE_SGE; + break; + + case OP_SLT_SAT: + fp->Saturate = 1; + case OP_SLT: + fp->Opcode = FP_OPCODE_SLT; + break; + + case OP_SUB_SAT: + fp->Saturate = 1; + case OP_SUB: + fp->Opcode = FP_OPCODE_SUB; + break; + + case OP_XPD_SAT: + fp->Saturate = 1; + case OP_XPD: + fp->Opcode = FP_OPCODE_XPD; + break; + } + + if (parse_fp_dst_reg (ctx, inst, vc_head, Program, &fp->DstReg)) + return 1; + for (a = 0; a < 2; a++) { + if (parse_fp_vector_src_reg(ctx, inst, vc_head, Program, &fp->SrcReg[a])) + return 1; + } + break; + + case OP_ALU_TRI: + switch (code) { + case OP_CMP_SAT: + fp->Saturate = 1; + case OP_CMP: + fp->Opcode = FP_OPCODE_CMP; + break; + + case OP_LRP_SAT: + fp->Saturate = 1; + case OP_LRP: + fp->Opcode = FP_OPCODE_LRP; + break; + + case OP_MAD_SAT: + fp->Saturate = 1; + case OP_MAD: + fp->Opcode = FP_OPCODE_MAD; + break; + } + + if (parse_fp_dst_reg (ctx, inst, vc_head, Program, &fp->DstReg)) + return 1; + + for (a = 0; a < 3; a++) { + if (parse_fp_vector_src_reg(ctx, inst, vc_head, Program, &fp->SrcReg[a])) + return 1; + } + break; + + case OP_ALU_SWZ: + switch (code) { + case OP_SWZ_SAT: + fp->Saturate = 1; + case OP_SWZ: + fp->Opcode = FP_OPCODE_SWZ; + break; + } + if (parse_fp_dst_reg (ctx, inst, vc_head, Program, &fp->DstReg)) + return 1; + + { + GLubyte Swizzle[4]; /* FP's swizzle mask is a GLubyte, while VP's is GLuint */ + GLubyte negateMask; + GLint File, Index; + + if (parse_src_reg(ctx, inst, vc_head, Program, &File, &Index, &rel)) + return 1; + parse_extended_swizzle_mask (inst, Swizzle, &negateMask); + fp->SrcReg[0].File = File; + fp->SrcReg[0].Index = Index; + fp->SrcReg[0].NegateBase = negateMask; + fp->SrcReg[0].Swizzle = (Swizzle[0] << 0 | + Swizzle[1] << 3 | + Swizzle[2] << 6 | + Swizzle[3] << 9); + } + break; + + case OP_TEX_SAMPLE: + switch (code) { + case OP_TEX_SAT: + fp->Saturate = 1; + case OP_TEX: + fp->Opcode = FP_OPCODE_TEX; + break; + + case OP_TXP_SAT: + fp->Saturate = 1; + case OP_TXP: + fp->Opcode = FP_OPCODE_TXP; + break; + + case OP_TXB_SAT: + fp->Saturate = 1; + case OP_TXB: + fp->Opcode = FP_OPCODE_TXB; + break; + } + + if (parse_fp_dst_reg (ctx, inst, vc_head, Program, &fp->DstReg)) + return 1; + + if (parse_fp_vector_src_reg(ctx, inst, vc_head, Program, &fp->SrcReg[0])) + return 1; + + /* texImageUnit */ + if (parse_texcoord_num (ctx, inst, Program, &texcoord)) + return 1; + fp->TexSrcUnit = texcoord; + + /* texTarget */ + switch (*(*inst)++) { + case TEXTARGET_1D: + fp->TexSrcIdx = TEXTURE_1D_INDEX; + break; + case TEXTARGET_2D: + fp->TexSrcIdx = TEXTURE_2D_INDEX; + break; + case TEXTARGET_3D: + fp->TexSrcIdx = TEXTURE_3D_INDEX; + break; + case TEXTARGET_RECT: + fp->TexSrcIdx = TEXTURE_RECT_INDEX; + break; + case TEXTARGET_CUBE: + fp->TexSrcIdx = TEXTURE_CUBE_INDEX; + break; + case TEXTARGET_SHADOW1D: + case TEXTARGET_SHADOW2D: + case TEXTARGET_SHADOWRECT: + /* TODO ARB_fragment_program_shadow code */ + break; + } + Program->TexturesUsed[texcoord] |= (1<<fp->TexSrcIdx); + break; + + case OP_TEX_KIL: + if (parse_fp_vector_src_reg(ctx, inst, vc_head, Program, &fp->SrcReg[0])) + return 1; + fp->Opcode = FP_OPCODE_KIL; + break; + } + + return 0; +} + +static GLuint +parse_vp_dst_reg(GLcontext * ctx, GLubyte ** inst, + struct var_cache **vc_head, struct arb_program *Program, + struct vp_dst_register *reg ) +{ + GLint file, idx, mask; + + if (parse_masked_dst_reg(ctx, inst, vc_head, Program, &file, &idx, &mask)) + return 1; + + reg->File = file; + reg->Index = idx; + reg->WriteMask = mask; + return 0; +} + +/** + * Handle the parsing out of a masked address register + * + * \param Index - The register index we write to + * \param WriteMask - The mask controlling which components we write (1->write) + * + * \return 0 on sucess, 1 on error + */ +static GLuint +parse_vp_address_reg (GLcontext * ctx, GLubyte ** inst, + struct var_cache **vc_head, + struct arb_program *Program, + struct vp_dst_register *reg) +{ + GLint idx; + + if (parse_address_reg (ctx, inst, vc_head, Program, &idx)) + return 1; + + /* This should be 0x8 */ + (*inst)++; + + reg->File = PROGRAM_ADDRESS; + reg->Index = idx; + + /* Writemask of .x is implied */ + reg->WriteMask = 0x1; + return 0; +} + +/** + */ +static GLuint +parse_vp_vector_src_reg (GLcontext * ctx, GLubyte ** inst, + struct var_cache **vc_head, struct arb_program *Program, + struct vp_src_register *reg ) +{ + + GLint File; + GLint Index; + GLboolean Negate; + GLubyte Swizzle[4]; + GLboolean IsRelOffset; + + /* Grab the sign */ + Negate = (parse_sign (inst) == -1) ? 0xf : 0x0; + + /* And the src reg */ + if (parse_src_reg (ctx, inst, vc_head, Program, &File, &Index, &IsRelOffset)) + return 1; + + /* finally, the swizzle */ + parse_swizzle_mask (inst, Swizzle, 4); + + reg->File = File; + reg->Index = Index; + reg->Swizzle = ((Swizzle[0] << 0) | + (Swizzle[1] << 3) | + (Swizzle[2] << 6) | + (Swizzle[3] << 9)); + reg->Negate = Negate; + reg->RelAddr = IsRelOffset; + return 0; +} + + +static GLuint +parse_vp_scalar_src_reg (GLcontext * ctx, GLubyte ** inst, + struct var_cache **vc_head, struct arb_program *Program, + struct vp_src_register *reg ) +{ + + GLint File; + GLint Index; + GLboolean Negate; + GLubyte Swizzle[4]; + GLboolean IsRelOffset; + + /* Grab the sign */ + Negate = (parse_sign (inst) == -1) ? 0x1 : 0x0; + + /* And the src reg */ + if (parse_src_reg (ctx, inst, vc_head, Program, &File, &Index, &IsRelOffset)) + return 1; + + /* finally, the swizzle */ + parse_swizzle_mask (inst, Swizzle, 1); + + reg->File = File; + reg->Index = Index; + reg->Swizzle = (Swizzle[0] << 0); + reg->Negate = Negate; + reg->RelAddr = IsRelOffset; + return 0; +} + + +/** + * This is a big mother that handles getting opcodes into the instruction + * and handling the src & dst registers for vertex program instructions + */ +static GLuint +parse_vp_instruction (GLcontext * ctx, GLubyte ** inst, + struct var_cache **vc_head, struct arb_program *Program, + struct vp_instruction *vp) +{ + GLint a; + GLubyte type, code; + + /* OP_ALU_{ARL, VECTOR, SCALAR, BINSC, BIN, TRI, SWZ} */ + type = *(*inst)++; + + /* The actual opcode name */ + code = *(*inst)++; + + /* Record the position in the program string for debugging */ + vp->StringPos = Program->Position; + vp->Data = NULL; + vp->SrcReg[0].RelAddr = vp->SrcReg[1].RelAddr = vp->SrcReg[2].RelAddr = 0; + vp->SrcReg[0].Swizzle = SWIZZLE_NOOP; + vp->SrcReg[1].Swizzle = SWIZZLE_NOOP; + vp->SrcReg[2].Swizzle = SWIZZLE_NOOP; + vp->DstReg.WriteMask = 0xf; + + switch (type) { + /* XXX: */ + case OP_ALU_ARL: + vp->Opcode = VP_OPCODE_ARL; + + /* Remember to set SrcReg.RelAddr; */ + + /* Get the masked address register [dst] */ + if (parse_vp_address_reg(ctx, inst, vc_head, Program, &vp->DstReg)) + return 1; + + vp->DstReg.File = PROGRAM_ADDRESS; + + /* Get a scalar src register */ + if (parse_vp_scalar_src_reg(ctx, inst, vc_head, Program, &vp->SrcReg[0])) + return 1; + + break; + + case OP_ALU_VECTOR: + switch (code) { + case OP_ABS: + vp->Opcode = VP_OPCODE_ABS; + break; + case OP_FLR: + vp->Opcode = VP_OPCODE_FLR; + break; + case OP_FRC: + vp->Opcode = VP_OPCODE_FRC; + break; + case OP_LIT: + vp->Opcode = VP_OPCODE_LIT; + break; + case OP_MOV: + vp->Opcode = VP_OPCODE_MOV; + break; + } + + if (parse_vp_dst_reg(ctx, inst, vc_head, Program, &vp->DstReg)) + return 1; + + if (parse_vp_vector_src_reg(ctx, inst, vc_head, Program, &vp->SrcReg[0])) + return 1; + break; + + case OP_ALU_SCALAR: + switch (code) { + case OP_EX2: + vp->Opcode = VP_OPCODE_EX2; + break; + case OP_EXP: + vp->Opcode = VP_OPCODE_EXP; + break; + case OP_LG2: + vp->Opcode = VP_OPCODE_LG2; + break; + case OP_LOG: + vp->Opcode = VP_OPCODE_LOG; + break; + case OP_RCP: + vp->Opcode = VP_OPCODE_RCP; + break; + case OP_RSQ: + vp->Opcode = VP_OPCODE_RSQ; + break; + } + if (parse_vp_dst_reg(ctx, inst, vc_head, Program, &vp->DstReg)) + return 1; + + if (parse_vp_scalar_src_reg(ctx, inst, vc_head, Program, &vp->SrcReg[0])) + return 1; + break; + + case OP_ALU_BINSC: + switch (code) { + case OP_POW: + vp->Opcode = VP_OPCODE_POW; + break; + } + if (parse_vp_dst_reg(ctx, inst, vc_head, Program, &vp->DstReg)) + return 1; + + for (a = 0; a < 2; a++) { + if (parse_vp_scalar_src_reg(ctx, inst, vc_head, Program, &vp->SrcReg[a])) + return 1; + } + break; + + case OP_ALU_BIN: + switch (code) { + case OP_ADD: + vp->Opcode = VP_OPCODE_ADD; + break; + case OP_DP3: + vp->Opcode = VP_OPCODE_DP3; + break; + case OP_DP4: + vp->Opcode = VP_OPCODE_DP4; + break; + case OP_DPH: + vp->Opcode = VP_OPCODE_DPH; + break; + case OP_DST: + vp->Opcode = VP_OPCODE_DST; + break; + case OP_MAX: + vp->Opcode = VP_OPCODE_MAX; + break; + case OP_MIN: + vp->Opcode = VP_OPCODE_MIN; + break; + case OP_MUL: + vp->Opcode = VP_OPCODE_MUL; + break; + case OP_SGE: + vp->Opcode = VP_OPCODE_SGE; + break; + case OP_SLT: + vp->Opcode = VP_OPCODE_SLT; + break; + case OP_SUB: + vp->Opcode = VP_OPCODE_SUB; + break; + case OP_XPD: + vp->Opcode = VP_OPCODE_XPD; + break; + } + if (parse_vp_dst_reg(ctx, inst, vc_head, Program, &vp->DstReg)) + return 1; + + for (a = 0; a < 2; a++) { + if (parse_vp_vector_src_reg(ctx, inst, vc_head, Program, &vp->SrcReg[a])) + return 1; + } + break; + + case OP_ALU_TRI: + switch (code) { + case OP_MAD: + vp->Opcode = VP_OPCODE_MAD; + break; + } + + if (parse_vp_dst_reg(ctx, inst, vc_head, Program, &vp->DstReg)) + return 1; + + for (a = 0; a < 3; a++) { + if (parse_vp_vector_src_reg(ctx, inst, vc_head, Program, &vp->SrcReg[a])) + return 1; + } + break; + + case OP_ALU_SWZ: + switch (code) { + case OP_SWZ: + vp->Opcode = VP_OPCODE_SWZ; + break; + } + { + GLubyte Swizzle[4]; /* FP's swizzle mask is a GLubyte, while VP's is GLuint */ + GLubyte Negate[4]; + GLboolean RelAddr; + GLint File, Index; + + if (parse_vp_dst_reg(ctx, inst, vc_head, Program, &vp->DstReg)) + return 1; + + if (parse_src_reg(ctx, inst, vc_head, Program, &File, &Index, &RelAddr)) + return 1; + parse_extended_swizzle_mask (inst, Swizzle, Negate); + vp->SrcReg[0].File = File; + vp->SrcReg[0].Index = Index; + vp->SrcReg[0].Negate = (Negate[0] << 0 | + Negate[1] << 1 | + Negate[2] << 2 | + Negate[3] << 3); + vp->SrcReg[0].Swizzle = (Swizzle[0] << 0 | + Swizzle[1] << 3 | + Swizzle[2] << 6 | + Swizzle[3] << 9); + vp->SrcReg[0].RelAddr = RelAddr; + } + break; + } + return 0; +} + +#if DEBUG_PARSING + +static GLvoid +print_state_token (GLint token) +{ + switch (token) { + case STATE_MATERIAL: + fprintf (stderr, "STATE_MATERIAL "); + break; + case STATE_LIGHT: + fprintf (stderr, "STATE_LIGHT "); + break; + + case STATE_LIGHTMODEL_AMBIENT: + fprintf (stderr, "STATE_AMBIENT "); + break; + + case STATE_LIGHTMODEL_SCENECOLOR: + fprintf (stderr, "STATE_SCENECOLOR "); + break; + + case STATE_LIGHTPROD: + fprintf (stderr, "STATE_LIGHTPROD "); + break; + + case STATE_TEXGEN: + fprintf (stderr, "STATE_TEXGEN "); + break; + + case STATE_FOG_COLOR: + fprintf (stderr, "STATE_FOG_COLOR "); + break; + + case STATE_FOG_PARAMS: + fprintf (stderr, "STATE_FOG_PARAMS "); + break; + + case STATE_CLIPPLANE: + fprintf (stderr, "STATE_CLIPPLANE "); + break; + + case STATE_POINT_SIZE: + fprintf (stderr, "STATE_POINT_SIZE "); + break; + + case STATE_POINT_ATTENUATION: + fprintf (stderr, "STATE_ATTENUATION "); + break; + + case STATE_MATRIX: + fprintf (stderr, "STATE_MATRIX "); + break; + + case STATE_MODELVIEW: + fprintf (stderr, "STATE_MODELVIEW "); + break; + + case STATE_PROJECTION: + fprintf (stderr, "STATE_PROJECTION "); + break; + + case STATE_MVP: + fprintf (stderr, "STATE_MVP "); + break; + + case STATE_TEXTURE: + fprintf (stderr, "STATE_TEXTURE "); + break; + + case STATE_PROGRAM: + fprintf (stderr, "STATE_PROGRAM "); + break; + + case STATE_MATRIX_INVERSE: + fprintf (stderr, "STATE_INVERSE "); + break; + + case STATE_MATRIX_TRANSPOSE: + fprintf (stderr, "STATE_TRANSPOSE "); + break; + + case STATE_MATRIX_INVTRANS: + fprintf (stderr, "STATE_INVTRANS "); + break; + + case STATE_AMBIENT: + fprintf (stderr, "STATE_AMBIENT "); + break; + + case STATE_DIFFUSE: + fprintf (stderr, "STATE_DIFFUSE "); + break; + + case STATE_SPECULAR: + fprintf (stderr, "STATE_SPECULAR "); + break; + + case STATE_EMISSION: + fprintf (stderr, "STATE_EMISSION "); + break; + + case STATE_SHININESS: + fprintf (stderr, "STATE_SHININESS "); + break; + + case STATE_HALF: + fprintf (stderr, "STATE_HALF "); + break; + + case STATE_POSITION: + fprintf (stderr, "STATE_POSITION "); + break; + + case STATE_ATTENUATION: + fprintf (stderr, "STATE_ATTENUATION "); + break; + + case STATE_SPOT_DIRECTION: + fprintf (stderr, "STATE_DIRECTION "); + break; + + case STATE_TEXGEN_EYE_S: + fprintf (stderr, "STATE_TEXGEN_EYE_S "); + break; + + case STATE_TEXGEN_EYE_T: + fprintf (stderr, "STATE_TEXGEN_EYE_T "); + break; + + case STATE_TEXGEN_EYE_R: + fprintf (stderr, "STATE_TEXGEN_EYE_R "); + break; + + case STATE_TEXGEN_EYE_Q: + fprintf (stderr, "STATE_TEXGEN_EYE_Q "); + break; + + case STATE_TEXGEN_OBJECT_S: + fprintf (stderr, "STATE_TEXGEN_EYE_S "); + break; + + case STATE_TEXGEN_OBJECT_T: + fprintf (stderr, "STATE_TEXGEN_OBJECT_T "); + break; + + case STATE_TEXGEN_OBJECT_R: + fprintf (stderr, "STATE_TEXGEN_OBJECT_R "); + break; + + case STATE_TEXGEN_OBJECT_Q: + fprintf (stderr, "STATE_TEXGEN_OBJECT_Q "); + break; + + case STATE_TEXENV_COLOR: + fprintf (stderr, "STATE_TEXENV_COLOR "); + break; + + case STATE_DEPTH_RANGE: + fprintf (stderr, "STATE_DEPTH_RANGE "); + break; + + case STATE_VERTEX_PROGRAM: + fprintf (stderr, "STATE_VERTEX_PROGRAM "); + break; + + case STATE_FRAGMENT_PROGRAM: + fprintf (stderr, "STATE_FRAGMENT_PROGRAM "); + break; + + case STATE_ENV: + fprintf (stderr, "STATE_ENV "); + break; + + case STATE_LOCAL: + fprintf (stderr, "STATE_LOCAL "); + break; + + } + fprintf (stderr, "[%d] ", token); +} + + +static GLvoid +debug_variables (GLcontext * ctx, struct var_cache *vc_head, + struct arb_program *Program) +{ + struct var_cache *vc; + GLint a, b; + + fprintf (stderr, "debug_variables, vc_head: %x\n", vc_head); + + /* First of all, print out the contents of the var_cache */ + vc = vc_head; + while (vc) { + fprintf (stderr, "[%x]\n", vc); + switch (vc->type) { + case vt_none: + fprintf (stderr, "UNDEFINED %s\n", vc->name); + break; + case vt_attrib: + fprintf (stderr, "ATTRIB %s\n", vc->name); + fprintf (stderr, " binding: 0x%x\n", vc->attrib_binding); + break; + case vt_param: + fprintf (stderr, "PARAM %s begin: %d len: %d\n", vc->name, + vc->param_binding_begin, vc->param_binding_length); + b = vc->param_binding_begin; + for (a = 0; a < vc->param_binding_length; a++) { + fprintf (stderr, "%s\n", + Program->Parameters->Parameters[a + b].Name); + if (Program->Parameters->Parameters[a + b].Type == STATE) { + print_state_token (Program->Parameters->Parameters[a + b]. + StateIndexes[0]); + print_state_token (Program->Parameters->Parameters[a + b]. + StateIndexes[1]); + print_state_token (Program->Parameters->Parameters[a + b]. + StateIndexes[2]); + print_state_token (Program->Parameters->Parameters[a + b]. + StateIndexes[3]); + print_state_token (Program->Parameters->Parameters[a + b]. + StateIndexes[4]); + print_state_token (Program->Parameters->Parameters[a + b]. + StateIndexes[5]); + } + else + fprintf (stderr, "%f %f %f %f\n", + Program->Parameters->Parameters[a + b].Values[0], + Program->Parameters->Parameters[a + b].Values[1], + Program->Parameters->Parameters[a + b].Values[2], + Program->Parameters->Parameters[a + b].Values[3]); + } + break; + case vt_temp: + fprintf (stderr, "TEMP %s\n", vc->name); + fprintf (stderr, " binding: 0x%x\n", vc->temp_binding); + break; + case vt_output: + fprintf (stderr, "OUTPUT %s\n", vc->name); + fprintf (stderr, " binding: 0x%x\n", vc->output_binding); + break; + case vt_alias: + fprintf (stderr, "ALIAS %s\n", vc->name); + fprintf (stderr, " binding: 0x%x (%s)\n", + vc->alias_binding, vc->alias_binding->name); + break; + } + vc = vc->next; + } +} + +#endif + + +/** + * The main loop for parsing a fragment or vertex program + * + * \return GL_TRUE on success, GL_FALSE on error. + */ +static GLboolean +parse_arb_program(GLcontext * ctx, GLubyte * inst, struct var_cache **vc_head, + struct arb_program *Program) +{ + GLint err = 0; + + Program->MajorVersion = (GLuint) * inst++; + Program->MinorVersion = (GLuint) * inst++; + + while (*inst != END) { + switch (*inst++) { + + case OPTION: + switch (*inst++) { + case ARB_PRECISION_HINT_FASTEST: + Program->PrecisionOption = GL_FASTEST; + break; + + case ARB_PRECISION_HINT_NICEST: + Program->PrecisionOption = GL_NICEST; + break; + + case ARB_FOG_EXP: + Program->FogOption = GL_EXP; + break; + + case ARB_FOG_EXP2: + Program->FogOption = GL_EXP2; + break; + + case ARB_FOG_LINEAR: + Program->FogOption = GL_LINEAR; + break; + + case ARB_POSITION_INVARIANT: + if (Program->Base.Target == GL_VERTEX_PROGRAM_ARB) + Program->HintPositionInvariant = 1; + break; + + case ARB_FRAGMENT_PROGRAM_SHADOW: + if (Program->Base.Target == GL_FRAGMENT_PROGRAM_ARB) { + /* TODO ARB_fragment_program_shadow code */ + } + break; + + case ARB_DRAW_BUFFERS: + if (Program->Base.Target == GL_FRAGMENT_PROGRAM_ARB) { + /* do nothing for now */ + } + break; + } + break; + + case INSTRUCTION: + Program->Position = parse_position (&inst); + + if (Program->Base.Target == GL_FRAGMENT_PROGRAM_ARB) { + + /* Check the instruction count + * XXX: Does END count as an instruction? + */ + if (Program->Base.NumInstructions+1 == MAX_NV_FRAGMENT_PROGRAM_INSTRUCTIONS) { + _mesa_set_program_error (ctx, Program->Position, + "Max instruction count exceeded!"); + _mesa_error (ctx, GL_INVALID_OPERATION, + "Max instruction count exceeded!"); + } + + /* Realloc Program->FPInstructions */ + Program->FPInstructions = + (struct fp_instruction *) _mesa_realloc (Program->FPInstructions, + Program->Base.NumInstructions*sizeof(struct fp_instruction), + (Program->Base.NumInstructions+1)*sizeof (struct fp_instruction)); + + /* parse the current instruction */ + err = parse_fp_instruction (ctx, &inst, vc_head, Program, + &Program->FPInstructions[Program->Base.NumInstructions]); + + } + else { + /* Check the instruction count + * XXX: Does END count as an instruction? + */ + if (Program->Base.NumInstructions+1 == MAX_NV_VERTEX_PROGRAM_INSTRUCTIONS) { + _mesa_set_program_error (ctx, Program->Position, + "Max instruction count exceeded!"); + _mesa_error (ctx, GL_INVALID_OPERATION, + "Max instruction count exceeded!"); + } + + /* Realloc Program->VPInstructions */ + Program->VPInstructions = + (struct vp_instruction *) _mesa_realloc (Program->VPInstructions, + Program->Base.NumInstructions*sizeof(struct vp_instruction), + (Program->Base.NumInstructions +1)*sizeof(struct vp_instruction)); + + /* parse the current instruction */ + err = parse_vp_instruction (ctx, &inst, vc_head, Program, + &Program->VPInstructions[Program->Base.NumInstructions]); + } + + /* increment Program->Base.NumInstructions */ + Program->Base.NumInstructions++; + break; + + case DECLARATION: + err = parse_declaration (ctx, &inst, vc_head, Program); + break; + + default: + break; + } + + if (err) + break; + } + + /* Finally, tag on an OPCODE_END instruction */ + if (Program->Base.Target == GL_FRAGMENT_PROGRAM_ARB) { + Program->FPInstructions = + (struct fp_instruction *) _mesa_realloc (Program->FPInstructions, + Program->Base.NumInstructions*sizeof(struct fp_instruction), + (Program->Base.NumInstructions+1)*sizeof(struct fp_instruction)); + + Program->FPInstructions[Program->Base.NumInstructions].Opcode = FP_OPCODE_END; + Program->FPInstructions[Program->Base.NumInstructions].Saturate = 0; + Program->FPInstructions[Program->Base.NumInstructions].DstReg.File = 0xf; + Program->FPInstructions[Program->Base.NumInstructions].SrcReg[0].File = 0xf; + Program->FPInstructions[Program->Base.NumInstructions].SrcReg[1].File = 0xf; + Program->FPInstructions[Program->Base.NumInstructions].SrcReg[2].File = 0xf; + /* YYY Wrong Position in program, whatever, at least not random -> crash + Program->Position = parse_position (&inst); + */ + Program->FPInstructions[Program->Base.NumInstructions].StringPos = Program->Position; + Program->FPInstructions[Program->Base.NumInstructions].Data = NULL; + } + else { + Program->VPInstructions = + (struct vp_instruction *) _mesa_realloc (Program->VPInstructions, + Program->Base.NumInstructions*sizeof(struct vp_instruction), + (Program->Base.NumInstructions+1)*sizeof(struct vp_instruction)); + + Program->VPInstructions[Program->Base.NumInstructions].Opcode = VP_OPCODE_END; + /* YYY Wrong Position in program, whatever, at least not random -> crash + Program->Position = parse_position (&inst); + */ + Program->VPInstructions[Program->Base.NumInstructions].StringPos = Program->Position; + Program->VPInstructions[Program->Base.NumInstructions].Data = NULL; + } + + /* increment Program->Base.NumInstructions */ + Program->Base.NumInstructions++; + + return err; +} + +/* XXX temporary */ +__extension__ static char core_grammar_text[] = +#include "grammar_syn.h" +; + +static int set_reg8 (GLcontext *ctx, grammar id, const byte *name, byte value) +{ + char error_msg[300]; + GLint error_pos; + + if (grammar_set_reg8 (id, name, value)) + return 0; + + grammar_get_last_error ((byte *) error_msg, 300, &error_pos); + _mesa_set_program_error (ctx, error_pos, error_msg); + _mesa_error (ctx, GL_INVALID_OPERATION, "Grammar Register Error"); + return 1; +} + +static int extension_is_supported (const GLubyte *ext) +{ + const GLubyte *extensions = CALL_GetString(GET_DISPATCH(), (GL_EXTENSIONS)); + const GLubyte *end = extensions + _mesa_strlen ((const char *) extensions); + const GLint ext_len = (GLint)_mesa_strlen ((const char *) ext); + + while (extensions < end) + { + const GLubyte *name_end = (const GLubyte *) strchr ((const char *) extensions, ' '); + if (name_end == NULL) + name_end = end; + if (name_end - extensions == ext_len && _mesa_strncmp ((const char *) ext, + (const char *) extensions, ext_len) == 0) + return 1; + extensions = name_end + 1; + } + + return 0; +} + +static int enable_ext (GLcontext *ctx, grammar id, const byte *name, const byte *extname) +{ + if (extension_is_supported (extname)) + if (set_reg8 (ctx, id, name, 0x01)) + return 1; + return 0; +} + +/** + * This kicks everything off. + * + * \param ctx - The GL Context + * \param str - The program string + * \param len - The program string length + * \param program - The arb_program struct to return all the parsed info in + * \return GL_TRUE on sucess, GL_FALSE on error + */ +GLboolean +_mesa_parse_arb_program (GLcontext * ctx, const GLubyte * str, GLsizei len, + struct arb_program * program) +{ + GLint a, err, error_pos; + char error_msg[300]; + GLuint parsed_len; + struct var_cache *vc_head; + grammar arbprogram_syn_id; + GLubyte *parsed, *inst; + GLubyte *strz = NULL; + static int arbprogram_syn_is_ok = 0; /* XXX temporary */ + + /* Reset error state */ + _mesa_set_program_error(ctx, -1, NULL); + +#if DEBUG_PARSING + fprintf (stderr, "Loading grammar text!\n"); +#endif + + /* check if the arb_grammar_text (arbprogram.syn) is syntactically correct */ + if (!arbprogram_syn_is_ok) { + grammar grammar_syn_id; + GLint err; + GLuint parsed_len; + byte *parsed; + + grammar_syn_id = grammar_load_from_text ((byte *) core_grammar_text); + if (grammar_syn_id == 0) { + grammar_get_last_error ((byte *) error_msg, 300, &error_pos); + _mesa_set_program_error (ctx, error_pos, error_msg); + _mesa_error (ctx, GL_INVALID_OPERATION, + "Error loading grammar rule set"); + return GL_FALSE; + } + + err = grammar_check (grammar_syn_id, (byte *) arb_grammar_text, &parsed, &parsed_len); + + /* NOTE: we can't destroy grammar_syn_id right here because + * grammar_destroy() can reset the last error + */ + if (err == 0) { + grammar_get_last_error ((byte *) error_msg, 300, &error_pos); + _mesa_set_program_error (ctx, error_pos, error_msg); + _mesa_error (ctx, GL_INVALID_OPERATION, "Error loading grammar rule set"); + + grammar_destroy (grammar_syn_id); + return GL_FALSE; + } + + grammar_destroy (grammar_syn_id); + + arbprogram_syn_is_ok = 1; + } + + /* create the grammar object */ + arbprogram_syn_id = grammar_load_from_text ((byte *) arb_grammar_text); + if (arbprogram_syn_id == 0) { + grammar_get_last_error ((GLubyte *) error_msg, 300, &error_pos); + _mesa_set_program_error (ctx, error_pos, error_msg); + _mesa_error (ctx, GL_INVALID_OPERATION, + "Error loading grammar rule set"); + return GL_FALSE; + } + + /* Set program_target register value */ + if (set_reg8 (ctx, arbprogram_syn_id, (byte *) "program_target", + program->Base.Target == GL_FRAGMENT_PROGRAM_ARB ? 0x10 : 0x20)) { + grammar_destroy (arbprogram_syn_id); + return GL_FALSE; + } + + /* Enable all active extensions */ + if (enable_ext (ctx, arbprogram_syn_id, + (byte *) "vertex_blend", (byte *) "GL_ARB_vertex_blend") || + enable_ext (ctx, arbprogram_syn_id, + (byte *) "vertex_blend", (byte *) "GL_EXT_vertex_weighting") || + enable_ext (ctx, arbprogram_syn_id, + (byte *) "matrix_palette", (byte *) "GL_ARB_matrix_palette") || + enable_ext (ctx, arbprogram_syn_id, + (byte *) "point_parameters", (byte *) "GL_ARB_point_parameters") || + enable_ext (ctx, arbprogram_syn_id, + (byte *) "point_parameters", (byte *) "GL_EXT_point_parameters") || + enable_ext (ctx, arbprogram_syn_id, + (byte *) "secondary_color", (byte *) "GL_EXT_secondary_color") || + enable_ext (ctx, arbprogram_syn_id, + (byte *) "fog_coord", (byte *) "GL_EXT_fog_coord") || + enable_ext (ctx, arbprogram_syn_id, + (byte *) "texture_rectangle", (byte *) "GL_ARB_texture_rectangle") || + enable_ext (ctx, arbprogram_syn_id, + (byte *) "texture_rectangle", (byte *) "GL_EXT_texture_rectangle") || + enable_ext (ctx, arbprogram_syn_id, + (byte *) "texture_rectangle", (byte *) "GL_NV_texture_rectangle") || + enable_ext (ctx, arbprogram_syn_id, + (byte *) "fragment_program_shadow", (byte *) "GL_ARB_fragment_program_shadow") || + enable_ext (ctx, arbprogram_syn_id, + (byte *) "draw_buffers", (byte *) "GL_ARB_draw_buffers")) { + grammar_destroy (arbprogram_syn_id); + return GL_FALSE; + } + + /* check for NULL character occurences */ + { + int i; + for (i = 0; i < len; i++) + if (str[i] == '\0') { + _mesa_set_program_error (ctx, i, "invalid character"); + _mesa_error (ctx, GL_INVALID_OPERATION, "Lexical Error"); + + grammar_destroy (arbprogram_syn_id); + return GL_FALSE; + } + } + + /* copy the program string to a null-terminated string */ + strz = (GLubyte *) _mesa_malloc (len + 1); + if (!strz) { + _mesa_error(ctx, GL_OUT_OF_MEMORY, "glprogramStringARB"); + return GL_FALSE; + } + _mesa_memcpy (strz, str, len); + strz[len] = '\0'; + +#if DEBUG_PARSING + printf ("Checking Grammar!\n"); +#endif + /* do a fast check on program string - initial production buffer is 4K */ + err = grammar_fast_check (arbprogram_syn_id, strz, &parsed, &parsed_len, 0x1000); + + /* Syntax parse error */ + if (err == 0) { + _mesa_free (strz); + grammar_get_last_error ((GLubyte *) error_msg, 300, &error_pos); + _mesa_set_program_error (ctx, error_pos, error_msg); + _mesa_error (ctx, GL_INVALID_OPERATION, "glProgramStringARB(syntax error)"); + + /* useful for debugging */ + if (0) { + int line, col; + char *s; + printf("Program: %s\n", (char *) strz); + printf("Error Pos: %d\n", ctx->Program.ErrorPos); + s = (char *) _mesa_find_line_column(strz, strz+ctx->Program.ErrorPos, &line, &col); + printf("line %d col %d: %s\n", line, col, s); + } + + grammar_destroy (arbprogram_syn_id); + return 1; + } + +#if DEBUG_PARSING + printf ("Destroying grammer dict [parse retval: %d]\n", err); +#endif + grammar_destroy (arbprogram_syn_id); + + /* Initialize the arb_program struct */ + program->Base.String = strz; + program->Base.NumInstructions = + program->Base.NumTemporaries = + program->Base.NumParameters = + program->Base.NumAttributes = program->Base.NumAddressRegs = 0; + program->Parameters = _mesa_new_parameter_list (); + program->InputsRead = 0; + program->OutputsWritten = 0; + program->Position = 0; + program->MajorVersion = program->MinorVersion = 0; + program->PrecisionOption = GL_DONT_CARE; + program->FogOption = GL_NONE; + program->HintPositionInvariant = GL_FALSE; + for (a = 0; a < MAX_TEXTURE_IMAGE_UNITS; a++) + program->TexturesUsed[a] = 0; + program->NumAluInstructions = + program->NumTexInstructions = + program->NumTexIndirections = 0; + + program->FPInstructions = NULL; + program->VPInstructions = NULL; + + vc_head = NULL; + err = GL_FALSE; + + /* Start examining the tokens in the array */ + inst = parsed; + + /* Check the grammer rev */ + if (*inst++ != REVISION) { + _mesa_set_program_error (ctx, 0, "Grammar version mismatch"); + _mesa_error(ctx, GL_INVALID_OPERATION, + "glProgramStringARB(Grammar version mismatch)"); + err = GL_TRUE; + } + else { + /* ignore program target */ + inst++; + + err = parse_arb_program (ctx, inst, &vc_head, program); +#if DEBUG_PARSING + fprintf (stderr, "Symantic analysis returns %d [1 is bad!]\n", err); +#endif + } + + /*debug_variables(ctx, vc_head, program); */ + + /* We're done with the parsed binary array */ + var_cache_destroy (&vc_head); + + _mesa_free (parsed); +#if DEBUG_PARSING + printf ("_mesa_parse_arb_program() done\n"); +#endif + + return !err; +} diff --git a/nx-X11/extras/Mesa/src/mesa/shader/arbprogparse.h b/nx-X11/extras/Mesa/src/mesa/shader/arbprogparse.h new file mode 100644 index 000000000..ececfafa8 --- /dev/null +++ b/nx-X11/extras/Mesa/src/mesa/shader/arbprogparse.h @@ -0,0 +1,75 @@ +/* + * Mesa 3-D graphics library + * Version: 6.3 + * + * Copyright (C) 1999-2005 Brian Paul All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN + * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + + +#ifndef ARBPROGPARSE_H +#define ARBPROGPARSE_H + +#include "context.h" +#include "mtypes.h" +#include "nvvertprog.h" +#include "nvfragprog.h" + +/** + * This is basically a union of the vertex_program and fragment_program + * structs that we can use to parse the program into + * + * XXX: this should go into mtypes.h? + */ +struct arb_program +{ + struct program Base; + struct program_parameter_list *Parameters; + GLuint InputsRead; + GLuint OutputsWritten; + + GLuint Position; /* Just used for error reporting while parsing */ + GLuint MajorVersion; + GLuint MinorVersion; + + /* ARB_vertex_program specifics */ + struct vp_instruction *VPInstructions; + + /* Options currently recognized by the parser */ + /* ARB_fp */ + GLenum PrecisionOption; /* GL_DONT_CARE, GL_NICEST or GL_FASTEST */ + GLenum FogOption; /* GL_NONE, GL_LINEAR, GL_EXP or GL_EXP2 */ + + /* ARB_fp & _vp */ + GLboolean HintPositionInvariant; + + /* ARB_fragment_program specifics */ + struct fp_instruction *FPInstructions; + GLuint TexturesUsed[MAX_TEXTURE_IMAGE_UNITS]; + GLuint NumAluInstructions; + GLuint NumTexInstructions; + GLuint NumTexIndirections; +}; + + +extern GLboolean +_mesa_parse_arb_program( GLcontext *ctx, const GLubyte *str, GLsizei len, + struct arb_program *program ); + +#endif diff --git a/nx-X11/extras/Mesa/src/mesa/shader/arbprogram.c b/nx-X11/extras/Mesa/src/mesa/shader/arbprogram.c new file mode 100644 index 000000000..43baab4b0 --- /dev/null +++ b/nx-X11/extras/Mesa/src/mesa/shader/arbprogram.c @@ -0,0 +1,724 @@ +/* + * 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. + */ + +/** + * \file arbprogram.c + * ARB_vertex/fragment_program state management functions. + * \author Brian Paul + */ + + +#include "glheader.h" +#include "arbprogram.h" +#include "arbfragparse.h" +#include "arbvertparse.h" +#include "context.h" +#include "imports.h" +#include "macros.h" +#include "mtypes.h" +#include "nvprogram.h" +#include "nvfragparse.h" +#include "nvfragprog.h" +#include "nvvertparse.h" +#include "nvvertprog.h" + + +void GLAPIENTRY +_mesa_EnableVertexAttribArrayARB(GLuint index) +{ + GET_CURRENT_CONTEXT(ctx); + ASSERT_OUTSIDE_BEGIN_END(ctx); + + if (index >= ctx->Const.MaxVertexProgramAttribs) { + _mesa_error(ctx, GL_INVALID_VALUE, + "glEnableVertexAttribArrayARB(index)"); + return; + } + + FLUSH_VERTICES(ctx, _NEW_ARRAY); + ctx->Array.VertexAttrib[index].Enabled = GL_TRUE; + ctx->Array._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.MaxVertexProgramAttribs) { + _mesa_error(ctx, GL_INVALID_VALUE, + "glEnableVertexAttribArrayARB(index)"); + return; + } + + FLUSH_VERTICES(ctx, _NEW_ARRAY); + ctx->Array.VertexAttrib[index].Enabled = GL_FALSE; + ctx->Array._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]; + } + } +} + + +void GLAPIENTRY +_mesa_GetVertexAttribfvARB(GLuint index, GLenum pname, GLfloat *params) +{ + GET_CURRENT_CONTEXT(ctx); + ASSERT_OUTSIDE_BEGIN_END(ctx); + + if (index == 0 || index >= MAX_VERTEX_PROGRAM_ATTRIBS) { + _mesa_error(ctx, GL_INVALID_VALUE, "glGetVertexAttribfvARB(index)"); + return; + } + + switch (pname) { + case GL_VERTEX_ATTRIB_ARRAY_ENABLED_ARB: + params[0] = (GLfloat) ctx->Array.VertexAttrib[index].Enabled; + break; + case GL_VERTEX_ATTRIB_ARRAY_SIZE_ARB: + params[0] = (GLfloat) ctx->Array.VertexAttrib[index].Size; + break; + case GL_VERTEX_ATTRIB_ARRAY_STRIDE_ARB: + params[0] = (GLfloat) ctx->Array.VertexAttrib[index].Stride; + break; + case GL_VERTEX_ATTRIB_ARRAY_TYPE_ARB: + params[0] = (GLfloat) ctx->Array.VertexAttrib[index].Type; + break; + case GL_VERTEX_ATTRIB_ARRAY_NORMALIZED_ARB: + params[0] = ctx->Array.VertexAttrib[index].Normalized; + break; + case GL_CURRENT_VERTEX_ATTRIB_ARB: + FLUSH_CURRENT(ctx, 0); + /* XXX should read: + COPY_4V(params, ctx->Current.Attrib[VERT_ATTRIB_GENERIC0 + index]); + */ + COPY_4V(params, ctx->Current.Attrib[index]); + break; + case GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING_ARB: + if (!ctx->Extensions.ARB_vertex_buffer_object) { + _mesa_error(ctx, GL_INVALID_ENUM, "glGetVertexAttribfvARB(pname)"); + return; + } + params[0] = (GLfloat) ctx->Array.VertexAttrib[index].BufferObj->Name; + 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.MaxVertexProgramAttribs) { + _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; + } + + *pointer = (GLvoid *) ctx->Array.VertexAttrib[index].Ptr;; +} + + +void GLAPIENTRY +_mesa_ProgramStringARB(GLenum target, GLenum format, GLsizei len, + const GLvoid *string) +{ + GET_CURRENT_CONTEXT(ctx); + ASSERT_OUTSIDE_BEGIN_END(ctx); + + FLUSH_VERTICES(ctx, _NEW_PROGRAM); + + if (target == GL_VERTEX_PROGRAM_ARB + && ctx->Extensions.ARB_vertex_program) { + struct vertex_program *prog = ctx->VertexProgram.Current; + if (format != GL_PROGRAM_FORMAT_ASCII_ARB) { + _mesa_error(ctx, GL_INVALID_ENUM, "glProgramStringARB(format)"); + return; + } + _mesa_parse_arb_vertex_program(ctx, target, (const GLubyte *) string, + len, prog); + + if (ctx->Driver.ProgramStringNotify) + ctx->Driver.ProgramStringNotify( ctx, target, &prog->Base ); + } + else if (target == GL_FRAGMENT_PROGRAM_ARB + && ctx->Extensions.ARB_fragment_program) { + struct fragment_program *prog = ctx->FragmentProgram.Current; + if (format != GL_PROGRAM_FORMAT_ASCII_ARB) { + _mesa_error(ctx, GL_INVALID_ENUM, "glProgramStringARB(format)"); + return; + } + _mesa_parse_arb_fragment_program(ctx, target, (const GLubyte *) string, + len, prog); + + if (ctx->Driver.ProgramStringNotify) + ctx->Driver.ProgramStringNotify( ctx, target, &prog->Base ); + } + else { + _mesa_error(ctx, GL_INVALID_ENUM, "glProgramStringARB(target)"); + return; + } +} + + +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); +} + + +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]); +} + + +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); + + if (target == GL_FRAGMENT_PROGRAM_ARB + && ctx->Extensions.ARB_fragment_program) { + if (index >= ctx->Const.MaxFragmentProgramEnvParams) { + _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 + && ctx->Extensions.ARB_vertex_program) { + if (index >= ctx->Const.MaxVertexProgramEnvParams) { + _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; + } +} + + +void GLAPIENTRY +_mesa_ProgramEnvParameter4fvARB(GLenum target, GLuint index, + const GLfloat *params) +{ + _mesa_ProgramEnvParameter4fARB(target, index, params[0], params[1], + params[2], params[3]); +} + + +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); + + FLUSH_VERTICES(ctx, _NEW_PROGRAM); + + if (!ctx->_CurrentProgram) + ASSERT_OUTSIDE_BEGIN_END(ctx); + + if (target == GL_FRAGMENT_PROGRAM_ARB + && ctx->Extensions.ARB_fragment_program) { + if (index >= ctx->Const.MaxFragmentProgramEnvParams) { + _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.MaxVertexProgramEnvParams) { + _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 program *prog; + ASSERT_OUTSIDE_BEGIN_END(ctx); + + FLUSH_VERTICES(ctx, _NEW_PROGRAM); + + 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.MaxFragmentProgramLocalParams) { + _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.MaxVertexProgramLocalParams) { + _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]); +} + + +/** + * 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 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.MaxVertexProgramLocalParams; + } + else if (target == GL_FRAGMENT_PROGRAM_ARB + && ctx->Extensions.ARB_fragment_program) { + prog = &(ctx->FragmentProgram.Current->Base); + maxParams = ctx->Const.MaxFragmentProgramLocalParams; + } + 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]; + _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) +{ + struct program *prog; + GET_CURRENT_CONTEXT(ctx); + + if (!ctx->_CurrentProgram) + ASSERT_OUTSIDE_BEGIN_END(ctx); + + if (target == GL_VERTEX_PROGRAM_ARB + && ctx->Extensions.ARB_vertex_program) { + prog = &(ctx->VertexProgram.Current->Base); + } + else if (target == GL_FRAGMENT_PROGRAM_ARB + && ctx->Extensions.ARB_fragment_program) { + prog = &(ctx->FragmentProgram.Current->Base); + } + else { + _mesa_error(ctx, GL_INVALID_ENUM, "glGetProgramivARB(target)"); + return; + } + + ASSERT(prog); + + switch (pname) { + case GL_PROGRAM_LENGTH_ARB: + *params = prog->String ? (GLint)_mesa_strlen((char *) prog->String) : 0; + break; + case GL_PROGRAM_FORMAT_ARB: + *params = prog->Format; + break; + case GL_PROGRAM_BINDING_ARB: + *params = prog->Id; + break; + case GL_PROGRAM_INSTRUCTIONS_ARB: + *params = prog->NumInstructions; + break; + case GL_MAX_PROGRAM_INSTRUCTIONS_ARB: + if (target == GL_VERTEX_PROGRAM_ARB) + *params = ctx->Const.MaxVertexProgramInstructions; + else + *params = ctx->Const.MaxFragmentProgramInstructions; + break; + case GL_PROGRAM_NATIVE_INSTRUCTIONS_ARB: + *params = prog->NumInstructions; + break; + case GL_MAX_PROGRAM_NATIVE_INSTRUCTIONS_ARB: + if (target == GL_VERTEX_PROGRAM_ARB) + *params = ctx->Const.MaxVertexProgramInstructions; + else + *params = ctx->Const.MaxFragmentProgramInstructions; + break; + case GL_PROGRAM_TEMPORARIES_ARB: + *params = prog->NumTemporaries; + break; + case GL_MAX_PROGRAM_TEMPORARIES_ARB: + if (target == GL_VERTEX_PROGRAM_ARB) + *params = ctx->Const.MaxVertexProgramTemps; + else + *params = ctx->Const.MaxFragmentProgramTemps; + break; + case GL_PROGRAM_NATIVE_TEMPORARIES_ARB: + /* XXX same as GL_PROGRAM_TEMPORARIES_ARB? */ + *params = prog->NumTemporaries; + break; + case GL_MAX_PROGRAM_NATIVE_TEMPORARIES_ARB: + /* XXX same as GL_MAX_PROGRAM_TEMPORARIES_ARB? */ + if (target == GL_VERTEX_PROGRAM_ARB) + *params = ctx->Const.MaxVertexProgramTemps; + else + *params = ctx->Const.MaxFragmentProgramTemps; + break; + case GL_PROGRAM_PARAMETERS_ARB: + *params = prog->NumParameters; + break; + case GL_MAX_PROGRAM_PARAMETERS_ARB: + if (target == GL_VERTEX_PROGRAM_ARB) + *params = ctx->Const.MaxVertexProgramLocalParams; + else + *params = ctx->Const.MaxFragmentProgramLocalParams; + break; + case GL_PROGRAM_NATIVE_PARAMETERS_ARB: + /* XXX same as GL_MAX_PROGRAM_PARAMETERS_ARB? */ + *params = prog->NumParameters; + break; + case GL_MAX_PROGRAM_NATIVE_PARAMETERS_ARB: + /* XXX same as GL_MAX_PROGRAM_PARAMETERS_ARB? */ + if (target == GL_VERTEX_PROGRAM_ARB) + *params = ctx->Const.MaxVertexProgramLocalParams; + else + *params = ctx->Const.MaxFragmentProgramLocalParams; + break; + case GL_PROGRAM_ATTRIBS_ARB: + *params = prog->NumAttributes; + break; + case GL_MAX_PROGRAM_ATTRIBS_ARB: + if (target == GL_VERTEX_PROGRAM_ARB) + *params = ctx->Const.MaxVertexProgramAttribs; + else + *params = ctx->Const.MaxFragmentProgramAttribs; + break; + case GL_PROGRAM_NATIVE_ATTRIBS_ARB: + /* XXX same as GL_PROGRAM_ATTRIBS_ARB? */ + *params = prog->NumAttributes; + break; + case GL_MAX_PROGRAM_NATIVE_ATTRIBS_ARB: + /* XXX same as GL_MAX_PROGRAM_ATTRIBS_ARB? */ + if (target == GL_VERTEX_PROGRAM_ARB) + *params = ctx->Const.MaxVertexProgramAttribs; + else + *params = ctx->Const.MaxFragmentProgramAttribs; + break; + case GL_PROGRAM_ADDRESS_REGISTERS_ARB: + *params = prog->NumAddressRegs; + break; + case GL_MAX_PROGRAM_ADDRESS_REGISTERS_ARB: + if (target == GL_VERTEX_PROGRAM_ARB) + *params = ctx->Const.MaxVertexProgramAddressRegs; + else + *params = ctx->Const.MaxFragmentProgramAddressRegs; + break; + case GL_PROGRAM_NATIVE_ADDRESS_REGISTERS_ARB: + /* XXX same as GL_PROGRAM_ADDRESS_REGISTERS_ARB? */ + *params = prog->NumAddressRegs; + break; + case GL_MAX_PROGRAM_NATIVE_ADDRESS_REGISTERS_ARB: + /* XXX same as GL_MAX_PROGRAM_ADDRESS_REGISTERS_ARB? */ + if (target == GL_VERTEX_PROGRAM_ARB) + *params = ctx->Const.MaxVertexProgramAddressRegs; + else + *params = ctx->Const.MaxFragmentProgramAddressRegs; + break; + case GL_MAX_PROGRAM_LOCAL_PARAMETERS_ARB: + if (target == GL_VERTEX_PROGRAM_ARB) + *params = ctx->Const.MaxVertexProgramLocalParams; + else + *params = ctx->Const.MaxFragmentProgramLocalParams; + break; + case GL_MAX_PROGRAM_ENV_PARAMETERS_ARB: + if (target == GL_VERTEX_PROGRAM_ARB) + *params = ctx->Const.MaxVertexProgramEnvParams; + else + *params = ctx->Const.MaxFragmentProgramEnvParams; + break; + case GL_PROGRAM_UNDER_NATIVE_LIMITS_ARB: + if (ctx->Driver.IsProgramNative) + *params = ctx->Driver.IsProgramNative( ctx, target, prog ); + else + *params = GL_TRUE; + break; + + /* + * The following apply to fragment programs only. + */ + case GL_PROGRAM_ALU_INSTRUCTIONS_ARB: + case GL_PROGRAM_NATIVE_ALU_INSTRUCTIONS_ARB: + if (target != GL_FRAGMENT_PROGRAM_ARB) { + _mesa_error(ctx, GL_INVALID_ENUM, "glGetProgramivARB(target)"); + return; + } + *params = ctx->FragmentProgram.Current->NumAluInstructions; + break; + case GL_PROGRAM_TEX_INSTRUCTIONS_ARB: + case GL_PROGRAM_NATIVE_TEX_INSTRUCTIONS_ARB: + if (target != GL_FRAGMENT_PROGRAM_ARB) { + _mesa_error(ctx, GL_INVALID_ENUM, "glGetProgramivARB(target)"); + return; + } + *params = ctx->FragmentProgram.Current->NumTexInstructions; + break; + case GL_PROGRAM_TEX_INDIRECTIONS_ARB: + case GL_PROGRAM_NATIVE_TEX_INDIRECTIONS_ARB: + if (target != GL_FRAGMENT_PROGRAM_ARB) { + _mesa_error(ctx, GL_INVALID_ENUM, "glGetProgramivARB(target)"); + return; + } + *params = ctx->FragmentProgram.Current->NumTexIndirections; + break; + case GL_MAX_PROGRAM_ALU_INSTRUCTIONS_ARB: + case GL_MAX_PROGRAM_NATIVE_ALU_INSTRUCTIONS_ARB: + if (target != GL_FRAGMENT_PROGRAM_ARB) { + _mesa_error(ctx, GL_INVALID_ENUM, "glGetProgramivARB(target)"); + return; + } + *params = ctx->Const.MaxFragmentProgramAluInstructions; + break; + case GL_MAX_PROGRAM_TEX_INSTRUCTIONS_ARB: + case GL_MAX_PROGRAM_NATIVE_TEX_INSTRUCTIONS_ARB: + if (target != GL_FRAGMENT_PROGRAM_ARB) { + _mesa_error(ctx, GL_INVALID_ENUM, "glGetProgramivARB(target)"); + return; + } + *params = ctx->Const.MaxFragmentProgramTexInstructions; + break; + case GL_MAX_PROGRAM_TEX_INDIRECTIONS_ARB: + case GL_MAX_PROGRAM_NATIVE_TEX_INDIRECTIONS_ARB: + if (target != GL_FRAGMENT_PROGRAM_ARB) { + _mesa_error(ctx, GL_INVALID_ENUM, "glGetProgramivARB(target)"); + return; + } + *params = ctx->Const.MaxFragmentProgramTexIndirections; + break; + default: + _mesa_error(ctx, GL_INVALID_ENUM, "glGetProgramivARB(pname)"); + return; + } +} + + +void GLAPIENTRY +_mesa_GetProgramStringARB(GLenum target, GLenum pname, GLvoid *string) +{ + struct program *prog; + GET_CURRENT_CONTEXT(ctx); + + if (!ctx->_CurrentProgram) + 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; + } + + MEMCPY(string, prog->String, _mesa_strlen((char *) prog->String)); +} + diff --git a/nx-X11/extras/Mesa/src/mesa/shader/arbprogram.h b/nx-X11/extras/Mesa/src/mesa/shader/arbprogram.h new file mode 100644 index 000000000..e1b99ab68 --- /dev/null +++ b/nx-X11/extras/Mesa/src/mesa/shader/arbprogram.h @@ -0,0 +1,128 @@ +/* + * 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. + */ + + +#ifndef ARBPROGRAM_H +#define ARBPROGRAM_H + + +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 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_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_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/nx-X11/extras/Mesa/src/mesa/shader/arbprogram_syn.h b/nx-X11/extras/Mesa/src/mesa/shader/arbprogram_syn.h new file mode 100644 index 000000000..c67afc67d --- /dev/null +++ b/nx-X11/extras/Mesa/src/mesa/shader/arbprogram_syn.h @@ -0,0 +1,1327 @@ +".syntax program;\n" +".emtcode REVISION 0x09\n" +".emtcode FRAGMENT_PROGRAM 0x01\n" +".emtcode VERTEX_PROGRAM 0x02\n" +".emtcode OPTION 0x01\n" +".emtcode INSTRUCTION 0x02\n" +".emtcode DECLARATION 0x03\n" +".emtcode END 0x04\n" +".emtcode ARB_PRECISION_HINT_FASTEST 0x00\n" +".emtcode ARB_PRECISION_HINT_NICEST 0x01\n" +".emtcode ARB_FOG_EXP 0x02\n" +".emtcode ARB_FOG_EXP2 0x03\n" +".emtcode ARB_FOG_LINEAR 0x04\n" +".emtcode ARB_POSITION_INVARIANT 0x05\n" +".emtcode ARB_FRAGMENT_PROGRAM_SHADOW 0x06\n" +".emtcode ARB_DRAW_BUFFERS 0x07\n" +".emtcode OP_ALU_INST 0x00\n" +".emtcode OP_TEX_INST 0x01\n" +".emtcode OP_ALU_VECTOR 0x00\n" +".emtcode OP_ALU_SCALAR 0x01\n" +".emtcode OP_ALU_BINSC 0x02\n" +".emtcode OP_ALU_BIN 0x03\n" +".emtcode OP_ALU_TRI 0x04\n" +".emtcode OP_ALU_SWZ 0x05\n" +".emtcode OP_TEX_SAMPLE 0x06\n" +".emtcode OP_TEX_KIL 0x07\n" +".emtcode OP_ALU_ARL 0x08\n" +".emtcode OP_ABS 0x00\n" +".emtcode OP_ABS_SAT 0x1B\n" +".emtcode OP_FLR 0x09\n" +".emtcode OP_FLR_SAT 0x26\n" +".emtcode OP_FRC 0x0A\n" +".emtcode OP_FRC_SAT 0x27\n" +".emtcode OP_LIT 0x0C\n" +".emtcode OP_LIT_SAT 0x2A\n" +".emtcode OP_MOV 0x11\n" +".emtcode OP_MOV_SAT 0x30\n" +".emtcode OP_COS 0x1F\n" +".emtcode OP_COS_SAT 0x20\n" +".emtcode OP_EX2 0x07\n" +".emtcode OP_EX2_SAT 0x25\n" +".emtcode OP_LG2 0x0B\n" +".emtcode OP_LG2_SAT 0x29\n" +".emtcode OP_RCP 0x14\n" +".emtcode OP_RCP_SAT 0x33\n" +".emtcode OP_RSQ 0x15\n" +".emtcode OP_RSQ_SAT 0x34\n" +".emtcode OP_SIN 0x38\n" +".emtcode OP_SIN_SAT 0x39\n" +".emtcode OP_SCS 0x35\n" +".emtcode OP_SCS_SAT 0x36\n" +".emtcode OP_POW 0x13\n" +".emtcode OP_POW_SAT 0x32\n" +".emtcode OP_ADD 0x01\n" +".emtcode OP_ADD_SAT 0x1C\n" +".emtcode OP_DP3 0x03\n" +".emtcode OP_DP3_SAT 0x21\n" +".emtcode OP_DP4 0x04\n" +".emtcode OP_DP4_SAT 0x22\n" +".emtcode OP_DPH 0x05\n" +".emtcode OP_DPH_SAT 0x23\n" +".emtcode OP_DST 0x06\n" +".emtcode OP_DST_SAT 0x24\n" +".emtcode OP_MAX 0x0F\n" +".emtcode OP_MAX_SAT 0x2E\n" +".emtcode OP_MIN 0x10\n" +".emtcode OP_MIN_SAT 0x2F\n" +".emtcode OP_MUL 0x12\n" +".emtcode OP_MUL_SAT 0x31\n" +".emtcode OP_SGE 0x16\n" +".emtcode OP_SGE_SAT 0x37\n" +".emtcode OP_SLT 0x17\n" +".emtcode OP_SLT_SAT 0x3A\n" +".emtcode OP_SUB 0x18\n" +".emtcode OP_SUB_SAT 0x3B\n" +".emtcode OP_XPD 0x1A\n" +".emtcode OP_XPD_SAT 0x43\n" +".emtcode OP_CMP 0x1D\n" +".emtcode OP_CMP_SAT 0x1E\n" +".emtcode OP_LRP 0x2B\n" +".emtcode OP_LRP_SAT 0x2C\n" +".emtcode OP_MAD 0x0E\n" +".emtcode OP_MAD_SAT 0x2D\n" +".emtcode OP_SWZ 0x19\n" +".emtcode OP_SWZ_SAT 0x3C\n" +".emtcode OP_TEX 0x3D\n" +".emtcode OP_TEX_SAT 0x3E\n" +".emtcode OP_TXB 0x3F\n" +".emtcode OP_TXB_SAT 0x40\n" +".emtcode OP_TXP 0x41\n" +".emtcode OP_TXP_SAT 0x42\n" +".emtcode OP_KIL 0x28\n" +".emtcode OP_ARL 0x02\n" +".emtcode OP_EXP 0x08\n" +".emtcode OP_LOG 0x0D\n" +".emtcode FRAGMENT_ATTRIB_COLOR 0x01\n" +".emtcode FRAGMENT_ATTRIB_TEXCOORD 0x02\n" +".emtcode FRAGMENT_ATTRIB_FOGCOORD 0x03\n" +".emtcode FRAGMENT_ATTRIB_POSITION 0x04\n" +".emtcode VERTEX_ATTRIB_POSITION 0x01\n" +".emtcode VERTEX_ATTRIB_WEIGHT 0x02\n" +".emtcode VERTEX_ATTRIB_NORMAL 0x03\n" +".emtcode VERTEX_ATTRIB_COLOR 0x04\n" +".emtcode VERTEX_ATTRIB_FOGCOORD 0x05\n" +".emtcode VERTEX_ATTRIB_TEXCOORD 0x06\n" +".emtcode VERTEX_ATTRIB_MATRIXINDEX 0x07\n" +".emtcode VERTEX_ATTRIB_GENERIC 0x08\n" +".emtcode FRAGMENT_RESULT_COLOR 0x01\n" +".emtcode FRAGMENT_RESULT_DEPTH 0x02\n" +".emtcode VERTEX_RESULT_POSITION 0x01\n" +".emtcode VERTEX_RESULT_COLOR 0x02\n" +".emtcode VERTEX_RESULT_FOGCOORD 0x03\n" +".emtcode VERTEX_RESULT_POINTSIZE 0x04\n" +".emtcode VERTEX_RESULT_TEXCOORD 0x05\n" +".emtcode TEXTARGET_1D 0x01\n" +".emtcode TEXTARGET_2D 0x02\n" +".emtcode TEXTARGET_3D 0x03\n" +".emtcode TEXTARGET_RECT 0x04\n" +".emtcode TEXTARGET_CUBE 0x05\n" +".emtcode TEXTARGET_SHADOW1D 0x06\n" +".emtcode TEXTARGET_SHADOW2D 0x07\n" +".emtcode TEXTARGET_SHADOWRECT 0x08\n" +".emtcode FACE_FRONT 0x00\n" +".emtcode FACE_BACK 0x01\n" +".emtcode COLOR_PRIMARY 0x00\n" +".emtcode COLOR_SECONDARY 0x01\n" +".emtcode COMPONENT_X 0x00\n" +".emtcode COMPONENT_Y 0x01\n" +".emtcode COMPONENT_Z 0x02\n" +".emtcode COMPONENT_W 0x03\n" +".emtcode COMPONENT_0 0x04\n" +".emtcode COMPONENT_1 0x05\n" +".emtcode ARRAY_INDEX_ABSOLUTE 0x00\n" +".emtcode ARRAY_INDEX_RELATIVE 0x01\n" +".emtcode MATRIX_MODELVIEW 0x01\n" +".emtcode MATRIX_PROJECTION 0x02\n" +".emtcode MATRIX_MVP 0x03\n" +".emtcode MATRIX_TEXTURE 0x04\n" +".emtcode MATRIX_PALETTE 0x05\n" +".emtcode MATRIX_PROGRAM 0x06\n" +".emtcode MATRIX_MODIFIER_IDENTITY 0x00\n" +".emtcode MATRIX_MODIFIER_INVERSE 0x01\n" +".emtcode MATRIX_MODIFIER_TRANSPOSE 0x02\n" +".emtcode MATRIX_MODIFIER_INVTRANS 0x03\n" +".emtcode CONSTANT_SCALAR 0x01\n" +".emtcode CONSTANT_VECTOR 0x02\n" +".emtcode PROGRAM_PARAM_ENV 0x01\n" +".emtcode PROGRAM_PARAM_LOCAL 0x02\n" +".emtcode REGISTER_ATTRIB 0x01\n" +".emtcode REGISTER_PARAM 0x02\n" +".emtcode REGISTER_RESULT 0x03\n" +".emtcode REGISTER_ESTABLISHED_NAME 0x04\n" +".emtcode PARAM_NULL 0x00\n" +".emtcode PARAM_ARRAY_ELEMENT 0x01\n" +".emtcode PARAM_STATE_ELEMENT 0x02\n" +".emtcode PARAM_PROGRAM_ELEMENT 0x03\n" +".emtcode PARAM_PROGRAM_ELEMENTS 0x04\n" +".emtcode PARAM_CONSTANT 0x05\n" +".emtcode STATE_MATERIAL 0x01\n" +".emtcode STATE_LIGHT 0x02\n" +".emtcode STATE_LIGHT_MODEL 0x03\n" +".emtcode STATE_LIGHT_PROD 0x04\n" +".emtcode STATE_FOG 0x05\n" +".emtcode STATE_MATRIX_ROWS 0x06\n" +".emtcode STATE_TEX_ENV 0x07\n" +".emtcode STATE_DEPTH 0x08\n" +".emtcode STATE_TEX_GEN 0x09\n" +".emtcode STATE_CLIP_PLANE 0x0A\n" +".emtcode STATE_POINT 0x0B\n" +".emtcode MATERIAL_AMBIENT 0x01\n" +".emtcode MATERIAL_DIFFUSE 0x02\n" +".emtcode MATERIAL_SPECULAR 0x03\n" +".emtcode MATERIAL_EMISSION 0x04\n" +".emtcode MATERIAL_SHININESS 0x05\n" +".emtcode LIGHT_AMBIENT 0x01\n" +".emtcode LIGHT_DIFFUSE 0x02\n" +".emtcode LIGHT_SPECULAR 0x03\n" +".emtcode LIGHT_POSITION 0x04\n" +".emtcode LIGHT_ATTENUATION 0x05\n" +".emtcode LIGHT_HALF 0x06\n" +".emtcode LIGHT_SPOT_DIRECTION 0x07\n" +".emtcode LIGHT_MODEL_AMBIENT 0x01\n" +".emtcode LIGHT_MODEL_SCENECOLOR 0x02\n" +".emtcode LIGHT_PROD_AMBIENT 0x01\n" +".emtcode LIGHT_PROD_DIFFUSE 0x02\n" +".emtcode LIGHT_PROD_SPECULAR 0x03\n" +".emtcode TEX_ENV_COLOR 0x01\n" +".emtcode TEX_GEN_EYE 0x01\n" +".emtcode TEX_GEN_OBJECT 0x02\n" +".emtcode FOG_COLOR 0x01\n" +".emtcode FOG_PARAMS 0x02\n" +".emtcode DEPTH_RANGE 0x01\n" +".emtcode POINT_SIZE 0x01\n" +".emtcode POINT_ATTENUATION 0x02\n" +".emtcode ATTRIB 0x01\n" +".emtcode PARAM 0x02\n" +".emtcode TEMP 0x03\n" +".emtcode OUTPUT 0x04\n" +".emtcode ALIAS 0x05\n" +".emtcode ADDRESS 0x06\n" +".errtext UNKNOWN_PROGRAM_SIGNATURE \"1001: '$e_signature$': unknown program signature\"\n" +".errtext MISSING_END_OR_INVALID_STATEMENT \"1002: '$e_statement$': invalid statement\"\n" +".errtext CODE_AFTER_END \"1003: '$e_statement$': code after 'END' keyword\"\n" +".errtext INVALID_PROGRAM_OPTION \"1004: '$e_identifier$': invalid program option\"\n" +".errtext EXT_SWIZ_COMP_EXPECTED \"1005: extended swizzle component expected but '$e_token$' found\"\n" +".errtext TEX_TARGET_EXPECTED \"1006: texture target expected but '$e_token$' found\"\n" +".errtext TEXTURE_EXPECTED \"1007: 'texture' expected but '$e_identifier$' found\"\n" +".errtext SOURCE_REGISTER_EXPECTED \"1008: source register expected but '$e_token$' found\"\n" +".errtext DESTINATION_REGISTER_EXPECTED \"1009: destination register expected but '$e_token$' found\"\n" +".errtext INVALID_ADDRESS_COMPONENT \"1010: '$e_identifier$': invalid address component\"\n" +".errtext INVALID_ADDRESS_WRITEMASK \"1011: '$e_identifier$': invalid address writemask\"\n" +".errtext INVALID_COMPONENT \"1012: '$e_charordigit$': invalid component\"\n" +".errtext INVALID_SUFFIX \"1013: '$e_identifier$': invalid suffix\"\n" +".errtext INVALID_WRITEMASK \"1014: '$e_identifier$': invalid writemask\"\n" +".errtext FRAGMENT_EXPECTED \"1015: 'fragment' expected but '$e_identifier$' found\"\n" +".errtext VERTEX_EXPECTED \"1016: 'vertex' expected but '$e_identifier$' found\"\n" +".errtext INVALID_FRAGMENT_PROPERTY \"1017: '$e_identifier$': invalid fragment property\"\n" +".errtext INVALID_VERTEX_PROPERTY \"1018: '$e_identifier$': invalid vertex property\"\n" +".errtext INVALID_STATE_PROPERTY \"1019: '$e_identifier$': invalid state property\"\n" +".errtext INVALID_MATERIAL_PROPERTY \"1020: '$e_identifier$': invalid material property\"\n" +".errtext INVALID_LIGHT_PROPERTY \"1021: '$e_identifier$': invalid light property\"\n" +".errtext INVALID_SPOT_PROPERTY \"1022: '$e_identifier$': invalid spot property\"\n" +".errtext INVALID_LIGHTMODEL_PROPERTY \"1023: '$e_identifier$': invalid light model property\"\n" +".errtext INVALID_LIGHTPROD_PROPERTY \"1024: '$e_identifier$': invalid light product property\"\n" +".errtext INVALID_TEXENV_PROPERTY \"1025: '$e_identifier$': invalid texture environment property\"\n" +".errtext INVALID_TEXGEN_PROPERTY \"1026: '$e_identifier$': invalid texture generating property\"\n" +".errtext INVALID_TEXGEN_COORD \"1027: '$e_identifier$': invalid texture generating coord\"\n" +".errtext INVALID_FOG_PROPERTY \"1028: '$e_identifier$': invalid fog property\"\n" +".errtext INVALID_DEPTH_PROPERTY \"1029: '$e_identifier$': invalid depth property\"\n" +".errtext INVALID_CLIPPLANE_PROPERTY \"1030: '$e_identifier$': invalid clip plane property\"\n" +".errtext INVALID_POINT_PROPERTY \"1031: '$e_identifier$': invalid point property\"\n" +".errtext MATRIX_ROW_SELECTOR_OR_MODIFIER_EXPECTED \"1032: matrix row selector or modifier expected but '$e_token$' found\"\n" +".errtext INVALID_MATRIX_NAME \"1033: '$e_identifier$': invalid matrix name\"\n" +".errtext INVALID_PROGRAM_PROPERTY \"1034: '$e_identifier$': invalid program property\"\n" +".errtext RESULT_EXPECTED \"1035: 'result' expected but '$e_token$' found\"\n" +".errtext INVALID_RESULT_PROPERTY \"1036: '$e_identifier$': invalid result property\"\n" +".errtext INVALID_FACE_PROPERTY \"1037: '$e_identifier$': invalid face property\"\n" +".errtext INVALID_COLOR_PROPERTY \"1038: '$e_identifier$': invalid color property\"\n" +".errtext IDENTIFIER_EXPECTED \"1039: identifier expected but '$e_token$' found\"\n" +".errtext RESERVED_KEYWORD \"1040: use of reserved keyword as an identifier\"\n" +".errtext INTEGER_EXPECTED \"1041: integer value expected but '$e_token$' found\"\n" +".errtext MISSING_SEMICOLON \"1042: ';' expected but '$e_token$' found\"\n" +".errtext MISSING_COMMA \"1043: ',' expected but '$e_token$' found\"\n" +".errtext MISSING_LBRACKET \"1044: '[' expected but '$e_token$' found\"\n" +".errtext MISSING_RBRACKET \"1045: ']' expected but '$e_token$' found\"\n" +".errtext MISSING_DOT \"1046: '.' expected but '$e_token$' found\"\n" +".errtext MISSING_EQUAL \"1047: '=' expected but '$e_token$' found\"\n" +".errtext MISSING_LBRACE \"1048: '{' expected but '$e_token$' found\"\n" +".errtext MISSING_RBRACE \"1049: '}' expected but '$e_token$' found\"\n" +".errtext MISSING_DOTDOT \"1050: '..' expected but '$e_token$' found\"\n" +".errtext MISSING_FRACTION_OR_EXPONENT \"1051: missing fraction part or exponent\"\n" +".errtext MISSING_DOT_OR_EXPONENT \"1052: missing '.' or exponent\"\n" +".errtext EXPONENT_VALUE_EXPECTED \"1053: exponent value expected\"\n" +".errtext INTEGER_OUT_OF_RANGE \"1054: integer value out of range\"\n" +".errtext OPERATION_NEEDS_DESTINATION_VARIABLE \"1055: operation needs destination variable\"\n" +".errtext OPERATION_NEEDS_SOURCE_VARIABLE \"1056: operation needs source variable\"\n" +".errtext ADDRESS_REGISTER_EXPECTED \"1057: address register expected but '$e_token$' found\"\n" +".errtext ADDRESS_REGISTER_OR_INTEGER_EXPECTED \"1058: address register or integer literal expected but '$e_token$' found\"\n" +".regbyte vertex_blend 0x00\n" +".regbyte matrix_palette 0x00\n" +".regbyte point_parameters 0x00\n" +".regbyte secondary_color 0x00\n" +".regbyte fog_coord 0x00\n" +".regbyte texture_rectangle 0x00\n" +".regbyte fragment_program_shadow 0x00\n" +".regbyte draw_buffers 0x00\n" +".regbyte ARB_precision_hint_fastest 0x00\n" +".regbyte ARB_precision_hint_nicest 0x00\n" +".regbyte ARB_fog_exp 0x00\n" +".regbyte ARB_fog_exp2 0x00\n" +".regbyte ARB_fog_linear 0x00\n" +".regbyte ARB_position_invariant 0x00\n" +".regbyte ARB_fragment_program_shadow 0x00\n" +".regbyte ARB_draw_buffers 0x00\n" +".regbyte program_target 0x00\n" +"program\n" +" programs .error UNKNOWN_PROGRAM_SIGNATURE .emit REVISION;\n" +"programs\n" +" .if (program_target == 0x10) frag_program_1_0 .emit FRAGMENT_PROGRAM .emit 0x01 .emit 0x00 .or\n" +" .if (program_target == 0x20) vert_program_1_0 .emit VERTEX_PROGRAM .emit 0x01 .emit 0x00;\n" +"frag_program_1_0\n" +" '!' .and '!' .and 'A' .and 'R' .and 'B' .and 'f' .and 'p' .and '1' .and '.' .and '0' .and\n" +" optional_space .and fp_optionSequence .and fp_statementSequence .and\n" +" \"END\" .error MISSING_END_OR_INVALID_STATEMENT .emit END .and optional_space .and\n" +" '\\0' .error CODE_AFTER_END;\n" +"vert_program_1_0\n" +" '!' .and '!' .and 'A' .and 'R' .and 'B' .and 'v' .and 'p' .and '1' .and '.' .and '0' .and\n" +" optional_space .and vp_optionSequence .and vp_statementSequence .and\n" +" \"END\" .error MISSING_END_OR_INVALID_STATEMENT .emit END .and optional_space .and\n" +" '\\0' .error CODE_AFTER_END;\n" +"fp_optionSequence\n" +" .loop fp_option;\n" +"vp_optionSequence\n" +" .loop vp_option;\n" +"fp_option\n" +" \"OPTION\" .emit OPTION .and space .error IDENTIFIER_EXPECTED .and\n" +" fp_optionString .error INVALID_PROGRAM_OPTION .and semicolon;\n" +"vp_option\n" +" \"OPTION\" .emit OPTION .and space .error IDENTIFIER_EXPECTED .and\n" +" vp_optionString .error INVALID_PROGRAM_OPTION .and semicolon;\n" +"fp_optionString\n" +" .if (ARB_precision_hint_nicest == 0x00) \"ARB_precision_hint_fastest\"\n" +" .emit ARB_PRECISION_HINT_FASTEST .load ARB_precision_hint_fastest 0x01 .or\n" +" .if (ARB_precision_hint_fastest == 0x00) \"ARB_precision_hint_nicest\"\n" +" .emit ARB_PRECISION_HINT_NICEST .load ARB_precision_hint_nicest 0x01 .or\n" +" fp_ARB_fog_exp .emit ARB_FOG_EXP .load ARB_fog_exp 0x01 .or\n" +" fp_ARB_fog_exp2 .emit ARB_FOG_EXP2 .load ARB_fog_exp2 0x01 .or\n" +" fp_ARB_fog_linear .emit ARB_FOG_LINEAR .load ARB_fog_linear 0x01 .or\n" +" .if (fragment_program_shadow != 0x00) \"ARB_fragment_program_shadow\"\n" +" .emit ARB_FRAGMENT_PROGRAM_SHADOW .load ARB_fragment_program_shadow 0x01 .or\n" +" .if (draw_buffers != 0x00) \"ARB_draw_buffers\" .emit ARB_DRAW_BUFFERS\n" +" .load ARB_draw_buffers 0x01;\n" +"vp_optionString\n" +" \"ARB_position_invariant\" .emit ARB_POSITION_INVARIANT .load ARB_position_invariant 0x01;\n" +"fp_ARB_fog_exp\n" +" .if (ARB_fog_exp2 == 0x00) .true .and .if (ARB_fog_linear == 0x00) \"ARB_fog_exp\";\n" +"fp_ARB_fog_exp2\n" +" .if (ARB_fog_exp == 0x00) .true .and .if (ARB_fog_linear == 0x00) \"ARB_fog_exp2\";\n" +"fp_ARB_fog_linear\n" +" .if (ARB_fog_exp == 0x00) .true .and .if (ARB_fog_exp2 == 0x00) \"ARB_fog_linear\";\n" +"fp_statementSequence\n" +" .loop fp_statement;\n" +"vp_statementSequence\n" +" .loop vp_statement;\n" +"fp_statement\n" +" fp_statement_1 .or fp_statement_2;\n" +"vp_statement\n" +" vp_statement_1 .or vp_statement_2;\n" +"fp_statement_1\n" +" fp_instruction .emit INSTRUCTION .emit $ .and semicolon;\n" +"fp_statement_2\n" +" fp_namingStatement .emit DECLARATION .and semicolon;\n" +"vp_statement_1\n" +" vp_instruction .emit INSTRUCTION .emit $ .and semicolon;\n" +"vp_statement_2\n" +" vp_namingStatement .emit DECLARATION .and semicolon;\n" +"fp_instruction\n" +" ALUInstruction .emit OP_ALU_INST .or\n" +" TexInstruction .emit OP_TEX_INST;\n" +"vp_instruction\n" +" ARL_instruction .emit OP_ALU_ARL .or\n" +" vp_VECTORop_instruction .emit OP_ALU_VECTOR .or\n" +" vp_SCALARop_instruction .emit OP_ALU_SCALAR .or\n" +" vp_BINSCop_instruction .emit OP_ALU_BINSC .or\n" +" vp_BINop_instruction .emit OP_ALU_BIN .or\n" +" vp_TRIop_instruction .emit OP_ALU_TRI .or\n" +" vp_SWZ_instruction .emit OP_ALU_SWZ;\n" +"ALUInstruction\n" +" fp_VECTORop_instruction .emit OP_ALU_VECTOR .or\n" +" fp_SCALARop_instruction .emit OP_ALU_SCALAR .or\n" +" fp_BINSCop_instruction .emit OP_ALU_BINSC .or\n" +" fp_BINop_instruction .emit OP_ALU_BIN .or\n" +" fp_TRIop_instruction .emit OP_ALU_TRI .or\n" +" fp_SWZ_instruction .emit OP_ALU_SWZ;\n" +"TexInstruction\n" +" SAMPLE_instruction .emit OP_TEX_SAMPLE .or\n" +" KIL_instruction .emit OP_TEX_KIL;\n" +"ARL_instruction\n" +" \"ARL\" .emit OP_ARL .and space_dst .and maskedAddrReg .and comma .and vp_scalarSrcReg;\n" +"fp_VECTORop_instruction\n" +" fp_VECTORop .and space_dst .and fp_maskedDstReg .and comma .and vectorSrcReg;\n" +"vp_VECTORop_instruction\n" +" vp_VECTORop .and space_dst .and vp_maskedDstReg .and comma .and swizzleSrcReg;\n" +"fp_VECTORop\n" +" \"ABS\" .emit OP_ABS .or \"ABS_SAT\" .emit OP_ABS_SAT .or\n" +" \"FLR\" .emit OP_FLR .or \"FLR_SAT\" .emit OP_FLR_SAT .or\n" +" \"FRC\" .emit OP_FRC .or \"FRC_SAT\" .emit OP_FRC_SAT .or\n" +" \"LIT\" .emit OP_LIT .or \"LIT_SAT\" .emit OP_LIT_SAT .or\n" +" \"MOV\" .emit OP_MOV .or \"MOV_SAT\" .emit OP_MOV_SAT;\n" +"vp_VECTORop\n" +" \"ABS\" .emit OP_ABS .or\n" +" \"FLR\" .emit OP_FLR .or\n" +" \"FRC\" .emit OP_FRC .or\n" +" \"LIT\" .emit OP_LIT .or\n" +" \"MOV\" .emit OP_MOV;\n" +"fp_SCALARop_instruction\n" +" fp_SCALARop .and space_dst .and fp_maskedDstReg .and comma .and fp_scalarSrcReg;\n" +"vp_SCALARop_instruction\n" +" vp_SCALARop .and space_dst .and vp_maskedDstReg .and comma .and vp_scalarSrcReg;\n" +"fp_SCALARop\n" +" \"COS\" .emit OP_COS .or \"COS_SAT\" .emit OP_COS_SAT .or\n" +" \"EX2\" .emit OP_EX2 .or \"EX2_SAT\" .emit OP_EX2_SAT .or\n" +" \"LG2\" .emit OP_LG2 .or \"LG2_SAT\" .emit OP_LG2_SAT .or\n" +" \"RCP\" .emit OP_RCP .or \"RCP_SAT\" .emit OP_RCP_SAT .or\n" +" \"RSQ\" .emit OP_RSQ .or \"RSQ_SAT\" .emit OP_RSQ_SAT .or\n" +" \"SIN\" .emit OP_SIN .or \"SIN_SAT\" .emit OP_SIN_SAT .or\n" +" \"SCS\" .emit OP_SCS .or \"SCS_SAT\" .emit OP_SCS_SAT;\n" +"vp_SCALARop\n" +" \"EX2\" .emit OP_EX2 .or\n" +" \"EXP\" .emit OP_EXP .or\n" +" \"LG2\" .emit OP_LG2 .or\n" +" \"LOG\" .emit OP_LOG .or\n" +" \"RCP\" .emit OP_RCP .or\n" +" \"RSQ\" .emit OP_RSQ;\n" +"fp_BINSCop_instruction\n" +" fp_BINSCop .and space_dst .and fp_maskedDstReg .and comma .and fp_scalarSrcReg .and comma .and\n" +" fp_scalarSrcReg;\n" +"vp_BINSCop_instruction\n" +" vp_BINSCop .and space_dst .and vp_maskedDstReg .and comma .and vp_scalarSrcReg .and comma .and\n" +" vp_scalarSrcReg;\n" +"fp_BINSCop\n" +" \"POW\" .emit OP_POW .or \"POW_SAT\" .emit OP_POW_SAT;\n" +"vp_BINSCop\n" +" \"POW\" .emit OP_POW;\n" +"fp_BINop_instruction\n" +" fp_BINop .and space_dst .and fp_maskedDstReg .and comma .and vectorSrcReg .and comma .and\n" +" vectorSrcReg;\n" +"vp_BINop_instruction\n" +" vp_BINop .and space_dst .and vp_maskedDstReg .and comma .and swizzleSrcReg .and comma .and\n" +" swizzleSrcReg;\n" +"fp_BINop\n" +" \"ADD\" .emit OP_ADD .or \"ADD_SAT\" .emit OP_ADD_SAT .or\n" +" \"DP3\" .emit OP_DP3 .or \"DP3_SAT\" .emit OP_DP3_SAT .or\n" +" \"DP4\" .emit OP_DP4 .or \"DP4_SAT\" .emit OP_DP4_SAT .or\n" +" \"DPH\" .emit OP_DPH .or \"DPH_SAT\" .emit OP_DPH_SAT .or\n" +" \"DST\" .emit OP_DST .or \"DST_SAT\" .emit OP_DST_SAT .or\n" +" \"MAX\" .emit OP_MAX .or \"MAX_SAT\" .emit OP_MAX_SAT .or\n" +" \"MIN\" .emit OP_MIN .or \"MIN_SAT\" .emit OP_MIN_SAT .or\n" +" \"MUL\" .emit OP_MUL .or \"MUL_SAT\" .emit OP_MUL_SAT .or\n" +" \"SGE\" .emit OP_SGE .or \"SGE_SAT\" .emit OP_SGE_SAT .or\n" +" \"SLT\" .emit OP_SLT .or \"SLT_SAT\" .emit OP_SLT_SAT .or\n" +" \"SUB\" .emit OP_SUB .or \"SUB_SAT\" .emit OP_SUB_SAT .or\n" +" \"XPD\" .emit OP_XPD .or \"XPD_SAT\" .emit OP_XPD_SAT;\n" +"vp_BINop\n" +" \"ADD\" .emit OP_ADD .or\n" +" \"DP3\" .emit OP_DP3 .or\n" +" \"DP4\" .emit OP_DP4 .or\n" +" \"DPH\" .emit OP_DPH .or\n" +" \"DST\" .emit OP_DST .or\n" +" \"MAX\" .emit OP_MAX .or\n" +" \"MIN\" .emit OP_MIN .or\n" +" \"MUL\" .emit OP_MUL .or\n" +" \"SGE\" .emit OP_SGE .or\n" +" \"SLT\" .emit OP_SLT .or\n" +" \"SUB\" .emit OP_SUB .or\n" +" \"XPD\" .emit OP_XPD;\n" +"fp_TRIop_instruction\n" +" fp_TRIop .and space_dst .and fp_maskedDstReg .and comma .and vectorSrcReg .and comma .and\n" +" vectorSrcReg .and comma .and vectorSrcReg;\n" +"vp_TRIop_instruction\n" +" vp_TRIop .and space_dst .and vp_maskedDstReg .and comma .and swizzleSrcReg .and comma .and\n" +" swizzleSrcReg .and comma .and swizzleSrcReg;\n" +"fp_TRIop\n" +" \"CMP\" .emit OP_CMP .or \"CMP_SAT\" .emit OP_CMP_SAT .or\n" +" \"LRP\" .emit OP_LRP .or \"LRP_SAT\" .emit OP_LRP_SAT .or\n" +" \"MAD\" .emit OP_MAD .or \"MAD_SAT\" .emit OP_MAD_SAT;\n" +"vp_TRIop\n" +" \"MAD\" .emit OP_MAD;\n" +"fp_SWZ_instruction\n" +" SWZop .and space_dst .and fp_maskedDstReg .and comma .and fp_srcReg .and comma .and\n" +" fp_extendedSwizzle .error EXT_SWIZ_COMP_EXPECTED;\n" +"vp_SWZ_instruction\n" +" \"SWZ\" .emit OP_SWZ .and space_dst .and vp_maskedDstReg .and comma .and vp_srcReg .and comma .and\n" +" vp_extendedSwizzle .error EXT_SWIZ_COMP_EXPECTED;\n" +"SWZop\n" +" \"SWZ\" .emit OP_SWZ .or \"SWZ_SAT\" .emit OP_SWZ_SAT;\n" +"SAMPLE_instruction\n" +" SAMPLEop .and space_dst .and fp_maskedDstReg .and comma .and vectorSrcReg .and comma .and\n" +" texImageUnit .and comma .and texTarget .error TEX_TARGET_EXPECTED;\n" +"SAMPLEop\n" +" \"TEX\" .emit OP_TEX .or \"TEX_SAT\" .emit OP_TEX_SAT .or\n" +" \"TXB\" .emit OP_TXB .or \"TXB_SAT\" .emit OP_TXB_SAT .or\n" +" \"TXP\" .emit OP_TXP .or \"TXP_SAT\" .emit OP_TXP_SAT;\n" +"KIL_instruction\n" +" \"KIL\" .emit OP_KIL .and space_src .and vectorSrcReg;\n" +"texImageUnit\n" +" \"texture\" .error TEXTURE_EXPECTED .and optTexImageUnitNum;\n" +"texTarget\n" +" \"1D\" .emit TEXTARGET_1D .or\n" +" \"2D\" .emit TEXTARGET_2D .or\n" +" \"3D\" .emit TEXTARGET_3D .or\n" +" .if (texture_rectangle != 0x00) \"RECT\" .emit TEXTARGET_RECT .or\n" +" \"CUBE\" .emit TEXTARGET_CUBE .or\n" +" .if (ARB_fragment_program_shadow != 0x00) shadowTarget;\n" +"shadowTarget\n" +" \"SHADOW1D\" .emit TEXTARGET_SHADOW1D .or\n" +" \"SHADOW2D\" .emit TEXTARGET_SHADOW2D .or\n" +" .if (texture_rectangle != 0x00) \"SHADOWRECT\" .emit TEXTARGET_SHADOWRECT;\n" +"optTexImageUnitNum\n" +" optTexImageUnitNum_1 .or .true .emit 0x00;\n" +"optTexImageUnitNum_1\n" +" lbracket_ne .and texImageUnitNum .and rbracket;\n" +"texImageUnitNum\n" +" integer;\n" +"fp_scalarSrcReg\n" +" optionalSign .and fp_srcReg .and fp_scalarSuffix;\n" +"vp_scalarSrcReg\n" +" optionalSign .and vp_srcReg .and vp_scalarSuffix;\n" +"swizzleSrcReg\n" +" optionalSign .and vp_srcReg .and swizzleSuffix;\n" +"vectorSrcReg\n" +" optionalSign .and fp_srcReg .and optionalSuffix;\n" +"fp_maskedDstReg\n" +" fp_dstReg .and fp_optionalMask;\n" +"vp_maskedDstReg\n" +" vp_dstReg .and vp_optionalMask;\n" +"maskedAddrReg\n" +" addrReg .error ADDRESS_REGISTER_EXPECTED .and addrWriteMask;\n" +"fp_extendedSwizzle\n" +" rgbaExtendedSwizzle .or xyzwExtendedSwizzle;\n" +"vp_extendedSwizzle\n" +" extSwizComp .and comma .and\n" +" extSwizComp .error EXT_SWIZ_COMP_EXPECTED .and comma .and\n" +" extSwizComp .error EXT_SWIZ_COMP_EXPECTED .and comma .and\n" +" extSwizComp .error EXT_SWIZ_COMP_EXPECTED;\n" +"xyzwExtendedSwizzle\n" +" xyzwExtSwizComp .and comma .and\n" +" xyzwExtSwizComp .error EXT_SWIZ_COMP_EXPECTED .and comma .and\n" +" xyzwExtSwizComp .error EXT_SWIZ_COMP_EXPECTED .and comma .and\n" +" xyzwExtSwizComp .error EXT_SWIZ_COMP_EXPECTED;\n" +"rgbaExtendedSwizzle\n" +" rgbaExtendedSwizzle_1 .or rgbaExtendedSwizzle_2 .or rgbaExtendedSwizzle_3 .or\n" +" rgbaExtendedSwizzle_4;\n" +"rgbaExtendedSwizzle_1\n" +" rgbaExtSwizComp_digit .and comma .and rgbaExtSwizComp_digit .and comma .and\n" +" rgbaExtSwizComp_digit .and comma .and rgbaExtSwizComp;\n" +"rgbaExtendedSwizzle_2\n" +" rgbaExtSwizComp_digit .and comma .and rgbaExtSwizComp_digit .and comma .and\n" +" rgbaExtSwizComp_alpha .and comma .and rgbaExtSwizComp .error EXT_SWIZ_COMP_EXPECTED;\n" +"rgbaExtendedSwizzle_3\n" +" rgbaExtSwizComp_digit .and comma .and rgbaExtSwizComp_alpha .and comma .and\n" +" rgbaExtSwizComp .error EXT_SWIZ_COMP_EXPECTED .and comma .and\n" +" rgbaExtSwizComp .error EXT_SWIZ_COMP_EXPECTED;\n" +"rgbaExtendedSwizzle_4\n" +" rgbaExtSwizComp_alpha .and comma .and \n" +"rgbaExtSwizComp .error EXT_SWIZ_COMP_EXPECTED .and comma .and\n" +" rgbaExtSwizComp .error EXT_SWIZ_COMP_EXPECTED .and comma .and\n" +" rgbaExtSwizComp .error EXT_SWIZ_COMP_EXPECTED;\n" +"xyzwExtSwizComp\n" +" optionalSign .and xyzwExtSwizSel;\n" +"rgbaExtSwizComp\n" +" optionalSign .and rgbaExtSwizSel;\n" +"rgbaExtSwizComp_digit\n" +" optionalSign .and rgbaExtSwizSel_digit;\n" +"rgbaExtSwizComp_alpha\n" +" optionalSign .and rgbaExtSwizSel_alpha;\n" +"extSwizComp\n" +" optionalSign .and extSwizSel;\n" +"xyzwExtSwizSel\n" +" \"0\" .emit COMPONENT_0 .or \"1\" .emit COMPONENT_1 .or xyzwComponent_single;\n" +"rgbaExtSwizSel\n" +" rgbaExtSwizSel_digit .or rgbaExtSwizSel_alpha;\n" +"rgbaExtSwizSel_digit\n" +" \"0\" .emit COMPONENT_0 .or \"1\" .emit COMPONENT_1;\n" +"rgbaExtSwizSel_alpha\n" +" rgbaComponent_single;\n" +"extSwizSel\n" +" \"0\" .emit COMPONENT_0 .or \"1\" .emit COMPONENT_1 .or vp_component_single;\n" +"fp_srcReg\n" +" fp_srcReg_1 .error SOURCE_REGISTER_EXPECTED;\n" +"vp_srcReg\n" +" vp_srcReg_1 .error SOURCE_REGISTER_EXPECTED;\n" +"fp_srcReg_1\n" +" fragmentAttribReg .emit REGISTER_ATTRIB .or\n" +" fp_progParamReg .emit REGISTER_PARAM .or\n" +" fp_temporaryReg .emit REGISTER_ESTABLISHED_NAME;\n" +"vp_srcReg_1\n" +" vertexAttribReg .emit REGISTER_ATTRIB .or\n" +" vp_progParamReg .emit REGISTER_PARAM .or\n" +" vp_temporaryReg .emit REGISTER_ESTABLISHED_NAME;\n" +"fp_dstReg\n" +" fp_dstReg_1 .error DESTINATION_REGISTER_EXPECTED;\n" +"vp_dstReg\n" +" vp_dstReg_1 .error DESTINATION_REGISTER_EXPECTED;\n" +"fp_dstReg_1\n" +" fragmentResultReg .emit REGISTER_RESULT .or\n" +" fp_temporaryReg .emit REGISTER_ESTABLISHED_NAME;\n" +"vp_dstReg_1\n" +" vertexResultReg .emit REGISTER_RESULT .or\n" +" vp_temporaryReg .emit REGISTER_ESTABLISHED_NAME;\n" +"fragmentAttribReg\n" +" fragAttribBinding;\n" +"vertexAttribReg\n" +" vtxAttribBinding;\n" +"fp_temporaryReg\n" +" fp_establishedName_no_error_on_identifier;\n" +"vp_temporaryReg\n" +" vp_establishedName_no_error_on_identifier;\n" +"fp_progParamReg\n" +" fp_paramSingleItemUse .or fp_progParamReg_1 .or fp_progParamSingle;\n" +"vp_progParamReg\n" +" vp_paramSingleItemUse .or vp_progParamReg_1 .or vp_progParamSingle;\n" +"fp_progParamReg_1\n" +" fp_progParamArray .emit PARAM_ARRAY_ELEMENT .and lbracket_ne .and progParamArrayAbs .and\n" +" rbracket;\n" +"vp_progParamReg_1\n" +" vp_progParamArray .emit PARAM_ARRAY_ELEMENT .and lbracket_ne .and progParamArrayMem .and\n" +" rbracket;\n" +"fp_progParamSingle\n" +" .false;\n" +"vp_progParamSingle\n" +" .false;\n" +"fp_progParamArray\n" +" fp_establishedName_no_error_on_identifier;\n" +"vp_progParamArray\n" +" vp_establishedName_no_error_on_identifier;\n" +"progParamArrayMem\n" +" progParamArrayAbs .or progParamArrayRel;\n" +"progParamArrayAbs\n" +" integer_ne .emit ARRAY_INDEX_ABSOLUTE;\n" +"progParamArrayRel\n" +" addrReg .error ADDRESS_REGISTER_OR_INTEGER_EXPECTED .emit ARRAY_INDEX_RELATIVE .and\n" +" addrComponent .and addrRegRelOffset;\n" +"addrRegRelOffset\n" +" addrRegRelOffset_1 .or addrRegRelOffset_2 .or .true .emit 0x00;\n" +"addrRegRelOffset_1\n" +" plus_ne .and addrRegPosOffset;\n" +"addrRegRelOffset_2\n" +" minus_ne .and addrRegNegOffset;\n" +"addrRegPosOffset\n" +" integer_0_63;\n" +"addrRegNegOffset\n" +" integer_0_64;\n" +"fragmentResultReg\n" +" fp_resultBinding;\n" +"vertexResultReg\n" +" vp_resultBinding;\n" +"addrReg\n" +" vp_establishedName_no_error_on_identifier;\n" +"addrComponent\n" +" dot .and \"x\" .error INVALID_ADDRESS_COMPONENT .emit COMPONENT_X .emit COMPONENT_X\n" +" .emit COMPONENT_X .emit COMPONENT_X;\n" +"addrWriteMask\n" +" dot .and \"x\" .error INVALID_ADDRESS_WRITEMASK .emit 0x08;\n" +"fp_scalarSuffix\n" +" dot .and fp_component_single .error INVALID_COMPONENT;\n" +"vp_scalarSuffix\n" +" dot .and vp_component_single .error INVALID_COMPONENT;\n" +"swizzleSuffix\n" +" swizzleSuffix_1 .or\n" +" .true .emit COMPONENT_X .emit COMPONENT_Y .emit COMPONENT_Z .emit COMPONENT_W;\n" +"swizzleSuffix_1\n" +" dot_ne .and swizzleSuffix_2 .error INVALID_SUFFIX;\n" +"swizzleSuffix_2\n" +" swizzleSuffix_3 .or swizzleSuffix_4;\n" +"swizzleSuffix_3\n" +" vp_component_multi .and vp_component_multi .and vp_component_multi .error INVALID_COMPONENT .and\n" +" vp_component_multi .error INVALID_COMPONENT;\n" +"swizzleSuffix_4\n" +" \"x\" .emit COMPONENT_X .emit COMPONENT_X .emit COMPONENT_X .emit COMPONENT_X .or\n" +" \"y\" .emit COMPONENT_Y .emit COMPONENT_Y .emit COMPONENT_Y .emit COMPONENT_Y .or\n" +" \"z\" .emit COMPONENT_Z .emit COMPONENT_Z .emit COMPONENT_Z .emit COMPONENT_Z .or\n" +" \"w\" .emit COMPONENT_W .emit COMPONENT_W .emit COMPONENT_W .emit COMPONENT_W;\n" +"optionalSuffix\n" +" optionalSuffix_1 .or\n" +" .true .emit COMPONENT_X .emit COMPONENT_Y .emit COMPONENT_Z .emit COMPONENT_W;\n" +"optionalSuffix_1\n" +" dot_ne .and optionalSuffix_2 .error INVALID_SUFFIX;\n" +"optionalSuffix_2\n" +" optionalSuffix_3 .or optionalSuffix_4 .or optionalSuffix_5;\n" +"optionalSuffix_3\n" +" xyzwComponent_multi .and xyzwComponent_multi .and\n" +" xyzwComponent_multi .error INVALID_COMPONENT .and xyzwComponent_multi .error INVALID_COMPONENT;\n" +"optionalSuffix_4\n" +" rgbaComponent_multi .and rgbaComponent_multi .and\n" +" rgbaComponent_multi .error INVALID_COMPONENT .and rgbaComponent_multi .error INVALID_COMPONENT;\n" +"optionalSuffix_5\n" +" \"x\" .emit COMPONENT_X .emit COMPONENT_X .emit COMPONENT_X .emit COMPONENT_X .or\n" +" \"y\" .emit COMPONENT_Y .emit COMPONENT_Y .emit COMPONENT_Y .emit COMPONENT_Y .or\n" +" \"z\" .emit COMPONENT_Z .emit COMPONENT_Z .emit COMPONENT_Z .emit COMPONENT_Z .or\n" +" \"w\" .emit COMPONENT_W .emit COMPONENT_W .emit COMPONENT_W .emit COMPONENT_W .or\n" +" \"r\" .emit COMPONENT_X .emit COMPONENT_X .emit COMPONENT_X .emit COMPONENT_X .or\n" +" \"g\" .emit COMPONENT_Y .emit COMPONENT_Y .emit COMPONENT_Y .emit COMPONENT_Y .or\n" +" \"b\" .emit COMPONENT_Z .emit COMPONENT_Z .emit COMPONENT_Z .emit COMPONENT_Z .or\n" +" \"a\" .emit COMPONENT_W .emit COMPONENT_W .emit COMPONENT_W .emit COMPONENT_W;\n" +"fp_component_single\n" +" xyzwComponent_single .or rgbaComponent_single;\n" +"vp_component_multi\n" +" 'x' .emit COMPONENT_X .or 'y' .emit COMPONENT_Y .or 'z' .emit COMPONENT_Z .or\n" +" 'w' .emit COMPONENT_W;\n" +"vp_component_single\n" +" \"x\" .emit COMPONENT_X .or \"y\" .emit COMPONENT_Y .or \"z\" .emit COMPONENT_Z .or\n" +" \"w\" .emit COMPONENT_W;\n" +"xyzwComponent_multi\n" +" 'x' .emit COMPONENT_X .or 'y' .emit COMPONENT_Y .or 'z' .emit COMPONENT_Z .or\n" +" 'w' .emit COMPONENT_W;\n" +"xyzwComponent_single\n" +" \"x\" .emit COMPONENT_X .or \"y\" .emit COMPONENT_Y .or \"z\" .emit COMPONENT_Z .or\n" +" \"w\" .emit COMPONENT_W;\n" +"rgbaComponent_multi\n" +" 'r' .emit COMPONENT_X .or 'g' .emit COMPONENT_Y .or 'b' .emit COMPONENT_Z .or\n" +" 'a' .emit COMPONENT_W;\n" +"rgbaComponent_single\n" +" \"r\" .emit COMPONENT_X .or \"g\" .emit COMPONENT_Y .or \"b\" .emit COMPONENT_Z .or\n" +" \"a\" .emit COMPONENT_W;\n" +"fp_optionalMask\n" +" rgbaMask .or xyzwMask .or .true .emit 0x0F;\n" +"vp_optionalMask\n" +" xyzwMask .or .true .emit 0x0F;\n" +"xyzwMask\n" +" dot_ne .and xyzwMask_1 .error INVALID_WRITEMASK;\n" +"xyzwMask_1\n" +" \"xyzw\" .emit 0x0F .or \"xyz\" .emit 0x0E .or \"xyw\" .emit 0x0D .or \"xy\" .emit 0x0C .or\n" +" \"xzw\" .emit 0x0B .or \"xz\" .emit 0x0A .or \"xw\" .emit 0x09 .or \"x\" .emit 0x08 .or\n" +" \"yzw\" .emit 0x07 .or \"yz\" .emit 0x06 .or \"yw\" .emit 0x05 .or \"y\" .emit 0x04 .or\n" +" \"zw\" .emit 0x03 .or \"z\" .emit 0x02 .or \"w\" .emit 0x01;\n" +"rgbaMask\n" +" dot_ne .and rgbaMask_1;\n" +"rgbaMask_1\n" +" \"rgba\" .emit 0x0F .or \"rgb\" .emit 0x0E .or \"rga\" .emit 0x0D .or \"rg\" .emit 0x0C .or\n" +" \"rba\" .emit 0x0B .or \"rb\" .emit 0x0A .or \"ra\" .emit 0x09 .or \"r\" .emit 0x08 .or\n" +" \"gba\" .emit 0x07 .or \"gb\" .emit 0x06 .or \"ga\" .emit 0x05 .or \"g\" .emit 0x04 .or\n" +" \"ba\" .emit 0x03 .or \"b\" .emit 0x02 .or \"a\" .emit 0x01;\n" +"fp_namingStatement\n" +" fp_ATTRIB_statement .emit ATTRIB .or\n" +" fp_PARAM_statement .emit PARAM .or\n" +" fp_TEMP_statement .emit TEMP .or\n" +" fp_OUTPUT_statement .emit OUTPUT .or\n" +" fp_ALIAS_statement .emit ALIAS;\n" +"vp_namingStatement\n" +" vp_ATTRIB_statement .emit ATTRIB .or\n" +" vp_PARAM_statement .emit PARAM .or\n" +" vp_TEMP_statement .emit TEMP .or\n" +" ADDRESS_statement .emit ADDRESS .or\n" +" vp_OUTPUT_statement .emit OUTPUT .or\n" +" vp_ALIAS_statement .emit ALIAS;\n" +"fp_ATTRIB_statement\n" +" \"ATTRIB\" .and space .and fp_establishName .and equal .and\n" +" fragAttribBinding .error FRAGMENT_EXPECTED;\n" +"vp_ATTRIB_statement\n" +" \"ATTRIB\" .and space .and vp_establishName .and equal .and\n" +" vtxAttribBinding .error VERTEX_EXPECTED;\n" +"fragAttribBinding\n" +" \"fragment\" .and dot .and fragAttribItem .error INVALID_FRAGMENT_PROPERTY;\n" +"vtxAttribBinding\n" +" \"vertex\" .and dot .and vtxAttribItem .error INVALID_VERTEX_PROPERTY;\n" +"fragAttribItem\n" +" fragAttribItem_1 .emit FRAGMENT_ATTRIB_COLOR .or\n" +" fragAttribItem_2 .emit FRAGMENT_ATTRIB_TEXCOORD .or\n" +" .if (fog_coord != 0x00) \"fogcoord\" .emit FRAGMENT_ATTRIB_FOGCOORD .or\n" +" \"position\" .emit FRAGMENT_ATTRIB_POSITION;\n" +"fragAttribItem_1\n" +" \"color\" .and optColorType;\n" +"fragAttribItem_2\n" +" \"texcoord\" .and optTexCoordNum;\n" +"vtxAttribItem\n" +" \"position\" .emit VERTEX_ATTRIB_POSITION .or\n" +" .if (vertex_blend != 0x00) vtxAttribItem_1 .emit VERTEX_ATTRIB_WEIGHT .or\n" +" \"normal\" .emit VERTEX_ATTRIB_NORMAL .or\n" +" vtxAttribItem_2 .emit VERTEX_ATTRIB_COLOR .or\n" +" \"fogcoord\" .emit VERTEX_ATTRIB_FOGCOORD .or\n" +" vtxAttribItem_3 .emit VERTEX_ATTRIB_TEXCOORD .or\n" +" .if (matrix_palette != 0x00) vtxAttribItem_4 .emit VERTEX_ATTRIB_MATRIXINDEX .or\n" +" vtxAttribItem_5 .emit VERTEX_ATTRIB_GENERIC;\n" +"vtxAttribItem_1\n" +" \"weight\" .and vtxOptWeightNum;\n" +"vtxAttribItem_2\n" +" \"color\" .and optColorType;\n" +"vtxAttribItem_3\n" +" \"texcoord\" .and optTexCoordNum;\n" +"vtxAttribItem_4\n" +" \"matrixindex\" .and lbracket .and vtxWeightNum .and rbracket;\n" +"vtxAttribItem_5\n" +" \"attrib\" .and lbracket .and vtxAttribNum .and rbracket;\n" +"vtxAttribNum\n" +" integer;\n" +"vtxOptWeightNum\n" +" vtxOptWeightNum_1 .or .true .emit 0x00;\n" +"vtxOptWeightNum_1\n" +" lbracket_ne .and vtxWeightNum .and rbracket;\n" +"vtxWeightNum\n" +" integer;\n" +"fp_PARAM_statement\n" +" fp_PARAM_multipleStmt .or fp_PARAM_singleStmt;\n" +"vp_PARAM_statement\n" +" vp_PARAM_multipleStmt .or vp_PARAM_singleStmt;\n" +"fp_PARAM_singleStmt\n" +" \"PARAM\" .and space .and fp_establishName .and .true .emit 0x00 .and fp_paramSingleInit .and\n" +" .true .emit PARAM_NULL;\n" +"vp_PARAM_singleStmt\n" +" \"PARAM\" .and space .and vp_establishName .and .true .emit 0x00 .and vp_paramSingleInit .and\n" +" .true .emit PARAM_NULL;\n" +"fp_PARAM_multipleStmt\n" +" \"PARAM\" .and space .and fp_establishName .and lbracket_ne .and optArraySize .and rbracket .and\n" +" fp_paramMultipleInit .and .true .emit PARAM_NULL;\n" +"vp_PARAM_multipleStmt\n" +" \"PARAM\" .and space .and vp_establishName .and lbracket_ne .and optArraySize .and rbracket .and\n" +" vp_paramMultipleInit .and .true .emit PARAM_NULL;\n" +"optArraySize\n" +" optional_integer;\n" +"fp_paramSingleInit\n" +" equal .and fp_paramSingleItemDecl;\n" +"vp_paramSingleInit\n" +" equal .and vp_paramSingleItemDecl;\n" +"fp_paramMultipleInit\n" +" equal .and lbrace .and fp_paramMultInitList .and rbrace;\n" +"vp_paramMultipleInit\n" +" equal .and lbrace .and vp_paramMultInitList .and rbrace;\n" +"fp_paramMultInitList\n" +" fp_paramMultInitList_1 .or fp_paramMultipleItem;\n" +"vp_paramMultInitList\n" +" vp_paramMultInitList_1 .or vp_paramMultipleItem;\n" +"fp_paramMultInitList_1\n" +" fp_paramMultipleItem .and comma_ne .and fp_paramMultInitList;\n" +"vp_paramMultInitList_1\n" +" vp_paramMultipleItem .and comma_ne .and vp_paramMultInitList;\n" +"fp_paramSingleItemDecl\n" +" fp_stateSingleItem .emit PARAM_STATE_ELEMENT .or\n" +" programSingleItem .emit PARAM_PROGRAM_ELEMENT .or\n" +" paramConstDecl .emit PARAM_CONSTANT;\n" +"vp_paramSingleItemDecl\n" +" vp_stateSingleItem .emit PARAM_STATE_ELEMENT .or\n" +" programSingleItem .emit PARAM_PROGRAM_ELEMENT .or\n" +" paramConstDecl .emit PARAM_CONSTANT;\n" +"fp_paramSingleItemUse\n" +" fp_stateSingleItem .emit PARAM_STATE_ELEMENT .or\n" +" programSingleItem .emit PARAM_PROGRAM_ELEMENT .or\n" +" paramConstUse .emit PARAM_CONSTANT;\n" +"vp_paramSingleItemUse\n" +" vp_stateSingleItem .emit PARAM_STATE_ELEMENT .or\n" +" programSingleItem .emit PARAM_PROGRAM_ELEMENT .or\n" +" paramConstUse .emit PARAM_CONSTANT;\n" +"fp_paramMultipleItem\n" +" fp_stateMultipleItem .emit PARAM_STATE_ELEMENT .or\n" +" programMultipleItem .emit PARAM_PROGRAM_ELEMENT .or\n" +" paramConstDecl .emit PARAM_CONSTANT;\n" +"vp_paramMultipleItem\n" +" vp_stateMultipleItem .emit PARAM_STATE_ELEMENT .or\n" +" programMultipleItem .emit PARAM_PROGRAM_ELEMENT .or\n" +" paramConstDecl .emit PARAM_CONSTANT;\n" +"fp_stateMultipleItem\n" +" stateMultipleItem_1 .or fp_stateSingleItem;\n" +"vp_stateMultipleItem\n" +" stateMultipleItem_1 .or vp_stateSingleItem;\n" +"stateMultipleItem_1\n" +" \"state\" .and dot .and stateMatrixRows .emit STATE_MATRIX_ROWS;\n" +"fp_stateSingleItem\n" +" \"state\" .and dot .and fp_stateSingleItem_1 .error INVALID_STATE_PROPERTY;\n" +"vp_stateSingleItem\n" +" \"state\" .and dot .and vp_stateSingleItem_1 .error INVALID_STATE_PROPERTY;\n" +"fp_stateSingleItem_1\n" +" stateSingleItem_1 .or stateSingleItem_2 .or stateSingleItem_3 .or stateSingleItem_4 .or\n" +" stateSingleItem_5 .or stateSingleItem_7 .or stateSingleItem_8 .or stateSingleItem_11;\n" +"vp_stateSingleItem_1\n" +" stateSingleItem_1 .or stateSingleItem_2 .or stateSingleItem_3 .or stateSingleItem_4 .or\n" +" stateSingleItem_6 .or stateSingleItem_7 .or stateSingleItem_9 .or stateSingleItem_10 .or\n" +" stateSingleItem_11;\n" +"stateSingleItem_1\n" +" stateMaterialItem .emit STATE_MATERIAL;\n" +"stateSingleItem_2\n" +" stateLightItem .emit STATE_LIGHT;\n" +"stateSingleItem_3\n" +" stateLightModelItem .emit STATE_LIGHT_MODEL;\n" +"stateSingleItem_4\n" +" stateLightProdItem .emit STATE_LIGHT_PROD;\n" +"stateSingleItem_5\n" +" stateTexEnvItem .emit STATE_TEX_ENV;\n" +"stateSingleItem_6\n" +" stateTexGenItem .emit STATE_TEX_GEN;\n" +"stateSingleItem_7\n" +" stateFogItem .emit STATE_FOG;\n" +"stateSingleItem_8\n" +" stateDepthItem .emit STATE_DEPTH;\n" +"stateSingleItem_9\n" +" stateClipPlaneItem .emit STATE_CLIP_PLANE;\n" +"stateSingleItem_10\n" +" statePointItem .emit STATE_POINT;\n" +"stateSingleItem_11\n" +" stateMatrixRow .emit STATE_MATRIX_ROWS;\n" +"stateMaterialItem\n" +" \"material\" .and optFaceType .and dot .and stateMatProperty .error INVALID_MATERIAL_PROPERTY;\n" +"stateMatProperty\n" +" \"ambient\" .emit MATERIAL_AMBIENT .or\n" +" \"diffuse\" .emit MATERIAL_DIFFUSE .or\n" +" \"specular\" .emit MATERIAL_SPECULAR .or\n" +" \"emission\" .emit MATERIAL_EMISSION .or\n" +" \"shininess\" .emit MATERIAL_SHININESS;\n" +"stateLightItem\n" +" \"light\" .and lbracket .and stateLightNumber .and rbracket .and dot .and\n" +" stateLightProperty .error INVALID_LIGHT_PROPERTY;\n" +"stateLightProperty\n" +" \"ambient\" .emit LIGHT_AMBIENT .or\n" +" \"diffuse\" .emit LIGHT_DIFFUSE .or\n" +" \"specular\" .emit LIGHT_SPECULAR .or\n" +" \"position\" .emit LIGHT_POSITION .or\n" +" \"attenuation\" .emit LIGHT_ATTENUATION .or\n" +" stateLightProperty_1 .emit LIGHT_SPOT_DIRECTION .or\n" +" \"half\" .emit LIGHT_HALF;\n" +"stateLightProperty_1\n" +" \"spot\" .and dot .and stateSpotProperty .error INVALID_SPOT_PROPERTY;\n" +"stateSpotProperty\n" +" \"direction\";\n" +"stateLightModelItem\n" +" \"lightmodel\" .and stateLModProperty .error INVALID_LIGHTMODEL_PROPERTY;\n" +"stateLModProperty\n" +" stateLModProperty_1 .or stateLModProperty_2;\n" +"stateLModProperty_1\n" +" dot .and \"ambient\" .emit LIGHT_MODEL_AMBIENT;\n" +"stateLModProperty_2\n" +" stateLModProperty_3 .emit LIGHT_MODEL_SCENECOLOR;\n" +"stateLModProperty_3\n" +" optFaceType .and dot .and \"scenecolor\";\n" +"stateLightProdItem\n" +" \"lightprod\" .and lbracket .and stateLightNumber .and rbracket .and optFaceType .and dot .and\n" +" stateLProdProperty .error INVALID_LIGHTPROD_PROPERTY;\n" +"stateLProdProperty\n" +" \"ambient\" .emit LIGHT_PROD_AMBIENT .or\n" +" \"diffuse\" .emit LIGHT_PROD_DIFFUSE .or\n" +" \"specular\" .emit LIGHT_PROD_SPECULAR;\n" +"stateLightNumber\n" +" integer;\n" +"stateTexEnvItem\n" +" \"texenv\" .and optLegacyTexUnitNum .and dot .and\n" +" stateTexEnvProperty .error INVALID_TEXENV_PROPERTY;\n" +"stateTexEnvProperty\n" +" \"color\" .emit TEX_ENV_COLOR;\n" +"optLegacyTexUnitNum\n" +" lbracket_ne .and legacyTexUnitNum .and rbracket;\n" +"legacyTexUnitNum\n" +" integer;\n" +"stateTexGenItem\n" +" \"texgen\" .and optTexCoordNum .and dot .and stateTexGenType .error INVALID_TEXGEN_PROPERTY .and\n" +" dot .and stateTexGenCoord .error INVALID_TEXGEN_COORD;\n" +"stateTexGenType\n" +" \"eye\" .emit TEX_GEN_EYE .or\n" +" \"object\" .emit TEX_GEN_OBJECT;\n" +"stateTexGenCoord\n" +" \"s\" .emit COMPONENT_X .or\n" +" \"t\" .emit COMPONENT_Y .or\n" +" \"r\" .emit COMPONENT_Z .or\n" +" \"q\" .emit COMPONENT_W;\n" +"stateFogItem\n" +" \"fog\" .and dot .and stateFogProperty .error INVALID_FOG_PROPERTY;\n" +"stateFogProperty\n" +" \"color\" .emit FOG_COLOR .or\n" +" \"params\" .emit FOG_PARAMS;\n" +"stateDepthItem\n" +" \"depth\" .and dot .and stateDepthProperty .error INVALID_DEPTH_PROPERTY;\n" +"stateDepthProperty\n" +" \"range\" .emit DEPTH_RANGE;\n" +"stateClipPlaneItem\n" +" \"clip\" .and lbracket .and stateClipPlaneNum .and rbracket .and dot .and\n" +" \"plane\" .error INVALID_CLIPPLANE_PROPERTY;\n" +"stateClipPlaneNum\n" +" integer;\n" +"statePointItem\n" +" \"point\" .and dot .and statePointProperty .error INVALID_POINT_PROPERTY;\n" +"statePointProperty\n" +" \"size\" .emit POINT_SIZE .or\n" +" .if (point_parameters != 0x00) \"attenuation\" .emit POINT_ATTENUATION;\n" +"stateMatrixRow\n" +" stateMatrixItem .and dot .and \"row\" .error MATRIX_ROW_SELECTOR_OR_MODIFIER_EXPECTED .and\n" +" lbracket .and stateMatrixRowNum .and rbracket .emit 0x0;\n" +"stateMatrixRows\n" +" stateMatrixItem .and optMatrixRows;\n" +"optMatrixRows\n" +" optMatrixRows_1 .or .true .emit 0x0 .emit '3' .emit 0x0 .emit $;\n" +"optMatrixRows_1\n" +" dot_ne .and \"row\" .error MATRIX_ROW_SELECTOR_OR_MODIFIER_EXPECTED .and lbracket .and\n" +" stateMatrixRowNum .and dotdot .and stateMatrixRowNum .and rbracket;\n" +"stateMatrixItem\n" +" \"matrix\" .and dot .and stateMatrixName .error INVALID_MATRIX_NAME .and stateOptMatModifier;\n" +"stateOptMatModifier\n" +" stateOptMatModifier_1 .or .true .emit MATRIX_MODIFIER_IDENTITY;\n" +"stateOptMatModifier_1\n" +" dot_ne .and stateMatModifier;\n" +"stateMatModifier\n" +" \"inverse\" .emit MATRIX_MODIFIER_INVERSE .or\n" +" \"transpose\" .emit MATRIX_MODIFIER_TRANSPOSE .or\n" +" \"invtrans\" .emit MATRIX_MODIFIER_INVTRANS;\n" +"stateMatrixRowNum\n" +" integer_0_3;\n" +"stateMatrixName\n" +" stateMatrixName_1_1 .emit MATRIX_MODELVIEW .or\n" +" \"projection\" .emit MATRIX_PROJECTION .or\n" +" \"mvp\" .emit MATRIX_MVP .or\n" +" stateMatrixName_1_2 .emit MATRIX_TEXTURE .or\n" +" .if (matrix_palette != 0x00) stateMatrixName_1_3 .emit MATRIX_PALETTE .or\n" +" stateMatrixName_1_4 .emit MATRIX_PROGRAM;\n" +"stateMatrixName_1_1\n" +" \"modelview\" .and stateOptModMatNum;\n" +"stateMatrixName_1_2\n" +" \"texture\" .and optTexCoordNum;\n" +"stateMatrixName_1_3\n" +" \"palette\" .and lbracket .and statePaletteMatNum .and rbracket;\n" +"stateMatrixName_1_4\n" +" \"program\" .and lbracket .and stateProgramMatNum .and rbracket;\n" +"stateOptModMatNum\n" +" .if (vertex_blend != 0x00) stateOptModMatNum_1 .or\n" +" .true .emit 0x00;\n" +"stateOptModMatNum_1\n" +" lbracket_ne .and stateModMatNum .and rbracket;\n" +"stateModMatNum\n" +" integer;\n" +"optTexCoordNum\n" +" optTexCoordNum_1 .or .true .emit 0x00;\n" +"optTexCoordNum_1\n" +" lbracket_ne .and texCoordNum .and rbracket;\n" +"texCoordNum\n" +" integer;\n" +"statePaletteMatNum\n" +" integer;\n" +"stateProgramMatNum\n" +" integer;\n" +"programSingleItem\n" +" \"program\" .and dot .and programSingleItem_1 .error INVALID_PROGRAM_PROPERTY;\n" +"programSingleItem_1\n" +" progEnvParam .or progLocalParam;\n" +"programMultipleItem\n" +" \"program\" .and dot .and programMultipleItem_1 .error INVALID_PROGRAM_PROPERTY;\n" +"programMultipleItem_1\n" +" progEnvParams .or progLocalParams;\n" +"progEnvParams\n" +" \"env\" .emit PROGRAM_PARAM_ENV .and lbracket .and progEnvParamNums .and rbracket;\n" +"progEnvParamNums\n" +" progEnvParamNums_1 .or progEnvParamNums_2;\n" +"progEnvParamNums_1\n" +" progEnvParamNum .and dotdot_ne .and progEnvParamNum;\n" +"progEnvParamNums_2\n" +" progEnvParamNum .and .true .emit 0x00;\n" +"progEnvParam\n" +" \"env\" .emit PROGRAM_PARAM_ENV .and lbracket .and progEnvParamNum .and rbracket .emit 0x00;\n" +"progLocalParams\n" +" \"local\" .emit PROGRAM_PARAM_LOCAL .and lbracket .and progLocalParamNums .and rbracket;\n" +"progLocalParamNums\n" +" progLocalParamNums_1 .or progLocalParamNums_2;\n" +"progLocalParamNums_1\n" +" progLocalParamNum .and dotdot_ne .and progLocalParamNum;\n" +"progLocalParamNums_2\n" +" progLocalParamNum .and .true .emit 0x00;\n" +"progLocalParam\n" +" \"local\" .emit PROGRAM_PARAM_LOCAL .and lbracket .and progLocalParamNum .and rbracket .emit 0x00;\n" +"progEnvParamNum\n" +" integer;\n" +"progLocalParamNum\n" +" integer;\n" +"paramConstDecl\n" +" paramConstScalarDecl .emit CONSTANT_SCALAR .or paramConstVector .emit CONSTANT_VECTOR;\n" +"paramConstUse\n" +" paramConstScalarUse .emit CONSTANT_SCALAR .or paramConstVector .emit CONSTANT_VECTOR;\n" +"paramConstScalarDecl\n" +" signedFloatConstant;\n" +"paramConstScalarUse\n" +" floatConstant;\n" +"paramConstVector\n" +" paramConstVector_4 .emit 0x04 .or paramConstVector_3 .emit 0x03 .or\n" +" paramConstVector_2 .emit 0x02 .or paramConstVector_1 .emit 0x01;\n" +"paramConstVector_1\n" +" lbrace_ne .and signedFloatConstant .and rbrace;\n" +"paramConstVector_2\n" +" lbrace_ne .and signedFloatConstant .and comma_ne .and signedFloatConstant .and rbrace;\n" +"paramConstVector_3\n" +" lbrace_ne .and signedFloatConstant .and comma_ne .and signedFloatConstant .and comma_ne .and\n" +" signedFloatConstant .and rbrace;\n" +"paramConstVector_4\n" +" lbrace_ne .and signedFloatConstant .and comma_ne .and signedFloatConstant .and comma_ne .and\n" +" signedFloatConstant .and comma_ne .and signedFloatConstant .and rbrace;\n" +"signedFloatConstant\n" +" optionalSign .and floatConstant;\n" +"floatConstant\n" +" float;\n" +"optionalSign\n" +" optional_sign_ne;\n" +"fp_TEMP_statement\n" +" \"TEMP\" .and space .and fp_varNameList .and .true .emit 0x00;\n" +"vp_TEMP_statement\n" +" \"TEMP\" .and space .and vp_varNameList .and .true .emit 0x00;\n" +"ADDRESS_statement\n" +" \"ADDRESS\" .and space .and vp_varNameList .and .true .emit 0x00;\n" +"fp_varNameList\n" +" fp_varNameList_1 .or fp_establishName;\n" +"vp_varNameList\n" +" vp_varNameList_1 .or vp_establishName;\n" +"fp_varNameList_1\n" +" fp_establishName .and comma_ne .and fp_varNameList;\n" +"vp_varNameList_1\n" +" vp_establishName .and comma_ne .and vp_varNameList;\n" +"fp_OUTPUT_statement\n" +" \"OUTPUT\" .and space .and fp_establishName .and equal .and\n" +" fp_resultBinding .error RESULT_EXPECTED;\n" +"vp_OUTPUT_statement\n" +" \"OUTPUT\" .and space .and vp_establishName .and equal .and\n" +" vp_resultBinding .error RESULT_EXPECTED;\n" +"fp_resultBinding\n" +" \"result\" .and dot .and fp_resultBinding_1 .error INVALID_RESULT_PROPERTY;\n" +"vp_resultBinding\n" +" \"result\" .and dot .and vp_resultBinding_1 .error INVALID_RESULT_PROPERTY;\n" +"fp_resultBinding_1\n" +" fp_resultBinding_2 .emit FRAGMENT_RESULT_COLOR .or\n" +" \"depth\" .emit FRAGMENT_RESULT_DEPTH;\n" +"fp_resultBinding_2\n" +" \"color\" .and optOutputColorNum;\n" +"vp_resultBinding_1\n" +" .if (ARB_position_invariant == 0x00) \"position\" .emit VERTEX_RESULT_POSITION .or\n" +" resultColBinding .emit VERTEX_RESULT_COLOR .or\n" +" \"fogcoord\" .emit VERTEX_RESULT_FOGCOORD .or\n" +" \"pointsize\" .emit VERTEX_RESULT_POINTSIZE .or\n" +" vp_resultBinding_2 .emit VERTEX_RESULT_TEXCOORD;\n" +"vp_resultBinding_2\n" +" \"texcoord\" .and optTexCoordNum;\n" +"optOutputColorNum\n" +" .if (ARB_draw_buffers != 0x00) optOutputColorNum_1 .or .true .emit 0x00;\n" +"optOutputColorNum_1\n" +" lbracket_ne .and outputColorNum .and rbracket;\n" +"outputColorNum\n" +" integer;\n" +"resultColBinding\n" +" \"color\" .and optFaceType .and optColorType;\n" +"optFaceType\n" +" FaceType .or .true .emit FACE_FRONT;\n" +"FaceType\n" +" dot_ne .and FaceProperty;\n" +"FaceProperty\n" +" \"front\" .emit FACE_FRONT .or \"back\" .emit FACE_BACK;\n" +"optColorType\n" +" ColorType .or .true .emit COLOR_PRIMARY;\n" +"ColorType\n" +" dot_ne .and ColorProperty;\n" +"ColorProperty\n" +" \"primary\" .emit COLOR_PRIMARY .or\n" +" .if (secondary_color != 0x00) \"secondary\" .emit COLOR_SECONDARY;\n" +"fp_ALIAS_statement\n" +" \"ALIAS\" .and fp_ALIAS_statement_1 .error IDENTIFIER_EXPECTED .and equal .and fp_establishedName;\n" +"vp_ALIAS_statement\n" +" \"ALIAS\" .and vp_ALIAS_statement_1 .error IDENTIFIER_EXPECTED .and equal .and vp_establishedName;\n" +"fp_ALIAS_statement_1\n" +" space .and fp_establishName;\n" +"vp_ALIAS_statement_1\n" +" space .and vp_establishName;\n" +"fp_establishName\n" +" fp_identifier;\n" +"vp_establishName\n" +" vp_identifier;\n" +"fp_establishedName\n" +" fp_identifier;\n" +"vp_establishedName\n" +" vp_identifier;\n" +"fp_establishedName_no_error_on_identifier\n" +" fp_identifier_ne;\n" +"vp_establishedName_no_error_on_identifier\n" +" vp_identifier_ne;\n" +"fp_identifier\n" +" fp_identifier_ne .error IDENTIFIER_EXPECTED;\n" +"vp_identifier\n" +" vp_identifier_ne .error IDENTIFIER_EXPECTED;\n" +"fp_identifier_ne\n" +" fp_not_reserved_identifier .and identifier_ne;\n" +"vp_identifier_ne\n" +" vp_not_reserved_identifier .and identifier_ne;\n" +"fp_not_reserved_identifier\n" +" fp_not_reserved_identifier_1 .or .true;\n" +"fp_not_reserved_identifier_1\n" +" fp_reserved_identifier .and .false .error RESERVED_KEYWORD;\n" +"vp_not_reserved_identifier\n" +" vp_not_reserved_identifier_1 .or .true;\n" +"vp_not_reserved_identifier_1\n" +" vp_reserved_identifier .and .false .error RESERVED_KEYWORD;\n" +"fp_reserved_identifier\n" +" \"ABS\" .or \"ABS_SAT\" .or \"ADD\" .or \"ADD_SAT\" .or \"ALIAS\" .or \"ATTRIB\" .or \"CMP\" .or \"CMP_SAT\" .or\n" +" \"COS\" .or \"COS_SAT\" .or \"DP3\" .or \"DP3_SAT\" .or \"DP4\" .or \"DP4_SAT\" .or \"DPH\" .or \"DPH_SAT\" .or\n" +" \"DST\" .or \"DST_SAT\" .or \"END\" .or \"EX2\" .or \"EX2_SAT\" .or \"FLR\" .or \"FLR_SAT\" .or \"FRC\" .or\n" +" \"FRC_SAT\" .or \"KIL\" .or \"LG2\" .or \"LG2_SAT\" .or \"LIT\" .or \"LIT_SAT\" .or \"LRP\" .or \"LRP_SAT\" .or\n" +" \"MAD\" .or \"MAD_SAT\" .or \"MAX\" .or \"MAX_SAT\" .or \"MIN\" .or \"MIN_SAT\" .or \"MOV\" .or \"MOV_SAT\" .or\n" +" \"MUL\" .or \"MUL_SAT\" .or \"OPTION\" .or \"OUTPUT\" .or \"PARAM\" .or \"POW\" .or \"POW_SAT\" .or \"RCP\" .or\n" +" \"RCP_SAT\" .or \"RSQ\" .or \"RSQ_SAT\" .or \"SIN\" .or \"SIN_SAT\" .or \"SCS\" .or \"SCS_SAT\" .or \"SGE\" .or\n" +" \"SGE_SAT\" .or \"SLT\" .or \"SLT_SAT\" .or \"SUB\" .or \"SUB_SAT\" .or \"SWZ\" .or \"SWZ_SAT\" .or \"TEMP\" .or\n" +" \"TEX\" .or \"TEX_SAT\" .or \"TXB\" .or \"TXB_SAT\" .or \"TXP\" .or \"TXP_SAT\" .or \"XPD\" .or \"XPD_SAT\" .or\n" +" \"fragment\" .or \"program\" .or \"result\" .or \"state\" .or \"texture\";\n" +"vp_reserved_identifier\n" +" \"ABS\" .or \"ADD\" .or \"ADDRESS\" .or \"ALIAS\" .or \"ARL\" .or \"ATTRIB\" .or \"DP3\" .or \"DP4\" .or\n" +" \"DPH\" .or \"DST\" .or \"END\" .or \"EX2\" .or \"EXP\" .or \"FLR\" .or \"FRC\" .or \"LG2\" .or \"LIT\" .or\n" +" \"LOG\" .or \"MAD\" .or \"MAX\" .or \"MIN\" .or \"MOV\" .or \"MUL\" .or \"OPTION\" .or \"OUTPUT\" .or\n" +" \"PARAM\" .or \"POW\" .or \"RCP\" .or \"RSQ\" .or \"SGE\" .or \"SLT\" .or \"SUB\" .or \"SWZ\" .or \"TEMP\" .or\n" +" \"XPD\" .or \"program\" .or \"result\" .or \"state\" .or \"vertex\";\n" +"integer\n" +" integer_ne .error INTEGER_EXPECTED;\n" +"zero\n" +" '0';\n" +"leading_zeroes\n" +" .loop zero;\n" +"no_digit\n" +" no_digit_1 .or .true;\n" +"no_digit_1\n" +" digit10 .and .false .error INTEGER_OUT_OF_RANGE;\n" +"all_zeroes\n" +" all_zeroes_1 .or no_digit_1;\n" +"all_zeroes_1\n" +" '0' .and .loop zero .and no_digit;\n" +"integer_0_3\n" +" integer_0_3_1 .error INTEGER_EXPECTED .and .true .emit 0x00 .emit $;\n" +"integer_0_3_1\n" +" integer_0_3_2 .or all_zeroes .emit '0';\n" +"integer_0_3_2 \n" +" leading_zeroes .and '1'-'3' .emit * .and no_digit;\n" +"integer_0_63\n" +" integer_0_63_1 .error INTEGER_EXPECTED .and .true .emit 0x00 .emit $;\n" +"integer_0_63_1\n" +" integer_0_63_2 .or integer_0_63_3 .or integer_0_63_4 .or integer_0_63_5 .or\n" +" all_zeroes .emit '0';\n" +"integer_0_63_2 \n" +" leading_zeroes .and '7'-'9' .emit * .and no_digit;\n" +"integer_0_63_3 \n" +" leading_zeroes .and '1'-'5' .emit * .and '0'-'9' .emit * .and no_digit;\n" +"integer_0_63_4 \n" +" leading_zeroes .and '6' .emit * .and '0'-'3' .emit * .and no_digit;\n" +"integer_0_63_5 \n" +" leading_zeroes .and '1'-'6' .emit * .and no_digit;\n" +"integer_0_64\n" +" integer_0_64_1 .error INTEGER_EXPECTED .and .true .emit 0x00 .emit $;\n" +"integer_0_64_1\n" +" integer_0_64_2 .or integer_0_64_3 .or integer_0_64_4 .or integer_0_64_5 .or\n" +" all_zeroes .emit '0';\n" +"integer_0_64_2 \n" +" leading_zeroes .and '7'-'9' .emit * .and no_digit;\n" +"integer_0_64_3 \n" +" leading_zeroes .and '1'-'5' .emit * .and '0'-'9' .emit * .and no_digit;\n" +"integer_0_64_4 \n" +" leading_zeroes .and '6' .emit * .and '0'-'4' .emit * .and no_digit;\n" +"integer_0_64_5 \n" +" leading_zeroes .and '1'-'6' .emit * .and no_digit;\n" +"optional_space\n" +" space .or .true;\n" +"space_dst\n" +" space .error OPERATION_NEEDS_DESTINATION_VARIABLE;\n" +"space_src\n" +" space .error OPERATION_NEEDS_SOURCE_VARIABLE;\n" +"space\n" +" single_space .and .loop single_space;\n" +"single_space\n" +" white_char .or comment_block;\n" +"white_char\n" +" ' ' .or '\\t' .or '\\n' .or '\\r';\n" +"comment_block\n" +" '#' .and .loop comment_char .and new_line;\n" +"comment_char\n" +" '\\x0E'-'\\xFF' .or '\\x01'-'\\x09' .or '\\x0B'-'\\x0C';\n" +"new_line\n" +" '\\n' .or crlf .or '\\0';\n" +"crlf\n" +" '\\r' .and '\\n';\n" +"semicolon\n" +" optional_space .and ';' .error MISSING_SEMICOLON .and optional_space;\n" +"comma\n" +" optional_space .and ',' .error MISSING_COMMA .and optional_space;\n" +"comma_ne\n" +" optional_space .and ',' .and optional_space;\n" +"lbracket\n" +" optional_space .and '[' .error MISSING_LBRACKET .and optional_space;\n" +"lbracket_ne\n" +" optional_space .and '[' .and optional_space;\n" +"rbracket\n" +" optional_space .and ']' .error MISSING_RBRACKET .and optional_space;\n" +"dot\n" +" optional_space .and '.' .error MISSING_DOT .and optional_space;\n" +"dot_ne\n" +" optional_space .and '.' .and optional_space;\n" +"equal\n" +" optional_space .and '=' .error MISSING_EQUAL .and optional_space;\n" +"lbrace\n" +" optional_space .and '{' .error MISSING_LBRACE .and optional_space;\n" +"lbrace_ne\n" +" optional_space .and '{' .and optional_space;\n" +"rbrace\n" +" optional_space .and '}' .error MISSING_RBRACE .and optional_space;\n" +"dotdot\n" +" optional_space .and '.' .and '.' .error MISSING_DOTDOT .and optional_space;\n" +"dotdot_ne\n" +" optional_space .and '.' .and '.' .and optional_space;\n" +"float\n" +" float_1 .or float_2 .or float_legacy;\n" +"float_1\n" +" '.' .emit 0x00 .and integer_ne .error MISSING_FRACTION_OR_EXPONENT .and optional_exponent;\n" +"float_2\n" +" integer_ne .and float_3;\n" +"float_3\n" +" float_4 .or float_5;\n" +"float_4\n" +" '.' .and optional_integer .and optional_exponent;\n" +"float_5\n" +" exponent .emit 0x00;\n" +"float_legacy\n" +" integer_ne .and .true .emit 0x00 .emit 0x00;\n" +"integer_ne\n" +" integer_ne_1 .and .true .emit 0x00 .emit $;\n" +"integer_ne_1\n" +" digit10 .emit * .and .loop digit10 .emit *;\n" +"optional_integer\n" +" integer_ne .or .true .emit 0x00;\n" +"optional_exponent\n" +" exponent .or .true .emit 0x00;\n" +"exponent\n" +" exponent_1 .and optional_sign_ne .and integer_ne .error EXPONENT_VALUE_EXPECTED;\n" +"exponent_1\n" +" 'e' .or 'E';\n" +"optional_sign_ne\n" +" minus_ne .or plus_ne .or .true;\n" +"plus_ne\n" +" optional_space .and '+' .and optional_space;\n" +"minus_ne\n" +" optional_space .and '-' .emit '-' .and optional_space;\n" +"identifier_ne\n" +" first_idchar .emit * .and .loop follow_idchar .emit * .and .true .emit 0x00 .emit $;\n" +"follow_idchar\n" +" first_idchar .or digit10;\n" +"first_idchar\n" +" 'a'-'z' .or 'A'-'Z' .or '_' .or '$';\n" +"digit10\n" +" '0'-'9';\n" +".string __string_filter;\n" +"__string_filter\n" +" .loop __identifier_char;\n" +"__identifier_char\n" +" 'a'-'z' .or 'A'-'Z' .or '_' .or '$' .or '0'-'9';\n" +"e_signature\n" +" e_signature_char .and .loop e_signature_char;\n" +"e_signature_char\n" +" '!' .or '.' .or 'A'-'Z' .or 'a'-'z' .or '0'-'9';\n" +"e_statement\n" +" .loop e_statement_not_term;\n" +"e_statement_not_term\n" +" '\\x3C'-'\\xFF' .or '\\x0E'-'\\x3A' .or '\\x01'-'\\x09' .or '\\x0B'-'\\x0C';\n" +"e_identifier\n" +" e_identifier_first .and .loop e_identifier_next;\n" +"e_identifier_first\n" +" 'a'-'z' .or 'A'-'Z' .or '_' .or '$';\n" +"e_identifier_next\n" +" e_identifier_first .or '0'-'9';\n" +"e_token\n" +" e_identifier .or e_token_number .or '[' .or ']' .or '.' .or '{' .or '}' .or '=' .or '+' .or\n" +" '-' .or ',' .or ';';\n" +"e_token_number\n" +" e_token_digit .and .loop e_token_digit;\n" +"e_token_digit\n" +" '0'-'9';\n" +"e_charordigit\n" +" 'A'-'Z' .or 'a'-'z' .or '0'-'9';\n" +"" diff --git a/nx-X11/extras/Mesa/src/mesa/shader/arbvertparse.c b/nx-X11/extras/Mesa/src/mesa/shader/arbvertparse.c new file mode 100644 index 000000000..5d1ad3de2 --- /dev/null +++ b/nx-X11/extras/Mesa/src/mesa/shader/arbvertparse.c @@ -0,0 +1,207 @@ +/* + * Mesa 3-D graphics library + * Version: 6.2 + * + * Copyright (C) 1999-2004 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_VP 0 + +/** + * \file arbvertparse.c + * ARB_vertex_program parser. + * \author Karl Rasche + */ + +#include "glheader.h" +#include "context.h" +#include "arbvertparse.h" +#include "hash.h" +#include "imports.h" +#include "macros.h" +#include "mtypes.h" +#include "program.h" +#include "nvprogram.h" +#include "nvvertparse.h" +#include "nvvertprog.h" + +#include "arbprogparse.h" + + +/** + * XXX this is probably redundant. We've already got code like this + * in the nvvertparse.c file. Combine/clean-up someday. + */ +void _mesa_debug_vp_inst(GLint num, struct vp_instruction *vp) +{ + GLint a; + static const char *opcode_string[] = { + "ABS", + "ADD", + "ARL", + "DP3", + "DP4", + "DPH", + "DST", + "END", /* Placeholder */ + "EX2", /* ARB only */ + "EXP", + "FLR", /* ARB */ + "FRC", /* ARB */ + "LG2", /* ARB only */ + "LIT", + "LOG", + "MAD", + "MAX", + "MIN", + "MOV", + "MUL", + "POW", /* ARB only */ + "PRINT", /* Mesa only */ + "RCC", + "RCP", + "RSQ", + "SGE", + "SLT", + "SUB", + "SWZ", /* ARB only */ + "XPD" /* ARB only */ + }; + + static const char *file_string[] = { + "TEMP", + "INPUT", + "OUTPUT", + "LOCAL", + "ENV", + "NAMED", + "STATE", + "WRITE_ONLY", + "ADDR" + }; + + static const char swz[] = "xyzw01??"; + + for (a=0; a<num; a++) { + _mesa_printf("%s", opcode_string[vp[a].Opcode]); + + if (vp[a].DstReg.File != 0xf) { + if (vp[a].DstReg.WriteMask != 0xf) + _mesa_printf(" %s[%d].%s%s%s%s ", file_string[vp[a].DstReg.File], vp[a].DstReg.Index, + GET_BIT(vp[a].DstReg.WriteMask, 0) ? "x" : "", + GET_BIT(vp[a].DstReg.WriteMask, 1) ? "y" : "", + GET_BIT(vp[a].DstReg.WriteMask, 2) ? "z" : "", + GET_BIT(vp[a].DstReg.WriteMask, 3) ? "w" : ""); + else + _mesa_printf(" %s[%d] ", file_string[vp[a].DstReg.File], vp[a].DstReg.Index); + } + + if (vp[a].SrcReg[0].File != 0xf) { + if (vp[a].SrcReg[0].Swizzle != SWIZZLE_NOOP || + vp[a].SrcReg[0].Negate) + _mesa_printf("%s[%d].%s%c%c%c%c ", file_string[vp[a].SrcReg[0].File], vp[a].SrcReg[0].Index, + vp[a].SrcReg[0].Negate ? "-" : "", + swz[GET_SWZ(vp[a].SrcReg[0].Swizzle, 0)], + swz[GET_SWZ(vp[a].SrcReg[0].Swizzle, 1)], + swz[GET_SWZ(vp[a].SrcReg[0].Swizzle, 2)], + swz[GET_SWZ(vp[a].SrcReg[0].Swizzle, 3)]); + else + _mesa_printf("%s[%d] ", file_string[vp[a].SrcReg[0].File], vp[a].SrcReg[0].Index); + } + + if (vp[a].SrcReg[1].File != 0xf) { + if (vp[a].SrcReg[1].Swizzle != SWIZZLE_NOOP || + vp[a].SrcReg[1].Negate) + _mesa_printf("%s[%d].%s%c%c%c%c ", file_string[vp[a].SrcReg[1].File], vp[a].SrcReg[1].Index, + vp[a].SrcReg[1].Negate ? "-" : "", + swz[GET_SWZ(vp[a].SrcReg[1].Swizzle, 0)], + swz[GET_SWZ(vp[a].SrcReg[1].Swizzle, 1)], + swz[GET_SWZ(vp[a].SrcReg[1].Swizzle, 2)], + swz[GET_SWZ(vp[a].SrcReg[1].Swizzle, 3)]); + else + _mesa_printf("%s[%d] ", file_string[vp[a].SrcReg[1].File], vp[a].SrcReg[1].Index); + } + + if (vp[a].SrcReg[2].File != 0xf) { + if (vp[a].SrcReg[2].Swizzle != SWIZZLE_NOOP || + vp[a].SrcReg[2].Negate) + _mesa_printf("%s[%d].%s%c%c%c%c ", file_string[vp[a].SrcReg[2].File], vp[a].SrcReg[2].Index, + vp[a].SrcReg[2].Negate ? "-" : "", + swz[GET_SWZ(vp[a].SrcReg[2].Swizzle, 0)], + swz[GET_SWZ(vp[a].SrcReg[2].Swizzle, 1)], + swz[GET_SWZ(vp[a].SrcReg[2].Swizzle, 2)], + swz[GET_SWZ(vp[a].SrcReg[2].Swizzle, 3)]); + else + _mesa_printf("%s[%d] ", file_string[vp[a].SrcReg[2].File], vp[a].SrcReg[2].Index); + } + + _mesa_printf("\n"); + } +} + + +/** + * 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 GLubyte * str, GLsizei len, + struct vertex_program *program) +{ + struct arb_program ap; + (void) target; + + /* set the program target before parsing */ + ap.Base.Target = GL_VERTEX_PROGRAM_ARB; + + if (!_mesa_parse_arb_program(ctx, str, len, &ap)) { + /* Error in the program. Just return. */ + return; + } + + /* Copy the relevant contents of the arb_program struct into the + * vertex_program struct. + */ + program->Base.String = ap.Base.String; + program->Base.NumInstructions = ap.Base.NumInstructions; + program->Base.NumTemporaries = ap.Base.NumTemporaries; + program->Base.NumParameters = ap.Base.NumParameters; + program->Base.NumAttributes = ap.Base.NumAttributes; + program->Base.NumAddressRegs = ap.Base.NumAddressRegs; + + program->IsPositionInvariant = ap.HintPositionInvariant; + program->InputsRead = ap.InputsRead; + program->OutputsWritten = ap.OutputsWritten; + + if (program->Parameters) { + /* free previous program's parameters */ + _mesa_free_parameter_list(program->Parameters); + } + program->Parameters = ap.Parameters; + + program->Instructions = ap.VPInstructions; + +#if DEBUG_VP + _mesa_debug_vp_inst(ap.Base.NumInstructions, ap.VPInstructions); +#endif + +} diff --git a/nx-X11/extras/Mesa/src/mesa/shader/arbvertparse.h b/nx-X11/extras/Mesa/src/mesa/shader/arbvertparse.h new file mode 100644 index 000000000..f2ac1570b --- /dev/null +++ b/nx-X11/extras/Mesa/src/mesa/shader/arbvertparse.h @@ -0,0 +1,36 @@ +/* + * 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. + */ + +#ifndef ARBVERTPARSE_H +#define ARBVERTPARSE_H + +extern void +_mesa_parse_arb_vertex_program(GLcontext * ctx, GLenum target, + const GLubyte * str, GLsizei len, + struct vertex_program *program); + +extern void +_mesa_debug_vp_inst(GLint num, struct vp_instruction *vp); + +#endif diff --git a/nx-X11/extras/Mesa/src/mesa/shader/atifragshader.c b/nx-X11/extras/Mesa/src/mesa/shader/atifragshader.c new file mode 100644 index 000000000..d8df8f518 --- /dev/null +++ b/nx-X11/extras/Mesa/src/mesa/shader/atifragshader.c @@ -0,0 +1,439 @@ +/** + * \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 "glheader.h" +#include "context.h" +#include "hash.h" +#include "imports.h" +#include "macros.h" +#include "enums.h" +#include "mtypes.h" +#include "atifragshader.h" + +#define MESA_DEBUG_ATI_FS 0 + +extern struct program _mesa_DummyProgram; + +static void +new_inst(struct ati_fragment_shader *prog) +{ + prog->Base.NumInstructions++; +} + +#if MESA_DEBUG_ATI_FS +static char * +create_dst_mod_str(GLuint mod) +{ + static char ret_str[1024]; + + _mesa_memset(ret_str, 0, 1024); + if (mod & GL_2X_BIT_ATI) + _mesa_strncat(ret_str, "|2X", 1024); + + if (mod & GL_4X_BIT_ATI) + _mesa_strncat(ret_str, "|4X", 1024); + + if (mod & GL_8X_BIT_ATI) + _mesa_strncat(ret_str, "|8X", 1024); + if (mod & GL_HALF_BIT_ATI) + _mesa_strncat(ret_str, "|HA", 1024); + if (mod & GL_QUARTER_BIT_ATI) + _mesa_strncat(ret_str, "|QU", 1024); + if (mod & GL_EIGHTH_BIT_ATI) + _mesa_strncat(ret_str, "|EI", 1024); + + if (mod & GL_SATURATE_BIT_ATI) + _mesa_strncat(ret_str, "|SAT", 1024); + + if (_mesa_strlen(ret_str) == 0) + _mesa_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 + +GLuint GLAPIENTRY +_mesa_GenFragmentShadersATI(GLuint range) +{ + GLuint first; + GLuint i; + GET_CURRENT_CONTEXT(ctx); + + first = _mesa_HashFindFreeKeyBlock(ctx->Shared->Programs, range); + for (i = 0; i < range; i++) { + _mesa_HashInsert(ctx->Shared->Programs, first + i, &_mesa_DummyProgram); + } + + return first; +} + +void GLAPIENTRY +_mesa_BindFragmentShaderATI(GLuint id) +{ + struct program *prog; + GET_CURRENT_CONTEXT(ctx); + struct ati_fragment_shader *curProg = ctx->ATIFragmentShader.Current; + + FLUSH_VERTICES(ctx, _NEW_PROGRAM); + + if (curProg->Base.Id == id) { + return; + } + + if (curProg->Base.Id != 0) { + curProg->Base.RefCount--; + if (curProg->Base.RefCount <= 0) { + _mesa_HashRemove(ctx->Shared->Programs, id); + } + } + + /* Go bind */ + if (id == 0) { + prog = ctx->Shared->DefaultFragmentShader; + } + else { + prog = (struct program *) _mesa_HashLookup(ctx->Shared->Programs, id); + if (!prog || prog == &_mesa_DummyProgram) { + /* allocate a new program now */ + prog = ctx->Driver.NewProgram(ctx, GL_FRAGMENT_SHADER_ATI, id); + if (!prog) { + _mesa_error(ctx, GL_OUT_OF_MEMORY, "glBindFragmentShaderATI"); + return; + } + _mesa_HashInsert(ctx->Shared->Programs, id, prog); + } + + } + + /* do actual bind */ + ctx->ATIFragmentShader.Current = (struct ati_fragment_shader *) prog; + + ASSERT(ctx->ATIFragmentShader.Current); + if (prog) + prog->RefCount++; + + /*if (ctx->Driver.BindProgram) + ctx->Driver.BindProgram(ctx, target, prog); */ +} + +void GLAPIENTRY +_mesa_DeleteFragmentShaderATI(GLuint id) +{ + GET_CURRENT_CONTEXT(ctx); + + if (id != 0) { + struct program *prog = (struct program *) + _mesa_HashLookup(ctx->Shared->Programs, id); + if (prog == &_mesa_DummyProgram) { + _mesa_HashRemove(ctx->Shared->Programs, id); + } + else if (prog) { + if (ctx->ATIFragmentShader.Current && + ctx->ATIFragmentShader.Current->Base.Id == id) { + _mesa_BindFragmentShaderATI(0); + } + } +#if 0 + if (!prog->DeletePending) { + prog->DeletePending = GL_TRUE; + prog->RefCount--; + } + if (prog->RefCount <= 0) { + _mesa_HashRemove(ctx->Shared->Programs, id); + ctx->Driver.DeleteProgram(ctx, prog); + } +#else + /* The ID is immediately available for re-use now */ + _mesa_HashRemove(ctx->Shared->Programs, id); + prog->RefCount--; + if (prog->RefCount <= 0) { + ctx->Driver.DeleteProgram(ctx, prog); + } +#endif + } +} + +void GLAPIENTRY +_mesa_BeginFragmentShaderATI(void) +{ + GET_CURRENT_CONTEXT(ctx); + + /* malloc the instructions here - not sure if the best place but its + a start */ + ctx->ATIFragmentShader.Current->Instructions = + (struct atifs_instruction *) + _mesa_calloc(sizeof(struct atifs_instruction) * MAX_NUM_PASSES_ATI * + MAX_NUM_INSTRUCTIONS_PER_PASS_ATI * 2); + + ctx->ATIFragmentShader.Current->cur_pass = 0; + ctx->ATIFragmentShader.Compiling = 1; +} + +void GLAPIENTRY +_mesa_EndFragmentShaderATI(void) +{ + GET_CURRENT_CONTEXT(ctx); +#if MESA_DEBUG_ATI_FS + struct ati_fragment_shader *curProg = ctx->ATIFragmentShader.Current; + GLint i; +#endif + + ctx->ATIFragmentShader.Compiling = 0; + ctx->ATIFragmentShader.Current->NumPasses = ctx->ATIFragmentShader.Current->cur_pass; + ctx->ATIFragmentShader.Current->cur_pass=0; +#if MESA_DEBUG_ATI_FS + for (i = 0; i < curProg->Base.NumInstructions; i++) { + GLuint op0 = curProg->Instructions[i].Opcode[0]; + GLuint op1 = curProg->Instructions[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[i].ArgCount[0]; + GLuint count1 = curProg->Instructions[i].ArgCount[1]; + + fprintf(stderr, "%2d %04X %s %d %04X %s %d\n", i, op0, op0_enum, count0, + op1, op1_enum, count1); + } +#endif +} + +void GLAPIENTRY +_mesa_PassTexCoordATI(GLuint dst, GLuint coord, GLenum swizzle) +{ + GET_CURRENT_CONTEXT(ctx); + struct ati_fragment_shader *curProg = ctx->ATIFragmentShader.Current; + GLint ci; + struct atifs_instruction *curI; + + if (ctx->ATIFragmentShader.Current->cur_pass==1) + ctx->ATIFragmentShader.Current->cur_pass=2; + + new_inst(curProg); + ci = curProg->Base.NumInstructions - 1; + /* some validation + if ((swizzle != GL_SWIZZLE_STR_ATI) || + (swizzle != GL_SWIZZLE_STQ_ATI) || + (swizzle != GL_SWIZZLE_STR_DR_ATI) || + (swizzle != GL_SWIZZLE_STQ_DQ_ATI)) + */ + + /* add the instructions */ + curI = &curProg->Instructions[ci]; + + curI->Opcode[0] = ATI_FRAGMENT_SHADER_PASS_OP; + curI->DstReg[0].Index = dst; + curI->SrcReg[0][0].Index = coord; + curI->DstReg[0].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; + GLint ci; + struct atifs_instruction *curI; + + if (ctx->ATIFragmentShader.Current->cur_pass==1) + ctx->ATIFragmentShader.Current->cur_pass=2; + + + new_inst(curProg); + + ci = curProg->Base.NumInstructions - 1; + /* add the instructions */ + curI = &curProg->Instructions[ci]; + + curI->Opcode[0] = ATI_FRAGMENT_SHADER_SAMPLE_OP; + curI->DstReg[0].Index = dst; + curI->DstReg[0].Swizzle = swizzle; + + curI->SrcReg[0][0].Index = interp; + +#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; + + if (ctx->ATIFragmentShader.Current->cur_pass==0) + ctx->ATIFragmentShader.Current->cur_pass=1; + + /* decide whether this is a new instruction or not ... all color instructions are new */ + if (optype == 0) + new_inst(curProg); + + ci = curProg->Base.NumInstructions - 1; + + /* add the instructions */ + curI = &curProg->Instructions[ci]; + + 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) +{ + GET_CURRENT_CONTEXT(ctx); + GLuint dstindex = dst - GL_CON_0_ATI; + struct ati_fragment_shader *curProg = ctx->ATIFragmentShader.Current; + + COPY_4V(curProg->Constants[dstindex], value); +} diff --git a/nx-X11/extras/Mesa/src/mesa/shader/atifragshader.h b/nx-X11/extras/Mesa/src/mesa/shader/atifragshader.h new file mode 100644 index 000000000..82ac4746b --- /dev/null +++ b/nx-X11/extras/Mesa/src/mesa/shader/atifragshader.h @@ -0,0 +1,105 @@ +/* + * Mesa 3-D graphics library ATI Fragment Shader + * + * Copyright (C) 2004 David Airlie All Rights Reserved. + * + */ + +#ifndef ATIFRAGSHADER_H +#define ATIFRAGSHADER_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; + GLuint Swizzle; +}; + +#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 - also pass/sample */ +/* 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]; +}; + +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/nx-X11/extras/Mesa/src/mesa/shader/grammar/grammar.c b/nx-X11/extras/Mesa/src/mesa/shader/grammar/grammar.c new file mode 100644 index 000000000..0b767c02c --- /dev/null +++ b/nx-X11/extras/Mesa/src/mesa/shader/grammar/grammar.c @@ -0,0 +1,3148 @@ +/* + * Mesa 3-D graphics library + * Version: 6.2 + * + * Copyright (C) 1999-2004 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 grammar.c + * syntax parsing engine + * \author Michal Krol + */ + +#ifndef GRAMMAR_PORT_BUILD +#error Do not build this file directly, build your grammar_XXX.c instead, which includes this file +#endif + +/* +*/ + +/* + INTRODUCTION + ------------ + + The task is to check the syntax of an input string. Input string is a stream of ASCII + characters terminated with a null-character ('\0'). Checking it using C language is + difficult and hard to implement without bugs. It is hard to maintain and make changes when + the syntax changes. + + This is because of a high redundancy of the C code. Large blocks of code are duplicated with + only small changes. Even use of macros does not solve the problem because macros cannot + erase the complexity of the problem. + + The resolution is to create a new language that will be highly oriented to our task. Once + we describe a particular syntax, we are done. We can then focus on the code that implements + the language. The size and complexity of it is relatively small than the code that directly + checks the syntax. + + First, we must implement our new language. Here, the language is implemented in C, but it + could also be implemented in any other language. The code is listed below. We must take + a good care that it is bug free. This is simple because the code is simple and clean. + + Next, we must describe the syntax of our new language in itself. Once created and checked + manually that it is correct, we can use it to check another scripts. + + Note that our new language loading code does not have to check the syntax. It is because we + assume that the script describing itself is correct, and other scripts can be syntactically + checked by the former script. The loading code must only do semantic checking which leads us to + simple resolving references. + + THE LANGUAGE + ------------ + + Here I will describe the syntax of the new language (further called "Synek"). It is mainly a + sequence of declarations terminated by a semicolon. The declaration consists of a symbol, + which is an identifier, and its definition. A definition is in turn a sequence of specifiers + connected with ".and" or ".or" operator. These operators cannot be mixed together in a one + definition. Specifier can be a symbol, string, character, character range or a special + keyword ".true" or ".false". + + On the very beginning of the script there is a declaration of a root symbol and is in the form: + .syntax <root_symbol>; + The <root_symbol> must be on of the symbols in declaration sequence. The syntax is correct if + the root symbol evaluates to true. A symbol evaluates to true if the definition associated with + the symbol evaluates to true. Definition evaluation depends on the operator used to connect + specifiers in the definition. If ".and" operator is used, definition evaluates to true if and + only if all the specifiers evaluate to true. If ".or" operator is used, definition evalutes to + true if any of the specifiers evaluates to true. If definition contains only one specifier, + it is evaluated as if it was connected with ".true" keyword by ".and" operator. + + If specifier is a ".true" keyword, it always evaluates to true. + + If specifier is a ".false" keyword, it always evaluates to false. Specifier evaluates to false + when it does not evaluate to true. + + Character range specifier is in the form: + '<first_character>' - '<second_character>' + If specifier is a character range, it evaluates to true if character in the stream is greater + or equal to <first_character> and less or equal to <second_character>. In that situation + the stream pointer is advanced to point to next character in the stream. All C-style escape + sequences are supported although trigraph sequences are not. The comparisions are performed + on 8-bit unsigned integers. + + Character specifier is in the form: + '<single_character>' + It evaluates to true if the following character range specifier evaluates to true: + '<single_character>' - '<single_character>' + + String specifier is in the form: + "<string>" + Let N be the number of characters in <string>. Let <string>[i] designate i-th character in + <string>. Then the string specifier evaluates to true if and only if for i in the range [0, N) + the following character specifier evaluates to true: + '<string>[i]' + If <string>[i] is a quotation mark, '<string>[i]' is replaced with '\<string>[i]'. + + Symbol specifier can be optionally preceded by a ".loop" keyword in the form: + .loop <symbol> (1) + where <symbol> is defined as follows: + <symbol> <definition>; (2) + Construction (1) is replaced by the following code: + <symbol$1> + and declaration (2) is replaced by the following: + <symbol$1> <symbol$2> .or .true; + <symbol$2> <symbol> .and <symbol$1>; + <symbol> <definition>; + + Synek supports also a register mechanizm. User can, in its SYN file, declare a number of + registers that can be accessed in the syn body. Each reg has its name and a default value. + The register is one byte wide. The C code can change the default value by calling + grammar_set_reg8() with grammar id, register name and a new value. As we know, each rule is + a sequence of specifiers joined with .and or .or operator. And now each specifier can be + prefixed with a condition expression in a form ".if (<reg_name> <operator> <hex_literal>)" + where <operator> can be == or !=. If the condition evaluates to false, the specifier + evaluates to .false. Otherwise it evalutes to the specifier. + + ESCAPE SEQUENCES + ---------------- + + Synek supports all escape sequences in character specifiers. The mapping table is listed below. + All occurences of the characters in the first column are replaced with the corresponding + character in the second column. + + Escape sequence Represents + ------------------------------------------------------------------------------------------------ + \a Bell (alert) + \b Backspace + \f Formfeed + \n New line + \r Carriage return + \t Horizontal tab + \v Vertical tab + \' Single quotation mark + \" Double quotation mark + \\ Backslash + \? Literal question mark + \ooo ASCII character in octal notation + \xhhh ASCII character in hexadecimal notation + ------------------------------------------------------------------------------------------------ + + RAISING ERRORS + -------------- + + Any specifier can be followed by a special construction that is executed when the specifier + evaluates to false. The construction is in the form: + .error <ERROR_TEXT> + <ERROR_TEXT> is an identifier declared earlier by error text declaration. The declaration is + in the form: + .errtext <ERROR_TEXT> "<error_desc>" + When specifier evaluates to false and this construction is present, parsing is stopped + immediately and <error_desc> is returned as a result of parsing. The error position is also + returned and it is meant as an offset from the beggining of the stream to the character that + was valid so far. Example: + + (**** syntax script ****) + + .syntax program; + .errtext MISSING_SEMICOLON "missing ';'" + program declaration .and .loop space .and ';' .error MISSING_SEMICOLON .and + .loop space .and '\0'; + declaration "declare" .and .loop space .and identifier; + space ' '; + + (**** sample code ****) + + declare foo , + + In the example above checking the sample code will result in error message "missing ';'" and + error position 12. The sample code is not correct. Note the presence of '\0' specifier to + assure that there is no code after semicolon - only spaces. + <error_desc> can optionally contain identifier surrounded by dollar signs $. In such a case, + the identifier and dollar signs are replaced by a string retrieved by invoking symbol with + the identifier name. The starting position is the error position. The lenght of the resulting + string is the position after invoking the symbol. + + PRODUCTION + ---------- + + Synek not only checks the syntax but it can also produce (emit) bytes associated with specifiers + that evaluate to true. That is, every specifier and optional error construction can be followed + by a number of emit constructions that are in the form: + .emit <parameter> + <paramater> can be a HEX number, identifier, a star * or a dollar $. HEX number is preceded by + 0x or 0X. If <parameter> is an identifier, it must be earlier declared by emit code declaration + in the form: + .emtcode <identifier> <hex_number> + + When given specifier evaluates to true, all emits associated with the specifier are output + in order they were declared. A star means that last-read character should be output instead + of constant value. Example: + + (**** syntax script ****) + + .syntax foobar; + .emtcode WORD_FOO 0x01 + .emtcode WORD_BAR 0x02 + foobar FOO .emit WORD_FOO .or BAR .emit WORD_BAR .or .true .emit 0x00; + FOO "foo" .and SPACE; + BAR "bar" .and SPACE; + SPACE ' ' .or '\0'; + + (**** sample text 1 ****) + + foo + + (**** sample text 2 ****) + + foobar + + For both samples the result will be one-element array. For first sample text it will be + value 1, for second - 0. Note that every text will be accepted because of presence of + .true as an alternative. + + Another example: + + (**** syntax script ****) + + .syntax declaration; + .emtcode VARIABLE 0x01 + declaration "declare" .and .loop space .and + identifier .emit VARIABLE .and (1) + .true .emit 0x00 .and (2) + .loop space .and ';'; + space ' ' .or '\t'; + identifier .loop id_char .emit *; (3) + id_char 'a'-'z' .or 'A'-'Z' .or '_'; + + (**** sample code ****) + + declare fubar; + + In specifier (1) symbol <identifier> is followed by .emit VARIABLE. If it evaluates to + true, VARIABLE constant and then production of the symbol is output. Specifier (2) is used + to terminate the string with null to signal when the string ends. Specifier (3) outputs + all characters that make declared identifier. The result of sample code will be the + following array: + { 1, 'f', 'u', 'b', 'a', 'r', 0 } + + If .emit is followed by dollar $, it means that current position should be output. Current + position is a 32-bit unsigned integer distance from the very beginning of the parsed string to + first character consumed by the specifier associated with the .emit instruction. Current + position is stored in the output buffer in Little-Endian convention (the lowest byte comes + first). +*/ + +static void mem_free (void **); + +/* + internal error messages +*/ +static const byte *OUT_OF_MEMORY = (byte *) "internal error 1001: out of physical memory"; +static const byte *UNRESOLVED_REFERENCE = (byte *) "internal error 1002: unresolved reference '$'"; +static const byte *INVALID_GRAMMAR_ID = (byte *) "internal error 1003: invalid grammar object"; +static const byte *INVALID_REGISTER_NAME = (byte *) "internal error 1004: invalid register name: '$'"; +/*static const byte *DUPLICATE_IDENTIFIER = (byte *) "internal error 1005: identifier '$' already defined";*/ +static const byte *UNREFERENCED_IDENTIFIER =(byte *) "internal error 1006: unreferenced identifier '$'"; + +static const byte *error_message = NULL; /* points to one of the error messages above */ +static byte *error_param = NULL; /* this is inserted into error_message in place of $ */ +static int error_position = -1; + +static byte *unknown = (byte *) "???"; + +static void clear_last_error (void) +{ + /* reset error message */ + error_message = NULL; + + /* free error parameter - if error_param is a "???" don't free it - it's static */ + if (error_param != unknown) + mem_free ((void **) (void *) &error_param); + else + error_param = NULL; + + /* reset error position */ + error_position = -1; +} + +static void set_last_error (const byte *msg, byte *param, int pos) +{ + /* error message can be set only once */ + if (error_message != NULL) + { + mem_free ((void **) (void *) ¶m); + return; + } + + error_message = msg; + + /* if param is NULL, set error_param to unknown ("???") */ + /* note: do not try to strdup the "???" - it may be that we are here because of */ + /* out of memory error so strdup can fail */ + if (param != NULL) + error_param = param; + else + error_param = unknown; + + error_position = pos; +} + +/* + memory management routines +*/ +static void *mem_alloc (size_t size) +{ + void *ptr = grammar_alloc_malloc (size); + if (ptr == NULL) + set_last_error (OUT_OF_MEMORY, NULL, -1); + return ptr; +} + +static void *mem_copy (void *dst, const void *src, size_t size) +{ + return grammar_memory_copy (dst, src, size); +} + +static void mem_free (void **ptr) +{ + grammar_alloc_free (*ptr); + *ptr = NULL; +} + +static void *mem_realloc (void *ptr, size_t old_size, size_t new_size) +{ + void *ptr2 = grammar_alloc_realloc (ptr, old_size, new_size); + if (ptr2 == NULL) + set_last_error (OUT_OF_MEMORY, NULL, -1); + return ptr2; +} + +static byte *str_copy_n (byte *dst, const byte *src, size_t max_len) +{ + return grammar_string_copy_n (dst, src, max_len); +} + +static byte *str_duplicate (const byte *str) +{ + byte *new_str = grammar_string_duplicate (str); + if (new_str == NULL) + set_last_error (OUT_OF_MEMORY, NULL, -1); + return new_str; +} + +static int str_equal (const byte *str1, const byte *str2) +{ + return grammar_string_compare (str1, str2) == 0; +} + +static int str_equal_n (const byte *str1, const byte *str2, unsigned int n) +{ + return grammar_string_compare_n (str1, str2, n) == 0; +} + +static unsigned int str_length (const byte *str) +{ + return grammar_string_length (str); +} + +/* + useful macros +*/ +#define GRAMMAR_IMPLEMENT_LIST_APPEND(_Ty)\ + static void _Ty##_append (_Ty **x, _Ty *nx) {\ + while (*x) x = &(**x).next;\ + *x = nx;\ + } + +/* + string to byte map typedef +*/ +typedef struct map_byte_ +{ + byte *key; + byte data; + struct map_byte_ *next; +} map_byte; + +static void map_byte_create (map_byte **ma) +{ + *ma = (map_byte *) mem_alloc (sizeof (map_byte)); + if (*ma) + { + (**ma).key = NULL; + (**ma).data = '\0'; + (**ma).next = NULL; + } +} + +static void map_byte_destroy (map_byte **ma) +{ + if (*ma) + { + map_byte_destroy (&(**ma).next); + mem_free ((void **) &(**ma).key); + mem_free ((void **) ma); + } +} + +GRAMMAR_IMPLEMENT_LIST_APPEND(map_byte) + +/* + searches the map for the specified key, + returns pointer to the element with the specified key if it exists + returns NULL otherwise +*/ +static map_byte *map_byte_locate (map_byte **ma, const byte *key) +{ + while (*ma) + { + if (str_equal ((**ma).key, key)) + return *ma; + + ma = &(**ma).next; + } + + set_last_error (UNRESOLVED_REFERENCE, str_duplicate (key), -1); + return NULL; +} + +/* + searches the map for specified key, + if the key is matched, *data is filled with data associated with the key, + returns 0 if the key is matched, + returns 1 otherwise +*/ +static int map_byte_find (map_byte **ma, const byte *key, byte *data) +{ + map_byte *found = map_byte_locate (ma, key); + if (found != NULL) + { + *data = found->data; + + return 0; + } + + return 1; +} + +/* + regbyte context typedef + + Each regbyte consists of its name and a default value. These are static and created at + grammar script compile-time, for example the following line: + .regbyte vertex_blend 0x00 + adds a new regbyte named "vertex_blend" to the static list and initializes it to 0. + When the script is executed, this regbyte can be accessed by name for read and write. When a + particular regbyte is written, a new regbyte_ctx entry is added to the top of the regbyte_ctx + stack. The new entry contains information abot which regbyte it references and its new value. + When a given regbyte is accessed for read, the stack is searched top-down to find an + entry that references the regbyte. The first matching entry is used to return the current + value it holds. If no entry is found, the default value is returned. +*/ +typedef struct regbyte_ctx_ +{ + map_byte *m_regbyte; + byte m_current_value; + struct regbyte_ctx_ *m_prev; +} regbyte_ctx; + +static void regbyte_ctx_create (regbyte_ctx **re) +{ + *re = (regbyte_ctx *) mem_alloc (sizeof (regbyte_ctx)); + if (*re) + { + (**re).m_regbyte = NULL; + (**re).m_prev = NULL; + } +} + +static void regbyte_ctx_destroy (regbyte_ctx **re) +{ + if (*re) + { + mem_free ((void **) re); + } +} + +static byte regbyte_ctx_extract (regbyte_ctx **re, map_byte *reg) +{ + /* first lookup in the register stack */ + while (*re != NULL) + { + if ((**re).m_regbyte == reg) + return (**re).m_current_value; + + re = &(**re).m_prev; + } + + /* if not found - return the default value */ + return reg->data; +} + +/* + emit type typedef +*/ +typedef enum emit_type_ +{ + et_byte, /* explicit number */ + et_stream, /* eaten character */ + et_position /* current position */ +} emit_type; + +/* + emit destination typedef +*/ +typedef enum emit_dest_ +{ + ed_output, /* write to the output buffer */ + ed_regbyte /* write a particular regbyte */ +} emit_dest; + +/* + emit typedef +*/ +typedef struct emit_ +{ + emit_dest m_emit_dest; + emit_type m_emit_type; /* ed_output */ + byte m_byte; /* et_byte */ + map_byte *m_regbyte; /* ed_regbyte */ + byte *m_regname; /* ed_regbyte - temporary */ + struct emit_ *m_next; +} emit; + +static void emit_create (emit **em) +{ + *em = (emit *) mem_alloc (sizeof (emit)); + if (*em) + { + (**em).m_emit_dest = ed_output; + (**em).m_emit_type = et_byte; + (**em).m_byte = '\0'; + (**em).m_regbyte = NULL; + (**em).m_regname = NULL; + (**em).m_next = NULL; + } +} + +static void emit_destroy (emit **em) +{ + if (*em) + { + emit_destroy (&(**em).m_next); + mem_free ((void **) &(**em).m_regname); + mem_free ((void **) em); + } +} + +static unsigned int emit_size (emit *_E) +{ + unsigned int n = 0; + + while (_E != NULL) + { + if (_E->m_emit_dest == ed_output) + { + if (_E->m_emit_type == et_position) + n += 4; /* position is a 32-bit unsigned integer */ + else + n++; + } + _E = _E->m_next; + } + + return n; +} + +static int emit_push (emit *_E, byte *_P, byte c, unsigned int _Pos, regbyte_ctx **_Ctx) +{ + while (_E != NULL) + { + if (_E->m_emit_dest == ed_output) + { + if (_E->m_emit_type == et_byte) + *_P++ = _E->m_byte; + else if (_E->m_emit_type == et_stream) + *_P++ = c; + else /* _Em->type == et_position */ + { + *_P++ = (byte) (_Pos); + *_P++ = (byte) (_Pos >> 8); + *_P++ = (byte) (_Pos >> 16); + *_P++ = (byte) (_Pos >> 24); + } + } + else + { + regbyte_ctx *new_rbc; + regbyte_ctx_create (&new_rbc); + if (new_rbc == NULL) + return 1; + + new_rbc->m_prev = *_Ctx; + new_rbc->m_regbyte = _E->m_regbyte; + *_Ctx = new_rbc; + + if (_E->m_emit_type == et_byte) + new_rbc->m_current_value = _E->m_byte; + else if (_E->m_emit_type == et_stream) + new_rbc->m_current_value = c; + } + + _E = _E->m_next; + } + + return 0; +} + +/* + error typedef +*/ +typedef struct error_ +{ + byte *m_text; + byte *m_token_name; + struct rule_ *m_token; +} error; + +static void error_create (error **er) +{ + *er = (error *) mem_alloc (sizeof (error)); + if (*er) + { + (**er).m_text = NULL; + (**er).m_token_name = NULL; + (**er).m_token = NULL; + } +} + +static void error_destroy (error **er) +{ + if (*er) + { + mem_free ((void **) &(**er).m_text); + mem_free ((void **) &(**er).m_token_name); + mem_free ((void **) er); + } +} + +struct dict_; +static byte *error_get_token (error *, struct dict_ *, const byte *, unsigned int); + +/* + condition operand type typedef +*/ +typedef enum cond_oper_type_ +{ + cot_byte, /* constant 8-bit unsigned integer */ + cot_regbyte /* pointer to byte register containing the current value */ +} cond_oper_type; + +/* + condition operand typedef +*/ +typedef struct cond_oper_ +{ + cond_oper_type m_type; + byte m_byte; /* cot_byte */ + map_byte *m_regbyte; /* cot_regbyte */ + byte *m_regname; /* cot_regbyte - temporary */ +} cond_oper; + +/* + condition type typedef +*/ +typedef enum cond_type_ +{ + ct_equal, + ct_not_equal +} cond_type; + +/* + condition typedef +*/ +typedef struct cond_ +{ + cond_type m_type; + cond_oper m_operands[2]; +} cond; + +static void cond_create (cond **co) +{ + *co = (cond *) mem_alloc (sizeof (cond)); + if (*co) + { + (**co).m_operands[0].m_regname = NULL; + (**co).m_operands[1].m_regname = NULL; + } +} + +static void cond_destroy (cond **co) +{ + if (*co) + { + mem_free ((void **) &(**co).m_operands[0].m_regname); + mem_free ((void **) &(**co).m_operands[1].m_regname); + mem_free ((void **) co); + } +} + +/* + specifier type typedef +*/ +typedef enum spec_type_ +{ + st_false, + st_true, + st_byte, + st_byte_range, + st_string, + st_identifier, + st_identifier_loop, + st_debug +} spec_type; + +/* + specifier typedef +*/ +typedef struct spec_ +{ + spec_type m_spec_type; + byte m_byte[2]; /* st_byte, st_byte_range */ + byte *m_string; /* st_string */ + struct rule_ *m_rule; /* st_identifier, st_identifier_loop */ + emit *m_emits; + error *m_errtext; + cond *m_cond; + struct spec_ *next; +} spec; + +static void spec_create (spec **sp) +{ + *sp = (spec *) mem_alloc (sizeof (spec)); + if (*sp) + { + (**sp).m_spec_type = st_false; + (**sp).m_byte[0] = '\0'; + (**sp).m_byte[1] = '\0'; + (**sp).m_string = NULL; + (**sp).m_rule = NULL; + (**sp).m_emits = NULL; + (**sp).m_errtext = NULL; + (**sp).m_cond = NULL; + (**sp).next = NULL; + } +} + +static void spec_destroy (spec **sp) +{ + if (*sp) + { + spec_destroy (&(**sp).next); + emit_destroy (&(**sp).m_emits); + error_destroy (&(**sp).m_errtext); + mem_free ((void **) &(**sp).m_string); + cond_destroy (&(**sp).m_cond); + mem_free ((void **) sp); + } +} + +GRAMMAR_IMPLEMENT_LIST_APPEND(spec) + +/* + operator typedef +*/ +typedef enum oper_ +{ + op_none, + op_and, + op_or +} oper; + +/* + rule typedef +*/ +typedef struct rule_ +{ + oper m_oper; + spec *m_specs; + struct rule_ *next; + int m_referenced; +} rule; + +static void rule_create (rule **ru) +{ + *ru = (rule *) mem_alloc (sizeof (rule)); + if (*ru) + { + (**ru).m_oper = op_none; + (**ru).m_specs = NULL; + (**ru).next = NULL; + (**ru).m_referenced = 0; + } +} + +static void rule_destroy (rule **ru) +{ + if (*ru) + { + rule_destroy (&(**ru).next); + spec_destroy (&(**ru).m_specs); + mem_free ((void **) ru); + } +} + +GRAMMAR_IMPLEMENT_LIST_APPEND(rule) + +/* + returns unique grammar id +*/ +static grammar next_valid_grammar_id (void) +{ + static grammar id = 0; + + return ++id; +} + +/* + dictionary typedef +*/ +typedef struct dict_ +{ + rule *m_rulez; + rule *m_syntax; + rule *m_string; + map_byte *m_regbytes; + grammar m_id; + struct dict_ *next; +} dict; + +static void dict_create (dict **di) +{ + *di = (dict *) mem_alloc (sizeof (dict)); + if (*di) + { + (**di).m_rulez = NULL; + (**di).m_syntax = NULL; + (**di).m_string = NULL; + (**di).m_regbytes = NULL; + (**di).m_id = next_valid_grammar_id (); + (**di).next = NULL; + } +} + +static void dict_destroy (dict **di) +{ + if (*di) + { + rule_destroy (&(**di).m_rulez); + map_byte_destroy (&(**di).m_regbytes); + mem_free ((void **) di); + } +} + +GRAMMAR_IMPLEMENT_LIST_APPEND(dict) + +static void dict_find (dict **di, grammar key, dict **data) +{ + while (*di) + { + if ((**di).m_id == key) + { + *data = *di; + return; + } + + di = &(**di).next; + } + + *data = NULL; +} + +static dict *g_dicts = NULL; + +/* + byte array typedef +*/ +typedef struct barray_ +{ + byte *data; + unsigned int len; +} barray; + +static void barray_create (barray **ba) +{ + *ba = (barray *) mem_alloc (sizeof (barray)); + if (*ba) + { + (**ba).data = NULL; + (**ba).len = 0; + } +} + +static void barray_destroy (barray **ba) +{ + if (*ba) + { + mem_free ((void **) &(**ba).data); + mem_free ((void **) ba); + } +} + +/* + reallocates byte array to requested size, + returns 0 on success, + returns 1 otherwise +*/ +static int barray_resize (barray **ba, unsigned int nlen) +{ + byte *new_pointer; + + if (nlen == 0) + { + mem_free ((void **) &(**ba).data); + (**ba).data = NULL; + (**ba).len = 0; + + return 0; + } + else + { + new_pointer = (byte *) mem_realloc ((**ba).data, (**ba).len * sizeof (byte), + nlen * sizeof (byte)); + if (new_pointer) + { + (**ba).data = new_pointer; + (**ba).len = nlen; + + return 0; + } + } + + return 1; +} + +/* + adds byte array pointed by *nb to the end of array pointed by *ba, + returns 0 on success, + returns 1 otherwise +*/ +static int barray_append (barray **ba, barray **nb) +{ + const unsigned int len = (**ba).len; + + if (barray_resize (ba, (**ba).len + (**nb).len)) + return 1; + + mem_copy ((**ba).data + len, (**nb).data, (**nb).len); + + return 0; +} + +/* + adds emit chain pointed by em to the end of array pointed by *ba, + returns 0 on success, + returns 1 otherwise +*/ +static int barray_push (barray **ba, emit *em, byte c, unsigned int pos, regbyte_ctx **rbc) +{ + unsigned int count = emit_size (em); + + if (barray_resize (ba, (**ba).len + count)) + return 1; + + return emit_push (em, (**ba).data + ((**ba).len - count), c, pos, rbc); +} + +/* + byte pool typedef +*/ +typedef struct bytepool_ +{ + byte *_F; + unsigned int _Siz; +} bytepool; + +static void bytepool_destroy (bytepool **by) +{ + if (*by != NULL) + { + mem_free ((void **) &(**by)._F); + mem_free ((void **) by); + } +} + +static void bytepool_create (bytepool **by, int len) +{ + *by = (bytepool *) (mem_alloc (sizeof (bytepool))); + if (*by != NULL) + { + (**by)._F = (byte *) (mem_alloc (sizeof (byte) * len)); + (**by)._Siz = len; + + if ((**by)._F == NULL) + bytepool_destroy (by); + } +} + +static int bytepool_reserve (bytepool *by, unsigned int n) +{ + byte *_P; + + if (n <= by->_Siz) + return 0; + + /* byte pool can only grow and at least by doubling its size */ + n = n >= by->_Siz * 2 ? n : by->_Siz * 2; + + /* reallocate the memory and adjust pointers to the new memory location */ + _P = (byte *) (mem_realloc (by->_F, sizeof (byte) * by->_Siz, sizeof (byte) * n)); + if (_P != NULL) + { + by->_F = _P; + by->_Siz = n; + return 0; + } + + return 1; +} + +/* + string to string map typedef +*/ +typedef struct map_str_ +{ + byte *key; + byte *data; + struct map_str_ *next; +} map_str; + +static void map_str_create (map_str **ma) +{ + *ma = (map_str *) mem_alloc (sizeof (map_str)); + if (*ma) + { + (**ma).key = NULL; + (**ma).data = NULL; + (**ma).next = NULL; + } +} + +static void map_str_destroy (map_str **ma) +{ + if (*ma) + { + map_str_destroy (&(**ma).next); + mem_free ((void **) &(**ma).key); + mem_free ((void **) &(**ma).data); + mem_free ((void **) ma); + } +} + +GRAMMAR_IMPLEMENT_LIST_APPEND(map_str) + +/* + searches the map for specified key, + if the key is matched, *data is filled with data associated with the key, + returns 0 if the key is matched, + returns 1 otherwise +*/ +static int map_str_find (map_str **ma, const byte *key, byte **data) +{ + while (*ma) + { + if (str_equal ((**ma).key, key)) + { + *data = str_duplicate ((**ma).data); + if (*data == NULL) + return 1; + + return 0; + } + + ma = &(**ma).next; + } + + set_last_error (UNRESOLVED_REFERENCE, str_duplicate (key), -1); + return 1; +} + +/* + string to rule map typedef +*/ +typedef struct map_rule_ +{ + byte *key; + rule *data; + struct map_rule_ *next; +} map_rule; + +static void map_rule_create (map_rule **ma) +{ + *ma = (map_rule *) mem_alloc (sizeof (map_rule)); + if (*ma) + { + (**ma).key = NULL; + (**ma).data = NULL; + (**ma).next = NULL; + } +} + +static void map_rule_destroy (map_rule **ma) +{ + if (*ma) + { + map_rule_destroy (&(**ma).next); + mem_free ((void **) &(**ma).key); + mem_free ((void **) ma); + } +} + +GRAMMAR_IMPLEMENT_LIST_APPEND(map_rule) + +/* + searches the map for specified key, + if the key is matched, *data is filled with data associated with the key, + returns 0 if the is matched, + returns 1 otherwise +*/ +static int map_rule_find (map_rule **ma, const byte *key, rule **data) +{ + while (*ma) + { + if (str_equal ((**ma).key, key)) + { + *data = (**ma).data; + + return 0; + } + + ma = &(**ma).next; + } + + set_last_error (UNRESOLVED_REFERENCE, str_duplicate (key), -1); + return 1; +} + +/* + returns 1 if given character is a white space, + returns 0 otherwise +*/ +static int is_space (byte c) +{ + return c == ' ' || c == '\t' || c == '\n' || c == '\r'; +} + +/* + advances text pointer by 1 if character pointed by *text is a space, + returns 1 if a space has been eaten, + returns 0 otherwise +*/ +static int eat_space (const byte **text) +{ + if (is_space (**text)) + { + (*text)++; + + return 1; + } + + return 0; +} + +/* + returns 1 if text points to C-style comment start string, + returns 0 otherwise +*/ +static int is_comment_start (const byte *text) +{ + return text[0] == '/' && text[1] == '*'; +} + +/* + advances text pointer to first character after C-style comment block - if any, + returns 1 if C-style comment block has been encountered and eaten, + returns 0 otherwise +*/ +static int eat_comment (const byte **text) +{ + if (is_comment_start (*text)) + { + /* *text points to comment block - skip two characters to enter comment body */ + *text += 2; + /* skip any character except consecutive '*' and '/' */ + while (!((*text)[0] == '*' && (*text)[1] == '/')) + (*text)++; + /* skip those two terminating characters */ + *text += 2; + + return 1; + } + + return 0; +} + +/* + advances text pointer to first character that is neither space nor C-style comment block +*/ +static void eat_spaces (const byte **text) +{ + while (eat_space (text) || eat_comment (text)) + ; +} + +/* + resizes string pointed by *ptr to successfully add character c to the end of the string, + returns 0 on success, + returns 1 otherwise +*/ +static int string_grow (byte **ptr, unsigned int *len, byte c) +{ + /* reallocate the string in 16-byte increments */ + if ((*len & 0x0F) == 0x0F || *ptr == NULL) + { + byte *tmp = (byte *) mem_realloc (*ptr, ((*len + 1) & ~0x0F) * sizeof (byte), + ((*len + 1 + 0x10) & ~0x0F) * sizeof (byte)); + if (tmp == NULL) + return 1; + + *ptr = tmp; + } + + if (c) + { + /* append given character */ + (*ptr)[*len] = c; + (*len)++; + } + (*ptr)[*len] = '\0'; + + return 0; +} + +/* + returns 1 if given character is a valid identifier character a-z, A-Z, 0-9 or _ + returns 0 otherwise +*/ +static int is_identifier (byte c) +{ + return (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || (c >= '0' && c <= '9') || c == '_'; +} + +/* + copies characters from *text to *id until non-identifier character is encountered, + assumes that *id points to NULL object - caller is responsible for later freeing the string, + text pointer is advanced to point past the copied identifier, + returns 0 if identifier was successfully copied, + returns 1 otherwise +*/ +static int get_identifier (const byte **text, byte **id) +{ + const byte *t = *text; + byte *p = NULL; + unsigned int len = 0; + + if (string_grow (&p, &len, '\0')) + return 1; + + /* loop while next character in buffer is valid for identifiers */ + while (is_identifier (*t)) + { + if (string_grow (&p, &len, *t++)) + { + mem_free ((void **) (void *) &p); + return 1; + } + } + + *text = t; + *id = p; + + return 0; +} + +/* + converts sequence of DEC digits pointed by *text until non-DEC digit is encountered, + advances text pointer past the converted sequence, + returns the converted value +*/ +static unsigned int dec_convert (const byte **text) +{ + unsigned int value = 0; + + while (**text >= '0' && **text <= '9') + { + value = value * 10 + **text - '0'; + (*text)++; + } + + return value; +} + +/* + returns 1 if given character is HEX digit 0-9, A-F or a-f, + returns 0 otherwise +*/ +static int is_hex (byte c) +{ + return (c >= '0' && c <= '9') || (c >= 'A' && c <= 'F') || (c >= 'a' && c <= 'f'); +} + +/* + returns value of passed character as if it was HEX digit +*/ +static unsigned int hex2dec (byte c) +{ + if (c >= '0' && c <= '9') + return c - '0'; + if (c >= 'A' && c <= 'F') + return c - 'A' + 10; + return c - 'a' + 10; +} + +/* + converts sequence of HEX digits pointed by *text until non-HEX digit is encountered, + advances text pointer past the converted sequence, + returns the converted value +*/ +static unsigned int hex_convert (const byte **text) +{ + unsigned int value = 0; + + while (is_hex (**text)) + { + value = value * 0x10 + hex2dec (**text); + (*text)++; + } + + return value; +} + +/* + returns 1 if given character is OCT digit 0-7, + returns 0 otherwise +*/ +static int is_oct (byte c) +{ + return c >= '0' && c <= '7'; +} + +/* + returns value of passed character as if it was OCT digit +*/ +static int oct2dec (byte c) +{ + return c - '0'; +} + +static byte get_escape_sequence (const byte **text) +{ + int value = 0; + + /* skip '\' character */ + (*text)++; + + switch (*(*text)++) + { + case '\'': + return '\''; + case '"': + return '\"'; + case '?': + return '\?'; + case '\\': + return '\\'; + case 'a': + return '\a'; + case 'b': + return '\b'; + case 'f': + return '\f'; + case 'n': + return '\n'; + case 'r': + return '\r'; + case 't': + return '\t'; + case 'v': + return '\v'; + case 'x': + return (byte) hex_convert (text); + } + + (*text)--; + if (is_oct (**text)) + { + value = oct2dec (*(*text)++); + if (is_oct (**text)) + { + value = value * 010 + oct2dec (*(*text)++); + if (is_oct (**text)) + value = value * 010 + oct2dec (*(*text)++); + } + } + + return (byte) value; +} + +/* + copies characters from *text to *str until " or ' character is encountered, + assumes that *str points to NULL object - caller is responsible for later freeing the string, + assumes that *text points to " or ' character that starts the string, + text pointer is advanced to point past the " or ' character, + returns 0 if string was successfully copied, + returns 1 otherwise +*/ +static int get_string (const byte **text, byte **str) +{ + const byte *t = *text; + byte *p = NULL; + unsigned int len = 0; + byte term_char; + + if (string_grow (&p, &len, '\0')) + return 1; + + /* read " or ' character that starts the string */ + term_char = *t++; + /* while next character is not the terminating character */ + while (*t && *t != term_char) + { + byte c; + + if (*t == '\\') + c = get_escape_sequence (&t); + else + c = *t++; + + if (string_grow (&p, &len, c)) + { + mem_free ((void **) (void *) &p); + return 1; + } + } + /* skip " or ' character that ends the string */ + t++; + + *text = t; + *str = p; + return 0; +} + +/* + gets emit code, the syntax is: + ".emtcode" " " <symbol> " " (("0x" | "0X") <hex_value>) | <dec_value> | <character> + assumes that *text already points to <symbol>, + returns 0 if emit code is successfully read, + returns 1 otherwise +*/ +static int get_emtcode (const byte **text, map_byte **ma) +{ + const byte *t = *text; + map_byte *m = NULL; + + map_byte_create (&m); + if (m == NULL) + return 1; + + if (get_identifier (&t, &m->key)) + { + map_byte_destroy (&m); + return 1; + } + eat_spaces (&t); + + if (*t == '\'') + { + byte *c; + + if (get_string (&t, &c)) + { + map_byte_destroy (&m); + return 1; + } + + m->data = (byte) c[0]; + mem_free ((void **) (void *) &c); + } + else if (t[0] == '0' && (t[1] == 'x' || t[1] == 'X')) + { + /* skip HEX "0x" or "0X" prefix */ + t += 2; + m->data = (byte) hex_convert (&t); + } + else + { + m->data = (byte) dec_convert (&t); + } + + eat_spaces (&t); + + *text = t; + *ma = m; + return 0; +} + +/* + gets regbyte declaration, the syntax is: + ".regbyte" " " <symbol> " " (("0x" | "0X") <hex_value>) | <dec_value> | <character> + assumes that *text already points to <symbol>, + returns 0 if regbyte is successfully read, + returns 1 otherwise +*/ +static int get_regbyte (const byte **text, map_byte **ma) +{ + /* pass it to the emtcode parser as it has the same syntax starting at <symbol> */ + return get_emtcode (text, ma); +} + +/* + returns 0 on success, + returns 1 otherwise +*/ +static int get_errtext (const byte **text, map_str **ma) +{ + const byte *t = *text; + map_str *m = NULL; + + map_str_create (&m); + if (m == NULL) + return 1; + + if (get_identifier (&t, &m->key)) + { + map_str_destroy (&m); + return 1; + } + eat_spaces (&t); + + if (get_string (&t, &m->data)) + { + map_str_destroy (&m); + return 1; + } + eat_spaces (&t); + + *text = t; + *ma = m; + return 0; +} + +/* + returns 0 on success, + returns 1 otherwise, +*/ +static int get_error (const byte **text, error **er, map_str *maps) +{ + const byte *t = *text; + byte *temp = NULL; + + if (*t != '.') + return 0; + + t++; + if (get_identifier (&t, &temp)) + return 1; + eat_spaces (&t); + + if (!str_equal ((byte *) "error", temp)) + { + mem_free ((void **) (void *) &temp); + return 0; + } + + mem_free ((void **) (void *) &temp); + + error_create (er); + if (*er == NULL) + return 1; + + if (*t == '\"') + { + if (get_string (&t, &(**er).m_text)) + { + error_destroy (er); + return 1; + } + eat_spaces (&t); + } + else + { + if (get_identifier (&t, &temp)) + { + error_destroy (er); + return 1; + } + eat_spaces (&t); + + if (map_str_find (&maps, temp, &(**er).m_text)) + { + mem_free ((void **) (void *) &temp); + error_destroy (er); + return 1; + } + + mem_free ((void **) (void *) &temp); + } + + /* try to extract "token" from "...$token$..." */ + { + byte *processed = NULL; + unsigned int len = 0, i = 0; + + if (string_grow (&processed, &len, '\0')) + { + error_destroy (er); + return 1; + } + + while (i < str_length ((**er).m_text)) + { + /* check if the dollar sign is repeated - if so skip it */ + if ((**er).m_text[i] == '$' && (**er).m_text[i + 1] == '$') + { + if (string_grow (&processed, &len, '$')) + { + mem_free ((void **) (void *) &processed); + error_destroy (er); + return 1; + } + + i += 2; + } + else if ((**er).m_text[i] != '$') + { + if (string_grow (&processed, &len, (**er).m_text[i])) + { + mem_free ((void **) (void *) &processed); + error_destroy (er); + return 1; + } + + i++; + } + else + { + if (string_grow (&processed, &len, '$')) + { + mem_free ((void **) (void *) &processed); + error_destroy (er); + return 1; + } + + { + /* length of token being extracted */ + unsigned int tlen = 0; + + if (string_grow (&(**er).m_token_name, &tlen, '\0')) + { + mem_free ((void **) (void *) &processed); + error_destroy (er); + return 1; + } + + /* skip the dollar sign */ + i++; + + while ((**er).m_text[i] != '$') + { + if (string_grow (&(**er).m_token_name, &tlen, (**er).m_text[i])) + { + mem_free ((void **) (void *) &processed); + error_destroy (er); + return 1; + } + + i++; + } + + /* skip the dollar sign */ + i++; + } + } + } + + mem_free ((void **) &(**er).m_text); + (**er).m_text = processed; + } + + *text = t; + return 0; +} + +/* + returns 0 on success, + returns 1 otherwise, +*/ +static int get_emits (const byte **text, emit **em, map_byte *mapb) +{ + const byte *t = *text; + byte *temp = NULL; + emit *e = NULL; + emit_dest dest; + + if (*t != '.') + return 0; + + t++; + if (get_identifier (&t, &temp)) + return 1; + eat_spaces (&t); + + /* .emit */ + if (str_equal ((byte *) "emit", temp)) + dest = ed_output; + /* .load */ + else if (str_equal ((byte *) "load", temp)) + dest = ed_regbyte; + else + { + mem_free ((void **) (void *) &temp); + return 0; + } + + mem_free ((void **) (void *) &temp); + + emit_create (&e); + if (e == NULL) + return 1; + + e->m_emit_dest = dest; + + if (dest == ed_regbyte) + { + if (get_identifier (&t, &e->m_regname)) + { + emit_destroy (&e); + return 1; + } + eat_spaces (&t); + } + + /* 0xNN */ + if (*t == '0' && (t[1] == 'x' || t[1] == 'X')) + { + t += 2; + e->m_byte = (byte) hex_convert (&t); + + e->m_emit_type = et_byte; + } + /* NNN */ + else if (*t >= '0' && *t <= '9') + { + e->m_byte = (byte) dec_convert (&t); + + e->m_emit_type = et_byte; + } + /* * */ + else if (*t == '*') + { + t++; + + e->m_emit_type = et_stream; + } + /* $ */ + else if (*t == '$') + { + t++; + + e->m_emit_type = et_position; + } + /* 'c' */ + else if (*t == '\'') + { + if (get_string (&t, &temp)) + { + emit_destroy (&e); + return 1; + } + e->m_byte = (byte) temp[0]; + + mem_free ((void **) (void *) &temp); + + e->m_emit_type = et_byte; + } + else + { + if (get_identifier (&t, &temp)) + { + emit_destroy (&e); + return 1; + } + + if (map_byte_find (&mapb, temp, &e->m_byte)) + { + mem_free ((void **) (void *) &temp); + emit_destroy (&e); + return 1; + } + + mem_free ((void **) (void *) &temp); + + e->m_emit_type = et_byte; + } + + eat_spaces (&t); + + if (get_emits (&t, &e->m_next, mapb)) + { + emit_destroy (&e); + return 1; + } + + *text = t; + *em = e; + return 0; +} + +/* + returns 0 on success, + returns 1 otherwise, +*/ +static int get_spec (const byte **text, spec **sp, map_str *maps, map_byte *mapb) +{ + const byte *t = *text; + spec *s = NULL; + + spec_create (&s); + if (s == NULL) + return 1; + + /* first - read optional .if statement */ + if (*t == '.') + { + const byte *u = t; + byte *keyword = NULL; + + /* skip the dot */ + u++; + + if (get_identifier (&u, &keyword)) + { + spec_destroy (&s); + return 1; + } + + /* .if */ + if (str_equal ((byte *) "if", keyword)) + { + cond_create (&s->m_cond); + if (s->m_cond == NULL) + { + spec_destroy (&s); + return 1; + } + + /* skip the left paren */ + eat_spaces (&u); + u++; + + /* get the left operand */ + eat_spaces (&u); + if (get_identifier (&u, &s->m_cond->m_operands[0].m_regname)) + { + spec_destroy (&s); + return 1; + } + s->m_cond->m_operands[0].m_type = cot_regbyte; + + /* get the operator (!= or ==) */ + eat_spaces (&u); + if (*u == '!') + s->m_cond->m_type = ct_not_equal; + else + s->m_cond->m_type = ct_equal; + u += 2; + eat_spaces (&u); + + if (u[0] == '0' && (u[1] == 'x' || u[1] == 'X')) + { + /* skip the 0x prefix */ + u += 2; + + /* get the right operand */ + s->m_cond->m_operands[1].m_byte = hex_convert (&u); + s->m_cond->m_operands[1].m_type = cot_byte; + } + else /*if (*u >= '0' && *u <= '9')*/ + { + /* get the right operand */ + s->m_cond->m_operands[1].m_byte = dec_convert (&u); + s->m_cond->m_operands[1].m_type = cot_byte; + } + + /* skip the right paren */ + eat_spaces (&u); + u++; + + eat_spaces (&u); + + t = u; + } + + mem_free ((void **) (void *) &keyword); + } + + if (*t == '\'') + { + byte *temp = NULL; + + if (get_string (&t, &temp)) + { + spec_destroy (&s); + return 1; + } + eat_spaces (&t); + + if (*t == '-') + { + byte *temp2 = NULL; + + /* skip the '-' character */ + t++; + eat_spaces (&t); + + if (get_string (&t, &temp2)) + { + mem_free ((void **) (void *) &temp); + spec_destroy (&s); + return 1; + } + eat_spaces (&t); + + s->m_spec_type = st_byte_range; + s->m_byte[0] = *temp; + s->m_byte[1] = *temp2; + + mem_free ((void **) (void *) &temp2); + } + else + { + s->m_spec_type = st_byte; + *s->m_byte = *temp; + } + + mem_free ((void **) (void *) &temp); + } + else if (*t == '"') + { + if (get_string (&t, &s->m_string)) + { + spec_destroy (&s); + return 1; + } + eat_spaces (&t); + + s->m_spec_type = st_string; + } + else if (*t == '.') + { + byte *keyword = NULL; + + /* skip the dot */ + t++; + + if (get_identifier (&t, &keyword)) + { + spec_destroy (&s); + return 1; + } + eat_spaces (&t); + + /* .true */ + if (str_equal ((byte *) "true", keyword)) + { + s->m_spec_type = st_true; + } + /* .false */ + else if (str_equal ((byte *) "false", keyword)) + { + s->m_spec_type = st_false; + } + /* .debug */ + else if (str_equal ((byte *) "debug", keyword)) + { + s->m_spec_type = st_debug; + } + /* .loop */ + else if (str_equal ((byte *) "loop", keyword)) + { + if (get_identifier (&t, &s->m_string)) + { + mem_free ((void **) (void *) &keyword); + spec_destroy (&s); + return 1; + } + eat_spaces (&t); + + s->m_spec_type = st_identifier_loop; + } + mem_free ((void **) (void *) &keyword); + } + else + { + if (get_identifier (&t, &s->m_string)) + { + spec_destroy (&s); + return 1; + } + eat_spaces (&t); + + s->m_spec_type = st_identifier; + } + + if (get_error (&t, &s->m_errtext, maps)) + { + spec_destroy (&s); + return 1; + } + + if (get_emits (&t, &s->m_emits, mapb)) + { + spec_destroy (&s); + return 1; + } + + *text = t; + *sp = s; + return 0; +} + +/* + returns 0 on success, + returns 1 otherwise, +*/ +static int get_rule (const byte **text, rule **ru, map_str *maps, map_byte *mapb) +{ + const byte *t = *text; + rule *r = NULL; + + rule_create (&r); + if (r == NULL) + return 1; + + if (get_spec (&t, &r->m_specs, maps, mapb)) + { + rule_destroy (&r); + return 1; + } + + while (*t != ';') + { + byte *op = NULL; + spec *sp = NULL; + + /* skip the dot that precedes "and" or "or" */ + t++; + + /* read "and" or "or" keyword */ + if (get_identifier (&t, &op)) + { + rule_destroy (&r); + return 1; + } + eat_spaces (&t); + + if (r->m_oper == op_none) + { + /* .and */ + if (str_equal ((byte *) "and", op)) + r->m_oper = op_and; + /* .or */ + else + r->m_oper = op_or; + } + + mem_free ((void **) (void *) &op); + + if (get_spec (&t, &sp, maps, mapb)) + { + rule_destroy (&r); + return 1; + } + + spec_append (&r->m_specs, sp); + } + + /* skip the semicolon */ + t++; + eat_spaces (&t); + + *text = t; + *ru = r; + return 0; +} + +/* + returns 0 on success, + returns 1 otherwise, +*/ +static int update_dependency (map_rule *mapr, byte *symbol, rule **ru) +{ + if (map_rule_find (&mapr, symbol, ru)) + return 1; + + (**ru).m_referenced = 1; + + return 0; +} + +/* + returns 0 on success, + returns 1 otherwise, +*/ +static int update_dependencies (dict *di, map_rule *mapr, byte **syntax_symbol, + byte **string_symbol, map_byte *regbytes) +{ + rule *rulez = di->m_rulez; + + /* update dependecies for the root and lexer symbols */ + if (update_dependency (mapr, *syntax_symbol, &di->m_syntax) || + (*string_symbol != NULL && update_dependency (mapr, *string_symbol, &di->m_string))) + return 1; + + mem_free ((void **) syntax_symbol); + mem_free ((void **) string_symbol); + + /* update dependecies for the rest of the rules */ + while (rulez) + { + spec *sp = rulez->m_specs; + + /* iterate through all the specifiers */ + while (sp) + { + /* update dependency for identifier */ + if (sp->m_spec_type == st_identifier || sp->m_spec_type == st_identifier_loop) + { + if (update_dependency (mapr, sp->m_string, &sp->m_rule)) + return 1; + + mem_free ((void **) &sp->m_string); + } + + /* some errtexts reference to a rule */ + if (sp->m_errtext && sp->m_errtext->m_token_name) + { + if (update_dependency (mapr, sp->m_errtext->m_token_name, &sp->m_errtext->m_token)) + return 1; + + mem_free ((void **) &sp->m_errtext->m_token_name); + } + + /* update dependency for condition */ + if (sp->m_cond) + { + int i; + for (i = 0; i < 2; i++) + if (sp->m_cond->m_operands[i].m_type == cot_regbyte) + { + sp->m_cond->m_operands[i].m_regbyte = map_byte_locate (®bytes, + sp->m_cond->m_operands[i].m_regname); + + if (sp->m_cond->m_operands[i].m_regbyte == NULL) + return 1; + + mem_free ((void **) &sp->m_cond->m_operands[i].m_regname); + } + } + + /* update dependency for all .load instructions */ + if (sp->m_emits) + { + emit *em = sp->m_emits; + while (em != NULL) + { + if (em->m_emit_dest == ed_regbyte) + { + em->m_regbyte = map_byte_locate (®bytes, em->m_regname); + + if (em->m_regbyte == NULL) + return 1; + + mem_free ((void **) &em->m_regname); + } + + em = em->m_next; + } + } + + sp = sp->next; + } + + rulez = rulez->next; + } + + /* check for unreferenced symbols */ + rulez = di->m_rulez; + while (rulez != NULL) + { + if (!rulez->m_referenced) + { + map_rule *ma = mapr; + while (ma) + { + if (ma->data == rulez) + { + set_last_error (UNREFERENCED_IDENTIFIER, str_duplicate (ma->key), -1); + return 1; + } + ma = ma->next; + } + } + rulez = rulez->next; + } + + return 0; +} + +static int satisfies_condition (cond *co, regbyte_ctx *ctx) +{ + byte values[2]; + int i; + + if (co == NULL) + return 1; + + for (i = 0; i < 2; i++) + switch (co->m_operands[i].m_type) + { + case cot_byte: + values[i] = co->m_operands[i].m_byte; + break; + case cot_regbyte: + values[i] = regbyte_ctx_extract (&ctx, co->m_operands[i].m_regbyte); + break; + } + + switch (co->m_type) + { + case ct_equal: + return values[0] == values[1]; + case ct_not_equal: + return values[0] != values[1]; + } + + return 0; +} + +static void free_regbyte_ctx_stack (regbyte_ctx *top, regbyte_ctx *limit) +{ + while (top != limit) + { + regbyte_ctx *rbc = top->m_prev; + regbyte_ctx_destroy (&top); + top = rbc; + } +} + +typedef enum match_result_ +{ + mr_not_matched, /* the examined string does not match */ + mr_matched, /* the examined string matches */ + mr_error_raised, /* mr_not_matched + error has been raised */ + mr_dont_emit, /* used by identifier loops only */ + mr_internal_error /* an internal error has occured such as out of memory */ +} match_result; + +/* + This function does the main job. It parses the text and generates output data. +*/ +static match_result match (dict *di, const byte *text, unsigned int *index, rule *ru, barray **ba, + int filtering_string, regbyte_ctx **rbc) +{ + unsigned int ind = *index; + match_result status = mr_not_matched; + spec *sp = ru->m_specs; + regbyte_ctx *ctx = *rbc; + + /* for every specifier in the rule */ + while (sp) + { + unsigned int i, len, save_ind = ind; + barray *array = NULL; + + if (satisfies_condition (sp->m_cond, ctx)) + { + switch (sp->m_spec_type) + { + case st_identifier: + barray_create (&array); + if (array == NULL) + { + free_regbyte_ctx_stack (ctx, *rbc); + return mr_internal_error; + } + + status = match (di, text, &ind, sp->m_rule, &array, filtering_string, &ctx); + + if (status == mr_internal_error) + { + free_regbyte_ctx_stack (ctx, *rbc); + barray_destroy (&array); + return mr_internal_error; + } + break; + case st_string: + len = str_length (sp->m_string); + + /* prefilter the stream */ + if (!filtering_string && di->m_string) + { + barray *ba; + unsigned int filter_index = 0; + match_result result; + regbyte_ctx *null_ctx = NULL; + + barray_create (&ba); + if (ba == NULL) + { + free_regbyte_ctx_stack (ctx, *rbc); + return mr_internal_error; + } + + result = match (di, text + ind, &filter_index, di->m_string, &ba, 1, &null_ctx); + + if (result == mr_internal_error) + { + free_regbyte_ctx_stack (ctx, *rbc); + barray_destroy (&ba); + return mr_internal_error; + } + + if (result != mr_matched) + { + barray_destroy (&ba); + status = mr_not_matched; + break; + } + + barray_destroy (&ba); + + if (filter_index != len || !str_equal_n (sp->m_string, text + ind, len)) + { + status = mr_not_matched; + break; + } + + status = mr_matched; + ind += len; + } + else + { + status = mr_matched; + for (i = 0; status == mr_matched && i < len; i++) + if (text[ind + i] != sp->m_string[i]) + status = mr_not_matched; + + if (status == mr_matched) + ind += len; + } + break; + case st_byte: + status = text[ind] == *sp->m_byte ? mr_matched : mr_not_matched; + if (status == mr_matched) + ind++; + break; + case st_byte_range: + status = (text[ind] >= sp->m_byte[0] && text[ind] <= sp->m_byte[1]) ? + mr_matched : mr_not_matched; + if (status == mr_matched) + ind++; + break; + case st_true: + status = mr_matched; + break; + case st_false: + status = mr_not_matched; + break; + case st_debug: + status = ru->m_oper == op_and ? mr_matched : mr_not_matched; + break; + case st_identifier_loop: + barray_create (&array); + if (array == NULL) + { + free_regbyte_ctx_stack (ctx, *rbc); + return mr_internal_error; + } + + status = mr_dont_emit; + for (;;) + { + match_result result; + + save_ind = ind; + result = match (di, text, &ind, sp->m_rule, &array, filtering_string, &ctx); + + if (result == mr_error_raised) + { + status = result; + break; + } + else if (result == mr_matched) + { + if (barray_push (ba, sp->m_emits, text[ind - 1], save_ind, &ctx) || + barray_append (ba, &array)) + { + free_regbyte_ctx_stack (ctx, *rbc); + barray_destroy (&array); + return mr_internal_error; + } + barray_destroy (&array); + barray_create (&array); + if (array == NULL) + { + free_regbyte_ctx_stack (ctx, *rbc); + return mr_internal_error; + } + } + else if (result == mr_internal_error) + { + free_regbyte_ctx_stack (ctx, *rbc); + barray_destroy (&array); + return mr_internal_error; + } + else + break; + } + break; + } + } + else + { + status = mr_not_matched; + } + + if (status == mr_error_raised) + { + free_regbyte_ctx_stack (ctx, *rbc); + barray_destroy (&array); + + return mr_error_raised; + } + + if (ru->m_oper == op_and && status != mr_matched && status != mr_dont_emit) + { + free_regbyte_ctx_stack (ctx, *rbc); + barray_destroy (&array); + + if (sp->m_errtext) + { + set_last_error (sp->m_errtext->m_text, error_get_token (sp->m_errtext, di, text, + ind), ind); + + return mr_error_raised; + } + + return mr_not_matched; + } + + if (status == mr_matched) + { + if (sp->m_emits) + if (barray_push (ba, sp->m_emits, text[ind - 1], save_ind, &ctx)) + { + free_regbyte_ctx_stack (ctx, *rbc); + barray_destroy (&array); + return mr_internal_error; + } + + if (array) + if (barray_append (ba, &array)) + { + free_regbyte_ctx_stack (ctx, *rbc); + barray_destroy (&array); + return mr_internal_error; + } + } + + barray_destroy (&array); + + /* if the rule operator is a logical or, we pick up the first matching specifier */ + if (ru->m_oper == op_or && (status == mr_matched || status == mr_dont_emit)) + { + *index = ind; + *rbc = ctx; + return mr_matched; + } + + sp = sp->next; + } + + /* everything went fine - all specifiers match up */ + if (ru->m_oper == op_and && (status == mr_matched || status == mr_dont_emit)) + { + *index = ind; + *rbc = ctx; + return mr_matched; + } + + free_regbyte_ctx_stack (ctx, *rbc); + return mr_not_matched; +} + +static match_result fast_match (dict *di, const byte *text, unsigned int *index, rule *ru, int *_PP, bytepool *_BP, + int filtering_string, regbyte_ctx **rbc) +{ + unsigned int ind = *index; + int _P = filtering_string ? 0 : *_PP; + int _P2; + match_result status = mr_not_matched; + spec *sp = ru->m_specs; + regbyte_ctx *ctx = *rbc; + + /* for every specifier in the rule */ + while (sp) + { + unsigned int i, len, save_ind = ind; + + _P2 = _P + (sp->m_emits ? emit_size (sp->m_emits) : 0); + if (bytepool_reserve (_BP, _P2)) + { + free_regbyte_ctx_stack (ctx, *rbc); + return mr_internal_error; + } + + if (satisfies_condition (sp->m_cond, ctx)) + { + switch (sp->m_spec_type) + { + case st_identifier: + status = fast_match (di, text, &ind, sp->m_rule, &_P2, _BP, filtering_string, &ctx); + + if (status == mr_internal_error) + { + free_regbyte_ctx_stack (ctx, *rbc); + return mr_internal_error; + } + break; + case st_string: + len = str_length (sp->m_string); + + /* prefilter the stream */ + if (!filtering_string && di->m_string) + { + unsigned int filter_index = 0; + match_result result; + regbyte_ctx *null_ctx = NULL; + + result = fast_match (di, text + ind, &filter_index, di->m_string, NULL, _BP, 1, &null_ctx); + + if (result == mr_internal_error) + { + free_regbyte_ctx_stack (ctx, *rbc); + return mr_internal_error; + } + + if (result != mr_matched) + { + status = mr_not_matched; + break; + } + + if (filter_index != len || !str_equal_n (sp->m_string, text + ind, len)) + { + status = mr_not_matched; + break; + } + + status = mr_matched; + ind += len; + } + else + { + status = mr_matched; + for (i = 0; status == mr_matched && i < len; i++) + if (text[ind + i] != sp->m_string[i]) + status = mr_not_matched; + + if (status == mr_matched) + ind += len; + } + break; + case st_byte: + status = text[ind] == *sp->m_byte ? mr_matched : mr_not_matched; + if (status == mr_matched) + ind++; + break; + case st_byte_range: + status = (text[ind] >= sp->m_byte[0] && text[ind] <= sp->m_byte[1]) ? + mr_matched : mr_not_matched; + if (status == mr_matched) + ind++; + break; + case st_true: + status = mr_matched; + break; + case st_false: + status = mr_not_matched; + break; + case st_debug: + status = ru->m_oper == op_and ? mr_matched : mr_not_matched; + break; + case st_identifier_loop: + status = mr_dont_emit; + for (;;) + { + match_result result; + + save_ind = ind; + result = fast_match (di, text, &ind, sp->m_rule, &_P2, _BP, filtering_string, &ctx); + + if (result == mr_error_raised) + { + status = result; + break; + } + else if (result == mr_matched) + { + if (!filtering_string) + { + if (sp->m_emits != NULL) + { + if (emit_push (sp->m_emits, _BP->_F + _P, text[ind - 1], save_ind, &ctx)) + { + free_regbyte_ctx_stack (ctx, *rbc); + return mr_internal_error; + } + } + + _P = _P2; + _P2 += sp->m_emits ? emit_size (sp->m_emits) : 0; + if (bytepool_reserve (_BP, _P2)) + { + free_regbyte_ctx_stack (ctx, *rbc); + return mr_internal_error; + } + } + } + else if (result == mr_internal_error) + { + free_regbyte_ctx_stack (ctx, *rbc); + return mr_internal_error; + } + else + break; + } + break; + } + } + else + { + status = mr_not_matched; + } + + if (status == mr_error_raised) + { + free_regbyte_ctx_stack (ctx, *rbc); + + return mr_error_raised; + } + + if (ru->m_oper == op_and && status != mr_matched && status != mr_dont_emit) + { + free_regbyte_ctx_stack (ctx, *rbc); + + if (sp->m_errtext) + { + set_last_error (sp->m_errtext->m_text, error_get_token (sp->m_errtext, di, text, + ind), ind); + + return mr_error_raised; + } + + return mr_not_matched; + } + + if (status == mr_matched) + { + if (sp->m_emits != NULL) + if (emit_push (sp->m_emits, _BP->_F + _P, text[ind - 1], save_ind, &ctx)) + { + free_regbyte_ctx_stack (ctx, *rbc); + return mr_internal_error; + } + + _P = _P2; + } + + /* if the rule operator is a logical or, we pick up the first matching specifier */ + if (ru->m_oper == op_or && (status == mr_matched || status == mr_dont_emit)) + { + *index = ind; + *rbc = ctx; + if (!filtering_string) + *_PP = _P; + return mr_matched; + } + + sp = sp->next; + } + + /* everything went fine - all specifiers match up */ + if (ru->m_oper == op_and && (status == mr_matched || status == mr_dont_emit)) + { + *index = ind; + *rbc = ctx; + if (!filtering_string) + *_PP = _P; + return mr_matched; + } + + free_regbyte_ctx_stack (ctx, *rbc); + return mr_not_matched; +} + +static byte *error_get_token (error *er, dict *di, const byte *text, unsigned int ind) +{ + byte *str = NULL; + + if (er->m_token) + { + barray *ba; + unsigned int filter_index = 0; + regbyte_ctx *ctx = NULL; + + barray_create (&ba); + if (ba != NULL) + { + if (match (di, text + ind, &filter_index, er->m_token, &ba, 0, &ctx) == mr_matched && + filter_index) + { + str = (byte *) mem_alloc (filter_index + 1); + if (str != NULL) + { + str_copy_n (str, text + ind, filter_index); + str[filter_index] = '\0'; + } + } + barray_destroy (&ba); + } + } + + return str; +} + +typedef struct grammar_load_state_ +{ + dict *di; + byte *syntax_symbol; + byte *string_symbol; + map_str *maps; + map_byte *mapb; + map_rule *mapr; +} grammar_load_state; + +static void grammar_load_state_create (grammar_load_state **gr) +{ + *gr = (grammar_load_state *) mem_alloc (sizeof (grammar_load_state)); + if (*gr) + { + (**gr).di = NULL; + (**gr).syntax_symbol = NULL; + (**gr).string_symbol = NULL; + (**gr).maps = NULL; + (**gr).mapb = NULL; + (**gr).mapr = NULL; + } +} + +static void grammar_load_state_destroy (grammar_load_state **gr) +{ + if (*gr) + { + dict_destroy (&(**gr).di); + mem_free ((void **) &(**gr).syntax_symbol); + mem_free ((void **) &(**gr).string_symbol); + map_str_destroy (&(**gr).maps); + map_byte_destroy (&(**gr).mapb); + map_rule_destroy (&(**gr).mapr); + mem_free ((void **) gr); + } +} + +/* + the API +*/ + +grammar grammar_load_from_text (const byte *text) +{ + grammar_load_state *g = NULL; + grammar id = 0; + + clear_last_error (); + + grammar_load_state_create (&g); + if (g == NULL) + return 0; + + dict_create (&g->di); + if (g->di == NULL) + { + grammar_load_state_destroy (&g); + return 0; + } + + eat_spaces (&text); + + /* skip ".syntax" keyword */ + text += 7; + eat_spaces (&text); + + /* retrieve root symbol */ + if (get_identifier (&text, &g->syntax_symbol)) + { + grammar_load_state_destroy (&g); + return 0; + } + eat_spaces (&text); + + /* skip semicolon */ + text++; + eat_spaces (&text); + + while (*text) + { + byte *symbol = NULL; + int is_dot = *text == '.'; + + if (is_dot) + text++; + + if (get_identifier (&text, &symbol)) + { + grammar_load_state_destroy (&g); + return 0; + } + eat_spaces (&text); + + /* .emtcode */ + if (is_dot && str_equal (symbol, (byte *) "emtcode")) + { + map_byte *ma = NULL; + + mem_free ((void **) (void *) &symbol); + + if (get_emtcode (&text, &ma)) + { + grammar_load_state_destroy (&g); + return 0; + } + + map_byte_append (&g->mapb, ma); + } + /* .regbyte */ + else if (is_dot && str_equal (symbol, (byte *) "regbyte")) + { + map_byte *ma = NULL; + + mem_free ((void **) (void *) &symbol); + + if (get_regbyte (&text, &ma)) + { + grammar_load_state_destroy (&g); + return 0; + } + + map_byte_append (&g->di->m_regbytes, ma); + } + /* .errtext */ + else if (is_dot && str_equal (symbol, (byte *) "errtext")) + { + map_str *ma = NULL; + + mem_free ((void **) (void *) &symbol); + + if (get_errtext (&text, &ma)) + { + grammar_load_state_destroy (&g); + return 0; + } + + map_str_append (&g->maps, ma); + } + /* .string */ + else if (is_dot && str_equal (symbol, (byte *) "string")) + { + mem_free ((void **) (void *) &symbol); + + if (g->di->m_string != NULL) + { + grammar_load_state_destroy (&g); + return 0; + } + + if (get_identifier (&text, &g->string_symbol)) + { + grammar_load_state_destroy (&g); + return 0; + } + + /* skip semicolon */ + eat_spaces (&text); + text++; + eat_spaces (&text); + } + else + { + rule *ru = NULL; + map_rule *ma = NULL; + + if (get_rule (&text, &ru, g->maps, g->mapb)) + { + grammar_load_state_destroy (&g); + return 0; + } + + rule_append (&g->di->m_rulez, ru); + + /* if a rule consist of only one specifier, give it an ".and" operator */ + if (ru->m_oper == op_none) + ru->m_oper = op_and; + + map_rule_create (&ma); + if (ma == NULL) + { + grammar_load_state_destroy (&g); + return 0; + } + + ma->key = symbol; + ma->data = ru; + map_rule_append (&g->mapr, ma); + } + } + + if (update_dependencies (g->di, g->mapr, &g->syntax_symbol, &g->string_symbol, + g->di->m_regbytes)) + { + grammar_load_state_destroy (&g); + return 0; + } + + dict_append (&g_dicts, g->di); + id = g->di->m_id; + g->di = NULL; + + grammar_load_state_destroy (&g); + + return id; +} + +int grammar_set_reg8 (grammar id, const byte *name, byte value) +{ + dict *di = NULL; + map_byte *reg = NULL; + + clear_last_error (); + + dict_find (&g_dicts, id, &di); + if (di == NULL) + { + set_last_error (INVALID_GRAMMAR_ID, NULL, -1); + return 0; + } + + reg = map_byte_locate (&di->m_regbytes, name); + if (reg == NULL) + { + set_last_error (INVALID_REGISTER_NAME, str_duplicate (name), -1); + return 0; + } + + reg->data = value; + return 1; +} + +/* + internal checking function used by both grammar_check and grammar_fast_check functions +*/ +static int _grammar_check (grammar id, const byte *text, byte **prod, unsigned int *size, + unsigned int estimate_prod_size, int use_fast_path) +{ + dict *di = NULL; + unsigned int index = 0; + + clear_last_error (); + + dict_find (&g_dicts, id, &di); + if (di == NULL) + { + set_last_error (INVALID_GRAMMAR_ID, NULL, -1); + return 0; + } + + *prod = NULL; + *size = 0; + + if (use_fast_path) + { + regbyte_ctx *rbc = NULL; + bytepool *bp = NULL; + int _P = 0; + + bytepool_create (&bp, estimate_prod_size); + if (bp == NULL) + return 0; + + if (fast_match (di, text, &index, di->m_syntax, &_P, bp, 0, &rbc) != mr_matched) + { + bytepool_destroy (&bp); + free_regbyte_ctx_stack (rbc, NULL); + return 0; + } + + free_regbyte_ctx_stack (rbc, NULL); + + *prod = bp->_F; + *size = _P; + bp->_F = NULL; + bytepool_destroy (&bp); + } + else + { + regbyte_ctx *rbc = NULL; + barray *ba = NULL; + + barray_create (&ba); + if (ba == NULL) + return 0; + + if (match (di, text, &index, di->m_syntax, &ba, 0, &rbc) != mr_matched) + { + barray_destroy (&ba); + free_regbyte_ctx_stack (rbc, NULL); + return 0; + } + + free_regbyte_ctx_stack (rbc, NULL); + + *prod = (byte *) mem_alloc (ba->len * sizeof (byte)); + if (*prod == NULL) + { + barray_destroy (&ba); + return 0; + } + + mem_copy (*prod, ba->data, ba->len * sizeof (byte)); + *size = ba->len; + barray_destroy (&ba); + } + + return 1; +} + +int grammar_check (grammar id, const byte *text, byte **prod, unsigned int *size) +{ + return _grammar_check (id, text, prod, size, 0, 0); +} + +int grammar_fast_check (grammar id, const byte *text, byte **prod, unsigned int *size, + unsigned int estimate_prod_size) +{ + return _grammar_check (id, text, prod, size, estimate_prod_size, 1); +} + +int grammar_destroy (grammar id) +{ + dict **di = &g_dicts; + + clear_last_error (); + + while (*di != NULL) + { + if ((**di).m_id == id) + { + dict *tmp = *di; + *di = (**di).next; + dict_destroy (&tmp); + return 1; + } + + di = &(**di).next; + } + + set_last_error (INVALID_GRAMMAR_ID, NULL, -1); + return 0; +} + +static void append_character (const char x, byte *text, int *dots_made, int *len, int size) +{ + if (*dots_made == 0) + { + if (*len < size - 1) + { + text[(*len)++] = x; + text[*len] = '\0'; + } + else + { + int i; + for (i = 0; i < 3; i++) + if (--(*len) >= 0) + text[*len] = '.'; + *dots_made = 1; + } + } +} + +void grammar_get_last_error (byte *text, unsigned int size, int *pos) +{ + int len = 0, dots_made = 0; + const byte *p = error_message; + + *text = '\0'; + + if (p) + { + while (*p) + { + if (*p == '$') + { + const byte *r = error_param; + + while (*r) + { + append_character (*r++, text, &dots_made, &len, (int) size); + } + + p++; + } + else + { + append_character (*p++, text, &dots_made, &len, size); + } + } + } + + *pos = error_position; +} diff --git a/nx-X11/extras/Mesa/src/mesa/shader/grammar/grammar.h b/nx-X11/extras/Mesa/src/mesa/shader/grammar/grammar.h new file mode 100644 index 000000000..591e38aef --- /dev/null +++ b/nx-X11/extras/Mesa/src/mesa/shader/grammar/grammar.h @@ -0,0 +1,103 @@ +/* + * Mesa 3-D graphics library + * Version: 6.2 + * + * Copyright (C) 1999-2004 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 GRAMMAR_H +#define GRAMMAR_H + + +#ifndef GRAMMAR_PORT_INCLUDE +#error Do not include this file directly, include your grammar_XXX.h instead +#endif + + +#ifdef __cplusplus +extern "C" { +#endif + +void grammar_alloc_free (void *); +void *grammar_alloc_malloc (size_t); +void *grammar_alloc_realloc (void *, size_t, size_t); +void *grammar_memory_copy (void *, const void *, size_t); +int grammar_string_compare (const byte *, const byte *); +int grammar_string_compare_n (const byte *, const byte *, size_t); +byte *grammar_string_copy (byte *, const byte *); +byte *grammar_string_copy_n (byte *, const byte *, size_t); +byte *grammar_string_duplicate (const byte *); +unsigned int grammar_string_length (const byte *); + +/* + loads grammar script from null-terminated ASCII <text> + returns unique grammar id to grammar object + returns 0 if an error occurs (call grammar_get_last_error to retrieve the error text) +*/ +grammar grammar_load_from_text (const byte *text); + +/* + sets a new <value> to a register <name> for grammar <id> + returns 0 on error (call grammar_get_last_error to retrieve the error text) + returns 1 on success +*/ +int grammar_set_reg8 (grammar id, const byte *name, byte value); + +/* + this function is obsolete, use only for debugging purposes + + checks if a null-terminated <text> matches given grammar <id> + returns 0 on error (call grammar_get_last_error to retrieve the error text) + returns 1 on success, the <prod> points to newly allocated buffer with production and <size> + is filled with the production size + call grammar_alloc_free to free the memory block pointed by <prod> +*/ +int grammar_check (grammar id, const byte *text, byte **prod, unsigned int *size); + +/* + does the same what grammar_check does but much more (approx. 4 times) faster + use this function instead of grammar_check + <estimate_prod_size> is a hint - the initial production buffer size will be of this size, + but if more room is needed it will be safely resized; set it to 0x1000 or so +*/ +int grammar_fast_check (grammar id, const byte *text, byte **prod, unsigned int *size, + unsigned int estimate_prod_size); + +/* + destroys grammar object identified by <id> + returns 0 on error (call grammar_get_last_error to retrieve the error text) + returns 1 on success +*/ +int grammar_destroy (grammar id); + +/* + retrieves last grammar error reported either by grammar_load_from_text, grammar_check + or grammar_destroy + the user allocated <text> buffer receives error description, <pos> points to error position, + <size> is the size of the text buffer to fill in - it must be at least 4 bytes long, +*/ +void grammar_get_last_error (byte *text, unsigned int size, int *pos); + +#ifdef __cplusplus +} +#endif + +#endif + diff --git a/nx-X11/extras/Mesa/src/mesa/shader/grammar/grammar_mesa.c b/nx-X11/extras/Mesa/src/mesa/shader/grammar/grammar_mesa.c new file mode 100644 index 000000000..eb962505b --- /dev/null +++ b/nx-X11/extras/Mesa/src/mesa/shader/grammar/grammar_mesa.c @@ -0,0 +1,87 @@ +/* + * Mesa 3-D graphics library + * Version: 6.1 + * + * Copyright (C) 1999-2004 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 grammar_mesa.c + * mesa3d port to syntax parsing engine + * \author Michal Krol + */ + +#include "grammar_mesa.h" + +#define GRAMMAR_PORT_BUILD 1 +#include "grammar.c" +#undef GRAMMAR_PORT_BUILD + + +void grammar_alloc_free (void *ptr) +{ + _mesa_free (ptr); +} + +void *grammar_alloc_malloc (size_t size) +{ + return _mesa_malloc (size); +} + +void *grammar_alloc_realloc (void *ptr, size_t old_size, size_t size) +{ + return _mesa_realloc (ptr, old_size, size); +} + +void *grammar_memory_copy (void *dst, const void * src, size_t size) +{ + return _mesa_memcpy (dst, src, size); +} + +int grammar_string_compare (const byte *str1, const byte *str2) +{ + return _mesa_strcmp ((const char *) str1, (const char *) str2); +} + +int grammar_string_compare_n (const byte *str1, const byte *str2, size_t n) +{ + return _mesa_strncmp ((const char *) str1, (const char *) str2, n); +} + +byte *grammar_string_copy (byte *dst, const byte *src) +{ + return (byte *) _mesa_strcpy ((char *) dst, (const char *) src); +} + +byte *grammar_string_copy_n (byte *dst, const byte *src, size_t n) +{ + return (byte *) _mesa_strncpy ((char *) dst, (const char *) src, n); +} + +byte *grammar_string_duplicate (const byte *src) +{ + return (byte *) _mesa_strdup ((const char *) src); +} + +unsigned int grammar_string_length (const byte *str) +{ + return (unsigned int)_mesa_strlen ((const char *) str); +} + diff --git a/nx-X11/extras/Mesa/src/mesa/shader/grammar/grammar_mesa.h b/nx-X11/extras/Mesa/src/mesa/shader/grammar/grammar_mesa.h new file mode 100644 index 000000000..c14033a9d --- /dev/null +++ b/nx-X11/extras/Mesa/src/mesa/shader/grammar/grammar_mesa.h @@ -0,0 +1,43 @@ +/* + * Mesa 3-D graphics library + * Version: 6.1 + * + * Copyright (C) 1999-2004 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 GRAMMAR_MESA_H +#define GRAMMAR_MESA_H + + +#include "imports.h" +/* NOTE: include Mesa 3-D specific headers here */ + + +typedef GLuint grammar; +typedef GLubyte byte; + + +#define GRAMMAR_PORT_INCLUDE 1 +#include "grammar.h" +#undef GRAMMAR_PORT_INCLUDE + + +#endif + diff --git a/nx-X11/extras/Mesa/src/mesa/shader/grammar/grammar_syn.h b/nx-X11/extras/Mesa/src/mesa/shader/grammar/grammar_syn.h new file mode 100644 index 000000000..840a1ab62 --- /dev/null +++ b/nx-X11/extras/Mesa/src/mesa/shader/grammar/grammar_syn.h @@ -0,0 +1,202 @@ +".syntax grammar;\n" +".emtcode DECLARATION_END 0\n" +".emtcode DECLARATION_EMITCODE 1\n" +".emtcode DECLARATION_ERRORTEXT 2\n" +".emtcode DECLARATION_REGBYTE 3\n" +".emtcode DECLARATION_LEXER 4\n" +".emtcode DECLARATION_RULE 5\n" +".emtcode SPECIFIER_END 0\n" +".emtcode SPECIFIER_AND_TAG 1\n" +".emtcode SPECIFIER_OR_TAG 2\n" +".emtcode SPECIFIER_CHARACTER_RANGE 3\n" +".emtcode SPECIFIER_CHARACTER 4\n" +".emtcode SPECIFIER_STRING 5\n" +".emtcode SPECIFIER_IDENTIFIER 6\n" +".emtcode SPECIFIER_TRUE 7\n" +".emtcode SPECIFIER_FALSE 8\n" +".emtcode SPECIFIER_DEBUG 9\n" +".emtcode IDENTIFIER_SIMPLE 0\n" +".emtcode IDENTIFIER_LOOP 1\n" +".emtcode ERROR_NOT_PRESENT 0\n" +".emtcode ERROR_PRESENT 1\n" +".emtcode EMIT_NULL 0\n" +".emtcode EMIT_INTEGER 1\n" +".emtcode EMIT_IDENTIFIER 2\n" +".emtcode EMIT_CHARACTER 3\n" +".emtcode EMIT_LAST_CHARACTER 4\n" +".emtcode EMIT_CURRENT_POSITION 5\n" +".errtext INVALID_GRAMMAR \"internal error 2001: invalid grammar script\"\n" +".errtext SYNTAX_EXPECTED \"internal error 2002: '.syntax' keyword expected\"\n" +".errtext IDENTIFIER_EXPECTED \"internal error 2003: identifier expected\"\n" +".errtext MISSING_SEMICOLON \"internal error 2004: missing ';'\"\n" +".errtext INTEGER_EXPECTED \"internal error 2005: integer value expected\"\n" +".errtext STRING_EXPECTED \"internal error 2006: string expected\"\n" +"grammar\n" +" grammar_1 .error INVALID_GRAMMAR;\n" +"grammar_1\n" +" optional_space .and \".syntax\" .error SYNTAX_EXPECTED .and space .and identifier .and\n" +" semicolon .and declaration_list .and optional_space .and '\\0' .emit DECLARATION_END;\n" +"optional_space\n" +" space .or .true;\n" +"space\n" +" single_space .and .loop single_space;\n" +"single_space\n" +" white_char .or comment_block;\n" +"white_char\n" +" ' ' .or '\\t' .or '\\n' .or '\\r';\n" +"comment_block\n" +" '/' .and '*' .and comment_rest;\n" +"comment_rest\n" +" .loop comment_char_no_star .and comment_rest_1;\n" +"comment_rest_1\n" +" comment_end .or comment_rest_2;\n" +"comment_rest_2\n" +" '*' .and comment_rest;\n" +"comment_char_no_star\n" +" '\\x2B'-'\\xFF' .or '\\x01'-'\\x29';\n" +"comment_end\n" +" '*' .and '/';\n" +"identifier\n" +" identifier_ne .error IDENTIFIER_EXPECTED;\n" +"identifier_ne\n" +" first_idchar .emit * .and .loop follow_idchar .emit * .and .true .emit '\\0';\n" +"first_idchar\n" +" 'a'-'z' .or 'A'-'Z' .or '_';\n" +"follow_idchar\n" +" first_idchar .or digit_dec;\n" +"digit_dec\n" +" '0'-'9';\n" +"semicolon\n" +" optional_space .and ';' .error MISSING_SEMICOLON .and optional_space;\n" +"declaration_list\n" +" declaration .and .loop declaration;\n" +"declaration\n" +" emitcode_definition .emit DECLARATION_EMITCODE .or\n" +" errortext_definition .emit DECLARATION_ERRORTEXT .or\n" +" regbyte_definition .emit DECLARATION_REGBYTE .or\n" +" lexer_definition .emit DECLARATION_LEXER .or\n" +" rule_definition .emit DECLARATION_RULE;\n" +"emitcode_definition\n" +" \".emtcode\" .and space .and identifier .and space .and integer .and space_or_null;\n" +"integer\n" +" integer_ne .error INTEGER_EXPECTED;\n" +"integer_ne\n" +" hex_integer .emit 0x10 .or dec_integer .emit 10;\n" +"hex_integer\n" +" hex_prefix .and digit_hex .emit * .and .loop digit_hex .emit * .and .true .emit '\\0';\n" +"hex_prefix\n" +" '0' .and hex_prefix_1;\n" +"hex_prefix_1\n" +" 'x' .or 'X';\n" +"digit_hex\n" +" '0'-'9' .or 'a'-'f' .or 'A'-'F';\n" +"dec_integer\n" +" digit_dec .emit * .and .loop digit_dec .emit * .and .true .emit '\\0';\n" +"space_or_null\n" +" space .or '\\0';\n" +"errortext_definition\n" +" \".errtext\" .and space .and identifier .and space .and string .and space_or_null;\n" +"string\n" +" string_ne .error STRING_EXPECTED;\n" +"string_ne\n" +" '\"' .and .loop string_char_double_quotes .and '\"' .emit '\\0';\n" +"string_char_double_quotes\n" +" escape_sequence .or string_char .emit * .or '\\'' .emit *;\n" +"string_char\n" +" '\\x5D'-'\\xFF' .or '\\x28'-'\\x5B' .or '\\x23'-'\\x26' .or '\\x0E'-'\\x21' .or '\\x0B'-'\\x0C' .or\n" +" '\\x01'-'\\x09';\n" +"escape_sequence\n" +" '\\\\' .emit * .and escape_code;\n" +"escape_code\n" +" simple_escape_code .emit * .or hex_escape_code .or oct_escape_code;\n" +"simple_escape_code\n" +" '\\'' .or '\"' .or '?' .or '\\\\' .or 'a' .or 'b' .or 'f' .or 'n' .or 'r' .or 't' .or 'v';\n" +"hex_escape_code\n" +" 'x' .emit * .and digit_hex .emit * .and .loop digit_hex .emit *;\n" +"oct_escape_code\n" +" digit_oct .emit * .and optional_digit_oct .and optional_digit_oct;\n" +"digit_oct\n" +" '0'-'7';\n" +"optional_digit_oct\n" +" digit_oct .emit * .or .true;\n" +"regbyte_definition\n" +" \".regbyte\" .and space .and identifier .and space .and integer .and space_or_null;\n" +"lexer_definition\n" +" \".string\" .and space .and identifier .and semicolon;\n" +"rule_definition\n" +" identifier_ne .and space .and definition;\n" +"definition\n" +" specifier .and optional_specifiers_and_or .and semicolon .emit SPECIFIER_END;\n" +"optional_specifiers_and_or\n" +" and_specifiers .emit SPECIFIER_AND_TAG .or or_specifiers .emit SPECIFIER_OR_TAG .or .true;\n" +"specifier\n" +" specifier_condition .and optional_space .and specifier_rule;\n" +"specifier_condition\n" +" specifier_condition_1 .or .true;\n" +"specifier_condition_1\n" +" \".if\" .and optional_space .and '(' .and optional_space .and left_operand .and operator .and\n" +" right_operand .and optional_space .and ')';\n" +"left_operand\n" +" identifier;\n" +"operator\n" +" operator_1 .or operator_2;\n" +"operator_1\n" +" optional_space .and '!' .and '=' .and optional_space;\n" +"operator_2\n" +" optional_space .and '=' .and '=' .and optional_space;\n" +"right_operand\n" +" integer;\n" +"specifier_rule\n" +" specifier_rule_1 .and optional_error .and .loop emit .and .true .emit EMIT_NULL;\n" +"specifier_rule_1\n" +" character_range .emit SPECIFIER_CHARACTER_RANGE .or\n" +" character .emit SPECIFIER_CHARACTER .or\n" +" string_ne .emit SPECIFIER_STRING .or\n" +" \".true\" .emit SPECIFIER_TRUE .or\n" +" \".false\" .emit SPECIFIER_FALSE .or\n" +" \".debug\" .emit SPECIFIER_DEBUG .or\n" +" advanced_identifier .emit SPECIFIER_IDENTIFIER;\n" +"character\n" +" '\\'' .and string_char_single_quotes .and '\\'' .emit '\\0';\n" +"string_char_single_quotes\n" +" escape_sequence .or string_char .emit * .or '\"' .emit *;\n" +"character_range\n" +" character .and optional_space .and '-' .and optional_space .and character;\n" +"advanced_identifier\n" +" optional_loop .and identifier;\n" +"optional_loop\n" +" optional_loop_1 .emit IDENTIFIER_LOOP .or .true .emit IDENTIFIER_SIMPLE;\n" +"optional_loop_1\n" +" \".loop\" .and space;\n" +"optional_error\n" +" error .emit ERROR_PRESENT .or .true .emit ERROR_NOT_PRESENT;\n" +"error\n" +" space .and \".error\" .and space .and identifier;\n" +"emit\n" +" emit_output .or emit_regbyte;\n" +"emit_output\n" +" space .and \".emit\" .and space .and emit_param;\n" +"emit_param\n" +" integer_ne .emit EMIT_INTEGER .or\n" +" identifier_ne .emit EMIT_IDENTIFIER .or\n" +" character .emit EMIT_CHARACTER .or\n" +" '*' .emit EMIT_LAST_CHARACTER .or\n" +" '$' .emit EMIT_CURRENT_POSITION;\n" +"emit_regbyte\n" +" space .and \".load\" .and space .and identifier .and space .and emit_param;\n" +"and_specifiers\n" +" and_specifier .and .loop and_specifier;\n" +"or_specifiers\n" +" or_specifier .and .loop or_specifier;\n" +"and_specifier\n" +" space .and \".and\" .and space .and specifier;\n" +"or_specifier\n" +" space .and \".or\" .and space .and specifier;\n" +".string __string_filter;\n" +"__string_filter\n" +" __first_identifier_char .and .loop __next_identifier_char;\n" +"__first_identifier_char\n" +" 'a'-'z' .or 'A'-'Z' .or '_' .or '.';\n" +"__next_identifier_char\n" +" 'a'-'z' .or 'A'-'Z' .or '_' .or '0'-'9';\n" +"" diff --git a/nx-X11/extras/Mesa/src/mesa/shader/nvfragparse.c b/nx-X11/extras/Mesa/src/mesa/shader/nvfragparse.c new file mode 100644 index 000000000..cd1aa35bf --- /dev/null +++ b/nx-X11/extras/Mesa/src/mesa/shader/nvfragparse.c @@ -0,0 +1,1826 @@ +/* + * Mesa 3-D graphics library + * Version: 6.4 + * + * 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 "glheader.h" +#include "context.h" +#include "hash.h" +#include "imports.h" +#include "macros.h" +#include "mtypes.h" +#include "nvfragprog.h" +#include "nvfragparse.h" +#include "nvprogram.h" +#include "program.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 fp_opcode opcode; + GLuint inputs; + GLuint outputs; + GLuint suffixes; +}; + +static const struct instruction_pattern Instructions[] = { + { "ADD", FP_OPCODE_ADD, INPUT_2V, OUTPUT_V, _R | _H | _X | _C | _S }, + { "COS", FP_OPCODE_COS, INPUT_1S, OUTPUT_S, _R | _H | _C | _S }, + { "DDX", FP_OPCODE_DDX, INPUT_1V, OUTPUT_V, _R | _H | _C | _S }, + { "DDY", FP_OPCODE_DDY, INPUT_1V, OUTPUT_V, _R | _H | _C | _S }, + { "DP3", FP_OPCODE_DP3, INPUT_2V, OUTPUT_S, _R | _H | _X | _C | _S }, + { "DP4", FP_OPCODE_DP4, INPUT_2V, OUTPUT_S, _R | _H | _X | _C | _S }, + { "DST", FP_OPCODE_DP4, INPUT_2V, OUTPUT_V, _R | _H | _C | _S }, + { "EX2", FP_OPCODE_DP4, INPUT_1S, OUTPUT_S, _R | _H | _C | _S }, + { "FLR", FP_OPCODE_FLR, INPUT_1V, OUTPUT_V, _R | _H | _X | _C | _S }, + { "FRC", FP_OPCODE_FRC, INPUT_1V, OUTPUT_V, _R | _H | _X | _C | _S }, + { "KIL", FP_OPCODE_KIL_NV, INPUT_CC, OUTPUT_NONE, 0 }, + { "LG2", FP_OPCODE_LG2, INPUT_1S, OUTPUT_S, _R | _H | _C | _S }, + { "LIT", FP_OPCODE_LIT, INPUT_1V, OUTPUT_V, _R | _H | _C | _S }, + { "LRP", FP_OPCODE_LRP, INPUT_3V, OUTPUT_V, _R | _H | _X | _C | _S }, + { "MAD", FP_OPCODE_MAD, INPUT_3V, OUTPUT_V, _R | _H | _X | _C | _S }, + { "MAX", FP_OPCODE_MAX, INPUT_2V, OUTPUT_V, _R | _H | _X | _C | _S }, + { "MIN", FP_OPCODE_MIN, INPUT_2V, OUTPUT_V, _R | _H | _X | _C | _S }, + { "MOV", FP_OPCODE_MOV, INPUT_1V, OUTPUT_V, _R | _H | _X | _C | _S }, + { "MUL", FP_OPCODE_MUL, INPUT_2V, OUTPUT_V, _R | _H | _X | _C | _S }, + { "PK2H", FP_OPCODE_PK2H, INPUT_1V, OUTPUT_S, 0 }, + { "PK2US", FP_OPCODE_PK2US, INPUT_1V, OUTPUT_S, 0 }, + { "PK4B", FP_OPCODE_PK4B, INPUT_1V, OUTPUT_S, 0 }, + { "PK4UB", FP_OPCODE_PK4UB, INPUT_1V, OUTPUT_S, 0 }, + { "POW", FP_OPCODE_POW, INPUT_2S, OUTPUT_S, _R | _H | _C | _S }, + { "RCP", FP_OPCODE_RCP, INPUT_1S, OUTPUT_S, _R | _H | _C | _S }, + { "RFL", FP_OPCODE_RFL, INPUT_2V, OUTPUT_V, _R | _H | _C | _S }, + { "RSQ", FP_OPCODE_RSQ, INPUT_1S, OUTPUT_S, _R | _H | _C | _S }, + { "SEQ", FP_OPCODE_SEQ, INPUT_2V, OUTPUT_V, _R | _H | _X | _C | _S }, + { "SFL", FP_OPCODE_SFL, INPUT_2V, OUTPUT_V, _R | _H | _X | _C | _S }, + { "SGE", FP_OPCODE_SGE, INPUT_2V, OUTPUT_V, _R | _H | _X | _C | _S }, + { "SGT", FP_OPCODE_SGT, INPUT_2V, OUTPUT_V, _R | _H | _X | _C | _S }, + { "SIN", FP_OPCODE_SIN, INPUT_1S, OUTPUT_S, _R | _H | _C | _S }, + { "SLE", FP_OPCODE_SLE, INPUT_2V, OUTPUT_V, _R | _H | _X | _C | _S }, + { "SLT", FP_OPCODE_SLT, INPUT_2V, OUTPUT_V, _R | _H | _X | _C | _S }, + { "SNE", FP_OPCODE_SNE, INPUT_2V, OUTPUT_V, _R | _H | _X | _C | _S }, + { "STR", FP_OPCODE_STR, INPUT_2V, OUTPUT_V, _R | _H | _X | _C | _S }, + { "SUB", FP_OPCODE_SUB, INPUT_2V, OUTPUT_V, _R | _H | _X | _C | _S }, + { "TEX", FP_OPCODE_TEX, INPUT_1V_T, OUTPUT_V, _C | _S }, + { "TXD", FP_OPCODE_TXD, INPUT_3V_T, OUTPUT_V, _C | _S }, + { "TXP", FP_OPCODE_TXP_NV, INPUT_1V_T, OUTPUT_V, _C | _S }, + { "UP2H", FP_OPCODE_UP2H, INPUT_1S, OUTPUT_V, _C | _S }, + { "UP2US", FP_OPCODE_UP2US, INPUT_1S, OUTPUT_V, _C | _S }, + { "UP4B", FP_OPCODE_UP4B, INPUT_1S, OUTPUT_V, _C | _S }, + { "UP4UB", FP_OPCODE_UP4UB, INPUT_1S, OUTPUT_V, _C | _S }, + { "X2D", FP_OPCODE_X2D, INPUT_3V, OUTPUT_V, _R | _H | _C | _S }, + { "PRINT", FP_OPCODE_PRINT, INPUT_1V_S, OUTPUT_NONE, 0 }, + { NULL, (enum fp_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 fragment_program *program; /* current program */ + + struct 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); + _mesa_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]; \ + _mesa_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; + + for (inst = Instructions; inst->name; inst++) { + if (_mesa_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; + } + } + result.opcode = (enum fp_opcode) -1; + 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)_mesa_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 +}; + +static const char *OutputRegisters[MAX_NV_FRAGMENT_PROGRAM_OUTPUTS + 1] = { + "COLR", "COLH", + /* These are only allows for register combiners */ + /* + "TEX0", "TEX1", "TEX2", "TEX3", + */ + "DEPR", 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_strtod((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 = _mesa_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; token[k] && k < 4; 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 fp_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_SWIZZLE(swz); + } + + 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 = _mesa_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 = _mesa_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 (_mesa_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]; + GLint j; + + /* 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 */ + for (j = 0; OutputRegisters[j]; j++) { + if (_mesa_strcmp((const char *) token, OutputRegisters[j]) == 0) { + static GLuint bothColors = (1 << FRAG_OUTPUT_COLR) | (1 << FRAG_OUTPUT_COLH); + *outputRegNum = j; + parseState->outputsWritten |= (1 << j); + if ((parseState->outputsWritten & bothColors) == bothColors) { + RETURN_ERROR1("Illegal to write to both o[COLR] and o[COLH]"); + } + break; + } + } + if (!OutputRegisters[j]) + 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 fp_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 (_mesa_strcmp((const char *) token, "RC") == 0 || + _mesa_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 fp_src_register *srcReg) +{ + GLfloat sign = 1.0F; + GLubyte token[100]; + GLint idx; + + /* + * 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; + srcReg->NegateAbs = (sign < 0.0F) ? GL_TRUE : GL_FALSE; + + if (Parse_String(parseState, "-")) + srcReg->NegateBase = GL_TRUE; + else if (Parse_String(parseState, "+")) + srcReg->NegateBase = GL_FALSE; + else + srcReg->NegateBase = GL_FALSE; + } + else { + srcReg->Abs = GL_FALSE; + srcReg->NegateAbs = GL_FALSE; + srcReg->NegateBase = (sign < 0.0F) ? GL_TRUE : GL_FALSE; + } + + /* 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 identier! */ + srcReg->File = PROGRAM_INPUT; + if (!Parse_FragReg(parseState, &idx)) + RETURN_ERROR; + srcReg->Index = idx; + } + else if (token[0] == 'p') { + /* XXX this might be an identier! */ + 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); + 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); + 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_SWIZZLE(swz); + } + + /* Finish absolute value */ + if (srcReg->Abs && !Parse_String(parseState, "|")) { + RETURN_ERROR1("Expected |"); + } + + return GL_TRUE; +} + + +static GLboolean +Parse_ScalarSrcReg(struct parse_state *parseState, + struct fp_src_register *srcReg) +{ + GLubyte token[100]; + GLfloat sign = 1.0F; + GLboolean needSuffix = GL_TRUE; + GLint idx; + + /* + * 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; + srcReg->NegateAbs = (sign < 0.0F) ? GL_TRUE : GL_FALSE; + + if (Parse_String(parseState, "-")) + srcReg->NegateBase = GL_TRUE; + else if (Parse_String(parseState, "+")) + srcReg->NegateBase = GL_FALSE; + else + srcReg->NegateBase = GL_FALSE; + } + else { + srcReg->Abs = GL_FALSE; + srcReg->NegateAbs = GL_FALSE; + srcReg->NegateBase = (sign < 0.0F) ? GL_TRUE : GL_FALSE; + } + + 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); + 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); + 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 fp_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 = _mesa_malloc(len + 1); + + _mesa_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 { + /* File = 0 indicates no register to print */ + inst->SrcReg[0].File = PROGRAM_UNDEFINED; + } + + inst->SrcReg[0].Swizzle = SWIZZLE_NOOP; + inst->SrcReg[0].NegateBase = GL_FALSE; + inst->SrcReg[0].Abs = GL_FALSE; + inst->SrcReg[0].NegateAbs = GL_FALSE; + + return GL_TRUE; +} + + +static GLboolean +Parse_InstructionSequence(struct parse_state *parseState, + struct fp_instruction program[]) +{ + while (1) { + struct fp_instruction *inst = program + parseState->numInst; + struct instruction_pattern instMatch; + GLubyte token[100]; + + /* Initialize the instruction */ + inst->SrcReg[0].File = PROGRAM_UNDEFINED; + inst->SrcReg[1].File = PROGRAM_UNDEFINED; + inst->SrcReg[2].File = PROGRAM_UNDEFINED; + inst->DstReg.File = PROGRAM_UNDEFINED; + inst->DstReg.CondSwizzle = SWIZZLE_NOOP; + inst->Data = NULL; + + /* 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 = FP_OPCODE_END; + inst->StringPos = parseState->curLine - parseState->start; + assert(inst->StringPos >= 0); + 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 < 0) { + /* bad instruction name */ + RETURN_ERROR2("Unexpected token: ", token); + } + + inst->Opcode = instMatch.opcode; + inst->Precision = instMatch.suffixes & (_R | _H | _X); + inst->Saturate = (instMatch.suffixes & (_S)) ? GL_TRUE : GL_FALSE; + inst->UpdateCondRegister = (instMatch.suffixes & (_C)) ? GL_TRUE : GL_FALSE; + inst->StringPos = parseState->curLine - parseState->start; + assert(inst->StringPos >= 0); + + /* + * 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 == FP_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 == FP_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->TexSrcIdx = 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->TexSrcIdx = 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 fragment_program *program) +{ + struct parse_state parseState; + struct fp_instruction instBuffer[MAX_NV_FRAGMENT_PROGRAM_INSTRUCTIONS]; + struct fp_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 */ + _mesa_bzero(&parseState, 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 (_mesa_strncmp((const char *) programString, "!!FP1.0", 7) == 0) { + target = GL_FRAGMENT_PROGRAM_NV; + parseState.pos = programString + 7; + } + else if (_mesa_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 = (struct fp_instruction *) + MALLOC(parseState.numInst * sizeof(struct fp_instruction)); + if (!newInst) { + _mesa_error(ctx, GL_OUT_OF_MEMORY, "glLoadProgramNV"); + return; /* out of memory */ + } + MEMCPY(newInst, instBuffer, + parseState.numInst * sizeof(struct fp_instruction)); + + /* 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->Instructions) { + FREE(program->Instructions); + } + program->Instructions = newInst; + program->InputsRead = parseState.inputsRead; + program->OutputsWritten = parseState.outputsWritten; + for (u = 0; u < ctx->Const.MaxTextureImageUnits; u++) + program->TexturesUsed[u] = parseState.texturesUsed[u]; + + /* save program parameters */ + program->Parameters = parseState.parameters; + + /* allocate registers for declared program parameters */ +#if 00 + _mesa_assign_program_registers(&(program->SymbolTable)); +#endif + +#ifdef DEBUG_foo + _mesa_printf("--- glLoadProgramNV(%d) result ---\n", program->Base.Id); + _mesa_print_nv_fragment_program(program); + _mesa_printf("----------------------------------\n"); +#endif + } + else { + /* Error! */ + _mesa_error(ctx, GL_INVALID_OPERATION, "glLoadProgramNV"); + /* NOTE: _mesa_set_program_error would have been called already */ + } +} + + +static void +PrintSrcReg(const struct fragment_program *program, + const struct fp_src_register *src) +{ + static const char comps[5] = "xyzw"; + + if (src->NegateAbs) { + _mesa_printf("-"); + } + if (src->Abs) { + _mesa_printf("|"); + } + if (src->NegateBase) { + _mesa_printf("-"); + } + if (src->File == PROGRAM_NAMED_PARAM) { + if (program->Parameters->Parameters[src->Index].Type == CONSTANT) { + _mesa_printf("{%g, %g, %g, %g}", + program->Parameters->ParameterValues[src->Index][0], + program->Parameters->ParameterValues[src->Index][1], + program->Parameters->ParameterValues[src->Index][2], + program->Parameters->ParameterValues[src->Index][3]); + } + else { + ASSERT(program->Parameters->Parameters[src->Index].Type + == NAMED_PARAMETER); + _mesa_printf("%s", program->Parameters->Parameters[src->Index].Name); + } + } + else if (src->File == PROGRAM_OUTPUT) { + _mesa_printf("o[%s]", OutputRegisters[src->Index]); + } + else if (src->File == PROGRAM_INPUT) { + _mesa_printf("f[%s]", InputRegisters[src->Index]); + } + else if (src->File == PROGRAM_LOCAL_PARAM) { + _mesa_printf("p[%d]", src->Index); + } + else if (src->File == PROGRAM_TEMPORARY) { + if (src->Index >= 32) + _mesa_printf("H%d", src->Index); + else + _mesa_printf("R%d", src->Index); + } + else if (src->File == PROGRAM_WRITE_ONLY) { + _mesa_printf("%cC", "HR"[src->Index]); + } + else { + _mesa_problem(NULL, "Invalid fragment register %d", src->Index); + return; + } + if (GET_SWZ(src->Swizzle, 0) == GET_SWZ(src->Swizzle, 1) && + GET_SWZ(src->Swizzle, 0) == GET_SWZ(src->Swizzle, 2) && + GET_SWZ(src->Swizzle, 0) == GET_SWZ(src->Swizzle, 3)) { + _mesa_printf(".%c", comps[GET_SWZ(src->Swizzle, 0)]); + } + else if (src->Swizzle != SWIZZLE_NOOP) { + _mesa_printf(".%c%c%c%c", + comps[GET_SWZ(src->Swizzle, 0)], + comps[GET_SWZ(src->Swizzle, 1)], + comps[GET_SWZ(src->Swizzle, 2)], + comps[GET_SWZ(src->Swizzle, 3)]); + } + if (src->Abs) { + _mesa_printf("|"); + } +} + +static void +PrintTextureSrc(const struct fp_instruction *inst) +{ + _mesa_printf("TEX%d, ", inst->TexSrcUnit); + switch (inst->TexSrcIdx) { + case TEXTURE_1D_INDEX: + _mesa_printf("1D"); + break; + case TEXTURE_2D_INDEX: + _mesa_printf("2D"); + break; + case TEXTURE_3D_INDEX: + _mesa_printf("3D"); + break; + case TEXTURE_RECT_INDEX: + _mesa_printf("RECT"); + break; + case TEXTURE_CUBE_INDEX: + _mesa_printf("CUBE"); + break; + default: + _mesa_problem(NULL, "Invalid textue target in PrintTextureSrc"); + } +} + +static void +PrintCondCode(const struct fp_dst_register *dst) +{ + static const char *comps = "xyzw"; + static const char *ccString[] = { + "??", "GT", "EQ", "LT", "UN", "GE", "LE", "NE", "TR", "FL", "??" + }; + + _mesa_printf("%s", ccString[dst->CondMask]); + if (GET_SWZ(dst->CondSwizzle, 0) == GET_SWZ(dst->CondSwizzle, 1) && + GET_SWZ(dst->CondSwizzle, 0) == GET_SWZ(dst->CondSwizzle, 2) && + GET_SWZ(dst->CondSwizzle, 0) == GET_SWZ(dst->CondSwizzle, 3)) { + _mesa_printf(".%c", comps[GET_SWZ(dst->CondSwizzle, 0)]); + } + else if (dst->CondSwizzle != SWIZZLE_NOOP) { + _mesa_printf(".%c%c%c%c", + comps[GET_SWZ(dst->CondSwizzle, 0)], + comps[GET_SWZ(dst->CondSwizzle, 1)], + comps[GET_SWZ(dst->CondSwizzle, 2)], + comps[GET_SWZ(dst->CondSwizzle, 3)]); + } +} + + +static void +PrintDstReg(const struct fp_dst_register *dst) +{ + if (dst->File == PROGRAM_OUTPUT) { + _mesa_printf("o[%s]", OutputRegisters[dst->Index]); + } + else if (dst->File == PROGRAM_TEMPORARY) { + if (dst->Index >= 32) + _mesa_printf("H%d", dst->Index); + else + _mesa_printf("R%d", dst->Index); + } + else if (dst->File == PROGRAM_LOCAL_PARAM) { + _mesa_printf("p[%d]", dst->Index); + } + else if (dst->File == PROGRAM_WRITE_ONLY) { + _mesa_printf("%cC", "HR"[dst->Index]); + } + else { + _mesa_printf("???"); + } + + if (dst->WriteMask != 0 && dst->WriteMask != 0xf) { + _mesa_printf("."); + if (dst->WriteMask & 0x1) + _mesa_printf("x"); + if (dst->WriteMask & 0x2) + _mesa_printf("y"); + if (dst->WriteMask & 0x4) + _mesa_printf("z"); + if (dst->WriteMask & 0x8) + _mesa_printf("w"); + } + + if (dst->CondMask != COND_TR || + dst->CondSwizzle != SWIZZLE_NOOP) { + _mesa_printf(" ("); + PrintCondCode(dst); + _mesa_printf(")"); + } +} + + +/** + * Print (unparse) the given vertex program. Just for debugging. + */ +void +_mesa_print_nv_fragment_program(const struct fragment_program *program) +{ + const struct fp_instruction *inst; + + for (inst = program->Instructions; inst->Opcode != FP_OPCODE_END; inst++) { + int i; + for (i = 0; Instructions[i].name; i++) { + if (inst->Opcode == Instructions[i].opcode) { + /* print instruction name */ + _mesa_printf("%s", Instructions[i].name); + if (inst->Precision == FLOAT16) + _mesa_printf("H"); + else if (inst->Precision == FIXED12) + _mesa_printf("X"); + if (inst->UpdateCondRegister) + _mesa_printf("C"); + if (inst->Saturate) + _mesa_printf("_SAT"); + _mesa_printf(" "); + + if (Instructions[i].inputs == INPUT_CC) { + PrintCondCode(&inst->DstReg); + } + else if (Instructions[i].outputs == OUTPUT_V || + Instructions[i].outputs == OUTPUT_S) { + /* print dest register */ + PrintDstReg(&inst->DstReg); + _mesa_printf(", "); + } + + /* print source register(s) */ + if (Instructions[i].inputs == INPUT_1V || + Instructions[i].inputs == INPUT_1S) { + PrintSrcReg(program, &inst->SrcReg[0]); + } + else if (Instructions[i].inputs == INPUT_2V || + Instructions[i].inputs == INPUT_2S) { + PrintSrcReg(program, &inst->SrcReg[0]); + _mesa_printf(", "); + PrintSrcReg(program, &inst->SrcReg[1]); + } + else if (Instructions[i].inputs == INPUT_3V) { + PrintSrcReg(program, &inst->SrcReg[0]); + _mesa_printf(", "); + PrintSrcReg(program, &inst->SrcReg[1]); + _mesa_printf(", "); + PrintSrcReg(program, &inst->SrcReg[2]); + } + else if (Instructions[i].inputs == INPUT_1V_T) { + PrintSrcReg(program, &inst->SrcReg[0]); + _mesa_printf(", "); + PrintTextureSrc(inst); + } + else if (Instructions[i].inputs == INPUT_3V_T) { + PrintSrcReg(program, &inst->SrcReg[0]); + _mesa_printf(", "); + PrintSrcReg(program, &inst->SrcReg[1]); + _mesa_printf(", "); + PrintSrcReg(program, &inst->SrcReg[2]); + _mesa_printf(", "); + PrintTextureSrc(inst); + } + _mesa_printf(";\n"); + break; + } + } + if (!Instructions[i].name) { + _mesa_printf("Invalid opcode %d\n", inst->Opcode); + } + } + _mesa_printf("END\n"); +} + + +const char * +_mesa_nv_fragment_input_register_name(GLuint i) +{ + ASSERT(i < MAX_NV_FRAGMENT_PROGRAM_INPUTS); + return InputRegisters[i]; +} + + +const char * +_mesa_nv_fragment_output_register_name(GLuint i) +{ + ASSERT(i < MAX_NV_FRAGMENT_PROGRAM_OUTPUTS); + return OutputRegisters[i]; +} diff --git a/nx-X11/extras/Mesa/src/mesa/shader/nvfragparse.h b/nx-X11/extras/Mesa/src/mesa/shader/nvfragparse.h new file mode 100644 index 000000000..849a7fbc7 --- /dev/null +++ b/nx-X11/extras/Mesa/src/mesa/shader/nvfragparse.h @@ -0,0 +1,52 @@ + +/* + * 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 fragment_program *program); + + +extern void +_mesa_print_nv_fragment_program(const struct fragment_program *program); + + +extern const char * +_mesa_nv_fragment_input_register_name(GLuint i); + + +extern const char * +_mesa_nv_fragment_output_register_name(GLuint i); + + +#endif diff --git a/nx-X11/extras/Mesa/src/mesa/shader/nvfragprog.h b/nx-X11/extras/Mesa/src/mesa/shader/nvfragprog.h new file mode 100644 index 000000000..a7149cfdb --- /dev/null +++ b/nx-X11/extras/Mesa/src/mesa/shader/nvfragprog.h @@ -0,0 +1,168 @@ +/* + * Mesa 3-D graphics library + * Version: 6.3 + * + * Copyright (C) 1999-2004 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. + */ + + +/* Private fragment program types and constants only used by files + * related to fragment programs. + * + * XXX TO-DO: Rename this file "fragprog.h" since it's not NV-specific. + */ + + +#ifndef NVFRAGPROG_H +#define NVFRAGPROG_H + +#include "config.h" +#include "mtypes.h" + +/* output registers */ +#define FRAG_OUTPUT_COLR 0 +#define FRAG_OUTPUT_COLH 1 +#define FRAG_OUTPUT_DEPR 2 + + +/* condition codes */ +#define COND_GT 1 /* greater than zero */ +#define COND_EQ 2 /* equal to zero */ +#define COND_LT 3 /* less than zero */ +#define COND_UN 4 /* unordered (NaN) */ +#define COND_GE 5 /* greater then or equal to zero */ +#define COND_LE 6 /* less then or equal to zero */ +#define COND_NE 7 /* not equal to zero */ +#define COND_TR 8 /* always true */ +#define COND_FL 9 /* always false */ + + +/* instruction precision */ +#define FLOAT32 0x1 +#define FLOAT16 0x2 +#define FIXED12 0x4 + + +/* Fragment program instruction opcodes */ +enum fp_opcode { + FP_OPCODE_ABS, /* ARB_f_p only */ + FP_OPCODE_ADD, + FP_OPCODE_CMP, /* ARB_f_p only */ + FP_OPCODE_COS, + FP_OPCODE_DDX, /* NV_f_p only */ + FP_OPCODE_DDY, /* NV_f_p only */ + FP_OPCODE_DP3, + FP_OPCODE_DP4, + FP_OPCODE_DPH, /* ARB_f_p only */ + FP_OPCODE_DST, + FP_OPCODE_END, /* private opcode */ + FP_OPCODE_EX2, + FP_OPCODE_FLR, + FP_OPCODE_FRC, + FP_OPCODE_KIL, /* ARB_f_p only */ + FP_OPCODE_KIL_NV, /* NV_f_p only */ + FP_OPCODE_LG2, + FP_OPCODE_LIT, + FP_OPCODE_LRP, + FP_OPCODE_MAD, + FP_OPCODE_MAX, + FP_OPCODE_MIN, + FP_OPCODE_MOV, + FP_OPCODE_MUL, + FP_OPCODE_PK2H, /* NV_f_p only */ + FP_OPCODE_PK2US, /* NV_f_p only */ + FP_OPCODE_PK4B, /* NV_f_p only */ + FP_OPCODE_PK4UB, /* NV_f_p only */ + FP_OPCODE_POW, + FP_OPCODE_PRINT, /* Mesa only */ + FP_OPCODE_RCP, + FP_OPCODE_RFL, /* NV_f_p only */ + FP_OPCODE_RSQ, + FP_OPCODE_SCS, /* ARB_f_p only */ + FP_OPCODE_SEQ, /* NV_f_p only */ + FP_OPCODE_SFL, /* NV_f_p only */ + FP_OPCODE_SGE, /* NV_f_p only */ + FP_OPCODE_SGT, /* NV_f_p only */ + FP_OPCODE_SIN, + FP_OPCODE_SLE, /* NV_f_p only */ + FP_OPCODE_SLT, + FP_OPCODE_SNE, /* NV_f_p only */ + FP_OPCODE_STR, /* NV_f_p only */ + FP_OPCODE_SUB, + FP_OPCODE_SWZ, /* ARB_f_p only */ + FP_OPCODE_TEX, + FP_OPCODE_TXB, /* ARB_f_p only */ + FP_OPCODE_TXD, /* NV_f_p only */ + FP_OPCODE_TXP, /* ARB_f_p only */ + FP_OPCODE_TXP_NV, /* NV_f_p only */ + FP_OPCODE_UP2H, /* NV_f_p only */ + FP_OPCODE_UP2US, /* NV_f_p only */ + FP_OPCODE_UP4B, /* NV_f_p only */ + FP_OPCODE_UP4UB, /* NV_f_p only */ + FP_OPCODE_X2D, /* NV_f_p only - 2d mat mul */ + FP_OPCODE_XPD /* ARB_f_p only - cross product */ +}; + + +/* Instruction source register */ +struct fp_src_register +{ + GLuint File:4; + GLuint Index:8; + GLuint Swizzle:12; + GLuint NegateBase:4; /* ARB: negate/extended negate. + NV: negate before absolute value? */ + GLuint Abs:1; /* NV: take absolute value? */ + GLuint NegateAbs:1; /* NV: negate after absolute value? */ +}; + + +/* Instruction destination register */ +struct fp_dst_register +{ + GLuint File:4; + GLuint Index:8; + GLuint WriteMask:4; + GLuint CondMask:4; /* NV: enough bits? */ + GLuint CondSwizzle:12; /* NV: enough bits? */ +}; + + +/* Fragment program instruction */ +struct fp_instruction +{ + GLuint Opcode:6; + GLuint Saturate:1; + GLuint UpdateCondRegister:1; /* NV */ + GLuint Precision:2; /* NV: unused/unneeded? */ + GLuint TexSrcUnit:4; /* texture unit for TEX, TXD, TXP instructions */ + GLuint TexSrcIdx:3; /* TEXTURE_1D,2D,3D,CUBE,RECT_INDEX source target */ + +#if FEATURE_MESA_program_debug + GLint StringPos:15; /* enough bits? */ +#endif + + void *Data; /* some arbitrary data, only used for PRINT instruction now */ + struct fp_src_register SrcReg[3]; + struct fp_dst_register DstReg; +}; + + +#endif diff --git a/nx-X11/extras/Mesa/src/mesa/shader/nvprogram.c b/nx-X11/extras/Mesa/src/mesa/shader/nvprogram.c new file mode 100644 index 000000000..4b8930176 --- /dev/null +++ b/nx-X11/extras/Mesa/src/mesa/shader/nvprogram.c @@ -0,0 +1,869 @@ +/* + * Mesa 3-D graphics library + * Version: 6.1 + * + * Copyright (C) 1999-2004 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 "glheader.h" +#include "context.h" +#include "hash.h" +#include "imports.h" +#include "macros.h" +#include "mtypes.h" +#include "nvfragparse.h" +#include "nvfragprog.h" +#include "nvvertexec.h" +#include "nvvertparse.h" +#include "nvvertprog.h" +#include "nvprogram.h" +#include "program.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 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 vertex_program *) + _mesa_HashLookup(ctx->Shared->Programs, id); + + if (!vprog || vprog->Base.Target != GL_VERTEX_STATE_PROGRAM_NV) { + _mesa_error(ctx, GL_INVALID_OPERATION, "glExecuteProgramNV"); + return; + } + + _mesa_init_vp_per_vertex_registers(ctx); + _mesa_init_vp_per_primitive_registers(ctx); + COPY_4V(ctx->VertexProgram.Inputs[VERT_ATTRIB_POS], params); + _mesa_exec_vertex_program(ctx, vprog); +} + + +/** + * 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 program *prog; + if (ids[i] == 0) { + _mesa_error(ctx, GL_INVALID_VALUE, "glAreProgramsResidentNV"); + return GL_FALSE; + } + prog = (const struct program *) + _mesa_HashLookup(ctx->Shared->Programs, 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 program *prog; + + if (ids[i] == 0) { + _mesa_error(ctx, GL_INVALID_VALUE, "glRequestResidentProgramsNV(id)"); + return; + } + + prog = (struct program *) _mesa_HashLookup(ctx->Shared->Programs, 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 program *prog; + GET_CURRENT_CONTEXT(ctx); + + if (!ctx->_CurrentProgram) + ASSERT_OUTSIDE_BEGIN_END(ctx); + + prog = (struct program *) _mesa_HashLookup(ctx->Shared->Programs, 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)_mesa_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 program *prog; + GET_CURRENT_CONTEXT(ctx); + + if (!ctx->_CurrentProgram) + ASSERT_OUTSIDE_BEGIN_END(ctx); + + if (pname != GL_PROGRAM_STRING_NV) { + _mesa_error(ctx, GL_INVALID_ENUM, "glGetProgramStringNV(pname)"); + return; + } + + prog = (struct program *) _mesa_HashLookup(ctx->Shared->Programs, id); + if (!prog) { + _mesa_error(ctx, GL_INVALID_OPERATION, "glGetProgramStringNV"); + return; + } + + if (prog->String) { + MEMCPY(program, prog->String, _mesa_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) +{ + GET_CURRENT_CONTEXT(ctx); + ASSERT_OUTSIDE_BEGIN_END(ctx); + + if (index == 0 || index >= MAX_NV_VERTEX_PROGRAM_INPUTS) { + _mesa_error(ctx, GL_INVALID_VALUE, "glGetVertexAttribdvNV(index)"); + return; + } + + switch (pname) { + case GL_ATTRIB_ARRAY_SIZE_NV: + params[0] = ctx->Array.VertexAttrib[index].Size; + break; + case GL_ATTRIB_ARRAY_STRIDE_NV: + params[0] = ctx->Array.VertexAttrib[index].Stride; + break; + case GL_ATTRIB_ARRAY_TYPE_NV: + params[0] = ctx->Array.VertexAttrib[index].Type; + break; + case GL_CURRENT_ATTRIB_NV: + 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) +{ + GET_CURRENT_CONTEXT(ctx); + ASSERT_OUTSIDE_BEGIN_END(ctx); + + if (index == 0 || index >= MAX_NV_VERTEX_PROGRAM_INPUTS) { + _mesa_error(ctx, GL_INVALID_VALUE, "glGetVertexAttribdvNV(index)"); + return; + } + + switch (pname) { + case GL_ATTRIB_ARRAY_SIZE_NV: + params[0] = (GLfloat) ctx->Array.VertexAttrib[index].Size; + break; + case GL_ATTRIB_ARRAY_STRIDE_NV: + params[0] = (GLfloat) ctx->Array.VertexAttrib[index].Stride; + break; + case GL_ATTRIB_ARRAY_TYPE_NV: + params[0] = (GLfloat) ctx->Array.VertexAttrib[index].Type; + break; + case GL_CURRENT_ATTRIB_NV: + 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) +{ + GET_CURRENT_CONTEXT(ctx); + ASSERT_OUTSIDE_BEGIN_END(ctx); + + if (index == 0 || index >= MAX_NV_VERTEX_PROGRAM_INPUTS) { + _mesa_error(ctx, GL_INVALID_VALUE, "glGetVertexAttribdvNV(index)"); + return; + } + + switch (pname) { + case GL_ATTRIB_ARRAY_SIZE_NV: + params[0] = ctx->Array.VertexAttrib[index].Size; + break; + case GL_ATTRIB_ARRAY_STRIDE_NV: + params[0] = ctx->Array.VertexAttrib[index].Stride; + break; + case GL_ATTRIB_ARRAY_TYPE_NV: + params[0] = ctx->Array.VertexAttrib[index].Type; + break; + case GL_CURRENT_ATTRIB_NV: + 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: + if (!ctx->Extensions.ARB_vertex_buffer_object) { + _mesa_error(ctx, GL_INVALID_ENUM, "glGetVertexAttribdvNV"); + return; + } + params[0] = ctx->Array.VertexAttrib[index].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.VertexAttrib[index].Ptr;; +} + + + +/** + * 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 program *prog; + GET_CURRENT_CONTEXT(ctx); + ASSERT_OUTSIDE_BEGIN_END(ctx); + + if (id == 0) { + _mesa_error(ctx, GL_INVALID_VALUE, "glLoadProgramNV(id)"); + return; + } + + FLUSH_VERTICES(ctx, _NEW_PROGRAM); + + prog = (struct program *) _mesa_HashLookup(ctx->Shared->Programs, 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 vertex_program *vprog = (struct vertex_program *) prog; + if (!vprog || prog == &_mesa_DummyProgram) { + vprog = (struct 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); + } + _mesa_parse_nv_vertex_program(ctx, target, program, len, vprog); + } + else if (target == GL_FRAGMENT_PROGRAM_NV + && ctx->Extensions.NV_fragment_program) { + struct fragment_program *fprog = (struct fragment_program *) prog; + if (!fprog || prog == &_mesa_DummyProgram) { + fprog = (struct 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 { + _mesa_error(ctx, GL_INVALID_ENUM, "glLoadProgramNV(target)"); + } +} + + + +/** + * Set a program parameter register. + * \note Called from the GL API dispatcher. + */ +void GLAPIENTRY +_mesa_ProgramParameter4dNV(GLenum target, GLuint index, + GLdouble x, GLdouble y, GLdouble z, GLdouble w) +{ + _mesa_ProgramParameter4fNV(target, index, + (GLfloat)x, (GLfloat)y, (GLfloat)z, (GLfloat)w); +} + + +/** + * Set a program parameter register. + * \note Called from the GL API dispatcher. + */ +void GLAPIENTRY +_mesa_ProgramParameter4dvNV(GLenum target, GLuint index, + const GLdouble *params) +{ + _mesa_ProgramParameter4fNV(target, index, + (GLfloat)params[0], (GLfloat)params[1], + (GLfloat)params[2], (GLfloat)params[3]); +} + + +/** + * Set a program parameter register. + * \note Called from the GL API dispatcher. + */ +void GLAPIENTRY +_mesa_ProgramParameter4fNV(GLenum target, GLuint index, + GLfloat x, GLfloat y, GLfloat z, GLfloat w) +{ + GET_CURRENT_CONTEXT(ctx); + ASSERT_OUTSIDE_BEGIN_END(ctx); + + if (target == GL_VERTEX_PROGRAM_NV && ctx->Extensions.NV_vertex_program) { + if (index < MAX_NV_VERTEX_PROGRAM_PARAMS) { + FLUSH_VERTICES(ctx, _NEW_PROGRAM); + ASSIGN_4V(ctx->VertexProgram.Parameters[index], x, y, z, w); + } + else { + _mesa_error(ctx, GL_INVALID_VALUE, "glProgramParameterNV(index)"); + return; + } + } + else { + _mesa_error(ctx, GL_INVALID_ENUM, "glProgramParameterNV"); + return; + } +} + + +/** + * Set a program parameter register. + * \note Called from the GL API dispatcher. + */ +void GLAPIENTRY +_mesa_ProgramParameter4fvNV(GLenum target, GLuint index, + const GLfloat *params) +{ + _mesa_ProgramParameter4fNV(target, index, + params[0], params[1], params[2], params[3]); +} + + + +/** + * 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 program *prog; + struct fragment_program *fragProg; + GLfloat *v; + + GET_CURRENT_CONTEXT(ctx); + ASSERT_OUTSIDE_BEGIN_END(ctx); + + FLUSH_VERTICES(ctx, _NEW_PROGRAM); + + prog = (struct program *) _mesa_HashLookup(ctx->Shared->Programs, 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 fragment_program *) prog; + v = _mesa_lookup_parameter_value(fragProg->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 program *prog; + struct fragment_program *fragProg; + const GLfloat *v; + + GET_CURRENT_CONTEXT(ctx); + + if (!ctx->_CurrentProgram) + ASSERT_OUTSIDE_BEGIN_END(ctx); + + prog = (struct program *) _mesa_HashLookup(ctx->Shared->Programs, 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 fragment_program *) prog; + v = _mesa_lookup_parameter_value(fragProg->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/nx-X11/extras/Mesa/src/mesa/shader/nvprogram.h b/nx-X11/extras/Mesa/src/mesa/shader/nvprogram.h new file mode 100644 index 000000000..dcea7727e --- /dev/null +++ b/nx-X11/extras/Mesa/src/mesa/shader/nvprogram.h @@ -0,0 +1,119 @@ +/* + * 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_ProgramParameter4dNV(GLenum target, GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w); + +extern void GLAPIENTRY +_mesa_ProgramParameter4dvNV(GLenum target, GLuint index, const GLdouble *params); + +extern void GLAPIENTRY +_mesa_ProgramParameter4fNV(GLenum target, GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w); + +extern void GLAPIENTRY +_mesa_ProgramParameter4fvNV(GLenum target, GLuint index, const GLfloat *params); + +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); + + +#endif diff --git a/nx-X11/extras/Mesa/src/mesa/shader/nvvertexec.c b/nx-X11/extras/Mesa/src/mesa/shader/nvvertexec.c new file mode 100644 index 000000000..dd5959688 --- /dev/null +++ b/nx-X11/extras/Mesa/src/mesa/shader/nvvertexec.c @@ -0,0 +1,851 @@ +/* + * 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 nvvertexec.c + * Code to execute vertex programs. + * \author Brian Paul + */ + +#include "glheader.h" +#include "context.h" +#include "imports.h" +#include "macros.h" +#include "mtypes.h" +#include "nvvertexec.h" +#include "nvvertprog.h" +#include "program.h" +#include "math/m_matrix.h" + + +static const GLfloat ZeroVec[4] = { 0.0F, 0.0F, 0.0F, 0.0F }; + + +/** + * Load/initialize the vertex program registers which need to be set + * per-vertex. + */ +void +_mesa_init_vp_per_vertex_registers(GLcontext *ctx) +{ + /* Input registers get initialized from the current vertex attribs */ + MEMCPY(ctx->VertexProgram.Inputs, ctx->Current.Attrib, + VERT_ATTRIB_MAX * 4 * sizeof(GLfloat)); + + if (ctx->VertexProgram.Current->IsNVProgram) { + GLuint i; + /* Output/result regs are initialized to [0,0,0,1] */ + for (i = 0; i < MAX_NV_VERTEX_PROGRAM_OUTPUTS; i++) { + ASSIGN_4V(ctx->VertexProgram.Outputs[i], 0.0F, 0.0F, 0.0F, 1.0F); + } + /* Temp regs are initialized to [0,0,0,0] */ + for (i = 0; i < MAX_NV_VERTEX_PROGRAM_TEMPS; i++) { + ASSIGN_4V(ctx->VertexProgram.Temporaries[i], 0.0F, 0.0F, 0.0F, 0.0F); + } + ASSIGN_4V(ctx->VertexProgram.AddressReg, 0, 0, 0, 0); + } +} + + + +/** + * Copy the 16 elements of a matrix into four consecutive program + * registers starting at 'pos'. + */ +static void +load_matrix(GLfloat registers[][4], GLuint pos, const GLfloat mat[16]) +{ + GLuint i; + for (i = 0; i < 4; i++) { + registers[pos + i][0] = mat[0 + i]; + registers[pos + i][1] = mat[4 + i]; + registers[pos + i][2] = mat[8 + i]; + registers[pos + i][3] = mat[12 + i]; + } +} + + +/** + * As above, but transpose the matrix. + */ +static void +load_transpose_matrix(GLfloat registers[][4], GLuint pos, + const GLfloat mat[16]) +{ + MEMCPY(registers[pos], mat, 16 * sizeof(GLfloat)); +} + + +/** + * Load program parameter registers with tracked matrices (if NV program) + * or GL state values (if ARB program). + * This needs to be done per glBegin/glEnd, not per-vertex. + */ +void +_mesa_init_vp_per_primitive_registers(GLcontext *ctx) +{ + if (ctx->VertexProgram.Current->IsNVProgram) { + GLuint i; + + for (i = 0; i < MAX_NV_VERTEX_PROGRAM_PARAMS / 4; i++) { + /* point 'mat' at source matrix */ + GLmatrix *mat; + if (ctx->VertexProgram.TrackMatrix[i] == GL_MODELVIEW) { + mat = ctx->ModelviewMatrixStack.Top; + } + else if (ctx->VertexProgram.TrackMatrix[i] == GL_PROJECTION) { + mat = ctx->ProjectionMatrixStack.Top; + } + else if (ctx->VertexProgram.TrackMatrix[i] == GL_TEXTURE) { + mat = ctx->TextureMatrixStack[ctx->Texture.CurrentUnit].Top; + } + else if (ctx->VertexProgram.TrackMatrix[i] == GL_COLOR) { + mat = ctx->ColorMatrixStack.Top; + } + else if (ctx->VertexProgram.TrackMatrix[i]==GL_MODELVIEW_PROJECTION_NV) { + /* XXX verify the combined matrix is up to date */ + mat = &ctx->_ModelProjectMatrix; + } + else if (ctx->VertexProgram.TrackMatrix[i] >= GL_MATRIX0_NV && + ctx->VertexProgram.TrackMatrix[i] <= GL_MATRIX7_NV) { + GLuint n = ctx->VertexProgram.TrackMatrix[i] - GL_MATRIX0_NV; + ASSERT(n < MAX_PROGRAM_MATRICES); + mat = ctx->ProgramMatrixStack[n].Top; + } + else { + /* no matrix is tracked, but we leave the register values as-is */ + assert(ctx->VertexProgram.TrackMatrix[i] == GL_NONE); + continue; + } + + /* load the matrix */ + if (ctx->VertexProgram.TrackMatrixTransform[i] == GL_IDENTITY_NV) { + load_matrix(ctx->VertexProgram.Parameters, i*4, mat->m); + } + else if (ctx->VertexProgram.TrackMatrixTransform[i] == GL_INVERSE_NV) { + _math_matrix_analyse(mat); /* update the inverse */ + ASSERT(!_math_matrix_is_dirty(mat)); + load_matrix(ctx->VertexProgram.Parameters, i*4, mat->inv); + } + else if (ctx->VertexProgram.TrackMatrixTransform[i] == GL_TRANSPOSE_NV) { + load_transpose_matrix(ctx->VertexProgram.Parameters, i*4, mat->m); + } + else { + assert(ctx->VertexProgram.TrackMatrixTransform[i] + == GL_INVERSE_TRANSPOSE_NV); + _math_matrix_analyse(mat); /* update the inverse */ + ASSERT(!_math_matrix_is_dirty(mat)); + load_transpose_matrix(ctx->VertexProgram.Parameters, i*4, mat->inv); + } + } + } + else { + /* Using and ARB vertex program */ + if (ctx->VertexProgram.Current->Parameters) { + /* Grab the state GL state and put into registers */ + _mesa_load_state_parameters(ctx, + ctx->VertexProgram.Current->Parameters); + } + } +} + + + +/** + * For debugging. Dump the current vertex program machine registers. + */ +void +_mesa_dump_vp_state( const struct gl_vertex_program_state *state ) +{ + int i; + _mesa_printf("VertexIn:\n"); + for (i = 0; i < MAX_NV_VERTEX_PROGRAM_INPUTS; i++) { + _mesa_printf("%d: %f %f %f %f ", i, + state->Inputs[i][0], + state->Inputs[i][1], + state->Inputs[i][2], + state->Inputs[i][3]); + } + _mesa_printf("\n"); + + _mesa_printf("VertexOut:\n"); + for (i = 0; i < MAX_NV_VERTEX_PROGRAM_OUTPUTS; i++) { + _mesa_printf("%d: %f %f %f %f ", i, + state->Outputs[i][0], + state->Outputs[i][1], + state->Outputs[i][2], + state->Outputs[i][3]); + } + _mesa_printf("\n"); + + _mesa_printf("Registers:\n"); + for (i = 0; i < MAX_NV_VERTEX_PROGRAM_TEMPS; i++) { + _mesa_printf("%d: %f %f %f %f ", i, + state->Temporaries[i][0], + state->Temporaries[i][1], + state->Temporaries[i][2], + state->Temporaries[i][3]); + } + _mesa_printf("\n"); + + _mesa_printf("Parameters:\n"); + for (i = 0; i < MAX_NV_VERTEX_PROGRAM_PARAMS; i++) { + _mesa_printf("%d: %f %f %f %f ", i, + state->Parameters[i][0], + state->Parameters[i][1], + state->Parameters[i][2], + state->Parameters[i][3]); + } + _mesa_printf("\n"); +} + + + +/** + * Return a pointer to the 4-element float vector specified by the given + * source register. + */ +static INLINE const GLfloat * +get_register_pointer( const struct vp_src_register *source, + const struct gl_vertex_program_state *state ) +{ + if (source->RelAddr) { + const GLint reg = source->Index + state->AddressReg[0]; + ASSERT( (source->File == PROGRAM_ENV_PARAM) || + (source->File == PROGRAM_STATE_VAR) ); + if (reg < 0 || reg > MAX_NV_VERTEX_PROGRAM_PARAMS) + return ZeroVec; + else if (source->File == PROGRAM_ENV_PARAM) + return state->Parameters[reg]; + else + return state->Current->Parameters->ParameterValues[reg]; + } + else { + switch (source->File) { + case PROGRAM_TEMPORARY: + ASSERT(source->Index < MAX_NV_VERTEX_PROGRAM_TEMPS); + return state->Temporaries[source->Index]; + case PROGRAM_INPUT: + ASSERT(source->Index < MAX_NV_VERTEX_PROGRAM_INPUTS); + return state->Inputs[source->Index]; + case PROGRAM_OUTPUT: + /* This is only needed for the PRINT instruction */ + ASSERT(source->Index < MAX_NV_VERTEX_PROGRAM_OUTPUTS); + return state->Outputs[source->Index]; + case PROGRAM_LOCAL_PARAM: + ASSERT(source->Index < MAX_PROGRAM_LOCAL_PARAMS); + return state->Current->Base.LocalParams[source->Index]; + case PROGRAM_ENV_PARAM: + ASSERT(source->Index < MAX_NV_VERTEX_PROGRAM_PARAMS); + return state->Parameters[source->Index]; + case PROGRAM_STATE_VAR: + ASSERT(source->Index < state->Current->Parameters->NumParameters); + return state->Current->Parameters->ParameterValues[source->Index]; + default: + _mesa_problem(NULL, + "Bad source register file in get_register_pointer"); + return NULL; + } + } + return NULL; +} + + +/** + * Fetch a 4-element float vector from the given source register. + * Apply swizzling and negating as needed. + */ +static INLINE void +fetch_vector4( const struct vp_src_register *source, + const struct gl_vertex_program_state *state, + GLfloat result[4] ) +{ + const GLfloat *src = get_register_pointer(source, state); + + if (source->Negate) { + 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)]; + } + else { + result[0] = src[GET_SWZ(source->Swizzle, 0)]; + result[1] = src[GET_SWZ(source->Swizzle, 1)]; + result[2] = src[GET_SWZ(source->Swizzle, 2)]; + result[3] = src[GET_SWZ(source->Swizzle, 3)]; + } +} + + + +/** + * As above, but only return result[0] element. + */ +static INLINE void +fetch_vector1( const struct vp_src_register *source, + const struct gl_vertex_program_state *state, + GLfloat result[4] ) +{ + const GLfloat *src = get_register_pointer(source, state); + + if (source->Negate) { + result[0] = -src[GET_SWZ(source->Swizzle, 0)]; + } + else { + result[0] = src[GET_SWZ(source->Swizzle, 0)]; + } +} + + +/** + * Store 4 floats into a register. + */ +static void +store_vector4( const struct vp_dst_register *dest, + struct gl_vertex_program_state *state, + const GLfloat value[4] ) +{ + GLfloat *dst; + switch (dest->File) { + case PROGRAM_TEMPORARY: + dst = state->Temporaries[dest->Index]; + break; + case PROGRAM_OUTPUT: + dst = state->Outputs[dest->Index]; + break; + case PROGRAM_ENV_PARAM: + { + /* a slight hack */ + GET_CURRENT_CONTEXT(ctx); + dst = ctx->VertexProgram.Parameters[dest->Index]; + } + break; + default: + _mesa_problem(NULL, "Invalid register file in store_vector4(file=%d)", + dest->File); + return; + } + + if (dest->WriteMask & WRITEMASK_X) + dst[0] = value[0]; + if (dest->WriteMask & WRITEMASK_Y) + dst[1] = value[1]; + if (dest->WriteMask & WRITEMASK_Z) + dst[2] = value[2]; + if (dest->WriteMask & WRITEMASK_W) + dst[3] = value[3]; +} + + +/** + * Set x to positive or negative infinity. + */ +#if defined(USE_IEEE) || defined(_WIN32) +#define SET_POS_INFINITY(x) ( *((GLuint *) (void *)&x) = 0x7F800000 ) +#define SET_NEG_INFINITY(x) ( *((GLuint *) (void *)&x) = 0xFF800000 ) +#elif defined(VMS) +#define SET_POS_INFINITY(x) x = __MAXFLOAT +#define SET_NEG_INFINITY(x) x = -__MAXFLOAT +#else +#define SET_POS_INFINITY(x) x = (GLfloat) HUGE_VAL +#define SET_NEG_INFINITY(x) x = (GLfloat) -HUGE_VAL +#endif + +#define SET_FLOAT_BITS(x, bits) ((fi_type *) (void *) &(x))->i = bits + + +/** + * Execute the given vertex program + */ +void +_mesa_exec_vertex_program(GLcontext *ctx, const struct vertex_program *program) +{ + struct gl_vertex_program_state *state = &ctx->VertexProgram; + const struct vp_instruction *inst; + + ctx->_CurrentProgram = GL_VERTEX_PROGRAM_ARB; /* or NV, doesn't matter */ + + /* If the program is position invariant, multiply the input + * position and the MVP matrix and stick it into the output pos slot + */ + if (ctx->VertexProgram.Current->IsPositionInvariant) { + TRANSFORM_POINT( ctx->VertexProgram.Outputs[0], + ctx->_ModelProjectMatrix.m, + ctx->VertexProgram.Inputs[0]); + + /* XXX: This could go elsewhere */ + ctx->VertexProgram.Current->OutputsWritten |= 0x1; + } + for (inst = program->Instructions; ; inst++) { + + if (ctx->VertexProgram.CallbackEnabled && + ctx->VertexProgram.Callback) { + ctx->VertexProgram.CurrentPosition = inst->StringPos; + ctx->VertexProgram.Callback(program->Base.Target, + ctx->VertexProgram.CallbackData); + } + + switch (inst->Opcode) { + case VP_OPCODE_MOV: + { + GLfloat t[4]; + fetch_vector4( &inst->SrcReg[0], state, t ); + store_vector4( &inst->DstReg, state, t ); + } + break; + case VP_OPCODE_LIT: + { + const GLfloat epsilon = 1.0F / 256.0F; /* per NV spec */ + GLfloat t[4], lit[4]; + fetch_vector4( &inst->SrcReg[0], state, t ); + t[0] = MAX2(t[0], 0.0F); + t[1] = MAX2(t[1], 0.0F); + t[3] = CLAMP(t[3], -(128.0F - epsilon), (128.0F - epsilon)); + lit[0] = 1.0; + lit[1] = t[0]; + lit[2] = (t[0] > 0.0) ? (GLfloat) _mesa_pow(t[1], t[3]) : 0.0F; + lit[3] = 1.0; + store_vector4( &inst->DstReg, state, lit ); + } + break; + case VP_OPCODE_RCP: + { + GLfloat t[4]; + fetch_vector1( &inst->SrcReg[0], state, t ); + if (t[0] != 1.0F) + t[0] = 1.0F / t[0]; /* div by zero is infinity! */ + t[1] = t[2] = t[3] = t[0]; + store_vector4( &inst->DstReg, state, t ); + } + break; + case VP_OPCODE_RSQ: + { + GLfloat t[4]; + fetch_vector1( &inst->SrcReg[0], state, t ); + t[0] = INV_SQRTF(FABSF(t[0])); + t[1] = t[2] = t[3] = t[0]; + store_vector4( &inst->DstReg, state, t ); + } + break; + case VP_OPCODE_EXP: + { + GLfloat t[4], q[4], floor_t0; + fetch_vector1( &inst->SrcReg[0], state, t ); + floor_t0 = (float) floor(t[0]); + if (floor_t0 > FLT_MAX_EXP) { + SET_POS_INFINITY(q[0]); + SET_POS_INFINITY(q[2]); + } + else if (floor_t0 < FLT_MIN_EXP) { + q[0] = 0.0F; + q[2] = 0.0F; + } + else { +#ifdef USE_IEEE + GLint ii = (GLint) floor_t0; + ii = (ii < 23) + 0x3f800000; + SET_FLOAT_BITS(q[0], ii); + q[0] = *((GLfloat *) (void *)&ii); +#else + q[0] = (GLfloat) pow(2.0, floor_t0); +#endif + q[2] = (GLfloat) (q[0] * LOG2(q[1])); + } + q[1] = t[0] - floor_t0; + q[3] = 1.0F; + store_vector4( &inst->DstReg, state, q ); + } + break; + case VP_OPCODE_LOG: + { + GLfloat t[4], q[4], abs_t0; + fetch_vector1( &inst->SrcReg[0], state, t ); + abs_t0 = (GLfloat) fabs(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; + double mantissa = frexp(t[0], &exponent); + q[0] = (GLfloat) (exponent - 1); + q[1] = (GLfloat) (2.0 * mantissa); /* map [.5, 1) -> [1, 2) */ + q[2] = (GLfloat) (q[0] + LOG2(q[1])); + } + } + else { + SET_NEG_INFINITY(q[0]); + q[1] = 1.0F; + SET_NEG_INFINITY(q[2]); + } + q[3] = 1.0; + store_vector4( &inst->DstReg, state, q ); + } + break; + case VP_OPCODE_MUL: + { + GLfloat t[4], u[4], prod[4]; + fetch_vector4( &inst->SrcReg[0], state, t ); + fetch_vector4( &inst->SrcReg[1], state, u ); + prod[0] = t[0] * u[0]; + prod[1] = t[1] * u[1]; + prod[2] = t[2] * u[2]; + prod[3] = t[3] * u[3]; + store_vector4( &inst->DstReg, state, prod ); + } + break; + case VP_OPCODE_ADD: + { + GLfloat t[4], u[4], sum[4]; + fetch_vector4( &inst->SrcReg[0], state, t ); + fetch_vector4( &inst->SrcReg[1], state, u ); + sum[0] = t[0] + u[0]; + sum[1] = t[1] + u[1]; + sum[2] = t[2] + u[2]; + sum[3] = t[3] + u[3]; + store_vector4( &inst->DstReg, state, sum ); + } + break; + case VP_OPCODE_DP3: + { + GLfloat t[4], u[4], dot[4]; + fetch_vector4( &inst->SrcReg[0], state, t ); + fetch_vector4( &inst->SrcReg[1], state, u ); + dot[0] = t[0] * u[0] + t[1] * u[1] + t[2] * u[2]; + dot[1] = dot[2] = dot[3] = dot[0]; + store_vector4( &inst->DstReg, state, dot ); + } + break; + case VP_OPCODE_DP4: + { + GLfloat t[4], u[4], dot[4]; + fetch_vector4( &inst->SrcReg[0], state, t ); + fetch_vector4( &inst->SrcReg[1], state, u ); + dot[0] = t[0] * u[0] + t[1] * u[1] + t[2] * u[2] + t[3] * u[3]; + dot[1] = dot[2] = dot[3] = dot[0]; + store_vector4( &inst->DstReg, state, dot ); + } + break; + case VP_OPCODE_DST: + { + GLfloat t[4], u[4], dst[4]; + fetch_vector4( &inst->SrcReg[0], state, t ); + fetch_vector4( &inst->SrcReg[1], state, u ); + dst[0] = 1.0F; + dst[1] = t[1] * u[1]; + dst[2] = t[2]; + dst[3] = u[3]; + store_vector4( &inst->DstReg, state, dst ); + } + break; + case VP_OPCODE_MIN: + { + GLfloat t[4], u[4], min[4]; + fetch_vector4( &inst->SrcReg[0], state, t ); + fetch_vector4( &inst->SrcReg[1], state, u ); + min[0] = (t[0] < u[0]) ? t[0] : u[0]; + min[1] = (t[1] < u[1]) ? t[1] : u[1]; + min[2] = (t[2] < u[2]) ? t[2] : u[2]; + min[3] = (t[3] < u[3]) ? t[3] : u[3]; + store_vector4( &inst->DstReg, state, min ); + } + break; + case VP_OPCODE_MAX: + { + GLfloat t[4], u[4], max[4]; + fetch_vector4( &inst->SrcReg[0], state, t ); + fetch_vector4( &inst->SrcReg[1], state, u ); + max[0] = (t[0] > u[0]) ? t[0] : u[0]; + max[1] = (t[1] > u[1]) ? t[1] : u[1]; + max[2] = (t[2] > u[2]) ? t[2] : u[2]; + max[3] = (t[3] > u[3]) ? t[3] : u[3]; + store_vector4( &inst->DstReg, state, max ); + } + break; + case VP_OPCODE_SLT: + { + GLfloat t[4], u[4], slt[4]; + fetch_vector4( &inst->SrcReg[0], state, t ); + fetch_vector4( &inst->SrcReg[1], state, u ); + slt[0] = (t[0] < u[0]) ? 1.0F : 0.0F; + slt[1] = (t[1] < u[1]) ? 1.0F : 0.0F; + slt[2] = (t[2] < u[2]) ? 1.0F : 0.0F; + slt[3] = (t[3] < u[3]) ? 1.0F : 0.0F; + store_vector4( &inst->DstReg, state, slt ); + } + break; + case VP_OPCODE_SGE: + { + GLfloat t[4], u[4], sge[4]; + fetch_vector4( &inst->SrcReg[0], state, t ); + fetch_vector4( &inst->SrcReg[1], state, u ); + sge[0] = (t[0] >= u[0]) ? 1.0F : 0.0F; + sge[1] = (t[1] >= u[1]) ? 1.0F : 0.0F; + sge[2] = (t[2] >= u[2]) ? 1.0F : 0.0F; + sge[3] = (t[3] >= u[3]) ? 1.0F : 0.0F; + store_vector4( &inst->DstReg, state, sge ); + } + break; + case VP_OPCODE_MAD: + { + GLfloat t[4], u[4], v[4], sum[4]; + fetch_vector4( &inst->SrcReg[0], state, t ); + fetch_vector4( &inst->SrcReg[1], state, u ); + fetch_vector4( &inst->SrcReg[2], state, v ); + sum[0] = t[0] * u[0] + v[0]; + sum[1] = t[1] * u[1] + v[1]; + sum[2] = t[2] * u[2] + v[2]; + sum[3] = t[3] * u[3] + v[3]; + store_vector4( &inst->DstReg, state, sum ); + } + break; + case VP_OPCODE_ARL: + { + GLfloat t[4]; + fetch_vector4( &inst->SrcReg[0], state, t ); + state->AddressReg[0] = (GLint) floor(t[0]); + } + break; + case VP_OPCODE_DPH: + { + GLfloat t[4], u[4], dot[4]; + fetch_vector4( &inst->SrcReg[0], state, t ); + fetch_vector4( &inst->SrcReg[1], state, u ); + dot[0] = t[0] * u[0] + t[1] * u[1] + t[2] * u[2] + u[3]; + dot[1] = dot[2] = dot[3] = dot[0]; + store_vector4( &inst->DstReg, state, dot ); + } + break; + case VP_OPCODE_RCC: + { + GLfloat t[4], u; + fetch_vector1( &inst->SrcReg[0], state, t ); + if (t[0] == 1.0F) + u = 1.0F; + else + u = 1.0F / t[0]; + if (u > 0.0F) { + if (u > 1.884467e+019F) { + u = 1.884467e+019F; /* IEEE 32-bit binary value 0x5F800000 */ + } + else if (u < 5.42101e-020F) { + u = 5.42101e-020F; /* IEEE 32-bit binary value 0x1F800000 */ + } + } + else { + if (u < -1.884467e+019F) { + u = -1.884467e+019F; /* IEEE 32-bit binary value 0xDF800000 */ + } + else if (u > -5.42101e-020F) { + u = -5.42101e-020F; /* IEEE 32-bit binary value 0x9F800000 */ + } + } + t[0] = t[1] = t[2] = t[3] = u; + store_vector4( &inst->DstReg, state, t ); + } + break; + case VP_OPCODE_SUB: /* GL_NV_vertex_program1_1 */ + { + GLfloat t[4], u[4], sum[4]; + fetch_vector4( &inst->SrcReg[0], state, t ); + fetch_vector4( &inst->SrcReg[1], state, u ); + sum[0] = t[0] - u[0]; + sum[1] = t[1] - u[1]; + sum[2] = t[2] - u[2]; + sum[3] = t[3] - u[3]; + store_vector4( &inst->DstReg, state, sum ); + } + break; + case VP_OPCODE_ABS: /* GL_NV_vertex_program1_1 */ + { + GLfloat t[4]; + fetch_vector4( &inst->SrcReg[0], state, t ); + if (t[0] < 0.0) t[0] = -t[0]; + if (t[1] < 0.0) t[1] = -t[1]; + if (t[2] < 0.0) t[2] = -t[2]; + if (t[3] < 0.0) t[3] = -t[3]; + store_vector4( &inst->DstReg, state, t ); + } + break; + case VP_OPCODE_FLR: /* GL_ARB_vertex_program */ + { + GLfloat t[4]; + fetch_vector4( &inst->SrcReg[0], state, t ); + t[0] = FLOORF(t[0]); + t[1] = FLOORF(t[1]); + t[2] = FLOORF(t[2]); + t[3] = FLOORF(t[3]); + store_vector4( &inst->DstReg, state, t ); + } + break; + case VP_OPCODE_FRC: /* GL_ARB_vertex_program */ + { + GLfloat t[4]; + fetch_vector4( &inst->SrcReg[0], state, t ); + t[0] = t[0] - FLOORF(t[0]); + t[1] = t[1] - FLOORF(t[1]); + t[2] = t[2] - FLOORF(t[2]); + t[3] = t[3] - FLOORF(t[3]); + store_vector4( &inst->DstReg, state, t ); + } + break; + case VP_OPCODE_EX2: /* GL_ARB_vertex_program */ + { + GLfloat t[4]; + fetch_vector1( &inst->SrcReg[0], state, t ); + t[0] = t[1] = t[2] = t[3] = (GLfloat)_mesa_pow(2.0, t[0]); + store_vector4( &inst->DstReg, state, t ); + } + break; + case VP_OPCODE_LG2: /* GL_ARB_vertex_program */ + { + GLfloat t[4]; + fetch_vector1( &inst->SrcReg[0], state, t ); + t[0] = t[1] = t[2] = t[3] = LOG2(t[0]); + store_vector4( &inst->DstReg, state, t ); + } + break; + case VP_OPCODE_POW: /* GL_ARB_vertex_program */ + { + GLfloat t[4], u[4]; + fetch_vector1( &inst->SrcReg[0], state, t ); + fetch_vector1( &inst->SrcReg[1], state, u ); + t[0] = t[1] = t[2] = t[3] = (GLfloat)_mesa_pow(t[0], u[0]); + store_vector4( &inst->DstReg, state, t ); + } + break; + case VP_OPCODE_XPD: /* GL_ARB_vertex_program */ + { + GLfloat t[4], u[4], cross[4]; + fetch_vector4( &inst->SrcReg[0], state, t ); + fetch_vector4( &inst->SrcReg[1], state, u ); + cross[0] = t[1] * u[2] - t[2] * u[1]; + cross[1] = t[2] * u[0] - t[0] * u[2]; + cross[2] = t[0] * u[1] - t[1] * u[0]; + store_vector4( &inst->DstReg, state, cross ); + } + break; + case VP_OPCODE_SWZ: /* GL_ARB_vertex_program */ + { + const struct vp_src_register *source = &inst->SrcReg[0]; + const GLfloat *src = get_register_pointer(source, state); + GLfloat result[4]; + GLuint i; + + /* do extended swizzling here */ + for (i = 0; i < 4; i++) { + if (GET_SWZ(source->Swizzle, i) == SWIZZLE_ZERO) + result[i] = 0.0; + else if (GET_SWZ(source->Swizzle, i) == SWIZZLE_ONE) + result[i] = 1.0; + else + result[i] = src[GET_SWZ(source->Swizzle, i)]; + if (source->Negate & (1 << i)) + result[i] = -result[i]; + } + store_vector4( &inst->DstReg, state, result ); + } + break; + case VP_OPCODE_PRINT: + if (inst->SrcReg[0].File) { + GLfloat t[4]; + fetch_vector4( &inst->SrcReg[0], state, t ); + _mesa_printf("%s%g, %g, %g, %g\n", + (char *) inst->Data, t[0], t[1], t[2], t[3]); + } + else { + _mesa_printf("%s\n", (char *) inst->Data); + } + break; + case VP_OPCODE_END: + ctx->_CurrentProgram = 0; + return; + default: + /* bad instruction opcode */ + _mesa_problem(ctx, "Bad VP Opcode in _mesa_exec_vertex_program"); + ctx->_CurrentProgram = 0; + return; + } /* switch */ + } /* for */ + + ctx->_CurrentProgram = 0; +} + + + +/** +Thoughts on vertex program optimization: + +The obvious thing to do is to compile the vertex program into X86/SSE/3DNow! +assembly code. That will probably be a lot of work. + +Another approach might be to replace the vp_instruction->Opcode field with +a pointer to a specialized C function which executes the instruction. +In particular we can write functions which skip swizzling, negating, +masking, relative addressing, etc. when they're not needed. + +For example: + +void simple_add( struct vp_instruction *inst ) +{ + GLfloat *sum = machine->Registers[inst->DstReg.Register]; + GLfloat *a = machine->Registers[inst->SrcReg[0].Register]; + GLfloat *b = machine->Registers[inst->SrcReg[1].Register]; + sum[0] = a[0] + b[0]; + sum[1] = a[1] + b[1]; + sum[2] = a[2] + b[2]; + sum[3] = a[3] + b[3]; +} + +*/ + +/* + +KW: + +A first step would be to 'vectorize' the programs in the same way as +the normal transformation code in the tnl module. Thus each opcode +takes zero or more input vectors (registers) and produces one or more +output vectors. + +These operations would intially be coded in C, with machine-specific +assembly following, as is currently the case for matrix +transformations in the math/ directory. The preprocessing scheme for +selecting simpler operations Brian describes above would also work +here. + +This should give reasonable performance without excessive effort. + +*/ diff --git a/nx-X11/extras/Mesa/src/mesa/shader/nvvertexec.h b/nx-X11/extras/Mesa/src/mesa/shader/nvvertexec.h new file mode 100644 index 000000000..cdf1bd588 --- /dev/null +++ b/nx-X11/extras/Mesa/src/mesa/shader/nvvertexec.h @@ -0,0 +1,43 @@ +/* + * Mesa 3-D graphics library + * Version: 6.1 + * + * Copyright (C) 1999-2004 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 NVVERTEXEC_H +#define NVVERTEXEC_H + +extern void +_mesa_init_vp_per_vertex_registers(GLcontext *ctx); + +extern void +_mesa_init_vp_per_primitive_registers(GLcontext *ctx); + +extern void +_mesa_exec_vertex_program(GLcontext *ctx, const struct vertex_program *program); + +extern void +_mesa_dump_vp_state( const struct gl_vertex_program_state *state ); + +#endif diff --git a/nx-X11/extras/Mesa/src/mesa/shader/nvvertparse.c b/nx-X11/extras/Mesa/src/mesa/shader/nvvertparse.c new file mode 100644 index 000000000..33bc2004a --- /dev/null +++ b/nx-X11/extras/Mesa/src/mesa/shader/nvvertparse.c @@ -0,0 +1,1603 @@ +/* + * Mesa 3-D graphics library + * Version: 6.3 + * + * Copyright (C) 1999-2004 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 "glheader.h" +#include "context.h" +#include "hash.h" +#include "imports.h" +#include "macros.h" +#include "mtypes.h" +#include "nvprogram.h" +#include "nvvertparse.h" +#include "nvvertprog.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; + GLuint inputsRead; + GLuint 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); + _mesa_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]; \ + _mesa_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)_mesa_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", "BFC0", "BFC1", "FOGC", "PSIZ", + "TEX0", "TEX1", "TEX2", "TEX3", "TEX4", "TEX5", "TEX6", "TEX7", NULL +}; + +/* NOTE: the order here must match opcodes in nvvertprog.h */ +static const char *Opcodes[] = { + "MOV", "LIT", "RCP", "RSQ", "EXP", "LOG", "MUL", "ADD", "DP3", "DP4", + "DST", "MIN", "MAX", "SLT", "SGE", "MAD", "ARL", "DPH", "RCC", "SUB", + "ABS", "END", + /* GL_ARB_vertex_program */ + "FLR", "FRC", "EX2", "LG2", "POW", "XPD", "SWZ", + /* Mesa-specific */ + "PRINT", + 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 = _mesa_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 = _mesa_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 vp_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 = _mesa_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 (_mesa_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 = _mesa_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 = _mesa_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 (_mesa_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 (_mesa_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 vp_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 vp_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 = GL_TRUE; + if (!Peek_Token(parseState, token)) + RETURN_ERROR; + } + else { + srcReg->Negate = GL_FALSE; + } + + /* 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 = MAKE_SWIZZLE4(0, 0, 0, 0); + else if (token[0] == 'y') + srcReg->Swizzle = MAKE_SWIZZLE4(1, 1, 1, 1); + else if (token[0] == 'z') + srcReg->Swizzle = MAKE_SWIZZLE4(2, 2, 2, 2); + else if (token[0] == 'w') + srcReg->Swizzle = MAKE_SWIZZLE4(3, 3, 3, 3); + else + RETURN_ERROR1("Expected x, y, z, or w"); + } + else { + /* 2, 3 or 4-component swizzle */ + GLint k; + 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 vp_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 = GL_TRUE; + (void) Parse_String(parseState, "-"); /* consume '-' */ + if (!Peek_Token(parseState, token)) + RETURN_ERROR; + } + else { + srcReg->Negate = GL_FALSE; + } + + /* 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 vp_instruction *inst, enum vp_opcode opcode) +{ + if (opcode == VP_OPCODE_ABS && !parseState->isVersion1_1) + RETURN_ERROR1("ABS illegal for vertex program 1.0"); + + inst->Opcode = opcode; + inst->StringPos = parseState->curLine - parseState->start; + + /* 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 vp_instruction *inst, enum vp_opcode opcode) +{ + if (opcode == VP_OPCODE_DPH && !parseState->isVersion1_1) + RETURN_ERROR1("DPH illegal for vertex program 1.0"); + if (opcode == VP_OPCODE_SUB && !parseState->isVersion1_1) + RETURN_ERROR1("SUB illegal for vertex program 1.0"); + + inst->Opcode = opcode; + inst->StringPos = parseState->curLine - parseState->start; + + /* 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 vp_instruction *inst, enum vp_opcode opcode) +{ + inst->Opcode = opcode; + inst->StringPos = parseState->curLine - parseState->start; + + /* 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 vp_instruction *inst, enum vp_opcode opcode) +{ + if (opcode == VP_OPCODE_RCC && !parseState->isVersion1_1) + RETURN_ERROR1("RCC illegal for vertex program 1.0"); + + inst->Opcode = opcode; + inst->StringPos = parseState->curLine - parseState->start; + + /* 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 vp_instruction *inst) +{ + inst->Opcode = VP_OPCODE_ARL; + inst->StringPos = parseState->curLine - parseState->start; + + /* 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 vp_instruction *inst) +{ + GLubyte token[100]; + + inst->Opcode = VP_OPCODE_END; + inst->StringPos = parseState->curLine - parseState->start; + + /* 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 vp_instruction *inst) +{ + const GLubyte *str; + GLubyte *msg; + GLuint len; + GLubyte token[100]; + struct vp_src_register *srcReg = &inst->SrcReg[0]; + GLint idx; + + inst->Opcode = VP_OPCODE_PRINT; + inst->StringPos = parseState->curLine - parseState->start; + + /* 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 = _mesa_malloc(len + 1); + + _mesa_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 = GL_FALSE; + 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 vp_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 vp_instruction program[]) +{ + while (1) { + struct vp_instruction *inst = program + parseState->numInst; + + /* Initialize the instruction */ + inst->SrcReg[0].File = PROGRAM_UNDEFINED; + inst->SrcReg[1].File = PROGRAM_UNDEFINED; + inst->SrcReg[2].File = PROGRAM_UNDEFINED; + inst->DstReg.File = PROGRAM_UNDEFINED; + inst->Data = NULL; + + if (Parse_String(parseState, "MOV")) { + if (!Parse_UnaryOpInstruction(parseState, inst, VP_OPCODE_MOV)) + RETURN_ERROR; + } + else if (Parse_String(parseState, "LIT")) { + if (!Parse_UnaryOpInstruction(parseState, inst, VP_OPCODE_LIT)) + RETURN_ERROR; + } + else if (Parse_String(parseState, "ABS")) { + if (!Parse_UnaryOpInstruction(parseState, inst, VP_OPCODE_ABS)) + RETURN_ERROR; + } + else if (Parse_String(parseState, "MUL")) { + if (!Parse_BiOpInstruction(parseState, inst, VP_OPCODE_MUL)) + RETURN_ERROR; + } + else if (Parse_String(parseState, "ADD")) { + if (!Parse_BiOpInstruction(parseState, inst, VP_OPCODE_ADD)) + RETURN_ERROR; + } + else if (Parse_String(parseState, "DP3")) { + if (!Parse_BiOpInstruction(parseState, inst, VP_OPCODE_DP3)) + RETURN_ERROR; + } + else if (Parse_String(parseState, "DP4")) { + if (!Parse_BiOpInstruction(parseState, inst, VP_OPCODE_DP4)) + RETURN_ERROR; + } + else if (Parse_String(parseState, "DST")) { + if (!Parse_BiOpInstruction(parseState, inst, VP_OPCODE_DST)) + RETURN_ERROR; + } + else if (Parse_String(parseState, "MIN")) { + if (!Parse_BiOpInstruction(parseState, inst, VP_OPCODE_MIN)) + RETURN_ERROR; + } + else if (Parse_String(parseState, "MAX")) { + if (!Parse_BiOpInstruction(parseState, inst, VP_OPCODE_MAX)) + RETURN_ERROR; + } + else if (Parse_String(parseState, "SLT")) { + if (!Parse_BiOpInstruction(parseState, inst, VP_OPCODE_SLT)) + RETURN_ERROR; + } + else if (Parse_String(parseState, "SGE")) { + if (!Parse_BiOpInstruction(parseState, inst, VP_OPCODE_SGE)) + RETURN_ERROR; + } + else if (Parse_String(parseState, "DPH")) { + if (!Parse_BiOpInstruction(parseState, inst, VP_OPCODE_DPH)) + RETURN_ERROR; + } + else if (Parse_String(parseState, "SUB")) { + if (!Parse_BiOpInstruction(parseState, inst, VP_OPCODE_SUB)) + RETURN_ERROR; + } + else if (Parse_String(parseState, "MAD")) { + if (!Parse_TriOpInstruction(parseState, inst, VP_OPCODE_MAD)) + RETURN_ERROR; + } + else if (Parse_String(parseState, "RCP")) { + if (!Parse_ScalarInstruction(parseState, inst, VP_OPCODE_RCP)) + RETURN_ERROR; + } + else if (Parse_String(parseState, "RSQ")) { + if (!Parse_ScalarInstruction(parseState, inst, VP_OPCODE_RSQ)) + RETURN_ERROR; + } + else if (Parse_String(parseState, "EXP")) { + if (!Parse_ScalarInstruction(parseState, inst, VP_OPCODE_EXP)) + RETURN_ERROR; + } + else if (Parse_String(parseState, "LOG")) { + if (!Parse_ScalarInstruction(parseState, inst, VP_OPCODE_LOG)) + RETURN_ERROR; + } + else if (Parse_String(parseState, "RCC")) { + if (!Parse_ScalarInstruction(parseState, inst, VP_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 vp_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 vertex_program *program) +{ + struct parse_state parseState; + struct vp_instruction instBuffer[MAX_NV_VERTEX_PROGRAM_INSTRUCTIONS]; + struct vp_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 (_mesa_strncmp((const char *) programString, "!!VP1.0", 7) == 0) { + target = GL_VERTEX_PROGRAM_NV; + parseState.pos = programString + 7; + parseState.isStateProgram = GL_FALSE; + } + else if (_mesa_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 (_mesa_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)) { + /* 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)) { + /* 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 = (struct vp_instruction *) + MALLOC(parseState.numInst * sizeof(struct vp_instruction)); + if (!newInst) { + _mesa_error(ctx, GL_OUT_OF_MEMORY, "glLoadProgramNV"); + FREE(programString); + return; /* out of memory */ + } + MEMCPY(newInst, instBuffer, + parseState.numInst * sizeof(struct vp_instruction)); + + /* 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->Instructions) { + FREE(program->Instructions); + } + program->Instructions = newInst; + program->InputsRead = parseState.inputsRead; + program->OutputsWritten = parseState.outputsWritten; + program->IsPositionInvariant = parseState.isPositionInvariant; + program->IsNVProgram = GL_TRUE; + +#ifdef DEBUG_foo + _mesa_printf("--- glLoadProgramNV result ---\n"); + _mesa_print_nv_vertex_program(program); + _mesa_printf("------------------------------\n"); +#endif + } + 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); + } +} + + +static void +PrintSrcReg(const struct vp_src_register *src) +{ + static const char comps[5] = "xyzw"; + if (src->Negate) + _mesa_printf("-"); + if (src->RelAddr) { + if (src->Index > 0) + _mesa_printf("c[A0.x + %d]", src->Index); + else if (src->Index < 0) + _mesa_printf("c[A0.x - %d]", -src->Index); + else + _mesa_printf("c[A0.x]"); + } + else if (src->File == PROGRAM_OUTPUT) { + _mesa_printf("o[%s]", OutputRegisters[src->Index]); + } + else if (src->File == PROGRAM_INPUT) { + _mesa_printf("v[%s]", InputRegisters[src->Index]); + } + else if (src->File == PROGRAM_ENV_PARAM) { + _mesa_printf("c[%d]", src->Index); + } + else { + ASSERT(src->File == PROGRAM_TEMPORARY); + _mesa_printf("R%d", src->Index); + } + + if (GET_SWZ(src->Swizzle, 0) == GET_SWZ(src->Swizzle, 1) && + GET_SWZ(src->Swizzle, 0) == GET_SWZ(src->Swizzle, 2) && + GET_SWZ(src->Swizzle, 0) == GET_SWZ(src->Swizzle, 3)) { + _mesa_printf(".%c", comps[GET_SWZ(src->Swizzle, 0)]); + } + else if (src->Swizzle != SWIZZLE_NOOP) { + _mesa_printf(".%c%c%c%c", + comps[GET_SWZ(src->Swizzle, 0)], + comps[GET_SWZ(src->Swizzle, 1)], + comps[GET_SWZ(src->Swizzle, 2)], + comps[GET_SWZ(src->Swizzle, 3)]); + } +} + + +static void +PrintDstReg(const struct vp_dst_register *dst) +{ + if (dst->File == PROGRAM_OUTPUT) { + _mesa_printf("o[%s]", OutputRegisters[dst->Index]); + } + else if (dst->File == PROGRAM_INPUT) { + _mesa_printf("v[%s]", InputRegisters[dst->Index]); + } + else if (dst->File == PROGRAM_ENV_PARAM) { + _mesa_printf("c[%d]", dst->Index); + } + else { + ASSERT(dst->File == PROGRAM_TEMPORARY); + _mesa_printf("R%d", dst->Index); + } + + if (dst->WriteMask != 0 && dst->WriteMask != 0xf) { + _mesa_printf("."); + if (dst->WriteMask & 0x1) + _mesa_printf("x"); + if (dst->WriteMask & 0x2) + _mesa_printf("y"); + if (dst->WriteMask & 0x4) + _mesa_printf("z"); + if (dst->WriteMask & 0x8) + _mesa_printf("w"); + } +} + + +/** + * Print a single NVIDIA vertex program instruction. + */ +void +_mesa_print_nv_vertex_instruction(const struct vp_instruction *inst) +{ + switch (inst->Opcode) { + case VP_OPCODE_MOV: + case VP_OPCODE_LIT: + case VP_OPCODE_RCP: + case VP_OPCODE_RSQ: + case VP_OPCODE_EXP: + case VP_OPCODE_LOG: + case VP_OPCODE_RCC: + case VP_OPCODE_ABS: + _mesa_printf("%s ", Opcodes[(int) inst->Opcode]); + PrintDstReg(&inst->DstReg); + _mesa_printf(", "); + PrintSrcReg(&inst->SrcReg[0]); + _mesa_printf(";\n"); + break; + case VP_OPCODE_MUL: + case VP_OPCODE_ADD: + case VP_OPCODE_DP3: + case VP_OPCODE_DP4: + case VP_OPCODE_DST: + case VP_OPCODE_MIN: + case VP_OPCODE_MAX: + case VP_OPCODE_SLT: + case VP_OPCODE_SGE: + case VP_OPCODE_DPH: + case VP_OPCODE_SUB: + _mesa_printf("%s ", Opcodes[(int) inst->Opcode]); + PrintDstReg(&inst->DstReg); + _mesa_printf(", "); + PrintSrcReg(&inst->SrcReg[0]); + _mesa_printf(", "); + PrintSrcReg(&inst->SrcReg[1]); + _mesa_printf(";\n"); + break; + case VP_OPCODE_MAD: + _mesa_printf("MAD "); + PrintDstReg(&inst->DstReg); + _mesa_printf(", "); + PrintSrcReg(&inst->SrcReg[0]); + _mesa_printf(", "); + PrintSrcReg(&inst->SrcReg[1]); + _mesa_printf(", "); + PrintSrcReg(&inst->SrcReg[2]); + _mesa_printf(";\n"); + break; + case VP_OPCODE_ARL: + _mesa_printf("ARL A0.x, "); + PrintSrcReg(&inst->SrcReg[0]); + _mesa_printf(";\n"); + break; + case VP_OPCODE_PRINT: + _mesa_printf("PRINT '%s'", inst->Data); + if (inst->SrcReg[0].File) { + _mesa_printf(", "); + PrintSrcReg(&inst->SrcReg[0]); + _mesa_printf(";\n"); + } + else { + _mesa_printf("\n"); + } + break; + case VP_OPCODE_END: + _mesa_printf("END\n"); + break; + default: + _mesa_printf("BAD INSTRUCTION\n"); + } +} + + +/** + * Print (unparse) the given vertex program. Just for debugging. + */ +void +_mesa_print_nv_vertex_program(const struct vertex_program *program) +{ + const struct vp_instruction *inst; + + for (inst = program->Instructions; ; inst++) { + _mesa_print_nv_vertex_instruction(inst); + if (inst->Opcode == VP_OPCODE_END) + return; + } +} + + +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/nx-X11/extras/Mesa/src/mesa/shader/nvvertparse.h b/nx-X11/extras/Mesa/src/mesa/shader/nvvertparse.h new file mode 100644 index 000000000..205885f45 --- /dev/null +++ b/nx-X11/extras/Mesa/src/mesa/shader/nvvertparse.h @@ -0,0 +1,50 @@ +/* + * 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 vertex_program *program); + +extern void +_mesa_print_nv_vertex_instruction(const struct vp_instruction *inst); + +extern void +_mesa_print_nv_vertex_program(const struct 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/nx-X11/extras/Mesa/src/mesa/shader/nvvertprog.h b/nx-X11/extras/Mesa/src/mesa/shader/nvvertprog.h new file mode 100644 index 000000000..b8dbe3631 --- /dev/null +++ b/nx-X11/extras/Mesa/src/mesa/shader/nvvertprog.h @@ -0,0 +1,111 @@ +/* + * Mesa 3-D graphics library + * Version: 6.3.1 + * + * 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. + */ + + +/* Private vertex program types and constants only used by files + * related to vertex programs. + * + * XXX TO-DO: Rename this file "vertprog.h" since it's not NV-specific. + */ + + +#ifndef NVVERTPROG_H +#define NVVERTPROG_H + + +/* Vertex program opcodes */ +enum vp_opcode +{ + VP_OPCODE_ABS, + VP_OPCODE_ADD, + VP_OPCODE_ARL, + VP_OPCODE_DP3, + VP_OPCODE_DP4, + VP_OPCODE_DPH, + VP_OPCODE_DST, + VP_OPCODE_END, /* Placeholder */ + VP_OPCODE_EX2, /* ARB only */ + VP_OPCODE_EXP, + VP_OPCODE_FLR, /* ARB */ + VP_OPCODE_FRC, /* ARB */ + VP_OPCODE_LG2, /* ARB only */ + VP_OPCODE_LIT, + VP_OPCODE_LOG, + VP_OPCODE_MAD, + VP_OPCODE_MAX, + VP_OPCODE_MIN, + VP_OPCODE_MOV, + VP_OPCODE_MUL, + VP_OPCODE_POW, /* ARB only */ + VP_OPCODE_PRINT, /* Mesa only */ + VP_OPCODE_RCC, + VP_OPCODE_RCP, + VP_OPCODE_RSQ, + VP_OPCODE_SGE, + VP_OPCODE_SLT, + VP_OPCODE_SUB, + VP_OPCODE_SWZ, /* ARB only */ + VP_OPCODE_XPD, /* ARB only */ + + VP_MAX_OPCODE +}; + + + +/* Instruction source register */ +struct vp_src_register +{ + GLuint File:4; /* one of the PROGRAM_* register file values */ + GLint Index:9; /* may be negative for relative addressing */ + GLuint Swizzle:12; + GLuint Negate:4; /* ARB requires component-wise negation. */ + GLuint RelAddr:1; + GLuint pad:2; +}; + + +/* Instruction destination register */ +struct vp_dst_register +{ + GLuint File:4; /* one of the PROGRAM_* register file values */ + GLuint Index:8; + GLuint WriteMask:4; + GLuint pad:16; +}; + + +/* Vertex program instruction */ +struct vp_instruction +{ + GLshort Opcode; +#if FEATURE_MESA_program_debug + GLshort StringPos; +#endif + void *Data; /* some arbitrary data, only used for PRINT instruction now */ + struct vp_src_register SrcReg[3]; + struct vp_dst_register DstReg; +}; + + +#endif /* VERTPROG_H */ diff --git a/nx-X11/extras/Mesa/src/mesa/shader/program.c b/nx-X11/extras/Mesa/src/mesa/shader/program.c new file mode 100644 index 000000000..0ccc741dd --- /dev/null +++ b/nx-X11/extras/Mesa/src/mesa/shader/program.c @@ -0,0 +1,1405 @@ +/* + * Mesa 3-D graphics library + * Version: 6.2 + * + * Copyright (C) 1999-2004 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 "glheader.h" +#include "context.h" +#include "hash.h" +#include "imports.h" +#include "macros.h" +#include "mtypes.h" +#include "program.h" +#include "nvfragparse.h" +#include "nvfragprog.h" +#include "nvvertparse.h" +#include "nvvertprog.h" + + +/**********************************************************************/ +/* Utility functions */ +/**********************************************************************/ + + +/* A pointer to this dummy program is put into the hash table when + * glGenPrograms is called. + */ +struct program _mesa_DummyProgram; + + +/** + * Init context's vertex/fragment program state + */ +void +_mesa_init_program(GLcontext *ctx) +{ + GLuint i; + + ctx->Program.ErrorPos = -1; + ctx->Program.ErrorString = _mesa_strdup(""); + +#if FEATURE_NV_vertex_program || FEATURE_ARB_vertex_program + ctx->VertexProgram.Enabled = GL_FALSE; + ctx->VertexProgram.PointSizeEnabled = GL_FALSE; + ctx->VertexProgram.TwoSideEnabled = GL_FALSE; + ctx->VertexProgram.Current = (struct vertex_program *) ctx->Shared->DefaultVertexProgram; + assert(ctx->VertexProgram.Current); + ctx->VertexProgram.Current->Base.RefCount++; + for (i = 0; i < MAX_NV_VERTEX_PROGRAM_PARAMS / 4; i++) { + ctx->VertexProgram.TrackMatrix[i] = GL_NONE; + ctx->VertexProgram.TrackMatrixTransform[i] = GL_IDENTITY_NV; + } +#endif + +#if FEATURE_NV_fragment_program || FEATURE_ARB_fragment_program + ctx->FragmentProgram.Enabled = GL_FALSE; + ctx->FragmentProgram.Current = (struct fragment_program *) ctx->Shared->DefaultFragmentProgram; + assert(ctx->FragmentProgram.Current); + ctx->FragmentProgram.Current->Base.RefCount++; +#endif + +#if FEATURE_ATI_fragment_shader + ctx->ATIFragmentShader.Enabled = GL_FALSE; + ctx->ATIFragmentShader.Current = (struct ati_fragment_shader *) ctx->Shared->DefaultFragmentShader; + assert(ctx->ATIFragmentShader.Current); + ctx->ATIFragmentShader.Current->Base.RefCount++; +#endif +} + + +/** + * Free a context's vertex/fragment program state + */ +void +_mesa_free_program_data(GLcontext *ctx) +{ +#if FEATURE_NV_vertex_program + if (ctx->VertexProgram.Current) { + ctx->VertexProgram.Current->Base.RefCount--; + if (ctx->VertexProgram.Current->Base.RefCount <= 0) + ctx->Driver.DeleteProgram(ctx, &(ctx->VertexProgram.Current->Base)); + } +#endif +#if FEATURE_NV_fragment_program + if (ctx->FragmentProgram.Current) { + ctx->FragmentProgram.Current->Base.RefCount--; + if (ctx->FragmentProgram.Current->Base.RefCount <= 0) + ctx->Driver.DeleteProgram(ctx, &(ctx->FragmentProgram.Current->Base)); + } +#endif +#if FEATURE_ATI_fragment_shader + if (ctx->ATIFragmentShader.Current) { + ctx->ATIFragmentShader.Current->Base.RefCount--; + if (ctx->ATIFragmentShader.Current->Base.RefCount <= 0) + ctx->Driver.DeleteProgram(ctx, &(ctx->ATIFragmentShader.Current->Base)); + } +#endif + _mesa_free((void *) ctx->Program.ErrorString); +} + + + + +/** + * 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; + _mesa_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 + * _mesa_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 *) _mesa_malloc(len + 1); + _mesa_memcpy(s, lineStart, len); + s[len] = 0; + + return s; +} + + +/** + * Initialize a new vertex/fragment program object. + */ +static struct program * +_mesa_init_program_struct( GLcontext *ctx, struct program *prog, + GLenum target, GLuint id) +{ + (void) ctx; + if (prog) { + prog->Id = id; + prog->Target = target; + prog->Resident = GL_TRUE; + prog->RefCount = 1; + } + + return prog; +} + + +/** + * Initialize a new fragment program object. + */ +struct program * +_mesa_init_fragment_program( GLcontext *ctx, struct 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 program * +_mesa_init_vertex_program( GLcontext *ctx, struct vertex_program *prog, + GLenum target, GLuint id) +{ + if (prog) + return _mesa_init_program_struct( ctx, &prog->Base, target, id ); + else + return NULL; +} + +/** + * Initialize a new ATI fragment shader object. + */ +struct program * +_mesa_init_ati_fragment_shader( GLcontext *ctx, + struct ati_fragment_shader *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 program * +_mesa_new_program(GLcontext *ctx, GLenum target, GLuint id) +{ + switch (target) { + case GL_VERTEX_PROGRAM_ARB: /* == GL_VERTEX_PROGRAM_NV */ + return _mesa_init_vertex_program( ctx, CALLOC_STRUCT(vertex_program), + target, id ); + case GL_FRAGMENT_PROGRAM_NV: + case GL_FRAGMENT_PROGRAM_ARB: + return _mesa_init_fragment_program( ctx, CALLOC_STRUCT(fragment_program), + target, id ); + case GL_FRAGMENT_SHADER_ATI: + return _mesa_init_ati_fragment_shader( ctx, CALLOC_STRUCT(ati_fragment_shader), + target, id ); + + default: + _mesa_problem(ctx, "bad target in _mesa_new_program"); + return NULL; + } +} + + +/** + * 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 program *prog) +{ + (void) ctx; + ASSERT(prog); + + if (prog->String) + _mesa_free(prog->String); + if (prog->Target == GL_VERTEX_PROGRAM_NV || + prog->Target == GL_VERTEX_STATE_PROGRAM_NV) { + struct vertex_program *vprog = (struct vertex_program *) prog; + if (vprog->Instructions) { + GLuint i; + for (i = 0; i < vprog->Base.NumInstructions; i++) { + if (vprog->Instructions[i].Data) + _mesa_free(vprog->Instructions[i].Data); + } + _mesa_free(vprog->Instructions); + } + if (vprog->Parameters) + _mesa_free_parameter_list(vprog->Parameters); + } + else if (prog->Target == GL_FRAGMENT_PROGRAM_NV || + prog->Target == GL_FRAGMENT_PROGRAM_ARB) { + struct fragment_program *fprog = (struct fragment_program *) prog; + if (fprog->Instructions) { + GLuint i; + for (i = 0; i < fprog->Base.NumInstructions; i++) { + if (fprog->Instructions[i].Data) + _mesa_free(fprog->Instructions[i].Data); + } + _mesa_free(fprog->Instructions); + } + if (fprog->Parameters) + _mesa_free_parameter_list(fprog->Parameters); + } + else if (prog->Target == GL_FRAGMENT_SHADER_ATI) { + struct ati_fragment_shader *atifs = (struct ati_fragment_shader *)prog; + if (atifs->Instructions) + _mesa_free(atifs->Instructions); + } + + _mesa_free(prog); +} + + + +/**********************************************************************/ +/* Program parameter functions */ +/**********************************************************************/ + +struct program_parameter_list * +_mesa_new_parameter_list(void) +{ + return (struct program_parameter_list *) + _mesa_calloc(sizeof(struct program_parameter_list)); +} + + +/** + * Free a parameter list and all its parameters + */ +void +_mesa_free_parameter_list(struct program_parameter_list *paramList) +{ + _mesa_free_parameters(paramList); + _mesa_free(paramList->Parameters); + if (paramList->ParameterValues) + ALIGN_FREE(paramList->ParameterValues); + _mesa_free(paramList); +} + + +/** + * Free all the parameters in the given list, but don't free the + * paramList structure itself. + */ +void +_mesa_free_parameters(struct program_parameter_list *paramList) +{ + GLuint i; + for (i = 0; i < paramList->NumParameters; i++) { + if (paramList->Parameters[i].Name) + _mesa_free((void *) paramList->Parameters[i].Name); + } + paramList->NumParameters = 0; +} + + +/** + * Helper function used by the functions below. + */ +static GLint +add_parameter(struct program_parameter_list *paramList, + const char *name, const GLfloat values[4], + enum parameter_type type) +{ + const GLuint n = paramList->NumParameters; + + if (n == paramList->Size) { + GLfloat (*tmp)[4]; + + paramList->Size *= 2; + if (!paramList->Size) + paramList->Size = 8; + + paramList->Parameters = (struct program_parameter *) + _mesa_realloc(paramList->Parameters, + n * sizeof(struct program_parameter), + paramList->Size * sizeof(struct program_parameter)); + + tmp = paramList->ParameterValues; + paramList->ParameterValues = ALIGN_MALLOC(paramList->Size * 4 * sizeof(GLfloat), 16); + if (tmp) { + _mesa_memcpy(paramList->ParameterValues, tmp, + n * 4 * sizeof(GLfloat)); + ALIGN_FREE(tmp); + } + } + + if (!paramList->Parameters || + !paramList->ParameterValues) { + /* out of memory */ + paramList->NumParameters = 0; + paramList->Size = 0; + return -1; + } + else { + paramList->NumParameters = n + 1; + + _mesa_memset(¶mList->Parameters[n], 0, + sizeof(struct program_parameter)); + + paramList->Parameters[n].Name = name ? _mesa_strdup(name) : NULL; + paramList->Parameters[n].Type = type; + if (values) + COPY_4V(paramList->ParameterValues[n], values); + return (GLint) n; + } +} + + +/** + * Add a new named program parameter (Ex: NV_fragment_program DEFINE statement) + * \return index of the new entry in the parameter list + */ +GLint +_mesa_add_named_parameter(struct program_parameter_list *paramList, + const char *name, const GLfloat values[4]) +{ + return add_parameter(paramList, name, values, NAMED_PARAMETER); +} + + +/** + * Add a new unnamed constant to the parameter list. + * \param paramList - the parameter list + * \param values - four float values + * \return index of the new parameter. + */ +GLint +_mesa_add_named_constant(struct program_parameter_list *paramList, + const char *name, const GLfloat values[4]) +{ + return add_parameter(paramList, name, values, CONSTANT); +} + + +/** + * Add a new unnamed constant to the parameter list. + * \param paramList - the parameter list + * \param values - four float values + * \return index of the new parameter. + */ +GLint +_mesa_add_unnamed_constant(struct program_parameter_list *paramList, + const GLfloat values[4]) +{ + return add_parameter(paramList, NULL, values, CONSTANT); +} + + +/** + * Add a new state reference to the parameter list. + * \param paramList - the parameter list + * \param state - an array of 6 state tokens + * + * \return index of the new parameter. + */ +GLint +_mesa_add_state_reference(struct program_parameter_list *paramList, + GLint *stateTokens) +{ + /* XXX Should we parse <stateString> here and produce the parameter's + * list of STATE_* tokens here, or in the parser? + */ + GLint a, idx; + + idx = add_parameter(paramList, NULL, NULL, STATE); + + for (a=0; a<6; a++) + paramList->Parameters[idx].StateIndexes[a] = (enum state_index) stateTokens[a]; + + return idx; +} + + +/** + * Lookup a parameter value by name in the given parameter list. + * \return pointer to the float[4] values. + */ +GLfloat * +_mesa_lookup_parameter_value(struct program_parameter_list *paramList, + GLsizei nameLen, const char *name) +{ + GLuint i; + + if (!paramList) + return NULL; + + if (nameLen == -1) { + /* name is null-terminated */ + for (i = 0; i < paramList->NumParameters; i++) { + if (paramList->Parameters[i].Name && + _mesa_strcmp(paramList->Parameters[i].Name, name) == 0) + return paramList->ParameterValues[i]; + } + } + else { + /* name is not null-terminated, use nameLen */ + for (i = 0; i < paramList->NumParameters; i++) { + if (paramList->Parameters[i].Name && + _mesa_strncmp(paramList->Parameters[i].Name, name, nameLen) == 0 + && _mesa_strlen(paramList->Parameters[i].Name) == (size_t)nameLen) + return paramList->ParameterValues[i]; + } + } + return NULL; +} + + +/** + * Lookup a parameter index by name in the given parameter list. + * \return index of parameter in the list. + */ +GLint +_mesa_lookup_parameter_index(struct program_parameter_list *paramList, + GLsizei nameLen, const char *name) +{ + GLint i; + + if (!paramList) + return -1; + + if (nameLen == -1) { + /* name is null-terminated */ + for (i = 0; i < (GLint) paramList->NumParameters; i++) { + if (paramList->Parameters[i].Name && + _mesa_strcmp(paramList->Parameters[i].Name, name) == 0) + return i; + } + } + else { + /* name is not null-terminated, use nameLen */ + for (i = 0; i < (GLint) paramList->NumParameters; i++) { + if (paramList->Parameters[i].Name && + _mesa_strncmp(paramList->Parameters[i].Name, name, nameLen) == 0 + && _mesa_strlen(paramList->Parameters[i].Name) == (size_t)nameLen) + return i; + } + } + return -1; +} + + +/** + * Use the list of tokens in the state[] array to find global GL state + * and return it in <value>. Usually, four values are returned in <value> + * but matrix queries may return as many as 16 values. + * This function is used for ARB vertex/fragment programs. + * The program parser will produce the state[] values. + */ +static void +_mesa_fetch_state(GLcontext *ctx, const enum state_index state[], + GLfloat *value) +{ + switch (state[0]) { + case STATE_MATERIAL: + { + /* state[1] is either 0=front or 1=back side */ + const GLuint face = (GLuint) state[1]; + /* state[2] is the material attribute */ + switch (state[2]) { + case STATE_AMBIENT: + if (face == 0) + COPY_4V(value, ctx->Light.Material.Attrib[MAT_ATTRIB_FRONT_AMBIENT]); + else + COPY_4V(value, ctx->Light.Material.Attrib[MAT_ATTRIB_BACK_AMBIENT]); + return; + case STATE_DIFFUSE: + if (face == 0) + COPY_4V(value, ctx->Light.Material.Attrib[MAT_ATTRIB_FRONT_DIFFUSE]); + else + COPY_4V(value, ctx->Light.Material.Attrib[MAT_ATTRIB_BACK_DIFFUSE]); + return; + case STATE_SPECULAR: + if (face == 0) + COPY_4V(value, ctx->Light.Material.Attrib[MAT_ATTRIB_FRONT_SPECULAR]); + else + COPY_4V(value, ctx->Light.Material.Attrib[MAT_ATTRIB_BACK_SPECULAR]); + return; + case STATE_EMISSION: + if (face == 0) + COPY_4V(value, ctx->Light.Material.Attrib[MAT_ATTRIB_FRONT_EMISSION]); + else + COPY_4V(value, ctx->Light.Material.Attrib[MAT_ATTRIB_BACK_EMISSION]); + return; + case STATE_SHININESS: + if (face == 0) + value[0] = ctx->Light.Material.Attrib[MAT_ATTRIB_FRONT_SHININESS][0]; + else + value[0] = ctx->Light.Material.Attrib[MAT_ATTRIB_BACK_SHININESS][0]; + value[1] = 0.0F; + value[2] = 0.0F; + value[3] = 1.0F; + return; + default: + _mesa_problem(ctx, "Invalid material state in fetch_state"); + return; + } + } + case STATE_LIGHT: + { + /* state[1] is the light number */ + const GLuint ln = (GLuint) state[1]; + /* state[2] is the light attribute */ + switch (state[2]) { + case STATE_AMBIENT: + COPY_4V(value, ctx->Light.Light[ln].Ambient); + return; + case STATE_DIFFUSE: + COPY_4V(value, ctx->Light.Light[ln].Diffuse); + return; + case STATE_SPECULAR: + COPY_4V(value, ctx->Light.Light[ln].Specular); + return; + case STATE_POSITION: + COPY_4V(value, ctx->Light.Light[ln].EyePosition); + return; + case STATE_ATTENUATION: + value[0] = ctx->Light.Light[ln].ConstantAttenuation; + value[1] = ctx->Light.Light[ln].LinearAttenuation; + value[2] = ctx->Light.Light[ln].QuadraticAttenuation; + value[3] = ctx->Light.Light[ln].SpotExponent; + return; + case STATE_SPOT_DIRECTION: + COPY_3V(value, ctx->Light.Light[ln].EyeDirection); + value[3] = ctx->Light.Light[ln]._CosCutoff; + return; + case STATE_HALF: + { + GLfloat eye_z[] = {0, 0, 1}; + + /* Compute infinite half angle vector: + * half-vector = light_position + (0, 0, 1) + * and then normalize. w = 0 + * + * light.EyePosition.w should be 0 for infinite lights. + */ + ADD_3V(value, eye_z, ctx->Light.Light[ln].EyePosition); + NORMALIZE_3FV(value); + value[3] = 0; + } + return; + case STATE_POSITION_NORMALIZED: + COPY_4V(value, ctx->Light.Light[ln].EyePosition); + NORMALIZE_3FV( value ); + return; + default: + _mesa_problem(ctx, "Invalid light state in fetch_state"); + return; + } + } + case STATE_LIGHTMODEL_AMBIENT: + COPY_4V(value, ctx->Light.Model.Ambient); + return; + case STATE_LIGHTMODEL_SCENECOLOR: + if (state[1] == 0) { + /* front */ + GLint i; + for (i = 0; i < 3; i++) { + value[i] = ctx->Light.Model.Ambient[i] + * ctx->Light.Material.Attrib[MAT_ATTRIB_FRONT_AMBIENT][i] + + ctx->Light.Material.Attrib[MAT_ATTRIB_FRONT_EMISSION][i]; + } + value[3] = ctx->Light.Material.Attrib[MAT_ATTRIB_FRONT_DIFFUSE][3]; + } + else { + /* back */ + GLint i; + for (i = 0; i < 3; i++) { + value[i] = ctx->Light.Model.Ambient[i] + * ctx->Light.Material.Attrib[MAT_ATTRIB_BACK_AMBIENT][i] + + ctx->Light.Material.Attrib[MAT_ATTRIB_BACK_EMISSION][i]; + } + value[3] = ctx->Light.Material.Attrib[MAT_ATTRIB_BACK_DIFFUSE][3]; + } + return; + case STATE_LIGHTPROD: + { + const GLuint ln = (GLuint) state[1]; + const GLuint face = (GLuint) state[2]; + GLint i; + ASSERT(face == 0 || face == 1); + switch (state[3]) { + case STATE_AMBIENT: + for (i = 0; i < 3; i++) { + value[i] = ctx->Light.Light[ln].Ambient[i] * + ctx->Light.Material.Attrib[MAT_ATTRIB_FRONT_AMBIENT+face][i]; + } + /* [3] = material alpha */ + value[3] = ctx->Light.Material.Attrib[MAT_ATTRIB_FRONT_DIFFUSE+face][3]; + return; + case STATE_DIFFUSE: + for (i = 0; i < 3; i++) { + value[i] = ctx->Light.Light[ln].Diffuse[i] * + ctx->Light.Material.Attrib[MAT_ATTRIB_FRONT_DIFFUSE+face][i]; + } + /* [3] = material alpha */ + value[3] = ctx->Light.Material.Attrib[MAT_ATTRIB_FRONT_DIFFUSE+face][3]; + return; + case STATE_SPECULAR: + for (i = 0; i < 3; i++) { + value[i] = ctx->Light.Light[ln].Specular[i] * + ctx->Light.Material.Attrib[MAT_ATTRIB_FRONT_SPECULAR+face][i]; + } + /* [3] = material alpha */ + value[3] = ctx->Light.Material.Attrib[MAT_ATTRIB_FRONT_DIFFUSE+face][3]; + return; + default: + _mesa_problem(ctx, "Invalid lightprod state in fetch_state"); + return; + } + } + case STATE_TEXGEN: + { + /* state[1] is the texture unit */ + const GLuint unit = (GLuint) state[1]; + /* state[2] is the texgen attribute */ + switch (state[2]) { + case STATE_TEXGEN_EYE_S: + COPY_4V(value, ctx->Texture.Unit[unit].EyePlaneS); + return; + case STATE_TEXGEN_EYE_T: + COPY_4V(value, ctx->Texture.Unit[unit].EyePlaneT); + return; + case STATE_TEXGEN_EYE_R: + COPY_4V(value, ctx->Texture.Unit[unit].EyePlaneR); + return; + case STATE_TEXGEN_EYE_Q: + COPY_4V(value, ctx->Texture.Unit[unit].EyePlaneQ); + return; + case STATE_TEXGEN_OBJECT_S: + COPY_4V(value, ctx->Texture.Unit[unit].ObjectPlaneS); + return; + case STATE_TEXGEN_OBJECT_T: + COPY_4V(value, ctx->Texture.Unit[unit].ObjectPlaneT); + return; + case STATE_TEXGEN_OBJECT_R: + COPY_4V(value, ctx->Texture.Unit[unit].ObjectPlaneR); + return; + case STATE_TEXGEN_OBJECT_Q: + COPY_4V(value, ctx->Texture.Unit[unit].ObjectPlaneQ); + return; + default: + _mesa_problem(ctx, "Invalid texgen state in fetch_state"); + return; + } + } + case STATE_TEXENV_COLOR: + { + /* state[1] is the texture unit */ + const GLuint unit = (GLuint) state[1]; + COPY_4V(value, ctx->Texture.Unit[unit].EnvColor); + } + return; + case STATE_FOG_COLOR: + COPY_4V(value, ctx->Fog.Color); + return; + case STATE_FOG_PARAMS: + value[0] = ctx->Fog.Density; + value[1] = ctx->Fog.Start; + value[2] = ctx->Fog.End; + value[3] = 1.0F / (ctx->Fog.End - ctx->Fog.Start); + return; + case STATE_CLIPPLANE: + { + const GLuint plane = (GLuint) state[1]; + COPY_4V(value, ctx->Transform.EyeUserPlane[plane]); + } + return; + case STATE_POINT_SIZE: + value[0] = ctx->Point.Size; + value[1] = ctx->Point.MinSize; + value[2] = ctx->Point.MaxSize; + value[3] = ctx->Point.Threshold; + return; + case STATE_POINT_ATTENUATION: + value[0] = ctx->Point.Params[0]; + value[1] = ctx->Point.Params[1]; + value[2] = ctx->Point.Params[2]; + value[3] = 1.0F; + return; + case STATE_MATRIX: + { + /* state[1] = modelview, projection, texture, etc. */ + /* state[2] = which texture matrix or program matrix */ + /* state[3] = first column to fetch */ + /* state[4] = last column to fetch */ + /* state[5] = transpose, inverse or invtrans */ + + const GLmatrix *matrix; + const enum state_index mat = state[1]; + const GLuint index = (GLuint) state[2]; + const GLuint first = (GLuint) state[3]; + const GLuint last = (GLuint) state[4]; + const enum state_index modifier = state[5]; + const GLfloat *m; + GLuint row, i; + if (mat == STATE_MODELVIEW) { + matrix = ctx->ModelviewMatrixStack.Top; + } + else if (mat == STATE_PROJECTION) { + matrix = ctx->ProjectionMatrixStack.Top; + } + else if (mat == STATE_MVP) { + matrix = &ctx->_ModelProjectMatrix; + } + else if (mat == STATE_TEXTURE) { + matrix = ctx->TextureMatrixStack[index].Top; + } + else if (mat == STATE_PROGRAM) { + matrix = ctx->ProgramMatrixStack[index].Top; + } + else { + _mesa_problem(ctx, "Bad matrix name in _mesa_fetch_state()"); + return; + } + if (modifier == STATE_MATRIX_INVERSE || + modifier == STATE_MATRIX_INVTRANS) { + /* Be sure inverse is up to date: + */ + _math_matrix_analyse( (GLmatrix*) matrix ); + m = matrix->inv; + } + else { + m = matrix->m; + } + if (modifier == STATE_MATRIX_TRANSPOSE || + modifier == STATE_MATRIX_INVTRANS) { + for (i = 0, row = first; row <= last; row++) { + value[i++] = m[row * 4 + 0]; + value[i++] = m[row * 4 + 1]; + value[i++] = m[row * 4 + 2]; + value[i++] = m[row * 4 + 3]; + } + } + else { + for (i = 0, row = first; row <= last; row++) { + value[i++] = m[row + 0]; + value[i++] = m[row + 4]; + value[i++] = m[row + 8]; + value[i++] = m[row + 12]; + } + } + } + return; + case STATE_DEPTH_RANGE: + value[0] = ctx->Viewport.Near; /* near */ + value[1] = ctx->Viewport.Far; /* far */ + value[2] = ctx->Viewport.Far - ctx->Viewport.Near; /* far - near */ + value[3] = 0; + return; + case STATE_FRAGMENT_PROGRAM: + { + /* state[1] = {STATE_ENV, STATE_LOCAL} */ + /* state[2] = parameter index */ + const int idx = (int) state[2]; + switch (state[1]) { + case STATE_ENV: + COPY_4V(value, ctx->FragmentProgram.Parameters[idx]); + break; + case STATE_LOCAL: + COPY_4V(value, ctx->FragmentProgram.Current->Base.LocalParams[idx]); + break; + default: + _mesa_problem(ctx, "Bad state switch in _mesa_fetch_state()"); + return; + } + } + return; + + case STATE_VERTEX_PROGRAM: + { + /* state[1] = {STATE_ENV, STATE_LOCAL} */ + /* state[2] = parameter index */ + const int idx = (int) state[2]; + switch (state[1]) { + case STATE_ENV: + COPY_4V(value, ctx->VertexProgram.Parameters[idx]); + break; + case STATE_LOCAL: + COPY_4V(value, ctx->VertexProgram.Current->Base.LocalParams[idx]); + break; + default: + _mesa_problem(ctx, "Bad state switch in _mesa_fetch_state()"); + return; + } + } + return; + + case STATE_INTERNAL: + { + switch (state[1]) { + case STATE_NORMAL_SCALE: + ASSIGN_4V(value, ctx->_ModelViewInvScale, 0, 0, 1); + break; + default: + _mesa_problem(ctx, "Bad state switch in _mesa_fetch_state()"); + return; + } + } + return; + + default: + _mesa_problem(ctx, "Invalid state in _mesa_fetch_state"); + return; + } +} + + +/** + * 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 program_parameter_list *paramList) +{ + GLuint i; + + if (!paramList) + return; + + for (i = 0; i < paramList->NumParameters; i++) { + if (paramList->Parameters[i].Type == STATE) { + _mesa_fetch_state(ctx, + paramList->Parameters[i].StateIndexes, + paramList->ParameterValues[i]); + } + } +} + + + +/**********************************************************************/ +/* API functions */ +/**********************************************************************/ + + +/** + * 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 program *prog; + 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) || + (target == GL_VERTEX_PROGRAM_ARB + && ctx->Extensions.ARB_vertex_program)) { + /*** Vertex program binding ***/ + struct vertex_program *curProg = ctx->VertexProgram.Current; + if (curProg->Base.Id == id) { + /* binding same program - no change */ + return; + } + if (curProg->Base.Id != 0) { + /* decrement refcount on previously bound vertex program */ + curProg->Base.RefCount--; + /* and delete if refcount goes below one */ + if (curProg->Base.RefCount <= 0) { + /* the program ID was already removed from the hash table */ + ctx->Driver.DeleteProgram(ctx, &(curProg->Base)); + } + } + } + else if ((target == GL_FRAGMENT_PROGRAM_NV + && ctx->Extensions.NV_fragment_program) || + (target == GL_FRAGMENT_PROGRAM_ARB + && ctx->Extensions.ARB_fragment_program)) { + /*** Fragment program binding ***/ + struct fragment_program *curProg = ctx->FragmentProgram.Current; + if (curProg->Base.Id == id) { + /* binding same program - no change */ + return; + } + if (curProg->Base.Id != 0) { + /* decrement refcount on previously bound fragment program */ + curProg->Base.RefCount--; + /* and delete if refcount goes below one */ + if (curProg->Base.RefCount <= 0) { + /* the program ID was already removed from the hash table */ + ctx->Driver.DeleteProgram(ctx, &(curProg->Base)); + } + } + } + else { + _mesa_error(ctx, GL_INVALID_ENUM, "glBindProgramNV/ARB(target)"); + return; + } + + /* NOTE: binding to a non-existant program is not an error. + * That's supposed to be caught in glBegin. + */ + if (id == 0) { + /* Bind default program */ + prog = NULL; + if (target == GL_VERTEX_PROGRAM_NV || target == GL_VERTEX_PROGRAM_ARB) + prog = ctx->Shared->DefaultVertexProgram; + else + prog = ctx->Shared->DefaultFragmentProgram; + } + else { + /* Bind user program */ + prog = (struct program *) _mesa_HashLookup(ctx->Shared->Programs, id); + if (!prog || prog == &_mesa_DummyProgram) { + /* allocate a new program now */ + prog = ctx->Driver.NewProgram(ctx, target, id); + if (!prog) { + _mesa_error(ctx, GL_OUT_OF_MEMORY, "glBindProgramNV/ARB"); + return; + } + _mesa_HashInsert(ctx->Shared->Programs, id, prog); + } + else if (prog->Target != target) { + _mesa_error(ctx, GL_INVALID_OPERATION, + "glBindProgramNV/ARB(target mismatch)"); + return; + } + } + + /* bind now */ + if (target == GL_VERTEX_PROGRAM_NV || target == GL_VERTEX_PROGRAM_ARB) { + ctx->VertexProgram.Current = (struct vertex_program *) prog; + } + else if (target == GL_FRAGMENT_PROGRAM_NV || target == GL_FRAGMENT_PROGRAM_ARB) { + ctx->FragmentProgram.Current = (struct fragment_program *) prog; + } + + /* Never null pointers */ + ASSERT(ctx->VertexProgram.Current); + ASSERT(ctx->FragmentProgram.Current); + + if (prog) + prog->RefCount++; + + if (ctx->Driver.BindProgram) + ctx->Driver.BindProgram(ctx, target, prog); +} + + +/** + * 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 program *prog = (struct program *) + _mesa_HashLookup(ctx->Shared->Programs, ids[i]); + if (prog == &_mesa_DummyProgram) { + _mesa_HashRemove(ctx->Shared->Programs, ids[i]); + } + else if (prog) { + /* Unbind program if necessary */ + if (prog->Target == GL_VERTEX_PROGRAM_NV || + prog->Target == 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); + } + } + else if (prog->Target == GL_FRAGMENT_PROGRAM_NV || + prog->Target == 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); + } + } + else { + _mesa_problem(ctx, "bad target in glDeleteProgramsNV"); + return; + } + /* The ID is immediately available for re-use now */ + _mesa_HashRemove(ctx->Shared->Programs, ids[i]); + prog->RefCount--; + if (prog->RefCount <= 0) { + ctx->Driver.DeleteProgram(ctx, prog); + } + } + } + } +} + + +/** + * 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; + } +} + + +/** + * 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_IsProgram(GLuint id) +{ + GET_CURRENT_CONTEXT(ctx); + ASSERT_OUTSIDE_BEGIN_END_WITH_RETVAL(ctx, GL_FALSE); + + if (id == 0) + return GL_FALSE; + + if (_mesa_HashLookup(ctx->Shared->Programs, id)) + return GL_TRUE; + else + return GL_FALSE; +} + + + +/**********************************************************************/ +/* GL_MESA_program_debug extension */ +/**********************************************************************/ + + +/* XXX temporary */ +GLAPI void GLAPIENTRY +glProgramCallbackMESA(GLenum target, GLprogramcallbackMESA callback, + GLvoid *data) +{ + _mesa_ProgramCallbackMESA(target, callback, data); +} + + +void +_mesa_ProgramCallbackMESA(GLenum target, GLprogramcallbackMESA callback, + GLvoid *data) +{ + GET_CURRENT_CONTEXT(ctx); + + switch (target) { + case GL_FRAGMENT_PROGRAM_ARB: + if (!ctx->Extensions.ARB_fragment_program) { + _mesa_error(ctx, GL_INVALID_ENUM, "glProgramCallbackMESA(target)"); + return; + } + ctx->FragmentProgram.Callback = callback; + ctx->FragmentProgram.CallbackData = data; + break; + case GL_FRAGMENT_PROGRAM_NV: + if (!ctx->Extensions.NV_fragment_program) { + _mesa_error(ctx, GL_INVALID_ENUM, "glProgramCallbackMESA(target)"); + return; + } + ctx->FragmentProgram.Callback = callback; + ctx->FragmentProgram.CallbackData = data; + break; + case GL_VERTEX_PROGRAM_ARB: /* == GL_VERTEX_PROGRAM_NV */ + if (!ctx->Extensions.ARB_vertex_program && + !ctx->Extensions.NV_vertex_program) { + _mesa_error(ctx, GL_INVALID_ENUM, "glProgramCallbackMESA(target)"); + return; + } + ctx->VertexProgram.Callback = callback; + ctx->VertexProgram.CallbackData = data; + break; + default: + _mesa_error(ctx, GL_INVALID_ENUM, "glProgramCallbackMESA(target)"); + return; + } +} + + +/* XXX temporary */ +GLAPI void GLAPIENTRY +glGetProgramRegisterfvMESA(GLenum target, + GLsizei len, const GLubyte *registerName, + GLfloat *v) +{ + _mesa_GetProgramRegisterfvMESA(target, len, registerName, v); +} + + +void +_mesa_GetProgramRegisterfvMESA(GLenum target, + GLsizei len, const GLubyte *registerName, + GLfloat *v) +{ + char reg[1000]; + GET_CURRENT_CONTEXT(ctx); + + /* We _should_ be inside glBegin/glEnd */ +#if 0 + if (ctx->Driver.CurrentExecPrimitive == PRIM_OUTSIDE_BEGIN_END) { + _mesa_error(ctx, GL_INVALID_OPERATION, "glGetProgramRegisterfvMESA"); + return; + } +#endif + + /* make null-terminated copy of registerName */ + len = MIN2((unsigned int) len, sizeof(reg) - 1); + _mesa_memcpy(reg, registerName, len); + reg[len] = 0; + + switch (target) { + case GL_VERTEX_PROGRAM_NV: + if (!ctx->Extensions.ARB_vertex_program && + !ctx->Extensions.NV_vertex_program) { + _mesa_error(ctx, GL_INVALID_ENUM, + "glGetProgramRegisterfvMESA(target)"); + return; + } + if (!ctx->VertexProgram._Enabled) { + _mesa_error(ctx, GL_INVALID_OPERATION, + "glGetProgramRegisterfvMESA"); + return; + } + /* GL_NV_vertex_program */ + if (reg[0] == 'R') { + /* Temp register */ + GLint i = _mesa_atoi(reg + 1); + if (i >= (GLint)ctx->Const.MaxVertexProgramTemps) { + _mesa_error(ctx, GL_INVALID_VALUE, + "glGetProgramRegisterfvMESA(registerName)"); + return; + } + COPY_4V(v, ctx->VertexProgram.Temporaries[i]); + } + else if (reg[0] == 'v' && reg[1] == '[') { + /* Vertex Input attribute */ + GLuint i; + for (i = 0; i < ctx->Const.MaxVertexProgramAttribs; i++) { + const char *name = _mesa_nv_vertex_input_register_name(i); + char number[10]; + sprintf(number, "%d", i); + if (_mesa_strncmp(reg + 2, name, 4) == 0 || + _mesa_strncmp(reg + 2, number, _mesa_strlen(number)) == 0) { + COPY_4V(v, ctx->VertexProgram.Inputs[i]); + return; + } + } + _mesa_error(ctx, GL_INVALID_VALUE, + "glGetProgramRegisterfvMESA(registerName)"); + return; + } + else if (reg[0] == 'o' && reg[1] == '[') { + /* Vertex output attribute */ + } + /* GL_ARB_vertex_program */ + else if (_mesa_strncmp(reg, "vertex.", 7) == 0) { + + } + else { + _mesa_error(ctx, GL_INVALID_VALUE, + "glGetProgramRegisterfvMESA(registerName)"); + return; + } + break; + case GL_FRAGMENT_PROGRAM_ARB: + if (!ctx->Extensions.ARB_fragment_program) { + _mesa_error(ctx, GL_INVALID_ENUM, + "glGetProgramRegisterfvMESA(target)"); + return; + } + if (!ctx->FragmentProgram._Enabled) { + _mesa_error(ctx, GL_INVALID_OPERATION, + "glGetProgramRegisterfvMESA"); + return; + } + /* XXX to do */ + break; + case GL_FRAGMENT_PROGRAM_NV: + if (!ctx->Extensions.NV_fragment_program) { + _mesa_error(ctx, GL_INVALID_ENUM, + "glGetProgramRegisterfvMESA(target)"); + return; + } + if (!ctx->FragmentProgram._Enabled) { + _mesa_error(ctx, GL_INVALID_OPERATION, + "glGetProgramRegisterfvMESA"); + return; + } + if (reg[0] == 'R') { + /* Temp register */ + GLint i = _mesa_atoi(reg + 1); + if (i >= (GLint)ctx->Const.MaxFragmentProgramTemps) { + _mesa_error(ctx, GL_INVALID_VALUE, + "glGetProgramRegisterfvMESA(registerName)"); + return; + } + COPY_4V(v, ctx->FragmentProgram.Machine.Temporaries[i]); + } + else if (reg[0] == 'f' && reg[1] == '[') { + /* Fragment input attribute */ + GLuint i; + for (i = 0; i < ctx->Const.MaxFragmentProgramAttribs; i++) { + const char *name = _mesa_nv_fragment_input_register_name(i); + if (_mesa_strncmp(reg + 2, name, 4) == 0) { + COPY_4V(v, ctx->FragmentProgram.Machine.Inputs[i]); + return; + } + } + _mesa_error(ctx, GL_INVALID_VALUE, + "glGetProgramRegisterfvMESA(registerName)"); + return; + } + else if (_mesa_strcmp(reg, "o[COLR]") == 0) { + /* Fragment output color */ + COPY_4V(v, ctx->FragmentProgram.Machine.Outputs[FRAG_OUTPUT_COLR]); + } + else if (_mesa_strcmp(reg, "o[COLH]") == 0) { + /* Fragment output color */ + COPY_4V(v, ctx->FragmentProgram.Machine.Outputs[FRAG_OUTPUT_COLH]); + } + else if (_mesa_strcmp(reg, "o[DEPR]") == 0) { + /* Fragment output depth */ + COPY_4V(v, ctx->FragmentProgram.Machine.Outputs[FRAG_OUTPUT_DEPR]); + } + else { + /* try user-defined identifiers */ + const GLfloat *value = _mesa_lookup_parameter_value( + ctx->FragmentProgram.Current->Parameters, -1, reg); + if (value) { + COPY_4V(v, value); + } + else { + _mesa_error(ctx, GL_INVALID_VALUE, + "glGetProgramRegisterfvMESA(registerName)"); + return; + } + } + break; + default: + _mesa_error(ctx, GL_INVALID_ENUM, + "glGetProgramRegisterfvMESA(target)"); + return; + } + +} diff --git a/nx-X11/extras/Mesa/src/mesa/shader/program.h b/nx-X11/extras/Mesa/src/mesa/shader/program.h new file mode 100644 index 000000000..87590ceea --- /dev/null +++ b/nx-X11/extras/Mesa/src/mesa/shader/program.h @@ -0,0 +1,298 @@ +/* + * Mesa 3-D graphics library + * Version: 6.3 + * + * Copyright (C) 1999-2005 Brian Paul All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN + * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +/** + * \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 "mtypes.h" + + +/* for GL_ARB_v_p and GL_ARB_f_p SWZ instruction */ +#define SWIZZLE_X 0 +#define SWIZZLE_Y 1 +#define SWIZZLE_Z 2 +#define SWIZZLE_W 3 +#define SWIZZLE_ZERO 4 /* keep these values together: KW */ +#define SWIZZLE_ONE 5 /* keep these values together: KW */ + +#define MAKE_SWIZZLE4(a,b,c,d) (((a)<<0) | ((b)<<3) | ((c)<<6) | ((d)<<9)) +#define MAKE_SWIZZLE(x) MAKE_SWIZZLE4((x)[0], (x)[1], (x)[2], (x)[3]) +#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 WRITEMASK_X 0x1 +#define WRITEMASK_Y 0x2 +#define WRITEMASK_XY 0x3 +#define WRITEMASK_Z 0x4 +#define WRITEMASK_XZ 0x5 +#define WRITEMASK_YZ 0x6 +#define WRITEMASK_XYZ 0x7 +#define WRITEMASK_W 0x8 +#define WRITEMASK_XW 0x9 +#define WRITEMASK_YW 0xa +#define WRITEMASK_XYW 0xb +#define WRITEMASK_ZW 0xc +#define WRITEMASK_XZW 0xd +#define WRITEMASK_YZW 0xe +#define WRITEMASK_XYZW 0xf + + +extern struct program _mesa_DummyProgram; + + +/* + * Internal functions + */ + +extern void +_mesa_init_program(GLcontext *ctx); + +extern void +_mesa_free_program_data(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 program * +_mesa_init_vertex_program(GLcontext *ctx, + struct vertex_program *prog, + GLenum target, GLuint id); + +extern struct program * +_mesa_init_fragment_program(GLcontext *ctx, + struct fragment_program *prog, + GLenum target, GLuint id); + +extern struct program * +_mesa_init_ati_fragment_shader(GLcontext *ctx, + struct ati_fragment_shader *prog, + GLenum target, GLuint id ); + +extern struct program * +_mesa_new_program(GLcontext *ctx, GLenum target, GLuint id); + +extern void +_mesa_delete_program(GLcontext *ctx, struct program *prog); + + + +/* + * Used for describing GL state referenced from inside ARB vertex and + * fragment programs. + * A string such as "state.light[0].ambient" gets translated into a + * sequence of tokens such as [ STATE_LIGHT, 0, STATE_AMBIENT ]. + */ +enum state_index { + STATE_MATERIAL, + + STATE_LIGHT, + STATE_LIGHTMODEL_AMBIENT, + STATE_LIGHTMODEL_SCENECOLOR, + STATE_LIGHTPROD, + + STATE_TEXGEN, + + STATE_FOG_COLOR, + STATE_FOG_PARAMS, + + STATE_CLIPPLANE, + + STATE_POINT_SIZE, + STATE_POINT_ATTENUATION, + + STATE_MATRIX, + STATE_MODELVIEW, + STATE_PROJECTION, + STATE_MVP, + STATE_TEXTURE, + STATE_PROGRAM, + STATE_MATRIX_INVERSE, + STATE_MATRIX_TRANSPOSE, + STATE_MATRIX_INVTRANS, + + STATE_AMBIENT, + STATE_DIFFUSE, + STATE_SPECULAR, + STATE_EMISSION, + STATE_SHININESS, + STATE_HALF, + + STATE_POSITION, + STATE_ATTENUATION, + STATE_SPOT_DIRECTION, + + STATE_TEXGEN_EYE_S, + STATE_TEXGEN_EYE_T, + STATE_TEXGEN_EYE_R, + STATE_TEXGEN_EYE_Q, + STATE_TEXGEN_OBJECT_S, + STATE_TEXGEN_OBJECT_T, + STATE_TEXGEN_OBJECT_R, + STATE_TEXGEN_OBJECT_Q, + + STATE_TEXENV_COLOR, + + STATE_DEPTH_RANGE, + + STATE_VERTEX_PROGRAM, + STATE_FRAGMENT_PROGRAM, + + STATE_ENV, + STATE_LOCAL, + + STATE_INTERNAL, /* Mesa additions */ + STATE_NORMAL_SCALE, + STATE_POSITION_NORMALIZED +}; + + + +/* + * Named program parameters + * Used for NV_fragment_program "DEFINE"d constants and "DECLARE"d parameters, + * and ARB_fragment_program global state references. For the later, Name + * might be "state.light[0].diffuse", for example. + */ + +enum parameter_type +{ + NAMED_PARAMETER, + CONSTANT, + STATE +}; + + +struct program_parameter +{ + const char *Name; /* Null-terminated */ + enum parameter_type Type; + enum state_index StateIndexes[6]; /* Global state reference */ +}; + + +struct program_parameter_list +{ + GLuint Size; + GLuint NumParameters; + struct program_parameter *Parameters; + GLfloat (*ParameterValues)[4]; +}; + + +/* + * Program parameter functions + */ + +extern struct program_parameter_list * +_mesa_new_parameter_list(void); + +extern void +_mesa_free_parameter_list(struct program_parameter_list *paramList); + +extern void +_mesa_free_parameters(struct program_parameter_list *paramList); + +extern GLint +_mesa_add_named_parameter(struct program_parameter_list *paramList, + const char *name, const GLfloat values[4]); + +extern GLint +_mesa_add_named_constant(struct program_parameter_list *paramList, + const char *name, const GLfloat values[4]); + +extern GLint +_mesa_add_unnamed_constant(struct program_parameter_list *paramList, + const GLfloat values[4]); + +extern GLint +_mesa_add_state_reference(struct program_parameter_list *paramList, + GLint *stateTokens); + +extern GLfloat * +_mesa_lookup_parameter_value(struct program_parameter_list *paramList, + GLsizei nameLen, const char *name); + +extern GLint +_mesa_lookup_parameter_index(struct program_parameter_list *paramList, + GLsizei nameLen, const char *name); + +extern void +_mesa_load_state_parameters(GLcontext *ctx, + struct program_parameter_list *paramList); + + +/* + * API functions + */ + +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 GLboolean GLAPIENTRY +_mesa_IsProgram(GLuint id); + + + +/* + * GL_MESA_program_debug + */ + +extern void +_mesa_ProgramCallbackMESA(GLenum target, GLprogramcallbackMESA callback, + GLvoid *data); + +extern void +_mesa_GetProgramRegisterfvMESA(GLenum target, GLsizei len, + const GLubyte *registerName, GLfloat *v); + + +#endif /* PROGRAM_H */ diff --git a/nx-X11/extras/Mesa/src/mesa/shader/shaderobjects.c b/nx-X11/extras/Mesa/src/mesa/shader/shaderobjects.c new file mode 100644 index 000000000..ac8ff1af4 --- /dev/null +++ b/nx-X11/extras/Mesa/src/mesa/shader/shaderobjects.c @@ -0,0 +1,1182 @@ +/* + * Mesa 3-D graphics library + * Version: 6.3 + * + * Copyright (C) 2004-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 shaderobjects.c + * ARB_shader_objects state management functions + * \author Michal Krol + */ + + +#include "glheader.h" +#include "shaderobjects.h" +#include "shaderobjects_3dlabs.h" +#include "context.h" +#include "macros.h" +#include "hash.h" + + +void GLAPIENTRY +_mesa_DeleteObjectARB (GLhandleARB obj) +{ + GET_CURRENT_CONTEXT(ctx); + struct gl2_unknown_intf **unk; + struct gl2_generic_intf **gen; + + _glthread_LOCK_MUTEX (ctx->Shared->Mutex); + unk = (struct gl2_unknown_intf **) _mesa_HashLookup (ctx->Shared->GL2Objects, obj); + _glthread_UNLOCK_MUTEX (ctx->Shared->Mutex); + + if (unk == NULL) + { + _mesa_error (ctx, GL_INVALID_VALUE, "glDeleteObjectARB"); + return; + } + + gen = (struct gl2_generic_intf **) (**unk).QueryInterface (unk, UIID_GENERIC); + if (gen == NULL) + { + _mesa_error (ctx, GL_INVALID_VALUE, "glDeleteObjectARB"); + return; + } + + (**gen).Delete (gen); + (**gen)._unknown.Release ((struct gl2_unknown_intf **) gen); +} + +GLhandleARB GLAPIENTRY +_mesa_GetHandleARB (GLenum pname) +{ + GET_CURRENT_CONTEXT(ctx); + + switch (pname) + { + case GL_PROGRAM_OBJECT_ARB: + if (ctx->ShaderObjects.current_program != NULL) + return (**ctx->ShaderObjects.current_program)._container._generic.GetName ( + (struct gl2_generic_intf **) ctx->ShaderObjects.current_program); + break; + } + + return 0; +} + +void GLAPIENTRY +_mesa_DetachObjectARB (GLhandleARB containerObj, GLhandleARB attachedObj) +{ + GET_CURRENT_CONTEXT(ctx); + struct gl2_unknown_intf **unkc, **unka; + struct gl2_container_intf **con; + struct gl2_generic_intf **att; + + _glthread_LOCK_MUTEX (ctx->Shared->Mutex); + unkc = (struct gl2_unknown_intf **) _mesa_HashLookup (ctx->Shared->GL2Objects, containerObj); + unka = (struct gl2_unknown_intf **) _mesa_HashLookup (ctx->Shared->GL2Objects, attachedObj); + _glthread_UNLOCK_MUTEX (ctx->Shared->Mutex); + + if (unkc == NULL || unka == NULL) + { + _mesa_error (ctx, GL_INVALID_VALUE, "glDetachObjectARB"); + return; + } + + con = (struct gl2_container_intf **) (**unkc).QueryInterface (unkc, UIID_CONTAINER); + if (con == NULL) + { + _mesa_error (ctx, GL_INVALID_OPERATION, "glDetachObjectARB"); + return; + } + + att = (struct gl2_generic_intf **) (**unka).QueryInterface (unka, UIID_GENERIC); + if (att == NULL) + { + (**con)._generic._unknown.Release ((struct gl2_unknown_intf **) con); + _mesa_error (ctx, GL_INVALID_VALUE, "glDetachObjectARB"); + return; + } + + if ((**con).Detach (con, att) == GL_FALSE) + { + (**con)._generic._unknown.Release ((struct gl2_unknown_intf **) con); + (**att)._unknown.Release ((struct gl2_unknown_intf **) att); + return; + } + + (**con)._generic._unknown.Release ((struct gl2_unknown_intf **) con); + (**att)._unknown.Release ((struct gl2_unknown_intf **) att); +} + +GLhandleARB GLAPIENTRY +_mesa_CreateShaderObjectARB (GLenum shaderType) +{ + return _mesa_3dlabs_create_shader_object (shaderType); +} + +void GLAPIENTRY +_mesa_ShaderSourceARB (GLhandleARB shaderObj, GLsizei count, const GLcharARB **string, + const GLint *length) +{ + GET_CURRENT_CONTEXT(ctx); + struct gl2_unknown_intf **unk; + struct gl2_shader_intf **sha; + GLint *offsets; + GLsizei i; + GLcharARB *source; + + _glthread_LOCK_MUTEX (ctx->Shared->Mutex); + unk = (struct gl2_unknown_intf **) _mesa_HashLookup (ctx->Shared->GL2Objects, shaderObj); + _glthread_UNLOCK_MUTEX (ctx->Shared->Mutex); + + if (unk == NULL) + { + _mesa_error (ctx, GL_INVALID_VALUE, "glShaderSourceARB"); + return; + } + + sha = (struct gl2_shader_intf **) (**unk).QueryInterface (unk, UIID_SHADER); + if (sha == NULL) + { + _mesa_error (ctx, GL_INVALID_OPERATION, "glShaderSourceARB"); + return; + } + + /* this array holds offsets of where the appropriate string ends, thus the last + element will be set to the total length of the source code */ + offsets = (GLint *) _mesa_malloc (count * sizeof (GLint)); + if (offsets == NULL) + { + (**sha)._generic._unknown.Release ((struct gl2_unknown_intf **) sha); + _mesa_error (ctx, GL_OUT_OF_MEMORY, "glShaderSourceARB"); + return; + } + + for (i = 0; i < count; i++) + { + if (length == NULL || length[i] < 0) + offsets[i] = _mesa_strlen (string[i]); + else + offsets[i] = length[i]; + /* accumulate string lengths */ + if (i > 0) + offsets[i] += offsets[i - 1]; + } + + source = (GLcharARB *) _mesa_malloc ((offsets[count - 1] + 1) * sizeof (GLcharARB)); + if (source == NULL) + { + _mesa_free ((void *) offsets); + (**sha)._generic._unknown.Release ((struct gl2_unknown_intf **) sha); + _mesa_error (ctx, GL_OUT_OF_MEMORY, "glShaderSourceARB"); + return; + } + + for (i = 0; i < count; i++) + { + GLint start = (i > 0) ? offsets[i - 1] : 0; + _mesa_memcpy (source + start, string[i], (offsets[i] - start) * sizeof (GLcharARB)); + } + source[offsets[count - 1]] = '\0'; + + (**sha).SetSource (sha, source, offsets, count); + (**sha)._generic._unknown.Release ((struct gl2_unknown_intf **) sha); +} + +void GLAPIENTRY +_mesa_CompileShaderARB (GLhandleARB shaderObj) +{ + GET_CURRENT_CONTEXT(ctx); + struct gl2_unknown_intf **unk; + struct gl2_shader_intf **sha; + + _glthread_LOCK_MUTEX (ctx->Shared->Mutex); + unk = (struct gl2_unknown_intf **) _mesa_HashLookup (ctx->Shared->GL2Objects, shaderObj); + _glthread_UNLOCK_MUTEX (ctx->Shared->Mutex); + + if (unk == NULL) + { + _mesa_error (ctx, GL_INVALID_VALUE, "glCompileShaderARB"); + return; + } + + sha = (struct gl2_shader_intf **) (**unk).QueryInterface (unk, UIID_SHADER); + if (sha == NULL) + { + _mesa_error (ctx, GL_INVALID_OPERATION, "glCompileShaderARB"); + return; + } + + (**sha).Compile (sha); + (**sha)._generic._unknown.Release ((struct gl2_unknown_intf **) sha); +} + +GLhandleARB GLAPIENTRY +_mesa_CreateProgramObjectARB (void) +{ + return _mesa_3dlabs_create_program_object (); +} + +void GLAPIENTRY +_mesa_AttachObjectARB (GLhandleARB containerObj, GLhandleARB obj) +{ + GET_CURRENT_CONTEXT(ctx); + struct gl2_unknown_intf **unkc, **unka; + struct gl2_container_intf **con; + struct gl2_generic_intf **att; + + _glthread_LOCK_MUTEX (ctx->Shared->Mutex); + unkc = (struct gl2_unknown_intf **) _mesa_HashLookup (ctx->Shared->GL2Objects, containerObj); + unka = (struct gl2_unknown_intf **) _mesa_HashLookup (ctx->Shared->GL2Objects, obj); + _glthread_UNLOCK_MUTEX (ctx->Shared->Mutex); + + if (unkc == NULL || unka == NULL) + { + _mesa_error (ctx, GL_INVALID_VALUE, "glAttachObjectARB"); + return; + } + + con = (struct gl2_container_intf **) (**unkc).QueryInterface (unkc, UIID_CONTAINER); + if (con == NULL) + { + _mesa_error (ctx, GL_INVALID_VALUE, "glAttachObjectARB"); + return; + } + + att = (struct gl2_generic_intf **) (**unka).QueryInterface (unka, UIID_GENERIC); + if (att == NULL) + { + (**con)._generic._unknown.Release ((struct gl2_unknown_intf **) con); + _mesa_error (ctx, GL_INVALID_VALUE, "glAttachObjectARB"); + return; + } + + if (!(**con).Attach (con, att)) + { + (**con)._generic._unknown.Release ((struct gl2_unknown_intf **) con); + (**att)._unknown.Release ((struct gl2_unknown_intf **) att); + return; + } + + (**con)._generic._unknown.Release ((struct gl2_unknown_intf **) con); + (**att)._unknown.Release ((struct gl2_unknown_intf **) att); +} + +void GLAPIENTRY +_mesa_LinkProgramARB (GLhandleARB programObj) +{ + GET_CURRENT_CONTEXT(ctx); + struct gl2_unknown_intf **unk; + struct gl2_program_intf **pro; + + _glthread_LOCK_MUTEX (ctx->Shared->Mutex); + unk = (struct gl2_unknown_intf **) _mesa_HashLookup (ctx->Shared->GL2Objects, programObj); + _glthread_UNLOCK_MUTEX (ctx->Shared->Mutex); + + if (unk == NULL) + { + _mesa_error (ctx, GL_INVALID_VALUE, "glLinkProgramARB"); + return; + } + + pro = (struct gl2_program_intf **) (**unk).QueryInterface (unk, UIID_PROGRAM); + if (pro == NULL) + { + _mesa_error (ctx, GL_INVALID_OPERATION, "glLinkProgramARB"); + return; + } + + if (pro == ctx->ShaderObjects.current_program) + { + /* TODO re-install executable program */ + } + + (**pro).Link (pro); + (**pro)._container._generic._unknown.Release ((struct gl2_unknown_intf **) pro); +} + +void GLAPIENTRY +_mesa_UseProgramObjectARB (GLhandleARB programObj) +{ + GET_CURRENT_CONTEXT(ctx); + struct gl2_program_intf **pro; + + if (programObj == 0) + { + pro = NULL; + } + else + { + struct gl2_unknown_intf **unk; + + _glthread_LOCK_MUTEX (ctx->Shared->Mutex); + unk = (struct gl2_unknown_intf **) _mesa_HashLookup (ctx->Shared->GL2Objects, programObj); + _glthread_UNLOCK_MUTEX (ctx->Shared->Mutex); + + if (unk == NULL) + { + _mesa_error (ctx, GL_INVALID_VALUE, "glUseProgramObjectARB"); + return; + } + + pro = (struct gl2_program_intf **) (**unk).QueryInterface (unk, UIID_PROGRAM); + if (pro == NULL) + { + _mesa_error (ctx, GL_INVALID_OPERATION, "glUseProgramObjectARB"); + return; + } + + if ((**pro).GetLinkStatus (pro) == GL_FALSE) + { + (**pro)._container._generic._unknown.Release ((struct gl2_unknown_intf **) pro); + _mesa_error (ctx, GL_INVALID_OPERATION, "glUseProgramObjectARB"); + return; + } + } + + if (ctx->ShaderObjects.current_program != NULL) + { + (**ctx->ShaderObjects.current_program)._container._generic._unknown.Release ( + (struct gl2_unknown_intf **) ctx->ShaderObjects.current_program); + } + + ctx->ShaderObjects.current_program = pro; +} + +void GLAPIENTRY +_mesa_ValidateProgramARB (GLhandleARB programObj) +{ + GET_CURRENT_CONTEXT(ctx); + struct gl2_unknown_intf **unk; + struct gl2_program_intf **pro; + + _glthread_LOCK_MUTEX (ctx->Shared->Mutex); + unk = (struct gl2_unknown_intf **) _mesa_HashLookup (ctx->Shared->GL2Objects, programObj); + _glthread_UNLOCK_MUTEX (ctx->Shared->Mutex); + + if (unk == NULL) + { + _mesa_error (ctx, GL_INVALID_VALUE, "glValidateProgramARB"); + return; + } + + pro = (struct gl2_program_intf **) (**unk).QueryInterface (unk, UIID_PROGRAM); + if (pro == NULL) + { + _mesa_error (ctx, GL_INVALID_OPERATION, "glValidateProgramARB"); + return; + } + + (**pro).Validate (pro); + (**pro)._container._generic._unknown.Release ((struct gl2_unknown_intf **) pro); +} + +/* +Errors TODO + + The error INVALID_OPERATION is generated by the Uniform*ARB if the + number of values loaded results in exceeding the declared extent of a + uniform. + + The error INVALID_OPERATION is generated by the Uniform*ARB commands if + the size does not match the size of the uniform declared in the shader. + + The error INVALID_OPERATION is generated by the Uniform*ARB commands if + the type does not match the type of the uniform declared in the shader, + if the uniform is not of type Boolean. + + The error INVALID_OPERATION is generated by the Uniform*ARB commands if + <location> does not exist for the program object currently in use. + + The error INVALID_OPERATION is generated if a uniform command other than + Uniform1i{v}ARB is used to load a sampler value. + + +*/ + +void GLAPIENTRY +_mesa_Uniform1fARB (GLint location, GLfloat v0) +{ + GET_CURRENT_CONTEXT(ctx); + + if (ctx->ShaderObjects.current_program == NULL) + { + _mesa_error (ctx, GL_INVALID_OPERATION, "glUniform1fARB"); + return; + } +} + +void GLAPIENTRY +_mesa_Uniform2fARB (GLint location, GLfloat v0, GLfloat v1) +{ + GET_CURRENT_CONTEXT(ctx); + + if (ctx->ShaderObjects.current_program == NULL) + { + _mesa_error (ctx, GL_INVALID_OPERATION, "glUniform2fARB"); + return; + } +} + +void GLAPIENTRY +_mesa_Uniform3fARB (GLint location, GLfloat v0, GLfloat v1, GLfloat v2) +{ + GET_CURRENT_CONTEXT(ctx); + + if (ctx->ShaderObjects.current_program == NULL) + { + _mesa_error (ctx, GL_INVALID_OPERATION, "glUniform3fARB"); + return; + } +} + +void GLAPIENTRY +_mesa_Uniform4fARB (GLint location, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3) +{ + GET_CURRENT_CONTEXT(ctx); + + if (ctx->ShaderObjects.current_program == NULL) + { + _mesa_error (ctx, GL_INVALID_OPERATION, "glUniform4fARB"); + return; + } +} + +void GLAPIENTRY +_mesa_Uniform1iARB (GLint location, GLint v0) +{ + GET_CURRENT_CONTEXT(ctx); + + if (ctx->ShaderObjects.current_program == NULL) + { + _mesa_error (ctx, GL_INVALID_OPERATION, "glUniform1iARB"); + return; + } +} + +void GLAPIENTRY +_mesa_Uniform2iARB (GLint location, GLint v0, GLint v1) +{ + GET_CURRENT_CONTEXT(ctx); + + if (ctx->ShaderObjects.current_program == NULL) + { + _mesa_error (ctx, GL_INVALID_OPERATION, "glUniform2iARB"); + return; + } +} + +void GLAPIENTRY +_mesa_Uniform3iARB (GLint location, GLint v0, GLint v1, GLint v2) +{ + GET_CURRENT_CONTEXT(ctx); + + if (ctx->ShaderObjects.current_program == NULL) + { + _mesa_error (ctx, GL_INVALID_OPERATION, "glUniform3iARB"); + return; + } +} + +void GLAPIENTRY +_mesa_Uniform4iARB (GLint location, GLint v0, GLint v1, GLint v2, GLint v3) +{ + GET_CURRENT_CONTEXT(ctx); + + if (ctx->ShaderObjects.current_program == NULL) + { + _mesa_error (ctx, GL_INVALID_OPERATION, "glUniform4iARB"); + return; + } +} + +void GLAPIENTRY +_mesa_Uniform1fvARB (GLint location, GLsizei count, const GLfloat *value) +{ + GET_CURRENT_CONTEXT(ctx); + + if (ctx->ShaderObjects.current_program == NULL) + { + _mesa_error (ctx, GL_INVALID_OPERATION, "glUniform1fvARB"); + return; + } +} + +void GLAPIENTRY +_mesa_Uniform2fvARB (GLint location, GLsizei count, const GLfloat *value) +{ + GET_CURRENT_CONTEXT(ctx); + + if (ctx->ShaderObjects.current_program == NULL) + { + _mesa_error (ctx, GL_INVALID_OPERATION, "glUniform2fvARB"); + return; + } +} + +void GLAPIENTRY +_mesa_Uniform3fvARB (GLint location, GLsizei count, const GLfloat *value) +{ + GET_CURRENT_CONTEXT(ctx); + + if (ctx->ShaderObjects.current_program == NULL) + { + _mesa_error (ctx, GL_INVALID_OPERATION, "glUniform3fvARB"); + return; + } +} + +void GLAPIENTRY +_mesa_Uniform4fvARB (GLint location, GLsizei count, const GLfloat *value) +{ + GET_CURRENT_CONTEXT(ctx); + + if (ctx->ShaderObjects.current_program == NULL) + { + _mesa_error (ctx, GL_INVALID_OPERATION, "glUniform4fvARB"); + return; + } +} + +void GLAPIENTRY +_mesa_Uniform1ivARB (GLint location, GLsizei count, const GLint *value) +{ + GET_CURRENT_CONTEXT(ctx); + + if (ctx->ShaderObjects.current_program == NULL) + { + _mesa_error (ctx, GL_INVALID_OPERATION, "glUniform1ivARB"); + return; + } +} + +void GLAPIENTRY +_mesa_Uniform2ivARB (GLint location, GLsizei count, const GLint *value) +{ + GET_CURRENT_CONTEXT(ctx); + + if (ctx->ShaderObjects.current_program == NULL) + { + _mesa_error (ctx, GL_INVALID_OPERATION, "glUniform2ivARB"); + return; + } +} + +void GLAPIENTRY +_mesa_Uniform3ivARB (GLint location, GLsizei count, const GLint *value) +{ + GET_CURRENT_CONTEXT(ctx); + + if (ctx->ShaderObjects.current_program == NULL) + { + _mesa_error (ctx, GL_INVALID_OPERATION, "glUniform3ivARB"); + return; + } +} + +void GLAPIENTRY +_mesa_Uniform4ivARB (GLint location, GLsizei count, const GLint *value) +{ + GET_CURRENT_CONTEXT(ctx); + + if (ctx->ShaderObjects.current_program == NULL) + { + _mesa_error (ctx, GL_INVALID_OPERATION, "glUniform4ivARB"); + return; + } +} + +void GLAPIENTRY +_mesa_UniformMatrix2fvARB (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value) +{ + GET_CURRENT_CONTEXT(ctx); + + if (ctx->ShaderObjects.current_program == NULL) + { + _mesa_error (ctx, GL_INVALID_OPERATION, "glUniformMatrix2fvARB"); + return; + } +} + +void GLAPIENTRY +_mesa_UniformMatrix3fvARB (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value) +{ + GET_CURRENT_CONTEXT(ctx); + + if (ctx->ShaderObjects.current_program == NULL) + { + _mesa_error (ctx, GL_INVALID_OPERATION, "glUniformMatrix3fvARB"); + return; + } +} + +void GLAPIENTRY +_mesa_UniformMatrix4fvARB (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value) +{ + GET_CURRENT_CONTEXT(ctx); + + if (ctx->ShaderObjects.current_program == NULL) + { + _mesa_error (ctx, GL_INVALID_OPERATION, "glUniformMatrix4fvARB"); + return; + } +} + +static GLboolean +_mesa_get_object_parameter (GLhandleARB obj, GLenum pname, GLvoid *params, GLboolean *integral, + GLint *size) +{ + GET_CURRENT_CONTEXT(ctx); + struct gl2_unknown_intf **unk; + struct gl2_generic_intf **gen; + struct gl2_shader_intf **sha; + struct gl2_program_intf **pro; + GLint *ipar = (GLint *) params; + /*GLfloat *fpar = (GLfloat *) params;*/ + GLboolean success = GL_TRUE; + + _glthread_LOCK_MUTEX (ctx->Shared->Mutex); + unk = (struct gl2_unknown_intf **) _mesa_HashLookup (ctx->Shared->GL2Objects, obj); + _glthread_UNLOCK_MUTEX (ctx->Shared->Mutex); + + if (unk == NULL) + { + _mesa_error (ctx, GL_INVALID_VALUE, "glGetObjectParameterivARB"); + return GL_FALSE; + } + + gen = (struct gl2_generic_intf **) (**unk).QueryInterface (unk, UIID_GENERIC); + if (gen == NULL) + { + _mesa_error (ctx, GL_INVALID_OPERATION, "glGetObjectParameterivARB"); + return GL_FALSE; + } + + sha = (struct gl2_shader_intf **) (**unk).QueryInterface (unk, UIID_SHADER); + pro = (struct gl2_program_intf **) (**unk).QueryInterface (unk, UIID_PROGRAM); + + /* set default values */ + *integral = GL_TRUE; /* indicates param type, TRUE: GLint, FALSE: GLfloat */ + *size = 1; /* param array size */ + + switch (pname) + { + case GL_OBJECT_TYPE_ARB: + *ipar = (**gen).GetType (gen); + break; + case GL_OBJECT_SUBTYPE_ARB: + if (sha != NULL) + *ipar = (**sha).GetSubType (sha); + else { + _mesa_error (ctx, GL_INVALID_OPERATION, "glGetObjectParameterivARB"); + success = GL_FALSE; + } + break; + case GL_OBJECT_DELETE_STATUS_ARB: + *ipar = (**gen).GetDeleteStatus (gen); + break; + case GL_OBJECT_COMPILE_STATUS_ARB: + if (sha != NULL) + *ipar = (**sha).GetCompileStatus (sha); + else { + _mesa_error (ctx, GL_INVALID_OPERATION, "glGetObjectParameterivARB"); + success = GL_FALSE; + } + break; + case GL_OBJECT_LINK_STATUS_ARB: + if (pro != NULL) + *ipar = (**pro).GetLinkStatus (pro); + else { + _mesa_error (ctx, GL_INVALID_OPERATION, "glGetObjectParameterivARB"); + success = GL_FALSE; + } + break; + case GL_OBJECT_VALIDATE_STATUS_ARB: + if (pro != NULL) + *ipar = (**pro).GetValidateStatus (pro); + else { + _mesa_error (ctx, GL_INVALID_OPERATION, "glGetObjectParameterivARB"); + success = GL_FALSE; + } + break; + case GL_OBJECT_INFO_LOG_LENGTH_ARB: + { + const GLcharARB *info = (**gen).GetInfoLog (gen); + if (info == NULL) + *ipar = 0; + else + *ipar = _mesa_strlen (info) + 1; + } + break; + case GL_OBJECT_ATTACHED_OBJECTS_ARB: + if (pro != NULL) + *ipar = (**pro)._container.GetAttachedCount ((struct gl2_container_intf **) pro); + else { + _mesa_error (ctx, GL_INVALID_OPERATION, "glGetObjectParameterivARB"); + success = GL_FALSE; + } + break; + case GL_OBJECT_ACTIVE_UNIFORMS_ARB: + if (pro != NULL) + *ipar = 0; /* TODO */ + else { + _mesa_error (ctx, GL_INVALID_OPERATION, "glGetObjectParameterivARB"); + success = GL_FALSE; + } + break; + case GL_OBJECT_ACTIVE_UNIFORM_MAX_LENGTH_ARB: + if (pro != NULL) + *ipar = 0; /* TODO */ + else { + _mesa_error (ctx, GL_INVALID_OPERATION, "glGetObjectParameterivARB"); + success = GL_FALSE; + } + break; + case GL_OBJECT_SHADER_SOURCE_LENGTH_ARB: + if (sha != NULL) { + const GLcharARB *src = (**sha).GetSource (sha); + if (src == NULL) + *ipar = 0; + else + *ipar = _mesa_strlen (src) + 1; + } else { + _mesa_error (ctx, GL_INVALID_OPERATION, "glGetObjectParameterivARB"); + success = GL_FALSE; + } + break; + default: + _mesa_error (ctx, GL_INVALID_ENUM, "glGetObjectParameterivARB"); + success = GL_FALSE; + break; + } + + (**gen)._unknown.Release ((struct gl2_unknown_intf **) gen); + if (sha != NULL) + (**sha)._generic._unknown.Release ((struct gl2_unknown_intf **) sha); + if (pro != NULL) + (**pro)._container._generic._unknown.Release ((struct gl2_unknown_intf **) pro); + + return success; +} + +void GLAPIENTRY +_mesa_GetObjectParameterfvARB (GLhandleARB obj, GLenum pname, GLfloat *params) +{ + GLboolean integral; + GLint size, i; + + assert (sizeof (GLfloat) == sizeof (GLint)); + + if (_mesa_get_object_parameter (obj, pname, (GLvoid *) params, &integral, &size) != GL_FALSE) + if (integral != GL_FALSE) + for (i = 0; i < size; i++) + params[i] = (GLfloat) ((GLint *) params)[i]; +} + +void GLAPIENTRY +_mesa_GetObjectParameterivARB (GLhandleARB obj, GLenum pname, GLint *params) +{ + GLboolean integral; + GLint size, i; + + assert (sizeof (GLfloat) == sizeof (GLint)); + + if (_mesa_get_object_parameter (obj, pname, (GLvoid *) params, &integral, &size) != GL_FALSE) + if (integral == GL_FALSE) + for (i = 0; i < size; i++) + params[i] = (GLint) ((GLfloat *) params)[i]; +} + +static void +_mesa_get_string (const GLcharARB *src, GLsizei maxLength, GLsizei *length, GLcharARB *str) +{ + GLsizei len; + + if (src == NULL) + src = ""; + + len = _mesa_strlen (src); + if (len > maxLength) + { + len = maxLength; + /* allocate space for null termination */ + if (len > 0) + len--; + } + + _mesa_memcpy (str, src, len * sizeof (GLcharARB)); + if (maxLength > 0) + str[len] = '\0'; + + if (length != NULL) + *length = len; +} + +void GLAPIENTRY +_mesa_GetInfoLogARB (GLhandleARB obj, GLsizei maxLength, GLsizei *length, GLcharARB *infoLog) +{ + GET_CURRENT_CONTEXT(ctx); + struct gl2_unknown_intf **unk; + struct gl2_generic_intf **gen; + + _glthread_LOCK_MUTEX (ctx->Shared->Mutex); + unk = (struct gl2_unknown_intf **) _mesa_HashLookup (ctx->Shared->GL2Objects, obj); + _glthread_UNLOCK_MUTEX (ctx->Shared->Mutex); + + if (unk == NULL) + { + _mesa_error (ctx, GL_INVALID_VALUE, "glGetInfoLogARB"); + return; + } + + gen = (struct gl2_generic_intf **) (**unk).QueryInterface (unk, UIID_GENERIC); + if (gen == NULL) + { + _mesa_error (ctx, GL_INVALID_OPERATION, "glGetInfoLogARB"); + return; + } + + _mesa_get_string ((**gen).GetInfoLog (gen), maxLength, length, infoLog); + + (**gen)._unknown.Release ((struct gl2_unknown_intf **) gen); +} + +void GLAPIENTRY +_mesa_GetAttachedObjectsARB (GLhandleARB containerObj, GLsizei maxCount, GLsizei *count, GLhandleARB *obj) +{ + GET_CURRENT_CONTEXT(ctx); + struct gl2_unknown_intf **unk; + struct gl2_container_intf **con; + GLsizei cnt, i; + + _glthread_LOCK_MUTEX (ctx->Shared->Mutex); + unk = (struct gl2_unknown_intf **) _mesa_HashLookup (ctx->Shared->GL2Objects, containerObj); + _glthread_UNLOCK_MUTEX (ctx->Shared->Mutex); + + if (unk == NULL) + { + _mesa_error (ctx, GL_INVALID_VALUE, "glGetAttachedObjectsARB"); + return; + } + + con = (struct gl2_container_intf **) (**unk).QueryInterface (unk, UIID_CONTAINER); + if (con == NULL) + { + _mesa_error (ctx, GL_INVALID_OPERATION, "glGetAttachedObjectsARB"); + return; + } + + cnt = (**con).GetAttachedCount (con); + if (cnt > maxCount) + cnt = maxCount; + + for (i = 0; i < cnt; i++) + { + struct gl2_generic_intf **x = (**con).GetAttached (con, i); + obj[i] = (**x).GetName (x); + (**x)._unknown.Release ((struct gl2_unknown_intf **) x); + } + + (**con)._generic._unknown.Release ((struct gl2_unknown_intf **) con); + + if (count != NULL) + *count = cnt; +} + +GLint GLAPIENTRY +_mesa_GetUniformLocationARB (GLhandleARB programObj, const GLcharARB *name) +{ + GET_CURRENT_CONTEXT(ctx); + struct gl2_unknown_intf **unk; + struct gl2_program_intf **pro; + GLint loc = -1; + + _glthread_LOCK_MUTEX (ctx->Shared->Mutex); + unk = (struct gl2_unknown_intf **) _mesa_HashLookup (ctx->Shared->GL2Objects, programObj); + _glthread_UNLOCK_MUTEX (ctx->Shared->Mutex); + + if (unk == NULL) + { + _mesa_error (ctx, GL_INVALID_VALUE, "glGetUniformLocationARB"); + return -1; + } + + pro = (struct gl2_program_intf **) (**unk).QueryInterface (unk, UIID_PROGRAM); + if (pro == NULL) + { + _mesa_error (ctx, GL_INVALID_OPERATION, "glGetUniformLocationARB"); + return -1; + } + + if ((**pro).GetLinkStatus (pro) == GL_FALSE) + { + _mesa_error (ctx, GL_INVALID_OPERATION, "glGetUniformLocationARB"); + (**pro)._container._generic._unknown.Release ((struct gl2_unknown_intf **) pro); + return -1; + } + + /* TODO */ + + (**pro)._container._generic._unknown.Release ((struct gl2_unknown_intf **) pro); + return loc; +} + +void GLAPIENTRY +_mesa_GetActiveUniformARB (GLhandleARB programObj, GLuint index, GLsizei maxLength, GLsizei *length, GLint *size, GLenum *type, GLcharARB *name) +{ + GET_CURRENT_CONTEXT(ctx); + struct gl2_unknown_intf **unk; + struct gl2_program_intf **pro; + + _glthread_LOCK_MUTEX (ctx->Shared->Mutex); + unk = (struct gl2_unknown_intf **) _mesa_HashLookup (ctx->Shared->GL2Objects, programObj); + _glthread_UNLOCK_MUTEX (ctx->Shared->Mutex); + + if (unk == NULL) + { + _mesa_error (ctx, GL_INVALID_VALUE, "glGetActiveUniformARB"); + return; + } + + pro = (struct gl2_program_intf **) (**unk).QueryInterface (unk, UIID_PROGRAM); + if (pro == NULL) + { + _mesa_error (ctx, GL_INVALID_OPERATION, "glGetActiveUniformARB"); + return; + } + +/* if (index >= val (OBJECT_ACTIVE_ATTRIBUTES_ARB)) + { + _mesa_error (ctx, GL_INVALID_VALUE, "glGetActiveUniformARB"); + (**pro)._container._generic._unknown.Release ((struct gl2_unknown_intf **) pro); + return; + }*/ + + /* TODO */ + + (**pro)._container._generic._unknown.Release ((struct gl2_unknown_intf **) pro); +} + +void GLAPIENTRY +_mesa_GetUniformfvARB (GLhandleARB programObj, GLint location, GLfloat *params) +{ + GET_CURRENT_CONTEXT(ctx); + struct gl2_unknown_intf **unk; + struct gl2_program_intf **pro; + + _glthread_LOCK_MUTEX (ctx->Shared->Mutex); + unk = (struct gl2_unknown_intf **) _mesa_HashLookup (ctx->Shared->GL2Objects, programObj); + _glthread_UNLOCK_MUTEX (ctx->Shared->Mutex); + + if (unk == NULL) + { + _mesa_error (ctx, GL_INVALID_VALUE, "glGetUniformfvARB"); + return; + } + + pro = (struct gl2_program_intf **) (**unk).QueryInterface (unk, UIID_PROGRAM); + if (pro == NULL) + { + _mesa_error (ctx, GL_INVALID_OPERATION, "glGetUniformfvARB"); + return; + } + + if ((**pro).GetLinkStatus (pro) == GL_FALSE) + { + _mesa_error (ctx, GL_INVALID_OPERATION, "glGetUniformfvARB"); + (**pro)._container._generic._unknown.Release ((struct gl2_unknown_intf **) pro); + return; + } + + /* TODO validate location (OPERATION) */ + + /* TODO */ + + (**pro)._container._generic._unknown.Release ((struct gl2_unknown_intf **) pro); +} + +void GLAPIENTRY +_mesa_GetUniformivARB (GLhandleARB programObj, GLint location, GLint *params) +{ + GET_CURRENT_CONTEXT(ctx); + struct gl2_unknown_intf **unk; + struct gl2_program_intf **pro; + + _glthread_LOCK_MUTEX (ctx->Shared->Mutex); + unk = (struct gl2_unknown_intf **) _mesa_HashLookup (ctx->Shared->GL2Objects, programObj); + _glthread_UNLOCK_MUTEX (ctx->Shared->Mutex); + + if (unk == NULL) + { + _mesa_error (ctx, GL_INVALID_VALUE, "glGetUniformivARB"); + return; + } + + pro = (struct gl2_program_intf **) (**unk).QueryInterface (unk, UIID_PROGRAM); + if (pro == NULL) + { + _mesa_error (ctx, GL_INVALID_OPERATION, "glGetUniformivARB"); + return; + } + + if ((**pro).GetLinkStatus (pro) == GL_FALSE) + { + _mesa_error (ctx, GL_INVALID_OPERATION, "glGetUniformivARB"); + (**pro)._container._generic._unknown.Release ((struct gl2_unknown_intf **) pro); + return; + } + + /* TODO validate location (GL_INVALID_OPERATION) */ + + /* TODO */ + + (**pro)._container._generic._unknown.Release ((struct gl2_unknown_intf **) pro); +} + +void GLAPIENTRY +_mesa_GetShaderSourceARB (GLhandleARB obj, GLsizei maxLength, GLsizei *length, GLcharARB *source) +{ + GET_CURRENT_CONTEXT(ctx); + struct gl2_unknown_intf **unk; + struct gl2_shader_intf **sha; + + _glthread_LOCK_MUTEX (ctx->Shared->Mutex); + unk = (struct gl2_unknown_intf **) _mesa_HashLookup (ctx->Shared->GL2Objects, obj); + _glthread_UNLOCK_MUTEX (ctx->Shared->Mutex); + + if (unk == NULL) + { + _mesa_error (ctx, GL_INVALID_VALUE, "glGetShaderSourceARB"); + return; + } + + sha = (struct gl2_shader_intf **) (**unk).QueryInterface (unk, UIID_SHADER); + if (sha == NULL) + { + _mesa_error (ctx, GL_INVALID_OPERATION, "glGetShaderSourceARB"); + return; + } + + _mesa_get_string ((**sha).GetSource (sha), maxLength, length, source); + + (**sha)._generic._unknown.Release ((struct gl2_unknown_intf **) sha); +} + +/* GL_ARB_vertex_shader */ + +void GLAPIENTRY +_mesa_BindAttribLocationARB (GLhandleARB programObj, GLuint index, const GLcharARB *name) +{ + GET_CURRENT_CONTEXT(ctx); + struct gl2_unknown_intf **unk; + struct gl2_program_intf **pro; + + _glthread_LOCK_MUTEX (ctx->Shared->Mutex); + unk = (struct gl2_unknown_intf **) _mesa_HashLookup (ctx->Shared->GL2Objects, programObj); + _glthread_UNLOCK_MUTEX (ctx->Shared->Mutex); + + if (unk == NULL) + { + _mesa_error (ctx, GL_INVALID_VALUE, "glBindAttribLocationARB"); + return; + } + + pro = (struct gl2_program_intf **) (**unk).QueryInterface (unk, UIID_PROGRAM); + if (pro == NULL) + { + _mesa_error (ctx, GL_INVALID_VALUE, "glBindAttribLocationARB"); + return; + } + + /* TODO */ + + (**pro)._container._generic._unknown.Release ((struct gl2_unknown_intf **) pro); +} + +void GLAPIENTRY +_mesa_GetActiveAttribARB (GLhandleARB programObj, GLuint index, GLsizei maxLength, GLsizei *length, GLint *size, GLenum *type, GLcharARB *name) +{ + GET_CURRENT_CONTEXT(ctx); + struct gl2_unknown_intf **unk; + struct gl2_program_intf **pro; + + _glthread_LOCK_MUTEX (ctx->Shared->Mutex); + unk = (struct gl2_unknown_intf **) _mesa_HashLookup (ctx->Shared->GL2Objects, programObj); + _glthread_UNLOCK_MUTEX (ctx->Shared->Mutex); + + if (unk == NULL) + { + _mesa_error (ctx, GL_INVALID_VALUE, "glGetActiveAttribARB"); + return; + } + + pro = (struct gl2_program_intf **) (**unk).QueryInterface (unk, UIID_PROGRAM); + if (pro == NULL) + { + _mesa_error (ctx, GL_INVALID_VALUE, "glGetActiveAttribARB"); + return; + } + + /* TODO */ + + (**pro)._container._generic._unknown.Release ((struct gl2_unknown_intf **) pro); +} + +GLint GLAPIENTRY +_mesa_GetAttribLocationARB (GLhandleARB programObj, const GLcharARB *name) +{ + GET_CURRENT_CONTEXT(ctx); + struct gl2_unknown_intf **unk; + struct gl2_program_intf **pro; + GLint loc = 0; + + _glthread_LOCK_MUTEX (ctx->Shared->Mutex); + unk = (struct gl2_unknown_intf **) _mesa_HashLookup (ctx->Shared->GL2Objects, programObj); + _glthread_UNLOCK_MUTEX (ctx->Shared->Mutex); + + if (unk == NULL) + { + _mesa_error (ctx, GL_INVALID_VALUE, "glGetAttribLocationARB"); + return 0; + } + + pro = (struct gl2_program_intf **) (**unk).QueryInterface (unk, UIID_PROGRAM); + if (pro == NULL) + { + _mesa_error (ctx, GL_INVALID_VALUE, "glGetAttribLocationARB"); + return 0; + } + + /* TODO */ + + (**pro)._container._generic._unknown.Release ((struct gl2_unknown_intf **) pro); + return loc; +} + +void +_mesa_init_shaderobjects (GLcontext *ctx) +{ + ctx->ShaderObjects.current_program = NULL; + + _mesa_init_shaderobjects_3dlabs (ctx); +} + diff --git a/nx-X11/extras/Mesa/src/mesa/shader/shaderobjects.h b/nx-X11/extras/Mesa/src/mesa/shader/shaderobjects.h new file mode 100644 index 000000000..29747ca85 --- /dev/null +++ b/nx-X11/extras/Mesa/src/mesa/shader/shaderobjects.h @@ -0,0 +1,168 @@ +/* + * Mesa 3-D graphics library + * Version: 6.3 + * + * Copyright (C) 2004-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 SHADEROBJECTS_H +#define SHADEROBJECTS_H + +#include "mtypes.h" + +#if FEATURE_ARB_shader_objects + +extern void GLAPIENTRY +_mesa_DeleteObjectARB(GLhandleARB obj); + +extern GLhandleARB GLAPIENTRY +_mesa_GetHandleARB(GLenum pname); + +extern void GLAPIENTRY +_mesa_DetachObjectARB (GLhandleARB, GLhandleARB); + +extern GLhandleARB GLAPIENTRY +_mesa_CreateShaderObjectARB (GLenum); + +extern void GLAPIENTRY +_mesa_ShaderSourceARB (GLhandleARB, GLsizei, const GLcharARB* *, const GLint *); + +extern void GLAPIENTRY +_mesa_CompileShaderARB (GLhandleARB); + +extern GLhandleARB GLAPIENTRY +_mesa_CreateProgramObjectARB (void); + +extern void GLAPIENTRY +_mesa_AttachObjectARB (GLhandleARB, GLhandleARB); + +extern void GLAPIENTRY +_mesa_LinkProgramARB (GLhandleARB); + +extern void GLAPIENTRY +_mesa_UseProgramObjectARB (GLhandleARB); + +extern void GLAPIENTRY +_mesa_ValidateProgramARB (GLhandleARB); + +extern void GLAPIENTRY +_mesa_Uniform1fARB (GLint, GLfloat); + +extern void GLAPIENTRY +_mesa_Uniform2fARB (GLint, GLfloat, GLfloat); + +extern void GLAPIENTRY +_mesa_Uniform3fARB (GLint, GLfloat, GLfloat, GLfloat); + +extern void GLAPIENTRY +_mesa_Uniform4fARB (GLint, GLfloat, GLfloat, GLfloat, GLfloat); + +extern void GLAPIENTRY +_mesa_Uniform1iARB (GLint, GLint); + +extern void GLAPIENTRY +_mesa_Uniform2iARB (GLint, GLint, GLint); + +extern void GLAPIENTRY +_mesa_Uniform3iARB (GLint, GLint, GLint, GLint); + +extern void GLAPIENTRY +_mesa_Uniform4iARB (GLint, GLint, GLint, GLint, GLint); + +extern void GLAPIENTRY +_mesa_Uniform1fvARB (GLint, GLsizei, const GLfloat *); + +extern void GLAPIENTRY +_mesa_Uniform2fvARB (GLint, GLsizei, const GLfloat *); + +extern void GLAPIENTRY +_mesa_Uniform3fvARB (GLint, GLsizei, const GLfloat *); + +extern void GLAPIENTRY +_mesa_Uniform4fvARB (GLint, GLsizei, const GLfloat *); + +extern void GLAPIENTRY +_mesa_Uniform1ivARB (GLint, GLsizei, const GLint *); + +extern void GLAPIENTRY +_mesa_Uniform2ivARB (GLint, GLsizei, const GLint *); + +extern void GLAPIENTRY +_mesa_Uniform3ivARB (GLint, GLsizei, const GLint *); + +extern void GLAPIENTRY +_mesa_Uniform4ivARB (GLint, GLsizei, const GLint *); + +extern void GLAPIENTRY +_mesa_UniformMatrix2fvARB (GLint, GLsizei, GLboolean, const GLfloat *); + +extern void GLAPIENTRY +_mesa_UniformMatrix3fvARB (GLint, GLsizei, GLboolean, const GLfloat *); + +extern void GLAPIENTRY +_mesa_UniformMatrix4fvARB (GLint, GLsizei, GLboolean, const GLfloat *); + +extern void GLAPIENTRY +_mesa_GetObjectParameterfvARB (GLhandleARB, GLenum, GLfloat *); + +extern void GLAPIENTRY +_mesa_GetObjectParameterivARB (GLhandleARB, GLenum, GLint *); + +extern void GLAPIENTRY +_mesa_GetInfoLogARB (GLhandleARB, GLsizei, GLsizei *, GLcharARB *); + +extern void GLAPIENTRY +_mesa_GetAttachedObjectsARB (GLhandleARB, GLsizei, GLsizei *, GLhandleARB *); + +extern GLint GLAPIENTRY +_mesa_GetUniformLocationARB (GLhandleARB, const GLcharARB *); + +extern void GLAPIENTRY +_mesa_GetActiveUniformARB (GLhandleARB, GLuint, GLsizei, GLsizei *, GLint *, GLenum *, GLcharARB *); + +extern void GLAPIENTRY +_mesa_GetUniformfvARB (GLhandleARB, GLint, GLfloat *); + +extern void GLAPIENTRY +_mesa_GetUniformivARB (GLhandleARB, GLint, GLint *); + +extern void GLAPIENTRY +_mesa_GetShaderSourceARB (GLhandleARB, GLsizei, GLsizei *, GLcharARB *); + +#if FEATURE_ARB_vertex_shader + +extern void GLAPIENTRY +_mesa_BindAttribLocationARB (GLhandleARB, GLuint, const GLcharARB *); + +extern void GLAPIENTRY +_mesa_GetActiveAttribARB (GLhandleARB, GLuint, GLsizei, GLsizei *, GLint *, GLenum *, GLcharARB *); + +extern GLint GLAPIENTRY +_mesa_GetAttribLocationARB (GLhandleARB, const GLcharARB *); + +#endif + +extern void +_mesa_init_shaderobjects (GLcontext *ctx); + +#endif + +#endif + diff --git a/nx-X11/extras/Mesa/src/mesa/shader/shaderobjects_3dlabs.c b/nx-X11/extras/Mesa/src/mesa/shader/shaderobjects_3dlabs.c new file mode 100644 index 000000000..112ff0506 --- /dev/null +++ b/nx-X11/extras/Mesa/src/mesa/shader/shaderobjects_3dlabs.c @@ -0,0 +1,1052 @@ +/* + * Mesa 3-D graphics library + * Version: 6.3 + * + * Copyright (C) 2005 Brian Paul All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN + * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +/** + * \file shaderobjects_3dlabs.c + * shader objects definitions for 3dlabs compiler + * \author Michal Krol + */ + +/* Set this to 1 when we are ready to use 3dlabs' front-end */ +#define USE_3DLABS_FRONTEND 0 + +#include "glheader.h" +#include "shaderobjects.h" +#include "shaderobjects_3dlabs.h" +#include "context.h" +#include "macros.h" +#include "hash.h" + +#if USE_3DLABS_FRONTEND +#include "slang_mesa.h" +#include "Public/ShaderLang.h" +#else +#include "slang_compile.h" +#endif + +struct gl2_unknown_obj +{ + GLuint reference_count; + void (* _destructor) (struct gl2_unknown_intf **); +}; + +struct gl2_unknown_impl +{ + struct gl2_unknown_intf *_vftbl; + struct gl2_unknown_obj _obj; +}; + +static void +_unknown_destructor (struct gl2_unknown_intf **intf) +{ +} + +static void +_unknown_AddRef (struct gl2_unknown_intf **intf) +{ + struct gl2_unknown_impl *impl = (struct gl2_unknown_impl *) intf; + + impl->_obj.reference_count++; +} + +static void +_unknown_Release (struct gl2_unknown_intf **intf) +{ + struct gl2_unknown_impl *impl = (struct gl2_unknown_impl *) intf; + + impl->_obj.reference_count--; + if (impl->_obj.reference_count == 0) + { + impl->_obj._destructor (intf); + _mesa_free ((void *) intf); + } +} + +static struct gl2_unknown_intf ** +_unknown_QueryInterface (struct gl2_unknown_intf **intf, enum gl2_uiid uiid) +{ + if (uiid == UIID_UNKNOWN) + { + (**intf).AddRef (intf); + return intf; + } + return NULL; +} + +static struct gl2_unknown_intf _unknown_vftbl = { + _unknown_AddRef, + _unknown_Release, + _unknown_QueryInterface +}; + +static void +_unknown_constructor (struct gl2_unknown_impl *impl) +{ + impl->_vftbl = &_unknown_vftbl; + impl->_obj.reference_count = 1; + impl->_obj._destructor = _unknown_destructor; +} + +struct gl2_unkinner_obj +{ + struct gl2_unknown_intf **unkouter; +}; + +struct gl2_unkinner_impl +{ + struct gl2_unknown_intf *_vftbl; + struct gl2_unkinner_obj _obj; +}; + +static void +_unkinner_destructor (struct gl2_unknown_intf **intf) +{ +} + +static void +_unkinner_AddRef (struct gl2_unknown_intf **intf) +{ + struct gl2_unkinner_impl *impl = (struct gl2_unkinner_impl *) intf; + + (**impl->_obj.unkouter).AddRef (impl->_obj.unkouter); +} + +static void +_unkinner_Release (struct gl2_unknown_intf **intf) +{ + struct gl2_unkinner_impl *impl = (struct gl2_unkinner_impl *) intf; + + (**impl->_obj.unkouter).Release (impl->_obj.unkouter); +} + +static struct gl2_unknown_intf ** +_unkinner_QueryInterface (struct gl2_unknown_intf **intf, enum gl2_uiid uiid) +{ + struct gl2_unkinner_impl *impl = (struct gl2_unkinner_impl *) intf; + + return (**impl->_obj.unkouter).QueryInterface (impl->_obj.unkouter, uiid); +} + +static struct gl2_unknown_intf _unkinner_vftbl = { + _unkinner_AddRef, + _unkinner_Release, + _unkinner_QueryInterface +}; + +static void +_unkinner_constructor (struct gl2_unkinner_impl *impl, struct gl2_unknown_intf **outer) +{ + impl->_vftbl = &_unkinner_vftbl; + impl->_obj.unkouter = outer; +} + +struct gl2_generic_obj +{ + struct gl2_unknown_obj _unknown; + GLhandleARB name; + GLboolean delete_status; + GLcharARB *info_log; +}; + +struct gl2_generic_impl +{ + struct gl2_generic_intf *_vftbl; + struct gl2_generic_obj _obj; +}; + +static void +_generic_destructor (struct gl2_unknown_intf **intf) +{ + GET_CURRENT_CONTEXT(ctx); + struct gl2_generic_impl *impl = (struct gl2_generic_impl *) intf; + + _mesa_free ((void *) impl->_obj.info_log); + + _glthread_LOCK_MUTEX (ctx->Shared->Mutex); + _mesa_HashRemove (ctx->Shared->GL2Objects, impl->_obj.name); + _glthread_UNLOCK_MUTEX (ctx->Shared->Mutex); + + _unknown_destructor (intf); +} + +static struct gl2_unknown_intf ** +_generic_QueryInterface (struct gl2_unknown_intf **intf, enum gl2_uiid uiid) +{ + if (uiid == UIID_GENERIC) + { + (**intf).AddRef (intf); + return intf; + } + return _unknown_QueryInterface (intf, uiid); +} + +static void +_generic_Delete (struct gl2_generic_intf **intf) +{ + struct gl2_generic_impl *impl = (struct gl2_generic_impl *) intf; + + if (impl->_obj.delete_status == GL_FALSE) + { + impl->_obj.delete_status = GL_TRUE; + (**intf)._unknown.Release ((struct gl2_unknown_intf **) intf); + } +} + +static GLhandleARB +_generic_GetName (struct gl2_generic_intf **intf) +{ + struct gl2_generic_impl *impl = (struct gl2_generic_impl *) intf; + + return impl->_obj.name; +} + +static GLboolean +_generic_GetDeleteStatus (struct gl2_generic_intf **intf) +{ + struct gl2_generic_impl *impl = (struct gl2_generic_impl *) intf; + + return impl->_obj.delete_status; +} + +static const GLcharARB * +_generic_GetInfoLog (struct gl2_generic_intf **intf) +{ + struct gl2_generic_impl *impl = (struct gl2_generic_impl *) intf; + + return impl->_obj.info_log; +} + +static struct gl2_generic_intf _generic_vftbl = { + { + _unknown_AddRef, + _unknown_Release, + _generic_QueryInterface + }, + _generic_Delete, + NULL, /* abstract GetType */ + _generic_GetName, + _generic_GetDeleteStatus, + _generic_GetInfoLog +}; + +static void +_generic_constructor (struct gl2_generic_impl *impl) +{ + GET_CURRENT_CONTEXT(ctx); + + _unknown_constructor ((struct gl2_unknown_impl *) impl); + impl->_vftbl = &_generic_vftbl; + impl->_obj._unknown._destructor = _generic_destructor; + impl->_obj.delete_status = GL_FALSE; + impl->_obj.info_log = NULL; + + _glthread_LOCK_MUTEX (ctx->Shared->Mutex); + impl->_obj.name = _mesa_HashFindFreeKeyBlock (ctx->Shared->GL2Objects, 1); + _mesa_HashInsert (ctx->Shared->GL2Objects, impl->_obj.name, (void *) impl); + _glthread_UNLOCK_MUTEX (ctx->Shared->Mutex); +} + +struct gl2_container_obj +{ + struct gl2_generic_obj _generic; + struct gl2_generic_intf ***attached; + GLuint attached_count; +}; + +struct gl2_container_impl +{ + struct gl2_container_intf *_vftbl; + struct gl2_container_obj _obj; +}; + +static void +_container_destructor (struct gl2_unknown_intf **intf) +{ + struct gl2_container_impl *impl = (struct gl2_container_impl *) intf; + GLuint i; + + for (i = 0; i < impl->_obj.attached_count; i++) + { + struct gl2_generic_intf **x = impl->_obj.attached[i]; + (**x)._unknown.Release ((struct gl2_unknown_intf **) x); + } + + _generic_destructor (intf); +} + +static struct gl2_unknown_intf ** +_container_QueryInterface (struct gl2_unknown_intf **intf, enum gl2_uiid uiid) +{ + if (uiid == UIID_CONTAINER) + { + (**intf).AddRef (intf); + return intf; + } + return _generic_QueryInterface (intf, uiid); +} + +static GLboolean +_container_Attach (struct gl2_container_intf **intf, struct gl2_generic_intf **att) +{ + GET_CURRENT_CONTEXT(ctx); + struct gl2_container_impl *impl = (struct gl2_container_impl *) intf; + GLuint i; + + for (i = 0; i < impl->_obj.attached_count; i++) + if (impl->_obj.attached[i] == att) + { + _mesa_error (ctx, GL_INVALID_OPERATION, "_container_Attach"); + return GL_FALSE; + } + + impl->_obj.attached = (struct gl2_generic_intf ***) _mesa_realloc (impl->_obj.attached, + impl->_obj.attached_count * sizeof (*impl->_obj.attached), (impl->_obj.attached_count + 1) * + sizeof (*impl->_obj.attached)); + if (impl->_obj.attached == NULL) + return GL_FALSE; + + impl->_obj.attached[impl->_obj.attached_count] = att; + impl->_obj.attached_count++; + (**att)._unknown.AddRef ((struct gl2_unknown_intf **) att); + return GL_TRUE; +} + +static GLboolean +_container_Detach (struct gl2_container_intf **intf, struct gl2_generic_intf **att) +{ + GET_CURRENT_CONTEXT(ctx); + struct gl2_container_impl *impl = (struct gl2_container_impl *) intf; + GLuint i, j; + + for (i = 0; i < impl->_obj.attached_count; i++) + if (impl->_obj.attached[i] == att) + { + for (j = i; j < impl->_obj.attached_count - 1; j++) + impl->_obj.attached[j] = impl->_obj.attached[j + 1]; + impl->_obj.attached = (struct gl2_generic_intf ***) _mesa_realloc (impl->_obj.attached, + impl->_obj.attached_count * sizeof (*impl->_obj.attached), + (impl->_obj.attached_count - 1) * sizeof (*impl->_obj.attached)); + impl->_obj.attached_count--; + (**att)._unknown.Release ((struct gl2_unknown_intf **) att); + return GL_TRUE; + } + + _mesa_error (ctx, GL_INVALID_OPERATION, "_container_Detach"); + return GL_FALSE; +} + +static GLsizei +_container_GetAttachedCount (struct gl2_container_intf **intf) +{ + struct gl2_container_impl *impl = (struct gl2_container_impl *) intf; + + return impl->_obj.attached_count; +} + +static struct gl2_generic_intf ** +_container_GetAttached (struct gl2_container_intf **intf, GLuint index) +{ + struct gl2_container_impl *impl = (struct gl2_container_impl *) intf; + + (**impl->_obj.attached[index])._unknown.AddRef ( + (struct gl2_unknown_intf **)impl->_obj.attached[index]); + return impl->_obj.attached[index]; +} + +static struct gl2_container_intf _container_vftbl = { + { + { + _unknown_AddRef, + _unknown_Release, + _container_QueryInterface + }, + _generic_Delete, + NULL, /* abstract GetType */ + _generic_GetName, + _generic_GetDeleteStatus, + _generic_GetInfoLog + }, + _container_Attach, + _container_Detach, + _container_GetAttachedCount, + _container_GetAttached +}; + +static void +_container_constructor (struct gl2_container_impl *impl) +{ + _generic_constructor ((struct gl2_generic_impl *) impl); + impl->_vftbl = &_container_vftbl; + impl->_obj._generic._unknown._destructor = _container_destructor; + impl->_obj.attached = NULL; + impl->_obj.attached_count = 0; +} + +struct gl2_3dlabs_shhandle_obj +{ + struct gl2_unkinner_obj _unknown; +#if USE_3DLABS_FRONTEND + ShHandle handle; +#endif +}; + +struct gl2_3dlabs_shhandle_impl +{ + struct gl2_3dlabs_shhandle_intf *_vftbl; + struct gl2_3dlabs_shhandle_obj _obj; +}; + +static void +_3dlabs_shhandle_destructor (struct gl2_unknown_intf **intf) +{ +#if USE_3DLABS_FRONTEND + struct gl2_3dlabs_shhandle_impl *impl = (struct gl2_3dlabs_shhandle_impl *) intf; + ShDestruct (impl->_obj.handle); +#endif + _unkinner_destructor (intf); +} + +static GLvoid * +_3dlabs_shhandle_GetShHandle (struct gl2_3dlabs_shhandle_intf **intf) +{ +#if USE_3DLABS_FRONTEND + struct gl2_3dlabs_shhandle_impl *impl = (struct gl2_3dlabs_shhandle_impl *) intf; + return impl->_obj.handle; +#else + return NULL; +#endif +} + +static struct gl2_3dlabs_shhandle_intf _3dlabs_shhandle_vftbl = { + { + _unkinner_AddRef, + _unkinner_Release, + _unkinner_QueryInterface + }, + _3dlabs_shhandle_GetShHandle +}; + +static void +_3dlabs_shhandle_constructor (struct gl2_3dlabs_shhandle_impl *impl, struct gl2_unknown_intf **outer) +{ + _unkinner_constructor ((struct gl2_unkinner_impl *) impl, outer); + impl->_vftbl = &_3dlabs_shhandle_vftbl; +#if USE_3DLABS_FRONTEND + impl->_obj.handle = NULL; +#endif +} + +struct gl2_shader_obj +{ + struct gl2_generic_obj _generic; + struct gl2_3dlabs_shhandle_impl _3dlabs_shhandle; + GLboolean compile_status; + GLcharARB *source; + GLint *offsets; + GLsizei offset_count; +}; + +struct gl2_shader_impl +{ + struct gl2_shader_intf *_vftbl; + struct gl2_shader_obj _obj; +}; + +static void +_shader_destructor (struct gl2_unknown_intf **intf) +{ + struct gl2_shader_impl *impl = (struct gl2_shader_impl *) intf; + + _mesa_free ((void *) impl->_obj.source); + _mesa_free ((void *) impl->_obj.offsets); + _3dlabs_shhandle_destructor ((struct gl2_unknown_intf **) &impl->_obj._3dlabs_shhandle._vftbl); + _generic_destructor (intf); +} + +static struct gl2_unknown_intf ** +_shader_QueryInterface (struct gl2_unknown_intf **intf, enum gl2_uiid uiid) +{ +#if USE_3DLABS_FRONTEND + struct gl2_shader_impl *impl = (struct gl2_shader_impl *) intf; +#endif + + if (uiid == UIID_SHADER) + { + (**intf).AddRef (intf); + return intf; + } +#if USE_3DLABS_FRONTEND + if (uiid == UIID_3DLABS_SHHANDLE) + { + (**intf).AddRef (intf); + return (struct gl2_unknown_intf **) &impl->_obj._3dlabs_shhandle._vftbl; + } +#endif + return _generic_QueryInterface (intf, uiid); +} + +static GLenum +_shader_GetType (struct gl2_generic_intf **intf) +{ + return GL_SHADER_OBJECT_ARB; +} + +static GLboolean +_shader_GetCompileStatus (struct gl2_shader_intf **intf) +{ + struct gl2_shader_impl *impl = (struct gl2_shader_impl *) intf; + + return impl->_obj.compile_status; +} + +static GLvoid +_shader_SetSource (struct gl2_shader_intf **intf, GLcharARB *src, GLint *off, GLsizei cnt) +{ + struct gl2_shader_impl *impl = (struct gl2_shader_impl *) intf; + + _mesa_free ((void *) impl->_obj.source); + impl->_obj.source = src; + _mesa_free ((void *) impl->_obj.offsets); + impl->_obj.offsets = off; + impl->_obj.offset_count = cnt; +} + +static const GLcharARB * +_shader_GetSource (struct gl2_shader_intf **intf) +{ + struct gl2_shader_impl *impl = (struct gl2_shader_impl *) intf; + + return impl->_obj.source; +} + +static GLvoid +_shader_Compile (struct gl2_shader_intf **intf) +{ + struct gl2_shader_impl *impl = (struct gl2_shader_impl *) intf; +#if USE_3DLABS_FRONTEND + char **strings; + TBuiltInResource res; +#else + slang_translation_unit unit; + slang_unit_type type; + slang_info_log info_log; +#endif + + impl->_obj.compile_status = GL_FALSE; + _mesa_free ((void *) impl->_obj._generic.info_log); + impl->_obj._generic.info_log = NULL; + +#if USE_3DLABS_FRONTEND + /* 3dlabs compiler expects us to feed it with null-terminated string array, + we've got only one big string with offsets, so we must split it; but when + there's only one string to deal with, we pass its address directly */ + + if (impl->_obj.offset_count <= 1) + strings = &impl->_obj.source; + else + { + GLsizei i, offset = 0; + + strings = (char **) _mesa_malloc (impl->_obj.offset_count * sizeof (char *)); + if (strings == NULL) + return; + + for (i = 0; i < impl->_obj.offset_count; i++) + { + GLsizei size = impl->_obj.offsets[i] - offset; + + strings[i] = (char *) _mesa_malloc ((size + 1) * sizeof (char)); + if (strings[i] == NULL) + { + GLsizei j; + + for (j = 0; j < i; j++) + _mesa_free (strings[j]); + _mesa_free (strings); + return; + } + + _mesa_memcpy (strings[i], impl->_obj.source + offset, size * sizeof (char)); + strings[i][size] = '\0'; + offset = impl->_obj.offsets[i]; + } + } + + /* TODO set these fields to some REAL numbers */ + res.maxLights = 8; + res.maxClipPlanes = 6; + res.maxTextureUnits = 2; + res.maxTextureCoords = 2; + res.maxVertexAttribs = 8; + res.maxVertexUniformComponents = 64; + res.maxVaryingFloats = 8; + res.maxVertexTextureImageUnits = 2; + res.maxCombinedTextureImageUnits = 2; + res.maxTextureImageUnits = 2; + res.maxFragmentUniformComponents = 64; + res.maxDrawBuffers = 1; + + if (ShCompile (impl->_obj._3dlabs_shhandle._obj.handle, strings, impl->_obj.offset_count, + EShOptFull, &res, 0)) + impl->_obj.compile_status = GL_TRUE; + if (impl->_obj.offset_count > 1) + { + GLsizei i; + + for (i = 0; i < impl->_obj.offset_count; i++) + _mesa_free (strings[i]); + _mesa_free (strings); + } + + impl->_obj._generic.info_log = _mesa_strdup (ShGetInfoLog ( + impl->_obj._3dlabs_shhandle._obj.handle)); +#else + if (impl->_vftbl->GetSubType (intf) == GL_FRAGMENT_SHADER) + type = slang_unit_fragment_shader; + else + type = slang_unit_vertex_shader; + slang_info_log_construct (&info_log); + if (_slang_compile (impl->_obj.source, &unit, type, &info_log)) + { + impl->_obj.compile_status = GL_TRUE; + } + if (info_log.text != NULL) + impl->_obj._generic.info_log = _mesa_strdup (info_log.text); + else + impl->_obj._generic.info_log = _mesa_strdup (""); + slang_info_log_destruct (&info_log); +#endif +} + +static struct gl2_shader_intf _shader_vftbl = { + { + { + _unknown_AddRef, + _unknown_Release, + _shader_QueryInterface + }, + _generic_Delete, + _shader_GetType, + _generic_GetName, + _generic_GetDeleteStatus, + _generic_GetInfoLog + }, + NULL, /* abstract GetSubType */ + _shader_GetCompileStatus, + _shader_SetSource, + _shader_GetSource, + _shader_Compile +}; + +static void +_shader_constructor (struct gl2_shader_impl *impl) +{ + _generic_constructor ((struct gl2_generic_impl *) impl); + _3dlabs_shhandle_constructor (&impl->_obj._3dlabs_shhandle, (struct gl2_unknown_intf **) + &impl->_vftbl); + impl->_vftbl = &_shader_vftbl; + impl->_obj._generic._unknown._destructor = _shader_destructor; + impl->_obj.compile_status = GL_FALSE; + impl->_obj.source = NULL; + impl->_obj.offsets = NULL; + impl->_obj.offset_count = 0; +} + +struct gl2_program_obj +{ + struct gl2_container_obj _container; + GLboolean link_status; + GLboolean validate_status; +#if USE_3DLABS_FRONTEND + ShHandle linker; + ShHandle uniforms; +#endif +}; + +struct gl2_program_impl +{ + struct gl2_program_intf *_vftbl; + struct gl2_program_obj _obj; +}; + +static void +_program_destructor (struct gl2_unknown_intf **intf) +{ +#if USE_3DLABS_FRONTEND + struct gl2_program_impl *impl = (struct gl2_program_impl *) intf; + + ShDestruct (impl->_obj.linker); + ShDestruct (impl->_obj.uniforms); +#endif + _container_destructor (intf); +} + +static struct gl2_unknown_intf ** +_program_QueryInterface (struct gl2_unknown_intf **intf, enum gl2_uiid uiid) +{ + if (uiid == UIID_PROGRAM) + { + (**intf).AddRef (intf); + return intf; + } + return _container_QueryInterface (intf, uiid); +} + +static GLenum +_program_GetType (struct gl2_generic_intf **intf) +{ + return GL_PROGRAM_OBJECT_ARB; +} + +static GLboolean +_program_Attach (struct gl2_container_intf **intf, struct gl2_generic_intf **att) +{ + GET_CURRENT_CONTEXT(ctx); + struct gl2_unknown_intf **sha; + + sha = (**att)._unknown.QueryInterface ((struct gl2_unknown_intf **) att, UIID_SHADER); + if (sha == NULL) + { + _mesa_error (ctx, GL_INVALID_OPERATION, "_program_Attach"); + return GL_FALSE; + } + + (**sha).Release (sha); + return _container_Attach (intf, att); +} + +static GLboolean +_program_GetLinkStatus (struct gl2_program_intf **intf) +{ + struct gl2_program_impl *impl = (struct gl2_program_impl *) intf; + + return impl->_obj.link_status; +} + +static GLboolean +_program_GetValidateStatus (struct gl2_program_intf **intf) +{ + struct gl2_program_impl *impl = (struct gl2_program_impl *) intf; + + return impl->_obj.validate_status; +} + +static GLvoid +_program_Link (struct gl2_program_intf **intf) +{ + struct gl2_program_impl *impl = (struct gl2_program_impl *) intf; +#if USE_3DLABS_FRONTEND + ShHandle *handles; + GLuint i; +#endif + + impl->_obj.link_status = GL_FALSE; + _mesa_free ((void *) impl->_obj._container._generic.info_log); + impl->_obj._container._generic.info_log = NULL; + +#if USE_3DLABS_FRONTEND + handles = (ShHandle *) _mesa_malloc (impl->_obj._container.attached_count * sizeof (ShHandle)); + if (handles == NULL) + return; + + for (i = 0; i < impl->_obj._container.attached_count; i++) + { + struct gl2_generic_intf **gen = impl->_obj._container.attached[i]; + struct gl2_3dlabs_shhandle_intf **sh; + + sh = (struct gl2_3dlabs_shhandle_intf **) (**gen)._unknown.QueryInterface ( + (struct gl2_unknown_intf **) gen, UIID_3DLABS_SHHANDLE); + if (sh != NULL) + { + handles[i] = (**sh).GetShHandle (sh); + (**sh)._unknown.Release ((struct gl2_unknown_intf **) sh); + } + else + { + _mesa_free (handles); + return; + } + } + + if (ShLink (impl->_obj.linker, handles, impl->_obj._container.attached_count, + impl->_obj.uniforms, NULL, NULL)) + impl->_obj.link_status = GL_TRUE; + + impl->_obj._container._generic.info_log = _mesa_strdup (ShGetInfoLog (impl->_obj.linker)); +#endif +} + +static GLvoid +_program_Validate (struct gl2_program_intf **intf) +{ + struct gl2_program_impl *impl = (struct gl2_program_impl *) intf; + + impl->_obj.validate_status = GL_FALSE; + _mesa_free ((void *) impl->_obj._container._generic.info_log); + impl->_obj._container._generic.info_log = NULL; + + /* TODO validate */ +} + +static struct gl2_program_intf _program_vftbl = { + { + { + { + _unknown_AddRef, + _unknown_Release, + _program_QueryInterface + }, + _generic_Delete, + _program_GetType, + _generic_GetName, + _generic_GetDeleteStatus, + _generic_GetInfoLog + }, + _program_Attach, + _container_Detach, + _container_GetAttachedCount, + _container_GetAttached + }, + _program_GetLinkStatus, + _program_GetValidateStatus, + _program_Link, + _program_Validate +}; + +static void +_program_constructor (struct gl2_program_impl *impl) +{ + _container_constructor ((struct gl2_container_impl *) impl); + impl->_vftbl = &_program_vftbl; + impl->_obj._container._generic._unknown._destructor = _program_destructor; + impl->_obj.link_status = GL_FALSE; + impl->_obj.validate_status = GL_FALSE; +#if USE_3DLABS_FRONTEND + impl->_obj.linker = ShConstructLinker (EShExVertexFragment, 0); + impl->_obj.uniforms = ShConstructUniformMap (); +#endif +} + +struct gl2_fragment_shader_obj +{ + struct gl2_shader_obj _shader; +}; + +struct gl2_fragment_shader_impl +{ + struct gl2_fragment_shader_intf *_vftbl; + struct gl2_fragment_shader_obj _obj; +}; + +static void +_fragment_shader_destructor (struct gl2_unknown_intf **intf) +{ + struct gl2_fragment_shader_impl *impl = (struct gl2_fragment_shader_impl *) intf; + + (void) impl; + /* TODO free fragment shader data */ + + _shader_destructor (intf); +} + +static struct gl2_unknown_intf ** +_fragment_shader_QueryInterface (struct gl2_unknown_intf **intf, enum gl2_uiid uiid) +{ + if (uiid == UIID_FRAGMENT_SHADER) + { + (**intf).AddRef (intf); + return intf; + } + return _shader_QueryInterface (intf, uiid); +} + +static GLenum +_fragment_shader_GetSubType (struct gl2_shader_intf **intf) +{ + return GL_FRAGMENT_SHADER_ARB; +} + +static struct gl2_fragment_shader_intf _fragment_shader_vftbl = { + { + { + { + _unknown_AddRef, + _unknown_Release, + _fragment_shader_QueryInterface + }, + _generic_Delete, + _shader_GetType, + _generic_GetName, + _generic_GetDeleteStatus, + _generic_GetInfoLog + }, + _fragment_shader_GetSubType, + _shader_GetCompileStatus, + _shader_SetSource, + _shader_GetSource, + _shader_Compile + } +}; + +static void +_fragment_shader_constructor (struct gl2_fragment_shader_impl *impl) +{ + _shader_constructor ((struct gl2_shader_impl *) impl); + impl->_vftbl = &_fragment_shader_vftbl; + impl->_obj._shader._generic._unknown._destructor = _fragment_shader_destructor; +#if USE_3DLABS_FRONTEND + impl->_obj._shader._3dlabs_shhandle._obj.handle = ShConstructCompiler (EShLangFragment, 0); +#endif +} + +struct gl2_vertex_shader_obj +{ + struct gl2_shader_obj _shader; +}; + +struct gl2_vertex_shader_impl +{ + struct gl2_vertex_shader_intf *_vftbl; + struct gl2_vertex_shader_obj _obj; +}; + +static void +_vertex_shader_destructor (struct gl2_unknown_intf **intf) +{ + struct gl2_vertex_shader_impl *impl = (struct gl2_vertex_shader_impl *) intf; + + (void) impl; + /* TODO free vertex shader data */ + + _shader_destructor (intf); +} + +static struct gl2_unknown_intf ** +_vertex_shader_QueryInterface (struct gl2_unknown_intf **intf, enum gl2_uiid uiid) +{ + if (uiid == UIID_VERTEX_SHADER) + { + (**intf).AddRef (intf); + return intf; + } + return _shader_QueryInterface (intf, uiid); +} + +static GLenum +_vertex_shader_GetSubType (struct gl2_shader_intf **intf) +{ + return GL_VERTEX_SHADER_ARB; +} + +static struct gl2_vertex_shader_intf _vertex_shader_vftbl = { + { + { + { + _unknown_AddRef, + _unknown_Release, + _vertex_shader_QueryInterface + }, + _generic_Delete, + _shader_GetType, + _generic_GetName, + _generic_GetDeleteStatus, + _generic_GetInfoLog + }, + _vertex_shader_GetSubType, + _shader_GetCompileStatus, + _shader_SetSource, + _shader_GetSource, + _shader_Compile + } +}; + +static void +_vertex_shader_constructor (struct gl2_vertex_shader_impl *impl) +{ + _shader_constructor ((struct gl2_shader_impl *) impl); + impl->_vftbl = &_vertex_shader_vftbl; + impl->_obj._shader._generic._unknown._destructor = _vertex_shader_destructor; +#if USE_3DLABS_FRONTEND + impl->_obj._shader._3dlabs_shhandle._obj.handle = ShConstructCompiler (EShLangVertex, 0); +#endif +} + +GLhandleARB +_mesa_3dlabs_create_shader_object (GLenum shaderType) +{ + switch (shaderType) + { + case GL_FRAGMENT_SHADER_ARB: + { + struct gl2_fragment_shader_impl *x = (struct gl2_fragment_shader_impl *) + _mesa_malloc (sizeof (struct gl2_fragment_shader_impl)); + + if (x != NULL) + { + _fragment_shader_constructor (x); + return x->_obj._shader._generic.name; + } + } + break; + case GL_VERTEX_SHADER_ARB: + { + struct gl2_vertex_shader_impl *x = (struct gl2_vertex_shader_impl *) + _mesa_malloc (sizeof (struct gl2_vertex_shader_impl)); + + if (x != NULL) + { + _vertex_shader_constructor (x); + return x->_obj._shader._generic.name; + } + } + break; + } + + return 0; +} + +GLhandleARB +_mesa_3dlabs_create_program_object (void) +{ + struct gl2_program_impl *x = (struct gl2_program_impl *) + _mesa_malloc (sizeof (struct gl2_program_impl)); + + if (x != NULL) + { + _program_constructor (x); + return x->_obj._container._generic.name; + } + + return 0; +} + +void +_mesa_init_shaderobjects_3dlabs (GLcontext *ctx) +{ +#if USE_3DLABS_FRONTEND + _glslang_3dlabs_InitProcess (); + _glslang_3dlabs_ShInitialize (); +#endif +} + diff --git a/nx-X11/extras/Mesa/src/mesa/shader/shaderobjects_3dlabs.h b/nx-X11/extras/Mesa/src/mesa/shader/shaderobjects_3dlabs.h new file mode 100644 index 000000000..5deff2f6a --- /dev/null +++ b/nx-X11/extras/Mesa/src/mesa/shader/shaderobjects_3dlabs.h @@ -0,0 +1,40 @@ +/* + * Mesa 3-D graphics library + * Version: 6.3 + * + * Copyright (C) 2005 Brian Paul All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN + * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#ifndef SHADEROBJECTS_3DLABS_H +#define SHADEROBJECTS_3DLABS_H + +#include "mtypes.h" + +extern GLhandleARB +_mesa_3dlabs_create_shader_object (GLenum); + +extern GLhandleARB +_mesa_3dlabs_create_program_object (void); + +extern void +_mesa_init_shaderobjects_3dlabs (GLcontext *ctx); + +#endif + diff --git a/nx-X11/extras/Mesa/src/mesa/shader/slang/library/slang_common_builtin_gc.h b/nx-X11/extras/Mesa/src/mesa/shader/slang/library/slang_common_builtin_gc.h new file mode 100644 index 000000000..cd9d9ac7d --- /dev/null +++ b/nx-X11/extras/Mesa/src/mesa/shader/slang/library/slang_common_builtin_gc.h @@ -0,0 +1,1410 @@ +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"const int gl_MaxLights = 8;\n" +"const int gl_MaxClipPlanes = 6;\n" +"const int gl_MaxTextureUnits = 2;\n" +"const int gl_MaxTextureCoords = 2;\n" +"const int gl_MaxVertexAttribs = 16;\n" +"const int gl_MaxVertexUniformComponents = 512;\n" +"const int gl_MaxVaryingFloats = 32;\n" +"const int gl_MaxVertexTextureImageUnits = 0;\n" +"const int gl_MaxCombinedTextureImageUnits = 2;\n" +"const int gl_MaxTextureImageUnits = 2;\n" +"const int gl_MaxFragmentUniformComponents = 64;\n" +"const int gl_MaxDrawBuffers = 1;\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"uniform mat4 gl_ModelViewMatrix;\n" +"uniform mat4 gl_ProjectionMatrix;\n" +"uniform mat4 gl_ModelViewProjectionMatrix;\n" +"uniform mat4 gl_TextureMatrix[gl_MaxTextureCoords];\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"uniform mat3 gl_NormalMatrix;\n" +"\n" +"\n" +"uniform mat4 gl_ModelViewMatrixInverse;\n" +"uniform mat4 gl_ProjectionMatrixInverse;\n" +"uniform mat4 gl_ModelViewProjectionMatrixInverse;\n" +"uniform mat4 gl_TextureMatrixInverse[gl_MaxTextureCoords];\n" +"\n" +"uniform mat4 gl_ModelViewMatrixTranspose;\n" +"uniform mat4 gl_ProjectionMatrixTranspose;\n" +"uniform mat4 gl_ModelViewProjectionMatrixTranspose;\n" +"uniform mat4 gl_TextureMatrixTranspose[gl_MaxTextureCoords];\n" +"\n" +"uniform mat4 gl_ModelViewMatrixInverseTranspose;\n" +"uniform mat4 gl_ProjectionMatrixInverseTranspose;\n" +"uniform mat4 gl_ModelViewProjectionMatrixInverseTranspose;\n" +"uniform mat4 gl_TextureMatrixInverseTranspose[gl_MaxTextureCoords];\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"uniform float gl_NormalScale;\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"struct gl_DepthRangeParameters {\n" +" float near;\n" +" float far;\n" +" float diff;\n" +"};\n" +"\n" +"uniform gl_DepthRangeParameters gl_DepthRange;\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"uniform vec4 gl_ClipPlane[gl_MaxClipPlanes];\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"struct gl_PointParameters {\n" +" float size;\n" +" float sizeMin;\n" +" float sizeMax;\n" +" float fadeThresholdSize;\n" +" float distanceConstantAttenuation;\n" +" float distanceLinearAttenuation;\n" +" float distanceQuadraticAttenuation;\n" +"};\n" +"\n" +"uniform gl_PointParameters gl_Point;\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"struct gl_MaterialParameters {\n" +" vec4 emission;\n" +" vec4 ambient;\n" +" vec4 diffuse;\n" +" vec4 specular;\n" +" float shininess;\n" +"};\n" +"\n" +"uniform gl_MaterialParameters gl_FrontMaterial;\n" +"uniform gl_MaterialParameters gl_BackMaterial;\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"struct gl_LightSourceParameters {\n" +" vec4 ambient;\n" +" vec4 diffuse;\n" +" vec4 specular;\n" +" vec4 position;\n" +" vec4 halfVector;\n" +" vec3 spotDirection;\n" +" float spotExponent;\n" +" float spotCutoff;\n" +"\n" +" float spotCosCutoff;\n" +"\n" +" float constantAttenuation;\n" +" float linearAttenuation;\n" +" float quadraticAttenuation;\n" +"};\n" +"\n" +"uniform gl_LightSourceParameters gl_LightSource[gl_MaxLights];\n" +"\n" +"struct gl_LightModelParameters {\n" +" vec4 ambient;\n" +"};\n" +"\n" +"uniform gl_LightModelParameters gl_LightModel;\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"struct gl_LightModelProducts {\n" +" vec4 sceneColor;\n" +"};\n" +"\n" +"uniform gl_LightModelProducts gl_FrontLightModelProduct;\n" +"uniform gl_LightModelProducts gl_BackLightModelProduct;\n" +"\n" +"struct gl_LightProducts {\n" +" vec4 ambient;\n" +" vec4 diffuse;\n" +" vec4 specular;\n" +"};\n" +"\n" +"uniform gl_LightProducts gl_FrontLightProduct[gl_MaxLights];\n" +"uniform gl_LightProducts gl_BackLightProduct[gl_MaxLights];\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"uniform vec4 gl_TextureEnvColor[gl_MaxTextureImageUnits];\n" +"uniform vec4 gl_EyePlaneS[gl_MaxTextureCoords];\n" +"uniform vec4 gl_EyePlaneT[gl_MaxTextureCoords];\n" +"uniform vec4 gl_EyePlaneR[gl_MaxTextureCoords];\n" +"uniform vec4 gl_EyePlaneQ[gl_MaxTextureCoords];\n" +"uniform vec4 gl_ObjectPlaneS[gl_MaxTextureCoords];\n" +"uniform vec4 gl_ObjectPlaneT[gl_MaxTextureCoords];\n" +"uniform vec4 gl_ObjectPlaneR[gl_MaxTextureCoords];\n" +"uniform vec4 gl_ObjectPlaneQ[gl_MaxTextureCoords];\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"struct gl_FogParameters {\n" +" vec4 color;\n" +" float density;\n" +" float start;\n" +" float end;\n" +" float scale;\n" +"};\n" +"\n" +"uniform gl_FogParameters gl_Fog;\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"float radians (float deg) {\n" +" return 3.141593 * deg / 180.0;\n" +"}\n" +"vec2 radians (vec2 deg) {\n" +" return vec2 (radians (deg.x), radians (deg.y));\n" +"}\n" +"vec3 radians (vec3 deg) {\n" +" return vec3 (radians (deg.x), radians (deg.y), radians (deg.z));\n" +"}\n" +"vec4 radians (vec4 deg) {\n" +" return vec4 (radians (deg.x), radians (deg.y), radians (deg.z), radians (deg.w));\n" +"}\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"float degrees (float rad) {\n" +" return 180.0 * rad / 3.141593;\n" +"}\n" +"vec2 degrees (vec2 rad) {\n" +" return vec2 (degrees (rad.x), degrees (rad.y));\n" +"}\n" +"vec3 degrees (vec3 rad) {\n" +" return vec3 (degrees (rad.x), degrees (rad.y), degrees (rad.z));\n" +"}\n" +"vec4 degrees (vec4 rad) {\n" +" return vec4 (degrees (rad.x), degrees (rad.y), degrees (rad.z), degrees (rad.w));\n" +"}\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"float sin (float angle) {\n" +" return 0.0;\n" +"}\n" +"vec2 sin (vec2 angle) {\n" +" return vec2 (sin (angle.x), sin (angle.y));\n" +"}\n" +"vec3 sin (vec3 angle) {\n" +" return vec3 (sin (angle.x), sin (angle.y), sin (angle.z));\n" +"}\n" +"vec4 sin (vec4 angle) {\n" +" return vec4 (sin (angle.x), sin (angle.y), sin (angle.z), sin (angle.w));\n" +"}\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"float cos (float angle) {\n" +" return sin (angle + 1.5708);\n" +"}\n" +"vec2 cos (vec2 angle) {\n" +" return vec2 (cos (angle.x), cos (angle.y));\n" +"}\n" +"vec3 cos (vec3 angle) {\n" +" return vec3 (cos (angle.x), cos (angle.y), cos (angle.z));\n" +"}\n" +"vec4 cos (vec4 angle) {\n" +" return vec4 (cos (angle.x), cos (angle.y), cos (angle.z), cos (angle.w));\n" +"}\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"float tan (float angle) {\n" +" return sin (angle) / cos (angle);\n" +"}\n" +"vec2 tan (vec2 angle) {\n" +" return vec2 (tan (angle.x), tan (angle.y));\n" +"}\n" +"vec3 tan (vec3 angle) {\n" +" return vec3 (tan (angle.x), tan (angle.y), tan (angle.z));\n" +"}\n" +"vec4 tan (vec4 angle) {\n" +" return vec4 (tan (angle.x), tan (angle.y), tan (angle.z), tan (angle.w));\n" +"}\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"float asin (float x) {\n" +" return 0.0;\n" +"}\n" +"vec2 asin (vec2 x) {\n" +" return vec2 (asin (x.x), asin (x.y));\n" +"}\n" +"vec3 asin (vec3 x) {\n" +" return vec3 (asin (x.x), asin (x.y), asin (x.z));\n" +"}\n" +"vec4 asin (vec4 x) {\n" +" return vec4 (asin (x.x), asin (x.y), asin (x.z), asin (x.w));\n" +"}\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"float acos (float x) {\n" +" return 0.0;\n" +"}\n" +"vec2 acos (vec2 x) {\n" +" return vec2 (acos (x.x), acos (x.y));\n" +"}\n" +"vec3 acos (vec3 x) {\n" +" return vec3 (acos (x.x), acos (x.y), acos (x.z));\n" +"}\n" +"vec4 acos (vec4 x) {\n" +" return vec4 (acos (x.x), acos (x.y), acos (x.z), acos (x.w));\n" +"}\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"float atan (float x, float y) {\n" +" return 0.0;\n" +"}\n" +"vec2 atan (vec2 x, vec2 y) {\n" +" return vec2 (atan (x.x, y.x), atan (x.y, y.y));\n" +"}\n" +"vec3 atan (vec3 x, vec3 y) {\n" +" return vec3 (atan (x.x, y.x), atan (x.y, y.y), atan (x.z, y.z));\n" +"}\n" +"vec4 atan (vec4 x, vec4 y) {\n" +" return vec4 (atan (x.x, y.x), atan (x.y, y.y), atan (x.z, y.z), atan (x.w, y.w));\n" +"}\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"float atan (float y_over_x) {\n" +" return 0.0;\n" +"}\n" +"vec2 atan (vec2 y_over_x) {\n" +" return vec2 (atan (y_over_x.x), atan (y_over_x.y));\n" +"}\n" +"vec3 atan (vec3 y_over_x) {\n" +" return vec3 (atan (y_over_x.x), atan (y_over_x.y), atan (y_over_x.z));\n" +"}\n" +"vec4 atan (vec4 y_over_x) {\n" +" return vec4 (atan (y_over_x.x), atan (y_over_x.y), atan (y_over_x.z), atan (y_over_x.w));\n" +"}\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"float pow (float x, float y) {\n" +" return 0.0;\n" +"}\n" +"vec2 pow (vec2 x, vec2 y) {\n" +" return vec2 (pow (x.x, y.x), pow (x.y, y.y));\n" +"}\n" +"vec3 pow (vec3 x, vec3 y) {\n" +" return vec3 (pow (x.x, y.x), pow (x.y, y.y), pow (x.z, y.z));\n" +"}\n" +"vec4 pow (vec4 x, vec4 y) {\n" +" return vec4 (pow (x.x, y.x), pow (x.y, y.y), pow (x.z, y.z), pow (x.w, y.w));\n" +"}\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"float exp (float x) {\n" +" return pow (2.71828183, x);\n" +"}\n" +"vec2 exp (vec2 x) {\n" +" return vec2 (exp (x.x), exp (x.y));\n" +"}\n" +"vec3 exp (vec3 x) {\n" +" return vec3 (exp (x.x), exp (x.y), exp (x.z));\n" +"}\n" +"vec4 exp (vec4 x) {\n" +" return vec4 (exp (x.x), exp (x.y), exp (x.z), exp (x.w));\n" +"}\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"float log (float x) {\n" +" return log2 (x) / log2 (2.71828183);\n" +"}\n" +"vec2 log (vec2 x) {\n" +" return vec2 (log (x.x), log (x.y));\n" +"}\n" +"vec3 log (vec3 x) {\n" +" return vec3 (log (x.x), log (x.y), log (x.z));\n" +"}\n" +"vec4 log (vec4 x) {\n" +" return vec4 (log (x.x), log (x.y), log (x.z), log (x.w));\n" +"}\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"float exp2 (float x) {\n" +" return pow (2.0, x);\n" +"}\n" +"vec2 exp2 (vec2 x) {\n" +" return vec2 (exp2 (x.x), exp2 (x.y));\n" +"}\n" +"vec3 exp2 (vec3 x) {\n" +" return vec3 (exp2 (x.x), exp2 (x.y), exp2 (x.z));\n" +"}\n" +"vec4 exp2 (vec4 x) {\n" +" return vec4 (exp2 (x.x), exp2 (x.y), exp2 (x.z), exp2 (x.w));\n" +"}\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"float log2 (float x) {\n" +" return 0.0;\n" +"}\n" +"vec2 log2 (vec2 x) {\n" +" return vec2 (log2 (x.x), log2 (x.y));\n" +"}\n" +"vec3 log2 (vec3 x) {\n" +" return vec3 (log2 (x.x), log2 (x.y), log2 (x.z));\n" +"}\n" +"vec4 log2 (vec4 x) {\n" +" return vec4 (log2 (x.x), log2 (x.y), log2 (x.z), log2 (x.w));\n" +"}\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"float sqrt (float x) {\n" +" return pow (x, 0.5);\n" +"}\n" +"vec2 sqrt (vec2 x) {\n" +" return vec2 (sqrt (x.x), sqrt (x.y));\n" +"}\n" +"vec3 sqrt (vec3 x) {\n" +" return vec3 (sqrt (x.x), sqrt (x.y), sqrt (x.z));\n" +"}\n" +"vec4 sqrt (vec4 x) {\n" +" return vec4 (sqrt (x.x), sqrt (x.y), sqrt (x.z), sqrt (x.w));\n" +"}\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"float inversesqrt (float x) {\n" +" return 1.0 / sqrt (x);\n" +"}\n" +"vec2 inversesqrt (vec2 x) {\n" +" return vec2 (inversesqrt (x.x), inversesqrt (x.y));\n" +"}\n" +"vec3 inversesqrt (vec3 x) {\n" +" return vec3 (inversesqrt (x.x), inversesqrt (x.y), inversesqrt (x.z));\n" +"}\n" +"vec4 inversesqrt (vec4 x) {\n" +" return vec4 (inversesqrt (x.x), inversesqrt (x.y), inversesqrt (x.z), inversesqrt (x.w));\n" +"}\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"float abs (float x) {\n" +" return x >= 0.0 ? x : -x;\n" +"}\n" +"vec2 abs (vec2 x) {\n" +" return vec2 (abs (x.x), abs (x.y));\n" +"}\n" +"vec3 abs (vec3 x) {\n" +" return vec3 (abs (x.x), abs (x.y), abs (x.z));\n" +"}\n" +"vec4 abs (vec4 x) {\n" +" return vec4 (abs (x.x), abs (x.y), abs (x.z), abs (x.w));\n" +"}\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"float sign (float x) {\n" +" return x > 0.0 ? 1.0 : x < 0.0 ? -1.0 : 0.0;\n" +"}\n" +"vec2 sign (vec2 x) {\n" +" return vec2 (sign (x.x), sign (x.y));\n" +"}\n" +"vec3 sign (vec3 x) {\n" +" return vec3 (sign (x.x), sign (x.y), sign (x.z));\n" +"}\n" +"vec4 sign (vec4 x) {\n" +" return vec4 (sign (x.x), sign (x.y), sign (x.z), sign (x.w));\n" +"}\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"float floor (float x) {\n" +" return 0.0;\n" +"}\n" +"vec2 floor (vec2 x) {\n" +" return vec2 (floor (x.x), floor (x.y));\n" +"}\n" +"vec3 floor (vec3 x) {\n" +" return vec3 (floor (x.x), floor (x.y), floor (x.z));\n" +"}\n" +"vec4 floor (vec4 x) {\n" +" return vec4 (floor (x.x), floor (x.y), floor (x.z), floor (x.w));\n" +"}\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"float ceil (float x) {\n" +" return 0.0;\n" +"}\n" +"vec2 ceil (vec2 x) {\n" +" return vec2 (ceil (x.x), ceil (x.y));\n" +"}\n" +"vec3 ceil (vec3 x) {\n" +" return vec3 (ceil (x.x), ceil (x.y), ceil (x.z));\n" +"}\n" +"vec4 ceil (vec4 x) {\n" +" return vec4 (ceil (x.x), ceil (x.y), ceil (x.z), ceil (x.w));\n" +"}\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"float fract (float x) {\n" +" return x - floor (x);\n" +"}\n" +"vec2 fract (vec2 x) {\n" +" return vec2 (fract (x.x), fract (x.y));\n" +"}\n" +"vec3 fract (vec3 x) {\n" +" return vec3 (fract (x.x), fract (x.y), fract (x.z));\n" +"}\n" +"vec4 fract (vec4 x) {\n" +" return vec4 (fract (x.x), fract (x.y), fract (x.z), fract (x.w));\n" +"}\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"float mod (float x, float y) {\n" +" return x - y * floor (x / y);\n" +"}\n" +"vec2 mod (vec2 x, float y) {\n" +" return vec2 (mod (x.x, y), mod (x.y, y));\n" +"}\n" +"vec3 mod (vec3 x, float y) {\n" +" return vec3 (mod (x.x, y), mod (x.y, y), mod (x.z, y));\n" +"}\n" +"vec4 mod (vec4 x, float y) {\n" +" return vec4 (mod (x.x, y), mod (x.y, y), mod (x.z, y), mod (x.w, y));\n" +"}\n" +"vec2 mod (vec2 x, vec2 y) {\n" +" return vec2 (mod (x.x, y.x), mod (x.y, y.y));\n" +"}\n" +"vec3 mod (vec3 x, vec3 y) {\n" +" return vec3 (mod (x.x, y.x), mod (x.y, y.y), mod (x.z, y.z));\n" +"}\n" +"vec4 mod (vec4 x, vec4 y) {\n" +" return vec4 (mod (x.x, y.x), mod (x.y, y.y), mod (x.z, y.z), mod (x.w, y.w));\n" +"}\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"float min (float x, float y) {\n" +" return y < x ? y : x;\n" +"}\n" +"vec2 min (vec2 x, float y) {\n" +" return vec2 (min (x.x, y), min (x.y, y));\n" +"}\n" +"vec3 min (vec3 x, float y) {\n" +" return vec3 (min (x.x, y), min (x.y, y), min (x.z, y));\n" +"}\n" +"vec4 min (vec4 x, float y) {\n" +" return vec4 (min (x.x, y), min (x.y, y), min (x.z, y), min (x.w, y));\n" +"}\n" +"vec2 min (vec2 x, vec2 y) {\n" +" return vec2 (min (x.x, y.x), min (x.y, y.y));\n" +"}\n" +"vec3 min (vec3 x, vec3 y) {\n" +" return vec3 (min (x.x, y.x), min (x.y, y.y), min (x.z, y.z));\n" +"}\n" +"vec4 min (vec4 x, vec4 y) {\n" +" return vec4 (min (x.x, y.x), min (x.y, y.y), min (x.z, y.z), min (x.w, y.w));\n" +"}\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"float max (float x, float y) {\n" +" return min (y, x);\n" +"}\n" +"vec2 max (vec2 x, float y) {\n" +" return vec2 (max (x.x, y), max (x.y, y));\n" +"}\n" +"vec3 max (vec3 x, float y) {\n" +" return vec3 (max (x.x, y), max (x.y, y), max (x.z, y));\n" +"}\n" +"vec4 max (vec4 x, float y) {\n" +" return vec4 (max (x.x, y), max (x.y, y), max (x.z, y), max (x.w, y));\n" +"}\n" +"vec2 max (vec2 x, vec2 y) {\n" +" return vec2 (max (x.x, y.x), max (x.y, y.y));\n" +"}\n" +"vec3 max (vec3 x, vec3 y) {\n" +" return vec3 (max (x.x, y.x), max (x.y, y.y), max (x.z, y.z));\n" +"}\n" +"vec4 max (vec4 x, vec4 y) {\n" +" return vec4 (max (x.x, y.x), max (x.y, y.y), max (x.z, y.z), max (x.w, y.w));\n" +"}\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"float clamp (float x, float minVal, float maxVal) {\n" +" return min (max (x, minVal), maxVal);\n" +"}\n" +"vec2 clamp (vec2 x, float minVal, float maxVal) {\n" +" return vec2 (clamp (x.x, minVal, maxVal), clamp (x.y, minVal, maxVal));\n" +"}\n" +"vec3 clamp (vec3 x, float minVal, float maxVal) {\n" +" return vec3 (clamp (x.x, minVal, maxVal), clamp (x.y, minVal, maxVal),\n" +" clamp (x.z, minVal, maxVal));\n" +"}\n" +"vec4 clamp (vec4 x, float minVal, float maxVal) {\n" +" return vec4 (clamp (x.x, minVal, maxVal), clamp (x.y, minVal, maxVal),\n" +" clamp (x.z, minVal, maxVal), clamp (x.w, minVal, maxVal));\n" +"}\n" +"vec2 clamp (vec2 x, vec2 minVal, vec2 maxVal) {\n" +" return vec2 (clamp (x.x, minVal.x, maxVal.x), clamp (x.y, minVal.y, maxVal.y));\n" +"}\n" +"vec3 clamp (vec3 x, vec3 minVal, vec3 maxVal) {\n" +" return vec3 (clamp (x.x, minVal.x, maxVal.x), clamp (x.y, minVal.y, maxVal.y),\n" +" clamp (x.z, minVal.z, maxVal.z));\n" +"}\n" +"vec4 clamp (vec4 x, vec4 minVal, vec4 maxVal) {\n" +" return vec4 (clamp (x.x, minVal.x, maxVal.y), clamp (x.y, minVal.y, maxVal.y),\n" +" clamp (x.z, minVal.z, maxVal.z), clamp (x.w, minVal.w, maxVal.w));\n" +"}\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"float mix (float x, float y, float a) {\n" +" return x * (1.0 - a) + y * a;\n" +"}\n" +"vec2 mix (vec2 x, vec2 y, float a) {\n" +" return vec2 (mix (x.x, y.x, a), mix (x.y, y.y, a));\n" +"}\n" +"vec3 mix (vec3 x, vec3 y, float a) {\n" +" return vec3 (mix (x.x, y.x, a), mix (x.y, y.y, a), mix (x.z, y.z, a));\n" +"}\n" +"vec4 mix (vec4 x, vec4 y, float a) {\n" +" return vec4 (mix (x.x, y.x, a), mix (x.y, y.y, a), mix (x.z, y.z, a), mix (x.w, y.w, a));\n" +"}\n" +"vec2 mix (vec2 x, vec2 y, vec2 a) {\n" +" return vec2 (mix (x.x, y.x, a.x), mix (x.y, y.y, a.y));\n" +"}\n" +"vec3 mix (vec3 x, vec3 y, vec3 a) {\n" +" return vec3 (mix (x.x, y.x, a.x), mix (x.y, y.y, a.y), mix (x.z, y.z, a.z));\n" +"}\n" +"vec4 mix (vec4 x, vec4 y, vec4 a) {\n" +" return vec4 (mix (x.x, y.x, a.x), mix (x.y, y.y, a.y), mix (x.z, y.z, a.z),\n" +" mix (x.w, y.w, a.w));\n" +"}\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"float step (float edge, float x) {\n" +" return x < edge ? 0.0 : 1.0;\n" +"}\n" +"vec2 step (float edge, vec2 x) {\n" +" return vec2 (step (edge, x.x), step (edge, x.y));\n" +"}\n" +"vec3 step (float edge, vec3 x) {\n" +" return vec3 (step (edge, x.x), step (edge, x.y), step (edge, x.z));\n" +"}\n" +"vec4 step (float edge, vec4 x) {\n" +" return vec4 (step (edge, x.x), step (edge, x.y), step (edge, x.z), step (edge, x.w));\n" +"}\n" +"vec2 step (vec2 edge, vec2 x) {\n" +" return vec2 (step (edge.x, x.x), step (edge.y, x.y));\n" +"}\n" +"vec3 step (vec3 edge, vec3 x) {\n" +" return vec3 (step (edge.x, x.x), step (edge.y, x.y), step (edge.z, x.z));\n" +"}\n" +"vec4 step (vec4 edge, vec4 x) {\n" +" return vec4 (step (edge.x, x.x), step (edge.y, x.y), step (edge.z, x.z), step (edge.w, x.w));\n" +"}\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"float smoothstep (float edge0, float edge1, float x) {\n" +" const float t = clamp ((x - edge0) / (edge1 - edge0), 0.0, 1.0);\n" +" return t * t * (3.0 - 2.0 * t);\n" +"}\n" +"vec2 smoothstep (float edge0, float edge1, vec2 x) {\n" +" return vec2 (smoothstep (edge0, edge1, x.x), smoothstep (edge0, edge1, x.y));\n" +"}\n" +"vec3 smoothstep (float edge0, float edge1, vec3 x) {\n" +" return vec3 (smoothstep (edge0, edge1, x.x), smoothstep (edge0, edge1, x.y),\n" +" smoothstep (edge0, edge1, x.z));\n" +"}\n" +"vec4 smoothstep (float edge0, float edge1, vec4 x) {\n" +" return vec4 (smoothstep (edge0, edge1, x.x), smoothstep (edge0, edge1, x.y),\n" +" smoothstep (edge0, edge1, x.z), smoothstep (edge0, edge1, x.w));\n" +"}\n" +"vec2 smoothstep (vec2 edge0, vec2 edge1, vec2 x) {\n" +" return vec2 (smoothstep (edge0.x, edge1.x, x.x), smoothstep (edge0.y, edge1.y, x.y));\n" +"}\n" +"vec3 smoothstep (vec3 edge0, vec3 edge1, vec3 x) {\n" +" return vec3 (smoothstep (edge0.x, edge1.x, x.x), smoothstep (edge0.y, edge1.y, x.y),\n" +" smoothstep (edge0.z, edge1.z, x.z));\n" +"}\n" +"vec4 smoothstep (vec4 edge0, vec4 edge1, vec4 x) {\n" +" return vec4 (smoothstep (edge0.x, edge1.x, x.x), smoothstep (edge0.y, edge1.y, x.y),\n" +" smoothstep (edge0.z, edge1.z, x.z), smoothstep (edge0.w, edge1.w, x.w));\n" +"}\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"float dot (float x, float y) {\n" +" return x * y;\n" +"}\n" +"float dot (vec2 x, vec2 y) {\n" +" return dot (x.x, y.x) + dot (x.y, y.y);\n" +"}\n" +"float dot (vec3 x, vec3 y) {\n" +" return dot (x.x, y.x) + dot (x.y, y.y) + dot (x.z, y.z);\n" +"}\n" +"float dot (vec4 x, vec4 y) {\n" +" return dot (x.x, y.x) + dot (x.y, y.y) + dot (x.z, y.z) + dot (x.w, y.w);\n" +"}\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"float length (float x) {\n" +" return sqrt (dot (x, x));\n" +"}\n" +"float length (vec2 x) {\n" +" return sqrt (dot (x, x));\n" +"}\n" +"float length (vec3 x) {\n" +" return sqrt (dot (x, x));\n" +"}\n" +"float length (vec4 x) {\n" +" return sqrt (dot (x, x));\n" +"}\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"float distance (float x, float y) {\n" +" return length (x - y);\n" +"}\n" +"float distance (vec2 x, vec2 y) {\n" +" return length (x - y);\n" +"}\n" +"float distance (vec3 x, vec3 y) {\n" +" return length (x - y);\n" +"}\n" +"float distance (vec4 x, vec4 y) {\n" +" return length (x - y);\n" +"}\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"vec3 cross (vec3 x, vec3 y) {\n" +" return vec3 (x.y * y.z - y.y * x.z, x.z * y.x - y.z * x.x, x.x * y.y - y.x * x.y);\n" +"}\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"float normalize (float x) {\n" +" return 1.0;\n" +"}\n" +"vec2 normalize (vec2 x) {\n" +" return x / length (x);\n" +"}\n" +"vec3 normalize (vec3 x) {\n" +" return x / length (x);\n" +"}\n" +"vec4 normalize (vec4 x) {\n" +" return x / length (x);\n" +"}\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"float faceforward (float N, float I, float Nref) {\n" +" return dot (Nref, I) < 0.0 ? N : -N;\n" +"}\n" +"vec2 faceforward (vec2 N, vec2 I, vec2 Nref) {\n" +" return dot (Nref, I) < 0.0 ? N : -N;\n" +"}\n" +"vec3 faceforward (vec3 N, vec3 I, vec3 Nref) {\n" +" return dot (Nref, I) < 0.0 ? N : -N;\n" +"}\n" +"vec4 faceforward (vec4 N, vec4 I, vec4 Nref) {\n" +" return dot (Nref, I) < 0.0 ? N : -N;\n" +"}\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"float reflect (float I, float N) {\n" +" return I - 2.0 * dot (N, I) * N;\n" +"}\n" +"vec2 reflect (vec2 I, vec2 N) {\n" +" return I - 2.0 * dot (N, I) * N;\n" +"}\n" +"vec3 reflect (vec3 I, vec3 N) {\n" +" return I - 2.0 * dot (N, I) * N;\n" +"}\n" +"vec4 reflect (vec4 I, vec4 N) {\n" +" return I - 2.0 * dot (N, I) * N;\n" +"}\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"float refract (float I, float N, float eta) {\n" +" const float k = 1.0 - eta * eta * (1.0 - dot (N, I) * dot (N, I));\n" +" if (k < 0.0)\n" +" return 0.0;\n" +" return eta * I - (eta * dot (N, I) + sqrt (k)) * N;\n" +"}\n" +"vec2 refract (vec2 I, vec2 N, float eta) {\n" +" const float k = 1.0 - eta * eta * (1.0 - dot (N, I) * dot (N, I));\n" +" if (k < 0.0)\n" +" return vec2 (0.0);\n" +" return eta * I - (eta * dot (N, I) + sqrt (k)) * N;\n" +"}\n" +"vec3 refract (vec3 I, vec3 N, float eta) {\n" +" const float k = 1.0 - eta * eta * (1.0 - dot (N, I) * dot (N, I));\n" +" if (k < 0.0)\n" +" return vec3 (0.0);\n" +" return eta * I - (eta * dot (N, I) + sqrt (k)) * N;\n" +"}\n" +"vec4 refract (vec4 I, vec4 N, float eta) {\n" +" const float k = 1.0 - eta * eta * (1.0 - dot (N, I) * dot (N, I));\n" +" if (k < 0.0)\n" +" return vec4 (0.0);\n" +" return eta * I - (eta * dot (N, I) + sqrt (k)) * N;\n" +"}\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"mat2 matrixCompMult (mat2 x, mat2 y) {\n" +" return mat2 (\n" +" x[0].x * y[0].x, x[0].y * y[0].y,\n" +" x[1].x * y[1].x, x[1].y * y[1].y\n" +" );\n" +"}\n" +"mat3 matrixCompMult (mat3 x, mat3 y) {\n" +" return mat4 (\n" +" x[0].x * y[0].x, x[0].y * y[0].y, x[0].z * y[0].z,\n" +" x[1].x * y[1].x, x[1].y * y[1].y, x[1].z * y[1].z,\n" +" x[2].x * y[2].x, x[2].y * y[2].y, x[2].z * y[2].z\n" +" );\n" +"}\n" +"mat4 matrixCompMult (mat4 x, mat4 y) {\n" +" return mat4 (\n" +" x[0].x * y[0].x, x[0].y * y[0].y, x[0].z * y[0].z + x[0].w * y[0].w,\n" +" x[1].x * y[1].x, x[1].y * y[1].y, x[1].z * y[1].z + x[1].w * y[1].w,\n" +" x[2].x * y[2].x, x[2].y * y[2].y, x[2].z * y[2].z + x[2].w * y[2].w,\n" +" x[3].x * y[3].x, x[3].y * y[3].y, x[3].z * y[3].z + x[3].w * y[3].w\n" +" );\n" +"}\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"bvec2 lessThan (vec2 x, vec2 y) {\n" +" return bvec2 (x.x < y.x, x.y < y.y);\n" +"}\n" +"bvec3 lessThan (vec3 x, vec3 y) {\n" +" return bvec3 (x.x < y.x, x.y < y.y, x.z < y.z);\n" +"}\n" +"bvec4 lessThan (vec4 x, vec4 y) {\n" +" return bvec4 (x.x < y.x, x.y < y.y, x.z < y.z, x.w < y.w);\n" +"}\n" +"bvec2 lessThan (ivec2 x, ivec2 y) {\n" +" return bvec2 (x.x < y.x, x.y < y.y);\n" +"}\n" +"bvec3 lessThan (ivec3 x, ivec3 y) {\n" +" return bvec3 (x.x < y.x, x.y < y.y, x.z < y.z);\n" +"}\n" +"bvec4 lessThan (ivec4 x, ivec4 y) {\n" +" return bvec4 (x.x < y.x, x.y < y.y, x.z < y.z, x.w < y.w);\n" +"}\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"bvec2 lessThanEqual (vec2 x, vec2 y) {\n" +" return bvec2 (x.x <= y.x, x.y <= y.y);\n" +"}\n" +"bvec3 lessThanEqual (vec3 x, vec3 y) {\n" +" return bvec3 (x.x <= y.x, x.y <= y.y, x.z <= y.z);\n" +"}\n" +"bvec4 lessThanEqual (vec4 x, vec4 y) {\n" +" return bvec4 (x.x <= y.x, x.y <= y.y, x.z <= y.z, x.w <= y.w);\n" +"}\n" +"bvec2 lessThanEqual (ivec2 x, ivec2 y) {\n" +" return bvec2 (x.x <= y.x, x.y <= y.y);\n" +"}\n" +"bvec3 lessThanEqual (ivec3 x, ivec3 y) {\n" +" return bvec3 (x.x <= y.x, x.y <= y.y, x.z <= y.z);\n" +"}\n" +"bvec4 lessThanEqual (ivec4 x, ivec4 y) {\n" +" return bvec4 (x.x <= y.x, x.y <= y.y, x.z <= y.z, x.w <= y.w);\n" +"}\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"bvec2 greaterThan (vec2 x, vec2 y) {\n" +" return bvec2 (x.x > y.x, x.y > y.y);\n" +"}\n" +"bvec3 greaterThan (vec3 x, vec3 y) {\n" +" return bvec3 (x.x > y.x, x.y > y.y, x.z > y.z);\n" +"}\n" +"bvec4 greaterThan (vec4 x, vec4 y) {\n" +" return bvec4 (x.x > y.x, x.y > y.y, x.z > y.z, x.w > y.w);\n" +"}\n" +"bvec2 greaterThan (ivec2 x, ivec2 y) {\n" +" return bvec2 (x.x > y.x, x.y > y.y);\n" +"}\n" +"bvec3 greaterThan (ivec3 x, ivec3 y) {\n" +" return bvec3 (x.x > y.x, x.y > y.y, x.z > y.z);\n" +"}\n" +"bvec4 greaterThan (ivec4 x, ivec4 y) {\n" +" return bvec4 (x.x > y.x, x.y > y.y, x.z > y.z, x.w > y.w);\n" +"}\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"bvec2 greaterThanEqual (vec2 x, vec2 y) {\n" +" return bvec2 (x.x >= y.x, x.y >= y.y);\n" +"}\n" +"bvec3 greaterThanEqual (vec3 x, vec3 y) {\n" +" return bvec3 (x.x >= y.x, x.y >= y.y, x.z >= y.z);\n" +"}\n" +"bvec4 greaterThanEqual (vec4 x, vec4 y) {\n" +" return bvec4 (x.x >= y.x, x.y >= y.y, x.z >= y.z, x.w >= y.w);\n" +"}\n" +"bvec2 greaterThanEqual (ivec2 x, ivec2 y) {\n" +" return bvec2 (x.x >= y.x, x.y >= y.y);\n" +"}\n" +"bvec3 greaterThanEqual (ivec3 x, ivec3 y) {\n" +" return bvec3 (x.x >= y.x, x.y >= y.y, x.z >= y.z);\n" +"}\n" +"bvec4 greaterThanEqual (ivec4 x, ivec4 y) {\n" +" return bvec4 (x.x >= y.x, x.y >= y.y, x.z >= y.z, x.w >= y.w);\n" +"}\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"bvec2 equal (vec2 x, vec2 y) {\n" +" return bvec2 (x.x == y.x, x.y == y.y);\n" +"}\n" +"bvec3 equal (vec3 x, vec3 y) {\n" +" return bvec3 (x.x == y.x, x.y == y.y, x.z == y.z);\n" +"}\n" +"bvec4 equal (vec4 x, vec4 y) {\n" +" return bvec4 (x.x == y.x, x.y == y.y, x.z == y.z, x.w == y.w);\n" +"}\n" +"bvec2 equal (ivec2 x, ivec2 y) {\n" +" return bvec2 (x.x == y.x, x.y == y.y);\n" +"}\n" +"bvec3 equal (ivec3 x, ivec3 y) {\n" +" return bvec3 (x.x == y.x, x.y == y.y, x.z == y.z);\n" +"}\n" +"bvec4 equal (ivec4 x, ivec4 y) {\n" +" return bvec4 (x.x == y.x, x.y == y.y, x.z == y.z, x.w == y.w);\n" +"}\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"bvec2 notEqual (vec2 x, vec2 y) {\n" +" return bvec2 (x.x != y.x, x.y != y.y);\n" +"}\n" +"bvec3 notEqual (vec3 x, vec3 y) {\n" +" return bvec3 (x.x != y.x, x.y != y.y, x.z != y.z);\n" +"}\n" +"bvec4 notEqual (vec4 x, vec4 y) {\n" +" return bvec4 (x.x != y.x, x.y != y.y, x.z != y.z, x.w != y.w);\n" +"}\n" +"bvec2 notEqual (ivec2 x, ivec2 y) {\n" +" return bvec2 (x.x != y.x, x.y != y.y);\n" +"}\n" +"bvec3 notEqual (ivec3 x, ivec3 y) {\n" +" return bvec3 (x.x != y.x, x.y != y.y, x.z != y.z);\n" +"}\n" +"bvec4 notEqual (ivec4 x, ivec4 y) {\n" +" return bvec4 (x.x != y.x, x.y != y.y, x.z != y.z, x.w != y.w);\n" +"}\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"bool any (bvec2 x) {\n" +" return x.x || x.y;\n" +"}\n" +"bool any (bvec3 x) {\n" +" return x.x || x.y || x.z;\n" +"}\n" +"bool any (bvec4 x) {\n" +" return x.x || x.y || x.z || x.w;\n" +"}\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"bool all (bvec2 x) {\n" +" return x.x && x.y;\n" +"}\n" +"bool all (bvec3 x) {\n" +" return x.x && x.y && x.z;\n" +"}\n" +"bool all (bvec4 x) {\n" +" return x.x && x.y && x.z && x.w;\n" +"}\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"bvec2 not (bvec2 x) {\n" +" return bvec2 (!x.x, !x.y);\n" +"}\n" +"bvec3 not (bvec3 x) {\n" +" return bvec3 (!x.x, !x.y, !x.z);\n" +"}\n" +"bvec4 not (bvec4 x) {\n" +" return bvec4 (!x.x, !x.y, !x.z, !x.w);\n" +"}\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"vec4 texture1D (sampler1D sampler, float coord) {\n" +" return vec4 (0.0);\n" +"}\n" +"vec4 texture1DProj (sampler1D sampler, vec2 coord) {\n" +" return texture1D (sampler, coord.s / coord.t);\n" +"}\n" +"vec4 texture1DProj (sampler1D sampler, vec4 coord) {\n" +" return texture1D (sampler, coord.s / coord.q);\n" +"}\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"vec4 texture2D (sampler2D sampler, vec2 coord) {\n" +" return vec4 (0.0);\n" +"}\n" +"vec4 texture2DProj (sampler2D sampler, vec3 coord) {\n" +" return texture2D (sampler, vec2 (coord.s / coord.p, coord.t / coord.p));\n" +"}\n" +"vec4 texture2DProj (sampler2D sampler, vec4 coord) {\n" +" return texture2D (sampler, vec2 (coord.s / coord.q, coord.t / coord.q));\n" +"}\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"vec4 texture3D (sampler3D sampler, vec3 coord) {\n" +" return vec4 (0.0);\n" +"}\n" +"vec4 texture3DProj (sampler3D sampler, vec4 coord) {\n" +" return texture3D (sampler, vec3 (coord.s / coord.q, coord.t / coord.q, coord.p / coord.q));\n" +"}\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"vec4 textureCube (samplerCube sampler, vec3 coord) {\n" +" return vec4 (0.0);\n" +"}\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"vec4 shadow1D (sampler1DShadow sampler, vec3 coord) {\n" +" return vec4 (0.0);\n" +"}\n" +"\n" +"vec4 shadow2D (sampler2DShadow sampler, vec3 coord) {\n" +" return vec4 (0.0);\n" +"}\n" +"vec4 shadow1DProj (sampler1DShadow sampler, vec4 coord) {\n" +" return shadow1D (sampler, vec3 (coord.s / coord.q, 0.0, coord.p / coord.q));\n" +"}\n" +"vec4 shadow2DProj (sampler2DShadow sampler, vec4 coord) {\n" +" return shadow2D (sampler, vec3 (coord.s / coord.q, coord.t / coord.q, coord.p / coord.q));\n" +"}\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"float noise1 (float x) {\n" +" return 0.0;\n" +"}\n" +"\n" +"float noise1 (vec2 x) {\n" +" return 0.0;\n" +"}\n" +"\n" +"float noise1 (vec3 x) {\n" +" return 0.0;\n" +"}\n" +"\n" +"float noise1 (vec4 x) {\n" +" return 0.0;\n" +"}\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"vec2 noise2 (float x) {\n" +" return vec2 (0.0);\n" +"}\n" +"\n" +"vec2 noise2 (vec2 x) {\n" +" return vec2 (0.0);\n" +"}\n" +"\n" +"vec2 noise2 (vec3 x) {\n" +" return vec2 (0.0);\n" +"}\n" +"\n" +"vec2 noise2 (vec4 x) {\n" +" return vec2 (0.0);\n" +"}\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"vec3 noise3 (float x) {\n" +" return vec3 (0.0);\n" +"}\n" +"\n" +"vec3 noise3 (vec2 x) {\n" +" return vec3 (0.0);\n" +"}\n" +"\n" +"vec3 noise3 (vec3 x) {\n" +" return vec3 (0.0);\n" +"}\n" +"\n" +"vec3 noise3 (vec4 x) {\n" +" return vec3 (0.0);\n" +"}\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"vec4 noise4 (float x) {\n" +" return vec4 (0.0);\n" +"}\n" +"\n" +"vec4 noise4 (vec2 x) {\n" +" return vec4 (0.0);\n" +"}\n" +"\n" +"vec4 noise4 (vec3 x) {\n" +" return vec4 (0.0);\n" +"}\n" +"\n" +"vec4 noise4 (vec4 x) {\n" +" return vec4 (0.0);\n" +"}\n" +"\n" diff --git a/nx-X11/extras/Mesa/src/mesa/shader/slang/library/slang_common_builtin_gc_bin.h b/nx-X11/extras/Mesa/src/mesa/shader/slang/library/slang_common_builtin_gc_bin.h new file mode 100644 index 000000000..971229a92 --- /dev/null +++ b/nx-X11/extras/Mesa/src/mesa/shader/slang/library/slang_common_builtin_gc_bin.h @@ -0,0 +1,943 @@ +2,2,2,1,5,1,103,108,95,77,97,120,76,105,103,104,116,115,0,2,16,10,56,0, +0,0,2,2,1,5,1,103,108,95,77,97,120,67,108,105,112,80,108,97,110,101,115,0, +2,16,10,54,0,0,0,2,2,1,5,1,103,108,95,77,97,120,84,101,120,116,117,114, +101,85,110,105,116,115,0,2,16,10,50,0,0,0,2,2,1,5,1,103,108,95,77,97, +120,84,101,120,116,117,114,101,67,111,111,114,100,115,0,2,16,10,50,0,0,0,2,2, +1,5,1,103,108,95,77,97,120,86,101,114,116,101,120,65,116,116,114,105,98,115,0,2, +16,10,49,54,0,0,0,2,2,1,5,1,103,108,95,77,97,120,86,101,114,116,101,120, +85,110,105,102,111,114,109,67,111,109,112,111,110,101,110,116,115,0,2,16,10,53,49,50, +0,0,0,2,2,1,5,1,103,108,95,77,97,120,86,97,114,121,105,110,103,70,108,111, +97,116,115,0,2,16,10,51,50,0,0,0,2,2,1,5,1,103,108,95,77,97,120,86, +101,114,116,101,120,84,101,120,116,117,114,101,73,109,97,103,101,85,110,105,116,115,0,2, +16,8,48,0,0,0,2,2,1,5,1,103,108,95,77,97,120,67,111,109,98,105,110,101, +100,84,101,120,116,117,114,101,73,109,97,103,101,85,110,105,116,115,0,2,16,10,50,0, +0,0,2,2,1,5,1,103,108,95,77,97,120,84,101,120,116,117,114,101,73,109,97,103, +101,85,110,105,116,115,0,2,16,10,50,0,0,0,2,2,1,5,1,103,108,95,77,97, +120,70,114,97,103,109,101,110,116,85,110,105,102,111,114,109,67,111,109,112,111,110,101,110, +116,115,0,2,16,10,54,52,0,0,0,2,2,1,5,1,103,108,95,77,97,120,68,114, +97,119,66,117,102,102,101,114,115,0,2,16,10,49,0,0,0,2,2,4,15,1,103,108, +95,77,111,100,101,108,86,105,101,119,77,97,116,114,105,120,0,0,0,2,2,4,15,1, +103,108,95,80,114,111,106,101,99,116,105,111,110,77,97,116,114,105,120,0,0,0,2,2, +4,15,1,103,108,95,77,111,100,101,108,86,105,101,119,80,114,111,106,101,99,116,105,111, +110,77,97,116,114,105,120,0,0,0,2,2,4,15,1,103,108,95,84,101,120,116,117,114, +101,77,97,116,114,105,120,0,3,18,103,108,95,77,97,120,84,101,120,116,117,114,101,67, +111,111,114,100,115,0,0,0,2,2,4,14,1,103,108,95,78,111,114,109,97,108,77,97, +116,114,105,120,0,0,0,2,2,4,15,1,103,108,95,77,111,100,101,108,86,105,101,119, +77,97,116,114,105,120,73,110,118,101,114,115,101,0,0,0,2,2,4,15,1,103,108,95, +80,114,111,106,101,99,116,105,111,110,77,97,116,114,105,120,73,110,118,101,114,115,101,0, +0,0,2,2,4,15,1,103,108,95,77,111,100,101,108,86,105,101,119,80,114,111,106,101, +99,116,105,111,110,77,97,116,114,105,120,73,110,118,101,114,115,101,0,0,0,2,2,4, +15,1,103,108,95,84,101,120,116,117,114,101,77,97,116,114,105,120,73,110,118,101,114,115, +101,0,3,18,103,108,95,77,97,120,84,101,120,116,117,114,101,67,111,111,114,100,115,0, +0,0,2,2,4,15,1,103,108,95,77,111,100,101,108,86,105,101,119,77,97,116,114,105, +120,84,114,97,110,115,112,111,115,101,0,0,0,2,2,4,15,1,103,108,95,80,114,111, +106,101,99,116,105,111,110,77,97,116,114,105,120,84,114,97,110,115,112,111,115,101,0,0, +0,2,2,4,15,1,103,108,95,77,111,100,101,108,86,105,101,119,80,114,111,106,101,99, +116,105,111,110,77,97,116,114,105,120,84,114,97,110,115,112,111,115,101,0,0,0,2,2, +4,15,1,103,108,95,84,101,120,116,117,114,101,77,97,116,114,105,120,84,114,97,110,115, +112,111,115,101,0,3,18,103,108,95,77,97,120,84,101,120,116,117,114,101,67,111,111,114, +100,115,0,0,0,2,2,4,15,1,103,108,95,77,111,100,101,108,86,105,101,119,77,97, +116,114,105,120,73,110,118,101,114,115,101,84,114,97,110,115,112,111,115,101,0,0,0,2, +2,4,15,1,103,108,95,80,114,111,106,101,99,116,105,111,110,77,97,116,114,105,120,73, +110,118,101,114,115,101,84,114,97,110,115,112,111,115,101,0,0,0,2,2,4,15,1,103, +108,95,77,111,100,101,108,86,105,101,119,80,114,111,106,101,99,116,105,111,110,77,97,116, +114,105,120,73,110,118,101,114,115,101,84,114,97,110,115,112,111,115,101,0,0,0,2,2, +4,15,1,103,108,95,84,101,120,116,117,114,101,77,97,116,114,105,120,73,110,118,101,114, +115,101,84,114,97,110,115,112,111,115,101,0,3,18,103,108,95,77,97,120,84,101,120,116, +117,114,101,67,111,111,114,100,115,0,0,0,2,2,4,9,1,103,108,95,78,111,114,109, +97,108,83,99,97,108,101,0,0,0,2,2,0,22,103,108,95,68,101,112,116,104,82,97, +110,103,101,80,97,114,97,109,101,116,101,114,115,0,9,110,101,97,114,0,0,0,1,9, +102,97,114,0,0,0,1,9,100,105,102,102,0,0,0,0,0,0,2,2,4,23,103,108, +95,68,101,112,116,104,82,97,110,103,101,80,97,114,97,109,101,116,101,114,115,0,1,103, +108,95,68,101,112,116,104,82,97,110,103,101,0,0,0,2,2,4,12,1,103,108,95,67, +108,105,112,80,108,97,110,101,0,3,18,103,108,95,77,97,120,67,108,105,112,80,108,97, +110,101,115,0,0,0,2,2,0,22,103,108,95,80,111,105,110,116,80,97,114,97,109,101, +116,101,114,115,0,9,115,105,122,101,0,0,0,1,9,115,105,122,101,77,105,110,0,0, +0,1,9,115,105,122,101,77,97,120,0,0,0,1,9,102,97,100,101,84,104,114,101,115, +104,111,108,100,83,105,122,101,0,0,0,1,9,100,105,115,116,97,110,99,101,67,111,110, +115,116,97,110,116,65,116,116,101,110,117,97,116,105,111,110,0,0,0,1,9,100,105,115, +116,97,110,99,101,76,105,110,101,97,114,65,116,116,101,110,117,97,116,105,111,110,0,0, +0,1,9,100,105,115,116,97,110,99,101,81,117,97,100,114,97,116,105,99,65,116,116,101, +110,117,97,116,105,111,110,0,0,0,0,0,0,2,2,4,23,103,108,95,80,111,105,110, +116,80,97,114,97,109,101,116,101,114,115,0,1,103,108,95,80,111,105,110,116,0,0,0, +2,2,0,22,103,108,95,77,97,116,101,114,105,97,108,80,97,114,97,109,101,116,101,114, +115,0,12,101,109,105,115,115,105,111,110,0,0,0,1,12,97,109,98,105,101,110,116,0, +0,0,1,12,100,105,102,102,117,115,101,0,0,0,1,12,115,112,101,99,117,108,97,114, +0,0,0,1,9,115,104,105,110,105,110,101,115,115,0,0,0,0,0,0,2,2,4,23, +103,108,95,77,97,116,101,114,105,97,108,80,97,114,97,109,101,116,101,114,115,0,1,103, +108,95,70,114,111,110,116,77,97,116,101,114,105,97,108,0,0,0,2,2,4,23,103,108, +95,77,97,116,101,114,105,97,108,80,97,114,97,109,101,116,101,114,115,0,1,103,108,95, +66,97,99,107,77,97,116,101,114,105,97,108,0,0,0,2,2,0,22,103,108,95,76,105, +103,104,116,83,111,117,114,99,101,80,97,114,97,109,101,116,101,114,115,0,12,97,109,98, +105,101,110,116,0,0,0,1,12,100,105,102,102,117,115,101,0,0,0,1,12,115,112,101, +99,117,108,97,114,0,0,0,1,12,112,111,115,105,116,105,111,110,0,0,0,1,12,104, +97,108,102,86,101,99,116,111,114,0,0,0,1,11,115,112,111,116,68,105,114,101,99,116, +105,111,110,0,0,0,1,9,115,112,111,116,69,120,112,111,110,101,110,116,0,0,0,1, +9,115,112,111,116,67,117,116,111,102,102,0,0,0,1,9,115,112,111,116,67,111,115,67, +117,116,111,102,102,0,0,0,1,9,99,111,110,115,116,97,110,116,65,116,116,101,110,117, +97,116,105,111,110,0,0,0,1,9,108,105,110,101,97,114,65,116,116,101,110,117,97,116, +105,111,110,0,0,0,1,9,113,117,97,100,114,97,116,105,99,65,116,116,101,110,117,97, +116,105,111,110,0,0,0,0,0,0,2,2,4,23,103,108,95,76,105,103,104,116,83,111, +117,114,99,101,80,97,114,97,109,101,116,101,114,115,0,1,103,108,95,76,105,103,104,116, +83,111,117,114,99,101,0,3,18,103,108,95,77,97,120,76,105,103,104,116,115,0,0,0, +2,2,0,22,103,108,95,76,105,103,104,116,77,111,100,101,108,80,97,114,97,109,101,116, +101,114,115,0,12,97,109,98,105,101,110,116,0,0,0,0,0,0,2,2,4,23,103,108, +95,76,105,103,104,116,77,111,100,101,108,80,97,114,97,109,101,116,101,114,115,0,1,103, +108,95,76,105,103,104,116,77,111,100,101,108,0,0,0,2,2,0,22,103,108,95,76,105, +103,104,116,77,111,100,101,108,80,114,111,100,117,99,116,115,0,12,115,99,101,110,101,67, +111,108,111,114,0,0,0,0,0,0,2,2,4,23,103,108,95,76,105,103,104,116,77,111, +100,101,108,80,114,111,100,117,99,116,115,0,1,103,108,95,70,114,111,110,116,76,105,103, +104,116,77,111,100,101,108,80,114,111,100,117,99,116,0,0,0,2,2,4,23,103,108,95, +76,105,103,104,116,77,111,100,101,108,80,114,111,100,117,99,116,115,0,1,103,108,95,66, +97,99,107,76,105,103,104,116,77,111,100,101,108,80,114,111,100,117,99,116,0,0,0,2, +2,0,22,103,108,95,76,105,103,104,116,80,114,111,100,117,99,116,115,0,12,97,109,98, +105,101,110,116,0,0,0,1,12,100,105,102,102,117,115,101,0,0,0,1,12,115,112,101, +99,117,108,97,114,0,0,0,0,0,0,2,2,4,23,103,108,95,76,105,103,104,116,80, +114,111,100,117,99,116,115,0,1,103,108,95,70,114,111,110,116,76,105,103,104,116,80,114, +111,100,117,99,116,0,3,18,103,108,95,77,97,120,76,105,103,104,116,115,0,0,0,2, +2,4,23,103,108,95,76,105,103,104,116,80,114,111,100,117,99,116,115,0,1,103,108,95, +66,97,99,107,76,105,103,104,116,80,114,111,100,117,99,116,0,3,18,103,108,95,77,97, +120,76,105,103,104,116,115,0,0,0,2,2,4,12,1,103,108,95,84,101,120,116,117,114, +101,69,110,118,67,111,108,111,114,0,3,18,103,108,95,77,97,120,84,101,120,116,117,114, +101,73,109,97,103,101,85,110,105,116,115,0,0,0,2,2,4,12,1,103,108,95,69,121, +101,80,108,97,110,101,83,0,3,18,103,108,95,77,97,120,84,101,120,116,117,114,101,67, +111,111,114,100,115,0,0,0,2,2,4,12,1,103,108,95,69,121,101,80,108,97,110,101, +84,0,3,18,103,108,95,77,97,120,84,101,120,116,117,114,101,67,111,111,114,100,115,0, +0,0,2,2,4,12,1,103,108,95,69,121,101,80,108,97,110,101,82,0,3,18,103,108, +95,77,97,120,84,101,120,116,117,114,101,67,111,111,114,100,115,0,0,0,2,2,4,12, +1,103,108,95,69,121,101,80,108,97,110,101,81,0,3,18,103,108,95,77,97,120,84,101, +120,116,117,114,101,67,111,111,114,100,115,0,0,0,2,2,4,12,1,103,108,95,79,98, +106,101,99,116,80,108,97,110,101,83,0,3,18,103,108,95,77,97,120,84,101,120,116,117, +114,101,67,111,111,114,100,115,0,0,0,2,2,4,12,1,103,108,95,79,98,106,101,99, +116,80,108,97,110,101,84,0,3,18,103,108,95,77,97,120,84,101,120,116,117,114,101,67, +111,111,114,100,115,0,0,0,2,2,4,12,1,103,108,95,79,98,106,101,99,116,80,108, +97,110,101,82,0,3,18,103,108,95,77,97,120,84,101,120,116,117,114,101,67,111,111,114, +100,115,0,0,0,2,2,4,12,1,103,108,95,79,98,106,101,99,116,80,108,97,110,101, +81,0,3,18,103,108,95,77,97,120,84,101,120,116,117,114,101,67,111,111,114,100,115,0, +0,0,2,2,0,22,103,108,95,70,111,103,80,97,114,97,109,101,116,101,114,115,0,12, +99,111,108,111,114,0,0,0,1,9,100,101,110,115,105,116,121,0,0,0,1,9,115,116, +97,114,116,0,0,0,1,9,101,110,100,0,0,0,1,9,115,99,97,108,101,0,0,0, +0,0,0,2,2,4,23,103,108,95,70,111,103,80,97,114,97,109,101,116,101,114,115,0, +1,103,108,95,70,111,103,0,0,0,1,0,9,0,114,97,100,105,97,110,115,0,1,0, +0,9,100,101,103,0,0,0,1,8,17,51,0,49,52,49,53,57,51,0,0,18,100,101, +103,0,48,17,49,56,48,0,48,0,0,49,0,0,1,0,10,0,114,97,100,105,97,110, +115,0,1,0,0,10,100,101,103,0,0,0,1,8,58,118,101,99,50,0,58,114,97,100, +105,97,110,115,0,18,100,101,103,0,59,120,0,0,0,0,58,114,97,100,105,97,110,115, +0,18,100,101,103,0,59,121,0,0,0,0,0,0,0,1,0,11,0,114,97,100,105,97, +110,115,0,1,0,0,11,100,101,103,0,0,0,1,8,58,118,101,99,51,0,58,114,97, +100,105,97,110,115,0,18,100,101,103,0,59,120,0,0,0,0,58,114,97,100,105,97,110, +115,0,18,100,101,103,0,59,121,0,0,0,0,58,114,97,100,105,97,110,115,0,18,100, +101,103,0,59,122,0,0,0,0,0,0,0,1,0,12,0,114,97,100,105,97,110,115,0, +1,0,0,12,100,101,103,0,0,0,1,8,58,118,101,99,52,0,58,114,97,100,105,97, +110,115,0,18,100,101,103,0,59,120,0,0,0,0,58,114,97,100,105,97,110,115,0,18, +100,101,103,0,59,121,0,0,0,0,58,114,97,100,105,97,110,115,0,18,100,101,103,0, +59,122,0,0,0,0,58,114,97,100,105,97,110,115,0,18,100,101,103,0,59,119,0,0, +0,0,0,0,0,1,0,9,0,100,101,103,114,101,101,115,0,1,0,0,9,114,97,100, +0,0,0,1,8,17,49,56,48,0,48,0,0,18,114,97,100,0,48,17,51,0,49,52, +49,53,57,51,0,0,49,0,0,1,0,10,0,100,101,103,114,101,101,115,0,1,0,0, +10,114,97,100,0,0,0,1,8,58,118,101,99,50,0,58,100,101,103,114,101,101,115,0, +18,114,97,100,0,59,120,0,0,0,0,58,100,101,103,114,101,101,115,0,18,114,97,100, +0,59,121,0,0,0,0,0,0,0,1,0,11,0,100,101,103,114,101,101,115,0,1,0, +0,11,114,97,100,0,0,0,1,8,58,118,101,99,51,0,58,100,101,103,114,101,101,115, +0,18,114,97,100,0,59,120,0,0,0,0,58,100,101,103,114,101,101,115,0,18,114,97, +100,0,59,121,0,0,0,0,58,100,101,103,114,101,101,115,0,18,114,97,100,0,59,122, +0,0,0,0,0,0,0,1,0,12,0,100,101,103,114,101,101,115,0,1,0,0,12,114, +97,100,0,0,0,1,8,58,118,101,99,52,0,58,100,101,103,114,101,101,115,0,18,114, +97,100,0,59,120,0,0,0,0,58,100,101,103,114,101,101,115,0,18,114,97,100,0,59, +121,0,0,0,0,58,100,101,103,114,101,101,115,0,18,114,97,100,0,59,122,0,0,0, +0,58,100,101,103,114,101,101,115,0,18,114,97,100,0,59,119,0,0,0,0,0,0,0, +1,0,9,0,115,105,110,0,1,0,0,9,97,110,103,108,101,0,0,0,1,8,17,48, +0,48,0,0,0,0,1,0,10,0,115,105,110,0,1,0,0,10,97,110,103,108,101,0, +0,0,1,8,58,118,101,99,50,0,58,115,105,110,0,18,97,110,103,108,101,0,59,120, +0,0,0,0,58,115,105,110,0,18,97,110,103,108,101,0,59,121,0,0,0,0,0,0, +0,1,0,11,0,115,105,110,0,1,0,0,11,97,110,103,108,101,0,0,0,1,8,58, +118,101,99,51,0,58,115,105,110,0,18,97,110,103,108,101,0,59,120,0,0,0,0,58, +115,105,110,0,18,97,110,103,108,101,0,59,121,0,0,0,0,58,115,105,110,0,18,97, +110,103,108,101,0,59,122,0,0,0,0,0,0,0,1,0,12,0,115,105,110,0,1,0, +0,12,97,110,103,108,101,0,0,0,1,8,58,118,101,99,52,0,58,115,105,110,0,18, +97,110,103,108,101,0,59,120,0,0,0,0,58,115,105,110,0,18,97,110,103,108,101,0, +59,121,0,0,0,0,58,115,105,110,0,18,97,110,103,108,101,0,59,122,0,0,0,0, +58,115,105,110,0,18,97,110,103,108,101,0,59,119,0,0,0,0,0,0,0,1,0,9, +0,99,111,115,0,1,0,0,9,97,110,103,108,101,0,0,0,1,8,58,115,105,110,0, +18,97,110,103,108,101,0,17,49,0,53,55,48,56,0,0,46,0,0,0,0,1,0,10, +0,99,111,115,0,1,0,0,10,97,110,103,108,101,0,0,0,1,8,58,118,101,99,50, +0,58,99,111,115,0,18,97,110,103,108,101,0,59,120,0,0,0,0,58,99,111,115,0, +18,97,110,103,108,101,0,59,121,0,0,0,0,0,0,0,1,0,11,0,99,111,115,0, +1,0,0,11,97,110,103,108,101,0,0,0,1,8,58,118,101,99,51,0,58,99,111,115, +0,18,97,110,103,108,101,0,59,120,0,0,0,0,58,99,111,115,0,18,97,110,103,108, +101,0,59,121,0,0,0,0,58,99,111,115,0,18,97,110,103,108,101,0,59,122,0,0, +0,0,0,0,0,1,0,12,0,99,111,115,0,1,0,0,12,97,110,103,108,101,0,0, +0,1,8,58,118,101,99,52,0,58,99,111,115,0,18,97,110,103,108,101,0,59,120,0, +0,0,0,58,99,111,115,0,18,97,110,103,108,101,0,59,121,0,0,0,0,58,99,111, +115,0,18,97,110,103,108,101,0,59,122,0,0,0,0,58,99,111,115,0,18,97,110,103, +108,101,0,59,119,0,0,0,0,0,0,0,1,0,9,0,116,97,110,0,1,0,0,9, +97,110,103,108,101,0,0,0,1,8,58,115,105,110,0,18,97,110,103,108,101,0,0,0, +58,99,111,115,0,18,97,110,103,108,101,0,0,0,49,0,0,1,0,10,0,116,97,110, +0,1,0,0,10,97,110,103,108,101,0,0,0,1,8,58,118,101,99,50,0,58,116,97, +110,0,18,97,110,103,108,101,0,59,120,0,0,0,0,58,116,97,110,0,18,97,110,103, +108,101,0,59,121,0,0,0,0,0,0,0,1,0,11,0,116,97,110,0,1,0,0,11, +97,110,103,108,101,0,0,0,1,8,58,118,101,99,51,0,58,116,97,110,0,18,97,110, +103,108,101,0,59,120,0,0,0,0,58,116,97,110,0,18,97,110,103,108,101,0,59,121, +0,0,0,0,58,116,97,110,0,18,97,110,103,108,101,0,59,122,0,0,0,0,0,0, +0,1,0,12,0,116,97,110,0,1,0,0,12,97,110,103,108,101,0,0,0,1,8,58, +118,101,99,52,0,58,116,97,110,0,18,97,110,103,108,101,0,59,120,0,0,0,0,58, +116,97,110,0,18,97,110,103,108,101,0,59,121,0,0,0,0,58,116,97,110,0,18,97, +110,103,108,101,0,59,122,0,0,0,0,58,116,97,110,0,18,97,110,103,108,101,0,59, +119,0,0,0,0,0,0,0,1,0,9,0,97,115,105,110,0,1,0,0,9,120,0,0, +0,1,8,17,48,0,48,0,0,0,0,1,0,10,0,97,115,105,110,0,1,0,0,10, +120,0,0,0,1,8,58,118,101,99,50,0,58,97,115,105,110,0,18,120,0,59,120,0, +0,0,0,58,97,115,105,110,0,18,120,0,59,121,0,0,0,0,0,0,0,1,0,11, +0,97,115,105,110,0,1,0,0,11,120,0,0,0,1,8,58,118,101,99,51,0,58,97, +115,105,110,0,18,120,0,59,120,0,0,0,0,58,97,115,105,110,0,18,120,0,59,121, +0,0,0,0,58,97,115,105,110,0,18,120,0,59,122,0,0,0,0,0,0,0,1,0, +12,0,97,115,105,110,0,1,0,0,12,120,0,0,0,1,8,58,118,101,99,52,0,58, +97,115,105,110,0,18,120,0,59,120,0,0,0,0,58,97,115,105,110,0,18,120,0,59, +121,0,0,0,0,58,97,115,105,110,0,18,120,0,59,122,0,0,0,0,58,97,115,105, +110,0,18,120,0,59,119,0,0,0,0,0,0,0,1,0,9,0,97,99,111,115,0,1, +0,0,9,120,0,0,0,1,8,17,48,0,48,0,0,0,0,1,0,10,0,97,99,111, +115,0,1,0,0,10,120,0,0,0,1,8,58,118,101,99,50,0,58,97,99,111,115,0, +18,120,0,59,120,0,0,0,0,58,97,99,111,115,0,18,120,0,59,121,0,0,0,0, +0,0,0,1,0,11,0,97,99,111,115,0,1,0,0,11,120,0,0,0,1,8,58,118, +101,99,51,0,58,97,99,111,115,0,18,120,0,59,120,0,0,0,0,58,97,99,111,115, +0,18,120,0,59,121,0,0,0,0,58,97,99,111,115,0,18,120,0,59,122,0,0,0, +0,0,0,0,1,0,12,0,97,99,111,115,0,1,0,0,12,120,0,0,0,1,8,58, +118,101,99,52,0,58,97,99,111,115,0,18,120,0,59,120,0,0,0,0,58,97,99,111, +115,0,18,120,0,59,121,0,0,0,0,58,97,99,111,115,0,18,120,0,59,122,0,0, +0,0,58,97,99,111,115,0,18,120,0,59,119,0,0,0,0,0,0,0,1,0,9,0, +97,116,97,110,0,1,0,0,9,120,0,0,1,0,0,9,121,0,0,0,1,8,17,48, +0,48,0,0,0,0,1,0,10,0,97,116,97,110,0,1,0,0,10,120,0,0,1,0, +0,10,121,0,0,0,1,8,58,118,101,99,50,0,58,97,116,97,110,0,18,120,0,59, +120,0,0,18,121,0,59,120,0,0,0,0,58,97,116,97,110,0,18,120,0,59,121,0, +0,18,121,0,59,121,0,0,0,0,0,0,0,1,0,11,0,97,116,97,110,0,1,0, +0,11,120,0,0,1,0,0,11,121,0,0,0,1,8,58,118,101,99,51,0,58,97,116, +97,110,0,18,120,0,59,120,0,0,18,121,0,59,120,0,0,0,0,58,97,116,97,110, +0,18,120,0,59,121,0,0,18,121,0,59,121,0,0,0,0,58,97,116,97,110,0,18, +120,0,59,122,0,0,18,121,0,59,122,0,0,0,0,0,0,0,1,0,12,0,97,116, +97,110,0,1,0,0,12,120,0,0,1,0,0,12,121,0,0,0,1,8,58,118,101,99, +52,0,58,97,116,97,110,0,18,120,0,59,120,0,0,18,121,0,59,120,0,0,0,0, +58,97,116,97,110,0,18,120,0,59,121,0,0,18,121,0,59,121,0,0,0,0,58,97, +116,97,110,0,18,120,0,59,122,0,0,18,121,0,59,122,0,0,0,0,58,97,116,97, +110,0,18,120,0,59,119,0,0,18,121,0,59,119,0,0,0,0,0,0,0,1,0,9, +0,97,116,97,110,0,1,0,0,9,121,95,111,118,101,114,95,120,0,0,0,1,8,17, +48,0,48,0,0,0,0,1,0,10,0,97,116,97,110,0,1,0,0,10,121,95,111,118, +101,114,95,120,0,0,0,1,8,58,118,101,99,50,0,58,97,116,97,110,0,18,121,95, +111,118,101,114,95,120,0,59,120,0,0,0,0,58,97,116,97,110,0,18,121,95,111,118, +101,114,95,120,0,59,121,0,0,0,0,0,0,0,1,0,11,0,97,116,97,110,0,1, +0,0,11,121,95,111,118,101,114,95,120,0,0,0,1,8,58,118,101,99,51,0,58,97, +116,97,110,0,18,121,95,111,118,101,114,95,120,0,59,120,0,0,0,0,58,97,116,97, +110,0,18,121,95,111,118,101,114,95,120,0,59,121,0,0,0,0,58,97,116,97,110,0, +18,121,95,111,118,101,114,95,120,0,59,122,0,0,0,0,0,0,0,1,0,12,0,97, +116,97,110,0,1,0,0,12,121,95,111,118,101,114,95,120,0,0,0,1,8,58,118,101, +99,52,0,58,97,116,97,110,0,18,121,95,111,118,101,114,95,120,0,59,120,0,0,0, +0,58,97,116,97,110,0,18,121,95,111,118,101,114,95,120,0,59,121,0,0,0,0,58, +97,116,97,110,0,18,121,95,111,118,101,114,95,120,0,59,122,0,0,0,0,58,97,116, +97,110,0,18,121,95,111,118,101,114,95,120,0,59,119,0,0,0,0,0,0,0,1,0, +9,0,112,111,119,0,1,0,0,9,120,0,0,1,0,0,9,121,0,0,0,1,8,17, +48,0,48,0,0,0,0,1,0,10,0,112,111,119,0,1,0,0,10,120,0,0,1,0, +0,10,121,0,0,0,1,8,58,118,101,99,50,0,58,112,111,119,0,18,120,0,59,120, +0,0,18,121,0,59,120,0,0,0,0,58,112,111,119,0,18,120,0,59,121,0,0,18, +121,0,59,121,0,0,0,0,0,0,0,1,0,11,0,112,111,119,0,1,0,0,11,120, +0,0,1,0,0,11,121,0,0,0,1,8,58,118,101,99,51,0,58,112,111,119,0,18, +120,0,59,120,0,0,18,121,0,59,120,0,0,0,0,58,112,111,119,0,18,120,0,59, +121,0,0,18,121,0,59,121,0,0,0,0,58,112,111,119,0,18,120,0,59,122,0,0, +18,121,0,59,122,0,0,0,0,0,0,0,1,0,12,0,112,111,119,0,1,0,0,12, +120,0,0,1,0,0,12,121,0,0,0,1,8,58,118,101,99,52,0,58,112,111,119,0, +18,120,0,59,120,0,0,18,121,0,59,120,0,0,0,0,58,112,111,119,0,18,120,0, +59,121,0,0,18,121,0,59,121,0,0,0,0,58,112,111,119,0,18,120,0,59,122,0, +0,18,121,0,59,122,0,0,0,0,58,112,111,119,0,18,120,0,59,119,0,0,18,121, +0,59,119,0,0,0,0,0,0,0,1,0,9,0,101,120,112,0,1,0,0,9,120,0, +0,0,1,8,58,112,111,119,0,17,50,0,55,49,56,50,56,49,56,51,0,0,0,18, +120,0,0,0,0,0,1,0,10,0,101,120,112,0,1,0,0,10,120,0,0,0,1,8, +58,118,101,99,50,0,58,101,120,112,0,18,120,0,59,120,0,0,0,0,58,101,120,112, +0,18,120,0,59,121,0,0,0,0,0,0,0,1,0,11,0,101,120,112,0,1,0,0, +11,120,0,0,0,1,8,58,118,101,99,51,0,58,101,120,112,0,18,120,0,59,120,0, +0,0,0,58,101,120,112,0,18,120,0,59,121,0,0,0,0,58,101,120,112,0,18,120, +0,59,122,0,0,0,0,0,0,0,1,0,12,0,101,120,112,0,1,0,0,12,120,0, +0,0,1,8,58,118,101,99,52,0,58,101,120,112,0,18,120,0,59,120,0,0,0,0, +58,101,120,112,0,18,120,0,59,121,0,0,0,0,58,101,120,112,0,18,120,0,59,122, +0,0,0,0,58,101,120,112,0,18,120,0,59,119,0,0,0,0,0,0,0,1,0,9, +0,108,111,103,0,1,0,0,9,120,0,0,0,1,8,58,108,111,103,50,0,18,120,0, +0,0,58,108,111,103,50,0,17,50,0,55,49,56,50,56,49,56,51,0,0,0,0,49, +0,0,1,0,10,0,108,111,103,0,1,0,0,10,120,0,0,0,1,8,58,118,101,99, +50,0,58,108,111,103,0,18,120,0,59,120,0,0,0,0,58,108,111,103,0,18,120,0, +59,121,0,0,0,0,0,0,0,1,0,11,0,108,111,103,0,1,0,0,11,120,0,0, +0,1,8,58,118,101,99,51,0,58,108,111,103,0,18,120,0,59,120,0,0,0,0,58, +108,111,103,0,18,120,0,59,121,0,0,0,0,58,108,111,103,0,18,120,0,59,122,0, +0,0,0,0,0,0,1,0,12,0,108,111,103,0,1,0,0,12,120,0,0,0,1,8, +58,118,101,99,52,0,58,108,111,103,0,18,120,0,59,120,0,0,0,0,58,108,111,103, +0,18,120,0,59,121,0,0,0,0,58,108,111,103,0,18,120,0,59,122,0,0,0,0, +58,108,111,103,0,18,120,0,59,119,0,0,0,0,0,0,0,1,0,9,0,101,120,112, +50,0,1,0,0,9,120,0,0,0,1,8,58,112,111,119,0,17,50,0,48,0,0,0, +18,120,0,0,0,0,0,1,0,10,0,101,120,112,50,0,1,0,0,10,120,0,0,0, +1,8,58,118,101,99,50,0,58,101,120,112,50,0,18,120,0,59,120,0,0,0,0,58, +101,120,112,50,0,18,120,0,59,121,0,0,0,0,0,0,0,1,0,11,0,101,120,112, +50,0,1,0,0,11,120,0,0,0,1,8,58,118,101,99,51,0,58,101,120,112,50,0, +18,120,0,59,120,0,0,0,0,58,101,120,112,50,0,18,120,0,59,121,0,0,0,0, +58,101,120,112,50,0,18,120,0,59,122,0,0,0,0,0,0,0,1,0,12,0,101,120, +112,50,0,1,0,0,12,120,0,0,0,1,8,58,118,101,99,52,0,58,101,120,112,50, +0,18,120,0,59,120,0,0,0,0,58,101,120,112,50,0,18,120,0,59,121,0,0,0, +0,58,101,120,112,50,0,18,120,0,59,122,0,0,0,0,58,101,120,112,50,0,18,120, +0,59,119,0,0,0,0,0,0,0,1,0,9,0,108,111,103,50,0,1,0,0,9,120, +0,0,0,1,8,17,48,0,48,0,0,0,0,1,0,10,0,108,111,103,50,0,1,0, +0,10,120,0,0,0,1,8,58,118,101,99,50,0,58,108,111,103,50,0,18,120,0,59, +120,0,0,0,0,58,108,111,103,50,0,18,120,0,59,121,0,0,0,0,0,0,0,1, +0,11,0,108,111,103,50,0,1,0,0,11,120,0,0,0,1,8,58,118,101,99,51,0, +58,108,111,103,50,0,18,120,0,59,120,0,0,0,0,58,108,111,103,50,0,18,120,0, +59,121,0,0,0,0,58,108,111,103,50,0,18,120,0,59,122,0,0,0,0,0,0,0, +1,0,12,0,108,111,103,50,0,1,0,0,12,120,0,0,0,1,8,58,118,101,99,52, +0,58,108,111,103,50,0,18,120,0,59,120,0,0,0,0,58,108,111,103,50,0,18,120, +0,59,121,0,0,0,0,58,108,111,103,50,0,18,120,0,59,122,0,0,0,0,58,108, +111,103,50,0,18,120,0,59,119,0,0,0,0,0,0,0,1,0,9,0,115,113,114,116, +0,1,0,0,9,120,0,0,0,1,8,58,112,111,119,0,18,120,0,0,17,48,0,53, +0,0,0,0,0,0,1,0,10,0,115,113,114,116,0,1,0,0,10,120,0,0,0,1, +8,58,118,101,99,50,0,58,115,113,114,116,0,18,120,0,59,120,0,0,0,0,58,115, +113,114,116,0,18,120,0,59,121,0,0,0,0,0,0,0,1,0,11,0,115,113,114,116, +0,1,0,0,11,120,0,0,0,1,8,58,118,101,99,51,0,58,115,113,114,116,0,18, +120,0,59,120,0,0,0,0,58,115,113,114,116,0,18,120,0,59,121,0,0,0,0,58, +115,113,114,116,0,18,120,0,59,122,0,0,0,0,0,0,0,1,0,12,0,115,113,114, +116,0,1,0,0,12,120,0,0,0,1,8,58,118,101,99,52,0,58,115,113,114,116,0, +18,120,0,59,120,0,0,0,0,58,115,113,114,116,0,18,120,0,59,121,0,0,0,0, +58,115,113,114,116,0,18,120,0,59,122,0,0,0,0,58,115,113,114,116,0,18,120,0, +59,119,0,0,0,0,0,0,0,1,0,9,0,105,110,118,101,114,115,101,115,113,114,116, +0,1,0,0,9,120,0,0,0,1,8,17,49,0,48,0,0,58,115,113,114,116,0,18, +120,0,0,0,49,0,0,1,0,10,0,105,110,118,101,114,115,101,115,113,114,116,0,1, +0,0,10,120,0,0,0,1,8,58,118,101,99,50,0,58,105,110,118,101,114,115,101,115, +113,114,116,0,18,120,0,59,120,0,0,0,0,58,105,110,118,101,114,115,101,115,113,114, +116,0,18,120,0,59,121,0,0,0,0,0,0,0,1,0,11,0,105,110,118,101,114,115, +101,115,113,114,116,0,1,0,0,11,120,0,0,0,1,8,58,118,101,99,51,0,58,105, +110,118,101,114,115,101,115,113,114,116,0,18,120,0,59,120,0,0,0,0,58,105,110,118, +101,114,115,101,115,113,114,116,0,18,120,0,59,121,0,0,0,0,58,105,110,118,101,114, +115,101,115,113,114,116,0,18,120,0,59,122,0,0,0,0,0,0,0,1,0,12,0,105, +110,118,101,114,115,101,115,113,114,116,0,1,0,0,12,120,0,0,0,1,8,58,118,101, +99,52,0,58,105,110,118,101,114,115,101,115,113,114,116,0,18,120,0,59,120,0,0,0, +0,58,105,110,118,101,114,115,101,115,113,114,116,0,18,120,0,59,121,0,0,0,0,58, +105,110,118,101,114,115,101,115,113,114,116,0,18,120,0,59,122,0,0,0,0,58,105,110, +118,101,114,115,101,115,113,114,116,0,18,120,0,59,119,0,0,0,0,0,0,0,1,0, +9,0,97,98,115,0,1,0,0,9,120,0,0,0,1,8,18,120,0,17,48,0,48,0, +0,43,18,120,0,18,120,0,54,31,0,0,1,0,10,0,97,98,115,0,1,0,0,10, +120,0,0,0,1,8,58,118,101,99,50,0,58,97,98,115,0,18,120,0,59,120,0,0, +0,0,58,97,98,115,0,18,120,0,59,121,0,0,0,0,0,0,0,1,0,11,0,97, +98,115,0,1,0,0,11,120,0,0,0,1,8,58,118,101,99,51,0,58,97,98,115,0, +18,120,0,59,120,0,0,0,0,58,97,98,115,0,18,120,0,59,121,0,0,0,0,58, +97,98,115,0,18,120,0,59,122,0,0,0,0,0,0,0,1,0,12,0,97,98,115,0, +1,0,0,12,120,0,0,0,1,8,58,118,101,99,52,0,58,97,98,115,0,18,120,0, +59,120,0,0,0,0,58,97,98,115,0,18,120,0,59,121,0,0,0,0,58,97,98,115, +0,18,120,0,59,122,0,0,0,0,58,97,98,115,0,18,120,0,59,119,0,0,0,0, +0,0,0,1,0,9,0,115,105,103,110,0,1,0,0,9,120,0,0,0,1,8,18,120, +0,17,48,0,48,0,0,41,17,49,0,48,0,0,18,120,0,17,48,0,48,0,0,40, +17,49,0,48,0,0,54,17,48,0,48,0,0,31,31,0,0,1,0,10,0,115,105,103, +110,0,1,0,0,10,120,0,0,0,1,8,58,118,101,99,50,0,58,115,105,103,110,0, +18,120,0,59,120,0,0,0,0,58,115,105,103,110,0,18,120,0,59,121,0,0,0,0, +0,0,0,1,0,11,0,115,105,103,110,0,1,0,0,11,120,0,0,0,1,8,58,118, +101,99,51,0,58,115,105,103,110,0,18,120,0,59,120,0,0,0,0,58,115,105,103,110, +0,18,120,0,59,121,0,0,0,0,58,115,105,103,110,0,18,120,0,59,122,0,0,0, +0,0,0,0,1,0,12,0,115,105,103,110,0,1,0,0,12,120,0,0,0,1,8,58, +118,101,99,52,0,58,115,105,103,110,0,18,120,0,59,120,0,0,0,0,58,115,105,103, +110,0,18,120,0,59,121,0,0,0,0,58,115,105,103,110,0,18,120,0,59,122,0,0, +0,0,58,115,105,103,110,0,18,120,0,59,119,0,0,0,0,0,0,0,1,0,9,0, +102,108,111,111,114,0,1,0,0,9,120,0,0,0,1,8,17,48,0,48,0,0,0,0, +1,0,10,0,102,108,111,111,114,0,1,0,0,10,120,0,0,0,1,8,58,118,101,99, +50,0,58,102,108,111,111,114,0,18,120,0,59,120,0,0,0,0,58,102,108,111,111,114, +0,18,120,0,59,121,0,0,0,0,0,0,0,1,0,11,0,102,108,111,111,114,0,1, +0,0,11,120,0,0,0,1,8,58,118,101,99,51,0,58,102,108,111,111,114,0,18,120, +0,59,120,0,0,0,0,58,102,108,111,111,114,0,18,120,0,59,121,0,0,0,0,58, +102,108,111,111,114,0,18,120,0,59,122,0,0,0,0,0,0,0,1,0,12,0,102,108, +111,111,114,0,1,0,0,12,120,0,0,0,1,8,58,118,101,99,52,0,58,102,108,111, +111,114,0,18,120,0,59,120,0,0,0,0,58,102,108,111,111,114,0,18,120,0,59,121, +0,0,0,0,58,102,108,111,111,114,0,18,120,0,59,122,0,0,0,0,58,102,108,111, +111,114,0,18,120,0,59,119,0,0,0,0,0,0,0,1,0,9,0,99,101,105,108,0, +1,0,0,9,120,0,0,0,1,8,17,48,0,48,0,0,0,0,1,0,10,0,99,101, +105,108,0,1,0,0,10,120,0,0,0,1,8,58,118,101,99,50,0,58,99,101,105,108, +0,18,120,0,59,120,0,0,0,0,58,99,101,105,108,0,18,120,0,59,121,0,0,0, +0,0,0,0,1,0,11,0,99,101,105,108,0,1,0,0,11,120,0,0,0,1,8,58, +118,101,99,51,0,58,99,101,105,108,0,18,120,0,59,120,0,0,0,0,58,99,101,105, +108,0,18,120,0,59,121,0,0,0,0,58,99,101,105,108,0,18,120,0,59,122,0,0, +0,0,0,0,0,1,0,12,0,99,101,105,108,0,1,0,0,12,120,0,0,0,1,8, +58,118,101,99,52,0,58,99,101,105,108,0,18,120,0,59,120,0,0,0,0,58,99,101, +105,108,0,18,120,0,59,121,0,0,0,0,58,99,101,105,108,0,18,120,0,59,122,0, +0,0,0,58,99,101,105,108,0,18,120,0,59,119,0,0,0,0,0,0,0,1,0,9, +0,102,114,97,99,116,0,1,0,0,9,120,0,0,0,1,8,18,120,0,58,102,108,111, +111,114,0,18,120,0,0,0,47,0,0,1,0,10,0,102,114,97,99,116,0,1,0,0, +10,120,0,0,0,1,8,58,118,101,99,50,0,58,102,114,97,99,116,0,18,120,0,59, +120,0,0,0,0,58,102,114,97,99,116,0,18,120,0,59,121,0,0,0,0,0,0,0, +1,0,11,0,102,114,97,99,116,0,1,0,0,11,120,0,0,0,1,8,58,118,101,99, +51,0,58,102,114,97,99,116,0,18,120,0,59,120,0,0,0,0,58,102,114,97,99,116, +0,18,120,0,59,121,0,0,0,0,58,102,114,97,99,116,0,18,120,0,59,122,0,0, +0,0,0,0,0,1,0,12,0,102,114,97,99,116,0,1,0,0,12,120,0,0,0,1, +8,58,118,101,99,52,0,58,102,114,97,99,116,0,18,120,0,59,120,0,0,0,0,58, +102,114,97,99,116,0,18,120,0,59,121,0,0,0,0,58,102,114,97,99,116,0,18,120, +0,59,122,0,0,0,0,58,102,114,97,99,116,0,18,120,0,59,119,0,0,0,0,0, +0,0,1,0,9,0,109,111,100,0,1,0,0,9,120,0,0,1,0,0,9,121,0,0, +0,1,8,18,120,0,18,121,0,58,102,108,111,111,114,0,18,120,0,18,121,0,49,0, +0,48,47,0,0,1,0,10,0,109,111,100,0,1,0,0,10,120,0,0,1,0,0,9, +121,0,0,0,1,8,58,118,101,99,50,0,58,109,111,100,0,18,120,0,59,120,0,0, +18,121,0,0,0,0,58,109,111,100,0,18,120,0,59,121,0,0,18,121,0,0,0,0, +0,0,0,1,0,11,0,109,111,100,0,1,0,0,11,120,0,0,1,0,0,9,121,0, +0,0,1,8,58,118,101,99,51,0,58,109,111,100,0,18,120,0,59,120,0,0,18,121, +0,0,0,0,58,109,111,100,0,18,120,0,59,121,0,0,18,121,0,0,0,0,58,109, +111,100,0,18,120,0,59,122,0,0,18,121,0,0,0,0,0,0,0,1,0,12,0,109, +111,100,0,1,0,0,12,120,0,0,1,0,0,9,121,0,0,0,1,8,58,118,101,99, +52,0,58,109,111,100,0,18,120,0,59,120,0,0,18,121,0,0,0,0,58,109,111,100, +0,18,120,0,59,121,0,0,18,121,0,0,0,0,58,109,111,100,0,18,120,0,59,122, +0,0,18,121,0,0,0,0,58,109,111,100,0,18,120,0,59,119,0,0,18,121,0,0, +0,0,0,0,0,1,0,10,0,109,111,100,0,1,0,0,10,120,0,0,1,0,0,10, +121,0,0,0,1,8,58,118,101,99,50,0,58,109,111,100,0,18,120,0,59,120,0,0, +18,121,0,59,120,0,0,0,0,58,109,111,100,0,18,120,0,59,121,0,0,18,121,0, +59,121,0,0,0,0,0,0,0,1,0,11,0,109,111,100,0,1,0,0,11,120,0,0, +1,0,0,11,121,0,0,0,1,8,58,118,101,99,51,0,58,109,111,100,0,18,120,0, +59,120,0,0,18,121,0,59,120,0,0,0,0,58,109,111,100,0,18,120,0,59,121,0, +0,18,121,0,59,121,0,0,0,0,58,109,111,100,0,18,120,0,59,122,0,0,18,121, +0,59,122,0,0,0,0,0,0,0,1,0,12,0,109,111,100,0,1,0,0,12,120,0, +0,1,0,0,12,121,0,0,0,1,8,58,118,101,99,52,0,58,109,111,100,0,18,120, +0,59,120,0,0,18,121,0,59,120,0,0,0,0,58,109,111,100,0,18,120,0,59,121, +0,0,18,121,0,59,121,0,0,0,0,58,109,111,100,0,18,120,0,59,122,0,0,18, +121,0,59,122,0,0,0,0,58,109,111,100,0,18,120,0,59,119,0,0,18,121,0,59, +119,0,0,0,0,0,0,0,1,0,9,0,109,105,110,0,1,0,0,9,120,0,0,1, +0,0,9,121,0,0,0,1,8,18,121,0,18,120,0,40,18,121,0,18,120,0,31,0, +0,1,0,10,0,109,105,110,0,1,0,0,10,120,0,0,1,0,0,9,121,0,0,0, +1,8,58,118,101,99,50,0,58,109,105,110,0,18,120,0,59,120,0,0,18,121,0,0, +0,0,58,109,105,110,0,18,120,0,59,121,0,0,18,121,0,0,0,0,0,0,0,1, +0,11,0,109,105,110,0,1,0,0,11,120,0,0,1,0,0,9,121,0,0,0,1,8, +58,118,101,99,51,0,58,109,105,110,0,18,120,0,59,120,0,0,18,121,0,0,0,0, +58,109,105,110,0,18,120,0,59,121,0,0,18,121,0,0,0,0,58,109,105,110,0,18, +120,0,59,122,0,0,18,121,0,0,0,0,0,0,0,1,0,12,0,109,105,110,0,1, +0,0,12,120,0,0,1,0,0,9,121,0,0,0,1,8,58,118,101,99,52,0,58,109, +105,110,0,18,120,0,59,120,0,0,18,121,0,0,0,0,58,109,105,110,0,18,120,0, +59,121,0,0,18,121,0,0,0,0,58,109,105,110,0,18,120,0,59,122,0,0,18,121, +0,0,0,0,58,109,105,110,0,18,120,0,59,119,0,0,18,121,0,0,0,0,0,0, +0,1,0,10,0,109,105,110,0,1,0,0,10,120,0,0,1,0,0,10,121,0,0,0, +1,8,58,118,101,99,50,0,58,109,105,110,0,18,120,0,59,120,0,0,18,121,0,59, +120,0,0,0,0,58,109,105,110,0,18,120,0,59,121,0,0,18,121,0,59,121,0,0, +0,0,0,0,0,1,0,11,0,109,105,110,0,1,0,0,11,120,0,0,1,0,0,11, +121,0,0,0,1,8,58,118,101,99,51,0,58,109,105,110,0,18,120,0,59,120,0,0, +18,121,0,59,120,0,0,0,0,58,109,105,110,0,18,120,0,59,121,0,0,18,121,0, +59,121,0,0,0,0,58,109,105,110,0,18,120,0,59,122,0,0,18,121,0,59,122,0, +0,0,0,0,0,0,1,0,12,0,109,105,110,0,1,0,0,12,120,0,0,1,0,0, +12,121,0,0,0,1,8,58,118,101,99,52,0,58,109,105,110,0,18,120,0,59,120,0, +0,18,121,0,59,120,0,0,0,0,58,109,105,110,0,18,120,0,59,121,0,0,18,121, +0,59,121,0,0,0,0,58,109,105,110,0,18,120,0,59,122,0,0,18,121,0,59,122, +0,0,0,0,58,109,105,110,0,18,120,0,59,119,0,0,18,121,0,59,119,0,0,0, +0,0,0,0,1,0,9,0,109,97,120,0,1,0,0,9,120,0,0,1,0,0,9,121, +0,0,0,1,8,58,109,105,110,0,18,121,0,0,18,120,0,0,0,0,0,1,0,10, +0,109,97,120,0,1,0,0,10,120,0,0,1,0,0,9,121,0,0,0,1,8,58,118, +101,99,50,0,58,109,97,120,0,18,120,0,59,120,0,0,18,121,0,0,0,0,58,109, +97,120,0,18,120,0,59,121,0,0,18,121,0,0,0,0,0,0,0,1,0,11,0,109, +97,120,0,1,0,0,11,120,0,0,1,0,0,9,121,0,0,0,1,8,58,118,101,99, +51,0,58,109,97,120,0,18,120,0,59,120,0,0,18,121,0,0,0,0,58,109,97,120, +0,18,120,0,59,121,0,0,18,121,0,0,0,0,58,109,97,120,0,18,120,0,59,122, +0,0,18,121,0,0,0,0,0,0,0,1,0,12,0,109,97,120,0,1,0,0,12,120, +0,0,1,0,0,9,121,0,0,0,1,8,58,118,101,99,52,0,58,109,97,120,0,18, +120,0,59,120,0,0,18,121,0,0,0,0,58,109,97,120,0,18,120,0,59,121,0,0, +18,121,0,0,0,0,58,109,97,120,0,18,120,0,59,122,0,0,18,121,0,0,0,0, +58,109,97,120,0,18,120,0,59,119,0,0,18,121,0,0,0,0,0,0,0,1,0,10, +0,109,97,120,0,1,0,0,10,120,0,0,1,0,0,10,121,0,0,0,1,8,58,118, +101,99,50,0,58,109,97,120,0,18,120,0,59,120,0,0,18,121,0,59,120,0,0,0, +0,58,109,97,120,0,18,120,0,59,121,0,0,18,121,0,59,121,0,0,0,0,0,0, +0,1,0,11,0,109,97,120,0,1,0,0,11,120,0,0,1,0,0,11,121,0,0,0, +1,8,58,118,101,99,51,0,58,109,97,120,0,18,120,0,59,120,0,0,18,121,0,59, +120,0,0,0,0,58,109,97,120,0,18,120,0,59,121,0,0,18,121,0,59,121,0,0, +0,0,58,109,97,120,0,18,120,0,59,122,0,0,18,121,0,59,122,0,0,0,0,0, +0,0,1,0,12,0,109,97,120,0,1,0,0,12,120,0,0,1,0,0,12,121,0,0, +0,1,8,58,118,101,99,52,0,58,109,97,120,0,18,120,0,59,120,0,0,18,121,0, +59,120,0,0,0,0,58,109,97,120,0,18,120,0,59,121,0,0,18,121,0,59,121,0, +0,0,0,58,109,97,120,0,18,120,0,59,122,0,0,18,121,0,59,122,0,0,0,0, +58,109,97,120,0,18,120,0,59,119,0,0,18,121,0,59,119,0,0,0,0,0,0,0, +1,0,9,0,99,108,97,109,112,0,1,0,0,9,120,0,0,1,0,0,9,109,105,110, +86,97,108,0,0,1,0,0,9,109,97,120,86,97,108,0,0,0,1,8,58,109,105,110, +0,58,109,97,120,0,18,120,0,0,18,109,105,110,86,97,108,0,0,0,0,18,109,97, +120,86,97,108,0,0,0,0,0,1,0,10,0,99,108,97,109,112,0,1,0,0,10,120, +0,0,1,0,0,9,109,105,110,86,97,108,0,0,1,0,0,9,109,97,120,86,97,108, +0,0,0,1,8,58,118,101,99,50,0,58,99,108,97,109,112,0,18,120,0,59,120,0, +0,18,109,105,110,86,97,108,0,0,18,109,97,120,86,97,108,0,0,0,0,58,99,108, +97,109,112,0,18,120,0,59,121,0,0,18,109,105,110,86,97,108,0,0,18,109,97,120, +86,97,108,0,0,0,0,0,0,0,1,0,11,0,99,108,97,109,112,0,1,0,0,11, +120,0,0,1,0,0,9,109,105,110,86,97,108,0,0,1,0,0,9,109,97,120,86,97, +108,0,0,0,1,8,58,118,101,99,51,0,58,99,108,97,109,112,0,18,120,0,59,120, +0,0,18,109,105,110,86,97,108,0,0,18,109,97,120,86,97,108,0,0,0,0,58,99, +108,97,109,112,0,18,120,0,59,121,0,0,18,109,105,110,86,97,108,0,0,18,109,97, +120,86,97,108,0,0,0,0,58,99,108,97,109,112,0,18,120,0,59,122,0,0,18,109, +105,110,86,97,108,0,0,18,109,97,120,86,97,108,0,0,0,0,0,0,0,1,0,12, +0,99,108,97,109,112,0,1,0,0,12,120,0,0,1,0,0,9,109,105,110,86,97,108, +0,0,1,0,0,9,109,97,120,86,97,108,0,0,0,1,8,58,118,101,99,52,0,58, +99,108,97,109,112,0,18,120,0,59,120,0,0,18,109,105,110,86,97,108,0,0,18,109, +97,120,86,97,108,0,0,0,0,58,99,108,97,109,112,0,18,120,0,59,121,0,0,18, +109,105,110,86,97,108,0,0,18,109,97,120,86,97,108,0,0,0,0,58,99,108,97,109, +112,0,18,120,0,59,122,0,0,18,109,105,110,86,97,108,0,0,18,109,97,120,86,97, +108,0,0,0,0,58,99,108,97,109,112,0,18,120,0,59,119,0,0,18,109,105,110,86, +97,108,0,0,18,109,97,120,86,97,108,0,0,0,0,0,0,0,1,0,10,0,99,108, +97,109,112,0,1,0,0,10,120,0,0,1,0,0,10,109,105,110,86,97,108,0,0,1, +0,0,10,109,97,120,86,97,108,0,0,0,1,8,58,118,101,99,50,0,58,99,108,97, +109,112,0,18,120,0,59,120,0,0,18,109,105,110,86,97,108,0,59,120,0,0,18,109, +97,120,86,97,108,0,59,120,0,0,0,0,58,99,108,97,109,112,0,18,120,0,59,121, +0,0,18,109,105,110,86,97,108,0,59,121,0,0,18,109,97,120,86,97,108,0,59,121, +0,0,0,0,0,0,0,1,0,11,0,99,108,97,109,112,0,1,0,0,11,120,0,0, +1,0,0,11,109,105,110,86,97,108,0,0,1,0,0,11,109,97,120,86,97,108,0,0, +0,1,8,58,118,101,99,51,0,58,99,108,97,109,112,0,18,120,0,59,120,0,0,18, +109,105,110,86,97,108,0,59,120,0,0,18,109,97,120,86,97,108,0,59,120,0,0,0, +0,58,99,108,97,109,112,0,18,120,0,59,121,0,0,18,109,105,110,86,97,108,0,59, +121,0,0,18,109,97,120,86,97,108,0,59,121,0,0,0,0,58,99,108,97,109,112,0, +18,120,0,59,122,0,0,18,109,105,110,86,97,108,0,59,122,0,0,18,109,97,120,86, +97,108,0,59,122,0,0,0,0,0,0,0,1,0,12,0,99,108,97,109,112,0,1,0, +0,12,120,0,0,1,0,0,12,109,105,110,86,97,108,0,0,1,0,0,12,109,97,120, +86,97,108,0,0,0,1,8,58,118,101,99,52,0,58,99,108,97,109,112,0,18,120,0, +59,120,0,0,18,109,105,110,86,97,108,0,59,120,0,0,18,109,97,120,86,97,108,0, +59,121,0,0,0,0,58,99,108,97,109,112,0,18,120,0,59,121,0,0,18,109,105,110, +86,97,108,0,59,121,0,0,18,109,97,120,86,97,108,0,59,121,0,0,0,0,58,99, +108,97,109,112,0,18,120,0,59,122,0,0,18,109,105,110,86,97,108,0,59,122,0,0, +18,109,97,120,86,97,108,0,59,122,0,0,0,0,58,99,108,97,109,112,0,18,120,0, +59,119,0,0,18,109,105,110,86,97,108,0,59,119,0,0,18,109,97,120,86,97,108,0, +59,119,0,0,0,0,0,0,0,1,0,9,0,109,105,120,0,1,0,0,9,120,0,0, +1,0,0,9,121,0,0,1,0,0,9,97,0,0,0,1,8,18,120,0,17,49,0,48, +0,0,18,97,0,47,48,18,121,0,18,97,0,48,46,0,0,1,0,10,0,109,105,120, +0,1,0,0,10,120,0,0,1,0,0,10,121,0,0,1,0,0,9,97,0,0,0,1, +8,58,118,101,99,50,0,58,109,105,120,0,18,120,0,59,120,0,0,18,121,0,59,120, +0,0,18,97,0,0,0,0,58,109,105,120,0,18,120,0,59,121,0,0,18,121,0,59, +121,0,0,18,97,0,0,0,0,0,0,0,1,0,11,0,109,105,120,0,1,0,0,11, +120,0,0,1,0,0,11,121,0,0,1,0,0,9,97,0,0,0,1,8,58,118,101,99, +51,0,58,109,105,120,0,18,120,0,59,120,0,0,18,121,0,59,120,0,0,18,97,0, +0,0,0,58,109,105,120,0,18,120,0,59,121,0,0,18,121,0,59,121,0,0,18,97, +0,0,0,0,58,109,105,120,0,18,120,0,59,122,0,0,18,121,0,59,122,0,0,18, +97,0,0,0,0,0,0,0,1,0,12,0,109,105,120,0,1,0,0,12,120,0,0,1, +0,0,12,121,0,0,1,0,0,9,97,0,0,0,1,8,58,118,101,99,52,0,58,109, +105,120,0,18,120,0,59,120,0,0,18,121,0,59,120,0,0,18,97,0,0,0,0,58, +109,105,120,0,18,120,0,59,121,0,0,18,121,0,59,121,0,0,18,97,0,0,0,0, +58,109,105,120,0,18,120,0,59,122,0,0,18,121,0,59,122,0,0,18,97,0,0,0, +0,58,109,105,120,0,18,120,0,59,119,0,0,18,121,0,59,119,0,0,18,97,0,0, +0,0,0,0,0,1,0,10,0,109,105,120,0,1,0,0,10,120,0,0,1,0,0,10, +121,0,0,1,0,0,10,97,0,0,0,1,8,58,118,101,99,50,0,58,109,105,120,0, +18,120,0,59,120,0,0,18,121,0,59,120,0,0,18,97,0,59,120,0,0,0,0,58, +109,105,120,0,18,120,0,59,121,0,0,18,121,0,59,121,0,0,18,97,0,59,121,0, +0,0,0,0,0,0,1,0,11,0,109,105,120,0,1,0,0,11,120,0,0,1,0,0, +11,121,0,0,1,0,0,11,97,0,0,0,1,8,58,118,101,99,51,0,58,109,105,120, +0,18,120,0,59,120,0,0,18,121,0,59,120,0,0,18,97,0,59,120,0,0,0,0, +58,109,105,120,0,18,120,0,59,121,0,0,18,121,0,59,121,0,0,18,97,0,59,121, +0,0,0,0,58,109,105,120,0,18,120,0,59,122,0,0,18,121,0,59,122,0,0,18, +97,0,59,122,0,0,0,0,0,0,0,1,0,12,0,109,105,120,0,1,0,0,12,120, +0,0,1,0,0,12,121,0,0,1,0,0,12,97,0,0,0,1,8,58,118,101,99,52, +0,58,109,105,120,0,18,120,0,59,120,0,0,18,121,0,59,120,0,0,18,97,0,59, +120,0,0,0,0,58,109,105,120,0,18,120,0,59,121,0,0,18,121,0,59,121,0,0, +18,97,0,59,121,0,0,0,0,58,109,105,120,0,18,120,0,59,122,0,0,18,121,0, +59,122,0,0,18,97,0,59,122,0,0,0,0,58,109,105,120,0,18,120,0,59,119,0, +0,18,121,0,59,119,0,0,18,97,0,59,119,0,0,0,0,0,0,0,1,0,9,0, +115,116,101,112,0,1,0,0,9,101,100,103,101,0,0,1,0,0,9,120,0,0,0,1, +8,18,120,0,18,101,100,103,101,0,40,17,48,0,48,0,0,17,49,0,48,0,0,31, +0,0,1,0,10,0,115,116,101,112,0,1,0,0,9,101,100,103,101,0,0,1,0,0, +10,120,0,0,0,1,8,58,118,101,99,50,0,58,115,116,101,112,0,18,101,100,103,101, +0,0,18,120,0,59,120,0,0,0,0,58,115,116,101,112,0,18,101,100,103,101,0,0, +18,120,0,59,121,0,0,0,0,0,0,0,1,0,11,0,115,116,101,112,0,1,0,0, +9,101,100,103,101,0,0,1,0,0,11,120,0,0,0,1,8,58,118,101,99,51,0,58, +115,116,101,112,0,18,101,100,103,101,0,0,18,120,0,59,120,0,0,0,0,58,115,116, +101,112,0,18,101,100,103,101,0,0,18,120,0,59,121,0,0,0,0,58,115,116,101,112, +0,18,101,100,103,101,0,0,18,120,0,59,122,0,0,0,0,0,0,0,1,0,12,0, +115,116,101,112,0,1,0,0,9,101,100,103,101,0,0,1,0,0,12,120,0,0,0,1, +8,58,118,101,99,52,0,58,115,116,101,112,0,18,101,100,103,101,0,0,18,120,0,59, +120,0,0,0,0,58,115,116,101,112,0,18,101,100,103,101,0,0,18,120,0,59,121,0, +0,0,0,58,115,116,101,112,0,18,101,100,103,101,0,0,18,120,0,59,122,0,0,0, +0,58,115,116,101,112,0,18,101,100,103,101,0,0,18,120,0,59,119,0,0,0,0,0, +0,0,1,0,10,0,115,116,101,112,0,1,0,0,10,101,100,103,101,0,0,1,0,0, +10,120,0,0,0,1,8,58,118,101,99,50,0,58,115,116,101,112,0,18,101,100,103,101, +0,59,120,0,0,18,120,0,59,120,0,0,0,0,58,115,116,101,112,0,18,101,100,103, +101,0,59,121,0,0,18,120,0,59,121,0,0,0,0,0,0,0,1,0,11,0,115,116, +101,112,0,1,0,0,11,101,100,103,101,0,0,1,0,0,11,120,0,0,0,1,8,58, +118,101,99,51,0,58,115,116,101,112,0,18,101,100,103,101,0,59,120,0,0,18,120,0, +59,120,0,0,0,0,58,115,116,101,112,0,18,101,100,103,101,0,59,121,0,0,18,120, +0,59,121,0,0,0,0,58,115,116,101,112,0,18,101,100,103,101,0,59,122,0,0,18, +120,0,59,122,0,0,0,0,0,0,0,1,0,12,0,115,116,101,112,0,1,0,0,12, +101,100,103,101,0,0,1,0,0,12,120,0,0,0,1,8,58,118,101,99,52,0,58,115, +116,101,112,0,18,101,100,103,101,0,59,120,0,0,18,120,0,59,120,0,0,0,0,58, +115,116,101,112,0,18,101,100,103,101,0,59,121,0,0,18,120,0,59,121,0,0,0,0, +58,115,116,101,112,0,18,101,100,103,101,0,59,122,0,0,18,120,0,59,122,0,0,0, +0,58,115,116,101,112,0,18,101,100,103,101,0,59,119,0,0,18,120,0,59,119,0,0, +0,0,0,0,0,1,0,9,0,115,109,111,111,116,104,115,116,101,112,0,1,0,0,9, +101,100,103,101,48,0,0,1,0,0,9,101,100,103,101,49,0,0,1,0,0,9,120,0, +0,0,1,3,2,1,9,1,116,0,2,58,99,108,97,109,112,0,18,120,0,18,101,100, +103,101,48,0,47,18,101,100,103,101,49,0,18,101,100,103,101,48,0,47,49,0,17,48, +0,48,0,0,0,17,49,0,48,0,0,0,0,0,0,8,18,116,0,18,116,0,48,17, +51,0,48,0,0,17,50,0,48,0,0,18,116,0,48,47,48,0,0,1,0,10,0,115, +109,111,111,116,104,115,116,101,112,0,1,0,0,9,101,100,103,101,48,0,0,1,0,0, +9,101,100,103,101,49,0,0,1,0,0,10,120,0,0,0,1,8,58,118,101,99,50,0, +58,115,109,111,111,116,104,115,116,101,112,0,18,101,100,103,101,48,0,0,18,101,100,103, +101,49,0,0,18,120,0,59,120,0,0,0,0,58,115,109,111,111,116,104,115,116,101,112, +0,18,101,100,103,101,48,0,0,18,101,100,103,101,49,0,0,18,120,0,59,121,0,0, +0,0,0,0,0,1,0,11,0,115,109,111,111,116,104,115,116,101,112,0,1,0,0,9, +101,100,103,101,48,0,0,1,0,0,9,101,100,103,101,49,0,0,1,0,0,11,120,0, +0,0,1,8,58,118,101,99,51,0,58,115,109,111,111,116,104,115,116,101,112,0,18,101, +100,103,101,48,0,0,18,101,100,103,101,49,0,0,18,120,0,59,120,0,0,0,0,58, +115,109,111,111,116,104,115,116,101,112,0,18,101,100,103,101,48,0,0,18,101,100,103,101, +49,0,0,18,120,0,59,121,0,0,0,0,58,115,109,111,111,116,104,115,116,101,112,0, +18,101,100,103,101,48,0,0,18,101,100,103,101,49,0,0,18,120,0,59,122,0,0,0, +0,0,0,0,1,0,12,0,115,109,111,111,116,104,115,116,101,112,0,1,0,0,9,101, +100,103,101,48,0,0,1,0,0,9,101,100,103,101,49,0,0,1,0,0,12,120,0,0, +0,1,8,58,118,101,99,52,0,58,115,109,111,111,116,104,115,116,101,112,0,18,101,100, +103,101,48,0,0,18,101,100,103,101,49,0,0,18,120,0,59,120,0,0,0,0,58,115, +109,111,111,116,104,115,116,101,112,0,18,101,100,103,101,48,0,0,18,101,100,103,101,49, +0,0,18,120,0,59,121,0,0,0,0,58,115,109,111,111,116,104,115,116,101,112,0,18, +101,100,103,101,48,0,0,18,101,100,103,101,49,0,0,18,120,0,59,122,0,0,0,0, +58,115,109,111,111,116,104,115,116,101,112,0,18,101,100,103,101,48,0,0,18,101,100,103, +101,49,0,0,18,120,0,59,119,0,0,0,0,0,0,0,1,0,10,0,115,109,111,111, +116,104,115,116,101,112,0,1,0,0,10,101,100,103,101,48,0,0,1,0,0,10,101,100, +103,101,49,0,0,1,0,0,10,120,0,0,0,1,8,58,118,101,99,50,0,58,115,109, +111,111,116,104,115,116,101,112,0,18,101,100,103,101,48,0,59,120,0,0,18,101,100,103, +101,49,0,59,120,0,0,18,120,0,59,120,0,0,0,0,58,115,109,111,111,116,104,115, +116,101,112,0,18,101,100,103,101,48,0,59,121,0,0,18,101,100,103,101,49,0,59,121, +0,0,18,120,0,59,121,0,0,0,0,0,0,0,1,0,11,0,115,109,111,111,116,104, +115,116,101,112,0,1,0,0,11,101,100,103,101,48,0,0,1,0,0,11,101,100,103,101, +49,0,0,1,0,0,11,120,0,0,0,1,8,58,118,101,99,51,0,58,115,109,111,111, +116,104,115,116,101,112,0,18,101,100,103,101,48,0,59,120,0,0,18,101,100,103,101,49, +0,59,120,0,0,18,120,0,59,120,0,0,0,0,58,115,109,111,111,116,104,115,116,101, +112,0,18,101,100,103,101,48,0,59,121,0,0,18,101,100,103,101,49,0,59,121,0,0, +18,120,0,59,121,0,0,0,0,58,115,109,111,111,116,104,115,116,101,112,0,18,101,100, +103,101,48,0,59,122,0,0,18,101,100,103,101,49,0,59,122,0,0,18,120,0,59,122, +0,0,0,0,0,0,0,1,0,12,0,115,109,111,111,116,104,115,116,101,112,0,1,0, +0,12,101,100,103,101,48,0,0,1,0,0,12,101,100,103,101,49,0,0,1,0,0,12, +120,0,0,0,1,8,58,118,101,99,52,0,58,115,109,111,111,116,104,115,116,101,112,0, +18,101,100,103,101,48,0,59,120,0,0,18,101,100,103,101,49,0,59,120,0,0,18,120, +0,59,120,0,0,0,0,58,115,109,111,111,116,104,115,116,101,112,0,18,101,100,103,101, +48,0,59,121,0,0,18,101,100,103,101,49,0,59,121,0,0,18,120,0,59,121,0,0, +0,0,58,115,109,111,111,116,104,115,116,101,112,0,18,101,100,103,101,48,0,59,122,0, +0,18,101,100,103,101,49,0,59,122,0,0,18,120,0,59,122,0,0,0,0,58,115,109, +111,111,116,104,115,116,101,112,0,18,101,100,103,101,48,0,59,119,0,0,18,101,100,103, +101,49,0,59,119,0,0,18,120,0,59,119,0,0,0,0,0,0,0,1,0,9,0,100, +111,116,0,1,0,0,9,120,0,0,1,0,0,9,121,0,0,0,1,8,18,120,0,18, +121,0,48,0,0,1,0,9,0,100,111,116,0,1,0,0,10,120,0,0,1,0,0,10, +121,0,0,0,1,8,58,100,111,116,0,18,120,0,59,120,0,0,18,121,0,59,120,0, +0,0,58,100,111,116,0,18,120,0,59,121,0,0,18,121,0,59,121,0,0,0,46,0, +0,1,0,9,0,100,111,116,0,1,0,0,11,120,0,0,1,0,0,11,121,0,0,0, +1,8,58,100,111,116,0,18,120,0,59,120,0,0,18,121,0,59,120,0,0,0,58,100, +111,116,0,18,120,0,59,121,0,0,18,121,0,59,121,0,0,0,46,58,100,111,116,0, +18,120,0,59,122,0,0,18,121,0,59,122,0,0,0,46,0,0,1,0,9,0,100,111, +116,0,1,0,0,12,120,0,0,1,0,0,12,121,0,0,0,1,8,58,100,111,116,0, +18,120,0,59,120,0,0,18,121,0,59,120,0,0,0,58,100,111,116,0,18,120,0,59, +121,0,0,18,121,0,59,121,0,0,0,46,58,100,111,116,0,18,120,0,59,122,0,0, +18,121,0,59,122,0,0,0,46,58,100,111,116,0,18,120,0,59,119,0,0,18,121,0, +59,119,0,0,0,46,0,0,1,0,9,0,108,101,110,103,116,104,0,1,0,0,9,120, +0,0,0,1,8,58,115,113,114,116,0,58,100,111,116,0,18,120,0,0,18,120,0,0, +0,0,0,0,0,1,0,9,0,108,101,110,103,116,104,0,1,0,0,10,120,0,0,0, +1,8,58,115,113,114,116,0,58,100,111,116,0,18,120,0,0,18,120,0,0,0,0,0, +0,0,1,0,9,0,108,101,110,103,116,104,0,1,0,0,11,120,0,0,0,1,8,58, +115,113,114,116,0,58,100,111,116,0,18,120,0,0,18,120,0,0,0,0,0,0,0,1, +0,9,0,108,101,110,103,116,104,0,1,0,0,12,120,0,0,0,1,8,58,115,113,114, +116,0,58,100,111,116,0,18,120,0,0,18,120,0,0,0,0,0,0,0,1,0,9,0, +100,105,115,116,97,110,99,101,0,1,0,0,9,120,0,0,1,0,0,9,121,0,0,0, +1,8,58,108,101,110,103,116,104,0,18,120,0,18,121,0,47,0,0,0,0,1,0,9, +0,100,105,115,116,97,110,99,101,0,1,0,0,10,120,0,0,1,0,0,10,121,0,0, +0,1,8,58,108,101,110,103,116,104,0,18,120,0,18,121,0,47,0,0,0,0,1,0, +9,0,100,105,115,116,97,110,99,101,0,1,0,0,11,120,0,0,1,0,0,11,121,0, +0,0,1,8,58,108,101,110,103,116,104,0,18,120,0,18,121,0,47,0,0,0,0,1, +0,9,0,100,105,115,116,97,110,99,101,0,1,0,0,12,120,0,0,1,0,0,12,121, +0,0,0,1,8,58,108,101,110,103,116,104,0,18,120,0,18,121,0,47,0,0,0,0, +1,0,11,0,99,114,111,115,115,0,1,0,0,11,120,0,0,1,0,0,11,121,0,0, +0,1,8,58,118,101,99,51,0,18,120,0,59,121,0,18,121,0,59,122,0,48,18,121, +0,59,121,0,18,120,0,59,122,0,48,47,0,18,120,0,59,122,0,18,121,0,59,120, +0,48,18,121,0,59,122,0,18,120,0,59,120,0,48,47,0,18,120,0,59,120,0,18, +121,0,59,121,0,48,18,121,0,59,120,0,18,120,0,59,121,0,48,47,0,0,0,0, +1,0,9,0,110,111,114,109,97,108,105,122,101,0,1,0,0,9,120,0,0,0,1,8, +17,49,0,48,0,0,0,0,1,0,10,0,110,111,114,109,97,108,105,122,101,0,1,0, +0,10,120,0,0,0,1,8,18,120,0,58,108,101,110,103,116,104,0,18,120,0,0,0, +49,0,0,1,0,11,0,110,111,114,109,97,108,105,122,101,0,1,0,0,11,120,0,0, +0,1,8,18,120,0,58,108,101,110,103,116,104,0,18,120,0,0,0,49,0,0,1,0, +12,0,110,111,114,109,97,108,105,122,101,0,1,0,0,12,120,0,0,0,1,8,18,120, +0,58,108,101,110,103,116,104,0,18,120,0,0,0,49,0,0,1,0,9,0,102,97,99, +101,102,111,114,119,97,114,100,0,1,0,0,9,78,0,0,1,0,0,9,73,0,0,1, +0,0,9,78,114,101,102,0,0,0,1,8,58,100,111,116,0,18,78,114,101,102,0,0, +18,73,0,0,0,17,48,0,48,0,0,40,18,78,0,18,78,0,54,31,0,0,1,0, +10,0,102,97,99,101,102,111,114,119,97,114,100,0,1,0,0,10,78,0,0,1,0,0, +10,73,0,0,1,0,0,10,78,114,101,102,0,0,0,1,8,58,100,111,116,0,18,78, +114,101,102,0,0,18,73,0,0,0,17,48,0,48,0,0,40,18,78,0,18,78,0,54, +31,0,0,1,0,11,0,102,97,99,101,102,111,114,119,97,114,100,0,1,0,0,11,78, +0,0,1,0,0,11,73,0,0,1,0,0,11,78,114,101,102,0,0,0,1,8,58,100, +111,116,0,18,78,114,101,102,0,0,18,73,0,0,0,17,48,0,48,0,0,40,18,78, +0,18,78,0,54,31,0,0,1,0,12,0,102,97,99,101,102,111,114,119,97,114,100,0, +1,0,0,12,78,0,0,1,0,0,12,73,0,0,1,0,0,12,78,114,101,102,0,0, +0,1,8,58,100,111,116,0,18,78,114,101,102,0,0,18,73,0,0,0,17,48,0,48, +0,0,40,18,78,0,18,78,0,54,31,0,0,1,0,9,0,114,101,102,108,101,99,116, +0,1,0,0,9,73,0,0,1,0,0,9,78,0,0,0,1,8,18,73,0,17,50,0, +48,0,0,58,100,111,116,0,18,78,0,0,18,73,0,0,0,48,18,78,0,48,47,0, +0,1,0,10,0,114,101,102,108,101,99,116,0,1,0,0,10,73,0,0,1,0,0,10, +78,0,0,0,1,8,18,73,0,17,50,0,48,0,0,58,100,111,116,0,18,78,0,0, +18,73,0,0,0,48,18,78,0,48,47,0,0,1,0,11,0,114,101,102,108,101,99,116, +0,1,0,0,11,73,0,0,1,0,0,11,78,0,0,0,1,8,18,73,0,17,50,0, +48,0,0,58,100,111,116,0,18,78,0,0,18,73,0,0,0,48,18,78,0,48,47,0, +0,1,0,12,0,114,101,102,108,101,99,116,0,1,0,0,12,73,0,0,1,0,0,12, +78,0,0,0,1,8,18,73,0,17,50,0,48,0,0,58,100,111,116,0,18,78,0,0, +18,73,0,0,0,48,18,78,0,48,47,0,0,1,0,9,0,114,101,102,114,97,99,116, +0,1,0,0,9,73,0,0,1,0,0,9,78,0,0,1,0,0,9,101,116,97,0,0, +0,1,3,2,1,9,1,107,0,2,17,49,0,48,0,0,18,101,116,97,0,18,101,116, +97,0,48,17,49,0,48,0,0,58,100,111,116,0,18,78,0,0,18,73,0,0,0,58, +100,111,116,0,18,78,0,0,18,73,0,0,0,48,47,48,47,0,0,10,18,107,0,17, +48,0,48,0,0,40,0,8,17,48,0,48,0,0,0,9,14,0,8,18,101,116,97,0, +18,73,0,48,18,101,116,97,0,58,100,111,116,0,18,78,0,0,18,73,0,0,0,48, +58,115,113,114,116,0,18,107,0,0,0,46,18,78,0,48,47,0,0,1,0,10,0,114, +101,102,114,97,99,116,0,1,0,0,10,73,0,0,1,0,0,10,78,0,0,1,0,0, +9,101,116,97,0,0,0,1,3,2,1,9,1,107,0,2,17,49,0,48,0,0,18,101, +116,97,0,18,101,116,97,0,48,17,49,0,48,0,0,58,100,111,116,0,18,78,0,0, +18,73,0,0,0,58,100,111,116,0,18,78,0,0,18,73,0,0,0,48,47,48,47,0, +0,10,18,107,0,17,48,0,48,0,0,40,0,8,58,118,101,99,50,0,17,48,0,48, +0,0,0,0,0,9,14,0,8,18,101,116,97,0,18,73,0,48,18,101,116,97,0,58, +100,111,116,0,18,78,0,0,18,73,0,0,0,48,58,115,113,114,116,0,18,107,0,0, +0,46,18,78,0,48,47,0,0,1,0,11,0,114,101,102,114,97,99,116,0,1,0,0, +11,73,0,0,1,0,0,11,78,0,0,1,0,0,9,101,116,97,0,0,0,1,3,2, +1,9,1,107,0,2,17,49,0,48,0,0,18,101,116,97,0,18,101,116,97,0,48,17, +49,0,48,0,0,58,100,111,116,0,18,78,0,0,18,73,0,0,0,58,100,111,116,0, +18,78,0,0,18,73,0,0,0,48,47,48,47,0,0,10,18,107,0,17,48,0,48,0, +0,40,0,8,58,118,101,99,51,0,17,48,0,48,0,0,0,0,0,9,14,0,8,18, +101,116,97,0,18,73,0,48,18,101,116,97,0,58,100,111,116,0,18,78,0,0,18,73, +0,0,0,48,58,115,113,114,116,0,18,107,0,0,0,46,18,78,0,48,47,0,0,1, +0,12,0,114,101,102,114,97,99,116,0,1,0,0,12,73,0,0,1,0,0,12,78,0, +0,1,0,0,9,101,116,97,0,0,0,1,3,2,1,9,1,107,0,2,17,49,0,48, +0,0,18,101,116,97,0,18,101,116,97,0,48,17,49,0,48,0,0,58,100,111,116,0, +18,78,0,0,18,73,0,0,0,58,100,111,116,0,18,78,0,0,18,73,0,0,0,48, +47,48,47,0,0,10,18,107,0,17,48,0,48,0,0,40,0,8,58,118,101,99,52,0, +17,48,0,48,0,0,0,0,0,9,14,0,8,18,101,116,97,0,18,73,0,48,18,101, +116,97,0,58,100,111,116,0,18,78,0,0,18,73,0,0,0,48,58,115,113,114,116,0, +18,107,0,0,0,46,18,78,0,48,47,0,0,1,0,13,0,109,97,116,114,105,120,67, +111,109,112,77,117,108,116,0,1,0,0,13,120,0,0,1,0,0,13,121,0,0,0,1, +8,58,109,97,116,50,0,18,120,0,16,8,48,0,57,59,120,0,18,121,0,16,8,48, +0,57,59,120,0,48,0,18,120,0,16,8,48,0,57,59,121,0,18,121,0,16,8,48, +0,57,59,121,0,48,0,18,120,0,16,10,49,0,57,59,120,0,18,121,0,16,10,49, +0,57,59,120,0,48,0,18,120,0,16,10,49,0,57,59,121,0,18,121,0,16,10,49, +0,57,59,121,0,48,0,0,0,0,1,0,14,0,109,97,116,114,105,120,67,111,109,112, +77,117,108,116,0,1,0,0,14,120,0,0,1,0,0,14,121,0,0,0,1,8,58,109, +97,116,52,0,18,120,0,16,8,48,0,57,59,120,0,18,121,0,16,8,48,0,57,59, +120,0,48,0,18,120,0,16,8,48,0,57,59,121,0,18,121,0,16,8,48,0,57,59, +121,0,48,0,18,120,0,16,8,48,0,57,59,122,0,18,121,0,16,8,48,0,57,59, +122,0,48,0,18,120,0,16,10,49,0,57,59,120,0,18,121,0,16,10,49,0,57,59, +120,0,48,0,18,120,0,16,10,49,0,57,59,121,0,18,121,0,16,10,49,0,57,59, +121,0,48,0,18,120,0,16,10,49,0,57,59,122,0,18,121,0,16,10,49,0,57,59, +122,0,48,0,18,120,0,16,10,50,0,57,59,120,0,18,121,0,16,10,50,0,57,59, +120,0,48,0,18,120,0,16,10,50,0,57,59,121,0,18,121,0,16,10,50,0,57,59, +121,0,48,0,18,120,0,16,10,50,0,57,59,122,0,18,121,0,16,10,50,0,57,59, +122,0,48,0,0,0,0,1,0,15,0,109,97,116,114,105,120,67,111,109,112,77,117,108, +116,0,1,0,0,15,120,0,0,1,0,0,15,121,0,0,0,1,8,58,109,97,116,52, +0,18,120,0,16,8,48,0,57,59,120,0,18,121,0,16,8,48,0,57,59,120,0,48, +0,18,120,0,16,8,48,0,57,59,121,0,18,121,0,16,8,48,0,57,59,121,0,48, +0,18,120,0,16,8,48,0,57,59,122,0,18,121,0,16,8,48,0,57,59,122,0,48, +18,120,0,16,8,48,0,57,59,119,0,18,121,0,16,8,48,0,57,59,119,0,48,46, +0,18,120,0,16,10,49,0,57,59,120,0,18,121,0,16,10,49,0,57,59,120,0,48, +0,18,120,0,16,10,49,0,57,59,121,0,18,121,0,16,10,49,0,57,59,121,0,48, +0,18,120,0,16,10,49,0,57,59,122,0,18,121,0,16,10,49,0,57,59,122,0,48, +18,120,0,16,10,49,0,57,59,119,0,18,121,0,16,10,49,0,57,59,119,0,48,46, +0,18,120,0,16,10,50,0,57,59,120,0,18,121,0,16,10,50,0,57,59,120,0,48, +0,18,120,0,16,10,50,0,57,59,121,0,18,121,0,16,10,50,0,57,59,121,0,48, +0,18,120,0,16,10,50,0,57,59,122,0,18,121,0,16,10,50,0,57,59,122,0,48, +18,120,0,16,10,50,0,57,59,119,0,18,121,0,16,10,50,0,57,59,119,0,48,46, +0,18,120,0,16,10,51,0,57,59,120,0,18,121,0,16,10,51,0,57,59,120,0,48, +0,18,120,0,16,10,51,0,57,59,121,0,18,121,0,16,10,51,0,57,59,121,0,48, +0,18,120,0,16,10,51,0,57,59,122,0,18,121,0,16,10,51,0,57,59,122,0,48, +18,120,0,16,10,51,0,57,59,119,0,18,121,0,16,10,51,0,57,59,119,0,48,46, +0,0,0,0,1,0,2,0,108,101,115,115,84,104,97,110,0,1,0,0,10,120,0,0, +1,0,0,10,121,0,0,0,1,8,58,98,118,101,99,50,0,18,120,0,59,120,0,18, +121,0,59,120,0,40,0,18,120,0,59,121,0,18,121,0,59,121,0,40,0,0,0,0, +1,0,3,0,108,101,115,115,84,104,97,110,0,1,0,0,11,120,0,0,1,0,0,11, +121,0,0,0,1,8,58,98,118,101,99,51,0,18,120,0,59,120,0,18,121,0,59,120, +0,40,0,18,120,0,59,121,0,18,121,0,59,121,0,40,0,18,120,0,59,122,0,18, +121,0,59,122,0,40,0,0,0,0,1,0,4,0,108,101,115,115,84,104,97,110,0,1, +0,0,12,120,0,0,1,0,0,12,121,0,0,0,1,8,58,98,118,101,99,52,0,18, +120,0,59,120,0,18,121,0,59,120,0,40,0,18,120,0,59,121,0,18,121,0,59,121, +0,40,0,18,120,0,59,122,0,18,121,0,59,122,0,40,0,18,120,0,59,119,0,18, +121,0,59,119,0,40,0,0,0,0,1,0,2,0,108,101,115,115,84,104,97,110,0,1, +0,0,6,120,0,0,1,0,0,6,121,0,0,0,1,8,58,98,118,101,99,50,0,18, +120,0,59,120,0,18,121,0,59,120,0,40,0,18,120,0,59,121,0,18,121,0,59,121, +0,40,0,0,0,0,1,0,3,0,108,101,115,115,84,104,97,110,0,1,0,0,7,120, +0,0,1,0,0,7,121,0,0,0,1,8,58,98,118,101,99,51,0,18,120,0,59,120, +0,18,121,0,59,120,0,40,0,18,120,0,59,121,0,18,121,0,59,121,0,40,0,18, +120,0,59,122,0,18,121,0,59,122,0,40,0,0,0,0,1,0,4,0,108,101,115,115, +84,104,97,110,0,1,0,0,8,120,0,0,1,0,0,8,121,0,0,0,1,8,58,98, +118,101,99,52,0,18,120,0,59,120,0,18,121,0,59,120,0,40,0,18,120,0,59,121, +0,18,121,0,59,121,0,40,0,18,120,0,59,122,0,18,121,0,59,122,0,40,0,18, +120,0,59,119,0,18,121,0,59,119,0,40,0,0,0,0,1,0,2,0,108,101,115,115, +84,104,97,110,69,113,117,97,108,0,1,0,0,10,120,0,0,1,0,0,10,121,0,0, +0,1,8,58,98,118,101,99,50,0,18,120,0,59,120,0,18,121,0,59,120,0,42,0, +18,120,0,59,121,0,18,121,0,59,121,0,42,0,0,0,0,1,0,3,0,108,101,115, +115,84,104,97,110,69,113,117,97,108,0,1,0,0,11,120,0,0,1,0,0,11,121,0, +0,0,1,8,58,98,118,101,99,51,0,18,120,0,59,120,0,18,121,0,59,120,0,42, +0,18,120,0,59,121,0,18,121,0,59,121,0,42,0,18,120,0,59,122,0,18,121,0, +59,122,0,42,0,0,0,0,1,0,4,0,108,101,115,115,84,104,97,110,69,113,117,97, +108,0,1,0,0,12,120,0,0,1,0,0,12,121,0,0,0,1,8,58,98,118,101,99, +52,0,18,120,0,59,120,0,18,121,0,59,120,0,42,0,18,120,0,59,121,0,18,121, +0,59,121,0,42,0,18,120,0,59,122,0,18,121,0,59,122,0,42,0,18,120,0,59, +119,0,18,121,0,59,119,0,42,0,0,0,0,1,0,2,0,108,101,115,115,84,104,97, +110,69,113,117,97,108,0,1,0,0,6,120,0,0,1,0,0,6,121,0,0,0,1,8, +58,98,118,101,99,50,0,18,120,0,59,120,0,18,121,0,59,120,0,42,0,18,120,0, +59,121,0,18,121,0,59,121,0,42,0,0,0,0,1,0,3,0,108,101,115,115,84,104, +97,110,69,113,117,97,108,0,1,0,0,7,120,0,0,1,0,0,7,121,0,0,0,1, +8,58,98,118,101,99,51,0,18,120,0,59,120,0,18,121,0,59,120,0,42,0,18,120, +0,59,121,0,18,121,0,59,121,0,42,0,18,120,0,59,122,0,18,121,0,59,122,0, +42,0,0,0,0,1,0,4,0,108,101,115,115,84,104,97,110,69,113,117,97,108,0,1, +0,0,8,120,0,0,1,0,0,8,121,0,0,0,1,8,58,98,118,101,99,52,0,18, +120,0,59,120,0,18,121,0,59,120,0,42,0,18,120,0,59,121,0,18,121,0,59,121, +0,42,0,18,120,0,59,122,0,18,121,0,59,122,0,42,0,18,120,0,59,119,0,18, +121,0,59,119,0,42,0,0,0,0,1,0,2,0,103,114,101,97,116,101,114,84,104,97, +110,0,1,0,0,10,120,0,0,1,0,0,10,121,0,0,0,1,8,58,98,118,101,99, +50,0,18,120,0,59,120,0,18,121,0,59,120,0,41,0,18,120,0,59,121,0,18,121, +0,59,121,0,41,0,0,0,0,1,0,3,0,103,114,101,97,116,101,114,84,104,97,110, +0,1,0,0,11,120,0,0,1,0,0,11,121,0,0,0,1,8,58,98,118,101,99,51, +0,18,120,0,59,120,0,18,121,0,59,120,0,41,0,18,120,0,59,121,0,18,121,0, +59,121,0,41,0,18,120,0,59,122,0,18,121,0,59,122,0,41,0,0,0,0,1,0, +4,0,103,114,101,97,116,101,114,84,104,97,110,0,1,0,0,12,120,0,0,1,0,0, +12,121,0,0,0,1,8,58,98,118,101,99,52,0,18,120,0,59,120,0,18,121,0,59, +120,0,41,0,18,120,0,59,121,0,18,121,0,59,121,0,41,0,18,120,0,59,122,0, +18,121,0,59,122,0,41,0,18,120,0,59,119,0,18,121,0,59,119,0,41,0,0,0, +0,1,0,2,0,103,114,101,97,116,101,114,84,104,97,110,0,1,0,0,6,120,0,0, +1,0,0,6,121,0,0,0,1,8,58,98,118,101,99,50,0,18,120,0,59,120,0,18, +121,0,59,120,0,41,0,18,120,0,59,121,0,18,121,0,59,121,0,41,0,0,0,0, +1,0,3,0,103,114,101,97,116,101,114,84,104,97,110,0,1,0,0,7,120,0,0,1, +0,0,7,121,0,0,0,1,8,58,98,118,101,99,51,0,18,120,0,59,120,0,18,121, +0,59,120,0,41,0,18,120,0,59,121,0,18,121,0,59,121,0,41,0,18,120,0,59, +122,0,18,121,0,59,122,0,41,0,0,0,0,1,0,4,0,103,114,101,97,116,101,114, +84,104,97,110,0,1,0,0,8,120,0,0,1,0,0,8,121,0,0,0,1,8,58,98, +118,101,99,52,0,18,120,0,59,120,0,18,121,0,59,120,0,41,0,18,120,0,59,121, +0,18,121,0,59,121,0,41,0,18,120,0,59,122,0,18,121,0,59,122,0,41,0,18, +120,0,59,119,0,18,121,0,59,119,0,41,0,0,0,0,1,0,2,0,103,114,101,97, +116,101,114,84,104,97,110,69,113,117,97,108,0,1,0,0,10,120,0,0,1,0,0,10, +121,0,0,0,1,8,58,98,118,101,99,50,0,18,120,0,59,120,0,18,121,0,59,120, +0,43,0,18,120,0,59,121,0,18,121,0,59,121,0,43,0,0,0,0,1,0,3,0, +103,114,101,97,116,101,114,84,104,97,110,69,113,117,97,108,0,1,0,0,11,120,0,0, +1,0,0,11,121,0,0,0,1,8,58,98,118,101,99,51,0,18,120,0,59,120,0,18, +121,0,59,120,0,43,0,18,120,0,59,121,0,18,121,0,59,121,0,43,0,18,120,0, +59,122,0,18,121,0,59,122,0,43,0,0,0,0,1,0,4,0,103,114,101,97,116,101, +114,84,104,97,110,69,113,117,97,108,0,1,0,0,12,120,0,0,1,0,0,12,121,0, +0,0,1,8,58,98,118,101,99,52,0,18,120,0,59,120,0,18,121,0,59,120,0,43, +0,18,120,0,59,121,0,18,121,0,59,121,0,43,0,18,120,0,59,122,0,18,121,0, +59,122,0,43,0,18,120,0,59,119,0,18,121,0,59,119,0,43,0,0,0,0,1,0, +2,0,103,114,101,97,116,101,114,84,104,97,110,69,113,117,97,108,0,1,0,0,6,120, +0,0,1,0,0,6,121,0,0,0,1,8,58,98,118,101,99,50,0,18,120,0,59,120, +0,18,121,0,59,120,0,43,0,18,120,0,59,121,0,18,121,0,59,121,0,43,0,0, +0,0,1,0,3,0,103,114,101,97,116,101,114,84,104,97,110,69,113,117,97,108,0,1, +0,0,7,120,0,0,1,0,0,7,121,0,0,0,1,8,58,98,118,101,99,51,0,18, +120,0,59,120,0,18,121,0,59,120,0,43,0,18,120,0,59,121,0,18,121,0,59,121, +0,43,0,18,120,0,59,122,0,18,121,0,59,122,0,43,0,0,0,0,1,0,4,0, +103,114,101,97,116,101,114,84,104,97,110,69,113,117,97,108,0,1,0,0,8,120,0,0, +1,0,0,8,121,0,0,0,1,8,58,98,118,101,99,52,0,18,120,0,59,120,0,18, +121,0,59,120,0,43,0,18,120,0,59,121,0,18,121,0,59,121,0,43,0,18,120,0, +59,122,0,18,121,0,59,122,0,43,0,18,120,0,59,119,0,18,121,0,59,119,0,43, +0,0,0,0,1,0,2,0,101,113,117,97,108,0,1,0,0,10,120,0,0,1,0,0, +10,121,0,0,0,1,8,58,98,118,101,99,50,0,18,120,0,59,120,0,18,121,0,59, +120,0,38,0,18,120,0,59,121,0,18,121,0,59,121,0,38,0,0,0,0,1,0,3, +0,101,113,117,97,108,0,1,0,0,11,120,0,0,1,0,0,11,121,0,0,0,1,8, +58,98,118,101,99,51,0,18,120,0,59,120,0,18,121,0,59,120,0,38,0,18,120,0, +59,121,0,18,121,0,59,121,0,38,0,18,120,0,59,122,0,18,121,0,59,122,0,38, +0,0,0,0,1,0,4,0,101,113,117,97,108,0,1,0,0,12,120,0,0,1,0,0, +12,121,0,0,0,1,8,58,98,118,101,99,52,0,18,120,0,59,120,0,18,121,0,59, +120,0,38,0,18,120,0,59,121,0,18,121,0,59,121,0,38,0,18,120,0,59,122,0, +18,121,0,59,122,0,38,0,18,120,0,59,119,0,18,121,0,59,119,0,38,0,0,0, +0,1,0,2,0,101,113,117,97,108,0,1,0,0,6,120,0,0,1,0,0,6,121,0, +0,0,1,8,58,98,118,101,99,50,0,18,120,0,59,120,0,18,121,0,59,120,0,38, +0,18,120,0,59,121,0,18,121,0,59,121,0,38,0,0,0,0,1,0,3,0,101,113, +117,97,108,0,1,0,0,7,120,0,0,1,0,0,7,121,0,0,0,1,8,58,98,118, +101,99,51,0,18,120,0,59,120,0,18,121,0,59,120,0,38,0,18,120,0,59,121,0, +18,121,0,59,121,0,38,0,18,120,0,59,122,0,18,121,0,59,122,0,38,0,0,0, +0,1,0,4,0,101,113,117,97,108,0,1,0,0,8,120,0,0,1,0,0,8,121,0, +0,0,1,8,58,98,118,101,99,52,0,18,120,0,59,120,0,18,121,0,59,120,0,38, +0,18,120,0,59,121,0,18,121,0,59,121,0,38,0,18,120,0,59,122,0,18,121,0, +59,122,0,38,0,18,120,0,59,119,0,18,121,0,59,119,0,38,0,0,0,0,1,0, +2,0,110,111,116,69,113,117,97,108,0,1,0,0,10,120,0,0,1,0,0,10,121,0, +0,0,1,8,58,98,118,101,99,50,0,18,120,0,59,120,0,18,121,0,59,120,0,39, +0,18,120,0,59,121,0,18,121,0,59,121,0,39,0,0,0,0,1,0,3,0,110,111, +116,69,113,117,97,108,0,1,0,0,11,120,0,0,1,0,0,11,121,0,0,0,1,8, +58,98,118,101,99,51,0,18,120,0,59,120,0,18,121,0,59,120,0,39,0,18,120,0, +59,121,0,18,121,0,59,121,0,39,0,18,120,0,59,122,0,18,121,0,59,122,0,39, +0,0,0,0,1,0,4,0,110,111,116,69,113,117,97,108,0,1,0,0,12,120,0,0, +1,0,0,12,121,0,0,0,1,8,58,98,118,101,99,52,0,18,120,0,59,120,0,18, +121,0,59,120,0,39,0,18,120,0,59,121,0,18,121,0,59,121,0,39,0,18,120,0, +59,122,0,18,121,0,59,122,0,39,0,18,120,0,59,119,0,18,121,0,59,119,0,39, +0,0,0,0,1,0,2,0,110,111,116,69,113,117,97,108,0,1,0,0,6,120,0,0, +1,0,0,6,121,0,0,0,1,8,58,98,118,101,99,50,0,18,120,0,59,120,0,18, +121,0,59,120,0,39,0,18,120,0,59,121,0,18,121,0,59,121,0,39,0,0,0,0, +1,0,3,0,110,111,116,69,113,117,97,108,0,1,0,0,7,120,0,0,1,0,0,7, +121,0,0,0,1,8,58,98,118,101,99,51,0,18,120,0,59,120,0,18,121,0,59,120, +0,39,0,18,120,0,59,121,0,18,121,0,59,121,0,39,0,18,120,0,59,122,0,18, +121,0,59,122,0,39,0,0,0,0,1,0,4,0,110,111,116,69,113,117,97,108,0,1, +0,0,8,120,0,0,1,0,0,8,121,0,0,0,1,8,58,98,118,101,99,52,0,18, +120,0,59,120,0,18,121,0,59,120,0,39,0,18,120,0,59,121,0,18,121,0,59,121, +0,39,0,18,120,0,59,122,0,18,121,0,59,122,0,39,0,18,120,0,59,119,0,18, +121,0,59,119,0,39,0,0,0,0,1,0,1,0,97,110,121,0,1,0,0,2,120,0, +0,0,1,8,18,120,0,59,120,0,18,120,0,59,121,0,32,0,0,1,0,1,0,97, +110,121,0,1,0,0,3,120,0,0,0,1,8,18,120,0,59,120,0,18,120,0,59,121, +0,32,18,120,0,59,122,0,32,0,0,1,0,1,0,97,110,121,0,1,0,0,4,120, +0,0,0,1,8,18,120,0,59,120,0,18,120,0,59,121,0,32,18,120,0,59,122,0, +32,18,120,0,59,119,0,32,0,0,1,0,1,0,97,108,108,0,1,0,0,2,120,0, +0,0,1,8,18,120,0,59,120,0,18,120,0,59,121,0,34,0,0,1,0,1,0,97, +108,108,0,1,0,0,3,120,0,0,0,1,8,18,120,0,59,120,0,18,120,0,59,121, +0,34,18,120,0,59,122,0,34,0,0,1,0,1,0,97,108,108,0,1,0,0,4,120, +0,0,0,1,8,18,120,0,59,120,0,18,120,0,59,121,0,34,18,120,0,59,122,0, +34,18,120,0,59,119,0,34,0,0,1,0,2,0,110,111,116,0,1,0,0,2,120,0, +0,0,1,8,58,98,118,101,99,50,0,18,120,0,59,120,0,56,0,18,120,0,59,121, +0,56,0,0,0,0,1,0,3,0,110,111,116,0,1,0,0,3,120,0,0,0,1,8, +58,98,118,101,99,51,0,18,120,0,59,120,0,56,0,18,120,0,59,121,0,56,0,18, +120,0,59,122,0,56,0,0,0,0,1,0,4,0,110,111,116,0,1,0,0,4,120,0, +0,0,1,8,58,98,118,101,99,52,0,18,120,0,59,120,0,56,0,18,120,0,59,121, +0,56,0,18,120,0,59,122,0,56,0,18,120,0,59,119,0,56,0,0,0,0,1,0, +12,0,116,101,120,116,117,114,101,49,68,0,1,0,0,16,115,97,109,112,108,101,114,0, +0,1,0,0,9,99,111,111,114,100,0,0,0,1,8,58,118,101,99,52,0,17,48,0, +48,0,0,0,0,0,0,1,0,12,0,116,101,120,116,117,114,101,49,68,80,114,111,106, +0,1,0,0,16,115,97,109,112,108,101,114,0,0,1,0,0,10,99,111,111,114,100,0, +0,0,1,8,58,116,101,120,116,117,114,101,49,68,0,18,115,97,109,112,108,101,114,0, +0,18,99,111,111,114,100,0,59,115,0,18,99,111,111,114,100,0,59,116,0,49,0,0, +0,0,1,0,12,0,116,101,120,116,117,114,101,49,68,80,114,111,106,0,1,0,0,16, +115,97,109,112,108,101,114,0,0,1,0,0,12,99,111,111,114,100,0,0,0,1,8,58, +116,101,120,116,117,114,101,49,68,0,18,115,97,109,112,108,101,114,0,0,18,99,111,111, +114,100,0,59,115,0,18,99,111,111,114,100,0,59,113,0,49,0,0,0,0,1,0,12, +0,116,101,120,116,117,114,101,50,68,0,1,0,0,17,115,97,109,112,108,101,114,0,0, +1,0,0,10,99,111,111,114,100,0,0,0,1,8,58,118,101,99,52,0,17,48,0,48, +0,0,0,0,0,0,1,0,12,0,116,101,120,116,117,114,101,50,68,80,114,111,106,0, +1,0,0,17,115,97,109,112,108,101,114,0,0,1,0,0,11,99,111,111,114,100,0,0, +0,1,8,58,116,101,120,116,117,114,101,50,68,0,18,115,97,109,112,108,101,114,0,0, +58,118,101,99,50,0,18,99,111,111,114,100,0,59,115,0,18,99,111,111,114,100,0,59, +112,0,49,0,18,99,111,111,114,100,0,59,116,0,18,99,111,111,114,100,0,59,112,0, +49,0,0,0,0,0,0,1,0,12,0,116,101,120,116,117,114,101,50,68,80,114,111,106, +0,1,0,0,17,115,97,109,112,108,101,114,0,0,1,0,0,12,99,111,111,114,100,0, +0,0,1,8,58,116,101,120,116,117,114,101,50,68,0,18,115,97,109,112,108,101,114,0, +0,58,118,101,99,50,0,18,99,111,111,114,100,0,59,115,0,18,99,111,111,114,100,0, +59,113,0,49,0,18,99,111,111,114,100,0,59,116,0,18,99,111,111,114,100,0,59,113, +0,49,0,0,0,0,0,0,1,0,12,0,116,101,120,116,117,114,101,51,68,0,1,0, +0,18,115,97,109,112,108,101,114,0,0,1,0,0,11,99,111,111,114,100,0,0,0,1, +8,58,118,101,99,52,0,17,48,0,48,0,0,0,0,0,0,1,0,12,0,116,101,120, +116,117,114,101,51,68,80,114,111,106,0,1,0,0,18,115,97,109,112,108,101,114,0,0, +1,0,0,12,99,111,111,114,100,0,0,0,1,8,58,116,101,120,116,117,114,101,51,68, +0,18,115,97,109,112,108,101,114,0,0,58,118,101,99,51,0,18,99,111,111,114,100,0, +59,115,0,18,99,111,111,114,100,0,59,113,0,49,0,18,99,111,111,114,100,0,59,116, +0,18,99,111,111,114,100,0,59,113,0,49,0,18,99,111,111,114,100,0,59,112,0,18, +99,111,111,114,100,0,59,113,0,49,0,0,0,0,0,0,1,0,12,0,116,101,120,116, +117,114,101,67,117,98,101,0,1,0,0,19,115,97,109,112,108,101,114,0,0,1,0,0, +11,99,111,111,114,100,0,0,0,1,8,58,118,101,99,52,0,17,48,0,48,0,0,0, +0,0,0,1,0,12,0,115,104,97,100,111,119,49,68,0,1,0,0,20,115,97,109,112, +108,101,114,0,0,1,0,0,11,99,111,111,114,100,0,0,0,1,8,58,118,101,99,52, +0,17,48,0,48,0,0,0,0,0,0,1,0,12,0,115,104,97,100,111,119,50,68,0, +1,0,0,21,115,97,109,112,108,101,114,0,0,1,0,0,11,99,111,111,114,100,0,0, +0,1,8,58,118,101,99,52,0,17,48,0,48,0,0,0,0,0,0,1,0,12,0,115, +104,97,100,111,119,49,68,80,114,111,106,0,1,0,0,20,115,97,109,112,108,101,114,0, +0,1,0,0,12,99,111,111,114,100,0,0,0,1,8,58,115,104,97,100,111,119,49,68, +0,18,115,97,109,112,108,101,114,0,0,58,118,101,99,51,0,18,99,111,111,114,100,0, +59,115,0,18,99,111,111,114,100,0,59,113,0,49,0,17,48,0,48,0,0,0,18,99, +111,111,114,100,0,59,112,0,18,99,111,111,114,100,0,59,113,0,49,0,0,0,0,0, +0,1,0,12,0,115,104,97,100,111,119,50,68,80,114,111,106,0,1,0,0,21,115,97, +109,112,108,101,114,0,0,1,0,0,12,99,111,111,114,100,0,0,0,1,8,58,115,104, +97,100,111,119,50,68,0,18,115,97,109,112,108,101,114,0,0,58,118,101,99,51,0,18, +99,111,111,114,100,0,59,115,0,18,99,111,111,114,100,0,59,113,0,49,0,18,99,111, +111,114,100,0,59,116,0,18,99,111,111,114,100,0,59,113,0,49,0,18,99,111,111,114, +100,0,59,112,0,18,99,111,111,114,100,0,59,113,0,49,0,0,0,0,0,0,1,0, +9,0,110,111,105,115,101,49,0,1,0,0,9,120,0,0,0,1,8,17,48,0,48,0, +0,0,0,1,0,9,0,110,111,105,115,101,49,0,1,0,0,10,120,0,0,0,1,8, +17,48,0,48,0,0,0,0,1,0,9,0,110,111,105,115,101,49,0,1,0,0,11,120, +0,0,0,1,8,17,48,0,48,0,0,0,0,1,0,9,0,110,111,105,115,101,49,0, +1,0,0,12,120,0,0,0,1,8,17,48,0,48,0,0,0,0,1,0,10,0,110,111, +105,115,101,50,0,1,0,0,9,120,0,0,0,1,8,58,118,101,99,50,0,17,48,0, +48,0,0,0,0,0,0,1,0,10,0,110,111,105,115,101,50,0,1,0,0,10,120,0, +0,0,1,8,58,118,101,99,50,0,17,48,0,48,0,0,0,0,0,0,1,0,10,0, +110,111,105,115,101,50,0,1,0,0,11,120,0,0,0,1,8,58,118,101,99,50,0,17, +48,0,48,0,0,0,0,0,0,1,0,10,0,110,111,105,115,101,50,0,1,0,0,12, +120,0,0,0,1,8,58,118,101,99,50,0,17,48,0,48,0,0,0,0,0,0,1,0, +11,0,110,111,105,115,101,51,0,1,0,0,9,120,0,0,0,1,8,58,118,101,99,51, +0,17,48,0,48,0,0,0,0,0,0,1,0,11,0,110,111,105,115,101,51,0,1,0, +0,10,120,0,0,0,1,8,58,118,101,99,51,0,17,48,0,48,0,0,0,0,0,0, +1,0,11,0,110,111,105,115,101,51,0,1,0,0,11,120,0,0,0,1,8,58,118,101, +99,51,0,17,48,0,48,0,0,0,0,0,0,1,0,11,0,110,111,105,115,101,51,0, +1,0,0,12,120,0,0,0,1,8,58,118,101,99,51,0,17,48,0,48,0,0,0,0, +0,0,1,0,12,0,110,111,105,115,101,52,0,1,0,0,9,120,0,0,0,1,8,58, +118,101,99,52,0,17,48,0,48,0,0,0,0,0,0,1,0,12,0,110,111,105,115,101, +52,0,1,0,0,10,120,0,0,0,1,8,58,118,101,99,52,0,17,48,0,48,0,0, +0,0,0,0,1,0,12,0,110,111,105,115,101,52,0,1,0,0,11,120,0,0,0,1, +8,58,118,101,99,52,0,17,48,0,48,0,0,0,0,0,0,1,0,12,0,110,111,105, +115,101,52,0,1,0,0,12,120,0,0,0,1,8,58,118,101,99,52,0,17,48,0,48, +0,0,0,0,0,0,0
\ No newline at end of file diff --git a/nx-X11/extras/Mesa/src/mesa/shader/slang/library/slang_core_gc.h b/nx-X11/extras/Mesa/src/mesa/shader/slang/library/slang_core_gc.h new file mode 100644 index 000000000..f838859bb --- /dev/null +++ b/nx-X11/extras/Mesa/src/mesa/shader/slang/library/slang_core_gc.h @@ -0,0 +1,1565 @@ +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"int __constructor (const float _f) {\n" +" int _i;\n" +" __asm float_to_int _i, _f;\n" +" return _i;\n" +"}\n" +"\n" +"bool __constructor (const int _i) {\n" +" return _i != 0;\n" +"}\n" +"\n" +"bool __constructor (const float _f) {\n" +" return _f != 0.0;\n" +"}\n" +"\n" +"int __constructor (const bool _b) {\n" +" return _b ? 1 : 0;\n" +"}\n" +"\n" +"float __constructor (const bool _b) {\n" +" return _b ? 1.0 : 0.0;\n" +"}\n" +"\n" +"float __constructor (const int _i) {\n" +" float _f;\n" +" __asm int_to_float _f, _i;\n" +" return _f;\n" +"}\n" +"\n" +"bool __constructor (const bool _b) {\n" +" return _b;\n" +"}\n" +"\n" +"int __constructor (const int _i) {\n" +" return _i;\n" +"}\n" +"\n" +"float __constructor (const float _f) {\n" +" return _f;\n" +"}\n" +"\n" +"vec2 __constructor (const float _f) {\n" +" return vec2 (_f, _f);\n" +"}\n" +"\n" +"vec2 __constructor (const int _i) {\n" +" return vec2 (_i, _i);\n" +"}\n" +"\n" +"vec2 __constructor (const bool _b) {\n" +" return vec2 (_b, _b);\n" +"}\n" +"\n" +"vec3 __constructor (const float _f) {\n" +" return vec3 (_f, _f, _f);\n" +"}\n" +"\n" +"vec3 __constructor (const int _i) {\n" +" return vec3 (_i, _i, _i);\n" +"}\n" +"\n" +"vec3 __constructor (const bool _b) {\n" +" return vec3 (_b, _b, _b);\n" +"}\n" +"\n" +"vec4 __constructor (const float _f) {\n" +" return vec4 (_f, _f, _f, _f);\n" +"}\n" +"\n" +"vec4 __constructor (const int _i) {\n" +" return vec4 (_i, _i, _i, _i);\n" +"}\n" +"\n" +"vec4 __constructor (const bool _b) {\n" +" return vec4 (_b, _b, _b, _b);\n" +"}\n" +"\n" +"ivec2 __constructor (const int _i) {\n" +" return ivec2 (_i, _i);\n" +"}\n" +"\n" +"ivec2 __constructor (const float _f) {\n" +" return ivec2 (_f, _f);\n" +"}\n" +"\n" +"ivec2 __constructor (const bool _b) {\n" +" return ivec2 (_b, _b);\n" +"}\n" +"\n" +"ivec3 __constructor (const int _i) {\n" +" return ivec3 (_i, _i, _i);\n" +"}\n" +"\n" +"ivec3 __constructor (const float _f) {\n" +" return ivec3 (_f, _f, _f);\n" +"}\n" +"\n" +"ivec3 __constructor (const bool _b) {\n" +" return ivec3 (_b, _b, _b);\n" +"}\n" +"\n" +"ivec4 __constructor (const int _i) {\n" +" return ivec4 (_i, _i, _i, _i);\n" +"}\n" +"\n" +"ivec4 __constructor (const float _f) {\n" +" return ivec4 (_f, _f, _f, _f);\n" +"}\n" +"\n" +"ivec4 __constructor (const bool _b) {\n" +" return ivec4 (_b, _b, _b, _b);\n" +"}\n" +"\n" +"bvec2 __constructor (const bool _b) {\n" +" return bvec2 (_b, _b);\n" +"}\n" +"\n" +"bvec2 __constructor (const float _f) {\n" +" return bvec2 (_f, _f);\n" +"}\n" +"\n" +"bvec2 __constructor (const int _i) {\n" +" return bvec2 (_i, _i);\n" +"}\n" +"\n" +"bvec3 __constructor (const bool _b) {\n" +" return bvec3 (_b, _b, _b);\n" +"}\n" +"\n" +"bvec3 __constructor (const float _f) {\n" +" return bvec3 (_f, _f, _f);\n" +"}\n" +"\n" +"bvec3 __constructor (const int _i) {\n" +" return bvec3 (_i, _i, _i);\n" +"}\n" +"\n" +"bvec4 __constructor (const bool _b) {\n" +" return bvec4 (_b, _b, _b, _b);\n" +"}\n" +"\n" +"bvec4 __constructor (const float _f) {\n" +" return bvec4 (_f, _f, _f, _f);\n" +"}\n" +"\n" +"bvec4 __constructor (const int _i) {\n" +" return bvec4 (_i, _i, _i, _i);\n" +"}\n" +"\n" +"mat2 __constructor (const float _f) {\n" +" return mat2 (\n" +" _f, .0,\n" +" .0, _f\n" +" );\n" +"}\n" +"\n" +"mat2 __constructor (const int _i) {\n" +" return mat2 (\n" +" _i, .0,\n" +" .0, _i\n" +" );\n" +"}\n" +"\n" +"mat2 __constructor (const bool _b) {\n" +" return mat2 (\n" +" _b, .0,\n" +" .0, _b\n" +" );\n" +"}\n" +"\n" +"mat3 __constructor (const float _f) {\n" +" return mat3 (\n" +" _f, .0, .0,\n" +" .0, _f, .0,\n" +" .0, .0, _f\n" +" );\n" +"}\n" +"\n" +"mat3 __constructor (const int _i) {\n" +" return mat3 (\n" +" _i, .0, .0,\n" +" .0, _i, .0,\n" +" .0, .0, _i\n" +" );\n" +"}\n" +"\n" +"mat3 __constructor (const bool _b) {\n" +" return mat3 (\n" +" _b, .0, .0,\n" +" .0, _b, .0,\n" +" .0, .0, _b\n" +" );\n" +"}\n" +"\n" +"mat4 __constructor (const float _f) {\n" +" return mat4 (\n" +" _f, .0, .0, .0,\n" +" .0, _f, .0, .0,\n" +" .0, .0, _f, .0,\n" +" .0, .0, .0, _f\n" +" );\n" +"}\n" +"\n" +"mat4 __constructor (const int _i) {\n" +" return mat4 (\n" +" _i, .0, .0, .0,\n" +" .0, _i, .0, .0,\n" +" .0, .0, _i, .0,\n" +" .0, .0, .0, _i\n" +" );\n" +"}\n" +"\n" +"mat4 __constructor (const bool _b) {\n" +" return mat4 (\n" +" _b, .0, .0, .0,\n" +" .0, _b, .0, .0,\n" +" .0, .0, _b, .0,\n" +" .0, .0, .0, _b\n" +" );\n" +"}\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"void __operator += (inout float a, const float b) {\n" +" __asm float_add a, a, b;\n" +"}\n" +"\n" +"float __operator - (const float a) {\n" +" float c;\n" +" __asm float_negate c, a;\n" +" return c;\n" +"}\n" +"\n" +"void __operator -= (inout float a, const float b) {\n" +" a += -b;\n" +"}\n" +"\n" +"void __operator *= (inout float a, const float b) {\n" +" __asm float_multiply a, a, b;\n" +"}\n" +"\n" +"void __operator /= (inout float a, const float b) {\n" +" __asm float_divide a, a, b;\n" +"}\n" +"\n" +"float __operator + (const float a, const float b) {\n" +" float c;\n" +" c = a;\n" +" return c += b;\n" +"}\n" +"\n" +"void __operator += (inout int a, const int b) {\n" +" a = int (float (a) + float (b));\n" +"}\n" +"\n" +"int __operator - (const int a) {\n" +" return int (-float (a));\n" +"}\n" +"\n" +"void __operator -= (inout int a, const int b) {\n" +" a += -b;\n" +"}\n" +"\n" +"float __operator * (const float a, const float b) {\n" +" float c;\n" +" c = a;\n" +" return c *= b;\n" +"}\n" +"\n" +"void __operator *= (inout int a, const int b) {\n" +" a = int (float (a) * float (b));\n" +"}\n" +"\n" +"float __operator / (const float a, const float b) {\n" +" float c;\n" +" c = a;\n" +" return c /= b;\n" +"}\n" +"\n" +"void __operator /= (inout int a, const int b) {\n" +" a = int (float (a) / float (b));\n" +"}\n" +"\n" +"void __operator += (inout vec2 v, const vec2 u) {\n" +" v.x += u.x, v.y += u.y;\n" +"}\n" +"\n" +"void __operator -= (inout vec2 v, const vec2 u) {\n" +" v.x -= u.x, v.y -= u.y;\n" +"}\n" +"\n" +"void __operator *= (inout vec2 v, const vec2 u) {\n" +" v.x *= u.x, v.y *= u.y;\n" +"}\n" +"\n" +"void __operator /= (inout vec2 v, const vec2 u) {\n" +" v.x /= u.x, v.y /= u.y;\n" +"}\n" +"\n" +"void __operator += (inout vec3 v, const vec3 u) {\n" +" v.x += u.x, v.y += u.y, v.z += u.z;\n" +"}\n" +"\n" +"void __operator -= (inout vec3 v, const vec3 u) {\n" +" v.x -= u.x, v.y -= u.y, v.z -= u.z;\n" +"}\n" +"\n" +"void __operator *= (inout vec3 v, const vec3 u) {\n" +" v.x *= u.x, v.y *= u.y, v.z *= u.z;\n" +"}\n" +"\n" +"void __operator /= (inout vec3 v, const vec3 u) {\n" +" v.x /= u.x, v.y /= u.y, v.z /= u.z;\n" +"}\n" +"\n" +"void __operator += (inout vec4 v, const vec4 u) {\n" +" v.x += u.x, v.y += u.y, v.z += u.z, v.w += u.w;\n" +"}\n" +"\n" +"void __operator -= (inout vec4 v, const vec4 u) {\n" +" v.x -= u.x, v.y -= u.y, v.z -= u.z, v.w -= u.w;\n" +"}\n" +"\n" +"void __operator *= (inout vec4 v, const vec4 u) {\n" +" v.x *= u.x, v.y *= u.y, v.z *= u.z, v.w *= u.w;\n" +"}\n" +"\n" +"void __operator /= (inout vec4 v, const vec4 u) {\n" +" v.x /= u.x, v.y /= u.y, v.z /= u.z, v.w /= u.w;\n" +"}\n" +"\n" +"void __operator += (inout ivec2 v, const ivec2 u) {\n" +" v.x += u.x, v.y += u.y;\n" +"}\n" +"\n" +"void __operator -= (inout ivec2 v, const ivec2 u) {\n" +" v.x -= u.x, v.y -= u.y;\n" +"}\n" +"\n" +"void __operator *= (inout ivec2 v, const ivec2 u) {\n" +" v.x *= u.x, v.y *= u.y;\n" +"}\n" +"\n" +"void __operator /= (inout ivec2 v, const ivec2 u) {\n" +" v.x /= u.x, v.y /= u.y;\n" +"}\n" +"\n" +"void __operator += (inout ivec3 v, const ivec3 u) {\n" +" v.x += u.x, v.y += u.y, v.z += u.z;\n" +"}\n" +"\n" +"void __operator -= (inout ivec3 v, const ivec3 u) {\n" +" v.x -= u.x, v.y -= u.y, v.z -= u.z;\n" +"}\n" +"\n" +"void __operator *= (inout ivec3 v, const ivec3 u) {\n" +" v.x *= u.x, v.y *= u.y, v.z *= u.z;\n" +"}\n" +"\n" +"void __operator /= (inout ivec3 v, const ivec3 u) {\n" +" v.x /= u.x, v.y /= u.y, v.z /= u.z;\n" +"}\n" +"\n" +"void __operator += (inout ivec4 v, const ivec4 u) {\n" +" v.x += u.x, v.y += u.y, v.z += u.z, v.w += u.w;\n" +"}\n" +"\n" +"void __operator -= (inout ivec4 v, const ivec4 u) {\n" +" v.x -= u.x, v.y -= u.y, v.z -= u.z, v.w -= u.w;\n" +"}\n" +"\n" +"void __operator *= (inout ivec4 v, const ivec4 u) {\n" +" v.x *= u.x, v.y *= u.y, v.z *= u.z, v.w *= u.w;\n" +"}\n" +"\n" +"void __operator /= (inout ivec4 v, const ivec4 u) {\n" +" v.x /= u.x, v.y /= u.y, v.z /= u.z, v.w /= u.w;\n" +"}\n" +"\n" +"void __operator += (inout mat2 m, const mat2 n) {\n" +" m[0] += n[0], m[1] += n[1];\n" +"}\n" +"\n" +"void __operator -= (inout mat2 m, const mat2 n) {\n" +" m[0] -= n[0], m[1] -= n[1];\n" +"}\n" +"\n" +"vec2 __operator * (const mat2 m, const vec2 v) {\n" +" return vec2 (\n" +" v.x * m[0].x + v.y * m[1].x,\n" +" v.x * m[0].y + v.y * m[1].y\n" +" );\n" +"}\n" +"\n" +"mat2 __operator * (const mat2 m, const mat2 n) {\n" +" return mat2 (m * n[0], m * n[1]);\n" +"}\n" +"\n" +"void __operator *= (inout mat2 m, const mat2 n) {\n" +" m = m * n;\n" +"}\n" +"\n" +"void __operator /= (inout mat2 m, const mat2 n) {\n" +" m[0] /= n[0], m[1] /= n[1];\n" +"}\n" +"\n" +"void __operator += (inout mat3 m, const mat3 n) {\n" +" m[0] += n[0], m[1] += n[1], m[2] += n[2];\n" +"}\n" +"\n" +"void __operator -= (inout mat3 m, const mat3 n) {\n" +" m[0] -= n[0], m[1] -= n[1], m[2] -= n[2];\n" +"}\n" +"\n" +"vec3 __operator * (const mat3 m, const vec3 v) {\n" +" return vec3 (\n" +" v.x * m[0].x + v.y * m[1].x + v.z * m[2].x,\n" +" v.x * m[0].y + v.y * m[1].y + v.z * m[2].y,\n" +" v.x * m[0].z + v.y * m[1].z + v.z * m[2].z\n" +" );\n" +"}\n" +"\n" +"mat3 __operator * (const mat3 m, const mat3 n) {\n" +" return mat3 (m * n[0], m * n[1], m * n[2]);\n" +"}\n" +"\n" +"void __operator *= (inout mat3 m, const mat3 n) {\n" +" m = m * n;\n" +"}\n" +"\n" +"void __operator /= (inout mat3 m, const mat3 n) {\n" +" m[0] /= n[0], m[1] /= n[1], m[2] /= n[2];\n" +"}\n" +"\n" +"void __operator += (inout mat4 m, const mat4 n) {\n" +" m[0] += n[0], m[1] += n[1], m[2] += n[2], m[3] += n[3];\n" +"}\n" +"\n" +"void __operator -= (inout mat4 m, const mat4 n) {\n" +" m[0] -= n[0], m[1] -= n[1], m[2] -= n[2], m[3] -= n[3];\n" +"}\n" +"\n" +"vec4 __operator * (const mat4 m, const vec4 v) {\n" +" return vec4 (\n" +" v.x * m[0].x + v.y * m[1].x + v.z * m[2].x + v.w * m[3].x,\n" +" v.x * m[0].y + v.y * m[1].y + v.z * m[2].y + v.w * m[3].y,\n" +" v.x * m[0].z + v.y * m[1].z + v.z * m[2].z + v.w * m[3].z,\n" +" v.x * m[0].w + v.y * m[1].w + v.z * m[2].w + v.w * m[3].w\n" +" );\n" +"}\n" +"\n" +"mat4 __operator * (const mat4 m, const mat4 n) {\n" +" return mat4 (m * n[0], m * n[1], m * n[2], m * n[3]);\n" +"}\n" +"\n" +"void __operator *= (inout mat4 m, const mat4 n) {\n" +" m = m * n;\n" +"}\n" +"\n" +"void __operator /= (inout mat4 m, const mat4 n) {\n" +" m[0] /= n[0], m[1] /= n[1], m[2] /= n[2], m[3] /= n[3];\n" +"}\n" +"\n" +"void __operator += (inout vec2 v, const float a) {\n" +" v.x += a, v.y += a;\n" +"}\n" +"\n" +"void __operator -= (inout vec2 v, const float a) {\n" +" v.x -= a, v.y -= a;\n" +"}\n" +"\n" +"void __operator *= (inout vec2 v, const float a) {\n" +" v.x *= a, v.y *= a;\n" +"}\n" +"\n" +"void __operator /= (inout vec2 v, const float a) {\n" +" v.x /= a, v.y /= a;\n" +"}\n" +"\n" +"void __operator += (inout vec3 v, const float a) {\n" +" v.x += a, v.y += a, v.z += a;\n" +"}\n" +"\n" +"void __operator -= (inout vec3 v, const float a) {\n" +" v.x -= a, v.y -= a, v.z -= a;\n" +"}\n" +"\n" +"void __operator *= (inout vec3 v, const float a) {\n" +" v.x *= a, v.y *= a, v.z *= a;\n" +"}\n" +"\n" +"void __operator /= (inout vec3 v, const float a) {\n" +" v.x /= a, v.y /= a, v.z /= a;\n" +"}\n" +"\n" +"void __operator += (inout vec4 v, const float a) {\n" +" v.x += a, v.y += a, v.z += a, v.w += a;\n" +"}\n" +"\n" +"void __operator -= (inout vec4 v, const float a) {\n" +" v.x -= a, v.y -= a, v.z -= a, v.w -= a;\n" +"}\n" +"\n" +"void __operator *= (inout vec4 v, const float a) {\n" +" v.x *= a, v.y *= a, v.z *= a, v.w *= a;\n" +"}\n" +"\n" +"void __operator /= (inout vec4 v, const float a) {\n" +" v.x /= a, v.y /= a, v.z /= a, v.w /= a;\n" +"}\n" +"\n" +"void __operator += (inout mat2 m, const float a) {\n" +" m[0] += a, m[1] += a;\n" +"}\n" +"\n" +"void __operator -= (inout mat2 m, const float a) {\n" +" m[0] -= a, m[1] -= a;\n" +"}\n" +"\n" +"void __operator *= (inout mat2 m, const float a) {\n" +" m[0] *= a, m[1] *= a;\n" +"}\n" +"\n" +"void __operator /= (inout mat2 m, const float a) {\n" +" m[0] /= a, m[1] /= a;\n" +"}\n" +"\n" +"void __operator += (inout mat3 m, const float a) {\n" +" m[0] += a, m[1] += a, m[2] += a;\n" +"}\n" +"\n" +"void __operator -= (inout mat3 m, const float a) {\n" +" m[0] -= a, m[1] -= a, m[2] -= a;\n" +"}\n" +"\n" +"void __operator *= (inout mat3 m, const float a) {\n" +" m[0] *= a, m[1] *= a, m[2] *= a;\n" +"}\n" +"\n" +"void __operator /= (inout mat3 m, const float a) {\n" +" m[0] /= a, m[1] /= a, m[2] /= a;\n" +"}\n" +"\n" +"void __operator += (inout mat4 m, const float a) {\n" +" m[0] += a, m[1] += a, m[2] += a, m[3] += a;\n" +"}\n" +"\n" +"void __operator -= (inout mat4 m, const float a) {\n" +" m[0] -= a, m[1] -= a, m[2] -= a, m[3] -= a;\n" +"}\n" +"\n" +"void __operator *= (inout mat4 m, const float a) {\n" +" m[0] *= a, m[1] *= a, m[2] *= a, m[3] *= a;\n" +"}\n" +"\n" +"void __operator /= (inout mat4 m, const float a) {\n" +" m[0] /= a, m[1] /= a, m[2] /= a, m[3] /= a;\n" +"}\n" +"\n" +"vec2 __operator * (const vec2 v, const mat2 m) {\n" +" return vec2 (\n" +" v.x * m[0].x + v.y * m[0].y,\n" +" v.x * m[1].x + v.y * m[1].y\n" +" );\n" +"}\n" +"\n" +"void __operator *= (inout vec2 v, const mat2 m) {\n" +" v = v * m;\n" +"}\n" +"\n" +"vec3 __operator * (const vec3 v, const mat3 m) {\n" +" return vec3 (\n" +" v.x * m[0].x + v.y * m[0].y + v.z * m[0].z,\n" +" v.x * m[1].x + v.y * m[1].y + v.z * m[1].z,\n" +" v.x * m[2].x + v.y * m[2].y + v.z * m[2].z\n" +" );\n" +"}\n" +"\n" +"void __operator *= (inout vec3 v, const mat3 m) {\n" +" v = v * m;\n" +"}\n" +"\n" +"vec4 __operator * (const vec4 v, const mat4 m) {\n" +" return vec4 (\n" +" v.x * m[0].x + v.y * m[0].y + v.z * m[0].z + v.w * m[0].w,\n" +" v.x * m[1].x + v.y * m[1].y + v.z * m[1].z + v.w * m[1].w,\n" +" v.x * m[2].x + v.y * m[2].y + v.z * m[2].z + v.w * m[2].w,\n" +" v.x * m[3].x + v.y * m[3].y + v.z * m[3].z + v.w * m[3].w\n" +" );\n" +"}\n" +"\n" +"void __operator *= (inout vec4 v, const mat4 m) {\n" +" v = v * m;\n" +"}\n" +"\n" +"float __operator - (const float a, const float b) {\n" +" return a + -b;\n" +"}\n" +"\n" +"int __operator + (const int a, const int b) {\n" +" int c;\n" +" c = a;\n" +" return c += b;\n" +"}\n" +"\n" +"int __operator - (const int a, const int b) {\n" +" return a + -b;\n" +"}\n" +"\n" +"int __operator * (const int a, const int b) {\n" +" int c;\n" +" return (c = a) *= b;\n" +"}\n" +"\n" +"int __operator / (const int a, const int b) {\n" +" int c;\n" +" return (c = a) /= b;\n" +"}\n" +"\n" +"vec2 __operator + (const vec2 v, const vec2 u) {\n" +" return vec2 (v.x + u.x, v.y + u.y);\n" +"}\n" +"\n" +"vec2 __operator - (const vec2 v, const vec2 u) {\n" +" return vec2 (v.x - u.x, v.y - u.y);\n" +"}\n" +"\n" +"vec3 __operator + (const vec3 v, const vec3 u) {\n" +" return vec3 (v.x + u.x, v.y + u.y, v.z + u.z);\n" +"}\n" +"\n" +"vec3 __operator - (const vec3 v, const vec3 u) {\n" +" return vec3 (v.x - u.x, v.y - u.y, v.z - u.z);\n" +"}\n" +"\n" +"vec4 __operator + (const vec4 v, const vec4 u) {\n" +" return vec4 (v.x + u.x, v.y + u.y, v.z + u.z, v.w + u.w);\n" +"}\n" +"\n" +"vec4 __operator - (const vec4 v, const vec4 u) {\n" +" return vec4 (v.x - u.x, v.y - u.y, v.z - u.z, v.w - u.w);\n" +"}\n" +"\n" +"ivec2 __operator + (const ivec2 v, const ivec2 u) {\n" +" return ivec2 (v.x + u.x, v.y + u.y);\n" +"}\n" +"\n" +"ivec2 __operator - (const ivec2 v, const ivec2 u) {\n" +" return ivec2 (v.x - u.x, v.y - u.y);\n" +"}\n" +"\n" +"ivec3 __operator + (const ivec3 v, const ivec3 u) {\n" +" return ivec3 (v.x + u.x, v.y + u.y, v.z + u.z);\n" +"}\n" +"\n" +"ivec3 __operator - (const ivec3 v, const ivec3 u) {\n" +" return ivec3 (v.x - u.x, v.y - u.y, v.z - u.z);\n" +"}\n" +"\n" +"ivec4 __operator + (const ivec4 v, const ivec4 u) {\n" +" return ivec4 (v.x + u.x, v.y + u.y, v.z + u.z, v.w + u.w);\n" +"}\n" +"\n" +"ivec4 __operator - (const ivec4 v, const ivec4 u) {\n" +" return ivec4 (v.x - u.x, v.y - u.y, v.z - u.z, v.w - u.w);\n" +"}\n" +"\n" +"mat2 __operator + (const mat2 m, const mat2 n) {\n" +" return mat2 (m[0] + n[0], m[1] + n[1]);\n" +"}\n" +"\n" +"mat2 __operator - (const mat2 m, const mat2 n) {\n" +" return mat2 (m[0] - n[0], m[1] - n[1]);\n" +"}\n" +"\n" +"mat3 __operator + (const mat3 m, const mat3 n) {\n" +" return mat3 (m[0] + n[0], m[1] + n[1], m[2] + n[2]);\n" +"}\n" +"\n" +"mat3 __operator - (const mat3 m, const mat3 n) {\n" +" return mat3 (m[0] - n[0], m[1] - n[1], m[2] - n[2]);\n" +"}\n" +"\n" +"mat4 __operator + (const mat4 m, const mat4 n) {\n" +" return mat4 (m[0] + n[0], m[1] + n[1], m[2] + n[2], m[3] + n[3]);\n" +"}\n" +"\n" +"mat4 __operator - (const mat4 m, const mat4 n) {\n" +" return mat4 (m[0] - n[0], m[1] - n[1], m[2] - n[2], m[3] - n[3]);\n" +"}\n" +"\n" +"vec2 __operator + (const float a, const vec2 u) {\n" +" return vec2 (a + u.x, a + u.y);\n" +"}\n" +"\n" +"vec2 __operator + (const vec2 v, const float b) {\n" +" return vec2 (v.x + b, v.y + b);\n" +"}\n" +"\n" +"vec2 __operator - (const float a, const vec2 u) {\n" +" return vec2 (a - u.x, a - u.y);\n" +"}\n" +"\n" +"vec2 __operator - (const vec2 v, const float b) {\n" +" return vec2 (v.x - b, v.y - b);\n" +"}\n" +"\n" +"vec2 __operator * (const float a, const vec2 u) {\n" +" return vec2 (a * u.x, a * u.y);\n" +"}\n" +"\n" +"vec2 __operator * (const vec2 v, const float b) {\n" +" return vec2 (v.x * b, v.y * b);\n" +"}\n" +"\n" +"vec2 __operator / (const float a, const vec2 u) {\n" +" return vec2 (a / u.x, a / u.y);\n" +"}\n" +"\n" +"vec2 __operator / (const vec2 v, const float b) {\n" +" return vec2 (v.x / b, v.y / b);\n" +"}\n" +"\n" +"vec3 __operator + (const float a, const vec3 u) {\n" +" return vec3 (a + u.x, a + u.y, a + u.z);\n" +"}\n" +"\n" +"vec3 __operator + (const vec3 v, const float b) {\n" +" return vec3 (v.x + b, v.y + b, v.z + b);\n" +"}\n" +"\n" +"vec3 __operator - (const float a, const vec3 u) {\n" +" return vec3 (a - u.x, a - u.y, a - u.z);\n" +"}\n" +"\n" +"vec3 __operator - (const vec3 v, const float b) {\n" +" return vec3 (v.x - b, v.y - b, v.z - b);\n" +"}\n" +"\n" +"vec3 __operator * (const float a, const vec3 u) {\n" +" return vec3 (a * u.x, a * u.y, a * u.z);\n" +"}\n" +"\n" +"vec3 __operator * (const vec3 v, const float b) {\n" +" return vec3 (v.x * b, v.y * b, v.z * b);\n" +"}\n" +"\n" +"vec3 __operator / (const float a, const vec3 u) {\n" +" return vec3 (a / u.x, a / u.y, a / u.z);\n" +"}\n" +"\n" +"vec3 __operator / (const vec3 v, const float b) {\n" +" return vec3 (v.x / b, v.y / b, v.z / b);\n" +"}\n" +"\n" +"vec4 __operator + (const float a, const vec4 u) {\n" +" return vec4 (a + u.x, a + u.y, a + u.z, a + u.w);\n" +"}\n" +"\n" +"vec4 __operator + (const vec4 v, const float b) {\n" +" return vec4 (v.x + b, v.y + b, v.z + b, v.w + b);\n" +"}\n" +"\n" +"vec4 __operator - (const float a, const vec4 u) {\n" +" return vec4 (a - u.x, a - u.y, a - u.z, a - u.w);\n" +"}\n" +"\n" +"vec4 __operator - (const vec4 v, const float b) {\n" +" return vec4 (v.x - b, v.y - b, v.z - b, v.w - b);\n" +"}\n" +"\n" +"vec4 __operator * (const float a, const vec4 u) {\n" +" return vec4 (a * u.x, a * u.y, a * u.z, a * u.w);\n" +"}\n" +"\n" +"vec4 __operator * (const vec4 v, const float b) {\n" +" return vec4 (v.x * b, v.y * b, v.z * b, v.w * b);\n" +"}\n" +"\n" +"vec4 __operator / (const float a, const vec4 u) {\n" +" return vec4 (a / u.x, a / u.y, a / u.z, a / u.w);\n" +"}\n" +"\n" +"vec4 __operator / (const vec4 v, const float b) {\n" +" return vec4 (v.x / b, v.y / b, v.z / b, v.w / b);\n" +"}\n" +"\n" +"mat2 __operator + (const float a, const mat2 n) {\n" +" return mat2 (a + n[0], a + n[1]);\n" +"}\n" +"\n" +"mat2 __operator + (const mat2 m, const float b) {\n" +" return mat2 (m[0] + b, m[1] + b);\n" +"}\n" +"\n" +"mat2 __operator - (const float a, const mat2 n) {\n" +" return mat2 (a - n[0], a - n[1]);\n" +"}\n" +"\n" +"mat2 __operator - (const mat2 m, const float b) {\n" +" return mat2 (m[0] - b, m[1] - b);\n" +"}\n" +"\n" +"mat2 __operator * (const float a, const mat2 n) {\n" +" return mat2 (a * n[0], a * n[1]);\n" +"}\n" +"\n" +"mat2 __operator * (const mat2 m, const float b) {\n" +" return mat2 (m[0] * b, m[1] * b);\n" +"}\n" +"\n" +"mat2 __operator / (const float a, const mat2 n) {\n" +" return mat2 (a / n[0], a / n[1]);\n" +"}\n" +"\n" +"mat2 __operator / (const mat2 m, const float b) {\n" +" return mat2 (m[0] / b, m[1] / b);\n" +"}\n" +"\n" +"mat3 __operator + (const float a, const mat3 n) {\n" +" return mat3 (a + n[0], a + n[1], a + n[2]);\n" +"}\n" +"\n" +"mat3 __operator + (const mat3 m, const float b) {\n" +" return mat3 (m[0] + b, m[1] + b, m[2] + b);\n" +"}\n" +"\n" +"mat3 __operator - (const float a, const mat3 n) {\n" +" return mat3 (a - n[0], a - n[1], a - n[2]);\n" +"}\n" +"\n" +"mat3 __operator - (const mat3 m, const float b) {\n" +" return mat3 (m[0] - b, m[1] - b, m[2] - b);\n" +"}\n" +"\n" +"mat3 __operator * (const float a, const mat3 n) {\n" +" return mat3 (a * n[0], a * n[1], a * n[2]);\n" +"}\n" +"\n" +"mat3 __operator * (const mat3 m, const float b) {\n" +" return mat3 (m[0] * b, m[1] * b, m[2] * b);\n" +"}\n" +"\n" +"mat3 __operator / (const float a, const mat3 n) {\n" +" return mat3 (a / n[0], a / n[1], a / n[2]);\n" +"}\n" +"\n" +"mat3 __operator / (const mat3 m, const float b) {\n" +" return mat3 (m[0] / b, m[1] / b, m[2] / b);\n" +"}\n" +"\n" +"mat4 __operator + (const float a, const mat4 n) {\n" +" return mat4 (a + n[0], a + n[1], a + n[2], a + n[3]);\n" +"}\n" +"\n" +"mat4 __operator + (const mat4 m, const float b) {\n" +" return mat4 (m[0] + b, m[1] + b, m[2] + b, m[3] + b);\n" +"}\n" +"\n" +"mat4 __operator - (const float a, const mat4 n) {\n" +" return mat4 (a - n[0], a - n[1], a - n[2], a - n[3]);\n" +"}\n" +"\n" +"mat4 __operator - (const mat4 m, const float b) {\n" +" return mat4 (m[0] - b, m[1] - b, m[2] - b, m[3] - b);\n" +"}\n" +"\n" +"mat4 __operator * (const float a, const mat4 n) {\n" +" return mat4 (a * n[0], a * n[1], a * n[2], a * n[3]);\n" +"}\n" +"\n" +"mat4 __operator * (const mat4 m, const float b) {\n" +" return mat4 (m[0] * b, m[1] * b, m[2] * b, m[3] * b);\n" +"}\n" +"\n" +"mat4 __operator / (const float a, const mat4 n) {\n" +" return mat4 (a / n[0], a / n[1], a / n[2], a / n[3]);\n" +"}\n" +"\n" +"mat4 __operator / (const mat4 m, const float b) {\n" +" return mat4 (m[0] / b, m[1] / b, m[2] / b, m[3] / b);\n" +"}\n" +"\n" +"ivec2 __operator + (const int a, const ivec2 u) {\n" +" return ivec2 (a + u.x, a + u.y);\n" +"}\n" +"\n" +"ivec2 __operator + (const ivec2 v, const int b) {\n" +" return ivec2 (v.x + b, v.y + b);\n" +"}\n" +"\n" +"ivec2 __operator - (const int a, const ivec2 u) {\n" +" return ivec2 (a - u.x, a - u.y);\n" +"}\n" +"\n" +"ivec2 __operator - (const ivec2 v, const int b) {\n" +" return ivec2 (v.x - b, v.y - b);\n" +"}\n" +"\n" +"ivec2 __operator * (const int a, const ivec2 u) {\n" +" return ivec2 (a * u.x, a * u.y);\n" +"}\n" +"\n" +"ivec2 __operator * (const ivec2 v, const int b) {\n" +" return ivec2 (v.x * b, v.y * b);\n" +"}\n" +"\n" +"ivec2 __operator / (const int a, const ivec2 u) {\n" +" return ivec2 (a / u.x, a / u.y);\n" +"}\n" +"\n" +"ivec2 __operator / (const ivec2 v, const int b) {\n" +" return ivec2 (v.x / b, v.y / b);\n" +"}\n" +"\n" +"ivec3 __operator + (const int a, const ivec3 u) {\n" +" return ivec3 (a + u.x, a + u.y, a + u.z);\n" +"}\n" +"\n" +"ivec3 __operator + (const ivec3 v, const int b) {\n" +" return ivec3 (v.x + b, v.y + b, v.z + b);\n" +"}\n" +"\n" +"ivec3 __operator - (const int a, const ivec3 u) {\n" +" return ivec3 (a - u.x, a - u.y, a - u.z);\n" +"}\n" +"\n" +"ivec3 __operator - (const ivec3 v, const int b) {\n" +" return ivec3 (v.x - b, v.y - b, v.z - b);\n" +"}\n" +"\n" +"ivec3 __operator * (const int a, const ivec3 u) {\n" +" return ivec3 (a * u.x, a * u.y, a * u.z);\n" +"}\n" +"\n" +"ivec3 __operator * (const ivec3 v, const int b) {\n" +" return ivec3 (v.x * b, v.y * b, v.z * b);\n" +"}\n" +"\n" +"ivec3 __operator / (const int a, const ivec3 u) {\n" +" return ivec3 (a / u.x, a / u.y, a / u.z);\n" +"}\n" +"\n" +"ivec3 __operator / (const ivec3 v, const int b) {\n" +" return ivec3 (v.x / b, v.y / b, v.z / b);\n" +"}\n" +"\n" +"ivec4 __operator + (const int a, const ivec4 u) {\n" +" return ivec4 (a + u.x, a + u.y, a + u.z, a + u.w);\n" +"}\n" +"\n" +"ivec4 __operator + (const ivec4 v, const int b) {\n" +" return ivec4 (v.x + b, v.y + b, v.z + b, v.w + b);\n" +"}\n" +"\n" +"ivec4 __operator - (const int a, const ivec4 u) {\n" +" return ivec4 (a - u.x, a - u.y, a - u.z, a - u.w);\n" +"}\n" +"\n" +"ivec4 __operator - (const ivec4 v, const int b) {\n" +" return ivec4 (v.x - b, v.y - b, v.z - b, v.w - b);\n" +"}\n" +"\n" +"ivec4 __operator * (const int a, const ivec4 u) {\n" +" return ivec4 (a * u.x, a * u.y, a * u.z, a * u.w);\n" +"}\n" +"\n" +"ivec4 __operator * (const ivec4 v, const int b) {\n" +" return ivec4 (v.x * b, v.y * b, v.z * b, v.w * b);\n" +"}\n" +"\n" +"ivec4 __operator / (const int a, const ivec4 u) {\n" +" return ivec4 (a / u.x, a / u.y, a / u.z, a / u.w);\n" +"}\n" +"\n" +"ivec4 __operator / (const ivec4 v, const int b) {\n" +" return ivec4 (v.x / b, v.y / b, v.z / b, v.w / b);\n" +"}\n" +"\n" +"vec2 __operator * (const vec2 v, const vec2 u) {\n" +" return vec2 (v.x * u.x, v.y * u.y);\n" +"}\n" +"\n" +"vec3 __operator * (const vec3 v, const vec3 u) {\n" +" return vec3 (v.x * u.x, v.y * u.y, v.z * u.z);\n" +"}\n" +"\n" +"vec4 __operator * (const vec4 v, const vec4 u) {\n" +" return vec4 (v.x * u.x, v.y * u.y, v.z * u.z, v.w * u.w);\n" +"}\n" +"\n" +"ivec2 __operator * (const ivec2 v, const ivec2 u) {\n" +" return ivec2 (v.x * u.x, v.y * u.y);\n" +"}\n" +"\n" +"ivec3 __operator * (const ivec3 v, const ivec3 u) {\n" +" return ivec3 (v.x * u.x, v.y * u.y, v.z * u.z);\n" +"}\n" +"\n" +"ivec4 __operator * (const ivec4 v, const ivec4 u) {\n" +" return ivec4 (v.x * u.x, v.y * u.y, v.z * u.z, v.w * u.w);\n" +"}\n" +"\n" +"vec2 __operator / (const vec2 v, const vec2 u) {\n" +" return vec2 (v.x / u.x, v.y / u.y);\n" +"}\n" +"\n" +"vec3 __operator / (const vec3 v, const vec3 u) {\n" +" return vec3 (v.x / u.x, v.y / u.y, v.z / u.z);\n" +"}\n" +"\n" +"vec4 __operator / (const vec4 v, const vec4 u) {\n" +" return vec4 (v.x / u.x, v.y / u.y, v.z / u.z, v.w / u.w);\n" +"}\n" +"\n" +"ivec2 __operator / (const ivec2 v, const ivec2 u) {\n" +" return ivec2 (v.x / u.x, v.y / u.y);\n" +"}\n" +"\n" +"ivec3 __operator / (const ivec3 v, const ivec3 u) {\n" +" return ivec3 (v.x / u.x, v.y / u.y, v.z / u.z);\n" +"}\n" +"\n" +"ivec4 __operator / (const ivec4 v, const ivec4 u) {\n" +" return ivec4 (v.x / u.x, v.y / u.y, v.z / u.z, v.w / u.w);\n" +"}\n" +"\n" +"mat2 __operator / (const mat2 m, const mat2 n) {\n" +" return mat2 (m[0] / n[0], m[1] / n[1]);\n" +"}\n" +"\n" +"mat3 __operator / (const mat3 m, const mat3 n) {\n" +" return mat3 (m[0] / n[0], m[1] / n[1], m[2] / n[2]);\n" +"}\n" +"\n" +"mat4 __operator / (const mat4 m, const mat4 n) {\n" +" return mat4 (m[0] / n[0], m[1] / n[1], m[2] / n[2], m[3] / n[3]);\n" +"}\n" +"\n" +"vec2 __operator - (const vec2 v) {\n" +" return vec2 (-v.x, -v.y);\n" +"}\n" +"\n" +"vec3 __operator - (const vec3 v) {\n" +" return vec3 (-v.x, -v.y, -v.z);\n" +"}\n" +"\n" +"vec4 __operator - (const vec4 v) {\n" +" return vec4 (-v.x, -v.y, -v.z, -v.w);\n" +"}\n" +"\n" +"ivec2 __operator - (const ivec2 v) {\n" +" return ivec2 (-v.x, -v.y);\n" +"}\n" +"\n" +"ivec3 __operator - (const ivec3 v) {\n" +" return ivec3 (-v.x, -v.y, -v.z);\n" +"}\n" +"\n" +"ivec4 __operator - (const ivec4 v) {\n" +" return ivec4 (-v.x, -v.y, -v.z, -v.w);\n" +"}\n" +"\n" +"mat2 __operator - (const mat2 m) {\n" +" return mat2 (-m[0], -m[1]);\n" +"}\n" +"\n" +"mat3 __operator - (const mat3 m) {\n" +" return mat3 (-m[0], -m[1], -m[2]);\n" +"}\n" +"\n" +"mat4 __operator - (const mat4 m) {\n" +" return mat4 (-m[0], -m[1], -m[2], -m[3]);\n" +"}\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"void __operator -- (inout float a) {\n" +" a -= 1.0;\n" +"}\n" +"\n" +"void __operator -- (inout int a) {\n" +" a -= 1;\n" +"}\n" +"\n" +"void __operator -- (inout vec2 v) {\n" +" --v.x, --v.y;\n" +"}\n" +"\n" +"void __operator -- (inout vec3 v) {\n" +" --v.x, --v.y, --v.z;\n" +"}\n" +"\n" +"void __operator -- (inout vec4 v) {\n" +" --v.x, --v.y, --v.z, --v.w;\n" +"}\n" +"\n" +"void __operator -- (inout ivec2 v) {\n" +" --v.x, --v.y;\n" +"}\n" +"\n" +"void __operator -- (inout ivec3 v) {\n" +" --v.x, --v.y, --v.z;\n" +"}\n" +"\n" +"void __operator -- (inout ivec4 v) {\n" +" --v.x, --v.y, --v.z, --v.w;\n" +"}\n" +"\n" +"void __operator -- (inout mat2 m) {\n" +" --m[0], --m[1];\n" +"}\n" +"\n" +"void __operator -- (inout mat3 m) {\n" +" --m[0], --m[1], --m[2];\n" +"}\n" +"\n" +"void __operator -- (inout mat4 m) {\n" +" --m[0], --m[1], --m[2], --m[3];\n" +"}\n" +"\n" +"void __operator ++ (inout float a) {\n" +" a += 1.0;\n" +"}\n" +"\n" +"void __operator ++ (inout int a) {\n" +" a += 1;\n" +"}\n" +"\n" +"void __operator ++ (inout vec2 v) {\n" +" ++v.x, ++v.y;\n" +"}\n" +"\n" +"void __operator ++ (inout vec3 v) {\n" +" ++v.x, ++v.y, ++v.z;\n" +"}\n" +"\n" +"void __operator ++ (inout vec4 v) {\n" +" ++v.x, ++v.y, ++v.z, ++v.w;\n" +"}\n" +"\n" +"void __operator ++ (inout ivec2 v) {\n" +" ++v.x, ++v.y;\n" +"}\n" +"\n" +"void __operator ++ (inout ivec3 v) {\n" +" ++v.x, ++v.y, ++v.z;\n" +"}\n" +"\n" +"void __operator ++ (inout ivec4 v) {\n" +" ++v.x, ++v.y, ++v.z, ++v.w;\n" +"}\n" +"\n" +"void __operator ++ (inout mat2 m) {\n" +" ++m[0], ++m[1];\n" +"}\n" +"\n" +"void __operator ++ (inout mat3 m) {\n" +" ++m[0], ++m[1], ++m[2];\n" +"}\n" +"\n" +"void __operator ++ (inout mat4 m) {\n" +" ++m[0], ++m[1], ++m[2], ++m[3];\n" +"}\n" +"\n" +"float __operator -- (inout float a, const int) {\n" +" float c;\n" +" c = a;\n" +" --a;\n" +" return c;\n" +"}\n" +"\n" +"int __operator -- (inout int a, const int) {\n" +" int c;\n" +" c = a;\n" +" --a;\n" +" return c;\n" +"}\n" +"\n" +"vec2 __operator -- (inout vec2 v, const int) {\n" +" return vec2 (v.x--, v.y--);\n" +"}\n" +"\n" +"vec3 __operator -- (inout vec3 v, const int) {\n" +" return vec3 (v.x--, v.y--, v.z--);\n" +"}\n" +"\n" +"vec4 __operator -- (inout vec4 v, const int) {\n" +" return vec4 (v.x--, v.y--, v.z--, v.w--);\n" +"}\n" +"\n" +"ivec2 __operator -- (inout ivec2 v, const int) {\n" +" return ivec2 (v.x--, v.y--);\n" +"}\n" +"\n" +"ivec3 __operator -- (inout ivec3 v, const int) {\n" +" return ivec3 (v.x--, v.y--, v.z--);\n" +"}\n" +"\n" +"ivec4 __operator -- (inout ivec4 v, const int) {\n" +" return ivec4 (v.x--, v.y--, v.z--, v.w--);\n" +"}\n" +"\n" +"mat2 __operator -- (inout mat2 m, const int) {\n" +" return mat2 (m[0]--, m[1]--);\n" +"}\n" +"\n" +"mat3 __operator -- (inout mat3 m, const int) {\n" +" return mat3 (m[0]--, m[1]--, m[2]--);\n" +"}\n" +"\n" +"mat4 __operator -- (inout mat4 m, const int) {\n" +" return mat4 (m[0]--, m[1]--, m[2]--, m[3]--);\n" +"}\n" +"\n" +"float __operator ++ (inout float a, const int) {\n" +" float c;\n" +" c = a;\n" +" ++a;\n" +" return c;\n" +"}\n" +"\n" +"int __operator ++ (inout int a, const int) {\n" +" int c;\n" +" c = a;\n" +" ++a;\n" +" return c;\n" +"}\n" +"\n" +"vec2 __operator ++ (inout vec2 v, const int) {\n" +" return vec2 (v.x++, v.y++);\n" +"}\n" +"\n" +"vec3 __operator ++ (inout vec3 v, const int) {\n" +" return vec3 (v.x++, v.y++, v.z++);\n" +"}\n" +"\n" +"vec4 __operator ++ (inout vec4 v, const int) {\n" +" return vec4 (v.x++, v.y++, v.z++, v.w++);\n" +"}\n" +"\n" +"ivec2 __operator ++ (inout ivec2 v, const int) {\n" +" return ivec2 (v.x++, v.y++);\n" +"}\n" +"\n" +"ivec3 __operator ++ (inout ivec3 v, const int) {\n" +" return ivec3 (v.x++, v.y++, v.z++);\n" +"}\n" +"\n" +"ivec4 __operator ++ (inout ivec4 v, const int) {\n" +" return ivec4 (v.x++, v.y++, v.z++, v.w++);\n" +"}\n" +"\n" +"mat2 __operator ++ (inout mat2 m, const int) {\n" +" return mat2 (m[0]++, m[1]++);\n" +"}\n" +"\n" +"mat3 __operator ++ (inout mat3 m, const int) {\n" +" return mat3 (m[0]++, m[1]++, m[2]++);\n" +"}\n" +"\n" +"mat4 __operator ++ (inout mat4 m, const int) {\n" +" return mat4 (m[0]++, m[1]++, m[2]++, m[3]++);\n" +"}\n" +"\n" +"bool __operator < (const float a, const float b) {\n" +" bool c;\n" +" __asm float_less c, a, b;\n" +" return c;\n" +"}\n" +"\n" +"bool __operator < (const int a, const int b) {\n" +" return float (a) < float (b);\n" +"}\n" +"\n" +"bool __operator > (const float a, const float b) {\n" +" return b < a;\n" +"}\n" +"\n" +"bool __operator > (const int a, const int b) {\n" +" return b < a;\n" +"}\n" +"\n" +"bool __operator >= (const float a, const float b) {\n" +" return a > b || a == b;\n" +"}\n" +"\n" +"bool __operator >= (const int a, const int b) {\n" +" return a > b || a == b;\n" +"}\n" +"\n" +"bool __operator <= (const float a, const float b) {\n" +" return a < b || a == b;\n" +"}\n" +"\n" +"bool __operator <= (const int a, const int b) {\n" +" return a < b || a == b;\n" +"}\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"bool __operator ^^ (const bool a, const bool b) {\n" +" return a != b;\n" +"}\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"bool __operator ! (const bool a) {\n" +" return a == false;\n" +"}\n" +"\n" diff --git a/nx-X11/extras/Mesa/src/mesa/shader/slang/library/slang_core_gc_bin.h b/nx-X11/extras/Mesa/src/mesa/shader/slang/library/slang_core_gc_bin.h new file mode 100644 index 000000000..ac53ceea8 --- /dev/null +++ b/nx-X11/extras/Mesa/src/mesa/shader/slang/library/slang_core_gc_bin.h @@ -0,0 +1,490 @@ +2,1,0,5,1,1,1,0,9,95,102,0,0,0,1,3,2,0,5,1,95,105,0,0,0,4,102,108,111,97,116,95,116,111,95,105,110, +116,0,18,95,105,0,0,18,95,102,0,0,0,8,18,95,105,0,0,0,1,0,1,1,1,1,0,5,95,105,0,0,0,1,8,18,95,105,0, +16,8,48,0,39,0,0,1,0,1,1,1,1,0,9,95,102,0,0,0,1,8,18,95,102,0,17,48,0,48,0,0,39,0,0,1,0,5,1,1,1,0,1, +95,98,0,0,0,1,8,18,95,98,0,16,10,49,0,16,8,48,0,31,0,0,1,0,9,1,1,1,0,1,95,98,0,0,0,1,8,18,95,98,0, +17,49,0,48,0,0,17,48,0,48,0,0,31,0,0,1,0,9,1,1,1,0,5,95,105,0,0,0,1,3,2,0,9,1,95,102,0,0,0,4,105, +110,116,95,116,111,95,102,108,111,97,116,0,18,95,102,0,0,18,95,105,0,0,0,8,18,95,102,0,0,0,1,0,1,1, +1,1,0,1,95,98,0,0,0,1,8,18,95,98,0,0,0,1,0,5,1,1,1,0,5,95,105,0,0,0,1,8,18,95,105,0,0,0,1,0,9,1,1,1, +0,9,95,102,0,0,0,1,8,18,95,102,0,0,0,1,0,10,1,1,1,0,9,95,102,0,0,0,1,8,58,118,101,99,50,0,18,95,102, +0,0,18,95,102,0,0,0,0,0,1,0,10,1,1,1,0,5,95,105,0,0,0,1,8,58,118,101,99,50,0,18,95,105,0,0,18,95, +105,0,0,0,0,0,1,0,10,1,1,1,0,1,95,98,0,0,0,1,8,58,118,101,99,50,0,18,95,98,0,0,18,95,98,0,0,0,0,0,1, +0,11,1,1,1,0,9,95,102,0,0,0,1,8,58,118,101,99,51,0,18,95,102,0,0,18,95,102,0,0,18,95,102,0,0,0,0,0, +1,0,11,1,1,1,0,5,95,105,0,0,0,1,8,58,118,101,99,51,0,18,95,105,0,0,18,95,105,0,0,18,95,105,0,0,0,0, +0,1,0,11,1,1,1,0,1,95,98,0,0,0,1,8,58,118,101,99,51,0,18,95,98,0,0,18,95,98,0,0,18,95,98,0,0,0,0,0, +1,0,12,1,1,1,0,9,95,102,0,0,0,1,8,58,118,101,99,52,0,18,95,102,0,0,18,95,102,0,0,18,95,102,0,0,18, +95,102,0,0,0,0,0,1,0,12,1,1,1,0,5,95,105,0,0,0,1,8,58,118,101,99,52,0,18,95,105,0,0,18,95,105,0,0, +18,95,105,0,0,18,95,105,0,0,0,0,0,1,0,12,1,1,1,0,1,95,98,0,0,0,1,8,58,118,101,99,52,0,18,95,98,0,0, +18,95,98,0,0,18,95,98,0,0,18,95,98,0,0,0,0,0,1,0,6,1,1,1,0,5,95,105,0,0,0,1,8,58,105,118,101,99,50, +0,18,95,105,0,0,18,95,105,0,0,0,0,0,1,0,6,1,1,1,0,9,95,102,0,0,0,1,8,58,105,118,101,99,50,0,18,95, +102,0,0,18,95,102,0,0,0,0,0,1,0,6,1,1,1,0,1,95,98,0,0,0,1,8,58,105,118,101,99,50,0,18,95,98,0,0,18, +95,98,0,0,0,0,0,1,0,7,1,1,1,0,5,95,105,0,0,0,1,8,58,105,118,101,99,51,0,18,95,105,0,0,18,95,105,0,0, +18,95,105,0,0,0,0,0,1,0,7,1,1,1,0,9,95,102,0,0,0,1,8,58,105,118,101,99,51,0,18,95,102,0,0,18,95,102, +0,0,18,95,102,0,0,0,0,0,1,0,7,1,1,1,0,1,95,98,0,0,0,1,8,58,105,118,101,99,51,0,18,95,98,0,0,18,95, +98,0,0,18,95,98,0,0,0,0,0,1,0,8,1,1,1,0,5,95,105,0,0,0,1,8,58,105,118,101,99,52,0,18,95,105,0,0,18, +95,105,0,0,18,95,105,0,0,18,95,105,0,0,0,0,0,1,0,8,1,1,1,0,9,95,102,0,0,0,1,8,58,105,118,101,99,52, +0,18,95,102,0,0,18,95,102,0,0,18,95,102,0,0,18,95,102,0,0,0,0,0,1,0,8,1,1,1,0,1,95,98,0,0,0,1,8,58, +105,118,101,99,52,0,18,95,98,0,0,18,95,98,0,0,18,95,98,0,0,18,95,98,0,0,0,0,0,1,0,2,1,1,1,0,1,95,98, +0,0,0,1,8,58,98,118,101,99,50,0,18,95,98,0,0,18,95,98,0,0,0,0,0,1,0,2,1,1,1,0,9,95,102,0,0,0,1,8,58, +98,118,101,99,50,0,18,95,102,0,0,18,95,102,0,0,0,0,0,1,0,2,1,1,1,0,5,95,105,0,0,0,1,8,58,98,118,101, +99,50,0,18,95,105,0,0,18,95,105,0,0,0,0,0,1,0,3,1,1,1,0,1,95,98,0,0,0,1,8,58,98,118,101,99,51,0,18, +95,98,0,0,18,95,98,0,0,18,95,98,0,0,0,0,0,1,0,3,1,1,1,0,9,95,102,0,0,0,1,8,58,98,118,101,99,51,0,18, +95,102,0,0,18,95,102,0,0,18,95,102,0,0,0,0,0,1,0,3,1,1,1,0,5,95,105,0,0,0,1,8,58,98,118,101,99,51,0, +18,95,105,0,0,18,95,105,0,0,18,95,105,0,0,0,0,0,1,0,4,1,1,1,0,1,95,98,0,0,0,1,8,58,98,118,101,99,52, +0,18,95,98,0,0,18,95,98,0,0,18,95,98,0,0,18,95,98,0,0,0,0,0,1,0,4,1,1,1,0,9,95,102,0,0,0,1,8,58,98, +118,101,99,52,0,18,95,102,0,0,18,95,102,0,0,18,95,102,0,0,18,95,102,0,0,0,0,0,1,0,4,1,1,1,0,5,95, +105,0,0,0,1,8,58,98,118,101,99,52,0,18,95,105,0,0,18,95,105,0,0,18,95,105,0,0,18,95,105,0,0,0,0,0,1, +0,13,1,1,1,0,9,95,102,0,0,0,1,8,58,109,97,116,50,0,18,95,102,0,0,17,0,48,0,0,0,17,0,48,0,0,0,18,95, +102,0,0,0,0,0,1,0,13,1,1,1,0,5,95,105,0,0,0,1,8,58,109,97,116,50,0,18,95,105,0,0,17,0,48,0,0,0,17,0, +48,0,0,0,18,95,105,0,0,0,0,0,1,0,13,1,1,1,0,1,95,98,0,0,0,1,8,58,109,97,116,50,0,18,95,98,0,0,17,0, +48,0,0,0,17,0,48,0,0,0,18,95,98,0,0,0,0,0,1,0,14,1,1,1,0,9,95,102,0,0,0,1,8,58,109,97,116,51,0,18, +95,102,0,0,17,0,48,0,0,0,17,0,48,0,0,0,17,0,48,0,0,0,18,95,102,0,0,17,0,48,0,0,0,17,0,48,0,0,0,17,0, +48,0,0,0,18,95,102,0,0,0,0,0,1,0,14,1,1,1,0,5,95,105,0,0,0,1,8,58,109,97,116,51,0,18,95,105,0,0,17, +0,48,0,0,0,17,0,48,0,0,0,17,0,48,0,0,0,18,95,105,0,0,17,0,48,0,0,0,17,0,48,0,0,0,17,0,48,0,0,0,18, +95,105,0,0,0,0,0,1,0,14,1,1,1,0,1,95,98,0,0,0,1,8,58,109,97,116,51,0,18,95,98,0,0,17,0,48,0,0,0,17, +0,48,0,0,0,17,0,48,0,0,0,18,95,98,0,0,17,0,48,0,0,0,17,0,48,0,0,0,17,0,48,0,0,0,18,95,98,0,0,0,0,0, +1,0,15,1,1,1,0,9,95,102,0,0,0,1,8,58,109,97,116,52,0,18,95,102,0,0,17,0,48,0,0,0,17,0,48,0,0,0,17,0, +48,0,0,0,17,0,48,0,0,0,18,95,102,0,0,17,0,48,0,0,0,17,0,48,0,0,0,17,0,48,0,0,0,17,0,48,0,0,0,18,95, +102,0,0,17,0,48,0,0,0,17,0,48,0,0,0,17,0,48,0,0,0,17,0,48,0,0,0,18,95,102,0,0,0,0,0,1,0,15,1,1,1,0, +5,95,105,0,0,0,1,8,58,109,97,116,52,0,18,95,105,0,0,17,0,48,0,0,0,17,0,48,0,0,0,17,0,48,0,0,0,17,0, +48,0,0,0,18,95,105,0,0,17,0,48,0,0,0,17,0,48,0,0,0,17,0,48,0,0,0,17,0,48,0,0,0,18,95,105,0,0,17,0, +48,0,0,0,17,0,48,0,0,0,17,0,48,0,0,0,17,0,48,0,0,0,18,95,105,0,0,0,0,0,1,0,15,1,1,1,0,1,95,98,0,0,0, +1,8,58,109,97,116,52,0,18,95,98,0,0,17,0,48,0,0,0,17,0,48,0,0,0,17,0,48,0,0,0,17,0,48,0,0,0,18,95, +98,0,0,17,0,48,0,0,0,17,0,48,0,0,0,17,0,48,0,0,0,17,0,48,0,0,0,18,95,98,0,0,17,0,48,0,0,0,17,0,48,0, +0,0,17,0,48,0,0,0,17,0,48,0,0,0,18,95,98,0,0,0,0,0,1,0,0,2,2,1,0,2,9,97,0,0,1,1,0,9,98,0,0,0,1,4, +102,108,111,97,116,95,97,100,100,0,18,97,0,0,18,97,0,0,18,98,0,0,0,0,1,0,9,2,30,1,1,0,9,97,0,0,0,1, +3,2,0,9,1,99,0,0,0,4,102,108,111,97,116,95,110,101,103,97,116,101,0,18,99,0,0,18,97,0,0,0,8,18,99,0, +0,0,1,0,0,2,3,1,0,2,9,97,0,0,1,1,0,9,98,0,0,0,1,9,18,97,0,18,98,0,54,21,0,0,1,0,0,2,4,1,0,2,9,97,0, +0,1,1,0,9,98,0,0,0,1,4,102,108,111,97,116,95,109,117,108,116,105,112,108,121,0,18,97,0,0,18,97,0,0, +18,98,0,0,0,0,1,0,0,2,5,1,0,2,9,97,0,0,1,1,0,9,98,0,0,0,1,4,102,108,111,97,116,95,100,105,118,105, +100,101,0,18,97,0,0,18,97,0,0,18,98,0,0,0,0,1,0,9,2,29,1,1,0,9,97,0,0,1,1,0,9,98,0,0,0,1,3,2,0,9,1, +99,0,0,0,9,18,99,0,18,97,0,20,0,8,18,99,0,18,98,0,21,0,0,1,0,0,2,2,1,0,2,5,97,0,0,1,1,0,5,98,0,0,0, +1,9,18,97,0,58,105,110,116,0,58,102,108,111,97,116,0,18,97,0,0,0,58,102,108,111,97,116,0,18,98,0,0, +0,46,0,0,20,0,0,1,0,5,2,30,1,1,0,5,97,0,0,0,1,8,58,105,110,116,0,58,102,108,111,97,116,0,18,97,0,0, +0,54,0,0,0,0,1,0,0,2,3,1,0,2,5,97,0,0,1,1,0,5,98,0,0,0,1,9,18,97,0,18,98,0,54,21,0,0,1,0,9,2,24,1,1, +0,9,97,0,0,1,1,0,9,98,0,0,0,1,3,2,0,9,1,99,0,0,0,9,18,99,0,18,97,0,20,0,8,18,99,0,18,98,0,23,0,0,1, +0,0,2,4,1,0,2,5,97,0,0,1,1,0,5,98,0,0,0,1,9,18,97,0,58,105,110,116,0,58,102,108,111,97,116,0,18,97, +0,0,0,58,102,108,111,97,116,0,18,98,0,0,0,48,0,0,20,0,0,1,0,9,2,25,1,1,0,9,97,0,0,1,1,0,9,98,0,0,0, +1,3,2,0,9,1,99,0,0,0,9,18,99,0,18,97,0,20,0,8,18,99,0,18,98,0,24,0,0,1,0,0,2,5,1,0,2,5,97,0,0,1,1,0, +5,98,0,0,0,1,9,18,97,0,58,105,110,116,0,58,102,108,111,97,116,0,18,97,0,0,0,58,102,108,111,97,116,0, +18,98,0,0,0,49,0,0,20,0,0,1,0,0,2,2,1,0,2,10,118,0,0,1,1,0,10,117,0,0,0,1,9,18,118,0,59,120,0,18, +117,0,59,120,0,21,18,118,0,59,121,0,18,117,0,59,121,0,21,19,0,0,1,0,0,2,3,1,0,2,10,118,0,0,1,1,0,10, +117,0,0,0,1,9,18,118,0,59,120,0,18,117,0,59,120,0,22,18,118,0,59,121,0,18,117,0,59,121,0,22,19,0,0, +1,0,0,2,4,1,0,2,10,118,0,0,1,1,0,10,117,0,0,0,1,9,18,118,0,59,120,0,18,117,0,59,120,0,23,18,118,0, +59,121,0,18,117,0,59,121,0,23,19,0,0,1,0,0,2,5,1,0,2,10,118,0,0,1,1,0,10,117,0,0,0,1,9,18,118,0,59, +120,0,18,117,0,59,120,0,24,18,118,0,59,121,0,18,117,0,59,121,0,24,19,0,0,1,0,0,2,2,1,0,2,11,118,0,0, +1,1,0,11,117,0,0,0,1,9,18,118,0,59,120,0,18,117,0,59,120,0,21,18,118,0,59,121,0,18,117,0,59,121,0, +21,19,18,118,0,59,122,0,18,117,0,59,122,0,21,19,0,0,1,0,0,2,3,1,0,2,11,118,0,0,1,1,0,11,117,0,0,0,1, +9,18,118,0,59,120,0,18,117,0,59,120,0,22,18,118,0,59,121,0,18,117,0,59,121,0,22,19,18,118,0,59,122, +0,18,117,0,59,122,0,22,19,0,0,1,0,0,2,4,1,0,2,11,118,0,0,1,1,0,11,117,0,0,0,1,9,18,118,0,59,120,0, +18,117,0,59,120,0,23,18,118,0,59,121,0,18,117,0,59,121,0,23,19,18,118,0,59,122,0,18,117,0,59,122,0, +23,19,0,0,1,0,0,2,5,1,0,2,11,118,0,0,1,1,0,11,117,0,0,0,1,9,18,118,0,59,120,0,18,117,0,59,120,0,24, +18,118,0,59,121,0,18,117,0,59,121,0,24,19,18,118,0,59,122,0,18,117,0,59,122,0,24,19,0,0,1,0,0,2,2,1, +0,2,12,118,0,0,1,1,0,12,117,0,0,0,1,9,18,118,0,59,120,0,18,117,0,59,120,0,21,18,118,0,59,121,0,18, +117,0,59,121,0,21,19,18,118,0,59,122,0,18,117,0,59,122,0,21,19,18,118,0,59,119,0,18,117,0,59,119,0, +21,19,0,0,1,0,0,2,3,1,0,2,12,118,0,0,1,1,0,12,117,0,0,0,1,9,18,118,0,59,120,0,18,117,0,59,120,0,22, +18,118,0,59,121,0,18,117,0,59,121,0,22,19,18,118,0,59,122,0,18,117,0,59,122,0,22,19,18,118,0,59,119, +0,18,117,0,59,119,0,22,19,0,0,1,0,0,2,4,1,0,2,12,118,0,0,1,1,0,12,117,0,0,0,1,9,18,118,0,59,120,0, +18,117,0,59,120,0,23,18,118,0,59,121,0,18,117,0,59,121,0,23,19,18,118,0,59,122,0,18,117,0,59,122,0, +23,19,18,118,0,59,119,0,18,117,0,59,119,0,23,19,0,0,1,0,0,2,5,1,0,2,12,118,0,0,1,1,0,12,117,0,0,0,1, +9,18,118,0,59,120,0,18,117,0,59,120,0,24,18,118,0,59,121,0,18,117,0,59,121,0,24,19,18,118,0,59,122, +0,18,117,0,59,122,0,24,19,18,118,0,59,119,0,18,117,0,59,119,0,24,19,0,0,1,0,0,2,2,1,0,2,6,118,0,0,1, +1,0,6,117,0,0,0,1,9,18,118,0,59,120,0,18,117,0,59,120,0,21,18,118,0,59,121,0,18,117,0,59,121,0,21, +19,0,0,1,0,0,2,3,1,0,2,6,118,0,0,1,1,0,6,117,0,0,0,1,9,18,118,0,59,120,0,18,117,0,59,120,0,22,18, +118,0,59,121,0,18,117,0,59,121,0,22,19,0,0,1,0,0,2,4,1,0,2,6,118,0,0,1,1,0,6,117,0,0,0,1,9,18,118,0, +59,120,0,18,117,0,59,120,0,23,18,118,0,59,121,0,18,117,0,59,121,0,23,19,0,0,1,0,0,2,5,1,0,2,6,118,0, +0,1,1,0,6,117,0,0,0,1,9,18,118,0,59,120,0,18,117,0,59,120,0,24,18,118,0,59,121,0,18,117,0,59,121,0, +24,19,0,0,1,0,0,2,2,1,0,2,7,118,0,0,1,1,0,7,117,0,0,0,1,9,18,118,0,59,120,0,18,117,0,59,120,0,21,18, +118,0,59,121,0,18,117,0,59,121,0,21,19,18,118,0,59,122,0,18,117,0,59,122,0,21,19,0,0,1,0,0,2,3,1,0, +2,7,118,0,0,1,1,0,7,117,0,0,0,1,9,18,118,0,59,120,0,18,117,0,59,120,0,22,18,118,0,59,121,0,18,117,0, +59,121,0,22,19,18,118,0,59,122,0,18,117,0,59,122,0,22,19,0,0,1,0,0,2,4,1,0,2,7,118,0,0,1,1,0,7,117, +0,0,0,1,9,18,118,0,59,120,0,18,117,0,59,120,0,23,18,118,0,59,121,0,18,117,0,59,121,0,23,19,18,118,0, +59,122,0,18,117,0,59,122,0,23,19,0,0,1,0,0,2,5,1,0,2,7,118,0,0,1,1,0,7,117,0,0,0,1,9,18,118,0,59, +120,0,18,117,0,59,120,0,24,18,118,0,59,121,0,18,117,0,59,121,0,24,19,18,118,0,59,122,0,18,117,0,59, +122,0,24,19,0,0,1,0,0,2,2,1,0,2,8,118,0,0,1,1,0,8,117,0,0,0,1,9,18,118,0,59,120,0,18,117,0,59,120,0, +21,18,118,0,59,121,0,18,117,0,59,121,0,21,19,18,118,0,59,122,0,18,117,0,59,122,0,21,19,18,118,0,59, +119,0,18,117,0,59,119,0,21,19,0,0,1,0,0,2,3,1,0,2,8,118,0,0,1,1,0,8,117,0,0,0,1,9,18,118,0,59,120,0, +18,117,0,59,120,0,22,18,118,0,59,121,0,18,117,0,59,121,0,22,19,18,118,0,59,122,0,18,117,0,59,122,0, +22,19,18,118,0,59,119,0,18,117,0,59,119,0,22,19,0,0,1,0,0,2,4,1,0,2,8,118,0,0,1,1,0,8,117,0,0,0,1,9, +18,118,0,59,120,0,18,117,0,59,120,0,23,18,118,0,59,121,0,18,117,0,59,121,0,23,19,18,118,0,59,122,0, +18,117,0,59,122,0,23,19,18,118,0,59,119,0,18,117,0,59,119,0,23,19,0,0,1,0,0,2,5,1,0,2,8,118,0,0,1,1, +0,8,117,0,0,0,1,9,18,118,0,59,120,0,18,117,0,59,120,0,24,18,118,0,59,121,0,18,117,0,59,121,0,24,19, +18,118,0,59,122,0,18,117,0,59,122,0,24,19,18,118,0,59,119,0,18,117,0,59,119,0,24,19,0,0,1,0,0,2,2,1, +0,2,13,109,0,0,1,1,0,13,110,0,0,0,1,9,18,109,0,16,8,48,0,57,18,110,0,16,8,48,0,57,21,18,109,0,16,10, +49,0,57,18,110,0,16,10,49,0,57,21,19,0,0,1,0,0,2,3,1,0,2,13,109,0,0,1,1,0,13,110,0,0,0,1,9,18,109,0, +16,8,48,0,57,18,110,0,16,8,48,0,57,22,18,109,0,16,10,49,0,57,18,110,0,16,10,49,0,57,22,19,0,0,1,0, +10,2,24,1,1,0,13,109,0,0,1,1,0,10,118,0,0,0,1,8,58,118,101,99,50,0,18,118,0,59,120,0,18,109,0,16,8, +48,0,57,59,120,0,48,18,118,0,59,121,0,18,109,0,16,10,49,0,57,59,120,0,48,46,0,18,118,0,59,120,0,18, +109,0,16,8,48,0,57,59,121,0,48,18,118,0,59,121,0,18,109,0,16,10,49,0,57,59,121,0,48,46,0,0,0,0,1,0, +13,2,24,1,1,0,13,109,0,0,1,1,0,13,110,0,0,0,1,8,58,109,97,116,50,0,18,109,0,18,110,0,16,8,48,0,57, +48,0,18,109,0,18,110,0,16,10,49,0,57,48,0,0,0,0,1,0,0,2,4,1,0,2,13,109,0,0,1,1,0,13,110,0,0,0,1,9, +18,109,0,18,109,0,18,110,0,48,20,0,0,1,0,0,2,5,1,0,2,13,109,0,0,1,1,0,13,110,0,0,0,1,9,18,109,0,16, +8,48,0,57,18,110,0,16,8,48,0,57,24,18,109,0,16,10,49,0,57,18,110,0,16,10,49,0,57,24,19,0,0,1,0,0,2, +2,1,0,2,14,109,0,0,1,1,0,14,110,0,0,0,1,9,18,109,0,16,8,48,0,57,18,110,0,16,8,48,0,57,21,18,109,0, +16,10,49,0,57,18,110,0,16,10,49,0,57,21,19,18,109,0,16,10,50,0,57,18,110,0,16,10,50,0,57,21,19,0,0, +1,0,0,2,3,1,0,2,14,109,0,0,1,1,0,14,110,0,0,0,1,9,18,109,0,16,8,48,0,57,18,110,0,16,8,48,0,57,22,18, +109,0,16,10,49,0,57,18,110,0,16,10,49,0,57,22,19,18,109,0,16,10,50,0,57,18,110,0,16,10,50,0,57,22, +19,0,0,1,0,11,2,24,1,1,0,14,109,0,0,1,1,0,11,118,0,0,0,1,8,58,118,101,99,51,0,18,118,0,59,120,0,18, +109,0,16,8,48,0,57,59,120,0,48,18,118,0,59,121,0,18,109,0,16,10,49,0,57,59,120,0,48,46,18,118,0,59, +122,0,18,109,0,16,10,50,0,57,59,120,0,48,46,0,18,118,0,59,120,0,18,109,0,16,8,48,0,57,59,121,0,48, +18,118,0,59,121,0,18,109,0,16,10,49,0,57,59,121,0,48,46,18,118,0,59,122,0,18,109,0,16,10,50,0,57,59, +121,0,48,46,0,18,118,0,59,120,0,18,109,0,16,8,48,0,57,59,122,0,48,18,118,0,59,121,0,18,109,0,16,10, +49,0,57,59,122,0,48,46,18,118,0,59,122,0,18,109,0,16,10,50,0,57,59,122,0,48,46,0,0,0,0,1,0,14,2,24, +1,1,0,14,109,0,0,1,1,0,14,110,0,0,0,1,8,58,109,97,116,51,0,18,109,0,18,110,0,16,8,48,0,57,48,0,18, +109,0,18,110,0,16,10,49,0,57,48,0,18,109,0,18,110,0,16,10,50,0,57,48,0,0,0,0,1,0,0,2,4,1,0,2,14,109, +0,0,1,1,0,14,110,0,0,0,1,9,18,109,0,18,109,0,18,110,0,48,20,0,0,1,0,0,2,5,1,0,2,14,109,0,0,1,1,0,14, +110,0,0,0,1,9,18,109,0,16,8,48,0,57,18,110,0,16,8,48,0,57,24,18,109,0,16,10,49,0,57,18,110,0,16,10, +49,0,57,24,19,18,109,0,16,10,50,0,57,18,110,0,16,10,50,0,57,24,19,0,0,1,0,0,2,2,1,0,2,15,109,0,0,1, +1,0,15,110,0,0,0,1,9,18,109,0,16,8,48,0,57,18,110,0,16,8,48,0,57,21,18,109,0,16,10,49,0,57,18,110,0, +16,10,49,0,57,21,19,18,109,0,16,10,50,0,57,18,110,0,16,10,50,0,57,21,19,18,109,0,16,10,51,0,57,18, +110,0,16,10,51,0,57,21,19,0,0,1,0,0,2,3,1,0,2,15,109,0,0,1,1,0,15,110,0,0,0,1,9,18,109,0,16,8,48,0, +57,18,110,0,16,8,48,0,57,22,18,109,0,16,10,49,0,57,18,110,0,16,10,49,0,57,22,19,18,109,0,16,10,50,0, +57,18,110,0,16,10,50,0,57,22,19,18,109,0,16,10,51,0,57,18,110,0,16,10,51,0,57,22,19,0,0,1,0,12,2,24, +1,1,0,15,109,0,0,1,1,0,12,118,0,0,0,1,8,58,118,101,99,52,0,18,118,0,59,120,0,18,109,0,16,8,48,0,57, +59,120,0,48,18,118,0,59,121,0,18,109,0,16,10,49,0,57,59,120,0,48,46,18,118,0,59,122,0,18,109,0,16, +10,50,0,57,59,120,0,48,46,18,118,0,59,119,0,18,109,0,16,10,51,0,57,59,120,0,48,46,0,18,118,0,59,120, +0,18,109,0,16,8,48,0,57,59,121,0,48,18,118,0,59,121,0,18,109,0,16,10,49,0,57,59,121,0,48,46,18,118, +0,59,122,0,18,109,0,16,10,50,0,57,59,121,0,48,46,18,118,0,59,119,0,18,109,0,16,10,51,0,57,59,121,0, +48,46,0,18,118,0,59,120,0,18,109,0,16,8,48,0,57,59,122,0,48,18,118,0,59,121,0,18,109,0,16,10,49,0, +57,59,122,0,48,46,18,118,0,59,122,0,18,109,0,16,10,50,0,57,59,122,0,48,46,18,118,0,59,119,0,18,109, +0,16,10,51,0,57,59,122,0,48,46,0,18,118,0,59,120,0,18,109,0,16,8,48,0,57,59,119,0,48,18,118,0,59, +121,0,18,109,0,16,10,49,0,57,59,119,0,48,46,18,118,0,59,122,0,18,109,0,16,10,50,0,57,59,119,0,48,46, +18,118,0,59,119,0,18,109,0,16,10,51,0,57,59,119,0,48,46,0,0,0,0,1,0,15,2,24,1,1,0,15,109,0,0,1,1,0, +15,110,0,0,0,1,8,58,109,97,116,52,0,18,109,0,18,110,0,16,8,48,0,57,48,0,18,109,0,18,110,0,16,10,49, +0,57,48,0,18,109,0,18,110,0,16,10,50,0,57,48,0,18,109,0,18,110,0,16,10,51,0,57,48,0,0,0,0,1,0,0,2,4, +1,0,2,15,109,0,0,1,1,0,15,110,0,0,0,1,9,18,109,0,18,109,0,18,110,0,48,20,0,0,1,0,0,2,5,1,0,2,15,109, +0,0,1,1,0,15,110,0,0,0,1,9,18,109,0,16,8,48,0,57,18,110,0,16,8,48,0,57,24,18,109,0,16,10,49,0,57,18, +110,0,16,10,49,0,57,24,19,18,109,0,16,10,50,0,57,18,110,0,16,10,50,0,57,24,19,18,109,0,16,10,51,0, +57,18,110,0,16,10,51,0,57,24,19,0,0,1,0,0,2,2,1,0,2,10,118,0,0,1,1,0,9,97,0,0,0,1,9,18,118,0,59,120, +0,18,97,0,21,18,118,0,59,121,0,18,97,0,21,19,0,0,1,0,0,2,3,1,0,2,10,118,0,0,1,1,0,9,97,0,0,0,1,9,18, +118,0,59,120,0,18,97,0,22,18,118,0,59,121,0,18,97,0,22,19,0,0,1,0,0,2,4,1,0,2,10,118,0,0,1,1,0,9,97, +0,0,0,1,9,18,118,0,59,120,0,18,97,0,23,18,118,0,59,121,0,18,97,0,23,19,0,0,1,0,0,2,5,1,0,2,10,118,0, +0,1,1,0,9,97,0,0,0,1,9,18,118,0,59,120,0,18,97,0,24,18,118,0,59,121,0,18,97,0,24,19,0,0,1,0,0,2,2,1, +0,2,11,118,0,0,1,1,0,9,97,0,0,0,1,9,18,118,0,59,120,0,18,97,0,21,18,118,0,59,121,0,18,97,0,21,19,18, +118,0,59,122,0,18,97,0,21,19,0,0,1,0,0,2,3,1,0,2,11,118,0,0,1,1,0,9,97,0,0,0,1,9,18,118,0,59,120,0, +18,97,0,22,18,118,0,59,121,0,18,97,0,22,19,18,118,0,59,122,0,18,97,0,22,19,0,0,1,0,0,2,4,1,0,2,11, +118,0,0,1,1,0,9,97,0,0,0,1,9,18,118,0,59,120,0,18,97,0,23,18,118,0,59,121,0,18,97,0,23,19,18,118,0, +59,122,0,18,97,0,23,19,0,0,1,0,0,2,5,1,0,2,11,118,0,0,1,1,0,9,97,0,0,0,1,9,18,118,0,59,120,0,18,97, +0,24,18,118,0,59,121,0,18,97,0,24,19,18,118,0,59,122,0,18,97,0,24,19,0,0,1,0,0,2,2,1,0,2,12,118,0,0, +1,1,0,9,97,0,0,0,1,9,18,118,0,59,120,0,18,97,0,21,18,118,0,59,121,0,18,97,0,21,19,18,118,0,59,122,0, +18,97,0,21,19,18,118,0,59,119,0,18,97,0,21,19,0,0,1,0,0,2,3,1,0,2,12,118,0,0,1,1,0,9,97,0,0,0,1,9, +18,118,0,59,120,0,18,97,0,22,18,118,0,59,121,0,18,97,0,22,19,18,118,0,59,122,0,18,97,0,22,19,18,118, +0,59,119,0,18,97,0,22,19,0,0,1,0,0,2,4,1,0,2,12,118,0,0,1,1,0,9,97,0,0,0,1,9,18,118,0,59,120,0,18, +97,0,23,18,118,0,59,121,0,18,97,0,23,19,18,118,0,59,122,0,18,97,0,23,19,18,118,0,59,119,0,18,97,0, +23,19,0,0,1,0,0,2,5,1,0,2,12,118,0,0,1,1,0,9,97,0,0,0,1,9,18,118,0,59,120,0,18,97,0,24,18,118,0,59, +121,0,18,97,0,24,19,18,118,0,59,122,0,18,97,0,24,19,18,118,0,59,119,0,18,97,0,24,19,0,0,1,0,0,2,2,1, +0,2,13,109,0,0,1,1,0,9,97,0,0,0,1,9,18,109,0,16,8,48,0,57,18,97,0,21,18,109,0,16,10,49,0,57,18,97,0, +21,19,0,0,1,0,0,2,3,1,0,2,13,109,0,0,1,1,0,9,97,0,0,0,1,9,18,109,0,16,8,48,0,57,18,97,0,22,18,109,0, +16,10,49,0,57,18,97,0,22,19,0,0,1,0,0,2,4,1,0,2,13,109,0,0,1,1,0,9,97,0,0,0,1,9,18,109,0,16,8,48,0, +57,18,97,0,23,18,109,0,16,10,49,0,57,18,97,0,23,19,0,0,1,0,0,2,5,1,0,2,13,109,0,0,1,1,0,9,97,0,0,0, +1,9,18,109,0,16,8,48,0,57,18,97,0,24,18,109,0,16,10,49,0,57,18,97,0,24,19,0,0,1,0,0,2,2,1,0,2,14, +109,0,0,1,1,0,9,97,0,0,0,1,9,18,109,0,16,8,48,0,57,18,97,0,21,18,109,0,16,10,49,0,57,18,97,0,21,19, +18,109,0,16,10,50,0,57,18,97,0,21,19,0,0,1,0,0,2,3,1,0,2,14,109,0,0,1,1,0,9,97,0,0,0,1,9,18,109,0, +16,8,48,0,57,18,97,0,22,18,109,0,16,10,49,0,57,18,97,0,22,19,18,109,0,16,10,50,0,57,18,97,0,22,19,0, +0,1,0,0,2,4,1,0,2,14,109,0,0,1,1,0,9,97,0,0,0,1,9,18,109,0,16,8,48,0,57,18,97,0,23,18,109,0,16,10, +49,0,57,18,97,0,23,19,18,109,0,16,10,50,0,57,18,97,0,23,19,0,0,1,0,0,2,5,1,0,2,14,109,0,0,1,1,0,9, +97,0,0,0,1,9,18,109,0,16,8,48,0,57,18,97,0,24,18,109,0,16,10,49,0,57,18,97,0,24,19,18,109,0,16,10, +50,0,57,18,97,0,24,19,0,0,1,0,0,2,2,1,0,2,15,109,0,0,1,1,0,9,97,0,0,0,1,9,18,109,0,16,8,48,0,57,18, +97,0,21,18,109,0,16,10,49,0,57,18,97,0,21,19,18,109,0,16,10,50,0,57,18,97,0,21,19,18,109,0,16,10,51, +0,57,18,97,0,21,19,0,0,1,0,0,2,3,1,0,2,15,109,0,0,1,1,0,9,97,0,0,0,1,9,18,109,0,16,8,48,0,57,18,97, +0,22,18,109,0,16,10,49,0,57,18,97,0,22,19,18,109,0,16,10,50,0,57,18,97,0,22,19,18,109,0,16,10,51,0, +57,18,97,0,22,19,0,0,1,0,0,2,4,1,0,2,15,109,0,0,1,1,0,9,97,0,0,0,1,9,18,109,0,16,8,48,0,57,18,97,0, +23,18,109,0,16,10,49,0,57,18,97,0,23,19,18,109,0,16,10,50,0,57,18,97,0,23,19,18,109,0,16,10,51,0,57, +18,97,0,23,19,0,0,1,0,0,2,5,1,0,2,15,109,0,0,1,1,0,9,97,0,0,0,1,9,18,109,0,16,8,48,0,57,18,97,0,24, +18,109,0,16,10,49,0,57,18,97,0,24,19,18,109,0,16,10,50,0,57,18,97,0,24,19,18,109,0,16,10,51,0,57,18, +97,0,24,19,0,0,1,0,10,2,24,1,1,0,10,118,0,0,1,1,0,13,109,0,0,0,1,8,58,118,101,99,50,0,18,118,0,59, +120,0,18,109,0,16,8,48,0,57,59,120,0,48,18,118,0,59,121,0,18,109,0,16,8,48,0,57,59,121,0,48,46,0,18, +118,0,59,120,0,18,109,0,16,10,49,0,57,59,120,0,48,18,118,0,59,121,0,18,109,0,16,10,49,0,57,59,121,0, +48,46,0,0,0,0,1,0,0,2,4,1,0,2,10,118,0,0,1,1,0,13,109,0,0,0,1,9,18,118,0,18,118,0,18,109,0,48,20,0, +0,1,0,11,2,24,1,1,0,11,118,0,0,1,1,0,14,109,0,0,0,1,8,58,118,101,99,51,0,18,118,0,59,120,0,18,109,0, +16,8,48,0,57,59,120,0,48,18,118,0,59,121,0,18,109,0,16,8,48,0,57,59,121,0,48,46,18,118,0,59,122,0, +18,109,0,16,8,48,0,57,59,122,0,48,46,0,18,118,0,59,120,0,18,109,0,16,10,49,0,57,59,120,0,48,18,118, +0,59,121,0,18,109,0,16,10,49,0,57,59,121,0,48,46,18,118,0,59,122,0,18,109,0,16,10,49,0,57,59,122,0, +48,46,0,18,118,0,59,120,0,18,109,0,16,10,50,0,57,59,120,0,48,18,118,0,59,121,0,18,109,0,16,10,50,0, +57,59,121,0,48,46,18,118,0,59,122,0,18,109,0,16,10,50,0,57,59,122,0,48,46,0,0,0,0,1,0,0,2,4,1,0,2, +11,118,0,0,1,1,0,14,109,0,0,0,1,9,18,118,0,18,118,0,18,109,0,48,20,0,0,1,0,12,2,24,1,1,0,12,118,0,0, +1,1,0,15,109,0,0,0,1,8,58,118,101,99,52,0,18,118,0,59,120,0,18,109,0,16,8,48,0,57,59,120,0,48,18, +118,0,59,121,0,18,109,0,16,8,48,0,57,59,121,0,48,46,18,118,0,59,122,0,18,109,0,16,8,48,0,57,59,122, +0,48,46,18,118,0,59,119,0,18,109,0,16,8,48,0,57,59,119,0,48,46,0,18,118,0,59,120,0,18,109,0,16,10, +49,0,57,59,120,0,48,18,118,0,59,121,0,18,109,0,16,10,49,0,57,59,121,0,48,46,18,118,0,59,122,0,18, +109,0,16,10,49,0,57,59,122,0,48,46,18,118,0,59,119,0,18,109,0,16,10,49,0,57,59,119,0,48,46,0,18,118, +0,59,120,0,18,109,0,16,10,50,0,57,59,120,0,48,18,118,0,59,121,0,18,109,0,16,10,50,0,57,59,121,0,48, +46,18,118,0,59,122,0,18,109,0,16,10,50,0,57,59,122,0,48,46,18,118,0,59,119,0,18,109,0,16,10,50,0,57, +59,119,0,48,46,0,18,118,0,59,120,0,18,109,0,16,10,51,0,57,59,120,0,48,18,118,0,59,121,0,18,109,0,16, +10,51,0,57,59,121,0,48,46,18,118,0,59,122,0,18,109,0,16,10,51,0,57,59,122,0,48,46,18,118,0,59,119,0, +18,109,0,16,10,51,0,57,59,119,0,48,46,0,0,0,0,1,0,0,2,4,1,0,2,12,118,0,0,1,1,0,15,109,0,0,0,1,9,18, +118,0,18,118,0,18,109,0,48,20,0,0,1,0,9,2,30,1,1,0,9,97,0,0,1,1,0,9,98,0,0,0,1,8,18,97,0,18,98,0,54, +46,0,0,1,0,5,2,29,1,1,0,5,97,0,0,1,1,0,5,98,0,0,0,1,3,2,0,5,1,99,0,0,0,9,18,99,0,18,97,0,20,0,8,18, +99,0,18,98,0,21,0,0,1,0,5,2,30,1,1,0,5,97,0,0,1,1,0,5,98,0,0,0,1,8,18,97,0,18,98,0,54,46,0,0,1,0,5, +2,24,1,1,0,5,97,0,0,1,1,0,5,98,0,0,0,1,3,2,0,5,1,99,0,0,0,8,18,99,0,18,97,0,20,18,98,0,23,0,0,1,0,5, +2,25,1,1,0,5,97,0,0,1,1,0,5,98,0,0,0,1,3,2,0,5,1,99,0,0,0,8,18,99,0,18,97,0,20,18,98,0,24,0,0,1,0, +10,2,29,1,1,0,10,118,0,0,1,1,0,10,117,0,0,0,1,8,58,118,101,99,50,0,18,118,0,59,120,0,18,117,0,59, +120,0,46,0,18,118,0,59,121,0,18,117,0,59,121,0,46,0,0,0,0,1,0,10,2,30,1,1,0,10,118,0,0,1,1,0,10,117, +0,0,0,1,8,58,118,101,99,50,0,18,118,0,59,120,0,18,117,0,59,120,0,47,0,18,118,0,59,121,0,18,117,0,59, +121,0,47,0,0,0,0,1,0,11,2,29,1,1,0,11,118,0,0,1,1,0,11,117,0,0,0,1,8,58,118,101,99,51,0,18,118,0,59, +120,0,18,117,0,59,120,0,46,0,18,118,0,59,121,0,18,117,0,59,121,0,46,0,18,118,0,59,122,0,18,117,0,59, +122,0,46,0,0,0,0,1,0,11,2,30,1,1,0,11,118,0,0,1,1,0,11,117,0,0,0,1,8,58,118,101,99,51,0,18,118,0,59, +120,0,18,117,0,59,120,0,47,0,18,118,0,59,121,0,18,117,0,59,121,0,47,0,18,118,0,59,122,0,18,117,0,59, +122,0,47,0,0,0,0,1,0,12,2,29,1,1,0,12,118,0,0,1,1,0,12,117,0,0,0,1,8,58,118,101,99,52,0,18,118,0,59, +120,0,18,117,0,59,120,0,46,0,18,118,0,59,121,0,18,117,0,59,121,0,46,0,18,118,0,59,122,0,18,117,0,59, +122,0,46,0,18,118,0,59,119,0,18,117,0,59,119,0,46,0,0,0,0,1,0,12,2,30,1,1,0,12,118,0,0,1,1,0,12,117, +0,0,0,1,8,58,118,101,99,52,0,18,118,0,59,120,0,18,117,0,59,120,0,47,0,18,118,0,59,121,0,18,117,0,59, +121,0,47,0,18,118,0,59,122,0,18,117,0,59,122,0,47,0,18,118,0,59,119,0,18,117,0,59,119,0,47,0,0,0,0, +1,0,6,2,29,1,1,0,6,118,0,0,1,1,0,6,117,0,0,0,1,8,58,105,118,101,99,50,0,18,118,0,59,120,0,18,117,0, +59,120,0,46,0,18,118,0,59,121,0,18,117,0,59,121,0,46,0,0,0,0,1,0,6,2,30,1,1,0,6,118,0,0,1,1,0,6,117, +0,0,0,1,8,58,105,118,101,99,50,0,18,118,0,59,120,0,18,117,0,59,120,0,47,0,18,118,0,59,121,0,18,117, +0,59,121,0,47,0,0,0,0,1,0,7,2,29,1,1,0,7,118,0,0,1,1,0,7,117,0,0,0,1,8,58,105,118,101,99,51,0,18, +118,0,59,120,0,18,117,0,59,120,0,46,0,18,118,0,59,121,0,18,117,0,59,121,0,46,0,18,118,0,59,122,0,18, +117,0,59,122,0,46,0,0,0,0,1,0,7,2,30,1,1,0,7,118,0,0,1,1,0,7,117,0,0,0,1,8,58,105,118,101,99,51,0, +18,118,0,59,120,0,18,117,0,59,120,0,47,0,18,118,0,59,121,0,18,117,0,59,121,0,47,0,18,118,0,59,122,0, +18,117,0,59,122,0,47,0,0,0,0,1,0,8,2,29,1,1,0,8,118,0,0,1,1,0,8,117,0,0,0,1,8,58,105,118,101,99,52, +0,18,118,0,59,120,0,18,117,0,59,120,0,46,0,18,118,0,59,121,0,18,117,0,59,121,0,46,0,18,118,0,59,122, +0,18,117,0,59,122,0,46,0,18,118,0,59,119,0,18,117,0,59,119,0,46,0,0,0,0,1,0,8,2,30,1,1,0,8,118,0,0, +1,1,0,8,117,0,0,0,1,8,58,105,118,101,99,52,0,18,118,0,59,120,0,18,117,0,59,120,0,47,0,18,118,0,59, +121,0,18,117,0,59,121,0,47,0,18,118,0,59,122,0,18,117,0,59,122,0,47,0,18,118,0,59,119,0,18,117,0,59, +119,0,47,0,0,0,0,1,0,13,2,29,1,1,0,13,109,0,0,1,1,0,13,110,0,0,0,1,8,58,109,97,116,50,0,18,109,0,16, +8,48,0,57,18,110,0,16,8,48,0,57,46,0,18,109,0,16,10,49,0,57,18,110,0,16,10,49,0,57,46,0,0,0,0,1,0, +13,2,30,1,1,0,13,109,0,0,1,1,0,13,110,0,0,0,1,8,58,109,97,116,50,0,18,109,0,16,8,48,0,57,18,110,0, +16,8,48,0,57,47,0,18,109,0,16,10,49,0,57,18,110,0,16,10,49,0,57,47,0,0,0,0,1,0,14,2,29,1,1,0,14,109, +0,0,1,1,0,14,110,0,0,0,1,8,58,109,97,116,51,0,18,109,0,16,8,48,0,57,18,110,0,16,8,48,0,57,46,0,18, +109,0,16,10,49,0,57,18,110,0,16,10,49,0,57,46,0,18,109,0,16,10,50,0,57,18,110,0,16,10,50,0,57,46,0, +0,0,0,1,0,14,2,30,1,1,0,14,109,0,0,1,1,0,14,110,0,0,0,1,8,58,109,97,116,51,0,18,109,0,16,8,48,0,57, +18,110,0,16,8,48,0,57,47,0,18,109,0,16,10,49,0,57,18,110,0,16,10,49,0,57,47,0,18,109,0,16,10,50,0, +57,18,110,0,16,10,50,0,57,47,0,0,0,0,1,0,15,2,29,1,1,0,15,109,0,0,1,1,0,15,110,0,0,0,1,8,58,109,97, +116,52,0,18,109,0,16,8,48,0,57,18,110,0,16,8,48,0,57,46,0,18,109,0,16,10,49,0,57,18,110,0,16,10,49, +0,57,46,0,18,109,0,16,10,50,0,57,18,110,0,16,10,50,0,57,46,0,18,109,0,16,10,51,0,57,18,110,0,16,10, +51,0,57,46,0,0,0,0,1,0,15,2,30,1,1,0,15,109,0,0,1,1,0,15,110,0,0,0,1,8,58,109,97,116,52,0,18,109,0, +16,8,48,0,57,18,110,0,16,8,48,0,57,47,0,18,109,0,16,10,49,0,57,18,110,0,16,10,49,0,57,47,0,18,109,0, +16,10,50,0,57,18,110,0,16,10,50,0,57,47,0,18,109,0,16,10,51,0,57,18,110,0,16,10,51,0,57,47,0,0,0,0, +1,0,10,2,29,1,1,0,9,97,0,0,1,1,0,10,117,0,0,0,1,8,58,118,101,99,50,0,18,97,0,18,117,0,59,120,0,46,0, +18,97,0,18,117,0,59,121,0,46,0,0,0,0,1,0,10,2,29,1,1,0,10,118,0,0,1,1,0,9,98,0,0,0,1,8,58,118,101, +99,50,0,18,118,0,59,120,0,18,98,0,46,0,18,118,0,59,121,0,18,98,0,46,0,0,0,0,1,0,10,2,30,1,1,0,9,97, +0,0,1,1,0,10,117,0,0,0,1,8,58,118,101,99,50,0,18,97,0,18,117,0,59,120,0,47,0,18,97,0,18,117,0,59, +121,0,47,0,0,0,0,1,0,10,2,30,1,1,0,10,118,0,0,1,1,0,9,98,0,0,0,1,8,58,118,101,99,50,0,18,118,0,59, +120,0,18,98,0,47,0,18,118,0,59,121,0,18,98,0,47,0,0,0,0,1,0,10,2,24,1,1,0,9,97,0,0,1,1,0,10,117,0,0, +0,1,8,58,118,101,99,50,0,18,97,0,18,117,0,59,120,0,48,0,18,97,0,18,117,0,59,121,0,48,0,0,0,0,1,0,10, +2,24,1,1,0,10,118,0,0,1,1,0,9,98,0,0,0,1,8,58,118,101,99,50,0,18,118,0,59,120,0,18,98,0,48,0,18,118, +0,59,121,0,18,98,0,48,0,0,0,0,1,0,10,2,25,1,1,0,9,97,0,0,1,1,0,10,117,0,0,0,1,8,58,118,101,99,50,0, +18,97,0,18,117,0,59,120,0,49,0,18,97,0,18,117,0,59,121,0,49,0,0,0,0,1,0,10,2,25,1,1,0,10,118,0,0,1, +1,0,9,98,0,0,0,1,8,58,118,101,99,50,0,18,118,0,59,120,0,18,98,0,49,0,18,118,0,59,121,0,18,98,0,49,0, +0,0,0,1,0,11,2,29,1,1,0,9,97,0,0,1,1,0,11,117,0,0,0,1,8,58,118,101,99,51,0,18,97,0,18,117,0,59,120, +0,46,0,18,97,0,18,117,0,59,121,0,46,0,18,97,0,18,117,0,59,122,0,46,0,0,0,0,1,0,11,2,29,1,1,0,11,118, +0,0,1,1,0,9,98,0,0,0,1,8,58,118,101,99,51,0,18,118,0,59,120,0,18,98,0,46,0,18,118,0,59,121,0,18,98, +0,46,0,18,118,0,59,122,0,18,98,0,46,0,0,0,0,1,0,11,2,30,1,1,0,9,97,0,0,1,1,0,11,117,0,0,0,1,8,58, +118,101,99,51,0,18,97,0,18,117,0,59,120,0,47,0,18,97,0,18,117,0,59,121,0,47,0,18,97,0,18,117,0,59, +122,0,47,0,0,0,0,1,0,11,2,30,1,1,0,11,118,0,0,1,1,0,9,98,0,0,0,1,8,58,118,101,99,51,0,18,118,0,59, +120,0,18,98,0,47,0,18,118,0,59,121,0,18,98,0,47,0,18,118,0,59,122,0,18,98,0,47,0,0,0,0,1,0,11,2,24, +1,1,0,9,97,0,0,1,1,0,11,117,0,0,0,1,8,58,118,101,99,51,0,18,97,0,18,117,0,59,120,0,48,0,18,97,0,18, +117,0,59,121,0,48,0,18,97,0,18,117,0,59,122,0,48,0,0,0,0,1,0,11,2,24,1,1,0,11,118,0,0,1,1,0,9,98,0, +0,0,1,8,58,118,101,99,51,0,18,118,0,59,120,0,18,98,0,48,0,18,118,0,59,121,0,18,98,0,48,0,18,118,0, +59,122,0,18,98,0,48,0,0,0,0,1,0,11,2,25,1,1,0,9,97,0,0,1,1,0,11,117,0,0,0,1,8,58,118,101,99,51,0,18, +97,0,18,117,0,59,120,0,49,0,18,97,0,18,117,0,59,121,0,49,0,18,97,0,18,117,0,59,122,0,49,0,0,0,0,1,0, +11,2,25,1,1,0,11,118,0,0,1,1,0,9,98,0,0,0,1,8,58,118,101,99,51,0,18,118,0,59,120,0,18,98,0,49,0,18, +118,0,59,121,0,18,98,0,49,0,18,118,0,59,122,0,18,98,0,49,0,0,0,0,1,0,12,2,29,1,1,0,9,97,0,0,1,1,0, +12,117,0,0,0,1,8,58,118,101,99,52,0,18,97,0,18,117,0,59,120,0,46,0,18,97,0,18,117,0,59,121,0,46,0, +18,97,0,18,117,0,59,122,0,46,0,18,97,0,18,117,0,59,119,0,46,0,0,0,0,1,0,12,2,29,1,1,0,12,118,0,0,1, +1,0,9,98,0,0,0,1,8,58,118,101,99,52,0,18,118,0,59,120,0,18,98,0,46,0,18,118,0,59,121,0,18,98,0,46,0, +18,118,0,59,122,0,18,98,0,46,0,18,118,0,59,119,0,18,98,0,46,0,0,0,0,1,0,12,2,30,1,1,0,9,97,0,0,1,1, +0,12,117,0,0,0,1,8,58,118,101,99,52,0,18,97,0,18,117,0,59,120,0,47,0,18,97,0,18,117,0,59,121,0,47,0, +18,97,0,18,117,0,59,122,0,47,0,18,97,0,18,117,0,59,119,0,47,0,0,0,0,1,0,12,2,30,1,1,0,12,118,0,0,1, +1,0,9,98,0,0,0,1,8,58,118,101,99,52,0,18,118,0,59,120,0,18,98,0,47,0,18,118,0,59,121,0,18,98,0,47,0, +18,118,0,59,122,0,18,98,0,47,0,18,118,0,59,119,0,18,98,0,47,0,0,0,0,1,0,12,2,24,1,1,0,9,97,0,0,1,1, +0,12,117,0,0,0,1,8,58,118,101,99,52,0,18,97,0,18,117,0,59,120,0,48,0,18,97,0,18,117,0,59,121,0,48,0, +18,97,0,18,117,0,59,122,0,48,0,18,97,0,18,117,0,59,119,0,48,0,0,0,0,1,0,12,2,24,1,1,0,12,118,0,0,1, +1,0,9,98,0,0,0,1,8,58,118,101,99,52,0,18,118,0,59,120,0,18,98,0,48,0,18,118,0,59,121,0,18,98,0,48,0, +18,118,0,59,122,0,18,98,0,48,0,18,118,0,59,119,0,18,98,0,48,0,0,0,0,1,0,12,2,25,1,1,0,9,97,0,0,1,1, +0,12,117,0,0,0,1,8,58,118,101,99,52,0,18,97,0,18,117,0,59,120,0,49,0,18,97,0,18,117,0,59,121,0,49,0, +18,97,0,18,117,0,59,122,0,49,0,18,97,0,18,117,0,59,119,0,49,0,0,0,0,1,0,12,2,25,1,1,0,12,118,0,0,1, +1,0,9,98,0,0,0,1,8,58,118,101,99,52,0,18,118,0,59,120,0,18,98,0,49,0,18,118,0,59,121,0,18,98,0,49,0, +18,118,0,59,122,0,18,98,0,49,0,18,118,0,59,119,0,18,98,0,49,0,0,0,0,1,0,13,2,29,1,1,0,9,97,0,0,1,1, +0,13,110,0,0,0,1,8,58,109,97,116,50,0,18,97,0,18,110,0,16,8,48,0,57,46,0,18,97,0,18,110,0,16,10,49, +0,57,46,0,0,0,0,1,0,13,2,29,1,1,0,13,109,0,0,1,1,0,9,98,0,0,0,1,8,58,109,97,116,50,0,18,109,0,16,8, +48,0,57,18,98,0,46,0,18,109,0,16,10,49,0,57,18,98,0,46,0,0,0,0,1,0,13,2,30,1,1,0,9,97,0,0,1,1,0,13, +110,0,0,0,1,8,58,109,97,116,50,0,18,97,0,18,110,0,16,8,48,0,57,47,0,18,97,0,18,110,0,16,10,49,0,57, +47,0,0,0,0,1,0,13,2,30,1,1,0,13,109,0,0,1,1,0,9,98,0,0,0,1,8,58,109,97,116,50,0,18,109,0,16,8,48,0, +57,18,98,0,47,0,18,109,0,16,10,49,0,57,18,98,0,47,0,0,0,0,1,0,13,2,24,1,1,0,9,97,0,0,1,1,0,13,110,0, +0,0,1,8,58,109,97,116,50,0,18,97,0,18,110,0,16,8,48,0,57,48,0,18,97,0,18,110,0,16,10,49,0,57,48,0,0, +0,0,1,0,13,2,24,1,1,0,13,109,0,0,1,1,0,9,98,0,0,0,1,8,58,109,97,116,50,0,18,109,0,16,8,48,0,57,18, +98,0,48,0,18,109,0,16,10,49,0,57,18,98,0,48,0,0,0,0,1,0,13,2,25,1,1,0,9,97,0,0,1,1,0,13,110,0,0,0,1, +8,58,109,97,116,50,0,18,97,0,18,110,0,16,8,48,0,57,49,0,18,97,0,18,110,0,16,10,49,0,57,49,0,0,0,0,1, +0,13,2,25,1,1,0,13,109,0,0,1,1,0,9,98,0,0,0,1,8,58,109,97,116,50,0,18,109,0,16,8,48,0,57,18,98,0,49, +0,18,109,0,16,10,49,0,57,18,98,0,49,0,0,0,0,1,0,14,2,29,1,1,0,9,97,0,0,1,1,0,14,110,0,0,0,1,8,58, +109,97,116,51,0,18,97,0,18,110,0,16,8,48,0,57,46,0,18,97,0,18,110,0,16,10,49,0,57,46,0,18,97,0,18, +110,0,16,10,50,0,57,46,0,0,0,0,1,0,14,2,29,1,1,0,14,109,0,0,1,1,0,9,98,0,0,0,1,8,58,109,97,116,51,0, +18,109,0,16,8,48,0,57,18,98,0,46,0,18,109,0,16,10,49,0,57,18,98,0,46,0,18,109,0,16,10,50,0,57,18,98, +0,46,0,0,0,0,1,0,14,2,30,1,1,0,9,97,0,0,1,1,0,14,110,0,0,0,1,8,58,109,97,116,51,0,18,97,0,18,110,0, +16,8,48,0,57,47,0,18,97,0,18,110,0,16,10,49,0,57,47,0,18,97,0,18,110,0,16,10,50,0,57,47,0,0,0,0,1,0, +14,2,30,1,1,0,14,109,0,0,1,1,0,9,98,0,0,0,1,8,58,109,97,116,51,0,18,109,0,16,8,48,0,57,18,98,0,47,0, +18,109,0,16,10,49,0,57,18,98,0,47,0,18,109,0,16,10,50,0,57,18,98,0,47,0,0,0,0,1,0,14,2,24,1,1,0,9, +97,0,0,1,1,0,14,110,0,0,0,1,8,58,109,97,116,51,0,18,97,0,18,110,0,16,8,48,0,57,48,0,18,97,0,18,110, +0,16,10,49,0,57,48,0,18,97,0,18,110,0,16,10,50,0,57,48,0,0,0,0,1,0,14,2,24,1,1,0,14,109,0,0,1,1,0,9, +98,0,0,0,1,8,58,109,97,116,51,0,18,109,0,16,8,48,0,57,18,98,0,48,0,18,109,0,16,10,49,0,57,18,98,0, +48,0,18,109,0,16,10,50,0,57,18,98,0,48,0,0,0,0,1,0,14,2,25,1,1,0,9,97,0,0,1,1,0,14,110,0,0,0,1,8,58, +109,97,116,51,0,18,97,0,18,110,0,16,8,48,0,57,49,0,18,97,0,18,110,0,16,10,49,0,57,49,0,18,97,0,18, +110,0,16,10,50,0,57,49,0,0,0,0,1,0,14,2,25,1,1,0,14,109,0,0,1,1,0,9,98,0,0,0,1,8,58,109,97,116,51,0, +18,109,0,16,8,48,0,57,18,98,0,49,0,18,109,0,16,10,49,0,57,18,98,0,49,0,18,109,0,16,10,50,0,57,18,98, +0,49,0,0,0,0,1,0,15,2,29,1,1,0,9,97,0,0,1,1,0,15,110,0,0,0,1,8,58,109,97,116,52,0,18,97,0,18,110,0, +16,8,48,0,57,46,0,18,97,0,18,110,0,16,10,49,0,57,46,0,18,97,0,18,110,0,16,10,50,0,57,46,0,18,97,0, +18,110,0,16,10,51,0,57,46,0,0,0,0,1,0,15,2,29,1,1,0,15,109,0,0,1,1,0,9,98,0,0,0,1,8,58,109,97,116, +52,0,18,109,0,16,8,48,0,57,18,98,0,46,0,18,109,0,16,10,49,0,57,18,98,0,46,0,18,109,0,16,10,50,0,57, +18,98,0,46,0,18,109,0,16,10,51,0,57,18,98,0,46,0,0,0,0,1,0,15,2,30,1,1,0,9,97,0,0,1,1,0,15,110,0,0, +0,1,8,58,109,97,116,52,0,18,97,0,18,110,0,16,8,48,0,57,47,0,18,97,0,18,110,0,16,10,49,0,57,47,0,18, +97,0,18,110,0,16,10,50,0,57,47,0,18,97,0,18,110,0,16,10,51,0,57,47,0,0,0,0,1,0,15,2,30,1,1,0,15,109, +0,0,1,1,0,9,98,0,0,0,1,8,58,109,97,116,52,0,18,109,0,16,8,48,0,57,18,98,0,47,0,18,109,0,16,10,49,0, +57,18,98,0,47,0,18,109,0,16,10,50,0,57,18,98,0,47,0,18,109,0,16,10,51,0,57,18,98,0,47,0,0,0,0,1,0, +15,2,24,1,1,0,9,97,0,0,1,1,0,15,110,0,0,0,1,8,58,109,97,116,52,0,18,97,0,18,110,0,16,8,48,0,57,48,0, +18,97,0,18,110,0,16,10,49,0,57,48,0,18,97,0,18,110,0,16,10,50,0,57,48,0,18,97,0,18,110,0,16,10,51,0, +57,48,0,0,0,0,1,0,15,2,24,1,1,0,15,109,0,0,1,1,0,9,98,0,0,0,1,8,58,109,97,116,52,0,18,109,0,16,8,48, +0,57,18,98,0,48,0,18,109,0,16,10,49,0,57,18,98,0,48,0,18,109,0,16,10,50,0,57,18,98,0,48,0,18,109,0, +16,10,51,0,57,18,98,0,48,0,0,0,0,1,0,15,2,25,1,1,0,9,97,0,0,1,1,0,15,110,0,0,0,1,8,58,109,97,116,52, +0,18,97,0,18,110,0,16,8,48,0,57,49,0,18,97,0,18,110,0,16,10,49,0,57,49,0,18,97,0,18,110,0,16,10,50, +0,57,49,0,18,97,0,18,110,0,16,10,51,0,57,49,0,0,0,0,1,0,15,2,25,1,1,0,15,109,0,0,1,1,0,9,98,0,0,0,1, +8,58,109,97,116,52,0,18,109,0,16,8,48,0,57,18,98,0,49,0,18,109,0,16,10,49,0,57,18,98,0,49,0,18,109, +0,16,10,50,0,57,18,98,0,49,0,18,109,0,16,10,51,0,57,18,98,0,49,0,0,0,0,1,0,6,2,29,1,1,0,5,97,0,0,1, +1,0,6,117,0,0,0,1,8,58,105,118,101,99,50,0,18,97,0,18,117,0,59,120,0,46,0,18,97,0,18,117,0,59,121,0, +46,0,0,0,0,1,0,6,2,29,1,1,0,6,118,0,0,1,1,0,5,98,0,0,0,1,8,58,105,118,101,99,50,0,18,118,0,59,120,0, +18,98,0,46,0,18,118,0,59,121,0,18,98,0,46,0,0,0,0,1,0,6,2,30,1,1,0,5,97,0,0,1,1,0,6,117,0,0,0,1,8, +58,105,118,101,99,50,0,18,97,0,18,117,0,59,120,0,47,0,18,97,0,18,117,0,59,121,0,47,0,0,0,0,1,0,6,2, +30,1,1,0,6,118,0,0,1,1,0,5,98,0,0,0,1,8,58,105,118,101,99,50,0,18,118,0,59,120,0,18,98,0,47,0,18, +118,0,59,121,0,18,98,0,47,0,0,0,0,1,0,6,2,24,1,1,0,5,97,0,0,1,1,0,6,117,0,0,0,1,8,58,105,118,101,99, +50,0,18,97,0,18,117,0,59,120,0,48,0,18,97,0,18,117,0,59,121,0,48,0,0,0,0,1,0,6,2,24,1,1,0,6,118,0,0, +1,1,0,5,98,0,0,0,1,8,58,105,118,101,99,50,0,18,118,0,59,120,0,18,98,0,48,0,18,118,0,59,121,0,18,98, +0,48,0,0,0,0,1,0,6,2,25,1,1,0,5,97,0,0,1,1,0,6,117,0,0,0,1,8,58,105,118,101,99,50,0,18,97,0,18,117, +0,59,120,0,49,0,18,97,0,18,117,0,59,121,0,49,0,0,0,0,1,0,6,2,25,1,1,0,6,118,0,0,1,1,0,5,98,0,0,0,1, +8,58,105,118,101,99,50,0,18,118,0,59,120,0,18,98,0,49,0,18,118,0,59,121,0,18,98,0,49,0,0,0,0,1,0,7, +2,29,1,1,0,5,97,0,0,1,1,0,7,117,0,0,0,1,8,58,105,118,101,99,51,0,18,97,0,18,117,0,59,120,0,46,0,18, +97,0,18,117,0,59,121,0,46,0,18,97,0,18,117,0,59,122,0,46,0,0,0,0,1,0,7,2,29,1,1,0,7,118,0,0,1,1,0,5, +98,0,0,0,1,8,58,105,118,101,99,51,0,18,118,0,59,120,0,18,98,0,46,0,18,118,0,59,121,0,18,98,0,46,0, +18,118,0,59,122,0,18,98,0,46,0,0,0,0,1,0,7,2,30,1,1,0,5,97,0,0,1,1,0,7,117,0,0,0,1,8,58,105,118,101, +99,51,0,18,97,0,18,117,0,59,120,0,47,0,18,97,0,18,117,0,59,121,0,47,0,18,97,0,18,117,0,59,122,0,47, +0,0,0,0,1,0,7,2,30,1,1,0,7,118,0,0,1,1,0,5,98,0,0,0,1,8,58,105,118,101,99,51,0,18,118,0,59,120,0,18, +98,0,47,0,18,118,0,59,121,0,18,98,0,47,0,18,118,0,59,122,0,18,98,0,47,0,0,0,0,1,0,7,2,24,1,1,0,5,97, +0,0,1,1,0,7,117,0,0,0,1,8,58,105,118,101,99,51,0,18,97,0,18,117,0,59,120,0,48,0,18,97,0,18,117,0,59, +121,0,48,0,18,97,0,18,117,0,59,122,0,48,0,0,0,0,1,0,7,2,24,1,1,0,7,118,0,0,1,1,0,5,98,0,0,0,1,8,58, +105,118,101,99,51,0,18,118,0,59,120,0,18,98,0,48,0,18,118,0,59,121,0,18,98,0,48,0,18,118,0,59,122,0, +18,98,0,48,0,0,0,0,1,0,7,2,25,1,1,0,5,97,0,0,1,1,0,7,117,0,0,0,1,8,58,105,118,101,99,51,0,18,97,0, +18,117,0,59,120,0,49,0,18,97,0,18,117,0,59,121,0,49,0,18,97,0,18,117,0,59,122,0,49,0,0,0,0,1,0,7,2, +25,1,1,0,7,118,0,0,1,1,0,5,98,0,0,0,1,8,58,105,118,101,99,51,0,18,118,0,59,120,0,18,98,0,49,0,18, +118,0,59,121,0,18,98,0,49,0,18,118,0,59,122,0,18,98,0,49,0,0,0,0,1,0,8,2,29,1,1,0,5,97,0,0,1,1,0,8, +117,0,0,0,1,8,58,105,118,101,99,52,0,18,97,0,18,117,0,59,120,0,46,0,18,97,0,18,117,0,59,121,0,46,0, +18,97,0,18,117,0,59,122,0,46,0,18,97,0,18,117,0,59,119,0,46,0,0,0,0,1,0,8,2,29,1,1,0,8,118,0,0,1,1, +0,5,98,0,0,0,1,8,58,105,118,101,99,52,0,18,118,0,59,120,0,18,98,0,46,0,18,118,0,59,121,0,18,98,0,46, +0,18,118,0,59,122,0,18,98,0,46,0,18,118,0,59,119,0,18,98,0,46,0,0,0,0,1,0,8,2,30,1,1,0,5,97,0,0,1,1, +0,8,117,0,0,0,1,8,58,105,118,101,99,52,0,18,97,0,18,117,0,59,120,0,47,0,18,97,0,18,117,0,59,121,0, +47,0,18,97,0,18,117,0,59,122,0,47,0,18,97,0,18,117,0,59,119,0,47,0,0,0,0,1,0,8,2,30,1,1,0,8,118,0,0, +1,1,0,5,98,0,0,0,1,8,58,105,118,101,99,52,0,18,118,0,59,120,0,18,98,0,47,0,18,118,0,59,121,0,18,98, +0,47,0,18,118,0,59,122,0,18,98,0,47,0,18,118,0,59,119,0,18,98,0,47,0,0,0,0,1,0,8,2,24,1,1,0,5,97,0, +0,1,1,0,8,117,0,0,0,1,8,58,105,118,101,99,52,0,18,97,0,18,117,0,59,120,0,48,0,18,97,0,18,117,0,59, +121,0,48,0,18,97,0,18,117,0,59,122,0,48,0,18,97,0,18,117,0,59,119,0,48,0,0,0,0,1,0,8,2,24,1,1,0,8, +118,0,0,1,1,0,5,98,0,0,0,1,8,58,105,118,101,99,52,0,18,118,0,59,120,0,18,98,0,48,0,18,118,0,59,121, +0,18,98,0,48,0,18,118,0,59,122,0,18,98,0,48,0,18,118,0,59,119,0,18,98,0,48,0,0,0,0,1,0,8,2,25,1,1,0, +5,97,0,0,1,1,0,8,117,0,0,0,1,8,58,105,118,101,99,52,0,18,97,0,18,117,0,59,120,0,49,0,18,97,0,18,117, +0,59,121,0,49,0,18,97,0,18,117,0,59,122,0,49,0,18,97,0,18,117,0,59,119,0,49,0,0,0,0,1,0,8,2,25,1,1, +0,8,118,0,0,1,1,0,5,98,0,0,0,1,8,58,105,118,101,99,52,0,18,118,0,59,120,0,18,98,0,49,0,18,118,0,59, +121,0,18,98,0,49,0,18,118,0,59,122,0,18,98,0,49,0,18,118,0,59,119,0,18,98,0,49,0,0,0,0,1,0,10,2,24, +1,1,0,10,118,0,0,1,1,0,10,117,0,0,0,1,8,58,118,101,99,50,0,18,118,0,59,120,0,18,117,0,59,120,0,48,0, +18,118,0,59,121,0,18,117,0,59,121,0,48,0,0,0,0,1,0,11,2,24,1,1,0,11,118,0,0,1,1,0,11,117,0,0,0,1,8, +58,118,101,99,51,0,18,118,0,59,120,0,18,117,0,59,120,0,48,0,18,118,0,59,121,0,18,117,0,59,121,0,48, +0,18,118,0,59,122,0,18,117,0,59,122,0,48,0,0,0,0,1,0,12,2,24,1,1,0,12,118,0,0,1,1,0,12,117,0,0,0,1, +8,58,118,101,99,52,0,18,118,0,59,120,0,18,117,0,59,120,0,48,0,18,118,0,59,121,0,18,117,0,59,121,0, +48,0,18,118,0,59,122,0,18,117,0,59,122,0,48,0,18,118,0,59,119,0,18,117,0,59,119,0,48,0,0,0,0,1,0,6, +2,24,1,1,0,6,118,0,0,1,1,0,6,117,0,0,0,1,8,58,105,118,101,99,50,0,18,118,0,59,120,0,18,117,0,59,120, +0,48,0,18,118,0,59,121,0,18,117,0,59,121,0,48,0,0,0,0,1,0,7,2,24,1,1,0,7,118,0,0,1,1,0,7,117,0,0,0, +1,8,58,105,118,101,99,51,0,18,118,0,59,120,0,18,117,0,59,120,0,48,0,18,118,0,59,121,0,18,117,0,59, +121,0,48,0,18,118,0,59,122,0,18,117,0,59,122,0,48,0,0,0,0,1,0,8,2,24,1,1,0,8,118,0,0,1,1,0,8,117,0, +0,0,1,8,58,105,118,101,99,52,0,18,118,0,59,120,0,18,117,0,59,120,0,48,0,18,118,0,59,121,0,18,117,0, +59,121,0,48,0,18,118,0,59,122,0,18,117,0,59,122,0,48,0,18,118,0,59,119,0,18,117,0,59,119,0,48,0,0,0, +0,1,0,10,2,25,1,1,0,10,118,0,0,1,1,0,10,117,0,0,0,1,8,58,118,101,99,50,0,18,118,0,59,120,0,18,117,0, +59,120,0,49,0,18,118,0,59,121,0,18,117,0,59,121,0,49,0,0,0,0,1,0,11,2,25,1,1,0,11,118,0,0,1,1,0,11, +117,0,0,0,1,8,58,118,101,99,51,0,18,118,0,59,120,0,18,117,0,59,120,0,49,0,18,118,0,59,121,0,18,117, +0,59,121,0,49,0,18,118,0,59,122,0,18,117,0,59,122,0,49,0,0,0,0,1,0,12,2,25,1,1,0,12,118,0,0,1,1,0, +12,117,0,0,0,1,8,58,118,101,99,52,0,18,118,0,59,120,0,18,117,0,59,120,0,49,0,18,118,0,59,121,0,18, +117,0,59,121,0,49,0,18,118,0,59,122,0,18,117,0,59,122,0,49,0,18,118,0,59,119,0,18,117,0,59,119,0,49, +0,0,0,0,1,0,6,2,25,1,1,0,6,118,0,0,1,1,0,6,117,0,0,0,1,8,58,105,118,101,99,50,0,18,118,0,59,120,0, +18,117,0,59,120,0,49,0,18,118,0,59,121,0,18,117,0,59,121,0,49,0,0,0,0,1,0,7,2,25,1,1,0,7,118,0,0,1, +1,0,7,117,0,0,0,1,8,58,105,118,101,99,51,0,18,118,0,59,120,0,18,117,0,59,120,0,49,0,18,118,0,59,121, +0,18,117,0,59,121,0,49,0,18,118,0,59,122,0,18,117,0,59,122,0,49,0,0,0,0,1,0,8,2,25,1,1,0,8,118,0,0, +1,1,0,8,117,0,0,0,1,8,58,105,118,101,99,52,0,18,118,0,59,120,0,18,117,0,59,120,0,49,0,18,118,0,59, +121,0,18,117,0,59,121,0,49,0,18,118,0,59,122,0,18,117,0,59,122,0,49,0,18,118,0,59,119,0,18,117,0,59, +119,0,49,0,0,0,0,1,0,13,2,25,1,1,0,13,109,0,0,1,1,0,13,110,0,0,0,1,8,58,109,97,116,50,0,18,109,0,16, +8,48,0,57,18,110,0,16,8,48,0,57,49,0,18,109,0,16,10,49,0,57,18,110,0,16,10,49,0,57,49,0,0,0,0,1,0, +14,2,25,1,1,0,14,109,0,0,1,1,0,14,110,0,0,0,1,8,58,109,97,116,51,0,18,109,0,16,8,48,0,57,18,110,0, +16,8,48,0,57,49,0,18,109,0,16,10,49,0,57,18,110,0,16,10,49,0,57,49,0,18,109,0,16,10,50,0,57,18,110, +0,16,10,50,0,57,49,0,0,0,0,1,0,15,2,25,1,1,0,15,109,0,0,1,1,0,15,110,0,0,0,1,8,58,109,97,116,52,0, +18,109,0,16,8,48,0,57,18,110,0,16,8,48,0,57,49,0,18,109,0,16,10,49,0,57,18,110,0,16,10,49,0,57,49,0, +18,109,0,16,10,50,0,57,18,110,0,16,10,50,0,57,49,0,18,109,0,16,10,51,0,57,18,110,0,16,10,51,0,57,49, +0,0,0,0,1,0,10,2,30,1,1,0,10,118,0,0,0,1,8,58,118,101,99,50,0,18,118,0,59,120,0,54,0,18,118,0,59, +121,0,54,0,0,0,0,1,0,11,2,30,1,1,0,11,118,0,0,0,1,8,58,118,101,99,51,0,18,118,0,59,120,0,54,0,18, +118,0,59,121,0,54,0,18,118,0,59,122,0,54,0,0,0,0,1,0,12,2,30,1,1,0,12,118,0,0,0,1,8,58,118,101,99, +52,0,18,118,0,59,120,0,54,0,18,118,0,59,121,0,54,0,18,118,0,59,122,0,54,0,18,118,0,59,119,0,54,0,0, +0,0,1,0,6,2,30,1,1,0,6,118,0,0,0,1,8,58,105,118,101,99,50,0,18,118,0,59,120,0,54,0,18,118,0,59,121, +0,54,0,0,0,0,1,0,7,2,30,1,1,0,7,118,0,0,0,1,8,58,105,118,101,99,51,0,18,118,0,59,120,0,54,0,18,118, +0,59,121,0,54,0,18,118,0,59,122,0,54,0,0,0,0,1,0,8,2,30,1,1,0,8,118,0,0,0,1,8,58,105,118,101,99,52, +0,18,118,0,59,120,0,54,0,18,118,0,59,121,0,54,0,18,118,0,59,122,0,54,0,18,118,0,59,119,0,54,0,0,0,0, +1,0,13,2,30,1,1,0,13,109,0,0,0,1,8,58,109,97,116,50,0,18,109,0,16,8,48,0,57,54,0,18,109,0,16,10,49, +0,57,54,0,0,0,0,1,0,14,2,30,1,1,0,14,109,0,0,0,1,8,58,109,97,116,51,0,18,109,0,16,8,48,0,57,54,0,18, +109,0,16,10,49,0,57,54,0,18,109,0,16,10,50,0,57,54,0,0,0,0,1,0,15,2,30,1,1,0,15,109,0,0,0,1,8,58, +109,97,116,52,0,18,109,0,16,8,48,0,57,54,0,18,109,0,16,10,49,0,57,54,0,18,109,0,16,10,50,0,57,54,0, +18,109,0,16,10,51,0,57,54,0,0,0,0,1,0,0,2,28,1,0,2,9,97,0,0,0,1,9,18,97,0,17,49,0,48,0,0,22,0,0,1,0, +0,2,28,1,0,2,5,97,0,0,0,1,9,18,97,0,16,10,49,0,22,0,0,1,0,0,2,28,1,0,2,10,118,0,0,0,1,9,18,118,0,59, +120,0,52,18,118,0,59,121,0,52,19,0,0,1,0,0,2,28,1,0,2,11,118,0,0,0,1,9,18,118,0,59,120,0,52,18,118, +0,59,121,0,52,19,18,118,0,59,122,0,52,19,0,0,1,0,0,2,28,1,0,2,12,118,0,0,0,1,9,18,118,0,59,120,0,52, +18,118,0,59,121,0,52,19,18,118,0,59,122,0,52,19,18,118,0,59,119,0,52,19,0,0,1,0,0,2,28,1,0,2,6,118, +0,0,0,1,9,18,118,0,59,120,0,52,18,118,0,59,121,0,52,19,0,0,1,0,0,2,28,1,0,2,7,118,0,0,0,1,9,18,118, +0,59,120,0,52,18,118,0,59,121,0,52,19,18,118,0,59,122,0,52,19,0,0,1,0,0,2,28,1,0,2,8,118,0,0,0,1,9, +18,118,0,59,120,0,52,18,118,0,59,121,0,52,19,18,118,0,59,122,0,52,19,18,118,0,59,119,0,52,19,0,0,1, +0,0,2,28,1,0,2,13,109,0,0,0,1,9,18,109,0,16,8,48,0,57,52,18,109,0,16,10,49,0,57,52,19,0,0,1,0,0,2, +28,1,0,2,14,109,0,0,0,1,9,18,109,0,16,8,48,0,57,52,18,109,0,16,10,49,0,57,52,19,18,109,0,16,10,50,0, +57,52,19,0,0,1,0,0,2,28,1,0,2,15,109,0,0,0,1,9,18,109,0,16,8,48,0,57,52,18,109,0,16,10,49,0,57,52, +19,18,109,0,16,10,50,0,57,52,19,18,109,0,16,10,51,0,57,52,19,0,0,1,0,0,2,27,1,0,2,9,97,0,0,0,1,9,18, +97,0,17,49,0,48,0,0,21,0,0,1,0,0,2,27,1,0,2,5,97,0,0,0,1,9,18,97,0,16,10,49,0,21,0,0,1,0,0,2,27,1,0, +2,10,118,0,0,0,1,9,18,118,0,59,120,0,51,18,118,0,59,121,0,51,19,0,0,1,0,0,2,27,1,0,2,11,118,0,0,0,1, +9,18,118,0,59,120,0,51,18,118,0,59,121,0,51,19,18,118,0,59,122,0,51,19,0,0,1,0,0,2,27,1,0,2,12,118, +0,0,0,1,9,18,118,0,59,120,0,51,18,118,0,59,121,0,51,19,18,118,0,59,122,0,51,19,18,118,0,59,119,0,51, +19,0,0,1,0,0,2,27,1,0,2,6,118,0,0,0,1,9,18,118,0,59,120,0,51,18,118,0,59,121,0,51,19,0,0,1,0,0,2,27, +1,0,2,7,118,0,0,0,1,9,18,118,0,59,120,0,51,18,118,0,59,121,0,51,19,18,118,0,59,122,0,51,19,0,0,1,0, +0,2,27,1,0,2,8,118,0,0,0,1,9,18,118,0,59,120,0,51,18,118,0,59,121,0,51,19,18,118,0,59,122,0,51,19, +18,118,0,59,119,0,51,19,0,0,1,0,0,2,27,1,0,2,13,109,0,0,0,1,9,18,109,0,16,8,48,0,57,51,18,109,0,16, +10,49,0,57,51,19,0,0,1,0,0,2,27,1,0,2,14,109,0,0,0,1,9,18,109,0,16,8,48,0,57,51,18,109,0,16,10,49,0, +57,51,19,18,109,0,16,10,50,0,57,51,19,0,0,1,0,0,2,27,1,0,2,15,109,0,0,0,1,9,18,109,0,16,8,48,0,57, +51,18,109,0,16,10,49,0,57,51,19,18,109,0,16,10,50,0,57,51,19,18,109,0,16,10,51,0,57,51,19,0,0,1,0,9, +2,28,1,0,2,9,97,0,0,1,1,0,5,0,0,0,1,3,2,0,9,1,99,0,0,0,9,18,99,0,18,97,0,20,0,9,18,97,0,52,0,8,18, +99,0,0,0,1,0,5,2,28,1,0,2,5,97,0,0,1,1,0,5,0,0,0,1,3,2,0,5,1,99,0,0,0,9,18,99,0,18,97,0,20,0,9,18, +97,0,52,0,8,18,99,0,0,0,1,0,10,2,28,1,0,2,10,118,0,0,1,1,0,5,0,0,0,1,8,58,118,101,99,50,0,18,118,0, +59,120,0,61,0,18,118,0,59,121,0,61,0,0,0,0,1,0,11,2,28,1,0,2,11,118,0,0,1,1,0,5,0,0,0,1,8,58,118, +101,99,51,0,18,118,0,59,120,0,61,0,18,118,0,59,121,0,61,0,18,118,0,59,122,0,61,0,0,0,0,1,0,12,2,28, +1,0,2,12,118,0,0,1,1,0,5,0,0,0,1,8,58,118,101,99,52,0,18,118,0,59,120,0,61,0,18,118,0,59,121,0,61,0, +18,118,0,59,122,0,61,0,18,118,0,59,119,0,61,0,0,0,0,1,0,6,2,28,1,0,2,6,118,0,0,1,1,0,5,0,0,0,1,8,58, +105,118,101,99,50,0,18,118,0,59,120,0,61,0,18,118,0,59,121,0,61,0,0,0,0,1,0,7,2,28,1,0,2,7,118,0,0, +1,1,0,5,0,0,0,1,8,58,105,118,101,99,51,0,18,118,0,59,120,0,61,0,18,118,0,59,121,0,61,0,18,118,0,59, +122,0,61,0,0,0,0,1,0,8,2,28,1,0,2,8,118,0,0,1,1,0,5,0,0,0,1,8,58,105,118,101,99,52,0,18,118,0,59, +120,0,61,0,18,118,0,59,121,0,61,0,18,118,0,59,122,0,61,0,18,118,0,59,119,0,61,0,0,0,0,1,0,13,2,28,1, +0,2,13,109,0,0,1,1,0,5,0,0,0,1,8,58,109,97,116,50,0,18,109,0,16,8,48,0,57,61,0,18,109,0,16,10,49,0, +57,61,0,0,0,0,1,0,14,2,28,1,0,2,14,109,0,0,1,1,0,5,0,0,0,1,8,58,109,97,116,51,0,18,109,0,16,8,48,0, +57,61,0,18,109,0,16,10,49,0,57,61,0,18,109,0,16,10,50,0,57,61,0,0,0,0,1,0,15,2,28,1,0,2,15,109,0,0, +1,1,0,5,0,0,0,1,8,58,109,97,116,52,0,18,109,0,16,8,48,0,57,61,0,18,109,0,16,10,49,0,57,61,0,18,109, +0,16,10,50,0,57,61,0,18,109,0,16,10,51,0,57,61,0,0,0,0,1,0,9,2,27,1,0,2,9,97,0,0,1,1,0,5,0,0,0,1,3, +2,0,9,1,99,0,0,0,9,18,99,0,18,97,0,20,0,9,18,97,0,51,0,8,18,99,0,0,0,1,0,5,2,27,1,0,2,5,97,0,0,1,1, +0,5,0,0,0,1,3,2,0,5,1,99,0,0,0,9,18,99,0,18,97,0,20,0,9,18,97,0,51,0,8,18,99,0,0,0,1,0,10,2,27,1,0, +2,10,118,0,0,1,1,0,5,0,0,0,1,8,58,118,101,99,50,0,18,118,0,59,120,0,60,0,18,118,0,59,121,0,60,0,0,0, +0,1,0,11,2,27,1,0,2,11,118,0,0,1,1,0,5,0,0,0,1,8,58,118,101,99,51,0,18,118,0,59,120,0,60,0,18,118,0, +59,121,0,60,0,18,118,0,59,122,0,60,0,0,0,0,1,0,12,2,27,1,0,2,12,118,0,0,1,1,0,5,0,0,0,1,8,58,118, +101,99,52,0,18,118,0,59,120,0,60,0,18,118,0,59,121,0,60,0,18,118,0,59,122,0,60,0,18,118,0,59,119,0, +60,0,0,0,0,1,0,6,2,27,1,0,2,6,118,0,0,1,1,0,5,0,0,0,1,8,58,105,118,101,99,50,0,18,118,0,59,120,0,60, +0,18,118,0,59,121,0,60,0,0,0,0,1,0,7,2,27,1,0,2,7,118,0,0,1,1,0,5,0,0,0,1,8,58,105,118,101,99,51,0, +18,118,0,59,120,0,60,0,18,118,0,59,121,0,60,0,18,118,0,59,122,0,60,0,0,0,0,1,0,8,2,27,1,0,2,8,118,0, +0,1,1,0,5,0,0,0,1,8,58,105,118,101,99,52,0,18,118,0,59,120,0,60,0,18,118,0,59,121,0,60,0,18,118,0, +59,122,0,60,0,18,118,0,59,119,0,60,0,0,0,0,1,0,13,2,27,1,0,2,13,109,0,0,1,1,0,5,0,0,0,1,8,58,109,97, +116,50,0,18,109,0,16,8,48,0,57,60,0,18,109,0,16,10,49,0,57,60,0,0,0,0,1,0,14,2,27,1,0,2,14,109,0,0, +1,1,0,5,0,0,0,1,8,58,109,97,116,51,0,18,109,0,16,8,48,0,57,60,0,18,109,0,16,10,49,0,57,60,0,18,109, +0,16,10,50,0,57,60,0,0,0,0,1,0,15,2,27,1,0,2,15,109,0,0,1,1,0,5,0,0,0,1,8,58,109,97,116,52,0,18,109, +0,16,8,48,0,57,60,0,18,109,0,16,10,49,0,57,60,0,18,109,0,16,10,50,0,57,60,0,18,109,0,16,10,51,0,57, +60,0,0,0,0,1,0,1,2,18,1,1,0,9,97,0,0,1,1,0,9,98,0,0,0,1,3,2,0,1,1,99,0,0,0,4,102,108,111,97,116,95, +108,101,115,115,0,18,99,0,0,18,97,0,0,18,98,0,0,0,8,18,99,0,0,0,1,0,1,2,18,1,1,0,5,97,0,0,1,1,0,5, +98,0,0,0,1,8,58,102,108,111,97,116,0,18,97,0,0,0,58,102,108,111,97,116,0,18,98,0,0,0,40,0,0,1,0,1,2, +19,1,1,0,9,97,0,0,1,1,0,9,98,0,0,0,1,8,18,98,0,18,97,0,40,0,0,1,0,1,2,19,1,1,0,5,97,0,0,1,1,0,5,98, +0,0,0,1,8,18,98,0,18,97,0,40,0,0,1,0,1,2,21,1,1,0,9,97,0,0,1,1,0,9,98,0,0,0,1,8,18,97,0,18,98,0,41, +18,97,0,18,98,0,38,32,0,0,1,0,1,2,21,1,1,0,5,97,0,0,1,1,0,5,98,0,0,0,1,8,18,97,0,18,98,0,41,18,97,0, +18,98,0,38,32,0,0,1,0,1,2,20,1,1,0,9,97,0,0,1,1,0,9,98,0,0,0,1,8,18,97,0,18,98,0,40,18,97,0,18,98,0, +38,32,0,0,1,0,1,2,20,1,1,0,5,97,0,0,1,1,0,5,98,0,0,0,1,8,18,97,0,18,98,0,40,18,97,0,18,98,0,38,32,0, +0,1,0,1,2,12,1,1,0,1,97,0,0,1,1,0,1,98,0,0,0,1,8,18,97,0,18,98,0,39,0,0,1,0,1,2,32,1,1,0,1,97,0,0,0, +1,8,18,97,0,15,2,48,0,38,0,0,0
\ No newline at end of file diff --git a/nx-X11/extras/Mesa/src/mesa/shader/slang/library/slang_fragment_builtin_gc.h b/nx-X11/extras/Mesa/src/mesa/shader/slang/library/slang_fragment_builtin_gc.h new file mode 100644 index 000000000..85f74bda8 --- /dev/null +++ b/nx-X11/extras/Mesa/src/mesa/shader/slang/library/slang_fragment_builtin_gc.h @@ -0,0 +1,366 @@ +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"__fixed_input vec4 gl_FragCoord;\n" +"__fixed_input bool gl_FrontFacing;\n" +"__fixed_output vec4 gl_FragColor;\n" +"__fixed_output vec4 gl_FragData[gl_MaxDrawBuffers];\n" +"__fixed_output float gl_FragDepth;\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"varying vec4 gl_Color;\n" +"varying vec4 gl_SecondaryColor;\n" +"varying vec4 gl_TexCoord[];\n" +"varying float gl_FogFragCoord;\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"vec4 texture1D (sampler1D sampler, float coord, float bias) {\n" +" return vec4 (0.0);\n" +"}\n" +"vec4 texture1DProj (sampler1D sampler, vec2 coord, float bias) {\n" +" return texture1D (sampler, coord.s / coord.t, bias);\n" +"}\n" +"vec4 texture1DProj (sampler1D sampler, vec4 coord, float bias) {\n" +" return texture1D (sampler, coord.s / coord.q, bias);\n" +"}\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"vec4 texture2D (sampler2D sampler, vec2 coord, float bias) {\n" +" return vec4 (0.0);\n" +"}\n" +"vec4 texture2DProj (sampler2D sampler, vec3 coord, float bias) {\n" +" return texture2D (sampler, vec2 (coord.s / coord.p, coord.t / coord.p), bias);\n" +"}\n" +"vec4 texture2DProj (sampler2D sampler, vec4 coord, float bias) {\n" +" return texture2D (sampler, vec2 (coord.s / coord.q, coord.s / coord.q), bias);\n" +"}\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"vec4 texture3D (sampler3D sampler, vec3 coord, float bias) {\n" +" return vec4 (0.0);\n" +"}\n" +"vec4 texture3DProj (sampler3D sampler, vec4 coord, float bias) {\n" +" return texture3DProj (sampler, vec3 (coord.s / coord.q, coord.t / coord.q, coord.p / coord.q),\n" +" bias);\n" +"}\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"vec4 textureCube (samplerCube sampler, vec3 coord, float bias) {\n" +" return vec4 (0.0);\n" +"}\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"vec4 shadow1D (sampler1DShadow sampler, vec3 coord, float bias) {\n" +" return vec4 (0.0);\n" +"}\n" +"\n" +"vec4 shadow2D (sampler2DShadow sampler, vec3 coord, float bias) {\n" +" return vec4 (0.0);\n" +"}\n" +"vec4 shadow1DProj (sampler1DShadow sampler, vec4 coord, float bias) {\n" +" return shadow1D (sampler, vec3 (coord.s / coord.q, 0.0, coord.p / coord.q), bias);\n" +"}\n" +"vec4 shadow2DProj (sampler2DShadow sampler, vec4 coord, float bias) {\n" +" return shadow2D (sampler, vec3 (coord.s / coord.q, coord.t / coord.q, coord.p / coord.q), bias);\n" +"}\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"float dFdx (float p) {\n" +" return 0.0;\n" +"}\n" +"\n" +"vec2 dFdx (vec2 p) {\n" +" return vec2 (0.0);\n" +"}\n" +"\n" +"vec3 dFdx (vec3 p) {\n" +" return vec3 (0.0);\n" +"}\n" +"\n" +"vec4 dFdx (vec4 p) {\n" +" return vec4 (0.0);\n" +"}\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"float dFdy (float p) {\n" +" return 0.0;\n" +"}\n" +"\n" +"vec2 dFdy (vec2 p) {\n" +" return vec2 (0.0);\n" +"}\n" +"\n" +"vec3 dFdy (vec3 p) {\n" +" return vec3 (0.0);\n" +"}\n" +"\n" +"vec4 dFdy (vec4 p) {\n" +" return vec4 (0.0);\n" +"}\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"float fwidth (float p) {\n" +" return abs (dFdx (p)) + abs (dFdy (p));\n" +"}\n" +"vec2 fwidth (vec2 p) {\n" +" return abs (dFdx (p)) + abs (dFdy (p));\n" +"}\n" +"vec3 fwidth (vec3 p) {\n" +" return abs (dFdx (p)) + abs (dFdy (p));\n" +"}\n" +"vec4 fwidth (vec4 p) {\n" +" return abs (dFdx (p)) + abs (dFdy (p));\n" +"}\n" +"\n" diff --git a/nx-X11/extras/Mesa/src/mesa/shader/slang/library/slang_fragment_builtin_gc_bin.h b/nx-X11/extras/Mesa/src/mesa/shader/slang/library/slang_fragment_builtin_gc_bin.h new file mode 100644 index 000000000..b566c8b33 --- /dev/null +++ b/nx-X11/extras/Mesa/src/mesa/shader/slang/library/slang_fragment_builtin_gc_bin.h @@ -0,0 +1,87 @@ +2,2,2,6,12,1,103,108,95,70,114,97,103,67,111,111,114,100,0,0,0,2,2,6, +1,1,103,108,95,70,114,111,110,116,70,97,99,105,110,103,0,0,0,2,2,5,12,1, +103,108,95,70,114,97,103,67,111,108,111,114,0,0,0,2,2,5,12,1,103,108,95,70, +114,97,103,68,97,116,97,0,3,18,103,108,95,77,97,120,68,114,97,119,66,117,102,102, +101,114,115,0,0,0,2,2,5,9,1,103,108,95,70,114,97,103,68,101,112,116,104,0, +0,0,2,2,3,12,1,103,108,95,67,111,108,111,114,0,0,0,2,2,3,12,1,103, +108,95,83,101,99,111,110,100,97,114,121,67,111,108,111,114,0,0,0,2,2,3,12,1, +103,108,95,84,101,120,67,111,111,114,100,0,4,0,2,2,3,9,1,103,108,95,70,111, +103,70,114,97,103,67,111,111,114,100,0,0,0,1,0,12,0,116,101,120,116,117,114,101, +49,68,0,1,0,0,16,115,97,109,112,108,101,114,0,0,1,0,0,9,99,111,111,114, +100,0,0,1,0,0,9,98,105,97,115,0,0,0,1,8,58,118,101,99,52,0,17,48, +0,48,0,0,0,0,0,0,1,0,12,0,116,101,120,116,117,114,101,49,68,80,114,111, +106,0,1,0,0,16,115,97,109,112,108,101,114,0,0,1,0,0,10,99,111,111,114,100, +0,0,1,0,0,9,98,105,97,115,0,0,0,1,8,58,116,101,120,116,117,114,101,49, +68,0,18,115,97,109,112,108,101,114,0,0,18,99,111,111,114,100,0,59,115,0,18,99, +111,111,114,100,0,59,116,0,49,0,18,98,105,97,115,0,0,0,0,0,1,0,12,0, +116,101,120,116,117,114,101,49,68,80,114,111,106,0,1,0,0,16,115,97,109,112,108,101, +114,0,0,1,0,0,12,99,111,111,114,100,0,0,1,0,0,9,98,105,97,115,0,0, +0,1,8,58,116,101,120,116,117,114,101,49,68,0,18,115,97,109,112,108,101,114,0,0, +18,99,111,111,114,100,0,59,115,0,18,99,111,111,114,100,0,59,113,0,49,0,18,98, +105,97,115,0,0,0,0,0,1,0,12,0,116,101,120,116,117,114,101,50,68,0,1,0, +0,17,115,97,109,112,108,101,114,0,0,1,0,0,10,99,111,111,114,100,0,0,1,0, +0,9,98,105,97,115,0,0,0,1,8,58,118,101,99,52,0,17,48,0,48,0,0,0, +0,0,0,1,0,12,0,116,101,120,116,117,114,101,50,68,80,114,111,106,0,1,0,0, +17,115,97,109,112,108,101,114,0,0,1,0,0,11,99,111,111,114,100,0,0,1,0,0, +9,98,105,97,115,0,0,0,1,8,58,116,101,120,116,117,114,101,50,68,0,18,115,97, +109,112,108,101,114,0,0,58,118,101,99,50,0,18,99,111,111,114,100,0,59,115,0,18, +99,111,111,114,100,0,59,112,0,49,0,18,99,111,111,114,100,0,59,116,0,18,99,111, +111,114,100,0,59,112,0,49,0,0,0,18,98,105,97,115,0,0,0,0,0,1,0,12, +0,116,101,120,116,117,114,101,50,68,80,114,111,106,0,1,0,0,17,115,97,109,112,108, +101,114,0,0,1,0,0,12,99,111,111,114,100,0,0,1,0,0,9,98,105,97,115,0, +0,0,1,8,58,116,101,120,116,117,114,101,50,68,0,18,115,97,109,112,108,101,114,0, +0,58,118,101,99,50,0,18,99,111,111,114,100,0,59,115,0,18,99,111,111,114,100,0, +59,113,0,49,0,18,99,111,111,114,100,0,59,115,0,18,99,111,111,114,100,0,59,113, +0,49,0,0,0,18,98,105,97,115,0,0,0,0,0,1,0,12,0,116,101,120,116,117, +114,101,51,68,0,1,0,0,18,115,97,109,112,108,101,114,0,0,1,0,0,11,99,111, +111,114,100,0,0,1,0,0,9,98,105,97,115,0,0,0,1,8,58,118,101,99,52,0, +17,48,0,48,0,0,0,0,0,0,1,0,12,0,116,101,120,116,117,114,101,51,68,80, +114,111,106,0,1,0,0,18,115,97,109,112,108,101,114,0,0,1,0,0,12,99,111,111, +114,100,0,0,1,0,0,9,98,105,97,115,0,0,0,1,8,58,116,101,120,116,117,114, +101,51,68,80,114,111,106,0,18,115,97,109,112,108,101,114,0,0,58,118,101,99,51,0, +18,99,111,111,114,100,0,59,115,0,18,99,111,111,114,100,0,59,113,0,49,0,18,99, +111,111,114,100,0,59,116,0,18,99,111,111,114,100,0,59,113,0,49,0,18,99,111,111, +114,100,0,59,112,0,18,99,111,111,114,100,0,59,113,0,49,0,0,0,18,98,105,97, +115,0,0,0,0,0,1,0,12,0,116,101,120,116,117,114,101,67,117,98,101,0,1,0, +0,19,115,97,109,112,108,101,114,0,0,1,0,0,11,99,111,111,114,100,0,0,1,0, +0,9,98,105,97,115,0,0,0,1,8,58,118,101,99,52,0,17,48,0,48,0,0,0, +0,0,0,1,0,12,0,115,104,97,100,111,119,49,68,0,1,0,0,20,115,97,109,112, +108,101,114,0,0,1,0,0,11,99,111,111,114,100,0,0,1,0,0,9,98,105,97,115, +0,0,0,1,8,58,118,101,99,52,0,17,48,0,48,0,0,0,0,0,0,1,0,12, +0,115,104,97,100,111,119,50,68,0,1,0,0,21,115,97,109,112,108,101,114,0,0,1, +0,0,11,99,111,111,114,100,0,0,1,0,0,9,98,105,97,115,0,0,0,1,8,58, +118,101,99,52,0,17,48,0,48,0,0,0,0,0,0,1,0,12,0,115,104,97,100,111, +119,49,68,80,114,111,106,0,1,0,0,20,115,97,109,112,108,101,114,0,0,1,0,0, +12,99,111,111,114,100,0,0,1,0,0,9,98,105,97,115,0,0,0,1,8,58,115,104, +97,100,111,119,49,68,0,18,115,97,109,112,108,101,114,0,0,58,118,101,99,51,0,18, +99,111,111,114,100,0,59,115,0,18,99,111,111,114,100,0,59,113,0,49,0,17,48,0, +48,0,0,0,18,99,111,111,114,100,0,59,112,0,18,99,111,111,114,100,0,59,113,0, +49,0,0,0,18,98,105,97,115,0,0,0,0,0,1,0,12,0,115,104,97,100,111,119, +50,68,80,114,111,106,0,1,0,0,21,115,97,109,112,108,101,114,0,0,1,0,0,12, +99,111,111,114,100,0,0,1,0,0,9,98,105,97,115,0,0,0,1,8,58,115,104,97, +100,111,119,50,68,0,18,115,97,109,112,108,101,114,0,0,58,118,101,99,51,0,18,99, +111,111,114,100,0,59,115,0,18,99,111,111,114,100,0,59,113,0,49,0,18,99,111,111, +114,100,0,59,116,0,18,99,111,111,114,100,0,59,113,0,49,0,18,99,111,111,114,100, +0,59,112,0,18,99,111,111,114,100,0,59,113,0,49,0,0,0,18,98,105,97,115,0, +0,0,0,0,1,0,9,0,100,70,100,120,0,1,0,0,9,112,0,0,0,1,8,17, +48,0,48,0,0,0,0,1,0,10,0,100,70,100,120,0,1,0,0,10,112,0,0,0, +1,8,58,118,101,99,50,0,17,48,0,48,0,0,0,0,0,0,1,0,11,0,100,70, +100,120,0,1,0,0,11,112,0,0,0,1,8,58,118,101,99,51,0,17,48,0,48,0, +0,0,0,0,0,1,0,12,0,100,70,100,120,0,1,0,0,12,112,0,0,0,1,8, +58,118,101,99,52,0,17,48,0,48,0,0,0,0,0,0,1,0,9,0,100,70,100,121, +0,1,0,0,9,112,0,0,0,1,8,17,48,0,48,0,0,0,0,1,0,10,0,100, +70,100,121,0,1,0,0,10,112,0,0,0,1,8,58,118,101,99,50,0,17,48,0,48, +0,0,0,0,0,0,1,0,11,0,100,70,100,121,0,1,0,0,11,112,0,0,0,1, +8,58,118,101,99,51,0,17,48,0,48,0,0,0,0,0,0,1,0,12,0,100,70,100, +121,0,1,0,0,12,112,0,0,0,1,8,58,118,101,99,52,0,17,48,0,48,0,0, +0,0,0,0,1,0,9,0,102,119,105,100,116,104,0,1,0,0,9,112,0,0,0,1, +8,58,97,98,115,0,58,100,70,100,120,0,18,112,0,0,0,0,0,58,97,98,115,0, +58,100,70,100,121,0,18,112,0,0,0,0,0,46,0,0,1,0,10,0,102,119,105,100, +116,104,0,1,0,0,10,112,0,0,0,1,8,58,97,98,115,0,58,100,70,100,120,0, +18,112,0,0,0,0,0,58,97,98,115,0,58,100,70,100,121,0,18,112,0,0,0,0, +0,46,0,0,1,0,11,0,102,119,105,100,116,104,0,1,0,0,11,112,0,0,0,1, +8,58,97,98,115,0,58,100,70,100,120,0,18,112,0,0,0,0,0,58,97,98,115,0, +58,100,70,100,121,0,18,112,0,0,0,0,0,46,0,0,1,0,12,0,102,119,105,100, +116,104,0,1,0,0,12,112,0,0,0,1,8,58,97,98,115,0,58,100,70,100,120,0, +18,112,0,0,0,0,0,58,97,98,115,0,58,100,70,100,121,0,18,112,0,0,0,0, +0,46,0,0,0
\ No newline at end of file diff --git a/nx-X11/extras/Mesa/src/mesa/shader/slang/library/slang_shader_syn.h b/nx-X11/extras/Mesa/src/mesa/shader/slang/library/slang_shader_syn.h new file mode 100644 index 000000000..12e2a2137 --- /dev/null +++ b/nx-X11/extras/Mesa/src/mesa/shader/slang/library/slang_shader_syn.h @@ -0,0 +1,758 @@ +".syntax translation_unit;\n" +".emtcode REVISION 2\n" +".emtcode EXTERNAL_NULL 0\n" +".emtcode EXTERNAL_FUNCTION_DEFINITION 1\n" +".emtcode EXTERNAL_DECLARATION 2\n" +".emtcode DECLARATION_FUNCTION_PROTOTYPE 1\n" +".emtcode DECLARATION_INIT_DECLARATOR_LIST 2\n" +".emtcode FUNCTION_ORDINARY 0\n" +".emtcode FUNCTION_CONSTRUCTOR 1\n" +".emtcode FUNCTION_OPERATOR 2\n" +".emtcode OPERATOR_ASSIGN 1\n" +".emtcode OPERATOR_ADDASSIGN 2\n" +".emtcode OPERATOR_SUBASSIGN 3\n" +".emtcode OPERATOR_MULASSIGN 4\n" +".emtcode OPERATOR_DIVASSIGN 5\n" +".emtcode OPERATOR_LOGICALXOR 12\n" +".emtcode OPERATOR_EQUAL 16\n" +".emtcode OPERATOR_NOTEQUAL 17\n" +".emtcode OPERATOR_LESS 18\n" +".emtcode OPERATOR_GREATER 19\n" +".emtcode OPERATOR_LESSEQUAL 20\n" +".emtcode OPERATOR_GREATEREQUAL 21\n" +".emtcode OPERATOR_MULTIPLY 24\n" +".emtcode OPERATOR_DIVIDE 25\n" +".emtcode OPERATOR_INCREMENT 27\n" +".emtcode OPERATOR_DECREMENT 28\n" +".emtcode OPERATOR_PLUS 29\n" +".emtcode OPERATOR_MINUS 30\n" +".emtcode OPERATOR_NOT 32\n" +".emtcode DECLARATOR_NONE 0\n" +".emtcode DECLARATOR_NEXT 1\n" +".emtcode VARIABLE_NONE 0\n" +".emtcode VARIABLE_IDENTIFIER 1\n" +".emtcode VARIABLE_INITIALIZER 2\n" +".emtcode VARIABLE_ARRAY_EXPLICIT 3\n" +".emtcode VARIABLE_ARRAY_UNKNOWN 4\n" +".emtcode TYPE_QUALIFIER_NONE 0\n" +".emtcode TYPE_QUALIFIER_CONST 1\n" +".emtcode TYPE_QUALIFIER_ATTRIBUTE 2\n" +".emtcode TYPE_QUALIFIER_VARYING 3\n" +".emtcode TYPE_QUALIFIER_UNIFORM 4\n" +".emtcode TYPE_QUALIFIER_FIXEDOUTPUT 5\n" +".emtcode TYPE_QUALIFIER_FIXEDINPUT 6\n" +".emtcode TYPE_SPECIFIER_VOID 0\n" +".emtcode TYPE_SPECIFIER_BOOL 1\n" +".emtcode TYPE_SPECIFIER_BVEC2 2\n" +".emtcode TYPE_SPECIFIER_BVEC3 3\n" +".emtcode TYPE_SPECIFIER_BVEC4 4\n" +".emtcode TYPE_SPECIFIER_INT 5\n" +".emtcode TYPE_SPECIFIER_IVEC2 6\n" +".emtcode TYPE_SPECIFIER_IVEC3 7\n" +".emtcode TYPE_SPECIFIER_IVEC4 8\n" +".emtcode TYPE_SPECIFIER_FLOAT 9\n" +".emtcode TYPE_SPECIFIER_VEC2 10\n" +".emtcode TYPE_SPECIFIER_VEC3 11\n" +".emtcode TYPE_SPECIFIER_VEC4 12\n" +".emtcode TYPE_SPECIFIER_MAT2 13\n" +".emtcode TYPE_SPECIFIER_MAT3 14\n" +".emtcode TYPE_SPECIFIER_MAT4 15\n" +".emtcode TYPE_SPECIFIER_SAMPLER1D 16\n" +".emtcode TYPE_SPECIFIER_SAMPLER2D 17\n" +".emtcode TYPE_SPECIFIER_SAMPLER3D 18\n" +".emtcode TYPE_SPECIFIER_SAMPLERCUBE 19\n" +".emtcode TYPE_SPECIFIER_SAMPLER1DSHADOW 20\n" +".emtcode TYPE_SPECIFIER_SAMPLER2DSHADOW 21\n" +".emtcode TYPE_SPECIFIER_STRUCT 22\n" +".emtcode TYPE_SPECIFIER_TYPENAME 23\n" +".emtcode FIELD_NONE 0\n" +".emtcode FIELD_NEXT 1\n" +".emtcode FIELD_ARRAY 2\n" +".emtcode OP_END 0\n" +".emtcode OP_BLOCK_BEGIN_NO_NEW_SCOPE 1\n" +".emtcode OP_BLOCK_BEGIN_NEW_SCOPE 2\n" +".emtcode OP_DECLARE 3\n" +".emtcode OP_ASM 4\n" +".emtcode OP_BREAK 5\n" +".emtcode OP_CONTINUE 6\n" +".emtcode OP_DISCARD 7\n" +".emtcode OP_RETURN 8\n" +".emtcode OP_EXPRESSION 9\n" +".emtcode OP_IF 10\n" +".emtcode OP_WHILE 11\n" +".emtcode OP_DO 12\n" +".emtcode OP_FOR 13\n" +".emtcode OP_PUSH_VOID 14\n" +".emtcode OP_PUSH_BOOL 15\n" +".emtcode OP_PUSH_INT 16\n" +".emtcode OP_PUSH_FLOAT 17\n" +".emtcode OP_PUSH_IDENTIFIER 18\n" +".emtcode OP_SEQUENCE 19\n" +".emtcode OP_ASSIGN 20\n" +".emtcode OP_ADDASSIGN 21\n" +".emtcode OP_SUBASSIGN 22\n" +".emtcode OP_MULASSIGN 23\n" +".emtcode OP_DIVASSIGN 24\n" +".emtcode OP_SELECT 31\n" +".emtcode OP_LOGICALOR 32\n" +".emtcode OP_LOGICALXOR 33\n" +".emtcode OP_LOGICALAND 34\n" +".emtcode OP_EQUAL 38\n" +".emtcode OP_NOTEQUAL 39\n" +".emtcode OP_LESS 40\n" +".emtcode OP_GREATER 41\n" +".emtcode OP_LESSEQUAL 42\n" +".emtcode OP_GREATEREQUAL 43\n" +".emtcode OP_ADD 46\n" +".emtcode OP_SUBTRACT 47\n" +".emtcode OP_MULTIPLY 48\n" +".emtcode OP_DIVIDE 49\n" +".emtcode OP_PREINCREMENT 51\n" +".emtcode OP_PREDECREMENT 52\n" +".emtcode OP_PLUS 53\n" +".emtcode OP_MINUS 54\n" +".emtcode OP_NOT 56\n" +".emtcode OP_SUBSCRIPT 57\n" +".emtcode OP_CALL 58\n" +".emtcode OP_FIELD 59\n" +".emtcode OP_POSTINCREMENT 60\n" +".emtcode OP_POSTDECREMENT 61\n" +".emtcode PARAM_QUALIFIER_IN 0\n" +".emtcode PARAM_QUALIFIER_OUT 1\n" +".emtcode PARAM_QUALIFIER_INOUT 2\n" +".emtcode PARAMETER_NONE 0\n" +".emtcode PARAMETER_NEXT 1\n" +".emtcode PARAMETER_ARRAY_NOT_PRESENT 0\n" +".emtcode PARAMETER_ARRAY_PRESENT 1\n" +".errtext INVALID_EXTERNAL_DECLARATION \"error 2001: invalid external declaration\"\n" +".errtext INVALID_OPERATOR_OVERRIDE \"error 2002: invalid operator override\"\n" +".errtext LBRACE_EXPECTED \"error 2003: '{' expected but '$err_token$' found\"\n" +".errtext LPAREN_EXPECTED \"error 2004: '(' expected but '$err_token$' found\"\n" +".errtext RPAREN_EXPECTED \"error 2005: ')' expected but '$err_token$' found\"\n" +".regbyte parsing_builtin 0\n" +".regbyte shader_type 0\n" +"variable_identifier\n" +" identifier .emit OP_PUSH_IDENTIFIER;\n" +"primary_expression\n" +" floatconstant .or boolconstant .or intconstant .or variable_identifier .or primary_expression_1;\n" +"primary_expression_1\n" +" lparen .and expression .and rparen;\n" +"postfix_expression\n" +" postfix_expression_1 .and .loop postfix_expression_2;\n" +"postfix_expression_1\n" +" function_call .or primary_expression;\n" +"postfix_expression_2\n" +" postfix_expression_3 .or postfix_expression_4 .or\n" +" plusplus .emit OP_POSTINCREMENT .or\n" +" minusminus .emit OP_POSTDECREMENT;\n" +"postfix_expression_3\n" +" lbracket .and integer_expression .and rbracket .emit OP_SUBSCRIPT;\n" +"postfix_expression_4\n" +" dot .and field_selection .emit OP_FIELD;\n" +"integer_expression\n" +" expression;\n" +"function_call\n" +" function_call_generic .emit OP_CALL .and .true .emit OP_END;\n" +"function_call_generic\n" +" function_call_generic_1 .or function_call_generic_2;\n" +"function_call_generic_1\n" +" function_call_header_with_parameters .and rparen .error RPAREN_EXPECTED;\n" +"function_call_generic_2\n" +" function_call_header_no_parameters .and rparen .error RPAREN_EXPECTED;\n" +"function_call_header_no_parameters\n" +" function_call_header .and function_call_header_no_parameters_1;\n" +"function_call_header_no_parameters_1\n" +" \"void\" .or .true;\n" +"function_call_header_with_parameters\n" +" function_call_header .and assignment_expression .and .true .emit OP_END .and\n" +" .loop function_call_header_with_parameters_1;\n" +"function_call_header_with_parameters_1\n" +" comma .and assignment_expression .and .true .emit OP_END;\n" +"function_call_header\n" +" function_identifier .and lparen;\n" +"function_identifier\n" +" identifier;\n" +"unary_expression\n" +" postfix_expression .or unary_expression_1 .or unary_expression_2 .or unary_expression_3 .or\n" +" unary_expression_4 .or unary_expression_5;\n" +"unary_expression_1\n" +" plusplus .and unary_expression .and .true .emit OP_PREINCREMENT;\n" +"unary_expression_2\n" +" minusminus .and unary_expression .and .true .emit OP_PREDECREMENT;\n" +"unary_expression_3\n" +" plus .and unary_expression .and .true .emit OP_PLUS;\n" +"unary_expression_4\n" +" minus .and unary_expression .and .true .emit OP_MINUS;\n" +"unary_expression_5\n" +" bang .and unary_expression .and .true .emit OP_NOT;\n" +"multiplicative_expression\n" +" unary_expression .and .loop multiplicative_expression_1;\n" +"multiplicative_expression_1\n" +" multiplicative_expression_2 .or multiplicative_expression_3;\n" +"multiplicative_expression_2\n" +" star .and unary_expression .and .true .emit OP_MULTIPLY;\n" +"multiplicative_expression_3\n" +" slash .and unary_expression .and .true .emit OP_DIVIDE;\n" +"additive_expression\n" +" multiplicative_expression .and .loop additive_expression_1;\n" +"additive_expression_1\n" +" additive_expression_2 .or additive_expression_3;\n" +"additive_expression_2\n" +" plus .and multiplicative_expression .and .true .emit OP_ADD;\n" +"additive_expression_3\n" +" minus .and multiplicative_expression .and .true .emit OP_SUBTRACT;\n" +"shift_expression\n" +" additive_expression;\n" +"relational_expression\n" +" shift_expression .and .loop relational_expression_1;\n" +"relational_expression_1\n" +" relational_expression_2 .or relational_expression_3 .or relational_expression_4 .or\n" +" relational_expression_5;\n" +"relational_expression_2\n" +" lessequals .and shift_expression .and .true .emit OP_LESSEQUAL;\n" +"relational_expression_3\n" +" greaterequals .and shift_expression .and .true .emit OP_GREATEREQUAL;\n" +"relational_expression_4\n" +" less .and shift_expression .and .true .emit OP_LESS;\n" +"relational_expression_5\n" +" greater .and shift_expression .and .true .emit OP_GREATER;\n" +"equality_expression\n" +" relational_expression .and .loop equality_expression_1;\n" +"equality_expression_1\n" +" equality_expression_2 .or equality_expression_3;\n" +"equality_expression_2\n" +" equalsequals .and relational_expression .and .true .emit OP_EQUAL;\n" +"equality_expression_3\n" +" bangequals .and relational_expression .and .true .emit OP_NOTEQUAL;\n" +"and_expression\n" +" equality_expression;\n" +"exclusive_or_expression\n" +" and_expression;\n" +"inclusive_or_expression\n" +" exclusive_or_expression;\n" +"logical_and_expression\n" +" inclusive_or_expression .and .loop logical_and_expression_1;\n" +"logical_and_expression_1\n" +" ampersandampersand .and inclusive_or_expression .and .true .emit OP_LOGICALAND;\n" +"logical_xor_expression\n" +" logical_and_expression .and .loop logical_xor_expression_1;\n" +"logical_xor_expression_1\n" +" caretcaret .and logical_and_expression .and .true .emit OP_LOGICALXOR;\n" +"logical_or_expression\n" +" logical_xor_expression .and .loop logical_or_expression_1;\n" +"logical_or_expression_1\n" +" barbar .and logical_xor_expression .and .true .emit OP_LOGICALOR;\n" +"conditional_expression\n" +" logical_or_expression .and .loop conditional_expression_1;\n" +"conditional_expression_1\n" +" question .and expression .and colon .and conditional_expression .and .true .emit OP_SELECT;\n" +"assignment_expression\n" +" assignment_expression_1 .or assignment_expression_2 .or assignment_expression_3 .or\n" +" assignment_expression_4 .or assignment_expression_5 .or conditional_expression;\n" +"assignment_expression_1\n" +" unary_expression .and equals .and assignment_expression .and .true .emit OP_ASSIGN;\n" +"assignment_expression_2\n" +" unary_expression .and starequals .and assignment_expression .and .true .emit OP_MULASSIGN;\n" +"assignment_expression_3\n" +" unary_expression .and slashequals .and assignment_expression .and .true .emit OP_DIVASSIGN;\n" +"assignment_expression_4\n" +" unary_expression .and plusequals .and assignment_expression .and .true .emit OP_ADDASSIGN;\n" +"assignment_expression_5\n" +" unary_expression .and minusequals .and assignment_expression .and .true .emit OP_SUBASSIGN;\n" +"expression\n" +" assignment_expression .and .loop expression_1;\n" +"expression_1\n" +" comma .and assignment_expression .and .true .emit OP_SEQUENCE;\n" +"constant_expression\n" +" conditional_expression .and .true .emit OP_END;\n" +"declaration\n" +" declaration_1 .or declaration_2;\n" +"declaration_1\n" +" function_prototype .emit DECLARATION_FUNCTION_PROTOTYPE .and semicolon;\n" +"declaration_2\n" +" init_declarator_list .emit DECLARATION_INIT_DECLARATOR_LIST .and semicolon;\n" +"function_prototype\n" +" function_declarator .and rparen .error RPAREN_EXPECTED .emit PARAMETER_NONE;\n" +"function_declarator\n" +" function_header_with_parameters .or function_header;\n" +"function_header_with_parameters\n" +" function_header .and parameter_declaration .and .loop function_header_with_parameters_1;\n" +"function_header_with_parameters_1\n" +" comma .and parameter_declaration;\n" +"function_header\n" +" function_header_nospace .or function_header_space;\n" +"function_header_space\n" +" fully_specified_type_space .and space .and function_decl_identifier .and lparen;\n" +"function_header_nospace\n" +" fully_specified_type_nospace .and function_decl_identifier .and lparen;\n" +"function_decl_identifier\n" +" .if (parsing_builtin != 0) __operator .emit FUNCTION_OPERATOR .or\n" +" .if (parsing_builtin != 0) \"__constructor\" .emit FUNCTION_CONSTRUCTOR .or\n" +" identifier .emit FUNCTION_ORDINARY;\n" +"__operator\n" +" \"__operator\" .and overriden_operator .error INVALID_OPERATOR_OVERRIDE;\n" +"overriden_operator\n" +" plusplus .emit OPERATOR_INCREMENT .or\n" +" plusequals .emit OPERATOR_ADDASSIGN .or\n" +" plus .emit OPERATOR_PLUS .or\n" +" minusminus .emit OPERATOR_DECREMENT .or\n" +" minusequals .emit OPERATOR_SUBASSIGN .or\n" +" minus .emit OPERATOR_MINUS .or\n" +" bangequals .emit OPERATOR_NOTEQUAL .or\n" +" bang .emit OPERATOR_NOT .or\n" +" starequals .emit OPERATOR_MULASSIGN .or\n" +" star .emit OPERATOR_MULTIPLY .or\n" +" slashequals .emit OPERATOR_DIVASSIGN .or\n" +" slash .emit OPERATOR_DIVIDE .or\n" +" lessequals .emit OPERATOR_LESSEQUAL .or\n" +" \n" +" \n" +" less .emit OPERATOR_LESS .or\n" +" greaterequals .emit OPERATOR_GREATEREQUAL .or\n" +" \n" +" \n" +" greater .emit OPERATOR_GREATER .or\n" +" equalsequals .emit OPERATOR_EQUAL .or\n" +" equals .emit OPERATOR_ASSIGN .or\n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" caretcaret .emit OPERATOR_LOGICALXOR ;\n" +"parameter_declarator\n" +" parameter_declarator_nospace .or parameter_declarator_space;\n" +"parameter_declarator_nospace\n" +" type_specifier_nospace .and identifier .and parameter_declarator_1;\n" +"parameter_declarator_space\n" +" type_specifier_space .and space .and identifier .and parameter_declarator_1;\n" +"parameter_declarator_1\n" +" parameter_declarator_2 .emit PARAMETER_ARRAY_PRESENT .or\n" +" .true .emit PARAMETER_ARRAY_NOT_PRESENT;\n" +"parameter_declarator_2\n" +" lbracket .and constant_expression .and rbracket;\n" +"parameter_declaration\n" +" parameter_declaration_1 .emit PARAMETER_NEXT;\n" +"parameter_declaration_1\n" +" parameter_declaration_2 .or parameter_declaration_3;\n" +"parameter_declaration_2\n" +" type_qualifier .and space .and parameter_qualifier .and parameter_declaration_4;\n" +"parameter_declaration_3\n" +" parameter_qualifier .emit TYPE_QUALIFIER_NONE .and parameter_declaration_4;\n" +"parameter_declaration_4\n" +" parameter_declarator .or parameter_type_specifier;\n" +"parameter_qualifier\n" +" parameter_qualifier_1 .or .true .emit PARAM_QUALIFIER_IN;\n" +"parameter_qualifier_1\n" +" parameter_qualifier_2 .and space;\n" +"parameter_qualifier_2\n" +" \"in\" .emit PARAM_QUALIFIER_IN .or\n" +" \"out\" .emit PARAM_QUALIFIER_OUT .or\n" +" \"inout\" .emit PARAM_QUALIFIER_INOUT;\n" +"parameter_type_specifier\n" +" parameter_type_specifier_1 .and .true .emit '\\0' .and parameter_type_specifier_2;\n" +"parameter_type_specifier_1\n" +" type_specifier_nospace .or type_specifier_space;\n" +"parameter_type_specifier_2\n" +" parameter_type_specifier_3 .emit PARAMETER_ARRAY_PRESENT .or\n" +" .true .emit PARAMETER_ARRAY_NOT_PRESENT;\n" +"parameter_type_specifier_3\n" +" lbracket .and constant_expression .and rbracket;\n" +"init_declarator_list\n" +" single_declaration .and .loop init_declarator_list_1 .emit DECLARATOR_NEXT .and\n" +" .true .emit DECLARATOR_NONE;\n" +"init_declarator_list_1\n" +" comma .and identifier .emit VARIABLE_IDENTIFIER .and init_declarator_list_2;\n" +"init_declarator_list_2\n" +" init_declarator_list_3 .or init_declarator_list_4 .or .true .emit VARIABLE_NONE;\n" +"init_declarator_list_3\n" +" equals .and initializer .emit VARIABLE_INITIALIZER;\n" +"init_declarator_list_4\n" +" lbracket .and init_declarator_list_5 .and rbracket;\n" +"init_declarator_list_5\n" +" constant_expression .emit VARIABLE_ARRAY_EXPLICIT .or .true .emit VARIABLE_ARRAY_UNKNOWN;\n" +"single_declaration\n" +" single_declaration_nospace .or single_declaration_space;\n" +"single_declaration_space\n" +" fully_specified_type_space .and single_declaration_space_1;\n" +"single_declaration_nospace\n" +" fully_specified_type_nospace .and single_declaration_nospace_1;\n" +"single_declaration_space_1\n" +" single_declaration_space_2 .emit VARIABLE_IDENTIFIER .or .true .emit VARIABLE_NONE;\n" +"single_declaration_nospace_1\n" +" single_declaration_nospace_2 .emit VARIABLE_IDENTIFIER .or .true .emit VARIABLE_NONE;\n" +"single_declaration_space_2\n" +" space .and identifier .and single_declaration_3;\n" +"single_declaration_nospace_2\n" +" identifier .and single_declaration_3;\n" +"single_declaration_3\n" +" single_declaration_4 .or single_declaration_5 .or .true .emit VARIABLE_NONE;\n" +"single_declaration_4\n" +" equals .and initializer .emit VARIABLE_INITIALIZER;\n" +"single_declaration_5\n" +" lbracket .and single_declaration_6 .and rbracket;\n" +"single_declaration_6\n" +" constant_expression .emit VARIABLE_ARRAY_EXPLICIT .or .true .emit VARIABLE_ARRAY_UNKNOWN;\n" +"fully_specified_type_space\n" +" fully_specified_type_1 .and type_specifier_space;\n" +"fully_specified_type_nospace\n" +" fully_specified_type_1 .and type_specifier_nospace;\n" +"fully_specified_type_1\n" +" fully_specified_type_2 .or .true .emit TYPE_QUALIFIER_NONE;\n" +"fully_specified_type_2\n" +" type_qualifier .and space;\n" +"type_qualifier\n" +" \"const\" .emit TYPE_QUALIFIER_CONST .or\n" +" .if (shader_type == 2) \"attribute\" .emit TYPE_QUALIFIER_ATTRIBUTE .or\n" +" \"varying\" .emit TYPE_QUALIFIER_VARYING .or\n" +" \"uniform\" .emit TYPE_QUALIFIER_UNIFORM .or\n" +" .if (parsing_builtin != 0) \"__fixed_output\" .emit TYPE_QUALIFIER_FIXEDOUTPUT .or\n" +" .if (parsing_builtin != 0) \"__fixed_input\" .emit TYPE_QUALIFIER_FIXEDINPUT;\n" +"type_specifier_space\n" +" \"void\" .emit TYPE_SPECIFIER_VOID .or\n" +" \"float\" .emit TYPE_SPECIFIER_FLOAT .or\n" +" \"int\" .emit TYPE_SPECIFIER_INT .or\n" +" \"bool\" .emit TYPE_SPECIFIER_BOOL .or\n" +" \"vec2\" .emit TYPE_SPECIFIER_VEC2 .or\n" +" \"vec3\" .emit TYPE_SPECIFIER_VEC3 .or\n" +" \"vec4\" .emit TYPE_SPECIFIER_VEC4 .or\n" +" \"bvec2\" .emit TYPE_SPECIFIER_BVEC2 .or\n" +" \"bvec3\" .emit TYPE_SPECIFIER_BVEC3 .or\n" +" \"bvec4\" .emit TYPE_SPECIFIER_BVEC4 .or\n" +" \"ivec2\" .emit TYPE_SPECIFIER_IVEC2 .or\n" +" \"ivec3\" .emit TYPE_SPECIFIER_IVEC3 .or\n" +" \"ivec4\" .emit TYPE_SPECIFIER_IVEC4 .or\n" +" \"mat2\" .emit TYPE_SPECIFIER_MAT2 .or\n" +" \"mat3\" .emit TYPE_SPECIFIER_MAT3 .or\n" +" \"mat4\" .emit TYPE_SPECIFIER_MAT4 .or\n" +" \"sampler1D\" .emit TYPE_SPECIFIER_SAMPLER1D .or\n" +" \"sampler2D\" .emit TYPE_SPECIFIER_SAMPLER2D .or\n" +" \"sampler3D\" .emit TYPE_SPECIFIER_SAMPLER3D .or\n" +" \"samplerCube\" .emit TYPE_SPECIFIER_SAMPLERCUBE .or\n" +" \"sampler1DShadow\" .emit TYPE_SPECIFIER_SAMPLER1DSHADOW .or\n" +" \"sampler2DShadow\" .emit TYPE_SPECIFIER_SAMPLER2DSHADOW .or\n" +" type_name .emit TYPE_SPECIFIER_TYPENAME;\n" +"type_specifier_nospace\n" +" struct_specifier .emit TYPE_SPECIFIER_STRUCT;\n" +"struct_specifier\n" +" \"struct\" .and struct_specifier_1 .and optional_space .and lbrace .error LBRACE_EXPECTED .and\n" +" struct_declaration_list .and rbrace .emit FIELD_NONE;\n" +"struct_specifier_1\n" +" struct_specifier_2 .or .true .emit '\\0';\n" +"struct_specifier_2\n" +" space .and identifier;\n" +"struct_declaration_list\n" +" struct_declaration .and .loop struct_declaration .emit FIELD_NEXT;\n" +"struct_declaration\n" +" struct_declaration_nospace .or struct_declaration_space;\n" +"struct_declaration_space\n" +" type_specifier_space .and space .and struct_declarator_list .and semicolon .emit FIELD_NONE;\n" +"struct_declaration_nospace\n" +" type_specifier_nospace .and struct_declarator_list .and semicolon .emit FIELD_NONE;\n" +"struct_declarator_list\n" +" struct_declarator .and .loop struct_declarator_list_1 .emit FIELD_NEXT;\n" +"struct_declarator_list_1\n" +" comma .and struct_declarator;\n" +"struct_declarator\n" +" identifier .and struct_declarator_1;\n" +"struct_declarator_1\n" +" struct_declarator_2 .emit FIELD_ARRAY .or .true .emit FIELD_NONE;\n" +"struct_declarator_2\n" +" lbracket .and constant_expression .and rbracket;\n" +"initializer\n" +" assignment_expression .and .true .emit OP_END;\n" +"declaration_statement\n" +" declaration;\n" +"statement\n" +" compound_statement .or simple_statement;\n" +"statement_space\n" +" compound_statement .or statement_space_1;\n" +"statement_space_1\n" +" space .and simple_statement;\n" +"simple_statement\n" +" .if (parsing_builtin != 0) __asm_statement .emit OP_ASM .or\n" +" selection_statement .or\n" +" iteration_statement .or\n" +" jump_statement .or\n" +" expression_statement .emit OP_EXPRESSION .or\n" +" declaration_statement .emit OP_DECLARE;\n" +"compound_statement\n" +" compound_statement_1 .emit OP_BLOCK_BEGIN_NEW_SCOPE .and .true .emit OP_END;\n" +"compound_statement_1\n" +" compound_statement_2 .or compound_statement_3;\n" +"compound_statement_2\n" +" lbrace .and rbrace;\n" +"compound_statement_3\n" +" lbrace .and statement_list .and rbrace;\n" +"statement_no_new_scope\n" +" compound_statement_no_new_scope .or simple_statement;\n" +"compound_statement_no_new_scope\n" +" compound_statement_no_new_scope_1 .emit OP_BLOCK_BEGIN_NO_NEW_SCOPE .and .true .emit OP_END;\n" +"compound_statement_no_new_scope_1\n" +" compound_statement_no_new_scope_2 .or compound_statement_no_new_scope_3;\n" +"compound_statement_no_new_scope_2\n" +" lbrace .and rbrace;\n" +"compound_statement_no_new_scope_3\n" +" lbrace .and statement_list .and rbrace;\n" +"statement_list\n" +" statement .and .loop statement;\n" +"expression_statement\n" +" expression_statement_1 .or expression_statement_2;\n" +"expression_statement_1\n" +" semicolon .emit OP_PUSH_VOID .emit OP_END;\n" +"expression_statement_2\n" +" expression .and semicolon .emit OP_END;\n" +"selection_statement\n" +" \"if\" .emit OP_IF .and lparen .error LPAREN_EXPECTED .and expression .and\n" +" rparen .error RPAREN_EXPECTED .emit OP_END .and selection_rest_statement;\n" +"selection_rest_statement\n" +" statement .and selection_rest_statement_1;\n" +"selection_rest_statement_1\n" +" selection_rest_statement_2 .or .true .emit OP_EXPRESSION .emit OP_PUSH_VOID .emit OP_END;\n" +"selection_rest_statement_2\n" +" \"else\" .and optional_space .and statement;\n" +"condition\n" +" condition_1 .emit OP_DECLARE .emit DECLARATION_INIT_DECLARATOR_LIST .or\n" +" condition_3 .emit OP_EXPRESSION;\n" +"condition_1\n" +" condition_1_nospace .or condition_1_space;\n" +"condition_1_nospace\n" +" fully_specified_type_nospace .and condition_2;\n" +"condition_1_space\n" +" fully_specified_type_space .and space .and condition_2;\n" +"condition_2\n" +" identifier .emit VARIABLE_IDENTIFIER .and equals .emit VARIABLE_INITIALIZER .and\n" +" initializer .and .true .emit DECLARATOR_NONE;\n" +"condition_3\n" +" expression .and .true .emit OP_END;\n" +"iteration_statement\n" +" iteration_statement_1 .or iteration_statement_2 .or iteration_statement_3;\n" +"iteration_statement_1\n" +" \"while\" .emit OP_WHILE .and lparen .error LPAREN_EXPECTED .and condition .and\n" +" rparen .error RPAREN_EXPECTED .and statement_no_new_scope;\n" +"iteration_statement_2\n" +" \"do\" .emit OP_DO .and statement_space .and \"while\" .and lparen .error LPAREN_EXPECTED .and\n" +" expression .and rparen .error RPAREN_EXPECTED .emit OP_END .and semicolon;\n" +"iteration_statement_3\n" +" \"for\" .emit OP_FOR .and lparen .error LPAREN_EXPECTED .and for_init_statement .and\n" +" for_rest_statement .and rparen .error RPAREN_EXPECTED .and statement_no_new_scope;\n" +"for_init_statement\n" +" expression_statement .emit OP_EXPRESSION .or declaration_statement .emit OP_DECLARE;\n" +"conditionopt\n" +" condition .or\n" +" .true .emit OP_EXPRESSION .emit OP_PUSH_BOOL .emit 2 .emit '1' .emit '\\0' .emit OP_END;\n" +"for_rest_statement\n" +" conditionopt .and semicolon .and for_rest_statement_1;\n" +"for_rest_statement_1\n" +" for_rest_statement_2 .or .true .emit OP_PUSH_VOID .emit OP_END;\n" +"for_rest_statement_2\n" +" expression .and .true .emit OP_END;\n" +"jump_statement\n" +" jump_statement_1 .or jump_statement_2 .or jump_statement_3 .or jump_statement_4 .or\n" +" .if (shader_type == 1) jump_statement_5;\n" +"jump_statement_1\n" +" \"continue\" .and semicolon .emit OP_CONTINUE;\n" +"jump_statement_2\n" +" \"break\" .and semicolon .emit OP_BREAK;\n" +"jump_statement_3\n" +" \"return\" .emit OP_RETURN .and optional_space .and expression .and semicolon .emit OP_END;\n" +"jump_statement_4\n" +" \"return\" .emit OP_RETURN .and semicolon .emit OP_PUSH_VOID .emit OP_END;\n" +"jump_statement_5\n" +" \"discard\" .and semicolon .emit OP_DISCARD;\n" +"__asm_statement\n" +" \"__asm\" .and space .and identifier .and space .and asm_arguments .and semicolon .emit OP_END;\n" +"asm_arguments\n" +" variable_identifier .and .true .emit OP_END .and .loop asm_arguments_1;\n" +"asm_arguments_1\n" +" comma .and variable_identifier .and .true .emit OP_END;\n" +"translation_unit\n" +" optional_space .emit REVISION .and external_declaration .error INVALID_EXTERNAL_DECLARATION .and\n" +" .loop external_declaration .and optional_space .and\n" +" '\\0' .error INVALID_EXTERNAL_DECLARATION .emit EXTERNAL_NULL;\n" +"external_declaration\n" +" function_definition .emit EXTERNAL_FUNCTION_DEFINITION .or\n" +" declaration .emit EXTERNAL_DECLARATION;\n" +"function_definition\n" +" function_prototype .and compound_statement_no_new_scope;\n" +"digit_oct\n" +" '0'-'7';\n" +"digit_dec\n" +" '0'-'9';\n" +"digit_hex\n" +" '0'-'9' .or 'A'-'F' .or 'a'-'f';\n" +"id_character_first\n" +" 'a'-'z' .or 'A'-'Z' .or '_';\n" +"id_character_next\n" +" id_character_first .or digit_dec;\n" +"identifier\n" +" id_character_first .emit * .and .loop id_character_next .emit * .and .true .emit '\\0';\n" +"float\n" +" float_1 .or float_2;\n" +"float_1\n" +" float_fractional_constant .and float_optional_exponent_part;\n" +"float_2\n" +" float_digit_sequence .and .true .emit '\\0' .and float_exponent_part;\n" +"float_fractional_constant\n" +" float_fractional_constant_1 .or float_fractional_constant_2 .or float_fractional_constant_3;\n" +"float_fractional_constant_1\n" +" float_digit_sequence .and '.' .and float_digit_sequence;\n" +"float_fractional_constant_2\n" +" float_digit_sequence .and '.' .and .true .emit '\\0';\n" +"float_fractional_constant_3\n" +" '.' .emit '\\0' .and float_digit_sequence;\n" +"float_optional_exponent_part\n" +" float_exponent_part .or .true .emit '\\0';\n" +"float_digit_sequence\n" +" digit_dec .emit * .and .loop digit_dec .emit * .and .true .emit '\\0';\n" +"float_exponent_part\n" +" float_exponent_part_1 .or float_exponent_part_2;\n" +"float_exponent_part_1\n" +" 'e' .and float_optional_sign .and float_digit_sequence;\n" +"float_exponent_part_2\n" +" 'E' .and float_optional_sign .and float_digit_sequence;\n" +"float_optional_sign\n" +" float_sign .or .true;\n" +"float_sign\n" +" '+' .or '-' .emit '-';\n" +"integer\n" +" integer_hex .or integer_oct .or integer_dec;\n" +"integer_hex\n" +" '0' .and integer_hex_1 .emit 0x10 .and digit_hex .emit * .and .loop digit_hex .emit * .and\n" +" .true .emit '\\0';\n" +"integer_hex_1\n" +" 'x' .or 'X';\n" +"integer_oct\n" +" '0' .emit 8 .emit * .and .loop digit_oct .emit * .and .true .emit '\\0';\n" +"integer_dec\n" +" digit_dec .emit 10 .emit * .and .loop digit_dec .emit * .and .true .emit '\\0';\n" +"boolean\n" +" \"true\" .emit 2 .emit '1' .emit '\\0' .or\n" +" \"false\" .emit 2 .emit '0' .emit '\\0';\n" +"type_name\n" +" identifier;\n" +"field_selection\n" +" identifier;\n" +"floatconstant\n" +" float .emit OP_PUSH_FLOAT;\n" +"intconstant\n" +" integer .emit OP_PUSH_INT;\n" +"boolconstant\n" +" boolean .emit OP_PUSH_BOOL;\n" +"optional_space\n" +" .loop single_space;\n" +"space\n" +" single_space .and .loop single_space;\n" +"single_space\n" +" white_char .or c_style_comment_block .or cpp_style_comment_block;\n" +"white_char\n" +" ' ' .or '\\t' .or new_line .or '\\v' .or '\\f';\n" +"new_line\n" +" cr_lf .or lf_cr .or '\\n' .or '\\r';\n" +"cr_lf\n" +" '\\r' .and '\\n';\n" +"lf_cr\n" +" '\\n' .and '\\r';\n" +"c_style_comment_block\n" +" '/' .and '*' .and c_style_comment_rest;\n" +"c_style_comment_rest\n" +" .loop c_style_comment_char_no_star .and c_style_comment_rest_1;\n" +"c_style_comment_rest_1\n" +" c_style_comment_end .or c_style_comment_rest_2;\n" +"c_style_comment_rest_2\n" +" '*' .and c_style_comment_rest;\n" +"c_style_comment_char_no_star\n" +" '\\x2B'-'\\xFF' .or '\\x01'-'\\x29';\n" +"c_style_comment_end\n" +" '*' .and '/';\n" +"cpp_style_comment_block\n" +" '/' .and '/' .and cpp_style_comment_block_1;\n" +"cpp_style_comment_block_1\n" +" cpp_style_comment_block_2 .or cpp_style_comment_block_3;\n" +"cpp_style_comment_block_2\n" +" .loop cpp_style_comment_char .and new_line;\n" +"cpp_style_comment_block_3\n" +" .loop cpp_style_comment_char;\n" +"cpp_style_comment_char\n" +" '\\x0E'-'\\xFF' .or '\\x01'-'\\x09' .or '\\x0B'-'\\x0C';\n" +"ampersandampersand\n" +" optional_space .and '&' .and '&' .and optional_space;\n" +"barbar\n" +" optional_space .and '|' .and '|' .and optional_space;\n" +"bang\n" +" optional_space .and '!' .and optional_space;\n" +"bangequals\n" +" optional_space .and '!' .and '=' .and optional_space;\n" +"caretcaret\n" +" optional_space .and '^' .and '^' .and optional_space;\n" +"colon\n" +" optional_space .and ':' .and optional_space;\n" +"comma\n" +" optional_space .and ',' .and optional_space;\n" +"dot\n" +" optional_space .and '.' .and optional_space;\n" +"equals\n" +" optional_space .and '=' .and optional_space;\n" +"equalsequals\n" +" optional_space .and '=' .and '=' .and optional_space;\n" +"greater\n" +" optional_space .and '>' .and optional_space;\n" +"greaterequals\n" +" optional_space .and '>' .and '=' .and optional_space;\n" +"lbrace\n" +" optional_space .and '{' .and optional_space;\n" +"lbracket\n" +" optional_space .and '[' .and optional_space;\n" +"less\n" +" optional_space .and '<' .and optional_space;\n" +"lessequals\n" +" optional_space .and '<' .and '=' .and optional_space;\n" +"lparen\n" +" optional_space .and '(' .and optional_space;\n" +"minus\n" +" optional_space .and '-' .and optional_space;\n" +"minusequals\n" +" optional_space .and '-' .and '=' .and optional_space;\n" +"minusminus\n" +" optional_space .and '-' .and '-' .and optional_space;\n" +"plus\n" +" optional_space .and '+' .and optional_space;\n" +"plusequals\n" +" optional_space .and '+' .and '=' .and optional_space;\n" +"plusplus\n" +" optional_space .and '+' .and '+' .and optional_space;\n" +"question\n" +" optional_space .and '?' .and optional_space;\n" +"rbrace\n" +" optional_space .and '}' .and optional_space;\n" +"rbracket\n" +" optional_space .and ']' .and optional_space;\n" +"rparen\n" +" optional_space .and ')' .and optional_space;\n" +"semicolon\n" +" optional_space .and ';' .and optional_space;\n" +"slash\n" +" optional_space .and '/' .and optional_space;\n" +"slashequals\n" +" optional_space .and '/' .and '=' .and optional_space;\n" +"star\n" +" optional_space .and '*' .and optional_space;\n" +"starequals\n" +" optional_space .and '*' .and '=' .and optional_space;\n" +".string string_lexer;\n" +"string_lexer\n" +" lex_first_identifier_character .and .loop lex_next_identifier_character;\n" +"lex_first_identifier_character\n" +" 'a'-'z' .or 'A'-'Z' .or '_';\n" +"lex_next_identifier_character\n" +" 'a'-'z' .or 'A'-'Z' .or '0'-'9' .or '_';\n" +"err_token\n" +" '~' .or '`' .or '!' .or '@' .or '#' .or '$' .or '%' .or '^' .or '&' .or '*' .or '(' .or ')' .or\n" +" '-' .or '+' .or '=' .or '|' .or '\\\\' .or '[' .or ']' .or '{' .or '}' .or ':' .or ';' .or '\"' .or\n" +" '\\'' .or '<' .or ',' .or '>' .or '.' .or '/' .or '?' .or err_identifier;\n" +"err_identifier\n" +" id_character_first .and .loop id_character_next;\n" +"" diff --git a/nx-X11/extras/Mesa/src/mesa/shader/slang/library/slang_version_syn.h b/nx-X11/extras/Mesa/src/mesa/shader/slang/library/slang_version_syn.h new file mode 100644 index 000000000..3b94d8592 --- /dev/null +++ b/nx-X11/extras/Mesa/src/mesa/shader/slang/library/slang_version_syn.h @@ -0,0 +1,64 @@ +".syntax version_directive;\n" +"version_directive\n" +" version_directive_1 .and .loop version_directive_2;\n" +"version_directive_1\n" +" prior_optional_spaces .and optional_version_directive .and .true .emit $;\n" +"version_directive_2\n" +" prior_optional_spaces .and version_directive_body .and .true .emit $;\n" +"optional_version_directive\n" +" version_directive_body .or .true .emit 10 .emit 1;\n" +"version_directive_body\n" +" '#' .and optional_space .and \"version\" .and space .and version_number .and optional_space .and\n" +" new_line;\n" +"version_number\n" +" version_number_110;\n" +"version_number_110\n" +" leading_zeroes .and \"110\" .emit 10 .emit 1;\n" +"leading_zeroes\n" +" .loop zero;\n" +"zero\n" +" '0';\n" +"space\n" +" single_space .and .loop single_space;\n" +"optional_space\n" +" .loop single_space;\n" +"single_space\n" +" ' ' .or '\\t';\n" +"prior_optional_spaces\n" +" .loop prior_space;\n" +"prior_space\n" +" c_style_comment_block .or cpp_style_comment_block .or space .or new_line;\n" +"c_style_comment_block\n" +" '/' .and '*' .and c_style_comment_rest;\n" +"c_style_comment_rest\n" +" .loop c_style_comment_char_no_star .and c_style_comment_rest_1;\n" +"c_style_comment_rest_1\n" +" c_style_comment_end .or c_style_comment_rest_2;\n" +"c_style_comment_rest_2\n" +" '*' .and c_style_comment_rest;\n" +"c_style_comment_char_no_star\n" +" '\\x2B'-'\\xFF' .or '\\x01'-'\\x29';\n" +"c_style_comment_end\n" +" '*' .and '/';\n" +"cpp_style_comment_block\n" +" '/' .and '/' .and cpp_style_comment_block_1;\n" +"cpp_style_comment_block_1\n" +" cpp_style_comment_block_2 .or cpp_style_comment_block_3;\n" +"cpp_style_comment_block_2\n" +" .loop cpp_style_comment_char .and new_line;\n" +"cpp_style_comment_block_3\n" +" .loop cpp_style_comment_char;\n" +"cpp_style_comment_char\n" +" '\\x0E'-'\\xFF' .or '\\x01'-'\\x09' .or '\\x0B'-'\\x0C';\n" +"new_line\n" +" cr_lf .or lf_cr .or '\\n' .or '\\r';\n" +"cr_lf\n" +" '\\r' .and '\\n';\n" +"lf_cr\n" +" '\\n' .and '\\r';\n" +".string __string_filter;\n" +"__string_filter\n" +" .loop __identifier_char;\n" +"__identifier_char\n" +" 'a'-'z' .or 'A'-'Z' .or '_' .or '0'-'9';\n" +"" diff --git a/nx-X11/extras/Mesa/src/mesa/shader/slang/library/slang_vertex_builtin_gc.h b/nx-X11/extras/Mesa/src/mesa/shader/slang/library/slang_vertex_builtin_gc.h new file mode 100644 index 000000000..746226180 --- /dev/null +++ b/nx-X11/extras/Mesa/src/mesa/shader/slang/library/slang_vertex_builtin_gc.h @@ -0,0 +1,262 @@ +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"__fixed_output vec4 gl_Position;\n" +"__fixed_output float gl_PointSize;\n" +"__fixed_output vec4 gl_ClipVertex;\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"attribute vec4 gl_Color;\n" +"attribute vec4 gl_SecondaryColor;\n" +"attribute vec3 gl_Normal;\n" +"attribute vec4 gl_Vertex;\n" +"attribute vec4 gl_MultiTexCoord0;\n" +"attribute vec4 gl_MultiTexCoord1;\n" +"attribute vec4 gl_MultiTexCoord2;\n" +"attribute vec4 gl_MultiTexCoord3;\n" +"attribute vec4 gl_MultiTexCoord4;\n" +"attribute vec4 gl_MultiTexCoord5;\n" +"attribute vec4 gl_MultiTexCoord6;\n" +"attribute vec4 gl_MultiTexCoord7;\n" +"attribute float gl_FogCoord;\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"varying vec4 gl_FrontColor;\n" +"varying vec4 gl_BackColor;\n" +"varying vec4 gl_FrontSecondaryColor;\n" +"varying vec4 gl_BackSecondaryColor;\n" +"varying vec4 gl_TexCoord[];\n" +"varying float gl_FogFragCoord;\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"vec4 ftransform () {\n" +" return gl_ModelViewProjectionMatrix * gl_Vertex;\n" +"}\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"vec4 texture1DLod (sampler1D sampler, float coord, float lod) {\n" +" return vec4 (0.0);\n" +"}\n" +"vec4 texture1DProjLod (sampler1D sampler, vec2 coord, float lod) {\n" +" return texture1DLod (sampler, coord.s / coord.t, lod);\n" +"}\n" +"vec4 texture1DProjLod (sampler1D sampler, vec4 coord, float lod) {\n" +" return texture1DLod (sampler, coord.s / coord.q, lod);\n" +"}\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"vec4 texture2DLod (sampler2D sampler, vec2 coord, float lod) {\n" +" return vec4 (0.0);\n" +"}\n" +"vec4 texture2DProjLod (sampler2D sampler, vec3 coord, float lod) {\n" +" return texture2DLod (sampler, vec2 (coord.s / coord.p, coord.t / coord.p), lod);\n" +"}\n" +"vec4 texture2DProjLod (sampler2D sampler, vec4 coord, float lod) {\n" +" return texture2DLod (sampler, vec2 (coord.s / coord.q, coord.t / coord.q), lod);\n" +"}\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"vec4 texture3DLod (sampler3D sampler, vec3 coord, float lod) {\n" +" return vec4 (0.0);\n" +"}\n" +"vec4 texture3DProjLod (sampler3D sampler, vec4 coord, float lod) {\n" +" return texture3DLod (sampler, vec3 (coord.s / coord.q, coord.t / coord.q, coord.s / coord.q),\n" +" lod);\n" +"}\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"vec4 textureCubeLod (samplerCube sampler, vec3 coord, float lod) {\n" +" return vec4 (0.0);\n" +"}\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"\n" +"vec4 shadow1DLod (sampler1DShadow sampler, vec3 coord, float lod) {\n" +" return vec4 (0.0);\n" +"}\n" +"\n" +"vec4 shadow2DLod (sampler2DShadow sampler, vec3 coord, float lod) {\n" +" return vec4 (0.0);\n" +"}\n" +"vec4 shadow1DProjLod (sampler1DShadow sampler, vec4 coord, float lod) {\n" +" return shadow1DLod (sampler, vec3 (coord.s / coord.q, 0.0, coord.p / coord.q), lod);\n" +"}\n" +"vec4 shadow2DProjLod (sampler2DShadow sampler, vec4 coord, float lod) {\n" +" return shadow2DLod (sampler, vec3 (coord.s / coord.q, coord.t / coord.q, coord.p / coord.q),\n" +" lod);\n" +"}\n" +"\n" diff --git a/nx-X11/extras/Mesa/src/mesa/shader/slang/library/slang_vertex_builtin_gc_bin.h b/nx-X11/extras/Mesa/src/mesa/shader/slang/library/slang_vertex_builtin_gc_bin.h new file mode 100644 index 000000000..31d1fce3a --- /dev/null +++ b/nx-X11/extras/Mesa/src/mesa/shader/slang/library/slang_vertex_builtin_gc_bin.h @@ -0,0 +1,82 @@ +2,2,2,5,12,1,103,108,95,80,111,115,105,116,105,111,110,0,0,0,2,2,5,9, +1,103,108,95,80,111,105,110,116,83,105,122,101,0,0,0,2,2,5,12,1,103,108,95, +67,108,105,112,86,101,114,116,101,120,0,0,0,2,2,2,12,1,103,108,95,67,111,108, +111,114,0,0,0,2,2,2,12,1,103,108,95,83,101,99,111,110,100,97,114,121,67,111, +108,111,114,0,0,0,2,2,2,11,1,103,108,95,78,111,114,109,97,108,0,0,0,2, +2,2,12,1,103,108,95,86,101,114,116,101,120,0,0,0,2,2,2,12,1,103,108,95, +77,117,108,116,105,84,101,120,67,111,111,114,100,48,0,0,0,2,2,2,12,1,103,108, +95,77,117,108,116,105,84,101,120,67,111,111,114,100,49,0,0,0,2,2,2,12,1,103, +108,95,77,117,108,116,105,84,101,120,67,111,111,114,100,50,0,0,0,2,2,2,12,1, +103,108,95,77,117,108,116,105,84,101,120,67,111,111,114,100,51,0,0,0,2,2,2,12, +1,103,108,95,77,117,108,116,105,84,101,120,67,111,111,114,100,52,0,0,0,2,2,2, +12,1,103,108,95,77,117,108,116,105,84,101,120,67,111,111,114,100,53,0,0,0,2,2, +2,12,1,103,108,95,77,117,108,116,105,84,101,120,67,111,111,114,100,54,0,0,0,2, +2,2,12,1,103,108,95,77,117,108,116,105,84,101,120,67,111,111,114,100,55,0,0,0, +2,2,2,9,1,103,108,95,70,111,103,67,111,111,114,100,0,0,0,2,2,3,12,1, +103,108,95,70,114,111,110,116,67,111,108,111,114,0,0,0,2,2,3,12,1,103,108,95, +66,97,99,107,67,111,108,111,114,0,0,0,2,2,3,12,1,103,108,95,70,114,111,110, +116,83,101,99,111,110,100,97,114,121,67,111,108,111,114,0,0,0,2,2,3,12,1,103, +108,95,66,97,99,107,83,101,99,111,110,100,97,114,121,67,111,108,111,114,0,0,0,2, +2,3,12,1,103,108,95,84,101,120,67,111,111,114,100,0,4,0,2,2,3,9,1,103, +108,95,70,111,103,70,114,97,103,67,111,111,114,100,0,0,0,1,0,12,0,102,116,114, +97,110,115,102,111,114,109,0,0,1,8,18,103,108,95,77,111,100,101,108,86,105,101,119, +80,114,111,106,101,99,116,105,111,110,77,97,116,114,105,120,0,18,103,108,95,86,101,114, +116,101,120,0,48,0,0,1,0,12,0,116,101,120,116,117,114,101,49,68,76,111,100,0, +1,0,0,16,115,97,109,112,108,101,114,0,0,1,0,0,9,99,111,111,114,100,0,0, +1,0,0,9,108,111,100,0,0,0,1,8,58,118,101,99,52,0,17,48,0,48,0,0, +0,0,0,0,1,0,12,0,116,101,120,116,117,114,101,49,68,80,114,111,106,76,111,100, +0,1,0,0,16,115,97,109,112,108,101,114,0,0,1,0,0,10,99,111,111,114,100,0, +0,1,0,0,9,108,111,100,0,0,0,1,8,58,116,101,120,116,117,114,101,49,68,76, +111,100,0,18,115,97,109,112,108,101,114,0,0,18,99,111,111,114,100,0,59,115,0,18, +99,111,111,114,100,0,59,116,0,49,0,18,108,111,100,0,0,0,0,0,1,0,12,0, +116,101,120,116,117,114,101,49,68,80,114,111,106,76,111,100,0,1,0,0,16,115,97,109, +112,108,101,114,0,0,1,0,0,12,99,111,111,114,100,0,0,1,0,0,9,108,111,100, +0,0,0,1,8,58,116,101,120,116,117,114,101,49,68,76,111,100,0,18,115,97,109,112, +108,101,114,0,0,18,99,111,111,114,100,0,59,115,0,18,99,111,111,114,100,0,59,113, +0,49,0,18,108,111,100,0,0,0,0,0,1,0,12,0,116,101,120,116,117,114,101,50, +68,76,111,100,0,1,0,0,17,115,97,109,112,108,101,114,0,0,1,0,0,10,99,111, +111,114,100,0,0,1,0,0,9,108,111,100,0,0,0,1,8,58,118,101,99,52,0,17, +48,0,48,0,0,0,0,0,0,1,0,12,0,116,101,120,116,117,114,101,50,68,80,114, +111,106,76,111,100,0,1,0,0,17,115,97,109,112,108,101,114,0,0,1,0,0,11,99, +111,111,114,100,0,0,1,0,0,9,108,111,100,0,0,0,1,8,58,116,101,120,116,117, +114,101,50,68,76,111,100,0,18,115,97,109,112,108,101,114,0,0,58,118,101,99,50,0, +18,99,111,111,114,100,0,59,115,0,18,99,111,111,114,100,0,59,112,0,49,0,18,99, +111,111,114,100,0,59,116,0,18,99,111,111,114,100,0,59,112,0,49,0,0,0,18,108, +111,100,0,0,0,0,0,1,0,12,0,116,101,120,116,117,114,101,50,68,80,114,111,106, +76,111,100,0,1,0,0,17,115,97,109,112,108,101,114,0,0,1,0,0,12,99,111,111, +114,100,0,0,1,0,0,9,108,111,100,0,0,0,1,8,58,116,101,120,116,117,114,101, +50,68,76,111,100,0,18,115,97,109,112,108,101,114,0,0,58,118,101,99,50,0,18,99, +111,111,114,100,0,59,115,0,18,99,111,111,114,100,0,59,113,0,49,0,18,99,111,111, +114,100,0,59,116,0,18,99,111,111,114,100,0,59,113,0,49,0,0,0,18,108,111,100, +0,0,0,0,0,1,0,12,0,116,101,120,116,117,114,101,51,68,76,111,100,0,1,0, +0,18,115,97,109,112,108,101,114,0,0,1,0,0,11,99,111,111,114,100,0,0,1,0, +0,9,108,111,100,0,0,0,1,8,58,118,101,99,52,0,17,48,0,48,0,0,0,0, +0,0,1,0,12,0,116,101,120,116,117,114,101,51,68,80,114,111,106,76,111,100,0,1, +0,0,18,115,97,109,112,108,101,114,0,0,1,0,0,12,99,111,111,114,100,0,0,1, +0,0,9,108,111,100,0,0,0,1,8,58,116,101,120,116,117,114,101,51,68,76,111,100, +0,18,115,97,109,112,108,101,114,0,0,58,118,101,99,51,0,18,99,111,111,114,100,0, +59,115,0,18,99,111,111,114,100,0,59,113,0,49,0,18,99,111,111,114,100,0,59,116, +0,18,99,111,111,114,100,0,59,113,0,49,0,18,99,111,111,114,100,0,59,115,0,18, +99,111,111,114,100,0,59,113,0,49,0,0,0,18,108,111,100,0,0,0,0,0,1,0, +12,0,116,101,120,116,117,114,101,67,117,98,101,76,111,100,0,1,0,0,19,115,97,109, +112,108,101,114,0,0,1,0,0,11,99,111,111,114,100,0,0,1,0,0,9,108,111,100, +0,0,0,1,8,58,118,101,99,52,0,17,48,0,48,0,0,0,0,0,0,1,0,12, +0,115,104,97,100,111,119,49,68,76,111,100,0,1,0,0,20,115,97,109,112,108,101,114, +0,0,1,0,0,11,99,111,111,114,100,0,0,1,0,0,9,108,111,100,0,0,0,1, +8,58,118,101,99,52,0,17,48,0,48,0,0,0,0,0,0,1,0,12,0,115,104,97, +100,111,119,50,68,76,111,100,0,1,0,0,21,115,97,109,112,108,101,114,0,0,1,0, +0,11,99,111,111,114,100,0,0,1,0,0,9,108,111,100,0,0,0,1,8,58,118,101, +99,52,0,17,48,0,48,0,0,0,0,0,0,1,0,12,0,115,104,97,100,111,119,49, +68,80,114,111,106,76,111,100,0,1,0,0,20,115,97,109,112,108,101,114,0,0,1,0, +0,12,99,111,111,114,100,0,0,1,0,0,9,108,111,100,0,0,0,1,8,58,115,104, +97,100,111,119,49,68,76,111,100,0,18,115,97,109,112,108,101,114,0,0,58,118,101,99, +51,0,18,99,111,111,114,100,0,59,115,0,18,99,111,111,114,100,0,59,113,0,49,0, +17,48,0,48,0,0,0,18,99,111,111,114,100,0,59,112,0,18,99,111,111,114,100,0, +59,113,0,49,0,0,0,18,108,111,100,0,0,0,0,0,1,0,12,0,115,104,97,100, +111,119,50,68,80,114,111,106,76,111,100,0,1,0,0,21,115,97,109,112,108,101,114,0, +0,1,0,0,12,99,111,111,114,100,0,0,1,0,0,9,108,111,100,0,0,0,1,8, +58,115,104,97,100,111,119,50,68,76,111,100,0,18,115,97,109,112,108,101,114,0,0,58, +118,101,99,51,0,18,99,111,111,114,100,0,59,115,0,18,99,111,111,114,100,0,59,113, +0,49,0,18,99,111,111,114,100,0,59,116,0,18,99,111,111,114,100,0,59,113,0,49, +0,18,99,111,111,114,100,0,59,112,0,18,99,111,111,114,100,0,59,113,0,49,0,0, +0,18,108,111,100,0,0,0,0,0,0
\ No newline at end of file diff --git a/nx-X11/extras/Mesa/src/mesa/shader/slang/slang_assemble.c b/nx-X11/extras/Mesa/src/mesa/shader/slang/slang_assemble.c new file mode 100644 index 000000000..ef22a0172 --- /dev/null +++ b/nx-X11/extras/Mesa/src/mesa/shader/slang/slang_assemble.c @@ -0,0 +1,1208 @@ +/* + * Mesa 3-D graphics library + * Version: 6.3 + * + * Copyright (C) 2005 Brian Paul All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN + * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +/** + * \file slang_assemble.c + * slang intermediate code assembler + * \author Michal Krol + */ + +#include "imports.h" +#include "slang_utility.h" +#include "slang_assemble.h" +#include "slang_compile.h" +#include "slang_storage.h" +#include "slang_assemble_constructor.h" +#include "slang_assemble_typeinfo.h" +#include "slang_assemble_conditional.h" +#include "slang_assemble_assignment.h" + +/* slang_assembly */ + +static void slang_assembly_construct (slang_assembly *assem) +{ + assem->type = slang_asm_none; +} + +static void slang_assembly_destruct (slang_assembly *assem) +{ +} + +/* slang_assembly_file */ + +void slang_assembly_file_construct (slang_assembly_file *file) +{ + file->code = NULL; + file->count = 0; +} + +void slang_assembly_file_destruct (slang_assembly_file *file) +{ + unsigned int i; + + for (i = 0; i < file->count; i++) + slang_assembly_destruct (file->code + i); + slang_alloc_free (file->code); +} + +static int slang_assembly_file_push_new (slang_assembly_file *file) +{ + file->code = (slang_assembly *) slang_alloc_realloc (file->code, file->count * sizeof ( + slang_assembly), (file->count + 1) * sizeof (slang_assembly)); + if (file->code != NULL) + { + slang_assembly_construct (file->code + file->count); + file->count++; + return 1; + } + return 0; +} + +static int slang_assembly_file_push_general (slang_assembly_file *file, slang_assembly_type type, + GLfloat literal, GLuint label, GLuint size) +{ + slang_assembly *assem; + if (!slang_assembly_file_push_new (file)) + return 0; + assem = file->code + file->count - 1; + assem->type = type; + assem->literal = literal; + assem->param[0] = label; + assem->param[1] = size; + return 1; +} + +int slang_assembly_file_push (slang_assembly_file *file, slang_assembly_type type) +{ + return slang_assembly_file_push_general (file, type, (GLfloat) 0, 0, 0); +} + +int slang_assembly_file_push_label (slang_assembly_file *file, slang_assembly_type type, + GLuint label) +{ + return slang_assembly_file_push_general (file, type, (GLfloat) 0, label, 0); +} + +int slang_assembly_file_push_label2 (slang_assembly_file *file, slang_assembly_type type, + GLuint label1, GLuint label2) +{ + return slang_assembly_file_push_general (file, type, (GLfloat) 0, label1, label2); +} + +int slang_assembly_file_push_literal (slang_assembly_file *file, slang_assembly_type type, + GLfloat literal) +{ + return slang_assembly_file_push_general (file, type, literal, 0, 0); +} + +/* utility functions */ + +static int sizeof_variable (slang_type_specifier *spec, slang_type_qualifier qual, + slang_operation *array_size, slang_assembly_name_space *space, unsigned int *size) +{ + slang_storage_aggregate agg; + + slang_storage_aggregate_construct (&agg); + if (!_slang_aggregate_variable (&agg, spec, array_size, space->funcs, space->structs)) + { + slang_storage_aggregate_destruct (&agg); + return 0; + } + *size += _slang_sizeof_aggregate (&agg); + if (qual == slang_qual_out || qual == slang_qual_inout) + *size += 4; + slang_storage_aggregate_destruct (&agg); + return 1; +} + +static int sizeof_variable2 (slang_variable *var, slang_assembly_name_space *space, + unsigned int *size) +{ + var->address = *size; + if (var->type.qualifier == slang_qual_out || var->type.qualifier == slang_qual_inout) + var->address += 4; + return sizeof_variable (&var->type.specifier, var->type.qualifier, var->array_size, space, + size); +} + +static int sizeof_variables (slang_variable_scope *vars, unsigned int start, unsigned int stop, + slang_assembly_name_space *space, unsigned int *size) +{ + unsigned int i; + + for (i = start; i < stop; i++) + if (!sizeof_variable2 (vars->variables + i, space, size)) + return 0; + return 1; +} + +static int collect_locals (slang_operation *op, slang_assembly_name_space *space, + unsigned int *size) +{ + unsigned int i; + + if (!sizeof_variables (op->locals, 0, op->locals->num_variables, space, size)) + return 0; + for (i = 0; i < op->num_children; i++) + if (!collect_locals (op->children + i, space, size)) + return 0; + return 1; +} + +/* _slang_locate_function() */ + +slang_function *_slang_locate_function (const char *name, slang_operation *params, + unsigned int num_params, slang_assembly_name_space *space) +{ + unsigned int i; + + for (i = 0; i < space->funcs->num_functions; i++) + { + unsigned int j; + slang_function *f = space->funcs->functions + i; + + if (slang_string_compare (name, f->header.name) != 0) + continue; + if (f->param_count != num_params) + continue; + for (j = 0; j < num_params; j++) + { + slang_assembly_typeinfo ti; + slang_assembly_typeinfo_construct (&ti); + if (!_slang_typeof_operation (params + j, space, &ti)) + { + slang_assembly_typeinfo_destruct (&ti); + return 0; + } + if (!slang_type_specifier_equal (&ti.spec, &f->parameters->variables[j].type.specifier)) + { + slang_assembly_typeinfo_destruct (&ti); + break; + } + slang_assembly_typeinfo_destruct (&ti); + /* "out" and "inout" formal parameter requires the actual parameter to be l-value */ + if (!ti.can_be_referenced && + (f->parameters->variables[j].type.qualifier == slang_qual_out || + f->parameters->variables[j].type.qualifier == slang_qual_inout)) + break; + } + if (j == num_params) + return f; + } + if (space->funcs->outer_scope != NULL) + { + slang_assembly_name_space my_space = *space; + my_space.funcs = space->funcs->outer_scope; + return _slang_locate_function (name, params, num_params, &my_space); + } + return NULL; +} + +/* _slang_assemble_function() */ + +int _slang_assemble_function (slang_assembly_file *file, slang_function *fun, + slang_assembly_name_space *space) +{ + unsigned int param_size, local_size; + unsigned int skip, cleanup; + slang_assembly_flow_control flow; + slang_assembly_local_info info; + slang_assembly_stack_info stk; + + fun->address = file->count; + + if (fun->body == NULL) + { + /* TODO: jump to the actual function body */ + return 1; + } + + /* calculate return value and parameters size */ + param_size = 0; + if (fun->header.type.specifier.type != slang_spec_void) + if (!sizeof_variable (&fun->header.type.specifier, slang_qual_none, NULL, space, + ¶m_size)) + return 0; + info.ret_size = param_size; + if (!sizeof_variables (fun->parameters, 0, fun->param_count, space, ¶m_size)) + return 0; + + /* calculate local variables size, take into account the four-byte return address and + temporaries for various tasks */ + info.addr_tmp = param_size + 4; + info.swizzle_tmp = param_size + 4 + 4; + local_size = param_size + 4 + 4 + 16; + if (!sizeof_variables (fun->parameters, fun->param_count, fun->parameters->num_variables, space, + &local_size)) + return 0; + if (!collect_locals (fun->body, space, &local_size)) + return 0; + + /* allocate local variable storage */ + if (!slang_assembly_file_push_label (file, slang_asm_local_alloc, local_size - param_size - 4)) + return 0; + + /* mark a new frame for function variable storage */ + if (!slang_assembly_file_push_label (file, slang_asm_enter, local_size)) + return 0; + + /* skip the cleanup jump */ + skip = file->count; + if (!slang_assembly_file_push_new (file)) + return 0; + file->code[skip].type = slang_asm_jump; + + /* all "return" statements will be directed here */ + flow.function_end = file->count; + cleanup = file->count; + if (!slang_assembly_file_push_new (file)) + return 0; + file->code[cleanup].type = slang_asm_jump; + + /* execute the function body */ + file->code[skip].param[0] = file->count; + if (!_slang_assemble_operation (file, fun->body, 0, &flow, space, &info, &stk)) + return 0; + + /* this is the end of the function - restore the old function frame */ + file->code[cleanup].param[0] = file->count; + if (!slang_assembly_file_push (file, slang_asm_leave)) + return 0; + + /* free local variable storage */ + if (!slang_assembly_file_push_label (file, slang_asm_local_free, local_size - param_size - 4)) + return 0; + + /* jump out of the function */ + if (!slang_assembly_file_push (file, slang_asm_return)) + return 0; + return 1; +} + +int _slang_cleanup_stack (slang_assembly_file *file, slang_operation *op, int ref, + slang_assembly_name_space *space) +{ + slang_assembly_typeinfo ti; + unsigned int size; + + slang_assembly_typeinfo_construct (&ti); + if (!_slang_typeof_operation (op, space, &ti)) + { + slang_assembly_typeinfo_destruct (&ti); + return 0; + } + if (ti.spec.type == slang_spec_void) + size = 0; + else if (ref) + size = 4; + else + { + size = 0; + if (!sizeof_variable (&ti.spec, slang_qual_none, NULL, space, &size)) + { + slang_assembly_typeinfo_destruct (&ti); + return 0; + } + } + slang_assembly_typeinfo_destruct (&ti); + if (size != 0) + { + if (!slang_assembly_file_push_label (file, slang_asm_local_free, size)) + return 0; + } + return 1; +} + +/* _slang_assemble_operation() */ + +/* XXX: general swizzle! */ +static int dereference_aggregate (slang_assembly_file *file, const slang_storage_aggregate *agg, + unsigned int index, unsigned int *size, slang_assembly_local_info *info) +{ + unsigned int i; + + for (i = agg->count; i > 0; i--) + { + const slang_storage_array *arr = agg->arrays + i - 1; + unsigned int j; + + for (j = arr->length; j > 0; j--) + { + if (arr->type == slang_stor_aggregate) + { + if (!dereference_aggregate (file, arr->aggregate, index, size, info)) + return 0; + } + else + { + *size -= 4; + if (!slang_assembly_file_push_label2 (file, slang_asm_local_addr, info->addr_tmp, + 4)) + return 0; + if (!slang_assembly_file_push (file, slang_asm_addr_deref)) + return 0; + if (!slang_assembly_file_push_label (file, slang_asm_addr_push, *size)) + return 0; + if (!slang_assembly_file_push (file, slang_asm_addr_add)) + return 0; + switch (arr->type) + { + case slang_stor_bool: + if (!slang_assembly_file_push (file, slang_asm_bool_deref)) + return 0; + break; + case slang_stor_int: + if (!slang_assembly_file_push (file, slang_asm_int_deref)) + return 0; + break; + case slang_stor_float: + if (!slang_assembly_file_push (file, slang_asm_float_deref)) + return 0; + break; + } + index += 4; + } + } + } + return 1; +} +/* XXX: general swizzle! */ +int dereference (slang_assembly_file *file, slang_operation *op, + slang_assembly_name_space *space, slang_assembly_local_info *info) +{ + slang_assembly_typeinfo ti; + int result; + slang_storage_aggregate agg; + unsigned int size; + + slang_assembly_typeinfo_construct (&ti); + if (!_slang_typeof_operation (op, space, &ti)) + { + slang_assembly_typeinfo_destruct (&ti); + return 0; + } + + slang_storage_aggregate_construct (&agg); + if (!_slang_aggregate_variable (&agg, &ti.spec, NULL, space->funcs, space->structs)) + { + slang_storage_aggregate_destruct (&agg); + slang_assembly_typeinfo_destruct (&ti); + return 0; + } + + size = _slang_sizeof_aggregate (&agg); + result = dereference_aggregate (file, &agg, 0, &size, info); + + slang_storage_aggregate_destruct (&agg); + slang_assembly_typeinfo_destruct (&ti); + return result; +} + +static int call_function (slang_assembly_file *file, slang_function *fun, slang_operation *params, + unsigned int param_count, int assignment, slang_assembly_name_space *space, + slang_assembly_local_info *info) +{ + unsigned int i; + slang_assembly_stack_info stk; + + /* make room for the return value, if any */ + if (fun->header.type.specifier.type != slang_spec_void) + { + unsigned int ret_size = 0; + if (!sizeof_variable (&fun->header.type.specifier, slang_qual_none, NULL, space, &ret_size)) + return 0; + if (!slang_assembly_file_push_label (file, slang_asm_local_alloc, ret_size)) + return 0; + } + + /* push the actual parameters on the stack */ + for (i = 0; i < param_count; i++) + { + slang_assembly_flow_control flow; + + if (fun->parameters->variables[i].type.qualifier == slang_qual_inout || + fun->parameters->variables[i].type.qualifier == slang_qual_out) + { + if (!slang_assembly_file_push_label2 (file, slang_asm_local_addr, info->addr_tmp, 4)) + return 0; + /* TODO: optimize the "out" parameter case */ + /* TODO: inspect stk */ + if (!_slang_assemble_operation (file, params + i, 1, &flow, space, info, &stk)) + return 0; + if (!slang_assembly_file_push (file, slang_asm_addr_copy)) + return 0; + if (!slang_assembly_file_push (file, slang_asm_addr_deref)) + return 0; + if (i == 0 && assignment) + { + if (!slang_assembly_file_push_label2 (file, slang_asm_local_addr, info->addr_tmp, + 4)) + return 0; + if (!slang_assembly_file_push (file, slang_asm_addr_deref)) + return 0; + } + if (!dereference (file, params, space, info)) + return 0; + } + else + { + /* TODO: for "out" and "inout" parameters also push the address (first) */ + /* TODO: optimize the "out" parameter case */ + /* TODO: inspect stk */ + if (!_slang_assemble_operation (file, params + i, 0, &flow, space, info, &stk)) + return 0; + } + } + + /* call the function */ + if (!slang_assembly_file_push_label (file, slang_asm_call, fun->address)) + return 0; + + /* pop the parameters from the stack */ + for (i = param_count; i > 0; i--) + { + unsigned int j = i - 1; + if (fun->parameters->variables[j].type.qualifier == slang_qual_inout || + fun->parameters->variables[j].type.qualifier == slang_qual_out) + { + if (!_slang_assemble_assignment (file, params + j, space, info)) + return 0; + if (!slang_assembly_file_push_label (file, slang_asm_local_free, 4)) + return 0; + } + else + { + if (!_slang_cleanup_stack (file, params + j, 0, space)) + return 0; + } + } + + return 1; +} + +int call_function_name (slang_assembly_file *file, const char *name, slang_operation *params, + unsigned int param_count, int assignment, slang_assembly_name_space *space, + slang_assembly_local_info *info) +{ + slang_function *fun = _slang_locate_function (name, params, param_count, space); + if (fun == NULL) + return 0; + return call_function (file, fun, params, param_count, assignment, space, info); +} + +static int call_function_name_dummyint (slang_assembly_file *file, const char *name, + slang_operation *params, slang_assembly_name_space *space, slang_assembly_local_info *info) +{ + slang_operation p2[2]; + int result; + + p2[0] = *params; + if (!slang_operation_construct_a (p2 + 1)) + return 0; + p2[1].type = slang_oper_literal_int; + result = call_function_name (file, name, p2, 2, 0, space, info); + slang_operation_destruct (p2 + 1); + return result; +} + +static int call_asm_instruction (slang_assembly_file *file, const char *name) +{ + const struct + { + const char *name; + slang_assembly_type code1, code2; + } inst[] = { + { "float_to_int", slang_asm_float_to_int, slang_asm_int_copy }, + { "int_to_float", slang_asm_int_to_float, slang_asm_float_copy }, + { "float_copy", slang_asm_float_copy, slang_asm_none }, + { "int_copy", slang_asm_int_copy, slang_asm_none }, + { "bool_copy", slang_asm_bool_copy, slang_asm_none }, + { "float_add", slang_asm_float_add, slang_asm_float_copy }, + { "float_multiply", slang_asm_float_multiply, slang_asm_float_copy }, + { "float_divide", slang_asm_float_divide, slang_asm_float_copy }, + { "float_negate", slang_asm_float_negate, slang_asm_float_copy }, + { "float_less", slang_asm_float_less, slang_asm_bool_copy }, + { "float_equal", slang_asm_float_equal, slang_asm_bool_copy }, + { NULL, slang_asm_none, slang_asm_none } + }; + unsigned int i; + + for (i = 0; inst[i].name != NULL; i++) + if (slang_string_compare (name, inst[i].name) == 0) + break; + if (inst[i].name == NULL) + return 0; + + if (!slang_assembly_file_push_label2 (file, inst[i].code1, 4, 0)) + return 0; + if (inst[i].code2 != slang_asm_none) + if (!slang_assembly_file_push_label2 (file, inst[i].code2, 4, 0)) + return 0; + + /* clean-up the stack from the remaining dst address */ + if (!slang_assembly_file_push_label (file, slang_asm_local_free, 4)) + return 0; + + return 1; +} + +/* XXX: general swizzle! */ +static int equality_aggregate (slang_assembly_file *file, const slang_storage_aggregate *agg, + unsigned int *index, unsigned int size, slang_assembly_local_info *info, unsigned int z_label) +{ + unsigned int i; + + for (i = 0; i < agg->count; i++) + { + const slang_storage_array *arr = agg->arrays + i; + unsigned int j; + + for (j = 0; j < arr->length; j++) + { + if (arr->type == slang_stor_aggregate) + { + if (!equality_aggregate (file, arr->aggregate, index, size, info, z_label)) + return 0; + } + else + { + if (!slang_assembly_file_push_label2 (file, slang_asm_float_equal, size + *index, + *index)) + return 0; + *index += 4; + if (!slang_assembly_file_push_label (file, slang_asm_jump_if_zero, z_label)) + return 0; + } + } + } + return 1; +} +/* XXX: general swizzle! */ +static int equality (slang_assembly_file *file, slang_operation *op, + slang_assembly_name_space *space, slang_assembly_local_info *info, int equal) +{ + slang_assembly_typeinfo ti; + int result; + slang_storage_aggregate agg; + unsigned int index, size; + unsigned int skip_jump, true_label, true_jump, false_label, false_jump; + + /* get type of operation */ + slang_assembly_typeinfo_construct (&ti); + if (!_slang_typeof_operation (op, space, &ti)) + { + slang_assembly_typeinfo_destruct (&ti); + return 0; + } + + /* convert it to an aggregate */ + slang_storage_aggregate_construct (&agg); + if (!(result = _slang_aggregate_variable (&agg, &ti.spec, NULL, space->funcs, space->structs))) + goto end; + + /* compute the size of the agregate - there are two such aggregates on the stack */ + size = _slang_sizeof_aggregate (&agg); + + /* jump to the actual data-comparison code */ + skip_jump = file->count; + if (!(result = slang_assembly_file_push (file, slang_asm_jump))) + goto end; + + /* pop off the stack the compared data and push 1 */ + true_label = file->count; + if (!(result = slang_assembly_file_push_label (file, slang_asm_local_free, size * 2))) + goto end; + if (!(result = slang_assembly_file_push_literal (file, slang_asm_bool_push, 1.0f))) + goto end; + true_jump = file->count; + if (!(result = slang_assembly_file_push (file, slang_asm_jump))) + goto end; + + false_label = file->count; + if (!(result = slang_assembly_file_push_label (file, slang_asm_local_free, size * 2))) + goto end; + if (!(result = slang_assembly_file_push_literal (file, slang_asm_bool_push, 0.0f))) + goto end; + false_jump = file->count; + if (!(result = slang_assembly_file_push (file, slang_asm_jump))) + goto end; + + file->code[skip_jump].param[0] = file->count; + + /* compare the data on stack, it will eventually jump either to true or false label */ + index = 0; + if (!(result = equality_aggregate (file, &agg, &index, size, info, + equal ? false_label : true_label))) + goto end; + if (!(result = slang_assembly_file_push_label (file, slang_asm_jump, + equal ? true_label : false_label))) + goto end; + + file->code[true_jump].param[0] = file->count; + file->code[false_jump].param[0] = file->count; + + result = 1; +end: + slang_storage_aggregate_destruct (&agg); + slang_assembly_typeinfo_destruct (&ti); + return result; +} + +int _slang_assemble_operation (slang_assembly_file *file, slang_operation *op, int reference, + slang_assembly_flow_control *flow, slang_assembly_name_space *space, + slang_assembly_local_info *info, slang_assembly_stack_info *stk) +{ + unsigned int assem; + + stk->swizzle_mask = 0; + + assem = file->count; + if (!slang_assembly_file_push_new (file)) + return 0; + + switch (op->type) + { + case slang_oper_block_no_new_scope: + case slang_oper_block_new_scope: + { + unsigned int i; + for (i = 0; i < op->num_children; i++) + { + slang_assembly_stack_info stk; + if (!_slang_assemble_operation (file, op->children + i, 0, flow, space, info, &stk)) + return 0; + /* TODO: pass-in stk to cleanup */ + if (!_slang_cleanup_stack (file, op->children + i, 0, space)) + return 0; + } + } + break; + case slang_oper_variable_decl: + { + unsigned int i; + + for (i = 0; i < op->num_children; i++) + { + /* TODO: perform initialization of op->children[i] */ + /* TODO: clean-up stack */ + } + } + break; + case slang_oper_asm: + { + unsigned int i; + for (i = 0; i < op->num_children; i++) + { + slang_assembly_stack_info stk; + if (!_slang_assemble_operation (file, op->children + i, i == 0, flow, space, info, + &stk)) + return 0; + /* TODO: inspect stk */ + } + if (!call_asm_instruction (file, op->identifier)) + return 0; + } + break; + case slang_oper_break: + file->code[assem].type = slang_asm_jump; + file->code[assem].param[0] = flow->loop_end; + break; + case slang_oper_continue: + file->code[assem].type = slang_asm_jump; + file->code[assem].param[0] = flow->loop_start; + break; + case slang_oper_discard: + file->code[assem].type = slang_asm_discard; + if (!slang_assembly_file_push (file, slang_asm_exit)) + return 0; + break; + case slang_oper_return: + if (info->ret_size != 0) + { + slang_assembly_stack_info stk; + if (!slang_assembly_file_push_label2 (file, slang_asm_local_addr, 0, info->ret_size)) + return 0; + if (!_slang_assemble_operation (file, op->children, 0, flow, space, info, &stk)) + return 0; + /* TODO: inspect stk */ + if (!_slang_assemble_assignment (file, op->children, space, info)) + return 0; + if (!slang_assembly_file_push_label (file, slang_asm_local_free, 4)) + return 0; + } + if (!slang_assembly_file_push_label (file, slang_asm_jump, flow->function_end)) + return 0; + break; + case slang_oper_expression: + { + slang_assembly_stack_info stk; + if (!_slang_assemble_operation (file, op->children, reference, flow, space, info, &stk)) + return 0; + /* TODO: inspect stk */ + } + break; + case slang_oper_if: + if (!_slang_assemble_if (file, op, flow, space, info)) + return 0; + break; + case slang_oper_while: + if (!_slang_assemble_while (file, op, flow, space, info)) + return 0; + break; + case slang_oper_do: + if (!_slang_assemble_do (file, op, flow, space, info)) + return 0; + break; + case slang_oper_for: + if (!_slang_assemble_for (file, op, flow, space, info)) + return 0; + break; + case slang_oper_void: + break; + case slang_oper_literal_bool: + file->code[assem].type = slang_asm_bool_push; + file->code[assem].literal = op->literal; + break; + case slang_oper_literal_int: + file->code[assem].type = slang_asm_int_push; + file->code[assem].literal = op->literal; + break; + case slang_oper_literal_float: + file->code[assem].type = slang_asm_float_push; + file->code[assem].literal = op->literal; + break; + case slang_oper_identifier: + { + slang_variable *var; + unsigned int size; + var = _slang_locate_variable (op->locals, op->identifier, 1); + if (var == NULL) + return 0; + size = 0; + if (!sizeof_variable (&var->type.specifier, slang_qual_none, var->array_size, space, + &size)) + return 0; + if (var->initializer != NULL) + { + assert (!"var->initializer, oper_identifier"); + } + else + { + if (!reference) + { + if (!slang_assembly_file_push_label2 (file, slang_asm_local_addr, + info->addr_tmp, 4)) + return 0; + } + /* XXX: globals! */ + if (!slang_assembly_file_push_label2 (file, slang_asm_local_addr, var->address, + size)) + return 0; + if (!reference) + { + if (!slang_assembly_file_push (file, slang_asm_addr_copy)) + return 0; + if (!slang_assembly_file_push_label (file, slang_asm_local_free, 4)) + return 0; + if (!dereference (file, op, space, info)) + return 0; + } + } + } + break; + case slang_oper_sequence: + { + slang_assembly_stack_info stk; + if (!_slang_assemble_operation (file, op->children, 0, flow, space, info, &stk)) + return 0; + /* TODO: pass-in stk to cleanup */ + if (!_slang_cleanup_stack (file, op->children, 0, space)) + return 0; + if (!_slang_assemble_operation (file, op->children + 1, 0, flow, space, info, + &stk)) + return 0; + /* TODO: inspect stk */ + } + break; + case slang_oper_assign: + if (!_slang_assemble_assign (file, op, "=", reference, space, info)) + return 0; + break; + case slang_oper_addassign: + if (!_slang_assemble_assign (file, op, "+=", reference, space, info)) + return 0; + break; + case slang_oper_subassign: + if (!_slang_assemble_assign (file, op, "-=", reference, space, info)) + return 0; + break; + case slang_oper_mulassign: + if (!_slang_assemble_assign (file, op, "*=", reference, space, info)) + return 0; + break; + /*case slang_oper_modassign:*/ + /*case slang_oper_lshassign:*/ + /*case slang_oper_rshassign:*/ + /*case slang_oper_orassign:*/ + /*case slang_oper_xorassign:*/ + /*case slang_oper_andassign:*/ + case slang_oper_divassign: + if (!_slang_assemble_assign (file, op, "/=", reference, space, info)) + return 0; + break; + case slang_oper_select: + if (!_slang_assemble_select (file, op, flow, space, info)) + return 0; + break; + case slang_oper_logicalor: + if (!_slang_assemble_logicalor (file, op, flow, space, info)) + return 0; + break; + case slang_oper_logicaland: + if (!_slang_assemble_logicaland (file, op, flow, space, info)) + return 0; + break; + case slang_oper_logicalxor: + if (!call_function_name (file, "^^", op->children, 2, 0, space, info)) + return 0; + break; + /*case slang_oper_bitor:*/ + /*case slang_oper_bitxor:*/ + /*case slang_oper_bitand:*/ + case slang_oper_less: + if (!call_function_name (file, "<", op->children, 2, 0, space, info)) + return 0; + break; + case slang_oper_greater: + if (!call_function_name (file, ">", op->children, 2, 0, space, info)) + return 0; + break; + case slang_oper_lessequal: + if (!call_function_name (file, "<=", op->children, 2, 0, space, info)) + return 0; + break; + case slang_oper_greaterequal: + if (!call_function_name (file, ">=", op->children, 2, 0, space, info)) + return 0; + break; + /*case slang_oper_lshift:*/ + /*case slang_oper_rshift:*/ + case slang_oper_add: + if (!call_function_name (file, "+", op->children, 2, 0, space, info)) + return 0; + break; + case slang_oper_subtract: + if (!call_function_name (file, "-", op->children, 2, 0, space, info)) + return 0; + break; + case slang_oper_multiply: + if (!call_function_name (file, "*", op->children, 2, 0, space, info)) + return 0; + break; + /*case slang_oper_modulus:*/ + case slang_oper_divide: + if (!call_function_name (file, "/", op->children, 2, 0, space, info)) + return 0; + break; + case slang_oper_equal: + { + slang_assembly_stack_info stk; + if (!_slang_assemble_operation (file, op->children, 0, flow, space, info, &stk)) + return 0; + /* TODO: inspect stk */ + if (!_slang_assemble_operation (file, op->children + 1, 0, flow, space, info, &stk)) + return 0; + /* TODO: inspect stk */ + if (!equality (file, op->children, space, info, 1)) + return 0; + } + break; + case slang_oper_notequal: + { + slang_assembly_stack_info stk; + if (!_slang_assemble_operation (file, op->children, 0, flow, space, info, &stk)) + return 0; + /* TODO: inspect stk */ + if (!_slang_assemble_operation (file, op->children + 1, 0, flow, space, info, &stk)) + return 0; + /* TODO: inspect stk */ + if (!equality (file, op->children, space, info, 0)) + return 0; + } + break; + case slang_oper_preincrement: + if (!_slang_assemble_assign (file, op, "++", reference, space, info)) + return 0; + break; + case slang_oper_predecrement: + if (!_slang_assemble_assign (file, op, "--", reference, space, info)) + return 0; + break; + case slang_oper_plus: + if (!call_function_name (file, "+", op->children, 1, 0, space, info)) + return 0; + break; + case slang_oper_minus: + if (!call_function_name (file, "-", op->children, 1, 0, space, info)) + return 0; + break; + /*case slang_oper_complement:*/ + case slang_oper_not: + if (!call_function_name (file, "!", op->children, 1, 0, space, info)) + return 0; + break; + case slang_oper_subscript: + { + slang_assembly_stack_info _stk; + slang_assembly_typeinfo ti_arr, ti_elem; + unsigned int arr_size = 0, elem_size = 0; + if (!_slang_assemble_operation (file, op->children, reference, flow, space, info, + &_stk)) + return 0; + if (!_slang_assemble_operation (file, op->children + 1, 0, flow, space, info, &_stk)) + return 0; + slang_assembly_typeinfo_construct (&ti_arr); + if (!_slang_typeof_operation (op->children, space, &ti_arr)) + { + slang_assembly_typeinfo_destruct (&ti_arr); + return 0; + } + if (!sizeof_variable (&ti_arr.spec, slang_qual_none, NULL, space, &arr_size)) + { + slang_assembly_typeinfo_destruct (&ti_arr); + return 0; + } + slang_assembly_typeinfo_construct (&ti_elem); + if (!_slang_typeof_operation (op, space, &ti_elem)) + { + slang_assembly_typeinfo_destruct (&ti_arr); + slang_assembly_typeinfo_destruct (&ti_elem); + return 0; + } + if (!sizeof_variable (&ti_elem.spec, slang_qual_none, NULL, space, &elem_size)) + { + slang_assembly_typeinfo_destruct (&ti_arr); + slang_assembly_typeinfo_destruct (&ti_elem); + return 0; + } + if (!slang_assembly_file_push (file, slang_asm_int_to_addr)) + { + slang_assembly_typeinfo_destruct (&ti_arr); + slang_assembly_typeinfo_destruct (&ti_elem); + return 0; + } + if (!slang_assembly_file_push_label (file, slang_asm_addr_push, elem_size)) + { + slang_assembly_typeinfo_destruct (&ti_arr); + slang_assembly_typeinfo_destruct (&ti_elem); + return 0; + } + if (!slang_assembly_file_push (file, slang_asm_addr_multiply)) + { + slang_assembly_typeinfo_destruct (&ti_arr); + slang_assembly_typeinfo_destruct (&ti_elem); + return 0; + } + if (reference) + { + if (!slang_assembly_file_push (file, slang_asm_addr_add)) + { + slang_assembly_typeinfo_destruct (&ti_arr); + slang_assembly_typeinfo_destruct (&ti_elem); + return 0; + } + } + else + { + unsigned int i; + for (i = 0; i < elem_size; i += 4) + { + if (!slang_assembly_file_push_label2 (file, slang_asm_float_move, + arr_size - elem_size + i + 4, i + 4)) + { + slang_assembly_typeinfo_destruct (&ti_arr); + slang_assembly_typeinfo_destruct (&ti_elem); + return 0; + } + } + if (!slang_assembly_file_push_label (file, slang_asm_local_free, 4)) + { + slang_assembly_typeinfo_destruct (&ti_arr); + slang_assembly_typeinfo_destruct (&ti_elem); + return 0; + } + if (!slang_assembly_file_push_label (file, slang_asm_local_free, + arr_size - elem_size)) + { + slang_assembly_typeinfo_destruct (&ti_arr); + slang_assembly_typeinfo_destruct (&ti_elem); + return 0; + } + } + slang_assembly_typeinfo_destruct (&ti_arr); + slang_assembly_typeinfo_destruct (&ti_elem); + } + break; + case slang_oper_call: + { + slang_function *fun = _slang_locate_function (op->identifier, op->children, + op->num_children, space); + if (fun == NULL) + { + if (!_slang_assemble_constructor (file, op, flow, space, info)) + return 0; + } + else + { + if (!call_function (file, fun, op->children, op->num_children, 0, space, info)) + return 0; + } + } + break; + case slang_oper_field: + { + slang_assembly_typeinfo ti_after, ti_before; + slang_assembly_stack_info _stk; + slang_assembly_typeinfo_construct (&ti_after); + if (!_slang_typeof_operation (op, space, &ti_after)) + { + slang_assembly_typeinfo_destruct (&ti_after); + return 0; + } + slang_assembly_typeinfo_construct (&ti_before); + if (!_slang_typeof_operation (op->children, space, &ti_before)) + { + slang_assembly_typeinfo_destruct (&ti_after); + slang_assembly_typeinfo_destruct (&ti_before); + return 0; + } + if (!reference && ti_after.is_swizzled) + { + if (!slang_assembly_file_push_label2 (file, slang_asm_local_addr, + info->swizzle_tmp, 16)) + { + slang_assembly_typeinfo_destruct (&ti_after); + slang_assembly_typeinfo_destruct (&ti_before); + return 0; + } + } + if (!_slang_assemble_operation (file, op->children, reference, flow, space, info, + &_stk)) + { + slang_assembly_typeinfo_destruct (&ti_after); + slang_assembly_typeinfo_destruct (&ti_before); + return 0; + } + /* TODO: inspect stk */ + if (ti_after.is_swizzled) + { + if (reference) + { + if (ti_after.swz.num_components == 1) + { + if (!slang_assembly_file_push_label (file, slang_asm_addr_push, + ti_after.swz.swizzle[0] * 4)) + { + slang_assembly_typeinfo_destruct (&ti_after); + slang_assembly_typeinfo_destruct (&ti_before); + return 0; + } + if (!slang_assembly_file_push (file, slang_asm_addr_add)) + { + slang_assembly_typeinfo_destruct (&ti_after); + slang_assembly_typeinfo_destruct (&ti_before); + return 0; + } + } + else + { + unsigned int i; + for (i = 0; i < ti_after.swz.num_components; i++) + stk->swizzle_mask |= 1 << ti_after.swz.swizzle[i]; + } + } + else + { + if (!_slang_assemble_constructor_from_swizzle (file, &ti_after.swz, + &ti_after.spec, &ti_before.spec, info)) + { + slang_assembly_typeinfo_destruct (&ti_after); + slang_assembly_typeinfo_destruct (&ti_before); + return 0; + } + } + } + else + { + if (reference) + { + /* TODO: struct field address */ + } + else + { + /* TODO: struct field value */ + } + } + slang_assembly_typeinfo_destruct (&ti_after); + slang_assembly_typeinfo_destruct (&ti_before); + } + break; + case slang_oper_postincrement: + if (!call_function_name_dummyint (file, "++", op->children, space, info)) + return 0; + if (!dereference (file, op, space, info)) + return 0; + break; + case slang_oper_postdecrement: + if (!call_function_name_dummyint (file, "--", op->children, space, info)) + return 0; + if (!dereference (file, op, space, info)) + return 0; + break; + default: + return 0; + } + return 1; +} + + + + + + + + + +void xxx_first (slang_assembly_file *file) +{ + slang_assembly_file_push (file, slang_asm_jump); +} + +void xxx_prolog (slang_assembly_file *file, unsigned int addr) +{ + file->code[0].param[0] = file->count; + slang_assembly_file_push_label (file, slang_asm_call, addr); + slang_assembly_file_push (file, slang_asm_exit); +} + diff --git a/nx-X11/extras/Mesa/src/mesa/shader/slang/slang_assemble.h b/nx-X11/extras/Mesa/src/mesa/shader/slang/slang_assemble.h new file mode 100644 index 000000000..04ba7cf04 --- /dev/null +++ b/nx-X11/extras/Mesa/src/mesa/shader/slang/slang_assemble.h @@ -0,0 +1,145 @@ +/* + * Mesa 3-D graphics library + * Version: 6.3 + * + * Copyright (C) 2005 Brian Paul All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN + * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#if !defined SLANG_ASSEMBLE_H +#define SLANG_ASSEMBLE_H + +#include "slang_compile.h" + +#if defined __cplusplus +extern "C" { +#endif + +typedef enum slang_assembly_type_ +{ + /* core */ + slang_asm_none, + slang_asm_float_copy, + slang_asm_float_move, + slang_asm_float_push, + slang_asm_float_deref, + slang_asm_float_add, + slang_asm_float_multiply, + slang_asm_float_divide, + slang_asm_float_negate, + slang_asm_float_less, + slang_asm_float_equal, + slang_asm_float_to_int, + slang_asm_int_copy, + slang_asm_int_move, + slang_asm_int_push, + slang_asm_int_deref, + slang_asm_int_to_float, + slang_asm_int_to_addr, + slang_asm_bool_copy, + slang_asm_bool_move, + slang_asm_bool_push, + slang_asm_bool_deref, + slang_asm_addr_copy, + slang_asm_addr_push, + slang_asm_addr_deref, + slang_asm_addr_add, + slang_asm_addr_multiply, + slang_asm_jump, + slang_asm_jump_if_zero, + slang_asm_enter, + slang_asm_leave, + slang_asm_local_alloc, + slang_asm_local_free, + slang_asm_local_addr, + slang_asm_call, + slang_asm_return, + slang_asm_discard, + slang_asm_exit, + slang_asm__last +} slang_assembly_type; + +typedef struct slang_assembly_ +{ + slang_assembly_type type; + GLfloat literal; + GLuint param[2]; +} slang_assembly; + +typedef struct slang_assembly_file_ +{ + slang_assembly *code; + unsigned int count; +} slang_assembly_file; + +void slang_assembly_file_construct (slang_assembly_file *); +void slang_assembly_file_destruct (slang_assembly_file *); +int slang_assembly_file_push (slang_assembly_file *, slang_assembly_type); +int slang_assembly_file_push_label (slang_assembly_file *, slang_assembly_type, GLuint); +int slang_assembly_file_push_label2 (slang_assembly_file *, slang_assembly_type, GLuint, GLuint); +int slang_assembly_file_push_literal (slang_assembly_file *, slang_assembly_type, GLfloat); + +typedef struct slang_assembly_flow_control_ +{ + unsigned int loop_start; /* for "continue" statement */ + unsigned int loop_end; /* for "break" statement */ + unsigned int function_end; /* for "return" statement */ +} slang_assembly_flow_control; + +typedef struct slang_assembly_name_space_ +{ + struct slang_function_scope_ *funcs; + struct slang_struct_scope_ *structs; + struct slang_variable_scope_ *vars; +} slang_assembly_name_space; + +slang_function *_slang_locate_function (const char *name, slang_operation *params, + unsigned int num_params, slang_assembly_name_space *space); + +int _slang_assemble_function (slang_assembly_file *, struct slang_function_ *, + slang_assembly_name_space *); + +typedef struct slang_assembly_stack_info_ +{ + unsigned int swizzle_mask; +} slang_assembly_stack_info; + +int _slang_cleanup_stack (slang_assembly_file *, slang_operation *, int ref, + slang_assembly_name_space *); + +typedef struct slang_assembly_local_info_ +{ + unsigned int ret_size; + unsigned int addr_tmp; + unsigned int swizzle_tmp; +} slang_assembly_local_info; + +int _slang_assemble_operation (slang_assembly_file *, struct slang_operation_ *, int reference, + slang_assembly_flow_control *, slang_assembly_name_space *, slang_assembly_local_info *, + slang_assembly_stack_info *); + +void xxx_first (slang_assembly_file *); +void xxx_prolog (slang_assembly_file *, unsigned int); + +#ifdef __cplusplus +} +#endif + +#endif + diff --git a/nx-X11/extras/Mesa/src/mesa/shader/slang/slang_assemble_assignment.c b/nx-X11/extras/Mesa/src/mesa/shader/slang/slang_assemble_assignment.c new file mode 100644 index 000000000..488c7a91f --- /dev/null +++ b/nx-X11/extras/Mesa/src/mesa/shader/slang/slang_assemble_assignment.c @@ -0,0 +1,187 @@ +/* + * Mesa 3-D graphics library + * Version: 6.3 + * + * Copyright (C) 2005 Brian Paul All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN + * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +/** + * \file slang_assemble_assignment.c + * slang assignment expressions assembler + * \author Michal Krol + */ + +#include "imports.h" +#include "slang_assemble_assignment.h" +#include "slang_assemble_typeinfo.h" +#include "slang_storage.h" +#include "slang_utility.h" + +/* + _slang_assemble_assignment() + + copies values on the stack (<component 0> to <component N-1>) to a memory + location pointed by <addr of variable>; + + in: + +------------------+ + | addr of variable | + +------------------+ + | component N-1 | + | ... | + | component 0 | + +------------------+ + + out: + +------------------+ + | addr of variable | + +------------------+ +*/ +/* TODO: add support for swizzle mask */ +static int assign_aggregate (slang_assembly_file *file, const slang_storage_aggregate *agg, + unsigned int *index, unsigned int size, slang_assembly_local_info *info) +{ + unsigned int i; + + for (i = 0; i < agg->count; i++) + { + const slang_storage_array *arr = agg->arrays + i; + unsigned int j; + + for (j = 0; j < arr->length; j++) + { + if (arr->type == slang_stor_aggregate) + { + if (!assign_aggregate (file, arr->aggregate, index, size, info)) + return 0; + } + else + { + slang_assembly_type ty; + + switch (arr->type) + { + case slang_stor_bool: + ty = slang_asm_bool_copy; + break; + case slang_stor_int: + ty = slang_asm_int_copy; + break; + case slang_stor_float: + ty = slang_asm_float_copy; + break; + default: + break; + } + if (!slang_assembly_file_push_label2 (file, ty, size - *index, *index)) + return 0; + *index += 4; + } + } + } + return 1; +} + +int _slang_assemble_assignment (slang_assembly_file *file, slang_operation *op, + slang_assembly_name_space *space, slang_assembly_local_info *info) +{ + slang_assembly_typeinfo ti; + int result; + slang_storage_aggregate agg; + unsigned int index, size; + + slang_assembly_typeinfo_construct (&ti); + if (!_slang_typeof_operation (op, space, &ti)) + { + slang_assembly_typeinfo_destruct (&ti); + return 0; + } + + slang_storage_aggregate_construct (&agg); + if (!_slang_aggregate_variable (&agg, &ti.spec, NULL, space->funcs, space->structs)) + { + slang_storage_aggregate_destruct (&agg); + slang_assembly_typeinfo_destruct (&ti); + return 0; + } + + index = 0; + size = _slang_sizeof_aggregate (&agg); + result = assign_aggregate (file, &agg, &index, size, info); + + slang_storage_aggregate_destruct (&agg); + slang_assembly_typeinfo_destruct (&ti); + return result; +} + +/* + _slang_assemble_assign() + + performs unary (pre ++ and --) or binary (=, +=, -=, *=, /=) assignment on the operation's + children +*/ + +int dereference (slang_assembly_file *file, slang_operation *op, + slang_assembly_name_space *space, slang_assembly_local_info *info); + +int call_function_name (slang_assembly_file *file, const char *name, slang_operation *params, + unsigned int param_count, int assignment, slang_assembly_name_space *space, + slang_assembly_local_info *info); + +int _slang_assemble_assign (slang_assembly_file *file, slang_operation *op, const char *oper, + int ref, slang_assembly_name_space *space, slang_assembly_local_info *info) +{ + slang_assembly_stack_info stk; + slang_assembly_flow_control flow; + + if (!ref) + { + if (!slang_assembly_file_push_label2 (file, slang_asm_local_addr, info->addr_tmp, 4)) + return 0; + } + + if (slang_string_compare ("=", oper) == 0) + { + if (!_slang_assemble_operation (file, op->children, 1, &flow, space, info, &stk)) + return 0; + if (!_slang_assemble_operation (file, op->children + 1, 0, &flow, space, info, &stk)) + return 0; + if (!_slang_assemble_assignment (file, op->children, space, info)) + return 0; + } + else + { + if (!call_function_name (file, oper, op->children, op->num_children, 1, space, info)) + return 0; + } + + if (!ref) + { + if (!slang_assembly_file_push (file, slang_asm_addr_copy)) + return 0; + if (!slang_assembly_file_push_label (file, slang_asm_local_free, 4)) + return 0; + if (!dereference (file, op->children, space, info)) + return 0; + } + + return 1; +} + diff --git a/nx-X11/extras/Mesa/src/mesa/shader/slang/slang_assemble_assignment.h b/nx-X11/extras/Mesa/src/mesa/shader/slang/slang_assemble_assignment.h new file mode 100644 index 000000000..8ffd9e4cd --- /dev/null +++ b/nx-X11/extras/Mesa/src/mesa/shader/slang/slang_assemble_assignment.h @@ -0,0 +1,45 @@ +/* + * Mesa 3-D graphics library + * Version: 6.3 + * + * Copyright (C) 2005 Brian Paul All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN + * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#if !defined SLANG_ASSEMBLE_ASSIGNMENT_H +#define SLANG_ASSEMBLE_ASSIGNMENT_H + +#include "slang_assemble.h" + +#if defined __cplusplus +extern "C" { +#endif + +int _slang_assemble_assignment (slang_assembly_file *, slang_operation *, + slang_assembly_name_space *, slang_assembly_local_info *); + +int _slang_assemble_assign (slang_assembly_file *, slang_operation *, const char *, int ref, + slang_assembly_name_space *, slang_assembly_local_info *); + +#ifdef __cplusplus +} +#endif + +#endif + diff --git a/nx-X11/extras/Mesa/src/mesa/shader/slang/slang_assemble_conditional.c b/nx-X11/extras/Mesa/src/mesa/shader/slang/slang_assemble_conditional.c new file mode 100644 index 000000000..2347475f4 --- /dev/null +++ b/nx-X11/extras/Mesa/src/mesa/shader/slang/slang_assemble_conditional.c @@ -0,0 +1,485 @@ +/* + * Mesa 3-D graphics library + * Version: 6.3 + * + * Copyright (C) 2005 Brian Paul All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN + * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +/** + * \file slang_assemble_conditional.c + * slang condtional expressions assembler + * \author Michal Krol + */ + +#include "imports.h" +#include "slang_utility.h" +#include "slang_assemble_conditional.h" +#include "slang_assemble.h" + +/* _slang_assemble_logicaland() */ + +int _slang_assemble_logicaland (slang_assembly_file *file, slang_operation *op, + slang_assembly_flow_control *flow, slang_assembly_name_space *space, + slang_assembly_local_info *info) +{ + /* + and: + <left-expression> + jumpz zero + <right-expression> + jump end + zero: + push 0 + end: + */ + + unsigned int zero_jump, end_jump; + slang_assembly_stack_info stk; + + /* evaluate left expression */ + if (!_slang_assemble_operation (file, op->children, 0, flow, space, info, &stk)) + return 0; + /* TODO: inspect stk */ + + /* jump to pushing 0 if not true */ + zero_jump = file->count; + if (!slang_assembly_file_push (file, slang_asm_jump_if_zero)) + return 0; + + /* evaluate right expression */ + if (!_slang_assemble_operation (file, op->children + 1, 0, flow, space, info, &stk)) + return 0; + /* TODO: inspect stk */ + + /* jump to the end of the expression */ + end_jump = file->count; + if (!slang_assembly_file_push (file, slang_asm_jump)) + return 0; + + /* push 0 on stack */ + file->code[zero_jump].param[0] = file->count; + if (!slang_assembly_file_push (file, slang_asm_bool_push)) + return 0; + + /* the end of the expression */ + file->code[end_jump].param[0] = file->count; + + return 1; +} + +/* _slang_assemble_logicalor() */ + +int _slang_assemble_logicalor (slang_assembly_file *file, slang_operation *op, + slang_assembly_flow_control *flow, slang_assembly_name_space *space, + slang_assembly_local_info *info) +{ + /* + or: + <left-expression> + jumpz right + push 1 + jump end + right: + <right-expression> + end: + */ + + unsigned int right_jump, end_jump; + slang_assembly_stack_info stk; + + /* evaluate left expression */ + if (!_slang_assemble_operation (file, op->children, 0, flow, space, info, &stk)) + return 0; + /* TODO: inspect stk */ + + /* jump to evaluation of right expression if not true */ + right_jump = file->count; + if (!slang_assembly_file_push (file, slang_asm_jump_if_zero)) + return 0; + + /* push 1 on stack */ + if (!slang_assembly_file_push_literal (file, slang_asm_bool_push, 1.0f)) + return 0; + + /* jump to the end of the expression */ + end_jump = file->count; + if (!slang_assembly_file_push (file, slang_asm_jump)) + return 0; + + /* evaluate right expression */ + file->code[right_jump].param[0] = file->count; + if (!_slang_assemble_operation (file, op->children + 1, 0, flow, space, info, &stk)) + return 0; + /* TODO: inspect stk */ + + /* the end of the expression */ + file->code[end_jump].param[0] = file->count; + + return 1; +} + +/* _slang_assemble_select() */ + +int _slang_assemble_select (slang_assembly_file *file, slang_operation *op, + slang_assembly_flow_control *flow, slang_assembly_name_space *space, + slang_assembly_local_info *info) +{ + /* + select: + <condition-expression> + jumpz false + <true-expression> + jump end + false: + <false-expression> + end: + */ + + unsigned int cond_jump, end_jump; + slang_assembly_stack_info stk; + + /* execute condition expression */ + if (!_slang_assemble_operation (file, op->children, 0, flow, space, info, &stk)) + return 0; + /* TODO: inspect stk */ + + /* jump to false expression if not true */ + cond_jump = file->count; + if (!slang_assembly_file_push (file, slang_asm_jump_if_zero)) + return 0; + + /* execute true expression */ + if (!_slang_assemble_operation (file, op->children + 1, 0, flow, space, info, &stk)) + return 0; + /* TODO: inspect stk */ + + /* jump to the end of the expression */ + end_jump = file->count; + if (!slang_assembly_file_push (file, slang_asm_jump)) + return 0; + + /* resolve false point */ + file->code[cond_jump].param[0] = file->count; + + /* execute false expression */ + if (!_slang_assemble_operation (file, op->children + 2, 0, flow, space, info, &stk)) + return 0; + /* TODO: inspect stk */ + + /* resolve the end of the expression */ + file->code[end_jump].param[0] = file->count; + + return 1; +} + +/* _slang_assemble_for() */ + +int _slang_assemble_for (slang_assembly_file *file, slang_operation *op, + slang_assembly_flow_control *flow, slang_assembly_name_space *space, + slang_assembly_local_info *info) +{ + /* + for: + <init-statement> + jump start + break: + jump end + continue: + <loop-increment> + start: + <condition-statement> + jumpz end + <loop-body> + jump continue + end: + */ + + unsigned int start_jump, end_jump, cond_jump; + unsigned int break_label, cont_label; + slang_assembly_flow_control loop_flow = *flow; + slang_assembly_stack_info stk; + + /* execute initialization statement */ + if (!_slang_assemble_operation (file, op->children, 0, flow, space, info, &stk)) + return 0; + /* TODO: pass-in stk to cleanup */ + if (!_slang_cleanup_stack (file, op->children, 0, space)) + return 0; + + /* skip the "go to the end of the loop" and loop-increment statements */ + start_jump = file->count; + if (!slang_assembly_file_push (file, slang_asm_jump)) + return 0; + + /* go to the end of the loop - break statements are directed here */ + break_label = file->count; + end_jump = file->count; + if (!slang_assembly_file_push (file, slang_asm_jump)) + return 0; + + /* resolve the beginning of the loop - continue statements are directed here */ + cont_label = file->count; + + /* execute loop-increment statement */ + if (!_slang_assemble_operation (file, op->children + 2, 0, flow, space, info, &stk)) + return 0; + /* TODO: pass-in stk to cleanup */ + if (!_slang_cleanup_stack (file, op->children + 2, 0, space)) + return 0; + + /* resolve the condition point */ + file->code[start_jump].param[0] = file->count; + + /* execute condition statement */ + if (!_slang_assemble_operation (file, op->children + 1, 0, flow, space, info, &stk)) + return 0; + /* TODO: inspect stk */ + + /* jump to the end of the loop if not true */ + cond_jump = file->count; + if (!slang_assembly_file_push (file, slang_asm_jump_if_zero)) + return 0; + + /* execute loop body */ + loop_flow.loop_start = cont_label; + loop_flow.loop_end = break_label; + if (!_slang_assemble_operation (file, op->children + 3, 0, &loop_flow, space, info, &stk)) + return 0; + /* TODO: pass-in stk to cleanup */ + if (!_slang_cleanup_stack (file, op->children + 3, 0, space)) + return 0; + + /* go to the beginning of the loop */ + if (!slang_assembly_file_push_label (file, slang_asm_jump, cont_label)) + return 0; + + /* resolve the end of the loop */ + file->code[end_jump].param[0] = file->count; + file->code[cond_jump].param[0] = file->count; + + return 1; +} + +/* _slang_assemble_do() */ + +int _slang_assemble_do (slang_assembly_file *file, slang_operation *op, + slang_assembly_flow_control *flow, slang_assembly_name_space *space, + slang_assembly_local_info *info) +{ + /* + do: + jump start + break: + jump end + continue: + jump condition + start: + <loop-body> + condition: + <condition-statement> + jumpz end + jump start + end: + */ + + unsigned int skip_jump, end_jump, cont_jump, cond_jump; + unsigned int break_label, cont_label; + slang_assembly_flow_control loop_flow = *flow; + slang_assembly_stack_info stk; + + /* skip the "go to the end of the loop" and "go to condition" statements */ + skip_jump = file->count; + if (!slang_assembly_file_push (file, slang_asm_jump)) + return 0; + + /* go to the end of the loop - break statements are directed here */ + break_label = file->count; + end_jump = file->count; + if (!slang_assembly_file_push (file, slang_asm_jump)) + return 0; + + /* go to condition - continue statements are directed here */ + cont_label = file->count; + cont_jump = file->count; + if (!slang_assembly_file_push (file, slang_asm_jump)) + return 0; + + /* resolve the beginning of the loop */ + file->code[skip_jump].param[0] = file->count; + + /* execute loop body */ + loop_flow.loop_start = cont_label; + loop_flow.loop_end = break_label; + if (!_slang_assemble_operation (file, op->children, 0, &loop_flow, space, info, &stk)) + return 0; + /* TODO: pass-in stk to cleanup */ + if (!_slang_cleanup_stack (file, op->children, 0, space)) + return 0; + + /* resolve condition point */ + file->code[cont_jump].param[0] = file->count; + + /* execute condition statement */ + if (!_slang_assemble_operation (file, op->children + 1, 0, flow, space, info, &stk)) + return 0; + /* TODO: pass-in stk to cleanup */ + + /* jump to the end of the loop if not true */ + cond_jump = file->count; + if (!slang_assembly_file_push (file, slang_asm_jump_if_zero)) + return 0; + + /* jump to the beginning of the loop */ + if (!slang_assembly_file_push_label (file, slang_asm_jump, file->code[skip_jump].param[0])) + return 0; + + /* resolve the end of the loop */ + file->code[end_jump].param[0] = file->count; + file->code[cond_jump].param[0] = file->count; + + return 1; +} + +/* _slang_assemble_while() */ + +int _slang_assemble_while (slang_assembly_file *file, slang_operation *op, + slang_assembly_flow_control *flow, slang_assembly_name_space *space, + slang_assembly_local_info *info) +{ + /* + while: + jump continue + break: + jump end + continue: + <condition-statement> + jumpz end + <loop-body> + jump continue + end: + */ + + unsigned int skip_jump, end_jump, cond_jump; + unsigned int break_label; + slang_assembly_flow_control loop_flow = *flow; + slang_assembly_stack_info stk; + + /* skip the "go to the end of the loop" statement */ + skip_jump = file->count; + if (!slang_assembly_file_push (file, slang_asm_jump)) + return 0; + + /* go to the end of the loop - break statements are directed here */ + break_label = file->count; + end_jump = file->count; + if (!slang_assembly_file_push (file, slang_asm_jump)) + return 0; + + /* resolve the beginning of the loop - continue statements are directed here */ + file->code[skip_jump].param[0] = file->count; + + /* execute condition statement */ + if (!_slang_assemble_operation (file, op->children, 0, flow, space, info, &stk)) + return 0; + /* TODO: pass-in stk to cleanup */ + + /* jump to the end of the loop if not true */ + cond_jump = file->count; + if (!slang_assembly_file_push (file, slang_asm_jump_if_zero)) + return 0; + + /* execute loop body */ + loop_flow.loop_start = file->code[skip_jump].param[0]; + loop_flow.loop_end = break_label; + if (!_slang_assemble_operation (file, op->children + 1, 0, &loop_flow, space, info, &stk)) + return 0; + /* TODO: pass-in stk to cleanup */ + if (!_slang_cleanup_stack (file, op->children + 1, 0, space)) + return 0; + + /* jump to the beginning of the loop */ + if (!slang_assembly_file_push_label (file, slang_asm_jump, file->code[skip_jump].param[0])) + return 0; + + /* resolve the end of the loop */ + file->code[end_jump].param[0] = file->count; + file->code[cond_jump].param[0] = file->count; + + return 1; +} + +/* _slang_assemble_if() */ + +int _slang_assemble_if (slang_assembly_file *file, slang_operation *op, + slang_assembly_flow_control *flow, slang_assembly_name_space *space, + slang_assembly_local_info *info) +{ + /* + if: + <condition-statement> + jumpz else + <true-statement> + jump end + else: + <false-statement> + end: + */ + + unsigned int cond_jump, else_jump; + slang_assembly_stack_info stk; + + /* execute condition statement */ + if (!_slang_assemble_operation (file, op->children, 0, flow, space, info, &stk)) + return 0; + /* TODO: pass-in stk to cleanup */ + + /* jump to false-statement if not true */ + cond_jump = file->count; + if (!slang_assembly_file_push (file, slang_asm_jump_if_zero)) + return 0; + + /* execute true-statement */ + if (!_slang_assemble_operation (file, op->children + 1, 0, flow, space, info, &stk)) + return 0; + /* TODO: pass-in stk to cleanup */ + if (!_slang_cleanup_stack (file, op->children + 1, 0, space)) + return 0; + + /* skip if-false statement */ + else_jump = file->count; + if (!slang_assembly_file_push (file, slang_asm_jump)) + return 0; + + /* resolve start of false-statement */ + file->code[cond_jump].param[0] = file->count; + + /* execute false-statement */ + if (!_slang_assemble_operation (file, op->children + 2, 0, flow, space, info, &stk)) + return 0; + /* TODO: pass-in stk to cleanup */ + if (!_slang_cleanup_stack (file, op->children + 2, 0, space)) + return 0; + + /* resolve end of if-false statement */ + file->code[else_jump].param[0] = file->count; + + return 1; +} + diff --git a/nx-X11/extras/Mesa/src/mesa/shader/slang/slang_assemble_conditional.h b/nx-X11/extras/Mesa/src/mesa/shader/slang/slang_assemble_conditional.h new file mode 100644 index 000000000..b8defae68 --- /dev/null +++ b/nx-X11/extras/Mesa/src/mesa/shader/slang/slang_assemble_conditional.h @@ -0,0 +1,67 @@ +/* + * Mesa 3-D graphics library + * Version: 6.3 + * + * Copyright (C) 2005 Brian Paul All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN + * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#if !defined SLANG_ASSEMBLE_CONDITIONAL_H +#define SLANG_ASSEMBLE_CONDITIONAL_H + +#include "slang_assemble.h" + +#if defined __cplusplus +extern "C" { +#endif + +int _slang_assemble_logicaland (slang_assembly_file *file, slang_operation *op, + slang_assembly_flow_control *flow, slang_assembly_name_space *space, + slang_assembly_local_info *info); + +int _slang_assemble_logicalor (slang_assembly_file *file, slang_operation *op, + slang_assembly_flow_control *flow, slang_assembly_name_space *space, + slang_assembly_local_info *info); + +int _slang_assemble_select (slang_assembly_file *file, slang_operation *op, + slang_assembly_flow_control *flow, slang_assembly_name_space *space, + slang_assembly_local_info *info); + +int _slang_assemble_for (slang_assembly_file *file, slang_operation *op, + slang_assembly_flow_control *flow, slang_assembly_name_space *space, + slang_assembly_local_info *info); + +int _slang_assemble_do (slang_assembly_file *file, slang_operation *op, + slang_assembly_flow_control *flow, slang_assembly_name_space *space, + slang_assembly_local_info *info); + +int _slang_assemble_while (slang_assembly_file *file, slang_operation *op, + slang_assembly_flow_control *flow, slang_assembly_name_space *space, + slang_assembly_local_info *info); + +int _slang_assemble_if (slang_assembly_file *file, slang_operation *op, + slang_assembly_flow_control *flow, slang_assembly_name_space *space, + slang_assembly_local_info *info); + +#ifdef __cplusplus +} +#endif + +#endif + diff --git a/nx-X11/extras/Mesa/src/mesa/shader/slang/slang_assemble_constructor.c b/nx-X11/extras/Mesa/src/mesa/shader/slang/slang_assemble_constructor.c new file mode 100644 index 000000000..85ccea9e2 --- /dev/null +++ b/nx-X11/extras/Mesa/src/mesa/shader/slang/slang_assemble_constructor.c @@ -0,0 +1,339 @@ +/* + * Mesa 3-D graphics library + * Version: 6.3 + * + * Copyright (C) 2005 Brian Paul All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN + * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +/** + * \file slang_assemble_constructor.c + * slang constructor and vector swizzle assembler + * \author Michal Krol + */ + +#include "imports.h" +#include "slang_utility.h" +#include "slang_assemble_constructor.h" +#include "slang_assemble_typeinfo.h" +#include "slang_storage.h" + +/* _slang_is_swizzle() */ + +int _slang_is_swizzle (const char *field, unsigned int rows, slang_swizzle *swz) +{ + unsigned int i; + int xyzw = 0, rgba = 0, stpq = 0; + + /* the swizzle can be at most 4-component long */ + swz->num_components = slang_string_length (field); + if (swz->num_components > 4) + return 0; + + 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 = 1; + break; + case 'r': + case 'g': + case 'b': + case 'a': + rgba = 1; + break; + case 's': + case 't': + case 'p': + case 'q': + stpq = 1; + break; + default: + return 0; + } + + /* collect swizzle component */ + switch (field[i]) + { + case 'x': + case 'r': + case 's': + swz->swizzle[i] = 0; + break; + case 'y': + case 'g': + case 't': + if (rows < 2) + return 0; + swz->swizzle[i] = 1; + break; + case 'z': + case 'b': + case 'p': + if (rows < 3) + return 0; + swz->swizzle[i] = 2; + break; + case 'w': + case 'a': + case 'q': + if (rows < 4) + return 0; + swz->swizzle[i] = 3; + break; + } + } + + /* only one swizzle group can be used */ + if ((xyzw && rgba) || (xyzw && stpq) || (rgba && stpq)) + return 0; + + return 1; +} + +/* _slang_is_swizzle_mask() */ + +int _slang_is_swizzle_mask (const slang_swizzle *swz, unsigned int rows) +{ + unsigned int c, i; + + if (swz->num_components > rows) + return 0; + c = swz->swizzle[0]; + for (i = 1; i < swz->num_components; i++) + { + if (swz->swizzle[i] <= c) + return 0; + c = swz->swizzle[i]; + } + return 1; +} + +/* _slang_multiply_swizzles() */ + +void _slang_multiply_swizzles (slang_swizzle *dst, const slang_swizzle *left, + const slang_swizzle *right) +{ + unsigned int i; + dst->num_components = right->num_components; + for (i = 0; i < right->num_components; i++) + dst->swizzle[i] = left->swizzle[right->swizzle[i]]; +} + +/* _slang_assemble_constructor() */ + +static int constructor_aggregate (slang_assembly_file *file, const slang_storage_aggregate *flat, + unsigned int *index, slang_operation *op, unsigned int size, slang_assembly_flow_control *flow, + slang_assembly_name_space *space, slang_assembly_local_info *info) +{ + slang_assembly_typeinfo ti; + int result; + slang_storage_aggregate agg, flat_agg; + slang_assembly_stack_info stk; + unsigned int i; + + slang_assembly_typeinfo_construct (&ti); + if (!(result = _slang_typeof_operation (op, space, &ti))) + goto end1; + + slang_storage_aggregate_construct (&agg); + if (!(result = _slang_aggregate_variable (&agg, &ti.spec, NULL, space->funcs, space->structs))) + goto end2; + + slang_storage_aggregate_construct (&flat_agg); + if (!(result = _slang_flatten_aggregate (&flat_agg, &agg))) + goto end; + + if (!(result = _slang_assemble_operation (file, op, 0, flow, space, info, &stk))) + goto end; + + for (i = 0; i < flat_agg.count; i++) + { + const slang_storage_array *arr1 = flat_agg.arrays + i; + const slang_storage_array *arr2 = flat->arrays + *index; + + if (arr1->type != arr2->type) + { + /* TODO: convert (generic) from arr1 to arr2 */ + } + (*index)++; + /* TODO: watch the index, if it reaches the size, pop off the stack subsequent values */ + } + + result = 1; +end: + slang_storage_aggregate_destruct (&flat_agg); +end2: + slang_storage_aggregate_destruct (&agg); +end1: + slang_assembly_typeinfo_destruct (&ti); + return result; +} +/* XXX: general swizzle! */ +int _slang_assemble_constructor (slang_assembly_file *file, slang_operation *op, + slang_assembly_flow_control *flow, slang_assembly_name_space *space, + slang_assembly_local_info *info) +{ + slang_assembly_typeinfo ti; + int result; + slang_storage_aggregate agg, flat; + unsigned int size, index, i; + + slang_assembly_typeinfo_construct (&ti); + if (!(result = _slang_typeof_operation (op, space, &ti))) + goto end1; + + slang_storage_aggregate_construct (&agg); + if (!(result = _slang_aggregate_variable (&agg, &ti.spec, NULL, space->funcs, space->structs))) + goto end2; + + size = _slang_sizeof_aggregate (&agg); + + slang_storage_aggregate_construct (&flat); + if (!(result = _slang_flatten_aggregate (&flat, &agg))) + goto end; + + index = 0; + for (i = 0; i < op->num_children; i++) + { + if (!(result = constructor_aggregate (file, &flat, &index, op->children + i, size, flow, + space, info))) + goto end; + /* TODO: watch the index, if it reaches the size, raise an error */ + } + + result = 1; +end: + slang_storage_aggregate_destruct (&flat); +end2: + slang_storage_aggregate_destruct (&agg); +end1: + slang_assembly_typeinfo_destruct (&ti); + return result; +} + +/* _slang_assemble_constructor_from_swizzle() */ +/* XXX: wrong */ +int _slang_assemble_constructor_from_swizzle (slang_assembly_file *file, const slang_swizzle *swz, + slang_type_specifier *spec, slang_type_specifier *master_spec, slang_assembly_local_info *info) +{ + unsigned int master_rows, i; + switch (master_spec->type) + { + case slang_spec_bool: + case slang_spec_int: + case slang_spec_float: + master_rows = 1; + break; + case slang_spec_bvec2: + case slang_spec_ivec2: + case slang_spec_vec2: + master_rows = 2; + break; + case slang_spec_bvec3: + case slang_spec_ivec3: + case slang_spec_vec3: + master_rows = 3; + break; + case slang_spec_bvec4: + case slang_spec_ivec4: + case slang_spec_vec4: + master_rows = 4; + break; + default: + break; + } + for (i = 0; i < master_rows; i++) + { + switch (master_spec->type) + { + case slang_spec_bool: + case slang_spec_bvec2: + case slang_spec_bvec3: + case slang_spec_bvec4: + if (!slang_assembly_file_push_label2 (file, slang_asm_bool_copy, (master_rows - i) * 4, + i * 4)) + return 0; + break; + case slang_spec_int: + case slang_spec_ivec2: + case slang_spec_ivec3: + case slang_spec_ivec4: + if (!slang_assembly_file_push_label2 (file, slang_asm_int_copy, (master_rows - i) * 4, + i * 4)) + return 0; + break; + case slang_spec_float: + case slang_spec_vec2: + case slang_spec_vec3: + case slang_spec_vec4: + if (!slang_assembly_file_push_label2 (file, slang_asm_float_copy, + (master_rows - i) * 4, i * 4)) + return 0; + break; + default: + break; + } + } + if (!slang_assembly_file_push_label (file, slang_asm_local_free, 4)) + return 0; + for (i = swz->num_components; i > 0; i--) + { + unsigned int n = i - 1; + if (!slang_assembly_file_push_label2 (file, slang_asm_local_addr, info->swizzle_tmp, 16)) + return 0; + if (!slang_assembly_file_push_label (file, slang_asm_addr_push, swz->swizzle[n] * 4)) + return 0; + if (!slang_assembly_file_push (file, slang_asm_addr_add)) + return 0; + switch (master_spec->type) + { + case slang_spec_bool: + case slang_spec_bvec2: + case slang_spec_bvec3: + case slang_spec_bvec4: + if (!slang_assembly_file_push (file, slang_asm_bool_deref)) + return 0; + break; + case slang_spec_int: + case slang_spec_ivec2: + case slang_spec_ivec3: + case slang_spec_ivec4: + if (!slang_assembly_file_push (file, slang_asm_int_deref)) + return 0; + break; + case slang_spec_float: + case slang_spec_vec2: + case slang_spec_vec3: + case slang_spec_vec4: + if (!slang_assembly_file_push (file, slang_asm_float_deref)) + return 0; + break; + default: + break; + } + } + return 1; +} + diff --git a/nx-X11/extras/Mesa/src/mesa/shader/slang/slang_assemble_constructor.h b/nx-X11/extras/Mesa/src/mesa/shader/slang/slang_assemble_constructor.h new file mode 100644 index 000000000..31048bc7b --- /dev/null +++ b/nx-X11/extras/Mesa/src/mesa/shader/slang/slang_assemble_constructor.h @@ -0,0 +1,80 @@ +/* + * Mesa 3-D graphics library + * Version: 6.3 + * + * Copyright (C) 2005 Brian Paul All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN + * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#if !defined SLANG_ASSEMBLE_CONSTRUCTOR_H +#define SLANG_ASSEMBLE_CONSTRUCTOR_H + +#include "slang_assemble.h" +#include "slang_compile.h" + +#if defined __cplusplus +extern "C" { +#endif + +/* + holds a complete information about vector swizzle - the <swizzle> array contains + vector component sources indices, where 0 is "x", 1 is "y", ... + example: "xwz" --> { 3, { 0, 3, 2, n/u } } +*/ +typedef struct slang_swizzle_ +{ + unsigned int num_components; + unsigned int swizzle[4]; +} slang_swizzle; + +/* + 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 1 if this is the case, <swz> is filled with swizzle information + returns 0 otherwise +*/ +int _slang_is_swizzle (const char *field, unsigned int rows, slang_swizzle *swz); + +/* + checks if a general swizzle is an l-value swizzle - these swizzles do not have + duplicated fields and they are specified in order + returns 1 if this is a swizzle mask + returns 0 otherwise +*/ +int _slang_is_swizzle_mask (const slang_swizzle *swz, unsigned int rows); + +/* + combines two swizzles to form single swizzle + example: "wzyx.yx" --> "zw" +*/ +void _slang_multiply_swizzles (slang_swizzle *, const slang_swizzle *, const slang_swizzle *); + +int _slang_assemble_constructor (slang_assembly_file *file, slang_operation *op, + slang_assembly_flow_control *flow, slang_assembly_name_space *space, + slang_assembly_local_info *info); + +int _slang_assemble_constructor_from_swizzle (slang_assembly_file *file, const slang_swizzle *swz, + slang_type_specifier *spec, slang_type_specifier *master_spec, slang_assembly_local_info *info); + +#ifdef __cplusplus +} +#endif + +#endif + diff --git a/nx-X11/extras/Mesa/src/mesa/shader/slang/slang_assemble_typeinfo.c b/nx-X11/extras/Mesa/src/mesa/shader/slang/slang_assemble_typeinfo.c new file mode 100644 index 000000000..d2cae447a --- /dev/null +++ b/nx-X11/extras/Mesa/src/mesa/shader/slang/slang_assemble_typeinfo.c @@ -0,0 +1,430 @@ +/* + * Mesa 3-D graphics library + * Version: 6.3 + * + * Copyright (C) 2005 Brian Paul All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN + * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +/** + * \file slang_assemble_typeinfo.c + * slang type info + * \author Michal Krol + */ + +#include "imports.h" +#include "slang_utility.h" +#include "slang_assemble_typeinfo.h" + +/* slang_assembly_typeinfo */ + +void slang_assembly_typeinfo_construct (slang_assembly_typeinfo *ti) +{ + slang_type_specifier_construct (&ti->spec); +} + +void slang_assembly_typeinfo_destruct (slang_assembly_typeinfo *ti) +{ + slang_type_specifier_destruct (&ti->spec); +} + +/* _slang_typeof_operation() */ + +int _slang_typeof_operation (slang_operation *op, slang_assembly_name_space *space, + slang_assembly_typeinfo *ti) +{ + ti->can_be_referenced = 0; + ti->is_swizzled = 0; + + switch (op->type) + { + case slang_oper_block_no_new_scope: + case slang_oper_block_new_scope: + case slang_oper_variable_decl: + case slang_oper_asm: + case slang_oper_break: + case slang_oper_continue: + case slang_oper_discard: + case slang_oper_return: + case slang_oper_if: + case slang_oper_while: + case slang_oper_do: + case slang_oper_for: + case slang_oper_void: + ti->spec.type = slang_spec_void; + break; + case slang_oper_expression: + case slang_oper_assign: + case slang_oper_addassign: + case slang_oper_subassign: + case slang_oper_mulassign: + case slang_oper_divassign: + case slang_oper_preincrement: + case slang_oper_predecrement: + if (!_slang_typeof_operation (op->children, space, ti)) + return 0; + break; + case slang_oper_literal_bool: + case slang_oper_logicalor: + case slang_oper_logicalxor: + case slang_oper_logicaland: + case slang_oper_equal: + case slang_oper_notequal: + case slang_oper_less: + case slang_oper_greater: + case slang_oper_lessequal: + case slang_oper_greaterequal: + case slang_oper_not: + ti->spec.type = slang_spec_bool; + break; + case slang_oper_literal_int: + ti->spec.type = slang_spec_int; + break; + case slang_oper_literal_float: + ti->spec.type = slang_spec_float; + break; + case slang_oper_identifier: + { + slang_variable *var; + + var = _slang_locate_variable (op->locals, op->identifier, 1); + if (var == NULL) + return 0; + if (!slang_type_specifier_copy (&ti->spec, &var->type.specifier)) + return 0; + ti->can_be_referenced = 1; + } + break; + case slang_oper_sequence: + /* TODO: check [0] and [1] if they match */ + if (!_slang_typeof_operation (op->children + 1, space, ti)) + return 0; + ti->can_be_referenced = 0; + ti->is_swizzled = 0; + 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)) + return 0; + ti->can_be_referenced = 0; + ti->is_swizzled = 0; + 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: + { + int exists; + if (!_slang_typeof_function ("+", op->children, 2, space, &ti->spec, &exists)) + return 0; + if (!exists) + return 0; + } + break; + case slang_oper_subtract: + { + int exists; + if (!_slang_typeof_function ("-", op->children, 2, space, &ti->spec, &exists)) + return 0; + if (!exists) + return 0; + } + break; + case slang_oper_multiply: + { + int exists; + if (!_slang_typeof_function ("*", op->children, 2, space, &ti->spec, &exists)) + return 0; + if (!exists) + return 0; + } + break; + case slang_oper_divide: + { + int exists; + if (!_slang_typeof_function ("/", op->children, 2, space, &ti->spec, &exists)) + return 0; + if (!exists) + return 0; + } + break; + /*case slang_oper_modulus:*/ + case slang_oper_plus: + { + int exists; + if (!_slang_typeof_function ("+", op->children, 1, space, &ti->spec, &exists)) + return 0; + if (!exists) + return 0; + } + break; + case slang_oper_minus: + { + int exists; + if (!_slang_typeof_function ("-", op->children, 1, space, &ti->spec, &exists)) + return 0; + if (!exists) + return 0; + } + break; + /*case slang_oper_complement:*/ + case slang_oper_subscript: + { + slang_assembly_typeinfo _ti; + slang_assembly_typeinfo_construct (&_ti); + if (!_slang_typeof_operation (op->children, space, &_ti)) + { + slang_assembly_typeinfo_destruct (&_ti); + return 0; + } + ti->can_be_referenced = _ti.can_be_referenced; + switch (_ti.spec.type) + { + case slang_spec_bvec2: + case slang_spec_bvec3: + case slang_spec_bvec4: + ti->spec.type = slang_spec_bool; + break; + case slang_spec_ivec2: + case slang_spec_ivec3: + case slang_spec_ivec4: + ti->spec.type = slang_spec_int; + break; + case slang_spec_vec2: + case slang_spec_vec3: + case slang_spec_vec4: + ti->spec.type = slang_spec_float; + break; + case slang_spec_mat2: + ti->spec.type = slang_spec_vec2; + break; + case slang_spec_mat3: + ti->spec.type = slang_spec_vec3; + break; + case slang_spec_mat4: + ti->spec.type = slang_spec_vec4; + break; + case slang_spec_array: + if (!slang_type_specifier_copy (&ti->spec, _ti.spec._array)) + { + slang_assembly_typeinfo_destruct (&_ti); + return 0; + } + break; + default: + slang_assembly_typeinfo_destruct (&_ti); + return 0; + } + slang_assembly_typeinfo_destruct (&_ti); + } + break; + case slang_oper_call: + { + int exists; + if (!_slang_typeof_function (op->identifier, op->children, op->num_children, space, + &ti->spec, &exists)) + return 0; + if (!exists) + { + slang_struct *s = slang_struct_scope_find (space->structs, op->identifier, 1); + if (s != NULL) + { + ti->spec.type = slang_spec_struct; + ti->spec._struct = (slang_struct *) slang_alloc_malloc (sizeof (slang_struct)); + if (ti->spec._struct == NULL) + return 0; + if (!slang_struct_construct_a (ti->spec._struct)) + { + slang_alloc_free (ti->spec._struct); + ti->spec._struct = NULL; + return 0; + } + if (!slang_struct_copy (ti->spec._struct, s)) + return 0; + } + else + { + slang_type_specifier_type type = slang_type_specifier_type_from_string ( + op->identifier); + if (type == slang_spec_void) + return 0; + ti->spec.type = type; + } + } + } + break; + case slang_oper_field: + { + slang_assembly_typeinfo _ti; + slang_assembly_typeinfo_construct (&_ti); + if (!_slang_typeof_operation (op->children, space, &_ti)) + { + slang_assembly_typeinfo_destruct (&_ti); + return 0; + } + if (_ti.spec.type == slang_spec_struct) + { + slang_variable *field = _slang_locate_variable (_ti.spec._struct->fields, + op->identifier, 0); + if (field == NULL) + { + slang_assembly_typeinfo_destruct (&_ti); + return 0; + } + if (!slang_type_specifier_copy (&ti->spec, &field->type.specifier)) + { + slang_assembly_typeinfo_destruct (&_ti); + return 0; + } + } + else + { + unsigned int rows; + switch (_ti.spec.type) + { + case slang_spec_vec2: + case slang_spec_ivec2: + case slang_spec_bvec2: + rows = 2; + break; + case slang_spec_vec3: + case slang_spec_ivec3: + case slang_spec_bvec3: + rows = 3; + break; + case slang_spec_vec4: + case slang_spec_ivec4: + case slang_spec_bvec4: + rows = 4; + break; + default: + slang_assembly_typeinfo_destruct (&_ti); + return 0; + } + if (!_slang_is_swizzle (op->identifier, rows, &ti->swz)) + return 0; + ti->is_swizzled = 1; + ti->can_be_referenced = _ti.can_be_referenced && _slang_is_swizzle_mask (&ti->swz, + rows); + if (_ti.is_swizzled) + { + slang_swizzle swz; + _slang_multiply_swizzles (&swz, &_ti.swz, &ti->swz); + ti->swz = swz; + } + switch (_ti.spec.type) + { + case slang_spec_vec2: + case slang_spec_vec3: + case slang_spec_vec4: + switch (ti->swz.num_components) + { + case 1: + ti->spec.type = slang_spec_float; + break; + case 2: + ti->spec.type = slang_spec_vec2; + break; + case 3: + ti->spec.type = slang_spec_vec3; + break; + case 4: + ti->spec.type = slang_spec_vec4; + break; + } + break; + case slang_spec_ivec2: + case slang_spec_ivec3: + case slang_spec_ivec4: + switch (ti->swz.num_components) + { + case 1: + ti->spec.type = slang_spec_int; + break; + case 2: + ti->spec.type = slang_spec_ivec2; + break; + case 3: + ti->spec.type = slang_spec_ivec3; + break; + case 4: + ti->spec.type = slang_spec_ivec4; + break; + } + break; + case slang_spec_bvec2: + case slang_spec_bvec3: + case slang_spec_bvec4: + switch (ti->swz.num_components) + { + case 1: + ti->spec.type = slang_spec_bool; + break; + case 2: + ti->spec.type = slang_spec_bvec2; + break; + case 3: + ti->spec.type = slang_spec_bvec3; + break; + case 4: + ti->spec.type = slang_spec_bvec4; + break; + } + break; + default: + break; + } + } + slang_assembly_typeinfo_destruct (&_ti); + return 1; + } + break; + case slang_oper_postincrement: + case slang_oper_postdecrement: + if (!_slang_typeof_operation (op->children, space, ti)) + return 0; + ti->can_be_referenced = 0; + ti->is_swizzled = 0; + break; + default: + return 0; + } + return 1; +} + +/* _slang_typeof_function() */ + +int _slang_typeof_function (const char *name, slang_operation *params, unsigned int num_params, + slang_assembly_name_space *space, slang_type_specifier *spec, int *exists) +{ + slang_function *fun = _slang_locate_function (name, params, num_params, space); + *exists = fun != NULL; + if (fun == NULL) + return 1; + return slang_type_specifier_copy (spec, &fun->header.type.specifier); +} + diff --git a/nx-X11/extras/Mesa/src/mesa/shader/slang/slang_assemble_typeinfo.h b/nx-X11/extras/Mesa/src/mesa/shader/slang/slang_assemble_typeinfo.h new file mode 100644 index 000000000..fc1f3e3ae --- /dev/null +++ b/nx-X11/extras/Mesa/src/mesa/shader/slang/slang_assemble_typeinfo.h @@ -0,0 +1,67 @@ +/* + * Mesa 3-D graphics library + * Version: 6.3 + * + * Copyright (C) 2005 Brian Paul All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN + * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#if !defined SLANG_ASSEMBLE_TYPEINFO_H +#define SLANG_ASSEMBLE_TYPEINFO_H + +#include "slang_assemble_constructor.h" +#include "slang_compile.h" + +#if defined __cplusplus +extern "C" { +#endif + +typedef struct slang_assembly_typeinfo_ +{ + int can_be_referenced; + int is_swizzled; + slang_swizzle swz; + slang_type_specifier spec; +} slang_assembly_typeinfo; + +void slang_assembly_typeinfo_construct (slang_assembly_typeinfo *); +void slang_assembly_typeinfo_destruct (slang_assembly_typeinfo *); + +/* + retrieves type information about an operation + returns 1 on success + returns 0 otherwise +*/ +int _slang_typeof_operation (slang_operation *, slang_assembly_name_space *, + slang_assembly_typeinfo *); + +/* + retrieves type of a function prototype, if one exists + returns 1 on success, even if the function was not found + returns 0 otherwise +*/ +int _slang_typeof_function (const char *name, slang_operation *params, unsigned int num_params, + slang_assembly_name_space *space, slang_type_specifier *spec, int *exists); + +#ifdef __cplusplus +} +#endif + +#endif + diff --git a/nx-X11/extras/Mesa/src/mesa/shader/slang/slang_compile.c b/nx-X11/extras/Mesa/src/mesa/shader/slang/slang_compile.c new file mode 100644 index 000000000..2377173cf --- /dev/null +++ b/nx-X11/extras/Mesa/src/mesa/shader/slang/slang_compile.c @@ -0,0 +1,2369 @@ +/* + * Mesa 3-D graphics library + * Version: 6.3 + * + * Copyright (C) 2005 Brian Paul All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN + * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +/** + * \file slang_compile.c + * slang front-end compiler + * \author Michal Krol + */ + +#include "imports.h" +#include "grammar_mesa.h" +#include "slang_utility.h" +#include "slang_compile.h" +#include "slang_preprocess.h" +#include "slang_storage.h" +#include "slang_assemble.h" +#include "slang_execute.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. +*/ + +static void slang_variable_construct (slang_variable *); +static int slang_variable_copy (slang_variable *, const slang_variable *); +static void slang_struct_destruct (slang_struct *); +static int slang_struct_equal (const slang_struct *, const slang_struct *); +static void slang_variable_destruct (slang_variable *); + +/* slang_type_specifier_type */ + +/* these must match with slang_type_specifier_type enum */ +static const char *type_specifier_type_names[] = { + "void", + "bool", + "bvec2", + "bvec3", + "bvec4", + "int", + "ivec2", + "ivec3", + "ivec4", + "float", + "vec2", + "vec3", + "vec4", + "mat2", + "mat3", + "mat4", + "sampler1D", + "sampler2D", + "sampler3D", + "samplerCube", + "sampler1DShadow", + "sampler2DShadow", + NULL +}; + +slang_type_specifier_type slang_type_specifier_type_from_string (const char *name) +{ + const char **p = type_specifier_type_names; + while (*p != NULL) + { + if (slang_string_compare (*p, name) == 0) + return (slang_type_specifier_type) (p - type_specifier_type_names); + p++; + } + return slang_spec_void; +} + +/* slang_type_specifier */ + +void slang_type_specifier_construct (slang_type_specifier *spec) +{ + spec->type = slang_spec_void; + spec->_struct = NULL; + spec->_array = NULL; +} + +void slang_type_specifier_destruct (slang_type_specifier *spec) +{ + if (spec->_struct != NULL) + { + slang_struct_destruct (spec->_struct); + slang_alloc_free (spec->_struct); + } + if (spec->_array != NULL) + { + slang_type_specifier_destruct (spec->_array); + slang_alloc_free (spec->_array); + } +} + +int slang_type_specifier_copy (slang_type_specifier *x, const slang_type_specifier *y) +{ + slang_type_specifier_destruct (x); + slang_type_specifier_construct (x); + x->type = y->type; + if (x->type == slang_spec_struct) + { + x->_struct = (slang_struct *) slang_alloc_malloc (sizeof (slang_struct)); + if (x->_struct == NULL) + return 0; + if (!slang_struct_construct_a (x->_struct)) + { + slang_alloc_free (x->_struct); + x->_struct = NULL; + return 0; + } + return slang_struct_copy (x->_struct, y->_struct); + } + if (x->type == slang_spec_array) + { + x->_array = (slang_type_specifier *) slang_alloc_malloc (sizeof (slang_type_specifier)); + if (x->_array == NULL) + return 0; + slang_type_specifier_construct (x->_array); + return slang_type_specifier_copy (x->_array, y->_array); + } + return 1; +} + +int slang_type_specifier_equal (const slang_type_specifier *x, const slang_type_specifier *y) +{ + if (x->type != y->type) + return 0; + if (x->type == slang_spec_struct) + return slang_struct_equal (x->_struct, y->_struct); + if (x->type == slang_spec_array) + return slang_type_specifier_equal (x->_array, y->_array); + return 1; +} + +/* slang_fully_specified_type */ + +static void slang_fully_specified_type_construct (slang_fully_specified_type *type) +{ + type->qualifier = slang_qual_none; + slang_type_specifier_construct (&type->specifier); +} + +static void slang_fully_specified_type_destruct (slang_fully_specified_type *type) +{ + slang_type_specifier_destruct (&type->specifier); +} + +static int slang_fully_specified_type_copy (slang_fully_specified_type *x, + const slang_fully_specified_type *y) +{ + slang_fully_specified_type_construct (x); + slang_fully_specified_type_destruct (x); + x->qualifier = y->qualifier; + return slang_type_specifier_copy (&x->specifier, &y->specifier); +} + +/* slang_variable_scope */ + +static void slang_variable_scope_construct (slang_variable_scope *scope) +{ + scope->variables = NULL; + scope->num_variables = 0; + scope->outer_scope = NULL; +} + +static void slang_variable_scope_destruct (slang_variable_scope *scope) +{ + unsigned int i; + for (i = 0; i < scope->num_variables; i++) + slang_variable_destruct (scope->variables + i); + slang_alloc_free (scope->variables); +} + +static int slang_variable_scope_copy (slang_variable_scope *x, const slang_variable_scope *y) +{ + unsigned int i; + slang_variable_scope_destruct (x); + slang_variable_scope_construct (x); + x->variables = (slang_variable *) slang_alloc_malloc (y->num_variables * sizeof ( + slang_variable)); + if (x->variables == NULL) + return 0; + x->num_variables = y->num_variables; + for (i = 0; i < x->num_variables; i++) + slang_variable_construct (x->variables + i); + for (i = 0; i < x->num_variables; i++) + if (!slang_variable_copy (x->variables + i, y->variables + i)) + return 0; + x->outer_scope = y->outer_scope; + return 1; +} + +/* slang_operation */ + +int slang_operation_construct_a (slang_operation *oper) +{ + oper->type = slang_oper_none; + oper->children = NULL; + oper->num_children = 0; + oper->literal = (float) 0; + oper->identifier = NULL; + oper->locals = (slang_variable_scope *) slang_alloc_malloc (sizeof (slang_variable_scope)); + if (oper->locals == NULL) + return 0; + slang_variable_scope_construct (oper->locals); + return 1; +} + +void slang_operation_destruct (slang_operation *oper) +{ + unsigned int i; + for (i = 0; i < oper->num_children; i++) + slang_operation_destruct (oper->children + i); + slang_alloc_free (oper->children); + slang_alloc_free (oper->identifier); + slang_variable_scope_destruct (oper->locals); + slang_alloc_free (oper->locals); +} + +static int slang_operation_copy (slang_operation *x, const slang_operation *y) +{ + unsigned int i; + for (i = 0; i < x->num_children; i++) + slang_operation_destruct (x->children + i); + slang_alloc_free (x->children); + x->num_children = 0; + slang_alloc_free (x->identifier); + x->identifier = NULL; + slang_variable_scope_destruct (x->locals); + slang_variable_scope_construct (x->locals); + + x->type = y->type; + x->children = (slang_operation *) slang_alloc_malloc (y->num_children * sizeof ( + slang_operation)); + if (x->children == NULL) + return 0; + for (i = 0; i < y->num_children; i++) + if (!slang_operation_construct_a (x->children + i)) + { + unsigned int j; + for (j = 0; j < i; j++) + slang_operation_destruct (x->children + j); + slang_alloc_free (x->children); + x->children = NULL; + return 0; + } + x->num_children = y->num_children; + for (i = 0; i < x->num_children; i++) + if (!slang_operation_copy (x->children + i, y->children + i)) + return 0; + x->literal = y->literal; + if (y->identifier != NULL) + { + x->identifier = slang_string_duplicate (y->identifier); + if (x->identifier == NULL) + return 0; + } + if (!slang_variable_scope_copy (x->locals, y->locals)) + return 0; + return 1; +} + +/* slang_variable */ + +static void slang_variable_construct (slang_variable *var) +{ + slang_fully_specified_type_construct (&var->type); + var->name = NULL; + var->array_size = NULL; + var->initializer = NULL; + var->address = ~0; +} + +static void slang_variable_destruct (slang_variable *var) +{ + slang_fully_specified_type_destruct (&var->type); + slang_alloc_free (var->name); + if (var->array_size != NULL) + { + slang_operation_destruct (var->array_size); + slang_alloc_free (var->array_size); + } + if (var->initializer != NULL) + { + slang_operation_destruct (var->initializer); + slang_alloc_free (var->initializer); + } +} + +static int slang_variable_copy (slang_variable *x, const slang_variable *y) +{ + slang_variable_destruct (x); + slang_variable_construct (x); + if (!slang_fully_specified_type_copy (&x->type, &y->type)) + return 0; + if (y->name != NULL) + { + x->name = slang_string_duplicate (y->name); + if (x->name == NULL) + return 0; + } + if (y->array_size != NULL) + { + x->array_size = (slang_operation *) slang_alloc_malloc (sizeof (slang_operation)); + if (x->array_size == NULL) + return 0; + if (!slang_operation_construct_a (x->array_size)) + { + slang_alloc_free (x->array_size); + x->array_size = NULL; + return 0; + } + if (!slang_operation_copy (x->array_size, y->array_size)) + return 0; + } + if (y->initializer != NULL) + { + x->initializer = (slang_operation *) slang_alloc_malloc (sizeof (slang_operation)); + if (x->initializer == NULL) + return 0; + if (!slang_operation_construct_a (x->initializer)) + { + slang_alloc_free (x->initializer); + x->initializer = NULL; + return 0; + } + if (!slang_operation_copy (x->initializer, y->initializer)) + return 0; + } + return 1; +} + +slang_variable *_slang_locate_variable (slang_variable_scope *scope, const char *name, int all) +{ + unsigned int i; + for (i = 0; i < scope->num_variables; i++) + if (slang_string_compare (name, scope->variables[i].name) == 0) + return scope->variables + i; + if (all && scope->outer_scope != NULL) + return _slang_locate_variable (scope->outer_scope, name, 1); + return NULL; +} + +/* slang_struct_scope */ + +static void slang_struct_scope_construct (slang_struct_scope *scope) +{ + scope->structs = NULL; + scope->num_structs = 0; + scope->outer_scope = NULL; +} + +static void slang_struct_scope_destruct (slang_struct_scope *scope) +{ + unsigned int i; + for (i = 0; i < scope->num_structs; i++) + slang_struct_destruct (scope->structs + i); + slang_alloc_free (scope->structs); +} + +static int slang_struct_scope_copy (slang_struct_scope *x, const slang_struct_scope *y) +{ + unsigned int i; + slang_struct_scope_destruct (x); + slang_struct_scope_construct (x); + x->structs = (slang_struct *) slang_alloc_malloc (y->num_structs * sizeof (slang_struct)); + if (x->structs == NULL) + return 0; + x->num_structs = y->num_structs; + for (i = 0; i < x->num_structs; i++) + { + unsigned int j; + if (!slang_struct_construct_a (x->structs + i)) + { + for (j = 0; j < i; j++) + slang_struct_destruct (x->structs + j); + slang_alloc_free (x->structs); + x->structs = NULL; + return 0; + } + } + for (i = 0; i < x->num_structs; i++) + if (!slang_struct_copy (x->structs + i, y->structs + i)) + return 0; + x->outer_scope = y->outer_scope; + return 1; +} + +slang_struct *slang_struct_scope_find (slang_struct_scope *stru, const char *name, int all_scopes) +{ + unsigned int i; + for (i = 0; i < stru->num_structs; i++) + if (slang_string_compare (name, stru->structs[i].name) == 0) + return stru->structs + i; + if (all_scopes && stru->outer_scope != NULL) + return slang_struct_scope_find (stru->outer_scope, name, 1); + return NULL; +} + +/* slang_struct */ + +int slang_struct_construct_a (slang_struct *stru) +{ + stru->name = NULL; + stru->fields = (slang_variable_scope *) slang_alloc_malloc (sizeof (slang_variable_scope)); + if (stru->fields == NULL) + return 0; + slang_variable_scope_construct (stru->fields); + stru->structs = (slang_struct_scope *) slang_alloc_malloc (sizeof (slang_struct_scope)); + if (stru->structs == NULL) + { + slang_variable_scope_destruct (stru->fields); + slang_alloc_free (stru->fields); + return 0; + } + slang_struct_scope_construct (stru->structs); + return 1; +} + +static void slang_struct_destruct (slang_struct *stru) +{ + slang_alloc_free (stru->name); + slang_variable_scope_destruct (stru->fields); + slang_alloc_free (stru->fields); + slang_struct_scope_destruct (stru->structs); + slang_alloc_free (stru->structs); +} + +int slang_struct_copy (slang_struct *x, const slang_struct *y) +{ + slang_alloc_free (x->name); + x->name = NULL; + slang_variable_scope_destruct (x->fields); + slang_variable_scope_construct (x->fields); + slang_struct_scope_destruct (x->structs); + slang_struct_scope_construct (x->structs); + if (y->name != NULL) + { + x->name = slang_string_duplicate (y->name); + if (x->name == NULL) + return 0; + } + if (!slang_variable_scope_copy (x->fields, y->fields)) + return 0; + if (!slang_struct_scope_copy (x->structs, y->structs)) + return 0; + return 1; +} + +static int slang_struct_equal (const slang_struct *x, const slang_struct *y) +{ + unsigned int i; + if (x->fields->num_variables != y->fields->num_variables) + return 0; + for (i = 0; i < x->fields->num_variables; i++) + { + slang_variable *varx = x->fields->variables + i; + slang_variable *vary = y->fields->variables + i; + if (slang_string_compare (varx->name, vary->name) != 0) + return 0; + if (!slang_type_specifier_equal (&varx->type.specifier, &vary->type.specifier)) + return 0; + if (varx->type.specifier.type == slang_spec_array) + { + /* TODO compare array sizes */ + } + } + return 1; +} + +/* slang_function */ +/* XXX mem! */ +static void slang_function_construct (slang_function *func) +{ + func->kind = slang_func_ordinary; + slang_variable_construct (&func->header); + func->parameters = (slang_variable_scope *) slang_alloc_malloc (sizeof (slang_variable_scope)); + slang_variable_scope_construct (func->parameters); + func->body = NULL; + func->address = ~0; +} + +static void slang_function_destruct (slang_function *func) +{ + slang_variable_destruct (&func->header); + slang_variable_scope_destruct (func->parameters); + slang_alloc_free (func->parameters); + if (func->body != NULL) + { + slang_operation_destruct (func->body); + slang_alloc_free (func->body); + } +} + +/* slang_function_scope */ + +static void slang_function_scope_construct (slang_function_scope *scope) +{ + scope->functions = NULL; + scope->num_functions = 0; + scope->outer_scope = NULL; +} + +static 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_alloc_free (scope->functions); +} + +static int slang_function_scope_find_by_name (slang_function_scope *funcs, const char *name, + int all_scopes) +{ + unsigned int i; + for (i = 0; i < funcs->num_functions; i++) + if (slang_string_compare (name, funcs->functions[i].header.name) == 0) + return 1; + if (all_scopes && funcs->outer_scope != NULL) + return slang_function_scope_find_by_name (funcs->outer_scope, name, 1); + return 0; +} + +static 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; + unsigned int j; + if (slang_string_compare (fun->header.name, f->header.name) != 0) + continue; + if (fun->param_count != f->param_count) + continue; + for (j = 0; 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) + return f; + } + if (all_scopes && funcs->outer_scope != NULL) + return slang_function_scope_find (funcs->outer_scope, fun, 1); + return NULL; +} + +/* slang_translation_unit */ + +void slang_translation_unit_construct (slang_translation_unit *unit) +{ + slang_variable_scope_construct (&unit->globals); + slang_function_scope_construct (&unit->functions); + slang_struct_scope_construct (&unit->structs); +} + +void slang_translation_unit_destruct (slang_translation_unit *unit) +{ + slang_variable_scope_destruct (&unit->globals); + slang_function_scope_destruct (&unit->functions); + slang_struct_scope_destruct (&unit->structs); +} + +/* slang_info_log */ + +static char *out_of_memory = "error: out of memory\n"; + +void slang_info_log_construct (slang_info_log *log) +{ + log->text = NULL; + log->dont_free_text = 0; +} + +void slang_info_log_destruct (slang_info_log *log) +{ + if (!log->dont_free_text) + slang_alloc_free (log->text); +} + +static int slang_info_log_message (slang_info_log *log, const char *prefix, const char *msg) +{ + unsigned int new_size; + if (log->dont_free_text) + return 0; + new_size = slang_string_length (prefix) + 3 + slang_string_length (msg); + if (log->text != NULL) + { + log->text = (char *) slang_alloc_realloc (log->text, slang_string_length (log->text) + 1, + new_size + slang_string_length (log->text) + 1); + } + else + { + log->text = (char *) slang_alloc_malloc (new_size + 1); + if (log->text != NULL) + *log->text = '\0'; + } + if (log->text == NULL) + return 0; + 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_error (slang_info_log *log, const char *msg, ...) +{ + va_list va; + char buf[1024]; + + va_start (va, msg); + vsprintf (buf, msg, va); + if (slang_info_log_message (log, "error", buf)) + return 1; + slang_info_log_memory (log); + va_end (va); + 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); + if (slang_info_log_message (log, "warning", buf)) + return 1; + slang_info_log_memory (log); + va_end (va); + return 0; +} + +void slang_info_log_memory (slang_info_log *log) +{ + if (!slang_info_log_message (log, "error", "out of memory")) + { + log->dont_free_text = 1; + log->text = out_of_memory; + } +} + +/* slang_parse_ctx */ + +typedef struct slang_parse_ctx_ +{ + const byte *I; + slang_info_log *L; + int parsing_builtin; +} slang_parse_ctx; + +/* _slang_compile() */ + +static int parse_identifier (slang_parse_ctx *C, char **id) +{ + *id = slang_string_duplicate ((const char *) C->I); + if (*id == NULL) + { + slang_info_log_memory (C->L); + return 0; + } + C->I += strlen ((const char *) C->I) + 1; + return 1; +} + +static int parse_number (slang_parse_ctx *C, int *number) +{ + const int radix = (int) (*C->I++); + *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) +{ + char *integral = NULL; + char *fractional = NULL; + char *exponent = NULL; + char *whole = NULL; + + if (!parse_identifier (C, &integral)) + return 0; + + if (!parse_identifier (C, &fractional)) + { + slang_alloc_free (integral); + return 0; + } + + if (!parse_identifier (C, &exponent)) + { + slang_alloc_free (fractional); + slang_alloc_free (integral); + return 0; + } + + whole = (char *) (slang_alloc_malloc ((strlen (integral) + strlen (fractional) + strlen ( + exponent) + 3) * sizeof (char))); + if (whole == NULL) + { + slang_alloc_free (exponent); + slang_alloc_free (fractional); + slang_alloc_free (integral); + slang_info_log_memory (C->L); + return 0; + } + + 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 = (float) (atof (whole)); + + slang_alloc_free (whole); + slang_alloc_free (exponent); + slang_alloc_free (fractional); + slang_alloc_free (integral); + return 1; +} + +/* revision number - increment after each change affecting emitted output */ +#define REVISION 2 + +static int check_revision (slang_parse_ctx *C) +{ + if (*C->I != REVISION) + { + slang_info_log_error (C->L, "internal compiler error"); + return 0; + } + C->I++; + return 1; +} + +static int parse_statement (slang_parse_ctx *, slang_operation *, slang_variable_scope *, + slang_struct_scope *, slang_function_scope *); +static int parse_expression (slang_parse_ctx *, slang_operation *, slang_variable_scope *, + slang_struct_scope *, slang_function_scope *); + +/* 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) +{ + switch (*C->I++) + { + 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: + return 0; + } + 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_STRUCT 22 +#define TYPE_SPECIFIER_TYPENAME 23 + +/* structure field */ +#define FIELD_NONE 0 +#define FIELD_NEXT 1 +#define FIELD_ARRAY 2 + +static int parse_type_specifier (slang_parse_ctx *C, slang_type_specifier *spec, + slang_struct_scope *structs, slang_variable_scope *scope, slang_function_scope *funcs) +{ + switch (*C->I++) + { + 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_SAMPLER1D: + spec->type = slang_spec_sampler1D; + break; + case TYPE_SPECIFIER_SAMPLER2D: + spec->type = slang_spec_sampler2D; + break; + case TYPE_SPECIFIER_SAMPLER3D: + spec->type = slang_spec_sampler3D; + break; + case TYPE_SPECIFIER_SAMPLERCUBE: + spec->type = slang_spec_samplerCube; + break; + case TYPE_SPECIFIER_SAMPLER1DSHADOW: + spec->type = slang_spec_sampler1DShadow; + break; + case TYPE_SPECIFIER_SAMPLER2DSHADOW: + spec->type = slang_spec_sampler2DShadow; + break; + case TYPE_SPECIFIER_STRUCT: + spec->type = slang_spec_struct; + { + char *name; + if (!parse_identifier (C, &name)) + return 0; + if (*name != '\0' && slang_struct_scope_find (structs, name, 0) != NULL) + { + slang_info_log_error (C->L, "%s: duplicate type name", name); + slang_alloc_free (name); + return 0; + } + spec->_struct = (slang_struct *) slang_alloc_malloc (sizeof (slang_struct)); + if (spec->_struct == NULL) + { + slang_alloc_free (name); + slang_info_log_memory (C->L); + return 0; + } + if (!slang_struct_construct_a (spec->_struct)) + { + slang_alloc_free (spec->_struct); + spec->_struct = NULL; + slang_alloc_free (name); + slang_info_log_memory (C->L); + return 0; + } + spec->_struct->name = name; + spec->_struct->structs->outer_scope = structs; + } + do + { + slang_type_specifier sp; + slang_type_specifier_construct (&sp); + if (!parse_type_specifier (C, &sp, spec->_struct->structs, scope, funcs)) + { + slang_type_specifier_destruct (&sp); + return 0; + } + do + { + slang_variable *var; + spec->_struct->fields->variables = (slang_variable *) slang_alloc_realloc ( + spec->_struct->fields->variables, + spec->_struct->fields->num_variables * sizeof (slang_variable), + (spec->_struct->fields->num_variables + 1) * sizeof (slang_variable)); + if (spec->_struct->fields->variables == NULL) + { + slang_type_specifier_destruct (&sp); + slang_info_log_memory (C->L); + return 0; + } + var = spec->_struct->fields->variables + spec->_struct->fields->num_variables; + spec->_struct->fields->num_variables++; + slang_variable_construct (var); + if (!slang_type_specifier_copy (&var->type.specifier, &sp)) + { + slang_type_specifier_destruct (&sp); + return 0; + } + if (!parse_identifier (C, &var->name)) + { + slang_type_specifier_destruct (&sp); + return 0; + } + switch (*C->I++) + { + case FIELD_NONE: + break; + case FIELD_ARRAY: + var->array_size = (slang_operation *) slang_alloc_malloc (sizeof ( + slang_operation)); + if (var->array_size == NULL) + { + slang_type_specifier_destruct (&sp); + slang_info_log_memory (C->L); + return 0; + } + if (!slang_operation_construct_a (var->array_size)) + { + slang_alloc_free (var->array_size); + var->array_size = NULL; + slang_type_specifier_destruct (&sp); + slang_info_log_memory (C->L); + return 0; + } + if (!parse_expression (C, var->array_size, scope, structs, funcs)) + { + slang_type_specifier_destruct (&sp); + return 0; + } + break; + default: + return 0; + } + } + while (*C->I++ != FIELD_NONE); + } + while (*C->I++ != FIELD_NONE); + if (*spec->_struct->name != '\0') + { + slang_struct *s; + structs->structs = (slang_struct *) slang_alloc_realloc (structs->structs, + structs->num_structs * sizeof (slang_struct), + (structs->num_structs + 1) * sizeof (slang_struct)); + if (structs->structs == NULL) + { + slang_info_log_memory (C->L); + return 0; + } + s = structs->structs + structs->num_structs; + if (!slang_struct_construct_a (s)) + return 0; + structs->num_structs++; + if (!slang_struct_copy (s, spec->_struct)) + return 0; + } + break; + case TYPE_SPECIFIER_TYPENAME: + spec->type = slang_spec_struct; + { + char *name; + slang_struct *stru; + if (!parse_identifier (C, &name)) + return 0; + stru = slang_struct_scope_find (structs, name, 1); + if (stru == NULL) + { + slang_info_log_error (C->L, "%s: undeclared type name", name); + slang_alloc_free (name); + return 0; + } + slang_alloc_free (name); + spec->_struct = (slang_struct *) slang_alloc_malloc (sizeof (slang_struct)); + if (spec->_struct == NULL) + { + slang_info_log_memory (C->L); + return 0; + } + if (!slang_struct_construct_a (spec->_struct)) + { + slang_alloc_free (spec->_struct); + spec->_struct = NULL; + return 0; + } + if (!slang_struct_copy (spec->_struct, stru)) + return 0; + } + break; + default: + return 0; + } + return 1; +} + +static int parse_fully_specified_type (slang_parse_ctx *C, slang_fully_specified_type *type, + slang_struct_scope *structs, slang_variable_scope *scope, slang_function_scope *funcs) +{ + if (!parse_type_qualifier (C, &type->qualifier)) + return 0; + return parse_type_specifier (C, &type->specifier, structs, scope, funcs); +} + +/* 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 + +static int parse_child_operation (slang_parse_ctx *C, slang_operation *oper, int statement, + slang_variable_scope *scope, slang_struct_scope *structs, slang_function_scope *funcs) +{ + oper->children = (slang_operation *) slang_alloc_realloc (oper->children, + oper->num_children * sizeof (slang_operation), + (oper->num_children + 1) * sizeof (slang_operation)); + if (oper->children == NULL) + { + slang_info_log_memory (C->L); + return 0; + } + if (!slang_operation_construct_a (oper->children + oper->num_children)) + { + slang_info_log_memory (C->L); + return 0; + } + oper->num_children++; + if (statement) + return parse_statement (C, oper->children + oper->num_children - 1, scope, structs, funcs); + return parse_expression (C, oper->children + oper->num_children - 1, scope, structs, funcs); +} + +static int parse_declaration (slang_parse_ctx *C, slang_variable_scope *, slang_struct_scope *, + slang_function_scope *); + +static int parse_statement (slang_parse_ctx *C, slang_operation *oper, slang_variable_scope *scope, + slang_struct_scope *structs, slang_function_scope *funcs) +{ + oper->locals->outer_scope = scope; + switch (*C->I++) + { + case OP_BLOCK_BEGIN_NO_NEW_SCOPE: + oper->type = slang_oper_block_no_new_scope; + while (*C->I != OP_END) + if (!parse_child_operation (C, oper, 1, scope, structs, funcs)) + return 0; + C->I++; + break; + case OP_BLOCK_BEGIN_NEW_SCOPE: + oper->type = slang_oper_block_new_scope; + while (*C->I != OP_END) + if (!parse_child_operation (C, oper, 1, oper->locals, structs, funcs)) + return 0; + C->I++; + break; + case OP_DECLARE: + oper->type = slang_oper_variable_decl; + { + const unsigned int first_var = scope->num_variables; + if (!parse_declaration (C, scope, structs, funcs)) + return 0; + if (first_var < scope->num_variables) + { + const unsigned int num_vars = scope->num_variables - first_var; + unsigned int i; + oper->children = (slang_operation *) slang_alloc_malloc (num_vars * sizeof ( + slang_operation)); + if (oper->children == NULL) + { + slang_info_log_memory (C->L); + return 0; + } + for (i = 0; i < num_vars; i++) + if (!slang_operation_construct_a (oper->children + i)) + { + unsigned int j; + for (j = 0; j < i; j++) + slang_operation_destruct (oper->children + j); + slang_alloc_free (oper->children); + oper->children = NULL; + slang_info_log_memory (C->L); + return 0; + } + oper->num_children = num_vars; + for (i = first_var; i < scope->num_variables; i++) + { + slang_operation *o = oper->children + i - first_var; + o->type = slang_oper_identifier; + o->locals->outer_scope = scope; + o->identifier = slang_string_duplicate (scope->variables[i].name); + if (o->identifier == NULL) + { + slang_info_log_memory (C->L); + return 0; + } + } + } + } + break; + case OP_ASM: + oper->type = slang_oper_asm; + if (!parse_identifier (C, &oper->identifier)) + return 0; + while (*C->I != OP_END) + if (!parse_child_operation (C, oper, 0, scope, structs, funcs)) + return 0; + 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, oper, 0, scope, structs, funcs)) + return 0; + break; + case OP_EXPRESSION: + oper->type = slang_oper_expression; + if (!parse_child_operation (C, oper, 0, scope, structs, funcs)) + return 0; + break; + case OP_IF: + oper->type = slang_oper_if; + if (!parse_child_operation (C, oper, 0, scope, structs, funcs)) + return 0; + if (!parse_child_operation (C, oper, 1, scope, structs, funcs)) + return 0; + if (!parse_child_operation (C, oper, 1, scope, structs, funcs)) + return 0; + break; + case OP_WHILE: + oper->type = slang_oper_while; + if (!parse_child_operation (C, oper, 1, oper->locals, structs, funcs)) + return 0; + if (!parse_child_operation (C, oper, 1, oper->locals, structs, funcs)) + return 0; + break; + case OP_DO: + oper->type = slang_oper_do; + if (!parse_child_operation (C, oper, 1, scope, structs, funcs)) + return 0; + if (!parse_child_operation (C, oper, 0, scope, structs, funcs)) + return 0; + break; + case OP_FOR: + oper->type = slang_oper_for; + if (!parse_child_operation (C, oper, 1, oper->locals, structs, funcs)) + return 0; + if (!parse_child_operation (C, oper, 1, oper->locals, structs, funcs)) + return 0; + if (!parse_child_operation (C, oper, 0, oper->locals, structs, funcs)) + return 0; + if (!parse_child_operation (C, oper, 1, oper->locals, structs, funcs)) + return 0; + break; + default: + return 0; + } + return 1; +} + +static int handle_trinary_expression (slang_parse_ctx *C, slang_operation *op, + slang_operation **ops, unsigned int *num_ops) +{ + op->num_children = 3; + op->children = (slang_operation *) slang_alloc_malloc (3 * sizeof (slang_operation)); + if (op->children == NULL) + { + slang_info_log_memory (C->L); + return 0; + } + op->children[0] = (*ops)[*num_ops - 4]; + op->children[1] = (*ops)[*num_ops - 3]; + op->children[2] = (*ops)[*num_ops - 2]; + (*ops)[*num_ops - 4] = (*ops)[*num_ops - 1]; + *num_ops -= 3; + *ops = (slang_operation *) slang_alloc_realloc (*ops, (*num_ops + 3) * sizeof (slang_operation), + *num_ops * sizeof (slang_operation)); + if (*ops == NULL) + { + slang_info_log_memory (C->L); + return 0; + } + return 1; +} + +static int handle_binary_expression (slang_parse_ctx *C, slang_operation *op, + slang_operation **ops, unsigned int *num_ops) +{ + op->num_children = 2; + op->children = (slang_operation *) slang_alloc_malloc (2 * sizeof (slang_operation)); + if (op->children == NULL) + { + slang_info_log_memory (C->L); + return 0; + } + op->children[0] = (*ops)[*num_ops - 3]; + op->children[1] = (*ops)[*num_ops - 2]; + (*ops)[*num_ops - 3] = (*ops)[*num_ops - 1]; + *num_ops -= 2; + *ops = (slang_operation *) slang_alloc_realloc (*ops, (*num_ops + 2) * sizeof (slang_operation), + *num_ops * sizeof (slang_operation)); + if (*ops == NULL) + { + slang_info_log_memory (C->L); + return 0; + } + return 1; +} + +static int handle_unary_expression (slang_parse_ctx *C, slang_operation *op, + slang_operation **ops, unsigned int *num_ops) +{ + op->num_children = 1; + op->children = (slang_operation *) slang_alloc_malloc (sizeof (slang_operation)); + if (op->children == NULL) + { + slang_info_log_memory (C->L); + return 0; + } + op->children[0] = (*ops)[*num_ops - 2]; + (*ops)[*num_ops - 2] = (*ops)[*num_ops - 1]; + (*num_ops)--; + *ops = (slang_operation *) slang_alloc_realloc (*ops, (*num_ops + 1) * sizeof (slang_operation), + *num_ops * sizeof (slang_operation)); + if (*ops == NULL) + { + slang_info_log_memory (C->L); + return 0; + } + return 1; +} + +static int is_constructor_name (const char *name, slang_struct_scope *structs) +{ + if (slang_type_specifier_type_from_string (name) != slang_spec_void) + return 1; + return slang_struct_scope_find (structs, name, 1) != NULL; +} + +static int parse_expression (slang_parse_ctx *C, slang_operation *oper, slang_variable_scope *scope, + slang_struct_scope *structs, slang_function_scope *funcs) +{ + 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++; + ops = (slang_operation *) slang_alloc_realloc (ops, + num_ops * sizeof (slang_operation), (num_ops + 1) * sizeof (slang_operation)); + if (ops == NULL) + { + slang_info_log_memory (C->L); + return 0; + } + op = ops + num_ops; + if (!slang_operation_construct_a (op)) + { + slang_info_log_memory (C->L); + return 0; + } + num_ops++; + op->locals->outer_scope = scope; + 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)) + return 0; + op->literal = (float) number; + break; + case OP_PUSH_INT: + op->type = slang_oper_literal_int; + if (!parse_number (C, &number)) + return 0; + op->literal = (float) number; + break; + case OP_PUSH_FLOAT: + op->type = slang_oper_literal_float; + if (!parse_float (C, &op->literal)) + return 0; + break; + case OP_PUSH_IDENTIFIER: + op->type = slang_oper_identifier; + if (!parse_identifier (C, &op->identifier)) + return 0; + break; + case OP_SEQUENCE: + op->type = slang_oper_sequence; + if (!handle_binary_expression (C, op, &ops, &num_ops)) + return 0; + break; + case OP_ASSIGN: + op->type = slang_oper_assign; + if (!handle_binary_expression (C, op, &ops, &num_ops)) + return 0; + break; + case OP_ADDASSIGN: + op->type = slang_oper_addassign; + if (!handle_binary_expression (C, op, &ops, &num_ops)) + return 0; + break; + case OP_SUBASSIGN: + op->type = slang_oper_subassign; + if (!handle_binary_expression (C, op, &ops, &num_ops)) + return 0; + break; + case OP_MULASSIGN: + op->type = slang_oper_mulassign; + if (!handle_binary_expression (C, op, &ops, &num_ops)) + return 0; + break; + case OP_DIVASSIGN: + op->type = slang_oper_divassign; + if (!handle_binary_expression (C, op, &ops, &num_ops)) + return 0; + 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_trinary_expression (C, op, &ops, &num_ops)) + return 0; + break; + case OP_LOGICALOR: + op->type = slang_oper_logicalor; + if (!handle_binary_expression (C, op, &ops, &num_ops)) + return 0; + break; + case OP_LOGICALXOR: + op->type = slang_oper_logicalxor; + if (!handle_binary_expression (C, op, &ops, &num_ops)) + return 0; + break; + case OP_LOGICALAND: + op->type = slang_oper_logicaland; + if (!handle_binary_expression (C, op, &ops, &num_ops)) + return 0; + break; + /*case OP_BITOR:*/ + /*case OP_BITXOR:*/ + /*case OP_BITAND:*/ + case OP_EQUAL: + op->type = slang_oper_equal; + if (!handle_binary_expression (C, op, &ops, &num_ops)) + return 0; + break; + case OP_NOTEQUAL: + op->type = slang_oper_notequal; + if (!handle_binary_expression (C, op, &ops, &num_ops)) + return 0; + break; + case OP_LESS: + op->type = slang_oper_less; + if (!handle_binary_expression (C, op, &ops, &num_ops)) + return 0; + break; + case OP_GREATER: + op->type = slang_oper_greater; + if (!handle_binary_expression (C, op, &ops, &num_ops)) + return 0; + break; + case OP_LESSEQUAL: + op->type = slang_oper_lessequal; + if (!handle_binary_expression (C, op, &ops, &num_ops)) + return 0; + break; + case OP_GREATEREQUAL: + op->type = slang_oper_greaterequal; + if (!handle_binary_expression (C, op, &ops, &num_ops)) + return 0; + break; + /*case OP_LSHIFT:*/ + /*case OP_RSHIFT:*/ + case OP_ADD: + op->type = slang_oper_add; + if (!handle_binary_expression (C, op, &ops, &num_ops)) + return 0; + break; + case OP_SUBTRACT: + op->type = slang_oper_subtract; + if (!handle_binary_expression (C, op, &ops, &num_ops)) + return 0; + break; + case OP_MULTIPLY: + op->type = slang_oper_multiply; + if (!handle_binary_expression (C, op, &ops, &num_ops)) + return 0; + break; + case OP_DIVIDE: + op->type = slang_oper_divide; + if (!handle_binary_expression (C, op, &ops, &num_ops)) + return 0; + break; + /*case OP_MODULUS:*/ + case OP_PREINCREMENT: + op->type = slang_oper_preincrement; + if (!handle_unary_expression (C, op, &ops, &num_ops)) + return 0; + break; + case OP_PREDECREMENT: + op->type = slang_oper_predecrement; + if (!handle_unary_expression (C, op, &ops, &num_ops)) + return 0; + break; + case OP_PLUS: + op->type = slang_oper_plus; + if (!handle_unary_expression (C, op, &ops, &num_ops)) + return 0; + break; + case OP_MINUS: + op->type = slang_oper_minus; + if (!handle_unary_expression (C, op, &ops, &num_ops)) + return 0; + break; + case OP_NOT: + op->type = slang_oper_not; + if (!handle_unary_expression (C, op, &ops, &num_ops)) + return 0; + break; + /*case OP_COMPLEMENT:*/ + case OP_SUBSCRIPT: + op->type = slang_oper_subscript; + if (!handle_binary_expression (C, op, &ops, &num_ops)) + return 0; + break; + case OP_CALL: + op->type = slang_oper_call; + if (!parse_identifier (C, &op->identifier)) + return 0; + while (*C->I != OP_END) + if (!parse_child_operation (C, op, 0, scope, structs, funcs)) + return 0; + C->I++; + if (!C->parsing_builtin && + !slang_function_scope_find_by_name (funcs, op->identifier, 1) && + !is_constructor_name (op->identifier, structs)) + { + slang_info_log_error (C->L, "%s: undeclared function name", op->identifier); + return 0; + } + break; + case OP_FIELD: + op->type = slang_oper_field; + if (!parse_identifier (C, &op->identifier)) + return 0; + if (!handle_unary_expression (C, op, &ops, &num_ops)) + return 0; + break; + case OP_POSTINCREMENT: + op->type = slang_oper_postincrement; + if (!handle_unary_expression (C, op, &ops, &num_ops)) + return 0; + break; + case OP_POSTDECREMENT: + op->type = slang_oper_postdecrement; + if (!handle_unary_expression (C, op, &ops, &num_ops)) + return 0; + break; + default: + return 0; + } + } + C->I++; + *oper = *ops; + slang_alloc_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_variable *param, + slang_struct_scope *structs, slang_variable_scope *scope, slang_function_scope *funcs) +{ + slang_storage_aggregate agg; + if (!parse_type_qualifier (C, ¶m->type.qualifier)) + return 0; + switch (*C->I++) + { + 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"); + return 0; + } + 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"); + return 0; + } + 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"); + return 0; + } + break; + default: + return 0; + } + if (!parse_type_specifier (C, ¶m->type.specifier, structs, scope, funcs)) + return 0; + if (!parse_identifier (C, ¶m->name)) + return 0; + if (*C->I++ == PARAMETER_ARRAY_PRESENT) + { + param->array_size = (slang_operation *) slang_alloc_malloc (sizeof (slang_operation)); + if (param->array_size == NULL) + { + slang_info_log_memory (C->L); + return 0; + } + if (!slang_operation_construct_a (param->array_size)) + { + slang_alloc_free (param->array_size); + param->array_size = NULL; + slang_info_log_memory (C->L); + return 0; + } + if (!parse_expression (C, param->array_size, scope, structs, funcs)) + return 0; + } + slang_storage_aggregate_construct (&agg); + if (!_slang_aggregate_variable (&agg, ¶m->type.specifier, param->array_size, funcs, + structs)) + { + slang_storage_aggregate_destruct (&agg); + return 0; + } + slang_storage_aggregate_destruct (&agg); + 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_ASSIGN 1 +#define OPERATOR_ADDASSIGN 2 +#define OPERATOR_SUBASSIGN 3 +#define OPERATOR_MULASSIGN 4 +#define OPERATOR_DIVASSIGN 5 +/*#define OPERATOR_MODASSIGN 6*/ +/*#define OPERATOR_LSHASSIGN 7*/ +/*#define OPERATOR_RSHASSIGN 8*/ +/*#define OPERATOR_ANDASSIGN 9*/ +/*#define OPERATOR_XORASSIGN 10*/ +/*#define OPERATOR_ORASSIGN 11*/ +#define OPERATOR_LOGICALXOR 12 +/*#define OPERATOR_BITOR 13*/ +/*#define OPERATOR_BITXOR 14*/ +/*#define OPERATOR_BITAND 15*/ +#define OPERATOR_EQUAL 16 +#define OPERATOR_NOTEQUAL 17 +#define OPERATOR_LESS 18 +#define OPERATOR_GREATER 19 +#define OPERATOR_LESSEQUAL 20 +#define OPERATOR_GREATEREQUAL 21 +/*#define OPERATOR_LSHIFT 22*/ +/*#define OPERATOR_RSHIFT 23*/ +#define OPERATOR_MULTIPLY 24 +#define OPERATOR_DIVIDE 25 +/*#define OPERATOR_MODULUS 26*/ +#define OPERATOR_INCREMENT 27 +#define OPERATOR_DECREMENT 28 +#define OPERATOR_PLUS 29 +#define OPERATOR_MINUS 30 +/*#define OPERATOR_COMPLEMENT 31*/ +#define OPERATOR_NOT 32 + +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_NOTEQUAL, "!=" }, + { 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_EQUAL, "==" }, + { OPERATOR_ASSIGN, "=" }, + /*{ OPERATOR_MODASSIGN, "%=" },*/ + /*{ OPERATOR_MODULUS, "%" },*/ + /*{ OPERATOR_ANDASSIGN, "&=" },*/ + /*{ OPERATOR_BITAND, "&" },*/ + /*{ OPERATOR_ORASSIGN, "|=" },*/ + /*{ OPERATOR_BITOR, "|" },*/ + /*{ OPERATOR_COMPLEMENT, "~" },*/ + /*{ OPERATOR_XORASSIGN, "^=" },*/ + { OPERATOR_LOGICALXOR, "^^" }/*,*/ + /*{ OPERATOR_BITXOR, "^" }*/ +}; + +static int parse_operator_name (slang_parse_ctx *C, char **pname) +{ + unsigned int i; + for (i = 0; i < sizeof (operator_names) / sizeof (*operator_names); i++) + if (operator_names[i].o_code == (unsigned int) (*C->I)) + { + *pname = slang_string_duplicate (operator_names[i].o_name); + if (*pname == NULL) + { + slang_info_log_memory (C->L); + return 0; + } + C->I++; + return 1; + } + return 0; +} + +static int parse_function_prototype (slang_parse_ctx *C, slang_function *func, + slang_struct_scope *structs, slang_variable_scope *scope, slang_function_scope *funcs) +{ + if (!parse_fully_specified_type (C, &func->header.type, structs, scope, funcs)) + return 0; + switch (*C->I++) + { + case FUNCTION_ORDINARY: + func->kind = slang_func_ordinary; + if (!parse_identifier (C, &func->header.name)) + return 0; + break; + case FUNCTION_CONSTRUCTOR: + func->kind = slang_func_constructor; + if (func->header.type.specifier.type == slang_spec_struct) + return 0; + func->header.name = slang_string_duplicate ( + type_specifier_type_names[func->header.type.specifier.type]); + if (func->header.name == NULL) + { + slang_info_log_memory (C->L); + return 0; + } + break; + case FUNCTION_OPERATOR: + func->kind = slang_func_operator; + if (!parse_operator_name (C, &func->header.name)) + return 0; + break; + default: + return 0; + } + func->parameters->outer_scope = scope; + while (*C->I++ == PARAMETER_NEXT) + { + func->parameters->variables = (slang_variable *) slang_alloc_realloc ( + func->parameters->variables, + func->parameters->num_variables * sizeof (slang_variable), + (func->parameters->num_variables + 1) * sizeof (slang_variable)); + if (func->parameters->variables == NULL) + { + slang_info_log_memory (C->L); + return 0; + } + slang_variable_construct (func->parameters->variables + func->parameters->num_variables); + func->parameters->num_variables++; + if (!parse_parameter_declaration (C, func->parameters->variables + + func->parameters->num_variables - 1, structs, scope, funcs)) + return 0; + } + func->param_count = func->parameters->num_variables; + return 1; +} + +static int parse_function_definition (slang_parse_ctx *C, slang_function *func, + slang_struct_scope *structs, slang_variable_scope *scope, slang_function_scope *funcs) +{ + if (!parse_function_prototype (C, func, structs, scope, funcs)) + return 0; + func->body = (slang_operation *) slang_alloc_malloc (sizeof (slang_operation)); + if (func->body == NULL) + { + slang_info_log_memory (C->L); + return 0; + } + if (!slang_operation_construct_a (func->body)) + { + slang_alloc_free (func->body); + func->body = NULL; + slang_info_log_memory (C->L); + return 0; + } + if (!parse_statement (C, func->body, func->parameters, structs, funcs)) + return 0; + return 1; +} + +/* 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 + +static int parse_init_declarator (slang_parse_ctx *C, const slang_fully_specified_type *type, + slang_variable_scope *vars, slang_struct_scope *structs, slang_function_scope *funcs) +{ + slang_variable *var; + + if (*C->I++ == VARIABLE_NONE) + return 1; + vars->variables = (slang_variable *) slang_alloc_realloc (vars->variables, + vars->num_variables * sizeof (slang_variable), + (vars->num_variables + 1) * sizeof (slang_variable)); + if (vars->variables == NULL) + { + slang_info_log_memory (C->L); + return 0; + } + var = vars->variables + vars->num_variables; + vars->num_variables++; + slang_variable_construct (var); + var->type.qualifier = type->qualifier; + if (!parse_identifier (C, &var->name)) + return 0; + switch (*C->I++) + { + case VARIABLE_NONE: + if (!slang_type_specifier_copy (&var->type.specifier, &type->specifier)) + return 0; + break; + case VARIABLE_INITIALIZER: + if (!slang_type_specifier_copy (&var->type.specifier, &type->specifier)) + return 0; + var->initializer = (slang_operation *) slang_alloc_malloc (sizeof (slang_operation)); + if (var->initializer == NULL) + { + slang_info_log_memory (C->L); + return 0; + } + if (!slang_operation_construct_a (var->initializer)) + { + slang_alloc_free (var->initializer); + var->initializer = NULL; + slang_info_log_memory (C->L); + return 0; + } + if (!parse_expression (C, var->initializer, vars, structs, funcs)) + return 0; + break; + case VARIABLE_ARRAY_UNKNOWN: + var->type.specifier.type = slang_spec_array; + var->type.specifier._array = (slang_type_specifier *) slang_alloc_malloc (sizeof ( + slang_type_specifier)); + if (var->type.specifier._array == NULL) + { + slang_info_log_memory (C->L); + return 0; + } + slang_type_specifier_construct (var->type.specifier._array); + if (!slang_type_specifier_copy (var->type.specifier._array, &type->specifier)) + return 0; + break; + case VARIABLE_ARRAY_EXPLICIT: + var->type.specifier.type = slang_spec_array; + var->type.specifier._array = (slang_type_specifier *) slang_alloc_malloc (sizeof ( + slang_type_specifier)); + if (var->type.specifier._array == NULL) + { + slang_info_log_memory (C->L); + return 0; + } + slang_type_specifier_construct (var->type.specifier._array); + if (!slang_type_specifier_copy (var->type.specifier._array, &type->specifier)) + return 0; + var->array_size = (slang_operation *) slang_alloc_malloc (sizeof (slang_operation)); + if (var->array_size == NULL) + { + slang_info_log_memory (C->L); + return 0; + } + if (!slang_operation_construct_a (var->array_size)) + { + slang_alloc_free (var->array_size); + var->array_size = NULL; + slang_info_log_memory (C->L); + return 0; + } + if (!parse_expression (C, var->array_size, vars, structs, funcs)) + return 0; + break; + default: + return 0; + } + if (!(var->type.specifier.type == slang_spec_array && var->array_size == NULL)) + { + slang_storage_aggregate agg; + + slang_storage_aggregate_construct (&agg); + if (!_slang_aggregate_variable (&agg, &var->type.specifier, var->array_size, funcs, + structs)) + { + slang_storage_aggregate_destruct (&agg); + return 0; + } + slang_storage_aggregate_destruct (&agg); + } + return 1; +} + +static int parse_init_declarator_list (slang_parse_ctx *C, slang_variable_scope *vars, + slang_struct_scope *structs, slang_function_scope *funcs) +{ + slang_fully_specified_type type; + + slang_fully_specified_type_construct (&type); + if (!parse_fully_specified_type (C, &type, structs, vars, funcs)) + { + slang_fully_specified_type_destruct (&type); + return 0; + } + do + { + if (!parse_init_declarator (C, &type, vars, structs, funcs)) + { + slang_fully_specified_type_destruct (&type); + return 0; + } + } + while (*C->I++ == DECLARATOR_NEXT); + slang_fully_specified_type_destruct (&type); + return 1; +} + +static int parse_function (slang_parse_ctx *C, int definition, slang_struct_scope *structs, + slang_function_scope *funcs, slang_variable_scope *scope, slang_function **parsed_func_ret) +{ + slang_function parsed_func, *found_func; + + /* parse function definition/declaration */ + slang_function_construct (&parsed_func); + if (definition) + { + if (!parse_function_definition (C, &parsed_func, structs, scope, funcs)) + { + slang_function_destruct (&parsed_func); + return 0; + } + } + else + { + if (!parse_function_prototype (C, &parsed_func, structs, scope, funcs)) + { + slang_function_destruct (&parsed_func); + return 0; + } + } + + /* 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 (funcs, &parsed_func, 0); + if (found_func == NULL) + { + /* add the parsed function to the function list */ + funcs->functions = (slang_function *) slang_alloc_realloc (funcs->functions, + funcs->num_functions * sizeof (slang_function), (funcs->num_functions + 1) * sizeof ( + slang_function)); + if (funcs->functions == NULL) + { + slang_info_log_memory (C->L); + slang_function_destruct (&parsed_func); + return 0; + } + funcs->functions[funcs->num_functions] = parsed_func; + funcs->num_functions++; + + /* return the newly parsed function */ + *parsed_func_ret = funcs->functions + funcs->num_functions - 1; + } + else + { + /* TODO: check function return type qualifiers and specifiers */ + if (definition) + { + /* destroy the existing function declaration and replace it with the new one */ + if (found_func->body != NULL) + { + slang_info_log_error (C->L, "%s: function already has a body", + parsed_func.header.name); + slang_function_destruct (&parsed_func); + return 0; + } + 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; + } + + /* assemble the parsed function */ + if (definition) + { +static int x = 0; +static + slang_assembly_file file; + slang_assembly_name_space space; +x++; +if (x == 1) + slang_assembly_file_construct (&file); + space.funcs = funcs; + space.structs = structs; + space.vars = scope; +if (x == 1) +xxx_first (&file); + (**parsed_func_ret).address = file.count; + if (!_slang_assemble_function (&file, *parsed_func_ret, &space)) + { + slang_assembly_file_destruct (&file); + return 0; + } +if (slang_string_compare ("main", (**parsed_func_ret).header.name) == 0) +{ +xxx_prolog (&file, (**parsed_func_ret).address); +_slang_execute (&file); +slang_assembly_file_destruct (&file); +exit (0); +} + } + return 1; +} + +/* declaration */ +#define DECLARATION_FUNCTION_PROTOTYPE 1 +#define DECLARATION_INIT_DECLARATOR_LIST 2 + +static int parse_declaration (slang_parse_ctx *C, slang_variable_scope *scope, + slang_struct_scope *structs, slang_function_scope *funcs) +{ + slang_function *dummy_func; + + switch (*C->I++) + { + case DECLARATION_INIT_DECLARATOR_LIST: + if (!parse_init_declarator_list (C, scope, structs, funcs)) + return 0; + break; + case DECLARATION_FUNCTION_PROTOTYPE: + if (!parse_function (C, 0, structs, funcs, scope, &dummy_func)) + return 0; + break; + default: + return 0; + } + return 1; +} + +/* external declaration */ +#define EXTERNAL_NULL 0 +#define EXTERNAL_FUNCTION_DEFINITION 1 +#define EXTERNAL_DECLARATION 2 + +static int parse_translation_unit (slang_parse_ctx *C, slang_translation_unit *unit) +{ + while (*C->I != EXTERNAL_NULL) + { + slang_function *func; + + switch (*C->I++) + { + case EXTERNAL_FUNCTION_DEFINITION: + if (!parse_function (C, 1, &unit->structs, &unit->functions, &unit->globals, &func)) + return 0; + break; + case EXTERNAL_DECLARATION: + if (!parse_declaration (C, &unit->globals, &unit->structs, &unit->functions)) + return 0; + break; + default: + return 0; + } + } + C->I++; + return 1; +} + +static int compile_binary (const byte *prod, slang_translation_unit *unit, slang_unit_type type, + slang_info_log *log, slang_translation_unit *builtins) +{ + slang_parse_ctx C; + + /* set-up parse context */ + C.I = prod; + C.L = log; + C.parsing_builtin = builtins == NULL; + + if (!check_revision (&C)) + return 0; + + /* create translation unit object */ + slang_translation_unit_construct (unit); + unit->type = type; + + if (builtins != NULL) + { + /* link to built-in functions */ + builtins[1].functions.outer_scope = &builtins[0].functions; + builtins[2].functions.outer_scope = &builtins[1].functions; + unit->functions.outer_scope = &builtins[2].functions; + + /* link to built-in variables - core unit does not define any */ + builtins[2].globals.outer_scope = &builtins[1].globals; + unit->globals.outer_scope = &builtins[2].globals; + + /* link to built-in structure typedefs - only in common unit */ + unit->structs.outer_scope = &builtins[1].structs; + } + + /* parse translation unit */ + if (!parse_translation_unit (&C, unit)) + { + slang_translation_unit_destruct (unit); + return 0; + } + + return 1; +} + +static int compile_with_grammar (grammar id, const char *source, slang_translation_unit *unit, + slang_unit_type type, slang_info_log *log, slang_translation_unit *builtins) +{ + byte *prod; + unsigned int size, start, version; + + /* retrieve version */ + if (!_slang_preprocess_version (source, &version, &start, log)) + return 0; + + /* check the syntax */ + if (!grammar_fast_check (id, (const byte *) source + start, &prod, &size, 65536)) + { + char buf[1024]; + unsigned int pos; + grammar_get_last_error ( (unsigned char*) buf, 1024, (int*) &pos); + slang_info_log_error (log, buf); + return 0; + } + + if (!compile_binary (prod, unit, type, log, builtins)) + { + grammar_alloc_free (prod); + return 0; + } + + grammar_alloc_free (prod); + return 1; +} + +static const char *slang_shader_syn = +#include "library/slang_shader_syn.h" +; +/* +static const byte slang_core_gc_bin[] = { +#include "library/slang_core_gc_bin.h" +};*/ +static const byte slang_core_gc[] = { +#include "library/slang_core_gc.h" +}; + +static const byte slang_common_builtin_gc_bin[] = { +#include "library/slang_common_builtin_gc_bin.h" +}; + +static const byte slang_fragment_builtin_gc_bin[] = { +#include "library/slang_fragment_builtin_gc_bin.h" +}; + +static const byte slang_vertex_builtin_gc_bin[] = { +#include "library/slang_vertex_builtin_gc_bin.h" +}; + +int _slang_compile (const char *source, slang_translation_unit *unit, slang_unit_type type, + slang_info_log *log) +{ + grammar id; + slang_translation_unit builtin_units[3]; + slang_translation_unit *builtins = NULL; + + /* load slang grammar */ + id = grammar_load_from_text ((const byte *) slang_shader_syn); + if (id == 0) + { + char buf[1024]; + unsigned int pos; + grammar_get_last_error ( (unsigned char*) buf, 1024, (int*) &pos); + slang_info_log_error (log, buf); + return 0; + } + + /* set shader type - the syntax is slightly different for different shaders */ + if (type == slang_unit_fragment_shader || type == slang_unit_fragment_builtin) + grammar_set_reg8 (id, (const byte *) "shader_type", 1); + else + grammar_set_reg8 (id, (const byte *) "shader_type", 2); + + /* enable language extensions */ + grammar_set_reg8 (id, (const byte *) "parsing_builtin", 1); + + /* if parsing user-specified shader, load built-in library */ + if (type == slang_unit_fragment_shader || type == slang_unit_vertex_shader) + { + /*if (!compile_binary (slang_core_gc_bin, builtin_units, + slang_unit_fragment_builtin, log, NULL))*/ + if (!compile_with_grammar (id, (const char*) slang_core_gc, builtin_units, slang_unit_fragment_builtin, + log, NULL)) + { + grammar_destroy (id); + return 0; + } + if (!compile_binary (slang_common_builtin_gc_bin, builtin_units + 1, + slang_unit_fragment_builtin, log, NULL)) + { + slang_translation_unit_destruct (builtin_units); + grammar_destroy (id); + return 0; + } + if (type == slang_unit_fragment_shader) + { + if (!compile_binary (slang_fragment_builtin_gc_bin, builtin_units + 2, + slang_unit_fragment_builtin, log, NULL)) + { + slang_translation_unit_destruct (builtin_units); + slang_translation_unit_destruct (builtin_units + 1); + grammar_destroy (id); + return 0; + } + } + else if (type == slang_unit_vertex_shader) + { + if (!compile_binary (slang_vertex_builtin_gc_bin, builtin_units + 2, + slang_unit_vertex_builtin, log, NULL)) + { + slang_translation_unit_destruct (builtin_units); + slang_translation_unit_destruct (builtin_units + 1); + grammar_destroy (id); + return 0; + } + } + + /* disable language extensions */ + grammar_set_reg8 (id, (const byte *) "parsing_builtin", 0); + builtins = builtin_units; + } + + /* compile the actual shader - pass-in built-in library for external shader */ + if (!compile_with_grammar (id, source, unit, type, log, builtins)) + { + if (type == slang_unit_fragment_shader || type == slang_unit_vertex_shader) + { + slang_translation_unit_destruct (builtin_units); + slang_translation_unit_destruct (builtin_units + 1); + slang_translation_unit_destruct (builtin_units + 2); + } + grammar_destroy (id); + return 0; + } + + /* destroy built-in library */ + if (type == slang_unit_fragment_shader || type == slang_unit_vertex_shader) + { + slang_translation_unit_destruct (builtin_units); + slang_translation_unit_destruct (builtin_units + 1); + slang_translation_unit_destruct (builtin_units + 2); + } + grammar_destroy (id); + return 1; +} + diff --git a/nx-X11/extras/Mesa/src/mesa/shader/slang/slang_compile.h b/nx-X11/extras/Mesa/src/mesa/shader/slang/slang_compile.h new file mode 100644 index 000000000..d78c66f00 --- /dev/null +++ b/nx-X11/extras/Mesa/src/mesa/shader/slang/slang_compile.h @@ -0,0 +1,271 @@ +/* + * Mesa 3-D graphics library + * Version: 6.3 + * + * Copyright (C) 2005 Brian Paul All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN + * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#if !defined SLANG_COMPILE_H +#define SLANG_COMPILE_H + +#if defined __cplusplus +extern "C" { +#endif + +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_specifier_type_ +{ + slang_spec_void, + slang_spec_bool, + slang_spec_bvec2, + slang_spec_bvec3, + slang_spec_bvec4, + slang_spec_int, + slang_spec_ivec2, + slang_spec_ivec3, + slang_spec_ivec4, + slang_spec_float, + slang_spec_vec2, + slang_spec_vec3, + slang_spec_vec4, + slang_spec_mat2, + slang_spec_mat3, + slang_spec_mat4, + slang_spec_sampler1D, + slang_spec_sampler2D, + slang_spec_sampler3D, + slang_spec_samplerCube, + slang_spec_sampler1DShadow, + slang_spec_sampler2DShadow, + slang_spec_struct, + slang_spec_array +} slang_type_specifier_type; + +slang_type_specifier_type slang_type_specifier_type_from_string (const char *); + +typedef struct slang_type_specifier_ +{ + slang_type_specifier_type type; + struct slang_struct_ *_struct; /* spec_struct */ + struct slang_type_specifier_ *_array; /* spec_array */ +} slang_type_specifier; + +void slang_type_specifier_construct (slang_type_specifier *); +void slang_type_specifier_destruct (slang_type_specifier *); +int slang_type_specifier_copy (slang_type_specifier *, const slang_type_specifier *); +int slang_type_specifier_equal (const slang_type_specifier *, const slang_type_specifier *); + +typedef struct slang_fully_specified_type_ +{ + slang_type_qualifier qualifier; + slang_type_specifier specifier; +} slang_fully_specified_type; + +typedef struct slang_variable_scope_ +{ + struct slang_variable_ *variables; + unsigned int num_variables; + struct slang_variable_scope_ *outer_scope; +} slang_variable_scope; + +typedef enum slang_operation_type_ +{ + slang_oper_none, + slang_oper_block_no_new_scope, + slang_oper_block_new_scope, + slang_oper_variable_decl, + slang_oper_asm, + slang_oper_break, + slang_oper_continue, + slang_oper_discard, + slang_oper_return, + slang_oper_expression, + slang_oper_if, + slang_oper_while, + slang_oper_do, + slang_oper_for, + slang_oper_void, + slang_oper_literal_bool, + slang_oper_literal_int, + slang_oper_literal_float, + slang_oper_identifier, + slang_oper_sequence, + slang_oper_assign, + slang_oper_addassign, + slang_oper_subassign, + slang_oper_mulassign, + slang_oper_divassign, + /*slang_oper_modassign,*/ + /*slang_oper_lshassign,*/ + /*slang_oper_rshassign,*/ + /*slang_oper_orassign,*/ + /*slang_oper_xorassign,*/ + /*slang_oper_andassign,*/ + slang_oper_select, + slang_oper_logicalor, + slang_oper_logicalxor, + slang_oper_logicaland, + /*slang_oper_bitor,*/ + /*slang_oper_bitxor,*/ + /*slang_oper_bitand,*/ + slang_oper_equal, + slang_oper_notequal, + slang_oper_less, + slang_oper_greater, + slang_oper_lessequal, + slang_oper_greaterequal, + /*slang_oper_lshift,*/ + /*slang_oper_rshift,*/ + slang_oper_add, + slang_oper_subtract, + slang_oper_multiply, + slang_oper_divide, + /*slang_oper_modulus,*/ + slang_oper_preincrement, + slang_oper_predecrement, + slang_oper_plus, + slang_oper_minus, + /*slang_oper_complement,*/ + slang_oper_not, + slang_oper_subscript, + slang_oper_call, + slang_oper_field, + slang_oper_postincrement, + slang_oper_postdecrement +} slang_operation_type; + +typedef struct slang_operation_ +{ + slang_operation_type type; + struct slang_operation_ *children; + unsigned int num_children; + float literal; /* bool, literal_int, literal_float */ + char *identifier; /* asm, identifier, call, field */ + slang_variable_scope *locals; +} slang_operation; + +int slang_operation_construct_a (slang_operation *); +void slang_operation_destruct (slang_operation *); + +typedef struct slang_variable_ +{ + slang_fully_specified_type type; + char *name; + slang_operation *array_size; /* spec_array */ + slang_operation *initializer; + unsigned int address; +} slang_variable; + +slang_variable *_slang_locate_variable (slang_variable_scope *scope, const char *name, int all); + +typedef struct slang_struct_scope_ +{ + struct slang_struct_ *structs; + unsigned int num_structs; + struct slang_struct_scope_ *outer_scope; +} slang_struct_scope; + +struct slang_struct_ *slang_struct_scope_find (slang_struct_scope *, const char *, int); + +typedef struct slang_struct_ +{ + char *name; + slang_variable_scope *fields; + slang_struct_scope *structs; +} slang_struct; + +int slang_struct_construct_a (slang_struct *); +int slang_struct_copy (slang_struct *, const slang_struct *); + +typedef enum slang_function_kind_ +{ + slang_func_ordinary, + slang_func_constructor, + slang_func_operator +} slang_function_kind; + +typedef struct slang_function_ +{ + slang_function_kind kind; + slang_variable header; + slang_variable_scope *parameters; + unsigned int param_count; + slang_operation *body; + unsigned int address; +} slang_function; + +typedef struct slang_function_scope_ +{ + slang_function *functions; + unsigned int num_functions; + struct slang_function_scope_ *outer_scope; +} slang_function_scope; + +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_translation_unit_ +{ + slang_variable_scope globals; + slang_function_scope functions; + slang_struct_scope structs; + slang_unit_type type; +} slang_translation_unit; + +void slang_translation_unit_construct (slang_translation_unit *); +void slang_translation_unit_destruct (slang_translation_unit *); + +typedef struct slang_info_log_ +{ + char *text; + int dont_free_text; +} slang_info_log; + +void slang_info_log_construct (slang_info_log *); +void slang_info_log_destruct (slang_info_log *); +int slang_info_log_error (slang_info_log *, const char *, ...); +int slang_info_log_warning (slang_info_log *, const char *, ...); +void slang_info_log_memory (slang_info_log *); + +int _slang_compile (const char *, slang_translation_unit *, slang_unit_type type, slang_info_log *); + +#ifdef __cplusplus +} +#endif + +#endif + diff --git a/nx-X11/extras/Mesa/src/mesa/shader/slang/slang_execute.c b/nx-X11/extras/Mesa/src/mesa/shader/slang/slang_execute.c new file mode 100644 index 000000000..57941469c --- /dev/null +++ b/nx-X11/extras/Mesa/src/mesa/shader/slang/slang_execute.c @@ -0,0 +1,352 @@ +/* + * Mesa 3-D graphics library + * Version: 6.3 + * + * Copyright (C) 2005 Brian Paul All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN + * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +/** + * \file slang_execute.c + * intermediate code interpreter + * \author Michal Krol + */ + +#include "imports.h" +#include "slang_utility.h" +#include "slang_assemble.h" +#include "slang_storage.h" +#include "slang_execute.h" + +static void dump_instruction (FILE *f, slang_assembly *a, unsigned int i) +{ + fprintf (f, "%.5u:\t", i); + + switch (a->type) + { + case slang_asm_none: + fprintf (f, "none"); + break; + case slang_asm_float_copy: + fprintf (f, "float_copy\t%d, %d", a->param[0], a->param[1]); + break; + case slang_asm_float_move: + fprintf (f, "float_move\t%d, %d", a->param[0], a->param[1]); + break; + case slang_asm_float_push: + fprintf (f, "float_push\t%f", a->literal); + break; + case slang_asm_float_deref: + fprintf (f, "float_deref"); + break; + case slang_asm_float_add: + fprintf (f, "float_add"); + break; + case slang_asm_float_multiply: + fprintf (f, "float_multiply"); + break; + case slang_asm_float_divide: + fprintf (f, "float_divide"); + break; + case slang_asm_float_negate: + fprintf (f, "float_negate"); + break; + case slang_asm_float_less: + fprintf (f, "float_less"); + break; + case slang_asm_float_equal: + fprintf (f, "float_equal\t%d, %d", a->param[0], a->param[1]); + break; + case slang_asm_float_to_int: + fprintf (f, "float_to_int"); + break; + case slang_asm_int_copy: + fprintf (f, "int_copy\t%d, %d", a->param[0], a->param[1]); + break; + case slang_asm_int_move: + fprintf (f, "int_move\t%d, %d", a->param[0], a->param[1]); + break; + case slang_asm_int_push: + fprintf (f, "int_push\t%d", (GLint) a->literal); + break; + case slang_asm_int_deref: + fprintf (f, "int_deref"); + break; + case slang_asm_int_to_float: + fprintf (f, "int_to_float"); + break; + case slang_asm_int_to_addr: + fprintf (f, "int_to_addr"); + break; + case slang_asm_bool_copy: + fprintf (f, "bool_copy\t%d, %d", a->param[0], a->param[1]); + break; + case slang_asm_bool_move: + fprintf (f, "bool_move\t%d, %d", a->param[0], a->param[1]); + break; + case slang_asm_bool_push: + fprintf (f, "bool_push\t%d", a->literal != 0.0f); + break; + case slang_asm_bool_deref: + fprintf (f, "bool_deref"); + break; + case slang_asm_addr_copy: + fprintf (f, "addr_copy"); + break; + case slang_asm_addr_push: + fprintf (f, "addr_push\t%u", a->param[0]); + break; + case slang_asm_addr_deref: + fprintf (f, "addr_deref"); + break; + case slang_asm_addr_add: + fprintf (f, "addr_add"); + break; + case slang_asm_addr_multiply: + fprintf (f, "addr_multiply"); + break; + case slang_asm_jump: + fprintf (f, "jump\t%u", a->param[0]); + break; + case slang_asm_jump_if_zero: + fprintf (f, "jump_if_zero\t%u", a->param[0]); + break; + case slang_asm_enter: + fprintf (f, "enter\t%u", a->param[0]); + break; + case slang_asm_leave: + fprintf (f, "leave"); + break; + case slang_asm_local_alloc: + fprintf (f, "local_alloc\t%u", a->param[0]); + break; + case slang_asm_local_free: + fprintf (f, "local_free\t%u", a->param[0]); + break; + case slang_asm_local_addr: + fprintf (f, "local_addr\t%u, %u", a->param[0], a->param[1]); + break; + case slang_asm_call: + fprintf (f, "call\t%u", a->param[0]); + break; + case slang_asm_return: + fprintf (f, "return"); + break; + case slang_asm_discard: + fprintf (f, "discard"); + break; + case slang_asm_exit: + fprintf (f, "exit"); + break; + default: + break; + } + + fprintf (f, "\n"); +} + +static void dump (const slang_assembly_file *file) +{ + unsigned int i; + static unsigned int counter = 0; + FILE *f; + char filename[256]; + + counter++; + sprintf (filename, "~mesa-slang-assembly-dump-(%u).txt", counter); + f = fopen (filename, "w"); + if (f == NULL) + return; + + for (i = 0; i < file->count; i++) + dump_instruction (f, file->code + i, i); + + fclose (f); +} + +int _slang_execute (const slang_assembly_file *file) +{ + slang_machine mach; + FILE *f; + + mach.ip = 0; + mach.sp = SLANG_MACHINE_STACK_SIZE; + mach.bp = 0; + mach.kill = 0; + mach.exit = 0; + + /* assume 32-bit machine */ + /* XXX why???, disabling the pointer size assertions here. + * See bug 4021. + */ + _static_assert(sizeof (GLfloat) == 4); + /*_static_assert(sizeof (GLfloat *) == 4);*/ + _static_assert(sizeof (GLuint) == 4); + /*_static_assert(sizeof (GLuint *) == 4);*/ + + dump (file); + + f = fopen ("~mesa-slang-assembly-execution.txt", "w"); + + while (!mach.exit) + { + slang_assembly *a = file->code + mach.ip; + if (f != NULL) + { + unsigned int i; + dump_instruction (f, a, mach.ip); + fprintf (f, "\t\tsp=%u bp=%u\n", mach.sp, mach.bp); + for (i = mach.sp; i < SLANG_MACHINE_STACK_SIZE; i++) + fprintf (f, "\t%.5u\t%6f\t%u\n", i, mach.stack._float[i], mach.stack._addr[i]); + fflush (f); + } + mach.ip++; + + switch (a->type) + { + case slang_asm_none: + break; + case slang_asm_float_copy: + case slang_asm_int_copy: + case slang_asm_bool_copy: + *(mach.stack._floatp[mach.sp + a->param[0] / 4] + a->param[1] / 4) = + mach.stack._float[mach.sp]; + mach.sp++; + break; + case slang_asm_float_move: + case slang_asm_int_move: + case slang_asm_bool_move: + mach.stack._float[mach.sp + a->param[0] / 4] = + mach.stack._float[mach.sp + (mach.stack._addr[mach.sp] + a->param[1]) / 4]; + break; + case slang_asm_float_push: + case slang_asm_int_push: + case slang_asm_bool_push: + mach.sp--; + mach.stack._float[mach.sp] = a->literal; + break; + case slang_asm_float_deref: + case slang_asm_int_deref: + case slang_asm_bool_deref: + mach.stack._float[mach.sp] = *mach.stack._floatp[mach.sp]; + break; + case slang_asm_float_add: + mach.stack._float[mach.sp + 1] += mach.stack._float[mach.sp]; + mach.sp++; + break; + case slang_asm_float_multiply: + mach.stack._float[mach.sp + 1] *= mach.stack._float[mach.sp]; + mach.sp++; + break; + case slang_asm_float_divide: + mach.stack._float[mach.sp + 1] /= mach.stack._float[mach.sp]; + mach.sp++; + break; + case slang_asm_float_negate: + mach.stack._float[mach.sp] = -mach.stack._float[mach.sp]; + break; + case slang_asm_float_less: + mach.stack._float[mach.sp + 1] = + mach.stack._float[mach.sp + 1] < mach.stack._float[mach.sp] ? 1.0f : 0.0f; + mach.sp++; + break; + case slang_asm_float_equal: + mach.sp--; + mach.stack._float[mach.sp] = mach.stack._float[mach.sp + 1 + a->param[0] / 4] == + mach.stack._float[mach.sp + 1 + a->param[1] / 4] ? 1.0f : 0.0f; + break; + case slang_asm_float_to_int: + mach.stack._float[mach.sp] = (GLfloat) (GLint) mach.stack._float[mach.sp]; + break; + case slang_asm_int_to_float: + break; + case slang_asm_int_to_addr: + mach.stack._addr[mach.sp] = (GLuint) (GLint) mach.stack._float[mach.sp]; + break; + case slang_asm_addr_copy: + *mach.stack._addrp[mach.sp + 1] = mach.stack._addr[mach.sp]; + mach.sp++; + break; + case slang_asm_addr_push: + mach.sp--; + mach.stack._addr[mach.sp] = a->param[0]; + break; + case slang_asm_addr_deref: + mach.stack._addr[mach.sp] = *mach.stack._addrp[mach.sp]; + break; + case slang_asm_addr_add: + mach.stack._addr[mach.sp + 1] += mach.stack._addr[mach.sp]; + mach.sp++; + break; + case slang_asm_addr_multiply: + mach.stack._addr[mach.sp + 1] *= mach.stack._addr[mach.sp]; + mach.sp++; + break; + case slang_asm_jump: + mach.ip = a->param[0]; + break; + case slang_asm_jump_if_zero: + if (mach.stack._float[mach.sp] == 0.0f) + mach.ip = a->param[0]; + mach.sp++; + break; + case slang_asm_enter: + mach.sp--; + mach.stack._addr[mach.sp] = mach.bp; + mach.bp = mach.sp + a->param[0] / 4; + break; + case slang_asm_leave: + mach.bp = mach.stack._addr[mach.sp]; + mach.sp++; + break; + case slang_asm_local_alloc: + mach.sp -= a->param[0] / 4; + break; + case slang_asm_local_free: + mach.sp += a->param[0] / 4; + break; + case slang_asm_local_addr: + mach.sp--; + mach.stack._addr[mach.sp] = (GLuint) mach.stack._addr + mach.bp * 4 - + (a->param[0] + a->param[1]) + 4; + break; + case slang_asm_call: + mach.sp--; + mach.stack._addr[mach.sp] = mach.ip; + mach.ip = a->param[0]; + break; + case slang_asm_return: + mach.ip = mach.stack._addr[mach.sp]; + mach.sp++; + break; + case slang_asm_discard: + mach.kill = 1; + break; + case slang_asm_exit: + mach.exit = 1; + break; + } + } + + if (f != NULL) + fclose (f); + + return 0; +} + diff --git a/nx-X11/extras/Mesa/src/mesa/shader/slang/slang_execute.h b/nx-X11/extras/Mesa/src/mesa/shader/slang/slang_execute.h new file mode 100644 index 000000000..7a7765441 --- /dev/null +++ b/nx-X11/extras/Mesa/src/mesa/shader/slang/slang_execute.h @@ -0,0 +1,57 @@ +/* + * Mesa 3-D graphics library + * Version: 6.3 + * + * Copyright (C) 2005 Brian Paul All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN + * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#if !defined SLANG_EXECUTE_H +#define SLANG_EXECUTE_H + +#if defined __cplusplus +extern "C" { +#endif + +#define SLANG_MACHINE_STACK_SIZE 1024 + +typedef struct slang_machine_ +{ + GLuint ip; /* instruction pointer, for flow control */ + GLuint sp; /* stack pointer, for stack access */ + GLuint bp; /* base pointer, for local variable access */ + GLuint kill; /* discard the fragment */ + GLuint exit; /* terminate the shader */ + union stack_ + { + GLfloat _float[SLANG_MACHINE_STACK_SIZE]; + GLfloat *_floatp[SLANG_MACHINE_STACK_SIZE]; + GLuint _addr[SLANG_MACHINE_STACK_SIZE]; + GLuint *_addrp[SLANG_MACHINE_STACK_SIZE]; + } stack; +} slang_machine; + +int _slang_execute (const slang_assembly_file *); + +#ifdef __cplusplus +} +#endif + +#endif + diff --git a/nx-X11/extras/Mesa/src/mesa/shader/slang/slang_preprocess.c b/nx-X11/extras/Mesa/src/mesa/shader/slang/slang_preprocess.c new file mode 100644 index 000000000..1dc156eed --- /dev/null +++ b/nx-X11/extras/Mesa/src/mesa/shader/slang/slang_preprocess.c @@ -0,0 +1,87 @@ +/* + * Mesa 3-D graphics library + * Version: 6.3 + * + * Copyright (C) 2005 Brian Paul All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN + * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +/** + * \file slang_preprocess.c + * slang preprocessor + * \author Michal Krol + */ + +#include "imports.h" +#include "grammar_mesa.h" +#include "slang_compile.h" +#include "slang_preprocess.h" + +static const char *slang_version_syn = +#include "library/slang_version_syn.h" +; + +int _slang_preprocess_version (const char *text, unsigned int *version, unsigned int *eaten, + slang_info_log *log) +{ + grammar id; + byte *prod, *I; + unsigned int size; + + id = grammar_load_from_text ((const byte *) slang_version_syn); + if (id == 0) + { + char buf[1024]; + unsigned int pos; + grammar_get_last_error ( (unsigned char*) buf, 1024, (int*) &pos); + slang_info_log_error (log, buf); + return 0; + } + + if (!grammar_fast_check (id, (const byte *) text, &prod, &size, 8)) + { + char buf[1024]; + unsigned int pos; + grammar_get_last_error ( (unsigned char*) buf, 1024, (int*) &pos); + slang_info_log_error (log, buf); + grammar_destroy (id); + return 0; + } + + grammar_destroy (id); + + /* there can be multiple #version directives - grab the last one */ + I = prod; + while (I < prod + size) + { + *version = + (unsigned int) I[0] + + (unsigned int) I[1] * 100; + *eaten = + ((unsigned int) I[2]) + + ((unsigned int) I[3] << 8) + + ((unsigned int) I[4] << 16) + + ((unsigned int) I[5] << 24); + I += 6; + } + + grammar_alloc_free (prod); + return 1; +} + diff --git a/nx-X11/extras/Mesa/src/mesa/shader/slang/slang_preprocess.h b/nx-X11/extras/Mesa/src/mesa/shader/slang/slang_preprocess.h new file mode 100644 index 000000000..637b822c9 --- /dev/null +++ b/nx-X11/extras/Mesa/src/mesa/shader/slang/slang_preprocess.h @@ -0,0 +1,39 @@ +/* + * Mesa 3-D graphics library + * Version: 6.3 + * + * Copyright (C) 2005 Brian Paul All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN + * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#if !defined SLANG_PREPROCESS_H +#define SLANG_PREPROCESS_H + +#if defined __cplusplus +extern "C" { +#endif + +int _slang_preprocess_version (const char *, unsigned int *, unsigned int *, slang_info_log *); + +#ifdef __cplusplus +} +#endif + +#endif + diff --git a/nx-X11/extras/Mesa/src/mesa/shader/slang/slang_storage.c b/nx-X11/extras/Mesa/src/mesa/shader/slang/slang_storage.c new file mode 100644 index 000000000..3b2fda415 --- /dev/null +++ b/nx-X11/extras/Mesa/src/mesa/shader/slang/slang_storage.c @@ -0,0 +1,255 @@ +/* + * Mesa 3-D graphics library + * Version: 6.3 + * + * Copyright (C) 2005 Brian Paul All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN + * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +/** + * \file slang_storage.c + * slang variable storage + * \author Michal Krol + */ + +#include "imports.h" +#include "slang_utility.h" +#include "slang_storage.h" +#include "slang_assemble.h" + +/* slang_storage_array */ + +void slang_storage_array_construct (slang_storage_array *arr) +{ + arr->type = slang_stor_aggregate; + arr->aggregate = NULL; + arr->length = 0; +} + +void slang_storage_array_destruct (slang_storage_array *arr) +{ + if (arr->aggregate != NULL) + { + slang_storage_aggregate_destruct (arr->aggregate); + slang_alloc_free (arr->aggregate); + } +} + +/* slang_storage_aggregate */ + +void slang_storage_aggregate_construct (slang_storage_aggregate *agg) +{ + agg->arrays = NULL; + agg->count = 0; +} + +void slang_storage_aggregate_destruct (slang_storage_aggregate *agg) +{ + unsigned int i; + for (i = 0; i < agg->count; i++) + slang_storage_array_destruct (agg->arrays + i); + slang_alloc_free (agg->arrays); +} + +static slang_storage_array *slang_storage_aggregate_push_new (slang_storage_aggregate *agg) +{ + slang_storage_array *arr = NULL; + agg->arrays = (slang_storage_array *) slang_alloc_realloc (agg->arrays, agg->count * sizeof ( + slang_storage_array), (agg->count + 1) * sizeof (slang_storage_array)); + if (agg->arrays != NULL) + { + arr = agg->arrays + agg->count; + slang_storage_array_construct (arr); + agg->count++; + } + return arr; +} + +/* _slang_aggregate_variable() */ + +static int aggregate_vector (slang_storage_aggregate *agg, slang_storage_type basic_type, + unsigned int row_count) +{ + slang_storage_array *arr = slang_storage_aggregate_push_new (agg); + if (arr == NULL) + return 0; + arr->type = basic_type; + arr->length = row_count; + return 1; +} + +static int aggregate_matrix (slang_storage_aggregate *agg, slang_storage_type basic_type, + unsigned int dimension) +{ + slang_storage_array *arr = slang_storage_aggregate_push_new (agg); + if (arr == NULL) + return 0; + arr->type = slang_stor_aggregate; + arr->length = dimension; + arr->aggregate = (slang_storage_aggregate *) slang_alloc_malloc (sizeof ( + slang_storage_aggregate)); + if (arr->aggregate == NULL) + return 0; + slang_storage_aggregate_construct (arr->aggregate); + if (!aggregate_vector (arr->aggregate, basic_type, dimension)) + return 0; + return 1; +} + +static int aggregate_variables (slang_storage_aggregate *agg, const slang_variable_scope *vars, + slang_function_scope *funcs, slang_struct_scope *structs) +{ + unsigned int i; + for (i = 0; i < vars->num_variables; i++) + if (!_slang_aggregate_variable (agg, &vars->variables[i].type.specifier, + vars->variables[i].array_size, funcs, structs)) + return 0; + return 1; +} + +int _slang_aggregate_variable (slang_storage_aggregate *agg, slang_type_specifier *spec, + slang_operation *array_size, slang_function_scope *funcs, slang_struct_scope *structs) +{ + switch (spec->type) + { + case slang_spec_bool: + return aggregate_vector (agg, slang_stor_bool, 1); + case slang_spec_bvec2: + return aggregate_vector (agg, slang_stor_bool, 2); + case slang_spec_bvec3: + return aggregate_vector (agg, slang_stor_bool, 3); + case slang_spec_bvec4: + return aggregate_vector (agg, slang_stor_bool, 4); + case slang_spec_int: + return aggregate_vector (agg, slang_stor_int, 1); + case slang_spec_ivec2: + return aggregate_vector (agg, slang_stor_int, 2); + case slang_spec_ivec3: + return aggregate_vector (agg, slang_stor_int, 3); + case slang_spec_ivec4: + return aggregate_vector (agg, slang_stor_int, 4); + case slang_spec_float: + return aggregate_vector (agg, slang_stor_float, 1); + case slang_spec_vec2: + return aggregate_vector (agg, slang_stor_float, 2); + case slang_spec_vec3: + return aggregate_vector (agg, slang_stor_float, 3); + case slang_spec_vec4: + return aggregate_vector (agg, slang_stor_float, 4); + case slang_spec_mat2: + return aggregate_matrix (agg, slang_stor_float, 2); + case slang_spec_mat3: + return aggregate_matrix (agg, slang_stor_float, 3); + case slang_spec_mat4: + return aggregate_matrix (agg, slang_stor_float, 4); + case slang_spec_sampler1D: + case slang_spec_sampler2D: + case slang_spec_sampler3D: + case slang_spec_samplerCube: + case slang_spec_sampler1DShadow: + case slang_spec_sampler2DShadow: + return aggregate_vector (agg, slang_stor_int, 1); + case slang_spec_struct: + return aggregate_variables (agg, spec->_struct->fields, funcs, structs); + case slang_spec_array: + { + slang_storage_array *arr; + slang_assembly_file file; + slang_assembly_flow_control flow; + slang_assembly_name_space space; + slang_assembly_local_info info; + slang_assembly_stack_info stk; + + arr = slang_storage_aggregate_push_new (agg); + if (arr == NULL) + return 0; + arr->type = slang_stor_aggregate; + arr->aggregate = (slang_storage_aggregate *) slang_alloc_malloc (sizeof ( + slang_storage_aggregate)); + if (arr->aggregate == NULL) + return 0; + slang_storage_aggregate_construct (arr->aggregate); + if (!_slang_aggregate_variable (arr->aggregate, spec->_array, NULL, funcs, structs)) + return 0; + slang_assembly_file_construct (&file); + space.funcs = funcs; + space.structs = structs; + /* XXX: vars! */ + space.vars = NULL; + if (!_slang_assemble_operation (&file, array_size, 0, &flow, &space, &info, &stk)) + { + slang_assembly_file_destruct (&file); + return 0; + } + /* TODO: evaluate array size */ + slang_assembly_file_destruct (&file); + arr->length = 256; + } + return 1; + default: + return 0; + } +} + +/* _slang_sizeof_aggregate() */ + +unsigned int _slang_sizeof_aggregate (const slang_storage_aggregate *agg) +{ + unsigned int i, size = 0; + for (i = 0; i < agg->count; i++) + { + unsigned int element_size; + if (agg->arrays[i].type == slang_stor_aggregate) + element_size = _slang_sizeof_aggregate (agg->arrays[i].aggregate); + else + element_size = sizeof (GLfloat); + size += element_size * agg->arrays[i].length; + } + return size; +} + +/* _slang_flatten_aggregate () */ + +int _slang_flatten_aggregate (slang_storage_aggregate *flat, const slang_storage_aggregate *agg) +{ + unsigned int i; + for (i = 0; i < agg->count; i++) + { + unsigned int j; + for (j = 0; j < agg->arrays[i].length; j++) + { + if (agg->arrays[i].type == slang_stor_aggregate) + { + if (!_slang_flatten_aggregate (flat, agg->arrays[i].aggregate)) + return 0; + } + else + { + slang_storage_array *arr; + arr = slang_storage_aggregate_push_new (flat); + if (arr == NULL) + return 0; + arr->type = agg->arrays[i].type; + arr->length = 1; + } + } + } + return 1; +} + diff --git a/nx-X11/extras/Mesa/src/mesa/shader/slang/slang_storage.h b/nx-X11/extras/Mesa/src/mesa/shader/slang/slang_storage.h new file mode 100644 index 000000000..77962c198 --- /dev/null +++ b/nx-X11/extras/Mesa/src/mesa/shader/slang/slang_storage.h @@ -0,0 +1,109 @@ +/* + * Mesa 3-D graphics library + * Version: 6.3 + * + * Copyright (C) 2005 Brian Paul All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN + * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#if !defined SLANG_STORAGE_H +#define SLANG_STORAGE_H + +#include "slang_compile.h" + +#if defined __cplusplus +extern "C" { +#endif + +/* + Program variable data storage is kept completely transparent to the front-end compiler. It is + up to the back-end how the data is actually allocated. The slang_storage_type enum + provides the basic information about how the memory is interpreted. This abstract piece + of memory is called a data slot. A data slot of a particular type has a fixed size. + + 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. +*/ +typedef enum slang_storage_type_ +{ + slang_stor_aggregate, + slang_stor_bool, + slang_stor_int, + slang_stor_float +} 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; /* slang_stor_aggregate */ + unsigned int length; +} slang_storage_array; + +void slang_storage_array_construct (slang_storage_array *); +void 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; + unsigned int count; +} slang_storage_aggregate; + +void slang_storage_aggregate_construct (slang_storage_aggregate *); +void slang_storage_aggregate_destruct (slang_storage_aggregate *); + +int _slang_aggregate_variable (slang_storage_aggregate *, struct slang_type_specifier_ *, + struct slang_operation_ *, struct slang_function_scope_ *, slang_struct_scope *); + +/* + returns total size (in machine units) of the given aggregate + returns 0 on error +*/ +unsigned int _slang_sizeof_aggregate (const slang_storage_aggregate *); + +/* + converts structured aggregate to a flat one, with arrays of generic type being + one-element long + returns 1 on success + returns 0 otherwise +*/ +int _slang_flatten_aggregate (slang_storage_aggregate *, const slang_storage_aggregate *); + +#ifdef __cplusplus +} +#endif + +#endif + diff --git a/nx-X11/extras/Mesa/src/mesa/shader/slang/slang_utility.c b/nx-X11/extras/Mesa/src/mesa/shader/slang/slang_utility.c new file mode 100644 index 000000000..b1b20d9e3 --- /dev/null +++ b/nx-X11/extras/Mesa/src/mesa/shader/slang/slang_utility.c @@ -0,0 +1,73 @@ +/* + * Mesa 3-D graphics library + * Version: 6.3 + * + * Copyright (C) 2005 Brian Paul All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN + * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +/** + * \file slang_utility.c + * slang utilities + * \author Michal Krol + */ + +#include "imports.h" +#include "slang_utility.h" + +void slang_alloc_free (void *ptr) +{ + _mesa_free (ptr); +} + +void *slang_alloc_malloc (unsigned int size) +{ + return _mesa_malloc (size); +} + +void *slang_alloc_realloc (void *ptr, unsigned int old_size, unsigned int size) +{ + return _mesa_realloc (ptr, old_size, size); +} + +int slang_string_compare (const char *str1, const char *str2) +{ + return _mesa_strcmp (str1, str2); +} + +char *slang_string_copy (char *dst, const char *src) +{ + return _mesa_strcpy (dst, src); +} + +char *slang_string_concat (char *dst, const char *src) +{ + return _mesa_strcpy (dst + _mesa_strlen (dst), src); +} + +char *slang_string_duplicate (const char *src) +{ + return _mesa_strdup (src); +} + +unsigned int slang_string_length (const char *str) +{ + return _mesa_strlen (str); +} + diff --git a/nx-X11/extras/Mesa/src/mesa/shader/slang/slang_utility.h b/nx-X11/extras/Mesa/src/mesa/shader/slang/slang_utility.h new file mode 100644 index 000000000..04afa18d1 --- /dev/null +++ b/nx-X11/extras/Mesa/src/mesa/shader/slang/slang_utility.h @@ -0,0 +1,51 @@ +/* + * Mesa 3-D graphics library + * Version: 6.3 + * + * Copyright (C) 2005 Brian Paul All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN + * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#if !defined SLANG_UTILITY_H +#define SLANG_UTILITY_H + +#if defined __cplusplus +extern "C" { +#endif + +/* Compile-time assertions. If the expression is zero, try to declare an + * array of size [-1] to cause compilation error. + */ +#define _static_assert(expr) do { int _array[(expr) ? 1 : -1]; _array[0]; } while (0) + +void slang_alloc_free (void *); +void *slang_alloc_malloc (unsigned int); +void *slang_alloc_realloc (void *, unsigned int, unsigned int); +int slang_string_compare (const char *, const char *); +char *slang_string_copy (char *, const char *); +char *slang_string_concat (char *, const char *); +char *slang_string_duplicate (const char *); +unsigned int slang_string_length (const char *); + +#ifdef __cplusplus +} +#endif + +#endif + diff --git a/nx-X11/extras/Mesa/src/mesa/shader/slang/traverse_wrap.h b/nx-X11/extras/Mesa/src/mesa/shader/slang/traverse_wrap.h new file mode 100644 index 000000000..b2f244ee0 --- /dev/null +++ b/nx-X11/extras/Mesa/src/mesa/shader/slang/traverse_wrap.h @@ -0,0 +1,112 @@ +/* + * Mesa 3-D graphics library + * Version: 6.3 + * + * Copyright (C) 2005 Brian Paul All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN + * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +/** + * \file traverse_wrap.h + * Handy TIntermTraverser class wrapper + * \author Michal Krol + */ + +#ifndef __TRAVERSE_WRAP_H__ +#define __TRAVERSE_WRAP_H__ + +#include "Include/intermediate.h" + +/* + The original TIntermTraverser class that is used to walk the intermediate tree, + is not very elegant in its design. One must define static functions with + appropriate prototypes, construct TIntermTraverser object, and set its member + function pointers to one's static functions. If traversal-specific data + is needed, a new class must be derived, and one must up-cast the object + passed as a parameter to the static function. + + The class below eliminates this burden by providing virtual methods that are + to be overridden in the derived class. +*/ + +class traverse_wrap: private TIntermTraverser +{ +private: + static void _visitSymbol (TIntermSymbol *S, TIntermTraverser *T) { + static_cast<traverse_wrap *> (T)->Symbol (*S); + } + static void _visitConstantUnion (TIntermConstantUnion *U, TIntermTraverser *T) { + static_cast<traverse_wrap *> (T)->ConstantUnion (*U); + } + static bool _visitBinary (bool preVisit, TIntermBinary *B, TIntermTraverser *T) { + return static_cast<traverse_wrap *> (T)->Binary (preVisit, *B); + } + static bool _visitUnary (bool preVisit, TIntermUnary *U, TIntermTraverser *T) { + return static_cast<traverse_wrap *> (T)->Unary (preVisit, *U); + } + static bool _visitSelection (bool preVisit, TIntermSelection *S, TIntermTraverser *T) { + return static_cast<traverse_wrap *> (T)->Selection (preVisit, *S); + } + static bool _visitAggregate (bool preVisit, TIntermAggregate *A, TIntermTraverser *T) { + return static_cast<traverse_wrap *> (T)->Aggregate (preVisit, *A); + } + static bool _visitLoop (bool preVisit, TIntermLoop *L, TIntermTraverser *T) { + return static_cast<traverse_wrap *> (T)->Loop (preVisit, *L); + } + static bool _visitBranch (bool preVisit, TIntermBranch *B, TIntermTraverser *T) { + return static_cast<traverse_wrap *> (T)->Branch (preVisit, *B); + } +public: + traverse_wrap () { + visitSymbol = _visitSymbol; + visitConstantUnion = _visitConstantUnion; + visitBinary = _visitBinary; + visitUnary = _visitUnary; + visitSelection = _visitSelection; + visitAggregate = _visitAggregate; + visitLoop = _visitLoop; + visitBranch = _visitBranch; + } +protected: + virtual void Symbol (const TIntermSymbol &) { + } + virtual void ConstantUnion (const TIntermConstantUnion &) { + } + virtual bool Binary (bool, const TIntermBinary &) { + return true; + } + virtual bool Unary (bool, const TIntermUnary &) { + return true; + } + virtual bool Selection (bool, const TIntermSelection &) { + return true; + } + virtual bool Aggregate (bool, const TIntermAggregate &) { + return true; + } + virtual bool Loop (bool, const TIntermLoop &) { + return true; + } + virtual bool Branch (bool, const TIntermBranch &) { + return true; + } +}; + +#endif + |