/*
* Mesa 3-D graphics library
- * Version: 6.1
+ * Version: 6.5
*
- * Copyright (C) 1999-2004 Brian Paul All Rights Reserved.
+ * Copyright (C) 1999-2005 Brian Paul All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
#include "imports.h"
#include "macros.h"
#include "mtypes.h"
-#include "nvfragprog.h"
+#include "program_instruction.h"
#include "nvfragparse.h"
#include "nvprogram.h"
#include "program.h"
#define INPUT_1V_T 7 /* one source vector, plus textureId */
#define INPUT_3V_T 8 /* one source vector, plus textureId */
#define INPUT_NONE 9
+#define INPUT_1V_S 10 /* a string and a vector register */
#define OUTPUT_V 20
#define OUTPUT_S 21
#define OUTPUT_NONE 22
struct instruction_pattern {
const char *name;
- enum fp_opcode opcode;
+ enum prog_opcode opcode;
GLuint inputs;
GLuint outputs;
GLuint suffixes;
};
static const struct instruction_pattern Instructions[] = {
- { "ADD", FP_OPCODE_ADD, INPUT_2V, OUTPUT_V, _R | _H | _X | _C | _S },
- { "COS", FP_OPCODE_COS, INPUT_1S, OUTPUT_S, _R | _H | _C | _S },
- { "DDX", FP_OPCODE_DDX, INPUT_1V, OUTPUT_V, _R | _H | _C | _S },
- { "DDY", FP_OPCODE_DDY, INPUT_1V, OUTPUT_V, _R | _H | _C | _S },
- { "DP3", FP_OPCODE_DP3, INPUT_2V, OUTPUT_S, _R | _H | _X | _C | _S },
- { "DP4", FP_OPCODE_DP4, INPUT_2V, OUTPUT_S, _R | _H | _X | _C | _S },
- { "DST", FP_OPCODE_DP4, INPUT_2V, OUTPUT_V, _R | _H | _C | _S },
- { "EX2", FP_OPCODE_DP4, INPUT_1S, OUTPUT_S, _R | _H | _C | _S },
- { "FLR", FP_OPCODE_FLR, INPUT_1V, OUTPUT_V, _R | _H | _X | _C | _S },
- { "FRC", FP_OPCODE_FRC, INPUT_1V, OUTPUT_V, _R | _H | _X | _C | _S },
- { "KIL", FP_OPCODE_KIL_NV, INPUT_CC, OUTPUT_NONE, 0 },
- { "LG2", FP_OPCODE_LG2, INPUT_1S, OUTPUT_S, _R | _H | _C | _S },
- { "LIT", FP_OPCODE_LIT, INPUT_1V, OUTPUT_V, _R | _H | _C | _S },
- { "LRP", FP_OPCODE_LRP, INPUT_3V, OUTPUT_V, _R | _H | _X | _C | _S },
- { "MAD", FP_OPCODE_MAD, INPUT_3V, OUTPUT_V, _R | _H | _X | _C | _S },
- { "MAX", FP_OPCODE_MAX, INPUT_2V, OUTPUT_V, _R | _H | _X | _C | _S },
- { "MIN", FP_OPCODE_MIN, INPUT_2V, OUTPUT_V, _R | _H | _X | _C | _S },
- { "MOV", FP_OPCODE_MOV, INPUT_1V, OUTPUT_V, _R | _H | _X | _C | _S },
- { "MUL", FP_OPCODE_MUL, INPUT_2V, OUTPUT_V, _R | _H | _X | _C | _S },
- { "PK2H", FP_OPCODE_PK2H, INPUT_1V, OUTPUT_S, 0 },
- { "PK2US", FP_OPCODE_PK2US, INPUT_1V, OUTPUT_S, 0 },
- { "PK4B", FP_OPCODE_PK4B, INPUT_1V, OUTPUT_S, 0 },
- { "PK4UB", FP_OPCODE_PK4UB, INPUT_1V, OUTPUT_S, 0 },
- { "POW", FP_OPCODE_POW, INPUT_2S, OUTPUT_S, _R | _H | _C | _S },
- { "RCP", FP_OPCODE_RCP, INPUT_1S, OUTPUT_S, _R | _H | _C | _S },
- { "RFL", FP_OPCODE_RFL, INPUT_2V, OUTPUT_V, _R | _H | _C | _S },
- { "RSQ", FP_OPCODE_RSQ, INPUT_1S, OUTPUT_S, _R | _H | _C | _S },
- { "SEQ", FP_OPCODE_SEQ, INPUT_2V, OUTPUT_V, _R | _H | _X | _C | _S },
- { "SFL", FP_OPCODE_SFL, INPUT_2V, OUTPUT_V, _R | _H | _X | _C | _S },
- { "SGE", FP_OPCODE_SGE, INPUT_2V, OUTPUT_V, _R | _H | _X | _C | _S },
- { "SGT", FP_OPCODE_SGT, INPUT_2V, OUTPUT_V, _R | _H | _X | _C | _S },
- { "SIN", FP_OPCODE_SIN, INPUT_1S, OUTPUT_S, _R | _H | _C | _S },
- { "SLE", FP_OPCODE_SLE, INPUT_2V, OUTPUT_V, _R | _H | _X | _C | _S },
- { "SLT", FP_OPCODE_SLT, INPUT_2V, OUTPUT_V, _R | _H | _X | _C | _S },
- { "SNE", FP_OPCODE_SNE, INPUT_2V, OUTPUT_V, _R | _H | _X | _C | _S },
- { "STR", FP_OPCODE_STR, INPUT_2V, OUTPUT_V, _R | _H | _X | _C | _S },
- { "SUB", FP_OPCODE_SUB, INPUT_2V, OUTPUT_V, _R | _H | _X | _C | _S },
- { "TEX", FP_OPCODE_TEX, INPUT_1V_T, OUTPUT_V, _C | _S },
- { "TXD", FP_OPCODE_TXD, INPUT_3V_T, OUTPUT_V, _C | _S },
- { "TXP", FP_OPCODE_TXP_NV, INPUT_1V_T, OUTPUT_V, _C | _S },
- { "UP2H", FP_OPCODE_UP2H, INPUT_1S, OUTPUT_V, _C | _S },
- { "UP2US", FP_OPCODE_UP2US, INPUT_1S, OUTPUT_V, _C | _S },
- { "UP4B", FP_OPCODE_UP4B, INPUT_1S, OUTPUT_V, _C | _S },
- { "UP4UB", FP_OPCODE_UP4UB, INPUT_1S, OUTPUT_V, _C | _S },
- { "X2D", FP_OPCODE_X2D, INPUT_3V, OUTPUT_V, _R | _H | _C | _S },
- { NULL, (enum fp_opcode) -1, 0, 0, 0 }
+ { "ADD", OPCODE_ADD, INPUT_2V, OUTPUT_V, _R | _H | _X | _C | _S },
+ { "COS", OPCODE_COS, INPUT_1S, OUTPUT_S, _R | _H | _C | _S },
+ { "DDX", OPCODE_DDX, INPUT_1V, OUTPUT_V, _R | _H | _C | _S },
+ { "DDY", OPCODE_DDY, INPUT_1V, OUTPUT_V, _R | _H | _C | _S },
+ { "DP3", OPCODE_DP3, INPUT_2V, OUTPUT_S, _R | _H | _X | _C | _S },
+ { "DP4", OPCODE_DP4, INPUT_2V, OUTPUT_S, _R | _H | _X | _C | _S },
+ { "DST", OPCODE_DP4, INPUT_2V, OUTPUT_V, _R | _H | _C | _S },
+ { "EX2", OPCODE_DP4, INPUT_1S, OUTPUT_S, _R | _H | _C | _S },
+ { "FLR", OPCODE_FLR, INPUT_1V, OUTPUT_V, _R | _H | _X | _C | _S },
+ { "FRC", OPCODE_FRC, INPUT_1V, OUTPUT_V, _R | _H | _X | _C | _S },
+ { "KIL", OPCODE_KIL_NV, INPUT_CC, OUTPUT_NONE, 0 },
+ { "LG2", OPCODE_LG2, INPUT_1S, OUTPUT_S, _R | _H | _C | _S },
+ { "LIT", OPCODE_LIT, INPUT_1V, OUTPUT_V, _R | _H | _C | _S },
+ { "LRP", OPCODE_LRP, INPUT_3V, OUTPUT_V, _R | _H | _X | _C | _S },
+ { "MAD", OPCODE_MAD, INPUT_3V, OUTPUT_V, _R | _H | _X | _C | _S },
+ { "MAX", OPCODE_MAX, INPUT_2V, OUTPUT_V, _R | _H | _X | _C | _S },
+ { "MIN", OPCODE_MIN, INPUT_2V, OUTPUT_V, _R | _H | _X | _C | _S },
+ { "MOV", OPCODE_MOV, INPUT_1V, OUTPUT_V, _R | _H | _X | _C | _S },
+ { "MUL", OPCODE_MUL, INPUT_2V, OUTPUT_V, _R | _H | _X | _C | _S },
+ { "PK2H", OPCODE_PK2H, INPUT_1V, OUTPUT_S, 0 },
+ { "PK2US", OPCODE_PK2US, INPUT_1V, OUTPUT_S, 0 },
+ { "PK4B", OPCODE_PK4B, INPUT_1V, OUTPUT_S, 0 },
+ { "PK4UB", OPCODE_PK4UB, INPUT_1V, OUTPUT_S, 0 },
+ { "POW", OPCODE_POW, INPUT_2S, OUTPUT_S, _R | _H | _C | _S },
+ { "RCP", OPCODE_RCP, INPUT_1S, OUTPUT_S, _R | _H | _C | _S },
+ { "RFL", OPCODE_RFL, INPUT_2V, OUTPUT_V, _R | _H | _C | _S },
+ { "RSQ", OPCODE_RSQ, INPUT_1S, OUTPUT_S, _R | _H | _C | _S },
+ { "SEQ", OPCODE_SEQ, INPUT_2V, OUTPUT_V, _R | _H | _X | _C | _S },
+ { "SFL", OPCODE_SFL, INPUT_2V, OUTPUT_V, _R | _H | _X | _C | _S },
+ { "SGE", OPCODE_SGE, INPUT_2V, OUTPUT_V, _R | _H | _X | _C | _S },
+ { "SGT", OPCODE_SGT, INPUT_2V, OUTPUT_V, _R | _H | _X | _C | _S },
+ { "SIN", OPCODE_SIN, INPUT_1S, OUTPUT_S, _R | _H | _C | _S },
+ { "SLE", OPCODE_SLE, INPUT_2V, OUTPUT_V, _R | _H | _X | _C | _S },
+ { "SLT", OPCODE_SLT, INPUT_2V, OUTPUT_V, _R | _H | _X | _C | _S },
+ { "SNE", OPCODE_SNE, INPUT_2V, OUTPUT_V, _R | _H | _X | _C | _S },
+ { "STR", OPCODE_STR, INPUT_2V, OUTPUT_V, _R | _H | _X | _C | _S },
+ { "SUB", OPCODE_SUB, INPUT_2V, OUTPUT_V, _R | _H | _X | _C | _S },
+ { "TEX", OPCODE_TEX, INPUT_1V_T, OUTPUT_V, _C | _S },
+ { "TXD", OPCODE_TXD, INPUT_3V_T, OUTPUT_V, _C | _S },
+ { "TXP", OPCODE_TXP_NV, INPUT_1V_T, OUTPUT_V, _C | _S },
+ { "UP2H", OPCODE_UP2H, INPUT_1S, OUTPUT_V, _C | _S },
+ { "UP2US", OPCODE_UP2US, INPUT_1S, OUTPUT_V, _C | _S },
+ { "UP4B", OPCODE_UP4B, INPUT_1S, OUTPUT_V, _C | _S },
+ { "UP4UB", OPCODE_UP4UB, INPUT_1S, OUTPUT_V, _C | _S },
+ { "X2D", OPCODE_X2D, INPUT_3V, OUTPUT_V, _R | _H | _C | _S },
+ { "PRINT", OPCODE_PRINT, INPUT_1V_S, OUTPUT_NONE, 0 },
+ { NULL, (enum prog_opcode) -1, 0, 0, 0 }
};
const GLubyte *start; /* start of program string */
const GLubyte *pos; /* current position */
const GLubyte *curLine;
- struct fragment_program *program; /* current program */
+ struct gl_fragment_program *program; /* current program */
- struct program_parameter_list *parameters;
+ struct gl_program_parameter_list *parameters;
GLuint numInst; /* number of instructions parsed */
GLuint inputsRead; /* bitmask of input registers used */
return result;
}
}
- result.opcode = (enum fp_opcode) -1;
+ result.opcode = MAX_OPCODE; /* i.e. invalid instruction */
return result;
}
parseState->pos += (-i);
return GL_FALSE;
}
- len = _mesa_strlen((const char *) token);
+ len = (GLint)_mesa_strlen((const char *) token);
parseState->pos += (i - len);
return GL_TRUE;
}
static GLboolean
Parse_CondCodeMask(struct parse_state *parseState,
- struct fp_dst_register *dstReg)
+ struct prog_dst_register *dstReg)
{
if (Parse_String(parseState, "EQ"))
dstReg->CondMask = COND_EQ;
/* look for optional .xyzw swizzle */
if (Parse_String(parseState, ".")) {
GLubyte token[100];
+ GLuint swz[4];
+
if (!Parse_Token(parseState, token)) /* get xyzw suffix */
RETURN_ERROR;
- if (!Parse_SwizzleSuffix(token, dstReg->CondSwizzle))
+ if (!Parse_SwizzleSuffix(token, swz))
RETURN_ERROR1("Invalid swizzle suffix");
+
+ dstReg->CondSwizzle = MAKE_SWIZZLE4(swz[0], swz[1], swz[2], swz[3]);
}
return GL_TRUE;
/* try to match an output register name */
for (j = 0; OutputRegisters[j]; j++) {
if (_mesa_strcmp((const char *) token, OutputRegisters[j]) == 0) {
- static GLuint bothColors = (1 << FRAG_OUTPUT_COLR) | (1 << FRAG_OUTPUT_COLH);
+ static GLuint bothColors = (1 << FRAG_RESULT_COLR) | (1 << FRAG_RESULT_COLH);
*outputRegNum = j;
parseState->outputsWritten |= (1 << j);
if ((parseState->outputsWritten & bothColors) == bothColors) {
static GLboolean
Parse_MaskedDstReg(struct parse_state *parseState,
- struct fp_dst_register *dstReg)
+ struct prog_dst_register *dstReg)
{
GLubyte token[100];
+ GLint idx;
/* Dst reg can be R<n>, H<n>, o[n], RC or HC */
if (!Peek_Token(parseState, token))
_mesa_strcmp((const char *) token, "HC") == 0) {
/* a write-only register */
dstReg->File = PROGRAM_WRITE_ONLY;
- if (!Parse_DummyReg(parseState, &dstReg->Index))
+ if (!Parse_DummyReg(parseState, &idx))
RETURN_ERROR;
+ dstReg->Index = idx;
}
else if (token[0] == 'R' || token[0] == 'H') {
/* a temporary register */
dstReg->File = PROGRAM_TEMPORARY;
- if (!Parse_TempReg(parseState, &dstReg->Index))
+ if (!Parse_TempReg(parseState, &idx))
RETURN_ERROR;
+ dstReg->Index = idx;
}
else if (token[0] == 'o') {
/* an output register */
dstReg->File = PROGRAM_OUTPUT;
- if (!Parse_OutputReg(parseState, &dstReg->Index))
+ if (!Parse_OutputReg(parseState, &idx))
RETURN_ERROR;
+ dstReg->Index = idx;
}
else {
RETURN_ERROR1("Invalid destination register name");
if (!Parse_Token(parseState, token)) /* get xyzw writemask */
RETURN_ERROR;
- dstReg->WriteMask[0] = GL_FALSE;
- dstReg->WriteMask[1] = GL_FALSE;
- dstReg->WriteMask[2] = GL_FALSE;
- dstReg->WriteMask[3] = GL_FALSE;
+ dstReg->WriteMask = 0;
if (token[k] == 'x') {
- dstReg->WriteMask[0] = GL_TRUE;
+ dstReg->WriteMask |= WRITEMASK_X;
k++;
}
if (token[k] == 'y') {
- dstReg->WriteMask[1] = GL_TRUE;
+ dstReg->WriteMask |= WRITEMASK_Y;
k++;
}
if (token[k] == 'z') {
- dstReg->WriteMask[2] = GL_TRUE;
+ dstReg->WriteMask |= WRITEMASK_Z;
k++;
}
if (token[k] == 'w') {
- dstReg->WriteMask[3] = GL_TRUE;
+ dstReg->WriteMask |= WRITEMASK_W;
k++;
}
if (k == 0) {
}
else {
- dstReg->WriteMask[0] = GL_TRUE;
- dstReg->WriteMask[1] = GL_TRUE;
- dstReg->WriteMask[2] = GL_TRUE;
- dstReg->WriteMask[3] = GL_TRUE;
+ dstReg->WriteMask = WRITEMASK_XYZW;
}
/* optional condition code mask */
else {
/* no cond code mask */
dstReg->CondMask = COND_TR;
- dstReg->CondSwizzle[0] = 0;
- dstReg->CondSwizzle[1] = 1;
- dstReg->CondSwizzle[2] = 2;
- dstReg->CondSwizzle[3] = 3;
+ dstReg->CondSwizzle = SWIZZLE_NOOP;
return GL_TRUE;
}
}
*/
static GLboolean
Parse_VectorSrc(struct parse_state *parseState,
- struct fp_src_register *srcReg)
+ struct prog_src_register *srcReg)
{
GLfloat sign = 1.0F;
GLubyte token[100];
+ GLint idx;
/*
* First, take care of +/- and absolute value stuff.
srcReg->NegateAbs = (sign < 0.0F) ? GL_TRUE : GL_FALSE;
if (Parse_String(parseState, "-"))
- srcReg->NegateBase = GL_TRUE;
+ srcReg->NegateBase = NEGATE_XYZW;
else if (Parse_String(parseState, "+"))
- srcReg->NegateBase = GL_FALSE;
+ srcReg->NegateBase = NEGATE_NONE;
else
- srcReg->NegateBase = GL_FALSE;
+ srcReg->NegateBase = NEGATE_NONE;
}
else {
srcReg->Abs = GL_FALSE;
srcReg->NegateAbs = GL_FALSE;
- srcReg->NegateBase = (sign < 0.0F) ? GL_TRUE : GL_FALSE;
+ srcReg->NegateBase = (sign < 0.0F) ? NEGATE_XYZW : NEGATE_NONE;
}
/* This should be the real src vector/register name */
*/
if (token[0] == 'R' || token[0] == 'H') {
srcReg->File = PROGRAM_TEMPORARY;
- if (!Parse_TempReg(parseState, &srcReg->Index))
+ if (!Parse_TempReg(parseState, &idx))
RETURN_ERROR;
+ srcReg->Index = idx;
}
else if (token[0] == 'f') {
- /* XXX this might be an identier! */
+ /* XXX this might be an identifier! */
srcReg->File = PROGRAM_INPUT;
- if (!Parse_FragReg(parseState, &srcReg->Index))
+ if (!Parse_FragReg(parseState, &idx))
RETURN_ERROR;
+ srcReg->Index = idx;
}
else if (token[0] == 'p') {
- /* XXX this might be an identier! */
+ /* XXX this might be an identifier! */
srcReg->File = PROGRAM_LOCAL_PARAM;
- if (!Parse_ProgramParamReg(parseState, &srcReg->Index))
+ if (!Parse_ProgramParamReg(parseState, &idx))
RETURN_ERROR;
+ srcReg->Index = idx;
}
else if (IsLetter(token[0])){
GLubyte ident[100];
GLuint paramIndex;
if (!Parse_ScalarConstant(parseState, values))
RETURN_ERROR;
- paramIndex = _mesa_add_unnamed_constant(parseState->parameters, values);
+ paramIndex = _mesa_add_unnamed_constant(parseState->parameters, values, 4);
srcReg->File = PROGRAM_NAMED_PARAM;
srcReg->Index = paramIndex;
}
(void) Parse_String(parseState, "{");
if (!Parse_VectorConstant(parseState, values))
RETURN_ERROR;
- paramIndex = _mesa_add_unnamed_constant(parseState->parameters, values);
+ paramIndex = _mesa_add_unnamed_constant(parseState->parameters, values, 4);
srcReg->File = PROGRAM_NAMED_PARAM;
srcReg->Index = paramIndex;
}
}
/* init swizzle fields */
- srcReg->Swizzle[0] = 0;
- srcReg->Swizzle[1] = 1;
- srcReg->Swizzle[2] = 2;
- srcReg->Swizzle[3] = 3;
+ srcReg->Swizzle = SWIZZLE_NOOP;
/* Look for optional swizzle suffix */
if (Parse_String(parseState, ".")) {
+ GLuint swz[4];
+
if (!Parse_Token(parseState, token))
RETURN_ERROR;
- if (!Parse_SwizzleSuffix(token, srcReg->Swizzle))
+ if (!Parse_SwizzleSuffix(token, swz))
RETURN_ERROR1("Invalid swizzle suffix");
+
+ srcReg->Swizzle = MAKE_SWIZZLE4(swz[0], swz[1], swz[2], swz[3]);
}
/* Finish absolute value */
static GLboolean
Parse_ScalarSrcReg(struct parse_state *parseState,
- struct fp_src_register *srcReg)
+ struct prog_src_register *srcReg)
{
GLubyte token[100];
GLfloat sign = 1.0F;
GLboolean needSuffix = GL_TRUE;
+ GLint idx;
/*
* First, take care of +/- and absolute value stuff.
srcReg->NegateAbs = (sign < 0.0F) ? GL_TRUE : GL_FALSE;
if (Parse_String(parseState, "-"))
- srcReg->NegateBase = GL_TRUE;
+ srcReg->NegateBase = NEGATE_XYZW;
else if (Parse_String(parseState, "+"))
- srcReg->NegateBase = GL_FALSE;
+ srcReg->NegateBase = NEGATE_NONE;
else
- srcReg->NegateBase = GL_FALSE;
+ srcReg->NegateBase = NEGATE_NONE;
}
else {
srcReg->Abs = GL_FALSE;
srcReg->NegateAbs = GL_FALSE;
- srcReg->NegateBase = (sign < 0.0F) ? GL_TRUE : GL_FALSE;
+ srcReg->NegateBase = (sign < 0.0F) ? NEGATE_XYZW : NEGATE_NONE;
}
if (!Peek_Token(parseState, token))
/* Src reg can be R<n>, H<n> or a named fragment attrib */
if (token[0] == 'R' || token[0] == 'H') {
srcReg->File = PROGRAM_TEMPORARY;
- if (!Parse_TempReg(parseState, &srcReg->Index))
+ if (!Parse_TempReg(parseState, &idx))
RETURN_ERROR;
+ srcReg->Index = idx;
}
else if (token[0] == 'f') {
srcReg->File = PROGRAM_INPUT;
- if (!Parse_FragReg(parseState, &srcReg->Index))
+ if (!Parse_FragReg(parseState, &idx))
RETURN_ERROR;
+ srcReg->Index = idx;
}
else if (token[0] == '{') {
/* vector literal */
(void) Parse_String(parseState, "{");
if (!Parse_VectorConstant(parseState, values))
RETURN_ERROR;
- paramIndex = _mesa_add_unnamed_constant(parseState->parameters, values);
+ paramIndex = _mesa_add_unnamed_constant(parseState->parameters, values, 4);
+ srcReg->File = PROGRAM_NAMED_PARAM;
+ srcReg->Index = paramIndex;
+ }
+ else if (IsLetter(token[0])){
+ /* named param/constant */
+ GLubyte ident[100];
+ GLint paramIndex;
+ if (!Parse_Identifier(parseState, ident))
+ RETURN_ERROR;
+ paramIndex = _mesa_lookup_parameter_index(parseState->parameters,
+ -1, (const char *) ident);
+ if (paramIndex < 0) {
+ RETURN_ERROR2("Undefined constant or parameter: ", ident);
+ }
srcReg->File = PROGRAM_NAMED_PARAM;
srcReg->Index = paramIndex;
}
GLuint paramIndex;
if (!Parse_ScalarConstant(parseState, values))
RETURN_ERROR;
- paramIndex = _mesa_add_unnamed_constant(parseState->parameters, values);
+ paramIndex = _mesa_add_unnamed_constant(parseState->parameters, values, 4);
srcReg->Index = paramIndex;
srcReg->File = PROGRAM_NAMED_PARAM;
needSuffix = GL_FALSE;
RETURN_ERROR2("Invalid scalar source argument", token);
}
+ srcReg->Swizzle = 0;
if (needSuffix) {
/* parse .[xyzw] suffix */
if (!Parse_String(parseState, "."))
RETURN_ERROR;
if (token[0] == 'x' && token[1] == 0) {
- srcReg->Swizzle[0] = 0;
+ srcReg->Swizzle = 0;
}
else if (token[0] == 'y' && token[1] == 0) {
- srcReg->Swizzle[0] = 1;
+ srcReg->Swizzle = 1;
}
else if (token[0] == 'z' && token[1] == 0) {
- srcReg->Swizzle[0] = 2;
+ srcReg->Swizzle = 2;
}
else if (token[0] == 'w' && token[1] == 0) {
- srcReg->Swizzle[0] = 3;
+ srcReg->Swizzle = 3;
}
else {
RETURN_ERROR1("Invalid scalar source suffix");
}
}
- else {
- srcReg->Swizzle[0] = 0;
- }
- srcReg->Swizzle[1] = srcReg->Swizzle[2] = srcReg->Swizzle[3] = 0;
/* Finish absolute value */
if (srcReg->Abs && !Parse_String(parseState, "|")) {
}
+static GLboolean
+Parse_PrintInstruction(struct parse_state *parseState,
+ struct prog_instruction *inst)
+{
+ const GLubyte *str;
+ GLubyte *msg;
+ GLuint len;
+ GLint idx;
+
+ /* The first argument is a literal string 'just like this' */
+ if (!Parse_String(parseState, "'"))
+ RETURN_ERROR1("Expected '");
+
+ str = parseState->pos;
+ for (len = 0; str[len] != '\''; len++) /* find closing quote */
+ ;
+ parseState->pos += len + 1;
+ msg = (GLubyte*) _mesa_malloc(len + 1);
+
+ _mesa_memcpy(msg, str, len);
+ msg[len] = 0;
+ inst->Data = msg;
+
+ if (Parse_String(parseState, ",")) {
+ /* got an optional register to print */
+ GLubyte token[100];
+ GetToken(parseState, token);
+ if (token[0] == 'o') {
+ /* dst reg */
+ if (!Parse_OutputReg(parseState, &idx))
+ RETURN_ERROR;
+ inst->SrcReg[0].Index = idx;
+ inst->SrcReg[0].File = PROGRAM_OUTPUT;
+ }
+ else {
+ /* src reg */
+ if (!Parse_VectorSrc(parseState, &inst->SrcReg[0]))
+ RETURN_ERROR;
+ }
+ }
+ else {
+ inst->SrcReg[0].File = PROGRAM_UNDEFINED;
+ }
+
+ inst->SrcReg[0].Swizzle = SWIZZLE_NOOP;
+ inst->SrcReg[0].NegateBase = NEGATE_NONE;
+ inst->SrcReg[0].Abs = GL_FALSE;
+ inst->SrcReg[0].NegateAbs = GL_FALSE;
+
+ return GL_TRUE;
+}
+
static GLboolean
Parse_InstructionSequence(struct parse_state *parseState,
- struct fp_instruction program[])
+ struct prog_instruction program[])
{
while (1) {
- struct fp_instruction *inst = program + parseState->numInst;
+ struct prog_instruction *inst = program + parseState->numInst;
struct instruction_pattern instMatch;
GLubyte token[100];
/* Initialize the instruction */
- inst->SrcReg[0].File = (enum register_file) -1;
- inst->SrcReg[1].File = (enum register_file) -1;
- inst->SrcReg[2].File = (enum register_file) -1;
- inst->DstReg.File = (enum register_file) -1;
- inst->DstReg.CondSwizzle[0] = 0;
- inst->DstReg.CondSwizzle[1] = 1;
- inst->DstReg.CondSwizzle[2] = 2;
- inst->DstReg.CondSwizzle[3] = 3;
+ _mesa_init_instructions(inst, 1);
/* special instructions */
if (Parse_String(parseState, "DEFINE")) {
(const char *) id, value);
}
else if (Parse_String(parseState, "END")) {
- inst->Opcode = FP_OPCODE_END;
+ inst->Opcode = OPCODE_END;
inst->StringPos = parseState->curLine - parseState->start;
assert(inst->StringPos >= 0);
parseState->numInst++;
/* try to find matching instuction */
instMatch = MatchInstruction(token);
- if (instMatch.opcode < 0) {
+ if (instMatch.opcode >= MAX_OPCODE) {
/* bad instruction name */
RETURN_ERROR2("Unexpected token: ", token);
}
inst->Opcode = instMatch.opcode;
inst->Precision = instMatch.suffixes & (_R | _H | _X);
- inst->Saturate = (instMatch.suffixes & (_S)) ? GL_TRUE : GL_FALSE;
- inst->UpdateCondRegister = (instMatch.suffixes & (_C)) ? GL_TRUE : GL_FALSE;
+ inst->SaturateMode = (instMatch.suffixes & (_S))
+ ? SATURATE_ZERO_ONE : SATURATE_OFF;
+ inst->CondUpdate = (instMatch.suffixes & (_C)) ? GL_TRUE : GL_FALSE;
inst->StringPos = parseState->curLine - parseState->start;
assert(inst->StringPos >= 0);
RETURN_ERROR1("Expected ,");
}
else if (instMatch.outputs == OUTPUT_NONE) {
- ASSERT(instMatch.opcode == FP_OPCODE_KIL_NV);
- /* This is a little weird, the cond code info is in the dest register */
- if (!Parse_CondCodeMask(parseState, &inst->DstReg))
- RETURN_ERROR;
+ if (instMatch.opcode == OPCODE_KIL_NV) {
+ /* This is a little weird, the cond code info is in
+ * the dest register.
+ */
+ if (!Parse_CondCodeMask(parseState, &inst->DstReg))
+ RETURN_ERROR;
+ }
+ else {
+ ASSERT(instMatch.opcode == OPCODE_PRINT);
+ }
}
if (instMatch.inputs == INPUT_1V) {
/* XXX to-do */
}
else if (instMatch.inputs == INPUT_1V_T) {
+ GLubyte unit, idx;
if (!Parse_VectorSrc(parseState, &inst->SrcReg[0]))
RETURN_ERROR;
if (!Parse_String(parseState, ","))
RETURN_ERROR1("Expected ,");
- if (!Parse_TextureImageId(parseState, &inst->TexSrcUnit,
- &inst->TexSrcBit))
+ if (!Parse_TextureImageId(parseState, &unit, &idx))
RETURN_ERROR;
+ inst->TexSrcUnit = unit;
+ inst->TexSrcTarget = idx;
}
else if (instMatch.inputs == INPUT_3V_T) {
+ GLubyte unit, idx;
if (!Parse_VectorSrc(parseState, &inst->SrcReg[0]))
RETURN_ERROR;
if (!Parse_String(parseState, ","))
RETURN_ERROR;
if (!Parse_String(parseState, ","))
RETURN_ERROR1("Expected ,");
- if (!Parse_TextureImageId(parseState, &inst->TexSrcUnit,
- &inst->TexSrcBit))
+ if (!Parse_TextureImageId(parseState, &unit, &idx))
+ RETURN_ERROR;
+ inst->TexSrcUnit = unit;
+ inst->TexSrcTarget = idx;
+ }
+ else if (instMatch.inputs == INPUT_1V_S) {
+ if (!Parse_PrintInstruction(parseState, inst))
RETURN_ERROR;
}
void
_mesa_parse_nv_fragment_program(GLcontext *ctx, GLenum dstTarget,
const GLubyte *str, GLsizei len,
- struct fragment_program *program)
+ struct gl_fragment_program *program)
{
struct parse_state parseState;
- struct fp_instruction instBuffer[MAX_NV_FRAGMENT_PROGRAM_INSTRUCTIONS];
- struct fp_instruction *newInst;
+ struct prog_instruction instBuffer[MAX_NV_FRAGMENT_PROGRAM_INSTRUCTIONS];
+ struct prog_instruction *newInst;
GLenum target;
GLubyte *programString;
/* copy the compiled instructions */
assert(parseState.numInst <= MAX_NV_FRAGMENT_PROGRAM_INSTRUCTIONS);
- newInst = (struct fp_instruction *)
- MALLOC(parseState.numInst * sizeof(struct fp_instruction));
+ newInst = _mesa_alloc_instructions(parseState.numInst);
if (!newInst) {
_mesa_error(ctx, GL_OUT_OF_MEMORY, "glLoadProgramNV");
return; /* out of memory */
}
- MEMCPY(newInst, instBuffer,
- parseState.numInst * sizeof(struct fp_instruction));
+ _mesa_memcpy(newInst, instBuffer,
+ parseState.numInst * sizeof(struct prog_instruction));
/* install the program */
program->Base.Target = target;
}
program->Base.String = programString;
program->Base.Format = GL_PROGRAM_FORMAT_ASCII_ARB;
- if (program->Instructions) {
- FREE(program->Instructions);
+ if (program->Base.Instructions) {
+ _mesa_free(program->Base.Instructions);
}
- program->Instructions = newInst;
- program->InputsRead = parseState.inputsRead;
- program->OutputsWritten = parseState.outputsWritten;
+ program->Base.Instructions = newInst;
+ program->Base.NumInstructions = parseState.numInst;
+ program->Base.InputsRead = parseState.inputsRead;
+ program->Base.OutputsWritten = parseState.outputsWritten;
for (u = 0; u < ctx->Const.MaxTextureImageUnits; u++)
program->TexturesUsed[u] = parseState.texturesUsed[u];
/* save program parameters */
- program->Parameters = parseState.parameters;
+ program->Base.Parameters = parseState.parameters;
/* allocate registers for declared program parameters */
#if 00
static void
-PrintSrcReg(const struct fragment_program *program,
- const struct fp_src_register *src)
+PrintSrcReg(const struct gl_fragment_program *program,
+ const struct prog_src_register *src)
{
static const char comps[5] = "xyzw";
_mesa_printf("-");
}
if (src->File == PROGRAM_NAMED_PARAM) {
- if (program->Parameters->Parameters[src->Index].Type == CONSTANT) {
- printf("{%g, %g, %g, %g}",
- program->Parameters->Parameters[src->Index].Values[0],
- program->Parameters->Parameters[src->Index].Values[1],
- program->Parameters->Parameters[src->Index].Values[2],
- program->Parameters->Parameters[src->Index].Values[3]);
+ if (program->Base.Parameters->Parameters[src->Index].Type
+ == PROGRAM_CONSTANT) {
+ const GLfloat *v;
+ v = program->Base.Parameters->ParameterValues[src->Index];
+ _mesa_printf("{%g, %g, %g, %g}", v[0], v[1], v[2], v[3]);
}
else {
- ASSERT(program->Parameters->Parameters[src->Index].Type
- == NAMED_PARAMETER);
- printf("%s", program->Parameters->Parameters[src->Index].Name);
+ ASSERT(program->Base.Parameters->Parameters[src->Index].Type
+ == PROGRAM_NAMED_PARAM);
+ _mesa_printf("%s", program->Base.Parameters->Parameters[src->Index].Name);
}
}
else if (src->File == PROGRAM_OUTPUT) {
_mesa_problem(NULL, "Invalid fragment register %d", src->Index);
return;
}
- if (src->Swizzle[0] == src->Swizzle[1] &&
- src->Swizzle[0] == src->Swizzle[2] &&
- src->Swizzle[0] == src->Swizzle[3]) {
- _mesa_printf(".%c", comps[src->Swizzle[0]]);
+ if (GET_SWZ(src->Swizzle, 0) == GET_SWZ(src->Swizzle, 1) &&
+ GET_SWZ(src->Swizzle, 0) == GET_SWZ(src->Swizzle, 2) &&
+ GET_SWZ(src->Swizzle, 0) == GET_SWZ(src->Swizzle, 3)) {
+ _mesa_printf(".%c", comps[GET_SWZ(src->Swizzle, 0)]);
}
- else if (src->Swizzle[0] != 0 ||
- src->Swizzle[1] != 1 ||
- src->Swizzle[2] != 2 ||
- src->Swizzle[3] != 3) {
+ else if (src->Swizzle != SWIZZLE_NOOP) {
_mesa_printf(".%c%c%c%c",
- comps[src->Swizzle[0]],
- comps[src->Swizzle[1]],
- comps[src->Swizzle[2]],
- comps[src->Swizzle[3]]);
+ comps[GET_SWZ(src->Swizzle, 0)],
+ comps[GET_SWZ(src->Swizzle, 1)],
+ comps[GET_SWZ(src->Swizzle, 2)],
+ comps[GET_SWZ(src->Swizzle, 3)]);
}
if (src->Abs) {
_mesa_printf("|");
}
static void
-PrintTextureSrc(const struct fp_instruction *inst)
+PrintTextureSrc(const struct prog_instruction *inst)
{
_mesa_printf("TEX%d, ", inst->TexSrcUnit);
- switch (inst->TexSrcBit) {
- case TEXTURE_1D_BIT:
+ switch (inst->TexSrcTarget) {
+ case TEXTURE_1D_INDEX:
_mesa_printf("1D");
break;
- case TEXTURE_2D_BIT:
+ case TEXTURE_2D_INDEX:
_mesa_printf("2D");
break;
- case TEXTURE_3D_BIT:
+ case TEXTURE_3D_INDEX:
_mesa_printf("3D");
break;
- case TEXTURE_RECT_BIT:
+ case TEXTURE_RECT_INDEX:
_mesa_printf("RECT");
break;
- case TEXTURE_CUBE_BIT:
+ case TEXTURE_CUBE_INDEX:
_mesa_printf("CUBE");
break;
default:
}
static void
-PrintCondCode(const struct fp_dst_register *dst)
+PrintCondCode(const struct prog_dst_register *dst)
{
static const char *comps = "xyzw";
static const char *ccString[] = {
};
_mesa_printf("%s", ccString[dst->CondMask]);
- if (dst->CondSwizzle[0] == dst->CondSwizzle[1] &&
- dst->CondSwizzle[0] == dst->CondSwizzle[2] &&
- dst->CondSwizzle[0] == dst->CondSwizzle[3]) {
- _mesa_printf(".%c", comps[dst->CondSwizzle[0]]);
- }
- else if (dst->CondSwizzle[0] != 0 ||
- dst->CondSwizzle[1] != 1 ||
- dst->CondSwizzle[2] != 2 ||
- dst->CondSwizzle[3] != 3) {
+ if (GET_SWZ(dst->CondSwizzle, 0) == GET_SWZ(dst->CondSwizzle, 1) &&
+ GET_SWZ(dst->CondSwizzle, 0) == GET_SWZ(dst->CondSwizzle, 2) &&
+ GET_SWZ(dst->CondSwizzle, 0) == GET_SWZ(dst->CondSwizzle, 3)) {
+ _mesa_printf(".%c", comps[GET_SWZ(dst->CondSwizzle, 0)]);
+ }
+ else if (dst->CondSwizzle != SWIZZLE_NOOP) {
_mesa_printf(".%c%c%c%c",
- comps[dst->CondSwizzle[0]],
- comps[dst->CondSwizzle[1]],
- comps[dst->CondSwizzle[2]],
- comps[dst->CondSwizzle[3]]);
+ comps[GET_SWZ(dst->CondSwizzle, 0)],
+ comps[GET_SWZ(dst->CondSwizzle, 1)],
+ comps[GET_SWZ(dst->CondSwizzle, 2)],
+ comps[GET_SWZ(dst->CondSwizzle, 3)]);
}
}
static void
-PrintDstReg(const struct fp_dst_register *dst)
+PrintDstReg(const struct prog_dst_register *dst)
{
- GLint w = dst->WriteMask[0] + dst->WriteMask[1]
- + dst->WriteMask[2] + dst->WriteMask[3];
-
if (dst->File == PROGRAM_OUTPUT) {
_mesa_printf("o[%s]", OutputRegisters[dst->Index]);
}
_mesa_printf("???");
}
- if (w != 0 && w != 4) {
+ if (dst->WriteMask != 0 && dst->WriteMask != WRITEMASK_XYZW) {
_mesa_printf(".");
- if (dst->WriteMask[0])
+ if (dst->WriteMask & WRITEMASK_X)
_mesa_printf("x");
- if (dst->WriteMask[1])
+ if (dst->WriteMask & WRITEMASK_Y)
_mesa_printf("y");
- if (dst->WriteMask[2])
+ if (dst->WriteMask & WRITEMASK_Z)
_mesa_printf("z");
- if (dst->WriteMask[3])
+ if (dst->WriteMask & WRITEMASK_W)
_mesa_printf("w");
}
if (dst->CondMask != COND_TR ||
- dst->CondSwizzle[0] != 0 ||
- dst->CondSwizzle[1] != 1 ||
- dst->CondSwizzle[2] != 2 ||
- dst->CondSwizzle[3] != 3) {
+ dst->CondSwizzle != SWIZZLE_NOOP) {
_mesa_printf(" (");
PrintCondCode(dst);
_mesa_printf(")");
* Print (unparse) the given vertex program. Just for debugging.
*/
void
-_mesa_print_nv_fragment_program(const struct fragment_program *program)
+_mesa_print_nv_fragment_program(const struct gl_fragment_program *program)
{
- const struct fp_instruction *inst;
+ const struct prog_instruction *inst;
- for (inst = program->Instructions; inst->Opcode != FP_OPCODE_END; inst++) {
+ for (inst = program->Base.Instructions; inst->Opcode != OPCODE_END; inst++) {
int i;
for (i = 0; Instructions[i].name; i++) {
if (inst->Opcode == Instructions[i].opcode) {
_mesa_printf("H");
else if (inst->Precision == FIXED12)
_mesa_printf("X");
- if (inst->UpdateCondRegister)
+ if (inst->CondUpdate)
_mesa_printf("C");
- if (inst->Saturate)
+ if (inst->SaturateMode == SATURATE_ZERO_ONE)
_mesa_printf("_SAT");
_mesa_printf(" ");