/*
* Mesa 3-D graphics library
- * Version: 5.1
+ * Version: 6.0
*
- * Copyright (C) 1999-2003 Brian Paul All Rights Reserved.
+ * Copyright (C) 1999-2004 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"),
* \author Michal Krol, Karl Rasche
*/
-
#include "mtypes.h"
#include "glheader.h"
#include "context.h"
#include "nvfragprog.h"
#include "arbparse.h"
-
/* TODO:
* Fragment Program Stuff:
* -----------------------------------------------------
- * - How does negating on SWZ work?? If any of the components have a -, negate?
- * - how does thing like 'foo[N]' work in src registers?
*
* - things from Michal's email
* + overflow on atoi
* + not-overflowing floats (don't use parse_integer..)
- *
- * + fix multiple cases in switches, that might change
- * (these are things that are #defined to the same value, but occur
- * only on fp or vp's, which funkifies the switch statements)
- * - STATE_TEX_* STATE_CLIP_PLANE, etc and PRECISION_HINT_FASTEST/PositionInvariant
- *
+ * + can remove range checking in arbparse.c
+ *
* - check all limits of number of various variables
* + parameters
- * + modelview matrix number
*
* - test! test! test!
*
* Vertex Program Stuff:
* -----------------------------------------------------
- * - Add in cases for vp attribs
- * + VERTEX_ATTRIB_MATRIXINDEX -- ??
- * + VERTEX_ATTRIB_GENERIC
- * * Test for input alias error --> bleh!
- *
- * - ARRAY_INDEX_RELATIVE
+ * - Optimize param array usage and count limits correctly, see spec,
+ * section 2.14.3.7
+ * + Record if an array is reference absolutly or relatively (or both)
+ * + For absolute arrays, store a bitmap of accesses
+ * + For single parameters, store an access flag
+ * + After parsing, make a parameter cleanup and merging pass, where
+ * relative arrays are layed out first, followed by abs arrays, and
+ * finally single state.
+ * + Remap offsets for param src and dst registers
+ * + Now we can properly count parameter usage
+ *
+ * - Multiple state binding errors in param arrays (see spec, just before
+ * section 2.14.3.3)
* - grep for XXX
*
* Mesa Stuff
* -----------------------------------------------------
+ * - User clipping planes vs. PositionInvariant
+ * - Is it sufficient to just multiply by the mvp to transform in the
+ * PositionInvariant case? Or do we need something more involved?
+ *
* - vp_src swizzle is GLubyte, fp_src swizzle is GLuint
* - fetch state listed in program_parameters list
* + WTF should this go???
*
* Cosmetic Stuff
* -----------------------------------------------------
- * - fix compiler warnings
* - remove any leftover unused grammer.c stuff (dict_ ?)
* - fix grammer.c error handling so its not static
* - #ifdef around stuff pertaining to extentions
*
* Outstanding Questions:
* -----------------------------------------------------
- * - palette matrix? do we support this extension? what is the extention?
- * - When can we fetch env/local params from their own register files, and when
- * to we have to fetch them into the main state register file? (think arrays)
+ * - ARB_matrix_palette / ARB_vertex_blend -- not supported
+ * what gets hacked off because of this:
+ * + VERTEX_ATTRIB_MATRIXINDEX
+ * + VERTEX_ATTRIB_WEIGHT
+ * + MATRIX_MODELVIEW
+ * + MATRIX_PALETTE
+ *
+ * - When can we fetch env/local params from their own register files, and
+ * when to we have to fetch them into the main state register file?
+ * (think arrays)
*
* Grammar Changes:
* -----------------------------------------------------
- * - changed optional_exponent rule from:
- * " exponent .or .true .emit '1' .emit 0x00;\n"
- * to
- * " exponent .or .true .emit '1' .emit 0x00 .emit $;\n"
- *
- * - XXX: need to recognize "1" as a valid float ?
*/
-typedef unsigned char byte;
-typedef byte *production;
+typedef GLubyte *production;
/*-----------------------------------------------------------------------
* From here on down is the syntax checking portion
*/
-/* VERSION: 0.3 */
+/* VERSION: 0.4 */
/*
- INTRODUCTION
- ------------
-
- The task is to check the syntax of an input string. Input string is a stream of ASCII
- characters terminated with null-character ('\0'). Checking it using C language is
- difficult and hard to implement without bugs. It is hard to maintain and change prior
- to further syntax changes.
-
- This is because of high redundancy of the C code. Large blocks of code are duplicated with
- only small changes. Even using macros does not solve the problem, because macros cannot
- erase the complexity of the code.
-
- The resolution is to create a new language that will be highly oriented to our task. Once
- we describe particular syntax, we are done. We can then focus on the code that implements
- the language. The size and complexity of it is relatively small than the code that directly
- checks the syntax.
-
- First, we must implement our new language. Here, the language is implemented in C, but it
- could also be implemented in any other language. The code is listed below. We must take
- a good care that it is bug free. This is simple because the code is simple and clean.
-
- Next, we must describe the syntax of our new language in itself. Once created and checked
- manually that it is correct, we can use it to check another scripts.
-
- Note that our new language loading code does not have to check the syntax. It is because we
- assume that the script describing itself is correct, and other scripts can be syntactically
- checked by the former script. The loading code must only do semantic checking which leads us to
- simple resolving references.
-
- THE LANGUAGE
- ------------
-
- Here I will describe the syntax of the new language (further called "Synek"). It is mainly a
- sequence of declarations terminated by a semicolon. The declaration consists of a symbol,
- which is an identifier, and its definition. A definition is in turn a sequence of specifiers
- connected with ".and" or ".or" operator. These operators cannot be mixed together in a one
- definition. Specifier can be a symbol, string, character, character range or a special
- keyword ".true" or ".false".
-
- On the very beginning of the script there is a declaration of a root symbol and is in the form:
+INTRODUCTION
+------------
+
+The task is to check the syntax of an input string. Input string is a
+stream of ASCII characters terminated with null-character
+('\0'). Checking it using C language is difficult and hard to
+implement without bugs. It is hard to maintain and change prior to
+further syntax changes.
+
+This is because of high redundancy of the C code. Large blocks of code
+are duplicated with only small changes. Even using macros does not
+solve the problem, because macros cannot erase the complexity of the
+code.
+
+The resolution is to create a new language that will be highly
+oriented to our task. Once we describe particular syntax, we are
+done. We can then focus on the code that implements the language. The
+size and complexity of it is relatively small than the code that
+directly checks the syntax.
+
+First, we must implement our new language. Here, the language is
+implemented in C, but it could also be implemented in any other
+language. The code is listed below. We must take a good care that it
+is bug free. This is simple because the code is simple and clean.
+
+Next, we must describe the syntax of our new language in itself. Once
+created and checked manually that it is correct, we can use it to
+check another scripts.
+
+Note that our new language loading code does not have to check the
+syntax. It is because we assume that the script describing itself is
+correct, and other scripts can be syntactically checked by the former
+script. The loading code must only do semantic checking which leads us
+to simple resolving references.
+
+THE LANGUAGE
+------------
+
+Here I will describe the syntax of the new language (further called
+"Synek"). It is mainly a sequence of declarations terminated by a
+semicolon. The declaration consists of a symbol, which is an
+identifier, and its definition. A definition is in turn a sequence of
+specifiers connected with ".and" or ".or" operator. These operators
+cannot be mixed together in a one definition. Specifier can be a
+symbol, string, character, character range or a special keyword
+".true" or ".false".
+
+On the very beginning of the script there is a declaration of a root
+symbol and is in the form:
.syntax <root_symbol>;
- The <root_symbol> must be on of the symbols in declaration sequence. The syntax is correct if
- the root symbol evaluates to true. A symbol evaluates to true if the definition associated with
- the symbol evaluates to true. Definition evaluation depends on the operator used to connect
- specifiers in the definition. If ".and" operator is used, definition evaluates to true if and
- only if all the specifiers evaluate to true. If ".or" operator is used, definition evalutes to
- true if any of the specifiers evaluates to true. If definition contains only one specifier,
- it is evaluated as if it was connected with ".true" keyword by ".and" operator.
-
- If specifier is a ".true" keyword, it always evaluates to true.
-
- If specifier is a ".false" keyword, it always evaluates to false. Specifier evaluates to false
- when it does not evaluate to true.
-
- Character range specifier is in the form:
- '<first_character>' - '<second_character>'
- If specifier is a character range, it evaluates to true if character in the stream is greater
- or equal to <first_character> and less or equal to <second_character>. In that situation
- the stream pointer is advanced to point to next character in the stream. All C-style escape
- sequences are supported although trigraph sequences are not. The comparisions are performed
- on 8-bit unsigned integers.
-
- Character specifier is in the form:
- '<single_character>'
- It evaluates to true if the following character range specifier evaluates to true:
- '<single_character>' - '<single_character>'
-
- String specifier is in the form:
+
+The <root_symbol> must be on of the symbols in declaration
+sequence. The syntax is correct if the root symbol evaluates to
+true. A symbol evaluates to true if the definition associated with the
+symbol evaluates to true. Definition evaluation depends on the
+operator used to connect specifiers in the definition. If ".and"
+operator is used, definition evaluates to true if and only if all the
+specifiers evaluate to true. If ".or" operator is used, definition
+evalutes to true if any of the specifiers evaluates to true. If
+definition contains only one specifier, it is evaluated as if it was
+connected with ".true" keyword by ".and" operator.
+
+If specifier is a ".true" keyword, it always evaluates to true.
+
+If specifier is a ".false" keyword, it always evaluates to
+false. Specifier evaluates to false when it does not evaluate to true.
+
+Character range specifier is in the form:
+ '<first_character>' - '<second_character>'
+
+If specifier is a character range, it evaluates to true if character
+in the stream is greater or equal to <first_character> and less or
+equal to <second_character>. In that situation the stream pointer is
+advanced to point to next character in the stream. All C-style escape
+sequences are supported although trigraph sequences are not. The
+comparisions are performed on 8-bit unsigned integers.
+
+Character specifier is in the form:
+ '<single_character>'
+
+It evaluates to true if the following character range specifier evaluates to
+true:
+ '<single_character>' - '<single_character>'
+
+String specifier is in the form:
"<string>"
- Let N be the number of characters in <string>. Let <string>[i] designate i-th character in
- <string>. Then the string specifier evaluates to true if and only if for i in the range [0, N)
- the following character specifier evaluates to true:
- '<string>[i]'
- If <string>[i] is a quotation mark, '<string>[i]' is replaced with '\<string>[i]'.
-
- Symbol specifier can be optionally preceded by a ".loop" keyword in the form:
- .loop <symbol> (1)
+
+Let N be the number of characters in <string>. Let <string>[i]
+designate i-th character in <string>. Then the string specifier
+evaluates to true if and only if for i in the range [0, N) the
+following character specifier evaluates to true:
+ '<string>[i]'
+
+If <string>[i] is a quotation mark, '<string>[i]' is replaced with
+'\<string>[i]'.
+
+Symbol specifier can be optionally preceded by a ".loop" keyword in the form:
+ .loop <symbol> (1)
where <symbol> is defined as follows:
<symbol> <definition>; (2)
Construction (1) is replaced by the following code:
<symbol$2> <symbol> .and <symbol$1>;
<symbol> <definition>;
- ESCAPE SEQUENCES
- ----------------
-
- Synek supports all escape sequences in character specifiers. The mapping table is listed below.
- All occurences of the characters in the first column are replaced with the corresponding
- character in the second column.
-
- Escape sequence Represents
- ------------------------------------------------------------------------------------------------
- \a Bell (alert)
- \b Backspace
- \f Formfeed
- \n New line
- \r Carriage return
- \t Horizontal tab
- \v Vertical tab
- \' Single quotation mark
- \" Double quotation mark
- \\ Backslash
- \? Literal question mark
- \ooo ASCII character in octal notation
- \xhhh ASCII character in hexadecimal notation
- ------------------------------------------------------------------------------------------------
-
- RAISING ERRORS
- --------------
-
- Any specifier can be followed by a special construction that is executed when the specifier
- evaluates to false. The construction is in the form:
- .error <ERROR_TEXT>
- <ERROR_TEXT> is an identifier declared earlier by error text declaration. The declaration is
- in the form:
- .errtext <ERROR_TEXT> "<error_desc>"
- When specifier evaluates to false and this construction is present, parsing is stopped
- immediately and <error_desc> is returned as a result of parsing. The error position is also
- returned and it is meant as an offset from the beggining of the stream to the character that
- was valid so far. Example:
-
- (**** syntax script ****)
-
- .syntax program;
- .errtext MISSING_SEMICOLON "missing ';'"
- program declaration .and .loop space .and ';' .error MISSING_SEMICOLON .and
- .loop space .and '\0';
- declaration "declare" .and .loop space .and identifier;
- space ' ';
+ESCAPE SEQUENCES
+----------------
+
+Synek supports all escape sequences in character specifiers. The
+mapping table is listed below. All occurences of the characters in
+the first column are replaced with the corresponding character in the
+second column.
+
+ Escape sequence Represents
+ -----------------------------------------------------------------------
+ \a Bell (alert)
+ \b Backspace
+ \f Formfeed
+ \n New line
+ \r Carriage return
+ \t Horizontal tab
+ \v Vertical tab
+ \' Single quotation mark
+ \" Double quotation mark
+ \\ Backslash
+ \? Literal question mark
+ \ooo ASCII character in octal notation
+ \xhhh ASCII character in hexadecimal notation
+ -----------------------------------------------------------------------
+
+
+RAISING ERRORS
+--------------
+
+Any specifier can be followed by a special construction that is
+executed when the specifier evaluates to false. The construction is in
+the form:
+ .error <ERROR_TEXT>
+
+<ERROR_TEXT> is an identifier declared earlier by error text
+declaration. The declaration is in the form:
+
+ .errtext <ERROR_TEXT> "<error_desc>"
+
+When specifier evaluates to false and this construction is present,
+parsing is stopped immediately and <error_desc> is returned as a
+result of parsing. The error position is also returned and it is meant
+as an offset from the beggining of the stream to the character that
+was valid so far. Example:
+
+ (**** syntax script ****)
+
+ .syntax program;
+ .errtext MISSING_SEMICOLON "missing ';'"
+ program declaration .and .loop space .and ';'
+ .error MISSING_SEMICOLON .and
+ .loop space .and '\0';
+ declaration "declare" .and .loop space .and identifier;
+ space ' ';
(**** sample code ****)
-
- declare foo ,
-
- In the example above checking the sample code will result in error message "missing ';'" and
- error position 12. The sample code is not correct. Note the presence of '\0' specifier to
- assure that there is no code after semicolon - only spaces.
- <error_desc> can optionally contain identifier surrounded by dollar signs $. In such a case,
- the identifier and dollar signs are replaced by a string retrieved by invoking symbol with
- the identifier name. The starting position is the error position. The lenght of the resulting
- string is the position after invoking the symbol.
-
- PRODUCTION
- ----------
-
- Synek not only checks the syntax but it can also produce (emit) bytes associated with specifiers
- that evaluate to true. That is, every specifier and optional error construction can be followed
- by a number of emit constructions that are in the form:
- .emit <parameter>
- <paramater> can be a HEX number, identifier, a star * or a dollar $. HEX number is preceded by
- 0x or 0X. If <parameter> is an identifier, it must be earlier declared by emit code declaration
- in the form:
+ declare foo ,
+
+In the example above checking the sample code will result in error
+message "missing ';'" and error position 12. The sample code is not
+correct. Note the presence of '\0' specifier to assure that there is
+no code after semicolon - only spaces. <error_desc> can optionally
+contain identifier surrounded by dollar signs $. In such a case, the
+identifier and dollar signs are replaced by a string retrieved by
+invoking symbol with the identifier name. The starting position is the
+error position. The lenght of the resulting string is the position
+after invoking the symbol.
+
+
+PRODUCTION
+----------
+
+Synek not only checks the syntax but it can also produce (emit) bytes
+associated with specifiers that evaluate to true. That is, every
+specifier and optional error construction can be followed by a number
+of emit constructions that are in the form:
+ .emit <parameter>
+
+<paramater> can be a HEX number, identifier, a star * or a dollar
+$. HEX number is preceded by 0x or 0X. If <parameter> is an
+identifier, it must be earlier declared by emit code declaration in
+the form:
.emtcode <identifier> <hex_number>
- When given specifier evaluates to true, all emits associated with the specifier are output
- in order they were declared. A star means that last-read character should be output instead
- of constant value. Example:
+When given specifier evaluates to true, all emits associated with the
+specifier are output in order they were declared. A star means that
+last-read character should be output instead of constant
+value. Example:
- (**** syntax script ****)
+ (**** syntax script ****)
- .syntax foobar;
- .emtcode WORD_FOO 0x01
- .emtcode WORD_BAR 0x02
- foobar FOO .emit WORD_FOO .or BAR .emit WORD_BAR .or .true .emit 0x00;
- FOO "foo" .and SPACE;
- BAR "bar" .and SPACE;
- SPACE ' ' .or '\0';
+ .syntax foobar;
+ .emtcode WORD_FOO 0x01
+ .emtcode WORD_BAR 0x02
+ foobar FOO .emit WORD_FOO .or BAR .emit WORD_BAR .or .true .emit 0x00;
+ FOO "foo" .and SPACE;
+ BAR "bar" .and SPACE;
+ SPACE ' ' .or '\0';
- (**** sample text 1 ****)
+ (**** sample text 1 ****)
- foo
+ foo
- (**** sample text 2 ****)
+ (**** sample text 2 ****)
- foobar
+ foobar
- For both samples the result will be one-element array. For first sample text it will be
- value 1, for second - 0. Note that every text will be accepted because of presence of
- .true as an alternative.
+For both samples the result will be one-element array. For first
+sample text it will be value 1, for second - 0. Note that every text
+will be accepted because of presence of .true as an alternative.
- Another example:
+Another example:
- (**** syntax script ****)
-
- .syntax declaration;
- .emtcode VARIABLE 0x01
- declaration "declare" .and .loop space .and
- identifier .emit VARIABLE .and (1)
- .true .emit 0x00 .and (2)
- .loop space .and ';';
- space ' ' .or '\t';
- identifier .loop id_char .emit *; (3)
- id_char 'a'-'z' .or 'A'-'Z' .or '_';
+ (**** syntax script ****)
+ .syntax declaration;
+ .emtcode VARIABLE 0x01
+ declaration "declare" .and .loop space .and
+ identifier .emit VARIABLE .and (1)
+ .true .emit 0x00 .and (2)
+ .loop space .and ';';
+ space ' ' .or '\t';
+ identifier .loop id_char .emit *; (3)
+ id_char 'a'-'z' .or 'A'-'Z' .or '_';
(**** sample code ****)
-
- declare fubar;
-
- In specifier (1) symbol <identifier> is followed by .emit VARIABLE. If it evaluates to
- true, VARIABLE constant and then production of the symbol is output. Specifier (2) is used
- to terminate the string with null to signal when the string ends. Specifier (3) outputs
- all characters that make declared identifier. The result of sample code will be the
- following array:
+ declare fubar;
+
+In specifier (1) symbol <identifier> is followed by .emit VARIABLE. If
+it evaluates to true, VARIABLE constant and then production of the
+symbol is output. Specifier (2) is used to terminate the string with
+null to signal when the string ends. Specifier (3) outputs all
+characters that make declared identifier. The result of sample code
+will be the following array:
{ 1, 'f', 'u', 'b', 'a', 'r', 0 }
- If .emit is followed by dollar $, it means that current position should be output. Current
- position is a 32-bit unsigned integer distance from the very beginning of the parsed string to
- first character consumed by the specifier associated with the .emit instruction. Current
- position is stored in the output buffer in Little-Endian convention (the lowest byte comes
- first).
-*/
+If .emit is followed by dollar $, it means that current position
+should be output. Current position is a 32-bit unsigned integer
+distance from the very beginning of the parsed string to first
+character consumed by the specifier associated with the .emit
+instruction. Current position is stored in the output buffer in
+Little-Endian convention (the lowest byte comes first). */
/**
* This is the text describing the rules to parse the grammar
* These should match up with the values defined in arbparse.syn.h
*/
-#define REVISION 0x03
+/*
+ Changes:
+ - changed and merged V_* and F_* opcode values to OP_*.
+*/
+#define REVISION 0x05
/* program type */
#define FRAGMENT_PROGRAM 0x01
#define ARB_FOG_LINEAR 0x10
/* vertex program option flags */
-#define ARB_POSITION_INVARIANT 0x01
-
-/* fragment program instruction class */
-#define F_ALU_INST 0x01
-#define F_TEX_INST 0x02
-
-/* fragment program instruction type */
-#define F_ALU_VECTOR 0x01
-#define F_ALU_SCALAR 0x02
-#define F_ALU_BINSC 0x03
-#define F_ALU_BIN 0x04
-#define F_ALU_TRI 0x05
-#define F_ALU_SWZ 0x06
-#define F_TEX_SAMPLE 0x07
-#define F_TEX_KIL 0x08
-
-/* vertex program instruction type */
-#define V_GEN_ARL 0x01
-#define V_GEN_VECTOR 0x02
-#define V_GEN_SCALAR 0x03
-#define V_GEN_BINSC 0x04
-#define V_GEN_BIN 0x05
-#define V_GEN_TRI 0x06
-#define V_GEN_SWZ 0x07
-
-/* fragment program instruction code */
-#define F_ABS 0x00
-#define F_ABS_SAT 0x01
-#define F_FLR 0x02
-#define F_FLR_SAT 0x03
-#define F_FRC 0x04
-#define F_FRC_SAT 0x05
-#define F_LIT 0x06
-#define F_LIT_SAT 0x07
-#define F_MOV 0x08
-#define F_MOV_SAT 0x09
-#define F_COS 0x0A
-#define F_COS_SAT 0x0B
-#define F_EX2 0x0C
-#define F_EX2_SAT 0x0D
-#define F_LG2 0x0E
-#define F_LG2_SAT 0x0F
-#define F_RCP 0x10
-#define F_RCP_SAT 0x11
-#define F_RSQ 0x12
-#define F_RSQ_SAT 0x13
-#define F_SIN 0x14
-#define F_SIN_SAT 0x15
-#define F_SCS 0x16
-#define F_SCS_SAT 0x17
-#define F_POW 0x18
-#define F_POW_SAT 0x19
-#define F_ADD 0x1A
-#define F_ADD_SAT 0x1B
-#define F_DP3 0x1C
-#define F_DP3_SAT 0x1D
-#define F_DP4 0x1E
-#define F_DP4_SAT 0x1F
-#define F_DPH 0x20
-#define F_DPH_SAT 0x21
-#define F_DST 0x22
-#define F_DST_SAT 0x23
-#define F_MAX 0x24
-#define F_MAX_SAT 0x25
-#define F_MIN 0x26
-#define F_MIN_SAT 0x27
-#define F_MUL 0x28
-#define F_MUL_SAT 0x29
-#define F_SGE 0x2A
-#define F_SGE_SAT 0x2B
-#define F_SLT 0x2C
-#define F_SLT_SAT 0x2D
-#define F_SUB 0x2E
-#define F_SUB_SAT 0x2F
-#define F_XPD 0x30
-#define F_XPD_SAT 0x31
-#define F_CMP 0x32
-#define F_CMP_SAT 0x33
-#define F_LRP 0x34
-#define F_LRP_SAT 0x35
-#define F_MAD 0x36
-#define F_MAD_SAT 0x37
-#define F_SWZ 0x38
-#define F_SWZ_SAT 0x39
-#define F_TEX 0x3A
-#define F_TEX_SAT 0x3B
-#define F_TXB 0x3C
-#define F_TXB_SAT 0x3D
-#define F_TXP 0x3E
-#define F_TXP_SAT 0x3F
-#define F_KIL 0x40
-
-/* vertex program instruction code */
-#define V_ARL 0x01
-#define V_ABS 0x02
-#define V_FLR 0x03
-#define V_FRC 0x04
-#define V_LIT 0x05
-#define V_MOV 0x06
-#define V_EX2 0x07
-#define V_EXP 0x08
-#define V_LG2 0x09
-#define V_LOG 0x0A
-#define V_RCP 0x0B
-#define V_RSQ 0x0C
-#define V_POW 0x0D
-#define V_ADD 0x0E
-#define V_DP3 0x0F
-#define V_DP4 0x10
-#define V_DPH 0x11
-#define V_DST 0x12
-#define V_MAX 0x13
-#define V_MIN 0x14
-#define V_MUL 0x15
-#define V_SGE 0x16
-#define V_SLT 0x17
-#define V_SUB 0x18
-#define V_XPD 0x19
-#define V_MAD 0x1A
-#define V_SWZ 0x1B
+/*
+$4: changed from 0x01 to 0x20.
+*/
+#define ARB_POSITION_INVARIANT 0x20
+
+/* fragment program 1.0 instruction class */
+#define OP_ALU_INST 0x00
+#define OP_TEX_INST 0x01
+
+/* vertex program 1.0 instruction class */
+/* OP_ALU_INST */
+
+/* fragment program 1.0 instruction type */
+#define OP_ALU_VECTOR 0x06
+#define OP_ALU_SCALAR 0x03
+#define OP_ALU_BINSC 0x02
+#define OP_ALU_BIN 0x01
+#define OP_ALU_TRI 0x05
+#define OP_ALU_SWZ 0x04
+#define OP_TEX_SAMPLE 0x07
+#define OP_TEX_KIL 0x08
+
+/* vertex program 1.0 instruction type */
+#define OP_ALU_ARL 0x00
+/* OP_ALU_VECTOR */
+/* OP_ALU_SCALAR */
+/* OP_ALU_BINSC */
+/* OP_ALU_BIN */
+/* OP_ALU_TRI */
+/* OP_ALU_SWZ */
+
+/* fragment program 1.0 instruction code */
+#define OP_ABS 0x00
+#define OP_ABS_SAT 0x1B
+#define OP_FLR 0x09
+#define OP_FLR_SAT 0x26
+#define OP_FRC 0x0A
+#define OP_FRC_SAT 0x27
+#define OP_LIT 0x0C
+#define OP_LIT_SAT 0x2A
+#define OP_MOV 0x11
+#define OP_MOV_SAT 0x30
+#define OP_COS 0x1F
+#define OP_COS_SAT 0x20
+#define OP_EX2 0x07
+#define OP_EX2_SAT 0x25
+#define OP_LG2 0x0B
+#define OP_LG2_SAT 0x29
+#define OP_RCP 0x14
+#define OP_RCP_SAT 0x33
+#define OP_RSQ 0x15
+#define OP_RSQ_SAT 0x34
+#define OP_SIN 0x38
+#define OP_SIN_SAT 0x39
+#define OP_SCS 0x35
+#define OP_SCS_SAT 0x36
+#define OP_POW 0x13
+#define OP_POW_SAT 0x32
+#define OP_ADD 0x01
+#define OP_ADD_SAT 0x1C
+#define OP_DP3 0x03
+#define OP_DP3_SAT 0x21
+#define OP_DP4 0x04
+#define OP_DP4_SAT 0x22
+#define OP_DPH 0x05
+#define OP_DPH_SAT 0x23
+#define OP_DST 0x06
+#define OP_DST_SAT 0x24
+#define OP_MAX 0x0F
+#define OP_MAX_SAT 0x2E
+#define OP_MIN 0x10
+#define OP_MIN_SAT 0x2F
+#define OP_MUL 0x12
+#define OP_MUL_SAT 0x31
+#define OP_SGE 0x16
+#define OP_SGE_SAT 0x37
+#define OP_SLT 0x17
+#define OP_SLT_SAT 0x3A
+#define OP_SUB 0x18
+#define OP_SUB_SAT 0x3B
+#define OP_XPD 0x1A
+#define OP_XPD_SAT 0x43
+#define OP_CMP 0x1D
+#define OP_CMP_SAT 0x1E
+#define OP_LRP 0x2B
+#define OP_LRP_SAT 0x2C
+#define OP_MAD 0x0E
+#define OP_MAD_SAT 0x2D
+#define OP_SWZ 0x19
+#define OP_SWZ_SAT 0x3C
+#define OP_TEX 0x3D
+#define OP_TEX_SAT 0x3E
+#define OP_TXB 0x3F
+#define OP_TXB_SAT 0x40
+#define OP_TXP 0x41
+#define OP_TXP_SAT 0x42
+#define OP_KIL 0x28
+
+/* vertex program 1.0 instruction code */
+#define OP_ARL 0x02
+/* OP_ABS */
+/* OP_FLR */
+/* OP_FRC */
+/* OP_LIT */
+/* OP_MOV */
+/* OP_EX2 */
+#define OP_EXP 0x08
+/* OP_LG2 */
+#define OP_LOG 0x0D
+/* OP_RCP */
+/* OP_RSQ */
+/* OP_POW */
+/* OP_ADD */
+/* OP_DP3 */
+/* OP_DP4 */
+/* OP_DPH */
+/* OP_DST */
+/* OP_MAX */
+/* OP_MIN */
+/* OP_MUL */
+/* OP_SGE */
+/* OP_SLT */
+/* OP_SUB */
+/* OP_XPD */
+/* OP_MAD */
+/* OP_SWZ */
/* fragment attribute binding */
#define FRAGMENT_ATTRIB_COLOR 0x01
#define STATE_TEX_ENV 0x07
#define STATE_DEPTH 0x08
/* vertex program only */
-#define STATE_TEX_GEN 0x07
-#define STATE_CLIP_PLANE 0x08
-#define STATE_POINT 0x09
+/*
+$4: incremented all the three emit codes by two to not collide with other STATE_* emit codes.
+*/
+#define STATE_TEX_GEN 0x09
+#define STATE_CLIP_PLANE 0x0A
+#define STATE_POINT 0x0B
/* state material property */
#define MATERIAL_AMBIENT 0x01
static GLvoid *mem_alloc (GLsizei);
static GLvoid mem_free (GLvoid **);
static GLvoid *mem_realloc (GLvoid *, GLsizei, GLsizei);
-static byte *str_duplicate (const byte *);
+static GLubyte *str_duplicate (const GLubyte *);
/*
internal error messages
*/
-static const byte *OUT_OF_MEMORY =
- (byte *) "internal error 1001: out of physical memory";
-static const byte *UNRESOLVED_REFERENCE =
- (byte *) "internal error 1002: unresolved reference '$'";
+static const GLubyte *OUT_OF_MEMORY =
+ (GLubyte *) "internal error 1001: out of physical memory";
+static const GLubyte *UNRESOLVED_REFERENCE =
+ (GLubyte *) "internal error 1002: unresolved reference '$'";
/*
-static const byte *INVALID_PARAMETER =
- (byte *) "internal error 1003: invalid parameter";
+static const GLubyte *INVALID_PARAMETER =
+ (GLubyte *) "internal error 1003: invalid parameter";
*/
-static const byte *error_message = NULL;
-static byte *error_param = NULL; /* this is inserted into error_message in place of $ */
+static const GLubyte *error_message = NULL;
+static GLubyte *error_param = NULL; /* this is inserted into error_message in place of $ */
static GLint error_position = -1;
-static byte *unknown = (byte *) "???";
+static GLubyte *unknown = (GLubyte *) "???";
static GLvoid
-clear_last_error ()
+clear_last_error (GLvoid)
{
/* reset error message */
error_message = NULL;
}
static GLvoid
-set_last_error (const byte * msg, byte * param, GLint pos)
+set_last_error (const GLubyte * msg, GLubyte * param, GLint pos)
{
if (error_message != NULL)
return;
}
/*
- memory management routines
-*/
+ * memory management routines
+ */
static GLvoid *
mem_alloc (GLsizei size)
{
return ptr2;
}
-static byte *
-str_duplicate (const byte * str)
+static GLubyte *
+str_duplicate (const GLubyte * str)
{
- return (byte *) _mesa_strdup ((const char *) str);
+ return (GLubyte *) _mesa_strdup ((const char *) str);
}
/*
- emit type typedef
-*/
+ * emit type typedef
+ */
typedef enum emit_type_
{
et_byte, /* explicit number */
emit_type;
/*
- emit typedef
-*/
+ * emit typedef
+ */
typedef struct emit_
{
emit_type m_emit_type;
- byte m_byte; /* et_byte */
+ GLubyte m_byte; /* et_byte */
struct emit_ *m_next;
}
emit;
static GLvoid
emit_create (emit ** em)
{
- *em = mem_alloc (sizeof (emit));
+ *em = (emit *) mem_alloc (sizeof (emit));
if (*em) {
(**em).m_emit_type = et_byte;
(**em).m_byte = 0;
*/
typedef struct error_
{
- byte *m_text;
- byte *m_token_name;
+ GLubyte *m_text;
+ GLubyte *m_token_name;
struct defntn_ *m_token;
}
error;
static GLvoid
error_create (error ** er)
{
- *er = mem_alloc (sizeof (error));
+ *er = (error *) mem_alloc (sizeof (error));
if (*er) {
(**er).m_text = NULL;
(**er).m_token_name = NULL;
}
struct dict_;
-static byte *error_get_token (error *, struct dict_ *, const byte *, GLuint);
+static GLubyte *error_get_token (error *, struct dict_ *, const GLubyte *, GLuint);
/*
* specifier type typedef
typedef struct spec_
{
spec_type m_spec_type;
- byte m_byte[2]; /* st_byte, st_byte_range */
- byte *m_string; /* st_string */
+ GLubyte m_byte[2]; /* st_byte, st_byte_range */
+ GLubyte *m_string; /* st_string */
struct defntn_ *m_defntn; /* st_identifier, st_identifier_loop */
emit *m_emits;
error *m_errtext;
static GLvoid
spec_create (spec ** sp)
{
- *sp = mem_alloc (sizeof (spec));
+ *sp = (spec *) mem_alloc (sizeof (spec));
if (*sp) {
(**sp).m_spec_type = st_false;
(**sp).m_byte[0] = '\0';
static GLvoid
defntn_create (defntn ** de)
{
- *de = mem_alloc (sizeof (defntn));
+ *de = (defntn *) mem_alloc (sizeof (defntn));
if (*de) {
(**de).m_oper = op_none;
(**de).m_specs = NULL;
static GLvoid
dict_create (dict ** di)
{
- *di = mem_alloc (sizeof (dict));
+ *di = (dict *) mem_alloc (sizeof (dict));
if (*di) {
(**di).m_defntns = NULL;
(**di).m_syntax = NULL;
}
/*
- * byte array typedef
+ * GLubyte array typedef
*/
typedef struct barray_
{
- byte *data;
+ GLubyte *data;
GLuint len;
} barray;
static GLvoid
barray_create (barray ** ba)
{
- *ba = mem_alloc (sizeof (barray));
+ *ba = (barray *) mem_alloc (sizeof (barray));
if (*ba) {
(**ba).data = NULL;
(**ba).len = 0;
}
/*
- * reallocates byte array to requested size,
+ * reallocates GLubyte array to requested size,
* returns 0 on success,
* returns 1 otherwise
*/
static GLint
barray_resize (barray ** ba, GLuint nlen)
{
- byte *new_pointer;
+ GLubyte *new_pointer;
if (nlen == 0) {
mem_free ((void **) &(**ba).data);
return 0;
}
else {
- new_pointer =
- mem_realloc ((**ba).data, (**ba).len * sizeof (byte),
- nlen * sizeof (byte));
+ new_pointer = (GLubyte *)
+ mem_realloc ((**ba).data, (**ba).len * sizeof (GLubyte),
+ nlen * sizeof (GLubyte));
if (new_pointer) {
(**ba).data = new_pointer;
(**ba).len = nlen;
}
/*
- * adds byte array pointed by *nb to the end of array pointed by *ba,
+ * adds GLubyte array pointed by *nb to the end of array pointed by *ba,
* returns 0 on success,
* returns 1 otherwise
*/
return 0;
}
-/*
- * adds emit chain pointed by em to the end of array pointed by *ba,
- * returns 0 on success,
- * returns 1 otherwise
+
+/**
+ * Adds emit chain pointed by em to the end of array pointed by *ba.
+ * \return 0 on success, 1 otherwise.
*/
static GLint
-barray_push (barray ** ba, emit * em, byte c, GLuint pos)
+barray_push (barray ** ba, emit * em, GLubyte c, GLuint pos)
{
emit *temp = em;
GLuint count = 0;
/* This is where the position is emitted into the stream */
else { /* em->type == et_position */
#if 0
- (**ba).data[(**ba).len - count--] = (byte) pos,
- (**ba).data[(**ba).len - count--] = (byte) (pos >> 8),
- (**ba).data[(**ba).len - count--] = (byte) (pos >> 16),
- (**ba).data[(**ba).len - count--] = (byte) (pos >> 24);
+ (**ba).data[(**ba).len - count--] = (GLubyte) pos,
+ (**ba).data[(**ba).len - count--] = (GLubyte) (pos >> 8),
+ (**ba).data[(**ba).len - count--] = (GLubyte) (pos >> 16),
+ (**ba).data[(**ba).len - count--] = (GLubyte) (pos >> 24);
#else
- (**ba).data[(**ba).len - count--] = (byte) pos;
- (**ba).data[(**ba).len - count--] = (byte) (pos / 0x100);
- (**ba).data[(**ba).len - count--] = (byte) (pos / 0x10000);
- (**ba).data[(**ba).len - count--] = (byte) (pos / 0x1000000);
+ (**ba).data[(**ba).len - count--] = (GLubyte) pos;
+ (**ba).data[(**ba).len - count--] = (GLubyte) (pos / 0x100);
+ (**ba).data[(**ba).len - count--] = (GLubyte) (pos / 0x10000);
+ (**ba).data[(**ba).len - count--] = (GLubyte) (pos / 0x1000000);
#endif
}
return 0;
}
-/*
+/**
* string to string map typedef
*/
typedef struct map_str_
{
- byte *key;
- byte *data;
+ GLubyte *key;
+ GLubyte *data;
struct map_str_ *next;
} map_str;
static GLvoid
map_str_create (map_str ** ma)
{
- *ma = mem_alloc (sizeof (map_str));
+ *ma = (map_str *) mem_alloc (sizeof (map_str));
if (*ma) {
(**ma).key = NULL;
(**ma).data = NULL;
*ma = *nm;
}
-/*
+/**
* searches the map for specified key,
* if the key is matched, *data is filled with data associated with the key,
- * returns 0 if the key is matched,
- * returns 1 otherwise
+ * \return 0 if the key is matched, 1 otherwise
*/
static GLint
-map_str_find (map_str ** ma, const byte * key, byte ** data)
+map_str_find (map_str ** ma, const GLubyte * key, GLubyte ** data)
{
while (*ma) {
if (strcmp ((const char *) (**ma).key, (const char *) key) == 0) {
return 1;
}
-/*
- * string to byte map typedef
+/**
+ * string to GLubyte map typedef
*/
typedef struct map_byte_
{
- byte *key;
- byte data;
+ GLubyte *key;
+ GLubyte data;
struct map_byte_ *next;
} map_byte;
static GLvoid
map_byte_create (map_byte ** ma)
{
- *ma = mem_alloc (sizeof (map_byte));
+ *ma = (map_byte *) mem_alloc (sizeof (map_byte));
if (*ma) {
(**ma).key = NULL;
(**ma).data = 0;
*ma = *nm;
}
-/*
- * searches the map for specified key,
- * if the key is matched, *data is filled with data associated with the key,
- * returns 0 if the is matched,
- * returns 1 otherwise
+/**
+ * Searches the map for specified key,
+ * If the key is matched, *data is filled with data associated with the key,
+ * \return 0 if the is matched, 1 otherwise
*/
static GLint
-map_byte_find (map_byte ** ma, const byte * key, byte * data)
+map_byte_find (map_byte ** ma, const GLubyte * key, GLubyte * data)
{
while (*ma) {
if (strcmp ((const char *) (**ma).key, (const char *) key) == 0) {
*/
typedef struct map_def_
{
- byte *key;
+ GLubyte *key;
defntn *data;
struct map_def_ *next;
} map_def;
static GLvoid
map_def_create (map_def ** ma)
{
- *ma = mem_alloc (sizeof (map_def));
+ *ma = (map_def *) mem_alloc (sizeof (map_def));
if (*ma) {
(**ma).key = NULL;
(**ma).data = NULL;
*ma = *nm;
}
-/*
+/**
* searches the map for specified key,
* if the key is matched, *data is filled with data associated with the key,
- * returns 0 if the is matched,
- * returns 1 otherwise
+ * \return 0 if the is matched, 1 otherwise
*/
static GLint
-map_def_find (map_def ** ma, const byte * key, defntn ** data)
+map_def_find (map_def ** ma, const GLubyte * key, defntn ** data)
{
while (*ma) {
if (_mesa_strcmp ((const char *) (**ma).key, (const char *) key) == 0) {
* returns 0 otherwise
*/
static GLint
-is_space (byte c)
+is_space (GLubyte c)
{
return c == ' ' || c == '\t' || c == '\n' || c == '\r';
}
* returns 0 otherwise
*/
static GLint
-eat_space (const byte ** text)
+eat_space (const GLubyte ** text)
{
if (is_space (**text)) {
(*text)++;
* returns 0 otherwise
*/
static GLint
-is_comment_start (const byte * text)
+is_comment_start (const GLubyte * text)
{
return text[0] == '/' && text[1] == '*';
}
* returns 0 otherwise
*/
static GLint
-eat_comment (const byte ** text)
+eat_comment (const GLubyte ** text)
{
if (is_comment_start (*text)) {
/* *text points to comment block - skip two characters to enter comment body */
* advances text pointer to first character that is neither space nor C-style comment block
*/
static GLvoid
-eat_spaces (const byte ** text)
+eat_spaces (const GLubyte ** text)
{
while (eat_space (text) || eat_comment (text));
}
* returns 1 otherwise
*/
static GLint
-string_grow (byte ** ptr, GLuint * len, byte c)
+string_grow (GLubyte ** ptr, GLuint * len, GLubyte c)
{
/* reallocate the string in 16-length increments */
if ((*len & 0x0F) == 0x0F || *ptr == NULL) {
- byte *tmp = mem_realloc (*ptr, (*len) * sizeof (byte),
+ GLubyte *tmp = (GLubyte *) mem_realloc (*ptr, (*len) * sizeof (GLubyte),
((*len + 1 + 1 +
- 0x0F) & ~0x0F) * sizeof (byte));
+ 0x0F) & ~0x0F) * sizeof (GLubyte));
if (tmp == NULL)
return 1;
* returns 0 otherwise
*/
static GLint
-is_identifier (byte c)
+is_identifier (GLubyte c)
{
return (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') ||
(c >= '0' && c <= '9') || c == '_';
* returns 1 otherwise
*/
static GLint
-get_identifier (const byte ** text, byte ** id)
+get_identifier (const GLubyte ** text, GLubyte ** id)
{
- const byte *t = *text;
- byte *p = NULL;
+ const GLubyte *t = *text;
+ GLubyte *p = NULL;
GLuint len = 0;
if (string_grow (&p, &len, '\0'))
* returns 0 otherwise
*/
static GLint
-is_hex (byte c)
+is_hex (GLubyte c)
{
return (c >= '0' && c <= '9') || (c >= 'A' && c <= 'F') || (c >= 'a'
&& c <= 'f');
* returns value of passed character as if it was HEX digit
*/
static GLuint
-hex2dec (byte c)
+hex2dec (GLubyte c)
{
if (c >= '0' && c <= '9')
return c - '0';
* returns the converted value
*/
static GLuint
-hex_convert (const byte ** text)
+hex_convert (const GLubyte ** text)
{
GLuint value = 0;
* returns 0 otherwise
*/
static GLint
-is_oct (byte c)
+is_oct (GLubyte c)
{
return c >= '0' && c <= '7';
}
* returns value of passed character as if it was OCT digit
*/
static GLint
-oct2dec (byte c)
+oct2dec (GLubyte c)
{
return c - '0';
}
-static byte
-get_escape_sequence (const byte ** text)
+static GLubyte
+get_escape_sequence (const GLubyte ** text)
{
GLint value = 0;
case 'v':
return '\v';
case 'x':
- return (byte) hex_convert (text);
+ return (GLubyte) hex_convert (text);
}
(*text)--;
}
}
- return (byte) value;
+ return (GLubyte) value;
}
/*
* returns 1 otherwise
*/
static GLint
-get_string (const byte ** text, byte ** str)
+get_string (const GLubyte ** text, GLubyte ** str)
{
- const byte *t = *text;
- byte *p = NULL;
+ const GLubyte *t = *text;
+ GLubyte *p = NULL;
GLuint len = 0;
- byte term_char;
+ GLubyte term_char;
if (string_grow (&p, &len, '\0'))
return 1;
term_char = *t++;
/* while next character is not the terminating character */
while (*t && *t != term_char) {
- byte c;
+ GLubyte c;
if (*t == '\\')
c = get_escape_sequence (&t);
* returns 1 otherwise
*/
static GLint
-get_emtcode (const byte ** text, map_byte ** ma)
+get_emtcode (const GLubyte ** text, map_byte ** ma)
{
- const byte *t = *text;
+ const GLubyte *t = *text;
map_byte *m = NULL;
map_byte_create (&m);
eat_spaces (&t);
if (*t == '\'') {
- byte *c;
+ GLubyte *c;
if (get_string (&t, &c)) {
map_byte_destroy (&m);
return 1;
}
- m->data = (byte) c[0];
+ m->data = (GLubyte) c[0];
mem_free ((GLvoid **) & c);
}
else {
/* skip HEX "0x" or "0X" prefix */
t += 2;
- m->data = (byte) hex_convert (&t);
+ m->data = (GLubyte) hex_convert (&t);
}
eat_spaces (&t);
* returns 1 otherwise
*/
static GLint
-get_errtext (const byte ** text, map_str ** ma)
+get_errtext (const GLubyte ** text, map_str ** ma)
{
- const byte *t = *text;
+ const GLubyte *t = *text;
map_str *m = NULL;
map_str_create (&m);
* returns 1 otherwise,
*/
static GLint
-get_error (const byte ** text, error ** er, map_str * maps)
+get_error (const GLubyte ** text, error ** er, map_str * maps)
{
- const byte *t = *text;
- byte *temp = NULL;
+ const GLubyte *t = *text;
+ GLubyte *temp = NULL;
if (*t != '.')
return 0;
char *processed = NULL;
GLuint len = 0, i = 0;
- if (string_grow ((byte **) (&processed), &len, '\0')) {
+ if (string_grow ((GLubyte **) (&processed), &len, '\0')) {
error_destroy (er);
return 1;
}
while (i < _mesa_strlen ((char *) ((**er).m_text))) {
/* check if the dollar sign is repeated - if so skip it */
if ((**er).m_text[i] == '$' && (**er).m_text[i + 1] == '$') {
- if (string_grow ((byte **) (&processed), &len, '$')) {
+ if (string_grow ((GLubyte **) (&processed), &len, '$')) {
mem_free ((GLvoid **) & processed);
error_destroy (er);
return 1;
i += 2;
}
else if ((**er).m_text[i] != '$') {
- if (string_grow ((byte **) (&processed), &len, (**er).m_text[i])) {
+ if (string_grow ((GLubyte **) (&processed), &len, (**er).m_text[i])) {
mem_free ((GLvoid **) & processed);
error_destroy (er);
return 1;
i++;
}
else {
- if (string_grow ((byte **) (&processed), &len, '$')) {
+ if (string_grow ((GLubyte **) (&processed), &len, '$')) {
mem_free ((GLvoid **) & processed);
error_destroy (er);
return 1;
}
mem_free ((GLvoid **) & (**er).m_text);
- (**er).m_text = (byte *) processed;
+ (**er).m_text = (GLubyte *) processed;
}
*text = t;
* returns 1 otherwise,
*/
static GLint
-get_emits (const byte ** text, emit ** em, map_byte * mapb)
+get_emits (const GLubyte ** text, emit ** em, map_byte * mapb)
{
- const byte *t = *text;
- byte *temp = NULL;
+ const GLubyte *t = *text;
+ GLubyte *temp = NULL;
emit *e = NULL;
if (*t != '.')
/* 0xNN */
if (*t == '0') {
t += 2;
- e->m_byte = (byte) hex_convert (&t);
+ e->m_byte = (GLubyte) hex_convert (&t);
e->m_emit_type = et_byte;
}
emit_destroy (&e);
return 1;
}
- e->m_byte = (byte) temp[0];
+ e->m_byte = (GLubyte) temp[0];
mem_free ((GLvoid **) & temp);
* returns 1 otherwise,
*/
static GLint
-get_spec (const byte ** text, spec ** sp, map_str * maps, map_byte * mapb)
+get_spec (const GLubyte ** text, spec ** sp, map_str * maps, map_byte * mapb)
{
- const byte *t = *text;
+ const GLubyte *t = *text;
spec *s = NULL;
spec_create (&s);
return 1;
if (*t == '\'') {
- byte *temp = NULL;
+ GLubyte *temp = NULL;
if (get_string (&t, &temp)) {
spec_destroy (&s);
eat_spaces (&t);
if (*t == '-') {
- byte *temp2 = NULL;
+ GLubyte *temp2 = NULL;
/* skip the '-' character */
t++;
s->m_spec_type = st_string;
}
else if (*t == '.') {
- byte *keyword = NULL;
+ GLubyte *keyword = NULL;
/* skip the dot */
t++;
* returns 1 otherwise,
*/
static GLint
-get_definition (const byte ** text, defntn ** de, map_str * maps,
+get_definition (const GLubyte ** text, defntn ** de, map_str * maps,
map_byte * mapb)
{
- const byte *t = *text;
+ const GLubyte *t = *text;
defntn *d = NULL;
defntn_create (&d);
}
while (*t != ';') {
- byte *op = NULL;
+ GLubyte *op = NULL;
spec *sp = NULL;
/* skip the dot that precedes "and" or "or" */
* returns 1 otherwise,
*/
static GLint
-update_dependency (map_def * mapd, byte * symbol, defntn ** def)
+update_dependency (map_def * mapd, GLubyte * symbol, defntn ** def)
{
if (map_def_find (&mapd, symbol, def))
return 1;
* returns 1 otherwise,
*/
static GLint
-update_dependencies (dict * di, map_def * mapd, byte ** syntax_symbol,
- byte ** string_symbol)
+update_dependencies (dict * di, map_def * mapd, GLubyte ** syntax_symbol,
+ GLubyte ** string_symbol)
{
defntn *de = di->m_defntns;
} match_result;
static match_result
-match (dict * di, const byte * text, GLuint * index, defntn * de,
+match (dict * di, const GLubyte * text, GLuint * index, defntn * de,
barray ** ba, GLint filtering_string)
{
GLuint ind = *index;
return mr_not_matched;
}
-static byte *
-error_get_token (error * er, dict * di, const byte * text, unsigned int ind)
+static GLubyte *
+error_get_token (error * er, dict * di, const GLubyte * text, unsigned int ind)
{
- byte *str = NULL;
+ GLubyte *str = NULL;
if (er->m_token) {
barray *ba;
- unsigned int filter_index = 0;
+ GLuint filter_index = 0;
barray_create (&ba);
if (ba != NULL) {
if (match (di, text + ind, &filter_index, er->m_token, &ba, 0) ==
mr_matched && filter_index) {
- str = mem_alloc (filter_index + 1);
+ str = (GLubyte *) mem_alloc (filter_index + 1);
if (str != NULL) {
_mesa_strncpy ((char *) str, (char *) (text + ind),
filter_index);
typedef struct grammar_load_state_
{
dict *di;
- byte *syntax_symbol;
- byte *string_symbol;
+ GLubyte *syntax_symbol;
+ GLubyte *string_symbol;
map_str *maps;
map_byte *mapb;
map_def *mapd;
static GLvoid
grammar_load_state_create (grammar_load_state ** gr)
{
- *gr = mem_alloc (sizeof (grammar_load_state));
+ *gr = (grammar_load_state *) mem_alloc (sizeof (grammar_load_state));
if (*gr) {
(**gr).di = NULL;
(**gr).syntax_symbol = NULL;
*/
static dict *
-grammar_load_from_text (const byte * text)
+grammar_load_from_text (const GLubyte * text)
{
dict *d = NULL;
grammar_load_state *g = NULL;
eat_spaces (&text);
while (*text) {
- byte *symbol = NULL;
+ GLubyte *symbol = NULL;
GLint is_dot = *text == '.';
if (is_dot)
/**
* checks if a null-terminated text matches given grammar
* returns 0 on error (call grammar_get_last_error to retrieve the error text)
- * returns 1 on success, the prod points to newly allocated buffer with production and size
- * is filled with the production size
+ * returns 1 on success, the prod points to newly allocated buffer with
+ * production and size is filled with the production size
*
* \param id - The grammar returned from grammar_load_from_text()
* \param text - The program string
- * \param production - The return parameter for the binary array holding the parsed results
+ * \param production - The return parameter for the binary array holding the
+ * parsed results
* \param size - The return parameter for the size of production
*
* \return 1 on sucess, 0 on parser error
*/
static GLint
-grammar_check (dict * di, const byte * text, byte ** production,
+grammar_check (dict * di, const GLubyte * text, GLubyte ** production,
GLuint *size)
{
barray *ba = NULL;
return 0;
}
- *production = mem_alloc (ba->len * sizeof (byte));
+ *production = (GLubyte *) mem_alloc (ba->len * sizeof (GLubyte));
if (*production == NULL) {
barray_destroy (&ba);
return 0;
}
- memcpy (*production, ba->data, ba->len * sizeof (byte));
+ _mesa_memcpy(*production, ba->data, ba->len * sizeof (GLubyte));
*size = ba->len;
barray_destroy (&ba);
}
static GLvoid
-grammar_get_last_error (byte * text, int size, int *pos)
+grammar_get_last_error (GLubyte * text, GLint size, GLint *pos)
{
GLint len = 0, dots_made = 0;
- const byte *p = error_message;
+ const GLubyte *p = error_message;
*text = '\0';
#define APPEND_CHARACTER(x) if (dots_made == 0) {\
if (len < size - 1) {\
text[len++] = (x); text[len] = '\0';\
} else {\
- int i;\
+ GLint i;\
for (i = 0; i < 3; i++)\
if (--len >= 0)\
text[len] = '.';\
if (p) {
while (*p) {
if (*p == '$') {
- const byte *r = error_param;
+ const GLubyte *r = error_param;
while (*r) {
APPEND_CHARACTER (*r)
*/
struct var_cache
{
- byte *name;
+ GLubyte *name;
var_type type;
GLuint address_binding; /* The index of the address register we should
* be using */
GLuint attrib_binding; /* For type vt_attrib, see nvfragprog.h for values */
GLuint attrib_binding_idx; /* The index into the attrib register file corresponding
* to the state in attrib_binding */
+ GLuint attrib_is_generic; /* If the attrib was specified through a generic
+ * vertex attrib */
GLuint temp_binding; /* The index of the temp register we are to use */
GLuint output_binding; /* For type vt_output, see nvfragprog.h for values */
GLuint output_binding_idx; /* This is the index into the result register file
* corresponding to the bound result state */
struct var_cache *alias_binding; /* For type vt_alias, points to the var_cache entry
- * * that this is aliased to */
+ * that this is aliased to */
GLuint param_binding_type; /* {PROGRAM_STATE_VAR, PROGRAM_LOCAL_PARAM,
* PROGRAM_ENV_PARAM} */
GLuint param_binding_begin; /* This is the offset into the program_parameter_list where
static GLvoid
var_cache_create (struct var_cache **va)
{
- *va = _mesa_malloc (sizeof (struct var_cache));
+ *va = (struct var_cache *) _mesa_malloc (sizeof (struct var_cache));
if (*va) {
(**va).name = NULL;
(**va).type = vt_none;
- (**va).attrib_binding = -1;
- (**va).temp_binding = -1;
- (**va).output_binding = -1;
- (**va).output_binding_idx = -1;
- (**va).param_binding_type = -1;
- (**va).param_binding_begin = -1;
- (**va).param_binding_length = -1;
+ (**va).attrib_binding = ~0;
+ (**va).attrib_is_generic = 0;
+ (**va).temp_binding = ~0;
+ (**va).output_binding = ~0;
+ (**va).output_binding_idx = ~0;
+ (**va).param_binding_type = ~0;
+ (**va).param_binding_begin = ~0;
+ (**va).param_binding_length = ~0;
(**va).alias_binding = NULL;
(**va).next = NULL;
}
}
static struct var_cache *
-var_cache_find (struct var_cache *va, byte * name)
+var_cache_find (struct var_cache *va, GLubyte * name)
{
struct var_cache *first = va;
}
/**
- * constructs an integer from 4 bytes in LE format
+ * constructs an integer from 4 GLubytes in LE format
*/
static GLuint
-parse_position (byte ** inst)
+parse_position (GLubyte ** inst)
{
GLuint value;
* \return The location on the var_cache corresponding the the string starting at I
*/
static struct var_cache *
-parse_string (byte ** inst, struct var_cache **vc_head,
+parse_string (GLubyte ** inst, struct var_cache **vc_head,
struct arb_program *Program, GLuint * found)
{
- byte *i = *inst;
+ GLubyte *i = *inst;
struct var_cache *va = NULL;
*inst += _mesa_strlen ((char *) i) + 1;
}
static char *
-parse_string_without_adding (byte ** inst, struct arb_program *Program)
+parse_string_without_adding (GLubyte ** inst, struct arb_program *Program)
{
- byte *i = *inst;
+ GLubyte *i = *inst;
*inst += _mesa_strlen ((char *) i) + 1;
* \return 0 if sign is plus, 1 if sign is minus
*/
static GLuint
-parse_sign (byte ** inst)
+parse_sign (GLubyte ** inst)
{
/*return *(*inst)++ != '+'; */
if (**inst == '-') {
- *(*inst)++;
+ (*inst)++;
return 1;
}
else if (**inst == '+') {
- *(*inst)++;
+ (*inst)++;
return 0;
}
* parses and returns signed integer
*/
static GLint
-parse_integer (byte ** inst, struct arb_program *Program)
+parse_integer (GLubyte ** inst, struct arb_program *Program)
{
GLint sign;
GLint value;
* if yes, increment the *inst and return the default value
*/
if (**inst == 0) {
- *(*inst)++;
+ (*inst)++;
return 0;
}
/**
*/
static GLfloat
-parse_float (byte ** inst, struct arb_program *Program)
+parse_float (GLubyte ** inst, struct arb_program *Program)
{
GLint tmp[5], denom;
+ GLuint leading_zeros =0;
GLfloat value = 0;
#if 0
tmp[0] = parse_sign (inst); /* This is the sign of the number + - >0, - -> 1 */
#endif
tmp[1] = parse_integer (inst, Program); /* This is the integer portion of the number */
+
+ /* Now we grab the fractional portion of the number (the digits after
+ * the .). We can have leading 0's here, which parse_integer will ignore,
+ * so we'll check for those first
+ */
+ while ((**inst == '0') && ( *(*inst+1) != 0))
+ {
+ leading_zeros++;
+ (*inst)++;
+ }
tmp[2] = parse_integer (inst, Program); /* This is the fractional portion of the number */
tmp[3] = parse_sign (inst); /* This is the sign of the exponent */
tmp[4] = parse_integer (inst, Program); /* This is the exponent */
value = (GLfloat) tmp[1];
- denom = 1;
+ denom = 1;
while (denom < tmp[2])
denom *= 10;
+ denom *= (GLint) _mesa_pow( 10, leading_zeros );
value += (GLfloat) tmp[2] / (GLfloat) denom;
#if 0
if (tmp[0])
value *= -1;
#endif
- value *= _mesa_pow (10, (GLfloat) tmp[3] * (GLfloat) tmp[4]);
+ value *= (GLfloat) _mesa_pow (10, (GLfloat) tmp[3] * (GLfloat) tmp[4]);
return value;
}
+
/**
*/
static GLfloat
-parse_signed_float (byte ** inst, struct arb_program *Program)
+parse_signed_float (GLubyte ** inst, struct arb_program *Program)
{
GLint negate;
GLfloat value;
* \param values - The 4 component vector with the constant value in it
*/
static GLvoid
-parse_constant (byte ** inst, GLfloat *values, struct arb_program *Program,
+parse_constant (GLubyte ** inst, GLfloat *values, struct arb_program *Program,
GLboolean use)
{
GLuint components, i;
}
}
+/**
+ * \param offset The offset from the address register that we should
+ * address
+ *
+ * \return 0 on sucess, 1 on error
+ */
+static GLuint
+parse_relative_offset (GLcontext *ctx, GLubyte **inst, struct arb_program *Program,
+ GLint *offset)
+{
+ *offset = parse_integer(inst, Program);
+ if ((*offset > 63) || (*offset < -64)) {
+ _mesa_set_program_error (ctx, Program->Position,
+ "Relative offset out of range");
+ _mesa_error (ctx, GL_INVALID_OPERATION, "Relative offset %d out of range",
+ *offset);
+ return 1;
+ }
+
+ return 0;
+}
/**
* \param color 0 if color type is primary, 1 if color type is secondary
* \return 0 on sucess, 1 on error
*/
static GLuint
-parse_color_type (GLcontext * ctx, byte ** inst, struct arb_program *Program,
+parse_color_type (GLcontext * ctx, GLubyte ** inst, struct arb_program *Program,
GLint * color)
{
*color = *(*inst)++ != COLOR_PRIMARY;
return 0;
}
+/**
+ * Get an integer corresponding to a generic vertex attribute.
+ *
+ * \return 0 on sucess, 1 on error
+ */
+static GLuint
+parse_generic_attrib_num(GLcontext *ctx, GLubyte ** inst,
+ struct arb_program *Program, GLuint *attrib)
+{
+ *attrib = parse_integer(inst, Program);
+
+ if ((*attrib < 0) || (*attrib > MAX_VERTEX_PROGRAM_ATTRIBS))
+ {
+ _mesa_set_program_error (ctx, Program->Position,
+ "Invalid generic vertex attribute index");
+ _mesa_error (ctx, GL_INVALID_OPERATION, "Invalid generic vertex attribute index");
+
+ return 1;
+ }
+
+ return 0;
+}
+
+
/**
* \param coord The texture unit index
* \return 0 on sucess, 1 on error
*/
static GLuint
-parse_texcoord_num (GLcontext * ctx, byte ** inst,
+parse_texcoord_num (GLcontext * ctx, GLubyte ** inst,
struct arb_program *Program, GLuint * coord)
{
*coord = parse_integer (inst, Program);
return 1;
}
- Program->TexturesUsed[*coord] = 1;
return 0;
}
* \return 0 on sucess, 1 on error
*/
static GLuint
-parse_weight_num (GLcontext * ctx, byte ** inst, struct arb_program *Program,
+parse_weight_num (GLcontext * ctx, GLubyte ** inst, struct arb_program *Program,
GLint * coord)
{
*coord = parse_integer (inst, Program);
* \return 0 on sucess, 1 on error
*/
static GLuint
-parse_clipplane_num (GLcontext * ctx, byte ** inst,
+parse_clipplane_num (GLcontext * ctx, GLubyte ** inst,
struct arb_program *Program, GLint * coord)
{
*coord = parse_integer (inst, Program);
- if ((*coord < 0) || (*coord >= ctx->Const.MaxClipPlanes)) {
+ if ((*coord < 0) || (*coord >= (GLint) ctx->Const.MaxClipPlanes)) {
_mesa_set_program_error (ctx, Program->Position,
"Invalid clip plane index");
_mesa_error (ctx, GL_INVALID_OPERATION, "Invalid clip plane index");
}
-
-
/**
* \return 0 on front face, 1 on back face
*/
static GLuint
-parse_face_type (byte ** inst)
+parse_face_type (GLubyte ** inst)
{
switch (*(*inst)++) {
case FACE_FRONT:
return 0;
}
+
/**
* Given a matrix and a modifier token on the binary array, return tokens
* that _mesa_fetch_state() [program.c] can understand.
* \return 0 on sucess, 1 on failure
*/
static GLuint
-parse_matrix (GLcontext * ctx, byte ** inst, struct arb_program *Program,
+parse_matrix (GLcontext * ctx, GLubyte ** inst, struct arb_program *Program,
GLint * matrix, GLint * matrix_idx, GLint * matrix_modifier)
{
- byte mat = *(*inst)++;
+ GLubyte mat = *(*inst)++;
*matrix_idx = 0;
-
+
switch (mat) {
case MATRIX_MODELVIEW:
*matrix = STATE_MODELVIEW;
*matrix_idx = parse_integer (inst, Program);
- /* XXX: if (*matrix_idx >= ctx->Const. */
+ if (*matrix_idx > 0) {
+ _mesa_set_program_error (ctx, Program->Position,
+ "ARB_vertex_blend not supported\n");
+ _mesa_error (ctx, GL_INVALID_OPERATION,
+ "ARB_vertex_blend not supported\n");
+ return 1;
+ }
break;
case MATRIX_PROJECTION:
case MATRIX_TEXTURE:
*matrix = STATE_TEXTURE;
*matrix_idx = parse_integer (inst, Program);
- if (*matrix_idx >= ctx->Const.MaxTextureUnits) {
+ if (*matrix_idx >= (GLint) ctx->Const.MaxTextureUnits) {
_mesa_set_program_error (ctx, Program->Position,
"Invalid Texture Unit");
_mesa_error (ctx, GL_INVALID_OPERATION,
}
break;
- /* XXX: How should we handle the palette matrix? */
+ /* This is not currently supported (ARB_matrix_palette) */
case MATRIX_PALETTE:
*matrix_idx = parse_integer (inst, Program);
+ _mesa_set_program_error (ctx, Program->Position,
+ "ARB_matrix_palette not supported\n");
+ _mesa_error (ctx, GL_INVALID_OPERATION,
+ "ARB_matrix_palette not supported\n");
+ return 1;
break;
case MATRIX_PROGRAM:
*matrix = STATE_PROGRAM;
*matrix_idx = parse_integer (inst, Program);
- if (*matrix_idx >= ctx->Const.MaxProgramMatrices) {
+ if (*matrix_idx >= (GLint) ctx->Const.MaxProgramMatrices) {
_mesa_set_program_error (ctx, Program->Position,
"Invalid Program Matrix");
_mesa_error (ctx, GL_INVALID_OPERATION,
* \return - 0 on sucess, 1 on error
*/
static GLuint
-parse_state_single_item (GLcontext * ctx, byte ** inst,
+parse_state_single_item (GLcontext * ctx, GLubyte ** inst,
struct arb_program *Program, GLint * state_tokens)
{
switch (*(*inst)++) {
state_tokens[1] = parse_integer (inst, Program);
/* Check the value of state_tokens[1] against the # of lights */
- if (state_tokens[1] >= ctx->Const.MaxLights) {
+ if (state_tokens[1] >= (GLint) ctx->Const.MaxLights) {
_mesa_set_program_error (ctx, Program->Position,
"Invalid Light Number");
_mesa_error (ctx, GL_INVALID_OPERATION,
state_tokens[1] = parse_integer (inst, Program);
/* Check the value of state_tokens[1] against the # of lights */
- if (state_tokens[1] >= ctx->Const.MaxLights) {
+ if (state_tokens[1] >= (GLint) ctx->Const.MaxLights) {
_mesa_set_program_error (ctx, Program->Position,
"Invalid Light Number");
_mesa_error (ctx, GL_INVALID_OPERATION,
}
break;
- /* STATE_TEX_ENV == STATE_TEX_GEN */
case STATE_TEX_ENV:
- if (Program->type == GL_FRAGMENT_PROGRAM_ARB) {
- state_tokens[1] = parse_integer (inst, Program);
- switch (*(*inst)++) {
- case TEX_ENV_COLOR:
- state_tokens[0] = STATE_TEXENV_COLOR;
- break;
- }
+ state_tokens[1] = parse_integer (inst, Program);
+ switch (*(*inst)++) {
+ case TEX_ENV_COLOR:
+ state_tokens[0] = STATE_TEXENV_COLOR;
+ break;
}
- /* For vertex programs, this case is STATE_TEX_GEN */
- else {
+ break;
+
+ case STATE_TEX_GEN:
+ {
GLuint type, coord;
state_tokens[0] = STATE_TEXGEN;
}
break;
- /* STATE_DEPTH = STATE_CLIP_PLANE */
case STATE_DEPTH:
- if (Program->type == GL_FRAGMENT_PROGRAM_ARB) {
- switch (*(*inst)++) {
- case DEPTH_RANGE:
- state_tokens[0] = STATE_DEPTH_RANGE;
- break;
- }
- }
- /* for vertex programs, we want STATE_CLIP_PLANE */
- else {
- state_tokens[0] = STATE_CLIPPLANE;
- state_tokens[1] = parse_integer (inst, Program);
- if (parse_clipplane_num (ctx, inst, Program, &state_tokens[1]))
- return 1;
+ switch (*(*inst)++) {
+ case DEPTH_RANGE:
+ state_tokens[0] = STATE_DEPTH_RANGE;
+ break;
}
break;
+ case STATE_CLIP_PLANE:
+ state_tokens[0] = STATE_CLIPPLANE;
+ state_tokens[1] = parse_integer (inst, Program);
+ if (parse_clipplane_num (ctx, inst, Program, &state_tokens[1]))
+ return 1;
+ break;
+
case STATE_POINT:
switch (*(*inst++)) {
case POINT_SIZE:
/* XXX: I think this is the correct format for a matrix row */
case STATE_MATRIX_ROWS:
state_tokens[0] = STATE_MATRIX;
-
if (parse_matrix
(ctx, inst, Program, &state_tokens[1], &state_tokens[2],
&state_tokens[5]))
state_tokens[3] = parse_integer (inst, Program); /* The first row to grab */
- state_tokens[4] = parse_integer (inst, Program); /* Either the last row, 0 */
- if (state_tokens[4] == 0) {
+ if ((**inst) != 0) { /* Either the last row, 0 */
+ state_tokens[4] = parse_integer (inst, Program);
+ if (state_tokens[4] < state_tokens[3]) {
+ _mesa_set_program_error (ctx, Program->Position,
+ "Second matrix index less than the first");
+ _mesa_error (ctx, GL_INVALID_OPERATION,
+ "Second matrix index (%d) less than the first (%d)",
+ state_tokens[4], state_tokens[3]);
+ return 1;
+ }
+ }
+ else {
state_tokens[4] = state_tokens[3];
+ (*inst)++;
}
break;
}
* \return - 0 on sucess, 1 on failure
*/
static GLuint
-parse_program_single_item (GLcontext * ctx, byte ** inst,
+parse_program_single_item (GLcontext * ctx, GLubyte ** inst,
struct arb_program *Program, GLint * state_tokens)
{
if (Program->type == GL_FRAGMENT_PROGRAM_ARB)
case PROGRAM_PARAM_ENV:
state_tokens[1] = STATE_ENV;
state_tokens[2] = parse_integer (inst, Program);
+
/* Check state_tokens[2] against the number of ENV parameters available */
if (((Program->type == GL_FRAGMENT_PROGRAM_ARB) &&
- (state_tokens[2] >= ctx->Const.MaxFragmentProgramEnvParams))
+ (state_tokens[2] >= (GLint) ctx->Const.MaxFragmentProgramEnvParams))
||
((Program->type == GL_VERTEX_PROGRAM_ARB) &&
- (state_tokens[2] >= ctx->Const.MaxVertexProgramEnvParams))) {
+ (state_tokens[2] >= (GLint) ctx->Const.MaxVertexProgramEnvParams))) {
_mesa_set_program_error (ctx, Program->Position,
"Invalid Program Env Parameter");
_mesa_error (ctx, GL_INVALID_OPERATION,
case PROGRAM_PARAM_LOCAL:
state_tokens[1] = STATE_LOCAL;
state_tokens[2] = parse_integer (inst, Program);
+
/* Check state_tokens[2] against the number of LOCAL parameters available */
if (((Program->type == GL_FRAGMENT_PROGRAM_ARB) &&
- (state_tokens[2] >= ctx->Const.MaxFragmentProgramLocalParams))
+ (state_tokens[2] >= (GLint) ctx->Const.MaxFragmentProgramLocalParams))
||
((Program->type == GL_VERTEX_PROGRAM_ARB) &&
- (state_tokens[2] >= ctx->Const.MaxVertexProgramLocalParams))) {
+ (state_tokens[2] >= (GLint) ctx->Const.MaxVertexProgramLocalParams))) {
_mesa_set_program_error (ctx, Program->Position,
"Invalid Program Local Parameter");
_mesa_error (ctx, GL_INVALID_OPERATION,
return 0;
}
+/**
+ * For ARB_vertex_program, programs are not allowed to use both an explicit
+ * vertex attribute and a generic vertex attribute corresponding to the same
+ * state. See section 2.14.3.1 of the GL_ARB_vertex_program spec.
+ *
+ * This will walk our var_cache and make sure that nobody does anything fishy.
+ *
+ * \return 0 on sucess, 1 on error
+ */
+static GLuint
+generic_attrib_check(struct var_cache *vc_head)
+{
+ int a;
+ struct var_cache *curr;
+ GLboolean explicitAttrib[MAX_VERTEX_PROGRAM_ATTRIBS],
+ genericAttrib[MAX_VERTEX_PROGRAM_ATTRIBS];
+
+ for (a=0; a<MAX_VERTEX_PROGRAM_ATTRIBS; a++) {
+ explicitAttrib[a] = GL_FALSE;
+ genericAttrib[a] = GL_FALSE;
+ }
+
+ curr = vc_head;
+ while (curr) {
+ if (curr->type == vt_attrib) {
+ if (curr->attrib_is_generic)
+ genericAttrib[ curr->attrib_binding_idx ] = GL_TRUE;
+ else
+ explicitAttrib[ curr->attrib_binding_idx ] = GL_TRUE;
+ }
+
+ curr = curr->next;
+ }
+
+ for (a=0; a<MAX_VERTEX_PROGRAM_ATTRIBS; a++) {
+ if ((explicitAttrib[a]) && (genericAttrib[a]))
+ return 1;
+ }
+
+ return 0;
+}
/**
* This will handle the binding side of an ATTRIB var declaration
* See nvfragparse.c for attrib register file layout
*/
static GLuint
-parse_attrib_binding (GLcontext * ctx, byte ** inst,
+parse_attrib_binding (GLcontext * ctx, GLubyte ** inst,
struct arb_program *Program, GLuint * binding,
- GLuint * binding_idx)
+ GLuint * binding_idx, GLuint *is_generic)
{
GLuint texcoord;
GLint coord;
GLint err = 0;
+ *is_generic = 0;
if (Program->type == GL_FRAGMENT_PROGRAM_ARB) {
switch (*(*inst)++) {
case FRAGMENT_ATTRIB_COLOR:
*binding = VERT_ATTRIB_WEIGHT;
*binding_idx = 1;
}
+ _mesa_set_program_error (ctx, Program->Position,
+ "ARB_vertex_blend not supported\n");
+ _mesa_error (ctx, GL_INVALID_OPERATION,
+ "ARB_vertex_blend not supported\n");
+ return 1;
break;
case VERTEX_ATTRIB_NORMAL:
}
break;
- /* XXX: It looks like we don't support this at all, atm */
+ /* It looks like we don't support this at all, atm */
case VERTEX_ATTRIB_MATRIXINDEX:
parse_integer (inst, Program);
+ _mesa_set_program_error (ctx, Program->Position,
+ "ARB_palette_matrix not supported");
+ _mesa_error (ctx, GL_INVALID_OPERATION,
+ "ARB_palette_matrix not supported");
+ return 1;
break;
- /* XXX: */
case VERTEX_ATTRIB_GENERIC:
+ {
+ GLuint attrib;
+
+ if (!parse_generic_attrib_num(ctx, inst, Program, &attrib)) {
+ *is_generic = 1;
+ switch (attrib) {
+ case 0:
+ *binding = VERT_ATTRIB_POS;
+ break;
+ case 1:
+ *binding = VERT_ATTRIB_WEIGHT;
+ break;
+ case 2:
+ *binding = VERT_ATTRIB_NORMAL;
+ break;
+ case 3:
+ *binding = VERT_ATTRIB_COLOR0;
+ break;
+ case 4:
+ *binding = VERT_ATTRIB_COLOR1;
+ break;
+ case 5:
+ *binding = VERT_ATTRIB_FOG;
+ break;
+ case 6:
+ break;
+ case 7:
+ break;
+ default:
+ *binding = VERT_ATTRIB_TEX0 + (attrib-8);
+ break;
+ }
+ *binding_idx = attrib;
+ }
+ }
break;
default:
* See nvvertparse.c for the register file layout for vertex programs
*/
static GLuint
-parse_result_binding (GLcontext * ctx, byte ** inst, GLuint * binding,
+parse_result_binding (GLcontext * ctx, GLubyte ** inst, GLuint * binding,
GLuint * binding_idx, struct arb_program *Program)
{
GLuint b;
* \return 0 on sucess, 1 on error
*/
static GLint
-parse_attrib (GLcontext * ctx, byte ** inst, struct var_cache **vc_head,
+parse_attrib (GLcontext * ctx, GLubyte ** inst, struct var_cache **vc_head,
struct arb_program *Program)
{
GLuint found;
attrib_var = parse_string (inst, vc_head, Program, &found);
Program->Position = parse_position (inst);
if (found) {
- error_msg =
+ error_msg = (char *)
_mesa_malloc (_mesa_strlen ((char *) attrib_var->name) + 40);
_mesa_sprintf (error_msg, "Duplicate Varible Declaration: %s",
attrib_var->name);
{
if (parse_attrib_binding
(ctx, inst, Program, &attrib_var->attrib_binding,
- &attrib_var->attrib_binding_idx))
+ &attrib_var->attrib_binding_idx, &attrib_var->attrib_is_generic))
return 1;
+ if (generic_attrib_check(*vc_head)) {
+ _mesa_set_program_error (ctx, Program->Position,
+ "Cannot use both a generic vertex attribute and a specific attribute of the same type");
+ _mesa_error (ctx, GL_INVALID_OPERATION,
+ "Cannot use both a generic vertex attribute and a specific attribute of the same type");
+ return 1;
+ }
+
}
Program->Base.NumAttributes++;
* if we get a signed or unsigned float for scalar constants
*/
static GLuint
-parse_param_elements (GLcontext * ctx, byte ** inst,
+parse_param_elements (GLcontext * ctx, GLubyte ** inst,
struct var_cache *param_var,
struct arb_program *Program, GLboolean use)
{
switch (*(*inst)++) {
case PARAM_STATE_ELEMENT:
+
if (parse_state_single_item (ctx, inst, Program, state_tokens))
return 1;
idx =
_mesa_add_state_reference (Program->Parameters,
state_tokens);
- if (param_var->param_binding_begin == -1)
+ if (param_var->param_binding_begin == ~0U)
param_var->param_binding_begin = idx;
param_var->param_binding_length++;
Program->Base.NumParameters++;
else {
idx =
_mesa_add_state_reference (Program->Parameters, state_tokens);
- if (param_var->param_binding_begin == -1)
+ if (param_var->param_binding_begin == ~0U)
param_var->param_binding_begin = idx;
param_var->param_binding_length++;
Program->Base.NumParameters++;
break;
case PARAM_PROGRAM_ELEMENT:
+
if (parse_program_single_item (ctx, inst, Program, state_tokens))
return 1;
idx = _mesa_add_state_reference (Program->Parameters, state_tokens);
- if (param_var->param_binding_begin == -1)
+ if (param_var->param_binding_begin == ~0U)
param_var->param_binding_begin = idx;
param_var->param_binding_length++;
Program->Base.NumParameters++;
}
else {
if (((state_tokens[1] == STATE_ENV)
- && (end_idx >= ctx->Const.MaxFragmentProgramEnvParams))
+ && (end_idx >= ctx->Const.MaxVertexProgramEnvParams))
|| ((state_tokens[1] == STATE_LOCAL)
&& (end_idx >=
- ctx->Const.MaxFragmentProgramLocalParams)))
+ ctx->Const.MaxVertexProgramLocalParams)))
out_of_range = 1;
}
if (out_of_range) {
Program->Base.NumParameters++;
}
}
+ else
+ {
+ (*inst)++;
+ }
break;
case PARAM_CONSTANT:
idx =
_mesa_add_named_constant (Program->Parameters,
(char *) param_var->name, const_values);
- if (param_var->param_binding_begin == -1)
+ if (param_var->param_binding_begin == ~0U)
param_var->param_binding_begin = idx;
param_var->param_binding_length++;
Program->Base.NumParameters++;
* \return 0 on sucess, 1 on error
*/
static GLuint
-parse_param (GLcontext * ctx, byte ** inst, struct var_cache **vc_head,
+parse_param (GLcontext * ctx, GLubyte ** inst, struct var_cache **vc_head,
struct arb_program *Program)
{
GLuint found, specified_length, err;
Program->Position = parse_position (inst);
if (found) {
- error_msg = _mesa_malloc (_mesa_strlen ((char *) param_var->name) + 40);
+ error_msg = (char *) _mesa_malloc (_mesa_strlen ((char *) param_var->name) + 40);
_mesa_sprintf (error_msg, "Duplicate Varible Declaration: %s",
param_var->name);
*
*/
static GLuint
-parse_param_use (GLcontext * ctx, byte ** inst, struct var_cache **vc_head,
+parse_param_use (GLcontext * ctx, GLubyte ** inst, struct var_cache **vc_head,
struct arb_program *Program, struct var_cache **new_var)
{
struct var_cache *param_var;
/* First, insert a dummy entry into the var_cache */
var_cache_create (¶m_var);
- param_var->name = (byte *) _mesa_strdup (" ");
+ param_var->name = (GLubyte *) _mesa_strdup (" ");
param_var->type = vt_param;
param_var->param_binding_length = 0;
*/
param_var->param_binding_type = PROGRAM_STATE_VAR;
-
var_cache_append (vc_head, param_var);
/* Then fill it with juicy parameter goodness */
* \return 0 on sucess, 1 on error
*/
static GLuint
-parse_temp (GLcontext * ctx, byte ** inst, struct var_cache **vc_head,
+parse_temp (GLcontext * ctx, GLubyte ** inst, struct var_cache **vc_head,
struct arb_program *Program)
{
GLuint found;
temp_var = parse_string (inst, vc_head, Program, &found);
Program->Position = parse_position (inst);
if (found) {
- error_msg =
+ error_msg = (char *)
_mesa_malloc (_mesa_strlen ((char *) temp_var->name) + 40);
_mesa_sprintf (error_msg, "Duplicate Varible Declaration: %s",
temp_var->name);
* \return 0 on sucess, 1 on error
*/
static GLuint
-parse_output (GLcontext * ctx, byte ** inst, struct var_cache **vc_head,
+parse_output (GLcontext * ctx, GLubyte ** inst, struct var_cache **vc_head,
struct arb_program *Program)
{
GLuint found;
Program->Position = parse_position (inst);
if (found) {
char *error_msg;
- error_msg =
+ error_msg = (char *)
_mesa_malloc (_mesa_strlen ((char *) output_var->name) + 40);
_mesa_sprintf (error_msg, "Duplicate Varible Declaration: %s",
output_var->name);
* \return 0 on sucess, 1 on error
*/
static GLuint
-parse_alias (GLcontext * ctx, byte ** inst, struct var_cache **vc_head,
+parse_alias (GLcontext * ctx, GLubyte ** inst, struct var_cache **vc_head,
struct arb_program *Program)
{
GLuint found;
struct var_cache *temp_var;
char *error_msg;
- while (**inst != 0) {
- temp_var = parse_string (inst, vc_head, Program, &found);
- Program->Position = parse_position (inst);
- if (found) {
- error_msg =
- _mesa_malloc (_mesa_strlen ((char *) temp_var->name) + 40);
- _mesa_sprintf (error_msg, "Duplicate Varible Declaration: %s",
- temp_var->name);
+
+ temp_var = parse_string (inst, vc_head, Program, &found);
+ Program->Position = parse_position (inst);
- _mesa_set_program_error (ctx, Program->Position, error_msg);
- _mesa_error (ctx, GL_INVALID_OPERATION, error_msg);
+ if (found) {
+ error_msg = (char *)
+ _mesa_malloc (_mesa_strlen ((char *) temp_var->name) + 40);
+ _mesa_sprintf (error_msg, "Duplicate Varible Declaration: %s",
+ temp_var->name);
- _mesa_free (error_msg);
- return 1;
- }
+ _mesa_set_program_error (ctx, Program->Position, error_msg);
+ _mesa_error (ctx, GL_INVALID_OPERATION, error_msg);
- temp_var->type = vt_temp;
+ _mesa_free (error_msg);
+ return 1;
+ }
- if (((Program->type == GL_FRAGMENT_PROGRAM_ARB) &&
- (Program->Base.NumTemporaries >=
- ctx->Const.MaxFragmentProgramTemps))
- || ((Program->type == GL_VERTEX_PROGRAM_ARB)
- && (Program->Base.NumTemporaries >=
- ctx->Const.MaxVertexProgramTemps))) {
- _mesa_set_program_error (ctx, Program->Position,
- "Too many TEMP variables declared");
- _mesa_error (ctx, GL_INVALID_OPERATION,
- "Too many TEMP variables declared");
- return 1;
- }
+ temp_var->type = vt_alias;
+ temp_var->alias_binding = parse_string (inst, vc_head, Program, &found);
+ Program->Position = parse_position (inst);
- temp_var->temp_binding = Program->Base.NumTemporaries;
- Program->Base.NumTemporaries++;
+ if (!found)
+ {
+ error_msg = (char *)
+ _mesa_malloc (_mesa_strlen ((char *) temp_var->name) + 40);
+ _mesa_sprintf (error_msg, "Alias value %s is not defined",
+ temp_var->alias_binding->name);
+
+ _mesa_set_program_error (ctx, Program->Position, error_msg);
+ _mesa_error (ctx, GL_INVALID_OPERATION, error_msg);
+
+ _mesa_free (error_msg);
+ return 1;
}
- (*inst)++;
return 0;
}
* \return 0 on sucess, 1 on error
*/
static GLuint
-parse_address (GLcontext * ctx, byte ** inst, struct var_cache **vc_head,
+parse_address (GLcontext * ctx, GLubyte ** inst, struct var_cache **vc_head,
struct arb_program *Program)
{
GLuint found;
temp_var = parse_string (inst, vc_head, Program, &found);
Program->Position = parse_position (inst);
if (found) {
- error_msg =
+ error_msg = (char *)
_mesa_malloc (_mesa_strlen ((char *) temp_var->name) + 40);
_mesa_sprintf (error_msg, "Duplicate Varible Declaration: %s",
temp_var->name);
* \return 0 on sucess, 1 on error
*/
static GLint
-parse_declaration (GLcontext * ctx, byte ** inst, struct var_cache **vc_head,
+parse_declaration (GLcontext * ctx, GLubyte ** inst, struct var_cache **vc_head,
struct arb_program *Program)
{
GLint err = 0;
/**
* Handle the parsing out of a masked destination register
*
+ * If we are a vertex program, make sure we don't write to
+ * result.position of we have specified that the program is
+ * position invariant
+ *
* \param File - The register file we write to
* \param Index - The register index we write to
* \param WriteMask - The mask controlling which components we write (1->write)
* \return 0 on sucess, 1 on error
*/
static GLuint
-parse_masked_dst_reg (GLcontext * ctx, byte ** inst,
+parse_masked_dst_reg (GLcontext * ctx, GLubyte ** inst,
struct var_cache **vc_head, struct arb_program *Program,
GLint * File, GLint * Index, GLboolean * WriteMask)
{
GLuint result;
- byte mask;
+ GLubyte mask;
struct var_cache *dst;
/* We either have a result register specified, or a
/* If the name has never been added to our symbol table, we're hosed */
if (!result) {
_mesa_set_program_error (ctx, Program->Position,
- "Undefined variable");
- _mesa_error (ctx, GL_INVALID_OPERATION, "Undefined variable: %s",
+ "0: Undefined variable");
+ _mesa_error (ctx, GL_INVALID_OPERATION, "0: Undefined variable: %s",
dst->name);
return 1;
}
return 1;
}
+
+ /* Position invariance test */
+ if ((Program->HintPositionInvariant) && (*File == PROGRAM_OUTPUT) &&
+ (*Index == 0)) {
+ _mesa_set_program_error (ctx, Program->Position,
+ "Vertex program specified position invariance and wrote vertex position");
+ _mesa_error (ctx, GL_INVALID_OPERATION,
+ "Vertex program specified position invariance and wrote vertex position");
+ }
+
/* And then the mask.
* w,a -> bit 0
* z,b -> bit 1
*/
mask = *(*inst)++;
- WriteMask[0] = (mask & (1 << 3)) >> 3;
- WriteMask[1] = (mask & (1 << 2)) >> 2;
- WriteMask[2] = (mask & (1 << 1)) >> 1;
- WriteMask[3] = (mask & (1));
+ WriteMask[0] = (GLboolean) (mask & (1 << 3)) >> 3;
+ WriteMask[1] = (GLboolean) (mask & (1 << 2)) >> 2;
+ WriteMask[2] = (GLboolean) (mask & (1 << 1)) >> 1;
+ WriteMask[3] = (GLboolean) (mask & (1));
return 0;
}
-/**
- * Handle the parsing out of a masked address register
+
+/**
+ * Handle the parsing of a address register
*
* \param Index - The register index we write to
- * \param WriteMask - The mask controlling which components we write (1->write)
*
* \return 0 on sucess, 1 on error
*/
static GLuint
-parse_masked_address_reg (GLcontext * ctx, byte ** inst,
+parse_address_reg (GLcontext * ctx, GLubyte ** inst,
struct var_cache **vc_head,
- struct arb_program *Program, GLint * Index,
- GLboolean * WriteMask)
+ struct arb_program *Program, GLint * Index)
{
struct var_cache *dst;
GLuint result;
return 1;
}
+ return 0;
+}
+
+/**
+ * Handle the parsing out of a masked address register
+ *
+ * \param Index - The register index we write to
+ * \param WriteMask - The mask controlling which components we write (1->write)
+ *
+ * \return 0 on sucess, 1 on error
+ */
+static GLuint
+parse_masked_address_reg (GLcontext * ctx, GLubyte ** inst,
+ struct var_cache **vc_head,
+ struct arb_program *Program, GLint * Index,
+ GLboolean * WriteMask)
+{
+ if (parse_address_reg (ctx, inst, vc_head, Program, Index))
+ return 1;
+
+ /* This should be 0x8 */
+ (*inst)++;
+
/* Writemask of .x is implied */
WriteMask[0] = 1;
WriteMask[1] = WriteMask[2] = WriteMask[3] = 0;
return 0;
}
+
/**
* Parse out a swizzle mask.
*
* swizzle, or just 1 component for a scalar src register selection
*/
static GLuint
-parse_swizzle_mask (byte ** inst, GLubyte * mask, GLint len)
+parse_swizzle_mask (GLubyte ** inst, GLubyte * mask, GLint len)
{
GLint a;
/**
*/
static GLuint
-parse_extended_swizzle_mask (byte ** inst, GLubyte * mask, GLboolean * Negate)
+parse_extended_swizzle_mask (GLubyte ** inst, GLubyte * mask, GLboolean * Negate)
{
GLint a;
- byte swz;
+ GLubyte swz;
*Negate = GL_FALSE;
for (a = 0; a < 4; a++) {
mask[a] = SWIZZLE_ONE;
break;
case COMPONENT_X:
- mask[a] = 0;
+ mask[a] = SWIZZLE_X;
break;
case COMPONENT_Y:
- mask[a] = 1;
+ mask[a] = SWIZZLE_Y;
break;
case COMPONENT_Z:
- mask[a] = 2;
+ mask[a] = SWIZZLE_Z;
break;
case COMPONENT_W:
- mask[a] = 3;
+ mask[a] = SWIZZLE_W;
break;
}
static GLuint
-parse_src_reg (GLcontext * ctx, byte ** inst, struct var_cache **vc_head,
- struct arb_program *Program, GLint * File, GLint * Index)
+parse_src_reg (GLcontext * ctx, GLubyte ** inst, struct var_cache **vc_head,
+ struct arb_program *Program, GLint * File, GLint * Index,
+ GLboolean *IsRelOffset )
{
struct var_cache *src;
- GLuint binding_state, binding_idx, found, offset;
+ GLuint binding_state, binding_idx, is_generic, found, offset;
/* And the binding for the src */
switch (*(*inst)++) {
case REGISTER_ATTRIB:
if (parse_attrib_binding
- (ctx, inst, Program, &binding_state, &binding_idx))
+ (ctx, inst, Program, &binding_state, &binding_idx, &is_generic))
return 1;
*File = PROGRAM_INPUT;
*Index = binding_idx;
+
+ /* We need to insert a dummy variable into the var_cache so we can
+ * catch generic vertex attrib aliasing errors
+ */
+ var_cache_create(&src);
+ src->type = vt_attrib;
+ src->name = (GLubyte *)_mesa_strdup("Dummy Attrib Variable");
+ src->attrib_binding = binding_state;
+ src->attrib_binding_idx = binding_idx;
+ src->attrib_is_generic = is_generic;
+ var_cache_append(vc_head, src);
+ if (generic_attrib_check(*vc_head)) {
+ _mesa_set_program_error (ctx, Program->Position,
+ "Cannot use both a generic vertex attribute and a specific attribute of the same type");
+ _mesa_error (ctx, GL_INVALID_OPERATION,
+ "Cannot use both a generic vertex attribute and a specific attribute of the same type");
+ return 1;
+ }
break;
case REGISTER_PARAM:
-
switch (**inst) {
case PARAM_ARRAY_ELEMENT:
- *(*inst)++;
+ (*inst)++;
src = parse_string (inst, vc_head, Program, &found);
Program->Position = parse_position (inst);
if (!found) {
_mesa_set_program_error (ctx, Program->Position,
- "Undefined variable");
+ "2: Undefined variable");
_mesa_error (ctx, GL_INVALID_OPERATION,
- "Undefined variable: %s", src->name);
+ "2: Undefined variable: %s", src->name);
return 1;
}
*Index = src->param_binding_begin + offset;
break;
- /* XXX: */
case ARRAY_INDEX_RELATIVE:
+ {
+ GLint addr_reg_idx, rel_off;
+
+ /* First, grab the address regiseter */
+ if (parse_address_reg (ctx, inst, vc_head, Program, &addr_reg_idx))
+ return 1;
+
+ /* And the .x */
+ ((*inst)++);
+ ((*inst)++);
+ ((*inst)++);
+ ((*inst)++);
+
+ /* Then the relative offset */
+ if (parse_relative_offset(ctx, inst, Program, &rel_off)) return 1;
+
+ /* And store it properly */
+ *Index = src->param_binding_begin + rel_off;
+ *IsRelOffset = 1;
+ }
break;
}
break;
default:
+
if (parse_param_use (ctx, inst, vc_head, Program, &src))
return 1;
break;
case REGISTER_ESTABLISHED_NAME:
+
src = parse_string (inst, vc_head, Program, &found);
Program->Position = parse_position (inst);
/* If the name has never been added to our symbol table, we're hosed */
if (!found) {
_mesa_set_program_error (ctx, Program->Position,
- "Undefined variable");
- _mesa_error (ctx, GL_INVALID_OPERATION, "Undefined variable: %s",
+ "3: Undefined variable");
+ _mesa_error (ctx, GL_INVALID_OPERATION, "3: Undefined variable: %s",
src->name);
return 1;
}
/**
*/
static GLuint
-parse_vector_src_reg (GLcontext * ctx, byte ** inst,
+parse_vector_src_reg (GLcontext * ctx, GLubyte ** inst,
struct var_cache **vc_head, struct arb_program *Program,
GLint * File, GLint * Index, GLboolean * Negate,
- GLubyte * Swizzle)
+ GLubyte * Swizzle, GLboolean *IsRelOffset)
{
/* Grab the sign */
*Negate = parse_sign (inst);
/* And the src reg */
- if (parse_src_reg (ctx, inst, vc_head, Program, File, Index))
+ if (parse_src_reg (ctx, inst, vc_head, Program, File, Index, IsRelOffset))
return 1;
/* finally, the swizzle */
parse_swizzle_mask (inst, Swizzle, 4);
-
+
return 0;
}
/**
*/
static GLuint
-parse_scalar_src_reg (GLcontext * ctx, byte ** inst,
+parse_scalar_src_reg (GLcontext * ctx, GLubyte ** inst,
struct var_cache **vc_head, struct arb_program *Program,
GLint * File, GLint * Index, GLboolean * Negate,
- GLubyte * Swizzle)
+ GLubyte * Swizzle, GLboolean *IsRelOffset)
{
/* Grab the sign */
*Negate = parse_sign (inst);
/* And the src reg */
- if (parse_src_reg (ctx, inst, vc_head, Program, File, Index))
+ if (parse_src_reg (ctx, inst, vc_head, Program, File, Index, IsRelOffset))
return 1;
/* Now, get the component and shove it into all the swizzle slots */
* and handling the src & dst registers for fragment program instructions
*/
static GLuint
-parse_fp_instruction (GLcontext * ctx, byte ** inst,
+parse_fp_instruction (GLcontext * ctx, GLubyte ** inst,
struct var_cache **vc_head, struct arb_program *Program,
struct fp_instruction *fp)
{
GLint a, b;
GLubyte swz[4]; /* FP's swizzle mask is a GLubyte, while VP's is GLuint */
GLuint texcoord;
- byte class, type, code;
+ GLubyte instClass, type, code;
+ GLboolean rel;
/* No condition codes in ARB_fp */
fp->UpdateCondRegister = 0;
/* Record the position in the program string for debugging */
fp->StringPos = Program->Position;
- /* F_ALU_INST or F_TEX_INST */
- class = *(*inst)++;
+ /* OP_ALU_INST or OP_TEX_INST */
+ instClass = *(*inst)++;
- /* F_ALU_{VECTOR, SCALAR, BINSC, BIN, TRI, SWZ},
- * F_TEX_{SAMPLE, KIL}
+ /* OP_ALU_{VECTOR, SCALAR, BINSC, BIN, TRI, SWZ},
+ * OP_TEX_{SAMPLE, KIL}
*/
type = *(*inst)++;
/* The actual opcode name */
code = *(*inst)++;
-
/* Increment the correct count */
- switch (class) {
- case F_ALU_INST:
+ switch (instClass) {
+ case OP_ALU_INST:
Program->NumAluInstructions++;
break;
- case F_TEX_INST:
+ case OP_TEX_INST:
Program->NumTexInstructions++;
break;
}
fp->DstReg.CondMask = COND_TR;
switch (type) {
- case F_ALU_VECTOR:
+ case OP_ALU_VECTOR:
switch (code) {
- case F_ABS_SAT:
+ case OP_ABS_SAT:
fp->Saturate = 1;
- case F_ABS:
+ case OP_ABS:
fp->Opcode = FP_OPCODE_ABS;
break;
- case F_FLR_SAT:
+ case OP_FLR_SAT:
fp->Saturate = 1;
- case F_FLR:
+ case OP_FLR:
fp->Opcode = FP_OPCODE_FLR;
break;
- case F_FRC_SAT:
+ case OP_FRC_SAT:
fp->Saturate = 1;
- case F_FRC:
+ case OP_FRC:
fp->Opcode = FP_OPCODE_FRC;
break;
- case F_LIT_SAT:
+ case OP_LIT_SAT:
fp->Saturate = 1;
- case F_LIT:
+ case OP_LIT:
fp->Opcode = FP_OPCODE_LIT;
break;
- case F_MOV_SAT:
+ case OP_MOV_SAT:
fp->Saturate = 1;
- case F_MOV:
+ case OP_MOV:
fp->Opcode = FP_OPCODE_MOV;
break;
}
if (parse_vector_src_reg
(ctx, inst, vc_head, Program, (GLint *) & fp->SrcReg[0].File,
&fp->SrcReg[0].Index, &fp->SrcReg[0].NegateBase,
- swz))
+ swz, &rel))
return 1;
for (b=0; b<4; b++)
fp->SrcReg[0].Swizzle[b] = swz[b];
break;
- case F_ALU_SCALAR:
+ case OP_ALU_SCALAR:
switch (code) {
- case F_COS_SAT:
+ case OP_COS_SAT:
fp->Saturate = 1;
- case F_COS:
+ case OP_COS:
fp->Opcode = FP_OPCODE_COS;
break;
- case F_EX2_SAT:
+ case OP_EX2_SAT:
fp->Saturate = 1;
- case F_EX2:
+ case OP_EX2:
fp->Opcode = FP_OPCODE_EX2;
break;
- case F_LG2_SAT:
+ case OP_LG2_SAT:
fp->Saturate = 1;
- case F_LG2:
+ case OP_LG2:
fp->Opcode = FP_OPCODE_LG2;
break;
- case F_RCP_SAT:
+ case OP_RCP_SAT:
fp->Saturate = 1;
- case F_RCP:
+ case OP_RCP:
fp->Opcode = FP_OPCODE_RCP;
break;
- case F_RSQ_SAT:
+ case OP_RSQ_SAT:
fp->Saturate = 1;
- case F_RSQ:
+ case OP_RSQ:
fp->Opcode = FP_OPCODE_RSQ;
break;
- case F_SIN_SAT:
+ case OP_SIN_SAT:
fp->Saturate = 1;
- case F_SIN:
+ case OP_SIN:
fp->Opcode = FP_OPCODE_SIN;
break;
- case F_SCS_SAT:
+ case OP_SCS_SAT:
fp->Saturate = 1;
- case F_SCS:
+ case OP_SCS:
+
fp->Opcode = FP_OPCODE_SCS;
break;
}
if (parse_scalar_src_reg
(ctx, inst, vc_head, Program, (GLint *) & fp->SrcReg[0].File,
&fp->SrcReg[0].Index, &fp->SrcReg[0].NegateBase,
- swz))
+ swz, &rel))
return 1;
for (b=0; b<4; b++)
fp->SrcReg[0].Swizzle[b] = swz[b];
break;
- case F_ALU_BINSC:
+ case OP_ALU_BINSC:
switch (code) {
- case F_POW_SAT:
+ case OP_POW_SAT:
fp->Saturate = 1;
- case F_POW:
+ case OP_POW:
fp->Opcode = FP_OPCODE_POW;
break;
}
if (parse_scalar_src_reg
(ctx, inst, vc_head, Program, (GLint *) & fp->SrcReg[a].File,
&fp->SrcReg[a].Index, &fp->SrcReg[a].NegateBase,
- swz))
+ swz, &rel))
return 1;
for (b=0; b<4; b++)
fp->SrcReg[a].Swizzle[b] = swz[b];
break;
- case F_ALU_BIN:
+ case OP_ALU_BIN:
switch (code) {
- case F_ADD_SAT:
+ case OP_ADD_SAT:
fp->Saturate = 1;
- case F_ADD:
+ case OP_ADD:
fp->Opcode = FP_OPCODE_ADD;
break;
- case F_DP3_SAT:
+ case OP_DP3_SAT:
fp->Saturate = 1;
- case F_DP3:
+ case OP_DP3:
fp->Opcode = FP_OPCODE_DP3;
break;
- case F_DP4_SAT:
+ case OP_DP4_SAT:
fp->Saturate = 1;
- case F_DP4:
+ case OP_DP4:
fp->Opcode = FP_OPCODE_DP4;
break;
- case F_DPH_SAT:
+ case OP_DPH_SAT:
fp->Saturate = 1;
- case F_DPH:
+ case OP_DPH:
fp->Opcode = FP_OPCODE_DPH;
break;
- case F_DST_SAT:
+ case OP_DST_SAT:
fp->Saturate = 1;
- case F_DST:
+ case OP_DST:
fp->Opcode = FP_OPCODE_DST;
break;
- case F_MAX_SAT:
+ case OP_MAX_SAT:
fp->Saturate = 1;
- case F_MAX:
+ case OP_MAX:
fp->Opcode = FP_OPCODE_MAX;
break;
- case F_MIN_SAT:
+ case OP_MIN_SAT:
fp->Saturate = 1;
- case F_MIN:
+ case OP_MIN:
fp->Opcode = FP_OPCODE_MIN;
break;
- case F_MUL_SAT:
+ case OP_MUL_SAT:
fp->Saturate = 1;
- case F_MUL:
+ case OP_MUL:
fp->Opcode = FP_OPCODE_MUL;
break;
- case F_SGE_SAT:
+ case OP_SGE_SAT:
fp->Saturate = 1;
- case F_SGE:
+ case OP_SGE:
fp->Opcode = FP_OPCODE_SGE;
break;
- case F_SLT_SAT:
+ case OP_SLT_SAT:
fp->Saturate = 1;
- case F_SLT:
+ case OP_SLT:
fp->Opcode = FP_OPCODE_SLT;
break;
- case F_SUB_SAT:
+ case OP_SUB_SAT:
fp->Saturate = 1;
- case F_SUB:
+ case OP_SUB:
fp->Opcode = FP_OPCODE_SUB;
break;
- case F_XPD_SAT:
+ case OP_XPD_SAT:
fp->Saturate = 1;
- case F_XPD:
+ case OP_XPD:
fp->Opcode = FP_OPCODE_X2D;
break;
}
if (parse_vector_src_reg
(ctx, inst, vc_head, Program, (GLint *) & fp->SrcReg[a].File,
&fp->SrcReg[a].Index, &fp->SrcReg[a].NegateBase,
- swz))
+ swz, &rel))
return 1;
for (b=0; b<4; b++)
fp->SrcReg[a].Swizzle[b] = swz[b];
}
break;
- case F_ALU_TRI:
+ case OP_ALU_TRI:
switch (code) {
- case F_CMP_SAT:
+ case OP_CMP_SAT:
fp->Saturate = 1;
- case F_CMP:
+ case OP_CMP:
fp->Opcode = FP_OPCODE_CMP;
break;
- case F_LRP_SAT:
+ case OP_LRP_SAT:
fp->Saturate = 1;
- case F_LRP:
+ case OP_LRP:
fp->Opcode = FP_OPCODE_LRP;
break;
- case F_MAD_SAT:
+ case OP_MAD_SAT:
fp->Saturate = 1;
- case F_MAD:
+ case OP_MAD:
fp->Opcode = FP_OPCODE_MAD;
break;
}
if (parse_vector_src_reg
(ctx, inst, vc_head, Program, (GLint *) & fp->SrcReg[a].File,
&fp->SrcReg[a].Index, &fp->SrcReg[a].NegateBase,
- swz))
+ swz, &rel))
return 1;
for (b=0; b<4; b++)
fp->SrcReg[a].Swizzle[b] = swz[b];
}
break;
- case F_ALU_SWZ:
+ case OP_ALU_SWZ:
switch (code) {
- case F_SWZ_SAT:
+ case OP_SWZ_SAT:
fp->Saturate = 1;
- case F_SWZ:
+ case OP_SWZ:
fp->Opcode = FP_OPCODE_SWZ;
break;
}
if (parse_src_reg
(ctx, inst, vc_head, Program, (GLint *) & fp->SrcReg[0].File,
- &fp->SrcReg[0].Index))
+ &fp->SrcReg[0].Index, &rel))
return 1;
parse_extended_swizzle_mask (inst, swz,
&fp->SrcReg[0].NegateBase);
fp->SrcReg[0].Swizzle[b] = swz[b];
break;
- case F_TEX_SAMPLE:
+ case OP_TEX_SAMPLE:
switch (code) {
- case F_TEX_SAT:
+ case OP_TEX_SAT:
fp->Saturate = 1;
- case F_TEX:
+ case OP_TEX:
fp->Opcode = FP_OPCODE_TEX;
break;
- case F_TXP_SAT:
+ case OP_TXP_SAT:
fp->Saturate = 1;
- case F_TXP:
+ case OP_TXP:
fp->Opcode = FP_OPCODE_TXP;
break;
- case F_TXB_SAT:
+ case OP_TXB_SAT:
+
fp->Saturate = 1;
- case F_TXB:
+ case OP_TXB:
fp->Opcode = FP_OPCODE_TXB;
break;
}
if (parse_vector_src_reg
(ctx, inst, vc_head, Program, (GLint *) & fp->SrcReg[0].File,
&fp->SrcReg[0].Index, &fp->SrcReg[0].NegateBase,
- swz))
+ swz, &rel))
return 1;
for (b=0; b<4; b++)
fp->SrcReg[0].Swizzle[b] = swz[b];
fp->TexSrcUnit = texcoord;
/* texTarget */
- switch (*(*inst)) {
+ switch (*(*inst)++) {
case TEXTARGET_1D:
fp->TexSrcBit = TEXTURE_1D_BIT;
break;
fp->TexSrcBit = TEXTURE_CUBE_BIT;
break;
}
+ Program->TexturesUsed[texcoord] |= fp->TexSrcBit;
break;
- case F_TEX_KIL:
+ case OP_TEX_KIL:
fp->Opcode = FP_OPCODE_KIL;
fp->SrcReg[0].Abs = GL_FALSE;
fp->SrcReg[0].NegateAbs = GL_FALSE;
if (parse_vector_src_reg
(ctx, inst, vc_head, Program, (GLint *) & fp->SrcReg[0].File,
&fp->SrcReg[0].Index, &fp->SrcReg[0].NegateBase,
- swz))
+ swz, &rel))
return 1;
for (b=0; b<4; b++)
fp->SrcReg[0].Swizzle[b] = swz[b];
* and handling the src & dst registers for vertex program instructions
*/
static GLuint
-parse_vp_instruction (GLcontext * ctx, byte ** inst,
+parse_vp_instruction (GLcontext * ctx, GLubyte ** inst,
struct var_cache **vc_head, struct arb_program *Program,
struct vp_instruction *vp)
{
GLint a;
- byte type, code;
+ GLubyte type, code;
- /* V_GEN_{ARL, VECTOR, SCALAR, BINSC, BIN, TRI, SWZ} */
+ /* OP_ALU_{ARL, VECTOR, SCALAR, BINSC, BIN, TRI, SWZ} */
type = *(*inst)++;
/* The actual opcode name */
code = *(*inst)++;
+ /* Record the position in the program string for debugging */
+ vp->StringPos = Program->Position;
+
vp->SrcReg[0].RelAddr = vp->SrcReg[1].RelAddr = vp->SrcReg[2].RelAddr = 0;
for (a = 0; a < 4; a++) {
switch (type) {
/* XXX: */
- case V_GEN_ARL:
+ case OP_ALU_ARL:
vp->Opcode = VP_OPCODE_ARL;
/* Remember to set SrcReg.RelAddr; */
return 1;
vp->DstReg.File = PROGRAM_ADDRESS;
-
/* Get a scalar src register */
if (parse_scalar_src_reg
(ctx, inst, vc_head, Program, (GLint *) & vp->SrcReg[0].File,
&vp->SrcReg[0].Index, &vp->SrcReg[0].Negate,
- vp->SrcReg[0].Swizzle))
+ vp->SrcReg[0].Swizzle, &vp->SrcReg[0].RelAddr))
return 1;
break;
- case V_GEN_VECTOR:
+ case OP_ALU_VECTOR:
switch (code) {
- case V_ABS:
+ case OP_ABS:
vp->Opcode = VP_OPCODE_ABS;
break;
- case V_FLR:
+ case OP_FLR:
vp->Opcode = VP_OPCODE_FLR;
break;
- case V_FRC:
+ case OP_FRC:
vp->Opcode = VP_OPCODE_FRC;
break;
- case V_LIT:
+ case OP_LIT:
vp->Opcode = VP_OPCODE_LIT;
break;
- case V_MOV:
+ case OP_MOV:
vp->Opcode = VP_OPCODE_MOV;
break;
}
if (parse_vector_src_reg
(ctx, inst, vc_head, Program, (GLint *) & vp->SrcReg[0].File,
&vp->SrcReg[0].Index, &vp->SrcReg[0].Negate,
- vp->SrcReg[0].Swizzle))
+ vp->SrcReg[0].Swizzle, &vp->SrcReg[0].RelAddr))
return 1;
break;
- case V_GEN_SCALAR:
+ case OP_ALU_SCALAR:
switch (code) {
- case V_EX2:
+ case OP_EX2:
vp->Opcode = VP_OPCODE_EX2;
break;
- case V_EXP:
+ case OP_EXP:
vp->Opcode = VP_OPCODE_EXP;
break;
- case V_LG2:
+ case OP_LG2:
vp->Opcode = VP_OPCODE_LG2;
break;
- case V_LOG:
+ case OP_LOG:
vp->Opcode = VP_OPCODE_LOG;
break;
- case V_RCP:
+ case OP_RCP:
vp->Opcode = VP_OPCODE_RCP;
break;
- case V_RSQ:
+ case OP_RSQ:
vp->Opcode = VP_OPCODE_RSQ;
break;
}
if (parse_scalar_src_reg
(ctx, inst, vc_head, Program, (GLint *) & vp->SrcReg[0].File,
&vp->SrcReg[0].Index, &vp->SrcReg[0].Negate,
- vp->SrcReg[0].Swizzle))
+ vp->SrcReg[0].Swizzle, &vp->SrcReg[0].RelAddr))
return 1;
break;
- case V_GEN_BINSC:
+ case OP_ALU_BINSC:
switch (code) {
- case V_POW:
+ case OP_POW:
vp->Opcode = VP_OPCODE_POW;
break;
}
if (parse_scalar_src_reg
(ctx, inst, vc_head, Program, (GLint *) & vp->SrcReg[a].File,
&vp->SrcReg[a].Index, &vp->SrcReg[a].Negate,
- vp->SrcReg[a].Swizzle))
+ vp->SrcReg[a].Swizzle, &vp->SrcReg[a].RelAddr))
return 1;
}
break;
- case V_GEN_BIN:
+ case OP_ALU_BIN:
switch (code) {
- case V_ADD:
+ case OP_ADD:
vp->Opcode = VP_OPCODE_ADD;
break;
- case V_DP3:
+ case OP_DP3:
vp->Opcode = VP_OPCODE_DP3;
break;
- case V_DP4:
+ case OP_DP4:
vp->Opcode = VP_OPCODE_DP4;
break;
- case V_DPH:
+ case OP_DPH:
vp->Opcode = VP_OPCODE_DPH;
break;
- case V_DST:
+ case OP_DST:
vp->Opcode = VP_OPCODE_DST;
break;
- case V_MAX:
+ case OP_MAX:
vp->Opcode = VP_OPCODE_MAX;
break;
- case V_MIN:
+ case OP_MIN:
vp->Opcode = VP_OPCODE_MIN;
break;
- case V_MUL:
+ case OP_MUL:
vp->Opcode = VP_OPCODE_MUL;
break;
- case V_SGE:
+ case OP_SGE:
vp->Opcode = VP_OPCODE_SGE;
break;
- case V_SLT:
+ case OP_SLT:
vp->Opcode = VP_OPCODE_SLT;
break;
- case V_SUB:
+ case OP_SUB:
vp->Opcode = VP_OPCODE_SUB;
break;
- case V_XPD:
+ case OP_XPD:
vp->Opcode = VP_OPCODE_XPD;
break;
}
if (parse_vector_src_reg
(ctx, inst, vc_head, Program, (GLint *) & vp->SrcReg[a].File,
&vp->SrcReg[a].Index, &vp->SrcReg[a].Negate,
- vp->SrcReg[a].Swizzle))
+ vp->SrcReg[a].Swizzle, &vp->SrcReg[a].RelAddr))
return 1;
}
break;
- case V_GEN_TRI:
+ case OP_ALU_TRI:
switch (code) {
- case V_MAD:
+ case OP_MAD:
vp->Opcode = VP_OPCODE_MAD;
break;
}
if (parse_vector_src_reg
(ctx, inst, vc_head, Program, (GLint *) & vp->SrcReg[a].File,
&vp->SrcReg[a].Index, &vp->SrcReg[a].Negate,
- vp->SrcReg[a].Swizzle))
+ vp->SrcReg[a].Swizzle, &vp->SrcReg[a].RelAddr))
return 1;
}
break;
- case V_GEN_SWZ:
+ case OP_ALU_SWZ:
switch (code) {
- case V_SWZ:
+ case OP_SWZ:
vp->Opcode = VP_OPCODE_SWZ;
break;
}
if (parse_src_reg
(ctx, inst, vc_head, Program, (GLint *) & vp->SrcReg[0].File,
- &vp->SrcReg[0].Index))
+ &vp->SrcReg[0].Index, &vp->SrcReg[0].RelAddr))
return 1;
parse_extended_swizzle_mask (inst, vp->SrcReg[0].Swizzle,
&vp->SrcReg[0].Negate);
}
-
-
static GLvoid
debug_variables (GLcontext * ctx, struct var_cache *vc_head,
struct arb_program *Program)
#endif
+
/**
* The main loop for parsing a fragment or vertex program
*
* \return 0 on sucess, 1 on error
*/
-
static GLint
-parse_arb_program (GLcontext * ctx, byte * inst, struct var_cache **vc_head,
+parse_arb_program (GLcontext * ctx, GLubyte * inst, struct var_cache **vc_head,
struct arb_program *Program)
{
GLint err = 0;
while (*inst != END) {
switch (*inst++) {
- /* XXX: */
+
case OPTION:
+ switch (*inst++) {
+ case ARB_PRECISION_HINT_FASTEST:
+ Program->HintPrecisionFastest = 1;
+ break;
- if (Program->type == GL_FRAGMENT_PROGRAM_ARB) {
- switch (*inst++) {
- case ARB_PRECISION_HINT_FASTEST:
- Program->HintPrecisionFastest = 1;
- break;
+ case ARB_PRECISION_HINT_NICEST:
+ Program->HintPrecisionNicest = 1;
+ break;
- case ARB_PRECISION_HINT_NICEST:
- Program->HintPrecisionNicest = 1;
- break;
+ case ARB_FOG_EXP:
+ Program->HintFogExp = 1;
+ break;
- case ARB_FOG_EXP:
- Program->HintFogExp = 1;
- break;
+ case ARB_FOG_EXP2:
+ Program->HintFogExp2 = 1;
+ break;
- case ARB_FOG_EXP2:
- Program->HintFogExp2 = 1;
- break;
+ case ARB_FOG_LINEAR:
+ Program->HintFogLinear = 1;
+ break;
- case ARB_FOG_LINEAR:
- Program->HintFogLinear = 1;
- break;
- }
- }
- else {
- switch (*inst++) {
- case ARB_POSITION_INVARIANT:
+ case ARB_POSITION_INVARIANT:
+ if (Program->type == GL_VERTEX_PROGRAM_ARB)
Program->HintPositionInvariant = 1;
- break;
- }
+ break;
}
break;
Program->Position = parse_position (&inst);
if (Program->type == GL_FRAGMENT_PROGRAM_ARB) {
+
+ /* Check the instruction count
+ * XXX: Does END count as an instruction?
+ */
+ if (Program->Base.NumInstructions+1 == MAX_NV_FRAGMENT_PROGRAM_INSTRUCTIONS) {
+ _mesa_set_program_error (ctx, Program->Position,
+ "Max instruction count exceeded!");
+ _mesa_error (ctx, GL_INVALID_OPERATION,
+ "Max instruction count exceeded!");
+ }
+
/* Realloc Program->FPInstructions */
Program->FPInstructions =
(struct fp_instruction *) _mesa_realloc (Program->FPInstructions,
}
else {
+ /* Check the instruction count
+ * XXX: Does END count as an instruction?
+ */
+ if (Program->Base.NumInstructions+1 == MAX_NV_VERTEX_PROGRAM_INSTRUCTIONS) {
+ _mesa_set_program_error (ctx, Program->Position,
+ "Max instruction count exceeded!");
+ _mesa_error (ctx, GL_INVALID_OPERATION,
+ "Max instruction count exceeded!");
+ }
+
/* Realloc Program->VPInstructions */
Program->VPInstructions =
(struct vp_instruction *) _mesa_realloc (Program->VPInstructions,
(Program->Base.NumInstructions+1)*sizeof(struct fp_instruction));
Program->FPInstructions[Program->Base.NumInstructions].Opcode = FP_OPCODE_END;
+ /* YYY Wrong Position in program, whatever, at least not random -> crash
+ Program->Position = parse_position (&inst);
+ */
+ Program->FPInstructions[Program->Base.NumInstructions].StringPos = Program->Position;
}
else {
Program->VPInstructions =
(Program->Base.NumInstructions+1)*sizeof(struct vp_instruction));
Program->VPInstructions[Program->Base.NumInstructions].Opcode = VP_OPCODE_END;
+ /* YYY Wrong Position in program, whatever, at least not random -> crash
+ Program->Position = parse_position (&inst);
+ */
+ Program->VPInstructions[Program->Base.NumInstructions].StringPos = Program->Position;
}
/* increment Program->Base.NumInstructions */
return err;
}
+
/**
* This kicks everything off.
*
*/
GLuint
_mesa_parse_arb_program (GLcontext * ctx, const GLubyte * str, GLsizei len,
- struct arb_program * Program)
+ struct arb_program * program)
{
GLint a, err, error_pos;
char error_msg[300];
GLuint parsed_len;
struct var_cache *vc_head;
dict *dt;
- byte *parsed, *inst;
+ GLubyte *parsed, *inst;
#if DEBUG_PARSING
fprintf (stderr, "Loading grammar text!\n");
#endif
- dt = grammar_load_from_text ((byte *) arb_grammar_text);
+ dt = grammar_load_from_text ((GLubyte *) arb_grammar_text);
if (!dt) {
- grammar_get_last_error ((byte *) error_msg, 300, &error_pos);
+ grammar_get_last_error ((GLubyte *) error_msg, 300, &error_pos);
_mesa_set_program_error (ctx, error_pos, error_msg);
_mesa_error (ctx, GL_INVALID_OPERATION,
"Error loading grammer rule set");
/* Syntax parse error */
if (err == 0) {
- grammar_get_last_error ((byte *) error_msg, 300, &error_pos);
+ grammar_get_last_error ((GLubyte *) error_msg, 300, &error_pos);
_mesa_set_program_error (ctx, error_pos, error_msg);
_mesa_error (ctx, GL_INVALID_OPERATION, "Parse Error");
dict_destroy (&dt);
/* Initialize the arb_program struct */
- Program->Base.NumInstructions =
- Program->Base.NumTemporaries =
- Program->Base.NumParameters =
- Program->Base.NumAttributes = Program->Base.NumAddressRegs = 0;
- Program->Parameters = _mesa_new_parameter_list ();
- Program->InputsRead = 0;
- Program->OutputsWritten = 0;
- Program->Position = 0;
- Program->MajorVersion = Program->MinorVersion = 0;
- Program->HintPrecisionFastest =
- Program->HintPrecisionNicest =
- Program->HintFogExp2 =
- Program->HintFogExp =
- Program->HintFogLinear = Program->HintPositionInvariant = 0;
+ program->Base.NumInstructions =
+ program->Base.NumTemporaries =
+ program->Base.NumParameters =
+ program->Base.NumAttributes = program->Base.NumAddressRegs = 0;
+ program->Parameters = _mesa_new_parameter_list ();
+ program->InputsRead = 0;
+ program->OutputsWritten = 0;
+ program->Position = 0;
+ program->MajorVersion = program->MinorVersion = 0;
+ program->HintPrecisionFastest =
+ program->HintPrecisionNicest =
+ program->HintFogExp2 =
+ program->HintFogExp =
+ program->HintFogLinear = program->HintPositionInvariant = 0;
for (a = 0; a < MAX_TEXTURE_IMAGE_UNITS; a++)
- Program->TexturesUsed[a] = 0;
- Program->NumAluInstructions =
- Program->NumTexInstructions =
- Program->NumTexIndirections = 0;
+ program->TexturesUsed[a] = 0;
+ program->NumAluInstructions =
+ program->NumTexInstructions =
+ program->NumTexIndirections = 0;
- Program->FPInstructions = NULL;
- Program->VPInstructions = NULL;
+ program->FPInstructions = NULL;
+ program->VPInstructions = NULL;
vc_head = NULL;
err = 0;
else {
switch (*inst++) {
case FRAGMENT_PROGRAM:
- Program->type = GL_FRAGMENT_PROGRAM_ARB;
+ program->type = GL_FRAGMENT_PROGRAM_ARB;
break;
case VERTEX_PROGRAM:
- Program->type = GL_VERTEX_PROGRAM_ARB;
+ program->type = GL_VERTEX_PROGRAM_ARB;
break;
}
- err = parse_arb_program (ctx, inst, &vc_head, Program);
+ err = parse_arb_program (ctx, inst, &vc_head, program);
#if DEBUG_PARSING
fprintf (stderr, "Symantic analysis returns %d [1 is bad!]\n", err);
#endif
}
- /*debug_variables(ctx, vc_head, Program); */
+ /*debug_variables(ctx, vc_head, program); */
/* We're done with the parsed binary array */
var_cache_destroy (&vc_head);