gallium: add a couple of hardwired vertex fetch functions
authorKeith Whitwell <keith@tungstengraphics.com>
Mon, 28 Jan 2008 12:40:29 +0000 (12:40 +0000)
committerBen Skeggs <skeggsb@gmail.com>
Fri, 15 Feb 2008 02:50:22 +0000 (13:50 +1100)
src/mesa/pipe/draw/draw_private.h
src/mesa/pipe/draw/draw_vertex_fetch.c
src/mesa/pipe/draw/draw_vertex_shader.c

index 1e59f5bd8d933da536202bcad592a9c1f014e43a..21de4006769579a4be9a913c05a5ac678e611af4 100644 (file)
@@ -141,6 +141,10 @@ struct draw_vertex_shader {
 /* Internal function for vertex fetch.
  */
 typedef void (*fetch_func)(const void *ptr, float *attrib);
+typedef void (*full_fetch_func)( struct draw_context *draw,
+                                struct tgsi_exec_machine *machine,
+                                const unsigned *elts,
+                                unsigned count );
 
 
 
@@ -210,6 +214,7 @@ struct draw_context
       unsigned pitch[PIPE_ATTRIB_MAX];
       fetch_func fetch[PIPE_ATTRIB_MAX];
       unsigned nr_attrs;
+      full_fetch_func fetch_func;
    } vertex_fetch;
 
    /* Post-tnl vertex cache:
@@ -287,10 +292,6 @@ extern void draw_vertex_shader_queue_flush_llvm( struct draw_context *draw );
 struct tgsi_exec_machine;
 
 extern void draw_update_vertex_fetch( struct draw_context *draw );
-extern void draw_vertex_fetch( struct draw_context *draw,
-                              struct tgsi_exec_machine *machine,
-                              const unsigned *elts,
-                              unsigned count );
 
 
 #define DRAW_FLUSH_SHADER_QUEUE              0x1 /* sized not to overflow, never raised */
index 143acdd3b49a65f1e9dd164f2bfa7230eca0b15b..afdf1971d2400985addb906a9cd37c5fb28d128c 100644 (file)
@@ -320,42 +320,101 @@ transpose_4x4( float *out, const float *in )
 }
 
 
-                              
-void draw_update_vertex_fetch( struct draw_context *draw )
+
+static void fetch_xyz_rgb( struct draw_context *draw,
+                          struct tgsi_exec_machine *machine,
+                          const unsigned *elts,
+                          unsigned count )
 {
-   unsigned nr_attrs, i;
+   assert(count <= 4);
 
 //   _mesa_printf("%s\n", __FUNCTION__);
-   
-   /* this may happend during context init */
-   if (!draw->vertex_shader)
-      return;
 
-   nr_attrs = draw->vertex_shader->state->num_inputs;
+   /* loop over vertex attributes (vertex shader inputs)
+    */
 
-   for (i = 0; i < nr_attrs; i++) {
-      unsigned buf = draw->vertex_element[i].vertex_buffer_index;
-      enum pipe_format format  = draw->vertex_element[i].src_format;
+   const unsigned *pitch   = draw->vertex_fetch.pitch;
+   const ubyte **src       = draw->vertex_fetch.src_ptr;
+   int i;
+
+   for (i = 0; i < 4; i++) {
+      {
+        const float *in = (const float *)(src[0] + elts[i] * pitch[0]);
+        float *out = &machine->Inputs[0].xyzw[0].f[i];
+        out[0] = in[0];
+        out[4] = in[1];
+        out[8] = in[2];
+        out[12] = 1.0f;
+      }
+
+      {
+        const float *in = (const float *)(src[1] + elts[i] * pitch[1]);
+        float *out = &machine->Inputs[1].xyzw[0].f[i];
+        out[0] = in[0];
+        out[4] = in[1];
+        out[8] = in[2];
+        out[12] = 1.0f;
+      }
+   }
+}
 
-      draw->vertex_fetch.src_ptr[i] = (const ubyte *) draw->user.vbuffer[buf] + 
-                                                      draw->vertex_buffer[buf].buffer_offset + 
-                                                      draw->vertex_element[i].src_offset;
 
-      draw->vertex_fetch.pitch[i] = draw->vertex_buffer[buf].pitch;
-      draw->vertex_fetch.fetch[i] = get_fetch_func( format );
-   }
 
