* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*/
+
+#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
+#include "main/errors.h"
#include "main/mtypes.h"
-#include "main/imports.h"
+#include "util/imports.h"
#include "program/program.h"
#include "program/prog_parameter.h"
#include "program/prog_parameter_layout.h"
#include "program/symbol_table.h"
#include "program/program_parser.h"
+#include "util/u_math.h"
+
extern void *yy_scan_string(char *);
extern void yy_delete_buffer(void *);
char *name, enum asm_type t, struct YYLTYPE *locp);
static int add_state_reference(struct gl_program_parameter_list *param_list,
- const gl_state_index tokens[STATE_LENGTH]);
+ const gl_state_index16 tokens[STATE_LENGTH]);
static int initialize_symbol_from_state(struct gl_program *prog,
- struct asm_symbol *param_var, const gl_state_index tokens[STATE_LENGTH]);
+ struct asm_symbol *param_var, const gl_state_index16 tokens[STATE_LENGTH]);
static int initialize_symbol_from_param(struct gl_program *prog,
- struct asm_symbol *param_var, const gl_state_index tokens[STATE_LENGTH]);
+ struct asm_symbol *param_var, const gl_state_index16 tokens[STATE_LENGTH]);
static int initialize_symbol_from_const(struct gl_program *prog,
struct asm_symbol *param_var, const struct asm_vector *vec,
const struct prog_dst_register *dst, const struct asm_src_register *src0,
const struct asm_src_register *src1, const struct asm_src_register *src2);
-static struct asm_instruction *asm_instruction_ctor(gl_inst_opcode op,
+static struct asm_instruction *asm_instruction_ctor(enum prog_opcode op,
const struct prog_dst_register *dst, const struct asm_src_register *src0,
const struct asm_src_register *src1, const struct asm_src_register *src2);
#define YYLLOC_DEFAULT(Current, Rhs, N) \
do { \
- if (YYID(N)) { \
+ if (N) { \
(Current).first_line = YYRHSLOC(Rhs, 1).first_line; \
(Current).first_column = YYRHSLOC(Rhs, 1).first_column; \
(Current).position = YYRHSLOC(Rhs, 1).position; \
(Current).position = YYRHSLOC(Rhs, 0).position \
+ (Current).first_column; \
} \
- } while(YYID(0))
-
-#define YYLEX_PARAM state->scanner
+ } while(0)
%}
%pure-parser
%locations
+%lex-param { struct asm_parser_state *state }
%parse-param { struct asm_parser_state *state }
%error-verbose
-%lex-param { void *scanner }
%union {
struct asm_instruction *inst;
unsigned attrib;
int integer;
float real;
- gl_state_index state[STATE_LENGTH];
+ gl_state_index16 state[STATE_LENGTH];
int negate;
struct asm_vector vector;
- gl_inst_opcode opcode;
+ enum prog_opcode opcode;
struct {
unsigned swz;
%token TEX_SHADOW1D TEX_SHADOW2D TEX_SHADOWRECT
%token TEX_ARRAY1D TEX_ARRAY2D TEX_ARRAYSHADOW1D TEX_ARRAYSHADOW2D
%token VERTEX VTXATTRIB
-%token WEIGHT
%token <string> IDENTIFIER USED_IDENTIFIER
%type <string> string
%type <sym> addrReg
%type <swiz_mask> addrComponent addrWriteMask
-%type <dst_reg> ccMaskRule ccTest ccMaskRule2 ccTest2 optionalCcMask
-
%type <result> resultBinding resultColBinding
%type <integer> optFaceType optColorType
%type <integer> optResultFaceType optResultColorType
%type <negate> optionalSign
%{
-extern int yylex(YYSTYPE *yylval_param, YYLTYPE *yylloc_param,
- void *yyscanner);
+extern int
+_mesa_program_lexer_lex(YYSTYPE *yylval_param, YYLTYPE *yylloc_param,
+ void *yyscanner);
+
+static int
+yylex(YYSTYPE *yylval_param, YYLTYPE *yylloc_param,
+ struct asm_parser_state *state)
+{
+ return _mesa_program_lexer_lex(yylval_param, yylloc_param, state->scanner);
+}
%}
%%
state->inst_tail = $1;
$1->next = NULL;
- state->prog->NumInstructions++;
+ state->prog->arb.NumInstructions++;
}
}
| namingStatement ';'
instruction: ALU_instruction
{
$$ = $1;
- state->prog->NumAluInstructions++;
+ state->prog->arb.NumAluInstructions++;
}
| TexInstruction
{
$$ = $1;
- state->prog->NumTexInstructions++;
+ state->prog->arb.NumTexInstructions++;
}
;
$$ = asm_instruction_ctor(OPCODE_KIL, NULL, & $2, NULL, NULL);
state->fragment.UsesKill = 1;
}
- | KIL ccTest
- {
- $$ = asm_instruction_ctor(OPCODE_KIL_NV, NULL, NULL, NULL, NULL);
- $$->Base.DstReg.CondMask = $2.CondMask;
- $$->Base.DstReg.CondSwizzle = $2.CondSwizzle;
- $$->Base.DstReg.CondSrc = $2.CondSrc;
- state->fragment.UsesKill = 1;
- }
;
TXD_instruction: TXD_OP maskedDstReg ',' swizzleSrcReg ',' swizzleSrcReg ',' swizzleSrcReg ',' texImageUnit ',' texTarget
$$.Base.Negate = ~$$.Base.Negate;
}
}
- | optionalSign '|' scalarUse '|'
- {
- $$ = $3;
-
- if (!state->option.NV_fragment) {
- yyerror(& @2, state, "unexpected character '|'");
- YYERROR;
- }
-
- if ($1) {
- $$.Base.Negate = ~$$.Base.Negate;
- }
-
- $$.Base.Abs = 1;
- }
;
scalarUse: srcReg scalarSuffix
$$.Base.Swizzle = _mesa_combine_swizzles($$.Base.Swizzle,
$2.swizzle);
}
- | paramConstScalarUse
- {
- struct asm_symbol temp_sym;
-
- if (!state->option.NV_fragment) {
- yyerror(& @1, state, "expected scalar suffix");
- YYERROR;
- }
-
- memset(& temp_sym, 0, sizeof(temp_sym));
- temp_sym.param_binding_begin = ~0;
- initialize_symbol_from_const(state->prog, & temp_sym, & $1, GL_TRUE);
-
- set_src_reg_swz(& $$, PROGRAM_CONSTANT,
- temp_sym.param_binding_begin,
- temp_sym.param_binding_swizzle);
- }
;
swizzleSrcReg: optionalSign srcReg swizzleSuffix
$$.Base.Swizzle = _mesa_combine_swizzles($$.Base.Swizzle,
$3.swizzle);
}
- | optionalSign '|' srcReg swizzleSuffix '|'
- {
- $$ = $3;
-
- if (!state->option.NV_fragment) {
- yyerror(& @2, state, "unexpected character '|'");
- YYERROR;
- }
-
- if ($1) {
- $$.Base.Negate = ~$$.Base.Negate;
- }
-
- $$.Base.Abs = 1;
- $$.Base.Swizzle = _mesa_combine_swizzles($$.Base.Swizzle,
- $4.swizzle);
- }
-
;
-maskedDstReg: dstReg optionalMask optionalCcMask
+maskedDstReg: dstReg optionalMask
{
$$ = $1;
$$.WriteMask = $2.mask;
- $$.CondMask = $3.CondMask;
- $$.CondSwizzle = $3.CondSwizzle;
- $$.CondSrc = $3.CondSrc;
if ($$.File == PROGRAM_OUTPUT) {
/* Technically speaking, this should check that it is in
* set in fragment program mode, so it is somewhat irrelevant.
*/
if (state->option.PositionInvariant
- && ($$.Index == VERT_RESULT_HPOS)) {
+ && ($$.Index == VARYING_SLOT_POS)) {
yyerror(& @1, state, "position-invariant programs cannot "
"write position");
YYERROR;
}
- state->prog->OutputsWritten |= BITFIELD64_BIT($$.Index);
+ state->prog->info.outputs_written |= BITFIELD64_BIT($$.Index);
}
}
;
}
$$.swz = ($1 == 0) ? SWIZZLE_ZERO : SWIZZLE_ONE;
+ $$.negate = 0;
/* 0 and 1 are valid for both RGBA swizzle names and XYZW
* swizzle names.
s = $1[0];
free($1);
+ $$.rgba_valid = 0;
+ $$.xyzw_valid = 0;
+ $$.negate = 0;
+
switch (s) {
case 'x':
$$.swz = SWIZZLE_X;
srcReg: USED_IDENTIFIER /* temporaryReg | progParamSingle */
{
struct asm_symbol *const s = (struct asm_symbol *)
- _mesa_symbol_table_find_symbol(state->st, 0, $1);
+ _mesa_symbol_table_find_symbol(state->st, $1);
free($1);
break;
case at_attrib:
set_src_reg(& $$, PROGRAM_INPUT, s->attrib_binding);
- state->prog->InputsRead |= (1U << $$.Base.Index);
+ state->prog->info.inputs_read |= BITFIELD64_BIT($$.Base.Index);
if (!validate_inputs(& @1, state)) {
YYERROR;
| attribBinding
{
set_src_reg(& $$, PROGRAM_INPUT, $1);
- state->prog->InputsRead |= (1U << $$.Base.Index);
+ state->prog->info.inputs_read |= BITFIELD64_BIT($$.Base.Index);
if (!validate_inputs(& @1, state)) {
YYERROR;
$$.Base.File = $1->param_binding_type;
if ($3.Base.RelAddr) {
+ state->prog->arb.IndirectRegisterFiles |= (1 << $$.Base.File);
$1->param_accessed_indirectly = 1;
$$.Base.RelAddr = 1;
| USED_IDENTIFIER /* temporaryReg | vertexResultReg */
{
struct asm_symbol *const s = (struct asm_symbol *)
- _mesa_symbol_table_find_symbol(state->st, 0, $1);
+ _mesa_symbol_table_find_symbol(state->st, $1);
free($1);
progParamArray: USED_IDENTIFIER
{
struct asm_symbol *const s = (struct asm_symbol *)
- _mesa_symbol_table_find_symbol(state->st, 0, $1);
+ _mesa_symbol_table_find_symbol(state->st, $1);
free($1);
addrRegPosOffset: INTEGER
{
- if (($1 < 0) || ($1 > 63)) {
+ if (($1 < 0) || ($1 > (state->limits->MaxAddressOffset - 1))) {
char s[100];
_mesa_snprintf(s, sizeof(s),
"relative address offset too large (%d)", $1);
addrRegNegOffset: INTEGER
{
- if (($1 < 0) || ($1 > 64)) {
+ if (($1 < 0) || ($1 > state->limits->MaxAddressOffset)) {
char s[100];
_mesa_snprintf(s, sizeof(s),
"relative address offset too large (%d)", $1);
addrReg: USED_IDENTIFIER
{
struct asm_symbol *const s = (struct asm_symbol *)
- _mesa_symbol_table_find_symbol(state->st, 0, $1);
+ _mesa_symbol_table_find_symbol(state->st, $1);
free($1);
| { $$.swizzle = SWIZZLE_NOOP; $$.mask = WRITEMASK_XYZW; }
;
-optionalCcMask: '(' ccTest ')'
- {
- $$ = $2;
- }
- | '(' ccTest2 ')'
- {
- $$ = $2;
- }
- |
- {
- $$.CondMask = COND_TR;
- $$.CondSwizzle = SWIZZLE_NOOP;
- $$.CondSrc = 0;
- }
- ;
-
-ccTest: ccMaskRule swizzleSuffix
- {
- $$ = $1;
- $$.CondSwizzle = $2.swizzle;
- }
- ;
-
-ccTest2: ccMaskRule2 swizzleSuffix
- {
- $$ = $1;
- $$.CondSwizzle = $2.swizzle;
- }
- ;
-
-ccMaskRule: IDENTIFIER
- {
- const int cond = _mesa_parse_cc($1);
- if ((cond == 0) || ($1[2] != '\0')) {
- char *const err_str =
- make_error_string("invalid condition code \"%s\"", $1);
-
- yyerror(& @1, state, (err_str != NULL)
- ? err_str : "invalid condition code");
-
- if (err_str != NULL) {
- free(err_str);
- }
-
- YYERROR;
- }
-
- $$.CondMask = cond;
- $$.CondSwizzle = SWIZZLE_NOOP;
- $$.CondSrc = 0;
- }
- ;
-
-ccMaskRule2: USED_IDENTIFIER
- {
- const int cond = _mesa_parse_cc($1);
- if ((cond == 0) || ($1[2] != '\0')) {
- char *const err_str =
- make_error_string("invalid condition code \"%s\"", $1);
-
- yyerror(& @1, state, (err_str != NULL)
- ? err_str : "invalid condition code");
-
- if (err_str != NULL) {
- free(err_str);
- }
-
- YYERROR;
- }
-
- $$.CondMask = cond;
- $$.CondSwizzle = SWIZZLE_NOOP;
- $$.CondSrc = 0;
- }
- ;
-
namingStatement: ATTRIB_statement
| PARAM_statement
| TEMP_statement
YYERROR;
} else {
s->attrib_binding = $4;
- state->InputsBound |= (1U << s->attrib_binding);
+ state->InputsBound |= BITFIELD64_BIT(s->attrib_binding);
if (!validate_inputs(& @4, state)) {
YYERROR;
{
$$ = VERT_ATTRIB_POS;
}
- | WEIGHT vtxOptWeightNum
- {
- $$ = VERT_ATTRIB_WEIGHT;
- }
| NORMAL
{
$$ = VERT_ATTRIB_NORMAL;
}
| COLOR optColorType
{
- if (!state->ctx->Extensions.EXT_secondary_color) {
- yyerror(& @2, state, "GL_EXT_secondary_color not supported");
- YYERROR;
- }
-
$$ = VERT_ATTRIB_COLOR0 + $2;
}
| FOGCOORD
{
- if (!state->ctx->Extensions.EXT_fog_coord) {
- yyerror(& @1, state, "GL_EXT_fog_coord not supported");
- YYERROR;
- }
-
$$ = VERT_ATTRIB_FOG;
}
| TEXCOORD optTexCoordUnitNum
}
;
-vtxOptWeightNum: | '[' vtxWeightNum ']';
vtxWeightNum: INTEGER;
fragAttribItem: POSITION
{
- $$ = FRAG_ATTRIB_WPOS;
+ $$ = VARYING_SLOT_POS;
}
| COLOR optColorType
{
- $$ = FRAG_ATTRIB_COL0 + $2;
+ $$ = VARYING_SLOT_COL0 + $2;
}
| FOGCOORD
{
- $$ = FRAG_ATTRIB_FOGC;
+ $$ = VARYING_SLOT_FOGC;
}
| TEXCOORD optTexCoordUnitNum
{
- $$ = FRAG_ATTRIB_TEX0 + $2;
+ $$ = VARYING_SLOT_TEX0 + $2;
}
;
| INTEGER
{
if (($1 < 1) || ((unsigned) $1 > state->limits->MaxParameters)) {
- yyerror(& @1, state, "invalid parameter array size");
+ char msg[100];
+ _mesa_snprintf(msg, sizeof(msg),
+ "invalid parameter array size (size=%d max=%u)",
+ $1, state->limits->MaxParameters);
+ yyerror(& @1, state, msg);
YYERROR;
} else {
$$ = $1;
paramConstScalarDecl: signedFloatConstant
{
$$.count = 4;
- $$.data[0] = $1;
- $$.data[1] = $1;
- $$.data[2] = $1;
- $$.data[3] = $1;
+ $$.data[0].f = $1;
+ $$.data[1].f = $1;
+ $$.data[2].f = $1;
+ $$.data[3].f = $1;
}
;
paramConstScalarUse: REAL
{
$$.count = 1;
- $$.data[0] = $1;
- $$.data[1] = $1;
- $$.data[2] = $1;
- $$.data[3] = $1;
+ $$.data[0].f = $1;
+ $$.data[1].f = $1;
+ $$.data[2].f = $1;
+ $$.data[3].f = $1;
}
| INTEGER
{
$$.count = 1;
- $$.data[0] = (float) $1;
- $$.data[1] = (float) $1;
- $$.data[2] = (float) $1;
- $$.data[3] = (float) $1;
+ $$.data[0].f = (float) $1;
+ $$.data[1].f = (float) $1;
+ $$.data[2].f = (float) $1;
+ $$.data[3].f = (float) $1;
}
;
paramConstVector: '{' signedFloatConstant '}'
{
$$.count = 4;
- $$.data[0] = $2;
- $$.data[1] = 0.0f;
- $$.data[2] = 0.0f;
- $$.data[3] = 1.0f;
+ $$.data[0].f = $2;
+ $$.data[1].f = 0.0f;
+ $$.data[2].f = 0.0f;
+ $$.data[3].f = 1.0f;
}
| '{' signedFloatConstant ',' signedFloatConstant '}'
{
$$.count = 4;
- $$.data[0] = $2;
- $$.data[1] = $4;
- $$.data[2] = 0.0f;
- $$.data[3] = 1.0f;
+ $$.data[0].f = $2;
+ $$.data[1].f = $4;
+ $$.data[2].f = 0.0f;
+ $$.data[3].f = 1.0f;
}
| '{' signedFloatConstant ',' signedFloatConstant ','
signedFloatConstant '}'
{
$$.count = 4;
- $$.data[0] = $2;
- $$.data[1] = $4;
- $$.data[2] = $6;
- $$.data[3] = 1.0f;
+ $$.data[0].f = $2;
+ $$.data[1].f = $4;
+ $$.data[2].f = $6;
+ $$.data[3].f = 1.0f;
}
| '{' signedFloatConstant ',' signedFloatConstant ','
signedFloatConstant ',' signedFloatConstant '}'
{
$$.count = 4;
- $$.data[0] = $2;
- $$.data[1] = $4;
- $$.data[2] = $6;
- $$.data[3] = $8;
+ $$.data[0].f = $2;
+ $$.data[1].f = $4;
+ $$.data[2].f = $6;
+ $$.data[3].f = $8;
}
;
| { $$ = FALSE; }
;
-TEMP_statement: optVarSize TEMP { $<integer>$ = $2; } varNameList
- ;
-
-optVarSize: string
- {
- /* NV_fragment_program_option defines the size qualifiers in a
- * fairly broken way. "SHORT" or "LONG" can optionally be used
- * before TEMP or OUTPUT. However, neither is a reserved word!
- * This means that we have to parse it as an identifier, then check
- * to make sure it's one of the valid values. *sigh*
- *
- * In addition, the grammar in the extension spec does *not* allow
- * the size specifier to be optional, but all known implementations
- * do.
- */
- if (!state->option.NV_fragment) {
- yyerror(& @1, state, "unexpected IDENTIFIER");
- YYERROR;
- }
-
- if (strcmp("SHORT", $1) == 0) {
- } else if (strcmp("LONG", $1) == 0) {
- } else {
- char *const err_str =
- make_error_string("invalid storage size specifier \"%s\"",
- $1);
-
- yyerror(& @1, state, (err_str != NULL)
- ? err_str : "invalid storage size specifier");
-
- if (err_str != NULL) {
- free(err_str);
- }
-
- YYERROR;
- }
- }
- |
- {
- }
+TEMP_statement: TEMP { $<integer>$ = $1; } varNameList
;
ADDRESS_statement: ADDRESS { $<integer>$ = $1; } varNameList
}
;
-OUTPUT_statement: optVarSize OUTPUT IDENTIFIER '=' resultBinding
+OUTPUT_statement: OUTPUT IDENTIFIER '=' resultBinding
{
struct asm_symbol *const s =
- declare_variable(state, $3, at_output, & @3);
+ declare_variable(state, $2, at_output, & @2);
if (s == NULL) {
- free($3);
+ free($2);
YYERROR;
} else {
- s->output_binding = $5;
+ s->output_binding = $4;
}
}
;
resultBinding: RESULT POSITION
{
if (state->mode == ARB_vertex) {
- $$ = VERT_RESULT_HPOS;
+ $$ = VARYING_SLOT_POS;
} else {
yyerror(& @2, state, "invalid program result name");
YYERROR;
| RESULT FOGCOORD
{
if (state->mode == ARB_vertex) {
- $$ = VERT_RESULT_FOGC;
+ $$ = VARYING_SLOT_FOGC;
} else {
yyerror(& @2, state, "invalid program result name");
YYERROR;
| RESULT POINTSIZE
{
if (state->mode == ARB_vertex) {
- $$ = VERT_RESULT_PSIZ;
+ $$ = VARYING_SLOT_PSIZ;
} else {
yyerror(& @2, state, "invalid program result name");
YYERROR;
| RESULT TEXCOORD optTexCoordUnitNum
{
if (state->mode == ARB_vertex) {
- $$ = VERT_RESULT_TEX0 + $3;
+ $$ = VARYING_SLOT_TEX0 + $3;
} else {
yyerror(& @2, state, "invalid program result name");
YYERROR;
optResultFaceType:
{
- $$ = (state->mode == ARB_vertex)
- ? VERT_RESULT_COL0
- : FRAG_RESULT_COLOR;
+ if (state->mode == ARB_vertex) {
+ $$ = VARYING_SLOT_COL0;
+ } else {
+ if (state->option.DrawBuffers)
+ $$ = FRAG_RESULT_DATA0;
+ else
+ $$ = FRAG_RESULT_COLOR;
+ }
+ }
+ | '[' INTEGER ']'
+ {
+ if (state->mode == ARB_vertex) {
+ yyerror(& @1, state, "invalid program result name");
+ YYERROR;
+ } else {
+ if (!state->option.DrawBuffers) {
+ /* From the ARB_draw_buffers spec (same text exists
+ * for ATI_draw_buffers):
+ *
+ * If this option is not specified, a fragment
+ * program that attempts to bind
+ * "result.color[n]" will fail to load, and only
+ * "result.color" will be allowed.
+ */
+ yyerror(& @1, state,
+ "result.color[] used without "
+ "`OPTION ARB_draw_buffers' or "
+ "`OPTION ATI_draw_buffers'");
+ YYERROR;
+ } else if ($2 >= state->MaxDrawBuffers) {
+ yyerror(& @1, state,
+ "result.color[] exceeds MAX_DRAW_BUFFERS_ARB");
+ YYERROR;
+ }
+ $$ = FRAG_RESULT_DATA0 + $2;
+ }
}
| FRONT
{
if (state->mode == ARB_vertex) {
- $$ = VERT_RESULT_COL0;
+ $$ = VARYING_SLOT_COL0;
} else {
yyerror(& @1, state, "invalid program result name");
YYERROR;
| BACK
{
if (state->mode == ARB_vertex) {
- $$ = VERT_RESULT_BFC0;
+ $$ = VARYING_SLOT_BFC0;
} else {
yyerror(& @1, state, "invalid program result name");
YYERROR;
ALIAS_statement: ALIAS IDENTIFIER '=' USED_IDENTIFIER
{
struct asm_symbol *exist = (struct asm_symbol *)
- _mesa_symbol_table_find_symbol(state->st, 0, $2);
+ _mesa_symbol_table_find_symbol(state->st, $2);
struct asm_symbol *target = (struct asm_symbol *)
- _mesa_symbol_table_find_symbol(state->st, 0, $4);
+ _mesa_symbol_table_find_symbol(state->st, $4);
free($4);
"undefined variable binding in ALIAS statement");
YYERROR;
} else {
- _mesa_symbol_table_add_symbol(state->st, 0, $2, target);
+ _mesa_symbol_table_add_symbol(state->st, $2, target);
}
}
;
inst->Base.DstReg = *dst;
}
- /* The only instruction that doesn't have any source registers is the
- * condition-code based KIL instruction added by NV_fragment_program_option.
- */
if (src0 != NULL) {
inst->Base.SrcReg[0] = src0->Base;
inst->SrcReg[0] = *src0;
struct asm_instruction *
-asm_instruction_ctor(gl_inst_opcode op,
+asm_instruction_ctor(enum prog_opcode op,
const struct prog_dst_register *dst,
const struct asm_src_register *src0,
const struct asm_src_register *src1,
if (inst) {
_mesa_init_instructions(& inst->Base, 1);
inst->Base.Opcode = base->Opcode;
- inst->Base.CondUpdate = base->CondUpdate;
- inst->Base.CondDst = base->CondDst;
- inst->Base.SaturateMode = base->SaturateMode;
- inst->Base.Precision = base->Precision;
+ inst->Base.Saturate = base->Saturate;
asm_instruction_set_operands(inst, dst, src0, src1, src2);
}
memset(r, 0, sizeof(*r));
r->File = PROGRAM_UNDEFINED;
r->WriteMask = WRITEMASK_XYZW;
- r->CondMask = COND_TR;
- r->CondSwizzle = SWIZZLE_NOOP;
}
{
const GLint maxIndex = 1 << INST_INDEX_BITS;
const GLint minIndex = 0;
- ASSERT(index >= minIndex);
+ assert(index >= minIndex);
(void) minIndex;
- ASSERT(index <= maxIndex);
+ assert(index <= maxIndex);
(void) maxIndex;
- ASSERT(file == PROGRAM_TEMPORARY ||
+ assert(file == PROGRAM_TEMPORARY ||
file == PROGRAM_ADDRESS ||
file == PROGRAM_OUTPUT);
memset(r, 0, sizeof(*r));
r->File = file;
r->Index = index;
r->WriteMask = WRITEMASK_XYZW;
- r->CondMask = COND_TR;
- r->CondSwizzle = SWIZZLE_NOOP;
}
{
const GLint maxIndex = (1 << INST_INDEX_BITS) - 1;
const GLint minIndex = -(1 << INST_INDEX_BITS);
- ASSERT(file < PROGRAM_FILE_MAX);
- ASSERT(index >= minIndex);
+ assert(file < PROGRAM_FILE_MAX);
+ assert(index >= minIndex);
(void) minIndex;
- ASSERT(index <= maxIndex);
+ assert(index <= maxIndex);
(void) maxIndex;
memset(r, 0, sizeof(*r));
r->Base.File = file;
int
validate_inputs(struct YYLTYPE *locp, struct asm_parser_state *state)
{
- const int inputs = state->prog->InputsRead | state->InputsBound;
+ const GLbitfield64 inputs = state->prog->info.inputs_read | state->InputsBound;
+ GLbitfield ff_inputs = 0;
- if (((inputs & 0x0ffff) & (inputs >> 16)) != 0) {
+ /* Since Mesa internal attribute indices are different from
+ * how NV_vertex_program defines attribute aliasing, we have to construct
+ * a separate usage mask based on how the aliasing is defined.
+ *
+ * Note that attribute aliasing is optional if NV_vertex_program is
+ * unsupported.
+ */
+ if (inputs & VERT_BIT_POS)
+ ff_inputs |= 1 << 0;
+ if (inputs & VERT_BIT_NORMAL)
+ ff_inputs |= 1 << 2;
+ if (inputs & VERT_BIT_COLOR0)
+ ff_inputs |= 1 << 3;
+ if (inputs & VERT_BIT_COLOR1)
+ ff_inputs |= 1 << 4;
+ if (inputs & VERT_BIT_FOG)
+ ff_inputs |= 1 << 5;
+
+ ff_inputs |= ((inputs & VERT_BIT_TEX_ALL) >> VERT_ATTRIB_TEX0) << 8;
+
+ if ((ff_inputs & (inputs >> VERT_ATTRIB_GENERIC0)) != 0) {
yyerror(locp, state, "illegal use of generic attribute and name attribute");
return 0;
}
{
struct asm_symbol *s = NULL;
struct asm_symbol *exist = (struct asm_symbol *)
- _mesa_symbol_table_find_symbol(state->st, 0, name);
+ _mesa_symbol_table_find_symbol(state->st, name);
if (exist != NULL) {
switch (t) {
case at_temp:
- if (state->prog->NumTemporaries >= state->limits->MaxTemps) {
+ if (state->prog->arb.NumTemporaries >= state->limits->MaxTemps) {
yyerror(locp, state, "too many temporaries declared");
free(s);
return NULL;
}
- s->temp_binding = state->prog->NumTemporaries;
- state->prog->NumTemporaries++;
+ s->temp_binding = state->prog->arb.NumTemporaries;
+ state->prog->arb.NumTemporaries++;
break;
case at_address:
- if (state->prog->NumAddressRegs >= state->limits->MaxAddressRegs) {
+ if (state->prog->arb.NumAddressRegs >=
+ state->limits->MaxAddressRegs) {
yyerror(locp, state, "too many address registers declared");
free(s);
return NULL;
/* FINISHME: Add support for multiple address registers.
*/
- state->prog->NumAddressRegs++;
+ state->prog->arb.NumAddressRegs++;
break;
default:
break;
}
- _mesa_symbol_table_add_symbol(state->st, 0, s->name, s);
+ _mesa_symbol_table_add_symbol(state->st, s->name, s);
s->next = state->sym;
state->sym = s;
}
int add_state_reference(struct gl_program_parameter_list *param_list,
- const gl_state_index tokens[STATE_LENGTH])
+ const gl_state_index16 tokens[STATE_LENGTH])
{
const GLuint size = 4; /* XXX fix */
char *name;
name = _mesa_program_state_string(tokens);
index = _mesa_add_parameter(param_list, PROGRAM_STATE_VAR, name,
- size, GL_NONE, NULL, tokens, 0x0);
+ size, GL_NONE, NULL, tokens, true);
param_list->StateFlags |= _mesa_program_state_flags(tokens);
/* free name string here since we duplicated it in add_parameter() */
int
initialize_symbol_from_state(struct gl_program *prog,
struct asm_symbol *param_var,
- const gl_state_index tokens[STATE_LENGTH])
+ const gl_state_index16 tokens[STATE_LENGTH])
{
int idx = -1;
- gl_state_index state_tokens[STATE_LENGTH];
+ gl_state_index16 state_tokens[STATE_LENGTH];
memcpy(state_tokens, tokens, sizeof(state_tokens));
int
initialize_symbol_from_param(struct gl_program *prog,
struct asm_symbol *param_var,
- const gl_state_index tokens[STATE_LENGTH])
+ const gl_state_index16 tokens[STATE_LENGTH])
{
int idx = -1;
- gl_state_index state_tokens[STATE_LENGTH];
+ gl_state_index16 state_tokens[STATE_LENGTH];
memcpy(state_tokens, tokens, sizeof(state_tokens));
err_str = make_error_string("glProgramStringARB(%s)\n", s);
if (err_str) {
- _mesa_error(state->ctx, GL_INVALID_OPERATION, err_str);
+ _mesa_error(state->ctx, GL_INVALID_OPERATION, "%s", err_str);
free(err_str);
}
GLboolean
-_mesa_parse_arb_program(GLcontext *ctx, GLenum target, const GLubyte *str,
+_mesa_parse_arb_program(struct gl_context *ctx, GLenum target, const GLubyte *str,
GLsizei len, struct asm_parser_state *state)
{
struct asm_instruction *inst;
/* Make a copy of the program string and force it to be NUL-terminated.
*/
- strz = (GLubyte *) malloc(len + 1);
+ strz = (GLubyte *) ralloc_size(state->mem_ctx, len + 1);
if (strz == NULL) {
+ if (state->prog->Parameters) {
+ _mesa_free_parameter_list(state->prog->Parameters);
+ state->prog->Parameters = NULL;
+ }
_mesa_error(ctx, GL_OUT_OF_MEMORY, "glProgramStringARB");
return GL_FALSE;
}
state->st = _mesa_symbol_table_ctor();
state->limits = (target == GL_VERTEX_PROGRAM_ARB)
- ? & ctx->Const.VertexProgram
- : & ctx->Const.FragmentProgram;
+ ? & ctx->Const.Program[MESA_SHADER_VERTEX]
+ : & ctx->Const.Program[MESA_SHADER_FRAGMENT];
- state->MaxTextureImageUnits = ctx->Const.MaxTextureImageUnits;
+ state->MaxTextureImageUnits = ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxTextureImageUnits;
state->MaxTextureCoordUnits = ctx->Const.MaxTextureCoordUnits;
state->MaxTextureUnits = ctx->Const.MaxTextureUnits;
state->MaxClipPlanes = ctx->Const.MaxClipPlanes;
state->MaxLights = ctx->Const.MaxLights;
state->MaxProgramMatrices = ctx->Const.MaxProgramMatrices;
+ state->MaxDrawBuffers = ctx->Const.MaxDrawBuffers;
state->state_param_enum = (target == GL_VERTEX_PROGRAM_ARB)
? STATE_VERTEX_PROGRAM : STATE_FRAGMENT_PROGRAM;
/* Add one instruction to store the "END" instruction.
*/
- state->prog->Instructions =
- _mesa_alloc_instructions(state->prog->NumInstructions + 1);
+ state->prog->arb.Instructions =
+ rzalloc_array(state->mem_ctx, struct prog_instruction,
+ state->prog->arb.NumInstructions + 1);
+
+ if (state->prog->arb.Instructions == NULL) {
+ goto error;
+ }
+
inst = state->inst_head;
- for (i = 0; i < state->prog->NumInstructions; i++) {
+ for (i = 0; i < state->prog->arb.NumInstructions; i++) {
struct asm_instruction *const temp = inst->next;
- state->prog->Instructions[i] = inst->Base;
+ state->prog->arb.Instructions[i] = inst->Base;
inst = temp;
}
/* Finally, tag on an OPCODE_END instruction */
{
- const GLuint numInst = state->prog->NumInstructions;
- _mesa_init_instructions(state->prog->Instructions + numInst, 1);
- state->prog->Instructions[numInst].Opcode = OPCODE_END;
+ const GLuint numInst = state->prog->arb.NumInstructions;
+ _mesa_init_instructions(state->prog->arb.Instructions + numInst, 1);
+ state->prog->arb.Instructions[numInst].Opcode = OPCODE_END;
}
- state->prog->NumInstructions++;
+ state->prog->arb.NumInstructions++;
- state->prog->NumParameters = state->prog->Parameters->NumParameters;
- state->prog->NumAttributes = _mesa_bitcount(state->prog->InputsRead);
+ state->prog->arb.NumParameters = state->prog->Parameters->NumParameters;
+ state->prog->arb.NumAttributes =
+ util_bitcount64(state->prog->info.inputs_read);
/*
* Initialize native counts to logical counts. The device driver may
* change them if program is translated into a hardware program.
*/
- state->prog->NumNativeInstructions = state->prog->NumInstructions;
- state->prog->NumNativeTemporaries = state->prog->NumTemporaries;
- state->prog->NumNativeParameters = state->prog->NumParameters;
- state->prog->NumNativeAttributes = state->prog->NumAttributes;
- state->prog->NumNativeAddressRegs = state->prog->NumAddressRegs;
+ state->prog->arb.NumNativeInstructions = state->prog->arb.NumInstructions;
+ state->prog->arb.NumNativeTemporaries = state->prog->arb.NumTemporaries;
+ state->prog->arb.NumNativeParameters = state->prog->arb.NumParameters;
+ state->prog->arb.NumNativeAttributes = state->prog->arb.NumAttributes;
+ state->prog->arb.NumNativeAddressRegs = state->prog->arb.NumAddressRegs;
result = GL_TRUE;
_mesa_symbol_table_dtor(state->st);
state->st = NULL;
+ if (result != GL_TRUE) {
+ if (state->prog->Parameters) {
+ _mesa_free_parameter_list(state->prog->Parameters);
+ state->prog->Parameters = NULL;
+ }
+ ralloc_free(state->prog->String);
+ state->prog->String = NULL;
+ }
+
return result;
}