mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-01-08 10:40:11 +01:00
- Create a dummy program to keep from segfaulting when parsing
fails - Change to grammar .emit to fix single LOCAL/ENV param usage
This commit is contained in:
parent
15955f1c5e
commit
4eebfa14e7
4 changed files with 95 additions and 53 deletions
|
|
@ -189,24 +189,6 @@ _mesa_parse_arb_fragment_program(GLcontext * ctx, GLenum target,
|
|||
|
||||
retval = _mesa_parse_arb_program(ctx, str, len, &ap);
|
||||
|
||||
/* XXX: Parse error. Cleanup things and return */
|
||||
if (retval)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
/* XXX: Eh.. we parsed something that wasn't a fragment program. doh! */
|
||||
if (ap.type != GL_FRAGMENT_PROGRAM_ARB)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
#if DEBUG_FP
|
||||
debug_fp_inst(ap.Base.NumInstructions, ap.FPInstructions);
|
||||
#else
|
||||
(void) debug_fp_inst;
|
||||
#endif
|
||||
|
||||
/* copy the relvant contents of the arb_program struct into the
|
||||
* fragment_program struct
|
||||
*/
|
||||
|
|
@ -216,7 +198,6 @@ _mesa_parse_arb_fragment_program(GLcontext * ctx, GLenum target,
|
|||
program->Base.NumAttributes = ap.Base.NumAttributes;
|
||||
program->Base.NumAddressRegs = ap.Base.NumAddressRegs;
|
||||
|
||||
program->Instructions = ap.FPInstructions;
|
||||
program->InputsRead = ap.InputsRead;
|
||||
program->OutputsWritten = ap.OutputsWritten;
|
||||
for (retval=0; retval<MAX_TEXTURE_IMAGE_UNITS; retval++)
|
||||
|
|
@ -225,4 +206,32 @@ _mesa_parse_arb_fragment_program(GLcontext * ctx, GLenum target,
|
|||
program->NumTexInstructions = ap.NumTexInstructions;
|
||||
program->NumTexIndirections = ap.NumTexIndirections;
|
||||
program->Parameters = ap.Parameters;
|
||||
|
||||
/* XXX: Parse error. Cleanup things and return */
|
||||
if (retval)
|
||||
{
|
||||
program->Instructions = (struct fp_instruction *) _mesa_malloc (
|
||||
sizeof(struct fp_instruction) );
|
||||
program->Instructions[0].Opcode = FP_OPCODE_END;
|
||||
return;
|
||||
}
|
||||
|
||||
/* XXX: Eh.. we parsed something that wasn't a fragment program. doh! */
|
||||
if (ap.type != GL_FRAGMENT_PROGRAM_ARB)
|
||||
{
|
||||
program->Instructions = (struct fp_instruction *) _mesa_malloc (
|
||||
sizeof(struct fp_instruction) );
|
||||
program->Instructions[0].Opcode = FP_OPCODE_END;
|
||||
|
||||
_mesa_error (ctx, GL_INVALID_OPERATION, "Parsed a non-fragment program as a fragment program");
|
||||
return;
|
||||
}
|
||||
|
||||
#if DEBUG_FP
|
||||
debug_fp_inst(ap.Base.NumInstructions, ap.FPInstructions);
|
||||
#else
|
||||
(void) debug_fp_inst;
|
||||
#endif
|
||||
|
||||
program->Instructions = ap.FPInstructions;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -87,7 +87,7 @@
|
|||
*
|
||||
* Cosmetic Stuff
|
||||
* -----------------------------------------------------
|
||||
* - fix compiler warnings
|
||||
* - 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
|
||||
|
|
@ -107,6 +107,21 @@
|
|||
* " exponent .or .true .emit '1' .emit 0x00 .emit $;\n"
|
||||
*
|
||||
* - XXX: need to recognize "1" as a valid float ?
|
||||
* - XXX: this fails:
|
||||
* "MUL result.color.xyz, R0, program.local[35] ;"
|
||||
* but this works:
|
||||
* "MUL result.color.primary.xyz, R0, program.local[35] ;"
|
||||
* -> see progs/tests/arbvptorus.c
|
||||
*
|
||||
* - changed "progLocalParam\n" changed from:
|
||||
* " \"local\" .emit PROGRAM_PARAM_LOCAL .and lbracket .and progLocalParamNum
|
||||
* .and rbracket;\n"
|
||||
* to:
|
||||
* " \"local\" .emit PROGRAM_PARAM_LOCAL .and lbracket .and progLocalParamNum
|
||||
* .and rbracket .emit 0x00;\n"
|
||||
* so we can distinguish between the progLocalParam and progLocalParams rules
|
||||
*
|
||||
* - made the same change as above to the progEnvParam rule
|
||||
*/
|
||||
|
||||
typedef GLubyte *production;
|
||||
|
|
@ -3437,6 +3452,7 @@ parse_program_single_item (GLcontext * ctx, GLubyte ** inst,
|
|||
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))
|
||||
|
|
@ -3456,6 +3472,7 @@ parse_program_single_item (GLcontext * ctx, GLubyte ** inst,
|
|||
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))
|
||||
|
|
@ -3764,6 +3781,7 @@ parse_param_elements (GLcontext * ctx, GLubyte ** inst,
|
|||
|
||||
switch (*(*inst)++) {
|
||||
case PARAM_STATE_ELEMENT:
|
||||
|
||||
if (parse_state_single_item (ctx, inst, Program, state_tokens))
|
||||
return 1;
|
||||
|
||||
|
|
@ -3799,6 +3817,7 @@ parse_param_elements (GLcontext * ctx, GLubyte ** inst,
|
|||
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);
|
||||
|
|
@ -3847,6 +3866,10 @@ parse_param_elements (GLcontext * ctx, GLubyte ** inst,
|
|||
Program->Base.NumParameters++;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
(*(*inst)++);
|
||||
}
|
||||
break;
|
||||
|
||||
case PARAM_CONSTANT:
|
||||
|
|
@ -3983,7 +4006,6 @@ parse_param_use (GLcontext * ctx, GLubyte ** inst, struct var_cache **vc_head,
|
|||
*/
|
||||
param_var->param_binding_type = PROGRAM_STATE_VAR;
|
||||
|
||||
|
||||
var_cache_append (vc_head, param_var);
|
||||
|
||||
/* Then fill it with juicy parameter goodness */
|
||||
|
|
@ -4257,8 +4279,8 @@ parse_masked_dst_reg (GLcontext * ctx, GLubyte ** inst,
|
|||
/* 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;
|
||||
}
|
||||
|
|
@ -4329,10 +4351,10 @@ parse_masked_address_reg (GLcontext * ctx, GLubyte ** inst,
|
|||
dst = parse_string (inst, vc_head, Program, &result);
|
||||
Program->Position = parse_position (inst);
|
||||
|
||||
/* If the name has never been added to our symbol table, we're hosed */
|
||||
/* 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",
|
||||
_mesa_set_program_error (ctx, Program->Position, "1: Undefined variable");
|
||||
_mesa_error (ctx, GL_INVALID_OPERATION, "1: Undefined variable: %s",
|
||||
dst->name);
|
||||
return 1;
|
||||
}
|
||||
|
|
@ -4470,7 +4492,6 @@ parse_src_reg (GLcontext * ctx, GLubyte ** inst, struct var_cache **vc_head,
|
|||
break;
|
||||
|
||||
case REGISTER_PARAM:
|
||||
|
||||
switch (**inst) {
|
||||
case PARAM_ARRAY_ELEMENT:
|
||||
*(*inst)++;
|
||||
|
|
@ -4479,9 +4500,9 @@ parse_src_reg (GLcontext * ctx, GLubyte ** inst, struct var_cache **vc_head,
|
|||
|
||||
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;
|
||||
}
|
||||
|
||||
|
|
@ -4511,6 +4532,7 @@ parse_src_reg (GLcontext * ctx, GLubyte ** inst, struct var_cache **vc_head,
|
|||
break;
|
||||
|
||||
default:
|
||||
|
||||
if (parse_param_use (ctx, inst, vc_head, Program, &src))
|
||||
return 1;
|
||||
|
||||
|
|
@ -4521,14 +4543,15 @@ parse_src_reg (GLcontext * ctx, GLubyte ** inst, struct var_cache **vc_head,
|
|||
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;
|
||||
}
|
||||
|
|
@ -4589,7 +4612,7 @@ parse_vector_src_reg (GLcontext * ctx, GLubyte ** inst,
|
|||
|
||||
/* finally, the swizzle */
|
||||
parse_swizzle_mask (inst, Swizzle, 4);
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -966,7 +966,7 @@ static char arb_grammar_text[] = ".syntax program;\n"
|
|||
"progEnvParamNums_2\n"
|
||||
" progEnvParamNum .and .true .emit 0x00;\n"
|
||||
"progEnvParam\n"
|
||||
" \"env\" .emit PROGRAM_PARAM_ENV .and lbracket .and progEnvParamNum .and rbracket;\n"
|
||||
" \"env\" .emit PROGRAM_PARAM_ENV .and lbracket .and progEnvParamNum .and rbracket .emit 0x00;\n"
|
||||
"progLocalParams\n"
|
||||
" \"local\" .emit PROGRAM_PARAM_LOCAL .and lbracket .and progLocalParamNums .and rbracket;\n"
|
||||
"progLocalParamNums\n"
|
||||
|
|
@ -976,7 +976,7 @@ static char arb_grammar_text[] = ".syntax program;\n"
|
|||
"progLocalParamNums_2\n"
|
||||
" progLocalParamNum .and .true .emit 0x00;\n"
|
||||
"progLocalParam\n"
|
||||
" \"local\" .emit PROGRAM_PARAM_LOCAL .and lbracket .and progLocalParamNum .and rbracket;\n"
|
||||
" \"local\" .emit PROGRAM_PARAM_LOCAL .and lbracket .and progLocalParamNum .and rbracket .emit 0x00;\n"
|
||||
"progEnvParamNum\n"
|
||||
" integer;\n"
|
||||
"progLocalParamNum\n"
|
||||
|
|
|
|||
|
|
@ -178,24 +178,6 @@ _mesa_parse_arb_vertex_program(GLcontext * ctx, GLenum target,
|
|||
|
||||
retval = _mesa_parse_arb_program(ctx, str, len, &ap);
|
||||
|
||||
/* XXX: Parse error. Cleanup things and return */
|
||||
if (retval)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
/* XXX: Eh.. we parsed something that wasn't a vertex program. doh! */
|
||||
if (ap.type != GL_VERTEX_PROGRAM_ARB)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
#if DEBUG_VP
|
||||
debug_vp_inst(ap.Base.NumInstructions, ap.VPInstructions);
|
||||
#else
|
||||
(void) debug_vp_inst;
|
||||
#endif
|
||||
|
||||
/* copy the relvant contents of the arb_program struct into the
|
||||
* fragment_program struct
|
||||
*/
|
||||
|
|
@ -205,9 +187,37 @@ _mesa_parse_arb_vertex_program(GLcontext * ctx, GLenum target,
|
|||
program->Base.NumAttributes = ap.Base.NumAttributes;
|
||||
program->Base.NumAddressRegs = ap.Base.NumAddressRegs;
|
||||
|
||||
program->Instructions = ap.VPInstructions;
|
||||
program->IsPositionInvariant = ap.HintPositionInvariant;
|
||||
program->InputsRead = ap.InputsRead;
|
||||
program->OutputsWritten = ap.OutputsWritten;
|
||||
program->Parameters = ap.Parameters;
|
||||
|
||||
/* Parse error. Allocate a dummy program and return */
|
||||
if (retval)
|
||||
{
|
||||
program->Instructions = (struct vp_instruction *) _mesa_malloc (
|
||||
sizeof(struct vp_instruction) );
|
||||
program->Instructions[0].Opcode = VP_OPCODE_END;
|
||||
return;
|
||||
}
|
||||
|
||||
/* Eh.. we parsed something that wasn't a vertex program. doh! */
|
||||
if (ap.type != GL_VERTEX_PROGRAM_ARB)
|
||||
{
|
||||
program->Instructions = (struct vp_instruction *) _mesa_malloc (
|
||||
sizeof(struct vp_instruction) );
|
||||
program->Instructions[0].Opcode = VP_OPCODE_END;
|
||||
|
||||
_mesa_error (ctx, GL_INVALID_OPERATION, "Parsed a non-vertex program as a vertex program");
|
||||
return;
|
||||
}
|
||||
|
||||
program->Instructions = ap.VPInstructions;
|
||||
|
||||
#if DEBUG_VP
|
||||
debug_vp_inst(ap.Base.NumInstructions, ap.VPInstructions);
|
||||
#else
|
||||
(void) debug_vp_inst;
|
||||
#endif
|
||||
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue