diff options
author | Brian Paul <[email protected]> | 2008-05-14 12:39:41 -0600 |
---|---|---|
committer | Brian Paul <[email protected]> | 2008-05-14 12:39:41 -0600 |
commit | 19ad9cf7741c641bd83d20485b32d11fe27ca8df (patch) | |
tree | 5f3a147e42e08ccb6ae72a432859a60659ea7978 /src/mesa/shader | |
parent | 450136d368ce7a08cf25992c79b51f51f8a9bb7c (diff) |
mesa: added _mesa_insert_instructions()
Also, use new _mesa_free_instructions() in a few places.
cherry-picked from gallium-0.1
Diffstat (limited to 'src/mesa/shader')
-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 bde04b9c29e..92aa6ee44a3 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 9a6883e6a55..c5d36c78a03 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 |