-   draw->vertex_fetch.nr_attrs = nr_attrs;
+
+static void fetch_xyz_rgb_st( struct draw_context *draw,
+                             struct tgsi_exec_machine *machine,
+                             const unsigned *elts,
+                             unsigned count )
+{
+   assert(count <= 4);
+
+   /* loop over vertex attributes (vertex shader inputs)
+    */
+
+   const unsigned *pitch   = draw->vertex_fetch.pitch;
+   const ubyte **src       = draw->vertex_fetch.src_ptr;
+   int i;
+
+   for (i = 0; i < 4; i++) {
+      {
+        const float *in = (const float *)(src[0] + elts[i] * pitch[0]);
+        float *out = &machine->Inputs[0].xyzw[0].f[i];
+        out[0] = in[0];
+        out[4] = in[1];
+        out[8] = in[2];
+        out[12] = 1.0f;
+      }
+
+      {
+        const float *in = (const float *)(src[1] + elts[i] * pitch[1]);
+        float *out = &machine->Inputs[1].xyzw[0].f[i];
+        out[0] = in[0];
+        out[4] = in[1];
+        out[8] = in[2];
+        out[12] = 1.0f;
+      }
+
+      {
+        const float *in = (const float *)(src[2] + elts[i] * pitch[2]);
+        float *out = &machine->Inputs[1].xyzw[0].f[i];
+        out[0] = in[0];
+        out[4] = in[1];
+        out[8] = 0.0f;
+        out[12] = 1.0f;
+      }
+   }
 }
 
 
+
+
 /**
  * Fetch vertex attributes for 'count' vertices.
  */
-void draw_vertex_fetch( struct draw_context *draw,
-                       struct tgsi_exec_machine *machine,
-                       const unsigned *elts,
-                       unsigned count )
+static void generic_vertex_fetch( struct draw_context *draw,
+                                 struct tgsi_exec_machine *machine,
+                                 const unsigned *elts,
+                                 unsigned count )
 {
    unsigned nr_attrs = draw->vertex_fetch.nr_attrs;
    unsigned attr;
@@ -402,3 +461,50 @@ void draw_vertex_fetch( struct draw_context *draw,
    }
 }
 
+
+                              
+void draw_update_vertex_fetch( struct draw_context *draw )
+{
+   unsigned nr_attrs, i;
+
+//   _mesa_printf("%s\n", __FUNCTION__);
+   
+   /* this may happend during context init */
+   if (!draw->vertex_shader)
+      return;
+
+   nr_attrs = draw->vertex_shader->state->num_inputs;
+
+   for (i = 0; i < nr_attrs; i++) {
+      unsigned buf = draw->vertex_element[i].vertex_buffer_index;
+      enum pipe_format format  = draw->vertex_element[i].src_format;
+
+      draw->vertex_fetch.src_ptr[i] = (const ubyte *) draw->user.vbuffer[buf] + 
+                                                      draw->vertex_buffer[buf].buffer_offset + 
+                                                      draw->vertex_element[i].src_offset;
+
+      draw->vertex_fetch.pitch[i] = draw->vertex_buffer[buf].pitch;
+      draw->vertex_fetch.fetch[i] = get_fetch_func( format );
+   }
+
+   draw->vertex_fetch.nr_attrs = nr_attrs;
+
+   draw->vertex_fetch.fetch_func = generic_vertex_fetch;
+
+   switch (nr_attrs) {
+   case 2:
+      if (draw->vertex_element[0].src_format == PIPE_FORMAT_R32G32B32_FLOAT &&
+         draw->vertex_element[1].src_format == PIPE_FORMAT_R32G32B32_FLOAT)
+        draw->vertex_fetch.fetch_func = fetch_xyz_rgb;
+      break;
+   case 3:
+      if (draw->vertex_element[0].src_format == PIPE_FORMAT_R32G32B32_FLOAT &&
+         draw->vertex_element[1].src_format == PIPE_FORMAT_R32G32B32_FLOAT &&
+         draw->vertex_element[1].src_format == PIPE_FORMAT_R32G32_FLOAT)
+        draw->vertex_fetch.fetch_func = fetch_xyz_rgb_st;
+      break;
+   default:
+      break;
+   }
+
+}
index 289c35c7ae402abd54303a7ad31783431a7b12a4..0806e23d6c461070628bf47427a9b0e4313a0520 100644 (file)
@@ -110,7 +110,7 @@ run_vertex_program(struct draw_context *draw,
    machine->Inputs = ALIGN16_ASSIGN(inputs);
    machine->Outputs = ALIGN16_ASSIGN(outputs);
 
-   draw_vertex_fetch( draw, machine, elts, count );
+   draw->vertex_fetch.fetch_func( draw, machine, elts, count );
 
    /* run shader */
 #if defined(__i386__) || defined(__386__)
@@ -219,14 +219,18 @@ draw_vertex_shader_queue_flush(struct draw_context *draw)
    for (i = 0; i < draw->vs.queue_nr; i += 4) {
       struct vertex_header *dests[4];
       unsigned elts[4];
-      int n;
+      int n = MIN2(4, draw->vs.queue_nr - i);
 
-      for (j = 0; j < 4; j++) {
+      for (j = 0; j < n; j++) {
          elts[j] = draw->vs.queue[i + j].elt;
          dests[j] = draw->vs.queue[i + j].dest;
       }
 
-      n = MIN2(4, draw->vs.queue_nr - i);
+      for ( ; j < 4; j++) {
+        elts[j] = elts[0];
+        dests[j] = dests[0];
+      }
+
       assert(n > 0);
       assert(n <= 4);