draw: fetch_shade_pipeline needs to translate to hw vertex format (from get_vertex_info)
authorKeith Whitwell <keith@tungstengraphics.com>
Tue, 15 Apr 2008 13:28:41 +0000 (14:28 +0100)
committerKeith Whitwell <keith@tungstengraphics.com>
Tue, 15 Apr 2008 13:30:06 +0000 (14:30 +0100)
src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline.c

index 04b3d2c4cfb770013509e43dc2d73a5cf44e8224..557cd43f5b15b299d0940f4a74dc4777068681bb 100644 (file)
@@ -36,52 +36,60 @@ struct fetch_pipeline_middle_end {
    struct draw_pt_middle_end base;
    struct draw_context *draw;
 
+   const ubyte *input_buf[2];
+
    struct {
-      const ubyte *ptr;
-      unsigned pitch;
-      void (*fetch)( const void *from, float *attrib);
-      void (*emit)( const float *attrib, float **out );
-   } fetch[PIPE_MAX_ATTRIBS];
+      const ubyte **input_buf;
+      unsigned input_offset;
+      unsigned output_offset;
+
+      void (*emit)( const float *attrib, void *ptr );
+   } translate[PIPE_MAX_ATTRIBS];
+   unsigned nr_translate;
 
-   unsigned nr_fetch;
    unsigned pipeline_vertex_size;
    unsigned hw_vertex_size;
    unsigned prim;
 };
 
-#if 0
+
+static void emit_NULL( const float *attrib,
+                      void *ptr )
+{
+}
+
 static void emit_R32_FLOAT( const float *attrib,
-                            float **out )
+                            void *ptr )
 {
-   (*out)[0] = attrib[0];
-   (*out) += 1;
+   float *out = (float *)ptr;
+   out[0] = attrib[0];
 }
 
 static void emit_R32G32_FLOAT( const float *attrib,
-                               float **out )
+                               void *ptr )
 {
-   (*out)[0] = attrib[0];
-   (*out)[1] = attrib[1];
-   (*out) += 2;
+   float *out = (float *)ptr;
+   out[0] = attrib[0];
+   out[1] = attrib[1];
 }
 
 static void emit_R32G32B32_FLOAT( const float *attrib,
-                                  float **out )
+                                  void *ptr )
 {
-   (*out)[0] = attrib[0];
-   (*out)[1] = attrib[1];
-   (*out)[2] = attrib[2];
-   (*out) += 3;
+   float *out = (float *)ptr;
+   out[0] = attrib[0];
+   out[1] = attrib[1];
+   out[2] = attrib[2];
 }
