mesa: added _mesa_insert_instructions()
authorBrian <brian.paul@tungstengraphics.com>
Mon, 7 Apr 2008 17:16:18 +0000 (11:16 -0600)
committerBrian <brian.paul@tungstengraphics.com>
Mon, 7 Apr 2008 17:23:43 +0000 (11:23 -0600)
Also, use new _mesa_free_instructions() in a few places.

src/mesa/shader/program.c
src/mesa/shader/program.h

index 3069b04836d46e385734913e0707de20c45928ef..0ed7f833d20861dca16a6fdbe1ac2e18932c991c 100644 (file)
@@ -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),
index 4b7297e4c65edb1f589fd823fafbc1502a2a3e05..414a57d39cc4175d373649bdcb84ea006f9d06b9 100644 (file)
@@ -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,