Cell: propogate vertex info to SPUs, use it for attrib interpolation
authorBrian <brian.paul@tungstengraphics.com>
Fri, 25 Jan 2008 15:17:52 +0000 (08:17 -0700)
committerBrian <brian.paul@tungstengraphics.com>
Fri, 25 Jan 2008 15:20:10 +0000 (08:20 -0700)
src/mesa/pipe/cell/common.h
src/mesa/pipe/cell/ppu/cell_state.h
src/mesa/pipe/cell/ppu/cell_state_derived.c
src/mesa/pipe/cell/ppu/cell_state_emit.c
src/mesa/pipe/cell/spu/spu_main.c
src/mesa/pipe/cell/spu/spu_main.h
src/mesa/pipe/cell/spu/spu_tri.c

index 5c437daac6fceecda8e33d7ea72c9177ca571c23..af7f27bc831652458adbebe744d66d311486b052 100644 (file)
@@ -64,6 +64,7 @@
 #define CELL_CMD_BATCH         6
 #define CELL_CMD_STATE_DEPTH_STENCIL 7
 #define CELL_CMD_STATE_SAMPLER       8
+#define CELL_CMD_STATE_VERTEX_INFO   9
 
 
 #define CELL_NUM_BATCH_BUFFERS 3
@@ -103,11 +104,11 @@ struct cell_command_clear_surface
 
 struct cell_command_render
 {
-   uint opcode;
-   uint prim_type;
+   uint opcode;       /**< CELL_CMD_RENDER */
+   uint prim_type;    /**< PIPE_PRIM_x */
    uint num_verts;
    uint vertex_size;  /**< bytes per vertex */
-   uint dummy;       /* XXX this dummy field works around a compiler bug */
+   uint dummy;        /* XXX this dummy field works around a compiler bug */
    uint num_indexes;
    const void *vertex_data;
    const ushort *index_data;
index fbca7c95744b367da07153dbf1f23e24f10ce52d..3a71ba14fa8f30265d6132db3a77558e1598cdcd 100644 (file)
@@ -19,6 +19,7 @@
 #define CELL_NEW_VERTEX        0x1000
 #define CELL_NEW_VS            0x2000
 #define CELL_NEW_CONSTANTS     0x4000
+#define CELL_NEW_VERTEX_INFO   0x8000
 
 
 
index f3b3ae8544dc551c1ef4b78222afba9d26218c52..56daf5dfde0e183ae12e6d37615eee9a20968fb1 100644 (file)
@@ -30,6 +30,7 @@
 #include "pipe/draw/draw_context.h"
 #include "pipe/draw/draw_vertex.h"
 #include "cell_context.h"
+#include "cell_batch.h"
 #include "cell_state.h"
 #include "cell_state_emit.h"
 
@@ -85,6 +86,7 @@ calculate_vertex_layout( struct cell_context *cell )
    assert(src >= 0);
    draw_emit_vertex_attr(vinfo, EMIT_4F, INTERP_POS, src);
 
+
    /*
     * Loop over fragment shader inputs, searching for the matching output
     * from the vertex shader.
@@ -126,6 +128,9 @@ calculate_vertex_layout( struct cell_context *cell )
    }
 
    draw_compute_vertex_size(vinfo);
+
+   /* XXX only signal this if format really changes */
+   cell->dirty |= CELL_NEW_VERTEX_INFO;
 }
 
 
index e7d14d0d252d137c05259f706fe13e09d1ff161f..e5b7c925143b25c117611d42b0969ad6d58d6910 100644 (file)
@@ -49,4 +49,10 @@ cell_emit_state(struct cell_context *cell)
       cell_batch_append(cell, cell->sampler[0],
                         sizeof(struct pipe_sampler_state));
    }
+
+   if (cell->dirty & CELL_NEW_VERTEX_INFO) {
+      uint cmd = CELL_CMD_STATE_VERTEX_INFO;
+      cell_batch_append(cell, &cmd, 4);
+      cell_batch_append(cell, &cell->vertex_info, sizeof(struct vertex_info));
+   }
 }
index 1d0de7b1f9ea3375d941c914d1b9c90c4ed099e6..880f8de550ec819f8f506a29b1135ecea658839b 100644 (file)
@@ -390,6 +390,17 @@ cmd_state_sampler(const struct pipe_sampler_state *state)
 }
 
 
