diff options
| -rw-r--r-- | src/mesa/shader/program.c | 60 | ||||
| -rw-r--r-- | src/mesa/shader/program.h | 2 | 
2 files changed, 52 insertions, 10 deletions
| diff --git a/src/mesa/shader/program.c b/src/mesa/shader/program.c index bde04b9c29..92aa6ee44a 100644 --- a/src/mesa/shader/program.c +++ b/src/mesa/shader/program.c @@ -304,16 +304,7 @@ _mesa_delete_program(GLcontext *ctx, struct gl_program *prog)     if (prog->String)        _mesa_free(prog->String); -   if (prog->Instructions) { -      GLuint i; -      for (i = 0; i < prog->NumInstructions; i++) { -         if (prog->Instructions[i].Data) -            _mesa_free(prog->Instructions[i].Data); -         if (prog->Instructions[i].Comment) -            _mesa_free((char *) prog->Instructions[i].Comment); -      } -      _mesa_free(prog->Instructions); -   } +   _mesa_free_instructions(prog->Instructions, prog->NumInstructions);     if (prog->Parameters) {        _mesa_free_parameter_list(prog->Parameters); @@ -485,6 +476,55 @@ _mesa_clone_program(GLcontext *ctx, const struct gl_program *prog)  } +/** + * Insert 'count' NOP instructions at 'start' in the given program. + * Adjust branch targets accordingly. + */ +GLboolean +_mesa_insert_instructions(struct gl_program *prog, GLuint start, GLuint count) +{ +   const GLuint origLen = prog->NumInstructions; +   const GLuint newLen = origLen + count; +   struct prog_instruction *newInst; +   GLuint i; + +   /* adjust branches */ +   for (i = 0; i < prog->NumInstructions; i++) { +      struct prog_instruction *inst = prog->Instructions + i; +      if (inst->BranchTarget > 0) { +         if (inst->BranchTarget >= start) { +            inst->BranchTarget += count; +         } +      } +   } + +   /* Alloc storage for new instructions */ +   newInst = _mesa_alloc_instructions(newLen); +   if (!newInst) { +      return GL_FALSE; +   } + +   /* Copy 'start' instructions into new instruction buffer */ +   _mesa_copy_instructions(newInst, prog->Instructions, start); + +   /* init the new instructions */ +   _mesa_init_instructions(newInst + start, count); + +   /* Copy the remaining/tail instructions to new inst buffer */ +   _mesa_copy_instructions(newInst + start + count, +                           prog->Instructions + start, +                           origLen - start); + +   /* free old instructions */ +   _mesa_free_instructions(prog->Instructions, origLen); + +   /* install new instructions */ +   prog->Instructions = newInst; +   prog->NumInstructions = newLen; + +   return GL_TRUE; +} +  /**   * Mixing ARB and NV vertex/fragment programs can be tricky. diff --git a/src/mesa/shader/program.h b/src/mesa/shader/program.h index 9a6883e6a5..c5d36c78a0 100644 --- a/src/mesa/shader/program.h +++ b/src/mesa/shader/program.h @@ -112,6 +112,8 @@ _mesa_reference_fragprog(GLcontext *ctx,  extern struct gl_program *  _mesa_clone_program(GLcontext *ctx, const struct gl_program *prog); +extern  GLboolean +_mesa_insert_instructions(struct gl_program *prog, GLuint start, GLuint count);  /*   * API functions common to ARB/NV_vertex/fragment_program | 
