summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorBrian <brian.paul@tungstengraphics.com>2008-04-07 11:16:18 -0600
committerBrian <brian.paul@tungstengraphics.com>2008-04-07 11:23:43 -0600
commit5d1e73028aabfa1470bfed02c705a2696706f857 (patch)
treee65048e73d2d57932218b6355c39a88bbd4ffa68 /src
parentf3bd7bf5c913d2a58d424e995b4d441e402bd62b (diff)
mesa: added _mesa_insert_instructions()
Also, use new _mesa_free_instructions() in a few places.
Diffstat (limited to 'src')
-rw-r--r--src/mesa/shader/program.c60
-rw-r--r--src/mesa/shader/program.h2
2 files changed, 52 insertions, 10 deletions
diff --git a/src/mesa/shader/program.c b/src/mesa/shader/program.c
index 3069b04836..0ed7f833d2 100644
--- a/src/mesa/shader/program.c
+++ b/src/mesa/shader/program.c
@@ -287,16 +287,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);
@@ -415,6 +406,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;
+}
+
/**
* Search instructions for registers that match (oldFile, oldIndex),
diff --git a/src/mesa/shader/program.h b/src/mesa/shader/program.h
index 4b7297e4c6..414a57d39c 100644
--- a/src/mesa/shader/program.h
+++ b/src/mesa/shader/program.h
@@ -87,6 +87,8 @@ _mesa_lookup_program(GLcontext *ctx, GLuint id);
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);
extern struct gl_program *
_mesa_combine_programs(GLcontext *ctx,