+static void
+cmd_state_vertex_info(const struct vertex_info *vinfo)
+{
+   if (Debug)
+      printf("SPU %u: VERTEX_INFO num_attribs=%u\n", spu.init.id,
+             vinfo->num_attribs);
+   memcpy(&spu.vertex_info, vinfo, sizeof(*vinfo));
+}
+
+
+
 static void
 cmd_finish(void)
 {
@@ -472,7 +483,6 @@ cmd_batch(uint opcode)
    /* Tell PPU we're done copying the buffer to local store */
    release_batch_buffer(buf);
 
-
    for (pos = 0; pos < usize; /* no incr */) {
       switch (buffer[pos]) {
       case CELL_CMD_FRAMEBUFFER:
@@ -509,10 +519,13 @@ cmd_batch(uint opcode)
          pos += (1 + sizeof(struct pipe_depth_stencil_alpha_state) / 4);
          break;
       case CELL_CMD_STATE_SAMPLER:
-         cmd_state_sampler((struct pipe_sampler_state *)
-                           &buffer[pos+1]);
+         cmd_state_sampler((struct pipe_sampler_state *) &buffer[pos+1]);
          pos += (1 + sizeof(struct pipe_sampler_state) / 4);
          break;
+      case CELL_CMD_STATE_VERTEX_INFO:
+         cmd_state_vertex_info((struct vertex_info *) &buffer[pos+1]);
+         pos += (1 + sizeof(struct vertex_info) / 4);
+         break;
       default:
          printf("SPU %u: bad opcode: 0x%x\n", spu.init.id, buffer[pos]);
          ASSERT(0);
index 3ef73c9473dc8df7805c703bda69eb6942e7e90b..e4359bf60d0a647fb9b45358e953db85722f8d14 100644 (file)
@@ -30,6 +30,7 @@
 
 
 #include "pipe/cell/common.h"
+#include "pipe/draw/draw_vertex.h"
 #include "pipe/p_state.h"
 
 
@@ -59,6 +60,9 @@ struct spu_global
    struct pipe_depth_stencil_alpha_state depth_stencil;
    struct pipe_blend_state blend;
    struct pipe_sampler_state sampler[PIPE_MAX_SAMPLERS];
+
+   struct vertex_info vertex_info;
+
    /* XXX more state to come */
 
 } ALIGN16_ATTRIB;
index 1d73c5171ce67c2fdbdb9a30cf098b7aa7a202db..3d0d106c10e0e1b5118e7f9b41f7f484f579269d 100644 (file)
@@ -42,7 +42,7 @@
  * Simplified types taken from other parts of Gallium
  */
 struct vertex_header {
-   float data[2][4];  /* pos and color */
+   float data[0][4];
 };
 
 struct prim_header {
@@ -727,40 +727,32 @@ static void tri_persp_coeff( struct setup_stage *setup,
  */
 static void setup_tri_coefficients( struct setup_stage *setup )
 {
-#if 0
-   const enum interp_mode *interp = setup->softpipe->vertex_info.interp_mode;
-   unsigned slot, j;
-
-   /* z and w are done by linear interpolation:
-    */
-   tri_linear_coeff(setup, 0, 2);
-   tri_linear_coeff(setup, 0, 3);
+#if 1
+   uint i;
 
-   /* setup interpolation for all the remaining attributes:
-    */
-   for (slot = 1; slot < setup->quad.nr_attrs; slot++) {
-      switch (interp[slot]) {
+   for (i = 0; i < spu.vertex_info.num_attribs; i++) {
+      switch (spu.vertex_info.interp_mode[i]) {
+      case INTERP_NONE:
+         break;
+      case INTERP_POS:
+         tri_linear_coeff(setup, i, 2, 3);  /* slot 0, z */
+         /* XXX interp W if PERSPECTIVE... */
+         break;
       case INTERP_CONSTANT:
-        for (j = 0; j < NUM_CHANNELS; j++)
-           const_coeff(setup, slot, j);
-        break;
-      
+         /* fall-through */
       case INTERP_LINEAR:
-        for (j = 0; j < NUM_CHANNELS; j++)
-           tri_linear_coeff(setup, slot, j);
-        break;
-
+         tri_linear_coeff(setup, i, 0, 4);  /* slot 1, color */
+         break;
       case INTERP_PERSPECTIVE:
-        for (j = 0; j < NUM_CHANNELS; j++)
-           tri_persp_coeff(setup, slot, j);
-        break;
-
+         break;
       default:
-         /* invalid interp mode */
-         assert(0);
+         ASSERT(0);
       }
    }
 #else
+   ASSERT(spu.vertex_info.interp_mode[0] == INTERP_POS);
+   ASSERT(spu.vertex_info.interp_mode[1] == INTERP_LINEAR ||
+          spu.vertex_info.interp_mode[1] == INTERP_CONSTANT);
    tri_linear_coeff(setup, 0, 2, 3);  /* slot 0, z */
    tri_linear_coeff(setup, 1, 0, 4);  /* slot 1, color */
 #endif