arb_program struct.tags/mesa_20060201
@@ -190,6 +190,7 @@ _mesa_parse_arb_fragment_program(GLcontext * ctx, GLenum target, | |||
{ | |||
GLuint i; | |||
struct arb_program ap; | |||
struct fp_instruction *newInstructions; | |||
(void) target; | |||
/* set the program target before parsing */ | |||
@@ -203,6 +204,18 @@ _mesa_parse_arb_fragment_program(GLcontext * ctx, GLenum target, | |||
/* 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; | |||
@@ -212,7 +225,6 @@ _mesa_parse_arb_fragment_program(GLcontext * ctx, GLenum target, | |||
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++) | |||
@@ -228,6 +240,4 @@ _mesa_parse_arb_fragment_program(GLcontext * ctx, GLenum target, | |||
#if DEBUG_FP | |||
_mesa_debug_fp_inst(ap.Base.NumInstructions, ap.FPInstructions); | |||
#endif | |||
program->Instructions = ap.FPInstructions; | |||
} |
@@ -3594,47 +3594,25 @@ debug_variables (GLcontext * ctx, struct var_cache *vc_head, | |||
} | |||
} | |||
#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++; | |||
@@ -3683,44 +3661,25 @@ parse_arb_program(GLcontext * ctx, GLubyte * inst, struct var_cache **vc_head, | |||
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; | |||
@@ -3739,8 +3698,6 @@ parse_arb_program(GLcontext * ctx, GLubyte * inst, struct var_cache **vc_head, | |||
/* 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 | |||
@@ -3750,8 +3707,6 @@ parse_arb_program(GLcontext * ctx, GLubyte * inst, struct var_cache **vc_head, | |||
} | |||
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 | |||
@@ -4017,9 +3972,6 @@ _mesa_parse_arb_program (GLcontext * ctx, const GLubyte * str, GLsizei len, | |||
program->UsesKill = 0; | |||
program->FPInstructions = NULL; | |||
program->VPInstructions = NULL; | |||
vc_head = NULL; | |||
err = GL_FALSE; | |||
@@ -1,6 +1,6 @@ | |||
/* | |||
* Mesa 3-D graphics library | |||
* Version: 6.3 | |||
* Version: 6.5 | |||
* | |||
* Copyright (C) 1999-2005 Brian Paul All Rights Reserved. | |||
* | |||
@@ -31,25 +31,29 @@ | |||
#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 */ | |||
@@ -60,8 +64,8 @@ struct arb_program | |||
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; |
@@ -169,6 +169,7 @@ _mesa_parse_arb_vertex_program(GLcontext * ctx, GLenum target, | |||
{ | |||
struct arb_program ap; | |||
(void) target; | |||
struct vp_instruction *newInstructions; | |||
/* set the program target before parsing */ | |||
ap.Base.Target = GL_VERTEX_PROGRAM_ARB; | |||
@@ -181,13 +182,24 @@ _mesa_parse_arb_vertex_program(GLcontext * ctx, GLenum target, | |||
/* 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; | |||
@@ -198,10 +210,7 @@ _mesa_parse_arb_vertex_program(GLcontext * ctx, GLenum target, | |||
} | |||
program->Parameters = ap.Parameters; | |||
program->Instructions = ap.VPInstructions; | |||
#if DEBUG_VP | |||
_mesa_debug_vp_inst(ap.Base.NumInstructions, ap.VPInstructions); | |||
#endif | |||
} |