i915g: Separate declarations and program in the fragment program struct.
authorStéphane Marchesin <marcheu@chromium.org>
Sun, 22 Jan 2012 10:22:20 +0000 (02:22 -0800)
committerStéphane Marchesin <marcheu@chromium.org>
Mon, 13 Feb 2012 00:32:14 +0000 (16:32 -0800)
We need this later to fixup fragment programs properly.

src/gallium/drivers/i915/i915_context.h
src/gallium/drivers/i915/i915_fpc_translate.c
src/gallium/drivers/i915/i915_state.c
src/gallium/drivers/i915/i915_state_emit.c

index e39c7cc137f457fa3cb223ab3e11dbdb36bb36e4..b019c9f342a2a30dc680652f2a5e8d207a4d49ac 100644 (file)
@@ -104,6 +104,9 @@ struct i915_fragment_shader
 
    struct draw_fragment_shader *draw_data;
 
+   uint *decl;
+   uint decl_len;
+
    uint *program;
    uint program_len;
 
index 5bfbfa0fa0508e3bd4131e81f0949bea102d627a..a82ad146dfd16f87b03e5b590177777612b568d4 100644 (file)
@@ -1277,17 +1277,26 @@ i915_fini_compile(struct i915_context *i915, struct i915_fp_compile *p)
 
       /* Copy compilation results to fragment program struct: 
        */
+      assert(!ifs->decl);
       assert(!ifs->program);
+
+      ifs->decl
+         = (uint *) MALLOC(decl_size * sizeof(uint));
       ifs->program
-         = (uint *) MALLOC((program_size + decl_size) * sizeof(uint));
-      if (ifs->program) {
-         ifs->program_len = program_size + decl_size;
+         = (uint *) MALLOC(program_size * sizeof(uint));
 
-         memcpy(ifs->program,
+      if (ifs->decl) {
+         ifs->decl_len = decl_size;
+
+         memcpy(ifs->decl,
                 p->declarations,
                 decl_size * sizeof(uint));
+      }
+
+      if (ifs->program) {
+         ifs->program_len = program_size;
 
-         memcpy(ifs->program + decl_size,
+         memcpy(ifs->program,
                 p->program,
                 program_size * sizeof(uint));
       }
index 853468c6ffd5101179cab7746e7c93fed8c6281b..d0063e3901aed6a9d77b69d2f6b2b006caf4899b 100644 (file)
@@ -608,6 +608,11 @@ void i915_delete_fs_state(struct pipe_context *pipe, void *shader)
 {
    struct i915_fragment_shader *ifs = (struct i915_fragment_shader *) shader;
 
+   if (ifs->decl) {
+      FREE(ifs->decl);
+      ifs->decl = NULL;
+   }
+
    if (ifs->program) {
       FREE(ifs->program);
       ifs->program = NULL;
@@ -615,6 +620,7 @@ void i915_delete_fs_state(struct pipe_context *pipe, void *shader)
       ifs->state.tokens = NULL;
    }
    ifs->program_len = 0;
+   ifs->decl_len = 0;
 
    FREE(ifs);
 }
index 9c941ae9e41ee3b932a829592b855c648307071b..2aed3f1c7dcc6566fa44458dc819ea1fb7d24ca3 100644 (file)
@@ -366,7 +366,7 @@ validate_program(struct i915_context *i915, unsigned *batch_space)
    uint additional_size = i915->current.target_fixup_format ? 1 : 0;
 
    /* we need more batch space if we want to emulate rgba framebuffers */
-   *batch_space = i915->fs->program_len + 3 * additional_size;
+   *batch_space = i915->fs->decl_len + i915->fs->program_len + 3 * additional_size;
 }
 
 static void
@@ -378,15 +378,19 @@ emit_program(struct i915_context *i915)
    /* we should always have, at least, a pass-through program */
    assert(i915->fs->program_len > 0);
 
+   /* output the declarations */
    {
       /* first word has the size, we have to adjust that */
-      uint size = (i915->fs->program[0]);
+      uint size = (i915->fs->decl[0]);
       size += need_target_fixup * 3;
       OUT_BATCH(size);
    }
 
-   /* output the declarations and the program */
-   for (i = 1 ; i < i915->fs->program_len; i++)
+   for (i = 1 ; i < i915->fs->decl_len; i++)
+      OUT_BATCH(i915->fs->decl[i]);
+
+   /* output the program */
+   for (i = 0 ; i < i915->fs->program_len; i++)
       OUT_BATCH(i915->fs->program[i]);
 
    /* we emit an additional mov with swizzle to fake RGBA framebuffers */