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 { 144f9995b30756140724f41daf963fa06167912be7fKristian Høgsberg struct gl_context *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); 17432f2fd1c5d6088692551c80352b7d6fa35b0cd09Kristian Høgsberg 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]; \ 203298be2b028263b2c343a707662c6fbfa18293cb2Kristian Høgsberg 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 459346298c7658f2ec8b105e5e53101637af232724fMarcin Baczyński *number = (GLfloat) _mesa_strtof((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"); 4756d89abadbcd68bbe9e08f041412549f8dc1fc73cBryan Cain constant = (GLfloat *)_mesa_lookup_parameter_value(parseState->parameters, 4766d89abadbcd68bbe9e08f041412549f8dc1fc73cBryan Cain -1, 4776d89abadbcd68bbe9e08f041412549f8dc1fc73cBryan Cain (const char *) ident); 4782861e737e84e4884109b9526ac645194ba892a74Michal Krol /* XXX Check that it's a constant and not a parameter */ 4792861e737e84e4884109b9526ac645194ba892a74Michal Krol if (!constant) { 4802861e737e84e4884109b9526ac645194ba892a74Michal Krol RETURN_ERROR1("Undefined symbol"); 4812861e737e84e4884109b9526ac645194ba892a74Michal Krol } 4822861e737e84e4884109b9526ac645194ba892a74Michal Krol else { 4832861e737e84e4884109b9526ac645194ba892a74Michal Krol COPY_4V(number, constant); 4842861e737e84e4884109b9526ac645194ba892a74Michal Krol return GL_TRUE; 4852861e737e84e4884109b9526ac645194ba892a74Michal Krol } 4862861e737e84e4884109b9526ac645194ba892a74Michal Krol } 4872861e737e84e4884109b9526ac645194ba892a74Michal Krol} 4882861e737e84e4884109b9526ac645194ba892a74Michal Krol 4892861e737e84e4884109b9526ac645194ba892a74Michal Krol 4902861e737e84e4884109b9526ac645194ba892a74Michal Krol 4912861e737e84e4884109b9526ac645194ba892a74Michal Krol/** 4922861e737e84e4884109b9526ac645194ba892a74Michal Krol * Parse a vector constant, one of: 4932861e737e84e4884109b9526ac645194ba892a74Michal Krol * { float } 4942861e737e84e4884109b9526ac645194ba892a74Michal Krol * { float, float } 4952861e737e84e4884109b9526ac645194ba892a74Michal Krol * { float, float, float } 4962861e737e84e4884109b9526ac645194ba892a74Michal Krol * { float, float, float, float } 4972861e737e84e4884109b9526ac645194ba892a74Michal Krol */ 4982861e737e84e4884109b9526ac645194ba892a74Michal Krolstatic GLboolean 4992861e737e84e4884109b9526ac645194ba892a74Michal KrolParse_VectorConstant(struct parse_state *parseState, GLfloat *vec) 5002861e737e84e4884109b9526ac645194ba892a74Michal Krol{ 5012861e737e84e4884109b9526ac645194ba892a74Michal Krol /* "{" was already consumed */ 5022861e737e84e4884109b9526ac645194ba892a74Michal Krol 5032861e737e84e4884109b9526ac645194ba892a74Michal Krol ASSIGN_4V(vec, 0.0, 0.0, 0.0, 1.0); 5042861e737e84e4884109b9526ac645194ba892a74Michal Krol 5052861e737e84e4884109b9526ac645194ba892a74Michal Krol if (!Parse_ScalarConstant(parseState, vec+0)) /* X */ 5062861e737e84e4884109b9526ac645194ba892a74Michal Krol return GL_FALSE; 5072861e737e84e4884109b9526ac645194ba892a74Michal Krol 5082861e737e84e4884109b9526ac645194ba892a74Michal Krol if (Parse_String(parseState, "}")) { 5092861e737e84e4884109b9526ac645194ba892a74Michal Krol return GL_TRUE; 5102861e737e84e4884109b9526ac645194ba892a74Michal Krol } 5112861e737e84e4884109b9526ac645194ba892a74Michal Krol 5122861e737e84e4884109b9526ac645194ba892a74Michal Krol if (!Parse_String(parseState, ",")) 5132861e737e84e4884109b9526ac645194ba892a74Michal Krol RETURN_ERROR1("Expected comma in vector constant"); 5142861e737e84e4884109b9526ac645194ba892a74Michal Krol 5152861e737e84e4884109b9526ac645194ba892a74Michal Krol if (!Parse_ScalarConstant(parseState, vec+1)) /* Y */ 5162861e737e84e4884109b9526ac645194ba892a74Michal Krol return GL_FALSE; 5172861e737e84e4884109b9526ac645194ba892a74Michal Krol 5182861e737e84e4884109b9526ac645194ba892a74Michal Krol if (Parse_String(parseState, "}")) { 5192861e737e84e4884109b9526ac645194ba892a74Michal Krol return GL_TRUE; 5202861e737e84e4884109b9526ac645194ba892a74Michal Krol } 5212861e737e84e4884109b9526ac645194ba892a74Michal Krol 5222861e737e84e4884109b9526ac645194ba892a74Michal Krol if (!Parse_String(parseState, ",")) 5232861e737e84e4884109b9526ac645194ba892a74Michal Krol RETURN_ERROR1("Expected comma in vector constant"); 5242861e737e84e4884109b9526ac645194ba892a74Michal Krol 5252861e737e84e4884109b9526ac645194ba892a74Michal Krol if (!Parse_ScalarConstant(parseState, vec+2)) /* Z */ 5262861e737e84e4884109b9526ac645194ba892a74Michal Krol return GL_FALSE; 5272861e737e84e4884109b9526ac645194ba892a74Michal Krol 5282861e737e84e4884109b9526ac645194ba892a74Michal Krol if (Parse_String(parseState, "}")) { 5292861e737e84e4884109b9526ac645194ba892a74Michal Krol return GL_TRUE; 5302861e737e84e4884109b9526ac645194ba892a74Michal Krol } 5312861e737e84e4884109b9526ac645194ba892a74Michal Krol 5322861e737e84e4884109b9526ac645194ba892a74Michal Krol if (!Parse_String(parseState, ",")) 5332861e737e84e4884109b9526ac645194ba892a74Michal Krol RETURN_ERROR1("Expected comma in vector constant"); 5342861e737e84e4884109b9526ac645194ba892a74Michal Krol 5352861e737e84e4884109b9526ac645194ba892a74Michal Krol if (!Parse_ScalarConstant(parseState, vec+3)) /* W */ 5362861e737e84e4884109b9526ac645194ba892a74Michal Krol return GL_FALSE; 5372861e737e84e4884109b9526ac645194ba892a74Michal Krol 5382861e737e84e4884109b9526ac645194ba892a74Michal Krol if (!Parse_String(parseState, "}")) 5392861e737e84e4884109b9526ac645194ba892a74Michal Krol RETURN_ERROR1("Expected closing brace in vector constant"); 5402861e737e84e4884109b9526ac645194ba892a74Michal Krol 5412861e737e84e4884109b9526ac645194ba892a74Michal Krol return GL_TRUE; 5422861e737e84e4884109b9526ac645194ba892a74Michal Krol} 5432861e737e84e4884109b9526ac645194ba892a74Michal Krol 5442861e737e84e4884109b9526ac645194ba892a74Michal Krol 5452861e737e84e4884109b9526ac645194ba892a74Michal Krol/** 5462861e737e84e4884109b9526ac645194ba892a74Michal Krol * Parse <number>, <varname> or {a, b, c, d}. 5472861e737e84e4884109b9526ac645194ba892a74Michal Krol * Return number of values in the vector or scalar, or zero if parse error. 5482861e737e84e4884109b9526ac645194ba892a74Michal Krol */ 5492861e737e84e4884109b9526ac645194ba892a74Michal Krolstatic GLuint 5502861e737e84e4884109b9526ac645194ba892a74Michal KrolParse_VectorOrScalarConstant(struct parse_state *parseState, GLfloat *vec) 5512861e737e84e4884109b9526ac645194ba892a74Michal Krol{ 5522861e737e84e4884109b9526ac645194ba892a74Michal Krol if (Parse_String(parseState, "{")) { 5532861e737e84e4884109b9526ac645194ba892a74Michal Krol return Parse_VectorConstant(parseState, vec); 5542861e737e84e4884109b9526ac645194ba892a74Michal Krol } 5552861e737e84e4884109b9526ac645194ba892a74Michal Krol else { 5562861e737e84e4884109b9526ac645194ba892a74Michal Krol GLboolean b = Parse_ScalarConstant(parseState, vec); 5572861e737e84e4884109b9526ac645194ba892a74Michal Krol if (b) { 5582861e737e84e4884109b9526ac645194ba892a74Michal Krol vec[1] = vec[2] = vec[3] = vec[0]; 5592861e737e84e4884109b9526ac645194ba892a74Michal Krol } 5602861e737e84e4884109b9526ac645194ba892a74Michal Krol return b; 5612861e737e84e4884109b9526ac645194ba892a74Michal Krol } 5622861e737e84e4884109b9526ac645194ba892a74Michal Krol} 5632861e737e84e4884109b9526ac645194ba892a74Michal Krol 5642861e737e84e4884109b9526ac645194ba892a74Michal Krol 5652861e737e84e4884109b9526ac645194ba892a74Michal Krol/** 5662861e737e84e4884109b9526ac645194ba892a74Michal Krol * Parse a texture image source: 5672861e737e84e4884109b9526ac645194ba892a74Michal Krol * [TEX0 | TEX1 | .. | TEX15] , [1D | 2D | 3D | CUBE | RECT] 5682861e737e84e4884109b9526ac645194ba892a74Michal Krol */ 5692861e737e84e4884109b9526ac645194ba892a74Michal Krolstatic GLboolean 5702861e737e84e4884109b9526ac645194ba892a74Michal KrolParse_TextureImageId(struct parse_state *parseState, 571bf5255fb30d9d9832f93616016c94782469d43adBrian Paul GLubyte *texUnit, GLubyte *texTarget) 5722861e737e84e4884109b9526ac645194ba892a74Michal Krol{ 5732861e737e84e4884109b9526ac645194ba892a74Michal Krol GLubyte imageSrc[100]; 5742861e737e84e4884109b9526ac645194ba892a74Michal Krol GLint unit; 5752861e737e84e4884109b9526ac645194ba892a74Michal Krol 5762861e737e84e4884109b9526ac645194ba892a74Michal Krol if (!Parse_Token(parseState, imageSrc)) 5772861e737e84e4884109b9526ac645194ba892a74Michal Krol RETURN_ERROR; 5782861e737e84e4884109b9526ac645194ba892a74Michal Krol 5792861e737e84e4884109b9526ac645194ba892a74Michal Krol if (imageSrc[0] != 'T' || 5802861e737e84e4884109b9526ac645194ba892a74Michal Krol imageSrc[1] != 'E' || 5812861e737e84e4884109b9526ac645194ba892a74Michal Krol imageSrc[2] != 'X') { 5822861e737e84e4884109b9526ac645194ba892a74Michal Krol RETURN_ERROR1("Expected TEX# source"); 5832861e737e84e4884109b9526ac645194ba892a74Michal Krol } 58460b0cae412029e53654f38d0de151908f1feb310Kenneth Graunke unit = atoi((const char *) imageSrc + 3); 58561b62c007a7941e9b45e83440e932160a597e0e1Vinson Lee if ((unit < 0 || unit >= MAX_TEXTURE_IMAGE_UNITS) || 5862861e737e84e4884109b9526ac645194ba892a74Michal Krol (unit == 0 && (imageSrc[3] != '0' || imageSrc[4] != 0))) { 5872861e737e84e4884109b9526ac645194ba892a74Michal Krol RETURN_ERROR1("Invalied TEX# source index"); 5882861e737e84e4884109b9526ac645194ba892a74Michal Krol } 5892861e737e84e4884109b9526ac645194ba892a74Michal Krol *texUnit = unit; 5902861e737e84e4884109b9526ac645194ba892a74Michal Krol 5912861e737e84e4884109b9526ac645194ba892a74Michal Krol if (!Parse_String(parseState, ",")) 5922861e737e84e4884109b9526ac645194ba892a74Michal Krol RETURN_ERROR1("Expected ,"); 5932861e737e84e4884109b9526ac645194ba892a74Michal Krol 5942861e737e84e4884109b9526ac645194ba892a74Michal Krol if (Parse_String(parseState, "1D")) { 595bf5255fb30d9d9832f93616016c94782469d43adBrian Paul *texTarget = TEXTURE_1D_INDEX; 5962861e737e84e4884109b9526ac645194ba892a74Michal Krol } 5972861e737e84e4884109b9526ac645194ba892a74Michal Krol else if (Parse_String(parseState, "2D")) { 598bf5255fb30d9d9832f93616016c94782469d43adBrian Paul *texTarget = TEXTURE_2D_INDEX; 5992861e737e84e4884109b9526ac645194ba892a74Michal Krol } 6002861e737e84e4884109b9526ac645194ba892a74Michal Krol else if (Parse_String(parseState, "3D")) { 601bf5255fb30d9d9832f93616016c94782469d43adBrian Paul *texTarget = TEXTURE_3D_INDEX; 6022861e737e84e4884109b9526ac645194ba892a74Michal Krol } 6032861e737e84e4884109b9526ac645194ba892a74Michal Krol else if (Parse_String(parseState, "CUBE")) { 604bf5255fb30d9d9832f93616016c94782469d43adBrian Paul *texTarget = TEXTURE_CUBE_INDEX; 6052861e737e84e4884109b9526ac645194ba892a74Michal Krol } 6062861e737e84e4884109b9526ac645194ba892a74Michal Krol else if (Parse_String(parseState, "RECT")) { 607bf5255fb30d9d9832f93616016c94782469d43adBrian Paul *texTarget = TEXTURE_RECT_INDEX; 6082861e737e84e4884109b9526ac645194ba892a74Michal Krol } 6092861e737e84e4884109b9526ac645194ba892a74Michal Krol else { 6102861e737e84e4884109b9526ac645194ba892a74Michal Krol RETURN_ERROR1("Invalid texture target token"); 6112861e737e84e4884109b9526ac645194ba892a74Michal Krol } 6122861e737e84e4884109b9526ac645194ba892a74Michal Krol 6132861e737e84e4884109b9526ac645194ba892a74Michal Krol /* update record of referenced texture units */ 614bf5255fb30d9d9832f93616016c94782469d43adBrian Paul parseState->texturesUsed[*texUnit] |= (1 << *texTarget); 6152861e737e84e4884109b9526ac645194ba892a74Michal Krol if (_mesa_bitcount(parseState->texturesUsed[*texUnit]) > 1) { 6162861e737e84e4884109b9526ac645194ba892a74Michal Krol RETURN_ERROR1("Only one texture target can be used per texture unit."); 6172861e737e84e4884109b9526ac645194ba892a74Michal Krol } 6182861e737e84e4884109b9526ac645194ba892a74Michal Krol 6192861e737e84e4884109b9526ac645194ba892a74Michal Krol return GL_TRUE; 6202861e737e84e4884109b9526ac645194ba892a74Michal Krol} 6212861e737e84e4884109b9526ac645194ba892a74Michal Krol 6222861e737e84e4884109b9526ac645194ba892a74Michal Krol 6232861e737e84e4884109b9526ac645194ba892a74Michal Krol/** 6242861e737e84e4884109b9526ac645194ba892a74Michal Krol * Parse a scalar suffix like .x, .y, .z or .w or parse a swizzle suffix 6252861e737e84e4884109b9526ac645194ba892a74Michal Krol * like .wxyz, .xxyy, etc and return the swizzle indexes. 6262861e737e84e4884109b9526ac645194ba892a74Michal Krol */ 6272861e737e84e4884109b9526ac645194ba892a74Michal Krolstatic GLboolean 6282861e737e84e4884109b9526ac645194ba892a74Michal KrolParse_SwizzleSuffix(const GLubyte *token, GLuint swizzle[4]) 6292861e737e84e4884109b9526ac645194ba892a74Michal Krol{ 6302861e737e84e4884109b9526ac645194ba892a74Michal Krol if (token[1] == 0) { 6312861e737e84e4884109b9526ac645194ba892a74Michal Krol /* single letter swizzle (scalar) */ 6322861e737e84e4884109b9526ac645194ba892a74Michal Krol if (token[0] == 'x') 6332861e737e84e4884109b9526ac645194ba892a74Michal Krol ASSIGN_4V(swizzle, 0, 0, 0, 0); 6342861e737e84e4884109b9526ac645194ba892a74Michal Krol else if (token[0] == 'y') 6352861e737e84e4884109b9526ac645194ba892a74Michal Krol ASSIGN_4V(swizzle, 1, 1, 1, 1); 6362861e737e84e4884109b9526ac645194ba892a74Michal Krol else if (token[0] == 'z') 6372861e737e84e4884109b9526ac645194ba892a74Michal Krol ASSIGN_4V(swizzle, 2, 2, 2, 2); 6382861e737e84e4884109b9526ac645194ba892a74Michal Krol else if (token[0] == 'w') 6392861e737e84e4884109b9526ac645194ba892a74Michal Krol ASSIGN_4V(swizzle, 3, 3, 3, 3); 6402861e737e84e4884109b9526ac645194ba892a74Michal Krol else 6412861e737e84e4884109b9526ac645194ba892a74Michal Krol return GL_FALSE; 6422861e737e84e4884109b9526ac645194ba892a74Michal Krol } 6432861e737e84e4884109b9526ac645194ba892a74Michal Krol else { 6442861e737e84e4884109b9526ac645194ba892a74Michal Krol /* 4-component swizzle (vector) */ 6452861e737e84e4884109b9526ac645194ba892a74Michal Krol GLint k; 646324568f79d6e014900c981bd9a0e1dffedc326c8Roel Kluin for (k = 0; k < 4 && token[k]; k++) { 6472861e737e84e4884109b9526ac645194ba892a74Michal Krol if (token[k] == 'x') 6482861e737e84e4884109b9526ac645194ba892a74Michal Krol swizzle[k] = 0; 6492861e737e84e4884109b9526ac645194ba892a74Michal Krol else if (token[k] == 'y') 6502861e737e84e4884109b9526ac645194ba892a74Michal Krol swizzle[k] = 1; 6512861e737e84e4884109b9526ac645194ba892a74Michal Krol else if (token[k] == 'z') 6522861e737e84e4884109b9526ac645194ba892a74Michal Krol swizzle[k] = 2; 6532861e737e84e4884109b9526ac645194ba892a74Michal Krol else if (token[k] == 'w') 6542861e737e84e4884109b9526ac645194ba892a74Michal Krol swizzle[k] = 3; 6552861e737e84e4884109b9526ac645194ba892a74Michal Krol else 6562861e737e84e4884109b9526ac645194ba892a74Michal Krol return GL_FALSE; 6572861e737e84e4884109b9526ac645194ba892a74Michal Krol } 6582861e737e84e4884109b9526ac645194ba892a74Michal Krol if (k != 4) 6592861e737e84e4884109b9526ac645194ba892a74Michal Krol return GL_FALSE; 6602861e737e84e4884109b9526ac645194ba892a74Michal Krol } 6612861e737e84e4884109b9526ac645194ba892a74Michal Krol return GL_TRUE; 6622861e737e84e4884109b9526ac645194ba892a74Michal Krol} 6632861e737e84e4884109b9526ac645194ba892a74Michal Krol 6642861e737e84e4884109b9526ac645194ba892a74Michal Krol 6652861e737e84e4884109b9526ac645194ba892a74Michal Krolstatic GLboolean 6662861e737e84e4884109b9526ac645194ba892a74Michal KrolParse_CondCodeMask(struct parse_state *parseState, 6677e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul struct prog_dst_register *dstReg) 6682861e737e84e4884109b9526ac645194ba892a74Michal Krol{ 6692861e737e84e4884109b9526ac645194ba892a74Michal Krol if (Parse_String(parseState, "EQ")) 6702861e737e84e4884109b9526ac645194ba892a74Michal Krol dstReg->CondMask = COND_EQ; 6712861e737e84e4884109b9526ac645194ba892a74Michal Krol else if (Parse_String(parseState, "GE")) 6722861e737e84e4884109b9526ac645194ba892a74Michal Krol dstReg->CondMask = COND_GE; 6732861e737e84e4884109b9526ac645194ba892a74Michal Krol else if (Parse_String(parseState, "GT")) 6742861e737e84e4884109b9526ac645194ba892a74Michal Krol dstReg->CondMask = COND_GT; 6752861e737e84e4884109b9526ac645194ba892a74Michal Krol else if (Parse_String(parseState, "LE")) 6762861e737e84e4884109b9526ac645194ba892a74Michal Krol dstReg->CondMask = COND_LE; 6772861e737e84e4884109b9526ac645194ba892a74Michal Krol else if (Parse_String(parseState, "LT")) 6782861e737e84e4884109b9526ac645194ba892a74Michal Krol dstReg->CondMask = COND_LT; 6792861e737e84e4884109b9526ac645194ba892a74Michal Krol else if (Parse_String(parseState, "NE")) 6802861e737e84e4884109b9526ac645194ba892a74Michal Krol dstReg->CondMask = COND_NE; 6812861e737e84e4884109b9526ac645194ba892a74Michal Krol else if (Parse_String(parseState, "TR")) 6822861e737e84e4884109b9526ac645194ba892a74Michal Krol dstReg->CondMask = COND_TR; 6832861e737e84e4884109b9526ac645194ba892a74Michal Krol else if (Parse_String(parseState, "FL")) 6842861e737e84e4884109b9526ac645194ba892a74Michal Krol dstReg->CondMask = COND_FL; 6852861e737e84e4884109b9526ac645194ba892a74Michal Krol else 6862861e737e84e4884109b9526ac645194ba892a74Michal Krol RETURN_ERROR1("Invalid condition code mask"); 6872861e737e84e4884109b9526ac645194ba892a74Michal Krol 6882861e737e84e4884109b9526ac645194ba892a74Michal Krol /* look for optional .xyzw swizzle */ 6892861e737e84e4884109b9526ac645194ba892a74Michal Krol if (Parse_String(parseState, ".")) { 6902861e737e84e4884109b9526ac645194ba892a74Michal Krol GLubyte token[100]; 6917c26b61f9366a397e353d7b7f1f1d1f6d0dcd0c7Keith Whitwell GLuint swz[4]; 6927c26b61f9366a397e353d7b7f1f1d1f6d0dcd0c7Keith Whitwell 6932861e737e84e4884109b9526ac645194ba892a74Michal Krol if (!Parse_Token(parseState, token)) /* get xyzw suffix */ 6942861e737e84e4884109b9526ac645194ba892a74Michal Krol RETURN_ERROR; 6952861e737e84e4884109b9526ac645194ba892a74Michal Krol 6967c26b61f9366a397e353d7b7f1f1d1f6d0dcd0c7Keith Whitwell if (!Parse_SwizzleSuffix(token, swz)) 6972861e737e84e4884109b9526ac645194ba892a74Michal Krol RETURN_ERROR1("Invalid swizzle suffix"); 6987c26b61f9366a397e353d7b7f1f1d1f6d0dcd0c7Keith Whitwell 699fd4395b8d1d6f8f018e7e7c3dd0c52fe52ab2794Brian Paul dstReg->CondSwizzle = MAKE_SWIZZLE4(swz[0], swz[1], swz[2], swz[3]); 7002861e737e84e4884109b9526ac645194ba892a74Michal Krol } 7012861e737e84e4884109b9526ac645194ba892a74Michal Krol 7022861e737e84e4884109b9526ac645194ba892a74Michal Krol return GL_TRUE; 7032861e737e84e4884109b9526ac645194ba892a74Michal Krol} 7042861e737e84e4884109b9526ac645194ba892a74Michal Krol 7052861e737e84e4884109b9526ac645194ba892a74Michal Krol 7062861e737e84e4884109b9526ac645194ba892a74Michal Krol/** 7072861e737e84e4884109b9526ac645194ba892a74Michal Krol * Parse a temporary register: Rnn or Hnn 7082861e737e84e4884109b9526ac645194ba892a74Michal Krol */ 7092861e737e84e4884109b9526ac645194ba892a74Michal Krolstatic GLboolean 7102861e737e84e4884109b9526ac645194ba892a74Michal KrolParse_TempReg(struct parse_state *parseState, GLint *tempRegNum) 7112861e737e84e4884109b9526ac645194ba892a74Michal Krol{ 7122861e737e84e4884109b9526ac645194ba892a74Michal Krol GLubyte token[100]; 7132861e737e84e4884109b9526ac645194ba892a74Michal Krol 7142861e737e84e4884109b9526ac645194ba892a74Michal Krol /* Should be 'R##' or 'H##' */ 7152861e737e84e4884109b9526ac645194ba892a74Michal Krol if (!Parse_Token(parseState, token)) 7162861e737e84e4884109b9526ac645194ba892a74Michal Krol RETURN_ERROR; 7172861e737e84e4884109b9526ac645194ba892a74Michal Krol if (token[0] != 'R' && token[0] != 'H') 7182861e737e84e4884109b9526ac645194ba892a74Michal Krol RETURN_ERROR1("Expected R## or H##"); 7192861e737e84e4884109b9526ac645194ba892a74Michal Krol 7202861e737e84e4884109b9526ac645194ba892a74Michal Krol if (IsDigit(token[1])) { 72160b0cae412029e53654f38d0de151908f1feb310Kenneth Graunke GLint reg = atoi((const char *) (token + 1)); 7222861e737e84e4884109b9526ac645194ba892a74Michal Krol if (token[0] == 'H') 7232861e737e84e4884109b9526ac645194ba892a74Michal Krol reg += 32; 7242861e737e84e4884109b9526ac645194ba892a74Michal Krol if (reg >= MAX_NV_FRAGMENT_PROGRAM_TEMPS) 7252861e737e84e4884109b9526ac645194ba892a74Michal Krol RETURN_ERROR1("Invalid temporary register name"); 7262861e737e84e4884109b9526ac645194ba892a74Michal Krol *tempRegNum = reg; 7272861e737e84e4884109b9526ac645194ba892a74Michal Krol } 7282861e737e84e4884109b9526ac645194ba892a74Michal Krol else { 7292861e737e84e4884109b9526ac645194ba892a74Michal Krol RETURN_ERROR1("Invalid temporary register name"); 7302861e737e84e4884109b9526ac645194ba892a74Michal Krol } 7312861e737e84e4884109b9526ac645194ba892a74Michal Krol 7322861e737e84e4884109b9526ac645194ba892a74Michal Krol return GL_TRUE; 7332861e737e84e4884109b9526ac645194ba892a74Michal Krol} 7342861e737e84e4884109b9526ac645194ba892a74Michal Krol 7352861e737e84e4884109b9526ac645194ba892a74Michal Krol 7362861e737e84e4884109b9526ac645194ba892a74Michal Krol/** 7372861e737e84e4884109b9526ac645194ba892a74Michal Krol * Parse a write-only dummy register: RC or HC. 7382861e737e84e4884109b9526ac645194ba892a74Michal Krol */ 7392861e737e84e4884109b9526ac645194ba892a74Michal Krolstatic GLboolean 7402861e737e84e4884109b9526ac645194ba892a74Michal KrolParse_DummyReg(struct parse_state *parseState, GLint *regNum) 7412861e737e84e4884109b9526ac645194ba892a74Michal Krol{ 7422861e737e84e4884109b9526ac645194ba892a74Michal Krol if (Parse_String(parseState, "RC")) { 7432861e737e84e4884109b9526ac645194ba892a74Michal Krol *regNum = 0; 7442861e737e84e4884109b9526ac645194ba892a74Michal Krol } 7452861e737e84e4884109b9526ac645194ba892a74Michal Krol else if (Parse_String(parseState, "HC")) { 7462861e737e84e4884109b9526ac645194ba892a74Michal Krol *regNum = 1; 7472861e737e84e4884109b9526ac645194ba892a74Michal Krol } 7482861e737e84e4884109b9526ac645194ba892a74Michal Krol else { 7492861e737e84e4884109b9526ac645194ba892a74Michal Krol RETURN_ERROR1("Invalid write-only register name"); 7502861e737e84e4884109b9526ac645194ba892a74Michal Krol } 7512861e737e84e4884109b9526ac645194ba892a74Michal Krol 7522861e737e84e4884109b9526ac645194ba892a74Michal Krol return GL_TRUE; 7532861e737e84e4884109b9526ac645194ba892a74Michal Krol} 7542861e737e84e4884109b9526ac645194ba892a74Michal Krol 7552861e737e84e4884109b9526ac645194ba892a74Michal Krol 7562861e737e84e4884109b9526ac645194ba892a74Michal Krol/** 7572861e737e84e4884109b9526ac645194ba892a74Michal Krol * Parse a program local parameter register "p[##]" 7582861e737e84e4884109b9526ac645194ba892a74Michal Krol */ 7592861e737e84e4884109b9526ac645194ba892a74Michal Krolstatic GLboolean 7602861e737e84e4884109b9526ac645194ba892a74Michal KrolParse_ProgramParamReg(struct parse_state *parseState, GLint *regNum) 7612861e737e84e4884109b9526ac645194ba892a74Michal Krol{ 7622861e737e84e4884109b9526ac645194ba892a74Michal Krol GLubyte token[100]; 7632861e737e84e4884109b9526ac645194ba892a74Michal Krol 7642861e737e84e4884109b9526ac645194ba892a74Michal Krol if (!Parse_String(parseState, "p[")) 7652861e737e84e4884109b9526ac645194ba892a74Michal Krol RETURN_ERROR1("Expected p["); 7662861e737e84e4884109b9526ac645194ba892a74Michal Krol 7672861e737e84e4884109b9526ac645194ba892a74Michal Krol if (!Parse_Token(parseState, token)) 7682861e737e84e4884109b9526ac645194ba892a74Michal Krol RETURN_ERROR; 7692861e737e84e4884109b9526ac645194ba892a74Michal Krol 7702861e737e84e4884109b9526ac645194ba892a74Michal Krol if (IsDigit(token[0])) { 7712861e737e84e4884109b9526ac645194ba892a74Michal Krol /* a numbered program parameter register */ 77260b0cae412029e53654f38d0de151908f1feb310Kenneth Graunke GLint reg = atoi((const char *) token); 7732861e737e84e4884109b9526ac645194ba892a74Michal Krol if (reg >= MAX_NV_FRAGMENT_PROGRAM_PARAMS) 7742861e737e84e4884109b9526ac645194ba892a74Michal Krol RETURN_ERROR1("Invalid constant program number"); 7752861e737e84e4884109b9526ac645194ba892a74Michal Krol *regNum = reg; 7762861e737e84e4884109b9526ac645194ba892a74Michal Krol } 7772861e737e84e4884109b9526ac645194ba892a74Michal Krol else { 7782861e737e84e4884109b9526ac645194ba892a74Michal Krol RETURN_ERROR; 7792861e737e84e4884109b9526ac645194ba892a74Michal Krol } 7802861e737e84e4884109b9526ac645194ba892a74Michal Krol 7812861e737e84e4884109b9526ac645194ba892a74Michal Krol if (!Parse_String(parseState, "]")) 7822861e737e84e4884109b9526ac645194ba892a74Michal Krol RETURN_ERROR1("Expected ]"); 7832861e737e84e4884109b9526ac645194ba892a74Michal Krol 7842861e737e84e4884109b9526ac645194ba892a74Michal Krol return GL_TRUE; 7852861e737e84e4884109b9526ac645194ba892a74Michal Krol} 7862861e737e84e4884109b9526ac645194ba892a74Michal Krol 7872861e737e84e4884109b9526ac645194ba892a74Michal Krol 7882861e737e84e4884109b9526ac645194ba892a74Michal Krol/** 7892861e737e84e4884109b9526ac645194ba892a74Michal Krol * Parse f[name] - fragment input register 7902861e737e84e4884109b9526ac645194ba892a74Michal Krol */ 7912861e737e84e4884109b9526ac645194ba892a74Michal Krolstatic GLboolean 7922861e737e84e4884109b9526ac645194ba892a74Michal KrolParse_FragReg(struct parse_state *parseState, GLint *tempRegNum) 7932861e737e84e4884109b9526ac645194ba892a74Michal Krol{ 7942861e737e84e4884109b9526ac645194ba892a74Michal Krol GLubyte token[100]; 7952861e737e84e4884109b9526ac645194ba892a74Michal Krol GLint j; 7962861e737e84e4884109b9526ac645194ba892a74Michal Krol 7972861e737e84e4884109b9526ac645194ba892a74Michal Krol /* Match 'f[' */ 7982861e737e84e4884109b9526ac645194ba892a74Michal Krol if (!Parse_String(parseState, "f[")) 7992861e737e84e4884109b9526ac645194ba892a74Michal Krol RETURN_ERROR1("Expected f["); 8002861e737e84e4884109b9526ac645194ba892a74Michal Krol 8012861e737e84e4884109b9526ac645194ba892a74Michal Krol /* get <name> and look for match */ 8022861e737e84e4884109b9526ac645194ba892a74Michal Krol if (!Parse_Token(parseState, token)) { 8032861e737e84e4884109b9526ac645194ba892a74Michal Krol RETURN_ERROR; 8042861e737e84e4884109b9526ac645194ba892a74Michal Krol } 8052861e737e84e4884109b9526ac645194ba892a74Michal Krol for (j = 0; InputRegisters[j]; j++) { 8068d73aa6d1ae6e89bb2cd8f52f5586d569a4b6eebKenneth Graunke if (strcmp((const char *) token, InputRegisters[j]) == 0) { 8072861e737e84e4884109b9526ac645194ba892a74Michal Krol *tempRegNum = j; 8082861e737e84e4884109b9526ac645194ba892a74Michal Krol parseState->inputsRead |= (1 << j); 8092861e737e84e4884109b9526ac645194ba892a74Michal Krol break; 8102861e737e84e4884109b9526ac645194ba892a74Michal Krol } 8112861e737e84e4884109b9526ac645194ba892a74Michal Krol } 8122861e737e84e4884109b9526ac645194ba892a74Michal Krol if (!InputRegisters[j]) { 8132861e737e84e4884109b9526ac645194ba892a74Michal Krol /* unknown input register label */ 8142861e737e84e4884109b9526ac645194ba892a74Michal Krol RETURN_ERROR2("Invalid register name", token); 8152861e737e84e4884109b9526ac645194ba892a74Michal Krol } 8162861e737e84e4884109b9526ac645194ba892a74Michal Krol 8172861e737e84e4884109b9526ac645194ba892a74Michal Krol /* Match '[' */ 8182861e737e84e4884109b9526ac645194ba892a74Michal Krol if (!Parse_String(parseState, "]")) 8192861e737e84e4884109b9526ac645194ba892a74Michal Krol RETURN_ERROR1("Expected ]"); 8202861e737e84e4884109b9526ac645194ba892a74Michal Krol 8212861e737e84e4884109b9526ac645194ba892a74Michal Krol return GL_TRUE; 8222861e737e84e4884109b9526ac645194ba892a74Michal Krol} 8232861e737e84e4884109b9526ac645194ba892a74Michal Krol 8242861e737e84e4884109b9526ac645194ba892a74Michal Krol 8252861e737e84e4884109b9526ac645194ba892a74Michal Krolstatic GLboolean 8262861e737e84e4884109b9526ac645194ba892a74Michal KrolParse_OutputReg(struct parse_state *parseState, GLint *outputRegNum) 8272861e737e84e4884109b9526ac645194ba892a74Michal Krol{ 8282861e737e84e4884109b9526ac645194ba892a74Michal Krol GLubyte token[100]; 8292861e737e84e4884109b9526ac645194ba892a74Michal Krol 8302861e737e84e4884109b9526ac645194ba892a74Michal Krol /* Match "o[" */ 8312861e737e84e4884109b9526ac645194ba892a74Michal Krol if (!Parse_String(parseState, "o[")) 8322861e737e84e4884109b9526ac645194ba892a74Michal Krol RETURN_ERROR1("Expected o["); 8332861e737e84e4884109b9526ac645194ba892a74Michal Krol 8342861e737e84e4884109b9526ac645194ba892a74Michal Krol /* Get output reg name */ 8352861e737e84e4884109b9526ac645194ba892a74Michal Krol if (!Parse_Token(parseState, token)) 8362861e737e84e4884109b9526ac645194ba892a74Michal Krol RETURN_ERROR; 8372861e737e84e4884109b9526ac645194ba892a74Michal Krol 8382861e737e84e4884109b9526ac645194ba892a74Michal Krol /* try to match an output register name */ 8398d73aa6d1ae6e89bb2cd8f52f5586d569a4b6eebKenneth Graunke if (strcmp((char *) token, "COLR") == 0 || 8408d73aa6d1ae6e89bb2cd8f52f5586d569a4b6eebKenneth Graunke strcmp((char *) token, "COLH") == 0) { 8418d475822e6e19fa79719c856a2db5b6a205db1b9Brian Paul /* note that we don't distinguish between COLR and COLH */ 8428d475822e6e19fa79719c856a2db5b6a205db1b9Brian Paul *outputRegNum = FRAG_RESULT_COLOR; 8438d475822e6e19fa79719c856a2db5b6a205db1b9Brian Paul parseState->outputsWritten |= (1 << FRAG_RESULT_COLOR); 8442861e737e84e4884109b9526ac645194ba892a74Michal Krol } 8458d73aa6d1ae6e89bb2cd8f52f5586d569a4b6eebKenneth Graunke else if (strcmp((char *) token, "DEPR") == 0) { 8468d475822e6e19fa79719c856a2db5b6a205db1b9Brian Paul *outputRegNum = FRAG_RESULT_DEPTH; 8478d475822e6e19fa79719c856a2db5b6a205db1b9Brian Paul parseState->outputsWritten |= (1 << FRAG_RESULT_DEPTH); 8488d475822e6e19fa79719c856a2db5b6a205db1b9Brian Paul } 8498d475822e6e19fa79719c856a2db5b6a205db1b9Brian Paul else { 8502861e737e84e4884109b9526ac645194ba892a74Michal Krol RETURN_ERROR1("Invalid output register name"); 8518d475822e6e19fa79719c856a2db5b6a205db1b9Brian Paul } 8522861e737e84e4884109b9526ac645194ba892a74Michal Krol 8532861e737e84e4884109b9526ac645194ba892a74Michal Krol /* Match ']' */ 8542861e737e84e4884109b9526ac645194ba892a74Michal Krol if (!Parse_String(parseState, "]")) 8552861e737e84e4884109b9526ac645194ba892a74Michal Krol RETURN_ERROR1("Expected ]"); 8562861e737e84e4884109b9526ac645194ba892a74Michal Krol 8572861e737e84e4884109b9526ac645194ba892a74Michal Krol return GL_TRUE; 8582861e737e84e4884109b9526ac645194ba892a74Michal Krol} 8592861e737e84e4884109b9526ac645194ba892a74Michal Krol 8602861e737e84e4884109b9526ac645194ba892a74Michal Krol 8612861e737e84e4884109b9526ac645194ba892a74Michal Krolstatic GLboolean 8622861e737e84e4884109b9526ac645194ba892a74Michal KrolParse_MaskedDstReg(struct parse_state *parseState, 8637e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul struct prog_dst_register *dstReg) 8642861e737e84e4884109b9526ac645194ba892a74Michal Krol{ 8652861e737e84e4884109b9526ac645194ba892a74Michal Krol GLubyte token[100]; 8667c26b61f9366a397e353d7b7f1f1d1f6d0dcd0c7Keith Whitwell GLint idx; 8672861e737e84e4884109b9526ac645194ba892a74Michal Krol 8682861e737e84e4884109b9526ac645194ba892a74Michal Krol /* Dst reg can be R<n>, H<n>, o[n], RC or HC */ 8692861e737e84e4884109b9526ac645194ba892a74Michal Krol if (!Peek_Token(parseState, token)) 8702861e737e84e4884109b9526ac645194ba892a74Michal Krol RETURN_ERROR; 8712861e737e84e4884109b9526ac645194ba892a74Michal Krol 8728d73aa6d1ae6e89bb2cd8f52f5586d569a4b6eebKenneth Graunke if (strcmp((const char *) token, "RC") == 0 || 8738d73aa6d1ae6e89bb2cd8f52f5586d569a4b6eebKenneth Graunke strcmp((const char *) token, "HC") == 0) { 8742861e737e84e4884109b9526ac645194ba892a74Michal Krol /* a write-only register */ 8752861e737e84e4884109b9526ac645194ba892a74Michal Krol dstReg->File = PROGRAM_WRITE_ONLY; 8767c26b61f9366a397e353d7b7f1f1d1f6d0dcd0c7Keith Whitwell if (!Parse_DummyReg(parseState, &idx)) 8772861e737e84e4884109b9526ac645194ba892a74Michal Krol RETURN_ERROR; 8787c26b61f9366a397e353d7b7f1f1d1f6d0dcd0c7Keith Whitwell dstReg->Index = idx; 8792861e737e84e4884109b9526ac645194ba892a74Michal Krol } 8802861e737e84e4884109b9526ac645194ba892a74Michal Krol else if (token[0] == 'R' || token[0] == 'H') { 8812861e737e84e4884109b9526ac645194ba892a74Michal Krol /* a temporary register */ 8822861e737e84e4884109b9526ac645194ba892a74Michal Krol dstReg->File = PROGRAM_TEMPORARY; 8837c26b61f9366a397e353d7b7f1f1d1f6d0dcd0c7Keith Whitwell if (!Parse_TempReg(parseState, &idx)) 8842861e737e84e4884109b9526ac645194ba892a74Michal Krol RETURN_ERROR; 8857c26b61f9366a397e353d7b7f1f1d1f6d0dcd0c7Keith Whitwell dstReg->Index = idx; 8862861e737e84e4884109b9526ac645194ba892a74Michal Krol } 8872861e737e84e4884109b9526ac645194ba892a74Michal Krol else if (token[0] == 'o') { 8882861e737e84e4884109b9526ac645194ba892a74Michal Krol /* an output register */ 8892861e737e84e4884109b9526ac645194ba892a74Michal Krol dstReg->File = PROGRAM_OUTPUT; 8907c26b61f9366a397e353d7b7f1f1d1f6d0dcd0c7Keith Whitwell if (!Parse_OutputReg(parseState, &idx)) 8912861e737e84e4884109b9526ac645194ba892a74Michal Krol RETURN_ERROR; 8927c26b61f9366a397e353d7b7f1f1d1f6d0dcd0c7Keith Whitwell dstReg->Index = idx; 8932861e737e84e4884109b9526ac645194ba892a74Michal Krol } 8942861e737e84e4884109b9526ac645194ba892a74Michal Krol else { 8952861e737e84e4884109b9526ac645194ba892a74Michal Krol RETURN_ERROR1("Invalid destination register name"); 8962861e737e84e4884109b9526ac645194ba892a74Michal Krol } 8972861e737e84e4884109b9526ac645194ba892a74Michal Krol 8982861e737e84e4884109b9526ac645194ba892a74Michal Krol /* Parse optional write mask */ 8992861e737e84e4884109b9526ac645194ba892a74Michal Krol if (Parse_String(parseState, ".")) { 9002861e737e84e4884109b9526ac645194ba892a74Michal Krol /* got a mask */ 9012861e737e84e4884109b9526ac645194ba892a74Michal Krol GLint k = 0; 9022861e737e84e4884109b9526ac645194ba892a74Michal Krol 9032861e737e84e4884109b9526ac645194ba892a74Michal Krol if (!Parse_Token(parseState, token)) /* get xyzw writemask */ 9042861e737e84e4884109b9526ac645194ba892a74Michal Krol RETURN_ERROR; 9052861e737e84e4884109b9526ac645194ba892a74Michal Krol 9067c26b61f9366a397e353d7b7f1f1d1f6d0dcd0c7Keith Whitwell dstReg->WriteMask = 0; 9072861e737e84e4884109b9526ac645194ba892a74Michal Krol 9082861e737e84e4884109b9526ac645194ba892a74Michal Krol if (token[k] == 'x') { 9097c26b61f9366a397e353d7b7f1f1d1f6d0dcd0c7Keith Whitwell dstReg->WriteMask |= WRITEMASK_X; 9102861e737e84e4884109b9526ac645194ba892a74Michal Krol k++; 9112861e737e84e4884109b9526ac645194ba892a74Michal Krol } 9122861e737e84e4884109b9526ac645194ba892a74Michal Krol if (token[k] == 'y') { 9137c26b61f9366a397e353d7b7f1f1d1f6d0dcd0c7Keith Whitwell dstReg->WriteMask |= WRITEMASK_Y; 9142861e737e84e4884109b9526ac645194ba892a74Michal Krol k++; 9152861e737e84e4884109b9526ac645194ba892a74Michal Krol } 9162861e737e84e4884109b9526ac645194ba892a74Michal Krol if (token[k] == 'z') { 9177c26b61f9366a397e353d7b7f1f1d1f6d0dcd0c7Keith Whitwell dstReg->WriteMask |= WRITEMASK_Z; 9182861e737e84e4884109b9526ac645194ba892a74Michal Krol k++; 9192861e737e84e4884109b9526ac645194ba892a74Michal Krol } 9202861e737e84e4884109b9526ac645194ba892a74Michal Krol if (token[k] == 'w') { 9217c26b61f9366a397e353d7b7f1f1d1f6d0dcd0c7Keith Whitwell dstReg->WriteMask |= WRITEMASK_W; 9222861e737e84e4884109b9526ac645194ba892a74Michal Krol k++; 9232861e737e84e4884109b9526ac645194ba892a74Michal Krol } 9242861e737e84e4884109b9526ac645194ba892a74Michal Krol if (k == 0) { 9252861e737e84e4884109b9526ac645194ba892a74Michal Krol RETURN_ERROR1("Invalid writemask character"); 9262861e737e84e4884109b9526ac645194ba892a74Michal Krol } 9272861e737e84e4884109b9526ac645194ba892a74Michal Krol 9282861e737e84e4884109b9526ac645194ba892a74Michal Krol } 9292861e737e84e4884109b9526ac645194ba892a74Michal Krol else { 9307c26b61f9366a397e353d7b7f1f1d1f6d0dcd0c7Keith Whitwell dstReg->WriteMask = WRITEMASK_XYZW; 9312861e737e84e4884109b9526ac645194ba892a74Michal Krol } 9322861e737e84e4884109b9526ac645194ba892a74Michal Krol 9332861e737e84e4884109b9526ac645194ba892a74Michal Krol /* optional condition code mask */ 9342861e737e84e4884109b9526ac645194ba892a74Michal Krol if (Parse_String(parseState, "(")) { 9352861e737e84e4884109b9526ac645194ba892a74Michal Krol /* ("EQ" | "GE" | "GT" | "LE" | "LT" | "NE" | "TR" | "FL".x|y|z|w) */ 9362861e737e84e4884109b9526ac645194ba892a74Michal Krol /* ("EQ" | "GE" | "GT" | "LE" | "LT" | "NE" | "TR" | "FL".[xyzw]) */ 9372861e737e84e4884109b9526ac645194ba892a74Michal Krol if (!Parse_CondCodeMask(parseState, dstReg)) 9382861e737e84e4884109b9526ac645194ba892a74Michal Krol RETURN_ERROR; 9392861e737e84e4884109b9526ac645194ba892a74Michal Krol 9402861e737e84e4884109b9526ac645194ba892a74Michal Krol if (!Parse_String(parseState, ")")) /* consume ")" */ 9412861e737e84e4884109b9526ac645194ba892a74Michal Krol RETURN_ERROR1("Expected )"); 9422861e737e84e4884109b9526ac645194ba892a74Michal Krol 9432861e737e84e4884109b9526ac645194ba892a74Michal Krol return GL_TRUE; 9442861e737e84e4884109b9526ac645194ba892a74Michal Krol } 9452861e737e84e4884109b9526ac645194ba892a74Michal Krol else { 9462861e737e84e4884109b9526ac645194ba892a74Michal Krol /* no cond code mask */ 9472861e737e84e4884109b9526ac645194ba892a74Michal Krol dstReg->CondMask = COND_TR; 9487c26b61f9366a397e353d7b7f1f1d1f6d0dcd0c7Keith Whitwell dstReg->CondSwizzle = SWIZZLE_NOOP; 9492861e737e84e4884109b9526ac645194ba892a74Michal Krol return GL_TRUE; 9502861e737e84e4884109b9526ac645194ba892a74Michal Krol } 9512861e737e84e4884109b9526ac645194ba892a74Michal Krol} 9522861e737e84e4884109b9526ac645194ba892a74Michal Krol 9532861e737e84e4884109b9526ac645194ba892a74Michal Krol 9542861e737e84e4884109b9526ac645194ba892a74Michal Krol/** 9552861e737e84e4884109b9526ac645194ba892a74Michal Krol * Parse a vector source (register, constant, etc): 9562861e737e84e4884109b9526ac645194ba892a74Michal Krol * <vectorSrc> ::= <absVectorSrc> 9572861e737e84e4884109b9526ac645194ba892a74Michal Krol * | <baseVectorSrc> 9582861e737e84e4884109b9526ac645194ba892a74Michal Krol * <absVectorSrc> ::= <negate> "|" <baseVectorSrc> "|" 9592861e737e84e4884109b9526ac645194ba892a74Michal Krol */ 9602861e737e84e4884109b9526ac645194ba892a74Michal Krolstatic GLboolean 9612861e737e84e4884109b9526ac645194ba892a74Michal KrolParse_VectorSrc(struct parse_state *parseState, 9627e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul struct prog_src_register *srcReg) 9632861e737e84e4884109b9526ac645194ba892a74Michal Krol{ 9642861e737e84e4884109b9526ac645194ba892a74Michal Krol GLfloat sign = 1.0F; 9652861e737e84e4884109b9526ac645194ba892a74Michal Krol GLubyte token[100]; 9667c26b61f9366a397e353d7b7f1f1d1f6d0dcd0c7Keith Whitwell GLint idx; 9677db7ff878d3e5a6b345228e6eaee4797bb68b360Brian Paul GLuint negateBase, negateAbs; 9682861e737e84e4884109b9526ac645194ba892a74Michal Krol 9692861e737e84e4884109b9526ac645194ba892a74Michal Krol /* 9702861e737e84e4884109b9526ac645194ba892a74Michal Krol * First, take care of +/- and absolute value stuff. 9712861e737e84e4884109b9526ac645194ba892a74Michal Krol */ 9722861e737e84e4884109b9526ac645194ba892a74Michal Krol if (Parse_String(parseState, "-")) 9732861e737e84e4884109b9526ac645194ba892a74Michal Krol sign = -1.0F; 9742861e737e84e4884109b9526ac645194ba892a74Michal Krol else if (Parse_String(parseState, "+")) 9752861e737e84e4884109b9526ac645194ba892a74Michal Krol sign = +1.0F; 9762861e737e84e4884109b9526ac645194ba892a74Michal Krol 9772861e737e84e4884109b9526ac645194ba892a74Michal Krol if (Parse_String(parseState, "|")) { 9782861e737e84e4884109b9526ac645194ba892a74Michal Krol srcReg->Abs = GL_TRUE; 9797db7ff878d3e5a6b345228e6eaee4797bb68b360Brian Paul negateAbs = (sign < 0.0F) ? NEGATE_XYZW : NEGATE_NONE; 9802861e737e84e4884109b9526ac645194ba892a74Michal Krol 9812861e737e84e4884109b9526ac645194ba892a74Michal Krol if (Parse_String(parseState, "-")) 9827db7ff878d3e5a6b345228e6eaee4797bb68b360Brian Paul negateBase = NEGATE_XYZW; 9832861e737e84e4884109b9526ac645194ba892a74Michal Krol else if (Parse_String(parseState, "+")) 9847db7ff878d3e5a6b345228e6eaee4797bb68b360Brian Paul negateBase = NEGATE_NONE; 9852861e737e84e4884109b9526ac645194ba892a74Michal Krol else 9867db7ff878d3e5a6b345228e6eaee4797bb68b360Brian Paul negateBase = NEGATE_NONE; 9872861e737e84e4884109b9526ac645194ba892a74Michal Krol } 9882861e737e84e4884109b9526ac645194ba892a74Michal Krol else { 9892861e737e84e4884109b9526ac645194ba892a74Michal Krol srcReg->Abs = GL_FALSE; 9907db7ff878d3e5a6b345228e6eaee4797bb68b360Brian Paul negateAbs = NEGATE_NONE; 9917db7ff878d3e5a6b345228e6eaee4797bb68b360Brian Paul negateBase = (sign < 0.0F) ? NEGATE_XYZW : NEGATE_NONE; 9922861e737e84e4884109b9526ac645194ba892a74Michal Krol } 9932861e737e84e4884109b9526ac645194ba892a74Michal Krol 9947db7ff878d3e5a6b345228e6eaee4797bb68b360Brian Paul srcReg->Negate = srcReg->Abs ? negateAbs : negateBase; 9957db7ff878d3e5a6b345228e6eaee4797bb68b360Brian Paul 9962861e737e84e4884109b9526ac645194ba892a74Michal Krol /* This should be the real src vector/register name */ 9972861e737e84e4884109b9526ac645194ba892a74Michal Krol if (!Peek_Token(parseState, token)) 9982861e737e84e4884109b9526ac645194ba892a74Michal Krol RETURN_ERROR; 9992861e737e84e4884109b9526ac645194ba892a74Michal Krol 10002861e737e84e4884109b9526ac645194ba892a74Michal Krol /* Src reg can be Rn, Hn, f[n], p[n], a named parameter, a scalar 10012861e737e84e4884109b9526ac645194ba892a74Michal Krol * literal or vector literal. 10022861e737e84e4884109b9526ac645194ba892a74Michal Krol */ 10032861e737e84e4884109b9526ac645194ba892a74Michal Krol if (token[0] == 'R' || token[0] == 'H') { 10042861e737e84e4884109b9526ac645194ba892a74Michal Krol srcReg->File = PROGRAM_TEMPORARY; 10057c26b61f9366a397e353d7b7f1f1d1f6d0dcd0c7Keith Whitwell if (!Parse_TempReg(parseState, &idx)) 10062861e737e84e4884109b9526ac645194ba892a74Michal Krol RETURN_ERROR; 10077c26b61f9366a397e353d7b7f1f1d1f6d0dcd0c7Keith Whitwell srcReg->Index = idx; 10082861e737e84e4884109b9526ac645194ba892a74Michal Krol } 10092861e737e84e4884109b9526ac645194ba892a74Michal Krol else if (token[0] == 'f') { 1010e6940f0a33a571b199bab60b680c30b718c47445Brian Paul /* XXX this might be an identifier! */ 10112861e737e84e4884109b9526ac645194ba892a74Michal Krol srcReg->File = PROGRAM_INPUT; 10127c26b61f9366a397e353d7b7f1f1d1f6d0dcd0c7Keith Whitwell if (!Parse_FragReg(parseState, &idx)) 10132861e737e84e4884109b9526ac645194ba892a74Michal Krol RETURN_ERROR; 10147c26b61f9366a397e353d7b7f1f1d1f6d0dcd0c7Keith Whitwell srcReg->Index = idx; 10152861e737e84e4884109b9526ac645194ba892a74Michal Krol } 10162861e737e84e4884109b9526ac645194ba892a74Michal Krol else if (token[0] == 'p') { 1017e6940f0a33a571b199bab60b680c30b718c47445Brian Paul /* XXX this might be an identifier! */ 10182861e737e84e4884109b9526ac645194ba892a74Michal Krol srcReg->File = PROGRAM_LOCAL_PARAM; 10197c26b61f9366a397e353d7b7f1f1d1f6d0dcd0c7Keith Whitwell if (!Parse_ProgramParamReg(parseState, &idx)) 10202861e737e84e4884109b9526ac645194ba892a74Michal Krol RETURN_ERROR; 10217c26b61f9366a397e353d7b7f1f1d1f6d0dcd0c7Keith Whitwell srcReg->Index = idx; 10222861e737e84e4884109b9526ac645194ba892a74Michal Krol } 10232861e737e84e4884109b9526ac645194ba892a74Michal Krol else if (IsLetter(token[0])){ 10242861e737e84e4884109b9526ac645194ba892a74Michal Krol GLubyte ident[100]; 10252861e737e84e4884109b9526ac645194ba892a74Michal Krol GLint paramIndex; 10262861e737e84e4884109b9526ac645194ba892a74Michal Krol if (!Parse_Identifier(parseState, ident)) 10272861e737e84e4884109b9526ac645194ba892a74Michal Krol RETURN_ERROR; 10282861e737e84e4884109b9526ac645194ba892a74Michal Krol paramIndex = _mesa_lookup_parameter_index(parseState->parameters, 10292861e737e84e4884109b9526ac645194ba892a74Michal Krol -1, (const char *) ident); 10302861e737e84e4884109b9526ac645194ba892a74Michal Krol if (paramIndex < 0) { 10312861e737e84e4884109b9526ac645194ba892a74Michal Krol RETURN_ERROR2("Undefined constant or parameter: ", ident); 10322861e737e84e4884109b9526ac645194ba892a74Michal Krol } 10332861e737e84e4884109b9526ac645194ba892a74Michal Krol srcReg->File = PROGRAM_NAMED_PARAM; 10342861e737e84e4884109b9526ac645194ba892a74Michal Krol srcReg->Index = paramIndex; 10352861e737e84e4884109b9526ac645194ba892a74Michal Krol } 10362861e737e84e4884109b9526ac645194ba892a74Michal Krol else if (IsDigit(token[0]) || token[0] == '-' || token[0] == '+' || token[0] == '.'){ 10372861e737e84e4884109b9526ac645194ba892a74Michal Krol /* literal scalar constant */ 10382861e737e84e4884109b9526ac645194ba892a74Michal Krol GLfloat values[4]; 1039257f799849a1eb3e81851b92a8fd27efa8f93d47Brian GLuint paramIndex; 10402861e737e84e4884109b9526ac645194ba892a74Michal Krol if (!Parse_ScalarConstant(parseState, values)) 10412861e737e84e4884109b9526ac645194ba892a74Michal Krol RETURN_ERROR; 1042fe1d01cb398cbcb5b28a0b222845d3865c4d612bBrian paramIndex = _mesa_add_unnamed_constant(parseState->parameters, 10436d89abadbcd68bbe9e08f041412549f8dc1fc73cBryan Cain (gl_constant_value *) values, 10446d89abadbcd68bbe9e08f041412549f8dc1fc73cBryan Cain 4, NULL); 10452861e737e84e4884109b9526ac645194ba892a74Michal Krol srcReg->File = PROGRAM_NAMED_PARAM; 10462861e737e84e4884109b9526ac645194ba892a74Michal Krol srcReg->Index = paramIndex; 10472861e737e84e4884109b9526ac645194ba892a74Michal Krol } 10482861e737e84e4884109b9526ac645194ba892a74Michal Krol else if (token[0] == '{'){ 10492861e737e84e4884109b9526ac645194ba892a74Michal Krol /* literal vector constant */ 10502861e737e84e4884109b9526ac645194ba892a74Michal Krol GLfloat values[4]; 1051257f799849a1eb3e81851b92a8fd27efa8f93d47Brian GLuint paramIndex; 10522861e737e84e4884109b9526ac645194ba892a74Michal Krol (void) Parse_String(parseState, "{"); 10532861e737e84e4884109b9526ac645194ba892a74Michal Krol if (!Parse_VectorConstant(parseState, values)) 10542861e737e84e4884109b9526ac645194ba892a74Michal Krol RETURN_ERROR; 1055fe1d01cb398cbcb5b28a0b222845d3865c4d612bBrian paramIndex = _mesa_add_unnamed_constant(parseState->parameters, 10566d89abadbcd68bbe9e08f041412549f8dc1fc73cBryan Cain (gl_constant_value *) values, 10576d89abadbcd68bbe9e08f041412549f8dc1fc73cBryan Cain 4, NULL); 10582861e737e84e4884109b9526ac645194ba892a74Michal Krol srcReg->File = PROGRAM_NAMED_PARAM; 10592861e737e84e4884109b9526ac645194ba892a74Michal Krol srcReg->Index = paramIndex; 10602861e737e84e4884109b9526ac645194ba892a74Michal Krol } 10612861e737e84e4884109b9526ac645194ba892a74Michal Krol else { 10622861e737e84e4884109b9526ac645194ba892a74Michal Krol RETURN_ERROR2("Invalid source register name", token); 10632861e737e84e4884109b9526ac645194ba892a74Michal Krol } 10642861e737e84e4884109b9526ac645194ba892a74Michal Krol 10652861e737e84e4884109b9526ac645194ba892a74Michal Krol /* init swizzle fields */ 10667c26b61f9366a397e353d7b7f1f1d1f6d0dcd0c7Keith Whitwell srcReg->Swizzle = SWIZZLE_NOOP; 10672861e737e84e4884109b9526ac645194ba892a74Michal Krol 10682861e737e84e4884109b9526ac645194ba892a74Michal Krol /* Look for optional swizzle suffix */ 10692861e737e84e4884109b9526ac645194ba892a74Michal Krol if (Parse_String(parseState, ".")) { 10707c26b61f9366a397e353d7b7f1f1d1f6d0dcd0c7Keith Whitwell GLuint swz[4]; 10717c26b61f9366a397e353d7b7f1f1d1f6d0dcd0c7Keith Whitwell 10722861e737e84e4884109b9526ac645194ba892a74Michal Krol if (!Parse_Token(parseState, token)) 10732861e737e84e4884109b9526ac645194ba892a74Michal Krol RETURN_ERROR; 10742861e737e84e4884109b9526ac645194ba892a74Michal Krol 10757c26b61f9366a397e353d7b7f1f1d1f6d0dcd0c7Keith Whitwell if (!Parse_SwizzleSuffix(token, swz)) 10762861e737e84e4884109b9526ac645194ba892a74Michal Krol RETURN_ERROR1("Invalid swizzle suffix"); 10777c26b61f9366a397e353d7b7f1f1d1f6d0dcd0c7Keith Whitwell 1078fd4395b8d1d6f8f018e7e7c3dd0c52fe52ab2794Brian Paul srcReg->Swizzle = MAKE_SWIZZLE4(swz[0], swz[1], swz[2], swz[3]); 10792861e737e84e4884109b9526ac645194ba892a74Michal Krol } 10802861e737e84e4884109b9526ac645194ba892a74Michal Krol 10812861e737e84e4884109b9526ac645194ba892a74Michal Krol /* Finish absolute value */ 10822861e737e84e4884109b9526ac645194ba892a74Michal Krol if (srcReg->Abs && !Parse_String(parseState, "|")) { 10832861e737e84e4884109b9526ac645194ba892a74Michal Krol RETURN_ERROR1("Expected |"); 10842861e737e84e4884109b9526ac645194ba892a74Michal Krol } 10852861e737e84e4884109b9526ac645194ba892a74Michal Krol 10862861e737e84e4884109b9526ac645194ba892a74Michal Krol return GL_TRUE; 10872861e737e84e4884109b9526ac645194ba892a74Michal Krol} 10882861e737e84e4884109b9526ac645194ba892a74Michal Krol 10892861e737e84e4884109b9526ac645194ba892a74Michal Krol 10902861e737e84e4884109b9526ac645194ba892a74Michal Krolstatic GLboolean 10912861e737e84e4884109b9526ac645194ba892a74Michal KrolParse_ScalarSrcReg(struct parse_state *parseState, 10927e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul struct prog_src_register *srcReg) 10932861e737e84e4884109b9526ac645194ba892a74Michal Krol{ 10942861e737e84e4884109b9526ac645194ba892a74Michal Krol GLubyte token[100]; 10952861e737e84e4884109b9526ac645194ba892a74Michal Krol GLfloat sign = 1.0F; 10962861e737e84e4884109b9526ac645194ba892a74Michal Krol GLboolean needSuffix = GL_TRUE; 10977c26b61f9366a397e353d7b7f1f1d1f6d0dcd0c7Keith Whitwell GLint idx; 10987db7ff878d3e5a6b345228e6eaee4797bb68b360Brian Paul GLuint negateBase, negateAbs; 10992861e737e84e4884109b9526ac645194ba892a74Michal Krol 11002861e737e84e4884109b9526ac645194ba892a74Michal Krol /* 11012861e737e84e4884109b9526ac645194ba892a74Michal Krol * First, take care of +/- and absolute value stuff. 11022861e737e84e4884109b9526ac645194ba892a74Michal Krol */ 11032861e737e84e4884109b9526ac645194ba892a74Michal Krol if (Parse_String(parseState, "-")) 11042861e737e84e4884109b9526ac645194ba892a74Michal Krol sign = -1.0F; 11052861e737e84e4884109b9526ac645194ba892a74Michal Krol else if (Parse_String(parseState, "+")) 11062861e737e84e4884109b9526ac645194ba892a74Michal Krol sign = +1.0F; 11072861e737e84e4884109b9526ac645194ba892a74Michal Krol 11082861e737e84e4884109b9526ac645194ba892a74Michal Krol if (Parse_String(parseState, "|")) { 11092861e737e84e4884109b9526ac645194ba892a74Michal Krol srcReg->Abs = GL_TRUE; 11107db7ff878d3e5a6b345228e6eaee4797bb68b360Brian Paul negateAbs = (sign < 0.0F) ? NEGATE_XYZW : NEGATE_NONE; 11112861e737e84e4884109b9526ac645194ba892a74Michal Krol 11122861e737e84e4884109b9526ac645194ba892a74Michal Krol if (Parse_String(parseState, "-")) 11137db7ff878d3e5a6b345228e6eaee4797bb68b360Brian Paul negateBase = NEGATE_XYZW; 11142861e737e84e4884109b9526ac645194ba892a74Michal Krol else if (Parse_String(parseState, "+")) 11157db7ff878d3e5a6b345228e6eaee4797bb68b360Brian Paul negateBase = NEGATE_NONE; 11162861e737e84e4884109b9526ac645194ba892a74Michal Krol else 11177db7ff878d3e5a6b345228e6eaee4797bb68b360Brian Paul negateBase = NEGATE_NONE; 11182861e737e84e4884109b9526ac645194ba892a74Michal Krol } 11192861e737e84e4884109b9526ac645194ba892a74Michal Krol else { 11202861e737e84e4884109b9526ac645194ba892a74Michal Krol srcReg->Abs = GL_FALSE; 11217db7ff878d3e5a6b345228e6eaee4797bb68b360Brian Paul negateAbs = NEGATE_NONE; 11227db7ff878d3e5a6b345228e6eaee4797bb68b360Brian Paul negateBase = (sign < 0.0F) ? NEGATE_XYZW : NEGATE_NONE; 11232861e737e84e4884109b9526ac645194ba892a74Michal Krol } 11242861e737e84e4884109b9526ac645194ba892a74Michal Krol 11257db7ff878d3e5a6b345228e6eaee4797bb68b360Brian Paul srcReg->Negate = srcReg->Abs ? negateAbs : negateBase; 11267db7ff878d3e5a6b345228e6eaee4797bb68b360Brian Paul 11272861e737e84e4884109b9526ac645194ba892a74Michal Krol if (!Peek_Token(parseState, token)) 11282861e737e84e4884109b9526ac645194ba892a74Michal Krol RETURN_ERROR; 11292861e737e84e4884109b9526ac645194ba892a74Michal Krol 11302861e737e84e4884109b9526ac645194ba892a74Michal Krol /* Src reg can be R<n>, H<n> or a named fragment attrib */ 11312861e737e84e4884109b9526ac645194ba892a74Michal Krol if (token[0] == 'R' || token[0] == 'H') { 11322861e737e84e4884109b9526ac645194ba892a74Michal Krol srcReg->File = PROGRAM_TEMPORARY; 11337c26b61f9366a397e353d7b7f1f1d1f6d0dcd0c7Keith Whitwell if (!Parse_TempReg(parseState, &idx)) 11342861e737e84e4884109b9526ac645194ba892a74Michal Krol RETURN_ERROR; 11357c26b61f9366a397e353d7b7f1f1d1f6d0dcd0c7Keith Whitwell srcReg->Index = idx; 11362861e737e84e4884109b9526ac645194ba892a74Michal Krol } 11372861e737e84e4884109b9526ac645194ba892a74Michal Krol else if (token[0] == 'f') { 11382861e737e84e4884109b9526ac645194ba892a74Michal Krol srcReg->File = PROGRAM_INPUT; 11397c26b61f9366a397e353d7b7f1f1d1f6d0dcd0c7Keith Whitwell if (!Parse_FragReg(parseState, &idx)) 11402861e737e84e4884109b9526ac645194ba892a74Michal Krol RETURN_ERROR; 11417c26b61f9366a397e353d7b7f1f1d1f6d0dcd0c7Keith Whitwell srcReg->Index = idx; 11422861e737e84e4884109b9526ac645194ba892a74Michal Krol } 11432861e737e84e4884109b9526ac645194ba892a74Michal Krol else if (token[0] == '{') { 11442861e737e84e4884109b9526ac645194ba892a74Michal Krol /* vector literal */ 11452861e737e84e4884109b9526ac645194ba892a74Michal Krol GLfloat values[4]; 114681c4fee160cd2840caf77bbdbf462e783911141aBrian GLuint paramIndex; 11472861e737e84e4884109b9526ac645194ba892a74Michal Krol (void) Parse_String(parseState, "{"); 11482861e737e84e4884109b9526ac645194ba892a74Michal Krol if (!Parse_VectorConstant(parseState, values)) 11492861e737e84e4884109b9526ac645194ba892a74Michal Krol RETURN_ERROR; 1150fe1d01cb398cbcb5b28a0b222845d3865c4d612bBrian paramIndex = _mesa_add_unnamed_constant(parseState->parameters, 11516d89abadbcd68bbe9e08f041412549f8dc1fc73cBryan Cain (gl_constant_value *) values, 11526d89abadbcd68bbe9e08f041412549f8dc1fc73cBryan Cain 4, NULL); 11532861e737e84e4884109b9526ac645194ba892a74Michal Krol srcReg->File = PROGRAM_NAMED_PARAM; 11542861e737e84e4884109b9526ac645194ba892a74Michal Krol srcReg->Index = paramIndex; 11552861e737e84e4884109b9526ac645194ba892a74Michal Krol } 1156e6940f0a33a571b199bab60b680c30b718c47445Brian Paul else if (IsLetter(token[0])){ 1157e6940f0a33a571b199bab60b680c30b718c47445Brian Paul /* named param/constant */ 1158e6940f0a33a571b199bab60b680c30b718c47445Brian Paul GLubyte ident[100]; 1159e6940f0a33a571b199bab60b680c30b718c47445Brian Paul GLint paramIndex; 1160e6940f0a33a571b199bab60b680c30b718c47445Brian Paul if (!Parse_Identifier(parseState, ident)) 1161e6940f0a33a571b199bab60b680c30b718c47445Brian Paul RETURN_ERROR; 1162e6940f0a33a571b199bab60b680c30b718c47445Brian Paul paramIndex = _mesa_lookup_parameter_index(parseState->parameters, 1163e6940f0a33a571b199bab60b680c30b718c47445Brian Paul -1, (const char *) ident); 1164e6940f0a33a571b199bab60b680c30b718c47445Brian Paul if (paramIndex < 0) { 1165e6940f0a33a571b199bab60b680c30b718c47445Brian Paul RETURN_ERROR2("Undefined constant or parameter: ", ident); 1166e6940f0a33a571b199bab60b680c30b718c47445Brian Paul } 1167e6940f0a33a571b199bab60b680c30b718c47445Brian Paul srcReg->File = PROGRAM_NAMED_PARAM; 1168e6940f0a33a571b199bab60b680c30b718c47445Brian Paul srcReg->Index = paramIndex; 1169e6940f0a33a571b199bab60b680c30b718c47445Brian Paul } 11702861e737e84e4884109b9526ac645194ba892a74Michal Krol else if (IsDigit(token[0])) { 11712861e737e84e4884109b9526ac645194ba892a74Michal Krol /* scalar literal */ 11722861e737e84e4884109b9526ac645194ba892a74Michal Krol GLfloat values[4]; 117381c4fee160cd2840caf77bbdbf462e783911141aBrian GLuint paramIndex; 11742861e737e84e4884109b9526ac645194ba892a74Michal Krol if (!Parse_ScalarConstant(parseState, values)) 11752861e737e84e4884109b9526ac645194ba892a74Michal Krol RETURN_ERROR; 1176fe1d01cb398cbcb5b28a0b222845d3865c4d612bBrian paramIndex = _mesa_add_unnamed_constant(parseState->parameters, 11776d89abadbcd68bbe9e08f041412549f8dc1fc73cBryan Cain (gl_constant_value *) values, 11786d89abadbcd68bbe9e08f041412549f8dc1fc73cBryan Cain 4, NULL); 11792861e737e84e4884109b9526ac645194ba892a74Michal Krol srcReg->Index = paramIndex; 11802861e737e84e4884109b9526ac645194ba892a74Michal Krol srcReg->File = PROGRAM_NAMED_PARAM; 11812861e737e84e4884109b9526ac645194ba892a74Michal Krol needSuffix = GL_FALSE; 11822861e737e84e4884109b9526ac645194ba892a74Michal Krol } 11832861e737e84e4884109b9526ac645194ba892a74Michal Krol else { 11842861e737e84e4884109b9526ac645194ba892a74Michal Krol RETURN_ERROR2("Invalid scalar source argument", token); 11852861e737e84e4884109b9526ac645194ba892a74Michal Krol } 11862861e737e84e4884109b9526ac645194ba892a74Michal Krol 11877c26b61f9366a397e353d7b7f1f1d1f6d0dcd0c7Keith Whitwell srcReg->Swizzle = 0; 11882861e737e84e4884109b9526ac645194ba892a74Michal Krol if (needSuffix) { 11892861e737e84e4884109b9526ac645194ba892a74Michal Krol /* parse .[xyzw] suffix */ 11902861e737e84e4884109b9526ac645194ba892a74Michal Krol if (!Parse_String(parseState, ".")) 11912861e737e84e4884109b9526ac645194ba892a74Michal Krol RETURN_ERROR1("Expected ."); 11922861e737e84e4884109b9526ac645194ba892a74Michal Krol 11932861e737e84e4884109b9526ac645194ba892a74Michal Krol if (!Parse_Token(parseState, token)) 11942861e737e84e4884109b9526ac645194ba892a74Michal Krol RETURN_ERROR; 11952861e737e84e4884109b9526ac645194ba892a74Michal Krol 11962861e737e84e4884109b9526ac645194ba892a74Michal Krol if (token[0] == 'x' && token[1] == 0) { 11977c26b61f9366a397e353d7b7f1f1d1f6d0dcd0c7Keith Whitwell srcReg->Swizzle = 0; 11982861e737e84e4884109b9526ac645194ba892a74Michal Krol } 11992861e737e84e4884109b9526ac645194ba892a74Michal Krol else if (token[0] == 'y' && token[1] == 0) { 12007c26b61f9366a397e353d7b7f1f1d1f6d0dcd0c7Keith Whitwell srcReg->Swizzle = 1; 12012861e737e84e4884109b9526ac645194ba892a74Michal Krol } 12022861e737e84e4884109b9526ac645194ba892a74Michal Krol else if (token[0] == 'z' && token[1] == 0) { 12037c26b61f9366a397e353d7b7f1f1d1f6d0dcd0c7Keith Whitwell srcReg->Swizzle = 2; 12042861e737e84e4884109b9526ac645194ba892a74Michal Krol } 12052861e737e84e4884109b9526ac645194ba892a74Michal Krol else if (token[0] == 'w' && token[1] == 0) { 12067c26b61f9366a397e353d7b7f1f1d1f6d0dcd0c7Keith Whitwell srcReg->Swizzle = 3; 12072861e737e84e4884109b9526ac645194ba892a74Michal Krol } 12082861e737e84e4884109b9526ac645194ba892a74Michal Krol else { 12092861e737e84e4884109b9526ac645194ba892a74Michal Krol RETURN_ERROR1("Invalid scalar source suffix"); 12102861e737e84e4884109b9526ac645194ba892a74Michal Krol } 12112861e737e84e4884109b9526ac645194ba892a74Michal Krol } 12122861e737e84e4884109b9526ac645194ba892a74Michal Krol 12132861e737e84e4884109b9526ac645194ba892a74Michal Krol /* Finish absolute value */ 12142861e737e84e4884109b9526ac645194ba892a74Michal Krol if (srcReg->Abs && !Parse_String(parseState, "|")) { 12152861e737e84e4884109b9526ac645194ba892a74Michal Krol RETURN_ERROR1("Expected |"); 12162861e737e84e4884109b9526ac645194ba892a74Michal Krol } 12172861e737e84e4884109b9526ac645194ba892a74Michal Krol 12182861e737e84e4884109b9526ac645194ba892a74Michal Krol return GL_TRUE; 12192861e737e84e4884109b9526ac645194ba892a74Michal Krol} 12202861e737e84e4884109b9526ac645194ba892a74Michal Krol 12212861e737e84e4884109b9526ac645194ba892a74Michal Krol 12222a5afe3ab8d4c3624ed72b99a11b6a9017078d1cBrian Paulstatic GLboolean 12232a5afe3ab8d4c3624ed72b99a11b6a9017078d1cBrian PaulParse_PrintInstruction(struct parse_state *parseState, 12247e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul struct prog_instruction *inst) 12252a5afe3ab8d4c3624ed72b99a11b6a9017078d1cBrian Paul{ 12262a5afe3ab8d4c3624ed72b99a11b6a9017078d1cBrian Paul const GLubyte *str; 12272a5afe3ab8d4c3624ed72b99a11b6a9017078d1cBrian Paul GLubyte *msg; 12282a5afe3ab8d4c3624ed72b99a11b6a9017078d1cBrian Paul GLuint len; 12297c26b61f9366a397e353d7b7f1f1d1f6d0dcd0c7Keith Whitwell GLint idx; 12302a5afe3ab8d4c3624ed72b99a11b6a9017078d1cBrian Paul 12312a5afe3ab8d4c3624ed72b99a11b6a9017078d1cBrian Paul /* The first argument is a literal string 'just like this' */ 12322a5afe3ab8d4c3624ed72b99a11b6a9017078d1cBrian Paul if (!Parse_String(parseState, "'")) 12332a5afe3ab8d4c3624ed72b99a11b6a9017078d1cBrian Paul RETURN_ERROR1("Expected '"); 12342a5afe3ab8d4c3624ed72b99a11b6a9017078d1cBrian Paul 12352a5afe3ab8d4c3624ed72b99a11b6a9017078d1cBrian Paul str = parseState->pos; 12362a5afe3ab8d4c3624ed72b99a11b6a9017078d1cBrian Paul for (len = 0; str[len] != '\''; len++) /* find closing quote */ 12372a5afe3ab8d4c3624ed72b99a11b6a9017078d1cBrian Paul ; 12382a5afe3ab8d4c3624ed72b99a11b6a9017078d1cBrian Paul parseState->pos += len + 1; 123932f2fd1c5d6088692551c80352b7d6fa35b0cd09Kristian Høgsberg msg = (GLubyte*) malloc(len + 1); 12402a5afe3ab8d4c3624ed72b99a11b6a9017078d1cBrian Paul 1241c7ac486261ad30ef654f6d0b1608da4e8483cd40Kenneth Graunke memcpy(msg, str, len); 12422a5afe3ab8d4c3624ed72b99a11b6a9017078d1cBrian Paul msg[len] = 0; 12432a5afe3ab8d4c3624ed72b99a11b6a9017078d1cBrian Paul inst->Data = msg; 12442a5afe3ab8d4c3624ed72b99a11b6a9017078d1cBrian Paul 12452a5afe3ab8d4c3624ed72b99a11b6a9017078d1cBrian Paul if (Parse_String(parseState, ",")) { 12462a5afe3ab8d4c3624ed72b99a11b6a9017078d1cBrian Paul /* got an optional register to print */ 12472a5afe3ab8d4c3624ed72b99a11b6a9017078d1cBrian Paul GLubyte token[100]; 12482a5afe3ab8d4c3624ed72b99a11b6a9017078d1cBrian Paul GetToken(parseState, token); 12492a5afe3ab8d4c3624ed72b99a11b6a9017078d1cBrian Paul if (token[0] == 'o') { 12502a5afe3ab8d4c3624ed72b99a11b6a9017078d1cBrian Paul /* dst reg */ 12517c26b61f9366a397e353d7b7f1f1d1f6d0dcd0c7Keith Whitwell if (!Parse_OutputReg(parseState, &idx)) 12522a5afe3ab8d4c3624ed72b99a11b6a9017078d1cBrian Paul RETURN_ERROR; 12537c26b61f9366a397e353d7b7f1f1d1f6d0dcd0c7Keith Whitwell inst->SrcReg[0].Index = idx; 12542a5afe3ab8d4c3624ed72b99a11b6a9017078d1cBrian Paul inst->SrcReg[0].File = PROGRAM_OUTPUT; 12552a5afe3ab8d4c3624ed72b99a11b6a9017078d1cBrian Paul } 12562a5afe3ab8d4c3624ed72b99a11b6a9017078d1cBrian Paul else { 12572a5afe3ab8d4c3624ed72b99a11b6a9017078d1cBrian Paul /* src reg */ 12582a5afe3ab8d4c3624ed72b99a11b6a9017078d1cBrian Paul if (!Parse_VectorSrc(parseState, &inst->SrcReg[0])) 12592a5afe3ab8d4c3624ed72b99a11b6a9017078d1cBrian Paul RETURN_ERROR; 12602a5afe3ab8d4c3624ed72b99a11b6a9017078d1cBrian Paul } 12612a5afe3ab8d4c3624ed72b99a11b6a9017078d1cBrian Paul } 12622a5afe3ab8d4c3624ed72b99a11b6a9017078d1cBrian Paul else { 12638cdf3729468aefb7c67c8ecd32fd850adbf6d351Brian Paul inst->SrcReg[0].File = PROGRAM_UNDEFINED; 12642a5afe3ab8d4c3624ed72b99a11b6a9017078d1cBrian Paul } 12652a5afe3ab8d4c3624ed72b99a11b6a9017078d1cBrian Paul 12667c26b61f9366a397e353d7b7f1f1d1f6d0dcd0c7Keith Whitwell inst->SrcReg[0].Swizzle = SWIZZLE_NOOP; 12672a5afe3ab8d4c3624ed72b99a11b6a9017078d1cBrian Paul inst->SrcReg[0].Abs = GL_FALSE; 12687db7ff878d3e5a6b345228e6eaee4797bb68b360Brian Paul inst->SrcReg[0].Negate = NEGATE_NONE; 12692a5afe3ab8d4c3624ed72b99a11b6a9017078d1cBrian Paul 12702a5afe3ab8d4c3624ed72b99a11b6a9017078d1cBrian Paul return GL_TRUE; 12712a5afe3ab8d4c3624ed72b99a11b6a9017078d1cBrian Paul} 12722a5afe3ab8d4c3624ed72b99a11b6a9017078d1cBrian Paul 12732861e737e84e4884109b9526ac645194ba892a74Michal Krol 12742861e737e84e4884109b9526ac645194ba892a74Michal Krolstatic GLboolean 12752861e737e84e4884109b9526ac645194ba892a74Michal KrolParse_InstructionSequence(struct parse_state *parseState, 12767e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul struct prog_instruction program[]) 12772861e737e84e4884109b9526ac645194ba892a74Michal Krol{ 12782861e737e84e4884109b9526ac645194ba892a74Michal Krol while (1) { 12797e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul struct prog_instruction *inst = program + parseState->numInst; 12802861e737e84e4884109b9526ac645194ba892a74Michal Krol struct instruction_pattern instMatch; 12812861e737e84e4884109b9526ac645194ba892a74Michal Krol GLubyte token[100]; 12822861e737e84e4884109b9526ac645194ba892a74Michal Krol 12832861e737e84e4884109b9526ac645194ba892a74Michal Krol /* Initialize the instruction */ 1284d6272e06172f7ac7a0d6e8062e8ffba33e1ab3baBrian Paul _mesa_init_instructions(inst, 1); 12852861e737e84e4884109b9526ac645194ba892a74Michal Krol 12862861e737e84e4884109b9526ac645194ba892a74Michal Krol /* special instructions */ 12872861e737e84e4884109b9526ac645194ba892a74Michal Krol if (Parse_String(parseState, "DEFINE")) { 12882861e737e84e4884109b9526ac645194ba892a74Michal Krol GLubyte id[100]; 12892861e737e84e4884109b9526ac645194ba892a74Michal Krol GLfloat value[7]; /* yes, 7 to be safe */ 12902861e737e84e4884109b9526ac645194ba892a74Michal Krol if (!Parse_Identifier(parseState, id)) 12912861e737e84e4884109b9526ac645194ba892a74Michal Krol RETURN_ERROR; 12922861e737e84e4884109b9526ac645194ba892a74Michal Krol /* XXX make sure id is not a reserved identifer, like R9 */ 12932861e737e84e4884109b9526ac645194ba892a74Michal Krol if (!Parse_String(parseState, "=")) 12942861e737e84e4884109b9526ac645194ba892a74Michal Krol RETURN_ERROR1("Expected ="); 12952861e737e84e4884109b9526ac645194ba892a74Michal Krol if (!Parse_VectorOrScalarConstant(parseState, value)) 12962861e737e84e4884109b9526ac645194ba892a74Michal Krol RETURN_ERROR; 12972861e737e84e4884109b9526ac645194ba892a74Michal Krol if (!Parse_String(parseState, ";")) 12982861e737e84e4884109b9526ac645194ba892a74Michal Krol RETURN_ERROR1("Expected ;"); 12992861e737e84e4884109b9526ac645194ba892a74Michal Krol if (_mesa_lookup_parameter_index(parseState->parameters, 13002861e737e84e4884109b9526ac645194ba892a74Michal Krol -1, (const char *) id) >= 0) { 13012861e737e84e4884109b9526ac645194ba892a74Michal Krol RETURN_ERROR2(id, "already defined"); 13022861e737e84e4884109b9526ac645194ba892a74Michal Krol } 13032861e737e84e4884109b9526ac645194ba892a74Michal Krol _mesa_add_named_parameter(parseState->parameters, 13046d89abadbcd68bbe9e08f041412549f8dc1fc73cBryan Cain (const char *) id, 13056d89abadbcd68bbe9e08f041412549f8dc1fc73cBryan Cain (gl_constant_value *) value); 13062861e737e84e4884109b9526ac645194ba892a74Michal Krol } 13072861e737e84e4884109b9526ac645194ba892a74Michal Krol else if (Parse_String(parseState, "DECLARE")) { 13082861e737e84e4884109b9526ac645194ba892a74Michal Krol GLubyte id[100]; 13092861e737e84e4884109b9526ac645194ba892a74Michal Krol GLfloat value[7] = {0, 0, 0, 0, 0, 0, 0}; /* yes, to be safe */ 13102861e737e84e4884109b9526ac645194ba892a74Michal Krol if (!Parse_Identifier(parseState, id)) 13112861e737e84e4884109b9526ac645194ba892a74Michal Krol RETURN_ERROR; 13122861e737e84e4884109b9526ac645194ba892a74Michal Krol /* XXX make sure id is not a reserved identifer, like R9 */ 13132861e737e84e4884109b9526ac645194ba892a74Michal Krol if (Parse_String(parseState, "=")) { 13142861e737e84e4884109b9526ac645194ba892a74Michal Krol if (!Parse_VectorOrScalarConstant(parseState, value)) 13152861e737e84e4884109b9526ac645194ba892a74Michal Krol RETURN_ERROR; 13162861e737e84e4884109b9526ac645194ba892a74Michal Krol } 13172861e737e84e4884109b9526ac645194ba892a74Michal Krol if (!Parse_String(parseState, ";")) 13182861e737e84e4884109b9526ac645194ba892a74Michal Krol RETURN_ERROR1("Expected ;"); 13192861e737e84e4884109b9526ac645194ba892a74Michal Krol if (_mesa_lookup_parameter_index(parseState->parameters, 13202861e737e84e4884109b9526ac645194ba892a74Michal Krol -1, (const char *) id) >= 0) { 13212861e737e84e4884109b9526ac645194ba892a74Michal Krol RETURN_ERROR2(id, "already declared"); 13222861e737e84e4884109b9526ac645194ba892a74Michal Krol } 13232861e737e84e4884109b9526ac645194ba892a74Michal Krol _mesa_add_named_parameter(parseState->parameters, 13246d89abadbcd68bbe9e08f041412549f8dc1fc73cBryan Cain (const char *) id, 13256d89abadbcd68bbe9e08f041412549f8dc1fc73cBryan Cain (gl_constant_value *) value); 13262861e737e84e4884109b9526ac645194ba892a74Michal Krol } 13272861e737e84e4884109b9526ac645194ba892a74Michal Krol else if (Parse_String(parseState, "END")) { 13287e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul inst->Opcode = OPCODE_END; 13292861e737e84e4884109b9526ac645194ba892a74Michal Krol parseState->numInst++; 13302861e737e84e4884109b9526ac645194ba892a74Michal Krol if (Parse_Token(parseState, token)) { 13312861e737e84e4884109b9526ac645194ba892a74Michal Krol RETURN_ERROR1("Code after END opcode."); 13322861e737e84e4884109b9526ac645194ba892a74Michal Krol } 13332861e737e84e4884109b9526ac645194ba892a74Michal Krol break; 13342861e737e84e4884109b9526ac645194ba892a74Michal Krol } 13352861e737e84e4884109b9526ac645194ba892a74Michal Krol else { 13362861e737e84e4884109b9526ac645194ba892a74Michal Krol /* general/arithmetic instruction */ 13372861e737e84e4884109b9526ac645194ba892a74Michal Krol 13382861e737e84e4884109b9526ac645194ba892a74Michal Krol /* get token */ 13392861e737e84e4884109b9526ac645194ba892a74Michal Krol if (!Parse_Token(parseState, token)) { 13402861e737e84e4884109b9526ac645194ba892a74Michal Krol RETURN_ERROR1("Missing END instruction."); 13412861e737e84e4884109b9526ac645194ba892a74Michal Krol } 13422861e737e84e4884109b9526ac645194ba892a74Michal Krol 13432861e737e84e4884109b9526ac645194ba892a74Michal Krol /* try to find matching instuction */ 13442861e737e84e4884109b9526ac645194ba892a74Michal Krol instMatch = MatchInstruction(token); 134528b014ee256290eb0494b967e40c475c0c895f57Brian Paul if (instMatch.opcode >= MAX_OPCODE) { 13462861e737e84e4884109b9526ac645194ba892a74Michal Krol /* bad instruction name */ 13472861e737e84e4884109b9526ac645194ba892a74Michal Krol RETURN_ERROR2("Unexpected token: ", token); 13482861e737e84e4884109b9526ac645194ba892a74Michal Krol } 13492861e737e84e4884109b9526ac645194ba892a74Michal Krol 13502861e737e84e4884109b9526ac645194ba892a74Michal Krol inst->Opcode = instMatch.opcode; 13512861e737e84e4884109b9526ac645194ba892a74Michal Krol inst->Precision = instMatch.suffixes & (_R | _H | _X); 1352e31ac052236ea615b4995f9ec301d8af4b864531Brian Paul inst->SaturateMode = (instMatch.suffixes & (_S)) 1353e31ac052236ea615b4995f9ec301d8af4b864531Brian Paul ? SATURATE_ZERO_ONE : SATURATE_OFF; 13547e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul inst->CondUpdate = (instMatch.suffixes & (_C)) ? GL_TRUE : GL_FALSE; 13552861e737e84e4884109b9526ac645194ba892a74Michal Krol 13562861e737e84e4884109b9526ac645194ba892a74Michal Krol /* 13572861e737e84e4884109b9526ac645194ba892a74Michal Krol * parse the input and output operands 13582861e737e84e4884109b9526ac645194ba892a74Michal Krol */ 13592861e737e84e4884109b9526ac645194ba892a74Michal Krol if (instMatch.outputs == OUTPUT_S || instMatch.outputs == OUTPUT_V) { 13602861e737e84e4884109b9526ac645194ba892a74Michal Krol if (!Parse_MaskedDstReg(parseState, &inst->DstReg)) 13612861e737e84e4884109b9526ac645194ba892a74Michal Krol RETURN_ERROR; 13622861e737e84e4884109b9526ac645194ba892a74Michal Krol if (!Parse_String(parseState, ",")) 13632861e737e84e4884109b9526ac645194ba892a74Michal Krol RETURN_ERROR1("Expected ,"); 13642861e737e84e4884109b9526ac645194ba892a74Michal Krol } 13652861e737e84e4884109b9526ac645194ba892a74Michal Krol else if (instMatch.outputs == OUTPUT_NONE) { 13667e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul if (instMatch.opcode == OPCODE_KIL_NV) { 13672a5afe3ab8d4c3624ed72b99a11b6a9017078d1cBrian Paul /* This is a little weird, the cond code info is in 13682a5afe3ab8d4c3624ed72b99a11b6a9017078d1cBrian Paul * the dest register. 13692a5afe3ab8d4c3624ed72b99a11b6a9017078d1cBrian Paul */ 13702a5afe3ab8d4c3624ed72b99a11b6a9017078d1cBrian Paul if (!Parse_CondCodeMask(parseState, &inst->DstReg)) 13712a5afe3ab8d4c3624ed72b99a11b6a9017078d1cBrian Paul RETURN_ERROR; 13722a5afe3ab8d4c3624ed72b99a11b6a9017078d1cBrian Paul } 13732a5afe3ab8d4c3624ed72b99a11b6a9017078d1cBrian Paul else { 13747e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul ASSERT(instMatch.opcode == OPCODE_PRINT); 13752a5afe3ab8d4c3624ed72b99a11b6a9017078d1cBrian Paul } 13762861e737e84e4884109b9526ac645194ba892a74Michal Krol } 13772861e737e84e4884109b9526ac645194ba892a74Michal Krol 13782861e737e84e4884109b9526ac645194ba892a74Michal Krol if (instMatch.inputs == INPUT_1V) { 13792861e737e84e4884109b9526ac645194ba892a74Michal Krol if (!Parse_VectorSrc(parseState, &inst->SrcReg[0])) 13802861e737e84e4884109b9526ac645194ba892a74Michal Krol RETURN_ERROR; 13812861e737e84e4884109b9526ac645194ba892a74Michal Krol } 13822861e737e84e4884109b9526ac645194ba892a74Michal Krol else if (instMatch.inputs == INPUT_2V) { 13832861e737e84e4884109b9526ac645194ba892a74Michal Krol if (!Parse_VectorSrc(parseState, &inst->SrcReg[0])) 13842861e737e84e4884109b9526ac645194ba892a74Michal Krol RETURN_ERROR; 13852861e737e84e4884109b9526ac645194ba892a74Michal Krol if (!Parse_String(parseState, ",")) 13862861e737e84e4884109b9526ac645194ba892a74Michal Krol RETURN_ERROR1("Expected ,"); 13872861e737e84e4884109b9526ac645194ba892a74Michal Krol if (!Parse_VectorSrc(parseState, &inst->SrcReg[1])) 13882861e737e84e4884109b9526ac645194ba892a74Michal Krol RETURN_ERROR; 13892861e737e84e4884109b9526ac645194ba892a74Michal Krol } 13902861e737e84e4884109b9526ac645194ba892a74Michal Krol else if (instMatch.inputs == INPUT_3V) { 13912861e737e84e4884109b9526ac645194ba892a74Michal Krol if (!Parse_VectorSrc(parseState, &inst->SrcReg[0])) 13922861e737e84e4884109b9526ac645194ba892a74Michal Krol RETURN_ERROR; 13932861e737e84e4884109b9526ac645194ba892a74Michal Krol if (!Parse_String(parseState, ",")) 13942861e737e84e4884109b9526ac645194ba892a74Michal Krol RETURN_ERROR1("Expected ,"); 13952861e737e84e4884109b9526ac645194ba892a74Michal Krol if (!Parse_VectorSrc(parseState, &inst->SrcReg[1])) 13962861e737e84e4884109b9526ac645194ba892a74Michal Krol RETURN_ERROR; 13972861e737e84e4884109b9526ac645194ba892a74Michal Krol if (!Parse_String(parseState, ",")) 13982861e737e84e4884109b9526ac645194ba892a74Michal Krol RETURN_ERROR1("Expected ,"); 13992861e737e84e4884109b9526ac645194ba892a74Michal Krol if (!Parse_VectorSrc(parseState, &inst->SrcReg[2])) 14002861e737e84e4884109b9526ac645194ba892a74Michal Krol RETURN_ERROR; 14012861e737e84e4884109b9526ac645194ba892a74Michal Krol } 14022861e737e84e4884109b9526ac645194ba892a74Michal Krol else if (instMatch.inputs == INPUT_1S) { 14032861e737e84e4884109b9526ac645194ba892a74Michal Krol if (!Parse_ScalarSrcReg(parseState, &inst->SrcReg[0])) 14042861e737e84e4884109b9526ac645194ba892a74Michal Krol RETURN_ERROR; 14052861e737e84e4884109b9526ac645194ba892a74Michal Krol } 14062861e737e84e4884109b9526ac645194ba892a74Michal Krol else if (instMatch.inputs == INPUT_2S) { 14072861e737e84e4884109b9526ac645194ba892a74Michal Krol if (!Parse_ScalarSrcReg(parseState, &inst->SrcReg[0])) 14082861e737e84e4884109b9526ac645194ba892a74Michal Krol RETURN_ERROR; 14092861e737e84e4884109b9526ac645194ba892a74Michal Krol if (!Parse_String(parseState, ",")) 14102861e737e84e4884109b9526ac645194ba892a74Michal Krol RETURN_ERROR1("Expected ,"); 14112861e737e84e4884109b9526ac645194ba892a74Michal Krol if (!Parse_ScalarSrcReg(parseState, &inst->SrcReg[1])) 14122861e737e84e4884109b9526ac645194ba892a74Michal Krol RETURN_ERROR; 14132861e737e84e4884109b9526ac645194ba892a74Michal Krol } 14142861e737e84e4884109b9526ac645194ba892a74Michal Krol else if (instMatch.inputs == INPUT_CC) { 14152861e737e84e4884109b9526ac645194ba892a74Michal Krol /* XXX to-do */ 14162861e737e84e4884109b9526ac645194ba892a74Michal Krol } 14172861e737e84e4884109b9526ac645194ba892a74Michal Krol else if (instMatch.inputs == INPUT_1V_T) { 14187c26b61f9366a397e353d7b7f1f1d1f6d0dcd0c7Keith Whitwell GLubyte unit, idx; 14192861e737e84e4884109b9526ac645194ba892a74Michal Krol if (!Parse_VectorSrc(parseState, &inst->SrcReg[0])) 14202861e737e84e4884109b9526ac645194ba892a74Michal Krol RETURN_ERROR; 14212861e737e84e4884109b9526ac645194ba892a74Michal Krol if (!Parse_String(parseState, ",")) 14222861e737e84e4884109b9526ac645194ba892a74Michal Krol RETURN_ERROR1("Expected ,"); 14237c26b61f9366a397e353d7b7f1f1d1f6d0dcd0c7Keith Whitwell if (!Parse_TextureImageId(parseState, &unit, &idx)) 14242861e737e84e4884109b9526ac645194ba892a74Michal Krol RETURN_ERROR; 14257c26b61f9366a397e353d7b7f1f1d1f6d0dcd0c7Keith Whitwell inst->TexSrcUnit = unit; 14267e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul inst->TexSrcTarget = idx; 14272861e737e84e4884109b9526ac645194ba892a74Michal Krol } 14282861e737e84e4884109b9526ac645194ba892a74Michal Krol else if (instMatch.inputs == INPUT_3V_T) { 14297c26b61f9366a397e353d7b7f1f1d1f6d0dcd0c7Keith Whitwell GLubyte unit, idx; 14302861e737e84e4884109b9526ac645194ba892a74Michal Krol if (!Parse_VectorSrc(parseState, &inst->SrcReg[0])) 14312861e737e84e4884109b9526ac645194ba892a74Michal Krol RETURN_ERROR; 14322861e737e84e4884109b9526ac645194ba892a74Michal Krol if (!Parse_String(parseState, ",")) 14332861e737e84e4884109b9526ac645194ba892a74Michal Krol RETURN_ERROR1("Expected ,"); 14342861e737e84e4884109b9526ac645194ba892a74Michal Krol if (!Parse_VectorSrc(parseState, &inst->SrcReg[1])) 14352861e737e84e4884109b9526ac645194ba892a74Michal Krol RETURN_ERROR; 14362861e737e84e4884109b9526ac645194ba892a74Michal Krol if (!Parse_String(parseState, ",")) 14372861e737e84e4884109b9526ac645194ba892a74Michal Krol RETURN_ERROR1("Expected ,"); 14382861e737e84e4884109b9526ac645194ba892a74Michal Krol if (!Parse_VectorSrc(parseState, &inst->SrcReg[2])) 14392861e737e84e4884109b9526ac645194ba892a74Michal Krol RETURN_ERROR; 14402861e737e84e4884109b9526ac645194ba892a74Michal Krol if (!Parse_String(parseState, ",")) 14412861e737e84e4884109b9526ac645194ba892a74Michal Krol RETURN_ERROR1("Expected ,"); 14427c26b61f9366a397e353d7b7f1f1d1f6d0dcd0c7Keith Whitwell if (!Parse_TextureImageId(parseState, &unit, &idx)) 14432861e737e84e4884109b9526ac645194ba892a74Michal Krol RETURN_ERROR; 14447c26b61f9366a397e353d7b7f1f1d1f6d0dcd0c7Keith Whitwell inst->TexSrcUnit = unit; 14457e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul inst->TexSrcTarget = idx; 14462861e737e84e4884109b9526ac645194ba892a74Michal Krol } 14472a5afe3ab8d4c3624ed72b99a11b6a9017078d1cBrian Paul else if (instMatch.inputs == INPUT_1V_S) { 14482a5afe3ab8d4c3624ed72b99a11b6a9017078d1cBrian Paul if (!Parse_PrintInstruction(parseState, inst)) 14492a5afe3ab8d4c3624ed72b99a11b6a9017078d1cBrian Paul RETURN_ERROR; 14502a5afe3ab8d4c3624ed72b99a11b6a9017078d1cBrian Paul } 14512861e737e84e4884109b9526ac645194ba892a74Michal Krol 14522861e737e84e4884109b9526ac645194ba892a74Michal Krol /* end of statement semicolon */ 14532861e737e84e4884109b9526ac645194ba892a74Michal Krol if (!Parse_String(parseState, ";")) 14542861e737e84e4884109b9526ac645194ba892a74Michal Krol RETURN_ERROR1("Expected ;"); 14552861e737e84e4884109b9526ac645194ba892a74Michal Krol 14562861e737e84e4884109b9526ac645194ba892a74Michal Krol parseState->numInst++; 14572861e737e84e4884109b9526ac645194ba892a74Michal Krol 14582861e737e84e4884109b9526ac645194ba892a74Michal Krol if (parseState->numInst >= MAX_NV_FRAGMENT_PROGRAM_INSTRUCTIONS) 14592861e737e84e4884109b9526ac645194ba892a74Michal Krol RETURN_ERROR1("Program too long"); 14602861e737e84e4884109b9526ac645194ba892a74Michal Krol } 14612861e737e84e4884109b9526ac645194ba892a74Michal Krol } 14622861e737e84e4884109b9526ac645194ba892a74Michal Krol return GL_TRUE; 14632861e737e84e4884109b9526ac645194ba892a74Michal Krol} 14642861e737e84e4884109b9526ac645194ba892a74Michal Krol 14652861e737e84e4884109b9526ac645194ba892a74Michal Krol 14662861e737e84e4884109b9526ac645194ba892a74Michal Krol 14672861e737e84e4884109b9526ac645194ba892a74Michal Krol/** 14682861e737e84e4884109b9526ac645194ba892a74Michal Krol * Parse/compile the 'str' returning the compiled 'program'. 14692861e737e84e4884109b9526ac645194ba892a74Michal Krol * ctx->Program.ErrorPos will be -1 if successful. Otherwise, ErrorPos 14702861e737e84e4884109b9526ac645194ba892a74Michal Krol * indicates the position of the error in 'str'. 14712861e737e84e4884109b9526ac645194ba892a74Michal Krol */ 14722861e737e84e4884109b9526ac645194ba892a74Michal Krolvoid 1473f9995b30756140724f41daf963fa06167912be7fKristian Høgsberg_mesa_parse_nv_fragment_program(struct gl_context *ctx, GLenum dstTarget, 14742861e737e84e4884109b9526ac645194ba892a74Michal Krol const GLubyte *str, GLsizei len, 1475122629f27925a9dc50029bebc5079f87f416a7e1Brian Paul struct gl_fragment_program *program) 14762861e737e84e4884109b9526ac645194ba892a74Michal Krol{ 14772861e737e84e4884109b9526ac645194ba892a74Michal Krol struct parse_state parseState; 14787e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul struct prog_instruction instBuffer[MAX_NV_FRAGMENT_PROGRAM_INSTRUCTIONS]; 14797e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul struct prog_instruction *newInst; 14802861e737e84e4884109b9526ac645194ba892a74Michal Krol GLenum target; 14812861e737e84e4884109b9526ac645194ba892a74Michal Krol GLubyte *programString; 14822861e737e84e4884109b9526ac645194ba892a74Michal Krol 14832861e737e84e4884109b9526ac645194ba892a74Michal Krol /* Make a null-terminated copy of the program string */ 14842861e737e84e4884109b9526ac645194ba892a74Michal Krol programString = (GLubyte *) MALLOC(len + 1); 14852861e737e84e4884109b9526ac645194ba892a74Michal Krol if (!programString) { 14862861e737e84e4884109b9526ac645194ba892a74Michal Krol _mesa_error(ctx, GL_OUT_OF_MEMORY, "glLoadProgramNV"); 14872861e737e84e4884109b9526ac645194ba892a74Michal Krol return; 14882861e737e84e4884109b9526ac645194ba892a74Michal Krol } 1489e197de56cdb86835f1437688a9161cd909792d80Brian Paul memcpy(programString, str, len); 14902861e737e84e4884109b9526ac645194ba892a74Michal Krol programString[len] = 0; 14912861e737e84e4884109b9526ac645194ba892a74Michal Krol 14922861e737e84e4884109b9526ac645194ba892a74Michal Krol /* Get ready to parse */ 14936bf1ea897fa470af58fe8916dff45e2da79634a3Brian Paul memset(&parseState, 0, sizeof(struct parse_state)); 14942861e737e84e4884109b9526ac645194ba892a74Michal Krol parseState.ctx = ctx; 14952861e737e84e4884109b9526ac645194ba892a74Michal Krol parseState.start = programString; 14962861e737e84e4884109b9526ac645194ba892a74Michal Krol parseState.program = program; 14972861e737e84e4884109b9526ac645194ba892a74Michal Krol parseState.numInst = 0; 14982861e737e84e4884109b9526ac645194ba892a74Michal Krol parseState.curLine = programString; 14992861e737e84e4884109b9526ac645194ba892a74Michal Krol parseState.parameters = _mesa_new_parameter_list(); 15002861e737e84e4884109b9526ac645194ba892a74Michal Krol 15012861e737e84e4884109b9526ac645194ba892a74Michal Krol /* Reset error state */ 15022861e737e84e4884109b9526ac645194ba892a74Michal Krol _mesa_set_program_error(ctx, -1, NULL); 15032861e737e84e4884109b9526ac645194ba892a74Michal Krol 15042861e737e84e4884109b9526ac645194ba892a74Michal Krol /* check the program header */ 15059d9afe9393fde99858ddf40e478bc16cf44e60dcKenneth Graunke if (strncmp((const char *) programString, "!!FP1.0", 7) == 0) { 15062861e737e84e4884109b9526ac645194ba892a74Michal Krol target = GL_FRAGMENT_PROGRAM_NV; 15072861e737e84e4884109b9526ac645194ba892a74Michal Krol parseState.pos = programString + 7; 15082861e737e84e4884109b9526ac645194ba892a74Michal Krol } 15099d9afe9393fde99858ddf40e478bc16cf44e60dcKenneth Graunke else if (strncmp((const char *) programString, "!!FCP1.0", 8) == 0) { 15102861e737e84e4884109b9526ac645194ba892a74Michal Krol /* fragment / register combiner program - not supported */ 15112861e737e84e4884109b9526ac645194ba892a74Michal Krol _mesa_set_program_error(ctx, 0, "Invalid fragment program header"); 15122861e737e84e4884109b9526ac645194ba892a74Michal Krol _mesa_error(ctx, GL_INVALID_OPERATION, "glLoadProgramNV(bad header)"); 15132861e737e84e4884109b9526ac645194ba892a74Michal Krol return; 15142861e737e84e4884109b9526ac645194ba892a74Michal Krol } 15152861e737e84e4884109b9526ac645194ba892a74Michal Krol else { 15162861e737e84e4884109b9526ac645194ba892a74Michal Krol /* invalid header */ 15172861e737e84e4884109b9526ac645194ba892a74Michal Krol _mesa_set_program_error(ctx, 0, "Invalid fragment program header"); 15182861e737e84e4884109b9526ac645194ba892a74Michal Krol _mesa_error(ctx, GL_INVALID_OPERATION, "glLoadProgramNV(bad header)"); 15192861e737e84e4884109b9526ac645194ba892a74Michal Krol return; 15202861e737e84e4884109b9526ac645194ba892a74Michal Krol } 15212861e737e84e4884109b9526ac645194ba892a74Michal Krol 15222861e737e84e4884109b9526ac645194ba892a74Michal Krol /* make sure target and header match */ 15232861e737e84e4884109b9526ac645194ba892a74Michal Krol if (target != dstTarget) { 15242861e737e84e4884109b9526ac645194ba892a74Michal Krol _mesa_error(ctx, GL_INVALID_OPERATION, 15252861e737e84e4884109b9526ac645194ba892a74Michal Krol "glLoadProgramNV(target mismatch 0x%x != 0x%x)", 15262861e737e84e4884109b9526ac645194ba892a74Michal Krol target, dstTarget); 15272861e737e84e4884109b9526ac645194ba892a74Michal Krol return; 15282861e737e84e4884109b9526ac645194ba892a74Michal Krol } 15292861e737e84e4884109b9526ac645194ba892a74Michal Krol 15302861e737e84e4884109b9526ac645194ba892a74Michal Krol if (Parse_InstructionSequence(&parseState, instBuffer)) { 15312861e737e84e4884109b9526ac645194ba892a74Michal Krol GLuint u; 15322861e737e84e4884109b9526ac645194ba892a74Michal Krol /* successful parse! */ 15332861e737e84e4884109b9526ac645194ba892a74Michal Krol 15342861e737e84e4884109b9526ac645194ba892a74Michal Krol if (parseState.outputsWritten == 0) { 15352861e737e84e4884109b9526ac645194ba892a74Michal Krol /* must write at least one output! */ 15362861e737e84e4884109b9526ac645194ba892a74Michal Krol _mesa_error(ctx, GL_INVALID_OPERATION, 15372861e737e84e4884109b9526ac645194ba892a74Michal Krol "Invalid fragment program - no outputs written."); 15382861e737e84e4884109b9526ac645194ba892a74Michal Krol return; 15392861e737e84e4884109b9526ac645194ba892a74Michal Krol } 15402861e737e84e4884109b9526ac645194ba892a74Michal Krol 15412861e737e84e4884109b9526ac645194ba892a74Michal Krol /* copy the compiled instructions */ 15422861e737e84e4884109b9526ac645194ba892a74Michal Krol assert(parseState.numInst <= MAX_NV_FRAGMENT_PROGRAM_INSTRUCTIONS); 1543383c39e58e0ab888afac473526109b62ec0f8f6fBrian Paul newInst = _mesa_alloc_instructions(parseState.numInst); 15442861e737e84e4884109b9526ac645194ba892a74Michal Krol if (!newInst) { 15452861e737e84e4884109b9526ac645194ba892a74Michal Krol _mesa_error(ctx, GL_OUT_OF_MEMORY, "glLoadProgramNV"); 15462861e737e84e4884109b9526ac645194ba892a74Michal Krol return; /* out of memory */ 15472861e737e84e4884109b9526ac645194ba892a74Michal Krol } 154812229f119d754715e0315846fdd8d6e9213e8edfBrian _mesa_copy_instructions(newInst, instBuffer, parseState.numInst); 15492861e737e84e4884109b9526ac645194ba892a74Michal Krol 15502861e737e84e4884109b9526ac645194ba892a74Michal Krol /* install the program */ 15512861e737e84e4884109b9526ac645194ba892a74Michal Krol program->Base.Target = target; 15522861e737e84e4884109b9526ac645194ba892a74Michal Krol if (program->Base.String) { 15532861e737e84e4884109b9526ac645194ba892a74Michal Krol FREE(program->Base.String); 15542861e737e84e4884109b9526ac645194ba892a74Michal Krol } 15552861e737e84e4884109b9526ac645194ba892a74Michal Krol program->Base.String = programString; 15562861e737e84e4884109b9526ac645194ba892a74Michal Krol program->Base.Format = GL_PROGRAM_FORMAT_ASCII_ARB; 1557de99760bf3511d05185799c4fb4347f9e5f420f4Brian Paul if (program->Base.Instructions) { 155832f2fd1c5d6088692551c80352b7d6fa35b0cd09Kristian Høgsberg free(program->Base.Instructions); 15592861e737e84e4884109b9526ac645194ba892a74Michal Krol } 1560de99760bf3511d05185799c4fb4347f9e5f420f4Brian Paul program->Base.Instructions = newInst; 1561ee40c4fb34bd06ecc6dd6f2e658ca2c2c20af952Brian Paul program->Base.NumInstructions = parseState.numInst; 1562de99760bf3511d05185799c4fb4347f9e5f420f4Brian Paul program->Base.InputsRead = parseState.inputsRead; 1563de99760bf3511d05185799c4fb4347f9e5f420f4Brian Paul program->Base.OutputsWritten = parseState.outputsWritten; 15642861e737e84e4884109b9526ac645194ba892a74Michal Krol for (u = 0; u < ctx->Const.MaxTextureImageUnits; u++) 1565c9db223f902ce9d7e9f3038e6baac6da7f231b34Brian program->Base.TexturesUsed[u] = parseState.texturesUsed[u]; 15662861e737e84e4884109b9526ac645194ba892a74Michal Krol 15672861e737e84e4884109b9526ac645194ba892a74Michal Krol /* save program parameters */ 1568de99760bf3511d05185799c4fb4347f9e5f420f4Brian Paul program->Base.Parameters = parseState.parameters; 15692861e737e84e4884109b9526ac645194ba892a74Michal Krol 15702861e737e84e4884109b9526ac645194ba892a74Michal Krol /* allocate registers for declared program parameters */ 15712861e737e84e4884109b9526ac645194ba892a74Michal Krol#if 00 15722861e737e84e4884109b9526ac645194ba892a74Michal Krol _mesa_assign_program_registers(&(program->SymbolTable)); 15732861e737e84e4884109b9526ac645194ba892a74Michal Krol#endif 15742861e737e84e4884109b9526ac645194ba892a74Michal Krol 1575ac33dd1312530e0bab0c7e5d25c9d70f4e884753Brian Paul#ifdef DEBUG_foo 1576298be2b028263b2c343a707662c6fbfa18293cb2Kristian Høgsberg printf("--- glLoadProgramNV(%d) result ---\n", program->Base.Id); 1577fe278f1e600058af18c6ba5fe77bfc5a772bf9f5Brian Paul _mesa_fprint_program_opt(stdout, &program->Base, PROG_PRINT_NV, 0); 1578298be2b028263b2c343a707662c6fbfa18293cb2Kristian Høgsberg printf("----------------------------------\n"); 15792861e737e84e4884109b9526ac645194ba892a74Michal Krol#endif 15802861e737e84e4884109b9526ac645194ba892a74Michal Krol } 15812861e737e84e4884109b9526ac645194ba892a74Michal Krol else { 15822861e737e84e4884109b9526ac645194ba892a74Michal Krol /* Error! */ 15832861e737e84e4884109b9526ac645194ba892a74Michal Krol _mesa_error(ctx, GL_INVALID_OPERATION, "glLoadProgramNV"); 15842861e737e84e4884109b9526ac645194ba892a74Michal Krol /* NOTE: _mesa_set_program_error would have been called already */ 15852861e737e84e4884109b9526ac645194ba892a74Michal Krol } 15862861e737e84e4884109b9526ac645194ba892a74Michal Krol} 15872861e737e84e4884109b9526ac645194ba892a74Michal Krol 15882861e737e84e4884109b9526ac645194ba892a74Michal Krol 15892861e737e84e4884109b9526ac645194ba892a74Michal Krolconst char * 15902861e737e84e4884109b9526ac645194ba892a74Michal Krol_mesa_nv_fragment_input_register_name(GLuint i) 15912861e737e84e4884109b9526ac645194ba892a74Michal Krol{ 15922861e737e84e4884109b9526ac645194ba892a74Michal Krol ASSERT(i < MAX_NV_FRAGMENT_PROGRAM_INPUTS); 15932861e737e84e4884109b9526ac645194ba892a74Michal Krol return InputRegisters[i]; 15942861e737e84e4884109b9526ac645194ba892a74Michal Krol} 15952861e737e84e4884109b9526ac645194ba892a74Michal Krol 1596