From 72030e0d91cc505db1eb7d39d5240b2f562cf710 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Thu, 3 Nov 2005 03:30:34 +0000 Subject: Streamline code generation by using a fixed size instruction buffer in arb_program struct. --- src/mesa/shader/arbfragparse.c | 16 +++++++-- src/mesa/shader/arbprogparse.c | 82 +++++++++--------------------------------- src/mesa/shader/arbprogparse.h | 18 ++++++---- src/mesa/shader/arbvertparse.c | 17 ++++++--- 4 files changed, 54 insertions(+), 79 deletions(-) (limited to 'src/mesa') diff --git a/src/mesa/shader/arbfragparse.c b/src/mesa/shader/arbfragparse.c index 7b9abec1c9..75c7b35e40 100644 --- a/src/mesa/shader/arbfragparse.c +++ b/src/mesa/shader/arbfragparse.c @@ -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; } diff --git a/src/mesa/shader/arbprogparse.c b/src/mesa/shader/arbprogparse.c index 4e4f2cdd41..7b56b078a1 100644 --- a/src/mesa/shader/arbprogparse.c +++ b/src/mesa/shader/arbprogparse.c @@ -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; diff --git a/src/mesa/shader/arbprogparse.h b/src/mesa/shader/arbprogparse.h index 947c22e767..59f8e3b22e 100644 --- a/src/mesa/shader/arbprogparse.h +++ b/src/mesa/shader/arbprogparse.h @@ -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; diff --git a/src/mesa/shader/arbvertparse.c b/src/mesa/shader/arbvertparse.c index 5d1ad3de2e..2fbfa5fe9e 100644 --- a/src/mesa/shader/arbvertparse.c +++ b/src/mesa/shader/arbvertparse.c @@ -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 - } -- cgit v1.2.3