gallivm: Support 4 x unorm8 in lp_build_fetch_rgba_aos().
[mesa.git] / src / gallium / auxiliary / draw / draw_pt.c
index 4865a2d85421cc28f74fc753629bce7db1503d8c..6234272d6ce98a334b716111b9535b3e56df4a0e 100644 (file)
   */
 
 #include "draw/draw_context.h"
+#include "draw/draw_gs.h"
 #include "draw/draw_private.h"
 #include "draw/draw_pt.h"
-#include "draw/draw_vs.h"
 #include "tgsi/tgsi_dump.h"
 #include "util/u_math.h"
 #include "util/u_prim.h"
 
+
+DEBUG_GET_ONCE_BOOL_OPTION(draw_fse, "DRAW_FSE", FALSE)
+DEBUG_GET_ONCE_BOOL_OPTION(draw_no_fse, "DRAW_NO_FSE", FALSE)
+#ifdef HAVE_LLVM
+DEBUG_GET_ONCE_BOOL_OPTION(draw_use_llvm, "DRAW_USE_LLVM", TRUE)
+#endif
+
 static unsigned trim( unsigned count, unsigned first, unsigned incr )
 {
    if (count < first)
@@ -68,37 +75,43 @@ draw_pt_arrays(struct draw_context *draw,
    {
       unsigned first, incr;
       draw_pt_split_prim(prim, &first, &incr);
-      count = trim(count, first, incr); 
+      count = trim(count, first, incr);
       if (count < first)
          return TRUE;
    }
 
    if (!draw->force_passthrough) {
+      unsigned gs_out_prim = (draw->gs.geometry_shader ? 
+                              draw->gs.geometry_shader->output_primitive :
+                              prim);
+
       if (!draw->render) {
          opt |= PT_PIPELINE;
       }
-      
+
       if (draw_need_pipeline(draw,
                              draw->rasterizer,
-                             prim)) {
+                             gs_out_prim)) {
          opt |= PT_PIPELINE;
       }
 
       if (!draw->bypass_clipping && !draw->pt.test_fse) {
          opt |= PT_CLIPTEST;
       }
-      
-      if (!draw->rasterizer->bypass_vs_clip_and_viewport) {
-         opt |= PT_SHADE;
-      }
+
+      opt |= PT_SHADE;
+   }
+
+   if (draw->pt.middle.llvm && !draw->gs.geometry_shader) {
+      middle = draw->pt.middle.llvm;
+   } else {
+      if (opt == 0)
+         middle = draw->pt.middle.fetch_emit;
+      else if (opt == PT_SHADE && !draw->pt.no_fse)
+         middle = draw->pt.middle.fetch_shade_emit;
+      else
+         middle = draw->pt.middle.general;
    }
-      
-   if (opt == 0) 
-      middle = draw->pt.middle.fetch_emit;
-   else if (opt == PT_SHADE && !draw->pt.no_fse)
-      middle = draw->pt.middle.fetch_shade_emit;
-   else
-      middle = draw->pt.middle.general;
 
 
    /* Pick the right frontend
@@ -111,9 +124,10 @@ draw_pt_arrays(struct draw_context *draw,
 
    frontend->prepare( frontend, prim, middle, opt );
 
-   frontend->run(frontend, 
+   frontend->run(frontend,
                  draw_pt_elt_func(draw),
                  draw_pt_elt_ptr(draw, start),
+                 draw->pt.user.eltBias,
                  count);
 
    frontend->finish( frontend );
@@ -124,8 +138,8 @@ draw_pt_arrays(struct draw_context *draw,
 
 boolean draw_pt_init( struct draw_context *draw )
 {
-   draw->pt.test_fse = debug_get_bool_option("DRAW_FSE", FALSE);
-   draw->pt.no_fse = debug_get_bool_option("DRAW_NO_FSE", FALSE);
+   draw->pt.test_fse = debug_get_option_draw_fse();
+   draw->pt.no_fse = debug_get_option_draw_no_fse();
 
    draw->pt.front.vcache = draw_pt_vcache( draw );
    if (!draw->pt.front.vcache)
@@ -147,12 +161,22 @@ boolean draw_pt_init( struct draw_context *draw )
    if (!draw->pt.middle.general)
       return FALSE;
 
+#if HAVE_LLVM
+   if (debug_get_option_draw_use_llvm())
+      draw->pt.middle.llvm = draw_pt_fetch_pipeline_or_emit_llvm( draw );
+#endif
+
    return TRUE;
 }
 
 
 void draw_pt_destroy( struct draw_context *draw )
 {
+   if (draw->pt.middle.llvm) {
+      draw->pt.middle.llvm->destroy( draw->pt.middle.llvm );
+      draw->pt.middle.llvm = NULL;
+   }
+
    if (draw->pt.middle.general) {
       draw->pt.middle.general->destroy( draw->pt.middle.general );
       draw->pt.middle.general = NULL;
@@ -218,8 +242,11 @@ draw_print_arrays(struct draw_context *draw, uint prim, int start, uint count)
             break;
          default:
             assert(0);
+            return;
          }
-         debug_printf("Element[%u + %u] -> Vertex %u:\n", start, i, ii);
+         ii += draw->pt.user.eltBias;
+         debug_printf("Element[%u + %u] + %i -> Vertex %u:\n", start, i,
+                      draw->pt.user.eltBias, ii);
       }
       else {
          /* non-indexed arrays */
@@ -280,26 +307,38 @@ void
 draw_arrays(struct draw_context *draw, unsigned prim,
             unsigned start, unsigned count)
 {
-   unsigned reduced_prim = u_reduced_prim(prim);
+   draw_arrays_instanced(draw, prim, start, count, 0, 1);
+}
+
+void
+draw_arrays_instanced(struct draw_context *draw,
+                      unsigned mode,
+                      unsigned start,
+                      unsigned count,
+                      unsigned startInstance,
+                      unsigned instanceCount)
+{
+   unsigned reduced_prim = u_reduced_prim(mode);
+   unsigned instance;
+
    if (reduced_prim != draw->reduced_prim) {
-      draw_do_flush( draw, DRAW_FLUSH_STATE_CHANGE );
+      draw_do_flush(draw, DRAW_FLUSH_STATE_CHANGE);
       draw->reduced_prim = reduced_prim;
    }
 
    if (0)
-      draw_print_arrays(draw, prim, start, MIN2(count, 20));
+      draw_print_arrays(draw, mode, start, MIN2(count, 20));
 
 #if 0
    {
       int i;
-      debug_printf("draw_arrays(prim=%u start=%u count=%u):\n",
-                   prim, start, count);
+      debug_printf("draw_arrays(mode=%u start=%u count=%u):\n",
+                   mode, start, count);
       tgsi_dump(draw->vs.vertex_shader->state.tokens, 0);
       debug_printf("Elements:\n");
       for (i = 0; i < draw->pt.nr_vertex_elements; i++) {
-         debug_printf("  format=%s comps=%u\n",
-                      pf_name(draw->pt.vertex_element[i].src_format),
-                      draw->pt.vertex_element[i].nr_components);
+         debug_printf("  format=%s\n",
+                      util_format_name(draw->pt.vertex_element[i].src_format));
       }
       debug_printf("Buffers:\n");
       for (i = 0; i < draw->pt.nr_vertex_buffers; i++) {
@@ -311,15 +350,8 @@ draw_arrays(struct draw_context *draw, unsigned prim,
    }
 #endif
 
-   /* drawing done here: */
-   draw_pt_arrays(draw, prim, start, count);
-}
-
-boolean draw_pt_get_edgeflag( struct draw_context *draw,
-                              unsigned idx )
-{
-   if (draw->pt.user.edgeflag)
-      return (draw->pt.user.edgeflag[idx/32] & (1 << (idx%32))) != 0;
-   else
-      return 1;
+   for (instance = 0; instance < instanceCount; instance++) {
+      draw->instance_id = instance + startInstance;
+      draw_pt_arrays(draw, mode, start, count);
+   }
 }