r600g: emit streamout from dma copy shader
[mesa.git] / src / gallium / drivers / svga / svga_pipe_draw.c
index d98b9b0e0005bd8b0b53c419dd557a2de4823dc9..87f6b3d7126246d8c2bceda304aac2d3af76f946 100644 (file)
  *
  **********************************************************/
 
-#include "svga_cmd.h"
 
+#include "util/u_format.h"
 #include "util/u_inlines.h"
 #include "util/u_prim.h"
 #include "util/u_time.h"
 #include "indices/u_indices.h"
 
 #include "svga_hw_reg.h"
+#include "svga_cmd.h"
 #include "svga_context.h"
 #include "svga_screen.h"
 #include "svga_draw.h"
 #include "svga_state.h"
 #include "svga_swtnl.h"
 #include "svga_debug.h"
-
+#include "svga_resource_buffer.h"
 
 
 static enum pipe_error
@@ -47,12 +48,13 @@ retry_draw_range_elements( struct svga_context *svga,
                            int index_bias,
                            unsigned min_index,
                            unsigned max_index,
-                           unsigned prim, 
-                           unsigned start, 
+                           unsigned prim,
+                           unsigned start,
                            unsigned count,
+                           unsigned instance_count,
                            boolean do_retry )
 {
-   enum pipe_error ret = 0;
+   enum pipe_error ret = PIPE_OK;
 
    svga_hwtnl_set_unfilled( svga->hwtnl,
                             svga->curr.rast->hw_unfilled );
@@ -61,24 +63,17 @@ retry_draw_range_elements( struct svga_context *svga,
                              svga->curr.rast->templ.flatshade,
                              svga->curr.rast->templ.flatshade_first );
 
-
    ret = svga_update_state( svga, SVGA_STATE_HW_DRAW );
-   if (ret)
+   if (ret != PIPE_OK)
       goto retry;
 
    ret = svga_hwtnl_draw_range_elements( svga->hwtnl,
                                          index_buffer, index_size, index_bias,
                                          min_index, max_index,
                                          prim, start, count );
-   if (ret)
+   if (ret != PIPE_OK)
       goto retry;
 
-   if (svga->curr.any_user_vertex_buffers) {
-      ret = svga_hwtnl_flush( svga->hwtnl );
-      if (ret)
-         goto retry;
-   }
-
    return PIPE_OK;
 
 retry:
@@ -90,7 +85,7 @@ retry:
                                         index_buffer, index_size, index_bias,
                                         min_index, max_index,
                                         prim, start, count,
-                                        FALSE );
+                                        instance_count, FALSE );
    }
 
    return ret;
@@ -99,9 +94,10 @@ retry:
 
 static enum pipe_error
 retry_draw_arrays( struct svga_context *svga,
-                   unsigned prim, 
-                   unsigned start, 
+                   unsigned prim,
+                   unsigned start,
                    unsigned count,
+                   unsigned instance_count,
                    boolean do_retry )
 {
    enum pipe_error ret;
@@ -114,24 +110,18 @@ retry_draw_arrays( struct svga_context *svga,
                              svga->curr.rast->templ.flatshade_first );
 
    ret = svga_update_state( svga, SVGA_STATE_HW_DRAW );
-   if (ret)
+   if (ret != PIPE_OK)
       goto retry;
 
    ret = svga_hwtnl_draw_arrays( svga->hwtnl, prim,
                                  start, count );
-   if (ret)
+   if (ret != PIPE_OK)
       goto retry;
 
-   if (svga->curr.any_user_vertex_buffers) {
-      ret = svga_hwtnl_flush( svga->hwtnl );
-      if (ret)
-         goto retry;
-   }
-
-   return 0;
+   return PIPE_OK;
 
 retry:
-   if (ret == PIPE_ERROR_OUT_OF_MEMORY && do_retry) 
+   if (ret == PIPE_ERROR_OUT_OF_MEMORY && do_retry)
    {
       svga_context_flush( svga, NULL );
 
@@ -139,6 +129,7 @@ retry:
                                 prim,
                                 start,
                                 count,
+                                instance_count,
                                 FALSE );
    }
 
@@ -153,18 +144,13 @@ svga_draw_vbo(struct pipe_context *pipe, const struct pipe_draw_info *info)
    unsigned reduced_prim = u_reduced_prim( info->mode );
    unsigned count = info->count;
    enum pipe_error ret = 0;
+   boolean needed_swtnl;
+
+   svga->num_draw_calls++;  /* for SVGA_QUERY_DRAW_CALLS */
 
    if (!u_trim_pipe_prim( info->mode, &count ))
       return;
 
-   if (svga->state.sw.need_swtnl != svga->prev_draw_swtnl) {
-      /* We're switching between SW and HW drawing.  Do a flush to avoid
-       * mixing HW and SW rendering with the same vertex buffer.
-       */
-      pipe->flush(pipe, ~0, NULL);
-      svga->prev_draw_swtnl = svga->state.sw.need_swtnl;
-   }
-
    /*
     * Mark currently bound target surfaces as dirty
     * doesn't really matter if it is done before drawing.
@@ -178,7 +164,9 @@ svga_draw_vbo(struct pipe_context *pipe, const struct pipe_draw_info *info)
       svga->curr.reduced_prim = reduced_prim;
       svga->dirty |= SVGA_NEW_REDUCED_PRIMITIVE;
    }
-   
+
+   needed_swtnl = svga->state.sw.need_swtnl;
+
    svga_update_state_retry( svga, SVGA_STATE_NEED_SWTNL );
 
 #ifdef DEBUG
@@ -188,6 +176,21 @@ svga_draw_vbo(struct pipe_context *pipe, const struct pipe_draw_info *info)
 #endif
 
    if (svga->state.sw.need_swtnl) {
+      svga->num_fallbacks++;  /* for SVGA_QUERY_FALLBACKS */
+      if (!needed_swtnl) {
+         /*
+          * We're switching from HW to SW TNL.  SW TNL will require mapping all
+          * currently bound vertex buffers, some of which may already be
+          * referenced in the current command buffer as result of previous HW
+          * TNL. So flush now, to prevent the context to flush while a referred
+          * vertex buffer is mapped.
+          */
+
+         svga_context_flush(svga, NULL);
+      }
+
+      /* Avoid leaking the previous hwtnl bias to swtnl */
+      svga_hwtnl_set_index_bias( svga->hwtnl, 0 );
       ret = svga_swtnl_draw_vbo( svga, info );
    }
    else {
@@ -206,6 +209,7 @@ svga_draw_vbo(struct pipe_context *pipe, const struct pipe_draw_info *info)
                                           info->mode,
                                           info->start + offset,
                                           info->count,
+                                          info->instance_count,
                                           TRUE );
       }
       else {
@@ -213,10 +217,14 @@ svga_draw_vbo(struct pipe_context *pipe, const struct pipe_draw_info *info)
                                   info->mode,
                                   info->start,
                                   info->count,
+                                  info->instance_count,
                                   TRUE );
       }
    }
 
+   /* XXX: Silence warnings, do something sensible here? */
+   (void)ret;
+
    if (SVGA_DEBUG & DEBUG_FLUSH) {
       svga_hwtnl_flush_retry( svga );
       svga_context_flush(svga, NULL);