-#endif
+
 static void emit_R32G32B32A32_FLOAT( const float *attrib,
-                                     float **out )
+                                     void *ptr )
 {
-   (*out)[0] = attrib[0];
-   (*out)[1] = attrib[1];
-   (*out)[2] = attrib[2];
-   (*out)[3] = attrib[3];
-   (*out) += 4;
+   float *out = (float *)ptr;
+   out[0] = attrib[0];
+   out[1] = attrib[1];
+   out[2] = attrib[2];
+   out[3] = attrib[3];
 }
 
 static void fetch_pipeline_prepare( struct draw_pt_middle_end *middle,
@@ -89,9 +97,10 @@ static void fetch_pipeline_prepare( struct draw_pt_middle_end *middle,
 {
    struct fetch_pipeline_middle_end *fpme = (struct fetch_pipeline_middle_end *)middle;
    struct draw_context *draw = fpme->draw;
-   unsigned i, nr = 0;
+   unsigned i;
    boolean ok;
    const struct vertex_info *vinfo;
+   unsigned dst_offset;
 
    fpme->prim = prim;
 
@@ -100,33 +109,63 @@ static void fetch_pipeline_prepare( struct draw_pt_middle_end *middle,
       assert(0);
       return;
    }
+
    /* Must do this after set_primitive() above:
     */
    vinfo = draw->render->get_vertex_info(draw->render);
 
-   /* Need to look at vertex shader inputs (we know it is a
-    * passthrough shader, so these define the outputs too).  If we
-    * were running a shader, we'd still be looking at the inputs at
-    * this point.
-    */
-   for (i = 0; i < draw->vertex_shader->info.num_inputs; i++) {
-      unsigned buf = draw->vertex_element[i].vertex_buffer_index;
-      enum pipe_format format  = draw->vertex_element[i].src_format;
-
-      fpme->fetch[nr].ptr = ((const ubyte *) draw->user.vbuffer[buf] +
-                            draw->vertex_buffer[buf].buffer_offset +
-                            draw->vertex_element[i].src_offset);
 
-      fpme->fetch[nr].pitch = draw->vertex_buffer[buf].pitch;
-      fpme->fetch[nr].fetch = draw_get_fetch_func( format );
+   /* In passthrough mode, need to translate from vertex shader
+    * outputs to hw vertices.
+    */
+   dst_offset = 0;
+   for (i = 0; i < vinfo->num_attribs; i++) {
+      unsigned emit_sz = 0;
+      unsigned src_buffer = 0;
+      unsigned src_offset = (sizeof(struct vertex_header) + 
+                            vinfo->src_index[i] * 4 * sizeof(float) );
+
+
+         
+      switch (vinfo->emit[i]) {
+      case EMIT_4F:
+         fpme->translate[i].emit = emit_R32G32B32A32_FLOAT;
+        emit_sz = 4 * sizeof(float);
+         break;
+      case EMIT_3F:
+         fpme->translate[i].emit = emit_R32G32B32_FLOAT;
+        emit_sz = 3 * sizeof(float);
+         break;
+      case EMIT_2F:
+         fpme->translate[i].emit = emit_R32G32_FLOAT;
+        emit_sz = 2 * sizeof(float);
+         break;
+      case EMIT_1F:
+         fpme->translate[i].emit = emit_R32_FLOAT;
+        emit_sz = 1 * sizeof(float);
+         break;
+      case EMIT_1F_PSIZE:
+         fpme->translate[i].emit = emit_R32_FLOAT;
+        emit_sz = 1 * sizeof(float);
+         src_buffer = 1;
+        src_offset = 0;
+         break;
+      default:
+         assert(0);
+         fpme->translate[i].emit = emit_NULL;
+        emit_sz = 0;
+         break;
+      }
 
-      /* Always do this -- somewhat redundant...
-       */
-      fpme->fetch[nr].emit = emit_R32G32B32A32_FLOAT;
-      nr++;
+      fpme->translate[i].input_buf = &fpme->input_buf[src_buffer];
+      fpme->translate[i].input_offset = src_offset;
+      fpme->translate[i].output_offset = dst_offset;
+      dst_offset += emit_sz;
    }
 
-   fpme->nr_fetch = nr;
+   fpme->nr_translate = vinfo->num_attribs;
+   fpme->hw_vertex_size = vinfo->size * 4;
+
    //fpme->pipeline_vertex_size = sizeof(struct vertex_header) + nr * 4 * sizeof(float);
    fpme->pipeline_vertex_size = MAX_VERTEX_ALLOCATION;
    fpme->hw_vertex_size = vinfo->size * 4;
@@ -171,7 +210,7 @@ static void fetch_pipeline_run( struct draw_pt_middle_end *middle,
    } else {
       unsigned i, j;
       void *hw_verts;
-      float *out;
+      char *out_buf;
 
       /* XXX: need to flush to get prim_vbuf.c to release its allocation?? 
        */
@@ -185,22 +224,29 @@ static void fetch_pipeline_run( struct draw_pt_middle_end *middle,
          return;
       }
 
-      out = (float *)hw_verts;
+      out_buf = (char *)hw_verts;
+      fpme->input_buf[0] = (const ubyte *)pipeline_verts;
+      fpme->input_buf[1] = (const ubyte *)&fpme->draw->rasterizer->point_size;
+
       for (i = 0; i < fetch_count; i++) {
-         struct vertex_header *header =
-            (struct vertex_header*)(pipeline_verts + (fpme->pipeline_vertex_size * i));
 
-         for (j = 0; j < fpme->nr_fetch; j++) {
-            float *attrib = header->data[j];
+         for (j = 0; j < fpme->nr_translate; j++) {
+
+            const float *attrib = (const float *)( (*fpme->translate[i].input_buf) + 
+                                                  fpme->translate[i].input_offset );
+
+           char *dest = out_buf + fpme->translate[i].output_offset;
+
             /*debug_printf("emiting [%f, %f, %f, %f]\n",
                          attrib[0], attrib[1],
                          attrib[2], attrib[3]);*/
-            fpme->fetch[j].emit(attrib, &out);
+
+            fpme->translate[j].emit(attrib, dest);
          }
+
+        fpme->input_buf[0] += fpme->pipeline_vertex_size;
       }
-      /* XXX: Draw arrays path to avoid re-emitting index list again and
-       * again.
-       */
+
       draw->render->draw(draw->render,
                          draw_elts,
                          draw_count);