diff options
Diffstat (limited to 'src/mesa/shader/program_parse.y')
-rw-r--r-- | src/mesa/shader/program_parse.y | 118 |
1 files changed, 86 insertions, 32 deletions
diff --git a/src/mesa/shader/program_parse.y b/src/mesa/shader/program_parse.y index 9703e8e670..8ca6f9805b 100644 --- a/src/mesa/shader/program_parse.y +++ b/src/mesa/shader/program_parse.y @@ -66,8 +66,14 @@ static int validate_inputs(struct YYLTYPE *locp, static void init_dst_reg(struct prog_dst_register *r); +static void set_dst_reg(struct prog_dst_register *r, + gl_register_file file, GLint index); + static void init_src_reg(struct asm_src_register *r); +static void set_src_reg(struct asm_src_register *r, + gl_register_file file, GLint index); + static void asm_instruction_set_operands(struct asm_instruction *inst, const struct prog_dst_register *dst, const struct asm_src_register *src0, const struct asm_src_register *src1, const struct asm_src_register *src2); @@ -303,6 +309,8 @@ option: OPTION string ';' } + free($2); + if (!valid) { const char *const err_str = (state->mode == ARB_vertex) ? "invalid ARB vertex program option" @@ -580,9 +588,7 @@ scalarUse: srcReg scalarSuffix temp_sym.param_binding_begin = ~0; initialize_symbol_from_const(state->prog, & temp_sym, & $1); - init_src_reg(& $$); - $$.Base.File = PROGRAM_CONSTANT; - $$.Base.Index = temp_sym.param_binding_begin; + set_src_reg(& $$, PROGRAM_CONSTANT, temp_sym.param_binding_begin); } ; @@ -637,16 +643,14 @@ maskedDstReg: dstReg optionalMask optionalCcMask YYERROR; } - state->prog->OutputsWritten |= (1U << $$.Index); + state->prog->OutputsWritten |= BITFIELD64_BIT($$.Index); } } ; maskedAddrReg: addrReg addrWriteMask { - init_dst_reg(& $$); - $$.File = PROGRAM_ADDRESS; - $$.Index = 0; + set_dst_reg(& $$, PROGRAM_ADDRESS, 0); $$.WriteMask = $2.mask; } ; @@ -708,12 +712,17 @@ extSwizSel: INTEGER } | string { + char s; + if (strlen($1) > 1) { yyerror(& @1, state, "invalid extended swizzle selector"); YYERROR; } - switch ($1[0]) { + s = $1[0]; + free($1); + + switch (s) { case 'x': $$.swz = SWIZZLE_X; $$.xyzw_valid = 1; @@ -761,6 +770,8 @@ srcReg: USED_IDENTIFIER /* temporaryReg | progParamSingle */ struct asm_symbol *const s = (struct asm_symbol *) _mesa_symbol_table_find_symbol(state->st, 0, $1); + free($1); + if (s == NULL) { yyerror(& @1, state, "invalid operand variable"); YYERROR; @@ -776,16 +787,13 @@ srcReg: USED_IDENTIFIER /* temporaryReg | progParamSingle */ init_src_reg(& $$); switch (s->type) { case at_temp: - $$.Base.File = PROGRAM_TEMPORARY; - $$.Base.Index = s->temp_binding; + set_src_reg(& $$, PROGRAM_TEMPORARY, s->temp_binding); break; case at_param: - $$.Base.File = s->param_binding_type; - $$.Base.Index = s->param_binding_begin; + set_src_reg(& $$, s->param_binding_type, s->param_binding_begin); break; case at_attrib: - $$.Base.File = PROGRAM_INPUT; - $$.Base.Index = s->attrib_binding; + set_src_reg(& $$, PROGRAM_INPUT, s->attrib_binding); state->prog->InputsRead |= (1U << $$.Base.Index); if (!validate_inputs(& @1, state)) { @@ -800,9 +808,7 @@ srcReg: USED_IDENTIFIER /* temporaryReg | progParamSingle */ } | attribBinding { - init_src_reg(& $$); - $$.Base.File = PROGRAM_INPUT; - $$.Base.Index = $1; + set_src_reg(& $$, PROGRAM_INPUT, $1); state->prog->InputsRead |= (1U << $$.Base.Index); if (!validate_inputs(& @1, state)) { @@ -832,25 +838,24 @@ srcReg: USED_IDENTIFIER /* temporaryReg | progParamSingle */ } | paramSingleItemUse { - init_src_reg(& $$); - $$.Base.File = ($1.name != NULL) + gl_register_file file = ($1.name != NULL) ? $1.param_binding_type : PROGRAM_CONSTANT; - $$.Base.Index = $1.param_binding_begin; + set_src_reg(& $$, file, $1.param_binding_begin); } ; dstReg: resultBinding { - init_dst_reg(& $$); - $$.File = PROGRAM_OUTPUT; - $$.Index = $1; + set_dst_reg(& $$, PROGRAM_OUTPUT, $1); } | USED_IDENTIFIER /* temporaryReg | vertexResultReg */ { struct asm_symbol *const s = (struct asm_symbol *) _mesa_symbol_table_find_symbol(state->st, 0, $1); + free($1); + if (s == NULL) { yyerror(& @1, state, "invalid operand variable"); YYERROR; @@ -859,19 +864,15 @@ dstReg: resultBinding YYERROR; } - init_dst_reg(& $$); switch (s->type) { case at_temp: - $$.File = PROGRAM_TEMPORARY; - $$.Index = s->temp_binding; + set_dst_reg(& $$, PROGRAM_TEMPORARY, s->temp_binding); break; case at_output: - $$.File = PROGRAM_OUTPUT; - $$.Index = s->output_binding; + set_dst_reg(& $$, PROGRAM_OUTPUT, s->output_binding); break; default: - $$.File = s->param_binding_type; - $$.Index = s->param_binding_begin; + set_dst_reg(& $$, s->param_binding_type, s->param_binding_begin); break; } } @@ -882,6 +883,8 @@ progParamArray: USED_IDENTIFIER struct asm_symbol *const s = (struct asm_symbol *) _mesa_symbol_table_find_symbol(state->st, 0, $1); + free($1); + if (s == NULL) { yyerror(& @1, state, "invalid operand variable"); YYERROR; @@ -953,6 +956,8 @@ addrReg: USED_IDENTIFIER struct asm_symbol *const s = (struct asm_symbol *) _mesa_symbol_table_find_symbol(state->st, 0, $1); + free($1); + if (s == NULL) { yyerror(& @1, state, "invalid array member"); YYERROR; @@ -1091,6 +1096,7 @@ ATTRIB_statement: ATTRIB IDENTIFIER '=' attribBinding declare_variable(state, $2, at_attrib, & @2); if (s == NULL) { + free($2); YYERROR; } else { s->attrib_binding = $4; @@ -1198,6 +1204,7 @@ PARAM_singleStmt: PARAM IDENTIFIER paramSingleInit declare_variable(state, $2, at_param, & @2); if (s == NULL) { + free($2); YYERROR; } else { s->param_binding_type = $3.param_binding_type; @@ -1211,6 +1218,7 @@ PARAM_singleStmt: PARAM IDENTIFIER paramSingleInit PARAM_multipleStmt: PARAM IDENTIFIER '[' optArraySize ']' paramMultipleInit { if (($4 != 0) && ((unsigned) $4 != $6.param_binding_length)) { + free($2); yyerror(& @4, state, "parameter array size and number of bindings must match"); YYERROR; @@ -1219,6 +1227,7 @@ PARAM_multipleStmt: PARAM IDENTIFIER '[' optArraySize ']' paramMultipleInit declare_variable(state, $2, $6.type, & @2); if (s == NULL) { + free($2); YYERROR; } else { s->param_binding_type = $6.param_binding_type; @@ -1236,7 +1245,7 @@ optArraySize: } | INTEGER { - if (($1 < 1) || ((unsigned) $1 >= state->limits->MaxParameters)) { + if (($1 < 1) || ((unsigned) $1 > state->limits->MaxParameters)) { yyerror(& @1, state, "invalid parameter array size"); YYERROR; } else { @@ -1953,12 +1962,14 @@ ADDRESS_statement: ADDRESS { $<integer>$ = $1; } varNameList varNameList: varNameList ',' IDENTIFIER { if (!declare_variable(state, $3, $<integer>0, & @3)) { + free($3); YYERROR; } } | IDENTIFIER { if (!declare_variable(state, $1, $<integer>0, & @1)) { + free($1); YYERROR; } } @@ -1970,6 +1981,7 @@ OUTPUT_statement: optVarSize OUTPUT IDENTIFIER '=' resultBinding declare_variable(state, $3, at_output, & @3); if (s == NULL) { + free($3); YYERROR; } else { s->output_binding = $5; @@ -2146,11 +2158,16 @@ ALIAS_statement: ALIAS IDENTIFIER '=' USED_IDENTIFIER struct asm_symbol *target = (struct asm_symbol *) _mesa_symbol_table_find_symbol(state->st, 0, $4); + free($4); if (exist != NULL) { - yyerror(& @2, state, "redeclared identifier"); + char m[1000]; + _mesa_snprintf(m, sizeof(m), "redeclared identifier: %s", $2); + free($2); + yyerror(& @2, state, m); YYERROR; } else if (target == NULL) { + free($2); yyerror(& @4, state, "undefined variable binding in ALIAS statement"); YYERROR; @@ -2263,6 +2280,26 @@ init_dst_reg(struct prog_dst_register *r) } +/** Like init_dst_reg() but set the File and Index fields. */ +void +set_dst_reg(struct prog_dst_register *r, gl_register_file file, GLint index) +{ + const GLint maxIndex = 1 << INST_INDEX_BITS; + const GLint minIndex = 0; + ASSERT(index >= minIndex); + ASSERT(index <= maxIndex); + 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; +} + + void init_src_reg(struct asm_src_register *r) { @@ -2273,6 +2310,23 @@ init_src_reg(struct asm_src_register *r) } +/** Like init_src_reg() but set the File and Index fields. */ +void +set_src_reg(struct asm_src_register *r, gl_register_file file, GLint index) +{ + const GLint maxIndex = (1 << INST_INDEX_BITS) - 1; + const GLint minIndex = -(1 << INST_INDEX_BITS); + ASSERT(index >= minIndex); + ASSERT(index <= maxIndex); + ASSERT(file < PROGRAM_FILE_MAX); + memset(r, 0, sizeof(*r)); + r->Base.File = file; + r->Base.Index = index; + r->Base.Swizzle = SWIZZLE_NOOP; + r->Symbol = NULL; +} + + /** * Validate the set of inputs used by a program * |