Merge remote branch 'origin/master' into nv50-compiler
[mesa.git] / src / gallium / auxiliary / draw / draw_pt_fetch_emit.c
index 39159b747da95b3cbb80e8f5bdaced4340131119..e706b7796f82249e451196a61a5494ae208d03f4 100644 (file)
@@ -36,6 +36,7 @@
 #include "draw/draw_vbuf.h"
 #include "draw/draw_vertex.h"
 #include "draw/draw_pt.h"
+#include "draw/draw_gs.h"
 #include "translate/translate.h"
 #include "translate/translate_cache.h"
 
@@ -100,9 +101,14 @@ static void fetch_emit_prepare( struct draw_pt_middle_end *middle,
    boolean ok;
    struct translate_key key;
 
+   unsigned gs_out_prim = (draw->gs.geometry_shader ? 
+                           draw->gs.geometry_shader->output_primitive :
+                           prim);
+
+
 
    ok = draw->render->set_primitive( draw->render, 
-                                     prim );
+                                     gs_out_prim );
    if (!ok) {
       assert(0);
       return;
@@ -129,40 +135,23 @@ static void fetch_emit_prepare( struct draw_pt_middle_end *middle,
       unsigned input_offset = src->src_offset;
       unsigned output_format;
 
-      switch (vinfo->attrib[i].emit) {
-      case EMIT_4F:
-        output_format = PIPE_FORMAT_R32G32B32A32_FLOAT;
-        emit_sz = 4 * sizeof(float);
-         break;
-      case EMIT_3F:
-        output_format = PIPE_FORMAT_R32G32B32_FLOAT;
-        emit_sz = 3 * sizeof(float);
-         break;
-      case EMIT_2F:
-        output_format = PIPE_FORMAT_R32G32_FLOAT;
-        emit_sz = 2 * sizeof(float);
-         break;
-      case EMIT_1F:
-        output_format = PIPE_FORMAT_R32_FLOAT;
-        emit_sz = 1 * sizeof(float);
-         break;
-      case EMIT_1F_PSIZE:
+      output_format = draw_translate_vinfo_format(vinfo->attrib[i].emit);
+      emit_sz = draw_translate_vinfo_size(vinfo->attrib[i].emit);
+
+      if (vinfo->attrib[i].emit == EMIT_OMIT)
+        continue;
+
+      if (vinfo->attrib[i].emit == EMIT_1F_PSIZE) {
         input_format = PIPE_FORMAT_R32_FLOAT;
         input_buffer = draw->pt.nr_vertex_buffers;
         input_offset = 0;
-        output_format = PIPE_FORMAT_R32_FLOAT;
-        emit_sz = 1 * sizeof(float);
-         break;
-      default:
-         assert(0);
-        output_format = PIPE_FORMAT_NONE;
-        emit_sz = 0;
-        continue;
       }
 
+      key.element[i].type = TRANSLATE_ELEMENT_NORMAL;
       key.element[i].input_format = input_format;
       key.element[i].input_buffer = input_buffer;
       key.element[i].input_offset = input_offset;
+      key.element[i].instance_divisor = src->instance_divisor;
       key.element[i].output_format = output_format;
       key.element[i].output_offset = dst_offset;
       
@@ -185,7 +174,8 @@ static void fetch_emit_prepare( struct draw_pt_middle_end *middle,
       feme->translate->set_buffer(feme->translate, 
                                  draw->pt.nr_vertex_buffers, 
                                  &feme->point_size,
-                                 0);
+                                 0,
+                                 ~0);
    }
    
    feme->point_size = draw->rasterizer->point_size;
@@ -195,20 +185,12 @@ static void fetch_emit_prepare( struct draw_pt_middle_end *middle,
                                   i, 
                                   ((char *)draw->pt.user.vbuffer[i] + 
                                    draw->pt.vertex_buffer[i].buffer_offset),
-                                  draw->pt.vertex_buffer[i].pitch );
+                                  draw->pt.vertex_buffer[i].stride,
+                                  draw->pt.vertex_buffer[i].max_index);
    }
 
    *max_vertices = (draw->render->max_vertex_buffer_bytes / 
                     (vinfo->size * 4));
-
-   /* Return an even number of verts.
-    * This prevents "parity" errors when splitting long triangle strips which
-    * can lead to front/back culling mix-ups.
-    * Every other triangle in a strip has an alternate front/back orientation
-    * so splitting at an odd position can cause the orientation of subsequent
-    * triangles to get reversed.
-    */
-   *max_vertices = *max_vertices & ~1;
 }
 
 
