{
GLuint i;
struct arb_program ap;
+ struct fp_instruction *newInstructions;
(void) target;
/* set the program target before parsing */
/* Copy the relevant contents of the arb_program struct into the
* fragment_program struct.
*/
+ /* copy instruction buffer */
+ newInstructions = (struct fp_instruction *)
+ _mesa_malloc(ap.Base.NumInstructions * sizeof(struct fp_instruction));
+ if (!newInstructions) {
+ _mesa_error(ctx, GL_OUT_OF_MEMORY, "glProgramStringARB");
+ return;
+ }
+ _mesa_memcpy(newInstructions, ap.FPInstructions,
+ ap.Base.NumInstructions * sizeof(struct fp_instruction));
+ if (program->Instructions)
+ _mesa_free(program->Instructions);
+ program->Instructions = newInstructions;
program->Base.String = ap.Base.String;
program->Base.NumInstructions = ap.Base.NumInstructions;
program->Base.NumTemporaries = ap.Base.NumTemporaries;
program->NumAluInstructions = ap.NumAluInstructions;
program->NumTexInstructions = ap.NumTexInstructions;
program->NumTexIndirections = ap.NumTexIndirections;
-
program->InputsRead = ap.InputsRead;
program->OutputsWritten = ap.OutputsWritten;
for (i = 0; i < MAX_TEXTURE_IMAGE_UNITS; i++)
#if DEBUG_FP
_mesa_debug_fp_inst(ap.Base.NumInstructions, ap.FPInstructions);
#endif
-
- program->Instructions = ap.FPInstructions;
}
}
}
-#endif
-
-
-/**
- * Grow an array of fragment program instructions.
- */
-static struct fp_instruction *
-realloc_fp_instructions(struct fp_instruction *oldArray, GLuint oldSize)
-{
- struct fp_instruction *array = (struct fp_instruction *)
- _mesa_realloc(oldArray,
- oldSize * sizeof(struct fp_instruction),
- (oldSize + 1) * sizeof(struct fp_instruction));
- return array;
-}
-
-/**
- * Grow an array of vertex program instructions.
- */
-static struct vp_instruction *
-realloc_vp_instructions(struct vp_instruction *oldArray, GLuint oldSize)
-{
- struct vp_instruction *array = (struct vp_instruction *)
- _mesa_realloc(oldArray,
- oldSize * sizeof(struct vp_instruction),
- (oldSize + 1) * sizeof(struct vp_instruction));
- return array;
-}
+#endif /* DEBUG_PARSING */
/**
* The main loop for parsing a fragment or vertex program
*
- * \return GL_TRUE on success, GL_FALSE on error.
+ * \return 1 on error, 0 on success
*/
-static GLboolean
+static GLint
parse_arb_program(GLcontext * ctx, GLubyte * inst, struct var_cache **vc_head,
struct arb_program *Program)
{
+ const GLuint maxInst = (Program->Base.Target == GL_FRAGMENT_PROGRAM_ARB)
+ ? ctx->Const.FragmentProgram.MaxInstructions
+ : ctx->Const.VertexProgram.MaxInstructions;
GLint err = 0;
+ ASSERT(MAX_INSTRUCTIONS >= maxInst);
+
Program->MajorVersion = (GLuint) * inst++;
Program->MinorVersion = (GLuint) * inst++;
break;
case INSTRUCTION:
+ /* check length */
+ if (Program->Base.NumInstructions + 1 >= maxInst) {
+ const char *msg = "Max instruction count exceeded";
+ _mesa_set_program_error(ctx, Program->Position, msg);
+ _mesa_error(ctx, GL_INVALID_OPERATION, msg);
+ return 1;
+ }
Program->Position = parse_position (&inst);
-
+ /* parse the current instruction */
if (Program->Base.Target == GL_FRAGMENT_PROGRAM_ARB) {
- /* Check instruction count. END counts as an instruction. */
- if (Program->Base.NumInstructions + 1
- == MAX_NV_FRAGMENT_PROGRAM_INSTRUCTIONS) {
- const char *msg = "Max instruction count exceeded";
- _mesa_set_program_error(ctx, Program->Position, msg);
- _mesa_error(ctx, GL_INVALID_OPERATION, msg);
- }
-
- /* grow instruction list */
- Program->FPInstructions
- = realloc_fp_instructions(Program->FPInstructions,
- Program->Base.NumInstructions);
- /* parse the current instruction */
err = parse_fp_instruction (ctx, &inst, vc_head, Program,
&Program->FPInstructions[Program->Base.NumInstructions]);
}
else {
- /* Check instruction count. END counts as an instruction. */
- if (Program->Base.NumInstructions + 1
- == MAX_NV_VERTEX_PROGRAM_INSTRUCTIONS) {
- const char *msg = "Max instruction count exceeded";
- _mesa_set_program_error(ctx, Program->Position, msg);
- _mesa_error(ctx, GL_INVALID_OPERATION, msg);
- }
-
- /* grow instruction list */
- Program->VPInstructions
- = realloc_vp_instructions(Program->VPInstructions,
- Program->Base.NumInstructions);
- /* parse the current instruction */
err = parse_vp_instruction (ctx, &inst, vc_head, Program,
&Program->VPInstructions[Program->Base.NumInstructions]);
}
- /* increment Program->Base.NumInstructions */
+ /* increment instuction count */
Program->Base.NumInstructions++;
break;
/* Finally, tag on an OPCODE_END instruction */
if (Program->Base.Target == GL_FRAGMENT_PROGRAM_ARB) {
const GLuint numInst = Program->Base.NumInstructions;
- Program->FPInstructions
- = realloc_fp_instructions(Program->FPInstructions, numInst);
_mesa_init_fp_instruction(Program->FPInstructions + numInst);
Program->FPInstructions[numInst].Opcode = FP_OPCODE_END;
/* YYY Wrong Position in program, whatever, at least not random -> crash
}
else {
const GLuint numInst = Program->Base.NumInstructions;
- Program->VPInstructions
- = realloc_vp_instructions(Program->VPInstructions, numInst);
_mesa_init_vp_instruction(Program->VPInstructions + numInst);
Program->VPInstructions[numInst].Opcode = VP_OPCODE_END;
/* YYY Wrong Position in program, whatever, at least not random -> crash
program->UsesKill = 0;
- program->FPInstructions = NULL;
- program->VPInstructions = NULL;
-
vc_head = NULL;
err = GL_FALSE;
/*
* Mesa 3-D graphics library
- * Version: 6.3
+ * Version: 6.5
*
* Copyright (C) 1999-2005 Brian Paul All Rights Reserved.
*
#include "nvvertprog.h"
#include "nvfragprog.h"
+
+#define MAX_INSTRUCTIONS 256
+
+
/**
* This is basically a union of the vertex_program and fragment_program
* structs that we can use to parse the program into
*
- * XXX: this should go into mtypes.h?
+ * XXX we can probably get rid of this entirely someday.
*/
struct arb_program
{
struct program Base;
struct program_parameter_list *Parameters;
- GLuint InputsRead;
- GLuint OutputsWritten;
+ GLbitfield InputsRead;
+ GLbitfield OutputsWritten;
GLuint Position; /* Just used for error reporting while parsing */
GLuint MajorVersion;
GLuint MinorVersion;
/* ARB_vertex_program specifics */
- struct vp_instruction *VPInstructions;
+ struct vp_instruction VPInstructions[MAX_INSTRUCTIONS];
/* Options currently recognized by the parser */
/* ARB_fp */
GLboolean HintPositionInvariant;
/* ARB_fragment_program specifics */
- struct fp_instruction *FPInstructions;
- GLuint TexturesUsed[MAX_TEXTURE_IMAGE_UNITS];
+ struct fp_instruction FPInstructions[MAX_INSTRUCTIONS];
+ GLbitfield TexturesUsed[MAX_TEXTURE_IMAGE_UNITS];
GLuint NumAluInstructions;
GLuint NumTexInstructions;
GLuint NumTexIndirections;
{
struct arb_program ap;
(void) target;
+ struct vp_instruction *newInstructions;
/* set the program target before parsing */
ap.Base.Target = GL_VERTEX_PROGRAM_ARB;
/* Copy the relevant contents of the arb_program struct into the
* vertex_program struct.
*/
+ /* copy instruction buffer */
+ newInstructions = (struct vp_instruction *)
+ _mesa_malloc(ap.Base.NumInstructions * sizeof(struct vp_instruction));
+ if (!newInstructions) {
+ _mesa_error(ctx, GL_OUT_OF_MEMORY, "glProgramStringARB");
+ return;
+ }
+ _mesa_memcpy(newInstructions, ap.VPInstructions,
+ ap.Base.NumInstructions * sizeof(struct vp_instruction));
+ if (program->Instructions)
+ _mesa_free(program->Instructions);
+ program->Instructions = newInstructions;
program->Base.String = ap.Base.String;
program->Base.NumInstructions = ap.Base.NumInstructions;
program->Base.NumTemporaries = ap.Base.NumTemporaries;
program->Base.NumParameters = ap.Base.NumParameters;
program->Base.NumAttributes = ap.Base.NumAttributes;
program->Base.NumAddressRegs = ap.Base.NumAddressRegs;
-
program->IsPositionInvariant = ap.HintPositionInvariant;
program->InputsRead = ap.InputsRead;
program->OutputsWritten = ap.OutputsWritten;
}
program->Parameters = ap.Parameters;
- program->Instructions = ap.VPInstructions;
-
#if DEBUG_VP
_mesa_debug_vp_inst(ap.Base.NumInstructions, ap.VPInstructions);
#endif
-
}