nvfragparse.c revision e197de56cdb86835f1437688a9161cd909792d80
12861e737e84e4884109b9526ac645194ba892a74Michal Krol/* 22861e737e84e4884109b9526ac645194ba892a74Michal Krol * Mesa 3-D graphics library 37e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul * Version: 6.5 42861e737e84e4884109b9526ac645194ba892a74Michal Krol * 57e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul * Copyright (C) 1999-2005 Brian Paul All Rights Reserved. 62861e737e84e4884109b9526ac645194ba892a74Michal Krol * 72861e737e84e4884109b9526ac645194ba892a74Michal Krol * Permission is hereby granted, free of charge, to any person obtaining a 82861e737e84e4884109b9526ac645194ba892a74Michal Krol * copy of this software and associated documentation files (the "Software"), 92861e737e84e4884109b9526ac645194ba892a74Michal Krol * to deal in the Software without restriction, including without limitation 102861e737e84e4884109b9526ac645194ba892a74Michal Krol * the rights to use, copy, modify, merge, publish, distribute, sublicense, 112861e737e84e4884109b9526ac645194ba892a74Michal Krol * and/or sell copies of the Software, and to permit persons to whom the 122861e737e84e4884109b9526ac645194ba892a74Michal Krol * Software is furnished to do so, subject to the following conditions: 132861e737e84e4884109b9526ac645194ba892a74Michal Krol * 142861e737e84e4884109b9526ac645194ba892a74Michal Krol * The above copyright notice and this permission notice shall be included 152861e737e84e4884109b9526ac645194ba892a74Michal Krol * in all copies or substantial portions of the Software. 162861e737e84e4884109b9526ac645194ba892a74Michal Krol * 172861e737e84e4884109b9526ac645194ba892a74Michal Krol * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 182861e737e84e4884109b9526ac645194ba892a74Michal Krol * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 192861e737e84e4884109b9526ac645194ba892a74Michal Krol * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 202861e737e84e4884109b9526ac645194ba892a74Michal Krol * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN 212861e737e84e4884109b9526ac645194ba892a74Michal Krol * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 222861e737e84e4884109b9526ac645194ba892a74Michal Krol * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 232861e737e84e4884109b9526ac645194ba892a74Michal Krol */ 242861e737e84e4884109b9526ac645194ba892a74Michal Krol 252861e737e84e4884109b9526ac645194ba892a74Michal Krol/** 262861e737e84e4884109b9526ac645194ba892a74Michal Krol * \file nvfragparse.c 272861e737e84e4884109b9526ac645194ba892a74Michal Krol * NVIDIA fragment program parser. 282861e737e84e4884109b9526ac645194ba892a74Michal Krol * \author Brian Paul 292861e737e84e4884109b9526ac645194ba892a74Michal Krol */ 302861e737e84e4884109b9526ac645194ba892a74Michal Krol 312861e737e84e4884109b9526ac645194ba892a74Michal Krol/* 322861e737e84e4884109b9526ac645194ba892a74Michal Krol * Regarding GL_NV_fragment_program: 332861e737e84e4884109b9526ac645194ba892a74Michal Krol * 342861e737e84e4884109b9526ac645194ba892a74Michal Krol * Portions of this software may use or implement intellectual 352861e737e84e4884109b9526ac645194ba892a74Michal Krol * property owned and licensed by NVIDIA Corporation. NVIDIA disclaims 362861e737e84e4884109b9526ac645194ba892a74Michal Krol * any and all warranties with respect to such intellectual property, 372861e737e84e4884109b9526ac645194ba892a74Michal Krol * including any use thereof or modifications thereto. 382861e737e84e4884109b9526ac645194ba892a74Michal Krol */ 392861e737e84e4884109b9526ac645194ba892a74Michal Krol 40bbd287103dad776d8a45c87c4e51fbc26d9b80d5Brian Paul#include "main/glheader.h" 41bbd287103dad776d8a45c87c4e51fbc26d9b80d5Brian Paul#include "main/context.h" 42bbd287103dad776d8a45c87c4e51fbc26d9b80d5Brian Paul#include "main/imports.h" 43bbd287103dad776d8a45c87c4e51fbc26d9b80d5Brian Paul#include "main/macros.h" 44bbd287103dad776d8a45c87c4e51fbc26d9b80d5Brian Paul#include "program.h" 45c0551f0a465b577a17698ede46370a17e29b3df7Brian#include "prog_parameter.h" 46fe278f1e600058af18c6ba5fe77bfc5a772bf9f5Brian Paul#include "prog_print.h" 47c0551f0a465b577a17698ede46370a17e29b3df7Brian#include "prog_instruction.h" 482861e737e84e4884109b9526ac645194ba892a74Michal Krol#include "nvfragparse.h" 492861e737e84e4884109b9526ac645194ba892a74Michal Krol 502861e737e84e4884109b9526ac645194ba892a74Michal Krol 512861e737e84e4884109b9526ac645194ba892a74Michal Krol#define INPUT_1V 1 522861e737e84e4884109b9526ac645194ba892a74Michal Krol#define INPUT_2V 2 532861e737e84e4884109b9526ac645194ba892a74Michal Krol#define INPUT_3V 3 542861e737e84e4884109b9526ac645194ba892a74Michal Krol#define INPUT_1S 4 552861e737e84e4884109b9526ac645194ba892a74Michal Krol#define INPUT_2S 5 562861e737e84e4884109b9526ac645194ba892a74Michal Krol#define INPUT_CC 6 572861e737e84e4884109b9526ac645194ba892a74Michal Krol#define INPUT_1V_T 7 /* one source vector, plus textureId */ 582861e737e84e4884109b9526ac645194ba892a74Michal Krol#define INPUT_3V_T 8 /* one source vector, plus textureId */ 592861e737e84e4884109b9526ac645194ba892a74Michal Krol#define INPUT_NONE 9 602a5afe3ab8d4c3624ed72b99a11b6a9017078d1cBrian Paul#define INPUT_1V_S 10 /* a string and a vector register */ 612861e737e84e4884109b9526ac645194ba892a74Michal Krol#define OUTPUT_V 20 622861e737e84e4884109b9526ac645194ba892a74Michal Krol#define OUTPUT_S 21 632861e737e84e4884109b9526ac645194ba892a74Michal Krol#define OUTPUT_NONE 22 642861e737e84e4884109b9526ac645194ba892a74Michal Krol 652861e737e84e4884109b9526ac645194ba892a74Michal Krol/* IRIX defines some of these */ 662861e737e84e4884109b9526ac645194ba892a74Michal Krol#undef _R 672861e737e84e4884109b9526ac645194ba892a74Michal Krol#undef _H 682861e737e84e4884109b9526ac645194ba892a74Michal Krol#undef _X 692861e737e84e4884109b9526ac645194ba892a74Michal Krol#undef _C 702861e737e84e4884109b9526ac645194ba892a74Michal Krol#undef _S 712861e737e84e4884109b9526ac645194ba892a74Michal Krol 722861e737e84e4884109b9526ac645194ba892a74Michal Krol/* Optional suffixes */ 732861e737e84e4884109b9526ac645194ba892a74Michal Krol#define _R FLOAT32 /* float */ 742861e737e84e4884109b9526ac645194ba892a74Michal Krol#define _H FLOAT16 /* half-float */ 752861e737e84e4884109b9526ac645194ba892a74Michal Krol#define _X FIXED12 /* fixed */ 762861e737e84e4884109b9526ac645194ba892a74Michal Krol#define _C 0x08 /* set cond codes */ 772861e737e84e4884109b9526ac645194ba892a74Michal Krol#define _S 0x10 /* saturate, clamp result to [0,1] */ 782861e737e84e4884109b9526ac645194ba892a74Michal Krol 792861e737e84e4884109b9526ac645194ba892a74Michal Krolstruct instruction_pattern { 802861e737e84e4884109b9526ac645194ba892a74Michal Krol const char *name; 817e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul enum prog_opcode opcode; 822861e737e84e4884109b9526ac645194ba892a74Michal Krol GLuint inputs; 832861e737e84e4884109b9526ac645194ba892a74Michal Krol GLuint outputs; 842861e737e84e4884109b9526ac645194ba892a74Michal Krol GLuint suffixes; 852861e737e84e4884109b9526ac645194ba892a74Michal Krol}; 862861e737e84e4884109b9526ac645194ba892a74Michal Krol 872861e737e84e4884109b9526ac645194ba892a74Michal Krolstatic const struct instruction_pattern Instructions[] = { 887e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul { "ADD", OPCODE_ADD, INPUT_2V, OUTPUT_V, _R | _H | _X | _C | _S }, 897e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul { "COS", OPCODE_COS, INPUT_1S, OUTPUT_S, _R | _H | _C | _S }, 907e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul { "DDX", OPCODE_DDX, INPUT_1V, OUTPUT_V, _R | _H | _C | _S }, 917e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul { "DDY", OPCODE_DDY, INPUT_1V, OUTPUT_V, _R | _H | _C | _S }, 927e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul { "DP3", OPCODE_DP3, INPUT_2V, OUTPUT_S, _R | _H | _X | _C | _S }, 937e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul { "DP4", OPCODE_DP4, INPUT_2V, OUTPUT_S, _R | _H | _X | _C | _S }, 947e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul { "DST", OPCODE_DP4, INPUT_2V, OUTPUT_V, _R | _H | _C | _S }, 957e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul { "EX2", OPCODE_DP4, INPUT_1S, OUTPUT_S, _R | _H | _C | _S }, 967e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul { "FLR", OPCODE_FLR, INPUT_1V, OUTPUT_V, _R | _H | _X | _C | _S }, 977e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul { "FRC", OPCODE_FRC, INPUT_1V, OUTPUT_V, _R | _H | _X | _C | _S }, 987e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul { "KIL", OPCODE_KIL_NV, INPUT_CC, OUTPUT_NONE, 0 }, 997e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul { "LG2", OPCODE_LG2, INPUT_1S, OUTPUT_S, _R | _H | _C | _S }, 1007e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul { "LIT", OPCODE_LIT, INPUT_1V, OUTPUT_V, _R | _H | _C | _S }, 1017e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul { "LRP", OPCODE_LRP, INPUT_3V, OUTPUT_V, _R | _H | _X | _C | _S }, 1027e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul { "MAD", OPCODE_MAD, INPUT_3V, OUTPUT_V, _R | _H | _X | _C | _S }, 1037e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul { "MAX", OPCODE_MAX, INPUT_2V, OUTPUT_V, _R | _H | _X | _C | _S }, 1047e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul { "MIN", OPCODE_MIN, INPUT_2V, OUTPUT_V, _R | _H | _X | _C | _S }, 1057e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul { "MOV", OPCODE_MOV, INPUT_1V, OUTPUT_V, _R | _H | _X | _C | _S }, 1067e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul { "MUL", OPCODE_MUL, INPUT_2V, OUTPUT_V, _R | _H | _X | _C | _S }, 1077e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul { "PK2H", OPCODE_PK2H, INPUT_1V, OUTPUT_S, 0 }, 1087e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul { "PK2US", OPCODE_PK2US, INPUT_1V, OUTPUT_S, 0 }, 1097e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul { "PK4B", OPCODE_PK4B, INPUT_1V, OUTPUT_S, 0 }, 1107e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul { "PK4UB", OPCODE_PK4UB, INPUT_1V, OUTPUT_S, 0 }, 1117e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul { "POW", OPCODE_POW, INPUT_2S, OUTPUT_S, _R | _H | _C | _S }, 1127e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul { "RCP", OPCODE_RCP, INPUT_1S, OUTPUT_S, _R | _H | _C | _S }, 1137e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul { "RFL", OPCODE_RFL, INPUT_2V, OUTPUT_V, _R | _H | _C | _S }, 1147e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul { "RSQ", OPCODE_RSQ, INPUT_1S, OUTPUT_S, _R | _H | _C | _S }, 1157e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul { "SEQ", OPCODE_SEQ, INPUT_2V, OUTPUT_V, _R | _H | _X | _C | _S }, 1167e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul { "SFL", OPCODE_SFL, INPUT_2V, OUTPUT_V, _R | _H | _X | _C | _S }, 1177e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul { "SGE", OPCODE_SGE, INPUT_2V, OUTPUT_V, _R | _H | _X | _C | _S }, 1187e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul { "SGT", OPCODE_SGT, INPUT_2V, OUTPUT_V, _R | _H | _X | _C | _S }, 1197e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul { "SIN", OPCODE_SIN, INPUT_1S, OUTPUT_S, _R | _H | _C | _S }, 1207e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul { "SLE", OPCODE_SLE, INPUT_2V, OUTPUT_V, _R | _H | _X | _C | _S }, 1217e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul { "SLT", OPCODE_SLT, INPUT_2V, OUTPUT_V, _R | _H | _X | _C | _S }, 1227e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul { "SNE", OPCODE_SNE, INPUT_2V, OUTPUT_V, _R | _H | _X | _C | _S }, 1237e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul { "STR", OPCODE_STR, INPUT_2V, OUTPUT_V, _R | _H | _X | _C | _S }, 1247e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul { "SUB", OPCODE_SUB, INPUT_2V, OUTPUT_V, _R | _H | _X | _C | _S }, 1257e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul { "TEX", OPCODE_TEX, INPUT_1V_T, OUTPUT_V, _C | _S }, 1267e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul { "TXD", OPCODE_TXD, INPUT_3V_T, OUTPUT_V, _C | _S }, 1277e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul { "TXP", OPCODE_TXP_NV, INPUT_1V_T, OUTPUT_V, _C | _S }, 1287e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul { "UP2H", OPCODE_UP2H, INPUT_1S, OUTPUT_V, _C | _S }, 1297e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul { "UP2US", OPCODE_UP2US, INPUT_1S, OUTPUT_V, _C | _S }, 1307e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul { "UP4B", OPCODE_UP4B, INPUT_1S, OUTPUT_V, _C | _S }, 1317e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul { "UP4UB", OPCODE_UP4UB, INPUT_1S, OUTPUT_V, _C | _S }, 1327e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul { "X2D", OPCODE_X2D, INPUT_3V, OUTPUT_V, _R | _H | _C | _S }, 1337e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul { "PRINT", OPCODE_PRINT, INPUT_1V_S, OUTPUT_NONE, 0 }, 1347e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul { NULL, (enum prog_opcode) -1, 0, 0, 0 } 1352861e737e84e4884109b9526ac645194ba892a74Michal Krol}; 1362861e737e84e4884109b9526ac645194ba892a74Michal Krol 1372861e737e84e4884109b9526ac645194ba892a74Michal Krol 1382861e737e84e4884109b9526ac645194ba892a74Michal Krol/* 1392861e737e84e4884109b9526ac645194ba892a74Michal Krol * Information needed or computed during parsing. 1402861e737e84e4884109b9526ac645194ba892a74Michal Krol * Remember, we can't modify the target program object until we've 1412861e737e84e4884109b9526ac645194ba892a74Michal Krol * _successfully_ parsed the program text. 1422861e737e84e4884109b9526ac645194ba892a74Michal Krol */ 1432861e737e84e4884109b9526ac645194ba892a74Michal Krolstruct parse_state { 1442861e737e84e4884109b9526ac645194ba892a74Michal Krol GLcontext *ctx; 1452861e737e84e4884109b9526ac645194ba892a74Michal Krol const GLubyte *start; /* start of program string */ 1462861e737e84e4884109b9526ac645194ba892a74Michal Krol const GLubyte *pos; /* current position */ 1472861e737e84e4884109b9526ac645194ba892a74Michal Krol const GLubyte *curLine; 148122629f27925a9dc50029bebc5079f87f416a7e1Brian Paul struct gl_fragment_program *program; /* current program */ 1492861e737e84e4884109b9526ac645194ba892a74Michal Krol 150122629f27925a9dc50029bebc5079f87f416a7e1Brian Paul struct gl_program_parameter_list *parameters; 1512861e737e84e4884109b9526ac645194ba892a74Michal Krol 1522861e737e84e4884109b9526ac645194ba892a74Michal Krol GLuint numInst; /* number of instructions parsed */ 1532861e737e84e4884109b9526ac645194ba892a74Michal Krol GLuint inputsRead; /* bitmask of input registers used */ 1542861e737e84e4884109b9526ac645194ba892a74Michal Krol GLuint outputsWritten; /* bitmask of 1 << FRAG_OUTPUT_* bits */ 1552861e737e84e4884109b9526ac645194ba892a74Michal Krol GLuint texturesUsed[MAX_TEXTURE_IMAGE_UNITS]; 1562861e737e84e4884109b9526ac645194ba892a74Michal Krol}; 1572861e737e84e4884109b9526ac645194ba892a74Michal Krol 1582861e737e84e4884109b9526ac645194ba892a74Michal Krol 1592861e737e84e4884109b9526ac645194ba892a74Michal Krol 1602861e737e84e4884109b9526ac645194ba892a74Michal Krol/* 1612861e737e84e4884109b9526ac645194ba892a74Michal Krol * Called whenever we find an error during parsing. 1622861e737e84e4884109b9526ac645194ba892a74Michal Krol */ 1632861e737e84e4884109b9526ac645194ba892a74Michal Krolstatic void 1642861e737e84e4884109b9526ac645194ba892a74Michal Krolrecord_error(struct parse_state *parseState, const char *msg, int lineNo) 1652861e737e84e4884109b9526ac645194ba892a74Michal Krol{ 1662861e737e84e4884109b9526ac645194ba892a74Michal Krol#ifdef DEBUG 1672861e737e84e4884109b9526ac645194ba892a74Michal Krol GLint line, column; 1682861e737e84e4884109b9526ac645194ba892a74Michal Krol const GLubyte *lineStr; 1692861e737e84e4884109b9526ac645194ba892a74Michal Krol lineStr = _mesa_find_line_column(parseState->start, 1702861e737e84e4884109b9526ac645194ba892a74Michal Krol parseState->pos, &line, &column); 1712861e737e84e4884109b9526ac645194ba892a74Michal Krol _mesa_debug(parseState->ctx, 1722861e737e84e4884109b9526ac645194ba892a74Michal Krol "nvfragparse.c(%d): line %d, column %d:%s (%s)\n", 1732861e737e84e4884109b9526ac645194ba892a74Michal Krol lineNo, line, column, (char *) lineStr, msg); 1742861e737e84e4884109b9526ac645194ba892a74Michal Krol _mesa_free((void *) lineStr); 1752861e737e84e4884109b9526ac645194ba892a74Michal Krol#else 1762861e737e84e4884109b9526ac645194ba892a74Michal Krol (void) lineNo; 1772861e737e84e4884109b9526ac645194ba892a74Michal Krol#endif 1782861e737e84e4884109b9526ac645194ba892a74Michal Krol 1792861e737e84e4884109b9526ac645194ba892a74Michal Krol /* Check that no error was already recorded. Only record the first one. */ 1802861e737e84e4884109b9526ac645194ba892a74Michal Krol if (parseState->ctx->Program.ErrorString[0] == 0) { 1812861e737e84e4884109b9526ac645194ba892a74Michal Krol _mesa_set_program_error(parseState->ctx, 1822861e737e84e4884109b9526ac645194ba892a74Michal Krol parseState->pos - parseState->start, 1832861e737e84e4884109b9526ac645194ba892a74Michal Krol msg); 1842861e737e84e4884109b9526ac645194ba892a74Michal Krol } 1852861e737e84e4884109b9526ac645194ba892a74Michal Krol} 1862861e737e84e4884109b9526ac645194ba892a74Michal Krol 1872861e737e84e4884109b9526ac645194ba892a74Michal Krol 1882861e737e84e4884109b9526ac645194ba892a74Michal Krol#define RETURN_ERROR \ 1892861e737e84e4884109b9526ac645194ba892a74Michal Kroldo { \ 1902861e737e84e4884109b9526ac645194ba892a74Michal Krol record_error(parseState, "Unexpected end of input.", __LINE__); \ 1912861e737e84e4884109b9526ac645194ba892a74Michal Krol return GL_FALSE; \ 1922861e737e84e4884109b9526ac645194ba892a74Michal Krol} while(0) 1932861e737e84e4884109b9526ac645194ba892a74Michal Krol 1942861e737e84e4884109b9526ac645194ba892a74Michal Krol#define RETURN_ERROR1(msg) \ 1952861e737e84e4884109b9526ac645194ba892a74Michal Kroldo { \ 1962861e737e84e4884109b9526ac645194ba892a74Michal Krol record_error(parseState, msg, __LINE__); \ 1972861e737e84e4884109b9526ac645194ba892a74Michal Krol return GL_FALSE; \ 1982861e737e84e4884109b9526ac645194ba892a74Michal Krol} while(0) 1992861e737e84e4884109b9526ac645194ba892a74Michal Krol 2002861e737e84e4884109b9526ac645194ba892a74Michal Krol#define RETURN_ERROR2(msg1, msg2) \ 2012861e737e84e4884109b9526ac645194ba892a74Michal Kroldo { \ 2022861e737e84e4884109b9526ac645194ba892a74Michal Krol char err[1000]; \ 2032861e737e84e4884109b9526ac645194ba892a74Michal Krol _mesa_sprintf(err, "%s %s", msg1, msg2); \ 2042861e737e84e4884109b9526ac645194ba892a74Michal Krol record_error(parseState, err, __LINE__); \ 2052861e737e84e4884109b9526ac645194ba892a74Michal Krol return GL_FALSE; \ 2062861e737e84e4884109b9526ac645194ba892a74Michal Krol} while(0) 2072861e737e84e4884109b9526ac645194ba892a74Michal Krol 2082861e737e84e4884109b9526ac645194ba892a74Michal Krol 2092861e737e84e4884109b9526ac645194ba892a74Michal Krol 2102861e737e84e4884109b9526ac645194ba892a74Michal Krol 2112861e737e84e4884109b9526ac645194ba892a74Michal Krol/* 2122861e737e84e4884109b9526ac645194ba892a74Michal Krol * Search a list of instruction structures for a match. 2132861e737e84e4884109b9526ac645194ba892a74Michal Krol */ 2142861e737e84e4884109b9526ac645194ba892a74Michal Krolstatic struct instruction_pattern 2152861e737e84e4884109b9526ac645194ba892a74Michal KrolMatchInstruction(const GLubyte *token) 2162861e737e84e4884109b9526ac645194ba892a74Michal Krol{ 2172861e737e84e4884109b9526ac645194ba892a74Michal Krol const struct instruction_pattern *inst; 2182861e737e84e4884109b9526ac645194ba892a74Michal Krol struct instruction_pattern result; 2192861e737e84e4884109b9526ac645194ba892a74Michal Krol 22094fba49be97008565c0225bc46894bfd9453bb5eVinson Lee result.name = NULL; 22194fba49be97008565c0225bc46894bfd9453bb5eVinson Lee result.opcode = MAX_OPCODE; /* i.e. invalid instruction */ 22294fba49be97008565c0225bc46894bfd9453bb5eVinson Lee result.inputs = 0; 22394fba49be97008565c0225bc46894bfd9453bb5eVinson Lee result.outputs = 0; 22494fba49be97008565c0225bc46894bfd9453bb5eVinson Lee result.suffixes = 0; 22594fba49be97008565c0225bc46894bfd9453bb5eVinson Lee 2262861e737e84e4884109b9526ac645194ba892a74Michal Krol for (inst = Instructions; inst->name; inst++) { 2279d9afe9393fde99858ddf40e478bc16cf44e60dcKenneth Graunke if (strncmp((const char *) token, inst->name, 3) == 0) { 2282861e737e84e4884109b9526ac645194ba892a74Michal Krol /* matched! */ 2292861e737e84e4884109b9526ac645194ba892a74Michal Krol int i = 3; 2302861e737e84e4884109b9526ac645194ba892a74Michal Krol result = *inst; 2312861e737e84e4884109b9526ac645194ba892a74Michal Krol result.suffixes = 0; 2322861e737e84e4884109b9526ac645194ba892a74Michal Krol /* look at suffix */ 2332861e737e84e4884109b9526ac645194ba892a74Michal Krol if (token[i] == 'R') { 2342861e737e84e4884109b9526ac645194ba892a74Michal Krol result.suffixes |= _R; 2352861e737e84e4884109b9526ac645194ba892a74Michal Krol i++; 2362861e737e84e4884109b9526ac645194ba892a74Michal Krol } 2372861e737e84e4884109b9526ac645194ba892a74Michal Krol else if (token[i] == 'H') { 2382861e737e84e4884109b9526ac645194ba892a74Michal Krol result.suffixes |= _H; 2392861e737e84e4884109b9526ac645194ba892a74Michal Krol i++; 2402861e737e84e4884109b9526ac645194ba892a74Michal Krol } 2412861e737e84e4884109b9526ac645194ba892a74Michal Krol else if (token[i] == 'X') { 2422861e737e84e4884109b9526ac645194ba892a74Michal Krol result.suffixes |= _X; 2432861e737e84e4884109b9526ac645194ba892a74Michal Krol i++; 2442861e737e84e4884109b9526ac645194ba892a74Michal Krol } 2452861e737e84e4884109b9526ac645194ba892a74Michal Krol if (token[i] == 'C') { 2462861e737e84e4884109b9526ac645194ba892a74Michal Krol result.suffixes |= _C; 2472861e737e84e4884109b9526ac645194ba892a74Michal Krol i++; 2482861e737e84e4884109b9526ac645194ba892a74Michal Krol } 2492861e737e84e4884109b9526ac645194ba892a74Michal Krol if (token[i] == '_' && token[i+1] == 'S' && 2502861e737e84e4884109b9526ac645194ba892a74Michal Krol token[i+2] == 'A' && token[i+3] == 'T') { 2512861e737e84e4884109b9526ac645194ba892a74Michal Krol result.suffixes |= _S; 2522861e737e84e4884109b9526ac645194ba892a74Michal Krol } 2532861e737e84e4884109b9526ac645194ba892a74Michal Krol return result; 2542861e737e84e4884109b9526ac645194ba892a74Michal Krol } 2552861e737e84e4884109b9526ac645194ba892a74Michal Krol } 25694fba49be97008565c0225bc46894bfd9453bb5eVinson Lee 2572861e737e84e4884109b9526ac645194ba892a74Michal Krol return result; 2582861e737e84e4884109b9526ac645194ba892a74Michal Krol} 2592861e737e84e4884109b9526ac645194ba892a74Michal Krol 2602861e737e84e4884109b9526ac645194ba892a74Michal Krol 2612861e737e84e4884109b9526ac645194ba892a74Michal Krol 2622861e737e84e4884109b9526ac645194ba892a74Michal Krol 2632861e737e84e4884109b9526ac645194ba892a74Michal Krol/**********************************************************************/ 2642861e737e84e4884109b9526ac645194ba892a74Michal Krol 2652861e737e84e4884109b9526ac645194ba892a74Michal Krol 2662861e737e84e4884109b9526ac645194ba892a74Michal Krolstatic GLboolean IsLetter(GLubyte b) 2672861e737e84e4884109b9526ac645194ba892a74Michal Krol{ 2682861e737e84e4884109b9526ac645194ba892a74Michal Krol return (b >= 'a' && b <= 'z') || 2692861e737e84e4884109b9526ac645194ba892a74Michal Krol (b >= 'A' && b <= 'Z') || 2702861e737e84e4884109b9526ac645194ba892a74Michal Krol (b == '_') || 2712861e737e84e4884109b9526ac645194ba892a74Michal Krol (b == '$'); 2722861e737e84e4884109b9526ac645194ba892a74Michal Krol} 2732861e737e84e4884109b9526ac645194ba892a74Michal Krol 2742861e737e84e4884109b9526ac645194ba892a74Michal Krol 2752861e737e84e4884109b9526ac645194ba892a74Michal Krolstatic GLboolean IsDigit(GLubyte b) 2762861e737e84e4884109b9526ac645194ba892a74Michal Krol{ 2772861e737e84e4884109b9526ac645194ba892a74Michal Krol return b >= '0' && b <= '9'; 2782861e737e84e4884109b9526ac645194ba892a74Michal Krol} 2792861e737e84e4884109b9526ac645194ba892a74Michal Krol 2802861e737e84e4884109b9526ac645194ba892a74Michal Krol 2812861e737e84e4884109b9526ac645194ba892a74Michal Krolstatic GLboolean IsWhitespace(GLubyte b) 2822861e737e84e4884109b9526ac645194ba892a74Michal Krol{ 2832861e737e84e4884109b9526ac645194ba892a74Michal Krol return b == ' ' || b == '\t' || b == '\n' || b == '\r'; 2842861e737e84e4884109b9526ac645194ba892a74Michal Krol} 2852861e737e84e4884109b9526ac645194ba892a74Michal Krol 2862861e737e84e4884109b9526ac645194ba892a74Michal Krol 2872861e737e84e4884109b9526ac645194ba892a74Michal Krol/** 2882861e737e84e4884109b9526ac645194ba892a74Michal Krol * Starting at 'str' find the next token. A token can be an integer, 2892861e737e84e4884109b9526ac645194ba892a74Michal Krol * an identifier or punctuation symbol. 2902861e737e84e4884109b9526ac645194ba892a74Michal Krol * \return <= 0 we found an error, else, return number of characters parsed. 2912861e737e84e4884109b9526ac645194ba892a74Michal Krol */ 2922861e737e84e4884109b9526ac645194ba892a74Michal Krolstatic GLint 2932861e737e84e4884109b9526ac645194ba892a74Michal KrolGetToken(struct parse_state *parseState, GLubyte *token) 2942861e737e84e4884109b9526ac645194ba892a74Michal Krol{ 2952861e737e84e4884109b9526ac645194ba892a74Michal Krol const GLubyte *str = parseState->pos; 2962861e737e84e4884109b9526ac645194ba892a74Michal Krol GLint i = 0, j = 0; 2972861e737e84e4884109b9526ac645194ba892a74Michal Krol 2982861e737e84e4884109b9526ac645194ba892a74Michal Krol token[0] = 0; 2992861e737e84e4884109b9526ac645194ba892a74Michal Krol 3002861e737e84e4884109b9526ac645194ba892a74Michal Krol /* skip whitespace and comments */ 3012861e737e84e4884109b9526ac645194ba892a74Michal Krol while (str[i] && (IsWhitespace(str[i]) || str[i] == '#')) { 3022861e737e84e4884109b9526ac645194ba892a74Michal Krol if (str[i] == '#') { 3032861e737e84e4884109b9526ac645194ba892a74Michal Krol /* skip comment */ 3042861e737e84e4884109b9526ac645194ba892a74Michal Krol while (str[i] && (str[i] != '\n' && str[i] != '\r')) { 3052861e737e84e4884109b9526ac645194ba892a74Michal Krol i++; 3062861e737e84e4884109b9526ac645194ba892a74Michal Krol } 3072861e737e84e4884109b9526ac645194ba892a74Michal Krol if (str[i] == '\n' || str[i] == '\r') 3082861e737e84e4884109b9526ac645194ba892a74Michal Krol parseState->curLine = str + i + 1; 3092861e737e84e4884109b9526ac645194ba892a74Michal Krol } 3102861e737e84e4884109b9526ac645194ba892a74Michal Krol else { 3112861e737e84e4884109b9526ac645194ba892a74Michal Krol /* skip whitespace */ 3122861e737e84e4884109b9526ac645194ba892a74Michal Krol if (str[i] == '\n' || str[i] == '\r') 3132861e737e84e4884109b9526ac645194ba892a74Michal Krol parseState->curLine = str + i + 1; 3142861e737e84e4884109b9526ac645194ba892a74Michal Krol i++; 3152861e737e84e4884109b9526ac645194ba892a74Michal Krol } 3162861e737e84e4884109b9526ac645194ba892a74Michal Krol } 3172861e737e84e4884109b9526ac645194ba892a74Michal Krol 3182861e737e84e4884109b9526ac645194ba892a74Michal Krol if (str[i] == 0) 3192861e737e84e4884109b9526ac645194ba892a74Michal Krol return -i; 3202861e737e84e4884109b9526ac645194ba892a74Michal Krol 3212861e737e84e4884109b9526ac645194ba892a74Michal Krol /* try matching an integer */ 3222861e737e84e4884109b9526ac645194ba892a74Michal Krol while (str[i] && IsDigit(str[i])) { 3232861e737e84e4884109b9526ac645194ba892a74Michal Krol token[j++] = str[i++]; 3242861e737e84e4884109b9526ac645194ba892a74Michal Krol } 3252861e737e84e4884109b9526ac645194ba892a74Michal Krol if (j > 0 || !str[i]) { 3262861e737e84e4884109b9526ac645194ba892a74Michal Krol token[j] = 0; 3272861e737e84e4884109b9526ac645194ba892a74Michal Krol return i; 3282861e737e84e4884109b9526ac645194ba892a74Michal Krol } 3292861e737e84e4884109b9526ac645194ba892a74Michal Krol 3302861e737e84e4884109b9526ac645194ba892a74Michal Krol /* try matching an identifier */ 3312861e737e84e4884109b9526ac645194ba892a74Michal Krol if (IsLetter(str[i])) { 3322861e737e84e4884109b9526ac645194ba892a74Michal Krol while (str[i] && (IsLetter(str[i]) || IsDigit(str[i]))) { 3332861e737e84e4884109b9526ac645194ba892a74Michal Krol token[j++] = str[i++]; 3342861e737e84e4884109b9526ac645194ba892a74Michal Krol } 3352861e737e84e4884109b9526ac645194ba892a74Michal Krol token[j] = 0; 3362861e737e84e4884109b9526ac645194ba892a74Michal Krol return i; 3372861e737e84e4884109b9526ac645194ba892a74Michal Krol } 3382861e737e84e4884109b9526ac645194ba892a74Michal Krol 3392861e737e84e4884109b9526ac645194ba892a74Michal Krol /* punctuation character */ 3402861e737e84e4884109b9526ac645194ba892a74Michal Krol if (str[i]) { 3412861e737e84e4884109b9526ac645194ba892a74Michal Krol token[0] = str[i++]; 3422861e737e84e4884109b9526ac645194ba892a74Michal Krol token[1] = 0; 3432861e737e84e4884109b9526ac645194ba892a74Michal Krol return i; 3442861e737e84e4884109b9526ac645194ba892a74Michal Krol } 3452861e737e84e4884109b9526ac645194ba892a74Michal Krol 3462861e737e84e4884109b9526ac645194ba892a74Michal Krol /* end of input */ 3472861e737e84e4884109b9526ac645194ba892a74Michal Krol token[0] = 0; 3482861e737e84e4884109b9526ac645194ba892a74Michal Krol return i; 3492861e737e84e4884109b9526ac645194ba892a74Michal Krol} 3502861e737e84e4884109b9526ac645194ba892a74Michal Krol 3512861e737e84e4884109b9526ac645194ba892a74Michal Krol 3522861e737e84e4884109b9526ac645194ba892a74Michal Krol/** 3532861e737e84e4884109b9526ac645194ba892a74Michal Krol * Get next token from input stream and increment stream pointer past token. 3542861e737e84e4884109b9526ac645194ba892a74Michal Krol */ 3552861e737e84e4884109b9526ac645194ba892a74Michal Krolstatic GLboolean 3562861e737e84e4884109b9526ac645194ba892a74Michal KrolParse_Token(struct parse_state *parseState, GLubyte *token) 3572861e737e84e4884109b9526ac645194ba892a74Michal Krol{ 3582861e737e84e4884109b9526ac645194ba892a74Michal Krol GLint i; 3592861e737e84e4884109b9526ac645194ba892a74Michal Krol i = GetToken(parseState, token); 3602861e737e84e4884109b9526ac645194ba892a74Michal Krol if (i <= 0) { 3612861e737e84e4884109b9526ac645194ba892a74Michal Krol parseState->pos += (-i); 3622861e737e84e4884109b9526ac645194ba892a74Michal Krol return GL_FALSE; 3632861e737e84e4884109b9526ac645194ba892a74Michal Krol } 3642861e737e84e4884109b9526ac645194ba892a74Michal Krol parseState->pos += i; 3652861e737e84e4884109b9526ac645194ba892a74Michal Krol return GL_TRUE; 3662861e737e84e4884109b9526ac645194ba892a74Michal Krol} 3672861e737e84e4884109b9526ac645194ba892a74Michal Krol 3682861e737e84e4884109b9526ac645194ba892a74Michal Krol 3692861e737e84e4884109b9526ac645194ba892a74Michal Krol/** 3702861e737e84e4884109b9526ac645194ba892a74Michal Krol * Get next token from input stream but don't increment stream pointer. 3712861e737e84e4884109b9526ac645194ba892a74Michal Krol */ 3722861e737e84e4884109b9526ac645194ba892a74Michal Krolstatic GLboolean 3732861e737e84e4884109b9526ac645194ba892a74Michal KrolPeek_Token(struct parse_state *parseState, GLubyte *token) 3742861e737e84e4884109b9526ac645194ba892a74Michal Krol{ 3752861e737e84e4884109b9526ac645194ba892a74Michal Krol GLint i, len; 3762861e737e84e4884109b9526ac645194ba892a74Michal Krol i = GetToken(parseState, token); 3772861e737e84e4884109b9526ac645194ba892a74Michal Krol if (i <= 0) { 3782861e737e84e4884109b9526ac645194ba892a74Michal Krol parseState->pos += (-i); 3792861e737e84e4884109b9526ac645194ba892a74Michal Krol return GL_FALSE; 3802861e737e84e4884109b9526ac645194ba892a74Michal Krol } 38121d0c70b4b1c18dc1c3ac7d0fbd8a903d60f8be7Kenneth Graunke len = (GLint) strlen((const char *) token); 3822861e737e84e4884109b9526ac645194ba892a74Michal Krol parseState->pos += (i - len); 3832861e737e84e4884109b9526ac645194ba892a74Michal Krol return GL_TRUE; 3842861e737e84e4884109b9526ac645194ba892a74Michal Krol} 3852861e737e84e4884109b9526ac645194ba892a74Michal Krol 3862861e737e84e4884109b9526ac645194ba892a74Michal Krol 3872861e737e84e4884109b9526ac645194ba892a74Michal Krol/**********************************************************************/ 3882861e737e84e4884109b9526ac645194ba892a74Michal Krol 3892861e737e84e4884109b9526ac645194ba892a74Michal Krolstatic const char *InputRegisters[MAX_NV_FRAGMENT_PROGRAM_INPUTS + 1] = { 3902861e737e84e4884109b9526ac645194ba892a74Michal Krol "WPOS", "COL0", "COL1", "FOGC", 3912861e737e84e4884109b9526ac645194ba892a74Michal Krol "TEX0", "TEX1", "TEX2", "TEX3", "TEX4", "TEX5", "TEX6", "TEX7", NULL 3922861e737e84e4884109b9526ac645194ba892a74Michal Krol}; 3932861e737e84e4884109b9526ac645194ba892a74Michal Krol 3948d475822e6e19fa79719c856a2db5b6a205db1b9Brian Paul 3952861e737e84e4884109b9526ac645194ba892a74Michal Krol 3962861e737e84e4884109b9526ac645194ba892a74Michal Krol/**********************************************************************/ 3972861e737e84e4884109b9526ac645194ba892a74Michal Krol 3982861e737e84e4884109b9526ac645194ba892a74Michal Krol/** 3992861e737e84e4884109b9526ac645194ba892a74Michal Krol * Try to match 'pattern' as the next token after any whitespace/comments. 4002861e737e84e4884109b9526ac645194ba892a74Michal Krol */ 4012861e737e84e4884109b9526ac645194ba892a74Michal Krolstatic GLboolean 4022861e737e84e4884109b9526ac645194ba892a74Michal KrolParse_String(struct parse_state *parseState, const char *pattern) 4032861e737e84e4884109b9526ac645194ba892a74Michal Krol{ 4042861e737e84e4884109b9526ac645194ba892a74Michal Krol const GLubyte *m; 4052861e737e84e4884109b9526ac645194ba892a74Michal Krol GLint i; 4062861e737e84e4884109b9526ac645194ba892a74Michal Krol 4072861e737e84e4884109b9526ac645194ba892a74Michal Krol /* skip whitespace and comments */ 4082861e737e84e4884109b9526ac645194ba892a74Michal Krol while (IsWhitespace(*parseState->pos) || *parseState->pos == '#') { 4092861e737e84e4884109b9526ac645194ba892a74Michal Krol if (*parseState->pos == '#') { 4102861e737e84e4884109b9526ac645194ba892a74Michal Krol while (*parseState->pos && (*parseState->pos != '\n' && *parseState->pos != '\r')) { 4112861e737e84e4884109b9526ac645194ba892a74Michal Krol parseState->pos += 1; 4122861e737e84e4884109b9526ac645194ba892a74Michal Krol } 4132861e737e84e4884109b9526ac645194ba892a74Michal Krol if (*parseState->pos == '\n' || *parseState->pos == '\r') 4142861e737e84e4884109b9526ac645194ba892a74Michal Krol parseState->curLine = parseState->pos + 1; 4152861e737e84e4884109b9526ac645194ba892a74Michal Krol } 4162861e737e84e4884109b9526ac645194ba892a74Michal Krol else { 4172861e737e84e4884109b9526ac645194ba892a74Michal Krol /* skip whitespace */ 4182861e737e84e4884109b9526ac645194ba892a74Michal Krol if (*parseState->pos == '\n' || *parseState->pos == '\r') 4192861e737e84e4884109b9526ac645194ba892a74Michal Krol parseState->curLine = parseState->pos + 1; 4202861e737e84e4884109b9526ac645194ba892a74Michal Krol parseState->pos += 1; 4212861e737e84e4884109b9526ac645194ba892a74Michal Krol } 4222861e737e84e4884109b9526ac645194ba892a74Michal Krol } 4232861e737e84e4884109b9526ac645194ba892a74Michal Krol 4242861e737e84e4884109b9526ac645194ba892a74Michal Krol /* Try to match the pattern */ 4252861e737e84e4884109b9526ac645194ba892a74Michal Krol m = parseState->pos; 4262861e737e84e4884109b9526ac645194ba892a74Michal Krol for (i = 0; pattern[i]; i++) { 4272861e737e84e4884109b9526ac645194ba892a74Michal Krol if (*m != (GLubyte) pattern[i]) 4282861e737e84e4884109b9526ac645194ba892a74Michal Krol return GL_FALSE; 4292861e737e84e4884109b9526ac645194ba892a74Michal Krol m += 1; 4302861e737e84e4884109b9526ac645194ba892a74Michal Krol } 4312861e737e84e4884109b9526ac645194ba892a74Michal Krol parseState->pos = m; 4322861e737e84e4884109b9526ac645194ba892a74Michal Krol 4332861e737e84e4884109b9526ac645194ba892a74Michal Krol return GL_TRUE; /* success */ 4342861e737e84e4884109b9526ac645194ba892a74Michal Krol} 4352861e737e84e4884109b9526ac645194ba892a74Michal Krol 4362861e737e84e4884109b9526ac645194ba892a74Michal Krol 4372861e737e84e4884109b9526ac645194ba892a74Michal Krolstatic GLboolean 4382861e737e84e4884109b9526ac645194ba892a74Michal KrolParse_Identifier(struct parse_state *parseState, GLubyte *ident) 4392861e737e84e4884109b9526ac645194ba892a74Michal Krol{ 4402861e737e84e4884109b9526ac645194ba892a74Michal Krol if (!Parse_Token(parseState, ident)) 4412861e737e84e4884109b9526ac645194ba892a74Michal Krol RETURN_ERROR; 4422861e737e84e4884109b9526ac645194ba892a74Michal Krol if (IsLetter(ident[0])) 4432861e737e84e4884109b9526ac645194ba892a74Michal Krol return GL_TRUE; 4442861e737e84e4884109b9526ac645194ba892a74Michal Krol else 4452861e737e84e4884109b9526ac645194ba892a74Michal Krol RETURN_ERROR1("Expected an identfier"); 4462861e737e84e4884109b9526ac645194ba892a74Michal Krol} 4472861e737e84e4884109b9526ac645194ba892a74Michal Krol 4482861e737e84e4884109b9526ac645194ba892a74Michal Krol 4492861e737e84e4884109b9526ac645194ba892a74Michal Krol/** 4502861e737e84e4884109b9526ac645194ba892a74Michal Krol * Parse a floating point constant, or a defined symbol name. 4512861e737e84e4884109b9526ac645194ba892a74Michal Krol * [+/-]N[.N[eN]] 4522861e737e84e4884109b9526ac645194ba892a74Michal Krol * Output: number[0 .. 3] will get the value. 4532861e737e84e4884109b9526ac645194ba892a74Michal Krol */ 4542861e737e84e4884109b9526ac645194ba892a74Michal Krolstatic GLboolean 4552861e737e84e4884109b9526ac645194ba892a74Michal KrolParse_ScalarConstant(struct parse_state *parseState, GLfloat *number) 4562861e737e84e4884109b9526ac645194ba892a74Michal Krol{ 4572861e737e84e4884109b9526ac645194ba892a74Michal Krol char *end = NULL; 4582861e737e84e4884109b9526ac645194ba892a74Michal Krol 4592861e737e84e4884109b9526ac645194ba892a74Michal Krol *number = (GLfloat) _mesa_strtod((const char *) parseState->pos, &end); 4602861e737e84e4884109b9526ac645194ba892a74Michal Krol 4612861e737e84e4884109b9526ac645194ba892a74Michal Krol if (end && end > (char *) parseState->pos) { 4622861e737e84e4884109b9526ac645194ba892a74Michal Krol /* got a number */ 4632861e737e84e4884109b9526ac645194ba892a74Michal Krol parseState->pos = (GLubyte *) end; 4642861e737e84e4884109b9526ac645194ba892a74Michal Krol number[1] = *number; 4652861e737e84e4884109b9526ac645194ba892a74Michal Krol number[2] = *number; 4662861e737e84e4884109b9526ac645194ba892a74Michal Krol number[3] = *number; 4672861e737e84e4884109b9526ac645194ba892a74Michal Krol return GL_TRUE; 4682861e737e84e4884109b9526ac645194ba892a74Michal Krol } 4692861e737e84e4884109b9526ac645194ba892a74Michal Krol else { 4702861e737e84e4884109b9526ac645194ba892a74Michal Krol /* should be an identifier */ 4712861e737e84e4884109b9526ac645194ba892a74Michal Krol GLubyte ident[100]; 4722861e737e84e4884109b9526ac645194ba892a74Michal Krol const GLfloat *constant; 4732861e737e84e4884109b9526ac645194ba892a74Michal Krol if (!Parse_Identifier(parseState, ident)) 4742861e737e84e4884109b9526ac645194ba892a74Michal Krol RETURN_ERROR1("Expected an identifier"); 4752861e737e84e4884109b9526ac645194ba892a74Michal Krol constant = _mesa_lookup_parameter_value(parseState->parameters, 4762861e737e84e4884109b9526ac645194ba892a74Michal Krol -1, (const char *) ident); 4772861e737e84e4884109b9526ac645194ba892a74Michal Krol /* XXX Check that it's a constant and not a parameter */ 4782861e737e84e4884109b9526ac645194ba892a74Michal Krol if (!constant) { 4792861e737e84e4884109b9526ac645194ba892a74Michal Krol RETURN_ERROR1("Undefined symbol"); 4802861e737e84e4884109b9526ac645194ba892a74Michal Krol } 4812861e737e84e4884109b9526ac645194ba892a74Michal Krol else { 4822861e737e84e4884109b9526ac645194ba892a74Michal Krol COPY_4V(number, constant); 4832861e737e84e4884109b9526ac645194ba892a74Michal Krol return GL_TRUE; 4842861e737e84e4884109b9526ac645194ba892a74Michal Krol } 4852861e737e84e4884109b9526ac645194ba892a74Michal Krol } 4862861e737e84e4884109b9526ac645194ba892a74Michal Krol} 4872861e737e84e4884109b9526ac645194ba892a74Michal Krol 4882861e737e84e4884109b9526ac645194ba892a74Michal Krol 4892861e737e84e4884109b9526ac645194ba892a74Michal Krol 4902861e737e84e4884109b9526ac645194ba892a74Michal Krol/** 4912861e737e84e4884109b9526ac645194ba892a74Michal Krol * Parse a vector constant, one of: 4922861e737e84e4884109b9526ac645194ba892a74Michal Krol * { float } 4932861e737e84e4884109b9526ac645194ba892a74Michal Krol * { float, float } 4942861e737e84e4884109b9526ac645194ba892a74Michal Krol * { float, float, float } 4952861e737e84e4884109b9526ac645194ba892a74Michal Krol * { float, float, float, float } 4962861e737e84e4884109b9526ac645194ba892a74Michal Krol */ 4972861e737e84e4884109b9526ac645194ba892a74Michal Krolstatic GLboolean 4982861e737e84e4884109b9526ac645194ba892a74Michal KrolParse_VectorConstant(struct parse_state *parseState, GLfloat *vec) 4992861e737e84e4884109b9526ac645194ba892a74Michal Krol{ 5002861e737e84e4884109b9526ac645194ba892a74Michal Krol /* "{" was already consumed */ 5012861e737e84e4884109b9526ac645194ba892a74Michal Krol 5022861e737e84e4884109b9526ac645194ba892a74Michal Krol ASSIGN_4V(vec, 0.0, 0.0, 0.0, 1.0); 5032861e737e84e4884109b9526ac645194ba892a74Michal Krol 5042861e737e84e4884109b9526ac645194ba892a74Michal Krol if (!Parse_ScalarConstant(parseState, vec+0)) /* X */ 5052861e737e84e4884109b9526ac645194ba892a74Michal Krol return GL_FALSE; 5062861e737e84e4884109b9526ac645194ba892a74Michal Krol 5072861e737e84e4884109b9526ac645194ba892a74Michal Krol if (Parse_String(parseState, "}")) { 5082861e737e84e4884109b9526ac645194ba892a74Michal Krol return GL_TRUE; 5092861e737e84e4884109b9526ac645194ba892a74Michal Krol } 5102861e737e84e4884109b9526ac645194ba892a74Michal Krol 5112861e737e84e4884109b9526ac645194ba892a74Michal Krol if (!Parse_String(parseState, ",")) 5122861e737e84e4884109b9526ac645194ba892a74Michal Krol RETURN_ERROR1("Expected comma in vector constant"); 5132861e737e84e4884109b9526ac645194ba892a74Michal Krol 5142861e737e84e4884109b9526ac645194ba892a74Michal Krol if (!Parse_ScalarConstant(parseState, vec+1)) /* Y */ 5152861e737e84e4884109b9526ac645194ba892a74Michal Krol return GL_FALSE; 5162861e737e84e4884109b9526ac645194ba892a74Michal Krol 5172861e737e84e4884109b9526ac645194ba892a74Michal Krol if (Parse_String(parseState, "}")) { 5182861e737e84e4884109b9526ac645194ba892a74Michal Krol return GL_TRUE; 5192861e737e84e4884109b9526ac645194ba892a74Michal Krol } 5202861e737e84e4884109b9526ac645194ba892a74Michal Krol 5212861e737e84e4884109b9526ac645194ba892a74Michal Krol if (!Parse_String(parseState, ",")) 5222861e737e84e4884109b9526ac645194ba892a74Michal Krol RETURN_ERROR1("Expected comma in vector constant"); 5232861e737e84e4884109b9526ac645194ba892a74Michal Krol 5242861e737e84e4884109b9526ac645194ba892a74Michal Krol if (!Parse_ScalarConstant(parseState, vec+2)) /* Z */ 5252861e737e84e4884109b9526ac645194ba892a74Michal Krol return GL_FALSE; 5262861e737e84e4884109b9526ac645194ba892a74Michal Krol 5272861e737e84e4884109b9526ac645194ba892a74Michal Krol if (Parse_String(parseState, "}")) { 5282861e737e84e4884109b9526ac645194ba892a74Michal Krol return GL_TRUE; 5292861e737e84e4884109b9526ac645194ba892a74Michal Krol } 5302861e737e84e4884109b9526ac645194ba892a74Michal Krol 5312861e737e84e4884109b9526ac645194ba892a74Michal Krol if (!Parse_String(parseState, ",")) 5322861e737e84e4884109b9526ac645194ba892a74Michal Krol RETURN_ERROR1("Expected comma in vector constant"); 5332861e737e84e4884109b9526ac645194ba892a74Michal Krol 5342861e737e84e4884109b9526ac645194ba892a74Michal Krol if (!Parse_ScalarConstant(parseState, vec+3)) /* W */ 5352861e737e84e4884109b9526ac645194ba892a74Michal Krol return GL_FALSE; 5362861e737e84e4884109b9526ac645194ba892a74Michal Krol 5372861e737e84e4884109b9526ac645194ba892a74Michal Krol if (!Parse_String(parseState, "}")) 5382861e737e84e4884109b9526ac645194ba892a74Michal Krol RETURN_ERROR1("Expected closing brace in vector constant"); 5392861e737e84e4884109b9526ac645194ba892a74Michal Krol 5402861e737e84e4884109b9526ac645194ba892a74Michal Krol return GL_TRUE; 5412861e737e84e4884109b9526ac645194ba892a74Michal Krol} 5422861e737e84e4884109b9526ac645194ba892a74Michal Krol 5432861e737e84e4884109b9526ac645194ba892a74Michal Krol 5442861e737e84e4884109b9526ac645194ba892a74Michal Krol/** 5452861e737e84e4884109b9526ac645194ba892a74Michal Krol * Parse <number>, <varname> or {a, b, c, d}. 5462861e737e84e4884109b9526ac645194ba892a74Michal Krol * Return number of values in the vector or scalar, or zero if parse error. 5472861e737e84e4884109b9526ac645194ba892a74Michal Krol */ 5482861e737e84e4884109b9526ac645194ba892a74Michal Krolstatic GLuint 5492861e737e84e4884109b9526ac645194ba892a74Michal KrolParse_VectorOrScalarConstant(struct parse_state *parseState, GLfloat *vec) 5502861e737e84e4884109b9526ac645194ba892a74Michal Krol{ 5512861e737e84e4884109b9526ac645194ba892a74Michal Krol if (Parse_String(parseState, "{")) { 5522861e737e84e4884109b9526ac645194ba892a74Michal Krol return Parse_VectorConstant(parseState, vec); 5532861e737e84e4884109b9526ac645194ba892a74Michal Krol } 5542861e737e84e4884109b9526ac645194ba892a74Michal Krol else { 5552861e737e84e4884109b9526ac645194ba892a74Michal Krol GLboolean b = Parse_ScalarConstant(parseState, vec); 5562861e737e84e4884109b9526ac645194ba892a74Michal Krol if (b) { 5572861e737e84e4884109b9526ac645194ba892a74Michal Krol vec[1] = vec[2] = vec[3] = vec[0]; 5582861e737e84e4884109b9526ac645194ba892a74Michal Krol } 5592861e737e84e4884109b9526ac645194ba892a74Michal Krol return b; 5602861e737e84e4884109b9526ac645194ba892a74Michal Krol } 5612861e737e84e4884109b9526ac645194ba892a74Michal Krol} 5622861e737e84e4884109b9526ac645194ba892a74Michal Krol 5632861e737e84e4884109b9526ac645194ba892a74Michal Krol 5642861e737e84e4884109b9526ac645194ba892a74Michal Krol/** 5652861e737e84e4884109b9526ac645194ba892a74Michal Krol * Parse a texture image source: 5662861e737e84e4884109b9526ac645194ba892a74Michal Krol * [TEX0 | TEX1 | .. | TEX15] , [1D | 2D | 3D | CUBE | RECT] 5672861e737e84e4884109b9526ac645194ba892a74Michal Krol */ 5682861e737e84e4884109b9526ac645194ba892a74Michal Krolstatic GLboolean 5692861e737e84e4884109b9526ac645194ba892a74Michal KrolParse_TextureImageId(struct parse_state *parseState, 5702861e737e84e4884109b9526ac645194ba892a74Michal Krol GLubyte *texUnit, GLubyte *texTargetBit) 5712861e737e84e4884109b9526ac645194ba892a74Michal Krol{ 5722861e737e84e4884109b9526ac645194ba892a74Michal Krol GLubyte imageSrc[100]; 5732861e737e84e4884109b9526ac645194ba892a74Michal Krol GLint unit; 5742861e737e84e4884109b9526ac645194ba892a74Michal Krol 5752861e737e84e4884109b9526ac645194ba892a74Michal Krol if (!Parse_Token(parseState, imageSrc)) 5762861e737e84e4884109b9526ac645194ba892a74Michal Krol RETURN_ERROR; 5772861e737e84e4884109b9526ac645194ba892a74Michal Krol 5782861e737e84e4884109b9526ac645194ba892a74Michal Krol if (imageSrc[0] != 'T' || 5792861e737e84e4884109b9526ac645194ba892a74Michal Krol imageSrc[1] != 'E' || 5802861e737e84e4884109b9526ac645194ba892a74Michal Krol imageSrc[2] != 'X') { 5812861e737e84e4884109b9526ac645194ba892a74Michal Krol RETURN_ERROR1("Expected TEX# source"); 5822861e737e84e4884109b9526ac645194ba892a74Michal Krol } 58360b0cae412029e53654f38d0de151908f1feb310Kenneth Graunke unit = atoi((const char *) imageSrc + 3); 5842861e737e84e4884109b9526ac645194ba892a74Michal Krol if ((unit < 0 || unit > MAX_TEXTURE_IMAGE_UNITS) || 5852861e737e84e4884109b9526ac645194ba892a74Michal Krol (unit == 0 && (imageSrc[3] != '0' || imageSrc[4] != 0))) { 5862861e737e84e4884109b9526ac645194ba892a74Michal Krol RETURN_ERROR1("Invalied TEX# source index"); 5872861e737e84e4884109b9526ac645194ba892a74Michal Krol } 5882861e737e84e4884109b9526ac645194ba892a74Michal Krol *texUnit = unit; 5892861e737e84e4884109b9526ac645194ba892a74Michal Krol 5902861e737e84e4884109b9526ac645194ba892a74Michal Krol if (!Parse_String(parseState, ",")) 5912861e737e84e4884109b9526ac645194ba892a74Michal Krol RETURN_ERROR1("Expected ,"); 5922861e737e84e4884109b9526ac645194ba892a74Michal Krol 5932861e737e84e4884109b9526ac645194ba892a74Michal Krol if (Parse_String(parseState, "1D")) { 5942861e737e84e4884109b9526ac645194ba892a74Michal Krol *texTargetBit = TEXTURE_1D_BIT; 5952861e737e84e4884109b9526ac645194ba892a74Michal Krol } 5962861e737e84e4884109b9526ac645194ba892a74Michal Krol else if (Parse_String(parseState, "2D")) { 5972861e737e84e4884109b9526ac645194ba892a74Michal Krol *texTargetBit = TEXTURE_2D_BIT; 5982861e737e84e4884109b9526ac645194ba892a74Michal Krol } 5992861e737e84e4884109b9526ac645194ba892a74Michal Krol else if (Parse_String(parseState, "3D")) { 6002861e737e84e4884109b9526ac645194ba892a74Michal Krol *texTargetBit = TEXTURE_3D_BIT; 6012861e737e84e4884109b9526ac645194ba892a74Michal Krol } 6022861e737e84e4884109b9526ac645194ba892a74Michal Krol else if (Parse_String(parseState, "CUBE")) { 6032861e737e84e4884109b9526ac645194ba892a74Michal Krol *texTargetBit = TEXTURE_CUBE_BIT; 6042861e737e84e4884109b9526ac645194ba892a74Michal Krol } 6052861e737e84e4884109b9526ac645194ba892a74Michal Krol else if (Parse_String(parseState, "RECT")) { 6062861e737e84e4884109b9526ac645194ba892a74Michal Krol *texTargetBit = TEXTURE_RECT_BIT; 6072861e737e84e4884109b9526ac645194ba892a74Michal Krol } 6082861e737e84e4884109b9526ac645194ba892a74Michal Krol else { 6092861e737e84e4884109b9526ac645194ba892a74Michal Krol RETURN_ERROR1("Invalid texture target token"); 6102861e737e84e4884109b9526ac645194ba892a74Michal Krol } 6112861e737e84e4884109b9526ac645194ba892a74Michal Krol 6122861e737e84e4884109b9526ac645194ba892a74Michal Krol /* update record of referenced texture units */ 6132861e737e84e4884109b9526ac645194ba892a74Michal Krol parseState->texturesUsed[*texUnit] |= *texTargetBit; 6142861e737e84e4884109b9526ac645194ba892a74Michal Krol if (_mesa_bitcount(parseState->texturesUsed[*texUnit]) > 1) { 6152861e737e84e4884109b9526ac645194ba892a74Michal Krol RETURN_ERROR1("Only one texture target can be used per texture unit."); 6162861e737e84e4884109b9526ac645194ba892a74Michal Krol } 6172861e737e84e4884109b9526ac645194ba892a74Michal Krol 6182861e737e84e4884109b9526ac645194ba892a74Michal Krol return GL_TRUE; 6192861e737e84e4884109b9526ac645194ba892a74Michal Krol} 6202861e737e84e4884109b9526ac645194ba892a74Michal Krol 6212861e737e84e4884109b9526ac645194ba892a74Michal Krol 6222861e737e84e4884109b9526ac645194ba892a74Michal Krol/** 6232861e737e84e4884109b9526ac645194ba892a74Michal Krol * Parse a scalar suffix like .x, .y, .z or .w or parse a swizzle suffix 6242861e737e84e4884109b9526ac645194ba892a74Michal Krol * like .wxyz, .xxyy, etc and return the swizzle indexes. 6252861e737e84e4884109b9526ac645194ba892a74Michal Krol */ 6262861e737e84e4884109b9526ac645194ba892a74Michal Krolstatic GLboolean 6272861e737e84e4884109b9526ac645194ba892a74Michal KrolParse_SwizzleSuffix(const GLubyte *token, GLuint swizzle[4]) 6282861e737e84e4884109b9526ac645194ba892a74Michal Krol{ 6292861e737e84e4884109b9526ac645194ba892a74Michal Krol if (token[1] == 0) { 6302861e737e84e4884109b9526ac645194ba892a74Michal Krol /* single letter swizzle (scalar) */ 6312861e737e84e4884109b9526ac645194ba892a74Michal Krol if (token[0] == 'x') 6322861e737e84e4884109b9526ac645194ba892a74Michal Krol ASSIGN_4V(swizzle, 0, 0, 0, 0); 6332861e737e84e4884109b9526ac645194ba892a74Michal Krol else if (token[0] == 'y') 6342861e737e84e4884109b9526ac645194ba892a74Michal Krol ASSIGN_4V(swizzle, 1, 1, 1, 1); 6352861e737e84e4884109b9526ac645194ba892a74Michal Krol else if (token[0] == 'z') 6362861e737e84e4884109b9526ac645194ba892a74Michal Krol ASSIGN_4V(swizzle, 2, 2, 2, 2); 6372861e737e84e4884109b9526ac645194ba892a74Michal Krol else if (token[0] == 'w') 6382861e737e84e4884109b9526ac645194ba892a74Michal Krol ASSIGN_4V(swizzle, 3, 3, 3, 3); 6392861e737e84e4884109b9526ac645194ba892a74Michal Krol else 6402861e737e84e4884109b9526ac645194ba892a74Michal Krol return GL_FALSE; 6412861e737e84e4884109b9526ac645194ba892a74Michal Krol } 6422861e737e84e4884109b9526ac645194ba892a74Michal Krol else { 6432861e737e84e4884109b9526ac645194ba892a74Michal Krol /* 4-component swizzle (vector) */ 6442861e737e84e4884109b9526ac645194ba892a74Michal Krol GLint k; 645324568f79d6e014900c981bd9a0e1dffedc326c8Roel Kluin for (k = 0; k < 4 && token[k]; k++) { 6462861e737e84e4884109b9526ac645194ba892a74Michal Krol if (token[k] == 'x') 6472861e737e84e4884109b9526ac645194ba892a74Michal Krol swizzle[k] = 0; 6482861e737e84e4884109b9526ac645194ba892a74Michal Krol else if (token[k] == 'y') 6492861e737e84e4884109b9526ac645194ba892a74Michal Krol swizzle[k] = 1; 6502861e737e84e4884109b9526ac645194ba892a74Michal Krol else if (token[k] == 'z') 6512861e737e84e4884109b9526ac645194ba892a74Michal Krol swizzle[k] = 2; 6522861e737e84e4884109b9526ac645194ba892a74Michal Krol else if (token[k] == 'w') 6532861e737e84e4884109b9526ac645194ba892a74Michal Krol swizzle[k] = 3; 6542861e737e84e4884109b9526ac645194ba892a74Michal Krol else 6552861e737e84e4884109b9526ac645194ba892a74Michal Krol return GL_FALSE; 6562861e737e84e4884109b9526ac645194ba892a74Michal Krol } 6572861e737e84e4884109b9526ac645194ba892a74Michal Krol if (k != 4) 6582861e737e84e4884109b9526ac645194ba892a74Michal Krol return GL_FALSE; 6592861e737e84e4884109b9526ac645194ba892a74Michal Krol } 6602861e737e84e4884109b9526ac645194ba892a74Michal Krol return GL_TRUE; 6612861e737e84e4884109b9526ac645194ba892a74Michal Krol} 6622861e737e84e4884109b9526ac645194ba892a74Michal Krol 6632861e737e84e4884109b9526ac645194ba892a74Michal Krol 6642861e737e84e4884109b9526ac645194ba892a74Michal Krolstatic GLboolean 6652861e737e84e4884109b9526ac645194ba892a74Michal KrolParse_CondCodeMask(struct parse_state *parseState, 6667e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul struct prog_dst_register *dstReg) 6672861e737e84e4884109b9526ac645194ba892a74Michal Krol{ 6682861e737e84e4884109b9526ac645194ba892a74Michal Krol if (Parse_String(parseState, "EQ")) 6692861e737e84e4884109b9526ac645194ba892a74Michal Krol dstReg->CondMask = COND_EQ; 6702861e737e84e4884109b9526ac645194ba892a74Michal Krol else if (Parse_String(parseState, "GE")) 6712861e737e84e4884109b9526ac645194ba892a74Michal Krol dstReg->CondMask = COND_GE; 6722861e737e84e4884109b9526ac645194ba892a74Michal Krol else if (Parse_String(parseState, "GT")) 6732861e737e84e4884109b9526ac645194ba892a74Michal Krol dstReg->CondMask = COND_GT; 6742861e737e84e4884109b9526ac645194ba892a74Michal Krol else if (Parse_String(parseState, "LE")) 6752861e737e84e4884109b9526ac645194ba892a74Michal Krol dstReg->CondMask = COND_LE; 6762861e737e84e4884109b9526ac645194ba892a74Michal Krol else if (Parse_String(parseState, "LT")) 6772861e737e84e4884109b9526ac645194ba892a74Michal Krol dstReg->CondMask = COND_LT; 6782861e737e84e4884109b9526ac645194ba892a74Michal Krol else if (Parse_String(parseState, "NE")) 6792861e737e84e4884109b9526ac645194ba892a74Michal Krol dstReg->CondMask = COND_NE; 6802861e737e84e4884109b9526ac645194ba892a74Michal Krol else if (Parse_String(parseState, "TR")) 6812861e737e84e4884109b9526ac645194ba892a74Michal Krol dstReg->CondMask = COND_TR; 6822861e737e84e4884109b9526ac645194ba892a74Michal Krol else if (Parse_String(parseState, "FL")) 6832861e737e84e4884109b9526ac645194ba892a74Michal Krol dstReg->CondMask = COND_FL; 6842861e737e84e4884109b9526ac645194ba892a74Michal Krol else 6852861e737e84e4884109b9526ac645194ba892a74Michal Krol RETURN_ERROR1("Invalid condition code mask"); 6862861e737e84e4884109b9526ac645194ba892a74Michal Krol 6872861e737e84e4884109b9526ac645194ba892a74Michal Krol /* look for optional .xyzw swizzle */ 6882861e737e84e4884109b9526ac645194ba892a74Michal Krol if (Parse_String(parseState, ".")) { 6892861e737e84e4884109b9526ac645194ba892a74Michal Krol GLubyte token[100]; 6907c26b61f9366a397e353d7b7f1f1d1f6d0dcd0c7Keith Whitwell GLuint swz[4]; 6917c26b61f9366a397e353d7b7f1f1d1f6d0dcd0c7Keith Whitwell 6922861e737e84e4884109b9526ac645194ba892a74Michal Krol if (!Parse_Token(parseState, token)) /* get xyzw suffix */ 6932861e737e84e4884109b9526ac645194ba892a74Michal Krol RETURN_ERROR; 6942861e737e84e4884109b9526ac645194ba892a74Michal Krol 6957c26b61f9366a397e353d7b7f1f1d1f6d0dcd0c7Keith Whitwell if (!Parse_SwizzleSuffix(token, swz)) 6962861e737e84e4884109b9526ac645194ba892a74Michal Krol RETURN_ERROR1("Invalid swizzle suffix"); 6977c26b61f9366a397e353d7b7f1f1d1f6d0dcd0c7Keith Whitwell 698fd4395b8d1d6f8f018e7e7c3dd0c52fe52ab2794Brian Paul dstReg->CondSwizzle = MAKE_SWIZZLE4(swz[0], swz[1], swz[2], swz[3]); 6992861e737e84e4884109b9526ac645194ba892a74Michal Krol } 7002861e737e84e4884109b9526ac645194ba892a74Michal Krol 7012861e737e84e4884109b9526ac645194ba892a74Michal Krol return GL_TRUE; 7022861e737e84e4884109b9526ac645194ba892a74Michal Krol} 7032861e737e84e4884109b9526ac645194ba892a74Michal Krol 7042861e737e84e4884109b9526ac645194ba892a74Michal Krol 7052861e737e84e4884109b9526ac645194ba892a74Michal Krol/** 7062861e737e84e4884109b9526ac645194ba892a74Michal Krol * Parse a temporary register: Rnn or Hnn 7072861e737e84e4884109b9526ac645194ba892a74Michal Krol */ 7082861e737e84e4884109b9526ac645194ba892a74Michal Krolstatic GLboolean 7092861e737e84e4884109b9526ac645194ba892a74Michal KrolParse_TempReg(struct parse_state *parseState, GLint *tempRegNum) 7102861e737e84e4884109b9526ac645194ba892a74Michal Krol{ 7112861e737e84e4884109b9526ac645194ba892a74Michal Krol GLubyte token[100]; 7122861e737e84e4884109b9526ac645194ba892a74Michal Krol 7132861e737e84e4884109b9526ac645194ba892a74Michal Krol /* Should be 'R##' or 'H##' */ 7142861e737e84e4884109b9526ac645194ba892a74Michal Krol if (!Parse_Token(parseState, token)) 7152861e737e84e4884109b9526ac645194ba892a74Michal Krol RETURN_ERROR; 7162861e737e84e4884109b9526ac645194ba892a74Michal Krol if (token[0] != 'R' && token[0] != 'H') 7172861e737e84e4884109b9526ac645194ba892a74Michal Krol RETURN_ERROR1("Expected R## or H##"); 7182861e737e84e4884109b9526ac645194ba892a74Michal Krol 7192861e737e84e4884109b9526ac645194ba892a74Michal Krol if (IsDigit(token[1])) { 72060b0cae412029e53654f38d0de151908f1feb310Kenneth Graunke GLint reg = atoi((const char *) (token + 1)); 7212861e737e84e4884109b9526ac645194ba892a74Michal Krol if (token[0] == 'H') 7222861e737e84e4884109b9526ac645194ba892a74Michal Krol reg += 32; 7232861e737e84e4884109b9526ac645194ba892a74Michal Krol if (reg >= MAX_NV_FRAGMENT_PROGRAM_TEMPS) 7242861e737e84e4884109b9526ac645194ba892a74Michal Krol RETURN_ERROR1("Invalid temporary register name"); 7252861e737e84e4884109b9526ac645194ba892a74Michal Krol *tempRegNum = reg; 7262861e737e84e4884109b9526ac645194ba892a74Michal Krol } 7272861e737e84e4884109b9526ac645194ba892a74Michal Krol else { 7282861e737e84e4884109b9526ac645194ba892a74Michal Krol RETURN_ERROR1("Invalid temporary register name"); 7292861e737e84e4884109b9526ac645194ba892a74Michal Krol } 7302861e737e84e4884109b9526ac645194ba892a74Michal Krol 7312861e737e84e4884109b9526ac645194ba892a74Michal Krol return GL_TRUE; 7322861e737e84e4884109b9526ac645194ba892a74Michal Krol} 7332861e737e84e4884109b9526ac645194ba892a74Michal Krol 7342861e737e84e4884109b9526ac645194ba892a74Michal Krol 7352861e737e84e4884109b9526ac645194ba892a74Michal Krol/** 7362861e737e84e4884109b9526ac645194ba892a74Michal Krol * Parse a write-only dummy register: RC or HC. 7372861e737e84e4884109b9526ac645194ba892a74Michal Krol */ 7382861e737e84e4884109b9526ac645194ba892a74Michal Krolstatic GLboolean 7392861e737e84e4884109b9526ac645194ba892a74Michal KrolParse_DummyReg(struct parse_state *parseState, GLint *regNum) 7402861e737e84e4884109b9526ac645194ba892a74Michal Krol{ 7412861e737e84e4884109b9526ac645194ba892a74Michal Krol if (Parse_String(parseState, "RC")) { 7422861e737e84e4884109b9526ac645194ba892a74Michal Krol *regNum = 0; 7432861e737e84e4884109b9526ac645194ba892a74Michal Krol } 7442861e737e84e4884109b9526ac645194ba892a74Michal Krol else if (Parse_String(parseState, "HC")) { 7452861e737e84e4884109b9526ac645194ba892a74Michal Krol *regNum = 1; 7462861e737e84e4884109b9526ac645194ba892a74Michal Krol } 7472861e737e84e4884109b9526ac645194ba892a74Michal Krol else { 7482861e737e84e4884109b9526ac645194ba892a74Michal Krol RETURN_ERROR1("Invalid write-only register name"); 7492861e737e84e4884109b9526ac645194ba892a74Michal Krol } 7502861e737e84e4884109b9526ac645194ba892a74Michal Krol 7512861e737e84e4884109b9526ac645194ba892a74Michal Krol return GL_TRUE; 7522861e737e84e4884109b9526ac645194ba892a74Michal Krol} 7532861e737e84e4884109b9526ac645194ba892a74Michal Krol 7542861e737e84e4884109b9526ac645194ba892a74Michal Krol 7552861e737e84e4884109b9526ac645194ba892a74Michal Krol/** 7562861e737e84e4884109b9526ac645194ba892a74Michal Krol * Parse a program local parameter register "p[##]" 7572861e737e84e4884109b9526ac645194ba892a74Michal Krol */ 7582861e737e84e4884109b9526ac645194ba892a74Michal Krolstatic GLboolean 7592861e737e84e4884109b9526ac645194ba892a74Michal KrolParse_ProgramParamReg(struct parse_state *parseState, GLint *regNum) 7602861e737e84e4884109b9526ac645194ba892a74Michal Krol{ 7612861e737e84e4884109b9526ac645194ba892a74Michal Krol GLubyte token[100]; 7622861e737e84e4884109b9526ac645194ba892a74Michal Krol 7632861e737e84e4884109b9526ac645194ba892a74Michal Krol if (!Parse_String(parseState, "p[")) 7642861e737e84e4884109b9526ac645194ba892a74Michal Krol RETURN_ERROR1("Expected p["); 7652861e737e84e4884109b9526ac645194ba892a74Michal Krol 7662861e737e84e4884109b9526ac645194ba892a74Michal Krol if (!Parse_Token(parseState, token)) 7672861e737e84e4884109b9526ac645194ba892a74Michal Krol RETURN_ERROR; 7682861e737e84e4884109b9526ac645194ba892a74Michal Krol 7692861e737e84e4884109b9526ac645194ba892a74Michal Krol if (IsDigit(token[0])) { 7702861e737e84e4884109b9526ac645194ba892a74Michal Krol /* a numbered program parameter register */ 77160b0cae412029e53654f38d0de151908f1feb310Kenneth Graunke GLint reg = atoi((const char *) token); 7722861e737e84e4884109b9526ac645194ba892a74Michal Krol if (reg >= MAX_NV_FRAGMENT_PROGRAM_PARAMS) 7732861e737e84e4884109b9526ac645194ba892a74Michal Krol RETURN_ERROR1("Invalid constant program number"); 7742861e737e84e4884109b9526ac645194ba892a74Michal Krol *regNum = reg; 7752861e737e84e4884109b9526ac645194ba892a74Michal Krol } 7762861e737e84e4884109b9526ac645194ba892a74Michal Krol else { 7772861e737e84e4884109b9526ac645194ba892a74Michal Krol RETURN_ERROR; 7782861e737e84e4884109b9526ac645194ba892a74Michal Krol } 7792861e737e84e4884109b9526ac645194ba892a74Michal Krol 7802861e737e84e4884109b9526ac645194ba892a74Michal Krol if (!Parse_String(parseState, "]")) 7812861e737e84e4884109b9526ac645194ba892a74Michal Krol RETURN_ERROR1("Expected ]"); 7822861e737e84e4884109b9526ac645194ba892a74Michal Krol 7832861e737e84e4884109b9526ac645194ba892a74Michal Krol return GL_TRUE; 7842861e737e84e4884109b9526ac645194ba892a74Michal Krol} 7852861e737e84e4884109b9526ac645194ba892a74Michal Krol 7862861e737e84e4884109b9526ac645194ba892a74Michal Krol 7872861e737e84e4884109b9526ac645194ba892a74Michal Krol/** 7882861e737e84e4884109b9526ac645194ba892a74Michal Krol * Parse f[name] - fragment input register 7892861e737e84e4884109b9526ac645194ba892a74Michal Krol */ 7902861e737e84e4884109b9526ac645194ba892a74Michal Krolstatic GLboolean 7912861e737e84e4884109b9526ac645194ba892a74Michal KrolParse_FragReg(struct parse_state *parseState, GLint *tempRegNum) 7922861e737e84e4884109b9526ac645194ba892a74Michal Krol{ 7932861e737e84e4884109b9526ac645194ba892a74Michal Krol GLubyte token[100]; 7942861e737e84e4884109b9526ac645194ba892a74Michal Krol GLint j; 7952861e737e84e4884109b9526ac645194ba892a74Michal Krol 7962861e737e84e4884109b9526ac645194ba892a74Michal Krol /* Match 'f[' */ 7972861e737e84e4884109b9526ac645194ba892a74Michal Krol if (!Parse_String(parseState, "f[")) 7982861e737e84e4884109b9526ac645194ba892a74Michal Krol RETURN_ERROR1("Expected f["); 7992861e737e84e4884109b9526ac645194ba892a74Michal Krol 8002861e737e84e4884109b9526ac645194ba892a74Michal Krol /* get <name> and look for match */ 8012861e737e84e4884109b9526ac645194ba892a74Michal Krol if (!Parse_Token(parseState, token)) { 8022861e737e84e4884109b9526ac645194ba892a74Michal Krol RETURN_ERROR; 8032861e737e84e4884109b9526ac645194ba892a74Michal Krol } 8042861e737e84e4884109b9526ac645194ba892a74Michal Krol for (j = 0; InputRegisters[j]; j++) { 8058d73aa6d1ae6e89bb2cd8f52f5586d569a4b6eebKenneth Graunke if (strcmp((const char *) token, InputRegisters[j]) == 0) { 8062861e737e84e4884109b9526ac645194ba892a74Michal Krol *tempRegNum = j; 8072861e737e84e4884109b9526ac645194ba892a74Michal Krol parseState->inputsRead |= (1 << j); 8082861e737e84e4884109b9526ac645194ba892a74Michal Krol break; 8092861e737e84e4884109b9526ac645194ba892a74Michal Krol } 8102861e737e84e4884109b9526ac645194ba892a74Michal Krol } 8112861e737e84e4884109b9526ac645194ba892a74Michal Krol if (!InputRegisters[j]) { 8122861e737e84e4884109b9526ac645194ba892a74Michal Krol /* unknown input register label */ 8132861e737e84e4884109b9526ac645194ba892a74Michal Krol RETURN_ERROR2("Invalid register name", token); 8142861e737e84e4884109b9526ac645194ba892a74Michal Krol } 8152861e737e84e4884109b9526ac645194ba892a74Michal Krol 8162861e737e84e4884109b9526ac645194ba892a74Michal Krol /* Match '[' */ 8172861e737e84e4884109b9526ac645194ba892a74Michal Krol if (!Parse_String(parseState, "]")) 8182861e737e84e4884109b9526ac645194ba892a74Michal Krol RETURN_ERROR1("Expected ]"); 8192861e737e84e4884109b9526ac645194ba892a74Michal Krol 8202861e737e84e4884109b9526ac645194ba892a74Michal Krol return GL_TRUE; 8212861e737e84e4884109b9526ac645194ba892a74Michal Krol} 8222861e737e84e4884109b9526ac645194ba892a74Michal Krol 8232861e737e84e4884109b9526ac645194ba892a74Michal Krol 8242861e737e84e4884109b9526ac645194ba892a74Michal Krolstatic GLboolean 8252861e737e84e4884109b9526ac645194ba892a74Michal KrolParse_OutputReg(struct parse_state *parseState, GLint *outputRegNum) 8262861e737e84e4884109b9526ac645194ba892a74Michal Krol{ 8272861e737e84e4884109b9526ac645194ba892a74Michal Krol GLubyte token[100]; 8282861e737e84e4884109b9526ac645194ba892a74Michal Krol 8292861e737e84e4884109b9526ac645194ba892a74Michal Krol /* Match "o[" */ 8302861e737e84e4884109b9526ac645194ba892a74Michal Krol if (!Parse_String(parseState, "o[")) 8312861e737e84e4884109b9526ac645194ba892a74Michal Krol RETURN_ERROR1("Expected o["); 8322861e737e84e4884109b9526ac645194ba892a74Michal Krol 8332861e737e84e4884109b9526ac645194ba892a74Michal Krol /* Get output reg name */ 8342861e737e84e4884109b9526ac645194ba892a74Michal Krol if (!Parse_Token(parseState, token)) 8352861e737e84e4884109b9526ac645194ba892a74Michal Krol RETURN_ERROR; 8362861e737e84e4884109b9526ac645194ba892a74Michal Krol 8372861e737e84e4884109b9526ac645194ba892a74Michal Krol /* try to match an output register name */ 8388d73aa6d1ae6e89bb2cd8f52f5586d569a4b6eebKenneth Graunke if (strcmp((char *) token, "COLR") == 0 || 8398d73aa6d1ae6e89bb2cd8f52f5586d569a4b6eebKenneth Graunke strcmp((char *) token, "COLH") == 0) { 8408d475822e6e19fa79719c856a2db5b6a205db1b9Brian Paul /* note that we don't distinguish between COLR and COLH */ 8418d475822e6e19fa79719c856a2db5b6a205db1b9Brian Paul *outputRegNum = FRAG_RESULT_COLOR; 8428d475822e6e19fa79719c856a2db5b6a205db1b9Brian Paul parseState->outputsWritten |= (1 << FRAG_RESULT_COLOR); 8432861e737e84e4884109b9526ac645194ba892a74Michal Krol } 8448d73aa6d1ae6e89bb2cd8f52f5586d569a4b6eebKenneth Graunke else if (strcmp((char *) token, "DEPR") == 0) { 8458d475822e6e19fa79719c856a2db5b6a205db1b9Brian Paul *outputRegNum = FRAG_RESULT_DEPTH; 8468d475822e6e19fa79719c856a2db5b6a205db1b9Brian Paul parseState->outputsWritten |= (1 << FRAG_RESULT_DEPTH); 8478d475822e6e19fa79719c856a2db5b6a205db1b9Brian Paul } 8488d475822e6e19fa79719c856a2db5b6a205db1b9Brian Paul else { 8492861e737e84e4884109b9526ac645194ba892a74Michal Krol RETURN_ERROR1("Invalid output register name"); 8508d475822e6e19fa79719c856a2db5b6a205db1b9Brian Paul } 8512861e737e84e4884109b9526ac645194ba892a74Michal Krol 8522861e737e84e4884109b9526ac645194ba892a74Michal Krol /* Match ']' */ 8532861e737e84e4884109b9526ac645194ba892a74Michal Krol if (!Parse_String(parseState, "]")) 8542861e737e84e4884109b9526ac645194ba892a74Michal Krol RETURN_ERROR1("Expected ]"); 8552861e737e84e4884109b9526ac645194ba892a74Michal Krol 8562861e737e84e4884109b9526ac645194ba892a74Michal Krol return GL_TRUE; 8572861e737e84e4884109b9526ac645194ba892a74Michal Krol} 8582861e737e84e4884109b9526ac645194ba892a74Michal Krol 8592861e737e84e4884109b9526ac645194ba892a74Michal Krol 8602861e737e84e4884109b9526ac645194ba892a74Michal Krolstatic GLboolean 8612861e737e84e4884109b9526ac645194ba892a74Michal KrolParse_MaskedDstReg(struct parse_state *parseState, 8627e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul struct prog_dst_register *dstReg) 8632861e737e84e4884109b9526ac645194ba892a74Michal Krol{ 8642861e737e84e4884109b9526ac645194ba892a74Michal Krol GLubyte token[100]; 8657c26b61f9366a397e353d7b7f1f1d1f6d0dcd0c7Keith Whitwell GLint idx; 8662861e737e84e4884109b9526ac645194ba892a74Michal Krol 8672861e737e84e4884109b9526ac645194ba892a74Michal Krol /* Dst reg can be R<n>, H<n>, o[n], RC or HC */ 8682861e737e84e4884109b9526ac645194ba892a74Michal Krol if (!Peek_Token(parseState, token)) 8692861e737e84e4884109b9526ac645194ba892a74Michal Krol RETURN_ERROR; 8702861e737e84e4884109b9526ac645194ba892a74Michal Krol 8718d73aa6d1ae6e89bb2cd8f52f5586d569a4b6eebKenneth Graunke if (strcmp((const char *) token, "RC") == 0 || 8728d73aa6d1ae6e89bb2cd8f52f5586d569a4b6eebKenneth Graunke strcmp((const char *) token, "HC") == 0) { 8732861e737e84e4884109b9526ac645194ba892a74Michal Krol /* a write-only register */ 8742861e737e84e4884109b9526ac645194ba892a74Michal Krol dstReg->File = PROGRAM_WRITE_ONLY; 8757c26b61f9366a397e353d7b7f1f1d1f6d0dcd0c7Keith Whitwell if (!Parse_DummyReg(parseState, &idx)) 8762861e737e84e4884109b9526ac645194ba892a74Michal Krol RETURN_ERROR; 8777c26b61f9366a397e353d7b7f1f1d1f6d0dcd0c7Keith Whitwell dstReg->Index = idx; 8782861e737e84e4884109b9526ac645194ba892a74Michal Krol } 8792861e737e84e4884109b9526ac645194ba892a74Michal Krol else if (token[0] == 'R' || token[0] == 'H') { 8802861e737e84e4884109b9526ac645194ba892a74Michal Krol /* a temporary register */ 8812861e737e84e4884109b9526ac645194ba892a74Michal Krol dstReg->File = PROGRAM_TEMPORARY; 8827c26b61f9366a397e353d7b7f1f1d1f6d0dcd0c7Keith Whitwell if (!Parse_TempReg(parseState, &idx)) 8832861e737e84e4884109b9526ac645194ba892a74Michal Krol RETURN_ERROR; 8847c26b61f9366a397e353d7b7f1f1d1f6d0dcd0c7Keith Whitwell dstReg->Index = idx; 8852861e737e84e4884109b9526ac645194ba892a74Michal Krol } 8862861e737e84e4884109b9526ac645194ba892a74Michal Krol else if (token[0] == 'o') { 8872861e737e84e4884109b9526ac645194ba892a74Michal Krol /* an output register */ 8882861e737e84e4884109b9526ac645194ba892a74Michal Krol dstReg->File = PROGRAM_OUTPUT; 8897c26b61f9366a397e353d7b7f1f1d1f6d0dcd0c7Keith Whitwell if (!Parse_OutputReg(parseState, &idx)) 8902861e737e84e4884109b9526ac645194ba892a74Michal Krol RETURN_ERROR; 8917c26b61f9366a397e353d7b7f1f1d1f6d0dcd0c7Keith Whitwell dstReg->Index = idx; 8922861e737e84e4884109b9526ac645194ba892a74Michal Krol } 8932861e737e84e4884109b9526ac645194ba892a74Michal Krol else { 8942861e737e84e4884109b9526ac645194ba892a74Michal Krol RETURN_ERROR1("Invalid destination register name"); 8952861e737e84e4884109b9526ac645194ba892a74Michal Krol } 8962861e737e84e4884109b9526ac645194ba892a74Michal Krol 8972861e737e84e4884109b9526ac645194ba892a74Michal Krol /* Parse optional write mask */ 8982861e737e84e4884109b9526ac645194ba892a74Michal Krol if (Parse_String(parseState, ".")) { 8992861e737e84e4884109b9526ac645194ba892a74Michal Krol /* got a mask */ 9002861e737e84e4884109b9526ac645194ba892a74Michal Krol GLint k = 0; 9012861e737e84e4884109b9526ac645194ba892a74Michal Krol 9022861e737e84e4884109b9526ac645194ba892a74Michal Krol if (!Parse_Token(parseState, token)) /* get xyzw writemask */ 9032861e737e84e4884109b9526ac645194ba892a74Michal Krol RETURN_ERROR; 9042861e737e84e4884109b9526ac645194ba892a74Michal Krol 9057c26b61f9366a397e353d7b7f1f1d1f6d0dcd0c7Keith Whitwell dstReg->WriteMask = 0; 9062861e737e84e4884109b9526ac645194ba892a74Michal Krol 9072861e737e84e4884109b9526ac645194ba892a74Michal Krol if (token[k] == 'x') { 9087c26b61f9366a397e353d7b7f1f1d1f6d0dcd0c7Keith Whitwell dstReg->WriteMask |= WRITEMASK_X; 9092861e737e84e4884109b9526ac645194ba892a74Michal Krol k++; 9102861e737e84e4884109b9526ac645194ba892a74Michal Krol } 9112861e737e84e4884109b9526ac645194ba892a74Michal Krol if (token[k] == 'y') { 9127c26b61f9366a397e353d7b7f1f1d1f6d0dcd0c7Keith Whitwell dstReg->WriteMask |= WRITEMASK_Y; 9132861e737e84e4884109b9526ac645194ba892a74Michal Krol k++; 9142861e737e84e4884109b9526ac645194ba892a74Michal Krol } 9152861e737e84e4884109b9526ac645194ba892a74Michal Krol if (token[k] == 'z') { 9167c26b61f9366a397e353d7b7f1f1d1f6d0dcd0c7Keith Whitwell dstReg->WriteMask |= WRITEMASK_Z; 9172861e737e84e4884109b9526ac645194ba892a74Michal Krol k++; 9182861e737e84e4884109b9526ac645194ba892a74Michal Krol } 9192861e737e84e4884109b9526ac645194ba892a74Michal Krol if (token[k] == 'w') { 9207c26b61f9366a397e353d7b7f1f1d1f6d0dcd0c7Keith Whitwell dstReg->WriteMask |= WRITEMASK_W; 9212861e737e84e4884109b9526ac645194ba892a74Michal Krol k++; 9222861e737e84e4884109b9526ac645194ba892a74Michal Krol } 9232861e737e84e4884109b9526ac645194ba892a74Michal Krol if (k == 0) { 9242861e737e84e4884109b9526ac645194ba892a74Michal Krol RETURN_ERROR1("Invalid writemask character"); 9252861e737e84e4884109b9526ac645194ba892a74Michal Krol } 9262861e737e84e4884109b9526ac645194ba892a74Michal Krol 9272861e737e84e4884109b9526ac645194ba892a74Michal Krol } 9282861e737e84e4884109b9526ac645194ba892a74Michal Krol else { 9297c26b61f9366a397e353d7b7f1f1d1f6d0dcd0c7Keith Whitwell dstReg->WriteMask = WRITEMASK_XYZW; 9302861e737e84e4884109b9526ac645194ba892a74Michal Krol } 9312861e737e84e4884109b9526ac645194ba892a74Michal Krol 9322861e737e84e4884109b9526ac645194ba892a74Michal Krol /* optional condition code mask */ 9332861e737e84e4884109b9526ac645194ba892a74Michal Krol if (Parse_String(parseState, "(")) { 9342861e737e84e4884109b9526ac645194ba892a74Michal Krol /* ("EQ" | "GE" | "GT" | "LE" | "LT" | "NE" | "TR" | "FL".x|y|z|w) */ 9352861e737e84e4884109b9526ac645194ba892a74Michal Krol /* ("EQ" | "GE" | "GT" | "LE" | "LT" | "NE" | "TR" | "FL".[xyzw]) */ 9362861e737e84e4884109b9526ac645194ba892a74Michal Krol if (!Parse_CondCodeMask(parseState, dstReg)) 9372861e737e84e4884109b9526ac645194ba892a74Michal Krol RETURN_ERROR; 9382861e737e84e4884109b9526ac645194ba892a74Michal Krol 9392861e737e84e4884109b9526ac645194ba892a74Michal Krol if (!Parse_String(parseState, ")")) /* consume ")" */ 9402861e737e84e4884109b9526ac645194ba892a74Michal Krol RETURN_ERROR1("Expected )"); 9412861e737e84e4884109b9526ac645194ba892a74Michal Krol 9422861e737e84e4884109b9526ac645194ba892a74Michal Krol return GL_TRUE; 9432861e737e84e4884109b9526ac645194ba892a74Michal Krol } 9442861e737e84e4884109b9526ac645194ba892a74Michal Krol else { 9452861e737e84e4884109b9526ac645194ba892a74Michal Krol /* no cond code mask */ 9462861e737e84e4884109b9526ac645194ba892a74Michal Krol dstReg->CondMask = COND_TR; 9477c26b61f9366a397e353d7b7f1f1d1f6d0dcd0c7Keith Whitwell dstReg->CondSwizzle = SWIZZLE_NOOP; 9482861e737e84e4884109b9526ac645194ba892a74Michal Krol return GL_TRUE; 9492861e737e84e4884109b9526ac645194ba892a74Michal Krol } 9502861e737e84e4884109b9526ac645194ba892a74Michal Krol} 9512861e737e84e4884109b9526ac645194ba892a74Michal Krol 9522861e737e84e4884109b9526ac645194ba892a74Michal Krol 9532861e737e84e4884109b9526ac645194ba892a74Michal Krol/** 9542861e737e84e4884109b9526ac645194ba892a74Michal Krol * Parse a vector source (register, constant, etc): 9552861e737e84e4884109b9526ac645194ba892a74Michal Krol * <vectorSrc> ::= <absVectorSrc> 9562861e737e84e4884109b9526ac645194ba892a74Michal Krol * | <baseVectorSrc> 9572861e737e84e4884109b9526ac645194ba892a74Michal Krol * <absVectorSrc> ::= <negate> "|" <baseVectorSrc> "|" 9582861e737e84e4884109b9526ac645194ba892a74Michal Krol */ 9592861e737e84e4884109b9526ac645194ba892a74Michal Krolstatic GLboolean 9602861e737e84e4884109b9526ac645194ba892a74Michal KrolParse_VectorSrc(struct parse_state *parseState, 9617e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul struct prog_src_register *srcReg) 9622861e737e84e4884109b9526ac645194ba892a74Michal Krol{ 9632861e737e84e4884109b9526ac645194ba892a74Michal Krol GLfloat sign = 1.0F; 9642861e737e84e4884109b9526ac645194ba892a74Michal Krol GLubyte token[100]; 9657c26b61f9366a397e353d7b7f1f1d1f6d0dcd0c7Keith Whitwell GLint idx; 9667db7ff878d3e5a6b345228e6eaee4797bb68b360Brian Paul GLuint negateBase, negateAbs; 9672861e737e84e4884109b9526ac645194ba892a74Michal Krol 9682861e737e84e4884109b9526ac645194ba892a74Michal Krol /* 9692861e737e84e4884109b9526ac645194ba892a74Michal Krol * First, take care of +/- and absolute value stuff. 9702861e737e84e4884109b9526ac645194ba892a74Michal Krol */ 9712861e737e84e4884109b9526ac645194ba892a74Michal Krol if (Parse_String(parseState, "-")) 9722861e737e84e4884109b9526ac645194ba892a74Michal Krol sign = -1.0F; 9732861e737e84e4884109b9526ac645194ba892a74Michal Krol else if (Parse_String(parseState, "+")) 9742861e737e84e4884109b9526ac645194ba892a74Michal Krol sign = +1.0F; 9752861e737e84e4884109b9526ac645194ba892a74Michal Krol 9762861e737e84e4884109b9526ac645194ba892a74Michal Krol if (Parse_String(parseState, "|")) { 9772861e737e84e4884109b9526ac645194ba892a74Michal Krol srcReg->Abs = GL_TRUE; 9787db7ff878d3e5a6b345228e6eaee4797bb68b360Brian Paul negateAbs = (sign < 0.0F) ? NEGATE_XYZW : NEGATE_NONE; 9792861e737e84e4884109b9526ac645194ba892a74Michal Krol 9802861e737e84e4884109b9526ac645194ba892a74Michal Krol if (Parse_String(parseState, "-")) 9817db7ff878d3e5a6b345228e6eaee4797bb68b360Brian Paul negateBase = NEGATE_XYZW; 9822861e737e84e4884109b9526ac645194ba892a74Michal Krol else if (Parse_String(parseState, "+")) 9837db7ff878d3e5a6b345228e6eaee4797bb68b360Brian Paul negateBase = NEGATE_NONE; 9842861e737e84e4884109b9526ac645194ba892a74Michal Krol else 9857db7ff878d3e5a6b345228e6eaee4797bb68b360Brian Paul negateBase = NEGATE_NONE; 9862861e737e84e4884109b9526ac645194ba892a74Michal Krol } 9872861e737e84e4884109b9526ac645194ba892a74Michal Krol else { 9882861e737e84e4884109b9526ac645194ba892a74Michal Krol srcReg->Abs = GL_FALSE; 9897db7ff878d3e5a6b345228e6eaee4797bb68b360Brian Paul negateAbs = NEGATE_NONE; 9907db7ff878d3e5a6b345228e6eaee4797bb68b360Brian Paul negateBase = (sign < 0.0F) ? NEGATE_XYZW : NEGATE_NONE; 9912861e737e84e4884109b9526ac645194ba892a74Michal Krol } 9922861e737e84e4884109b9526ac645194ba892a74Michal Krol 9937db7ff878d3e5a6b345228e6eaee4797bb68b360Brian Paul srcReg->Negate = srcReg->Abs ? negateAbs : negateBase; 9947db7ff878d3e5a6b345228e6eaee4797bb68b360Brian Paul 9952861e737e84e4884109b9526ac645194ba892a74Michal Krol /* This should be the real src vector/register name */ 9962861e737e84e4884109b9526ac645194ba892a74Michal Krol if (!Peek_Token(parseState, token)) 9972861e737e84e4884109b9526ac645194ba892a74Michal Krol RETURN_ERROR; 9982861e737e84e4884109b9526ac645194ba892a74Michal Krol 9992861e737e84e4884109b9526ac645194ba892a74Michal Krol /* Src reg can be Rn, Hn, f[n], p[n], a named parameter, a scalar 10002861e737e84e4884109b9526ac645194ba892a74Michal Krol * literal or vector literal. 10012861e737e84e4884109b9526ac645194ba892a74Michal Krol */ 10022861e737e84e4884109b9526ac645194ba892a74Michal Krol if (token[0] == 'R' || token[0] == 'H') { 10032861e737e84e4884109b9526ac645194ba892a74Michal Krol srcReg->File = PROGRAM_TEMPORARY; 10047c26b61f9366a397e353d7b7f1f1d1f6d0dcd0c7Keith Whitwell if (!Parse_TempReg(parseState, &idx)) 10052861e737e84e4884109b9526ac645194ba892a74Michal Krol RETURN_ERROR; 10067c26b61f9366a397e353d7b7f1f1d1f6d0dcd0c7Keith Whitwell srcReg->Index = idx; 10072861e737e84e4884109b9526ac645194ba892a74Michal Krol } 10082861e737e84e4884109b9526ac645194ba892a74Michal Krol else if (token[0] == 'f') { 1009e6940f0a33a571b199bab60b680c30b718c47445Brian Paul /* XXX this might be an identifier! */ 10102861e737e84e4884109b9526ac645194ba892a74Michal Krol srcReg->File = PROGRAM_INPUT; 10117c26b61f9366a397e353d7b7f1f1d1f6d0dcd0c7Keith Whitwell if (!Parse_FragReg(parseState, &idx)) 10122861e737e84e4884109b9526ac645194ba892a74Michal Krol RETURN_ERROR; 10137c26b61f9366a397e353d7b7f1f1d1f6d0dcd0c7Keith Whitwell srcReg->Index = idx; 10142861e737e84e4884109b9526ac645194ba892a74Michal Krol } 10152861e737e84e4884109b9526ac645194ba892a74Michal Krol else if (token[0] == 'p') { 1016e6940f0a33a571b199bab60b680c30b718c47445Brian Paul /* XXX this might be an identifier! */ 10172861e737e84e4884109b9526ac645194ba892a74Michal Krol srcReg->File = PROGRAM_LOCAL_PARAM; 10187c26b61f9366a397e353d7b7f1f1d1f6d0dcd0c7Keith Whitwell if (!Parse_ProgramParamReg(parseState, &idx)) 10192861e737e84e4884109b9526ac645194ba892a74Michal Krol RETURN_ERROR; 10207c26b61f9366a397e353d7b7f1f1d1f6d0dcd0c7Keith Whitwell srcReg->Index = idx; 10212861e737e84e4884109b9526ac645194ba892a74Michal Krol } 10222861e737e84e4884109b9526ac645194ba892a74Michal Krol else if (IsLetter(token[0])){ 10232861e737e84e4884109b9526ac645194ba892a74Michal Krol GLubyte ident[100]; 10242861e737e84e4884109b9526ac645194ba892a74Michal Krol GLint paramIndex; 10252861e737e84e4884109b9526ac645194ba892a74Michal Krol if (!Parse_Identifier(parseState, ident)) 10262861e737e84e4884109b9526ac645194ba892a74Michal Krol RETURN_ERROR; 10272861e737e84e4884109b9526ac645194ba892a74Michal Krol paramIndex = _mesa_lookup_parameter_index(parseState->parameters, 10282861e737e84e4884109b9526ac645194ba892a74Michal Krol -1, (const char *) ident); 10292861e737e84e4884109b9526ac645194ba892a74Michal Krol if (paramIndex < 0) { 10302861e737e84e4884109b9526ac645194ba892a74Michal Krol RETURN_ERROR2("Undefined constant or parameter: ", ident); 10312861e737e84e4884109b9526ac645194ba892a74Michal Krol } 10322861e737e84e4884109b9526ac645194ba892a74Michal Krol srcReg->File = PROGRAM_NAMED_PARAM; 10332861e737e84e4884109b9526ac645194ba892a74Michal Krol srcReg->Index = paramIndex; 10342861e737e84e4884109b9526ac645194ba892a74Michal Krol } 10352861e737e84e4884109b9526ac645194ba892a74Michal Krol else if (IsDigit(token[0]) || token[0] == '-' || token[0] == '+' || token[0] == '.'){ 10362861e737e84e4884109b9526ac645194ba892a74Michal Krol /* literal scalar constant */ 10372861e737e84e4884109b9526ac645194ba892a74Michal Krol GLfloat values[4]; 1038257f799849a1eb3e81851b92a8fd27efa8f93d47Brian GLuint paramIndex; 10392861e737e84e4884109b9526ac645194ba892a74Michal Krol if (!Parse_ScalarConstant(parseState, values)) 10402861e737e84e4884109b9526ac645194ba892a74Michal Krol RETURN_ERROR; 1041fe1d01cb398cbcb5b28a0b222845d3865c4d612bBrian paramIndex = _mesa_add_unnamed_constant(parseState->parameters, 10421bf81e3c5d65b636658d11072f4f027f5c499396Brian values, 4, NULL); 10432861e737e84e4884109b9526ac645194ba892a74Michal Krol srcReg->File = PROGRAM_NAMED_PARAM; 10442861e737e84e4884109b9526ac645194ba892a74Michal Krol srcReg->Index = paramIndex; 10452861e737e84e4884109b9526ac645194ba892a74Michal Krol } 10462861e737e84e4884109b9526ac645194ba892a74Michal Krol else if (token[0] == '{'){ 10472861e737e84e4884109b9526ac645194ba892a74Michal Krol /* literal vector constant */ 10482861e737e84e4884109b9526ac645194ba892a74Michal Krol GLfloat values[4]; 1049257f799849a1eb3e81851b92a8fd27efa8f93d47Brian GLuint paramIndex; 10502861e737e84e4884109b9526ac645194ba892a74Michal Krol (void) Parse_String(parseState, "{"); 10512861e737e84e4884109b9526ac645194ba892a74Michal Krol if (!Parse_VectorConstant(parseState, values)) 10522861e737e84e4884109b9526ac645194ba892a74Michal Krol RETURN_ERROR; 1053fe1d01cb398cbcb5b28a0b222845d3865c4d612bBrian paramIndex = _mesa_add_unnamed_constant(parseState->parameters, 10541bf81e3c5d65b636658d11072f4f027f5c499396Brian values, 4, NULL); 10552861e737e84e4884109b9526ac645194ba892a74Michal Krol srcReg->File = PROGRAM_NAMED_PARAM; 10562861e737e84e4884109b9526ac645194ba892a74Michal Krol srcReg->Index = paramIndex; 10572861e737e84e4884109b9526ac645194ba892a74Michal Krol } 10582861e737e84e4884109b9526ac645194ba892a74Michal Krol else { 10592861e737e84e4884109b9526ac645194ba892a74Michal Krol RETURN_ERROR2("Invalid source register name", token); 10602861e737e84e4884109b9526ac645194ba892a74Michal Krol } 10612861e737e84e4884109b9526ac645194ba892a74Michal Krol 10622861e737e84e4884109b9526ac645194ba892a74Michal Krol /* init swizzle fields */ 10637c26b61f9366a397e353d7b7f1f1d1f6d0dcd0c7Keith Whitwell srcReg->Swizzle = SWIZZLE_NOOP; 10642861e737e84e4884109b9526ac645194ba892a74Michal Krol 10652861e737e84e4884109b9526ac645194ba892a74Michal Krol /* Look for optional swizzle suffix */ 10662861e737e84e4884109b9526ac645194ba892a74Michal Krol if (Parse_String(parseState, ".")) { 10677c26b61f9366a397e353d7b7f1f1d1f6d0dcd0c7Keith Whitwell GLuint swz[4]; 10687c26b61f9366a397e353d7b7f1f1d1f6d0dcd0c7Keith Whitwell 10692861e737e84e4884109b9526ac645194ba892a74Michal Krol if (!Parse_Token(parseState, token)) 10702861e737e84e4884109b9526ac645194ba892a74Michal Krol RETURN_ERROR; 10712861e737e84e4884109b9526ac645194ba892a74Michal Krol 10727c26b61f9366a397e353d7b7f1f1d1f6d0dcd0c7Keith Whitwell if (!Parse_SwizzleSuffix(token, swz)) 10732861e737e84e4884109b9526ac645194ba892a74Michal Krol RETURN_ERROR1("Invalid swizzle suffix"); 10747c26b61f9366a397e353d7b7f1f1d1f6d0dcd0c7Keith Whitwell 1075fd4395b8d1d6f8f018e7e7c3dd0c52fe52ab2794Brian Paul srcReg->Swizzle = MAKE_SWIZZLE4(swz[0], swz[1], swz[2], swz[3]); 10762861e737e84e4884109b9526ac645194ba892a74Michal Krol } 10772861e737e84e4884109b9526ac645194ba892a74Michal Krol 10782861e737e84e4884109b9526ac645194ba892a74Michal Krol /* Finish absolute value */ 10792861e737e84e4884109b9526ac645194ba892a74Michal Krol if (srcReg->Abs && !Parse_String(parseState, "|")) { 10802861e737e84e4884109b9526ac645194ba892a74Michal Krol RETURN_ERROR1("Expected |"); 10812861e737e84e4884109b9526ac645194ba892a74Michal Krol } 10822861e737e84e4884109b9526ac645194ba892a74Michal Krol 10832861e737e84e4884109b9526ac645194ba892a74Michal Krol return GL_TRUE; 10842861e737e84e4884109b9526ac645194ba892a74Michal Krol} 10852861e737e84e4884109b9526ac645194ba892a74Michal Krol 10862861e737e84e4884109b9526ac645194ba892a74Michal Krol 10872861e737e84e4884109b9526ac645194ba892a74Michal Krolstatic GLboolean 10882861e737e84e4884109b9526ac645194ba892a74Michal KrolParse_ScalarSrcReg(struct parse_state *parseState, 10897e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul struct prog_src_register *srcReg) 10902861e737e84e4884109b9526ac645194ba892a74Michal Krol{ 10912861e737e84e4884109b9526ac645194ba892a74Michal Krol GLubyte token[100]; 10922861e737e84e4884109b9526ac645194ba892a74Michal Krol GLfloat sign = 1.0F; 10932861e737e84e4884109b9526ac645194ba892a74Michal Krol GLboolean needSuffix = GL_TRUE; 10947c26b61f9366a397e353d7b7f1f1d1f6d0dcd0c7Keith Whitwell GLint idx; 10957db7ff878d3e5a6b345228e6eaee4797bb68b360Brian Paul GLuint negateBase, negateAbs; 10962861e737e84e4884109b9526ac645194ba892a74Michal Krol 10972861e737e84e4884109b9526ac645194ba892a74Michal Krol /* 10982861e737e84e4884109b9526ac645194ba892a74Michal Krol * First, take care of +/- and absolute value stuff. 10992861e737e84e4884109b9526ac645194ba892a74Michal Krol */ 11002861e737e84e4884109b9526ac645194ba892a74Michal Krol if (Parse_String(parseState, "-")) 11012861e737e84e4884109b9526ac645194ba892a74Michal Krol sign = -1.0F; 11022861e737e84e4884109b9526ac645194ba892a74Michal Krol else if (Parse_String(parseState, "+")) 11032861e737e84e4884109b9526ac645194ba892a74Michal Krol sign = +1.0F; 11042861e737e84e4884109b9526ac645194ba892a74Michal Krol 11052861e737e84e4884109b9526ac645194ba892a74Michal Krol if (Parse_String(parseState, "|")) { 11062861e737e84e4884109b9526ac645194ba892a74Michal Krol srcReg->Abs = GL_TRUE; 11077db7ff878d3e5a6b345228e6eaee4797bb68b360Brian Paul negateAbs = (sign < 0.0F) ? NEGATE_XYZW : NEGATE_NONE; 11082861e737e84e4884109b9526ac645194ba892a74Michal Krol 11092861e737e84e4884109b9526ac645194ba892a74Michal Krol if (Parse_String(parseState, "-")) 11107db7ff878d3e5a6b345228e6eaee4797bb68b360Brian Paul negateBase = NEGATE_XYZW; 11112861e737e84e4884109b9526ac645194ba892a74Michal Krol else if (Parse_String(parseState, "+")) 11127db7ff878d3e5a6b345228e6eaee4797bb68b360Brian Paul negateBase = NEGATE_NONE; 11132861e737e84e4884109b9526ac645194ba892a74Michal Krol else 11147db7ff878d3e5a6b345228e6eaee4797bb68b360Brian Paul negateBase = NEGATE_NONE; 11152861e737e84e4884109b9526ac645194ba892a74Michal Krol } 11162861e737e84e4884109b9526ac645194ba892a74Michal Krol else { 11172861e737e84e4884109b9526ac645194ba892a74Michal Krol srcReg->Abs = GL_FALSE; 11187db7ff878d3e5a6b345228e6eaee4797bb68b360Brian Paul negateAbs = NEGATE_NONE; 11197db7ff878d3e5a6b345228e6eaee4797bb68b360Brian Paul negateBase = (sign < 0.0F) ? NEGATE_XYZW : NEGATE_NONE; 11202861e737e84e4884109b9526ac645194ba892a74Michal Krol } 11212861e737e84e4884109b9526ac645194ba892a74Michal Krol 11227db7ff878d3e5a6b345228e6eaee4797bb68b360Brian Paul srcReg->Negate = srcReg->Abs ? negateAbs : negateBase; 11237db7ff878d3e5a6b345228e6eaee4797bb68b360Brian Paul 11242861e737e84e4884109b9526ac645194ba892a74Michal Krol if (!Peek_Token(parseState, token)) 11252861e737e84e4884109b9526ac645194ba892a74Michal Krol RETURN_ERROR; 11262861e737e84e4884109b9526ac645194ba892a74Michal Krol 11272861e737e84e4884109b9526ac645194ba892a74Michal Krol /* Src reg can be R<n>, H<n> or a named fragment attrib */ 11282861e737e84e4884109b9526ac645194ba892a74Michal Krol if (token[0] == 'R' || token[0] == 'H') { 11292861e737e84e4884109b9526ac645194ba892a74Michal Krol srcReg->File = PROGRAM_TEMPORARY; 11307c26b61f9366a397e353d7b7f1f1d1f6d0dcd0c7Keith Whitwell if (!Parse_TempReg(parseState, &idx)) 11312861e737e84e4884109b9526ac645194ba892a74Michal Krol RETURN_ERROR; 11327c26b61f9366a397e353d7b7f1f1d1f6d0dcd0c7Keith Whitwell srcReg->Index = idx; 11332861e737e84e4884109b9526ac645194ba892a74Michal Krol } 11342861e737e84e4884109b9526ac645194ba892a74Michal Krol else if (token[0] == 'f') { 11352861e737e84e4884109b9526ac645194ba892a74Michal Krol srcReg->File = PROGRAM_INPUT; 11367c26b61f9366a397e353d7b7f1f1d1f6d0dcd0c7Keith Whitwell if (!Parse_FragReg(parseState, &idx)) 11372861e737e84e4884109b9526ac645194ba892a74Michal Krol RETURN_ERROR; 11387c26b61f9366a397e353d7b7f1f1d1f6d0dcd0c7Keith Whitwell srcReg->Index = idx; 11392861e737e84e4884109b9526ac645194ba892a74Michal Krol } 11402861e737e84e4884109b9526ac645194ba892a74Michal Krol else if (token[0] == '{') { 11412861e737e84e4884109b9526ac645194ba892a74Michal Krol /* vector literal */ 11422861e737e84e4884109b9526ac645194ba892a74Michal Krol GLfloat values[4]; 114381c4fee160cd2840caf77bbdbf462e783911141aBrian GLuint paramIndex; 11442861e737e84e4884109b9526ac645194ba892a74Michal Krol (void) Parse_String(parseState, "{"); 11452861e737e84e4884109b9526ac645194ba892a74Michal Krol if (!Parse_VectorConstant(parseState, values)) 11462861e737e84e4884109b9526ac645194ba892a74Michal Krol RETURN_ERROR; 1147fe1d01cb398cbcb5b28a0b222845d3865c4d612bBrian paramIndex = _mesa_add_unnamed_constant(parseState->parameters, 11481bf81e3c5d65b636658d11072f4f027f5c499396Brian values, 4, NULL); 11492861e737e84e4884109b9526ac645194ba892a74Michal Krol srcReg->File = PROGRAM_NAMED_PARAM; 11502861e737e84e4884109b9526ac645194ba892a74Michal Krol srcReg->Index = paramIndex; 11512861e737e84e4884109b9526ac645194ba892a74Michal Krol } 1152e6940f0a33a571b199bab60b680c30b718c47445Brian Paul else if (IsLetter(token[0])){ 1153e6940f0a33a571b199bab60b680c30b718c47445Brian Paul /* named param/constant */ 1154e6940f0a33a571b199bab60b680c30b718c47445Brian Paul GLubyte ident[100]; 1155e6940f0a33a571b199bab60b680c30b718c47445Brian Paul GLint paramIndex; 1156e6940f0a33a571b199bab60b680c30b718c47445Brian Paul if (!Parse_Identifier(parseState, ident)) 1157e6940f0a33a571b199bab60b680c30b718c47445Brian Paul RETURN_ERROR; 1158e6940f0a33a571b199bab60b680c30b718c47445Brian Paul paramIndex = _mesa_lookup_parameter_index(parseState->parameters, 1159e6940f0a33a571b199bab60b680c30b718c47445Brian Paul -1, (const char *) ident); 1160e6940f0a33a571b199bab60b680c30b718c47445Brian Paul if (paramIndex < 0) { 1161e6940f0a33a571b199bab60b680c30b718c47445Brian Paul RETURN_ERROR2("Undefined constant or parameter: ", ident); 1162e6940f0a33a571b199bab60b680c30b718c47445Brian Paul } 1163e6940f0a33a571b199bab60b680c30b718c47445Brian Paul srcReg->File = PROGRAM_NAMED_PARAM; 1164e6940f0a33a571b199bab60b680c30b718c47445Brian Paul srcReg->Index = paramIndex; 1165e6940f0a33a571b199bab60b680c30b718c47445Brian Paul } 11662861e737e84e4884109b9526ac645194ba892a74Michal Krol else if (IsDigit(token[0])) { 11672861e737e84e4884109b9526ac645194ba892a74Michal Krol /* scalar literal */ 11682861e737e84e4884109b9526ac645194ba892a74Michal Krol GLfloat values[4]; 116981c4fee160cd2840caf77bbdbf462e783911141aBrian GLuint paramIndex; 11702861e737e84e4884109b9526ac645194ba892a74Michal Krol if (!Parse_ScalarConstant(parseState, values)) 11712861e737e84e4884109b9526ac645194ba892a74Michal Krol RETURN_ERROR; 1172fe1d01cb398cbcb5b28a0b222845d3865c4d612bBrian paramIndex = _mesa_add_unnamed_constant(parseState->parameters, 11731bf81e3c5d65b636658d11072f4f027f5c499396Brian values, 4, NULL); 11742861e737e84e4884109b9526ac645194ba892a74Michal Krol srcReg->Index = paramIndex; 11752861e737e84e4884109b9526ac645194ba892a74Michal Krol srcReg->File = PROGRAM_NAMED_PARAM; 11762861e737e84e4884109b9526ac645194ba892a74Michal Krol needSuffix = GL_FALSE; 11772861e737e84e4884109b9526ac645194ba892a74Michal Krol } 11782861e737e84e4884109b9526ac645194ba892a74Michal Krol else { 11792861e737e84e4884109b9526ac645194ba892a74Michal Krol RETURN_ERROR2("Invalid scalar source argument", token); 11802861e737e84e4884109b9526ac645194ba892a74Michal Krol } 11812861e737e84e4884109b9526ac645194ba892a74Michal Krol 11827c26b61f9366a397e353d7b7f1f1d1f6d0dcd0c7Keith Whitwell srcReg->Swizzle = 0; 11832861e737e84e4884109b9526ac645194ba892a74Michal Krol if (needSuffix) { 11842861e737e84e4884109b9526ac645194ba892a74Michal Krol /* parse .[xyzw] suffix */ 11852861e737e84e4884109b9526ac645194ba892a74Michal Krol if (!Parse_String(parseState, ".")) 11862861e737e84e4884109b9526ac645194ba892a74Michal Krol RETURN_ERROR1("Expected ."); 11872861e737e84e4884109b9526ac645194ba892a74Michal Krol 11882861e737e84e4884109b9526ac645194ba892a74Michal Krol if (!Parse_Token(parseState, token)) 11892861e737e84e4884109b9526ac645194ba892a74Michal Krol RETURN_ERROR; 11902861e737e84e4884109b9526ac645194ba892a74Michal Krol 11912861e737e84e4884109b9526ac645194ba892a74Michal Krol if (token[0] == 'x' && token[1] == 0) { 11927c26b61f9366a397e353d7b7f1f1d1f6d0dcd0c7Keith Whitwell srcReg->Swizzle = 0; 11932861e737e84e4884109b9526ac645194ba892a74Michal Krol } 11942861e737e84e4884109b9526ac645194ba892a74Michal Krol else if (token[0] == 'y' && token[1] == 0) { 11957c26b61f9366a397e353d7b7f1f1d1f6d0dcd0c7Keith Whitwell srcReg->Swizzle = 1; 11962861e737e84e4884109b9526ac645194ba892a74Michal Krol } 11972861e737e84e4884109b9526ac645194ba892a74Michal Krol else if (token[0] == 'z' && token[1] == 0) { 11987c26b61f9366a397e353d7b7f1f1d1f6d0dcd0c7Keith Whitwell srcReg->Swizzle = 2; 11992861e737e84e4884109b9526ac645194ba892a74Michal Krol } 12002861e737e84e4884109b9526ac645194ba892a74Michal Krol else if (token[0] == 'w' && token[1] == 0) { 12017c26b61f9366a397e353d7b7f1f1d1f6d0dcd0c7Keith Whitwell srcReg->Swizzle = 3; 12022861e737e84e4884109b9526ac645194ba892a74Michal Krol } 12032861e737e84e4884109b9526ac645194ba892a74Michal Krol else { 12042861e737e84e4884109b9526ac645194ba892a74Michal Krol RETURN_ERROR1("Invalid scalar source suffix"); 12052861e737e84e4884109b9526ac645194ba892a74Michal Krol } 12062861e737e84e4884109b9526ac645194ba892a74Michal Krol } 12072861e737e84e4884109b9526ac645194ba892a74Michal Krol 12082861e737e84e4884109b9526ac645194ba892a74Michal Krol /* Finish absolute value */ 12092861e737e84e4884109b9526ac645194ba892a74Michal Krol if (srcReg->Abs && !Parse_String(parseState, "|")) { 12102861e737e84e4884109b9526ac645194ba892a74Michal Krol RETURN_ERROR1("Expected |"); 12112861e737e84e4884109b9526ac645194ba892a74Michal Krol } 12122861e737e84e4884109b9526ac645194ba892a74Michal Krol 12132861e737e84e4884109b9526ac645194ba892a74Michal Krol return GL_TRUE; 12142861e737e84e4884109b9526ac645194ba892a74Michal Krol} 12152861e737e84e4884109b9526ac645194ba892a74Michal Krol 12162861e737e84e4884109b9526ac645194ba892a74Michal Krol 12172a5afe3ab8d4c3624ed72b99a11b6a9017078d1cBrian Paulstatic GLboolean 12182a5afe3ab8d4c3624ed72b99a11b6a9017078d1cBrian PaulParse_PrintInstruction(struct parse_state *parseState, 12197e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul struct prog_instruction *inst) 12202a5afe3ab8d4c3624ed72b99a11b6a9017078d1cBrian Paul{ 12212a5afe3ab8d4c3624ed72b99a11b6a9017078d1cBrian Paul const GLubyte *str; 12222a5afe3ab8d4c3624ed72b99a11b6a9017078d1cBrian Paul GLubyte *msg; 12232a5afe3ab8d4c3624ed72b99a11b6a9017078d1cBrian Paul GLuint len; 12247c26b61f9366a397e353d7b7f1f1d1f6d0dcd0c7Keith Whitwell GLint idx; 12252a5afe3ab8d4c3624ed72b99a11b6a9017078d1cBrian Paul 12262a5afe3ab8d4c3624ed72b99a11b6a9017078d1cBrian Paul /* The first argument is a literal string 'just like this' */ 12272a5afe3ab8d4c3624ed72b99a11b6a9017078d1cBrian Paul if (!Parse_String(parseState, "'")) 12282a5afe3ab8d4c3624ed72b99a11b6a9017078d1cBrian Paul RETURN_ERROR1("Expected '"); 12292a5afe3ab8d4c3624ed72b99a11b6a9017078d1cBrian Paul 12302a5afe3ab8d4c3624ed72b99a11b6a9017078d1cBrian Paul str = parseState->pos; 12312a5afe3ab8d4c3624ed72b99a11b6a9017078d1cBrian Paul for (len = 0; str[len] != '\''; len++) /* find closing quote */ 12322a5afe3ab8d4c3624ed72b99a11b6a9017078d1cBrian Paul ; 12332a5afe3ab8d4c3624ed72b99a11b6a9017078d1cBrian Paul parseState->pos += len + 1; 12349580179dfb42d5b81ff6ec9704b82a556c7f1229Brian Paul msg = (GLubyte*) _mesa_malloc(len + 1); 12352a5afe3ab8d4c3624ed72b99a11b6a9017078d1cBrian Paul 1236c7ac486261ad30ef654f6d0b1608da4e8483cd40Kenneth Graunke memcpy(msg, str, len); 12372a5afe3ab8d4c3624ed72b99a11b6a9017078d1cBrian Paul msg[len] = 0; 12382a5afe3ab8d4c3624ed72b99a11b6a9017078d1cBrian Paul inst->Data = msg; 12392a5afe3ab8d4c3624ed72b99a11b6a9017078d1cBrian Paul 12402a5afe3ab8d4c3624ed72b99a11b6a9017078d1cBrian Paul if (Parse_String(parseState, ",")) { 12412a5afe3ab8d4c3624ed72b99a11b6a9017078d1cBrian Paul /* got an optional register to print */ 12422a5afe3ab8d4c3624ed72b99a11b6a9017078d1cBrian Paul GLubyte token[100]; 12432a5afe3ab8d4c3624ed72b99a11b6a9017078d1cBrian Paul GetToken(parseState, token); 12442a5afe3ab8d4c3624ed72b99a11b6a9017078d1cBrian Paul if (token[0] == 'o') { 12452a5afe3ab8d4c3624ed72b99a11b6a9017078d1cBrian Paul /* dst reg */ 12467c26b61f9366a397e353d7b7f1f1d1f6d0dcd0c7Keith Whitwell if (!Parse_OutputReg(parseState, &idx)) 12472a5afe3ab8d4c3624ed72b99a11b6a9017078d1cBrian Paul RETURN_ERROR; 12487c26b61f9366a397e353d7b7f1f1d1f6d0dcd0c7Keith Whitwell inst->SrcReg[0].Index = idx; 12492a5afe3ab8d4c3624ed72b99a11b6a9017078d1cBrian Paul inst->SrcReg[0].File = PROGRAM_OUTPUT; 12502a5afe3ab8d4c3624ed72b99a11b6a9017078d1cBrian Paul } 12512a5afe3ab8d4c3624ed72b99a11b6a9017078d1cBrian Paul else { 12522a5afe3ab8d4c3624ed72b99a11b6a9017078d1cBrian Paul /* src reg */ 12532a5afe3ab8d4c3624ed72b99a11b6a9017078d1cBrian Paul if (!Parse_VectorSrc(parseState, &inst->SrcReg[0])) 12542a5afe3ab8d4c3624ed72b99a11b6a9017078d1cBrian Paul RETURN_ERROR; 12552a5afe3ab8d4c3624ed72b99a11b6a9017078d1cBrian Paul } 12562a5afe3ab8d4c3624ed72b99a11b6a9017078d1cBrian Paul } 12572a5afe3ab8d4c3624ed72b99a11b6a9017078d1cBrian Paul else { 12588cdf3729468aefb7c67c8ecd32fd850adbf6d351Brian Paul inst->SrcReg[0].File = PROGRAM_UNDEFINED; 12592a5afe3ab8d4c3624ed72b99a11b6a9017078d1cBrian Paul } 12602a5afe3ab8d4c3624ed72b99a11b6a9017078d1cBrian Paul 12617c26b61f9366a397e353d7b7f1f1d1f6d0dcd0c7Keith Whitwell inst->SrcReg[0].Swizzle = SWIZZLE_NOOP; 12622a5afe3ab8d4c3624ed72b99a11b6a9017078d1cBrian Paul inst->SrcReg[0].Abs = GL_FALSE; 12637db7ff878d3e5a6b345228e6eaee4797bb68b360Brian Paul inst->SrcReg[0].Negate = NEGATE_NONE; 12642a5afe3ab8d4c3624ed72b99a11b6a9017078d1cBrian Paul 12652a5afe3ab8d4c3624ed72b99a11b6a9017078d1cBrian Paul return GL_TRUE; 12662a5afe3ab8d4c3624ed72b99a11b6a9017078d1cBrian Paul} 12672a5afe3ab8d4c3624ed72b99a11b6a9017078d1cBrian Paul 12682861e737e84e4884109b9526ac645194ba892a74Michal Krol 12692861e737e84e4884109b9526ac645194ba892a74Michal Krolstatic GLboolean 12702861e737e84e4884109b9526ac645194ba892a74Michal KrolParse_InstructionSequence(struct parse_state *parseState, 12717e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul struct prog_instruction program[]) 12722861e737e84e4884109b9526ac645194ba892a74Michal Krol{ 12732861e737e84e4884109b9526ac645194ba892a74Michal Krol while (1) { 12747e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul struct prog_instruction *inst = program + parseState->numInst; 12752861e737e84e4884109b9526ac645194ba892a74Michal Krol struct instruction_pattern instMatch; 12762861e737e84e4884109b9526ac645194ba892a74Michal Krol GLubyte token[100]; 12772861e737e84e4884109b9526ac645194ba892a74Michal Krol 12782861e737e84e4884109b9526ac645194ba892a74Michal Krol /* Initialize the instruction */ 1279d6272e06172f7ac7a0d6e8062e8ffba33e1ab3baBrian Paul _mesa_init_instructions(inst, 1); 12802861e737e84e4884109b9526ac645194ba892a74Michal Krol 12812861e737e84e4884109b9526ac645194ba892a74Michal Krol /* special instructions */ 12822861e737e84e4884109b9526ac645194ba892a74Michal Krol if (Parse_String(parseState, "DEFINE")) { 12832861e737e84e4884109b9526ac645194ba892a74Michal Krol GLubyte id[100]; 12842861e737e84e4884109b9526ac645194ba892a74Michal Krol GLfloat value[7]; /* yes, 7 to be safe */ 12852861e737e84e4884109b9526ac645194ba892a74Michal Krol if (!Parse_Identifier(parseState, id)) 12862861e737e84e4884109b9526ac645194ba892a74Michal Krol RETURN_ERROR; 12872861e737e84e4884109b9526ac645194ba892a74Michal Krol /* XXX make sure id is not a reserved identifer, like R9 */ 12882861e737e84e4884109b9526ac645194ba892a74Michal Krol if (!Parse_String(parseState, "=")) 12892861e737e84e4884109b9526ac645194ba892a74Michal Krol RETURN_ERROR1("Expected ="); 12902861e737e84e4884109b9526ac645194ba892a74Michal Krol if (!Parse_VectorOrScalarConstant(parseState, value)) 12912861e737e84e4884109b9526ac645194ba892a74Michal Krol RETURN_ERROR; 12922861e737e84e4884109b9526ac645194ba892a74Michal Krol if (!Parse_String(parseState, ";")) 12932861e737e84e4884109b9526ac645194ba892a74Michal Krol RETURN_ERROR1("Expected ;"); 12942861e737e84e4884109b9526ac645194ba892a74Michal Krol if (_mesa_lookup_parameter_index(parseState->parameters, 12952861e737e84e4884109b9526ac645194ba892a74Michal Krol -1, (const char *) id) >= 0) { 12962861e737e84e4884109b9526ac645194ba892a74Michal Krol RETURN_ERROR2(id, "already defined"); 12972861e737e84e4884109b9526ac645194ba892a74Michal Krol } 12982861e737e84e4884109b9526ac645194ba892a74Michal Krol _mesa_add_named_parameter(parseState->parameters, 12992861e737e84e4884109b9526ac645194ba892a74Michal Krol (const char *) id, value); 13002861e737e84e4884109b9526ac645194ba892a74Michal Krol } 13012861e737e84e4884109b9526ac645194ba892a74Michal Krol else if (Parse_String(parseState, "DECLARE")) { 13022861e737e84e4884109b9526ac645194ba892a74Michal Krol GLubyte id[100]; 13032861e737e84e4884109b9526ac645194ba892a74Michal Krol GLfloat value[7] = {0, 0, 0, 0, 0, 0, 0}; /* yes, to be safe */ 13042861e737e84e4884109b9526ac645194ba892a74Michal Krol if (!Parse_Identifier(parseState, id)) 13052861e737e84e4884109b9526ac645194ba892a74Michal Krol RETURN_ERROR; 13062861e737e84e4884109b9526ac645194ba892a74Michal Krol /* XXX make sure id is not a reserved identifer, like R9 */ 13072861e737e84e4884109b9526ac645194ba892a74Michal Krol if (Parse_String(parseState, "=")) { 13082861e737e84e4884109b9526ac645194ba892a74Michal Krol if (!Parse_VectorOrScalarConstant(parseState, value)) 13092861e737e84e4884109b9526ac645194ba892a74Michal Krol RETURN_ERROR; 13102861e737e84e4884109b9526ac645194ba892a74Michal Krol } 13112861e737e84e4884109b9526ac645194ba892a74Michal Krol if (!Parse_String(parseState, ";")) 13122861e737e84e4884109b9526ac645194ba892a74Michal Krol RETURN_ERROR1("Expected ;"); 13132861e737e84e4884109b9526ac645194ba892a74Michal Krol if (_mesa_lookup_parameter_index(parseState->parameters, 13142861e737e84e4884109b9526ac645194ba892a74Michal Krol -1, (const char *) id) >= 0) { 13152861e737e84e4884109b9526ac645194ba892a74Michal Krol RETURN_ERROR2(id, "already declared"); 13162861e737e84e4884109b9526ac645194ba892a74Michal Krol } 13172861e737e84e4884109b9526ac645194ba892a74Michal Krol _mesa_add_named_parameter(parseState->parameters, 13182861e737e84e4884109b9526ac645194ba892a74Michal Krol (const char *) id, value); 13192861e737e84e4884109b9526ac645194ba892a74Michal Krol } 13202861e737e84e4884109b9526ac645194ba892a74Michal Krol else if (Parse_String(parseState, "END")) { 13217e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul inst->Opcode = OPCODE_END; 13222861e737e84e4884109b9526ac645194ba892a74Michal Krol parseState->numInst++; 13232861e737e84e4884109b9526ac645194ba892a74Michal Krol if (Parse_Token(parseState, token)) { 13242861e737e84e4884109b9526ac645194ba892a74Michal Krol RETURN_ERROR1("Code after END opcode."); 13252861e737e84e4884109b9526ac645194ba892a74Michal Krol } 13262861e737e84e4884109b9526ac645194ba892a74Michal Krol break; 13272861e737e84e4884109b9526ac645194ba892a74Michal Krol } 13282861e737e84e4884109b9526ac645194ba892a74Michal Krol else { 13292861e737e84e4884109b9526ac645194ba892a74Michal Krol /* general/arithmetic instruction */ 13302861e737e84e4884109b9526ac645194ba892a74Michal Krol 13312861e737e84e4884109b9526ac645194ba892a74Michal Krol /* get token */ 13322861e737e84e4884109b9526ac645194ba892a74Michal Krol if (!Parse_Token(parseState, token)) { 13332861e737e84e4884109b9526ac645194ba892a74Michal Krol RETURN_ERROR1("Missing END instruction."); 13342861e737e84e4884109b9526ac645194ba892a74Michal Krol } 13352861e737e84e4884109b9526ac645194ba892a74Michal Krol 13362861e737e84e4884109b9526ac645194ba892a74Michal Krol /* try to find matching instuction */ 13372861e737e84e4884109b9526ac645194ba892a74Michal Krol instMatch = MatchInstruction(token); 133828b014ee256290eb0494b967e40c475c0c895f57Brian Paul if (instMatch.opcode >= MAX_OPCODE) { 13392861e737e84e4884109b9526ac645194ba892a74Michal Krol /* bad instruction name */ 13402861e737e84e4884109b9526ac645194ba892a74Michal Krol RETURN_ERROR2("Unexpected token: ", token); 13412861e737e84e4884109b9526ac645194ba892a74Michal Krol } 13422861e737e84e4884109b9526ac645194ba892a74Michal Krol 13432861e737e84e4884109b9526ac645194ba892a74Michal Krol inst->Opcode = instMatch.opcode; 13442861e737e84e4884109b9526ac645194ba892a74Michal Krol inst->Precision = instMatch.suffixes & (_R | _H | _X); 1345e31ac052236ea615b4995f9ec301d8af4b864531Brian Paul inst->SaturateMode = (instMatch.suffixes & (_S)) 1346e31ac052236ea615b4995f9ec301d8af4b864531Brian Paul ? SATURATE_ZERO_ONE : SATURATE_OFF; 13477e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul inst->CondUpdate = (instMatch.suffixes & (_C)) ? GL_TRUE : GL_FALSE; 13482861e737e84e4884109b9526ac645194ba892a74Michal Krol 13492861e737e84e4884109b9526ac645194ba892a74Michal Krol /* 13502861e737e84e4884109b9526ac645194ba892a74Michal Krol * parse the input and output operands 13512861e737e84e4884109b9526ac645194ba892a74Michal Krol */ 13522861e737e84e4884109b9526ac645194ba892a74Michal Krol if (instMatch.outputs == OUTPUT_S || instMatch.outputs == OUTPUT_V) { 13532861e737e84e4884109b9526ac645194ba892a74Michal Krol if (!Parse_MaskedDstReg(parseState, &inst->DstReg)) 13542861e737e84e4884109b9526ac645194ba892a74Michal Krol RETURN_ERROR; 13552861e737e84e4884109b9526ac645194ba892a74Michal Krol if (!Parse_String(parseState, ",")) 13562861e737e84e4884109b9526ac645194ba892a74Michal Krol RETURN_ERROR1("Expected ,"); 13572861e737e84e4884109b9526ac645194ba892a74Michal Krol } 13582861e737e84e4884109b9526ac645194ba892a74Michal Krol else if (instMatch.outputs == OUTPUT_NONE) { 13597e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul if (instMatch.opcode == OPCODE_KIL_NV) { 13602a5afe3ab8d4c3624ed72b99a11b6a9017078d1cBrian Paul /* This is a little weird, the cond code info is in 13612a5afe3ab8d4c3624ed72b99a11b6a9017078d1cBrian Paul * the dest register. 13622a5afe3ab8d4c3624ed72b99a11b6a9017078d1cBrian Paul */ 13632a5afe3ab8d4c3624ed72b99a11b6a9017078d1cBrian Paul if (!Parse_CondCodeMask(parseState, &inst->DstReg)) 13642a5afe3ab8d4c3624ed72b99a11b6a9017078d1cBrian Paul RETURN_ERROR; 13652a5afe3ab8d4c3624ed72b99a11b6a9017078d1cBrian Paul } 13662a5afe3ab8d4c3624ed72b99a11b6a9017078d1cBrian Paul else { 13677e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul ASSERT(instMatch.opcode == OPCODE_PRINT); 13682a5afe3ab8d4c3624ed72b99a11b6a9017078d1cBrian Paul } 13692861e737e84e4884109b9526ac645194ba892a74Michal Krol } 13702861e737e84e4884109b9526ac645194ba892a74Michal Krol 13712861e737e84e4884109b9526ac645194ba892a74Michal Krol if (instMatch.inputs == INPUT_1V) { 13722861e737e84e4884109b9526ac645194ba892a74Michal Krol if (!Parse_VectorSrc(parseState, &inst->SrcReg[0])) 13732861e737e84e4884109b9526ac645194ba892a74Michal Krol RETURN_ERROR; 13742861e737e84e4884109b9526ac645194ba892a74Michal Krol } 13752861e737e84e4884109b9526ac645194ba892a74Michal Krol else if (instMatch.inputs == INPUT_2V) { 13762861e737e84e4884109b9526ac645194ba892a74Michal Krol if (!Parse_VectorSrc(parseState, &inst->SrcReg[0])) 13772861e737e84e4884109b9526ac645194ba892a74Michal Krol RETURN_ERROR; 13782861e737e84e4884109b9526ac645194ba892a74Michal Krol if (!Parse_String(parseState, ",")) 13792861e737e84e4884109b9526ac645194ba892a74Michal Krol RETURN_ERROR1("Expected ,"); 13802861e737e84e4884109b9526ac645194ba892a74Michal Krol if (!Parse_VectorSrc(parseState, &inst->SrcReg[1])) 13812861e737e84e4884109b9526ac645194ba892a74Michal Krol RETURN_ERROR; 13822861e737e84e4884109b9526ac645194ba892a74Michal Krol } 13832861e737e84e4884109b9526ac645194ba892a74Michal Krol else if (instMatch.inputs == INPUT_3V) { 13842861e737e84e4884109b9526ac645194ba892a74Michal Krol if (!Parse_VectorSrc(parseState, &inst->SrcReg[0])) 13852861e737e84e4884109b9526ac645194ba892a74Michal Krol RETURN_ERROR; 13862861e737e84e4884109b9526ac645194ba892a74Michal Krol if (!Parse_String(parseState, ",")) 13872861e737e84e4884109b9526ac645194ba892a74Michal Krol RETURN_ERROR1("Expected ,"); 13882861e737e84e4884109b9526ac645194ba892a74Michal Krol if (!Parse_VectorSrc(parseState, &inst->SrcReg[1])) 13892861e737e84e4884109b9526ac645194ba892a74Michal Krol RETURN_ERROR; 13902861e737e84e4884109b9526ac645194ba892a74Michal Krol if (!Parse_String(parseState, ",")) 13912861e737e84e4884109b9526ac645194ba892a74Michal Krol RETURN_ERROR1("Expected ,"); 13922861e737e84e4884109b9526ac645194ba892a74Michal Krol if (!Parse_VectorSrc(parseState, &inst->SrcReg[2])) 13932861e737e84e4884109b9526ac645194ba892a74Michal Krol RETURN_ERROR; 13942861e737e84e4884109b9526ac645194ba892a74Michal Krol } 13952861e737e84e4884109b9526ac645194ba892a74Michal Krol else if (instMatch.inputs == INPUT_1S) { 13962861e737e84e4884109b9526ac645194ba892a74Michal Krol if (!Parse_ScalarSrcReg(parseState, &inst->SrcReg[0])) 13972861e737e84e4884109b9526ac645194ba892a74Michal Krol RETURN_ERROR; 13982861e737e84e4884109b9526ac645194ba892a74Michal Krol } 13992861e737e84e4884109b9526ac645194ba892a74Michal Krol else if (instMatch.inputs == INPUT_2S) { 14002861e737e84e4884109b9526ac645194ba892a74Michal Krol if (!Parse_ScalarSrcReg(parseState, &inst->SrcReg[0])) 14012861e737e84e4884109b9526ac645194ba892a74Michal Krol RETURN_ERROR; 14022861e737e84e4884109b9526ac645194ba892a74Michal Krol if (!Parse_String(parseState, ",")) 14032861e737e84e4884109b9526ac645194ba892a74Michal Krol RETURN_ERROR1("Expected ,"); 14042861e737e84e4884109b9526ac645194ba892a74Michal Krol if (!Parse_ScalarSrcReg(parseState, &inst->SrcReg[1])) 14052861e737e84e4884109b9526ac645194ba892a74Michal Krol RETURN_ERROR; 14062861e737e84e4884109b9526ac645194ba892a74Michal Krol } 14072861e737e84e4884109b9526ac645194ba892a74Michal Krol else if (instMatch.inputs == INPUT_CC) { 14082861e737e84e4884109b9526ac645194ba892a74Michal Krol /* XXX to-do */ 14092861e737e84e4884109b9526ac645194ba892a74Michal Krol } 14102861e737e84e4884109b9526ac645194ba892a74Michal Krol else if (instMatch.inputs == INPUT_1V_T) { 14117c26b61f9366a397e353d7b7f1f1d1f6d0dcd0c7Keith Whitwell GLubyte unit, idx; 14122861e737e84e4884109b9526ac645194ba892a74Michal Krol if (!Parse_VectorSrc(parseState, &inst->SrcReg[0])) 14132861e737e84e4884109b9526ac645194ba892a74Michal Krol RETURN_ERROR; 14142861e737e84e4884109b9526ac645194ba892a74Michal Krol if (!Parse_String(parseState, ",")) 14152861e737e84e4884109b9526ac645194ba892a74Michal Krol RETURN_ERROR1("Expected ,"); 14167c26b61f9366a397e353d7b7f1f1d1f6d0dcd0c7Keith Whitwell if (!Parse_TextureImageId(parseState, &unit, &idx)) 14172861e737e84e4884109b9526ac645194ba892a74Michal Krol RETURN_ERROR; 14187c26b61f9366a397e353d7b7f1f1d1f6d0dcd0c7Keith Whitwell inst->TexSrcUnit = unit; 14197e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul inst->TexSrcTarget = idx; 14202861e737e84e4884109b9526ac645194ba892a74Michal Krol } 14212861e737e84e4884109b9526ac645194ba892a74Michal Krol else if (instMatch.inputs == INPUT_3V_T) { 14227c26b61f9366a397e353d7b7f1f1d1f6d0dcd0c7Keith Whitwell GLubyte unit, idx; 14232861e737e84e4884109b9526ac645194ba892a74Michal Krol if (!Parse_VectorSrc(parseState, &inst->SrcReg[0])) 14242861e737e84e4884109b9526ac645194ba892a74Michal Krol RETURN_ERROR; 14252861e737e84e4884109b9526ac645194ba892a74Michal Krol if (!Parse_String(parseState, ",")) 14262861e737e84e4884109b9526ac645194ba892a74Michal Krol RETURN_ERROR1("Expected ,"); 14272861e737e84e4884109b9526ac645194ba892a74Michal Krol if (!Parse_VectorSrc(parseState, &inst->SrcReg[1])) 14282861e737e84e4884109b9526ac645194ba892a74Michal Krol RETURN_ERROR; 14292861e737e84e4884109b9526ac645194ba892a74Michal Krol if (!Parse_String(parseState, ",")) 14302861e737e84e4884109b9526ac645194ba892a74Michal Krol RETURN_ERROR1("Expected ,"); 14312861e737e84e4884109b9526ac645194ba892a74Michal Krol if (!Parse_VectorSrc(parseState, &inst->SrcReg[2])) 14322861e737e84e4884109b9526ac645194ba892a74Michal Krol RETURN_ERROR; 14332861e737e84e4884109b9526ac645194ba892a74Michal Krol if (!Parse_String(parseState, ",")) 14342861e737e84e4884109b9526ac645194ba892a74Michal Krol RETURN_ERROR1("Expected ,"); 14357c26b61f9366a397e353d7b7f1f1d1f6d0dcd0c7Keith Whitwell if (!Parse_TextureImageId(parseState, &unit, &idx)) 14362861e737e84e4884109b9526ac645194ba892a74Michal Krol RETURN_ERROR; 14377c26b61f9366a397e353d7b7f1f1d1f6d0dcd0c7Keith Whitwell inst->TexSrcUnit = unit; 14387e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul inst->TexSrcTarget = idx; 14392861e737e84e4884109b9526ac645194ba892a74Michal Krol } 14402a5afe3ab8d4c3624ed72b99a11b6a9017078d1cBrian Paul else if (instMatch.inputs == INPUT_1V_S) { 14412a5afe3ab8d4c3624ed72b99a11b6a9017078d1cBrian Paul if (!Parse_PrintInstruction(parseState, inst)) 14422a5afe3ab8d4c3624ed72b99a11b6a9017078d1cBrian Paul RETURN_ERROR; 14432a5afe3ab8d4c3624ed72b99a11b6a9017078d1cBrian Paul } 14442861e737e84e4884109b9526ac645194ba892a74Michal Krol 14452861e737e84e4884109b9526ac645194ba892a74Michal Krol /* end of statement semicolon */ 14462861e737e84e4884109b9526ac645194ba892a74Michal Krol if (!Parse_String(parseState, ";")) 14472861e737e84e4884109b9526ac645194ba892a74Michal Krol RETURN_ERROR1("Expected ;"); 14482861e737e84e4884109b9526ac645194ba892a74Michal Krol 14492861e737e84e4884109b9526ac645194ba892a74Michal Krol parseState->numInst++; 14502861e737e84e4884109b9526ac645194ba892a74Michal Krol 14512861e737e84e4884109b9526ac645194ba892a74Michal Krol if (parseState->numInst >= MAX_NV_FRAGMENT_PROGRAM_INSTRUCTIONS) 14522861e737e84e4884109b9526ac645194ba892a74Michal Krol RETURN_ERROR1("Program too long"); 14532861e737e84e4884109b9526ac645194ba892a74Michal Krol } 14542861e737e84e4884109b9526ac645194ba892a74Michal Krol } 14552861e737e84e4884109b9526ac645194ba892a74Michal Krol return GL_TRUE; 14562861e737e84e4884109b9526ac645194ba892a74Michal Krol} 14572861e737e84e4884109b9526ac645194ba892a74Michal Krol 14582861e737e84e4884109b9526ac645194ba892a74Michal Krol 14592861e737e84e4884109b9526ac645194ba892a74Michal Krol 14602861e737e84e4884109b9526ac645194ba892a74Michal Krol/** 14612861e737e84e4884109b9526ac645194ba892a74Michal Krol * Parse/compile the 'str' returning the compiled 'program'. 14622861e737e84e4884109b9526ac645194ba892a74Michal Krol * ctx->Program.ErrorPos will be -1 if successful. Otherwise, ErrorPos 14632861e737e84e4884109b9526ac645194ba892a74Michal Krol * indicates the position of the error in 'str'. 14642861e737e84e4884109b9526ac645194ba892a74Michal Krol */ 14652861e737e84e4884109b9526ac645194ba892a74Michal Krolvoid 14662861e737e84e4884109b9526ac645194ba892a74Michal Krol_mesa_parse_nv_fragment_program(GLcontext *ctx, GLenum dstTarget, 14672861e737e84e4884109b9526ac645194ba892a74Michal Krol const GLubyte *str, GLsizei len, 1468122629f27925a9dc50029bebc5079f87f416a7e1Brian Paul struct gl_fragment_program *program) 14692861e737e84e4884109b9526ac645194ba892a74Michal Krol{ 14702861e737e84e4884109b9526ac645194ba892a74Michal Krol struct parse_state parseState; 14717e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul struct prog_instruction instBuffer[MAX_NV_FRAGMENT_PROGRAM_INSTRUCTIONS]; 14727e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul struct prog_instruction *newInst; 14732861e737e84e4884109b9526ac645194ba892a74Michal Krol GLenum target; 14742861e737e84e4884109b9526ac645194ba892a74Michal Krol GLubyte *programString; 14752861e737e84e4884109b9526ac645194ba892a74Michal Krol 14762861e737e84e4884109b9526ac645194ba892a74Michal Krol /* Make a null-terminated copy of the program string */ 14772861e737e84e4884109b9526ac645194ba892a74Michal Krol programString = (GLubyte *) MALLOC(len + 1); 14782861e737e84e4884109b9526ac645194ba892a74Michal Krol if (!programString) { 14792861e737e84e4884109b9526ac645194ba892a74Michal Krol _mesa_error(ctx, GL_OUT_OF_MEMORY, "glLoadProgramNV"); 14802861e737e84e4884109b9526ac645194ba892a74Michal Krol return; 14812861e737e84e4884109b9526ac645194ba892a74Michal Krol } 1482e197de56cdb86835f1437688a9161cd909792d80Brian Paul memcpy(programString, str, len); 14832861e737e84e4884109b9526ac645194ba892a74Michal Krol programString[len] = 0; 14842861e737e84e4884109b9526ac645194ba892a74Michal Krol 14852861e737e84e4884109b9526ac645194ba892a74Michal Krol /* Get ready to parse */ 14862861e737e84e4884109b9526ac645194ba892a74Michal Krol _mesa_bzero(&parseState, sizeof(struct parse_state)); 14872861e737e84e4884109b9526ac645194ba892a74Michal Krol parseState.ctx = ctx; 14882861e737e84e4884109b9526ac645194ba892a74Michal Krol parseState.start = programString; 14892861e737e84e4884109b9526ac645194ba892a74Michal Krol parseState.program = program; 14902861e737e84e4884109b9526ac645194ba892a74Michal Krol parseState.numInst = 0; 14912861e737e84e4884109b9526ac645194ba892a74Michal Krol parseState.curLine = programString; 14922861e737e84e4884109b9526ac645194ba892a74Michal Krol parseState.parameters = _mesa_new_parameter_list(); 14932861e737e84e4884109b9526ac645194ba892a74Michal Krol 14942861e737e84e4884109b9526ac645194ba892a74Michal Krol /* Reset error state */ 14952861e737e84e4884109b9526ac645194ba892a74Michal Krol _mesa_set_program_error(ctx, -1, NULL); 14962861e737e84e4884109b9526ac645194ba892a74Michal Krol 14972861e737e84e4884109b9526ac645194ba892a74Michal Krol /* check the program header */ 14989d9afe9393fde99858ddf40e478bc16cf44e60dcKenneth Graunke if (strncmp((const char *) programString, "!!FP1.0", 7) == 0) { 14992861e737e84e4884109b9526ac645194ba892a74Michal Krol target = GL_FRAGMENT_PROGRAM_NV; 15002861e737e84e4884109b9526ac645194ba892a74Michal Krol parseState.pos = programString + 7; 15012861e737e84e4884109b9526ac645194ba892a74Michal Krol } 15029d9afe9393fde99858ddf40e478bc16cf44e60dcKenneth Graunke else if (strncmp((const char *) programString, "!!FCP1.0", 8) == 0) { 15032861e737e84e4884109b9526ac645194ba892a74Michal Krol /* fragment / register combiner program - not supported */ 15042861e737e84e4884109b9526ac645194ba892a74Michal Krol _mesa_set_program_error(ctx, 0, "Invalid fragment program header"); 15052861e737e84e4884109b9526ac645194ba892a74Michal Krol _mesa_error(ctx, GL_INVALID_OPERATION, "glLoadProgramNV(bad header)"); 15062861e737e84e4884109b9526ac645194ba892a74Michal Krol return; 15072861e737e84e4884109b9526ac645194ba892a74Michal Krol } 15082861e737e84e4884109b9526ac645194ba892a74Michal Krol else { 15092861e737e84e4884109b9526ac645194ba892a74Michal Krol /* invalid header */ 15102861e737e84e4884109b9526ac645194ba892a74Michal Krol _mesa_set_program_error(ctx, 0, "Invalid fragment program header"); 15112861e737e84e4884109b9526ac645194ba892a74Michal Krol _mesa_error(ctx, GL_INVALID_OPERATION, "glLoadProgramNV(bad header)"); 15122861e737e84e4884109b9526ac645194ba892a74Michal Krol return; 15132861e737e84e4884109b9526ac645194ba892a74Michal Krol } 15142861e737e84e4884109b9526ac645194ba892a74Michal Krol 15152861e737e84e4884109b9526ac645194ba892a74Michal Krol /* make sure target and header match */ 15162861e737e84e4884109b9526ac645194ba892a74Michal Krol if (target != dstTarget) { 15172861e737e84e4884109b9526ac645194ba892a74Michal Krol _mesa_error(ctx, GL_INVALID_OPERATION, 15182861e737e84e4884109b9526ac645194ba892a74Michal Krol "glLoadProgramNV(target mismatch 0x%x != 0x%x)", 15192861e737e84e4884109b9526ac645194ba892a74Michal Krol target, dstTarget); 15202861e737e84e4884109b9526ac645194ba892a74Michal Krol return; 15212861e737e84e4884109b9526ac645194ba892a74Michal Krol } 15222861e737e84e4884109b9526ac645194ba892a74Michal Krol 15232861e737e84e4884109b9526ac645194ba892a74Michal Krol if (Parse_InstructionSequence(&parseState, instBuffer)) { 15242861e737e84e4884109b9526ac645194ba892a74Michal Krol GLuint u; 15252861e737e84e4884109b9526ac645194ba892a74Michal Krol /* successful parse! */ 15262861e737e84e4884109b9526ac645194ba892a74Michal Krol 15272861e737e84e4884109b9526ac645194ba892a74Michal Krol if (parseState.outputsWritten == 0) { 15282861e737e84e4884109b9526ac645194ba892a74Michal Krol /* must write at least one output! */ 15292861e737e84e4884109b9526ac645194ba892a74Michal Krol _mesa_error(ctx, GL_INVALID_OPERATION, 15302861e737e84e4884109b9526ac645194ba892a74Michal Krol "Invalid fragment program - no outputs written."); 15312861e737e84e4884109b9526ac645194ba892a74Michal Krol return; 15322861e737e84e4884109b9526ac645194ba892a74Michal Krol } 15332861e737e84e4884109b9526ac645194ba892a74Michal Krol 15342861e737e84e4884109b9526ac645194ba892a74Michal Krol /* copy the compiled instructions */ 15352861e737e84e4884109b9526ac645194ba892a74Michal Krol assert(parseState.numInst <= MAX_NV_FRAGMENT_PROGRAM_INSTRUCTIONS); 1536383c39e58e0ab888afac473526109b62ec0f8f6fBrian Paul newInst = _mesa_alloc_instructions(parseState.numInst); 15372861e737e84e4884109b9526ac645194ba892a74Michal Krol if (!newInst) { 15382861e737e84e4884109b9526ac645194ba892a74Michal Krol _mesa_error(ctx, GL_OUT_OF_MEMORY, "glLoadProgramNV"); 15392861e737e84e4884109b9526ac645194ba892a74Michal Krol return; /* out of memory */ 15402861e737e84e4884109b9526ac645194ba892a74Michal Krol } 154112229f119d754715e0315846fdd8d6e9213e8edfBrian _mesa_copy_instructions(newInst, instBuffer, parseState.numInst); 15422861e737e84e4884109b9526ac645194ba892a74Michal Krol 15432861e737e84e4884109b9526ac645194ba892a74Michal Krol /* install the program */ 15442861e737e84e4884109b9526ac645194ba892a74Michal Krol program->Base.Target = target; 15452861e737e84e4884109b9526ac645194ba892a74Michal Krol if (program->Base.String) { 15462861e737e84e4884109b9526ac645194ba892a74Michal Krol FREE(program->Base.String); 15472861e737e84e4884109b9526ac645194ba892a74Michal Krol } 15482861e737e84e4884109b9526ac645194ba892a74Michal Krol program->Base.String = programString; 15492861e737e84e4884109b9526ac645194ba892a74Michal Krol program->Base.Format = GL_PROGRAM_FORMAT_ASCII_ARB; 1550de99760bf3511d05185799c4fb4347f9e5f420f4Brian Paul if (program->Base.Instructions) { 1551de99760bf3511d05185799c4fb4347f9e5f420f4Brian Paul _mesa_free(program->Base.Instructions); 15522861e737e84e4884109b9526ac645194ba892a74Michal Krol } 1553de99760bf3511d05185799c4fb4347f9e5f420f4Brian Paul program->Base.Instructions = newInst; 1554ee40c4fb34bd06ecc6dd6f2e658ca2c2c20af952Brian Paul program->Base.NumInstructions = parseState.numInst; 1555de99760bf3511d05185799c4fb4347f9e5f420f4Brian Paul program->Base.InputsRead = parseState.inputsRead; 1556de99760bf3511d05185799c4fb4347f9e5f420f4Brian Paul program->Base.OutputsWritten = parseState.outputsWritten; 15572861e737e84e4884109b9526ac645194ba892a74Michal Krol for (u = 0; u < ctx->Const.MaxTextureImageUnits; u++) 1558c9db223f902ce9d7e9f3038e6baac6da7f231b34Brian program->Base.TexturesUsed[u] = parseState.texturesUsed[u]; 15592861e737e84e4884109b9526ac645194ba892a74Michal Krol 15602861e737e84e4884109b9526ac645194ba892a74Michal Krol /* save program parameters */ 1561de99760bf3511d05185799c4fb4347f9e5f420f4Brian Paul program->Base.Parameters = parseState.parameters; 15622861e737e84e4884109b9526ac645194ba892a74Michal Krol 15632861e737e84e4884109b9526ac645194ba892a74Michal Krol /* allocate registers for declared program parameters */ 15642861e737e84e4884109b9526ac645194ba892a74Michal Krol#if 00 15652861e737e84e4884109b9526ac645194ba892a74Michal Krol _mesa_assign_program_registers(&(program->SymbolTable)); 15662861e737e84e4884109b9526ac645194ba892a74Michal Krol#endif 15672861e737e84e4884109b9526ac645194ba892a74Michal Krol 1568ac33dd1312530e0bab0c7e5d25c9d70f4e884753Brian Paul#ifdef DEBUG_foo 15692861e737e84e4884109b9526ac645194ba892a74Michal Krol _mesa_printf("--- glLoadProgramNV(%d) result ---\n", program->Base.Id); 1570fe278f1e600058af18c6ba5fe77bfc5a772bf9f5Brian Paul _mesa_fprint_program_opt(stdout, &program->Base, PROG_PRINT_NV, 0); 15712861e737e84e4884109b9526ac645194ba892a74Michal Krol _mesa_printf("----------------------------------\n"); 15722861e737e84e4884109b9526ac645194ba892a74Michal Krol#endif 15732861e737e84e4884109b9526ac645194ba892a74Michal Krol } 15742861e737e84e4884109b9526ac645194ba892a74Michal Krol else { 15752861e737e84e4884109b9526ac645194ba892a74Michal Krol /* Error! */ 15762861e737e84e4884109b9526ac645194ba892a74Michal Krol _mesa_error(ctx, GL_INVALID_OPERATION, "glLoadProgramNV"); 15772861e737e84e4884109b9526ac645194ba892a74Michal Krol /* NOTE: _mesa_set_program_error would have been called already */ 15782861e737e84e4884109b9526ac645194ba892a74Michal Krol } 15792861e737e84e4884109b9526ac645194ba892a74Michal Krol} 15802861e737e84e4884109b9526ac645194ba892a74Michal Krol 15812861e737e84e4884109b9526ac645194ba892a74Michal Krol 15822861e737e84e4884109b9526ac645194ba892a74Michal Krolconst char * 15832861e737e84e4884109b9526ac645194ba892a74Michal Krol_mesa_nv_fragment_input_register_name(GLuint i) 15842861e737e84e4884109b9526ac645194ba892a74Michal Krol{ 15852861e737e84e4884109b9526ac645194ba892a74Michal Krol ASSERT(i < MAX_NV_FRAGMENT_PROGRAM_INPUTS); 15862861e737e84e4884109b9526ac645194ba892a74Michal Krol return InputRegisters[i]; 15872861e737e84e4884109b9526ac645194ba892a74Michal Krol} 15882861e737e84e4884109b9526ac645194ba892a74Michal Krol 1589