Merge branch 'mesa_7_7_branch'
[mesa.git] / src / gallium / auxiliary / draw / draw_pt_fetch_shade_emit.c
index 73fc70c1bc9fc66de4c8caafb904c6df4d734684..c5dfbcfa3cb70802f2869a21db5ffc3e7a71642e 100644 (file)
@@ -40,7 +40,6 @@
 #include "draw/draw_pt.h"
 #include "draw/draw_vs.h"
 
-#include "translate/translate.h"
 
 struct fetch_shade_emit;
 
@@ -79,6 +78,7 @@ static void fse_prepare( struct draw_pt_middle_end *middle,
    unsigned num_vs_inputs = draw->vs.vertex_shader->info.num_inputs;
    const struct vertex_info *vinfo;
    unsigned i;
+   unsigned nr_vbs = 0;
    
 
    if (!draw->render->set_primitive( draw->render, 
@@ -100,9 +100,10 @@ static void fse_prepare( struct draw_pt_middle_end *middle,
    fse->key.nr_elements = MAX2(fse->key.nr_outputs,     /* outputs - translate to hw format */
                                fse->key.nr_inputs);     /* inputs - fetch from api format */
 
-   fse->key.viewport = !draw->identity_viewport;
+   fse->key.viewport = (!draw->rasterizer->bypass_vs_clip_and_viewport &&
+                        !draw->identity_viewport);
    fse->key.clip = !draw->bypass_clipping;
-   fse->key.pad = 0;
+   fse->key.const_vbuffers = 0;
 
    memset(fse->key.element, 0, 
           fse->key.nr_elements * sizeof(fse->key.element[0]));
@@ -116,16 +117,23 @@ static void fse_prepare( struct draw_pt_middle_end *middle,
        */
       fse->key.element[i].in.buffer = src->vertex_buffer_index;
       fse->key.element[i].in.offset = src->src_offset;
+      nr_vbs = MAX2(nr_vbs, src->vertex_buffer_index + 1);
    }
    
+   for (i = 0; i < 5 && i < nr_vbs; i++) {
+      if (draw->pt.vertex_buffer[i].stride == 0)
+         fse->key.const_vbuffers |= (1<<i);
+   }
 
+   if (0) debug_printf("%s: lookup const_vbuffers: %x\n", __FUNCTION__, fse->key.const_vbuffers);
+   
    {
       unsigned dst_offset = 0;
 
       for (i = 0; i < vinfo->num_attribs; i++) {
          unsigned emit_sz = 0;
 
-         switch (vinfo->emit[i]) {
+         switch (vinfo->attrib[i].emit) {
          case EMIT_4F:
             emit_sz = 4 * sizeof(float);
             break;
@@ -153,8 +161,8 @@ static void fse_prepare( struct draw_pt_middle_end *middle,
           * numbers, not to positions in the hw vertex description --
           * that's handled by the output_offset field.
           */
-         fse->key.element[i].out.format = vinfo->emit[i];
-         fse->key.element[i].out.vs_output = vinfo->src_index[i];
+         fse->key.element[i].out.format = vinfo->attrib[i].emit;
+         fse->key.element[i].out.vs_output = vinfo->attrib[i].src_index;
          fse->key.element[i].out.offset = dst_offset;
       
          dst_offset += emit_sz;
@@ -162,13 +170,7 @@ static void fse_prepare( struct draw_pt_middle_end *middle,
       }
    }
 
-
-   /* Would normally look up a vertex shader and peruse its list of
-    * varients somehow.  We omitted that step and put all the
-    * hardcoded "shaders" into an array.  We're just making the
-    * assumption that this happens to be a matching shader...  ie
-    * you're running isosurf, aren't you?
-    */
+   
    fse->active = draw_vs_lookup_varient( draw->vs.vertex_shader, 
                                          &fse->key );
 
@@ -177,18 +179,17 @@ static void fse_prepare( struct draw_pt_middle_end *middle,
       return ;
    }
 
+   if (0) debug_printf("%s: found const_vbuffers: %x\n", __FUNCTION__, 
+                       fse->active->key.const_vbuffers);
+
    /* Now set buffer pointers:
     */
-   for (i = 0; i < num_vs_inputs; i++) {
-      unsigned buf = draw->pt.vertex_element[i].vertex_buffer_index;
-
-      fse->active->set_input( fse->active, 
-                              i, 
-                              
-                              ((const ubyte *) draw->pt.user.vbuffer[buf] + 
-                               draw->pt.vertex_buffer[buf].buffer_offset),
-                              
-                              draw->pt.vertex_buffer[buf].pitch );
+   for (i = 0; i < draw->pt.nr_vertex_buffers; i++) {
+      fse->active->set_buffer( fse->active, 
+                               i, 
+                               ((const ubyte *) draw->pt.user.vbuffer[i] + 
+                                draw->pt.vertex_buffer[i].buffer_offset),
+                              draw->pt.vertex_buffer[i].stride );
    }
 
    *max_vertices = (draw->render->max_vertex_buffer_bytes / 
@@ -210,17 +211,10 @@ static void fse_prepare( struct draw_pt_middle_end *middle,
       struct draw_vertex_shader *vs = draw->vs.vertex_shader;
       vs->prepare(vs, draw);
    }
-   
-
-   //return TRUE;
 }
 
 
 
-
-
-
-
 static void fse_run_linear( struct draw_pt_middle_end *middle, 
                             unsigned start, 
                             unsigned count )
@@ -233,14 +227,17 @@ static void fse_run_linear( struct draw_pt_middle_end *middle,
     */
    draw_do_flush( draw, DRAW_FLUSH_BACKEND );
 
-   hw_verts = draw->render->allocate_vertices( draw->render,
-                                               (ushort)fse->key.output_stride,
-                                               (ushort)count );
+   if (count >= UNDEFINED_VERTEX_ID) 
+      goto fail;
 
-   if (!hw_verts) {
-      assert(0);
-      return;
-   }
+   if (!draw->render->allocate_vertices( draw->render,
+                                         (ushort)fse->key.output_stride,
+                                         (ushort)count ))
+      goto fail;
+
+   hw_verts = draw->render->map_vertices( draw->render );
+   if (!hw_verts)
+      goto fail;
 
    /* Single routine to fetch vertices, run shader and emit HW verts.
     * Clipping is done elsewhere -- either by the API or on hardware,
@@ -250,13 +247,7 @@ static void fse_run_linear( struct draw_pt_middle_end *middle,
                             start, count,
                             hw_verts );
 
-   /* Draw arrays path to avoid re-emitting index list again and
-    * again.
-    */
-   draw->render->draw_arrays( draw->render,
-                              0,
-                              count );
-   
+
    if (0) {
       unsigned i;
       for (i = 0; i < count; i++) {
@@ -268,12 +259,24 @@ static void fse_run_linear( struct draw_pt_middle_end *middle,
                                    (const uint8_t *)hw_verts + fse->key.output_stride * i );
       }
    }
+   
+   draw->render->unmap_vertices( draw->render, 0, (ushort)(count - 1) );
 
+   /* Draw arrays path to avoid re-emitting index list again and
+    * again.
+    */
+   draw->render->draw_arrays( draw->render,
+                              0,
+                              count );
+   
 
-   draw->render->release_vertices( draw->render, 
-                                  hw_verts, 
-                                  fse->key.output_stride, 
-                                  count );
+   draw->render->release_vertices( draw->render );
+
+   return;
+
+fail:
+   assert(0);
+   return;
 }
 
 
@@ -292,13 +295,17 @@ fse_run(struct draw_pt_middle_end *middle,
     */
    draw_do_flush( draw, DRAW_FLUSH_BACKEND );
 
-   hw_verts = draw->render->allocate_vertices( draw->render,
-                                               (ushort)fse->key.output_stride,
-                                               (ushort)fetch_count );
-   if (!hw_verts) {
-      assert(0);
-      return;
-   }
+   if (fetch_count >= UNDEFINED_VERTEX_ID) 
+      goto fail;
+
+   if (!draw->render->allocate_vertices( draw->render,
+                                         (ushort)fse->key.output_stride,
+                                         (ushort)fetch_count ))
+      goto fail;
+
+   hw_verts = draw->render->map_vertices( draw->render ); 
+   if (!hw_verts) 
+      goto fail;
          
                                        
    /* Single routine to fetch vertices, run shader and emit HW verts.
@@ -308,9 +315,6 @@ fse_run(struct draw_pt_middle_end *middle,
                           fetch_count,
                           hw_verts );
 
-   draw->render->draw( draw->render, 
-                       draw_elts, 
-                       draw_count );
 
    if (0) {
       unsigned i;
@@ -322,12 +326,19 @@ fse_run(struct draw_pt_middle_end *middle,
       }
    }
 
+   draw->render->unmap_vertices( draw->render, 0, (ushort)(fetch_count - 1) );
+   
+   draw->render->draw( draw->render, 
+                       draw_elts, 
+                       draw_count );
+
 
-   draw->render->release_vertices( draw->render, 
-                                   hw_verts, 
-                                   fse->key.output_stride, 
-                                   fetch_count );
+   draw->render->release_vertices( draw->render );
+   return;
 
+fail:
+   assert(0);
+   return;
 }
 
 
@@ -346,13 +357,17 @@ static boolean fse_run_linear_elts( struct draw_pt_middle_end *middle,
     */
    draw_do_flush( draw, DRAW_FLUSH_BACKEND );
 
-   hw_verts = draw->render->allocate_vertices( draw->render,
-                                               (ushort)fse->key.output_stride,
-                                               (ushort)count );
+   if (count >= UNDEFINED_VERTEX_ID)
+      return FALSE;
+
+   if (!draw->render->allocate_vertices( draw->render,
+                                         (ushort)fse->key.output_stride,
+                                         (ushort)count ))
+      return FALSE;
 
-   if (!hw_verts) {
+   hw_verts = draw->render->map_vertices( draw->render );
+   if (!hw_verts) 
       return FALSE;
-   }
 
    /* Single routine to fetch vertices, run shader and emit HW verts.
     * Clipping is done elsewhere -- either by the API or on hardware,
@@ -368,11 +383,9 @@ static boolean fse_run_linear_elts( struct draw_pt_middle_end *middle,
                        draw_count );
    
 
+   draw->render->unmap_vertices( draw->render, 0, (ushort)(count - 1) );
 
-   draw->render->release_vertices( draw->render, 
-                                  hw_verts, 
-                                  fse->key.output_stride, 
-                                  count );
+   draw->render->release_vertices( draw->render );
 
    return TRUE;
 }