nvfragparse.c revision c9db223f902ce9d7e9f3038e6baac6da7f231b34
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 402861e737e84e4884109b9526ac645194ba892a74Michal Krol#include "glheader.h" 412861e737e84e4884109b9526ac645194ba892a74Michal Krol#include "context.h" 422861e737e84e4884109b9526ac645194ba892a74Michal Krol#include "imports.h" 432861e737e84e4884109b9526ac645194ba892a74Michal Krol#include "macros.h" 44c0551f0a465b577a17698ede46370a17e29b3df7Brian#include "prog_parameter.h" 45c0551f0a465b577a17698ede46370a17e29b3df7Brian#include "prog_instruction.h" 462861e737e84e4884109b9526ac645194ba892a74Michal Krol#include "nvfragparse.h" 472861e737e84e4884109b9526ac645194ba892a74Michal Krol#include "program.h" 482861e737e84e4884109b9526ac645194ba892a74Michal Krol 492861e737e84e4884109b9526ac645194ba892a74Michal Krol 502861e737e84e4884109b9526ac645194ba892a74Michal Krol#define INPUT_1V 1 512861e737e84e4884109b9526ac645194ba892a74Michal Krol#define INPUT_2V 2 522861e737e84e4884109b9526ac645194ba892a74Michal Krol#define INPUT_3V 3 532861e737e84e4884109b9526ac645194ba892a74Michal Krol#define INPUT_1S 4 542861e737e84e4884109b9526ac645194ba892a74Michal Krol#define INPUT_2S 5 552861e737e84e4884109b9526ac645194ba892a74Michal Krol#define INPUT_CC 6 562861e737e84e4884109b9526ac645194ba892a74Michal Krol#define INPUT_1V_T 7 /* one source vector, plus textureId */ 572861e737e84e4884109b9526ac645194ba892a74Michal Krol#define INPUT_3V_T 8 /* one source vector, plus textureId */ 582861e737e84e4884109b9526ac645194ba892a74Michal Krol#define INPUT_NONE 9 592a5afe3ab8d4c3624ed72b99a11b6a9017078d1cBrian Paul#define INPUT_1V_S 10 /* a string and a vector register */ 602861e737e84e4884109b9526ac645194ba892a74Michal Krol#define OUTPUT_V 20 612861e737e84e4884109b9526ac645194ba892a74Michal Krol#define OUTPUT_S 21 622861e737e84e4884109b9526ac645194ba892a74Michal Krol#define OUTPUT_NONE 22 632861e737e84e4884109b9526ac645194ba892a74Michal Krol 642861e737e84e4884109b9526ac645194ba892a74Michal Krol/* IRIX defines some of these */ 652861e737e84e4884109b9526ac645194ba892a74Michal Krol#undef _R 662861e737e84e4884109b9526ac645194ba892a74Michal Krol#undef _H 672861e737e84e4884109b9526ac645194ba892a74Michal Krol#undef _X 682861e737e84e4884109b9526ac645194ba892a74Michal Krol#undef _C 692861e737e84e4884109b9526ac645194ba892a74Michal Krol#undef _S 702861e737e84e4884109b9526ac645194ba892a74Michal Krol 712861e737e84e4884109b9526ac645194ba892a74Michal Krol/* Optional suffixes */ 722861e737e84e4884109b9526ac645194ba892a74Michal Krol#define _R FLOAT32 /* float */ 732861e737e84e4884109b9526ac645194ba892a74Michal Krol#define _H FLOAT16 /* half-float */ 742861e737e84e4884109b9526ac645194ba892a74Michal Krol#define _X FIXED12 /* fixed */ 752861e737e84e4884109b9526ac645194ba892a74Michal Krol#define _C 0x08 /* set cond codes */ 762861e737e84e4884109b9526ac645194ba892a74Michal Krol#define _S 0x10 /* saturate, clamp result to [0,1] */ 772861e737e84e4884109b9526ac645194ba892a74Michal Krol 782861e737e84e4884109b9526ac645194ba892a74Michal Krolstruct instruction_pattern { 792861e737e84e4884109b9526ac645194ba892a74Michal Krol const char *name; 807e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul enum prog_opcode opcode; 812861e737e84e4884109b9526ac645194ba892a74Michal Krol GLuint inputs; 822861e737e84e4884109b9526ac645194ba892a74Michal Krol GLuint outputs; 832861e737e84e4884109b9526ac645194ba892a74Michal Krol GLuint suffixes; 842861e737e84e4884109b9526ac645194ba892a74Michal Krol}; 852861e737e84e4884109b9526ac645194ba892a74Michal Krol 862861e737e84e4884109b9526ac645194ba892a74Michal Krolstatic const struct instruction_pattern Instructions[] = { 877e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul { "ADD", OPCODE_ADD, INPUT_2V, OUTPUT_V, _R | _H | _X | _C | _S }, 887e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul { "COS", OPCODE_COS, INPUT_1S, OUTPUT_S, _R | _H | _C | _S }, 897e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul { "DDX", OPCODE_DDX, INPUT_1V, OUTPUT_V, _R | _H | _C | _S }, 907e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul { "DDY", OPCODE_DDY, INPUT_1V, OUTPUT_V, _R | _H | _C | _S }, 917e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul { "DP3", OPCODE_DP3, INPUT_2V, OUTPUT_S, _R | _H | _X | _C | _S }, 927e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul { "DP4", OPCODE_DP4, INPUT_2V, OUTPUT_S, _R | _H | _X | _C | _S }, 937e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul { "DST", OPCODE_DP4, INPUT_2V, OUTPUT_V, _R | _H | _C | _S }, 947e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul { "EX2", OPCODE_DP4, INPUT_1S, OUTPUT_S, _R | _H | _C | _S }, 957e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul { "FLR", OPCODE_FLR, INPUT_1V, OUTPUT_V, _R | _H | _X | _C | _S }, 967e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul { "FRC", OPCODE_FRC, INPUT_1V, OUTPUT_V, _R | _H | _X | _C | _S }, 977e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul { "KIL", OPCODE_KIL_NV, INPUT_CC, OUTPUT_NONE, 0 }, 987e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul { "LG2", OPCODE_LG2, INPUT_1S, OUTPUT_S, _R | _H | _C | _S }, 997e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul { "LIT", OPCODE_LIT, INPUT_1V, OUTPUT_V, _R | _H | _C | _S }, 1007e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul { "LRP", OPCODE_LRP, INPUT_3V, OUTPUT_V, _R | _H | _X | _C | _S }, 1017e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul { "MAD", OPCODE_MAD, INPUT_3V, OUTPUT_V, _R | _H | _X | _C | _S }, 1027e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul { "MAX", OPCODE_MAX, INPUT_2V, OUTPUT_V, _R | _H | _X | _C | _S }, 1037e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul { "MIN", OPCODE_MIN, INPUT_2V, OUTPUT_V, _R | _H | _X | _C | _S }, 1047e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul { "MOV", OPCODE_MOV, INPUT_1V, OUTPUT_V, _R | _H | _X | _C | _S }, 1057e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul { "MUL", OPCODE_MUL, INPUT_2V, OUTPUT_V, _R | _H | _X | _C | _S }, 1067e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul { "PK2H", OPCODE_PK2H, INPUT_1V, OUTPUT_S, 0 }, 1077e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul { "PK2US", OPCODE_PK2US, INPUT_1V, OUTPUT_S, 0 }, 1087e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul { "PK4B", OPCODE_PK4B, INPUT_1V, OUTPUT_S, 0 }, 1097e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul { "PK4UB", OPCODE_PK4UB, INPUT_1V, OUTPUT_S, 0 }, 1107e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul { "POW", OPCODE_POW, INPUT_2S, OUTPUT_S, _R | _H | _C | _S }, 1117e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul { "RCP", OPCODE_RCP, INPUT_1S, OUTPUT_S, _R | _H | _C | _S }, 1127e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul { "RFL", OPCODE_RFL, INPUT_2V, OUTPUT_V, _R | _H | _C | _S }, 1137e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul { "RSQ", OPCODE_RSQ, INPUT_1S, OUTPUT_S, _R | _H | _C | _S }, 1147e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul { "SEQ", OPCODE_SEQ, INPUT_2V, OUTPUT_V, _R | _H | _X | _C | _S }, 1157e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul { "SFL", OPCODE_SFL, INPUT_2V, OUTPUT_V, _R | _H | _X | _C | _S }, 1167e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul { "SGE", OPCODE_SGE, INPUT_2V, OUTPUT_V, _R | _H | _X | _C | _S }, 1177e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul { "SGT", OPCODE_SGT, INPUT_2V, OUTPUT_V, _R | _H | _X | _C | _S }, 1187e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul { "SIN", OPCODE_SIN, INPUT_1S, OUTPUT_S, _R | _H | _C | _S }, 1197e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul { "SLE", OPCODE_SLE, INPUT_2V, OUTPUT_V, _R | _H | _X | _C | _S }, 1207e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul { "SLT", OPCODE_SLT, INPUT_2V, OUTPUT_V, _R | _H | _X | _C | _S }, 1217e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul { "SNE", OPCODE_SNE, INPUT_2V, OUTPUT_V, _R | _H | _X | _C | _S }, 1227e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul { "STR", OPCODE_STR, INPUT_2V, OUTPUT_V, _R | _H | _X | _C | _S }, 1237e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul { "SUB", OPCODE_SUB, INPUT_2V, OUTPUT_V, _R | _H | _X | _C | _S }, 1247e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul { "TEX", OPCODE_TEX, INPUT_1V_T, OUTPUT_V, _C | _S }, 1257e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul { "TXD", OPCODE_TXD, INPUT_3V_T, OUTPUT_V, _C | _S }, 1267e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul { "TXP", OPCODE_TXP_NV, INPUT_1V_T, OUTPUT_V, _C | _S }, 1277e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul { "UP2H", OPCODE_UP2H, INPUT_1S, OUTPUT_V, _C | _S }, 1287e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul { "UP2US", OPCODE_UP2US, INPUT_1S, OUTPUT_V, _C | _S }, 1297e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul { "UP4B", OPCODE_UP4B, INPUT_1S, OUTPUT_V, _C | _S }, 1307e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul { "UP4UB", OPCODE_UP4UB, INPUT_1S, OUTPUT_V, _C | _S }, 1317e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul { "X2D", OPCODE_X2D, INPUT_3V, OUTPUT_V, _R | _H | _C | _S }, 1327e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul { "PRINT", OPCODE_PRINT, INPUT_1V_S, OUTPUT_NONE, 0 }, 1337e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul { NULL, (enum prog_opcode) -1, 0, 0, 0 } 1342861e737e84e4884109b9526ac645194ba892a74Michal Krol}; 1352861e737e84e4884109b9526ac645194ba892a74Michal Krol 1362861e737e84e4884109b9526ac645194ba892a74Michal Krol 1372861e737e84e4884109b9526ac645194ba892a74Michal Krol/* 1382861e737e84e4884109b9526ac645194ba892a74Michal Krol * Information needed or computed during parsing. 1392861e737e84e4884109b9526ac645194ba892a74Michal Krol * Remember, we can't modify the target program object until we've 1402861e737e84e4884109b9526ac645194ba892a74Michal Krol * _successfully_ parsed the program text. 1412861e737e84e4884109b9526ac645194ba892a74Michal Krol */ 1422861e737e84e4884109b9526ac645194ba892a74Michal Krolstruct parse_state { 1432861e737e84e4884109b9526ac645194ba892a74Michal Krol GLcontext *ctx; 1442861e737e84e4884109b9526ac645194ba892a74Michal Krol const GLubyte *start; /* start of program string */ 1452861e737e84e4884109b9526ac645194ba892a74Michal Krol const GLubyte *pos; /* current position */ 1462861e737e84e4884109b9526ac645194ba892a74Michal Krol const GLubyte *curLine; 147122629f27925a9dc50029bebc5079f87f416a7e1Brian Paul struct gl_fragment_program *program; /* current program */ 1482861e737e84e4884109b9526ac645194ba892a74Michal Krol 149122629f27925a9dc50029bebc5079f87f416a7e1Brian Paul struct gl_program_parameter_list *parameters; 1502861e737e84e4884109b9526ac645194ba892a74Michal Krol 1512861e737e84e4884109b9526ac645194ba892a74Michal Krol GLuint numInst; /* number of instructions parsed */ 1522861e737e84e4884109b9526ac645194ba892a74Michal Krol GLuint inputsRead; /* bitmask of input registers used */ 1532861e737e84e4884109b9526ac645194ba892a74Michal Krol GLuint outputsWritten; /* bitmask of 1 << FRAG_OUTPUT_* bits */ 1542861e737e84e4884109b9526ac645194ba892a74Michal Krol GLuint texturesUsed[MAX_TEXTURE_IMAGE_UNITS]; 1552861e737e84e4884109b9526ac645194ba892a74Michal Krol}; 1562861e737e84e4884109b9526ac645194ba892a74Michal Krol 1572861e737e84e4884109b9526ac645194ba892a74Michal Krol 1582861e737e84e4884109b9526ac645194ba892a74Michal Krol 1592861e737e84e4884109b9526ac645194ba892a74Michal Krol/* 1602861e737e84e4884109b9526ac645194ba892a74Michal Krol * Called whenever we find an error during parsing. 1612861e737e84e4884109b9526ac645194ba892a74Michal Krol */ 1622861e737e84e4884109b9526ac645194ba892a74Michal Krolstatic void 1632861e737e84e4884109b9526ac645194ba892a74Michal Krolrecord_error(struct parse_state *parseState, const char *msg, int lineNo) 1642861e737e84e4884109b9526ac645194ba892a74Michal Krol{ 1652861e737e84e4884109b9526ac645194ba892a74Michal Krol#ifdef DEBUG 1662861e737e84e4884109b9526ac645194ba892a74Michal Krol GLint line, column; 1672861e737e84e4884109b9526ac645194ba892a74Michal Krol const GLubyte *lineStr; 1682861e737e84e4884109b9526ac645194ba892a74Michal Krol lineStr = _mesa_find_line_column(parseState->start, 1692861e737e84e4884109b9526ac645194ba892a74Michal Krol parseState->pos, &line, &column); 1702861e737e84e4884109b9526ac645194ba892a74Michal Krol _mesa_debug(parseState->ctx, 1712861e737e84e4884109b9526ac645194ba892a74Michal Krol "nvfragparse.c(%d): line %d, column %d:%s (%s)\n", 1722861e737e84e4884109b9526ac645194ba892a74Michal Krol lineNo, line, column, (char *) lineStr, msg); 1732861e737e84e4884109b9526ac645194ba892a74Michal Krol _mesa_free((void *) lineStr); 1742861e737e84e4884109b9526ac645194ba892a74Michal Krol#else 1752861e737e84e4884109b9526ac645194ba892a74Michal Krol (void) lineNo; 1762861e737e84e4884109b9526ac645194ba892a74Michal Krol#endif 1772861e737e84e4884109b9526ac645194ba892a74Michal Krol 1782861e737e84e4884109b9526ac645194ba892a74Michal Krol /* Check that no error was already recorded. Only record the first one. */ 1792861e737e84e4884109b9526ac645194ba892a74Michal Krol if (parseState->ctx->Program.ErrorString[0] == 0) { 1802861e737e84e4884109b9526ac645194ba892a74Michal Krol _mesa_set_program_error(parseState->ctx, 1812861e737e84e4884109b9526ac645194ba892a74Michal Krol parseState->pos - parseState->start, 1822861e737e84e4884109b9526ac645194ba892a74Michal Krol msg); 1832861e737e84e4884109b9526ac645194ba892a74Michal Krol } 1842861e737e84e4884109b9526ac645194ba892a74Michal Krol} 1852861e737e84e4884109b9526ac645194ba892a74Michal Krol 1862861e737e84e4884109b9526ac645194ba892a74Michal Krol 1872861e737e84e4884109b9526ac645194ba892a74Michal Krol#define RETURN_ERROR \ 1882861e737e84e4884109b9526ac645194ba892a74Michal Kroldo { \ 1892861e737e84e4884109b9526ac645194ba892a74Michal Krol record_error(parseState, "Unexpected end of input.", __LINE__); \ 1902861e737e84e4884109b9526ac645194ba892a74Michal Krol return GL_FALSE; \ 1912861e737e84e4884109b9526ac645194ba892a74Michal Krol} while(0) 1922861e737e84e4884109b9526ac645194ba892a74Michal Krol 1932861e737e84e4884109b9526ac645194ba892a74Michal Krol#define RETURN_ERROR1(msg) \ 1942861e737e84e4884109b9526ac645194ba892a74Michal Kroldo { \ 1952861e737e84e4884109b9526ac645194ba892a74Michal Krol record_error(parseState, msg, __LINE__); \ 1962861e737e84e4884109b9526ac645194ba892a74Michal Krol return GL_FALSE; \ 1972861e737e84e4884109b9526ac645194ba892a74Michal Krol} while(0) 1982861e737e84e4884109b9526ac645194ba892a74Michal Krol 1992861e737e84e4884109b9526ac645194ba892a74Michal Krol#define RETURN_ERROR2(msg1, msg2) \ 2002861e737e84e4884109b9526ac645194ba892a74Michal Kroldo { \ 2012861e737e84e4884109b9526ac645194ba892a74Michal Krol char err[1000]; \ 2022861e737e84e4884109b9526ac645194ba892a74Michal Krol _mesa_sprintf(err, "%s %s", msg1, msg2); \ 2032861e737e84e4884109b9526ac645194ba892a74Michal Krol record_error(parseState, err, __LINE__); \ 2042861e737e84e4884109b9526ac645194ba892a74Michal Krol return GL_FALSE; \ 2052861e737e84e4884109b9526ac645194ba892a74Michal Krol} while(0) 2062861e737e84e4884109b9526ac645194ba892a74Michal Krol 2072861e737e84e4884109b9526ac645194ba892a74Michal Krol 2082861e737e84e4884109b9526ac645194ba892a74Michal Krol 2092861e737e84e4884109b9526ac645194ba892a74Michal Krol 2102861e737e84e4884109b9526ac645194ba892a74Michal Krol/* 2112861e737e84e4884109b9526ac645194ba892a74Michal Krol * Search a list of instruction structures for a match. 2122861e737e84e4884109b9526ac645194ba892a74Michal Krol */ 2132861e737e84e4884109b9526ac645194ba892a74Michal Krolstatic struct instruction_pattern 2142861e737e84e4884109b9526ac645194ba892a74Michal KrolMatchInstruction(const GLubyte *token) 2152861e737e84e4884109b9526ac645194ba892a74Michal Krol{ 2162861e737e84e4884109b9526ac645194ba892a74Michal Krol const struct instruction_pattern *inst; 2172861e737e84e4884109b9526ac645194ba892a74Michal Krol struct instruction_pattern result; 2182861e737e84e4884109b9526ac645194ba892a74Michal Krol 2192861e737e84e4884109b9526ac645194ba892a74Michal Krol for (inst = Instructions; inst->name; inst++) { 2202861e737e84e4884109b9526ac645194ba892a74Michal Krol if (_mesa_strncmp((const char *) token, inst->name, 3) == 0) { 2212861e737e84e4884109b9526ac645194ba892a74Michal Krol /* matched! */ 2222861e737e84e4884109b9526ac645194ba892a74Michal Krol int i = 3; 2232861e737e84e4884109b9526ac645194ba892a74Michal Krol result = *inst; 2242861e737e84e4884109b9526ac645194ba892a74Michal Krol result.suffixes = 0; 2252861e737e84e4884109b9526ac645194ba892a74Michal Krol /* look at suffix */ 2262861e737e84e4884109b9526ac645194ba892a74Michal Krol if (token[i] == 'R') { 2272861e737e84e4884109b9526ac645194ba892a74Michal Krol result.suffixes |= _R; 2282861e737e84e4884109b9526ac645194ba892a74Michal Krol i++; 2292861e737e84e4884109b9526ac645194ba892a74Michal Krol } 2302861e737e84e4884109b9526ac645194ba892a74Michal Krol else if (token[i] == 'H') { 2312861e737e84e4884109b9526ac645194ba892a74Michal Krol result.suffixes |= _H; 2322861e737e84e4884109b9526ac645194ba892a74Michal Krol i++; 2332861e737e84e4884109b9526ac645194ba892a74Michal Krol } 2342861e737e84e4884109b9526ac645194ba892a74Michal Krol else if (token[i] == 'X') { 2352861e737e84e4884109b9526ac645194ba892a74Michal Krol result.suffixes |= _X; 2362861e737e84e4884109b9526ac645194ba892a74Michal Krol i++; 2372861e737e84e4884109b9526ac645194ba892a74Michal Krol } 2382861e737e84e4884109b9526ac645194ba892a74Michal Krol if (token[i] == 'C') { 2392861e737e84e4884109b9526ac645194ba892a74Michal Krol result.suffixes |= _C; 2402861e737e84e4884109b9526ac645194ba892a74Michal Krol i++; 2412861e737e84e4884109b9526ac645194ba892a74Michal Krol } 2422861e737e84e4884109b9526ac645194ba892a74Michal Krol if (token[i] == '_' && token[i+1] == 'S' && 2432861e737e84e4884109b9526ac645194ba892a74Michal Krol token[i+2] == 'A' && token[i+3] == 'T') { 2442861e737e84e4884109b9526ac645194ba892a74Michal Krol result.suffixes |= _S; 2452861e737e84e4884109b9526ac645194ba892a74Michal Krol } 2462861e737e84e4884109b9526ac645194ba892a74Michal Krol return result; 2472861e737e84e4884109b9526ac645194ba892a74Michal Krol } 2482861e737e84e4884109b9526ac645194ba892a74Michal Krol } 24928b014ee256290eb0494b967e40c475c0c895f57Brian Paul result.opcode = MAX_OPCODE; /* i.e. invalid instruction */ 2502861e737e84e4884109b9526ac645194ba892a74Michal Krol return result; 2512861e737e84e4884109b9526ac645194ba892a74Michal Krol} 2522861e737e84e4884109b9526ac645194ba892a74Michal Krol 2532861e737e84e4884109b9526ac645194ba892a74Michal Krol 2542861e737e84e4884109b9526ac645194ba892a74Michal Krol 2552861e737e84e4884109b9526ac645194ba892a74Michal Krol 2562861e737e84e4884109b9526ac645194ba892a74Michal Krol/**********************************************************************/ 2572861e737e84e4884109b9526ac645194ba892a74Michal Krol 2582861e737e84e4884109b9526ac645194ba892a74Michal Krol 2592861e737e84e4884109b9526ac645194ba892a74Michal Krolstatic GLboolean IsLetter(GLubyte b) 2602861e737e84e4884109b9526ac645194ba892a74Michal Krol{ 2612861e737e84e4884109b9526ac645194ba892a74Michal Krol return (b >= 'a' && b <= 'z') || 2622861e737e84e4884109b9526ac645194ba892a74Michal Krol (b >= 'A' && b <= 'Z') || 2632861e737e84e4884109b9526ac645194ba892a74Michal Krol (b == '_') || 2642861e737e84e4884109b9526ac645194ba892a74Michal Krol (b == '$'); 2652861e737e84e4884109b9526ac645194ba892a74Michal Krol} 2662861e737e84e4884109b9526ac645194ba892a74Michal Krol 2672861e737e84e4884109b9526ac645194ba892a74Michal Krol 2682861e737e84e4884109b9526ac645194ba892a74Michal Krolstatic GLboolean IsDigit(GLubyte b) 2692861e737e84e4884109b9526ac645194ba892a74Michal Krol{ 2702861e737e84e4884109b9526ac645194ba892a74Michal Krol return b >= '0' && b <= '9'; 2712861e737e84e4884109b9526ac645194ba892a74Michal Krol} 2722861e737e84e4884109b9526ac645194ba892a74Michal Krol 2732861e737e84e4884109b9526ac645194ba892a74Michal Krol 2742861e737e84e4884109b9526ac645194ba892a74Michal Krolstatic GLboolean IsWhitespace(GLubyte b) 2752861e737e84e4884109b9526ac645194ba892a74Michal Krol{ 2762861e737e84e4884109b9526ac645194ba892a74Michal Krol return b == ' ' || b == '\t' || b == '\n' || b == '\r'; 2772861e737e84e4884109b9526ac645194ba892a74Michal Krol} 2782861e737e84e4884109b9526ac645194ba892a74Michal Krol 2792861e737e84e4884109b9526ac645194ba892a74Michal Krol 2802861e737e84e4884109b9526ac645194ba892a74Michal Krol/** 2812861e737e84e4884109b9526ac645194ba892a74Michal Krol * Starting at 'str' find the next token. A token can be an integer, 2822861e737e84e4884109b9526ac645194ba892a74Michal Krol * an identifier or punctuation symbol. 2832861e737e84e4884109b9526ac645194ba892a74Michal Krol * \return <= 0 we found an error, else, return number of characters parsed. 2842861e737e84e4884109b9526ac645194ba892a74Michal Krol */ 2852861e737e84e4884109b9526ac645194ba892a74Michal Krolstatic GLint 2862861e737e84e4884109b9526ac645194ba892a74Michal KrolGetToken(struct parse_state *parseState, GLubyte *token) 2872861e737e84e4884109b9526ac645194ba892a74Michal Krol{ 2882861e737e84e4884109b9526ac645194ba892a74Michal Krol const GLubyte *str = parseState->pos; 2892861e737e84e4884109b9526ac645194ba892a74Michal Krol GLint i = 0, j = 0; 2902861e737e84e4884109b9526ac645194ba892a74Michal Krol 2912861e737e84e4884109b9526ac645194ba892a74Michal Krol token[0] = 0; 2922861e737e84e4884109b9526ac645194ba892a74Michal Krol 2932861e737e84e4884109b9526ac645194ba892a74Michal Krol /* skip whitespace and comments */ 2942861e737e84e4884109b9526ac645194ba892a74Michal Krol while (str[i] && (IsWhitespace(str[i]) || str[i] == '#')) { 2952861e737e84e4884109b9526ac645194ba892a74Michal Krol if (str[i] == '#') { 2962861e737e84e4884109b9526ac645194ba892a74Michal Krol /* skip comment */ 2972861e737e84e4884109b9526ac645194ba892a74Michal Krol while (str[i] && (str[i] != '\n' && str[i] != '\r')) { 2982861e737e84e4884109b9526ac645194ba892a74Michal Krol i++; 2992861e737e84e4884109b9526ac645194ba892a74Michal Krol } 3002861e737e84e4884109b9526ac645194ba892a74Michal Krol if (str[i] == '\n' || str[i] == '\r') 3012861e737e84e4884109b9526ac645194ba892a74Michal Krol parseState->curLine = str + i + 1; 3022861e737e84e4884109b9526ac645194ba892a74Michal Krol } 3032861e737e84e4884109b9526ac645194ba892a74Michal Krol else { 3042861e737e84e4884109b9526ac645194ba892a74Michal Krol /* skip whitespace */ 3052861e737e84e4884109b9526ac645194ba892a74Michal Krol if (str[i] == '\n' || str[i] == '\r') 3062861e737e84e4884109b9526ac645194ba892a74Michal Krol parseState->curLine = str + i + 1; 3072861e737e84e4884109b9526ac645194ba892a74Michal Krol i++; 3082861e737e84e4884109b9526ac645194ba892a74Michal Krol } 3092861e737e84e4884109b9526ac645194ba892a74Michal Krol } 3102861e737e84e4884109b9526ac645194ba892a74Michal Krol 3112861e737e84e4884109b9526ac645194ba892a74Michal Krol if (str[i] == 0) 3122861e737e84e4884109b9526ac645194ba892a74Michal Krol return -i; 3132861e737e84e4884109b9526ac645194ba892a74Michal Krol 3142861e737e84e4884109b9526ac645194ba892a74Michal Krol /* try matching an integer */ 3152861e737e84e4884109b9526ac645194ba892a74Michal Krol while (str[i] && IsDigit(str[i])) { 3162861e737e84e4884109b9526ac645194ba892a74Michal Krol token[j++] = str[i++]; 3172861e737e84e4884109b9526ac645194ba892a74Michal Krol } 3182861e737e84e4884109b9526ac645194ba892a74Michal Krol if (j > 0 || !str[i]) { 3192861e737e84e4884109b9526ac645194ba892a74Michal Krol token[j] = 0; 3202861e737e84e4884109b9526ac645194ba892a74Michal Krol return i; 3212861e737e84e4884109b9526ac645194ba892a74Michal Krol } 3222861e737e84e4884109b9526ac645194ba892a74Michal Krol 3232861e737e84e4884109b9526ac645194ba892a74Michal Krol /* try matching an identifier */ 3242861e737e84e4884109b9526ac645194ba892a74Michal Krol if (IsLetter(str[i])) { 3252861e737e84e4884109b9526ac645194ba892a74Michal Krol while (str[i] && (IsLetter(str[i]) || IsDigit(str[i]))) { 3262861e737e84e4884109b9526ac645194ba892a74Michal Krol token[j++] = str[i++]; 3272861e737e84e4884109b9526ac645194ba892a74Michal Krol } 3282861e737e84e4884109b9526ac645194ba892a74Michal Krol token[j] = 0; 3292861e737e84e4884109b9526ac645194ba892a74Michal Krol return i; 3302861e737e84e4884109b9526ac645194ba892a74Michal Krol } 3312861e737e84e4884109b9526ac645194ba892a74Michal Krol 3322861e737e84e4884109b9526ac645194ba892a74Michal Krol /* punctuation character */ 3332861e737e84e4884109b9526ac645194ba892a74Michal Krol if (str[i]) { 3342861e737e84e4884109b9526ac645194ba892a74Michal Krol token[0] = str[i++]; 3352861e737e84e4884109b9526ac645194ba892a74Michal Krol token[1] = 0; 3362861e737e84e4884109b9526ac645194ba892a74Michal Krol return i; 3372861e737e84e4884109b9526ac645194ba892a74Michal Krol } 3382861e737e84e4884109b9526ac645194ba892a74Michal Krol 3392861e737e84e4884109b9526ac645194ba892a74Michal Krol /* end of input */ 3402861e737e84e4884109b9526ac645194ba892a74Michal Krol token[0] = 0; 3412861e737e84e4884109b9526ac645194ba892a74Michal Krol return i; 3422861e737e84e4884109b9526ac645194ba892a74Michal Krol} 3432861e737e84e4884109b9526ac645194ba892a74Michal Krol 3442861e737e84e4884109b9526ac645194ba892a74Michal Krol 3452861e737e84e4884109b9526ac645194ba892a74Michal Krol/** 3462861e737e84e4884109b9526ac645194ba892a74Michal Krol * Get next token from input stream and increment stream pointer past token. 3472861e737e84e4884109b9526ac645194ba892a74Michal Krol */ 3482861e737e84e4884109b9526ac645194ba892a74Michal Krolstatic GLboolean 3492861e737e84e4884109b9526ac645194ba892a74Michal KrolParse_Token(struct parse_state *parseState, GLubyte *token) 3502861e737e84e4884109b9526ac645194ba892a74Michal Krol{ 3512861e737e84e4884109b9526ac645194ba892a74Michal Krol GLint i; 3522861e737e84e4884109b9526ac645194ba892a74Michal Krol i = GetToken(parseState, token); 3532861e737e84e4884109b9526ac645194ba892a74Michal Krol if (i <= 0) { 3542861e737e84e4884109b9526ac645194ba892a74Michal Krol parseState->pos += (-i); 3552861e737e84e4884109b9526ac645194ba892a74Michal Krol return GL_FALSE; 3562861e737e84e4884109b9526ac645194ba892a74Michal Krol } 3572861e737e84e4884109b9526ac645194ba892a74Michal Krol parseState->pos += i; 3582861e737e84e4884109b9526ac645194ba892a74Michal Krol return GL_TRUE; 3592861e737e84e4884109b9526ac645194ba892a74Michal Krol} 3602861e737e84e4884109b9526ac645194ba892a74Michal Krol 3612861e737e84e4884109b9526ac645194ba892a74Michal Krol 3622861e737e84e4884109b9526ac645194ba892a74Michal Krol/** 3632861e737e84e4884109b9526ac645194ba892a74Michal Krol * Get next token from input stream but don't increment stream pointer. 3642861e737e84e4884109b9526ac645194ba892a74Michal Krol */ 3652861e737e84e4884109b9526ac645194ba892a74Michal Krolstatic GLboolean 3662861e737e84e4884109b9526ac645194ba892a74Michal KrolPeek_Token(struct parse_state *parseState, GLubyte *token) 3672861e737e84e4884109b9526ac645194ba892a74Michal Krol{ 3682861e737e84e4884109b9526ac645194ba892a74Michal Krol GLint i, len; 3692861e737e84e4884109b9526ac645194ba892a74Michal Krol i = GetToken(parseState, token); 3702861e737e84e4884109b9526ac645194ba892a74Michal Krol if (i <= 0) { 3712861e737e84e4884109b9526ac645194ba892a74Michal Krol parseState->pos += (-i); 3722861e737e84e4884109b9526ac645194ba892a74Michal Krol return GL_FALSE; 3732861e737e84e4884109b9526ac645194ba892a74Michal Krol } 3746258b76c49f49a56a7c713914b798e80c6553b06Karl Schultz len = (GLint)_mesa_strlen((const char *) token); 3752861e737e84e4884109b9526ac645194ba892a74Michal Krol parseState->pos += (i - len); 3762861e737e84e4884109b9526ac645194ba892a74Michal Krol return GL_TRUE; 3772861e737e84e4884109b9526ac645194ba892a74Michal Krol} 3782861e737e84e4884109b9526ac645194ba892a74Michal Krol 3792861e737e84e4884109b9526ac645194ba892a74Michal Krol 3802861e737e84e4884109b9526ac645194ba892a74Michal Krol/**********************************************************************/ 3812861e737e84e4884109b9526ac645194ba892a74Michal Krol 3822861e737e84e4884109b9526ac645194ba892a74Michal Krolstatic const char *InputRegisters[MAX_NV_FRAGMENT_PROGRAM_INPUTS + 1] = { 3832861e737e84e4884109b9526ac645194ba892a74Michal Krol "WPOS", "COL0", "COL1", "FOGC", 3842861e737e84e4884109b9526ac645194ba892a74Michal Krol "TEX0", "TEX1", "TEX2", "TEX3", "TEX4", "TEX5", "TEX6", "TEX7", NULL 3852861e737e84e4884109b9526ac645194ba892a74Michal Krol}; 3862861e737e84e4884109b9526ac645194ba892a74Michal Krol 3872861e737e84e4884109b9526ac645194ba892a74Michal Krolstatic const char *OutputRegisters[MAX_NV_FRAGMENT_PROGRAM_OUTPUTS + 1] = { 3882861e737e84e4884109b9526ac645194ba892a74Michal Krol "COLR", "COLH", 3892861e737e84e4884109b9526ac645194ba892a74Michal Krol /* These are only allows for register combiners */ 3902861e737e84e4884109b9526ac645194ba892a74Michal Krol /* 3912861e737e84e4884109b9526ac645194ba892a74Michal Krol "TEX0", "TEX1", "TEX2", "TEX3", 3922861e737e84e4884109b9526ac645194ba892a74Michal Krol */ 3932861e737e84e4884109b9526ac645194ba892a74Michal Krol "DEPR", NULL 3942861e737e84e4884109b9526ac645194ba892a74Michal Krol}; 3952861e737e84e4884109b9526ac645194ba892a74Michal Krol 3962861e737e84e4884109b9526ac645194ba892a74Michal Krol 3972861e737e84e4884109b9526ac645194ba892a74Michal Krol 3982861e737e84e4884109b9526ac645194ba892a74Michal Krol 3992861e737e84e4884109b9526ac645194ba892a74Michal Krol/**********************************************************************/ 4002861e737e84e4884109b9526ac645194ba892a74Michal Krol 4012861e737e84e4884109b9526ac645194ba892a74Michal Krol/** 4022861e737e84e4884109b9526ac645194ba892a74Michal Krol * Try to match 'pattern' as the next token after any whitespace/comments. 4032861e737e84e4884109b9526ac645194ba892a74Michal Krol */ 4042861e737e84e4884109b9526ac645194ba892a74Michal Krolstatic GLboolean 4052861e737e84e4884109b9526ac645194ba892a74Michal KrolParse_String(struct parse_state *parseState, const char *pattern) 4062861e737e84e4884109b9526ac645194ba892a74Michal Krol{ 4072861e737e84e4884109b9526ac645194ba892a74Michal Krol const GLubyte *m; 4082861e737e84e4884109b9526ac645194ba892a74Michal Krol GLint i; 4092861e737e84e4884109b9526ac645194ba892a74Michal Krol 4102861e737e84e4884109b9526ac645194ba892a74Michal Krol /* skip whitespace and comments */ 4112861e737e84e4884109b9526ac645194ba892a74Michal Krol while (IsWhitespace(*parseState->pos) || *parseState->pos == '#') { 4122861e737e84e4884109b9526ac645194ba892a74Michal Krol if (*parseState->pos == '#') { 4132861e737e84e4884109b9526ac645194ba892a74Michal Krol while (*parseState->pos && (*parseState->pos != '\n' && *parseState->pos != '\r')) { 4142861e737e84e4884109b9526ac645194ba892a74Michal Krol parseState->pos += 1; 4152861e737e84e4884109b9526ac645194ba892a74Michal Krol } 4162861e737e84e4884109b9526ac645194ba892a74Michal Krol if (*parseState->pos == '\n' || *parseState->pos == '\r') 4172861e737e84e4884109b9526ac645194ba892a74Michal Krol parseState->curLine = parseState->pos + 1; 4182861e737e84e4884109b9526ac645194ba892a74Michal Krol } 4192861e737e84e4884109b9526ac645194ba892a74Michal Krol else { 4202861e737e84e4884109b9526ac645194ba892a74Michal Krol /* skip whitespace */ 4212861e737e84e4884109b9526ac645194ba892a74Michal Krol if (*parseState->pos == '\n' || *parseState->pos == '\r') 4222861e737e84e4884109b9526ac645194ba892a74Michal Krol parseState->curLine = parseState->pos + 1; 4232861e737e84e4884109b9526ac645194ba892a74Michal Krol parseState->pos += 1; 4242861e737e84e4884109b9526ac645194ba892a74Michal Krol } 4252861e737e84e4884109b9526ac645194ba892a74Michal Krol } 4262861e737e84e4884109b9526ac645194ba892a74Michal Krol 4272861e737e84e4884109b9526ac645194ba892a74Michal Krol /* Try to match the pattern */ 4282861e737e84e4884109b9526ac645194ba892a74Michal Krol m = parseState->pos; 4292861e737e84e4884109b9526ac645194ba892a74Michal Krol for (i = 0; pattern[i]; i++) { 4302861e737e84e4884109b9526ac645194ba892a74Michal Krol if (*m != (GLubyte) pattern[i]) 4312861e737e84e4884109b9526ac645194ba892a74Michal Krol return GL_FALSE; 4322861e737e84e4884109b9526ac645194ba892a74Michal Krol m += 1; 4332861e737e84e4884109b9526ac645194ba892a74Michal Krol } 4342861e737e84e4884109b9526ac645194ba892a74Michal Krol parseState->pos = m; 4352861e737e84e4884109b9526ac645194ba892a74Michal Krol 4362861e737e84e4884109b9526ac645194ba892a74Michal Krol return GL_TRUE; /* success */ 4372861e737e84e4884109b9526ac645194ba892a74Michal Krol} 4382861e737e84e4884109b9526ac645194ba892a74Michal Krol 4392861e737e84e4884109b9526ac645194ba892a74Michal Krol 4402861e737e84e4884109b9526ac645194ba892a74Michal Krolstatic GLboolean 4412861e737e84e4884109b9526ac645194ba892a74Michal KrolParse_Identifier(struct parse_state *parseState, GLubyte *ident) 4422861e737e84e4884109b9526ac645194ba892a74Michal Krol{ 4432861e737e84e4884109b9526ac645194ba892a74Michal Krol if (!Parse_Token(parseState, ident)) 4442861e737e84e4884109b9526ac645194ba892a74Michal Krol RETURN_ERROR; 4452861e737e84e4884109b9526ac645194ba892a74Michal Krol if (IsLetter(ident[0])) 4462861e737e84e4884109b9526ac645194ba892a74Michal Krol return GL_TRUE; 4472861e737e84e4884109b9526ac645194ba892a74Michal Krol else 4482861e737e84e4884109b9526ac645194ba892a74Michal Krol RETURN_ERROR1("Expected an identfier"); 4492861e737e84e4884109b9526ac645194ba892a74Michal Krol} 4502861e737e84e4884109b9526ac645194ba892a74Michal Krol 4512861e737e84e4884109b9526ac645194ba892a74Michal Krol 4522861e737e84e4884109b9526ac645194ba892a74Michal Krol/** 4532861e737e84e4884109b9526ac645194ba892a74Michal Krol * Parse a floating point constant, or a defined symbol name. 4542861e737e84e4884109b9526ac645194ba892a74Michal Krol * [+/-]N[.N[eN]] 4552861e737e84e4884109b9526ac645194ba892a74Michal Krol * Output: number[0 .. 3] will get the value. 4562861e737e84e4884109b9526ac645194ba892a74Michal Krol */ 4572861e737e84e4884109b9526ac645194ba892a74Michal Krolstatic GLboolean 4582861e737e84e4884109b9526ac645194ba892a74Michal KrolParse_ScalarConstant(struct parse_state *parseState, GLfloat *number) 4592861e737e84e4884109b9526ac645194ba892a74Michal Krol{ 4602861e737e84e4884109b9526ac645194ba892a74Michal Krol char *end = NULL; 4612861e737e84e4884109b9526ac645194ba892a74Michal Krol 4622861e737e84e4884109b9526ac645194ba892a74Michal Krol *number = (GLfloat) _mesa_strtod((const char *) parseState->pos, &end); 4632861e737e84e4884109b9526ac645194ba892a74Michal Krol 4642861e737e84e4884109b9526ac645194ba892a74Michal Krol if (end && end > (char *) parseState->pos) { 4652861e737e84e4884109b9526ac645194ba892a74Michal Krol /* got a number */ 4662861e737e84e4884109b9526ac645194ba892a74Michal Krol parseState->pos = (GLubyte *) end; 4672861e737e84e4884109b9526ac645194ba892a74Michal Krol number[1] = *number; 4682861e737e84e4884109b9526ac645194ba892a74Michal Krol number[2] = *number; 4692861e737e84e4884109b9526ac645194ba892a74Michal Krol number[3] = *number; 4702861e737e84e4884109b9526ac645194ba892a74Michal Krol return GL_TRUE; 4712861e737e84e4884109b9526ac645194ba892a74Michal Krol } 4722861e737e84e4884109b9526ac645194ba892a74Michal Krol else { 4732861e737e84e4884109b9526ac645194ba892a74Michal Krol /* should be an identifier */ 4742861e737e84e4884109b9526ac645194ba892a74Michal Krol GLubyte ident[100]; 4752861e737e84e4884109b9526ac645194ba892a74Michal Krol const GLfloat *constant; 4762861e737e84e4884109b9526ac645194ba892a74Michal Krol if (!Parse_Identifier(parseState, ident)) 4772861e737e84e4884109b9526ac645194ba892a74Michal Krol RETURN_ERROR1("Expected an identifier"); 4782861e737e84e4884109b9526ac645194ba892a74Michal Krol constant = _mesa_lookup_parameter_value(parseState->parameters, 4792861e737e84e4884109b9526ac645194ba892a74Michal Krol -1, (const char *) ident); 4802861e737e84e4884109b9526ac645194ba892a74Michal Krol /* XXX Check that it's a constant and not a parameter */ 4812861e737e84e4884109b9526ac645194ba892a74Michal Krol if (!constant) { 4822861e737e84e4884109b9526ac645194ba892a74Michal Krol RETURN_ERROR1("Undefined symbol"); 4832861e737e84e4884109b9526ac645194ba892a74Michal Krol } 4842861e737e84e4884109b9526ac645194ba892a74Michal Krol else { 4852861e737e84e4884109b9526ac645194ba892a74Michal Krol COPY_4V(number, constant); 4862861e737e84e4884109b9526ac645194ba892a74Michal Krol return GL_TRUE; 4872861e737e84e4884109b9526ac645194ba892a74Michal Krol } 4882861e737e84e4884109b9526ac645194ba892a74Michal Krol } 4892861e737e84e4884109b9526ac645194ba892a74Michal Krol} 4902861e737e84e4884109b9526ac645194ba892a74Michal Krol 4912861e737e84e4884109b9526ac645194ba892a74Michal Krol 4922861e737e84e4884109b9526ac645194ba892a74Michal Krol 4932861e737e84e4884109b9526ac645194ba892a74Michal Krol/** 4942861e737e84e4884109b9526ac645194ba892a74Michal Krol * Parse a vector constant, one of: 4952861e737e84e4884109b9526ac645194ba892a74Michal Krol * { float } 4962861e737e84e4884109b9526ac645194ba892a74Michal Krol * { float, float } 4972861e737e84e4884109b9526ac645194ba892a74Michal Krol * { float, float, float } 4982861e737e84e4884109b9526ac645194ba892a74Michal Krol * { float, float, float, float } 4992861e737e84e4884109b9526ac645194ba892a74Michal Krol */ 5002861e737e84e4884109b9526ac645194ba892a74Michal Krolstatic GLboolean 5012861e737e84e4884109b9526ac645194ba892a74Michal KrolParse_VectorConstant(struct parse_state *parseState, GLfloat *vec) 5022861e737e84e4884109b9526ac645194ba892a74Michal Krol{ 5032861e737e84e4884109b9526ac645194ba892a74Michal Krol /* "{" was already consumed */ 5042861e737e84e4884109b9526ac645194ba892a74Michal Krol 5052861e737e84e4884109b9526ac645194ba892a74Michal Krol ASSIGN_4V(vec, 0.0, 0.0, 0.0, 1.0); 5062861e737e84e4884109b9526ac645194ba892a74Michal Krol 5072861e737e84e4884109b9526ac645194ba892a74Michal Krol if (!Parse_ScalarConstant(parseState, vec+0)) /* X */ 5082861e737e84e4884109b9526ac645194ba892a74Michal Krol return GL_FALSE; 5092861e737e84e4884109b9526ac645194ba892a74Michal Krol 5102861e737e84e4884109b9526ac645194ba892a74Michal Krol if (Parse_String(parseState, "}")) { 5112861e737e84e4884109b9526ac645194ba892a74Michal Krol return GL_TRUE; 5122861e737e84e4884109b9526ac645194ba892a74Michal Krol } 5132861e737e84e4884109b9526ac645194ba892a74Michal Krol 5142861e737e84e4884109b9526ac645194ba892a74Michal Krol if (!Parse_String(parseState, ",")) 5152861e737e84e4884109b9526ac645194ba892a74Michal Krol RETURN_ERROR1("Expected comma in vector constant"); 5162861e737e84e4884109b9526ac645194ba892a74Michal Krol 5172861e737e84e4884109b9526ac645194ba892a74Michal Krol if (!Parse_ScalarConstant(parseState, vec+1)) /* Y */ 5182861e737e84e4884109b9526ac645194ba892a74Michal Krol return GL_FALSE; 5192861e737e84e4884109b9526ac645194ba892a74Michal Krol 5202861e737e84e4884109b9526ac645194ba892a74Michal Krol if (Parse_String(parseState, "}")) { 5212861e737e84e4884109b9526ac645194ba892a74Michal Krol return GL_TRUE; 5222861e737e84e4884109b9526ac645194ba892a74Michal Krol } 5232861e737e84e4884109b9526ac645194ba892a74Michal Krol 5242861e737e84e4884109b9526ac645194ba892a74Michal Krol if (!Parse_String(parseState, ",")) 5252861e737e84e4884109b9526ac645194ba892a74Michal Krol RETURN_ERROR1("Expected comma in vector constant"); 5262861e737e84e4884109b9526ac645194ba892a74Michal Krol 5272861e737e84e4884109b9526ac645194ba892a74Michal Krol if (!Parse_ScalarConstant(parseState, vec+2)) /* Z */ 5282861e737e84e4884109b9526ac645194ba892a74Michal Krol return GL_FALSE; 5292861e737e84e4884109b9526ac645194ba892a74Michal Krol 5302861e737e84e4884109b9526ac645194ba892a74Michal Krol if (Parse_String(parseState, "}")) { 5312861e737e84e4884109b9526ac645194ba892a74Michal Krol return GL_TRUE; 5322861e737e84e4884109b9526ac645194ba892a74Michal Krol } 5332861e737e84e4884109b9526ac645194ba892a74Michal Krol 5342861e737e84e4884109b9526ac645194ba892a74Michal Krol if (!Parse_String(parseState, ",")) 5352861e737e84e4884109b9526ac645194ba892a74Michal Krol RETURN_ERROR1("Expected comma in vector constant"); 5362861e737e84e4884109b9526ac645194ba892a74Michal Krol 5372861e737e84e4884109b9526ac645194ba892a74Michal Krol if (!Parse_ScalarConstant(parseState, vec+3)) /* W */ 5382861e737e84e4884109b9526ac645194ba892a74Michal Krol return GL_FALSE; 5392861e737e84e4884109b9526ac645194ba892a74Michal Krol 5402861e737e84e4884109b9526ac645194ba892a74Michal Krol if (!Parse_String(parseState, "}")) 5412861e737e84e4884109b9526ac645194ba892a74Michal Krol RETURN_ERROR1("Expected closing brace in vector constant"); 5422861e737e84e4884109b9526ac645194ba892a74Michal Krol 5432861e737e84e4884109b9526ac645194ba892a74Michal Krol return GL_TRUE; 5442861e737e84e4884109b9526ac645194ba892a74Michal Krol} 5452861e737e84e4884109b9526ac645194ba892a74Michal Krol 5462861e737e84e4884109b9526ac645194ba892a74Michal Krol 5472861e737e84e4884109b9526ac645194ba892a74Michal Krol/** 5482861e737e84e4884109b9526ac645194ba892a74Michal Krol * Parse <number>, <varname> or {a, b, c, d}. 5492861e737e84e4884109b9526ac645194ba892a74Michal Krol * Return number of values in the vector or scalar, or zero if parse error. 5502861e737e84e4884109b9526ac645194ba892a74Michal Krol */ 5512861e737e84e4884109b9526ac645194ba892a74Michal Krolstatic GLuint 5522861e737e84e4884109b9526ac645194ba892a74Michal KrolParse_VectorOrScalarConstant(struct parse_state *parseState, GLfloat *vec) 5532861e737e84e4884109b9526ac645194ba892a74Michal Krol{ 5542861e737e84e4884109b9526ac645194ba892a74Michal Krol if (Parse_String(parseState, "{")) { 5552861e737e84e4884109b9526ac645194ba892a74Michal Krol return Parse_VectorConstant(parseState, vec); 5562861e737e84e4884109b9526ac645194ba892a74Michal Krol } 5572861e737e84e4884109b9526ac645194ba892a74Michal Krol else { 5582861e737e84e4884109b9526ac645194ba892a74Michal Krol GLboolean b = Parse_ScalarConstant(parseState, vec); 5592861e737e84e4884109b9526ac645194ba892a74Michal Krol if (b) { 5602861e737e84e4884109b9526ac645194ba892a74Michal Krol vec[1] = vec[2] = vec[3] = vec[0]; 5612861e737e84e4884109b9526ac645194ba892a74Michal Krol } 5622861e737e84e4884109b9526ac645194ba892a74Michal Krol return b; 5632861e737e84e4884109b9526ac645194ba892a74Michal Krol } 5642861e737e84e4884109b9526ac645194ba892a74Michal Krol} 5652861e737e84e4884109b9526ac645194ba892a74Michal Krol 5662861e737e84e4884109b9526ac645194ba892a74Michal Krol 5672861e737e84e4884109b9526ac645194ba892a74Michal Krol/** 5682861e737e84e4884109b9526ac645194ba892a74Michal Krol * Parse a texture image source: 5692861e737e84e4884109b9526ac645194ba892a74Michal Krol * [TEX0 | TEX1 | .. | TEX15] , [1D | 2D | 3D | CUBE | RECT] 5702861e737e84e4884109b9526ac645194ba892a74Michal Krol */ 5712861e737e84e4884109b9526ac645194ba892a74Michal Krolstatic GLboolean 5722861e737e84e4884109b9526ac645194ba892a74Michal KrolParse_TextureImageId(struct parse_state *parseState, 5732861e737e84e4884109b9526ac645194ba892a74Michal Krol GLubyte *texUnit, GLubyte *texTargetBit) 5742861e737e84e4884109b9526ac645194ba892a74Michal Krol{ 5752861e737e84e4884109b9526ac645194ba892a74Michal Krol GLubyte imageSrc[100]; 5762861e737e84e4884109b9526ac645194ba892a74Michal Krol GLint unit; 5772861e737e84e4884109b9526ac645194ba892a74Michal Krol 5782861e737e84e4884109b9526ac645194ba892a74Michal Krol if (!Parse_Token(parseState, imageSrc)) 5792861e737e84e4884109b9526ac645194ba892a74Michal Krol RETURN_ERROR; 5802861e737e84e4884109b9526ac645194ba892a74Michal Krol 5812861e737e84e4884109b9526ac645194ba892a74Michal Krol if (imageSrc[0] != 'T' || 5822861e737e84e4884109b9526ac645194ba892a74Michal Krol imageSrc[1] != 'E' || 5832861e737e84e4884109b9526ac645194ba892a74Michal Krol imageSrc[2] != 'X') { 5842861e737e84e4884109b9526ac645194ba892a74Michal Krol RETURN_ERROR1("Expected TEX# source"); 5852861e737e84e4884109b9526ac645194ba892a74Michal Krol } 5862861e737e84e4884109b9526ac645194ba892a74Michal Krol unit = _mesa_atoi((const char *) imageSrc + 3); 5872861e737e84e4884109b9526ac645194ba892a74Michal Krol if ((unit < 0 || unit > MAX_TEXTURE_IMAGE_UNITS) || 5882861e737e84e4884109b9526ac645194ba892a74Michal Krol (unit == 0 && (imageSrc[3] != '0' || imageSrc[4] != 0))) { 5892861e737e84e4884109b9526ac645194ba892a74Michal Krol RETURN_ERROR1("Invalied TEX# source index"); 5902861e737e84e4884109b9526ac645194ba892a74Michal Krol } 5912861e737e84e4884109b9526ac645194ba892a74Michal Krol *texUnit = unit; 5922861e737e84e4884109b9526ac645194ba892a74Michal Krol 5932861e737e84e4884109b9526ac645194ba892a74Michal Krol if (!Parse_String(parseState, ",")) 5942861e737e84e4884109b9526ac645194ba892a74Michal Krol RETURN_ERROR1("Expected ,"); 5952861e737e84e4884109b9526ac645194ba892a74Michal Krol 5962861e737e84e4884109b9526ac645194ba892a74Michal Krol if (Parse_String(parseState, "1D")) { 5972861e737e84e4884109b9526ac645194ba892a74Michal Krol *texTargetBit = TEXTURE_1D_BIT; 5982861e737e84e4884109b9526ac645194ba892a74Michal Krol } 5992861e737e84e4884109b9526ac645194ba892a74Michal Krol else if (Parse_String(parseState, "2D")) { 6002861e737e84e4884109b9526ac645194ba892a74Michal Krol *texTargetBit = TEXTURE_2D_BIT; 6012861e737e84e4884109b9526ac645194ba892a74Michal Krol } 6022861e737e84e4884109b9526ac645194ba892a74Michal Krol else if (Parse_String(parseState, "3D")) { 6032861e737e84e4884109b9526ac645194ba892a74Michal Krol *texTargetBit = TEXTURE_3D_BIT; 6042861e737e84e4884109b9526ac645194ba892a74Michal Krol } 6052861e737e84e4884109b9526ac645194ba892a74Michal Krol else if (Parse_String(parseState, "CUBE")) { 6062861e737e84e4884109b9526ac645194ba892a74Michal Krol *texTargetBit = TEXTURE_CUBE_BIT; 6072861e737e84e4884109b9526ac645194ba892a74Michal Krol } 6082861e737e84e4884109b9526ac645194ba892a74Michal Krol else if (Parse_String(parseState, "RECT")) { 6092861e737e84e4884109b9526ac645194ba892a74Michal Krol *texTargetBit = TEXTURE_RECT_BIT; 6102861e737e84e4884109b9526ac645194ba892a74Michal Krol } 6112861e737e84e4884109b9526ac645194ba892a74Michal Krol else { 6122861e737e84e4884109b9526ac645194ba892a74Michal Krol RETURN_ERROR1("Invalid texture target token"); 6132861e737e84e4884109b9526ac645194ba892a74Michal Krol } 6142861e737e84e4884109b9526ac645194ba892a74Michal Krol 6152861e737e84e4884109b9526ac645194ba892a74Michal Krol /* update record of referenced texture units */ 6162861e737e84e4884109b9526ac645194ba892a74Michal Krol parseState->texturesUsed[*texUnit] |= *texTargetBit; 6172861e737e84e4884109b9526ac645194ba892a74Michal Krol if (_mesa_bitcount(parseState->texturesUsed[*texUnit]) > 1) { 6182861e737e84e4884109b9526ac645194ba892a74Michal Krol RETURN_ERROR1("Only one texture target can be used per texture unit."); 6192861e737e84e4884109b9526ac645194ba892a74Michal Krol } 6202861e737e84e4884109b9526ac645194ba892a74Michal Krol 6212861e737e84e4884109b9526ac645194ba892a74Michal Krol return GL_TRUE; 6222861e737e84e4884109b9526ac645194ba892a74Michal Krol} 6232861e737e84e4884109b9526ac645194ba892a74Michal Krol 6242861e737e84e4884109b9526ac645194ba892a74Michal Krol 6252861e737e84e4884109b9526ac645194ba892a74Michal Krol/** 6262861e737e84e4884109b9526ac645194ba892a74Michal Krol * Parse a scalar suffix like .x, .y, .z or .w or parse a swizzle suffix 6272861e737e84e4884109b9526ac645194ba892a74Michal Krol * like .wxyz, .xxyy, etc and return the swizzle indexes. 6282861e737e84e4884109b9526ac645194ba892a74Michal Krol */ 6292861e737e84e4884109b9526ac645194ba892a74Michal Krolstatic GLboolean 6302861e737e84e4884109b9526ac645194ba892a74Michal KrolParse_SwizzleSuffix(const GLubyte *token, GLuint swizzle[4]) 6312861e737e84e4884109b9526ac645194ba892a74Michal Krol{ 6322861e737e84e4884109b9526ac645194ba892a74Michal Krol if (token[1] == 0) { 6332861e737e84e4884109b9526ac645194ba892a74Michal Krol /* single letter swizzle (scalar) */ 6342861e737e84e4884109b9526ac645194ba892a74Michal Krol if (token[0] == 'x') 6352861e737e84e4884109b9526ac645194ba892a74Michal Krol ASSIGN_4V(swizzle, 0, 0, 0, 0); 6362861e737e84e4884109b9526ac645194ba892a74Michal Krol else if (token[0] == 'y') 6372861e737e84e4884109b9526ac645194ba892a74Michal Krol ASSIGN_4V(swizzle, 1, 1, 1, 1); 6382861e737e84e4884109b9526ac645194ba892a74Michal Krol else if (token[0] == 'z') 6392861e737e84e4884109b9526ac645194ba892a74Michal Krol ASSIGN_4V(swizzle, 2, 2, 2, 2); 6402861e737e84e4884109b9526ac645194ba892a74Michal Krol else if (token[0] == 'w') 6412861e737e84e4884109b9526ac645194ba892a74Michal Krol ASSIGN_4V(swizzle, 3, 3, 3, 3); 6422861e737e84e4884109b9526ac645194ba892a74Michal Krol else 6432861e737e84e4884109b9526ac645194ba892a74Michal Krol return GL_FALSE; 6442861e737e84e4884109b9526ac645194ba892a74Michal Krol } 6452861e737e84e4884109b9526ac645194ba892a74Michal Krol else { 6462861e737e84e4884109b9526ac645194ba892a74Michal Krol /* 4-component swizzle (vector) */ 6472861e737e84e4884109b9526ac645194ba892a74Michal Krol GLint k; 6482861e737e84e4884109b9526ac645194ba892a74Michal Krol for (k = 0; token[k] && k < 4; k++) { 6492861e737e84e4884109b9526ac645194ba892a74Michal Krol if (token[k] == 'x') 6502861e737e84e4884109b9526ac645194ba892a74Michal Krol swizzle[k] = 0; 6512861e737e84e4884109b9526ac645194ba892a74Michal Krol else if (token[k] == 'y') 6522861e737e84e4884109b9526ac645194ba892a74Michal Krol swizzle[k] = 1; 6532861e737e84e4884109b9526ac645194ba892a74Michal Krol else if (token[k] == 'z') 6542861e737e84e4884109b9526ac645194ba892a74Michal Krol swizzle[k] = 2; 6552861e737e84e4884109b9526ac645194ba892a74Michal Krol else if (token[k] == 'w') 6562861e737e84e4884109b9526ac645194ba892a74Michal Krol swizzle[k] = 3; 6572861e737e84e4884109b9526ac645194ba892a74Michal Krol else 6582861e737e84e4884109b9526ac645194ba892a74Michal Krol return GL_FALSE; 6592861e737e84e4884109b9526ac645194ba892a74Michal Krol } 6602861e737e84e4884109b9526ac645194ba892a74Michal Krol if (k != 4) 6612861e737e84e4884109b9526ac645194ba892a74Michal Krol return GL_FALSE; 6622861e737e84e4884109b9526ac645194ba892a74Michal Krol } 6632861e737e84e4884109b9526ac645194ba892a74Michal Krol return GL_TRUE; 6642861e737e84e4884109b9526ac645194ba892a74Michal Krol} 6652861e737e84e4884109b9526ac645194ba892a74Michal Krol 6662861e737e84e4884109b9526ac645194ba892a74Michal Krol 6672861e737e84e4884109b9526ac645194ba892a74Michal Krolstatic GLboolean 6682861e737e84e4884109b9526ac645194ba892a74Michal KrolParse_CondCodeMask(struct parse_state *parseState, 6697e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul struct prog_dst_register *dstReg) 6702861e737e84e4884109b9526ac645194ba892a74Michal Krol{ 6712861e737e84e4884109b9526ac645194ba892a74Michal Krol if (Parse_String(parseState, "EQ")) 6722861e737e84e4884109b9526ac645194ba892a74Michal Krol dstReg->CondMask = COND_EQ; 6732861e737e84e4884109b9526ac645194ba892a74Michal Krol else if (Parse_String(parseState, "GE")) 6742861e737e84e4884109b9526ac645194ba892a74Michal Krol dstReg->CondMask = COND_GE; 6752861e737e84e4884109b9526ac645194ba892a74Michal Krol else if (Parse_String(parseState, "GT")) 6762861e737e84e4884109b9526ac645194ba892a74Michal Krol dstReg->CondMask = COND_GT; 6772861e737e84e4884109b9526ac645194ba892a74Michal Krol else if (Parse_String(parseState, "LE")) 6782861e737e84e4884109b9526ac645194ba892a74Michal Krol dstReg->CondMask = COND_LE; 6792861e737e84e4884109b9526ac645194ba892a74Michal Krol else if (Parse_String(parseState, "LT")) 6802861e737e84e4884109b9526ac645194ba892a74Michal Krol dstReg->CondMask = COND_LT; 6812861e737e84e4884109b9526ac645194ba892a74Michal Krol else if (Parse_String(parseState, "NE")) 6822861e737e84e4884109b9526ac645194ba892a74Michal Krol dstReg->CondMask = COND_NE; 6832861e737e84e4884109b9526ac645194ba892a74Michal Krol else if (Parse_String(parseState, "TR")) 6842861e737e84e4884109b9526ac645194ba892a74Michal Krol dstReg->CondMask = COND_TR; 6852861e737e84e4884109b9526ac645194ba892a74Michal Krol else if (Parse_String(parseState, "FL")) 6862861e737e84e4884109b9526ac645194ba892a74Michal Krol dstReg->CondMask = COND_FL; 6872861e737e84e4884109b9526ac645194ba892a74Michal Krol else 6882861e737e84e4884109b9526ac645194ba892a74Michal Krol RETURN_ERROR1("Invalid condition code mask"); 6892861e737e84e4884109b9526ac645194ba892a74Michal Krol 6902861e737e84e4884109b9526ac645194ba892a74Michal Krol /* look for optional .xyzw swizzle */ 6912861e737e84e4884109b9526ac645194ba892a74Michal Krol if (Parse_String(parseState, ".")) { 6922861e737e84e4884109b9526ac645194ba892a74Michal Krol GLubyte token[100]; 6937c26b61f9366a397e353d7b7f1f1d1f6d0dcd0c7Keith Whitwell GLuint swz[4]; 6947c26b61f9366a397e353d7b7f1f1d1f6d0dcd0c7Keith Whitwell 6952861e737e84e4884109b9526ac645194ba892a74Michal Krol if (!Parse_Token(parseState, token)) /* get xyzw suffix */ 6962861e737e84e4884109b9526ac645194ba892a74Michal Krol RETURN_ERROR; 6972861e737e84e4884109b9526ac645194ba892a74Michal Krol 6987c26b61f9366a397e353d7b7f1f1d1f6d0dcd0c7Keith Whitwell if (!Parse_SwizzleSuffix(token, swz)) 6992861e737e84e4884109b9526ac645194ba892a74Michal Krol RETURN_ERROR1("Invalid swizzle suffix"); 7007c26b61f9366a397e353d7b7f1f1d1f6d0dcd0c7Keith Whitwell 701fd4395b8d1d6f8f018e7e7c3dd0c52fe52ab2794Brian Paul dstReg->CondSwizzle = MAKE_SWIZZLE4(swz[0], swz[1], swz[2], swz[3]); 7022861e737e84e4884109b9526ac645194ba892a74Michal Krol } 7032861e737e84e4884109b9526ac645194ba892a74Michal Krol 7042861e737e84e4884109b9526ac645194ba892a74Michal Krol return GL_TRUE; 7052861e737e84e4884109b9526ac645194ba892a74Michal Krol} 7062861e737e84e4884109b9526ac645194ba892a74Michal Krol 7072861e737e84e4884109b9526ac645194ba892a74Michal Krol 7082861e737e84e4884109b9526ac645194ba892a74Michal Krol/** 7092861e737e84e4884109b9526ac645194ba892a74Michal Krol * Parse a temporary register: Rnn or Hnn 7102861e737e84e4884109b9526ac645194ba892a74Michal Krol */ 7112861e737e84e4884109b9526ac645194ba892a74Michal Krolstatic GLboolean 7122861e737e84e4884109b9526ac645194ba892a74Michal KrolParse_TempReg(struct parse_state *parseState, GLint *tempRegNum) 7132861e737e84e4884109b9526ac645194ba892a74Michal Krol{ 7142861e737e84e4884109b9526ac645194ba892a74Michal Krol GLubyte token[100]; 7152861e737e84e4884109b9526ac645194ba892a74Michal Krol 7162861e737e84e4884109b9526ac645194ba892a74Michal Krol /* Should be 'R##' or 'H##' */ 7172861e737e84e4884109b9526ac645194ba892a74Michal Krol if (!Parse_Token(parseState, token)) 7182861e737e84e4884109b9526ac645194ba892a74Michal Krol RETURN_ERROR; 7192861e737e84e4884109b9526ac645194ba892a74Michal Krol if (token[0] != 'R' && token[0] != 'H') 7202861e737e84e4884109b9526ac645194ba892a74Michal Krol RETURN_ERROR1("Expected R## or H##"); 7212861e737e84e4884109b9526ac645194ba892a74Michal Krol 7222861e737e84e4884109b9526ac645194ba892a74Michal Krol if (IsDigit(token[1])) { 7232861e737e84e4884109b9526ac645194ba892a74Michal Krol GLint reg = _mesa_atoi((const char *) (token + 1)); 7242861e737e84e4884109b9526ac645194ba892a74Michal Krol if (token[0] == 'H') 7252861e737e84e4884109b9526ac645194ba892a74Michal Krol reg += 32; 7262861e737e84e4884109b9526ac645194ba892a74Michal Krol if (reg >= MAX_NV_FRAGMENT_PROGRAM_TEMPS) 7272861e737e84e4884109b9526ac645194ba892a74Michal Krol RETURN_ERROR1("Invalid temporary register name"); 7282861e737e84e4884109b9526ac645194ba892a74Michal Krol *tempRegNum = reg; 7292861e737e84e4884109b9526ac645194ba892a74Michal Krol } 7302861e737e84e4884109b9526ac645194ba892a74Michal Krol else { 7312861e737e84e4884109b9526ac645194ba892a74Michal Krol RETURN_ERROR1("Invalid temporary register name"); 7322861e737e84e4884109b9526ac645194ba892a74Michal Krol } 7332861e737e84e4884109b9526ac645194ba892a74Michal Krol 7342861e737e84e4884109b9526ac645194ba892a74Michal Krol return GL_TRUE; 7352861e737e84e4884109b9526ac645194ba892a74Michal Krol} 7362861e737e84e4884109b9526ac645194ba892a74Michal Krol 7372861e737e84e4884109b9526ac645194ba892a74Michal Krol 7382861e737e84e4884109b9526ac645194ba892a74Michal Krol/** 7392861e737e84e4884109b9526ac645194ba892a74Michal Krol * Parse a write-only dummy register: RC or HC. 7402861e737e84e4884109b9526ac645194ba892a74Michal Krol */ 7412861e737e84e4884109b9526ac645194ba892a74Michal Krolstatic GLboolean 7422861e737e84e4884109b9526ac645194ba892a74Michal KrolParse_DummyReg(struct parse_state *parseState, GLint *regNum) 7432861e737e84e4884109b9526ac645194ba892a74Michal Krol{ 7442861e737e84e4884109b9526ac645194ba892a74Michal Krol if (Parse_String(parseState, "RC")) { 7452861e737e84e4884109b9526ac645194ba892a74Michal Krol *regNum = 0; 7462861e737e84e4884109b9526ac645194ba892a74Michal Krol } 7472861e737e84e4884109b9526ac645194ba892a74Michal Krol else if (Parse_String(parseState, "HC")) { 7482861e737e84e4884109b9526ac645194ba892a74Michal Krol *regNum = 1; 7492861e737e84e4884109b9526ac645194ba892a74Michal Krol } 7502861e737e84e4884109b9526ac645194ba892a74Michal Krol else { 7512861e737e84e4884109b9526ac645194ba892a74Michal Krol RETURN_ERROR1("Invalid write-only register name"); 7522861e737e84e4884109b9526ac645194ba892a74Michal Krol } 7532861e737e84e4884109b9526ac645194ba892a74Michal Krol 7542861e737e84e4884109b9526ac645194ba892a74Michal Krol return GL_TRUE; 7552861e737e84e4884109b9526ac645194ba892a74Michal Krol} 7562861e737e84e4884109b9526ac645194ba892a74Michal Krol 7572861e737e84e4884109b9526ac645194ba892a74Michal Krol 7582861e737e84e4884109b9526ac645194ba892a74Michal Krol/** 7592861e737e84e4884109b9526ac645194ba892a74Michal Krol * Parse a program local parameter register "p[##]" 7602861e737e84e4884109b9526ac645194ba892a74Michal Krol */ 7612861e737e84e4884109b9526ac645194ba892a74Michal Krolstatic GLboolean 7622861e737e84e4884109b9526ac645194ba892a74Michal KrolParse_ProgramParamReg(struct parse_state *parseState, GLint *regNum) 7632861e737e84e4884109b9526ac645194ba892a74Michal Krol{ 7642861e737e84e4884109b9526ac645194ba892a74Michal Krol GLubyte token[100]; 7652861e737e84e4884109b9526ac645194ba892a74Michal Krol 7662861e737e84e4884109b9526ac645194ba892a74Michal Krol if (!Parse_String(parseState, "p[")) 7672861e737e84e4884109b9526ac645194ba892a74Michal Krol RETURN_ERROR1("Expected p["); 7682861e737e84e4884109b9526ac645194ba892a74Michal Krol 7692861e737e84e4884109b9526ac645194ba892a74Michal Krol if (!Parse_Token(parseState, token)) 7702861e737e84e4884109b9526ac645194ba892a74Michal Krol RETURN_ERROR; 7712861e737e84e4884109b9526ac645194ba892a74Michal Krol 7722861e737e84e4884109b9526ac645194ba892a74Michal Krol if (IsDigit(token[0])) { 7732861e737e84e4884109b9526ac645194ba892a74Michal Krol /* a numbered program parameter register */ 7742861e737e84e4884109b9526ac645194ba892a74Michal Krol GLint reg = _mesa_atoi((const char *) token); 7752861e737e84e4884109b9526ac645194ba892a74Michal Krol if (reg >= MAX_NV_FRAGMENT_PROGRAM_PARAMS) 7762861e737e84e4884109b9526ac645194ba892a74Michal Krol RETURN_ERROR1("Invalid constant program number"); 7772861e737e84e4884109b9526ac645194ba892a74Michal Krol *regNum = reg; 7782861e737e84e4884109b9526ac645194ba892a74Michal Krol } 7792861e737e84e4884109b9526ac645194ba892a74Michal Krol else { 7802861e737e84e4884109b9526ac645194ba892a74Michal Krol RETURN_ERROR; 7812861e737e84e4884109b9526ac645194ba892a74Michal Krol } 7822861e737e84e4884109b9526ac645194ba892a74Michal Krol 7832861e737e84e4884109b9526ac645194ba892a74Michal Krol if (!Parse_String(parseState, "]")) 7842861e737e84e4884109b9526ac645194ba892a74Michal Krol RETURN_ERROR1("Expected ]"); 7852861e737e84e4884109b9526ac645194ba892a74Michal Krol 7862861e737e84e4884109b9526ac645194ba892a74Michal Krol return GL_TRUE; 7872861e737e84e4884109b9526ac645194ba892a74Michal Krol} 7882861e737e84e4884109b9526ac645194ba892a74Michal Krol 7892861e737e84e4884109b9526ac645194ba892a74Michal Krol 7902861e737e84e4884109b9526ac645194ba892a74Michal Krol/** 7912861e737e84e4884109b9526ac645194ba892a74Michal Krol * Parse f[name] - fragment input register 7922861e737e84e4884109b9526ac645194ba892a74Michal Krol */ 7932861e737e84e4884109b9526ac645194ba892a74Michal Krolstatic GLboolean 7942861e737e84e4884109b9526ac645194ba892a74Michal KrolParse_FragReg(struct parse_state *parseState, GLint *tempRegNum) 7952861e737e84e4884109b9526ac645194ba892a74Michal Krol{ 7962861e737e84e4884109b9526ac645194ba892a74Michal Krol GLubyte token[100]; 7972861e737e84e4884109b9526ac645194ba892a74Michal Krol GLint j; 7982861e737e84e4884109b9526ac645194ba892a74Michal Krol 7992861e737e84e4884109b9526ac645194ba892a74Michal Krol /* Match 'f[' */ 8002861e737e84e4884109b9526ac645194ba892a74Michal Krol if (!Parse_String(parseState, "f[")) 8012861e737e84e4884109b9526ac645194ba892a74Michal Krol RETURN_ERROR1("Expected f["); 8022861e737e84e4884109b9526ac645194ba892a74Michal Krol 8032861e737e84e4884109b9526ac645194ba892a74Michal Krol /* get <name> and look for match */ 8042861e737e84e4884109b9526ac645194ba892a74Michal Krol if (!Parse_Token(parseState, token)) { 8052861e737e84e4884109b9526ac645194ba892a74Michal Krol RETURN_ERROR; 8062861e737e84e4884109b9526ac645194ba892a74Michal Krol } 8072861e737e84e4884109b9526ac645194ba892a74Michal Krol for (j = 0; InputRegisters[j]; j++) { 8082861e737e84e4884109b9526ac645194ba892a74Michal Krol if (_mesa_strcmp((const char *) token, InputRegisters[j]) == 0) { 8092861e737e84e4884109b9526ac645194ba892a74Michal Krol *tempRegNum = j; 8102861e737e84e4884109b9526ac645194ba892a74Michal Krol parseState->inputsRead |= (1 << j); 8112861e737e84e4884109b9526ac645194ba892a74Michal Krol break; 8122861e737e84e4884109b9526ac645194ba892a74Michal Krol } 8132861e737e84e4884109b9526ac645194ba892a74Michal Krol } 8142861e737e84e4884109b9526ac645194ba892a74Michal Krol if (!InputRegisters[j]) { 8152861e737e84e4884109b9526ac645194ba892a74Michal Krol /* unknown input register label */ 8162861e737e84e4884109b9526ac645194ba892a74Michal Krol RETURN_ERROR2("Invalid register name", token); 8172861e737e84e4884109b9526ac645194ba892a74Michal Krol } 8182861e737e84e4884109b9526ac645194ba892a74Michal Krol 8192861e737e84e4884109b9526ac645194ba892a74Michal Krol /* Match '[' */ 8202861e737e84e4884109b9526ac645194ba892a74Michal Krol if (!Parse_String(parseState, "]")) 8212861e737e84e4884109b9526ac645194ba892a74Michal Krol RETURN_ERROR1("Expected ]"); 8222861e737e84e4884109b9526ac645194ba892a74Michal Krol 8232861e737e84e4884109b9526ac645194ba892a74Michal Krol return GL_TRUE; 8242861e737e84e4884109b9526ac645194ba892a74Michal Krol} 8252861e737e84e4884109b9526ac645194ba892a74Michal Krol 8262861e737e84e4884109b9526ac645194ba892a74Michal Krol 8272861e737e84e4884109b9526ac645194ba892a74Michal Krolstatic GLboolean 8282861e737e84e4884109b9526ac645194ba892a74Michal KrolParse_OutputReg(struct parse_state *parseState, GLint *outputRegNum) 8292861e737e84e4884109b9526ac645194ba892a74Michal Krol{ 8302861e737e84e4884109b9526ac645194ba892a74Michal Krol GLubyte token[100]; 8312861e737e84e4884109b9526ac645194ba892a74Michal Krol GLint j; 8322861e737e84e4884109b9526ac645194ba892a74Michal Krol 8332861e737e84e4884109b9526ac645194ba892a74Michal Krol /* Match "o[" */ 8342861e737e84e4884109b9526ac645194ba892a74Michal Krol if (!Parse_String(parseState, "o[")) 8352861e737e84e4884109b9526ac645194ba892a74Michal Krol RETURN_ERROR1("Expected o["); 8362861e737e84e4884109b9526ac645194ba892a74Michal Krol 8372861e737e84e4884109b9526ac645194ba892a74Michal Krol /* Get output reg name */ 8382861e737e84e4884109b9526ac645194ba892a74Michal Krol if (!Parse_Token(parseState, token)) 8392861e737e84e4884109b9526ac645194ba892a74Michal Krol RETURN_ERROR; 8402861e737e84e4884109b9526ac645194ba892a74Michal Krol 8412861e737e84e4884109b9526ac645194ba892a74Michal Krol /* try to match an output register name */ 8422861e737e84e4884109b9526ac645194ba892a74Michal Krol for (j = 0; OutputRegisters[j]; j++) { 8432861e737e84e4884109b9526ac645194ba892a74Michal Krol if (_mesa_strcmp((const char *) token, OutputRegisters[j]) == 0) { 84490ebb581e60d29bd565ad4d8a49e642de7b0ce5dBrian Paul static GLuint bothColors = (1 << FRAG_RESULT_COLR) | (1 << FRAG_RESULT_COLH); 8452861e737e84e4884109b9526ac645194ba892a74Michal Krol *outputRegNum = j; 8462861e737e84e4884109b9526ac645194ba892a74Michal Krol parseState->outputsWritten |= (1 << j); 8472861e737e84e4884109b9526ac645194ba892a74Michal Krol if ((parseState->outputsWritten & bothColors) == bothColors) { 8482861e737e84e4884109b9526ac645194ba892a74Michal Krol RETURN_ERROR1("Illegal to write to both o[COLR] and o[COLH]"); 8492861e737e84e4884109b9526ac645194ba892a74Michal Krol } 8502861e737e84e4884109b9526ac645194ba892a74Michal Krol break; 8512861e737e84e4884109b9526ac645194ba892a74Michal Krol } 8522861e737e84e4884109b9526ac645194ba892a74Michal Krol } 8532861e737e84e4884109b9526ac645194ba892a74Michal Krol if (!OutputRegisters[j]) 8542861e737e84e4884109b9526ac645194ba892a74Michal Krol RETURN_ERROR1("Invalid output register name"); 8552861e737e84e4884109b9526ac645194ba892a74Michal Krol 8562861e737e84e4884109b9526ac645194ba892a74Michal Krol /* Match ']' */ 8572861e737e84e4884109b9526ac645194ba892a74Michal Krol if (!Parse_String(parseState, "]")) 8582861e737e84e4884109b9526ac645194ba892a74Michal Krol RETURN_ERROR1("Expected ]"); 8592861e737e84e4884109b9526ac645194ba892a74Michal Krol 8602861e737e84e4884109b9526ac645194ba892a74Michal Krol return GL_TRUE; 8612861e737e84e4884109b9526ac645194ba892a74Michal Krol} 8622861e737e84e4884109b9526ac645194ba892a74Michal Krol 8632861e737e84e4884109b9526ac645194ba892a74Michal Krol 8642861e737e84e4884109b9526ac645194ba892a74Michal Krolstatic GLboolean 8652861e737e84e4884109b9526ac645194ba892a74Michal KrolParse_MaskedDstReg(struct parse_state *parseState, 8667e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul struct prog_dst_register *dstReg) 8672861e737e84e4884109b9526ac645194ba892a74Michal Krol{ 8682861e737e84e4884109b9526ac645194ba892a74Michal Krol GLubyte token[100]; 8697c26b61f9366a397e353d7b7f1f1d1f6d0dcd0c7Keith Whitwell GLint idx; 8702861e737e84e4884109b9526ac645194ba892a74Michal Krol 8712861e737e84e4884109b9526ac645194ba892a74Michal Krol /* Dst reg can be R<n>, H<n>, o[n], RC or HC */ 8722861e737e84e4884109b9526ac645194ba892a74Michal Krol if (!Peek_Token(parseState, token)) 8732861e737e84e4884109b9526ac645194ba892a74Michal Krol RETURN_ERROR; 8742861e737e84e4884109b9526ac645194ba892a74Michal Krol 8752861e737e84e4884109b9526ac645194ba892a74Michal Krol if (_mesa_strcmp((const char *) token, "RC") == 0 || 8762861e737e84e4884109b9526ac645194ba892a74Michal Krol _mesa_strcmp((const char *) token, "HC") == 0) { 8772861e737e84e4884109b9526ac645194ba892a74Michal Krol /* a write-only register */ 8782861e737e84e4884109b9526ac645194ba892a74Michal Krol dstReg->File = PROGRAM_WRITE_ONLY; 8797c26b61f9366a397e353d7b7f1f1d1f6d0dcd0c7Keith Whitwell if (!Parse_DummyReg(parseState, &idx)) 8802861e737e84e4884109b9526ac645194ba892a74Michal Krol RETURN_ERROR; 8817c26b61f9366a397e353d7b7f1f1d1f6d0dcd0c7Keith Whitwell dstReg->Index = idx; 8822861e737e84e4884109b9526ac645194ba892a74Michal Krol } 8832861e737e84e4884109b9526ac645194ba892a74Michal Krol else if (token[0] == 'R' || token[0] == 'H') { 8842861e737e84e4884109b9526ac645194ba892a74Michal Krol /* a temporary register */ 8852861e737e84e4884109b9526ac645194ba892a74Michal Krol dstReg->File = PROGRAM_TEMPORARY; 8867c26b61f9366a397e353d7b7f1f1d1f6d0dcd0c7Keith Whitwell if (!Parse_TempReg(parseState, &idx)) 8872861e737e84e4884109b9526ac645194ba892a74Michal Krol RETURN_ERROR; 8887c26b61f9366a397e353d7b7f1f1d1f6d0dcd0c7Keith Whitwell dstReg->Index = idx; 8892861e737e84e4884109b9526ac645194ba892a74Michal Krol } 8902861e737e84e4884109b9526ac645194ba892a74Michal Krol else if (token[0] == 'o') { 8912861e737e84e4884109b9526ac645194ba892a74Michal Krol /* an output register */ 8922861e737e84e4884109b9526ac645194ba892a74Michal Krol dstReg->File = PROGRAM_OUTPUT; 8937c26b61f9366a397e353d7b7f1f1d1f6d0dcd0c7Keith Whitwell if (!Parse_OutputReg(parseState, &idx)) 8942861e737e84e4884109b9526ac645194ba892a74Michal Krol RETURN_ERROR; 8957c26b61f9366a397e353d7b7f1f1d1f6d0dcd0c7Keith Whitwell dstReg->Index = idx; 8962861e737e84e4884109b9526ac645194ba892a74Michal Krol } 8972861e737e84e4884109b9526ac645194ba892a74Michal Krol else { 8982861e737e84e4884109b9526ac645194ba892a74Michal Krol RETURN_ERROR1("Invalid destination register name"); 8992861e737e84e4884109b9526ac645194ba892a74Michal Krol } 9002861e737e84e4884109b9526ac645194ba892a74Michal Krol 9012861e737e84e4884109b9526ac645194ba892a74Michal Krol /* Parse optional write mask */ 9022861e737e84e4884109b9526ac645194ba892a74Michal Krol if (Parse_String(parseState, ".")) { 9032861e737e84e4884109b9526ac645194ba892a74Michal Krol /* got a mask */ 9042861e737e84e4884109b9526ac645194ba892a74Michal Krol GLint k = 0; 9052861e737e84e4884109b9526ac645194ba892a74Michal Krol 9062861e737e84e4884109b9526ac645194ba892a74Michal Krol if (!Parse_Token(parseState, token)) /* get xyzw writemask */ 9072861e737e84e4884109b9526ac645194ba892a74Michal Krol RETURN_ERROR; 9082861e737e84e4884109b9526ac645194ba892a74Michal Krol 9097c26b61f9366a397e353d7b7f1f1d1f6d0dcd0c7Keith Whitwell dstReg->WriteMask = 0; 9102861e737e84e4884109b9526ac645194ba892a74Michal Krol 9112861e737e84e4884109b9526ac645194ba892a74Michal Krol if (token[k] == 'x') { 9127c26b61f9366a397e353d7b7f1f1d1f6d0dcd0c7Keith Whitwell dstReg->WriteMask |= WRITEMASK_X; 9132861e737e84e4884109b9526ac645194ba892a74Michal Krol k++; 9142861e737e84e4884109b9526ac645194ba892a74Michal Krol } 9152861e737e84e4884109b9526ac645194ba892a74Michal Krol if (token[k] == 'y') { 9167c26b61f9366a397e353d7b7f1f1d1f6d0dcd0c7Keith Whitwell dstReg->WriteMask |= WRITEMASK_Y; 9172861e737e84e4884109b9526ac645194ba892a74Michal Krol k++; 9182861e737e84e4884109b9526ac645194ba892a74Michal Krol } 9192861e737e84e4884109b9526ac645194ba892a74Michal Krol if (token[k] == 'z') { 9207c26b61f9366a397e353d7b7f1f1d1f6d0dcd0c7Keith Whitwell dstReg->WriteMask |= WRITEMASK_Z; 9212861e737e84e4884109b9526ac645194ba892a74Michal Krol k++; 9222861e737e84e4884109b9526ac645194ba892a74Michal Krol } 9232861e737e84e4884109b9526ac645194ba892a74Michal Krol if (token[k] == 'w') { 9247c26b61f9366a397e353d7b7f1f1d1f6d0dcd0c7Keith Whitwell dstReg->WriteMask |= WRITEMASK_W; 9252861e737e84e4884109b9526ac645194ba892a74Michal Krol k++; 9262861e737e84e4884109b9526ac645194ba892a74Michal Krol } 9272861e737e84e4884109b9526ac645194ba892a74Michal Krol if (k == 0) { 9282861e737e84e4884109b9526ac645194ba892a74Michal Krol RETURN_ERROR1("Invalid writemask character"); 9292861e737e84e4884109b9526ac645194ba892a74Michal Krol } 9302861e737e84e4884109b9526ac645194ba892a74Michal Krol 9312861e737e84e4884109b9526ac645194ba892a74Michal Krol } 9322861e737e84e4884109b9526ac645194ba892a74Michal Krol else { 9337c26b61f9366a397e353d7b7f1f1d1f6d0dcd0c7Keith Whitwell dstReg->WriteMask = WRITEMASK_XYZW; 9342861e737e84e4884109b9526ac645194ba892a74Michal Krol } 9352861e737e84e4884109b9526ac645194ba892a74Michal Krol 9362861e737e84e4884109b9526ac645194ba892a74Michal Krol /* optional condition code mask */ 9372861e737e84e4884109b9526ac645194ba892a74Michal Krol if (Parse_String(parseState, "(")) { 9382861e737e84e4884109b9526ac645194ba892a74Michal Krol /* ("EQ" | "GE" | "GT" | "LE" | "LT" | "NE" | "TR" | "FL".x|y|z|w) */ 9392861e737e84e4884109b9526ac645194ba892a74Michal Krol /* ("EQ" | "GE" | "GT" | "LE" | "LT" | "NE" | "TR" | "FL".[xyzw]) */ 9402861e737e84e4884109b9526ac645194ba892a74Michal Krol if (!Parse_CondCodeMask(parseState, dstReg)) 9412861e737e84e4884109b9526ac645194ba892a74Michal Krol RETURN_ERROR; 9422861e737e84e4884109b9526ac645194ba892a74Michal Krol 9432861e737e84e4884109b9526ac645194ba892a74Michal Krol if (!Parse_String(parseState, ")")) /* consume ")" */ 9442861e737e84e4884109b9526ac645194ba892a74Michal Krol RETURN_ERROR1("Expected )"); 9452861e737e84e4884109b9526ac645194ba892a74Michal Krol 9462861e737e84e4884109b9526ac645194ba892a74Michal Krol return GL_TRUE; 9472861e737e84e4884109b9526ac645194ba892a74Michal Krol } 9482861e737e84e4884109b9526ac645194ba892a74Michal Krol else { 9492861e737e84e4884109b9526ac645194ba892a74Michal Krol /* no cond code mask */ 9502861e737e84e4884109b9526ac645194ba892a74Michal Krol dstReg->CondMask = COND_TR; 9517c26b61f9366a397e353d7b7f1f1d1f6d0dcd0c7Keith Whitwell dstReg->CondSwizzle = SWIZZLE_NOOP; 9522861e737e84e4884109b9526ac645194ba892a74Michal Krol return GL_TRUE; 9532861e737e84e4884109b9526ac645194ba892a74Michal Krol } 9542861e737e84e4884109b9526ac645194ba892a74Michal Krol} 9552861e737e84e4884109b9526ac645194ba892a74Michal Krol 9562861e737e84e4884109b9526ac645194ba892a74Michal Krol 9572861e737e84e4884109b9526ac645194ba892a74Michal Krol/** 9582861e737e84e4884109b9526ac645194ba892a74Michal Krol * Parse a vector source (register, constant, etc): 9592861e737e84e4884109b9526ac645194ba892a74Michal Krol * <vectorSrc> ::= <absVectorSrc> 9602861e737e84e4884109b9526ac645194ba892a74Michal Krol * | <baseVectorSrc> 9612861e737e84e4884109b9526ac645194ba892a74Michal Krol * <absVectorSrc> ::= <negate> "|" <baseVectorSrc> "|" 9622861e737e84e4884109b9526ac645194ba892a74Michal Krol */ 9632861e737e84e4884109b9526ac645194ba892a74Michal Krolstatic GLboolean 9642861e737e84e4884109b9526ac645194ba892a74Michal KrolParse_VectorSrc(struct parse_state *parseState, 9657e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul struct prog_src_register *srcReg) 9662861e737e84e4884109b9526ac645194ba892a74Michal Krol{ 9672861e737e84e4884109b9526ac645194ba892a74Michal Krol GLfloat sign = 1.0F; 9682861e737e84e4884109b9526ac645194ba892a74Michal Krol GLubyte token[100]; 9697c26b61f9366a397e353d7b7f1f1d1f6d0dcd0c7Keith Whitwell GLint idx; 9702861e737e84e4884109b9526ac645194ba892a74Michal Krol 9712861e737e84e4884109b9526ac645194ba892a74Michal Krol /* 9722861e737e84e4884109b9526ac645194ba892a74Michal Krol * First, take care of +/- and absolute value stuff. 9732861e737e84e4884109b9526ac645194ba892a74Michal Krol */ 9742861e737e84e4884109b9526ac645194ba892a74Michal Krol if (Parse_String(parseState, "-")) 9752861e737e84e4884109b9526ac645194ba892a74Michal Krol sign = -1.0F; 9762861e737e84e4884109b9526ac645194ba892a74Michal Krol else if (Parse_String(parseState, "+")) 9772861e737e84e4884109b9526ac645194ba892a74Michal Krol sign = +1.0F; 9782861e737e84e4884109b9526ac645194ba892a74Michal Krol 9792861e737e84e4884109b9526ac645194ba892a74Michal Krol if (Parse_String(parseState, "|")) { 9802861e737e84e4884109b9526ac645194ba892a74Michal Krol srcReg->Abs = GL_TRUE; 9812861e737e84e4884109b9526ac645194ba892a74Michal Krol srcReg->NegateAbs = (sign < 0.0F) ? GL_TRUE : GL_FALSE; 9822861e737e84e4884109b9526ac645194ba892a74Michal Krol 9832861e737e84e4884109b9526ac645194ba892a74Michal Krol if (Parse_String(parseState, "-")) 984a8c4242395b1bce0eac2a20243e5289414a9f511Brian Paul srcReg->NegateBase = NEGATE_XYZW; 9852861e737e84e4884109b9526ac645194ba892a74Michal Krol else if (Parse_String(parseState, "+")) 986a8c4242395b1bce0eac2a20243e5289414a9f511Brian Paul srcReg->NegateBase = NEGATE_NONE; 9872861e737e84e4884109b9526ac645194ba892a74Michal Krol else 988a8c4242395b1bce0eac2a20243e5289414a9f511Brian Paul srcReg->NegateBase = NEGATE_NONE; 9892861e737e84e4884109b9526ac645194ba892a74Michal Krol } 9902861e737e84e4884109b9526ac645194ba892a74Michal Krol else { 9912861e737e84e4884109b9526ac645194ba892a74Michal Krol srcReg->Abs = GL_FALSE; 9922861e737e84e4884109b9526ac645194ba892a74Michal Krol srcReg->NegateAbs = GL_FALSE; 993a8c4242395b1bce0eac2a20243e5289414a9f511Brian Paul srcReg->NegateBase = (sign < 0.0F) ? NEGATE_XYZW : NEGATE_NONE; 9942861e737e84e4884109b9526ac645194ba892a74Michal Krol } 9952861e737e84e4884109b9526ac645194ba892a74Michal Krol 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]; 1039fe1d01cb398cbcb5b28a0b222845d3865c4d612bBrian GLuint paramIndex, swizzle; 10402861e737e84e4884109b9526ac645194ba892a74Michal Krol if (!Parse_ScalarConstant(parseState, values)) 10412861e737e84e4884109b9526ac645194ba892a74Michal Krol RETURN_ERROR; 1042fe1d01cb398cbcb5b28a0b222845d3865c4d612bBrian paramIndex = _mesa_add_unnamed_constant(parseState->parameters, 1043fe1d01cb398cbcb5b28a0b222845d3865c4d612bBrian values, 4, &swizzle); 1044fe1d01cb398cbcb5b28a0b222845d3865c4d612bBrian ASSERT(swizzle == SWIZZLE_NOOP); 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]; 1051fe1d01cb398cbcb5b28a0b222845d3865c4d612bBrian GLuint paramIndex, swizzle; 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, 1056fe1d01cb398cbcb5b28a0b222845d3865c4d612bBrian values, 4, &swizzle); 1057fe1d01cb398cbcb5b28a0b222845d3865c4d612bBrian ASSERT(swizzle == SWIZZLE_NOOP); 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; 10982861e737e84e4884109b9526ac645194ba892a74Michal Krol 10992861e737e84e4884109b9526ac645194ba892a74Michal Krol /* 11002861e737e84e4884109b9526ac645194ba892a74Michal Krol * First, take care of +/- and absolute value stuff. 11012861e737e84e4884109b9526ac645194ba892a74Michal Krol */ 11022861e737e84e4884109b9526ac645194ba892a74Michal Krol if (Parse_String(parseState, "-")) 11032861e737e84e4884109b9526ac645194ba892a74Michal Krol sign = -1.0F; 11042861e737e84e4884109b9526ac645194ba892a74Michal Krol else if (Parse_String(parseState, "+")) 11052861e737e84e4884109b9526ac645194ba892a74Michal Krol sign = +1.0F; 11062861e737e84e4884109b9526ac645194ba892a74Michal Krol 11072861e737e84e4884109b9526ac645194ba892a74Michal Krol if (Parse_String(parseState, "|")) { 11082861e737e84e4884109b9526ac645194ba892a74Michal Krol srcReg->Abs = GL_TRUE; 11092861e737e84e4884109b9526ac645194ba892a74Michal Krol srcReg->NegateAbs = (sign < 0.0F) ? GL_TRUE : GL_FALSE; 11102861e737e84e4884109b9526ac645194ba892a74Michal Krol 11112861e737e84e4884109b9526ac645194ba892a74Michal Krol if (Parse_String(parseState, "-")) 1112a8c4242395b1bce0eac2a20243e5289414a9f511Brian Paul srcReg->NegateBase = NEGATE_XYZW; 11132861e737e84e4884109b9526ac645194ba892a74Michal Krol else if (Parse_String(parseState, "+")) 1114a8c4242395b1bce0eac2a20243e5289414a9f511Brian Paul srcReg->NegateBase = NEGATE_NONE; 11152861e737e84e4884109b9526ac645194ba892a74Michal Krol else 1116a8c4242395b1bce0eac2a20243e5289414a9f511Brian Paul srcReg->NegateBase = NEGATE_NONE; 11172861e737e84e4884109b9526ac645194ba892a74Michal Krol } 11182861e737e84e4884109b9526ac645194ba892a74Michal Krol else { 11192861e737e84e4884109b9526ac645194ba892a74Michal Krol srcReg->Abs = GL_FALSE; 11202861e737e84e4884109b9526ac645194ba892a74Michal Krol srcReg->NegateAbs = GL_FALSE; 1121a8c4242395b1bce0eac2a20243e5289414a9f511Brian Paul srcReg->NegateBase = (sign < 0.0F) ? NEGATE_XYZW : NEGATE_NONE; 11222861e737e84e4884109b9526ac645194ba892a74Michal Krol } 11232861e737e84e4884109b9526ac645194ba892a74Michal Krol 11242861e737e84e4884109b9526ac645194ba892a74Michal Krol if (!Peek_Token(parseState, token)) 11252861e737e84e4884109b9526ac645194ba892a74Michal Krol RETURN_ERROR; 11262861e737e84e4884109b9526ac645194ba892a74Michal Krol 11272861e737e84e4884109b9526ac645194ba892a74Michal Krol /* Src reg can be R<n>, H<n> or a named fragment attrib */ 11282861e737e84e4884109b9526ac645194ba892a74Michal Krol if (token[0] == 'R' || token[0] == 'H') { 11292861e737e84e4884109b9526ac645194ba892a74Michal Krol srcReg->File = PROGRAM_TEMPORARY; 11307c26b61f9366a397e353d7b7f1f1d1f6d0dcd0c7Keith Whitwell if (!Parse_TempReg(parseState, &idx)) 11312861e737e84e4884109b9526ac645194ba892a74Michal Krol RETURN_ERROR; 11327c26b61f9366a397e353d7b7f1f1d1f6d0dcd0c7Keith Whitwell srcReg->Index = idx; 11332861e737e84e4884109b9526ac645194ba892a74Michal Krol } 11342861e737e84e4884109b9526ac645194ba892a74Michal Krol else if (token[0] == 'f') { 11352861e737e84e4884109b9526ac645194ba892a74Michal Krol srcReg->File = PROGRAM_INPUT; 11367c26b61f9366a397e353d7b7f1f1d1f6d0dcd0c7Keith Whitwell if (!Parse_FragReg(parseState, &idx)) 11372861e737e84e4884109b9526ac645194ba892a74Michal Krol RETURN_ERROR; 11387c26b61f9366a397e353d7b7f1f1d1f6d0dcd0c7Keith Whitwell srcReg->Index = idx; 11392861e737e84e4884109b9526ac645194ba892a74Michal Krol } 11402861e737e84e4884109b9526ac645194ba892a74Michal Krol else if (token[0] == '{') { 11412861e737e84e4884109b9526ac645194ba892a74Michal Krol /* vector literal */ 11422861e737e84e4884109b9526ac645194ba892a74Michal Krol GLfloat values[4]; 1143fe1d01cb398cbcb5b28a0b222845d3865c4d612bBrian GLuint paramIndex, swizzle; 11442861e737e84e4884109b9526ac645194ba892a74Michal Krol (void) Parse_String(parseState, "{"); 11452861e737e84e4884109b9526ac645194ba892a74Michal Krol if (!Parse_VectorConstant(parseState, values)) 11462861e737e84e4884109b9526ac645194ba892a74Michal Krol RETURN_ERROR; 1147fe1d01cb398cbcb5b28a0b222845d3865c4d612bBrian paramIndex = _mesa_add_unnamed_constant(parseState->parameters, 1148fe1d01cb398cbcb5b28a0b222845d3865c4d612bBrian values, 4, &swizzle); 1149fe1d01cb398cbcb5b28a0b222845d3865c4d612bBrian ASSERT(swizzle == SWIZZLE_NOOP); 11502861e737e84e4884109b9526ac645194ba892a74Michal Krol srcReg->File = PROGRAM_NAMED_PARAM; 11512861e737e84e4884109b9526ac645194ba892a74Michal Krol srcReg->Index = paramIndex; 11522861e737e84e4884109b9526ac645194ba892a74Michal Krol } 1153e6940f0a33a571b199bab60b680c30b718c47445Brian Paul else if (IsLetter(token[0])){ 1154e6940f0a33a571b199bab60b680c30b718c47445Brian Paul /* named param/constant */ 1155e6940f0a33a571b199bab60b680c30b718c47445Brian Paul GLubyte ident[100]; 1156e6940f0a33a571b199bab60b680c30b718c47445Brian Paul GLint paramIndex; 1157e6940f0a33a571b199bab60b680c30b718c47445Brian Paul if (!Parse_Identifier(parseState, ident)) 1158e6940f0a33a571b199bab60b680c30b718c47445Brian Paul RETURN_ERROR; 1159e6940f0a33a571b199bab60b680c30b718c47445Brian Paul paramIndex = _mesa_lookup_parameter_index(parseState->parameters, 1160e6940f0a33a571b199bab60b680c30b718c47445Brian Paul -1, (const char *) ident); 1161e6940f0a33a571b199bab60b680c30b718c47445Brian Paul if (paramIndex < 0) { 1162e6940f0a33a571b199bab60b680c30b718c47445Brian Paul RETURN_ERROR2("Undefined constant or parameter: ", ident); 1163e6940f0a33a571b199bab60b680c30b718c47445Brian Paul } 1164e6940f0a33a571b199bab60b680c30b718c47445Brian Paul srcReg->File = PROGRAM_NAMED_PARAM; 1165e6940f0a33a571b199bab60b680c30b718c47445Brian Paul srcReg->Index = paramIndex; 1166e6940f0a33a571b199bab60b680c30b718c47445Brian Paul } 11672861e737e84e4884109b9526ac645194ba892a74Michal Krol else if (IsDigit(token[0])) { 11682861e737e84e4884109b9526ac645194ba892a74Michal Krol /* scalar literal */ 11692861e737e84e4884109b9526ac645194ba892a74Michal Krol GLfloat values[4]; 1170fe1d01cb398cbcb5b28a0b222845d3865c4d612bBrian GLuint paramIndex, swizzle; 11712861e737e84e4884109b9526ac645194ba892a74Michal Krol if (!Parse_ScalarConstant(parseState, values)) 11722861e737e84e4884109b9526ac645194ba892a74Michal Krol RETURN_ERROR; 1173fe1d01cb398cbcb5b28a0b222845d3865c4d612bBrian paramIndex = _mesa_add_unnamed_constant(parseState->parameters, 1174fe1d01cb398cbcb5b28a0b222845d3865c4d612bBrian values, 4, &swizzle); 1175fe1d01cb398cbcb5b28a0b222845d3865c4d612bBrian ASSERT(swizzle == SWIZZLE_NOOP); 11762861e737e84e4884109b9526ac645194ba892a74Michal Krol srcReg->Index = paramIndex; 11772861e737e84e4884109b9526ac645194ba892a74Michal Krol srcReg->File = PROGRAM_NAMED_PARAM; 11782861e737e84e4884109b9526ac645194ba892a74Michal Krol needSuffix = GL_FALSE; 11792861e737e84e4884109b9526ac645194ba892a74Michal Krol } 11802861e737e84e4884109b9526ac645194ba892a74Michal Krol else { 11812861e737e84e4884109b9526ac645194ba892a74Michal Krol RETURN_ERROR2("Invalid scalar source argument", token); 11822861e737e84e4884109b9526ac645194ba892a74Michal Krol } 11832861e737e84e4884109b9526ac645194ba892a74Michal Krol 11847c26b61f9366a397e353d7b7f1f1d1f6d0dcd0c7Keith Whitwell srcReg->Swizzle = 0; 11852861e737e84e4884109b9526ac645194ba892a74Michal Krol if (needSuffix) { 11862861e737e84e4884109b9526ac645194ba892a74Michal Krol /* parse .[xyzw] suffix */ 11872861e737e84e4884109b9526ac645194ba892a74Michal Krol if (!Parse_String(parseState, ".")) 11882861e737e84e4884109b9526ac645194ba892a74Michal Krol RETURN_ERROR1("Expected ."); 11892861e737e84e4884109b9526ac645194ba892a74Michal Krol 11902861e737e84e4884109b9526ac645194ba892a74Michal Krol if (!Parse_Token(parseState, token)) 11912861e737e84e4884109b9526ac645194ba892a74Michal Krol RETURN_ERROR; 11922861e737e84e4884109b9526ac645194ba892a74Michal Krol 11932861e737e84e4884109b9526ac645194ba892a74Michal Krol if (token[0] == 'x' && token[1] == 0) { 11947c26b61f9366a397e353d7b7f1f1d1f6d0dcd0c7Keith Whitwell srcReg->Swizzle = 0; 11952861e737e84e4884109b9526ac645194ba892a74Michal Krol } 11962861e737e84e4884109b9526ac645194ba892a74Michal Krol else if (token[0] == 'y' && token[1] == 0) { 11977c26b61f9366a397e353d7b7f1f1d1f6d0dcd0c7Keith Whitwell srcReg->Swizzle = 1; 11982861e737e84e4884109b9526ac645194ba892a74Michal Krol } 11992861e737e84e4884109b9526ac645194ba892a74Michal Krol else if (token[0] == 'z' && token[1] == 0) { 12007c26b61f9366a397e353d7b7f1f1d1f6d0dcd0c7Keith Whitwell srcReg->Swizzle = 2; 12012861e737e84e4884109b9526ac645194ba892a74Michal Krol } 12022861e737e84e4884109b9526ac645194ba892a74Michal Krol else if (token[0] == 'w' && token[1] == 0) { 12037c26b61f9366a397e353d7b7f1f1d1f6d0dcd0c7Keith Whitwell srcReg->Swizzle = 3; 12042861e737e84e4884109b9526ac645194ba892a74Michal Krol } 12052861e737e84e4884109b9526ac645194ba892a74Michal Krol else { 12062861e737e84e4884109b9526ac645194ba892a74Michal Krol RETURN_ERROR1("Invalid scalar source suffix"); 12072861e737e84e4884109b9526ac645194ba892a74Michal Krol } 12082861e737e84e4884109b9526ac645194ba892a74Michal Krol } 12092861e737e84e4884109b9526ac645194ba892a74Michal Krol 12102861e737e84e4884109b9526ac645194ba892a74Michal Krol /* Finish absolute value */ 12112861e737e84e4884109b9526ac645194ba892a74Michal Krol if (srcReg->Abs && !Parse_String(parseState, "|")) { 12122861e737e84e4884109b9526ac645194ba892a74Michal Krol RETURN_ERROR1("Expected |"); 12132861e737e84e4884109b9526ac645194ba892a74Michal Krol } 12142861e737e84e4884109b9526ac645194ba892a74Michal Krol 12152861e737e84e4884109b9526ac645194ba892a74Michal Krol return GL_TRUE; 12162861e737e84e4884109b9526ac645194ba892a74Michal Krol} 12172861e737e84e4884109b9526ac645194ba892a74Michal Krol 12182861e737e84e4884109b9526ac645194ba892a74Michal Krol 12192a5afe3ab8d4c3624ed72b99a11b6a9017078d1cBrian Paulstatic GLboolean 12202a5afe3ab8d4c3624ed72b99a11b6a9017078d1cBrian PaulParse_PrintInstruction(struct parse_state *parseState, 12217e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul struct prog_instruction *inst) 12222a5afe3ab8d4c3624ed72b99a11b6a9017078d1cBrian Paul{ 12232a5afe3ab8d4c3624ed72b99a11b6a9017078d1cBrian Paul const GLubyte *str; 12242a5afe3ab8d4c3624ed72b99a11b6a9017078d1cBrian Paul GLubyte *msg; 12252a5afe3ab8d4c3624ed72b99a11b6a9017078d1cBrian Paul GLuint len; 12267c26b61f9366a397e353d7b7f1f1d1f6d0dcd0c7Keith Whitwell GLint idx; 12272a5afe3ab8d4c3624ed72b99a11b6a9017078d1cBrian Paul 12282a5afe3ab8d4c3624ed72b99a11b6a9017078d1cBrian Paul /* The first argument is a literal string 'just like this' */ 12292a5afe3ab8d4c3624ed72b99a11b6a9017078d1cBrian Paul if (!Parse_String(parseState, "'")) 12302a5afe3ab8d4c3624ed72b99a11b6a9017078d1cBrian Paul RETURN_ERROR1("Expected '"); 12312a5afe3ab8d4c3624ed72b99a11b6a9017078d1cBrian Paul 12322a5afe3ab8d4c3624ed72b99a11b6a9017078d1cBrian Paul str = parseState->pos; 12332a5afe3ab8d4c3624ed72b99a11b6a9017078d1cBrian Paul for (len = 0; str[len] != '\''; len++) /* find closing quote */ 12342a5afe3ab8d4c3624ed72b99a11b6a9017078d1cBrian Paul ; 12352a5afe3ab8d4c3624ed72b99a11b6a9017078d1cBrian Paul parseState->pos += len + 1; 12369580179dfb42d5b81ff6ec9704b82a556c7f1229Brian Paul msg = (GLubyte*) _mesa_malloc(len + 1); 12372a5afe3ab8d4c3624ed72b99a11b6a9017078d1cBrian Paul 12382a5afe3ab8d4c3624ed72b99a11b6a9017078d1cBrian Paul _mesa_memcpy(msg, str, len); 12392a5afe3ab8d4c3624ed72b99a11b6a9017078d1cBrian Paul msg[len] = 0; 12402a5afe3ab8d4c3624ed72b99a11b6a9017078d1cBrian Paul inst->Data = msg; 12412a5afe3ab8d4c3624ed72b99a11b6a9017078d1cBrian Paul 12422a5afe3ab8d4c3624ed72b99a11b6a9017078d1cBrian Paul if (Parse_String(parseState, ",")) { 12432a5afe3ab8d4c3624ed72b99a11b6a9017078d1cBrian Paul /* got an optional register to print */ 12442a5afe3ab8d4c3624ed72b99a11b6a9017078d1cBrian Paul GLubyte token[100]; 12452a5afe3ab8d4c3624ed72b99a11b6a9017078d1cBrian Paul GetToken(parseState, token); 12462a5afe3ab8d4c3624ed72b99a11b6a9017078d1cBrian Paul if (token[0] == 'o') { 12472a5afe3ab8d4c3624ed72b99a11b6a9017078d1cBrian Paul /* dst reg */ 12487c26b61f9366a397e353d7b7f1f1d1f6d0dcd0c7Keith Whitwell if (!Parse_OutputReg(parseState, &idx)) 12492a5afe3ab8d4c3624ed72b99a11b6a9017078d1cBrian Paul RETURN_ERROR; 12507c26b61f9366a397e353d7b7f1f1d1f6d0dcd0c7Keith Whitwell inst->SrcReg[0].Index = idx; 12512a5afe3ab8d4c3624ed72b99a11b6a9017078d1cBrian Paul inst->SrcReg[0].File = PROGRAM_OUTPUT; 12522a5afe3ab8d4c3624ed72b99a11b6a9017078d1cBrian Paul } 12532a5afe3ab8d4c3624ed72b99a11b6a9017078d1cBrian Paul else { 12542a5afe3ab8d4c3624ed72b99a11b6a9017078d1cBrian Paul /* src reg */ 12552a5afe3ab8d4c3624ed72b99a11b6a9017078d1cBrian Paul if (!Parse_VectorSrc(parseState, &inst->SrcReg[0])) 12562a5afe3ab8d4c3624ed72b99a11b6a9017078d1cBrian Paul RETURN_ERROR; 12572a5afe3ab8d4c3624ed72b99a11b6a9017078d1cBrian Paul } 12582a5afe3ab8d4c3624ed72b99a11b6a9017078d1cBrian Paul } 12592a5afe3ab8d4c3624ed72b99a11b6a9017078d1cBrian Paul else { 12608cdf3729468aefb7c67c8ecd32fd850adbf6d351Brian Paul inst->SrcReg[0].File = PROGRAM_UNDEFINED; 12612a5afe3ab8d4c3624ed72b99a11b6a9017078d1cBrian Paul } 12622a5afe3ab8d4c3624ed72b99a11b6a9017078d1cBrian Paul 12637c26b61f9366a397e353d7b7f1f1d1f6d0dcd0c7Keith Whitwell inst->SrcReg[0].Swizzle = SWIZZLE_NOOP; 1264a8c4242395b1bce0eac2a20243e5289414a9f511Brian Paul inst->SrcReg[0].NegateBase = NEGATE_NONE; 12652a5afe3ab8d4c3624ed72b99a11b6a9017078d1cBrian Paul inst->SrcReg[0].Abs = GL_FALSE; 12662a5afe3ab8d4c3624ed72b99a11b6a9017078d1cBrian Paul inst->SrcReg[0].NegateAbs = GL_FALSE; 12672a5afe3ab8d4c3624ed72b99a11b6a9017078d1cBrian Paul 12682a5afe3ab8d4c3624ed72b99a11b6a9017078d1cBrian Paul return GL_TRUE; 12692a5afe3ab8d4c3624ed72b99a11b6a9017078d1cBrian Paul} 12702a5afe3ab8d4c3624ed72b99a11b6a9017078d1cBrian Paul 12712861e737e84e4884109b9526ac645194ba892a74Michal Krol 12722861e737e84e4884109b9526ac645194ba892a74Michal Krolstatic GLboolean 12732861e737e84e4884109b9526ac645194ba892a74Michal KrolParse_InstructionSequence(struct parse_state *parseState, 12747e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul struct prog_instruction program[]) 12752861e737e84e4884109b9526ac645194ba892a74Michal Krol{ 12762861e737e84e4884109b9526ac645194ba892a74Michal Krol while (1) { 12777e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul struct prog_instruction *inst = program + parseState->numInst; 12782861e737e84e4884109b9526ac645194ba892a74Michal Krol struct instruction_pattern instMatch; 12792861e737e84e4884109b9526ac645194ba892a74Michal Krol GLubyte token[100]; 12802861e737e84e4884109b9526ac645194ba892a74Michal Krol 12812861e737e84e4884109b9526ac645194ba892a74Michal Krol /* Initialize the instruction */ 1282d6272e06172f7ac7a0d6e8062e8ffba33e1ab3baBrian Paul _mesa_init_instructions(inst, 1); 12832861e737e84e4884109b9526ac645194ba892a74Michal Krol 12842861e737e84e4884109b9526ac645194ba892a74Michal Krol /* special instructions */ 12852861e737e84e4884109b9526ac645194ba892a74Michal Krol if (Parse_String(parseState, "DEFINE")) { 12862861e737e84e4884109b9526ac645194ba892a74Michal Krol GLubyte id[100]; 12872861e737e84e4884109b9526ac645194ba892a74Michal Krol GLfloat value[7]; /* yes, 7 to be safe */ 12882861e737e84e4884109b9526ac645194ba892a74Michal Krol if (!Parse_Identifier(parseState, id)) 12892861e737e84e4884109b9526ac645194ba892a74Michal Krol RETURN_ERROR; 12902861e737e84e4884109b9526ac645194ba892a74Michal Krol /* XXX make sure id is not a reserved identifer, like R9 */ 12912861e737e84e4884109b9526ac645194ba892a74Michal Krol if (!Parse_String(parseState, "=")) 12922861e737e84e4884109b9526ac645194ba892a74Michal Krol RETURN_ERROR1("Expected ="); 12932861e737e84e4884109b9526ac645194ba892a74Michal Krol if (!Parse_VectorOrScalarConstant(parseState, value)) 12942861e737e84e4884109b9526ac645194ba892a74Michal Krol RETURN_ERROR; 12952861e737e84e4884109b9526ac645194ba892a74Michal Krol if (!Parse_String(parseState, ";")) 12962861e737e84e4884109b9526ac645194ba892a74Michal Krol RETURN_ERROR1("Expected ;"); 12972861e737e84e4884109b9526ac645194ba892a74Michal Krol if (_mesa_lookup_parameter_index(parseState->parameters, 12982861e737e84e4884109b9526ac645194ba892a74Michal Krol -1, (const char *) id) >= 0) { 12992861e737e84e4884109b9526ac645194ba892a74Michal Krol RETURN_ERROR2(id, "already defined"); 13002861e737e84e4884109b9526ac645194ba892a74Michal Krol } 13012861e737e84e4884109b9526ac645194ba892a74Michal Krol _mesa_add_named_parameter(parseState->parameters, 13022861e737e84e4884109b9526ac645194ba892a74Michal Krol (const char *) id, value); 13032861e737e84e4884109b9526ac645194ba892a74Michal Krol } 13042861e737e84e4884109b9526ac645194ba892a74Michal Krol else if (Parse_String(parseState, "DECLARE")) { 13052861e737e84e4884109b9526ac645194ba892a74Michal Krol GLubyte id[100]; 13062861e737e84e4884109b9526ac645194ba892a74Michal Krol GLfloat value[7] = {0, 0, 0, 0, 0, 0, 0}; /* yes, to be safe */ 13072861e737e84e4884109b9526ac645194ba892a74Michal Krol if (!Parse_Identifier(parseState, id)) 13082861e737e84e4884109b9526ac645194ba892a74Michal Krol RETURN_ERROR; 13092861e737e84e4884109b9526ac645194ba892a74Michal Krol /* XXX make sure id is not a reserved identifer, like R9 */ 13102861e737e84e4884109b9526ac645194ba892a74Michal Krol if (Parse_String(parseState, "=")) { 13112861e737e84e4884109b9526ac645194ba892a74Michal Krol if (!Parse_VectorOrScalarConstant(parseState, value)) 13122861e737e84e4884109b9526ac645194ba892a74Michal Krol RETURN_ERROR; 13132861e737e84e4884109b9526ac645194ba892a74Michal Krol } 13142861e737e84e4884109b9526ac645194ba892a74Michal Krol if (!Parse_String(parseState, ";")) 13152861e737e84e4884109b9526ac645194ba892a74Michal Krol RETURN_ERROR1("Expected ;"); 13162861e737e84e4884109b9526ac645194ba892a74Michal Krol if (_mesa_lookup_parameter_index(parseState->parameters, 13172861e737e84e4884109b9526ac645194ba892a74Michal Krol -1, (const char *) id) >= 0) { 13182861e737e84e4884109b9526ac645194ba892a74Michal Krol RETURN_ERROR2(id, "already declared"); 13192861e737e84e4884109b9526ac645194ba892a74Michal Krol } 13202861e737e84e4884109b9526ac645194ba892a74Michal Krol _mesa_add_named_parameter(parseState->parameters, 13212861e737e84e4884109b9526ac645194ba892a74Michal Krol (const char *) id, value); 13222861e737e84e4884109b9526ac645194ba892a74Michal Krol } 13232861e737e84e4884109b9526ac645194ba892a74Michal Krol else if (Parse_String(parseState, "END")) { 13247e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul inst->Opcode = OPCODE_END; 13252861e737e84e4884109b9526ac645194ba892a74Michal Krol inst->StringPos = parseState->curLine - parseState->start; 13262861e737e84e4884109b9526ac645194ba892a74Michal Krol assert(inst->StringPos >= 0); 13272861e737e84e4884109b9526ac645194ba892a74Michal Krol parseState->numInst++; 13282861e737e84e4884109b9526ac645194ba892a74Michal Krol if (Parse_Token(parseState, token)) { 13292861e737e84e4884109b9526ac645194ba892a74Michal Krol RETURN_ERROR1("Code after END opcode."); 13302861e737e84e4884109b9526ac645194ba892a74Michal Krol } 13312861e737e84e4884109b9526ac645194ba892a74Michal Krol break; 13322861e737e84e4884109b9526ac645194ba892a74Michal Krol } 13332861e737e84e4884109b9526ac645194ba892a74Michal Krol else { 13342861e737e84e4884109b9526ac645194ba892a74Michal Krol /* general/arithmetic instruction */ 13352861e737e84e4884109b9526ac645194ba892a74Michal Krol 13362861e737e84e4884109b9526ac645194ba892a74Michal Krol /* get token */ 13372861e737e84e4884109b9526ac645194ba892a74Michal Krol if (!Parse_Token(parseState, token)) { 13382861e737e84e4884109b9526ac645194ba892a74Michal Krol RETURN_ERROR1("Missing END instruction."); 13392861e737e84e4884109b9526ac645194ba892a74Michal Krol } 13402861e737e84e4884109b9526ac645194ba892a74Michal Krol 13412861e737e84e4884109b9526ac645194ba892a74Michal Krol /* try to find matching instuction */ 13422861e737e84e4884109b9526ac645194ba892a74Michal Krol instMatch = MatchInstruction(token); 134328b014ee256290eb0494b967e40c475c0c895f57Brian Paul if (instMatch.opcode >= MAX_OPCODE) { 13442861e737e84e4884109b9526ac645194ba892a74Michal Krol /* bad instruction name */ 13452861e737e84e4884109b9526ac645194ba892a74Michal Krol RETURN_ERROR2("Unexpected token: ", token); 13462861e737e84e4884109b9526ac645194ba892a74Michal Krol } 13472861e737e84e4884109b9526ac645194ba892a74Michal Krol 13482861e737e84e4884109b9526ac645194ba892a74Michal Krol inst->Opcode = instMatch.opcode; 13492861e737e84e4884109b9526ac645194ba892a74Michal Krol inst->Precision = instMatch.suffixes & (_R | _H | _X); 1350e31ac052236ea615b4995f9ec301d8af4b864531Brian Paul inst->SaturateMode = (instMatch.suffixes & (_S)) 1351e31ac052236ea615b4995f9ec301d8af4b864531Brian Paul ? SATURATE_ZERO_ONE : SATURATE_OFF; 13527e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul inst->CondUpdate = (instMatch.suffixes & (_C)) ? GL_TRUE : GL_FALSE; 13532861e737e84e4884109b9526ac645194ba892a74Michal Krol inst->StringPos = parseState->curLine - parseState->start; 13542861e737e84e4884109b9526ac645194ba892a74Michal Krol assert(inst->StringPos >= 0); 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 14732861e737e84e4884109b9526ac645194ba892a74Michal Krol_mesa_parse_nv_fragment_program(GLcontext *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 } 14892861e737e84e4884109b9526ac645194ba892a74Michal Krol MEMCPY(programString, str, len); 14902861e737e84e4884109b9526ac645194ba892a74Michal Krol programString[len] = 0; 14912861e737e84e4884109b9526ac645194ba892a74Michal Krol 14922861e737e84e4884109b9526ac645194ba892a74Michal Krol /* Get ready to parse */ 14932861e737e84e4884109b9526ac645194ba892a74Michal Krol _mesa_bzero(&parseState, 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 */ 15052861e737e84e4884109b9526ac645194ba892a74Michal Krol if (_mesa_strncmp((const char *) programString, "!!FP1.0", 7) == 0) { 15062861e737e84e4884109b9526ac645194ba892a74Michal Krol target = GL_FRAGMENT_PROGRAM_NV; 15072861e737e84e4884109b9526ac645194ba892a74Michal Krol parseState.pos = programString + 7; 15082861e737e84e4884109b9526ac645194ba892a74Michal Krol } 15092861e737e84e4884109b9526ac645194ba892a74Michal Krol else if (_mesa_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 } 1548383c39e58e0ab888afac473526109b62ec0f8f6fBrian Paul _mesa_memcpy(newInst, instBuffer, 1549383c39e58e0ab888afac473526109b62ec0f8f6fBrian Paul parseState.numInst * sizeof(struct prog_instruction)); 15502861e737e84e4884109b9526ac645194ba892a74Michal Krol 15512861e737e84e4884109b9526ac645194ba892a74Michal Krol /* install the program */ 15522861e737e84e4884109b9526ac645194ba892a74Michal Krol program->Base.Target = target; 15532861e737e84e4884109b9526ac645194ba892a74Michal Krol if (program->Base.String) { 15542861e737e84e4884109b9526ac645194ba892a74Michal Krol FREE(program->Base.String); 15552861e737e84e4884109b9526ac645194ba892a74Michal Krol } 15562861e737e84e4884109b9526ac645194ba892a74Michal Krol program->Base.String = programString; 15572861e737e84e4884109b9526ac645194ba892a74Michal Krol program->Base.Format = GL_PROGRAM_FORMAT_ASCII_ARB; 1558de99760bf3511d05185799c4fb4347f9e5f420f4Brian Paul if (program->Base.Instructions) { 1559de99760bf3511d05185799c4fb4347f9e5f420f4Brian Paul _mesa_free(program->Base.Instructions); 15602861e737e84e4884109b9526ac645194ba892a74Michal Krol } 1561de99760bf3511d05185799c4fb4347f9e5f420f4Brian Paul program->Base.Instructions = newInst; 1562ee40c4fb34bd06ecc6dd6f2e658ca2c2c20af952Brian Paul program->Base.NumInstructions = parseState.numInst; 1563de99760bf3511d05185799c4fb4347f9e5f420f4Brian Paul program->Base.InputsRead = parseState.inputsRead; 1564de99760bf3511d05185799c4fb4347f9e5f420f4Brian Paul program->Base.OutputsWritten = parseState.outputsWritten; 15652861e737e84e4884109b9526ac645194ba892a74Michal Krol for (u = 0; u < ctx->Const.MaxTextureImageUnits; u++) 1566c9db223f902ce9d7e9f3038e6baac6da7f231b34Brian program->Base.TexturesUsed[u] = parseState.texturesUsed[u]; 15672861e737e84e4884109b9526ac645194ba892a74Michal Krol 15682861e737e84e4884109b9526ac645194ba892a74Michal Krol /* save program parameters */ 1569de99760bf3511d05185799c4fb4347f9e5f420f4Brian Paul program->Base.Parameters = parseState.parameters; 15702861e737e84e4884109b9526ac645194ba892a74Michal Krol 15712861e737e84e4884109b9526ac645194ba892a74Michal Krol /* allocate registers for declared program parameters */ 15722861e737e84e4884109b9526ac645194ba892a74Michal Krol#if 00 15732861e737e84e4884109b9526ac645194ba892a74Michal Krol _mesa_assign_program_registers(&(program->SymbolTable)); 15742861e737e84e4884109b9526ac645194ba892a74Michal Krol#endif 15752861e737e84e4884109b9526ac645194ba892a74Michal Krol 1576ac33dd1312530e0bab0c7e5d25c9d70f4e884753Brian Paul#ifdef DEBUG_foo 15772861e737e84e4884109b9526ac645194ba892a74Michal Krol _mesa_printf("--- glLoadProgramNV(%d) result ---\n", program->Base.Id); 15782861e737e84e4884109b9526ac645194ba892a74Michal Krol _mesa_print_nv_fragment_program(program); 15792861e737e84e4884109b9526ac645194ba892a74Michal Krol _mesa_printf("----------------------------------\n"); 15802861e737e84e4884109b9526ac645194ba892a74Michal Krol#endif 15812861e737e84e4884109b9526ac645194ba892a74Michal Krol } 15822861e737e84e4884109b9526ac645194ba892a74Michal Krol else { 15832861e737e84e4884109b9526ac645194ba892a74Michal Krol /* Error! */ 15842861e737e84e4884109b9526ac645194ba892a74Michal Krol _mesa_error(ctx, GL_INVALID_OPERATION, "glLoadProgramNV"); 15852861e737e84e4884109b9526ac645194ba892a74Michal Krol /* NOTE: _mesa_set_program_error would have been called already */ 15862861e737e84e4884109b9526ac645194ba892a74Michal Krol } 15872861e737e84e4884109b9526ac645194ba892a74Michal Krol} 15882861e737e84e4884109b9526ac645194ba892a74Michal Krol 15892861e737e84e4884109b9526ac645194ba892a74Michal Krol 15902861e737e84e4884109b9526ac645194ba892a74Michal Krolstatic void 1591122629f27925a9dc50029bebc5079f87f416a7e1Brian PaulPrintSrcReg(const struct gl_fragment_program *program, 15927e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul const struct prog_src_register *src) 15932861e737e84e4884109b9526ac645194ba892a74Michal Krol{ 15942861e737e84e4884109b9526ac645194ba892a74Michal Krol static const char comps[5] = "xyzw"; 15952861e737e84e4884109b9526ac645194ba892a74Michal Krol 15962861e737e84e4884109b9526ac645194ba892a74Michal Krol if (src->NegateAbs) { 15972861e737e84e4884109b9526ac645194ba892a74Michal Krol _mesa_printf("-"); 15982861e737e84e4884109b9526ac645194ba892a74Michal Krol } 15992861e737e84e4884109b9526ac645194ba892a74Michal Krol if (src->Abs) { 16002861e737e84e4884109b9526ac645194ba892a74Michal Krol _mesa_printf("|"); 16012861e737e84e4884109b9526ac645194ba892a74Michal Krol } 16022861e737e84e4884109b9526ac645194ba892a74Michal Krol if (src->NegateBase) { 16032861e737e84e4884109b9526ac645194ba892a74Michal Krol _mesa_printf("-"); 16042861e737e84e4884109b9526ac645194ba892a74Michal Krol } 16052861e737e84e4884109b9526ac645194ba892a74Michal Krol if (src->File == PROGRAM_NAMED_PARAM) { 1606de99760bf3511d05185799c4fb4347f9e5f420f4Brian Paul if (program->Base.Parameters->Parameters[src->Index].Type 1607de99760bf3511d05185799c4fb4347f9e5f420f4Brian Paul == PROGRAM_CONSTANT) { 1608de99760bf3511d05185799c4fb4347f9e5f420f4Brian Paul const GLfloat *v; 1609de99760bf3511d05185799c4fb4347f9e5f420f4Brian Paul v = program->Base.Parameters->ParameterValues[src->Index]; 1610de99760bf3511d05185799c4fb4347f9e5f420f4Brian Paul _mesa_printf("{%g, %g, %g, %g}", v[0], v[1], v[2], v[3]); 16112861e737e84e4884109b9526ac645194ba892a74Michal Krol } 16122861e737e84e4884109b9526ac645194ba892a74Michal Krol else { 1613bed8363aa6ab9f3dbd8052acc8c12d3de14f1399Brian Paul ASSERT(program->Base.Parameters->Parameters[src->Index].Type 1614613e1ad5d517d9964bd9cf94daa931dda33113feBrian Paul == PROGRAM_NAMED_PARAM); 1615de99760bf3511d05185799c4fb4347f9e5f420f4Brian Paul _mesa_printf("%s", program->Base.Parameters->Parameters[src->Index].Name); 16162861e737e84e4884109b9526ac645194ba892a74Michal Krol } 16172861e737e84e4884109b9526ac645194ba892a74Michal Krol } 16182861e737e84e4884109b9526ac645194ba892a74Michal Krol else if (src->File == PROGRAM_OUTPUT) { 16192861e737e84e4884109b9526ac645194ba892a74Michal Krol _mesa_printf("o[%s]", OutputRegisters[src->Index]); 16202861e737e84e4884109b9526ac645194ba892a74Michal Krol } 16212861e737e84e4884109b9526ac645194ba892a74Michal Krol else if (src->File == PROGRAM_INPUT) { 16222861e737e84e4884109b9526ac645194ba892a74Michal Krol _mesa_printf("f[%s]", InputRegisters[src->Index]); 16232861e737e84e4884109b9526ac645194ba892a74Michal Krol } 16242861e737e84e4884109b9526ac645194ba892a74Michal Krol else if (src->File == PROGRAM_LOCAL_PARAM) { 16252861e737e84e4884109b9526ac645194ba892a74Michal Krol _mesa_printf("p[%d]", src->Index); 16262861e737e84e4884109b9526ac645194ba892a74Michal Krol } 16272861e737e84e4884109b9526ac645194ba892a74Michal Krol else if (src->File == PROGRAM_TEMPORARY) { 16282861e737e84e4884109b9526ac645194ba892a74Michal Krol if (src->Index >= 32) 16292861e737e84e4884109b9526ac645194ba892a74Michal Krol _mesa_printf("H%d", src->Index); 16302861e737e84e4884109b9526ac645194ba892a74Michal Krol else 16312861e737e84e4884109b9526ac645194ba892a74Michal Krol _mesa_printf("R%d", src->Index); 16322861e737e84e4884109b9526ac645194ba892a74Michal Krol } 16332861e737e84e4884109b9526ac645194ba892a74Michal Krol else if (src->File == PROGRAM_WRITE_ONLY) { 16342861e737e84e4884109b9526ac645194ba892a74Michal Krol _mesa_printf("%cC", "HR"[src->Index]); 16352861e737e84e4884109b9526ac645194ba892a74Michal Krol } 16362861e737e84e4884109b9526ac645194ba892a74Michal Krol else { 16372861e737e84e4884109b9526ac645194ba892a74Michal Krol _mesa_problem(NULL, "Invalid fragment register %d", src->Index); 16382861e737e84e4884109b9526ac645194ba892a74Michal Krol return; 16392861e737e84e4884109b9526ac645194ba892a74Michal Krol } 16407c26b61f9366a397e353d7b7f1f1d1f6d0dcd0c7Keith Whitwell if (GET_SWZ(src->Swizzle, 0) == GET_SWZ(src->Swizzle, 1) && 16417c26b61f9366a397e353d7b7f1f1d1f6d0dcd0c7Keith Whitwell GET_SWZ(src->Swizzle, 0) == GET_SWZ(src->Swizzle, 2) && 16427c26b61f9366a397e353d7b7f1f1d1f6d0dcd0c7Keith Whitwell GET_SWZ(src->Swizzle, 0) == GET_SWZ(src->Swizzle, 3)) { 16437c26b61f9366a397e353d7b7f1f1d1f6d0dcd0c7Keith Whitwell _mesa_printf(".%c", comps[GET_SWZ(src->Swizzle, 0)]); 16442861e737e84e4884109b9526ac645194ba892a74Michal Krol } 16457c26b61f9366a397e353d7b7f1f1d1f6d0dcd0c7Keith Whitwell else if (src->Swizzle != SWIZZLE_NOOP) { 16462861e737e84e4884109b9526ac645194ba892a74Michal Krol _mesa_printf(".%c%c%c%c", 16477c26b61f9366a397e353d7b7f1f1d1f6d0dcd0c7Keith Whitwell comps[GET_SWZ(src->Swizzle, 0)], 16487c26b61f9366a397e353d7b7f1f1d1f6d0dcd0c7Keith Whitwell comps[GET_SWZ(src->Swizzle, 1)], 16497c26b61f9366a397e353d7b7f1f1d1f6d0dcd0c7Keith Whitwell comps[GET_SWZ(src->Swizzle, 2)], 16507c26b61f9366a397e353d7b7f1f1d1f6d0dcd0c7Keith Whitwell comps[GET_SWZ(src->Swizzle, 3)]); 16512861e737e84e4884109b9526ac645194ba892a74Michal Krol } 16522861e737e84e4884109b9526ac645194ba892a74Michal Krol if (src->Abs) { 16532861e737e84e4884109b9526ac645194ba892a74Michal Krol _mesa_printf("|"); 16542861e737e84e4884109b9526ac645194ba892a74Michal Krol } 16552861e737e84e4884109b9526ac645194ba892a74Michal Krol} 16562861e737e84e4884109b9526ac645194ba892a74Michal Krol 16572861e737e84e4884109b9526ac645194ba892a74Michal Krolstatic void 16587e807510d8c3e88ee7ae6c697393201cf08f992fBrian PaulPrintTextureSrc(const struct prog_instruction *inst) 16592861e737e84e4884109b9526ac645194ba892a74Michal Krol{ 16602861e737e84e4884109b9526ac645194ba892a74Michal Krol _mesa_printf("TEX%d, ", inst->TexSrcUnit); 16617e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul switch (inst->TexSrcTarget) { 16627c26b61f9366a397e353d7b7f1f1d1f6d0dcd0c7Keith Whitwell case TEXTURE_1D_INDEX: 16632861e737e84e4884109b9526ac645194ba892a74Michal Krol _mesa_printf("1D"); 16642861e737e84e4884109b9526ac645194ba892a74Michal Krol break; 16657c26b61f9366a397e353d7b7f1f1d1f6d0dcd0c7Keith Whitwell case TEXTURE_2D_INDEX: 16662861e737e84e4884109b9526ac645194ba892a74Michal Krol _mesa_printf("2D"); 16672861e737e84e4884109b9526ac645194ba892a74Michal Krol break; 16687c26b61f9366a397e353d7b7f1f1d1f6d0dcd0c7Keith Whitwell case TEXTURE_3D_INDEX: 16692861e737e84e4884109b9526ac645194ba892a74Michal Krol _mesa_printf("3D"); 16702861e737e84e4884109b9526ac645194ba892a74Michal Krol break; 16717c26b61f9366a397e353d7b7f1f1d1f6d0dcd0c7Keith Whitwell case TEXTURE_RECT_INDEX: 16722861e737e84e4884109b9526ac645194ba892a74Michal Krol _mesa_printf("RECT"); 16732861e737e84e4884109b9526ac645194ba892a74Michal Krol break; 16747c26b61f9366a397e353d7b7f1f1d1f6d0dcd0c7Keith Whitwell case TEXTURE_CUBE_INDEX: 16752861e737e84e4884109b9526ac645194ba892a74Michal Krol _mesa_printf("CUBE"); 16762861e737e84e4884109b9526ac645194ba892a74Michal Krol break; 16772861e737e84e4884109b9526ac645194ba892a74Michal Krol default: 16782861e737e84e4884109b9526ac645194ba892a74Michal Krol _mesa_problem(NULL, "Invalid textue target in PrintTextureSrc"); 16792861e737e84e4884109b9526ac645194ba892a74Michal Krol } 16802861e737e84e4884109b9526ac645194ba892a74Michal Krol} 16812861e737e84e4884109b9526ac645194ba892a74Michal Krol 16822861e737e84e4884109b9526ac645194ba892a74Michal Krolstatic void 16837e807510d8c3e88ee7ae6c697393201cf08f992fBrian PaulPrintCondCode(const struct prog_dst_register *dst) 16842861e737e84e4884109b9526ac645194ba892a74Michal Krol{ 16852861e737e84e4884109b9526ac645194ba892a74Michal Krol static const char *comps = "xyzw"; 16862861e737e84e4884109b9526ac645194ba892a74Michal Krol static const char *ccString[] = { 16872861e737e84e4884109b9526ac645194ba892a74Michal Krol "??", "GT", "EQ", "LT", "UN", "GE", "LE", "NE", "TR", "FL", "??" 16882861e737e84e4884109b9526ac645194ba892a74Michal Krol }; 16892861e737e84e4884109b9526ac645194ba892a74Michal Krol 16902861e737e84e4884109b9526ac645194ba892a74Michal Krol _mesa_printf("%s", ccString[dst->CondMask]); 16917c26b61f9366a397e353d7b7f1f1d1f6d0dcd0c7Keith Whitwell if (GET_SWZ(dst->CondSwizzle, 0) == GET_SWZ(dst->CondSwizzle, 1) && 16927c26b61f9366a397e353d7b7f1f1d1f6d0dcd0c7Keith Whitwell GET_SWZ(dst->CondSwizzle, 0) == GET_SWZ(dst->CondSwizzle, 2) && 16937c26b61f9366a397e353d7b7f1f1d1f6d0dcd0c7Keith Whitwell GET_SWZ(dst->CondSwizzle, 0) == GET_SWZ(dst->CondSwizzle, 3)) { 16947c26b61f9366a397e353d7b7f1f1d1f6d0dcd0c7Keith Whitwell _mesa_printf(".%c", comps[GET_SWZ(dst->CondSwizzle, 0)]); 16957c26b61f9366a397e353d7b7f1f1d1f6d0dcd0c7Keith Whitwell } 16967c26b61f9366a397e353d7b7f1f1d1f6d0dcd0c7Keith Whitwell else if (dst->CondSwizzle != SWIZZLE_NOOP) { 16972861e737e84e4884109b9526ac645194ba892a74Michal Krol _mesa_printf(".%c%c%c%c", 16987c26b61f9366a397e353d7b7f1f1d1f6d0dcd0c7Keith Whitwell comps[GET_SWZ(dst->CondSwizzle, 0)], 16997c26b61f9366a397e353d7b7f1f1d1f6d0dcd0c7Keith Whitwell comps[GET_SWZ(dst->CondSwizzle, 1)], 17007c26b61f9366a397e353d7b7f1f1d1f6d0dcd0c7Keith Whitwell comps[GET_SWZ(dst->CondSwizzle, 2)], 17017c26b61f9366a397e353d7b7f1f1d1f6d0dcd0c7Keith Whitwell comps[GET_SWZ(dst->CondSwizzle, 3)]); 17022861e737e84e4884109b9526ac645194ba892a74Michal Krol } 17032861e737e84e4884109b9526ac645194ba892a74Michal Krol} 17042861e737e84e4884109b9526ac645194ba892a74Michal Krol 17052861e737e84e4884109b9526ac645194ba892a74Michal Krol 17062861e737e84e4884109b9526ac645194ba892a74Michal Krolstatic void 17077e807510d8c3e88ee7ae6c697393201cf08f992fBrian PaulPrintDstReg(const struct prog_dst_register *dst) 17082861e737e84e4884109b9526ac645194ba892a74Michal Krol{ 17092861e737e84e4884109b9526ac645194ba892a74Michal Krol if (dst->File == PROGRAM_OUTPUT) { 17102861e737e84e4884109b9526ac645194ba892a74Michal Krol _mesa_printf("o[%s]", OutputRegisters[dst->Index]); 17112861e737e84e4884109b9526ac645194ba892a74Michal Krol } 17122861e737e84e4884109b9526ac645194ba892a74Michal Krol else if (dst->File == PROGRAM_TEMPORARY) { 17132861e737e84e4884109b9526ac645194ba892a74Michal Krol if (dst->Index >= 32) 17142861e737e84e4884109b9526ac645194ba892a74Michal Krol _mesa_printf("H%d", dst->Index); 17152861e737e84e4884109b9526ac645194ba892a74Michal Krol else 17162861e737e84e4884109b9526ac645194ba892a74Michal Krol _mesa_printf("R%d", dst->Index); 17172861e737e84e4884109b9526ac645194ba892a74Michal Krol } 17182861e737e84e4884109b9526ac645194ba892a74Michal Krol else if (dst->File == PROGRAM_LOCAL_PARAM) { 17192861e737e84e4884109b9526ac645194ba892a74Michal Krol _mesa_printf("p[%d]", dst->Index); 17202861e737e84e4884109b9526ac645194ba892a74Michal Krol } 17212861e737e84e4884109b9526ac645194ba892a74Michal Krol else if (dst->File == PROGRAM_WRITE_ONLY) { 17222861e737e84e4884109b9526ac645194ba892a74Michal Krol _mesa_printf("%cC", "HR"[dst->Index]); 17232861e737e84e4884109b9526ac645194ba892a74Michal Krol } 17242861e737e84e4884109b9526ac645194ba892a74Michal Krol else { 17252861e737e84e4884109b9526ac645194ba892a74Michal Krol _mesa_printf("???"); 17262861e737e84e4884109b9526ac645194ba892a74Michal Krol } 17272861e737e84e4884109b9526ac645194ba892a74Michal Krol 1728ccfe3d4683bb6c97ffacd67267aa002dcb060433Brian Paul if (dst->WriteMask != 0 && dst->WriteMask != WRITEMASK_XYZW) { 17292861e737e84e4884109b9526ac645194ba892a74Michal Krol _mesa_printf("."); 1730ccfe3d4683bb6c97ffacd67267aa002dcb060433Brian Paul if (dst->WriteMask & WRITEMASK_X) 17312861e737e84e4884109b9526ac645194ba892a74Michal Krol _mesa_printf("x"); 1732ccfe3d4683bb6c97ffacd67267aa002dcb060433Brian Paul if (dst->WriteMask & WRITEMASK_Y) 17332861e737e84e4884109b9526ac645194ba892a74Michal Krol _mesa_printf("y"); 1734ccfe3d4683bb6c97ffacd67267aa002dcb060433Brian Paul if (dst->WriteMask & WRITEMASK_Z) 17352861e737e84e4884109b9526ac645194ba892a74Michal Krol _mesa_printf("z"); 1736ccfe3d4683bb6c97ffacd67267aa002dcb060433Brian Paul if (dst->WriteMask & WRITEMASK_W) 17372861e737e84e4884109b9526ac645194ba892a74Michal Krol _mesa_printf("w"); 17382861e737e84e4884109b9526ac645194ba892a74Michal Krol } 17392861e737e84e4884109b9526ac645194ba892a74Michal Krol 17402861e737e84e4884109b9526ac645194ba892a74Michal Krol if (dst->CondMask != COND_TR || 17417c26b61f9366a397e353d7b7f1f1d1f6d0dcd0c7Keith Whitwell dst->CondSwizzle != SWIZZLE_NOOP) { 17422861e737e84e4884109b9526ac645194ba892a74Michal Krol _mesa_printf(" ("); 17432861e737e84e4884109b9526ac645194ba892a74Michal Krol PrintCondCode(dst); 17442861e737e84e4884109b9526ac645194ba892a74Michal Krol _mesa_printf(")"); 17452861e737e84e4884109b9526ac645194ba892a74Michal Krol } 17462861e737e84e4884109b9526ac645194ba892a74Michal Krol} 17472861e737e84e4884109b9526ac645194ba892a74Michal Krol 17482861e737e84e4884109b9526ac645194ba892a74Michal Krol 17492861e737e84e4884109b9526ac645194ba892a74Michal Krol/** 17502861e737e84e4884109b9526ac645194ba892a74Michal Krol * Print (unparse) the given vertex program. Just for debugging. 17512861e737e84e4884109b9526ac645194ba892a74Michal Krol */ 17522861e737e84e4884109b9526ac645194ba892a74Michal Krolvoid 1753122629f27925a9dc50029bebc5079f87f416a7e1Brian Paul_mesa_print_nv_fragment_program(const struct gl_fragment_program *program) 17542861e737e84e4884109b9526ac645194ba892a74Michal Krol{ 17557e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul const struct prog_instruction *inst; 17562861e737e84e4884109b9526ac645194ba892a74Michal Krol 1757de99760bf3511d05185799c4fb4347f9e5f420f4Brian Paul for (inst = program->Base.Instructions; inst->Opcode != OPCODE_END; inst++) { 17582861e737e84e4884109b9526ac645194ba892a74Michal Krol int i; 17592861e737e84e4884109b9526ac645194ba892a74Michal Krol for (i = 0; Instructions[i].name; i++) { 17602861e737e84e4884109b9526ac645194ba892a74Michal Krol if (inst->Opcode == Instructions[i].opcode) { 17612861e737e84e4884109b9526ac645194ba892a74Michal Krol /* print instruction name */ 17622861e737e84e4884109b9526ac645194ba892a74Michal Krol _mesa_printf("%s", Instructions[i].name); 17632861e737e84e4884109b9526ac645194ba892a74Michal Krol if (inst->Precision == FLOAT16) 17642861e737e84e4884109b9526ac645194ba892a74Michal Krol _mesa_printf("H"); 17652861e737e84e4884109b9526ac645194ba892a74Michal Krol else if (inst->Precision == FIXED12) 17662861e737e84e4884109b9526ac645194ba892a74Michal Krol _mesa_printf("X"); 17677e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul if (inst->CondUpdate) 17682861e737e84e4884109b9526ac645194ba892a74Michal Krol _mesa_printf("C"); 1769e31ac052236ea615b4995f9ec301d8af4b864531Brian Paul if (inst->SaturateMode == SATURATE_ZERO_ONE) 17702861e737e84e4884109b9526ac645194ba892a74Michal Krol _mesa_printf("_SAT"); 17712861e737e84e4884109b9526ac645194ba892a74Michal Krol _mesa_printf(" "); 17722861e737e84e4884109b9526ac645194ba892a74Michal Krol 17732861e737e84e4884109b9526ac645194ba892a74Michal Krol if (Instructions[i].inputs == INPUT_CC) { 17742861e737e84e4884109b9526ac645194ba892a74Michal Krol PrintCondCode(&inst->DstReg); 17752861e737e84e4884109b9526ac645194ba892a74Michal Krol } 17762861e737e84e4884109b9526ac645194ba892a74Michal Krol else if (Instructions[i].outputs == OUTPUT_V || 17772861e737e84e4884109b9526ac645194ba892a74Michal Krol Instructions[i].outputs == OUTPUT_S) { 17782861e737e84e4884109b9526ac645194ba892a74Michal Krol /* print dest register */ 17792861e737e84e4884109b9526ac645194ba892a74Michal Krol PrintDstReg(&inst->DstReg); 17802861e737e84e4884109b9526ac645194ba892a74Michal Krol _mesa_printf(", "); 17812861e737e84e4884109b9526ac645194ba892a74Michal Krol } 17822861e737e84e4884109b9526ac645194ba892a74Michal Krol 17832861e737e84e4884109b9526ac645194ba892a74Michal Krol /* print source register(s) */ 17842861e737e84e4884109b9526ac645194ba892a74Michal Krol if (Instructions[i].inputs == INPUT_1V || 17852861e737e84e4884109b9526ac645194ba892a74Michal Krol Instructions[i].inputs == INPUT_1S) { 17862861e737e84e4884109b9526ac645194ba892a74Michal Krol PrintSrcReg(program, &inst->SrcReg[0]); 17872861e737e84e4884109b9526ac645194ba892a74Michal Krol } 17882861e737e84e4884109b9526ac645194ba892a74Michal Krol else if (Instructions[i].inputs == INPUT_2V || 17892861e737e84e4884109b9526ac645194ba892a74Michal Krol Instructions[i].inputs == INPUT_2S) { 17902861e737e84e4884109b9526ac645194ba892a74Michal Krol PrintSrcReg(program, &inst->SrcReg[0]); 17912861e737e84e4884109b9526ac645194ba892a74Michal Krol _mesa_printf(", "); 17922861e737e84e4884109b9526ac645194ba892a74Michal Krol PrintSrcReg(program, &inst->SrcReg[1]); 17932861e737e84e4884109b9526ac645194ba892a74Michal Krol } 17942861e737e84e4884109b9526ac645194ba892a74Michal Krol else if (Instructions[i].inputs == INPUT_3V) { 17952861e737e84e4884109b9526ac645194ba892a74Michal Krol PrintSrcReg(program, &inst->SrcReg[0]); 17962861e737e84e4884109b9526ac645194ba892a74Michal Krol _mesa_printf(", "); 17972861e737e84e4884109b9526ac645194ba892a74Michal Krol PrintSrcReg(program, &inst->SrcReg[1]); 17982861e737e84e4884109b9526ac645194ba892a74Michal Krol _mesa_printf(", "); 17992861e737e84e4884109b9526ac645194ba892a74Michal Krol PrintSrcReg(program, &inst->SrcReg[2]); 18002861e737e84e4884109b9526ac645194ba892a74Michal Krol } 18012861e737e84e4884109b9526ac645194ba892a74Michal Krol else if (Instructions[i].inputs == INPUT_1V_T) { 18022861e737e84e4884109b9526ac645194ba892a74Michal Krol PrintSrcReg(program, &inst->SrcReg[0]); 18032861e737e84e4884109b9526ac645194ba892a74Michal Krol _mesa_printf(", "); 18042861e737e84e4884109b9526ac645194ba892a74Michal Krol PrintTextureSrc(inst); 18052861e737e84e4884109b9526ac645194ba892a74Michal Krol } 18062861e737e84e4884109b9526ac645194ba892a74Michal Krol else if (Instructions[i].inputs == INPUT_3V_T) { 18072861e737e84e4884109b9526ac645194ba892a74Michal Krol PrintSrcReg(program, &inst->SrcReg[0]); 18082861e737e84e4884109b9526ac645194ba892a74Michal Krol _mesa_printf(", "); 18092861e737e84e4884109b9526ac645194ba892a74Michal Krol PrintSrcReg(program, &inst->SrcReg[1]); 18102861e737e84e4884109b9526ac645194ba892a74Michal Krol _mesa_printf(", "); 18112861e737e84e4884109b9526ac645194ba892a74Michal Krol PrintSrcReg(program, &inst->SrcReg[2]); 18122861e737e84e4884109b9526ac645194ba892a74Michal Krol _mesa_printf(", "); 18132861e737e84e4884109b9526ac645194ba892a74Michal Krol PrintTextureSrc(inst); 18142861e737e84e4884109b9526ac645194ba892a74Michal Krol } 18152861e737e84e4884109b9526ac645194ba892a74Michal Krol _mesa_printf(";\n"); 18162861e737e84e4884109b9526ac645194ba892a74Michal Krol break; 18172861e737e84e4884109b9526ac645194ba892a74Michal Krol } 18182861e737e84e4884109b9526ac645194ba892a74Michal Krol } 18192861e737e84e4884109b9526ac645194ba892a74Michal Krol if (!Instructions[i].name) { 18202861e737e84e4884109b9526ac645194ba892a74Michal Krol _mesa_printf("Invalid opcode %d\n", inst->Opcode); 18212861e737e84e4884109b9526ac645194ba892a74Michal Krol } 18222861e737e84e4884109b9526ac645194ba892a74Michal Krol } 18232861e737e84e4884109b9526ac645194ba892a74Michal Krol _mesa_printf("END\n"); 18242861e737e84e4884109b9526ac645194ba892a74Michal Krol} 18252861e737e84e4884109b9526ac645194ba892a74Michal Krol 18262861e737e84e4884109b9526ac645194ba892a74Michal Krol 18272861e737e84e4884109b9526ac645194ba892a74Michal Krolconst char * 18282861e737e84e4884109b9526ac645194ba892a74Michal Krol_mesa_nv_fragment_input_register_name(GLuint i) 18292861e737e84e4884109b9526ac645194ba892a74Michal Krol{ 18302861e737e84e4884109b9526ac645194ba892a74Michal Krol ASSERT(i < MAX_NV_FRAGMENT_PROGRAM_INPUTS); 18312861e737e84e4884109b9526ac645194ba892a74Michal Krol return InputRegisters[i]; 18322861e737e84e4884109b9526ac645194ba892a74Michal Krol} 18332861e737e84e4884109b9526ac645194ba892a74Michal Krol 18342861e737e84e4884109b9526ac645194ba892a74Michal Krol 18352861e737e84e4884109b9526ac645194ba892a74Michal Krolconst char * 18362861e737e84e4884109b9526ac645194ba892a74Michal Krol_mesa_nv_fragment_output_register_name(GLuint i) 18372861e737e84e4884109b9526ac645194ba892a74Michal Krol{ 18382861e737e84e4884109b9526ac645194ba892a74Michal Krol ASSERT(i < MAX_NV_FRAGMENT_PROGRAM_OUTPUTS); 18392861e737e84e4884109b9526ac645194ba892a74Michal Krol return OutputRegisters[i]; 18402861e737e84e4884109b9526ac645194ba892a74Michal Krol} 1841