diff options
Diffstat (limited to 'src/mesa/shader/program_parse.y')
-rw-r--r-- | src/mesa/shader/program_parse.y | 146 |
1 files changed, 105 insertions, 41 deletions
diff --git a/src/mesa/shader/program_parse.y b/src/mesa/shader/program_parse.y index 5767c51759..5c5d8d7590 100644 --- a/src/mesa/shader/program_parse.y +++ b/src/mesa/shader/program_parse.y @@ -52,7 +52,8 @@ static int initialize_symbol_from_param(struct gl_program *prog, struct asm_symbol *param_var, const gl_state_index tokens[STATE_LENGTH]); static int initialize_symbol_from_const(struct gl_program *prog, - struct asm_symbol *param_var, const struct asm_vector *vec); + struct asm_symbol *param_var, const struct asm_vector *vec, + GLboolean allowSwizzle); static int yyparse(struct asm_parser_state *state); @@ -74,6 +75,9 @@ 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 set_src_reg_swz(struct asm_src_register *r, + gl_register_file file, GLint index, GLuint swizzle); + 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); @@ -309,6 +313,8 @@ option: OPTION string ';' } + free($2); + if (!valid) { const char *const err_str = (state->mode == ARB_vertex) ? "invalid ARB vertex program option" @@ -584,9 +590,11 @@ scalarUse: srcReg scalarSuffix memset(& temp_sym, 0, sizeof(temp_sym)); temp_sym.param_binding_begin = ~0; - initialize_symbol_from_const(state->prog, & temp_sym, & $1); + initialize_symbol_from_const(state->prog, & temp_sym, & $1, GL_TRUE); - set_src_reg(& $$, PROGRAM_CONSTANT, temp_sym.param_binding_begin); + set_src_reg_swz(& $$, PROGRAM_CONSTANT, + temp_sym.param_binding_begin, + temp_sym.param_binding_swizzle); } ; @@ -641,7 +649,7 @@ maskedDstReg: dstReg optionalMask optionalCcMask YYERROR; } - state->prog->OutputsWritten |= (1U << $$.Index); + state->prog->OutputsWritten |= BITFIELD64_BIT($$.Index); } } ; @@ -710,12 +718,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; @@ -763,6 +776,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; @@ -781,7 +796,9 @@ srcReg: USED_IDENTIFIER /* temporaryReg | progParamSingle */ set_src_reg(& $$, PROGRAM_TEMPORARY, s->temp_binding); break; case at_param: - set_src_reg(& $$, s->param_binding_type, s->param_binding_begin); + set_src_reg_swz(& $$, s->param_binding_type, + s->param_binding_begin, + s->param_binding_swizzle); break; case at_attrib: set_src_reg(& $$, PROGRAM_INPUT, s->attrib_binding); @@ -832,7 +849,8 @@ srcReg: USED_IDENTIFIER /* temporaryReg | progParamSingle */ gl_register_file file = ($1.name != NULL) ? $1.param_binding_type : PROGRAM_CONSTANT; - set_src_reg(& $$, file, $1.param_binding_begin); + set_src_reg_swz(& $$, file, $1.param_binding_begin, + $1.param_binding_swizzle); } ; @@ -845,6 +863,8 @@ dstReg: resultBinding 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; @@ -872,6 +892,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; @@ -943,6 +965,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; @@ -1081,6 +1105,7 @@ ATTRIB_statement: ATTRIB IDENTIFIER '=' attribBinding declare_variable(state, $2, at_attrib, & @2); if (s == NULL) { + free($2); YYERROR; } else { s->attrib_binding = $4; @@ -1188,11 +1213,13 @@ 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; s->param_binding_begin = $3.param_binding_begin; s->param_binding_length = $3.param_binding_length; + s->param_binding_swizzle = SWIZZLE_XYZW; s->param_is_array = 0; } } @@ -1201,6 +1228,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; @@ -1209,11 +1237,13 @@ 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; s->param_binding_begin = $6.param_binding_begin; s->param_binding_length = $6.param_binding_length; + s->param_binding_swizzle = SWIZZLE_XYZW; s->param_is_array = 1; } } @@ -1271,7 +1301,7 @@ paramSingleItemDecl: stateSingleItem { memset(& $$, 0, sizeof($$)); $$.param_binding_begin = ~0; - initialize_symbol_from_const(state->prog, & $$, & $1); + initialize_symbol_from_const(state->prog, & $$, & $1, GL_TRUE); } ; @@ -1291,7 +1321,7 @@ paramSingleItemUse: stateSingleItem { memset(& $$, 0, sizeof($$)); $$.param_binding_begin = ~0; - initialize_symbol_from_const(state->prog, & $$, & $1); + initialize_symbol_from_const(state->prog, & $$, & $1, GL_TRUE); } ; @@ -1311,7 +1341,7 @@ paramMultipleItem: stateMultipleItem { memset(& $$, 0, sizeof($$)); $$.param_binding_begin = ~0; - initialize_symbol_from_const(state->prog, & $$, & $1); + initialize_symbol_from_const(state->prog, & $$, & $1, GL_FALSE); } ; @@ -1943,12 +1973,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; } } @@ -1960,6 +1992,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; @@ -2136,17 +2169,21 @@ 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) { 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; } else { - _mesa_symbol_table_add_symbol(state->st, 0, strdup($2), target); + _mesa_symbol_table_add_symbol(state->st, 0, $2, target); } } ; @@ -2261,7 +2298,9 @@ 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); + (void) minIndex; ASSERT(index <= maxIndex); + (void) maxIndex; ASSERT(file == PROGRAM_TEMPORARY || file == PROGRAM_ADDRESS || file == PROGRAM_OUTPUT); @@ -2284,19 +2323,31 @@ init_src_reg(struct asm_src_register *r) } -/** Like init_src_reg() but set the File and Index fields. */ +/** Like init_src_reg() but set the File and Index fields. + * \return GL_TRUE if a valid src register, GL_FALSE otherwise + */ void set_src_reg(struct asm_src_register *r, gl_register_file file, GLint index) { + set_src_reg_swz(r, file, index, SWIZZLE_XYZW); +} + + +void +set_src_reg_swz(struct asm_src_register *r, gl_register_file file, GLint index, + GLuint swizzle) +{ const GLint maxIndex = (1 << INST_INDEX_BITS) - 1; const GLint minIndex = -(1 << INST_INDEX_BITS); + ASSERT(file < PROGRAM_FILE_MAX); ASSERT(index >= minIndex); + (void) minIndex; ASSERT(index <= maxIndex); - ASSERT(file < PROGRAM_FILE_MAX); + (void) maxIndex; memset(r, 0, sizeof(*r)); r->Base.File = file; r->Base.Index = index; - r->Base.Swizzle = SWIZZLE_NOOP; + r->Base.Swizzle = swizzle; r->Symbol = NULL; } @@ -2337,14 +2388,10 @@ declare_variable(struct asm_parser_state *state, char *name, enum asm_type t, if (exist != NULL) { yyerror(locp, state, "redeclared identifier"); } else { - const size_t name_len = strlen(name); - - s = calloc(1, sizeof(struct asm_symbol) + name_len + 1); - s->name = (char *)(s + 1); + s = calloc(1, sizeof(struct asm_symbol)); + s->name = name; s->type = t; - memcpy((char *) s->name, name, name_len + 1); - switch (t) { case at_temp: if (state->prog->NumTemporaries >= state->limits->MaxTemps) { @@ -2432,15 +2479,20 @@ initialize_symbol_from_state(struct gl_program *prog, state_tokens[2] = state_tokens[3] = row; idx = add_state_reference(prog->Parameters, state_tokens); - if (param_var->param_binding_begin == ~0U) + if (param_var->param_binding_begin == ~0U) { param_var->param_binding_begin = idx; + param_var->param_binding_swizzle = SWIZZLE_XYZW; + } + param_var->param_binding_length++; } } else { idx = add_state_reference(prog->Parameters, state_tokens); - if (param_var->param_binding_begin == ~0U) + if (param_var->param_binding_begin == ~0U) { param_var->param_binding_begin = idx; + param_var->param_binding_swizzle = SWIZZLE_XYZW; + } param_var->param_binding_length++; } @@ -2464,9 +2516,12 @@ initialize_symbol_from_param(struct gl_program *prog, assert((state_tokens[1] == STATE_ENV) || (state_tokens[1] == STATE_LOCAL)); + /* + * The param type is STATE_VAR. The program parameter entry will + * effectively be a pointer into the LOCAL or ENV parameter array. + */ param_var->type = at_param; - param_var->param_binding_type = (state_tokens[1] == STATE_ENV) - ? PROGRAM_ENV_PARAM : PROGRAM_LOCAL_PARAM; + param_var->param_binding_type = PROGRAM_STATE_VAR; /* If we are adding a STATE_ENV or STATE_LOCAL that has multiple elements, * we need to unroll it and call add_state_reference() for each row @@ -2480,15 +2535,19 @@ initialize_symbol_from_param(struct gl_program *prog, state_tokens[2] = state_tokens[3] = row; idx = add_state_reference(prog->Parameters, state_tokens); - if (param_var->param_binding_begin == ~0U) + if (param_var->param_binding_begin == ~0U) { param_var->param_binding_begin = idx; + param_var->param_binding_swizzle = SWIZZLE_XYZW; + } param_var->param_binding_length++; } } else { idx = add_state_reference(prog->Parameters, state_tokens); - if (param_var->param_binding_begin == ~0U) + if (param_var->param_binding_begin == ~0U) { param_var->param_binding_begin = idx; + param_var->param_binding_swizzle = SWIZZLE_XYZW; + } param_var->param_binding_length++; } @@ -2496,20 +2555,34 @@ initialize_symbol_from_param(struct gl_program *prog, } +/** + * Put a float/vector constant/literal into the parameter list. + * \param param_var returns info about the parameter/constant's location, + * binding, type, etc. + * \param vec the vector/constant to add + * \param allowSwizzle if true, try to consolidate constants which only differ + * by a swizzle. We don't want to do this when building + * arrays of constants that may be indexed indirectly. + * \return index of the constant in the parameter list. + */ int initialize_symbol_from_const(struct gl_program *prog, struct asm_symbol *param_var, - const struct asm_vector *vec) + const struct asm_vector *vec, + GLboolean allowSwizzle) { - const int idx = _mesa_add_parameter(prog->Parameters, PROGRAM_CONSTANT, - NULL, vec->count, GL_NONE, vec->data, - NULL, 0x0); + unsigned swizzle; + const int idx = _mesa_add_unnamed_constant(prog->Parameters, + vec->data, vec->count, + allowSwizzle ? &swizzle : NULL); param_var->type = at_param; param_var->param_binding_type = PROGRAM_CONSTANT; - if (param_var->param_binding_begin == ~0U) + if (param_var->param_binding_begin == ~0U) { param_var->param_binding_begin = idx; + param_var->param_binding_swizzle = allowSwizzle ? swizzle : SWIZZLE_XYZW; + } param_var->param_binding_length++; return idx; @@ -2592,11 +2665,6 @@ _mesa_parse_arb_program(GLcontext *ctx, GLenum target, const GLubyte *str, _mesa_memcpy (strz, str, len); strz[len] = '\0'; - if (state->prog->String != NULL) { - _mesa_free(state->prog->String); - state->prog->String = NULL; - } - state->prog->String = strz; state->st = _mesa_symbol_table_ctor(); @@ -2686,6 +2754,7 @@ error: for (sym = state->sym; sym != NULL; sym = temp) { temp = sym->next; + _mesa_free((void *) sym->name); _mesa_free(sym); } state->sym = NULL; @@ -2693,10 +2762,5 @@ error: _mesa_symbol_table_dtor(state->st); state->st = NULL; - if (state->string_dumpster != NULL) { - _mesa_free(state->string_dumpster); - state->dumpster_size = 0; - } - return result; } |