@@ -219,7 +201,8 @@ static void fetch_emit_run( struct draw_pt_middle_end *middle,
                             const unsigned *fetch_elts,
                             unsigned fetch_count,
                             const ushort *draw_elts,
-                            unsigned draw_count )
+                            unsigned draw_count,
+                            unsigned prim_flags )
 {
    struct fetch_emit_middle_end *feme = (struct fetch_emit_middle_end *)middle;
    struct draw_context *draw = feme->draw;
@@ -229,14 +212,11 @@ static void fetch_emit_run( struct draw_pt_middle_end *middle,
     */
    draw_do_flush( draw, DRAW_FLUSH_BACKEND );
 
-   if (fetch_count >= UNDEFINED_VERTEX_ID) {
-      assert(0);
-      return;
-   }
+   draw->render->allocate_vertices( draw->render,
+                                    (ushort)feme->translate->key.output_stride,
+                                    (ushort)fetch_count );
 
-   hw_verts = draw->render->allocate_vertices( draw->render,
-                                               (ushort)feme->translate->key.output_stride,
-                                               (ushort)fetch_count );
+   hw_verts = draw->render->map_vertices( draw->render );
    if (!hw_verts) {
       assert(0);
       return;
@@ -248,6 +228,7 @@ static void fetch_emit_run( struct draw_pt_middle_end *middle,
    feme->translate->run_elts( feme->translate, 
                              fetch_elts,
                              fetch_count,
+                              draw->instance_id,
                              hw_verts );
 
    if (0) {
@@ -259,26 +240,28 @@ static void fetch_emit_run( struct draw_pt_middle_end *middle,
       }
    }
 
+   draw->render->unmap_vertices( draw->render, 
+                                 0, 
+                                 (ushort)(fetch_count - 1) );
+
    /* XXX: Draw arrays path to avoid re-emitting index list again and
     * again.
     */
-   draw->render->draw( draw->render, 
-                       draw_elts, 
-                       draw_count );
+   draw->render->draw_elements( draw->render, 
+                                draw_elts, 
+                                draw_count );
 
    /* Done -- that was easy, wasn't it: 
     */
-   draw->render->release_vertices( draw->render, 
-                                   hw_verts, 
-                                   feme->translate->key.output_stride, 
-                                   fetch_count );
+   draw->render->release_vertices( draw->render );
 
 }
 
 
 static void fetch_emit_run_linear( struct draw_pt_middle_end *middle,
                                    unsigned start,
-                                   unsigned count )
+                                   unsigned count,
+                                   unsigned prim_flags )
 {
    struct fetch_emit_middle_end *feme = (struct fetch_emit_middle_end *)middle;
    struct draw_context *draw = feme->draw;
@@ -288,24 +271,21 @@ static void fetch_emit_run_linear( struct draw_pt_middle_end *middle,
     */
    draw_do_flush( draw, DRAW_FLUSH_BACKEND );
 
-   if (count >= UNDEFINED_VERTEX_ID)
-      assert(0);
-      return;
-   }
+   if (!draw->render->allocate_vertices( draw->render,
+                                         (ushort)feme->translate->key.output_stride,
+                                         (ushort)count )) 
+      goto fail;
 
-   hw_verts = draw->render->allocate_vertices( draw->render,
-                                               (ushort)feme->translate->key.output_stride,
-                                               (ushort)count );
-   if (!hw_verts) {
-      assert(0);
-      return;
-   }
+   hw_verts = draw->render->map_vertices( draw->render );
+   if (!hw_verts) 
+      goto fail;
 
    /* Single routine to fetch vertices and emit HW verts.
     */
    feme->translate->run( feme->translate,
                          start,
                          count,
+                         draw->instance_id,
                          hw_verts );
 
    if (0) {
@@ -317,20 +297,21 @@ static void fetch_emit_run_linear( struct draw_pt_middle_end *middle,
       }
    }
 
+   draw->render->unmap_vertices( draw->render, 0, count - 1 );
+
    /* XXX: Draw arrays path to avoid re-emitting index list again and
     * again.
     */
-   draw->render->draw_arrays( draw->render,
-                              0, /*start*/
-                              count );
+   draw->render->draw_arrays( draw->render, 0, count );
 
    /* Done -- that was easy, wasn't it:
     */
-   draw->render->release_vertices( draw->render,
-                                   hw_verts,
-                                   feme->translate->key.output_stride,
-                                   count );
+   draw->render->release_vertices( draw->render );
+   return;
 
+fail:
+   assert(0);
+   return;
 }
 
 
@@ -338,7 +319,8 @@ static boolean fetch_emit_run_linear_elts( struct draw_pt_middle_end *middle,
                                         unsigned start,
                                         unsigned count,
                                         const ushort *draw_elts,
-                                        unsigned draw_count )
+                                        unsigned draw_count,
+                                        unsigned prim_flags )
 {
    struct fetch_emit_middle_end *feme = (struct fetch_emit_middle_end *)middle;
    struct draw_context *draw = feme->draw;
@@ -348,12 +330,12 @@ static boolean fetch_emit_run_linear_elts( struct draw_pt_middle_end *middle,
     */
    draw_do_flush( draw, DRAW_FLUSH_BACKEND );
 
-   if (count >= UNDEFINED_VERTEX_ID)
+   if (!draw->render->allocate_vertices( draw->render,
+                                         (ushort)feme->translate->key.output_stride,
+                                         (ushort)count ))
       return FALSE;
 
-   hw_verts = draw->render->allocate_vertices( draw->render,
-                                               (ushort)feme->translate->key.output_stride,
-                                               (ushort)count );
+   hw_verts = draw->render->map_vertices( draw->render );
    if (!hw_verts) 
       return FALSE;
 
@@ -362,21 +344,21 @@ static boolean fetch_emit_run_linear_elts( struct draw_pt_middle_end *middle,
    feme->translate->run( feme->translate,
                          start,
                          count,
+                         draw->instance_id,
                          hw_verts );
 
+   draw->render->unmap_vertices( draw->render, 0, (ushort)(count - 1) );
+
    /* XXX: Draw arrays path to avoid re-emitting index list again and
     * again.
     */
-   draw->render->draw( draw->render, 
-                       draw_elts, 
-                       draw_count );
+   draw->render->draw_elements( draw->render, 
+                                draw_elts, 
+                                draw_count );
 
    /* Done -- that was easy, wasn't it:
     */
-   draw->render->release_vertices( draw->render,
-                                   hw_verts,
-                                   feme->translate->key.output_stride,
-                                   count );
+   draw->render->release_vertices( draw->render );
 
    return TRUE;
 }