summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBrian Paul <brian.paul@tungstengraphics.com>2003-02-16 23:07:34 +0000
committerBrian Paul <brian.paul@tungstengraphics.com>2003-02-16 23:07:34 +0000
commit2c1912fe84d110d4c8cccc207827a154c09dd09a (patch)
treeccb6cfadd52472b444a27a88e088b118ec9ad910
parenta89cc0edad31001a4207e180e618004fc43c82eb (diff)
more work on DEFINE/DECLARATION statements, symbol tables
-rw-r--r--src/mesa/main/mtypes.h8
-rw-r--r--src/mesa/main/nvfragparse.c253
-rw-r--r--src/mesa/main/nvprogram.c122
-rw-r--r--src/mesa/main/nvprogram.h24
4 files changed, 264 insertions, 143 deletions
diff --git a/src/mesa/main/mtypes.h b/src/mesa/main/mtypes.h
index 4c3fb3bbd4..716bbfcf85 100644
--- a/src/mesa/main/mtypes.h
+++ b/src/mesa/main/mtypes.h
@@ -1,4 +1,4 @@
-/* $Id: mtypes.h,v 1.102 2003/01/26 14:37:15 brianp Exp $ */
+/* $Id: mtypes.h,v 1.103 2003/02/16 23:07:34 brianp Exp $ */
/*
* Mesa 3-D graphics library
@@ -1177,6 +1177,11 @@ struct fp_machine
struct vp_instruction;
struct fp_instruction;
+struct symbol_table
+{
+ struct symbol *Head;
+};
+
/* Base class for any kind of program object */
struct program
@@ -1208,6 +1213,7 @@ struct fragment_program
GLuint InputsRead; /* Bitmask of which input regs are read */
GLuint OutputsWritten; /* Bitmask of which output regs are written to */
GLfloat LocalParams[MAX_NV_FRAGMENT_PROGRAM_PARAMS][4];
+ struct symbol_table SymbolTable;
};
diff --git a/src/mesa/main/nvfragparse.c b/src/mesa/main/nvfragparse.c
index 05d0ac5452..7b9208d521 100644
--- a/src/mesa/main/nvfragparse.c
+++ b/src/mesa/main/nvfragparse.c
@@ -1,4 +1,4 @@
-/* $Id: nvfragparse.c,v 1.3 2003/02/08 15:56:34 brianp Exp $ */
+/* $Id: nvfragparse.c,v 1.4 2003/02/16 23:07:35 brianp Exp $ */
/*
* Mesa 3-D graphics library
@@ -142,14 +142,18 @@ static const struct instruction_pattern Instructions[] = {
/**********************************************************************/
+/* XXX not used yet */
struct parse_state {
const GLubyte *start; /* start of program */
const GLubyte *end; /* one char past end of the program */
const GLubyte *s; /* current position */
GLboolean IsStateProgram;
GLboolean IsVersion1_1;
+ struct fragment_program *currentProgram;
};
+/* XXX temporary hack */
+static struct fragment_program *CurrentProgram = NULL;
/*
@@ -476,13 +480,13 @@ Parse_Identifier(const char **s, char *ident)
/**
- * Parse a floating point constant.
+ * Parse a floating point constant, or a defined symbol name.
* [+/-]N[.N[eN]]
*/
static GLboolean
Parse_ScalarConstant(const char **s, GLfloat *number)
{
- char *end;
+ char *end = NULL;
*number = (GLfloat) _mesa_strtod(*s, &end);
@@ -496,8 +500,9 @@ Parse_ScalarConstant(const char **s, GLfloat *number)
char ident[100];
if (!Parse_Identifier(s, ident))
PARSE_ERROR1("Expected an identifier");
- /* XXX Look up the value in the symbol table */
- *number = -999;
+ if (!_mesa_lookup_symbol(&(CurrentProgram->SymbolTable), ident, number)) {
+ PARSE_ERROR1("Undefined symbol");
+ }
return GL_TRUE;
}
}
@@ -571,7 +576,11 @@ Parse_VectorConstant(const char **s, GLfloat *vec)
}
-static GLboolean
+/**
+ * Parse <number>, <varname> or {a, b, c, d}.
+ * Return number of values in the vector or scalar, or zero if parse error.
+ */
+static GLuint
Parse_VectorOrScalarConstant(const char **s, GLfloat *vec)
{
char token[100];
@@ -1082,7 +1091,8 @@ Parse_ScalarSrcReg(const char **s, struct fp_src_register *srcReg)
static GLboolean
-Parse_InstructionSequence(const char **s, struct fp_instruction program[])
+Parse_InstructionSequence(struct fragment_program *fragProg,
+ const char **s, struct fp_instruction program[])
{
char token[100];
GLint count = 0;
@@ -1107,19 +1117,22 @@ Parse_InstructionSequence(const char **s, struct fp_instruction program[])
/* special instructions */
if (StrEq(token, "DEFINE")) {
char id[100];
- GLfloat value[4];
+ GLfloat value[7]; /* yes, 7 to be safe */
if (!Parse_Identifier(s, id))
PARSE_ERROR;
if (!Parse_String(s, "="))
PARSE_ERROR1("Expected = symbol");
if (!Parse_VectorOrScalarConstant(s, value))
PARSE_ERROR;
+ if (!Parse_String(s, ";"))
+ PARSE_ERROR1("Expected ;");
printf("Parsed DEFINE %s = %f %f %f %f\n", id, value[0], value[1],
value[2], value[3]);
+ _mesa_add_symbol(&(fragProg->SymbolTable), id, Definition, value);
}
else if (StrEq(token, "DECLARE")) {
char id[100];
- GLfloat value[4];
+ GLfloat value[7] = {0, 0, 0, 0, 0, 0, 0}; /* yes, to be safe */
if (!Parse_Identifier(s, id))
PARSE_ERROR;
if (!Peek_Token(s, token))
@@ -1128,128 +1141,128 @@ Parse_InstructionSequence(const char **s, struct fp_instruction program[])
Parse_String(s, "=");
if (!Parse_VectorOrScalarConstant(s, value))
PARSE_ERROR;
- printf("Parsed DECLARE %s = %f %f %f %f\n", id, value[0], value[1],
- value[2], value[3]);
+ printf("Parsed DECLARE %s = %f %f %f %f\n", id,
+ value[0], value[1], value[2], value[3]);
}
else {
printf("Parsed DECLARE %s\n", id);
}
+ if (!Parse_String(s, ";"))
+ PARSE_ERROR1("Expected ;");
+ _mesa_add_symbol(&(fragProg->SymbolTable), id, Declaration, value);
}
+ else {
+ /* arithmetic instruction */
+
+ /* try to find matching instuction */
+ instMatch = MatchInstruction(token);
+ if (instMatch.opcode < 0) {
+ /* bad instruction name */
+ printf("-------- errror\n");
+ PARSE_ERROR2("Unexpected token: ", token);
+ }
- /* try to find matching instuction */
- instMatch = MatchInstruction(token);
- if (instMatch.opcode < 0) {
- /* bad instruction name */
- PARSE_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->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;
- /*
- * parse the input and output operands
- */
- if (instMatch.outputs == OUTPUT_S || instMatch.outputs == OUTPUT_V) {
- if (!Parse_MaskedDstReg(s, &inst->DstReg))
- PARSE_ERROR;
- if (!Parse_String(s, ","))
- PARSE_ERROR;
- }
- else if (instMatch.outputs == OUTPUT_NONE) {
- ASSERT(instMatch.opcode == FP_OPCODE_KIL);
- /* This is a little weird, the cond code info is in the dest register */
- if (!Parse_CondCodeMask(s, &inst->DstReg))
- PARSE_ERROR;
- }
+ /*
+ * parse the input and output operands
+ */
+ if (instMatch.outputs == OUTPUT_S || instMatch.outputs == OUTPUT_V) {
+ if (!Parse_MaskedDstReg(s, &inst->DstReg))
+ PARSE_ERROR;
+ if (!Parse_String(s, ","))
+ PARSE_ERROR;
+ }
+ else if (instMatch.outputs == OUTPUT_NONE) {
+ ASSERT(instMatch.opcode == FP_OPCODE_KIL);
+ /* This is a little weird, the cond code info is in the dest register */
+ if (!Parse_CondCodeMask(s, &inst->DstReg))
+ PARSE_ERROR;
+ }
- if (instMatch.inputs == INPUT_1V) {
- if (!Parse_SwizzleSrcReg(s, &inst->SrcReg[0]))
- PARSE_ERROR;
- }
- else if (instMatch.inputs == INPUT_2V) {
- if (!Parse_SwizzleSrcReg(s, &inst->SrcReg[0]))
- PARSE_ERROR;
- if (!Parse_String(s, ","))
- PARSE_ERROR;
- if (!Parse_SwizzleSrcReg(s, &inst->SrcReg[1]))
- PARSE_ERROR;
- }
- else if (instMatch.inputs == INPUT_3V) {
- if (!Parse_SwizzleSrcReg(s, &inst->SrcReg[1]))
- PARSE_ERROR;
- if (!Parse_String(s, ","))
- PARSE_ERROR;
- if (!Parse_SwizzleSrcReg(s, &inst->SrcReg[1]))
- PARSE_ERROR;
- if (!Parse_String(s, ","))
- PARSE_ERROR;
- if (!Parse_SwizzleSrcReg(s, &inst->SrcReg[1]))
- PARSE_ERROR;
- }
- else if (instMatch.inputs == INPUT_1S) {
- if (!Parse_ScalarSrcReg(s, &inst->SrcReg[1]))
- PARSE_ERROR;
- }
- else if (instMatch.inputs == INPUT_2S) {
- if (!Parse_ScalarSrcReg(s, &inst->SrcReg[0]))
- PARSE_ERROR;
- if (!Parse_String(s, ","))
- PARSE_ERROR;
- if (!Parse_ScalarSrcReg(s, &inst->SrcReg[1]))
- PARSE_ERROR;
- }
- else if (instMatch.inputs == INPUT_CC) {
+ if (instMatch.inputs == INPUT_1V) {
+ if (!Parse_SwizzleSrcReg(s, &inst->SrcReg[0]))
+ PARSE_ERROR;
+ }
+ else if (instMatch.inputs == INPUT_2V) {
+ if (!Parse_SwizzleSrcReg(s, &inst->SrcReg[0]))
+ PARSE_ERROR;
+ if (!Parse_String(s, ","))
+ PARSE_ERROR;
+ if (!Parse_SwizzleSrcReg(s, &inst->SrcReg[1]))
+ PARSE_ERROR;
+ }
+ else if (instMatch.inputs == INPUT_3V) {
+ if (!Parse_SwizzleSrcReg(s, &inst->SrcReg[1]))
+ PARSE_ERROR;
+ if (!Parse_String(s, ","))
+ PARSE_ERROR;
+ if (!Parse_SwizzleSrcReg(s, &inst->SrcReg[1]))
+ PARSE_ERROR;
+ if (!Parse_String(s, ","))
+ PARSE_ERROR;
+ if (!Parse_SwizzleSrcReg(s, &inst->SrcReg[1]))
+ PARSE_ERROR;
+ }
+ else if (instMatch.inputs == INPUT_1S) {
+ if (!Parse_ScalarSrcReg(s, &inst->SrcReg[1]))
+ PARSE_ERROR;
+ }
+ else if (instMatch.inputs == INPUT_2S) {
+ if (!Parse_ScalarSrcReg(s, &inst->SrcReg[0]))
+ PARSE_ERROR;
+ if (!Parse_String(s, ","))
+ PARSE_ERROR;
+ if (!Parse_ScalarSrcReg(s, &inst->SrcReg[1]))
+ PARSE_ERROR;
+ }
+ else if (instMatch.inputs == INPUT_CC) {
#if 00
- if (!ParseCondCodeSrc(s, &inst->srcReg[0]))
- PARSE_ERROR;
+ if (!ParseCondCodeSrc(s, &inst->srcReg[0]))
+ PARSE_ERROR;
#endif
- }
- else if (instMatch.inputs == INPUT_1V_T) {
- if (!Parse_SwizzleSrcReg(s, &inst->SrcReg[0]))
- PARSE_ERROR;
- if (!Parse_String(s, ","))
- PARSE_ERROR;
- if (!Parse_TextureImageId(s, &inst->TexSrcUnit, &inst->TexSrcTarget))
- PARSE_ERROR;
- }
- else if (instMatch.inputs == INPUT_1V_T) {
- if (!Parse_SwizzleSrcReg(s, &inst->SrcReg[0]))
- PARSE_ERROR;
- if (!Parse_String(s, ","))
- PARSE_ERROR;
- if (!Parse_SwizzleSrcReg(s, &inst->SrcReg[1]))
- PARSE_ERROR;
- if (!Parse_String(s, ","))
- PARSE_ERROR;
- if (!Parse_SwizzleSrcReg(s, &inst->SrcReg[2]))
- PARSE_ERROR;
- if (!Parse_String(s, ","))
- PARSE_ERROR;
- if (!Parse_TextureImageId(s, &inst->TexSrcUnit, &inst->TexSrcTarget))
- PARSE_ERROR;
- }
+ }
+ else if (instMatch.inputs == INPUT_1V_T) {
+ if (!Parse_SwizzleSrcReg(s, &inst->SrcReg[0]))
+ PARSE_ERROR;
+ if (!Parse_String(s, ","))
+ PARSE_ERROR;
+ if (!Parse_TextureImageId(s, &inst->TexSrcUnit, &inst->TexSrcTarget))
+ PARSE_ERROR;
+ }
+ else if (instMatch.inputs == INPUT_1V_T) {
+ if (!Parse_SwizzleSrcReg(s, &inst->SrcReg[0]))
+ PARSE_ERROR;
+ if (!Parse_String(s, ","))
+ PARSE_ERROR;
+ if (!Parse_SwizzleSrcReg(s, &inst->SrcReg[1]))
+ PARSE_ERROR;
+ if (!Parse_String(s, ","))
+ PARSE_ERROR;
+ if (!Parse_SwizzleSrcReg(s, &inst->SrcReg[2]))
+ PARSE_ERROR;
+ if (!Parse_String(s, ","))
+ PARSE_ERROR;
+ if (!Parse_TextureImageId(s, &inst->TexSrcUnit, &inst->TexSrcTarget))
+ PARSE_ERROR;
+ }
- /* end of statement semicolon */
- if (!Parse_String(s, ";"))
- PARSE_ERROR;
+ /* end of statement semicolon */
+ if (!Parse_String(s, ";"))
+ PARSE_ERROR;
- count++;
- if (count >= MAX_NV_FRAGMENT_PROGRAM_INSTRUCTIONS)
- PARSE_ERROR1("Program too long");
+ count++;
+ if (count >= MAX_NV_FRAGMENT_PROGRAM_INSTRUCTIONS)
+ PARSE_ERROR1("Program too long");
+ }
}
return GL_TRUE;
}
-static GLboolean
-Parse_Program(const char **s, struct fp_instruction instBuffer[])
-{
- return Parse_InstructionSequence(s, instBuffer);
-}
-
-
/**
* Parse/compile the 'str' returning the compiled 'program'.
* ctx->Program.ErrorPos will be -1 if successful. Otherwise, ErrorPos
@@ -1297,7 +1310,10 @@ _mesa_parse_nv_fragment_program(GLcontext *ctx, GLenum dstTarget,
return;
}
- if (Parse_Program(&s, instBuffer)) {
+ /* XXX temporary */
+ CurrentProgram = program;
+
+ if (Parse_InstructionSequence(program, &s, instBuffer)) {
GLuint numInst;
GLuint strLen;
GLuint inputsRead = 0;
@@ -1323,10 +1339,10 @@ _mesa_parse_nv_fragment_program(GLcontext *ctx, GLenum dstTarget,
if ((r = InputRegisterNumber(srcReg0)) >= 0
&& !instBuffer[numInst].SrcReg[0].RelAddr)
inputsRead |= (1 << r);
- if ((r = InputRegisterNumber(srcReg1) >= 0
+ if ((r = InputRegisterNumber(srcReg1)) >= 0
&& !instBuffer[numInst].SrcReg[1].RelAddr)
inputsRead |= (1 << r);
- if ((r = InputRegisterNumber(srcReg2) >= 0
+ if ((r = InputRegisterNumber(srcReg2)) >= 0
&& !instBuffer[numInst].SrcReg[2].RelAddr)
inputsRead |= (1 << r);
#endif
@@ -1367,6 +1383,9 @@ _mesa_parse_nv_fragment_program(GLcontext *ctx, GLenum dstTarget,
}
program->Instructions = newInst;
+ /* allocate registers for declared program parameters */
+ _mesa_assign_program_registers(&(program->SymbolTable));
+
#ifdef DEBUG
_mesa_printf("--- glLoadProgramNV result ---\n");
_mesa_print_nv_fragment_program(program);
diff --git a/src/mesa/main/nvprogram.c b/src/mesa/main/nvprogram.c
index d09e7afbee..b6960c0df8 100644
--- a/src/mesa/main/nvprogram.c
+++ b/src/mesa/main/nvprogram.c
@@ -1,4 +1,4 @@
-/* $Id: nvprogram.c,v 1.2 2003/02/10 20:31:11 alanh Exp $ */
+/* $Id: nvprogram.c,v 1.3 2003/02/16 23:07:36 brianp Exp $ */
/*
* Mesa 3-D graphics library
@@ -45,6 +45,86 @@
#include "nvprogram.h"
+/**
+ * Symbol table entry.
+ * Used for named program parameters.
+ */
+struct symbol
+{
+ const char *Name;
+ enum symbol_type Type;
+ GLfloat Value[4];
+ GLuint Register;
+ struct symbol *Next;
+};
+
+
+
+void
+_mesa_add_symbol(struct symbol_table *symbolTable,
+ const char *name, enum symbol_type type, const GLfloat *value)
+{
+ struct symbol *s = MALLOC_STRUCT(symbol);
+ if (s) {
+ s->Name = _mesa_strdup(name);
+ s->Type = type;
+ s->Value[0] = value[0];
+ s->Value[1] = value[1];
+ s->Value[2] = value[2];
+ s->Value[3] = value[3];
+ s->Next = symbolTable->Head;
+ symbolTable->Head = s;
+ }
+}
+
+
+GLboolean
+_mesa_lookup_symbol(const struct symbol_table *symbolTable,
+ const char *name, GLfloat *value)
+{
+ const struct symbol *s;
+ for (s = symbolTable->Head; s; s = s->Next) {
+ if (_mesa_strcmp(s->Name, name) == 0) {
+ value[0] = s->Value[0];
+ value[1] = s->Value[1];
+ value[2] = s->Value[2];
+ value[3] = s->Value[3];
+ return GL_TRUE;
+ }
+ }
+ printf("lookup %s failed\n", name);
+ return GL_FALSE;
+}
+
+
+static GLint
+_mesa_lookup_program_register(const struct symbol_table *symbolTable,
+ GLsizei len, const GLubyte *name)
+{
+ const struct symbol *s;
+ for (s = symbolTable->Head; s; s = s->Next) {
+ if (_mesa_strcmp(s->Name, (const char *) name) == 0 &&
+ _mesa_strlen(s->Name) == len) {
+ return s->Register;
+ }
+ }
+ return -1;
+}
+
+
+void
+_mesa_assign_program_registers(struct symbol_table *symbolTable)
+{
+ struct symbol *s;
+ GLuint reg = 0;
+ for (s = symbolTable->Head; s; s = s->Next) {
+ if (s->Type == Declaration) {
+ s->Register = reg++;
+ }
+ }
+}
+
+
/**
* Set the vertex/fragment program error state (position and error string).
@@ -984,20 +1064,13 @@ _mesa_TrackMatrixNV(GLenum target, GLuint address,
}
-static GLfloat *
-lookup_program_parameter(struct fragment_program *fprog,
- GLsizei len, const GLubyte *name)
-{
- return NULL;
-}
-
-
void
glProgramNamedParameter4fNV(GLuint id, GLsizei len, const GLubyte *name,
GLfloat x, GLfloat y, GLfloat z, GLfloat w)
{
struct program *prog;
- GLfloat *p;
+ struct fragment_program *fragProg;
+ GLint reg;
GET_CURRENT_CONTEXT(ctx);
ASSERT_OUTSIDE_BEGIN_END(ctx);
@@ -1012,16 +1085,17 @@ glProgramNamedParameter4fNV(GLuint id, GLsizei len, const GLubyte *name,
return;
}
- p = lookup_program_parameter((struct fragment_program *) prog, len, name);
- if (!p) {
+ fragProg = (struct fragment_program *) prog;
+ reg = _mesa_lookup_program_register(&(fragProg->SymbolTable), len, name);
+ if (reg < 0) {
_mesa_error(ctx, GL_INVALID_VALUE, "glProgramNamedParameterNV");
return;
}
- p[0] = x;
- p[1] = y;
- p[2] = z;
- p[3] = w;
+ fragProg->LocalParams[reg][0] = x;
+ fragProg->LocalParams[reg][1] = y;
+ fragProg->LocalParams[reg][2] = z;
+ fragProg->LocalParams[reg][3] = w;
}
@@ -1056,7 +1130,8 @@ glGetProgramNamedParameterfvNV(GLuint id, GLsizei len, const GLubyte *name,
GLfloat *params)
{
struct program *prog;
- const GLfloat *p;
+ struct fragment_program *fragProg;
+ GLint reg;
GET_CURRENT_CONTEXT(ctx);
ASSERT_OUTSIDE_BEGIN_END(ctx);
@@ -1071,16 +1146,17 @@ glGetProgramNamedParameterfvNV(GLuint id, GLsizei len, const GLubyte *name,
return;
}
- p = lookup_program_parameter((struct fragment_program *) prog, len, name);
- if (!p) {
+ fragProg = (struct fragment_program *) prog;
+ reg = _mesa_lookup_program_register(&(fragProg->SymbolTable), len, name);
+ if (reg < 0) {
_mesa_error(ctx, GL_INVALID_VALUE, "glGetProgramNamedParameterNV");
return;
}
- params[0] = p[0];
- params[1] = p[1];
- params[2] = p[2];
- params[3] = p[3];
+ params[0] = fragProg->LocalParams[reg][0];
+ params[1] = fragProg->LocalParams[reg][1];
+ params[2] = fragProg->LocalParams[reg][2];
+ params[3] = fragProg->LocalParams[reg][3];
}
diff --git a/src/mesa/main/nvprogram.h b/src/mesa/main/nvprogram.h
index 3ede705722..5d31ebba3b 100644
--- a/src/mesa/main/nvprogram.h
+++ b/src/mesa/main/nvprogram.h
@@ -1,10 +1,10 @@
-/* $Id: nvprogram.h,v 1.1 2003/01/14 04:55:46 brianp Exp $ */
+/* $Id: nvprogram.h,v 1.2 2003/02/16 23:07:36 brianp Exp $ */
/*
* Mesa 3-D graphics library
* Version: 5.1
*
- * Copyright (C) 1999-2001 Brian Paul All Rights Reserved.
+ * Copyright (C) 1999-2003 Brian Paul All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
@@ -32,6 +32,26 @@
#define NVPROGRAM_H
+enum symbol_type
+{
+ Definition,
+ Declaration
+};
+
+
+extern void
+_mesa_add_symbol(struct symbol_table *symbolTable,
+ const char *name, enum symbol_type type,
+ const GLfloat *value);
+
+extern GLboolean
+_mesa_lookup_symbol(const struct symbol_table *symbolTable,
+ const char *name, GLfloat *value);
+
+extern void
+_mesa_assign_program_registers(struct symbol_table *symbolTable);
+
+
extern void
_mesa_set_program_error(GLcontext *ctx, GLint pos, const char *string);